|
@@ -0,0 +1,1408 @@
|
|
|
|
|
+<script setup lang="ts">
|
|
|
|
|
+import {
|
|
|
|
|
+ exportFileV2,
|
|
|
|
|
+ exportOperationFile,
|
|
|
|
|
+ readValidationV2,
|
|
|
|
|
+ updateValidationV2,
|
|
|
|
|
+ uploadFileV2,
|
|
|
|
|
+ validationV2_add,
|
|
|
|
|
+ validationV2_del,
|
|
|
|
|
+ validationV2_List,
|
|
|
|
|
+ validationV2_operationList,
|
|
|
|
|
+ validationV2_recordList,
|
|
|
|
|
+ validationV2_update,
|
|
|
|
|
+ validationToolV2_class_list
|
|
|
|
|
+} from '@/api/storehouse'
|
|
|
|
|
+import {User_List} from '@/api/user/index';
|
|
|
|
|
+import TableBase from '@/components/TableBase/index.vue'
|
|
|
|
|
+import {computed, nextTick, onMounted, reactive, ref, watch} from 'vue'
|
|
|
|
|
+import {GlobalStore} from '@/stores'
|
|
|
|
|
+import type {ColumnProps} from '@/components/TableBase/interface'
|
|
|
|
|
+import {Delete, Edit, View} from '@element-plus/icons-vue'
|
|
|
|
|
+import type {FormInstance, UploadInstance} from 'element-plus'
|
|
|
|
|
+import {ElLoading, ElMessage, ElMessageBox} from 'element-plus'
|
|
|
|
|
+import snAdd from './modules/snAdd.vue'
|
|
|
|
|
+import Drawer from "@/components/Drawer/index.vue";
|
|
|
|
|
+
|
|
|
|
|
+const formLabelWidth = ref('100px')
|
|
|
|
|
+const uploadRef = ref<UploadInstance>()
|
|
|
|
|
+const uploadFiles = ref<File[]>([]) // 新增:用于存储上传的文件
|
|
|
|
|
+const globalStore = GlobalStore()
|
|
|
|
|
+const TableRef = ref<InstanceType<typeof TableBase> | null>(null)
|
|
|
|
|
+const recordTableRef = ref<InstanceType<typeof TableBase> | null>(null)
|
|
|
|
|
+const operationTableRef = ref<InstanceType<typeof TableBase> | null>(null)
|
|
|
|
|
+const drawerSnRef = ref<InstanceType<typeof Drawer> | null>(null)
|
|
|
|
|
+
|
|
|
|
|
+const initParam = reactive({
|
|
|
|
|
+ User_tokey: globalStore.GET_User_tokey,
|
|
|
|
|
+ Validationnumber: '',
|
|
|
|
|
+ T_state: '',
|
|
|
|
|
+ T_sn: '',
|
|
|
|
|
+ T_imei: '',
|
|
|
|
|
+ T_iccid: '',
|
|
|
|
|
+ LendUser: '',
|
|
|
|
|
+ T_project: '',
|
|
|
|
|
+ T_class: ''
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+const recordInitParam = reactive({
|
|
|
|
|
+ User_tokey: globalStore.GET_User_tokey,
|
|
|
|
|
+ Validationnumber: '',
|
|
|
|
|
+ T_state: '',
|
|
|
|
|
+ T_sn: '',
|
|
|
|
|
+ T_imei: '',
|
|
|
|
|
+ T_iccid: '',
|
|
|
|
|
+ LendUser: '',
|
|
|
|
|
+ T_project: '',
|
|
|
|
|
+ T_class: ''
|
|
|
|
|
+})
|
|
|
|
|
+const operationInitParam = reactive({
|
|
|
|
|
+ User_tokey: globalStore.GET_User_tokey,
|
|
|
|
|
+ T_state: '',
|
|
|
|
|
+ T_sn: '',
|
|
|
|
|
+ LendUser: '',
|
|
|
|
|
+ T_project: '',
|
|
|
|
|
+})
|
|
|
|
|
+const columns: ColumnProps[] = [
|
|
|
|
|
+ {type: 'index', label: '序号', width: 80},
|
|
|
|
|
+ {prop: 'Validationnumber', label: '设备编号', ellipsis: true},
|
|
|
|
|
+ {prop: 'T_sn', label: '设备SN', ellipsis: true, width: 180},
|
|
|
|
|
+ {prop: 'T_imei', label: '模组imei', ellipsis: true},
|
|
|
|
|
+ {prop: 'T_iccid', label: '物联网卡号', ellipsis: true},
|
|
|
|
|
+ {prop: 'T_state', label: '状态', name: 'T_state'},
|
|
|
|
|
+ {prop: 'T_class', label: '设备类型', name: 'T_class'},
|
|
|
|
|
+ {prop: 'LendUser', label: '借出人', ellipsis: true},
|
|
|
|
|
+ {prop: 'T_project', label: '借出项目', ellipsis: true},
|
|
|
|
|
+ {prop: 'T_remark', label: '备注', ellipsis: true},
|
|
|
|
|
+ {prop: 'operation', label: '操作', width: 260, fixed: 'right'}
|
|
|
|
|
+]
|
|
|
|
|
+
|
|
|
|
|
+const recordColumns: ColumnProps[] = [
|
|
|
|
|
+ {type: 'index', label: '序号', width: 80},
|
|
|
|
|
+ {prop: 'Validationnumber', label: '设备编号', ellipsis: true},
|
|
|
|
|
+ {prop: 'T_sn', label: '设备SN', ellipsis: true, width: 180},
|
|
|
|
|
+ {prop: 'T_imei', label: '模组imei', ellipsis: true},
|
|
|
|
|
+ {prop: 'T_iccid', label: '物联网卡号', ellipsis: true},
|
|
|
|
|
+ {prop: 'T_state', label: '状态', name: 'T_state'},
|
|
|
|
|
+ {prop: 'T_class', label: '设备类型', name: 'T_class'},
|
|
|
|
|
+ {prop: 'LendUser', label: '借出(归还)人', ellipsis: true},
|
|
|
|
|
+ {prop: 'T_project', label: '关联项目', ellipsis: true},
|
|
|
|
|
+ {prop: 'T_remark', label: '备注', ellipsis: true},
|
|
|
|
|
+ {prop: 'CreateTime', label: '操作时间', ellipsis: true},
|
|
|
|
|
+]
|
|
|
|
|
+const operationColumns: ColumnProps[] = [
|
|
|
|
|
+ {type: 'index', label: '序号', width: 80},
|
|
|
|
|
+ {prop: 'BatchNumber', label: '操作时间', width: 190},
|
|
|
|
|
+ {prop: 'T_state', label: '操作', name: 'T_state', width: 90},
|
|
|
|
|
+ {prop: 'LendUser', label: '借出(归还)人', ellipsis: true},
|
|
|
|
|
+ {prop: 'T_project', label: '关联项目', name: 'T_project', ellipsis: true, width: 300},
|
|
|
|
|
+ {prop: 'T_remark', label: '备注', ellipsis: true},
|
|
|
|
|
+ {prop: 'T_sn_quantity', label: '设备数量'},
|
|
|
|
|
+ {prop: 'operation', label: 'SN', width: 100, fixed: 'right', align: 'center'}
|
|
|
|
|
+
|
|
|
|
|
+]
|
|
|
|
|
+const snColumns = [
|
|
|
|
|
+ {type: 'index', label: '序号', width: 80, align: 'center '},
|
|
|
|
|
+ {label: '关联项目', prop: 'T_project', align: 'center '},
|
|
|
|
|
+ {label: '数量', prop: 'T_number', align: 'center '},
|
|
|
|
|
+ {label: 'SN', prop: 'T_sn', align: 'center '}
|
|
|
|
|
+]
|
|
|
|
|
+// 搜索
|
|
|
|
|
+const options = reactive([
|
|
|
|
|
+ {name: '已出库', id: 1},
|
|
|
|
|
+ {name: '未出库', id: 2},
|
|
|
|
|
+ {name: '维修中', id: 3},
|
|
|
|
|
+ {name: '已报废', id: 4},
|
|
|
|
|
+ {name: '已损坏', id: 5}
|
|
|
|
|
+])
|
|
|
|
|
+const searchHandle = () => {
|
|
|
|
|
+ TableRef.value?.searchTable()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const recordSearchHandle = () => {
|
|
|
|
|
+ recordTableRef.value?.searchTable()
|
|
|
|
|
+}
|
|
|
|
|
+const operationSearchHandle = () => {
|
|
|
|
|
+ operationTableRef.value?.searchTable()
|
|
|
|
|
+}
|
|
|
|
|
+/**
|
|
|
|
|
+ * 删除
|
|
|
|
|
+ */
|
|
|
|
|
+const deleteFun = (row: any) => {
|
|
|
|
|
+ ElMessageBox.confirm('删除操作,是否立即删除?', '删除', {
|
|
|
|
|
+ confirmButtonText: '立即删除',
|
|
|
|
|
+ cancelButtonText: '取消',
|
|
|
|
|
+ type: 'warning',
|
|
|
|
|
+ center: true
|
|
|
|
|
+ })
|
|
|
|
|
+ .then(async () => {
|
|
|
|
|
+ const result: any = await validationV2_del({t_sn: row})
|
|
|
|
|
+ if (result.Code == 200) {
|
|
|
|
|
+ ElMessage.success('删除成功')
|
|
|
|
|
+ TableRef.value?.searchTable()
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
|
|
|
+ .catch(() => {
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+//导出文件excel
|
|
|
|
|
+const exportExcel = async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const response: any = await exportFileV2({
|
|
|
|
|
+ User_tokey: globalStore.GET_User_tokey,
|
|
|
|
|
+ Validationnumber: initParam.Validationnumber,
|
|
|
|
|
+ T_state: initParam.T_state,
|
|
|
|
|
+ T_sn: initParam.T_sn,
|
|
|
|
|
+ T_imei: initParam.T_imei,
|
|
|
|
|
+ T_iccid: initParam.T_iccid,
|
|
|
|
|
+ LendUser: initParam.LendUser,
|
|
|
|
|
+ T_project: initParam.T_project,
|
|
|
|
|
+ T_class: initParam.T_class
|
|
|
|
|
+ })
|
|
|
|
|
+ // 处理返回的二进制文件并触发下载
|
|
|
|
|
+ const blob = new Blob([response], {type: 'application/vnd.ms-excel;charset=utf8'})
|
|
|
|
|
+ const url = window.URL.createObjectURL(blob)
|
|
|
|
|
+ const a = document.createElement('a')
|
|
|
|
|
+ a.href = url
|
|
|
|
|
+ const now = new Date();
|
|
|
|
|
+ const formattedDate = `${now.getFullYear()}${(now.getMonth() + 1).toString().padStart(2, '0')}${now.getDate().toString().padStart(2, '0')}_${now.getHours().toString().padStart(2, '0')}${now.getMinutes().toString().padStart(2, '0')}`;
|
|
|
|
|
+ a.download = `验证工具记录表_${formattedDate}.xlsx`;
|
|
|
|
|
+ document.body.appendChild(a)
|
|
|
|
|
+ a.click()
|
|
|
|
|
+ a.remove()
|
|
|
|
|
+ window.URL.revokeObjectURL(url)
|
|
|
|
|
+ ElMessage.success('导出成功')
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ ElMessage.error('导出失败,请检查网络连接')
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+const exportOperationExcel = async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const response: any = await exportOperationFile({
|
|
|
|
|
+ User_tokey: globalStore.GET_User_tokey,
|
|
|
|
|
+ T_state: operationInitParam.T_state,
|
|
|
|
|
+ T_sn: operationInitParam.T_sn,
|
|
|
|
|
+ LendUser: operationInitParam.LendUser,
|
|
|
|
|
+ T_project: operationInitParam.T_project,
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ // 处理返回的二进制文件并触发下载
|
|
|
|
|
+ const blob = new Blob([response], {type: 'application/vnd.ms-excel;charset=utf8'})
|
|
|
|
|
+ const url = window.URL.createObjectURL(blob)
|
|
|
|
|
+ const a = document.createElement('a')
|
|
|
|
|
+ a.href = url
|
|
|
|
|
+ const now = new Date();
|
|
|
|
|
+ const formattedDate = `${now.getFullYear()}${(now.getMonth() + 1).toString().padStart(2, '0')}${now.getDate().toString().padStart(2, '0')}_${now.getHours().toString().padStart(2, '0')}${now.getMinutes().toString().padStart(2, '0')}`;
|
|
|
|
|
+ a.download = `验证工具操作记录表_${formattedDate}.xlsx`;
|
|
|
|
|
+ document.body.appendChild(a)
|
|
|
|
|
+ a.click()
|
|
|
|
|
+ a.remove()
|
|
|
|
|
+ window.URL.revokeObjectURL(url)
|
|
|
|
|
+ ElMessage.success('导出成功')
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ ElMessage.error('导出失败,请检查网络连接')
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const showInStorageForm = ref(false)
|
|
|
|
|
+const dialogTableVisible = ref(false)
|
|
|
|
|
+const operationVisible = ref(false)
|
|
|
|
|
+const showBatchInputDialog = ref(false)
|
|
|
|
|
+const batchInputType = ref<'inStorage' | 'lend'>('inStorage')
|
|
|
|
|
+const batchSNText = ref('')
|
|
|
|
|
+
|
|
|
|
|
+const inStorageFormRef = ref<FormInstance | null>(null)
|
|
|
|
|
+const inStorageForm = reactive({
|
|
|
|
|
+ T_sn: '',
|
|
|
|
|
+ Validationnumber: '',
|
|
|
|
|
+ T_remark: '',
|
|
|
|
|
+ T_class: null
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+interface InStorageItem {
|
|
|
|
|
+ T_sn: string
|
|
|
|
|
+ Validationnumber: string
|
|
|
|
|
+ T_remark: string
|
|
|
|
|
+ T_class?: string | null
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 获取设备类型
|
|
|
|
|
+const Pruductoptions = ref<any[]>([
|
|
|
|
|
+ {
|
|
|
|
|
+ Id: '',
|
|
|
|
|
+ T_name: ''
|
|
|
|
|
+ }
|
|
|
|
|
+])
|
|
|
|
|
+const getValidationToolClassList = async () => {
|
|
|
|
|
+ const res: any = await validationToolV2_class_list({page: 1, page_z: 999})
|
|
|
|
|
+ Pruductoptions.value = res.Data.Data
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const pendingItems = ref<InStorageItem[]>([])
|
|
|
|
|
+const pageSize = ref(8)
|
|
|
|
|
+const currentPage = ref(1)
|
|
|
|
|
+
|
|
|
|
|
+const paginatedPendingItems = computed(() => {
|
|
|
|
|
+ const start = (currentPage.value - 1) * pageSize.value
|
|
|
|
|
+ const end = start + pageSize.value
|
|
|
|
|
+ return pendingItems.value.slice(start, end)
|
|
|
|
|
+})
|
|
|
|
|
+const rules = reactive({
|
|
|
|
|
+ T_sn: [{required: true, message: '请输入SN', trigger: 'blur'}],
|
|
|
|
|
+ Validationnumber: [{required: true, message: '请输入设备编号', trigger: 'blur'}],
|
|
|
|
|
+ T_class: [{required: true, message: '请选择设备类型', trigger: 'blur'}]
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+const extractSN = (fullSN: string): string => {
|
|
|
|
|
+ if (fullSN.length === 24 && fullSN.startsWith('03') && fullSN.endsWith('000001')) {
|
|
|
|
|
+ return fullSN.substring(2, 18)
|
|
|
|
|
+ }
|
|
|
|
|
+ return fullSN
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 批量处理SN数据
|
|
|
|
|
+ * 去除前2个字符(03)和后6个字符(000001)
|
|
|
|
|
+ */
|
|
|
|
|
+const processBatchSN = (text: string): string[] => {
|
|
|
|
|
+ const lines = text.split('\n').map(line => line.trim()).filter(line => line.length > 0)
|
|
|
|
|
+ return lines.map(line => {
|
|
|
|
|
+ // 只有当前缀为03且后缀为000001时才截取中间值
|
|
|
|
|
+ if (line.startsWith('03') && line.endsWith('000001') && line.length > 8) {
|
|
|
|
|
+ return line.substring(2, line.length - 6).trim()
|
|
|
|
|
+ }
|
|
|
|
|
+ return line.trim()
|
|
|
|
|
+ }).filter(sn => sn.length > 0)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 打开批量录入对话框
|
|
|
|
|
+ */
|
|
|
|
|
+const openBatchInputDialog = (type: 'inStorage' | 'lend') => {
|
|
|
|
|
+ batchInputType.value = type
|
|
|
|
|
+ batchSNText.value = ''
|
|
|
|
|
+ showBatchInputDialog.value = true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 提交批量录入的SN
|
|
|
|
|
+ */
|
|
|
|
|
+const submitBatchSN = async () => {
|
|
|
|
|
+ if (!batchSNText.value.trim()) {
|
|
|
|
|
+ ElMessage.warning('请输入SN数据')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const processedSNs = processBatchSN(batchSNText.value)
|
|
|
|
|
+ console.log("已处理数据=====",processedSNs)
|
|
|
|
|
+ if (processedSNs.length === 0) {
|
|
|
|
|
+ ElMessage.warning('没有有效的SN数据')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ let successCount = 0
|
|
|
|
|
+ let failCount = 0
|
|
|
|
|
+ const failMessages: string[] = []
|
|
|
|
|
+
|
|
|
|
|
+ if (batchInputType.value === 'inStorage') {
|
|
|
|
|
+ // 入库批量处理
|
|
|
|
|
+ for (const sn of processedSNs) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 检查是否已存在
|
|
|
|
|
+ if (pendingItems.value.some((item: any) => item.T_sn === sn)) {
|
|
|
|
|
+ failCount++
|
|
|
|
|
+ failMessages.push(`SN ${sn} 已存在`)
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
|
|
+ // 检查是否已入库
|
|
|
|
|
+ const result: any = await readValidationV2({sn: sn})
|
|
|
|
|
+ if ((result.Code == 200) && (result.Data.T_state == 2)) {
|
|
|
|
|
+ failCount++
|
|
|
|
|
+ failMessages.push(`SN ${sn} 已入库不能重复入库`)
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
|
|
+ // 添加到待提交列表
|
|
|
|
|
+ pendingItems.value.unshift({
|
|
|
|
|
+ T_sn: sn,
|
|
|
|
|
+ Validationnumber: inStorageForm.Validationnumber || '',
|
|
|
|
|
+ T_remark: inStorageForm.T_remark || '',
|
|
|
|
|
+ T_class: inStorageForm.T_class || null
|
|
|
|
|
+ })
|
|
|
|
|
+ successCount++
|
|
|
|
|
+ } catch (error: any) {
|
|
|
|
|
+ failCount++
|
|
|
|
|
+ const errorMsg = error?.message || error?.toString() || '未知错误'
|
|
|
|
|
+ failMessages.push(`SN ${sn} 处理失败: ${errorMsg}`)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ console.log("借出批量处理13=====",pendingLendItems.value)
|
|
|
|
|
+ // 借出批量处理
|
|
|
|
|
+ for (const sn of processedSNs) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 检查是否已存在
|
|
|
|
|
+ if (pendingLendItems.value.some((item: any) => item.T_sn === sn)) {
|
|
|
|
|
+ failCount++
|
|
|
|
|
+ failMessages.push(`SN ${sn} 已存在`)
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
|
|
+ // 检查SN状态
|
|
|
|
|
+ const result: any = await readValidationV2({sn: sn})
|
|
|
|
|
+ if (result.Code !== 200) {
|
|
|
|
|
+ failCount++
|
|
|
|
|
+ failMessages.push(`SN ${sn} 未入库不能借出`)
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
|
|
+ if (result.Data.T_state == 5) {
|
|
|
|
|
+ failCount++
|
|
|
|
|
+ failMessages.push(`SN ${sn} 设备已损坏`)
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
|
|
+ if (result.Data.T_state != 2) {
|
|
|
|
|
+ failCount++
|
|
|
|
|
+ failMessages.push(`SN ${sn} 未入库不能借出`)
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
|
|
+ // 添加到待提交列表
|
|
|
|
|
+ pendingLendItems.value.unshift({
|
|
|
|
|
+ T_sn: sn,
|
|
|
|
|
+ Validationnumber: lendForm.Validationnumber || '',
|
|
|
|
|
+ T_remark: lendForm.T_remark || '',
|
|
|
|
|
+ LendUser: lendForm.LendUser || '',
|
|
|
|
|
+ T_project: lendForm.T_project || ''
|
|
|
|
|
+ })
|
|
|
|
|
+ successCount++
|
|
|
|
|
+ } catch (error: any) {
|
|
|
|
|
+ failCount++
|
|
|
|
|
+ const errorMsg = error?.message || error?.toString() || '未知错误'
|
|
|
|
|
+ failMessages.push(`SN ${sn} 处理失败: ${errorMsg}`)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ // 去重
|
|
|
|
|
+ pendingLendItems.value = pendingLendItems.value.filter((value: any, index: any, self: any) => {
|
|
|
|
|
+ return self.findIndex((t: any) => (t.T_sn === value.T_sn)) === index;
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 显示处理结果
|
|
|
|
|
+ if (successCount > 0) {
|
|
|
|
|
+ ElMessage.success(`成功添加 ${successCount} 条SN数据`)
|
|
|
|
|
+ if ('speechSynthesis' in window) {
|
|
|
|
|
+ const utterance = new SpeechSynthesisUtterance(`成功添加${successCount}条数据`)
|
|
|
|
|
+ window.speechSynthesis.speak(utterance)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (failCount > 0) {
|
|
|
|
|
+ // 显示详细的失败原因
|
|
|
|
|
+ const failMessageHTML = `<div style="margin-top: 10px;">
|
|
|
|
|
+ <p style="margin-bottom: 15px; font-weight: 500; color: #303133;">有 ${failCount} 条SN数据处理失败,具体原因如下:</p>
|
|
|
|
|
+ <div style="max-height: 400px; overflow-y: auto; padding-right: 5px;">
|
|
|
|
|
+ ${failMessages.map((msg, index) => `<div style="padding: 10px 0; border-bottom: 1px solid #ebeef5; line-height: 1.8;">
|
|
|
|
|
+ <span style="color: #909399; margin-right: 10px; font-weight: 500;">${index + 1}.</span>
|
|
|
|
|
+ <span style="color: #606266;">${msg}</span>
|
|
|
|
|
+ </div>`).join('')}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>`
|
|
|
|
|
+ ElMessageBox.alert(
|
|
|
|
|
+ failMessageHTML,
|
|
|
|
|
+ '批量录入失败详情',
|
|
|
|
|
+ {
|
|
|
|
|
+ confirmButtonText: '确定',
|
|
|
|
|
+ type: 'warning',
|
|
|
|
|
+ dangerouslyUseHTMLString: true
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 关闭对话框并清空输入
|
|
|
|
|
+ showBatchInputDialog.value = false
|
|
|
|
|
+ batchSNText.value = ''
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 处理SN输入,自动提取中间数据并更新输入框显示
|
|
|
|
|
+ * @param formType 表单类型:'inStorageForm' | 'lendForm' | 'editForm'
|
|
|
|
|
+ */
|
|
|
|
|
+const handleSNInput = (formType: string) => {
|
|
|
|
|
+ let form: any
|
|
|
|
|
+ switch (formType) {
|
|
|
|
|
+ case 'inStorageForm':
|
|
|
|
|
+ form = inStorageForm
|
|
|
|
|
+ break
|
|
|
|
|
+ case 'lendForm':
|
|
|
|
|
+ form = lendForm
|
|
|
|
|
+ break
|
|
|
|
|
+ case 'editForm':
|
|
|
|
|
+ form = editForm
|
|
|
|
|
+ break
|
|
|
|
|
+ default:
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (form.T_sn) {
|
|
|
|
|
+ const extractedSN = extractSN(form.T_sn)
|
|
|
|
|
+ // 如果提取的SN与原始SN不同,说明需要自动处理
|
|
|
|
|
+ if (extractedSN !== form.T_sn) {
|
|
|
|
|
+ form.T_sn = extractedSN
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 入库
|
|
|
|
|
+const submitInStorageForm = () => {
|
|
|
|
|
+ inStorageFormRef.value?.validate(async (valid: boolean) => {
|
|
|
|
|
+ if (valid) {
|
|
|
|
|
+ console.log(inStorageForm.T_sn)
|
|
|
|
|
+ const extractedSN = extractSN(inStorageForm.T_sn)
|
|
|
|
|
+ if (pendingItems.value.some((item: any) => item.T_sn === extractedSN)) {
|
|
|
|
|
+ inStorageForm.T_sn = ''
|
|
|
|
|
+ ElMessage.warning('已存在相同的SN,不能添加')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ const result: any = await readValidationV2({sn: extractedSN})
|
|
|
|
|
+ if ((result.Code == 200) && (result.Data.T_state == 2)) {
|
|
|
|
|
+ //1-已出库 2-待使用 3-待维修
|
|
|
|
|
+ inStorageForm.T_sn = ''
|
|
|
|
|
+ ElMessage.warning('当前SN已入库不能重复入库')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ pendingItems.value.unshift({...inStorageForm, T_sn: extractedSN})
|
|
|
|
|
+ inStorageForm.T_sn = ''
|
|
|
|
|
+ inStorageForm.Validationnumber = ''
|
|
|
|
|
+ inStorageForm.T_remark = ''
|
|
|
|
|
+ ElMessage.success('已添加到待提交列表')
|
|
|
|
|
+ if ('speechSynthesis' in window) {
|
|
|
|
|
+ const utterance = new SpeechSynthesisUtterance('添加成功')
|
|
|
|
|
+ window.speechSynthesis.speak(utterance)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ console.warn('Web Speech API 不被支持')
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const removePendingItem = (index: number) => {
|
|
|
|
|
+ pendingItems.value.splice(index, 1)
|
|
|
|
|
+ ElMessage.success('已从待提交列表中移除')
|
|
|
|
|
+}
|
|
|
|
|
+// 归还
|
|
|
|
|
+const submitInStoragePendingItems = async () => {
|
|
|
|
|
+ if (pendingItems.value.length === 0) {
|
|
|
|
|
+ ElMessage.warning('暂无数据可提交')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const rest = JSON.parse(JSON.stringify(pendingItems.value))
|
|
|
|
|
+ try {
|
|
|
|
|
+ const result: any = await validationV2_add(rest)
|
|
|
|
|
+ if (result.Code === 200) {
|
|
|
|
|
+ ElMessage.success('提交成功')
|
|
|
|
|
+ pendingItems.value = []
|
|
|
|
|
+ inStorageForm.T_sn = ''
|
|
|
|
|
+ inStorageForm.Validationnumber = ''
|
|
|
|
|
+ inStorageForm.T_remark = ''
|
|
|
|
|
+ searchHandle()
|
|
|
|
|
+ nextTick(() => {
|
|
|
|
|
+ showInStorageForm.value = false
|
|
|
|
|
+ })
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error('提交失败')
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ ElMessage.error('提交失败,请检查网络连接')
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+const handlePageChange = (page: number) => {
|
|
|
|
|
+ currentPage.value = page
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const showLendForm = ref(false)
|
|
|
|
|
+const lendFormRef = ref<FormInstance | null>(null)
|
|
|
|
|
+const lendForm = reactive({
|
|
|
|
|
+ T_sn: '',
|
|
|
|
|
+ Validationnumber: '',
|
|
|
|
|
+ T_remark: '',
|
|
|
|
|
+ LendUser: '',
|
|
|
|
|
+ T_project: ''
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+// 同步“借出人”和“借出项目”到下方待提交表格
|
|
|
|
|
+watch(
|
|
|
|
|
+ () => lendForm.LendUser,
|
|
|
|
|
+ (newVal) => {
|
|
|
|
|
+ pendingLendItems.value.forEach((item) => {
|
|
|
|
|
+ item.LendUser = newVal || ''
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+watch(
|
|
|
|
|
+ () => lendForm.T_project,
|
|
|
|
|
+ (newVal) => {
|
|
|
|
|
+ pendingLendItems.value.forEach((item) => {
|
|
|
|
|
+ item.T_project = newVal || ''
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+interface LendItem {
|
|
|
|
|
+ T_sn: string
|
|
|
|
|
+ Validationnumber: string
|
|
|
|
|
+ T_remark: string
|
|
|
|
|
+ LendUser: string
|
|
|
|
|
+ T_project: string
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const pendingLendItems = ref<LendItem[]>([])
|
|
|
|
|
+const lendPageSize = ref(8)
|
|
|
|
|
+const lendCurrentPage = ref(1)
|
|
|
|
|
+
|
|
|
|
|
+const paginatedPendingLendItems = computed(() => {
|
|
|
|
|
+ const start = (lendCurrentPage.value - 1) * lendPageSize.value
|
|
|
|
|
+ const end = start + lendPageSize.value
|
|
|
|
|
+ return pendingLendItems.value.slice(start, end)
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+const lendRules = reactive({
|
|
|
|
|
+ T_sn: [{required: true, message: '请输入SN', trigger: 'blur'}],
|
|
|
|
|
+ LendUser: [{required: true, message: '请输入借出人', trigger: 'blur'}]
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+const submitLendForm = () => {
|
|
|
|
|
+ console.log()
|
|
|
|
|
+ lendFormRef.value?.validate(async (valid: boolean) => {
|
|
|
|
|
+ if (valid) {
|
|
|
|
|
+ const extractedSN = extractSN(lendForm.T_sn)
|
|
|
|
|
+ console.log(lendForm.T_sn)
|
|
|
|
|
+ if (pendingLendItems.value.some((item: any) => item.T_sn === extractedSN)) {
|
|
|
|
|
+ lendForm.T_sn = ''
|
|
|
|
|
+ ElMessage.warning('已存在相同的SN,不能添加')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ const result: any = await readValidationV2({sn: extractedSN})
|
|
|
|
|
+ if (result.Code !== 200) {
|
|
|
|
|
+ lendForm.T_sn = ''
|
|
|
|
|
+ ElMessage.warning('当前SN未入库不能借出')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if (result.Data.T_state == 5) {
|
|
|
|
|
+ ElMessage.warning('设备已损坏')
|
|
|
|
|
+ if ('speechSynthesis' in window) {
|
|
|
|
|
+ const utterance = new SpeechSynthesisUtterance('设备已损坏')
|
|
|
|
|
+ window.speechSynthesis.speak(utterance)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ console.warn('Web Speech API 不被支持')
|
|
|
|
|
+ }
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if (result.Data.T_state != 2) {
|
|
|
|
|
+ lendForm.T_sn = ''
|
|
|
|
|
+ ElMessage.warning('当前SN未入库不能借出')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ pendingLendItems.value.unshift({
|
|
|
|
|
+ T_sn: extractedSN,
|
|
|
|
|
+ Validationnumber: lendForm.Validationnumber,
|
|
|
|
|
+ T_remark: lendForm.T_remark,
|
|
|
|
|
+ LendUser: lendForm.LendUser,
|
|
|
|
|
+ T_project: lendForm.T_project
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ lendForm.T_sn = ''
|
|
|
|
|
+ lendForm.T_remark = ''
|
|
|
|
|
+ ElMessage.success('已添加到待提交列表')
|
|
|
|
|
+ if ('speechSynthesis' in window) {
|
|
|
|
|
+ const utterance = new SpeechSynthesisUtterance('添加成功')
|
|
|
|
|
+ window.speechSynthesis.speak(utterance)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ console.warn('Web Speech API 不被支持')
|
|
|
|
|
+ }
|
|
|
|
|
+ pendingLendItems.value = pendingLendItems.value.filter((value: any, index: any, self: any) => { //去重
|
|
|
|
|
+ return self.findIndex((t: any) => (t.T_sn === value.T_sn)) === index;
|
|
|
|
|
+ });
|
|
|
|
|
+ } else {
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const removePendingLendItem = (index: number) => {
|
|
|
|
|
+ pendingLendItems.value.splice(index, 1)
|
|
|
|
|
+ ElMessage.success('已从待提交列表中移除')
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const submitLendPendingItems = async () => {
|
|
|
|
|
+ if (pendingLendItems.value.length === 0) {
|
|
|
|
|
+ ElMessage.warning('暂无数据可提交')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ const rest = JSON.parse(JSON.stringify(pendingLendItems.value))
|
|
|
|
|
+
|
|
|
|
|
+ const result: any = await validationV2_update(rest)
|
|
|
|
|
+ if (result.Code == 200) {
|
|
|
|
|
+ ElMessage.success('提交成功')
|
|
|
|
|
+ pendingLendItems.value = []
|
|
|
|
|
+ lendForm.T_sn = ''
|
|
|
|
|
+ lendForm.T_remark = ''
|
|
|
|
|
+ lendForm.LendUser = ''
|
|
|
|
|
+ lendForm.T_project = ''
|
|
|
|
|
+ searchHandle()
|
|
|
|
|
+ nextTick(() => {
|
|
|
|
|
+ showLendForm.value = false
|
|
|
|
|
+ })
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error('提交失败')
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleLendPageChange = (page: number) => {
|
|
|
|
|
+ lendCurrentPage.value = page
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const showEditForm = ref(false)
|
|
|
|
|
+const ImportEdit = ref(false)
|
|
|
|
|
+const editFormRef = ref<FormInstance | null>(null)
|
|
|
|
|
+const editForm = reactive({
|
|
|
|
|
+ T_sn: '',
|
|
|
|
|
+ Validationnumber: '',
|
|
|
|
|
+ T_remark: '',
|
|
|
|
|
+ T_state: '',
|
|
|
|
|
+ T_class: ''
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+const previewEdit = async (row: any) => {
|
|
|
|
|
+ showEditForm.value = true
|
|
|
|
|
+ const result: any = await readValidationV2({sn: row.T_sn})
|
|
|
|
|
+ if (result.Code === 200) {
|
|
|
|
|
+ Object.assign(editForm, result.Data)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error('获取数据失败')
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+const preview = (T_sn: any) => {
|
|
|
|
|
+ recordInitParam.T_sn = T_sn
|
|
|
|
|
+ dialogTableVisible.value = true
|
|
|
|
|
+ recordTableRef.value?.searchTable()
|
|
|
|
|
+}
|
|
|
|
|
+const callbackSnDrawer = (done: () => void) => done()
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+const operationPreview = () => {
|
|
|
|
|
+ operationVisible.value = true
|
|
|
|
|
+ operationTableRef.value?.searchTable()
|
|
|
|
|
+}
|
|
|
|
|
+const tableSnData = ref<any[]>([])
|
|
|
|
|
+const previewSn = (devicelist: any[]) => {
|
|
|
|
|
+ drawerSnRef.value?.openDrawer()
|
|
|
|
|
+ if (!devicelist) return
|
|
|
|
|
+ tableSnData.value = devicelist.map((item: string) => {
|
|
|
|
|
+ return {
|
|
|
|
|
+ sn: item
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const submitEditForm = () => {
|
|
|
|
|
+ editFormRef.value?.validate(async (valid: boolean): Promise<void> => {
|
|
|
|
|
+ if (valid) {
|
|
|
|
|
+ const result: any = await updateValidationV2(editForm)
|
|
|
|
|
+ if (result.Code === 200) {
|
|
|
|
|
+ ElMessage.success('编辑成功')
|
|
|
|
|
+ showEditForm.value = false
|
|
|
|
|
+ searchHandle()
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error('编辑失败')
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // do nothing
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const handleFileChange = (file: any, fileList: any) => {
|
|
|
|
|
+ uploadFiles.value = fileList.map((item: any) => item.raw) // 新增:更新上传文件列表
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const submitUpload = async () => {
|
|
|
|
|
+ if (uploadFiles.value.length === 0) {
|
|
|
|
|
+ // 修改:使用 uploadFiles.value
|
|
|
|
|
+ ElMessage.warning('请先选择文件')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ const formData = new FormData()
|
|
|
|
|
+ uploadFiles.value.forEach((file: File) => {
|
|
|
|
|
+ // 修改:遍历 uploadFiles.value
|
|
|
|
|
+ formData.append('excelFile', file)
|
|
|
|
|
+ })
|
|
|
|
|
+ const loading = ElLoading.service({
|
|
|
|
|
+ // 新增:显示加载动画
|
|
|
|
|
+ lock: true,
|
|
|
|
|
+ text: '正在上传文件...',
|
|
|
|
|
+ background: 'rgba(0, 0, 0, 0.7)'
|
|
|
|
|
+ })
|
|
|
|
|
+ try {
|
|
|
|
|
+ const result: any = await uploadFileV2(formData)
|
|
|
|
|
+ if (result.Code === 200) {
|
|
|
|
|
+ ElMessage.success('文件上传成功')
|
|
|
|
|
+ // 处理上传成功后的逻辑
|
|
|
|
|
+ searchHandle()
|
|
|
|
|
+ uploadFiles.value = [] // 新增:清除文件上传列表
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error('文件上传失败')
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ ElMessage.error('文件上传失败,请检查网络连接')
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ loading.close() // 新增:关闭加载动画
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const btnRef = ref()
|
|
|
|
|
+const openDrawer = (tit: string, row: any, snItems: any) => {
|
|
|
|
|
+ btnRef.value.outerVisible = true
|
|
|
|
|
+ btnRef.value.data.title = tit
|
|
|
|
|
+ btnRef.value.data.snItems = snItems
|
|
|
|
|
+ btnRef.value.data.fromData = row
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+interface AddSnItem {
|
|
|
|
|
+ T_sn: string
|
|
|
|
|
+ Validationnumber: string
|
|
|
|
|
+ T_remark: string
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const holdRepairForm = reactive({
|
|
|
|
|
+ T_sn: '',
|
|
|
|
|
+ T_remark: '',
|
|
|
|
|
+})
|
|
|
|
|
+const holdScrapForm = reactive({
|
|
|
|
|
+ T_sn: '',
|
|
|
|
|
+ T_remark: '',
|
|
|
|
|
+})
|
|
|
|
|
+const holdReturnForm = reactive({
|
|
|
|
|
+ T_sn: '',
|
|
|
|
|
+ T_remark: '',
|
|
|
|
|
+})
|
|
|
|
|
+const ReturnSnItems = ref<AddSnItem[]>([])
|
|
|
|
|
+const RepairSnItems = ref<AddSnItem[]>([])
|
|
|
|
|
+const ScrapSnItems = ref<AddSnItem[]>([])
|
|
|
|
|
+const successFun = () => {
|
|
|
|
|
+ TableRef.value?.searchTable()
|
|
|
|
|
+ btnRef.value.data.fromData.T_remark = ''
|
|
|
|
|
+ if (btnRef.value.data.title == '归还') {
|
|
|
|
|
+ ReturnSnItems.value = [];
|
|
|
|
|
+ }
|
|
|
|
|
+ if (btnRef.value.data.title == '维修') {
|
|
|
|
|
+ RepairSnItems.value = [];
|
|
|
|
|
+ }
|
|
|
|
|
+ if (btnRef.value.data.title == '报废') {
|
|
|
|
|
+ ScrapSnItems.value = [];
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 远程搜索用户的方法
|
|
|
|
|
+const remoteMethod = async (query: string) => {
|
|
|
|
|
+ if (query.trim()) {
|
|
|
|
|
+ userLoading.value = true;
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res: any = await User_List({
|
|
|
|
|
+ User_tokey: globalStore.GET_User_tokey,
|
|
|
|
|
+ T_name: query,
|
|
|
|
|
+ page_z: 100
|
|
|
|
|
+ });
|
|
|
|
|
+ if (res.Code === 200) {
|
|
|
|
|
+ // 确保数据格式正确
|
|
|
|
|
+ const formattedOptions = res.Data.Data?.map((user: any) => ({
|
|
|
|
|
+ T_uuid: user.T_uuid,
|
|
|
|
|
+ T_name: user.T_name
|
|
|
|
|
+ })) || [];
|
|
|
|
|
+ userOptions.value = formattedOptions;
|
|
|
|
|
+ // 添加调试信息
|
|
|
|
|
+ console.log('搜索结果:', formattedOptions);
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ ElMessage.error('搜索用户失败');
|
|
|
|
|
+ console.error('搜索用户错误:', error);
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ userLoading.value = false;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ userOptions.value = [];
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+// 选择用户后的处理函数
|
|
|
|
|
+const handleUserChange = (value: string) => {
|
|
|
|
|
+ if (value) {
|
|
|
|
|
+ const selectedUser = userOptions.value.find(user => user.T_uuid === value);
|
|
|
|
|
+ if (selectedUser) {
|
|
|
|
|
+ lendForm.LendUser = selectedUser.T_name;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ lendForm.LendUser = '';
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+// 用户搜索相关
|
|
|
|
|
+const userOptions = ref<any[]>([]);
|
|
|
|
|
+const userLoading = ref(false);
|
|
|
|
|
+
|
|
|
|
|
+onMounted(() => {
|
|
|
|
|
+ getValidationToolClassList()
|
|
|
|
|
+})
|
|
|
|
|
+</script>
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div class="list">
|
|
|
|
|
+ <TableBase
|
|
|
|
|
+ ref="TableRef"
|
|
|
|
|
+ :columns="columns"
|
|
|
|
|
+ :requestApi="validationV2_List"
|
|
|
|
|
+ :initParam="initParam"
|
|
|
|
|
+ :pagination="true"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #table-header>
|
|
|
|
|
+ <div class="input-suffix">
|
|
|
|
|
+ <el-row :gutter="20" style="margin-bottom: 0">
|
|
|
|
|
+ <el-col :xl="3" :lg="3" :md="3">
|
|
|
|
|
+ <span class="inline-flex items-center">设备编号:</span>
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="initParam.Validationnumber"
|
|
|
|
|
+ class="w-50 m-2"
|
|
|
|
|
+ type="text"
|
|
|
|
|
+ placeholder="设备编号搜索"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ @change="searchHandle"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :xl="3" :lg="3" :md="3">
|
|
|
|
|
+ <span class="inline-flex items-center">状态:</span>
|
|
|
|
|
+ <el-select v-model="initParam.T_state" class="w-50 m-2" clearable placeholder="请选择状态~">
|
|
|
|
|
+ <el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id"/>
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :xl="3" :lg="3" :md="3">
|
|
|
|
|
+ <span class="inline-flex items-center">SN:</span>
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ class="w-50 m-2"
|
|
|
|
|
+ v-model="initParam.T_sn"
|
|
|
|
|
+ type="text"
|
|
|
|
|
+ placeholder="按SN搜索"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ @change="searchHandle"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :xl="3" :lg="3" :md="3">
|
|
|
|
|
+ <span class="inline-flex items-center">设备类型:</span>
|
|
|
|
|
+ <el-select v-model="initParam.T_class" class="w-50 m-2" clearable
|
|
|
|
|
+ placeholder="请选择设备类型~">
|
|
|
|
|
+ <el-option v-for="item in Pruductoptions" :key="item.Id" :label="item.T_name"
|
|
|
|
|
+ :value="item.Id"/>
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :xl="3" :lg="3" :md="3">
|
|
|
|
|
+ <span class="inline-flex items-center">模组imei:</span>
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ class="w-50 m-2"
|
|
|
|
|
+ v-model="initParam.T_imei"
|
|
|
|
|
+ type="text"
|
|
|
|
|
+ placeholder="按模组imei搜索"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ @change="searchHandle"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :xl="3" :lg="3" :md="3">
|
|
|
|
|
+ <span class="inline-flex items-center">借出人</span>
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ class="w-50 m-2"
|
|
|
|
|
+ v-model="initParam.LendUser"
|
|
|
|
|
+ type="text"
|
|
|
|
|
+ placeholder="按借出人搜索"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ @change="searchHandle"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :xl="3" :lg="3" :md="3">
|
|
|
|
|
+ <span class="inline-flex items-center">借出项目</span>
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ class="w-50 m-2"
|
|
|
|
|
+ v-model="initParam.T_project"
|
|
|
|
|
+ type="text"
|
|
|
|
|
+ placeholder="按借出项目搜索"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ @change="searchHandle"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :xl="3" :lg="3" :md="3">
|
|
|
|
|
+ <span class="inline-flex items-center">物联网卡号:</span>
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ class="w-50 m-2"
|
|
|
|
|
+ v-model="initParam.T_iccid"
|
|
|
|
|
+ type="text"
|
|
|
|
|
+ placeholder="按物联网卡号搜索"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ @change="searchHandle"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :xl="15" :lg="15" :md="15" style="margin-top: 10px">
|
|
|
|
|
+ <el-button type="primary" @click="searchHandle">搜索</el-button>
|
|
|
|
|
+ <el-button type="primary" @click="showInStorageForm = true">入库
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <el-button type="primary" @click="showLendForm = true">借出
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <el-button type="primary" @click="openDrawer('归还',holdReturnForm,ReturnSnItems)">归还
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <el-button type="warning" @click="openDrawer('维修',holdRepairForm,RepairSnItems)">维修
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <el-button type="danger" @click="openDrawer('报废',holdScrapForm,ScrapSnItems)">报废
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <el-button type="success" @click="ImportEdit = true">模板导入</el-button>
|
|
|
|
|
+ <el-button type="success" @click="exportExcel">导出</el-button>
|
|
|
|
|
+ <el-button type="primary" @click="operationPreview">操作记录</el-button>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <template #T_state="{ row }">
|
|
|
|
|
+ <el-tag v-if="row.T_state == 1" type="success" effect="dark"> 已出库</el-tag>
|
|
|
|
|
+ <el-tag v-if="row.T_state == 2" effect="dark">未出库</el-tag>
|
|
|
|
|
+ <el-tag v-if="row.T_state == 3" effect="dark" type="warning">维修中</el-tag>
|
|
|
|
|
+ <el-tag v-if="row.T_state == 4" effect="dark" type="danger">已报废</el-tag>
|
|
|
|
|
+ <el-tag v-if="row.T_state == 5" effect="dark" type="info">已损坏</el-tag>
|
|
|
|
|
+ <el-tag v-if="row.T_state == 6" effect="light" type="warning">转移中</el-tag>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <template #T_class="{ row }">
|
|
|
|
|
+ <el-tag>{{ Pruductoptions.find((option: any) => option.Id === row.T_class)?.T_name || '' }}</el-tag>
|
|
|
|
|
+
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <template #right="{ row }">
|
|
|
|
|
+ <el-button link type="primary" size="small" :icon="View" @click="preview(row.T_sn)">记录</el-button>
|
|
|
|
|
+ <el-button link type="success" size="small" :icon="Edit" @click="previewEdit(row)">编辑</el-button>
|
|
|
|
|
+ <el-button link type="danger" size="small" :icon="Delete" @click="deleteFun(row.T_sn)">删除</el-button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </TableBase>
|
|
|
|
|
+ <el-dialog title="入库" v-model="showInStorageForm" width="50%">
|
|
|
|
|
+ <el-form :model="inStorageForm" :rules="rules" ref="inStorageFormRef">
|
|
|
|
|
+ <el-form-item label="SN" prop="T_sn">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="inStorageForm.T_sn"
|
|
|
|
|
+ placeholder="请输入SN"
|
|
|
|
|
+ @keyup.enter="submitInStorageForm"
|
|
|
|
|
+ @input="handleSNInput('inStorageForm')"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="设备编号" prop="Validationnumber">
|
|
|
|
|
+ <el-input v-model="inStorageForm.Validationnumber" placeholder="请输入设备编号"></el-input>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="设备类型" prop="T_class">
|
|
|
|
|
+ <el-select v-model="inStorageForm.T_class" class="w-50 m-2" clearable placeholder="请选择设备类型~">
|
|
|
|
|
+ <el-option v-for="item in Pruductoptions" :key="item.Id" :label="item.T_name" :value="item.Id"/>
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="备注">
|
|
|
|
|
+ <el-input v-model="inStorageForm.T_remark" type="textarea" placeholder="请输入备注"></el-input>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ <!-- 新增数据条数提示 -->
|
|
|
|
|
+ <div style="margin: 10px 0">
|
|
|
|
|
+ <span>当前待提交数据条数: {{ pendingItems.length }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <el-table :data="paginatedPendingItems" style="width: 100%; margin-top: 20px">
|
|
|
|
|
+ <el-table-column type="index" label="序号" width="80"></el-table-column>
|
|
|
|
|
+ <!-- 添加序号列 -->
|
|
|
|
|
+ <el-table-column prop="T_sn" label="SN" width="300"></el-table-column>
|
|
|
|
|
+ <el-table-column prop="Validationnumber" label="设备编号"></el-table-column>
|
|
|
|
|
+ <el-table-column prop="T_class" label="设备类型"></el-table-column>
|
|
|
|
|
+ <el-table-column prop="T_remark" label="备注"></el-table-column>
|
|
|
|
|
+ <el-table-column label="操作" width="180">
|
|
|
|
|
+ <template #default="scope">
|
|
|
|
|
+ <el-button type="danger" size="small" @click="removePendingItem(scope.$index)">删除</el-button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ </el-table>
|
|
|
|
|
+ <el-pagination
|
|
|
|
|
+ background
|
|
|
|
|
+ layout="prev, pager, next"
|
|
|
|
|
+ :total="pendingItems.length"
|
|
|
|
|
+ :page-size="pageSize"
|
|
|
|
|
+ :current-page="currentPage"
|
|
|
|
|
+ @current-change="handlePageChange"
|
|
|
|
|
+ style="margin-top: 20px; text-align: right"
|
|
|
|
|
+ />
|
|
|
|
|
+ <template #footer>
|
|
|
|
|
+ <span class="dialog-footer">
|
|
|
|
|
+ <el-button @click="showInStorageForm = false">取消</el-button>
|
|
|
|
|
+ <el-button type="primary" @click="submitInStorageForm">添加到暂存</el-button>
|
|
|
|
|
+ <!-- 新增提交按钮 -->
|
|
|
|
|
+ <el-button type="primary" @click="submitInStoragePendingItems">提交</el-button>
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-dialog>
|
|
|
|
|
+ <el-dialog title="借出" v-model="showLendForm" width="50%">
|
|
|
|
|
+ <el-form :model="lendForm" :rules="lendRules" ref="lendFormRef">
|
|
|
|
|
+ <!-- 新增借出人和借出项目 -->
|
|
|
|
|
+ <el-form-item class="m-b-6" :label-width="formLabelWidth" label="借出人" prop="LendUser">
|
|
|
|
|
+ <el-select
|
|
|
|
|
+ v-model="lendForm.LendUser"
|
|
|
|
|
+ filterable
|
|
|
|
|
+ remote
|
|
|
|
|
+ reserve-keyword
|
|
|
|
|
+ placeholder="请输入接收人"
|
|
|
|
|
+ :remote-method="remoteMethod"
|
|
|
|
|
+ :loading="userLoading"
|
|
|
|
|
+ class="w-50"
|
|
|
|
|
+ @change="handleUserChange"
|
|
|
|
|
+ :clearable="true"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-option
|
|
|
|
|
+ v-for="item in userOptions"
|
|
|
|
|
+ :key="item.T_uuid"
|
|
|
|
|
+ :label="item.T_name"
|
|
|
|
|
+ :value="item.T_uuid"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item class="m-b-6" :label-width="formLabelWidth" label="借出项目" prop="T_project">
|
|
|
|
|
+ <el-input v-model="lendForm.T_project" placeholder="请输入借出项目"></el-input>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item class="m-b-6" :label-width="formLabelWidth" label="SN" prop="T_sn">
|
|
|
|
|
+ <el-input v-model="lendForm.T_sn" placeholder="请输入SN" @keyup.enter="submitLendForm" @input="handleSNInput('lendForm')">
|
|
|
|
|
+ <template #append>
|
|
|
|
|
+ <el-button type="primary" @click="openBatchInputDialog('lend')">批量录入</el-button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-input>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item class="m-b-6" :label-width="formLabelWidth" label="备注">
|
|
|
|
|
+ <el-input v-model="lendForm.T_remark" type="textarea" placeholder="请输入备注"></el-input>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ <!-- 新增数据条数提示 -->
|
|
|
|
|
+ <div style="margin: 10px 0">
|
|
|
|
|
+ <span>当前待提交数据条数: {{ pendingLendItems.length }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <el-table :data="paginatedPendingLendItems" style="width: 100%; margin-top: 20px">
|
|
|
|
|
+ <el-table-column type="index" label="序号" width="80"></el-table-column>
|
|
|
|
|
+ <!-- 添加序号列 -->
|
|
|
|
|
+ <el-table-column prop="T_sn" label="SN" width="300"></el-table-column>
|
|
|
|
|
+ <el-table-column prop="LendUser" label="借出人"></el-table-column>
|
|
|
|
|
+ <el-table-column prop="T_project" label="借出项目"></el-table-column>
|
|
|
|
|
+ <el-table-column prop="T_remark" label="备注"></el-table-column>
|
|
|
|
|
+ <el-table-column label="操作" width="180">
|
|
|
|
|
+ <template #default="scope">
|
|
|
|
|
+ <el-button type="danger" size="small" @click="removePendingLendItem(scope.$index)">删除
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ </el-table>
|
|
|
|
|
+ <el-pagination
|
|
|
|
|
+ background
|
|
|
|
|
+ layout="prev, pager, next"
|
|
|
|
|
+ :total="pendingLendItems.length"
|
|
|
|
|
+ :page-size="lendPageSize"
|
|
|
|
|
+ :current-page="lendCurrentPage"
|
|
|
|
|
+ @current-change="handleLendPageChange"
|
|
|
|
|
+ style="margin-top: 20px; text-align: right"
|
|
|
|
|
+ />
|
|
|
|
|
+ <template #footer>
|
|
|
|
|
+ <span class="dialog-footer">
|
|
|
|
|
+ <el-button @click="showLendForm = false">取消</el-button>
|
|
|
|
|
+ <el-button type="primary" @click="submitLendForm">添加到暂存</el-button>
|
|
|
|
|
+ <!-- 新增提交按钮 -->
|
|
|
|
|
+ <el-button type="primary" @click="submitLendPendingItems">提交</el-button>
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-dialog>
|
|
|
|
|
+ <el-dialog title="编辑" v-model="showEditForm" width="50%">
|
|
|
|
|
+ <el-form :model="editForm" ref="editFormRef">
|
|
|
|
|
+ <el-form-item label="SN" prop="T_sn">
|
|
|
|
|
+ <el-input v-model="editForm.T_sn" placeholder="请输入SN" @input="handleSNInput('editForm')"></el-input>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="设备编号" prop="Validationnumber">
|
|
|
|
|
+ <el-input v-model="editForm.Validationnumber" placeholder="请输入设备编号"></el-input>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="状态">
|
|
|
|
|
+ <el-select v-model="editForm.T_state" class="w-50 m-2" clearable placeholder="请选择状态~">
|
|
|
|
|
+ <el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id"/>
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="设备类型">
|
|
|
|
|
+ <el-select v-model="editForm.T_class" class="w-50 m-2" clearable placeholder="请选择设备类型~">
|
|
|
|
|
+ <el-option v-for="item in Pruductoptions" :key="item.Id" :label="item.T_name" :value="item.Id"/>
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="备注">
|
|
|
|
|
+ <el-input v-model="editForm.T_remark" type="textarea" placeholder="请输入备注"></el-input>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ <template #footer>
|
|
|
|
|
+ <span class="dialog-footer">
|
|
|
|
|
+ <el-button @click="showEditForm = false">取消</el-button>
|
|
|
|
|
+ <el-button type="primary" @click="submitEditForm">提交</el-button>
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-dialog>
|
|
|
|
|
+
|
|
|
|
|
+ <el-dialog title="模板导入" v-model="ImportEdit" width="50%">
|
|
|
|
|
+ <el-upload ref="uploadRef" class="upload-demo" :auto-upload="false" @change="handleFileChange">
|
|
|
|
|
+ <template #trigger>
|
|
|
|
|
+ <el-button type="primary">模板导入</el-button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+
|
|
|
|
|
+ <el-button class="ml-3" type="success" @click="submitUpload"> 提交文件</el-button>
|
|
|
|
|
+ <template #tip></template>
|
|
|
|
|
+ </el-upload>
|
|
|
|
|
+ </el-dialog>
|
|
|
|
|
+ <el-dialog title="查看记录" v-model="dialogTableVisible" width="60%">
|
|
|
|
|
+
|
|
|
|
|
+ <TableBase
|
|
|
|
|
+ ref="recordTableRef"
|
|
|
|
|
+ :columns="recordColumns"
|
|
|
|
|
+ :requestApi="validationV2_recordList"
|
|
|
|
|
+ :initParam="recordInitParam"
|
|
|
|
|
+ :pagination="true"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #table-header>
|
|
|
|
|
+ <div class="input-suffix">
|
|
|
|
|
+ <el-row :gutter="20" style="margin-bottom: 0">
|
|
|
|
|
+ <el-col :xl="4" :lg="4" :md="4">
|
|
|
|
|
+ <span class="inline-flex items-center">设备编号:</span>
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="recordInitParam.Validationnumber"
|
|
|
|
|
+ class="w-50 m-2"
|
|
|
|
|
+ type="text"
|
|
|
|
|
+ placeholder="设备编号搜索"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ @change="recordSearchHandle"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :xl="4" :lg="4" :md="4">
|
|
|
|
|
+ <span class="inline-flex items-center">状态:</span>
|
|
|
|
|
+ <el-select v-model="recordInitParam.T_state" class="w-50 m-2" clearable
|
|
|
|
|
+ placeholder="请选择状态~">
|
|
|
|
|
+ <el-option v-for="item in options" :key="item.id" :label="item.name"
|
|
|
|
|
+ :value="item.id"/>
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :xl="4" :lg="4" :md="4">
|
|
|
|
|
+ <span class="inline-flex items-center">借出(归还)人</span>
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ class="w-50 m-2"
|
|
|
|
|
+ v-model="recordInitParam.LendUser"
|
|
|
|
|
+ type="text"
|
|
|
|
|
+ placeholder="按借出(归还)人搜索"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ @change="recordSearchHandle"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :xl="4" :lg="4" :md="4">
|
|
|
|
|
+ <span class="inline-flex items-center">关联项目</span>
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ class="w-50 m-2"
|
|
|
|
|
+ v-model="recordInitParam.T_project"
|
|
|
|
|
+ type="text"
|
|
|
|
|
+ placeholder="按关联项目搜索"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ @change="recordSearchHandle"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :xl="4" :lg="4" :md="4">
|
|
|
|
|
+ <span class="inline-flex items-center">物联网卡号:</span>
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ class="w-50 m-2"
|
|
|
|
|
+ v-model="recordInitParam.T_iccid"
|
|
|
|
|
+ type="text"
|
|
|
|
|
+ placeholder="按物联网卡号搜索"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ @change="recordSearchHandle"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :xl="4" :lg="4" :md="4" style="margin-top: 10px">
|
|
|
|
|
+ <el-button type="primary" @click="recordSearchHandle">搜索</el-button>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+
|
|
|
|
|
+ <template #T_state="{ row }">
|
|
|
|
|
+ <el-tag v-if="row.T_state == 1" type="success" effect="dark"> 已出库</el-tag>
|
|
|
|
|
+ <el-tag v-if="row.T_state == 2" effect="dark">未出库</el-tag>
|
|
|
|
|
+ <el-tag v-if="row.T_state == 3" effect="dark" type="warning">维修中</el-tag>
|
|
|
|
|
+ <el-tag v-if="row.T_state == 4" effect="dark" type="danger">已报废</el-tag>
|
|
|
|
|
+ <el-tag v-if="row.T_state == 5" effect="dark" type="info">已损坏</el-tag>
|
|
|
|
|
+ <el-tag v-if="row.T_state == 6" effect="light" type="warning">转移</el-tag>
|
|
|
|
|
+ <el-tag v-if="row.T_state == 7" effect="light" type="info">取消转移</el-tag>
|
|
|
|
|
+ <el-tag v-if="row.T_state == 8" effect="light" type="success">已接收</el-tag>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <template #T_class="{ row }">
|
|
|
|
|
+ <el-tag>{{ Pruductoptions.find((option: any) => option.Id === row.T_class)?.T_name || '' }}</el-tag>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </TableBase>
|
|
|
|
|
+ </el-dialog>
|
|
|
|
|
+ <el-dialog title="操作记录" v-model="operationVisible" width="60%">
|
|
|
|
|
+
|
|
|
|
|
+ <TableBase
|
|
|
|
|
+ ref="operationTableRef"
|
|
|
|
|
+ :columns="operationColumns"
|
|
|
|
|
+ :requestApi="validationV2_operationList"
|
|
|
|
|
+ :initParam="operationInitParam"
|
|
|
|
|
+ :pagination="true"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #table-header>
|
|
|
|
|
+ <div class="input-suffix">
|
|
|
|
|
+ <el-row :gutter="20" style="margin-bottom: 0">
|
|
|
|
|
+ <el-col :xl="5" :lg="5" :md="5">
|
|
|
|
|
+ <span class="inline-flex items-center">SN:</span>
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ class="w-50 m-2"
|
|
|
|
|
+ v-model="operationInitParam.T_sn"
|
|
|
|
|
+ type="text"
|
|
|
|
|
+ placeholder="按SN搜索"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ @change="searchHandle"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :xl="5" :lg="5" :md="5">
|
|
|
|
|
+ <span class="inline-flex items-center">状态:</span>
|
|
|
|
|
+ <el-select v-model="operationInitParam.T_state" class="w-50 m-2" clearable
|
|
|
|
|
+ placeholder="请选择状态~">
|
|
|
|
|
+ <el-option v-for="item in options" :key="item.id" :label="item.name"
|
|
|
|
|
+ :value="item.id"/>
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :xl="5" :lg="5" :md="5">
|
|
|
|
|
+ <span class="inline-flex items-center">借出(归还)人</span>
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ class="w-50 m-2"
|
|
|
|
|
+ v-model="operationInitParam.LendUser"
|
|
|
|
|
+ type="text"
|
|
|
|
|
+ placeholder="按借出(归还)人搜索"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ @change="operationSearchHandle"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :xl="5" :lg="5" :md="5">
|
|
|
|
|
+ <span class="inline-flex items-center">关联项目</span>
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ class="w-50 m-2"
|
|
|
|
|
+ v-model="operationInitParam.T_project"
|
|
|
|
|
+ type="text"
|
|
|
|
|
+ placeholder="按关联项目搜索"
|
|
|
|
|
+ clearable
|
|
|
|
|
+ @change="operationSearchHandle"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :xl="4" :lg="4" :md="4" style="margin-top: 10px">
|
|
|
|
|
+ <el-button type="primary" @click="operationSearchHandle">搜索</el-button>
|
|
|
|
|
+ <el-button type="success" @click="exportOperationExcel">导出</el-button>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <template #T_state="{ row }">
|
|
|
|
|
+ <el-tag v-if="row.T_state == 1" type="success" effect="dark">出库</el-tag>
|
|
|
|
|
+ <el-tag v-if="row.T_state == 2" effect="dark">入库</el-tag>
|
|
|
|
|
+ <el-tag v-if="row.T_state == 3" effect="dark" type="warning">维修</el-tag>
|
|
|
|
|
+ <el-tag v-if="row.T_state == 4" effect="dark" type="danger">报废</el-tag>
|
|
|
|
|
+ <el-tag v-if="row.T_state == 5" effect="dark" type="info">损坏</el-tag>
|
|
|
|
|
+ <el-tag v-if="row.T_state == 6" effect="light" type="warning">转移</el-tag>
|
|
|
|
|
+ <el-tag v-if="row.T_state == 7" effect="light" type="info">取消转移</el-tag>
|
|
|
|
|
+ <el-tag v-if="row.T_state == 8" effect="light" type="success">已接收</el-tag>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <template #T_project="{ row }">
|
|
|
|
|
+ <div v-for="(item, index) in row.T_project" :key="index"> {{ item }}</div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <template #right="{ row }">
|
|
|
|
|
+ <el-button type="primary" @click="previewSn(row.T_sn_List)">查看</el-button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </TableBase>
|
|
|
|
|
+ </el-dialog>
|
|
|
|
|
+ <Drawer ref="drawerSnRef" :handleClose="callbackSnDrawer" size="40%">
|
|
|
|
|
+ <el-table
|
|
|
|
|
+ :data="tableSnData"
|
|
|
|
|
+ style="width: 100%; height: 99%"
|
|
|
|
|
+ :header-cell-style="{
|
|
|
|
|
+ background: '#dedfe0',
|
|
|
|
|
+ height: '50px'
|
|
|
|
|
+ }"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template v-for="item in snColumns" :key="item.prop">
|
|
|
|
|
+ <el-table-column show-overflow-tooltip v-if="item.type === 'index'" v-bind="item"/>
|
|
|
|
|
+ <el-table-column
|
|
|
|
|
+ show-overflow-tooltip
|
|
|
|
|
+ v-else-if="item.prop === 'T_project'"
|
|
|
|
|
+ :label="item.label"
|
|
|
|
|
+ :width="item.width"
|
|
|
|
|
+ align="center"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #default="scope">
|
|
|
|
|
+ {{ scope.row.sn.T_project }}
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column
|
|
|
|
|
+ show-overflow-tooltip
|
|
|
|
|
+ v-else-if="item.prop === 'T_number'"
|
|
|
|
|
+ :label="item.label"
|
|
|
|
|
+ :width="item.width"
|
|
|
|
|
+ align="center"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #default="scope">
|
|
|
|
|
+ {{ scope.row.sn.T_sn.length }}
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column
|
|
|
|
|
+ show-overflow-tooltip
|
|
|
|
|
+ v-else-if="item.prop === 'T_sn'"
|
|
|
|
|
+ :label="item.label"
|
|
|
|
|
+ :width="item.width"
|
|
|
|
|
+ align="center"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #default="scope">
|
|
|
|
|
+ <div v-for="(item, index) in scope.row.sn.T_sn" :key="index"> {{ item }}</div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table>
|
|
|
|
|
+
|
|
|
|
|
+ </Drawer>
|
|
|
|
|
+ <snAdd ref="btnRef" @successFun="successFun"></snAdd>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 批量录入SN对话框 -->
|
|
|
|
|
+ <el-dialog title="批量录入SN" v-model="showBatchInputDialog" width="60%">
|
|
|
|
|
+ <div style="margin-bottom: 10px;">
|
|
|
|
|
+ <p style="color: #909399; font-size: 12px;">
|
|
|
|
|
+ 提示:每行输入一个SN,系统会自动去除前2个字符(03)和后6个字符(000001)
|
|
|
|
|
+ </p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="batchSNText"
|
|
|
|
|
+ type="textarea"
|
|
|
|
|
+ :rows="10"
|
|
|
|
|
+ placeholder="请输入SN数据,每行一个,例如: 032025138451413256000001 032025144612387706000001"
|
|
|
|
|
+ />
|
|
|
|
|
+ <template #footer>
|
|
|
|
|
+ <span class="dialog-footer">
|
|
|
|
|
+ <el-button @click="showBatchInputDialog = false">取消</el-button>
|
|
|
|
|
+ <el-button type="primary" @click="submitBatchSN">确认添加</el-button>
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-dialog>
|
|
|
|
|
+
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped lang="scss">
|
|
|
|
|
+@import '@/styles/var.scss';
|
|
|
|
|
+
|
|
|
|
|
+.list {
|
|
|
|
|
+ @include f-direction;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// .input-suffix {
|
|
|
|
|
+// width: 100%;
|
|
|
|
|
+// .w-50 {
|
|
|
|
|
+// width: 33.33%;
|
|
|
|
|
+// }
|
|
|
|
|
+// }
|
|
|
|
|
+</style>
|
|
|
|
|
+
|
|
|
|
|
+
|