sign.go 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. package sign
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "mtp20access/global"
  7. "mtp20access/model/account"
  8. "mtp20access/model/account/request"
  9. "mtp20access/model/account/response"
  10. "mtp20access/service/asign"
  11. "os"
  12. "strconv"
  13. "time"
  14. "github.com/gofrs/uuid"
  15. "go.uber.org/zap"
  16. )
  17. // QueryUserESignRecord 查询用户电子签记录表
  18. func QueryUserESignRecord(userId int) (rsp []account.Useresignrecord, err error) {
  19. rsp = make([]account.Useresignrecord, 0)
  20. err = global.M2A_DB.Where("USERID = ?", userId).Find(&rsp)
  21. return
  22. }
  23. // AddUser 添加用户
  24. func AddUser(req request.AddUserReq, userId int) (err error) {
  25. // 获取用户电子签记录
  26. useresignrecord := new(account.Useresignrecord)
  27. has, _ := global.M2A_DB.Where("USERID = ? AND TEMPLATETYPE = 1 AND RECORDSTATUS = 3", userId).Get(useresignrecord)
  28. if has {
  29. err = errors.New("用户已同步")
  30. return
  31. }
  32. // 调用爱签API-添加个人用户(https://{host}/user/addPersonalUser)
  33. rsp, err := asign.AddPersonalUserBy(
  34. strconv.Itoa(userId),
  35. req.Name,
  36. req.IdCard,
  37. req.Mobile,
  38. req.IdCardType,
  39. )
  40. if err != nil {
  41. return
  42. }
  43. if rsp.Code != 100000 {
  44. err = errors.New(strconv.Itoa(rsp.Code))
  45. global.M2A_LOG.Error("【AddUser】 接口调用失败", zap.Error(err))
  46. return
  47. }
  48. // 更新用户电子签记录-实名认证状态
  49. authinfo, err := json.Marshal(req)
  50. if err != nil {
  51. global.M2A_LOG.Error("【AddUser】 构建AUTHINFO失败", zap.Error(err))
  52. return
  53. }
  54. sql := fmt.Sprintf(`
  55. UPDATE useresignrecord
  56. SET RECORDSTATUS = 3,
  57. UPDATETIME = SYSDATE,
  58. AUTHINFO = '%v'
  59. WHERE USERID = %v AND TEMPLATETYPE = 1
  60. `, string(authinfo), userId)
  61. if _, err = global.M2A_DB.Exec(sql); err != nil {
  62. global.M2A_LOG.Error("【AddUser】 更新用户电子签记录失败", zap.Error(err))
  63. return
  64. }
  65. return
  66. }
  67. // CreateContractAndAddSigner 上传待签署文件和添加签署方
  68. func CreateContractAndAddSigner(req request.CreateContractAndAddSignerReq, userId int) (rsp response.CreateContractAndAddSignerRsp, err error) {
  69. // 获取用户电子签记录
  70. useresignrecord := new(account.Useresignrecord)
  71. has, err := global.M2A_DB.Where("USERID = ? AND TEMPLATENO = ?", userId, req.TemplateNo).Get(useresignrecord)
  72. if err != nil || !has {
  73. global.M2A_LOG.Error("【CreateContractAndAddSigner】 获取用户电子签记录失败", zap.Error(err))
  74. return
  75. }
  76. // 判断是否需要创建合同(上传待签署文件)
  77. if useresignrecord.CONTRACTNO == "" {
  78. // 生成合同编号
  79. // #{userid} || '_' || to_char(sysdate, 'yyyyMMddhh24miss') || '_' || seq_useresignrecord.currval,
  80. contractNo := fmt.Sprintf("%d_%s_%v", userId, time.Now().Format("20060102150405"), useresignrecord.RECORDID)
  81. // 调用爱签API-上传待签署文件(https://{host}/contract/createContract)
  82. r, e := asign.CreateContract(
  83. contractNo,
  84. useresignrecord.TEMPLATENAME,
  85. useresignrecord.TEMPLATENO,
  86. )
  87. if e != nil {
  88. err = e
  89. return
  90. }
  91. if r.Code != 100000 {
  92. err = errors.New(strconv.Itoa(r.Code))
  93. global.M2A_LOG.Error("【CreateContractAndAddSigner】 上传待签署文件接口调用失败", zap.Error(err))
  94. return
  95. }
  96. // 将返回的合同编号写入数据库
  97. useresignrecord.CONTRACTNO = contractNo
  98. sql := fmt.Sprintf(`
  99. UPDATE useresignrecord
  100. SET contractNo = '%v',
  101. UPDATETIME = SYSDATE
  102. WHERE RECORDID = %v
  103. `, useresignrecord.CONTRACTNO, useresignrecord.RECORDID)
  104. if _, err = global.M2A_DB.Exec(sql); err != nil {
  105. global.M2A_LOG.Error("【CreateContractAndAddSigner】 写入合同编号失败", zap.Error(err))
  106. return
  107. }
  108. }
  109. // 判断是否需要添加签署方(获取合同签约地址)
  110. if useresignrecord.SIGNURL != "" {
  111. err = errors.New("合同签署链接已存在")
  112. } else {
  113. // 调用爱签API-添加签署方(https://{host}/contract/addSigner)
  114. r, e := asign.AddSigner(
  115. useresignrecord.CONTRACTNO,
  116. strconv.Itoa(userId),
  117. )
  118. if e != nil {
  119. err = e
  120. return
  121. }
  122. if r.Code != 100000 {
  123. err = errors.New(strconv.Itoa(r.Code))
  124. global.M2A_LOG.Error("【CreateContractAndAddSigner】 添加签署方接口调用失败", zap.Error(err))
  125. return
  126. }
  127. if len(r.Data.SignUser) > 0 {
  128. useresignrecord.SIGNURL = r.Data.SignUser[0].SignUrl
  129. // 将返回的合同编号写入数据库
  130. sql := fmt.Sprintf(`
  131. UPDATE useresignrecord
  132. SET SIGNURL = '%v',
  133. UPDATETIME = SYSDATE
  134. WHERE RECORDID = %v
  135. `, useresignrecord.SIGNURL, useresignrecord.RECORDID)
  136. if _, err = global.M2A_DB.Exec(sql); err != nil {
  137. global.M2A_LOG.Error("【CreateContractAndAddSigner】 写入合同签署链接失败", zap.Error(err))
  138. return
  139. }
  140. // 给客户端返回合同签署地址
  141. rsp.SignUrl = useresignrecord.SIGNURL
  142. }
  143. }
  144. return
  145. }
  146. // SignCompleted
  147. func SignCompleted(userId int) (err error) {
  148. // 获取用户电子签记录
  149. datas := make([]account.Useresignrecord, 0)
  150. err = global.M2A_DB.Where("USERID = ?", userId).Find(&datas)
  151. if err != nil {
  152. global.M2A_LOG.Error("SignCompleted 获取用户电子签记录失败", zap.Error(err))
  153. return
  154. }
  155. for _, item := range datas {
  156. if item.RECORDSTATUS != 3 {
  157. err = errors.New("未完成所有合同签署")
  158. return
  159. }
  160. }
  161. return
  162. }
  163. /*
  164. handleASignCompleted 处理爱签合同签署完成后回调通知
  165. req 异步推送参数
  166. */
  167. func HandleASignCompleted(req request.HandleASignCompletedReq) (err error) {
  168. /*
  169. // 合同签署完成后回调通知示例
  170. String publickey = "MFwwDQcccccxxxxmEz/nw27Ln6AP90ZCMPi+iNF1m9mhNECAwEAAQ==";
  171. String remark = ""; // 若被拒签则会返回拒签原因,拒签原因不参与签名
  172. Map <String, String> map = new HashMap<>();
  173. map.put("action", "signCompleted");
  174. map.put("contractNo", "20221114142140345");
  175. map.put("status", "2");
  176. map.put("signTime", "2022-11-14 14:22:00");
  177. map.put("timestamp", "1668406920005");
  178. map.put("validityTime", "2022-11-24 23:59:59");
  179. String json = JSONObject.toJSONString(map, SerializerFeature.MapSortField);
  180. System.out.println("数据:" + json);
  181. // 计算签名
  182. try {
  183. String sign = "feFfcprGjdmDDqRmxK5qlWlMncX0mc6LJ5agebOGIx2QiAern+6ZRg/SBHOgvHp/+1ywVRdyKNUKxPneETwKPw==";
  184. System.out.println(RSAUtils.rsaSignCheck(sign, json, publickey));
  185. } catch (Exception e) {
  186. e.printStackTrace();
  187. }
  188. */
  189. // 获取合同编号
  190. if req.ContractNo == "" {
  191. global.M2A_LOG.Error("【HandleASignCompleted】 获取合同编号失败", zap.Any("req", req))
  192. return
  193. }
  194. // 获取合同状态
  195. if req.Status == "" {
  196. global.M2A_LOG.Error("【HandleASignCompleted】 获取获取合同状态失败", zap.Any("req", req))
  197. return
  198. }
  199. if req.Status == "2" {
  200. // 已签约
  201. // 下载合同
  202. r, e := asign.DownloadContract(req.ContractNo)
  203. if e != nil {
  204. err = e
  205. return
  206. }
  207. if r.Code != 100000 {
  208. err = errors.New(strconv.Itoa(r.Code))
  209. global.M2A_LOG.Error("【HandleASignCompleted】 下载合同接口调用失败", zap.Error(err))
  210. return
  211. }
  212. if r.Data.Data != "" {
  213. // 获取网上开户地址(用于客户端下载文件)
  214. openconfig := account.Wskhopenaccountconfig{CONFIGID: 6}
  215. has, e := openconfig.Get()
  216. if e != nil || !has {
  217. err = e
  218. global.M2A_LOG.Error("【HandleASignCompleted】 获取网上开户地址失败", zap.Error(err))
  219. return
  220. }
  221. // 将Base64写入目标文件
  222. uid, _ := uuid.NewV4()
  223. fileName := fmt.Sprintf("%v_%v.pdf", r.Data.FileName, uid.String())
  224. openconfig.CONFIGVALUE = "./" // FIXME: - 测试代码
  225. folderPath := "sign/" + time.Now().Format("20060102")
  226. savePath := openconfig.CONFIGVALUE + "/uploadFile/" + folderPath
  227. fmt.Println(savePath + "/" + fileName)
  228. f, e := os.OpenFile(savePath+"/"+fileName, os.O_RDWR|os.O_CREATE, os.ModePerm)
  229. if e != nil {
  230. err = e
  231. global.M2A_LOG.Error("【HandleASignCompleted】 获取网上开户地址失败", zap.Error(err))
  232. return
  233. }
  234. defer f.Close()
  235. // 更新数据库记录
  236. // 获取用户电子签记录
  237. // useresignrecord := new(account.Useresignrecord)
  238. // has, e = global.M2A_DB.Where("CONTRACTNO = ?", req.ContractNo).Get(useresignrecord)
  239. // if e != nil || !has {
  240. // err = e
  241. // global.M2A_LOG.Error("【HandleASignCompleted】 获取用户电子签记录失败", zap.Error(err))
  242. // return
  243. // }
  244. contractfileaddr := fmt.Sprintf("./uploadFile/%v/%v", folderPath, fileName)
  245. sql := fmt.Sprintf(`
  246. UPDATE useresignrecord
  247. SET RECORDSTATUS = 3,
  248. UPDATETIME = SYSDATE,
  249. CONTRACTFILEADDR = '%v'
  250. WHERE CONTRACTNO = %v
  251. `, contractfileaddr, req.ContractNo)
  252. if _, err = global.M2A_DB.Exec(sql); err != nil {
  253. global.M2A_LOG.Error("【HandleASignCompleted】 更新用户电子签记录失败", zap.Error(err))
  254. return
  255. }
  256. }
  257. }
  258. return
  259. }