<template>
|
<el-dialog v-dialogDrag :title="config.title" :label-position="config.labelPosition" :top="currentTop" :width="config.width" :visible.sync="isShowDialog" append-to-body class="selector-dialog" @open="onOpen">
|
<div class="selector-container">
|
<el-form ref="searcher-form" :inline="true" :model="searchData" class="searcher-form">
|
<template v-for="(field, index) in editorOptions.fields">
|
<el-form-item :key="index">
|
<el-select v-if="field.type=='select'" v-model="searchData[field.options.prop]" :ref="'select-'+field.options.prop" :clearable="true" :key="field.key" :placeholder="field.label" :multiple="field.options.multiple" :disabled="field.options.disabled" filterable class="w-150" @change="(val)=>{change($refs['select-' + field.options.prop][0], val, field);}">
|
<el-option v-for="item in getOptions(field)" :key="item.id" v-bind="item" :label="item.label" :value="item.value" :option="item">
|
</el-option>
|
</el-select>
|
<el-input v-else :ref="'input-'+field.options.prop" v-model="searchData[field.options.prop]" :clearable="true" :key="field.key" :placeholder="field.label" class="w-150"></el-input>
|
</el-form-item>
|
</template>
|
<slot name="search-form-item"></slot>
|
<el-form-item>
|
<el-button type="primary" icon="el-icon-yrt-chaxun" @click.native="loadData();">查询</el-button>
|
<el-button type="default" icon="el-icon-yrt-chaxun" @click.native="reset();">重置</el-button>
|
</el-form-item>
|
</el-form>
|
|
<!--数据Table-->
|
<template>
|
<el-table v-loading.lock="initLoading" ref="datatable" :data="dataList" :max-height="300" highlight-current-row border size="mini" class="table-region" @selection-change="handleSelectionChange">
|
<el-table-column width="35px" type="selection" class="col-selection">
|
</el-table-column>
|
<el-table-column :index="(index)=>{return (dataOptions.pageIndex-1) * dataOptions.pageSize + index+1}" label="#" width="40px" type="index" class="col-index">
|
</el-table-column>
|
<template v-for="(col, index) in dataListOptions.fields">
|
<el-table-column v-if="!col.hidden" :key="index" :sortable="!!col.sortable" :prop="col.prop" :label="col.label" :width="col.width || 'auto'" :min-width="col.minWidth || 'auto'" :header-align="col.headerAlign || 'left'" :align="col.align || 'left'">
|
<template slot-scope="{row}">
|
<!--列插槽-->
|
<slot :row="row" :col="col" :translateText="translateText" name="common-column-slot">
|
<template v-if="col.dropdown_Id>0">
|
{{ translateText(col.prop, row[col.prop], col.dropdown_Id) }}
|
</template>
|
<template v-else>
|
<template v-if="['date', 'datetime'].indexOf(col.dataType)>=0 && col.formatter">
|
{{ common.formatDate(row[col.prop], col.formatter) }}
|
</template>
|
<template v-else-if="['byte', 'int32', 'int64', 'decimal', 'double'].indexOf(col.dataType)>=0 && col.formatter">
|
{{ common.formatNumber(row[col.prop], col.formatter) }}
|
</template>
|
<template v-else>
|
{{ row[col.prop] }}
|
</template>
|
</template>
|
</slot>
|
</template>
|
</el-table-column>
|
</template>
|
</el-table>
|
<div class="pagination-container">
|
<el-pagination :current-page="dataOptions.pageIndex" :page-sizes="[5, 10, 15, 20, 50, 100, 200, 300, 400, 1000]" :page-size="dataOptions.pageSize" :total="dataOptions.total" background layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" @current-change="handleCurrentChange">
|
</el-pagination>
|
</div>
|
</template>
|
</div>
|
|
<div slot="footer" class="dialog-footer">
|
<el-button icon="el-icon-yrt-guanbi1" @click="_cancel">取 消</el-button>
|
<el-button :loading="selectorLoading" type="primary" icon="el-icon-yrt-gouxuan5" @click="onSelectData">确认选择</el-button>
|
</div>
|
</el-dialog>
|
</template>
|
|
<script>
|
export default {
|
name: 'yrt-selector',
|
components: {},
|
props: {
|
// 配置参数
|
config: {
|
type: Object,
|
default: () => {
|
return {
|
top: '15vh',
|
width: '1000px',
|
title: '物料选择器',
|
// 是否显示添加实验室小组对话框
|
visible: false,
|
// 选择器路由
|
router: '/selector/s-product-selector',
|
fixedWhere: {}
|
}
|
}
|
},
|
// 数据访问地址
|
url: {
|
type: String,
|
default: '/api/common/loadDataList'
|
},
|
// 查询条件钩子属性函数
|
setSearchDefault: {
|
type: Function,
|
default: () => {}
|
},
|
// 自定义条件钩子函数
|
getCustomWhere: {
|
type: Function,
|
required: false,
|
default: () => {
|
return ''
|
}
|
}
|
},
|
data() {
|
return {
|
// 配置参数
|
sysConfig: {
|
// 物料 - 不默认货主/供应商
|
sku_noDefaultConsignorProvider: false,
|
// 物料 - 货主/供应商后不可编辑
|
sku_editConsignorProvider: false,
|
// 库存 - 不默认货主/供应商
|
sku_noDefaultConsignorProvider_storage: false,
|
// 库存 - 货主/供应商后不可编辑
|
sku_editConsignorProvider_storage: false
|
},
|
dataOptions: {},
|
dataListOptions: {},
|
editorOptions: {
|
fields: [],
|
config: {}
|
},
|
|
selectorLoading: false, // 查询loading
|
initLoading: false, // 加载数据初始化loading
|
// 表单数据集合
|
searchData: {},
|
// 数据集合
|
dataList: [],
|
// 选中的数据
|
dataListSelections: [],
|
// 下拉框值集合
|
dropdownData: {}
|
}
|
},
|
computed: {
|
// 是否显示dialog
|
isShowDialog: {
|
get: function() {
|
return this.config.visible
|
},
|
set: function(newValue) {
|
this.$emit('update:visible', newValue) // 双向绑定prop.visible,通知父级组件变量值同步更新
|
}
|
},
|
// 当前diaolog top
|
currentTop: {
|
get: function() {
|
return this.config.top
|
},
|
set: function(newValue) {
|
this.$emit('update:top', newValue) // 双向绑定prop.action,通知父级组件变量值同步更新
|
}
|
},
|
// 获得下拉框options
|
getOptions: {
|
get: function() {
|
return field => {
|
if (field.options.remote === 'bindDropdown') {
|
field.options.options = this.dropdownData['dropdown' + field.options.dropdown_Id]
|
}
|
return field.options.options
|
}
|
}
|
}
|
},
|
watch: {
|
searchData: {
|
handler(val) {},
|
deep: true
|
}
|
},
|
created() {
|
// 获取配置参数
|
this.getConfig()
|
this.init()
|
},
|
activated() {
|
this.setSearchDefault(this.searchData)
|
},
|
methods: {
|
// 获得配置参数
|
getConfig() {
|
var keys = Object.keys(this.sysConfig).join(',')
|
var url = '/api/sys/param/getConfig'
|
var params = {
|
openNodeApi: true,
|
keys: keys
|
}
|
var callback = res => {
|
this.common.showMsg(res)
|
this.valueList = res.data
|
// 获得参数值列表,将数字转换为对象
|
res.data.forEach(item => {
|
var value03 = item.value03
|
if (this.common.isNumber(item.value03)) {
|
value03 = parseInt(item.value03)
|
}
|
this.$set(this.sysConfig, item.value02, !!value03)
|
})
|
}
|
var target = this.$refs['settings']
|
this.common.ajax(url, params, callback, target)
|
},
|
// 字段change事件
|
change(ref, val, field) {
|
this.$emit('on-change', ref, val, field)
|
},
|
// 选择items
|
handleSelectionChange(val) {
|
this.dataListSelections = val
|
},
|
// 分页大小改变
|
handleSizeChange(pageSize) {
|
this.dataOptions.pageSize = pageSize
|
this.loadData()
|
this.$emit('on-page-size-change', pageSize)
|
},
|
// 当前页码大小改变
|
handleCurrentChange(val) {
|
this.dataOptions.pageIndex = val
|
this.loadData()
|
},
|
// 初始化数据
|
init() {
|
var json = '/static' + this.config.router + '.json'
|
// "/selector/s-product-selector",
|
this.axios
|
.get(json)
|
.then(response => {
|
Object.keys(response.data).forEach(key => {
|
this.$set(this, key, response.data[key])
|
})
|
// 加载权限
|
this.loadAuth()
|
// 加载下拉框
|
this.loadDropDown()
|
})
|
.catch(error => {
|
this.$message.error(error.message)
|
})
|
},
|
// 加载权限
|
loadAuth() {
|
// 加载页面权限
|
var url = '/api/auth/getAuth'
|
|
var params = {
|
id: this.dataOptions.menu_Id,
|
table_Id: this.dataOptions.table_Id,
|
fromVueData_Id: this.dataOptions.vueData_Id, // 根据原始ID找到用户自定义UIID
|
tableView: this.dataOptions.tableView,
|
subTableViews: []
|
}
|
this.common.ajax(
|
url,
|
params,
|
res => {
|
this.common.showMsg(res)
|
// 自定义UI
|
//debugger
|
if (res.result && !res.global_closeUserUIJson && res.userUIJson && res.userUIJson.dataOptions) {
|
debugger
|
this.$set(this, 'dataOptions', res.userUIJson.dataOptions)
|
this.$set(this, 'dataListOptions', res.userUIJson.dataListOptions)
|
this.$set(this, 'editorOptions', res.userUIJson.editorOptions)
|
// 获得表格自定义设置
|
var router = this.$route.fullPath
|
var key = 'tableConfig_' + router
|
var fields = localStorage.getItem(key)
|
if (fields) {
|
fields = JSON.parse(fields)
|
debugger
|
this.dataListOptions.fields = fields
|
}
|
}
|
// 开启全局数据排序
|
if (res.global_openSortable) {
|
this.dataListOptions.fields.forEach(item => {
|
item.sortable = true
|
})
|
}
|
|
if (res.result && res.userJson) {
|
this.setUserJson(res)
|
}
|
},
|
false
|
)
|
},
|
// 合并自定义设置
|
setUserJson(res) {
|
const userJson = res.userJson
|
// 查找明细字段
|
var _findEditorField = function(array, prop) {
|
for (const item of array) {
|
if (item.type === 'grid') {
|
for (const colItem of item.columns) {
|
const _field = _findEditorField(colItem.fields, prop)
|
if (_field) return _field
|
}
|
} else if (item.type === 'inline-group') {
|
const _field = _findEditorField(item.fields, prop)
|
if (_field) return _field
|
} else if (item.type === 'detail-grid') {
|
const _field = _findEditorField(item.fields, prop)
|
if (_field) return _field
|
} else {
|
if (item.options && item.options.prop === prop) {
|
return item
|
}
|
}
|
}
|
}
|
if (userJson && userJson.fields) {
|
// 存在自定义排序
|
let hasSortNo = false
|
userJson.fields.forEach(field => {
|
// 列表页面
|
const _field = this.dataListOptions.fields.find(f => f.prop === field.prop)
|
if (_field) {
|
if (field.sortNo) {
|
_field.sortNo = field.sortNo
|
hasSortNo = true
|
}
|
if (field.label) {
|
_field.label = field.label
|
}
|
if (field.width) {
|
_field.width = field.width
|
}
|
}
|
// 编辑页面
|
const _fieldEditor = _findEditorField(this.editorOptions.fields, field.prop)
|
if (_fieldEditor) {
|
if (field.label) {
|
_fieldEditor.label = field.label
|
}
|
if (field.blank !== undefined) {
|
_fieldEditor.options.required = !field.blank
|
if (_fieldEditor.rules) {
|
const rule = _fieldEditor.rules.find(item => item.required)
|
if (rule) {
|
rule.required = !field.blank
|
}
|
}
|
}
|
}
|
})
|
// 列表进行排序
|
if (hasSortNo) {
|
this.dataListOptions.fields.sort((a, b) => {
|
return (a.sortNo || 0) > (b.sortNo || 0) ? -1 : 1
|
})
|
this.$nextTick(() => {
|
this.$forceUpdate()
|
if (this.dataList) this.dataList.setCurrentRow() // 目的是让列表页面重新渲染一下
|
})
|
}
|
}
|
|
// 系统自动计算列宽
|
this.dataListOptions.fields.forEach(field => {
|
let width = 60
|
if (field.label) width = 16 * field.label.length
|
if (width < 60) width = 60
|
// 开启全局数据排序
|
if (res.global_openSortable) {
|
width += 30
|
}
|
if (field.remark) {
|
width += 20
|
}
|
if (width > field.width || !field.width) {
|
this.$set(field, 'minWidth', width)
|
delete field.width
|
}
|
})
|
|
// 获得明细表
|
var subTableViews = this.editorOptions.fields.filter(item => item.type === 'detail-grid')
|
|
// 明细字段处理
|
const subUserJsons = res.subUserJsons
|
subUserJsons.forEach(item => {
|
const userJson = item.userJson
|
const subFields = subTableViews.find(row => row.subTableView === item.subTableView).fields
|
if (userJson && userJson.fields) {
|
// 存在自定义排序
|
let hasSortNo = false
|
userJson.fields.forEach(field => {
|
// 明细列表
|
const _field = subFields.find(f => f.prop === field.prop)
|
if (_field) {
|
if (field.sortNo) {
|
_field.sortNo = field.sortNo
|
hasSortNo = true
|
}
|
if (field.label) {
|
_field.label = field.label
|
}
|
if (field.width) {
|
_field.width = field.width
|
}
|
}
|
})
|
// 列表进行排序
|
if (hasSortNo) {
|
subFields.sort((a, b) => {
|
return (a.sortNo || 0) > (b.sortNo || 0) ? -1 : 1
|
})
|
}
|
}
|
})
|
},
|
// 获得快速查询条件
|
getWhere() {
|
let where = {}
|
Object.keys(this.searchData).forEach(field => {
|
var val = this.searchData[field]
|
var propInfo = this.editorOptions.fields.find(item => {
|
return item.options.prop === field
|
})
|
if (!propInfo) {
|
this.$message.error(field + '未设置为查询条件')
|
return
|
}
|
if ((!Array.isArray(val) && val) || (Array.isArray(val) && val.length)) {
|
if (propInfo.options.keyProp) {
|
field = propInfo.options.keyProp
|
}
|
if (propInfo.type === 'select') {
|
if (Array.isArray(val)) {
|
where[field] = val
|
} else {
|
where[field] = val
|
}
|
} else {
|
if (val === '>0') {
|
where[field] = {
|
operator: '>',
|
value: 0
|
}
|
} else if (val === '>=0') {
|
where[field] = {
|
operator: '>=',
|
value: 0
|
}
|
} else if (val === '=0') {
|
where[field] = {
|
operator: '=',
|
value: 0
|
}
|
} else {
|
where[field] = {
|
operator: 'like',
|
value: val
|
}
|
}
|
}
|
}
|
})
|
if (this.config.fixedWhere) {
|
where = Object.assign(where, this.config.fixedWhere)
|
}
|
// 获得自定义条件
|
var customWhere = this.getCustomWhere()
|
if (customWhere) {
|
where = Object.assign(where, customWhere)
|
}
|
|
return where
|
},
|
// 加载数据
|
loadData() {
|
var where = this.getWhere()
|
this.initLoading = true
|
var params = Object.assign({}, this.dataOptions, {
|
openNodeApi: true,
|
where: where,
|
pageIndex: this.dataOptions.pageIndex,
|
pageSize: this.dataOptions.pageSize
|
})
|
this.common.ajax(
|
this.url,
|
params,
|
res => {
|
if (res.result) {
|
this.dataList = res.data.rows
|
this.translate(this.dataList)
|
this.dataOptions.total = res.data.total
|
} else {
|
this.$message({
|
showClose: true,
|
duration: 6000,
|
message: res.msg,
|
type: 'error'
|
})
|
}
|
this.initLoading = false
|
},
|
true
|
)
|
},
|
// 数据转换
|
translate(rows) {
|
for (const row of rows) {
|
this.dataListOptions.fields.forEach(field => {
|
var prop = field.prop
|
if (field.dataType === 'date') {
|
const v = row[prop]
|
if (v) {
|
let formatter = 'yyyy-MM-dd'
|
if (field.formatter) formatter = field.formatter
|
row[prop] = this.common.formatDate(v, formatter)
|
}
|
} else if (field.dataType === 'datetime') {
|
const v = row[prop]
|
if (v) {
|
let formatter = 'yyyy-MM-dd HH:mm:ss'
|
if (field.formatter) formatter = field.formatter
|
row[prop] = this.common.formatDate(v, formatter)
|
}
|
}
|
})
|
}
|
},
|
// 重置
|
reset() {
|
Object.keys(this.searchData).forEach(key => {
|
var propInfo = this.editorOptions.fields.find(item => {
|
return item.options.prop === key
|
})
|
// disabled=true的不清除
|
if (propInfo.options.disabled) {
|
return false
|
}
|
if (propInfo.type === 'select') {
|
if (Array.isArray(this.searchData[key])) {
|
this.searchData[key] = []
|
} else {
|
this.searchData[key] = null
|
}
|
} else {
|
this.searchData[key] = null
|
}
|
})
|
},
|
// 关闭窗口
|
_cancel() {
|
this.$emit('update:visible', !this.config.visible) // 双向绑定prop.visible,通知父级组件变量值同步更新
|
},
|
// 选择数据
|
onSelectData() {
|
if (!this.dataListSelections.length) {
|
this.$message('至少选择一条记录')
|
return
|
}
|
debugger
|
// 标示已经修改
|
this.dataListSelections.forEach(item => (item.__ischange__ = true))
|
const rows = JSON.parse(JSON.stringify(this.dataListSelections))
|
const rowChange = []
|
rows.forEach(item =>
|
rowChange.push({
|
productModel: item.ProductCode,
|
product_Id: item.Product_Id,
|
extendField04: item.ExtendField04, //跟踪号
|
productCode: item.ProductCode,
|
productName: item.ProductName,
|
smallUnit: item.SmallUnit,
|
productStorage: item.ProductStorage, //未出库数量
|
usingStorage: item.ProductStorage //本次分拣数量
|
})
|
)
|
this.$emit('on-selected', rowChange)
|
},
|
// 加载下拉框数据
|
loadDropDown() {
|
if (this.dropdownLoaded) return // 已加载下拉框不在重复加载
|
// 获得下拉框ID
|
var ddIDs = []
|
var _getDropDownId = array => {
|
array.forEach(item => {
|
if (Array.isArray(item)) {
|
_getDropDownId(item)
|
} else {
|
if (item.dropdown_Id) {
|
ddIDs.push(item.dropdown_Id)
|
}
|
}
|
})
|
}
|
_getDropDownId(this.dataListOptions.fields)
|
// 查询条件下拉框ID
|
var _getEditorDropDownId = array => {
|
array.forEach(item => {
|
if (item.type === 'grid') {
|
item.columns.forEach(colItem => {
|
_getDropDownId(colItem.fields)
|
})
|
} else if (item.type === 'inline-group') {
|
_getDropDownId(item.fields)
|
} else {
|
if (item.options && item.options.dropdown_Id) {
|
ddIDs.push(item.options.dropdown_Id)
|
}
|
}
|
})
|
}
|
_getEditorDropDownId(this.editorOptions.fields)
|
if (!ddIDs.length) {
|
// 加载数据
|
this.loadData()
|
return
|
}
|
this.initLoading = true
|
var url = '/api/common/loadDropDown'
|
var params = Object.assign({}, this.dataOptions, {
|
openNodeApi: true,
|
where: ddIDs.join(','),
|
data: JSON.stringify(this.formData)
|
})
|
this.common.ajax(
|
url,
|
params,
|
res => {
|
this.common.showMsg(res)
|
if (res.result) {
|
this.dropdownLoaded = true // 记录已加载下拉框数据
|
Object.keys(res.data).forEach((key, index) => {
|
this.$set(this.dropdownData, key, res.data[key])
|
})
|
}
|
this.initLoading = false
|
// 加载数据
|
this.loadData()
|
},
|
true
|
)
|
},
|
// 翻译下拉框值
|
translateText(prop, val, dropdown_Id) {
|
var ddList = this.dropdownData['dropdown' + dropdown_Id]
|
if (!ddList) return val
|
var item = ddList.find((item, index, arr) => {
|
return item.value === val
|
})
|
if (!item) return val
|
return item.label
|
},
|
// 清除选中项
|
clearSelection() {
|
if (this.$refs.datatable) {
|
this.$refs.datatable.clearSelection()
|
}
|
},
|
// 对话框显示完后
|
onOpen() {
|
this.clearSelection()
|
},
|
// 设置查询条件值
|
setSearchValue(prop, value) {
|
if (['storage_Id', 'consignor_Id', 'provider_Id'].indexOf(prop) >= 0) {
|
if (this.config.title === '物料选择器') {
|
// 系统参数sku_autoDefaultConsignorProvider开启,自动默认值
|
if (!this.sysConfig.sku_noDefaultConsignorProvider) {
|
this.$set(this.searchData, prop, value)
|
}
|
} else if (this.config.title === '物料库存选择器') {
|
debugger
|
// 系统参数sku_noDefaultConsignorProvider_storage开启,自动默认值
|
if (!this.sysConfig.sku_noDefaultConsignorProvider_storage) {
|
this.$set(this.searchData, prop, value)
|
}
|
} else {
|
this.$set(this.searchData, prop, value)
|
}
|
} else {
|
this.$set(this.searchData, prop, value)
|
}
|
},
|
// 设置为只读
|
setReadOnly(fieldName, disabled) {
|
const fieldInfo = this.editorOptions.fields.find(item => item.options.prop === fieldName)
|
if (['storage_Id', 'consignor_Id', 'provider_Id'].indexOf(fieldName) >= 0) {
|
if (this.config.title === '物料选择器') {
|
// 系统参数sku_editConsignorProvider开启,可编辑筛选框
|
if (fieldInfo && !this.sysConfig.sku_editConsignorProvider) {
|
fieldInfo.options.disabled = disabled
|
}
|
} else if (this.config.title === '物料库存选择器') {
|
debugger
|
// 系统参数sku_editConsignorProvider开启,可编辑筛选框
|
if (fieldInfo && !this.sysConfig.sku_editConsignorProvider_storage) {
|
fieldInfo.options.disabled = disabled
|
}
|
} else {
|
if (fieldInfo) {
|
fieldInfo.options.disabled = disabled
|
}
|
}
|
} else {
|
if (fieldInfo) {
|
fieldInfo.options.disabled = disabled
|
}
|
}
|
}
|
}
|
}
|
</script>
|
|
<style rel="stylesheet/scss" lang="scss" scoped>
|
.selector-dialog {
|
.selector-container {
|
.splitter-title {
|
background-color: #f2f6fc;
|
padding: 0px 10px;
|
margin-bottom: 10px;
|
border-bottom: #dcdfe6 2px double;
|
position: relative;
|
.title {
|
padding: 10px 3px;
|
border-bottom: #036fba 3px solid;
|
font-size: 16px;
|
display: inline-block;
|
position: relative;
|
bottom: -2px;
|
}
|
}
|
|
.selector-table {
|
padding: 0px;
|
}
|
|
.footer {
|
text-align: center;
|
padding: 30px 0 0;
|
a.create {
|
display: block;
|
color: #036fba;
|
text-decoration: underline;
|
padding: 20px;
|
}
|
.el-button {
|
padding: 15px 50px;
|
font-size: 20px;
|
background-color: #036fba;
|
}
|
}
|
}
|
}
|
</style>
|
|
<style rel="stylesheet/scss" lang="scss">
|
.selector-dialog {
|
.el-dialog__body {
|
padding: 10px 20px 10px 10px;
|
}
|
.pagination-container {
|
margin-top: 10px;
|
}
|
}
|
</style>
|