完善工序单元功能迁移
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="$t(title)"
|
||||
:title="title"
|
||||
:visible.sync="visible"
|
||||
:append-to-body="true"
|
||||
:close-on-click-modal="false"
|
||||
@@ -129,6 +129,66 @@
|
||||
<el-button type="primary" @click="handleSubmit">{{ $t(key('confirm')) }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
:title="$t(key('preset_result_param_import'))"
|
||||
:visible.sync="importVisible"
|
||||
append-to-body
|
||||
width="75%"
|
||||
:close-on-click-modal="false"
|
||||
:before-close="handleImportClose"
|
||||
>
|
||||
<el-alert
|
||||
:title="$t(key('file_suffix_rule'))"
|
||||
:closable="false"
|
||||
type="warning"
|
||||
show-icon
|
||||
/>
|
||||
<el-form label-width="90px" class="import-form">
|
||||
<el-form-item :label="$t(key('import_table'))">
|
||||
<el-upload
|
||||
action=""
|
||||
:multiple="false"
|
||||
:auto-upload="false"
|
||||
:show-file-list="true"
|
||||
:file-list="importFileList"
|
||||
accept=".xls,.xlsx"
|
||||
:on-change="onImportFileChange"
|
||||
>
|
||||
<el-button slot="trigger" size="mini" type="success">{{ $t(key('select_file')) }}</el-button>
|
||||
<el-button
|
||||
style="margin-left:10px"
|
||||
size="mini"
|
||||
type="primary"
|
||||
:loading="downloadImportLoading"
|
||||
@click.stop="downloadTemplate"
|
||||
>
|
||||
{{ $t(key('download_template')) }}
|
||||
</el-button>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t(key('preview'))">
|
||||
<el-table
|
||||
v-loading="importTableLoading"
|
||||
:data="importRows"
|
||||
border
|
||||
height="360"
|
||||
style="width:100%"
|
||||
>
|
||||
<el-table-column prop="name" :label="$t(key('name'))" min-width="140" show-overflow-tooltip />
|
||||
<el-table-column prop="code" :label="$t(key('param'))" min-width="140" show-overflow-tooltip />
|
||||
<el-table-column prop="field_type" :label="$t(key('category'))" min-width="120" />
|
||||
<el-table-column prop="remark" :label="$t(key('remark'))" min-width="160" show-overflow-tooltip />
|
||||
<el-table-column prop="is_only" :label="$t(key('is_unique'))" width="110" />
|
||||
<el-table-column prop="is_upload" :label="$t(key('is_upload'))" width="110" />
|
||||
</el-table>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer">
|
||||
<el-button @click="handleImportClose">{{ $t(key('cancel')) }}</el-button>
|
||||
<el-button type="primary" :loading="importSubmitting" @click="submitImport">{{ $t(key('confirm')) }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
@@ -138,8 +198,11 @@ import {
|
||||
getOptionalParamsList,
|
||||
createOptionalParams,
|
||||
editOptionalParams,
|
||||
deleteOptionalParams
|
||||
deleteOptionalParams,
|
||||
getImportTemplate,
|
||||
importDataCreate
|
||||
} from '@/api/production-master-data/optional-params'
|
||||
import { downloadRename, readExcel } from '@/utils/file'
|
||||
|
||||
export default {
|
||||
name: 'ProcessStepResultParam',
|
||||
@@ -167,6 +230,12 @@ export default {
|
||||
pagination: { current: 1, size: 10, total: 0 },
|
||||
innerVisible: false,
|
||||
dialogTitle: '',
|
||||
importVisible: false,
|
||||
downloadImportLoading: false,
|
||||
importFileList: [],
|
||||
importTableLoading: false,
|
||||
importSubmitting: false,
|
||||
importRows: [],
|
||||
formData: {
|
||||
id: '',
|
||||
code: '',
|
||||
@@ -201,6 +270,25 @@ export default {
|
||||
this.innerVisible = false
|
||||
this.$refs.form && this.$refs.form.resetFields()
|
||||
},
|
||||
normalizeResponse (res) {
|
||||
const getTotal = (source, fallback) => {
|
||||
if (!source) return fallback
|
||||
const total = source.count ?? source.total ?? source.total_count ?? source.record_count
|
||||
const value = Number(total)
|
||||
return Number.isNaN(value) ? fallback : value
|
||||
}
|
||||
const containers = [res, res && res.data, res && res.data && res.data.data].filter(Boolean)
|
||||
for (const item of containers) {
|
||||
if (Array.isArray(item)) {
|
||||
return { list: item, total: getTotal(res, item.length) }
|
||||
}
|
||||
const list = item.data || item.list || item.rows || item.records || item.items
|
||||
if (Array.isArray(list)) {
|
||||
return { list, total: getTotal(item, getTotal(res, list.length)) }
|
||||
}
|
||||
}
|
||||
return { list: [], total: 0 }
|
||||
},
|
||||
onSearch () {
|
||||
this.pagination.current = 1
|
||||
this.fetchData()
|
||||
@@ -214,10 +302,9 @@ export default {
|
||||
page_size: this.pagination.size,
|
||||
...this.searchForm
|
||||
}).then(res => {
|
||||
const list = Array.isArray(res) ? res : (res.data || [])
|
||||
const total = Array.isArray(res) ? res.length : (res.count || 0)
|
||||
this.tableData = list
|
||||
this.pagination.total = total
|
||||
const data = this.normalizeResponse(res)
|
||||
this.tableData = data.list
|
||||
this.pagination.total = data.total
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
@@ -265,6 +352,7 @@ export default {
|
||||
}).then(() => {
|
||||
deleteOptionalParams({ workingsubclass_id: this.workingsubclass_id, id: row.id }).then(() => {
|
||||
this.$message.success(this.$t(this.key('operation_success')))
|
||||
this.pagination.current = Math.min(this.pagination.current, Math.ceil((this.pagination.total - 1) / this.pagination.size) || 1)
|
||||
this.fetchData()
|
||||
})
|
||||
}).catch(() => {})
|
||||
@@ -283,7 +371,109 @@ export default {
|
||||
})
|
||||
},
|
||||
handleImport () {
|
||||
this.$message.info(this.$t(this.key('import_tip')))
|
||||
this.importFileList = []
|
||||
this.importRows = []
|
||||
this.importVisible = true
|
||||
},
|
||||
handleImportClose () {
|
||||
this.importVisible = false
|
||||
this.importFileList = []
|
||||
this.importRows = []
|
||||
},
|
||||
async downloadTemplate () {
|
||||
this.downloadImportLoading = true
|
||||
try {
|
||||
const res = await getImportTemplate({})
|
||||
downloadRename(res, 'xlsx', this.$t(this.key('optional_param_import_template')))
|
||||
} finally {
|
||||
this.downloadImportLoading = false
|
||||
}
|
||||
},
|
||||
getImportValue (row, keys) {
|
||||
for (const key of keys) {
|
||||
if (row[key] !== undefined && row[key] !== null) return row[key]
|
||||
}
|
||||
return ''
|
||||
},
|
||||
normalizeFlag (value) {
|
||||
if (value === 1 || value === '1') return 1
|
||||
if (value === 0 || value === '0') return 0
|
||||
const text = String(value || '').trim().toLowerCase()
|
||||
if ([this.$t(this.key('yes')).toLowerCase(), '是', 'yes', 'true'].includes(text)) return 1
|
||||
if ([this.$t(this.key('no')).toLowerCase(), '否', 'no', 'false'].includes(text)) return 0
|
||||
return value
|
||||
},
|
||||
async onImportFileChange (file) {
|
||||
if (!file || !/\.(xls|xlsx)$/i.test(file.name)) {
|
||||
this.$message.error(this.$t(this.key('upload_format_error')))
|
||||
this.importFileList = []
|
||||
return
|
||||
}
|
||||
this.importFileList = [file]
|
||||
this.importTableLoading = true
|
||||
try {
|
||||
const rows = await readExcel(file.raw)
|
||||
const required = [
|
||||
{ label: this.key('name'), aliases: [this.$t(this.key('name')), '名称', 'Name'] },
|
||||
{ label: this.key('param'), aliases: [this.$t(this.key('param')), '参数', 'Parameter'] },
|
||||
{ label: this.key('category'), aliases: [this.$t(this.key('category')), '类别', 'Category'] }
|
||||
]
|
||||
const first = rows[0] || {}
|
||||
const missing = required.find(field => !field.aliases.some(alias => Object.prototype.hasOwnProperty.call(first, alias)))
|
||||
if (missing) {
|
||||
this.$message.error(this.$t(this.key('import_missing_column'), { name: this.$t(missing.label) }))
|
||||
this.importRows = []
|
||||
return
|
||||
}
|
||||
const nameSet = new Set()
|
||||
const codeSet = new Set()
|
||||
const result = []
|
||||
for (const row of rows) {
|
||||
const name = this.getImportValue(row, [this.$t(this.key('name')), '名称', 'Name'])
|
||||
const code = this.getImportValue(row, [this.$t(this.key('param')), '参数', 'Parameter'])
|
||||
if (nameSet.has(name)) {
|
||||
this.$message.error(this.$t(this.key('import_duplicate_name'), { name }))
|
||||
this.importRows = []
|
||||
return
|
||||
}
|
||||
if (codeSet.has(code)) {
|
||||
this.$message.error(this.$t(this.key('import_duplicate_param'), { param: code }))
|
||||
this.importRows = []
|
||||
return
|
||||
}
|
||||
nameSet.add(name)
|
||||
codeSet.add(code)
|
||||
result.push({
|
||||
name,
|
||||
code,
|
||||
field_type: this.getImportValue(row, [this.$t(this.key('category')), '类别', 'Category']),
|
||||
remark: this.getImportValue(row, [this.$t(this.key('remark')), '备注', 'Remark']),
|
||||
is_only: this.normalizeFlag(this.getImportValue(row, [this.$t(this.key('is_unique')), '是否唯一', 'Is Unique'])),
|
||||
is_upload: this.normalizeFlag(this.getImportValue(row, [this.$t(this.key('is_upload')), '是否上传', 'Is Upload Required']))
|
||||
})
|
||||
}
|
||||
this.importRows = result
|
||||
} finally {
|
||||
this.importTableLoading = false
|
||||
}
|
||||
},
|
||||
async submitImport () {
|
||||
if (!this.importRows.length) {
|
||||
this.$message.error(this.$t(this.key('please_import_data')))
|
||||
return
|
||||
}
|
||||
this.importSubmitting = true
|
||||
try {
|
||||
await importDataCreate({
|
||||
workingsubclass_id: this.workingsubclass_id,
|
||||
import_data: JSON.stringify(this.importRows)
|
||||
})
|
||||
this.$message.success(this.$t(this.key('operation_success')))
|
||||
this.handleImportClose()
|
||||
this.fetchData()
|
||||
} finally {
|
||||
this.importSubmitting = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -296,4 +486,7 @@ export default {
|
||||
.box-card {
|
||||
width: 100%;
|
||||
}
|
||||
.import-form {
|
||||
margin-top: 16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="$t(title)"
|
||||
:title="title"
|
||||
:visible.sync="visible"
|
||||
:append-to-body="true"
|
||||
:close-on-click-modal="false"
|
||||
|
||||
@@ -21,6 +21,24 @@
|
||||
@keyup.enter.native="onSearch"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t(key('device_category'))">
|
||||
<el-select
|
||||
v-model="search.device_category_id"
|
||||
:placeholder="$t(key('select_device_category'))"
|
||||
clearable
|
||||
filterable
|
||||
style="width:200px"
|
||||
@focus="loadDeviceCategoryOptions"
|
||||
@change="onSearch"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in deviceCategoryOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" @click="onSearch">
|
||||
{{ $t(key('search')) }}
|
||||
@@ -46,7 +64,12 @@
|
||||
auto-height
|
||||
@page-change="onPageChange"
|
||||
@selection-change="onSelect"
|
||||
/>
|
||||
>
|
||||
<template #col-is_denglu_process="{ row }">
|
||||
<el-tag v-if="String(row.is_denglu_process) === '1'" size="mini">{{ $t(key('yes')) }}</el-tag>
|
||||
<el-tag v-else type="warning" size="mini">{{ $t(key('no')) }}</el-tag>
|
||||
</template>
|
||||
</page-table>
|
||||
|
||||
<page-dialog-form
|
||||
ref="dialogForm"
|
||||
@@ -116,9 +139,10 @@ export default {
|
||||
dialogTitle: '',
|
||||
editId: '',
|
||||
handleType: 'create',
|
||||
search: { code: '', name: '' },
|
||||
search: { code: '', name: '', device_category_id: '' },
|
||||
pagination: { current: 1, size: 10, total: 0 },
|
||||
formData: { code: '', name: '', device_category_id: '', remark: '' },
|
||||
deviceCategoryOptions: [],
|
||||
formData: { code: '', name: '', device_category_id: '', is_denglu_process: '0', remark: '' },
|
||||
settingVisible: false,
|
||||
settingTitle: '',
|
||||
settingType: '',
|
||||
@@ -139,6 +163,9 @@ export default {
|
||||
],
|
||||
device_category_id: [
|
||||
{ required: true, message: this.key('select_device_category'), trigger: 'change' }
|
||||
],
|
||||
is_denglu_process: [
|
||||
{ required: true, message: this.key('select_login_process'), trigger: 'change' }
|
||||
]
|
||||
},
|
||||
columns: [],
|
||||
@@ -175,7 +202,23 @@ export default {
|
||||
clearable: true,
|
||||
filterable: true,
|
||||
style: { width: '90%' },
|
||||
options: []
|
||||
options: [],
|
||||
onFocus: this.loadDeviceCategoryOptions
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
type: 'select',
|
||||
prop: 'is_denglu_process',
|
||||
label: this.key('login_process'),
|
||||
placeholder: this.key('select_login_process'),
|
||||
clearable: false,
|
||||
filterable: true,
|
||||
style: { width: '90%' },
|
||||
options: [
|
||||
{ label: this.$t(this.key('yes')), value: '1' },
|
||||
{ label: this.$t(this.key('no')), value: '0' }
|
||||
]
|
||||
}
|
||||
],
|
||||
[
|
||||
@@ -198,8 +241,9 @@ export default {
|
||||
{ prop: 'code', label: this.key('process_unit_code'), minWidth: 120 },
|
||||
{ prop: 'name', label: this.key('process_unit_name'), minWidth: 120 },
|
||||
{ prop: 'device_category_name', label: this.key('device_category'), minWidth: 120 },
|
||||
{ prop: 'is_denglu_process', label: this.key('login_process'), width: 120, slot: 'is_denglu_process' },
|
||||
{ prop: 'remark', label: this.key('remark') },
|
||||
{ prop: '_actions', label: this.key('operation'), width: 160, fixed: 'right' }
|
||||
{ prop: '_actions', label: this.key('operation'), width: 350, fixed: 'right' }
|
||||
])
|
||||
const btns = useTableButtons({
|
||||
toolbar: [
|
||||
@@ -217,7 +261,7 @@ export default {
|
||||
key: 'edit',
|
||||
label: this.key('edit'),
|
||||
icon: 'el-icon-edit',
|
||||
auth: '/production_configuration/technology_model/technology_flow_process/edit',
|
||||
auth: '/production_configuration/technology_model/technology_flow_workingsubclass/edit',
|
||||
onClick: this.openEdit
|
||||
},
|
||||
{
|
||||
@@ -226,7 +270,8 @@ export default {
|
||||
icon: 'el-icon-setting',
|
||||
color: 'warning',
|
||||
auth: '/production_configuration/technology_model/technology_flow_workingsubclass/setting',
|
||||
onClick: this.openSetting
|
||||
onClick: this.openSetting,
|
||||
visible: row => !!row.setting_plugin
|
||||
},
|
||||
{
|
||||
key: 'result',
|
||||
@@ -248,17 +293,38 @@ export default {
|
||||
}, this.$permission)
|
||||
this.toolbarButtons = btns.toolbarButtons
|
||||
this.rowButtons = btns.rowButtons
|
||||
this.loadDeviceCategoryOptions()
|
||||
this.fetchData()
|
||||
},
|
||||
methods: {
|
||||
normalizeResponse (res) {
|
||||
const getTotal = (source, fallback) => {
|
||||
if (!source) return fallback
|
||||
const total = source.count ?? source.total ?? source.total_count ?? source.record_count
|
||||
const value = Number(total)
|
||||
return Number.isNaN(value) ? fallback : value
|
||||
}
|
||||
const containers = [res, res && res.data, res && res.data && res.data.data].filter(Boolean)
|
||||
for (const item of containers) {
|
||||
if (Array.isArray(item)) {
|
||||
return { list: item, total: getTotal(res, item.length) }
|
||||
}
|
||||
const list = item.data || item.list || item.rows || item.records || item.items
|
||||
if (Array.isArray(list)) {
|
||||
return { list, total: getTotal(item, getTotal(res, list.length)) }
|
||||
}
|
||||
}
|
||||
return { list: [], total: 0 }
|
||||
},
|
||||
loadDeviceCategoryOptions () {
|
||||
if (this.formCols[2][0].options.length > 0) return Promise.resolve()
|
||||
if (this.deviceCategoryOptions.length > 0) return Promise.resolve()
|
||||
return getDeviceCategoryAll().then(res => {
|
||||
const list = res.data || res || []
|
||||
this.formCols[2][0].options = list.map(item => ({
|
||||
const list = this.normalizeResponse(res).list
|
||||
this.deviceCategoryOptions = list.map(item => ({
|
||||
label: item.name,
|
||||
value: item.id
|
||||
}))
|
||||
this.formCols[2][0].options = this.deviceCategoryOptions
|
||||
})
|
||||
},
|
||||
async fetchData () {
|
||||
@@ -269,10 +335,9 @@ export default {
|
||||
page_no: this.pagination.current,
|
||||
page_size: this.pagination.size
|
||||
})
|
||||
const list = Array.isArray(res) ? res : (res.data || [])
|
||||
const total = Array.isArray(res) ? res.length : (res.count || 0)
|
||||
this.tableData = list
|
||||
this.pagination.total = total
|
||||
const data = this.normalizeResponse(res)
|
||||
this.tableData = data.list
|
||||
this.pagination.total = data.total
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
@@ -282,7 +347,7 @@ export default {
|
||||
this.fetchData()
|
||||
},
|
||||
onReset () {
|
||||
this.search = { code: '', name: '' }
|
||||
this.search = { code: '', name: '', device_category_id: '' }
|
||||
this.pagination.current = 1
|
||||
this.fetchData()
|
||||
},
|
||||
@@ -295,7 +360,7 @@ export default {
|
||||
this.selectedRows = rows
|
||||
},
|
||||
resetForm () {
|
||||
this.formData = { code: '', name: '', device_category_id: '', remark: '' }
|
||||
this.formData = { code: '', name: '', device_category_id: '', is_denglu_process: '0', remark: '' }
|
||||
this.editId = ''
|
||||
this.$nextTick(() => {
|
||||
this.formCols[0][0].disabled = false
|
||||
@@ -320,6 +385,7 @@ export default {
|
||||
code: row.code,
|
||||
name: row.name,
|
||||
device_category_id: row.device_category_id || '',
|
||||
is_denglu_process: String(row.is_denglu_process || '0'),
|
||||
remark: row.remark || ''
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
@@ -365,17 +431,17 @@ export default {
|
||||
},
|
||||
openSetting (row) {
|
||||
this.currentRowId = row.id
|
||||
this.settingTitle = this.key('preset_setting')
|
||||
this.settingType = row.device_category_code || row.device_category_name || ''
|
||||
this.settingTitle = `【${row.name}】${this.$t(this.key('preset_setting'))}`
|
||||
this.settingType = row.setting_plugin || ''
|
||||
this.settingCode = row.code
|
||||
this.settingWidth = '60%'
|
||||
this.settingPluginData = row.setting || {}
|
||||
this.settingWidth = row.setting_plugin_width ? `${row.setting_plugin_width}%` : '35%'
|
||||
this.settingPluginData = row.default_setting || {}
|
||||
this.settingVisible = true
|
||||
},
|
||||
async handleSettingSubmit (data) {
|
||||
await settingSubmit({
|
||||
id: this.currentRowId,
|
||||
setting: JSON.stringify(data)
|
||||
default_setting: JSON.stringify(data)
|
||||
})
|
||||
this.$message.success(this.$t(this.key('operation_success')))
|
||||
this.settingVisible = false
|
||||
@@ -383,7 +449,7 @@ export default {
|
||||
},
|
||||
openResult (row) {
|
||||
this.currentRowId = row.id
|
||||
this.resultTitle = this.key('preset_result_param')
|
||||
this.resultTitle = `【${row.name}】${this.$t(this.key('preset_result_param'))}`
|
||||
this.resultVisible = true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user