first commit

This commit is contained in:
2025-12-26 23:19:09 +08:00
commit b29d128e41
788 changed files with 100922 additions and 0 deletions

View File

@@ -0,0 +1,259 @@
<template>
<div class="layout-padding">
<div class="layout-padding-auto layout-padding-view">
<el-card shadow="never" class="mb-4 overflow-auto">
<template #header>
<div class="card-header">
<div class="flex items-center">
<el-button type="primary" icon="plus" @click="handleAddRow">
{{ $t('projectReviewPolicy.addRow') }}
</el-button>
</div>
</div>
</template>
<el-table
:data="state.dataList"
style="width: 100%"
v-loading="state.loading"
border
row-key="id"
>
<el-table-column type="index" :label="$t('projectReviewPolicy.index')" width="60" />
<el-table-column prop="projectType" :label="$t('projectReviewPolicy.projectType')">
<template #default="{ row, $index }">
<el-select
v-model="row.projectType"
:placeholder="$t('projectReviewPolicy.selectProjectType')"
@change="handleFieldChange($index)"
style="width: 100%"
>
<el-option
v-for="item in projectTypeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column :label="$t('projectReviewPolicy.finalReminderPeriod')">
<template #default="{ row, $index }">
<el-select
v-model="row.finalReminderPeriod"
@change="handleFieldChange($index)"
style="width: 100%"
>
<el-option
v-for="item in finalReminderPeriodOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column :label="$t('projectReviewPolicy.advanceReminder')">
<template #default="{ row, $index }">
<el-select
v-model="row.advanceReminderPeriod"
@change="handleFieldChange($index)"
style="width: 100%"
>
<el-option
v-for="item in advanceReminderPeriodOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column :label="$t('projectReviewPolicy.action')" width="120">
<template #default="{ row, $index }">
<el-button
text
size="small"
type="danger"
icon="delete"
@click="handleDeleteRow($index, row)"
>
{{ $t('common.delBtn') }}
</el-button>
</template>
</el-table-column>
</el-table>
<div class="mt-4 flex justify-end">
<el-button type="primary" @click="handleSaveAll" :loading="saving">
{{ $t('projectReviewPolicy.saveAll') }}
</el-button>
</div>
</el-card>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, reactive, onMounted } from 'vue';
import { useI18n } from 'vue-i18n';
import { useMessage } from '/@/hooks/message';
import {
fetchProjectReviewPolicyPage,
addProjectReviewPolicy,
updateProjectReviewPolicy,
deleteProjectReviewPolicy
} from '/@/api/config/projectReviewPolicy';
import { debounce } from 'lodash';
const { t } = useI18n();
const message = useMessage();
// 定义项目类型选项
const projectTypeOptions = ref([
{ value: '1', label: t('projectReviewPolicy.infrastructure') },
{ value: '2', label: t('projectReviewPolicy.industrial') },
{ value: '3', label: t('projectReviewPolicy.civilEngineering') },
{ value: '4', label: t('projectReviewPolicy.other') }
]);
// 最后提醒期限选项 (1-9年)
const finalReminderPeriodOptions = ref([
{ value: 1, label: '1' + t('projectReviewPolicy.year') },
{ value: 2, label: '2' + t('projectReviewPolicy.year') },
{ value: 3, label: '3' + t('projectReviewPolicy.year') },
{ value: 4, label: '4' + t('projectReviewPolicy.year') },
{ value: 5, label: '5' + t('projectReviewPolicy.year') },
{ value: 6, label: '6' + t('projectReviewPolicy.year') },
{ value: 7, label: '7' + t('projectReviewPolicy.year') },
{ value: 8, label: '8' + t('projectReviewPolicy.year') },
{ value: 9, label: '9' + t('projectReviewPolicy.year') }
]);
// 提前提醒选项 (无、提前3、15、30、60、90天)
const advanceReminderPeriodOptions = ref([
{ value: 0, label: t('projectReviewPolicy.none') },
{ value: 3, label: t('projectReviewPolicy.advance') + '3' + t('projectReviewPolicy.day') },
{ value: 15, label: t('projectReviewPolicy.advance') + '15' + t('projectReviewPolicy.day') },
{ value: 30, label: t('projectReviewPolicy.advance') + '30' + t('projectReviewPolicy.day') },
{ value: 60, label: t('projectReviewPolicy.advance') + '60' + t('projectReviewPolicy.day') },
{ value: 90, label: t('projectReviewPolicy.advance') + '90' + t('projectReviewPolicy.day') }
]);
// 表格状态
const state = reactive({
dataList: [] as any[],
loading: false,
});
// 保存状态
const saving = ref(false);
// 防抖保存函数
const debouncedSave = debounce(async (row, type) => {
try {
if (type === 'add') {
const res = await addProjectReviewPolicy(row);
// 更新ID
row.id = res.data?.id || row.id;
message.success(t('projectReviewPolicy.saveSuccess'));
} else if (type === 'update') {
await updateProjectReviewPolicy(row);
message.success(t('projectReviewPolicy.updateSuccess'));
}
} catch (err: any) {
message.error(err?.msg || err?.message || t('common.operateFail'));
}
}, 800);
// 字段变更处理
const handleFieldChange = (index: number) => {
const row = state.dataList[index];
if (!row) return;
// 如果是新行且没有ID则添加
if (!row.id || row.id === '') {
debouncedSave(row, 'add');
} else {
// 否则更新现有行
debouncedSave(row, 'update');
}
};
// 添加行
const handleAddRow = () => {
state.dataList.push({
id: '',
projectType: '',
finalReminderPeriod: 1,
finalReminderUnit: '年',
advanceReminderPeriod: 30,
advanceReminderUnit: '天',
createTime: ''
});
};
// 删除行
const handleDeleteRow = async (index: number, row: any) => {
try {
if (row.id) {
// 如果有ID从服务器删除
await deleteProjectReviewPolicy(row.id);
}
// 从前端列表中移除
state.dataList.splice(index, 1);
message.success(t('projectReviewPolicy.deleteSuccess'));
} catch (err: any) {
message.error(err?.msg || err?.message || t('common.operateFail'));
}
};
// 保存所有数据
const handleSaveAll = async () => {
saving.value = true;
try {
// 取消所有待处理的防抖调用
debouncedSave.cancel();
// 处理所有未保存的数据
const promises = state.dataList.map(item => {
if (!item.id || item.id === '') {
return addProjectReviewPolicy(item);
} else {
return updateProjectReviewPolicy(item);
}
});
await Promise.all(promises);
message.success(t('projectReviewPolicy.saveAllSuccess'));
await getDataList();
} catch (err: any) {
message.error(err?.msg || err?.message || t('common.operateFail'));
} finally {
saving.value = false;
}
};
// 获取数据列表
const getDataList = async () => {
try {
state.loading = true;
const res = await fetchProjectReviewPolicyPage({ page: 1, size: 1000 });
state.dataList = res.data?.records || [];
} catch (err: any) {
message.error(err?.msg || err?.message || t('common.operateFail'));
} finally {
state.loading = false;
}
};
// 初始化加载数据
onMounted(() => {
getDataList();
});
</script>