fix(personal-item): 个人事项&任务添加type类型字段

This commit is contained in:
caozehui
2026-05-21 14:06:05 +08:00
parent fe29fde564
commit 28d597d91e
11 changed files with 151 additions and 15 deletions

View File

@@ -2,6 +2,7 @@
import { computed, nextTick, reactive, ref, watch } from 'vue';
import { useResizeObserver } from '@vueuse/core';
import dayjs from 'dayjs';
import { RDMS_TASK_ITEM_TYPE_DICT_CODE } from '@/constants/dict';
import { fetchCreatePersonalItem, fetchGetPersonalItemDetail, fetchUpdatePersonalItem } from '@/service/api';
import { useAuthStore } from '@/store/modules/auth';
import { useForm, useFormRules } from '@/hooks/common/form';
@@ -9,6 +10,7 @@ import BusinessAttachmentUploader from '@/components/custom/business-attachment-
import BusinessFormDialog from '@/components/custom/business-form-dialog.vue';
import BusinessFormSection from '@/components/custom/business-form-section.vue';
import BusinessRichTextEditor from '@/components/custom/business-rich-text-editor.vue';
import DictSelect from '@/components/custom/dict-select.vue';
import { isEmptyRichText } from './personal-item-shared';
defineOptions({ name: 'PersonalItemOperateDialog' });
@@ -57,6 +59,7 @@ const submitting = ref(false);
interface Model {
taskTitle: string;
type: string;
plannedStartDate: string | null;
plannedEndDate: string | null;
taskDesc: string | null;
@@ -76,6 +79,7 @@ const title = computed(() => {
function createDefaultModel(): Model {
return {
taskTitle: '',
type: '',
plannedStartDate: null,
plannedEndDate: null,
taskDesc: null,
@@ -108,6 +112,7 @@ const rules = computed(
trigger: 'blur'
}
],
type: [createRequiredRule('请选择事项类型')],
plannedStartDate: [createRequiredRule('请选择计划开始日期')],
plannedEndDate: [
createRequiredRule('请选择计划结束日期'),
@@ -136,6 +141,7 @@ async function initModel() {
if (!error && data) {
model.taskTitle = data.taskTitle;
model.type = data.type;
model.plannedStartDate = data.plannedStartDate;
model.plannedEndDate = data.plannedEndDate;
model.taskDesc = data.taskDesc;
@@ -166,6 +172,7 @@ async function handleSubmit() {
const payload: Api.PersonalItem.SavePersonalItemParams = {
taskTitle: model.taskTitle.trim(),
type: model.type,
ownerId: currentUserId.value,
plannedStartDate: model.plannedStartDate,
plannedEndDate: model.plannedEndDate,
@@ -235,6 +242,16 @@ watch(
/>
</ElFormItem>
<ElFormItem label="事项类型" prop="type">
<DictSelect
v-model="model.type"
:dict-code="RDMS_TASK_ITEM_TYPE_DICT_CODE"
:clearable="!isView"
:disabled="isView"
placeholder="请选择事项类型"
/>
</ElFormItem>
<ElFormItem label="计划开始日期" prop="plannedStartDate">
<ElDatePicker
v-model="model.plannedStartDate"

View File

@@ -162,7 +162,7 @@ const rules = computed(
trigger: 'change'
}
],
difficulty: [createRequiredRule('请选择完成难度')],
difficulty: [createRequiredRule('请选择难度')],
workContent: [
{
required: true,
@@ -356,7 +356,7 @@ defineExpose({
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElFormItem label="完成难度" prop="difficulty">
<ElFormItem label="难度" prop="difficulty">
<DictSelect
v-model="model.difficulty"
:dict-code="RDMS_WORKLOG_DIFFICULTY_DICT_CODE"

View File

@@ -1,12 +1,14 @@
<script setup lang="ts">
import { computed, ref, watch } from 'vue';
import { ElPopconfirm, ElTag, ElTooltip } from 'element-plus';
import { ElMessageBox, ElPopconfirm, ElTag, ElTooltip } from 'element-plus';
import dayjs from 'dayjs';
import { Plus } from '@element-plus/icons-vue';
import { RDMS_WORKLOG_DIFFICULTY_DICT_CODE } from '@/constants/dict';
import {
fetchCompletePersonalItem,
fetchCreatePersonalItemWorklog,
fetchDeletePersonalItemWorklog,
fetchGetPersonalItemDetail,
fetchGetPersonalItemWorklogPage,
fetchUpdatePersonalItemWorklog
} from '@/service/api';
@@ -52,6 +54,8 @@ const currentUserName = computed(
const PAGE_SIZE = 10;
const TABLE_HEIGHT = 390;
const COMPLETED_STATUS_CODE: Api.PersonalItem.PersonalItemStatusCode = 'completed';
const COMPLETE_ACTION_CODE = 'complete';
const pageNo = ref(1);
const total = ref(0);
@@ -189,6 +193,56 @@ async function loadRecords() {
total.value = data.total;
}
function canPromptCompleteItem(item: Api.PersonalItem.PersonalItem) {
if (item.statusCode === COMPLETED_STATUS_CODE || item.terminal) {
return false;
}
return (
item.progressRate >= 100 && (item.availableActions ?? []).some(action => action.actionCode === COMPLETE_ACTION_CODE)
);
}
async function fetchLatestItem() {
const { error, data } = await fetchGetPersonalItemDetail(props.item.id);
if (error || !data) {
return null;
}
return data;
}
async function promptCompleteItemIfNeeded() {
const latestItem = await fetchLatestItem();
if (!latestItem || !canPromptCompleteItem(latestItem)) {
return;
}
try {
await ElMessageBox.confirm('事项进度已达 100%,是否完成当前事项?', '完成确认', {
confirmButtonText: '完成事项',
cancelButtonText: '仅保留工时',
type: 'info'
});
} catch {
return;
}
const { error } = await fetchCompletePersonalItem(latestItem.id);
if (!error) {
window.$message?.success('个人事项已完成');
}
}
async function reloadAfterWorklogChanged() {
await loadRecords();
await promptCompleteItemIfNeeded();
emit('changed');
}
function handlePageChange(page: number) {
pageNo.value = page;
loadRecords();
@@ -225,8 +279,7 @@ async function handleDelete(row: Api.PersonalItem.PersonalItemWorklog) {
}
window.$message?.success('工作日志删除成功');
await loadRecords();
emit('changed');
await reloadAfterWorklogChanged();
}
async function handleSubmit(payload: Api.PersonalItem.SavePersonalItemWorklogParams) {
@@ -249,8 +302,7 @@ async function handleSubmit(payload: Api.PersonalItem.SavePersonalItemWorklogPar
window.$message?.success(formMode.value === 'edit' ? '工作日志修改成功' : '工作日志新增成功');
formVisible.value = false;
await loadRecords();
emit('changed');
await reloadAfterWorklogChanged();
} finally {
submitting.value = false;
}