Просмотр исходного кода

feature: 添加了检查任务起止时间的功能,结束时间不能早于起始时间,并且结束时间不能晚于项目交付时间

eyes4 6 месяцев назад
Родитель
Сommit
406bd6d44c

+ 3 - 0
base-lib/src/core-models/PrjInfo.ts

@@ -19,6 +19,9 @@ export class PrjInfo extends Model {
     declare progress: number;
     declare checkers: any;
     declare contract_id: string;
+    declare created_at: string;
+    declare started_at: string;
+    declare deliver_at: string;
 
     static table_name = 'tb_prj_info';
 

+ 3 - 1
pmr-biz-manager/src/models/Models.ts

@@ -25,6 +25,7 @@ import {PrjTaskOutcomeDraft} from "@core-models/PrjTaskOutcomeDraft";
 import {PrjLogs} from "@core-models/PrjLogs";
 import {ReportPrjStat} from "@core-models/ReportPrjStat";
 import {ReportTaskStat} from "@core-models/ReportTaskStat";
+import {ReportTaskDelayRate} from "@core-models/ReportTaskDelayRate";
 
 export const Models: Array<IDataModelInfo> = [
     {tag: 'acs', model: AcsDomain, timestamps: false},
@@ -52,5 +53,6 @@ export const Models: Array<IDataModelInfo> = [
     {tag: 'pmr', model: BpmnForm, timestamps: false},
     {tag: 'pmr', model: PrjLogs, timestamps: false},
     {tag: 'pmr', model: ReportPrjStat, timestamps: false},
-    {tag: 'pmr', model: ReportTaskStat, timestamps: false}
+    {tag: 'pmr', model: ReportTaskStat, timestamps: false},
+    {tag: 'pmr', model: ReportTaskDelayRate, timestamps: false}
 ]

+ 3 - 0
pmr-biz-manager/src/routes/api/prj/info/add.ts

@@ -64,6 +64,9 @@ function add(json: IRequest, params: IMethodParams, cached_data: ICachedData): P
             let data = <IData>json.data;
             let id = IdGen.id();
             let flow_case_id = IdGen.id();
+            if (data.deliver_at) {
+                data.deliver_at += ' 23:59:59';
+            }
             let value: any = {
                 id: id,
                 phase_id: 'new',

+ 14 - 3
pmr-biz-manager/src/routes/api/prj/info/modify.ts

@@ -1,6 +1,6 @@
 import {IApiProcessor, ICachedData, IMethodParams, IRequest} from "@core/Defined";
 import DataCURD from "@core/DataCURD";
-import {Transaction, WhereOptions} from "sequelize";
+import {Op, Transaction, WhereOptions} from "sequelize";
 import {PrjInfo} from "@core-models/PrjInfo";
 import dayjs from "dayjs";
 import {PrjLogger} from "@src/utils/prj_logger";
@@ -63,11 +63,21 @@ function permission_guard(content: IRequest, cached_data: ICachedData): Promise<
         let data = <IData>content.data;
         let prj = await PrjInfo.findOne({where: {id: data.id},  raw: true});
         if (!prj)
-            throw Resp.gen_err(Resp.ResourceNotFound, '项目不存在。');
+            return reject(Resp.gen_err(Resp.ResourceNotFound, '项目不存在。'));
 
         if (!await is_project_modifiable(cached_data.user_id, prj.id))
             return reject(Resp.gen_err(Resp.Forbidden, '您没有权限修改该项目,请确认您是项目负责人或特权人员。'));
-
+        if (data.deliver_at) {
+            data.deliver_at += ' 23:59:59';
+        }
+        let task = await PrjPlanTask.findOne({where: {prj_id: prj.id, end_at: {[Op.gt]: data.deliver_at}}, raw: true});
+        if (task) {
+            return reject(Resp.gen_err(Resp.Forbidden, '项目交付时间不能早于项目计划中任务的结束时间。'));
+        }
+        task =  await PrjPlanTaskDraft.findOne({where: {prj_id: prj.id, end_at: {[Op.gt]: data.deliver_at}}, raw: true});
+        if (task) {
+            return reject(Resp.gen_err(Resp.Forbidden, '项目交付时间不能早于项目计划草稿中任务的结束时间。'));
+        }
         resolve();
 
     });
@@ -75,6 +85,7 @@ function permission_guard(content: IRequest, cached_data: ICachedData): Promise<
 
 async function get_where(json: IRequest, params: IMethodParams, cached_data: ICachedData): Promise<WhereOptions> {
     let data = <IData>json.data;
+
     return {id: data.id};
 }
 

+ 12 - 3
pmr-biz-manager/src/routes/api/prj/plan/add_task.ts

@@ -58,13 +58,22 @@ function guard(json: IRequest, cached_data: ICachedData): Promise<void> {
         let data = <IData>json.data;
         if (!user) return reject(Resp.gen_err(Resp.Forbidden));
         if (user === ADMINISTRATOR) return resolve();
-        // 检查计划结束时间是否晚于计划开始时间
+
+        let prj_info = await PrjInfo.findOne({where: {id: data.prj_id}, raw: true});
+        if (!prj_info) return reject(Resp.gen_err(Resp.ResourceNotFound));
+
         data.begin_at += ' 00:00:00';
         data.end_at += ' 23:59:59';
+
+        // 检查计划结束时间不能晚于项目交付时间
+        if (dayjs(data.end_at).diff(dayjs(prj_info.deliver_at)) > 0) {
+            return reject(Resp.gen_err(Resp.ParamsError, `计划结束时间不能晚于项目交付时间 ${dayjs(prj_info.deliver_at).format('YYYY-MM-DD')}。`));
+        }
+        // 检查计划结束时间是否晚于计划开始时间
+
         if (dayjs(data.end_at).diff(dayjs(data.begin_at)) <= 0)
             return reject(Resp.gen_err(Resp.ParamsError, '计划结束时间必须晚于计划开始时间。'));
-        let prj_info = await PrjInfo.findOne({where: {id: data.prj_id}, raw: true});
-        if (!prj_info) return reject(Resp.gen_err(Resp.ResourceNotFound));
+
         // 只有项目负责人或特权人员才可以添加任务
         if (!await is_project_task_addable(user, prj_info.id)) {
             return reject(Resp.gen_err(Resp.Forbidden, '您不是项目负责人或特权人员,不能添加任务。'));

+ 9 - 44
pmr-biz-manager/src/routes/api/prj/plan/modify_task.ts

@@ -77,6 +77,8 @@ function guard(json: IRequest, cached_data: ICachedData): Promise<void> {
 
         let prj_info = await PrjInfo.findOne({where: {id: task.prj_id}, raw: true});
         if (!prj_info) return reject(Resp.gen_err(Resp.ResourceNotFound));
+        cached_data.deliver_at = prj_info.deliver_at; // 缓存项目的交付时间
+
         // 检查用户是否是项目负责人,只有项目负责人才可以修改任务
         if (cached_data.user_id !== prj_info.leader_id) {
             return reject(Resp.gen_err(Resp.Forbidden, '您不是项目负责人,不能修改任务。'));
@@ -121,6 +123,12 @@ function modify(json: IRequest, params: IMethodParams, cached_data: ICachedData)
             // 检查起止时间是否合法
             let begin_at = data.begin_at || task.begin_at;
             let end_at = data.end_at || task.end_at;
+
+            // 检查计划结束时间不能晚于项目交付时间
+            if (dayjs(data.end_at).diff(dayjs(cached_data.deliver_at)) > 0) {
+                return reject(Resp.gen_err(Resp.ParamsError, `计划结束时间不能晚于项目交付时间 ${dayjs(cached_data.deliver_at).format('YYYY-MM-DD')}。`));
+            }
+
             if (dayjs(end_at).diff(dayjs(begin_at)) <= 0)
                 throw Resp.gen_err(Resp.ParamsError, '任务结束时间必须晚于开始时间。');
 
@@ -146,8 +154,7 @@ function modify(json: IRequest, params: IMethodParams, cached_data: ICachedData)
                     updated_at: "updated_at"
                 }
             }, cached_data, t);
-            // await update_parent_task_time(data.task_id, t);
-            // await update_parent_task_info(result.pid, t);
+
             await update_parent_task_info(data.draft, result.prj_id, result.pid, t as Transaction);
 
             /// 如果计划任务是草稿,且还没有生成计划变更任务,则生成任务
@@ -164,48 +171,6 @@ function modify(json: IRequest, params: IMethodParams, cached_data: ICachedData)
     })
 }
 
-
-/// 递归逐级更新任务起止时间
-async function update_parent_task_time(task_id: string, t: Transaction, max?: Dayjs, min?: Dayjs): Promise<void> {
-    let task = await PrjPlanTask.findOne({where: {id: task_id}, transaction: t});
-
-    if (!task) {
-        throw new Error(`Task with ID ${task_id} not found.`);
-    }
-
-    if (task.pid) {
-        let child_tasks = await PrjPlanTask.findAll({
-            where: {pid: task.pid},
-            transaction: t
-        });
-        let total_duration = 0;
-        let completed = 0;
-        for (let i = 0; i < child_tasks.length; i++) {
-            let child_task = child_tasks[i];
-            let begin = dayjs(child_task.begin_at);
-            let end = dayjs(child_task.end_at);
-            if (max === undefined) max = end;
-            else max = end.diff(max) > 0 ? end : max;
-            if (min === undefined) min = begin;
-            else min = begin.diff(min) < 0 ? begin : min;
-            let duration = dayjs(child_task.end_at).diff(child_task.begin_at, 'hours');
-            total_duration += duration;
-            completed += duration * child_task.progress / 100;
-        }
-        let progress = total_duration !== 0 ? (completed * 100 / total_duration) : 0;
-        if (progress > 0 && progress < 1) progress = 1;
-        else if (progress < 100 && progress > 99) progress = 99;
-        else progress = Math.round(progress);
-        await PrjPlanTask.update({begin_at: min!, end_at: max!, progress: progress}, {
-            where: {id: task.pid},
-            transaction: t
-        })
-        await update_parent_task_time(task.pid, t);
-        // await update_parent_task_info(task.prj_id, task.pid, t);
-    }
-}
-
-
 async function before_respond(content: IRequest, params: IMethodParams, cached_data: ICachedData | any, result: any): Promise<unknown> {
     result = DataCURD.filter_null(result, new Map(Object.entries({
         "updated_at": "YYYY-MM-DD HH:mm:ss",