diff --git a/ruoyi-ui/src/api/ccdiAssetInfo.js b/ruoyi-ui/src/api/ccdiAssetInfo.js index 60a9470..84e4613 100644 --- a/ruoyi-ui/src/api/ccdiAssetInfo.js +++ b/ruoyi-ui/src/api/ccdiAssetInfo.js @@ -1,6 +1,6 @@ import request from '@/utils/request' -// 下载员工资产导入模板 +// 下载资产导入模板 export function importAssetTemplate() { return request({ url: '/ccdi/assetInfo/importTemplate', @@ -8,7 +8,7 @@ export function importAssetTemplate() { }) } -// 导入员工资产 +// 导入资产数据 export function importAssetData(data) { return request({ url: '/ccdi/assetInfo/importData', @@ -17,7 +17,7 @@ export function importAssetData(data) { }) } -// 查询员工资产导入状态 +// 查询资产导入状态 export function getAssetImportStatus(taskId) { return request({ url: '/ccdi/assetInfo/importStatus/' + taskId, @@ -25,7 +25,7 @@ export function getAssetImportStatus(taskId) { }) } -// 查询员工资产导入失败记录 +// 查询资产导入失败记录 export function getAssetImportFailures(taskId, pageNum, pageSize) { return request({ url: '/ccdi/assetInfo/importFailures/' + taskId, diff --git a/ruoyi-ui/src/views/ccdiStaffFmyRelation/index.vue b/ruoyi-ui/src/views/ccdiStaffFmyRelation/index.vue index 45d34f5..016edec 100644 --- a/ruoyi-ui/src/views/ccdiStaffFmyRelation/index.vue +++ b/ruoyi-ui/src/views/ccdiStaffFmyRelation/index.vue @@ -62,6 +62,16 @@ v-hasPermi="['ccdi:staffFmyRelation:import']" >导入 + + 导入亲属资产信息 + 查看导入失败记录 + + + 查看亲属资产导入失败记录 + + @@ -153,7 +177,7 @@ /> - + 基本信息 @@ -218,7 +242,7 @@ - + - + @@ -319,6 +343,98 @@ +
+ 亲属资产信息 + + + 新增资产 + + +
+ +
+ + 暂无亲属资产信息,请点击新增资产 +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
@@ -330,7 +446,7 @@
- +
基本信息 @@ -366,6 +482,31 @@ {{ relationDetail.remark || '-' }} + 亲属资产信息 +
+ 暂无亲属资产信息 +
+ + + + + + + + + + + + + + + + + 审计信息 @@ -418,6 +559,44 @@
+ + + +
将文件拖到此处,或点击上传
+
+ 下载亲属资产模板 +
+
+ 仅允许导入"xls"或"xlsx"格式文件,系统将根据关系人证件号自动识别归属员工。 +
+
+ +
+ 清除历史记录 + + + + + + + + + + + + + + + + + + @@ -466,6 +683,10 @@ import { listRelation, updateRelation } from "@/api/ccdiStaffFmyRelation"; +import { + getAssetImportFailures, + getAssetImportStatus +} from "@/api/ccdiAssetInfo"; import {listBaseStaff} from "@/api/ccdiBaseStaff"; import {getToken} from "@/utils/auth"; import EnumTag from '@/components/EnumTag' @@ -516,6 +737,12 @@ export default { }, // 表单参数 form: {}, + assetStatusOptions: [ + { label: "正常", value: "正常" }, + { label: "冻结", value: "冻结" }, + { label: "处置中", value: "处置中" }, + { label: "报废", value: "报废" } + ], // 表单校验 rules: { personId: [ @@ -569,6 +796,24 @@ export default { pageNum: 1, pageSize: 10 }, + assetUpload: { + open: false, + title: "", + isUploading: false, + headers: { Authorization: "Bearer " + getToken() }, + url: process.env.VUE_APP_BASE_API + "/ccdi/assetInfo/importData" + }, + assetImportPollingTimer: null, + assetShowFailureButton: false, + assetCurrentTaskId: null, + assetFailureDialogVisible: false, + assetFailureList: [], + assetFailureLoading: false, + assetFailureTotal: 0, + assetFailureQueryParams: { + pageNum: 1, + pageSize: 10 + }, // 员工选项 staffOptions: [], staffLoading: false @@ -584,11 +829,22 @@ export default { return `导入时间: ${this.parseTime(savedTask.saveTime)} | 总数: ${savedTask.totalCount}条 | 成功: ${savedTask.successCount}条 | 失败: ${savedTask.failureCount}条`; } return ''; + }, + lastAssetImportInfo() { + const savedTask = this.getAssetImportTaskFromStorage(); + if (savedTask && savedTask.totalCount) { + return `导入时间: ${this.parseTime(savedTask.saveTime)} | 总数: ${savedTask.totalCount}条 | 成功: ${savedTask.successCount}条 | 失败: ${savedTask.failureCount}条`; + } + return ''; + }, + canAddAsset() { + return Boolean(this.form.relationCertType && String(this.form.relationCertNo || '').trim()) } }, created() { this.getList(); this.restoreImportState(); + this.restoreAssetImportState(); this.loadEnumOptions(); }, beforeDestroy() { @@ -596,6 +852,10 @@ export default { clearInterval(this.importPollingTimer); this.importPollingTimer = null; } + if (this.assetImportPollingTimer) { + clearInterval(this.assetImportPollingTimer); + this.assetImportPollingTimer = null; + } }, methods: { /** @@ -652,6 +912,18 @@ export default { this.showFailureButton = true; } }, + restoreAssetImportState() { + const savedTask = this.getAssetImportTaskFromStorage(); + if (!savedTask) { + this.assetShowFailureButton = false; + this.assetCurrentTaskId = null; + return; + } + if (savedTask.hasFailures && savedTask.taskId) { + this.assetCurrentTaskId = savedTask.taskId; + this.assetShowFailureButton = true; + } + }, /** * 获取上次导入的提示信息 */ @@ -664,6 +936,15 @@ export default { } return ''; }, + getLastAssetImportTooltip() { + const savedTask = this.getAssetImportTaskFromStorage(); + if (savedTask && savedTask.saveTime) { + const date = new Date(savedTask.saveTime); + const timeStr = this.parseTime(date, '{y}-{m}-{d} {h}:{i}'); + return `上次亲属资产导入: ${timeStr}`; + } + return ''; + }, // 取消按钮 cancel() { this.open = false; @@ -690,11 +971,101 @@ export default { effectiveDate: null, invalidDate: null, status: 1, - remark: null + remark: null, + assetInfoList: [] }; this.staffOptions = []; this.resetForm("form"); }, + createEmptyAssetRow() { + return { + assetMainType: "", + assetSubType: "", + assetName: "", + ownershipRatio: "", + purchaseEvalDate: "", + originalValue: "", + currentValue: "", + valuationDate: "", + assetStatus: "", + remarks: "" + }; + }, + hasAssetContent(row) { + if (!row || typeof row !== "object") { + return false; + } + return Object.keys(row).some(key => { + const value = row[key]; + return value !== null && value !== undefined && String(value).trim() !== ""; + }); + }, + normalizeAssetInfoList() { + const assetInfoList = Array.isArray(this.form.assetInfoList) + ? this.form.assetInfoList + : []; + return assetInfoList.filter(item => this.hasAssetContent(item)); + }, + validateAssetInfoList(assetInfoList) { + const requiredFields = [ + { key: "assetMainType", label: "资产大类" }, + { key: "assetSubType", label: "资产小类" }, + { key: "assetName", label: "资产名称" }, + { key: "currentValue", label: "当前估值" }, + { key: "assetStatus", label: "资产状态" } + ]; + const numericFields = [ + { key: "ownershipRatio", label: "产权占比" }, + { key: "originalValue", label: "资产原值" }, + { key: "currentValue", label: "当前估值" } + ]; + + for (let index = 0; index < assetInfoList.length; index++) { + const asset = assetInfoList[index]; + const rowNo = index + 1; + + for (const field of requiredFields) { + const value = asset[field.key]; + if (value === null || value === undefined || String(value).trim() === "") { + this.$modal.msgError(`第${rowNo}条资产的${field.label}不能为空`); + return false; + } + } + + for (const field of numericFields) { + const value = asset[field.key]; + if (value !== null && value !== undefined && String(value).trim() !== "") { + if (!/^-?\d+(\.\d+)?$/.test(String(value).trim())) { + this.$modal.msgError(`第${rowNo}条资产的${field.label}格式不正确`); + return false; + } + } + } + + if (!this.assetStatusOptions.some(option => option.value === asset.assetStatus)) { + this.$modal.msgError(`第${rowNo}条资产的资产状态不在允许范围内`); + return false; + } + } + + return true; + }, + handleAddAsset() { + if (!this.canAddAsset) { + this.$modal.msgWarning("请先填写关系人证件信息"); + return; + } + if (!Array.isArray(this.form.assetInfoList)) { + this.form.assetInfoList = []; + } + this.form.assetInfoList.push(this.createEmptyAssetRow()); + }, + handleRemoveAsset(index) { + if (!Array.isArray(this.form.assetInfoList)) { + return; + } + this.form.assetInfoList.splice(index, 1); + }, /** 搜索按钮操作 */ handleQuery() { this.queryParams.pageNum = 1; @@ -723,7 +1094,10 @@ export default { this.reset(); const id = row.id || this.ids[0]; getRelation(id).then(response => { - this.form = response.data; + this.form = { + ...response.data, + assetInfoList: response.data.assetInfoList || [] + }; // 加载员工信息以支持下拉显示 if (this.form.personId) { this.searchStaff(this.form.personId); @@ -737,7 +1111,10 @@ export default { handleDetail(row) { const id = row.id; getRelation(id).then(response => { - this.relationDetail = response.data; + this.relationDetail = { + ...response.data, + assetInfoList: response.data.assetInfoList || [] + }; this.detailOpen = true; }); }, @@ -745,14 +1122,30 @@ export default { submitForm() { this.$refs["form"].validate(valid => { if (valid) { + this.form.assetInfoList = this.normalizeAssetInfoList(); + if (!this.validateAssetInfoList(this.form.assetInfoList)) { + return; + } + + const payload = { + ...this.form, + assetInfoList: this.form.assetInfoList.map(item => ({ ...item })) + }; + payload.assetInfoList.forEach((asset, index) => { + delete payload.assetInfoList[index].familyId; + delete payload.assetInfoList[index].personId; + delete asset.familyId; + delete asset.personId; + }); + if (this.isAdd) { - addRelation(this.form).then(response => { + addRelation(payload).then(response => { this.$modal.msgSuccess("新增成功"); this.open = false; this.getList(); }); } else { - updateRelation(this.form).then(response => { + updateRelation(payload).then(response => { this.$modal.msgSuccess("修改成功"); this.open = false; this.getList(); @@ -782,14 +1175,24 @@ export default { this.upload.title = "员工亲属关系数据导入"; this.upload.open = true; }, + handleAssetImport() { + this.assetUpload.title = "亲属资产数据导入"; + this.assetUpload.open = true; + }, /** 下载模板操作 */ importTemplate() { this.download('ccdi/staffFmyRelation/importTemplate', {}, `员工亲属关系导入模板_${new Date().getTime()}.xlsx`); }, + importAssetTemplate() { + this.download('ccdi/assetInfo/importTemplate', {}, `亲属资产信息模板_${new Date().getTime()}.xlsx`); + }, // 文件上传中处理 handleFileUploadProgress(event, file, fileList) { this.upload.isUploading = true; }, + handleAssetFileUploadProgress() { + this.assetUpload.isUploading = true; + }, // 文件上传成功处理 handleFileSuccess(response, file, fileList) { this.upload.isUploading = false; @@ -834,6 +1237,49 @@ export default { this.$modal.msgError(response.msg); } }, + handleAssetFileSuccess(response) { + this.assetUpload.isUploading = false; + this.assetUpload.open = false; + + if (response.code === 200) { + if (!response.data || !response.data.taskId) { + this.$modal.msgError('亲属资产导入任务创建失败:缺少任务ID'); + this.assetUpload.isUploading = false; + this.assetUpload.open = true; + return; + } + + const taskId = response.data.taskId; + + if (this.assetImportPollingTimer) { + clearInterval(this.assetImportPollingTimer); + this.assetImportPollingTimer = null; + } + + this.clearAssetImportTaskFromStorage(); + + this.saveAssetImportTaskToStorage({ + taskId: taskId, + status: 'PROCESSING', + timestamp: Date.now(), + hasFailures: false + }); + + this.assetShowFailureButton = false; + this.assetCurrentTaskId = taskId; + + this.$notify({ + title: '亲属资产导入任务已提交', + message: '正在后台处理中,处理完成后将通知您', + type: 'info', + duration: 3000 + }); + + this.startAssetImportStatusPolling(taskId); + } else { + this.$modal.msgError(response.msg); + } + }, /** 开始轮询导入状态 */ startImportStatusPolling(taskId) { let pollCount = 0; @@ -861,6 +1307,32 @@ export default { } }, 2000); }, + startAssetImportStatusPolling(taskId) { + let pollCount = 0; + const maxPolls = 150; + + this.assetImportPollingTimer = setInterval(async () => { + try { + pollCount++; + + if (pollCount > maxPolls) { + clearInterval(this.assetImportPollingTimer); + this.$modal.msgWarning('亲属资产导入任务处理超时,请联系管理员'); + return; + } + + const response = await getAssetImportStatus(taskId); + + if (response.data && response.data.status !== 'PROCESSING') { + clearInterval(this.assetImportPollingTimer); + this.handleAssetImportComplete(response.data); + } + } catch (error) { + clearInterval(this.assetImportPollingTimer); + this.$modal.msgError('查询亲属资产导入状态失败: ' + error.message); + } + }, 2000); + }, /** 查询失败记录列表 */ getFailureList() { this.failureLoading = true; @@ -885,11 +1357,42 @@ export default { } }); }, + getAssetFailureList() { + this.assetFailureLoading = true; + getAssetImportFailures( + this.assetCurrentTaskId, + this.assetFailureQueryParams.pageNum, + this.assetFailureQueryParams.pageSize + ).then(response => { + this.assetFailureList = response.rows; + this.assetFailureTotal = response.total; + this.assetFailureLoading = false; + }).catch(error => { + this.assetFailureLoading = false; + if (error.response && error.response.status === 404) { + this.$modal.msgWarning('亲属资产导入记录已过期,无法查看失败记录'); + this.clearAssetImportTaskFromStorage(); + this.assetShowFailureButton = false; + this.assetCurrentTaskId = null; + this.assetFailureDialogVisible = false; + } else if (error.response && error.response.status === 500) { + this.$modal.msgError('服务器错误,请稍后重试'); + } else if (error.request) { + this.$modal.msgError('网络连接失败,请检查网络'); + } else { + this.$modal.msgError('查询亲属资产失败记录失败'); + } + }); + }, /** 查看导入失败记录 */ viewImportFailures() { this.failureDialogVisible = true; this.getFailureList(); }, + viewAssetImportFailures() { + this.assetFailureDialogVisible = true; + this.getAssetFailureList(); + }, /** 处理导入完成 */ handleImportComplete(statusResult) { this.saveImportTaskToStorage({ @@ -922,14 +1425,60 @@ export default { this.getList(); } }, + handleAssetImportComplete(statusResult) { + this.saveAssetImportTaskToStorage({ + taskId: statusResult.taskId, + status: statusResult.status, + hasFailures: statusResult.failureCount > 0, + totalCount: statusResult.totalCount, + successCount: statusResult.successCount, + failureCount: statusResult.failureCount + }); + + if (statusResult.status === 'SUCCESS') { + this.$notify({ + title: '亲属资产导入完成', + message: `全部成功!共导入${statusResult.totalCount}条数据`, + type: 'success', + duration: 5000 + }); + this.assetShowFailureButton = false; + this.getList(); + } else if (statusResult.failureCount > 0) { + this.$notify({ + title: '亲属资产导入完成', + message: `成功${statusResult.successCount}条,失败${statusResult.failureCount}条`, + type: 'warning', + duration: 5000 + }); + this.assetShowFailureButton = true; + this.assetCurrentTaskId = statusResult.taskId; + this.getList(); + } + }, // 提交上传文件 submitFileForm() { this.$refs.upload.submit(); }, + submitAssetFileForm() { + this.$refs.assetUpload.submit(); + }, // 关闭导入对话框 handleImportDialogClose() { this.upload.isUploading = false; - this.$refs.upload.clearFiles(); + this.$nextTick(() => { + if (this.$refs.upload) { + this.$refs.upload.clearFiles(); + } + }); + }, + handleAssetImportDialogClose() { + this.assetUpload.isUploading = false; + this.$nextTick(() => { + if (this.$refs.assetUpload) { + this.$refs.assetUpload.clearFiles(); + } + }); }, /** * 保存导入任务到localStorage @@ -945,6 +1494,17 @@ export default { console.error('保存导入任务状态失败:', error); } }, + saveAssetImportTaskToStorage(taskData) { + try { + const data = { + ...taskData, + saveTime: Date.now() + }; + localStorage.setItem('staff_fmy_asset_import_last_task', JSON.stringify(data)); + } catch (error) { + console.error('保存亲属资产导入任务状态失败:', error); + } + }, /** * 从localStorage读取导入任务 */ @@ -972,6 +1532,30 @@ export default { return null; } }, + getAssetImportTaskFromStorage() { + try { + const data = localStorage.getItem('staff_fmy_asset_import_last_task'); + if (!data) return null; + + const task = JSON.parse(data); + if (!task || !task.taskId) { + this.clearAssetImportTaskFromStorage(); + return null; + } + + const sevenDays = 7 * 24 * 60 * 60 * 1000; + if (Date.now() - task.saveTime > sevenDays) { + this.clearAssetImportTaskFromStorage(); + return null; + } + + return task; + } catch (error) { + console.error('读取亲属资产导入任务状态失败:', error); + this.clearAssetImportTaskFromStorage(); + return null; + } + }, /** * 清除导入历史记录 */ @@ -988,6 +1572,19 @@ export default { this.$message.success('已清除'); }).catch(() => {}); }, + clearAssetImportHistory() { + this.$confirm('确认清除上次亲属资产导入记录?', '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }).then(() => { + this.clearAssetImportTaskFromStorage(); + this.assetShowFailureButton = false; + this.assetCurrentTaskId = null; + this.assetFailureDialogVisible = false; + this.$message.success('已清除'); + }).catch(() => {}); + }, /** * 清除localStorage中的导入任务 */ @@ -997,6 +1594,13 @@ export default { } catch (error) { console.error('清除导入任务状态失败:', error); } + }, + clearAssetImportTaskFromStorage() { + try { + localStorage.removeItem('staff_fmy_asset_import_last_task'); + } catch (error) { + console.error('清除亲属资产导入任务状态失败:', error); + } } } }; @@ -1006,4 +1610,65 @@ export default { .detail-container { padding: 0 20px; } + +.relation-detail-dialog .detail-assets-table { + margin-bottom: 16px; +} + +.relation-detail-dialog .empty-assets-detail { + padding: 32px 0; + margin-bottom: 16px; + text-align: center; + color: #909399; + background: #fff; + border-radius: 4px; + border: 1px dashed #dcdfe6; +} + +.asset-section-header { + display: flex; + align-items: center; + justify-content: space-between; + margin: 8px 0 12px; + padding-top: 8px; + border-top: 1px solid #ebeef5; + color: #303133; + font-size: 14px; + font-weight: 500; +} + +.assets-table-wrapper { + width: 100%; + overflow-x: auto; +} + +.assets-table { + min-width: 1440px; +} + +.assets-table .el-input, +.assets-table .el-date-editor, +.assets-table .el-select { + width: 100%; +} + +.empty-assets { + padding: 30px 0; + text-align: center; + color: #909399; + border: 1px dashed #dcdfe6; + border-radius: 4px; + background: #fafafa; +} + +.empty-assets i { + display: block; + margin-bottom: 8px; + font-size: 30px; + color: #c0c4cc; +} + +.empty-assets span { + font-size: 13px; +} diff --git a/ruoyi-ui/tests/unit/staff-family-asset-api-contract.test.js b/ruoyi-ui/tests/unit/staff-family-asset-api-contract.test.js new file mode 100644 index 0000000..a293f1e --- /dev/null +++ b/ruoyi-ui/tests/unit/staff-family-asset-api-contract.test.js @@ -0,0 +1,45 @@ +const assert = require("assert"); +const fs = require("fs"); +const path = require("path"); + +const relationApiPath = path.resolve( + __dirname, + "../../src/api/ccdiStaffFmyRelation.js" +); +const assetApiPath = path.resolve( + __dirname, + "../../src/api/ccdiAssetInfo.js" +); + +assert(fs.existsSync(relationApiPath), "未找到亲属关系 API 文件 ccdiStaffFmyRelation.js"); +assert(fs.existsSync(assetApiPath), "未找到资产 API 文件 ccdiAssetInfo.js"); + +const relationSource = fs.readFileSync(relationApiPath, "utf8"); +const assetSource = fs.readFileSync(assetApiPath, "utf8"); + +[ + "export function getRelation(id)", + "export function addRelation(data)", + "export function updateRelation(data)", + "data: data", +].forEach((token) => { + assert( + relationSource.includes(token), + `亲属关系 API 需保持聚合保存契约: ${token}` + ); +}); + +[ + "export function importAssetTemplate()", + "export function importAssetData(data)", + "export function getAssetImportStatus(taskId)", + "export function getAssetImportFailures(taskId, pageNum, pageSize)", + "/ccdi/assetInfo/importTemplate", + "/ccdi/assetInfo/importData", + "/ccdi/assetInfo/importStatus/", + "/ccdi/assetInfo/importFailures/", +].forEach((token) => { + assert(assetSource.includes(token), `亲属资产 API 缺少关键契约: ${token}`); +}); + +console.log("staff-family-asset-api-contract test passed"); diff --git a/ruoyi-ui/tests/unit/staff-family-asset-detail-import-ui.test.js b/ruoyi-ui/tests/unit/staff-family-asset-detail-import-ui.test.js new file mode 100644 index 0000000..3ce1986 --- /dev/null +++ b/ruoyi-ui/tests/unit/staff-family-asset-detail-import-ui.test.js @@ -0,0 +1,40 @@ +const assert = require("assert"); +const fs = require("fs"); +const path = require("path"); + +const componentPath = path.resolve( + __dirname, + "../../src/views/ccdiStaffFmyRelation/index.vue" +); +const source = fs.readFileSync(componentPath, "utf8"); + +[ + "导入亲属资产信息", + "查看亲属资产导入失败记录", + "assetUpload", + "assetImportPollingTimer", + "assetCurrentTaskId", + "assetFailureDialogVisible", + "staff_fmy_asset_import_last_task", + "亲属资产数据导入", + "亲属资产导入失败记录", + "viewAssetImportFailures()", + "handleAssetImport()", + "handleAssetFileSuccess(response)", + "startAssetImportStatusPolling(taskId)", + "getAssetFailureList()", + "clearAssetImportHistory()", +].forEach((token) => { + assert(source.includes(token), `亲属资产导入 UI 缺少关键结构或状态: ${token}`); +}); + +[ + ">亲属资产信息", + "暂无亲属资产信息", + "detail-assets-table", + ":disabled=\"!isAdd\"", +].forEach((token) => { + assert(source.includes(token), `详情展示或禁改逻辑缺少关键结构: ${token}`); +}); + +console.log("staff-family-asset-detail-import-ui test passed"); diff --git a/ruoyi-ui/tests/unit/staff-family-asset-maintenance-layout.test.js b/ruoyi-ui/tests/unit/staff-family-asset-maintenance-layout.test.js new file mode 100644 index 0000000..7bddbb8 --- /dev/null +++ b/ruoyi-ui/tests/unit/staff-family-asset-maintenance-layout.test.js @@ -0,0 +1,42 @@ +const assert = require("assert"); +const fs = require("fs"); +const path = require("path"); + +const componentPath = path.resolve( + __dirname, + "../../src/views/ccdiStaffFmyRelation/index.vue" +); +const source = fs.readFileSync(componentPath, "utf8"); + +[ + "亲属资产信息", + "新增资产", + "handleAddAsset()", + "handleRemoveAsset(index)", + "createEmptyAssetRow()", + "请先填写关系人证件信息", + "暂无亲属资产信息,请点击新增资产", + "prop=\"assetInfoList\"", + "v-model=\"scope.row.assetMainType\"", + "v-model=\"scope.row.assetSubType\"", + "v-model=\"scope.row.assetName\"", + "v-model=\"scope.row.assetStatus\"", + "v-model=\"scope.row.remarks\"", +].forEach((token) => { + assert( + source.includes(token), + `亲属资产维护弹窗缺少关键结构: ${token}` + ); +}); + +[ + "v-model=\"scope.row.familyId\"", + "v-model=\"scope.row.personId\"", +].forEach((token) => { + assert( + !source.includes(token), + `亲属资产维护弹窗不应暴露归属字段: ${token}` + ); +}); + +console.log("staff-family-asset-maintenance-layout test passed"); diff --git a/ruoyi-ui/tests/unit/staff-family-asset-submit-flow.test.js b/ruoyi-ui/tests/unit/staff-family-asset-submit-flow.test.js new file mode 100644 index 0000000..b045fee --- /dev/null +++ b/ruoyi-ui/tests/unit/staff-family-asset-submit-flow.test.js @@ -0,0 +1,38 @@ +const assert = require("assert"); +const fs = require("fs"); +const path = require("path"); + +const componentPath = path.resolve( + __dirname, + "../../src/views/ccdiStaffFmyRelation/index.vue" +); +const source = fs.readFileSync(componentPath, "utf8"); + +[ + "assetInfoList: []", + "normalizeAssetInfoList()", + "response.data.assetInfoList || []", + "this.form.assetInfoList = this.normalizeAssetInfoList();", + "this.form.assetInfoList.push(this.createEmptyAssetRow());", + "relationCertType: null", + "relationCertNo: null", +].forEach((token) => { + assert( + source.includes(token), + `亲属资产提交流程缺少关键处理: ${token}` + ); +}); + +[ + "delete payload.assetInfoList[index].familyId", + "delete payload.assetInfoList[index].personId", + "delete asset.familyId", + "delete asset.personId", +].forEach((token) => { + assert( + source.includes(token), + `提交前需要清理归属字段: ${token}` + ); +}); + +console.log("staff-family-asset-submit-flow test passed");