From 7f99b772440f6a970e3d21b1fd40e01c46dd26f2 Mon Sep 17 00:00:00 2001 From: shiji <1913712590@qq.com> Date: Fri, 21 Jul 2023 11:44:17 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../views/functionx/modules/FunctionxForm.vue | 16 + .../modules/FunctionxModal__Style#Drawer.vue | 6 + .../src/views/rulex/modules/RulexForm.vue | 11 + .../modules/RulexModal__Style#Drawer.vue | 6 + .../src/views/task/modules/TaskForm.vue | 290 ++++++++++++++---- .../task/controller/TaskController.java | 204 +++++++++++- .../controller/TaskTypeController.java | 43 ++- .../modules/taskType/entity/dto/TypeDto.java | 24 ++ 8 files changed, 531 insertions(+), 69 deletions(-) create mode 100644 jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/taskType/entity/dto/TypeDto.java diff --git a/ant-design-vue-jeecg/src/views/functionx/modules/FunctionxForm.vue b/ant-design-vue-jeecg/src/views/functionx/modules/FunctionxForm.vue index 9000645..41738aa 100644 --- a/ant-design-vue-jeecg/src/views/functionx/modules/FunctionxForm.vue +++ b/ant-design-vue-jeecg/src/views/functionx/modules/FunctionxForm.vue @@ -451,6 +451,22 @@ export default { add() { this.edit(this.modelDefault) }, + add1 (moduleId) { + console.log(moduleId+"--------------------") + getAction(this.url.getmoduleid,{id:moduleId}).then((res)=>{ + + if (res.success) { + this.moduleid=res.result.id; + this.model.moduleId=res.result.id; + //获得模块编码 + this.modulebianma(this.moduleid); + this.modelDefault = JSON.parse(JSON.stringify(this.model)); + this.edit(this.modelDefault); + }else{ + this.$message.warning(res.message); + } + }); + }, edit(record) { this.model = Object.assign({}, record) if (this.model.functionName1 != null) { diff --git a/ant-design-vue-jeecg/src/views/functionx/modules/FunctionxModal__Style#Drawer.vue b/ant-design-vue-jeecg/src/views/functionx/modules/FunctionxModal__Style#Drawer.vue index 867d695..e525b4d 100644 --- a/ant-design-vue-jeecg/src/views/functionx/modules/FunctionxModal__Style#Drawer.vue +++ b/ant-design-vue-jeecg/src/views/functionx/modules/FunctionxModal__Style#Drawer.vue @@ -39,6 +39,12 @@ this.$refs.realForm.add(); }) }, + add1 (moduleId) { + this.visible=true + this.$nextTick(()=>{ + this.$refs.realForm.add(moduleId); + }) + }, edit (record) { this.visible=true this.$nextTick(()=>{ diff --git a/ant-design-vue-jeecg/src/views/rulex/modules/RulexForm.vue b/ant-design-vue-jeecg/src/views/rulex/modules/RulexForm.vue index 1ec86c9..11e8ff1 100644 --- a/ant-design-vue-jeecg/src/views/rulex/modules/RulexForm.vue +++ b/ant-design-vue-jeecg/src/views/rulex/modules/RulexForm.vue @@ -216,6 +216,17 @@ export default { add() { this.edit(this.modelDefault); }, + add1(functionId,moduleId) { + this.functionId=functionId; + this.model.functionId=functionId; + this.moduleId=moduleId; + this.model.moduleId=moduleId; + this.sort(); + this.shiti(); + this.modelDefault = JSON.parse(JSON.stringify(this.model)); + this.edit(this.modelDefault); + + }, edit(record) { this.model = Object.assign({}, record); this.visible = true; diff --git a/ant-design-vue-jeecg/src/views/rulex/modules/RulexModal__Style#Drawer.vue b/ant-design-vue-jeecg/src/views/rulex/modules/RulexModal__Style#Drawer.vue index 7827922..0fb99ea 100644 --- a/ant-design-vue-jeecg/src/views/rulex/modules/RulexModal__Style#Drawer.vue +++ b/ant-design-vue-jeecg/src/views/rulex/modules/RulexModal__Style#Drawer.vue @@ -39,6 +39,12 @@ this.$refs.realForm.add(); }) }, + add1 (functionId,moduleId) { + this.visible=true + this.$nextTick(()=>{ + this.$refs.realForm.add1(functionId,moduleId); + }) + }, edit (record) { this.visible=true this.$nextTick(()=>{ diff --git a/ant-design-vue-jeecg/src/views/task/modules/TaskForm.vue b/ant-design-vue-jeecg/src/views/task/modules/TaskForm.vue index f2212eb..7103f54 100644 --- a/ant-design-vue-jeecg/src/views/task/modules/TaskForm.vue +++ b/ant-design-vue-jeecg/src/views/task/modules/TaskForm.vue @@ -4,28 +4,71 @@ + + + + + + + + + + + + - - + - + + + + + + + + + + + - - - + + + + + +
+ {{ item.type_Name }} + + + {{ child.type_Name }} + + +
+
+ - + @@ -42,86 +85,88 @@ auto-size /> + + + + + - - - + + + - + + :dict-code="functionx" + style="width: 80%" @change="fillFunctionName()"> + - - + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - + - - - + + + + - - - - + + - - + + - - - + + + - - + + + @@ -130,16 +175,18 @@ - - - - + + +
+ + + @@ -150,12 +197,23 @@ import {httpAction, getAction} from '@api/manage' import {validateDuplicateValue} from '@/utils/util' import JVxeDateCell from "@comp/jeecg/JVxeTable/components/cells/JVxeDateCell"; import JMultiSelectTag from "@/components/dict/JMultiSelectTag" +import TaskModal from "@views/task/modules/TaskModal.vue"; +import {JeecgListMixin} from '@/mixins/JeecgListMixin' +import {mixinDevice} from "@/utils/mixin"; +import modulexModal from "@views/modulex/modules/ModulexModal__Style#Drawer.vue"; +import FunctionxModal from "@views/functionx/modules/FunctionxModal__Style#Drawer.vue"; +import RulexModal from "@views/rulex/modules/RulexModal__Style#Drawer.vue"; export default { name: 'TaskForm', + mixins: [JeecgListMixin, mixinDevice], components: { + RulexModal, + FunctionxModal, + modulexModal, + TaskModal, JVxeDateCell, - JMultiSelectTag + JMultiSelectTag, }, props: { //表单禁用 @@ -167,6 +225,12 @@ export default { }, data() { return { + modulex: "modulex,module_name,id", + functionx: "functionx,function_name,id", + rulex: "rulex,rule_no,id", + task: "task,task_name,id", + value: new Date(), + model: { workLevel: 2, workStatus: 0, @@ -175,14 +239,49 @@ export default { expectedDuration: 1, // curryUserName: '', }, + options: [], + // labelCol: { + // xs: {span: 24}, + // sm: {span: 5}, + // }, + // wrapperCol: { + // xs: {span: 24}, + // sm: {span: 16}, + // }, labelCol: { - xs: {span: 24}, - sm: {span: 5}, + xs: {span: 23}, + sm: {span: 6}, }, wrapperCol: { xs: {span: 24}, sm: {span: 16}, }, + // 任务层级 任务类型 任务状态 + labelCol1: { + xs: {span: 24}, + sm: {span: 3}, + }, + wrapperCol1: { + xs: {span: 24}, + sm: {span: 21}, + }, + // 任务描述 + labelCol2: { + xs: {span: 24}, + sm: {span: 3}, + }, + wrapperCol2: { + xs: {span: 24}, + sm: {span: 20}, + }, + labelCol3: { + xs: {span: 24}, + sm: {span: 7}, + }, + wrapperCol3: { + xs: {span: 24}, + sm: {span: 15}, + }, confirmLoading: false, validatorRules: { taskName: [ @@ -227,6 +326,7 @@ export default { // queryTaskTypeById: "/taskType/taskType/queryById", fillTaskName: "/task/task/fillTaskName", list: "/task/task/list", + listtasktype: '/taskType/taskType/getTypeMap' } } @@ -240,8 +340,22 @@ export default { created() { //备份model原始值 this.modelDefault = JSON.parse(JSON.stringify(this.model)); + this.tasktype() }, methods: { + tasktype() { + getAction(this.url.listtasktype).then((res) => { + const data = res.result; + this.options = Object.entries(data).map(([key, value]) => { + const item = JSON.parse(key); + item.children = value; + return item; + }) + }) + }, + popupCallback(value,row){ + this.model = Object.assign(this.model, row); + }, handleCheckChange(data, checked, tree) { if (checked) { this.currentNodeData.id = data.id @@ -255,6 +369,8 @@ export default { } , fillTaskName() { + this.modulex = "modulex,module_name,id,project_id='"+this.model.projectId+"'"; + let that = this; let fillTaskName = ""; let param = { @@ -280,7 +396,38 @@ export default { } } , - + fillLevelName(){ + this.task = "task,task_name,id,level='"+this.model.level+"'"; + } + , + handleAdd3: function () { + this.$refs.modalForm3.add(); + this.$refs.modalForm3.title = "新增"; + this.$refs.modalForm3.disableSubmit = false; + }, + // handleAdd1: function (moduleId) { + // console.log(this.moduleId,'1111') + // this.$refs.modalForm1.add(); + // this.$refs.modalForm1.title = "新增"; + // this.$refs.modalForm1.disableSubmit = false; + // }, + handleAdd1(moduleId){ + console.log(moduleId+"22222222222222") + this.$refs.modalForm1.add1(moduleId) + this.$refs.modalForm1.title = "新增"; + this.$refs.modalForm1.disableSubmit = false; + }, + handleAdd2: function (functionId,moduleId) { + this.$refs.modalForm2.add1(functionId,moduleId); + this.$refs.modalForm2.title = "新增"; + this.$refs.modalForm2.disableSubmit = false; + }, + fillModuleName() { + this.functionx = "functionx,function_name,id,module_id='"+this.model.moduleId+"'"; + }, + fillFunctionName(){ + this.rulex = "rulex,rule_no,id,function_id='"+this.model.functionId+"'"; + }, // 获取当前日期的方法 getProjectNum() { const projectTime = new Date() // 当前中国标准时间 @@ -350,4 +497,19 @@ export default { , } } - \ No newline at end of file + + diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/task/controller/TaskController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/task/controller/TaskController.java index af575b6..91e35c3 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/task/controller/TaskController.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/task/controller/TaskController.java @@ -39,6 +39,7 @@ import org.springframework.web.servlet.ModelAndView; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.math.BigDecimal; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; @@ -60,6 +61,14 @@ public class TaskController extends JeecgController { private static final String ADMIN = "admin"; private static final String FORMAT = "yyyy/MM/dd HH:mm:ss"; + private static final long DAYWORKTIME = 35*60*60*100*2; + private static final long DAYTIME = 24*60*60*1000; + + private static final String MORINGSTART = " 08:30:00"; + private static final String MORINGEND = " 12:00:00"; + private static final String AFTERNOONSTART = " 14:30:00"; + private static final String AFTERNOONEND= " 18:00:00"; + @Resource private IProjectxService iProjectxService; @@ -358,15 +367,206 @@ public class TaskController extends JeecgController { taskService.updateById(task); return Result.OK("编辑成功!"); } - + /** + * 提交任务,更新状态,同时计算实际任务时长 + * 计算一整天,之后算头和尾时间 + * @param task + * @return + */ @ApiOperation(value = "任务管理-更新状态", notes = "任务管理-更新状态") @PutMapping(value = "/updateWorkStatus") public Result updateWorkStatus(@RequestBody Task task) { - task.setUpdateTime(new Date()); + Date time = new Date(); + + if (task.getWorkStatus() == 3){ + //获取数据 + Task oldTask = taskService.query().eq("id", task.getId()).one(); + Date startTime = oldTask.getStartTime(); + long realTime = 0; + try { + realTime = realDuration(startTime, time); + } catch (ParseException e) { + throw new RuntimeException(e); + } + + //设置更新数据 + double realTimeHour = (double)realTime/(60*60*1000); + realTimeHour = new BigDecimal(realTimeHour).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue(); + task.setRealDuration(realTimeHour); + task.setSubmitTime(time); + } + + task.setUpdateTime(time); taskService.updateById(task); return Result.OK("编辑成功!"); } + //计算真实时间, 单位:小时 + private long realDuration(Date startTime, Date endTime) throws ParseException { + long workTime = 0; + long millisecond = endTime.getTime() - startTime.getTime(); + //统计整天时间 + workTime += (millisecond / DAYTIME) * DAYWORKTIME; + millisecond = millisecond % DAYTIME; + + + SimpleDateFormat sdf1 = new SimpleDateFormat("HH:mm:ss"); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd"); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + String time = dateFormat.format(new Date()); + String start = sdf1.format(startTime); + String time0 = time + " " + start; + + startTime = sdf.parse(time0); + String time1 = time + MORINGSTART; + String time2 = time + MORINGEND; + String time3 = time + AFTERNOONSTART; + String time4 = time + AFTERNOONEND; + Date date3 = sdf.parse(time3); + Date date2 = sdf.parse(time2); + Date date1 = sdf.parse(time1); + Date date4 = sdf.parse(time4); + + //从start往后推到end,要判断大量情况 + if (startTime.compareTo(endTime) > 0){ + //时间跨度两天,但总时间不超过24小时 + if (startTime.compareTo(date1) <= 0) + startTime = date1; //任务发布在8点前,从8点开始算 + if (startTime.compareTo(date2) <= 0){ + //早上有工作时间 + workTime += date2.getTime() - startTime.getTime(); + //跨度两天,下午必有任务时间 + workTime += DAYWORKTIME/2; + //第二天下午必没有工作时间,判断第二天早上是否有部分工作时间 + if (endTime.compareTo(date1) > 0) + workTime += endTime.getTime() - date1.getTime(); //第二天早上有工作时间 + return workTime; //计算完成,返回结果 + } + + //上午没有工作时间 + if (startTime.compareTo(date3) <= 0) + startTime = date3; //任务发布时间在12点后,14点前 + if (startTime.compareTo(date4) <= 0) //下午有工作时间 + workTime += date4.getTime() - startTime.getTime(); + if (endTime.compareTo(date1) <= 0) + return workTime; //第二天没有工作时间 + if (endTime.compareTo(date2) <= 0){ + workTime += endTime.getTime() - date1.getTime(); //第二天上午有部分工作时间 + return workTime; //必然下午没有工作时间 + } + workTime += DAYWORKTIME/2; //第二天上午工作时间占满 + if (endTime.compareTo(date3) <= 0) + return workTime; //下午没有工作时间 + if (endTime.compareTo(date4) >= 0) + endTime = date4; //下午干满了 + workTime += endTime.getTime() - date3.getTime(); + return workTime; + }else { + //时间跨度没有超过两天 + if (startTime.compareTo(date1) <= 0) + startTime = date1; //发布任务在8点之前 + if (startTime.compareTo(date2) <= 0){ + //上午发布的任务 + if (endTime.compareTo(date2) <= 0){ + //上午提交的任务 + workTime += endTime.getTime() - startTime.getTime(); + return workTime; + } + workTime += date2.getTime() - startTime.getTime(); //上午没有提交任务 + if (endTime.compareTo(date3) <= 0) + return workTime; //中午12点后14点前提交任务 + if (endTime.compareTo(date4) >= 0) + endTime = date4; //时间偏移 + workTime += endTime.getTime() - date3.getTime(); //下午工作时间 + }else { + //下午发布的任务 + if (startTime.compareTo(date3) <= 0) + startTime = date3; //12点之后,14点之前发布任务 + if (endTime.compareTo(date4) >= 0) + endTime = date4; //时间偏移 + workTime += endTime.getTime() - startTime.getTime(); + } + return workTime; + } + } + + /** + * 计算预计结束时间 + * @param task + * @return + */ + @GetMapping("/estimateTime") + public Result calculating(Task task){ + if (task.getStartTime() == null || task.getExpectedDuration() == null) + return Result.error("参数不足,无法计算预计结束时间"); + Date date = null; + try { + date = estimateTime(task.getStartTime(), task.getExpectedDuration()); + } catch (ParseException e) { + throw new RuntimeException(e); + } + return Result.OK(date); + } + + /** + * 计算预计结束时间方法 + * @param startTime + * @param expectedDuration + * @return + */ + private Date estimateTime(Date startTime, Double expectedDuration) throws ParseException { + long millisecond = (long) (expectedDuration * 60 * 60 * 1000); + //整天偏移量 + int offset = (int) (millisecond / DAYWORKTIME); + //剩余工作量 + millisecond = millisecond % DAYWORKTIME; + + + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd"); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + + String time = dateFormat.format(startTime); + String time1 = time + MORINGSTART; + String time2 = time + MORINGEND; + String time3 = time + AFTERNOONSTART; + String time4 = time + AFTERNOONEND; + Date date3 = sdf.parse(time3); + Date date2 = sdf.parse(time2); + Date date1 = sdf.parse(time1); + Date date4 = sdf.parse(time4); + + long tempTime = 0; + if (startTime.compareTo(date1) <= 0) + startTime = date1; //任务发布在8点半之前,修正时间 + if (startTime.compareTo(date2) < 0){ + //上午发布任务 + tempTime = date2.getTime() - startTime.getTime(); + if (tempTime >= millisecond) + return new Date(startTime.getTime() + millisecond + DAYTIME*offset); //预计上午结束,直接偏移剩余时间 + //上午剩余时间全部工作,时间进行修正到下午工作开始时间 + millisecond -= tempTime; + startTime = date3; + } + + if (startTime.compareTo(date3) <= 0) + startTime = date3; //任务是下午发布且在2点半之前,修正时间 + if (startTime.compareTo(date4) < 0){ + //下午发布任务 + tempTime = date4.getTime() - startTime.getTime(); + if (tempTime >= millisecond) + return new Date(startTime.getTime() + millisecond + DAYTIME*offset); + } + //时间修正,天数偏移量加1,到这里有两中情况,1、白天工作时间不足抵消 2、下午6点之后发布任务 + offset ++; + startTime = date1; + + tempTime = date2.getTime() - date1.getTime(); + if (tempTime >= millisecond) + return new Date(startTime.getTime() + millisecond + DAYTIME*offset); + //上午偏移不足,下午一定够,因为不会跨两天 + millisecond -= tempTime; + return new Date(startTime.getTime() + millisecond + DAYTIME*offset); + } /** * 通过id删除 * diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/taskType/controller/TaskTypeController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/taskType/controller/TaskTypeController.java index 6207abe..2a254c4 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/taskType/controller/TaskTypeController.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/taskType/controller/TaskTypeController.java @@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; @@ -18,6 +20,7 @@ import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.oConvertUtils; import org.jeecg.modules.taskType.entity.TaskType; +import org.jeecg.modules.taskType.entity.dto.TypeDto; import org.jeecg.modules.taskType.service.ITaskTypeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -25,8 +28,7 @@ import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.util.Arrays; -import java.util.List; +import java.util.*; /** * @Description: 任务类型管理 @@ -41,9 +43,44 @@ import java.util.List; public class TaskTypeController extends JeecgController { @Autowired private ITaskTypeService taskTypeService; - + @Autowired + private ObjectMapper objectMapper; private static final String ADMIN_COLUMN_KEY = "99"; + /** + * 查询所有项目类型,并根据pid分类 + * @return + */ + @GetMapping("/getTypeMap") + public Result getMapType(){ + Map> listMap = new HashMap<>(); + + List hasChild = taskTypeService.query().eq("has_child", "1").list(); + if (hasChild == null || hasChild.size() == 0) + return Result.error("查询任务类型失败"); + for (TaskType taskType : hasChild) { + //准备map的key + String typeName = taskType.getTypeName(); + String id = taskType.getId(); + TypeDto typeDto = new TypeDto(id, typeName); + + //准备map的value + List list = taskTypeService.query().eq("pid", id).list(); + List typeDtoList = new ArrayList<>(list.size()); + for (TaskType type : list) + typeDtoList.add(new TypeDto(type.getId(), type.getTypeName())); + //放入数据到map + String key = null; + try { + key = objectMapper.writeValueAsString(typeDto); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + + listMap.put(key, typeDtoList); + } + return Result.OK(listMap); + } @ApiOperation(value = "文章栏目-分页列表查询", notes = "文章栏目-分页列表查询") @GetMapping(value = "/rootList") public Result rootList(TaskType taskType, diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/taskType/entity/dto/TypeDto.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/taskType/entity/dto/TypeDto.java new file mode 100644 index 0000000..c1f32d8 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/taskType/entity/dto/TypeDto.java @@ -0,0 +1,24 @@ +package org.jeecg.modules.taskType.entity.dto; + +import lombok.Data; + +/** + * @Author shkstart + * @create 2023-05-13-17:05 + */ +@Data +public class TypeDto { + + public TypeDto(){ + + } + + public TypeDto(String id, String type_Name) { + this.id = id; + this.type_Name = type_Name; + } + + private String id; + + private String type_Name; +} \ No newline at end of file