Explorar o código

Merge branch 'master' of http://47.100.37.243:10080/wutt/manHourHousekeeper

山水共长天一色 %!s(int64=3) %!d(string=hai) anos
pai
achega
b748fd5605

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

@@ -1,10 +1,10 @@
 package com.management.platform.service;
 
-import com.management.platform.entity.WxCorpInfo;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.management.platform.entity.WxCorpInfo;
 import com.management.platform.util.HttpRespMsg;
 
-import java.time.LocalDate;
 import java.time.LocalDateTime;
 
 /**
@@ -19,6 +19,8 @@ public interface WxCorpInfoService extends IService<WxCorpInfo> {
 
     public void sendWXCorpMsg(WxCorpInfo corpInfo, String corpUserid, String msg);
 
+    public void sendWXCorpTemplateMsg(WxCorpInfo corpInfo, String corpUserid, JSONObject msg);
+
     public String downloadFile(WxCorpInfo corpInfo, String mediaId);
 
     public String testDownloadFile();

+ 43 - 3
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/WxCorpInfoServiceImpl.java

@@ -3,6 +3,7 @@ package com.management.platform.service.impl;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.management.platform.controller.WeiXinCorpController;
 import com.management.platform.entity.SysConfig;
 import com.management.platform.entity.User;
@@ -13,7 +14,6 @@ import com.management.platform.mapper.UserCorpwxTimeMapper;
 import com.management.platform.mapper.UserMapper;
 import com.management.platform.mapper.WxCorpInfoMapper;
 import com.management.platform.service.WxCorpInfoService;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.management.platform.util.DateTimeUtil;
 import com.management.platform.util.HttpRespMsg;
 import lombok.extern.slf4j.Slf4j;
@@ -32,8 +32,6 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Collectors;
 
-import static org.mockito.ArgumentMatchers.startsWith;
-
 /**
  * <p>
  *  服务实现类
@@ -115,6 +113,48 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
 
     }
 
+    @Override
+    public void sendWXCorpTemplateMsg(WxCorpInfo corpInfo, String corpUserid, JSONObject msg) {
+        try {
+            log.info("发送企业微信模板消息==="+corpUserid);
+            System.out.println("发送企业微信模板消息==="+corpUserid);
+            String accessToken = getCorpAccessToken(corpInfo);
+            String url = URL_SEND_WXCORP_MSG.replaceAll("ACCESS_TOKEN", accessToken);
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.APPLICATION_JSON);
+            JSONObject reqParam = new JSONObject();
+            reqParam.put("touser",  corpUserid);
+            reqParam.put("toparty", "");
+            reqParam.put("totag",  "");
+            reqParam.put("msgtype",  "template_msg");
+            reqParam.put("agentid",  corpInfo.getAgentid());
+            reqParam.put("template_msg",msg);
+
+            HttpEntity<String> requestEntity = new HttpEntity<String>(reqParam.toJSONString(), headers);
+            ResponseEntity<String> responseEntity = this.restTemplate.exchange(url,
+                    HttpMethod.POST, requestEntity, String.class);
+            if (responseEntity.getStatusCode() == HttpStatus.OK) {
+                String resp = responseEntity.getBody();
+                log.info("发送企业微信模板消息返回结果=="+resp);
+                System.out.println("发送企业微信模板消息返回结果=="+resp);
+                JSONObject json = JSONObject.parseObject(resp);
+                if (json.getIntValue("errcode") == 0) {
+                    //发送成功
+
+                } else {
+                    throw new Exception(json.toJSONString());
+                }
+            } else {
+                log.error("发送失败:"+responseEntity.getStatusCode()+", "+responseEntity.getBody());
+                System.err.println("发送失败:"+responseEntity.getStatusCode()+", "+responseEntity.getBody());
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
     @Override
     public String downloadFile(WxCorpInfo corpInfo, String mediaId) {
         try {

+ 23 - 9
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/TimingTask.java

@@ -1,17 +1,15 @@
 package com.management.platform.task;
 
-import java.text.DecimalFormat;
-import java.time.LocalDate;
-import java.time.Period;
-import java.time.format.DateTimeFormatter;
-
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.management.platform.entity.*;
 import com.management.platform.mapper.*;
 import com.management.platform.service.CompanyDingdingService;
 import com.management.platform.service.DingDingService;
 import com.management.platform.service.WxCorpInfoService;
-import com.management.platform.util.*;
+import com.management.platform.util.RedisUtil;
+import com.management.platform.util.WorkDayCalculateUtils;
 import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
 import me.chanjar.weixin.mp.api.WxMpService;
 import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
@@ -19,14 +17,21 @@ 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.scheduling.annotation.EnableScheduling;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
 
 import javax.annotation.Resource;
+import java.text.DecimalFormat;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
-import java.util.*;
+import java.time.Period;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 /**
@@ -312,7 +317,16 @@ public class TimingTask {
                     if (u.get("corpwxUserid") != null) {
                         //推送到企业微信
                         String corpUid = (String) u.get("corpwxUserid");
-                        wxCorpInfoService.sendWXCorpMsg(cpList.get(0), corpUid, t.getAlertMsg());
+                        JSONObject json=new JSONObject();
+                        JSONArray dataJson=new JSONArray();
+                        JSONObject jsonObj=new JSONObject();
+                        jsonObj.put("key", "提醒");
+                        jsonObj.put("value", StringUtils.isEmpty(t.getAlertMsg())?"":t.getAlertMsg());
+                        dataJson.add(jsonObj);
+                        json.put("template_id","tty9TkCAAAYoevY-40ciWD5lDncDfR5w");
+                        json.put("url", " https://open.weixin.qq.com/connect/oauth2/authorize?appid=ww4e237fd6abb635af&redirect_uri=http://mobworktime.ttkuaiban.com/api/corpWXAuth&response_type=code&scope=snsapi_base&state=0#wechat_redirect");
+                        json.put("content_item",dataJson);
+                        wxCorpInfoService.sendWXCorpTemplateMsg(cpList.get(0), corpUid, json);
                     } else if (u.get("wxOpenid") != null) {
                         push(u, t.getAlertMsg());
                     }

+ 10 - 10
fhKeeper/formulahousekeeper/timesheet/config/index.js

@@ -1,18 +1,18 @@
 var path = require('path')
 
 //  var ip = '127.0.0.1'
-// var ip = '192.168.2.36'
+var ip = '192.168.2.36'
 // var ip = '192.168.2.12'// var ip = '47.100.37.243' 
 
-var os = require('os'), ip = '', ifaces = os.networkInterfaces() // 获取本机ip
-for (var i in ifaces) {
-    for (var j in ifaces[i]) {
-        var val = ifaces[i][j]
-        if (val.family === 'IPv4' && val.address !== '127.0.0.1') {
-            ip = val.address
-        }
-    }
-}
+// var os = require('os'), ip = '', ifaces = os.networkInterfaces() // 获取本机ip
+// for (var i in ifaces) {
+//     for (var j in ifaces[i]) {
+//         var val = ifaces[i][j]
+//         if (val.family === 'IPv4' && val.address !== '127.0.0.1') {
+//             ip = val.address
+//         }
+//     }
+// }
 
 module.exports = {
   build: {

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

@@ -74,6 +74,9 @@ import awayOffice from './views/awayOffice/awayOffice';
 // 角色权限
 import quanx from './views/quanx/quanx'
 
+// 研究中心管理
+import centerManage from './views/centerManage/centerManage'
+
 Vue.use(Router)
 
 export const fixedRouter = [
@@ -310,6 +313,17 @@ export const allRouters = [//组织架构
             { path: '/expense', component: expense, name: '费用报销' }
         ]
     },
+    
+    {
+        path: '/',
+        component: Home,
+        name: '研究中心管理',
+        iconCls: 'iconfont firerock-icondaibanshixiang',
+        leaf: true,//只有一个节点
+        children: [
+            { path: '/centerManage', component: centerManage, name: '研究中心管理' },
+        ]
+    },
     {
         path: '/',
         component: Home,

+ 204 - 0
fhKeeper/formulahousekeeper/timesheet/src/views/centerManage/centerManage.vue

@@ -0,0 +1,204 @@
+<template>
+    <section >
+        <el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
+            <el-form :inline="true">
+                <el-form-item label="研究中心管理">
+                </el-form-item>
+                <el-link icon="el-icon-circle-plus-outline" type="primary" :underline="false" class="tanjia" @click="addNewSubProject()">添加研究中心</el-link>
+            </el-form>
+        </el-col>
+        <el-table :data="subProjectList" highlight-current-row v-loading="listLoading" :height="heightDoms" style="width: 100%;">
+            <el-table-column prop="id" width="200" label="序号" align="center">
+                <template slot-scope="scope" >
+                    {{scope.$index + 1}}
+                </template>
+            </el-table-column>
+            <el-table-column prop="name" label="名称" ></el-table-column>
+            <el-table-column label="操作" width="150">
+                <template slot-scope="scope" >
+                    <el-button size="small" type="primary" @click="addNewSubProject(scope.row)">编辑</el-button>
+                    <el-button size="small" type="danger" @click="deleteSubPro(scope.row)">删除</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+        <el-dialog title="新增/修改维护数据" v-if="addSubProject" :visible.sync="addSubProject" :close-on-click-modal="false" customClass="customWidth" width="500px">
+            <el-form ref="form2" :model="addfm" :rules="ruless" label-width="100px">
+                <el-form-item label="名称" prop="name">
+                    <el-input v-model="addfm.name" placeholder="请输入名称" clearable></el-input>
+                </el-form-item>
+            </el-form>
+            <div slot="footer" class="dialog-footer">
+                <el-button @click.native="addSubProject = false">取消</el-button>
+                <el-button type="primary" @click="submitInsertSubProject" :loading="addLoading">提交</el-button>
+            </div>
+        </el-dialog>
+    </section>
+</template>
+<script>
+    export default {
+        data() {
+            return {
+                subProjectList: [],//子项目列表
+                listLoading: false,
+                addfm: {
+                    name: '',
+                },
+                addSubProject: false,
+                ruless: {
+                    name: [{ required: true, message: "请输入名称", trigger: "blur" }],
+                },
+                heightDoms: document.documentElement.clientHeight - 140,
+            };
+        },
+        methods: {
+            getSub() {
+                this.listLoading = true;
+                this.http.post('/report-extra-degree/getAll ',{},
+                res => {
+                    this.listLoading = false;
+                    if (res.code == "ok") {
+                        console.log(res, '看看')
+                        this.subProjectList = res.data
+                    } else {
+                        this.$message({
+                            message: res.msg,
+                            type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.listLoading = false;
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                    }
+                );
+            },
+            addNewSubProject(subProject) {
+                // console.log(1234)
+                // if (subProject == null) {
+                //     this.addForm = {projectId: this.currentProject.id, level:1}
+                // } 
+                // else {
+                //     this.addForm = subProject;
+                // }
+                if(subProject) {
+                    this.addfm.name = subProject.name
+                    this.addfm.id = subProject.id
+                }
+                this.addSubProject = true;
+            },
+            deleteSubPro(subProject) {
+                this.$confirm("确定要这条" + subProject.name + "数据吗?","删除", {
+                    confirmButtonText: "确定",
+                    cancelButtonText: "取消",
+                    type: "warning"
+                })
+                .then(() => {
+                    this.listLoading = true;
+                    this.http.post('/report-extra-degree/delete',{ 
+                        id: subProject.id 
+                    },
+                    res => {
+                        this.listLoading = false;
+                        if (res.code == "ok") {
+                            this.$message({
+                                message: "删除成功",
+                                type: "success"
+                            });
+                            this.getSub();
+                        } else {
+                            if(res.msg.indexOf("无法删除1") == '-1') {
+                                this.$message({
+                                    message: '该数据正在使用,无法删除',
+                                    type: "error"
+                                });
+                            } else {
+                                this.$message({
+                                    message: res.msg,
+                                    type: "error"
+                                });
+                            }
+                        }
+                    },
+                    error => {
+                        this.listLoading = false;
+                        this.$message({
+                            message: error,
+                            type: "error"
+                        });
+                        }
+                    );
+                })
+                .catch(() => {});
+            },
+            submitInsertSubProject() {
+                this.$refs.form2.validate(valid => {
+                    if (valid) {
+                        var slp = this.addfm
+                        this.http.post('/report-extra-degree/addOrMod',slp,
+                        res => {
+                            this.listLoading = false;
+                            if (res.code == "ok") {
+                                this.$message({
+                                    message: '成功',
+                                    type: "success"
+                                });
+                                this.addfm = {name: ''}
+                                this.addSubProject = false
+                                this.getSub()
+                            } else {
+                                this.$message({
+                                    message: res.msg,
+                                    type: "error"
+                                });
+                            }
+                        },
+                        error => {
+                            this.listLoading = false;
+                            this.$message({
+                                message: error,
+                                type: "error"
+                            });
+                            }
+                        );
+                    }
+                })
+            },
+        },
+        created() {
+            this.getSub()
+        },
+        mounted() {
+
+        }
+    };
+</script>
+
+<style lang="scss" scoped>
+.addNode {
+  cursor:pointer;
+}
+.addNode:hover {
+  color:#20a0ff;
+}
+
+.panel {
+    padding:30px 15px ;box-shadow: 0 2px 4px rgba(3, 3, 3, 0.12), 0 0 6px rgba(0, 0, 0, .04);
+    
+}
+.sample {
+    margin-top:30px;
+    color: #999;
+}
+.tip {
+    margin-left:10px; color:gray;
+    
+}
+.tanjia {
+    float: right;
+    box-sizing: border-box;
+    margin: 10px 28px;
+}
+</style>

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

@@ -298,11 +298,12 @@
                 </div>
               </div>
               <el-table v-if="ins == 6" :key="ins" border :data="overTimeList" highlight-current-row v-loading="listLoading" :height="tableHeight" style="width: 100%;">
+                <el-table-column prop="projectCode" label="项目编号" width="180"></el-table-column> 
                 <el-table-column prop="username" label="姓名" width="180"></el-table-column> 
                 <!-- <el-table-column prop="workingTime" label="加班时长" width="180"></el-table-column>  -->
                 <el-table-column prop="overtimeHours" label="加班时长" width="180"></el-table-column> 
                 <el-table-column prop="cost" label="成本" width="180" v-if="permissions.reportCost"></el-table-column> 
-                <el-table-column prop="cost" label="操作" width="180">
+                <el-table-column label="操作" width="180">
                     <template slot-scope="scope">
                       <div>
                         <el-button icon="el-icon-search" size="mini" circle @click="costBtn(scope.row)"></el-button>
@@ -466,9 +467,11 @@
         </el-dialog>
 
         <!-- 加班详情 -->
-        <el-dialog title="加班详情" :visible.sync="dialogVisibleDetails" width="700px" v-loading="listLoading" :before-close="handleClose">
+        <el-dialog title="加班详情" :visible.sync="dialogVisibleDetails" width="800px" v-loading="listLoading" :before-close="handleClose">
           <div>
              <el-table :data="detailsList" style="width: 100%" height="400px">
+                <el-table-column prop="projectName" label="项目名称" width="200"></el-table-column>
+                <el-table-column prop="projectCode" label="项目编号" width="200"></el-table-column>
                 <el-table-column prop="createDate" label="加班日期" width="120"></el-table-column>
                 <el-table-column prop="workingTime" label="当天工作时长(h)" width="160"></el-table-column>
                 <el-table-column prop="username" label="姓名" width="120"></el-table-column>

+ 51 - 19
fhKeeper/formulahousekeeper/timesheet/src/views/project/projectInside.vue

@@ -270,7 +270,7 @@
                     </el-input>
                 <el-tree :data="deptMembData" show-checkbox :props="defaultProps" node-key="id"
                     ref="chooseMembTree2" @check-change="onTreeItemChange" :default-checked-keys="alreadyPartArray"
-                    highlight-current  :filter-node-method="filterNode"></el-tree>
+                    highlight-current  :filter-node-method="filterNode" default-expand-all></el-tree>
                 </el-scrollbar>
             </div>
             <div>已选中&nbsp;{{chosenMembCount}}&nbsp;人</div>
@@ -725,7 +725,6 @@
                                     <span style="color:#8c8c8c;font-size:12px;" v-for="(s,index) in t.stagesList" :key="s.id">
                                     <i class="el-icon-arrow-right" v-if="index>0"></i>
                                     {{s.stagesName}}</span>
-                                    
                                 </div>
                             </el-col>
                             <el-col :span="2">
@@ -1096,7 +1095,6 @@ import delete$ from 'dingtalk-jsapi/api/biz/cspace/delete';
                 this.ididid = item.id
                 console.log(item);
                 this.participantsDialog = true
-                this.participantsFilterText = ''
                 this.getAlreadyPartArray(item.id)
                 this.getDepartmentList()
                 
@@ -1768,11 +1766,16 @@ import delete$ from 'dingtalk-jsapi/api/biz/cspace/delete';
             },
             // 
             choseTemplate(tIndex) {
-                this.groupTemplateList.forEach(g=>{
-                    g.selected = false;
-                })
+                // this.groupTemplateList.forEach((g)=>{
+                //     g.selected = false;
+                // })
                 this.sidebarIndex = tIndex
-                this.groupTemplateList[tIndex].selected = true;
+                // this.groupTemplateList[tIndex].selected = true;
+                this.groupTemplateList.forEach((g, i)=>{
+                    if(tIndex == i) {
+                        g.selected = !g.selected;
+                    }
+                })
             },
             //获取分组模板列表
             getGroupTemplate() {
@@ -2423,16 +2426,41 @@ import delete$ from 'dingtalk-jsapi/api/biz/cspace/delete';
                 });
             },
             addTemplateGroup() {
-                var param = JSON.parse(JSON.stringify(this.groupTemplateList.filter(g=>g.selected)[0]));
-                delete param.stagesList;
-                param.projectId = this.curProjectId;
-                var k = this.groupTemplateList[this.sidebarIndex].name
-                var s = null;
+                // var param = JSON.parse(JSON.stringify(this.groupTemplateList.filter(g=>g.selected)[0]));
+                // delete param.stagesList;
+                // param.projectId = this.curProjectId;
+                // var k = this.groupTemplateList[this.sidebarIndex].name
+                // var s = null;
+                // var xmz = this.groupList.forEach(function(a, b, c){
+                //     if (a.name == k) {
+                //         s = true
+                //         return
+                //     }
+                // })
+                // if (s){ 
+                //     this.addGroupDialog = false;
+                //     this.$message({
+                //         message: '当前项目已存在分组['+k+'],请修改组名后重试。',
+                //         type: "error"
+                //         });
+                //     return 
+                // }
+                var param = JSON.parse(JSON.stringify(this.groupTemplateList.filter(g=>g.selected)))
+                console.log(param)
+                for(var i in param) {
+                    delete param[i].stagesList
+                }
+                console.log(this.groupList)
+                var s = null
+                var k = ''
                 var xmz = this.groupList.forEach(function(a, b, c){
-                    if (a.name == k) {
-                        s = true
-                        return
-                    }
+                    param.forEach((g, i) =>{
+                        if(a.name == g.name) {
+                            s = true
+                            k = g.name
+                            return
+                        }
+                    })
                 })
                 if (s){ 
                     this.addGroupDialog = false;
@@ -2442,8 +2470,13 @@ import delete$ from 'dingtalk-jsapi/api/biz/cspace/delete';
                         });
                     return 
                 }
-                // 
-                this.http.post('/task-group/createFromTemplate',param,
+                console.log('将要闯过去的值', param)
+                // return
+                // this.http.post('/task-group/createFromTemplate',param,
+                this.http.post('/task-group/createFromTemplate',{
+                    templateJson: JSON.stringify(param),
+                    projectId: this.curProjectId
+                },
                 res => {
                     if (res.code == "ok") {
                         this.selectedGroup = res.data
@@ -2571,7 +2604,6 @@ import delete$ from 'dingtalk-jsapi/api/biz/cspace/delete';
 
             //切换项目
             onProjectChange() {
-                this.groupSearch = null
                 let path = this.$route.path;
                 path = path.substring(0,path.lastIndexOf('/'))+'/'+this.curProjectId;
                 this.$router.push(path);