Преглед изворни кода

Merge remote-tracking branch 'origin/master'

yusm пре 1 година
родитељ
комит
feab75b530
55 измењених фајлова са 2816 додато и 314 уклоњено
  1. 4 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/api.ts
  2. 174 2
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/index.vue
  3. 3 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/FeishuInfoController.java
  4. 21 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ParticipationApprovalController.java
  5. 21 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectApprovalAuditorController.java
  6. 39 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectApprovalBasecostController.java
  7. 154 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectApprovalController.java
  8. 9 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java
  9. 7 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/Company.java
  10. 55 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ParticipationApproval.java
  11. 262 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ProjectApproval.java
  12. 54 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ProjectApprovalAuditor.java
  13. 60 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ProjectApprovalBasecost.java
  14. 7 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/SysModule.java
  15. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ParticipationApprovalMapper.java
  16. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ProjectApprovalAuditorMapper.java
  17. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ProjectApprovalBasecostMapper.java
  18. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ProjectApprovalMapper.java
  19. 10 4
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ReportMapper.java
  20. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ParticipationApprovalService.java
  21. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ProjectApprovalAuditorService.java
  22. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ProjectApprovalBasecostService.java
  23. 22 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ProjectApprovalService.java
  24. 3 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ReportService.java
  25. 20 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ParticipationApprovalServiceImpl.java
  26. 3 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/PermissionServiceImpl.java
  27. 20 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectApprovalAuditorServiceImpl.java
  28. 20 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectApprovalBasecostServiceImpl.java
  29. 84 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectApprovalServiceImpl.java
  30. 0 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java
  31. 88 46
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  32. 3 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/UserServiceImpl.java
  33. 2 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/CompanyMapper.xml
  34. 17 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ParticipationApprovalMapper.xml
  35. 18 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectApprovalAuditorMapper.xml
  36. 19 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectApprovalBasecostMapper.xml
  37. 48 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectApprovalMapper.xml
  38. 70 41
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportMapper.xml
  39. 2 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/SysModuleMapper.xml
  40. 11 1
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/entity/ProdProcedure.java
  41. 1 1
      fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/service/impl/ProdProcedureServiceImpl.java
  42. 9 5
      fhKeeper/formulahousekeeper/management-workshop/src/main/resources/mapper/ProdProcedureMapper.xml
  43. 15 4
      fhKeeper/formulahousekeeper/timesheet-workshop/src/views/product/list.vue
  44. 50 0
      fhKeeper/formulahousekeeper/timesheet/src/http.js
  45. 1 0
      fhKeeper/formulahousekeeper/timesheet/src/i18n/en.json
  46. 1 0
      fhKeeper/formulahousekeeper/timesheet/src/i18n/zh.json
  47. 15 0
      fhKeeper/formulahousekeeper/timesheet/src/permissions.js
  48. 15 0
      fhKeeper/formulahousekeeper/timesheet/src/routes.js
  49. 5 2
      fhKeeper/formulahousekeeper/timesheet/src/views/expense/expense.vue
  50. 1 1
      fhKeeper/formulahousekeeper/timesheet/src/views/project/list.vue
  51. 992 0
      fhKeeper/formulahousekeeper/timesheet/src/views/projectApproval/projectApproval.vue
  52. 70 30
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue
  53. 3 3
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/my/children/center.vue
  54. 1 1
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/project/index.vue
  55. 195 165
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/view/index.vue

+ 4 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/api.ts

@@ -0,0 +1,4 @@
+export const MOD = '/business'
+export const prefix = '/clue'
+export const GETSYSFILED = '/sys-dict/getListByCode'
+export const GETPERSONNEL = '/user/getSimpleActiveUserList'

+ 174 - 2
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/index.vue

@@ -1,11 +1,183 @@
 <template>
-  <div>
-    business
+  <div class="h-full flex">
+    <div class="p-5 w-80 pr-0">
+      <div class="bg-white w-full h-full shadow-md rounded-md flex flex-col">
+        <div class="flex-1 p-3 overflow-y-auto">
+          <el-form :model="businessOpportunityForm" label-width="70px" style="max-width: 600px">
+            <el-form-item label="商机名称">
+              <el-input v-model="businessOpportunityForm.name" clearable placeholder="请输入"></el-input>
+            </el-form-item>
+            <el-form-item label="商机阶段">
+              <el-select v-model="businessOpportunityForm.stageId" placeholder="请选择">
+                <el-option v-for="item in fixedData.BusinessStage" :key="item.id" :label="item.name" :value="item.id" />
+              </el-select>
+            </el-form-item>
+            <el-form-item label="客户名称">
+              <el-input v-model="businessOpportunityForm.customerName" clearable placeholder="请输入"></el-input>
+            </el-form-item>
+            <el-form-item label="联系人">
+              <el-input v-model="businessOpportunityForm.contactPerson" clearable placeholder="请输入"></el-input>
+            </el-form-item>
+            <el-form-item label="产品">
+              <el-select v-model="businessOpportunityForm.product" placeholder="请选择">
+                <el-option v-for="item in fixedData.Personnel" :key="item.id" :label="item.name" :value="item.id" />
+              </el-select>
+            </el-form-item>
+            <el-form-item label="负责人">
+              <el-select v-model="businessOpportunityForm.inchargerId" placeholder="请选择">
+                <el-option v-for="item in fixedData.Personnel" :key="item.id" :label="item.name" :value="item.id" />
+              </el-select>
+            </el-form-item>
+            <el-form-item label="创建时间">
+              <el-date-picker v-model="businessOpportunityForm.startTime" type="date" placeholder="请选择" :clearable="false"
+                format="YYYY-MM-DD" value-format="YYYY-MM-DD" />
+            </el-form-item>
+            <el-form-item label="">
+              <el-date-picker v-model="businessOpportunityForm.endTime" type="date" placeholder="请选择" :clearable="false"
+                format="YYYY-MM-DD" value-format="YYYY-MM-DD" />
+            </el-form-item>
+          </el-form>
+        </div>
+        <div class="w-full flex p-3 shadow-[0_-3px_5px_0px_rgba(0,0,0,0.2)]">
+          <El-button class="w-full">重置</El-Button>
+          <El-button type="primary" class="w-full">搜索</El-Button>
+        </div>
+      </div>
+    </div>
+    <div class="flex-1 p-5 overflow-auto">
+      <div class="bg-white w-full h-full p-3 shadow-md rounded-md flex flex-col">
+        <div class="flex justify-end pb-3">
+          <el-button type="primary">新建商机</el-button>
+          <el-button type="primary">批量转移</el-button>
+          <el-button type="primary">批量删除</el-button>
+          <el-button type="primary">导入</el-button>
+          <el-button type="primary">导出</el-button>
+        </div>
+        <div class="flex-1 w-full overflow-hidden">
+          <el-table ref="clueTableRef" :data="businessTable" border v-loading="allLoading.businessTableLading"
+            style="width: 100%;height: 100%;">
+            <el-table-column type="selection" width="55" />
+            <el-table-column prop="name" label="商机名称" width="180">
+              <template #default="scope">
+                <el-button link type="primary" size="large">{{
+                  scope.row.name
+                }}</el-button>
+              </template>
+            </el-table-column>
+            <el-table-column prop="clueSourceId" label="客户名称" width="180"></el-table-column>
+            <el-table-column prop="phone" label="联系人" width="180">
+              <template #default="scope">
+                <el-button link type="primary" size="large">{{
+                  scope.row.phone
+                }}</el-button>
+              </template>
+            </el-table-column>
+            <el-table-column prop="email" label="商机金额" width="180"></el-table-column>
+            <el-table-column prop="customerIndustryId" label="商机阶段" width="180"></el-table-column>
+            <el-table-column prop="customerLevelId" label="预计成交" width="180"></el-table-column>
+            <el-table-column prop="inchargerId" label="负责人" width="180"></el-table-column>
+            <el-table-column prop="createName" label="创建人" width="180"></el-table-column>
+            <el-table-column prop="createTime" label="创建时间" width="180"></el-table-column>
+            <el-table-column label="操作" fixed="right" width="200">
+              <template #default="scope">
+                <el-button link type="primary" size="large">编辑</el-button>
+                <el-button link type="primary" size="large">新建任务</el-button>
+                <el-button link type="danger" size="large">删除</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+        <div class="flex justify-end pt-3">
+          <el-pagination layout="total, prev, pager, next, sizes" :total="businessTotalTable"
+            :hide-on-single-page="true" />
+        </div>
+      </div>
+    </div>
   </div>
 </template>
 
 <script lang="ts" setup>
+import { ref, reactive, onMounted, inject } from "vue";
+import { GETSYSFILED, MOD, GETPERSONNEL } from './api'
+import { post, get } from "@/utils/request";
+import { getAllListByCode, getFromValue, resetFromValue, getFirstDayOfMonth, getLastDayOfMonth, formatDate } from '@/utils/tools'
 
+// 定义类型
+interface businessOpportunityFormType { // 线索筛选条件类型
+  name: string,
+  stageId: string | number,
+  customerName: string,
+  contactPerson: string,
+  product: string | number,
+  inchargerId: string | number,
+  startTime: string | number,
+  endTime: string | number,
+  pageIndex: string | number,
+  pageFrom: string | number
+}
+
+interface fixedDataInterface {
+  id: string | number,
+  companyId: string | number,
+  code: string,
+  name: string,
+  seq: string | number,
+}
+
+interface personnelInterface {
+  id: string | number,
+  name: string,
+  phone: string,
+  jobNumber: string
+}
+
+const businessTotalTable = ref(0)
+const businessTable = ref([
+  {name: '商机040101',phone: '张山'}
+])
+const allLoading = reactive({
+  businessTableLading: false
+})
+const businessOpportunityForm = reactive<businessOpportunityFormType>({
+  name: '',
+  stageId: '',
+  customerName: '',
+  contactPerson: '',
+  product: '',
+  inchargerId: '',
+  startTime: getFirstDayOfMonth(new Date()),
+  endTime: formatDate(new Date()),
+  pageIndex: 1,
+  pageFrom: 10
+})
+const fixedData = reactive({
+  BusinessStage: [] as fixedDataInterface[],
+  Personnel: [] as personnelInterface[]
+})
+
+async function getSystemField() {
+  const systemField = getAllListByCode(['商机阶段'])
+  for (let i in systemField) {
+    const { data } = await get(`${GETSYSFILED}?code=${systemField[i]}`)
+    for (let key of Object.keys(fixedData)) {
+      if (systemField[i] == key) {
+        Object.assign(fixedData, { [key]: data })
+      }
+    }
+  }
+
+  const { data } = await post(GETPERSONNEL, {})
+  fixedData.Personnel = data.map((item: any) => {
+    const { id, name, phone, jobNumber } = item
+    return {
+      id, name, phone, jobNumber
+    }
+  })
+}
+
+onMounted(() => {
+  getSystemField()
+})
 </script>
 
 <style lang="scss" scoped></style>

+ 3 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/FeishuInfoController.java

@@ -470,6 +470,9 @@ public class FeishuInfoController {
         if (company.getPackageProvider() == 1) {
             queryWrapper.or().eq("package_provider", 1);
         }
+        if (company.getPackageProjectApproval() == 1) {
+            queryWrapper.or().eq("package_project_approval", 1);
+        }
         if (timeType.getReportWorkflow() == 1) {
             queryWrapper.or().eq("report_workflow", 1);
         }

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ParticipationApprovalController.java

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 人员参与项目的情况 前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-03-18
+ */
+@RestController
+@RequestMapping("/participation-approval")
+public class ParticipationApprovalController {
+
+}
+

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectApprovalAuditorController.java

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-03-18
+ */
+@RestController
+@RequestMapping("/project-approval-auditor")
+public class ProjectApprovalAuditorController {
+
+}
+

+ 39 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectApprovalBasecostController.java

@@ -0,0 +1,39 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.management.platform.entity.ProjectApprovalBasecost;
+import com.management.platform.service.ProjectApprovalBasecostService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-03-18
+ */
+@RestController
+@RequestMapping("/project-approval-basecost")
+public class ProjectApprovalBasecostController {
+
+    @Resource
+    private ProjectApprovalBasecostService projectApprovalBasecostService;
+
+    @RequestMapping("/get")
+    public HttpRespMsg get(Integer projectId){
+        HttpRespMsg msg=new HttpRespMsg();
+        List<ProjectApprovalBasecost> list = projectApprovalBasecostService.list(new LambdaQueryWrapper<ProjectApprovalBasecost>().eq(ProjectApprovalBasecost::getProjectApprovalId, projectId));
+        msg.setData(list);
+        return msg;
+    }
+
+}
+

+ 154 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectApprovalController.java

@@ -0,0 +1,154 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.management.platform.entity.*;
+import com.management.platform.mapper.ProjectMapper;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.service.*;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.RequestBody;
+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;
+import java.time.LocalDate;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-03-18
+ */
+@RestController
+@RequestMapping("/project-approval")
+public class ProjectApprovalController {
+
+    @Resource
+    private ProjectApprovalService projectApprovalService;
+    @Resource
+    private UserMapper userMapper;
+    @Resource
+    private HttpServletRequest request;
+    @Resource
+    private ProjectMapper projectMapper;
+    @Resource
+    private ParticipationApprovalService participationApprovalService;
+    @Resource
+    private ProjectApprovalAuditorService projectApprovalAuditorService;
+    @Resource
+    private ProjectApprovalBasecostService projectApprovalBasecostService;
+    @Resource
+    private ProjectCategoryService projectCategoryService;
+
+    /**
+     * 分页获取项目列表
+     * pageIndex 页数
+     * pageSize 页面大小
+     */
+    @RequestMapping("/listByPage")
+    public HttpRespMsg getProjectPage(@RequestParam Integer pageIndex, @RequestParam Integer pageSize, String keyword,
+                                      @RequestParam(required = false, defaultValue = "1") Integer searchField,@RequestParam(defaultValue = "3") String statuses,Integer category) {
+        return projectApprovalService.listByPage(pageIndex, pageSize, keyword,searchField,statuses,category,request);
+    }
+
+    @RequestMapping("/editProjectApproval")
+    @Transactional(rollbackFor = Exception.class)
+    public HttpRespMsg editProjectApproval(@RequestBody ProjectApproval projectApproval) {
+        HttpRespMsg msg=new HttpRespMsg();
+        User user = userMapper.selectById(request.getHeader("token"));
+        Integer companyId = user.getCompanyId();
+        List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getCompanyId, companyId));
+        List<ProjectCategory> categoryList = projectCategoryService.list(new LambdaQueryWrapper<ProjectCategory>().eq(ProjectCategory::getCompanyId, companyId));
+        projectApproval.setCompanyId(companyId);
+        projectApproval.setCreateDate(LocalDate.now());
+        projectApproval.setCreatorId(user.getId());
+        Optional<ProjectCategory> category = categoryList.stream().filter(c -> c.getId().equals(projectApproval.getCategory())).findFirst();
+        if(category.isPresent()){
+            projectApproval.setCategoryName(category.get().getName());
+        }
+        Integer count;
+        if(projectApproval.getId()==null){
+            count = projectMapper.selectCount(new LambdaQueryWrapper<Project>().eq(Project::getCompanyId, companyId).eq(Project::getProjectCode, projectApproval.getProjectCode()));
+        }else {
+            count = projectMapper.selectCount(new LambdaQueryWrapper<Project>().ne(Project::getId,projectApproval.getId()).eq(Project::getCompanyId, companyId).eq(Project::getProjectCode,  projectApproval.getProjectCode()));
+        }
+        if(count>0){
+            msg.setError("已存在项目编号为["+projectApproval.getProjectCode()+"]的项目");
+            return msg;
+        }
+        if(!projectApprovalService.saveOrUpdate(projectApproval)){
+            msg.setError("验证失败");
+        }
+        participationApprovalService.remove(new LambdaQueryWrapper<ParticipationApproval>().eq(ParticipationApproval::getProjectApprovalId,projectApproval.getId()));
+        projectApprovalBasecostService.remove(new LambdaQueryWrapper<ProjectApprovalBasecost>().eq(ProjectApprovalBasecost::getProjectApprovalId,projectApproval.getId()));
+        projectApprovalAuditorService.remove(new LambdaQueryWrapper<ProjectApprovalAuditor>().eq(ProjectApprovalAuditor::getProjectApprovalId,projectApproval.getId()));
+        if(projectApproval.getParticipationApprovalList()!=null&&projectApproval.getParticipationApprovalList().size()>0){
+            List<ParticipationApproval> participationApprovalList = projectApproval.getParticipationApprovalList();
+            participationApprovalList.forEach(p->{
+                p.setProjectApprovalId(projectApproval.getId());
+                Optional<User> first = userList.stream().filter(u -> u.getId().equals(p.getUserId())).findFirst();
+                if(first.isPresent()){
+                    p.setUserName(first.get().getName());
+                }
+            });
+            participationApprovalService.saveBatch(participationApprovalList);
+        }
+        if(projectApproval.getProjectApprovalBasecostList()!=null&&projectApproval.getProjectApprovalBasecostList().size()>0){
+            List<ProjectApprovalBasecost> projectApprovalBasecostList = projectApproval.getProjectApprovalBasecostList();
+            projectApprovalBasecostList.forEach(p->{
+                p.setProjectApprovalId(projectApproval.getId());
+            });
+            projectApprovalBasecostService.saveBatch(projectApprovalBasecostList);
+        }
+        if(projectApproval.getProjectApprovalAuditorList()!=null&&projectApproval.getProjectApprovalAuditorList().size()>0){
+            List<ProjectApprovalAuditor> projectApprovalAuditorList = projectApproval.getProjectApprovalAuditorList();
+            projectApprovalAuditorList.forEach(p->{
+                p.setProjectApprovalId(projectApproval.getId());
+                Optional<User> first = userList.stream().filter(u -> u.getId().equals(p.getAuditorId())).findFirst();
+                if(first.isPresent()){
+                    p.setAuditorName(first.get().getName());
+                }
+            });
+            projectApprovalAuditorService.saveBatch(projectApprovalAuditorList);
+        }
+        return msg;
+    }
+
+
+    @RequestMapping("/getDetail")
+    public HttpRespMsg getDetail(Integer id){
+        HttpRespMsg msg=new HttpRespMsg();
+        Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();
+        List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getCompanyId, companyId));
+        ProjectApproval projectApproval = projectApprovalService.getById(id);
+        Optional<User> first = userList.stream().filter(u -> u.getId().equals(projectApproval.getInchargerId())).findFirst();
+        if(first.isPresent()){
+            projectApproval.setInchargerName(first.get().getName());
+        }
+        List<ParticipationApproval> participationApprovalList = participationApprovalService.list(new LambdaQueryWrapper<ParticipationApproval>().eq(ParticipationApproval::getProjectApprovalId, id));
+        participationApprovalList.forEach(p->{
+            Optional<User> user = userList.stream().filter(u -> u.getId().equals(p.getUserId())).findFirst();
+            if(user.isPresent()){
+                p.setUserName(user.get().getName());
+            }
+        });
+        projectApproval.setParticipationApprovalList(participationApprovalList);
+        List<ProjectApprovalAuditor> projectApprovalAuditorList = projectApprovalAuditorService.list(new LambdaQueryWrapper<ProjectApprovalAuditor>().eq(ProjectApprovalAuditor::getProjectApprovalId, id));
+        projectApproval.setProjectApprovalAuditorList(projectApprovalAuditorList);
+        List<ProjectApprovalBasecost> projectApprovalBasecostList = projectApprovalBasecostService.list(new LambdaQueryWrapper<ProjectApprovalBasecost>().eq(ProjectApprovalBasecost::getProjectApprovalId, id));
+        projectApproval.setProjectApprovalBasecostList(projectApprovalBasecostList);
+        msg.setData(projectApproval);
+        return msg;
+    }
+
+}
+

+ 9 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java

@@ -215,8 +215,10 @@ public class ReportController {
     }
 
     @RequestMapping("/getReportList")
-    public HttpRespMsg getReportList(@RequestParam String date, @RequestParam(required = false) Integer deptId, @RequestParam(required = false) String userId) {
-        return reportService.getReportList(date, deptId, userId, request);
+    public HttpRespMsg getReportList(@RequestParam String date, @RequestParam(required = false) Integer deptId,
+                                     @RequestParam(required = false) String userId, Integer pageIndex, //从0开始
+                                     @RequestParam(required = false, defaultValue="10") Integer pageSize) {
+        return reportService.getReportList(date, deptId, userId, pageIndex, pageSize, request);
     }
 
     /**
@@ -257,6 +259,11 @@ public class ReportController {
         return reportService.getReportById(reportId, request);
     }
 
+    @RequestMapping("/getDetailReportById")
+    public HttpRespMsg getDetailReportById(@RequestParam Integer reportId) {
+        return reportService.getDetailReportById(reportId, request);
+    }
+
     /**
      * AI智能填报
      * @return

+ 7 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/Company.java

@@ -16,7 +16,7 @@ import lombok.experimental.Accessors;
  * </p>
  *
  * @author Seyason
- * @since 2023-12-28
+ * @since 2024-03-18
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -121,6 +121,12 @@ public class Company extends Model<Company> {
     @TableField("package_provider")
     private Integer packageProvider;
 
+    /**
+     * 立项管理
+     */
+    @TableField("package_project_approval")
+    private Integer packageProjectApproval;
+
     /**
      * 是否是国际化版本
      */

+ 55 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ParticipationApproval.java

@@ -0,0 +1,55 @@
+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 2024-03-18
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class ParticipationApproval extends Model<ParticipationApproval> {
+
+    private static final long serialVersionUID=1L;
+
+    /**
+     * 主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 用户表主键
+     */
+    @TableField("user_id")
+    private String userId;
+
+    /**
+     * 项目立项表主键
+     */
+    @TableField("project_approval_id")
+    private Integer projectApprovalId;
+
+    @TableField(exist = false)
+    private String userName;
+
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 262 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ProjectApproval.java

@@ -0,0 +1,262 @@
+package com.management.platform.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import java.time.LocalDate;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.format.annotation.DateTimeFormat;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-03-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class ProjectApproval extends Model<ProjectApproval> {
+
+    private static final long serialVersionUID=1L;
+
+    /**
+     * 主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 项目名称
+     */
+    @TableField("project_name")
+    private String projectName;
+
+    /**
+     * 公司表外键
+     */
+    @TableField("company_id")
+    private Integer companyId;
+
+    /**
+     * 项目编码
+     */
+    @TableField("project_code")
+    private String projectCode;
+
+    /**
+     * 负责人id
+     */
+    @TableField("incharger_id")
+    private String inchargerId;
+
+    /**
+     * 计划开始日期
+     */
+    @TableField("plan_start_date")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private LocalDate planStartDate;
+
+    /**
+     * 计划结束日期
+     */
+    @TableField("plan_end_date")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private LocalDate planEndDate;
+
+    /**
+     * 项目进度
+     */
+    @TableField("progress")
+    private Integer progress;
+
+    /**
+     * 0-全部,1-正常,2-紧急,3-重要,4-重要且紧急 5-低风险 6-中风险 7-高风险
+     */
+    @TableField("level")
+    private Integer level;
+
+    /**
+     * 立项状态 0-待审核 1-已通过 2-已驳回
+     */
+    @TableField("status")
+    private Integer status;
+
+    /**
+     * 实际完成日期
+     */
+    @TableField("finish_date")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private LocalDate finishDate;
+
+    /**
+     * 创建人id
+     */
+    @TableField("creator_id")
+    private String creatorId;
+
+    /**
+     * 创建人姓名
+     */
+    @TableField("creator_name")
+    private String creatorName;
+
+    /**
+     * 创建日期
+     */
+    @TableField("create_date")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private LocalDate createDate;
+
+    /**
+     * 项目金额:单位元
+     */
+    @TableField("contract_amount")
+    private Double contractAmount;
+
+    /**
+     * 基线总成本:单位元
+     */
+    @TableField("budget")
+    private Double budget;
+
+    /**
+     * 人员成本:单位元
+     */
+    @TableField("base_man")
+    private Integer baseMan;
+
+    /**
+     * 外包费用
+     */
+    @TableField("base_outsourcing")
+    private Integer baseOutsourcing;
+
+    /**
+     * 风险预留资金1
+     */
+    @TableField("base_risk1")
+    private Integer baseRisk1;
+
+    /**
+     * 风险预留资金1
+     */
+    @TableField("base_risk2")
+    private Integer baseRisk2;
+
+    /**
+     * 基线费用
+     */
+    @TableField("base_fee")
+    private Integer baseFee;
+
+    /**
+     * 人工成本
+     */
+    @TableField("fee_man")
+    private Double feeMan;
+
+    /**
+     * 客户id
+     */
+    @TableField("customer_id")
+    private Integer customerId;
+
+    /**
+     * 客户名称
+     */
+    @TableField("customer_name")
+    private String customerName;
+
+    /**
+     * 是否是公共项目 0-否  1-是
+     */
+    @TableField("is_public")
+    private Integer isPublic;
+
+    /**
+     * 关联的自定义维度
+     */
+    @TableField("associate_degrees")
+    private String associateDegrees;
+
+    /**
+     * 关联的自定义维度名称
+     */
+    @TableField("associate_degree_names")
+    private String associateDegreeNames;
+
+    /**
+     * 下放日报审核权限到分组负责人
+     */
+    @TableField("task_gp_incharge")
+    private Integer taskGpIncharge;
+
+    /**
+     * 分类id
+     */
+    @TableField("category")
+    private Integer category;
+
+    /**
+     * 分类名称
+     */
+    @TableField("category_name")
+    private String categoryName;
+
+    /**
+     * 项目描述
+     */
+    @TableField("project_desc")
+    private String projectDesc;
+
+    /**
+     * 阶段id
+     */
+    @TableField("current_stage_id")
+    private Integer currentStageId;
+
+    /**
+     * 当前任务阶段名称
+     */
+    @TableField("current_stage_name")
+    private String currentStageName;
+
+    /**
+     * 项目产值
+     */
+    @TableField("output_value")
+    private Double outputValue;
+
+    @TableField(exist = false)
+    private List<ProjectApprovalBasecost> projectApprovalBasecostList;
+
+    @TableField(exist = false)
+    private List<ParticipationApproval> participationApprovalList;
+
+    @TableField(exist = false)
+    private List<ProjectApprovalAuditor> projectApprovalAuditorList;
+
+    @TableField(exist = false)
+    private String inchargerName;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 54 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ProjectApprovalAuditor.java

@@ -0,0 +1,54 @@
+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 2024-03-18
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class ProjectApprovalAuditor extends Model<ProjectApprovalAuditor> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 项目id
+     */
+    @TableField("project_approval_id")
+    private Integer projectApprovalId;
+
+    /**
+     * 审核人id
+     */
+    @TableField("auditor_id")
+    private String auditorId;
+
+    /**
+     * 审核人姓名
+     */
+    @TableField("auditor_name")
+    private String auditorName;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 60 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ProjectApprovalBasecost.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 2024-03-18
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class ProjectApprovalBasecost extends Model<ProjectApprovalBasecost> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 项目id
+     */
+    @TableField("project_approval_id")
+    private Integer projectApprovalId;
+
+    /**
+     * 预算项id
+     */
+    @TableField("base_id")
+    private Integer baseId;
+
+    /**
+     * 预算项名称
+     */
+    @TableField("base_name")
+    private String baseName;
+
+    /**
+     * 预算金额
+     */
+    @TableField("base_amount")
+    private Double baseAmount;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 7 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/SysModule.java

@@ -17,7 +17,7 @@ import lombok.experimental.Accessors;
  * </p>
  *
  * @author Seyason
- * @since 2022-07-07
+ * @since 2024-03-18
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -157,6 +157,12 @@ public class SysModule extends Model<SysModule> {
     @TableField("package_provider")
     private Integer packageProvider;
 
+    /**
+     * 是否属于立项管理模块
+     */
+    @TableField("package_project_approval")
+    private Integer packageProjectApproval;
+
 
     @Override
     protected Serializable pkVal() {

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

@@ -0,0 +1,16 @@
+package com.management.platform.mapper;
+
+import com.management.platform.entity.ParticipationApproval;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 人员参与项目的情况 Mapper 接口
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-03-18
+ */
+public interface ParticipationApprovalMapper extends BaseMapper<ParticipationApproval> {
+
+}

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

@@ -0,0 +1,16 @@
+package com.management.platform.mapper;
+
+import com.management.platform.entity.ProjectApprovalAuditor;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-03-18
+ */
+public interface ProjectApprovalAuditorMapper extends BaseMapper<ProjectApprovalAuditor> {
+
+}

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

@@ -0,0 +1,16 @@
+package com.management.platform.mapper;
+
+import com.management.platform.entity.ProjectApprovalBasecost;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-03-18
+ */
+public interface ProjectApprovalBasecostMapper extends BaseMapper<ProjectApprovalBasecost> {
+
+}

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

@@ -0,0 +1,16 @@
+package com.management.platform.mapper;
+
+import com.management.platform.entity.ProjectApproval;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-03-18
+ */
+public interface ProjectApprovalMapper extends BaseMapper<ProjectApproval> {
+
+}

+ 10 - 4
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ReportMapper.java

@@ -59,8 +59,7 @@ public interface ReportMapper extends BaseMapper<Report> {
                                                              @Param("deptIds") List<Integer> deptIds,
                                                              @Param("endDate") String endDate, @Param("projectId") Integer projectId,@Param("stateKey")Integer stateKey,@Param("branchDepartment")List<Integer> branchDepartment);
 
-    //按当前人员获取本人报告
-    List<Map<String, Object>> getReportByDate(@Param("date") String date, @Param("id") String id);
+
     //获取项目经理所管理的人员的报告
     List<Map<String, Object>> getInchargeReportByDate(@Param("date") String date, @Param("id") String id, @Param("state") Integer state);
 
@@ -81,8 +80,10 @@ public interface ReportMapper extends BaseMapper<Report> {
                                                                 @Param("id") String id,
                                                                 @Param("state") Integer state
                                                                 );
+    //按当前人员获取本人报告
+//    List<Map<String, Object>> getReportByDate(@Param("date") String date, @Param("id") String id);
 
-    List<Map<String, Object>> getUserReportByDate(@Param("date") String date, @Param("userIds") List<String> userIds);
+    List<Map<String, Object>> getUserReportByDateOrId(@Param("date") String date, @Param("userIds") List<String> userIds, @Param("id") Integer id);
 
     List<Map<String, Object>> getReportByTask(@Param("taskId") Integer taskId);
 
@@ -91,7 +92,12 @@ public interface ReportMapper extends BaseMapper<Report> {
     List<Map<String, Object>> getReportNameByDateAndDept(@Param("date") String date,
                                                          @Param("deptIds") List<Integer> deptIds,
                                                          @Param("userId") String userId,
-                                                         @Param("companyId") Integer company);
+                                                         @Param("companyId") Integer companyId, Integer pageStart, Integer pageSize);
+
+    Integer getReportNameByDateAndDeptCount(@Param("date") String date,
+                                                         @Param("deptIds") List<Integer> deptIds,
+                                                         @Param("userId") String userId,
+                                                         @Param("companyId") Integer companyId);
     List<Map<String, Object>> getDetailByStateInMyProfession(@Param("state") Integer state,
                                                @Param("companyId") Integer companyId,
                                                @Param("leaderId") String leaderId);

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

@@ -0,0 +1,16 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.ParticipationApproval;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 人员参与项目的情况 服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-03-18
+ */
+public interface ParticipationApprovalService extends IService<ParticipationApproval> {
+
+}

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

@@ -0,0 +1,16 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.ProjectApprovalAuditor;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-03-18
+ */
+public interface ProjectApprovalAuditorService extends IService<ProjectApprovalAuditor> {
+
+}

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

@@ -0,0 +1,16 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.ProjectApprovalBasecost;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-03-18
+ */
+public interface ProjectApprovalBasecostService extends IService<ProjectApprovalBasecost> {
+
+}

+ 22 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ProjectApprovalService.java

@@ -0,0 +1,22 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.ProjectApproval;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-03-18
+ */
+public interface ProjectApprovalService extends IService<ProjectApproval> {
+
+    HttpRespMsg listByPage(Integer pageIndex, Integer pageSize, String keyword, Integer searchField, String statuses, Integer category, HttpServletRequest request);
+
+}

+ 3 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ReportService.java

@@ -25,7 +25,7 @@ import java.util.Map;
  * @since 2019-12-31
  */
 public interface ReportService extends IService<Report> {
-    HttpRespMsg getReportList(String date, Integer deptId, String userId, HttpServletRequest request);
+    HttpRespMsg getReportList(String date, Integer deptId, String userId, Integer pageIndex, Integer pageSize, HttpServletRequest request);
 
     HttpRespMsg exportReport(@RequestParam String startDate, @RequestParam String endDate,Integer exportType, Integer projectId,Integer stateKey,Integer departmentId, HttpServletRequest request);
 
@@ -149,4 +149,6 @@ public interface ReportService extends IService<Report> {
     HttpRespMsg getHasPushForSap(String startDate, String endDate, String employeeID);
 
     HttpRespMsg getCustomDataWithDate(String startDate, String endDate, HttpServletRequest request);
+
+    HttpRespMsg getDetailReportById(Integer reportId, HttpServletRequest request);
 }

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

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.ParticipationApproval;
+import com.management.platform.mapper.ParticipationApprovalMapper;
+import com.management.platform.service.ParticipationApprovalService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 人员参与项目的情况 服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-03-18
+ */
+@Service
+public class ParticipationApprovalServiceImpl extends ServiceImpl<ParticipationApprovalMapper, ParticipationApproval> implements ParticipationApprovalService {
+
+}

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

@@ -204,6 +204,9 @@ public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permiss
             if (company.getPackageProvider() == 1) {
                 wrapper.or().eq("package_provider", 1);
             }
+            if (company.getPackageProjectApproval() == 1) {
+                wrapper.or().eq("package_project_approval", 1);
+            }
             if (timeType.getReportWorkflow() == 1) {
                 wrapper.or().eq("report_workflow", 1);
             }

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

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.ProjectApprovalAuditor;
+import com.management.platform.mapper.ProjectApprovalAuditorMapper;
+import com.management.platform.service.ProjectApprovalAuditorService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-03-18
+ */
+@Service
+public class ProjectApprovalAuditorServiceImpl extends ServiceImpl<ProjectApprovalAuditorMapper, ProjectApprovalAuditor> implements ProjectApprovalAuditorService {
+
+}

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

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.ProjectApprovalBasecost;
+import com.management.platform.mapper.ProjectApprovalBasecostMapper;
+import com.management.platform.service.ProjectApprovalBasecostService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-03-18
+ */
+@Service
+public class ProjectApprovalBasecostServiceImpl extends ServiceImpl<ProjectApprovalBasecostMapper, ProjectApprovalBasecost> implements ProjectApprovalBasecostService {
+
+}

+ 84 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectApprovalServiceImpl.java

@@ -0,0 +1,84 @@
+package com.management.platform.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.management.platform.entity.*;
+import com.management.platform.mapper.ProjectApprovalMapper;
+import com.management.platform.mapper.ProjectMapper;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.service.ParticipationApprovalService;
+import com.management.platform.service.ProjectApprovalAuditorService;
+import com.management.platform.service.ProjectApprovalBasecostService;
+import com.management.platform.service.ProjectApprovalService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.*;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-03-18
+ */
+@Service
+public class ProjectApprovalServiceImpl extends ServiceImpl<ProjectApprovalMapper, ProjectApproval> implements ProjectApprovalService {
+
+    @Resource
+    private ProjectApprovalMapper projectApprovalMapper;
+    @Resource
+    private UserMapper userMapper;
+
+
+
+    @Override
+    public HttpRespMsg listByPage(Integer pageIndex, Integer pageSize, String keyword, Integer searchField, String statuses, Integer category, HttpServletRequest request) {
+        HttpRespMsg msg=new HttpRespMsg();
+        Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();
+        List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getCompanyId, companyId));
+        LambdaQueryWrapper<ProjectApproval> queryWrapper = new LambdaQueryWrapper<>();
+        if(!StringUtils.isEmpty(keyword)){
+            switch (searchField){
+                case 1:queryWrapper.like(ProjectApproval::getProjectName,keyword);
+                    break;
+                case 2:queryWrapper.like(ProjectApproval::getProjectCode,keyword);
+                    break;
+            }
+        }
+        if(category!=null){
+            queryWrapper.eq(ProjectApproval::getCategory,category);
+        }
+        if(!StringUtils.isEmpty(statuses)){
+            if(statuses.contains(",")){
+                String[] split = statuses.split(",");
+                List<String> statusList = Arrays.asList(split);
+                queryWrapper.in(ProjectApproval::getStatus,statusList);
+            }else {
+                if(!statuses.equals("3")){
+                    queryWrapper.eq(ProjectApproval::getStatus,Integer.valueOf(statuses));
+                }
+            }
+        }
+        IPage<ProjectApproval> iPage = projectApprovalMapper.selectPage(new Page<>(pageIndex, pageSize), queryWrapper);
+        Map<String,Object> result=new HashMap<>();
+        List<ProjectApproval> records = iPage.getRecords();
+        records.forEach(r->{
+            Optional<User> optional = userList.stream().filter(u -> u.getId().equals(r.getInchargerId())).findFirst();
+            if(optional.isPresent()){
+                r.setInchargerName(optional.get().getName());
+            }
+        });
+        result.put("records",records);
+        result.put("total",iPage.getTotal());
+        msg.setData(result);
+        return msg;
+    }
+}

+ 0 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java

@@ -523,7 +523,6 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                     reportList = reportMapper.selectList(new QueryWrapper<Report>().select("id, create_date, project_id, working_time").in("project_id",projectIds).and(wrapper -> wrapper.eq("state", 0).or().eq("state", 1).or().eq("state", 3)));
                 }
             }
-            System.out.println("开始处理项目内数据");
             for (Project project : projectList) {
                 //todo:计算项目预算工时
                 if(project.getManDay()!=null){

+ 88 - 46
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -27,7 +27,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.*;
 import org.springframework.http.client.ClientHttpResponse;
-import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.StringUtils;
@@ -37,7 +36,6 @@ import org.springframework.web.client.RestTemplate;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
-import javax.print.DocFlavor;
 import javax.servlet.http.HttpServletRequest;
 import java.io.*;
 import java.math.BigDecimal;
@@ -225,15 +223,22 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
 
     //获取报告列表
     @Override
-    public HttpRespMsg getReportList(String date,  Integer deptId, String targetUid, HttpServletRequest request) {
+    public HttpRespMsg getReportList(String date,  Integer deptId, String targetUid, Integer pageIndex,
+                                     @RequestParam(required = false, defaultValue="10") Integer pageSize, HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         try {
+            Integer pageStart = null;
+            //pageIndex从0开始
+            if (pageIndex != null) {
+                pageStart = pageIndex * pageSize;
+            }
             //首先根据日期获取当天所有提交过日志的人
             String userId = request.getHeader("Token");
             User user = userMapper.selectById(userId);
             TimeType timeType = timeTypeMapper.selectById(user.getCompanyId());
             List<Map<String, Object>> nameList = new ArrayList<>();
             List<SysRichFunction> functionList = sysFunctionMapper.getRoleFunctions(user.getRoleId(), "查看全公司工时");
+            Integer totalMembCount = 0;
             if (functionList.size() == 0) {
                 String leaderId = user.getId();
                 //不是项目经理,只看自己的报告
@@ -241,40 +246,45 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 //没有指定员工或者指定的就是自己
                 if (targetUid == null || targetUid.equals(user.getId())) {
                     //查看自己的日报
-                    Map<String, Object> map = new HashMap<>();
-                    map.put("id", user.getId());
-                    map.put("name", user.getName());
-                    list = reportMapper.getReportByDate(date, (String) map.get("id"));
-                    if (list.size() > 0) {
-                        //个人日报
-                        nameList.add(map);
-                        map.put("data", list);
-                        double reportTime = 0;
-                        BigDecimal total = new BigDecimal(0);
-                        int state = (int)list.get(0).get("state");
-                        boolean hasDeny = false;
-                        boolean hasWaiting = false;
-                        for (Map<String, Object> m : list) {
-                            double t = (double) m.get("time");
-                            reportTime += t;
-                            total = total.add((BigDecimal)m.get("cost"));
-                            int curState = (int)m.get("state");
-                            if (curState == 2) {
-                                hasDeny = true;
+                    if (pageIndex != null && pageIndex == 0) {
+                        //仅第一页显示自己的
+                        Map<String, Object> map = new HashMap<>();
+                        map.put("id", user.getId());
+                        map.put("name", user.getName());
+                        List<String> uids = new ArrayList<>();
+                        uids.add(user.getId());
+                        list = reportMapper.getUserReportByDateOrId(date, uids, null);
+                        if (list.size() > 0) {
+                            //个人日报
+                            nameList.add(map);
+                            map.put("data", list);
+                            double reportTime = 0;
+                            BigDecimal total = new BigDecimal(0);
+                            int state = (int)list.get(0).get("state");
+                            boolean hasDeny = false;
+                            boolean hasWaiting = false;
+                            for (Map<String, Object> m : list) {
+                                double t = (double) m.get("time");
+                                reportTime += t;
+                                total = total.add((BigDecimal)m.get("cost"));
+                                int curState = (int)m.get("state");
+                                if (curState == 2) {
+                                    hasDeny = true;
+                                }
+                                if (curState == 0) {
+                                    hasWaiting = true;
+                                }
                             }
-                            if (curState == 0) {
-                                hasWaiting = true;
+                            if(hasDeny) {
+                                state = 2;
+                            } else if (hasWaiting) {
+                                state = 0;
                             }
+                            DecimalFormat df = new DecimalFormat("0.00");
+                            map.put("reportTime", df.format(reportTime));
+                            map.put("cost", total);
+                            map.put("state", state);
                         }
-                        if(hasDeny) {
-                            state = 2;
-                        } else if (hasWaiting) {
-                            state = 0;
-                        }
-                        DecimalFormat df = new DecimalFormat("0.00");
-                        map.put("reportTime", df.format(reportTime));
-                        map.put("cost", total);
-                        map.put("state", state);
                     }
                 }
 
@@ -284,7 +294,8 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                     if (nameList.size() > 0) {
                         //自己填写的日报
                         List<Map<String, Object>> deptNameList = reportMapper.getReportNameByDateAndDept(date,
-                                allVisibleDeptIdList, targetUid, null);
+                                allVisibleDeptIdList, targetUid, null, pageStart, pageSize);
+                        totalMembCount = reportMapper.getReportNameByDateAndDeptCount(date, allVisibleDeptIdList, targetUid, null);
                         for (Map<String, Object> deptNameItem : deptNameList) {
                             if (!deptNameItem.get("id").equals(user.getId())) {
                                 nameList.add(deptNameItem);
@@ -292,7 +303,8 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                         }
                     } else {
                         nameList = reportMapper.getReportNameByDateAndDept(date,
-                                allVisibleDeptIdList, targetUid, null);
+                                allVisibleDeptIdList, targetUid, null, pageStart, pageSize);
+                        totalMembCount = reportMapper.getReportNameByDateAndDeptCount(date, allVisibleDeptIdList, targetUid, null);
                     }
                     if (nameList.size() > 0) {
                         List<String> userIds = new ArrayList<>();
@@ -300,7 +312,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                             String id = (String) n.get("id");
                             userIds.add(id);
                         });
-                        List<Map<String, Object>> reportList = reportMapper.getUserReportByDate(date, userIds);
+                        List<Map<String, Object>> reportList = reportMapper.getUserReportByDateOrId(date, userIds, null);
                         for (Map<String, Object> memb : nameList) {
                             //再根据人分别获取当天的报告
                             List<Map<String, Object>> rList = new ArrayList<Map<String, Object>>();
@@ -443,14 +455,15 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                     }
                 }
                 nameList = reportMapper.getReportNameByDateAndDept(date,
-                        ids, targetUid, companyId);
+                        ids, targetUid, companyId, pageStart, pageSize);
+                totalMembCount = reportMapper.getReportNameByDateAndDeptCount(date, ids, targetUid, companyId);
                 if (nameList.size() > 0) {
                     List<String> userIds = new ArrayList<>();
                     nameList.forEach(n->{
                         String id = (String) n.get("id");
                         userIds.add(id);
                     });
-                    List<Map<String, Object>> reportList = reportMapper.getUserReportByDate(date, userIds);
+                    List<Map<String, Object>> reportList = reportMapper.getUserReportByDateOrId(date, userIds, null);
                     for (Map<String, Object> map : nameList) {
                         //再根据人分别获取当天的报告
                         List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
@@ -629,7 +642,17 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 }
             }
 
-            httpRespMsg.data = nameList;
+            if (pageStart == null) {
+                //老版本,不带分页的情况
+                httpRespMsg.data = nameList;
+            } else {
+                //新版,分页请求
+                HashMap retMap = new HashMap();
+                retMap.put("data", nameList);
+                retMap.put("pageIndex", pageIndex);
+                retMap.put("hasMore", pageIndex * pageSize + pageSize < totalMembCount);
+                httpRespMsg.data = retMap;
+            }
         } catch (NullPointerException e) {
             e.printStackTrace();
             //httpRespMsg.setError("验证失败");
@@ -750,7 +773,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                         List<GroupParticipator> groupParticipatorList = groupParticipatorMapper.selectList(new QueryWrapper<GroupParticipator>().eq("user_id", r.getCreatorId()));
                         if (groupParticipatorList.size() > 0) {
                             List<Integer> groupIds = groupParticipatorList.stream().map(GroupParticipator::getGroupId).collect(Collectors.toList());
-                            List<TaskGroup> findGroups = taskGroups.stream().filter(tg->groupIds.contains(tg.getId()) || userId.equals(tg.getInchargerId())).collect(Collectors.toList());
+                            List<TaskGroup> findGroups = taskGroups.stream().filter(tg->tg.getProjectId().equals(r.getProjectId()) && (groupIds.contains(tg.getId()) || userId.equals(tg.getInchargerId()))).collect(Collectors.toList());
                             r.setTaskGroups(findGroups);
                             if (r.getGroupId() != null && r.getGroupId() != 0) {
                                 Optional<TaskGroup> optinal = taskGroups.stream().filter(tg->tg.getId().equals(r.getGroupId())).findFirst();
@@ -2951,7 +2974,6 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
 
         List<DepartmentVO> list = null;
         List<SysRichFunction> functionList = sysFunctionMapper.getRoleFunctions(curUser.getRoleId(), "查看全公司工时");
-
         if (functionList.size() > 0) {
             //查看全部的
             HttpRespMsg departmentList = departmentService.getDepartmentList(request);
@@ -3012,7 +3034,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
 
             list = realMDeptList;
         }
-
+        long t2 = System.currentTimeMillis();
         if (list.size() > 0) {
             //存在查看权限的部门
             //获取公司全部人员; 按照人员状态,如果是已经离职的,当前日期在离职日期以后的,不需要显示该人员
@@ -3020,13 +3042,18 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             queryWrapper.and(wrapper->wrapper.eq("is_active", 1).eq("report_status",0)
                     .or(wrapper2->wrapper2.eq("is_active", 0).gt("inactive_date", date)));
             List<User> userList = userMapper.selectList(queryWrapper);
-            List<LeaveSheet> leaveSheetList = leaveSheetMapper.selectList(new QueryWrapper<LeaveSheet>().eq("company_id", companyId));
+            List<LeaveSheet> leaveSheetList = leaveSheetMapper.selectList(
+                    new QueryWrapper<LeaveSheet>().select("id, owner_id, start_date, end_date, leave_type, time_type, time_days, time_hours").eq("company_id", companyId));
+            long t3 = System.currentTimeMillis();
+            System.out.println("获取人员请假列表耗时:" + (t3 - t2) + "ms");
             LocalDate localDate = LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
             List<HashMap> userMapList = new ArrayList<>();
             LocalDate curDate = LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
 
             //获取当日已填写的人员报告
             List<Map<String, Object>> reportNameByDate = reportMapper.getReportNameByDate(date, companyId, null);
+            long t4 = System.currentTimeMillis();
+            System.out.println("获取当日已填写的人员报告耗时:" + (t4 - t3) + "ms");
             Company company = companyMapper.selectById(companyId);
             TimeType timeType = timeTypeMapper.selectById(companyId);
             //如果没有开通OA模块,有开通企业微信同步考勤,从user_corpwx_time表中获取请假时长
@@ -4125,13 +4152,16 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 n.put("dateStr",sdf.format((java.sql.Date)n.get("date")));
             });
 
-            List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId));
+//            List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId));
             List<Profession> professions = professionMapper.selectList(new QueryWrapper<Profession>().eq("company_id", curUser.getCompanyId()));
             for (int index=0;index<nameList.size(); index++) {
                 Map<String, Object> map2 = nameList.get(index);
                 java.sql.Date createDate = (java.sql.Date)map2.get("date");
                 List<Map<String, Object>> list2 = null;
-                list2 = reportMapper.getReportByDate(createDate.toString(), (String)map2.get("id"));
+                String uid = (String)map2.get("id");
+                List<String> uids = new ArrayList<>();
+                uids.add(uid);
+                list2 = reportMapper.getUserReportByDateOrId(createDate.toString(),uids, null);
                 //按项目过滤
                 if (projectId != null) {
                     list2 = list2.stream().filter(report->(((Integer)report.get("projectId")).equals(projectId))).collect(Collectors.toList());
@@ -8783,4 +8813,16 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         httpRespMsg.data = finalMap;
         return httpRespMsg;
     }
+
+    @Override
+    public HttpRespMsg getDetailReportById(Integer reportId, HttpServletRequest request) {
+        HttpRespMsg msg = new HttpRespMsg();
+        List list = reportMapper.getUserReportByDateOrId(null, null, reportId);
+        if (list.size() > 0) {
+            msg.data = list.get(0);
+        } else {
+            msg.setError("该日报已不存在");
+        }
+        return msg;
+    }
 }

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

@@ -571,6 +571,9 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
         if (company.getPackageProvider() == 1) {
             queryWrapper.or().eq("package_provider", 1);
         }
+        if (company.getPackageProjectApproval() == 1) {
+            queryWrapper.or().eq("package_project_approval", 1);
+        }
         if (timeType.getReportWorkflow() == 1) {
             queryWrapper.or().eq("report_workflow", 1);
         }

+ 2 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/CompanyMapper.xml

@@ -20,6 +20,7 @@
         <result column="package_simple" property="packageSimple" />
         <result column="package_finance" property="packageFinance" />
         <result column="package_provider" property="packageProvider" />
+        <result column="package_project_approval" property="packageProjectApproval" />
         <result column="is_international" property="isInternational" />
         <result column="create_date" property="createDate" />
         <result column="reg_from" property="regFrom" />
@@ -28,7 +29,7 @@
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        id, company_name, staff_count_max, expiration_date, set_meal, package_worktime, package_project, package_contract, package_oa, package_etimecard, package_expense, package_customer, package_engineering, package_simple, package_finance, package_provider, is_international, create_date, reg_from, non_project_simple
+        id, company_name, staff_count_max, expiration_date, set_meal, package_worktime, package_project, package_contract, package_oa, package_etimecard, package_expense, package_customer, package_engineering, package_simple, package_finance, package_provider, package_project_approval, is_international, create_date, reg_from, non_project_simple
     </sql>
 
 </mapper>

+ 17 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ParticipationApprovalMapper.xml

@@ -0,0 +1,17 @@
+<?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.ParticipationApprovalMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.ParticipationApproval">
+        <id column="id" property="id" />
+        <result column="user_id" property="userId" />
+        <result column="project_approval_id" property="projectApprovalId" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, user_id, project_approval_id
+    </sql>
+
+</mapper>

+ 18 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectApprovalAuditorMapper.xml

@@ -0,0 +1,18 @@
+<?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.ProjectApprovalAuditorMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.ProjectApprovalAuditor">
+        <id column="id" property="id" />
+        <result column="project_approval_id" property="projectApprovalId" />
+        <result column="auditor_id" property="auditorId" />
+        <result column="auditor_name" property="auditorName" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, project_approval_id, auditor_id, auditor_name
+    </sql>
+
+</mapper>

+ 19 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectApprovalBasecostMapper.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.ProjectApprovalBasecostMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.ProjectApprovalBasecost">
+        <id column="id" property="id" />
+        <result column="project_approval_id" property="projectApprovalId" />
+        <result column="base_id" property="baseId" />
+        <result column="base_name" property="baseName" />
+        <result column="base_amount" property="baseAmount" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, project_approval_id, base_id, base_name, base_amount
+    </sql>
+
+</mapper>

+ 48 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectApprovalMapper.xml

@@ -0,0 +1,48 @@
+<?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.ProjectApprovalMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.ProjectApproval">
+        <id column="id" property="id" />
+        <result column="project_name" property="projectName" />
+        <result column="company_id" property="companyId" />
+        <result column="project_code" property="projectCode" />
+        <result column="incharger_id" property="inchargerId" />
+        <result column="plan_start_date" property="planStartDate" />
+        <result column="plan_end_date" property="planEndDate" />
+        <result column="progress" property="progress" />
+        <result column="level" property="level" />
+        <result column="status" property="status" />
+        <result column="finish_date" property="finishDate" />
+        <result column="creator_id" property="creatorId" />
+        <result column="creator_name" property="creatorName" />
+        <result column="create_date" property="createDate" />
+        <result column="contract_amount" property="contractAmount" />
+        <result column="budget" property="budget" />
+        <result column="base_man" property="baseMan" />
+        <result column="base_outsourcing" property="baseOutsourcing" />
+        <result column="base_risk1" property="baseRisk1" />
+        <result column="base_risk2" property="baseRisk2" />
+        <result column="base_fee" property="baseFee" />
+        <result column="fee_man" property="feeMan" />
+        <result column="customer_id" property="customerId" />
+        <result column="customer_name" property="customerName" />
+        <result column="is_public" property="isPublic" />
+        <result column="associate_degrees" property="associateDegrees" />
+        <result column="associate_degree_names" property="associateDegreeNames" />
+        <result column="task_gp_incharge" property="taskGpIncharge" />
+        <result column="category" property="category" />
+        <result column="category_name" property="categoryName" />
+        <result column="project_desc" property="projectDesc" />
+        <result column="current_stage_id" property="currentStageId" />
+        <result column="current_stage_name" property="currentStageName" />
+        <result column="output_value" property="outputValue" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, project_name, company_id, project_code, incharger_id, plan_start_date, plan_end_date, progress, level, status, finish_date, creator_id, creator_name, create_date, contract_amount, budget, base_man, base_outsourcing, base_risk1, base_risk2, base_fee, fee_man, customer_id, customer_name, is_public, associate_degrees, associate_degree_names, task_gp_incharge, category, category_name, project_desc, current_stage_id, current_stage_name, output_value
+    </sql>
+
+</mapper>

+ 70 - 41
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportMapper.xml

@@ -396,14 +396,41 @@
 
 
     <!--根据员工id,日期获取当天全部报告信息-->
-    <select id="getReportByDate" resultType="java.util.Map">
-        SELECT a.id, a.project_id as projectId,b.project_name AS project, a.working_time AS time, a.content, a.state, a.time_type as timeType, a.cost, a.report_time_type as reportTimeType, a.start_time as startTime,
-        a.end_time as endTime, b.incharger_id as inchargerId,b.project_code as projectCode,
-        a.creator_id as creatorId, d.name as subProjectName,d.code as subProjectCode,a.task_id as taskId, task.name as taskName, a.is_overtime as isOvertime,a.progress as progress,
+<!--    <select id="getReportByDate" resultType="java.util.Map">-->
+<!--        SELECT a.id, a.project_id as projectId,b.project_name AS project, a.working_time AS time, a.content, a.state, a.time_type as timeType, a.cost, a.report_time_type as reportTimeType, a.start_time as startTime,-->
+<!--        a.end_time as endTime, b.incharger_id as inchargerId,b.project_code as projectCode,-->
+<!--        a.creator_id as creatorId, d.name as subProjectName,d.code as subProjectCode,a.task_id as taskId, task.name as taskName, a.is_overtime as isOvertime,a.progress as progress,-->
+<!--        a.department_audit_state as departmentAuditState, a.stage, a.pic_str as picStr, multi_worktime as multiWorktime-->
+<!--        , reject_reason as rejectReason, reject_username as rejectUsername, reject_userid as rejectUserid, degree_id as degree_id,report_extra_degree.name as degreeName,-->
+<!--        department.department_name as auditDeptName, a.is_dept_audit as isDeptAudit, a.project_audit_state as projectAuditState,task_group.name as groupName,a.group_id as groupId, a.custom_data as customData-->
+<!--        ,u.name as projectAuditorName, a.project_auditor_id as projectAuditorId,dp2.department_name as buDepartmentName,a.overtime_hours as overtimeHours, a.custom_text as customText,a.evaluate as evaluate,a.report_auto_approve as reportAutoApprove,-->
+<!--        a.extra_field1 as extraField1,a.extra_field2 as extraField2,a.extra_field3 as extraField3, a.batch_id as batchId,a.sap_service_id as sapServiceId, multi_degr_id as multiDegrId-->
+<!--        FROM report AS a-->
+<!--        JOIN project AS b ON a.project_id=b.id-->
+<!--        left join sub_project as d on d.id = a.sub_project_id-->
+<!--        left join task on task.id = a.task_id-->
+<!--        left join report_extra_degree on report_extra_degree.id = a.degree_id-->
+<!--        left join department on department.department_id = a.audit_deptid-->
+<!--        left join department dp2 on dp2.department_id = b.bu_id-->
+<!--        left join task_group on task_group.id = a.group_id-->
+<!--        left join user u on u.id = a.project_auditor_id-->
+<!--        WHERE 1=1-->
+<!--        <if test="date != null and date != ''">-->
+<!--            AND a.create_date=#{date}-->
+<!--        </if>-->
+<!--        AND a.creator_id=#{id}-->
+<!--        ORDER BY a.creator_id ASC-->
+<!--    </select>-->
+    <!-- 批量获取员工某天的报告 -->
+    <select id="getUserReportByDateOrId" resultType="java.util.Map">
+        SELECT a.id, b.project_name AS project, a.working_time AS time, a.content, a.state, a.time_type as timeType, a.creator_id as creatorId, a.cost, a.report_time_type as reportTimeType, a.start_time as startTime,
+        a.end_time as endTime, d.name as subProjectName,d.code as subProjectCode,a.task_id as taskId, task.name as taskName,
+        b.incharger_id as inchargerId,b.project_code as projectCode,
+        a.is_overtime as isOvertime,a.progress as progress,audit_dept_managerid as auditDeptManagerid,audit_deptid as auditDeptid,
         a.department_audit_state as departmentAuditState, a.stage, a.pic_str as picStr, multi_worktime as multiWorktime
         , reject_reason as rejectReason, reject_username as rejectUsername, reject_userid as rejectUserid, degree_id as degree_id,report_extra_degree.name as degreeName,
         department.department_name as auditDeptName, a.is_dept_audit as isDeptAudit, a.project_audit_state as projectAuditState,task_group.name as groupName,a.group_id as groupId, a.custom_data as customData
-        ,u.name as projectAuditorName, a.project_auditor_id as projectAuditorId,dp2.department_name as buDepartmentName,a.overtime_hours as overtimeHours, a.custom_text as customText,a.evaluate as evaluate,a.report_auto_approve as reportAutoApprove,
+        ,u.name as projectAuditorName, a.project_auditor_id as projectAuditorId,dp2.department_name as buDepartmentName, a.overtime_hours as overtimeHours, a.custom_text as customText, dept_manager.name as deptAuditorName,a.evaluate as evaluate,a.report_auto_approve as reportAutoApprove,
         a.extra_field1 as extraField1,a.extra_field2 as extraField2,a.extra_field3 as extraField3, a.batch_id as batchId,a.sap_service_id as sapServiceId, multi_degr_id as multiDegrId
         FROM report AS a
         JOIN project AS b ON a.project_id=b.id
@@ -412,16 +439,24 @@
         left join report_extra_degree on report_extra_degree.id = a.degree_id
         left join department on department.department_id = a.audit_deptid
         left join department dp2 on dp2.department_id = b.bu_id
+        left join user dept_manager on dept_manager.id = a.audit_dept_managerid
         left join task_group on task_group.id = a.group_id
         left join user u on u.id = a.project_auditor_id
         WHERE 1=1
-        <if test="date != null and date != ''">
-            AND a.create_date=#{date}
+        <if test="id == null">
+            <if test="date != null and date != ''">
+                AND a.create_date=#{date}
+            </if>
+            AND a.creator_id in
+            <foreach item="item" collection="userIds" separator="," open="(" close=")" index="">
+                #{item, jdbcType=VARCHAR}
+            </foreach>
+            ORDER BY a.creator_id ASC
+        </if>
+        <if test="id != null" >
+            AND a.id=#{id}
         </if>
-        AND a.creator_id=#{id}
-        ORDER BY a.creator_id ASC
     </select>
-
     <!--根据任务id,全部报告信息-->
     <select id="getReportByTask" resultType="java.util.Map">
         SELECT a.id,date_format(a.create_date, '%Y-%m-%d') as createDate,  my.id as userId, my.name as userName, a.project_id as projectId,b.project_name AS project, a.working_time AS time, a.content, a.state, a.time_type as timeType, a.cost, a.report_time_type as reportTimeType, a.start_time as startTime,
@@ -592,37 +627,6 @@
         ORDER BY a.creator_id ASC
     </select>
 
-    <!-- 批量获取员工某天的报告 -->
-    <select id="getUserReportByDate" resultType="java.util.Map">
-        SELECT a.id, b.project_name AS project, a.working_time AS time, a.content, a.state, a.time_type as timeType, a.creator_id as creatorId, a.cost, a.report_time_type as reportTimeType, a.start_time as startTime,
-        a.end_time as endTime, d.name as subProjectName,d.code as subProjectCode,a.task_id as taskId, task.name as taskName,
-        b.incharger_id as inchargerId,b.project_code as projectCode,
-        a.is_overtime as isOvertime,a.progress as progress,audit_dept_managerid as auditDeptManagerid,audit_deptid as auditDeptid,
-        a.department_audit_state as departmentAuditState, a.stage, a.pic_str as picStr, multi_worktime as multiWorktime
-        , reject_reason as rejectReason, reject_username as rejectUsername, reject_userid as rejectUserid, degree_id as degree_id,report_extra_degree.name as degreeName,
-        department.department_name as auditDeptName, a.is_dept_audit as isDeptAudit, a.project_audit_state as projectAuditState,task_group.name as groupName,a.group_id as groupId, a.custom_data as customData
-        ,u.name as projectAuditorName, a.project_auditor_id as projectAuditorId,dp2.department_name as buDepartmentName, a.overtime_hours as overtimeHours, a.custom_text as customText, dept_manager.name as deptAuditorName,a.evaluate as evaluate,a.report_auto_approve as reportAutoApprove,
-        a.extra_field1 as extraField1,a.extra_field2 as extraField2,a.extra_field3 as extraField3, a.batch_id as batchId,a.sap_service_id as sapServiceId, multi_degr_id as multiDegrId
-        FROM report AS a
-        JOIN project AS b ON a.project_id=b.id
-        left join sub_project as d on d.id = a.sub_project_id
-        left join task on task.id = a.task_id
-        left join report_extra_degree on report_extra_degree.id = a.degree_id
-        left join department on department.department_id = a.audit_deptid
-        left join department dp2 on dp2.department_id = b.bu_id
-        left join user dept_manager on dept_manager.id = a.audit_dept_managerid
-        left join task_group on task_group.id = a.group_id
-        left join user u on u.id = a.project_auditor_id
-        WHERE 1=1
-        <if test="date != null and date != ''">
-            AND a.create_date=#{date}
-        </if>
-        AND a.creator_id in
-        <foreach item="item" collection="userIds" separator="," open="(" close=")" index="">
-            #{item, jdbcType=VARCHAR}
-        </foreach>
-        ORDER BY a.creator_id ASC
-    </select>
 
     <!--根据日期获取报告上传人-->
     <select id="getReportNameByDate" resultType="java.util.Map">
@@ -682,6 +686,31 @@
         <if test="userId != null">
             AND b.id=#{userId}
         </if>
+        <if test="pageStart != null">
+            limit #{pageStart}, #{pageSize}
+        </if>
+    </select>
+
+    <select id="getReportNameByDateAndDeptCount" resultType="java.lang.Integer">
+        SELECT count(DISTINCT b.id) as count
+        FROM report AS a
+        JOIN user AS b ON a.creator_id=b.id
+        WHERE 1=1
+        <if test="date != null and date != ''">
+            AND a.create_date=#{date}
+        </if>
+        <if test="deptIds != null">
+            AND b.department_id in
+            <foreach item="item" collection="deptIds" separator="," open="(" close=")" index="">
+                #{item, jdbcType=INTEGER}
+            </foreach>
+        </if>
+        <if test="companyId != null">
+            AND b.company_id = #{companyId}
+        </if>
+        <if test="userId != null">
+            AND b.id=#{userId}
+        </if>
     </select>
 
     <!--专业待审核的报告列表-->

+ 2 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/SysModuleMapper.xml

@@ -24,11 +24,12 @@
         <result column="package_finance" property="packageFinance" />
         <result column="need_dept_audit" property="needDeptAudit" />
         <result column="package_provider" property="packageProvider" />
+        <result column="package_project_approval" property="packageProjectApproval" />
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        id, name, path, parent_id, icon, orderitem, is_menu, use_state, package_time, package_project, package_oa, package_expense, package_customer, package_engineering, package_contract, package_etimecard, report_workflow, package_finance, need_dept_audit, package_provider
+        id, name, path, parent_id, icon, orderitem, is_menu, use_state, package_time, package_project, package_oa, package_expense, package_customer, package_engineering, package_contract, package_etimecard, report_workflow, package_finance, need_dept_audit, package_provider, package_project_approval
     </sql>
 
 </mapper>

+ 11 - 1
fhKeeper/formulahousekeeper/management-workshop/src/main/java/com/management/platform/entity/ProdProcedure.java

@@ -16,13 +16,15 @@ import lombok.experimental.Accessors;
  * </p>
  *
  * @author Seyason
- * @since 2023-07-02
+ * @since 2024-03-19
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
 @Accessors(chain = true)
 public class ProdProcedure extends Model<ProdProcedure> {
 
+    private static final long serialVersionUID=1L;
+
     @TableId(value = "id", type = IdType.AUTO)
     private Integer id;
 
@@ -74,8 +76,16 @@ public class ProdProcedure extends Model<ProdProcedure> {
     @TableField("product_name")
     private String productName;
 
+    /**
+     * 排序
+     */
+    @TableField("seq")
+    private Integer seq;
+
+
     @Override
     protected Serializable pkVal() {
         return this.id;
     }
+
 }

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

@@ -154,7 +154,7 @@ public class ProdProcedureServiceImpl extends ServiceImpl<ProdProcedureMapper, P
                         .select("DISTINCT version_number")
                         .lambda()
                         .eq(productId != null, ProdProcedure::getProductId, productId)
-                        .eq(user.getCompanyId()!=null,ProdProcedure::getCompanyId,user.getCompanyId())
+                        .eq(user.getCompanyId()!=null,ProdProcedure::getCompanyId,user.getCompanyId()).orderByAsc(ProdProcedure::getSeq)
 
         );
         List<String> versionList = procedureVersions.stream().map(prodProcedure -> prodProcedure.getVersionNumber()).collect(Collectors.toList());

+ 9 - 5
fhKeeper/formulahousekeeper/management-workshop/src/main/resources/mapper/ProdProcedureMapper.xml

@@ -5,16 +5,20 @@
     <!-- 通用查询映射结果 -->
     <resultMap id="BaseResultMap" type="com.management.platform.entity.ProdProcedure">
         <id column="id" property="id" />
-        <result column="prod_id" property="prodId" />
-        <result column="procedure_id" property="procedureId" />
-        <result column="proced_type" property="procedType" />
-        <result column="price" property="price" />
+        <result column="name" property="name" />
+        <result column="company_id" property="companyId" />
+        <result column="product_id" property="productId" />
+        <result column="unit_price" property="unitPrice" />
         <result column="check_type" property="checkType" />
+        <result column="working_time" property="workingTime" />
+        <result column="version_number" property="versionNumber" />
+        <result column="product_name" property="productName" />
+        <result column="seq" property="seq" />
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        id, prod_id, procedure_id, proced_type, price, check_type
+        id, name, company_id, product_id, unit_price, check_type, working_time, version_number, product_name, seq
     </sql>
 
 </mapper>

+ 15 - 4
fhKeeper/formulahousekeeper/timesheet-workshop/src/views/product/list.vue

@@ -160,7 +160,7 @@
 
         <!--新增界面-->
         <el-dialog :title="title" v-if="addFormVisible" :visible.sync="addFormVisible" :close-on-click-modal="false"
-            customClass="customWidth" width="960px" :top="'6vh'">
+            customClass="customWidth" width="1100px" :top="'6vh'">
 
             <el-steps :active="prodEditActive" finish-status="success">
                 <el-step title="产品信息">
@@ -237,7 +237,7 @@
                     </el-table-column>
                     <el-table-column prop="unitPrice" label="单件工价(元)" width="140">
                         <template slot-scope="scope">
-                            <el-input v-model.number="scope.row.unitPrice"   clearable maxlength="9"  placeholder="请输入"></el-input>
+                            <el-input type="number" v-model="scope.row.unitPrice"   clearable maxlength="9"  placeholder="请输入"></el-input>
                         </template>
                     </el-table-column>
                     <el-table-column label="质检类型" width="150">
@@ -249,8 +249,9 @@
                             </el-select>
                         </template>
                     </el-table-column>
-                    <el-table-column label="操作" width="100" fixed="right">
+                    <el-table-column label="操作" width="200" fixed="right">
                         <template slot-scope="scope">
+                            <el-button size="mini" @click="newAddProcedure(scope.$index)">添加一行</el-button>
                             <el-button size="mini" @click="deleteProcedure(scope.$index, scope.row)">删除</el-button>
                         </template>
                     </el-table-column>
@@ -1256,6 +1257,9 @@ export default {
             if(flag){
 
                  this.addLoading = true;
+                this.procedureLit.forEach((item, index) => {
+                    item.seq = +index + 1
+                })
                 let procedureString = JSON.stringify(this.procedureLit);
                 this.http.post('/prod-procedure/changeProdProcedure', {
                     productId: this.productId,
@@ -1352,9 +1356,16 @@ export default {
                 unitPrice: '',
                 workingTime: '',
                 checkType: 0
-
             }]
         },
+        newAddProcedure(index) {
+            this.procedureLit.splice(index+1, 0, {
+                name: '',
+                unitPrice: '',
+                workingTime: '',
+                checkType: 0
+            })
+        },
         // 向表格中添加数据
         addMaterial() {
             this.prodMaterialList = [...this.prodMaterialList, {

+ 50 - 0
fhKeeper/formulahousekeeper/timesheet/src/http.js

@@ -101,6 +101,56 @@ export default {
         )
     },
 
+    JSONPost (url, data, response, exception) {
+        let user = sessionStorage.getItem('user') , token = "";
+        if(user != null){
+            token = JSON.parse(user).id
+            // data.token = token
+        }
+        if(localStorage.getItem('lang') == 'en') {
+            data.lang = 'english'
+        }
+        axios({
+            method: 'post',
+            url: handleUrl(url),
+            data,
+            timeout: TIME_OUT_MS,
+            headers: {
+                'Content-Type': 'application/json',
+                // 'Content-type': ' application/x-www-form-urlencoded; charset=UTF-8',
+                'Token': token
+            }
+        }).then(
+            (result) => {
+                response(handleResults(result))
+            }
+        ).catch(
+            (error) => {
+                if (exception) {
+                    var str = error + ''
+                    if(str.indexOf('504') != '-1' || str.indexOf('502') != '-1') {
+
+                        if (flgs == 0) {
+                            timer = setTimeout(() => {
+                                prompt()
+                            }, 100)
+                            flgs++
+                            clearTimeout(timer2)
+                            timer2 = setTimeout(() => {
+                                flgs = 0
+                            }, 12000)
+                        }
+                        // exception(false)
+                    } else {
+                        exception(error)
+                    }
+                } else {
+                    console.log(error, 3)
+                }
+            }
+        )
+    },
+
     WPGpost (url, data, response, exception) {
         let user = sessionStorage.getItem('user') , token = "";
         if(user != null){

+ 1 - 0
fhKeeper/formulahousekeeper/timesheet/src/i18n/en.json

@@ -3,6 +3,7 @@
   "navigation": {
     "reports": "Hours report",
     "projectManagement": "project management",
+    "projectApproval": "project approval",
     "contractManagement": "contract management",
     "professionalAudit": "Professional audit",
     "departmentAudit": "Department audit",

+ 1 - 0
fhKeeper/formulahousekeeper/timesheet/src/i18n/zh.json

@@ -3,6 +3,7 @@
   "navigation": {
     "reports": "工时报告",
     "projectManagement": "项目管理",
+    "projectApproval": "立项管理",
     "contractManagement": "合同管理",
     "professionalAudit": "专业审核",
     "departmentAudit": "部门审核",

+ 15 - 0
fhKeeper/formulahousekeeper/timesheet/src/permissions.js

@@ -20,6 +20,14 @@ const StringUtil = {
         projectEditDefaultFolder: false, // 修改默认文件夹 //
         projectViewAllTasks: false, // 查看全部任务 //
 
+        //立项管理
+        projectApprovalNew:false, //新增立项
+        projectApprovalView:false, //查看全部立项
+        projectApprovalExport:false, //导出立项
+        projectApprovalImport:false, //导入立项
+        projectApprovalCheck:false, //审核立项
+        projectApprovalEdit:false, //管理全部立项
+
         // 合同管理
         contractNew: false, // 新增合同 // 
         contractView: false, // 查看全部合同 // 
@@ -261,6 +269,13 @@ const StringUtil = {
         arr[i] == '全部分组耗用进度表' || arr[i] == '负责部门分组耗用进度表' ? obj.reportProjectConsumptionFirst = true : ''
         arr[i] == '全部项目耗用进度表' || arr[i] == '负责部门项目耗用进度表' ? obj.reportProjectConsumptionTwo = true : ''
         arr[i] == '全部员工任务进度表' || arr[i] == '负责部门员工任务进度表' ? obj.reportStaffTaskAccomplished = true : ''
+
+        arr[i] == '新增立项申请'  ? obj.projectApprovalNew = true : ''
+        arr[i] == '导入立项申请'  ? obj.projectApprovalImport = true : ''
+        arr[i] == '导出立项申请'  ? obj.projectApprovalExport = true : ''
+        arr[i] == '查看全部立项申请'  ? obj.projectApprovalView = true : ''
+        arr[i] == '管理全部立项申请'  ? obj.projectApprovalEdit = true : ''
+        arr[i] == '审核立项申请' ? obj.projectApprovalCheck = true : ''
     }
     return obj
   }

+ 15 - 0
fhKeeper/formulahousekeeper/timesheet/src/routes.js

@@ -31,6 +31,9 @@ import projectInside from  './views/project/projectInside.vue'
 import info from './views/project/info.vue'
 import projectGantt from './views/project/project_gantt.vue'
 
+// 立项管理
+import projectApproval from './views/projectApproval/projectApproval.vue'
+
 // 合同管理
 import contract from './views/contract/index.vue'
 
@@ -292,6 +295,18 @@ export const allRouters = [//组织架构
         // 其他信息
         meta: { text: 'navigation.projectManagement' } 
     },
+    {
+        path: '/',
+        component: Home,
+        name: '立项管理',
+        iconCls: 'iconfont firerock-iconxiangmu',
+        leaf: true,
+        children: [
+            { path: '/projectApproval', component: projectApproval, name: '立项管理' },
+        ],
+        // 其他信息
+        meta: { text: 'navigation.projectApproval' } 
+    },
     //预算工时审核
     {
         path: '/',

+ 5 - 2
fhKeeper/formulahousekeeper/timesheet/src/views/expense/expense.vue

@@ -514,7 +514,7 @@
             <el-input v-enter-number v-model="ParticularsList.ticketNum" :disabled="flg"></el-input>
           </el-form-item>
           <el-form-item :label="$t('costtype')" style="width: 270px">
-            <el-select size="small" v-model="expenseMainTypeValue" style="width: 150px" :disabled="flg">
+            <el-select size="small" v-model="ParticularsList.type" style="width: 150px" :disabled="flg">
               <el-option v-for="item in expenseMainTypes" :key="item.id" :label="item.name" :value="item.id"></el-option>
             </el-select>
           </el-form-item>
@@ -1752,6 +1752,7 @@ export default {
           if (res.code == "ok") {
             this.dialog = false;
             this.bills(this.isAuditList);
+            this.getList()
             this.$message({
               message: this.$t('editsuccess'),
               type: "success"
@@ -2060,8 +2061,10 @@ export default {
       },
         res => {
           if (res.code == "ok") {
-            this
+            // this
+            console.log(res, '<=== 详情数据')
             // this.ParticularsList = res.data
+            // this.expenseMainTypeValue = res.data.type
             var s = []
             // var b = []
             for (var i in res.data.invoiceList) {

+ 1 - 1
fhKeeper/formulahousekeeper/timesheet/src/views/project/list.vue

@@ -6148,7 +6148,7 @@ a {
             if (this.user.timeType.projectManDay == 1) {
                 this.getManDaySetting();
             }
-        }
+        },
     };
 </script>
 

+ 992 - 0
fhKeeper/formulahousekeeper/timesheet/src/views/projectApproval/projectApproval.vue

@@ -0,0 +1,992 @@
+<template>
+    <section>
+        <!--工具条 top-->
+        <el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
+            <el-form :inline="true">
+                <el-form-item >
+                    <!-- <div style="display: flex;align-items: center;height: 40px;"> -->
+                    <div v-if="true" style="display: flex;align-items: center;height: 40px;">
+                    <el-input v-model="keyword" class="input-with-select" :placeholder="searchField == '1' ? $t('peaseenterthe') : $t('peaseenterthe')" clearable="true" size="small">
+                        <el-select v-model="searchField" style="width:120px;"  slot="prepend" :placeholder="$t('defaultText.pleaseChoose')">
+                            <el-option :label="$t('headerTop.projectName')" value=1 ></el-option>
+                            <el-option :label="$t('Itemno')" value=2 ></el-option>
+                        </el-select>
+                        <el-button slot="append" @click="searchList" icon="el-icon-search"></el-button>
+                    </el-input>
+                    </div>
+                </el-form-item>
+                <!-- 分类筛选 -->
+                <el-form-item >
+                    <span style="margin-left:5px;margin-right:5px;color:#606266;">{{ $t('fen-lei') }}</span>
+                    <el-select v-model="statusClf" style="width:140px;"  :placeholder="$t('defaultText.pleaseChoose')" clearable @change="searchClfList" size="small">
+                        <el-option v-for="item in baseClfList" :key="item.id" :label="item.name" :value="item.id" ></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item style="float:right;">
+                    <el-link type="primary" :underline="false" @click="handleAdd(-1,null)">{{'新增'}}</el-link>
+                </el-form-item>
+            </el-form>
+        </el-col>
+        <!--列表-->
+        <el-table ref="projectlistOfWudulist" border @cell-mouse-enter="hoverCall" @cell-mouse-leave="handCall" :cell-class-name="tableCellClassName" :data="list" highlight-current-row v-loading="listLoading" :height="tableHeight" style="width: 100%;" @selection-change="checkedWudulist">
+            <el-table-column type="selection" width="60" :selectable="isSelectable">
+            </el-table-column>
+            <el-table-column prop="projectCode" :label="$t('Itemno')"  width="150"></el-table-column>
+            <el-table-column prop="projectName" :label="$t('headerTop.projectName')" min-width="250" ></el-table-column>
+            <el-table-column prop="categoryName" :label="$t('projectclassification')"  width="140"></el-table-column>
+            <el-table-column prop="isPublic" :label="'项目类型'"  width="140">
+                <template slot-scope="scope">{{scope.row.isPublic==0?"正式项目":"非项目"}}</template>
+            </el-table-column>
+            <el-table-column prop="inchargerName" :label="$t('projectmanager')"  min-width="150">
+                <template slot-scope="scope">
+                    <el-link type="primary" :underline="false" @click="showUser(scope.row.inchargerId)">
+                        <span v-if="user.userNameNeedTranslate != 1">
+                            {{scope.row.inchargerName}}
+                        </span>
+                        <span v-if="user.userNameNeedTranslate == 1">
+                            <ww-open-data type='userName' :openid='scope.row.inchargerName'></ww-open-data>
+                        </span>
+                    </el-link>
+                </template>
+            </el-table-column>
+            <!-- 级别 -->
+            <el-table-column :prop="user.timeType.projectLevelState == 1 ? 'levelName' : 'level'" :label="$t('ji-bie')" min-width="190"   v-if="user.company.packageProject == 1">
+                <template slot-scope="scope">
+                    <span v-if="user.timeType.projectLevelState == 1">{{scope.row.levelName}}</span>
+                    <span v-else>{{importanceListLable[scope.row.level - 1]}}</span>
+                </template>
+            </el-table-column>
+            <el-table-column prop="status" :label="'审核状态'" min-width="100" >
+                <template slot-scope="scope">
+                    {{scope.row.status == null?"-":approvalStatusStr[scope.row.status]}}
+                </template>
+            </el-table-column>
+            <el-table-column :label="$t('operation')" :width="300" align="left" fixed="right">
+                <template slot-scope="scope">
+                    <el-button size="mini" type="primary" @click="handleAdd(scope.$index, scope.row)">{{'编辑'}}</el-button>
+                    <el-button size="mini"  @click="restartPro(scope.row)">{{'通过'}}</el-button>
+                    <el-button size="mini"  @click="restartPro(scope.row)">{{'驳回'}}</el-button>
+                    <el-button size="mini"  @click="restartPro(scope.row)">{{'撤销'}}</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+
+        <!--工具条 footer-->
+        <el-col :span="24" class="toolbar">
+            <el-pagination :key="projectListPageComponentKey"
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+                :page-sizes="[20 , 50 , 80 , 100]"
+                :page-size="size"
+                :current-page.sync="page"
+                layout="total, sizes, prev, pager, next"
+                :total="total"
+                style="float:right;"
+            ></el-pagination>
+        </el-col>
+
+        <!--新增界面-->
+        <el-dialog :title="title" v-if="addFormVisible" :visible.sync="addFormVisible" :close-on-click-modal="false" customClass="customWidth" width="960px" :top="'6vh'">
+            <div style="height: 72vh;overflow-y: auto;overflow-x: hidden;">
+                <el-form ref="form1" :model="addForm" :rules="rules" label-width="120px">
+                    <el-form-item :label="$t('Itemno')" :class="title == $t('newproject')" v-if="user.companyId!=936">
+                        <!-- <el-input v-model="addForm.code" :disabled="!permissions.projectManagement && addForm.creatorId != user.id" placeholder="请输入项目编号" clearable></el-input> -->
+                        <el-input v-model="addForm.code" :placeholder="$t('peaseenterthe')" clearable :disabled="canOnlyModParticipator || (!permissions.projectManagement && addForm.creatorId != user.id && !permissions.projectCodeAndName)" maxlength="50" show-word-limit="true"></el-input>
+                    </el-form-item>
+                    <el-form-item :label="$t('headerTop.projectName')" prop="name">
+                        <!-- <el-input v-model="addForm.name" :disabled="!permissions.projectManagement && addForm.creatorId != user.id" placeholder="请输入项目名称" clearable></el-input> -->
+                        <el-input v-model="addForm.name" :placeholder="$t('peaseenterthe')" clearable :disabled="canOnlyModParticipator || (!permissions.projectManagement && addForm.creatorId != user.id && !permissions.projectCodeAndName) || isShowProjectName" maxlength="255" show-word-limit="true"></el-input>
+                    </el-form-item>
+                    <el-form-item :label="$t('projectclassification')" v-if="user.timeType.mainProjectState != '1'">
+                        <!-- <el-select v-model="addForm.category"  style="width:32%;" clearable :disabled="!permissions.projectManagement && addForm.creatorId != user.id"> -->
+                        <el-select v-model="addForm.category"  style="width:32%;" clearable filterable :disabled="canOnlyModParticipator">
+                            <el-option v-for="(item) in baseClfList" :key="item.id" :value="item.id" :label="item.name"></el-option>
+                        </el-select>
+                    </el-form-item>
+                    <el-form-item :label="$t('projecttype')" :class="title == $t('newproject') && user.companyId == 936 ? 'wpgCssClass' : ''" prop="isPublic">
+                        <el-select v-model="addForm.isPublic" style="width:32%;" @change="selectPublic" :disabled="canOnlyModParticipator">
+                            <el-option :value="0" :label="$t('zheng-shi-xiang-mu')"></el-option>
+                            <el-option :value="1" :label="$t('fei-xiang-mu')"></el-option>
+                        </el-select>
+                    </el-form-item>
+                    <el-form-item :label="$t('other.projectDescription')" prop="projectDesc">
+                        <!-- <el-input v-model="addForm.projectDesc" :disabled="!permissions.projectManagement && addForm.creatorId != user.id" placeholder="请输入项目描述" clearable maxlength="4000"></el-input> -->
+                        <el-input v-model="addForm.projectDesc" :placeholder="$t('peaseenterthe')" clearable maxlength="4000" :disabled="canOnlyModParticipator" show-word-limit></el-input>
+                    </el-form-item>
+                    <el-form-item :label="$t('Allparticipants')" v-show="addForm.isPublic == 0" :class="title == $t('newproject') && user.companyId == 936 ? 'wpgCssClass' : ''">
+                        <el-tooltip placement="top" effect="light" v-if="user.userNameNeedTranslate != 1">
+
+                            <div slot="content" style="width:780px">{{addForm.userNames}}</div>
+                            <el-input  @focus="showChooseMembTree" v-model="addForm.userNames"></el-input>
+                        </el-tooltip>
+
+                        <el-tooltip placement="top" effect="light" v-if="user.userNameNeedTranslate == 1">
+                            <div slot="content" style="width:780px">
+                                <span v-for="(item, index) in addFormUserNames" :key="index">
+                                    <!-- {{item}} -->
+                                    <ww-open-data type='userName' :openid='item'></ww-open-data>
+                                    <span v-if="index < addFormUserNames.length - 1">,</span>
+                                </span>
+                            </div>
+                            <div @click="showChooseMembTree" style="width: 800px;overflow:hidden;white-space:nowrap;height:40px;border: 1px solid #DCDFE6;border-radius: 4px;box-sizing: border-box;padding: 0 10px">
+                                <span v-for="(item, index) in addFormUserNames" :key="index">
+                                    <!-- {{item}} -->
+                                    <ww-open-data type='userName' :openid='item'></ww-open-data>
+                                    <span v-if="index < addFormUserNames.length - 1">,</span>
+                                </span>
+                            </div>
+                        </el-tooltip>
+                    </el-form-item>
+                    <el-form-item :label="$t('projectmanager')" :class="title == $t('newproject') && user.companyId == 936 ? 'wpgCssClass' : ''" v-if="user.company.nonProjectSimple == 0 || (user.company.nonProjectSimple == 1 && addForm.isPublic == 0)">
+                       <el-select v-if="user.userNameNeedTranslate != 1" v-model="addForm.inchargerId" filterable :placeholder="$t('defaultText.pleaseChoose')" style="width:32%;" :disabled="canOnlyModParticipator || projectManagerEdit">
+                            <el-option v-for="item in participator" :key="item.id" :label="item.name" :value="item.id">
+                                <span style="float: left">{{ item.name }}</span>
+                            </el-option>
+                        </el-select>
+                        <selectCat v-if="user.userNameNeedTranslate == 1" :size="'medium'" :subject="participator" :subjectId="addForm.inchargerId" :distinction="'3'" @selectCal="selectCal" :disabled="canOnlyModParticipator || projectManagerEdit || isShowProjectName"></selectCat>
+                    </el-form-item>
+
+                    <el-form-item :label="$t('newspaperauditor')">
+                        <el-select v-if="user.userNameNeedTranslate != '1'" @change="$forceUpdate()" v-model="addForm.auditUserIds"  :disabled="!(permissions.projectManagement|| user.id == addForm.inchargerId || user.id == addForm.creatorId)" filterable :placeholder="$t('defaultistheprojectleader')" style="width:100%;" :multiple="user.timeType.reportAuditType != 6" >
+                            <el-option v-for="item in participator" :key="item.id" :label="item.name" :value="item.id"></el-option>
+                        </el-select>
+                        <selectCat v-if="user.userNameNeedTranslate == '1'" :size="'medium'" :tile="true" :widthStr="'800'" :disabled="!(permissions.projectManagement|| user.id == addForm.inchargerId || user.id == addForm.creatorId)" :subjectId="addForm.auditUserIds" :subject="participator" :clearable="false" :distinction="'10'"  :multiSelect="user.timeType.reportAuditType != 6" @selectCal="selectCal"></selectCat>
+                    </el-form-item>
+                    <el-form-item :label="$t('ommencementDate')" prop="planStartDate"  v-if="(user.company.nonProjectSimple == 0 || (user.company.nonProjectSimple == 1 && addForm.isPublic == 0))">
+                        <el-date-picker v-model="addForm.planStartDate" :disabled="canOnlyModParticipator"
+                        :editable="false" style="width:32%;" 
+                        format="yyyy-MM-dd" 
+                        value-format="yyyy-MM-dd"
+                        :clearable="false" type="date" 
+                        :placeholder="$t('optiondate')"></el-date-picker>
+
+                        <span style="margin-left:63px;margin-right:10px;" >{{ $t('ji-hua-jie-shu-ri-qi') }}</span>
+                        <el-date-picker v-model="addForm.planEndDate" style="width:33%;"
+                        :editable="false" :disabled="canOnlyModParticipator"
+                        format="yyyy-MM-dd" 
+                        value-format="yyyy-MM-dd"
+                        :clearable="false" type="date" 
+                        :placeholder="$t('optiondate')"></el-date-picker>
+                    </el-form-item>
+                    <!-- 项目基线 -->
+                    <div style="margin: 10px 0 30px 0;min-height:200px;" v-if="user.company.packageProject == 1 && !canOnlyModParticipator && (user.company.nonProjectSimple == 0 || (user.company.nonProjectSimple == 1 && addForm.isPublic == 0))">
+                        <el-tabs v-model="activeName" @tab-click="handleClick">
+                        <el-tab-pane :label="$t('costbaseline')" name="baseCostPanel"  >
+                            <div style="padding-top:10px;">
+                                <!--新版 -->
+                                <span class="rg_span" v-for="(item, index) in projectBaseCostData" :key="item.id">
+                                    <span style="width:120px;display: inline-block;" v-if="user.company.packageProject==1">{{item.baseName}}</span>
+                                    <el-input :id="'baseCost'+index" @input="addUpfun()" v-model="item.baseAmount" style="width:200px; margin-bottom: 20px"
+                                    :placeholder="$t('zheng-shu')" clearable  @keyup.native="restrictNumber('baseCost'+index)"></el-input><span style="margin-left:10px;">{{ $t('yuan') }}</span>
+                                </span>    
+
+                                <!-- 合计 -->
+                                <div style="margin-top: 10px;float:right;">
+                                    <span style="margin-right:50px;margin-right:10px;" v-if="user.company.packageProject==1">{{ $t('other.totals') }}</span>
+                                    <span v-if="addForm.budget <= 0 || addForm.budget == undefined">0</span>
+                                    <span v-else>{{addForm.budget | numberToCurrency}}</span>
+                                    <span style="margin-right:50px;margin-left:10px;">{{ $t('yuan') }}</span>
+                                </div>
+                            </div>
+                        </el-tab-pane>
+                        </el-tabs>
+                    </div>
+                
+                </el-form>  
+            </div>
+            <div slot="footer" class="dialog-footer;">
+                <el-button @click.native="deletePro(1, addForm)" v-if="(permissions.projectManagement || user.id==deleteVif) && addForm.id" style="float:left">{{ $t('btn.delete') }}</el-button>
+                <el-button @click.native="addFormVisible = false">{{ $t('btn.cancel') }}</el-button>
+                <el-button type="primary" @click="submitInsert" :loading="addLoading">{{ $t('btn.submit') }}</el-button>
+            </div>
+        </el-dialog>
+        <!-- 按部门选择人员 -->
+        <el-dialog :title="$t('selectingParticipants')"  :visible.sync="chooseParticipVisible" :close-on-click-modal="false" customClass="customWidth" width="500px">
+            <!-- <el-input style="width:100%" v-model="filterName" placeholder="请输入姓名搜索" @change="findUserInTree"></el-input> -->
+            <div v-if="user.userNameNeedTranslate == '1'">
+                <el-input placeholder="请输入内容" v-model.trim="filterText" class="input-with-select">
+                    <el-button slot="append" icon="el-icon-search" @click="echartDepartment()"></el-button>
+                </el-input>
+            </div>
+            
+            <div class="tree" style="height:400px">
+                <el-scrollbar style="height:100%">
+                    <el-input
+                    :placeholder="$t('keywordfiltering')"
+                    v-model="filterText" v-if="user.userNameNeedTranslate != '1'">
+                    </el-input>
+                    <el-tree :data="deptMembData" :key="searchPersonnelFlgnum" show-checkbox :default-expand-all="searchPersonnelFlg" :props="defaultProps" node-key="id"
+                        ref="chooseMembTree" @check-change="onTreeItemChange" :default-checked-keys="addForm.userId"
+                        highlight-current  :filter-node-method="filterNode">
+                        <span class="custom-tree-node" slot-scope="{ node, data }">
+                            <span v-if="user.userNameNeedTranslate == '1'">
+                                <span v-if="node.data.children">
+                                    <ww-open-data type='departmentName' :openid='node.label'></ww-open-data>
+                                </span>
+                                <span v-else>
+                                    <ww-open-data type='userName' :openid='node.label'></ww-open-data>
+                                </span>
+                            </span>
+                            <span v-if="user.userNameNeedTranslate != '1'">
+                                {{ node.label }}
+                            </span>
+                            <!-- {{ node.label }} -->
+                        </span>
+                    </el-tree>
+                </el-scrollbar>
+            </div>
+            <div>{{ $t('btn.choose') }}&nbsp;{{chosenMembCount}}&nbsp;{{ $t('other.people') }}</div>
+            <div slot="footer" class="dialog-footer">
+                <el-button  @click="chooseParticipVisible = false" >{{ $t('btn.cancel') }}</el-button>
+                <el-button type="primary" @click="chooseParticip()" >{{ $t('btn.determine') }}</el-button>
+            </div>
+        </el-dialog>
+         <!--用户详细信息弹出框-->
+         <el-dialog :title="$t('Checkthedetails')" v-if="userDetailVisible" :visible.sync="userDetailVisible" :close-on-click-modal="false" customClass="customWidth" width="400px">
+            <div class="line"><span>{{ $t('lable.name') +":"}}</span>
+                <span v-if="user.userNameNeedTranslate != 1">{{userDetail.name}}</span>
+                <span v-if="user.userNameNeedTranslate == 1"><ww-open-data type='userName' :openid='userDetail.name'></ww-open-data></span>
+            </div>
+            <div class="line"><span>{{ $t('Worknumber') +":"}}</span><span>{{userDetail.jobNumber}}</span></div>
+            <div class="line"><span>{{ $t('lable.phone') +":"}}</span><span>{{userDetail.phone}}</span></div>
+            <div class="line"><span>{{ $t('jiao-se') +":"}}</span><span>{{userDetail.roleName}}</span></div>
+            <div class="line"><span>{{ $t('lable.department') +":"}}</span>
+
+                <span v-if="user.userNameNeedTranslate != 1">{{userDetail.departmentName}}</span>
+                <span v-if="user.userNameNeedTranslate == 1"><ww-open-data type='departmentName' :openid='userDetail.departmentName'></ww-open-data></span>
+            </div>
+            <div slot="footer" class="dialog-footer">
+                <el-button type="primary" @click="userDetailVisible = false" >{{ $t('btn.determine') }}</el-button>
+            </div>
+        </el-dialog>
+    </section>
+</template>
+
+<script>
+export default {
+name: '',
+components: {},
+props: { },
+data() { 
+return {
+    keyword:"",
+    searchField:"1",
+    user: JSON.parse(sessionStorage.getItem("user")),
+    total: 0,
+    page: 1,
+    size: localStorage.getItem("projectPageSize")==null?20:parseInt(localStorage.getItem("projectPageSize")),
+    listLoading:false,
+    approvalStatusStr:["待审核","已通过","已驳回"],
+    importanceList:[{id:1,label:this.$t('zheng-chang')},{id:2,label:this.$t('jin-ji')},{id:3,label:this.$t('zhong-yao')},{id:4,label:this.$t('zhong-yao-qie-jin-ji')}],
+    importanceListLable:[this.$t('zheng-chang'), this.$t('jin-ji'), this.$t('zhong-yao'), this.$t('zhong-yao-qie-jin-ji'), this.$t('di-feng-xian'), this.$t('zhong-feng-xian'), this.$t('gao-feng-xian')],
+    addFormVisible:false,
+    baseCostItemList:[],
+    permissions: JSON.parse(sessionStorage.getItem("permissions")),
+    addForm: {
+        name: '',
+        userId: [],
+        level:1,
+        bu:'',
+        id: '',
+        code: '',
+        projectDesc: '',
+        alarmType: 0
+    },
+    projectBaseCostData:[],
+    activeName:"baseCostPanel",
+    baseClfList:[],
+    addFormUserNames: [],
+    deptMembData: [
+        {
+            id: 0,
+            label: this.$t('lable.unassigned'),
+        }
+    ],
+    allMembData:[],
+    participator:[],
+    chosenListBackup: [], 
+    chooseParticipVisible:false,
+    rules: {
+        name: [{ required: true, message: this.$t('pleaseentername'), trigger: "blur" }],
+        code: [{ required: true, message: this.$t('qing-shu-ru-bian-hao'), trigger: "blur" }],
+        projectStageName: [{ required: true, message: this.$t('pleaseentername'), trigger: "blur" }],
+        projectLevelName: [{ required: true, message: this.$t('pleaseentername'), trigger: "blur" }],
+        deptId: [{ required: true, message: '请选择所属部门', trigger: "blur" }]
+    },
+    chosenMembCount:0,
+    dataDetail:{},
+    userDetailVisible:false,
+    userDetail:{},
+}
+},
+computed: {},
+watch: {},
+created () {},
+mounted () {
+    this.getList();
+    this.getProjectBaseConfigList();
+    this.getClfConfigList();
+    this.getDepartment();
+    this.getUsers();
+},
+methods: {
+    isSelectable(row,index){
+        if(row.creatorId == this.user.id || row.inchargerId == this.user.id || this.permissions.projectApprovalEdit){
+            return true
+        }else{
+            return false
+        }
+    },
+    submitInsert() {
+        this.$refs.form1.validate(valid => {
+            if (valid) {
+                this.addLoading = true;
+                let targetData = {};
+                targetData.projectName= this.addForm.name
+                if(this.addForm.projectDesc != null) {
+                    targetData.projectDesc=this.addForm.projectDesc
+                }
+                if(this.addForm.id != null) {
+                    targetData.id=this.addForm.id
+                }
+                if(this.addForm.isPublic != null) {
+                    targetData.isPublic=this.addForm.isPublic
+                }
+                if(this.addForm.userId.length != 0 && this.addForm.isPublic == 0) {
+                    let userArray=[]
+                    for(let i in this.addForm.userId){
+                        userArray.push({
+                            "userId":this.addForm.userId[i]
+                        })
+                    }
+                    targetData.participationApprovalList=userArray
+                }
+                if(this.addForm.inchargerId != null) {
+                    targetData.inchargerId=this.addForm.inchargerId
+                }
+                if(this.addForm.code != null) {
+                    targetData.projectCode=this.addForm.code
+                }
+                if(this.addForm.planStartDate != null) {
+                    targetData.planStartDate=this.addForm.planStartDate
+                }
+                if(this.addForm.planEndDate != null) {
+                    targetData.planEndDate=this.addForm.planEndDate
+                }
+                if(this.addForm.level != null) {
+                    targetData.level=this.addForm.level
+                }
+                if(this.addForm.contractAmount != null) {
+                    targetData.contractAmount=this.addForm.contractAmount
+                }
+                if (this.projectBaseCostData != null) {
+                    targetData.projectApprovalBasecostList=this.projectBaseCostData
+                    //计算总预算成本
+                    if (this.addForm.budget == null) {
+                        this.addForm.budget = 0;
+                    }
+                    targetData.budget=this.addForm.budget
+                }
+                if (this.addForm.contractAmount) {
+                    targetData.contractAmount=this.addForm.contractAmount
+                } else {
+                    targetData.contractAmount=0
+                }
+                if (this.user.timeType.outputValueStatus == 1){
+                    targetData.outputValue=this.addForm.outputValue ? this.addForm.outputValue : 0
+                }
+                //日报审核人
+                if (this.addForm.auditUserIds) {
+                    targetData.auditUserIds=this.addForm.auditUserIds
+                }
+                if(this.addForm.auditUserIds.length != 0) {
+                    let userArray=[]
+                    for(let i in this.addForm.auditUserIds){
+                        userArray.push({
+                            "auditorId":this.addForm.auditUserIds[i]
+                        })
+                    }
+                    targetData.projectApprovalAuditorList=userArray
+                }
+                if(this.addForm.category != null) {
+                    targetData.category=this.addForm.category
+                }
+                this.http.JSONPost("/project-approval/editProjectApproval",targetData,
+                res => {
+                    this.addLoading = false;
+                    if (res.code == "ok") {
+                        this.$message({
+                            message: (this.addForm.id!=null?this.$t('xiu-gai'):this.$t('create'))+this.$t('other.successful'),
+                            type: "success"
+                        });
+                        this.addFormVisible = false;
+                        this.getList();
+                        if (this.user.company.packageEngineering == 1) {
+                            this.saveProjectProfessions(res.data);
+                        }
+                    } else {
+                        this.$message({
+                            message: res.msg,
+                            type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.addLoading = false;
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            }
+        });
+    },
+    // 获取分类条目
+    getClfConfigList() {
+        this.http.get('/project-category/list',
+            res => {
+                if (res.code == "ok") {
+                    this.baseClfList = res.data;
+                //    console.log("获取分类条目",res.data);
+                    this.$forceUpdate();
+                } else {
+                    this.$message({
+                        message: res.msg,
+                        type: "error"
+                    });
+                }
+            },
+            error => {
+                this.$message({
+                    message: error,
+                    type: "error"
+                });
+                }
+            );
+        
+    },
+    //分页
+    handleCurrentChange(val) {
+        this.page = val;
+        this.getList();
+    },
+
+    handleSizeChange(val) {
+        this.size = val;
+        localStorage.projectPageSize = this.size;
+        this.page = 1
+        this.getList();
+    },
+    getProjectBaseConfigList() {
+        this.http.post('/project-basecost-setting/list',{},
+            res => {
+                if (res.code == "ok") {
+                    this.baseCostItemList = res.data;
+                    this.$forceUpdate();
+                } else {
+                    this.$message({
+                        message: res.msg,
+                        type: "error"
+                    });
+                }
+            },
+            error => {
+                this.$message({
+                    message: error,
+                    type: "error"
+                });
+            }
+        );
+    },
+    //显示新增界面
+    handleAdd(i, item) {
+        if(i == -1) {
+            this.title = this.$t('newproject');
+            this.addForm = {
+                name: '',
+                isPublic:0,
+                userId: [],
+                userNames:'',
+                code:'',
+                inchargerId:null,
+                level: this.user.timeType.projectLevelState == 1 ? (this.levelList.length > 0 ? this.levelList[0].id : null) : 1,
+                customerId:null,
+                notifyUserNames:'',
+                chosenLeaders:[],
+                category:null,
+                creatorId: this.user.id,
+                projectMainId: '',
+                outputValue: '',
+                bu: [],
+                manDay:0,
+                fromOutside: 0,
+            }
+            this.projectBaseCostData = [];
+            this.auseList = [];
+            for (var m=0;m<this.baseCostItemList.length; m++) {
+                this.projectBaseCostData.push({baseId: this.baseCostItemList[m].id, baseName:this.baseCostItemList[m].name, baseAmount:0});
+            }
+        } else {
+            this.http.post('/project-approval/getDetail', {id: item.id},
+            res => {
+            if (res.code == "ok") {
+                this.dataDetail=res.data
+            }
+            });
+            var arr=[]
+            var names=""
+            var auditorArr=[]
+            if(this.dataDetail.participationApprovalList){
+                for(let i in this.dataDetail.participationApprovalList){
+                    arr.push(this.dataDetail.participationApprovalList[i].userId);
+                }
+                this.participator=this.dataDetail.participationApprovalList
+            }
+            if(this.dataDetail.participationApprovalList){
+                for(let i in this.dataDetail.participationApprovalList){
+                    names+=this.dataDetail.participationApprovalList[i].userName+",";
+                }
+            }
+            // if (names.length > 0) {
+            //     names = names.substring(0, names.length -1);
+            // }
+            if(this.dataDetail.projectApprovalAuditorList){
+                for(let i in this.dataDetail.projectApprovalAuditorList){
+                    auditorArr.push(this.dataDetail.projectApprovalAuditorList[i].auditorId)
+                }
+            }
+            if (names.length > 0) {
+                names = names.substring(0, names.length -1);
+            }
+            this.addForm = {
+                id: item.id,
+                name: item.projectName,
+                userId: arr,
+                auditUserIds:auditorArr,
+                userNames:names,
+                isPublic: item.isPublic,
+                code:item.projectCode,
+                inchargerId: item.inchargerId,
+                level: item.level,
+                planStartDate: item.planStartDate,
+                planEndDate: item.planEndDate,
+                budget: item.budget,
+                baseMan: item.baseMan,
+                contractAmount: item.contractAmount,
+                baseFee: item.baseFee,
+                baseRisk1: item.baseRisk1,
+                baseRisk2: item.baseRisk2,
+                baseOutsourcing: item.baseOutsourcing,
+                customerId:item.customerId==0?null:item.customerId,
+                category:item.category,
+                projectDesc: item.projectDesc,
+                creatorId: item.creatorId,
+                outputValue: item.outputValue,
+            }
+            this.changeParticipator();
+            this.getProjectBaseData(item.id);
+        }
+        console.log('=========>',this.participator)
+        this.addFormVisible = true;
+    },
+    //获取项目列表
+    getList() {
+        localStorage.projectPageIndex = this.page;
+        this.listLoading = true;
+        let parameter = {
+            pageIndex: this.page,
+            pageSize: this.size,
+            keyword:this.keyword,
+            searchField: this.searchField,
+            category:this.statusClf,
+            status: this.status,
+        }
+        this.http.post("/project-approval/listByPage", parameter,
+        res => {
+            this.listLoading = false;
+            if (res.code == "ok") {
+                var list = res.data.records;
+                this.list = list;
+                this.total = res.data.total;
+            } else {
+                this.$message({
+                message: res.msg,
+                type: "error"
+                });
+            }
+        },
+        error => {
+            this.listLoading = false;
+            this.$message({
+                message: error,
+                type: "error"
+            });
+        });
+    },
+    // 项目基线合计
+    addUpfun() {
+        var total = 0;
+        for (var i=0;i<this.projectBaseCostData.length; i++) {
+            if (this.projectBaseCostData[i].baseAmount) {
+                total += parseFloat(this.projectBaseCostData[i].baseAmount);
+            }
+        }
+        this.addForm.budget = total;
+    },
+    restrictNumber(targetId) {
+        let inpu = document.getElementById(targetId);
+        inpu.value = inpu.value.replace(/[^\d.]/g, "");  //仅保留数字和"."
+        inpu.value = inpu.value.replace(/\.{2,}/g, "."); //两个连续的"."仅保留第一个"."
+        inpu.value = inpu.value.replace(".", "$#*").replace(/\./g,'').replace('$#*','.');//去除其他"."
+        inpu.value = inpu.value.replace(/^(\d+)\.(\d\d).*$/, '$1.$2');;//限制只能输入两个小数
+        if (inpu.value.indexOf(".") < 0 && inpu.value != "") { //首位是0的话去掉
+            inpu.value = parseFloat(inpu.value);
+        }
+    },
+    showChooseLeaderTree() {
+        this.chosenMembCount = this.chosenLeaders.length;
+        this.chooseLeaderVisible = true;
+    },
+    onLeaderTreeItemChange() {
+        var chosenList = this.$refs.chooseLeaderTree.getCheckedNodes();
+        var list = chosenList.filter(item=>item.isUser == 1);
+        this.chosenMembCount = list.length;
+    },
+
+    showChooseMembTree() {
+        this.deptMembData = JSON.parse(JSON.stringify(this.allMembData))
+        this.chosenMembCount = this.participator.length;
+        this.chooseParticipVisible = true;
+        this.filterText = ''
+        this.wxFilterText = ''
+        if(this.user.userNameNeedTranslate == 1) {
+            this.getDepartment()
+        }
+        let that = this
+        setTimeout(()=>{    
+            that.chosenListBackup = that.$refs.chooseMembTree.getCheckedNodes();
+        }, 500)
+    },
+    onTreeItemChange() {
+        var chosenList = this.$refs.chooseMembTree.getCheckedNodes();
+        var list = chosenList.filter(item=>item.isUser == 1);
+        this.chosenMembCount = list.length;
+    },
+    findUserInTree() {
+        if (this.filterName == '') {
+            this.deptMembData = this.allMembData;
+        } else {
+            var list = this.findRecursively(this.filterName, this.allMembData);
+            this.deptMembData = list;
+        }
+    },
+
+    findRecursively(username, list) {
+        var filterList = [];
+        for (var i=0;i<list.length; i++) {
+            if (list[i].isUser == 1) {
+                if (list[i].label.indexOf(username) >= 0) {
+                    //匹配上了
+                    filterList.push(list[i]);
+                }
+            } else if (list[i].children != null && list[i].children.length > 0) {
+                var subList = this.findRecursively(username, list[i].children);
+                if (subList.length > 0) {
+                    subList.forEach(s=>filterList.push(s));
+                }
+            }
+        }
+        return filterList;
+    },
+
+    //确定选择参与人
+    chooseParticip() {
+        this.chooseParticipVisible = false;
+        var chosenList = this.$refs.chooseMembTree.getCheckedNodes();
+        if(this.searchPersonnelFlg) {
+            chosenList = [...chosenList, ...this.chosenListBackup]
+        }
+        this.chosenMembList = chosenList.filter(item=>item.isUser == 1);
+        this.addForm.userNames = '';
+        this.addFormUserNames = []
+        this.addForm.userId = [];
+        this.participator = [];
+        for (var i=0;i<this.chosenMembList.length; i++) {
+            this.addForm.userId.push(this.chosenMembList[i].id);
+            this.addForm.userNames += this.chosenMembList[i].label+',';
+            this.addFormUserNames.push(this.chosenMembList[i].label)
+            var item = {id:this.chosenMembList[i].id, name:this.chosenMembList[i].label};
+            this.participator.push(item);
+        }
+        if (this.addForm.userNames.length > 0) {
+            this.addForm.userNames = this.addForm.userNames.substring(0, this.addForm.userNames.length-1);
+        }
+    },
+    // 获取部门列表
+    getDepartment() {
+        this.http.post("/department/listAllMemb", {},
+        res => {
+            if (res.code == "ok") {
+                var list = res.data;
+                //设置员工到部门下面
+                this.setUserToDept(list);
+                this.deptMembData = list;
+                console.log(this.deptMembData, '看看数据')
+                
+                //用于筛选过滤
+                this.allMembData = JSON.parse(JSON.stringify(this.deptMembData));
+            } else {
+                this.$message({
+                    message: res.msg,
+                    type: "error"
+                });
+            }
+        },
+        error => {
+            this.$message({
+                message: error,
+                type: "error"
+            });
+        });
+    },
+    onTreeItemChange() {
+        var chosenList = this.$refs.chooseMembTree.getCheckedNodes();
+        var list = chosenList.filter(item=>item.isUser == 1);
+        this.chosenMembCount = list.length;
+    },
+    findUserInTree() {
+        if (this.filterName == '') {
+            this.deptMembData = this.allMembData;
+        } else {
+            var list = this.findRecursively(this.filterName, this.allMembData);
+            this.deptMembData = list;
+        }
+    },
+    addPersonCheck(){
+        var chosenList = this.$refs.chooseMembTree2.getCheckedNodes();
+        var list = chosenList.filter(item=>item.isUser == 1);
+        this.chosenMembCount = list.length;
+        // console.log(list);
+    },
+    addPersonSure(){
+        this.addGroupPersonPdialog = false
+        let chosenList = this.$refs.chooseMembTree2.getCheckedNodes();
+        let list = chosenList.filter(item=>item.isUser == 1);
+        let listIDs = []
+        let listNames = ''
+        let listNamesList = []
+        for(let i=0;i<list.length;i++){
+            listIDs.push(list[i].id)
+            listNames += list[i].label + ','
+            listNamesList.push(list[i].label)
+        }
+        this.addGroupPersonData.person = listIDs
+        this.addGroupPersonData.personNames = listNames
+        this.addGroupPersonDataPersonNames = listNamesList
+        console.log('触发', this.addGroupPersonDataPersonNames)
+    },
+    // 企业微信搜索
+    echartDepartment() {
+        console.log('我点击了搜索')
+        if(this.filterText != '') {
+            this.http.post("/user/getEmployeeList", {
+                keyword: this.filterText,
+                cursor: '',
+                departmentId: -1,
+                pageIndex: 1,
+                pageSize: 1000
+            },
+            res => {
+                if (res.code == "ok") {
+                    this.filterNodePersonnel = res.data.records.map(item => item.name)
+                    this.$refs.chooseMembTree.filter(this.filterText);
+                } else {
+                    this.$message({
+                        message: res.msg,
+                        type: "error"
+                    });
+                }
+            },
+            error => {
+                this.$message({
+                    message: error,
+                    type: "error"
+                });
+            });
+        } else {
+            this.searchPersonnelFlgnum = +this.searchPersonnelFlgnum +1
+            this.searchPersonnelFlg = false
+            this.getDepartment()
+        }
+    },
+    setUserToDept(list) {
+        for (var i in list) {
+            if (list[i].children != null) {
+                this.setUserToDept(list[i].children);
+            }
+            
+            if (list[i].userList != null) {
+                if (list[i].children == null) {
+                    list[i].children = [];
+                }
+                list[i].userList.forEach(element => {
+                    var obj = {id: element.id, label:element.name, parentId:element.departmentId, isUser:1};
+                    list[i].children.push(obj);
+                });
+            }
+        }
+    },
+    formDataToObject(formData) {
+        const object = {};
+        for (const [key, value] of formData.entries()) {
+            if (key in object) {
+            object[key] = [].concat(object[key], value);
+            } else {
+            object[key] = value;
+            }
+        }
+        return object;
+    },
+    searchList() {
+        this.page = 1;
+        this.getList();
+    },
+    // 分类筛选
+    searchClfList(){
+        this.page = 1;
+        this.getList();
+    },
+    getUsers() {
+        // this.http.post(this.port.manage.list, {
+        //     departmentId: -1,
+        //     pageIndex: 1,
+        //     // pageSize: 99999
+        //     pageSize: -1
+        // },
+        this.http.post('/user/getSimpleActiveUserList', {},
+        res => {
+            if (res.code == "ok") {
+                this.users = res.data;
+            } else {
+                this.$message({
+                message: res.msg,
+                type: "error"
+                });
+            }
+        },
+        error => {
+            this.$message({
+                message: error,
+                type: "error"
+            });
+        });
+    },
+    // 自定义组件事件
+    selectCal(obj) {
+        if(obj.distinction == '1') {
+            this.inchagerId = obj.id
+            this.manageSelect()
+        } else if(obj.distinction == '2') {
+            this.participationId = obj.id
+            this.participationSelect()
+        } else if(obj.distinction == '3') {
+            this.addForm.inchargerId = obj.id
+            // console.log(this.participator)
+            this.participator = JSON.parse(JSON.stringify(this.participator))
+        } else if(obj.distinction =='4') {
+            this.projectProfessionList[obj.other].inchargerId = obj.id
+        } else if(obj.distinction =='5') {
+            this.paramInchargerId = obj.id
+        }else if(obj.distinction =='6') {
+            this.hasSetGroupInchargerId = obj.id
+        } else if(obj.distinction == '10') {
+            let userList = obj.arrUserList
+            let arr = []
+            for(var i in userList) {
+                arr.push(userList[i].id)
+            }
+            this.participator = JSON.parse(JSON.stringify(this.participator))
+            this.addForm.auditUserIds = arr
+        } else if(obj.distinction == '11') {
+            let userList = obj.id
+            console.log(obj)
+            this.curProfessionRow.membList[obj.other].membId = userList
+        }
+    },
+    getProjectBaseData(projectId) {
+        this.http.post('//project-approval-basecost/get',{projectId: projectId},
+                res => {
+                    if (res.code == "ok") {
+                        this.projectBaseCostData = res.data;
+                    } else {
+                        this.$message({
+                            message: res.msg,
+                            type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.listLoading = false;
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                    }
+                );
+    },
+    selectPublic() {
+        if (this.addForm.isPublic == 1) {
+            this.participator = this.users;
+        } else {
+            this.participator = [];
+        }
+    },
+    //选择参与人
+    changeParticipator() {
+        //检查是否在参与人中,如果没有需要加入到参与人中
+        // console.log('addform',this.addForm.userId,this.users);
+        this.participator = [];
+        this.addForm.userId.forEach(u=>{
+            var list = this.users.filter(au=>au.id == u);
+            if (list.length > 0) {
+                var findUser = list[0];    
+                this.participator.push(findUser);
+            } else {
+                console.log('未找到用户: '+u);
+            }
+            
+        })
+    },
+    //显示用户详情
+    showUser(userId) {
+        this.userDetailVisible = true;
+        this.http.post(this.port.manage.userDetail, {
+            userId: userId
+        },
+        res => {
+            if (res.code == "ok") {
+                this.userDetail = res.data;
+            } else {
+                this.$message({
+                message: res.msg,
+                type: "error"
+                });
+            }
+        },
+        error => {
+            this.$message({
+                message: error,
+                type: "error"
+            });
+        });
+    },
+},
+}
+</script>
+<style scoped lang='sass'>
+</style>
+<style>
+.toolbar_formitem_n1{
+    margin-right: 0 !important;
+}
+</style>

+ 70 - 30
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

@@ -334,6 +334,7 @@
                                         </el-timeline>
                                     </div>
                                 </div>
+                                <div v-if="hasMore && !listLoading" style="width:100%;font-size:17px;text-align:center;padding-bottom:15px;"><el-link @click="reqMore" :underline=false style="color:#20a0ff;">加载更多日报</el-link></div>
                                 <!-- 简陋的无报告提示 -->
                                 <div v-if="reportList.length==0" style="width:100%;font-size:17px;text-align:center;color:#aaa;">{{curDate}}{{$t('other.noReportYet')}}</div>
                             </div>
@@ -1982,6 +1983,8 @@
         },
         data() {
             return {
+                pageIndex: 0,
+                hasMore: true,
                 exportType: 0,
                 exportingData: false,
                 roleList:[{value: 1,label: 'CRC&LM'},{value: 2,label: 'PM'}],
@@ -5281,9 +5284,15 @@
                 curDate.setDate(0);
                 return curDate.getDate();
             },
-
-            //获取日报列表
-            getReportList() {
+            reqMore() {
+                if (this.hasMore) {
+                    this.pageIndex++;
+                    this.requestHttpReports();
+                }
+            },
+            //加载日报数据
+            requestHttpReports() {
+                //请求数据
                 this.listLoading = true;
                 let day = (this.choseDay + 1) > 9 ? "-" + (this.choseDay + 1) : "-0" + (this.choseDay + 1);
                 let param = {date: this.date + day};
@@ -5293,11 +5302,17 @@
                 if (this.targetUid) {
                     param.userId = this.targetUid;
                 }
+                //传页码
+                if (this.hasMore) {
+                    param.pageIndex = this.pageIndex;
+                }
                 this.http.post( this.port.report.list, param,
                 res => {
                     this.listLoading = false;
                     if (res.code == "ok") {
-                        this.reportList = res.data;
+                        //扩增
+                        this.reportList = this.reportList.concat(res.data.data);
+                        this.hasMore = res.data.hasMore;//标记是否还有更多数据
                         if(document.querySelector("#day"+this.choseDay)){
                             document.querySelector("#day"+this.choseDay).scrollIntoView(true);
                         }
@@ -5316,31 +5331,56 @@
                     });
                 });
             },
-            // 处理数据
-            // dealWith() {
-            //     var tianxie = 0
-            //     var weixtianxie = 0
-            //     if(this.selectState == -1) {
 
-            //     } else {
-            //         var arr = []
-            //         for (var i in this.reportList) {
-            //             arr.push(this.reportList[i].id)
-            //         }
-            //         this.getDealWith(this.dealList.children, tianxie, weixtianxie, arr)
-            //     }
-            // },
-            // getDealWith(item, tx, wtx, arr) {
-            //     for(var i in item) {
-            //         if(item[i].children) {
-            //             this.getDealWith(item[i].children, tx, wtx, arr)
-            //         } else {
-            //             if(arr.indexOf(item[i].id) != '-1') {
-            //                 tx = +tx + 1
-            //             }
-            //         }
-            //     }
-            // },
+            //获取日报列表
+            getReportList() {
+                //初始化,重置数据
+                this.pageIndex = 0;
+                this.hasMore = true;
+                this.reportList = [];
+                this.requestHttpReports();
+            },
+            //刷新日报状态,用于审核后更新
+            refreshReportData(reportId) {
+                this.http.post('/report/getDetailReportById', {reportId:reportId},
+                res => {
+                    if (res.code == "ok") {
+                        for (var m=0;m<this.reportList.length; m++) {
+                            var d = this.reportList[m].data;
+                            var find = d.filter(r=>r.id == reportId);
+                            if (find.length > 0) {
+                                find[0].state = res.data.state;
+                                if (find[0].state == 2) {//被驳回,要可以编辑
+                                    this.reportList[m].state = 2;
+                                }
+                                find[0].isDeptAudit = res.data.isDeptAudit;
+                                find[0].departmentAuditState = res.data.departmentAuditState;
+                                find[0].projectAuditorName = res.data.projectAuditorName;
+                                find[0].projectAuditorId = res.data.projectAuditorId;
+                                find[0].projectAuditState = res.data.projectAuditState;
+                                find[0].rejectUserid = res.data.rejectUserid;
+                                find[0].rejectUsername = res.data.rejectUsername;
+                                find[0].rejectReason = res.data.rejectReason;
+                                this.$forceUpdate();
+                                break;
+                            }
+                        }
+                    } else {
+                        this.$message({
+                            message: res.msg,
+                            type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.listLoading = false;
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    }); 
+                });
+            },
+            
             //导出员工工时统计
             exportUserTime() {
                 this.listLoading = true;
@@ -7765,7 +7805,7 @@
                             message: this.$t('message.Reviewsucceeded'),
                             type: "success"
                         });
-                        this.getReportList();
+                        this.refreshReportData(this.approveinData.reportIds);
                         this.getDepartment();
                     } else {
                         this.$message({
@@ -7845,7 +7885,7 @@
                             message: this.denyForm.i==0?this.$t('message.rejectedsuccessfully'):this.$t('Revocationofsuccess'),
                             type: "success"
                         });
-                        this.getReportList();
+                        this.refreshReportData(this.denyForm.reportIds);
                         this.getDepartment();
                         this.denyReasonDialog = false;
                     } else {

+ 3 - 3
fhKeeper/formulahousekeeper/timesheet_h5/src/views/my/children/center.vue

@@ -182,9 +182,9 @@
             if(localStorage.userInfo) {
                 // 日期
                 let userss = JSON.parse(localStorage.userInfo)
-                userss.company.expirationDate[2] >= 10 ? userss.company.expirationDate[2] : userss.company.expirationDate[1] = '0' + userss.company.expirationDate[2]
-                userss.company.expirationDate[1] >= 10 ? userss.company.expirationDate[1] : userss.company.expirationDate[1] = '0' + userss.company.expirationDate[1]
-                this.expirationDate = userss.company.expirationDate[0] + '-' + userss.company.expirationDate[1] + '-' + userss.company.expirationDate[2]
+                this.expirationDate = userss.company.expirationDate[0] + '-' + 
+                (userss.company.expirationDate[1] >= 10 ? userss.company.expirationDate[1] : ('0' + userss.company.expirationDate[1]))
+                 + '-' + (userss.company.expirationDate[2] >= 10 ? userss.company.expirationDate[2] : ('0' + userss.company.expirationDate[2]))
 
                 // 版本
                 userss.company.packageWorktime == 1 ? this.version = '基础版' : ''

+ 1 - 1
fhKeeper/formulahousekeeper/timesheet_h5/src/views/project/index.vue

@@ -164,7 +164,7 @@
                 ause: [],
                 projectAdd: false, // 新增项目
                 projectManagement: false, // 管理项目
-                 isDownLoading: false, // 下拉刷新
+                isDownLoading: false, // 下拉刷新
                 isUpLoading: false, // 上拉加载
                 upFinished: false, // 上拉加载完毕
                 offset: 100, // 滚动条与底部距离小于 offset 时触发load事件

+ 195 - 165
fhKeeper/formulahousekeeper/timesheet_h5/src/views/view/index.vue

@@ -3,11 +3,11 @@
         <van-nav-bar title="查看日报" left-text="返回" @click-left="back" fixed left-arrow />
 
         <div class="login_form">
-            <van-sticky :offset-top="46">
+            <van-sticky :offset-top="43">
                 <van-cell title="时间选择" clickable :value="nowTime" @click="showPicker = true" />
             </van-sticky>
             <div v-if="user.manageDeptId != 0 || reportsCompany || reportsDept">
-                <van-sticky :offset-top="90">
+                <van-sticky :offset-top="85">
                     <van-cell title="选择部门" clickable :value="departmentText" @click="selectDepartmentShow = true">
                         <template #extra>
                             <van-icon v-if="departmentText" name="close" class="clearSeach"
@@ -23,7 +23,7 @@
                         </template>
                     </van-cell>
                 </van-sticky>
-                <van-sticky :offset-top="134" class="one_report_select">
+                <van-sticky :offset-top="127" class="one_report_select">
                     <van-cell title="选择人员" clickable :value="userNameValue" @click="showUserPopu()"
                         value-class="userNameValue">
                         <template #extra>
@@ -47,145 +47,152 @@
                 <van-datetime-picker v-model="currentDate" type="date" :min-date="minDate" :max-date="maxDate"
                     @confirm="changeTime" @cancel="showPicker = false" />
             </van-popup>
-            <van-skeleton :v-if="report.length != 0" v-for="(item, index) in report" title avatar :row="3" :loading="false"
-                :key="index">
-                <van-panel class="one_report" :title="item.name" :status="statusTxt[item.state]">
-                    <template #header>
-                        <div class="van-cell van-panel__header">
-                            <div class="van-cell__title">
-                                <span v-if="user.userNameNeedTranslate == '1'"><ww-open-data type='userName'
-                                        :openid='item.name'></ww-open-data></span>
-                                <span v-else>{{ item.name }}</span>
-                            </div>
-                            <div class="van-cell__value van-panel__header-value">
-                                <span>{{ statusTxt[item.state] }}</span>
+            <!--分页,加载更多-->
+            <van-pull-refresh v-model="isDownloading" @refresh="onDownRefresh">
+                <van-list v-model="isUpLoading" :finished="upFinished" :immediate-check="false" :offset="100" finished-text="没有更多了" @load="onLoadList">
+                    <van-skeleton :v-if="report.length != 0" v-for="(item, index) in report" title avatar :row="3" :loading="false"
+                        :key="index">
+                        <van-panel class="one_report" :title="item.name" :status="statusTxt[item.state]">
+                            <template #header>
+                                <div class="van-cell van-panel__header">
+                                    <div class="van-cell__title">
+                                        <span v-if="user.userNameNeedTranslate == '1'"><ww-open-data type='userName'
+                                                :openid='item.name'></ww-open-data></span>
+                                        <span v-else>{{ item.name }}</span>
+                                    </div>
+                                    <div class="van-cell__value van-panel__header-value">
+                                        <span>{{ statusTxt[item.state] }}</span>
+                                    </div>
+                                </div>
+                            </template>
+                            <div class="form_text">
+                                <span style="margin-right:20px;margin-left:5px;font-size:14px;">
+                                    总填报:
+                                    <span>{{ parseFloat(item.reportTime).toFixed(1) }}h</span>
+                                </span>
                             </div>
-                        </div>
-                    </template>
-                    <div class="form_text">
-                        <span style="margin-right:20px;margin-left:5px;font-size:14px;">
-                            总填报:
-                            <span>{{ parseFloat(item.reportTime).toFixed(1) }}h</span>
-                        </span>
-                    </div>
-                    <div v-if="user.timeType.enableNewWeeklyfill == 1 && item.summary != null" style="margin-left:20px;"
-                        v-html="'<b>' + item.summaryTitle + '</b><br>' + item.summary.replace(/\r\n/g, '<br>')">
+                            <div v-if="user.timeType.enableNewWeeklyfill == 1 && item.summary != null" style="margin-left:20px;"
+                                v-html="'<b>' + item.summaryTitle + '</b><br>' + item.summary.replace(/\r\n/g, '<br>')">
 
-                    </div>
-                    <div v-for="(item1, index1) in item.data" class="one_report_data" :key="index1">
-                        <div class="project_title" style="font-weight:bold;">项目:{{ item1.project }} <span
-                                :style="'color:' + statusColor[item1.state]">[
-                                <span v-if="item1.state == 0">
-                                    <span v-if="item1.isDeptAudit == 0">
-                                        <span v-if="item1.projectAuditState == 0">
-                                            待项目审核人<span v-if="item1.projectAuditorName != null">(
-                                                <span v-if="user.userNameNeedTranslate == '1'"><ww-open-data type='userName'
-                                                        :openid='item1.projectAuditorName'></ww-open-data></span>
-                                                <span v-else>{{ item1.projectAuditorName }}</span>
-                                                )</span>审核
+                            </div>
+                            <div v-for="(item1, index1) in item.data" class="one_report_data" :key="index1">
+                                <div class="project_title" style="font-weight:bold;">项目:{{ item1.project }} <span
+                                        :style="'color:' + statusColor[item1.state]">[
+                                        <span v-if="item1.state == 0">
+                                            <span v-if="item1.isDeptAudit == 0">
+                                                <span v-if="item1.projectAuditState == 0">
+                                                    待项目审核人<span v-if="item1.projectAuditorName != null">(
+                                                        <span v-if="user.userNameNeedTranslate == '1'"><ww-open-data type='userName'
+                                                                :openid='item1.projectAuditorName'></ww-open-data></span>
+                                                        <span v-else>{{ item1.projectAuditorName }}</span>
+                                                        )</span>审核
+                                                </span>
+                                                <span style="color:#32CD32;" v-else-if="item1.projectAuditState == 1">
+                                                    项目审核人<span v-if="item1.projectAuditorName != null">(
+                                                        <span v-if="user.userNameNeedTranslate == '1'"><ww-open-data type='userName'
+                                                                :openid='item1.projectAuditorName'></ww-open-data></span>
+                                                        <span v-else>{{ item1.projectAuditorName }}</span>
+                                                        )</span>审核通过
+                                                </span>
+                                            </span>
+                                            <span v-else-if="item1.isDeptAudit == 1">
+                                                待
+                                                <span v-if="user.userNameNeedTranslate == '1'"><ww-open-data type='departmentName'
+                                                        :openid='item1.auditDeptName'></ww-open-data></span>
+                                                <span v-else>{{ item1.auditDeptName }}</span>
+                                                审核
+                                            </span>
                                         </span>
-                                        <span style="color:#32CD32;" v-else-if="item1.projectAuditState == 1">
-                                            项目审核人<span v-if="item1.projectAuditorName != null">(
-                                                <span v-if="user.userNameNeedTranslate == '1'"><ww-open-data type='userName'
-                                                        :openid='item1.projectAuditorName'></ww-open-data></span>
-                                                <span v-else>{{ item1.projectAuditorName }}</span>
-                                                )</span>审核通过
+                                        <span v-else>
+                                            {{ statusTxt[item1.state] }}
                                         </span>
-                                    </span>
-                                    <span v-else-if="item1.isDeptAudit == 1">
-                                        待
-                                        <span v-if="user.userNameNeedTranslate == '1'"><ww-open-data type='departmentName'
-                                                :openid='item1.auditDeptName'></ww-open-data></span>
-                                        <span v-else>{{ item1.auditDeptName }}</span>
-                                        审核
-                                    </span>
-                                </span>
-                                <span v-else>
-                                    {{ statusTxt[item1.state] }}
-                                </span>
-                                <!-- {{statusTxt[item1.state]}} -->
+                                        <!-- {{statusTxt[item1.state]}} -->
 
-                                ] </span></div>
-                        <div style="color:red;" v-if="item1.state == 2 && item1.rejectReason != null">原因:{{
-                            item1.rejectReason }}
-                        </div>
-                        <div class="project_title" v-if="item1.subProjectName != null && user.companyId != yuzhongCompId">
-                            子项目:{{ item1.subProjectName }}</div>
-                        <div class="project_title" v-if="user.companyId == yuzhongCompId">
-                            角色:{{ item1.extraField1 ? roleList.find(r => r.value == item1.extraField1).label : '' }}</div>
-                        <div class="project_title" v-if="user.company.packageProject == 1 && item1.groupName != null">
-                            任务分组:{{ item1.groupName }}</div>
-                        <div class="project_title" v-if="user.companyId == yuzhongCompId">
-                            工作职责:{{ item1.extraField2 ? item1.extraField2Name : '' }}</div>
-                        <div class="project_title" v-if="user.companyId == yuzhongCompId">
-                            工作内容:{{ item1.extraField3 ? item1.extraField3Name : '' }}</div>
-                        <div class="project_title" v-if="user.company.packageProject == 1 && item1.stage != '-'">
-                            投入阶段:{{ item1.stage }}</div>
-                        <!--自定义维度 -->
-                        <div class="project_title" v-if="user.timeType.customDegreeActive == 1">
-                            {{ user.timeType.customDegreeName }}:{{ item1.degreeName }}</div>
-                        <div class="project_title" v-if="user.timeType.customDataActive == 1">
-                            {{ user.timeType.customDataName }}:{{ item1.customData }}</div>
-                        <div class="project_title" v-if="user.timeType.customTextActive == 1">
-                            {{ user.timeType.customTextName }}:{{ item1.customText }}</div>
-                        <div class="project_title" v-if="user.company.packageEngineering == 1">
-                            专业进度:
-                            <span style="margin-right:10px;" v-for="progressItem in item1.professionProgress"
-                                :key="progressItem.id">{{ progressItem.professionName }}({{ progressItem.progress }}%)
-                            </span>
-                        </div>
+                                        ] </span></div>
+                                <div style="color:red;" v-if="item1.state == 2 && item1.rejectReason != null">原因:{{
+                                    item1.rejectReason }}
+                                </div>
+                                <div class="project_title" v-if="item1.subProjectName != null && user.companyId != yuzhongCompId">
+                                    子项目:{{ item1.subProjectName }}</div>
+                                <div class="project_title" v-if="user.companyId == yuzhongCompId">
+                                    角色:{{ item1.extraField1 ? roleList.find(r => r.value == item1.extraField1).label : '' }}</div>
+                                <div class="project_title" v-if="user.company.packageProject == 1 && item1.groupName != null">
+                                    任务分组:{{ item1.groupName }}</div>
+                                <div class="project_title" v-if="user.companyId == yuzhongCompId">
+                                    工作职责:{{ item1.extraField2 ? item1.extraField2Name : '' }}</div>
+                                <div class="project_title" v-if="user.companyId == yuzhongCompId">
+                                    工作内容:{{ item1.extraField3 ? item1.extraField3Name : '' }}</div>
+                                <div class="project_title" v-if="user.company.packageProject == 1 && item1.stage != '-'">
+                                    投入阶段:{{ item1.stage }}</div>
+                                <!--自定义维度 -->
+                                <div class="project_title" v-if="user.timeType.customDegreeActive == 1">
+                                    {{ user.timeType.customDegreeName }}:{{ item1.degreeName }}</div>
+                                <div class="project_title" v-if="user.timeType.customDataActive == 1">
+                                    {{ user.timeType.customDataName }}:{{ item1.customData }}</div>
+                                <div class="project_title" v-if="user.timeType.customTextActive == 1">
+                                    {{ user.timeType.customTextName }}:{{ item1.customText }}</div>
+                                <div class="project_title" v-if="user.company.packageEngineering == 1">
+                                    专业进度:
+                                    <span style="margin-right:10px;" v-for="progressItem in item1.professionProgress"
+                                        :key="progressItem.id">{{ progressItem.professionName }}({{ progressItem.progress }}%)
+                                    </span>
+                                </div>
 
-                        <div class="project_title" v-if="item1.taskId">任务:{{ item1.taskName }}</div>
-                        <!--根据类型选择使用的模板 -->
-                        <div v-if="item1.multiWorktime == 0">
-                            <div class="project_time">时长:
-                                <span v-if="item1.reportTimeType == 0" style="margin-right:10px;">{{
-                                    fullDayTxt[item1.timeType] }}</span>
-                                <span v-if="item1.reportTimeType == 2" style="margin-right:10px;">{{ item1.startTime + '-' +
-                                    item1.endTime }}</span>{{ item1.time.toFixed(1) }}h
-                                <div class="button" v-if="item1.isOvertime == 1">加班<span v-if="item1.overtimeHours">{{
-                                    item1.overtimeHours.toFixed(1) }}h</span></div>
-                            </div>
-                            <div class="project_content">事项:<span v-html="item1.content"></span></div>
+                                <div class="project_title" v-if="item1.taskId">任务:{{ item1.taskName }}</div>
+                                <!--根据类型选择使用的模板 -->
+                                <div v-if="item1.multiWorktime == 0">
+                                    <div class="project_time">时长:
+                                        <span v-if="item1.reportTimeType == 0" style="margin-right:10px;">{{
+                                            fullDayTxt[item1.timeType] }}</span>
+                                        <span v-if="item1.reportTimeType == 2" style="margin-right:10px;">{{ item1.startTime + '-' +
+                                            item1.endTime }}</span>{{ item1.time.toFixed(1) }}h
+                                        <div class="button" v-if="item1.isOvertime == 1">加班<span v-if="item1.overtimeHours">{{
+                                            item1.overtimeHours.toFixed(1) }}h</span></div>
+                                    </div>
+                                    <div class="project_content">事项:<span v-html="item1.content"></span></div>
 
-                        </div>
-                        <div v-if="item1.multiWorktime == 1">
-                            <div>项目时长:<span style="margin-right:10px;">{{ item1.time.toFixed(1) }}h</span>
-                                <div class="button" v-if="item1.isOvertime == 1">加班<span v-if="item1.overtimeHours">{{
-                                    item1.overtimeHours.toFixed(1) }}h</span></div>
-                            </div>
-                            <div style="position:relative;border:#ccc 0.5px solid;padding:3px;margin:5px 0px;"
-                                v-for="(timeItem, index) in item1.worktimeList" :key="index">
-                                <div class="project_time">时长:
-                                    <!-- <span v-if="timeItem.reportTimeType == 0" style="margin-right:10px;">{{fullDayTxt[item1.timeType]}}</span> -->
-                                    <span style="margin-right:10px;">{{ timeItem.startTime + '-' + timeItem.endTime
-                                    }}</span>{{ timeItem.time.toFixed(1) }}h
                                 </div>
-                                <div class="project_content">事项:<span v-html="timeItem.content"></span></div>
+                                <div v-if="item1.multiWorktime == 1">
+                                    <div>项目时长:<span style="margin-right:10px;">{{ item1.time.toFixed(1) }}h</span>
+                                        <div class="button" v-if="item1.isOvertime == 1">加班<span v-if="item1.overtimeHours">{{
+                                            item1.overtimeHours.toFixed(1) }}h</span></div>
+                                    </div>
+                                    <div style="position:relative;border:#ccc 0.5px solid;padding:3px;margin:5px 0px;"
+                                        v-for="(timeItem, index) in item1.worktimeList" :key="index">
+                                        <div class="project_time">时长:
+                                            <!-- <span v-if="timeItem.reportTimeType == 0" style="margin-right:10px;">{{fullDayTxt[item1.timeType]}}</span> -->
+                                            <span style="margin-right:10px;">{{ timeItem.startTime + '-' + timeItem.endTime
+                                            }}</span>{{ timeItem.time.toFixed(1) }}h
+                                        </div>
+                                        <div class="project_content">事项:<span v-html="timeItem.content"></span></div>
+                                    </div>
+                                </div>
+                                <div style="padding:5px;text-align:center;" v-if="item1.pics != null && item1.pics.length > 0">
+                                    <span v-for="(p, index) in item1.pics" :key="p" style="margin-right:10px;">
+                                        <img :src="p" style="width:80px; height:80px;" @click="showLargeImg(item1.pics, index)" />
+                                    </span>
+                                </div>
+                                <van-divider />
                             </div>
-                        </div>
-                        <div style="padding:5px;text-align:center;" v-if="item1.pics != null && item1.pics.length > 0">
-                            <span v-for="(p, index) in item1.pics" :key="p" style="margin-right:10px;">
-                                <img :src="p" style="width:80px; height:80px;" @click="showLargeImg(item1.pics, index)" />
-                            </span>
-                        </div>
-                        <van-divider />
-                    </div>
-                    <van-popup v-model="imgShow" position="bottom" closeable>
-                        <van-swipe class="my-swipe" indicator-color="white">
-                            <van-swipe-item v-for="(picItem, index) in tmpPics" :key="index">
-                                <img :src="picItem" style="width:100%;" />
-                            </van-swipe-item>
-                        </van-swipe>
-                    </van-popup>
-
-                    <!-- 编辑 -->
-                    <div slot="footer" class="foot">
-                        <van-button size="small" type="primary" @click="editor(item)"
-                            v-if="item.id == user.id && (item.state == 2 || item.state == 3)">编辑日报</van-button>
-                    </div>
-                </van-panel>
-            </van-skeleton>
+                            <van-popup v-model="imgShow" position="bottom" closeable>
+                                <van-swipe class="my-swipe" indicator-color="white">
+                                    <van-swipe-item v-for="(picItem, index) in tmpPics" :key="index">
+                                        <img :src="picItem" style="width:100%;" />
+                                    </van-swipe-item>
+                                </van-swipe>
+                            </van-popup>
+
+                            <!-- 编辑 -->
+                            <div slot="footer" class="foot">
+                                <van-button size="small" type="primary" @click="editor(item)"
+                                    v-if="item.id == user.id && (item.state == 2 || item.state == 3)">编辑日报</van-button>
+                            </div>
+                        </van-panel>
+                    </van-skeleton>
+                </van-list>
+            </van-pull-refresh>
+
+            
             <van-empty v-if="report.length == 0" description="暂无日报">
                 <van-button round type="primary" class="bottom-button" @click="toWriteReport()">去填写</van-button>
             </van-empty>
@@ -262,6 +269,11 @@ export default {
     components: {},
     data() {
         return {
+            isDownloading: false,
+            isUpLoading: false, // 上拉加载
+            upFinished: false, // 上拉加载完毕
+            pageIndex: 0,
+            hasMore: true,
             yuzhongCompId: 3385,
             roleList: [{ value: 1, label: 'CRC&LM' }, { value: 2, label: 'PM' }],
             tmpPics: [],
@@ -302,6 +314,52 @@ export default {
     created() {
     },
     methods: {
+        onDownRefresh() {
+            this.pageIndex = 1
+            this.upFinished = false // 不写这句会导致你上拉到底过后在下拉刷新将不能触发下拉加载事件
+            this.getReport();
+        },
+        onLoadList() {
+            if(!this.hasMore) {
+                this.upFinished = true
+                this.isUpLoading = false
+                return
+            }
+            this.pageIndex++;
+            this.requestHttpReports();
+        },
+        requestHttpReports() {
+            this.hasWaiting = false;
+            let pames = {
+                date: this.nowTime,
+            }
+            if (this.selectPeopleVal.id) {
+                pames.userId = this.selectPeopleVal.id
+            }
+            if (this.departmentText && this.selectDepartmentText.length > 0) {
+                pames.deptId = this.selectDepartmentText[0].id
+            }
+            pames.pageIndex = this.pageIndex;
+            this.$axios.post("/report/getReportList", pames)
+                .then(res => {
+                    if (res.code == "ok") {
+                        this.report = this.report.concat(res.data.data);
+                        this.hasMore = res.data.hasMore;
+                        this.isUpLoading = false;
+                        this.isDownloading = false;
+                        //计算状态
+                        for (var i = 0; i < this.report.length; i++) {
+                            var item = this.report[i];
+                            if (item.state == 0) {
+                                this.hasWaiting = true;
+                            }
+                        }
+                    } else {
+                        this.$toast.clear();
+                        this.$toast.fail('获取失败:' + res.msg);
+                    }
+                }).catch(err => { this.$toast.clear(); });
+        },
         showLargeImg(item, index) {
             this.imgShow = true;
             this.tmpPics = item;
@@ -446,38 +504,10 @@ export default {
 
         // 获取日报
         getReport() {
-            this.hasWaiting = false;
-            const toast = this.$toast.loading({
-                forbidClick: true,
-                duration: 0
-            });
-            // this.nowTime = '2023-04-13'
-            let pames = {
-                date: this.nowTime,
-            }
-            if (this.selectPeopleVal.id) {
-                pames.userId = this.selectPeopleVal.id
-            }
-            if (this.departmentText && this.selectDepartmentText.length > 0) {
-                pames.deptId = this.selectDepartmentText[0].id
-            }
-            this.$axios.post("/report/getReportList", pames)
-                .then(res => {
-                    if (res.code == "ok") {
-                        this.$toast.clear();
-                        this.report = res.data;
-                        //计算状态
-                        for (var i = 0; i < this.report.length; i++) {
-                            var item = this.report[i];
-                            if (item.state == 0) {
-                                this.hasWaiting = true;
-                            }
-                        }
-                    } else {
-                        this.$toast.clear();
-                        this.$toast.fail('获取失败:' + res.msg);
-                    }
-                }).catch(err => { this.$toast.clear(); });
+            this.pageIndex = 0;
+            this.isUpLoading = false;
+            this.report = [];
+            this.requestHttpReports();
         },
         // 点击编辑
         editor(item) {