From b6fed6892aefe22333a927ea80775fbe6194cd1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Fri, 28 Aug 2026 16:00:53 +0800 Subject: [PATCH] =?UTF-8?q?feat(organization):=20=E5=85=A8=E7=AB=99?= =?UTF-8?q?=E6=89=80=E5=B1=9E=E7=BB=84=E7=BB=87=E6=90=9C=E7=B4=A2=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E4=B8=BA=E6=A0=91=E5=BD=A2=E4=B8=8B=E6=8B=89=E5=B9=B6?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=A1=B9=E7=9B=AE=E9=83=A8=E9=97=A8=E5=AE=BD?= =?UTF-8?q?=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增复用 mixin organization-search.js,封装树形组织搜索功能,自动识别不同架构 - 替换合同管理、运输能力(司机/车辆/船舶)、费用模块的所属组织搜索使用树形下拉组件 - 将自定义搜索表单中所属组织 input 替换为 el-tree-select,支持树节点选中并写回名称 - 防止不同页面间组织数据相互覆盖,mixin 内部树数据命名为 organizationTreeOptions - 修复项目补录页面业务部门错用全宽样式,恢复半宽显示,调整注释避免误读 - 各相关页面组件中引入并使用 mixin,调用接口加载组织树数据,保障搜索功能一致性 --- .workbuddy/memory/2026-08-28.md | 15 +++++++++++++++ src/views/business/project-apply.vue | 6 +++--- .../components/bill-payment-search.vue | 19 ++++++++++++++++++- src/views/payment/invoice-application.vue | 17 ++++++++++++++++- src/views/payment/invoice-receipt.vue | 17 ++++++++++++++++- src/views/payment/payment-application.vue | 16 +++++++++++++++- src/views/transportCapacity/driver.vue | 3 +++ src/views/transportCapacity/ship.vue | 3 +++ 8 files changed, 89 insertions(+), 7 deletions(-) diff --git a/.workbuddy/memory/2026-08-28.md b/.workbuddy/memory/2026-08-28.md index ce01358..017fcab 100644 --- a/.workbuddy/memory/2026-08-28.md +++ b/.workbuddy/memory/2026-08-28.md @@ -43,3 +43,18 @@ - 验证:`vite build --outDir /tmp/tms-verify-build` 全量编译通过(exit 0,无报错)。注意原 `pnpm build` 因 WorkBuddy safe-delete 钩子拦截清空 dist/(741 文件)而中断,非代码问题。 - 注意:登录页 `activeName` 默认 `'iam'`(IAM 统一登录),图形验证码在 `userlogin.vue`,需点「账号密码登录」才可见;验证码图片依赖后端 `/blade-auth/oauth/captcha` 返回的 `data.key` + `data.image`。 +## 全站「所属组织」搜索统一为树形下拉(el-tree-select) +- 背景:合同管理页「所属组织」原为 cascader(radio 风格),客户档案页(vehicle/customer-archive)已用树形下拉。主人要求全站统一为树形。 +- 统一方案:新建可复用 mixin `src/mixins/organization-search.js`(封装 organizationTreeOptions 树数据、loadOrganizationOptions()、renderOrganizationSearch(scope) 渲染函数,自动识别 organizationName / deptName 两种 prop 并挂 column.renderSearch;树节点 node-key='id')。 +- 适用两种架构: + 1. **avue-crud 搜索**(renderSearch 模式):option 列加 `searchslot:true`,视图混入 mixin + created/初始化调 loadOrganizationOptions。已改:contract-manage(option 去 cascader 改 searchslot,视图用 renderOrganizationSearch 渲染函数)、transportCapacity 的 driver/vehicle/ship 三页(option 去 type:select 改 searchslot,视图混 mixin)。 + 2. **自定义搜索表单**(query.deptName 文本框模式):替换 `` 为 ``,node-key='id',@update:model-value 用 findOrgById(val)?.rawLabel 把 id 转回部门名写入 query.deptName(保后端按名称过滤兼容)。已改 payment 模块 4 处:invoice-application / invoice-receipt / payment-application / components/bill-payment-search。 +- 关键坑:mixin 内部树数据命名为 `organizationTreeOptions`(非 organizationOptions),与 transportCapacity 等页面表单自用的扁平 `organizationOptions` 隔离,避免相互覆盖破坏表单 select。 +- 待办(同自定义表单模式,未改):settlement 模块 4 个视图(transport-reconciliation/formal-settlement/pre-settlement/settlement-adjustment,搜索用动态 v-for 渲染 searchFields,需给 deptName 加 `type:'tree'` 分支)、system/user.vue(deptName)。business 模块(waybill-manage/transport-plan 等)所属组织为 `hide:true` 不展示搜索,无需改。 + +## project-apply 业务部门栏占满宽度修复 +- 文件:`src/views/business/project-apply.vue` +- 问题:「重大项目补录」(独立表单页 /business/project-apply/form?mode=majorSupplement)下"业务部门"项横跨整行,与上下两行半宽风格不一致。 +- 根因:`` 误加 `class="project-apply-form__item--full"`(该类对应样式 `:deep(.project-apply-form__item--full) { grid-column: 1 / -1; ... }` 是横跨整行的:本意只用于"项目由来说明"等多行文本字段)。 +- 修复:移除该 class,业务部门恢复为半宽(一行两列网格的常规项),仅"项目由来说明"等需要全宽铺开的字段仍保留 full。同时把样式块上方注释由「占满整行的表单项(业务部门 / 项目由来说明)」改为「占满整行的表单项(如项目由来说明等多行文本字段)」,避免再误读。 + diff --git a/src/views/business/project-apply.vue b/src/views/business/project-apply.vue index 3ddf88c..d8ef3ee 100644 --- a/src/views/business/project-apply.vue +++ b/src/views/business/project-apply.vue @@ -165,7 +165,7 @@ :disabled="isBasicInfoReadonly" /> - + - + @@ -2190,7 +2190,7 @@ export default { white-space: normal; } - // 占满整行的表单项(业务部门 / 项目由来说明) + // 占满整行的表单项(如项目由来说明等多行文本字段) :deep(.project-apply-form__item--full) { grid-column: 1 / -1; diff --git a/src/views/payment/components/bill-payment-search.vue b/src/views/payment/components/bill-payment-search.vue index a207150..1d855ca 100644 --- a/src/views/payment/components/bill-payment-search.vue +++ b/src/views/payment/components/bill-payment-search.vue @@ -6,7 +6,19 @@ - + import { ArrowDown, ArrowUp } from '@element-plus/icons-vue'; import { approvalStatusOptions } from '@/api/payment/billPayment'; +import organizationSearch from '@/mixins/organization-search'; export default { name: 'BillPaymentSearch', + mixins: [organizationSearch], props: { query: { type: Object, required: true }, loading: { type: Boolean, default: false }, @@ -58,6 +72,9 @@ export default { data() { return { ArrowDown, ArrowUp, expanded: false, approvalStatusOptions }; }, + mounted() { + this.loadOrganizationOptions(); + }, }; diff --git a/src/views/payment/invoice-application.vue b/src/views/payment/invoice-application.vue index 58624f6..f9d8115 100644 --- a/src/views/payment/invoice-application.vue +++ b/src/views/payment/invoice-application.vue @@ -10,7 +10,19 @@ - + @@ -234,6 +246,7 @@ import * as XLSX from 'xlsx'; import * as api from '@/api/payment/invoiceApplication'; import * as formalSettlementApi from '@/api/settlement/formalSettlement'; import { invoiceApplicationTableColumns } from '@/option/payment/invoiceApplication'; +import organizationSearch from '@/mixins/organization-search'; const emptyQuery = () => ({ applicationNo: '', @@ -245,6 +258,7 @@ const emptyQuery = () => ({ export default { name: 'InvoiceApplication', + mixins: [organizationSearch], data() { return { ArrowDown, @@ -266,6 +280,7 @@ export default { ...mapGetters(['permission']), }, mounted() { + this.loadOrganizationOptions(); this.loadTable(); }, methods: { diff --git a/src/views/payment/invoice-receipt.vue b/src/views/payment/invoice-receipt.vue index 59a9ada..3f4f4b3 100644 --- a/src/views/payment/invoice-receipt.vue +++ b/src/views/payment/invoice-receipt.vue @@ -19,7 +19,19 @@ - + @@ -226,6 +238,7 @@ import { mapGetters } from 'vuex'; import * as XLSX from 'xlsx'; import * as api from '@/api/payment/invoiceReceipt'; import { invoiceReceiptTableColumns } from '@/option/payment/invoiceReceipt'; +import organizationSearch from '@/mixins/organization-search'; const emptyQuery = () => ({ invoiceNo: '', @@ -238,6 +251,7 @@ const emptyQuery = () => ({ export default { name: 'InvoiceReceipt', + mixins: [organizationSearch], data() { return { ArrowDown, @@ -259,6 +273,7 @@ export default { ...mapGetters(['permission']), }, mounted() { + this.loadOrganizationOptions(); this.loadTable(); }, methods: { diff --git a/src/views/payment/payment-application.vue b/src/views/payment/payment-application.vue index 02eb4b3..d53e918 100644 --- a/src/views/payment/payment-application.vue +++ b/src/views/payment/payment-application.vue @@ -23,7 +23,18 @@ />