Prechádzať zdrojové kódy

'解决系统样式问题,工时报告日期位置'

Lljy-ai 4 rokov pred
rodič
commit
3ec0b0b6db
83 zmenil súbory, kde vykonal 2159 pridanie a 336 odobranie
  1. 7 0
      fhKeeper/formulahousekeeper/management-platform/pom.xml
  2. 2 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/aop/SensitiveWordConfig.java
  3. 14 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/config/Config.java
  4. 22 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/config/SchedulerConfig.java
  5. 21 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/AlertTimeController.java
  6. 5 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java
  7. 21 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/SysFunctionController.java
  8. 21 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/SysModuleController.java
  9. 50 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/SysRoleController.java
  10. 21 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/SysRoleFunctionController.java
  11. 21 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/SysRoleModuleController.java
  12. 4 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/TaskController.java
  13. 73 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/WXController.java
  14. 41 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/AlertTime.java
  15. 72 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/SysFunction.java
  16. 86 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/SysModule.java
  17. 57 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/SysRole.java
  18. 44 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/SysRoleFunction.java
  19. 44 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/SysRoleModule.java
  20. 7 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/TimeType.java
  21. 21 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/User.java
  22. 10 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/UserVO.java
  23. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/AlertTimeMapper.java
  24. 6 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ReportMapper.java
  25. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/SysFunctionMapper.java
  26. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/SysModuleMapper.java
  27. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/SysRoleFunctionMapper.java
  28. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/SysRoleMapper.java
  29. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/SysRoleModuleMapper.java
  30. 3 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/UserMapper.java
  31. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/AlertTimeService.java
  32. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ReportService.java
  33. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/SysFunctionService.java
  34. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/SysModuleService.java
  35. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/SysRoleFunctionService.java
  36. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/SysRoleModuleService.java
  37. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/SysRoleService.java
  38. 2 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/UserService.java
  39. 20 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/AlertTimeServiceImpl.java
  40. 4 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java
  41. 34 17
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  42. 20 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/SysFunctionServiceImpl.java
  43. 20 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/SysModuleServiceImpl.java
  44. 20 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/SysRoleFunctionServiceImpl.java
  45. 20 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/SysRoleModuleServiceImpl.java
  46. 20 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/SysRoleServiceImpl.java
  47. 159 7
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/UserServiceImpl.java
  48. 78 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/TimingTask.java
  49. 5 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/application.yml
  50. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/AlertTimeMapper.xml
  51. 7 4
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportMapper.xml
  52. 21 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/SysFunctionMapper.xml
  53. 23 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/SysModuleMapper.xml
  54. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/SysRoleFunctionMapper.xml
  55. 18 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/SysRoleMapper.xml
  56. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/SysRoleModuleMapper.xml
  57. 2 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/TimeTypeMapper.xml
  58. 14 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/UserMapper.xml
  59. 1 1
      fhKeeper/formulahousekeeper/timesheet/build/webpack.base.conf.js
  60. 26 3
      fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/demo_index.html
  61. 7 3
      fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.css
  62. 1 1
      fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.js
  63. 7 0
      fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.json
  64. BIN
      fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.ttf
  65. BIN
      fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.woff
  66. BIN
      fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.woff2
  67. 51 29
      fhKeeper/formulahousekeeper/timesheet/src/main.js
  68. 28 145
      fhKeeper/formulahousekeeper/timesheet/src/routes.js
  69. 11 1
      fhKeeper/formulahousekeeper/timesheet/src/views/Login.vue
  70. 1 5
      fhKeeper/formulahousekeeper/timesheet/src/views/expense/expense.vue
  71. 7 7
      fhKeeper/formulahousekeeper/timesheet/src/views/project/list.vue
  72. 7 4
      fhKeeper/formulahousekeeper/timesheet/src/views/project/projectInside.vue
  73. 184 0
      fhKeeper/formulahousekeeper/timesheet/src/views/role/role.vue
  74. 24 1
      fhKeeper/formulahousekeeper/timesheet/src/views/settings/timetype.vue
  75. 28 5
      fhKeeper/formulahousekeeper/timesheet/src/views/team/index.vue
  76. 159 54
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue
  77. 2 2
      fhKeeper/formulahousekeeper/timesheet_h5/src/main.js
  78. 130 27
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/index.vue
  79. 51 0
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/index/index.vue
  80. 24 1
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/my/children/center.vue
  81. 4 1
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/project/index.vue
  82. 4 2
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/review/index.vue
  83. 1 0
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/view/index.vue

+ 7 - 0
fhKeeper/formulahousekeeper/management-platform/pom.xml

@@ -130,6 +130,13 @@
             <scope>system</scope>
             <systemPath>${basedir}/opencv/opencv-420.jar</systemPath>
         </dependency>
+
+        <!--微信模版消息推送三方sdk-->
+        <dependency>
+            <groupId>com.github.binarywang</groupId>
+            <artifactId>weixin-java-mp</artifactId>
+            <version>3.3.0</version>
+        </dependency>
     </dependencies>
 
     <build>

+ 2 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/aop/SensitiveWordConfig.java

@@ -20,8 +20,8 @@ import java.time.LocalDate;
 /**
  * 敏感词过滤
  */
-@Aspect
-@Component
+//@Aspect
+//@Component
 public class SensitiveWordConfig {
     @Autowired
     RedisUtil redisUtils;

+ 14 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/config/Config.java

@@ -0,0 +1,14 @@
+package com.management.platform.config;
+
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.client.RestTemplate;
+
+@Configuration
+public class Config {
+  @Bean
+  public RestTemplate restTemplate(RestTemplateBuilder builder){
+    return builder.build();
+  }
+}

+ 22 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/config/SchedulerConfig.java

@@ -0,0 +1,22 @@
+package com.management.platform.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.TaskScheduler;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
+
+@Configuration
+@EnableScheduling
+public class SchedulerConfig {
+    @Bean
+    public TaskScheduler taskScheduler() {
+        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
+        //线程池大小
+        scheduler.setPoolSize(10);
+        //线程名字前缀
+        scheduler.setThreadNamePrefix("spring-task-thread");
+        return scheduler;
+    }
+}
+

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/AlertTimeController.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 2021-05-31
+ */
+@RestController
+@RequestMapping("/alert-time")
+public class AlertTimeController {
+
+}
+

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

@@ -53,8 +53,8 @@ public class ReportController {
      * date 日期 格式yyyy-mm-dd
      */
     @RequestMapping("/exportReport")
-    public HttpRespMsg exportReport(@RequestParam String date) {
-        return reportService.exportReport(date, request);
+    public HttpRespMsg exportReport(String startDate, String endDate, Integer projectId) {
+        return reportService.exportReport(startDate, endDate, projectId, request);
     }
 
 
@@ -91,6 +91,9 @@ public class ReportController {
         List<Report> reportList = new ArrayList<>();
         String token = request.getHeader("Token");
         BigDecimal hourCost = userService.getById(token).getCost();
+        if (hourCost == null) {
+            hourCost = new BigDecimal(0);
+        }
         SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
 
 

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/SysFunctionController.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 2021-06-03
+ */
+@RestController
+@RequestMapping("/sys-function")
+public class SysFunctionController {
+
+}
+

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/SysModuleController.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 2021-06-03
+ */
+@RestController
+@RequestMapping("/sys-module")
+public class SysModuleController {
+
+}
+

+ 50 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/SysRoleController.java

@@ -0,0 +1,50 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.SysRole;
+import com.management.platform.service.SysRoleService;
+import com.management.platform.service.UserService;
+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 javax.servlet.http.HttpServletRequest;
+
+/**
+ * <p>
+ * 角色表(职务) 前端控制器
+ * </p>
+ *
+ * @author Reiskuchen
+ * @since 2019-11-06
+ */
+@RestController
+@RequestMapping("/permission")
+public class SysRoleController {
+    @Resource
+    private HttpServletRequest request;
+    @Resource
+    private SysRoleService sysRoleService;
+    @Resource
+    private UserService userService;
+
+    @RequestMapping("/getFrontRoleList")
+    public HttpRespMsg getFrontRoleList() {
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.data = sysRoleService.list(new QueryWrapper<SysRole>());
+        return msg;
+    }
+
+    @RequestMapping("/getRoleList")
+    public HttpRespMsg getRoleList() {
+        HttpRespMsg msg = new HttpRespMsg();
+        String userId = request.getHeader("TOKEN");
+        Integer companyId = userService.getById(userId).getCompanyId();
+        msg.data = sysRoleService.list(new QueryWrapper<SysRole>().eq("company_id", companyId));
+        return msg;
+    }
+
+}
+

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/SysRoleFunctionController.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 2021-06-03
+ */
+@RestController
+@RequestMapping("/sys-role-function")
+public class SysRoleFunctionController {
+
+}
+

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/SysRoleModuleController.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 2021-06-03
+ */
+@RestController
+@RequestMapping("/sys-role-module")
+public class SysRoleModuleController {
+
+}
+

+ 4 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/TaskController.java

@@ -480,6 +480,8 @@ public class TaskController {
         taskLogService.remove(new QueryWrapper<TaskLog>().eq("task_id",  id));
         //删除留言
         taskCommentService.remove(new QueryWrapper<TaskComment>().eq("task_id", id));
+        //删除近期任务
+        userRecentTaskService.remove(new QueryWrapper<UserRecentTask>().eq("task_id", id));
         deleteSubTask(task);
 
         //删除根任务,需要重新计算项目进度
@@ -498,6 +500,8 @@ public class TaskController {
             taskLogService.remove(new QueryWrapper<TaskLog>().in("task_id",  collect));
             //删除留言
             taskCommentService.remove(new QueryWrapper<TaskComment>().in("task_id", collect));
+            //删除近期任务
+            userRecentTaskService.remove(new QueryWrapper<UserRecentTask>().in("task_id", collect));
             subTasks.forEach(s->{
                 deleteSubTask(s);
             });

+ 73 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/WXController.java

@@ -0,0 +1,73 @@
+package com.management.platform.controller;
+
+import com.management.platform.service.UserService;
+import com.management.platform.util.HttpRespMsg;
+import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
+import me.chanjar.weixin.mp.api.WxMpService;
+import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
+import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
+import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+@RestController
+@RequestMapping("/wechat")
+public class WXController {
+
+    @Value("${wx.template_report_fill}")
+    public String TEMPLATE_REPORT_FILL;
+    @Value("${wx.app_id}")
+    public String appId;
+    @Value("${wx.app_secret}")
+    public String appSecret;
+
+    @Resource
+    public UserService userService;
+
+
+    @GetMapping("/bindWeiXin")
+    public HttpRespMsg bindWeiXin(String code, String userId) {
+        return userService.bindWeiXin(code, userId);
+    }
+    /*
+     * 微信测试账号推送
+     * */
+    @GetMapping("/push")
+    public void push(String toOpenId) {
+        if (toOpenId == null) {
+            toOpenId = "o1L3L5lOrOl3_UEJjONaoT2Rne1I";
+        }
+        //1,配置
+        WxMpInMemoryConfigStorage wxStorage = new WxMpInMemoryConfigStorage();
+        wxStorage.setAppId(appId);
+        wxStorage.setSecret(appSecret);
+        WxMpService wxMpService = new WxMpServiceImpl();
+        wxMpService.setWxMpConfigStorage(wxStorage);
+
+        //2,推送消息
+        WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
+                .toUser(toOpenId)//要推送的用户openid
+                .templateId(TEMPLATE_REPORT_FILL)//模版id
+                .url("http://mob.ttkuaiban.com/")//点击模版消息要访问的网址
+                .build();
+        //3,如果是正式版发送模版消息,这里需要配置你的信息
+                templateMessage.addData(new WxMpTemplateData("first", "您今天的工时填报还未完成", "#FF00FF"));
+                templateMessage.addData(new WxMpTemplateData("keyword1", "屈跃庭", "#000000"));
+                templateMessage.addData(new WxMpTemplateData("keyword2", "市场部", "#000000"));
+                templateMessage.addData(new WxMpTemplateData("remark", "请尽快填报", "#000000"));
+        //                templateMessage.addData(new WxMpTemplateData(name2, value2, color2));
+        try {
+            wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
+        } catch (Exception e) {
+            System.out.println("推送失败:" + e.getMessage());
+            e.printStackTrace();
+        }
+
+    }
+
+
+}

+ 41 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/AlertTime.java

@@ -0,0 +1,41 @@
+package com.management.platform.entity;
+
+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 2021-05-31
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class AlertTime extends Model<AlertTime> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableId("company_id")
+    private Integer companyId;
+
+    /**
+     * 提醒时间; 例如18:00
+     */
+    @TableField("alert_time")
+    private String alertTime;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.companyId;
+    }
+
+}

+ 72 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/SysFunction.java

@@ -0,0 +1,72 @@
+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 2021-06-03
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class SysFunction extends Model<SysFunction> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 功能名称
+     */
+    @TableField("name")
+    private String name;
+
+    /**
+     * 图标
+     */
+    @TableField("icon")
+    private String icon;
+
+    /**
+     * 功能字符KEY
+     */
+    @TableField("code")
+    private String code;
+
+    /**
+     * 对应模块ID
+     */
+    @TableField("module_id")
+    private Integer moduleId;
+
+    /**
+     * 功能排序
+     */
+    @TableField("seq")
+    private Integer seq;
+
+    /**
+     * 0:启用,1.未启用
+     */
+    @TableField("use_state")
+    private Boolean useState;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 86 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/SysModule.java

@@ -0,0 +1,86 @@
+package com.management.platform.entity;
+
+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 2021-06-03
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class SysModule extends Model<SysModule> {
+
+    private static final long serialVersionUID=1L;
+
+    /**
+     * 主键CODE
+     */
+    @TableId("id")
+    private Integer id;
+
+    /**
+     * 模块名称
+     */
+    @TableField("name")
+    private String name;
+
+    /**
+     * 模块路径
+     */
+    @TableField("path")
+    private String path;
+
+    /**
+     * 模块父级ID
+     */
+    @TableField("parent_id")
+    private Integer parentId;
+
+    /**
+     * 模块图标
+     */
+    @TableField("icon")
+    private String icon;
+
+    /**
+     * 排序
+     */
+    @TableField("orderitem")
+    private Integer orderitem;
+
+    /**
+     * 是否菜单
+     */
+    @TableField("is_menu")
+    private Boolean isMenu;
+
+    /**
+     * 0:启用,1.未启用
+     */
+    @TableField("use_state")
+    private Boolean useState;
+
+    /**
+     * 账套级别的系统配置-Lei
+     */
+    @TableField("config")
+    private String config;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 57 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/SysRole.java

@@ -0,0 +1,57 @@
+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 2021-06-03
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class SysRole extends Model<SysRole> {
+
+    private static final long serialVersionUID=1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 公司id
+     */
+    @TableField("company_id")
+    private Integer companyId;
+
+    /**
+     * 角色名称
+     */
+    @TableField("rolename")
+    private String rolename;
+
+    /**
+     * 角色描述
+     */
+    @TableField("role_describe")
+    private String roleDescribe;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 44 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/SysRoleFunction.java

@@ -0,0 +1,44 @@
+package com.management.platform.entity;
+
+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 2021-06-03
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class SysRoleFunction extends Model<SysRoleFunction> {
+
+    private static final long serialVersionUID=1L;
+
+    /**
+     * 角色编号
+     */
+    @TableId("role_id")
+    private Integer roleId;
+
+    /**
+     * 模块对应操作ID
+     */
+    @TableField("function_id")
+    private Integer functionId;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.roleId;
+    }
+
+}

+ 44 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/SysRoleModule.java

@@ -0,0 +1,44 @@
+package com.management.platform.entity;
+
+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 2021-06-03
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class SysRoleModule extends Model<SysRoleModule> {
+
+    private static final long serialVersionUID=1L;
+
+    /**
+     * 角色编号
+     */
+    @TableId("role_id")
+    private Integer roleId;
+
+    /**
+     * 模块ID
+     */
+    @TableField("module_id")
+    private Integer moduleId;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.roleId;
+    }
+
+}

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

@@ -15,7 +15,7 @@ import lombok.experimental.Accessors;
  * </p>
  *
  * @author Seyason
- * @since 2021-03-29
+ * @since 2021-05-31
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -72,6 +72,12 @@ public class TimeType extends Model<TimeType> {
     @TableField("pay_overtime")
     private Boolean payOvertime;
 
+    /**
+     * 提醒时间
+     */
+    @TableField("alert_time")
+    private String alertTime;
+
 
     @Override
     protected Serializable pkVal() {

+ 21 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/User.java

@@ -16,7 +16,7 @@ import lombok.experimental.Accessors;
  * </p>
  *
  * @author Seyason
- * @since 2021-05-19
+ * @since 2021-06-04
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -121,9 +121,28 @@ public class User extends Model<User> {
     @TableField("is_active")
     private Integer isActive;
 
+    /**
+     * 微信openid
+     */
+    @TableField("wx_openid")
+    private String wxOpenid;
+
+    /**
+     * 新版权限角色的id
+     */
+    @TableField("role_id")
+    private Integer roleId;
+
+    /**
+     * 新版权限角色的名称
+     */
+    @TableField("role_name")
+    private String roleName;
+
+
+
     @TableField(exist = false)
     private String departmentName;
-
     @Override
     protected Serializable pkVal() {
         return this.id;

+ 10 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/UserVO.java

@@ -1,11 +1,15 @@
 package com.management.platform.entity.vo;
 
 import com.management.platform.entity.Company;
+import com.management.platform.entity.SysFunction;
+import com.management.platform.entity.SysModule;
 import com.management.platform.entity.User;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
 
+import java.util.List;
+
 @Data
 @EqualsAndHashCode(callSuper = false)
 @Accessors(chain = true)
@@ -15,4 +19,10 @@ public class UserVO extends User {
     //是否是项目经理
     private boolean isLeader;
     private Company company;
+
+    //模块菜单的访问权限
+    private List<SysModule> moduleList;
+    //功能按钮的访问权限
+    private List<SysFunction> functionList;
+
 }

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

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

+ 6 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ReportMapper.java

@@ -18,7 +18,12 @@ import java.util.Map;
  * @since 2019-12-31
  */
 public interface ReportMapper extends BaseMapper<Report> {
-    List<Map<String, Object>> getAllReportByDate(@Param("date") String date, @Param("companyId") Integer companyId, @Param("userId") String userId);
+    List<Map<String, Object>> getAllReportByDate(@Param("startDate") String startDate,
+                                                 @Param("companyId") Integer companyId,
+                                                 @Param("userId") String userId,
+                                                 @Param("endDate") String endDate,
+                                                 @Param("projectId") Integer projectId
+                                                 );
 
     //按当前人员获取本人报告
     List<Map<String, Object>> getReportByDate(@Param("date") String date, @Param("id") String id);

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

@@ -0,0 +1,16 @@
+package com.management.platform.mapper;
+
+import com.management.platform.entity.SysFunction;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 菜单功能权限关联表 Mapper 接口
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-06-03
+ */
+public interface SysFunctionMapper extends BaseMapper<SysFunction> {
+
+}

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

@@ -0,0 +1,16 @@
+package com.management.platform.mapper;
+
+import com.management.platform.entity.SysModule;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 菜单表 Mapper 接口
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-06-03
+ */
+public interface SysModuleMapper extends BaseMapper<SysModule> {
+
+}

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

@@ -0,0 +1,16 @@
+package com.management.platform.mapper;
+
+import com.management.platform.entity.SysRoleFunction;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 角色菜单关联表 Mapper 接口
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-06-03
+ */
+public interface SysRoleFunctionMapper extends BaseMapper<SysRoleFunction> {
+
+}

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

@@ -0,0 +1,16 @@
+package com.management.platform.mapper;
+
+import com.management.platform.entity.SysRole;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 角色表(职务) Mapper 接口
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-06-03
+ */
+public interface SysRoleMapper extends BaseMapper<SysRole> {
+
+}

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

@@ -0,0 +1,16 @@
+package com.management.platform.mapper;
+
+import com.management.platform.entity.SysRoleModule;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 角色操作功能权限关联表 Mapper 接口
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-06-03
+ */
+public interface SysRoleModuleMapper extends BaseMapper<SysRoleModule> {
+
+}

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

@@ -30,4 +30,7 @@ public interface UserMapper extends BaseMapper<User> {
 
     Integer countUserByDepartmentList(@Param("companyId") Integer companyId,
                                       @Param("departmentIds") List departmentIds);
+
+    List<Map<String, Object>> getPushUserList(@Param("companyId") Integer companyId);
+
 }

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

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

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

@@ -19,7 +19,7 @@ import java.util.List;
 public interface ReportService extends IService<Report> {
     HttpRespMsg getReportList(String date, Integer deptId, String userId, HttpServletRequest request);
 
-    HttpRespMsg exportReport(String date, HttpServletRequest request);
+    HttpRespMsg exportReport(@RequestParam String startDate, @RequestParam String endDate, Integer projectId, HttpServletRequest request);
 
     HttpRespMsg getReport(String date, HttpServletRequest request);
 

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

@@ -0,0 +1,16 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.SysFunction;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 菜单功能权限关联表 服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-06-03
+ */
+public interface SysFunctionService extends IService<SysFunction> {
+
+}

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

@@ -0,0 +1,16 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.SysModule;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 菜单表 服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-06-03
+ */
+public interface SysModuleService extends IService<SysModule> {
+
+}

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

@@ -0,0 +1,16 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.SysRoleFunction;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 角色菜单关联表 服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-06-03
+ */
+public interface SysRoleFunctionService extends IService<SysRoleFunction> {
+
+}

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

@@ -0,0 +1,16 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.SysRoleModule;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 角色操作功能权限关联表 服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-06-03
+ */
+public interface SysRoleModuleService extends IService<SysRoleModule> {
+
+}

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

@@ -0,0 +1,16 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.SysRole;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 角色表(职务) 服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-06-03
+ */
+public interface SysRoleService extends IService<SysRole> {
+
+}

+ 2 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/UserService.java

@@ -43,4 +43,6 @@ public interface UserService extends IService<User> {
     HttpRespMsg getUserSalaryList(String id);
 
     HttpRespMsg setActive(String id, int isActive);
+
+    HttpRespMsg bindWeiXin(String code, String userId);
 }

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

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.AlertTime;
+import com.management.platform.mapper.AlertTimeMapper;
+import com.management.platform.service.AlertTimeService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-05-31
+ */
+@Service
+public class AlertTimeServiceImpl extends ServiceImpl<AlertTimeMapper, AlertTime> implements AlertTimeService {
+
+}

+ 4 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java

@@ -92,7 +92,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
             Integer companyId = user.getCompanyId();
             //判断用户的角色,如果是管理员和负责人,查看全部的。如果是普通员工,只能是看到参与的项目
             QueryWrapper<Project> queryWrapper = null;
-            if (user.getRole() == 0) {
+            if (user.getRole() == 0 || user.getRole() == 5) {
                 //普通员工
                 List<Participation> pList = participationMapper.selectList(new QueryWrapper<Participation>().eq("user_id", user.getId()));
                 List<Integer> projectIds = new ArrayList<>();
@@ -101,7 +101,9 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                 } else {
                     projectIds.add(-1);
                 }
-                queryWrapper = new QueryWrapper<Project>().in("id", projectIds);
+                final List<Integer> ids = projectIds;
+                queryWrapper = new QueryWrapper<Project>();
+                queryWrapper.and(wrapper->wrapper.in("id", ids).or().eq("creator_id", user.getId()));
             } else {
                 queryWrapper = new QueryWrapper<Project>().eq("company_id", companyId);
             }

+ 34 - 17
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -13,6 +13,7 @@ import org.apache.poi.hssf.usermodel.*;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestParam;
 
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
@@ -192,8 +193,6 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                         }
                     }
                 }
-
-
             } else {
                 Integer companyId = userMapper.selectById(request.getHeader("Token")).getCompanyId();
                 List<Integer> ids = null;
@@ -673,7 +672,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
 
     //导出报告
     @Override
-    public HttpRespMsg exportReport(String date, HttpServletRequest request) {
+    public HttpRespMsg exportReport(@RequestParam String startDate, @RequestParam String endDate, Integer projectId, HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         try {
             String userId = request.getHeader("Token");
@@ -681,16 +680,19 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
 
             //准备导出
             HSSFWorkbook workbook = new HSSFWorkbook();
-            HSSFSheet sheet = workbook.createSheet(date + "日报");
+            HSSFSheet sheet = workbook.createSheet("工作日报");
             //创建表头
             HSSFRow headRow = sheet.createRow(0);
             //设置列宽 setColumnWidth的第二个参数要乘以256 这个参数的单位是1/256个字符宽度
             sheet.setColumnWidth(0, 5 * 256);
             sheet.setColumnWidth(1, 10 * 256);
             sheet.setColumnWidth(2, 20 * 256);
-            sheet.setColumnWidth(3, 10 * 256);
-            sheet.setColumnWidth(4, 50 * 256);
-            sheet.setColumnWidth(5, 18 * 256);
+            sheet.setColumnWidth(3, 20 * 256);
+            sheet.setColumnWidth(4, 60 * 256);
+
+            sheet.setColumnWidth(5, 15 * 256);
+            sheet.setColumnWidth(6, 15 * 256);
+            sheet.setColumnWidth(7, 100 * 256);
             //设置为居中加粗
             HSSFCellStyle headStyle = workbook.createCellStyle();
             HSSFFont font = workbook.createFont();
@@ -708,13 +710,22 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             headCell.setCellValue("项目名称");
             headCell.setCellStyle(headStyle);
             headCell = headRow.createCell(3);
-            headCell.setCellValue("工作时间");
+            headCell.setCellValue("子项目名称");
             headCell.setCellStyle(headStyle);
             headCell = headRow.createCell(4);
-            headCell.setCellValue("工作内容");
+            headCell.setCellValue("关联任务");
             headCell.setCellStyle(headStyle);
             headCell = headRow.createCell(5);
-            headCell.setCellValue("提交时间");
+            headCell.setCellValue("工作日期");
+            headCell.setCellStyle(headStyle);
+            headCell = headRow.createCell(6);
+            headCell.setCellValue("工作时长(小时)");
+            headCell.setCellStyle(headStyle);
+            headCell = headRow.createCell(7);
+            headCell.setCellValue("工作内容");
+            headCell.setCellStyle(headStyle);
+            headCell = headRow.createCell(8);
+            headCell.setCellValue("加班");
             headCell.setCellStyle(headStyle);
             //设置日期格式
             HSSFCellStyle style = workbook.createCellStyle();
@@ -724,10 +735,10 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             List<Map<String, Object>> allReportByDate = null;
             if (user.getRole() == 0) {
                 //普通员工只能看自己的
-                allReportByDate = reportMapper.getAllReportByDate(date, null, user.getId());
+                allReportByDate = reportMapper.getAllReportByDate(startDate, null, user.getId(), endDate, projectId);
             } else {
                 //管理员看公司所有人的
-                allReportByDate = reportMapper.getAllReportByDate(date, user.getCompanyId(), null);
+                allReportByDate = reportMapper.getAllReportByDate(startDate, user.getCompanyId(), null, endDate, projectId);
             }
 
             for (Map<String, Object> map : allReportByDate) {
@@ -735,16 +746,22 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 row.createCell(0).setCellValue(rowNum);
                 row.createCell(1).setCellValue((String) map.get("name"));
                 row.createCell(2).setCellValue((String) map.get("project"));
-                row.createCell(3).setCellValue(map.get("duration").toString());
-                row.createCell(4).setCellValue((String) map.get("content"));
+                row.createCell(3).setCellValue((String) map.get("subProjectName"));
+                row.createCell(4).setCellValue((String) map.get("taskName"));
+
                 HSSFCell cell = row.createCell(5);
-                cell.setCellValue(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
-                        .format((Timestamp) map.get("time")));
+                cell.setCellValue(new SimpleDateFormat("yyyy-MM-dd")
+                        .format((java.sql.Date) map.get("createDate")));
                 cell.setCellStyle(style);
+                row.createCell(6).setCellValue(map.get("duration").toString());
+                row.createCell(7).setCellValue((String) map.get("content"));
+                int isOverTime = (Integer) map.get("isOvertime");
+                row.createCell(8).setCellValue(isOverTime==1?"加班":"-");
+
                 rowNum++;
             }
             //生成Excel文件
-            String fileUrlSuffix = date + "日报" + System.currentTimeMillis() + ".xls";
+            String fileUrlSuffix = (startDate==null?"":(startDate+"至"+endDate))+"工作日报" + System.currentTimeMillis() + ".xls";
             FileOutputStream fos = new FileOutputStream(path + fileUrlSuffix);
             workbook.write(fos);
             fos.flush();

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

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.SysFunction;
+import com.management.platform.mapper.SysFunctionMapper;
+import com.management.platform.service.SysFunctionService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 菜单功能权限关联表 服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-06-03
+ */
+@Service
+public class SysFunctionServiceImpl extends ServiceImpl<SysFunctionMapper, SysFunction> implements SysFunctionService {
+
+}

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

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.SysModule;
+import com.management.platform.mapper.SysModuleMapper;
+import com.management.platform.service.SysModuleService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 菜单表 服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-06-03
+ */
+@Service
+public class SysModuleServiceImpl extends ServiceImpl<SysModuleMapper, SysModule> implements SysModuleService {
+
+}

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

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.SysRoleFunction;
+import com.management.platform.mapper.SysRoleFunctionMapper;
+import com.management.platform.service.SysRoleFunctionService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 角色菜单关联表 服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-06-03
+ */
+@Service
+public class SysRoleFunctionServiceImpl extends ServiceImpl<SysRoleFunctionMapper, SysRoleFunction> implements SysRoleFunctionService {
+
+}

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

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.SysRoleModule;
+import com.management.platform.mapper.SysRoleModuleMapper;
+import com.management.platform.service.SysRoleModuleService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 角色操作功能权限关联表 服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-06-03
+ */
+@Service
+public class SysRoleModuleServiceImpl extends ServiceImpl<SysRoleModuleMapper, SysRoleModule> implements SysRoleModuleService {
+
+}

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

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.SysRole;
+import com.management.platform.mapper.SysRoleMapper;
+import com.management.platform.service.SysRoleService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 角色表(职务) 服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-06-03
+ */
+@Service
+public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {
+
+}

+ 159 - 7
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/UserServiceImpl.java

@@ -1,8 +1,10 @@
 package com.management.platform.service.impl;
 
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.management.platform.constant.Constant;
 import com.management.platform.entity.*;
 import com.management.platform.entity.vo.UserVO;
 import com.management.platform.mapper.*;
@@ -14,8 +16,14 @@ import org.apache.poi.xssf.usermodel.XSSFRow;
 import org.apache.poi.xssf.usermodel.XSSFSheet;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
 import org.springframework.util.NumberUtils;
+import org.springframework.web.client.RestTemplate;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
@@ -40,6 +48,21 @@ import java.util.Map;
  */
 @Service
 public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
+
+    @Value("${wx.template_report_fill}")
+    public String TEMPLATE_REPORT_FILL;
+    @Value("${wx.app_id}")
+    public String appId;
+    @Value("${wx.app_secret}")
+    public String appSecret;
+    public static final String GET_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
+    public static final String GET_USERINFO_URL = "https://api.weixin.qq.com/sns/userinfo?access_token=accessToken&openid=openId&lang=zh_CN";
+    @Resource
+    private RedisUtil redisUtil;
+
+    @Autowired
+    private RestTemplate restTemplate;
+
     @Resource
     private HttpServletRequest request;
     @Resource
@@ -421,6 +444,15 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
         //首先先搞到公司id
         Integer companyId = userMapper.selectById(request.getHeader("Token")).getCompanyId();
 
+        //检查人数是否已达上限
+        Company company = companyMapper.selectById(companyId);
+        int maxCnt = company.getStaffCountMax();
+        long cnt = userMapper.selectCount(new QueryWrapper<User>().eq("company_id", companyId).eq("is_active", 1));
+        if (cnt >= maxCnt) {
+            httpRespMsg.setError("人数已达上限,无法导入.请联系客服提高人数上限。");
+            return httpRespMsg;
+        }
+        int canImportNum = (int)(maxCnt - cnt);
         //查询工作时长设置
         TimeType time = timeTypeMapper.selectById(companyId);
         BigDecimal monthHours = time.getMonthDays().multiply(new BigDecimal(time.getAllday()));
@@ -510,14 +542,19 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
 //            if (!file.delete()) {
 //                System.out.println("临时文件" + file.getName() + "删除失败");
 //            }
-            //校验是否有重复账号
-            if (userMapper.selectCount(new QueryWrapper<User>().in("phone", phoneList)) == 0) {
-                for (User user : userList) {
-                    userMapper.insert(user);
-                }
+            //检查本次导入人数是否超过上限
+            if (userList.size() > canImportNum) {
+                httpRespMsg.setError("仅剩余"+canImportNum+"人可添加,请减少本次导入的人员数量或者联系客服提高人数上限。");
             } else {
-                httpRespMsg.setError("手机号有重复 批量新建账号失败");
-                /*这里以后可能需要返回重复的手机号的具体信息*/
+                //校验是否有重复账号
+                if (userMapper.selectCount(new QueryWrapper<User>().in("phone", phoneList)) == 0) {
+                    for (User user : userList) {
+                        userMapper.insert(user);
+                    }
+                } else {
+                    httpRespMsg.setError("手机号有重复 批量新建账号失败");
+                    /*这里以后可能需要返回重复的手机号的具体信息*/
+                }
             }
         } catch (IOException e) {
             e.printStackTrace();
@@ -609,4 +646,119 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
 
         return msg;
     }
+//
+//    private String getAccessToken(String code) {
+//        String accessToken = "";
+//
+//        if (redisUtil.existsKey("wxAccessToken")) {
+//            accessToken = redisUtil.getKey("wxAccessToken");
+//        } else {
+//            // 拼接用户授权接口信息
+//            String requestUrl = GET_TOKEN_URL.replace("APPID", appId).replace("SECRET", appSecret)
+//                    .replace("CODE", code);
+//            // 存储获取到的授权字段信息
+//            JSONObject result = new JSONObject();
+//            Map<String, String> dataMap = new HashMap<>();
+//            ResponseEntity<String> responseEntity = this.restTemplate.exchange(requestUrl,
+//                    HttpMethod.GET, null, String.class);
+//            if (responseEntity.getStatusCode() == HttpStatus.OK) {
+//                String resp = responseEntity.getBody();
+//                log.debug("返回信息==" + resp);
+//                System.out.println("返回信息==" + resp);
+//                dataMap.put("resp", resp);
+//                JSONObject OpenidJSONO = JSONObject.parseObject(resp);
+//                result = OpenidJSONO;
+//                if (OpenidJSONO.containsKey("access_token")) {
+//                    accessToken = OpenidJSONO.getString("access_token");
+//                    redisUtil.setKeyWithExpireTime("wxAccessToken", accessToken, 7200);
+//                    return  accessToken;
+//                }
+//            }
+//
+//        }
+//        return null;
+//    }
+
+    @Override
+    public HttpRespMsg bindWeiXin(String code, String userId) {
+        HttpRespMsg respMsg = new HttpRespMsg();
+        log.debug("code==" + code);
+        System.out.println("code==" + code);
+        // 拼接用户授权接口信息
+        String requestUrl = GET_TOKEN_URL.replace("APPID", appId).replace("SECRET", appSecret)
+                .replace("CODE", code);
+        // 存储获取到的授权字段信息
+        JSONObject result = new JSONObject();
+        Map<String, String> dataMap = new HashMap<>();
+        ResponseEntity<String> responseEntity = this.restTemplate.exchange(requestUrl,
+                HttpMethod.GET, null, String.class);
+        if (responseEntity.getStatusCode() == HttpStatus.OK) {
+            String resp = responseEntity.getBody();
+            log.debug("返回信息==" + resp);
+            System.out.println("返回信息==" + resp);
+            dataMap.put("resp", resp);
+            JSONObject OpenidJSONO = JSONObject.parseObject(resp);
+            result = OpenidJSONO;
+            //{"access_token":"32_sheMcGJRDYXVaBoc06o8iT9CyxquudqHl90qGKHg_MGxFhpFA5S8WKUL_mCnfY7O1gcJpS_gBFa4w5Vqb8pCHA","expires_in":7200,"refresh_token":"32_c4ocyhmbbbKyEmG4pS-ywgbV7FkK3A29F_GdZdHKrcvidy0amQeGmhBAo1WBcEWn0T7kSxjbp0BI4lYYtY4wAw","openid":"o1L3L5lOrOl3_UEJjONaoT2Rne1I","scope":"snsapi_userinfo"}
+            if (OpenidJSONO.containsKey("access_token")) {
+                // OpenidJSONO可以得到的内容:access_token expires_in refresh_token openid scope
+                String openid = String.valueOf(OpenidJSONO.get("openid"));
+                String accessToken = String.valueOf(OpenidJSONO.get("access_token"));
+                // 用户保存的作用域
+                String scope = String.valueOf(OpenidJSONO.get("scope"));
+                String refresh_token = String.valueOf(OpenidJSONO.get("refresh_token"));
+
+                // 第四步:拉取用户信息(需scope为 snsapi_userinfo)
+//                String url = GET_USERINFO_URL.replaceAll("accessToken", accessToken).replaceAll("openId", openid);
+//                responseEntity = this.restTemplate.exchange(url,
+//                        HttpMethod.GET, null, String.class);
+//                resp = responseEntity.getBody();
+//                log.debug("获取微信个人信息返回==" + resp);
+//                System.out.println("获取微信个人信息返回==" + resp);
+//                JSONObject json = JSONObject.parseObject(resp);
+                User user = new User();
+                user.setId(userId);
+                user.setWxOpenid(openid);
+                userMapper.updateById(user);
+//                if (!json.containsKey("errcode")) {
+//                    user.setWxOpenid(openid);
+//                }
+                //创建用户
+//                int cnt = wechatUserMapper.selectCount(new QueryWrapper<WechatUser>().eq("open_id", openid));
+//                if (cnt == 0) {
+//                    //检查昵称是否存在
+//                    WechatUser one = wechatUserMapper.selectOne(new QueryWrapper<WechatUser>().eq("nickname", user.getNickname()));
+//                    if (one != null) {
+//                        //按昵称更新
+//                        one.setAvatar(user.getAvatar());
+//                        one.setOpenId(user.getOpenId());
+//                        wechatUserMapper.updateById(one);
+//                    } else {
+//                        wechatUserMapper.insert(user);
+//                    }
+//                }
+                //检测密码正确时
+                User u = userMapper.selectById(userId);
+
+                Company company = companyMapper.selectById(u.getCompanyId());
+                UserVO userVO = new UserVO().setCompanyName(company.getCompanyName());
+                userVO.setCompany(company);
+                BeanUtils.copyProperties(u, userVO);
+                //还要多返回一个公司名字
+                userVO.setPassword("");
+                LocalDateTime remainingTime = company.getExpirationDate() == null ? LocalDateTime.now() : company.getExpirationDate();
+                userVO.setRemainingTime(remainingTime.toInstant(ZoneOffset.of("+8")).toEpochMilli() -
+                        LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
+                //检测是否是项目经理,项目经理有审核功能权限
+                int cnt = projectMapper.selectCount(new QueryWrapper<Project>().eq("incharger_id", userVO.getId()));
+                if (cnt > 0) {
+                    userVO.setLeader(true);
+                }
+                respMsg.data = userVO;
+            } else {
+                respMsg.setError(OpenidJSONO.getString("errcode") + ":" + OpenidJSONO.getString("errmsg"));
+            }
+        }
+        return respMsg;
+    }
 }

+ 78 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/TimingTask.java

@@ -1,17 +1,27 @@
 package com.management.platform.task;
 
+import java.time.LocalDate;
+import java.time.ZoneOffset;
 import java.time.format.DateTimeFormatter;
 
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.management.platform.constant.Constant;
-import com.management.platform.entity.Screenshot;
-import com.management.platform.mapper.ScreenshotMapper;
+import com.management.platform.entity.*;
+import com.management.platform.mapper.*;
 import com.management.platform.service.ScreenshotService;
 import com.management.platform.util.AuthService;
 import com.management.platform.util.CheckPicUtil;
 import com.management.platform.util.RedisUtil;
+import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
+import me.chanjar.weixin.mp.api.WxMpService;
+import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
+import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
+import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.http.*;
 import org.springframework.scheduling.annotation.EnableScheduling;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
@@ -33,11 +43,26 @@ import java.util.Set;
 @EnableScheduling
 @Component
 public class TimingTask {
+
+    @Value("${wx.template_report_fill}")
+    public String TEMPLATE_REPORT_FILL;
+    @Value("${wx.app_id}")
+    public String appId;
+    @Value("${wx.app_secret}")
+    public String appSecret;
     @Autowired
     private RedisUtil redisUtil;
 
     @Resource
     private ScreenshotMapper screenshotMapper;
+    @Resource
+    private TimeTypeMapper timeTypeMapper;
+    @Resource
+    private UserMapper userMapper;
+    @Resource
+    private DepartmentMapper departmentMapper;
+    @Resource
+    private ReportMapper reportMapper;
 
     @Value(value = "${upload.path}")
     private String path;
@@ -73,4 +98,55 @@ public class TimingTask {
             }
         }
     }
+
+
+
+    //每分钟校验是否有需要提醒的填报
+    @Scheduled(fixedRate = 60 * 1000)
+    private void process() {
+        LocalDateTime now = LocalDateTime.now();
+        DateTimeFormatter dt = DateTimeFormatter.ofPattern("HH:mm");
+        String str = dt.format(now);
+        List<TimeType> typeList = timeTypeMapper.selectList(new QueryWrapper<TimeType>().isNotNull("alert_time")
+                .ge("alert_time", str));
+
+        typeList.forEach(t->{
+            if (str.equals(t.getAlertTime())) {
+                //发送推送提醒
+                List<Map<String, Object>> userList = userMapper.getPushUserList(t.getCompanyId());
+                userList.forEach(u->{
+                    push((u));
+                });
+            }
+        });
+    }
+
+    public void push(Map<String, Object> user) {
+        //1,配置
+        WxMpInMemoryConfigStorage wxStorage = new WxMpInMemoryConfigStorage();
+        wxStorage.setAppId(appId);
+        wxStorage.setSecret(appSecret);
+        WxMpService wxMpService = new WxMpServiceImpl();
+        wxMpService.setWxMpConfigStorage(wxStorage);
+
+        //2,推送消息
+        WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
+                .toUser((String)user.get("wxOpenid"))//要推送的用户openid
+                .templateId(TEMPLATE_REPORT_FILL)//模版id
+                .url("http://mobworktime.ttkuaiban.com/#/edit")//点击模版消息要访问的网址
+                .build();
+        //3,如果是正式版发送模版消息,这里需要配置你的信息
+        templateMessage.addData(new WxMpTemplateData("first", "您今天的工时填报还未完成", "#FF00FF"));
+        templateMessage.addData(new WxMpTemplateData("keyword1", (String)user.get("name"), "#000000"));
+        templateMessage.addData(new WxMpTemplateData("keyword2", (String)user.get("departmentName"), "#000000"));
+        templateMessage.addData(new WxMpTemplateData("remark", "请尽快填报", "#000000"));
+        //                templateMessage.addData(new WxMpTemplateData(name2, value2, color2));
+        try {
+            wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
+        } catch (Exception e) {
+            System.out.println("推送失败:" + e.getMessage());
+            e.printStackTrace();
+        }
+
+    }
 }

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

@@ -86,7 +86,11 @@ picrecongnize:
   develop: C:/picrecongnize/develop/
   im: C:/picrecongnize/im/
   design: C:/picrecongnize/design/
-
+# 智能工时管家公众号参数
+wx:
+  template_report_fill: lhwkaW9BKwCvMtCuoAxLw4lZoGgMaucL0Ap0Vz-5KOY
+  app_id: wx749c84daac654e1e
+  app_secret: aacbd046ec1c790836f4f684c96fe585
 ##actuator健康检查配置
 management:
   security:

+ 16 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/AlertTimeMapper.xml

@@ -0,0 +1,16 @@
+<?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.AlertTimeMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.AlertTime">
+        <id column="company_id" property="companyId" />
+        <result column="alert_time" property="alertTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        company_id, alert_time
+    </sql>
+
+</mapper>

+ 7 - 4
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportMapper.xml

@@ -29,7 +29,7 @@
     </sql>
     <!--根据日期获取全部报告信息-->
     <select id="getAllReportByDate" resultType="java.util.Map">
-        SELECT c.name, b.project_name AS project, a.working_time AS duration, a.content, a.create_time AS time,
+        SELECT c.name, b.project_name AS project, a.working_time AS duration, a.content, a.create_time AS time, a.create_date as createDate,
         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, d.name as subProjectName,a.task_id as taskId, task.name as taskName, a.is_overtime as isOvertime,a.progress as progress
         FROM report AS a
@@ -38,8 +38,11 @@
         left join sub_project as d on d.id = a.sub_project_id
         left join task on task.id = a.task_id
         WHERE a.state = 1
-        <if test="date != null and date != ''">
-            AND a.create_date = #{date}
+        <if test="startDate != null and startDate != ''">
+            AND a.create_date between #{startDate} and #{endDate}
+        </if>
+        <if test="projectId != null">
+            AND a.project_id = #{projectId}
         </if>
         <if test="companyId != null">
             AND c.company_id = #{companyId}
@@ -47,7 +50,7 @@
         <if test="userId != null">
             AND a.creator_id = #{userId}
         </if>
-        ORDER BY a.creator_id ASC
+        ORDER BY a.id desc
     </select>
 
     <!--根据员工id,日期获取当天全部报告信息-->

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/SysFunctionMapper.xml

@@ -0,0 +1,21 @@
+<?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.SysFunctionMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.SysFunction">
+        <id column="id" property="id" />
+        <result column="name" property="name" />
+        <result column="icon" property="icon" />
+        <result column="code" property="code" />
+        <result column="module_id" property="moduleId" />
+        <result column="seq" property="seq" />
+        <result column="use_state" property="useState" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, name, icon, code, module_id, seq, use_state
+    </sql>
+
+</mapper>

+ 23 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/SysModuleMapper.xml

@@ -0,0 +1,23 @@
+<?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.SysModuleMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.SysModule">
+        <id column="id" property="id" />
+        <result column="name" property="name" />
+        <result column="path" property="path" />
+        <result column="parent_id" property="parentId" />
+        <result column="icon" property="icon" />
+        <result column="orderitem" property="orderitem" />
+        <result column="is_menu" property="isMenu" />
+        <result column="use_state" property="useState" />
+        <result column="config" property="config" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, name, path, parent_id, icon, orderitem, is_menu, use_state, config
+    </sql>
+
+</mapper>

+ 16 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/SysRoleFunctionMapper.xml

@@ -0,0 +1,16 @@
+<?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.SysRoleFunctionMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.SysRoleFunction">
+        <id column="role_id" property="roleId" />
+        <result column="function_id" property="functionId" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        role_id, function_id
+    </sql>
+
+</mapper>

+ 18 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/SysRoleMapper.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.SysRoleMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.SysRole">
+        <id column="id" property="id" />
+        <result column="company_id" property="companyId" />
+        <result column="rolename" property="rolename" />
+        <result column="role_describe" property="roleDescribe" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, company_id, rolename, role_describe
+    </sql>
+
+</mapper>

+ 16 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/SysRoleModuleMapper.xml

@@ -0,0 +1,16 @@
+<?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.SysRoleModuleMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.SysRoleModule">
+        <id column="role_id" property="roleId" />
+        <result column="module_id" property="moduleId" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        role_id, module_id
+    </sql>
+
+</mapper>

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

@@ -12,11 +12,12 @@
         <result column="hour_cost_input_type" property="hourCostInputType" />
         <result column="type" property="type" />
         <result column="pay_overtime" property="payOvertime" />
+        <result column="alert_time" property="alertTime" />
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        company_id, allday, am, pm, month_days, hour_cost_input_type, type, pay_overtime
+        company_id, allday, am, pm, month_days, hour_cost_input_type, type, pay_overtime, alert_time
     </sql>
 
 </mapper>

+ 14 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/UserMapper.xml

@@ -20,11 +20,14 @@
         <result column="manage_dept_id" property="manageDeptId" />
         <result column="color" property="color" />
         <result column="is_active" property="isActive" />
+        <result column="wx_openid" property="wxOpenid" />
+        <result column="role_id" property="roleId" />
+        <result column="role_name" property="roleName" />
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        id, name, phone, password, portrait_url, create_time, role, company_id, department_id, department_cascade, cost, month_cost, salary_type, manage_dept_id, color, is_active
+        id, name, phone, password, portrait_url, create_time, role, company_id, department_id, department_cascade, cost, month_cost, salary_type, manage_dept_id, color, is_active, wx_openid, role_id, role_name
     </sql>
     <!--单独分页获取人员-->
     <select id="getUserByDepartment" resultType="java.util.Map">
@@ -71,4 +74,14 @@
             #{departmentId}
         </foreach>
     </select>
+
+
+    <select id="getPushUserList" resultType="java.util.Map">
+        SELECT a.id, a.wx_openid as wxOpenid, a.name, a.phone, b.department_name AS departmentName
+        FROM user AS a LEFT JOIN  department b ON a.department_id = b.department_id
+        WHERE a.company_id = #{companyId}
+        AND a.wx_openid IS NOT NULL
+        AND a.is_active = 1
+        AND NOT EXISTS(SELECT 1 FROM report WHERE report.`creator_id` = a.id AND report.`create_date` = DATE_FORMAT(NOW(), '%Y-%m-%d'))
+    </select>
 </mapper>

+ 1 - 1
fhKeeper/formulahousekeeper/timesheet/build/webpack.base.conf.js

@@ -17,7 +17,7 @@ module.exports = {
         'vue': 'Vue',
         'vue-router': 'VueRouter',
         'vuex': 'Vuex',
-        'element-ui': 'ElementUI',
+        // 'element-ui': 'ElementUI',
         'echarts': 'echarts',
     },
     output: {

+ 26 - 3
fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/demo_index.html

@@ -54,6 +54,12 @@
       <div class="content unicode" style="display: block;">
           <ul class="icon_lists dib-box">
           
+            <li class="dib">
+              <span class="icon iconfont">&#xe663;</span>
+                <div class="name">权限</div>
+                <div class="code-name">&amp;#xe663;</div>
+              </li>
+          
             <li class="dib">
               <span class="icon iconfont">&#xe788;</span>
                 <div class="name">报销</div>
@@ -276,9 +282,9 @@
 <pre><code class="language-css"
 >@font-face {
   font-family: 'iconfont';
-  src: url('iconfont.woff2?t=1621903475590') format('woff2'),
-       url('iconfont.woff?t=1621903475590') format('woff'),
-       url('iconfont.ttf?t=1621903475590') format('truetype');
+  src: url('iconfont.woff2?t=1622768216453') format('woff2'),
+       url('iconfont.woff?t=1622768216453') format('woff'),
+       url('iconfont.ttf?t=1622768216453') format('truetype');
 }
 </code></pre>
           <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
@@ -304,6 +310,15 @@
       <div class="content font-class">
         <ul class="icon_lists dib-box">
           
+          <li class="dib">
+            <span class="icon iconfont firerock-iconquanxian"></span>
+            <div class="name">
+              权限
+            </div>
+            <div class="code-name">.firerock-iconquanxian
+            </div>
+          </li>
+          
           <li class="dib">
             <span class="icon iconfont firerock-iconbaoxiao"></span>
             <div class="name">
@@ -637,6 +652,14 @@
       <div class="content symbol">
           <ul class="icon_lists dib-box">
           
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#firerock-iconquanxian"></use>
+                </svg>
+                <div class="name">权限</div>
+                <div class="code-name">#firerock-iconquanxian</div>
+            </li>
+          
             <li class="dib">
                 <svg class="icon svg-icon" aria-hidden="true">
                   <use xlink:href="#firerock-iconbaoxiao"></use>

+ 7 - 3
fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.css

@@ -1,8 +1,8 @@
 @font-face {
   font-family: "iconfont"; /* Project id 2390497 */
-  src: url('iconfont.woff2?t=1621903475590') format('woff2'),
-       url('iconfont.woff?t=1621903475590') format('woff'),
-       url('iconfont.ttf?t=1621903475590') format('truetype');
+  src: url('iconfont.woff2?t=1622768216453') format('woff2'),
+       url('iconfont.woff?t=1622768216453') format('woff'),
+       url('iconfont.ttf?t=1622768216453') format('truetype');
 }
 
 .iconfont {
@@ -13,6 +13,10 @@
   -moz-osx-font-smoothing: grayscale;
 }
 
+.firerock-iconquanxian:before {
+  content: "\e663";
+}
+
 .firerock-iconbaoxiao:before {
   content: "\e788";
 }

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.js


+ 7 - 0
fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.json

@@ -5,6 +5,13 @@
   "css_prefix_text": "firerock-icon",
   "description": "",
   "glyphs": [
+    {
+      "icon_id": "12860884",
+      "name": "权限",
+      "font_class": "quanxian",
+      "unicode": "e663",
+      "unicode_decimal": 58979
+    },
     {
       "icon_id": "2101853",
       "name": "报销",

BIN
fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.ttf


BIN
fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.woff


BIN
fhKeeper/formulahousekeeper/timesheet/src/assets/myfont/iconfont.woff2


+ 51 - 29
fhKeeper/formulahousekeeper/timesheet/src/main.js

@@ -1,10 +1,10 @@
 // import Vue from 'vue'
 // import VueRouter from 'vue-router'
 // Vue.use(VueRouter)
-// import ElementUI from 'element-ui'
-//全局修改默认配置,点击空白处不能关闭弹窗
-// Dialog.props.closeOnClickModal.default = false
-// Vue.use(ElementUI)
+import ElementUI from 'element-ui'
+// 全局修改默认配置,点击空白处不能关闭弹窗
+ElementUI.Dialog.props.closeOnClickModal.default = false
+Vue.use(ElementUI)
 // import Vuex from 'vuex'
 // Vue.use(Vuex)
 // import echarts from 'echarts'
@@ -37,14 +37,18 @@ import './assets/myfont/iconfont.css'
 // const router = new VueRouter({
 //     routes
 // })
-import { staffRouter, manageRouter, fixedRouter,leaderRouter, projectManageRouter, expenseRouter,sysManageRouter } from './routes'
+import {fixedRouter, allRouters } from './routes'
 import router from './routes'
 
 import NProgress from 'nprogress'
 import 'nprogress/nprogress.css'
 
 var addRouFlag = false;
-
+//角色权限对应关系
+var userModules = [{role:0, modules:["工时报告","自动计时","项目管理"]},
+            {role:3, modules:["成本统计","财务核算成本","项目管理"]},
+            {role:4, modules:["组织架构"]},
+            {role:5, modules:["工时报告","自动计时","项目管理"]},];
 router.beforeEach((to, from, next) => {
     NProgress.start();
     if (to.path == '/register') {
@@ -54,7 +58,7 @@ router.beforeEach((to, from, next) => {
 
     if(to.path != '/daily') {
         sessionStorage.removeItem("from")
-    }
+    } 
 
     if (to.path == '/login') {
         sessionStorage.removeItem('user');
@@ -66,31 +70,49 @@ router.beforeEach((to, from, next) => {
     } else {
         if (!addRouFlag) {
             if(user != null) {
-                addRouFlag = true
-                if(user.role == 0) {
-                    var getRoutes = baseRoleGetRouters(user.leader?leaderRouter:staffRouter, user);
-                    if (user.company.packageProject == 1 && !user.leader) {
-                        getRoutes = getRoutes.concat(projectManageRouter);
-                    }
-                    if (user.company.packageExpense == 1) {
-                        getRoutes = getRoutes.concat(expenseRouter);
-                    }
-                    global.antRouter = fixedRouter.concat(getRoutes);
-                    router.addRoutes(fixedRouter.concat(getRoutes));
-                    router.options.routes = fixedRouter.concat(getRoutes);
-                    router.push({ path: to.path })
+                addRouFlag = true;
+                var getRoutes = null;
+                if (user.company.packageExpense == 0) {
+                    allRoutes = allRouters.filter(r=>r.name != '费用报销');
+                }
+                if (user.role == 1 || user.role == 2) {
+                    getRoutes = allRouters;
                 } else {
-                    var getRoutes = baseRoleGetRouters(manageRouter, user);
-                    if (user.company.packageExpense == 1) {
-                        getRoutes = getRoutes.concat(expenseRouter);
-                    }
-                    getRoutes = getRoutes.concat(sysManageRouter);
+                    var modules = userModules.filter(u=>u.role == user.role)[0].modules;
                     
-                    global.antRouter = fixedRouter.concat(getRoutes);
-                    router.addRoutes(fixedRouter.concat(getRoutes));
-                    router.options.routes = fixedRouter.concat(getRoutes);
-                    router.push({ path: to.path })
+                    getRoutes = allRouters.filter(r=>{
+                        return modules.filter(m=>m == r.name).length > 0;
+                    });
                 }
+                global.antRouter = fixedRouter.concat(getRoutes);
+                router.addRoutes(fixedRouter.concat(getRoutes));
+                router.options.routes = fixedRouter.concat(getRoutes);
+                router.push({ path: to.path })
+                
+                // if(user.role == 0) {
+                //     var getRoutes = baseRoleGetRouters(user.leader?leaderRouter:staffRouter, user);
+                //     if (user.company.packageProject == 1 && !user.leader) {
+                //         getRoutes = getRoutes.concat(projectManageRouter);
+                //     }
+                //     if (user.company.packageExpense == 1) {
+                //         getRoutes = getRoutes.concat(expenseRouter);
+                //     }
+                //     global.antRouter = fixedRouter.concat(getRoutes);
+                //     router.addRoutes(fixedRouter.concat(getRoutes));
+                //     router.options.routes = fixedRouter.concat(getRoutes);
+                //     router.push({ path: to.path })
+                // } else {
+                //     var getRoutes = baseRoleGetRouters(manageRouter, user);
+                //     if (user.company.packageExpense == 1) {
+                //         getRoutes = getRoutes.concat(expenseRouter);
+                //     }
+                //     getRoutes = getRoutes.concat(sysManageRouter);
+                    
+                //     global.antRouter = fixedRouter.concat(getRoutes);
+                //     router.addRoutes(fixedRouter.concat(getRoutes));
+                //     router.options.routes = fixedRouter.concat(getRoutes);
+                //     router.push({ path: to.path })
+                // }
             }
         }
         next()

+ 28 - 145
fhKeeper/formulahousekeeper/timesheet/src/routes.js

@@ -31,6 +31,7 @@ import team from './views/team/index.vue'
 
 // 系统设置
 import timetype from './views/settings/timetype.vue';
+import role from './views/role/role';
 
 import finance from './views/project/finance';
 import Market from './views/market/list';
@@ -88,36 +89,7 @@ export const fixedRouter = [
     },
     
 ];
-export const projectManageRouter = [
-    //项目管理
-    {
-        path: '/',
-        component: Home,
-        name: '项目管理',
-        iconCls: 'iconfont firerock-iconxiangmu',
-        leaf: true,
-        children: [
-            { path: '/list', component: list, name: '项目管理' },
-            { path: '/projectInside/:id', component: projectInside, name: '项目查看' },
-        ]
-    }
-];
-export const expenseRouter = [
-    // 费用报销模块
-    {
-        path: '/',
-        component: Home,
-        name: '费用报销',
-        iconCls: 'iconfont firerock-iconbaoxiao',
-        leaf: true,
-        children: [
-            { path: '/expense', component: expense, name: '费用报销' }
-        ]
-    }
-];
-
-export const manageRouter = [
-    
+export const allRouters = [//组织架构
     //工时报告
     {
         path: '/',
@@ -150,18 +122,7 @@ export const manageRouter = [
             { path: '/review', component: review, name: '报告审核' },
         ]
     },
-
-    // {
-    //             path: '/',
-    //             component: Home,
-    //             name: '费用报销',
-    //             iconCls: 'iconfont firerock-iconbaoxiao',
-    //             leaf: true,
-    //             children: [
-    //                 { path: '/expense', component: expense, name: '费用报销' }
-    //             ]
-    //         },
-
+    
     //成本统计
     {
         path: '/',
@@ -186,9 +147,6 @@ export const manageRouter = [
             { path: '/finance', component: finance, name: '财务核算成本' },
         ]
     },
-    
-    
-
     //项目管理
     {
         path: '/',
@@ -198,101 +156,50 @@ export const manageRouter = [
         leaf: true,
         children: [
             { path: '/list', component: list, name: '项目管理' },
-            { path: '/projectInside/:id', component: projectInside, name: '项目查看' },
         ]
     },
-
-    {
-        path: '/404',
-        component: NotFound,
-        name: '',
-        hidden: true
-    },
-    {
-        path: '*',
-        hidden: true,
-        redirect: { path: '/404' }
-    }
-];
-
-export const staffRouter = [
-    //工时报告
+    // 费用报销模块
     {
         path: '/',
         component: Home,
-        name: '工时报告',
-        iconCls: 'fa fa-sticky-note',
+        name: '费用报销',
+        iconCls: 'iconfont firerock-iconbaoxiao',
         leaf: true,
         children: [
-            { path: '/daily', component: daily, name: '工时报告' },
+            { path: '/expense', component: expense, name: '费用报销' }
         ]
     },
     {
         path: '/',
         component: Home,
-        name: '自动计时',
-        iconCls: 'iconfont firerock-iconmiaobiao',
-        leaf: true,
+        name: '组织架构',
+        iconCls: 'fa fa-users',
+        leaf: true,//只有一个节点
         children: [
-            { path: '/timer', component: timer, name: '自动计时' },
+            { path: '/team', component: team, name: '组织架构' },
         ]
     },
+    // {
+    //     path: '/',
+    //     component: Home,
+    //     name: '',
+    //     iconCls: 'iconfont firerock-iconquanxian',
+    //     leaf: true,//只有一个节点
+    //     children: [
+    //         { path: '/role', component: role, name: '角色权限' },
+    //     ]
+    // },
     
+    //设置时间类型
     {
-        path: '/404',
-        component: NotFound,
-        name: '',
-        hidden: true
-    },
-    {
-        path: '*',
-        hidden: true,
-        redirect: { path: '/404' }
-    }
-];
-//项目经理的权限,填报和审核
-export const leaderRouter = [
-    //工时报告
-    {
-        path: '/',
-        component: Home,
-        name: '工时报告',
-        iconCls: 'fa fa-sticky-note',
-        leaf: true,
-        children: [
-            { path: '/daily', component: daily, name: '工时报告' },
-        ]
-    },
-    {
-        path: '/',
-        component: Home,
-        name: '自动计时',
-        iconCls: 'iconfont firerock-iconmiaobiao',
-        leaf: true,
-        children: [
-            { path: '/timer', component: timer, name: '自动计时' },
-        ]
-    },
-    //工时审核
-    {
-        path: '/',
-        component: Home,
-        name: '报告审核',
-        iconCls: 'iconfont firerock-iconshenhe',
-        leaf: true,
-        children: [
-            { path: '/review', component: review, name: '报告审核' },
-        ]
-    },
-    //项目管理
-    {
+        
         path: '/',
         component: Home,
-        name: '项目管理',
-        iconCls: 'iconfont firerock-iconxiangmu',
-        leaf: true,
+        name: '',
+        iconCls: 'iconfont firerock-iconsetting',
+        leaf: true,//只有一个节点
         children: [
-            { path: '/list', component: list, name: '项目管理' },
+            { path: '/timetype', component: timetype, name: '系统基础设置' },
         ]
     },
     {
@@ -306,31 +213,7 @@ export const leaderRouter = [
         hidden: true,
         redirect: { path: '/404' }
     }
-];
-
-export const sysManageRouter = [//组织架构
-    {
-        path: '/',
-        component: Home,
-        name: '',
-        iconCls: 'fa fa-users',
-        leaf: true,//只有一个节点
-        children: [
-            { path: '/team', component: team, name: '组织架构' },
-        ]
-    },
-    //设置时间类型
-    {
-        
-        path: '/',
-        component: Home,
-        name: '',
-        iconCls: 'iconfont firerock-iconsetting',
-        leaf: true,//只有一个节点
-        children: [
-            { path: '/timetype', component: timetype, name: '系统基础设置' },
-        ]
-    },]
+]
 
 export default new Router({
     routes: fixedRouter

+ 11 - 1
fhKeeper/formulahousekeeper/timesheet/src/views/Login.vue

@@ -76,8 +76,18 @@
                         this.http.post(this.port.manage.login, this.ruleForm , res => {
                             this.logining = false;
                             if (res.code == "ok") {
+                                var user = res.data;
                                 sessionStorage.setItem('user', JSON.stringify(res.data));
-                                this.$router.push({ path: '/daily' });
+                                if (user.role == 3) {
+                                    //公司高层
+                                    this.$router.push({ path: '/cost' });
+                                } else if (user.role == 4) {
+                                    //人事管理员
+                                    this.$router.push({ path: '/team' });
+                                } else {
+                                    this.$router.push({ path: '/daily' });
+                                }
+                                
                             } else {
                                 this.$message({
                                     message: res.msg,

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

@@ -455,11 +455,7 @@ export default {
     delec(ids) {
       // console.log('删除操作', ids);
       this.ParticularsList.invoiceList.splice(ids, 1)
-      this.$message({
-        message: '删除成功',
-        type: "success"
-      });
-      // 发起删除请求
+      
     },
      adds() {
       // happenDate

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

@@ -27,7 +27,7 @@
                             <el-option label="已撤销" value=3 ></el-option>
                         </el-select>
                 </el-form-item>
-                <el-form-item style="float:right;">
+                <el-form-item style="float:right;" v-if="user.role == 1||user.role == 2||user.role == 5">
                     <el-link type="primary" :underline="false" @click="handleAdd(-1,null)">新增项目</el-link>
                 </el-form-item>
             </el-form>
@@ -70,7 +70,7 @@
                     {{scope.row.progress==null?"-":scope.row.progress}}%
                 </template>
             </el-table-column>
-            <el-table-column label="操作" width="290">
+            <el-table-column label="操作" width="290" v-if="user.role == 1||user.role == 2||user.role == 5 || user.leader">
                 <template slot-scope="scope">
                     <el-button v-if="user.role>0" size="mini"  @click="subProject(scope.row)">子项目</el-button>
                     <el-button size="mini" v-if="user.role>0 || user.id==scope.row.inchargerId" type="primary" @click="handleAdd(scope.$index, scope.row)">编辑</el-button>
@@ -146,7 +146,7 @@
             <!-- 项目基线 -->
                 <!-- <div style="width: 100%;border: 1px solid #ddd"></div> -->
                 
-                <div style="margin: 90px 0 30px 0">
+                <div style="margin: 90px 0 30px 0" >
                     <el-divider></el-divider>
                     <span class="el-dialog__title">成本基线</span>
                 </div>
@@ -181,11 +181,11 @@
                 placeholder="整数" clearable @keyup.native="addForm.baseRisk2=addForm.baseRisk2.replace(/[^\d]/g,'');"></el-input><span style="margin-left:10px;">元</span>
             </div>
             <!-- 合计 -->
-            <div style="margin-top: 20px">
-                <span style="margin-left:50px;margin-right:10px;" v-if="user.company.packageProject==1">合计</span>
+            <div style="margin-top: 20px;float:right;">
+                <span style="margin-right:50px;margin-right:10px;" v-if="user.company.packageProject==1">合计</span>
                  <span v-if="addForm.budget <= 0 || addForm.budget == undefined">0</span>
                  <span v-else>{{addForm.budget | numberToCurrency}}</span>
-                <span style="margin-left:10px;">元</span>
+                <span style="margin-right:50px;margin-left:10px;">元</span>
             </div>
 
 
@@ -201,7 +201,7 @@
             <div class="line"><span>姓名</span><span>{{userDetail.name}}</span></div>
             <div class="line"><span>手机号码</span><span>{{userDetail.phone}}</span></div>
             <div class="line"><span>部门</span><span>{{userDetail.departmentName}}</span></div>
-            <div class="line" v-if="user.role>0"><span>成本</span><span>{{userDetail.cost}}元/小时</span></div>
+            <div class="line" v-if="user.role>0&&user.role<=3"><span>成本</span><span>{{userDetail.cost}}元/小时</span></div>
             <div slot="footer" class="dialog-footer">
                 <el-button type="primary" @click="userDetailVisible = false" >确定</el-button>
             </div>

+ 7 - 4
fhKeeper/formulahousekeeper/timesheet/src/views/project/projectInside.vue

@@ -224,11 +224,12 @@
             <el-tab-pane label="文件中心" name="files"><FileCenter ref="fileCenter"></FileCenter></el-tab-pane>
             <el-tab-pane label="项目概览" name="info"><ProjectInfo ref="projectInfo"></ProjectInfo></el-tab-pane>
             <el-tab-pane label="数据统计" name="summary"><Summary ref="summary"></Summary></el-tab-pane>
-            <el-tab-pane label="挣值分析" name="earning" v-if="user.role > 0 || user.id == currentProject.inchargerId"><Earning ref="earning"></Earning></el-tab-pane>
+            <el-tab-pane label="挣值分析" name="earning" v-if="user.role >= 1 && user.role<=3"><Earning ref="earning"></Earning></el-tab-pane>
         </el-tabs>
         
         <!--新增任务界面-->
-        <el-dialog class="jm" :title="title" v-if="addFormVisible" :visible.sync="addFormVisible" :close-on-click-modal="false" customClass="customWidth" width="800px">
+        <el-dialog :class="addForm.id==null?'':'jm'" :title="title" v-if="addFormVisible" :visible.sync="addFormVisible" 
+        :close-on-click-modal="false" customClass="customWidth" width="800px">
         <!-- <div style="width: 200%;height:80%;position: absolute;right:-100%;top:0;background:#000;opacity: 0;" @click="sss"></div> -->
 
             <el-form ref="form1" :model="addForm" :rules="taskRules" label-width="100px">
@@ -451,7 +452,7 @@
                 <el-page-header  @back="backToParentTask" title="返回父任务" :content="addForm.parentTname"></el-page-header>
             </div>
             <!-- 评论 -->
-            <div class="remark">
+            <div class="remark" v-show="addForm.id != null">
                 <span class="zh">
                     <span  v-for="(pl, i) in critic" :key="i">
                         <div class="player" v-if="pl">
@@ -1331,7 +1332,8 @@
             },  
             // 获取评论列表
             gain (task) {
-                this.taskId = task.id
+                this.commentList = [];
+                this.taskId = task.id;
                 this.http.post('/task-comment/getList', {taskId: task.id},
                 res => {
                     if (res.code == "ok") {
@@ -1417,6 +1419,7 @@
                 this.addForm = {projectId: stage.projectId, groupId: stage.groupId, stagesId: stage.id, taskLevel:0, planHours: 8, taskType: 0};
                 this.addLoading = false;
                 this.title="创建任务";
+                this.commentList = [];
             },
             renameStage(item) {
                 this.stageForm = JSON.parse(JSON.stringify(item));

+ 184 - 0
fhKeeper/formulahousekeeper/timesheet/src/views/role/role.vue

@@ -0,0 +1,184 @@
+<template>
+  <div class="app-container">
+    <div>
+      <el-row>
+        <el-col :span="24">
+          <el-button size="small" type="primary" @click="openCreateDialog">新增角色</el-button>
+        </el-col>
+      </el-row>
+      <el-table :data="roles" style="width: 100%" v-loading="loading">
+        <el-table-column type="index" width="40"></el-table-column>
+        <el-table-column prop="rolename" label="角色名称" width="160"></el-table-column>
+        <el-table-column prop="roleDescribe" label="角色描述"></el-table-column>
+        <el-table-column label="操作" width="290">
+          <template slot-scope="scope">
+            <el-button size="small" @click="openEditDialog(scope.$index)">修改角色</el-button>
+            <el-button
+              size="small"
+              @click="toAuthority(scope.row.id,scope.row.rolename)"
+            >修改权限</el-button>
+            <el-button
+              size="small"
+              type="danger"
+              @click="deleteRole(scope.row.id,scope.row.rolename)"
+            >删除角色</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+
+    <!-- 添加或修改的dialog -->
+    <el-dialog :close-on-click-modal="false" :title="(roleForm.id==null?'新增':'修改')+'角色'" :visible.sync="dialogVisible" width="400px">
+      <el-form ref="form" :model="roleForm" :rules="rules" label-width="60px">
+        <el-form-item label="名称" prop="name">
+          <el-input v-model="roleForm.name" ref="name" placeholder="请输入名称" clearable></el-input>
+        </el-form-item>
+        <el-form-item label="描述" prop="description">
+          <el-input v-model="roleForm.description" placeholder="请输入描述" clearable></el-input>
+        </el-form-item>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisible=false">取消</el-button>
+        <el-button type="primary" @click="submitRole">提交</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import util from "../../common/js/util";
+
+export default {
+  data() {
+    return {
+      roles: [],
+      loading: false,
+      dialogVisible: false,
+      roleForm: {
+        id: null,
+        name: null,
+        description: null
+      },
+      rules: {
+        name: [{ required: true, message: "请输入名称", trigger: "blur" }],
+        description: [
+          { required: true, message: "请输入描述", trigger: "blur" }
+        ]
+      },
+      //权限
+      viewPermission:
+        store.getters.authorization.indexOf("pc_view_permission") != -1,
+      editPermission:
+        store.getters.authorization.indexOf("pc_set_permission") != -1
+    };
+  },
+  methods: {
+    getRole() {
+      this.loading = true;
+      request({
+        url: "/permission/getRoleList",
+        method: "post"
+      })
+        .then(response => {
+          this.roles = response.data;
+          this.loading = false;
+        })
+        .catch(error => {
+          this.loading = false;
+        });
+    },
+    submitRole() {
+      this.$refs.form.validate(valid => {
+        if (valid) {
+          this.loading = true;
+          request({
+            url: "/permission/editRole",
+            method: "post",
+            params: {
+              id: this.roleForm.id,
+              name: this.roleForm.name,
+              description: this.roleForm.description
+            }
+          })
+            .then(response => {
+              this.loading = false;
+              if (response.code == 'ok') {
+                  this.$message({
+                    message: "操作成功",
+                    type: "success"
+                  });
+                  this.dialogVisible = false;
+                  this.getRole();
+              } else {
+                  this.$message({
+                    message: response.message,
+                    type: "error"
+                  });
+              }
+              
+            })
+            .catch(error => {
+              this.loading = false;
+            });
+        }
+      });
+    },
+    //删除
+    deleteRole(id, name) {
+      this.$confirm("是否删除" + name, "删除", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        closeOnClickModal: false,
+        type: "warning"
+      }).then(() => {
+        this.loading = true;
+        request({
+          url: "/permission/deleteRole",
+          method: "post",
+          params: {
+            id: id
+          }
+        })
+          .then(response => {
+            this.loading = false;
+            this.getRole();
+          })
+          .catch(error => {
+            this.loading = false;
+          });
+      });
+    },
+
+    //打开新建dialog
+    openCreateDialog() {
+      this.roleForm.id = null;
+      this.roleForm.name = "";
+      this.roleForm.description = "";
+      this.dialogVisible = true;
+      this.$nextTick(() => {
+          this.$refs.form.clearValidate();
+          this.$refs.name.focus();
+      },500)
+      
+    },
+    //打开编辑dialog
+    openEditDialog(index) {
+      this.roleForm.id = this.roles[index].id;
+      this.roleForm.name = this.roles[index].rolename;
+      this.roleForm.description = this.roles[index].roleDescribe;
+      this.dialogVisible = true;
+      this.$refs.form.clearValidate();
+    },
+    toAuthority(id, name) {
+      this.$router.push("/authority/" + id + "/" + name);
+    }
+  },
+  mounted() {
+    this.getRole();
+  }
+};
+</script>
+
+<style scoped>
+</style>
+

+ 24 - 1
fhKeeper/formulahousekeeper/timesheet/src/views/settings/timetype.vue

@@ -143,7 +143,30 @@
         </div>
         </el-col>
         </el-row>
-
+        <!--设置时长样式内容-->
+        <p style="margin-left:10px;color:#666;">填报提醒时间设置</p>
+        <el-row :gutter="20" style="padding-top:10px;width:100%;margin:0 auto;padding-left:10px;padding-right:10px;">
+        <el-col :span="24" >
+            <div class="panel" style="height:60px;">
+                <el-form :inline="true" :model="timeType"  style="margin-top:10px;">
+                 
+                <el-form-item label="未填报提醒时间 " prop="alertTime">
+                    <el-time-picker 
+                            v-model="timeType.alertTime"
+                            placeholder="提醒时间"
+                            style="width:120px;"
+                            format="HH:mm"
+                            value-format="HH:mm"
+                            :picker-options="{
+                            start: '08:00',
+                            end: '23:30'
+                            }">
+                        </el-time-picker>
+                </el-form-item>
+                </el-form>
+            </div>
+        </el-col>
+        </el-row>
         <div style="width:80px;margin:0 auto;padding:20px;">
             <el-button  type="primary" @click="submitInsert" :loading="addLoading">保存</el-button>
         </div>

+ 28 - 5
fhKeeper/formulahousekeeper/timesheet/src/views/team/index.vue

@@ -66,7 +66,7 @@
                 <el-table-column prop="phone" label="手机" width="120"></el-table-column>
                 <el-table-column prop="departmentName" label="部门" sortable></el-table-column>
                 <el-table-column label="角色" width="100">
-                    <template slot-scope="scope">{{scope.row.role == 0 ? "普通员工" : scope.row.role == 1 ? "负责人" : "管理员"}}</template>
+                    <template slot-scope="scope">{{roleArray[scope.row.role]}}</template>
                 </el-table-column>
                 <el-table-column prop="monthCost" label="月成本" sortable>
                     <template slot-scope="scope">{{scope.row.monthCost==null?0:scope.row.monthCost}} 元</template>
@@ -122,7 +122,7 @@
         </el-dialog>
 
         <!-- 新增单个人员的Dialog -->
-        <el-dialog :title="title" :visible.sync="dialogVisible" width="450px" >
+        <el-dialog :title="title" :visible.sync="dialogVisible" width="550px" >
             <el-form ref="form1" :model="insertForm" :rules="rules" label-width="80px">
                 <el-form-item label="名字" prop="name">
                     <el-input v-model="insertForm.name" placeholder="请输入姓名" clearable></el-input>
@@ -150,8 +150,21 @@
                 </el-form-item>
                 <el-form-item label="角色" prop="role">
                     <el-select v-model="insertForm.role" placeholder="请选择角色" style="width: 100%">
-                        <el-option label="普通员工" :value="0"></el-option>
-                        <el-option label="管理员" :value="2"></el-option>
+                        <!-- <el-option label="普通员工" :value="0">
+                            <span style="float: left">普通员工</span>
+                            <span style="float: right; color: #8492a6; font-size: 13px">具有填报日报,参与项目协作基础功能</span>
+                        </el-option>
+                        <el-option label="系统管理员" :value="2" :disabled="user.role != 1">
+                            <span style="float: left">普通员工</span>
+                            <span style="float: right; color: #8492a6; font-size: 13px">具有填报日报,参与项目协作基础功能</span>
+                        </el-option>
+                        <el-option label="公司高层" :value="3"></el-option>
+                        <el-option label="人事管理员" :value="4"></el-option>
+                        <el-option label="项目管理员" :value="5"></el-option> -->
+                        <el-option v-for="item in roleDescArray" :label="item.label" :value="item.value" :key="item.name">
+                            <span style="float: left">{{item.label}}</span>
+                            <span style="float: right; color: #8492a6; font-size: 13px">{{item.desc}}</span>
+                        </el-option>
                     </el-select>
                 </el-form-item>
             </el-form>
@@ -161,7 +174,7 @@
             </span>
         </el-dialog>
 
-        <el-dialog title="修改成本" :visible.sync="dialogVisible1" width="450px" >
+        <el-dialog title="修改成本" :visible.sync="dialogVisible1" width="550px" >
             <el-form ref="form1" :model="insertForm" :rules="rules" label-width="80px">
                 <el-form-item label="薪酬方式" prop="salaryType">
                     <el-radio-group v-model="insertForm.salaryType" @change="onSalaryTypeChange">
@@ -222,6 +235,12 @@
     export default {
         data() {
             return {
+                roleArray:["普通员工","超级管理员", "系统管理员", "公司高层","人事管理员", "项目管理员"],
+                roleDescArray:[{label:"普通员工",value:0, desc:"填报日报,参与项目协作"},
+                {label:"系统管理员",value:2, desc:"具有除了创建系统管理员之外的全部功能"},
+                {label:"公司高层",value:3, desc:"查阅项目信息,人员工时和成本情况"},
+                {label:"人事管理员",value:4, desc:"负责组织架构管理,薪资信息维护"},
+                {label:"项目管理员",value:5, desc:"创建和管理项目"}],
                 userSalaryList:[],
                 userSalaryListDialog: false,
                 value:{},
@@ -964,4 +983,8 @@
         margin: 0px;
         background:#f3f3f3;
     }
+    //全局的作用范围
+    .el-tree-node__content {
+        height:36px;
+    }
 </style>

+ 159 - 54
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

@@ -11,19 +11,32 @@
 
         <!--列表-->
         <div>
+
             <el-card class="box-card daily" shadow="never">
                 <div slot="header" class="clearfix" id="clearfix" style="padding-left: 260px;">
                     <div class="jjk" style="display:inline-block;position:fixed;top:70px;background:#fff;left:250px;">
-                        <el-date-picker size="small" v-model="date" :editable="false" format="yyyy-MM" value-format="yyyy-MM" @change="changeMonthOut" :clearable="false" type="month" placeholder="选择月份"></el-date-picker>
-                        <span>日期:</span>
+                        <el-date-picker size="small" v-model="date" :editable="false" format="yyyy-MM" value-format="yyyy-MM" style="width:190px;"
+                         @change="changeMonthOut" :clearable="false" type="month" placeholder="选择月份"></el-date-picker>
+                        <!-- <span>日期:</span> -->
                     </div>
                         <span v-for="(item,index) in allDate" :id="'day'+index" :class="index==choseDay?'chooseDate date_item':'date_item'" 
                         @click="choseDate(index, item)" :key="index">{{item}}</span>
+
+            <!-- <el-card class="box-card daily" shadow="never" >
+                <div slot="header" class="clearfix" @mousewheel="wheel" id="dateScroll">
+                    <el-date-picker size="small" v-model="date" :editable="false" format="yyyy-MM" style="width:187px;"
+                    value-format="yyyy-MM" @change="changeMonthOut" :clearable="false" type="month" placeholder="选择月份"></el-date-picker>
+                    <span >
+                    <span style="color:#999;">日期:</span>
+                    <span v-for="(item,index) in allDate" :id="'day'+index" :class="index==choseDay?'chooseDate date_item':'date_item'" 
+                        @click="choseDate(index, item)" :key="index">{{item}}</span>
+                    </span> -->
+
                 </div>
                 <div style="display:flex;">
-                <div v-if="user.role > 0 || user.manageDeptId != 0">
-                    <div>
-                        <el-select v-model="selectState" size="small" @change="stateChange">
+                <div v-if="user.role > 0 || user.manageDeptId != 0" >
+                    <div style="width:190px;">
+                        <el-select v-model="selectState" size="small" @change="stateChange" >
                         <el-option value="-1" label="全部状态" >全部状态</el-option>
                         <el-option value="-2" label="未填报">未填报</el-option>
                         <el-option value="1" label="已通过">已通过</el-option>
@@ -60,19 +73,19 @@
                 
                 <div :style="'height:'+tableHeight+'px;width:0.5px;background:#eee;margin-right:10px;margin-left:10px;'" ></div>
                 <div class="allDaily" style="float:left;flex-grow:1">
-                    <!--系统管理员 -->
-                    <div class="report_title" v-if="user.role > 0 || user.manageDeptId > 0">
+                    <!--系统管理员和部门负责人 -->
+                    <div class="report_title" v-if="user.role == 1 || user.role == 2 || user.manageDeptId > 0">
                         <span>工作日报 | {{depData.label}}</span> - 已填写<span style="margin-left:5px;margin-right:5px;color:green;">{{reportList.length}}</span>人,
                     未填写<span style="margin-left:5px;margin-right:5px;color:red;">{{(depData == null?data[0].membCount:(depData.isUser == 1?1:depData.membCount))-reportList.length}}</span>人
                         <span style="float:right;">
                             <el-link type="primary" style="margin-right:10px;" :underline="false" @click="fillInReport(-1)">填写日报</el-link>
-                            <el-link type="primary" style="margin-right:10px;" :underline="false" @click="exportReport">导出日报</el-link>
-                            <el-link type="primary" style="margin-right:10px;" :underline="false" @click="batchApprove">批量审核</el-link>
+                            <el-link type="primary" style="margin-right:10px;" :underline="false" @click="showExportDialog">导出日报</el-link>
+                            <el-link type="primary" style="margin-right:10px;" :underline="false" @click="batchApprove" >批量审核</el-link>
                         </span>
                     </div>
                     <!--普通员工,含项目经理 -->
-                    <div class="report_title" v-if="user.role==0"><span>日报列表</span>
-                    <span style="float:right;" v-if="user.role==0">
+                    <div class="report_title" v-if="(user.role==0||user.role==5) && user.manageDeptId == 0"><span>日报列表</span>
+                    <span style="float:right;" v-if="(user.role==0||user.role==5) && user.manageDeptId == 0">
                             <el-link type="primary" style="margin-right:10px;" :underline="false" @click="fillInReport(-1)">填写日报</el-link>
                             <el-link type="primary" v-if="user.leader" style="margin-right:10px;" :underline="false" @click="batchApprove">批量审核</el-link>
                     </span>
@@ -86,16 +99,16 @@
                                     工作总时长:
                                     <!-- <span :style="parseFloat(item1.reportTime)>parseFloat(item1.calculateTime)+0.5?'color:red':''">{{item1.reportTime}}h</span> -->
                                     <span >{{item1.reportTime}}</span>h
-                                    <span v-if="user.role > 0"><span  style="margin-left:10px;">成本:</span>
+                                    <span v-if="user.role >=1 && user.role <=3"><span  style="margin-left:10px;">成本:</span>
                                     <span >{{item1.cost}}</span>元</span>
                                 </span>
                             </span>
                             <div class="checkbtn">
-                                <el-button v-if="(user.role != 0 || user.id == item1.data[0].inchargerId) && item1.state == 0" type="primary" :loading="logining" size="small" @click="approve(item1.id, item1)">通过</el-button>
-                                <el-button v-if="(user.role != 0 || user.id == item1.data[0].inchargerId) && item1.state == 0" type="danger" :loading="logining" size="small" @click="deny(item1.id,0, item1)">驳回</el-button>
+                                <el-button v-if="(user.role == 1 || user.role == 2 || user.id == item1.data[0].inchargerId) && item1.state == 0" type="primary" :loading="logining" size="small" @click="approve(item1.id, item1)">通过</el-button>
+                                <el-button v-if="(user.role == 1 || user.role == 2 || user.id == item1.data[0].inchargerId) && item1.state == 0" type="danger" :loading="logining" size="small" @click="deny(item1.id,0, item1)">驳回</el-button>
                                 <!--自己可以撤回待审核状态的报告 -->
                                 <el-button v-if="(user.id == item1.id) && item1.state == 0" type="normal" :loading="logining" size="small" @click="cancel(item1)">撤回</el-button>
-                                <el-button v-if="(user.role != 0 || user.id == item1.data[0].inchargerId) && item1.state == 1" type="normal" :loading="logining" size="small" @click="deny(item1.id,1, item1)">撤销</el-button>
+                                <el-button v-if="(user.role == 1 || user.role == 2 || user.id == item1.data[0].inchargerId) && item1.state == 1" type="normal" :loading="logining" size="small" @click="deny(item1.id,1, item1)">撤销</el-button>
                                 <el-button v-if="item1.state >= 2 && user.id == item1.id" type="primary" size="small" @click="fillInReport(index1)">编辑日报</el-button>
                             </div>
                             <div class="one_daily_body">
@@ -133,13 +146,16 @@
         </div>
 
         <!-- 填写日报的dialog -->
-        <el-dialog title="填写日报" :visible.sync="dialogVisible" width="60%">
+        <el-dialog title="填写日报" :visible.sync="dialogVisible" width="60%" :close-on-click-modal="false">
             <el-form ref="workForm" :model="workForm" :rules="workRules" label-width="100px">
                 <el-form-item label="工作日期" prop="createDate">
                     <el-date-picker v-model="workForm.createDate" :editable="false" format="yyyy-MM-dd" value-format="yyyy-MM-dd" 
                     @change="changeMonth()" :clearable="false" type="date" placeholder="选择工作日期" :disabled="isDisable"></el-date-picker>
-
-                    <span v-if="reportTimeType.type == 3" style="margin-left:30px;" >总时长: {{reportTimeType.allday.toFixed(1)}}小时</span>
+                    <span v-if="reportTimeType.type == 3" style="margin-left:30px;">总时长:</span>
+                    <el-input-number :disabled="!canEdit" v-if="reportTimeType.type == 3" style="margin-left:10px;" @change="changeAllTime"
+                        v-model="reportTimeType.allday" :precision="1" :step="0.5" :max="12" :min="0.5"></el-input-number>
+                    <span v-if="reportTimeType.type == 3">小时</span>
+                    <!-- <span v-if="reportTimeType.type == 3" style="margin-left:30px;" >总时长: {{reportTimeType.allday.toFixed(1)}}小时</span> -->
                 </el-form-item>
                 
                 <div v-for="(domain, index) in workForm.domains" :key="domain.id">
@@ -193,7 +209,7 @@
                             }">
                         </el-time-picker>
                         </span>
-                        <div class="overtime"><el-checkbox v-model="domain.isOvertime">加班</el-checkbox></div>
+                        <div class="overtime"><el-checkbox :disabled="!canEdit" v-model="domain.isOvertime">加班</el-checkbox></div>
                     </el-form-item>
                     
                     <el-form-item label="投入项目" :prop="'domains.' + index + '.projectId'"
@@ -215,11 +231,11 @@
 
                     <el-form-item v-if="reportTimeType.type == 3" label="用时占比" :prop="'domains.' + index + '.'+timeFields[reportTimeType.type]"
                         :rules="{ required: true, message: '请选择工作时长', trigger: 'blur' }">
-                        <div style="width:250px;">
-                            <el-col span="14"><el-slider v-model="domain.progress" :min="10" :show-tooltip="false" :step="10" style="width:136px;" @change="domain.workingTime = (reportTimeType.allday*domain.progress/100).toFixed(1)"></el-slider></el-col>
+                        <div style="width:300px;">
+                            <el-col span="14"><el-slider :disabled="!canEdit" v-model="domain.progress" :min="10" :show-tooltip="false" :step="10" style="width:180px;" @change="domain.workingTime = (reportTimeType.allday*domain.progress/100).toFixed(1)"></el-slider></el-col>
                             <el-col span="10"><span style="margin-left:10px;float:right;"><span style="margin-right:10px;">{{domain.progress}}%</span>{{domain.workingTime}}小时</span></el-col>
                         </div>
-                        <div class="overtime"><el-checkbox v-model="domain.isOvertime">加班</el-checkbox></div>
+                        <div class="overtime"><el-checkbox :disabled="!canEdit" v-model="domain.isOvertime">加班</el-checkbox></div>
                     </el-form-item>
 
                     <!--项目管理专业版模式下,项目下的近期执行的任务 -->
@@ -233,9 +249,9 @@
                         <el-input v-model="domain.content" type="textarea" :rows="4" placeholder="请填写工作事项" clearable
                          :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)"></el-input>
                     </el-form-item>
-                    <el-divider v-if="workForm.domains.length>1"></el-divider>
+                    <el-divider v-if="workForm.domains.length>1" style="margin-bottom:10px;"></el-divider>
                 </div>
-                <el-link v-if="showAddMore" type="primary" :underline="false" @click="addDomain" style="margin-left:40px">添加更多</el-link>
+                <el-link v-if="showAddMore"  :disabled="!canEdit" type="primary" :underline="false" @click="addDomain" style="margin-left:40px">添加更多</el-link>
             </el-form>
             <span slot="footer" class="dialog-footer">
                 <el-button @click="deleteReport" v-if="workForm.domains[0].id != null">删除</el-button>
@@ -246,7 +262,7 @@
         </el-dialog>
 
         <!-- 批量日报审核 -->
-        <el-dialog title="批量日报审核" :visible.sync="approveDialogVisible" width="500px">
+        <el-dialog title="批量日报审核" :visible.sync="approveDialogVisible" width="500px" >
             <el-checkbox v-model="isAllSelect" label="全选" style="margin-left:24px;" @change="selectAll" v-if="reportNames.length > 0"></el-checkbox>
             <el-tree ref="approveTree" node-key="id" :data="reportNames" show-checkbox="true" @check-change="handleCheckChange" >
             </el-tree>
@@ -255,7 +271,31 @@
                 <el-button type="primary" @click="submitBatchApprove" :disabled="batchShowData.length == 0">审核通过</el-button>
             </span>
         </el-dialog>
-
+        <!--导出报表条件选择 -->
+        <el-dialog title="日报导出" v-if="exportDialog" :visible.sync="exportDialog" customClass="customWidth" width="500px">
+            <el-form ref="form3" :model="exportParam" >
+                <el-form-item prop="projectId" label="选择项目">
+                    <el-select v-model="exportParam.projectId" placeholder="全部项目"  clearable style="width:350px;">
+                        <el-option v-for="item in projectList"  :key="item.id" :label="item.projectName" :value="item.id"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item prop="projectId" label="日期范围">
+                    <el-date-picker
+                        v-model="exportParam.dateRange" :editable="false" 
+                        format="yyyy-MM-dd" value-format="yyyy-MM-dd" 
+                        :clearable="true" 
+                        range-separator="至"
+                        type="daterange" 
+                        start-placeholder="开始日期"
+                        end-placeholder="结束日期"
+                    ></el-date-picker>
+                </el-form-item>
+                
+            </el-form>
+            <div slot="footer" class="dialog-footer">
+                <el-button type="primary" @click="exportReport" style="width:100%;" >导出</el-button>
+            </div>
+        </el-dialog>
     </section>
 </template>
 
@@ -265,6 +305,8 @@
     export default {
         data() {
             return {
+                exportParam:{projectId: null, dateRange:[]},
+                exportDialog:false,
                 timeFields:['timeType', 'workingTime', 'startTime', 'progress'],
                 subProjectList:[],
                 canEdit: true,
@@ -342,6 +384,7 @@
             };
         },
         methods: {
+
             scrollFunction () {
                 this.domObj = document.getElementById('clearfix') // 通过id获取要设置的div
                 if (this.domObj.attachEvent) { // IE
@@ -362,6 +405,28 @@
                 this.domObj.scrollLeft = this.domObj.scrollLeft + step
             },
 
+            // //左右滚动
+            // wheel(e){
+            //     var a = document.getElementById("dateScroll");
+            //     var scroll_width = 80; //滚动一下的距离
+            //     var e = e || window.event, v;
+            //     e.wheelDelta ? v=e.wheelDelta : v=e.detail;
+            //     if(v>3||-v>3) v=-v;
+            //     v>0 ? a.scrollLeft+=scroll_width : a.scrollLeft-=scroll_width;
+                
+            //     e.preventDefault(); //阻止浏览器的默认滚动
+            // },
+
+            showExportDialog() {
+                this.exportDialog = true;
+            },
+            changeAllTime() {
+                //总时长发生改变,自动按比例计算
+                this.workForm.domains.forEach(d=>{
+                    d.workingTime = (d.progress*this.reportTimeType.allday/100).toFixed(1);
+                });
+            },
+
             // 是否加班的单机事件
             check() {
                 this.selected = !this.selected
@@ -765,6 +830,7 @@
             // 改变月份
             changeMonthOut() {
                 console.log(sessionStorage.msg)
+
                 this.getAllDate();
                 this.getReportList();
                 this.getDepartment();
@@ -784,6 +850,7 @@
             getAllDate() {
                 var dayArry = [];
                 var day = this.getCountDays();
+                let curMonthDay = null;
                 for (var k = 1; k <= day; k++) {
                     var str = new Date(this.date.replace(/-/g, "/")).getMonth() + 1 + "月" + k + "日";
                     if ( new Date(this.date.replace(/-/g, "/")).getFullYear() == new Date(new Date()).getFullYear() &&
@@ -791,20 +858,36 @@
                         if(sessionStorage.msg) {
                             if(parseInt(sessionStorage.msg.split("-")[2]) == k) {
                                 this.choseDay = k - 1;
+                                curMonthDay = str;
                             }
                         } else {
                             if (new Date().getDate() == k) {
                                 this.choseDay = k - 1;
                             }   
                         }
+                         
                     } else {
                         this.choseDay = 0;
                     }
                     dayArry.push(str);
                 }
                 this.allDate = dayArry;
-                if (sessionStorage.msg) {
+                //不能超过最大日期
+                if (this.choseDay > day-1) {
+                    this.choseDay = day-1;
+                }
+                //从消息点击跳转过来的,直接加载指定日期
+                if (sessionStorage.from == 1 && sessionStorage.msg) {
+                    console.log('sssss');
                     this.curDate = sessionStorage.msg;
+                    sessionStorage.from = 0;
+                } else {
+                    if (curMonthDay != null) {
+                        this.curDate = curMonthDay;
+                    } else {
+                        var d = new Date(this.date.replace(/-/g, "/"))
+                        this.curDate = (d.getMonth()+1)+'月'+d.getDate()+'日';  
+                    }
                 }
             },
 
@@ -853,35 +936,34 @@
 
             //导出日报
             exportReport() {
-                if (this.reportList.length > 0) {
-                    this.listLoading = true;
-                    //首先处理日期
-                    let day = this.choseDay > 9 ? "-" + (this.choseDay + 1) : "-0" + (this.choseDay + 1);
-                    this.http.post( this.port.report.export, { date: this.date + day },
-                    res => {
-                        this.listLoading = false;
-                        if (res.code == "ok") {
-                            location.href = res.data;
-                        } else {
-                            this.$message({
-                                message: res.msg,
-                                type: "error"
-                            });
-                        }
-                    },
-                    error => {
-                        this.listLoading = false;
+                this.listLoading = true;
+                var param = {};
+                if (this.exportParam.dateRange != null) {
+                    param = {startDate:this.exportParam.dateRange[0], endDate: this.exportParam.dateRange[1]};
+                }
+                if (this.exportParam.projectId != null) {
+                    param.projectId = this.exportParam.projectId;
+                }
+                this.http.post( this.port.report.export, param,
+                res => {
+                    this.listLoading = false;
+                    if (res.code == "ok") {
+                        location.href = res.data;
+                        this.exportDialog = false;
+                    } else {
                         this.$message({
-                            message: error,
+                            message: res.msg,
                             type: "error"
                         });
-                    });
-                } else {
+                    }
+                },
+                error => {
+                    this.listLoading = false;
                     this.$message({
-                        message: "当天没有报告 无法导出",
-                        type: "info"
+                        message: error,
+                        type: "error"
                     });
-                }
+                });
             },
 
             //获取项目列表
@@ -957,7 +1039,7 @@
                                     projectId: "",
                                     workingTime: this.reportTimeType.type==3?(10*this.reportTimeType.allday/100).toFixed(1):"",
                                     content: "",
-                                    progress:10,
+                                    progress:100,
                                     state: 2,
                                     timeType:0,
                                 }],
@@ -994,11 +1076,23 @@
 
             // 添加模块
             addDomain() {
+                var leftProgress = 10;
+                if (this.reportTimeType.type == 3) {
+                    //计算已经待分配工时比例
+                    let array = this.workForm.domains;
+                    let totalProgress = 0;
+                    for (var i=0;i<array.length; i++) {
+                        totalProgress += array[i].progress;
+                    }
+                    if (totalProgress < 100) {
+                        leftProgress = 100 - totalProgress;
+                    }
+                }
                 this.workForm.domains.push({
                         projectId: "",
-                        workingTime: this.reportTimeType.type == 3?(10*this.reportTimeType.allday/100).toFixed(1):"",
+                        workingTime: this.reportTimeType.type == 3?(leftProgress*this.reportTimeType.allday/100).toFixed(1):"",
                         content: "",
-                        progress:10,
+                        progress:leftProgress,
                         state:2,//2-表示待提交
                 });
                 
@@ -1087,6 +1181,12 @@
                                         type: "error"
                                     });
                                 return;
+                            } else if (total < 100) {
+                                this.$message({
+                                        message: "工时尚未完全分配,无法提交",
+                                        type: "error"
+                                    });
+                                return;
                             }
                         }
                         
@@ -1300,6 +1400,10 @@
 
         },
         mounted() {
+            var now = new Date();
+            var t = util.formatDate.format(now, 'yyyy-MM-dd');
+            var startStr = util.formatDate.format(new Date(), 'yyyy-MM') + "-01";
+            this.exportParam.dateRange = [startStr,t];
             this.getAllDate();
             this.getReportList();
             this.getProjectList();
@@ -1316,6 +1420,7 @@
     }
     .report_title {
         padding:10px 0;
+        color:#666;
     }
     .clearfix {
         overflow-x: auto;

+ 2 - 2
fhKeeper/formulahousekeeper/timesheet_h5/src/main.js

@@ -13,12 +13,12 @@ import "@/components/Vant";
 
 import { Form , Toast , Grid, GridItem , DatetimePicker ,
 Picker , Dialog , NumberKeyboard , Sticky , Skeleton ,
-Panel , Divider , List , pullRefresh , SwipeCell, Checkbox, Search, Slider } from 'vant';
+Panel , Divider , List , pullRefresh , SwipeCell, Checkbox, Search, Slider,Stepper,Tag } from 'vant';
 
 Vue.use(Form).use(Toast).use(Grid).use(GridItem).use(DatetimePicker)
 .use(Picker).use(Dialog).use(NumberKeyboard).use(Sticky).use(Skeleton)
 .use(Panel).use(Divider).use(List).use(pullRefresh).use(SwipeCell)
-.use(Checkbox).use(Search).use(Slider);
+.use(Checkbox).use(Search).use(Slider).use(Stepper).use(Tag);
 
 // rem
 import "amfe-flexible";

+ 130 - 27
fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/index.vue

@@ -8,19 +8,31 @@
             <van-popup v-model="showPicker" position="bottom">
                 <van-datetime-picker v-model="currentDate" type="date" :min-date="minDate" :max-date="maxDate" @confirm="changeTime" @cancel="showPicker = false"/>
             </van-popup>
-            <van-cell title="总时长" v-if="reportTimeType.type == 3" :value="reportTimeType.allday.toFixed(1)+'小时'" ></van-cell>
+            <van-cell title="总时长(h)" v-if="reportTimeType.type == 3">
+                <template>
+                    <van-stepper :disabled="!canEdit" v-model="reportTimeType.allday" @change="changeAllTime" min="0.5" max="12" step="0.5" :decimal-length="1" />
+                </template>
+            </van-cell>
+            
             <!-- <van-cell title="待分配时长" :value="report.time + 'h'" size="large"></van-cell> -->
 
             <div class="form_domains" v-for="(item,index) in form.domains" :key="item.id">
-                <van-button v-if="index == 0" :disabled="!canEdit" @click="addNewPro" class="form_addNew" icon="plus" type="info" size="mini">新增项目</van-button>
+                <van-tag v-if="index == 0 && canEdit" 
+                :disabled="!canEdit" @click="addNewPro" 
+                class="form_addNew" icon="plus" type="primary" >+ 新增项目</van-tag>
                 <van-icon v-if="index>0&&canEdit" class="form_del" name="delete" @click="delPro(index)" />
 
                 <van-cell-group :title="'项目' + (index+1)">
-                    <van-field readonly clickable name="projectId" :value="item.projectName" label="投入项目" placeholder="请选择投入项目" @click="clickPicker(index)"
+                    <van-field  readonly  name="projectId" clickable :value="item.projectName" label="投入项目" placeholder="请选择投入项目" @click="clickPicker(index)"
                     :rules="[{ required: true, message: '请选择投入项目' }]"/>
                     <van-popup v-model="showPickerProject" position="bottom">
                         <van-picker show-toolbar :columns="project" value-key="projectName" @confirm="choseProject" @cancel="showPickerProject = false" />
                     </van-popup>
+                    <van-field v-if="user.company.packageProject == 1"  readonly name="taskId" :value="item.taskName" label="关联任务" placeholder="请选择关联任务" @click="clickPickerTask(index)"
+                    />
+                    <van-popup v-model="showPickerTask" position="bottom">
+                        <van-picker show-toolbar :columns="item.taskList" value-key="taskName" @confirm="choseTask" @cancel="showPickerTask = false" />
+                    </van-popup>
                     <!-- <van-field readonly clickable class="form_input" :value="item.workingTime" name="workingTime" label="工作时长" placeholder="请输入工作时长(单位:小时)"
                     :rules="[{ required: true, message: '请输入工作时长(单位:小时)' }]" @touchstart.native.stop="showNumberKey = true"/>
                     <van-number-keyboard v-model="item.workingTime" :show="showNumberKey" close-button-text="完成" extra-key="." :maxlength="4" @blur="showNumberKey = false" /> -->
@@ -40,7 +52,7 @@
 
                     <!-- 时间段选择模式 -->
                     <van-field readonly v-if="reportTimeType.type == 2" clickable name="datetimePicker" :value="item.startTime" label="开始时间" placeholder="点击选择时间" 
-                        @click="showStartTime = true" />
+                        @click="canEdit?showStartTime = true:''" :disabled="!canEdit"  />
                     <van-popup v-model="showStartTime" position="bottom">
                         <van-datetime-picker
                         v-model="startTime"
@@ -53,7 +65,7 @@
                         <!-- :filter="filter" 原本这个属性在里面 -->
                     </van-popup>
                     <van-field v-if="reportTimeType.type == 2" readonly clickable name="datetimePicker" :value="item.endTime" label="结束时间" placeholder="点击选择时间" 
-                        @click="showEndTime = true" />
+                        @click="canEdit?showEndTime = true:''" :disabled="!canEdit" />
                     <van-popup v-model="showEndTime" position="bottom" >
                         <van-datetime-picker
                         v-model="endTime"
@@ -61,7 +73,7 @@
                         :min-hour="8"
                         :max-hour="23"
                         @confirm="confirmTime(item,1)"
-                        @cancel="showEndTime = false"
+                        @cancel="showEndTime = false" 
                         />
                         <!-- :filter="filter" 原本这个属性在里面 -->
                     </van-popup>
@@ -69,7 +81,7 @@
                         <template >
                             <div>
                         <span>用时占比</span>
-                        <van-slider :disabled="!canEdit" :min="10" :step="10" style="width:120px;display:inline-block;margin-left:50px;" v-model="item.progress" @change="item.workingTime = (reportTimeType.allday*item.progress/100).toFixed(1)" >
+                        <van-slider :disabled="!canEdit" :min="10" :step="10" style="width:120px;display:inline-block;margin-left:50px;" v-model="item.progress" :value="100" @change="item.workingTime = (reportTimeType.allday*item.progress/100).toFixed(1)" >
                         <template #button>
                             <div class="custom-button">{{ item.progress }}%</div>
                         </template>
@@ -78,7 +90,7 @@
                             </div>
                         </template>
                     </van-cell>
-                    <van-field class="form_input" 
+                    <van-field class="form_input" :disabled = "!canEdit"
                     v-model="item.content" name="content" type="textarea" label="工作事项" placeholder="请输入工作事项" 
                     rows="3" autosize  />
                     <!-- 单选按钮 -->
@@ -87,12 +99,13 @@
                         <van-radio name="1">加班</van-radio>
                     </van-radio-group> -->
                     <div class="overtime">
-                        <van-checkbox v-model="item.isOvertime">加班</van-checkbox>
+                        <van-checkbox :disabled="!canEdit" v-model="item.isOvertime">加班</van-checkbox>
                     </div>
                 </van-cell-group>
             </div>
             <div class="form_btn" style="margin: 16px;">
                 <van-button v-if="canEdit" round block type="info" native-type="submit"> 提交 </van-button>
+                <p v-if="canEdit&&form.domains.length>0 && form.domains[0].id != null" round block type="default" style="padding-top:30px;font-size:15px;color:#999;margin:0 auto;text-align:center;" @click="deleteReport"> 删除 </p>
             </div>
         </van-form>
         <div style="padding:15px;">
@@ -107,6 +120,8 @@
     export default {
         data() {
             return {
+
+                showPickerTask:false,
                 canCancel:false,
                 canEdit:false,
                 showEndTime: false,
@@ -120,7 +135,7 @@
                 reportTimeType:{},
                 user: JSON.parse(localStorage.userInfo),
                 minDate: new Date(2010, 0, 1),
-                maxDate: new Date(new Date().getFullYear(),new Date().getMonth(),new Date().getDate()),
+                maxDate: new Date(new Date().getFullYear(),new Date().getMonth(),new Date().getDate()+7),
                 currentDate: new Date(),
                 showPickerTime: false,
                 showPicker: false,
@@ -157,6 +172,35 @@
         },
 
         methods: {
+            //删除日报
+            deleteReport() {
+                this.$dialog.confirm({
+                    title: '删除日报',
+                    message: '确定要删除当天日报吗?'
+                }).then(() => {
+                    const toast = this.$toast.loading({
+                        forbidClick: true,
+                        duration: 0
+                    });
+                    this.$axios.post("/report/delete", {userId: this.user.id, date:this.form.createDate})
+                    .then(res => {
+                        if(res.code == "ok") {
+                            toast.clear();
+                            this.$toast.success('删除成功');
+                            window.location.reload();
+                        } else {
+                            toast.clear();
+                            this.$toast.fail('删除失败');
+                        }
+                    }).catch(err=> {toast.clear();});
+                }).catch(() => {});
+            },
+            changeAllTime() {
+                //总时长发生改变,自动按比例计算
+                this.form.domains.forEach(d=>{
+                    d.workingTime = (d.progress*this.reportTimeType.allday/100).toFixed(1);
+                });
+            },
             cancel() {
                 const toast = this.$toast.loading({
                     forbidClick: true,
@@ -214,6 +258,9 @@
       
             },
             clickTimePicker(i) {
+                if (!this.canEdit) {
+                    return;
+                }
                 this.clickTimeIndex = i;
                 
                 if (this.reportTimeType.type == 0) {
@@ -284,6 +331,11 @@
                     if(res.code == "ok") {
                         toast.clear();
                         this.project = res.data;
+                        
+                        // if (this.project.length > 0) {
+                        //     console.log('this.project[0].id=='+this.project[0].id);
+                        //     this.getTaskList(this.project[0].id);
+                        // }
                     } else {
                         toast.clear();
                         this.$toast.fail('获取失败');
@@ -321,13 +373,19 @@
                             let array = [];
                             for(var i in list) {
                                 var projectName = "";
-                                var flg = null
-                                list[i].isOvertime == 1 ? flg = true : flg = false
+                                var flg = (list[i].isOvertime == 1);
                                 for(var j in this.project) {
                                     if(this.project[j].id == list[i].projectId) {
                                         projectName = this.project[j].projectName;
                                     }
                                 }
+                                let tname = '';
+                                if (list[i].taskId != null && list[i].taskList.length > 0) {
+                                    let filterList = list[i].taskList.filter(t=>t.taskId == list[i].taskId);
+                                    if (filterList.length > 0) {
+                                        tname = filterList[0].taskName;
+                                    }
+                                } 
                                 array.push({
                                     id: list[i].id,
                                     projectId: list[i].projectId,
@@ -341,6 +399,9 @@
                                     endTime: list[i].endTime,
                                     isOvertime: flg,
                                     progress: list[i].progress,
+                                    taskList: list[i].taskList,
+                                    taskId: list[i].taskId,
+                                    taskName:tname,
                                 })
                                 if (list[i].state >= 2) {
                                     this.canEdit = true;
@@ -357,12 +418,12 @@
                                 id: null,
                                 projectId: "",
                                 projectName: "",
-                                workingTime: this.reportTimeType.type==3?(this.reportTimeType.allday*10/100).toFixed(1):"",
+                                workingTime: t.type==3?(t.allday).toFixed(1):"",
                                 content: "",
                                 state: 2,
-                                progress:10,
+                                progress:100,
+                                isOvertime:false,
                             }]
-                            
                             this.canEdit = true;
                         }
                     } else {
@@ -382,26 +443,70 @@
 
             // 选择项目
             clickPicker(i) {
+                if (!this.canEdit) return;
                 this.clickIndex = i;
                 this.showPickerProject = true;
             },
+            //选择任务
+            clickPickerTask(i) {
+                if (!this.canEdit) return;
+                this.clickIndex = i;
+                this.showPickerTask = true;
+            },
+            choseTask(value, index) {
+                this.form.domains[this.clickIndex].taskId = value.taskId;
+                this.form.domains[this.clickIndex].taskName = value.taskName;
+                this.showPickerTask = false;
+                
+            },
 
             choseProject(value, index) {
                 this.form.domains[this.clickIndex].projectId = value.id;
                 this.form.domains[this.clickIndex].projectName = value.projectName;
                 this.showPickerProject = false;
+                this.getTaskList(value.id);
+            },
+
+            getTaskList(projectId) {
+                console.log('==============='+projectId);
+                //如果是专业版,需要列出任务列表
+                if (this.user.company.packageProject == 1) {
+                    this.$axios.post("/task/getRecentTask", {projectId: projectId})
+                        .then(res => {
+                            if(res.code == "ok") {
+                                this.form.domains[this.clickIndex].taskList = res.data;
+                                this.$forceUpdate();
+                            } else {
+                                this.$toast.fail('获取失败');
+                            }
+                        }).catch(err=> {toast.clear();});
+                }
             },
 
             // 添加项目 
             addNewPro() {
+                var leftProgress = 10;
+                if (this.reportTimeType.type == 3) {
+                    //计算已经待分配工时比例
+                    let array = this.form.domains;
+                    let totalProgress = 0;
+                    for (var i=0;i<array.length; i++) {
+                        totalProgress += array[i].progress;
+                    }
+                    if (totalProgress < 100) {
+                        leftProgress = 100 - totalProgress;
+                    }
+                }
+
                 this.form.domains.push({
                     id: null,
                     projectId: "",
                     projectName: "",
-                    workingTime: this.reportTimeType.type==3?(10*this.reportTimeType.allday/100).toFixed(1):"",
-                    progress:10,
+                    workingTime: this.reportTimeType.type==3?(leftProgress*this.reportTimeType.allday/100).toFixed(1):"",
+                    progress:leftProgress,
                     content: "",
                     state: 2,
+                    isOvertime:false,
                 })
             },
 
@@ -460,6 +565,9 @@
                     if (total > 100) {
                         this.$toast.fail("用时比例之和不能超过100%");
                         return;
+                    } else if (total < 100) {
+                        this.$toast.fail("工时尚未完全分配,无法提交");
+                        return;
                     }
                 }
                 
@@ -495,18 +603,13 @@
                     } else {
                         formData.append("content", this.form.domains[i].content);
                     }
-                    formData.append("createDate", this.form.createDate);
-
-                    if(this.form.domains[i].isOvertime == undefined ) {
-                        this.form.domains[i].isOvertime = '0'
-                        formData.append("isOvertime", this.form.domains[i].isOvertime);
-                    } else if (this.form.domains[i].isOvertime == false){
-                        this.form.domains[i].isOvertime = '0'
-                        formData.append("isOvertime", this.form.domains[i].isOvertime);
+                    if (this.form.domains[i].taskId == null) {
+                        formData.append("taskId", 0);
                     } else {
-                        this.form.domains[i].isOvertime = '1'
-                        formData.append("isOvertime", this.form.domains[i].isOvertime);
+                        formData.append("taskId", this.form.domains[i].taskId);
                     }
+                    formData.append("createDate", this.form.createDate);
+                    formData.append("isOvertime", this.form.domains[i].isOvertime?1:0);
                 }
                 this.$axios.post("/report/editReport", formData)
                 .then(res => {

+ 51 - 0
fhKeeper/formulahousekeeper/timesheet_h5/src/views/index/index.vue

@@ -89,6 +89,57 @@
             }
 
             this.getMessage();
+
+            let href = window.location.href;
+            if (this.user.wxOpenid == null || this.user.wxOpenid == undefined || this.user.wxOpenid == 'undefined') {
+                // localStorage.openId = 'o1L3L5lOrOl3_UEJjONaoT2Rne1I';
+                //会自动跳转到首页
+                // let href = 'http://hq.tangusoft.com/?code=011Ptjgc2rx1eI09Irgc2Rvsgc2PtjgF&state=1#/index';
+                
+                if (href.includes("com/?code")) {  //url包括 com/?code 证明为从微信跳转回来的
+                    var url = href; //vue自动在末尾加了 #/ 符号,截取去掉
+                    var jingPosit = url.indexOf("com/") + 4; //获取域名结束的位置
+
+                    // var urlLeft = url.substring(0, jingPosit);//url左侧部分
+                    var urlRight = url.substring(jingPosit, url.length); //url右侧部分
+                    console.log('urlRight=' + urlRight);
+                    // window.location = urlLeft + "#/home" + urlRight;//拼接跳转
+                    //获取code
+                    var code = urlRight.substring('?code='.length,urlRight.indexOf('#/index'));
+                    if (code.indexOf('&state=1') > 0) {
+                        code = code.substring(0, code.indexOf('&state=1'));
+                    }
+
+                    //调用后台接口,注册用户
+                    console.log('获取到code=='+code);
+
+                    this.$axios.get("/wechat/bindWeiXin", {params:{code:code, userId: this.user.id}})
+                        .then(res => {
+                            console.log(res);
+                            if (res == null) {
+                                this.$toast.fail('绑定失败');
+                            } else if(res.errcode != null) {
+                                //报错了
+                                console.log(res.errmsg);
+                            } else {
+                                //获取openId
+                                if (res.data != null && res.data.wxOpenid != undefined) {
+                                    localStorage.userInfo = JSON.stringify(res.data);
+                                    console.log('绑定成功');
+                                    this.user = res.data;
+                                    window.location.href = '/#/my/center';
+                                    // if (sessionStorage.prePage != null) {
+                                    //     window.location.href = '/#'+sessionStorage.prePage;
+                                    // }
+                                }
+                            }
+                        }).catch(err=> {
+                            alert('err=' + err);
+                        });
+                }
+            } else {
+                
+            }
         },
         components: {
             Footer

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

@@ -16,6 +16,12 @@
                 <van-cell title="公司" :title-style="'flex: 0.5;'" :value="userInfo.companyName"></van-cell>
                 <van-cell title="修改密码" isLink to="/my/set"></van-cell>
             </div>
+            <van-cell title="绑定微信" @click="bindWeiXin" style="margin-top:10px;" :title-style="'flex: 2.5;'" label="绑定微信后可接收工时填报提醒">
+                <template>
+                    <span v-if="userInfo.wxOpenid == null" style="color:#ff0000;">未绑定</span>
+                    <span v-if="userInfo.wxOpenid != null" style="color:#7CCD7C;">已绑定</span>
+                </template>
+            </van-cell>
             <van-button class="logout" @click="logout" block round type="danger" >退出登录</van-button>
         </main>
 
@@ -46,11 +52,28 @@
                 this.$store.commit("updateLogin", false);
                 localStorage.removeItem("userInfo");
                 this.$router.push("/login");
-            }
+            },
+            bindWeiXin(){
+                if (this.userInfo.wxOpenid != null) {
+                    return;
+                }
+                var url = "http://mobworktime.ttkuaiban.com/";//授权回调页面
+                var appId = "wx749c84daac654e1e";//工时管家公众号
+                var weixinUrl="https://open.weixin.qq.com/connect/oauth2/authorize?appid="+appId+"&redirect_uri="+encodeURI(url)+"&response_type=code&scope=snsapi_base&state=1#wechat_redirect";
+                console.log(weixinUrl);
+                window.location.href = weixinUrl;
+            },
         },
         create() {
+            
         },
         mounted() {
+            // if (localStorage.openId == null || localStorage.openId == undefined || localStorage.openId == 'undefined') {
+            //     localStorage.openId = 'oBCQbt2yf7d-OxFuAF4tTJYbiI1I';//测试账号
+            //     // localStorage.openId = 'osp3lt91BuJ_JkwoqawsCI5b8IZM';//测试账号
+            // }
+            
+            
         }
     };
 </script>

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

@@ -59,7 +59,7 @@
                 userList:[],
                 inchargerUserList:[],
                 show: false,
-                title: "标题",
+                title: "修改项目",
                 form: {
                     id: null,
                     projectName: "",
@@ -150,6 +150,7 @@
                             this.list.push(res.data.records[i])
                         }
                         this.total = res.data.total;
+                        this.page++;
                     } else {
                         this.$toast.fail('获取失败');
                     }
@@ -166,6 +167,7 @@
             // 新增、编辑项目
             openDialog(i) {
                 if(i == -1) {
+                    this.title = "新增项目";
                     this.form = {
                         id: null,
                         projectName: "",
@@ -178,6 +180,7 @@
                     // this.userList.forEach(u=>u.isChecked=false);
                     // this.refreshParticipate();
                 } else {
+                    this.title = "修改项目";
                     this.form = {
                         id: this.list[i].id,
                         projectName: this.list[i].projectName,

+ 4 - 2
fhKeeper/formulahousekeeper/timesheet_h5/src/views/review/index.vue

@@ -9,7 +9,7 @@
             <van-popup v-model="showPicker" position="bottom">
                 <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" :key="index" title avatar :row="3" :loading="false">
+            <van-skeleton  v-for="(item,index) in report" :key="index" title avatar :row="3" :loading="false">
                 <van-panel class="one_report" :title="item.name" :status="item.state==0?'待审核':item.state==1?'已通过':'已驳回'">
                     <div class="form_text">
                         <span style="margin-right:20px;">
@@ -21,6 +21,7 @@
                     </div>
                     <div v-for="(item1,index1) in item.data" :key="index1" class="one_report_data">
                         <div class="project_title">项目:{{item1.project}}</div>
+                        <div class="project_title" v-if="item1.taskId != null" >任务:{{item1.taskName}}</div>
                         <div class="project_time">时长:{{item1.time}}h <span class="one_span" v-if="item1.isOvertime === 1">加班</span></div>
                         <div class="project_content">事项:<span v-html="item1.content"></span></div>
                         <van-divider />
@@ -170,6 +171,7 @@
 
     .one_report {
         margin-bottom: 15px;
+        font-size:14px;
     }
 
     .form_text {
@@ -186,7 +188,7 @@
     }
 
     .one_report_data {
-        margin-bottom: 20px;
+        margin-bottom: 10px;
         padding: 0 22px;
         div {
             line-height: 30px;

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

@@ -22,6 +22,7 @@
                     </div>
                     <div v-for="(item1,index1) in item.data" class="one_report_data" :key="index1">
                         <div class="project_title">项目:{{item1.project}}</div>
+                        <div class="project_title" v-if="item1.taskId != null" >任务:{{item1.taskName}}</div>
                         <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}}h