package sign import ( "encoding/json" "errors" "fmt" "mtp20access/global" "mtp20access/model/account" "mtp20access/model/account/request" "mtp20access/model/account/response" "mtp20access/service/asign" "os" "strconv" "time" "github.com/gofrs/uuid" "go.uber.org/zap" ) // QueryUserESignRecord 查询用户电子签记录表 func QueryUserESignRecord(userId int) (rsp []account.Useresignrecord, err error) { rsp = make([]account.Useresignrecord, 0) err = global.M2A_DB.Where("USERID = ?", userId).Find(&rsp) return } // AddUser 添加用户 func AddUser(req request.AddUserReq, userId int) (err error) { // 获取用户电子签记录 useresignrecord := new(account.Useresignrecord) has, _ := global.M2A_DB.Where("USERID = ? AND TEMPLATETYPE = 1 AND RECORDSTATUS = 3", userId).Get(useresignrecord) if has { err = errors.New("用户已同步") return } // 调用爱签API-添加个人用户(https://{host}/user/addPersonalUser) rsp, err := asign.AddPersonalUserBy( strconv.Itoa(userId), req.Name, req.IdCard, req.Mobile, req.IdCardType, ) if err != nil { return } if rsp.Code != 100000 { err = errors.New(strconv.Itoa(rsp.Code)) global.M2A_LOG.Error("【AddUser】 接口调用失败", zap.Error(err)) return } // 更新用户电子签记录-实名认证状态 authinfo, err := json.Marshal(req) if err != nil { global.M2A_LOG.Error("【AddUser】 构建AUTHINFO失败", zap.Error(err)) return } sql := fmt.Sprintf(` UPDATE useresignrecord SET RECORDSTATUS = 3, UPDATETIME = SYSDATE, AUTHINFO = '%v' WHERE USERID = %v AND TEMPLATETYPE = 1 `, string(authinfo), userId) if _, err = global.M2A_DB.Exec(sql); err != nil { global.M2A_LOG.Error("【AddUser】 更新用户电子签记录失败", zap.Error(err)) return } return } // CreateContractAndAddSigner 上传待签署文件和添加签署方 func CreateContractAndAddSigner(req request.CreateContractAndAddSignerReq, userId int) (rsp response.CreateContractAndAddSignerRsp, err error) { // 获取用户电子签记录 useresignrecord := new(account.Useresignrecord) has, err := global.M2A_DB.Where("USERID = ? AND TEMPLATENO = ?", userId, req.TemplateNo).Get(useresignrecord) if err != nil || !has { global.M2A_LOG.Error("【CreateContractAndAddSigner】 获取用户电子签记录失败", zap.Error(err)) return } // 判断是否需要创建合同(上传待签署文件) if useresignrecord.CONTRACTNO == "" { // 生成合同编号 // #{userid} || '_' || to_char(sysdate, 'yyyyMMddhh24miss') || '_' || seq_useresignrecord.currval, contractNo := fmt.Sprintf("%d_%s_%v", userId, time.Now().Format("20060102150405"), useresignrecord.RECORDID) // 调用爱签API-上传待签署文件(https://{host}/contract/createContract) r, e := asign.CreateContract( contractNo, useresignrecord.TEMPLATENAME, useresignrecord.TEMPLATENO, ) if e != nil { err = e return } if r.Code != 100000 { err = errors.New(strconv.Itoa(r.Code)) global.M2A_LOG.Error("【CreateContractAndAddSigner】 上传待签署文件接口调用失败", zap.Error(err)) return } // 将返回的合同编号写入数据库 useresignrecord.CONTRACTNO = contractNo sql := fmt.Sprintf(` UPDATE useresignrecord SET contractNo = '%v', UPDATETIME = SYSDATE WHERE RECORDID = %v `, useresignrecord.CONTRACTNO, useresignrecord.RECORDID) if _, err = global.M2A_DB.Exec(sql); err != nil { global.M2A_LOG.Error("【CreateContractAndAddSigner】 写入合同编号失败", zap.Error(err)) return } } // 判断是否需要添加签署方(获取合同签约地址) if useresignrecord.SIGNURL != "" { err = errors.New("合同签署链接已存在") } else { // 调用爱签API-添加签署方(https://{host}/contract/addSigner) r, e := asign.AddSigner( useresignrecord.CONTRACTNO, strconv.Itoa(userId), ) if e != nil { err = e return } if r.Code != 100000 { err = errors.New(strconv.Itoa(r.Code)) global.M2A_LOG.Error("【CreateContractAndAddSigner】 添加签署方接口调用失败", zap.Error(err)) return } if len(r.Data.SignUser) > 0 { useresignrecord.SIGNURL = r.Data.SignUser[0].SignUrl // 将返回的合同编号写入数据库 sql := fmt.Sprintf(` UPDATE useresignrecord SET SIGNURL = '%v', UPDATETIME = SYSDATE WHERE RECORDID = %v `, useresignrecord.SIGNURL, useresignrecord.RECORDID) if _, err = global.M2A_DB.Exec(sql); err != nil { global.M2A_LOG.Error("【CreateContractAndAddSigner】 写入合同签署链接失败", zap.Error(err)) return } // 给客户端返回合同签署地址 rsp.SignUrl = useresignrecord.SIGNURL } } return } // SignCompleted func SignCompleted(userId int) (err error) { // 获取用户电子签记录 datas := make([]account.Useresignrecord, 0) err = global.M2A_DB.Where("USERID = ?", userId).Find(&datas) if err != nil { global.M2A_LOG.Error("SignCompleted 获取用户电子签记录失败", zap.Error(err)) return } for _, item := range datas { if item.RECORDSTATUS != 3 { err = errors.New("未完成所有合同签署") return } } return } /* handleASignCompleted 处理爱签合同签署完成后回调通知 req 异步推送参数 */ func HandleASignCompleted(req request.HandleASignCompletedReq) (err error) { /* // 合同签署完成后回调通知示例 String publickey = "MFwwDQcccccxxxxmEz/nw27Ln6AP90ZCMPi+iNF1m9mhNECAwEAAQ=="; String remark = ""; // 若被拒签则会返回拒签原因,拒签原因不参与签名 Map map = new HashMap<>(); map.put("action", "signCompleted"); map.put("contractNo", "20221114142140345"); map.put("status", "2"); map.put("signTime", "2022-11-14 14:22:00"); map.put("timestamp", "1668406920005"); map.put("validityTime", "2022-11-24 23:59:59"); String json = JSONObject.toJSONString(map, SerializerFeature.MapSortField); System.out.println("数据:" + json); // 计算签名 try { String sign = "feFfcprGjdmDDqRmxK5qlWlMncX0mc6LJ5agebOGIx2QiAern+6ZRg/SBHOgvHp/+1ywVRdyKNUKxPneETwKPw=="; System.out.println(RSAUtils.rsaSignCheck(sign, json, publickey)); } catch (Exception e) { e.printStackTrace(); } */ // 获取合同编号 if req.ContractNo == "" { global.M2A_LOG.Error("【HandleASignCompleted】 获取合同编号失败", zap.Any("req", req)) return } // 获取合同状态 if req.Status == "" { global.M2A_LOG.Error("【HandleASignCompleted】 获取获取合同状态失败", zap.Any("req", req)) return } if req.Status == "2" { // 已签约 // 下载合同 r, e := asign.DownloadContract(req.ContractNo) if e != nil { err = e return } if r.Code != 100000 { err = errors.New(strconv.Itoa(r.Code)) global.M2A_LOG.Error("【HandleASignCompleted】 下载合同接口调用失败", zap.Error(err)) return } if r.Data.Data != "" { // 获取网上开户地址(用于客户端下载文件) openconfig := account.Wskhopenaccountconfig{CONFIGID: 6} has, e := openconfig.Get() if e != nil || !has { err = e global.M2A_LOG.Error("【HandleASignCompleted】 获取网上开户地址失败", zap.Error(err)) return } // 将Base64写入目标文件 uid, _ := uuid.NewV4() fileName := fmt.Sprintf("%v_%v.pdf", r.Data.FileName, uid.String()) openconfig.CONFIGVALUE = "./" // FIXME: - 测试代码 folderPath := "sign/" + time.Now().Format("20060102") savePath := openconfig.CONFIGVALUE + "/uploadFile/" + folderPath fmt.Println(savePath + "/" + fileName) f, e := os.OpenFile(savePath+"/"+fileName, os.O_RDWR|os.O_CREATE, os.ModePerm) if e != nil { err = e global.M2A_LOG.Error("【HandleASignCompleted】 获取网上开户地址失败", zap.Error(err)) return } defer f.Close() // 更新数据库记录 // 获取用户电子签记录 // useresignrecord := new(account.Useresignrecord) // has, e = global.M2A_DB.Where("CONTRACTNO = ?", req.ContractNo).Get(useresignrecord) // if e != nil || !has { // err = e // global.M2A_LOG.Error("【HandleASignCompleted】 获取用户电子签记录失败", zap.Error(err)) // return // } contractfileaddr := fmt.Sprintf("./uploadFile/%v/%v", folderPath, fileName) sql := fmt.Sprintf(` UPDATE useresignrecord SET RECORDSTATUS = 3, UPDATETIME = SYSDATE, CONTRACTFILEADDR = '%v' WHERE CONTRACTNO = %v `, contractfileaddr, req.ContractNo) if _, err = global.M2A_DB.Exec(sql); err != nil { global.M2A_LOG.Error("【HandleASignCompleted】 更新用户电子签记录失败", zap.Error(err)) return } } } return }