diff --git a/src/mixins/organization-search.js b/src/mixins/organization-search.js index 5842986..fd06b59 100644 --- a/src/mixins/organization-search.js +++ b/src/mixins/organization-search.js @@ -12,6 +12,8 @@ import { h } from 'vue'; * 1. 混入本 mixin:mixins: [organizationSearch] * 2. option 中「所属组织」列加上 searchslot: true(prop 为 organizationName 或 deptName 均可) * 3. 在 created / 初始化时调用 this.loadOrganizationOptions() + * 4. 需要「未分配组织」筛选项的页面在 data 里置 enableUnassignedOrgFilter: true; + * 该项只追加进搜索树 organizationSearchTreeOptions,表单级联 organizationTreeOptions 不含哨兵 * * 说明: * - 自动识别 organizationName / deptName 两种 prop,并挂载 column.renderSearch @@ -26,6 +28,12 @@ import { h } from 'vue'; */ const ORG_PROPS = ['organizationName', 'deptName']; +// 「未分配组织」筛选项的哨兵值:不是真实组织名,选中后提交给后端的就是这串字面量。 +// 后端 TransportBusiConstant.UNASSIGNED_ORG_FILTER、DriverMapper.xml / TransportVehicleMapper.xml +// 的 organizationName 分支以及司机、车辆导出查询都按它改判为 organization_name = ''; +// 后端换成空串会让整段组织条件不生效,筛选静默失效。前端与后端这几处必须同步修改。 +const UNASSIGNED_ORG_FILTER = '__UNASSIGNED_ORG__'; + export default { data() { return { @@ -34,9 +42,18 @@ export default { organizationTreeOptions: [], organizationTreeFlatOptions: [], organizationLoading: false, + // 组织筛选是否追加「未分配组织」一项;页面在 data 里覆盖为 true 才生效 + enableUnassignedOrgFilter: false, }; }, computed: { + // 搜索栏级联的选项:开关打开时在真实组织最前面追加「未分配组织」。 + // 不能直接改 organizationTreeOptions——司机/车辆页的编辑表单也用这棵树选组织。 + organizationSearchTreeOptions() { + return this.enableUnassignedOrgFilter + ? [this.unassignedOrgOption(), ...this.organizationTreeOptions] + : this.organizationTreeOptions; + }, // 所属组织级联配置:checkStrictly 允许选中任意层级,不必选到末级 organizationCascaderProps() { return { @@ -61,7 +78,7 @@ export default { ? this.excludeExternalOrganization(source) : source; this.organizationTreeOptions = this.normalizeOrgTree(tree); - this.organizationTreeFlatOptions = this.flattenOrgTree(this.organizationTreeOptions); + this.organizationTreeFlatOptions = this.flattenOrgTree(this.organizationSearchTreeOptions); const option = this.tableOption || this.option; if (!option) return; ORG_PROPS.forEach(prop => { @@ -100,12 +117,20 @@ export default { }; }); }, + // 哨兵节点的 id 与 rawLabel 都取哨兵值,resolveOrgName 取到的仍是哨兵而不是某个真实组织名 + unassignedOrgOption() { + return { id: UNASSIGNED_ORG_FILTER, label: '未分配组织', rawLabel: UNASSIGNED_ORG_FILTER }; + }, flattenOrgTree(tree = []) { return (tree || []).flatMap(item => [ { id: String(item.id), label: item.label, rawLabel: item.rawLabel }, ...this.flattenOrgTree(item.children || []), ]); }, + // 组织列渲染用:空串或纯空白即「未分配组织」(组织列 NOT NULL,无组织存空串) + isBlankOrganizationName(value) { + return String(value ?? '').trim() === ''; + }, // 兼容两种入参:级联路径数组(取末级)或单个部门 id findOrgById(id) { const value = Array.isArray(id) ? id.at(-1) : id; @@ -155,7 +180,7 @@ export default { // 级联单选:modelValue 必须是 id 路径数组,否则控件内部状态会错乱导致无法再次选中 if (scope.row) scope.row[prop] = Array.isArray(value) ? value : []; }, - options: this.organizationTreeOptions, + options: this.organizationSearchTreeOptions, props: { label: 'label', value: 'id', diff --git a/src/option/system/mpUser.js b/src/option/system/mpUser.js index bc06d41..7236a26 100644 --- a/src/option/system/mpUser.js +++ b/src/option/system/mpUser.js @@ -133,7 +133,7 @@ export default { hide: true, span: 24, order: 55, - rules: [{ required: true, message: '请选择所属组织', trigger: 'change' }], + // 所属组织可为空:为空表示未分配组织,账号的数据权限为空集 }, { label: '所属组织', diff --git a/src/views/business/components/punch-record-photos.vue b/src/views/business/components/punch-record-photos.vue index 455f7d1..2444cce 100644 --- a/src/views/business/components/punch-record-photos.vue +++ b/src/views/business/components/punch-record-photos.vue @@ -10,7 +10,7 @@ :class="{ 'punch-record-photos__grid--edit': editable }" >
- -
主图
} } - &__badge { - position: absolute; - top: 0; - left: 0; - padding: 0 6px; - border-radius: 4px 0 4px 0; - background: rgba(64, 158, 255, 0.9); - font-size: 12px; - line-height: 18px; - color: #fff; - } - &__remove { align-self: center; font-size: 12px; diff --git a/src/views/business/components/waybill-manage-page.vue b/src/views/business/components/waybill-manage-page.vue index 4715c05..421caed 100644 --- a/src/views/business/components/waybill-manage-page.vue +++ b/src/views/business/components/waybill-manage-page.vue @@ -2271,6 +2271,13 @@ 体积 {{ record.volume }}方 数量 {{ record.quantity }}
+ +
+ 里程 {{ record.mileage }} 公里 +
+ + + + + + + + 0 ? String(Number(record.mileage)) : '', remark: record.remark || '', photos: (record.photos || []) .filter(photo => photo?.url) @@ -6037,10 +6070,22 @@ export default { photos.splice(index, 1); this.waybillPunchEditForm.photos = photos; }, + // 里程只收整数:非数字直接丢掉,长度与「维护里程」一致(≤10 位) + handleWaybillPunchMileageInput(value) { + this.waybillPunchEditForm.mileage = String(value || '') + .replace(/\D/g, '') + .slice(0, 10); + }, async submitWaybillPunchRecordEdit() { await this.$refs.waybillPunchRecordEditFormRef.validate(); const record = this.waybillPunchEditRecord; const form = this.waybillPunchEditForm; + // 管理端里程选填:留空表示不改动运单里程,所以只校验填了值的情况 + const mileageText = String(form.mileage || '').trim(); + if (this.waybillPunchEditMileageVisible && mileageText && !/^[1-9]\d{0,9}$/.test(mileageText)) { + this.$message.warning('里程必须为不超过10位的正整数'); + return; + } const submit = typeof this.api?.savePunchRecord === 'function' ? this.api.savePunchRecord : savePunchRecord; this.waybillPunchRecordEditDialog.submitting = true; @@ -6059,6 +6104,8 @@ export default { weight: form.weight, volume: form.volume, quantity: form.quantity, + // 不传代表不改;后端按 null 处理 + mileage: mileageText ? Number(mileageText) : undefined, remark: form.remark, photos: form.photos.map(photo => ({ url: photo.url, type: photo.type })), }); diff --git a/src/views/business/process-config.vue b/src/views/business/process-config.vue index 4b3c136..d7ba2b1 100644 --- a/src/views/business/process-config.vue +++ b/src/views/business/process-config.vue @@ -245,7 +245,7 @@ 是 无需确认完成 @@ -253,10 +253,7 @@
确认完成 - 内部人员
@@ -549,15 +546,18 @@ export default { row.confirmDriver = row.confirmMode === 'yes'; this.syncNodeFields(); }, - handleReturnConfirmChange(row) { - row.confirmInternal = row.confirmMode === 'yes'; - this.syncNodeFields(); - }, enforceAcceptDriver(node) { if (!node || (node.key !== 'accept' && node.name !== '接单')) return node; node.confirmDriver = node.confirmMode === 'yes'; return node; }, + // 回单「确认完成」只有内部人员一种角色,是否确认为「是」时即由内部人员确认, + // 界面上只读展示,值始终由 confirmMode 推导 + enforceReturnInternal(node) { + if (!node || (node.key !== 'return' && node.name !== '回单')) return node; + node.confirmInternal = node.confirmMode === 'yes'; + return node; + }, initDeptOptions() { getDeptTree(this.userInfo.tenantId).then(res => { const deptColumn = this.findColumn(this.option.column, 'searchDeptId'); @@ -808,7 +808,10 @@ export default { this.syncNodeFields(); }, syncNodeFields() { - this.nodeRows.forEach(item => this.enforceAcceptDriver(item)); + this.nodeRows.forEach(item => { + this.enforceAcceptDriver(item); + this.enforceReturnInternal(item); + }); const enabledNodes = this.nodeRows.filter(item => item.enabled); this.form.includedNodes = enabledNodes.map(item => item.name).join(','); this.form.nodeConfigJson = JSON.stringify( diff --git a/src/views/system/mp-user.vue b/src/views/system/mp-user.vue index 072f3d8..bd3505f 100644 --- a/src/views/system/mp-user.vue +++ b/src/views/system/mp-user.vue @@ -315,11 +315,6 @@ export default { }, rowSave(row, done, loading) { const payload = this.normalizeSubmitRow(row, false); - if (!payload.deptId) { - this.$message.warning('请选择所属组织'); - loading(); - return; - } if (payload.dataScopeRange === 3 && (!payload.dataScopeDeptIds || !payload.dataScopeDeptIds.length)) { this.$message.warning('请选择自定义数据权限组织'); loading(); @@ -336,11 +331,6 @@ export default { }, rowUpdate(row, index, done, loading) { const payload = this.normalizeSubmitRow(row, true); - if (!payload.deptId) { - this.$message.warning('请选择所属组织'); - loading(); - return; - } if (payload.dataScopeRange === 3 && (!payload.dataScopeDeptIds || !payload.dataScopeDeptIds.length)) { this.$message.warning('请选择自定义数据权限组织'); loading(); diff --git a/src/views/transportCapacity/driver.vue b/src/views/transportCapacity/driver.vue index c4e771b..dbf7be1 100644 --- a/src/views/transportCapacity/driver.vue +++ b/src/views/transportCapacity/driver.vue @@ -60,7 +60,11 @@ {{ row.idCardNo || '-' }}