ソースを参照

Merge remote-tracking branch 'origin/master'

yusm 5 日 前
コミット
27902d91f3
100 ファイル変更19678 行追加3433 行削除
  1. 38 5
      fhKeeper/formulahousekeeper/collectdata/src/main/java/com/management/collectdata/controller/DataCollectController.java
  2. BIN
      fhKeeper/formulahousekeeper/course-pc/src/assets/image/yunketang.png
  3. 23 2
      fhKeeper/formulahousekeeper/course-pc/src/routes.js
  4. 177 0
      fhKeeper/formulahousekeeper/course-pc/src/views/coursemanagement/addVideo.vue
  5. 976 0
      fhKeeper/formulahousekeeper/course-pc/src/views/coursemanagement/list copy 2.vue
  6. 1634 0
      fhKeeper/formulahousekeeper/course-pc/src/views/coursemanagement/list copy.vue
  7. 485 986
      fhKeeper/formulahousekeeper/course-pc/src/views/coursemanagement/list.vue
  8. 415 0
      fhKeeper/formulahousekeeper/course-pc/src/views/lecturerManagement/index.vue
  9. 336 0
      fhKeeper/formulahousekeeper/course-pc/src/views/offlineTraining/offlineTraining.vue
  10. 0 1
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/constant/Constant.java
  11. 0 61
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FinanceMonthlyWorktimeController.java
  12. 2 2
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ProjectController.java
  13. 95 329
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/TaskController.java
  14. 78 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/TaskTypeController.java
  15. 0 1
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/WeiXinCorpController.java
  16. 38 78
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/entity/Task.java
  17. 30 22
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/entity/TaskExecutor.java
  18. 60 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/entity/TaskType.java
  19. 16 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/entity/TaskWithAuditor.java
  20. 12 14
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/mapper/ProjectMapper.java
  21. 3 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/mapper/TaskMapper.java
  22. 16 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/mapper/TaskTypeMapper.java
  23. 0 29
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/service/FinanceMonthlyWorktimeService.java
  24. 1 1
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/service/ProjectService.java
  25. 16 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/service/TaskTypeService.java
  26. 0 13
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/service/impl/DingDingServiceImpl.java
  27. 0 375
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/service/impl/FinanceMonthlyWorktimeServiceImpl.java
  28. 11 8
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/service/impl/InformationServiceImpl.java
  29. 141 169
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java
  30. 4 4
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/service/impl/SysRoleServiceImpl.java
  31. 84 84
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/service/impl/TaskServiceImpl.java
  32. 0 1088
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/service/impl/TaskServiceImpl.java~
  33. 20 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/service/impl/TaskTypeServiceImpl.java
  34. 24 57
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/service/impl/UserServiceImpl.java
  35. 1 1
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/util/CodeGenerator.java
  36. 1 4
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/resources/application.yml
  37. 16 62
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/resources/mapper/ProjectMapper.xml
  38. 5 2
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/resources/mapper/TaskExecutorMapper.xml
  39. 63 16
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/resources/mapper/TaskMapper.xml
  40. 19 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/resources/mapper/TaskTypeMapper.xml
  41. 3 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  42. 31 16
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/DataCollectTask.java
  43. 1 1
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  44. 2 2
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/weekEdit.vue
  45. 5 0
      fhKeeper/formulahousekeeper/timesheet_mld/.babelrc
  46. 8 0
      fhKeeper/formulahousekeeper/timesheet_mld/.gitignore
  47. 12 0
      fhKeeper/formulahousekeeper/timesheet_mld/.vscode/settings.json
  48. 21 0
      fhKeeper/formulahousekeeper/timesheet_mld/LICENSE
  49. 0 0
      fhKeeper/formulahousekeeper/timesheet_mld/README.md
  50. 12 0
      fhKeeper/formulahousekeeper/timesheet_mld/build-private.bat
  51. 1 0
      fhKeeper/formulahousekeeper/timesheet_mld/build.bat
  52. 35 0
      fhKeeper/formulahousekeeper/timesheet_mld/build/build.js
  53. 48 0
      fhKeeper/formulahousekeeper/timesheet_mld/build/check-versions.js
  54. 9 0
      fhKeeper/formulahousekeeper/timesheet_mld/build/dev-client.js
  55. 89 0
      fhKeeper/formulahousekeeper/timesheet_mld/build/dev-server.js
  56. 79 0
      fhKeeper/formulahousekeeper/timesheet_mld/build/utils.js
  57. 12 0
      fhKeeper/formulahousekeeper/timesheet_mld/build/vue-loader.conf.js
  58. 78 0
      fhKeeper/formulahousekeeper/timesheet_mld/build/webpack.base.conf.js
  59. 38 0
      fhKeeper/formulahousekeeper/timesheet_mld/build/webpack.dev.conf.js
  60. 125 0
      fhKeeper/formulahousekeeper/timesheet_mld/build/webpack.prod.conf.js
  61. BIN
      fhKeeper/formulahousekeeper/timesheet_mld/card_img.png
  62. 6 0
      fhKeeper/formulahousekeeper/timesheet_mld/config/dev.env.js
  63. 67 0
      fhKeeper/formulahousekeeper/timesheet_mld/config/index.js
  64. 3 0
      fhKeeper/formulahousekeeper/timesheet_mld/config/prod.env.js
  65. BIN
      fhKeeper/formulahousekeeper/timesheet_mld/favicon.ico
  66. 156 0
      fhKeeper/formulahousekeeper/timesheet_mld/index.html
  67. 10281 0
      fhKeeper/formulahousekeeper/timesheet_mld/package-lock.json
  68. 91 0
      fhKeeper/formulahousekeeper/timesheet_mld/package.json
  69. 156 0
      fhKeeper/formulahousekeeper/timesheet_mld/setIndex/indexOne.html
  70. 127 0
      fhKeeper/formulahousekeeper/timesheet_mld/setIndex/indexTwo.html
  71. 135 0
      fhKeeper/formulahousekeeper/timesheet_mld/src/App.vue
  72. 17 0
      fhKeeper/formulahousekeeper/timesheet_mld/src/api/api.js
  73. 3 0
      fhKeeper/formulahousekeeper/timesheet_mld/src/api/index.js
  74. 1 0
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/citys/address.js
  75. 1 0
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/citys/shju.json
  76. 539 0
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/iconfont/demo.css
  77. 1798 0
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/iconfont/demo_index.html
  78. 295 0
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/iconfont/iconfont.css
  79. BIN
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/iconfont/iconfont.eot
  80. 1 0
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/iconfont/iconfont.js
  81. 499 0
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/iconfont/iconfont.json
  82. 53 0
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/iconfont/iconfont.svg
  83. BIN
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/iconfont/iconfont.ttf
  84. BIN
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/iconfont/iconfont.woff
  85. BIN
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/iconfont/iconfont.woff2
  86. BIN
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/404.png
  87. BIN
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/Step1.jpg
  88. BIN
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/Step2.jpg
  89. BIN
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/Step3.jpg
  90. BIN
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/aacbc.png
  91. BIN
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/background.png
  92. BIN
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/close.gif
  93. BIN
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/code.jpg
  94. BIN
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/dui.png
  95. BIN
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/hanglie.png
  96. BIN
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/hanglie_corp.png
  97. BIN
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/hangs.png
  98. BIN
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/head_logo.png
  99. BIN
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/hong.png
  100. 0 0
      fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/huang.png

+ 38 - 5
fhKeeper/formulahousekeeper/collectdata/src/main/java/com/management/collectdata/controller/DataCollectController.java

@@ -362,8 +362,37 @@ public class DataCollectController {
                     userFvTime.setProcinstId(resultSet.getString("id"));
                     userFvTime.setUserId(resultSet.getString("emp_no"));
                     userFvTime.setWorkDate(null==resultSet.getDate("attendance_date")?null:LocalDate.parse(sdfYmd.format(resultSet.getDate("attendance_date")), DateTimeFormatter.ofPattern("yyyy-MM-dd")));
-                    userFvTime.setStartTime(resultSet.getString("come1"));
-                    userFvTime.setEndTime(resultSet.getString("go1"));
+                    String startTime = resultSet.getString("come1");
+                    //从9:00开始计算,小于9:00的以9:00为准,向上取30分钟, 比如9:09,就转换为9:30
+                    if (startTime.compareTo("09:00") < 0) {
+                        startTime = "09:00";
+                    }
+                    String[] startTimeArr = startTime.split(":");
+                    int hour = Integer.parseInt(startTimeArr[0]);
+                    int minute = Integer.parseInt(startTimeArr[1]);
+                    if (minute > 0) {
+                        if (minute <= 30) {
+                            minute = 30;
+                        } else {
+                            hour += 1;
+                            minute = 0;
+                        }
+                    }
+
+                    startTime = formatTime(hour, minute);
+
+                    String endTime = resultSet.getString("go1");
+                    String[] endTimeArr = endTime.split(":");
+                    hour = Integer.parseInt(endTimeArr[0]);
+                    minute = Integer.parseInt(endTimeArr[1]);
+                    if (minute < 30) {
+                        minute = 0;
+                    } else {
+                        minute = 30;
+                    }
+                    endTime = formatTime(hour, minute);
+                    userFvTime.setStartTime(startTime);
+                    userFvTime.setEndTime(endTime);
                     userFvTime.setWorkHours(calculateWorkHoursFromTime(userFvTime));
                     userFvTime.setOverTimeSeconds(null==resultSet.getBigDecimal("worktime_total_hour")?null:resultSet.getBigDecimal("worktime_total_hour").setScale(1,RoundingMode.HALF_UP)
                             .multiply(new BigDecimal("3600")).longValue());
@@ -378,6 +407,13 @@ public class DataCollectController {
         return resList;
     }
 
+    String formatTime(int hour, int minute) {
+        //格式化一下为HH:mm
+        DateTimeFormatter df = DateTimeFormatter.ofPattern("HH:mm");
+        LocalTime localTime = LocalDateTime.now().withHour(hour).withMinute(minute).withSecond(0).withNano(0).toLocalTime();
+        return localTime.format(df);
+    }
+
     private float calculateWorkHoursFromTime(UserFvTime userFvTime) {
         String baseMorningEnd = "12:00";
         String baseAfternoonStart = "13:00";
@@ -401,9 +437,6 @@ public class DataCollectController {
         double time = bigDecimal.doubleValue();
         if (time < 0) {
             time = 0;
-        } else {
-            BigDecimal decimal = new BigDecimal(time);
-            time = decimal.setScale(0, BigDecimal.ROUND_HALF_UP).doubleValue();
         }
         return (float)time;
     }

BIN
fhKeeper/formulahousekeeper/course-pc/src/assets/image/yunketang.png


+ 23 - 2
fhKeeper/formulahousekeeper/course-pc/src/routes.js

@@ -8,6 +8,8 @@ import Home from './views/Home.vue'
 import PdfView from './views/pdf/pdfview';
 //课程管理
 import courselist from './views/coursemanagement/list';
+import lecturerList from './views/lecturerManagement/index.vue'
+import offlineTraining from './views/offlineTraining/offlineTraining.vue'
 
 Vue.use(Router)
 
@@ -40,13 +42,32 @@ export const allRouters = [
             { path: '/courselist', component: courselist, name: '课程管理' }
         ]
     },
-    
+    {
+        path: '/lecturer',
+        component: Home,
+        name: '讲师管理',
+        iconCls: 'iconfont firerock-iconkehu',
+        leaf: true,
+        children: [
+            { path: '/lecturer', component: lecturerList, name: '讲师管理' }
+        ]
+    },
     {
         path: '/404',
         component: NotFound,
         name: '',
         hidden: true
     },
+    {
+        path: '/offline-training',
+        component: Home,
+        name: '线下研修班',
+        iconCls: 'iconfont firerock-iconkehu',
+        leaf: true,
+        children: [
+            { path: '/offline-training', component: offlineTraining, name: '线下研修班' }
+        ]
+    },
     {
         path: '*',
         hidden: true,
@@ -55,4 +76,4 @@ export const allRouters = [
 ]
 export default new Router({
     routes: allRouters
-})
+})

+ 177 - 0
fhKeeper/formulahousekeeper/course-pc/src/views/coursemanagement/addVideo.vue

@@ -0,0 +1,177 @@
+<template>
+  <div class="video-list-container">
+    <draggable v-model="videoListComputed" handle=".drag-handle" @end="onDragEnd">
+      <div
+        v-for="(item, index) in videoListComputed"
+        :key="index"
+        :class="['video-item', item.videoError ? 'error-video' : '']"
+        v-loading="item.videoLoading"
+        element-loading-text="上传中,请稍后..."
+        element-loading-spinner="el-icon-loading"
+        element-loading-background="rgba(0, 0, 0, 0.8)"
+        element-loading-customClass="loadingTextClolr"
+      >
+        <el-row :gutter="20">
+          <el-col :span="1">
+            <i class="el-icon-rank drag-handle" style="cursor: move; line-height: 32px;"></i>
+          </el-col>
+          <el-col :span="6">
+            <el-input v-model="item.videoName" size="small" placeholder="请输入视频名称"></el-input>
+          </el-col>
+          <el-col :span="4">
+            <el-select v-model="item.videoLecturerId" placeholder="请选择教师" size="small" style="width: 100%">
+              <el-option
+                v-for="type in videoTypes"
+                :key="type.id"
+                :label="type.teacherName"
+                :value="type.id"
+              ></el-option>
+            </el-select>
+          </el-col>
+          <el-col :span="8" style="display: flex; align-items: center;">
+            <div>试看时间(分钟)</div>
+            <el-input-number
+              size="small"
+              v-model="item.videoPreviewTime"
+              :min="0"
+              :max="600"
+              placeholder="试看时间(秒)"
+            ></el-input-number>
+          </el-col>
+          <el-col :span="5">
+            <el-button size="small" type="primary" @click="previewingVideoSrc(item)">预览视频</el-button>
+            <el-button size="small" type="danger" @click="removeRow(index)">删除</el-button>
+          </el-col>
+        </el-row>
+      </div>
+    </draggable>
+
+    <!-- 预览视频 -->
+    <el-dialog title="预览视频" append-to-body :visible.sync="previewingVideoVisable" width="900px" top="6.5vh" :before-close="handleClose">
+      <div class="previewingVideo">
+        <video :src="previewVideoSrc" :poster="require('../../assets/image/yunketang.png')" controls></video>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import draggable from 'vuedraggable'
+
+export default {
+  name: 'VideoListEditor',
+  components: {
+    draggable
+  },
+  props: {
+    value: {
+      type: Array,
+      required: true
+    }
+  },
+  computed: {
+    videoListComputed: {
+      get() {
+        return this.value
+      },
+      set(val) {
+        this.$emit('input', val)
+      }
+    }
+  },
+  data() {
+    return {
+      videoTypes: [],
+      previewVideoSrc: '',
+      previewingVideoVisable: false
+    }
+  },
+  methods: {
+    previewingVideoSrc(row) {
+      console.log(row)
+      this.previewVideoSrc = row.videoUrl
+      this.previewingVideoVisable = true
+    },
+    getAllTeachers() {
+      this.http.post(`/course-teacher/list`, {}, res => {
+        this.videoTypes = res.data || []
+      })
+    },
+    removeRow(index) {
+      const list = [...this.videoListComputed]
+      const row = list[index]
+      this.$confirm(`此操作将删除【${row.videoName}】视频, 是否继续?`, '删除视频', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.$message({
+          type: 'success',
+          message: '删除成功!'
+        });
+
+        list.splice(index, 1)
+        this.videoListComputed = list
+      })
+    },
+    onDragEnd() {
+      console.log('排序完成', this.videoListComputed)
+    },
+    handleClose(done) {
+      // 清除 video 的 src,释放资源
+      const videoEl = this.$refs.previewVideo
+      if (videoEl) {
+        videoEl.pause()
+        videoEl.removeAttribute('src')
+        videoEl.load()
+      }
+      this.previewingVideoVisable = false
+      this.previewVideoSrc = ''
+      done()
+    }
+  },
+  mounted() {
+    this.getAllTeachers()
+  }
+}
+</script>
+
+<style scoped>
+.video-list-container {
+  padding: 20px;
+}
+.video-item {
+  margin-bottom: 15px;
+  padding: 10px;
+  background: #f5f7fa;
+  border-radius: 4px;
+  position: relative;
+}
+.error-video {
+  background: #e6a23c;
+}
+</style>
+
+<style lang="scss">
+.video-list-container {
+  .el-loading-spinner i {
+    color: #fff !important;
+  }
+  .el-loading-text {
+    color: #fff !important;
+  }
+}
+
+.previewingVideo {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 100%;
+  height: 68vh;
+}
+
+.previewingVideo video {
+  width: 100%;
+  height: 100%;
+}
+</style>

+ 976 - 0
fhKeeper/formulahousekeeper/course-pc/src/views/coursemanagement/list copy 2.vue

@@ -0,0 +1,976 @@
+<template>
+    <section>
+        <!--工具条-->
+        <el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
+            <el-form :inline="true" @submit.native.prevent>
+                <el-form-item label="课程分类">
+                    <el-select v-model="categoryValue" placeholder="请选择" clearable @change="searchList" size="small">
+                        <el-option v-for="item in categoryOptions" :key="item.value" :label="item.label"
+                            :value="item.value">
+                        </el-option>
+                    </el-select>
+                </el-form-item> 
+                <el-form-item label="课程名称">
+                    <el-input v-model="keyword" placeholder="请输入" clearable @change="searchList"
+                        size="small"></el-input>
+                </el-form-item>
+                <el-form-item label="讲师">
+                    <el-input v-model="instructor" placeholder="请输入" clearable @change="searchList"
+                        size="small"></el-input>
+                </el-form-item>
+                <el-form-item>
+                    <el-button type="primary" @click="addCourse()" size="small">添加课程</el-button>
+                </el-form-item>
+                <el-form-item>
+                    <el-button type="primary" @click="batchManage" size="small">分类管理</el-button>
+                </el-form-item>
+            </el-form>
+        </el-col>
+
+        <!--列表-->
+        <el-table :data="list" highlight-current-row v-loading="listLoading" :height="tableHeight" style="width: 100%;">
+            <el-table-column type="index" width="50" align="center" label="#"></el-table-column>
+            <el-table-column label="封面" width="120" align="center">
+                <template slot-scope="scope">
+                    <img v-if="scope.row.coverImage" :src="scope.row.coverImage" class="course-cover-image" />
+                    <span v-else>无封面</span>
+                </template>
+            </el-table-column>
+            <el-table-column prop="courseTypeName" label="课程分类" min-width="120" align="center"></el-table-column>
+            <el-table-column prop="courseName" label="课程名称" min-width="180" align="center"></el-table-column>
+            <el-table-column prop="courseInstructor" label="讲师" min-width="120" align="center"></el-table-column>
+            <el-table-column prop="coursePrice" label="价格" min-width="100" align="center">
+                <template slot-scope="scope">
+                    <span>¥{{ scope.row.coursePrice }}</span>
+                </template>
+            </el-table-column>
+            <el-table-column prop="courseDuration" label="课程时间" min-width="120" align="center">
+                <template slot-scope="scope">
+                    <span>{{ scope.row.courseDuration ? scope.row.courseDuration + '分钟' : '' }}</span>
+                </template>
+            </el-table-column>
+
+            <el-table-column label="操作" width="340" class-name="btns" header-align="center" fixed="right">
+                <template slot-scope="scope">
+                    <el-button size="mini" type="primary" @click="addVideo(scope.row)">添加视频</el-button>
+                    <el-button size="mini" type="primary" @click="addCourse(scope.row)">编辑</el-button>
+                    <el-button size="mini" type="danger" @click="deleteItem(scope.row)">删除</el-button>
+                    <el-button size="mini" :type="scope.row.courseStatus === 1 ? 'warning' : 'success'"
+                        @click="uploadItem(scope.row)">{{ scope.row.courseStatus === 1 ? '下架' : '上架' }}</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+
+        <!--工具条-->
+        <el-col :span="24" class="toolbar">
+            <el-pagination
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+                :page-sizes="[10, 20, 50, 100]"
+                :page-size="size"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="total"
+                style="float:right;"
+            ></el-pagination>
+        </el-col>
+
+        <!-- 分类管理 -->
+        <el-dialog :visible.sync="categoryManageVisible" title="分类管理" width="600px">
+            <el-table :data="categoryList" style="width: 100%" max-height="400">
+                <el-table-column prop="label" label="分类名称" width="180"></el-table-column>
+                <el-table-column label="封面" width="180">
+                    <template slot-scope="scope">
+                        <img v-if="scope.row.coverImage" :src="scope.row.coverImage" class="category-cover-image" />
+                        <span v-else>无封面</span>
+                    </template>
+                </el-table-column>
+                <el-table-column label="操作" width="180">
+                    <template slot-scope="scope">
+                        <el-button size="mini" type="primary" @click="setCategoryCover(scope.$index, scope.row)">设置封面</el-button>
+                        <el-button size="mini" type="danger" @click="deleteCategory(scope.$index, scope.row)">删除</el-button>
+                    </template>
+                </el-table-column>
+            </el-table>
+            <div style="margin-top: 20px;">
+                <el-form :inline="true" :model="newCategory" class="demo-form-inline">
+                    <el-form-item label="分类名称">
+                        <el-input v-model="newCategory.label" placeholder="请输入分类名称"></el-input>
+                    </el-form-item>
+                    <el-form-item>
+                        <el-button type="primary" @click="addCategory">添加</el-button>
+                    </el-form-item>
+                </el-form>
+            </div>
+            <span slot="footer" class="dialog-dialog">
+                <el-button @click="categoryManageVisible = false">关 闭</el-button>
+            </span>
+        </el-dialog>
+
+        <!-- 设置分类封面 -->
+        <el-dialog :visible.sync="coverDialogVisible" title="设置分类封面" width="500px">
+            <div class="cover-upload-container">
+                <el-upload
+                    class="cover-uploader"
+                    action="#"
+                    :show-file-list="false"
+                    :on-change="handleCoverChange"
+                    :auto-upload="false"
+                    :before-upload="beforeCoverUpload">
+                    <img v-if="coverImageUrl" :src="coverImageUrl" class="cover-image" />
+                    <i v-else class="el-icon-plus cover-uploader-icon"></i>
+                </el-upload>
+                <div class="cover-tip">请上传分类封面图片,建议尺寸 16:9</div>
+            </div>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="coverDialogVisible = false">取 消</el-button>
+                <el-button type="primary" @click="saveCategoryCover">确 定</el-button>
+            </span>
+        </el-dialog>
+
+        <!-- 添加课程 -->
+        <el-dialog :visible.sync="addDialogVisible" title="添加课程" width="800px" top="6.5vh">
+            <el-form :model="courseForm" :rules="courseRules" ref="courseForm" label-width="120px">
+                <el-form-item label="课程分类" prop="courseTypeId">
+                    <el-select v-model="courseForm.courseTypeId" placeholder="请选择" style="width:100%">
+                        <el-option v-for="item in categoryOptions" :key="item.value" 
+                            :label="item.label" :value="item.value">
+                        </el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="课程名称" prop="courseName">
+                    <el-input v-model="courseForm.courseName" placeholder="请输入课程名称"></el-input>
+                </el-form-item>
+                <el-form-item label="课程介绍" style="height: 200px;">
+                    <quill-editor style="height: 150px" ref="text" v-model="courseForm.courseDesc" class="myQuillEditor" :options="editorOption"/>
+                </el-form-item>
+                <el-form-item label="课程价格">
+                    <el-input-number v-model="courseForm.coursePrice" :min="0" :precision="2"></el-input-number>
+                </el-form-item>
+                <el-form-item label="课程时间(分钟)">
+                    <el-input-number v-model="courseForm.courseDuration" :min="0"></el-input-number>
+                </el-form-item>
+                <el-form-item label="课程封面">
+                    <el-upload
+                        class="cover-uploader"
+                        action="#"
+                        :show-file-list="false"
+                        :on-change="handleCourseCoverChange"
+                        :auto-upload="false"
+                        :before-upload="beforeCoverUpload">
+                        <img v-if="courseForm.coverImageUrl" :src="courseForm.coverImageUrl" class="cover-image" />
+                        <i v-else class="el-icon-plus cover-uploader-icon"></i>
+                    </el-upload>
+                    <div class="cover-tip">建议尺寸 16:9,大小不超过2MB</div>
+                </el-form-item>
+            </el-form>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="addDialogVisible = false">取 消</el-button>
+                <el-button type="primary" @click="submitCourseForm">确 定</el-button>
+            </span>
+        </el-dialog>
+    </section>
+</template>
+
+<script>
+// 富文本样式
+import 'quill/dist/quill.core.css'
+import 'quill/dist/quill.snow.css'
+import 'quill/dist/quill.bubble.css'
+// 导入富文本
+import { quillEditor } from 'vue-quill-editor'
+export default {
+    components: {
+        quillEditor, // 富文本
+    },
+    data() {
+        return {
+            // 课程表单
+            courseForm: {
+                courseTypeId: '',
+                courseName: '',
+                courseDesc: '',
+                coursePrice: 0,
+                courseDuration: 0,
+                coverImageUrl: '',
+                coverImageFile: null
+            },
+            courseRules: {
+                courseTypeId: [
+                    { required: true, message: '请选择课程分类', trigger: 'change' }
+                ],
+                courseName: [
+                    { required: true, message: '请输入课程名称', trigger: 'blur' }
+                ]
+            },
+            // 课程分类选择
+            categoryValue: '',
+            categoryOptions: [],
+            // 搜索条件
+            keyword: null, // 课程名称
+            instructor: null, // 讲师
+
+            // 表格相关
+            tableHeight: 0,
+            listLoading: false,
+            total: 0,
+            page: 1,
+            size: 20,
+            list: [],
+
+            // 对话框控制
+            categoryManageVisible: false,
+            editDialogVisible: false,
+            addDialogVisible: false,
+
+            // 分类管理
+            categoryList: [],
+            newCategory: {
+                label: '',
+                value: '',
+                coverImage: ''
+            },
+
+            // 分类封面设置
+            coverDialogVisible: false,
+            currentCategoryIndex: -1,
+            coverImageUrl: '',
+            coverImageFile: null,
+            
+            // 用户信息
+            user: sessionStorage.user ? JSON.parse(sessionStorage.user) : {},
+            editorOption: { // 富文本框里面的默认值
+                placeholder: '请输入内容...',
+                modules: {
+                    toolbar:[
+                        ['bold', 'italic', 'underline', 'strike'],    //加粗,斜体,下划线,删除线
+                        // ['blockquote', 'code-block'],     //引用,代码块
+                
+                        [{ 'header': 1 }, { 'header': 2 }],        // 标题,键值对的形式;1、2表示字体大小
+                        // [{ 'list': 'ordered'}, { 'list': 'bullet' }],     //列表
+                        // [{ 'script': 'sub'}, { 'script': 'super' }],   // 上下标
+                        // [{ 'indent': '-1'}, { 'indent': '+1' }],     // 缩进
+                        // [{ 'direction': 'rtl' }],             // 文本方向
+                
+                        [{ 'size': ['small', false, 'large', 'huge'] }], // 字体大小
+                        [{ 'header': [1, 2, 3, 4, 5, 6, false] }],     //几级标题
+                
+                        [{ 'color': [] }, { 'background': [] }],     // 字体颜色,字体背景颜色
+                        // [{ 'font': [] }],     //字体
+                        [{ 'align': [] }],    //对齐方式
+                
+                        ['clean'],    //清除字体样式
+                        // ['image','video']    //上传图片、上传视频
+                        []    //上传图片、上传视频
+                    ], //工具栏设置
+                },
+                theme: 'snow',
+            },
+        }
+    },
+    methods: {
+        // 分类管理
+        batchManage() {
+            this.categoryManageVisible = true;
+            // 加载分类数据
+            this.http.post('/course-type/list', {}, res => {
+                if (res.code == "ok") {
+                    // 将后端返回的数据转换为前端需要的格式
+                    this.categoryList = res.data.map(item => ({
+                        label: item.typeName,
+                        value: item.id,
+                        coverImage: item.coverImage || ''
+                    }));
+                    
+                    // 同步更新下拉选项
+                    this.categoryOptions = [...this.categoryList];
+                } else {
+                    this.$message({
+                        message: res.msg || '获取分类列表失败',
+                        type: 'error'
+                    });
+                }
+            }, error => {
+                this.$message({
+                    message: error || '获取分类列表失败',
+                    type: 'error'
+                });
+            });
+        },
+
+        // 搜索课程列表
+        searchList() {
+            this.page = 1;
+            this.getList();
+        },
+
+        // 获取课程列表
+        getList() {
+            this.listLoading = true;
+
+            // 调用后端API获取课程列表
+            this.http.post('/course-info/list', {
+                page: this.page,
+                size: this.size,
+                courseType: this.categoryValue,
+                courseName: this.keyword,
+                courseInstructor: this.instructor
+            }, res => {
+                this.listLoading = false;
+                if (res.code == "ok") {
+                    this.list = res.data.records;
+                    this.total = res.data.total;
+                } else {
+                    this.$message({
+                        message: res.msg || '获取课程列表失败',
+                        type: 'error'
+                    });
+                }
+            }, error => {
+                this.listLoading = false;
+                this.$message({
+                    message: error || '获取课程列表失败',
+                    type: 'error'
+                });
+            });
+        },
+
+        // 分页相关
+        handleCurrentChange(val) {
+            this.page = val;
+            this.getList();
+        },
+        handleSizeChange(val) {
+            this.page = 1;
+            this.size = val;
+            this.getList();
+        },
+
+        // 删除课程
+        deleteItem(row) {
+            this.$confirm('确认删除该课程?', '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning'
+            }).then(() => {
+                // 调用后端API删除课程
+                this.http.post('/course-info/deleteCourse', {
+                    id: row.id
+                }, res => {
+                    if (res.code == "ok") {
+                        this.$message({
+                            type: 'success',
+                            message: '删除成功!'
+                        });
+                        this.getList();
+                    } else {
+                        this.$message({
+                            message: res.msg || '删除课程失败',
+                            type: 'error'
+                        });
+                    }
+                }, error => {
+                    this.$message({
+                        message: error || '删除课程失败',
+                        type: 'error'
+                    });
+                });
+            })
+        },
+
+        // 上架/下架课程
+        uploadItem(row) {
+            const action = row.courseStatus === 1 ? '下架' : '上架';
+            this.$confirm(`确认${action}该课程?`, '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning'
+            }).then(() => {
+                // 调用后端API上架/下架课程
+                this.http.post('/course-info/saveOrUpdate', {
+                    id: row.id,
+                    courseStatus: row.courseStatus === 1 ? 0 : 1 // 0: 下架, 1: 上架
+                }, res => {
+                    if (res.code == "ok") {
+                        row.courseStatus = row.courseStatus === 1 ? 0 : 1;
+                        this.$message({
+                            type: 'success',
+                            message: `${action}成功!`
+                        });
+                    } else {
+                        this.$message({
+                            message: res.msg || `${action}失败`,
+                            type: 'error'
+                        });
+                    }
+                }, error => {
+                    this.$message({
+                        message: error || `${action}失败`,
+                        type: 'error'
+                    });
+                });
+            })
+        },
+
+        // 保存分类封面
+        saveCategoryCover() {
+            if (!this.coverImageUrl) {
+                this.$message.warning('请先上传封面图片!');
+                return;
+            }
+            
+            // 关闭对话框
+            this.coverDialogVisible = false;
+            this.$message({
+                type: 'success',
+                message: '设置封面成功!'
+            });
+        },
+
+        // 处理封面图片变更
+        handleCoverChange(file) {
+            this.coverImageFile = file.raw;
+            if (this.coverImageFile) {
+                this.coverImageUrl = URL.createObjectURL(this.coverImageFile);
+                
+                // 获取当前分类的ID
+                if (this.currentCategoryIndex >= 0) {
+                    const categoryId = this.categoryList[this.currentCategoryIndex].value;
+                    
+                    // 立即上传封面图片
+                    this.listLoading = true;
+                    
+                    // 创建FormData对象用于上传文件
+                    const formData = new FormData();
+                    formData.append('id', categoryId);
+                    formData.append('coverImage', this.coverImageFile);
+                    
+                    // 调用上传图片的API
+                    this.http.uploadFile('/course-type/uploadCover', formData, res => {
+                        this.listLoading = false;
+                        if (res.code == "ok") {
+                            // 上传成功后,获取返回的图片URL
+                            const imageUrl = res.data && res.data.url ? res.data.url : this.coverImageUrl;
+                            
+                            // 更新本地数据
+                            this.categoryList[this.currentCategoryIndex].coverImage = imageUrl;
+                            
+                            // 同步更新到分类选项中
+                            const optionIndex = this.categoryOptions.findIndex(item => item.value === categoryId);
+                            if (optionIndex !== -1) {
+                                this.categoryOptions[optionIndex].coverImage = imageUrl;
+                            }
+                            
+                            this.$message({
+                                type: 'success',
+                                message: '封面图片上传成功!'
+                            });
+                        } else {
+                            this.$message({
+                                message: res.msg || '上传封面图片失败',
+                                type: 'error'
+                            });
+                        }
+                    }, error => {
+                        this.listLoading = false;
+                        this.$message({
+                            message: error || '上传封面图片失败',
+                            type: 'error'
+                        });
+                    });
+                }
+            }
+        },
+
+         // 设置分类封面
+         setCategoryCover(index, row) {
+            this.currentCategoryIndex = index;
+            this.coverImageUrl = row.coverImage || '';
+            this.coverDialogVisible = true;
+        },
+
+        // 处理封面图片上传前的验证
+        beforeCoverUpload(file) {
+            const isImage = file.type.indexOf('image/') === 0;
+            const isLt2M = file.size / 1024 / 1024 < 2;
+            
+            if (!isImage) {
+                this.$message.error('上传封面图片只能是图片格式!');
+            }
+            if (!isLt2M) {
+                this.$message.error('上传封面图片大小不能超过 2MB!');
+            }
+            
+            return isImage && isLt2M;
+        },
+
+        // 添加课程
+        addCourse(row) {
+            this.addDialogVisible = true;
+            if(!row) {
+                this.courseForm = {
+                    courseTypeId: '',
+                    courseName: '',
+                    courseDesc: '',
+                    coursePrice: 0,
+                    courseDuration: 0,
+                    coverImageUrl: '',
+                };
+                if (this.$refs.courseForm) {
+                    this.$refs.courseForm.resetFields();
+                }
+            } else {
+                console.log(row, '<==== 看看数据')
+                const { courseTypeId, courseName, courseDesc, coursePrice, courseDuration, coverImage, id } = row
+                this.courseForm = {
+                    id,
+                    courseTypeId,
+                    courseName,
+                    courseDesc,
+                    coursePrice,
+                    courseDuration,
+                    coverImageUrl: this.checkAndAddUpload(coverImage)
+                }
+            }
+        },
+
+        // 提交课程表单
+        submitCourseForm() {
+            this.$refs.courseForm.validate(valid => {
+                if (!valid) {
+                    return false;
+                }
+                
+                const formData = new FormData();
+                if(this.courseForm.id) {
+                    formData.append('id', this.courseForm.id);
+                }
+                formData.append('courseTypeId', this.courseForm.courseTypeId);
+                formData.append('courseName', this.courseForm.courseName);
+                formData.append('courseDesc', this.courseForm.courseDesc);
+                formData.append('coursePrice', this.courseForm.coursePrice);
+                formData.append('courseDuration', this.courseForm.courseDuration);
+                formData.append('coverImage', this.courseForm.coverImageUrl);
+
+                this.listLoading = true;
+                this.http.uploadFile('/course-info/saveOrUpdate', formData, res => {
+                    this.listLoading = false;
+                    if (res.code === "ok") {
+                        this.$message.success('添加课程成功');
+                        this.addDialogVisible = false;
+                        this.getList();
+                    } else {
+                        this.$message.error(res.msg || '添加课程失败');
+                    }
+                }, error => {
+                    this.listLoading = false;
+                    this.$message.error(error || '添加课程失败');
+                });
+            });
+        },
+
+        // 处理课程封面图片变更
+        handleCourseCoverChange(file) {
+            const row = file.raw
+            const formData = new FormData();
+            formData.append('multipartFile', row);
+            this.http.uploadFile('/common/uploadFile', formData, res => {
+              if (res.code == "ok") {
+                this.courseForm.coverImageUrl = this.checkAndAddUpload(res.data)
+              } else {
+                this.$message({
+                  message: res.msg || '图片上传失败',
+                  type: 'error'
+                });
+              }
+            })
+        },
+
+        checkAndAddUpload(str) {
+            if(!str) {
+                return '';
+            }
+            if (str.includes('/upload/')) {
+                return str;
+            } else {
+                return '/upload/' + str;
+            }
+        },
+
+        // 添加分类
+        addCategory() {
+            if (!this.newCategory.label || !this.newCategory.label.trim()) {
+                this.$message({
+                    type: 'warning',
+                    message: '请输入分类名称!'
+                });
+                return;
+            }
+            
+            // 调用后端API保存课程分类
+            this.http.post('/course-type/saveOrUpdate', {
+                typeName: this.newCategory.label
+            }, res => {
+                if (res.code == "ok") {
+                    // 生成唯一ID作为value,实际项目中应该使用后端返回的ID
+                    const categoryId = res.data && res.data.id ? res.data.id : 'category_' + Date.now();
+                    this.newCategory.value = categoryId;
+                    
+                    // 添加到分类列表
+                    this.categoryList.push({...this.newCategory});
+                    this.categoryOptions.push({...this.newCategory});
+                    
+                    // 清空输入
+                    this.newCategory.label = '';
+                    this.newCategory.value = '';
+                    
+                    this.$message({
+                        type: 'success',
+                        message: '添加分类成功!'
+                    });
+                } else {
+                    this.$message({
+                        message: res.msg || '添加分类失败',
+                        type: 'error'
+                    });
+                }
+            }, error => {
+                this.$message({
+                    message: error || '添加分类失败',
+                    type: 'error'
+                });
+            });
+        },
+        
+        // 删除分类
+        deleteCategory(index, row) {
+            this.$confirm('确认删除该分类?', '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning'
+            }).then(() => {
+                // 调用后端API删除课程分类
+                this.http.post('/course-type/delete', {
+                    id: row.value
+                }, res => {
+                    if (res.code == "ok") {
+                        // 从分类列表中删除
+                        this.categoryList.splice(index, 1);
+                        
+                        // 从下拉选项中删除
+                        const optionIndex = this.categoryOptions.findIndex(item => item.value === row.value);
+                        if (optionIndex !== -1) {
+                            this.categoryOptions.splice(optionIndex, 1);
+                        }
+                        
+                        this.$message({
+                            type: 'success',
+                            message: '删除分类成功!'
+                        });
+                    } else {
+                        this.$message({
+                            message: res.msg || '删除分类失败',
+                            type: 'error'
+                        });
+                    }
+                }, error => {
+                    this.$message({
+                        message: error || '删除分类失败',
+                        type: 'error'
+                    });
+                });
+            })
+        },
+    },
+
+    created() {
+        let height = window.innerHeight;
+        this.tableHeight = height - 195;
+        const that = this;
+        window.onresize = function temp() {
+            that.tableHeight = window.innerHeight - 195;
+        };
+
+        // 初始化分类列表
+        this.categoryList = [...this.categoryOptions];
+    },
+
+    mounted() {
+        // 获取课程分类数据
+        this.http.post('/course-type/list', {}, res => {
+            if (res.code == "ok") {
+                // 将后端返回的数据转换为前端需要的格式
+                this.categoryList = res.data.map(item => ({
+                    label: item.typeName,
+                    value: item.id,
+                    coverImage: item.coverImage || ''
+                }));
+
+                // 同步更新下拉选项
+                this.categoryOptions = [...this.categoryList];
+            } else {
+                this.$message({
+                    message: res.msg || '获取分类列表失败',
+                    type: 'error'
+                });
+            }
+        }, error => {
+            this.$message({
+                message: error || '获取分类列表失败',
+                type: 'error'
+            });
+        });
+
+        // 获取课程列表
+        this.getList();
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.rg_span {
+    display: inline-block;
+}
+
+.rg_span span {
+    text-align: right;
+    box-sizing: border-box;
+    padding-right: 10px;
+}
+
+.el-dialog__title {
+    display: inline-table;
+    margin-top: 20px;
+}
+
+.btns .el-button {
+    margin-left: 10px;
+    margin-bottom: 5px;
+}
+</style>
+<style>
+.course-cover-image {
+    width: 100px;
+    height: 100px;
+    object-fit: cover;
+    border-radius: 4px;
+}
+
+.otherForm .el-form-item {
+    float: left;
+    width: 50%;
+    margin: 0;
+}
+
+/* 视频播放器样式 */
+.video-player-container {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    width: 100%;
+}
+
+.video-player {
+    max-width: 100%;
+    max-height: 500px;
+}
+
+.video-preview {
+    margin-top: 10px;
+    border: 1px solid #ebeef5;
+    border-radius: 4px;
+    padding: 10px;
+    background-color: #f9f9f9;
+}
+
+.video-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 10px;
+    padding-bottom: 8px;
+    border-bottom: 1px solid #ebeef5;
+}
+
+.video-title {
+    font-weight: bold;
+    color: #303133;
+}
+
+.delete-video-btn {
+    color: #f56c6c;
+    padding: 0;
+}
+
+.delete-video-btn:hover {
+    color: #f78989;
+}
+
+.video-name {
+    margin-top: 5px;
+    color: #606266;
+    font-size: 14px;
+}
+
+/* 编辑器样式 */
+.editor-container {
+    border: 1px solid #dcdfe6;
+    border-radius: 4px;
+    overflow: hidden;
+}
+
+.editor-toolbar {
+    background-color: #f5f7fa;
+    padding: 5px;
+    border-bottom: 1px solid #dcdfe6;
+    display: flex;
+    align-items: center;
+}
+
+.editor-btn {
+    background: none;
+    border: none;
+    padding: 5px 8px;
+    margin: 0 2px;
+    cursor: pointer;
+    border-radius: 3px;
+}
+
+.editor-btn:hover {
+    background-color: #e4e7ed;
+}
+
+.editor-separator {
+    width: 1px;
+    height: 16px;
+    background-color: #dcdfe6;
+    margin: 0 5px;
+}
+
+.editor-select {
+    height: 24px;
+    border: 1px solid #dcdfe6;
+    border-radius: 3px;
+    margin: 0 5px;
+}
+
+.editor-content {
+    width: 100%;
+    min-height: 120px;
+    padding: 10px;
+    border: none;
+    resize: vertical;
+    outline: none;
+    font-family: Arial, sans-serif;
+    font-size: 14px;
+}
+
+/* 上传链接样式 */
+.upload-item {
+    margin-bottom: 20px;
+}
+
+.upload-link {
+    color: #409eff;
+    cursor: pointer;
+    font-size: 14px;
+}
+
+.upload-link:hover {
+    text-decoration: underline;
+}
+
+/* 分类封面图片样式 */
+.category-cover-image {
+    width: 100px;
+    height: 56px;
+    object-fit: cover;
+    border-radius: 4px;
+}
+
+.cover-upload-container {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    padding: 20px 0;
+}
+
+.cover-uploader {
+    border: 1px dashed #d9d9d9;
+    border-radius: 6px;
+    cursor: pointer;
+    position: relative;
+    overflow: hidden;
+    width: 178px;
+    height: 100px;
+    margin-bottom: 10px;
+}
+
+.cover-uploader:hover {
+    border-color: #409EFF;
+}
+
+.cover-uploader-icon {
+    font-size: 28px;
+    color: #8c939d;
+    width: 178px;
+    height: 100px;
+    line-height: 100px;
+    text-align: center;
+}
+
+.cover-image {
+    width: 178px;
+    height: 100px;
+    display: block;
+    object-fit: cover;
+}
+
+.cover-tip {
+    color: #909399;
+    font-size: 12px;
+    margin-top: 10px;
+}
+
+/* 讲师照片上传样式 */
+.instructor-uploader {
+    border: 1px dashed #d9d9d9;
+    border-radius: 6px;
+    cursor: pointer;
+    position: relative;
+    overflow: hidden;
+    width: 100px;
+    height: 100px;
+    margin-bottom: 10px;
+}
+
+.instructor-uploader:hover {
+    border-color: #409EFF;
+}
+
+.instructor-uploader-icon {
+    font-size: 28px;
+    color: #8c939d;
+    width: 100px;
+    height: 100px;
+    line-height: 100px;
+    text-align: center;
+}
+
+.instructor-image {
+    width: 100px;
+    height: 100px;
+    display: block;
+    object-fit: cover;
+}
+
+.upload-tip {
+    color: #909399;
+    font-size: 12px;
+    margin-top: 5px;
+}
+
+.ql-snow .ql-picker-label::before {
+    position: relative;
+    top: -8px;
+}
+</style>

ファイルの差分が大きいため隠しています
+ 1634 - 0
fhKeeper/formulahousekeeper/course-pc/src/views/coursemanagement/list copy.vue


ファイルの差分が大きいため隠しています
+ 485 - 986
fhKeeper/formulahousekeeper/course-pc/src/views/coursemanagement/list.vue


+ 415 - 0
fhKeeper/formulahousekeeper/course-pc/src/views/lecturerManagement/index.vue

@@ -0,0 +1,415 @@
+<template>
+    <section>
+        <!--工具条-->
+        <el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
+            <el-form :inline="true" @submit.native.prevent>
+                <el-form-item label="讲师名称">
+                    <el-input v-model="keyword" placeholder="请输入讲师名称" clearable @change="searchList"
+                        size="small"></el-input>
+                </el-form-item>
+                <el-form-item>
+                    <el-button type="primary" @click="addLecturer" size="small">添加讲师</el-button>
+                </el-form-item>
+            </el-form>
+        </el-col>
+
+        <!--列表-->
+        <el-table :data="list" highlight-current-row v-loading="listLoading" :height="tableHeight" style="width: 100%;" @selection-change="handleSelectionChange">
+            <el-table-column type="selection" width="55" align="center"></el-table-column>
+            <el-table-column prop="name" label="讲师名称" min-width="180" align="center"></el-table-column>
+            <el-table-column prop="introduction" label="讲师介绍" min-width="300" align="center"></el-table-column>
+            <el-table-column label="讲师照片" width="120" align="center">
+                <template slot-scope="scope">
+                    <div v-if="scope.row.photo" >
+                        <img :src="scope.row.photo" class="lecturer-photo" @click="previewImage(scope.row.photo)" />
+                      </div>
+                    <span v-else>无照片</span>
+                </template>
+            </el-table-column>
+            <el-table-column label="操作" width="180" class-name="btns" header-align="center" fixed="right">
+                <template slot-scope="scope">
+                    <el-button size="small" type="primary" @click="editLecturer(scope.row)">编辑</el-button>
+                    <el-button size="small" type="danger" @click="deleteLecturer(scope.row)">删除</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+
+        <!--工具条-->
+        <el-col :span="24" class="toolbar">
+            <el-button type="danger" @click="batchDelete" :disabled="selectedIds.length===0" size="small">批量删除</el-button>
+            <el-pagination
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+                :page-sizes="[10, 20, 50, 100]"
+                :page-size="size"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="total"
+                style="float:right;"
+            ></el-pagination>
+        </el-col>
+
+        <!-- 添加/编辑讲师对话框 -->
+        <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="800px">
+            <el-form :model="lecturerForm" :rules="rules" ref="lecturerForm" label-width="100px">
+                <el-form-item label="讲师名称" prop="name">
+                    <el-input v-model="lecturerForm.name" placeholder="请输入讲师名称"></el-input>
+                </el-form-item>
+                <el-form-item label="讲师介绍">
+                    <el-input type="textarea" v-model="lecturerForm.introduction" placeholder="请输入讲师介绍"></el-input>
+                </el-form-item>
+                <el-form-item label="讲师照片">
+                    <el-upload
+                        class="lecturer-uploader"
+                        action="#"
+                        :show-file-list="false"
+                        :on-change="handlePhotoChange"
+                        :auto-upload="false"
+                        :before-upload="beforePhotoUpload">
+                        <img v-if="photoUrl" :src="photoUrl" class="lecturer-image" />
+                        <i v-else class="el-icon-plus lecturer-uploader-icon"></i>
+                    </el-upload>
+                    <div class="upload-tip">建议上传1:1比例的头像照片</div>
+                </el-form-item>
+            </el-form>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="dialogVisible = false">取 消</el-button>
+                <el-button type="primary" @click="saveLecturer">确 定</el-button>
+            </span>
+        </el-dialog>
+
+        <!-- 图片预览 -->
+        <viewer ref="imageWrapper" :images="images" style="opacity: 1;position: absolute;top: -9999px;">
+            <img v-for="(image, index) in images" :src="image" :key="index" />
+        </viewer>
+  
+    </section>
+</template>
+
+<script>
+export default {
+    data() {
+        return {
+            // 搜索条件
+            keyword: null,
+
+            // 表格相关
+            tableHeight: 0,
+            listLoading: false,
+            total: 0,
+            page: 1,
+            size: 20,
+            list: [],
+            selectedIds: [],
+
+            // 对话框控制
+            dialogVisible: false,
+            dialogTitle: '添加讲师',
+            currentLecturerId: null,
+            photoUrl: '',
+            photoFile: null,
+
+            // 表单数据
+            lecturerForm: {
+                name: '',
+                introduction: '',
+                photo: ''
+            },
+
+            // 表单验证规则
+            rules: {
+                name: [
+                    { required: true, message: '请输入讲师名称', trigger: 'blur' }
+                ]
+            },
+
+            images: [],
+        }
+    },
+    methods: {
+        previewImage(urls) {
+            this.images = [urls];
+            this.$nextTick(() => {
+                if (this.$refs.imageWrapper && this.$refs.imageWrapper.$viewer) {
+                    this.$refs.imageWrapper.$viewer.show();
+                }
+            });
+        },
+        checkAndAddUpload(str) {
+          if(!str) {
+              return '';
+          }
+          if (str.includes('/upload/')) {
+            return str;
+          } else {
+            return '/upload/' + str;
+          }
+        },
+
+        // 搜索讲师列表
+        searchList() {
+            this.page = 1;
+            this.getList();
+        },
+
+        // 获取讲师列表
+        getList() {
+            this.listLoading = true;
+            this.http.post('/course-teacher/pageList', {
+                teacherName: this.keyword,
+                page: this.page,
+                size: this.size
+            }, res => {
+                this.list = res.data.records.map(item => ({
+                    id: item.id,
+                    name: item.teacherName,
+                    introduction: item.teacherDesc,
+                    photo: this.checkAndAddUpload(item.teacherImgUrl)
+                }));
+                this.total = res.data.total;
+                this.listLoading = false;
+            }, () => {
+                this.listLoading = false;
+            })
+        },
+
+        // 分页相关
+        handleCurrentChange(val) {
+            this.page = val;
+            this.getList();
+        },
+        handleSizeChange(val) {
+            this.page = 1;
+            this.size = val;
+            this.getList();
+        },
+
+        // 选择变化
+        handleSelectionChange(val) {
+            this.selectedIds = val.map(item => item.id);
+        },
+
+        // 添加讲师
+        addLecturer() {
+            this.dialogTitle = '添加讲师';
+            this.currentLecturerId = null;
+            this.lecturerForm = {
+                name: '',
+                introduction: '',
+                photo: ''
+            };
+            this.photoUrl = '';
+            this.dialogVisible = true;
+        },
+
+        // 编辑讲师
+        editLecturer(row) {
+            this.dialogTitle = '编辑讲师';
+            this.currentLecturerId = row.id;
+            this.lecturerForm = {
+                name: row.name,
+                introduction: row.introduction,
+                photo: row.photo
+            };
+            this.photoUrl = row.photo || '';
+            this.dialogVisible = true;
+        },
+
+        // 删除讲师
+        deleteLecturer(row) {
+            this.$confirm('确认删除该讲师?', '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning'
+            }).then(() => {
+                this.http.post('/course-teacher/delete', { id: row.id }, res => {
+                    if (res.data.code === 'ok') {
+                        this.$message({
+                            type: 'success',
+                            message: '删除成功!'
+                        });
+                        this.getList();
+                    }
+                });
+            })
+        },
+
+        // 批量删除
+        batchDelete() {
+            if (this.selectedIds.length === 0) {
+                this.$message.warning('请选择要删除的讲师');
+                return;
+            }
+
+            this.$confirm(`确认删除选中的${this.selectedIds.length}位讲师?`, '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning'
+            }).then(() => {
+                this.http.post('/course-teacher/batchDelete', { ids: this.selectedIds }, res => {
+                    if (res.data.code === 'ok') {
+                        this.$message({
+                            type: 'success',
+                            message: '批量删除成功!'
+                        });
+                        this.getList();
+                        this.selectedIds = [];
+                    }
+                })
+            })
+        },
+
+        // 保存讲师
+        saveLecturer() {
+            this.$refs.lecturerForm.validate((valid) => {
+                if (valid) {
+                    this.saveLecturerInfo();
+                }
+            });
+        },
+
+        // 保存讲师信息
+        saveLecturerInfo() {
+            const params = {
+                teacherName: this.lecturerForm.name,
+                teacherDesc: this.lecturerForm.introduction,
+                teacherImgUrl: this.photoUrl
+            };
+            
+            if (this.currentLecturerId) {
+                params.id = this.currentLecturerId;
+            }
+
+            this.http.post('/course-teacher/save', params, res => {
+                if (res.code === 'ok') {
+                    this.$message({
+                        type: 'success',
+                        message: '保存成功!'
+                    });
+                    this.dialogVisible = false;
+                    this.getList();
+                }
+            })
+        },
+
+        // 处理照片变更
+        handlePhotoChange(file) {
+            const isImage = file.raw.type.indexOf('image/') === 0;
+            const isLt2M = file.raw.size / 1024 / 1024 < 5;
+            
+            if (!isImage) {
+                this.$message.error('上传文件只能是图片格式!');
+                return;
+            }
+            if (!isLt2M) {
+                this.$message.error('上传图片大小不能超过 2MB!');
+                return;
+            }
+
+            const row = file.raw
+            const formData = new FormData();
+            formData.append('multipartFile', row);
+            
+            this.http.uploadFile('/common/uploadFile', formData, res => {
+              if (res.code == "ok") {
+                this.photoUrl = this.checkAndAddUpload(res.data)
+              } else {
+                this.$message({
+                  message: res.msg || '图片上传失败',
+                  type: 'error'
+                });
+              }
+            })
+        },
+
+        // 处理照片上传前的验证
+        beforePhotoUpload(file) {
+            const isImage = file.type.indexOf('image/') === 0;
+            const isLt2M = file.size / 1024 / 1024 < 5;
+            
+            if (!isImage) {
+                this.$message.error('上传文件只能是图片格式!');
+            }
+            if (!isLt2M) {
+                this.$message.error('上传图片大小不能超过 2MB!');
+            }
+            
+            return isImage && isLt2M;
+        }
+    },
+
+    created() {
+        let height = window.innerHeight;
+        this.tableHeight = height - 195;
+        const that = this;
+        window.onresize = function temp() {
+            that.tableHeight = window.innerHeight - 195;
+        };
+    },
+    beforeDestroy() {
+        if (this.viewer) {
+        this.viewer.destroy();
+        this.viewer = null;
+        }
+    },
+
+    mounted() {
+        this.getList();
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.toolbar {
+    padding-bottom: 10px;
+}
+
+.btns .el-button {
+    margin-left: 10px;
+    margin-bottom: 5px;
+}
+
+.lecturer-photo {
+    width: 80px;
+    height: 80px;
+    object-fit: cover;
+    border-radius: 10px;
+    cursor: pointer;
+}
+
+.lecturer-uploader {
+    border: 1px dashed #d9d9d9;
+    border-radius: 6px;
+    cursor: pointer;
+    position: relative;
+    overflow: hidden;
+    width: 100px;
+    height: 100px;
+    margin-bottom: 10px;
+}
+
+.lecturer-uploader:hover {
+    border-color: #409EFF;
+}
+
+.lecturer-uploader-icon {
+    font-size: 28px;
+    color: #8c939d;
+    width: 100px;
+    height: 100px;
+    line-height: 100px;
+    text-align: center;
+}
+
+.lecturer-image {
+    width: 100px;
+    height: 100px;
+    display: block;
+    object-fit: cover;
+}
+
+.upload-tip {
+    color: #909399;
+    font-size: 12px;
+    margin-top: 5px;
+}
+</style>

+ 336 - 0
fhKeeper/formulahousekeeper/course-pc/src/views/offlineTraining/offlineTraining.vue

@@ -0,0 +1,336 @@
+<template>
+  <div class="offline-training-container">
+    <el-card class="box-card">
+      <div slot="header" class="clearfix">
+        <span>线下研修班介绍</span>
+      </div>
+      
+      <viewer ref="imageWrapper" :images="previewImages" style="opacity: 1;position: absolute;top: -9999px;">
+        <img v-for="(image, index) in previewImages" :src="image" :key="index" />
+      </viewer>
+
+      <el-form ref="form" :model="form" label-width="120px">
+        <div class="form-section">
+          <el-form-item label="分类名称" prop="categoryName">
+            <el-input v-model="form.categoryName" placeholder="请输入分类名称"></el-input>
+          </el-form-item>
+        </div>
+
+        <div class="form-section">
+          <el-form-item label="分类封面" prop="coverImage">
+            <div class="upload-area">
+              <el-upload
+                class="cover-uploader"
+                action="#"
+                :show-file-list="false"
+                :on-change="handleCoverChange"
+                :auto-upload="false"
+                :before-upload="beforeCoverUpload">
+                <img v-if="form.coverImage" :src="form.coverImage" class="cover-preview" @click="previewImage(form.coverImage)">
+                <i v-else class="el-icon-plus cover-uploader-icon"></i>
+              </el-upload>
+              <div class="upload-tip">建议尺寸:800x600px,大小不超过5MB</div>
+            </div>
+          </el-form-item>
+        </div>
+
+        <div class="form-section">
+          <el-form-item label="内容上传" prop="contentType">
+            <el-radio-group v-model="form.contentType" @change="handleContentTypeChange">
+              <el-radio label="image">图片</el-radio>
+              <el-radio label="video">视频</el-radio>
+            </el-radio-group>
+            
+            <div class="upload-area" v-if="form.contentType === 'image'">
+              <el-upload
+                action="#"
+                :show-file-list="false"
+                :on-change="handleImageChange"
+                :auto-upload="false"
+                :before-upload="beforeImageUpload">
+                <el-button size="small" type="primary">点击上传图片</el-button>
+              </el-upload>
+              <div class="upload-preview" v-if="form.contentImage">
+                <img :src="form.contentImage" class="content-preview" @click="previewImage(form.contentImage)">
+              </div>
+            </div>
+
+            <div class="upload-area" v-else-if="form.contentType === 'video'">
+              <el-upload
+                action="#"
+                :show-file-list="false"
+                :on-change="handleVideoChange"
+                :auto-upload="false"
+                :before-upload="beforeVideoUpload">
+                <el-button size="small" type="primary">点击上传视频</el-button>
+              </el-upload>
+              <div class="upload-preview" v-if="form.contentVideo">
+                <video controls class="video-preview">
+                  <source :src="form.contentVideo" type="video/mp4">
+                </video>
+              </div>
+            </div>
+          </el-form-item>
+        </div>
+
+        <div class="action-buttons">
+          <el-button type="primary" @click="submitForm">提交</el-button>
+          <el-button @click="resetForm">重置</el-button>
+        </div>
+      </el-form>
+    </el-card>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      form: {
+        categoryName: '',
+        coverImage: '',
+        contentType: 'image',
+        contentImage: '',
+        contentVideo: ''
+      },
+      previewImages: []
+    }
+  },
+  methods: {
+    previewImage(url) {
+      this.previewImages = [url];
+      this.$nextTick(() => {
+        if (this.$refs.imageWrapper && this.$refs.imageWrapper.$viewer) {
+          this.$refs.imageWrapper.$viewer.show();
+        }
+      });
+    },
+    
+    checkAndAddUpload(str) {
+      if(!str) return '';
+      return str.includes('/upload/') ? str : '/upload/' + str;
+    },
+
+    handleCoverChange(file) {
+      const isImage = file.raw.type.includes('image');
+      const isLt5M = file.raw.size / 1024 / 1024 < 5;
+      
+      if (!isImage) {
+        this.$message.error('只能上传图片文件!');
+        return;
+      }
+      if (!isLt5M) {
+        this.$message.error('图片大小不能超过5MB!');
+        return;
+      }
+
+      const formData = new FormData();
+      formData.append('multipartFile', file.raw);
+      
+      this.http.uploadFile('/common/uploadFile', formData, res => {
+        if (res.code === "ok") {
+          this.form.coverImage = this.checkAndAddUpload(res.data);
+          this.$message.success('封面图片上传成功');
+        } else {
+          this.$message.error(res.msg || '上传失败');
+        }
+      });
+    },
+    
+    beforeCoverUpload(file) {
+      const isImage = file.type.includes('image');
+      const isLt5M = file.size / 1024 / 1024 < 5;
+      
+      if (!isImage) {
+        this.$message.error('只能上传图片文件!');
+        return false;
+      }
+      if (!isLt5M) {
+        this.$message.error('图片大小不能超过5MB!');
+        return false;
+      }
+      return true;
+    },
+    
+    handleImageChange(file) {
+      const isImage = file.raw.type.includes('image');
+      const isLt5M = file.raw.size / 1024 / 1024 < 5;
+      
+      if (!isImage) {
+        this.$message.error('只能上传图片文件!');
+        return;
+      }
+      if (!isLt5M) {
+        this.$message.error('图片大小不能超过5MB!');
+        return;
+      }
+
+      const formData = new FormData();
+      formData.append('multipartFile', file.raw);
+      
+      this.http.uploadFile('/common/uploadFile', formData, res => {
+        if (res.code === "ok") {
+          this.form.contentImage = this.checkAndAddUpload(res.data);
+          this.$message.success('内容图片上传成功');
+        } else {
+          this.$message.error(res.msg || '上传失败');
+        }
+      });
+    },
+    
+    beforeImageUpload(file) {
+      return this.beforeCoverUpload(file);
+    },
+    
+    handleVideoChange(file) {
+      const isVideo = file.raw.type.includes('video');
+      const isLt50M = file.raw.size / 1024 / 1024 < 50;
+      
+      if (!isVideo) {
+        this.$message.error('只能上传视频文件!');
+        return;
+      }
+      if (!isLt50M) {
+        this.$message.error('视频大小不能超过50MB!');
+        return;
+      }
+
+      const formData = new FormData();
+      formData.append('multipartFile', file.raw);
+      
+      this.http.uploadFile('/common/uploadFile', formData, res => {
+        if (res.code === "ok") {
+          this.form.contentVideo = this.checkAndAddUpload(res.data);
+          this.$message.success('视频上传成功');
+        } else {
+          this.$message.error(res.msg || '上传失败');
+        }
+      });
+    },
+    
+    beforeVideoUpload(file) {
+      const isVideo = file.type.includes('video');
+      const isLt50M = file.size / 1024 / 1024 < 50;
+      
+      if (!isVideo) {
+        this.$message.error('只能上传视频文件!');
+        return false;
+      }
+      if (!isLt50M) {
+        this.$message.error('视频大小不能超过50MB!');
+        return false;
+      }
+      return true;
+    },
+
+    handleContentTypeChange(val) {
+      this.form.contentImage = '';
+      this.form.contentVideo = '';
+    },
+
+    submitForm() {
+      this.$refs.form.validate(valid => {
+        if (valid) {
+          // 提交表单逻辑
+          this.$message.success('提交成功!');
+        }
+      });
+    },
+
+    resetForm() {
+      this.$refs.form.resetFields();
+      this.form.contentImage = '';
+      this.form.contentVideo = '';
+    }
+  }
+}
+</script>
+
+<style scoped>
+.offline-training-container {
+  padding: 20px;
+  max-width: 1000px;
+  margin: 0 auto;
+}
+
+.box-card {
+  border-radius: 8px;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+}
+
+.form-section {
+  margin-bottom: 24px;
+}
+
+.upload-area {
+  border: 1px dashed #dcdfe6;
+  border-radius: 6px;
+  padding: 20px;
+  margin-bottom: 20px;
+  background-color: #f5f7fa;
+}
+
+.upload-preview {
+  margin-top: 15px;
+  text-align: center;
+}
+
+.cover-uploader {
+  border: 1px dashed #d9d9d9;
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+  width: 200px;
+  height: 150px;
+  margin: 0 auto;
+}
+
+.cover-uploader:hover {
+  border-color: #409EFF;
+}
+
+.cover-uploader-icon {
+  font-size: 28px;
+  color: #8c939d;
+  width: 200px;
+  height: 150px;
+  line-height: 150px;
+  text-align: center;
+}
+
+.cover-preview {
+  width: 200px;
+  height: 150px;
+  object-fit: cover;
+  border-radius: 4px;
+  cursor: pointer;
+}
+
+.content-preview {
+  max-width: 100%;
+  max-height: 300px;
+  border-radius: 4px;
+  cursor: pointer;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+}
+
+.video-preview {
+  max-width: 100%;
+  max-height: 300px;
+  border-radius: 4px;
+  background-color: #000;
+}
+
+.upload-tip {
+  color: #909399;
+  font-size: 12px;
+  margin-top: 8px;
+  text-align: center;
+}
+
+.action-buttons {
+  margin-top: 24px;
+  text-align: center;
+}
+</style>

+ 0 - 1
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/constant/Constant.java

@@ -60,7 +60,6 @@ public class Constant {
     public static final String[] LEAVE_CHECK= {"审核结果","审核人","请假时间","备注"};
     
     public static final int ZHE_ZHONG_COMPANY_ID=4811;
-    public static final int MLD_COMPANY_ID=876;
     //泓浒
     public static final int HONG_HU_COMPANY_ID=7536;
 }

+ 0 - 61
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FinanceMonthlyWorktimeController.java

@@ -1,61 +0,0 @@
-package com.management.platform.controller;
-
-
-import com.management.platform.entity.FmwDetail;
-import com.management.platform.service.FinanceMonthlyWorktimeService;
-import com.management.platform.util.HttpRespMsg;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
-import javax.annotation.Resource;
-import javax.servlet.http.HttpServletRequest;
-
-/**
- * <p>
- *  前端控制器
- * </p>
- *
- * @author Seyason
- * @since 2025-04-16
- */
-@RestController
-@RequestMapping("/finance-monthly-worktime")
-public class FinanceMonthlyWorktimeController {
-
-    @Resource
-    private FinanceMonthlyWorktimeService financeMonthlyWorktimeService;
-
-    @RequestMapping("/send")
-    public HttpRespMsg send(@RequestParam("id")String id, @RequestParam("timesheetDate") String timesheetDate, HttpServletRequest request) {
-        return financeMonthlyWorktimeService.send(id,timesheetDate,request);
-    }
-
-    @RequestMapping("/getByMonth")
-    public HttpRespMsg getByMonth(Integer companyId, String ymonth, @RequestParam(required = false, defaultValue = "0" ) Integer reGenerate,HttpServletRequest request) {
-        try {
-            return financeMonthlyWorktimeService.getByMonth(companyId, ymonth,reGenerate, request);
-        } catch (Exception e) {
-            e.printStackTrace();
-            HttpRespMsg msg = new HttpRespMsg();
-            msg.setError(e.getMessage());
-            return msg;
-        }
-    }
-
-    @RequestMapping("/setTimesheetDate")
-    public HttpRespMsg setTimesheetDate(Integer id, String timesheetDate, HttpServletRequest request) {
-        return financeMonthlyWorktimeService.setTimesheetDate(id, timesheetDate,request);
-    }
-
-    @RequestMapping("/changeWorktime")
-    public HttpRespMsg changeWorktime(FmwDetail detail, HttpServletRequest request) {
-        return financeMonthlyWorktimeService.changeWorktime(detail,request);
-    }
-
-    @RequestMapping("/setStatusFinal")
-    public HttpRespMsg setStatusFinal(Integer id, HttpServletRequest request) {
-        return financeMonthlyWorktimeService.setStatusFinal(id,request);
-    }
-}
-

+ 2 - 2
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ProjectController.java

@@ -564,8 +564,8 @@ public class ProjectController {
     }
 
     @RequestMapping("/getGanttData")
-    public HttpRespMsg getGanttData(@RequestParam(required = false, defaultValue = "0") Integer type, String startDate, String endDate, String userId, Integer projectId, String groupName,Integer taskType,@RequestParam(required = false) Integer justWaitForMe, HttpServletRequest request) {
-        return projectService.getGanttData(type, startDate, endDate, userId, projectId, groupName,taskType,justWaitForMe, request);
+    public HttpRespMsg getGanttData(@RequestParam(required = false, defaultValue = "0") Integer type, String startDate, String endDate, String userId, Integer projectId, String groupName,Integer taskType, HttpServletRequest request) {
+        return projectService.getGanttData(type, startDate, endDate, userId, projectId, groupName,taskType, request);
     }
 
     @RequestMapping("/getGanttDataNew")

+ 95 - 329
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/TaskController.java

@@ -169,28 +169,9 @@ public class TaskController {
         return taskService.getFileRejectReason(taskId,request);
     }
 
-
-//    /***
-//     * 文件审核
-//     * @param taskId 任务id
-//     * @param projectId 项目id
-//     * @param auditStatus 审核状态 1通过 2驳回
-//     * @param reason 驳回理由
-//     * @param request
-//     * @return
-//     */
-//    @PostMapping("/auditFile")
-//    public HttpRespMsg auditFile(@RequestParam("taskId")Integer taskId
-//            ,@RequestParam("projectId")String projectId
-//            ,@RequestParam("auditStatus")Integer auditStatus
-//            ,@RequestParam(value = "reason",required = false)String reason
-//            ,HttpServletRequest request) {
-//        return taskService.auditFile(taskId,projectId,auditStatus,reason,request);
-//    }
-
     @RequestMapping("/save")
     @Transactional
-    public HttpRespMsg save(Task task) throws Exception {
+    public HttpRespMsg save(Task task, @RequestParam(required = false, defaultValue = "false") boolean auditPass) throws Exception {
         String userId = request.getHeader("Token");
         String executorListStr = task.getExecutorListStr();
 
@@ -200,6 +181,12 @@ public class TaskController {
         WxCorpInfo wxCorpInfo = wxCorpInfoService.getOne(new QueryWrapper<WxCorpInfo>().eq("company_id", user.getCompanyId()));
         int isInsert=0;
         int isUpdate=0;
+        Project project = projectMapper.selectById(task.getProjectId());
+        String inchargerId = project.getInchargerId();
+        if (StringUtils.isEmpty(inchargerId)) {
+            msg.setError("请先设置项目经理");
+            return msg;
+        }
         //新建的任务,需要设置创建人,创建时间
         if (task.getId() == null) {
             isInsert=1;
@@ -208,15 +195,7 @@ public class TaskController {
             task.setCreaterName(user.getName());
             task.setCreatorColor(user.getColor());
             task.setCompanyId(user.getCompanyId());
-
-            if (user.getCompanyId()==Constant.MLD_COMPANY_ID&&task.getIsTaskPlan()==0&&task.getCheckFirstId()==null){
-                if (task.getProjectId()!=null){
-                    Project project = projectMapper.selectById(task.getProjectId());
-                    task.setCheckFirstId(project.getInchargerId());
-                }
-            }
-
-            if (user.getCompanyId()==Constant.MLD_COMPANY_ID&&task.getIsTaskPlan()==1){
+            if (task.getIsTaskPlan()==1){
                 task.setTaskPlan(1);
                 task.setTaskStatus(3);
                 //状态是请假 直接变成任务
@@ -226,24 +205,6 @@ public class TaskController {
                     task.setTaskPlan(1);
                 }
             }
-//            TimeType timeType = timeTypeMapper.selectById(user.getCompanyId());
-//            Integer taskFileCharge = timeType.getTaskFileCharge();
-//            if(1 == taskFileCharge){
-//                //主管: 员工所在部门[department]的manager_id 阶段一
-//                //项目经理:project表的in_charge_id 阶段二
-//                Department department = departmentMapper.selectById(user.getDepartmentId());
-//                Project project = projectMapper.selectById(task.getProjectId());
-//                if(org.apache.commons.lang3.StringUtils.isBlank(department.getManagerId())){
-//                    msg.setError("员工所在部门无负责人,请重新设置");
-//                    return msg;
-//                }
-//                if(org.apache.commons.lang3.StringUtils.isBlank(project.getInchargerId())){
-//                    msg.setError("该项目未设置项目经理,请重新设置");
-//                    return msg;
-//                }
-//                task.setChargeOneId(department.getManagerId());
-//                task.setChargeTwoId(project.getInchargerId());
-//            }
         }
         if (!StringUtils.isEmpty(executorListStr)) {
             List<User> allUsers = userMapper.selectList(new QueryWrapper<User>().eq("company_id", user.getCompanyId()));
@@ -253,7 +214,21 @@ public class TaskController {
                 User exeUser = allUsers.stream().filter(al->al.getId().equals(ex.getExecutorId())).findFirst().get();
                 ex.setExecutorName(exeUser.getName());
                 ex.setExecutorColor(exeUser.getColor());
+                ex.setFirstAuditorId(inchargerId);
+                //设置第二负责人,员工部门主要负责人
+                if (exeUser.getDepartmentId() != null && exeUser.getDepartmentId() > 0) {
+                    Department byId = departmentService.getById(exeUser.getDepartmentId());
+                    String managerId = byId.getManagerId();
+                    if (!StringUtils.isEmpty(managerId)) {
+                        ex.setSecondAuditorId(managerId);
+                    } else {
+                        msg.setError("请设置["+byId.getDepartmentName()+"]部门主要负责人");
+                    }
+                }
             });
+            if (msg.code.equals("error")) {
+                return msg;
+            }
             executorList.stream().forEach(ex->{
                 ex.setProjectId(task.getProjectId());
             });
@@ -297,28 +272,6 @@ public class TaskController {
                     }
                 }
             }
-            //针对依斯呗的校验
-            if(user.getCompanyId()==3092){
-                Project project = projectService.getById(task.getProjectId());
-                //除了报价项目  售后报价项目和研发项目不管控  其它项目都管控
-                List<String> excludeCategoryNames = Arrays.asList(new String[]{"报价项目","售后报价项目","研发项目","运维项目","数字化服务项目"});
-                List<ProjectCategory> extList = projectCategoryMapper.selectList(new QueryWrapper<ProjectCategory>().eq("company_id", user.getCompanyId()).in("name", excludeCategoryNames));
-                List<Integer> extIds = extList.stream().map(ProjectCategory::getId).collect(Collectors.toList());
-                if(task.getGroupId()!=null&&(project.getCategory()!=null && !extIds.contains(project.getCategory()))){
-                    TaskGroup taskGroup = taskGroupService.getById(task.getGroupId());
-                    if(taskGroup.getManDay()==null){
-                        msg.setError("创建失败,请先分配任务分组的预估工时");
-                        return msg;
-                    }
-                    //计算当前分组下的所有任务的计划工时
-                    List<Task> taskList = taskMapper.selectList(new LambdaQueryWrapper<Task>().select(Task::getPlanHours).eq(Task::getGroupId, taskGroup.getId()).isNotNull(Task::getPlanHours).ne(task.getId()!=null,Task::getId,task.getId()));
-                    int sum = taskList.stream().mapToInt(Task::getPlanHours).sum();
-                    if((sum+(task.getPlanHours()==null?0:task.getPlanHours()))>(taskGroup.getManDay()*8)){
-                        msg.setError("任务分组的预估工时不足,请增加预估工时");
-                        return msg;
-                    }
-                }
-            }
             //检查执行人是否在当前分组的参与人当中
             List<GroupParticipator> groupParticipatorList = groupParticipatorMapper.selectList(new QueryWrapper<GroupParticipator>().eq("group_id", task.getGroupId()));
             List<Participation> participationList = participationMapper.selectList(new QueryWrapper<Participation>().eq("project_id", task.getProjectId()));
@@ -380,15 +333,6 @@ public class TaskController {
                 needRecalculateProgress = true;
             }
         } else {
-//            task.setChargeOneId(null);
-//            task.setChargeStage(null);
-//            task.setChargeOneStatus(null);
-//            task.setChargeOneTime(null);
-//            task.setChargeTwoId(null);
-//            task.setChargeTwoStatus(null);
-//            task.setChargeTwoTime(null);
-//            task.setFinalChargeStatus(null);
-//            task.setFileRejectReason(null);
             //更新的情况,需要对比是否修改了任务标题,更新子任务的parentTname
             Task oldTask = taskService.getById(task.getId());
             if (!oldTask.getName().equals(task.getName())) {
@@ -479,52 +423,40 @@ public class TaskController {
                 needRecalculateProgress = true;
             }
             // 未驳回之前 第一审核人 修改工作计划
-            if (user.getCompanyId()==Constant.MLD_COMPANY_ID
-                    &&task.getIsTaskPlan()==1
-                    && org.apache.commons.lang3.StringUtils.isNotEmpty(task.getCheckFirstId())
-                    &&task.getCheckFirstId().equals(userId)
+            if (task.getIsTaskPlan()==1
+                    && auditPass
                     &&task.getTaskStatus()==3){
                 isUpdate=1;
                 task.setTaskStatus(4);//待第二审核人审核
-            } else if (user.getCompanyId() == Constant.MLD_COMPANY_ID
-                    && task.getIsTaskPlan() == 1
-                    && org.apache.commons.lang3.StringUtils.isNotEmpty(task.getCheckSecondId())
-                    && task.getCheckSecondId().equals(userId)
+            } else if (task.getIsTaskPlan() == 1
+                    && auditPass
                     &&task.getTaskStatus()==4) {
                 isUpdate=2;
                 task.setTaskStatus(0);//变化为进行中
                 task.setIsTaskPlan(0);//不再是计划
             }
             // 驳回后,小组长对计划进行修改
-            if (user.getCompanyId()==Constant.MLD_COMPANY_ID
-                    &&task.getIsTaskPlan()==1
+            if (task.getIsTaskPlan()==1
                     &&(task.getTaskStatus()==5||task.getTaskStatus()==6)
-                    &&(!userId.equals(task.getCheckFirstId())&&!userId.equals(task.getCheckSecondId()))
+                    && auditPass //小组长保存并提交
                     ){
                 isUpdate=3;
                 task.setTaskStatus(3);//待第一审核人审核
             }
             // 撤回后,对计划进行修改
-            if (user.getCompanyId()==Constant.MLD_COMPANY_ID
-                    &&task.getIsTaskPlan()==1
-                    &&(task.getTaskStatus()==2)
-            ){
-                if (user.getId().equals(task.getCheckFirstId())){
+            if (task.getIsTaskPlan()==1 && (task.getTaskStatus()==2) && auditPass) {
+                if (user.getId().equals(project.getInchargerId())) {
                     task.setTaskStatus(4);//待第二审核人审核
                     isUpdate=5;
-                } else if (user.getId().equals(task.getCheckSecondId())) {
-                    task.setTaskStatus(0);//变化为进行中
-                    task.setIsTaskPlan(0);//不再是计划
-                    isUpdate=6;
-                }else {
+                }
+                else {
                     task.setTaskStatus(3);//待第一审核人审核
                     isUpdate=4;
                 }
             }
         }
-        if (Constant.MLD_COMPANY_ID==user.getCompanyId()&&task.getIsTaskPlan()==1) {
-            if (task.getCheckSecondId() != null && !task.getExecutorList().isEmpty()) {
-                System.out.println("===>"+task.getExecutorList());
+        if (task.getIsTaskPlan()==1) {
+            if (!task.getExecutorList().isEmpty()) {
                 List<User> userManagers = userMapper.selectList(new QueryWrapper<User>()
                         .eq("role_name", "区域经理&PM").eq("company_id",user.getCompanyId()));
                 for (TaskExecutor taskExecutor : task.getExecutorList()) {
@@ -539,13 +471,12 @@ public class TaskController {
         boolean saved = taskService.saveOrUpdate(task);
         //新增成功,给第一审核人发送信息提醒
         if (saved&&isInsert==1){
-            if (user.getCompanyId()==Constant.MLD_COMPANY_ID&&task.getIsTaskPlan()==1&& org.apache.commons.lang3.StringUtils.isNotEmpty(task.getCheckFirstId())){
+            if (task.getIsTaskPlan()==1){
                 //给第一审核人发送信息提醒
                 msgRecepientList=new ArrayList<>();
                 log.info("添加工作计划,给第一审核人发送信息提醒");
-                User owner = userMapper.selectById(task.getCheckFirstId());
+                User owner = userMapper.selectById(inchargerId);
                 Information information = new Information();
-                Project project = projectMapper.selectById(task.getProjectId());
                 information.setMsg(project.getProjectName()+"项目有新的预计FTE计划审批任务,请您查收.");
                 information.setTaskId(task.getId());
                 information.setType(11);
@@ -557,15 +488,16 @@ public class TaskController {
             msgRecepientList=new ArrayList<>();
             //第一审核人修改后, 变成待第二审核人审核
             if (isUpdate==1||isUpdate==5){
-                User owner = userMapper.selectById(task.getCheckSecondId());
-                Information information = new Information();
-                Project project = projectMapper.selectById(task.getProjectId());
-                information.setMsg(project.getProjectName()+"项目有新的预计FTE计划审批任务,请您查收.");
-                information.setTaskId(task.getId());
-                information.setType(11);
-                information.setUserId(owner.getId());
-                information.setTime(LocalDateTime.now());
-                informationService.save(information);
+                for (TaskExecutor taskExecutor : task.getExecutorList()) {
+                    //给第二审核人发消息
+                    Information information = new Information();
+                    information.setMsg(project.getProjectName()+"项目有新的预计FTE计划审批任务,请您查收.");
+                    information.setTaskId(task.getId());
+                    information.setType(11);
+                    information.setUserId(taskExecutor.getSecondAuditorId());
+                    information.setTime(LocalDateTime.now());
+                    informationService.save(information);
+                }
 
             }else if(isUpdate==2||isUpdate==6){
                 List<TaskExecutor> taskExecutorList = taskExecutorMapper.selectList(new QueryWrapper<TaskExecutor>().eq("task_id", task.getId()));
@@ -585,10 +517,9 @@ public class TaskController {
             } else if (isUpdate==3) {
                 //给第一审核人发送信息提醒
                 log.info("驳回后小组长修改,给第一审核人发送信息提醒");
-                User owner = userMapper.selectById(task.getCheckFirstId());
+                User owner = userMapper.selectById(inchargerId);
                 Information information = new Information();
                 information.setType(11);
-                Project project = projectMapper.selectById(task.getProjectId());
                 information.setMsg(project.getProjectName()+"项目有新的预计FTE计划审批任务,请您查收.");
                 information.setTaskId(task.getId());
                 information.setUserId(owner.getId());
@@ -597,10 +528,9 @@ public class TaskController {
             } else if (isUpdate==4) {
                 //给第一审核人发送信息提醒
                 log.info("撤销后小组长修改,给第一审核人发送信息提醒");
-                User owner = userMapper.selectById(task.getCheckFirstId());
+                User owner = userMapper.selectById(inchargerId);
                 Information information = new Information();
                 information.setType(11);
-                Project project = projectMapper.selectById(task.getProjectId());
                 information.setMsg(project.getProjectName()+"项目有新的预计FTE计划审批任务,请您查收.");
                 information.setTaskId(task.getId());
                 information.setUserId(owner.getId());
@@ -624,7 +554,6 @@ public class TaskController {
             }
         }
 
-
         TaskComment comment = new TaskComment();
         comment.setTaskId(task.getId());
         comment.setUserId(user.getId());
@@ -644,7 +573,7 @@ public class TaskController {
                 informationService.save(new Information().setType(1).setContent(String.valueOf(task.getProjectId())).setUserId(msgRecepient));
             });
             List<User> recpUserList = userMapper.selectList(new QueryWrapper<User>().in("id", msgRecepientList));
-            if(user.getCompanyId()!=Constant.MLD_COMPANY_ID||task.getIsTaskPlan()!=1) {
+            if(task.getIsTaskPlan()!=1) {
                 if (recpUserList.size() > 0) {
                     if (recpUserList.get(0).getDingdingUserid() != null) {
                         //钉钉用户
@@ -683,6 +612,7 @@ public class TaskController {
         String token = request.getHeader("TOKEN");
         User user = userMapper.selectById(token);
         Task task = taskMapper.selectById(taskId);
+        Project project = projectMapper.selectById(task.getProjectId());
         if (task.getTaskPlan()!=1&&task.getIsTaskPlan()!=1){
             msg.setError("当前计划已变成任务不能撤回计划");
             return msg;
@@ -698,8 +628,8 @@ public class TaskController {
                 task.setTaskStatus(2);
                 taskMapper.updateById(task);
                 Information information = new Information();
-                User owner = userMapper.selectById(task.getCheckFirstId());
-                Project project = projectMapper.selectById(task.getProjectId());
+
+                User owner = userMapper.selectById(project.getInchargerId());
                 information.setMsg(project.getProjectName()+"项目有预计FTE计划撤销");
 //                information.setTaskId(task.getId());
                 information.setUserId(owner.getId());
@@ -712,18 +642,11 @@ public class TaskController {
             }
         }
         //计划的第一审核人
-        String checkFirstId = task.getCheckFirstId();
+        String checkFirstId = project.getInchargerId();
         if (checkFirstId!=null&&checkFirstId.equals(user.getId())){
             msg.setError("项目经理不能撤回");
             return msg;
         }
-
-        //计划的第二审核人
-        String checkSecondId = task.getCheckSecondId();
-        if (checkSecondId!=null&&checkSecondId.equals(user.getId())){
-            msg.setError("区域经理不能撤回");
-            return msg;
-        }
         return msg;
     }
 
@@ -1123,33 +1046,8 @@ public class TaskController {
             String name = userMapper.selectById(list.get(0).getCreatorId()).getName();
             list.get(0).setCreatorName(name);
         }
-        WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id",user.getCompanyId()));
         //查询任务的执行人
-//        List<TaskExecutor> executorList = taskExecutorMapper.selectList(new QueryWrapper<TaskExecutor>().eq("task_id", t.getId()));
-        List<TaskExecutor> executorList =taskExecutorMapper.getInfoWithFileCharge(t.getId());
-        if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
-            executorList.forEach(e->{
-                e.setFileChargeOneName("$userName="+e.getChargeOneWxId()+"$");
-                e.setFileChargeTwoName("$userName="+e.getChargeTwoWxId()+"$");
-                if(e.getServiceId()!=null){
-                    Optional<SapProjectService> first = serviceList.stream().filter(s -> s.getId().equals(e.getServiceId())).findFirst();
-                    if(first.isPresent()){
-                        e.setServiceName(first.get().getServiceName());
-                        e.setServiceCode(first.get().getServiceCode());
-                    }
-                }
-            });
-        }else{
-            executorList.forEach(e->{
-                if(e.getServiceId()!=null){
-                    Optional<SapProjectService> first = serviceList.stream().filter(s -> s.getId().equals(e.getServiceId())).findFirst();
-                    if(first.isPresent()){
-                        e.setServiceName(first.get().getServiceName());
-                        e.setServiceCode(first.get().getServiceCode());
-                    }
-                }
-            });
-        }
+        List<TaskExecutor> executorList = taskExecutorMapper.getInfoWithFileCharge(t.getId());
 
         t.setExecutorList(executorList);
         //设置人员选择下拉列表
@@ -1226,16 +1124,7 @@ public class TaskController {
         if (isSubstitude == 0 || userId == null) {
             userId = request.getHeader("Token");
         }
-
         msg.data = taskMapper.recentSimpleList(projectId, userId, stage, groupId);
-
-//        if (isSubstitude == 0) {
-//            msg.data = taskMapper.recentSimpleList(projectId, userId, stage, groupId);
-//        } else {
-//            //代填的情况,获取的是项目中的所有任务
-//            msg.data = taskMapper.recentSimpleList(projectId, null, stage, groupId);
-//        }
-
         return msg;
     }
 
@@ -1283,41 +1172,41 @@ public class TaskController {
         HttpRespMsg msg = new HttpRespMsg();
         String token = request.getHeader("TOKEN");
         User user = userMapper.selectById(token);
-        if (Constant.MLD_COMPANY_ID==user.getCompanyId()){
-            int count= projectLeaderMapper.selectCountIsLeader(id,user.getId());
-            //是这个计划的小组长
-            if (count>0){
-                /**
-                 * 任务状态,0-进行中 1-已完成 2-已撤销 3-待第一审核人审核 4-待第二审核人审核 5-第一审核人驳回  6-第二审核人驳回
-                 */
-                //待第一审核人审核
-                if (task.getTaskStatus()==3&&task.getIsTaskPlan()==1){
-                    msg.setError("当前计划已处于一级审核状态,小组长不能删除");
-                    return msg;
-                }else if(task.getTaskStatus()==4&&task.getIsTaskPlan()==1){
-                    msg.setError("当前计划已处于二级审核状态,小组长不能删除");
-                    return msg;
-                }else if(task.getTaskStatus()==0&&task.getIsTaskPlan()==0){
-                    msg.setError("当前计划已审核通过,小组长不能删除");
-                    return msg;
-                }
+        Project project = projectMapper.selectById(task.getProjectId());
+        int count= projectLeaderMapper.selectCountIsLeader(id,user.getId());
+        //是这个计划的小组长
+        if (count>0){
+            /**
+             * 任务状态,0-进行中 1-已完成 2-已撤销 3-待第一审核人审核 4-待第二审核人审核 5-第一审核人驳回  6-第二审核人驳回
+             */
+            //待第一审核人审核
+            if (task.getTaskStatus()==3&&task.getIsTaskPlan()==1){
+                msg.setError("当前计划已处于一级审核状态,小组长不能删除");
+                return msg;
+            }else if(task.getTaskStatus()==4&&task.getIsTaskPlan()==1){
+                msg.setError("当前计划已处于二级审核状态,小组长不能删除");
+                return msg;
+            }else if(task.getTaskStatus()==0&&task.getIsTaskPlan()==0){
+                msg.setError("当前计划已审核通过,小组长不能删除");
+                return msg;
             }
+        }
 
-            if (task.getCheckFirstId()!=null&&task.getCheckFirstId().equals(user.getId())){
-                if(task.getTaskStatus()==4&&task.getIsTaskPlan()==1){
-                    msg.setError("当前计划已处于二级审核状态,项目经理不能删除");
-                    return msg;
-                }else if(task.getTaskStatus()==0&&task.getIsTaskPlan()==0){
-                    msg.setError("当前计划已审核通过,项目经理不能删除");
-                    return msg;
-                }
+        if (project.getInchargerId()!=null&&project.getInchargerId().equals(user.getId())){
+            if(task.getTaskStatus()==4&&task.getIsTaskPlan()==1){
+                msg.setError("当前计划已处于二级审核状态,项目经理不能删除");
+                return msg;
+            }else if(task.getTaskStatus()==0&&task.getIsTaskPlan()==0){
+                msg.setError("当前计划已审核通过,项目经理不能删除");
+                return msg;
             }
+        }
 
-            if (task.getCheckSecondId()!=null&&task.getCheckSecondId().equals(user.getId())){
-                if(task.getTaskStatus()==3&&task.getIsTaskPlan()==1){
-                    msg.setError("当前计划已处于一级审核状态,区域经理不能删除");
-                    return msg;
-                }
+        List<TaskExecutor> executorList = taskExecutorMapper.selectList(new QueryWrapper<TaskExecutor>().eq("task_id", id));
+        for (TaskExecutor executor : executorList) {
+            if (task.getTaskStatus()==3&&task.getIsTaskPlan()==1 && user.getId().equals(executor.getSecondAuditorId())) {
+                msg.setError("当前计划已处于一级审核状态,区域经理不能删除");
+                return msg;
             }
         }
 
@@ -1623,6 +1512,9 @@ public class TaskController {
         } else if (viewId == 2) {
             //我创建的任务
             queryWrapper.eq("creater_id", userId);
+        } else if (viewId == 3) {
+            //我审核的
+
         }
         if(type!=null){
             queryWrapper.eq("task_type",type);
@@ -1633,13 +1525,11 @@ public class TaskController {
                     if(null != startDate && null != endDate){
                         queryWrapper.ge("start_date",startDate).le("start_date",endDate);
                     }
-
                     break;
                 case 1:
                     if(null != startDate && null != endDate){
                         queryWrapper.ge("task.end_date",startDate).le("task.end_date",endDate);
                     }
-
                     break;
             }
         }
@@ -1652,13 +1542,6 @@ public class TaskController {
         if(!StringUtils.isEmpty(targetUserId)){
             queryWrapper.like("task.executor_id",targetUserId);
         }
-//        else if (viewId == 3) {
-//            //今天的任务
-//            queryWrapper.eq("end_date", LocalDate.now());
-//        } else if (viewId == 4) {
-//            //已超期的任务,未完成的任务
-//            queryWrapper.lt("end_date", LocalDate.now()).eq("task_status", 0);
-//        }
         List<Integer> branchDepartment=null;
         if(deptId!=null){
             List<Department> departmentList=departmentService.list(new QueryWrapper<Department>().eq("company_id",companyId));
@@ -1668,137 +1551,20 @@ public class TaskController {
         if(pageIndex!=null&&pageSize!=null){
             pageStart = (pageIndex - 1) * pageSize;
         }
-        if (companyId==Constant.MLD_COMPANY_ID){
-            //美莱德 任务计划状态是1
-            queryWrapper.ne("is_task_plan",1);
+        //美莱德 任务计划状态是1
+        queryWrapper.ne("is_task_plan",1);
+        List<TaskWithAuditor> list;
+        if (viewId == 3) {
+            list = taskMapper.getMyAuditTaskList(queryWrapper,pageStart, pageSize,userId);
+        } else {
+            list = taskMapper.getTaskWithProjectName(queryWrapper,pageStart, pageSize,companyId,branchDepartment);
         }
-        List<Task> list = taskMapper.getTaskWithProjectName(queryWrapper,pageStart, pageSize,companyId,branchDepartment);
         List<Integer> collect = list.stream().map(l -> l.getId()).distinct().collect(Collectors.toList());
         collect.add(-1);
         List<TaskExecutor> taskExecutorList = taskExecutorMapper.selectList(new QueryWrapper<TaskExecutor>().in("task_id", collect));
-        List<TaskFiles> taskFilesList = taskFilesMapper.selectList(new LambdaQueryWrapper<TaskFiles>().eq(TaskFiles::getNeedFileCharge,1).in(TaskFiles::getTaskId, collect));
         List<Integer> pids = list.stream().map(Task::getProjectId).collect(Collectors.toList());
         pids.add(-1);
         List<Project> projectList = projectService.list(new QueryWrapper<Project>().in("id", pids));
-        TimeType timeType = timeTypeMapper.selectById(user.getCompanyId());
-//        WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id",user.getCompanyId()));
-//        CompanyDingding dingding = companyDingdingService.getOne(new LambdaQueryWrapper<CompanyDingding>().eq(CompanyDingding::getCompanyId, user.getCompanyId()));
-        if(0 != timeType.getTaskFileCharge()){
-            //根据该任务下的文件所处的状态判断
-            for (Task task : list) {
-                /**
-                 * 1、是否存在驳回文件
-                 *      过滤出上传人为当前登录人或审核人为当前登录人的任务文件
-                 *      若存在驳回文件,则显示存在驳回文件
-                 * 2、审核通过
-                 *      过滤出上传人为当前登录人或审核人为当前登录人的任务文件
-                 *      若都审核通过,则显示审核通过
-                 * 3、待审核
-                 *      过滤出上传人为当前登录人或审核人为当前登录人的任务文件
-                 *      若都是待审核或部分审核通过状态,则显示审核中
-                 **/
-                List<TaskFiles> currentTaskFiles = taskFilesList.stream().filter(tmp -> tmp.getTaskId().equals(task.getId()))
-                        .filter(t->{
-                            if(userId.equals(t.getCreatorId())){
-                                return true;
-                            } else if (userId.equals(t.getChargeOneId())) {
-                                return true;
-                            } else if (userId.equals(t.getChargeTwoId())) {
-                                return true;
-                            }else {
-                                return false;
-                            }
-                        })
-                        .collect(Collectors.toList());
-                if(CollectionUtils.isNotEmpty(currentTaskFiles)){
-                    //是否存在驳回
-                    long rejectCount = currentTaskFiles.stream().filter(tmp -> {
-                                if (2 == tmp.getChargeOneStatus() || 2 == tmp.getChargeTwoStatus()) {
-                                    return true;
-                                } else {
-                                    return false;
-                                }
-                            }).count();
-                    //是否都是全部通过
-                    long allPassCount = currentTaskFiles.stream().filter(tmp -> 1 == tmp.getFinalChargeStatus()).count();
-                    if(rejectCount > 0 ){
-                        task.setFileChargeStatus(2);
-                        task.setFinalChargeStatusText("存在驳回文件");
-                    } else if (allPassCount == currentTaskFiles.size()) {
-                        task.setFileChargeStatus(3);
-                        task.setFinalChargeStatusText("审核通过");
-                    }else {
-                        task.setFileChargeStatus(1);
-                        task.setFinalChargeStatusText("审核中");
-                    }
-
-                }
-
-            }
-
-        }
-//            List<String> userIds = new ArrayList<>();
-//            List<String> chargeOneIds = list.stream().filter(t-> org.apache.commons.lang3.StringUtils.isNotBlank(t.getChargeOneId()))
-//                    .map(Task::getChargeOneId).collect(Collectors.toList());
-//            List<String> chargeTwoIds = list.stream().filter(t-> org.apache.commons.lang3.StringUtils.isNotBlank(t.getChargeTwoId()))
-//                    .map(Task::getChargeTwoId).collect(Collectors.toList());
-//            userIds.addAll(chargeOneIds);
-//            userIds.addAll(chargeTwoIds);
-//            Map<String, User> userIdMap = new HashMap<>();
-//            if(CollectionUtils.isNotEmpty(userIds)){
-//                userIds = userIds.stream().distinct().collect(Collectors.toList());
-//                List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>()
-//                                .select(User::getId,User::getName)
-//                        .in(User::getId, userIds)
-//                );
-//                userIdMap = users.stream().collect(Collectors.toMap(User::getId, t->t));
-//            }
-//            Map<Integer, List<TaskFiles>> taskFilesMap = new HashMap<>();
-//            if(CollectionUtils.isNotEmpty(taskFilesList)){
-//                taskFilesMap  = taskFilesList.stream().collect(Collectors.groupingBy(TaskFiles::getTaskId));
-//            }
-//            for (Task task : list) {
-//                List<TaskFiles> tmp = taskFilesMap.get(task.getId());
-//                if(CollectionUtils.isEmpty(tmp)){
-//                    continue;
-//                }
-//                if(org.apache.commons.lang3.StringUtils.isBlank(task.getChargeOneId()) || org.apache.commons.lang3.StringUtils.isBlank(task.getChargeTwoId())){
-//                    continue;
-//                }
-//                if(1 == task.getFinalChargeStatus()){
-//                    task.setFinalChargeStatusText("审核通过");
-//                    task.setFileChargeStatus(1);
-//                } else if (0 == task.getFinalChargeStatus()) {
-//                    String name = "";
-//                    String statusText = "";
-//                    String userWxId = "";
-//                    String fileChargeStatusText = "";
-//                    int finalStatus = 1==task.getChargeStage()?task.getChargeOneStatus():task.getChargeTwoStatus();
-//                    String tmpUserId = 1==task.getChargeStage()?task.getChargeOneId():task.getChargeTwoId();
-//                    User chargeUser = userIdMap.get(tmpUserId);
-//                    if(null != chargeUser){
-//                        if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
-//                            userWxId = chargeUser.getCorpwxRealUserid();
-//                        }else if(dingding!=null&&dingding.getContactNeedTranslate()==1){
-//                            userWxId = chargeUser.getDingdingUserid();
-//                        }
-//                        name = chargeUser.getName();
-//                    }
-//                    switch (finalStatus)
-//                    {
-//                        case 0:  statusText = "待审核"; task.setFileChargeStatus(0);break;
-//                        case 1:  statusText = "通过";break;
-//                        case 2:  statusText = "驳回"; task.setFileChargeStatus(2);break;
-//                    }
-//                    if(org.apache.commons.lang3.StringUtils.isBlank(userWxId)){
-//                        fileChargeStatusText = statusText+"("+name+")";
-//                    }else{
-//                        fileChargeStatusText = statusText+"("+("$userName=" + userWxId + "$")+")";
-//                    }
-//                    task.setFinalChargeStatusText(fileChargeStatusText);
-//                }
-//            }
-//        }
         list.forEach(l->{
             List<TaskExecutor> executorList = taskExecutorList.stream().filter(tl -> tl.getTaskId().equals(l.getId())&&tl.getExecutorId()!=null).collect(Collectors.toList());
             l.setExecutorList(executorList);

+ 78 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/TaskTypeController.java

@@ -0,0 +1,78 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.Task;
+import com.management.platform.entity.TaskType;
+import com.management.platform.service.TaskService;
+import com.management.platform.service.TaskTypeService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.HttpRequestHandler;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-05-12
+ */
+@RestController
+@RequestMapping("/task-type")
+public class TaskTypeController {
+
+    @Resource
+    private TaskTypeService taskTypeService;
+    @Resource
+    private TaskService taskService;
+
+    @RequestMapping("/list")
+    public HttpRespMsg list(@RequestParam Integer companyId) {
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.data = taskTypeService.list(new QueryWrapper<TaskType>().eq("company_id", companyId));
+        return msg;
+    }
+
+    @RequestMapping("/save")
+    public HttpRespMsg save(TaskType taskType) {
+        //校验名称是否重叠
+        HttpRespMsg msg = new HttpRespMsg();
+        if (taskType.getId() == null) {
+            int cnt = taskTypeService.count(new QueryWrapper<TaskType>().eq("name", taskType.getName()).eq("company_id", taskType.getCompanyId()));
+            if (cnt > 0) {
+                msg.setError("名称重复");
+                return msg;
+            }
+        } else {
+            int cnt = taskTypeService.count(new QueryWrapper<TaskType>().ne("id", taskType.getId()).eq("name", taskType.getName()).eq("company_id", taskType.getCompanyId()));
+            if (cnt > 0) {
+                msg.setError("名称重复");
+                return msg;
+            }
+        }
+
+        taskTypeService.save(taskType);
+        return new HttpRespMsg();
+    }
+
+    @RequestMapping("/delete")
+    public HttpRespMsg delete(Integer id) {
+        //检查任务类型是否已经被使用
+        HttpRespMsg msg = new HttpRespMsg();
+        int cnt = taskService.count(new QueryWrapper<Task>().eq("task_plan_type", id));
+        if (cnt > 0) {
+            msg.setError("任务类型已经被使用");
+            return msg;
+        }
+        taskTypeService.removeById(id);
+        return new HttpRespMsg();
+    }
+}
+

+ 0 - 1
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/WeiXinCorpController.java

@@ -820,7 +820,6 @@ public class WeiXinCorpController {
                     ExcelExportServiceImpl.corpwxJobCenter.put(jobId, result);
                     ReportServiceImpl.corpwxJobCenter.put(jobId, result);
                     UserController.corpwxJobCenter.put(jobId, result);
-                    TaskController.corpwxJobCenter.put(jobId, result);
                     //注册到redis,其他系统可能需要用
                     redisUtil.setString("corpwxJobCenter"+jobId, jsonObject.toString(), 600);
                 } else if ("auto_activate".equals(infoType)) {

+ 38 - 78
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/entity/Task.java

@@ -21,7 +21,7 @@ import org.springframework.format.annotation.DateTimeFormat;
  * </p>
  *
  * @author Seyason
- * @since 2025-02-28
+ * @since 2025-05-12
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -85,7 +85,7 @@ public class Task extends Model<Task> {
     private Integer taskLevel;
 
     /**
-     * 任务状态,0-进行中 1-已完成 2-已撤销 3-待第一审核人审核 4-待第二审核人审核 5-第一审核人驳回  6-第二审核人驳回
+     * 任务状态,0-进行中 1-已完成 2-已撤销 3-待第一审核人审核 4-待第二审核人审核 5-驳回
      */
     @TableField("task_status")
     private Integer taskStatus;
@@ -174,19 +174,6 @@ public class Task extends Model<Task> {
     @DateTimeFormat(pattern = "yyyy-MM-dd")
     private LocalDate finishDate;
 
-    @TableField(exist = false)
-    private List<Task> subTaskList;
-
-    @TableField(exist = false)
-    private int subTaskFinishNum;
-    @TableField(exist = false)
-    private String stagesName;
-
-    @TableField(exist = false)
-    private TaskProgress progress;
-
-    @TableField(exist = false)
-    private String projectName;
     /**
      * 开始日期
      */
@@ -213,80 +200,47 @@ public class Task extends Model<Task> {
     @TableField("sap_task_code")
     private String sapTaskCode;
 
+    /**
+     * 任务预估成本
+     */
+    @TableField("plan_cost")
+    private Integer planCost;
+
+    /**
+     * 完成任务时,成果文件是否必传
+     */
+    @TableField("attach_file_required")
+    private Boolean attachFileRequired;
+
     /**
      * 任务计划类型 1.出差 2.在办公事处 3.请假
      */
     @TableField("task_plan_type")
     private Integer taskPlanType;
 
+    /**
+     * 标记任务计划 :0 否 ,1 是 ,默认 0
+     */
+    @TableField("task_plan")
+    private Integer taskPlan;
+
     /**
      * 是否是任务计划 :0 否 ,1 是 ,默认 0
      */
     @TableField("is_task_plan")
     private Integer isTaskPlan;
 
-    @TableField("task_plan")
-    private Integer taskPlan;
-
     /**
-     * 任务计划第一审核人id
-     */
-    @TableField("check_first_id")
-    private String checkFirstId;
-
-    /**
-     * 任务计划第二审核人id
-     */
-    @TableField("check_second_id")
-    private String checkSecondId;
-
-//    /**文件审核人一[部门负责人]id*/
-//    @TableField("charge_one_id")
-//    private String chargeOneId;
-//
-//
-//    /**文件审核人一的审核状态 0待审核 1通过 2驳回*/
-//    @TableField("charge_one_status")
-//    private Integer chargeOneStatus;
-//
-//    /**文件审核人一的审核时间*/
-//    @TableField("charge_one_time")
-//    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
-//    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-//    private Date chargeOneTime;
-//
-//    /**文件审核人二[项目审核人]id*/
-//    @TableField("charge_two_id")
-//    private String chargeTwoId;
-//
-//
-//    /**文件审核人二的审核状态 0待审核 1通过 2驳回*/
-//    @TableField("charge_two_status")
-//    private Integer chargeTwoStatus;
-//
-//    /**文件审核人二的审核时间*/
-//    @TableField("charge_two_time")
-//    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
-//    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-//    private Date chargeTwoTime;
-//
-//    /**文件审核阶段 1审核人一 2审核人二 3都审核通过*/
-//    @TableField("charge_stage")
-//    private Integer chargeStage;
-//
-//    /**文件最终审核状态  0未通过 1通过*/
-//    @TableField("final_charge_status")
-//    private Integer finalChargeStatus;
-//
-//    /**文件审核驳回原因*/
-//    @TableField("file_reject_reason")
-//    private String fileRejectReason;
+     * 研究中心
+     */
+    @TableField("center_id")
+    private Integer centerId;
 
     /**
-     * 任务预估成本
+     * 研究中心名称
      */
-    @TableField("plan_cost")
-    private Integer planCost;
+    @TableField("center_name")
+    private String centerName;
     /**
      * 项目负责人id
      */
@@ -327,13 +281,19 @@ public class Task extends Model<Task> {
      * 任务的外置状态显示 1审核中[待审核+(审核通过)] 2驳回[存在驳回文件]  3审核通过[全部审核通过]
      * */
     private int fileChargeStatus;
-    /**
-     * 完成任务时,成果文件是否必传
-     */
-    @TableField("attach_file_required")
-    private Boolean attachFileRequired;
+    @TableField(exist = false)
+    private List<Task> subTaskList;
 
+    @TableField(exist = false)
+    private int subTaskFinishNum;
+    @TableField(exist = false)
+    private String stagesName;
+
+    @TableField(exist = false)
+    private TaskProgress progress;
 
+    @TableField(exist = false)
+    private String projectName;
     @Override
     protected Serializable pkVal() {
         return this.id;

+ 30 - 22
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/entity/TaskExecutor.java

@@ -1,24 +1,24 @@
 package com.management.platform.entity;
 
 import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.extension.activerecord.Model;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.experimental.Accessors;
-
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
 
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
 /**
  * <p>
  * 
  * </p>
  *
  * @author Seyason
- * @since 2025-01-04
+ * @since 2025-05-12
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -72,32 +72,41 @@ public class TaskExecutor extends Model<TaskExecutor> {
     @TableField("real_cost")
     private Integer realCost;
 
-
-    @TableField(exist = false)
-    private String serviceName;
-
-    @TableField(exist = false)
-    private String serviceCode;
-
-    /**文件审核人一[自选]id*/
+    /**
+     * 文件审核人一
+     */
     @TableField("file_charge_one_id")
     private String fileChargeOneId;
 
-    @TableField(exist = false)
-    private String fileChargeOneName;
-
-    @TableField(exist = false)
-    private String chargeOneWxId;
-    /**文件审核人二[自选]id*/
+    /**
+     * 文件审核人二
+     */
     @TableField("file_charge_two_id")
     private String fileChargeTwoId;
 
+    /**
+     * 第一审核人
+     */
+    @TableField("first_auditor_id")
+    private String firstAuditorId;
+
+    /**
+     * 第二审核人
+     */
+    @TableField("second_auditor_id")
+    private String secondAuditorId;
+
     @TableField(exist = false)
     private String fileChargeTwoName;
 
     @TableField(exist = false)
     private String chargeTwoWxId;
 
+    @TableField(exist = false)
+    private String fileChargeOneName;
+
+    @TableField(exist = false)
+    private String chargeOneWxId;
     @Override
     protected Serializable pkVal() {
         return this.id;
@@ -128,5 +137,4 @@ public class TaskExecutor extends Model<TaskExecutor> {
         executor.setExecutorName(task.getExecutorName());
         executor.setExecutorColor(task.getExecutorColor());
     }
-
 }

+ 60 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/entity/TaskType.java

@@ -0,0 +1,60 @@
+package com.management.platform.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-05-12
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class TaskType extends Model<TaskType> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 类型名称
+     */
+    @TableField("name")
+    private String name;
+
+    /**
+     * 是否需要审核
+     */
+    @TableField("need_audit")
+    private Boolean needAudit;
+
+    /**
+     * 所属公司id
+     */
+    @TableField("company_id")
+    private Integer companyId;
+
+    /**
+     * 颜色
+     */
+    @TableField("color")
+    private String color;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 16 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/entity/TaskWithAuditor.java

@@ -0,0 +1,16 @@
+package com.management.platform.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import lombok.Data;
+
+@Data
+public class TaskWithAuditor extends Task {
+    @TableField(exist = false)
+    private String firstAuditorId;
+    @TableField(exist = false)
+    private String firstAuditorName;
+    @TableField(exist = false)
+    private String secondAuditorId;
+    @TableField(exist = false)
+    private String secondAuditorName;
+}

+ 12 - 14
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/mapper/ProjectMapper.java

@@ -68,39 +68,37 @@ public interface ProjectMapper extends BaseMapper<Project> {
 
     List<Map> getTaskPlanByMemb(@Param("userIds") List<String> userIds, @Param("startDate") String startDate,
                                     @Param("endDate") String endDate, @Param("companyId") Integer companyId,
-                                @Param("creatorId") String creatorId,@Param("justWaitForMe")Integer justWaitForMe
+                                    @Param("creatorId") String creatorId
                                 );
 
     List<Map> getTaskPlanByProject(@Param("projectIds") List<Integer> projectIds, @Param("startDate") String startDate,
                                 @Param("endDate") String endDate, @Param("companyId") Integer companyId,@Param("groupName")String groupName,@Param("taskType")Integer taskType,
-                                   @Param("creatorId") String creatorId,@Param("justWaitForMe")Integer justWaitForMe);
+                                   @Param("creatorId") String creatorId);
     List<Map> getTaskPlanWithLeave(@Param("userIds") List<String> userIds, @Param("startDate") String startDate,
                                    @Param("endDate") String endDate, @Param("companyId") Integer companyId,@Param("creatorId") String creatorId,@Param("targetUserId") String targetUserId);
 
     List<Map> getTaskPlanByGeneralMemb(@Param("userIds") List<String> userIds, @Param("startDate") String startDate,
-                                @Param("endDate") String endDate, @Param("companyId") Integer companyId,@Param("creatorId") String creatorId,@Param("targetUserId") String targetUserId,
-                                       @Param("justWaitForMe")Integer justWaitForMe);
+                                @Param("endDate") String endDate, @Param("companyId") Integer companyId,@Param("creatorId") String creatorId,@Param("targetUserId") String targetUserId
+                                       );
 
     List<Map> getTaskPlanByProManager(@Param("userIds") List<String> userIds, @Param("startDate") String startDate,
-                                      @Param("endDate") String endDate, @Param("companyId") Integer companyId,@Param("managerId") String managerId,@Param("targetUserId") String targetUserId,
-                                      @Param("justWaitForMe")Integer justWaitForMe);
+                                      @Param("endDate") String endDate, @Param("companyId") Integer companyId,@Param("managerId") String managerId,@Param("targetUserId") String targetUserId
+                                      );
     List<Map> getTaskPlanByAreaManager(@Param("userIds") List<String> userIds, @Param("startDate") String startDate,
-                                      @Param("endDate") String endDate, @Param("companyId") Integer companyId,@Param("managerId") String managerId,@Param("targetUserId") String targetUserId,
-                                       @Param("justWaitForMe")Integer justWaitForMe);
+                                      @Param("endDate") String endDate, @Param("companyId") Integer companyId,@Param("managerId") String managerId,@Param("targetUserId") String targetUserId
+                                       );
 
     List<Map> getTaskPlanByProjectGeneralMemb(@Param("projectIds") List<Integer> projectIds, @Param("startDate") String startDate,
                                    @Param("endDate") String endDate, @Param("companyId") Integer companyId,@Param("creatorId") String creatorId,
-                                              @Param("groupName")String groupName,@Param("taskType")Integer taskType,@Param("targetProjectId")Integer targetProjectId,
-                                              @Param("justWaitForMe")Integer justWaitForMe);
+                                              @Param("groupName")String groupName,@Param("taskType")Integer taskType,@Param("targetProjectId")Integer targetProjectId
+                                              );
 
     List<Map> getTaskPlanByProjectManager(@Param("projectIds") List<Integer> projectIds, @Param("startDate") String startDate,
                                               @Param("endDate") String endDate, @Param("companyId") Integer companyId,@Param("managerId") String managerId,
-                                          @Param("groupName")String groupName,@Param("taskType")Integer taskType,@Param("targetProjectId")Integer targetProjectId,
-                                          @Param("justWaitForMe")Integer justWaitForMe);
+                                          @Param("groupName")String groupName,@Param("taskType")Integer taskType,@Param("targetProjectId")Integer targetProjectId);
     List<Map> getTaskPlanByProjectAreaManager(@Param("projectIds") List<Integer> projectIds, @Param("startDate") String startDate,
                                           @Param("endDate") String endDate, @Param("companyId") Integer companyId,@Param("managerId") String managerId,
-                                              @Param("groupName")String groupName,@Param("taskType")Integer taskType,@Param("targetProjectId")Integer targetProjectId,
-                                              @Param("justWaitForMe")Integer justWaitForMe);
+                                              @Param("groupName")String groupName,@Param("taskType")Integer taskType,@Param("targetProjectId")Integer targetProjectId);
 
     List<ProjectWithStage> selectWithStage(Integer companyId, Integer startIndex, Integer endIndex, Integer projectId,String inchargerId,String startDate,String endDate);
 

+ 3 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/mapper/TaskMapper.java

@@ -88,4 +88,7 @@ public interface TaskMapper extends BaseMapper<Task> {
     List<ProjectTaskTimeCostVO> getProjectAllTaskTimeCost(@Param("projectId") Integer projectId);
 
     List<ProjectTimeCostVO> getProjectTaskTimeCostByIds(@Param("projectIds")List<Integer> projectIds);
+
+    List getMyAuditTaskList(@Param(Constants.WRAPPER) Wrapper wrapper, Integer pageStart, Integer pageSize,String userId);
+
 }

+ 16 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/mapper/TaskTypeMapper.java

@@ -0,0 +1,16 @@
+package com.management.platform.mapper;
+
+import com.management.platform.entity.TaskType;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-05-12
+ */
+public interface TaskTypeMapper extends BaseMapper<TaskType> {
+
+}

+ 0 - 29
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/service/FinanceMonthlyWorktimeService.java

@@ -1,29 +0,0 @@
-package com.management.platform.service;
-
-import com.management.platform.entity.FinanceMonthlyWorktime;
-import com.baomidou.mybatisplus.extension.service.IService;
-import com.management.platform.entity.FmwDetail;
-import com.management.platform.util.HttpRespMsg;
-
-import javax.servlet.http.HttpServletRequest;
-
-/**
- * <p>
- *  服务类
- * </p>
- *
- * @author Seyason
- * @since 2025-04-16
- */
-public interface FinanceMonthlyWorktimeService extends IService<FinanceMonthlyWorktime> {
-
-    HttpRespMsg send(String fmwId, String timesheetDate, HttpServletRequest request);
-
-    HttpRespMsg getByMonth(Integer companyId, String ymonth, Integer reGenerate, HttpServletRequest request) throws Exception;
-
-    HttpRespMsg setTimesheetDate(Integer id, String timesheetDate, HttpServletRequest request);
-
-    HttpRespMsg changeWorktime(FmwDetail detail, HttpServletRequest request);
-
-    HttpRespMsg setStatusFinal(Integer id, HttpServletRequest request);
-}

+ 1 - 1
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/service/ProjectService.java

@@ -116,7 +116,7 @@ public interface ProjectService extends IService<Project> {
 
     HttpRespMsg exportCustomerProjectInAndOut(HttpServletRequest request);
 
-    HttpRespMsg getGanttData(Integer type, String startDate, String endDate, String userId, Integer projectId, String groupName,Integer taskType,Integer justWaitForMe, HttpServletRequest request);
+    HttpRespMsg getGanttData(Integer type, String startDate, String endDate, String userId, Integer projectId, String groupName,Integer taskType, HttpServletRequest request);
 
     HttpRespMsg getProjectStagesCost(Integer pageIndex, Integer pageSize, Integer projectId, HttpServletRequest request,String stageNames,String startDate,String endDate);
 

+ 16 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/service/TaskTypeService.java

@@ -0,0 +1,16 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.TaskType;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-05-12
+ */
+public interface TaskTypeService extends IService<TaskType> {
+
+}

+ 0 - 13
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/service/impl/DingDingServiceImpl.java

@@ -20,7 +20,6 @@ import com.dingtalk.api.DingTalkClient;
 import com.dingtalk.api.request.*;
 import com.dingtalk.api.response.*;
 import com.management.platform.constant.Constant;
-import com.management.platform.controller.TaskController;
 import com.management.platform.controller.UserController;
 import com.management.platform.entity.*;
 import com.management.platform.entity.vo.UserVO;
@@ -1464,18 +1463,6 @@ public class DingDingServiceImpl implements DingDingService {
                                         }
                                     }
                                 }
-                            }else if(139 == bizType){
-                                JSONObject actionBizData = JSONObject.parseObject(bizItem.getString("biz_data"));
-                                String syncAction = actionBizData.getString("syncAction");
-                                if("transfer_contact_id_job_result".equals(syncAction)){
-                                    bizLogger.info("异步转译通讯录id任务完成通知");
-                                    String jobId = actionBizData.getString("jobId");
-                                    Integer status = actionBizData.getInteger("status");
-                                    ExcelExportServiceImpl.corpddJobCenter.put(jobId, status);
-                                    ReportServiceImpl.corpddJobCenter.put(jobId, status);
-                                    UserController.corpddJobCenter.put(jobId, status);
-                                    TaskController.corpddJobCenter.put(jobId, status);
-                                }
                             }
                         }
                     }

+ 0 - 375
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/service/impl/FinanceMonthlyWorktimeServiceImpl.java

@@ -1,375 +0,0 @@
-package com.management.platform.service.impl;
-
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.management.platform.entity.*;
-import com.management.platform.entity.vo.TisTimeVO;
-import com.management.platform.mapper.*;
-import com.management.platform.service.FinanceMonthlyWorktimeService;
-import com.management.platform.service.FmwDetailService;
-import com.management.platform.task.DataCollectTask;
-import com.management.platform.util.HttpRespMsg;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.ParameterizedTypeReference;
-import org.springframework.http.*;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.util.CollectionUtils;
-import org.springframework.web.client.RestTemplate;
-
-import javax.annotation.Resource;
-import javax.servlet.http.HttpServletRequest;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.*;
-import java.util.stream.Collectors;
-
-/**
- * <p>
- *  服务实现类
- * </p>
- *
- * @author Seyason
- * @since 2025-04-16
- */
-@Service
-public class FinanceMonthlyWorktimeServiceImpl extends ServiceImpl<FinanceMonthlyWorktimeMapper, FinanceMonthlyWorktime> implements FinanceMonthlyWorktimeService {
-    public static final String TIME_TYPE_COMPOSE = "组装工时(车间)";
-    public static final String TIME_TYPE_REPAIR = "维修工时(车间)";
-    public static final String TIME_TYPE_DEBUG = "调试工时(车间)";
-    public static final String TIME_TYPE_WAIT = "等料工时(车间)";
-    static List<String> groupNameList = new ArrayList<>();
-    {
-        groupNameList.add(TIME_TYPE_COMPOSE);
-        groupNameList.add(TIME_TYPE_REPAIR);
-        groupNameList.add(TIME_TYPE_DEBUG);
-        groupNameList.add(TIME_TYPE_WAIT);
-    }
-
-    @Resource
-    private FinanceMonthlyWorktimeMapper financeMonthlyWorktimeMapper;
-
-    @Resource
-    private FmwDetailMapper fmwDetailMapper;
-
-    @Resource
-    private UserMapper userMapper;
-    @Resource
-    private ReportMapper reportMapper;
-    @Resource
-    private DepartmentMapper departmentMapper;
-    @Resource
-    private TaskGroupMapper taskGroupMapper;
-    @Autowired
-    private ProjectMapper projectMapper;
-    @Autowired
-    private FmwDetailService fmwDetailService;
-    @Resource
-    private ErpOrderInfoMapper erpOrderInfoMapper;
-
-    @Override
-    public HttpRespMsg send(String fmwId, String timesheetDate, HttpServletRequest request) {
-        HttpRespMsg httpRespMsg = new HttpRespMsg();
-        String userId = request.getHeader("Token");
-        User user = userMapper.selectById(userId);
-//        String dateStr = "currentDate";//TODO 填充日期
-        FinanceMonthlyWorktime financeMonthlyWorktime = financeMonthlyWorktimeMapper.selectById(fmwId);
-        if(null == financeMonthlyWorktime){
-            httpRespMsg.setError("未找到当前内容");
-            return httpRespMsg;
-        }
-        if(0 == financeMonthlyWorktime.getStatus()){
-            httpRespMsg.setError("未定稿,无法发送");
-            return httpRespMsg;
-        }
-        financeMonthlyWorktimeMapper.update(null,new LambdaUpdateWrapper<FinanceMonthlyWorktime>()
-                .eq(FinanceMonthlyWorktime::getId,fmwId)
-                .set(FinanceMonthlyWorktime::getTimesheetDate, LocalDate.parse(timesheetDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")))
-        );
-
-
-        List<TisTimeVO> timeVOList = fmwDetailMapper.getTisTime(fmwId);
-
-        RestTemplate restTemplate = new RestTemplate();
-        String insertUrl = DataCollectTask.PREFIX_URL +"/dataCollect/insertCisData";
-        String checkUrl = DataCollectTask.PREFIX_URL +"/dataCollect/checkCisData";
-        if(!CollectionUtils.isEmpty(timeVOList)){
-            HttpHeaders headers = new HttpHeaders();
-            headers.setContentType(MediaType.APPLICATION_JSON);
-//            Map<String, Object> requestBody = new HashMap<>();
-//            requestBody.put("tisList", timeVOList);
-//            HttpEntity<Object> requestEntity = new HttpEntity<>(requestBody, headers);
-            HttpEntity<List<TisTimeVO>> requestEntity = new HttpEntity<>(timeVOList, headers);
-            ResponseEntity<List<TisTimeVO>> checkResponse = restTemplate.exchange(checkUrl, HttpMethod.POST, requestEntity
-                    ,new  ParameterizedTypeReference<List<TisTimeVO>>(){});
-            if(checkResponse.getStatusCode() == HttpStatus.OK){
-                List<TisTimeVO> resList = checkResponse.getBody();
-                List<TisTimeVO> tmpCheck = resList.stream().filter(t -> null != t.getCoId()).collect(Collectors.toList());
-                if(tmpCheck.size() != resList.size()){
-                    httpRespMsg.setError("财务尚未完成操作,无法获取cppid");
-                    return httpRespMsg;
-                }
-                resList.forEach(t->t.setDateStr(timesheetDate));
-                HttpHeaders insertHeaders = new HttpHeaders();
-                insertHeaders.setContentType(MediaType.APPLICATION_JSON);
-//                Map<String, Object> insertBody = new HashMap<>();
-//                insertBody.put("tisList", resList);
-//                HttpEntity<Object> insertEntity = new HttpEntity<>(insertBody, insertHeaders);
-                HttpEntity<List<TisTimeVO>> insertEntity = new HttpEntity<>(resList, headers);
-                ResponseEntity<String> tisResponse = restTemplate.exchange(insertUrl, HttpMethod.POST, insertEntity, String.class);
-                if (tisResponse.getStatusCode() == HttpStatus.OK) {
-                    System.out.println("插入成功");
-                    financeMonthlyWorktimeMapper.update(null,new LambdaUpdateWrapper<FinanceMonthlyWorktime>()
-                            .eq(FinanceMonthlyWorktime::getId,fmwId)
-                            .set(FinanceMonthlyWorktime::getIsSend, 1)
-                            .set(FinanceMonthlyWorktime::getLastSendTime, LocalDateTime.now())
-                    );
-                }else{
-                    System.out.println("插入失败");
-                }
-            }
-
-        }
-        financeMonthlyWorktime = financeMonthlyWorktimeMapper.selectById(fmwId);
-        httpRespMsg.setData(financeMonthlyWorktime);
-        return httpRespMsg;
-    }
-
-    @Transactional(rollbackFor = Exception.class)
-    @Override
-    public HttpRespMsg getByMonth(Integer companyId, String ymonth, Integer reGenerate, HttpServletRequest request) throws Exception {
-        //获取该月份的数据,如果没有自动生成
-        HttpRespMsg httpRespMsg = new HttpRespMsg();
-        String token = request.getHeader("token");
-        User user = userMapper.selectById(token);
-        FinanceMonthlyWorktime financeMonthlyWorktime = financeMonthlyWorktimeMapper.selectOne(new LambdaQueryWrapper<FinanceMonthlyWorktime>().eq(FinanceMonthlyWorktime::getCompanyId, companyId).eq(FinanceMonthlyWorktime::getYmonth, ymonth));
-        Integer detailCount = 0;
-        if (financeMonthlyWorktime != null) {
-            if (reGenerate== 1) {
-                if (financeMonthlyWorktime.getStatus() == 1) {
-                    httpRespMsg.setError("已定稿,无法重置");
-                    return httpRespMsg;
-                }
-                //删除明细数据
-                fmwDetailMapper.delete(new LambdaQueryWrapper<FmwDetail>().eq(FmwDetail::getFmwId, financeMonthlyWorktime.getId()));
-            } else {
-                detailCount = fmwDetailMapper.selectCount(new QueryWrapper<FmwDetail>().eq("fmw_id", financeMonthlyWorktime.getId()));
-            }
-        }
-        if(null == financeMonthlyWorktime || detailCount == 0){
-            if (null == financeMonthlyWorktime) {
-                //生成数据
-                financeMonthlyWorktime = new FinanceMonthlyWorktime();
-                financeMonthlyWorktime.setCompanyId(companyId);
-                financeMonthlyWorktime.setYmonth(ymonth);
-                financeMonthlyWorktime.setStatus(0);
-                //数据日期就是当前日期
-                financeMonthlyWorktime.setTimesheetDate(LocalDate.now());
-                financeMonthlyWorktime.setUserId(user.getId());
-                financeMonthlyWorktimeMapper.insert(financeMonthlyWorktime);
-            } else {
-                //更新数据日期为当前日期
-                financeMonthlyWorktime.setTimesheetDate(LocalDate.now());
-                financeMonthlyWorktime.setUserId(user.getId());
-                financeMonthlyWorktimeMapper.updateById(financeMonthlyWorktime);
-            }
-            //生成明细数据
-            //获取当月的第一天和最后一天
-            LocalDate firstDayOfMonth = LocalDate.parse(ymonth + "-01", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
-            LocalDate lastDayOfMonth = firstDayOfMonth.withDayOfMonth(firstDayOfMonth.lengthOfMonth());
-            //查询日报数据
-            List<Department> departmentList = departmentMapper.selectList(new LambdaQueryWrapper<Department>().eq(Department::getCompanyId, user.getCompanyId()));
-            List<Project> projectList = projectMapper.selectList(new LambdaQueryWrapper<Project>().eq(Project::getCompanyId, user.getCompanyId()));
-            List<Project> publicProjectList = projectList.stream().filter(p -> p.getIsPublic() == 1).collect(Collectors.toList());
-            List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().select(User::getId, User::getName, User::getDepartmentId).eq(User::getCompanyId, user.getCompanyId()));
-
-            List<Report> reportList = reportMapper.getReportProjectGroupDetailList(user.getCompanyId(), firstDayOfMonth, lastDayOfMonth, groupNameList);
-            List<Report> assistList = reportMapper.getReportProjectAssistTime(user.getCompanyId(), firstDayOfMonth, lastDayOfMonth, groupNameList);
-
-            System.out.println("reportSize==="+reportList.size());
-            List<FmwDetail> insertDataList = new ArrayList<>();
-            for (Report report : reportList) {
-                //在insertDataList中按照projectId, extraField4,extraField5进行匹配查找,有的话取出来,没有的话插入
-                Optional<FmwDetail> optional = insertDataList.stream().filter(f -> f.getProjectId().equals(report.getProjectId()) && f.getExtraField4().equals(report.getExtraField4()) && f.getExtraField5().equals(report.getExtraField5())).findFirst();
-                if (optional.isPresent()) {
-                    FmwDetail fmwDetail = optional.get();
-                    setFmwTime(fmwDetail, report);
-                } else {
-                    FmwDetail fmwDetail = new FmwDetail();
-                    fmwDetail.setComposeTime(0.0);
-                    fmwDetail.setRepairTime(0.0);
-                    fmwDetail.setDebugTime(0.0);
-                    fmwDetail.setWaitingTime(0.0);
-                    fmwDetail.setAssistTime(0.0);
-
-                    fmwDetail.setFmwId(financeMonthlyWorktime.getId());
-                    fmwDetail.setProjectId(report.getProjectId());
-                    projectList.stream().filter(p->p.getId().equals(report.getProjectId())).findFirst().ifPresent(project -> {
-                        fmwDetail.setProjectCode(project.getProjectCode());
-                    });
-                    fmwDetail.setExtraField4(report.getExtraField4());
-                    fmwDetail.setExtraField5(report.getExtraField5());
-                    fmwDetail.setDeptId(report.getDeptId());
-                    departmentList.stream().filter(d->d.getDepartmentId().equals(report.getDeptId())).findFirst().ifPresent(d->{
-                        fmwDetail.setDeptCode(d.getDeptCode());
-                        fmwDetail.setDeptName(d.getDepartmentName());
-                    });
-                    setFmwTime(fmwDetail, report);
-                    //从assistList中获取协作工时
-                    Optional<Report> assistItemOp = assistList.stream().filter(f -> f.getProjectId().equals(report.getProjectId()) && f.getExtraField4().equals(report.getExtraField4()) && f.getExtraField5().equals(report.getExtraField5())).findFirst();
-                    if (assistItemOp.isPresent()) {
-                        fmwDetail.setAssistTime(assistItemOp.get().getWorkingTime());
-                    }
-                    insertDataList.add(fmwDetail);
-                }
-            }
-            System.out.println("插入数据大小=="+insertDataList.size());
-
-            // 处理公共项目工时分摊
-            List<Integer> publicProjectIds = publicProjectList.stream()
-                    .map(Project::getId)
-                    .collect(Collectors.toList());
-
-            if (!publicProjectIds.isEmpty()) {
-                // 查询公共项目工时
-                //TODO: 需确认,员工填报公共项目工时的时候,会选择到工单吗?
-                List<Report> publicReportList = reportMapper.selectList(
-                        new LambdaQueryWrapper<Report>().select(Report::getCreatorId, Report::getDeptId, Report::getWorkingTime).eq(Report::getState, 1)
-                                .in(Report::getProjectId, publicProjectIds).between(Report::getCreateDate, firstDayOfMonth, lastDayOfMonth));
-                //按照人员所在的部门进行分组,汇总,如果公共项目没有工单,此步骤可以省略
-                publicReportList.forEach(report -> {
-                    User reportOwner = userList.stream().filter(u -> u.getId().equals(report.getCreatorId())).findFirst().orElse(null);
-                    if (reportOwner != null) {
-                        report.setDeptId(reportOwner.getDepartmentId());
-                    }
-                });
-                //分组,合计部门公共工时
-                Map<Integer, Double> map = publicReportList.stream().collect(Collectors.groupingBy(Report::getDeptId, Collectors.summingDouble(Report::getWorkingTime)));
-                //将map按照List形式重新组合
-                publicReportList = map.entrySet().stream()
-                        .map(e -> {
-                            Report report = new Report();
-                            report.setDeptId(e.getKey());
-                            report.setWorkingTime(e.getValue());
-                            return report;
-                        })
-                        .collect(Collectors.toList());
-                if (!publicReportList.isEmpty()) {
-                    //处理每个部门的公共项目工时分摊
-                    for (Report publicReportDeptItem : publicReportList) {
-                        Integer deptId = publicReportDeptItem.getDeptId();
-                        List<FmwDetail> deptAllReportList = insertDataList.stream().filter(r -> r.getDeptId().equals(deptId)).collect(Collectors.toList());
-                        double totalDeptTime = deptAllReportList.stream().reduce(0.0, (a, b) -> a + b.getComposeTime() + b.getRepairTime() + b.getDebugTime() + b.getWaitingTime(), Double::sum);
-                        System.out.println("处理公共工时分摊,总工时=="+totalDeptTime);
-                        if (totalDeptTime > 0) {
-                            //计算总工时: 用维修组装工时,调试工时和等料工时相加
-                            insertDataList.forEach(fmwDetail -> {
-                                //计算每一个项目的部门内部工时占比,按比例分摊公共工时
-                                if (fmwDetail.getDeptId().equals(deptId)) {
-                                    double curProjectTime = fmwDetail.getComposeTime() + fmwDetail.getRepairTime() + fmwDetail.getDebugTime() + fmwDetail.getWaitingTime();
-                                    double assignTime = curProjectTime / totalDeptTime * publicReportDeptItem.getWorkingTime();
-                                    //理论上不会出现fmwDetail.getPublicTime()有值的情况,但是为了保险起见做个叠加计算吧
-                                    fmwDetail.setPublicTime(fmwDetail.getPublicTime() == null ? assignTime : fmwDetail.getPublicTime() + assignTime);
-                                }
-                            });
-                        } else {
-                            //该部门没有部门内部工时,按照填报部门找协作工时
-                            // 查找该部门的员工都协作了哪些部门
-                            List<User> deptUserList = userList.stream().filter(u -> u.getDepartmentId().equals(deptId)).collect(Collectors.toList());
-                            List<String> deptUserIds = deptUserList.stream().map(User::getId).collect(Collectors.toList());
-                            List<Report> assistDeptListByUser = reportMapper.selectList(new QueryWrapper<Report>().select("dept_id, sum(working_time) working_time").eq("is_assist", 1)
-                                    .in("creator_id", deptUserIds).between("create_date", firstDayOfMonth, lastDayOfMonth).groupBy("dept_id"));
-                            //按协作的工时占比来分配
-                            if (!assistDeptListByUser.isEmpty()) {
-                                double totalAssistTime = assistDeptListByUser.stream().mapToDouble(Report::getWorkingTime).sum();
-                                if (totalAssistTime > 0) {
-                                    for (Report assistDeptItem : assistDeptListByUser) {
-                                        //处理部门公共工时的分摊,先按协作的其他部门的占比,分到其他部门
-                                        double curAssistTime = assistDeptItem.getWorkingTime();
-                                        double assignToDeptTime = curAssistTime / totalAssistTime * publicReportDeptItem.getWorkingTime();
-                                        //按目标部门的部门内部工时占比进行二次分配
-                                        Integer assignToDeptId = assistDeptItem.getDeptId();
-                                        List<FmwDetail> targetDeptReportList = insertDataList.stream().filter(r -> r.getDeptId().equals(assignToDeptId)).collect(Collectors.toList());
-                                        double totalTargetDeptTime = targetDeptReportList.stream().reduce(0.0, (a, b) -> a + b.getComposeTime() + b.getRepairTime() + b.getDebugTime() + b.getWaitingTime(), Double::sum);
-                                        if (totalTargetDeptTime > 0) {
-                                            //计算总工时: 用维修组装工时,调试工时和等料工时相加
-                                            insertDataList.forEach(fmwDetail -> {
-                                                //计算每一个项目的部门内部工时占比,按比例分摊公共工时
-                                                if (fmwDetail.getDeptId().equals(assignToDeptId)) {
-                                                    double curProjectTime = fmwDetail.getComposeTime() + fmwDetail.getRepairTime() + fmwDetail.getDebugTime() + fmwDetail.getWaitingTime();
-                                                    double assignTime = curProjectTime / totalTargetDeptTime * assignToDeptTime;
-                                                    //可能之前已经有其他部门的分摊过来了,需要叠加
-                                                    fmwDetail.setPublicTime(fmwDetail.getPublicTime() == null ? assignTime : fmwDetail.getPublicTime() +assignTime);
-                                                }
-                                            });
-                                        } else {
-                                            Department dept = departmentMapper.selectById(assignToDeptId);
-                                            throw new Exception("存在目标部门没有内部工时,导致公共工时无法分摊:部门=="+dept.getDepartmentName()+",deptId=="+assignToDeptId);
-                                        }
-                                    }
-                                }
-                            } else {
-                                //本部门也没有协作其他部门产生工单工时
-                                Department dept = departmentMapper.selectById(deptId);
-                                throw new Exception("公共工时无法分配,因为本部门没有协作其他部门产生工单工时,部门=="+dept.getDepartmentName()+",deptId=="+deptId);
-                            }
-                        }
-                    }
-                }
-            }
-
-            if (insertDataList.size() > 0) {
-                fmwDetailService.saveBatch(insertDataList);
-            }
-        }
-        //查询数据
-        List<FmwDetail> details = fmwDetailMapper.selectList(new QueryWrapper<FmwDetail>().eq("fmw_id", financeMonthlyWorktime.getId()));
-        financeMonthlyWorktime.setDetailList(details);
-        httpRespMsg.data = financeMonthlyWorktime;
-        return httpRespMsg;
-    }
-
-    private void setFmwTime(FmwDetail fmwDetail, Report report) {
-        switch (report.getGroupName()) {
-            case TIME_TYPE_COMPOSE:
-                fmwDetail.setComposeTime(report.getWorkingTime());
-                break;
-            case TIME_TYPE_REPAIR:
-                fmwDetail.setRepairTime(report.getWorkingTime());
-                break;
-            case TIME_TYPE_DEBUG:
-                fmwDetail.setDebugTime(report.getWorkingTime());
-                break;
-            case TIME_TYPE_WAIT:
-                fmwDetail.setWaitingTime(report.getWorkingTime());
-                break;
-        }
-    }
-
-    @Override
-    public HttpRespMsg setTimesheetDate(Integer id, String timesheetDate, HttpServletRequest request) {
-        FinanceMonthlyWorktime financeMonthlyWorktime = new FinanceMonthlyWorktime();
-        financeMonthlyWorktime.setId(id);
-        financeMonthlyWorktime.setTimesheetDate(LocalDate.parse(timesheetDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")));
-        financeMonthlyWorktimeMapper.updateById(financeMonthlyWorktime);
-        return new HttpRespMsg();
-    }
-
-    @Override
-    public HttpRespMsg changeWorktime(FmwDetail detail, HttpServletRequest request) {
-        fmwDetailService.updateById(detail);
-        return new HttpRespMsg();
-    }
-
-    @Override
-    public HttpRespMsg setStatusFinal(Integer id, HttpServletRequest request) {
-        FinanceMonthlyWorktime financeMonthlyWorktime = new FinanceMonthlyWorktime();
-        financeMonthlyWorktime.setId(id);
-        financeMonthlyWorktime.setStatus(1);
-        financeMonthlyWorktimeMapper.updateById(financeMonthlyWorktime);
-        return new HttpRespMsg();
-    }
-}

+ 11 - 8
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/service/impl/InformationServiceImpl.java

@@ -7,12 +7,11 @@ import com.baomidou.mybatisplus.generator.config.IFileCreate;
 import com.management.platform.constant.Constant;
 import com.management.platform.entity.*;
 import com.management.platform.entity.vo.GanttDataItem;
-import com.management.platform.mapper.InformationMapper;
-import com.management.platform.mapper.UserMapper;
-import com.management.platform.mapper.WxCorpInfoMapper;
+import com.management.platform.mapper.*;
 import com.management.platform.service.*;
 import com.management.platform.util.HttpRespMsg;
 import com.management.platform.util.MessageUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
@@ -37,6 +36,8 @@ public class InformationServiceImpl extends ServiceImpl<InformationMapper, Infor
 
     @Resource
     private UserMapper userMapper;
+    @Resource
+    TaskExecutorMapper taskExecutorMapper;
 
     @Resource
     private WxCorpInfoMapper wxCorpInfoMapper;
@@ -52,6 +53,8 @@ public class InformationServiceImpl extends ServiceImpl<InformationMapper, Infor
     private ProjectLeaderService projectLeaderService;
     @Resource
     private ProjectService projectService;
+    @Autowired
+    private ProjectMapper projectMapper;
 
     @Override
     public HttpRespMsg getInformationList(HttpServletRequest request) {
@@ -60,8 +63,8 @@ public class InformationServiceImpl extends ServiceImpl<InformationMapper, Infor
             User user = userMapper.selectById(request.getHeader("token"));
 
             int countLeader = projectLeaderService.count(new QueryWrapper<ProjectLeader>().eq("leader_id", user.getId()).eq("company_id", user.getCompanyId()));
-            int countFirstCheck = projectService.count(new QueryWrapper<Project>().eq("incharger_id", user.getId()));
-            int countSecondCheck = taskService.count(new QueryWrapper<Task>().eq("check_second_id", user.getId()));
+            int countFirstCheck = projectMapper.selectCount(new QueryWrapper<Project>().eq("incharger_id", user.getId()));
+            int countSecondCheck = taskExecutorMapper.selectCount(new QueryWrapper<TaskExecutor>().eq("second_auditor_id", user.getId()));
 
             List<Information> information = informationMapper.selectList(new QueryWrapper<Information>()
                     .eq("user_id", user.getId()).orderByDesc("time").last("LIMIT 20"));
@@ -89,7 +92,7 @@ public class InformationServiceImpl extends ServiceImpl<InformationMapper, Infor
                     String newMsg = msg.replace(name, "$userName=" + userWxId + "$");
                     info.setMsg(newMsg);
                 }
-                if (Constant.MLD_COMPANY_ID==user.getCompanyId()&&info.getTaskId()!=null){
+                if (info.getTaskId()!=null){
                     Task task = taskService.getById(info.getTaskId());
                     if (task!=null){
                         GanttDataItem dataItem = new GanttDataItem();
@@ -100,8 +103,8 @@ public class InformationServiceImpl extends ServiceImpl<InformationMapper, Infor
                         } else if (countFirstCheck > 0 || countSecondCheck > 0) {
                             dataItem.setLeaderOrManager(2);
                         }
-                        dataItem.setCheckFirstId(task.getCheckFirstId());
-                        dataItem.setCheckSecondId(task.getCheckSecondId());
+//                        dataItem.setCheckFirstId(task.getCheckFirstId());
+//                        dataItem.setCheckSecondId(task.getCheckSecondId());
                         dataItem.setObjType(2);
                         dataItem.setIsTaskPlan(task.getIsTaskPlan());
                         dataItem.setTaskPlan(task.getTaskPlan());

+ 141 - 169
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java

@@ -1601,23 +1601,16 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                     }
                     projectVO.setProviderInfoList(mapList);
                 }
-                if(companyId==936){
-                    Optional<ProjectSeparate> first1 = projectSeparateList.stream().filter(ps -> ps.getId().equals(project.getId())).findFirst();
-                    if(first1.isPresent()){
-                        projectVO.setProjectSeparate(first1.get());
-                    }
-                }else if (companyId==Constant.MLD_COMPANY_ID){
-                    if (!leaderList.isEmpty()) {
-                        List<ProjectLeader> leaderCollect = leaderList.stream().filter(l ->l.getProjectId()!=null&& l.getProjectId().equals(project.getId())).collect(Collectors.toList());
-                        leaderCollect.forEach(l -> {
-                            Optional<User> userOptional = userList.stream().filter(u -> u.getId().equals(l.getLeaderId())).findFirst();
-                            if (userOptional.isPresent()) {
-                                User user1 = userOptional.get();
-                                l.setUserName(user1.getName());
-                            }
-                        });
-                        projectVO.setLeaderList(leaderCollect);
-                    }
+                if (!leaderList.isEmpty()) {
+                    List<ProjectLeader> leaderCollect = leaderList.stream().filter(l ->l.getProjectId()!=null&& l.getProjectId().equals(project.getId())).collect(Collectors.toList());
+                    leaderCollect.forEach(l -> {
+                        Optional<User> userOptional = userList.stream().filter(u -> u.getId().equals(l.getLeaderId())).findFirst();
+                        if (userOptional.isPresent()) {
+                            User user1 = userOptional.get();
+                            l.setUserName(user1.getName());
+                        }
+                    });
+                    projectVO.setLeaderList(leaderCollect);
                 }
 
                 //工程专业版:计算当前项目的总进度
@@ -1868,24 +1861,22 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                     } else {
                         project.setCustomerName("");
                     }
-                    if (companyId==Constant.MLD_COMPANY_ID){
-                        if (leaderIds!=null&&leaderIds.length>0) {
-                            List<User> userManagers = userMapper.selectList(new QueryWrapper<User>()
-                                    .eq("role_name", "区域经理&PM").eq("company_id",companyId));
-                            for (String leaderId : leaderIds) {
-                                ProjectLeader leader = new ProjectLeader();
-                                leader.setProjectId(project.getId());
-                                leader.setLeaderId(leaderId);
-                                if (!userManagers.isEmpty()){
-                                    boolean b = userManagers.stream().anyMatch(u -> u.getId().equals(leaderId));
-                                    if (b){
-                                        httpRespMsg.setError("区域经理不能担任小组长");
-                                        return httpRespMsg;
-                                    }
+                    if (leaderIds!=null&&leaderIds.length>0) {
+                        List<User> userManagers = userMapper.selectList(new QueryWrapper<User>()
+                                .eq("role_name", "区域经理&PM").eq("company_id",companyId));
+                        for (String leaderId : leaderIds) {
+                            ProjectLeader leader = new ProjectLeader();
+                            leader.setProjectId(project.getId());
+                            leader.setLeaderId(leaderId);
+                            if (!userManagers.isEmpty()){
+                                boolean b = userManagers.stream().anyMatch(u -> u.getId().equals(leaderId));
+                                if (b){
+                                    httpRespMsg.setError("区域经理不能担任小组长");
+                                    return httpRespMsg;
                                 }
-                                leader.setCompanyId(companyId);
-                                leaderArrayList.add(leader);
                             }
+                            leader.setCompanyId(companyId);
+                            leaderArrayList.add(leader);
                         }
                     }
                     if (projectMapper.insert(project) == 0) {
@@ -1899,11 +1890,10 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                             updateProjectKeyNodesData(projectKeyNodesData, project.getId());
                         }
 
-                    }if (companyId==Constant.MLD_COMPANY_ID) {
-                        if (leaderIds != null && leaderIds.length > 0) {
-                            leaderArrayList.forEach(l->l.setProjectId(project.getId()));
-                            projectLeaderService.saveBatch(leaderArrayList);
-                        }
+                    }
+                    if (leaderIds != null && leaderIds.length > 0) {
+                        leaderArrayList.forEach(l->l.setProjectId(project.getId()));
+                        projectLeaderService.saveBatch(leaderArrayList);
                     }
                     id = project.getId();
                     if(companyId==936){
@@ -2140,13 +2130,11 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                     //httpRespMsg.setError("操作失败");
                     httpRespMsg.setError(MessageUtils.message("other.operationFail"));
                 } else {
-                    if (Constant.MLD_COMPANY_ID==companyId){
-                        //项目经理换人,对应任务计划的第一审核人得换
-                        String inchargerId_old = oldProject.getInchargerId();
-                        if (!inchargerId.equals(inchargerId_old)){
-                            taskService.update(null,new UpdateWrapper<Task>().eq("project_id",oldProject.getId())
-                                    .eq("task_plan",1).set("check_first_id",inchargerId));
-                        }
+                    //项目经理换人,对应任务计划的第一审核人得换
+                    String inchargerId_old = oldProject.getInchargerId();
+                    if (!inchargerId.equals(inchargerId_old)){
+                        taskService.update(null,new UpdateWrapper<Task>().eq("project_id",oldProject.getId())
+                                .eq("task_plan",1).set("check_first_id",inchargerId));
                     }
                     if (customerId == null) {
                         //去掉客户
@@ -2183,36 +2171,26 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                 operationRecord.setOperatorName(user.getName());
                 operationRecord.setOperationTime(LocalDateTime.now());
                 operationRecord.setCompanyId(companyId);
-                if(companyId==936){
-                    projectSeparate.setId(id);
-                    if(oldSeparate!=null){
-                        if(!onlyChangeParticipate){
-                            String s = beanChangeUtil.contrastObj(oldSeparate, projectSeparate);
-                            content+="\n"+s;
-                        }
-                    }
-                }else if (companyId==Constant.MLD_COMPANY_ID){
-                    projectLeaderService.remove(new QueryWrapper<ProjectLeader>().eq("project_id",p.getId()));
-                    List<User> userManagers = userMapper.selectList(new QueryWrapper<User>()
-                            .eq("role_name", "区域经理&PM").eq("company_id",companyId));
-                    if (leaderIds!=null&&leaderIds.length>0) {
-                        ArrayList<ProjectLeader> leaderArrayList = new ArrayList<>();
-                        for (String leaderId : leaderIds) {
-                            ProjectLeader leader = new ProjectLeader();
-                            leader.setProjectId(p.getId());
-                            leader.setLeaderId(leaderId);
-                            leader.setCompanyId(companyId);
-                            if (!userManagers.isEmpty()){
-                                boolean b = userManagers.stream().anyMatch(u -> u.getId().equals(leaderId));
-                                if (b){
-                                    httpRespMsg.setError("区域经理不能担任小组长");
-                                    return httpRespMsg;
-                                }
+                projectLeaderService.remove(new QueryWrapper<ProjectLeader>().eq("project_id",p.getId()));
+                List<User> userManagers = userMapper.selectList(new QueryWrapper<User>()
+                        .eq("role_name", "区域经理&PM").eq("company_id",companyId));
+                if (leaderIds!=null&&leaderIds.length>0) {
+                    ArrayList<ProjectLeader> leaderArrayList = new ArrayList<>();
+                    for (String leaderId : leaderIds) {
+                        ProjectLeader leader = new ProjectLeader();
+                        leader.setProjectId(p.getId());
+                        leader.setLeaderId(leaderId);
+                        leader.setCompanyId(companyId);
+                        if (!userManagers.isEmpty()){
+                            boolean b = userManagers.stream().anyMatch(u -> u.getId().equals(leaderId));
+                            if (b){
+                                httpRespMsg.setError("区域经理不能担任小组长");
+                                return httpRespMsg;
                             }
-                            leaderArrayList.add(leader);
                         }
-                        projectLeaderService.saveBatch(leaderArrayList);
+                        leaderArrayList.add(leader);
                     }
+                    projectLeaderService.saveBatch(leaderArrayList);
                 }
                 operationRecord.setContent(content);
                 //operationRecord.setModuleName("项目管理");
@@ -4804,7 +4782,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
     }
 
     @Override
-    public HttpRespMsg getGanttData(Integer type, String startDate, String endDate, String targetUserId, Integer targetProjectId, String groupName,Integer taskType,Integer justWaitForMe, HttpServletRequest request) {
+    public HttpRespMsg getGanttData(Integer type, String startDate, String endDate, String targetUserId, Integer targetProjectId, String groupName,Integer taskType,HttpServletRequest request) {
         //根据人员权限来获取,
         String token = request.getHeader("TOKEN");
         User user = userMapper.selectById(token);
@@ -4865,63 +4843,61 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                 String lsLastItemId = null;
                 String btLastItemId = null;
                 //按人员获取
-                ganttData = projectMapper.getTaskPlanByMemb(userIds, startDate ,endDate, user.getCompanyId(),user.getId(),justWaitForMe);
+                ganttData = projectMapper.getTaskPlanByMemb(userIds, startDate ,endDate, user.getCompanyId(),user.getId());
                 System.out.println("renyuan==>"+ganttData.size());
-                if (user.getCompanyId()==Constant.MLD_COMPANY_ID){
-                    List<ProjectLeader> leaderList = projectLeaderService.list(new QueryWrapper<ProjectLeader>().eq("leader_id", user.getId()).eq("company_id", user.getCompanyId()));
-                    //是小组长
-                    if (!leaderList.isEmpty()){
-                        List<Integer> projectIdList = leaderList.stream().map(ProjectLeader::getProjectId).collect(Collectors.toList());
-                        projectIdList.add(-1);
-                        List<Participation> participations = participationMapper.selectList(new QueryWrapper<Participation>().in("project_id", projectIdList));
-                        List<String> userProjectIds = participations.stream().distinct().map(Participation::getUserId).collect(Collectors.toList());
-                        userProjectIds.add("-1");
-                        userIdsExtra.addAll(userProjectIds);
-                        List<Map> taskPlanByGeneralMemb = projectMapper.getTaskPlanByGeneralMemb(userProjectIds, startDate, endDate, user.getCompanyId(), user.getId(),targetUserId,justWaitForMe);
-                        for (Map map : taskPlanByGeneralMemb) {
-                            map.put("leaderOrManager",1);
-                        }
-                        List<Map> taskPlanWithLeave = projectMapper.getTaskPlanWithLeave(null, startDate, endDate, user.getCompanyId(), user.getId(), targetUserId);
-                        for (Map map : taskPlanWithLeave) {
-                            map.put("leaderOrManager",1);
-                        }
-                        ganttData.addAll(taskPlanByGeneralMemb);
-                        ganttData.addAll(taskPlanWithLeave);
-                        System.out.println("renyuan0==>"+taskPlanByGeneralMemb.size());
-                        System.out.println("renyuan1==>"+taskPlanWithLeave.size());
-                    }
-                    //找到自己担任项目经理的项目,: is_task_plan==1 ,checkFirstId=自己的id 并且 task_status=3
-                    List<Project> projectList = projectMapper.selectList(new QueryWrapper<Project>().eq("incharger_id", user.getId()));
-                    if (!projectList.isEmpty()){
-                        List<Integer> projectIdList = projectList.stream().map(Project::getId).collect(Collectors.toList());
-                        projectIdList.add(-1);
-                        List<TaskExecutor> executorList = taskExecutorService.list(new QueryWrapper<TaskExecutor>().in("project_id", projectIdList).isNotNull("executor_id"));
-                        List<String> collectUserIdList = executorList.stream().distinct().map(TaskExecutor::getExecutorId).collect(Collectors.toList());
-                        collectUserIdList.add("-1");
-                        userIdsExtra.addAll(collectUserIdList);
-                        List<Map> getTaskPlanByProManager = projectMapper.getTaskPlanByProManager(collectUserIdList, startDate, endDate, user.getCompanyId(),user.getId(),targetUserId,justWaitForMe);
-                        for (Map map : getTaskPlanByProManager) {
-                            map.put("leaderOrManager",2);
-                        }
-                        System.out.println("renyuan2==>"+getTaskPlanByProManager.size());
-                        ganttData.addAll(getTaskPlanByProManager);
-                    }
-
-                    if (user.getRoleName().equals("区域经理&PM")){
-                        List<Task> taskList = taskService.list(new QueryWrapper<Task>().eq("check_second_id", user.getId()));
-                        List<Integer> taskIdList = taskList.stream().map(Task::getId).collect(Collectors.toList());
-                        taskIdList.add(-1);
-                        List<TaskExecutor> executorList = taskExecutorService.list(new QueryWrapper<TaskExecutor>().in("task_id", taskIdList).isNotNull("executor_id"));
-                        List<String> collectUserIdList = executorList.stream().distinct().map(TaskExecutor::getExecutorId).collect(Collectors.toList());
-                        collectUserIdList.add("-1");
-                        userIdsExtra.addAll(collectUserIdList);
-                        List<Map> getTaskPlanByProManager = projectMapper.getTaskPlanByAreaManager(collectUserIdList, startDate, endDate, user.getCompanyId(),user.getId(),targetUserId,justWaitForMe);
-                        for (Map map : getTaskPlanByProManager) {
-                            map.put("leaderOrManager",2);
-                        }
-                        System.out.println("renyuan3==>"+getTaskPlanByProManager.size());
-                        ganttData.addAll(getTaskPlanByProManager);
-                    }
+                List<ProjectLeader> leaderList = projectLeaderService.list(new QueryWrapper<ProjectLeader>().eq("leader_id", user.getId()).eq("company_id", user.getCompanyId()));
+                //是小组长
+                if (!leaderList.isEmpty()){
+                    List<Integer> projectIdList = leaderList.stream().map(ProjectLeader::getProjectId).collect(Collectors.toList());
+                    projectIdList.add(-1);
+                    List<Participation> participations = participationMapper.selectList(new QueryWrapper<Participation>().in("project_id", projectIdList));
+                    List<String> userProjectIds = participations.stream().distinct().map(Participation::getUserId).collect(Collectors.toList());
+                    userProjectIds.add("-1");
+                    userIdsExtra.addAll(userProjectIds);
+                    List<Map> taskPlanByGeneralMemb = projectMapper.getTaskPlanByGeneralMemb(userProjectIds, startDate, endDate, user.getCompanyId(), user.getId(),targetUserId);
+                    for (Map map : taskPlanByGeneralMemb) {
+                        map.put("leaderOrManager",1);
+                    }
+                    List<Map> taskPlanWithLeave = projectMapper.getTaskPlanWithLeave(null, startDate, endDate, user.getCompanyId(), user.getId(), targetUserId);
+                    for (Map map : taskPlanWithLeave) {
+                        map.put("leaderOrManager",1);
+                    }
+                    ganttData.addAll(taskPlanByGeneralMemb);
+                    ganttData.addAll(taskPlanWithLeave);
+                    System.out.println("renyuan0==>"+taskPlanByGeneralMemb.size());
+                    System.out.println("renyuan1==>"+taskPlanWithLeave.size());
+                }
+                //找到自己担任项目经理的项目,: is_task_plan==1 ,checkFirstId=自己的id 并且 task_status=3
+                List<Project> projectList = projectMapper.selectList(new QueryWrapper<Project>().eq("incharger_id", user.getId()));
+                if (!projectList.isEmpty()){
+                    List<Integer> projectIdList = projectList.stream().map(Project::getId).collect(Collectors.toList());
+                    projectIdList.add(-1);
+                    List<TaskExecutor> executorList = taskExecutorService.list(new QueryWrapper<TaskExecutor>().in("project_id", projectIdList).isNotNull("executor_id"));
+                    List<String> collectUserIdList = executorList.stream().distinct().map(TaskExecutor::getExecutorId).collect(Collectors.toList());
+                    collectUserIdList.add("-1");
+                    userIdsExtra.addAll(collectUserIdList);
+                    List<Map> getTaskPlanByProManager = projectMapper.getTaskPlanByProManager(collectUserIdList, startDate, endDate, user.getCompanyId(),user.getId(),targetUserId);
+                    for (Map map : getTaskPlanByProManager) {
+                        map.put("leaderOrManager",2);
+                    }
+                    System.out.println("renyuan2==>"+getTaskPlanByProManager.size());
+                    ganttData.addAll(getTaskPlanByProManager);
+                }
+
+                if (user.getRoleName().equals("区域经理&PM")){
+                    List<Task> taskList = taskService.list(new QueryWrapper<Task>().eq("check_second_id", user.getId()));
+                    List<Integer> taskIdList = taskList.stream().map(Task::getId).collect(Collectors.toList());
+                    taskIdList.add(-1);
+                    List<TaskExecutor> executorList = taskExecutorService.list(new QueryWrapper<TaskExecutor>().in("task_id", taskIdList).isNotNull("executor_id"));
+                    List<String> collectUserIdList = executorList.stream().distinct().map(TaskExecutor::getExecutorId).collect(Collectors.toList());
+                    collectUserIdList.add("-1");
+                    userIdsExtra.addAll(collectUserIdList);
+                    List<Map> getTaskPlanByProManager = projectMapper.getTaskPlanByAreaManager(collectUserIdList, startDate, endDate, user.getCompanyId(),user.getId(),targetUserId);
+                    for (Map map : getTaskPlanByProManager) {
+                        map.put("leaderOrManager",2);
+                    }
+                    System.out.println("renyuan3==>"+getTaskPlanByProManager.size());
+                    ganttData.addAll(getTaskPlanByProManager);
                 }
                 QueryWrapper<LeaveSheet> lsQueryWrapper=new QueryWrapper();
                 lsQueryWrapper.in("owner_id", userIds);
@@ -5111,39 +5087,37 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                         }
                     }
                 }
-                ganttData = projectMapper.getTaskPlanByProject(projectIds, startDate ,endDate, user.getCompanyId(),groupName,taskType,user.getId(),justWaitForMe);
+                ganttData = projectMapper.getTaskPlanByProject(projectIds, startDate ,endDate, user.getCompanyId(),groupName,taskType,user.getId());
                 System.out.println("ganttData1:"+ganttData.size());
-                if (user.getCompanyId()==Constant.MLD_COMPANY_ID){
-                    List<ProjectLeader> leaderList = projectLeaderService.list(new QueryWrapper<ProjectLeader>().eq("leader_id", user.getId()).eq("company_id", user.getCompanyId()));
-                    //是小组长
-                    if (!leaderList.isEmpty()){
-                        List<Integer> projectIdList = leaderList.stream().map(ProjectLeader::getProjectId).collect(Collectors.toList());
-                        projectIdList.add(-1);
-                        List<Map> taskPlanByGeneralMemb = projectMapper.getTaskPlanByProjectGeneralMemb(projectIdList,startDate ,endDate, user.getCompanyId(),user.getId(),groupName,taskType,targetProjectId,justWaitForMe);
-                        System.out.println("ganttData2:"+taskPlanByGeneralMemb.size());
-                        ganttData.addAll(taskPlanByGeneralMemb);
-                    }
-                    //找到自己担任项目经理的项目,: is_task_plan==1 ,checkFirstId=自己的id 并且 task_status=3
-                    List<Project> projectList = projectMapper.selectList(new QueryWrapper<Project>().eq("incharger_id", user.getId()));
-                    if (!projectList.isEmpty()){
-                        List<Integer> projectIdList = projectList.stream().map(Project::getId).collect(Collectors.toList());
-                        projectIdList.add(-1);
-                        List<Map> taskPlanByProjectManager = projectMapper.getTaskPlanByProjectManager(projectIdList,startDate ,endDate, user.getCompanyId(),user.getId(),groupName,taskType,targetProjectId,justWaitForMe);
-                        System.out.println("ganttData2:"+taskPlanByProjectManager.size());
-                        ganttData.addAll(taskPlanByProjectManager);
-                    }
-
-                    if (user.getRoleName().equals("区域经理&PM")){
-                        List<Task> taskList = taskService.list(new QueryWrapper<Task>().eq("check_second_id", user.getId()));
-                        List<Integer> taskIdList = taskList.stream().map(Task::getId).collect(Collectors.toList());
-                        taskIdList.add(-1);
-                        List<TaskExecutor> executorList = taskExecutorService.list(new QueryWrapper<TaskExecutor>().in("task_id", taskIdList).isNotNull("executor_id"));
-                        List<Integer> projectIdList = executorList.stream().distinct().map(TaskExecutor::getProjectId).collect(Collectors.toList());
-                        projectIdList.add(-1);
-                        List<Map> taskPlanByProjectAreaManager = projectMapper.getTaskPlanByProjectAreaManager(projectIdList, startDate, endDate, user.getCompanyId(),user.getId(),groupName,taskType,targetProjectId,justWaitForMe);
-                        System.out.println("ganttData2:"+taskPlanByProjectAreaManager.size());
-                        ganttData.addAll(taskPlanByProjectAreaManager);
-                    }
+                List<ProjectLeader> leaderList = projectLeaderService.list(new QueryWrapper<ProjectLeader>().eq("leader_id", user.getId()).eq("company_id", user.getCompanyId()));
+                //是小组长
+                if (!leaderList.isEmpty()){
+                    List<Integer> projectIdList = leaderList.stream().map(ProjectLeader::getProjectId).collect(Collectors.toList());
+                    projectIdList.add(-1);
+                    List<Map> taskPlanByGeneralMemb = projectMapper.getTaskPlanByProjectGeneralMemb(projectIdList,startDate ,endDate, user.getCompanyId(),user.getId(),groupName,taskType,targetProjectId);
+                    System.out.println("ganttData2:"+taskPlanByGeneralMemb.size());
+                    ganttData.addAll(taskPlanByGeneralMemb);
+                }
+                //找到自己担任项目经理的项目,: is_task_plan==1 ,checkFirstId=自己的id 并且 task_status=3
+                List<Project> projectList = projectMapper.selectList(new QueryWrapper<Project>().eq("incharger_id", user.getId()));
+                if (!projectList.isEmpty()){
+                    List<Integer> projectIdList = projectList.stream().map(Project::getId).collect(Collectors.toList());
+                    projectIdList.add(-1);
+                    List<Map> taskPlanByProjectManager = projectMapper.getTaskPlanByProjectManager(projectIdList,startDate ,endDate, user.getCompanyId(),user.getId(),groupName,taskType,targetProjectId);
+                    System.out.println("ganttData2:"+taskPlanByProjectManager.size());
+                    ganttData.addAll(taskPlanByProjectManager);
+                }
+
+                if (user.getRoleName().equals("区域经理&PM")){
+                    List<Task> taskList = taskService.list(new QueryWrapper<Task>().eq("check_second_id", user.getId()));
+                    List<Integer> taskIdList = taskList.stream().map(Task::getId).collect(Collectors.toList());
+                    taskIdList.add(-1);
+                    List<TaskExecutor> executorList = taskExecutorService.list(new QueryWrapper<TaskExecutor>().in("task_id", taskIdList).isNotNull("executor_id"));
+                    List<Integer> projectIdList = executorList.stream().distinct().map(TaskExecutor::getProjectId).collect(Collectors.toList());
+                    projectIdList.add(-1);
+                    List<Map> taskPlanByProjectAreaManager = projectMapper.getTaskPlanByProjectAreaManager(projectIdList, startDate, endDate, user.getCompanyId(),user.getId(),groupName,taskType,targetProjectId);
+                    System.out.println("ganttData2:"+taskPlanByProjectAreaManager.size());
+                    ganttData.addAll(taskPlanByProjectAreaManager);
                 }
                 QueryWrapper<BusinessTrip> btQueryWrapper =new QueryWrapper<>();
                 QueryWrapper<BustripProject> bpQueryWrapper =new QueryWrapper<>();
@@ -5163,13 +5137,13 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                     }
                 }
                 List<BustripProject> bustripProjectList = bustripProjectMapper.selectList(bpQueryWrapper);
-                List<Project> projectList = projectMapper.selectList(new QueryWrapper<Project>().eq("company_id", user.getCompanyId()));
+                List<Project> allProjectList = projectMapper.selectList(new QueryWrapper<Project>().eq("company_id", user.getCompanyId()));
                 for(BusinessTrip businessTrip:businessTripList){
                     List<BustripProject> collect = bustripProjectList.stream().filter(bp -> bp.getBustripId().equals(businessTrip.getId())).collect(Collectors.toList());
                     for(BustripProject bustripProject:collect){
                         GanttDataItem curItem = new GanttDataItem();
                         if(bustripProject.getProjectId()!=null) {
-                            Project project = projectList.stream().filter(pro -> pro.getId().equals(bustripProject.getProjectId())).collect(Collectors.toList()).get(0);
+                            Project project = allProjectList.stream().filter(pro -> pro.getId().equals(bustripProject.getProjectId())).collect(Collectors.toList()).get(0);
                             if (!bustripProject.getProjectId().equals(btLastItemId)) {
                                 //抽取父级对象,项目名称
                                 GanttDataItem parent = new GanttDataItem();
@@ -8815,10 +8789,8 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
             List<String> userIds = new ArrayList<>();
 
             List<Integer> proIds = projectList.stream().map(Project::getId).collect(Collectors.toList());
-            if (Constant.MLD_COMPANY_ID==user.getCompanyId()){
-                List<Integer> projectSelect =projectMapper.getRelatedProjectIds(user.getId(), user.getCompanyId());
-                proIds.addAll(projectSelect);
-            }
+            List<Integer> projectSelect =projectMapper.getRelatedProjectIds(user.getId(), user.getCompanyId());
+            proIds.addAll(projectSelect);
 
             proIds.add(-1);
             List<Participation> pList = participationMapper.selectList(new QueryWrapper<Participation>().in("project_id", proIds));
@@ -12801,7 +12773,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                 String lsLastItemId = null;
                 String btLastItemId = null;
                 //按人员获取
-                ganttData = projectMapper.getTaskPlanByMemb(userIds, startDate ,endDate, user.getCompanyId(),user.getId(),null);
+                ganttData = projectMapper.getTaskPlanByMemb(userIds, startDate ,endDate, user.getCompanyId(),user.getId());
                 QueryWrapper<LeaveSheet> lsQueryWrapper=new QueryWrapper();
                 lsQueryWrapper.in("owner_id", userIds);
                 if (startDate != null && endDate != null) {
@@ -12987,7 +12959,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                         }
                     }
                 }
-                ganttData = projectMapper.getTaskPlanByProject(projectIds, startDate ,endDate, user.getCompanyId(),null,null,user.getId(),null);
+                ganttData = projectMapper.getTaskPlanByProject(projectIds, startDate ,endDate, user.getCompanyId(),null,null,user.getId());
                 QueryWrapper<BusinessTrip> btQueryWrapper =new QueryWrapper<>();
                 QueryWrapper<BustripProject> bpQueryWrapper =new QueryWrapper<>();
                 btQueryWrapper.in("owner_id", userIds);

+ 4 - 4
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/service/impl/SysRoleServiceImpl.java

@@ -29,12 +29,12 @@ import java.util.stream.Collectors;
 @Transactional
 public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {
 
-    public static String[] employeeModules =  {"工时报告","项目报告审核", "专业审核","部门审核","费用报销","待办任务", "项目管理", "请假管理", "导入日报审核"};
-    public static String[] pmModules =  {"工时报告","项目报告审核", "专业审核","部门审核","费用报销","待办任务", "项目管理", "请假管理", "导入日报审核"};
+    public static String[] employeeModules =  {"工时报告","项目报告审核", "专业审核","部门审核","费用报销","工作计划", "项目管理", "请假管理", "导入日报审核"};
+    public static String[] pmModules =  {"工时报告","项目报告审核", "专业审核","部门审核","费用报销","工作计划", "项目管理", "请假管理", "导入日报审核"};
     public static String[] financeModules =  {"工时成本统计", "财务核算成本", "费用报销", "组织架构", "请假管理"};
-    public static String[] pmoModules =  {"工时报告","项目报告审核","查看全部任务", "费用报销", "待办任务", "项目管理", "客户管理", "工程专业管理","请假管理"};
+    public static String[] pmoModules =  {"工时报告","项目报告审核","查看全部任务", "费用报销", "工作计划", "项目管理", "客户管理", "工程专业管理","请假管理"};
     public static String[] corpLeaderModules =  {"工时报告","查看全部任务","工时成本统计","自定义数值统计","财务核算成本","项目报表服务",
-            "费用报销","待办任务","项目管理","请假管理","查看全部报销单", "查看全部请假单"};
+            "费用报销","工作计划","项目管理","请假管理","查看全部报销单", "查看全部请假单"};
 
     public static final HashMap<String, String[]> moduleMaps = new HashMap();
     static {

+ 84 - 84
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/service/impl/TaskServiceImpl.java

@@ -1062,90 +1062,90 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
         String userId = request.getHeader("Token");
         User user = userMapper.selectById(userId);
 
-        Task task = taskMapper.selectById(taskId);
-        if (!userId.equals(task.getCheckFirstId())&&!userId.equals(task.getCheckSecondId())){
-            msg.setError("当前人员不是审核人,不能审核");
-            return msg;
-        }
-        //通过
-        if (type){
-            //第一审核人通过
-            if (task.getIsTaskPlan()==1&&task.getTaskStatus()==3
-                    && StringUtils.isNotEmpty(task.getCheckFirstId())
-                    &&userId.equals(task.getCheckFirstId())){
-                task.setTaskStatus(4);
-                taskMapper.updateById(task);
-                //给第二审核人发送信息提醒
-                User owner = userMapper.selectById(task.getCheckSecondId());
-                Information information = new Information();
-                Project project = projectMapper.selectById(task.getProjectId());
-                information.setMsg(project.getProjectName()+"项目有新的预计FTE计划审批任务,请您查收.");
-                information.setTaskId(task.getId());
-                information.setUserId(owner.getId());
-                information.setType(11);
-                information.setTime(LocalDateTime.now());
-                informationMapper.insert(information);
-            }
-            //第二审核人通过
-            else if (task.getIsTaskPlan() == 1 && task.getTaskStatus() == 4
-                    && StringUtils.isNotEmpty(task.getCheckSecondId())
-                    && userId.equals(task.getCheckSecondId())) {
-
-                task.setTaskStatus(0);
-                task.setIsTaskPlan(0);
-                taskMapper.updateById(task);
-
-                List<TaskExecutor> taskExecutorList = taskExecutorMapper.selectList(new QueryWrapper<TaskExecutor>().eq("task_id", taskId));
-                if(CollectionUtils.isNotEmpty(taskExecutorList)){
-                    for (TaskExecutor taskExecutor : taskExecutorList) {
-                        //给任务的执行人发送信息提醒
-                        User owner = userMapper.selectById(taskExecutor.getExecutorId());
-                        Information information = new Information();
-                        information.setMsg("您有新的任务");
-                        information.setContent(taskExecutor.getProjectId()==null?null:(""+taskExecutor.getProjectId()));
-                        information.setType(1);
-                        information.setUserId(owner.getId());
-                        information.setTime(LocalDateTime.now());
-                        informationMapper.insert(information);
-                    }
-                }
-            }
-        }
-        //驳回
-        else {
-            //第一审核人驳回
-            if (task.getIsTaskPlan()==1&&task.getTaskStatus()==3
-                    && StringUtils.isNotEmpty(task.getCheckFirstId())
-                    &&userId.equals(task.getCheckFirstId())){
-                task.setTaskStatus(5);
-                taskMapper.updateById(task);
-                //给小组长发送信息提醒
-                User owner = userMapper.selectById(task.getCreaterId());
-                Information information = new Information();
-                information.setMsg("您有工作计划被驳回");
-                information.setType(11);
-                information.setUserId(owner.getId());
-                information.setTime(LocalDateTime.now());
-                informationMapper.insert(information);
-            }
-            //第二审核人驳回
-            else if (task.getIsTaskPlan() == 1 && task.getTaskStatus() == 4
-                    && StringUtils.isNotEmpty(task.getCheckSecondId())
-                    && userId.equals(task.getCheckSecondId())) {
-
-                task.setTaskStatus(6);
-                taskMapper.updateById(task);
-
-                //给小组长发送信息提醒
-                User owner = userMapper.selectById(task.getCreaterId());
-                Information information = new Information();
-                information.setMsg("您有工作计划被驳回");
-                information.setType(11);
-                information.setUserId(owner.getId());
-                information.setTime(LocalDateTime.now());
-                informationMapper.insert(information);
-            }
-        }
+//        Task task = taskMapper.selectById(taskId);
+//        if (!userId.equals(task.getCheckFirstId())&&!userId.equals(task.getCheckSecondId())){
+//            msg.setError("当前人员不是审核人,不能审核");
+//            return msg;
+//        }
+//        //通过
+//        if (type){
+//            //第一审核人通过
+//            if (task.getIsTaskPlan()==1&&task.getTaskStatus()==3
+//                    && StringUtils.isNotEmpty(task.getCheckFirstId())
+//                    &&userId.equals(task.getCheckFirstId())){
+//                task.setTaskStatus(4);
+//                taskMapper.updateById(task);
+//                //给第二审核人发送信息提醒
+//                User owner = userMapper.selectById(task.getCheckSecondId());
+//                Information information = new Information();
+//                Project project = projectMapper.selectById(task.getProjectId());
+//                information.setMsg(project.getProjectName()+"项目有新的预计FTE计划审批任务,请您查收.");
+//                information.setTaskId(task.getId());
+//                information.setUserId(owner.getId());
+//                information.setType(11);
+//                information.setTime(LocalDateTime.now());
+//                informationMapper.insert(information);
+//            }
+//            //第二审核人通过
+//            else if (task.getIsTaskPlan() == 1 && task.getTaskStatus() == 4
+//                    && StringUtils.isNotEmpty(task.getCheckSecondId())
+//                    && userId.equals(task.getCheckSecondId())) {
+//
+//                task.setTaskStatus(0);
+//                task.setIsTaskPlan(0);
+//                taskMapper.updateById(task);
+//
+//                List<TaskExecutor> taskExecutorList = taskExecutorMapper.selectList(new QueryWrapper<TaskExecutor>().eq("task_id", taskId));
+//                if(CollectionUtils.isNotEmpty(taskExecutorList)){
+//                    for (TaskExecutor taskExecutor : taskExecutorList) {
+//                        //给任务的执行人发送信息提醒
+//                        User owner = userMapper.selectById(taskExecutor.getExecutorId());
+//                        Information information = new Information();
+//                        information.setMsg("您有新的任务");
+//                        information.setContent(taskExecutor.getProjectId()==null?null:(""+taskExecutor.getProjectId()));
+//                        information.setType(1);
+//                        information.setUserId(owner.getId());
+//                        information.setTime(LocalDateTime.now());
+//                        informationMapper.insert(information);
+//                    }
+//                }
+//            }
+//        }
+//        //驳回
+//        else {
+//            //第一审核人驳回
+//            if (task.getIsTaskPlan()==1&&task.getTaskStatus()==3
+//                    && StringUtils.isNotEmpty(task.getCheckFirstId())
+//                    &&userId.equals(task.getCheckFirstId())){
+//                task.setTaskStatus(5);
+//                taskMapper.updateById(task);
+//                //给小组长发送信息提醒
+//                User owner = userMapper.selectById(task.getCreaterId());
+//                Information information = new Information();
+//                information.setMsg("您有工作计划被驳回");
+//                information.setType(11);
+//                information.setUserId(owner.getId());
+//                information.setTime(LocalDateTime.now());
+//                informationMapper.insert(information);
+//            }
+//            //第二审核人驳回
+//            else if (task.getIsTaskPlan() == 1 && task.getTaskStatus() == 4
+//                    && StringUtils.isNotEmpty(task.getCheckSecondId())
+//                    && userId.equals(task.getCheckSecondId())) {
+//
+//                task.setTaskStatus(6);
+//                taskMapper.updateById(task);
+//
+//                //给小组长发送信息提醒
+//                User owner = userMapper.selectById(task.getCreaterId());
+//                Information information = new Information();
+//                information.setMsg("您有工作计划被驳回");
+//                information.setType(11);
+//                information.setUserId(owner.getId());
+//                information.setTime(LocalDateTime.now());
+//                informationMapper.insert(information);
+//            }
+//        }
         return msg;
     }
 

ファイルの差分が大きいため隠しています
+ 0 - 1088
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/service/impl/TaskServiceImpl.java~


+ 20 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/service/impl/TaskTypeServiceImpl.java

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.TaskType;
+import com.management.platform.mapper.TaskTypeMapper;
+import com.management.platform.service.TaskTypeService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-05-12
+ */
+@Service
+public class TaskTypeServiceImpl extends ServiceImpl<TaskTypeMapper, TaskType> implements TaskTypeService {
+
+}

+ 24 - 57
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/service/impl/UserServiceImpl.java

@@ -295,12 +295,8 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
                         LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
                 //检测是否是项目审核人,有没有权限进行审核
                 userVO.setLeader(judgeIsLeader(userVO.getId()));
-
-                if(company.getId()==Constant.MLD_COMPANY_ID) {
-                    //检测项目角色
-                    userVO.setProjectLeaderType(judgeIsProjectLeader(userVO.getId(),company.getId()));
-                }
-
+                //检测项目角色
+                userVO.setProjectLeaderType(judgeIsProjectLeader(userVO.getId(),company.getId()));
                 userVO.setTimeType(timeTypeMapper.selectById(company.getId()));
                 List<Department> manageDeptList = departmentMapper.selectList(new QueryWrapper<Department>().eq("manager_id", userVO.getId()));
                 List<Integer> deptIds = manageDeptList.stream().map(Department::getDepartmentId).collect(Collectors.toList());
@@ -769,24 +765,9 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
 
     private int judgeIsProjectLeader(String userId,Integer companyId) {
         int LeaderCount = projectLeaderService.count(new QueryWrapper<ProjectLeader>().eq("leader_id", userId).eq("company_id", companyId));
-        int firstCheckCount = taskMapper.selectCount(
-                new QueryWrapper<Task>()
-                        .eq("company_id", companyId)
-                        .and(wrapper ->
-                                wrapper.eq("check_first_id", userId)
-                                        .or()
-                                        .eq("check_second_id", userId)
-                        )
-        );
-
-        if (LeaderCount>0&&firstCheckCount>0){
-            return 3;
-        }else if(LeaderCount > 0){
+        if(LeaderCount > 0){
             return 1;
-        } else if (firstCheckCount > 0) {
-            return 2;
-        }else return 0;
-
+        } else return 0;
     }
 
     //获取用户信息
@@ -2507,10 +2488,8 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
         //获取当前角色的权限菜单
         setUserRoleMenu(userVO);
 
-        if(company.getId()==Constant.MLD_COMPANY_ID) {
-            //检测项目角色
-            userVO.setProjectLeaderType(judgeIsProjectLeader(userVO.getId(),company.getId()));
-        }
+        //检测项目角色
+        userVO.setProjectLeaderType(judgeIsProjectLeader(userVO.getId(),company.getId()));
         httpRespMsg.data = userVO;
         return httpRespMsg;
     }
@@ -2808,23 +2787,17 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
         HttpRespMsg msg = new HttpRespMsg();
         String token = request.getHeader("TOKEN");
         User user = userMapper.selectById(token);
-        if (user.getCompanyId() != Constant.MLD_COMPANY_ID) {
-            msg.setData(new ArrayList<User>());
-            return msg;
+        List<SysRole> sysRoles = sysRoleMapper.selectList(new QueryWrapper<SysRole>().eq("company_id", user.getCompanyId()).eq("rolename", "项目经理"));
+        if (!sysRoles.isEmpty()) {
+            List<User> userList = userMapper.selectList(new QueryWrapper<User>()
+                    .eq("company_id", user.getCompanyId())
+                    .eq("is_active", 1)
+                    .eq("role_id", sysRoles.get(0).getId()));
+            msg.setData(userList);
         } else {
-
-            List<SysRole> sysRoles = sysRoleMapper.selectList(new QueryWrapper<SysRole>().eq("company_id", user.getCompanyId()).eq("rolename", "项目经理"));
-            if (!sysRoles.isEmpty()) {
-                List<User> userList = userMapper.selectList(new QueryWrapper<User>()
-                        .eq("company_id", user.getCompanyId())
-                        .eq("is_active", 1)
-                        .eq("role_id", sysRoles.get(0).getId()));
-                msg.setData(userList);
-            } else {
-                msg.setData(new ArrayList<User>());
-            }
-            return msg;
+            msg.setData(new ArrayList<User>());
         }
+        return msg;
     }
 
     @Override
@@ -2832,23 +2805,17 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
         HttpRespMsg msg = new HttpRespMsg();
         String token = request.getHeader("TOKEN");
         User user = userMapper.selectById(token);
-        if (user.getCompanyId() != Constant.MLD_COMPANY_ID) {
-            msg.setData(new ArrayList<User>());
-            return msg;
+        List<SysRole> sysRoles = sysRoleMapper.selectList(new QueryWrapper<SysRole>().eq("company_id", user.getCompanyId()).eq("rolename", "区域经理&PM"));
+        if (!sysRoles.isEmpty()) {
+            List<User> userList = userMapper.selectList(new QueryWrapper<User>()
+                    .eq("company_id", user.getCompanyId())
+                    .eq("is_active", 1)
+                    .eq("role_id", sysRoles.get(0).getId()));
+            msg.setData(userList);
         } else {
-
-            List<SysRole> sysRoles = sysRoleMapper.selectList(new QueryWrapper<SysRole>().eq("company_id", user.getCompanyId()).eq("rolename", "区域经理&PM"));
-            if (!sysRoles.isEmpty()) {
-                List<User> userList = userMapper.selectList(new QueryWrapper<User>()
-                        .eq("company_id", user.getCompanyId())
-                        .eq("is_active", 1)
-                        .eq("role_id", sysRoles.get(0).getId()));
-                msg.setData(userList);
-            } else {
-                msg.setData(new ArrayList<User>());
-            }
-            return msg;
+            msg.setData(new ArrayList<User>());
         }
+        return msg;
     }
 
     @Override

+ 1 - 1
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/util/CodeGenerator.java

@@ -92,7 +92,7 @@ public class CodeGenerator {
 
         // 数据源配置
         DataSourceConfig dsc = new DataSourceConfig();
-        dsc.setUrl("jdbc:mysql://1.94.62.58:17089/man_dev?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8");
+        dsc.setUrl("jdbc:mysql://1.94.62.58:17089/man_mld?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8");
 //        dsc.setSchemaName("public");
         dsc.setDriverName("com.mysql.cj.jdbc.Driver");
         dsc.setUsername("root");

+ 1 - 4
fhKeeper/formulahousekeeper/management-platform-mld/src/main/resources/application.yml

@@ -15,12 +15,9 @@ spring:
       location: C:/upload/
   datasource:
     driver-class-name: com.mysql.cj.jdbc.Driver
-    url: jdbc:mysql://1.94.62.58:17089/man_dev?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&useSSL=false
+    url: jdbc:mysql://1.94.62.58:17089/man_mld?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&useSSL=false
     username: root
     password: P011430@Huoshi*
-#    url: jdbc:mysql://47.100.37.243:7644/man_hour_manager?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&rewriteBatchedStatements=true
-#    username: root
-#    password: Ziyu20141026!@@
     hikari:
       maximum-pool-size: 60
       minimum-idle: 10

+ 16 - 62
fhKeeper/formulahousekeeper/management-platform-mld/src/main/resources/mapper/ProjectMapper.xml

@@ -743,7 +743,7 @@
     <select id="getTaskPlanByMemb" resultType="java.util.Map">
         SELECT user.`id` as user_id, user.`name`,project.id, project.`project_name`,task.id as task_id, task.name as task_name,task_executor.id as exe_id,
         IFNULL(task.`start_date`, task.end_date) as start_date, task.`end_date`, task_executor.plan_hours as duration, task.task_level as level ,
-        task.task_plan_type as taskPlanType,task.is_task_plan as isTaskPlan,task.check_first_id as checkFirstId,task.check_second_id as checkSecondId,
+        task.task_plan_type as taskPlanType,task.is_task_plan as isTaskPlan,
         task.task_status as taskStatus,task.id as taskId,task.task_plan taskPlan
         FROM user
         LEFT JOIN task_executor ON user.id = task_executor.`executor_id`
@@ -753,9 +753,6 @@
         <foreach collection="userIds" close=")" open="(" separator="," index="" item="item">
             #{item}
         </foreach>
-        <if test="justWaitForMe !=null  ">
-            and (task.check_first_id=#{creatorId} or task.check_second_id=#{creatorId})  and (task.task_status=3 or task.task_status=4)
-        </if>
         and ((IFNULL(task.start_date , task.end_date) between #{startDate} and #{endDate}) or (task.end_date between #{startDate} and #{endDate}))
         and task.end_date is not null and task.is_task_plan =0
         AND project.`status` = 1
@@ -764,8 +761,7 @@
 
     <select id="getTaskPlanByProject" resultType="java.util.Map">
         SELECT task.executor_id as user_id, task.executor_name as `name`,project.id, project.`project_name`,task.id as task_id, task.name as task_name,
-        task.task_plan_type as taskPlanType,task.is_task_plan as isTaskPlan,task.check_first_id as checkFirstId,task.check_second_id as checkSecondId
-        ,task.task_status as taskStatus,task.id as taskId,task.task_plan taskPlan,
+        task.task_plan_type as taskPlanType,task.is_task_plan as isTaskPlan,task.task_status as taskStatus,task.id as taskId,task.task_plan taskPlan,
         IFNULL(task.`start_date`, task.end_date) as start_date, task.`end_date`, task.plan_hours as duration FROM project
         LEFT JOIN task ON task.project_id = project.id
         <if test="groupName !=null and groupName !='' ">
@@ -784,35 +780,12 @@
         <if test="taskType !=null  ">
             and task.task_type = #{taskType}
         </if>
-        <if test="justWaitForMe !=null  ">
-            and (task.check_first_id=#{creatorId} or task.check_second_id=#{creatorId})  and (task.task_status=3 or task.task_status=4)
-        </if>
         and ((IFNULL(task.start_date , task.end_date) between #{startDate} and #{endDate}) or (task.end_date between #{startDate} and #{endDate}))
         and task.end_date is not null and task.task_plan =0
         AND project.`status` = 1
         ORDER BY project.id, task.start_date
     </select>
 
-    <!--获取加班统计报表 -->
-    <!--    <select id="getOvertimeList" resultType="java.util.Map">-->
-    <!--        SELECT report.`creator_id` AS userId, user.`name` AS username, SUM(report.`working_time`) AS workingTime,-->
-    <!--        IFNULL(SUM(report.`overtime_hours`),0) AS overtimeHours,-->
-    <!--        group_concat(distinct(project.project_code)) as projectCode,-->
-    <!--        IFNULL(SUM(report.overtime_cost), 0) AS cost FROM report LEFT JOIN user ON user.id = report.`creator_id`-->
-    <!--        left join project on project.id = report.project_id-->
-    <!--        WHERE report.is_overtime = 1-->
-    <!--        and report.`state` = 1-->
-    <!--        AND report.`create_date` BETWEEN #{startDate} and #{endDate}-->
-    <!--        AND user.`company_id` = #{companyId}-->
-    <!--        <if test="projectId != null">-->
-    <!--            AND report.`project_id` = #{projectId}-->
-    <!--        </if>-->
-    <!--        <if test="userId != null">-->
-    <!--            AND report.`creator_id` = #{userId}-->
-    <!--        </if>-->
-    <!--        GROUP BY report.creator_id-->
-    <!--    </select>-->
-
     <!-- 获取某个员工的某时间段内的加班详情 -->
     <select id="getOvertimeDetail" resultType="java.util.Map">
         SELECT report.id AS reportId,date_format(report.`create_date`, '%Y-%m-%d') AS createDate,
@@ -2736,7 +2709,7 @@
     <select id="getTaskPlanByGeneralMemb" resultType="java.util.Map">
         SELECT user.`id` as user_id, user.`name`,project.id, project.`project_name`,task.id as task_id, task.name as task_name,task_executor.id as exe_id,
         IFNULL(task.`start_date`, task.end_date) as start_date, task.`end_date`, task_executor.plan_hours as duration, task.task_level as level ,
-        task.task_plan_type as taskPlanType,task.is_task_plan as isTaskPlan,task.check_first_id as checkFirstId,task.check_second_id as checkSecondId,
+        task.task_plan_type as taskPlanType,task.is_task_plan as isTaskPlan,
         task.task_status as taskStatus,task.id as taskId,task.task_plan taskPlan
         FROM user
         LEFT JOIN task_executor ON user.id = task_executor.`executor_id`
@@ -2751,16 +2724,13 @@
         <if test="targetUserId !=null and targetUserId !='' ">
             and user.`id`=#{targetUserId}
         </if>
-        <if test="justWaitForMe !=null  ">
-            and (task.check_first_id=#{creatorId} or task.check_second_id=#{creatorId})  and (task.task_status=3 or task.task_status=4)
-        </if>
         AND project.`status` = 1 and task.task_plan=1
         ORDER BY user.id, task.start_date
     </select>
     <select id="getTaskPlanWithLeave" resultType="java.util.Map">
         SELECT user.`id` as user_id, user.`name`,task.id as task_id, task.name as task_name,task_executor.id as exe_id,
         IFNULL(task.`start_date`, task.end_date) as start_date, task.`end_date`, task_executor.plan_hours as duration, task.task_level as level ,
-        task.task_plan_type as taskPlanType,task.is_task_plan as isTaskPlan,task.check_first_id as checkFirstId,task.check_second_id as checkSecondId,
+        task.task_plan_type as taskPlanType,task.is_task_plan as isTaskPlan,
         task.task_status as taskStatus,task.id as taskId,task.task_plan taskPlan
         FROM user
         LEFT JOIN task_executor ON user.id = task_executor.`executor_id`
@@ -2776,7 +2746,7 @@
     <select id="getTaskPlanByProManager" resultType="java.util.Map">
         SELECT user.`id` as user_id, user.`name`,project.id, project.`project_name`,task.id as task_id, task.name as task_name,task_executor.id as exe_id,
         IFNULL(task.`start_date`, task.end_date) as start_date, task.`end_date`, task_executor.plan_hours as duration, task.task_level as level ,
-        task.task_plan_type as taskPlanType,task.is_task_plan as isTaskPlan,task.check_first_id as checkFirstId,task.check_second_id as checkSecondId,
+        task.task_plan_type as taskPlanType,task.is_task_plan as isTaskPlan,
         task.task_status as taskStatus,task.id as taskId,task.task_plan taskPlan
         FROM user
         LEFT JOIN task_executor ON user.id = task_executor.`executor_id`
@@ -2787,20 +2757,17 @@
             #{item}
         </foreach>
         and ((IFNULL(task.start_date , task.end_date) between #{startDate} and #{endDate}) or (task.end_date between #{startDate} and #{endDate}))
-        and task.end_date is not null and task.is_task_plan=1  and task.check_first_id=#{managerId}
+        and task.end_date is not null and task.is_task_plan=1  and project.incharger_id=#{managerId}
         AND project.`status` = 1 and task.task_plan=1 and task.task_status !=2
         <if test="targetUserId !=null and targetUserId !='' ">
             and user.`id`=#{targetUserId}
         </if>
-        <if test="justWaitForMe !=null">
-            and task.task_status=3
-        </if>
         ORDER BY user.id, task.start_date
     </select>
     <select id="getTaskPlanByAreaManager" resultType="java.util.Map">
         SELECT user.`id` as user_id, user.`name`,project.id, project.`project_name`,task.id as task_id, task.name as task_name,task_executor.id as exe_id,
         IFNULL(task.`start_date`, task.end_date) as start_date, task.`end_date`, task_executor.plan_hours as duration, task.task_level as level ,
-        task.task_plan_type as taskPlanType,task.is_task_plan as isTaskPlan,task.check_first_id as checkFirstId,task.check_second_id as checkSecondId,
+        task.task_plan_type as taskPlanType,task.is_task_plan as isTaskPlan,
         task.task_status as taskStatus,task.id as taskId,task.task_plan taskPlan
         FROM user
         LEFT JOIN task_executor ON user.id = task_executor.`executor_id`
@@ -2816,15 +2783,12 @@
         <if test="targetUserId !=null and targetUserId !='' ">
             and user.`id`=#{targetUserId}
         </if>
-        <if test="justWaitForMe !=null">
-            and task.task_status=4
-        </if>
         ORDER BY user.id, task.start_date
     </select>
     <select id="getTaskPlanByProjectGeneralMemb" resultType="java.util.Map">
         SELECT task.executor_id as user_id, task.executor_name as `name`,project.id, project.`project_name`,task.id as task_id, task.name as task_name,
-        task.task_plan_type as taskPlanType,task.is_task_plan as isTaskPlan,task.check_first_id as checkFirstId,task.check_second_id as checkSecondId
-        ,task.task_status as taskStatus,task.id as taskId,task.task_plan taskPlan,
+        task.task_plan_type as taskPlanType,task.is_task_plan as isTaskPlan,
+        task.task_status as taskStatus,task.id as taskId,task.task_plan taskPlan,
         IFNULL(task.`start_date`, task.end_date) as start_date, task.`end_date`, task.plan_hours as duration FROM project
         LEFT JOIN task ON task.project_id = project.id
         <if test="groupName !=null and groupName !='' ">
@@ -2846,9 +2810,6 @@
         <if test="targetProjectId !=null  ">
             and project.`id` = #{targetProjectId}
         </if>
-        <if test="justWaitForMe !=null">
-            and (task.check_first_id=#{creatorId} or task.check_second_id=#{creatorId}) and (task.task_status=3 or task.task_status=4)
-        </if>
         and ((IFNULL(task.start_date , task.end_date) between #{startDate} and #{endDate}) or (task.end_date between #{startDate} and #{endDate}))
         and task.end_date is not null
         AND project.`status` = 1
@@ -2856,8 +2817,8 @@
     </select>
     <select id="getTaskPlanByProjectManager" resultType="java.util.Map">
         SELECT task.executor_id as user_id, task.executor_name as `name`,project.id, project.`project_name`,task.id as task_id, task.name as task_name,
-        task.task_plan_type as taskPlanType,task.is_task_plan as isTaskPlan,task.check_first_id as checkFirstId,task.check_second_id as checkSecondId
-        ,task.task_status as taskStatus,task.id as taskId,task.task_plan taskPlan,
+        task.task_plan_type as taskPlanType,task.is_task_plan as isTaskPlan,
+        task.task_status as taskStatus,task.id as taskId,task.task_plan taskPlan,
         IFNULL(task.`start_date`, task.end_date) as start_date, task.`end_date`, task.plan_hours as duration FROM project
         LEFT JOIN task ON task.project_id = project.id
         <if test="groupName !=null and groupName !='' ">
@@ -2879,18 +2840,15 @@
         <if test="targetProjectId !=null  ">
             and project.`id` = #{targetProjectId}
         </if>
-        <if test="justWaitForMe !=null">
-            and task.task_status=3
-        </if>
         and ((IFNULL(task.start_date , task.end_date) between #{startDate} and #{endDate}) or (task.end_date between #{startDate} and #{endDate}))
-        and task.end_date is not null and task.is_task_plan=1  and task.check_first_id=#{managerId} and task.task_status !=2
+        and task.end_date is not null and task.is_task_plan=1  and project.incharger_id=#{managerId} and task.task_status !=2
         AND project.`status` = 1
         ORDER BY project.id, task.start_date
     </select>
     <select id="getTaskPlanByProjectAreaManager" resultType="java.util.Map">
         SELECT task.executor_id as user_id, task.executor_name as `name`,project.id, project.`project_name`,task.id as task_id, task.name as task_name,
-        task.task_plan_type as taskPlanType,task.is_task_plan as isTaskPlan,task.check_first_id as checkFirstId,task.check_second_id as checkSecondId
-        ,task.task_status as taskStatus,task.id as taskId,task.task_plan taskPlan,
+        task.task_plan_type as taskPlanType,task.is_task_plan as isTaskPlan,
+        task.task_status as taskStatus,task.id as taskId,task.task_plan taskPlan,
         IFNULL(task.`start_date`, task.end_date) as start_date, task.`end_date`, task.plan_hours as duration FROM project
         LEFT JOIN task ON task.project_id = project.id
         <if test="groupName !=null and groupName !='' ">
@@ -2912,9 +2870,6 @@
         <if test="targetProjectId !=null  ">
             and project.`id` = #{targetProjectId}
         </if>
-        <if test="justWaitForMe !=null">
-            and task.task_status=4
-        </if>
         and ((IFNULL(task.start_date , task.end_date) between #{startDate} and #{endDate}) or (task.end_date between #{startDate} and #{endDate}))
         and task.end_date is not null and task.task_plan=1 and  task.check_second_id=#{managerId}
         AND project.`status` = 1 and task.task_status !=2
@@ -2970,14 +2925,13 @@
         SELECT DISTINCT pl.project_id
         FROM project_leader pl
         WHERE pl.leader_id = #{userId}
-
         UNION
-
         SELECT DISTINCT p.id
         FROM project p
         INNER JOIN task t ON t.project_id = p.id
+        LEFT JOIN task_executor te ON te.task_id = t.id
         WHERE p.company_id = #{companyId}
-        AND (t.check_first_id = #{userId} OR t.check_second_id = #{userId})
+        AND (te.first_auditor_id = #{userId} OR te.second_auditor_id = #{userId})
     </select>
     <select id="getExistIds" resultType="java.lang.String">
         select project_code

+ 5 - 2
fhKeeper/formulahousekeeper/management-platform-mld/src/main/resources/mapper/TaskExecutorMapper.xml

@@ -13,11 +13,15 @@
         <result column="project_id" property="projectId" />
         <result column="service_id" property="serviceId" />
         <result column="real_cost" property="realCost" />
+        <result column="file_charge_one_id" property="fileChargeOneId" />
+        <result column="file_charge_two_id" property="fileChargeTwoId" />
+        <result column="first_auditor_id" property="firstAuditorId" />
+        <result column="second_auditor_id" property="secondAuditorId" />
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        id, task_id, executor_id, executor_name, executor_color, plan_hours, project_id, service_id, real_cost, file_charge_one_id, file_charge_two_id
+        id, task_id, executor_id, executor_name, executor_color, plan_hours, project_id, service_id, real_cost, file_charge_one_id, file_charge_two_id, first_auditor_id, second_auditor_id
     </sql>
     <select id="getInfoWithFileCharge" resultType="com.management.platform.entity.TaskExecutor">
         select te.id as id,   task_id, executor_id, executor_name, executor_color, plan_hours, project_id
@@ -29,5 +33,4 @@
                  left join user u2 on te.file_charge_two_id = u2.id
         where task_id = #{taskId}
     </select>
-
 </mapper>

+ 63 - 16
fhKeeper/formulahousekeeper/management-platform-mld/src/main/resources/mapper/TaskMapper.xml

@@ -33,13 +33,13 @@
         <result column="ahead_tid" property="aheadTid" />
         <result column="sap_task_code" property="sapTaskCode" />
         <result column="plan_cost" property="planCost" />
+        <result column="attach_file_required" property="attachFileRequired" />
         <result column="task_plan_type" property="taskPlanType" />
+        <result column="task_plan" property="taskPlan" />
         <result column="is_task_plan" property="isTaskPlan" />
-        <result column="check_first_id" property="checkFirstId" />
-        <result column="check_second_id" property="checkSecondId" />
-        <result column="attach_file_required" property="attachFileRequired" />
+        <result column="center_id" property="centerId" />
+        <result column="center_name" property="centerName" />
     </resultMap>
-
     <resultMap id="timeResultMap" type="com.management.platform.entity.TimeTask" >
         <id column="id" property="id" />
         <result column="name" property="name" />
@@ -104,19 +104,54 @@
         <result column="stages_name" property="stagesName" />
         <result column="department_name" property="departmentName" />
         <result column="attach_file_required" property="attachFileRequired" />
-        <!--        <result column="charge_one_id" property="chargeOneId" />-->
-        <!--        <result column="charge_one_status" property="chargeOneStatus" />-->
-        <!--        <result column="charge_one_time" property="chargeOneTime" />-->
-        <!--        <result column="charge_two_id" property="chargeTwoId" />-->
-        <!--        <result column="charge_two_status" property="chargeTwoStatus" />-->
-        <!--        <result column="charge_two_time" property="chargeTwoTime" />-->
-        <!--        <result column="charge_stage" property="chargeStage" />-->
-        <!--        <result column="final_charge_status" property="finalChargeStatus" />-->
-        <!--        <result column="file_reject_reason" property="fileRejectReason"></result>-->
+        <result column="center_id" property="centerId" />
+        <result column="center_name" property="centerName" />
+    </resultMap>
+    <resultMap id="AuditorResultMap" type="com.management.platform.entity.TaskWithAuditor">
+        <id column="id" property="id" />
+        <result column="name" property="name" />
+        <result column="task_desc" property="taskDesc" />
+        <result column="creater_id" property="createrId" />
+        <result column="creater_name" property="createrName" />
+        <result column="creator_color" property="creatorColor" />
+        <result column="executor_id" property="executorId" />
+        <result column="executor_name" property="executorName" />
+        <result column="executor_color" property="executorColor" />
+        <result column="task_level" property="taskLevel" />
+        <result column="task_status" property="taskStatus" />
+        <result column="create_date" property="createDate" />
+        <result column="end_date" property="endDate" />
+        <result column="project_id" property="projectId" />
+        <result column="stages_id" property="stagesId" />
+        <result column="company_id" property="companyId" />
+        <result column="indate" property="indate" />
+        <result column="parent_tid" property="parentTid" />
+        <result column="group_id" property="groupId" />
+        <result column="seq" property="seq" />
+        <result column="plan_hours" property="planHours" />
+        <result column="task_type" property="taskType" />
+        <result column="parent_tname" property="parentTname" />
+        <result column="finish_date" property="finishDate" />
+        <result column="project_name" property="projectName" />
+        <result column="start_date" property="startDate" />
+        <result column="meeting_id" property="meetingId" />
+        <result column="ahead_tid" property="aheadTid" />
+        <result column="sap_task_code" property="sapTaskCode" />
+        <result column="stages_name" property="stagesName" />
+        <result column="department_name" property="departmentName" />
+        <result column="attach_file_required" property="attachFileRequired" />
+        <result column="center_id" property="centerId" />
+        <result column="center_name" property="centerName" />
+        <result column="first_auditor_id" property="firstAuditorId" />
+        <result column="first_auditor_name" property="firstAuditorName" />
+        <result column="second_auditor_id" property="secondAuditorId" />
+        <result column="second_auditor_name" property="secondAuditorName" />
     </resultMap>
+
+
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        id, name, task_desc, creater_id, creater_name, creator_color, executor_id, executor_name, executor_color, task_level, task_status, create_date, end_date, project_id, stages_id, company_id, indate, parent_tid, group_id, seq, plan_hours, task_type, parent_tname, finish_date, start_date, meeting_id, ahead_tid, sap_task_code, plan_cost
+        id, name, task_desc, creater_id, creater_name, creator_color, executor_id, executor_name, executor_color, task_level, task_status, create_date, end_date, project_id, stages_id, company_id, indate, parent_tid, group_id, seq, plan_hours, task_type, parent_tname, finish_date, start_date, meeting_id, ahead_tid, sap_task_code, plan_cost, attach_file_required, task_plan_type, task_plan, is_task_plan, center_id, center_name
     </sql>
     <select id="simpleList" resultMap="BaseResultMap">
         select id, name, creater_id, creater_name, creator_color, executor_id, executor_name, executor_color, task_level, task_status, create_date, end_date, project_id, stages_id, company_id, indate, parent_tid, group_id, seq, plan_hours, task_type, parent_tname, finish_date, start_date
@@ -284,7 +319,7 @@
             </foreach>
         </if>
     </select>
-    <select id="getTaskWithProjectName" resultMap="RichResultMap">
+    <select id="getTaskWithProjectName" resultMap="AuditorResultMap">
         SELECT task.id, task.project_id, task.name, task.executor_name, task.start_date, task.`end_date`,task.create_date, task.`creater_id`, task.`creater_name`, task.group_id,
         task.plan_hours, task.task_type, task.task_level, task.task_status, task.`finish_date`, project.`project_name`, stages.stages_name,department.department_name
         <!-- ,task.charge_one_id,task.charge_one_status,task.charge_two_id,task.charge_two_status,task.charge_stage,task.final_charge_status -->
@@ -800,6 +835,18 @@
                 </foreach>
             </if>
         </where>
-             ) tmp1
+        ) tmp1
+    </select>
+
+    <select id="getMyAuditTaskList"
+            resultMap="AuditorResultMap">
+        SELECT DISTINCT task.*, task_executor.`first_auditor_id`, task_executor.`second_auditor_id`, u1.name AS first_auditor_name, u2.`name` AS second_auditor_name FROM task LEFT JOIN task_executor ON task.id = task_executor.`task_id`
+        LEFT JOIN USER u1 ON u1.id = task_executor.`first_auditor_id` LEFT JOIN USER u2 ON u2.id = task_executor.`second_auditor_id`
+        ${ew.customSqlSegment}
+        and (task.`task_status` = 3 AND task_executor.`first_auditor_id` = #{userId} ) or (task.`task_status` = 4 AND task_executor.`second_auditor_id` = #{userId} )
+        order by task.id desc
+        <if test="pageStart != null and pageSize != null">
+            limit #{pageStart}, #{pageSize}
+        </if>
     </select>
 </mapper>

+ 19 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/resources/mapper/TaskTypeMapper.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.management.platform.mapper.TaskTypeMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.TaskType">
+        <id column="id" property="id" />
+        <result column="name" property="name" />
+        <result column="need_audit" property="needAudit" />
+        <result column="company_id" property="companyId" />
+        <result column="color" property="color" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, name, need_audit, company_id, color
+    </sql>
+
+</mapper>

+ 3 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -11139,6 +11139,9 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                     map.put("createDate", dateTimeFormatter.format(fvTime.getWorkDate()));
                     map.put("workHours", fvTime.getWorkHours());
                     map.put("reportTime", reportTime);
+                    if (fvTime.getProcinstId() != null && fvTime.getProcinstId().startsWith("bustrip")) {
+                        map.put("isBusTrip", true);
+                    }
                     resultList.add(map);
                 }
             }

+ 31 - 16
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/DataCollectTask.java

@@ -291,11 +291,11 @@ public class DataCollectTask {
 
     }
 
-    @Scheduled(cron = "0 30 1 * * ?")
-//@Scheduled(cron = "0 42 16 * * ?")
+//    @Scheduled(cron = "0 30 1 * * ?")
+@Scheduled(cron = "50 24 11 * * ?")
     public void workDayTask(){
-        if(isDev){return;}
-        if(isPrivateDeploy) return;
+//        if(isDev){return;}
+//        if(isPrivateDeploy) return;
         RestTemplate restTemplate = new RestTemplate();
         String sumUrl = PREFIX_URL+"/dataCollect/getWorkDayDataSum";
         String listUrl = PREFIX_URL+"/dataCollect/getWorkDayDataList";
@@ -470,7 +470,7 @@ public class DataCollectTask {
                                     if (owner.getIsActive() == 0) {
                                         continue;
                                     }
-                                    Project project = projectMapper.selectOne(new QueryWrapper<Project>().eq("project_code", "HH-GG-0000001").eq("company_id", specialCompanyId));
+                                    Project project = projectMapper.selectOne(new QueryWrapper<Project>().eq("project_code", "HH-QJ-0000001").eq("company_id", specialCompanyId));
                                     TaskGroup leaveGroup = taskGroupMapper.selectOne(new LambdaQueryWrapper<TaskGroup>().eq(TaskGroup::getProjectId, project.getId()).eq(TaskGroup::getName, "请假工时"));
                                     for (LocalDate date = tmp.getStartDate(); date.compareTo(tmp.getEndDate()) <= 0; date = date.plusDays(1)) {
                                         //先计算每一天的请假工时数合计
@@ -733,12 +733,12 @@ public class DataCollectTask {
         }
     }
 
-    @Scheduled(cron = "0 0 3 * * ?")
-//@Scheduled(cron = "0 57 9 * * ?")
+//    @Scheduled(cron = "0 0 3 * * ?")
+@Scheduled(cron = "30 47 11 * * ?")
     @Async
     public void businessTripTask(){
-        if(isDev){return;}
-        if(isPrivateDeploy) return;
+//        if(isDev){return;}
+//        if(isPrivateDeploy) return;
         RestTemplate restTemplate = new RestTemplate();
         String sumUrl = PREFIX_URL+"/dataCollect/getBusinessTripDataSum";
         String listUrl = PREFIX_URL+"/dataCollect/getBusinessTripDataList";
@@ -799,14 +799,7 @@ public class DataCollectTask {
                                         toAddList.add(businessTrip);
                                     }
                                 }
-//                                if(existBTripList.size() > 0){
-//                                    toUpdateList.addAll(realDataList.stream().filter(t -> existIds.contains(t.getProcinstId())).collect(Collectors.toList()));
-//                                    toAddList.addAll(realDataList.stream().filter(t -> !existIds.contains(t.getProcinstId())).collect(Collectors.toList()));
-//                                }else{
-//                                    toAddList.addAll(realDataList);
-//                                }
                                 if(!CollectionUtils.isEmpty(toAddList)){
-//                                businessTripMapper.batchInsert(toAddList);
                                     for (BusinessTrip businessTrip : toAddList) {
                                         businessTripMapper.insert(businessTrip);
                                         if (!StringUtils.isEmpty(businessTrip.getCCcxmNo())) {
@@ -850,6 +843,28 @@ public class DataCollectTask {
                                         }
                                     }
                                 }
+
+                                //自动生成考勤数据
+                                for (BusinessTrip trip : realDataList) {
+                                    LocalDate startDate = trip.getStartDate();
+                                    LocalDate endDate = trip.getEndDate();
+                                    while (!startDate.isAfter(endDate)) {
+                                        //检查是否已经有当天的考勤
+                                        int cnt = userFvTimeMapper.selectCount(new QueryWrapper<UserFvTime>().eq("work_date", startDate).eq("user_id", trip.getOwnerId()));
+                                        if (cnt == 0) {
+                                            UserFvTime time = new UserFvTime();
+                                            time.setUserId(trip.getOwnerId());
+                                            time.setWorkDate(startDate);
+                                            time.setStartTime("9:00");
+                                            time.setEndTime("18:00");
+                                            time.setWorkHours(8.0f);
+                                            time.setCompanyId(trip.getCompanyId());
+                                            time.setProcinstId("bustrip_"+UUID.randomUUID().toString().replace("-",""));
+                                            userFvTimeMapper.insert(time);
+                                        }
+                                        startDate = startDate.plusDays(1);
+                                    }
+                                }
                             }
 
                             toUpdateList.clear();

+ 1 - 1
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -5070,7 +5070,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             if (map.get("planExtraInfoId")!=null){
                 BigDecimal num = new BigDecimal(String.valueOf(map.get("num")));
                 if (planManNum>1){
-                    avg = num.divide(BigDecimal.valueOf(planManNum)).setScale(3, RoundingMode.HALF_UP);
+                    avg = num.divide(BigDecimal.valueOf(planManNum), 3, RoundingMode.HALF_UP);
                 }
                 else {
 //                    item.add(String.valueOf(map.get("num")) + " 件");

+ 2 - 2
fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/weekEdit.vue

@@ -78,7 +78,7 @@
                                 @cancel="item.showPickerSubProject = false;$forceUpdate();" />
                         </van-popup>
                         <!--任务分组 -->
-                        <van-field  readonly  name="groupId" v-if="user.company.packageProject==1&&item.taskGroups != null && item.taskGroups.length > 0 && (user.company.nonProjectSimple==0 || (user.company.nonProjectSimple==1 && (item.projectId && projectss.filter(p => p.id == item.projectId)[0].isPublic!=1)))" clickable 
+                        <van-field  readonly  name="groupId" v-if="user.company.packageProject==1&&item.taskGroups != null && item.taskGroups.length > 0 && (user.company.nonProjectSimple==0 || (user.company.nonProjectSimple==1 && (item.projectId && (projectss.filter(p => p.id == item.projectId)[0] || {}).isPublic!=1)))" clickable 
                             :value="item.groupName" :label="user.timeType.enableNewWeeklyfill == 1 ? '分组' : '任务分组'" :placeholder="user.timeType.enableNewWeeklyfill == 1 ? '请选择分组' : '请选择任务分组'" 
                         @click="clickPickTaskGroup(index, item)" :disabled="item.state<=1" />
                         <!-- <van-popup v-model="item.showPickerTaskGroup" position="bottom">
@@ -225,7 +225,7 @@
 
                         <!-- 任务里程碑 -->
                         <van-field :label="'任务/里程碑'" :value="item.taskName" :disabled="item.state<=1" readonly 
-                            clickable v-if="user.company.packageProject == 1 && !user.timeType.hideStages && (user.company.nonProjectSimple==0 || (item.projectId && projectss.filter(p => p.id == item.projectId)[0].isPublic!=1))" 
+                            clickable v-if="user.company.packageProject == 1 && !user.timeType.hideStages && (user.company.nonProjectSimple==0 || (item.projectId && (projectss.filter(p => p.id == item.projectId)[0] || {}).isPublic!=1))" 
                             @click="clickTakKer(index, item)"
                         />
                         <van-popup v-model="item.showTaksDegree" position="bottom" @click-overlay="overlayPopup(index, 'showTaksDegree')">

+ 5 - 0
fhKeeper/formulahousekeeper/timesheet_mld/.babelrc

@@ -0,0 +1,5 @@
+{
+  "presets": ["es2015", "stage-2"],
+  "plugins": ["transform-runtime"],
+  "comments": false
+}

+ 8 - 0
fhKeeper/formulahousekeeper/timesheet_mld/.gitignore

@@ -0,0 +1,8 @@
+.DS_Store
+node_modules/
+npm-debug.log
+.editorconfig
+dist/
+.idea/misc.xml
+.idea/modules.xml
+.idea/workspace.xml

+ 12 - 0
fhKeeper/formulahousekeeper/timesheet_mld/.vscode/settings.json

@@ -0,0 +1,12 @@
+{
+  // Vue: i18n-ally 插件如下须要本身配置
+  "i18n-ally.localesPaths": ["src/i18n"], // 翻译的语言路径
+  "i18n-ally.enabledParsers": ["json", "js"], // 翻译支持的语言文件格式
+  "i18n-ally.encoding": "utf-8", // 翻译文件的编码
+  "i18n-ally.sourceLanguage": "zh", // 根据此 cn 语言文件翻译其他语言文件的 变量和内容
+  "i18n-ally.displayLanguage": "zh", // 组件中显示的语言
+  "i18n-ally.keystyle": "flat",
+  "i18n-ally.enabledFrameworks": ["vue"],
+  "vue-i18n.i18nPaths": "src\\i18n" // 翻译后变量的格式, flat(扁平式即对象属性路径变成一个长字符串), nested(嵌套式即对象属性变量可以进行相互之间的嵌套)
+  // 注意: 如果 i18n-ally 检测不出来框架, 或 提示错误, 可能是版本太高的缘故
+}

+ 21 - 0
fhKeeper/formulahousekeeper/timesheet_mld/LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2016-present taylorchen709
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 0 - 0
fhKeeper/formulahousekeeper/timesheet_mld/README.md


+ 12 - 0
fhKeeper/formulahousekeeper/timesheet_mld/build-private.bat

@@ -0,0 +1,12 @@
+@echo off
+
+copy /Y setIndex\indexTwo.html index.html
+
+start /B npm run build
+
+timeout /t 35 /nobreak
+
+copy /Y setIndex\indexOne.html index.html
+
+echo Done!
+pause

+ 1 - 0
fhKeeper/formulahousekeeper/timesheet_mld/build.bat

@@ -0,0 +1 @@
+npm run build

+ 35 - 0
fhKeeper/formulahousekeeper/timesheet_mld/build/build.js

@@ -0,0 +1,35 @@
+require('./check-versions')()
+
+process.env.NODE_ENV = 'production'
+
+var ora = require('ora')
+var rm = require('rimraf')
+var path = require('path')
+var chalk = require('chalk')
+var webpack = require('webpack')
+var config = require('../config')
+var webpackConfig = require('./webpack.prod.conf')
+
+var spinner = ora('building for production...')
+spinner.start()
+
+rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
+  if (err) throw err
+  webpack(webpackConfig, function (err, stats) {
+    spinner.stop()
+    if (err) throw err
+    process.stdout.write(stats.toString({
+      colors: true,
+      modules: false,
+      children: false,
+      chunks: false,
+      chunkModules: false
+    }) + '\n\n')
+
+    console.log(chalk.cyan('  Build complete.\n'))
+    console.log(chalk.yellow(
+      '  Tip: built files are meant to be served over an HTTP server.\n' +
+      '  Opening index.html over file:// won\'t work.\n'
+    ))
+  })
+})

+ 48 - 0
fhKeeper/formulahousekeeper/timesheet_mld/build/check-versions.js

@@ -0,0 +1,48 @@
+var chalk = require('chalk')
+var semver = require('semver')
+var packageConfig = require('../package.json')
+var shell = require('shelljs')
+function exec (cmd) {
+  return require('child_process').execSync(cmd).toString().trim()
+}
+
+var versionRequirements = [
+  {
+    name: 'node',
+    currentVersion: semver.clean(process.version),
+    versionRequirement: packageConfig.engines.node
+  },
+]
+
+if (shell.which('npm')) {
+  versionRequirements.push({
+    name: 'npm',
+    currentVersion: exec('npm --version'),
+    versionRequirement: packageConfig.engines.npm
+  })
+}
+
+module.exports = function () {
+  var warnings = []
+  for (var i = 0; i < versionRequirements.length; i++) {
+    var mod = versionRequirements[i]
+    if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
+      warnings.push(mod.name + ': ' +
+        chalk.red(mod.currentVersion) + ' should be ' +
+        chalk.green(mod.versionRequirement)
+      )
+    }
+  }
+
+  if (warnings.length) {
+    console.log('')
+    console.log(chalk.yellow('To use this template, you must update following to modules:'))
+    console.log()
+    for (var i = 0; i < warnings.length; i++) {
+      var warning = warnings[i]
+      console.log('  ' + warning)
+    }
+    console.log()
+    process.exit(1)
+  }
+}

+ 9 - 0
fhKeeper/formulahousekeeper/timesheet_mld/build/dev-client.js

@@ -0,0 +1,9 @@
+/* eslint-disable */
+require('eventsource-polyfill')
+var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
+
+hotClient.subscribe(function (event) {
+  if (event.action === 'reload') {
+    window.location.reload()
+  }
+})

+ 89 - 0
fhKeeper/formulahousekeeper/timesheet_mld/build/dev-server.js

@@ -0,0 +1,89 @@
+require('./check-versions')()
+
+var config = require('../config')
+if (!process.env.NODE_ENV) {
+  process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
+}
+
+var opn = require('opn')
+var path = require('path')
+var express = require('express')
+var webpack = require('webpack')
+var proxyMiddleware = require('http-proxy-middleware')
+var webpackConfig = require('./webpack.dev.conf')
+
+// default port where dev server listens for incoming traffic
+var port = process.env.PORT || config.dev.port
+// automatically open browser, if not set will be false
+var autoOpenBrowser = !!config.dev.autoOpenBrowser
+// Define HTTP proxies to your custom API backend
+// https://github.com/chimurai/http-proxy-middleware
+var proxyTable = config.dev.proxyTable
+
+var app = express()
+var compiler = webpack(webpackConfig)
+
+var devMiddleware = require('webpack-dev-middleware')(compiler, {
+  publicPath: webpackConfig.output.publicPath,
+  quiet: true
+})
+
+var hotMiddleware = require('webpack-hot-middleware')(compiler, {
+  log: () => {}
+})
+// force page reload when html-webpack-plugin template changes
+compiler.plugin('compilation', function (compilation) {
+  compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
+    hotMiddleware.publish({ action: 'reload' })
+    cb()
+  })
+})
+
+// proxy api requests
+Object.keys(proxyTable).forEach(function (context) {
+  var options = proxyTable[context]
+  if (typeof options === 'string') {
+    options = { target: options }
+  }
+  app.use(proxyMiddleware(options.filter || context, options))
+})
+
+// handle fallback for HTML5 history API
+app.use(require('connect-history-api-fallback')())
+
+// serve webpack bundle output
+app.use(devMiddleware)
+
+// enable hot-reload and state-preserving
+// compilation error display
+app.use(hotMiddleware)
+
+// serve pure static assets
+var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
+app.use(staticPath, express.static('./static'))
+
+var uri = 'http://localhost:' + port
+
+var _resolve
+var readyPromise = new Promise(resolve => {
+  _resolve = resolve
+})
+
+console.log('> Starting dev server...')
+devMiddleware.waitUntilValid(() => {
+  console.log('> Listening at ' + uri + '\n')
+  // when env is testing, don't need open it
+  if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
+    opn(uri)
+  }
+  _resolve()
+})
+
+var server = app.listen(port)
+
+module.exports = {
+  ready: readyPromise,
+  close: () => {
+    server.close()
+  }
+}

+ 79 - 0
fhKeeper/formulahousekeeper/timesheet_mld/build/utils.js

@@ -0,0 +1,79 @@
+var path = require('path')
+var config = require('../config')
+var ExtractTextPlugin = require('extract-text-webpack-plugin')
+
+exports.assetsPath = function (_path) {
+    var assetsSubDirectory = process.env.NODE_ENV === 'production'
+        ? config.build.assetsSubDirectory
+        : config.dev.assetsSubDirectory
+    return path.posix.join(assetsSubDirectory, _path)
+}
+
+exports.cssLoaders = function (options) {
+    options = options || {}
+
+    var cssLoader = {
+        loader: 'css-loader',
+        options: {
+        //minimize: process.env.NODE_ENV === 'production',
+        sourceMap: options.sourceMap
+        }
+    }
+
+    // generate loader string to be used with extract text plugin
+    function generateLoaders (loader, loaderOptions) {
+        var loaders = [cssLoader]
+        if (loader) {
+        loaders.push({
+            loader: loader + '-loader',
+            options: Object.assign({}, loaderOptions, {
+            sourceMap: options.sourceMap
+            })
+        })
+        }
+
+        // Extract CSS when that option is specified
+        // (which is the case during production build)
+        if (options.extract) {
+            return ExtractTextPlugin.extract({
+                use: loaders,
+                fallback: 'vue-style-loader',
+                publicPath: '../../'
+            })
+        } else {
+            return ['vue-style-loader'].concat(loaders)
+        }
+    }
+
+    // https://vue-loader.vuejs.org/en/configurations/extract-css.html
+    return {
+        css: generateLoaders(),
+        postcss: generateLoaders(),
+        less: generateLoaders('less'),
+        sass: generateLoaders('sass', { indentedSyntax: true }),
+        // scss: generateLoaders('sass'),
+        stylus: generateLoaders('stylus'),
+        styl: generateLoaders('stylus'),
+        scss: generateLoaders('sass').concat({
+            loader: 'sass-resources-loader',
+            options: {
+                //你自己的scss全局文件的路径
+                resources: path.resolve(__dirname, '../src/assets/scss/_common.scss')
+            }
+        })
+    }
+}
+
+// Generate loaders for standalone style files (outside of .vue)
+exports.styleLoaders = function (options) {
+    var output = []
+    var loaders = exports.cssLoaders(options)
+    for (var extension in loaders) {
+        var loader = loaders[extension]
+        output.push({
+            test: new RegExp('\\.' + extension + '$'),
+            use: loader
+        })
+    }
+    return output
+}

+ 12 - 0
fhKeeper/formulahousekeeper/timesheet_mld/build/vue-loader.conf.js

@@ -0,0 +1,12 @@
+var utils = require('./utils')
+var config = require('../config')
+var isProduction = process.env.NODE_ENV === 'production'
+
+module.exports = {
+  loaders: utils.cssLoaders({
+    sourceMap: isProduction
+      ? config.build.productionSourceMap
+      : config.dev.cssSourceMap,
+    extract: isProduction
+  })
+}

+ 78 - 0
fhKeeper/formulahousekeeper/timesheet_mld/build/webpack.base.conf.js

@@ -0,0 +1,78 @@
+var path = require('path')
+var utils = require('./utils')
+var config = require('../config')
+var vueLoaderConfig = require('./vue-loader.conf')
+var webpack = require("webpack")
+
+function resolve(dir) {
+  return path.join(__dirname, '..', dir)
+}
+
+module.exports = {
+    entry: {
+        //app: './src/main.js'
+        app: ["babel-polyfill", "./src/main.js"]
+    },
+    externals: {
+        'vue': 'Vue',
+        'vue-router': 'VueRouter',
+        'vuex': 'Vuex',
+        // 'element-ui': 'ElementUI',
+        'echarts': 'echarts',
+    },
+    output: {
+        path: config.build.assetsRoot,
+        filename: '[name].js',
+        publicPath: process.env.NODE_ENV === 'production'
+        ? config.build.assetsPublicPath
+        : config.dev.assetsPublicPath
+    },
+    resolve: {
+        extensions: ['.js', '.vue', '.json'],
+        alias: {
+        'vue$': 'vue/dist/vue.esm.js',
+        '@': resolve('src'),
+        'scss_vars': '@/styles/vars.scss'
+        }
+    },
+    plugins: [
+        new webpack.ProvidePlugin({
+        jQuery: 'jquery',
+        $: 'jquery'
+        })
+    ],
+    module: {
+        rules: [
+            {
+                test: /\.vue$/,
+                loader: 'vue-loader',
+                options: vueLoaderConfig
+            },
+            {
+                test: /\.js$/,
+                loader: 'babel-loader',
+                include: [resolve('src'), resolve('test')]
+            },
+            {
+                test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
+                loader: 'url-loader',
+                options: {
+                limit: 10000,
+                name: utils.assetsPath('img/[name].[hash:7].[ext]')
+                }
+            },
+            {
+                test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
+                loader: 'url-loader',
+                options: {
+                limit: 10000,
+                name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
+                }
+            },
+            {
+                test: /\.scss$/,
+                loaders: ['style', 'css', 'sass']
+            }
+        ]
+    }
+}

+ 38 - 0
fhKeeper/formulahousekeeper/timesheet_mld/build/webpack.dev.conf.js

@@ -0,0 +1,38 @@
+var utils = require('./utils')
+var webpack = require('webpack')
+var config = require('../config')
+var merge = require('webpack-merge')
+var baseWebpackConfig = require('./webpack.base.conf')
+var HtmlWebpackPlugin = require('html-webpack-plugin')
+var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
+
+// add hot-reload related code to entry chunks
+Object.keys(baseWebpackConfig.entry).forEach(function (name) {
+  baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
+})
+
+module.exports = merge(baseWebpackConfig, {
+  module: {
+    rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
+  },
+  // cheap-module-eval-source-map is faster for development
+  devtool: '#cheap-module-eval-source-map',
+  plugins: [
+    new webpack.DefinePlugin({
+      'process.env': config.dev.env,
+      'BASE_URL' : '"/api"',
+      'LINK_URL' : '"/ips"'
+    }),
+    // https://github.com/glenjamin/webpack-hot-middleware#installation--usage
+    new webpack.HotModuleReplacementPlugin(),
+    new webpack.NoEmitOnErrorsPlugin(),
+    // https://github.com/ampedandwired/html-webpack-plugin
+    new HtmlWebpackPlugin({
+      filename: 'index.html',
+      template: 'index.html',
+      inject: true,
+      favicon: './favicon.ico'
+    }),
+    new FriendlyErrorsPlugin()
+  ]
+})

+ 125 - 0
fhKeeper/formulahousekeeper/timesheet_mld/build/webpack.prod.conf.js

@@ -0,0 +1,125 @@
+var path = require('path')
+var utils = require('./utils')
+var webpack = require('webpack')
+var config = require('../config')
+var merge = require('webpack-merge')
+var baseWebpackConfig = require('./webpack.base.conf')
+var CopyWebpackPlugin = require('copy-webpack-plugin')
+var HtmlWebpackPlugin = require('html-webpack-plugin')
+var ExtractTextPlugin = require('extract-text-webpack-plugin')
+var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
+var version = new Date().getTime()
+
+var env = config.build.env
+
+var webpackConfig = merge(baseWebpackConfig, {
+    module: {
+        rules: utils.styleLoaders({
+        sourceMap: config.build.productionSourceMap,
+            extract: true
+        })
+    },
+    devtool: config.build.productionSourceMap ? '#source-map' : false,
+    output: {
+        publicPath: './',
+        path: config.build.assetsRoot,
+        filename: utils.assetsPath(`js/[name].[chunkhash].${version}.js`),
+        chunkFilename: utils.assetsPath(`js/[id].[chunkhash].${version}.js`)
+    },
+    plugins: [
+        // http://vuejs.github.io/vue-loader/en/workflow/production.html
+        new webpack.DefinePlugin({
+        'process.env': env,
+        'BASE_URL' : '"/api"',
+        'LINK_URL' : '"/ips"'
+        }),
+        new webpack.optimize.UglifyJsPlugin({
+        compress: {
+            warnings: false
+        },
+        sourceMap: true
+        }),
+        // extract css into its own file
+        new ExtractTextPlugin({
+        filename: utils.assetsPath(`css/[name].[contenthash].${version}.css`)
+        }),
+        // Compress extracted CSS. We are using this plugin so that possible
+        // duplicated CSS from different components can be deduped.
+        new OptimizeCSSPlugin({
+        cssProcessorOptions: {
+            safe: true
+        }
+        }),
+        // generate dist index.html with correct asset hash for caching.
+        // you can customize output by editing /index.html
+        // see https://github.com/ampedandwired/html-webpack-plugin
+        new HtmlWebpackPlugin({
+        filename: config.build.index,
+        template: 'index.html',
+        inject: true,
+        favicon: './favicon.ico',
+        minify: {
+            removeComments: true,
+            collapseWhitespace: true,
+            removeAttributeQuotes: true
+            // more options:
+            // https://github.com/kangax/html-minifier#options-quick-reference
+        },
+        // necessary to consistently work with multiple chunks via CommonsChunkPlugin
+        chunksSortMode: 'dependency'
+        }),
+        // split vendor js into its own file
+        new webpack.optimize.CommonsChunkPlugin({
+        name: 'vendor',
+        minChunks: function (module, count) {
+            // any required modules inside node_modules are extracted to vendor
+            return (
+            module.resource &&
+            /\.js$/.test(module.resource) &&
+            module.resource.indexOf(
+                path.join(__dirname, '../node_modules')
+            ) === 0
+            )
+        }
+        }),
+        // extract webpack runtime and module manifest to its own file in order to
+        // prevent vendor hash from being updated whenever app bundle is updated
+        new webpack.optimize.CommonsChunkPlugin({
+        name: 'manifest',
+        chunks: ['vendor']
+        }),
+        // copy custom static assets
+        new CopyWebpackPlugin([
+        {
+            from: path.resolve(__dirname, '../static'),
+            to: config.build.assetsSubDirectory,
+            ignore: ['.*']
+        }
+        ])
+    ]
+})
+
+if (config.build.productionGzip) {
+    var CompressionWebpackPlugin = require('compression-webpack-plugin')
+
+    webpackConfig.plugins.push(
+        new CompressionWebpackPlugin({
+        asset: '[path].gz[query]',
+        algorithm: 'gzip',
+        test: new RegExp(
+            '\\.(' +
+            config.build.productionGzipExtensions.join('|') +
+            ')$'
+        ),
+        threshold: 10240,
+        minRatio: 0.8
+        })
+    )
+}
+
+if (config.build.bundleAnalyzerReport) {
+    var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
+    webpackConfig.plugins.push(new BundleAnalyzerPlugin())
+}
+
+module.exports = webpackConfig

BIN
fhKeeper/formulahousekeeper/timesheet_mld/card_img.png


+ 6 - 0
fhKeeper/formulahousekeeper/timesheet_mld/config/dev.env.js

@@ -0,0 +1,6 @@
+var merge = require('webpack-merge')
+var prodEnv = require('./prod.env')
+
+module.exports = merge(prodEnv, {
+    NODE_ENV: '"development"'
+})

+ 67 - 0
fhKeeper/formulahousekeeper/timesheet_mld/config/index.js

@@ -0,0 +1,67 @@
+var path = require('path')
+
+//  var ip = '192.168.2.42'
+//  var ip = '192.168.2.49'
+// var ip = '47.101.180.183'
+// var ip = '47.100.37.243'
+// var ip = '192.168.10.2'
+// var ip = '192.168.2.11' 
+
+var os = require('os'), ip = '', ifaces = os.networkInterfaces() // 获取本机ip
+for (var i in ifaces) {
+    for (var j in ifaces[i]) {
+        var val = ifaces[i][j]
+        if (val.family === 'IPv4' && val.address !== '127.0.0.1') {
+            ip = val.address
+        }
+    }
+}
+// 1196735749
+module.exports = {
+  build: {
+    env: require('./prod.env'),
+    index: path.resolve(__dirname, '../dist/index.html'),
+    assetsRoot: path.resolve(__dirname, '../dist'),
+    assetsSubDirectory: 'static',
+    assetsPublicPath: './',
+    productionSourceMap: false,
+    productionGzip: false,
+    productionGzipExtensions: ['js', 'css'],
+    bundleAnalyzerReport: process.env.npm_config_report
+  },
+  dev: {
+    env: require('./dev.env'),
+    port: 10086,
+    autoOpenBrowser: true,
+    assetsSubDirectory: 'static',
+    assetsPublicPath: '/',
+    proxyTable: {
+        // '/api/permission': {
+        //   target: 'http://' + ip + ':2022',
+        //   pathRewrite: {'^api': '/'}
+        // },
+        // '/api/user': {
+        //   target: 'http://' + ip + ':10010',
+        //   pathRewrite: {'^api': '/'}
+        // }
+        // '/api/permission': {    
+        //     target: 'http://'+ ip +':2022',
+        //     secure: true,
+        //     changeOrigin: true,
+        //     pathRewrite: {
+        //         '^/api': '/' 
+        //     }
+        // },
+
+        '/api': {    
+            target: 'http://'+ ip +':10010',
+            secure: true,
+            changeOrigin: true,
+            pathRewrite: {
+                '^/api': '/' 
+            }
+        },
+    },
+    cssSourceMap: false
+  },
+}

+ 3 - 0
fhKeeper/formulahousekeeper/timesheet_mld/config/prod.env.js

@@ -0,0 +1,3 @@
+module.exports = {
+    NODE_ENV: '"production"'
+}

BIN
fhKeeper/formulahousekeeper/timesheet_mld/favicon.ico


+ 156 - 0
fhKeeper/formulahousekeeper/timesheet_mld/index.html

@@ -0,0 +1,156 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8" />
+    <!-- <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"> -->
+    <!-- 尝试清除打包缓存 -->
+    <!-- <meta http-equiv="pragram" content="no-cache">
+        <meta http-equiv="cache-control" content="no-cache, no-store, must-revalidate">
+        <meta http-equiv="expires" content="0"> -->
+    <!-- 尝试清除打包缓存 -->
+    <title>工时管家</title>
+    <!--接入钉钉前端组件,进行通讯录组件展示-->
+    <script src="https://auth.dingtalk.com/opendata-1.1.0.js"></script>
+    <link rel="shortcut icon" type="image/x-icon" href="./favicon.ico" />
+    <link href="./static/css/public.css" rel="stylesheet" type="text/css" />
+    <!-- <script async defer src="http://47.101.180.183:9999/api/application/embed?protocol=http&host=47.101.180.183:9999&token=56c5bbad807f9a14"></script> -->
+    <script async defer src="https://chatai.ttkuaiban.com/api/application/embed?protocol=https&host=chatai.ttkuaiban.com&token=8aa88c0a6d804a57"></script>
+    <!-- 引入样式 -->
+    <!-- <link href="https://cdn.staticfile.org/element-ui/2.13.0/theme-chalk/index.css" rel="stylesheet"/> -->
+    <!-- <link rel="stylesheet" href="./static/js/element-uiCss.css"> -->
+    <!-- 接入JQ  -->
+    <!-- <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script> -->
+    <script src="./static/js/jquery.min.js"></script>
+    <style>
+      /* 滚动条样式修改 */
+      /*滚动条凹槽的颜色,还可以设置边框属性 */
+      ::-webkit-scrollbar-track-piece {
+        background-color: #f8f8f8;
+        -webkit-border-radius: 2em;
+        -moz-border-radius: 2em;
+        border-radius: 2em;
+      }
+      /*滚动条的宽度*/
+      ::-webkit-scrollbar {
+        width: 9px;
+        height: 9px;
+      }
+      /*滚动条的设置*/
+      ::-webkit-scrollbar-thumb {
+        background-color: #dddddd;
+        background-clip: padding-box;
+        -webkit-border-radius: 2em;
+        -moz-border-radius: 2em;
+        border-radius: 2em;
+      }
+
+      /*滚动条鼠标移上去*/
+      ::-webkit-scrollbar-thumb:hover {
+        background-color: #bbb;
+      }
+
+      /*取消消息列表弹出框的内边距*/
+      .popover-self {
+        padding: 0 !important;
+      }
+
+      /*自定义颜色*/
+      #nprogress .bar {
+        background: #f58220 !important;
+      }
+
+      .selectworktime .el-dialog__header {
+        padding-top: 0;
+        padding-bottom: 0;
+      }
+      .selectworktime .el-dialog__body {
+        padding-top: 15px;
+      }
+      .el-dialog__headerbtn {
+        z-index: 2002;
+      }
+      .selecteorktime_datapick_popper {
+        left: 12vh !important;
+      }
+      .customsalary .el-input__inner {
+        height: 35px;
+        line-height: 35px;
+      }
+      .projectSelectPopperClass {
+        max-width: 1000px;
+      }
+      .projectSelectPopperClass li {
+        overflow: hidden;
+        white-space: nowrap;
+        text-overflow: ellipsis;
+      }
+      .projectSelectPopperClass .el-select-dropdown__item span:nth-child(1) {
+        font-size: 13px;
+        height: 34px;
+        max-width: 350px;
+      }
+      .projectSelectPopperClass .el-select-dropdown__item span:nth-child(2) {
+        font-size: 13px;
+        height: 34px;
+        max-width: 650px;
+
+        text-align: right;
+      }
+
+      /* 清除浮动 */
+      .clearfix:after {
+        content: "";
+        display: block;
+        height: 0;
+        clear: both;
+        visibility: hidden;
+      }
+      .clearfix {
+        /* 触发 hasLayout */
+        zoom: 1;
+      }
+      .fillWeekCustom {
+        .el-dialog__body {
+          padding: 10px 20px !important;
+        }
+      }
+    </style>
+  </head>
+  <!-- 接入飞书 -->
+  <script type="text/javascript" src="https://lf1-cdn-tos.bytegoofy.com/goofy/lark/op/h5-js-sdk-1.5.16.js"></script>
+  <!-- <script src="./static/js/goofy.js"></script> -->
+  <!-- <script src="https://unpkg.com/vconsole/dist/vconsole.min.js"></script>
+    <script>
+        var vConsole = new window.VConsole();
+    </script> -->
+  <body>
+    <div id="app"></div>
+    <script>
+      document.body.ondrop = function (event) {
+        event.preventDefault();
+        event.stopPropagation();
+      };
+    </script>
+    <!-- 引入Vue.js -->
+    <!-- <script src="https://cdn.staticfile.org/vue/2.6.10/vue.min.js"></script> -->
+    <script src="./static/js/vue.min.js"></script>
+    <!-- 引入vuex.js -->
+    <!-- <script src="https://cdn.staticfile.org/vuex/3.0.0/vuex.min.js"></script> -->
+    <script src="./static/js/vuex.min.js"></script>
+    <!-- 引入vue-router -->
+    <!-- <script src="https://cdn.staticfile.org/vue-router/3.0.0/vue-router.min.js"></script> -->
+    <script src="./static/js/vue-router.min.js"></script>
+    <!-- 引入组件库 -->
+    <!-- <script src="https://cdn.staticfile.org/element-ui/2.13.0/index.js"></script> -->
+    <script src="./static/js/element-ui.js"></script>
+    <!-- 引入echarts -->
+    <!-- <script src="https://cdn.staticfile.org/echarts/3.8.5/echarts.min.js"></script> -->
+    <script src="./static/js/echarts.min.js"></script>
+    <!-- 引入企业微信js -->
+    <script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js" referrerpolicy="origin"></script>
+    <script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js" referrerpolicy="origin"></script>
+    
+    <!-- <script src="./static/js/jweixin-1.2.0.js"></script>
+        <script src="./static/js/jwxwork-1.0.0.js"></script> -->
+  </body>
+</html>

ファイルの差分が大きいため隠しています
+ 10281 - 0
fhKeeper/formulahousekeeper/timesheet_mld/package-lock.json


+ 91 - 0
fhKeeper/formulahousekeeper/timesheet_mld/package.json

@@ -0,0 +1,91 @@
+{
+  "name": "ym_admin",
+  "version": "1.0.5",
+  "description": "ym_admin project",
+  "author": "taylor <709161610@qq.com>",
+  "license": "MIT",
+  "scripts": {
+    "dev": "node build/dev-server.js",
+    "start": "node build/dev-server.js",
+    "build": "node build/build.js"
+  },
+  "dependencies": {
+    "@tinymce/tinymce-vue": "^4.0.0",
+    "axios": "^0.15.3",
+    "dayjs": "^1.10.4",
+    "dhtmlx-gantt": "^7.1.6",
+    "dingtalk-jsapi": "^2.13.42",
+    "echarts": "^4.9.0",
+    "el-table-infinite-scroll": "^2.0.0",
+    "element-ui": "^2.15.3",
+    "font-awesome": "^4.7.0",
+    "jquery": "^3.4.1",
+    "nprogress": "^0.2.0",
+    "qrcode": "^1.5.4",
+    "tinymce": "^5.7.1",
+    "v-distpicker": "^1.2.13",
+    "v-viewer": "^1.6.4",
+    "vue": "^2.6.10",
+    "vue-clipboard2": "^0.3.0",
+    "vue-i18n": "^8.27.2",
+    "vue-pdf": "^4.2.0",
+    "vue-quill-editor": "^3.0.6",
+    "vue-router": "^2.3.0",
+    "vue-tour": "^2.0.0",
+    "vuedraggable": "^2.24.3",
+    "vuex": "^2.0.0-rc.6"
+  },
+  "devDependencies": {
+    "autoprefixer": "^6.7.2",
+    "axios-mock-adapter": "^1.7.1",
+    "babel-core": "^6.22.1",
+    "babel-loader": "^6.2.10",
+    "babel-plugin-transform-runtime": "^6.22.0",
+    "babel-polyfill": "^6.26.0",
+    "babel-preset-env": "^1.2.1",
+    "babel-preset-es2015": "^6.0.0",
+    "babel-preset-stage-2": "^6.22.0",
+    "babel-register": "^6.22.0",
+    "chalk": "^1.1.3",
+    "connect-history-api-fallback": "^1.3.0",
+    "copy-webpack-plugin": "^4.0.1",
+    "css-loader": "^0.26.1",
+    "eventsource-polyfill": "^0.9.6",
+    "express": "^4.14.1",
+    "extract-text-webpack-plugin": "^2.0.0",
+    "file-loader": "^0.10.0",
+    "friendly-errors-webpack-plugin": "^1.1.3",
+    "function-bind": "^1.0.2",
+    "html-webpack-plugin": "^2.28.0",
+    "http-proxy-middleware": "^0.17.3",
+    "json-loader": "^0.5.4",
+    "mockjs": "^1.0.1-beta3",
+    "node-sass": "^4.14.1",
+    "opn": "^4.0.2",
+    "optimize-css-assets-webpack-plugin": "^1.3.0",
+    "ora": "^1.0.0",
+    "qs": "^6.7.0",
+    "rimraf": "^2.6.0",
+    "sass-loader": "^6.0.0",
+    "semver": "^5.3.0",
+    "shelljs": "^0.7.6",
+    "url-loader": "^0.5.8",
+    "vue-loader": "^11.1.4",
+    "vue-style-loader": "^2.0.0",
+    "vue-template-compiler": "^2.2.4",
+    "webpack": "^2.7.0",
+    "webpack-bundle-analyzer": "^2.2.1",
+    "webpack-dev-middleware": "^1.10.0",
+    "webpack-hot-middleware": "^2.16.1",
+    "webpack-merge": "^2.6.1"
+  },
+  "engines": {
+    "node": ">= 4.0.0",
+    "npm": ">= 3.0.0"
+  },
+  "browserslist": [
+    "> 1%",
+    "last 2 versions",
+    "not ie <= 8"
+  ]
+}

+ 156 - 0
fhKeeper/formulahousekeeper/timesheet_mld/setIndex/indexOne.html

@@ -0,0 +1,156 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8" />
+    <!-- <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"> -->
+    <!-- 尝试清除打包缓存 -->
+    <!-- <meta http-equiv="pragram" content="no-cache">
+        <meta http-equiv="cache-control" content="no-cache, no-store, must-revalidate">
+        <meta http-equiv="expires" content="0"> -->
+    <!-- 尝试清除打包缓存 -->
+    <title>工时管家</title>
+    <!--接入钉钉前端组件,进行通讯录组件展示-->
+    <script src="https://auth.dingtalk.com/opendata-1.1.0.js"></script>
+    <link rel="shortcut icon" type="image/x-icon" href="./favicon.ico" />
+    <link href="./static/css/public.css" rel="stylesheet" type="text/css" />
+    <!-- <script async defer src="http://47.101.180.183:9999/api/application/embed?protocol=http&host=47.101.180.183:9999&token=56c5bbad807f9a14"></script> -->
+    <script async defer src="https://chatai.ttkuaiban.com/api/application/embed?protocol=https&host=chatai.ttkuaiban.com&token=56c5bbad807f9a14"></script>
+    <!-- 引入样式 -->
+    <!-- <link href="https://cdn.staticfile.org/element-ui/2.13.0/theme-chalk/index.css" rel="stylesheet"/> -->
+    <!-- <link rel="stylesheet" href="./static/js/element-uiCss.css"> -->
+    <!-- 接入JQ  -->
+    <!-- <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script> -->
+    <script src="./static/js/jquery.min.js"></script>
+    <style>
+      /* 滚动条样式修改 */
+      /*滚动条凹槽的颜色,还可以设置边框属性 */
+      ::-webkit-scrollbar-track-piece {
+        background-color: #f8f8f8;
+        -webkit-border-radius: 2em;
+        -moz-border-radius: 2em;
+        border-radius: 2em;
+      }
+      /*滚动条的宽度*/
+      ::-webkit-scrollbar {
+        width: 9px;
+        height: 9px;
+      }
+      /*滚动条的设置*/
+      ::-webkit-scrollbar-thumb {
+        background-color: #dddddd;
+        background-clip: padding-box;
+        -webkit-border-radius: 2em;
+        -moz-border-radius: 2em;
+        border-radius: 2em;
+      }
+
+      /*滚动条鼠标移上去*/
+      ::-webkit-scrollbar-thumb:hover {
+        background-color: #bbb;
+      }
+
+      /*取消消息列表弹出框的内边距*/
+      .popover-self {
+        padding: 0 !important;
+      }
+
+      /*自定义颜色*/
+      #nprogress .bar {
+        background: #f58220 !important;
+      }
+
+      .selectworktime .el-dialog__header {
+        padding-top: 0;
+        padding-bottom: 0;
+      }
+      .selectworktime .el-dialog__body {
+        padding-top: 15px;
+      }
+      .el-dialog__headerbtn {
+        z-index: 2002;
+      }
+      .selecteorktime_datapick_popper {
+        left: 12vh !important;
+      }
+      .customsalary .el-input__inner {
+        height: 35px;
+        line-height: 35px;
+      }
+      .projectSelectPopperClass {
+        max-width: 1000px;
+      }
+      .projectSelectPopperClass li {
+        overflow: hidden;
+        white-space: nowrap;
+        text-overflow: ellipsis;
+      }
+      .projectSelectPopperClass .el-select-dropdown__item span:nth-child(1) {
+        font-size: 13px;
+        height: 34px;
+        max-width: 350px;
+      }
+      .projectSelectPopperClass .el-select-dropdown__item span:nth-child(2) {
+        font-size: 13px;
+        height: 34px;
+        max-width: 650px;
+
+        text-align: right;
+      }
+
+      /* 清除浮动 */
+      .clearfix:after {
+        content: "";
+        display: block;
+        height: 0;
+        clear: both;
+        visibility: hidden;
+      }
+      .clearfix {
+        /* 触发 hasLayout */
+        zoom: 1;
+      }
+      .fillWeekCustom {
+        .el-dialog__body {
+          padding: 10px 20px !important;
+        }
+      }
+    </style>
+  </head>
+  <!-- 接入飞书 -->
+  <script type="text/javascript" src="https://lf1-cdn-tos.bytegoofy.com/goofy/lark/op/h5-js-sdk-1.5.16.js"></script>
+  <!-- <script src="./static/js/goofy.js"></script> -->
+  <!-- <script src="https://unpkg.com/vconsole/dist/vconsole.min.js"></script>
+    <script>
+        var vConsole = new window.VConsole();
+    </script> -->
+  <body>
+    <div id="app"></div>
+    <script>
+      document.body.ondrop = function (event) {
+        event.preventDefault();
+        event.stopPropagation();
+      };
+    </script>
+    <!-- 引入Vue.js -->
+    <!-- <script src="https://cdn.staticfile.org/vue/2.6.10/vue.min.js"></script> -->
+    <script src="./static/js/vue.min.js"></script>
+    <!-- 引入vuex.js -->
+    <!-- <script src="https://cdn.staticfile.org/vuex/3.0.0/vuex.min.js"></script> -->
+    <script src="./static/js/vuex.min.js"></script>
+    <!-- 引入vue-router -->
+    <!-- <script src="https://cdn.staticfile.org/vue-router/3.0.0/vue-router.min.js"></script> -->
+    <script src="./static/js/vue-router.min.js"></script>
+    <!-- 引入组件库 -->
+    <!-- <script src="https://cdn.staticfile.org/element-ui/2.13.0/index.js"></script> -->
+    <script src="./static/js/element-ui.js"></script>
+    <!-- 引入echarts -->
+    <!-- <script src="https://cdn.staticfile.org/echarts/3.8.5/echarts.min.js"></script> -->
+    <script src="./static/js/echarts.min.js"></script>
+    <!-- 引入企业微信js -->
+    <script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js" referrerpolicy="origin"></script>
+    <script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js" referrerpolicy="origin"></script>
+    
+    <!-- <script src="./static/js/jweixin-1.2.0.js"></script>
+        <script src="./static/js/jwxwork-1.0.0.js"></script> -->
+  </body>
+</html>

+ 127 - 0
fhKeeper/formulahousekeeper/timesheet_mld/setIndex/indexTwo.html

@@ -0,0 +1,127 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8" />
+    <title>工时管家</title>
+    <link rel="shortcut icon" type="image/x-icon" href="./favicon.ico" />
+    <link href="./static/css/public.css" rel="stylesheet" type="text/css" />
+    <script src="./static/js/jquery.min.js"></script>
+    <style>
+      /* 滚动条样式修改 */
+      /*滚动条凹槽的颜色,还可以设置边框属性 */
+      ::-webkit-scrollbar-track-piece {
+        background-color: #f8f8f8;
+        -webkit-border-radius: 2em;
+        -moz-border-radius: 2em;
+        border-radius: 2em;
+      }
+      /*滚动条的宽度*/
+      ::-webkit-scrollbar {
+        width: 9px;
+        height: 9px;
+      }
+      /*滚动条的设置*/
+      ::-webkit-scrollbar-thumb {
+        background-color: #dddddd;
+        background-clip: padding-box;
+        -webkit-border-radius: 2em;
+        -moz-border-radius: 2em;
+        border-radius: 2em;
+      }
+
+      /*滚动条鼠标移上去*/
+      ::-webkit-scrollbar-thumb:hover {
+        background-color: #bbb;
+      }
+
+      /*取消消息列表弹出框的内边距*/
+      .popover-self {
+        padding: 0 !important;
+      }
+
+      /*自定义颜色*/
+      #nprogress .bar {
+        background: #f58220 !important;
+      }
+
+      .selectworktime .el-dialog__header {
+        padding-top: 0;
+        padding-bottom: 0;
+      }
+      .selectworktime .el-dialog__body {
+        padding-top: 15px;
+      }
+      .el-dialog__headerbtn {
+        z-index: 2002;
+      }
+      .selecteorktime_datapick_popper {
+        left: 12vh !important;
+      }
+      .customsalary .el-input__inner {
+        height: 35px;
+        line-height: 35px;
+      }
+      .projectSelectPopperClass {
+        max-width: 1000px;
+      }
+      .projectSelectPopperClass li {
+        overflow: hidden;
+        white-space: nowrap;
+        text-overflow: ellipsis;
+      }
+      .projectSelectPopperClass .el-select-dropdown__item span:nth-child(1) {
+        font-size: 13px;
+        height: 34px;
+        max-width: 350px;
+      }
+      .projectSelectPopperClass .el-select-dropdown__item span:nth-child(2) {
+        font-size: 13px;
+        height: 34px;
+        max-width: 650px;
+
+        text-align: right;
+      }
+
+      /* 清除浮动 */
+      .clearfix:after {
+        content: "";
+        display: block;
+        height: 0;
+        clear: both;
+        visibility: hidden;
+      }
+      .clearfix {
+        /* 触发 hasLayout */
+        zoom: 1;
+      }
+      .fillWeekCustom {
+        .el-dialog__body {
+          padding: 10px 20px !important;
+        }
+      }
+    </style>
+  </head>
+  <!-- <script src="https://unpkg.com/vconsole/dist/vconsole.min.js"></script>
+    <script>
+        var vConsole = new window.VConsole();
+    </script> -->
+  <body>
+    <div id="app"></div>
+    <script>
+      document.body.ondrop = function (event) {
+        event.preventDefault();
+        event.stopPropagation();
+      };
+    </script>
+    <!-- 引入Vue.js -->
+    <script src="./static/js/vue.min.js"></script>
+    <!-- 引入vuex.js -->
+    <script src="./static/js/vuex.min.js"></script>
+    <!-- 引入vue-router -->
+    <script src="./static/js/vue-router.min.js"></script>
+    <!-- 引入组件库 -->
+    <script src="./static/js/element-ui.js"></script>
+    <!-- 引入echarts -->
+    <script src="./static/js/echarts.min.js"></script>
+  </body>
+</html>

+ 135 - 0
fhKeeper/formulahousekeeper/timesheet_mld/src/App.vue

@@ -0,0 +1,135 @@
+<template>
+	<div id="app">
+        <v-tour name="myTour" :steps="steps" :options="myOptions" :callbacks="myCallbacks" v-if="tourFlg"></v-tour>
+		<transition name="fade" mode="out-in">
+			<!-- <keep-alive>
+                <router-view v-if='$route.meta != null && $route.meta.keepAlive'/>
+            </keep-alive> -->
+            <router-view v-if="isRouterAlive"/>
+		</transition>
+
+        <themeCom :color="color" @color-update="colorChange" v-show="false" />
+	</div>
+</template>
+
+<script>
+    import themeCom from "@/components/themeCom";
+    export default {
+        name: 'app',
+        components: {
+            themeCom
+        },
+        //父组件中返回要传给下级的数据
+	  	provide() {
+	    	return {
+	     		reloads: this.reloads,
+    		}
+	  	},
+		data(){
+			return{
+				isRouterAlive:true,
+                firstTourFalse: false,
+                color: '#409EFF'
+			}
+		},
+        created() {
+            const windowsUrl = location.href
+            if(windowsUrl.indexOf('style=new') > 0) {
+                localStorage.setItem('themes', 'dark')
+            }
+            const themes = localStorage.getItem('themes') || 'default'
+            this.switchThemes(themes)
+        },
+        mounted() {
+            this.firstTourFalse = localStorage.getItem('firstTourFalse') | true
+            // 监听页面刷新事件
+			window.addEventListener('unload', this.setItemFirstTourFalse)
+        },
+		methods:{
+            switchThemes(type) {
+                const colorType = { 
+                    'default': '#409EFF',
+                    'dark': '#075985',
+                }
+                setTimeout(() => {
+                    this.colorChange(colorType[type])
+                }, 0)
+                if(type == 'dark') {
+                    document.title = '临床工时通'
+                }
+                window.document.documentElement.setAttribute( "data-theme", type );
+            },
+            colorChange(color) {
+                this.color = color;
+            },
+            setItemFirstTourFalse() {
+                localStorage.setItem('firstTourFalse', firstTourFalse)
+            },
+			reloads(){
+				this.isRouterAlive = false
+				this.$nextTick(() => {
+					this.isRouterAlive = true
+				})
+			}
+		}
+    }
+</script>
+<style>
+    .v-tour__target--highlighted {
+        box-shadow: 0 0 0 99999px rgba(0,0,0,.4) !important;
+    }
+    .el-tree-resetStyles .el-tree-node__content {
+        height: auto !important;
+    }
+</style>
+
+<style lang="scss">
+    body {
+        margin: 0px;
+        padding: 0px;
+        font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif;
+        font-size: 14px;
+        -webkit-font-smoothing: antialiased;
+    }
+
+    #app {
+        position: absolute;
+        top: 0px;
+        bottom: 0px;
+        width: 100%;
+    }
+
+    .el-submenu [class^=fa] {
+        vertical-align: baseline;
+        margin-right: 10px;
+    }
+
+    .el-menu-item [class^=fa] {
+        vertical-align: baseline;
+        margin-right: 10px;
+    }
+
+    .toolbar {
+        background: #f2f2f2;
+        padding: 10px;
+        .el-form-item {
+            margin-bottom: 10px;
+        }
+    }
+
+    .fade-enter-active,
+    .fade-leave-active {
+        transition: all .2s ease;
+    }
+
+    .fade-enter,
+    .fade-leave-active {
+        opacity: 0;
+    }
+
+    .resetElEmtClass {
+        .el-dialog__body {
+            padding: 0 !important;
+        }
+    }
+</style>

+ 17 - 0
fhKeeper/formulahousekeeper/timesheet_mld/src/api/api.js

@@ -0,0 +1,17 @@
+import axios from 'axios';
+
+let base = '';
+
+export const requestLogin = params => { return axios.post(`${base}/login`, params).then(res => res.data); };
+
+export const getUserList = params => { return axios.get(`${base}/user/list`, { params: params }); };
+
+export const getUserListPage = params => { return axios.get(`${base}/user/listpage`, { params: params }); };
+
+export const removeUser = params => { return axios.get(`${base}/user/remove`, { params: params }); };
+
+export const batchRemoveUser = params => { return axios.get(`${base}/user/batchremove`, { params: params }); };
+
+export const editUser = params => { return axios.get(`${base}/user/edit`, { params: params }); };
+
+export const addUser = params => { return axios.get(`${base}/user/add`, { params: params }); };

+ 3 - 0
fhKeeper/formulahousekeeper/timesheet_mld/src/api/index.js

@@ -0,0 +1,3 @@
+import * as api from './api';
+
+export default api;

ファイルの差分が大きいため隠しています
+ 1 - 0
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/citys/address.js


ファイルの差分が大きいため隠しています
+ 1 - 0
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/citys/shju.json


+ 539 - 0
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/iconfont/demo.css

@@ -0,0 +1,539 @@
+/* Logo 字体 */
+@font-face {
+  font-family: "iconfont logo";
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
+}
+
+.logo {
+  font-family: "iconfont logo";
+  font-size: 160px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+/* tabs */
+.nav-tabs {
+  position: relative;
+}
+
+.nav-tabs .nav-more {
+  position: absolute;
+  right: 0;
+  bottom: 0;
+  height: 42px;
+  line-height: 42px;
+  color: #666;
+}
+
+#tabs {
+  border-bottom: 1px solid #eee;
+}
+
+#tabs li {
+  cursor: pointer;
+  width: 100px;
+  height: 40px;
+  line-height: 40px;
+  text-align: center;
+  font-size: 16px;
+  border-bottom: 2px solid transparent;
+  position: relative;
+  z-index: 1;
+  margin-bottom: -1px;
+  color: #666;
+}
+
+
+#tabs .active {
+  border-bottom-color: #f00;
+  color: #222;
+}
+
+.tab-container .content {
+  display: none;
+}
+
+/* 页面布局 */
+.main {
+  padding: 30px 100px;
+  width: 960px;
+  margin: 0 auto;
+}
+
+.main .logo {
+  color: #333;
+  text-align: left;
+  margin-bottom: 30px;
+  line-height: 1;
+  height: 110px;
+  margin-top: -50px;
+  overflow: hidden;
+  *zoom: 1;
+}
+
+.main .logo a {
+  font-size: 160px;
+  color: #333;
+}
+
+.helps {
+  margin-top: 40px;
+}
+
+.helps pre {
+  padding: 20px;
+  margin: 10px 0;
+  border: solid 1px #e7e1cd;
+  background-color: #fffdef;
+  overflow: auto;
+}
+
+.icon_lists {
+  width: 100% !important;
+  overflow: hidden;
+  *zoom: 1;
+}
+
+.icon_lists li {
+  width: 100px;
+  margin-bottom: 10px;
+  margin-right: 20px;
+  text-align: center;
+  list-style: none !important;
+  cursor: default;
+}
+
+.icon_lists li .code-name {
+  line-height: 1.2;
+}
+
+.icon_lists .icon {
+  display: block;
+  height: 100px;
+  line-height: 100px;
+  font-size: 42px;
+  margin: 10px auto;
+  color: #333;
+  -webkit-transition: font-size 0.25s linear, width 0.25s linear;
+  -moz-transition: font-size 0.25s linear, width 0.25s linear;
+  transition: font-size 0.25s linear, width 0.25s linear;
+}
+
+.icon_lists .icon:hover {
+  font-size: 100px;
+}
+
+.icon_lists .svg-icon {
+  /* 通过设置 font-size 来改变图标大小 */
+  width: 1em;
+  /* 图标和文字相邻时,垂直对齐 */
+  vertical-align: -0.15em;
+  /* 通过设置 color 来改变 SVG 的颜色/fill */
+  fill: currentColor;
+  /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
+      normalize.css 中也包含这行 */
+  overflow: hidden;
+}
+
+.icon_lists li .name,
+.icon_lists li .code-name {
+  color: #666;
+}
+
+/* markdown 样式 */
+.markdown {
+  color: #666;
+  font-size: 14px;
+  line-height: 1.8;
+}
+
+.highlight {
+  line-height: 1.5;
+}
+
+.markdown img {
+  vertical-align: middle;
+  max-width: 100%;
+}
+
+.markdown h1 {
+  color: #404040;
+  font-weight: 500;
+  line-height: 40px;
+  margin-bottom: 24px;
+}
+
+.markdown h2,
+.markdown h3,
+.markdown h4,
+.markdown h5,
+.markdown h6 {
+  color: #404040;
+  margin: 1.6em 0 0.6em 0;
+  font-weight: 500;
+  clear: both;
+}
+
+.markdown h1 {
+  font-size: 28px;
+}
+
+.markdown h2 {
+  font-size: 22px;
+}
+
+.markdown h3 {
+  font-size: 16px;
+}
+
+.markdown h4 {
+  font-size: 14px;
+}
+
+.markdown h5 {
+  font-size: 12px;
+}
+
+.markdown h6 {
+  font-size: 12px;
+}
+
+.markdown hr {
+  height: 1px;
+  border: 0;
+  background: #e9e9e9;
+  margin: 16px 0;
+  clear: both;
+}
+
+.markdown p {
+  margin: 1em 0;
+}
+
+.markdown>p,
+.markdown>blockquote,
+.markdown>.highlight,
+.markdown>ol,
+.markdown>ul {
+  width: 80%;
+}
+
+.markdown ul>li {
+  list-style: circle;
+}
+
+.markdown>ul li,
+.markdown blockquote ul>li {
+  margin-left: 20px;
+  padding-left: 4px;
+}
+
+.markdown>ul li p,
+.markdown>ol li p {
+  margin: 0.6em 0;
+}
+
+.markdown ol>li {
+  list-style: decimal;
+}
+
+.markdown>ol li,
+.markdown blockquote ol>li {
+  margin-left: 20px;
+  padding-left: 4px;
+}
+
+.markdown code {
+  margin: 0 3px;
+  padding: 0 5px;
+  background: #eee;
+  border-radius: 3px;
+}
+
+.markdown strong,
+.markdown b {
+  font-weight: 600;
+}
+
+.markdown>table {
+  border-collapse: collapse;
+  border-spacing: 0px;
+  empty-cells: show;
+  border: 1px solid #e9e9e9;
+  width: 95%;
+  margin-bottom: 24px;
+}
+
+.markdown>table th {
+  white-space: nowrap;
+  color: #333;
+  font-weight: 600;
+}
+
+.markdown>table th,
+.markdown>table td {
+  border: 1px solid #e9e9e9;
+  padding: 8px 16px;
+  text-align: left;
+}
+
+.markdown>table th {
+  background: #F7F7F7;
+}
+
+.markdown blockquote {
+  font-size: 90%;
+  color: #999;
+  border-left: 4px solid #e9e9e9;
+  padding-left: 0.8em;
+  margin: 1em 0;
+}
+
+.markdown blockquote p {
+  margin: 0;
+}
+
+.markdown .anchor {
+  opacity: 0;
+  transition: opacity 0.3s ease;
+  margin-left: 8px;
+}
+
+.markdown .waiting {
+  color: #ccc;
+}
+
+.markdown h1:hover .anchor,
+.markdown h2:hover .anchor,
+.markdown h3:hover .anchor,
+.markdown h4:hover .anchor,
+.markdown h5:hover .anchor,
+.markdown h6:hover .anchor {
+  opacity: 1;
+  display: inline-block;
+}
+
+.markdown>br,
+.markdown>p>br {
+  clear: both;
+}
+
+
+.hljs {
+  display: block;
+  background: white;
+  padding: 0.5em;
+  color: #333333;
+  overflow-x: auto;
+}
+
+.hljs-comment,
+.hljs-meta {
+  color: #969896;
+}
+
+.hljs-string,
+.hljs-variable,
+.hljs-template-variable,
+.hljs-strong,
+.hljs-emphasis,
+.hljs-quote {
+  color: #df5000;
+}
+
+.hljs-keyword,
+.hljs-selector-tag,
+.hljs-type {
+  color: #a71d5d;
+}
+
+.hljs-literal,
+.hljs-symbol,
+.hljs-bullet,
+.hljs-attribute {
+  color: #0086b3;
+}
+
+.hljs-section,
+.hljs-name {
+  color: #63a35c;
+}
+
+.hljs-tag {
+  color: #333333;
+}
+
+.hljs-title,
+.hljs-attr,
+.hljs-selector-id,
+.hljs-selector-class,
+.hljs-selector-attr,
+.hljs-selector-pseudo {
+  color: #795da3;
+}
+
+.hljs-addition {
+  color: #55a532;
+  background-color: #eaffea;
+}
+
+.hljs-deletion {
+  color: #bd2c00;
+  background-color: #ffecec;
+}
+
+.hljs-link {
+  text-decoration: underline;
+}
+
+/* 代码高亮 */
+/* PrismJS 1.15.0
+https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
+/**
+ * prism.js default theme for JavaScript, CSS and HTML
+ * Based on dabblet (http://dabblet.com)
+ * @author Lea Verou
+ */
+code[class*="language-"],
+pre[class*="language-"] {
+  color: black;
+  background: none;
+  text-shadow: 0 1px white;
+  font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
+  text-align: left;
+  white-space: pre;
+  word-spacing: normal;
+  word-break: normal;
+  word-wrap: normal;
+  line-height: 1.5;
+
+  -moz-tab-size: 4;
+  -o-tab-size: 4;
+  tab-size: 4;
+
+  -webkit-hyphens: none;
+  -moz-hyphens: none;
+  -ms-hyphens: none;
+  hyphens: none;
+}
+
+pre[class*="language-"]::-moz-selection,
+pre[class*="language-"] ::-moz-selection,
+code[class*="language-"]::-moz-selection,
+code[class*="language-"] ::-moz-selection {
+  text-shadow: none;
+  background: #b3d4fc;
+}
+
+pre[class*="language-"]::selection,
+pre[class*="language-"] ::selection,
+code[class*="language-"]::selection,
+code[class*="language-"] ::selection {
+  text-shadow: none;
+  background: #b3d4fc;
+}
+
+@media print {
+
+  code[class*="language-"],
+  pre[class*="language-"] {
+    text-shadow: none;
+  }
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+  padding: 1em;
+  margin: .5em 0;
+  overflow: auto;
+}
+
+:not(pre)>code[class*="language-"],
+pre[class*="language-"] {
+  background: #f5f2f0;
+}
+
+/* Inline code */
+:not(pre)>code[class*="language-"] {
+  padding: .1em;
+  border-radius: .3em;
+  white-space: normal;
+}
+
+.token.comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+  color: slategray;
+}
+
+.token.punctuation {
+  color: #999;
+}
+
+.namespace {
+  opacity: .7;
+}
+
+.token.property,
+.token.tag,
+.token.boolean,
+.token.number,
+.token.constant,
+.token.symbol,
+.token.deleted {
+  color: #905;
+}
+
+.token.selector,
+.token.attr-name,
+.token.string,
+.token.char,
+.token.builtin,
+.token.inserted {
+  color: #690;
+}
+
+.token.operator,
+.token.entity,
+.token.url,
+.language-css .token.string,
+.style .token.string {
+  color: #9a6e3a;
+  background: hsla(0, 0%, 100%, .5);
+}
+
+.token.atrule,
+.token.attr-value,
+.token.keyword {
+  color: #07a;
+}
+
+.token.function,
+.token.class-name {
+  color: #DD4A68;
+}
+
+.token.regex,
+.token.important,
+.token.variable {
+  color: #e90;
+}
+
+.token.important,
+.token.bold {
+  font-weight: bold;
+}
+
+.token.italic {
+  font-style: italic;
+}
+
+.token.entity {
+  cursor: help;
+}

ファイルの差分が大きいため隠しています
+ 1798 - 0
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/iconfont/demo_index.html


+ 295 - 0
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/iconfont/iconfont.css

@@ -0,0 +1,295 @@
+@font-face {
+  font-family: "iconfont"; /* Project id 2390497 */
+  src: url('iconfont.woff2?t=1672729800404') format('woff2'),
+       url('iconfont.woff?t=1672729800404') format('woff'),
+       url('iconfont.ttf?t=1672729800404') format('truetype');
+}
+
+.iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+.firerock-icontuisong:before {
+  content: "\e625";
+}
+
+.firerock-iconhetong7:before {
+  content: "\e675";
+}
+
+.firerock-iconsync:before {
+  content: "\e6ca";
+}
+
+.firerock-iconliucheng1:before {
+  content: "\e700";
+}
+
+.firerock-icondakajilu:before {
+  content: "\e6e1";
+}
+
+.firerock-iconguanlian:before {
+  content: "\e674";
+}
+
+.firerock-iconusers:before {
+  content: "\e70a";
+}
+
+.firerock-iconquanxian1:before {
+  content: "\e615";
+}
+
+.firerock-iconxitong-:before {
+  content: "\e616";
+}
+
+.firerock-iconkehu:before {
+  content: "\e67e";
+}
+
+.firerock-iconwj-qjd:before {
+  content: "\e70e";
+}
+
+.firerock-icondaibanshixiang:before {
+  content: "\ec4e";
+}
+
+.firerock-icondaiban:before {
+  content: "\e64b";
+}
+
+.firerock-icongongshitongji:before {
+  content: "\e614";
+}
+
+.firerock-iconshenhetongguo:before {
+  content: "\e6a0";
+}
+
+.firerock-iconshenhebohui:before {
+  content: "\e6c6";
+}
+
+.firerock-icondaibandengdaishenhe:before {
+  content: "\e612";
+}
+
+.firerock-iconjianzhugongchenglei:before {
+  content: "\e61e";
+}
+
+.firerock-icongantetu:before {
+  content: "\e6a1";
+}
+
+.firerock-iconkehuguanli:before {
+  content: "\e60f";
+}
+
+.firerock-iconliucheng:before {
+  content: "\e634";
+}
+
+.firerock-iconright:before {
+  content: "\e60e";
+}
+
+.firerock-iconApp_New_Line:before {
+  content: "\e6e3";
+}
+
+.firerock-icon0:before {
+  content: "\e609";
+}
+
+.firerock-iconInsertLine:before {
+  content: "\e61d";
+}
+
+.firerock-iconmima:before {
+  content: "\e611";
+}
+
+.firerock-iconmima1:before {
+  content: "\e608";
+}
+
+.firerock-iconyanzhengma:before {
+  content: "\e60d";
+}
+
+.firerock-icondot:before {
+  content: "\e60b";
+}
+
+.firerock-icondot2:before {
+  content: "\e607";
+}
+
+.firerock-iconbaobiao:before {
+  content: "\e636";
+}
+
+.firerock-iconzuzhijiagou1:before {
+  content: "\e698";
+}
+
+.firerock-icontianbao1:before {
+  content: "\e60a";
+}
+
+.firerock-iconzuzhijiagou:before {
+  content: "\e606";
+}
+
+.firerock-iconzuzhijiegou:before {
+  content: "\e670";
+}
+
+.firerock-iconquanxian:before {
+  content: "\e663";
+}
+
+.firerock-iconbaoxiao:before {
+  content: "\e788";
+}
+
+.firerock-iconbaoxiaodan:before {
+  content: "\e644";
+}
+
+.firerock-icontianbao:before {
+  content: "\e726";
+}
+
+.firerock-iconrecord:before {
+  content: "\e605";
+}
+
+.firerock-icondaoru:before {
+  content: "\e613";
+}
+
+.firerock-icondaochu:before {
+  content: "\e6ab";
+}
+
+.firerock-iconexport:before {
+  content: "\e72d";
+}
+
+.firerock-iconqidong:before {
+  content: "\e63c";
+}
+
+.firerock-iconwancheng:before {
+  content: "\e610";
+}
+
+.firerock-iconcaidan:before {
+  content: "\e6b7";
+}
+
+.firerock-iconshenhe:before {
+  content: "\e604";
+}
+
+.firerock-iconicon-:before {
+  content: "\e6ad";
+}
+
+.firerock-iconrenwu:before {
+  content: "\e64c";
+}
+
+.firerock-iconfengxian:before {
+  content: "\e6a2";
+}
+
+.firerock-iconnormal-ico-ok:before {
+  content: "\e70f";
+}
+
+.firerock-iconicon2:before {
+  content: "\e603";
+}
+
+.firerock-iconfile:before {
+  content: "\e60c";
+}
+
+.firerock-iconex:before {
+  content: "\e65c";
+}
+
+.firerock-iconZip:before {
+  content: "\e9ec";
+}
+
+.firerock-iconJPG:before {
+  content: "\e6ed";
+}
+
+.firerock-iconaudio:before {
+  content: "\e602";
+}
+
+.firerock-icontxt:before {
+  content: "\e741";
+}
+
+.firerock-iconvideo:before {
+  content: "\e771";
+}
+
+.firerock-iconPDF:before {
+  content: "\e61a";
+}
+
+.firerock-iconword:before {
+  content: "\eecf";
+}
+
+.firerock-iconshangchuan:before {
+  content: "\e6fd";
+}
+
+.firerock-iconmiaobiao:before {
+  content: "\ecfa";
+}
+
+.firerock-icontask:before {
+  content: "\e600";
+}
+
+.firerock-iconmeditor-time:before {
+  content: "\e601";
+}
+
+.firerock-icontree:before {
+  content: "\e691";
+}
+
+.firerock-icontongji:before {
+  content: "\e631";
+}
+
+.firerock-iconxiangmu:before {
+  content: "\e617";
+}
+
+.firerock-iconcaiwu:before {
+  content: "\e89c";
+}
+
+.firerock-iconsetting:before {
+  content: "\e672";
+}
+

BIN
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/iconfont/iconfont.eot


ファイルの差分が大きいため隠しています
+ 1 - 0
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/iconfont/iconfont.js


+ 499 - 0
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/iconfont/iconfont.json

@@ -0,0 +1,499 @@
+{
+  "id": "2390497",
+  "name": "seyaproject",
+  "font_family": "iconfont",
+  "css_prefix_text": "firerock-icon",
+  "description": "",
+  "glyphs": [
+    {
+      "icon_id": "10936691",
+      "name": "推送",
+      "font_class": "tuisong",
+      "unicode": "e625",
+      "unicode_decimal": 58917
+    },
+    {
+      "icon_id": "774469",
+      "name": "合同7",
+      "font_class": "hetong7",
+      "unicode": "e675",
+      "unicode_decimal": 58997
+    },
+    {
+      "icon_id": "5832808",
+      "name": "sync",
+      "font_class": "sync",
+      "unicode": "e6ca",
+      "unicode_decimal": 59082
+    },
+    {
+      "icon_id": "6970024",
+      "name": "流程",
+      "font_class": "liucheng1",
+      "unicode": "e700",
+      "unicode_decimal": 59136
+    },
+    {
+      "icon_id": "15673407",
+      "name": "打卡记录",
+      "font_class": "dakajilu",
+      "unicode": "e6e1",
+      "unicode_decimal": 59105
+    },
+    {
+      "icon_id": "5651484",
+      "name": "关联",
+      "font_class": "guanlian",
+      "unicode": "e674",
+      "unicode_decimal": 58996
+    },
+    {
+      "icon_id": "14949575",
+      "name": "users",
+      "font_class": "users",
+      "unicode": "e70a",
+      "unicode_decimal": 59146
+    },
+    {
+      "icon_id": "736503",
+      "name": "权限",
+      "font_class": "quanxian1",
+      "unicode": "e615",
+      "unicode_decimal": 58901
+    },
+    {
+      "icon_id": "7987507",
+      "name": "系统",
+      "font_class": "xitong-",
+      "unicode": "e616",
+      "unicode_decimal": 58902
+    },
+    {
+      "icon_id": "11111002",
+      "name": "客户",
+      "font_class": "kehu",
+      "unicode": "e67e",
+      "unicode_decimal": 59006
+    },
+    {
+      "icon_id": "6517457",
+      "name": "文件-请假单",
+      "font_class": "wj-qjd",
+      "unicode": "e70e",
+      "unicode_decimal": 59150
+    },
+    {
+      "icon_id": "5961300",
+      "name": "待办事项",
+      "font_class": "daibanshixiang",
+      "unicode": "ec4e",
+      "unicode_decimal": 60494
+    },
+    {
+      "icon_id": "11465003",
+      "name": "待办",
+      "font_class": "daiban",
+      "unicode": "e64b",
+      "unicode_decimal": 58955
+    },
+    {
+      "icon_id": "6023953",
+      "name": "工时统计",
+      "font_class": "gongshitongji",
+      "unicode": "e614",
+      "unicode_decimal": 58900
+    },
+    {
+      "icon_id": "2318254",
+      "name": "审核通过",
+      "font_class": "shenhetongguo",
+      "unicode": "e6a0",
+      "unicode_decimal": 59040
+    },
+    {
+      "icon_id": "9144552",
+      "name": "审核驳回",
+      "font_class": "shenhebohui",
+      "unicode": "e6c6",
+      "unicode_decimal": 59078
+    },
+    {
+      "icon_id": "17483402",
+      "name": "待办  等待 审核",
+      "font_class": "daibandengdaishenhe",
+      "unicode": "e612",
+      "unicode_decimal": 58898
+    },
+    {
+      "icon_id": "5149104",
+      "name": "建筑工程类",
+      "font_class": "jianzhugongchenglei",
+      "unicode": "e61e",
+      "unicode_decimal": 58910
+    },
+    {
+      "icon_id": "16187171",
+      "name": "甘特图",
+      "font_class": "gantetu",
+      "unicode": "e6a1",
+      "unicode_decimal": 59041
+    },
+    {
+      "icon_id": "3686260",
+      "name": "客户管理",
+      "font_class": "kehuguanli",
+      "unicode": "e60f",
+      "unicode_decimal": 58895
+    },
+    {
+      "icon_id": "1868952",
+      "name": "流程",
+      "font_class": "liucheng",
+      "unicode": "e634",
+      "unicode_decimal": 58932
+    },
+    {
+      "icon_id": "9651039",
+      "name": "长箭头",
+      "font_class": "right",
+      "unicode": "e60e",
+      "unicode_decimal": 58894
+    },
+    {
+      "icon_id": "17223736",
+      "name": "App_New_Line",
+      "font_class": "App_New_Line",
+      "unicode": "e6e3",
+      "unicode_decimal": 59107
+    },
+    {
+      "icon_id": "261001",
+      "name": "line",
+      "font_class": "0",
+      "unicode": "e609",
+      "unicode_decimal": 58889
+    },
+    {
+      "icon_id": "17197893",
+      "name": "Insert Line",
+      "font_class": "InsertLine",
+      "unicode": "e61d",
+      "unicode_decimal": 58909
+    },
+    {
+      "icon_id": "19410111",
+      "name": "密 码",
+      "font_class": "mima",
+      "unicode": "e611",
+      "unicode_decimal": 58897
+    },
+    {
+      "icon_id": "16842350",
+      "name": "密 码",
+      "font_class": "mima1",
+      "unicode": "e608",
+      "unicode_decimal": 58888
+    },
+    {
+      "icon_id": "20915138",
+      "name": "验证码",
+      "font_class": "yanzhengma",
+      "unicode": "e60d",
+      "unicode_decimal": 58893
+    },
+    {
+      "icon_id": "11640993",
+      "name": "dot",
+      "font_class": "dot",
+      "unicode": "e60b",
+      "unicode_decimal": 58891
+    },
+    {
+      "icon_id": "9382963",
+      "name": "dot",
+      "font_class": "dot2",
+      "unicode": "e607",
+      "unicode_decimal": 58887
+    },
+    {
+      "icon_id": "7171606",
+      "name": "报表管理",
+      "font_class": "baobiao",
+      "unicode": "e636",
+      "unicode_decimal": 58934
+    },
+    {
+      "icon_id": "4426098",
+      "name": "组织架构",
+      "font_class": "zuzhijiagou1",
+      "unicode": "e698",
+      "unicode_decimal": 59032
+    },
+    {
+      "icon_id": "13100227",
+      "name": "填报",
+      "font_class": "tianbao1",
+      "unicode": "e60a",
+      "unicode_decimal": 58890
+    },
+    {
+      "icon_id": "4469651",
+      "name": "组织架构",
+      "font_class": "zuzhijiagou",
+      "unicode": "e606",
+      "unicode_decimal": 58886
+    },
+    {
+      "icon_id": "4231111",
+      "name": "组织结构",
+      "font_class": "zuzhijiegou",
+      "unicode": "e670",
+      "unicode_decimal": 58992
+    },
+    {
+      "icon_id": "12860884",
+      "name": "权限",
+      "font_class": "quanxian",
+      "unicode": "e663",
+      "unicode_decimal": 58979
+    },
+    {
+      "icon_id": "2101853",
+      "name": "报销",
+      "font_class": "baoxiao",
+      "unicode": "e788",
+      "unicode_decimal": 59272
+    },
+    {
+      "icon_id": "5207594",
+      "name": "报销单",
+      "font_class": "baoxiaodan",
+      "unicode": "e644",
+      "unicode_decimal": 58948
+    },
+    {
+      "icon_id": "19236386",
+      "name": "填报",
+      "font_class": "tianbao",
+      "unicode": "e726",
+      "unicode_decimal": 59174
+    },
+    {
+      "icon_id": "12000587",
+      "name": "记录",
+      "font_class": "record",
+      "unicode": "e605",
+      "unicode_decimal": 58885
+    },
+    {
+      "icon_id": "20147073",
+      "name": "导入",
+      "font_class": "daoru",
+      "unicode": "e613",
+      "unicode_decimal": 58899
+    },
+    {
+      "icon_id": "20154661",
+      "name": "导出",
+      "font_class": "daochu",
+      "unicode": "e6ab",
+      "unicode_decimal": 59051
+    },
+    {
+      "icon_id": "19441448",
+      "name": "export",
+      "font_class": "export",
+      "unicode": "e72d",
+      "unicode_decimal": 59181
+    },
+    {
+      "icon_id": "8796451",
+      "name": "启动",
+      "font_class": "qidong",
+      "unicode": "e63c",
+      "unicode_decimal": 58940
+    },
+    {
+      "icon_id": "19037188",
+      "name": "完 成 ",
+      "font_class": "wancheng",
+      "unicode": "e610",
+      "unicode_decimal": 58896
+    },
+    {
+      "icon_id": "20134686",
+      "name": "菜单",
+      "font_class": "caidan",
+      "unicode": "e6b7",
+      "unicode_decimal": 59063
+    },
+    {
+      "icon_id": "8524192",
+      "name": "审核",
+      "font_class": "shenhe",
+      "unicode": "e604",
+      "unicode_decimal": 58884
+    },
+    {
+      "icon_id": "3590688",
+      "name": "里程碑",
+      "font_class": "icon-",
+      "unicode": "e6ad",
+      "unicode_decimal": 59053
+    },
+    {
+      "icon_id": "5112963",
+      "name": "任务",
+      "font_class": "renwu",
+      "unicode": "e64c",
+      "unicode_decimal": 58956
+    },
+    {
+      "icon_id": "10368440",
+      "name": "风险",
+      "font_class": "fengxian",
+      "unicode": "e6a2",
+      "unicode_decimal": 59042
+    },
+    {
+      "icon_id": "17156568",
+      "name": "ok",
+      "font_class": "normal-ico-ok",
+      "unicode": "e70f",
+      "unicode_decimal": 59151
+    },
+    {
+      "icon_id": "1161198",
+      "name": "棱形",
+      "font_class": "icon2",
+      "unicode": "e603",
+      "unicode_decimal": 58883
+    },
+    {
+      "icon_id": "10202911",
+      "name": "file",
+      "font_class": "file",
+      "unicode": "e60c",
+      "unicode_decimal": 58892
+    },
+    {
+      "icon_id": "2078615",
+      "name": "excel",
+      "font_class": "ex",
+      "unicode": "e65c",
+      "unicode_decimal": 58972
+    },
+    {
+      "icon_id": "4073514",
+      "name": "Zip",
+      "font_class": "Zip",
+      "unicode": "e9ec",
+      "unicode_decimal": 59884
+    },
+    {
+      "icon_id": "4863362",
+      "name": "JPG",
+      "font_class": "JPG",
+      "unicode": "e6ed",
+      "unicode_decimal": 59117
+    },
+    {
+      "icon_id": "5173010",
+      "name": "audio",
+      "font_class": "audio",
+      "unicode": "e602",
+      "unicode_decimal": 58882
+    },
+    {
+      "icon_id": "8469709",
+      "name": "txt",
+      "font_class": "txt",
+      "unicode": "e741",
+      "unicode_decimal": 59201
+    },
+    {
+      "icon_id": "19705514",
+      "name": "video",
+      "font_class": "video",
+      "unicode": "e771",
+      "unicode_decimal": 59249
+    },
+    {
+      "icon_id": "20213818",
+      "name": "PDF",
+      "font_class": "PDF",
+      "unicode": "e61a",
+      "unicode_decimal": 58906
+    },
+    {
+      "icon_id": "20651005",
+      "name": "word",
+      "font_class": "word",
+      "unicode": "eecf",
+      "unicode_decimal": 61135
+    },
+    {
+      "icon_id": "17781647",
+      "name": "上 传",
+      "font_class": "shangchuan",
+      "unicode": "e6fd",
+      "unicode_decimal": 59133
+    },
+    {
+      "icon_id": "7337849",
+      "name": "秒表",
+      "font_class": "miaobiao",
+      "unicode": "ecfa",
+      "unicode_decimal": 60666
+    },
+    {
+      "icon_id": "8659928",
+      "name": "task",
+      "font_class": "task",
+      "unicode": "e600",
+      "unicode_decimal": 58880
+    },
+    {
+      "icon_id": "13530978",
+      "name": "time",
+      "font_class": "meditor-time",
+      "unicode": "e601",
+      "unicode_decimal": 58881
+    },
+    {
+      "icon_id": "9339879",
+      "name": "tree",
+      "font_class": "tree",
+      "unicode": "e691",
+      "unicode_decimal": 59025
+    },
+    {
+      "icon_id": "807967",
+      "name": "统计",
+      "font_class": "tongji",
+      "unicode": "e631",
+      "unicode_decimal": 58929
+    },
+    {
+      "icon_id": "1778691",
+      "name": "项目",
+      "font_class": "xiangmu",
+      "unicode": "e617",
+      "unicode_decimal": 58903
+    },
+    {
+      "icon_id": "14417643",
+      "name": "财务",
+      "font_class": "caiwu",
+      "unicode": "e89c",
+      "unicode_decimal": 59548
+    },
+    {
+      "icon_id": "11673579",
+      "name": "setting",
+      "font_class": "setting",
+      "unicode": "e672",
+      "unicode_decimal": 58994
+    }
+  ]
+}

ファイルの差分が大きいため隠しています
+ 53 - 0
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/iconfont/iconfont.svg


BIN
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/iconfont/iconfont.ttf


BIN
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/iconfont/iconfont.woff


BIN
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/iconfont/iconfont.woff2


BIN
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/404.png


BIN
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/Step1.jpg


BIN
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/Step2.jpg


BIN
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/Step3.jpg


BIN
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/aacbc.png


BIN
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/background.png


BIN
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/close.gif


BIN
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/code.jpg


BIN
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/dui.png


BIN
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/hanglie.png


BIN
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/hanglie_corp.png


BIN
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/hangs.png


BIN
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/head_logo.png


BIN
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/hong.png


+ 0 - 0
fhKeeper/formulahousekeeper/timesheet_mld/src/assets/image/huang.png


この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません