servcies.go 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  1. package asign
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "io"
  8. "mtp2_if/config"
  9. "mtp2_if/db"
  10. "mtp2_if/logger"
  11. "mtp2_if/models"
  12. "mtp2_if/utils"
  13. "net/http"
  14. "strconv"
  15. )
  16. // CreateSeal 创建印章
  17. func CreateSeal(req CreateSealReq) (err error) {
  18. apiReq := APIReq[APICreateSealReq]{
  19. Data: APICreateSealReq{
  20. Account: req.Account,
  21. IsDefault: req.IsDefault,
  22. Base64ImageStr: req.Base64ImageStr,
  23. SealName: req.SealName,
  24. SealNo: strconv.Itoa(int(utils.GenID())),
  25. },
  26. }
  27. apiRsp, err := APIPost[APICreateSealReq, interface{}](apiReq, APIURL_CreateSeal)
  28. if err != nil {
  29. return
  30. }
  31. if apiRsp.Code != CODE_SUCCESS {
  32. err = errors.New(apiRsp.Msg)
  33. return
  34. }
  35. return
  36. }
  37. // ModifySeal 修改印章
  38. func ModifySeal(req ModifySealReq) (err error) {
  39. apiReq := APIReq[APIModifySealReq]{
  40. Data: APIModifySealReq{
  41. Account: req.Account,
  42. IsDefault: req.IsDefault,
  43. Base64ImageStr: req.Base64ImageStr,
  44. SealName: req.SealName,
  45. SealNo: req.SealNo,
  46. },
  47. }
  48. apiRsp, err := APIPost[APIModifySealReq, interface{}](apiReq, APIURL_ModifySeal)
  49. if err != nil {
  50. return
  51. }
  52. if apiRsp.Code != CODE_SUCCESS {
  53. err = errors.New(apiRsp.Msg)
  54. return
  55. }
  56. return
  57. }
  58. // BankCard4 银行卡四要素认证
  59. func BankCard4(req BankCard4Req) (rsp BankCard4Rsp, err error) {
  60. // 校验入参
  61. if req.Type == 1 && req.Person == nil {
  62. err = errors.New("缺少参数")
  63. return
  64. }
  65. if req.Type == 2 && req.Company == nil {
  66. err = errors.New("缺少参数")
  67. return
  68. }
  69. if req.Type == 1 {
  70. // 判断此身份证号已经已经被别的账户占用
  71. if idCardNo, e := models.EncryptField(req.Person.IdCardNo); e == nil {
  72. if us, e := models.GetUserInfoByIdCardNo(idCardNo); e == nil {
  73. if len(us) > 0 {
  74. u := us[0]
  75. if u.Userid != int64(req.UserId) {
  76. err = errors.New("身份证号已被占用")
  77. return
  78. }
  79. }
  80. }
  81. }
  82. // 判断此手机号码已经已经被别的账户占用
  83. if mobile, e := models.EncryptField(req.Person.Mobile); e == nil {
  84. if us, e := models.GetUserInfoByMobile(mobile); e == nil {
  85. if len(us) > 0 {
  86. u := us[0]
  87. if u.Userid != int64(req.UserId) {
  88. err = errors.New("手机号码已被占用")
  89. return
  90. }
  91. }
  92. }
  93. }
  94. }
  95. // 判断证件号码是否已经在爱签平台存在
  96. // var getUserReq APIGetUserReq
  97. // getUserReq.Account = strconv.Itoa(req.UserId)
  98. getUserReq := APIReq[APIGetUserReq]{
  99. Data: APIGetUserReq{Account: strconv.Itoa(req.UserId)},
  100. }
  101. apiRsp, err := APIPost[APIGetUserReq, []APIGetUserRsp](getUserReq, APIURL_GetUser)
  102. if err != nil {
  103. return
  104. }
  105. if apiRsp.Code == CODE_SUCCESS {
  106. err = errors.New("电子签平台用户编号已存在")
  107. logger.GetLogger().Error("电子签平台用户编号已存在, apiRsp:", apiRsp)
  108. return
  109. }
  110. getUserReq.Data.Account = ""
  111. if req.Type == 1 {
  112. getUserReq.Data.IdCard = req.Person.IdCardNo
  113. } else {
  114. getUserReq.Data.CreditCode = req.Company.CreditCode
  115. }
  116. apiRsp, err = APIPost[APIGetUserReq, []APIGetUserRsp](getUserReq, APIURL_GetUser)
  117. if err != nil {
  118. return
  119. }
  120. if apiRsp.Code == CODE_SUCCESS && len(apiRsp.Data) > 0 {
  121. err = errors.New("电子签平台证件号码已存在")
  122. logger.GetLogger().Error("电子签平台证件号码已存在, apiRsp:", apiRsp)
  123. return
  124. }
  125. // 从交易库中获取类型为实名认证的电子签信息
  126. var record models.Useresignrecord
  127. has, err := db.GetEngine().Where("TEMPLATETYPE = 1 AND USERID = ?", req.UserId).Get(&record)
  128. if err != nil {
  129. return
  130. }
  131. if !has {
  132. err = errors.New("无对应实名认证记录信息")
  133. logger.GetLogger().Error("无对应实名认证记录信息, userId:", req.UserId)
  134. return
  135. }
  136. if record.RECORDSTATUS == 3 {
  137. err = errors.New("账户已实名")
  138. logger.GetLogger().Error("账户已实名, userId:", req.UserId)
  139. return
  140. }
  141. // 调用爱签接口
  142. var authinfo []byte
  143. var bankCard4Rsp *APIRsp[APIBankCard4Rsp]
  144. if req.Type == 1 { // 个人
  145. personBankCard4Req := APIReq[APIPersonBankCard4Req]{
  146. Data: APIPersonBankCard4Req{
  147. RealName: req.Person.RealName,
  148. IdCardNo: req.Person.IdCardNo,
  149. BankCard: req.Person.BankCard,
  150. Mobile: req.Person.Mobile,
  151. },
  152. }
  153. if bankCard4Rsp, err = APIPost[APIPersonBankCard4Req, APIBankCard4Rsp](personBankCard4Req, APIURL_Person_BankCard4); err != nil {
  154. return
  155. }
  156. if authinfo, err = json.Marshal(req.Person); err != nil {
  157. return
  158. }
  159. } else { // 企业
  160. companyBankCard4Req := APIReq[APICompanyBankCard4Req]{
  161. Data: APICompanyBankCard4Req{
  162. CompanyName: req.Company.CompanyName,
  163. CreditCode: req.Company.CreditCode,
  164. RealName: req.Company.RealName,
  165. IdCardNo: req.Company.IdCardNo,
  166. BankCard: req.Company.BankCard,
  167. Mobile: req.Company.Mobile,
  168. },
  169. }
  170. if bankCard4Rsp, err = APIPost[APICompanyBankCard4Req, APIBankCard4Rsp](companyBankCard4Req, APIURL_Person_BankCard4); err != nil {
  171. return
  172. }
  173. if authinfo, err = json.Marshal(req.Company); err != nil {
  174. return
  175. }
  176. }
  177. if bankCard4Rsp.Code != CODE_SUCCESS {
  178. err = errors.New(bankCard4Rsp.Msg)
  179. return
  180. }
  181. rsp.SerialNo = bankCard4Rsp.Data.SerialNo
  182. // 更新用户电子签记录-记录实名信息
  183. sql := fmt.Sprintf(`
  184. UPDATE useresignrecord
  185. SET RECORDSTATUS = 2,
  186. UPDATETIME = SYSDATE,
  187. AUTHINFO = '%v'
  188. WHERE USERID = %v AND TEMPLATETYPE = 1
  189. `, string(authinfo), req.UserId)
  190. _, err = db.GetEngine().Exec(sql)
  191. return
  192. }
  193. // CaptcaResend 重新发送认证验证码
  194. func CaptcaResend(req CaptchaResendReq) (err error) {
  195. apiReq := APIReq[APICaptchaResendReq]{Data: APICaptchaResendReq{SerialNo: req.SerialNo}}
  196. apiRsp, err := APIPost[APICaptchaResendReq, interface{}](apiReq, APIURL_Captcha_Resend)
  197. if err != nil {
  198. return
  199. }
  200. if apiRsp.Code != CODE_SUCCESS {
  201. err = errors.New(apiRsp.Msg)
  202. return
  203. }
  204. return
  205. }
  206. // CaptchaVerify 认证验证码校验
  207. func CaptchaVerify(req CaptchaVerifyReq) (err error) {
  208. // 从交易库中获取类型为实名认证的电子签信息
  209. var record models.Useresignrecord
  210. has, err := db.GetEngine().Where("TEMPLATETYPE = 1 AND RECORDSTATUS = 2 AND USERID = ?", req.UserId).Get(&record)
  211. if err != nil {
  212. return
  213. }
  214. if !has {
  215. err = errors.New("无对应实名认证记录信息")
  216. logger.GetLogger().Error("无对应实名认证记录信息, userId:", req.UserId)
  217. return
  218. }
  219. // 调用爱签接口 - 认证验证码校验
  220. apiReq := APIReq[APICaptchaVerifyReq]{
  221. Data: APICaptchaVerifyReq{
  222. SerialNo: req.SerialNo,
  223. Captcha: req.Captcha,
  224. },
  225. }
  226. apiRsp, err := APIPost[APICaptchaVerifyReq, interface{}](apiReq, APIURL_Captcha_Verify)
  227. if err != nil {
  228. return
  229. }
  230. if apiRsp.Code != CODE_SUCCESS {
  231. err = errors.New(apiRsp.Msg)
  232. return
  233. }
  234. // 调用爱签接口 - 添加用户
  235. var addUserRsp *APIRsp[APIAddUserRsp]
  236. if req.Type == 1 { // 个人
  237. addPersonalUserReq := APIReq[APIAddPersonalUserReq]{
  238. Data: APIAddPersonalUserReq{
  239. Account: strconv.Itoa(req.UserId),
  240. SerialNo: req.SerialNo,
  241. },
  242. }
  243. if addUserRsp, err = APIPost[APIAddPersonalUserReq, APIAddUserRsp](addPersonalUserReq, APIURL_V2_User_AddPersonalUser); err != nil {
  244. return
  245. }
  246. } else { // 企业
  247. addEnterpriseUserReq := APIReq[APIAddEnterpriseUserReq]{
  248. Data: APIAddEnterpriseUserReq{
  249. Account: strconv.Itoa(req.UserId),
  250. SerialNo: req.SerialNo,
  251. },
  252. }
  253. if addUserRsp, err = APIPost[APIAddEnterpriseUserReq, APIAddUserRsp](addEnterpriseUserReq, APIURL_V2_User_AddEnterpriseUser); err != nil {
  254. return
  255. }
  256. }
  257. if addUserRsp.Code != CODE_SUCCESS {
  258. err = errors.New(addUserRsp.Msg)
  259. return
  260. }
  261. // 获取临时存储的用户认证信息
  262. cacheMap := make(map[string]interface{})
  263. if err = json.Unmarshal([]byte(record.AUTHINFO), &cacheMap); err != nil {
  264. logger.GetLogger().Errorf("反序列化临时存储用户信息失败, AUTHINFO: %s", record.AUTHINFO)
  265. return
  266. }
  267. // 调用JAVA实名认证接口
  268. reqParam := make(map[string]interface{})
  269. if req.Type == 1 { // 个人
  270. reqParam["userid"] = req.UserId
  271. reqParam["cardnum"] = cacheMap["idCardNo"]
  272. reqParam["username"] = cacheMap["realName"]
  273. reqParam["cardtype"] = 0 // 目前写死证件类型为身份证 - 0
  274. reqParam["cardfrontphotourl"] = cacheMap["idCardPhoto"]
  275. reqParam["cardbackphotourl"] = cacheMap["idCardPhotoBackURL"]
  276. reqParam["bankaccount"] = cacheMap["bankCard"]
  277. reqParam["bankid"] = cacheMap["bankId"]
  278. reqParam["userinfotype"] = 1 // 1 - 个人
  279. } else {
  280. reqParam["userid"] = req.UserId
  281. reqParam["customername"] = cacheMap["companyName"]
  282. reqParam["cardtype"] = 4 // 企业统一信用
  283. reqParam["cardfrontphotourl"] = cacheMap["idCardPhoto"]
  284. reqParam["legalpersonname"] = cacheMap["realName"]
  285. reqParam["cardnum"] = cacheMap["creditCode"]
  286. reqParam["mobilephone"] = cacheMap["mobile"]
  287. reqParam["userinfotype"] = 2 // 2 - 企业
  288. }
  289. jsonParam, err := json.Marshal(&reqParam)
  290. if err != nil {
  291. logger.GetLogger().Error("反序列化JAVA实名认证入参失败, reqParam:", reqParam)
  292. return
  293. }
  294. // 构建请求
  295. javaUrl := config.SerCfg.AsignCfg.OpenApiUrl + "/onlineopen/userInfo/addAuth"
  296. javaReq, err := http.NewRequest("POST", javaUrl, bytes.NewReader(jsonParam))
  297. // 设置请求头
  298. javaReq.Header.Set("Content-Type", "application/json; charset=utf-8")
  299. client := &http.Client{}
  300. rsp, err := client.Do(javaReq)
  301. if err != nil {
  302. logger.GetLogger().Error("JAVA实名认证请求失败, err:", err)
  303. return
  304. }
  305. defer rsp.Body.Close()
  306. body, err := io.ReadAll(rsp.Body)
  307. if err != nil {
  308. logger.GetLogger().Error("JAVA实名认证请求获取body失败, err:", err)
  309. return
  310. }
  311. // rspData: map[code:0 hasAuth:1 message:认证成功]
  312. rspData := make(map[string]interface{})
  313. if err = json.Unmarshal(body, &rspData); err != nil {
  314. logger.GetLogger().Error("JAVA实名认证请求反序列化body失败, err:", err)
  315. return
  316. }
  317. logger.GetLogger().Info("调用JAVA实名认证接口返回, rspData:", rspData)
  318. code, ok := rspData["code"]
  319. if !ok {
  320. err = errors.New("实名认证失败,请稍后重试")
  321. logger.GetLogger().Error(err.Error())
  322. return
  323. }
  324. if code != "0" {
  325. err = fmt.Errorf("实名认证失败,%v", rspData["message"])
  326. logger.GetLogger().Error(err.Error())
  327. return
  328. }
  329. // 更新用户电子签记录 - 更新实名认证状态
  330. sql := fmt.Sprintf(`
  331. UPDATE useresignrecord
  332. SET RECORDSTATUS = 3,
  333. UPDATETIME = SYSDATE
  334. WHERE USERID = %v AND TEMPLATETYPE = 1
  335. `, req.UserId)
  336. _, err = db.GetEngine().Exec(sql)
  337. return
  338. }
  339. // SyncContractStatus 同步合同状态
  340. func SyncContractStatus(req SyncContractStatusReq) (rsp SyncContractStatusRsp, err error) {
  341. // 从交易库中获取类型为实名认证的电子签信息
  342. var record models.Useresignrecord
  343. has, err := db.GetEngine().Where("RECORDID = ?", req.RecordId).Get(&record)
  344. if err != nil {
  345. return
  346. }
  347. if !has {
  348. err = errors.New("查无此记录信息")
  349. logger.GetLogger().Error("查无此记录信息, RecordId:", req.RecordId)
  350. return
  351. }
  352. if record.CONTRACTNO == "" {
  353. err = errors.New("此记录未生成合同编号")
  354. logger.GetLogger().Error("此记录未生成合同编号, RecordId:", req.RecordId)
  355. return
  356. }
  357. // 调用爱签接口 - 查询合同状态
  358. apiReq := APIReq[APIContractStatusReq]{Data: APIContractStatusReq{ContractNo: record.CONTRACTNO}}
  359. apiRsp, err := APIPost[APIContractStatusReq, APIContractStatusRsp](apiReq, APIURL_Contract_Status)
  360. if err != nil {
  361. return
  362. }
  363. if apiRsp.Code != CODE_SUCCESS {
  364. err = errors.New(apiRsp.Msg)
  365. return
  366. }
  367. status := record.RECORDSTATUS // 记录状态: 1:未签署 2:签署中 3:已签署 4:签署拒绝
  368. switch apiRsp.Data.Status { // 合同状态:0:等待签约 1:签约中 2:已签约 3:过期 4:拒签 6:作废 -2:状态异常
  369. case 0:
  370. status = 1
  371. case 1:
  372. status = 2
  373. case 2:
  374. status = 3
  375. case 4:
  376. status = 4
  377. }
  378. // 更新用户电子签记录 - 更新合同签署状态
  379. sql := fmt.Sprintf(`
  380. UPDATE useresignrecord
  381. SET RECORDSTATUS = %v,
  382. UPDATETIME = SYSDATE
  383. WHERE RECORDID = %v
  384. `, status, req.RecordId)
  385. _, err = db.GetEngine().Exec(sql)
  386. if err != nil {
  387. return
  388. }
  389. rsp = SyncContractStatusRsp{
  390. ContractNo: apiRsp.Data.ContractNo,
  391. ContractName: apiRsp.Data.ContractName,
  392. Status: apiRsp.Data.Status,
  393. }
  394. return
  395. }
  396. // PARTYA_SIGNATURE
  397. // PARTYA_DATE
  398. //
  399. // P_PARTYB_SIGNATURE
  400. // P_PARTYB_ID
  401. // P_PARTYB_MOBILE
  402. // P_PARTYB_DATE
  403. //
  404. // E_PARTYB_SIGNATURE
  405. // E_PARTYB_LEGAL
  406. // E_PARTYB_DATE
  407. // CreateContract 创建合同
  408. func CreateContract(req CreateContractReq) (rsp CreateContractRsp, err error) {
  409. // 获取电子签信息
  410. var record models.Useresignrecord
  411. has, err := db.GetEngine().Where("RECORDID = ?", req.RecordId).Get(&record)
  412. if err != nil {
  413. logger.GetLogger().Error("获取电子签信息失败, err", err)
  414. err = errors.New("获取电子签信息失败")
  415. return
  416. }
  417. if !has {
  418. err = errors.New("查无此记录信息")
  419. logger.GetLogger().Error("查无此记录信息, RecordId:", req.RecordId)
  420. return
  421. }
  422. if record.RECORDSTATUS != 1 {
  423. err = errors.New("记录信息状态异常")
  424. logger.GetLogger().Error("记录信息状态异常, RecordId:", req.RecordId, record.RECORDSTATUS)
  425. return
  426. }
  427. // 调用爱签接口 - 查询模板列表
  428. apiReq := APIReq[APITemplateListReq]{Data: APITemplateListReq{Page: 1, Rows: 10}}
  429. apiRsp, err := APIPost[APITemplateListReq, APITemplateListRsp](apiReq, APIURL_Template_List)
  430. if err != nil {
  431. return
  432. }
  433. if apiRsp.Code != CODE_SUCCESS {
  434. err = errors.New(apiRsp.Msg)
  435. return
  436. }
  437. if len(apiRsp.Data.List) == 0 {
  438. err = errors.New("获取查询模板列表失败")
  439. logger.GetLogger().Error("获取查询模板列表失败")
  440. return
  441. }
  442. // 获取用户信息
  443. userInfo, err := models.GetUserInfo(int(record.USERID))
  444. if err != nil {
  445. logger.GetLogger().Error("获取用户信息失败, err:", err)
  446. err = errors.New("获取用户信息失败")
  447. return
  448. }
  449. templateName := record.TEMPLATENAME
  450. if userInfo.Userinfotype == 1 { // 个人
  451. templateName += "-个人"
  452. } else { // 企业
  453. templateName += "-企业"
  454. }
  455. // 获取模板信息
  456. templateIdent := ""
  457. for _, item := range apiRsp.Data.List {
  458. if item.TemplateName == templateName {
  459. templateIdent = item.TemplateIdent
  460. break
  461. }
  462. }
  463. if templateIdent == "" {
  464. err = errors.New("获取模板信息失败")
  465. logger.GetLogger().Error("获取模板信息失败")
  466. return
  467. }
  468. // 获取用户实名信息
  469. var recordAuth models.Useresignrecord
  470. has, err = db.GetEngine().Where("TEMPLATETYPE = 1 AND USERID = ?", userInfo.Userid).Get(&recordAuth)
  471. if err != nil {
  472. return
  473. }
  474. if !has {
  475. err = errors.New("无对应实名认证记录信息")
  476. logger.GetLogger().Error("无对应实名认证记录信息, userId:", userInfo.Userid)
  477. return
  478. }
  479. // 调用爱签接口 - 上传待签署文件
  480. contractNo := strconv.Itoa(int(utils.GenID()))
  481. apiCreateContractReq := APIReq[APICreateContractReq]{
  482. Data: APICreateContractReq{
  483. ContractNo: contractNo,
  484. ContractName: templateName,
  485. SignOrder: 1,
  486. ValidityTime: 30,
  487. NotifyUrl: config.SerCfg.AsignCfg.NotifyUrl,
  488. },
  489. }
  490. apiCreateContractReq.Data.Templates = []APITemplate{
  491. {
  492. TemplateNo: templateIdent,
  493. },
  494. }
  495. apiCreateContractRsp, err := APIPost[APICreateContractReq, APICreateContractRsp](apiCreateContractReq, APIURL_CreateContract)
  496. if err != nil {
  497. return
  498. }
  499. if apiCreateContractRsp.Code != CODE_SUCCESS {
  500. err = errors.New(apiCreateContractRsp.Msg)
  501. return
  502. }
  503. // 将合同编号写入数据库
  504. sql := fmt.Sprintf(`
  505. UPDATE useresignrecord
  506. SET contractNo = '%v',
  507. UPDATETIME = SYSDATE
  508. WHERE RECORDID = %v
  509. `, contractNo, record.RECORDID)
  510. if _, err = db.GetEngine().Exec(sql); err != nil {
  511. logger.GetLogger().Error("更新合同编号失败, err:", err)
  512. err = errors.New("更新合同编号失败")
  513. return
  514. }
  515. // 添加签署方 - 甲方 - 交易所
  516. // appAddSignerReq1 := APIAddSignerReq{
  517. // ContractNo: contractNo,
  518. // Account: "ZR_LEGAL",
  519. // SignType: 2, // 无感知签约(需要开通权限)
  520. // SignStrategyList: []APISignStrategy{
  521. // {AttachNo: 1, LocationMode: 4, SignKey: "PARTYA_SIGNATURE", SignType: 1}, // 甲方签章
  522. // {AttachNo: 1, LocationMode: 4, SignKey: "PARTYA_DATE", SignType: 2}, // 甲方签署时间
  523. // },
  524. // }
  525. appAddSignerReq1 := APIAddSignerReq{
  526. ContractNo: contractNo,
  527. Account: "EX_LEGAL",
  528. SignType: 2, // 无感知签约(需要开通权限)
  529. }
  530. signStrategyListPartyA, err := buildStrategyByPartyA(int(record.TEMPLATECONFIGID))
  531. if err != nil {
  532. return
  533. }
  534. if len(signStrategyListPartyA) > 0 {
  535. appAddSignerReq1.SignStrategyList = signStrategyListPartyA
  536. }
  537. // 获取临时存储的用户认证信息
  538. cacheMap := make(map[string]interface{})
  539. if err = json.Unmarshal([]byte(recordAuth.AUTHINFO), &cacheMap); err != nil {
  540. logger.GetLogger().Errorf("反序列化临时存储用户信息失败, AUTHINFO: %s", recordAuth.AUTHINFO)
  541. return
  542. }
  543. if recordAuth.AUTHINFO == "" {
  544. err = errors.New("获取实名信息失败")
  545. logger.GetLogger().Error("获取实名信息失败")
  546. return
  547. }
  548. // 添加签署方 - 乙方 - 投资者
  549. appAddSignerReq2 := APIAddSignerReq{
  550. ContractNo: contractNo,
  551. Account: strconv.Itoa(int(record.USERID)),
  552. SignType: 3,
  553. ValidateType: 3,
  554. }
  555. // // 签章策略
  556. // signStrategyList := make([]APISignStrategy, 0)
  557. // // 接收方模板填充策略
  558. // receiverFillStrategyList := make([]APIReceiverFillStrategy, 0)
  559. // if userInfo.Userinfotype == 1 { // 个人
  560. // // 乙方签章
  561. // signStrategyList = append(signStrategyList, APISignStrategy{AttachNo: 1, LocationMode: 4, SignKey: "P_PARTYB_SIGNATURE", SignType: 1})
  562. // // 乙方签署时间
  563. // signStrategyList = append(signStrategyList, APISignStrategy{AttachNo: 1, LocationMode: 4, SignKey: "P_PARTYB_DATE", SignType: 2})
  564. // // 身份证号
  565. // receiverFillStrategyList = append(receiverFillStrategyList, APIReceiverFillStrategy{AttachNo: 1, Key: "P_PARTYB_ID", Value: cacheMap["idCardNo"].(string)})
  566. // // 联系方式
  567. // receiverFillStrategyList = append(receiverFillStrategyList, APIReceiverFillStrategy{AttachNo: 1, Key: "P_PARTYB_MOBILE", Value: cacheMap["mobile"].(string)})
  568. // } else { // 企业
  569. // // 乙方签章
  570. // signStrategyList = append(signStrategyList, APISignStrategy{AttachNo: 1, LocationMode: 4, SignKey: "E_PARTYB_SIGNATURE", SignType: 1})
  571. // // 乙方签署时间
  572. // signStrategyList = append(signStrategyList, APISignStrategy{AttachNo: 1, LocationMode: 4, SignKey: "E_PARTYB_DATE", SignType: 2})
  573. // // 法定代表人名称
  574. // receiverFillStrategyList = append(receiverFillStrategyList, APIReceiverFillStrategy{AttachNo: 1, Key: "E_PARTYB_LEGAL", Value: cacheMap["realName"].(string)})
  575. // }
  576. // appAddSignerReq2.SignStrategyList = signStrategyList
  577. // appAddSignerReq2.ReceiverFillStrategyList = receiverFillStrategyList
  578. signStrategyList, receiverFillStrategyList, err := buildStrategyByPartyB(int(record.TEMPLATECONFIGID), int(userInfo.Userinfotype), cacheMap)
  579. if err != nil {
  580. return
  581. }
  582. if len(signStrategyList) > 0 {
  583. appAddSignerReq2.SignStrategyList = signStrategyList
  584. }
  585. if len(receiverFillStrategyList) > 0 {
  586. appAddSignerReq2.ReceiverFillStrategyList = receiverFillStrategyList
  587. }
  588. apiAddSignerReq := APIReq[APIAddSignerReq]{Datas: []APIAddSignerReq{appAddSignerReq1, appAddSignerReq2}}
  589. apiAddSignerRsp, err := APIPost[APIAddSignerReq, APIAddSignerRsp](apiAddSignerReq, APIURL_AddSigner)
  590. if err != nil {
  591. return
  592. }
  593. if apiAddSignerRsp.Code != CODE_SUCCESS {
  594. err = errors.New(apiAddSignerRsp.Msg)
  595. return
  596. }
  597. if len(apiAddSignerRsp.Data.SignUser) == 0 {
  598. err = errors.New("获取合同签署地址失败")
  599. logger.GetLogger().Error("获取合同签署地址失败")
  600. return
  601. }
  602. // 将返回的合同签署地址写入数据库
  603. sql = fmt.Sprintf(`
  604. UPDATE useresignrecord
  605. SET RECORDSTATUS = 2,
  606. SIGNURL = '%v',
  607. UPDATETIME = SYSDATE
  608. WHERE RECORDID = %v
  609. `, apiAddSignerRsp.Data.SignUser[0].SignUrl, record.RECORDID)
  610. if _, err = db.GetEngine().Exec(sql); err != nil {
  611. logger.GetLogger().Error("合同签署地址失败, err:", err)
  612. err = errors.New("合同签署地址失败")
  613. return
  614. }
  615. rsp = CreateContractRsp{SignUrl: apiAddSignerRsp.Data.SignUser[0].SignUrl}
  616. return
  617. }
  618. // 构建甲方签章策略
  619. func buildStrategyByPartyA(templateConfigId int) (signStrategyList []APISignStrategy, err error) {
  620. signStrategyList = make([]APISignStrategy, 0)
  621. // 获取电子签模板字段配置
  622. fields := make([]models.Esigntemplatefield, 0)
  623. if err = db.GetEngine().Where("TEMPLATECONFIGID = ?", templateConfigId).Find(&fields); err != nil {
  624. logger.GetLogger().Error("获取电子签模板字段配置失败, err", err)
  625. err = errors.New("获取电子签模板字段配置失败")
  626. return
  627. }
  628. if len(fields) == 0 {
  629. err = errors.New("获取电子签模板字段配置信息异常")
  630. logger.GetLogger().Error("获取电子签模板字段配置异常, templateconfigid:", templateConfigId)
  631. return
  632. }
  633. for _, item := range fields {
  634. switch item.FIELDKEY {
  635. case "PARTYA_SIGNATURE": // 甲方签章(企业印章)
  636. signStrategyList = append(signStrategyList, APISignStrategy{AttachNo: 1, LocationMode: 4, SignKey: "PARTYA_SIGNATURE", SignType: 1})
  637. case "PARTYA_DATE": // 甲方签署时间
  638. signStrategyList = append(signStrategyList, APISignStrategy{AttachNo: 1, LocationMode: 4, SignKey: "PARTYA_DATE", SignType: 2})
  639. }
  640. }
  641. return
  642. }
  643. // cacheMap {"realName":"邓志明","idCardNo":"430426198507087670","bankCard":"6221885840097492396","mobile":"18033442829","idCardPhoto":"./uploadFile/20231227/202312271427518530.jpg","idCardPhotoBackURL":"./uploadFile/20231227/202312271427544764.jpg","bankId":"403100000004"}
  644. // 构建乙方签章策略和模板填充策略
  645. func buildStrategyByPartyB(templateConfigId int, fieldUserType int, cacheMap map[string]interface{}) (signStrategyList []APISignStrategy, receiverFillStrategyList []APIReceiverFillStrategy, err error) {
  646. signStrategyList = make([]APISignStrategy, 0)
  647. receiverFillStrategyList = make([]APIReceiverFillStrategy, 0)
  648. // 获取电子签模板字段配置
  649. fields := make([]models.Esigntemplatefield, 0)
  650. if err = db.GetEngine().Where("TEMPLATECONFIGID = ? AND FIELDUSERTYPE = ?", templateConfigId, fieldUserType).Find(&fields); err != nil {
  651. logger.GetLogger().Error("获取电子签模板字段配置失败, err", err)
  652. err = errors.New("获取电子签模板字段配置失败")
  653. return
  654. }
  655. if len(fields) == 0 {
  656. err = errors.New("获取电子签模板字段配置信息异常")
  657. logger.GetLogger().Error("获取电子签模板字段配置异常, templateconfigid:", templateConfigId)
  658. return
  659. }
  660. for _, item := range fields {
  661. switch item.FIELDKEY {
  662. case "P_PARTYB_NAME": // 乙方名称
  663. receiverFillStrategyList = append(receiverFillStrategyList, APIReceiverFillStrategy{AttachNo: 1, Key: "P_PARTYB_NAME", Value: cacheMap["realName"].(string)})
  664. case "P_PARTYB_ID": // 乙方证件号码
  665. receiverFillStrategyList = append(receiverFillStrategyList, APIReceiverFillStrategy{AttachNo: 1, Key: "P_PARTYB_ID", Value: cacheMap["idCardNo"].(string)})
  666. case "P_PARTYB_MOBILE": // 乙方电话号码
  667. receiverFillStrategyList = append(receiverFillStrategyList, APIReceiverFillStrategy{AttachNo: 1, Key: "P_PARTYB_MOBILE", Value: cacheMap["mobile"].(string)})
  668. case "P_PARTYB_SIGNATURE": // 乙方签章(个人)
  669. signStrategyList = append(signStrategyList, APISignStrategy{AttachNo: 1, LocationMode: 4, SignKey: "P_PARTYB_SIGNATURE", SignType: 1})
  670. case "P_PARTYB_DATE": // 乙方签署时间
  671. signStrategyList = append(signStrategyList, APISignStrategy{AttachNo: 1, LocationMode: 4, SignKey: "P_PARTYB_DATE", SignType: 2})
  672. }
  673. }
  674. return
  675. }
  676. func ASignCompleted(contractNo, status string) (err error) {
  677. /*
  678. // 合同签署完成后回调通知示例
  679. String publickey = "MFwwDQcccccxxxxmEz/nw27Ln6AP90ZCMPi+iNF1m9mhNECAwEAAQ==";
  680. String remark = ""; // 若被拒签则会返回拒签原因,拒签原因不参与签名
  681. Map <String, String> map = new HashMap<>();
  682. map.put("action", "signCompleted");
  683. map.put("contractNo", "20221114142140345");
  684. map.put("status", "2");
  685. map.put("signTime", "2022-11-14 14:22:00");
  686. map.put("timestamp", "1668406920005");
  687. map.put("validityTime", "2022-11-24 23:59:59");
  688. String json = JSONObject.toJSONString(map, SerializerFeature.MapSortField);
  689. System.out.println("数据:" + json);
  690. // 计算签名
  691. try {
  692. String sign = "feFfcprGjdmDDqRmxK5qlWlMncX0mc6LJ5agebOGIx2QiAern+6ZRg/SBHOgvHp/+1ywVRdyKNUKxPneETwKPw==";
  693. System.out.println(RSAUtils.rsaSignCheck(sign, json, publickey));
  694. } catch (Exception e) {
  695. e.printStackTrace();
  696. }
  697. */
  698. // 获取合同编号
  699. if contractNo == "" {
  700. logger.GetLogger().Error("获取合同编号失败")
  701. err = errors.New("获取合同编号失败")
  702. return
  703. }
  704. // 获取合同状态
  705. if status == "" {
  706. logger.GetLogger().Error("获取获取合同状态失败")
  707. err = errors.New("获取获取合同状态失败")
  708. return
  709. }
  710. // 更新数据库记录
  711. sql := fmt.Sprintf(`
  712. UPDATE useresignrecord
  713. SET RECORDSTATUS = 3,
  714. UPDATETIME = SYSDATE
  715. WHERE CONTRACTNO = '%v'
  716. `, contractNo)
  717. _, err = db.GetEngine().Exec(sql)
  718. return
  719. }