feat: 合同模板设置

This commit is contained in:
Zzz1zz
2025-11-05 22:26:35 +08:00
parent 84aaa9ac10
commit 89960f749f
7 changed files with 139 additions and 31 deletions
@@ -206,7 +206,10 @@
{{ item.title }}
<icon-close v-if="item.isChoose === 1" />
</a-tag>
<a-tag class="cursor-pointer mb-[10px]" @click="handleAddTerm">
<a-tag
class="cursor-pointer mb-[10px]"
@click="handleAddDiscountTerm"
>
<icon-plus />
优惠条款
</a-tag>
@@ -214,11 +217,13 @@
<bond
v-if="isBondShown"
ref="bondRef"
:detail-info="termsDetailInfo?.bondTerm"
:title="'保证金条款(租金保证金)'"
/>
<incremental
v-if="isIncrementalShown"
ref="incrementalRef"
:detail-info="termsDetailInfo?.incrementalTerm"
:title="'递增条款'"
/>
<discount
@@ -226,15 +231,17 @@
:key="d.key"
:ref="(el) => setDiscountRef(el, di)"
:title="d.title"
:detail-info="termsDetailInfo?.discountTerm?.[di]"
/>
<lateFee
v-if="isLateFeeShown"
ref="lateFeeRef"
:detail-info="termsDetailInfo?.lateFeeTerm"
:title="'滞纳金条款'"
/>
<rentSetting
ref="rentSettingRef"
:term-setting-info="termSettingInfo"
:detail-info="termsDetailInfo?.leaseTerm"
/>
</div>
</template>
@@ -254,6 +261,7 @@
getContractTagsList,
updateTemplateSetting,
getAllTermsSettingList,
getTermsDataFromId,
} from '@/api/setting';
import contractTemplateForm from './modal/contract-template-form.vue';
import { DepartmentItem } from '@/types/setting';
@@ -276,6 +284,7 @@
{ type: 1, text: '含税合同' },
{ type: 2, text: '不含税合同' },
];
const termsDetailInfo = ref<any>(null);
// 表单数据
const formRef = ref<FormInstance>();
const defaultForm: any = {
@@ -394,6 +403,7 @@
(i: any) => i.type === 'lateFee' && i.isChoose === 1
)
);
// 获取条款设置相关设置
async function getTermsSettingFromIdData(id) {
const { code, data } = await getTermsSettingFromId(id);
if (code === 200) {
@@ -409,12 +419,31 @@
termTabList.value = next;
}
}
async function getTermsInfoFromId(contractTermsSettingId) {
const currentTerm =
(currentContractTemplateInfo.value?.terms || []).find(
(t: any) => t.id === currentId.value
) || {};
const params = {
type: 1,
contractTemplateSettingId: currentTerm?.id,
contractTermsSettingId,
};
const { code, data } = await getTermsDataFromId(params);
if (code === 200) {
termsDetailInfo.value = data?.term ?? {};
}
}
const handleChoose = (id: number, str: string, termId: number) => {
if (id === currentId.value) return;
currentId.value = id;
title.value = str;
if (id === 0) {
termsDetailInfo.value = {};
}
if (id === 0 || termId === 0) return;
getTermsSettingFromIdData(termId);
getTermsInfoFromId(termId);
};
const handleBaseInfoEdit = () => {
showModal.value = true;
@@ -652,7 +681,7 @@
info.isChoose = info.isChoose === 1 ? 2 : 1;
}
}
function handleAddTerm() {
function handleAddDiscountTerm() {
const idx = termTabList.value.filter(
(i: any) => i.type === 'discount'
).length;
@@ -54,10 +54,12 @@
</div>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue';
defineProps<{ title?: string }>();
import { ref, reactive, watch } from 'vue';
import type { FormInstance } from '@arco-design/web-vue';
const props = defineProps<{
title?: string;
detailInfo?: any | null;
}>();
// 表单数据
const formRef = ref<FormInstance>();
const defaultForm: any = {
@@ -83,7 +85,20 @@
const choosePayDateType = (type) => {
bondForm.payType = type;
};
watch(
() => props.detailInfo,
(newVal) => {
const data = { ...newVal };
if (data.payType === 0) {
data.payType = undefined;
}
if (data.priceType === 0) {
data.priceType = undefined;
}
Object.assign(bondForm, defaultForm, data);
},
{ immediate: true, deep: true }
);
// 暴露保存数据
function getData() {
return { ...bondForm };
@@ -56,9 +56,11 @@
</div>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue';
import { ref, reactive, watch } from 'vue';
import type { FormInstance } from '@arco-design/web-vue';
const props = defineProps<{
detailInfo?: any | null;
}>();
// 表单数据
const formRef = ref<FormInstance>();
const defaultForm: any = {
@@ -75,7 +77,17 @@
startNum: [{ required: true, message: '开始期数不能为空' }],
endNum: [{ required: true, message: '持续期数不能为空' }],
});
watch(
() => props.detailInfo,
(newVal) => {
const data = { ...newVal };
if (data.type === 0) {
data.type = undefined;
}
Object.assign(discountForm, defaultForm, data);
},
{ immediate: true, deep: true }
);
// 向父组件暴露数据与校验方法
function getData() {
const isEmptyValue = (v: any) =>
@@ -58,9 +58,11 @@
</div>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue';
import { ref, reactive, watch } from 'vue';
import type { FormInstance } from '@arco-design/web-vue';
const props = defineProps<{
detailInfo?: any | null;
}>();
// 表单数据
const formRef = ref<FormInstance>();
const defaultForm: any = {
@@ -78,6 +80,21 @@
bondIncrease: [{ required: true, message: '保证金递增不能为空' }],
});
watch(
() => props.detailInfo,
(newVal) => {
const data = { ...newVal };
if (data.priceIncreaseType === 0) {
data.priceIncreaseType = undefined;
}
if (data.bondIncreaseType === 0) {
data.bondIncreaseType = undefined;
}
Object.assign(increamForm, defaultForm, data);
},
{ immediate: true, deep: true }
);
// 向父组件暴露数据与校验方法
function getData() {
const isEmptyValue = (v: any) =>
@@ -65,9 +65,11 @@
</div>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue';
import { ref, reactive, watch } from 'vue';
import type { FormInstance } from '@arco-design/web-vue';
const props = defineProps<{
detailInfo?: any | null;
}>();
// 表单数据
const formRef = ref<FormInstance>();
const defaultForm: any = {
@@ -89,6 +91,24 @@
ceilingType: [{ required: true, message: '上限单位不能为空' }],
});
watch(
() => props.detailInfo,
(newVal) => {
const data = { ...newVal };
if (data.chargeType === 0) {
data.chargeType = undefined;
}
if (data.ratioType === 0) {
data.ratioType = undefined;
}
if (data.ceilingType === 0) {
data.ceilingType = undefined;
}
Object.assign(lateFeeForm, defaultForm, data);
},
{ immediate: true, deep: true }
);
// 向父组件暴露数据与校验方法
function getData() {
const isEmptyValue = (v: any) =>
@@ -22,16 +22,6 @@
layout="vertical"
>
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="首期账单缴费日期" field="firstPayDate" required>
<a-date-picker
v-model="rentSettingInfo.firstPayDate"
:disabled-date="
(current) => dayjs(current).isBefore(dayjs().subtract(1, 'day'))
"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="账单缴费日期" field="payDay" required>
<a-input-number v-model="rentSettingInfo.payDay">
@@ -100,7 +90,6 @@
partitionMode: 1, // 租期划分模式
firstLessMonthType: 1, // 首月不足月租金处理
otherLeaseProcessing: 1, // 免租期、装修期租期处理
firstPayDate: '',
payDay: '',
payDateType: 1,
payDayType: 1,
@@ -108,7 +97,6 @@
const rentSettingInfo = ref<any>({ ...defaultForm });
const formRef = ref<FormInstance>();
const rules = reactive({
firstPayDate: [{ required: true, message: '请选择首期账单缴费日期' }],
payDay: [{ required: true, message: '请输入账单缴费日期' }],
financeTurnoverAccountSettingId: [
{ required: true, message: '请选择默认收款账户' },
@@ -117,7 +105,7 @@
const turnoverAccountList = ref<any>([]);
const props = defineProps<{
termSettingInfo?: any | null;
detailInfo?: any | null;
}>();
// 文案映射与计算属性
const chargeTypeMap = new Map([
@@ -253,14 +241,37 @@
}
onMounted(() => {
triggerTurnoverList(props.termSettingInfo);
triggerTurnoverList(props.detailInfo);
});
watch(
() => props.termSettingInfo,
() => props.detailInfo,
(newVal) => {
const data = { ...(newVal || {}) };
const fieldsToProcess = [
'payDateType',
'payDayType',
'financeTurnoverAccountSettingId',
'chargeType',
'priceUnit',
'dayPriceAlgorithm',
'dayPriceUnit',
'calculationAccuracy',
'billAccuracy',
'partitionMode',
'firstLessMonthType',
'otherLeaseProcessing',
];
fieldsToProcess.forEach((field) => {
if (data[field] === 0) {
data[field] = undefined;
}
});
rentSettingInfo.value = { ...defaultForm, ...data };
triggerTurnoverList(newVal);
},
{ deep: false }
{ deep: true }
);
defineExpose({ getData, validate });