Files
leaser_front/src/views/setting/system/contract-settings/modal/contract-number-form-modal.vue
T

324 lines
9.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<a-drawer
:width="430"
:visible="visible"
:title="isEdit ? '编辑合同编号' : '新增合同编号'"
unmount-on-close
@ok="handleOk"
@cancel="handleCancel"
>
<a-form
ref="formRef"
:model="form"
:rules="rules"
auto-label-width
layout="vertical"
>
<!-- 合同编号 -->
<a-form-item label="合同编号" field="name" required>
<a-input
v-model="form.name"
:placeholder="$t('please.enter', { placeholder: '合同编号' })"
/>
</a-form-item>
<!-- 编号回收 -->
<a-form-item label="编号回收" field="ecycling" required>
<a-checkbox-group v-model="form.ecycling">
<a-checkbox :value="1">作废合同编号回收</a-checkbox>
<a-checkbox :value="2">删除合同编号回收</a-checkbox>
</a-checkbox-group>
</a-form-item>
<a-form-item label="编号编排" field="arrange" required>
<div class="numbering">编号预览:{{ numbering }}</div>
</a-form-item>
<draggable
v-model="arrangeList"
:animation="200"
item-key="sort"
@end="handleDragEnd"
>
<template #item="{ element }">
<a-row align="center" style="margin-top: 10px">
<a-col :span="6">
<div class="arrange_left">
<icon-unordered-list :size="24" />
<p class="text">{{ getArrangeText(element.type) }}</p>
</div>
</a-col>
<a-col :span="14">
<a-input
v-if="element.type === 1"
v-model="element.content"
placeholder="请输入固定文本"
/>
<a-select
v-else-if="element.type === 2"
v-model="element.date_type"
>
<a-option
v-for="(item, index) in dateTypeOptions"
:key="index"
:value="item.type"
>
{{ item.text }}</a-option
>
</a-select>
<template v-else>
<a-select v-model="element.data_type">
<a-option
v-for="(item, index) in dataTypeOptions"
:key="index"
:value="item.type"
>
{{ item.text }}</a-option
>
</a-select>
<a-input-number
v-model="element.data_digit"
:style="{ marginTop: '10px' }"
placeholder="Please enter something"
>
<template #append>位数</template>
</a-input-number>
</template>
</a-col>
<a-col :span="4">
<icon-delete
v-if="element.type === 1"
:size="16"
style="cursor: pointer"
@click="handleDeleteText(element)"
/>
</a-col>
</a-row>
</template>
</draggable>
<a-divider />
<a-button style="width: 130px" type="outline" @click="handleAddText"
><icon-plus /> 新增固定文本</a-button
>
</a-form>
</a-drawer>
</template>
<script lang="ts" setup>
import { ref, watch, reactive, computed } from 'vue';
import { useI18n } from 'vue-i18n';
import type { FormInstance } from '@arco-design/web-vue';
import { Message } from '@arco-design/web-vue';
import { createCodeSetting, updateCodeSetting } from '@/api/setting';
// import { CreateCodeSettingParam } from '@/types/setting'
import draggable from 'vuedraggable';
const props = defineProps<{
visible: boolean;
isEdit: boolean;
record?: any | null;
}>();
const emit = defineEmits<{
(e: 'update:visible', val: boolean): void;
(e: 'submitted'): void;
}>();
const arrangeList = ref([
{ type: 1, content: '', sort: 1 },
{ type: 2, date_type: 1, sort: 2 },
{ type: 3, data_type: 1, data_digit: 5, sort: 3 },
]);
const dateTypeOptions = [
{ text: '年月日时分', type: 1 },
{ text: '年月日时', type: 2 },
{ text: '年月日', type: 3 },
{ text: '年月', type: 4 },
];
const dataTypeOptions = [
{ text: '每月重置计数(每月1日零点重置)', type: 1 },
{ text: '按年顺序计数', type: 2 },
{ text: '按创建合同顺序计数', type: 3 },
];
// 表单数据
const formRef = ref<FormInstance>();
const defaultForm: any = {
name: '',
ecycling: [1],
arrange: arrangeList.value,
};
const form = reactive<any>({ ...defaultForm });
const { t } = useI18n();
// 校验规则
const rules = reactive({
name: [{ required: true, message: '请输入合同编号' }],
ecycling: [{ required: true, message: '请选择编号回收规则' }],
arrange: [{ required: true, message: '请选择编号回收规则' }],
});
watch(
() => props.visible,
(val) => {
if (val) {
if (props.isEdit && props.record) {
Object.assign(form, { ...props.record, ecycling: [] });
if (props.record.cancelCodeRecycling === 1) form.ecycling.push(1);
if (props.record.delCodeRecycling === 1) form.ecycling.push(2);
arrangeList.value = (props.record.arrange || []).map(
(item, index) => ({
...item,
sort: index + 1,
})
);
} else {
arrangeList.value = [
{ type: 1, content: '', sort: 1 },
{ type: 2, date_type: 1, sort: 2 },
{ type: 3, data_type: 1, data_digit: 5, sort: 3 },
];
Object.assign(form, defaultForm);
}
}
},
{ immediate: true }
);
// 生成日期字符串
function getDateStr(type) {
const now = new Date();
const pad = (n) => n.toString().padStart(2, '0');
const year = now.getFullYear();
const month = pad(now.getMonth() + 1);
const day = pad(now.getDate());
const hour = pad(now.getHours());
const minute = pad(now.getMinutes());
switch (type) {
case 1:
return `${year}${month}${day}${hour}${minute}`;
case 2:
return `${year}${month}${day}${hour}`;
case 3:
return `${year}${month}${day}`;
case 4:
return `${year}${month}`;
default:
return '';
}
}
const numbering = computed(() => {
const parts: string[] = [];
arrangeList.value.forEach((item) => {
if (item.type === 1) {
parts.push(item.content || '');
} else if (item.type === 2) {
parts.push(getDateStr(item.date_type));
} else if (item.type === 3) {
const digit = item.data_digit ? item.data_digit : 1;
parts.push('1'.padStart(digit, '0'));
}
});
return parts.filter(Boolean).join('-');
});
const getArrangeText = (type: number) => {
const textMap = { 1: '固定文本', 2: '日期', 3: '流水号' };
return type ? textMap[type] : '固定文本';
};
const handleAddText = () => {
const maxSort = Math.max(...arrangeList.value.map((i) => i.sort || 0));
arrangeList.value.push({
type: 1,
content: '',
sort: maxSort + 1,
});
};
const handleDeleteText = (targetItem) => {
const index = arrangeList.value.findIndex((item) => item === targetItem);
if (index !== -1) {
arrangeList.value.splice(index, 1);
}
};
const handleDragEnd = () => {
// 更新 sort 字段
arrangeList.value.forEach((item, index) => {
item.sort = index + 1;
});
// 同步到 form.arrange
form.arrange = JSON.parse(JSON.stringify(arrangeList.value));
};
const handleOk = async () => {
try {
const valid = await formRef.value.validate();
if (valid) return;
// 同步编号排序
form.arrange = arrangeList.value.map((item, index) => ({
...item,
sort: index + 1,
}));
const params = {
...form,
cancel_code_recycling: form.ecycling.includes(1) ? 1 : 0,
del_code_recycling: form.ecycling.includes(2) ? 1 : 0,
};
delete params.ecycling;
console.log('提交参数:', params);
const res = props?.isEdit
? await updateCodeSetting(params)
: await createCodeSetting(params);
if (res?.code === 200) {
Message.success(res?.message);
emit('submitted');
emit('update:visible', false);
}
} catch (err) {
// 捕获异常,暂不处理
}
};
const handleCancel = () => {
emit('update:visible', false);
};
</script>
<style lang="less" scoped>
:deep(label.arco-form-item-label) {
width: 100% !important;
}
.label_wrap {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
.left {
display: flex;
align-items: center;
.required {
color: #f53f3f;
margin-right: 4px;
font-size: 16px;
line-height: 1;
}
}
.right {
display: flex;
align-items: center;
gap: 4px;
}
}
.numbering {
background-color: #eaf3fe;
padding: 5px 10px;
width: 100%;
font-weight: bold;
}
.arrange_left {
display: flex;
align-items: center;
.text {
margin-left: 7px;
}
}
</style>