seyason преди 4 години
родител
ревизия
f365a30865
променени са 36 файла, в които са добавени 1477 реда и са изтрити 179 реда
  1. 2 0
      cloud-model/src/main/java/com/hssx/cloudmodel/constant/Constant.java
  2. 2 2
      cloud-model/src/main/java/com/hssx/cloudmodel/controller/MouldController.java
  3. 9 0
      cloud-model/src/main/java/com/hssx/cloudmodel/controller/UserController.java
  4. 121 3
      cloud-model/src/main/java/com/hssx/cloudmodel/controller/WeiXinCorpController.java
  5. 31 1
      cloud-model/src/main/java/com/hssx/cloudmodel/entity/Mould.java
  6. 16 1
      cloud-model/src/main/java/com/hssx/cloudmodel/entity/User.java
  7. 4 0
      cloud-model/src/main/java/com/hssx/cloudmodel/mapper/UserMapper.java
  8. 1 1
      cloud-model/src/main/java/com/hssx/cloudmodel/service/MouldService.java
  9. 4 0
      cloud-model/src/main/java/com/hssx/cloudmodel/service/UserService.java
  10. 1 1
      cloud-model/src/main/java/com/hssx/cloudmodel/service/impl/MouldEquipmentServiceImpl.java
  11. 57 1
      cloud-model/src/main/java/com/hssx/cloudmodel/service/impl/MouldFileServiceImpl.java
  12. 1 1
      cloud-model/src/main/java/com/hssx/cloudmodel/service/impl/MouldHistoryServiceImpl.java
  13. 32 5
      cloud-model/src/main/java/com/hssx/cloudmodel/service/impl/MouldServiceImpl.java
  14. 12 4
      cloud-model/src/main/java/com/hssx/cloudmodel/service/impl/ProjectFileServiceImpl.java
  15. 21 15
      cloud-model/src/main/java/com/hssx/cloudmodel/service/impl/ProjectServiceImpl.java
  16. 14 1
      cloud-model/src/main/java/com/hssx/cloudmodel/service/impl/UserServiceImpl.java
  17. 1 1
      cloud-model/src/main/java/com/hssx/cloudmodel/util/CodeGenerator.java
  18. 3 0
      cloud-model/src/main/java/com/hssx/cloudmodel/util/GainTokenUtil.java
  19. 103 0
      cloud-model/src/main/java/com/hssx/cloudmodel/util/WechatTemplateUtil.java
  20. 11 4
      cloud-model/src/main/resources/mapper/MouldMapper.xml
  21. 14 5
      cloud-model/src/main/resources/mapper/UserMapper.xml
  22. 255 62
      cloud-socket/src/com/js/kbt/socket/UserHandler.java
  23. 8 0
      ys_int/config/index.js
  24. 6 1
      ys_int/src/i18n/lang/en.js
  25. 8 4
      ys_int/src/i18n/lang/zh.js
  26. 56 4
      ys_int/src/views/Login.vue
  27. 164 2
      ys_int/src/views/base/comp.vue
  28. 166 3
      ys_int/src/views/base/factory.vue
  29. 7 5
      ys_int/src/views/detection/detection.vue
  30. 27 2
      ys_int/src/views/detection/maintenance.vue
  31. 200 21
      ys_int/src/views/mold/moldDetail.vue
  32. 3 3
      ys_int/src/views/mold/moldList.vue
  33. 21 6
      ys_int/src/views/project/competence.vue
  34. 65 10
      ys_int/src/views/project/projectDetail.vue
  35. 15 5
      ys_int/src/views/project/staff.vue
  36. 16 5
      ys_int/src/views/project/staffDetail.vue

+ 2 - 0
cloud-model/src/main/java/com/hssx/cloudmodel/constant/Constant.java

@@ -36,6 +36,8 @@ public class Constant {
     public static final Integer APPROVAL_AUTHORITY = 3;//审批权限
     public static final String WARNING_NOTICE_TEMPLATE_ID = "-EpBbqgMN2cCBf6pUSlFXGNlstkeCidVEejTOhrGcy4";//告警通知模板id
     public static final String MAINTAIN_NOTICE_TEMPLATE_ID = "VcU9E2f3Nn4uR6S1z57VBaLeBAhEO4vfivo3Tug_BKE";//保养通知模板id
+    public static final String AUDIT_SUBMIT_TEMPLATE_ID = "pGyPsy5mywi6E5fkyoO_UUNF_xpTkHhoj8Te5C8COLo";//待审核模板id
+    public static final String AUDIT_RESULT_TEMPLATE_ID = "u-5QdfWpx9YjQp4MlysHtjG9WX77ujVHFWz984uFQzI";//审核结果模板id
     public static final String WECHAT_SECRET = "473ee2fab33e6d8a885800403d777581";//secret
     public static final String WECHAT_APPID = "wx42c0f9d19a4756a7";//appId
     public static final String PLAN_TYPE = "保养类型";//保养类型

+ 2 - 2
cloud-model/src/main/java/com/hssx/cloudmodel/controller/MouldController.java

@@ -304,8 +304,8 @@ public class MouldController {
     @ApiOperation("申请移模")
     @RequestMapping("/applyMove")
     @ResponseBody
-    public HttpRespMsg applyMove(int mouldId, String reason, String time, String address) {
-        return mouldService.applyMove(mouldId, reason, time, address);
+    public HttpRespMsg applyMove(int mouldId, String reason, String time, String address, Integer producerCompanyId, Integer userId) {
+        return mouldService.applyMove(mouldId, reason, time, address, producerCompanyId, userId);
     }
     @ApiOperation("审核移模申请")
     @RequestMapping("/checkApplyMove")

+ 9 - 0
cloud-model/src/main/java/com/hssx/cloudmodel/controller/UserController.java

@@ -195,5 +195,14 @@ public class UserController {
         return userService.bindWeiXin(code, token);
     }
 
+    @RequestMapping(value = "/unbindWeiXin", method = RequestMethod.GET)
+    public HttpRespMsg unbindWeiXin(String token) {
+        return userService.unbindWeiXin(token);
+    }
+
+    @RequestMapping(value = "/unbindCorpWeiXin", method = RequestMethod.GET)
+    public HttpRespMsg unbindCorpWeiXin(String token) {
+        return userService.unbindCorpWeiXin(token);
+    }
 }
 

+ 121 - 3
cloud-model/src/main/java/com/hssx/cloudmodel/controller/WeiXinCorpController.java

@@ -18,6 +18,7 @@ import com.qq.weixin.mp.aes.AesException;
 import com.qq.weixin.mp.aes.WXBizMsgCrypt;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.tomcat.jni.Local;
 import org.json.XML;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -30,10 +31,10 @@ import javax.servlet.http.HttpServletRequest;
 import java.io.UnsupportedEncodingException;
 import java.net.URLDecoder;
 import java.net.URLEncoder;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
-import java.util.Date;
-import java.util.SortedMap;
-import java.util.TreeMap;
+import java.time.ZoneOffset;
+import java.util.*;
 
 @RestController
 @RequestMapping("/wxcorp")
@@ -43,6 +44,8 @@ public class WeiXinCorpController {
     public static final String GET_PREAUTH_CODE_URL = "https://qyapi.weixin.qq.com/cgi-bin/service/get_pre_auth_code?suite_access_token=SUITE_ACCESS_TOKEN";
     //获取企业永久授权码
     public static final String GET_CORP_PERMANENT_CODE_URL = "https://qyapi.weixin.qq.com/cgi-bin/service/get_permanent_code?suite_access_token=SUITE_ACCESS_TOKEN";
+    public static final String GET_CORP_ACCESSTOKEN_URL = "https://qyapi.weixin.qq.com/cgi-bin/service/get_corp_token?suite_access_token=SUITE_ACCESS_TOKEN";
+
     //获取成员详情
     public static final String GET_USER_INFO_URL = "https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&userid=USERID";
     //获取部门列表
@@ -51,6 +54,10 @@ public class WeiXinCorpController {
     public static final String GET_DEPARTMENT_USER_DETAIL_URL = "https://qyapi.weixin.qq.com/cgi-bin/user/list?access_token=ACCESS_TOKEN&department_id=DEPARTMENT_ID&fetch_child=1";
 
     public static final String AUTH_CALLBACK_URL = "http://ymhh.yunsu.cn/wxcorp/authcallback";
+    //网页获取企业用户信息
+    public static final String GET_CORP_USERINFO_URL = "https://qyapi.weixin.qq.com/cgi-bin/service/getuserinfo3rd?suite_access_token=SUITE_ACCESS_TOKEN&code=CODE";
+
+
     @Value("${suitId}")
     private String suitId;
     @Value("${suitSecret}")
@@ -71,6 +78,12 @@ public class WeiXinCorpController {
     public static String PRE_AUTH_CODE = null;
     public static long expireTime = 0L;
 
+    public Map<String, Item> corpTicketMap = new HashMap<String,Item>();
+    class Item {
+        String jsTicket = null;
+        LocalDateTime expireTime = null;
+    }
+
     @Resource
     SysParamMapper sysParamMapper;
     @Resource
@@ -78,6 +91,88 @@ public class WeiXinCorpController {
     @Resource
     UserMapper userMapper;
 
+    @ApiOperation(value = "获取企业微信jssdk初始化配置参数", notes = "获取企业微信jssdk初始化配置参数")
+    @RequestMapping("/getCorpWXConfig")
+    @ResponseBody
+    public HttpRespMsg getCorpWXConfig(String url, String token) {
+        HttpRespMsg msg = new HttpRespMsg();
+        try {
+            User user = userMapper.selectOne(new QueryWrapper<User>().eq("head_imgurl", token));
+            WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", user.getCompanyId()));
+
+            Date now = new Date();
+            Item item = corpTicketMap.get(wxCorpInfo.getCorpid());
+            if (item == null || item.expireTime.isBefore(LocalDateTime.now())) {
+                //重新获取
+                String getTicketUrl = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=ACCESS_TOKEN";
+                String corpToken = getCorpAccessToken(wxCorpInfo);
+                getTicketUrl = getTicketUrl.replace("ACCESS_TOKEN", corpToken);
+                String forObject = this.restTemplate.getForObject(getTicketUrl, String.class);
+                JSONObject json = JSONObject.parseObject(forObject);
+                log.info("返回:"+json.toJSONString());
+                if (json.getIntValue("errcode") == 0) {
+                    String ticket = json.getString("ticket");
+                    Item it = new Item();
+                    it.expireTime = LocalDateTime.now().plusSeconds(7200);
+                    it.jsTicket = ticket;
+                    corpTicketMap.put(wxCorpInfo.getCorpid(), it);
+                    item = it;
+                }
+            }
+            if (item == null) {
+                msg.setError("jsapiTicket获取失败");
+                return msg;
+            }
+            log.info("jsTicket = " + item.jsTicket);
+            // 随机数
+            String nonce_str = Sha1Util.getNonceStr();
+            String timestamp = Sha1Util.getTimeStamp();
+            // 对以下字段进行签名
+            SortedMap<String, String> packageParams = new TreeMap<String, String>();
+            packageParams.put("jsapi_ticket", item.jsTicket);
+            packageParams.put("noncestr", nonce_str);
+            packageParams.put("timestamp", ""+timestamp);
+            packageParams.put("url", url);
+            String sign = Sha1Util.createSHA1Sign(packageParams);
+            packageParams.put("sign", sign);
+            packageParams.put("appid", wxCorpInfo.getCorpid());//这里使用企业微信corpId
+            msg.data = packageParams;
+        } catch (Exception e) {
+            e.printStackTrace();
+            msg.setError(e.getMessage());
+        }
+        return msg;
+    }
+
+    //获取企业AccessToken
+    private String getCorpAccessToken(WxCorpInfo corpInfo) throws Exception {
+        if (corpInfo.getExpireTime().isBefore(LocalDateTime.now())) {
+            String url = GET_CORP_ACCESSTOKEN_URL.replace("SUITE_ACCESS_TOKEN", getSuiteAccessToken());
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.APPLICATION_JSON);
+            JSONObject reqParam = new JSONObject();
+            reqParam.put("auth_corpid",  corpInfo.getCorpid());
+            reqParam.put("permanent_code",  corpInfo.getPermanentCode());
+            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();
+                JSONObject json = JSONObject.parseObject(resp);
+                if (json.getIntValue("errcode") == 0) {
+                    String access_token = json.getString("access_token");
+                    corpInfo.setAccessToken(access_token);
+                    LocalDateTime now = LocalDateTime.now();
+                    now = now.plusSeconds(7200);
+                    corpInfo.setExpireTime(now);
+                    wxCorpInfoMapper.updateById(corpInfo);
+                } else {
+                    throw new Exception(json.toJSONString());
+                }
+            }
+        }
+        return corpInfo.getAccessToken();
+    }
 
     @ApiOperation(value = "企业微信数据回调", notes = "企业微信数据回调")
     @RequestMapping(value = "/dataCallback/{corpId}", method = RequestMethod.GET)
@@ -310,6 +405,7 @@ public class WeiXinCorpController {
                                 //手机号不存在的,添加
                                 if (data.getCompanyId() != null) {
                                     employee.setCompanyId(data.getCompanyId());
+                                    employee.setRoleName("企业微信导入");
                                     userMapper.insert(employee);
                                 }
                             }
@@ -387,4 +483,26 @@ public class WeiXinCorpController {
         }
         return SUITE_ACCESS_TOKEN;
     }
+
+    @RequestMapping(value = "/bindCorpWeiXin", method = RequestMethod.GET)
+    public HttpRespMsg bindCorpWeiXin(String code, String token) {
+        HttpRespMsg msg = new HttpRespMsg();
+        User curUser = userMapper.selectOne(new QueryWrapper<User>().eq("head_imgurl", token));
+        //https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=ACCESS_TOKEN&code=CODE
+        int compId = curUser.getCompanyId();
+        WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", compId));
+
+        String url = GET_CORP_USERINFO_URL.replace("SUITE_ACCESS_TOKEN", getSuiteAccessToken()).replace("CODE", code);
+        String forObject = this.restTemplate.getForObject(url, String.class);
+        JSONObject obj = JSONObject.parseObject(forObject);
+        String userId = obj.getString("UserId");
+        if (userId == null) {
+            msg.setError("该用户企业未授权");
+        } else {
+            curUser.setCorpUserId(userId);
+            userMapper.updateById(curUser);
+            msg.data = curUser;
+        }
+        return msg;
+    }
 }

+ 31 - 1
cloud-model/src/main/java/com/hssx/cloudmodel/entity/Mould.java

@@ -15,7 +15,7 @@ import java.io.Serializable;
  * </p>
  *
  * @author seya
- * @since 2020-08-16
+ * @since 2020-08-18
  */
 @TableName("tb_mould")
 public class Mould extends Model<Mould> {
@@ -220,6 +220,18 @@ public class Mould extends Model<Mould> {
     @TableField("move_apply_address")
     private String moveApplyAddress;
 
+    /**
+     * 移模生产方公司id
+     */
+    @TableField("move_apply_producer_id")
+    private Integer moveApplyProducerId;
+
+    /**
+     * 移模生产方公司名称
+     */
+    @TableField("move_apply_producer_name")
+    private String moveApplyProducerName;
+
 
     public Integer getId() {
         return id;
@@ -485,6 +497,22 @@ public class Mould extends Model<Mould> {
         this.moveApplyAddress = moveApplyAddress;
     }
 
+    public Integer getMoveApplyProducerId() {
+        return moveApplyProducerId;
+    }
+
+    public void setMoveApplyProducerId(Integer moveApplyProducerId) {
+        this.moveApplyProducerId = moveApplyProducerId;
+    }
+
+    public String getMoveApplyProducerName() {
+        return moveApplyProducerName;
+    }
+
+    public void setMoveApplyProducerName(String moveApplyProducerName) {
+        this.moveApplyProducerName = moveApplyProducerName;
+    }
+
     @Override
     protected Serializable pkVal() {
         return this.id;
@@ -526,6 +554,8 @@ public class Mould extends Model<Mould> {
         ", moveApplyReason=" + moveApplyReason +
         ", moveApplyTime=" + moveApplyTime +
         ", moveApplyAddress=" + moveApplyAddress +
+        ", moveApplyProducerId=" + moveApplyProducerId +
+        ", moveApplyProducerName=" + moveApplyProducerName +
         "}";
     }
 }

+ 16 - 1
cloud-model/src/main/java/com/hssx/cloudmodel/entity/User.java

@@ -14,7 +14,7 @@ import java.io.Serializable;
  * </p>
  *
  * @author seya
- * @since 2020-08-09
+ * @since 2020-08-20
  */
 @TableName("tb_user")
 public class User extends Model<User> {
@@ -135,6 +135,12 @@ public class User extends Model<User> {
     @TableField("nickname")
     private String nickname;
 
+    /**
+     * 企业用户userid
+     */
+    @TableField("corp_user_id")
+    private String corpUserId;
+
 
     public Integer getId() {
         return id;
@@ -288,6 +294,14 @@ public class User extends Model<User> {
         this.nickname = nickname;
     }
 
+    public String getCorpUserId() {
+        return corpUserId;
+    }
+
+    public void setCorpUserId(String corpUserId) {
+        this.corpUserId = corpUserId;
+    }
+
     @Override
     protected Serializable pkVal() {
         return this.id;
@@ -315,6 +329,7 @@ public class User extends Model<User> {
         ", openid=" + openid +
         ", avatar=" + avatar +
         ", nickname=" + nickname +
+        ", corpUserId=" + corpUserId +
         "}";
     }
 }

+ 4 - 0
cloud-model/src/main/java/com/hssx/cloudmodel/mapper/UserMapper.java

@@ -24,4 +24,8 @@ public interface UserMapper extends BaseMapper<User> {
     List<UserVO> selectUserListByCondition(@Param("roleType") Integer roleType, @Param("companyId")Integer companyId,@Param("flag") Integer flag, @Param("keyName") String keyName,@Param("list")List<Integer> uIds,@Param("user")User user);
 
     List<UserVO> selsctUsersByUids(@Param("list")List<Integer> uids, @Param("id")Integer id);
+
+
+    void unbindWeiXin(String token);
+    void unbindCorpWeiXin(String token);
 }

+ 1 - 1
cloud-model/src/main/java/com/hssx/cloudmodel/service/MouldService.java

@@ -40,7 +40,7 @@ public interface MouldService extends IService<Mould> {
 
     HttpRespMsg updateLastTimeRuntimesTask();
 
-    HttpRespMsg applyMove(int mouldId, String reason, String time, String address);
+    HttpRespMsg applyMove(int mouldId, String reason, String time, String address, Integer producerCompanyId, int userId);
 
     HttpRespMsg checkApplyMove(int mouldId, int status);
 

+ 4 - 0
cloud-model/src/main/java/com/hssx/cloudmodel/service/UserService.java

@@ -37,4 +37,8 @@ public interface UserService extends IService<User> {
     HttpRespMsg bindWeiXin(String code, String token);
 
     HttpRespMsg addNewAdmin(User user);
+
+    HttpRespMsg unbindWeiXin(String token);
+
+    HttpRespMsg unbindCorpWeiXin(String token);
 }

+ 1 - 1
cloud-model/src/main/java/com/hssx/cloudmodel/service/impl/MouldEquipmentServiceImpl.java

@@ -214,7 +214,7 @@ public class MouldEquipmentServiceImpl extends ServiceImpl<MouldEquipmentMapper,
             uids.add(project.getManagerId());
             uids.add(project.getCreatorId());
             uids.add(-1);
-            List<User> userList = userMapper.selectList(new QueryWrapper<User>().in("id", uids).isNotNull("openid").eq("is_disable", 1));
+            List<User> userList = userMapper.selectList(new QueryWrapper<User>().in("id", uids).isNotNull("openid").eq("is_disable", 0));
             if (Constant.ELECTRICITY_THRESHOLD >= Double.parseDouble(mouldEquipment.getHillNumber())) {
                 if (0 == mouldEquipment.getStage()) {
                     mouldEquipment.setStage(2);

+ 57 - 1
cloud-model/src/main/java/com/hssx/cloudmodel/service/impl/MouldFileServiceImpl.java

@@ -254,11 +254,22 @@ public class MouldFileServiceImpl extends ServiceImpl<MouldFileMapper, MouldFile
                         }
                         newsNotice.setContent("有新的" + content + "上传,待您审批。");
                         newsNoticeMapper.insert(newsNotice);
+                        WechatTemplateMessage templateMessage = new WechatTemplateMessage();
+                        String token = GainTokenUtil.getToken();
                         for (ProjectApprove projectApprove : projectApproves) {
                             NewsNoticeUser newsNoticeUser = new NewsNoticeUser();
                             newsNoticeUser.setUserId(projectApprove.getApproverId());
                             newsNoticeUser.setNewsId(newsNotice.getId());
                             newsNoticeUserMapper.insert(newsNoticeUser);
+                            //发送微信通知消息
+                            User wuser = userMapper.selectById(projectApprove.getApproverId());
+                            if (StringUtils.isNotEmpty(wuser.getOpenid())) {
+                                try {
+                                    WechatTemplateUtil.sendAuditSubmitMessage(wuser.getOpenid(), user.getUsername(), newsNotice.getContent(),newsNotice.getProjectName(), token);
+                                } catch (Exception e) {
+                                    e.printStackTrace();
+                                }
+                            }
                         }
                     }
                 }
@@ -283,11 +294,22 @@ public class MouldFileServiceImpl extends ServiceImpl<MouldFileMapper, MouldFile
                 newsNotice.setNoticeType(Constant.APPROVEL_TYPE);
                 newsNotice.setContent("有新的" + content + "申请记录,待您审批。");
                 newsNoticeMapper.insert(newsNotice);
+                String token = GainTokenUtil.getToken();
                 for (ProjectApprove projectApprove : projectApproves) {
                     NewsNoticeUser newsNoticeUser = new NewsNoticeUser();
                     newsNoticeUser.setUserId(projectApprove.getApproverId());
                     newsNoticeUser.setNewsId(newsNotice.getId());
                     newsNoticeUserMapper.insert(newsNoticeUser);
+
+                    //发送微信通知消息
+                    User wuser = userMapper.selectById(projectApprove.getApproverId());
+                    if (StringUtils.isNotEmpty(wuser.getOpenid())) {
+                        try {
+                            WechatTemplateUtil.sendAuditSubmitMessage(wuser.getOpenid(), user.getUsername(), newsNotice.getContent(), newsNotice.getProjectName(), token);
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+                    }
                 }
             }
         } else {
@@ -408,6 +430,17 @@ public class MouldFileServiceImpl extends ServiceImpl<MouldFileMapper, MouldFile
                 noticeUser.setUserId(creatorId);
                 noticeUser.setNewsId(notice.getId());
                 newsNoticeUserMapper.insert(noticeUser);
+
+                //发送微信消息,审核结果
+                String accessToken = GainTokenUtil.getToken();
+                User wuser = userMapper.selectById(creatorId);
+                if (StringUtils.isNotEmpty(wuser.getOpenid())) {
+                    try {
+                        WechatTemplateUtil.sendAuditResultMessage(wuser.getOpenid(), oldData.getUploadtor(), user.getUsername(), notice.getContent(), project.getProjectName(), accessToken);
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                }
             } else if (user.getSubordinateType() == 1) {
                 //生产方
                 boolean isDeleted = false;
@@ -501,6 +534,17 @@ public class MouldFileServiceImpl extends ServiceImpl<MouldFileMapper, MouldFile
                 noticeUser.setUserId(creatorId);
                 noticeUser.setNewsId(notice.getId());
                 newsNoticeUserMapper.insert(noticeUser);
+
+                //发送微信消息,审核结果
+                String accessToken = GainTokenUtil.getToken();
+                User wuser = userMapper.selectById(creatorId);
+                if (StringUtils.isNotEmpty(wuser.getOpenid())) {
+                    try {
+                        WechatTemplateUtil.sendAuditResultMessage(wuser.getOpenid(), oldData.getUploadtor(), user.getUsername(), notice.getContent(), project.getProjectName(), accessToken);
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                }
             } else {
                 msg.setError("只有生产方和资产方审批人才能审核");
             }
@@ -642,13 +686,14 @@ public class MouldFileServiceImpl extends ServiceImpl<MouldFileMapper, MouldFile
                 list = mouldFileMapper.getFileListByProjectId(userVO, proIds);
             } else {
                 QueryWrapper<Project> qw = new QueryWrapper<>();
-                qw.eq("manager_id", userVO.getId());
+                qw.eq("manager_id", currentUser.getId());
                 List<Project> projects = projectMapper.selectList(qw);
                 if (projects.size() > 0) {
                     for (Project project : projects) {
                         proIds.add(project.getId());
                     }
                 }
+                log.info("项目经理的项目大小=="+projects.size());
 //                //充当普通人员参与的项目
                 List<ProjectUser> projectUsers = projectUserMapper.selectList(new QueryWrapper<ProjectUser>().eq("user_id", currentUser.getId()));
                 if (projectUsers.size() > 0) {
@@ -1009,11 +1054,22 @@ public class MouldFileServiceImpl extends ServiceImpl<MouldFileMapper, MouldFile
                 newsNotice.setContent(currentUser.getUsername() + "申请删除" + content + "模块的"
                         + file.getFileName() + (StringUtils.isNotEmpty(reason)?("(原因:"+reason+")"):"")+",待您审批。");
                 newsNoticeMapper.insert(newsNotice);
+                String accessToken = GainTokenUtil.getToken();
                 for (ProjectApprove projectApprove : projectApproves) {
                     NewsNoticeUser newsNoticeUser = new NewsNoticeUser();
                     newsNoticeUser.setUserId(projectApprove.getApproverId());
                     newsNoticeUser.setNewsId(newsNotice.getId());
                     newsNoticeUserMapper.insert(newsNoticeUser);
+
+                    //发送微信消息
+                    User wuser = userMapper.selectById(projectApprove.getApproverId());
+                    if (StringUtils.isNotEmpty(wuser.getOpenid())) {
+                        try {
+                            WechatTemplateUtil.sendAuditSubmitMessage(wuser.getOpenid(), currentUser.getUsername(), newsNotice.getContent(), project.getProjectName(), accessToken);
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+                    }
                 }
 
                 //生成操作记录

+ 1 - 1
cloud-model/src/main/java/com/hssx/cloudmodel/service/impl/MouldHistoryServiceImpl.java

@@ -76,7 +76,7 @@ public class MouldHistoryServiceImpl extends ServiceImpl<MouldHistoryMapper, Mou
                     //时间段
                     rowList.add(cycleRuntime.getTimeSlot());
                     //运行次数
-                    rowList.add(cycleRuntime.getRuntime()/1000 + "s");
+                    rowList.add(cycleRuntime.getRuntime()+"");
 //                    rowList.add(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(dynamic.getIndate())
                     list.add(rowList);
                 }

+ 32 - 5
cloud-model/src/main/java/com/hssx/cloudmodel/service/impl/MouldServiceImpl.java

@@ -359,11 +359,15 @@ public class MouldServiceImpl extends ServiceImpl<MouldMapper, Mould> implements
                 m.setId(mould.getId());
                 m.setIsMaintain(1);
                 mouldMapper.updateById(m);
-                List<Integer> uids = projectUserMapper.selectList(new QueryWrapper<ProjectUser>().eq("project_id", project.getId())).stream().map(ProjectUser::getUserId).collect(Collectors.toList());
-                uids.add(project.getManagerId());
-                uids.add(project.getCreatorId());
+                //给具有保养权限的人发送
+                List<Power> powerList = powerMapper.selectList(new QueryWrapper<Power>().eq("project_id", project.getId()).eq("power_type", 4));
+                int[] ints = powerList.stream().mapToInt(Power::getUserId).toArray();
+
+                List<Integer> uids = ListUtil.convertFromIntArray(ints);//projectUserMapper.selectList(new QueryWrapper<ProjectUser>().eq("project_id", project.getId())).stream().map(ProjectUser::getUserId).collect(Collectors.toList());
+//                uids.add(project.getManagerId());
+//                uids.add(project.getCreatorId());
                 uids.add(-1);
-                List<User> userList = userMapper.selectList(new QueryWrapper<User>().in("id", uids).isNotNull("openid").eq("is_disable", 1));
+                List<User> userList = userMapper.selectList(new QueryWrapper<User>().in("id", uids).isNotNull("openid").eq("is_disable", 0));
                 //公众号的推送to do
                 userList.forEach(u -> {
                     try {
@@ -717,7 +721,7 @@ public class MouldServiceImpl extends ServiceImpl<MouldMapper, Mould> implements
     }
 
     @Override
-    public HttpRespMsg applyMove(int mouldId, String reason, String time, String address) {
+    public HttpRespMsg applyMove(int mouldId, String reason, String time, String address, Integer producerCompanyId, int userId) {
         HttpRespMsg msg = new HttpRespMsg();
         Mould mould = new Mould();
         mould.setId(mouldId);
@@ -725,6 +729,9 @@ public class MouldServiceImpl extends ServiceImpl<MouldMapper, Mould> implements
         mould.setMoveApplyReason(reason);
         mould.setMoveApplyAddress(address);
         mould.setMoveApplyTime(time);
+        mould.setMoveApplyProducerId(producerCompanyId);
+        String companyName = companyMapper.selectById(producerCompanyId).getCompanyName();
+        mould.setMoveApplyProducerName(companyName);
         mouldMapper.updateById(mould);
 
         //发送消息通知
@@ -738,6 +745,7 @@ public class MouldServiceImpl extends ServiceImpl<MouldMapper, Mould> implements
                     +(!StringUtils.isEmpty(mould.getMoveApplyReason())?"原因:"+mould.getMoveApplyReason()+",":"")
                     +(!StringUtils.isEmpty(mould.getMoveApplyTime())?"时间:"+mould.getMoveApplyTime()+",":"")
                     +(!StringUtils.isEmpty(mould.getMoveApplyAddress())?"地点:"+mould.getMoveApplyAddress()+",":"")
+                    +(!mould.getProduceCompanyId().equals(mould.getMoveApplyProducerId())?"生产方改为:"+mould.getMoveApplyProducerName()+",":"")
                     +"请审批");
             notice.setNoticeType(0);//待审批
             notice.setRefId(mouldId);//附带模具id
@@ -750,6 +758,17 @@ public class MouldServiceImpl extends ServiceImpl<MouldMapper, Mould> implements
             newsNoticeUser.setUserId(approve.getApproverId());
             newsNoticeUser.setIsRead(0);
             newsNoticeUserMapper.insert(newsNoticeUser);
+
+            String accessToken = GainTokenUtil.getToken();
+            User wuser = userMapper.selectById(approve.getApproverId());
+            User user = userMapper.selectById(userId);
+            if (org.apache.commons.lang3.StringUtils.isNotEmpty(wuser.getOpenid())) {
+                try {
+                    WechatTemplateUtil.sendAuditSubmitMessage(wuser.getOpenid(), user.getUsername(), notice.getContent(), project.getProjectName(), accessToken);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
         }
 
 
@@ -761,6 +780,14 @@ public class MouldServiceImpl extends ServiceImpl<MouldMapper, Mould> implements
         Mould mould = new Mould();
         mould.setId(mouldId);
         mould.setMoveApplyState(status);
+        if (status == 2) {
+            //审核通过,生产方公司发生变动时需要修改生产方公司
+            Mould oldMould = mouldMapper.selectById(mouldId);
+            if (!oldMould.getMoveApplyProducerId().equals(oldMould.getProduceCompanyId())) {
+                mould.setProduceCompanyId(oldMould.getMoveApplyProducerId());
+                mould.setProduceCompanyName(oldMould.getMoveApplyProducerName());
+            }
+        }
         mouldMapper.updateById(mould);
 
         //发送通知消息给项目经理

+ 12 - 4
cloud-model/src/main/java/com/hssx/cloudmodel/service/impl/ProjectFileServiceImpl.java

@@ -9,10 +9,7 @@ import com.hssx.cloudmodel.mapper.*;
 import com.hssx.cloudmodel.service.ProjectFileService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.hssx.cloudmodel.service.ProjectOperationDynamicsService;
-import com.hssx.cloudmodel.util.FileUtil;
-import com.hssx.cloudmodel.util.HttpRespMsg;
-import com.hssx.cloudmodel.util.OpenOfficeService;
-import com.hssx.cloudmodel.util.QcloudUntil;
+import com.hssx.cloudmodel.util.*;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -327,6 +324,17 @@ public class ProjectFileServiceImpl extends ServiceImpl<ProjectFileMapper, Proje
                 newsNoticeUserMapper.insert(newsNoticeUser);
 
                 msg.data = approve.getApproverName();//返回审批人姓名
+
+                //发送微信消息
+                String accessToken = GainTokenUtil.getToken();
+                User wuser = userMapper.selectById(approve.getApproverId());
+                if (StringUtils.isNotEmpty(wuser.getOpenid())) {
+                    try {
+                        WechatTemplateUtil.sendAuditSubmitMessage(wuser.getOpenid(), user.getUsername(), notice.getContent(), project.getProjectName(), accessToken);
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                }
             }else{
                 msg.setError("当前用户不存在或者未登录");
                 return msg;

+ 21 - 15
cloud-model/src/main/java/com/hssx/cloudmodel/service/impl/ProjectServiceImpl.java

@@ -243,21 +243,23 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                 }
 
                 //删除之前分配与项目关联的模具,即将之前的关联项目id修改成未关联
-                mouldMapper.updateMouldByProjectId(project);
-                log.info("==============删除之前关联的模具==========");
-                //再次模具的分配
-                log.info("==============新模具=========="+modelIds);
-                if (modelIds != null && !"".equals(modelIds)) {
-                    List<Integer> modelList = ListUtil.convertIntegerIdsArrayToList(modelIds);
-                    int sum = 1;
-                    if (modelList.size() > 0) {
-                        for (Integer id : modelList) {
-                            Mould mould = new Mould();
-                            mould.setId(id);
-                            mould.setProjectId(project.getId());
-                            mould.setBelongProjectGrade(sum + "");
-                            mouldMapper.updateById(mould);
-                            sum++;
+
+                if (modelIds != null) {//前端不修改modelIds时,传null, 不需要更新
+                    log.info("==============删除之前关联的模具==========");
+                    mouldMapper.updateMouldByProjectId(project);
+                    //再次模具的分配
+                    if (!"".equals(modelIds)) {
+                        List<Integer> modelList = ListUtil.convertIntegerIdsArrayToList(modelIds);
+                        int sum = 1;
+                        if (modelList.size() > 0) {
+                            for (Integer id : modelList) {
+                                Mould mould = new Mould();
+                                mould.setId(id);
+                                mould.setProjectId(project.getId());
+                                mould.setBelongProjectGrade(sum + "");
+                                mouldMapper.updateById(mould);
+                                sum++;
+                            }
                         }
                     }
                 }
@@ -414,6 +416,10 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
             return msg;
         }
         ProjectVO vo = projectMapper.getProjectById(project.getId(), user);
+        if (vo == null) {
+            msg.setError("您没有该权限!");
+            return msg;
+        }
         if (Constant.SYS_PARENT_ID.equals(user.getParentId())) {
             //当前人超级管理员 ,对项目只可以浏览
             map.put("update", 0);

+ 14 - 1
cloud-model/src/main/java/com/hssx/cloudmodel/service/impl/UserServiceImpl.java

@@ -68,7 +68,6 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
     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";
 
-
     @Override
     public HttpRespMsg login(UserVO userVO, boolean checkFirst, HttpServletRequest request) {
         System.out.println("user account== " + userVO.getAccount());
@@ -780,5 +779,19 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
     }
 
 
+    public HttpRespMsg unbindWeiXin(String token) {
+        HttpRespMsg respMsg = new HttpRespMsg();
+        userMapper.unbindWeiXin(token);
+        User curUser = userMapper.selectOne(new QueryWrapper<User>().eq("head_imgurl", token));
+        respMsg.data = curUser;
+        return respMsg;
+    }
 
+    public HttpRespMsg unbindCorpWeiXin(String token) {
+        HttpRespMsg respMsg = new HttpRespMsg();
+        userMapper.unbindCorpWeiXin(token);
+        User curUser = userMapper.selectOne(new QueryWrapper<User>().eq("head_imgurl", token));
+        respMsg.data = curUser;
+        return respMsg;
+    }
 }

+ 1 - 1
cloud-model/src/main/java/com/hssx/cloudmodel/util/CodeGenerator.java

@@ -210,7 +210,7 @@ public class CodeGenerator {
         //若想要生成的实体类继承某个Controller,则可打开下面注释。写上需要继承的Controller的位置即可
 //        strategy.setSuperControllerClass("com.baomidou.ant.common.BaseController");
         //此处user是表名,多个英文逗号分割
-        strategy.setInclude("tb_mould");
+        strategy.setInclude("tb_user");
 //        strategy.setExclude();//数据库表全生成
 //        strategy.setInclude(scanner("user").split(","));//表名,多个英文逗号分割
         strategy.setControllerMappingHyphenStyle(true);

+ 3 - 0
cloud-model/src/main/java/com/hssx/cloudmodel/util/GainTokenUtil.java

@@ -3,6 +3,7 @@ package com.hssx.cloudmodel.util;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.hssx.cloudmodel.constant.Constant;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringEscapeUtils;
 
 /**
@@ -11,6 +12,7 @@ import org.apache.commons.lang3.StringEscapeUtils;
  * Description:<描述>
  * Version: 1.0
  */
+@Slf4j
 public class GainTokenUtil {
 
     public static String getToken() {
@@ -21,6 +23,7 @@ public class GainTokenUtil {
         try {
             resp1 = HttpKit.get(url, true);
             resp1 = StringEscapeUtils.unescapeJava(resp1);
+            log.info("获取AccessToken返回="+resp1);
             JSONObject json = (JSONObject) JSON.parse(resp1);
             // 获取值赋值给全局变量
             if (!json.containsKey("errcode")) {

+ 103 - 0
cloud-model/src/main/java/com/hssx/cloudmodel/util/WechatTemplateUtil.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.hssx.cloudmodel.constant.Constant;
 import com.hssx.cloudmodel.entity.vo.MouldEquipmentVO;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringEscapeUtils;
 
 import java.text.SimpleDateFormat;
@@ -17,8 +18,110 @@ import java.util.Map;
  * Description:<描述>
  * Version: 1.0
  */
+@Slf4j
 public class WechatTemplateUtil {
 
+    /**
+     * 发送审批结果消息
+     * @param touserOpenId
+     * @param auditUserName
+     * @param msgContent
+     * @param projectName
+     * @param newAccessToken
+     * @throws Exception
+     */
+    public static void sendAuditResultMessage(String touserOpenId,String submitUserName, String auditUserName,String msgContent, String projectName, String newAccessToken) throws Exception {
+        log.info("发送微信消息了==" + touserOpenId+",审批人:"+auditUserName+", token="+newAccessToken);
+        HttpRespMsg msg = new HttpRespMsg();
+        String url1 = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="
+                + newAccessToken;
+        WechatTemplateMessage wechat = new WechatTemplateMessage();
+        wechat.setTemplate_id(Constant.AUDIT_RESULT_TEMPLATE_ID);
+        wechat.setTouser(touserOpenId);
+        wechat.setAppid(Constant.WECHAT_APPID);
+        Map<String, Map<String, String>> data = new HashMap<>();
+        Map<String, String> first = new HashMap<>();
+        Map<String, String> value1 = new HashMap<>();
+        Map<String, String> value2 = new HashMap<>();
+        Map<String, String> value3 = new HashMap<>();
+        Map<String, String> value4 = new HashMap<>();
+        Map<String, String> remark = new HashMap<>();
+        // 推送信息主体
+        first.put("value", msgContent);//firstData推送标题
+        data.put("first", first);
+        value1.put("value", "审批结果");
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        data.put("keyword1", value1);
+        value2.put("value", submitUserName);//申请人
+        data.put("keyword2", value2);
+        value3.put("value", auditUserName);//审批人
+        data.put("keyword3", value3);
+        value4.put("value", projectName);
+        data.put("keyword4", value4);
+        remark.put("value", "请查看");
+        data.put("remark", remark);
+        wechat.setData(data);
+        wechat.setUrl("http://ymhh.yunsu.cn/#/message");
+        String jsonString = JSONObject.toJSONString(wechat);
+        log.info("jsonString"+jsonString);
+        String resp = HttpKit.post(url1, jsonString);
+        log.info("resp=="+resp);
+        resp = StringEscapeUtils.unescapeJava(resp);
+        JSONObject json = (JSONObject) JSON.parse(resp);
+    }
+
+
+
+    /**
+     * 审核提交,待审批的微信消息
+     * @param touserOpenId
+     * @param submitUserName
+     * @param msgContent
+     * @param projectName
+     * @param newAccessToken
+     * @throws Exception
+     */
+    public static void sendAuditSubmitMessage(String touserOpenId, String submitUserName,String msgContent, String projectName, String newAccessToken) throws Exception {
+        log.info("发送微信消息了==" + touserOpenId+",提交人:"+submitUserName+", token="+newAccessToken);
+        HttpRespMsg msg = new HttpRespMsg();
+        String url1 = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="
+                + newAccessToken;
+        WechatTemplateMessage wechat = new WechatTemplateMessage();
+        wechat.setTemplate_id(Constant.AUDIT_SUBMIT_TEMPLATE_ID);
+        wechat.setTouser(touserOpenId);
+        wechat.setAppid(Constant.WECHAT_APPID);
+        Map<String, Map<String, String>> data = new HashMap<>();
+        Map<String, String> first = new HashMap<>();
+        Map<String, String> value1 = new HashMap<>();
+        Map<String, String> value2 = new HashMap<>();
+        Map<String, String> value3 = new HashMap<>();
+        Map<String, String> value4 = new HashMap<>();
+        Map<String, String> remark = new HashMap<>();
+        // 推送信息主体
+        first.put("value", msgContent);//firstData推送标题
+        data.put("first", first);
+        value1.put("value", "文档待审核");
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        data.put("keyword1", value1);
+        value2.put("value", submitUserName);//申请人
+        data.put("keyword2", value2);
+        value3.put("value", sdf.format(new Date()));//申请时间
+        data.put("keyword3", value3);
+        value4.put("value", projectName);
+        data.put("keyword4", value4);
+        remark.put("value", "请尽快审核");
+        data.put("remark", remark);
+        wechat.setData(data);
+        wechat.setUrl("http://ymhh.yunsu.cn/#/message");
+        String jsonString = JSONObject.toJSONString(wechat);
+        log.info("jsonString"+jsonString);
+        String resp = HttpKit.post(url1, jsonString);
+        log.info("resp=="+resp);
+        resp = StringEscapeUtils.unescapeJava(resp);
+        JSONObject json = (JSONObject) JSON.parse(resp);
+    }
+
+
     /**
      * 云模盒告警模板
      * touserOpenId 被推送者的openId

Файловите разлики са ограничени, защото са твърде много
+ 11 - 4
cloud-model/src/main/resources/mapper/MouldMapper.xml


+ 14 - 5
cloud-model/src/main/resources/mapper/UserMapper.xml

@@ -23,6 +23,7 @@
         <result column="openid" property="openid" />
         <result column="avatar" property="avatar" />
         <result column="nickname" property="nickname" />
+        <result column="corp_user_id" property="corpUserId" />
     </resultMap>
 
     <resultMap id="BaseResultMapVO" type="com.hssx.cloudmodel.entity.vo.UserVO">
@@ -46,18 +47,20 @@
         <result column="openid" property="openid" />
         <result column="avatar" property="avatar" />
         <result column="nickname" property="nickname" />
+        <result column="corp_user_id" property="corpUserId" />
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        id, account, username, password, mobile, role_type, company_id, parent_id, sex, role_name, work_state, is_disable, indate, head_imgurl, team_name, subordinate_type, openid, avatar, nickname
+        id, account, username, password, mobile, role_type, company_id, parent_id, sex, role_name, work_state, is_disable, indate, head_imgurl, team_name, subordinate_type, openid, avatar, nickname, corp_user_id
     </sql>
 
+
     <select id="selsctUsersByUids" resultMap="BaseResultMapVO">
         SELECT
         u.id id,  u.username username,  u.mobile mobile,  u.company_id company_id, c.`company_name` company_name,
         u.parent_id parent_id,  u.work_state work_state, u.is_disable is_disable,
-        u.indate indate, u.head_imgurl head_imgurl, u.team_name team_name, u.subordinate_type subordinate_type,avatar, nickname
+        u.indate indate, u.head_imgurl head_imgurl, u.team_name team_name, u.subordinate_type subordinate_type,avatar, nickname, corp_user_id
         FROM
         tb_user AS u
         LEFT JOIN tb_company c
@@ -74,7 +77,7 @@
         SELECT
         u.id id, u.account account, u.username username, u.password password, u.mobile mobile, u.role_type role_type, u.company_id company_id, c.`company_name` company_name,
         u.role_name role_name,u.parent_id parent_id, u.sex sex, u.work_state work_state, u.is_disable is_disable,
-        u.indate indate, u.head_imgurl head_imgurl, u.team_name team_name, u.subordinate_type subordinate_type
+        u.indate indate, u.head_imgurl head_imgurl, u.team_name team_name, u.subordinate_type subordinate_type, u.openid, u.corp_user_id
         FROM
         tb_user AS u
         LEFT JOIN tb_company c
@@ -100,7 +103,7 @@
         SELECT
         u.id id, u.account account, u.username username, u.password password, u.mobile mobile, u.role_type role_type, u.company_id company_id, c.`company_name` company_name,
         u.role_name role_name,u.parent_id parent_id, u.sex sex, u.work_state work_state, u.is_disable is_disable,
-        u.indate indate, u.head_imgurl head_imgurl, u.team_name team_name, u.subordinate_type subordinate_type
+        u.indate indate, u.head_imgurl head_imgurl, u.team_name team_name, u.subordinate_type subordinate_type, u.openid, u.corp_user_id
         FROM
         tb_user AS u
         LEFT JOIN tb_company c
@@ -129,7 +132,7 @@
         select
           u.id id, u.account account, u.username username, u.password password, u.mobile mobile, u.role_type role_type, u.company_id company_id, c.`company_name` company_name,
           u.role_name role_name,u.parent_id parent_id, u.sex sex, u.work_state work_state, u.is_disable is_disable,
-          u.indate indate, u.head_imgurl head_imgurl, u.team_name team_name, u.subordinate_type subordinate_type,avatar, nickname, openid
+          u.indate indate, u.head_imgurl head_imgurl, u.team_name team_name, u.subordinate_type subordinate_type,avatar, nickname, openid, corp_user_id
         from
           tb_user AS u
         LEFT JOIN tb_company c
@@ -137,4 +140,10 @@
         where
           u.account = #{userVO.account}
     </select>
+    <update id="unbindWeiXin">
+        update tb_user set openid = null, avatar = null, nickname = null where head_imgurl = #{token}
+    </update>
+    <update id="unbindCorpWeiXin">
+        update tb_user set corp_user_id = null where head_imgurl = #{token}
+    </update>
 </mapper>

+ 255 - 62
cloud-socket/src/com/js/kbt/socket/UserHandler.java

@@ -1,5 +1,9 @@
 package com.js.kbt.socket;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
 import java.math.BigDecimal;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
@@ -10,10 +14,10 @@ import java.util.List;
 
 import javax.annotation.Resource;
 
+import org.apache.commons.io.FileUtils;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
-import org.springframework.util.StringUtils;
 
 import com.alibaba.fastjson.JSONObject;
 import com.js.kbt.mapper.ChangeIpCommandMapper;
@@ -38,10 +42,7 @@ import com.js.kbt.model.EquipmentSendCommand;
 import com.js.kbt.model.EquipmentSendCommandExample;
 import com.js.kbt.model.LonLatRecord;
 import com.js.kbt.model.LonLatRecordExample;
-import com.js.kbt.model.MouldDownPacket;
-import com.js.kbt.model.MouldDownPacketExample;
 import com.js.kbt.model.MouldHistory;
-import com.js.kbt.model.MouldHistoryExample;
 import com.js.kbt.model.MouldHistoryTime;
 import com.js.kbt.model.MouldHistoryTimeExample;
 import com.js.kbt.model.RecDataLog;
@@ -51,7 +52,7 @@ import com.js.kbt.model.TbMouldEquipment;
 import com.js.kbt.model.TbMouldEquipmentExample;
 import com.js.kbt.model.TbMouldExample;
 import com.js.kbt.model.TimeCalibrationRecord;
-import com.taobao.api.internal.toplink.embedded.websocket.util.StringUtil;
+import com.js.kbt.util.ByteUtils;
 
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
@@ -119,7 +120,9 @@ public class UserHandler extends SimpleChannelInboundHandler<String> {
 	private String equipmentNo = null;
 	
 	public static int RET_CMD_LENGTH = "FAAF23000106000000000000000100000000000000000000000000000000000000B2C2".length() ;
-
+	public static String REMOTE_UPDATE_START = "FAAF0D0001";
+	public static String[] ERROR = {"无故障", "异或校验失败", "CRC校验失败", "超时", "包序号不匹配", "访问失败"};
+	
 	@Override
 	protected void channelRead0(ChannelHandlerContext arg0, String arg1) throws ParseException {
 		String pack = "FAAF0007001e781e50003C37D5";
@@ -127,9 +130,81 @@ public class UserHandler extends SimpleChannelInboundHandler<String> {
 		// sendChangeIp();
 		logger.info("开始接受数据...");
 		System.out.println("收到===" + arg1 + "\n");
-		//设备回馈的指令:FAAF23000106000000000000000100000000000000000000000000000000000000B2C2
-		if (arg1.length() == RET_CMD_LENGTH
-				&&arg1.startsWith("FAAF23000106")) {
+		
+		if (arg1.startsWith(REMOTE_UPDATE_START)) {//远程升级,设备到云平台的指令
+			String cmdStr = arg1.substring(REMOTE_UPDATE_START.length(), REMOTE_UPDATE_START.length() + 2);
+			if ("01".contentEquals(cmdStr)) {
+				//MCU已准备好,可以更新;云平台下发起始帧
+				File f = new File("E:\\software\\apache-tomcat-9.0.14\\webapps\\yscloud\\files\\Mould_Mnitor.bin");
+				int packSize = 900;
+				int packCount = (int) (f.length()/packSize + (f.length()%packSize==0?0:1));
+				String startCmd = startCmd(packCount);
+				sendMsg(startCmd);
+				receiveMCUProcess(equipmentNo, arg1, "MCU已准备就绪");
+			} else if ("02".contentEquals(cmdStr)) {
+				//状态反馈
+				String errorCode = arg1.substring(REMOTE_UPDATE_START.length() + 2, REMOTE_UPDATE_START.length() + 2 + 2);
+				logger.info("状态反馈="+ERROR[Integer.parseInt(errorCode, 16)]);
+				if ("00".equals(errorCode)) {
+					//反馈成功,获取需要接受的包数,从1开始
+					String recPackPageIndex = arg1.substring(REMOTE_UPDATE_START.length() + 4*2, REMOTE_UPDATE_START.length() + 4*2 + 2*2);//9-10位
+					int packIndex = Integer.parseInt(highInFrontLowInBack(recPackPageIndex), 16);
+					logger.info("接收到packIndex=="+packIndex);
+					File f = new File("E:\\software\\apache-tomcat-9.0.14\\webapps\\yscloud\\files\\Mould_Mnitor.bin");
+					
+					try {
+						//读取到全部文件内容
+						byte[] allFileBytes = FileUtils.readFileToByteArray(f);
+						//计算整包CRC校验位
+						String fileCRC = getCRC(allFileBytes);
+						fileCRC = fillZeroLeft(fileCRC, 2);//2位
+						fileCRC = highInFrontLowInBack(fileCRC);//高低位互换
+						int totalByteSize = allFileBytes.length + 2;//加上最后的两位校验位
+						byte[] crcByte = ByteUtils.getByteFromHex(fileCRC);
+						byte[] allBytes = ByteUtils.byteMerger(allFileBytes, crcByte);
+						
+						int packSize = 900;
+						int packCount = (int) (totalByteSize/packSize + (totalByteSize%packSize==0?0:1));
+						logger.info("总包数="+packCount);
+						
+						byte[] packData = null;
+						
+						if (packIndex == packCount) {
+							//这是最后一包,按实际大小
+							int lastPackSize = (int) (totalByteSize - (packIndex -1)*packSize);
+							logger.info("最后一包size="+lastPackSize);
+							packData = new byte[lastPackSize];
+						} else {
+							packData = new byte[900];
+						}
+						//从数据包中提取
+						int start = (packIndex-1)*packSize;
+						System.arraycopy(allBytes, start, packData, 0, packData.length);  
+						//组装返回数据
+						String msg = dataCmd(packIndex, packData);
+						sendMsg(msg);
+					} catch (FileNotFoundException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					} catch (IOException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					} 
+				} else {
+					//过程中出错的需要记录下来
+					receiveMCUProcess(equipmentNo, arg1, ERROR[Integer.parseInt(errorCode, 16)]);
+				}
+				
+			} else if ("03".contentEquals(cmdStr)){
+				logger.info("=============更新成功=================");
+				receiveMCUProcess(equipmentNo, arg1, "更新成功");
+			} else if ("04".contentEquals(cmdStr)){
+				logger.info("!!!!!!!!!!!!@@更新失败@@!!!!!!!!");
+				receiveMCUProcess(equipmentNo, arg1, "更新失败");
+			}
+			
+		} else if (arg1.length() == RET_CMD_LENGTH
+				&&arg1.startsWith("FAAF23000106")) {//设备回馈的指令:FAAF23000106000000000000000100000000000000000000000000000000000000B2C2
 			//TODO: 更新设备指令下发的执行状态
 			logger.info("设备回馈指令");
 			String cmdExecuteStatusStr = arg1.substring("FAAF23000106".length());
@@ -172,9 +247,24 @@ public class UserHandler extends SimpleChannelInboundHandler<String> {
 			"2621远程更新"
 	};
 	
+	//处理远程更新指令反馈
+	private void receiveMCUProcess(String equipmentNo, String recData, String txt) {
+		EquipmentRecCommand cmd = new EquipmentRecCommand();
+		cmd.setEquipmentNo(equipmentNo);
+		cmd.setCmd(recData);
+		cmd.setCmdTxt(txt);
+		equipmentRecCommandMapper.insertSelective(cmd);
+		
+		//主表设置有新状态
+		TbMouldEquipmentExample example = new TbMouldEquipmentExample();
+		example.createCriteria().andEquipmentNoEqualTo(equipmentNo);
+		TbMouldEquipment record = new TbMouldEquipment();
+		record.setHasNewMessage(1);
+		tbMouldEquipmentMapper.updateByExampleSelective(record, example);
+	}
+	
 	//存储设备返回的执行指令
 	private void receiveCmdStatus(String str) {
-		//找到最新的一条命令匹配的记录,更新其状态为已执行。
 		EquipmentRecCommand cmd = new EquipmentRecCommand();
 		cmd.setEquipmentNo(equipmentNo);
 		cmd.setCmd(str);
@@ -187,21 +277,24 @@ public class UserHandler extends SimpleChannelInboundHandler<String> {
 			}
 		}
 		StringBuilder sb = new StringBuilder();
-		for (int i=0;i<result.size(); i++) {
-			sb.append(result.get(i));
-			if (i < result.size() -1) {
-				sb.append(",");
+		if (result.size() > 0) {
+			//有回馈的情况
+			for (int i=0;i<result.size(); i++) {
+				sb.append(result.get(i));
+				if (i < result.size() -1) {
+					sb.append(",");
+				}
 			}
+			cmd.setCmdTxt(sb.toString());
+			equipmentRecCommandMapper.insertSelective(cmd);
+			
+			//主表设置有新状态
+			TbMouldEquipmentExample example = new TbMouldEquipmentExample();
+			example.createCriteria().andEquipmentNoEqualTo(equipmentNo);
+			TbMouldEquipment record = new TbMouldEquipment();
+			record.setHasNewMessage(1);
+			tbMouldEquipmentMapper.updateByExampleSelective(record, example);
 		}
-		cmd.setCmdTxt(sb.toString());
-		equipmentRecCommandMapper.insertSelective(cmd);
-		
-		//主表设置有新状态
-		TbMouldEquipmentExample example = new TbMouldEquipmentExample();
-		example.createCriteria().andEquipmentNoEqualTo(equipmentNo);
-		TbMouldEquipment record = new TbMouldEquipment();
-		record.setHasNewMessage(1);
-		tbMouldEquipmentMapper.updateByExampleSelective(record, example);
 	}
 
 	private String processMsg(String input) throws ParseException {
@@ -310,36 +403,41 @@ public class UserHandler extends SimpleChannelInboundHandler<String> {
 			item.setAlarm(Integer.decode("0x" + string.substring(64 * 2, 65 * 2)));
 			String str = string.substring(65 * 2, 69 * 2);
 			item.setRunCnt(reverseParseHex(str));
-			LonLatRecordExample rExp = new LonLatRecordExample();
-			rExp.createCriteria().andMccEqualTo("460").andMncEqualTo("0").andGprsCiEqualTo(item.getGprsCi())
-					.andGprsLacEqualTo(item.getGprsLac());
-			List<LonLatRecord> lRList = lonLatRecordMapper.selectByExample(rExp);
-			if (lRList.size() > 0) {
-				LonLatRecord lonLatRecord = lRList.get(0);
-				item.setLng(lonLatRecord.getLng());
-				item.setLat(lonLatRecord.getLat());
-//				System.out.println("直接重用经纬度===");
-			} else {
-				// 根据基站lac和ci获取经纬度
-				String api = "http://api.cellocation.com:81/cell/?mcc=460&mnc=0&lac=" + item.getGprsLac() + "&ci="
-						+ item.getGprsCi() + "&output=json";
-				String resp = com.js.kbt.util.HttpRequest.sendGet(api, null);
-				JSONObject json = JSONObject.parseObject(resp);
-				if (json != null && json.getInteger("errcode") == 0) {
-					item.setLng(json.getDouble("lon") + "");
-					item.setLat(json.getDouble("lat") + "");
+			if (!item.getGprsCi().equals("0") && !item.getGprsLac().contentEquals("0")) {
+				LonLatRecordExample rExp = new LonLatRecordExample();
+				rExp.createCriteria().andMccEqualTo("460").andMncEqualTo("0").andGprsCiEqualTo(item.getGprsCi())
+						.andGprsLacEqualTo(item.getGprsLac());
+				logger.info("ci="+item.getGprsCi()+", lac="+item.getGprsLac());
+				List<LonLatRecord> lRList = lonLatRecordMapper.selectByExample(rExp);
+				if (lRList.size() > 0) {
+					LonLatRecord lonLatRecord = lRList.get(0);
+					item.setLng(lonLatRecord.getLng());
+					item.setLat(lonLatRecord.getLat());
+					logger.info("直接重用经纬度===");
 				} else {
-					logger.error("调用基站解析平台出错: " + resp);
+					// 根据基站lac和ci获取经纬度
+					String api = "http://api.cellocation.com:81/cell/?mcc=460&mnc=0&lac=" + item.getGprsLac() + "&ci="
+							+ item.getGprsCi() + "&output=json";
+					String resp = com.js.kbt.util.HttpRequest.sendGet(api, null);
+					JSONObject json = JSONObject.parseObject(resp);
+					logger.info("请求经纬度=" +json.toJSONString() );
+					if (json != null && json.getInteger("errcode") == 0) {
+						item.setLng(json.getDouble("lon") + "");
+						item.setLat(json.getDouble("lat") + "");
+					} else {
+						logger.error("调用基站解析平台出错: " + resp);
+					}
+					LonLatRecord latRecord = new LonLatRecord();
+					latRecord.setGprsCi(item.getGprsCi());
+					latRecord.setMcc("460");
+					latRecord.setMnc("0");
+					latRecord.setGprsLac(item.getGprsLac());
+					latRecord.setLat(item.getLat());
+					latRecord.setLng(item.getLng());
+					lonLatRecordMapper.insertSelective(latRecord);
 				}
-				LonLatRecord latRecord = new LonLatRecord();
-				latRecord.setGprsCi(item.getGprsCi());
-				latRecord.setMcc("460");
-				latRecord.setMnc("0");
-				latRecord.setGprsLac(item.getGprsLac());
-				latRecord.setLat(item.getLat());
-				latRecord.setLng(item.getLng());
-				lonLatRecordMapper.insertSelective(latRecord);
 			}
+			
 			String crcStr = string.substring(string.length() - 4);
 			item.setCrcCode("" + reverseParseHex(crcStr));
 			// 存入数据库
@@ -553,7 +651,6 @@ public class UserHandler extends SimpleChannelInboundHandler<String> {
 	}
 
 	public void timeCalibration(String equipmentNo) {
-		 logger.info("下发校准时间的云模盒equipmentNo="+equipmentNo);
 		if (equipmentNo.startsWith("FAAF")) {
 			logger.info("非法云模盒编号,不作下发处理");
 			return;
@@ -563,6 +660,7 @@ public class UserHandler extends SimpleChannelInboundHandler<String> {
 		if (count.size() == 0) {
 			//新协议
 			String hexDate = getNowDateHex();
+			logger.info("下发校准时间的云模盒equipmentNo="+equipmentNo);
 			logger.info("校准系统模块时间转成16进制的字符串==>" + hexDate);
 			sendMsg(getDownPackage(CMD_TIME_FIX, hexDate));
 			TimeCalibrationRecord timeCalibrationRecord = new TimeCalibrationRecord();
@@ -659,7 +757,7 @@ public class UserHandler extends SimpleChannelInboundHandler<String> {
 			}
 			me.setCurhillNumber(item.getBattery() + "");
 			if (org.apache.commons.lang.StringUtils.isNotEmpty(item.getLng())) {
-				logger.info("更新经纬度:");
+				logger.info("更新经纬度: lng = " + item.getLng() + ", lat=" + item.getLat());
 				me.setLng(Double.parseDouble(item.getLng()));
 				me.setLat(Double.parseDouble(item.getLat()));
 			} else {
@@ -907,16 +1005,24 @@ public class UserHandler extends SimpleChannelInboundHandler<String> {
 	}
 
 	public static void main(String[] args) throws ParseException {
-		String string = "FAAF23000106000000000000000100000000000000000000000000000000000000B2C2";
-		if (string.length() >= 25 * 2) {
-			String mobilePart = string.substring(4 * 2, 5 * 2);
-			String mobile = getStringFromHexStr(mobilePart);
-			// 获取设备编码15-24
-			String deviceNumPart = string.substring(5 * 2, 25 * 2);
-			logger.info("解析出设备deviceNumPart=" + deviceNumPart);
-			String deviceNum = getStringFromHexStr(deviceNumPart);
-			logger.info("解析出设备No=" + deviceNum);
-		} 
+//		String string = "FAAF23000106000000000000000100000000000000000000000000000000000000B2C2";
+//		if (string.length() >= 25 * 2) {
+//			String mobilePart = string.substring(4 * 2, 5 * 2);
+//			String mobile = getStringFromHexStr(mobilePart);
+//			// 获取设备编码15-24
+//			String deviceNumPart = string.substring(5 * 2, 25 * 2);
+//			logger.info("解析出设备deviceNumPart=" + deviceNumPart);
+//			String deviceNum = getStringFromHexStr(deviceNumPart);
+//			logger.info("解析出设备No=" + deviceNum);
+//		} 
+		File f = new File("C:\\Mould_Mnitor.bin");
+		System.out.println("flength=="+f.length());
+		try {
+			System.out.println("size f="+FileUtils.readFileToByteArray(f).length);
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
 	}
 	
 	private String getNowDateHex() {
@@ -939,4 +1045,91 @@ public class UserHandler extends SimpleChannelInboundHandler<String> {
 		}
 		return str;
 	}
+	
+	private static String fillZeroLeft(String str, int bitNum) {
+		int fillNum = bitNum*2-str.length();
+		for (int i=0;i< fillNum; i++) {
+			str = "0" + str;
+		}
+		return str;
+	}
+	
+	//起始帧
+	public static byte[]  getCRCByStartCmd(String cmd, String hexData) {
+		byte[] crcByte = new byte[11];
+		crcByte[0]= (byte)Integer.parseInt("FA", 16);
+		crcByte[1]= (byte)Integer.parseInt("AF", 16);
+		crcByte[2]= (byte)Integer.parseInt("0D", 16);
+		crcByte[3]= (byte)Integer.parseInt("00", 16);
+		crcByte[4]= (byte)Integer.parseInt("00", 16);//云平台至设备
+		crcByte[5]= (byte)Integer.parseInt(cmd, 16);
+		crcByte[6] = (byte)Integer.parseInt(hexData.substring(0, 2), 16);
+		crcByte[7] = (byte)Integer.parseInt(hexData.substring(2, 4), 16);
+		crcByte[8] = (byte)Integer.parseInt(hexData.substring(4, 6), 16);
+		crcByte[9] = (byte)Integer.parseInt(hexData.substring(6, 8), 16);
+		crcByte[10] = (byte)Integer.parseInt(hexData.substring(8, 10), 16);
+		return crcByte;
+	}
+	
+	//组装起始帧命令
+	private static String startCmd(int packCount) {
+		String packCountHex = Integer.toHexString(packCount);
+		packCountHex = fillZeroLeft(packCountHex, 2);
+		System.out.println(packCountHex);
+		packCountHex = highInFrontLowInBack(packCountHex);
+		
+		String str = "00 00 00 "+packCountHex;
+		str = str.replaceAll(" ", "");
+		byte[] crcBytes = getCRCByStartCmd("03", str);
+		String crcCode = getCRC(crcBytes);
+		System.out.println("crcCode=="+crcCode);
+		crcCode = highInFrontLowInBack(crcCode);
+		
+		return "FAAF0D000003" + str + crcCode;
+	}
+	
+	//十六进制转byte
+	public static byte[]  getByteFromHex(String hexStr) {
+		byte[] data = new byte[hexStr.length()/2];
+		for (int i=0;i<hexStr.length(); i+=2) {
+			data[i/2] = (byte)Integer.parseInt(hexStr.substring(i, i+2), 16);
+		}
+		
+		return data;
+	}
+	
+	//组装数据帧命令
+	private static String dataCmd(int packIndex, byte[] data) {
+		String packIndexHex = Integer.toHexString(packIndex);
+		packIndexHex = fillZeroLeft(packIndexHex, 2);
+		System.out.println("dataCmd packIndexHex =="+packIndexHex);
+		packIndexHex = highInFrontLowInBack(packIndexHex);
+		logger.info("dataCmd packIndexHex =="+packIndexHex);
+		
+		int dataLength = data.length + 10;
+		String dataLengthHex = Integer.toHexString(dataLength);
+		dataLengthHex = fillZeroLeft(dataLengthHex, 2);
+		dataLengthHex = highInFrontLowInBack(dataLengthHex);
+		logger.info("dataCmd dataLengthHex =="+dataLengthHex);
+		
+		String allStr = "FAAF"+dataLengthHex+"0004" + packIndexHex;
+		byte[] byteFromHex = getByteFromHex(allStr);
+		byte[] allBytes = new byte[byteFromHex.length + data.length];
+		for (int i=0;i<byteFromHex.length; i++) {
+			allBytes[i] = byteFromHex[i];
+		}
+		int startIndex = byteFromHex.length;
+		for (int i=0;i<data.length; i++) {
+			allBytes[i+startIndex] = data[i];
+		}
+		
+		String crcCode = getCRC(allBytes);
+		logger.info("crcCode=="+crcCode);
+		crcCode = fillZeroLeft(crcCode, 2);
+		crcCode = highInFrontLowInBack(crcCode);
+		//数据转16进制
+		String str  = BinaryToHexString(data).replaceAll(" ", "");
+		
+		return "FAAF"+dataLengthHex+"0004" + packIndexHex + str + crcCode;
+	} 
 }

+ 8 - 0
ys_int/config/index.js

@@ -36,6 +36,14 @@ module.exports = {
                 '^/api': '/' 
             }
         },
+        '/upload': {
+            target: 'http://'+ ip +':8010',  // 接口域名 开发
+            secure: true,  // 如果是https接口,需要配置这个参数
+            changeOrigin: true,  //是否跨域
+            pathRewrite: { // 如果接口本身没有api的路径,那么这里将发送到后端的请求重写为没有api的路径
+                '^/upload': '/' 
+            }
+        },
         '/ips': {    
             target: 'http://'+ ip +':8080',  // 接口域名 开发
             secure: true,  // 如果是https接口,需要配置这个参数

+ 6 - 1
ys_int/src/i18n/lang/en.js

@@ -29,6 +29,7 @@ const lang = {
 		mouldNum:"Mould Number",
 		mouldName:"Mould Name",
 		productNum:"Product Number",
+		operationSuccess: "Operation Success",
     },
     prompt: {
         success: "Modify Success",
@@ -216,6 +217,8 @@ const lang = {
 		approve: "Approve",
 		editPower: "Edit Power",
 		config: "Config Power",
+		applySendSuccess:"apply send success, please wait for audit",
+		maintain: "Maintain",
     },
 	// 模具管理
 	mold: {
@@ -260,7 +263,8 @@ const lang = {
         mathead: "Total Head Weight(g)",
         minshot: "Min Shot Amount(g)",
         maxshot: "Max Shot Amount(g)",
-        stand: "StandardMolding Cycle(s)",
+		stand: "StandardMolding Cycle(s)",
+		realPeriod: "Real Molding Cycle(s)",
         dynamic: "MaleMold Temperature(℃)",
         fiexd: "MasterMold Temperature(℃)",
         inputmaterial: "Please enter Material Grade",
@@ -352,6 +356,7 @@ const lang = {
 	},
     // 基础管理
     basic: {
+		changeAdminTitle:"Change Admin",
 		select:"Please Select",
 		input: "Please Input",
         next: "Next",

+ 8 - 4
ys_int/src/i18n/lang/zh.js

@@ -29,6 +29,7 @@ const lang = {
 		mouldNum:"模具编号",
 		mouldName:"模具名称",
 		productNum:"产品编号",
+		operationSuccess: "操作成功",
     },
     prompt: {
         success: "修改成功",
@@ -216,7 +217,8 @@ const lang = {
 		approve: "审批",
 		editPower: "编辑权限",
 		config: "权限配置",
-		
+		applySendSuccess:"删除申请已发出,等待资产方和生产方管理员审批",
+		maintain: "保养",
     },
 	// 模具管理
 	mold: {
@@ -262,6 +264,7 @@ const lang = {
         minshot: "最小射胶量(g)",
         maxshot: "最大射胶量(g)",
         stand: "标准成型周期(s)",
+        realPeriod: "实际成型周期(s)",
         dynamic: "公模(动模)模温(℃)",
         fiexd: "母模(定模)模温(℃)",
         inputmaterial: "请输入材料牌号",
@@ -293,14 +296,14 @@ const lang = {
 		downloadMould: "下载模板",
 		batchImport: "批量导入",
 		apply: "申请",
-		moldFile: "模具档",
+		moldFile: "模具档",
 		state0: "生产方审核不通过",
 		state1: "资产方审核不通过",
 		state2: "待双方审核",
 		state3: "待生产方审核",
 		state4: "待资产方审核",
 		state5: "审核通过",
-		componentsFile: "零件文档",
+		componentsFile: "易损件清单",
 		partNo: "零件编号",
 		partName: "零件名称",
 		partLife: "寿命次数",
@@ -308,7 +311,7 @@ const lang = {
 		no: "否",
 		test: "试模及验收",
 		plan: "保养方案",
-		update: "模具更新",
+		update: "模具履历",
 		applicant: "申请人",
 		applicationTime: "申请时间",
 		updateM: "更新模具",
@@ -353,6 +356,7 @@ const lang = {
 	},
     // 基础管理
     basic: {
+		changeAdminTitle:"修改管理员",
 		select:"请选择",
 		input: "请输入",
         next: "下一步",

+ 56 - 4
ys_int/src/views/Login.vue

@@ -25,7 +25,46 @@
         <div class="login-backImg">
             <img src="../assets/image/login_center.png" />
         </div>
-        
+        <!-- 用户使用协议-->
+        <el-dialog title="用户使用协议" v-if="agreementVisible" :visible.sync="agreementVisible" :close-on-click-modal="false" >
+			<div>
+                <p>任何使用由南京塑维网络科技有限公司提供的云模盒系统服务的用户均应仔细阅读本协议:</p>
+ <p>1、使用规则</p>
+ <p>用户在使用云模盒系统(以下简称“本系统”)服务过程中,必须遵循以下原则:</p>
+ <p>(a) 遵守中国有关的法律和法规;</p>
+ <p>(b) 不得为任何非法目的而使用本系统服务;</p>
+ <p>(c) 遵守所有与网络服务有关的网络协议、规定和程序;</p>
+ <p>(d) 不得利用本系统进行任何可能对互联网的正常运转造成不利影响的行为;</p>
+ <p>(e) 不得利用本系统传输任何骚扰性的、中伤他人的、辱骂性的、恐吓性的、庸俗淫秽的或其他任何非法的信息资料;</p>
+ <p>(f) 不得利用本系统进行任何不利于塑维科技的行为;</p>
+ <p>(g) 如发现任何非法使用用户帐号或帐号出现安全漏洞的情况,应立即通告南京塑维网络科技有限公司(以下简称“塑维科技”)。</p>
+ <p>(h)用户必须保证其发布信息的真实性,并承担相关责任,该等法律责任与塑维科技无关。用户应承担任何有可能产生的民事侵权或刑事法律责任,本网站之法律声明的修改权、更新权及最终解释权均属于塑维科技所有。</p>
+ <p>2、内容所有权</p>
+ <p>(a) 塑维科技提供的系统服务内容可能包括:文字、图片、图表等。所有这些内容受版权、商标和其它财产所有权法律的保护。</p>
+ <p>(b) 用户只有在获得塑维科技或其他相关权利人的授权之后才能使用这些内容,而不能擅自复制、再造这些内容、或创造与内容有关的派生产品。</p>
+ <p>3、隐私保护</p>
+  <p>   3.1 保护用户隐私是塑维科技的一项基本政策,塑维科技保证不对外公开或向第三方提供用户注册资料及用户在使用网络服务时存储在塑维科技的非公开内容,但下列情况除外:</p>
+     <p>(a) 事先获得用户的明确授权;</p>
+    <p> (b) 根据有关的法律法规要求;</p>
+    <p> (c) 按照相关政府主管部门的要求;</p>
+    <p> (d) 为维护社会公众的利益;</p>
+    <p> (e) 为维护塑维科技的合法权益。</p>
+    <p> 3.2 塑维科技可能会与第三方合作向用户提供相关的网络服务,在此情况下,如该第三方同意承担与塑维科技同等的保护用户隐私的责任,则塑维科技可将用户的账户资料等提供给该第三方。</p>
+     <p>3.3 在不透露单个用户隐私资料的前提下,塑维科技有权对整个用户数据库进行分析并对用户数据库进行商业上的利用。</p>
+     <p>3.4 塑维科技有权删除相关不实不利信息,对不良用户,塑维科技有权停止其使用网络服务。</p>
+ <p>4、免责声明</p>
+     <p>(a) 因黑客攻击、通讯线路、系统升级等任何技术原因导致用户不能正常使用本服务,塑维科技不承担任何法律责任。</p>
+     <p>(b) 凡以任何方式登陆云模盒或直接、间接使用云模盒系统,视为自愿接受本协议的约束。所存在的风险将完全由其自己承担;因其使用本系统而产生的一切后果也由其自己承担,塑维科技对用户不承担任何责任。</p>
+     <p>(c) 塑维科技不担保本系统服务一定能满足用户的要求,也不担保本系统服务不会中断,对本系统服务的及时性、安全性、准确性也都不作担保。</p>
+    <p> (d)本声明未涉及的问题参见国家有关法律法规,当本声明与国家法律法规冲突时,以国家法律法规为准。</p>
+     <p>(e) 塑维科技之声明以及其修改权、更新权及最终解释权均属成塑维科技所有。</p>
+
+			</div>
+			<div slot="footer" class="dialog-footer">
+				<el-button @click.native="agreementVisible = false">不同意</el-button>
+				<el-button type="primary" @click.native="agree" >同意</el-button>
+			</div>
+		</el-dialog>
     </div>
 </template>
 
@@ -44,11 +83,13 @@
                 }
             };
             return {
+                agreementVisible: false,
                 logining: false,
                 // 登录信息
                 ruleForm: {
                     account: '',
-                    password: ''
+                    password: '',
+                    checkFirst: true,
                 },
                 rules: {
                     account: [
@@ -61,6 +102,12 @@
             };
         },
         methods: {
+            //同意协议
+            agree() {
+                this.agreementVisible = false;
+                this.ruleForm.checkFirst = false;
+                this.handleSubmit();
+            },
             handleReset2() {
                 this.$refs.ruleForm.resetFields();
             },
@@ -88,8 +135,13 @@
                         this.http.post(this.port.manage.login, this.ruleForm , res => {
                             this.logining = false;
                             if (res.code == "ok") {
-                                sessionStorage.setItem('user', JSON.stringify(res.data));
-                                this.$router.push({ path: '/map' });
+                                //确认用户协议后,才能进入系统
+                                if (res.data.firstLogin == true) {
+                                    this.agreementVisible = true;
+                                } else {
+                                    sessionStorage.setItem('user', JSON.stringify(res.data));
+                                    this.$router.push({ path: '/map' });
+                                }
                             } else {
                                 this.$message({
                                     message: res.msg,

+ 164 - 2
ys_int/src/views/base/comp.vue

@@ -22,7 +22,8 @@
             </el-table-column>
             <el-table-column prop="administrator" :label="$t('basic.assManager')" width="150" sortable>
                 <template slot-scope="scope">
-                    <router-link to="/staff" tag="span" style="cursor: pointer; color: #409eff;">{{scope.row.administrator}}</router-link>
+                    <router-link :to="'/staff?name='+scope.row.administrator" tag="span" style="cursor: pointer; color: #409eff;">{{scope.row.administrator}}</router-link>
+                    <i @click="modifyAdmin(scope.row)" class="el-icon-edit" style="margin-left:10px;cursor: pointer;color: #409eff;"></i>
                 </template>
             </el-table-column>
             <el-table-column prop="relateCompanyList" :label="$t('basic.assProducer')" sortable>
@@ -110,6 +111,41 @@
 				<el-button type="primary" @click.native="editSubmit" :loading="editLoading">{{$t('el.messagebox.confirm')}}</el-button>
 			</div>
 		</el-dialog>
+        
+        <!-- 修改管理员 -->
+        <el-dialog :title="changeAdminTitle" v-if="changeAdminVisible" :visible.sync="changeAdminVisible" :close-on-click-modal="false" customClass='customWidth'>
+			
+            <el-tabs v-model="activeName" >
+                <el-tab-pane label="选择已有人员" name="first">
+                    <el-select v-model="selectUserId" filterable placeholder="请选择">
+                        <el-option
+                        v-for="item in options"
+                        :key="item.value"
+                        :label="item.label"
+                        :value="item.value">
+                        </el-option>
+                    </el-select>
+                </el-tab-pane>
+                <el-tab-pane label="新建为管理员" name="second">
+                    <el-form :model="adminForm" :rules="formRules" ref="adminForm">
+                        <el-form-item label-width="80px" :label="$t('project.name')" prop="username" >
+                            <el-input v-model="adminForm.username" autocomplete="off" :placeholder="$t('project.inputName')"></el-input>
+                        </el-form-item>
+                        <el-form-item label-width="80px" :label="$t('project.mobile')" prop="account" >
+                            <el-input v-model="adminForm.account" autocomplete="off" :placeholder="$t('project.inputMobile')"></el-input>
+                        </el-form-item>
+                        <el-form-item label-width="80px" :label="$t('project.role')" >
+                            <el-input v-model="adminForm.roleName" autocomplete="off" :placeholder="$t('project.inputRole')"></el-input>
+                        </el-form-item>
+                    </el-form>
+                </el-tab-pane>
+            </el-tabs>
+            
+			<div slot="footer" class="dialog-footer">
+				<el-button @click.native="changeAdminVisible = false">{{$t('el.messagebox.cancel')}}</el-button>
+				<el-button type="primary" @click.native="confirmChange" :loading="addLoading">{{$t('el.messagebox.confirm')}}</el-button>
+			</div>
+		</el-dialog>
 	</section>
 </template>
 
@@ -197,6 +233,7 @@
 				},
                 
                 // 编辑界面
+                changeAdminTitle: this.$t('basic.changeAdminTitle'),
 				editFormVisible: false,
                 editLoading: false,
 				editForm: {
@@ -206,10 +243,135 @@
                     companyAddress: '',
                     companyIds: [],
                     flag: 1
-				}
+                },
+                
+                //修改管理员
+                activeName:'first',
+                changeAdminVisible:false,
+                selectUserId:null,
+                options:[],
+                adminForm: {
+                    username: '',
+                    account: '',
+                    companyId: '',
+                    roleName: this.$t('basic.system'),
+				},
 			}
 		},
 		methods: {
+            confirmChange() {
+                console.log(this.selectUserId);
+                if (this.activeName == 'first') {
+                    if (this.selectUserId == null) {
+                        this.$message({message:'请选择人员', type:'error'});
+                        return;
+                    }
+                    var username = null;
+                    console.log('options size=='+this.options.length);
+                    this.options.forEach(o=>{
+                        if (o.value == this.selectUserId) {
+                            username = o.label;
+                        }
+                    })
+                    //选择人员进行切换
+                    this.http.post('/company/changeAdmin', {
+                        companyId: this.adminForm.companyId,
+                        userId: this.selectUserId,
+                        username: username,
+
+                    }, res => {
+                        if (res.code == "ok") {
+                            this.getComp();
+                            this.changeAdminVisible = false;
+                        } else {
+                            this.$message({
+                                message: res.msg,
+                                type: 'error'
+                            });
+                        }
+                    }, error => {
+                        this.$message({
+                            message: error,
+                            type: 'error'
+                        });
+                    })
+
+                } else {
+                    //创建新的管理员
+                    if (this.$refs.adminForm.validate((valid)=>{
+                        if (valid) {
+                            //必填项都填了
+                            this.http.post("/user/addNewAdmin", {
+                                username: this.adminForm.username,
+                                account: this.adminForm.account,
+                                companyId: this.adminForm.companyId,
+                                roleName: this.adminForm.roleName,
+                                parentId: this.user.id,
+                                addType: 0,
+                                flag: 0
+                            } , res => {
+                                this.addLoading = false;
+                                if (res.code == "ok") {
+                                    this.changeAdminVisible = false;
+                                    this.$message({
+                                        message: this.$t('prompt.success2'),
+                                        type: 'success'
+                                    });
+                                    this.getComp();
+                                } else {
+                                    this.$message({
+                                        message: res.msg,
+                                        type: 'error'
+                                    });
+                                }
+                            }, error => {
+                                this.addLoading = false;
+                                this.addFormVisible = false;
+                                this.$message({
+                                    message: error,
+                                    type: 'error'
+                                });
+                            })
+                        }
+                    }));
+                }
+
+                
+            },
+            modifyAdmin(item) {
+                console.log(item);
+                this.selectUserId = item.administratorId;
+                this.adminForm.companyId = item.id;
+                this.adminForm.username = '',
+                this.adminForm.account = '';
+                this.changeAdminVisible = true;
+                this.getMembersByProducer(item.id);
+            },
+            getMembersByProducer(companyId) {
+                this.options = [];
+                this.http.post('/user/getUserListByCompanyId', {
+                    companyId: companyId
+                }, res => {
+                    if (res.code == "ok") {
+                        var companys = res.data;
+                        //解析
+                        companys.forEach(c=>{
+                            var op = {label:c.username, value:c.id}
+                            this.options.push(op);
+                        });
+                    } else {
+                        this.$message({
+                            message: res.msg,
+                            type: 'error'
+                        });
+                    }
+                }, error => {
+                    this.$message({
+                        message: error,
+                        type: 'error'
+                    });
+                })
+            },
             //  分页
 			handleCurrentChange(val) {
 				this.page = val;

+ 166 - 3
ys_int/src/views/base/factory.vue

@@ -22,6 +22,7 @@
             <el-table-column prop="administrator" :label="$t('basic.proManager')" width="150" sortable>
                 <template slot-scope="scope">
                     <router-link :to="'/staff?name='+scope.row.administrator" tag="span" style="cursor: pointer; color: #409eff;">{{scope.row.administrator}}</router-link>
+                    <i @click="modifyAdmin(scope.row)" class="el-icon-edit" style="margin-left:10px;cursor: pointer;color: #409eff;"></i>
                 </template>
             </el-table-column>
             <el-table-column prop="relateCompanyList" :label="$t('basic.proAsset')" sortable>
@@ -33,7 +34,7 @@
                 </template>
             </el-table-column>
             <el-table-column prop="companyAddress" :label="$t('basic.proAddress')" sortable></el-table-column>
-			<el-table-column :label="$t('base.operate')" width="200">
+			<el-table-column :label="$t('base.operate')" width="240">
 				<template slot-scope="scope">
 					<el-button size="small" @click.native="showDetail(scope.row.id)">{{$t('base.detail')}}</el-button>
 					<el-button size="small" @click.native="handleEdit(scope.$index, scope.row)">{{$t('base.edit')}}</el-button>
@@ -185,6 +186,41 @@
 				<el-button type="primary" @click.native="editSubmit" :loading="editLoading">{{$t('el.messagebox.confirm')}}</el-button>
 			</div>
 		</el-dialog>
+
+        <!-- 修改管理员 -->
+        <el-dialog :title="changeAdminTitle" v-if="changeAdminVisible" :visible.sync="changeAdminVisible" :close-on-click-modal="false" customClass='customWidth'>
+			
+            <el-tabs v-model="activeName" >
+                <el-tab-pane label="选择已有人员" name="first">
+                    <el-select v-model="selectUserId" filterable placeholder="请选择">
+                        <el-option
+                        v-for="item in options"
+                        :key="item.value"
+                        :label="item.label"
+                        :value="item.value">
+                        </el-option>
+                    </el-select>
+                </el-tab-pane>
+                <el-tab-pane label="新建为管理员" name="second">
+                    <el-form :model="adminForm" :rules="formRules" ref="adminForm">
+                        <el-form-item label-width="80px" :label="$t('project.name')" prop="username" >
+                            <el-input v-model="adminForm.username" autocomplete="off" :placeholder="$t('project.inputName')"></el-input>
+                        </el-form-item>
+                        <el-form-item label-width="80px" :label="$t('project.mobile')" prop="account" >
+                            <el-input v-model="adminForm.account" autocomplete="off" :placeholder="$t('project.inputMobile')"></el-input>
+                        </el-form-item>
+                        <el-form-item label-width="80px" :label="$t('project.role')" >
+                            <el-input v-model="adminForm.roleName" autocomplete="off" :placeholder="$t('project.inputRole')"></el-input>
+                        </el-form-item>
+                    </el-form>
+                </el-tab-pane>
+            </el-tabs>
+            
+			<div slot="footer" class="dialog-footer">
+				<el-button @click.native="changeAdminVisible = false">{{$t('el.messagebox.cancel')}}</el-button>
+				<el-button type="primary" @click.native="confirmChange" :loading="addLoading">{{$t('el.messagebox.confirm')}}</el-button>
+			</div>
+		</el-dialog>
 	</section>
 </template>
 
@@ -229,7 +265,7 @@
 				filters: {
                     keyName: ''
                 },
-
+                
                 user: JSON.parse(sessionStorage.getItem('user')),
                 companys:[],
 				list: [],
@@ -263,6 +299,7 @@
                 addLoading: false,
                 addState: true,
                 addTitle: this.$t('basic.addProducer'),
+                changeAdminTitle: this.$t('basic.changeAdminTitle'),
 				addForm: {
                     companyName: '',
                     companyType: 1,
@@ -300,10 +337,136 @@
                     prop:'',
                     runningTime:'',
                     area:'',
-				}
+                },
+                
+                //修改管理员
+                activeName:'first',
+                changeAdminVisible:false,
+                selectUserId:null,
+                options:[],
+                adminForm: {
+                    username: '',
+                    account: '',
+                    companyId: '',
+                    roleName: this.$t('basic.system'),
+				},
 			}
 		},
 		methods: {
+            confirmChange() {
+                console.log(this.selectUserId);
+                if (this.activeName == 'first') {
+                    if (this.selectUserId == null) {
+                        this.$message({message:'请选择人员', type:'error'});
+                        return;
+                    }
+                    var username = null;
+                    console.log('options size=='+this.options.length);
+                    this.options.forEach(o=>{
+                        if (o.value == this.selectUserId) {
+                            username = o.label;
+                        }
+                    })
+                    //选择人员进行切换
+                    this.http.post('/company/changeAdmin', {
+                        companyId: this.adminForm.companyId,
+                        userId: this.selectUserId,
+                        username: username,
+
+                    }, res => {
+                        if (res.code == "ok") {
+                            this.getFactory();
+                            this.changeAdminVisible = false;
+                        } else {
+                            this.$message({
+                                message: res.msg,
+                                type: 'error'
+                            });
+                        }
+                    }, error => {
+                        this.$message({
+                            message: error,
+                            type: 'error'
+                        });
+                    })
+
+                } else {
+                    //创建新的管理员
+                    console.log('=============add new Admin=======');
+                    if (this.$refs.adminForm.validate((valid)=>{
+                        if (valid) {
+                            //必填项都填了
+                            this.http.post("/user/addNewAdmin", {
+                                username: this.adminForm.username,
+                                account: this.adminForm.account,
+                                companyId: this.adminForm.companyId,
+                                roleName: this.adminForm.roleName,
+                                parentId: this.user.id,
+                                addType: 0,
+                                flag: 0
+                            } , res => {
+                                this.addLoading = false;
+                                if (res.code == "ok") {
+                                    this.changeAdminVisible = false;
+                                    this.$message({
+                                        message: this.$t('prompt.success2'),
+                                        type: 'success'
+                                    });
+                                    this.getFactory();
+                                } else {
+                                    this.$message({
+                                        message: res.msg,
+                                        type: 'error'
+                                    });
+                                }
+                            }, error => {
+                                this.addLoading = false;
+                                this.addFormVisible = false;
+                                this.$message({
+                                    message: error,
+                                    type: 'error'
+                                });
+                            })
+                        }
+                    }));
+                }
+
+                
+            },
+            modifyAdmin(item) {
+                console.log(item);
+                this.selectUserId = item.administratorId;
+                this.adminForm.companyId = item.id;
+                this.adminForm.username = '',
+                this.adminForm.account = '';
+                this.changeAdminVisible = true;
+                this.getMembersByProducer(item.id);
+            },
+            getMembersByProducer(companyId) {
+                this.options = [];
+                this.http.post('/user/getUserListByCompanyId', {
+                    companyId: companyId
+                }, res => {
+                    if (res.code == "ok") {
+                        var companys = res.data;
+                        //解析
+                        companys.forEach(c=>{
+                            var op = {label:c.username, value:c.id}
+                            this.options.push(op);
+                        });
+                    } else {
+                        this.$message({
+                            message: res.msg,
+                            type: 'error'
+                        });
+                    }
+                }, error => {
+                    this.$message({
+                        message: error,
+                        type: 'error'
+                    });
+                })
+            },
             //  分页
 			handleCurrentChange(val) {
 				this.page = val;

+ 7 - 5
ys_int/src/views/detection/detection.vue

@@ -3,11 +3,12 @@
         <!--工具条-->
         <el-col :span="24" class="toolbar" style="padding-bottom: 0px;">
             <el-form :inline="true" :model="filters">
-                <el-col :span="2">
+                <el-col :span="3">
                     <el-form-item>
                         <el-select v-model="filters.value" :placeholder="$t('base.choose')">
-                            <el-option :label="$t('base.num')" value="0"></el-option>
-                            <el-option :label="$t('base.name')" value="1"></el-option>
+                            <el-option :label="$t('base.mouldNum')" value="0"></el-option>
+                            <el-option :label="$t('base.mouldName')" value="1"></el-option>
+                            <el-option :label="$t('base.productNum')" value="2"></el-option>
                         </el-select>
                     </el-form-item>
                 </el-col>
@@ -36,7 +37,8 @@
                 </template>
             </el-table-column>
             
-            <el-table-column prop="ocCycle" :label="$t('mold.ocCycle')" align="center" width="140" sortable></el-table-column>
+            <el-table-column prop="ocCycle" :label="$t('mold.ocCycle')" align="center" width="140" sortable>
+            </el-table-column>
             <el-table-column prop="hillNumber" :label="$t('mold.hillNumber')" align="center" width="80" sortable>
                 <template slot-scope="scope">{{scope.row.hillNumber}}<span v-if="scope.row.hillNumber">%</span></template>
             </el-table-column>
@@ -53,7 +55,7 @@
             <el-table-column prop="produceCompany" :label="$t('mold.factoryName')" width="300" sortable></el-table-column>
             
             <el-table-column prop="area" :label="$t('mold.area')" width="300" sortable></el-table-column>
-            <el-table-column prop="equipmentNo" label="CCID" width="180" sortable></el-table-column>
+            <!-- <el-table-column prop="equipmentNo" label="CCID" width="180" sortable></el-table-column> -->
             <el-table-column prop="equipmentName" :label="$t('basic.proNum')" width="180" sortable></el-table-column>
             
             <!-- <el-table-column prop="equipmentNo" :label="$t('basic.equipmentNo')" width="180" sortable></el-table-column> -->

+ 27 - 2
ys_int/src/views/detection/maintenance.vue

@@ -28,7 +28,7 @@
                 <span v-if="requirement" style="color: #ff4949;">{{$t('runTest.isMaintain0')}}</span>
                 <span v-else style="color: black;">{{$t('runTest.isMaintain1')}}</span>
                 <el-button size="small" type="primary" @click="showMaintenance" style="margin-left: 16px;"
-                    v-if="requirement">
+                    v-if="requirement&&canMaintain">
                     {{$t('runTest.immediate')}}
                 </el-button>
             </el-col>
@@ -340,10 +340,34 @@
 
                 checkList: [this.$t('runTest.maxOpenCycle'),this.$t('runTest.minOpenCycle'),this.$t('runTest.avgOpenCycle'),this.$t('runTest.theoryCycle')],
                 option: null,
-
+                canMaintain:false,
             };
         },
         methods: {
+            getPower() {
+                this.http.post("/power/getByProject", {projectId:this.detail.projectId, userId:this.user.id},
+                res => {
+                    if (res.code == "ok") {
+                        var list = res.data;
+                        list.forEach(item=>{
+                            if (item.powerType == 4) {
+                                this.canMaintain = true;
+                            }
+                        })
+                    } else {
+                        this.$message({
+                            message: res.msg,
+                            type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            },
             //跳转到模具详情
             toMould(id) {
                 this.$router.push("/moldList/" + id + "/0");
@@ -452,6 +476,7 @@
                     if (res.code == "ok") {
                         this.detail = res.data.vo;
                         this.getEcharts();
+                        this.getPower();
                         this.mouldName = res.data.vo.modelName;
                         this.mouldState = res.data.vo.state;
                         this.requirement = res.data.vo.isMaintain == 1;

+ 200 - 21
ys_int/src/views/mold/moldDetail.vue

@@ -24,7 +24,7 @@
                 </el-form-item>
                 
                 <el-form-item class="state" style="margin-right:30px;">
-                    <el-tooltip v-if="moldDetail.moveApplyState > 0" class="item" effect="light" :content="'原因:'+moldDetail.moveApplyReason" placement="bottom">
+                    <el-tooltip v-if="moldDetail.moveApplyState > 0" class="item" effect="light" :content="'原因:'+moldDetail.moveApplyReason+', 时间:'+moldDetail.moveApplyTime+', 地点:'+ moldDetail.moveApplyAddress+(moldDetail.moveApplyProducerId !=null?',生产方:'+moldDetail.moveApplyProducerName:'')" placement="bottom">
                         <span 
                             :style="'color:' +['black','orange','green','red'][moldDetail.moveApplyState] "
                             >
@@ -35,7 +35,7 @@
                     
                     <!--项目经理负责申请移模-->
                     <span v-if="(moldDetail.managerId == user.id) && (moldDetail.moveApplyState==0||moldDetail.moveApplyState==3)">
-                        <el-button @click="moveDialogVisible=true">申请移模</el-button>
+                        <el-button @click="moveDialogVisible=true;producer=moldDetail.produceCompanyId">申请移模</el-button>
                     </span>
                     <!-- 移模同意后,项目经理可以完成移模,重置为正常状态 -->
                     <span v-if="(moldDetail.managerId == user.id) && (moldDetail.moveApplyState==2)">
@@ -54,7 +54,7 @@
         <el-col :span="24" :style="allDetail">
             <el-col :span="24" class="title">
                 {{$t('mold.moldDetail')}}
-                <!-- <i class="el-icon-edit editDetail" v-if="user.id == moldDetail.managerId || user.id == moldDetail.creatorId" @click="edit"></i> -->
+                <i class="el-icon-edit editDetail" v-if="user.id == moldDetail.managerId || user.id == moldDetail.creatorId" @click="edit"></i>
             </el-col>
 
             <el-col :span="24" class="main">
@@ -159,6 +159,10 @@
                     {{$t('mold.stand')}}:
                     <span class="info">{{moldDetail.injectionMolding==null?'':moldDetail.injectionMolding.cycle}}</span>
                 </el-col>
+                <el-col :span="6" class="detail">
+                    {{$t('mold.realPeriod')}}:
+                    <span class="info" :style="'color:'+(moldDetail.ocCycle != null && moldDetail.injectionMolding != null&&(moldDetail.ocCycle - moldDetail.injectionMolding.cycle > 5 || moldDetail.ocCycle - moldDetail.injectionMolding.cycle < -5 )?'red':'')">{{moldDetail.ocCycle==null?'':moldDetail.ocCycle}}</span>
+                </el-col>
                 <el-col :span="6" class="detail">
                     {{$t('mold.dynamic')}}:
                     <span class="info">{{moldDetail.injectionMolding==null?'':moldDetail.injectionMolding.commonModelTemperature}}</span>
@@ -252,6 +256,11 @@
                                     <span v-else-if="scope.row.state == 1">{{$t('mold.state3')}}</span>
                                     <span v-else-if="scope.row.state == 2">{{$t('mold.state4')}}</span>
                                     <span v-else-if="scope.row.state == 3">{{$t('mold.state5')}}</span>
+                                    <span v-else-if="scope.row.state == 4">删除待审批</span>
+                                    <span v-else-if="scope.row.state == 5">删除待生产方审核</span>
+                                    <span v-else-if="scope.row.state == 6">删除待资产方审核</span>
+                                    <span v-else-if="scope.row.state == -5">资产方不同意删除</span>
+                                    <span v-else-if="scope.row.state == -6">生产方不同意删除</span>
                                 </template>
                             </el-table-column>
                             <el-table-column :label="$t('base.operate')" width="200" align="center" sortable>
@@ -259,12 +268,20 @@
                                     <el-button size="small" @click="checkOpen(scope.row)"
                                         v-if="approve == 1 && (scope.row.state == 0 || (scope.row.state == 1 && user.subordinateType == 1) || (scope.row.state == 2 && user.subordinateType == 0))" 
                                     >{{$t('project.approve')}}</el-button>
+                                    <!--删除审核-->
+                                    <el-button size="small" @click="checkOpen(scope.row)"
+                                        v-if="approve == 1 && (scope.row.state == 4 || (scope.row.state == 5 && user.subordinateType == 1) || (scope.row.state == 6 && user.subordinateType == 0))" 
+                                    >{{$t('project.approve')}}</el-button>
                                     <a :href="scope.row.fileUrl" :download="scope.row.fileName" v-if="download == 1 && scope.row.state == 3">
                                         <el-button size="small" @click="dowloadfile(scope.row.id)">{{$t('project.download')}}</el-button>
                                     </a>
                                     <el-button size="small" 
-                                        v-if="(scope.row.uplodtorId == user.id && scope.row.state <= 0) || (scope.row.state == 3 && user.parentId == 1 && user.subordinateType == 0)" 
+                                        v-if="(scope.row.uplodtorId == user.id && scope.row.state <= 0 && scope.row.state > -5) || (scope.row.state == 3 && user.parentId == 1 && user.subordinateType == 0)" 
                                         @click="deleteFile(scope.row.id)" type="danger">{{$t('el.upload.delete')}}</el-button>
+                                    <!-- 资产方管理员可直接删除,不需要申请 -->
+                                    <el-button size="small" 
+                                        v-if="(scope.row.uplodtorId == user.id && scope.row.state == 3 && !(user.parentId == 1 && user.subordinateType == 0))" 
+                                        @click="applyDeleteFile(scope.row.id)" type="danger">{{$t('mold.applyDelete')}}</el-button>
                                     
                                 </template>
                             </el-table-column>
@@ -289,7 +306,7 @@
                                 <template slot-scope="scope" v-if="scope.row.part3dFile != null">
                                     <!-- <a v-if="scope.row.state == 3 && download == 1" class="download" :href="scope.row.part3dFile.fileUrl" target="_blank">{{scope.row.part3dFile.fileName}}</a> 
                                     <span v-else>{{scope.row.part2dFile.fileName}}</span> -->
-                                    <el-link v-if="view == 1" type="primary" @click="viewFile(scope.row)">{{scope.row.part3dFile.fileName}}</el-link>
+                                    <el-link v-if="view == 1" type="primary" @click="viewFile(scope.row, 3)">{{scope.row.part3dFile.fileName}}</el-link>
                                     <span v-else>{{scope.row.part3dFile.fileName}}</span>
                                 </template>
                             </el-table-column>
@@ -297,7 +314,7 @@
                                 <template slot-scope="scope" v-if="scope.row.part2dFile != null">
                                     <!-- <a v-if="scope.row.state == 3 && download == 1" class="download" :href="scope.row.part2dFile.fileUrl" :download="scope.row.part2dFile.fileName">{{scope.row.part2dFile.fileName}}</a>
                                     <span v-else>{{scope.row.part2dFile.fileName}}</span> -->
-                                    <el-link v-if="view == 1" type="primary" @click="viewFile(scope.row)">{{scope.row.part2dFile.fileName}}</el-link>
+                                    <el-link v-if="view == 1" type="primary" @click="viewFile(scope.row, 2)">{{scope.row.part2dFile.fileName}}</el-link>
                                     <span v-else>{{scope.row.part2dFile.fileName}}</span>
                                 </template>
                             </el-table-column>
@@ -310,15 +327,21 @@
                                     <span v-else-if="scope.row.state == 1">{{$t('mold.state3')}}</span>
                                     <span v-else-if="scope.row.state == 2">{{$t('mold.state4')}}</span>
                                     <span v-else-if="scope.row.state == 3">{{$t('mold.state5')}}</span>
+                                    <span v-else-if="scope.row.state == 4">删除待审批</span>
+                                    <span v-else-if="scope.row.state == 5">删除待生产方审核</span>
+                                    <span v-else-if="scope.row.state == 6">删除待资产方审核</span>
+                                    <span v-else-if="scope.row.state == -5">资产方不同意删除</span>
+                                    <span v-else-if="scope.row.state == -6">生产方不同意删除</span>
                                 </template>
                             </el-table-column>
-                            <el-table-column :label="$t('base.operate')" width="200" align="center" sortable>
+                            <el-table-column :label="$t('base.operate')" width="250" align="center" sortable>
                                 <template slot-scope="scope">
                                     <el-button size="small" 
                                         v-if="approve == 1 && (scope.row.state == 0 
                                             || (scope.row.state == 1 && user.subordinateType == 1) 
                                             || (scope.row.state == 2 && user.subordinateType == 0))" 
                                         @click="checkOpenPort(scope.row)">{{$t('project.approve')}}</el-button>
+                                    
                                     <el-button size="small" @click="editPort(scope.row)" v-if="scope.row.creatorId == user.id">
                                         {{$t('base.edit')}}
                                     </el-button>
@@ -328,14 +351,17 @@
                                     </el-button>
                                     <el-button size="small" 
                                         v-if="scope.row.state == 3 && user.parentId == 1 && user.subordinateType == 0"  
-                                        @click="deleteFile(scope.row.id)" type="danger">{{$t('mold.applyDelete')}}</el-button>
+                                        @click="deleteFile(scope.row.id)" type="danger">{{$t('el.upload.delete')}}</el-button>
+                                    <!-- <el-button size="small" 
+                                        v-if="(scope.row.creatorId == user.id && scope.row.state == 3)" 
+                                        @click="applyDeleteFile(scope.row.id)" type="danger">{{$t('mold.applyDelete')}}</el-button> -->
                                 </template>
                             </el-table-column>
                         </el-table>
                     </el-tab-pane>
 
                     <!-- 试模及验收 -->
-                    <el-tab-pane :label="$t('mold.test')" name="2">
+                    <!-- <el-tab-pane :label="$t('mold.test')" name="2">
                         <el-table :data="documents.check" highlight-current-row v-loading="listLoading" style="width: 100%;">
                             <el-table-column type="index" width="40"></el-table-column>
                             <el-table-column :label="$t('project.fileName')" sortable>
@@ -355,6 +381,11 @@
                                     <span v-else-if="scope.row.state == 1">{{$t('mold.state3')}}</span>
                                     <span v-else-if="scope.row.state == 2">{{$t('mold.state4')}}</span>
                                     <span v-else-if="scope.row.state == 3">{{$t('mold.state5')}}</span>
+                                    <span v-else-if="scope.row.state == 4">删除待审批</span>
+                                    <span v-else-if="scope.row.state == 5">删除待生产方审核</span>
+                                    <span v-else-if="scope.row.state == 6">删除待资产方审核</span>
+                                    <span v-else-if="scope.row.state == -5">资产方不同意删除</span>
+                                    <span v-else-if="scope.row.state == -6">生产方不同意删除</span>
                                 </template>
                             </el-table-column>
                             <el-table-column :label="$t('base.operate')" width="200" sortable>
@@ -362,16 +393,23 @@
                                     <el-button size="small" 
                                         v-if="approve == 1 && (scope.row.state == 0 || (scope.row.state == 1 && user.subordinateType == 1) || (scope.row.state == 2 && user.subordinateType == 0))" 
                                     @click="checkOpen(scope.row)">{{$t('project.approve')}}</el-button>
+                                   
+                                    <el-button size="small" @click="checkOpen(scope.row)"
+                                        v-if="approve == 1 && (scope.row.state == 4 || (scope.row.state == 5 && user.subordinateType == 1) || (scope.row.state == 6 && user.subordinateType == 0))" 
+                                    >{{$t('project.approve')}}</el-button>
                                     <a :href="scope.row.fileUrl" :download="scope.row.fileName" v-if="download == 1 && scope.row.state == 3">
                                         <el-button size="small" @click="dowloadfile(scope.row.id)">{{$t('project.download')}}</el-button>
                                     </a>
                                     <el-button size="small"
                                         v-if="(scope.row.uplodtorId == user.id && scope.row.state <= 0) || (scope.row.state == 3 && user.parentId == 1 && user.subordinateType == 0)" 
-                                        @click="deleteFile(scope.row.id)" type="danger">{{$t('mold.applyDelete')}}</el-button>
+                                        @click="deleteFile(scope.row.id)" type="danger">{{$t('el.upload.delete')}}</el-button>
+                                    <el-button size="small" 
+                                        v-if="(scope.row.uplodtorId == user.id && scope.row.state == 3&& !(user.parentId == 1 && user.subordinateType == 0))" 
+                                        @click="applyDeleteFile(scope.row.id)" type="danger">{{$t('mold.applyDelete')}}</el-button>
                                 </template>
                             </el-table-column>
                         </el-table>
-                    </el-tab-pane>
+                    </el-tab-pane> -->
 
                     <!-- 保养方案 -->
                     <el-tab-pane :label="$t('mold.plan')" name="3">
@@ -394,6 +432,11 @@
                                     <span v-else-if="scope.row.state == 1">{{$t('mold.state3')}}</span>
                                     <span v-else-if="scope.row.state == 2">{{$t('mold.state4')}}</span>
                                     <span v-else-if="scope.row.state == 3">{{$t('mold.state5')}}</span>
+                                    <span v-else-if="scope.row.state == 4">删除待审批</span>
+                                    <span v-else-if="scope.row.state == 5">删除待生产方审核</span>
+                                    <span v-else-if="scope.row.state == 6">删除待资产方审核</span>
+                                    <span v-else-if="scope.row.state == -5">资产方不同意删除</span>
+                                    <span v-else-if="scope.row.state == -6">生产方不同意删除</span>
                                 </template>
                             </el-table-column>
                             <el-table-column :label="$t('base.operate')" width="200" sortable>
@@ -401,12 +444,19 @@
                                     <el-button size="small" 
                                         v-if="approve == 1 && (scope.row.state == 0 || (scope.row.state == 1 && user.subordinateType == 1) || (scope.row.state == 2 && user.subordinateType == 0))" 
                                         @click="checkOpen(scope.row)">{{$t('project.approve')}}</el-button>
+                                    <!--删除审核-->
+                                    <el-button size="small" @click="checkOpen(scope.row)"
+                                        v-if="approve == 1 && (scope.row.state == 4 || (scope.row.state == 5 && user.subordinateType == 1) || (scope.row.state == 6 && user.subordinateType == 0))" 
+                                    >{{$t('project.approve')}}</el-button>
                                     <a :href="scope.row.fileUrl" :download="scope.row.fileName" v-if="download == 1 && scope.row.state == 3">
                                         <el-button size="small" @click="dowloadfile(scope.row.id)">{{$t('project.download')}}</el-button>
                                     </a>
                                     <el-button size="small"
                                         v-if="(scope.row.uplodtorId == user.id && scope.row.state <= 0) || (scope.row.state == 3 && user.parentId == 1 && user.subordinateType == 0)" 
-                                        @click="deleteFile(scope.row.id)" type="danger">{{$t('mold.applyDelete')}}</el-button>
+                                        @click="deleteFile(scope.row.id)" type="danger">{{$t('el.upload.delete')}}</el-button>
+                                    <el-button size="small" 
+                                        v-if="(scope.row.uplodtorId == user.id && scope.row.state == 3&& !(user.parentId == 1 && user.subordinateType == 0))" 
+                                        @click="applyDeleteFile(scope.row.id)" type="danger">{{$t('mold.applyDelete')}}</el-button>
                                 </template>
                             </el-table-column>
                         </el-table>
@@ -487,6 +537,11 @@
                                     <span v-else-if="scope.row.state == 1">{{$t('mold.state3')}}</span>
                                     <span v-else-if="scope.row.state == 2">{{$t('mold.state4')}}</span>
                                     <span v-else-if="scope.row.state == 3">{{$t('mold.state5')}}</span>
+                                    <span v-else-if="scope.row.state == 4">删除待审批</span>
+                                    <span v-else-if="scope.row.state == 5">删除待生产方审核</span>
+                                    <span v-else-if="scope.row.state == 6">删除待资产方审核</span>
+                                    <span v-else-if="scope.row.state == -5">资产方不同意删除</span>
+                                    <span v-else-if="scope.row.state == -6">生产方不同意删除</span>
                                 </template>
                             </el-table-column>
                             <el-table-column :label="$t('base.operate')" width="200" sortable>
@@ -494,12 +549,19 @@
                                     <el-button size="small" 
                                         v-if="approve == 1 && (scope.row.state == 0 || (scope.row.state == 1 && user.subordinateType == 1) || (scope.row.state == 2 && user.subordinateType == 0))" 
                                         @click="checkOpen(scope.row)">{{$t('project.approve')}}</el-button>
+                                        <!--删除审核-->
+                                    <el-button size="small" @click="checkOpen(scope.row)"
+                                        v-if="approve == 1 && (scope.row.state == 4 || (scope.row.state == 5 && user.subordinateType == 1) || (scope.row.state == 6 && user.subordinateType == 0))" 
+                                    >{{$t('project.approve')}}</el-button>
                                     <el-button size="small" @click="dowloadfile(scope.row.id,5,scope.row)" v-if="download == 1 && scope.row.state == 3 ">
                                         {{$t('project.download')}}
                                     </el-button>
                                     <el-button size="small"
                                         v-if="(scope.row.uplodtorId == user.id && scope.row.state <= 0) || (scope.row.state == 3 && user.parentId == 1 && user.subordinateType == 0)" 
-                                        @click="deleteFile(scope.row.id)" type="danger">{{$t('mold.applyDelete')}}</el-button>
+                                        @click="deleteFile(scope.row.id)" type="danger">{{$t('el.upload.delete')}}</el-button>
+                                    <el-button size="small" 
+                                        v-if="(scope.row.uplodtorId == user.id && scope.row.state == 3&& !(user.parentId == 1 && user.subordinateType == 0))" 
+                                        @click="applyDeleteFile(scope.row.id)" type="danger">{{$t('mold.applyDelete')}}</el-button>
                                 </template>
                             </el-table-column>
                         </el-table>
@@ -557,13 +619,34 @@
                     {{$t('mold.file2D')}}:<a :href="this.part2dFile.fileUrl" :download="this.part2dFile.fileName"><el-link type="primary">{{this.part2dFile.fileName}}</el-link></a>
                 </div>
                 <br>
-                <div v-if="this.part2dFile != null">
+                <div v-if="this.part3dFile != null">
                     {{$t('mold.file3D')}}:<a :href="this.part3dFile.fileUrl" :download="this.part3dFile.fileName"><el-link type="primary">{{this.part3dFile.fileName}}</el-link></a>
                 </div>
             </div>
+            <el-radio v-model="checkResult" label="1" >{{$t('mold.pass')}}</el-radio>
+            <el-radio v-model="checkResult" label="0" >{{$t('mold.fail')}}</el-radio>
+            <div v-show="checkResult==0" style="margin-top:10px;">
+                <el-input type="textarea"
+                    :rows="2"
+                    placeholder="请输入原因"
+                    v-model="checkReason"/>
+            </div>
+            <span slot="footer" class="dialog-footer">
+                <!-- <el-button @click="check(false)">{{$t('mold.fail')}}</el-button> -->
+                <el-button type="primary" @click="check()">提交</el-button>
+            </span>
+        </el-dialog>
+
+        <!-- 申请删除弹窗 -->
+        <el-dialog title="申请删除" :visible.sync="deleteDialogVisible" width="450px">
+            <div style="margin-top:10px;">
+                <el-input type="textarea"
+                    :rows="2"
+                    placeholder="请输入原因"
+                    v-model="deleteReason"/>
+            </div>
             <span slot="footer" class="dialog-footer">
-                <el-button @click="check(false)">{{$t('mold.fail')}}</el-button>
-                <el-button type="primary" @click="check(true)">{{$t('mold.pass')}}</el-button>
+                <el-button type="primary" @click="sendApplyDeleteFile">提交</el-button>
             </span>
         </el-dialog>
 
@@ -725,6 +808,24 @@
                 <el-form-item label="移模原因" prop="reason">
                     <el-input v-model="reason"  placeholder="请填写移模原因"></el-input>
                 </el-form-item>
+                <el-form-item label="移模日期" prop="time">
+                    <!-- <el-input v-model="time"  placeholder="请填写移模时间"></el-input> -->
+                    <el-date-picker style="width:100%;"
+                        v-model="time"
+                        type="date"
+                        value-format="yyyy-MM-dd"
+                        placeholder="选择移模日期">
+                    </el-date-picker>
+                </el-form-item>
+                <el-form-item label="移模地点" prop="address">
+                    <el-input v-model="address"  placeholder="请填写移模地点"></el-input>
+                </el-form-item>
+                <el-form-item label="生产方" prop="address" >
+                    <el-select v-model="producer" style="width:100%;">
+                        <el-option v-for="item in producerList" :key="item.id" :label="item.companyName" :value="item.id">
+                        </el-option>
+                    </el-select>
+                </el-form-item>
             </el-form>
             <div slot="footer" class="dialog-footer">
                 <el-button @click.native="moveDialogVisible = false">{{$t('el.messagebox.cancel')}}</el-button>
@@ -732,7 +833,7 @@
             </div>
         </el-dialog>
         <!--修改生产方弹出框 -->
-        <el-dialog title="移模申请" v-if="changeProducerDialogVisible" :visible.sync="changeProducerDialogVisible" :close-on-click-modal="false" customClass="customWidth">
+        <el-dialog title="修改生产方" v-if="changeProducerDialogVisible" :visible.sync="changeProducerDialogVisible" :close-on-click-modal="false" customClass="customWidth">
             <el-form :model="newParts" label-width="100px" ref="newParts" class="demo-form-inline">
                 <el-form-item :label="$t('mold.factoryName')" >
                     <el-select v-model="produceCompanyId" clearable filterable :placeholder="$t('mold.inputfactoryName')" style="width:470px">
@@ -847,11 +948,22 @@
                 }
             };            
             return {
+                deleteFileId:null,
+                deleteDialogVisible:false,
+                deleteReason:null,
+                //审批弹窗的radio选项值,默认通过
+                checkResult:"1",
+                checkReason:null,
                 produceCompanyId:null,
                 changeProducerDialogVisible:false,
                 assetApproverId:0,
+                //移模申请参数
+                producer:null,
+                producerList:[],
                 moveDialogVisible: false,
                 reason:null,
+                time:null,
+                address: null,
                 detailId: this.$route.params.id,
                 user: JSON.parse(sessionStorage.getItem("user")),
                 moldDetail: {},
@@ -1026,6 +1138,25 @@
             };
         },
         methods: {
+            getAllProducer() {
+                this.http.post("/company/relationList", {
+                   companyType:1,//获取生产方
+                }, res => {
+                    if (res.code == "ok") {
+                        this.producerList = res.data;
+                    } else {
+                        this.$message({
+                            message: res.msg,
+                            type: 'error'
+                        });
+                    }
+                }, error => {
+                    this.$message({
+                        message: error,
+                        type: 'error'
+                    });
+                });
+            },
             submitChangeProducer() {
                 //提交修改生产方
                 this.http.post(this.port.mold.changeProducer, {
@@ -1110,7 +1241,7 @@
                 //发起移模申请
                 this.http.post( this.port.mold.checkMoveMold, {
                     status: status,
-                    mouldId: this.detailId
+                    mouldId: this.detailId,
                 },
                 res => {
                     if (res.code == "ok") {
@@ -1136,7 +1267,11 @@
                 //发起移模申请
                 this.http.post( this.port.mold.moveMold, {
                     reason: this.reason,
-                    mouldId: this.detailId
+                    time:this.time,
+                    address: this.address,
+                    mouldId: this.detailId,
+                    producerCompanyId: this.producer,
+                    userId: this.user.id
                 },
                 res => {
                     if (res.code == "ok") {
@@ -1410,6 +1545,8 @@
                 this.twoId = null;
                 this.threeId = null;
                 this.centerDialogVisible = true;
+                this.checkResult = "1";
+                this.checkReason = null;
             },
 
             //打开审批窗口
@@ -1440,7 +1577,8 @@
             },
 
             //审批文件
-            check(adoption) {
+            check() {
+                var adoption = this.checkResult=="1"?true:false;
                 if(this.activeArticleId != null) {
                     this.onSubMit(this.activeArticleId , adoption , 0)
                 }
@@ -1455,7 +1593,8 @@
             onSubMit(id , type , from) {
                 this.http.post( this.port.mold.moldFileCheck, {
                     mouldFileId: id,
-                    isPass: type ? 1 : 0 //通过为1 不通过为0
+                    isPass: type ? 1 : 0, //通过为1 不通过为0
+                    reason:this.checkReason
                 },
                 res => {
                     if (res.code == "ok") {
@@ -1630,6 +1769,37 @@
                 }).catch(() => {});
             },
 
+            //文件删除
+            applyDeleteFile(fileId) {
+                this.deleteDialogVisible = true;
+                this.deleteFileId = fileId;
+            },
+
+            sendApplyDeleteFile(fileId) {
+                this.http.post(this.port.mold.moldFileApplyDelete, { id: this.deleteFileId, belongType:this.activeTab, reason:this.deleteReason },
+                    res => {
+                        if (res.code == "ok") {
+                            this.$message({
+                                message: this.$t('project.applySendSuccess'),
+                                type: "success"
+                            });
+                            this.deleteDialogVisible = false;
+                            this.getDocument();
+                        } else {
+                            this.$message({
+                                message: res.msg,
+                                type: "error"
+                            });
+                        }
+                    },
+                    error => {
+                        this.$message({
+                            message: error,
+                            type: "error"
+                        });
+                    });
+            },
+
             //零件新建
             subPart() {
                 this.$refs.newParts.validate(valid => {
@@ -2119,6 +2289,14 @@
                     } else {
                         data.sourceFileUrl = row.fileUrl2;
                     }
+                } else if (this.activeTab == 1) {//零件文档
+                    data.type = 1;//零件文档的类型也是1
+                    if (type == 2) {
+                        //2D图档
+                        data.fileId = row.part2dFile.id;
+                    } else {
+                        data.fileId = row.part3dFile.id;
+                    }
                 }
                 this.http.post(this.port.file.view, data,
                 res => {
@@ -2166,6 +2344,7 @@
         mounted() {
             this.getDetail();
             this.getCompanys();
+            this.getAllProducer();
         }
     };
 </script>

+ 3 - 3
ys_int/src/views/mold/moldList.vue

@@ -442,8 +442,8 @@
                 //获取模具
                 this.getMoulds();
                 //新版获取公司
-                this.http.post(this.port.base.relationList, {
-                    companyType: 1
+                this.http.post("/company/getRelatedProducerList", {
+                    companyId: this.user.companyId
                 }, res => {
                     if (res.code == "ok") {
                         this.companys = res.data;
@@ -616,7 +616,7 @@
             toPart(i) {
                 if(i == 0) {
                     this.addState = true;
-                    this.addTitle = this.$t('basic.addAsset');
+                    this.addTitle = this.$t('mold.addMold');
                 }
             },
 

+ 21 - 6
ys_int/src/views/project/competence.vue

@@ -26,24 +26,29 @@
 			<el-table-column prop="username" :label="$t('project.name')" width="150" sortable></el-table-column>
 			<el-table-column prop="companyName" :label="$t('project.company')" sortable></el-table-column>
 			<el-table-column prop="projectName" :label="$t('project.partake')" width="220" sortable></el-table-column>
-			<el-table-column prop="addr" :label="$t('project.upload')" align="center" width="150">
+			<el-table-column prop="addr" :label="$t('project.upload')" align="center" width="100">
                 <template slot-scope="scope">
                     <el-checkbox :value="scope.row.update==1?true:false"></el-checkbox>
                 </template>
 			</el-table-column>
-            <el-table-column prop="addr" :label="$t('project.download')" align="center" width="150">
+            <el-table-column prop="addr" :label="$t('project.download')" align="center" width="100">
                 <template slot-scope="scope">
                     <el-checkbox :value="scope.row.download==1?true:false"></el-checkbox>
                 </template>
 			</el-table-column>
-            <el-table-column prop="addr" :label="$t('project.view')" align="center" width="150">
+            <el-table-column prop="addr" :label="$t('project.view')" align="center" width="100">
                 <template slot-scope="scope">
                     <el-checkbox :value="scope.row.view==1?true:false"></el-checkbox>
                 </template>
 			</el-table-column>
-            <el-table-column prop="addr" :label="$t('project.approve')" align="center" width="150">
+            <el-table-column prop="addr" :label="$t('project.approve')" align="center" width="100">
                 <template slot-scope="scope">
                     <el-checkbox :value="scope.row.approve==1?true:false"></el-checkbox>
+                </template>
+			</el-table-column>
+             <el-table-column prop="addr" :label="$t('project.maintain')" align="center" width="100">
+                <template slot-scope="scope">
+                    <el-checkbox :value="scope.row.maintain==1?true:false"></el-checkbox>
                 </template>
 			</el-table-column>
 			<el-table-column :label="$t('base.operate')" width="150" align="center">
@@ -113,7 +118,8 @@
                     {name:this.$t('project.upload'),val:0,label:'uploadPower',uploadPower:false},
                     {name:this.$t('project.download'),val:1,label:'dowloadPower',dowloadPower:false},
                     {name:this.$t('project.view'),val:2,label:'viewPower',viewPower:false},
-                    {name:this.$t('project.approve'),val:3,label:'approvalPower',approvalPower:false}
+                    {name:this.$t('project.approve'),val:3,label:'approvalPower',approvalPower:false},
+                    {name:this.$t('project.maintain'),val:4,label:'maintainPower',maintainPower:false},
                 ],
 				//编辑界面数据
 				editForm: {
@@ -123,6 +129,7 @@
                     dowloadPower:false,
                     viewPower:false,
                     approvalPower:false,
+                    maintainPower:false,
 				}
 			}
 		},
@@ -173,6 +180,7 @@
                             list[i].download = 0;
                             list[i].view = 0;
                             list[i].approve = 0;
+                            list[i].maintain = 0;
 
                             var powers = list[i].powers;
                             for(var j in powers){
@@ -184,6 +192,8 @@
                                     list[i].view = 1;
                                 } else if(powers[j].powerType == 3){
                                     list[i].approve = 1;
+                                } else if (powers[j].powerType == 4) {
+                                    list[i].maintain = 1;//保养
                                 }
                             }
                         }
@@ -213,7 +223,8 @@
                     uploadPower: row.update==1?true:false,
                     dowloadPower: row.download==1?true:false,
                     viewPower: row.view==1?true:false,
-                    approvalPower: row.approve==1?true:false
+                    approvalPower: row.approve==1?true:false,
+                    maintainPower: row.maintain==1?true:false,
                 };
 			},
 			//编辑
@@ -232,6 +243,10 @@
                 if(this.editForm.approvalPower) {
                     str += "3,"
                 }
+                if (this.editForm.maintainPower) {
+                    str += "4,"
+                }
+                
 
                 str = str.substring(0,str.length-1)
  

+ 65 - 10
ys_int/src/views/project/projectDetail.vue

@@ -27,27 +27,27 @@
                 </el-col>
                 <el-col :span="6" class="detail">
                     {{$t('project.manager')}}:
-                    <router-link class="info" :to="'/staffDetail?id='+proDetail.managerId">{{proDetail.manager}}</router-link>
+                    <router-link class="link" :to="'/staffDetail?id='+proDetail.managerId">{{proDetail.manager}}</router-link>
                 </el-col>
                 <el-col :span="6" class="detail">
                     {{$t('project.ownerApprover')}}:
-                    <router-link class="info" :to="'/staffDetail?id='+proDetail.ownerApproverId">{{proDetail.ownerApprover}}</router-link>
+                    <router-link class="link" :to="'/staffDetail?id='+proDetail.ownerApproverId">{{proDetail.ownerApprover}}</router-link>
                 </el-col>
                 <el-col :span="6" class="detail">
                     {{$t('project.customerApprover')}}:
-                    <router-link class="info" :to="'/staffDetail?id='+proDetail.customerApproverId">{{proDetail.customerApprover}}</router-link>
+                    <router-link class="link" :to="'/staffDetail?id='+proDetail.customerApproverId">{{proDetail.customerApprover}}</router-link>
                 </el-col>
                 <el-col :span="24" class="detail">
                     {{$t('project.cusName')}}:
                     <span class="info" :key="index" v-for="(item, index) in proDetail.customCompanies">
-                        <router-link class="info" :to="'/factoryDetail?id='+item.companyId">{{item.companyName}}</router-link>
+                        <router-link class="link" :to="'/factoryDetail?id='+item.companyId">{{item.companyName}}</router-link>
                         <span v-if="index != proDetail.customCompanies.length-1">、</span>
                     </span>
                 </el-col>
                 <el-col :span="24" class="detail">
                     {{$t('project.users')}}:
                     <span class="info" :key="index" v-for="(item, index) in proDetail.participateUsers">
-                        <router-link class="info" :to="'/staffDetail?id='+item.id">{{item.username}}</router-link>
+                        <router-link class="link" :to="'/staffDetail?id='+item.id">{{item.username}}</router-link>
                         <span v-if="index != proDetail.participateUsers.length-1">、</span>
                     </span>
                 </el-col>
@@ -109,7 +109,7 @@
                                                 <el-button size="small" @click="dowloadFile(scope.row)">{{$t('project.download')}}</el-button>
                                             </a>
 
-                                            <el-button size="small" type="danger" @click="fileDel(scope.row.id)" v-if="scope.row.uploaderId == user.id && scope.row.status == 0">{{$t('el.upload.delete')}}</el-button>
+                                            <el-button size="small" type="danger" @click="applyDeleteFile(scope.row.id)" v-if="scope.row.uploaderId == user.id && scope.row.status == 0">{{$t('el.upload.delete')}}</el-button>
                                             <div  v-if="projectDocApprove==1 && scope.row.status == 1" style="margin-left:15px;display:inline;">
                                             <el-button @click="checkDel(scope.row.id, 1)" size="small" type="danger">{{$t('mold.pass')}}</el-button>
                                             <el-button @click="checkDel(scope.row.id, 0)" size="small" >{{$t('mold.fail')}}</el-button>
@@ -141,7 +141,18 @@
             </el-col>
             
         </el-col>
-
+        <!-- 申请删除弹窗 -->
+        <el-dialog title="申请删除" :visible.sync="deleteDialogVisible" width="450px">
+            <div style="margin-top:10px;">
+                <el-input type="textarea"
+                    :rows="2"
+                    placeholder="请输入原因"
+                    v-model="deleteReason"/>
+            </div>
+            <span slot="footer" class="dialog-footer">
+                <el-button type="primary" @click="sendApplyDeleteFile">提交</el-button>
+            </span>
+        </el-dialog>
         <!--编辑界面-->
 		<el-dialog :title="$t('project.editPro')" v-if="editFormVisible" :visible.sync="editFormVisible" :close-on-click-modal="false" customClass='customWidth'>
 			<el-form :model="editForm" label-width="120px" :rules="formRules" ref="editForm">
@@ -285,6 +296,11 @@
                 }
             };
             return {
+                //删除文件相关属性
+                deleteFileId:null,
+                deleteDialogVisible:false,
+                deleteReason:null,
+
                 activeNames: ['1','2','3'],
 
                 detailId: this.$route.params.id,
@@ -894,7 +910,7 @@
                         }
 
                         this.editLoading = true;
-                        this.http.post(this.port.project.addProject, {
+                        var reqParam = {
                             id: this.editForm.id,
                             projectName: this.editForm.projectName,
                             customerCompanyIds: cId,
@@ -903,10 +919,14 @@
                             managerId: this.editForm.managerId.id,
                             ownerApproverId: this.editForm.ownerApproverId,
                             customerApproverId: this.editForm.customerApproverId,
-                            modelIds: modelIds,
                             userIds: userIds,
                             flag: 1
-                        } , res => {
+                        }
+                        //只有资产方管理员才编辑模具
+                        if (this.user.parentId == 1 && this.user.subordinateType == 0) {
+                            reqParam.modelIds = modelIds
+                        }
+                        this.http.post(this.port.project.addProject, reqParam , res => {
                             this.editLoading = false;
                             this.editFormVisible = false;
                             if (res.code == "ok") {
@@ -1024,6 +1044,37 @@
                 })
             },
 
+            //文件删除
+            applyDeleteFile(fileId) {
+                this.deleteDialogVisible = true;
+                this.deleteFileId = fileId;
+            },
+            sendApplyDeleteFile(fileId) {
+                this.http.post(this.port.project.delFileApplication, {
+                        id: this.deleteFileId,
+                        reason: this.deleteReason
+                    }, res => {
+                        if (res.code == "ok") {
+                            this.$message({
+                                message: "申请已发起,请等待"+res.data+"审核",
+                                type: 'success'
+                            });
+                            this.deleteDialogVisible = false;
+                            this.getFileList();
+                            this.getOperList();
+                        } else {
+                            this.$message({
+                                message: res.msg,
+                                type: 'error'
+                            });
+                        }
+                    }, error => {
+                        this.$message({
+                            message: error,
+                            type: 'error'
+                        });
+                    })
+            },
             //删除上传文件
 			fileDel(id) {
                 this.$confirm(this.$t('project.delFileApplication'), this.$t('el.messagebox.title'), {
@@ -1192,6 +1243,10 @@
         color: grey;
     }
 
+    .link {
+        color:#20a0ff;
+    }
+
     .model {
         cursor: pointer;
         color:#20a0ff;

+ 15 - 5
ys_int/src/views/project/staff.vue

@@ -44,7 +44,7 @@
 			<!-- <el-table-column prop="mobile" label="联系方式" width="150" sortable></el-table-column> -->
             <el-table-column prop="projects" :label="$t('project.partake')" width="300">
                 <template slot-scope="scope">
-                    <span class="info" v-for="(item, index) in scope.row.projects">
+                    <span class="info" v-for="(item, index) in scope.row.projects" :key="item.id">
                         {{item.projectName}}
                         <span v-if="scope.row.projects != null && index != scope.row.projects.length-1">、</span>
                     </span>
@@ -53,6 +53,13 @@
             <el-table-column prop="roleName" :label="$t('project.remark')" width="180" sortable></el-table-column>
             <el-table-column prop="teamName" :label="$t('project.type')" width="120" align="center" sortable></el-table-column>
 			<el-table-column prop="companyName" :label="$t('project.company')" width="300" sortable></el-table-column>
+			<el-table-column prop="corpUserId" label="绑定情况" width="300" sortable>
+                <template slot-scope="scope" >
+                    <span v-if="scope.row.corpUserId != null" style="color:green;">企业微信已绑定</span>
+                    <span v-if="scope.row.openid != null" style="margin-left:10px;color:green;">个人微信已绑定</span>
+                    <span v-if="scope.row.openid == null && scope.corpUserId == null">未绑定</span>
+				</template>
+            </el-table-column>
 			<el-table-column :label="$t('base.operate')" align="left" width="230">
 				<template slot-scope="scope" v-if="user.id == scope.row.parentId || user.isManager == 1 || (user.parentId == 1 && user.subordinateType == 0)">
 					<el-button size="small" @click="handleEdit(scope.$index, scope.row)">{{$t('base.edit')}}</el-button>
@@ -92,7 +99,7 @@
 				</el-form-item>
                 <el-form-item :label="$t('project.company')" prop="companyId">
 					<el-select v-model="addForm.companyId" clearable filterable :placeholder="$t('project.inputCompany')" style="width:202px">
-                        <el-option v-for="item in company" :key="item.id" :label="item.companyName" :value="item.id">
+                        <el-option v-for="item in allCompanies" :key="item.id" :label="item.companyName" :value="item.id">
                         </el-option>
                     </el-select>
 				</el-form-item>
@@ -119,7 +126,7 @@
                 <el-form-item :label="$t('project.company')" prop="companyId">
                     <!-- <el-input v-model="editForm.companyId" autocomplete="off" :placeholder="$t('project.inputCompany')"></el-input> -->
                     <el-select v-model="editForm.companyId" clearable filterable :placeholder="$t('project.inputCompany')" style="width:202px">
-                        <el-option v-for="item in company" :key="item.id" :label="item.companyName" :value="item.id">
+                        <el-option v-for="item in allCompanies" :key="item.id" :label="item.companyName" :value="item.id">
                         </el-option>
                     </el-select>
 
@@ -275,7 +282,7 @@
                             type: 'error'
                         });
                     })
-                } else if(this.user.parentId > 1 && this.user.isManager == 1) {
+                } else if (this.user.parentId > 1 && this.user.isManager == 1) {
                     this.http.post(this.port.project.projectByUser, {}, 
                     res => {
                         if (res.code == "ok") {
@@ -294,6 +301,8 @@
                             type: 'error'
                         });
                     });
+                } else {
+                    this.getAllCompanies();
                 }
             },  
 
@@ -443,7 +452,7 @@
                     parentId: this.user.id,
 					username: row.username,
                     account: row.account,
-					companyId: row.companyName,
+					companyId: row.companyId,
                     roleName: row.roleName,
                     flag: 1
                 };
@@ -460,6 +469,7 @@
                             username: this.editForm.username,
                             roleName: this.editForm.roleName,
                             companyId: this.editForm.companyId,
+                            account: this.editForm.account,
                             flag: 1
                         } , res => {
                             this.editLoading = false;

+ 16 - 5
ys_int/src/views/project/staffDetail.vue

@@ -38,8 +38,18 @@
                         {{item.projectName}}
                         <span v-if="data.projects != null && index != data.projects.length-1">、</span>
                     </span>
-                    <!-- 只有资产方管理员或者系统管理员才有权限 -->
-                    <el-button size="mini" style="margin-left:10px;" v-show="data.projects != null && data.projects.length > 0 && (user.parentId == 0 || (user.parentId == 1 && user.subordinateType == 0))" type="default" @click="showTransferProject=true">项目交接</el-button>
+                    <!-- 只有资产方管理员 -->
+                    <el-button size="mini" style="margin-left:10px;" v-show="data.projects != null && data.projects.length > 0 && (user.parentId == 1 && user.subordinateType == 0)" type="default" @click="showTransferProject=true">项目交接</el-button>
+                </el-col>
+            </el-col>
+            <el-col :span="24" class="main">
+                <el-col :span="8" class="detail">
+                    个人微信:
+                    <span class="info">{{data.openid == null?'未绑定':'已绑定'}}</span>
+                </el-col>
+                <el-col :span="8" class="detail">
+                    企业微信:
+                    <span class="info">{{data.corpUserId == null?'未绑定':'已绑定'}}</span>
                 </el-col>
             </el-col>
             <el-col :span="24" class="main">
@@ -110,8 +120,8 @@
 		},
 		methods: {
             getUserList() {
-                this.http.post('/user/getAllAvailableUserList', {
-                    userId: this.user.id
+                this.http.post('/user/getUserListByCompanyId', {
+                    companyId: this.data.companyId
                 }, res => {
                     this.listLoading = false;
                     if (res.code == "ok") {
@@ -185,6 +195,7 @@
                     this.listLoading = false;
                     if (res.code == "ok") {
                         this.data = res.data;
+                        this.getUserList();
                         var projects = this.data.projects;
                         for (var i=0;i<projects.length; i++) {
                             
@@ -216,7 +227,7 @@
             window.onresize = function temp() {
                 that.allDetail.height = window.innerHeight - 170;
             };
-            this.getUserList();
+            
         },
         
 		mounted() {