Procházet zdrojové kódy

教务端,增加财务签章接口

river před 4 roky
rodič
revize
d237a96c18

+ 7 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/EmployeeDao.java

@@ -194,4 +194,11 @@ public interface EmployeeDao extends BaseDAO<Integer, Employee> {
      * @return
      */
     List<String> queryVipGroupIdByUserId(Integer levelUserId);
+
+    /**
+     * 获取用户信息
+     * @param userIds
+     * @return
+     */
+    List<SysUser> getUsers(@Param("userIds") List<Integer> userIds);
 }

+ 96 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/CirculationUser.java

@@ -0,0 +1,96 @@
+package com.ym.mec.biz.dal.dto;
+
+import com.ym.mec.biz.dal.entity.SysUserTsign;
+import io.swagger.annotations.ApiModelProperty;
+
+public class CirculationUser {
+
+    @ApiModelProperty(value = "OA审批id", required = false)
+    private Integer workOrderId;
+
+    @ApiModelProperty(value = "审批节点", required = false)
+    private String state;
+
+    @ApiModelProperty(value = "审批意见", required = false)
+    private String remark;
+
+    @ApiModelProperty(value = "审批用户id", required = false)
+    private Integer userId;
+
+    @ApiModelProperty(value = "审批用户姓名", required = false)
+    private String realName;
+
+    @ApiModelProperty(value = "审批用户身份证号", required = false)
+    private String idCard;
+
+    @ApiModelProperty(value = "审批用户手机号", required = false)
+    private String phone;
+
+    @ApiModelProperty(value = "签章数据", required = false)
+    private SysUserTsign sysUserTsign;
+
+
+    public Integer getWorkOrderId() {
+        return workOrderId;
+    }
+
+    public void setWorkOrderId(Integer workOrderId) {
+        this.workOrderId = workOrderId;
+    }
+
+    public String getState() {
+        return state;
+    }
+
+    public void setState(String state) {
+        this.state = state;
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+
+    public Integer getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Integer userId) {
+        this.userId = userId;
+    }
+
+    public String getRealName() {
+        return realName;
+    }
+
+    public void setRealName(String realName) {
+        this.realName = realName;
+    }
+
+    public String getIdCard() {
+        return idCard;
+    }
+
+    public void setIdCard(String idCard) {
+        this.idCard = idCard;
+    }
+
+    public String getPhone() {
+        return phone;
+    }
+
+    public void setPhone(String phone) {
+        this.phone = phone;
+    }
+
+    public SysUserTsign getSysUserTsign() {
+        return sysUserTsign;
+    }
+
+    public void setSysUserTsign(SysUserTsign sysUserTsign) {
+        this.sysUserTsign = sysUserTsign;
+    }
+}

+ 12 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/ContractService.java

@@ -2,8 +2,10 @@ package com.ym.mec.biz.service;
 
 import java.math.BigDecimal;
 import java.util.Date;
+import java.util.List;
 import java.util.Map;
 
+import com.ym.mec.biz.dal.dto.CirculationUser;
 import com.ym.mec.biz.dal.entity.SysUserTsign;
 import com.ym.mec.biz.dal.enums.KitGroupPurchaseTypeEnum;
 import com.ym.mec.common.entity.HttpResponseResult;
@@ -128,4 +130,14 @@ public interface ContractService {
 	 * @return
 	 */
 	Map<String, Object> queryProductContract(Integer userId,String musicGroupId);
+
+
+	/**
+	 * OA财务审批的签章
+	 * @param circulationUsers 审批人
+	 * @param executors 执行人
+	 * @return
+	 */
+	String transferOaFinancial(List<CirculationUser> circulationUsers, List<CirculationUser> executors);
+
 }

+ 1100 - 999
mec-biz/src/main/java/com/ym/mec/biz/service/impl/ContractServiceImpl.java

@@ -8,9 +8,11 @@ import java.text.SimpleDateFormat;
 import java.time.LocalDateTime;
 import java.util.*;
 import java.util.Map.Entry;
+import java.util.stream.Collectors;
 
 import com.ym.mec.auth.api.enums.CertificateTypeEnum;
 import com.ym.mec.biz.dal.dao.*;
+import com.ym.mec.biz.dal.dto.CirculationUser;
 import com.ym.mec.biz.dal.enums.CourseViewTypeEnum;
 import com.ym.mec.common.controller.BaseController;
 import com.ym.mec.common.entity.HttpResponseResult;
@@ -76,1183 +78,1282 @@ import com.ym.mec.util.pdf.PDFUtil;
 @Service
 public class ContractServiceImpl implements ContractService, InitializingBean {
 
-	@Autowired
-	private SysUserTsignService sysUserTsignService;
+    @Autowired
+    private SysUserTsignService sysUserTsignService;
 
-	@Autowired
-	private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
 
-	@Autowired
-	private SysUserContractsService sysUserContractsService;
+    @Autowired
+    private SysUserContractsService sysUserContractsService;
 
-	@Autowired
-	private SysUserContractsDao sysUserContractsDao;
+    @Autowired
+    private SysUserContractsDao sysUserContractsDao;
 
-	@Autowired
-	private StudentRegistrationService studentRegistrationService;
+    @Autowired
+    private StudentRegistrationService studentRegistrationService;
 
-	@Autowired
-	private StudentRegistrationDao studentRegistrationDao;
+    @Autowired
+    private StudentRegistrationDao studentRegistrationDao;
 
-	@Autowired
-	private StudentPaymentOrderService studentPaymentOrderService;
+    @Autowired
+    private StudentPaymentOrderService studentPaymentOrderService;
 
-	@Autowired
-	private MusicGroupSubjectPlanService musicGroupSubjectPlanService;
+    @Autowired
+    private MusicGroupSubjectPlanService musicGroupSubjectPlanService;
 
-	@Autowired
-	private MusicGroupSubjectGoodsGroupService musicGroupSubjectGoodsGroupService;
+    @Autowired
+    private MusicGroupSubjectGoodsGroupService musicGroupSubjectGoodsGroupService;
 
-	@Autowired
-	private MusicGroupPaymentCalenderDao musicGroupPaymentCalenderDao;
+    @Autowired
+    private MusicGroupPaymentCalenderDao musicGroupPaymentCalenderDao;
 
-	@Autowired
-	private MusicGroupStudentFeeDao musicGroupStudentFeeDao;
+    @Autowired
+    private MusicGroupStudentFeeDao musicGroupStudentFeeDao;
 
-	@Autowired
-	private StudentPaymentOrderDetailDao studentPaymentOrderDetailDao;
+    @Autowired
+    private StudentPaymentOrderDetailDao studentPaymentOrderDetailDao;
 
-	@Autowired
-	@Lazy
-	private VipGroupService vipGroupService;
+    @Autowired
+    @Lazy
+    private VipGroupService vipGroupService;
 
-	@Autowired
-	private SubjectService subjectService;
+    @Autowired
+    private SubjectService subjectService;
 
-	@Autowired
-	private ESealPlugin eSealPlugin;
+    @Autowired
+    private ESealPlugin eSealPlugin;
 
-	@Autowired
-	private StoragePluginContext storagePluginContext;
+    @Autowired
+    private StoragePluginContext storagePluginContext;
 
-	@Autowired
-	private GoodsService goodsService;
+    @Autowired
+    private GoodsService goodsService;
 
-	@Autowired
-	private MusicGroupService musicGroupService;
+    @Autowired
+    private MusicGroupService musicGroupService;
 
-	@Autowired
-	private StudentDao studentDao;
+    @Autowired
+    private StudentDao studentDao;
 
-	@Value("${contract.baseDir:/var/pdf}")
-	private String contractBaseDir;
+    @Autowired
+    private EmployeeDao employeeDao;
 
-	@Value("${message.debugMode}")
-	private boolean debugMode;
+    @Value("${contract.baseDir:/var/pdf}")
+    private String contractBaseDir;
 
-	@Autowired
-	private RealnameAuthenticationPluginContext realnameAuthenticationPluginContext;
+    @Value("${message.debugMode}")
+    private boolean debugMode;
 
-	private DateFormat dateFormatOss = new SimpleDateFormat("yyyy/MM/dd");
+    @Autowired
+    private RealnameAuthenticationPluginContext realnameAuthenticationPluginContext;
 
-	private DateFormat dateFormat1 = new SimpleDateFormat("yyMMddHHmmSS");
+    private DateFormat dateFormatOss = new SimpleDateFormat("yyyy/MM/dd");
 
-	private final Logger logger = LoggerFactory.getLogger(ContractService.class);
+    private DateFormat dateFormat1 = new SimpleDateFormat("yyMMddHHmmSS");
 
-	@Override
-	public void afterPropertiesSet() throws Exception {
-		// 注册企业账户
-		Map<String, String> organList = new HashMap<String, String>();
-		organList.put("91420106333619290A", "武汉长乐长风乐器销售有限公司");
-		organList.put("91440300326364429H", "深圳大雅乐盟网络教育股份有限公司");
+    private final Logger logger = LoggerFactory.getLogger(ContractService.class);
 
-		for (Entry<String, String> organ : organList.entrySet()) {
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        // 注册企业账户
+        Map<String, String> organList = new HashMap<String, String>();
+        organList.put("91420106333619290A", "武汉长乐长风乐器销售有限公司");
+        organList.put("91440300326364429H", "深圳大雅乐盟网络教育股份有限公司");
 
-			String organCode = organ.getKey();
-			String orgName = organ.getValue();
+        for (Entry<String, String> organ : organList.entrySet()) {
 
-			SysUserTsign sysUserTsign = sysUserTsignService.queryByCardNo(organCode);
+            String organCode = organ.getKey();
+            String orgName = organ.getValue();
 
-			if (sysUserTsign == null) {
-				String accountId = eSealPlugin.createOrganAccount(orgName, organCode);
+            SysUserTsign sysUserTsign = sysUserTsignService.queryByCardNo(organCode);
 
-				if (StringUtils.isBlank(accountId)) {
-					throw new BizException("创建企业电子存证账户失败");
-				}
+            if (sysUserTsign == null) {
+                String accountId = eSealPlugin.createOrganAccount(orgName, organCode);
 
-				String sealData = eSealPlugin.createOrganSeal(accountId, "", "");
+                if (StringUtils.isBlank(accountId)) {
+                    throw new BizException("创建企业电子存证账户失败");
+                }
 
-				if (StringUtils.isBlank(sealData)) {
-					throw new BizException("创建电子存证印章失败");
-				}
+                String sealData = eSealPlugin.createOrganSeal(accountId, "", "");
 
-				sysUserTsign = new SysUserTsign(-1, accountId, sealData, orgName, organCode);
+                if (StringUtils.isBlank(sealData)) {
+                    throw new BizException("创建电子存证印章失败");
+                }
 
-				sysUserTsignService.insert(sysUserTsign);
-			}
-		}
-	}
+                sysUserTsign = new SysUserTsign(-1, accountId, sealData, orgName, organCode);
 
-	@Override
-	public SysUserTsign register(Integer userId, String realName, String idCardNo, String mobileNo) {
+                sysUserTsignService.insert(sysUserTsign);
+            }
+        }
+    }
 
-		if (StringUtils.isBlank(realName) || StringUtils.isBlank(idCardNo) || StringUtils.isBlank(mobileNo)) {
-			return null;
-		}
+    @Override
+    public SysUserTsign register(Integer userId, String realName, String idCardNo, String mobileNo) {
 
-		SysUserTsign sysUserTsign = sysUserTsignService.get(userId);
-		if (sysUserTsign == null) {
+        if (StringUtils.isBlank(realName) || StringUtils.isBlank(idCardNo) || StringUtils.isBlank(mobileNo)) {
+            return null;
+        }
 
-			String accountId = "";
-			String sealData = "";
+        SysUserTsign sysUserTsign = sysUserTsignService.get(userId);
+        if (sysUserTsign == null) {
 
-			SysUser user = studentDao.getUser(userId);
-			if (user == null) {
-				throw new BizException("用户信息查询失败");
-			}
+            String accountId = "";
+            String sealData = "";
 
-			if(CertificateTypeEnum.IDENTITY.getCode().equals(user.getCertificateType())){
-				if(!debugMode){
-					realnameAuthenticationPluginContext.getRealnameAuthenticationPlugin(LinkfaceRealnameAuthenticationPlugin.getName()).verify(realName, idCardNo);
-				}
+            SysUser user = studentDao.getUser(userId);
+            if (user == null) {
+                throw new BizException("用户信息查询失败");
+            }
 
-				accountId = eSealPlugin.createUserAccount(realName, idCardNo, mobileNo);
+            if (CertificateTypeEnum.IDENTITY.getCode().equals(user.getCertificateType())) {
+                if (!debugMode) {
+                    realnameAuthenticationPluginContext.getRealnameAuthenticationPlugin(LinkfaceRealnameAuthenticationPlugin.getName()).verify(realName, idCardNo);
+                }
 
-				if (StringUtils.isBlank(accountId)) {
-					throw new BizException("创建电子存证账户失败");
-				}
+                accountId = eSealPlugin.createUserAccount(realName, idCardNo, mobileNo);
 
-				sealData = eSealPlugin.createUserSeal(accountId);
+                if (StringUtils.isBlank(accountId)) {
+                    throw new BizException("创建电子存证账户失败");
+                }
 
-				if (StringUtils.isBlank(sealData)) {
-					throw new BizException("创建电子存证印章失败");
-				}
-			}
+                sealData = eSealPlugin.createUserSeal(accountId);
 
-			sysUserTsign = new SysUserTsign(userId, accountId, sealData, realName, idCardNo);
+                if (StringUtils.isBlank(sealData)) {
+                    throw new BizException("创建电子存证印章失败");
+                }
+            }
 
-			sysUserTsignService.insert(sysUserTsign);
+            sysUserTsign = new SysUserTsign(userId, accountId, sealData, realName, idCardNo);
 
-			return sysUserTsign;
-		}
+            sysUserTsignService.insert(sysUserTsign);
 
-		return null;
-	}
+            return sysUserTsign;
+        }
 
-	@Override
-	public boolean transferRegisterContract(Integer userId) {
+        return null;
+    }
 
-		SysUserTsign sysUserTsign = sysUserTsignService.get(userId);
+    @Override
+    public boolean transferRegisterContract(Integer userId) {
 
-		if (sysUserTsign == null) {
-			SysUser user = sysUserFeignService.queryUserById(userId);
-			if (user == null) {
-				throw new BizException("用户信息查询失败");
-			}
-			sysUserTsign = register(userId, user.getRealName(), user.getIdCardNo(), user.getPhone());
-		}
+        SysUserTsign sysUserTsign = sysUserTsignService.get(userId);
 
-		// 合成freemarker
-		String srcPdfPath = contractBaseDir + "/register/" + userId + ".pdf";
+        if (sysUserTsign == null) {
+            SysUser user = sysUserFeignService.queryUserById(userId);
+            if (user == null) {
+                throw new BizException("用户信息查询失败");
+            }
+            sysUserTsign = register(userId, user.getRealName(), user.getIdCardNo(), user.getPhone());
+        }
 
-		File srcFile = new File(srcPdfPath);
+        // 合成freemarker
+        String srcPdfPath = contractBaseDir + "/register/" + userId + ".pdf";
 
-		File debtFile = new File(srcFile.getParent());
-		if (!debtFile.exists()) {
-			debtFile.mkdirs();
-		}
+        File srcFile = new File(srcPdfPath);
 
-		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
-		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
+        File debtFile = new File(srcFile.getParent());
+        if (!debtFile.exists()) {
+            debtFile.mkdirs();
+        }
 
-		Map<String, Object> params = new HashMap<String, Object>();
+        FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
+        templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
 
-		templateEngine.render(params, "register.ftl", srcFile);
+        Map<String, Object> params = new HashMap<String, Object>();
 
-		// 生成借款协议PDF
-		try {
-			PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(srcFile), srcPdfPath, "simsun.ttc");
-		} catch (IOException e) {
-			throw new BizException("生成pdf协议失败", e);
-		}
+        templateEngine.render(params, "register.ftl", srcFile);
 
-		if (sysUserTsign != null) {
-			eSealPlugin.userSign(sysUserTsign.getAccountId(), sysUserTsign.getSealData(), srcPdfPath, srcPdfPath);
-		}
+        // 生成借款协议PDF
+        try {
+            PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(srcFile), srcPdfPath, "simsun.ttc");
+        } catch (IOException e) {
+            throw new BizException("生成pdf协议失败", e);
+        }
 
-		Date date = new Date();
-		// 上传到oss
-		String dateStrOss = dateFormatOss.format(date);
-		dateStrOss = "users/" + dateStrOss + "/" + DateUtil.getHour(date);
-		String pdfFilePath = storagePluginContext.uploadFile(KS3StoragePlugin.PLUGIN_NAME, dateStrOss, srcFile);
+        if (sysUserTsign != null) {
+            eSealPlugin.userSign(sysUserTsign.getAccountId(), sysUserTsign.getSealData(), srcPdfPath, srcPdfPath);
+        }
 
-		SysUserContracts sysUserContracts = new SysUserContracts();
-		sysUserContracts.setCreateTime(date);
-		sysUserContracts.setType(ContractType.REGISTER);
-		sysUserContracts.setUrl(pdfFilePath);
-		sysUserContracts.setUserId(userId);
+        Date date = new Date();
+        // 上传到oss
+        String dateStrOss = dateFormatOss.format(date);
+        dateStrOss = "users/" + dateStrOss + "/" + DateUtil.getHour(date);
+        String pdfFilePath = storagePluginContext.uploadFile(KS3StoragePlugin.PLUGIN_NAME, dateStrOss, srcFile);
 
-		sysUserContractsService.insert(sysUserContracts);
+        SysUserContracts sysUserContracts = new SysUserContracts();
+        sysUserContracts.setCreateTime(date);
+        sysUserContracts.setType(ContractType.REGISTER);
+        sysUserContracts.setUrl(pdfFilePath);
+        sysUserContracts.setUserId(userId);
 
-		FileUtils.deleteQuietly(srcFile);
+        sysUserContractsService.insert(sysUserContracts);
 
-		return true;
-	}
+        FileUtils.deleteQuietly(srcFile);
 
-	@Override
-	public String queryRegisterContract(Integer userId) {
+        return true;
+    }
 
-		// 合成freemarker
-		String srcPdfPath = contractBaseDir + "/register/" + userId + ".pdf";
+    @Override
+    public String queryRegisterContract(Integer userId) {
 
-		File srcFile = new File(srcPdfPath);
+        // 合成freemarker
+        String srcPdfPath = contractBaseDir + "/register/" + userId + ".pdf";
 
-		File debtFile = new File(srcFile.getParent());
-		if (!debtFile.exists()) {
-			debtFile.mkdirs();
-		}
+        File srcFile = new File(srcPdfPath);
 
-		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
-		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
+        File debtFile = new File(srcFile.getParent());
+        if (!debtFile.exists()) {
+            debtFile.mkdirs();
+        }
 
-		Map<String, Object> params = new HashMap<String, Object>();
+        FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
+        templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
 
-		templateEngine.render(params, "register.ftl", srcFile);
+        Map<String, Object> params = new HashMap<String, Object>();
 
-		String result = "";
-		try {
-			result = FileUtils.readFileToString(srcFile);
-		} catch (IOException e) {
-			throw new BizException("读取注册协议出错", e);
-		} finally {
-			FileUtils.deleteQuietly(srcFile);
-		}
+        templateEngine.render(params, "register.ftl", srcFile);
 
-		return result;
-	}
+        String result = "";
+        try {
+            result = FileUtils.readFileToString(srcFile);
+        } catch (IOException e) {
+            throw new BizException("读取注册协议出错", e);
+        } finally {
+            FileUtils.deleteQuietly(srcFile);
+        }
 
-	@Override
-	public boolean transferMusicGroupCoursesContract(Integer userId, String musicGroupId) {
-		if(true){
-			return transferProduceContract(userId, musicGroupId);
-		}
-		SysUserTsign sysUserTsign = sysUserTsignService.get(userId);
-
-		if (sysUserTsign == null) {
-			SysUser user = sysUserFeignService.queryUserById(userId);
-			if (user == null) {
-				throw new BizException("用户信息查询失败");
-			}
-			sysUserTsign = register(userId, user.getRealName(), user.getIdCardNo(), user.getPhone());
-		}
-		Date date = new Date();
-
-		// 合成freemarker
-		String srcPdfPath = contractBaseDir + "/courses/" + dateFormat1.format(date) + "/" + userId + ".pdf";
-
-		File srcFile = new File(srcPdfPath);
+        return result;
+    }
 
-		File debtFile = new File(srcFile.getParent());
-		if (!debtFile.exists()) {
-			debtFile.mkdirs();
-		}
-
-		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
-		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
-
-		Map<String, Object> params = new HashMap<String, Object>();
-
-		// 查询参数信息
-		StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
-		params.put("studentInfo", studentInfo);
-
-		// 课程类型
-		params.put("classesType", "乐团团课");
-
-		// 课程费用
-		StudentRegistration studentRegistration = studentRegistrationService.queryByUserIdAndMusicGroupId(userId, musicGroupId);
-		if (studentRegistration == null) {
-			throw new BizException("用户 报名信息不存在");
-		}
-		MusicGroupStudentFee musicGroupStudentFee = musicGroupStudentFeeDao.findByUser(userId, musicGroupId);
-		if (musicGroupStudentFee == null) {
-			MusicGroupSubjectPlan musicGroupSubjectPlan = musicGroupSubjectPlanService.getMusicOneSubjectClassPlan(musicGroupId,
-					studentRegistration.getActualSubjectId());
-			if (musicGroupSubjectPlan == null) {
-				throw new BizException("声部课程费用设置找不到");
-			}
-			params.put("courseFee", musicGroupSubjectPlan.getFee().doubleValue());
-		} else {
-			params.put("courseFee", musicGroupStudentFee.getTemporaryCourseFee().doubleValue() > 0 ? musicGroupStudentFee.getTemporaryCourseFee().doubleValue()
-					: musicGroupStudentFee.getCourseFee().doubleValue());
-		}
+    @Override
+    public boolean transferMusicGroupCoursesContract(Integer userId, String musicGroupId) {
+        if (true) {
+            return transferProduceContract(userId, musicGroupId);
+        }
+        SysUserTsign sysUserTsign = sysUserTsignService.get(userId);
+
+        if (sysUserTsign == null) {
+            SysUser user = sysUserFeignService.queryUserById(userId);
+            if (user == null) {
+                throw new BizException("用户信息查询失败");
+            }
+            sysUserTsign = register(userId, user.getRealName(), user.getIdCardNo(), user.getPhone());
+        }
+        Date date = new Date();
+
+        // 合成freemarker
+        String srcPdfPath = contractBaseDir + "/courses/" + dateFormat1.format(date) + "/" + userId + ".pdf";
+
+        File srcFile = new File(srcPdfPath);
 
-		// 收费形式
-		List<MusicGroupPaymentCalender> calenders = musicGroupPaymentCalenderDao.findByMusicGroupId(musicGroupId);
+        File debtFile = new File(srcFile.getParent());
+        if (!debtFile.exists()) {
+            debtFile.mkdirs();
+        }
+
+        FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
+        templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
+
+        Map<String, Object> params = new HashMap<String, Object>();
+
+        // 查询参数信息
+        StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
+        params.put("studentInfo", studentInfo);
+
+        // 课程类型
+        params.put("classesType", "乐团团课");
+
+        // 课程费用
+        StudentRegistration studentRegistration = studentRegistrationService.queryByUserIdAndMusicGroupId(userId, musicGroupId);
+        if (studentRegistration == null) {
+            throw new BizException("用户 报名信息不存在");
+        }
+        MusicGroupStudentFee musicGroupStudentFee = musicGroupStudentFeeDao.findByUser(userId, musicGroupId);
+        if (musicGroupStudentFee == null) {
+            MusicGroupSubjectPlan musicGroupSubjectPlan = musicGroupSubjectPlanService.getMusicOneSubjectClassPlan(musicGroupId,
+                    studentRegistration.getActualSubjectId());
+            if (musicGroupSubjectPlan == null) {
+                throw new BizException("声部课程费用设置找不到");
+            }
+            params.put("courseFee", musicGroupSubjectPlan.getFee().doubleValue());
+        } else {
+            params.put("courseFee", musicGroupStudentFee.getTemporaryCourseFee().doubleValue() > 0 ? musicGroupStudentFee.getTemporaryCourseFee().doubleValue()
+                    : musicGroupStudentFee.getCourseFee().doubleValue());
+        }
+
+        // 收费形式
+        List<MusicGroupPaymentCalender> calenders = musicGroupPaymentCalenderDao.findByMusicGroupId(musicGroupId);
 
 		/*if (calenders == null || calenders.size() == 0) {
-			
+
 		} else {
 			params.put("paymentcalender", calenders.stream().map(cal -> cal.getPaymentMonth().toString()).collect(Collectors.joining("月,")) + "月");
 		}*/
-		params.put("paymentcalender", "一次性");
-
-		params.put("isShowVisualSeal", false);
-
-		MusicGroup musicGroup = musicGroupService.get(musicGroupId);
-		if (musicGroup == null) {
-			throw new BizException("乐团信息没找到");
-		}
-
-		params.put("ownershipType", musicGroup.getOwnershipType().name());
-
-		templateEngine.render(params, "courses.ftl", srcFile);
-
-		// 生成借款协议PDF
-		try {
-			PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(srcFile), srcPdfPath, "simsun.ttc");
-		} catch (IOException e) {
-			throw new BizException("生成pdf协议失败", e);
-		}
-		String organCode = "";
-		if (musicGroup.getOwnershipType() == OwnershipType.OWN) {
-			organCode = "91440300326364429H";
-		} else {
-			organCode = "91420106333619290A";
-		}
-		SysUserTsign organTsign = sysUserTsignService.queryByCardNo(organCode);
-		if (organTsign == null) {
-			throw new BizException("甲方未创建签章");
-		}
-
-		eSealPlugin.organSign(organTsign.getSealData(), srcPdfPath, srcPdfPath);
-		if (sysUserTsign != null) {
-			eSealPlugin.userSign(sysUserTsign.getAccountId(), sysUserTsign.getSealData(), srcPdfPath, srcPdfPath);
-		}
-
-		// 上传到oss
-		String dateStrOss = dateFormatOss.format(date);
-		dateStrOss = "musicCourses/" + dateStrOss + "/" + DateUtil.getHour(date);
-		String pdfFilePath = storagePluginContext.uploadFile(KS3StoragePlugin.PLUGIN_NAME, dateStrOss, srcFile);
-
-		SysUserContracts sysUserContracts = new SysUserContracts();
-		sysUserContracts.setCreateTime(date);
-		sysUserContracts.setType(ContractType.COURSES);
-		sysUserContracts.setUrl(pdfFilePath);
-		sysUserContracts.setUserId(userId);
-
-		sysUserContractsService.insert(sysUserContracts);
-
-		FileUtils.deleteQuietly(srcFile);
-
-		return true;
-	}
-
-	@Override
-	public String queryMusicGroupCoursesContract(Integer userId, String musicGroupId) {
-
-		// 合成freemarker
-		String srcPdfPath = contractBaseDir + "/courses/" + userId + ".pdf";
-
-		File srcFile = new File(srcPdfPath);
-
-		File debtFile = new File(srcFile.getParent());
-		if (!debtFile.exists()) {
-			debtFile.mkdirs();
-		}
-
-		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
-		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
-
-		Map<String, Object> params = new HashMap<String, Object>();
-
-		StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
-		params.put("studentInfo", studentInfo);
-
-		// 课程类型
-		params.put("classesType", "乐团团课");
-
-		// 课程费用
-		StudentRegistration studentRegistration = studentRegistrationService.queryByUserIdAndMusicGroupId(userId, musicGroupId);
-		if (studentRegistration == null) {
-			throw new BizException("用户报名信息不存在");
-		}
-		MusicGroupStudentFee musicGroupStudentFee = musicGroupStudentFeeDao.findByUser(userId, musicGroupId);
-		if (musicGroupStudentFee == null) {
-			MusicGroupSubjectPlan musicGroupSubjectPlan = musicGroupSubjectPlanService.getMusicOneSubjectClassPlan(musicGroupId,
-					studentRegistration.getActualSubjectId());
-			if (musicGroupSubjectPlan == null) {
-				throw new BizException("声部课程费用设置找不到");
-			}
-			params.put("courseFee", musicGroupSubjectPlan.getFee().doubleValue());
-		} else {
-			params.put(
-					"courseFee",
-					(musicGroupStudentFee.getTemporaryCourseFee() != null && musicGroupStudentFee.getTemporaryCourseFee().doubleValue() > 0) ? musicGroupStudentFee
-							.getTemporaryCourseFee().doubleValue() : musicGroupStudentFee.getCourseFee().doubleValue());
-		}
-
-		// 收费形式
-		List<MusicGroupPaymentCalender> calenders = musicGroupPaymentCalenderDao.findByMusicGroupId(musicGroupId);
+        params.put("paymentcalender", "一次性");
+
+        params.put("isShowVisualSeal", false);
+
+        MusicGroup musicGroup = musicGroupService.get(musicGroupId);
+        if (musicGroup == null) {
+            throw new BizException("乐团信息没找到");
+        }
+
+        params.put("ownershipType", musicGroup.getOwnershipType().name());
+
+        templateEngine.render(params, "courses.ftl", srcFile);
+
+        // 生成借款协议PDF
+        try {
+            PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(srcFile), srcPdfPath, "simsun.ttc");
+        } catch (IOException e) {
+            throw new BizException("生成pdf协议失败", e);
+        }
+        String organCode = "";
+        if (musicGroup.getOwnershipType() == OwnershipType.OWN) {
+            organCode = "91440300326364429H";
+        } else {
+            organCode = "91420106333619290A";
+        }
+        SysUserTsign organTsign = sysUserTsignService.queryByCardNo(organCode);
+        if (organTsign == null) {
+            throw new BizException("甲方未创建签章");
+        }
+
+        eSealPlugin.organSign(organTsign.getSealData(), srcPdfPath, srcPdfPath);
+        if (sysUserTsign != null) {
+            eSealPlugin.userSign(sysUserTsign.getAccountId(), sysUserTsign.getSealData(), srcPdfPath, srcPdfPath);
+        }
+
+        // 上传到oss
+        String dateStrOss = dateFormatOss.format(date);
+        dateStrOss = "musicCourses/" + dateStrOss + "/" + DateUtil.getHour(date);
+        String pdfFilePath = storagePluginContext.uploadFile(KS3StoragePlugin.PLUGIN_NAME, dateStrOss, srcFile);
+
+        SysUserContracts sysUserContracts = new SysUserContracts();
+        sysUserContracts.setCreateTime(date);
+        sysUserContracts.setType(ContractType.COURSES);
+        sysUserContracts.setUrl(pdfFilePath);
+        sysUserContracts.setUserId(userId);
+
+        sysUserContractsService.insert(sysUserContracts);
+
+        FileUtils.deleteQuietly(srcFile);
+
+        return true;
+    }
+
+    @Override
+    public String queryMusicGroupCoursesContract(Integer userId, String musicGroupId) {
+
+        // 合成freemarker
+        String srcPdfPath = contractBaseDir + "/courses/" + userId + ".pdf";
+
+        File srcFile = new File(srcPdfPath);
+
+        File debtFile = new File(srcFile.getParent());
+        if (!debtFile.exists()) {
+            debtFile.mkdirs();
+        }
+
+        FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
+        templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
+
+        Map<String, Object> params = new HashMap<String, Object>();
+
+        StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
+        params.put("studentInfo", studentInfo);
+
+        // 课程类型
+        params.put("classesType", "乐团团课");
+
+        // 课程费用
+        StudentRegistration studentRegistration = studentRegistrationService.queryByUserIdAndMusicGroupId(userId, musicGroupId);
+        if (studentRegistration == null) {
+            throw new BizException("用户报名信息不存在");
+        }
+        MusicGroupStudentFee musicGroupStudentFee = musicGroupStudentFeeDao.findByUser(userId, musicGroupId);
+        if (musicGroupStudentFee == null) {
+            MusicGroupSubjectPlan musicGroupSubjectPlan = musicGroupSubjectPlanService.getMusicOneSubjectClassPlan(musicGroupId,
+                    studentRegistration.getActualSubjectId());
+            if (musicGroupSubjectPlan == null) {
+                throw new BizException("声部课程费用设置找不到");
+            }
+            params.put("courseFee", musicGroupSubjectPlan.getFee().doubleValue());
+        } else {
+            params.put(
+                    "courseFee",
+                    (musicGroupStudentFee.getTemporaryCourseFee() != null && musicGroupStudentFee.getTemporaryCourseFee().doubleValue() > 0) ? musicGroupStudentFee
+                            .getTemporaryCourseFee().doubleValue() : musicGroupStudentFee.getCourseFee().doubleValue());
+        }
+
+        // 收费形式
+        List<MusicGroupPaymentCalender> calenders = musicGroupPaymentCalenderDao.findByMusicGroupId(musicGroupId);
 
 		/*if (calenders == null || calenders.size() == 0) {
 			params.put("paymentcalender", "一次性");
 		} else {
 			params.put("paymentcalender", calenders.stream().map(cal -> cal.getPaymentMonth().toString()).collect(Collectors.joining("月,")) + "月");
 		}*/
-		
-		params.put("paymentcalender", "一次性");
-
-		params.put("isShowVisualSeal", true);
-
-		MusicGroup musicGroup = musicGroupService.get(musicGroupId);
-		if (musicGroup == null) {
-			throw new BizException("乐团信息没找到");
-		}
 
-		params.put("ownershipType", musicGroup.getOwnershipType().name());
+        params.put("paymentcalender", "一次性");
 
-		templateEngine.render(params, "courses.ftl", srcFile);
+        params.put("isShowVisualSeal", true);
 
-		String result = "";
-		try {
-			result = FileUtils.readFileToString(srcFile);
-		} catch (IOException e) {
-			throw new BizException("读取课程协议出错", e);
-		} finally {
-			FileUtils.deleteQuietly(srcFile);
-		}
+        MusicGroup musicGroup = musicGroupService.get(musicGroupId);
+        if (musicGroup == null) {
+            throw new BizException("乐团信息没找到");
+        }
 
-		return result;
-	}
+        params.put("ownershipType", musicGroup.getOwnershipType().name());
 
-	@Override
-	public boolean transferVipGroupCoursesContract(Integer userId, Long vipGroupId) {
-		if(true){
-			return transferProduceContract(userId, null);
-		}
+        templateEngine.render(params, "courses.ftl", srcFile);
 
-		SysUserTsign sysUserTsign = sysUserTsignService.get(userId);
+        String result = "";
+        try {
+            result = FileUtils.readFileToString(srcFile);
+        } catch (IOException e) {
+            throw new BizException("读取课程协议出错", e);
+        } finally {
+            FileUtils.deleteQuietly(srcFile);
+        }
 
-		if (sysUserTsign == null) {
-			SysUser user = sysUserFeignService.queryUserById(userId);
-			if (user == null) {
-				throw new BizException("用户信息查询失败");
-			}
-			sysUserTsign = register(userId, user.getRealName(), user.getIdCardNo(), user.getPhone());
-		}
-		Date date = new Date();
+        return result;
+    }
 
-		// 合成freemarker
-		String srcPdfPath = contractBaseDir + "/vipCourses/" + dateFormat1.format(date) + "/" + userId + ".pdf";
+    @Override
+    public boolean transferVipGroupCoursesContract(Integer userId, Long vipGroupId) {
+        if (true) {
+            return transferProduceContract(userId, null);
+        }
 
-		File srcFile = new File(srcPdfPath);
+        SysUserTsign sysUserTsign = sysUserTsignService.get(userId);
 
-		File debtFile = new File(srcFile.getParent());
-		if (!debtFile.exists()) {
-			debtFile.mkdirs();
-		}
+        if (sysUserTsign == null) {
+            SysUser user = sysUserFeignService.queryUserById(userId);
+            if (user == null) {
+                throw new BizException("用户信息查询失败");
+            }
+            sysUserTsign = register(userId, user.getRealName(), user.getIdCardNo(), user.getPhone());
+        }
+        Date date = new Date();
 
-		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
-		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
+        // 合成freemarker
+        String srcPdfPath = contractBaseDir + "/vipCourses/" + dateFormat1.format(date) + "/" + userId + ".pdf";
 
-		Map<String, Object> params = new HashMap<String, Object>();
+        File srcFile = new File(srcPdfPath);
 
-		// 查询参数信息
-		StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
-		params.put("studentInfo", studentInfo);
+        File debtFile = new File(srcFile.getParent());
+        if (!debtFile.exists()) {
+            debtFile.mkdirs();
+        }
 
-		// 课程类型
-		params.put("classesType", "VIP课");
+        FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
+        templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
 
-		// 课程费用
-		VipGroup vipGroup = vipGroupService.get(vipGroupId);
-		if (vipGroup == null) {
-			throw new BizException("VIP课找不到");
-		}
-		params.put("courseFee", vipGroup.getTotalPrice().doubleValue());
+        Map<String, Object> params = new HashMap<String, Object>();
 
-		// 收费形式
-		params.put("paymentcalender", "一次性");
+        // 查询参数信息
+        StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
+        params.put("studentInfo", studentInfo);
 
-		params.put("isShowVisualSeal", false);
+        // 课程类型
+        params.put("classesType", "VIP课");
 
-		params.put("ownershipType", "OWN");
+        // 课程费用
+        VipGroup vipGroup = vipGroupService.get(vipGroupId);
+        if (vipGroup == null) {
+            throw new BizException("VIP课找不到");
+        }
+        params.put("courseFee", vipGroup.getTotalPrice().doubleValue());
 
-		templateEngine.render(params, "courses.ftl", srcFile);
+        // 收费形式
+        params.put("paymentcalender", "一次性");
 
-		// 生成借款协议PDF
-		try {
-			PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(srcFile), srcPdfPath, "simsun.ttc");
-		} catch (IOException e) {
-			throw new BizException("生成pdf协议失败", e);
-		}
-		String organCode = "91440300326364429H";
-		SysUserTsign organTsign = sysUserTsignService.queryByCardNo(organCode);
-		if (organTsign == null) {
-			throw new BizException("甲方未创建签章");
-		}
+        params.put("isShowVisualSeal", false);
 
-		eSealPlugin.organSign(organTsign.getSealData(), srcPdfPath, srcPdfPath);
+        params.put("ownershipType", "OWN");
 
-		if (sysUserTsign != null) {
-			eSealPlugin.userSign(sysUserTsign.getAccountId(), sysUserTsign.getSealData(), srcPdfPath, srcPdfPath);
-		}
+        templateEngine.render(params, "courses.ftl", srcFile);
 
-		// 上传到oss
-		String dateStrOss = dateFormatOss.format(date);
-		dateStrOss = "vipCourses/" + dateStrOss + "/" + DateUtil.getHour(date);
-		String pdfFilePath = storagePluginContext.uploadFile(KS3StoragePlugin.PLUGIN_NAME, dateStrOss, srcFile);
+        // 生成借款协议PDF
+        try {
+            PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(srcFile), srcPdfPath, "simsun.ttc");
+        } catch (IOException e) {
+            throw new BizException("生成pdf协议失败", e);
+        }
+        String organCode = "91440300326364429H";
+        SysUserTsign organTsign = sysUserTsignService.queryByCardNo(organCode);
+        if (organTsign == null) {
+            throw new BizException("甲方未创建签章");
+        }
 
-		SysUserContracts sysUserContracts = new SysUserContracts();
-		sysUserContracts.setCreateTime(date);
-		sysUserContracts.setType(ContractType.VIP_COURSES);
-		sysUserContracts.setUrl(pdfFilePath);
-		sysUserContracts.setUserId(userId);
+        eSealPlugin.organSign(organTsign.getSealData(), srcPdfPath, srcPdfPath);
 
-		sysUserContractsService.insert(sysUserContracts);
+        if (sysUserTsign != null) {
+            eSealPlugin.userSign(sysUserTsign.getAccountId(), sysUserTsign.getSealData(), srcPdfPath, srcPdfPath);
+        }
 
-		FileUtils.deleteQuietly(srcFile);
+        // 上传到oss
+        String dateStrOss = dateFormatOss.format(date);
+        dateStrOss = "vipCourses/" + dateStrOss + "/" + DateUtil.getHour(date);
+        String pdfFilePath = storagePluginContext.uploadFile(KS3StoragePlugin.PLUGIN_NAME, dateStrOss, srcFile);
 
-		return true;
-	}
+        SysUserContracts sysUserContracts = new SysUserContracts();
+        sysUserContracts.setCreateTime(date);
+        sysUserContracts.setType(ContractType.VIP_COURSES);
+        sysUserContracts.setUrl(pdfFilePath);
+        sysUserContracts.setUserId(userId);
 
-	@Override
-	public String queryVipGroupCoursesContract(Integer userId, Long vipGroupId) {
+        sysUserContractsService.insert(sysUserContracts);
 
-		// 合成freemarker
-		String srcPdfPath = contractBaseDir + "/courses/" + userId + ".pdf";
+        FileUtils.deleteQuietly(srcFile);
 
-		File srcFile = new File(srcPdfPath);
+        return true;
+    }
 
-		File debtFile = new File(srcFile.getParent());
-		if (!debtFile.exists()) {
-			debtFile.mkdirs();
-		}
+    @Override
+    public String queryVipGroupCoursesContract(Integer userId, Long vipGroupId) {
 
-		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
-		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
+        // 合成freemarker
+        String srcPdfPath = contractBaseDir + "/courses/" + userId + ".pdf";
 
-		Map<String, Object> params = new HashMap<String, Object>();
+        File srcFile = new File(srcPdfPath);
 
-		StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
-		params.put("studentInfo", studentInfo);
+        File debtFile = new File(srcFile.getParent());
+        if (!debtFile.exists()) {
+            debtFile.mkdirs();
+        }
 
-		// 课程类型
-		params.put("classesType", "VIP课");
+        FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
+        templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
 
-		// 课程费用
-		VipGroup vipGroup = vipGroupService.get(vipGroupId);
-		if (vipGroup == null) {
-			throw new BizException("VIP课找不到");
-		}
-		params.put("courseFee", vipGroup.getTotalPrice().doubleValue());
+        Map<String, Object> params = new HashMap<String, Object>();
 
-		// 收费形式
-		params.put("paymentcalender", "一次性");
+        StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
+        params.put("studentInfo", studentInfo);
 
-		params.put("isShowVisualSeal", true);
+        // 课程类型
+        params.put("classesType", "VIP课");
 
-		params.put("ownershipType", "OWN");
+        // 课程费用
+        VipGroup vipGroup = vipGroupService.get(vipGroupId);
+        if (vipGroup == null) {
+            throw new BizException("VIP课找不到");
+        }
+        params.put("courseFee", vipGroup.getTotalPrice().doubleValue());
 
-		templateEngine.render(params, "courses.ftl", srcFile);
+        // 收费形式
+        params.put("paymentcalender", "一次性");
 
-		String result = "";
-		try {
-			result = FileUtils.readFileToString(srcFile);
-		} catch (IOException e) {
-			throw new BizException("读取课程协议出错", e);
-		} finally {
-			FileUtils.deleteQuietly(srcFile);
-		}
+        params.put("isShowVisualSeal", true);
 
-		return result;
-	}
+        params.put("ownershipType", "OWN");
 
-	@Override
-	public boolean transferGoodsContract(Integer userId, String musicGroupId, String goodsIds, KitGroupPurchaseTypeEnum kitGroupPurchaseTypeEnum) {
-		if(true){
-			return transferProduceContract(userId, musicGroupId);
-		}
+        templateEngine.render(params, "courses.ftl", srcFile);
 
-		SysUserTsign sysUserTsign = sysUserTsignService.get(userId);
+        String result = "";
+        try {
+            result = FileUtils.readFileToString(srcFile);
+        } catch (IOException e) {
+            throw new BizException("读取课程协议出错", e);
+        } finally {
+            FileUtils.deleteQuietly(srcFile);
+        }
 
-		if (sysUserTsign == null) {
-			SysUser user = sysUserFeignService.queryUserById(userId);
-			if (user == null) {
-				throw new BizException("用户信息查询失败");
-			}
-			sysUserTsign = register(userId, user.getRealName(), user.getIdCardNo(), user.getPhone());
-		}
-		Date date = new Date();
+        return result;
+    }
 
-		// 合成freemarker
-		String srcPdfPath = contractBaseDir + "/goods/" + dateFormat1.format(date) + "/" + userId + ".pdf";
+    @Override
+    public boolean transferGoodsContract(Integer userId, String musicGroupId, String goodsIds, KitGroupPurchaseTypeEnum kitGroupPurchaseTypeEnum) {
+        if (true) {
+            return transferProduceContract(userId, musicGroupId);
+        }
 
-		File srcFile = new File(srcPdfPath);
+        SysUserTsign sysUserTsign = sysUserTsignService.get(userId);
 
-		File debtFile = new File(srcFile.getParent());
-		if (!debtFile.exists()) {
-			debtFile.mkdirs();
-		}
+        if (sysUserTsign == null) {
+            SysUser user = sysUserFeignService.queryUserById(userId);
+            if (user == null) {
+                throw new BizException("用户信息查询失败");
+            }
+            sysUserTsign = register(userId, user.getRealName(), user.getIdCardNo(), user.getPhone());
+        }
+        Date date = new Date();
 
-		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
-		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
+        // 合成freemarker
+        String srcPdfPath = contractBaseDir + "/goods/" + dateFormat1.format(date) + "/" + userId + ".pdf";
 
-		Map<String, Object> params = new HashMap<String, Object>();
+        File srcFile = new File(srcPdfPath);
 
-		// 查询参数信息
-		StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
+        File debtFile = new File(srcFile.getParent());
+        if (!debtFile.exists()) {
+            debtFile.mkdirs();
+        }
 
-		int subjectId = studentInfo.getSubject().getId();
+        FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
+        templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
 
-		Subject subject = subjectService.get(subjectId);
-		studentInfo.setSubject(subject);
+        Map<String, Object> params = new HashMap<String, Object>();
 
-		params.put("studentInfo", studentInfo);
+        // 查询参数信息
+        StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
 
-		List<Goods> goodsList = goodsService.findGoodsByIds(goodsIds);
-		params.put("goodsList", goodsList);
+        int subjectId = studentInfo.getSubject().getId();
 
-		double depositFee = 0d;
-		if (kitGroupPurchaseTypeEnum == KitGroupPurchaseTypeEnum.LEASE) {
-			StudentPaymentOrder studentPaymentOrder = studentPaymentOrderService.findMusicGroupApplyOrderByStatus(userId, musicGroupId, DealStatusEnum.SUCCESS);
+        Subject subject = subjectService.get(subjectId);
+        studentInfo.setSubject(subject);
 
-			if (studentPaymentOrder == null) {
-				MusicGroupSubjectGoodsGroup musicGroupSubjectPlan = musicGroupSubjectGoodsGroupService.query(musicGroupId, subjectId, goodsIds);
-				if (musicGroupSubjectPlan != null) {
-					depositFee = musicGroupSubjectPlan.getDepositFee().doubleValue();
-				}
-			} else {
+        params.put("studentInfo", studentInfo);
 
-				List<StudentPaymentOrderDetail> orderDetailList = studentPaymentOrderDetailDao.findApplyOrderGoods(studentPaymentOrder.getId());
-				for (StudentPaymentOrderDetail detail : orderDetailList) {
-					if (detail.getType() == OrderDetailTypeEnum.MUSICAL) {
-						depositFee = detail.getPrice().doubleValue();
-					}
-				}
-			}
-		}
-		params.put("depositFee", depositFee);
-		params.put("depositFeeFmt", MoneyUtil.toChinese(depositFee + ""));
-
-		params.put("isShowVisualSeal", false);
+        List<Goods> goodsList = goodsService.findGoodsByIds(goodsIds);
+        params.put("goodsList", goodsList);
 
-		MusicGroup musicGroup = musicGroupService.get(musicGroupId);
-		if (musicGroup == null) {
-			throw new BizException("乐团信息没找到");
-		}
-
-		params.put("ownershipType", musicGroup.getOwnershipType().name());
-
-		templateEngine.render(params, "goods.ftl", srcFile);
-
-		// 生成借款协议PDF
-		try {
-			PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(srcFile), srcPdfPath, "simsun.ttc");
-		} catch (IOException e) {
-			throw new BizException("生成pdf协议失败", e);
-		}
-		String organCode = "";
-		if (musicGroup.getOwnershipType() == OwnershipType.OWN) {
-			organCode = "91440300326364429H";
-		} else {
-			organCode = "91420106333619290A";
-		}
-		SysUserTsign organTsign = sysUserTsignService.queryByCardNo(organCode);
-		if (organTsign == null) {
-			throw new BizException("甲方未创建签章");
-		}
+        double depositFee = 0d;
+        if (kitGroupPurchaseTypeEnum == KitGroupPurchaseTypeEnum.LEASE) {
+            StudentPaymentOrder studentPaymentOrder = studentPaymentOrderService.findMusicGroupApplyOrderByStatus(userId, musicGroupId, DealStatusEnum.SUCCESS);
 
-		eSealPlugin.organSign(organTsign.getSealData(), srcPdfPath, srcPdfPath);
+            if (studentPaymentOrder == null) {
+                MusicGroupSubjectGoodsGroup musicGroupSubjectPlan = musicGroupSubjectGoodsGroupService.query(musicGroupId, subjectId, goodsIds);
+                if (musicGroupSubjectPlan != null) {
+                    depositFee = musicGroupSubjectPlan.getDepositFee().doubleValue();
+                }
+            } else {
 
-		if (sysUserTsign != null) {
-			eSealPlugin.userSign(sysUserTsign.getAccountId(), sysUserTsign.getSealData(), srcPdfPath, srcPdfPath);
-		}
+                List<StudentPaymentOrderDetail> orderDetailList = studentPaymentOrderDetailDao.findApplyOrderGoods(studentPaymentOrder.getId());
+                for (StudentPaymentOrderDetail detail : orderDetailList) {
+                    if (detail.getType() == OrderDetailTypeEnum.MUSICAL) {
+                        depositFee = detail.getPrice().doubleValue();
+                    }
+                }
+            }
+        }
+        params.put("depositFee", depositFee);
+        params.put("depositFeeFmt", MoneyUtil.toChinese(depositFee + ""));
 
-		// 上传到oss
-		String dateStrOss = dateFormatOss.format(date);
-		dateStrOss = "goods/" + dateStrOss + "/" + DateUtil.getHour(date);
-		String pdfFilePath = storagePluginContext.uploadFile(KS3StoragePlugin.PLUGIN_NAME, dateStrOss, srcFile);
+        params.put("isShowVisualSeal", false);
 
-		SysUserContracts sysUserContracts = new SysUserContracts();
-		sysUserContracts.setCreateTime(date);
-		sysUserContracts.setType(ContractType.INSTRUMENT);
-		sysUserContracts.setUrl(pdfFilePath);
-		sysUserContracts.setUserId(userId);
+        MusicGroup musicGroup = musicGroupService.get(musicGroupId);
+        if (musicGroup == null) {
+            throw new BizException("乐团信息没找到");
+        }
+
+        params.put("ownershipType", musicGroup.getOwnershipType().name());
 
-		sysUserContractsService.insert(sysUserContracts);
+        templateEngine.render(params, "goods.ftl", srcFile);
 
-		FileUtils.deleteQuietly(srcFile);
+        // 生成借款协议PDF
+        try {
+            PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(srcFile), srcPdfPath, "simsun.ttc");
+        } catch (IOException e) {
+            throw new BizException("生成pdf协议失败", e);
+        }
+        String organCode = "";
+        if (musicGroup.getOwnershipType() == OwnershipType.OWN) {
+            organCode = "91440300326364429H";
+        } else {
+            organCode = "91420106333619290A";
+        }
+        SysUserTsign organTsign = sysUserTsignService.queryByCardNo(organCode);
+        if (organTsign == null) {
+            throw new BizException("甲方未创建签章");
+        }
+
+        eSealPlugin.organSign(organTsign.getSealData(), srcPdfPath, srcPdfPath);
 
-		return true;
-	}
+        if (sysUserTsign != null) {
+            eSealPlugin.userSign(sysUserTsign.getAccountId(), sysUserTsign.getSealData(), srcPdfPath, srcPdfPath);
+        }
+
+        // 上传到oss
+        String dateStrOss = dateFormatOss.format(date);
+        dateStrOss = "goods/" + dateStrOss + "/" + DateUtil.getHour(date);
+        String pdfFilePath = storagePluginContext.uploadFile(KS3StoragePlugin.PLUGIN_NAME, dateStrOss, srcFile);
 
-	@Override
-	public String queryGoodsContract(Integer userId, String musicGroupId, String goodsIds, KitGroupPurchaseTypeEnum kitGroupPurchaseTypeEnum) {
+        SysUserContracts sysUserContracts = new SysUserContracts();
+        sysUserContracts.setCreateTime(date);
+        sysUserContracts.setType(ContractType.INSTRUMENT);
+        sysUserContracts.setUrl(pdfFilePath);
+        sysUserContracts.setUserId(userId);
 
-		// 合成freemarker
-		String srcPdfPath = contractBaseDir + "/goods/" + userId + ".pdf";
+        sysUserContractsService.insert(sysUserContracts);
 
-		File srcFile = new File(srcPdfPath);
+        FileUtils.deleteQuietly(srcFile);
 
-		File debtFile = new File(srcFile.getParent());
-		if (!debtFile.exists()) {
-			debtFile.mkdirs();
-		}
+        return true;
+    }
 
-		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
-		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
+    @Override
+    public String queryGoodsContract(Integer userId, String musicGroupId, String goodsIds, KitGroupPurchaseTypeEnum kitGroupPurchaseTypeEnum) {
 
-		Map<String, Object> params = new HashMap<String, Object>();
+        // 合成freemarker
+        String srcPdfPath = contractBaseDir + "/goods/" + userId + ".pdf";
 
-		// 查询参数信息
-		StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
+        File srcFile = new File(srcPdfPath);
 
-		int subjectId = studentInfo.getSubject().getId();
+        File debtFile = new File(srcFile.getParent());
+        if (!debtFile.exists()) {
+            debtFile.mkdirs();
+        }
 
-		Subject subject = subjectService.get(subjectId);
-		studentInfo.setSubject(subject);
+        FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
+        templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
 
-		params.put("studentInfo", studentInfo);
+        Map<String, Object> params = new HashMap<String, Object>();
+
+        // 查询参数信息
+        StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
+
+        int subjectId = studentInfo.getSubject().getId();
+
+        Subject subject = subjectService.get(subjectId);
+        studentInfo.setSubject(subject);
+
+        params.put("studentInfo", studentInfo);
+
+        List<Goods> goodsList = goodsService.findGoodsByIds(goodsIds);
+        params.put("goodsList", goodsList);
+
+        double depositFee = 0d;
+        if (kitGroupPurchaseTypeEnum == KitGroupPurchaseTypeEnum.LEASE) {
+            StudentPaymentOrder studentPaymentOrder = studentPaymentOrderService
+                    .findMusicGroupApplyOrderByStatus(userId, musicGroupId, DealStatusEnum.WAIT_PAY);
+
+            if (studentPaymentOrder == null) {
+                MusicGroupSubjectGoodsGroup musicGroupSubjectPlan = musicGroupSubjectGoodsGroupService.query(musicGroupId, subjectId, goodsIds);
+                if (musicGroupSubjectPlan != null) {
+                    depositFee = musicGroupSubjectPlan.getDepositFee().doubleValue();
+                }
+            } else {
+
+                List<StudentPaymentOrderDetail> orderDetailList = studentPaymentOrderDetailDao.findApplyOrderGoods(studentPaymentOrder.getId());
+                for (StudentPaymentOrderDetail detail : orderDetailList) {
+                    if (detail.getType() == OrderDetailTypeEnum.MUSICAL) {
+                        depositFee = detail.getPrice().doubleValue();
+                    }
+                }
+            }
+        }
+        params.put("depositFee", depositFee);
+        params.put("depositFeeFmt", MoneyUtil.toChinese(depositFee + ""));
 
-		List<Goods> goodsList = goodsService.findGoodsByIds(goodsIds);
-		params.put("goodsList", goodsList);
+        params.put("isShowVisualSeal", true);
 
-		double depositFee = 0d;
-		if (kitGroupPurchaseTypeEnum == KitGroupPurchaseTypeEnum.LEASE) {
-			StudentPaymentOrder studentPaymentOrder = studentPaymentOrderService
-					.findMusicGroupApplyOrderByStatus(userId, musicGroupId, DealStatusEnum.WAIT_PAY);
+        MusicGroup musicGroup = musicGroupService.get(musicGroupId);
+        if (musicGroup == null) {
+            throw new BizException("乐团信息没找到");
+        }
 
-			if (studentPaymentOrder == null) {
-				MusicGroupSubjectGoodsGroup musicGroupSubjectPlan = musicGroupSubjectGoodsGroupService.query(musicGroupId, subjectId, goodsIds);
-				if (musicGroupSubjectPlan != null) {
-					depositFee = musicGroupSubjectPlan.getDepositFee().doubleValue();
-				}
-			} else {
+        params.put("ownershipType", musicGroup.getOwnershipType().name());
 
-				List<StudentPaymentOrderDetail> orderDetailList = studentPaymentOrderDetailDao.findApplyOrderGoods(studentPaymentOrder.getId());
-				for (StudentPaymentOrderDetail detail : orderDetailList) {
-					if (detail.getType() == OrderDetailTypeEnum.MUSICAL) {
-						depositFee = detail.getPrice().doubleValue();
-					}
-				}
-			}
-		}
-		params.put("depositFee", depositFee);
-		params.put("depositFeeFmt", MoneyUtil.toChinese(depositFee + ""));
+        templateEngine.render(params, "goods.ftl", srcFile);
 
-		params.put("isShowVisualSeal", true);
+        String result = "";
+        try {
+            result = FileUtils.readFileToString(srcFile);
+        } catch (IOException e) {
+            throw new BizException("读取商品协议出错", e);
+        } finally {
+            FileUtils.deleteQuietly(srcFile);
+        }
 
-		MusicGroup musicGroup = musicGroupService.get(musicGroupId);
-		if (musicGroup == null) {
-			throw new BizException("乐团信息没找到");
-		}
+        return result;
+    }
 
-		params.put("ownershipType", musicGroup.getOwnershipType().name());
+    @Override
+    public String queryPracticeCoursesContract(Integer userId, int courseSectionNum, Date startDate, Date endDate, BigDecimal fee) {
+        // 合成freemarker
+        String srcPdfPath = contractBaseDir + "/practice/" + userId + ".pdf";
 
-		templateEngine.render(params, "goods.ftl", srcFile);
+        File srcFile = new File(srcPdfPath);
 
-		String result = "";
-		try {
-			result = FileUtils.readFileToString(srcFile);
-		} catch (IOException e) {
-			throw new BizException("读取商品协议出错", e);
-		} finally {
-			FileUtils.deleteQuietly(srcFile);
-		}
+        File debtFile = new File(srcFile.getParent());
+        if (!debtFile.exists()) {
+            debtFile.mkdirs();
+        }
 
-		return result;
-	}
+        FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
+        templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
 
-	@Override
-	public String queryPracticeCoursesContract(Integer userId, int courseSectionNum, Date startDate, Date endDate, BigDecimal fee) {
-		// 合成freemarker
-		String srcPdfPath = contractBaseDir + "/practice/" + userId + ".pdf";
+        Map<String, Object> params = new HashMap<String, Object>();
+        params.put("courseSectionNum", courseSectionNum);
+        params.put("startDate", startDate);
+        params.put("endDate", endDate);
+        params.put("fee", fee);
 
-		File srcFile = new File(srcPdfPath);
+        params.put("isShowVisualSeal", false);
 
-		File debtFile = new File(srcFile.getParent());
-		if (!debtFile.exists()) {
-			debtFile.mkdirs();
-		}
+        params.put("ownershipType", "OWN");
 
-		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
-		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
+        templateEngine.render(params, "practice.ftl", srcFile);
 
-		Map<String, Object> params = new HashMap<String, Object>();
-		params.put("courseSectionNum", courseSectionNum);
-		params.put("startDate", startDate);
-		params.put("endDate", endDate);
-		params.put("fee", fee);
+        String result = "";
+        try {
+            result = FileUtils.readFileToString(srcFile);
+        } catch (IOException e) {
+            throw new BizException("读取网管课购买协议出错", e);
+        } finally {
+            FileUtils.deleteQuietly(srcFile);
+        }
 
-		params.put("isShowVisualSeal", false);
+        return result;
+    }
+
+    @Override
+    public boolean transferPracticeCoursesContract(Integer userId, int courseSectionNum, Date startDate, Date endDate, BigDecimal fee) {
+        if (true) {
+            return transferProduceContract(userId, null);
+        }
+
+        SysUserTsign sysUserTsign = sysUserTsignService.get(userId);
+
+        if (sysUserTsign == null) {
+            SysUser user = sysUserFeignService.queryUserById(userId);
+            if (user == null) {
+                throw new BizException("用户信息查询失败");
+            }
+            sysUserTsign = register(userId, user.getRealName(), user.getIdCardNo(), user.getPhone());
+        }
+
+        Date date = new Date();
+
+        // 合成freemarker
+        String srcPdfPath = contractBaseDir + "/practice/" + userId + ".pdf";
+
+        File srcFile = new File(srcPdfPath);
+
+        File debtFile = new File(srcFile.getParent());
+        if (!debtFile.exists()) {
+            debtFile.mkdirs();
+        }
+
+        FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
+        templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
+
+        Map<String, Object> params = new HashMap<String, Object>();
+        params.put("courseSectionNum", courseSectionNum);
+        params.put("startDate", startDate);
+        params.put("endDate", endDate);
+        params.put("fee", fee);
+
+        params.put("isShowVisualSeal", false);
+
+        params.put("ownershipType", "OWN");
+
+        templateEngine.render(params, "practice.ftl", srcFile);
+
+        // 生成借款协议PDF
+        try {
+            PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(srcFile), srcPdfPath, "simsun.ttc");
+        } catch (IOException e) {
+            throw new BizException("生成pdf协议失败", e);
+        }
+        String organCode = "91440300326364429H";
+        SysUserTsign organTsign = sysUserTsignService.queryByCardNo(organCode);
+        if (organTsign == null) {
+            throw new BizException("甲方未创建签章");
+        }
+
+        eSealPlugin.organSign(organTsign.getSealData(), srcPdfPath, srcPdfPath);
+
+        if (sysUserTsign != null) {
+            eSealPlugin.userSign(sysUserTsign.getAccountId(), sysUserTsign.getSealData(), srcPdfPath, srcPdfPath);
+        }
+
+        // 上传到oss
+        String dateStrOss = dateFormatOss.format(date);
+        dateStrOss = "practice/" + dateStrOss + "/" + DateUtil.getHour(date);
+        String pdfFilePath = storagePluginContext.uploadFile(KS3StoragePlugin.PLUGIN_NAME, dateStrOss, srcFile);
+
+        SysUserContracts sysUserContracts = new SysUserContracts();
+        sysUserContracts.setCreateTime(date);
+        sysUserContracts.setType(ContractType.PRACTICE);
+        sysUserContracts.setUrl(pdfFilePath);
+        sysUserContracts.setUserId(userId);
+
+        sysUserContractsService.insert(sysUserContracts);
+
+        FileUtils.deleteQuietly(srcFile);
+
+        return true;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRES_NEW)
+    public boolean transferProduceContract(Integer userId, String musicGroupId) {
+        SysUser user = studentDao.lockUserReturnInfo(userId);
+
+        if (user == null) {
+            logger.error("用户不存在({})", userId);
+            return false;
+        }
+
+        if (StringUtils.isBlank(user.getRealName()) || StringUtils.isBlank(user.getIdCardNo())) {
+            logger.error("身份信息缺失({})", userId);
+            return false;
+        }
+
+        SysUserTsign sysUserTsign = sysUserTsignService.get(userId);
+        if (sysUserTsign == null) {
+            try {
+                sysUserTsign = register(userId, user.getRealName(), user.getIdCardNo(), user.getPhone());
+            } catch (Exception e) {
+                logger.error("用户电子签章注册失败", e);
+                return false;
+            }
+        }
+        Date date = new Date();
+
+        // 合成freemarker
+        String srcPdfPath = contractBaseDir + "/product/" + dateFormat1.format(date) + "/" + userId + "_" + LocalDateTime.now().getSecond() + ".pdf";
+
+        File srcFile = new File(srcPdfPath);
+
+        File debtFile = new File(srcFile.getParent());
+        if (!debtFile.exists()) {
+            debtFile.mkdirs();
+        }
+
+        FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
+        templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
+
+        Map<String, Object> params = new HashMap<String, Object>();
+
+        // 查询参数信息
+        StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
+        params.put("studentInfo", studentInfo);
+
+        params.put("isShowVisualSeal", false);
+
+        CourseViewTypeEnum ownershipType = CourseViewTypeEnum.COURSE_lIST;
+
+        if (StringUtils.isBlank(musicGroupId)) {
+            params.put("ownershipType", "OWN");
+            MusicGroup userLastNormalMusicGroup = studentRegistrationDao.getUserLastNormalMusicGroup(userId);
+            if (Objects.nonNull(userLastNormalMusicGroup)) {
+                ownershipType = userLastNormalMusicGroup.getCourseViewType();
+            }
+        } else {
+            MusicGroup musicGroup = musicGroupService.get(musicGroupId);
+            if (musicGroup == null) {
+                logger.error("乐团信息没找到({})", musicGroupId);
+                return false;
+            }
+            params.put("ownershipType", musicGroup.getOwnershipType().name());
+            ownershipType = musicGroup.getCourseViewType();
+        }
+
+        List<SysUserContracts> userContracts = sysUserContractsService.getUserContractWithType(userId, ContractType.PRODUCT, ownershipType.getContractVersion());
+        if (!CollectionUtils.isEmpty(userContracts)) {
+            return true;
+        }
+
+        templateEngine.render(params, "product" + ownershipType.getContractVersion() + ".ftl", srcFile);
+
+        // 生成借款协议PDF
+        try {
+            PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(srcFile), srcPdfPath, "simsun.ttc");
+        } catch (IOException e) {
+            logger.error("生成产品协议失败", e);
+            return false;
+        }
+
+
+        String organCode = "";
+        if (OwnershipType.OWN.name().equals(params.get("ownershipType"))) {
+            organCode = "91440300326364429H";
+        } else {
+            organCode = "91420106333619290A";
+        }
+        SysUserTsign organTsign = sysUserTsignService.queryByCardNo(organCode);
+        if (organTsign == null) {
+            logger.error("甲方未创建签章");
+            return false;
+        }
+
+        eSealPlugin.organSign(organTsign.getSealData(), srcPdfPath, srcPdfPath);
+        if (sysUserTsign != null && CertificateTypeEnum.IDENTITY.getCode().equals(user.getCertificateType())) {
+            eSealPlugin.userSign(sysUserTsign.getAccountId(), sysUserTsign.getSealData(), srcPdfPath, srcPdfPath);
+        }
+
+        // 上传到oss
+        String dateStrOss = dateFormatOss.format(date);
+        dateStrOss = "product/" + dateStrOss + "/" + DateUtil.getHour(date);
+        String pdfFilePath = storagePluginContext.uploadFile(KS3StoragePlugin.PLUGIN_NAME, dateStrOss, srcFile);
+
+        SysUserContracts sysUserContracts = new SysUserContracts();
+        sysUserContracts.setCreateTime(date);
+        sysUserContracts.setType(ContractType.PRODUCT);
+        sysUserContracts.setUrl(pdfFilePath);
+        sysUserContracts.setUserId(userId);
+        sysUserContracts.setVersion(ownershipType.getContractVersion());
+
+        sysUserContractsService.insert(sysUserContracts);
+
+        FileUtils.deleteQuietly(srcFile);
+        return true;
+    }
+
+    @Override
+    @Transactional(isolation = Isolation.READ_COMMITTED)
+    public Map<String, Object> queryProductContract(Integer userId, String musicGroupId) {
+        // 合成freemarker
+        String srcPdfPath = contractBaseDir + "/product/" + userId + ".pdf";
+
+        File srcFile = new File(srcPdfPath);
+
+        File debtFile = new File(srcFile.getParent());
+        if (!debtFile.exists()) {
+            debtFile.mkdirs();
+        }
+
+        FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
+        templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
+
+        Map<String, Object> params = new HashMap<String, Object>();
+
+        StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
+        if (Objects.isNull(studentInfo)) {
+            studentInfo = new StudentInfo();
+        }
+        if (StringUtils.isEmpty(studentInfo.getCertificateType())) {
+            studentInfo.setCertificateType(CertificateTypeEnum.IDENTITY.getCode());
+        }
+        params.put("studentInfo", studentInfo);
+        params.put("isShowVisualSeal", true);
+
+        Map<String, Object> result = new HashMap<>();
+        result.put("courseViewType", CourseViewTypeEnum.COURSE_lIST);
+        CourseViewTypeEnum ownershipType = CourseViewTypeEnum.COURSE_lIST;
+
+        if (StringUtils.isBlank(musicGroupId)) {
+            params.put("ownershipType", "OWN");
+            MusicGroup userLastNormalMusicGroup = studentRegistrationDao.getUserLastNormalMusicGroup(userId);
+            if (Objects.nonNull(userLastNormalMusicGroup)) {
+                result.put("courseViewType", userLastNormalMusicGroup.getCourseViewType());
+                ownershipType = userLastNormalMusicGroup.getCourseViewType();
+            }
+        } else {
+            MusicGroup musicGroup = musicGroupService.get(musicGroupId);
+            if (musicGroup == null) {
+                throw new BizException("乐团信息没找到");
+            }
+            params.put("ownershipType", musicGroup.getOwnershipType().name());
+            result.put("courseViewType", musicGroup.getCourseViewType());
+            ownershipType = musicGroup.getCourseViewType();
+        }
+
+
+        templateEngine.render(params, "product" + ownershipType.getContractVersion() + ".ftl", srcFile);
+
+        String html = "";
+        try {
+            html = FileUtils.readFileToString(srcFile);
+        } catch (IOException e) {
+            throw new BizException("读取产品协议出错", e);
+        } finally {
+            FileUtils.deleteQuietly(srcFile);
+        }
+
+        List<SysUserContracts> userContractWithType = sysUserContractsService.getUserContractWithType(userId, ContractType.PRODUCT, ownershipType.getContractVersion());
+
+        result.put("exists", !CollectionUtils.isEmpty(userContractWithType));
+        result.put("productContract", html);
+        return result;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public HttpResponseResult transferProduceContractOnlyWithCourseList(Integer userId) {
+        SysUser user = studentDao.lockUserReturnInfo(userId);
+        if (user == null) {
+            logger.error("用户不存在({})", userId);
+            return BaseController.failed("用户不存在");
+        }
+
+        int validContactNum = sysUserContractsDao.countUserValidContact(userId);
+        if (validContactNum > 0) {
+            return BaseController.succeed();
+        }
+
+        if (StringUtils.isBlank(user.getRealName()) || StringUtils.isBlank(user.getIdCardNo())) {
+            return BaseController.failed(HttpStatus.PARTIAL_CONTENT, user, "");
+        }
+
+        SysUserTsign sysUserTsign = sysUserTsignService.get(userId);
+        if (sysUserTsign == null) {
+            try {
+                sysUserTsign = register(userId, user.getRealName(), user.getIdCardNo(), user.getPhone());
+            } catch (Exception e) {
+                logger.error("用户电子签章注册失败", e);
+                return BaseController.failed("用户电子签章注册失败");
+            }
+        }
+        Date date = new Date();
+
+        // 合成freemarker
+        String srcPdfPath = contractBaseDir + "/product/" + dateFormat1.format(date) + "/" + userId + "_" + LocalDateTime.now().getSecond() + ".pdf";
+
+        File srcFile = new File(srcPdfPath);
+
+        File debtFile = new File(srcFile.getParent());
+        if (!debtFile.exists()) {
+            debtFile.mkdirs();
+        }
+
+        FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
+        templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
+
+        Map<String, Object> params = new HashMap<String, Object>();
+
+        // 查询参数信息
+        StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
+        params.put("studentInfo", studentInfo);
+
+        params.put("isShowVisualSeal", false);
+
+        CourseViewTypeEnum courseViewType = CourseViewTypeEnum.COURSE_lIST;
+        params.put("ownershipType", "OWN");
+
+        List<SysUserContracts> userContracts = sysUserContractsService.getUserContractWithType(userId, ContractType.PRODUCT, 2);
+        if (!CollectionUtils.isEmpty(userContracts)) {
+            return BaseController.succeed();
+        }
+
+        templateEngine.render(params, "product2.ftl", srcFile);
+
+        // 生成借款协议PDF
+        try {
+            PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(srcFile), srcPdfPath, "simsun.ttc");
+        } catch (IOException e) {
+            logger.error("生成产品协议失败", e);
+            return BaseController.failed("生成产品协议失败");
+        }
+
+        String organCode = "91440300326364429H";
+
+        SysUserTsign organTsign = sysUserTsignService.queryByCardNo(organCode);
+        if (organTsign == null) {
+            logger.error("甲方未创建签章");
+            return BaseController.failed("甲方未创建签章");
+        }
+
+        eSealPlugin.organSign(organTsign.getSealData(), srcPdfPath, srcPdfPath);
+        if (sysUserTsign != null && CertificateTypeEnum.IDENTITY.getCode().equals(user.getCertificateType())) {
+            eSealPlugin.userSign(sysUserTsign.getAccountId(), sysUserTsign.getSealData(), srcPdfPath, srcPdfPath);
+        }
+
+        // 上传到oss
+        String dateStrOss = dateFormatOss.format(date);
+        dateStrOss = "product/" + dateStrOss + "/" + DateUtil.getHour(date);
+        String pdfFilePath = storagePluginContext.uploadFile(KS3StoragePlugin.PLUGIN_NAME, dateStrOss, srcFile);
+
+        SysUserContracts sysUserContracts = new SysUserContracts();
+        sysUserContracts.setCreateTime(date);
+        sysUserContracts.setType(ContractType.PRODUCT);
+        sysUserContracts.setUrl(pdfFilePath);
+        sysUserContracts.setUserId(userId);
+        sysUserContracts.setVersion(2);
+
+        sysUserContractsService.insert(sysUserContracts);
+
+        FileUtils.deleteQuietly(srcFile);
+        return BaseController.succeed();
+    }
+
+
+    @Override
+    public String transferOaFinancial(List<CirculationUser> circulationUsers, List<CirculationUser> executors) {
+        List<Integer> circulationUserIds = circulationUsers.stream().map(CirculationUser::getUserId).collect(Collectors.toList());
+        List<Integer> executorIds = executors.stream().map(CirculationUser::getUserId).collect(Collectors.toList());
+        circulationUserIds.addAll(executorIds);
+        List<SysUser> users = employeeDao.getUsers(circulationUserIds);
+
+        Integer workOrderId = null;
+        for (SysUser user : users) {
+            SysUserTsign sysUserTsign = sysUserTsignService.get(user.getId());
+            if (sysUserTsign == null) {
+                try {
+                    sysUserTsign = register(user.getId(), user.getRealName(), user.getIdCardNo(), user.getPhone());
+                } catch (Exception e) {
+                    logger.error("用户电子签章注册失败", e);
+                    throw new BizException(user.getRealName() + "电子签章注册失败");
+                }
+            }
+            for (CirculationUser circulationUser : circulationUsers) {
+                if (workOrderId == null) {
+                    workOrderId = circulationUser.getWorkOrderId();
+                }
+                if (!circulationUser.getUserId().equals(user.getId())) continue;
+                circulationUser.setRealName(user.getRealName());
+                circulationUser.setIdCard(user.getIdCardNo());
+                circulationUser.setPhone(user.getPhone());
+                circulationUser.setSysUserTsign(sysUserTsign);
+            }
+            for (CirculationUser executor : executors) {
+                if (!executor.getUserId().equals(user.getId())) continue;
+                executor.setRealName(user.getRealName());
+                executor.setIdCard(user.getIdCardNo());
+                executor.setPhone(user.getPhone());
+                executor.setSysUserTsign(sysUserTsign);
+            }
+        }
+
+        Date date = new Date();
+
+        // 合成freemarker
+        String srcPdfPath = contractBaseDir + "/oa/" + dateFormat1.format(date) + "/" + workOrderId + "_" + LocalDateTime.now().getSecond() + ".pdf";
+
+        File srcFile = new File(srcPdfPath);
+
+        File debtFile = new File(srcFile.getParent());
+        if (!debtFile.exists()) {
+            debtFile.mkdirs();
+        }
+
+        FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
+        templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
+
+        Map<String, Object> params = new HashMap<String, Object>();
+
+        // 查询参数信息
+        params.put("circulationUsers", circulationUsers);
+        params.put("executors", executors);
+
+        templateEngine.render(params, "financial.ftl", srcFile);
+
+        // 生成借款协议PDF
+        try {
+            PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(srcFile), srcPdfPath, "simsun.ttc");
+        } catch (IOException e) {
+            logger.error("生成产品协议失败", e);
+        }
+
+        for (CirculationUser circulationUser : circulationUsers) {
+            eSealPlugin.userSign(circulationUser.getSysUserTsign().getAccountId(), circulationUser.getSysUserTsign().getSealData(),circulationUser.getRealName(), srcPdfPath, srcPdfPath);
+        }
+
+        for (CirculationUser executor : executors) {
+            eSealPlugin.userSign(executor.getSysUserTsign().getAccountId(), executor.getSysUserTsign().getSealData(),executor.getRealName(), srcPdfPath, srcPdfPath);
+        }
+
+        // 上传到oss
+        String dateStrOss = dateFormatOss.format(date);
+        dateStrOss = "oa/" + dateStrOss + "/" + DateUtil.getHour(date);
+        String pdfFilePath = storagePluginContext.uploadFile(KS3StoragePlugin.PLUGIN_NAME, dateStrOss, srcFile);
+
+//        SysUserContracts sysUserContracts = new SysUserContracts();
+//        sysUserContracts.setCreateTime(date);
+//        sysUserContracts.setType(ContractType.PRODUCT);
+//        sysUserContracts.setUrl(pdfFilePath);
+//        sysUserContracts.setUserId(userId);
+//        sysUserContracts.setVersion(2);
+//
+//        sysUserContractsService.insert(sysUserContracts);
+
+        FileUtils.deleteQuietly(srcFile);
+
+        return pdfFilePath;
+    }
 
-		params.put("ownershipType", "OWN");
-
-		templateEngine.render(params, "practice.ftl", srcFile);
-
-		String result = "";
-		try {
-			result = FileUtils.readFileToString(srcFile);
-		} catch (IOException e) {
-			throw new BizException("读取网管课购买协议出错", e);
-		} finally {
-			FileUtils.deleteQuietly(srcFile);
-		}
-
-		return result;
-	}
-
-	@Override
-	public boolean transferPracticeCoursesContract(Integer userId, int courseSectionNum, Date startDate, Date endDate, BigDecimal fee) {
-		if(true){
-			return transferProduceContract(userId, null);
-		}
-
-		SysUserTsign sysUserTsign = sysUserTsignService.get(userId);
-
-		if (sysUserTsign == null) {
-			SysUser user = sysUserFeignService.queryUserById(userId);
-			if (user == null) {
-				throw new BizException("用户信息查询失败");
-			}
-			sysUserTsign = register(userId, user.getRealName(), user.getIdCardNo(), user.getPhone());
-		}
-
-		Date date = new Date();
-
-		// 合成freemarker
-		String srcPdfPath = contractBaseDir + "/practice/" + userId + ".pdf";
-
-		File srcFile = new File(srcPdfPath);
-
-		File debtFile = new File(srcFile.getParent());
-		if (!debtFile.exists()) {
-			debtFile.mkdirs();
-		}
-
-		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
-		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
-
-		Map<String, Object> params = new HashMap<String, Object>();
-		params.put("courseSectionNum", courseSectionNum);
-		params.put("startDate", startDate);
-		params.put("endDate", endDate);
-		params.put("fee", fee);
-
-		params.put("isShowVisualSeal", false);
-
-		params.put("ownershipType", "OWN");
-
-		templateEngine.render(params, "practice.ftl", srcFile);
-
-		// 生成借款协议PDF
-		try {
-			PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(srcFile), srcPdfPath, "simsun.ttc");
-		} catch (IOException e) {
-			throw new BizException("生成pdf协议失败", e);
-		}
-		String organCode = "91440300326364429H";
-		SysUserTsign organTsign = sysUserTsignService.queryByCardNo(organCode);
-		if (organTsign == null) {
-			throw new BizException("甲方未创建签章");
-		}
-
-		eSealPlugin.organSign(organTsign.getSealData(), srcPdfPath, srcPdfPath);
-
-		if (sysUserTsign != null) {
-			eSealPlugin.userSign(sysUserTsign.getAccountId(), sysUserTsign.getSealData(), srcPdfPath, srcPdfPath);
-		}
-
-		// 上传到oss
-		String dateStrOss = dateFormatOss.format(date);
-		dateStrOss = "practice/" + dateStrOss + "/" + DateUtil.getHour(date);
-		String pdfFilePath = storagePluginContext.uploadFile(KS3StoragePlugin.PLUGIN_NAME, dateStrOss, srcFile);
-
-		SysUserContracts sysUserContracts = new SysUserContracts();
-		sysUserContracts.setCreateTime(date);
-		sysUserContracts.setType(ContractType.PRACTICE);
-		sysUserContracts.setUrl(pdfFilePath);
-		sysUserContracts.setUserId(userId);
-
-		sysUserContractsService.insert(sysUserContracts);
-
-		FileUtils.deleteQuietly(srcFile);
-
-		return true;
-	}
-
-	@Override
-	@Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRES_NEW)
-	public boolean transferProduceContract(Integer userId,String musicGroupId) {
-		SysUser user = studentDao.lockUserReturnInfo(userId);
-
-		if (user == null) {
-			logger.error("用户不存在({})", userId);
-			return false;
-		}
-
-		if(StringUtils.isBlank(user.getRealName())||StringUtils.isBlank(user.getIdCardNo())){
-			logger.error("身份信息缺失({})", userId);
-			return false;
-		}
-
-		SysUserTsign sysUserTsign = sysUserTsignService.get(userId);
-		if (sysUserTsign == null) {
-			try {
-				sysUserTsign = register(userId, user.getRealName(), user.getIdCardNo(), user.getPhone());
-			} catch (Exception e) {
-				logger.error("用户电子签章注册失败", e);
-				return false;
-			}
-		}
-		Date date = new Date();
-
-		// 合成freemarker
-		String srcPdfPath = contractBaseDir + "/product/" + dateFormat1.format(date) + "/" + userId + "_" + LocalDateTime.now().getSecond() + ".pdf";
-
-		File srcFile = new File(srcPdfPath);
-
-		File debtFile = new File(srcFile.getParent());
-		if (!debtFile.exists()) {
-			debtFile.mkdirs();
-		}
-
-		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
-		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
-
-		Map<String, Object> params = new HashMap<String, Object>();
-
-		// 查询参数信息
-		StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
-		params.put("studentInfo", studentInfo);
-
-		params.put("isShowVisualSeal", false);
-
-		CourseViewTypeEnum ownershipType = CourseViewTypeEnum.COURSE_lIST;
-
-		if(StringUtils.isBlank(musicGroupId)){
-			params.put("ownershipType", "OWN");
-			MusicGroup userLastNormalMusicGroup = studentRegistrationDao.getUserLastNormalMusicGroup(userId);
-			if(Objects.nonNull(userLastNormalMusicGroup)){
-				ownershipType = userLastNormalMusicGroup.getCourseViewType();
-			}
-		}else{
-			MusicGroup musicGroup = musicGroupService.get(musicGroupId);
-			if (musicGroup == null) {
-				logger.error("乐团信息没找到({})", musicGroupId);
-				return false;
-			}
-			params.put("ownershipType", musicGroup.getOwnershipType().name());
-			ownershipType = musicGroup.getCourseViewType();
-		}
-
-		List<SysUserContracts> userContracts = sysUserContractsService.getUserContractWithType(userId, ContractType.PRODUCT, ownershipType.getContractVersion());
-		if(!CollectionUtils.isEmpty(userContracts)){
-			return true;
-		}
-
-		templateEngine.render(params, "product"+ownershipType.getContractVersion()+".ftl", srcFile);
-
-		// 生成借款协议PDF
-		try {
-			PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(srcFile), srcPdfPath, "simsun.ttc");
-		} catch (IOException e) {
-			logger.error("生成产品协议失败", e);
-			return false;
-		}
-
-
-		String organCode = "";
-		if (OwnershipType.OWN.name().equals(params.get("ownershipType"))){
-			organCode = "91440300326364429H";
-		} else {
-			organCode = "91420106333619290A";
-		}
-		SysUserTsign organTsign = sysUserTsignService.queryByCardNo(organCode);
-		if (organTsign == null) {
-			logger.error("甲方未创建签章");
-			return false;
-		}
-
-		eSealPlugin.organSign(organTsign.getSealData(), srcPdfPath, srcPdfPath);
-		if (sysUserTsign != null && CertificateTypeEnum.IDENTITY.getCode().equals(user.getCertificateType())) {
-			eSealPlugin.userSign(sysUserTsign.getAccountId(), sysUserTsign.getSealData(), srcPdfPath, srcPdfPath);
-		}
-
-		// 上传到oss
-		String dateStrOss = dateFormatOss.format(date);
-		dateStrOss = "product/" + dateStrOss + "/" + DateUtil.getHour(date);
-		String pdfFilePath = storagePluginContext.uploadFile(KS3StoragePlugin.PLUGIN_NAME, dateStrOss, srcFile);
-
-		SysUserContracts sysUserContracts = new SysUserContracts();
-		sysUserContracts.setCreateTime(date);
-		sysUserContracts.setType(ContractType.PRODUCT);
-		sysUserContracts.setUrl(pdfFilePath);
-		sysUserContracts.setUserId(userId);
-		sysUserContracts.setVersion(ownershipType.getContractVersion());
-
-		sysUserContractsService.insert(sysUserContracts);
-
-		FileUtils.deleteQuietly(srcFile);
-		return true;
-	}
-
-	@Override
-	@Transactional(isolation = Isolation.READ_COMMITTED)
-	public Map<String, Object> queryProductContract(Integer userId,String musicGroupId) {
-		// 合成freemarker
-		String srcPdfPath = contractBaseDir + "/product/" + userId + ".pdf";
-
-		File srcFile = new File(srcPdfPath);
-
-		File debtFile = new File(srcFile.getParent());
-		if (!debtFile.exists()) {
-			debtFile.mkdirs();
-		}
-
-		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
-		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
-
-		Map<String, Object> params = new HashMap<String, Object>();
-
-		StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
-		if(Objects.isNull(studentInfo)){
-			studentInfo = new StudentInfo();
-		}
-		if(StringUtils.isEmpty(studentInfo.getCertificateType())){
-			studentInfo.setCertificateType(CertificateTypeEnum.IDENTITY.getCode());
-		}
-		params.put("studentInfo", studentInfo);
-		params.put("isShowVisualSeal", true);
-
-		Map<String, Object> result = new HashMap<>();
-		result.put("courseViewType", CourseViewTypeEnum.COURSE_lIST);
-		CourseViewTypeEnum ownershipType = CourseViewTypeEnum.COURSE_lIST;
-
-		if(StringUtils.isBlank(musicGroupId)){
-			params.put("ownershipType", "OWN");
-			MusicGroup userLastNormalMusicGroup = studentRegistrationDao.getUserLastNormalMusicGroup(userId);
-			if(Objects.nonNull(userLastNormalMusicGroup)){
-				result.put("courseViewType", userLastNormalMusicGroup.getCourseViewType());
-				ownershipType = userLastNormalMusicGroup.getCourseViewType();
-			}
-		}else{
-			MusicGroup musicGroup = musicGroupService.get(musicGroupId);
-			if (musicGroup == null) {
-				throw new BizException("乐团信息没找到");
-			}
-			params.put("ownershipType", musicGroup.getOwnershipType().name());
-			result.put("courseViewType", musicGroup.getCourseViewType());
-			ownershipType = musicGroup.getCourseViewType();
-		}
-
-
-		templateEngine.render(params, "product"+ownershipType.getContractVersion()+".ftl", srcFile);
-
-		String html = "";
-		try {
-			html = FileUtils.readFileToString(srcFile);
-		} catch (IOException e) {
-			throw new BizException("读取产品协议出错", e);
-		} finally {
-			FileUtils.deleteQuietly(srcFile);
-		}
-
-		List<SysUserContracts> userContractWithType = sysUserContractsService.getUserContractWithType(userId, ContractType.PRODUCT, ownershipType.getContractVersion());
-
-		result.put("exists", !CollectionUtils.isEmpty(userContractWithType));
-		result.put("productContract", html);
-		return result;
-	}
-
-	@Override
-	@Transactional(rollbackFor = Exception.class)
-	public HttpResponseResult transferProduceContractOnlyWithCourseList(Integer userId) {
-		SysUser user = studentDao.lockUserReturnInfo(userId);
-		if (user == null) {
-			logger.error("用户不存在({})", userId);
-			return BaseController.failed("用户不存在");
-		}
-
-		int validContactNum = sysUserContractsDao.countUserValidContact(userId);
-		if(validContactNum>0){
-			return BaseController.succeed();
-		}
-
-		if(StringUtils.isBlank(user.getRealName())||StringUtils.isBlank(user.getIdCardNo())){
-			return BaseController.failed(HttpStatus.PARTIAL_CONTENT, user, "");
-		}
-
-		SysUserTsign sysUserTsign = sysUserTsignService.get(userId);
-		if (sysUserTsign == null) {
-			try {
-				sysUserTsign = register(userId, user.getRealName(), user.getIdCardNo(), user.getPhone());
-			} catch (Exception e) {
-				logger.error("用户电子签章注册失败", e);
-				return BaseController.failed("用户电子签章注册失败");
-			}
-		}
-		Date date = new Date();
-
-		// 合成freemarker
-		String srcPdfPath = contractBaseDir + "/product/" + dateFormat1.format(date) + "/" + userId + "_" + LocalDateTime.now().getSecond() + ".pdf";
-
-		File srcFile = new File(srcPdfPath);
-
-		File debtFile = new File(srcFile.getParent());
-		if (!debtFile.exists()) {
-			debtFile.mkdirs();
-		}
-
-		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
-		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");
-
-		Map<String, Object> params = new HashMap<String, Object>();
-
-		// 查询参数信息
-		StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
-		params.put("studentInfo", studentInfo);
-
-		params.put("isShowVisualSeal", false);
-
-		CourseViewTypeEnum courseViewType = CourseViewTypeEnum.COURSE_lIST;
-		params.put("ownershipType", "OWN");
-
-		List<SysUserContracts> userContracts = sysUserContractsService.getUserContractWithType(userId, ContractType.PRODUCT, 2);
-		if(!CollectionUtils.isEmpty(userContracts)){
-			return BaseController.succeed();
-		}
-
-		templateEngine.render(params, "product2.ftl", srcFile);
-
-		// 生成借款协议PDF
-		try {
-			PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(srcFile), srcPdfPath, "simsun.ttc");
-		} catch (IOException e) {
-			logger.error("生成产品协议失败", e);
-			return BaseController.failed("生成产品协议失败");
-		}
-
-		String organCode = "91440300326364429H";
-
-		SysUserTsign organTsign = sysUserTsignService.queryByCardNo(organCode);
-		if (organTsign == null) {
-			logger.error("甲方未创建签章");
-			return BaseController.failed("甲方未创建签章");
-		}
-
-		eSealPlugin.organSign(organTsign.getSealData(), srcPdfPath, srcPdfPath);
-		if (sysUserTsign != null && CertificateTypeEnum.IDENTITY.getCode().equals(user.getCertificateType())) {
-			eSealPlugin.userSign(sysUserTsign.getAccountId(), sysUserTsign.getSealData(), srcPdfPath, srcPdfPath);
-		}
-
-		// 上传到oss
-		String dateStrOss = dateFormatOss.format(date);
-		dateStrOss = "product/" + dateStrOss + "/" + DateUtil.getHour(date);
-		String pdfFilePath = storagePluginContext.uploadFile(KS3StoragePlugin.PLUGIN_NAME, dateStrOss, srcFile);
-
-		SysUserContracts sysUserContracts = new SysUserContracts();
-		sysUserContracts.setCreateTime(date);
-		sysUserContracts.setType(ContractType.PRODUCT);
-		sysUserContracts.setUrl(pdfFilePath);
-		sysUserContracts.setUserId(userId);
-		sysUserContracts.setVersion(2);
-
-		sysUserContractsService.insert(sysUserContracts);
-
-		FileUtils.deleteQuietly(srcFile);
-		return BaseController.succeed();
-	}
 }

+ 226 - 0
mec-biz/src/main/resources/config/contracts/financial.ftl

@@ -0,0 +1,226 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8"/>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
+    <meta name="viewport"
+          content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"/>
+    <meta http-equiv="Pragma" content="no-cache"/>
+    <meta http-equiv="Cache-Control" content="no-cache"/>
+    <meta http-equiv="Expires" content="0"/>
+    <title>费用报销单</title>
+    <style>
+        p {
+            margin: 0;
+        }
+
+        body {
+            margin: 0;
+        }
+
+        header {
+            height: 40px;
+            line-height: .40px;
+            color: #000;
+            font-size: 17px;
+            background: #fff;
+            box-shadow: 0px 1px 8px 0px rgba(0, 0, 0, 0.07);
+            text-align: center;
+        }
+
+        header .back {
+            width: 20px;
+            height: 20px;
+            position: absolute;
+            left: 12px;
+            top: 10px;
+        }
+
+        .container {
+            padding: 22px 20px 3px;
+            font-size: 14px;
+            max-width: 600px;
+            margin: 0 auto;
+        }
+
+        h1 {
+            font-size: 18px;
+            text-align: center;
+            margin-bottom: 8px;
+        }
+
+        h2 {
+            font-size: 16px;
+            font-weight: bold;
+            padding-top: 15px;
+        }
+
+        h3 {
+            font-size: 14px;
+            font-weight: bold;
+        }
+
+        .signature {
+            padding-top: 50px;
+        }
+
+        .signature .sign {
+            position: relative;
+            width: 49%;
+            display: inline-block;
+        }
+
+        .signature span {
+            display: block;
+        }
+
+        .signature .cachet {
+            position: absolute;
+            top: -60px;
+            left: 0;
+            width: 150px;
+            height: 150px;
+        }
+
+        .iInfo {
+            display: flex;
+        }
+
+        .iInfo span {
+            flex: 1;
+        }
+
+        .iInfoContent, .iInfoContent span {
+            display: block;
+        }
+
+        .underline {
+            text-decoration: underline;
+        }
+
+        .bold {
+            font-weight: bold;
+        }
+
+        .msgWrap {
+            display: flex;
+            flex-direction: row;
+            justify-content: flex-start;
+            line-height: 30px;
+            flex-flow: row wrap;
+            border: 1px solid #333;
+            border-bottom: none;
+
+            align-items: center;
+            position: relative;
+        }
+
+        .msgWrap:last-child {
+            border-bottom: 1px solid #333;
+        }
+
+        .msgWrap .title {
+            width: 110px;
+            text-align: center;
+
+            margin: 0;
+            align-items: center;
+            height: 100%;
+        }
+
+        .msgWrap .concat {
+            padding-right: 10px;
+            margin: 0;
+            flex: 1;
+            border-left: 1px solid #333;
+            padding-left: 10px;
+        }
+
+        .msgWrap .wrap {
+            flex: 1;
+        }
+
+        .msgWrap .concatWrap:nth-child(1) {
+            border-top: 0;
+        }
+
+        .msgWrap .concatWrap {
+            padding-right: 10px;
+            border: 1px solid #333;
+            border-right: 0;
+            border-bottom: none;
+            border-left: 1px solid #333;
+            padding-left: 10px;
+            display: flex;
+            flex-direction: row;
+            justify-content: flex-start;
+            align-items: center;
+        }
+
+        .msgWrap .concatWrap .subTitle {
+            width: 120px;
+            text-align: right;
+            margin-right: 10px;
+        }
+
+        .msgWrap .concatWrap .subWrap {
+            border-left: 1px solid #333;
+            padding-left: 10px;
+            flex: 1
+        }
+    </style>
+</head>
+<body>
+<div class="container">
+    <h1>XXX(公司全称)费用报销单</h1>
+    <div class="msgWrap">
+        <p class='title'>公司名称: </p>
+        <p class="concat"> XXXXX</p>
+    </div>
+    <div class="msgWrap">
+        <p class='title'>费用申请人: </p>
+        <p class="concat"> XXXXX</p>
+    </div>
+    <div class="msgWrap">
+        <p class='title'>费用类型: </p>
+        <p class="concat"> XXXXX</p>
+    </div>
+    <div class="msgWrap">
+        <p class='title'>报销金额: </p>
+        <p class="concat"> XXXXX</p>
+    </div>
+    <div class="msgWrap">
+        <p class='title'>是否有借款: </p>
+        <p class="concat"> XXXXX</p>
+    </div>
+    <div class="msgWrap">
+        <p class='title'>情况说明: </p>
+        <p class="concat">
+            有很多很多的情况有很多很多的情况有很多很多的情况有很多很多的情况有很多很多的情况有很多很多的情况有很多很多的情况有很多很多的情况有很多很多的情况有很多很多的情况有很多很多的情况有很多很多的情况有很多很多的情况有很多很多的情况有很多很多的情况有很多很多的情况有很多很多的情况有很多很多的情况有很多很多的情况有很多很多的情况</p>
+    </div>
+    <div class="msgWrap">
+        <p class='title'>审批意见: </p>
+        <div class="wrap">
+            <#list circulationUsers as circulationUser>
+                <div class="concatWrap">
+                    <p class="subTitle">${circulationUser.state!} :</p>
+                    <p class="subWrap">${circulationUser.realName!} ${circulationUser.remark!}</p>
+                </div>
+            </#list>
+        </div>
+    </div>
+    <div class="msgWrap">
+        <p class='title'>执行: </p>
+        <div class="wrap">
+            <#list executors as executor>
+                <div class="concatWrap">
+                    <p class="subTitle">${executors.state!} :</p>
+                    <p class="subWrap">${executors.remark!}</p>
+                </div>
+            </#list>
+        </div>
+
+    </div>
+</div>
+</body>
+</html>

+ 8 - 0
mec-biz/src/main/resources/config/mybatis/EmployeeMapper.xml

@@ -49,6 +49,7 @@
         <result column="birthdate_" property="birthdate"/>
         <result column="email_" property="email"/>
         <result column="im_token_" property="imToken"/>
+        <result column="real_name_" property="realName"/>
         <result column="id_card_no_" property="idCardNo"/>
         <result column="wechat_id_" property="wechatId"/>
     </resultMap>
@@ -375,4 +376,11 @@
         SELECT DISTINCT id_ FROM vip_group
         WHERE educational_teacher_id_ = #{levelUserId} AND group_status_ IN (2,6)
     </select>
+
+    <select id="getUsers" resultMap="SysUser">
+        select * from sys_user where id_ IN
+        <foreach collection="userIds" open="(" close=")" separator="," item="userId">
+            #{userId}
+        </foreach>
+    </select>
 </mapper>

+ 72 - 53
mec-thirdparty/src/main/java/com/ym/mec/thirdparty/eseal/ESealPlugin.java

@@ -2,63 +2,82 @@ package com.ym.mec.thirdparty.eseal;
 
 public interface ESealPlugin {
 
-	/**
-	 * 创建用户账户(个人)
-	 * @param realName 姓名
-	 * @param idcard 身份证号码
-	 * @param mobile 手机号码
-	 * @return 账户唯一标识
-	 */
-	public String createUserAccount(String realName, String idcard, String mobile);
+    /**
+     * 创建用户账户(个人)
+     *
+     * @param realName 姓名
+     * @param idcard   身份证号码
+     * @param mobile   手机号码
+     * @return 账户唯一标识
+     */
+    public String createUserAccount(String realName, String idcard, String mobile);
 
-	/**
-	 * 创建用户账户(企业)
-	 * @param orgName  机构名称
-	 * @param organCode 统一社会信用代码
-	 * @return 账户唯一标识
-	 */
-	public String createOrganAccount(String orgName, String organCode);
+    /**
+     * 创建用户账户(企业)
+     *
+     * @param orgName   机构名称
+     * @param organCode 统一社会信用代码
+     * @return 账户唯一标识
+     */
+    public String createOrganAccount(String orgName, String organCode);
 
-	/**
-	 * 创建个人印章
-	 * @param accountId 账户唯一标识
-	 * @return 电子印章数据
-	 */
-	public String createUserSeal(String accountId);
+    /**
+     * 创建个人印章
+     *
+     * @param accountId 账户唯一标识
+     * @return 电子印章数据
+     */
+    public String createUserSeal(String accountId);
 
-	/**
-	 * 创建企业印章
-	 * @param accountId 账户唯一标识
-	 * @param hText 生成印章中的横向文内容
-	 * @param qText 生成印章中的下弦文内容
-	 * @return 电子印章数据
-	 */
-	public String createOrganSeal(String accountId, String hText, String qText);
+    /**
+     * 创建企业印章
+     *
+     * @param accountId 账户唯一标识
+     * @param hText     生成印章中的横向文内容
+     * @param qText     生成印章中的下弦文内容
+     * @return 电子印章数据
+     */
+    public String createOrganSeal(String accountId, String hText, String qText);
 
-	/**
-	 * 平台自身PDF摘要签署(印章标识)
-	 * @param srcPdfPath 源文件
-	 * @param destPdfPath 签名后的目标文件
-	 * @return
-	 */
-	public boolean platformSign(String srcPdfPath, String destPdfPath);
+    /**
+     * 平台自身PDF摘要签署(印章标识)
+     *
+     * @param srcPdfPath  源文件
+     * @param destPdfPath 签名后的目标文件
+     * @return
+     */
+    public boolean platformSign(String srcPdfPath, String destPdfPath);
 
-	/**
-	 * 企业PDF摘要签署(印章图片)
-	 * @param sealData 电子印章数据
-	 * @param srcPdfPath 源文件
-	 * @param destPdfPath 签名后的目标文件
-	 * @return
-	 */
-	public boolean organSign(String sealData, String srcPdfPath, String destPdfPath);
+    /**
+     * 企业PDF摘要签署(印章图片)
+     *
+     * @param sealData    电子印章数据
+     * @param srcPdfPath  源文件
+     * @param destPdfPath 签名后的目标文件
+     * @return
+     */
+    public boolean organSign(String sealData, String srcPdfPath, String destPdfPath);
 
-	/**
-	 * 用户签名
-	 * @param accountId 账户唯一标识
-	 * @param sealData 电子印章数据
-	 * @param srcPdfPath 平台签名后的源文件
-	 * @param destPdfPath 平台、用户都签名后的文件地址
-	 * @return
-	 */
-	public boolean userSign(String accountId, String sealData, String srcPdfPath, String destPdfPath);
+    /**
+     * 用户签名
+     *
+     * @param accountId   账户唯一标识
+     * @param sealData    电子印章数据
+     * @param srcPdfPath  平台签名后的源文件
+     * @param destPdfPath 平台、用户都签名后的文件地址
+     * @return
+     */
+    public boolean userSign(String accountId, String sealData, String srcPdfPath, String destPdfPath);
+
+    /**
+     * 用户签名
+     *
+     * @param accountId   账户唯一标识
+     * @param sealData    电子印章数据
+     * @param keyWorld    印章关键字
+     * @param srcPdfPath  平台签名后的源文件
+     * @param destPdfPath 平台、用户都签名后的文件地址
+     * @return
+     */
+     boolean userSign(String accountId, String sealData, String keyWorld, String srcPdfPath, String destPdfPath);
 }

+ 238 - 198
mec-thirdparty/src/main/java/com/ym/mec/thirdparty/eseal/provider/TsignPlugin.java

@@ -35,226 +35,266 @@ import com.ym.mec.thirdparty.exception.ThirdpartyException;
 @Service
 public class TsignPlugin implements ESealPlugin, InitializingBean, DisposableBean {
 
-	@Value("${eseal.tsign.projectid:4438776254}")
-	public String projectId; // = "1111563517";
+    @Value("${eseal.tsign.projectid:4438776254}")
+    public String projectId; // = "1111563517";
 
-	@Value("${eseal.tsign.projectSecret:a94cf63d6361084d232f345d71321691}")
-	public String projectSecret; // = "95439b0863c241c63a861b87d1e647b7";
+    @Value("${eseal.tsign.projectSecret:a94cf63d6361084d232f345d71321691}")
+    public String projectSecret; // = "95439b0863c241c63a861b87d1e647b7";
 
-	@Value("${eseal.tsign.apisUrl:http://smlitsm.tsign.cn:8080/tgmonitor/rest/app!getAPIInfo2}")
-	public String apisUrl; // = "http://smlitsm.tsign.cn:8080/tgmonitor/rest/app!getAPIInfo2";
+    @Value("${eseal.tsign.apisUrl:http://smlitsm.tsign.cn:8080/tgmonitor/rest/app!getAPIInfo2}")
+    public String apisUrl; // = "http://smlitsm.tsign.cn:8080/tgmonitor/rest/app!getAPIInfo2";
 
-	private ServiceClient serviceClient;
+    private ServiceClient serviceClient;
 
-	public static String getName() {
-		return "Tsign";
-	}
+    public static String getName() {
+        return "Tsign";
+    }
 
-	@Override
-	public void afterPropertiesSet(){
-		ProjectConfig projectconfig = new ProjectConfig();
-		projectconfig.setProjectId(projectId);
-		projectconfig.setProjectSecret(projectSecret);
-		projectconfig.setItsmApiUrl(apisUrl);
-		Result result = ServiceClientManager.registClient(projectconfig, null, null);
-		if (result.getErrCode() != 0) {
-			throw new ThirdpartyException("e签宝客户端注册失败:{}", result.getMsg());
-		}
+    @Override
+    public void afterPropertiesSet() {
+        ProjectConfig projectconfig = new ProjectConfig();
+        projectconfig.setProjectId(projectId);
+        projectconfig.setProjectSecret(projectSecret);
+        projectconfig.setItsmApiUrl(apisUrl);
+        Result result = ServiceClientManager.registClient(projectconfig, null, null);
+        if (result.getErrCode() != 0) {
+            throw new ThirdpartyException("e签宝客户端注册失败:{}", result.getMsg());
+        }
 
-		serviceClient = ServiceClientManager.get(projectId);
-		if (serviceClient == null) {
-			throw new ThirdpartyException("获取e签宝客户端失败");
-		}
-	}
+        serviceClient = ServiceClientManager.get(projectId);
+        if (serviceClient == null) {
+            throw new ThirdpartyException("获取e签宝客户端失败");
+        }
+    }
 
-	@Override
-	public void destroy() throws Exception {
-		ServiceClientManager.shutdown(projectId);
-	}
+    @Override
+    public void destroy() throws Exception {
+        ServiceClientManager.shutdown(projectId);
+    }
 
-	/**
-	 * 创建用户账户(个人)
-	 * @param realName 姓名
-	 * @param idcard 身份证号码
-	 * @param mobile 手机号码
-	 * @return e签宝账户唯一标识
-	 */
-	public String createUserAccount(String realName, String idcard, String mobile) {
-		PersonBean personbean = new PersonBean();
-		personbean.setName(realName);
-		personbean.setIdNo(idcard);
-		personbean.setMobile(mobile);
-		personbean.setPersonArea(LegalAreaType.MAINLAND);
-		// personbean.setPersonArea(4);
-		AccountService service = serviceClient.accountService();
-		AddAccountResult result = service.addAccount(personbean);
-		if (result.getErrCode() == 0) {
-			return result.getAccountId();
-		} else if (result.getErrCode() == 1500012) {
-			return queryAccountIdByIdNo(idcard);
-		}
-		throw new ThirdpartyException(result.getMsg());
-	}
+    /**
+     * 创建用户账户(个人)
+     *
+     * @param realName 姓名
+     * @param idcard   身份证号码
+     * @param mobile   手机号码
+     * @return e签宝账户唯一标识
+     */
+    public String createUserAccount(String realName, String idcard, String mobile) {
+        PersonBean personbean = new PersonBean();
+        personbean.setName(realName);
+        personbean.setIdNo(idcard);
+        personbean.setMobile(mobile);
+        personbean.setPersonArea(LegalAreaType.MAINLAND);
+        // personbean.setPersonArea(4);
+        AccountService service = serviceClient.accountService();
+        AddAccountResult result = service.addAccount(personbean);
+        if (result.getErrCode() == 0) {
+            return result.getAccountId();
+        } else if (result.getErrCode() == 1500012) {
+            return queryAccountIdByIdNo(idcard);
+        }
+        throw new ThirdpartyException(result.getMsg());
+    }
 
-	/**
-	 * 创建用户账户(企业)
-	 * @param orgName  机构名称
-	 * @param organCode 统一社会信用代码
-	 * @return e签宝账户唯一标识
-	 */
-	public String createOrganAccount(String orgName, String organCode) {
-		OrganizeBean organizeBean = new OrganizeBean();
-		organizeBean.setName(orgName);
-		organizeBean.setOrganCode(organCode);
-		organizeBean.setRegType(OrganRegType.MERGE);
-		organizeBean.setUserType(0);
+    /**
+     * 创建用户账户(企业)
+     *
+     * @param orgName   机构名称
+     * @param organCode 统一社会信用代码
+     * @return e签宝账户唯一标识
+     */
+    public String createOrganAccount(String orgName, String organCode) {
+        OrganizeBean organizeBean = new OrganizeBean();
+        organizeBean.setName(orgName);
+        organizeBean.setOrganCode(organCode);
+        organizeBean.setRegType(OrganRegType.MERGE);
+        organizeBean.setUserType(0);
 
-		AccountService service = serviceClient.accountService();
-		AddAccountResult result = service.addAccount(organizeBean);
-		if (result.getErrCode() == 0) {
-			return result.getAccountId();
-		}
-		throw new ThirdpartyException("创建企业账户接口调用失败code=" + result.getErrCode() + "msg=" + result.getMsg());
-	}
+        AccountService service = serviceClient.accountService();
+        AddAccountResult result = service.addAccount(organizeBean);
+        if (result.getErrCode() == 0) {
+            return result.getAccountId();
+        }
+        throw new ThirdpartyException("创建企业账户接口调用失败code=" + result.getErrCode() + "msg=" + result.getMsg());
+    }
 
-	/**
-	 * 创建印章
-	 * @param accountId e签宝账户唯一标识
-	 * @return 电子印章数据
-	 */
-	public String createUserSeal(String accountId) {
-		// 生成模板印章的颜色
-		SealColor color = SealColor.RED;
-		SealService service = serviceClient.sealService();
-		AddSealResult result = service.addTemplateSeal(accountId, PersonTemplateType.RECTANGLE, color);
-		if (0 == result.getErrCode()) {
-			return result.getSealData();
-		}
-		throw new ThirdpartyException("个人模板印章接口调用失败code=" + result.getErrCode() + "msg=" + result.getMsg());
-	}
+    /**
+     * 创建印章
+     *
+     * @param accountId e签宝账户唯一标识
+     * @return 电子印章数据
+     */
+    public String createUserSeal(String accountId) {
+        // 生成模板印章的颜色
+        SealColor color = SealColor.RED;
+        SealService service = serviceClient.sealService();
+        AddSealResult result = service.addTemplateSeal(accountId, PersonTemplateType.RECTANGLE, color);
+        if (0 == result.getErrCode()) {
+            return result.getSealData();
+        }
+        throw new ThirdpartyException("个人模板印章接口调用失败code=" + result.getErrCode() + "msg=" + result.getMsg());
+    }
 
-	@Override
-	public String createOrganSeal(String accountId, String hText, String qText) {
-		// 生成模板印章的颜色
-		SealColor color = SealColor.RED;
-		SealService service = serviceClient.sealService();
-		AddSealResult result = service.addTemplateSeal(accountId, OrganizeTemplateType.STAR, color, hText, qText);
-		if (0 == result.getErrCode()) {
-			return result.getSealData();
-		}
-		throw new ThirdpartyException("企业模板印章接口调用失败code=" + result.getErrCode() + "msg=" + result.getMsg());
-	}
+    @Override
+    public String createOrganSeal(String accountId, String hText, String qText) {
+        // 生成模板印章的颜色
+        SealColor color = SealColor.RED;
+        SealService service = serviceClient.sealService();
+        AddSealResult result = service.addTemplateSeal(accountId, OrganizeTemplateType.STAR, color, hText, qText);
+        if (0 == result.getErrCode()) {
+            return result.getSealData();
+        }
+        throw new ThirdpartyException("企业模板印章接口调用失败code=" + result.getErrCode() + "msg=" + result.getMsg());
+    }
 
-	/**
-	 * 平台自身PDF摘要签署(印章标识)
-	 * @param srcPdfPath 源文件
-	 * @param destPdfPath 签名后的目标文件
-	 * @return
-	 */
-	public boolean platformSign(String srcPdfPath, String destPdfPath) {
-		PosBean posBean = new PosBean();
-		// 签章类型,Single-单页签章、Multi-多页签章、Edges-骑缝章、Key-关键字签章
-		SignType signType = SignType.Key;
-		// 接口调用方(平台方)的印章,请在www.tsign.cn官网中设置默认印章其sealId值为0
-		int sealId = 0;
-		// 设置接口调用方(平台方)签章位置信息
-		posBean.setPosPage("1");// 签署页码,若为多页签章,支持页码格式“1-3,5,8“,若为坐标定位时,不可空
-		posBean.setKey("甲方签章");
-		// 签署位置X坐标,默认值为0,以pdf页面的左下角作为原点,控制距离页面左端的横向移动距离,单位为px
-		posBean.setPosX(100);
-		// 签署位置Y坐标,默认值为0,以pdf页面的左下角作为原点,控制距离页面底端的纵向移动距离,单位为px
-		posBean.setPosY(0);
-		// 印章图片在PDF文件中的等比缩放大小,公章标准大小为4.2厘米即159px
-		posBean.setWidth(100);
-		SignPDFFileBean PDFbean = new SignPDFFileBean();
-		PDFbean.setSrcPdfFile(srcPdfPath);
-		PDFbean.setDstPdfFile(destPdfPath);
+    /**
+     * 平台自身PDF摘要签署(印章标识)
+     *
+     * @param srcPdfPath  源文件
+     * @param destPdfPath 签名后的目标文件
+     * @return
+     */
+    public boolean platformSign(String srcPdfPath, String destPdfPath) {
+        PosBean posBean = new PosBean();
+        // 签章类型,Single-单页签章、Multi-多页签章、Edges-骑缝章、Key-关键字签章
+        SignType signType = SignType.Key;
+        // 接口调用方(平台方)的印章,请在www.tsign.cn官网中设置默认印章其sealId值为0
+        int sealId = 0;
+        // 设置接口调用方(平台方)签章位置信息
+        posBean.setPosPage("1");// 签署页码,若为多页签章,支持页码格式“1-3,5,8“,若为坐标定位时,不可空
+        posBean.setKey("甲方签章");
+        // 签署位置X坐标,默认值为0,以pdf页面的左下角作为原点,控制距离页面左端的横向移动距离,单位为px
+        posBean.setPosX(100);
+        // 签署位置Y坐标,默认值为0,以pdf页面的左下角作为原点,控制距离页面底端的纵向移动距离,单位为px
+        posBean.setPosY(0);
+        // 印章图片在PDF文件中的等比缩放大小,公章标准大小为4.2厘米即159px
+        posBean.setWidth(100);
+        SignPDFFileBean PDFbean = new SignPDFFileBean();
+        PDFbean.setSrcPdfFile(srcPdfPath);
+        PDFbean.setDstPdfFile(destPdfPath);
 
-		SelfSignService service = serviceClient.selfSignService();
-		FileDigestSignResult result = service.localSignPdf(PDFbean, posBean, sealId, signType);
-		if (0 != result.getErrCode()) {
-			throw new ThirdpartyException("平台自身PDF摘要签署接口调用失败!Code=" + result.getErrCode() + "MSG=" + result.getMsg());
-		}
-		return true;
-	}
+        SelfSignService service = serviceClient.selfSignService();
+        FileDigestSignResult result = service.localSignPdf(PDFbean, posBean, sealId, signType);
+        if (0 != result.getErrCode()) {
+            throw new ThirdpartyException("平台自身PDF摘要签署接口调用失败!Code=" + result.getErrCode() + "MSG=" + result.getMsg());
+        }
+        return true;
+    }
 
-	/**
-	 * 企业PDF摘要签署(印章图片)
-	 * @param sealData 电子印章数据
-	 * @param srcPdfPath 源文件
-	 * @param destPdfPath 签名后的目标文件
-	 * @return
-	 */
-	public boolean organSign(String sealData, String srcPdfPath, String destPdfPath) {
-		PosBean posBean = new PosBean();
-		// 签章类型,Single-单页签章、Multi-多页签章、Edges-骑缝章、Key-关键字签章
-		SignType signType = SignType.Key;
-		// 设置接口调用方(平台方)签章位置信息
-		posBean.setPosPage("1");// 签署页码,若为多页签章,支持页码格式“1-3,5,8“,若为坐标定位时,不可空
-		posBean.setKey("甲方签章");
-		// 签署位置X坐标,默认值为0,以pdf页面的左下角作为原点,控制距离页面左端的横向移动距离,单位为px
-		posBean.setPosX(100);
-		// 签署位置Y坐标,默认值为0,以pdf页面的左下角作为原点,控制距离页面底端的纵向移动距离,单位为px
-		posBean.setPosY(0);
-		// 印章图片在PDF文件中的等比缩放大小,公章标准大小为4.2厘米即159px
-		posBean.setWidth(100);
-		SignPDFFileBean PDFbean = new SignPDFFileBean();
-		PDFbean.setSrcPdfFile(srcPdfPath);
-		PDFbean.setDstPdfFile(destPdfPath);
+    /**
+     * 企业PDF摘要签署(印章图片)
+     *
+     * @param sealData    电子印章数据
+     * @param srcPdfPath  源文件
+     * @param destPdfPath 签名后的目标文件
+     * @return
+     */
+    public boolean organSign(String sealData, String srcPdfPath, String destPdfPath) {
+        PosBean posBean = new PosBean();
+        // 签章类型,Single-单页签章、Multi-多页签章、Edges-骑缝章、Key-关键字签章
+        SignType signType = SignType.Key;
+        // 设置接口调用方(平台方)签章位置信息
+        posBean.setPosPage("1");// 签署页码,若为多页签章,支持页码格式“1-3,5,8“,若为坐标定位时,不可空
+        posBean.setKey("甲方签章");
+        // 签署位置X坐标,默认值为0,以pdf页面的左下角作为原点,控制距离页面左端的横向移动距离,单位为px
+        posBean.setPosX(100);
+        // 签署位置Y坐标,默认值为0,以pdf页面的左下角作为原点,控制距离页面底端的纵向移动距离,单位为px
+        posBean.setPosY(0);
+        // 印章图片在PDF文件中的等比缩放大小,公章标准大小为4.2厘米即159px
+        posBean.setWidth(100);
+        SignPDFFileBean PDFbean = new SignPDFFileBean();
+        PDFbean.setSrcPdfFile(srcPdfPath);
+        PDFbean.setDstPdfFile(destPdfPath);
 
-		SelfSignService service = serviceClient.selfSignService();
-		FileDigestSignResult result = service.localSignPdf(PDFbean, posBean, sealData, signType);
-		if (0 != result.getErrCode()) {
-			throw new ThirdpartyException("平台自身PDF摘要签署接口调用失败!Code=" + result.getErrCode() + "MSG=" + result.getMsg());
-		}
-		return true;
-	}
+        SelfSignService service = serviceClient.selfSignService();
+        FileDigestSignResult result = service.localSignPdf(PDFbean, posBean, sealData, signType);
+        if (0 != result.getErrCode()) {
+            throw new ThirdpartyException("平台自身PDF摘要签署接口调用失败!Code=" + result.getErrCode() + "MSG=" + result.getMsg());
+        }
+        return true;
+    }
 
-	/**
-	 * 用户签名
-	 * @param accountId e签宝账户唯一标识
-	 * @param sealData 电子印章数据
-	 * @param srcPdfPath 平台签名后的源文件
-	 * @param destPdfPath 平台、用户都签名后的文件地址
-	 * @return
-	 */
-	public boolean userSign(String accountId, String sealData, String srcPdfPath, String destPdfPath) {
+    /**
+     * 用户签名
+     *
+     * @param accountId   e签宝账户唯一标识
+     * @param sealData    电子印章数据
+     * @param srcPdfPath  平台签名后的源文件
+     * @param destPdfPath 平台、用户都签名后的文件地址
+     * @return
+     */
+    public boolean userSign(String accountId, String sealData, String srcPdfPath, String destPdfPath) {
 
-		SignPDFFileBean signPDFStreamBean = new SignPDFFileBean();
-		// C:test_signed.pdf为平台自身签署后路径
-		signPDFStreamBean.setSrcPdfFile(srcPdfPath);
-		signPDFStreamBean.setDstPdfFile(destPdfPath);
-		PosBean posBean = new PosBean();
-		posBean.setPosPage("1");
-		posBean.setPosType(1);
-		posBean.setWidth(80);
-		posBean.setKey("乙方签章");
-		posBean.setPosX(100);
-		posBean.setPosY(0);
+        SignPDFFileBean signPDFStreamBean = new SignPDFFileBean();
+        // C:test_signed.pdf为平台自身签署后路径
+        signPDFStreamBean.setSrcPdfFile(srcPdfPath);
+        signPDFStreamBean.setDstPdfFile(destPdfPath);
+        PosBean posBean = new PosBean();
+        posBean.setPosPage("1");
+        posBean.setPosType(1);
+        posBean.setWidth(80);
+        posBean.setKey("乙方签章");
+        posBean.setPosX(100);
+        posBean.setPosY(0);
 
-		// 签章类型,Single-单页签章、Multi-多页签章、Edges-骑缝章、Key-关键字签章
-		SignType signtype = SignType.Key;
-		UserSignService service = serviceClient.userSignService();
-		FileDigestSignResult result = service.localSignPDF(accountId, sealData, signPDFStreamBean, posBean, signtype);
-		if (result.getErrCode() == 0) {
-			return true;
-		}
-		throw new ThirdpartyException("平台用户PDF摘要签署接口调用失败" + result.getErrCode() + "msg=" + result.getMsg());
-	}
+        // 签章类型,Single-单页签章、Multi-多页签章、Edges-骑缝章、Key-关键字签章
+        SignType signtype = SignType.Key;
+        UserSignService service = serviceClient.userSignService();
+        FileDigestSignResult result = service.localSignPDF(accountId, sealData, signPDFStreamBean, posBean, signtype);
+        if (result.getErrCode() == 0) {
+            return true;
+        }
+        throw new ThirdpartyException("平台用户PDF摘要签署接口调用失败" + result.getErrCode() + "msg=" + result.getMsg());
+    }
 
-	private String queryAccountIdByIdNo(String idcardNo) {
+    private String queryAccountIdByIdNo(String idcardNo) {
 
-		AccountService service = serviceClient.accountService();
+        AccountService service = serviceClient.accountService();
 
-		GetAccountProfileResult result = service.getAccountInfoByIdNo(idcardNo, LicenseQueryType.MAINLAND);
+        GetAccountProfileResult result = service.getAccountInfoByIdNo(idcardNo, LicenseQueryType.MAINLAND);
 
-		if (result != null) {
-			AccountProfile accountProfile = result.getAccountInfo();
-			if (accountProfile != null) {
-				return accountProfile.getAccountUid();
-			}
-		}
+        if (result != null) {
+            AccountProfile accountProfile = result.getAccountInfo();
+            if (accountProfile != null) {
+                return accountProfile.getAccountUid();
+            }
+        }
 
-		return null;
-	}
+        return null;
+    }
+
+    /**
+     * 用户签名
+     *
+     * @param accountId   e签宝账户唯一标识
+     * @param sealData    电子印章数据
+     * @param keyWorld    印章关键字
+     * @param srcPdfPath  平台签名后的源文件
+     * @param destPdfPath 平台、用户都签名后的文件地址
+     * @return
+     */
+    public boolean userSign(String accountId, String sealData, String keyWorld, String srcPdfPath, String destPdfPath) {
+
+        SignPDFFileBean signPDFStreamBean = new SignPDFFileBean();
+        // C:test_signed.pdf为平台自身签署后路径
+        signPDFStreamBean.setSrcPdfFile(srcPdfPath);
+        signPDFStreamBean.setDstPdfFile(destPdfPath);
+        PosBean posBean = new PosBean();
+        posBean.setPosPage("1");
+        posBean.setPosType(1);
+        posBean.setWidth(80);
+        posBean.setKey(keyWorld);
+        posBean.setPosX(100);
+        posBean.setPosY(0);
+
+        // 签章类型,Single-单页签章、Multi-多页签章、Edges-骑缝章、Key-关键字签章
+        SignType signtype = SignType.Key;
+        UserSignService service = serviceClient.userSignService();
+        FileDigestSignResult result = service.localSignPDF(accountId, sealData, signPDFStreamBean, posBean, signtype);
+        if (result.getErrCode() == 0) {
+            return true;
+        }
+        throw new ThirdpartyException("平台用户PDF摘要签署接口调用失败" + result.getErrCode() + "msg=" + result.getMsg());
+    }
 }

+ 28 - 26
mec-web/src/main/java/com/ym/mec/web/config/ResourceServerConfig.java

@@ -16,31 +16,33 @@ import com.ym.mec.common.security.BaseAuthenticationEntryPoint;
 @EnableGlobalMethodSecurity(prePostEnabled = true)
 public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
 
-	@Autowired
-	private BaseAccessDeniedHandler baseAccessDeniedHandler;
-
-	@Autowired
-	private BaseAuthenticationEntryPoint baseAuthenticationEntryPoint;
-
-	@Override
-	public void configure(HttpSecurity http) throws Exception {
-		http.csrf()
-				.disable()
-				.exceptionHandling()
-				.accessDeniedHandler(baseAccessDeniedHandler)
-				.authenticationEntryPoint(baseAuthenticationEntryPoint)
-				.and()
-				.authorizeRequests()
-				.antMatchers("/task/**")
-				.hasIpAddress("0.0.0.0/0")
-				.antMatchers("/v2/api-docs", "/classGroup/highClassGroups", "/code/*", "/api/*", "/appVersionInfo/queryByPlatform", "/eduDegree/*",
-						"/uploadFile", "/eduContracts/queryProduceContract","/activity/doubleEleven2020Statis","/replacementInstrument/queryPage",
-						"/replacementInstrumentActivity/queryReplacementsStat","/eduStudentRegistration/queryPreApplyList","/eduSubject/findSubSubjects","/eduFinancialExpenditure/batchAdd","/eduSendNotice/*").permitAll().anyRequest().authenticated().and().httpBasic();
-	}
-
-	@Override
-	public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
-		resources.authenticationEntryPoint(baseAuthenticationEntryPoint).accessDeniedHandler(baseAccessDeniedHandler);
-	}
+    @Autowired
+    private BaseAccessDeniedHandler baseAccessDeniedHandler;
+
+    @Autowired
+    private BaseAuthenticationEntryPoint baseAuthenticationEntryPoint;
+
+    @Override
+    public void configure(HttpSecurity http) throws Exception {
+        http.csrf()
+                .disable()
+                .exceptionHandling()
+                .accessDeniedHandler(baseAccessDeniedHandler)
+                .authenticationEntryPoint(baseAuthenticationEntryPoint)
+                .and()
+                .authorizeRequests()
+                .antMatchers("/task/**")
+                .hasIpAddress("0.0.0.0/0")
+                .antMatchers("/v2/api-docs", "/classGroup/highClassGroups", "/code/*", "/api/*", "/appVersionInfo/queryByPlatform", "/eduDegree/*",
+                        "/uploadFile", "/eduContracts/queryProduceContract", "/activity/doubleEleven2020Statis", "/replacementInstrument/queryPage",
+                        "/replacementInstrumentActivity/queryReplacementsStat", "/eduStudentRegistration/queryPreApplyList",
+                        "/eduSubject/findSubSubjects", "/eduFinancialExpenditure/batchAdd", "/eduSendNotice/*",
+                        "/oaContracts/*").permitAll().anyRequest().authenticated().and().httpBasic();
+    }
+
+    @Override
+    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
+        resources.authenticationEntryPoint(baseAuthenticationEntryPoint).accessDeniedHandler(baseAccessDeniedHandler);
+    }
 
 }

+ 73 - 0
mec-web/src/main/java/com/ym/mec/web/controller/education/OaContractsController.java

@@ -0,0 +1,73 @@
+package com.ym.mec.web.controller.education;
+
+import com.ym.mec.biz.dal.dto.CirculationUser;
+import com.ym.mec.biz.service.ContractService;
+import com.ym.mec.common.controller.BaseController;
+import com.ym.mec.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RequestMapping("oaContracts")
+@Api(tags = "OA签章服务")
+@RestController
+public class OaContractsController extends BaseController {
+
+    @Autowired
+    private ContractService contractService;
+
+    @GetMapping("finance")
+    public HttpResponseResult<String> transferProduceContract() {
+        List<CirculationUser> circulationUsers = new ArrayList<>();
+        CirculationUser circulationUser1 = new CirculationUser();
+        circulationUser1.setUserId(100002);
+        circulationUser1.setRealName("宋筠");
+        circulationUser1.setPhone("13986250561");
+        circulationUser1.setIdCard("420527198308075343");
+        circulationUser1.setState("主管审批");
+        circulationUser1.setRemark("费用无误通过");
+        circulationUser1.setWorkOrderId(1);
+        circulationUsers.add(circulationUser1);
+
+        CirculationUser circulationUser2 = new CirculationUser();
+        circulationUser2.setUserId(100134);
+        circulationUser2.setRealName("李志超");
+        circulationUser2.setPhone("18249982421");
+        circulationUser2.setIdCard("372901199202297212");
+        circulationUser2.setState("经理审批");
+        circulationUser2.setRemark("费用无误通过");
+        circulationUser2.setWorkOrderId(1);
+        circulationUsers.add(circulationUser2);
+
+        List<CirculationUser> executors = new ArrayList<>();
+
+        CirculationUser executor1 = new CirculationUser();
+        executor1.setUserId(100180);
+        executor1.setRealName("杨卉");
+        executor1.setPhone("18627021222");
+        executor1.setIdCard("420102198410072828");
+        executor1.setState("分部会计");
+        executor1.setRemark("费用无误通过");
+        executor1.setWorkOrderId(1);
+        executors.add(executor1);
+
+        CirculationUser executor2 = new CirculationUser();
+        executor2.setUserId(100201);
+        executor2.setRealName("蔡明哲");
+        executor2.setPhone("18611812776");
+        executor2.setIdCard("230204198110311914");
+        executor2.setState("财务经理");
+        executor2.setRemark("费用无误通过");
+        executor2.setWorkOrderId(1);
+        executors.add(executor2);
+
+        String fileUrl = contractService.transferOaFinancial(circulationUsers, executors);
+        return succeed(fileUrl);
+    }
+
+}