diff --git a/.env.development b/.env.development index 0750bac..ef4946d 100644 --- a/.env.development +++ b/.env.development @@ -14,4 +14,4 @@ VITE_APP_ROUTER_PREFIX = '/' VITE_APP_UPLOAD_URL = 'Common/UploadFile' #socket API -VITE_APP_SOCKET_API = 'http://localhost:11082/msghub' \ No newline at end of file +VITE_APP_SOCKET_API = 'http://localhost:11082/msghub' diff --git a/.env.production b/.env.production index 9b1280a..a107b9d 100644 --- a/.env.production +++ b/.env.production @@ -16,4 +16,4 @@ VITE_APP_UPLOAD_URL = 'Common/UploadFile' VITE_APP_SOCKET_API = 'http://49.233.115.141:11082/msghub' # 是否在打包时开启压缩,支持 gzip 和 brotli -VITE_BUILD_COMPRESS = gzip \ No newline at end of file +VITE_BUILD_COMPRESS = gzip diff --git a/.env.test b/.env.test new file mode 100644 index 0000000..51b2bae --- /dev/null +++ b/.env.test @@ -0,0 +1,19 @@ +# 生产环境配置 +ENV = 'production' + +VITE_APP_API_HOST = 'https://odf.zpc-xy.com/' + +# 生产环境 +VITE_APP_BASE_API = 'https://odf.zpc-xy.com/' + +# 路由前缀 +VITE_APP_ROUTER_PREFIX = '/' + +# 默认上传地址 +VITE_APP_UPLOAD_URL = 'Common/UploadFile' + +#socket API +VITE_APP_SOCKET_API = 'https://odf.zpc-xy.com/msghub' + +# 是否在打包时开启压缩,支持 gzip 和 brotli +VITE_BUILD_COMPRESS = gzip diff --git a/package.json b/package.json index f2d4dc9..da93fbc 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "dev": "vite", "build:prod": "vite build", "build:stage": "vite build --mode staging", + "build:test": "vite build --mode test", "preview": "vite preview" }, "repository": { diff --git a/src/api/business/odfappupdates.js b/src/api/business/odfappupdates.js new file mode 100644 index 0000000..d6d6abe --- /dev/null +++ b/src/api/business/odfappupdates.js @@ -0,0 +1,69 @@ +import request from '@/utils/request' + +/** + * App 更新表分页查询 + * @param {查询条件} data + */ +export function listOdfAppUpdates(query) { + return request({ + url: 'business/OdfAppUpdates/list', + method: 'get', + params: query, + }) +} + +/** + * 新增App 更新表 + * @param data + */ +export function addOdfAppUpdates(data) { + return request({ + url: 'business/OdfAppUpdates/add', + method: 'post', + data: data, + }) +} +/** + *修改App 更新表状态 + * @param {*} data {id:0,IsActive:true} + * @returns + */ +export function OdfAppStatus(data) { + return request({ + url: 'business/OdfAppUpdates/status', + method: 'post', + data: data, + }) +} +/** + * 修改App 更新表 + * @param data + */ +export function updateOdfAppUpdates(data) { + return request({ + url: 'business/OdfAppUpdates', + method: 'PUT', + data: data, + }) +} +/** + * 获取App 更新表详情 + * @param {Id} + */ +export function getOdfAppUpdates(id) { + return request({ + url: 'business/OdfAppUpdates/' + id, + method: 'get' + }) +} + +/** + * 删除App 更新表 + * @param {主键} pid + */ +export function delOdfAppUpdates(pid) { + return request({ + url: 'business/OdfAppUpdates/delete/' + pid, + method: 'POST' + }) +} diff --git a/src/components/FileUpload/index.vue b/src/components/FileUpload/index.vue index 872a3a3..6e4c111 100644 --- a/src/components/FileUpload/index.vue +++ b/src/components/FileUpload/index.vue @@ -68,12 +68,12 @@ const props = defineProps({ // 大小限制(MB) fileSize: { type: Number, - default: 5 + default: 50 }, // 文件类型, 例如['png', 'jpg', 'jpeg'] fileType: { type: Array, - default: () => ['doc', 'xls', 'ppt', 'txt', 'pdf'] + default: () => ['doc', 'xls', 'ppt', 'txt', 'pdf', 'apk'] }, // 是否显示提示 isShowTip: { diff --git a/src/components/business/OdfPortForm.vue b/src/components/business/OdfPortForm.vue index 45ff8fa..be534c6 100644 --- a/src/components/business/OdfPortForm.vue +++ b/src/components/business/OdfPortForm.vue @@ -30,18 +30,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + +
+
+ + + + + + + + + + + + +
+ +
+
+
+
+
+ 添加故障记录 +
+
- + @@ -132,8 +219,20 @@ const form = ref({ portNumber: null, status: null, opticalAttenuation: null, + equipmentModel: null, + businessType: null, + businessName: null, + port1: null, + port2: null, + port3: null, remarks: null, historyRemarks: null, + historyFault: [ + { + faultTime: null, + faultReason: null + } + ], createdAt: null, updatedAt: null }) @@ -151,15 +250,24 @@ const rules = { // 字典选项 const options = reactive({ - odf_ports_status: [] + odf_ports_status: [], + // 设备型号 选项列表 格式 eg:{ dictLabel: '标签', dictValue: '0'} + odf_ports_unit_type: [], + // 业务类型 选项列表 格式 eg:{ dictLabel: '标签', dictValue: '0'} + odf_ports_business_type: [] }) // 获取字典数据 -var dictParams = ['odf_ports_status'] +var dictParams = ['odf_ports_status', 'odf_ports_unit_type', 'odf_ports_business_type'] proxy.getDicts(dictParams).then((response) => { response.data.forEach((element) => { options[element.dictType] = element.list }) + console.debug('[OdfPortForm] dicts loaded:', { + statusLen: options.odf_ports_status.length, + unitTypeLen: options.odf_ports_unit_type.length, + businessTypeLen: options.odf_ports_business_type.length + }) }) // 重置表单 @@ -178,8 +286,20 @@ function resetForm() { portNumber: null, status: null, opticalAttenuation: null, + equipmentModel: null, + businessType: null, + businessName: null, + port1: null, + port2: null, + port3: null, remarks: null, historyRemarks: null, + historyFault: [ + { + faultTime: null, + faultReason: null + } + ], createdAt: null, updatedAt: null } @@ -190,11 +310,15 @@ function resetForm() { // 加载数据 function loadData() { + console.log('[OdfPortForm] loadData merged form:') if (props.id) { getOdfPorts(props.id).then((res) => { const { code, data } = res if (code == 200) { - form.value = { ...data } + // 合并后端数据,保留本地不提交字段 + form.value = { ...form.value, ...data } + console.log('[OdfPortForm] loadData merged form:', { form: { ...form.value } }) + parseRemarksToFields() } }) } else { @@ -208,8 +332,15 @@ function submitForm() { if (valid) { submitLoading.value = true + // 提交时排除不需要提交的本地字段 + const payload = { ...form.value } + delete payload.businessName + delete payload.port1 + delete payload.port2 + delete payload.port3 + if (isEdit.value) { - updateOdfPorts(form.value) + updateOdfPorts(payload) .then((res) => { proxy.$modal.msgSuccess('修改成功') handleSuccess() @@ -218,7 +349,7 @@ function submitForm() { submitLoading.value = false }) } else { - addOdfPorts(form.value) + addOdfPorts(payload) .then((res) => { proxy.$modal.msgSuccess('新增成功') handleSuccess() @@ -243,6 +374,21 @@ function handleClose() { resetForm() } +// 添加故障记录 +function addFaultRecord() { + form.value.historyFault.push({ + faultTime: null, + faultReason: null + }) +} + +// 删除故障记录 +function removeFaultRecord(index) { + if (form.value.historyFault.length > 0) { + form.value.historyFault.splice(index, 1) + } +} + // 监听对话框显示状态 watch( () => props.visible, @@ -252,4 +398,164 @@ watch( } } ) + +// 根据选择与输入自动拼接备注 +function getDictLabel(list, value) { + if (!Array.isArray(list)) return '' + const hit = list.find((x) => String(x.dictValue) === String(value)) + return hit ? hit.dictLabel : '' +} + +function updateRemarks() { + const equipmentLabel = getDictLabel(options.odf_ports_unit_type, form.value.equipmentModel) + const businessTypeLabel = getDictLabel(options.odf_ports_business_type, form.value.businessType) + const businessName = (form.value.businessName || '').trim() + const p1 = (form.value.port1 || '').trim() + const p2 = (form.value.port2 || '').trim() + const p3 = (form.value.port3 || '').trim() + const ports = [p1, p2, p3].filter((x) => x).join('/') + const parts = [businessName, equipmentLabel, businessTypeLabel, ports].filter((x) => x) + console.debug('[OdfPortForm] updateRemarks inputs:', { + businessName, + equipmentModel: form.value.equipmentModel, + equipmentLabel, + businessType: form.value.businessType, + businessTypeLabel, + p1, + p2, + p3, + ports, + parts + }) + form.value.remarks = parts.join(' ') + console.debug('[OdfPortForm] updateRemarks result:', form.value.remarks) +} + +// 监听字段变化,自动更新备注 +watch( + () => [form.value.equipmentModel, form.value.businessType, form.value.businessName, form.value.port1, form.value.port2, form.value.port3], + () => updateRemarks() +) + +// ----- 编辑态:解析备注并回填字段 ----- +const parsedFromRemarks = ref(false) + +function areOptionsReady() { + return ( + Array.isArray(options.odf_ports_unit_type) && + options.odf_ports_unit_type.length > 0 && + Array.isArray(options.odf_ports_business_type) && + options.odf_ports_business_type.length > 0 + ) +} + +function getDictValueByLabel(list, label) { + if (!Array.isArray(list)) return null + const hit = list.find((x) => String(x.dictLabel) === String(label)) + return hit ? hit.dictValue : null +} + +function parseRemarksToFields() { + const raw = form.value.remarks || '' + if (!raw) return + // 统一换行/空白为单个空格,并剔除前缀 + let remarks = raw + .replace(/[\r\n\t]+/g, ' ') + .replace(/\s+/g, ' ') + .trim() + if (!remarks) return + remarks = remarks.replace(/^端口备注信息\s*/, '') + console.debug('[OdfPortForm] parse start:', { raw, normalized: remarks }) + + // 提取端口部分(最后一个空格后的内容) + const lastSpaceIdx = remarks.lastIndexOf(' ') + if (lastSpaceIdx === -1) return + const beforePorts = remarks.substring(0, lastSpaceIdx).trim() + const portsStr = remarks.substring(lastSpaceIdx + 1).trim() + console.debug('[OdfPortForm] parse split:', { beforePorts, portsStr }) + + const [p1, p2, p3] = portsStr.split('/') + form.value.port1 = p1 || '' + form.value.port2 = p2 || '' + form.value.port3 = p3 || '' + + // 分割剩余部分:业务名称 [设备型号] [业务类型] + const tokens = beforePorts.split(' ').filter((x) => x) + if (tokens.length >= 2) { + const equipmentLabel = tokens[tokens.length - 2] || '' + const businessTypeLabel = tokens[tokens.length - 1] || '' + const nameTokens = tokens.slice(0, Math.max(0, tokens.length - 2)) + let businessName = nameTokens.join(' ').trim() + form.value.businessName = businessName + + const equipmentValue = getDictValueByLabel(options.odf_ports_unit_type, equipmentLabel) + const businessTypeValue = getDictValueByLabel(options.odf_ports_business_type, businessTypeLabel) + form.value.equipmentModel = equipmentValue + form.value.businessType = businessTypeValue + console.debug('[OdfPortForm] parse mapped:', { + equipmentLabel, + businessTypeLabel, + businessName, + p1: form.value.port1, + p2: form.value.port2, + p3: form.value.port3, + equipmentValue, + businessTypeValue + }) + } +} + +function tryParseRemarks() { + if (parsedFromRemarks.value) return + if (!props.id) return + if (!form.value.remarks) return + if (!areOptionsReady()) return + console.debug('[OdfPortForm] tryParseRemarks conditions ok, start parse') + parseRemarksToFields() + parsedFromRemarks.value = true + console.debug('[OdfPortForm] tryParseRemarks done. parsedFromRemarks=', parsedFromRemarks.value) +} + +// 当字典或备注变更时尝试解析一次 +watch( + () => [options.odf_ports_unit_type.length, options.odf_ports_business_type.length, form.value.remarks, props.visible], + () => { + if (props.visible) tryParseRemarks() + } +) + + diff --git a/src/components/business/OdfRoomExpertForm.vue b/src/components/business/OdfRoomExpertForm.vue index b37dde6..80e1be1 100644 --- a/src/components/business/OdfRoomExpertForm.vue +++ b/src/components/business/OdfRoomExpertForm.vue @@ -38,7 +38,11 @@ - + + + + + @@ -173,7 +177,8 @@ const form = ref({ framesCount: 9, rowCount: 6, portsCount: 12, - defaultStatus: 0 + defaultStatus: 0, + orderby: 0 }) // 表单验证规则 diff --git a/src/utils/request.js b/src/utils/request.js index 065b0f4..ed5e822 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -15,7 +15,7 @@ const service = axios.create({ // axios中请求配置有baseURL选项,表示请求URL公共部分 baseURL: import.meta.env.VITE_APP_BASE_API, // 超时 - timeout: 30000 + timeout: 300000 }) // request拦截器 diff --git a/src/views/business/OdfAppUpdates.vue b/src/views/business/OdfAppUpdates.vue new file mode 100644 index 0000000..ef75ef3 --- /dev/null +++ b/src/views/business/OdfAppUpdates.vue @@ -0,0 +1,335 @@ + + + + diff --git a/src/views/business/OdfIndex.vue b/src/views/business/OdfIndex.vue index 2833ac7..af50de3 100644 --- a/src/views/business/OdfIndex.vue +++ b/src/views/business/OdfIndex.vue @@ -188,6 +188,20 @@ align="center" :show-overflow-tooltip="true" v-if="columns.showColumn('opticalCableOffRemarks')" /> + +