Compare commits
9 Commits
4287133f84
..
uat
| Author | SHA1 | Date | |
|---|---|---|---|
| 8db52ef168 | |||
| 38ca250242 | |||
| f4542cd0b8 | |||
| d1e779bbcc | |||
| acfbb4c54e | |||
| 96b675b3be | |||
| 6067d24e3b | |||
| e051327f2d | |||
| f7759fd9e7 |
@@ -77,7 +77,8 @@ export const syncOaDepartment = (
|
|||||||
size = 20,
|
size = 20,
|
||||||
signal,
|
signal,
|
||||||
incremental = false,
|
incremental = false,
|
||||||
modifiedSince
|
modifiedSince,
|
||||||
|
companyOaId
|
||||||
) => {
|
) => {
|
||||||
return request({
|
return request({
|
||||||
url: '/blade-system/dept/sync-oa-department',
|
url: '/blade-system/dept/sync-oa-department',
|
||||||
@@ -87,6 +88,7 @@ export const syncOaDepartment = (
|
|||||||
size,
|
size,
|
||||||
incremental: !!incremental,
|
incremental: !!incremental,
|
||||||
modifiedSince: modifiedSince || undefined,
|
modifiedSince: modifiedSince || undefined,
|
||||||
|
companyOaId: companyOaId || undefined,
|
||||||
},
|
},
|
||||||
timeout: 60000,
|
timeout: 60000,
|
||||||
signal,
|
signal,
|
||||||
|
|||||||
@@ -97,7 +97,8 @@ export const config = {
|
|||||||
action: 'startChange',
|
action: 'startChange',
|
||||||
label: '变更',
|
label: '变更',
|
||||||
statusProp: 'approvalStatus',
|
statusProp: 'approvalStatus',
|
||||||
status: ['approved'],
|
// 立项通过、变更通过后均可再次发起变更
|
||||||
|
status: ['approved', 'change_approved'],
|
||||||
permission: 'project_apply_change',
|
permission: 'project_apply_change',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,3 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* 合并列表搜索条件:新条件覆盖旧条件,本次显式清空的字段从查询中移除。
|
||||||
|
*/
|
||||||
|
export const applyIncomingSearch = (current = {}, incoming = {}) => {
|
||||||
|
const merged = { ...current, ...incoming };
|
||||||
|
Object.keys(incoming || {}).forEach(key => {
|
||||||
|
const value = incoming[key];
|
||||||
|
if (
|
||||||
|
value === '' ||
|
||||||
|
value === null ||
|
||||||
|
value === undefined ||
|
||||||
|
(Array.isArray(value) && value.length === 0)
|
||||||
|
) {
|
||||||
|
delete merged[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return merged;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启停状态下拉「全部」在数字类型下会被转成 0/-1,不能当作查询条件。
|
||||||
|
* 状态 0 表示草稿等有效值的页面不要调用。
|
||||||
|
*/
|
||||||
|
export const omitInvalidListStatus = (params = {}) => {
|
||||||
|
const values = { ...params };
|
||||||
|
const status = values.status;
|
||||||
|
if (status === 0 || status === '0' || status === -1 || status === '-1') {
|
||||||
|
delete values.status;
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
};
|
||||||
|
|
||||||
export const normalizeSearchRangeParams = (params = {}, rangeMap = {}) => {
|
export const normalizeSearchRangeParams = (params = {}, rangeMap = {}) => {
|
||||||
const values = { ...params };
|
const values = { ...params };
|
||||||
|
|
||||||
|
|||||||
@@ -150,6 +150,7 @@ import { mapGetters } from 'vuex';
|
|||||||
import { downloadXls } from '@/utils/util';
|
import { downloadXls } from '@/utils/util';
|
||||||
import { openImportDialog } from '@/utils/import-excel';
|
import { openImportDialog } from '@/utils/import-excel';
|
||||||
import { formatUpdateUserName } from '@/utils/audit';
|
import { formatUpdateUserName } from '@/utils/audit';
|
||||||
|
import { omitInvalidListStatus } from '@/utils/search-range';
|
||||||
import { getToken, isAdministrator } from '@/utils/auth';
|
import { getToken, isAdministrator } from '@/utils/auth';
|
||||||
import { getCoordinateValidationMessage, normalizeCoordinateInput } from '@/utils/coordinate';
|
import { getCoordinateValidationMessage, normalizeCoordinateInput } from '@/utils/coordinate';
|
||||||
import AddressMapPicker from '@/components/address-map-picker/main.vue';
|
import AddressMapPicker from '@/components/address-map-picker/main.vue';
|
||||||
@@ -1182,7 +1183,7 @@ export default {
|
|||||||
},
|
},
|
||||||
onLoad(page, params = {}) {
|
onLoad(page, params = {}) {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
getList(page.currentPage, page.pageSize, { ...params, ...this.query })
|
getList(page.currentPage, page.pageSize, omitInvalidListStatus({ ...params, ...this.query }))
|
||||||
.then(res => {
|
.then(res => {
|
||||||
const data = res.data.data;
|
const data = res.data.data;
|
||||||
this.page.total = data.total;
|
this.page.total = data.total;
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ import { mapGetters } from 'vuex';
|
|||||||
import { downloadXls } from '@/utils/util';
|
import { downloadXls } from '@/utils/util';
|
||||||
import { openImportDialog } from '@/utils/import-excel';
|
import { openImportDialog } from '@/utils/import-excel';
|
||||||
import { formatUpdateUserName } from '@/utils/audit';
|
import { formatUpdateUserName } from '@/utils/audit';
|
||||||
|
import { omitInvalidListStatus } from '@/utils/search-range';
|
||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import 'nprogress/nprogress.css';
|
import 'nprogress/nprogress.css';
|
||||||
@@ -507,7 +508,7 @@ export default {
|
|||||||
this.onLoad(this.page, this.query);
|
this.onLoad(this.page, this.query);
|
||||||
},
|
},
|
||||||
buildQuery(params = {}) {
|
buildQuery(params = {}) {
|
||||||
const values = { ...params, ...this.query };
|
const values = omitInvalidListStatus({ ...params, ...this.query });
|
||||||
const rangeMap = {
|
const rangeMap = {
|
||||||
effectiveDateRange: ['effectiveDateStart', 'effectiveDateEnd'],
|
effectiveDateRange: ['effectiveDateStart', 'effectiveDateEnd'],
|
||||||
expiryDateRange: ['expiryDateStart', 'expiryDateEnd'],
|
expiryDateRange: ['expiryDateStart', 'expiryDateEnd'],
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getList, getDetail, submit, remove, changeStatus } from '@/api/base/customer-type';
|
import { getList, getDetail, submit, remove, changeStatus } from '@/api/base/customer-type';
|
||||||
|
import { omitInvalidListStatus } from '@/utils/search-range';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -290,7 +291,7 @@ export default {
|
|||||||
},
|
},
|
||||||
onLoad(page, params = {}) {
|
onLoad(page, params = {}) {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
|
getList(page.currentPage, page.pageSize, omitInvalidListStatus(Object.assign(params, this.query))).then(res => {
|
||||||
const data = res.data.data;
|
const data = res.data.data;
|
||||||
this.page.total = data.total;
|
this.page.total = data.total;
|
||||||
this.data = data.records;
|
this.data = data.records;
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ import { exportBlob } from '@/api/common';
|
|||||||
import { getDictionaryAll } from '@/api/system/dictbiz';
|
import { getDictionaryAll } from '@/api/system/dictbiz';
|
||||||
import { getDeptTree } from '@/api/system/dept';
|
import { getDeptTree } from '@/api/system/dept';
|
||||||
import { downloadXls } from '@/utils/util';
|
import { downloadXls } from '@/utils/util';
|
||||||
|
import { omitInvalidListStatus } from '@/utils/search-range';
|
||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
import { Download } from '@element-plus/icons-vue';
|
import { Download } from '@element-plus/icons-vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
@@ -569,7 +570,7 @@ export default {
|
|||||||
},
|
},
|
||||||
onLoad(page, params = {}) {
|
onLoad(page, params = {}) {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
|
getList(page.currentPage, page.pageSize, omitInvalidListStatus(Object.assign(params, this.query))).then(res => {
|
||||||
const data = res.data.data;
|
const data = res.data.data;
|
||||||
this.page.total = data.total;
|
this.page.total = data.total;
|
||||||
this.data = data.records;
|
this.data = data.records;
|
||||||
|
|||||||
@@ -82,6 +82,7 @@
|
|||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { changeStatus, getDetail, getList, remove, submit } from '@/api/base/measurement-unit';
|
import { changeStatus, getDetail, getList, remove, submit } from '@/api/base/measurement-unit';
|
||||||
import { createOption } from '@/option/base/measurement-unit';
|
import { createOption } from '@/option/base/measurement-unit';
|
||||||
|
import { omitInvalidListStatus } from '@/utils/search-range';
|
||||||
import { isAdministrator } from '@/utils/auth';
|
import { isAdministrator } from '@/utils/auth';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -218,7 +219,7 @@ export default {
|
|||||||
},
|
},
|
||||||
onLoad(page = this.page, params = this.query) {
|
onLoad(page = this.page, params = this.query) {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
return getList(page.currentPage, page.pageSize, params)
|
return getList(page.currentPage, page.pageSize, omitInvalidListStatus(params))
|
||||||
.then(res => {
|
.then(res => {
|
||||||
const pageData = res.data.data || {};
|
const pageData = res.data.data || {};
|
||||||
this.data = pageData.records || [];
|
this.data = pageData.records || [];
|
||||||
|
|||||||
@@ -270,6 +270,7 @@ import { mapGetters } from 'vuex';
|
|||||||
import { downloadXls } from '@/utils/util';
|
import { downloadXls } from '@/utils/util';
|
||||||
import { openImportDialog } from '@/utils/import-excel';
|
import { openImportDialog } from '@/utils/import-excel';
|
||||||
import { formatUpdateUserName } from '@/utils/audit';
|
import { formatUpdateUserName } from '@/utils/audit';
|
||||||
|
import { omitInvalidListStatus } from '@/utils/search-range';
|
||||||
import { getToken, isAdministrator } from '@/utils/auth';
|
import { getToken, isAdministrator } from '@/utils/auth';
|
||||||
import { getCoordinateValidationMessage, normalizeCoordinateInput } from '@/utils/coordinate';
|
import { getCoordinateValidationMessage, normalizeCoordinateInput } from '@/utils/coordinate';
|
||||||
import AddressMapPicker from '@/components/address-map-picker/main.vue';
|
import AddressMapPicker from '@/components/address-map-picker/main.vue';
|
||||||
@@ -1636,7 +1637,7 @@ export default {
|
|||||||
},
|
},
|
||||||
onLoad(page, params = {}) {
|
onLoad(page, params = {}) {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
getList(page.currentPage, page.pageSize, { ...params, ...this.query })
|
getList(page.currentPage, page.pageSize, omitInvalidListStatus({ ...params, ...this.query }))
|
||||||
.then(res => {
|
.then(res => {
|
||||||
const data = res.data.data;
|
const data = res.data.data;
|
||||||
this.page.total = data.total;
|
this.page.total = data.total;
|
||||||
|
|||||||
@@ -150,6 +150,7 @@ import { mapGetters } from 'vuex';
|
|||||||
import { downloadXls } from '@/utils/util';
|
import { downloadXls } from '@/utils/util';
|
||||||
import { openImportDialog } from '@/utils/import-excel';
|
import { openImportDialog } from '@/utils/import-excel';
|
||||||
import { formatUpdateUserName } from '@/utils/audit';
|
import { formatUpdateUserName } from '@/utils/audit';
|
||||||
|
import { omitInvalidListStatus } from '@/utils/search-range';
|
||||||
import { getToken, isAdministrator } from '@/utils/auth';
|
import { getToken, isAdministrator } from '@/utils/auth';
|
||||||
import { getCoordinateValidationMessage, normalizeCoordinateInput } from '@/utils/coordinate';
|
import { getCoordinateValidationMessage, normalizeCoordinateInput } from '@/utils/coordinate';
|
||||||
import AddressMapPicker from '@/components/address-map-picker/main.vue';
|
import AddressMapPicker from '@/components/address-map-picker/main.vue';
|
||||||
@@ -1157,7 +1158,7 @@ export default {
|
|||||||
},
|
},
|
||||||
onLoad(page, params = {}) {
|
onLoad(page, params = {}) {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
getList(page.currentPage, page.pageSize, { ...params, ...this.query })
|
getList(page.currentPage, page.pageSize, omitInvalidListStatus({ ...params, ...this.query }))
|
||||||
.then(res => {
|
.then(res => {
|
||||||
const data = res.data.data;
|
const data = res.data.data;
|
||||||
this.page.total = data.total;
|
this.page.total = data.total;
|
||||||
|
|||||||
@@ -416,6 +416,7 @@ import { getList as getProjectList } from '@/api/business/project-apply';
|
|||||||
import { getDeptTree } from '@/api/system/dept';
|
import { getDeptTree } from '@/api/system/dept';
|
||||||
import { exportBlob } from '@/api/common';
|
import { exportBlob } from '@/api/common';
|
||||||
import { config, option } from '@/option/business/process-config';
|
import { config, option } from '@/option/business/process-config';
|
||||||
|
import { applyIncomingSearch } from '@/utils/search-range';
|
||||||
import { getToken, isAdministrator } from '@/utils/auth';
|
import { getToken, isAdministrator } from '@/utils/auth';
|
||||||
import { downloadXls } from '@/utils/util';
|
import { downloadXls } from '@/utils/util';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
@@ -603,7 +604,8 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
normalizeListQuery(params = {}) {
|
normalizeListQuery(params = {}) {
|
||||||
const query = { ...params, ...this.query };
|
// 新条件覆盖旧条件,清空的筛选项不再沿用上一次的值。
|
||||||
|
const query = applyIncomingSearch(this.query, params);
|
||||||
const rawDeptId = query.deptId ?? query.searchDeptId;
|
const rawDeptId = query.deptId ?? query.searchDeptId;
|
||||||
delete query.searchDeptId;
|
delete query.searchDeptId;
|
||||||
if (rawDeptId !== undefined && rawDeptId !== null && String(rawDeptId).trim() !== '') {
|
if (rawDeptId !== undefined && rawDeptId !== null && String(rawDeptId).trim() !== '') {
|
||||||
|
|||||||
@@ -224,7 +224,7 @@
|
|||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
filterable
|
filterable
|
||||||
clearable
|
clearable
|
||||||
:disabled="isBasicInfoReadonly"
|
:disabled="dialogReadonly"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="平台公司" prop="undertakeDeptId">
|
<el-form-item label="平台公司" prop="undertakeDeptId">
|
||||||
@@ -236,7 +236,7 @@
|
|||||||
collapse-tags-tooltip
|
collapse-tags-tooltip
|
||||||
clearable
|
clearable
|
||||||
filterable
|
filterable
|
||||||
:disabled="isBasicInfoReadonly"
|
:disabled="dialogReadonly"
|
||||||
@change="handleUndertakeDeptChange"
|
@change="handleUndertakeDeptChange"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
@@ -2493,7 +2493,8 @@ export default {
|
|||||||
loadDeptOptions() {
|
loadDeptOptions() {
|
||||||
getDeptTree().then(res => {
|
getDeptTree().then(res => {
|
||||||
const deptTree = res.data.data || [];
|
const deptTree = res.data.data || [];
|
||||||
const businessDeptTree = ['add', 'edit', 'majorSupplement'].includes(this.dialogType)
|
// 新增/编辑/重大补录/项目变更均可选择业务部门,排除外部组织
|
||||||
|
const businessDeptTree = ['add', 'edit', 'majorSupplement', 'change'].includes(this.dialogType)
|
||||||
? this.excludeExternalOrganization(deptTree)
|
? this.excludeExternalOrganization(deptTree)
|
||||||
: deptTree;
|
: deptTree;
|
||||||
this.deptOptions = this.flattenDept(businessDeptTree);
|
this.deptOptions = this.flattenDept(businessDeptTree);
|
||||||
|
|||||||
@@ -1233,7 +1233,7 @@ export default {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
const referenceRow = this.createReferenceRow(data);
|
const referenceRow = this.createReferenceRow(data);
|
||||||
this.referenceRows = referenceRow.settlementNo ? [referenceRow] : [];
|
this.referenceRows = this.restoreReferenceRows(data, referenceRow);
|
||||||
this.paymentRecords = data.paymentRecords || [];
|
this.paymentRecords = data.paymentRecords || [];
|
||||||
},
|
},
|
||||||
async initialize() {
|
async initialize() {
|
||||||
@@ -1256,7 +1256,7 @@ export default {
|
|||||||
invoices: data.invoices || [],
|
invoices: data.invoices || [],
|
||||||
};
|
};
|
||||||
const referenceRow = this.createReferenceRow(data);
|
const referenceRow = this.createReferenceRow(data);
|
||||||
this.referenceRows = referenceRow.settlementNo ? [referenceRow] : [];
|
this.referenceRows = this.restoreReferenceRows(data, referenceRow);
|
||||||
this.paymentRecords = data.paymentRecords || [];
|
this.paymentRecords = data.paymentRecords || [];
|
||||||
if (this.form.paymentType === 'project_advance') {
|
if (this.form.paymentType === 'project_advance') {
|
||||||
await this.loadProjectOptions();
|
await this.loadProjectOptions();
|
||||||
@@ -1474,6 +1474,33 @@ export default {
|
|||||||
this.$refs.formRef?.clearValidate();
|
this.$refs.formRef?.clearValidate();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
restoreReferenceRows(data, fallbackRow) {
|
||||||
|
const relations = Array.isArray(data?.settlements) ? data.settlements : [];
|
||||||
|
const rows = relations
|
||||||
|
.map(item => {
|
||||||
|
const isPre = item.preSettlementId !== undefined && item.preSettlementId !== null && item.preSettlementId !== '';
|
||||||
|
const settlementNo = item.preSettlementNo || item.formalSettlementNo || '';
|
||||||
|
if (!settlementNo) return null;
|
||||||
|
return {
|
||||||
|
id: isPre ? item.preSettlementId : item.formalSettlementId,
|
||||||
|
settlementNo,
|
||||||
|
referenceType: isPre ? 'pre' : 'formal',
|
||||||
|
settlementAmount: Number(Number(item.settlementAmount || 0).toFixed(2)),
|
||||||
|
payableAmount: Number(Number(item.payableAmount ?? item.settlementAmount ?? 0).toFixed(2)),
|
||||||
|
appliedAmount: Number(Number(item.appliedAmount || 0).toFixed(2)),
|
||||||
|
fixedAppliedAmount: this.readonly,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.filter(Boolean);
|
||||||
|
if (rows.length > 1) {
|
||||||
|
this.form.preSettlementIds = rows.filter(item => item.referenceType === 'pre').map(item => item.id);
|
||||||
|
this.form.settlementIds = rows.filter(item => item.referenceType === 'formal').map(item => item.id);
|
||||||
|
if (this.form.preSettlementIds.length) this.form.preSettlementId = this.form.preSettlementIds[0];
|
||||||
|
if (this.form.settlementIds.length) this.form.settlementId = this.form.settlementIds[0];
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
return fallbackRow?.settlementNo ? [fallbackRow] : [];
|
||||||
|
},
|
||||||
createReferenceRow(row) {
|
createReferenceRow(row) {
|
||||||
const settlementAmount = Number(row.settlementAmount || 0);
|
const settlementAmount = Number(row.settlementAmount || 0);
|
||||||
const appliedAmount = Number(row.advanceAppliedAmount || row.appliedPaymentAmount || 0);
|
const appliedAmount = Number(row.advanceAppliedAmount || row.appliedPaymentAmount || 0);
|
||||||
@@ -1482,11 +1509,13 @@ export default {
|
|||||||
id: row.preSettlementId || row.settlementId || row.id,
|
id: row.preSettlementId || row.settlementId || row.id,
|
||||||
settlementNo: row.preSettlementNo || row.formalSettlementNo || row.settlementNo || '',
|
settlementNo: row.preSettlementNo || row.formalSettlementNo || row.settlementNo || '',
|
||||||
referenceType: isPre ? 'pre' : 'formal',
|
referenceType: isPre ? 'pre' : 'formal',
|
||||||
settlementAmount,
|
settlementAmount: Number(Number(settlementAmount || 0).toFixed(2)),
|
||||||
payableAmount:
|
payableAmount: Number(
|
||||||
row.payableAmount === undefined || row.payableAmount === null
|
(row.payableAmount === undefined || row.payableAmount === null
|
||||||
? Math.max(0, settlementAmount - appliedAmount)
|
? Math.max(0, settlementAmount - appliedAmount)
|
||||||
: Number(row.payableAmount || 0),
|
: Number(row.payableAmount || 0)
|
||||||
|
).toFixed(2)
|
||||||
|
),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
createInvoiceRows(invoices = [], settlementNo = '') {
|
createInvoiceRows(invoices = [], settlementNo = '') {
|
||||||
@@ -1544,9 +1573,24 @@ export default {
|
|||||||
}
|
}
|
||||||
const first = rows[0];
|
const first = rows[0];
|
||||||
this.form.invoices = [];
|
this.form.invoices = [];
|
||||||
this.referenceRows = rows.map(item =>
|
const paymentType =
|
||||||
this.createReferenceRow({ ...item, referenceType: 'pre' })
|
this.form.paymentType === 'settlement_payment' ? 'settlement_payment' : 'progress_advance';
|
||||||
|
const amountResponses = await Promise.all(
|
||||||
|
rows.map(item => {
|
||||||
|
const referenceId = item.preSettlementId || item.id;
|
||||||
|
if (!this.isValidReferenceId(referenceId)) return Promise.resolve(null);
|
||||||
|
return api.getReferenceAmount(paymentType, referenceId, this.form.id).catch(() => null);
|
||||||
|
})
|
||||||
);
|
);
|
||||||
|
this.referenceRows = rows.map((item, index) => {
|
||||||
|
const amount = this.unwrapData(amountResponses[index]) || {};
|
||||||
|
return this.createReferenceRow({
|
||||||
|
...item,
|
||||||
|
referenceType: 'pre',
|
||||||
|
settlementAmount: amount.settlementAmount ?? item.settlementAmount,
|
||||||
|
payableAmount: amount.payableAmount,
|
||||||
|
});
|
||||||
|
});
|
||||||
const settlementAmount = this.referenceRows.reduce(
|
const settlementAmount = this.referenceRows.reduce(
|
||||||
(total, item) => total + Number(item.settlementAmount || 0),
|
(total, item) => total + Number(item.settlementAmount || 0),
|
||||||
0
|
0
|
||||||
@@ -1557,8 +1601,6 @@ export default {
|
|||||||
);
|
);
|
||||||
const paymentRatio = Number(this.form.paymentRatio || 0);
|
const paymentRatio = Number(this.form.paymentRatio || 0);
|
||||||
// 尾款付款场景下选择预结算单时保留尾款付款类型,不强制改为进度预付
|
// 尾款付款场景下选择预结算单时保留尾款付款类型,不强制改为进度预付
|
||||||
const paymentType =
|
|
||||||
this.form.paymentType === 'settlement_payment' ? 'settlement_payment' : 'progress_advance';
|
|
||||||
this.amountSyncing = true;
|
this.amountSyncing = true;
|
||||||
Object.assign(this.form, {
|
Object.assign(this.form, {
|
||||||
paymentType,
|
paymentType,
|
||||||
|
|||||||
@@ -46,6 +46,9 @@
|
|||||||
<el-table-column label="金蝶未认领金额" min-width="140" align="right">
|
<el-table-column label="金蝶未认领金额" min-width="140" align="right">
|
||||||
<template #default="{ row }">{{ formatMoney(row.unclaimedAmount) }}</template>
|
<template #default="{ row }">{{ formatMoney(row.unclaimedAmount) }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column label="剩余可认领金额" min-width="140" align="right">
|
||||||
|
<template #default="{ row }">{{ formatMoney(flowRemaining(row)) }}</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column prop="summary" label="摘要" min-width="180" show-overflow-tooltip />
|
<el-table-column prop="summary" label="摘要" min-width="180" show-overflow-tooltip />
|
||||||
</el-table>
|
</el-table>
|
||||||
<el-row :gutter="32" class="receipt-claim-batch-form-page__claim-info">
|
<el-row :gutter="32" class="receipt-claim-batch-form-page__claim-info">
|
||||||
@@ -298,10 +301,21 @@ export default {
|
|||||||
0
|
0
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
flowRemaining(flow) {
|
||||||
|
return Math.max(Number(flow.unclaimedAmount || 0) - Number(flow.claimedAmount || 0), 0);
|
||||||
|
},
|
||||||
maxAllocation(row) {
|
maxAllocation(row) {
|
||||||
const current = Number(row.settlement.allocations?.[row.flow.id] || 0);
|
const current = Number(row.settlement.allocations?.[row.flow.id] || 0);
|
||||||
const otherTotal = this.settlementAllocatedTotal(row.settlement) - current;
|
const otherTotal = this.settlementAllocatedTotal(row.settlement) - current;
|
||||||
return Math.max(this.settlementRemaining(row.settlement) - otherTotal, 0);
|
// 流水维度:该流水其余分摊已占用部分同样挤占剩余可认领金额
|
||||||
|
const flowOtherTotal = this.flowAllocatedTotal(row.flow.id) - current;
|
||||||
|
return Math.max(
|
||||||
|
Math.min(
|
||||||
|
this.settlementRemaining(row.settlement) - otherTotal,
|
||||||
|
this.flowRemaining(row.flow) - flowOtherTotal
|
||||||
|
),
|
||||||
|
0
|
||||||
|
);
|
||||||
},
|
},
|
||||||
handleAllocationChange(settlement) {
|
handleAllocationChange(settlement) {
|
||||||
const total = this.settlementAllocatedTotal(settlement);
|
const total = this.settlementAllocatedTotal(settlement);
|
||||||
|
|||||||
@@ -252,31 +252,36 @@
|
|||||||
:index="detailIndexMethod"
|
:index="detailIndexMethod"
|
||||||
/>
|
/>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
v-for="column in detailTableColumns"
|
v-for="item in detailDisplayColumns"
|
||||||
:key="column.prop"
|
:key="item.key"
|
||||||
v-bind="column"
|
:label="item.kind === 'fee' ? item.name : item.column.label"
|
||||||
|
:prop="item.kind === 'fee' ? undefined : item.column.prop"
|
||||||
|
:min-width="item.kind === 'fee' ? 130 : item.column.minWidth"
|
||||||
align="center"
|
align="center"
|
||||||
show-overflow-tooltip
|
show-overflow-tooltip
|
||||||
>
|
>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
|
<span v-if="item.kind === 'fee'">
|
||||||
|
{{ formatMoney(parseFeeItems(row.feeItemsJson || row.feeItems)[item.name]) }}
|
||||||
|
</span>
|
||||||
<el-link
|
<el-link
|
||||||
v-if="column.link && row[column.prop] && !publicMode"
|
v-else-if="item.column.link && row[item.column.prop] && !publicMode"
|
||||||
type="primary"
|
type="primary"
|
||||||
@click.stop="handleDetailLink(row, column)"
|
@click.stop="handleDetailLink(row, item.column)"
|
||||||
>
|
>
|
||||||
{{ row[column.prop] }}
|
{{ row[item.column.prop] }}
|
||||||
</el-link>
|
</el-link>
|
||||||
<span v-else-if="column.money">{{ formatMoney(row[column.prop]) }}</span>
|
<span v-else-if="item.column.money">{{ formatMoney(row[item.column.prop]) }}</span>
|
||||||
<span v-else-if="column.prop === 'transportQuantity'">
|
<span v-else-if="item.column.prop === 'transportQuantity'">
|
||||||
{{ formatDetailTransportQuantity(row[column.prop]) }}
|
{{ formatDetailTransportQuantity(row[item.column.prop]) }}
|
||||||
</span>
|
</span>
|
||||||
<span v-else-if="column.prop === 'mileage'">
|
<span v-else-if="item.column.prop === 'mileage'">
|
||||||
{{ formatDetailMileage(row[column.prop]) }}
|
{{ formatDetailMileage(row[item.column.prop]) }}
|
||||||
</span>
|
</span>
|
||||||
<span v-else-if="column.prop === 'transportType'">
|
<span v-else-if="item.column.prop === 'transportType'">
|
||||||
{{ transportTypeName(row[column.prop]) }}
|
{{ transportTypeName(row[item.column.prop]) }}
|
||||||
</span>
|
</span>
|
||||||
<span v-else>{{ displayValue(row[column.prop]) }}</span>
|
<span v-else>{{ displayValue(row[item.column.prop]) }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column v-if="editable" label="操作" width="150" fixed="right" align="center">
|
<el-table-column v-if="editable" label="操作" width="150" fixed="right" align="center">
|
||||||
@@ -1217,6 +1222,26 @@ export default {
|
|||||||
title() {
|
title() {
|
||||||
return this.readonly ? '查看正式结算单' : this.recordId ? '编辑正式结算单' : '新增正式结算单';
|
return this.readonly ? '查看正式结算单' : this.recordId ? '编辑正式结算单' : '新增正式结算单';
|
||||||
},
|
},
|
||||||
|
detailFeeItemNames() {
|
||||||
|
const names = new Set();
|
||||||
|
this.details.forEach(row => {
|
||||||
|
Object.keys(this.parseFeeItems(row.feeItemsJson || row.feeItems)).forEach(name =>
|
||||||
|
names.add(name)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return Array.from(names);
|
||||||
|
},
|
||||||
|
detailDisplayColumns() {
|
||||||
|
const columns = this.detailTableColumns;
|
||||||
|
const unitPriceIndex = columns.findIndex(column => column.prop === 'unitPrice');
|
||||||
|
const beforeColumns = unitPriceIndex < 0 ? columns : columns.slice(0, unitPriceIndex + 1);
|
||||||
|
const afterColumns = unitPriceIndex < 0 ? [] : columns.slice(unitPriceIndex + 1);
|
||||||
|
return [
|
||||||
|
...beforeColumns.map(column => ({ kind: 'field', key: column.prop, column })),
|
||||||
|
...this.detailFeeItemNames.map(name => ({ kind: 'fee', key: `fee-${name}`, name })),
|
||||||
|
...afterColumns.map(column => ({ kind: 'field', key: column.prop, column })),
|
||||||
|
];
|
||||||
|
},
|
||||||
// 币种为空按人民币处理,与后端预结算/正式结算对空币种的默认取值一致
|
// 币种为空按人民币处理,与后端预结算/正式结算对空币种的默认取值一致
|
||||||
isLocalCurrencySettlement() {
|
isLocalCurrencySettlement() {
|
||||||
return normalizeCurrencyCode(this.form.currency) === 'RMB';
|
return normalizeCurrencyCode(this.form.currency) === 'RMB';
|
||||||
|
|||||||
@@ -247,60 +247,52 @@
|
|||||||
:index="detailIndexMethod"
|
:index="detailIndexMethod"
|
||||||
/>
|
/>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
v-for="column in visibleDetailColumns"
|
v-for="item in detailDisplayColumns"
|
||||||
:key="column.prop"
|
:key="item.key"
|
||||||
:label="column.label"
|
:label="item.kind === 'fee' ? item.name : item.column.label"
|
||||||
:prop="column.prop"
|
:prop="item.kind === 'fee' ? undefined : item.column.prop"
|
||||||
:min-width="column.minWidth"
|
:min-width="item.kind === 'fee' ? 130 : item.column.minWidth"
|
||||||
align="center"
|
align="center"
|
||||||
show-overflow-tooltip
|
show-overflow-tooltip
|
||||||
>
|
>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
|
<span v-if="item.kind === 'fee'">
|
||||||
|
{{
|
||||||
|
formatMoney(
|
||||||
|
parseFeeItems(row.feeItemsJson)[item.name],
|
||||||
|
row.currency || form.currency
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</span>
|
||||||
<el-link
|
<el-link
|
||||||
v-if="column.link && row[column.prop] && !publicMode"
|
v-else-if="item.column.link && row[item.column.prop] && !publicMode"
|
||||||
type="primary"
|
type="primary"
|
||||||
@click.stop="handleDetailLink(row, column)"
|
@click.stop="handleDetailLink(row, item.column)"
|
||||||
>
|
>
|
||||||
{{ row[column.prop] }}
|
{{ row[item.column.prop] }}
|
||||||
</el-link>
|
</el-link>
|
||||||
<span v-else-if="column.money && column.prop === 'unitPrice'">
|
<span v-else-if="item.column.money && item.column.prop === 'unitPrice'">
|
||||||
{{ formatUnitPrice(row) }}
|
{{ formatUnitPrice(row) }}
|
||||||
</span>
|
</span>
|
||||||
<span v-else-if="column.money">
|
<span v-else-if="item.column.money">
|
||||||
{{ formatMoney(row[column.prop], row.currency || form.currency) }}
|
{{ formatMoney(row[item.column.prop], row.currency || form.currency) }}
|
||||||
</span>
|
</span>
|
||||||
<span v-else-if="column.prop === 'transportQuantityText'">
|
<span v-else-if="item.column.prop === 'transportQuantityText'">
|
||||||
{{ formatQuantity(row) }}
|
{{ formatQuantity(row) }}
|
||||||
</span>
|
</span>
|
||||||
<span v-else-if="pageMode && column.prop === 'mileage'">
|
<span v-else-if="item.column.prop === 'mileage'">
|
||||||
{{ formatDetailMileage(row[column.prop]) }}
|
{{ formatDetailMileage(row[item.column.prop]) }}
|
||||||
</span>
|
</span>
|
||||||
<span v-else-if="column.prop === 'transportType'">
|
<span v-else-if="item.column.prop === 'transportType'">
|
||||||
{{ transportTypeName(row[column.prop]) }}
|
{{ transportTypeName(row[item.column.prop]) }}
|
||||||
</span>
|
</span>
|
||||||
<span v-else-if="column.prop === 'cargoName'">
|
<span v-else-if="item.column.prop === 'cargoName'">
|
||||||
{{ formatCargoNames(row) }}
|
{{ formatCargoNames(row) }}
|
||||||
</span>
|
</span>
|
||||||
<span v-else-if="column.prop === 'cargoType'">
|
<span v-else-if="item.column.prop === 'cargoType'">
|
||||||
{{ formatCargoTypes(row) }}
|
{{ formatCargoTypes(row) }}
|
||||||
</span>
|
</span>
|
||||||
<span v-else>{{ displayValue(row[column.prop]) }}</span>
|
<span v-else>{{ displayValue(row[item.column.prop]) }}</span>
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
v-for="feeItem in detailFeeItemNames"
|
|
||||||
:key="`fee-${feeItem}`"
|
|
||||||
:label="feeItem"
|
|
||||||
min-width="130"
|
|
||||||
align="center"
|
|
||||||
>
|
|
||||||
<template #default="{ row }">
|
|
||||||
{{
|
|
||||||
formatMoney(
|
|
||||||
parseFeeItems(row.feeItemsJson)[feeItem],
|
|
||||||
row.currency || form.currency
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" :width="editable ? 150 : 90" fixed="right" align="center">
|
<el-table-column label="操作" :width="editable ? 150 : 90" fixed="right" align="center">
|
||||||
@@ -790,12 +782,13 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="里程(KM)" min-width="140" align="center">
|
<el-table-column label="里程(KM)" min-width="140" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
|
<span v-if="adjustDialog.readonly">{{ formatDetailMileage(row.mileage) }}</span>
|
||||||
<el-input-number
|
<el-input-number
|
||||||
|
v-else
|
||||||
v-model="row.mileage"
|
v-model="row.mileage"
|
||||||
:min="0"
|
:min="0"
|
||||||
:precision="2"
|
:precision="2"
|
||||||
:controls="false"
|
:controls="false"
|
||||||
:disabled="adjustDialog.readonly"
|
|
||||||
@change="recalculateAdjustRow(row, 'mileage')"
|
@change="recalculateAdjustRow(row, 'mileage')"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
@@ -1244,6 +1237,17 @@ export default {
|
|||||||
});
|
});
|
||||||
return Array.from(names);
|
return Array.from(names);
|
||||||
},
|
},
|
||||||
|
detailDisplayColumns() {
|
||||||
|
const columns = this.visibleDetailColumns;
|
||||||
|
const unitPriceIndex = columns.findIndex(column => column.prop === 'unitPrice');
|
||||||
|
const beforeColumns = unitPriceIndex < 0 ? columns : columns.slice(0, unitPriceIndex + 1);
|
||||||
|
const afterColumns = unitPriceIndex < 0 ? [] : columns.slice(unitPriceIndex + 1);
|
||||||
|
return [
|
||||||
|
...beforeColumns.map(column => ({ kind: 'field', key: column.prop, column })),
|
||||||
|
...this.detailFeeItemNames.map(name => ({ kind: 'fee', key: `fee-${name}`, name })),
|
||||||
|
...afterColumns.map(column => ({ kind: 'field', key: column.prop, column })),
|
||||||
|
];
|
||||||
|
},
|
||||||
// 按 preSettlementDetailId 分组的明细数据(用于拼接货物名称和类型)
|
// 按 preSettlementDetailId 分组的明细数据(用于拼接货物名称和类型)
|
||||||
groupedDetails() {
|
groupedDetails() {
|
||||||
const groups = {};
|
const groups = {};
|
||||||
@@ -1792,7 +1796,7 @@ export default {
|
|||||||
return option?.dictValue || value;
|
return option?.dictValue || value;
|
||||||
},
|
},
|
||||||
formatDetailMileage(value) {
|
formatDetailMileage(value) {
|
||||||
if (value === undefined || value === null || value === '' || Number(value) === -1) return '';
|
if (value === undefined || value === null || value === '' || Number(value) === -1) return '-';
|
||||||
return value;
|
return value;
|
||||||
},
|
},
|
||||||
removeSummaryFee(index) {
|
removeSummaryFee(index) {
|
||||||
|
|||||||
@@ -272,7 +272,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, onMounted, reactive, ref } from 'vue';
|
import { computed, getCurrentInstance, onMounted, reactive, ref } from 'vue';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||||
import { QuestionFilled } from '@element-plus/icons-vue';
|
import { QuestionFilled } from '@element-plus/icons-vue';
|
||||||
@@ -284,6 +284,8 @@ import { downloadXls } from '@/utils/util';
|
|||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const instance = getCurrentInstance();
|
||||||
|
const settlementImportListRefreshKey = 'settlement-import-list-refresh';
|
||||||
|
|
||||||
const formRef = ref();
|
const formRef = ref();
|
||||||
const uploadRef = ref();
|
const uploadRef = ref();
|
||||||
@@ -859,6 +861,12 @@ const goBack = () => {
|
|||||||
router.push({ path: '/settlement/settlement-import' });
|
router.push({ path: '/settlement/settlement-import' });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const leaveAfterConfirm = () => {
|
||||||
|
sessionStorage.setItem(settlementImportListRefreshKey, '1');
|
||||||
|
instance?.proxy?.$router?.$avueRouter?.closeTag?.();
|
||||||
|
router.push({ path: '/settlement/settlement-import' });
|
||||||
|
};
|
||||||
|
|
||||||
const downloadFailureExcel = async failureRows => {
|
const downloadFailureExcel = async failureRows => {
|
||||||
const response = await api.exportFailures({
|
const response = await api.exportFailures({
|
||||||
feeItemNames: [...feeItemNames.value],
|
feeItemNames: [...feeItemNames.value],
|
||||||
@@ -942,7 +950,7 @@ const confirmImport = async () => {
|
|||||||
const batch = unwrapData(response) || {};
|
const batch = unwrapData(response) || {};
|
||||||
if (batch.batchNo) form.batchNo = batch.batchNo;
|
if (batch.batchNo) form.batchNo = batch.batchNo;
|
||||||
ElMessage.success('确认导入成功');
|
ElMessage.success('确认导入成功');
|
||||||
goBack();
|
leaveAfterConfirm();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error === 'cancel' || error === 'close') return;
|
if (error === 'cancel' || error === 'close') return;
|
||||||
ElMessage.error(error?.message || '确认导入失败');
|
ElMessage.error(error?.message || '确认导入失败');
|
||||||
|
|||||||
@@ -1278,10 +1278,13 @@ export default {
|
|||||||
delete snapshot._externalKey;
|
delete snapshot._externalKey;
|
||||||
delete snapshot.feeItems;
|
delete snapshot.feeItems;
|
||||||
snapshot.feeItemsJson = row.feeItemsJson || JSON.stringify(row.feeItems || {});
|
snapshot.feeItemsJson = row.feeItemsJson || JSON.stringify(row.feeItems || {});
|
||||||
|
snapshot.actualDepartureTime = this.normalizeExternalDateTime(row.actualDepartureTime);
|
||||||
|
snapshot.actualCompletionTime = this.normalizeExternalDateTime(row.actualCompletionTime);
|
||||||
return snapshot;
|
return snapshot;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
serializeExternalRows() {
|
serializeExternalRows() {
|
||||||
|
const duplicateIds = new Set(this.duplicateRows.map(row => String(row.id)));
|
||||||
return this.externalDetails.map(row => {
|
return this.externalDetails.map(row => {
|
||||||
const snapshot = { ...row };
|
const snapshot = { ...row };
|
||||||
delete snapshot._sourceRows;
|
delete snapshot._sourceRows;
|
||||||
@@ -1290,6 +1293,7 @@ export default {
|
|||||||
snapshot.feeItemsJson = row.feeItemsJson || JSON.stringify(row.feeItems || {});
|
snapshot.feeItemsJson = row.feeItemsJson || JSON.stringify(row.feeItems || {});
|
||||||
snapshot.actualDepartureTime = this.normalizeExternalDateTime(row.actualDepartureTime);
|
snapshot.actualDepartureTime = this.normalizeExternalDateTime(row.actualDepartureTime);
|
||||||
snapshot.actualCompletionTime = this.normalizeExternalDateTime(row.actualCompletionTime);
|
snapshot.actualCompletionTime = this.normalizeExternalDateTime(row.actualCompletionTime);
|
||||||
|
snapshot.suspectedDuplicate = duplicateIds.has(String(row.id));
|
||||||
return snapshot;
|
return snapshot;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -1336,6 +1340,11 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
async handleComplete() {
|
async handleComplete() {
|
||||||
|
const unmatchedInternal = this.internalDetails.filter(item => item.matchResult !== 'matched').length;
|
||||||
|
const unmatchedExternal = this.externalDetails.filter(item => item.matchStatus !== 'matched').length;
|
||||||
|
if (this.duplicateRows.length || unmatchedInternal || unmatchedExternal) {
|
||||||
|
return this.$message.warning('所有内外部账单明细必须一一匹配且不存在疑似重复');
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
Number(this.form.differenceCount || 0) !== 0 ||
|
Number(this.form.differenceCount || 0) !== 0 ||
|
||||||
Number(this.form.differenceQuantity || 0) !== 0 ||
|
Number(this.form.differenceQuantity || 0) !== 0 ||
|
||||||
@@ -1694,8 +1703,11 @@ export default {
|
|||||||
},
|
},
|
||||||
normalizeExternalDateTime(value) {
|
normalizeExternalDateTime(value) {
|
||||||
if (!value) return null;
|
if (!value) return null;
|
||||||
const text = String(value);
|
const text = String(value).trim();
|
||||||
return text.length === 10 ? `${text}T00:00:00` : text;
|
if (!text) return null;
|
||||||
|
const date = this.$dayjs(text);
|
||||||
|
if (date.isValid()) return date.format('YYYY-MM-DD HH:mm:ss');
|
||||||
|
return text.length === 10 ? `${text} 00:00:00` : text.replace('T', ' ');
|
||||||
},
|
},
|
||||||
refreshLocalStats() {
|
refreshLocalStats() {
|
||||||
const internalQuantity = this.internalDetails.reduce(
|
const internalQuantity = this.internalDetails.reduce(
|
||||||
|
|||||||
@@ -2691,12 +2691,12 @@ export default {
|
|||||||
return `${Number(value).toFixed(2)} ${currency}`;
|
return `${Number(value).toFixed(2)} ${currency}`;
|
||||||
},
|
},
|
||||||
formatDetailCell(row, prop) {
|
formatDetailCell(row, prop) {
|
||||||
|
if (prop === 'mileage' && Number(row?.[prop]) === -1) {
|
||||||
|
return '-';
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
prop === 'mileage' &&
|
prop === 'mileage' &&
|
||||||
(row?.[prop] === null ||
|
(row?.[prop] === null || row?.[prop] === undefined || row?.[prop] === '')
|
||||||
row?.[prop] === undefined ||
|
|
||||||
row?.[prop] === '' ||
|
|
||||||
Number(row[prop]) === -1)
|
|
||||||
) {
|
) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -211,6 +211,8 @@ const SETTLEMENT_TYPE_OPTIONS = [
|
|||||||
{ label: '应付正式结算单', value: 'payable' },
|
{ label: '应付正式结算单', value: 'payable' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const SETTLEMENT_IMPORT_LIST_REFRESH_KEY = 'settlement-import-list-refresh';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SettlementImport',
|
name: 'SettlementImport',
|
||||||
data() {
|
data() {
|
||||||
@@ -270,7 +272,29 @@ export default {
|
|||||||
this.loadOptions();
|
this.loadOptions();
|
||||||
this.loadTable();
|
this.loadTable();
|
||||||
},
|
},
|
||||||
|
activated() {
|
||||||
|
this.consumeListRefresh();
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
$route(to, from) {
|
||||||
|
if (
|
||||||
|
to.path === '/settlement/settlement-import' &&
|
||||||
|
from?.path === '/settlement/settlement-import/form'
|
||||||
|
) {
|
||||||
|
this.consumeListRefresh();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
consumeListRefresh() {
|
||||||
|
if (sessionStorage.getItem(SETTLEMENT_IMPORT_LIST_REFRESH_KEY) !== '1') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sessionStorage.removeItem(SETTLEMENT_IMPORT_LIST_REFRESH_KEY);
|
||||||
|
this.page.current = 1;
|
||||||
|
this.loadOptions();
|
||||||
|
this.loadTable();
|
||||||
|
},
|
||||||
hasPermission(code) {
|
hasPermission(code) {
|
||||||
return this.isAdmin || this.validData(this.permission?.[code], false);
|
return this.isAdmin || this.validData(this.permission?.[code], false);
|
||||||
},
|
},
|
||||||
|
|||||||
+101
-35
@@ -153,7 +153,12 @@
|
|||||||
/>
|
/>
|
||||||
<div class="oa-sync-meta" v-if="oaSyncStage === 'clear'">当前阶段:{{ oaSyncStageLabel }}</div>
|
<div class="oa-sync-meta" v-if="oaSyncStage === 'clear'">当前阶段:{{ oaSyncStageLabel }}</div>
|
||||||
<div class="oa-sync-meta" v-else>
|
<div class="oa-sync-meta" v-else>
|
||||||
当前阶段:{{ oaSyncStageLabel }},第 {{ oaSyncProgress.current || 0 }} / {{ oaSyncTotalPage }} 页
|
当前阶段:{{ oaSyncStageLabel }}
|
||||||
|
<template v-if="oaSyncStage === 'department' && oaSyncProgress.companyTotal">
|
||||||
|
,公司 {{ oaSyncProgress.companyIndex || 0 }} / {{ oaSyncProgress.companyTotal }}
|
||||||
|
<template v-if="oaSyncProgress.companyOaId">(oaId={{ oaSyncProgress.companyOaId }})</template>
|
||||||
|
</template>
|
||||||
|
,第 {{ oaSyncProgress.current || 0 }} / {{ oaSyncTotalPage }} 页
|
||||||
</div>
|
</div>
|
||||||
<div class="oa-sync-stats">
|
<div class="oa-sync-stats">
|
||||||
<div class="oa-sync-stat">
|
<div class="oa-sync-stat">
|
||||||
@@ -257,6 +262,9 @@ export default {
|
|||||||
synced: 0,
|
synced: 0,
|
||||||
skipped: 0,
|
skipped: 0,
|
||||||
dumpFilePath: '',
|
dumpFilePath: '',
|
||||||
|
companyOaId: '',
|
||||||
|
companyIndex: 0,
|
||||||
|
companyTotal: 0,
|
||||||
},
|
},
|
||||||
parentId: 0,
|
parentId: 0,
|
||||||
page: {
|
page: {
|
||||||
@@ -290,7 +298,9 @@ export default {
|
|||||||
{
|
{
|
||||||
label: '组织名称',
|
label: '组织名称',
|
||||||
prop: 'deptName',
|
prop: 'deptName',
|
||||||
minWidth: 160,
|
minWidth: 320,
|
||||||
|
align: 'left',
|
||||||
|
headerAlign: 'left',
|
||||||
order: 80,
|
order: 80,
|
||||||
search: true,
|
search: true,
|
||||||
searchOrder: 2,
|
searchOrder: 2,
|
||||||
@@ -642,12 +652,18 @@ export default {
|
|||||||
}
|
}
|
||||||
const totalPage = this.oaSyncTotalPage;
|
const totalPage = this.oaSyncTotalPage;
|
||||||
const current = Number(this.oaSyncProgress.current) || 0;
|
const current = Number(this.oaSyncProgress.current) || 0;
|
||||||
const stageBase = this.oaSyncStage === 'department' ? 50 : 0;
|
if (this.oaSyncStage === 'department') {
|
||||||
if (totalPage <= 0) {
|
const companyTotal = Math.max(1, Number(this.oaSyncProgress.companyTotal) || 1);
|
||||||
return stageBase;
|
const companyIndex = Math.max(1, Number(this.oaSyncProgress.companyIndex) || 1);
|
||||||
|
const companyBase = ((companyIndex - 1) / companyTotal) * 50;
|
||||||
|
const pageRatio = totalPage > 0 ? Math.min(1, current / totalPage) : 0;
|
||||||
|
const companyPagePercent = (pageRatio * 50) / companyTotal;
|
||||||
|
return Math.min(99, Math.round(50 + companyBase + companyPagePercent));
|
||||||
}
|
}
|
||||||
const stagePercent = Math.min(50, Math.round((current / totalPage) * 50));
|
if (totalPage <= 0) {
|
||||||
return Math.min(99, stageBase + stagePercent);
|
return 0;
|
||||||
|
}
|
||||||
|
return Math.min(49, Math.round((current / totalPage) * 50));
|
||||||
},
|
},
|
||||||
oaSyncProgressStatus() {
|
oaSyncProgressStatus() {
|
||||||
if (this.oaSyncStatus === 'done') {
|
if (this.oaSyncStatus === 'done') {
|
||||||
@@ -661,25 +677,7 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleOaOrgFullSync() {
|
handleOaOrgFullSync() {
|
||||||
this.$confirm(
|
this.startOaOrgSync({ clearNonTop: false, incremental: false });
|
||||||
'全量同步将拉取 OA 公司/部门(仅保留二级公司 oaId=2、135 及其子公司与部门);已存在且 OA 更新时间一致的记录会跳过。是否清除后同步?选择“是”将保留顶级「外部组织」与集团锚点(id=1/GWWL),删除其余组织后再同步;选择“否”则直接全量同步。',
|
|
||||||
'全量同步',
|
|
||||||
{
|
|
||||||
confirmButtonText: '是',
|
|
||||||
cancelButtonText: '否',
|
|
||||||
distinguishCancelAndClose: true,
|
|
||||||
closeOnClickModal: false,
|
|
||||||
type: 'warning',
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.then(() => {
|
|
||||||
this.startOaOrgSync({ clearNonTop: true, incremental: false });
|
|
||||||
})
|
|
||||||
.catch(action => {
|
|
||||||
if (action === 'cancel') {
|
|
||||||
this.startOaOrgSync({ clearNonTop: false, incremental: false });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
handleOaOrgIncrementalSync() {
|
handleOaOrgIncrementalSync() {
|
||||||
this.$confirm(
|
this.$confirm(
|
||||||
@@ -714,6 +712,9 @@ export default {
|
|||||||
synced: 0,
|
synced: 0,
|
||||||
skipped: 0,
|
skipped: 0,
|
||||||
dumpFilePath: '',
|
dumpFilePath: '',
|
||||||
|
companyOaId: '',
|
||||||
|
companyIndex: 0,
|
||||||
|
companyTotal: 0,
|
||||||
};
|
};
|
||||||
this.runOaOrgSyncPages();
|
this.runOaOrgSyncPages();
|
||||||
},
|
},
|
||||||
@@ -725,6 +726,25 @@ export default {
|
|||||||
error?.name === 'AbortError'
|
error?.name === 'AbortError'
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
applyOaOrgSyncPage(page, current, size) {
|
||||||
|
this.oaSyncProgress.current = page.current || current;
|
||||||
|
this.oaSyncProgress.size = page.size || size;
|
||||||
|
this.oaSyncProgress.total = page.total || 0;
|
||||||
|
this.oaSyncProgress.synced += page.syncedCount || 0;
|
||||||
|
this.oaSyncProgress.skipped += page.skippedCount || 0;
|
||||||
|
if (page.dumpFilePath) {
|
||||||
|
this.oaSyncProgress.dumpFilePath = page.dumpFilePath;
|
||||||
|
}
|
||||||
|
if (page.companyOaId != null) {
|
||||||
|
this.oaSyncProgress.companyOaId = page.companyOaId || '';
|
||||||
|
}
|
||||||
|
if (page.companyIndex != null) {
|
||||||
|
this.oaSyncProgress.companyIndex = page.companyIndex || 0;
|
||||||
|
}
|
||||||
|
if (page.companyTotal != null) {
|
||||||
|
this.oaSyncProgress.companyTotal = page.companyTotal || 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
async runOaOrgSyncStage(syncApi) {
|
async runOaOrgSyncStage(syncApi) {
|
||||||
const size = 20;
|
const size = 20;
|
||||||
const incremental = this.oaSyncMode === 'incremental';
|
const incremental = this.oaSyncMode === 'incremental';
|
||||||
@@ -742,20 +762,57 @@ export default {
|
|||||||
if (!modifiedSince && page.modifiedSince) {
|
if (!modifiedSince && page.modifiedSince) {
|
||||||
modifiedSince = page.modifiedSince;
|
modifiedSince = page.modifiedSince;
|
||||||
}
|
}
|
||||||
this.oaSyncProgress.current = page.current || current;
|
this.applyOaOrgSyncPage(page, current, size);
|
||||||
this.oaSyncProgress.size = page.size || size;
|
|
||||||
this.oaSyncProgress.total = page.total || 0;
|
|
||||||
this.oaSyncProgress.synced += page.syncedCount || 0;
|
|
||||||
this.oaSyncProgress.skipped += page.skippedCount || 0;
|
|
||||||
if (page.dumpFilePath) {
|
|
||||||
this.oaSyncProgress.dumpFilePath = page.dumpFilePath;
|
|
||||||
}
|
|
||||||
if (page.finished) {
|
if (page.finished) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
current += 1;
|
current += 1;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* 部门阶段:公司同步完成后,按公司 oaId 轮询;当前公司部门拉完后切换下一公司并重置页码
|
||||||
|
*/
|
||||||
|
async runOaOrgDepartmentSyncStage() {
|
||||||
|
const size = 20;
|
||||||
|
const incremental = this.oaSyncMode === 'incremental';
|
||||||
|
let current = 1;
|
||||||
|
let modifiedSince = '';
|
||||||
|
let companyOaId = '';
|
||||||
|
while (!this.oaSyncCancelled) {
|
||||||
|
const res = await syncOaDepartment(
|
||||||
|
current,
|
||||||
|
size,
|
||||||
|
this.oaSyncController?.signal,
|
||||||
|
incremental,
|
||||||
|
modifiedSince,
|
||||||
|
companyOaId
|
||||||
|
);
|
||||||
|
const page = res?.data?.data || {};
|
||||||
|
if (!modifiedSince && page.modifiedSince) {
|
||||||
|
modifiedSince = page.modifiedSince;
|
||||||
|
}
|
||||||
|
if (page.companyOaId) {
|
||||||
|
companyOaId = page.companyOaId;
|
||||||
|
}
|
||||||
|
this.applyOaOrgSyncPage(page, current, size);
|
||||||
|
if (page.finished) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (page.companyFinished && page.nextCompanyOaId) {
|
||||||
|
companyOaId = page.nextCompanyOaId;
|
||||||
|
current = 1;
|
||||||
|
this.oaSyncProgress.current = 0;
|
||||||
|
this.oaSyncProgress.total = 0;
|
||||||
|
// 单公司部门拉完并重建层级后刷新树,便于中途核对挂载结果
|
||||||
|
this.parentId = 0;
|
||||||
|
this.data = [];
|
||||||
|
this.$refs.crud?.refreshTable?.();
|
||||||
|
this.onLoad(this.page, this.query);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
current += 1;
|
||||||
|
}
|
||||||
|
},
|
||||||
async runOaOrgSyncPages() {
|
async runOaOrgSyncPages() {
|
||||||
try {
|
try {
|
||||||
if (this.oaSyncClearNonTop) {
|
if (this.oaSyncClearNonTop) {
|
||||||
@@ -775,7 +832,10 @@ export default {
|
|||||||
this.oaSyncStage = 'department';
|
this.oaSyncStage = 'department';
|
||||||
this.oaSyncProgress.current = 0;
|
this.oaSyncProgress.current = 0;
|
||||||
this.oaSyncProgress.total = 0;
|
this.oaSyncProgress.total = 0;
|
||||||
await this.runOaOrgSyncStage(syncOaDepartment);
|
this.oaSyncProgress.companyOaId = '';
|
||||||
|
this.oaSyncProgress.companyIndex = 0;
|
||||||
|
this.oaSyncProgress.companyTotal = 0;
|
||||||
|
await this.runOaOrgDepartmentSyncStage();
|
||||||
if (this.oaSyncCancelled) {
|
if (this.oaSyncCancelled) {
|
||||||
this.oaSyncStatus = 'cancelled';
|
this.oaSyncStatus = 'cancelled';
|
||||||
return;
|
return;
|
||||||
@@ -1460,6 +1520,12 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
/* 覆盖全站表格居中:树形组织名称需左对齐,展开后缩进才可读 */
|
||||||
|
:deep(.el-table th.el-table__cell.is-left .cell),
|
||||||
|
:deep(.el-table td.el-table__cell.is-left .cell) {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
.carrier-search-form {
|
.carrier-search-form {
|
||||||
padding: 12px 12px 4px;
|
padding: 12px 12px 4px;
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ import { exportBlob } from '@/api/common';
|
|||||||
import { downloadXls } from '@/utils/util';
|
import { downloadXls } from '@/utils/util';
|
||||||
import { openImportDialog } from '@/utils/import-excel';
|
import { openImportDialog } from '@/utils/import-excel';
|
||||||
import { getToken, isAdministrator } from '@/utils/auth';
|
import { getToken, isAdministrator } from '@/utils/auth';
|
||||||
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
import { applyIncomingSearch, normalizeSearchRangeParams } from '@/utils/search-range';
|
||||||
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { excelOption, exportColumns, option } from '@/option/vehicle/accident-record';
|
import { excelOption, exportColumns, option } from '@/option/vehicle/accident-record';
|
||||||
@@ -550,7 +550,7 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
buildQuery(params = {}) {
|
buildQuery(params = {}) {
|
||||||
return normalizeSearchRangeParams({ ...params, ...this.query }, createTimeRangeMap);
|
return normalizeSearchRangeParams(applyIncomingSearch(this.query, params), createTimeRangeMap);
|
||||||
},
|
},
|
||||||
handleTemplate() {
|
handleTemplate() {
|
||||||
exportBlob(
|
exportBlob(
|
||||||
|
|||||||
@@ -468,7 +468,11 @@ import {
|
|||||||
publish,
|
publish,
|
||||||
changeStatus,
|
changeStatus,
|
||||||
} from '@/api/vehicle/credit-score-quantification';
|
} from '@/api/vehicle/credit-score-quantification';
|
||||||
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
import {
|
||||||
|
applyIncomingSearch,
|
||||||
|
normalizeSearchRangeParams,
|
||||||
|
omitInvalidListStatus,
|
||||||
|
} from '@/utils/search-range';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { isAdministrator } from '@/utils/auth';
|
import { isAdministrator } from '@/utils/auth';
|
||||||
|
|
||||||
@@ -1324,7 +1328,9 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
buildQuery(params = {}) {
|
buildQuery(params = {}) {
|
||||||
return normalizeSearchRangeParams({ ...params, ...this.query }, createTimeRangeMap);
|
return omitInvalidListStatus(
|
||||||
|
normalizeSearchRangeParams(applyIncomingSearch(this.query, params), createTimeRangeMap)
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2043,7 +2043,6 @@ export default {
|
|||||||
search: true,
|
search: true,
|
||||||
searchOrder: 6,
|
searchOrder: 6,
|
||||||
searchValue: '',
|
searchValue: '',
|
||||||
dataType: 'number',
|
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
dicData: [
|
dicData: [
|
||||||
{ label: '全部', value: '' },
|
{ label: '全部', value: '' },
|
||||||
@@ -5297,19 +5296,9 @@ export default {
|
|||||||
this.onLoad(this.page);
|
this.onLoad(this.page);
|
||||||
},
|
},
|
||||||
searchChange(params, done) {
|
searchChange(params, done) {
|
||||||
// 搜索区所属组织级联返回的是 ID 路径数组,取末级 ID 转成部门名称传给后端(与列表接口 deptName 字段一致)
|
|
||||||
if (Array.isArray(params.deptName)) {
|
|
||||||
const path = params.deptName.filter(
|
|
||||||
item => item !== undefined && item !== null && item !== ''
|
|
||||||
);
|
|
||||||
const deptId = path.length ? path[path.length - 1] : '';
|
|
||||||
params.deptName = deptId
|
|
||||||
? this.deptOptions.find(item => String(item.value) === String(deptId))?.rawLabel || ''
|
|
||||||
: '';
|
|
||||||
}
|
|
||||||
this.query = this.buildQuery(params);
|
this.query = this.buildQuery(params);
|
||||||
this.page.currentPage = 1;
|
this.page.currentPage = 1;
|
||||||
this.onLoad(this.page);
|
this.onLoad(this.page, this.query);
|
||||||
done();
|
done();
|
||||||
},
|
},
|
||||||
selectionChange(list) {
|
selectionChange(list) {
|
||||||
@@ -5370,7 +5359,38 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
buildQuery(params = {}) {
|
buildQuery(params = {}) {
|
||||||
return normalizeSearchRangeParams({ ...params, ...this.query }, createTimeRangeMap);
|
// 新条件覆盖旧条件;本次显式清空的字段必须从查询里去掉,避免第二次搜索仍带着上一次的客商名称。
|
||||||
|
const merged = { ...this.query, ...params };
|
||||||
|
Object.keys(params).forEach(key => {
|
||||||
|
const value = params[key];
|
||||||
|
if (
|
||||||
|
value === '' ||
|
||||||
|
value === null ||
|
||||||
|
value === undefined ||
|
||||||
|
(Array.isArray(value) && value.length === 0)
|
||||||
|
) {
|
||||||
|
delete merged[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (Array.isArray(merged.deptName)) {
|
||||||
|
const path = merged.deptName.filter(
|
||||||
|
item => item !== undefined && item !== null && item !== ''
|
||||||
|
);
|
||||||
|
const deptId = path.length ? path[path.length - 1] : '';
|
||||||
|
merged.deptName = deptId
|
||||||
|
? this.deptOptions.find(item => String(item.value) === String(deptId))?.rawLabel || ''
|
||||||
|
: '';
|
||||||
|
if (!merged.deptName) {
|
||||||
|
delete merged.deptName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const values = normalizeSearchRangeParams(merged, createTimeRangeMap);
|
||||||
|
// 状态下拉「全部」会被数字类型转成 0/-1,二次搜索会把列表滤空。
|
||||||
|
const status = values.status;
|
||||||
|
if (status === 0 || status === '0' || status === -1 || status === '-1') {
|
||||||
|
delete values.status;
|
||||||
|
}
|
||||||
|
return values;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ import { downloadXls } from '@/utils/util';
|
|||||||
import { handleImportExcel } from '@/utils/import-excel';
|
import { handleImportExcel } from '@/utils/import-excel';
|
||||||
import { getToken, isAdministrator } from '@/utils/auth';
|
import { getToken, isAdministrator } from '@/utils/auth';
|
||||||
import { getUploadHeaders } from '@/utils/upload';
|
import { getUploadHeaders } from '@/utils/upload';
|
||||||
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
import { applyIncomingSearch, normalizeSearchRangeParams } from '@/utils/search-range';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { ElLoading } from 'element-plus';
|
import { ElLoading } from 'element-plus';
|
||||||
import { excelOption, exportColumns, option } from '@/option/vehicle/insurance-record';
|
import { excelOption, exportColumns, option } from '@/option/vehicle/insurance-record';
|
||||||
@@ -409,7 +409,7 @@ export default {
|
|||||||
: integerPart;
|
: integerPart;
|
||||||
},
|
},
|
||||||
buildQuery(params = {}) {
|
buildQuery(params = {}) {
|
||||||
return normalizeSearchRangeParams({ ...params, ...this.query }, createTimeRangeMap);
|
return normalizeSearchRangeParams(applyIncomingSearch(this.query, params), createTimeRangeMap);
|
||||||
},
|
},
|
||||||
validateRow(row) {
|
validateRow(row) {
|
||||||
if (row.startDate && row.endDate && row.endDate < row.startDate) {
|
if (row.startDate && row.endDate && row.endDate < row.startDate) {
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ import { downloadXls } from '@/utils/util';
|
|||||||
import { openImportDialog } from '@/utils/import-excel';
|
import { openImportDialog } from '@/utils/import-excel';
|
||||||
import { formatUpdateUserName } from '@/utils/audit';
|
import { formatUpdateUserName } from '@/utils/audit';
|
||||||
import { getToken, isAdministrator } from '@/utils/auth';
|
import { getToken, isAdministrator } from '@/utils/auth';
|
||||||
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
import { applyIncomingSearch, normalizeSearchRangeParams } from '@/utils/search-range';
|
||||||
import AddressMapPicker from '@/components/address-map-picker/main.vue';
|
import AddressMapPicker from '@/components/address-map-picker/main.vue';
|
||||||
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
@@ -903,7 +903,7 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
buildQuery(params = {}) {
|
buildQuery(params = {}) {
|
||||||
return normalizeSearchRangeParams({ ...params, ...this.query }, createTimeRangeMap);
|
return normalizeSearchRangeParams(applyIncomingSearch(this.query, params), createTimeRangeMap);
|
||||||
},
|
},
|
||||||
handleTemplate() {
|
handleTemplate() {
|
||||||
exportBlob(
|
exportBlob(
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ import { downloadXls } from '@/utils/util';
|
|||||||
import { openImportDialog } from '@/utils/import-excel';
|
import { openImportDialog } from '@/utils/import-excel';
|
||||||
import { formatUpdateUserName } from '@/utils/audit';
|
import { formatUpdateUserName } from '@/utils/audit';
|
||||||
import { getToken, isAdministrator } from '@/utils/auth';
|
import { getToken, isAdministrator } from '@/utils/auth';
|
||||||
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
import { applyIncomingSearch, normalizeSearchRangeParams } from '@/utils/search-range';
|
||||||
import AddressMapPicker from '@/components/address-map-picker/main.vue';
|
import AddressMapPicker from '@/components/address-map-picker/main.vue';
|
||||||
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
@@ -831,7 +831,7 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
buildQuery(params = {}) {
|
buildQuery(params = {}) {
|
||||||
return normalizeSearchRangeParams({ ...params, ...this.query }, createTimeRangeMap);
|
return normalizeSearchRangeParams(applyIncomingSearch(this.query, params), createTimeRangeMap);
|
||||||
},
|
},
|
||||||
handleTemplate() {
|
handleTemplate() {
|
||||||
exportBlob(
|
exportBlob(
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ import { exportBlob } from '@/api/common';
|
|||||||
import { downloadXls } from '@/utils/util';
|
import { downloadXls } from '@/utils/util';
|
||||||
import { openImportDialog } from '@/utils/import-excel';
|
import { openImportDialog } from '@/utils/import-excel';
|
||||||
import { getToken, isAdministrator } from '@/utils/auth';
|
import { getToken, isAdministrator } from '@/utils/auth';
|
||||||
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
import { applyIncomingSearch, normalizeSearchRangeParams } from '@/utils/search-range';
|
||||||
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { excelOption, exportColumns, option } from '@/option/vehicle/mileage-record';
|
import { excelOption, exportColumns, option } from '@/option/vehicle/mileage-record';
|
||||||
@@ -607,7 +607,7 @@ export default {
|
|||||||
},
|
},
|
||||||
buildQuery(params = {}) {
|
buildQuery(params = {}) {
|
||||||
return normalizeSearchRangeParams(
|
return normalizeSearchRangeParams(
|
||||||
{ ...params, ...this.query, vehicleType: '车辆' },
|
{ ...applyIncomingSearch(this.query, params), vehicleType: '车辆' },
|
||||||
createTimeRangeMap
|
createTimeRangeMap
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ import { exportBlob } from '@/api/common';
|
|||||||
import { downloadXls } from '@/utils/util';
|
import { downloadXls } from '@/utils/util';
|
||||||
import { openImportDialog } from '@/utils/import-excel';
|
import { openImportDialog } from '@/utils/import-excel';
|
||||||
import { getToken, isAdministrator } from '@/utils/auth';
|
import { getToken, isAdministrator } from '@/utils/auth';
|
||||||
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
import { applyIncomingSearch, normalizeSearchRangeParams } from '@/utils/search-range';
|
||||||
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { excelOption, exportColumns, option } from '@/option/vehicle/tire-replacement-record';
|
import { excelOption, exportColumns, option } from '@/option/vehicle/tire-replacement-record';
|
||||||
@@ -500,7 +500,7 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
buildQuery(params = {}) {
|
buildQuery(params = {}) {
|
||||||
return normalizeSearchRangeParams({ ...params, ...this.query }, createTimeRangeMap);
|
return normalizeSearchRangeParams(applyIncomingSearch(this.query, params), createTimeRangeMap);
|
||||||
},
|
},
|
||||||
handleTemplate() {
|
handleTemplate() {
|
||||||
exportBlob(
|
exportBlob(
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ import { exportBlob } from '@/api/common';
|
|||||||
import { downloadXls } from '@/utils/util';
|
import { downloadXls } from '@/utils/util';
|
||||||
import { openImportDialog } from '@/utils/import-excel';
|
import { openImportDialog } from '@/utils/import-excel';
|
||||||
import { getToken, isAdministrator } from '@/utils/auth';
|
import { getToken, isAdministrator } from '@/utils/auth';
|
||||||
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
import { applyIncomingSearch, normalizeSearchRangeParams } from '@/utils/search-range';
|
||||||
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { excelOption, exportColumns, option } from '@/option/vehicle/transport-change-record';
|
import { excelOption, exportColumns, option } from '@/option/vehicle/transport-change-record';
|
||||||
@@ -478,7 +478,7 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
buildQuery(params = {}) {
|
buildQuery(params = {}) {
|
||||||
return normalizeSearchRangeParams({ ...params, ...this.query }, createTimeRangeMap);
|
return normalizeSearchRangeParams(applyIncomingSearch(this.query, params), createTimeRangeMap);
|
||||||
},
|
},
|
||||||
handleTemplate() {
|
handleTemplate() {
|
||||||
exportBlob(
|
exportBlob(
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ import { exportBlob } from '@/api/common';
|
|||||||
import { downloadXls } from '@/utils/util';
|
import { downloadXls } from '@/utils/util';
|
||||||
import { openImportDialog } from '@/utils/import-excel';
|
import { openImportDialog } from '@/utils/import-excel';
|
||||||
import { getToken, isAdministrator } from '@/utils/auth';
|
import { getToken, isAdministrator } from '@/utils/auth';
|
||||||
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
import { applyIncomingSearch, normalizeSearchRangeParams } from '@/utils/search-range';
|
||||||
import AddressMapPicker from '@/components/address-map-picker/main.vue';
|
import AddressMapPicker from '@/components/address-map-picker/main.vue';
|
||||||
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
@@ -673,7 +673,7 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
buildQuery(params = {}) {
|
buildQuery(params = {}) {
|
||||||
return normalizeSearchRangeParams({ ...params, ...this.query }, createTimeRangeMap);
|
return normalizeSearchRangeParams(applyIncomingSearch(this.query, params), createTimeRangeMap);
|
||||||
},
|
},
|
||||||
handleTemplate() {
|
handleTemplate() {
|
||||||
exportBlob(
|
exportBlob(
|
||||||
|
|||||||
Reference in New Issue
Block a user