按组件规范重构设备模型页面
Some checks failed
Release pipeline / publish (push) Has been cancelled
Release pipeline / Always run job (push) Has been cancelled

This commit is contained in:
sheng
2026-06-22 19:03:44 +08:00
parent 8eaa5f90ca
commit 2690204ec5
15 changed files with 6148 additions and 814 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,66 +1,257 @@
<template> <template>
<d2-container> <d2-container>
<template #header><div class="search-bar"><el-form :inline="true" :model="search" size="mini"><el-form-item label="关键字"><el-input v-model.trim="search.keyword" placeholder="请输入关键字" clearable style="width:180px" @keyup.enter.native="onSearch" /></el-form-item><el-form-item><el-button type="primary" icon="el-icon-search" :disabled="loading" @click="onSearch">查询</el-button><el-button icon="el-icon-refresh" :disabled="loading" @click="onReset">重置</el-button><el-button type="primary" icon="el-icon-plus" @click="openDialog()">新增</el-button><el-button icon="el-icon-download" :disabled="loading" @click="exportTask">导出</el-button></el-form-item></el-form></div></template> <template #header>
<el-table v-loading="loading" :data="tableData" size="mini" border height="calc(100vh - 220px)"><el-table-column type="index" width="55" /><el-table-column v-for="column in displayColumns" :key="column.prop" :prop="column.prop" :label="column.label" min-width="150" show-overflow-tooltip /><el-table-column v-if="canEdit || canDelete" label="操作" fixed="right" width="150"><template slot-scope="scope"><el-button v-if="canEdit" type="text" size="mini" @click="openDialog(scope.row)">编辑</el-button><el-button v-if="canDelete" type="text" size="mini" class="danger" @click="remove(scope.row)">删除</el-button></template></el-table-column><template #empty><el-empty description="暂无数据" :image-size="80" /></template></el-table> <div class="search-bar">
<div class="pager"><el-pagination background layout="total, sizes, prev, pager, next, jumper" :current-page="pagination.current" :page-size="pagination.size" :total="pagination.total" @current-change="changePage" @size-change="changeSize" /></div> <el-form :inline="true" size="mini">
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="640px"><el-form ref="form" :model="form" label-width="130px" size="mini"><el-form-item v-for="field in formFields" :key="field.prop" :label="field.label" :prop="field.prop"><el-input v-model="form[field.prop]" clearable /></el-form-item></el-form><template #footer><el-button size="mini" @click="dialogVisible=false">取消</el-button><el-button type="primary" size="mini" :loading="saving" @click="save">确定</el-button></template></el-dialog> <el-form-item :label="$t(key('keyword'))">
<el-input
v-model="search.keyword"
:placeholder="$t(key('enter_keyword'))"
clearable
style="width:200px"
@keyup.enter.native="onSearch"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="onSearch">{{ $t(key('search')) }}</el-button>
<el-button icon="el-icon-refresh" @click="onReset">{{ $t(key('reset')) }}</el-button>
</el-form-item>
</el-form>
</div>
</template>
<page-table
ref="pageTable"
:columns="columns"
:data="tableData"
:loading="loading"
:toolbar-buttons="toolbarButtons"
:row-buttons="rowButtons"
:pagination="pagination"
auto-height
@page-change="onPageChange"
@selection-change="onSelect"
/>
<page-dialog-form
ref="dialogForm"
:visible.sync="dialogVisible"
:title="dialogTitle"
width="40%"
:form-cols="formCols"
:form-data="formData"
:rules="rules"
label-width="130px"
:submitting="submitting"
:confirm-text="key('confirm')"
:cancel-text="key('cancel')"
@submit="onDialogSubmit"
@close="onDialogClose"
/>
</d2-container> </d2-container>
</template> </template>
<script> <script>
import { useTableColumns } from '@/composables/useTableColumns'
import { useTableButtons } from '@/composables/useTableButtons'
import { i18nMixin } from '@/composables/useI18n'
import { confirmMixin } from '@/composables/useConfirmHandle'
import PageTable from '@/components/page-table'
import PageDialogForm from '@/components/page-dialog-form'
import { getList, createItem, editItem, deleteItem, createExportTask } from '@/api/equipment-management/consumables-category' import { getList, createItem, editItem, deleteItem, createExportTask } from '@/api/equipment-management/consumables-category'
export default { export default {
name: 'equipment-management-consumables-category', name: 'equipment-management-consumables-category',
components: { PageTable, PageDialogForm },
mixins: [i18nMixin('page.equipment_management.consumables_management.consumables_category'), confirmMixin],
data () { data () {
return { return {
loading: false, loading: false,
saving: false, submitting: false,
canCreate: true,
canEdit: true,
canDelete: true,
canExport: true,
search: { keyword: '' },
tableData: [], tableData: [],
selectedRows: [],
dialogVisible: false,
dialogTitle: '',
editId: '',
handleType: 'create',
search: {
keyword: ''
},
pagination: { current: 1, size: 10, total: 0 }, pagination: { current: 1, size: 10, total: 0 },
columns: [ formData: {
{ prop: 'device_consumables_category_code', label: '类别编码' }, device_consumables_category_code: '',
{ prop: 'device_consumables_category_name', label: '类别名称' }, device_consumables_category_name: '',
{ prop: 'remark', label: '备注' }, remark: ''
{ prop: 'create_time', label: '创建时间' } },
], rules: {
formFields: [ device_consumables_category_code: [{ required: true, message: this.key('enter_consumables_category_code'), trigger: 'blur' }],
{ prop: 'device_consumables_category_code', label: '类别编码' }, device_consumables_category_name: [{ required: true, message: this.key('enter_consumables_category_name'), trigger: 'blur' }]
{ prop: 'device_consumables_category_name', label: '类别名称' }, },
{ prop: 'remark', label: '备注' } columns: [],
], toolbarButtons: [],
form: {}, rowButtons: [],
dialogVisible: false formCols: [
[
{
type: 'input',
prop: 'device_consumables_category_code',
label: this.key('consumables_category_code'),
placeholder: this.key('enter_consumables_category_code'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'device_consumables_category_name',
label: this.key('consumables_category_name'),
placeholder: this.key('enter_consumables_category_name'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'remark',
label: this.key('remark'),
placeholder: this.key('enter_remark'),
inputType: 'textarea',
autosize: { minRows: 2, maxRows: 6 },
clearable: true,
style: { width: '90%' }
}
]
]
} }
}, },
computed: { dialogTitle () { return this.form && this.form.id ? '编辑设备损耗品类别' : '新增设备损耗品类别' }, displayColumns () { const keys = new Set(this.columns.map(item => item.prop)); const extra = Object.keys(this.tableData[0] || {}).filter(key => !keys.has(key) && key !== 'id').slice(0, 8).map(key => ({ prop: key, label: key })); return [...this.columns, ...extra] } }, created () {
mounted () { this.fetchData() }, this.columns = useTableColumns([
{ prop: 'device_consumables_category_code', label: this.key('consumables_category_code'), minWidth: 140 },
{ prop: 'device_consumables_category_name', label: this.key('consumables_category_name'), minWidth: 140 },
{ prop: 'remark', label: this.key('remark'), minWidth: 140 },
{ prop: 'create_time', label: this.key('create_time'), minWidth: 140 },
{ prop: '_actions', label: this.key('operation'), width: 170, fixed: 'right' }
])
const btns = useTableButtons({
toolbar: [
{ key: 'add', label: this.key('add'), icon: 'el-icon-plus', type: 'primary', auth: '/device_management/device_consumables/device_consumables_category/create', onClick: this.openAdd },
{ key: 'export', label: this.key('export'), icon: 'el-icon-download', auth: '/device_management/device_consumables/device_consumables_category/export', onClick: this.handleExport }
],
row: [
{ key: 'edit', label: this.key('edit'), icon: 'el-icon-edit', auth: '/device_management/device_consumables/device_consumables_category/edit', onClick: this.openEdit },
{ key: 'delete', label: this.key('delete'), icon: 'el-icon-delete', color: 'danger', auth: '/device_management/device_consumables/device_consumables_category/delete', onClick: this.handleDelete }
]
}, this.$permission)
this.toolbarButtons = btns.toolbarButtons
this.rowButtons = btns.rowButtons
this.fetchData()
},
methods: { methods: {
responseData (res) { return res && res.data !== undefined ? res.data : res }, normalizeResponse (res) {
normalizeList (data) { if (Array.isArray(data)) return { list: data, total: data.length }; if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }; if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) }; return { list: [], total: 0 } }, const data = res && res.data !== undefined ? res.data : res
buildParams () { return { ...this.search, page_no: this.pagination.current, page_size: this.pagination.size } }, if (Array.isArray(data)) return { list: data, total: data.length }
async fetchData () { this.loading = true; try { const res = await getList(this.buildParams()); const data = this.normalizeList(this.responseData(res)); this.tableData = data.list; this.pagination.total = data.total } finally { this.loading = false } }, if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }
onSearch () { this.pagination.current = 1; this.fetchData() }, if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) }
onReset () { this.search = { keyword: '' }; this.pagination.current = 1; this.fetchData() }, return { list: [], total: 0 }
changePage (page) { this.pagination.current = page; this.fetchData() }, },
changeSize (size) { this.pagination.size = size; this.pagination.current = 1; this.fetchData() }, async fetchData () {
openDialog (row) { this.form = row ? { ...row } : {}; this.dialogVisible = true }, this.loading = true
async save () {
this.saving = true
try { try {
if (this.form.id) await editItem(this.form) const res = await getList({ ...this.search, page_no: this.pagination.current, page_size: this.pagination.size })
else await createItem(this.form) const data = this.normalizeResponse(res)
this.$message.success('操作成功') this.tableData = data.list
this.pagination.total = data.total
} finally {
this.loading = false
}
},
onSearch () {
this.pagination.current = 1
this.fetchData()
},
onReset () {
this.search = {
keyword: ''
}
this.pagination.current = 1
this.fetchData()
},
onPageChange (page) {
this.pagination.current = page.current
this.pagination.size = page.size
this.fetchData()
},
onSelect (rows) {
this.selectedRows = rows
},
resetForm () {
this.formData = {
device_consumables_category_code: '',
device_consumables_category_name: '',
remark: ''
}
this.editId = ''
},
openAdd () {
this.handleType = 'create'
this.dialogTitle = this.key('add_title')
this.$nextTick(() => {
this.$refs.dialogForm && this.$refs.dialogForm.reset()
this.resetForm()
this.dialogVisible = true
})
},
openEdit (row) {
this.handleType = 'edit'
this.dialogTitle = this.key('edit_title')
this.editId = row.id
this.formData = {
device_consumables_category_code: row.device_consumables_category_code || '',
device_consumables_category_name: row.device_consumables_category_name || '',
remark: row.remark || ''
}
this.dialogVisible = true
},
async onDialogSubmit () {
this.submitting = true
try {
if (this.handleType === 'create') await createItem(this.formData)
else await editItem({ ...this.formData, id: this.editId })
this.$message.success(this.$t(this.key('operation_success')))
this.dialogVisible = false this.dialogVisible = false
this.fetchData() this.fetchData()
} finally { this.saving = false } } finally {
this.submitting = false
}
}, },
async remove (row) { await this.$confirm('确认删除该记录?', '提示', { type: 'warning' }); await deleteItem({ id: row.id }); this.$message.success('删除成功'); this.fetchData() }, onDialogClose () {
async exportTask () { await this.$confirm('确认创建导出任务?', '提示', { type: 'warning' }); await createExportTask(this.buildParams()); this.$message.success('导出任务创建成功') } this.resetForm()
},
async handleDelete (row) {
const cancelled = await this.$confirmAction(
{ message: this.key('confirm_delete'), title: this.key('tip') },
() => deleteItem({ id: [row.id] })
)
if (cancelled) return
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()
},
async handleExport () {
const cancelled = await this.$confirmAction(
{ message: this.key('confirm_export'), title: this.key('tip') },
() => createExportTask({ ...this.search })
)
if (cancelled) return
this.$message.success(this.$t(this.key('operation_success')))
}
} }
} }
</script> </script>
<style lang="scss" scoped>.search-bar { margin-bottom: -18px; }.pager { padding-top: 10px; text-align: right; }.danger { color: #f56c6c; }</style>
<style scoped>
.search-bar { padding: 10px 0; }
/deep/ .el-form-item--mini.el-form-item { margin-bottom: 4px; }
</style>

View File

@@ -1,69 +1,284 @@
<template> <template>
<d2-container> <d2-container>
<template #header><div class="search-bar"><el-form :inline="true" :model="search" size="mini"><el-form-item label="关键字"><el-input v-model.trim="search.keyword" placeholder="请输入关键字" clearable style="width:180px" @keyup.enter.native="onSearch" /></el-form-item><el-form-item><el-button type="primary" icon="el-icon-search" :disabled="loading" @click="onSearch">查询</el-button><el-button icon="el-icon-refresh" :disabled="loading" @click="onReset">重置</el-button><el-button type="primary" icon="el-icon-plus" @click="openDialog()">新增</el-button><el-button icon="el-icon-download" :disabled="loading" @click="exportTask">导出</el-button></el-form-item></el-form></div></template> <template #header>
<el-table v-loading="loading" :data="tableData" size="mini" border height="calc(100vh - 220px)"><el-table-column type="index" width="55" /><el-table-column v-for="column in displayColumns" :key="column.prop" :prop="column.prop" :label="column.label" min-width="150" show-overflow-tooltip /><el-table-column v-if="canEdit || canDelete" label="操作" fixed="right" width="150"><template slot-scope="scope"><el-button v-if="canEdit" type="text" size="mini" @click="openDialog(scope.row)">编辑</el-button><el-button v-if="canDelete" type="text" size="mini" class="danger" @click="remove(scope.row)">删除</el-button></template></el-table-column><template #empty><el-empty description="暂无数据" :image-size="80" /></template></el-table> <div class="search-bar">
<div class="pager"><el-pagination background layout="total, sizes, prev, pager, next, jumper" :current-page="pagination.current" :page-size="pagination.size" :total="pagination.total" @current-change="changePage" @size-change="changeSize" /></div> <el-form :inline="true" size="mini">
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="640px"><el-form ref="form" :model="form" label-width="130px" size="mini"><el-form-item v-for="field in formFields" :key="field.prop" :label="field.label" :prop="field.prop"><el-input v-model="form[field.prop]" clearable /></el-form-item></el-form><template #footer><el-button size="mini" @click="dialogVisible=false">取消</el-button><el-button type="primary" size="mini" :loading="saving" @click="save">确定</el-button></template></el-dialog> <el-form-item :label="$t(key('keyword'))">
<el-input
v-model="search.keyword"
:placeholder="$t(key('enter_keyword'))"
clearable
style="width:200px"
@keyup.enter.native="onSearch"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="onSearch">{{ $t(key('search')) }}</el-button>
<el-button icon="el-icon-refresh" @click="onReset">{{ $t(key('reset')) }}</el-button>
</el-form-item>
</el-form>
</div>
</template>
<page-table
ref="pageTable"
:columns="columns"
:data="tableData"
:loading="loading"
:toolbar-buttons="toolbarButtons"
:row-buttons="rowButtons"
:pagination="pagination"
auto-height
@page-change="onPageChange"
@selection-change="onSelect"
/>
<page-dialog-form
ref="dialogForm"
:visible.sync="dialogVisible"
:title="dialogTitle"
width="40%"
:form-cols="formCols"
:form-data="formData"
:rules="rules"
label-width="130px"
:submitting="submitting"
:confirm-text="key('confirm')"
:cancel-text="key('cancel')"
@submit="onDialogSubmit"
@close="onDialogClose"
/>
</d2-container> </d2-container>
</template> </template>
<script> <script>
import { useTableColumns } from '@/composables/useTableColumns'
import { useTableButtons } from '@/composables/useTableButtons'
import { i18nMixin } from '@/composables/useI18n'
import { confirmMixin } from '@/composables/useConfirmHandle'
import PageTable from '@/components/page-table'
import PageDialogForm from '@/components/page-dialog-form'
import { getList, createItem, editItem, deleteItem, createExportTask } from '@/api/equipment-management/consumables-items' import { getList, createItem, editItem, deleteItem, createExportTask } from '@/api/equipment-management/consumables-items'
export default { export default {
name: 'equipment-management-consumables-items', name: 'equipment-management-consumables-items',
components: { PageTable, PageDialogForm },
mixins: [i18nMixin('page.equipment_management.consumables_management.consumables_items'), confirmMixin],
data () { data () {
return { return {
loading: false, loading: false,
saving: false, submitting: false,
canCreate: true,
canEdit: true,
canDelete: true,
canExport: true,
search: { keyword: '' },
tableData: [], tableData: [],
selectedRows: [],
dialogVisible: false,
dialogTitle: '',
editId: '',
handleType: 'create',
search: {
keyword: ''
},
pagination: { current: 1, size: 10, total: 0 }, pagination: { current: 1, size: 10, total: 0 },
columns: [ formData: {
{ prop: 'device_consumables_item_code', label: '损耗品编码' }, device_consumables_item_code: '',
{ prop: 'device_consumables_item_name', label: '损耗品名称' }, device_consumables_item_name: '',
{ prop: 'device_consumables_category_name', label: '损耗品类别' }, device_consumables_category_id: '',
{ prop: 'specification', label: '规格' }, specification: '',
{ prop: 'remark', label: '备注' } remark: ''
], },
formFields: [ rules: {
{ prop: 'device_consumables_item_code', label: '损耗品编码' }, device_consumables_item_code: [{ required: true, message: this.key('enter_consumables_item_code'), trigger: 'blur' }],
{ prop: 'device_consumables_item_name', label: '损耗品名称' }, device_consumables_item_name: [{ required: true, message: this.key('enter_consumables_item_name'), trigger: 'blur' }]
{ prop: 'device_consumables_category_id', label: '类别ID' }, },
{ prop: 'specification', label: '规格' }, columns: [],
{ prop: 'remark', label: '备注' } toolbarButtons: [],
], rowButtons: [],
form: {}, formCols: [
dialogVisible: false [
{
type: 'input',
prop: 'device_consumables_item_code',
label: this.key('consumables_item_code'),
placeholder: this.key('enter_consumables_item_code'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'device_consumables_item_name',
label: this.key('consumables_item_name'),
placeholder: this.key('enter_consumables_item_name'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'device_consumables_category_id',
label: this.key('consumables_category_id'),
placeholder: this.key('enter_consumables_category_id'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'specification',
label: this.key('specification'),
placeholder: this.key('enter_specification'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'remark',
label: this.key('remark'),
placeholder: this.key('enter_remark'),
inputType: 'textarea',
autosize: { minRows: 2, maxRows: 6 },
clearable: true,
style: { width: '90%' }
}
]
]
} }
}, },
computed: { dialogTitle () { return this.form && this.form.id ? '编辑设备损耗品项目' : '新增设备损耗品项目' }, displayColumns () { const keys = new Set(this.columns.map(item => item.prop)); const extra = Object.keys(this.tableData[0] || {}).filter(key => !keys.has(key) && key !== 'id').slice(0, 8).map(key => ({ prop: key, label: key })); return [...this.columns, ...extra] } }, created () {
mounted () { this.fetchData() }, this.columns = useTableColumns([
{ prop: 'device_consumables_item_code', label: this.key('consumables_item_code'), minWidth: 140 },
{ prop: 'device_consumables_item_name', label: this.key('consumables_item_name'), minWidth: 140 },
{ prop: 'device_consumables_category_name', label: this.key('consumables_category'), minWidth: 140 },
{ prop: 'specification', label: this.key('specification'), minWidth: 140 },
{ prop: 'remark', label: this.key('remark'), minWidth: 140 },
{ prop: '_actions', label: this.key('operation'), width: 170, fixed: 'right' }
])
const btns = useTableButtons({
toolbar: [
{ key: 'add', label: this.key('add'), icon: 'el-icon-plus', type: 'primary', auth: '/device_management/device_consumables/device_consumables_items/create', onClick: this.openAdd },
{ key: 'export', label: this.key('export'), icon: 'el-icon-download', auth: '/device_management/device_consumables/device_consumables_items/export', onClick: this.handleExport }
],
row: [
{ key: 'edit', label: this.key('edit'), icon: 'el-icon-edit', auth: '/device_management/device_consumables/device_consumables_items/edit', onClick: this.openEdit },
{ key: 'delete', label: this.key('delete'), icon: 'el-icon-delete', color: 'danger', auth: '/device_management/device_consumables/device_consumables_items/delete', onClick: this.handleDelete }
]
}, this.$permission)
this.toolbarButtons = btns.toolbarButtons
this.rowButtons = btns.rowButtons
this.fetchData()
},
methods: { methods: {
responseData (res) { return res && res.data !== undefined ? res.data : res }, normalizeResponse (res) {
normalizeList (data) { if (Array.isArray(data)) return { list: data, total: data.length }; if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }; if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) }; return { list: [], total: 0 } }, const data = res && res.data !== undefined ? res.data : res
buildParams () { return { ...this.search, page_no: this.pagination.current, page_size: this.pagination.size } }, if (Array.isArray(data)) return { list: data, total: data.length }
async fetchData () { this.loading = true; try { const res = await getList(this.buildParams()); const data = this.normalizeList(this.responseData(res)); this.tableData = data.list; this.pagination.total = data.total } finally { this.loading = false } }, if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }
onSearch () { this.pagination.current = 1; this.fetchData() }, if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) }
onReset () { this.search = { keyword: '' }; this.pagination.current = 1; this.fetchData() }, return { list: [], total: 0 }
changePage (page) { this.pagination.current = page; this.fetchData() }, },
changeSize (size) { this.pagination.size = size; this.pagination.current = 1; this.fetchData() }, async fetchData () {
openDialog (row) { this.form = row ? { ...row } : {}; this.dialogVisible = true }, this.loading = true
async save () {
this.saving = true
try { try {
if (this.form.id) await editItem(this.form) const res = await getList({ ...this.search, page_no: this.pagination.current, page_size: this.pagination.size })
else await createItem(this.form) const data = this.normalizeResponse(res)
this.$message.success('操作成功') this.tableData = data.list
this.pagination.total = data.total
} finally {
this.loading = false
}
},
onSearch () {
this.pagination.current = 1
this.fetchData()
},
onReset () {
this.search = {
keyword: ''
}
this.pagination.current = 1
this.fetchData()
},
onPageChange (page) {
this.pagination.current = page.current
this.pagination.size = page.size
this.fetchData()
},
onSelect (rows) {
this.selectedRows = rows
},
resetForm () {
this.formData = {
device_consumables_item_code: '',
device_consumables_item_name: '',
device_consumables_category_id: '',
specification: '',
remark: ''
}
this.editId = ''
},
openAdd () {
this.handleType = 'create'
this.dialogTitle = this.key('add_title')
this.$nextTick(() => {
this.$refs.dialogForm && this.$refs.dialogForm.reset()
this.resetForm()
this.dialogVisible = true
})
},
openEdit (row) {
this.handleType = 'edit'
this.dialogTitle = this.key('edit_title')
this.editId = row.id
this.formData = {
device_consumables_item_code: row.device_consumables_item_code || '',
device_consumables_item_name: row.device_consumables_item_name || '',
device_consumables_category_id: row.device_consumables_category_id || '',
specification: row.specification || '',
remark: row.remark || ''
}
this.dialogVisible = true
},
async onDialogSubmit () {
this.submitting = true
try {
if (this.handleType === 'create') await createItem(this.formData)
else await editItem({ ...this.formData, id: this.editId })
this.$message.success(this.$t(this.key('operation_success')))
this.dialogVisible = false this.dialogVisible = false
this.fetchData() this.fetchData()
} finally { this.saving = false } } finally {
this.submitting = false
}
}, },
async remove (row) { await this.$confirm('确认删除该记录?', '提示', { type: 'warning' }); await deleteItem({ id: row.id }); this.$message.success('删除成功'); this.fetchData() }, onDialogClose () {
async exportTask () { await this.$confirm('确认创建导出任务?', '提示', { type: 'warning' }); await createExportTask(this.buildParams()); this.$message.success('导出任务创建成功') } this.resetForm()
},
async handleDelete (row) {
const cancelled = await this.$confirmAction(
{ message: this.key('confirm_delete'), title: this.key('tip') },
() => deleteItem({ id: [row.id] })
)
if (cancelled) return
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()
},
async handleExport () {
const cancelled = await this.$confirmAction(
{ message: this.key('confirm_export'), title: this.key('tip') },
() => createExportTask({ ...this.search })
)
if (cancelled) return
this.$message.success(this.$t(this.key('operation_success')))
}
} }
} }
</script> </script>
<style lang="scss" scoped>.search-bar { margin-bottom: -18px; }.pager { padding-top: 10px; text-align: right; }.danger { color: #f56c6c; }</style>
<style scoped>
.search-bar { padding: 10px 0; }
/deep/ .el-form-item--mini.el-form-item { margin-bottom: 4px; }
</style>

View File

@@ -1,71 +1,298 @@
<template> <template>
<d2-container> <d2-container>
<template #header><div class="search-bar"><el-form :inline="true" :model="search" size="mini"><el-form-item label="关键字"><el-input v-model.trim="search.keyword" placeholder="请输入关键字" clearable style="width:180px" @keyup.enter.native="onSearch" /></el-form-item><el-form-item><el-button type="primary" icon="el-icon-search" :disabled="loading" @click="onSearch">查询</el-button><el-button icon="el-icon-refresh" :disabled="loading" @click="onReset">重置</el-button><el-button type="primary" icon="el-icon-plus" @click="openDialog()">新增</el-button><el-button icon="el-icon-download" :disabled="loading" @click="exportTask">导出</el-button></el-form-item></el-form></div></template> <template #header>
<el-table v-loading="loading" :data="tableData" size="mini" border height="calc(100vh - 220px)"><el-table-column type="index" width="55" /><el-table-column v-for="column in displayColumns" :key="column.prop" :prop="column.prop" :label="column.label" min-width="150" show-overflow-tooltip /><el-table-column v-if="canEdit || canDelete" label="操作" fixed="right" width="150"><template slot-scope="scope"><el-button v-if="canEdit" type="text" size="mini" @click="openDialog(scope.row)">编辑</el-button><el-button v-if="canDelete" type="text" size="mini" class="danger" @click="remove(scope.row)">删除</el-button></template></el-table-column><template #empty><el-empty description="暂无数据" :image-size="80" /></template></el-table> <div class="search-bar">
<div class="pager"><el-pagination background layout="total, sizes, prev, pager, next, jumper" :current-page="pagination.current" :page-size="pagination.size" :total="pagination.total" @current-change="changePage" @size-change="changeSize" /></div> <el-form :inline="true" size="mini">
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="640px"><el-form ref="form" :model="form" label-width="130px" size="mini"><el-form-item v-for="field in formFields" :key="field.prop" :label="field.label" :prop="field.prop"><el-input v-model="form[field.prop]" clearable /></el-form-item></el-form><template #footer><el-button size="mini" @click="dialogVisible=false">取消</el-button><el-button type="primary" size="mini" :loading="saving" @click="save">确定</el-button></template></el-dialog> <el-form-item :label="$t(key('keyword'))">
<el-input
v-model="search.keyword"
:placeholder="$t(key('enter_keyword'))"
clearable
style="width:200px"
@keyup.enter.native="onSearch"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="onSearch">{{ $t(key('search')) }}</el-button>
<el-button icon="el-icon-refresh" @click="onReset">{{ $t(key('reset')) }}</el-button>
</el-form-item>
</el-form>
</div>
</template>
<page-table
ref="pageTable"
:columns="columns"
:data="tableData"
:loading="loading"
:toolbar-buttons="toolbarButtons"
:row-buttons="rowButtons"
:pagination="pagination"
auto-height
@page-change="onPageChange"
@selection-change="onSelect"
/>
<page-dialog-form
ref="dialogForm"
:visible.sync="dialogVisible"
:title="dialogTitle"
width="40%"
:form-cols="formCols"
:form-data="formData"
:rules="rules"
label-width="130px"
:submitting="submitting"
:confirm-text="key('confirm')"
:cancel-text="key('cancel')"
@submit="onDialogSubmit"
@close="onDialogClose"
/>
</d2-container> </d2-container>
</template> </template>
<script> <script>
import { useTableColumns } from '@/composables/useTableColumns'
import { useTableButtons } from '@/composables/useTableButtons'
import { i18nMixin } from '@/composables/useI18n'
import { confirmMixin } from '@/composables/useConfirmHandle'
import PageTable from '@/components/page-table'
import PageDialogForm from '@/components/page-dialog-form'
import { getList, createItem, editItem, deleteItem, createExportTask } from '@/api/equipment-management/consumables-lifecycle' import { getList, createItem, editItem, deleteItem, createExportTask } from '@/api/equipment-management/consumables-lifecycle'
export default { export default {
name: 'equipment-management-consumables-lifecycle', name: 'equipment-management-consumables-lifecycle',
components: { PageTable, PageDialogForm },
mixins: [i18nMixin('page.equipment_management.consumables_management.consumables_lifecycle'), confirmMixin],
data () { data () {
return { return {
loading: false, loading: false,
saving: false, submitting: false,
canCreate: true,
canEdit: true,
canDelete: true,
canExport: true,
search: { keyword: '' },
tableData: [], tableData: [],
selectedRows: [],
dialogVisible: false,
dialogTitle: '',
editId: '',
handleType: 'create',
search: {
keyword: ''
},
pagination: { current: 1, size: 10, total: 0 }, pagination: { current: 1, size: 10, total: 0 },
columns: [ formData: {
{ prop: 'device_consumables_item_name', label: '损耗品项目' }, device_consumables_item_id: '',
{ prop: 'device_name', label: '关联设备' }, device_id: '',
{ prop: 'standard_life', label: '标准寿命' }, standard_life: '',
{ prop: 'warning_life', label: '预警寿命' }, warning_life: '',
{ prop: 'used_life', label: '已用寿命' }, used_life: '',
{ prop: 'replace_time', label: '更换时间' } remark: ''
], },
formFields: [ rules: {
{ prop: 'device_consumables_item_id', label: '损耗品项目ID' }, device_consumables_item_id: [{ required: true, message: this.key('enter_consumables_item_id'), trigger: 'blur' }],
{ prop: 'device_id', label: '设备ID' }, device_id: [{ required: true, message: this.key('enter_device_id'), trigger: 'blur' }]
{ prop: 'standard_life', label: '标准寿命' }, },
{ prop: 'warning_life', label: '预警寿命' }, columns: [],
{ prop: 'used_life', label: '已用寿命' }, toolbarButtons: [],
{ prop: 'remark', label: '备注' } rowButtons: [],
], formCols: [
form: {}, [
dialogVisible: false {
type: 'input',
prop: 'device_consumables_item_id',
label: this.key('consumables_item_id'),
placeholder: this.key('enter_consumables_item_id'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'device_id',
label: this.key('device_id'),
placeholder: this.key('enter_device_id'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'standard_life',
label: this.key('standard_life'),
placeholder: this.key('enter_standard_life'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'warning_life',
label: this.key('warning_life'),
placeholder: this.key('enter_warning_life'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'used_life',
label: this.key('used_life'),
placeholder: this.key('enter_used_life'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'remark',
label: this.key('remark'),
placeholder: this.key('enter_remark'),
inputType: 'textarea',
autosize: { minRows: 2, maxRows: 6 },
clearable: true,
style: { width: '90%' }
}
]
]
} }
}, },
computed: { dialogTitle () { return this.form && this.form.id ? '编辑设备损耗品寿命管理' : '新增设备损耗品寿命管理' }, displayColumns () { const keys = new Set(this.columns.map(item => item.prop)); const extra = Object.keys(this.tableData[0] || {}).filter(key => !keys.has(key) && key !== 'id').slice(0, 8).map(key => ({ prop: key, label: key })); return [...this.columns, ...extra] } }, created () {
mounted () { this.fetchData() }, this.columns = useTableColumns([
{ prop: 'device_consumables_item_name', label: this.key('consumables_item'), minWidth: 140 },
{ prop: 'device_name', label: this.key('device_name'), minWidth: 140 },
{ prop: 'standard_life', label: this.key('standard_life'), minWidth: 140 },
{ prop: 'warning_life', label: this.key('warning_life'), minWidth: 140 },
{ prop: 'used_life', label: this.key('used_life'), minWidth: 140 },
{ prop: 'replace_time', label: this.key('replace_time'), minWidth: 140 },
{ prop: '_actions', label: this.key('operation'), width: 170, fixed: 'right' }
])
const btns = useTableButtons({
toolbar: [
{ key: 'add', label: this.key('add'), icon: 'el-icon-plus', type: 'primary', auth: '/device_management/device_consumables/device_consumables_lifetime_management/create', onClick: this.openAdd },
{ key: 'export', label: this.key('export'), icon: 'el-icon-download', auth: '/device_management/device_consumables/device_consumables_lifetime_management/export', onClick: this.handleExport }
],
row: [
{ key: 'edit', label: this.key('edit'), icon: 'el-icon-edit', auth: '/device_management/device_consumables/device_consumables_lifetime_management/edit', onClick: this.openEdit },
{ key: 'delete', label: this.key('delete'), icon: 'el-icon-delete', color: 'danger', auth: '/device_management/device_consumables/device_consumables_lifetime_management/delete', onClick: this.handleDelete }
]
}, this.$permission)
this.toolbarButtons = btns.toolbarButtons
this.rowButtons = btns.rowButtons
this.fetchData()
},
methods: { methods: {
responseData (res) { return res && res.data !== undefined ? res.data : res }, normalizeResponse (res) {
normalizeList (data) { if (Array.isArray(data)) return { list: data, total: data.length }; if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }; if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) }; return { list: [], total: 0 } }, const data = res && res.data !== undefined ? res.data : res
buildParams () { return { ...this.search, page_no: this.pagination.current, page_size: this.pagination.size } }, if (Array.isArray(data)) return { list: data, total: data.length }
async fetchData () { this.loading = true; try { const res = await getList(this.buildParams()); const data = this.normalizeList(this.responseData(res)); this.tableData = data.list; this.pagination.total = data.total } finally { this.loading = false } }, if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }
onSearch () { this.pagination.current = 1; this.fetchData() }, if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) }
onReset () { this.search = { keyword: '' }; this.pagination.current = 1; this.fetchData() }, return { list: [], total: 0 }
changePage (page) { this.pagination.current = page; this.fetchData() }, },
changeSize (size) { this.pagination.size = size; this.pagination.current = 1; this.fetchData() }, async fetchData () {
openDialog (row) { this.form = row ? { ...row } : {}; this.dialogVisible = true }, this.loading = true
async save () {
this.saving = true
try { try {
if (this.form.id) await editItem(this.form) const res = await getList({ ...this.search, page_no: this.pagination.current, page_size: this.pagination.size })
else await createItem(this.form) const data = this.normalizeResponse(res)
this.$message.success('操作成功') this.tableData = data.list
this.pagination.total = data.total
} finally {
this.loading = false
}
},
onSearch () {
this.pagination.current = 1
this.fetchData()
},
onReset () {
this.search = {
keyword: ''
}
this.pagination.current = 1
this.fetchData()
},
onPageChange (page) {
this.pagination.current = page.current
this.pagination.size = page.size
this.fetchData()
},
onSelect (rows) {
this.selectedRows = rows
},
resetForm () {
this.formData = {
device_consumables_item_id: '',
device_id: '',
standard_life: '',
warning_life: '',
used_life: '',
remark: ''
}
this.editId = ''
},
openAdd () {
this.handleType = 'create'
this.dialogTitle = this.key('add_title')
this.$nextTick(() => {
this.$refs.dialogForm && this.$refs.dialogForm.reset()
this.resetForm()
this.dialogVisible = true
})
},
openEdit (row) {
this.handleType = 'edit'
this.dialogTitle = this.key('edit_title')
this.editId = row.id
this.formData = {
device_consumables_item_id: row.device_consumables_item_id || '',
device_id: row.device_id || '',
standard_life: row.standard_life || '',
warning_life: row.warning_life || '',
used_life: row.used_life || '',
remark: row.remark || ''
}
this.dialogVisible = true
},
async onDialogSubmit () {
this.submitting = true
try {
if (this.handleType === 'create') await createItem(this.formData)
else await editItem({ ...this.formData, id: this.editId })
this.$message.success(this.$t(this.key('operation_success')))
this.dialogVisible = false this.dialogVisible = false
this.fetchData() this.fetchData()
} finally { this.saving = false } } finally {
this.submitting = false
}
}, },
async remove (row) { await this.$confirm('确认删除该记录?', '提示', { type: 'warning' }); await deleteItem({ id: row.id }); this.$message.success('删除成功'); this.fetchData() }, onDialogClose () {
async exportTask () { await this.$confirm('确认创建导出任务?', '提示', { type: 'warning' }); await createExportTask(this.buildParams()); this.$message.success('导出任务创建成功') } this.resetForm()
},
async handleDelete (row) {
const cancelled = await this.$confirmAction(
{ message: this.key('confirm_delete'), title: this.key('tip') },
() => deleteItem({ id: [row.id] })
)
if (cancelled) return
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()
},
async handleExport () {
const cancelled = await this.$confirmAction(
{ message: this.key('confirm_export'), title: this.key('tip') },
() => createExportTask({ ...this.search })
)
if (cancelled) return
this.$message.success(this.$t(this.key('operation_success')))
}
} }
} }
</script> </script>
<style lang="scss" scoped>.search-bar { margin-bottom: -18px; }.pager { padding-top: 10px; text-align: right; }.danger { color: #f56c6c; }</style>
<style scoped>
.search-bar { padding: 10px 0; }
/deep/ .el-form-item--mini.el-form-item { margin-bottom: 4px; }
</style>

View File

@@ -1,72 +1,311 @@
<template> <template>
<d2-container> <d2-container>
<template #header><div class="search-bar"><el-form :inline="true" :model="search" size="mini"><el-form-item label="关键字"><el-input v-model.trim="search.keyword" placeholder="请输入关键字" clearable style="width:180px" @keyup.enter.native="onSearch" /></el-form-item><el-form-item><el-button type="primary" icon="el-icon-search" :disabled="loading" @click="onSearch">查询</el-button><el-button icon="el-icon-refresh" :disabled="loading" @click="onReset">重置</el-button><el-button type="primary" icon="el-icon-plus" @click="openDialog()">新增</el-button><el-button icon="el-icon-download" :disabled="loading" @click="exportTask">导出</el-button></el-form-item></el-form></div></template> <template #header>
<el-table v-loading="loading" :data="tableData" size="mini" border height="calc(100vh - 220px)"><el-table-column type="index" width="55" /><el-table-column v-for="column in displayColumns" :key="column.prop" :prop="column.prop" :label="column.label" min-width="150" show-overflow-tooltip /><el-table-column v-if="canEdit || canDelete" label="操作" fixed="right" width="150"><template slot-scope="scope"><el-button v-if="canEdit" type="text" size="mini" @click="openDialog(scope.row)">编辑</el-button><el-button v-if="canDelete" type="text" size="mini" class="danger" @click="remove(scope.row)">删除</el-button></template></el-table-column><template #empty><el-empty description="暂无数据" :image-size="80" /></template></el-table> <div class="search-bar">
<div class="pager"><el-pagination background layout="total, sizes, prev, pager, next, jumper" :current-page="pagination.current" :page-size="pagination.size" :total="pagination.total" @current-change="changePage" @size-change="changeSize" /></div> <el-form :inline="true" size="mini">
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="640px"><el-form ref="form" :model="form" label-width="130px" size="mini"><el-form-item v-for="field in formFields" :key="field.prop" :label="field.label" :prop="field.prop"><el-input v-model="form[field.prop]" clearable /></el-form-item></el-form><template #footer><el-button size="mini" @click="dialogVisible=false">取消</el-button><el-button type="primary" size="mini" :loading="saving" @click="save">确定</el-button></template></el-dialog> <el-form-item :label="$t(key('keyword'))">
<el-input
v-model="search.keyword"
:placeholder="$t(key('enter_keyword'))"
clearable
style="width:200px"
@keyup.enter.native="onSearch"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="onSearch">{{ $t(key('search')) }}</el-button>
<el-button icon="el-icon-refresh" @click="onReset">{{ $t(key('reset')) }}</el-button>
</el-form-item>
</el-form>
</div>
</template>
<page-table
ref="pageTable"
:columns="columns"
:data="tableData"
:loading="loading"
:toolbar-buttons="toolbarButtons"
:row-buttons="rowButtons"
:pagination="pagination"
auto-height
@page-change="onPageChange"
@selection-change="onSelect"
/>
<page-dialog-form
ref="dialogForm"
:visible.sync="dialogVisible"
:title="dialogTitle"
width="40%"
:form-cols="formCols"
:form-data="formData"
:rules="rules"
label-width="130px"
:submitting="submitting"
:confirm-text="key('confirm')"
:cancel-text="key('cancel')"
@submit="onDialogSubmit"
@close="onDialogClose"
/>
</d2-container> </d2-container>
</template> </template>
<script> <script>
import { useTableColumns } from '@/composables/useTableColumns'
import { useTableButtons } from '@/composables/useTableButtons'
import { i18nMixin } from '@/composables/useI18n'
import { confirmMixin } from '@/composables/useConfirmHandle'
import PageTable from '@/components/page-table'
import PageDialogForm from '@/components/page-dialog-form'
import { getList, createItem, editItem, deleteItem, createExportTask } from '@/api/equipment-management/replacement-logs' import { getList, createItem, editItem, deleteItem, createExportTask } from '@/api/equipment-management/replacement-logs'
export default { export default {
name: 'equipment-management-replacement-logs', name: 'equipment-management-replacement-logs',
components: { PageTable, PageDialogForm },
mixins: [i18nMixin('page.equipment_management.consumables_management.replacement_logs'), confirmMixin],
data () { data () {
return { return {
loading: false, loading: false,
saving: false, submitting: false,
canCreate: true,
canEdit: true,
canDelete: true,
canExport: true,
search: { keyword: '' },
tableData: [], tableData: [],
selectedRows: [],
dialogVisible: false,
dialogTitle: '',
editId: '',
handleType: 'create',
search: {
keyword: ''
},
pagination: { current: 1, size: 10, total: 0 }, pagination: { current: 1, size: 10, total: 0 },
columns: [ formData: {
{ prop: 'device_consumables_item_name', label: '损耗品项目' }, device_consumables_item_id: '',
{ prop: 'device_name', label: '关联设备' }, device_id: '',
{ prop: 'replace_user', label: '更换人员' }, replace_user: '',
{ prop: 'replace_time', label: '更换时间' }, replace_time: '',
{ prop: 'replace_reason', label: '更换原因' }, replace_reason: '',
{ prop: 'replace_duration', label: '更换耗时' } replace_duration: '',
], remark: ''
formFields: [ },
{ prop: 'device_consumables_item_id', label: '损耗品项目ID' }, rules: {
{ prop: 'device_id', label: '设备ID' }, device_consumables_item_id: [{ required: true, message: this.key('enter_consumables_item_id'), trigger: 'blur' }],
{ prop: 'replace_user', label: '更换人员' }, device_id: [{ required: true, message: this.key('enter_device_id'), trigger: 'blur' }]
{ prop: 'replace_time', label: '更换时间' }, },
{ prop: 'replace_reason', label: '更换原因' }, columns: [],
{ prop: 'replace_duration', label: '更换耗时' }, toolbarButtons: [],
{ prop: 'remark', label: '备注' } rowButtons: [],
], formCols: [
form: {}, [
dialogVisible: false {
type: 'input',
prop: 'device_consumables_item_id',
label: this.key('consumables_item_id'),
placeholder: this.key('enter_consumables_item_id'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'device_id',
label: this.key('device_id'),
placeholder: this.key('enter_device_id'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'replace_user',
label: this.key('replace_user'),
placeholder: this.key('enter_replace_user'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'replace_time',
label: this.key('replace_time'),
placeholder: this.key('enter_replace_time'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'replace_reason',
label: this.key('replace_reason'),
placeholder: this.key('enter_replace_reason'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'replace_duration',
label: this.key('replace_duration'),
placeholder: this.key('enter_replace_duration'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'remark',
label: this.key('remark'),
placeholder: this.key('enter_remark'),
inputType: 'textarea',
autosize: { minRows: 2, maxRows: 6 },
clearable: true,
style: { width: '90%' }
}
]
]
} }
}, },
computed: { dialogTitle () { return this.form && this.form.id ? '编辑设备损耗品更换日志' : '新增设备损耗品更换日志' }, displayColumns () { const keys = new Set(this.columns.map(item => item.prop)); const extra = Object.keys(this.tableData[0] || {}).filter(key => !keys.has(key) && key !== 'id').slice(0, 8).map(key => ({ prop: key, label: key })); return [...this.columns, ...extra] } }, created () {
mounted () { this.fetchData() }, this.columns = useTableColumns([
{ prop: 'device_consumables_item_name', label: this.key('consumables_item'), minWidth: 140 },
{ prop: 'device_name', label: this.key('device_name'), minWidth: 140 },
{ prop: 'replace_user', label: this.key('replace_user'), minWidth: 140 },
{ prop: 'replace_time', label: this.key('replace_time'), minWidth: 140 },
{ prop: 'replace_reason', label: this.key('replace_reason'), minWidth: 140 },
{ prop: 'replace_duration', label: this.key('replace_duration'), minWidth: 140 },
{ prop: '_actions', label: this.key('operation'), width: 170, fixed: 'right' }
])
const btns = useTableButtons({
toolbar: [
{ key: 'add', label: this.key('add'), icon: 'el-icon-plus', type: 'primary', auth: '/device_management/device_consumables/device_consumables_replace_log/create', onClick: this.openAdd },
{ key: 'export', label: this.key('export'), icon: 'el-icon-download', auth: '/device_management/device_consumables/device_consumables_replace_log/export', onClick: this.handleExport }
],
row: [
{ key: 'edit', label: this.key('edit'), icon: 'el-icon-edit', auth: '/device_management/device_consumables/device_consumables_replace_log/edit', onClick: this.openEdit },
{ key: 'delete', label: this.key('delete'), icon: 'el-icon-delete', color: 'danger', auth: '/device_management/device_consumables/device_consumables_replace_log/delete', onClick: this.handleDelete }
]
}, this.$permission)
this.toolbarButtons = btns.toolbarButtons
this.rowButtons = btns.rowButtons
this.fetchData()
},
methods: { methods: {
responseData (res) { return res && res.data !== undefined ? res.data : res }, normalizeResponse (res) {
normalizeList (data) { if (Array.isArray(data)) return { list: data, total: data.length }; if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }; if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) }; return { list: [], total: 0 } }, const data = res && res.data !== undefined ? res.data : res
buildParams () { return { ...this.search, page_no: this.pagination.current, page_size: this.pagination.size } }, if (Array.isArray(data)) return { list: data, total: data.length }
async fetchData () { this.loading = true; try { const res = await getList(this.buildParams()); const data = this.normalizeList(this.responseData(res)); this.tableData = data.list; this.pagination.total = data.total } finally { this.loading = false } }, if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }
onSearch () { this.pagination.current = 1; this.fetchData() }, if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) }
onReset () { this.search = { keyword: '' }; this.pagination.current = 1; this.fetchData() }, return { list: [], total: 0 }
changePage (page) { this.pagination.current = page; this.fetchData() }, },
changeSize (size) { this.pagination.size = size; this.pagination.current = 1; this.fetchData() }, async fetchData () {
openDialog (row) { this.form = row ? { ...row } : {}; this.dialogVisible = true }, this.loading = true
async save () {
this.saving = true
try { try {
if (this.form.id) await editItem(this.form) const res = await getList({ ...this.search, page_no: this.pagination.current, page_size: this.pagination.size })
else await createItem(this.form) const data = this.normalizeResponse(res)
this.$message.success('操作成功') this.tableData = data.list
this.pagination.total = data.total
} finally {
this.loading = false
}
},
onSearch () {
this.pagination.current = 1
this.fetchData()
},
onReset () {
this.search = {
keyword: ''
}
this.pagination.current = 1
this.fetchData()
},
onPageChange (page) {
this.pagination.current = page.current
this.pagination.size = page.size
this.fetchData()
},
onSelect (rows) {
this.selectedRows = rows
},
resetForm () {
this.formData = {
device_consumables_item_id: '',
device_id: '',
replace_user: '',
replace_time: '',
replace_reason: '',
replace_duration: '',
remark: ''
}
this.editId = ''
},
openAdd () {
this.handleType = 'create'
this.dialogTitle = this.key('add_title')
this.$nextTick(() => {
this.$refs.dialogForm && this.$refs.dialogForm.reset()
this.resetForm()
this.dialogVisible = true
})
},
openEdit (row) {
this.handleType = 'edit'
this.dialogTitle = this.key('edit_title')
this.editId = row.id
this.formData = {
device_consumables_item_id: row.device_consumables_item_id || '',
device_id: row.device_id || '',
replace_user: row.replace_user || '',
replace_time: row.replace_time || '',
replace_reason: row.replace_reason || '',
replace_duration: row.replace_duration || '',
remark: row.remark || ''
}
this.dialogVisible = true
},
async onDialogSubmit () {
this.submitting = true
try {
if (this.handleType === 'create') await createItem(this.formData)
else await editItem({ ...this.formData, id: this.editId })
this.$message.success(this.$t(this.key('operation_success')))
this.dialogVisible = false this.dialogVisible = false
this.fetchData() this.fetchData()
} finally { this.saving = false } } finally {
this.submitting = false
}
}, },
async remove (row) { await this.$confirm('确认删除该记录?', '提示', { type: 'warning' }); await deleteItem({ id: row.id }); this.$message.success('删除成功'); this.fetchData() }, onDialogClose () {
async exportTask () { await this.$confirm('确认创建导出任务?', '提示', { type: 'warning' }); await createExportTask(this.buildParams()); this.$message.success('导出任务创建成功') } this.resetForm()
},
async handleDelete (row) {
const cancelled = await this.$confirmAction(
{ message: this.key('confirm_delete'), title: this.key('tip') },
() => deleteItem({ id: [row.id] })
)
if (cancelled) return
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()
},
async handleExport () {
const cancelled = await this.$confirmAction(
{ message: this.key('confirm_export'), title: this.key('tip') },
() => createExportTask({ ...this.search })
)
if (cancelled) return
this.$message.success(this.$t(this.key('operation_success')))
}
} }
} }
</script> </script>
<style lang="scss" scoped>.search-bar { margin-bottom: -18px; }.pager { padding-top: 10px; text-align: right; }.danger { color: #f56c6c; }</style>
<style scoped>
.search-bar { padding: 10px 0; }
/deep/ .el-form-item--mini.el-form-item { margin-bottom: 4px; }
</style>

View File

@@ -2,185 +2,322 @@
<d2-container> <d2-container>
<template #header> <template #header>
<div class="search-bar"> <div class="search-bar">
<el-form :inline="true" :model="search" size="mini"> <el-form :inline="true" size="mini">
<el-form-item label="关键字"> <el-form-item :label="$t(key('device_code'))">
<el-input v-model.trim="search.keyword" placeholder="请输入关键字" clearable style="width:180px" @keyup.enter.native="onSearch" /> <el-input
v-model="search.device_code"
:placeholder="$t(key('enter_device_code'))"
clearable
style="width:200px"
@keyup.enter.native="onSearch"
/>
</el-form-item>
<el-form-item :label="$t(key('device_name'))">
<el-input
v-model="search.device_name"
:placeholder="$t(key('enter_device_name'))"
clearable
style="width:200px"
@keyup.enter.native="onSearch"
/>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" icon="el-icon-search" :disabled="loading" @click="onSearch">查询</el-button> <el-button type="primary" icon="el-icon-search" @click="onSearch">{{ $t(key('search')) }}</el-button>
<el-button icon="el-icon-refresh" :disabled="loading" @click="onReset">重置</el-button> <el-button icon="el-icon-refresh" @click="onReset">{{ $t(key('reset')) }}</el-button>
<el-button type="primary" icon="el-icon-plus" @click="openDialog()">新增</el-button>
<el-button v-if="hasExport" icon="el-icon-download" :disabled="loading" @click="exportTask">导出</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
</template> </template>
<el-table v-loading="loading" :data="tableData" size="mini" border height="calc(100vh - 220px)"> <page-table
<el-table-column type="index" width="55" /> ref="pageTable"
<el-table-column v-for="column in displayColumns" :key="column.prop" :prop="column.prop" :label="column.label" min-width="150" show-overflow-tooltip /> :columns="columns"
<el-table-column label="操作" fixed="right" width="150"> :data="tableData"
<template slot-scope="scope"> :loading="loading"
<el-button type="text" size="mini" @click="openDialog(scope.row)">编辑</el-button> :toolbar-buttons="toolbarButtons"
<el-button type="text" size="mini" class="danger" @click="remove(scope.row)">删除</el-button> :row-buttons="rowButtons"
</template> :pagination="pagination"
</el-table-column> auto-height
<template #empty><el-empty description="暂无数据" :image-size="80" /></template> @page-change="onPageChange"
</el-table> @selection-change="onSelect"
<div class="pager"> />
<el-pagination background layout="total, sizes, prev, pager, next, jumper" :current-page="pagination.current" :page-size="pagination.size" :total="pagination.total" @current-change="changePage" @size-change="changeSize" />
</div>
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="640px"> <page-dialog-form
<el-form ref="form" :model="form" label-width="120px" size="mini"> ref="dialogForm"
<el-form-item v-for="field in formFields" :key="field.prop" :label="field.label" :prop="field.prop"> :visible.sync="dialogVisible"
<el-input v-model="form[field.prop]" clearable /> :title="dialogTitle"
</el-form-item> width="40%"
</el-form> :form-cols="formCols"
<template #footer> :form-data="formData"
<el-button size="mini" @click="dialogVisible=false">取消</el-button> :rules="rules"
<el-button type="primary" size="mini" :loading="saving" @click="save">确定</el-button> label-width="130px"
</template> :submitting="submitting"
</el-dialog> :confirm-text="key('confirm')"
:cancel-text="key('cancel')"
@submit="onDialogSubmit"
@close="onDialogClose"
/>
</d2-container> </d2-container>
</template> </template>
<script> <script>
import { createExportTask, createItem, deleteItem, editItem, getList } from '@/api/equipment-management/equipment-registry' import { useTableColumns } from '@/composables/useTableColumns'
import { useTableButtons } from '@/composables/useTableButtons'
import { i18nMixin } from '@/composables/useI18n'
import { confirmMixin } from '@/composables/useConfirmHandle'
import PageTable from '@/components/page-table'
import PageDialogForm from '@/components/page-dialog-form'
import { getList, createItem, editItem, deleteItem, createExportTask } from '@/api/equipment-management/equipment-registry'
export default { export default {
name: 'equipment-management-equipment-registry', name: 'equipment-management-equipment-registry',
components: { PageTable, PageDialogForm },
mixins: [i18nMixin('page.equipment_management.equipment_model.equipment_registry'), confirmMixin],
data () { data () {
return { return {
loading: false, loading: false,
saving: false, submitting: false,
search: { keyword: '' },
tableData: [], tableData: [],
selectedRows: [],
dialogVisible: false,
dialogTitle: '',
editId: '',
handleType: 'create',
search: {
device_code: '',
device_name: ''
},
pagination: { current: 1, size: 10, total: 0 }, pagination: { current: 1, size: 10, total: 0 },
columns: [ formData: {
{ device_code: '',
prop: 'device_code', device_name: '',
label: '设备编码' device_type_id: '',
}, device_status: '',
{ area_id: '',
prop: 'device_name', line_id: '',
label: '设备名称' remark: ''
}, },
{ rules: {
prop: 'device_type_name', device_code: [{ required: true, message: this.key('enter_device_code'), trigger: 'blur' }],
label: '设备类别' device_name: [{ required: true, message: this.key('enter_device_name'), trigger: 'blur' }]
}, },
{ columns: [],
prop: 'device_status', toolbarButtons: [],
label: '设备状态' rowButtons: [],
}, formCols: [
{ [
prop: 'area_name', {
label: '所属区域' type: 'input',
}, prop: 'device_code',
{ label: this.key('device_code'),
prop: 'line_name', placeholder: this.key('enter_device_code'),
label: '所属产线' clearable: true,
}, style: { width: '90%' }
{ }
prop: 'remark', ],
label: '备注' [
} {
], type: 'input',
formFields: [ prop: 'device_name',
{ label: this.key('device_name'),
prop: 'device_code', placeholder: this.key('enter_device_name'),
label: '设备编码' clearable: true,
}, style: { width: '90%' }
{ }
prop: 'device_name', ],
label: '设备名称' [
}, {
{ type: 'input',
prop: 'device_type_id', prop: 'device_type_id',
label: '设备类别ID' label: this.key('device_type'),
}, placeholder: this.key('enter_device_type'),
{ clearable: true,
prop: 'device_status', style: { width: '90%' }
label: '设备状态' }
}, ],
{ [
prop: 'area_id', {
label: '区域ID' type: 'input',
}, prop: 'device_status',
{ label: this.key('status'),
prop: 'line_id', placeholder: this.key('enter_status'),
label: '产线ID' clearable: true,
}, style: { width: '90%' }
{ }
prop: 'remark', ],
label: '备注' [
} {
], type: 'input',
form: {}, prop: 'area_id',
dialogVisible: false label: this.key('area'),
placeholder: this.key('enter_area'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'line_id',
label: this.key('line'),
placeholder: this.key('enter_line'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'remark',
label: this.key('remark'),
placeholder: this.key('enter_remark'),
inputType: 'textarea',
autosize: { minRows: 2, maxRows: 6 },
clearable: true,
style: { width: '90%' }
}
]
]
} }
}, },
computed: { created () {
dialogTitle () { return this.form && this.form.id ? '编辑设备信息' : '新增设备信息' }, this.columns = useTableColumns([
hasExport () { return typeof createExportTask === 'function' }, { prop: 'device_code', label: this.key('device_code'), minWidth: 140 },
displayColumns () { { prop: 'device_name', label: this.key('device_name'), minWidth: 140 },
const keys = new Set(this.columns.map(item => item.prop)) { prop: 'device_type_name', label: this.key('device_type'), minWidth: 140 },
const extra = Object.keys(this.tableData[0] || {}).filter(key => !keys.has(key) && key !== 'id').slice(0, 8).map(key => ({ prop: key, label: key })) { prop: 'device_status', label: this.key('status'), minWidth: 140 },
return [...this.columns, ...extra] { prop: 'area_name', label: this.key('area'), minWidth: 140 },
} { prop: 'line_name', label: this.key('line'), minWidth: 140 },
{ prop: 'remark', label: this.key('remark'), minWidth: 140 },
{ prop: '_actions', label: this.key('operation'), width: 170, fixed: 'right' }
])
const btns = useTableButtons({
toolbar: [
{ key: 'add', label: this.key('add'), icon: 'el-icon-plus', type: 'primary', auth: '/device_management/device_model/device_management/create', onClick: this.openAdd },
{ key: 'export', label: this.key('export'), icon: 'el-icon-download', auth: '/device_management/device_model/device_management/export', onClick: this.handleExport }
],
row: [
{ key: 'edit', label: this.key('edit'), icon: 'el-icon-edit', auth: '/device_management/device_model/device_management/edit', onClick: this.openEdit },
{ key: 'delete', label: this.key('delete'), icon: 'el-icon-delete', color: 'danger', auth: '/device_management/device_model/device_management/delete', onClick: this.handleDelete }
]
}, this.$permission)
this.toolbarButtons = btns.toolbarButtons
this.rowButtons = btns.rowButtons
this.fetchData()
}, },
mounted () { this.fetchData() },
methods: { methods: {
responseData (res) { return res && res.data !== undefined ? res.data : res }, normalizeResponse (res) {
normalizeList (data) { const data = res && res.data !== undefined ? res.data : res
if (Array.isArray(data)) return { list: data, total: data.length } if (Array.isArray(data)) return { list: data, total: data.length }
if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) } if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }
if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) } if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) }
return { list: [], total: 0 } return { list: [], total: 0 }
}, },
buildParams () { return { ...this.search, page_no: this.pagination.current, page_size: this.pagination.size } },
async fetchData () { async fetchData () {
this.loading = true this.loading = true
try { try {
const res = await getList(this.buildParams()) const res = await getList({ ...this.search, page_no: this.pagination.current, page_size: this.pagination.size })
const data = this.normalizeList(this.responseData(res)) const data = this.normalizeResponse(res)
this.tableData = data.list this.tableData = data.list
this.pagination.total = data.total this.pagination.total = data.total
} finally { this.loading = false } } finally {
this.loading = false
}
}, },
onSearch () { this.pagination.current = 1; this.fetchData() }, onSearch () {
onReset () { this.search = { keyword: '' }; this.pagination.current = 1; this.fetchData() }, this.pagination.current = 1
changePage (page) { this.pagination.current = page; this.fetchData() },
changeSize (size) { this.pagination.size = size; this.pagination.current = 1; this.fetchData() },
openDialog (row) { this.form = row ? { ...row } : {}; this.dialogVisible = true },
async save () {
this.saving = true
try {
if (this.form.id) await editItem(this.form)
else await createItem(this.form)
this.$message.success('操作成功')
this.dialogVisible = false
this.fetchData()
} finally { this.saving = false }
},
async remove (row) {
await this.$confirm('确认删除该记录?', '提示', { type: 'warning' })
await deleteItem({ id: row.id })
this.$message.success('删除成功')
this.fetchData() this.fetchData()
}, },
async exportTask () { onReset () {
await this.$confirm('确认创建导出任务?', '提示', { type: 'warning' }) this.search = {
await createExportTask(this.buildParams()) device_code: '',
this.$message.success('导出任务创建成功') device_name: ''
}
this.pagination.current = 1
this.fetchData()
},
onPageChange (page) {
this.pagination.current = page.current
this.pagination.size = page.size
this.fetchData()
},
onSelect (rows) {
this.selectedRows = rows
},
resetForm () {
this.formData = {
device_code: '',
device_name: '',
device_type_id: '',
device_status: '',
area_id: '',
line_id: '',
remark: ''
}
this.editId = ''
},
openAdd () {
this.handleType = 'create'
this.dialogTitle = this.key('add_title')
this.$nextTick(() => {
this.$refs.dialogForm && this.$refs.dialogForm.reset()
this.resetForm()
this.dialogVisible = true
})
},
openEdit (row) {
this.handleType = 'edit'
this.dialogTitle = this.key('edit_title')
this.editId = row.id
this.formData = {
device_code: row.device_code || '',
device_name: row.device_name || '',
device_type_id: row.device_type_id || '',
device_status: row.device_status || '',
area_id: row.area_id || '',
line_id: row.line_id || '',
remark: row.remark || ''
}
this.dialogVisible = true
},
async onDialogSubmit () {
this.submitting = true
try {
if (this.handleType === 'create') await createItem(this.formData)
else await editItem({ ...this.formData, id: this.editId })
this.$message.success(this.$t(this.key('operation_success')))
this.dialogVisible = false
this.fetchData()
} finally {
this.submitting = false
}
},
onDialogClose () {
this.resetForm()
},
async handleDelete (row) {
const cancelled = await this.$confirmAction(
{ message: this.key('confirm_delete'), title: this.key('tip') },
() => deleteItem({ id: [row.id] })
)
if (cancelled) return
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()
},
async handleExport () {
const cancelled = await this.$confirmAction(
{ message: this.key('confirm_export'), title: this.key('tip') },
() => createExportTask({ ...this.search })
)
if (cancelled) return
this.$message.success(this.$t(this.key('operation_success')))
} }
} }
} }
</script> </script>
<style lang="scss" scoped> <style scoped>
.search-bar { margin-bottom: -18px; } .search-bar { padding: 10px 0; }
.pager { padding-top: 10px; text-align: right; } /deep/ .el-form-item--mini.el-form-item { margin-bottom: 4px; }
.danger { color: #f56c6c; }
</style> </style>

View File

@@ -2,139 +2,288 @@
<d2-container> <d2-container>
<template #header> <template #header>
<div class="search-bar"> <div class="search-bar">
<el-form :inline="true" :model="search" size="mini"> <el-form :inline="true" size="mini">
<el-form-item label="关键字"> <el-form-item :label="$t(key('keyword'))">
<el-input v-model.trim="search.keyword" placeholder="请输入关键字" clearable style="width:180px" @keyup.enter.native="onSearch" /> <el-input
v-model="search.keyword"
:placeholder="$t(key('enter_keyword'))"
clearable
style="width:200px"
@keyup.enter.native="onSearch"
/>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" icon="el-icon-search" :disabled="loading" @click="onSearch">查询</el-button> <el-button type="primary" icon="el-icon-search" @click="onSearch">{{ $t(key('search')) }}</el-button>
<el-button icon="el-icon-refresh" :disabled="loading" @click="onReset">重置</el-button> <el-button icon="el-icon-refresh" @click="onReset">{{ $t(key('reset')) }}</el-button>
<el-button type="primary" icon="el-icon-plus" @click="openDialog()">新增</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
</template> </template>
<el-table v-loading="loading" :data="tableData" size="mini" border height="calc(100vh - 220px)"> <page-table
<el-table-column type="index" width="55" /> ref="pageTable"
<el-table-column v-for="column in displayColumns" :key="column.prop" :prop="column.prop" :label="column.label" min-width="150" show-overflow-tooltip /> :columns="columns"
<el-table-column v-if="canEdit || canDelete" label="操作" fixed="right" width="150"> :data="tableData"
<template slot-scope="scope"> :loading="loading"
<el-button v-if="canEdit" type="text" size="mini" @click="openDialog(scope.row)">编辑</el-button> :toolbar-buttons="toolbarButtons"
<el-button v-if="canDelete" type="text" size="mini" class="danger" @click="remove(scope.row)">删除</el-button> :row-buttons="rowButtons"
</template> :pagination="pagination"
</el-table-column> auto-height
<template #empty><el-empty description="暂无数据" :image-size="80" /></template> @page-change="onPageChange"
</el-table> @selection-change="onSelect"
<div class="pager"> />
<el-pagination background layout="total, sizes, prev, pager, next, jumper" :current-page="pagination.current" :page-size="pagination.size" :total="pagination.total" @current-change="changePage" @size-change="changeSize" />
</div>
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="640px"> <page-dialog-form
<el-form ref="form" :model="form" label-width="130px" size="mini"> ref="dialogForm"
<el-form-item v-for="field in formFields" :key="field.prop" :label="field.label" :prop="field.prop"> :visible.sync="dialogVisible"
<el-input v-model="form[field.prop]" clearable /> :title="dialogTitle"
</el-form-item> width="40%"
</el-form> :form-cols="formCols"
<template #footer> :form-data="formData"
<el-button size="mini" @click="dialogVisible=false">取消</el-button> :rules="rules"
<el-button type="primary" size="mini" :loading="saving" @click="save">确定</el-button> label-width="130px"
</template> :submitting="submitting"
</el-dialog> :confirm-text="key('confirm')"
:cancel-text="key('cancel')"
@submit="onDialogSubmit"
@close="onDialogClose"
/>
</d2-container> </d2-container>
</template> </template>
<script> <script>
import { useTableColumns } from '@/composables/useTableColumns'
import { useTableButtons } from '@/composables/useTableButtons'
import { i18nMixin } from '@/composables/useI18n'
import { confirmMixin } from '@/composables/useConfirmHandle'
import PageTable from '@/components/page-table'
import PageDialogForm from '@/components/page-dialog-form'
import { getList, createItem, editItem, deleteItem } from '@/api/equipment-management/inspection-items' import { getList, createItem, editItem, deleteItem } from '@/api/equipment-management/inspection-items'
export default { export default {
name: 'equipment-management-inspection-items', name: 'equipment-management-inspection-items',
components: { PageTable, PageDialogForm },
mixins: [i18nMixin('page.equipment_management.inspection_management.inspection_items'), confirmMixin],
data () { data () {
return { return {
loading: false, loading: false,
saving: false, submitting: false,
canCreate: true,
canEdit: true,
canDelete: true,
canExport: false,
search: { keyword: '' },
tableData: [], tableData: [],
selectedRows: [],
dialogVisible: false,
dialogTitle: '',
editId: '',
handleType: 'create',
search: {
keyword: ''
},
pagination: { current: 1, size: 10, total: 0 }, pagination: { current: 1, size: 10, total: 0 },
columns: [ formData: {
{ prop: 'device_check_item_code', label: '点检项目编码' }, device_check_item_code: '',
{ prop: 'device_check_item_name', label: '点检项目名称' }, device_check_item_name: '',
{ prop: 'device_name', label: '设备名称' }, device_id: '',
{ prop: 'cycle', label: '点检周期' }, cycle: '',
{ prop: 'standard', label: '点检标准' }, standard: '',
{ prop: 'remark', label: '备注' } remark: ''
], },
formFields: [ rules: {
{ prop: 'device_check_item_code', label: '点检项目编码' }, device_check_item_code: [{ required: true, message: this.key('enter_inspection_item_code'), trigger: 'blur' }],
{ prop: 'device_check_item_name', label: '点检项目名称' }, device_check_item_name: [{ required: true, message: this.key('enter_inspection_item_name'), trigger: 'blur' }]
{ prop: 'device_id', label: '设备ID' }, },
{ prop: 'cycle', label: '点检周期' }, columns: [],
{ prop: 'standard', label: '点检标准' }, toolbarButtons: [],
{ prop: 'remark', label: '备注' } rowButtons: [],
], formCols: [
form: {}, [
dialogVisible: false {
type: 'input',
prop: 'device_check_item_code',
label: this.key('inspection_item_code'),
placeholder: this.key('enter_inspection_item_code'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'device_check_item_name',
label: this.key('inspection_item_name'),
placeholder: this.key('enter_inspection_item_name'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'device_id',
label: this.key('device_id'),
placeholder: this.key('enter_device_id'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'cycle',
label: this.key('cycle'),
placeholder: this.key('enter_cycle'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'standard',
label: this.key('standard'),
placeholder: this.key('enter_standard'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'remark',
label: this.key('remark'),
placeholder: this.key('enter_remark'),
inputType: 'textarea',
autosize: { minRows: 2, maxRows: 6 },
clearable: true,
style: { width: '90%' }
}
]
]
} }
}, },
computed: { created () {
dialogTitle () { return this.form && this.form.id ? '编辑设备点检项目' : '新增设备点检项目' }, this.columns = useTableColumns([
displayColumns () { { prop: 'device_check_item_code', label: this.key('inspection_item_code'), minWidth: 140 },
const keys = new Set(this.columns.map(item => item.prop)) { prop: 'device_check_item_name', label: this.key('inspection_item_name'), minWidth: 140 },
const extra = Object.keys(this.tableData[0] || {}).filter(key => !keys.has(key) && key !== 'id').slice(0, 8).map(key => ({ prop: key, label: key })) { prop: 'device_name', label: this.key('device_name'), minWidth: 140 },
return [...this.columns, ...extra] { prop: 'cycle', label: this.key('cycle'), minWidth: 140 },
} { prop: 'standard', label: this.key('standard'), minWidth: 140 },
{ prop: 'remark', label: this.key('remark'), minWidth: 140 },
{ prop: '_actions', label: this.key('operation'), width: 170, fixed: 'right' }
])
const btns = useTableButtons({
toolbar: [
{ key: 'add', label: this.key('add'), icon: 'el-icon-plus', type: 'primary', auth: '/device_management/device_check/device_check_items/create', onClick: this.openAdd }
],
row: [
{ key: 'edit', label: this.key('edit'), icon: 'el-icon-edit', auth: '/device_management/device_check/device_check_items/edit', onClick: this.openEdit },
{ key: 'delete', label: this.key('delete'), icon: 'el-icon-delete', color: 'danger', auth: '/device_management/device_check/device_check_items/delete', onClick: this.handleDelete }
]
}, this.$permission)
this.toolbarButtons = btns.toolbarButtons
this.rowButtons = btns.rowButtons
this.fetchData()
}, },
mounted () { this.fetchData() },
methods: { methods: {
responseData (res) { return res && res.data !== undefined ? res.data : res }, normalizeResponse (res) {
normalizeList (data) { const data = res && res.data !== undefined ? res.data : res
if (Array.isArray(data)) return { list: data, total: data.length } if (Array.isArray(data)) return { list: data, total: data.length }
if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) } if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }
if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) } if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) }
return { list: [], total: 0 } return { list: [], total: 0 }
}, },
buildParams () { return { ...this.search, page_no: this.pagination.current, page_size: this.pagination.size } },
async fetchData () { async fetchData () {
this.loading = true this.loading = true
try { try {
const res = await getList(this.buildParams()) const res = await getList({ ...this.search, page_no: this.pagination.current, page_size: this.pagination.size })
const data = this.normalizeList(this.responseData(res)) const data = this.normalizeResponse(res)
this.tableData = data.list this.tableData = data.list
this.pagination.total = data.total this.pagination.total = data.total
} finally { this.loading = false } } finally {
this.loading = false
}
}, },
onSearch () { this.pagination.current = 1; this.fetchData() }, onSearch () {
onReset () { this.search = { keyword: '' }; this.pagination.current = 1; this.fetchData() }, this.pagination.current = 1
changePage (page) { this.pagination.current = page; this.fetchData() }, this.fetchData()
changeSize (size) { this.pagination.size = size; this.pagination.current = 1; this.fetchData() }, },
openDialog (row) { this.form = row ? { ...row } : {}; this.dialogVisible = true }, onReset () {
async save () { this.search = {
this.saving = true keyword: ''
}
this.pagination.current = 1
this.fetchData()
},
onPageChange (page) {
this.pagination.current = page.current
this.pagination.size = page.size
this.fetchData()
},
onSelect (rows) {
this.selectedRows = rows
},
resetForm () {
this.formData = {
device_check_item_code: '',
device_check_item_name: '',
device_id: '',
cycle: '',
standard: '',
remark: ''
}
this.editId = ''
},
openAdd () {
this.handleType = 'create'
this.dialogTitle = this.key('add_title')
this.$nextTick(() => {
this.$refs.dialogForm && this.$refs.dialogForm.reset()
this.resetForm()
this.dialogVisible = true
})
},
openEdit (row) {
this.handleType = 'edit'
this.dialogTitle = this.key('edit_title')
this.editId = row.id
this.formData = {
device_check_item_code: row.device_check_item_code || '',
device_check_item_name: row.device_check_item_name || '',
device_id: row.device_id || '',
cycle: row.cycle || '',
standard: row.standard || '',
remark: row.remark || ''
}
this.dialogVisible = true
},
async onDialogSubmit () {
this.submitting = true
try { try {
if (this.form.id) await editItem(this.form) if (this.handleType === 'create') await createItem(this.formData)
else await createItem(this.form) else await editItem({ ...this.formData, id: this.editId })
this.$message.success('操作成功') this.$message.success(this.$t(this.key('operation_success')))
this.dialogVisible = false this.dialogVisible = false
this.fetchData() this.fetchData()
} finally { this.saving = false } } finally {
this.submitting = false
}
}, },
async remove (row) { onDialogClose () {
await this.$confirm('确认删除该记录?', '提示', { type: 'warning' }) this.resetForm()
await deleteItem({ id: row.id }) },
this.$message.success('删除成功') async handleDelete (row) {
const cancelled = await this.$confirmAction(
{ message: this.key('confirm_delete'), title: this.key('tip') },
() => deleteItem({ id: [row.id] })
)
if (cancelled) return
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() this.fetchData()
} }
} }
} }
</script> </script>
<style lang="scss" scoped> <style scoped>
.search-bar { margin-bottom: -18px; } .search-bar { padding: 10px 0; }
.pager { padding-top: 10px; text-align: right; } /deep/ .el-form-item--mini.el-form-item { margin-bottom: 4px; }
.danger { color: #f56c6c; }
</style> </style>

View File

@@ -2,82 +2,153 @@
<d2-container> <d2-container>
<template #header> <template #header>
<div class="search-bar"> <div class="search-bar">
<el-form :inline="true" :model="search" size="mini"> <el-form :inline="true" size="mini">
<el-form-item label="关键字"><el-input v-model.trim="search.keyword" placeholder="请输入关键字" clearable style="width:180px" @keyup.enter.native="onSearch" /></el-form-item> <el-form-item :label="$t(key('keyword'))">
<el-input
v-model="search.keyword"
:placeholder="$t(key('enter_keyword'))"
clearable
style="width:200px"
@keyup.enter.native="onSearch"
/>
</el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" icon="el-icon-search" :disabled="loading" @click="onSearch">查询</el-button> <el-button type="primary" icon="el-icon-search" @click="onSearch">{{ $t(key('search')) }}</el-button>
<el-button icon="el-icon-refresh" :disabled="loading" @click="onReset">重置</el-button> <el-button icon="el-icon-refresh" @click="onReset">{{ $t(key('reset')) }}</el-button>
<el-button icon="el-icon-download" :disabled="loading" @click="exportTask">导出</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
</template> </template>
<el-table v-loading="loading" :data="tableData" size="mini" border height="calc(100vh - 220px)">
<el-table-column type="index" width="55" /> <page-table
<el-table-column v-for="column in displayColumns" :key="column.prop" :prop="column.prop" :label="column.label" min-width="150" show-overflow-tooltip /> ref="pageTable"
<el-table-column v-if="canEdit || canDelete" label="操作" fixed="right" width="150"><template slot-scope="scope"><el-button v-if="canEdit" type="text" size="mini" @click="openDialog(scope.row)">编辑</el-button><el-button v-if="canDelete" type="text" size="mini" class="danger" @click="remove(scope.row)">删除</el-button></template></el-table-column> :columns="columns"
<template #empty><el-empty description="暂无数据" :image-size="80" /></template> :data="tableData"
</el-table> :loading="loading"
<div class="pager"><el-pagination background layout="total, sizes, prev, pager, next, jumper" :current-page="pagination.current" :page-size="pagination.size" :total="pagination.total" @current-change="changePage" @size-change="changeSize" /></div> :toolbar-buttons="toolbarButtons"
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="640px"><el-form ref="form" :model="form" label-width="130px" size="mini"><el-form-item v-for="field in formFields" :key="field.prop" :label="field.label" :prop="field.prop"><el-input v-model="form[field.prop]" clearable /></el-form-item></el-form><template #footer><el-button size="mini" @click="dialogVisible=false">取消</el-button><el-button type="primary" size="mini" :loading="saving" @click="save">确定</el-button></template></el-dialog> :row-buttons="rowButtons"
:pagination="pagination"
auto-height
@page-change="onPageChange"
@selection-change="onSelect"
/>
</d2-container> </d2-container>
</template> </template>
<script> <script>
import { useTableColumns } from '@/composables/useTableColumns'
import { useTableButtons } from '@/composables/useTableButtons'
import { i18nMixin } from '@/composables/useI18n'
import { confirmMixin } from '@/composables/useConfirmHandle'
import PageTable from '@/components/page-table'
import { getList, createExportTask } from '@/api/equipment-management/inspection-logs' import { getList, createExportTask } from '@/api/equipment-management/inspection-logs'
export default { export default {
name: 'equipment-management-inspection-logs', name: 'equipment-management-inspection-logs',
components: { PageTable },
mixins: [i18nMixin('page.equipment_management.inspection_management.inspection_logs'), confirmMixin],
data () { data () {
return { return {
loading: false, loading: false,
saving: false, submitting: false,
canCreate: false,
canEdit: false,
canDelete: false,
canExport: true,
search: { keyword: '' },
tableData: [], tableData: [],
selectedRows: [],
dialogVisible: false,
dialogTitle: '',
editId: '',
handleType: 'create',
search: {
keyword: ''
},
pagination: { current: 1, size: 10, total: 0 }, pagination: { current: 1, size: 10, total: 0 },
columns: [ formData: {
{ prop: 'device_code', label: '设备编码' },
{ prop: 'device_name', label: '设备名称' },
{ prop: 'check_item_name', label: '点检项目' },
{ prop: 'check_result', label: '点检结果' },
{ prop: 'check_user', label: '点检人员' },
{ prop: 'check_time', label: '点检时间' }
],
formFields: [
], },
form: {}, rules: {},
dialogVisible: false columns: [],
toolbarButtons: [],
rowButtons: [],
formCols: []
} }
}, },
computed: { created () {
dialogTitle () { return this.form && this.form.id ? '编辑设备点检日志' : '新增设备点检日志' }, this.columns = useTableColumns([
displayColumns () { const keys = new Set(this.columns.map(item => item.prop)); const extra = Object.keys(this.tableData[0] || {}).filter(key => !keys.has(key) && key !== 'id').slice(0, 8).map(key => ({ prop: key, label: key })); return [...this.columns, ...extra] } { prop: 'device_code', label: this.key('device_code'), minWidth: 140 },
{ prop: 'device_name', label: this.key('device_name'), minWidth: 140 },
{ prop: 'check_item_name', label: this.key('inspection_item'), minWidth: 140 },
{ prop: 'check_result', label: this.key('inspection_result'), minWidth: 140 },
{ prop: 'check_user', label: this.key('inspection_user'), minWidth: 140 },
{ prop: 'check_time', label: this.key('inspection_time'), minWidth: 140 }
])
const btns = useTableButtons({
toolbar: [
{ key: 'export', label: this.key('export'), icon: 'el-icon-download', auth: '/device_management/device_check/device_check_items_log/export', onClick: this.handleExport }
],
row: [
]
}, this.$permission)
this.toolbarButtons = btns.toolbarButtons
this.rowButtons = btns.rowButtons
this.fetchData()
}, },
mounted () { this.fetchData() },
methods: { methods: {
responseData (res) { return res && res.data !== undefined ? res.data : res }, normalizeResponse (res) {
normalizeList (data) { if (Array.isArray(data)) return { list: data, total: data.length }; if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }; if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) }; return { list: [], total: 0 } }, const data = res && res.data !== undefined ? res.data : res
buildParams () { return { ...this.search, page_no: this.pagination.current, page_size: this.pagination.size } }, if (Array.isArray(data)) return { list: data, total: data.length }
async fetchData () { this.loading = true; try { const res = await getList(this.buildParams()); const data = this.normalizeList(this.responseData(res)); this.tableData = data.list; this.pagination.total = data.total } finally { this.loading = false } }, if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }
onSearch () { this.pagination.current = 1; this.fetchData() }, if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) }
onReset () { this.search = { keyword: '' }; this.pagination.current = 1; this.fetchData() }, return { list: [], total: 0 }
changePage (page) { this.pagination.current = page; this.fetchData() }, },
changeSize (size) { this.pagination.size = size; this.pagination.current = 1; this.fetchData() }, async fetchData () {
openDialog (row) { this.form = row ? { ...row } : {}; this.dialogVisible = true }, this.loading = true
async exportTask () { try {
await this.$confirm('确认创建导出任务?', '提示', { type: 'warning' }) const res = await getList({ ...this.search, page_no: this.pagination.current, page_size: this.pagination.size })
await createExportTask(this.buildParams()) const data = this.normalizeResponse(res)
this.$message.success('导出任务创建成功') this.tableData = data.list
this.pagination.total = data.total
} finally {
this.loading = false
}
},
onSearch () {
this.pagination.current = 1
this.fetchData()
},
onReset () {
this.search = {
keyword: ''
}
this.pagination.current = 1
this.fetchData()
},
onPageChange (page) {
this.pagination.current = page.current
this.pagination.size = page.size
this.fetchData()
},
onSelect (rows) {
this.selectedRows = rows
},
resetForm () {
this.formData = {
}
this.editId = ''
},
async handleExport () {
const cancelled = await this.$confirmAction(
{ message: this.key('confirm_export'), title: this.key('tip') },
() => createExportTask({ ...this.search })
)
if (cancelled) return
this.$message.success(this.$t(this.key('operation_success')))
} }
} }
} }
</script> </script>
<style lang="scss" scoped>
.search-bar { margin-bottom: -18px; } <style scoped>
.pager { padding-top: 10px; text-align: right; } .search-bar { padding: 10px 0; }
.danger { color: #f56c6c; } /deep/ .el-form-item--mini.el-form-item { margin-bottom: 4px; }
</style> </style>

View File

@@ -2,91 +2,264 @@
<d2-container> <d2-container>
<template #header> <template #header>
<div class="search-bar"> <div class="search-bar">
<el-form :inline="true" :model="search" size="mini"> <el-form :inline="true" size="mini">
<el-form-item label="关键字"><el-input v-model.trim="search.keyword" placeholder="请输入关键字" clearable style="width:180px" @keyup.enter.native="onSearch" /></el-form-item> <el-form-item :label="$t(key('keyword'))">
<el-input
v-model="search.keyword"
:placeholder="$t(key('enter_keyword'))"
clearable
style="width:200px"
@keyup.enter.native="onSearch"
/>
</el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" icon="el-icon-search" :disabled="loading" @click="onSearch">查询</el-button> <el-button type="primary" icon="el-icon-search" @click="onSearch">{{ $t(key('search')) }}</el-button>
<el-button icon="el-icon-refresh" :disabled="loading" @click="onReset">重置</el-button> <el-button icon="el-icon-refresh" @click="onReset">{{ $t(key('reset')) }}</el-button>
<el-button type="primary" icon="el-icon-plus" @click="openDialog()">新增</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
</template> </template>
<el-table v-loading="loading" :data="tableData" size="mini" border height="calc(100vh - 220px)">
<el-table-column type="index" width="55" /> <page-table
<el-table-column v-for="column in displayColumns" :key="column.prop" :prop="column.prop" :label="column.label" min-width="150" show-overflow-tooltip /> ref="pageTable"
<el-table-column v-if="canEdit || canDelete" label="操作" fixed="right" width="150"><template slot-scope="scope"><el-button v-if="canEdit" type="text" size="mini" @click="openDialog(scope.row)">编辑</el-button><el-button v-if="canDelete" type="text" size="mini" class="danger" @click="remove(scope.row)">删除</el-button></template></el-table-column> :columns="columns"
<template #empty><el-empty description="暂无数据" :image-size="80" /></template> :data="tableData"
</el-table> :loading="loading"
<div class="pager"><el-pagination background layout="total, sizes, prev, pager, next, jumper" :current-page="pagination.current" :page-size="pagination.size" :total="pagination.total" @current-change="changePage" @size-change="changeSize" /></div> :toolbar-buttons="toolbarButtons"
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="640px"><el-form ref="form" :model="form" label-width="130px" size="mini"><el-form-item v-for="field in formFields" :key="field.prop" :label="field.label" :prop="field.prop"><el-input v-model="form[field.prop]" clearable /></el-form-item></el-form><template #footer><el-button size="mini" @click="dialogVisible=false">取消</el-button><el-button type="primary" size="mini" :loading="saving" @click="save">确定</el-button></template></el-dialog> :row-buttons="rowButtons"
:pagination="pagination"
auto-height
@page-change="onPageChange"
@selection-change="onSelect"
/>
<page-dialog-form
ref="dialogForm"
:visible.sync="dialogVisible"
:title="dialogTitle"
width="40%"
:form-cols="formCols"
:form-data="formData"
:rules="rules"
label-width="130px"
:submitting="submitting"
:confirm-text="key('confirm')"
:cancel-text="key('cancel')"
@submit="onDialogSubmit"
@close="onDialogClose"
/>
</d2-container> </d2-container>
</template> </template>
<script> <script>
import { useTableColumns } from '@/composables/useTableColumns'
import { useTableButtons } from '@/composables/useTableButtons'
import { i18nMixin } from '@/composables/useI18n'
import { confirmMixin } from '@/composables/useConfirmHandle'
import PageTable from '@/components/page-table'
import PageDialogForm from '@/components/page-dialog-form'
import { getList, createItem, editItem } from '@/api/equipment-management/inspection-records' import { getList, createItem, editItem } from '@/api/equipment-management/inspection-records'
export default { export default {
name: 'equipment-management-inspection-records', name: 'equipment-management-inspection-records',
components: { PageTable, PageDialogForm },
mixins: [i18nMixin('page.equipment_management.inspection_management.inspection_records'), confirmMixin],
data () { data () {
return { return {
loading: false, loading: false,
saving: false, submitting: false,
canCreate: true,
canEdit: true,
canDelete: false,
canExport: false,
search: { keyword: '' },
tableData: [], tableData: [],
selectedRows: [],
dialogVisible: false,
dialogTitle: '',
editId: '',
handleType: 'create',
search: {
keyword: ''
},
pagination: { current: 1, size: 10, total: 0 }, pagination: { current: 1, size: 10, total: 0 },
columns: [ formData: {
{ prop: 'device_code', label: '设备编码' }, device_id: '',
{ prop: 'device_name', label: '设备名称' }, check_status: '',
{ prop: 'check_status', label: '点检状态' }, check_user: '',
{ prop: 'check_user', label: '点检人员' }, check_time: '',
{ prop: 'check_time', label: '点检时间' }, remark: ''
{ prop: 'remark', label: '备注' } },
], rules: {
formFields: [ device_id: [{ required: true, message: this.key('enter_device_id'), trigger: 'blur' }],
{ prop: 'device_id', label: '设备ID' }, check_status: [{ required: true, message: this.key('enter_inspection_status'), trigger: 'blur' }]
{ prop: 'check_status', label: '点检状态' }, },
{ prop: 'check_user', label: '点检人员' }, columns: [],
{ prop: 'check_time', label: '点检时间' }, toolbarButtons: [],
{ prop: 'remark', label: '备注' } rowButtons: [],
], formCols: [
form: {}, [
dialogVisible: false {
type: 'input',
prop: 'device_id',
label: this.key('device_id'),
placeholder: this.key('enter_device_id'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'check_status',
label: this.key('inspection_status'),
placeholder: this.key('enter_inspection_status'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'check_user',
label: this.key('inspection_user'),
placeholder: this.key('enter_inspection_user'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'check_time',
label: this.key('inspection_time'),
placeholder: this.key('enter_inspection_time'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'remark',
label: this.key('remark'),
placeholder: this.key('enter_remark'),
inputType: 'textarea',
autosize: { minRows: 2, maxRows: 6 },
clearable: true,
style: { width: '90%' }
}
]
]
} }
}, },
computed: { created () {
dialogTitle () { return this.form && this.form.id ? '编辑设备点检记录' : '新增设备点检记录' }, this.columns = useTableColumns([
displayColumns () { const keys = new Set(this.columns.map(item => item.prop)); const extra = Object.keys(this.tableData[0] || {}).filter(key => !keys.has(key) && key !== 'id').slice(0, 8).map(key => ({ prop: key, label: key })); return [...this.columns, ...extra] } { prop: 'device_code', label: this.key('device_code'), minWidth: 140 },
{ prop: 'device_name', label: this.key('device_name'), minWidth: 140 },
{ prop: 'check_status', label: this.key('inspection_status'), minWidth: 140 },
{ prop: 'check_user', label: this.key('inspection_user'), minWidth: 140 },
{ prop: 'check_time', label: this.key('inspection_time'), minWidth: 140 },
{ prop: 'remark', label: this.key('remark'), minWidth: 140 },
{ prop: '_actions', label: this.key('operation'), width: 170, fixed: 'right' }
])
const btns = useTableButtons({
toolbar: [
{ key: 'add', label: this.key('add'), icon: 'el-icon-plus', type: 'primary', auth: '/device_management/device_check/device_check_record/create', onClick: this.openAdd }
],
row: [
{ key: 'edit', label: this.key('edit'), icon: 'el-icon-edit', auth: '/device_management/device_check/device_check_record/edit', onClick: this.openEdit }
]
}, this.$permission)
this.toolbarButtons = btns.toolbarButtons
this.rowButtons = btns.rowButtons
this.fetchData()
}, },
mounted () { this.fetchData() },
methods: { methods: {
responseData (res) { return res && res.data !== undefined ? res.data : res }, normalizeResponse (res) {
normalizeList (data) { if (Array.isArray(data)) return { list: data, total: data.length }; if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }; if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) }; return { list: [], total: 0 } }, const data = res && res.data !== undefined ? res.data : res
buildParams () { return { ...this.search, page_no: this.pagination.current, page_size: this.pagination.size } }, if (Array.isArray(data)) return { list: data, total: data.length }
async fetchData () { this.loading = true; try { const res = await getList(this.buildParams()); const data = this.normalizeList(this.responseData(res)); this.tableData = data.list; this.pagination.total = data.total } finally { this.loading = false } }, if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }
onSearch () { this.pagination.current = 1; this.fetchData() }, if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) }
onReset () { this.search = { keyword: '' }; this.pagination.current = 1; this.fetchData() }, return { list: [], total: 0 }
changePage (page) { this.pagination.current = page; this.fetchData() }, },
changeSize (size) { this.pagination.size = size; this.pagination.current = 1; this.fetchData() }, async fetchData () {
openDialog (row) { this.form = row ? { ...row } : {}; this.dialogVisible = true }, this.loading = true
async save () {
this.saving = true
try { try {
if (this.form.id) await editItem(this.form) const res = await getList({ ...this.search, page_no: this.pagination.current, page_size: this.pagination.size })
else await createItem(this.form) const data = this.normalizeResponse(res)
this.$message.success('操作成功') this.tableData = data.list
this.pagination.total = data.total
} finally {
this.loading = false
}
},
onSearch () {
this.pagination.current = 1
this.fetchData()
},
onReset () {
this.search = {
keyword: ''
}
this.pagination.current = 1
this.fetchData()
},
onPageChange (page) {
this.pagination.current = page.current
this.pagination.size = page.size
this.fetchData()
},
onSelect (rows) {
this.selectedRows = rows
},
resetForm () {
this.formData = {
device_id: '',
check_status: '',
check_user: '',
check_time: '',
remark: ''
}
this.editId = ''
},
openAdd () {
this.handleType = 'create'
this.dialogTitle = this.key('add_title')
this.$nextTick(() => {
this.$refs.dialogForm && this.$refs.dialogForm.reset()
this.resetForm()
this.dialogVisible = true
})
},
openEdit (row) {
this.handleType = 'edit'
this.dialogTitle = this.key('edit_title')
this.editId = row.id
this.formData = {
device_id: row.device_id || '',
check_status: row.check_status || '',
check_user: row.check_user || '',
check_time: row.check_time || '',
remark: row.remark || ''
}
this.dialogVisible = true
},
async onDialogSubmit () {
this.submitting = true
try {
if (this.handleType === 'create') await createItem(this.formData)
else await editItem({ ...this.formData, id: this.editId })
this.$message.success(this.$t(this.key('operation_success')))
this.dialogVisible = false this.dialogVisible = false
this.fetchData() this.fetchData()
} finally { this.saving = false } } finally {
this.submitting = false
}
},
onDialogClose () {
this.resetForm()
} }
} }
} }
</script> </script>
<style lang="scss" scoped>
.search-bar { margin-bottom: -18px; } <style scoped>
.pager { padding-top: 10px; text-align: right; } .search-bar { padding: 10px 0; }
.danger { color: #f56c6c; } /deep/ .el-form-item--mini.el-form-item { margin-bottom: 4px; }
</style> </style>

View File

@@ -2,96 +2,278 @@
<d2-container> <d2-container>
<template #header> <template #header>
<div class="search-bar"> <div class="search-bar">
<el-form :inline="true" :model="search" size="mini"> <el-form :inline="true" size="mini">
<el-form-item label="关键字"><el-input v-model.trim="search.keyword" placeholder="请输入关键字" clearable style="width:180px" @keyup.enter.native="onSearch" /></el-form-item> <el-form-item :label="$t(key('keyword'))">
<el-input
v-model="search.keyword"
:placeholder="$t(key('enter_keyword'))"
clearable
style="width:200px"
@keyup.enter.native="onSearch"
/>
</el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" icon="el-icon-search" :disabled="loading" @click="onSearch">查询</el-button> <el-button type="primary" icon="el-icon-search" @click="onSearch">{{ $t(key('search')) }}</el-button>
<el-button icon="el-icon-refresh" :disabled="loading" @click="onReset">重置</el-button> <el-button icon="el-icon-refresh" @click="onReset">{{ $t(key('reset')) }}</el-button>
<el-button type="primary" icon="el-icon-plus" @click="openDialog()">新增</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
</template> </template>
<el-table v-loading="loading" :data="tableData" size="mini" border height="calc(100vh - 220px)">
<el-table-column type="index" width="55" /> <page-table
<el-table-column v-for="column in displayColumns" :key="column.prop" :prop="column.prop" :label="column.label" min-width="150" show-overflow-tooltip /> ref="pageTable"
<el-table-column v-if="canEdit || canDelete" label="操作" fixed="right" width="150"><template slot-scope="scope"><el-button v-if="canEdit" type="text" size="mini" @click="openDialog(scope.row)">编辑</el-button><el-button v-if="canDelete" type="text" size="mini" class="danger" @click="remove(scope.row)">删除</el-button></template></el-table-column> :columns="columns"
<template #empty><el-empty description="暂无数据" :image-size="80" /></template> :data="tableData"
</el-table> :loading="loading"
<div class="pager"><el-pagination background layout="total, sizes, prev, pager, next, jumper" :current-page="pagination.current" :page-size="pagination.size" :total="pagination.total" @current-change="changePage" @size-change="changeSize" /></div> :toolbar-buttons="toolbarButtons"
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="640px"><el-form ref="form" :model="form" label-width="130px" size="mini"><el-form-item v-for="field in formFields" :key="field.prop" :label="field.label" :prop="field.prop"><el-input v-model="form[field.prop]" clearable /></el-form-item></el-form><template #footer><el-button size="mini" @click="dialogVisible=false">取消</el-button><el-button type="primary" size="mini" :loading="saving" @click="save">确定</el-button></template></el-dialog> :row-buttons="rowButtons"
:pagination="pagination"
auto-height
@page-change="onPageChange"
@selection-change="onSelect"
/>
<page-dialog-form
ref="dialogForm"
:visible.sync="dialogVisible"
:title="dialogTitle"
width="40%"
:form-cols="formCols"
:form-data="formData"
:rules="rules"
label-width="130px"
:submitting="submitting"
:confirm-text="key('confirm')"
:cancel-text="key('cancel')"
@submit="onDialogSubmit"
@close="onDialogClose"
/>
</d2-container> </d2-container>
</template> </template>
<script> <script>
import { useTableColumns } from '@/composables/useTableColumns'
import { useTableButtons } from '@/composables/useTableButtons'
import { i18nMixin } from '@/composables/useI18n'
import { confirmMixin } from '@/composables/useConfirmHandle'
import PageTable from '@/components/page-table'
import PageDialogForm from '@/components/page-dialog-form'
import { getList, createItem, editItem, deleteItem } from '@/api/equipment-management/maintenance-details' import { getList, createItem, editItem, deleteItem } from '@/api/equipment-management/maintenance-details'
export default { export default {
name: 'equipment-management-maintenance-details', name: 'equipment-management-maintenance-details',
components: { PageTable, PageDialogForm },
mixins: [i18nMixin('page.equipment_management.maintenance_management.maintenance_details'), confirmMixin],
data () { data () {
return { return {
loading: false, loading: false,
saving: false, submitting: false,
canCreate: true,
canEdit: true,
canDelete: true,
canExport: false,
search: { keyword: '' },
tableData: [], tableData: [],
selectedRows: [],
dialogVisible: false,
dialogTitle: '',
editId: '',
handleType: 'create',
search: {
keyword: ''
},
pagination: { current: 1, size: 10, total: 0 }, pagination: { current: 1, size: 10, total: 0 },
columns: [ formData: {
{ prop: 'device_name', label: '设备名称' }, device_id: '',
{ prop: 'device_maintain_item_name', label: '保养项目' }, device_maintain_item_id: '',
{ prop: 'maintain_content', label: '保养内容' }, maintain_content: '',
{ prop: 'maintain_standard', label: '保养标准' }, maintain_standard: '',
{ prop: 'remark', label: '备注' } remark: ''
], },
formFields: [ rules: {
{ prop: 'device_id', label: '设备ID' }, device_id: [{ required: true, message: this.key('enter_device_id'), trigger: 'blur' }],
{ prop: 'device_maintain_item_id', label: '保养项目ID' }, device_maintain_item_id: [{ required: true, message: this.key('enter_maintenance_item_id'), trigger: 'blur' }]
{ prop: 'maintain_content', label: '保养内容' }, },
{ prop: 'maintain_standard', label: '保养标准' }, columns: [],
{ prop: 'remark', label: '备注' } toolbarButtons: [],
], rowButtons: [],
form: {}, formCols: [
dialogVisible: false [
{
type: 'input',
prop: 'device_id',
label: this.key('device_id'),
placeholder: this.key('enter_device_id'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'device_maintain_item_id',
label: this.key('maintenance_item_id'),
placeholder: this.key('enter_maintenance_item_id'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'maintain_content',
label: this.key('maintenance_content'),
placeholder: this.key('enter_maintenance_content'),
inputType: 'textarea',
autosize: { minRows: 2, maxRows: 6 },
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'maintain_standard',
label: this.key('maintenance_standard'),
placeholder: this.key('enter_maintenance_standard'),
inputType: 'textarea',
autosize: { minRows: 2, maxRows: 6 },
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'remark',
label: this.key('remark'),
placeholder: this.key('enter_remark'),
inputType: 'textarea',
autosize: { minRows: 2, maxRows: 6 },
clearable: true,
style: { width: '90%' }
}
]
]
} }
}, },
computed: { created () {
dialogTitle () { return this.form && this.form.id ? '编辑设备保养详情' : '新增设备保养详情' }, this.columns = useTableColumns([
displayColumns () { const keys = new Set(this.columns.map(item => item.prop)); const extra = Object.keys(this.tableData[0] || {}).filter(key => !keys.has(key) && key !== 'id').slice(0, 8).map(key => ({ prop: key, label: key })); return [...this.columns, ...extra] } { prop: 'device_name', label: this.key('device_name'), minWidth: 140 },
{ prop: 'device_maintain_item_name', label: this.key('maintenance_item'), minWidth: 140 },
{ prop: 'maintain_content', label: this.key('maintenance_content'), minWidth: 140 },
{ prop: 'maintain_standard', label: this.key('maintenance_standard'), minWidth: 140 },
{ prop: 'remark', label: this.key('remark'), minWidth: 140 },
{ prop: '_actions', label: this.key('operation'), width: 170, fixed: 'right' }
])
const btns = useTableButtons({
toolbar: [
{ key: 'add', label: this.key('add'), icon: 'el-icon-plus', type: 'primary', auth: '/device_management/device_maintain/device_maintain_items_details/create', onClick: this.openAdd }
],
row: [
{ key: 'edit', label: this.key('edit'), icon: 'el-icon-edit', auth: '/device_management/device_maintain/device_maintain_items_details/edit', onClick: this.openEdit },
{ key: 'delete', label: this.key('delete'), icon: 'el-icon-delete', color: 'danger', auth: '/device_management/device_maintain/device_maintain_items_details/delete', onClick: this.handleDelete }
]
}, this.$permission)
this.toolbarButtons = btns.toolbarButtons
this.rowButtons = btns.rowButtons
this.fetchData()
}, },
mounted () { this.fetchData() },
methods: { methods: {
responseData (res) { return res && res.data !== undefined ? res.data : res }, normalizeResponse (res) {
normalizeList (data) { if (Array.isArray(data)) return { list: data, total: data.length }; if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }; if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) }; return { list: [], total: 0 } }, const data = res && res.data !== undefined ? res.data : res
buildParams () { return { ...this.search, page_no: this.pagination.current, page_size: this.pagination.size } }, if (Array.isArray(data)) return { list: data, total: data.length }
async fetchData () { this.loading = true; try { const res = await getList(this.buildParams()); const data = this.normalizeList(this.responseData(res)); this.tableData = data.list; this.pagination.total = data.total } finally { this.loading = false } }, if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }
onSearch () { this.pagination.current = 1; this.fetchData() }, if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) }
onReset () { this.search = { keyword: '' }; this.pagination.current = 1; this.fetchData() }, return { list: [], total: 0 }
changePage (page) { this.pagination.current = page; this.fetchData() }, },
changeSize (size) { this.pagination.size = size; this.pagination.current = 1; this.fetchData() }, async fetchData () {
openDialog (row) { this.form = row ? { ...row } : {}; this.dialogVisible = true }, this.loading = true
async save () {
this.saving = true
try { try {
if (this.form.id) await editItem(this.form) const res = await getList({ ...this.search, page_no: this.pagination.current, page_size: this.pagination.size })
else await createItem(this.form) const data = this.normalizeResponse(res)
this.$message.success('操作成功') this.tableData = data.list
this.pagination.total = data.total
} finally {
this.loading = false
}
},
onSearch () {
this.pagination.current = 1
this.fetchData()
},
onReset () {
this.search = {
keyword: ''
}
this.pagination.current = 1
this.fetchData()
},
onPageChange (page) {
this.pagination.current = page.current
this.pagination.size = page.size
this.fetchData()
},
onSelect (rows) {
this.selectedRows = rows
},
resetForm () {
this.formData = {
device_id: '',
device_maintain_item_id: '',
maintain_content: '',
maintain_standard: '',
remark: ''
}
this.editId = ''
},
openAdd () {
this.handleType = 'create'
this.dialogTitle = this.key('add_title')
this.$nextTick(() => {
this.$refs.dialogForm && this.$refs.dialogForm.reset()
this.resetForm()
this.dialogVisible = true
})
},
openEdit (row) {
this.handleType = 'edit'
this.dialogTitle = this.key('edit_title')
this.editId = row.id
this.formData = {
device_id: row.device_id || '',
device_maintain_item_id: row.device_maintain_item_id || '',
maintain_content: row.maintain_content || '',
maintain_standard: row.maintain_standard || '',
remark: row.remark || ''
}
this.dialogVisible = true
},
async onDialogSubmit () {
this.submitting = true
try {
if (this.handleType === 'create') await createItem(this.formData)
else await editItem({ ...this.formData, id: this.editId })
this.$message.success(this.$t(this.key('operation_success')))
this.dialogVisible = false this.dialogVisible = false
this.fetchData() this.fetchData()
} finally { this.saving = false } } finally {
this.submitting = false
}
}, },
async remove (row) { onDialogClose () {
await this.$confirm('确认删除该记录?', '提示', { type: 'warning' }) this.resetForm()
await deleteItem({ id: row.id }) },
this.$message.success('删除成功') async handleDelete (row) {
const cancelled = await this.$confirmAction(
{ message: this.key('confirm_delete'), title: this.key('tip') },
() => deleteItem({ id: [row.id] })
)
if (cancelled) return
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() this.fetchData()
} }
} }
} }
</script> </script>
<style lang="scss" scoped>
.search-bar { margin-bottom: -18px; } <style scoped>
.pager { padding-top: 10px; text-align: right; } .search-bar { padding: 10px 0; }
.danger { color: #f56c6c; } /deep/ .el-form-item--mini.el-form-item { margin-bottom: 4px; }
</style> </style>

View File

@@ -2,98 +2,288 @@
<d2-container> <d2-container>
<template #header> <template #header>
<div class="search-bar"> <div class="search-bar">
<el-form :inline="true" :model="search" size="mini"> <el-form :inline="true" size="mini">
<el-form-item label="关键字"><el-input v-model.trim="search.keyword" placeholder="请输入关键字" clearable style="width:180px" @keyup.enter.native="onSearch" /></el-form-item> <el-form-item :label="$t(key('keyword'))">
<el-input
v-model="search.keyword"
:placeholder="$t(key('enter_keyword'))"
clearable
style="width:200px"
@keyup.enter.native="onSearch"
/>
</el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" icon="el-icon-search" :disabled="loading" @click="onSearch">查询</el-button> <el-button type="primary" icon="el-icon-search" @click="onSearch">{{ $t(key('search')) }}</el-button>
<el-button icon="el-icon-refresh" :disabled="loading" @click="onReset">重置</el-button> <el-button icon="el-icon-refresh" @click="onReset">{{ $t(key('reset')) }}</el-button>
<el-button type="primary" icon="el-icon-plus" @click="openDialog()">新增</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
</template> </template>
<el-table v-loading="loading" :data="tableData" size="mini" border height="calc(100vh - 220px)">
<el-table-column type="index" width="55" /> <page-table
<el-table-column v-for="column in displayColumns" :key="column.prop" :prop="column.prop" :label="column.label" min-width="150" show-overflow-tooltip /> ref="pageTable"
<el-table-column v-if="canEdit || canDelete" label="操作" fixed="right" width="150"><template slot-scope="scope"><el-button v-if="canEdit" type="text" size="mini" @click="openDialog(scope.row)">编辑</el-button><el-button v-if="canDelete" type="text" size="mini" class="danger" @click="remove(scope.row)">删除</el-button></template></el-table-column> :columns="columns"
<template #empty><el-empty description="暂无数据" :image-size="80" /></template> :data="tableData"
</el-table> :loading="loading"
<div class="pager"><el-pagination background layout="total, sizes, prev, pager, next, jumper" :current-page="pagination.current" :page-size="pagination.size" :total="pagination.total" @current-change="changePage" @size-change="changeSize" /></div> :toolbar-buttons="toolbarButtons"
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="640px"><el-form ref="form" :model="form" label-width="130px" size="mini"><el-form-item v-for="field in formFields" :key="field.prop" :label="field.label" :prop="field.prop"><el-input v-model="form[field.prop]" clearable /></el-form-item></el-form><template #footer><el-button size="mini" @click="dialogVisible=false">取消</el-button><el-button type="primary" size="mini" :loading="saving" @click="save">确定</el-button></template></el-dialog> :row-buttons="rowButtons"
:pagination="pagination"
auto-height
@page-change="onPageChange"
@selection-change="onSelect"
/>
<page-dialog-form
ref="dialogForm"
:visible.sync="dialogVisible"
:title="dialogTitle"
width="40%"
:form-cols="formCols"
:form-data="formData"
:rules="rules"
label-width="130px"
:submitting="submitting"
:confirm-text="key('confirm')"
:cancel-text="key('cancel')"
@submit="onDialogSubmit"
@close="onDialogClose"
/>
</d2-container> </d2-container>
</template> </template>
<script> <script>
import { useTableColumns } from '@/composables/useTableColumns'
import { useTableButtons } from '@/composables/useTableButtons'
import { i18nMixin } from '@/composables/useI18n'
import { confirmMixin } from '@/composables/useConfirmHandle'
import PageTable from '@/components/page-table'
import PageDialogForm from '@/components/page-dialog-form'
import { getList, createItem, editItem, deleteItem } from '@/api/equipment-management/maintenance-items' import { getList, createItem, editItem, deleteItem } from '@/api/equipment-management/maintenance-items'
export default { export default {
name: 'equipment-management-maintenance-items', name: 'equipment-management-maintenance-items',
components: { PageTable, PageDialogForm },
mixins: [i18nMixin('page.equipment_management.maintenance_management.maintenance_items'), confirmMixin],
data () { data () {
return { return {
loading: false, loading: false,
saving: false, submitting: false,
canCreate: true,
canEdit: true,
canDelete: true,
canExport: false,
search: { keyword: '' },
tableData: [], tableData: [],
selectedRows: [],
dialogVisible: false,
dialogTitle: '',
editId: '',
handleType: 'create',
search: {
keyword: ''
},
pagination: { current: 1, size: 10, total: 0 }, pagination: { current: 1, size: 10, total: 0 },
columns: [ formData: {
{ prop: 'device_maintain_item_code', label: '保养项目编码' }, device_maintain_item_code: '',
{ prop: 'device_maintain_item_name', label: '保养项目名称' }, device_maintain_item_name: '',
{ prop: 'device_name', label: '设备名称' }, device_id: '',
{ prop: 'maintain_cycle', label: '保养周期' }, maintain_cycle: '',
{ prop: 'standard', label: '保养标准' }, standard: '',
{ prop: 'remark', label: '备注' } remark: ''
], },
formFields: [ rules: {
{ prop: 'device_maintain_item_code', label: '保养项目编码' }, device_maintain_item_code: [{ required: true, message: this.key('enter_maintenance_item_code'), trigger: 'blur' }],
{ prop: 'device_maintain_item_name', label: '保养项目名称' }, device_maintain_item_name: [{ required: true, message: this.key('enter_maintenance_item_name'), trigger: 'blur' }]
{ prop: 'device_id', label: '设备ID' }, },
{ prop: 'maintain_cycle', label: '保养周期' }, columns: [],
{ prop: 'standard', label: '保养标准' }, toolbarButtons: [],
{ prop: 'remark', label: '备注' } rowButtons: [],
], formCols: [
form: {}, [
dialogVisible: false {
type: 'input',
prop: 'device_maintain_item_code',
label: this.key('maintenance_item_code'),
placeholder: this.key('enter_maintenance_item_code'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'device_maintain_item_name',
label: this.key('maintenance_item_name'),
placeholder: this.key('enter_maintenance_item_name'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'device_id',
label: this.key('device_id'),
placeholder: this.key('enter_device_id'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'maintain_cycle',
label: this.key('maintenance_cycle'),
placeholder: this.key('enter_maintenance_cycle'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'standard',
label: this.key('standard'),
placeholder: this.key('enter_standard'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'remark',
label: this.key('remark'),
placeholder: this.key('enter_remark'),
inputType: 'textarea',
autosize: { minRows: 2, maxRows: 6 },
clearable: true,
style: { width: '90%' }
}
]
]
} }
}, },
computed: { created () {
dialogTitle () { return this.form && this.form.id ? '编辑设备保养项目' : '新增设备保养项目' }, this.columns = useTableColumns([
displayColumns () { const keys = new Set(this.columns.map(item => item.prop)); const extra = Object.keys(this.tableData[0] || {}).filter(key => !keys.has(key) && key !== 'id').slice(0, 8).map(key => ({ prop: key, label: key })); return [...this.columns, ...extra] } { prop: 'device_maintain_item_code', label: this.key('maintenance_item_code'), minWidth: 140 },
{ prop: 'device_maintain_item_name', label: this.key('maintenance_item_name'), minWidth: 140 },
{ prop: 'device_name', label: this.key('device_name'), minWidth: 140 },
{ prop: 'maintain_cycle', label: this.key('maintenance_cycle'), minWidth: 140 },
{ prop: 'standard', label: this.key('standard'), minWidth: 140 },
{ prop: 'remark', label: this.key('remark'), minWidth: 140 },
{ prop: '_actions', label: this.key('operation'), width: 170, fixed: 'right' }
])
const btns = useTableButtons({
toolbar: [
{ key: 'add', label: this.key('add'), icon: 'el-icon-plus', type: 'primary', auth: '/device_management/device_maintain/device_maintain_items/create', onClick: this.openAdd }
],
row: [
{ key: 'edit', label: this.key('edit'), icon: 'el-icon-edit', auth: '/device_management/device_maintain/device_maintain_items/edit', onClick: this.openEdit },
{ key: 'delete', label: this.key('delete'), icon: 'el-icon-delete', color: 'danger', auth: '/device_management/device_maintain/device_maintain_items/delete', onClick: this.handleDelete }
]
}, this.$permission)
this.toolbarButtons = btns.toolbarButtons
this.rowButtons = btns.rowButtons
this.fetchData()
}, },
mounted () { this.fetchData() },
methods: { methods: {
responseData (res) { return res && res.data !== undefined ? res.data : res }, normalizeResponse (res) {
normalizeList (data) { if (Array.isArray(data)) return { list: data, total: data.length }; if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }; if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) }; return { list: [], total: 0 } }, const data = res && res.data !== undefined ? res.data : res
buildParams () { return { ...this.search, page_no: this.pagination.current, page_size: this.pagination.size } }, if (Array.isArray(data)) return { list: data, total: data.length }
async fetchData () { this.loading = true; try { const res = await getList(this.buildParams()); const data = this.normalizeList(this.responseData(res)); this.tableData = data.list; this.pagination.total = data.total } finally { this.loading = false } }, if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }
onSearch () { this.pagination.current = 1; this.fetchData() }, if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) }
onReset () { this.search = { keyword: '' }; this.pagination.current = 1; this.fetchData() }, return { list: [], total: 0 }
changePage (page) { this.pagination.current = page; this.fetchData() }, },
changeSize (size) { this.pagination.size = size; this.pagination.current = 1; this.fetchData() }, async fetchData () {
openDialog (row) { this.form = row ? { ...row } : {}; this.dialogVisible = true }, this.loading = true
async save () {
this.saving = true
try { try {
if (this.form.id) await editItem(this.form) const res = await getList({ ...this.search, page_no: this.pagination.current, page_size: this.pagination.size })
else await createItem(this.form) const data = this.normalizeResponse(res)
this.$message.success('操作成功') this.tableData = data.list
this.pagination.total = data.total
} finally {
this.loading = false
}
},
onSearch () {
this.pagination.current = 1
this.fetchData()
},
onReset () {
this.search = {
keyword: ''
}
this.pagination.current = 1
this.fetchData()
},
onPageChange (page) {
this.pagination.current = page.current
this.pagination.size = page.size
this.fetchData()
},
onSelect (rows) {
this.selectedRows = rows
},
resetForm () {
this.formData = {
device_maintain_item_code: '',
device_maintain_item_name: '',
device_id: '',
maintain_cycle: '',
standard: '',
remark: ''
}
this.editId = ''
},
openAdd () {
this.handleType = 'create'
this.dialogTitle = this.key('add_title')
this.$nextTick(() => {
this.$refs.dialogForm && this.$refs.dialogForm.reset()
this.resetForm()
this.dialogVisible = true
})
},
openEdit (row) {
this.handleType = 'edit'
this.dialogTitle = this.key('edit_title')
this.editId = row.id
this.formData = {
device_maintain_item_code: row.device_maintain_item_code || '',
device_maintain_item_name: row.device_maintain_item_name || '',
device_id: row.device_id || '',
maintain_cycle: row.maintain_cycle || '',
standard: row.standard || '',
remark: row.remark || ''
}
this.dialogVisible = true
},
async onDialogSubmit () {
this.submitting = true
try {
if (this.handleType === 'create') await createItem(this.formData)
else await editItem({ ...this.formData, id: this.editId })
this.$message.success(this.$t(this.key('operation_success')))
this.dialogVisible = false this.dialogVisible = false
this.fetchData() this.fetchData()
} finally { this.saving = false } } finally {
this.submitting = false
}
}, },
async remove (row) { onDialogClose () {
await this.$confirm('确认删除该记录?', '提示', { type: 'warning' }) this.resetForm()
await deleteItem({ id: row.id }) },
this.$message.success('删除成功') async handleDelete (row) {
const cancelled = await this.$confirmAction(
{ message: this.key('confirm_delete'), title: this.key('tip') },
() => deleteItem({ id: [row.id] })
)
if (cancelled) return
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() this.fetchData()
} }
} }
} }
</script> </script>
<style lang="scss" scoped>
.search-bar { margin-bottom: -18px; } <style scoped>
.pager { padding-top: 10px; text-align: right; } .search-bar { padding: 10px 0; }
.danger { color: #f56c6c; } /deep/ .el-form-item--mini.el-form-item { margin-bottom: 4px; }
</style> </style>

View File

@@ -2,96 +2,258 @@
<d2-container> <d2-container>
<template #header> <template #header>
<div class="search-bar"> <div class="search-bar">
<el-form :inline="true" :model="search" size="mini"> <el-form :inline="true" size="mini">
<el-form-item label="关键字"><el-input v-model.trim="search.keyword" placeholder="请输入关键字" clearable style="width:180px" @keyup.enter.native="onSearch" /></el-form-item> <el-form-item :label="$t(key('keyword'))">
<el-input
v-model="search.keyword"
:placeholder="$t(key('enter_keyword'))"
clearable
style="width:200px"
@keyup.enter.native="onSearch"
/>
</el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" icon="el-icon-search" :disabled="loading" @click="onSearch">查询</el-button> <el-button type="primary" icon="el-icon-search" @click="onSearch">{{ $t(key('search')) }}</el-button>
<el-button icon="el-icon-refresh" :disabled="loading" @click="onReset">重置</el-button> <el-button icon="el-icon-refresh" @click="onReset">{{ $t(key('reset')) }}</el-button>
<el-button icon="el-icon-download" :disabled="loading" @click="exportTask">导出</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
</template> </template>
<el-table v-loading="loading" :data="tableData" size="mini" border height="calc(100vh - 220px)">
<el-table-column type="index" width="55" /> <page-table
<el-table-column v-for="column in displayColumns" :key="column.prop" :prop="column.prop" :label="column.label" min-width="150" show-overflow-tooltip /> ref="pageTable"
<el-table-column v-if="canEdit || canDelete" label="操作" fixed="right" width="150"><template slot-scope="scope"><el-button v-if="canEdit" type="text" size="mini" @click="openDialog(scope.row)">编辑</el-button><el-button v-if="canDelete" type="text" size="mini" class="danger" @click="remove(scope.row)">删除</el-button></template></el-table-column> :columns="columns"
<template #empty><el-empty description="暂无数据" :image-size="80" /></template> :data="tableData"
</el-table> :loading="loading"
<div class="pager"><el-pagination background layout="total, sizes, prev, pager, next, jumper" :current-page="pagination.current" :page-size="pagination.size" :total="pagination.total" @current-change="changePage" @size-change="changeSize" /></div> :toolbar-buttons="toolbarButtons"
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="640px"><el-form ref="form" :model="form" label-width="130px" size="mini"><el-form-item v-for="field in formFields" :key="field.prop" :label="field.label" :prop="field.prop"><el-input v-model="form[field.prop]" clearable /></el-form-item></el-form><template #footer><el-button size="mini" @click="dialogVisible=false">取消</el-button><el-button type="primary" size="mini" :loading="saving" @click="save">确定</el-button></template></el-dialog> :row-buttons="rowButtons"
:pagination="pagination"
auto-height
@page-change="onPageChange"
@selection-change="onSelect"
/>
<page-dialog-form
ref="dialogForm"
:visible.sync="dialogVisible"
:title="dialogTitle"
width="40%"
:form-cols="formCols"
:form-data="formData"
:rules="rules"
label-width="130px"
:submitting="submitting"
:confirm-text="key('confirm')"
:cancel-text="key('cancel')"
@submit="onDialogSubmit"
@close="onDialogClose"
/>
</d2-container> </d2-container>
</template> </template>
<script> <script>
import { useTableColumns } from '@/composables/useTableColumns'
import { useTableButtons } from '@/composables/useTableButtons'
import { i18nMixin } from '@/composables/useI18n'
import { confirmMixin } from '@/composables/useConfirmHandle'
import PageTable from '@/components/page-table'
import PageDialogForm from '@/components/page-dialog-form'
import { getList, editItem, createExportTask } from '@/api/equipment-management/maintenance-logs' import { getList, editItem, createExportTask } from '@/api/equipment-management/maintenance-logs'
export default { export default {
name: 'equipment-management-maintenance-logs', name: 'equipment-management-maintenance-logs',
components: { PageTable, PageDialogForm },
mixins: [i18nMixin('page.equipment_management.maintenance_management.maintenance_logs'), confirmMixin],
data () { data () {
return { return {
loading: false, loading: false,
saving: false, submitting: false,
canCreate: false,
canEdit: true,
canDelete: false,
canExport: true,
search: { keyword: '' },
tableData: [], tableData: [],
selectedRows: [],
dialogVisible: false,
dialogTitle: '',
editId: '',
handleType: 'create',
search: {
keyword: ''
},
pagination: { current: 1, size: 10, total: 0 }, pagination: { current: 1, size: 10, total: 0 },
columns: [ formData: {
{ prop: 'device_code', label: '设备编码' }, maintain_time: '',
{ prop: 'device_name', label: '设备名称' }, maintain_user: '',
{ prop: 'device_maintain_item_name', label: '保养项目' }, maintain_result: '',
{ prop: 'maintain_user', label: '保养人员' }, remark: ''
{ prop: 'maintain_time', label: '保养时间' }, },
{ prop: 'maintain_result', label: '保养结果' } rules: {
], maintain_time: [{ required: true, message: this.key('enter_maintenance_time'), trigger: 'blur' }],
formFields: [ maintain_user: [{ required: true, message: this.key('enter_maintenance_user'), trigger: 'blur' }]
{ prop: 'id', label: 'ID' }, },
{ prop: 'maintain_time', label: '保养时间' }, columns: [],
{ prop: 'maintain_user', label: '保养人员' }, toolbarButtons: [],
{ prop: 'maintain_result', label: '保养结果' }, rowButtons: [],
{ prop: 'remark', label: '备注' } formCols: [
], [
form: {}, {
dialogVisible: false type: 'input',
prop: 'maintain_time',
label: this.key('maintenance_time'),
placeholder: this.key('enter_maintenance_time'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'maintain_user',
label: this.key('maintenance_user'),
placeholder: this.key('enter_maintenance_user'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'maintain_result',
label: this.key('maintenance_result'),
placeholder: this.key('enter_maintenance_result'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'remark',
label: this.key('remark'),
placeholder: this.key('enter_remark'),
inputType: 'textarea',
autosize: { minRows: 2, maxRows: 6 },
clearable: true,
style: { width: '90%' }
}
]
]
} }
}, },
computed: { created () {
dialogTitle () { return this.form && this.form.id ? '编辑设备保养日志' : '新增设备保养日志' }, this.columns = useTableColumns([
displayColumns () { const keys = new Set(this.columns.map(item => item.prop)); const extra = Object.keys(this.tableData[0] || {}).filter(key => !keys.has(key) && key !== 'id').slice(0, 8).map(key => ({ prop: key, label: key })); return [...this.columns, ...extra] } { prop: 'device_code', label: this.key('device_code'), minWidth: 140 },
{ prop: 'device_name', label: this.key('device_name'), minWidth: 140 },
{ prop: 'device_maintain_item_name', label: this.key('maintenance_item'), minWidth: 140 },
{ prop: 'maintain_user', label: this.key('maintenance_user'), minWidth: 140 },
{ prop: 'maintain_time', label: this.key('maintenance_time'), minWidth: 140 },
{ prop: 'maintain_result', label: this.key('maintenance_result'), minWidth: 140 },
{ prop: '_actions', label: this.key('operation'), width: 170, fixed: 'right' }
])
const btns = useTableButtons({
toolbar: [
{ key: 'export', label: this.key('export'), icon: 'el-icon-download', auth: '/device_management/device_maintain/device_maintain_items_log/export', onClick: this.handleExport }
],
row: [
{ key: 'edit', label: this.key('edit'), icon: 'el-icon-edit', auth: '/device_management/device_maintain/device_maintain_items_log/edit', onClick: this.openEdit }
]
}, this.$permission)
this.toolbarButtons = btns.toolbarButtons
this.rowButtons = btns.rowButtons
this.fetchData()
}, },
mounted () { this.fetchData() },
methods: { methods: {
responseData (res) { return res && res.data !== undefined ? res.data : res }, normalizeResponse (res) {
normalizeList (data) { if (Array.isArray(data)) return { list: data, total: data.length }; if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }; if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) }; return { list: [], total: 0 } }, const data = res && res.data !== undefined ? res.data : res
buildParams () { return { ...this.search, page_no: this.pagination.current, page_size: this.pagination.size } }, if (Array.isArray(data)) return { list: data, total: data.length }
async fetchData () { this.loading = true; try { const res = await getList(this.buildParams()); const data = this.normalizeList(this.responseData(res)); this.tableData = data.list; this.pagination.total = data.total } finally { this.loading = false } }, if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }
onSearch () { this.pagination.current = 1; this.fetchData() }, if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) }
onReset () { this.search = { keyword: '' }; this.pagination.current = 1; this.fetchData() }, return { list: [], total: 0 }
changePage (page) { this.pagination.current = page; this.fetchData() }, },
changeSize (size) { this.pagination.size = size; this.pagination.current = 1; this.fetchData() }, async fetchData () {
openDialog (row) { this.form = row ? { ...row } : {}; this.dialogVisible = true }, this.loading = true
async save () {
this.saving = true
try { try {
if (!this.form.id) { this.$message.warning('请选择需要编辑的记录'); return } const res = await getList({ ...this.search, page_no: this.pagination.current, page_size: this.pagination.size })
await editItem(this.form) const data = this.normalizeResponse(res)
this.$message.success('操作成功') this.tableData = data.list
this.pagination.total = data.total
} finally {
this.loading = false
}
},
onSearch () {
this.pagination.current = 1
this.fetchData()
},
onReset () {
this.search = {
keyword: ''
}
this.pagination.current = 1
this.fetchData()
},
onPageChange (page) {
this.pagination.current = page.current
this.pagination.size = page.size
this.fetchData()
},
onSelect (rows) {
this.selectedRows = rows
},
resetForm () {
this.formData = {
maintain_time: '',
maintain_user: '',
maintain_result: '',
remark: ''
}
this.editId = ''
},
openAdd () {
this.handleType = 'create'
this.dialogTitle = this.key('add_title')
this.$nextTick(() => {
this.$refs.dialogForm && this.$refs.dialogForm.reset()
this.resetForm()
this.dialogVisible = true
})
},
openEdit (row) {
this.handleType = 'edit'
this.dialogTitle = this.key('edit_title')
this.editId = row.id
this.formData = {
maintain_time: row.maintain_time || '',
maintain_user: row.maintain_user || '',
maintain_result: row.maintain_result || '',
remark: row.remark || ''
}
this.dialogVisible = true
},
async onDialogSubmit () {
this.submitting = true
try {
await editItem({ ...this.formData, id: this.editId })
this.$message.success(this.$t(this.key('operation_success')))
this.dialogVisible = false this.dialogVisible = false
this.fetchData() this.fetchData()
} finally { this.saving = false } } finally {
this.submitting = false
}
}, },
async exportTask () { onDialogClose () {
await this.$confirm('确认创建导出任务?', '提示', { type: 'warning' }) this.resetForm()
await createExportTask(this.buildParams()) },
this.$message.success('导出任务创建成功') async handleExport () {
const cancelled = await this.$confirmAction(
{ message: this.key('confirm_export'), title: this.key('tip') },
() => createExportTask({ ...this.search })
)
if (cancelled) return
this.$message.success(this.$t(this.key('operation_success')))
} }
} }
} }
</script> </script>
<style lang="scss" scoped>
.search-bar { margin-bottom: -18px; } <style scoped>
.pager { padding-top: 10px; text-align: right; } .search-bar { padding: 10px 0; }
.danger { color: #f56c6c; } /deep/ .el-form-item--mini.el-form-item { margin-bottom: 4px; }
</style> </style>

View File

@@ -1,71 +1,298 @@
<template> <template>
<d2-container> <d2-container>
<template #header><div class="search-bar"><el-form :inline="true" :model="search" size="mini"><el-form-item label="关键字"><el-input v-model.trim="search.keyword" placeholder="请输入关键字" clearable style="width:180px" @keyup.enter.native="onSearch" /></el-form-item><el-form-item><el-button type="primary" icon="el-icon-search" :disabled="loading" @click="onSearch">查询</el-button><el-button icon="el-icon-refresh" :disabled="loading" @click="onReset">重置</el-button><el-button type="primary" icon="el-icon-plus" @click="openDialog()">新增</el-button><el-button icon="el-icon-download" :disabled="loading" @click="exportTask">导出</el-button></el-form-item></el-form></div></template> <template #header>
<el-table v-loading="loading" :data="tableData" size="mini" border height="calc(100vh - 220px)"><el-table-column type="index" width="55" /><el-table-column v-for="column in displayColumns" :key="column.prop" :prop="column.prop" :label="column.label" min-width="150" show-overflow-tooltip /><el-table-column v-if="canEdit || canDelete" label="操作" fixed="right" width="150"><template slot-scope="scope"><el-button v-if="canEdit" type="text" size="mini" @click="openDialog(scope.row)">编辑</el-button><el-button v-if="canDelete" type="text" size="mini" class="danger" @click="remove(scope.row)">删除</el-button></template></el-table-column><template #empty><el-empty description="暂无数据" :image-size="80" /></template></el-table> <div class="search-bar">
<div class="pager"><el-pagination background layout="total, sizes, prev, pager, next, jumper" :current-page="pagination.current" :page-size="pagination.size" :total="pagination.total" @current-change="changePage" @size-change="changeSize" /></div> <el-form :inline="true" size="mini">
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="640px"><el-form ref="form" :model="form" label-width="130px" size="mini"><el-form-item v-for="field in formFields" :key="field.prop" :label="field.label" :prop="field.prop"><el-input v-model="form[field.prop]" clearable /></el-form-item></el-form><template #footer><el-button size="mini" @click="dialogVisible=false">取消</el-button><el-button type="primary" size="mini" :loading="saving" @click="save">确定</el-button></template></el-dialog> <el-form-item :label="$t(key('keyword'))">
<el-input
v-model="search.keyword"
:placeholder="$t(key('enter_keyword'))"
clearable
style="width:200px"
@keyup.enter.native="onSearch"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="onSearch">{{ $t(key('search')) }}</el-button>
<el-button icon="el-icon-refresh" @click="onReset">{{ $t(key('reset')) }}</el-button>
</el-form-item>
</el-form>
</div>
</template>
<page-table
ref="pageTable"
:columns="columns"
:data="tableData"
:loading="loading"
:toolbar-buttons="toolbarButtons"
:row-buttons="rowButtons"
:pagination="pagination"
auto-height
@page-change="onPageChange"
@selection-change="onSelect"
/>
<page-dialog-form
ref="dialogForm"
:visible.sync="dialogVisible"
:title="dialogTitle"
width="40%"
:form-cols="formCols"
:form-data="formData"
:rules="rules"
label-width="130px"
:submitting="submitting"
:confirm-text="key('confirm')"
:cancel-text="key('cancel')"
@submit="onDialogSubmit"
@close="onDialogClose"
/>
</d2-container> </d2-container>
</template> </template>
<script> <script>
import { useTableColumns } from '@/composables/useTableColumns'
import { useTableButtons } from '@/composables/useTableButtons'
import { i18nMixin } from '@/composables/useI18n'
import { confirmMixin } from '@/composables/useConfirmHandle'
import PageTable from '@/components/page-table'
import PageDialogForm from '@/components/page-dialog-form'
import { getList, createItem, editItem, deleteItem, createExportTask } from '@/api/equipment-management/repair-logs' import { getList, createItem, editItem, deleteItem, createExportTask } from '@/api/equipment-management/repair-logs'
export default { export default {
name: 'equipment-management-repair-logs', name: 'equipment-management-repair-logs',
components: { PageTable, PageDialogForm },
mixins: [i18nMixin('page.equipment_management.repair_management.repair_logs'), confirmMixin],
data () { data () {
return { return {
loading: false, loading: false,
saving: false, submitting: false,
canCreate: true,
canEdit: true,
canDelete: true,
canExport: true,
search: { keyword: '' },
tableData: [], tableData: [],
selectedRows: [],
dialogVisible: false,
dialogTitle: '',
editId: '',
handleType: 'create',
search: {
keyword: ''
},
pagination: { current: 1, size: 10, total: 0 }, pagination: { current: 1, size: 10, total: 0 },
columns: [ formData: {
{ prop: 'order_no', label: '维修单号' }, order_no: '',
{ prop: 'device_code', label: '设备编码' }, device_id: '',
{ prop: 'device_name', label: '设备名称' }, repair_user: '',
{ prop: 'repair_user', label: '维修人员' }, repair_time: '',
{ prop: 'repair_time', label: '维修时间' }, repair_result: '',
{ prop: 'repair_result', label: '维修结果' } remark: ''
], },
formFields: [ rules: {
{ prop: 'order_no', label: '维修单号' }, order_no: [{ required: true, message: this.key('enter_repair_order_no'), trigger: 'blur' }],
{ prop: 'device_id', label: '设备ID' }, device_id: [{ required: true, message: this.key('enter_device_id'), trigger: 'blur' }]
{ prop: 'repair_user', label: '维修人员' }, },
{ prop: 'repair_time', label: '维修时间' }, columns: [],
{ prop: 'repair_result', label: '维修结果' }, toolbarButtons: [],
{ prop: 'remark', label: '备注' } rowButtons: [],
], formCols: [
form: {}, [
dialogVisible: false {
type: 'input',
prop: 'order_no',
label: this.key('repair_order_no'),
placeholder: this.key('enter_repair_order_no'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'device_id',
label: this.key('device_id'),
placeholder: this.key('enter_device_id'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'repair_user',
label: this.key('repair_user'),
placeholder: this.key('enter_repair_user'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'repair_time',
label: this.key('repair_time'),
placeholder: this.key('enter_repair_time'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'repair_result',
label: this.key('repair_result'),
placeholder: this.key('enter_repair_result'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'remark',
label: this.key('remark'),
placeholder: this.key('enter_remark'),
inputType: 'textarea',
autosize: { minRows: 2, maxRows: 6 },
clearable: true,
style: { width: '90%' }
}
]
]
} }
}, },
computed: { dialogTitle () { return this.form && this.form.id ? '编辑设备维修日志' : '新增设备维修日志' }, displayColumns () { const keys = new Set(this.columns.map(item => item.prop)); const extra = Object.keys(this.tableData[0] || {}).filter(key => !keys.has(key) && key !== 'id').slice(0, 8).map(key => ({ prop: key, label: key })); return [...this.columns, ...extra] } }, created () {
mounted () { this.fetchData() }, this.columns = useTableColumns([
{ prop: 'order_no', label: this.key('repair_order_no'), minWidth: 140 },
{ prop: 'device_code', label: this.key('device_code'), minWidth: 140 },
{ prop: 'device_name', label: this.key('device_name'), minWidth: 140 },
{ prop: 'repair_user', label: this.key('repair_user'), minWidth: 140 },
{ prop: 'repair_time', label: this.key('repair_time'), minWidth: 140 },
{ prop: 'repair_result', label: this.key('repair_result'), minWidth: 140 },
{ prop: '_actions', label: this.key('operation'), width: 170, fixed: 'right' }
])
const btns = useTableButtons({
toolbar: [
{ key: 'add', label: this.key('add'), icon: 'el-icon-plus', type: 'primary', auth: '/device_management/device_repair/device_repair_log/create', onClick: this.openAdd },
{ key: 'export', label: this.key('export'), icon: 'el-icon-download', auth: '/device_management/device_repair/device_repair_log/export', onClick: this.handleExport }
],
row: [
{ key: 'edit', label: this.key('edit'), icon: 'el-icon-edit', auth: '/device_management/device_repair/device_repair_log/edit', onClick: this.openEdit },
{ key: 'delete', label: this.key('delete'), icon: 'el-icon-delete', color: 'danger', auth: '/device_management/device_repair/device_repair_log/delete', onClick: this.handleDelete }
]
}, this.$permission)
this.toolbarButtons = btns.toolbarButtons
this.rowButtons = btns.rowButtons
this.fetchData()
},
methods: { methods: {
responseData (res) { return res && res.data !== undefined ? res.data : res }, normalizeResponse (res) {
normalizeList (data) { if (Array.isArray(data)) return { list: data, total: data.length }; if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }; if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) }; return { list: [], total: 0 } }, const data = res && res.data !== undefined ? res.data : res
buildParams () { return { ...this.search, page_no: this.pagination.current, page_size: this.pagination.size } }, if (Array.isArray(data)) return { list: data, total: data.length }
async fetchData () { this.loading = true; try { const res = await getList(this.buildParams()); const data = this.normalizeList(this.responseData(res)); this.tableData = data.list; this.pagination.total = data.total } finally { this.loading = false } }, if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }
onSearch () { this.pagination.current = 1; this.fetchData() }, if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) }
onReset () { this.search = { keyword: '' }; this.pagination.current = 1; this.fetchData() }, return { list: [], total: 0 }
changePage (page) { this.pagination.current = page; this.fetchData() }, },
changeSize (size) { this.pagination.size = size; this.pagination.current = 1; this.fetchData() }, async fetchData () {
openDialog (row) { this.form = row ? { ...row } : {}; this.dialogVisible = true }, this.loading = true
async save () {
this.saving = true
try { try {
if (this.form.id) await editItem(this.form) const res = await getList({ ...this.search, page_no: this.pagination.current, page_size: this.pagination.size })
else await createItem(this.form) const data = this.normalizeResponse(res)
this.$message.success('操作成功') this.tableData = data.list
this.pagination.total = data.total
} finally {
this.loading = false
}
},
onSearch () {
this.pagination.current = 1
this.fetchData()
},
onReset () {
this.search = {
keyword: ''
}
this.pagination.current = 1
this.fetchData()
},
onPageChange (page) {
this.pagination.current = page.current
this.pagination.size = page.size
this.fetchData()
},
onSelect (rows) {
this.selectedRows = rows
},
resetForm () {
this.formData = {
order_no: '',
device_id: '',
repair_user: '',
repair_time: '',
repair_result: '',
remark: ''
}
this.editId = ''
},
openAdd () {
this.handleType = 'create'
this.dialogTitle = this.key('add_title')
this.$nextTick(() => {
this.$refs.dialogForm && this.$refs.dialogForm.reset()
this.resetForm()
this.dialogVisible = true
})
},
openEdit (row) {
this.handleType = 'edit'
this.dialogTitle = this.key('edit_title')
this.editId = row.id
this.formData = {
order_no: row.order_no || '',
device_id: row.device_id || '',
repair_user: row.repair_user || '',
repair_time: row.repair_time || '',
repair_result: row.repair_result || '',
remark: row.remark || ''
}
this.dialogVisible = true
},
async onDialogSubmit () {
this.submitting = true
try {
if (this.handleType === 'create') await createItem(this.formData)
else await editItem({ ...this.formData, id: this.editId })
this.$message.success(this.$t(this.key('operation_success')))
this.dialogVisible = false this.dialogVisible = false
this.fetchData() this.fetchData()
} finally { this.saving = false } } finally {
this.submitting = false
}
}, },
async remove (row) { await this.$confirm('确认删除该记录?', '提示', { type: 'warning' }); await deleteItem({ id: row.id }); this.$message.success('删除成功'); this.fetchData() }, onDialogClose () {
async exportTask () { await this.$confirm('确认创建导出任务?', '提示', { type: 'warning' }); await createExportTask(this.buildParams()); this.$message.success('导出任务创建成功') } this.resetForm()
},
async handleDelete (row) {
const cancelled = await this.$confirmAction(
{ message: this.key('confirm_delete'), title: this.key('tip') },
() => deleteItem({ id: [row.id] })
)
if (cancelled) return
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()
},
async handleExport () {
const cancelled = await this.$confirmAction(
{ message: this.key('confirm_export'), title: this.key('tip') },
() => createExportTask({ ...this.search })
)
if (cancelled) return
this.$message.success(this.$t(this.key('operation_success')))
}
} }
} }
</script> </script>
<style lang="scss" scoped>.search-bar { margin-bottom: -18px; }.pager { padding-top: 10px; text-align: right; }.danger { color: #f56c6c; }</style>
<style scoped>
.search-bar { padding: 10px 0; }
/deep/ .el-form-item--mini.el-form-item { margin-bottom: 4px; }
</style>

View File

@@ -1,70 +1,287 @@
<template> <template>
<d2-container> <d2-container>
<template #header><div class="search-bar"><el-form :inline="true" :model="search" size="mini"><el-form-item label="关键字"><el-input v-model.trim="search.keyword" placeholder="请输入关键字" clearable style="width:180px" @keyup.enter.native="onSearch" /></el-form-item><el-form-item><el-button type="primary" icon="el-icon-search" :disabled="loading" @click="onSearch">查询</el-button><el-button icon="el-icon-refresh" :disabled="loading" @click="onReset">重置</el-button><el-button type="primary" icon="el-icon-plus" @click="openDialog()">新增</el-button><el-button icon="el-icon-download" :disabled="loading" @click="exportTask">导出</el-button></el-form-item></el-form></div></template> <template #header>
<el-table v-loading="loading" :data="tableData" size="mini" border height="calc(100vh - 220px)"><el-table-column type="index" width="55" /><el-table-column v-for="column in displayColumns" :key="column.prop" :prop="column.prop" :label="column.label" min-width="150" show-overflow-tooltip /><el-table-column v-if="canEdit || canDelete" label="操作" fixed="right" width="150"><template slot-scope="scope"><el-button v-if="canEdit" type="text" size="mini" @click="openDialog(scope.row)">编辑</el-button><el-button v-if="canDelete" type="text" size="mini" class="danger" @click="remove(scope.row)">删除</el-button></template></el-table-column><template #empty><el-empty description="暂无数据" :image-size="80" /></template></el-table> <div class="search-bar">
<div class="pager"><el-pagination background layout="total, sizes, prev, pager, next, jumper" :current-page="pagination.current" :page-size="pagination.size" :total="pagination.total" @current-change="changePage" @size-change="changeSize" /></div> <el-form :inline="true" size="mini">
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="640px"><el-form ref="form" :model="form" label-width="130px" size="mini"><el-form-item v-for="field in formFields" :key="field.prop" :label="field.label" :prop="field.prop"><el-input v-model="form[field.prop]" clearable /></el-form-item></el-form><template #footer><el-button size="mini" @click="dialogVisible=false">取消</el-button><el-button type="primary" size="mini" :loading="saving" @click="save">确定</el-button></template></el-dialog> <el-form-item :label="$t(key('keyword'))">
<el-input
v-model="search.keyword"
:placeholder="$t(key('enter_keyword'))"
clearable
style="width:200px"
@keyup.enter.native="onSearch"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="onSearch">{{ $t(key('search')) }}</el-button>
<el-button icon="el-icon-refresh" @click="onReset">{{ $t(key('reset')) }}</el-button>
</el-form-item>
</el-form>
</div>
</template>
<page-table
ref="pageTable"
:columns="columns"
:data="tableData"
:loading="loading"
:toolbar-buttons="toolbarButtons"
:row-buttons="rowButtons"
:pagination="pagination"
auto-height
@page-change="onPageChange"
@selection-change="onSelect"
/>
<page-dialog-form
ref="dialogForm"
:visible.sync="dialogVisible"
:title="dialogTitle"
width="40%"
:form-cols="formCols"
:form-data="formData"
:rules="rules"
label-width="130px"
:submitting="submitting"
:confirm-text="key('confirm')"
:cancel-text="key('cancel')"
@submit="onDialogSubmit"
@close="onDialogClose"
/>
</d2-container> </d2-container>
</template> </template>
<script> <script>
import { useTableColumns } from '@/composables/useTableColumns'
import { useTableButtons } from '@/composables/useTableButtons'
import { i18nMixin } from '@/composables/useI18n'
import { confirmMixin } from '@/composables/useConfirmHandle'
import PageTable from '@/components/page-table'
import PageDialogForm from '@/components/page-dialog-form'
import { getList, createItem, editItem, deleteItem, createExportTask } from '@/api/equipment-management/repair-management' import { getList, createItem, editItem, deleteItem, createExportTask } from '@/api/equipment-management/repair-management'
export default { export default {
name: 'equipment-management-repair-management', name: 'equipment-management-repair-management',
components: { PageTable, PageDialogForm },
mixins: [i18nMixin('page.equipment_management.repair_management.repair_management'), confirmMixin],
data () { data () {
return { return {
loading: false, loading: false,
saving: false, submitting: false,
canCreate: true,
canEdit: true,
canDelete: true,
canExport: true,
search: { keyword: '' },
tableData: [], tableData: [],
selectedRows: [],
dialogVisible: false,
dialogTitle: '',
editId: '',
handleType: 'create',
search: {
keyword: ''
},
pagination: { current: 1, size: 10, total: 0 }, pagination: { current: 1, size: 10, total: 0 },
columns: [ formData: {
{ prop: 'order_no', label: '报修单号' }, order_no: '',
{ prop: 'device_code', label: '设备编码' }, device_id: '',
{ prop: 'device_name', label: '设备名称' }, fault_desc: '',
{ prop: 'fault_desc', label: '故障描述' }, repair_status: '',
{ prop: 'repair_status', label: '维修状态' }, remark: ''
{ prop: 'create_time', label: '创建时间' } },
], rules: {
formFields: [ order_no: [{ required: true, message: this.key('enter_repair_order_no'), trigger: 'blur' }],
{ prop: 'order_no', label: '报修单号' }, device_id: [{ required: true, message: this.key('enter_device_id'), trigger: 'blur' }]
{ prop: 'device_id', label: '设备ID' }, },
{ prop: 'fault_desc', label: '故障描述' }, columns: [],
{ prop: 'repair_status', label: '维修状态' }, toolbarButtons: [],
{ prop: 'remark', label: '备注' } rowButtons: [],
], formCols: [
form: {}, [
dialogVisible: false {
type: 'input',
prop: 'order_no',
label: this.key('repair_order_no'),
placeholder: this.key('enter_repair_order_no'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'device_id',
label: this.key('device_id'),
placeholder: this.key('enter_device_id'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'fault_desc',
label: this.key('fault_desc'),
placeholder: this.key('enter_fault_desc'),
inputType: 'textarea',
autosize: { minRows: 2, maxRows: 6 },
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'repair_status',
label: this.key('repair_status'),
placeholder: this.key('enter_repair_status'),
clearable: true,
style: { width: '90%' }
}
],
[
{
type: 'input',
prop: 'remark',
label: this.key('remark'),
placeholder: this.key('enter_remark'),
inputType: 'textarea',
autosize: { minRows: 2, maxRows: 6 },
clearable: true,
style: { width: '90%' }
}
]
]
} }
}, },
computed: { dialogTitle () { return this.form && this.form.id ? '编辑设备维修管理' : '新增设备维修管理' }, displayColumns () { const keys = new Set(this.columns.map(item => item.prop)); const extra = Object.keys(this.tableData[0] || {}).filter(key => !keys.has(key) && key !== 'id').slice(0, 8).map(key => ({ prop: key, label: key })); return [...this.columns, ...extra] } }, created () {
mounted () { this.fetchData() }, this.columns = useTableColumns([
{ prop: 'order_no', label: this.key('repair_order_no'), minWidth: 140 },
{ prop: 'device_code', label: this.key('device_code'), minWidth: 140 },
{ prop: 'device_name', label: this.key('device_name'), minWidth: 140 },
{ prop: 'fault_desc', label: this.key('fault_desc'), minWidth: 140 },
{ prop: 'repair_status', label: this.key('repair_status'), minWidth: 140 },
{ prop: 'create_time', label: this.key('create_time'), minWidth: 140 },
{ prop: '_actions', label: this.key('operation'), width: 170, fixed: 'right' }
])
const btns = useTableButtons({
toolbar: [
{ key: 'add', label: this.key('add'), icon: 'el-icon-plus', type: 'primary', auth: '/device_management/device_repair/device_repair_management/create', onClick: this.openAdd },
{ key: 'export', label: this.key('export'), icon: 'el-icon-download', auth: '/device_management/device_repair/device_repair_management/export', onClick: this.handleExport }
],
row: [
{ key: 'edit', label: this.key('edit'), icon: 'el-icon-edit', auth: '/device_management/device_repair/device_repair_management/edit', onClick: this.openEdit },
{ key: 'delete', label: this.key('delete'), icon: 'el-icon-delete', color: 'danger', auth: '/device_management/device_repair/device_repair_management/delete', onClick: this.handleDelete }
]
}, this.$permission)
this.toolbarButtons = btns.toolbarButtons
this.rowButtons = btns.rowButtons
this.fetchData()
},
methods: { methods: {
responseData (res) { return res && res.data !== undefined ? res.data : res }, normalizeResponse (res) {
normalizeList (data) { if (Array.isArray(data)) return { list: data, total: data.length }; if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }; if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) }; return { list: [], total: 0 } }, const data = res && res.data !== undefined ? res.data : res
buildParams () { return { ...this.search, page_no: this.pagination.current, page_size: this.pagination.size } }, if (Array.isArray(data)) return { list: data, total: data.length }
async fetchData () { this.loading = true; try { const res = await getList(this.buildParams()); const data = this.normalizeList(this.responseData(res)); this.tableData = data.list; this.pagination.total = data.total } finally { this.loading = false } }, if (data && Array.isArray(data.data)) return { list: data.data, total: Number(data.count || data.total || data.data.length) }
onSearch () { this.pagination.current = 1; this.fetchData() }, if (data && data.data && Array.isArray(data.data.data)) return { list: data.data.data, total: Number(data.data.count || data.data.total || data.data.data.length) }
onReset () { this.search = { keyword: '' }; this.pagination.current = 1; this.fetchData() }, return { list: [], total: 0 }
changePage (page) { this.pagination.current = page; this.fetchData() }, },
changeSize (size) { this.pagination.size = size; this.pagination.current = 1; this.fetchData() }, async fetchData () {
openDialog (row) { this.form = row ? { ...row } : {}; this.dialogVisible = true }, this.loading = true
async save () {
this.saving = true
try { try {
if (this.form.id) await editItem(this.form) const res = await getList({ ...this.search, page_no: this.pagination.current, page_size: this.pagination.size })
else await createItem(this.form) const data = this.normalizeResponse(res)
this.$message.success('操作成功') this.tableData = data.list
this.pagination.total = data.total
} finally {
this.loading = false
}
},
onSearch () {
this.pagination.current = 1
this.fetchData()
},
onReset () {
this.search = {
keyword: ''
}
this.pagination.current = 1
this.fetchData()
},
onPageChange (page) {
this.pagination.current = page.current
this.pagination.size = page.size
this.fetchData()
},
onSelect (rows) {
this.selectedRows = rows
},
resetForm () {
this.formData = {
order_no: '',
device_id: '',
fault_desc: '',
repair_status: '',
remark: ''
}
this.editId = ''
},
openAdd () {
this.handleType = 'create'
this.dialogTitle = this.key('add_title')
this.$nextTick(() => {
this.$refs.dialogForm && this.$refs.dialogForm.reset()
this.resetForm()
this.dialogVisible = true
})
},
openEdit (row) {
this.handleType = 'edit'
this.dialogTitle = this.key('edit_title')
this.editId = row.id
this.formData = {
order_no: row.order_no || '',
device_id: row.device_id || '',
fault_desc: row.fault_desc || '',
repair_status: row.repair_status || '',
remark: row.remark || ''
}
this.dialogVisible = true
},
async onDialogSubmit () {
this.submitting = true
try {
if (this.handleType === 'create') await createItem(this.formData)
else await editItem({ ...this.formData, id: this.editId })
this.$message.success(this.$t(this.key('operation_success')))
this.dialogVisible = false this.dialogVisible = false
this.fetchData() this.fetchData()
} finally { this.saving = false } } finally {
this.submitting = false
}
}, },
async remove (row) { await this.$confirm('确认删除该记录?', '提示', { type: 'warning' }); await deleteItem({ id: row.id }); this.$message.success('删除成功'); this.fetchData() }, onDialogClose () {
async exportTask () { await this.$confirm('确认创建导出任务?', '提示', { type: 'warning' }); await createExportTask(this.buildParams()); this.$message.success('导出任务创建成功') } this.resetForm()
},
async handleDelete (row) {
const cancelled = await this.$confirmAction(
{ message: this.key('confirm_delete'), title: this.key('tip') },
() => deleteItem({ id: [row.id] })
)
if (cancelled) return
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()
},
async handleExport () {
const cancelled = await this.$confirmAction(
{ message: this.key('confirm_export'), title: this.key('tip') },
() => createExportTask({ ...this.search })
)
if (cancelled) return
this.$message.success(this.$t(this.key('operation_success')))
}
} }
} }
</script> </script>
<style lang="scss" scoped>.search-bar { margin-bottom: -18px; }.pager { padding-top: 10px; text-align: right; }.danger { color: #f56c6c; }</style>
<style scoped>
.search-bar { padding: 10px 0; }
/deep/ .el-form-item--mini.el-form-item { margin-bottom: 4px; }
</style>