项目、合同fix
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
@current-change="currentChange"
|
||||
@size-change="sizeChange"
|
||||
@refresh-change="refreshChange"
|
||||
@search-icon-change="handleSearchIconChange"
|
||||
@on-load="onLoad"
|
||||
>
|
||||
<template #menu-left>
|
||||
@@ -113,11 +114,35 @@
|
||||
|
||||
<template #contractCategory-label>合同类型</template>
|
||||
|
||||
<template v-if="config.enableContractExpiryTags" #search-menu>
|
||||
<div v-show="searchExpanded" class="business-crud-page__contract-expiry-search">
|
||||
<span class="business-crud-page__contract-expiry-label">签约类型:</span>
|
||||
<el-select v-model="contractSignType" clearable placeholder="请选择">
|
||||
<el-option
|
||||
v-for="item in contractSignTypeOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<div class="business-crud-page__contract-expiry-tags">
|
||||
<el-check-tag
|
||||
v-for="item in contractExpiryTagOptions"
|
||||
:key="item.value"
|
||||
:checked="contractExpiryScope === item.value"
|
||||
@change="handleContractExpiryScopeChange(item.value)"
|
||||
>
|
||||
{{ item.label }}({{ contractExpiryStats[item.statKey] || 0 }})
|
||||
</el-check-tag>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #projectName-form>
|
||||
<el-select
|
||||
v-model="selectedProjectId"
|
||||
class="business-crud-page__field"
|
||||
placeholder="请选择项目名称"
|
||||
:placeholder="config.projectPlaceholder || '请选择项目名称'"
|
||||
filterable
|
||||
clearable
|
||||
:loading="projectLoading"
|
||||
@@ -1220,7 +1245,7 @@
|
||||
<el-cascader
|
||||
v-model="selectedOrganizationId"
|
||||
class="business-crud-page__field"
|
||||
placeholder="请选择所属组织"
|
||||
:placeholder="config.organizationPlaceholder || '请选择所属组织'"
|
||||
:options="organizationOptions"
|
||||
:props="organizationCascaderProps"
|
||||
clearable
|
||||
@@ -1401,12 +1426,17 @@
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<el-form
|
||||
v-if="settlementRuleEnabled"
|
||||
:model="settlementRuleForm"
|
||||
label-position="right"
|
||||
label-width="auto"
|
||||
class="business-crud-page__module-form business-crud-page__module-form--three"
|
||||
>
|
||||
<el-form-item label="账单起始日期" required>
|
||||
<el-form-item
|
||||
label="账单起始日期"
|
||||
required
|
||||
:error="settlementRuleErrors.billStartDate"
|
||||
>
|
||||
<el-date-picker
|
||||
v-model="settlementRuleForm.billStartDate"
|
||||
type="date"
|
||||
@@ -1414,9 +1444,10 @@
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
:disabled="dialogReadonly"
|
||||
@change="clearSettlementRuleError('billStartDate')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="结算类型" required>
|
||||
<el-form-item label="结算类型" required :error="settlementRuleErrors.settlementType">
|
||||
<el-select
|
||||
v-model="settlementRuleForm.settlementType"
|
||||
placeholder="请选择结算类型"
|
||||
@@ -1431,7 +1462,12 @@
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="showSettlementBillCycleType" label="账单周期类型" required>
|
||||
<el-form-item
|
||||
v-if="showSettlementBillCycleType"
|
||||
label="账单周期类型"
|
||||
required
|
||||
:error="settlementRuleErrors.billCycleType"
|
||||
>
|
||||
<el-select
|
||||
v-model="settlementRuleForm.billCycleType"
|
||||
placeholder="请选择账单周期类型"
|
||||
@@ -1446,11 +1482,17 @@
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="showSettlementBillCutoffDay" label="账单截单日">
|
||||
<el-form-item
|
||||
v-if="showSettlementBillCutoffDay"
|
||||
label="账单截单日"
|
||||
required
|
||||
:error="settlementRuleErrors.billCutoffDay"
|
||||
>
|
||||
<el-select
|
||||
v-model="settlementRuleForm.billCutoffDay"
|
||||
placeholder="请选择账单截单日"
|
||||
:disabled="dialogReadonly"
|
||||
@change="clearSettlementRuleError('billCutoffDay')"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in billCutoffDayOptions"
|
||||
@@ -1460,11 +1502,17 @@
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="showSettlementCycleDays" label="周期天数" required>
|
||||
<el-form-item
|
||||
v-if="showSettlementCycleDays"
|
||||
label="周期天数"
|
||||
required
|
||||
:error="settlementRuleErrors.cycleDays"
|
||||
>
|
||||
<el-select
|
||||
v-model="settlementRuleForm.cycleDays"
|
||||
placeholder="请选择周期天数"
|
||||
:disabled="dialogReadonly"
|
||||
@change="clearSettlementRuleError('cycleDays')"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in cycleDayOptions"
|
||||
@@ -2798,7 +2846,7 @@
|
||||
:title="billingPlanMode === 'edit' ? '编辑计费方案' : '添加计费方案'"
|
||||
append-to-body
|
||||
v-model="billingPlanBox"
|
||||
width="96%"
|
||||
width="90%"
|
||||
class="business-crud-page__billing-dialog"
|
||||
>
|
||||
<el-form
|
||||
@@ -2825,6 +2873,7 @@
|
||||
<el-form-item label="备注">
|
||||
<el-input
|
||||
v-model="billingPlanForm.remark"
|
||||
class="business-crud-page__billing-plan-remark"
|
||||
maxlength="100"
|
||||
show-word-limit
|
||||
:disabled="dialogReadonly"
|
||||
@@ -3956,6 +4005,7 @@ export default {
|
||||
cargoImportLoading: false,
|
||||
billingPlanRows: [],
|
||||
settlementRuleForm: defaultSettlementRule(),
|
||||
settlementRuleErrors: {},
|
||||
reconciliationForm: defaultReconciliation(),
|
||||
changeRecordRows: [],
|
||||
billingPlanBox: false,
|
||||
@@ -4033,9 +4083,23 @@ export default {
|
||||
total: 0,
|
||||
},
|
||||
selectionList: [],
|
||||
contractExpiryScope: '',
|
||||
contractSignType: '',
|
||||
searchExpanded: false,
|
||||
attachmentUploadMode: false,
|
||||
contractExpiryStats: {
|
||||
all: 0,
|
||||
within30: 0,
|
||||
within90: 0,
|
||||
over90: 0,
|
||||
expired: 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
if (this.config.enableAllDept && this.isAdmin) {
|
||||
this.allDept = 1;
|
||||
}
|
||||
if (this.config.enableProjectSelect) {
|
||||
this.loadProjectOptions();
|
||||
}
|
||||
@@ -4074,6 +4138,18 @@ export default {
|
||||
actionButtonLikeSearch() {
|
||||
return this.config.actionButtonLikeSearch === true;
|
||||
},
|
||||
contractSignTypeOptions() {
|
||||
return this.option.column?.find(column => column.prop === 'signType')?.dicData || [];
|
||||
},
|
||||
contractExpiryTagOptions() {
|
||||
return [
|
||||
{ label: '全部', value: '', statKey: 'all' },
|
||||
{ label: '30天内到期', value: 'within30', statKey: 'within30' },
|
||||
{ label: '90天内到期', value: 'within90', statKey: 'within90' },
|
||||
{ label: '90天以上', value: 'over90', statKey: 'over90' },
|
||||
{ label: '已到期', value: 'expired', statKey: 'expired' },
|
||||
];
|
||||
},
|
||||
contractSelectEnabled() {
|
||||
return this.config.enableContractSelect || this.config.enableTransportPlanForm;
|
||||
},
|
||||
@@ -4240,7 +4316,9 @@ export default {
|
||||
return this.isAdmin;
|
||||
},
|
||||
readonlyScope() {
|
||||
return this.config.enableAllDept && this.allDept === 1;
|
||||
return (
|
||||
this.config.enableAllDept && this.config.allDeptReadonly !== false && this.allDept === 1
|
||||
);
|
||||
},
|
||||
canCreate() {
|
||||
return this.hasPermission(`${this.config.permission}_add`) && !this.readonlyScope;
|
||||
@@ -4299,6 +4377,9 @@ export default {
|
||||
emitPath: true,
|
||||
};
|
||||
},
|
||||
settlementRuleEnabled() {
|
||||
return Number(this.settlementRuleForm.autoGenerate) === 1;
|
||||
},
|
||||
showSettlementBillCycleType() {
|
||||
return this.settlementRuleForm.settlementType === '月结';
|
||||
},
|
||||
@@ -4535,6 +4616,7 @@ export default {
|
||||
return;
|
||||
}
|
||||
if (action.action === 'edit' || action.action === 'attachmentUpload') {
|
||||
this.attachmentUploadMode = action.action === 'attachmentUpload';
|
||||
this.$refs.crud.rowEdit(row, index);
|
||||
return;
|
||||
}
|
||||
@@ -4712,6 +4794,7 @@ export default {
|
||||
return rule.settlementType === '固定天数周期结算';
|
||||
},
|
||||
handleSettlementTypeChange(value) {
|
||||
this.clearSettlementRuleError('settlementType');
|
||||
if (value === '月结') {
|
||||
if (!this.settlementRuleForm.billCycleType) {
|
||||
this.settlementRuleForm.billCycleType = '固定截单日';
|
||||
@@ -4729,6 +4812,7 @@ export default {
|
||||
}
|
||||
},
|
||||
handleSettlementBillCycleTypeChange(value) {
|
||||
this.clearSettlementRuleError('billCycleType');
|
||||
if (value === '固定截单日') {
|
||||
this.settlementRuleForm.billCutoffDay = this.settlementRuleForm.billCutoffDay || 25;
|
||||
return;
|
||||
@@ -4751,23 +4835,40 @@ export default {
|
||||
}
|
||||
return nextRule;
|
||||
},
|
||||
clearSettlementRuleError(field) {
|
||||
if (!this.settlementRuleErrors[field]) return;
|
||||
this.settlementRuleErrors = {
|
||||
...this.settlementRuleErrors,
|
||||
[field]: '',
|
||||
};
|
||||
},
|
||||
validateSettlementRule() {
|
||||
const rule = this.normalizeSettlementRule(this.settlementRuleForm);
|
||||
this.settlementRuleErrors = {};
|
||||
if (this.isBillingFieldEmpty(rule.billStartDate)) {
|
||||
this.settlementRuleErrors = { billStartDate: '请选择账单起始日期' };
|
||||
this.$message.warning('请选择账单起始日期');
|
||||
return false;
|
||||
}
|
||||
if (this.isBillingFieldEmpty(rule.settlementType)) {
|
||||
this.settlementRuleErrors = { settlementType: '请选择结算类型' };
|
||||
this.$message.warning('请选择结算类型');
|
||||
return false;
|
||||
}
|
||||
if (this.isMonthlySettlement(rule) && this.isBillingFieldEmpty(rule.billCycleType)) {
|
||||
this.settlementRuleErrors = { billCycleType: '请选择账单周期类型' };
|
||||
this.$message.warning('请选择账单周期类型');
|
||||
return false;
|
||||
}
|
||||
if (this.isFixedBillCutoffSettlement(rule)) {
|
||||
if (this.isBillingFieldEmpty(rule.billCutoffDay)) {
|
||||
this.settlementRuleErrors = { billCutoffDay: '请选择账单截单日' };
|
||||
this.$message.warning('请选择账单截单日');
|
||||
return false;
|
||||
}
|
||||
const billCutoffDay = Number(rule.billCutoffDay);
|
||||
if (!Number.isInteger(billCutoffDay) || billCutoffDay < 1 || billCutoffDay > 31) {
|
||||
this.settlementRuleErrors = { billCutoffDay: '账单截单日必须为1~31的整数' };
|
||||
this.$message.warning('账单截单日必须为1~31的整数');
|
||||
return false;
|
||||
}
|
||||
@@ -4775,13 +4876,14 @@ export default {
|
||||
if (this.isFixedCycleSettlement(rule)) {
|
||||
const cycleDays = Number(rule.cycleDays);
|
||||
if (!Number.isInteger(cycleDays) || cycleDays < 1 || cycleDays > 365) {
|
||||
this.settlementRuleErrors = { cycleDays: '周期天数必须为1~365的整数' };
|
||||
this.$message.warning('周期天数必须为1~365的整数');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
normalizeRow(row) {
|
||||
normalizeRow(row, saveAsDraft = false) {
|
||||
const submitRow = { ...row };
|
||||
if (this.config.enableTransportPlanForm) {
|
||||
if (!this.validateTransportPlanForm(submitRow)) return false;
|
||||
@@ -4801,7 +4903,7 @@ export default {
|
||||
submitRow.billingPlanJson = JSON.stringify(this.billingPlanRows);
|
||||
}
|
||||
if (this.config.enableSettlementRule) {
|
||||
if (!this.validateSettlementRule()) return false;
|
||||
if (this.settlementRuleEnabled && !this.validateSettlementRule()) return false;
|
||||
submitRow.settlementRuleJson = JSON.stringify(this.normalizeSettlementRule());
|
||||
}
|
||||
if (this.config.enableReconciliation) {
|
||||
@@ -4810,7 +4912,7 @@ export default {
|
||||
if (this.config.enableChangeRecord) {
|
||||
submitRow.changeRecordJson = JSON.stringify(this.changeRecordRows);
|
||||
}
|
||||
if (this.config.saveAsDraft) {
|
||||
if (this.config.saveAsDraft && saveAsDraft) {
|
||||
submitRow.approvalStatus = 'draft';
|
||||
}
|
||||
delete submitRow.basicInfoTitle;
|
||||
@@ -4894,22 +4996,25 @@ export default {
|
||||
this.stopSubmitLoading(loading);
|
||||
return;
|
||||
}
|
||||
this.getSaveRequest()(submitRow).then(
|
||||
const request =
|
||||
this.attachmentUploadMode && typeof this.api.updateAttachments === 'function'
|
||||
? this.api.updateAttachments
|
||||
: this.getSaveRequest();
|
||||
request(submitRow).then(
|
||||
() => {
|
||||
this.attachmentUploadMode = false;
|
||||
this.onLoad(this.page);
|
||||
this.$message({ type: 'success', message: '操作成功!' });
|
||||
done();
|
||||
},
|
||||
error => {
|
||||
this.attachmentUploadMode = false;
|
||||
window.console.log(error);
|
||||
this.stopSubmitLoading(loading);
|
||||
}
|
||||
);
|
||||
},
|
||||
getSaveRequest() {
|
||||
if (this.config.saveAsDraft && typeof this.api.saveDraft === 'function') {
|
||||
return this.api.saveDraft;
|
||||
}
|
||||
return this.api.submit;
|
||||
},
|
||||
buildContractCreateSubmitRow(action) {
|
||||
@@ -5031,7 +5136,7 @@ export default {
|
||||
handleDraftSave() {
|
||||
const request =
|
||||
typeof this.api.saveDraft === 'function' ? this.api.saveDraft : this.api.submit;
|
||||
const submitRow = this.normalizeRow(this.form);
|
||||
const submitRow = this.normalizeRow(this.form, true);
|
||||
if (!submitRow) return;
|
||||
this.draftSaveLoading = true;
|
||||
request(submitRow)
|
||||
@@ -5094,6 +5199,7 @@ export default {
|
||||
},
|
||||
beforeOpen(done, type) {
|
||||
this.crudDialogType = type;
|
||||
this.settlementRuleErrors = {};
|
||||
this.syncCustomCreateDialogButtons(type);
|
||||
this.dialogReadonly = type === 'view';
|
||||
this.syncContractNoDisabled(type);
|
||||
@@ -5175,8 +5281,7 @@ export default {
|
||||
this.syncCurrentOrganizationOption();
|
||||
}
|
||||
if (this.config.enableProjectSelect) {
|
||||
this.form.usedFundLimit = 0;
|
||||
this.form.remainingFundLimit = 0;
|
||||
this.form.remainingFundLimit = this.calculateRemainingFundLimit();
|
||||
this.syncCurrentProjectOption();
|
||||
}
|
||||
if (this.contractSelectEnabled) {
|
||||
@@ -5223,7 +5328,7 @@ export default {
|
||||
loadProjectOptions() {
|
||||
if (!this.config.enableProjectSelect || this.projectLoading) return;
|
||||
this.projectLoading = true;
|
||||
getProjectList(1, 9999, {})
|
||||
getProjectList(1, 9999, this.config.projectQueryParams || {})
|
||||
.then(res => {
|
||||
this.projectOptions = extractRecords(res);
|
||||
this.syncCurrentProjectOption();
|
||||
@@ -5247,6 +5352,12 @@ export default {
|
||||
});
|
||||
}
|
||||
},
|
||||
calculateRemainingFundLimit() {
|
||||
const projectFundLimit = Number(this.form.projectFundLimit);
|
||||
const usedFundLimit = Number(this.form.usedFundLimit);
|
||||
if (!Number.isFinite(projectFundLimit) || !Number.isFinite(usedFundLimit)) return '';
|
||||
return Math.round((projectFundLimit - usedFundLimit + Number.EPSILON) * 100) / 100;
|
||||
},
|
||||
handleProjectChange(projectId) {
|
||||
const project = this.projectOptions.find(item => String(item.id) === String(projectId));
|
||||
if (!project) {
|
||||
@@ -5274,7 +5385,7 @@ export default {
|
||||
this.form.undertakeDeptName = project.undertakeDeptName || '';
|
||||
this.form.projectFundLimit = project.fundLimit || project.projectFundLimit || 0;
|
||||
this.form.usedFundLimit = 0;
|
||||
this.form.remainingFundLimit = 0;
|
||||
this.form.remainingFundLimit = this.calculateRemainingFundLimit();
|
||||
if (this.contractSelectEnabled || this.config.enableTransportPlanForm) {
|
||||
this.form.customerName =
|
||||
project.customerName ||
|
||||
@@ -7616,11 +7727,16 @@ export default {
|
||||
},
|
||||
searchReset() {
|
||||
this.query = {};
|
||||
this.contractExpiryScope = '';
|
||||
this.contractSignType = '';
|
||||
this.page.currentPage = 1;
|
||||
this.onLoad(this.page);
|
||||
},
|
||||
searchChange(params, done) {
|
||||
this.query = params;
|
||||
this.query = {
|
||||
...params,
|
||||
...(this.contractSignType ? { signType: this.contractSignType } : {}),
|
||||
};
|
||||
this.page.currentPage = 1;
|
||||
this.onLoad(this.page, params);
|
||||
done();
|
||||
@@ -7643,6 +7759,25 @@ export default {
|
||||
refreshChange() {
|
||||
this.onLoad(this.page, this.query);
|
||||
},
|
||||
handleSearchIconChange(expanded) {
|
||||
this.searchExpanded = expanded;
|
||||
},
|
||||
handleContractExpiryScopeChange(expireScope) {
|
||||
this.contractExpiryScope = expireScope;
|
||||
this.page.currentPage = 1;
|
||||
this.onLoad(this.page, this.query);
|
||||
},
|
||||
refreshContractExpiryStats(query) {
|
||||
if (!this.config.enableContractExpiryTags || typeof this.api.expireStats !== 'function') return;
|
||||
const statsQuery = { ...query };
|
||||
delete statsQuery.expireScope;
|
||||
this.api.expireStats(statsQuery).then(res => {
|
||||
this.contractExpiryStats = {
|
||||
...this.contractExpiryStats,
|
||||
...(res.data.data || {}),
|
||||
};
|
||||
});
|
||||
},
|
||||
handleScopeChange() {
|
||||
if (!this.canViewAllDept) {
|
||||
this.allDept = 0;
|
||||
@@ -7699,7 +7834,13 @@ export default {
|
||||
},
|
||||
onLoad(page, params = {}) {
|
||||
this.loading = true;
|
||||
const query = this.normalizeQueryParams({ ...params, ...this.query, allDept: this.allDept });
|
||||
const query = this.normalizeQueryParams({
|
||||
...params,
|
||||
...this.query,
|
||||
allDept: this.allDept,
|
||||
...(this.contractSignType ? { signType: this.contractSignType } : {}),
|
||||
...(this.contractExpiryScope ? { expireScope: this.contractExpiryScope } : {}),
|
||||
});
|
||||
this.api
|
||||
.getList(page.currentPage, page.pageSize, query)
|
||||
.then(res => {
|
||||
@@ -7707,6 +7848,7 @@ export default {
|
||||
this.page.total = result.total;
|
||||
this.data = result.records;
|
||||
this.selectionClear();
|
||||
this.refreshContractExpiryStats(query);
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
@@ -8610,6 +8752,38 @@ export default {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&__contract-expiry-search {
|
||||
display: flex;
|
||||
order: -1;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-right: auto;
|
||||
min-width: 0;
|
||||
|
||||
:deep(.el-select) {
|
||||
width: 160px;
|
||||
}
|
||||
}
|
||||
|
||||
&__contract-expiry-label {
|
||||
flex: 0 0 auto;
|
||||
min-width: 140px;
|
||||
color: #606266;
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
&__contract-expiry-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
|
||||
:deep(.el-check-tag) {
|
||||
margin: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-section-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -9404,6 +9578,10 @@ export default {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
&__billing-plan-remark {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
&__billing-rule-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
Reference in New Issue
Block a user