@@ -168,6 +178,7 @@ import {
invoiceStatusOptions,
paymentStatusOptions,
} from '@/option/settlement/formalSettlementSearch';
+import organizationSearch from '@/mixins/organization-search';
import { formalSettlementTableColumns } from '@/option/settlement/formalSettlementTable';
import FormalSettlementEditor from './components/formal-settlement-editor.vue';
import FormalSettlementTablePanel from './components/formal-settlement-table-panel.vue';
@@ -176,7 +187,7 @@ const emptyQuery = () => ({
formalSettlementNo: '',
preSettlementNo: '',
projectName: '',
- deptName: '',
+ deptName: [],
contractNo: '',
payerName: '',
payeeName: '',
@@ -190,6 +201,7 @@ const emptyQuery = () => ({
export default {
name: 'FormalSettlement',
components: { FormalSettlementEditor, FormalSettlementTablePanel },
+ mixins: [organizationSearch],
data() {
return {
ArrowDown,
@@ -231,6 +243,7 @@ export default {
},
},
mounted() {
+ this.loadOrganizationOptions();
this.loadTable();
this.openRouteDetail();
},
@@ -517,7 +530,8 @@ export default {
XLSX.writeFile(workbook, `正式结算单${this.$dayjs().format('YYYY-MM-DD HH-mm-ss')}.xlsx`);
},
buildQueryParams() {
- const params = { ...this.query };
+ // 所属组织级联返回 id 路径,转成组织名称传给后端(用副本,避免污染搜索框回显)
+ const params = this.normalizeOrganizationSearch({ ...this.query }, 'deptName');
params.settlementType = this.activeSettlementType;
const range = params.createDateRange || [];
delete params.createDateRange;
diff --git a/src/views/settlement/pre-settlement.vue b/src/views/settlement/pre-settlement.vue
index 6b8b43f..8b78201 100644
--- a/src/views/settlement/pre-settlement.vue
+++ b/src/views/settlement/pre-settlement.vue
@@ -29,6 +29,16 @@
:value="item.value"
/>
+
@@ -280,6 +290,7 @@ import {
voidBill,
} from '@/api/settlement/preSettlement';
import { preSettlementSearchFields } from '@/option/settlement/preSettlementSearch';
+import organizationSearch from '@/mixins/organization-search';
import { preSettlementTableColumns } from '@/option/settlement/preSettlementTable';
import { createSettlementTransfer } from '@/utils/settlement-transfer';
import { downloadFile } from '@/utils/util';
@@ -289,7 +300,7 @@ const emptyQuery = () => ({
preSettlementNo: '',
advanceNo: '',
projectName: '',
- deptName: '',
+ deptName: [],
contractName: '',
contractNo: '',
payeeName: '',
@@ -301,6 +312,7 @@ const emptyQuery = () => ({
export default {
name: 'PreSettlement',
components: { PreSettlementEditor },
+ mixins: [organizationSearch],
data() {
return {
ArrowDown,
@@ -354,6 +366,7 @@ export default {
},
},
created() {
+ this.loadOrganizationOptions();
this.loadTable();
this.openRouteDetail();
},
@@ -374,8 +387,10 @@ export default {
},
buildQuery() {
const range = this.query.createDateRange || [];
+ // 所属组织级联返回 id 路径,转成组织名称传给后端(用副本,避免污染搜索框回显)
+ const query = this.normalizeOrganizationSearch({ ...this.query }, 'deptName');
return {
- ...this.query,
+ ...query,
createDateRange: undefined,
createStartDate: range[0],
createEndDate: range[1],
diff --git a/src/views/settlement/receivable-payable-detail.vue b/src/views/settlement/receivable-payable-detail.vue
index e5ee539..49372d9 100644
--- a/src/views/settlement/receivable-payable-detail.vue
+++ b/src/views/settlement/receivable-payable-detail.vue
@@ -15,6 +15,16 @@
start-placeholder="年/月/日"
end-placeholder="年/月/日"
/>
+
@@ -627,8 +637,10 @@ import { exportBlob } from '@/api/common';
import { getDictionary } from '@/api/system/dictbiz';
import { downloadXls } from '@/utils/util';
import { createSettlementTransfer } from '@/utils/settlement-transfer';
+import organizationSearch from '@/mixins/organization-search';
export default {
+ mixins: [organizationSearch],
props: {
settlementType: {
type: String,
@@ -755,6 +767,7 @@ export default {
},
},
mounted() {
+ this.loadOrganizationOptions();
this.loadTransportTypeOptions();
this.loadCargoTypeOptions();
this.loadPriceUnitOptions();
@@ -937,11 +950,15 @@ export default {
this.tableFeeItemNames = [];
try {
const params = this.buildRequestParams(
- this.normalizeQuery(
- this.query,
- 'generateDateRange',
- 'generateStartDate',
- 'generateEndDate'
+ // 所属组织级联返回 id 路径,转成组织名称传给后端(用副本,避免污染搜索框回显)
+ this.normalizeOrganizationSearch(
+ this.normalizeQuery(
+ { ...this.query },
+ 'generateDateRange',
+ 'generateStartDate',
+ 'generateEndDate'
+ ),
+ 'deptName'
)
);
const res = await api.getList(this.page.current, this.page.size, params);
diff --git a/src/views/settlement/settlement-adjustment.vue b/src/views/settlement/settlement-adjustment.vue
index c715186..752e7a2 100644
--- a/src/views/settlement/settlement-adjustment.vue
+++ b/src/views/settlement/settlement-adjustment.vue
@@ -25,6 +25,16 @@
:label="item.label"
:value="item.value"
/>
+
@@ -159,6 +169,7 @@ import { ArrowDown, ArrowUp, Refresh } from '@element-plus/icons-vue';
import { mapGetters } from 'vuex';
import * as api from '@/api/settlement/settlementAdjustment';
import { settlementAdjustmentSearchFields } from '@/option/settlement/settlementAdjustmentSearch';
+import organizationSearch from '@/mixins/organization-search';
import { settlementAdjustmentTableColumns } from '@/option/settlement/settlementAdjustmentTable';
import SettlementAdjustmentEditor from './components/settlement-adjustment-editor.vue';
@@ -167,7 +178,7 @@ const emptyQuery = () => ({
createDateRange: [],
customerName: '',
projectName: '',
- deptName: '',
+ deptName: [],
formalSettlementNo: '',
settlementType: '',
approvalStatus: '',
@@ -175,6 +186,7 @@ const emptyQuery = () => ({
export default {
name: 'SettlementAdjustment',
components: { SettlementAdjustmentEditor },
+ mixins: [organizationSearch],
data: () => ({
ArrowDown,
ArrowUp,
@@ -199,6 +211,7 @@ export default {
},
},
created() {
+ this.loadOrganizationOptions();
this.loadTable();
},
methods: {
@@ -210,7 +223,8 @@ export default {
try {
const range = this.query.createDateRange || [];
const { data } = await api.getList(this.page.current, this.page.size, {
- ...this.query,
+ // 所属组织级联返回 id 路径,转成组织名称传给后端(用副本,避免污染搜索框回显)
+ ...this.normalizeOrganizationSearch({ ...this.query }, 'deptName'),
createDateRange: undefined,
createStartDate: range[0],
createEndDate: range[1],
diff --git a/src/views/settlement/transport-reconciliation.vue b/src/views/settlement/transport-reconciliation.vue
index 4ad2554..0a87b48 100644
--- a/src/views/settlement/transport-reconciliation.vue
+++ b/src/views/settlement/transport-reconciliation.vue
@@ -17,6 +17,16 @@
:value="item.value"
/>
+
@@ -87,6 +97,7 @@ import * as XLSX from 'xlsx';
import * as api from '@/api/settlement/transportReconciliation';
import { transportReconciliationSearchFields } from '@/option/settlement/transportReconciliationSearch';
import { transportReconciliationTableColumns } from '@/option/settlement/transportReconciliationTable';
+import organizationSearch from '@/mixins/organization-search';
import TransportReconciliationEditor from './components/transport-reconciliation-editor.vue';
import TransportReconciliationTablePanel from './components/transport-reconciliation-table-panel.vue';
@@ -94,7 +105,7 @@ const emptyQuery = () => ({
reconciliationNo: '',
preSettlementNos: '',
projectName: '',
- deptName: '',
+ deptName: [],
contractNo: '',
payerName: '',
payeeName: '',
@@ -105,6 +116,7 @@ const emptyQuery = () => ({
export default {
name: 'TransportReconciliation',
components: { TransportReconciliationEditor, TransportReconciliationTablePanel },
+ mixins: [organizationSearch],
data() {
return {
ArrowDown,
@@ -129,6 +141,7 @@ export default {
},
},
mounted() {
+ this.loadOrganizationOptions();
this.loadTable();
},
methods: {
@@ -139,7 +152,8 @@ export default {
this.loading = true;
try {
const response = await api.getList(this.page.current, this.page.size, {
- ...this.query,
+ // 所属组织级联返回 id 路径,转成组织名称传给后端(用副本,避免污染搜索框回显)
+ ...this.normalizeOrganizationSearch({ ...this.query }, 'deptName'),
settlementType: this.settlementType,
});
const data = response?.data?.data || response?.data || response || {};
diff --git a/src/views/system/user.vue b/src/views/system/user.vue
index 0bc6c36..933f6a0 100644
--- a/src/views/system/user.vue
+++ b/src/views/system/user.vue
@@ -195,7 +195,7 @@
-
+
仅所属组织全部组织自定义
@@ -443,6 +443,36 @@ export default {
},
computed: {
...mapGetters(['userInfo', 'permission']),
+ // 所属组织级联配置:checkStrictly 允许选中任意层级,不必选到末级
+ deptCascaderProps() {
+ return {
+ label: 'title',
+ value: 'id',
+ children: 'children',
+ emitPath: true,
+ checkStrictly: true,
+ expandTrigger: 'click',
+ };
+ },
+ // 所属组织为单选级联:form.deptId 仍为数组(提交时 join),此处与 id 路径双向转换
+ deptCascaderValue: {
+ get() {
+ const ids = Array.isArray(this.form.deptId)
+ ? this.form.deptId
+ : this.form.deptId
+ ? [this.form.deptId]
+ : [];
+ const id = ids.find(item => item !== undefined && item !== null && item !== '');
+ return id === undefined ? [] : this.findDeptPath(id) || [id];
+ },
+ set(path) {
+ const value = Array.isArray(path)
+ ? path.filter(item => item !== undefined && item !== null && item !== '')
+ : [];
+ this.form.deptId = value.length ? [value.at(-1)] : [];
+ this.$refs.userFormRef?.validateField('deptId');
+ },
+ },
permissionList() {
return {
addBtn: this.validData(this.permission.user_add, false),
@@ -565,6 +595,18 @@ export default {
this.customerList = res.data.data || [];
});
},
+ // 由部门 id 反查「根 → 该节点」的 id 路径,供级联回显(找不到返回 null)
+ findDeptPath(id, tree = this.permissionDeptTree, parents = []) {
+ const target = Array.isArray(id) ? id.at(-1) : id;
+ if (target === undefined || target === null || target === '') return null;
+ for (const node of tree || []) {
+ const path = [...parents, node.id];
+ if (String(node.id) === String(target)) return path;
+ const matched = this.findDeptPath(target, node.children, path);
+ if (matched) return matched;
+ }
+ return null;
+ },
submitRole() {
const roleList = this.$refs.treeRole.getCheckedKeys().join(',');
if (this.roleFormMode) {
diff --git a/src/views/transportCapacity/driver.vue b/src/views/transportCapacity/driver.vue
index 6a63be0..94259fc 100644
--- a/src/views/transportCapacity/driver.vue
+++ b/src/views/transportCapacity/driver.vue
@@ -490,14 +490,14 @@
-
-
-
+
@@ -815,6 +815,15 @@ export default {
},
computed: {
...mapGetters(['permission', 'userInfo']),
+ // 所属组织级联:表单存组织名称,级联控件用 id 路径,两者在此双向转换
+ organizationCascaderValue: {
+ get() {
+ return this.resolveOrgPath(this.driverForm.organizationName);
+ },
+ set(path) {
+ this.driverForm.organizationName = this.resolveOrgName(path);
+ },
+ },
isAdmin() {
const authority = this.userInfo.authority || '';
return authority.includes('admin');
@@ -1613,6 +1622,8 @@ export default {
this.onLoad(this.page);
},
searchChange(params, done) {
+ // 所属组织级联返回的是 id 路径,转成组织名称传给后端
+ this.normalizeOrganizationSearch(params);
this.searchForm = params;
this.page.currentPage = 1;
this.onLoad(this.page, params);
diff --git a/src/views/transportCapacity/ship.vue b/src/views/transportCapacity/ship.vue
index 255570f..07b1912 100644
--- a/src/views/transportCapacity/ship.vue
+++ b/src/views/transportCapacity/ship.vue
@@ -145,19 +145,14 @@
-
-
-
+ placeholder="请选择 船舶所属组织"
+ />
@@ -707,6 +702,15 @@ export default {
},
computed: {
...mapGetters(['permission', 'userInfo']),
+ // 船舶所属组织级联:表单存组织名称,级联控件用 id 路径,两者在此双向转换
+ organizationCascaderValue: {
+ get() {
+ return this.resolveOrgPath(this.shipForm.organizationName);
+ },
+ set(path) {
+ this.shipForm.organizationName = this.resolveOrgName(path);
+ },
+ },
isAdmin() {
const authority = this.userInfo.authority || '';
return authority.includes('admin');
@@ -1100,6 +1104,8 @@ export default {
this.onLoad(this.page);
},
searchChange(params, done) {
+ // 所属组织级联返回的是 id 路径,转成组织名称传给后端
+ this.normalizeOrganizationSearch(params);
this.searchForm = params;
this.page.currentPage = 1;
this.onLoad(this.page, params);
diff --git a/src/views/transportCapacity/vehicle.vue b/src/views/transportCapacity/vehicle.vue
index 6c8dbca..8026573 100644
--- a/src/views/transportCapacity/vehicle.vue
+++ b/src/views/transportCapacity/vehicle.vue
@@ -159,19 +159,14 @@
-
-
-
+ placeholder="请选择 所属组织"
+ />
@@ -709,6 +704,15 @@ export default {
},
computed: {
...mapGetters(['permission', 'userInfo']),
+ // 所属组织级联:表单存组织名称,级联控件用 id 路径,两者在此双向转换
+ organizationCascaderValue: {
+ get() {
+ return this.resolveOrgPath(this.vehicleForm.organizationName);
+ },
+ set(path) {
+ this.vehicleForm.organizationName = this.resolveOrgName(path);
+ },
+ },
isAdmin() {
const authority = this.userInfo.authority || '';
return authority.includes('admin');
@@ -1275,6 +1279,8 @@ export default {
this.onLoad(this.page);
},
searchChange(params, done) {
+ // 所属组织级联返回的是 id 路径,转成组织名称传给后端
+ this.normalizeOrganizationSearch(params);
this.searchForm = params;
this.page.currentPage = 1;
this.onLoad(this.page, params);
diff --git a/src/views/vehicle/customer-archive.vue b/src/views/vehicle/customer-archive.vue
index 3e6ef0b..821c583 100644
--- a/src/views/vehicle/customer-archive.vue
+++ b/src/views/vehicle/customer-archive.vue
@@ -335,17 +335,13 @@
-
@@ -1381,7 +1377,7 @@