# Conflicts:
#	src/views/mes/deviceledger/DeviceLedgerForm.vue
#	src/views/mes/deviceledger/index.vue
pull/1/head
黄伟杰 1 month ago
commit 41c328bc09

@ -56,4 +56,9 @@ export const ProductUnitApi = {
getProductUnitListByFlag: async () => {
return await request.get({ url: `/erp/product-unit/flag-list`})
},
// 下载用户导入模板
importUserTemplate: async () => {
return await request.download({ url: '/erp/product-unit/get-import-template' })
}
}

@ -10,6 +10,7 @@ export interface CriticalComponentVO {
remark?: string
qrcodeUrl?: string
createTime?: string
images?: string
}
export const CriticalComponentApi = {

@ -42,6 +42,7 @@ export interface DeviceLedgerVO {
createTime?: string | number | Date
updateTime?: string | number | Date
sort: number // 排序
images?: string // 图片
}
// 设备类型 API

@ -1192,6 +1192,7 @@ export default {
},
// Equipment Ledger
EquipmentLedger: {
images:'Images',
deviceCode: 'Code',
qrcode: 'QR Code/Barcode',
deviceName: 'Name',
@ -1294,7 +1295,8 @@ export default {
qrcodeLoadError: 'Failed to load QR code',
qrcodeEmpty: 'No QR code',
validatorCodeRequired: 'Code can not be empty',
validatorNameRequired: 'Name can not be empty'
validatorNameRequired: 'Name can not be empty',
images:'images'
},
// Maintenance Project (Project Maintenance)
DvSubject: {
@ -2115,6 +2117,7 @@ export default {
resetButtonText: 'Reset',
addButtonText: 'Add',
exportButtonText: 'Export',
importButtonText: 'Import',
tableNameColumn: 'Unit Name',
tablePrimaryFlagColumn: 'Is Primary Unit',
tableChangeRateColumn: 'Conversion Rate to Primary Unit',
@ -2135,7 +2138,17 @@ export default {
dialogSubmitButton: 'Confirm',
validatorNameRequired: 'Unit name can not be empty',
validatorStatusRequired: 'Unit status can not be empty',
validatorPrimaryFlagRequired: 'Primary unit flag can not be empty'
validatorPrimaryFlagRequired: 'Primary unit flag can not be empty',
import:'Import unit',
importDragText: 'Drag file here, or',
importClickText: 'click to upload',
importUpdateSupport: 'Update existing user data if present',
importFormatLimit: 'Only xls, xlsx format files are allowed.',
importDownloadTemplate: 'Download template',
importFileRequired: 'Please upload file',
importSuccessTip: 'Upload success: {createCount}; Update success: {updateCount}; Update failed: {failureCount};',
importFailed: 'Upload failed, please upload again!',
importFileLimit: 'Only one file can be uploaded!',
},
CalHoliday: {
setWorkingDays: 'set working days',

@ -972,7 +972,7 @@ export default {
actions: '操作',
password: '用户密码',
role: '角色',
import: '用户导入',
import: '用户',
importDragText: '将文件拖到此处,或',
importClickText: '点击上传',
importUpdateSupport: '是否更新已经存在的用户数据',
@ -1184,6 +1184,7 @@ export default {
},
// 设备台账
EquipmentLedger: {
images:'图片',
deviceCode: '编码',
qrcode: '二维码/条形码',
deviceName: '名称',
@ -1191,8 +1192,8 @@ export default {
statusEnabled: '启用',
statusDisabled: '不启用',
deviceType: '类型',
deviceSpec: '规格',
deviceModel: '型号',
deviceSpec: '规格型号',
/* deviceModel: '型号',*/
isSchedueld: '是否排产',
ratedCapacity: '额定产能',
yes: '是',
@ -1215,7 +1216,7 @@ export default {
placeholderDeviceStatus: '请选择状态',
placeholderDeviceType: '请选择类型',
placeholderDeviceModel: '请输入型号',
placeholderDeviceSpec: '请输入规格',
placeholderDeviceSpec: '请输入规格型号',
placeholderRatedCapacity: '请输入额定产能',
placeholderProductionDate: '请选择生产日期',
placeholderFactoryEntryDate: '请选择入厂日期',
@ -1273,6 +1274,7 @@ export default {
code: '编码',
qrcode: '二维码/条形码',
name: '名称',
deviceSpec:'规格型号',
batchDelete: '批量删除',
description: '描述',
remark: '备注',
@ -1282,20 +1284,22 @@ export default {
delete: '删除',
placeholderCode: '请输入编码',
placeholderName: '请输入名称',
placeholderDeviceSpec: '请输入规格型号',
placeholderDescription: '请输入描述',
placeholderRemark: '请输入备注',
placeholderCount: '请输入数量',
qrcodeLoadError: '二维码加载失败',
qrcodeEmpty: '暂无二维码',
validatorCodeRequired: '编码不能为空',
validatorNameRequired: '名称不能为空'
validatorNameRequired: '名称不能为空',
images:'图片'
},
// 项目维护
DvSubject: {
code: '编码',
name: '名称',
inspectionMethod: '检验方式',
valueType: '类型',
inspectionMethod: '作业方式',
valueType: '结果类型',
judgmentCriteria: '判定基准',
upperVal: '上限值',
lowerVal: '下限值',
@ -1548,6 +1552,7 @@ export default {
SpareInfo: {
name: '备件名称',
code: '备件编码',
deviceSpec:'规格型号',
qrcode: '二维码/条形码',
standard: '规格',
expiryDay: '保质期天数',
@ -1561,6 +1566,7 @@ export default {
exportFilename: '备件信息.xls',
placeholderName: '请输入名称',
placeholderCode: '请输入编码',
placeholderDeviceSpec: '请输入规格型号',
placeholderUnit: '请选择单位',
placeholderSafetyNumber: '请输入预警库存数量',
placeholderRemark: '请输入备注',
@ -2957,7 +2963,19 @@ export default {
dialogSubmitButton: '确 定',
validatorNameRequired: '单位名称不能为空',
validatorStatusRequired: '单位状态不能为空',
validatorPrimaryFlagRequired: '是否主单位不能为空'
validatorPrimaryFlagRequired: '是否主单位不能为空',
importButtonText:'导入',
import:'导入单位',
importDragText: '将文件拖到此处,或',
importClickText: '点击上传',
importUpdateSupport: '是否更新已经存在的用户数据',
importFormatLimit: '仅允许导入 xls、xlsx 格式文件。',
importDownloadTemplate: '下载模板',
importFileRequired: '请上传文件',
importSuccessTip:
'上传成功数量:{createCount};更新成功数量:{updateCount};更新失败数量:{failureCount}',
importFailed: '上传失败,请您重新上传!',
importFileLimit: '最多只能上传一个文件!',
},
//假日管理
CalHoliday: {

@ -36,6 +36,11 @@
<el-input v-model="formData.name" :placeholder="t('SparePartsManagement.SpareInfo.placeholderName')" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="t('SparePartsManagement.SpareInfo.deviceSpec')" prop="deviceSpec">
<el-input v-model="formData.deviceSpec" :placeholder="t('SparePartsManagement.SpareInfo.placeholderDeviceSpec')" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="t('SparePartsManagement.SpareInfo.unit')" prop="unitId">
<el-select v-model="formData.unitId" clearable :placeholder="t('SparePartsManagement.SpareInfo.placeholderUnit')" class="w-1/1">

@ -58,6 +58,7 @@
<el-table-column :label="t('SparePartsManagement.SpareInfo.code')" align="center" prop="barCode" width="240px" sortable />
<el-table-column :label="t('SparePartsManagement.SpareInfo.name')" align="left" prop="name" width="220px" sortable />
<el-table-column v-if="checkPermi(['erp:component:standard'])" :label="t('SparePartsManagement.SpareInfo.standard')" align="center" prop="standard" />
<el-table-column :label="t('SparePartsManagement.SpareInfo.deviceSpec')" align="center" prop="deviceSpec" sortable />
<el-table-column :label="t('SparePartsManagement.SpareInfo.category')" align="center" prop="categoryName" sortable />
<el-table-column :label="t('SparePartsManagement.SpareInfo.unit')" align="center" prop="unitName" sortable />
<el-table-column :label="t('SparePartsManagement.SpareInfo.safetyNumber')" align="center" prop="safetyNumber" />

@ -0,0 +1,144 @@
<template>
<Dialog v-model="dialogVisible" :title="t('FactoryModeling.ProductUnit.import')" width="400">
<el-upload
ref="uploadRef"
v-model:file-list="fileList"
:action="importUrl + '?updateSupport=' + updateSupport"
:auto-upload="false"
:disabled="formLoading"
:headers="uploadHeaders"
:limit="1"
:on-error="submitFormError"
:on-exceed="handleExceed"
:on-success="submitFormSuccess"
accept=".xlsx, .xls"
drag
>
<Icon icon="ep:upload" />
<div class="el-upload__text">
{{ t('FactoryModeling.ProductUnit.importDragText') }}<em>{{ t('FactoryModeling.ProductUnit.importClickText') }}</em>
</div>
<template #tip>
<div class="el-upload__tip text-center">
<!-- <div class="el-upload__tip">
<el-checkbox v-model="updateSupport" />
{{ t('FactoryModeling.ProductUnit.importUpdateSupport') }}
</div>-->
<span>{{ t('FactoryModeling.ProductUnit.importFormatLimit') }}</span>
<el-link
:underline="false"
style="font-size: 12px; vertical-align: baseline"
type="primary"
@click="importTemplate"
>
{{ t('FactoryModeling.ProductUnit.importDownloadTemplate') }}
</el-link>
</div>
</template>
</el-upload>
<template #footer>
<el-button :disabled="formLoading" type="primary" @click="submitForm">{{ t('common.ok') }}</el-button>
<el-button @click="dialogVisible = false">{{ t('common.cancel') }}</el-button>
</template>
</Dialog>
</template>
<script lang="ts" setup>
import * as UserApi from '@/api/system/user'
import { getAccessToken, getTenantId } from '@/utils/auth'
import download from '@/utils/download'
import {ProductUnitApi} from "@/api/erp/product/unit";
defineOptions({ name: 'ProductUnitImportForm' })
const { t } = useI18n() //
const message = useMessage() //
const dialogVisible = ref(false) //
const formLoading = ref(false) //
const uploadRef = ref()
const importUrl =
import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/erp/product-unit/import'
const uploadHeaders = ref() // Header
const fileList = ref([]) //
const updateSupport = ref(0) //
/** 打开弹窗 */
const open = () => {
dialogVisible.value = true
updateSupport.value = 0
fileList.value = []
resetForm()
}
defineExpose({ open }) // open
/** 提交表单 */
const submitForm = async () => {
if (fileList.value.length == 0) {
message.error(t('FactoryModeling.ProductUnit.importFileRequired'))
return
}
//
uploadHeaders.value = {
Authorization: 'Bearer ' + getAccessToken(),
'tenantId': getTenantId()
}
formLoading.value = true
uploadRef.value!.submit()
}
/** 文件上传成功 */
const emits = defineEmits(['success'])
const submitFormSuccess = (response: any) => {
if (response.code !== 0) {
message.error(response.msg)
formLoading.value = false
return
}
/* // 拼接提示语
const data = response.data
let text = t('FactoryModeling.ProductUnit.importSuccessTip', {
createCount: data.createUsernames.length,
updateCount: data.updateUsernames.length,
failureCount: Object.keys(data.failureUsernames).length
})
for (let username of data.createUsernames) {
text += '< ' + username + ' >'
}
for (const username of data.updateUsernames) {
text += '< ' + username + ' >'
}
for (const username in data.failureUsernames) {
text += '< ' + username + ': ' + data.failureUsernames[username] + ' >'
}*/
message.alert(response.data)
formLoading.value = false
dialogVisible.value = false
//
emits('success')
}
/** 上传错误提示 */
const submitFormError = (): void => {
message.error(t('FactoryModeling.ProductUnit.importFailed'))
formLoading.value = false
}
/** 重置表单 */
const resetForm = async (): Promise<void> => {
//
formLoading.value = false
await nextTick()
uploadRef.value?.clearFiles()
}
/** 文件数超出提示 */
const handleExceed = (): void => {
message.error(t('FactoryModeling.ProductUnit.importFileLimit'))
}
/** 下载模板操作 */
const importTemplate = async () => {
const res = await ProductUnitApi.importUserTemplate()
download.excel(res, '单位导入模版.xls')
}
</script>

@ -50,6 +50,14 @@
<Icon icon="ep:plus" class="mr-5px" />
{{ t('FactoryModeling.ProductUnit.addButtonText') }}
</el-button>
<el-button
type="warning"
plain
@click="handleImport"
v-hasPermi="['system:user:import']"
>
<Icon icon="ep:upload" /> {{ t('FactoryModeling.ProductUnit.importButtonText') }}
</el-button>
<el-button
type="success"
plain
@ -129,6 +137,9 @@
<!-- 表单弹窗添加/修改 -->
<ProductUnitForm ref="formRef" @success="getList" />
<!-- 单位导入对话框 -->
<ProductUnitImportForm ref="importFormRef" @success="getList" />
</template>
<script setup lang="ts">
@ -199,6 +210,12 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 导入 */
const importFormRef = ref()
const handleImport = () => {
importFormRef.value.open()
}
/** 导出按钮操作 */
const handleExport = async () => {
try {

@ -1864,7 +1864,7 @@ const handleShowDeviceAlarmHistory = async () => {
background-color: #fff;
border-radius: 4px;
padding: 16px;
max-height: calc(100vh - 546px);
/* max-height: calc(100vh - 546px);*/
overflow-y: auto;
.empty-grid { //

@ -29,6 +29,13 @@
clearable
/>
</el-form-item>
<el-form-item :label="t('EquipmentManagement.EquipmentKeyItems.deviceSpec')" prop="deviceSpec">
<el-input
v-model="formData.deviceSpec"
:placeholder="t('EquipmentManagement.EquipmentKeyItems.placeholderDeviceSpec')"
clearable
/>
</el-form-item>
<el-form-item :label="t('EquipmentManagement.EquipmentKeyItems.description')" prop="description">
<el-input
v-model="formData.description"
@ -45,7 +52,14 @@
type="number"
/>
</el-form-item>
<el-form-item v-if="formType === 'update'" :label="t('EquipmentManagement.EquipmentKeyItems.qrcode')" prop="qrcodeUrl">
<el-row :gutter="16">
<!-- <el-col :span="24">
<el-form-item label="资产编号" prop="id">
<el-input v-model="formData.id" placeholder="系统自动生成" disabled />
</el-form-item>
</el-col> -->
<el-col :span="12" >
<el-form-item :label="t('EquipmentManagement.EquipmentKeyItems.qrcode')" prop="qrcodeUrl">
<QrcodeActionCard
:image-url="formData.qrcodeUrl"
:print-id="formData.id"
@ -61,6 +75,13 @@
@refresh-success="handleQrcodeRefreshSuccess"
/>
</el-form-item>
</el-col>
<el-col :span="12" >
<el-form-item :label="t('EquipmentManagement.EquipmentKeyItems.images')" prop="images">
<UploadImg style="height: 100px" v-model="formData.images" />
</el-form-item>
</el-col>
</el-row>
<el-form-item :label="t('EquipmentManagement.EquipmentKeyItems.remark')" prop="remark">
<el-input
v-model="formData.remark"
@ -80,6 +101,7 @@
<script setup lang="ts">
import { CriticalComponentApi, CriticalComponentVO } from '@/api/mes/criticalComponent'
import QrcodeActionCard from '@/components/QrcodeActionCard/index.vue'
import UploadImg from "@/components/UploadFile/src/UploadImg.vue";
defineOptions({ name: 'CriticalComponentForm' })
@ -100,7 +122,8 @@ const formData = ref<Partial<CriticalComponentVO>>({
description: undefined,
count: undefined,
remark: undefined,
qrcodeUrl: undefined
qrcodeUrl: undefined,
images: undefined
})
const validateCode = (_rule, value, callback) => {
@ -171,10 +194,12 @@ const open = async (type: 'create' | 'update', id?: number) => {
code: detail?.code,
isCode: detail?.isCode ?? false,
name: detail?.name,
deviceSpec:detail?.deviceSpec,
description: detail?.description,
count: detail?.count,
remark: detail?.remark,
qrcodeUrl: detail?.qrcodeUrl
qrcodeUrl: detail?.qrcodeUrl,
images: detail?.images
}
} finally {
formLoading.value = false

@ -74,6 +74,9 @@ v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true"
:label="t('EquipmentManagement.EquipmentKeyItems.name')" align="center" prop="name"
min-width="140" sortable />
<el-table-column
:label="t('EquipmentManagement.EquipmentKeyItems.deviceSpec')" align="center" prop="deviceSpec"
min-width="140" sortable />
<el-table-column
:label="t('EquipmentManagement.EquipmentKeyItems.description')" align="center" prop="description"
min-width="180" />
<el-table-column

@ -4,7 +4,7 @@
ref="formRef"
:model="formData"
:rules="formRules"
label-width="110px"
label-width="100px"
v-loading="formLoading"
>
<el-row :gutter="16">
@ -121,6 +121,17 @@
/>
</el-form-item>
</el-col>
<!-- <el-col :span="12">
<el-form-item :label="t('EquipmentManagement.EquipmentLedger.deviceBrand')" prop="deviceBrand">
<el-input v-model="formData.deviceBrand" placeholder="请输入品牌" />
</el-form-item>
</el-col> -->
<!-- <el-col :span="24">
<el-form-item :label="t('EquipmentManagement.EquipmentLedger.deviceModel')" prop="deviceModel">
<el-input v-model="formData.deviceModel" :placeholder="t('EquipmentManagement.EquipmentLedger.placeholderDeviceModel')" />
</el-form-item>
</el-col>-->
<!-- <el-col :span="12">
<el-form-item label="供应商" prop="supplier">
@ -443,7 +454,7 @@ const initFormData = () => ({
deviceBrand: undefined,
deviceModel: undefined,
deviceSpec: undefined,
isScheduled: 0,
isSchedueld: 0,
ratedCapacity: undefined,
deviceType: undefined,
supplier: undefined,
@ -459,9 +470,7 @@ const initFormData = () => ({
fileUrl: undefined,
qrcodeUrl: undefined,
sort: undefined,
dvId: undefined,
dailyAverageValue: undefined,
dataCollectionCapacity: undefined
dvId: undefined
})
const formData = ref({
@ -613,7 +622,7 @@ const open = async (type: string, id?: number, defaultDeviceTypeId?: number) =>
...initFormData(),
...(detail as any),
isCode: (detail as any)?.isCode ?? false,
isScheduled: normalizeNumberish((detail as any)?.isScheduled ?? (detail as any)?.isSchedueld) ?? 0,
isSchedueld: normalizeNumberish((detail as any)?.isSchedueld ?? (detail as any)?.isScheduled) ?? 0,
ratedCapacity: normalizeNumberish((detail as any)?.ratedCapacity),
deviceType: normalizeNumberish((detail as any)?.deviceType),
deviceManagerIds: parseIdsValue((detail as any)?.deviceManager),
@ -622,8 +631,6 @@ const open = async (type: string, id?: number, defaultDeviceTypeId?: number) =>
componentIds: parseIdsValue((detail as any)?.componentId),
beijianIds: parseIdsValue((detail as any)?.beijianId),
qrcodeUrl: (detail as any)?.qrcodeUrl,
dailyAverageValue: normalizeNumberish((detail as any)?.dailyAverageValue),
dataCollectionCapacity: normalizeNumberish((detail as any)?.dataCollectionCapacity),
}
} finally {
formLoading.value = false
@ -647,7 +654,7 @@ const submitForm = async () => {
try {
const data = {
...(formData.value as any),
isScheduled: normalizeNumberish((formData.value as any).isScheduled) ?? 0,
isSchedueld: normalizeNumberish((formData.value as any).isSchedueld) ?? 0,
ratedCapacity: normalizeNumberish((formData.value as any).ratedCapacity),
deviceType: normalizeNumberish(formData.value.deviceType),
productionDate: normalizeYmd(formData.value.productionDate),
@ -655,14 +662,11 @@ const submitForm = async () => {
deviceManager: formData.value.deviceManagerIds?.length ? formData.value.deviceManagerIds.join(',') : undefined,
componentId: formData.value.componentIds?.length ? formData.value.componentIds.join(',') : undefined,
beijianId: formData.value.beijianIds?.length ? formData.value.beijianIds.join(',') : undefined,
fileUrl: normalizeFileUrlAsJsonArrayString((formData.value as any).fileUrl),
dailyAverageValue: normalizeNumberish((formData.value as any).dailyAverageValue),
dataCollectionCapacity: normalizeNumberish((formData.value as any).dataCollectionCapacity)
fileUrl: normalizeFileUrlAsJsonArrayString((formData.value as any).fileUrl)
} as unknown as DeviceLedgerVO
delete (data as any).deviceManagerIds
delete (data as any).componentIds
delete (data as any).beijianIds
delete (data as any).isSchedueld
if (formType.value === 'create') {
await DeviceLedgerApi.createDeviceLedger(data)
message.success(t('common.createSuccess'))

@ -10,11 +10,9 @@
<div class="device-ledger-right">
<ContentWrap>
<el-form
class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true"
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true"
label-width="60px">
<el-form-item
:label="t('EquipmentManagement.EquipmentLedger.deviceCode')"
<el-form-item :label="t('EquipmentManagement.EquipmentLedger.deviceCode')"
prop="deviceCode">
<el-input
v-model="queryParams.deviceCode"
@ -22,8 +20,7 @@ class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true"
clearable @keyup.enter="handleQuery"
class="!w-240px"/>
</el-form-item>
<el-form-item
:label="t('EquipmentManagement.EquipmentLedger.deviceName')"
<el-form-item :label="t('EquipmentManagement.EquipmentLedger.deviceName')"
prop="deviceName">
<el-input
v-model="queryParams.deviceName"
@ -31,15 +28,12 @@ class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true"
clearable @keyup.enter="handleQuery"
class="!w-240px"/>
</el-form-item>
<el-form-item
:label="t('EquipmentManagement.EquipmentLedger.deviceStatus')"
<el-form-item :label="t('EquipmentManagement.EquipmentLedger.deviceStatus')"
prop="deviceStatus">
<el-select
v-model="queryParams.deviceStatus"
<el-select v-model="queryParams.deviceStatus"
:placeholder="t('EquipmentManagement.EquipmentLedger.placeholderDeviceStatus')"
clearable class="!w-240px">
<el-option
v-for="dict in tzStatusOptions" :key="dict.value" :label="dict.label"
<el-option v-for="dict in tzStatusOptions" :key="dict.value" :label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
@ -52,14 +46,12 @@ v-for="dict in tzStatusOptions" :key="dict.value" :label="dict.label"
<Icon icon="ep:refresh" class="mr-5px"/>
{{ t('common.reset') }}
</el-button>
<el-button
type="primary" plain @click="openForm('create')"
<el-button type="primary" plain @click="openForm('create')"
v-hasPermi="['mes:device-ledger:create']">
<Icon icon="ep:plus" class="mr-5px"/>
{{ t('action.add') }}
</el-button>
<el-button
type="danger" plain @click="handleBatchDelete"
<el-button type="danger" plain @click="handleBatchDelete"
v-hasPermi="['mes:device-ledger:delete']">
<Icon icon="ep:delete" class="mr-5px"/>
{{ t('EquipmentManagement.EquipmentLedger.batchDelete') }}
@ -90,21 +82,17 @@ type="danger" plain @click="handleBatchDelete"
:show-overflow-tooltip="true"
row-key="id" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" fixed="left" reserve-selection/>
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.serialNumber')"
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.serialNumber')"
align="center" width="50" fixed="left">
<template #default="scope">
{{ (queryParams.pageNo - 1) * queryParams.pageSize + scope.$index + 1 }}
</template>
</el-table-column>
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.deviceCode')"
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.deviceCode')"
align="center" prop="deviceCode" min-width="160px" sortable/>
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.deviceName')"
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.deviceName')"
align="center" prop="deviceName" min-width="140px" sortable/>
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.deviceType')"
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.deviceType')"
align="center" prop="deviceType" min-width="110px" sortable>
<template #default="scope">
<el-tag effect="light">
@ -112,8 +100,7 @@ type="danger" plain @click="handleBatchDelete"
</el-tag>
</template>
</el-table-column>
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.deviceStatus')"
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.deviceStatus')"
align="center" prop="deviceStatus" sortable>
<template #default="scope">
<el-switch
@ -124,24 +111,20 @@ type="danger" plain @click="handleBatchDelete"
/>
</template>
</el-table-column>
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.isSchedueld')"
align="center" prop="isScheduled" min-width="100px">
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.isSchedueld')"
align="center" prop="isSchedueld" min-width="100px">
<template #default="scope">
<el-tag :type="Number(scope.row.isScheduled ?? scope.row.isSchedueld) === 1 ? 'success' : 'info'" effect="light">
{{ formatScheduleLabel(scope.row.isScheduled ?? scope.row.isSchedueld) }}
<el-tag :type="Number(scope.row.isSchedueld ?? scope.row.isScheduled) === 1 ? 'success' : 'info'" effect="light">
{{ formatScheduleLabel(scope.row.isSchedueld ?? scope.row.isScheduled) }}
</el-tag>
</template>
</el-table-column>
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.ratedCapacity')"
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.ratedCapacity')"
align="center" prop="ratedCapacity" min-width="120px"/>
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.deviceSpec')"
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.deviceSpec')"
align="center" prop="deviceSpec"/>
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.deviceModel')"
align="center" prop="deviceModel"/>
<!-- <el-table-column :label="t('EquipmentManagement.EquipmentLedger.deviceModel')"
align="center" prop="deviceModel"/>-->
<!-- <el-table-column :label="t('EquipmentManagement.EquipmentLedger.deviceBrand')" align="center" prop="deviceBrand" /> -->
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.productionDate')" align="center"
@ -153,24 +136,19 @@ type="danger" plain @click="handleBatchDelete"
width="120px" sortable/>
<!-- <el-table-column :label="t('EquipmentManagement.EquipmentLedger.supplier')" align="center" prop="supplier" width="110px" /> -->
<!-- <el-table-column :label="t('EquipmentManagement.EquipmentLedger.workshop')" align="center" prop="workshop" width="110px" /> -->
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.workshop')"
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.workshop')"
align="center" prop="workshopName" min-width="150px" sortable/>
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.deviceLocation')"
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.deviceLocation')"
align="center" prop="deviceLocation" min-width="150px"/>
<!-- <el-table-column :label="t('EquipmentManagement.EquipmentLedger.systemOrg')" align="center" prop="systemOrg" width="110px" /> -->
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.deviceManagerName')"
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.deviceManagerName')"
align="center" prop="deviceManagerName" width="150px" sortable/>
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.remark')" align="center"
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.remark')" align="center"
prop="remark"/>
<!-- <el-table-column :label="t('EquipmentManagement.EquipmentLedger.creatorName')" align="center" prop="creatorName" width="150px" sortable />
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.createTime')" align="center" prop="createTime" :formatter="dateFormatter" width="180px" sortable /> -->
<!-- <el-table-column :label="t('EquipmentManagement.EquipmentLedger.updateTime')" align="center" prop="updateTime" :formatter="dateFormatter" width="180px" sortable /> -->
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.operate')"
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.operate')"
align="center" min-width="160px" fixed="right">
<template #default="scope">
<el-button link @click="handleDetail(scope.row.id)">
@ -377,8 +355,7 @@ type="danger" plain @click="handleBatchDelete"
<el-steps
v-else direction="vertical" :active="inspectionStepGroups.length"
class="device-ledger-history-steps">
<el-step
v-for="group in inspectionStepGroups" :key="group.key"
<el-step v-for="group in inspectionStepGroups" :key="group.key"
style="margin-top:8px">
<template #title>
<div class="device-ledger-history-title">
@ -390,8 +367,7 @@ v-for="group in inspectionStepGroups" :key="group.key"
</template>
<template #description>
<div class="device-ledger-history-items">
<div
v-for="item in group.items" :key="item.key"
<div v-for="item in group.items" :key="item.key"
class="device-ledger-history-item">
<div class="device-ledger-history-item-head">
<el-tag :type="getResultTagType(item.result)">{{
@ -458,8 +434,7 @@ v-for="item in group.items" :key="item.key"
</el-step>
</el-steps>
</el-tab-pane>
<el-tab-pane
:label="t('EquipmentManagement.EquipmentLedger.maintainHistory')"
<el-tab-pane :label="t('EquipmentManagement.EquipmentLedger.maintainHistory')"
name="maintain">
<div style="margin-bottom: 16px;">
<el-date-picker
@ -494,8 +469,7 @@ v-for="item in group.items" :key="item.key"
</template>
<template #description>
<div class="device-ledger-history-items">
<div
v-for="item in group.items" :key="item.key"
<div v-for="item in group.items" :key="item.key"
class="device-ledger-history-item">
<div class="device-ledger-history-item-head">
<el-tag :type="getResultTagType(item.result)">{{
@ -562,8 +536,7 @@ v-for="item in group.items" :key="item.key"
</el-step>
</el-steps>
</el-tab-pane>
<el-tab-pane
:label="t('EquipmentManagement.EquipmentLedger.repairHistory')"
<el-tab-pane :label="t('EquipmentManagement.EquipmentLedger.repairHistory')"
name="repair">
<div style="margin-bottom: 16px;">
<el-date-picker
@ -638,8 +611,7 @@ v-for="item in group.items" :key="item.key"
String(formatHistoryTime(row.finishDate)).split(' ')[0]
}}</span>
</div>
<div
v-if="row.malfunctionImages?.length"
<div v-if="row.malfunctionImages?.length"
class="device-ledger-history-item-images">
<el-image
v-for="img in row.malfunctionImages" :key="img" :src="img"
@ -656,8 +628,7 @@ v-if="row.malfunctionImages?.length"
</el-collapse-item>
</el-collapse>
</el-tab-pane>
<el-tab-pane
:label="t('EquipmentManagement.EquipmentLedger.criticalComponent')"
<el-tab-pane :label="t('EquipmentManagement.EquipmentLedger.criticalComponent')"
name="criticalComponent">
<div class="device-ledger-tab-toolbar">
<el-button
@ -671,20 +642,15 @@ v-if="row.malfunctionImages?.length"
<el-table
v-loading="loading" :data="detailData?.componentList" :stripe="true"
:show-overflow-tooltip="true">
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.componentCode')"
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.componentCode')"
align="center" prop="code" min-width="140" sortable/>
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.componentName')"
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.componentName')"
align="center" prop="name" min-width="140" sortable/>
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.componentDesc')"
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.componentDesc')"
align="center" prop="description" min-width="180"/>
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.remark')"
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.remark')"
align="center" prop="remark" min-width="180"/>
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.createTime')"
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.createTime')"
align="center" prop="createTime" :formatter="dateFormatter"
width="180" sortable/>
</el-table>
@ -698,42 +664,31 @@ v-if="row.malfunctionImages?.length"
{{ t('action.export') }}
</el-button>
</div>
<el-table
v-loading="loading" :data="detailData?.beijianList" :stripe="true"
<el-table v-loading="loading" :data="detailData?.beijianList" :stripe="true"
:show-overflow-tooltip="true">
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.spareCode')"
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.spareCode')"
align="center" prop="barCode" sortable/>
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.spareName')"
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.spareName')"
align="left" prop="name" width="220px" sortable/>
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.category')"
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.category')"
align="center" prop="categoryName" sortable/>
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.unit')" align="center"
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.unit')" align="center"
prop="unitName" sortable/>
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.createTime')"
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.createTime')"
align="center" prop="createTime" :formatter="dateFormatter"
width="180px" sortable/>
</el-table>
</el-tab-pane>
<el-tab-pane label="模具" name="mold">
<el-table
v-loading="loading" :data="detailData?.moldList" :stripe="true"
<el-table v-loading="loading" :data="detailData?.moldList" :stripe="true"
:show-overflow-tooltip="true">
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.moldCode')"
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.moldCode')"
align="center" prop="code" min-width="140" sortable/>
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.moldName')"
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.moldName')"
align="center" prop="name" min-width="140" sortable/>
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.moldRemark')"
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.moldRemark')"
align="center" prop="remark" min-width="180"/>
<el-table-column
:label="t('EquipmentManagement.EquipmentLedger.createTime')"
<el-table-column :label="t('EquipmentManagement.EquipmentLedger.createTime')"
align="center" prop="createTime" :formatter="dateFormatter"
width="180" sortable/>
</el-table>

@ -28,7 +28,7 @@
</el-form-item>
<el-form-item :label="t('EquipmentManagement.PlanMaintenance.subjectName')" prop="subjectIds">
<el-select
<!-- <el-select
v-model="formData.subjectIds"
multiple
filterable
@ -37,7 +37,17 @@
class="!w-full"
>
<el-option v-for="item in subjectOptions" :key="item.id" :label="item.subjectName" :value="item.id" />
</el-select>
</el-select>-->
<el-input
:model-value="subjectNameDisplay"
readonly
clearable
class="device-ledger-selection-input"
:placeholder="t('EquipmentManagement.PlanMaintenance.placeholderSubjectSelect')"
@clear="clearSubjectComponent"
@click="openSubjectComponentDialog"
/>
</el-form-item>
</el-form>
@ -46,12 +56,64 @@
<el-button @click="dialogVisible = false">{{ t('common.cancel') }}</el-button>
</template>
</Dialog>
<!--点检名称-->
<el-dialog
v-model="subjectComponentDialogVisible"
title="选择点检项"
width="1200px"
class="device-ledger-transfer-dialog"
append-to-body
>
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" min-label-width="68px" style="margin-bottom: 10px">
<el-form-item :label="t('EquipmentManagement.DvSubject.code')" prop="subjectCode">
<el-input
v-model="queryParams.subjectCode" :placeholder="t('EquipmentManagement.DvSubject.placeholderCode')"
clearable @keyup.enter="handleQuery" class="!w-240px" />
</el-form-item>
<el-form-item :label="t('EquipmentManagement.DvSubject.name')" prop="subjectName">
<el-input
v-model="queryParams.subjectName" :placeholder="t('EquipmentManagement.DvSubject.placeholderName')"
clearable @keyup.enter="handleQuery" class="!w-240px" />
</el-form-item>
<el-form-item>
<el-button @click="handleQuery">
<Icon icon="ep:search" class="mr-5px" />
{{ t('common.query') }}
</el-button>
<el-button @click="resetQuery">
<Icon icon="ep:refresh" class="mr-5px" />
{{ t('common.reset') }}
</el-button>
</el-form-item>
</el-form>
<ContentWrap>
<el-table
ref="multipleTableRef"
v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true"
@selection-change="handleSelectionChange" @select="handleSelect" @select-all="handleSelectAll" row-key="id">
<el-table-column type="selection" width="55" :reserve-selection="true" />
<el-table-column :label="t('EquipmentManagement.DvSubject.code')" align="center" prop="subjectCode" sortable />
<el-table-column :label="t('EquipmentManagement.DvSubject.name')" align="center" prop="subjectName" sortable />
<el-table-column :label="t('EquipmentManagement.DvSubject.judgmentCriteria')" align="center" width="480px" prop="judgmentCriteria" />
</el-table>
<Pagination
:total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize"
@pagination="getList" />
</ContentWrap>
<template #footer>
<el-button @click="subjectComponentDialogVisible = false">{{ t('common.cancel') }}</el-button>
<el-button type="primary" @click="confirmSubjectComponentDialog">{{ t('common.ok') }}</el-button>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import type { FormRules } from 'element-plus'
import { DvSubjectApi, DvSubjectVO } from '@/api/mes/dvsubject'
import { PlanMaintenanceApi, PlanMaintenanceVO } from '@/api/mes/planmaintenance'
import {ref} from "vue";
import {ElTable} from "element-plus";
defineOptions({ name: 'PlanMaintenanceForm' })
@ -62,13 +124,44 @@ const dialogVisible = ref(false)
const dialogTitle = ref('')
const formLoading = ref(false)
const formType = ref<'create' | 'update'>('create')
const queryFormRef = ref() //
const subjectComponentDialogVisible = ref(false)
const loading = ref(true) //
const list = ref<DvSubjectVO[]>([]) //
const total = ref(0) //
const tableRef = ref()
const selectedIds = ref<number[]>([])
const selectedRows = ref<any[]>([]) //
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
subjectCode: undefined as string | undefined,
subjectName: undefined as string | undefined,
})
const multipleTableRef = ref<InstanceType<typeof ElTable>>()
const beijianOptions = ref<{ label: string; value: number }[]>([])
const formatSelectedSummary = (ids: number[], options: { label: string; value: number }[]) => {
const optionMap = new Map<number, string>(options.map((item) => [item.value, item.label]))
const labels = ids.map((id) => optionMap.get(id)).filter((v): v is string => Boolean(v))
if (!labels.length) return ''
if (labels.length <= 3) return labels.join('、')
return `${labels.slice(0, 3).join('、')}…等${labels.length}`
}
const subjectNameDisplay = computed(() =>
formatSelectedSummary(formData.value.subjectIds ?? [], beijianOptions.value)
)
const subjectOptions = ref<DvSubjectVO[]>([])
const ensureSubjectOptionsLoaded = async () => {
if (subjectOptions.value.length) return
const res = await DvSubjectApi.getDvSubjectList()
console.log(res)
subjectOptions.value = (res ?? []) as DvSubjectVO[]
beijianOptions.value = (res ?? []).map((item: any) => {
const code = item.subjectCode ? String(item.subjectCode) : ''
const name = item.subjectName ? String(item.subjectName) : ''
const label = code && name ? `${code}-${name}` : name || code || String(item.id)
return { label, value: Number(item.id) }
})
}
const parseIds = (value: any): Array<number | string> => {
@ -128,6 +221,7 @@ const open = async (type: 'create' | 'update', row?: Partial<PlanMaintenanceVO>)
subjectIds: parseIds((row as any).subjectIds ?? (row as any).subjectIdS)
}
}
getList()
}
defineExpose({ open })
@ -162,4 +256,149 @@ const resetForm = () => {
formData.value = initFormData()
formRef.value?.resetFields()
}
const clearSubjectComponent = () => {
formData.value.subjectIds = []
}
const ids = ref([])
const openSubjectComponentDialog = () => {
if (formType.value === 'create') {
selectedIds.value = []
selectedRows.value =[]
//formData.value.subjectIds = []
// multipleTableRef.value.clearSelection()
}else{
selectedIds.value = []
selectedRows.value =[]
//formData.value.subjectIds = []
// multipleTableRef.value.clearSelection()
}
// criticalComponentDraft.value = [...(formData.value.componentIds ?? [])]
subjectComponentDialogVisible.value = true
ids.value =formData.value.subjectIds
setDefaultSelections()
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
const handleSelectionChange = (rows: any[]) => {
selectedIds.value = rows?.map((row) => row.id).filter((id) => id !== undefined) ?? []
// id
const currentPageIds = rows.map(item => item.id)
//
selectedRows.value = selectedRows.value.filter(
item => item.id !== undefined
)
selectedRows.value = selectedRows.value.filter(
item => !currentPageIds.includes(item.id)
)
//
selectedRows.value.push(...rows)
}
//
const currentSelectedRows = ref([])
// select row selected
const handleSelect = (selection, row) => {
//
const isSelected = selection.includes(row)
if (isSelected) {
// console.log(` : ID=${row.id}, Name=${row.name}`)
ids.value.push(row.id)
} else {
ids.value= ids.value.filter(
item => item !== row.id
)
// console.log(` : ID=${row.id}, Name=${row.name}`)
}
//
currentSelectedRows.value = selection
}
const handleSelectAll = (selection) => {
ids.value = selection?.map((row) => row.id).filter((id) => id !== undefined) ?? []
}
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const data = await DvSubjectApi.getDvSubjectPage(queryParams)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
const confirmSubjectComponentDialog = () => {
//let ids = selectedRows.value.map(item => item.id);
//const validMap = new Set(criticalComponentOptions.value.map((item) => item.value))
//const selected = Array.from(new Set(criticalComponentDraft.value.map((v) => Number(v)).filter((v) => validMap.has(v))))
formData.value.subjectIds = ids.value
subjectComponentDialogVisible.value = false
multipleTableRef.value.clearSelection()
}
const cancelHandle = () => {
multipleTableRef.value.clearSelection()
}
// 1 data
watch(list, (newData, oldData) => {
//
if (newData.length > 0) {
//
setDefaultSelections()
}
}, { deep: true })
//const defaultSelectedIds = [144, 143,141]
//
const setDefaultSelections = () => {
// DOM
nextTick(() => {
if (!multipleTableRef.value) return
multipleTableRef.value.clearSelection()
const rawSubjectIds = toRaw(formData.value.subjectIds)
if(rawSubjectIds.length != 0){
let row={
id: undefined
}
multipleTableRef.value.toggleRowSelection(row, true)
}
//
list.value.forEach(row => {
let id = row.id;
if (rawSubjectIds.includes(row.id)) {
multipleTableRef.value.toggleRowSelection(row, true)
}
})
})
}
</script>
<style lang="scss" scoped>
:deep(.device-ledger-transfer-dialog){
height: 200px;
}
</style>

Loading…
Cancel
Save