servcies.go 27 KB

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