xiaochan 2 months ago
parent
commit
fd8c5b8290

+ 1 - 1
pom.xml

@@ -10,7 +10,7 @@
     </parent>
     <groupId>thyyxxk</groupId>
     <artifactId>web-server</artifactId>
-    <version>13.3.9</version>
+    <version>13.4.3</version>
     <name>web-server</name>
     <description>server for yibao-web</description>
     <properties>

+ 52 - 0
src/main/java/thyyxxk/webserver/controller/settings/SchedulingClassController.java

@@ -0,0 +1,52 @@
+package thyyxxk.webserver.controller.settings;
+
+import cn.hutool.json.JSONObject;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+import thyyxxk.webserver.entity.ResultVo;
+import thyyxxk.webserver.entity.dictionary.CodeName;
+import thyyxxk.webserver.entity.schedulingClass.data.SchedulingClass;
+import thyyxxk.webserver.service.settings.SchedulingClass.SchedulingClassService;
+import thyyxxk.webserver.utils.R;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+@RequestMapping("/schedulingClass")
+@RestController
+@RequiredArgsConstructor
+public class SchedulingClassController {
+    private final SchedulingClassService service;
+
+    @GetMapping("/getCodes")
+    public ResultVo<List<CodeName>> getCodes() {
+        return R.ok(service.getCodes());
+    }
+
+    @GetMapping("/getSortAndName")
+    public ResultVo<List<CodeName>> getSortAndName() {
+        return R.ok(service.getSortAndName());
+    }
+
+    @PostMapping("/saveSort")
+    public ResultVo<String> saveSort(@RequestBody JSONObject value) {
+        return service.saveSort(value);
+    }
+
+    @GetMapping("/createByMonth")
+    public ResultVo<String> createByMonth(@RequestParam("month") String month) {
+        return service.createByMonth(month);
+    }
+
+    @GetMapping("/getByMonth")
+    public ResultVo<List<SchedulingClass.SchedulingClassVo>> getByMonth(@RequestParam("month") String month) {
+        return R.ok(service.getByMonth(month));
+    }
+
+    @PostMapping("/updateById")
+    public ResultVo<String> updateById(@RequestBody SchedulingClass data) {
+        return service.updateById(data);
+    }
+
+
+}

+ 49 - 0
src/main/java/thyyxxk/webserver/dao/his/settings/SchedulingClassDao.java

@@ -0,0 +1,49 @@
+package thyyxxk.webserver.dao.his.settings;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.Update;
+import thyyxxk.webserver.entity.dictionary.CodeName;
+import thyyxxk.webserver.entity.schedulingClass.data.SchedulingClass;
+
+import java.util.Date;
+import java.util.List;
+
+@Mapper
+public interface SchedulingClassDao extends BaseMapper<SchedulingClass> {
+
+    @Select("select code, rtrim(name) as name\n" +
+            "from a_employee_mi\n" +
+            "where dept_code = '3100000'\n" +
+            "  and del_flag = 0")
+    List<CodeName> getXinXiKeCode();
+
+    @Select("select dict_value\n" +
+            "from t_dict_data\n" +
+            "where dict_name = 'scheduling_class_sort'\n" +
+            "  and dict_type = '1.0'")
+    String getSort();
+
+
+    @Update("update  t_dict_data set  dict_value = #{value} " +
+            "where dict_name = 'scheduling_class_sort' and dict_type = '1.0'")
+    void updateDictData(String value);
+
+
+    @Select("select code," +
+            " name = (select rtrim(name) from a_employee_mi where scheduling_class.code = a_employee_mi.code)\n" +
+            "from scheduling_class where scheduling_date = #{date} ")
+    CodeName selectByDate(Date date);
+
+    @Select("select name = (select rtrim(name) from a_employee_mi where a_employee_mi.code = scheduling_class.code)," +
+            "change_class_name= (select rtrim(name)\n" +
+            "                           from a_employee_mi\n" +
+            "                           where scheduling_class.change_class = a_employee_mi.code),\n" +
+            "       *\n" +
+            "from scheduling_class ${ew.customSqlSegment} ")
+    List<SchedulingClass.SchedulingClassVo> selectByDateVo(@Param("ew") LambdaQueryWrapper<SchedulingClass> queryWrapper);
+
+}

+ 13 - 0
src/main/java/thyyxxk/webserver/entity/dictionary/SimpleCodeName.java

@@ -0,0 +1,13 @@
+package thyyxxk.webserver.entity.dictionary;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class SimpleCodeName {
+    private String code;
+    private String name;
+}

+ 89 - 0
src/main/java/thyyxxk/webserver/entity/schedulingClass/data/SchedulingClass.java

@@ -0,0 +1,89 @@
+package thyyxxk.webserver.entity.schedulingClass.data;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+import cn.hutool.core.date.DateTime;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.*;
+
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import org.springframework.format.annotation.DateTimeFormat;
+import thyyxxk.webserver.entity.dictionary.SimpleCodeName;
+import thyyxxk.webserver.utils.SnowFlakeId;
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@TableName(value = "scheduling_class")
+public class SchedulingClass implements Serializable {
+
+    private static final long serialVersionUID = 5734810717512894614L;
+
+    /**
+     * 主键
+     */
+    @TableId
+    private String id;
+
+    /**
+     * 值班的人的id
+     */
+    @TableField(value = "code")
+    private String code;
+
+    /**
+     * 排班时间
+     */
+    @TableField(value = "scheduling_date")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
+    private Date schedulingDate;
+
+    /**
+     * 和别人换班的人,为什么不直接改变 code是因为如果有人换班了的话下次计算就会有问题
+     */
+    @TableField(value = "change_class")
+    private String changeClass;
+
+    /**
+     * 次要的排班, 最多 10 个人可选
+     */
+    @TableField(value = "false_code")
+    private String falseCode;
+
+
+    public static LambdaQueryWrapper<SchedulingClass> lambdaQueryWrapper() {
+        return new LambdaQueryWrapper<>();
+    }
+
+    public static QueryWrapper<SchedulingClass> queryWrapper() {
+        return new QueryWrapper<>();
+    }
+
+    public SchedulingClass cloneData(Date schedulingTime) {
+        return SchedulingClass.builder()
+                .id(SnowFlakeId.instance().nextId())
+                .code(this.code).schedulingDate(schedulingTime).build();
+    }
+
+
+    @EqualsAndHashCode(callSuper = true)
+    @Data
+    @AllArgsConstructor
+    @NoArgsConstructor
+    public static class SchedulingClassVo extends SchedulingClass {
+        private String name;
+        private String changeClassName;
+        private List<SimpleCodeName> falseCodeList;
+    }
+
+
+}

+ 7 - 5
src/main/java/thyyxxk/webserver/service/reports/ClockinService.java

@@ -12,14 +12,12 @@ import thyyxxk.webserver.entity.ResultVo;
 import thyyxxk.webserver.entity.clockin.Clockin;
 import thyyxxk.webserver.entity.clockin.ClockinView;
 import thyyxxk.webserver.entity.clockin.QueryFromDbParam;
+import thyyxxk.webserver.utils.DateUtil;
 import thyyxxk.webserver.utils.ExcelUtil;
 import thyyxxk.webserver.utils.ResultVoUtil;
 
 import javax.servlet.http.HttpServletResponse;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 /**
  * @author dj
@@ -46,7 +44,7 @@ public class ClockinService {
         log.info("导出打卡数据Excel: {}", JSON.toJSONString(param));
         IPage<Clockin> iPage = getClockInPage(param);
         List<ClockinView> list = combineData(iPage.getRecords());
-        String[] title = {"日期","姓名","工号","科室", "打卡次数", "工作时长", "上班打卡时间", "上班打卡地点",
+        String[] title = {"日期", "姓名", "工号", "科室", "打卡次数", "工作时长", "上班打卡时间", "上班打卡地点",
                 "上班打卡状态", "上班打卡备注", "下班打卡时间", "下班打卡地点", "下班打卡状态", "下班打卡备注"};
         String[][] content = new String[list.size()][];
         for (int i = 0; i < list.size(); i++) {
@@ -72,6 +70,10 @@ public class ClockinService {
 
     private IPage<Clockin> getClockInPage(QueryFromDbParam param) {
         IPage<Clockin> iPage = new Page<>(param.getCurrentPage(), param.getPageSize());
+        // 如果当前时间小于选的结束时间的话就用
+        if (DateUtil.endOfDay(new Date()).compareTo(param.getEnd()) < 0) {
+            param.setEnd(DateUtil.endOfDay(new Date()));
+        }
         return dao.getAllClockInDataFromDb(iPage, param.getStart(), param.getEnd());
     }
 

+ 161 - 0
src/main/java/thyyxxk/webserver/service/settings/SchedulingClass/CreateMonth.java

@@ -0,0 +1,161 @@
+package thyyxxk.webserver.service.settings.SchedulingClass;
+
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.Week;
+import cn.hutool.extra.spring.SpringUtil;
+import com.alibaba.fastjson.JSONObject;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import thyyxxk.webserver.dao.his.settings.SchedulingClassDao;
+import thyyxxk.webserver.entity.dictionary.CodeName;
+import thyyxxk.webserver.entity.schedulingClass.data.SchedulingClass;
+import thyyxxk.webserver.utils.DateUtil;
+import thyyxxk.webserver.utils.SnowFlakeId;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Slf4j
+public class CreateMonth {
+    private DateTime month;
+    /**
+     * 这个月的第一天
+     */
+    @Getter
+    private DateTime firstDayOfMonth;
+
+    /**
+     * 这个月的最后一天
+     */
+    @Getter
+    private DateTime lastDayOfMonth;
+
+    /**
+     * 循环的当前日期
+     */
+    private DateTime currentDay;
+
+    /**
+     * 排序列表
+     */
+    private List<CodeName> sortCode;
+
+    /**
+     * dao类
+     */
+    private static final SchedulingClassDao dao = SpringUtil.getBean(SchedulingClassDao.class);
+
+
+    /**
+     * 返回结果
+     */
+    private List<SchedulingClass> rst = new ArrayList<>();
+
+    @Data
+    @AllArgsConstructor
+    @NoArgsConstructor
+    private static class FindCodeName {
+        private int current;
+        private String code;
+        private String name;
+    }
+
+    public CreateMonth(String month, List<CodeName> sortCode) {
+        this.month = cn.hutool.core.date.DateUtil.parse(month, "yyyy-MM");
+        this.sortCode = sortCode;
+        init();
+    }
+
+    private void init() {
+        // 获取第一个月
+        firstDayOfMonth = DateUtil.beginOfMonth(month);
+        // 获取最后一个月
+        lastDayOfMonth = DateUtil.endOfMonth(month);
+        currentDay = firstDayOfMonth;
+    }
+
+    private void forEach() {
+        while (currentDay.compareTo(lastDayOfMonth) <= 0) {
+            int i = currentDay.dayOfWeek();
+            // 如果是周一的话就要看周四的了
+            if (i == Week.MONDAY.getValue()) {
+                rst.add(day(-4));
+                // 周五用和流日一起
+            } else if (i == Week.FRIDAY.getValue()) {
+                // 周六周日排除
+                SchedulingClass day = day(-7);
+                rst.add(day);
+                currentDay = DateUtil.offsetDay(currentDay, 1);
+                rst.add(day.cloneData(currentDay));
+                currentDay = DateUtil.offsetDay(currentDay, 1);
+                rst.add(day.cloneData(currentDay));
+            } else if (i == Week.SATURDAY.getValue() || i == Week.SUNDAY.getValue()) {
+                continue;
+            } else {
+                rst.add(day(-1));
+            }
+            currentDay = DateUtil.offsetDay(currentDay, 1);
+        }
+    }
+
+    private SchedulingClass day(int offset) {
+        DateTime previous = DateUtil.offsetDay(currentDay, offset);
+        // 如果在上一个月的话那就去数据库查询
+        CodeName codeName = new CodeName();
+        if (previous.compareTo(firstDayOfMonth) < 0) {
+            codeName = dao.selectByDate(previous);
+        } else {
+            SchedulingClass byDate = findByDate(previous);
+            codeName.setCode(byDate.getCode());
+        }
+        // 获取到了上一次上班的人然后,获取排序的人
+        FindCodeName byCode = findByCode(codeName.getCode());
+        int nextIndex = byCode.getCurrent() + 1;
+        if (nextIndex >= sortCode.size()) {
+            nextIndex = 0;
+        }
+        CodeName nextCodeName = sortCode.get(nextIndex);
+        SchedulingClass vo = new SchedulingClass();
+
+        vo.setCode(nextCodeName.getCode());
+        vo.setId(SnowFlakeId.instance().nextId());
+        vo.setSchedulingDate(currentDay);
+        return vo;
+    }
+
+    private SchedulingClass findByDate(DateTime date) {
+        for (SchedulingClass item : rst) {
+            if (item.getSchedulingDate().compareTo(date) == 0) {
+                return item;
+            }
+        }
+        SchedulingClass vo = new SchedulingClass();
+        CodeName codeName = sortCode.get(0);
+        vo.setCode(codeName.getCode());
+        return vo;
+    }
+
+
+    private FindCodeName findByCode(String code) {
+        for (int i = 0; i < sortCode.size(); i++) {
+            CodeName item = sortCode.get(i);
+            if (item.getCode().equals(code)) {
+                return new FindCodeName(i, item.getCode(), item.getName());
+            }
+        }
+        CodeName codeName = sortCode.get(0);
+        return new FindCodeName(-1, codeName.getCode(), codeName.getName());
+    }
+
+
+    public List<SchedulingClass> computed() {
+        forEach();
+        log.info("数据:{}", JSONObject.toJSONStringWithDateFormat(rst, "yyyy-MM-dd"));
+        return rst;
+    }
+
+
+}

+ 160 - 0
src/main/java/thyyxxk/webserver/service/settings/SchedulingClass/SchedulingClassService.java

@@ -0,0 +1,160 @@
+package thyyxxk.webserver.service.settings.SchedulingClass;
+
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+import thyyxxk.webserver.config.envionment.JcptMobile;
+import thyyxxk.webserver.config.exception.ExceptionEnum;
+import thyyxxk.webserver.dao.his.settings.SchedulingClassDao;
+import thyyxxk.webserver.entity.ResultVo;
+import thyyxxk.webserver.entity.dictionary.CodeName;
+import thyyxxk.webserver.entity.dictionary.SimpleCodeName;
+import thyyxxk.webserver.entity.login.UserInfo;
+import thyyxxk.webserver.entity.schedulingClass.data.SchedulingClass;
+import thyyxxk.webserver.service.hutoolcache.UserCache;
+import thyyxxk.webserver.service.jcptmobile.JcptMobileService;
+import thyyxxk.webserver.utils.R;
+
+import javax.annotation.PostConstruct;
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class SchedulingClassService {
+    private final SchedulingClassDao dao;
+    private final UserCache userCache;
+    private final JcptMobile jcptMobile;
+    private final JcptMobileService mobileService;
+
+    @Scheduled(cron = "0 0 1 20 * ?")
+    public void create() {
+        DateTime now = DateTime.now();
+        // 获取下一个月的日期
+        String nextMonth = DateUtil.format(DateUtil.offsetMonth(now, 1), "yyyy-MM-dd");
+        // 生成下一个月的数据
+        createByMonth(nextMonth);
+    }
+
+    @Scheduled(cron = "0 20 17 * * ?")
+    public void sendMessageData() {
+        String now = DateUtil.format(DateTime.now(), "yyyy-MM-dd");
+        SchedulingClass schedulingClass = dao.selectOne(SchedulingClass.lambdaQueryWrapper().eq(SchedulingClass::getSchedulingDate, now));
+        String code = StrUtil.isNotBlank(schedulingClass.getChangeClass()) ? schedulingClass.getChangeClass() : schedulingClass.getCode();
+        if (jcptMobile.getUrl() == null) {
+            return;
+        }
+        // 丁捷不发送
+        if ("01897".equals(code)) {
+            return;
+        }
+        UserInfo userInfo = userCache.get(code);
+        if (userInfo == null) {
+            return;
+        }
+        com.alibaba.fastjson.JSONObject data = new com.alibaba.fastjson.JSONObject() {{
+            put("touser", userInfo.getCodeRs());
+            put("msgtype", "text");
+            put("enable_id_trans", 0);
+            put("enable_duplicate_check", 0);
+            put("duplicate_check_interval", 1800);
+            put("text", new com.alibaba.fastjson.JSONObject() {{
+                put("content", "今天到你值班了,记得转电话哦。");
+            }});
+        }};
+
+        mobileService.post("/wecom/sendMsg")
+                .addBody(data)
+                .execute();
+    }
+
+
+    public List<CodeName> getCodes() {
+        return dao.getXinXiKeCode();
+    }
+
+    public ResultVo<String> createByMonth(String month) {
+        CreateMonth createMonth = new CreateMonth(month, getSortAndName());
+        List<SchedulingClass> computed = createMonth.computed();
+        dao.delete(SchedulingClass.lambdaQueryWrapper()
+                .ge(SchedulingClass::getSchedulingDate, createMonth.getFirstDayOfMonth())
+                .le(SchedulingClass::getSchedulingDate, createMonth.getLastDayOfMonth())
+        );
+        dao.insert(computed);
+        return null;
+    }
+
+
+    public List<CodeName> getSortAndName() {
+        String codes = dao.getSort();
+        return JSONUtil.toList(codes, CodeName.class);
+    }
+
+    public ResultVo<String> saveSort(JSONObject value) {
+        dao.updateDictData(value.getStr("data"));
+        return R.ok(ExceptionEnum.SUCCESS_AND_EL_MESSAGE);
+    }
+
+    public List<SchedulingClass.SchedulingClassVo> getByMonth(String month) {
+        Result result = getResult(month);
+        List<SchedulingClass.SchedulingClassVo> rst = dao.selectByDateVo(SchedulingClass.lambdaQueryWrapper()
+                .ge(SchedulingClass::getSchedulingDate, result.firstDayOfMonth)
+                .le(SchedulingClass::getSchedulingDate, result.lastDayOfMonth)
+                .orderByAsc(SchedulingClass::getSchedulingDate)
+        );
+        for (SchedulingClass.SchedulingClassVo item : rst) {
+            if (StrUtil.isNotBlank(item.getFalseCode())) {
+                item.setFalseCodeList(new ArrayList<>());
+                List<String> split = StrUtil.split(item.getFalseCode(), ",");
+                split.forEach(i -> {
+                    String employeeName = userCache.getEmployeeName(i);
+                    item.getFalseCodeList().add(new SimpleCodeName(i, employeeName));
+                });
+            }
+        }
+        return rst;
+    }
+
+    private @NotNull Result getResult(String month) {
+        DateTime parse = DateUtil.parse(month, "yyyy-MM");
+        // 获取第一个月
+        DateTime firstDayOfMonth = thyyxxk.webserver.utils.DateUtil.beginOfMonth(parse);
+        // 获取最后一个月
+        DateTime lastDayOfMonth = thyyxxk.webserver.utils.DateUtil.endOfMonth(parse);
+        return new Result(firstDayOfMonth, lastDayOfMonth);
+    }
+
+    private static class Result {
+        public final DateTime firstDayOfMonth;
+        public final DateTime lastDayOfMonth;
+
+        public Result(DateTime firstDayOfMonth, DateTime lastDayOfMonth) {
+            this.firstDayOfMonth = firstDayOfMonth;
+            this.lastDayOfMonth = lastDayOfMonth;
+        }
+    }
+
+    public ResultVo<String> updateById(SchedulingClass data) {
+        DateTime now = DateUtil.parse(DateUtil.format(DateTime.now(), "yyyy-MM-dd") + " 17:20:20");
+        SchedulingClass schedulingClass = dao.selectById(data.getId());
+        if (schedulingClass == null) {
+            return R.fail(ExceptionEnum.LOGICAL_ERROR, "没有找到数据");
+        }
+
+        if (now.compareTo(schedulingClass.getSchedulingDate()) > 0) {
+            return R.fail(ExceptionEnum.LOGICAL_ERROR, "数据固话无法修改。");
+        }
+
+        dao.updateById(data);
+        return R.ok(ExceptionEnum.SUCCESS_AND_EL_MESSAGE);
+    }
+
+}

+ 0 - 5
src/main/java/thyyxxk/webserver/service/zhuyuanyisheng/emr/EmrControlRuleSever.java

@@ -66,7 +66,6 @@ public class EmrControlRuleSever {
     }
 
     public void sendWxMessage(EmrLimitUnlock param) {
-
         if (jcptMobile.getUrl() == null) {
             return;
         }
@@ -76,7 +75,6 @@ public class EmrControlRuleSever {
             return String.join("|", yiWuBuUser);
         });
 
-
         String date = FastDateFormat.getInstance("yyyy年MM月dd日 HH时mm分")
                 .format(param.getApplicationTime());
 
@@ -89,15 +87,12 @@ public class EmrControlRuleSever {
     }
 
     private @NotNull JSONObject getMessageJson(String data, String description) {
-
         String url = StrUtil.format("{}?appid={}&redirect_uri={}/login?page=unlockemr&response_type=code&scope=snsapi_privateinfo&state=STATE&agentid={}#wechat_redirect",
                 jcptMobile.getUrl(),
                 jcptMobile.getAppid(),
                 jcptMobile.getAddress(),
                 jcptMobile.getAgentid()
         );
-
-
         return new JSONObject() {{
             put("touser", data);
             put("msgtype", "textcard");

+ 33 - 32
src/main/resources/application-dev.yml

@@ -14,7 +14,7 @@ spring:
     cache: false
   datasource:
     dynamic:
-      primary: prod
+      primary: his
       strict: false
       datasource:
         prod:
@@ -153,44 +153,44 @@ rmHkUserApi: http://172.16.30.66:20923/thyy/api/haikang/door/destructionUser
 
 thyy:
   ca:
-    timestamp-authentication:
-      url: http://172.16.32.135/services/TimeStampServices
-      app-code: ywxt
-      app-pwd: 12345678
+    #    timestamp-authentication:
+    #      url: http://172.16.32.135/services/TimeStampServices
+    #      app-code: ywxt
+    #      app-pwd: 12345678
+    #    sign-authentication:
+    #      app-code: ywxt
+    #      app-pwd: 12345678
+    #      sign-aig: "SM3withSM2"
+    #      url: http://172.16.32.135/services/CipherServices
+    #      container-name: "Cont1"
+    #    mobile-app:
+    #      app-id: 1
+    #      url: http://172.16.32.135:8080/openapi
+    #      privatekey: MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCCuwgon3RCGr3PZD7yH+1SC1i9PzochRma3ZTO6OPkbuH9ng0ePu6tvSSgVKkKg8Z9xgGVAFbH9KIJGK/xrgEMfTBVd3K4vyE8amymT9MPF2HsjR3ghZnFqIhNeF3MzrpxtduC8J8CMM3eSC7i4XGYVTvl+w2ACFMkAYz+IbdIIICSqZOvJ9xISIBpVMilpnYrLq0G9M2ov6voagGavMp+/dxXztRYlRDKKfOXhmHoFmatk6xMzuHiUs1/drb6n5LmT4uj+aL4JQhAzfBbU4sPbwy+lpWiM4VL/QVvE1k2KpfDeobDFon7Iyr8tnsTuTs1THaKoIBu2UVCao9EC/sNAgMBAAECggEATkMt1TPwY4qiyz+WN1lJt+43B8SMQ3qjI4U3is79b0m6XRx7efnu5W/wN1O3hyXwdGdPlyYGzdn0D0IKQsMKubFQeDn0Igm6GfMUbFQpZEV5SCYLFtikgCIux0Ih1XSFRYG7kh3+807IUCQifYy9dpbALyQmptlU/J85CwKgOLrp8l6CgJ87jLWpjNW4hRybNQRRxD3YnUiZ0O/dPpKmGSz1CZKzFmAfph8GD/WEXrIzL86A9eQN5sf9lFFlJ1Umzu2cgpNjylq8Zqi9wDOrqdxznPylJST8zZCv0kWy3K3YuORW4Z4GzR1kN3Xy50vOfl75T6Gw9rXXesqh0jaCgQKBgQDtgqV7Lk6+cXtLbymehK8c4jfCRQAxRNdBvURurwDnP86d/YpANtWyOJId+Q4AXUF3wtYdFUFdTsje4rajaQVMOozVSX2oaG+597QqUuvKlK8TEMB9MTzkVvUf15tkPihdCyii13A/3Qz0bJ2mcMf+ZJPLNBALnu5jN0rp3oHQnQKBgQCM6F4OWyy9PnmljjYkzIn9DP2AinGY6V/XHLc1rSkLtzlHDa4BKCJToZ0vB9MqxT1LTBTsbg4+VhZmHw9vtZr3fyPmDLUfNQi3Q0/m4udUIRH4ptpZUE/JOb3vGUrL/VdsTgjWos/nJxOvkbAg+74H9khPygKgRAfC3PPLXckxMQKBgQDWobGZV4ehYjvhN1uM/Kqil2t8C47Y9zTvG3Kz80IFuAunim9dCDClFao1m9OjUKLQ7yk+ru6au4+am5Ygpc87y81pETiU74vHqqkNdlHOh/6OZB0PBWfZkRuC4vxx4hnnuyXFwpqVm9URLPZqapDQu2MzxqCZX85dqqHwJjt5oQKBgFbRGJppzJ/w7Ux22Z9EssRKC6r2IdWf/J/yHmOhBAgm5NCFei9WRggXLFx8yruwePp6ru2ZRYdczUIwYvdmAkv5dunX7ISEzZD0lTdhmDv6gDMewquC0xXdUMwPXklfF00wqztrZwM5zWRANC+uS8BmGtmmUoXiRJHoRwGHEF4RAoGBALfswY8UTXR5AzY7+q4MhMdJjDe9mseK6HjrE2m3ClZ21nxLtLRA4y6hD7NXWKrrwliriz+DFiv1TQ2uLWTUH0TErOzCDxtOdxslFeva44dTzdVMUjj3OQ1KwDBdiZy107eYDnSPvDNjzNGKp6cT4YvO4WLK+MbqkiIoFbzGnZJO
+    #    HBoard-sign:
+    #      api-key: ywxt
+    #      api-secret: 12345678
+    #      url: http://172.16.32.135:8082
+    #      return-url: http://172.16.30.66:8706/casign/hBoardSignReturnUrl
     sign-authentication:
       app-code: ywxt
       app-pwd: 12345678
       sign-aig: "SM3withSM2"
-      url: http://172.16.32.135/services/CipherServices
+      url: "http://103.36.136.173:7845/services/CipherServices"
       container-name: "Cont1"
     mobile-app:
-      app-id: 1
-      url: http://172.16.32.135:8080/openapi
-      privatekey: MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCCuwgon3RCGr3PZD7yH+1SC1i9PzochRma3ZTO6OPkbuH9ng0ePu6tvSSgVKkKg8Z9xgGVAFbH9KIJGK/xrgEMfTBVd3K4vyE8amymT9MPF2HsjR3ghZnFqIhNeF3MzrpxtduC8J8CMM3eSC7i4XGYVTvl+w2ACFMkAYz+IbdIIICSqZOvJ9xISIBpVMilpnYrLq0G9M2ov6voagGavMp+/dxXztRYlRDKKfOXhmHoFmatk6xMzuHiUs1/drb6n5LmT4uj+aL4JQhAzfBbU4sPbwy+lpWiM4VL/QVvE1k2KpfDeobDFon7Iyr8tnsTuTs1THaKoIBu2UVCao9EC/sNAgMBAAECggEATkMt1TPwY4qiyz+WN1lJt+43B8SMQ3qjI4U3is79b0m6XRx7efnu5W/wN1O3hyXwdGdPlyYGzdn0D0IKQsMKubFQeDn0Igm6GfMUbFQpZEV5SCYLFtikgCIux0Ih1XSFRYG7kh3+807IUCQifYy9dpbALyQmptlU/J85CwKgOLrp8l6CgJ87jLWpjNW4hRybNQRRxD3YnUiZ0O/dPpKmGSz1CZKzFmAfph8GD/WEXrIzL86A9eQN5sf9lFFlJ1Umzu2cgpNjylq8Zqi9wDOrqdxznPylJST8zZCv0kWy3K3YuORW4Z4GzR1kN3Xy50vOfl75T6Gw9rXXesqh0jaCgQKBgQDtgqV7Lk6+cXtLbymehK8c4jfCRQAxRNdBvURurwDnP86d/YpANtWyOJId+Q4AXUF3wtYdFUFdTsje4rajaQVMOozVSX2oaG+597QqUuvKlK8TEMB9MTzkVvUf15tkPihdCyii13A/3Qz0bJ2mcMf+ZJPLNBALnu5jN0rp3oHQnQKBgQCM6F4OWyy9PnmljjYkzIn9DP2AinGY6V/XHLc1rSkLtzlHDa4BKCJToZ0vB9MqxT1LTBTsbg4+VhZmHw9vtZr3fyPmDLUfNQi3Q0/m4udUIRH4ptpZUE/JOb3vGUrL/VdsTgjWos/nJxOvkbAg+74H9khPygKgRAfC3PPLXckxMQKBgQDWobGZV4ehYjvhN1uM/Kqil2t8C47Y9zTvG3Kz80IFuAunim9dCDClFao1m9OjUKLQ7yk+ru6au4+am5Ygpc87y81pETiU74vHqqkNdlHOh/6OZB0PBWfZkRuC4vxx4hnnuyXFwpqVm9URLPZqapDQu2MzxqCZX85dqqHwJjt5oQKBgFbRGJppzJ/w7Ux22Z9EssRKC6r2IdWf/J/yHmOhBAgm5NCFei9WRggXLFx8yruwePp6ru2ZRYdczUIwYvdmAkv5dunX7ISEzZD0lTdhmDv6gDMewquC0xXdUMwPXklfF00wqztrZwM5zWRANC+uS8BmGtmmUoXiRJHoRwGHEF4RAoGBALfswY8UTXR5AzY7+q4MhMdJjDe9mseK6HjrE2m3ClZ21nxLtLRA4y6hD7NXWKrrwliriz+DFiv1TQ2uLWTUH0TErOzCDxtOdxslFeva44dTzdVMUjj3OQ1KwDBdiZy107eYDnSPvDNjzNGKp6cT4YvO4WLK+MbqkiIoFbzGnZJO
+      app-id: 3
+      url: https://device.mkeysec.net/openapi
+      privatekey: "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCHwpN7M6Xhja7sfaB0K3y2MBd4xLfhOF64mv0mtEZfqaWvphadXAimnfru8Y4sf0wDb9LYjacXRTkRMhZaZq5ZRCNFB+G8HnNb1y9Vr+7VqvT3wlRV0n+Jar+rEFguW293kH6wOLPQVNkmL4xEy/ecI81gfqR0wSHbyVWaBJ4o7w8qYVFc3is0vswl/bpKE2/4ngjEGDNuYdS0oXZR1TOjEEtNPEws9944yHyfYnbJgbTXkO78hlRUUu4tA8UnSjLrO0m0I6aQkuibPHKjMj247q2629L5IQpn+mGpgxmqUQmzSlKf5wg3uE0Ss1Bea8/AneSDBx2tzjsEs2qKn8cfAgMBAAECggEAM18GbaVCjNIPMf/rmmnmPA6AoztVFU0+Un6bcmzfAE3ymz+u6QatY1b+YDJZiS72NYq37yfS5XRVPtOEL9sQ+EhXTETKP2QKZONNTxBOwN166tHHFd6cUgRp2LJLm+cPi9/KgKZELH4e2Vs+qb3AyX2mtm/VjTSTulY6JRjAPF6EIyQqiLIinyw9TUXNqBs1kT5ma/50YPO2pSXWiOcXX9WWL7ECCNLCfKVRCKlEuaHuIozDuuwGHBrALAdqjWxrj0IMywCZIoVbBke+U7+KCKhKsc5eqsUJu8YfoVR3hxVhUHjlqIFbuAlLvrMqYZd3HgT1O3RSp/eOyXRMGsW0kQKBgQDHvA1p9Qv7K62WYOwwHEIg5Qym5uK4ClhvWUUQPE63bhzrkLkfNlDEOFpsnIk1EonvJHbfzW4pKR36AjbGBv9xxdgntkee+35pN8d8MT2eNMyHdsF6TDToKqPmqKHcxXmnpOCtC9Cam1wjBU+e7gdSoAeNWJeKUzg79HN7M7uD6QKBgQCuAPkd1G7GHkhMiXur1Td6nTmzwz9zPeHHycAE2r1epH22VUfKTu/oDgmky/VKO3JJuc1txt2bHs90iTLRDmcMy9l+6Ix9UJzmanAIRzhAVgmwz1liUNLbnJGl0YxCq0qlQA3FUUmOP36C2cvHcJm/hRIPG2O2nT1DLKsHvgU1xwKBgGL6mPciHU7aBUrZOxJYXpjoiQ2Iq1+imNKNPYFfMW8LHT/LV0HVa87hUkYyiHgJeNtOia48olO5cYZ8ZGJcA2iBL632UaXCYZGIt82epTdqWNTkj9qoOyu2PcTHWncKUVA3j7ORgE2tocolDqDmujBC55svBOHifaKQcE3khA9JAoGAf/fLPjrrNN00gsVhpJ/sa0qSEzh2w4QxNkOT6n4MYzxKD/xsDcc7/MfGI+K0BOHvTXVONXvZoqloHOaB7unOs8R/sivIlqjgmzyQJCZsojQkcFot/HZAfK6LFw4jPyzGev2+ou0DUZA0tHsEuSqAiC+PdnjIPpcpZOvG5KzFHCUCgYEAuLEUmIzQ7ex85Ulag2qfGj0CDMAq1R/rmwrk+1d2aP9GY890HwcyN5dlZGy8/Z/lMlzOGo1kDhhhwOfbiYSit00FdLChVux0wh8nyqqB4IuTy0S0ZeTNjWnjftpNaPXdHh5mpUXXKygCp3UT65HC6coaqoD3Vv8jE32svsz/uPE="
+    timestamp-authentication:
+      url: http://103.36.136.173:7845/services/TimeStampServices
+      app-code: ywxt
+      app-pwd: 12345678
     HBoard-sign:
-      api-key: ywxt
-      api-secret: 12345678
-      url: http://172.16.32.135:8082
-      return-url: http://172.16.30.66:8706/casign/hBoardSignReturnUrl
-#    sign-authentication:
-#      app-code: ywxt
-#      app-pwd: 12345678
-#      sign-aig: "SM3withSM2"
-#      url: "http://103.36.136.173:7845/services/CipherServices"
-#      container-name: "Cont1"
-#    mobile-app:
-#      app-id: 3
-#      url: https://device.mkeysec.net/openapi
-#      privatekey: "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCHwpN7M6Xhja7sfaB0K3y2MBd4xLfhOF64mv0mtEZfqaWvphadXAimnfru8Y4sf0wDb9LYjacXRTkRMhZaZq5ZRCNFB+G8HnNb1y9Vr+7VqvT3wlRV0n+Jar+rEFguW293kH6wOLPQVNkmL4xEy/ecI81gfqR0wSHbyVWaBJ4o7w8qYVFc3is0vswl/bpKE2/4ngjEGDNuYdS0oXZR1TOjEEtNPEws9944yHyfYnbJgbTXkO78hlRUUu4tA8UnSjLrO0m0I6aQkuibPHKjMj247q2629L5IQpn+mGpgxmqUQmzSlKf5wg3uE0Ss1Bea8/AneSDBx2tzjsEs2qKn8cfAgMBAAECggEAM18GbaVCjNIPMf/rmmnmPA6AoztVFU0+Un6bcmzfAE3ymz+u6QatY1b+YDJZiS72NYq37yfS5XRVPtOEL9sQ+EhXTETKP2QKZONNTxBOwN166tHHFd6cUgRp2LJLm+cPi9/KgKZELH4e2Vs+qb3AyX2mtm/VjTSTulY6JRjAPF6EIyQqiLIinyw9TUXNqBs1kT5ma/50YPO2pSXWiOcXX9WWL7ECCNLCfKVRCKlEuaHuIozDuuwGHBrALAdqjWxrj0IMywCZIoVbBke+U7+KCKhKsc5eqsUJu8YfoVR3hxVhUHjlqIFbuAlLvrMqYZd3HgT1O3RSp/eOyXRMGsW0kQKBgQDHvA1p9Qv7K62WYOwwHEIg5Qym5uK4ClhvWUUQPE63bhzrkLkfNlDEOFpsnIk1EonvJHbfzW4pKR36AjbGBv9xxdgntkee+35pN8d8MT2eNMyHdsF6TDToKqPmqKHcxXmnpOCtC9Cam1wjBU+e7gdSoAeNWJeKUzg79HN7M7uD6QKBgQCuAPkd1G7GHkhMiXur1Td6nTmzwz9zPeHHycAE2r1epH22VUfKTu/oDgmky/VKO3JJuc1txt2bHs90iTLRDmcMy9l+6Ix9UJzmanAIRzhAVgmwz1liUNLbnJGl0YxCq0qlQA3FUUmOP36C2cvHcJm/hRIPG2O2nT1DLKsHvgU1xwKBgGL6mPciHU7aBUrZOxJYXpjoiQ2Iq1+imNKNPYFfMW8LHT/LV0HVa87hUkYyiHgJeNtOia48olO5cYZ8ZGJcA2iBL632UaXCYZGIt82epTdqWNTkj9qoOyu2PcTHWncKUVA3j7ORgE2tocolDqDmujBC55svBOHifaKQcE3khA9JAoGAf/fLPjrrNN00gsVhpJ/sa0qSEzh2w4QxNkOT6n4MYzxKD/xsDcc7/MfGI+K0BOHvTXVONXvZoqloHOaB7unOs8R/sivIlqjgmzyQJCZsojQkcFot/HZAfK6LFw4jPyzGev2+ou0DUZA0tHsEuSqAiC+PdnjIPpcpZOvG5KzFHCUCgYEAuLEUmIzQ7ex85Ulag2qfGj0CDMAq1R/rmwrk+1d2aP9GY890HwcyN5dlZGy8/Z/lMlzOGo1kDhhhwOfbiYSit00FdLChVux0wh8nyqqB4IuTy0S0ZeTNjWnjftpNaPXdHh5mpUXXKygCp3UT65HC6coaqoD3Vv8jE32svsz/uPE="
-#    timestamp-authentication:
-#      url: http://103.36.136.173:7845/services/TimeStampServices
-#      app-code: ywxt
-#      app-pwd: 12345678
-#    HBoard-sign:
-#      api-key: "00000"
-#      api-secret: "00000000"
-#      url: http://47.100.199.230:8080/pdfsign_hw
-#      return-url: "https://emr.hnthyy.cn:9222/caTest/casign/hBoardSignReturnUrl"
+      api-key: "00000"
+      api-secret: "00000000"
+      url: http://47.100.199.230:8080/pdfsign_hw
+      return-url: "https://emr.hnthyy.cn:9222/caTest/casign/hBoardSignReturnUrl"
   apiurl:
     socket-api: http://demo.hnthyy.cn:20922/thyy/api/socket
     scheduled-api: http://172.16.32.133:21702/thyy/scheduled/api
@@ -204,6 +204,7 @@ thyy:
   jcptmobile:
     address: "https://emr.hnthyy.cn:8081"
     agentid: 1000051
+    url: "https://open.weixin.qq.com/connect/oauth2/authorize"
   system:
     yz-config:
       exceeding-discharge-days: 4