Bläddra i källkod

修改分时图查询开休市计划BUG

zhou.xiaoning 1 år sedan
förälder
incheckning
b6d2829ca5
9 ändrade filer med 198 tillägg och 37 borttagningar
  1. 0 12
      config/config.go
  2. 6 14
      config/config.xml
  3. 11 3
      config/readme.md
  4. 2 1
      go.mod
  5. 2 0
      go.sum
  6. 1 1
      models/market.go
  7. 54 0
      services/asign/api.go
  8. 54 6
      services/asign/http.go
  9. 68 0
      services/asign/models.go

+ 0 - 12
config/config.go

@@ -73,7 +73,6 @@ type TencentConfig struct {
 }
 
 type AsignConfig struct {
-	Enabled    int
 	Url        string
 	AppId      string
 	PrivateKey string
@@ -444,17 +443,6 @@ func (c *ServiceConfig) Init(path string) error {
 	// 爱签配置
 	// asignsettings := root.SelectElements("Asign")
 	// for _, setting := range asignsettings {
-	// 	// 启用标志
-	// 	enabled := setting.SelectElement("Enabled")
-	// 	if enabled == nil {
-	// 		return errors.New("read asign enabled failed")
-	// 	}
-	// 	ret, err := strconv.ParseUint(enabled.SelectAttrValue("value", "0"), 10, 32)
-	// 	if err != nil {
-	// 		return errors.New("read asign enabled failed")
-	// 	}
-	// 	SerCfg.AsignCfg.Enabled = int(ret)
-
 	// 	// url
 	// 	url := setting.SelectElement("Url")
 	// 	if url == nil {

+ 6 - 14
config/config.xml

@@ -13,11 +13,11 @@
     <DbAddress value="192.168.31.88"/>
     <DbName value="orcl"/>
     <DbPort value="1521"/>
-    <DbUser value="mtp2_test171"/>
+    <DbUser value="mtp2_test204"/>
     <DbPwd value="muchinfo"/>
   </DbSetting>
   <RedisSetting>
-    <Address value="192.168.31.171"/>
+    <Address value="192.168.31.204"/>
     <Port value="5007"/>
     <Timeout value="3"/>
     <ConnNum value="1"/>
@@ -25,11 +25,11 @@
     <Pwd value=""/>
   </RedisSetting>
   <MqSetting>
-    <Url value="amqp://guest:guest@192.168.31.171:5020/test"/>
+    <Url value="amqp://guest:guest@192.168.31.204:5020/test"/>
     <Exchange value="entry"/>
   </MqSetting>
   <MongoDBSetting>
-    <HostName value="192.168.31.171"/>
+    <HostName value="192.168.31.204"/>
     <Port value="5025"/>
     <DBName value="HistoryQuote"/>
     <Username value="quote_test01"/>
@@ -38,8 +38,8 @@
   <MySQLSetting>
     <Host value="192.168.30.72"/>
     <Port value="3306"/>
-    <DBName value="historyquote_test171"/>
-    <Username value="quote_test171"/>
+    <DBName value="historyquote_test204"/>
+    <Username value="quote_test204"/>
     <Password value="123456"/>
   </MySQLSetting>
   <Tencent>
@@ -54,12 +54,4 @@
     <SignToken value="D586D270A51448179277A11729F37D3E"/>
     <SignKey value="8774F484EA294C1E829EA6E2D7F99123"/>
   </Tencent>
-  <Asign>
-    <Enabled value="1"/>
-    <Url value="https://prev.asign.cn/"/>
-    <AppId value="290912417"/>
-    <PrivateKey value="MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEAkMD+72J6iAF0ZNV+3t628lsRHfJ80nKZWK5/C7Pg+AZmOIzJlwHsKhRzCvxoxqYHQprhiFzW9l73v9vD9l1JYwIDAQABAkBVijccr01JYdKuY5t9iI8D2NzcnZc1pZMI3NUmzT18Uyg7b9CUvGHlLeg/gdT4QtVd7wIzHYCY4letEcEMh54BAiEAwzNWusj5XiLmty7PI0Hbakx4HtcND1+P0UHLEWqWOuECIQC91zQuL7nStgGzT3HvaeBB5Ouapa39fHRm2nCjHaxwwwIgRR2XdvmUOj23XWMomr5F14SN/7V7fVcD0D8wjNElsmECIDYavV5kb7tj7/wgqkInlKhzC8rZaUsTS0F9BBkY/eptAiAQJ8Saz8YlMIESdHMxANGSog01fECbcZqLFMuNf8SorA=="/>
-    <NotifyUrl value="http://218.17.158.45:15105/api/Account/HandleASignCompleted"/>
-    <OpenApiUrl value="http://192.168.31.202:5015/mtp2-onlineopen"/>
-  </Asign>
 </Configuration>

+ 11 - 3
config/readme.md

@@ -61,15 +61,23 @@ SignKey 腾讯电子签密回调通知密钥,用于解密,使用公司账号
 
 多元测试环境:
 <Asign>
-  <Enabled value="1"/>
-  <Url value="https://prev.asign.cn/"/>
+  <Url value="https://prev.asign.cn"/>
   <AppId value="290912417"/>
   <PrivateKey value="MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEAkMD+72J6iAF0ZNV+3t628lsRHfJ80nKZWK5/C7Pg+AZmOIzJlwHsKhRzCvxoxqYHQprhiFzW9l73v9vD9l1JYwIDAQABAkBVijccr01JYdKuY5t9iI8D2NzcnZc1pZMI3NUmzT18Uyg7b9CUvGHlLeg/gdT4QtVd7wIzHYCY4letEcEMh54BAiEAwzNWusj5XiLmty7PI0Hbakx4HtcND1+P0UHLEWqWOuECIQC91zQuL7nStgGzT3HvaeBB5Ouapa39fHRm2nCjHaxwwwIgRR2XdvmUOj23XWMomr5F14SN/7V7fVcD0D8wjNElsmECIDYavV5kb7tj7/wgqkInlKhzC8rZaUsTS0F9BBkY/eptAiAQJ8Saz8YlMIESdHMxANGSog01fECbcZqLFMuNf8SorA=="/>
   <NotifyUrl value="http://218.17.158.45:15105/api/Account/HandleASignCompleted"/>
   <OpenApiUrl value="http://192.168.31.202:5015/mtp2-onlineopen"/>
 </Asign>
 
-url: 'https://prev.asign.cn/' # 测试环境 - https://prev.asign.cn/  正式环境 - https://oapi.asign.cn/
+中融测试环境:
+<Asign>
+  <Url value="https://prev.asign.cn"/>
+  <AppId value="896210645"/>
+  <PrivateKey value="MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCqmByEbXbqqq+FYxD1+mJzqrVxG/7xNF3iZJV9q0PqOVwWPEtND8nNuB2FeAwHc5+W7dZwXheVaQqWXvV6lnWp3KaQ9S4CbeOX7zKKF0j42JMj4Adknid9X6OlULZeVoXcQsdQ2h9xpfJhwLka4aOX5p1eP6WocXMrkAVRXEA8aNAlTUHBWhrbiJpKdL4KIDs6hwh0QqLbnt8i7t02wq6qubGW0hYvdY3MQL2GfbNoIZUbYezp5eCyHm/8cFT/WTt1sGSg4hD8JbUn0GTMcrh4rrQLmcJbjStNUOyjqouASTK1A2QQxSS5p2Y7AC4yut3MIqyr7ByAX9/85HtHrdX3AgMBAAECggEAFWRBnzGCyeZhYB6OD+o30j1Dx001aNWiODNYs4t4VrSeoYMqBh3Gtm8x9HybNYwAJRLp4ulJl8i2NSjvK1IWqxgqIt87x74z3ed2tO46jknKGaOMCcfzN7t4b9BxLd83pekRyUewzbV7cVqTW5WTyAZ5EUp14Wtof7vtjsg8ndZp1C0LzJrsQ63LWJAWsfkiRwNwbjkIKTl12xwe3ctZD/PmxYVgWGog+32OiiiTuSf4O1ddp3y2kth66dSIO06VPCqgu8gLwG5epgHmy0Y1ugunpZINN2D7FCH7aaE+H+aQ4nltNIxpQV20grtQG546oDilfPCQLxeW1HUipq2wkQKBgQDyqo180/lJ4wSNFU/hNqLfs2629vU9MH9aSjG5nQpchkTgBxUhAE5RkKgQHLJHJTfPx7vkx2xkI3qddwsWzvt8lNs5NQNxh+LyXQEgy9FCfpopijy2epLpzd2WT+0Y9WK5oB7O32s2YW/6fm0ahu3EJnvBlp1M23FzuRfrV7gu5QKBgQCz98MyV0UAnP3x+Gq5/0siVGPInzYlfTfYcEI3qhlMfqPVkRqqHdGGsiQL70YJlTlZkLeh3r2UvoR956nV9lZgh37aWnaHw7FAYcA5z4FYEFdmpLK/8znaKn/fxypr9xkJtw5V1QgCeaSUCFbt0xp41LaAvwSDBfFqdOTzQMFHqwKBgEyZN4YypxsClPovwwI1K95vFkCc3baN63VFvEJ55r5kB7OrqKi9HvuyLMrBNCku/1oQEyhZJsbJSDgSTqbJeSrPFhANwuOAYEveva9rhsd1jRYVs6pqMJuqxwpeeloJgztS5saoUYBd62nnpGreMolbGG94KnkLP9mmkH1SOCpdAoGAbheD3ljKilx/cLVxvIRy1vZe8EyNGBPoxMuvhlPVFBloae5RLH3/PfHd4TsnUhdqNOM1op0axlJhxI+iMpR2NKjOrg6m8diBpwvlRrgsvM2KWe0ouAm3e0GCZkd1KQTI2UuVRmaCdtkpF7GeU/BPAlnFpy6zON+61k/Z+wDC++8CgYEA54xmJqIr19BpKkcHAxE2pzDrj6ssu2qObKLfsS27o4RevBnrhoY9kPwn8kUKpngoCTd7tM42y9fcpAdUDv+lENAcIF/kz4u+zkyRGR+SpirgAsCYzxZN3GfRNDHBaFEiTkyL6NFdPGV2GTPcd0b6JGf82Thb0JJCxB/J3hVnDIs="/>
+  <NotifyUrl value="http://218.17.158.45:15105/api/Account/HandleASignCompleted"/>
+  <OpenApiUrl value="http://192.168.31.202:5015/mtp2-onlineopen"/>
+</Asign>
+
+url: 'https://prev.asign.cn' # 测试环境 - https://prev.asign.cn  正式环境 - https://oapi.asign.cn
 appId: '290912417' # 测试-290912417 正式-944849860
 privateKey: 'MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEAkMD+72J6iAF0ZNV+3t628lsRHfJ80nKZWK5/C7Pg+AZmOIzJlwHsKhRzCvxoxqYHQprhiFzW9l73v9vD9l1JYwIDAQABAkBVijccr01JYdKuY5t9iI8D2NzcnZc1pZMI3NUmzT18Uyg7b9CUvGHlLeg/gdT4QtVd7wIzHYCY4letEcEMh54BAiEAwzNWusj5XiLmty7PI0Hbakx4HtcND1+P0UHLEWqWOuECIQC91zQuL7nStgGzT3HvaeBB5Ouapa39fHRm2nCjHaxwwwIgRR2XdvmUOj23XWMomr5F14SN/7V7fVcD0D8wjNElsmECIDYavV5kb7tj7/wgqkInlKhzC8rZaUsTS0F9BBkY/eptAiAQJ8Saz8YlMIESdHMxANGSog01fECbcZqLFMuNf8SorA=='
 notifyUrl: 'http://218.17.158.45:15105/api/Account/HandleASignCompleted' # 合同签署回调通知URL

+ 2 - 1
go.mod

@@ -13,7 +13,7 @@ require (
 	github.com/bndr/gotabulate v1.1.2 // indirect
 	github.com/clbanning/mxj v1.8.4 // indirect
 	github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect
-	github.com/fatih/structs v1.1.0 // indirect
+	github.com/fatih/structs v1.1.0
 	github.com/gin-gonic/gin v1.9.0
 	github.com/go-openapi/spec v0.20.4 // indirect
 	github.com/go-openapi/swag v0.19.15 // indirect
@@ -56,6 +56,7 @@ require (
 )
 
 require (
+	github.com/gofrs/uuid v4.4.0+incompatible
 	github.com/swaggo/files v1.0.1
 	github.com/swaggo/gin-swagger v1.6.0
 	github.com/swaggo/swag v1.16.2

+ 2 - 0
go.sum

@@ -68,6 +68,8 @@ github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gG
 github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
 github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA=
 github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
+github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
 github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=

+ 1 - 1
models/market.go

@@ -158,7 +158,7 @@ type Marketrunstepdetail struct {
 
 // TableName is MARKETRUNSTEPDETAIL
 func (Marketrunstepdetail) TableName() string {
-	return "MARKETRUNSTEPDETAIL"
+	return "TODAY_MARKETRUNSTEPDETAIL"
 }
 
 // Quotesourcegrouprunstep 行情源分组开休市计划明细

+ 54 - 0
services/asign/api.go

@@ -1 +1,55 @@
 package asign
+
+import (
+	"encoding/json"
+	"mtp2_if/config"
+	"mtp2_if/logger"
+
+	"github.com/fatih/structs"
+)
+
+// PersonBankCard4 个人银行卡四要素认证
+func PersonBankCard4(req PersonBankCard4Req) (rsp *Rsp[PersonBankCard4Rsp], err error) {
+	apiUrl := config.SerCfg.AsignCfg.Url + "/auth/person/bankCard4"
+
+	reqMap := structs.Map(req)
+	logger.GetLogger().Info("[asign.PersonBankCard4] 调用接口 /auth/person/bankCard4 请求, request:", reqMap)
+	rspBody, err := HttpPost(apiUrl, reqMap)
+	if err != nil {
+		logger.GetLogger().Error("[asign.PersonBankCard4] 调用接口 /auth/person/bankCard4 错误, error:", err.Error())
+		return
+	}
+	rspStr := string(rspBody)
+	if len(rspStr) == 0 {
+		logger.GetLogger().Error("[asign.PersonBankCard4] 调用接口 /auth/person/bankCard4 错误, response为空")
+		return
+	}
+	logger.GetLogger().Info("[asign.PersonBankCard4] 调用接口 /auth/person/bankCard4 返回, response:", rspStr)
+	rsp = new(Rsp[PersonBankCard4Rsp])
+	err = json.Unmarshal(rspBody, rsp)
+
+	return
+}
+
+// CaptchaVerify 认证验证码校验
+func CaptchaVerify(req CaptchaVerifyReq) (rsp *Rsp[CaptchaVerifyRsp], err error) {
+	apiUrl := config.SerCfg.AsignCfg.Url + "/auth/captcha/verify"
+
+	reqMap := structs.Map(req)
+	logger.GetLogger().Info("[asign.CaptchaVerify] 调用接口 /auth/captcha/verify 请求, request:", reqMap)
+	rspBody, err := HttpPost(apiUrl, reqMap)
+	if err != nil {
+		logger.GetLogger().Error("[asign.CaptchaVerify] 调用接口 /auth/captcha/verify 错误, error:", err.Error())
+		return
+	}
+	rspStr := string(rspBody)
+	if len(rspStr) == 0 {
+		logger.GetLogger().Error("[asign.CaptchaVerify] 调用接口 /auth/captcha/verify 错误, response为空")
+		return
+	}
+	logger.GetLogger().Info("[asign.CaptchaVerify] 调用接口 /auth/captcha/verify 返回, response:", rspStr)
+	rsp = new(Rsp[CaptchaVerifyRsp])
+	err = json.Unmarshal(rspBody, rsp)
+
+	return
+}

+ 54 - 6
services/asign/http.go

@@ -1,6 +1,7 @@
 package asign
 
 import (
+	"bytes"
 	"crypto"
 	"crypto/md5"
 	"crypto/rand"
@@ -11,13 +12,62 @@ import (
 	"encoding/hex"
 	"encoding/pem"
 	"fmt"
+	"io"
+	"mime/multipart"
+	"mtp2_if/config"
+	"mtp2_if/logger"
+	"net/http"
 	"sort"
+	"strconv"
+	"strings"
+	"time"
 )
 
-func HttpPost(url string, bizData map[string]interface{}) (rspBody []byte, err error) {
+// HttpPost
+//
+//	爱签HttpPost请求方法
+// @param  apiUrl  接口地址
+// @param  bizData formData入参
+// @return rspBody response body数据
+// @return err 错误
+func HttpPost(apiUrl string, bizData map[string]interface{}) (rspBody []byte, err error) {
+	appId := config.SerCfg.AsignCfg.AppId
+	privateKey := fmt.Sprintf("-----BEGIN PRIVATE KEY-----\n%s\n-----END PRIVATE KEY-----", config.SerCfg.AsignCfg.PrivateKey)
+
+	// fuck asign dev.
+	timestamp := strconv.Itoa(int(time.Now().UnixMilli() + 1000*60))
 
 	// 签名
-	// timestamp := int64(time.Now().Unix())
+	sortedData := sortMapByKey(bizData)
+	signature, err := getSignature(sortedData, appId, timestamp, privateKey)
+	if err != nil {
+		logger.GetLogger().Errorf("[asign.HttpPost] 签名失败:" + err.Error())
+		return
+	}
+
+	// 构建form-data请求参数
+	var requestBody bytes.Buffer
+	multipartWriter := multipart.NewWriter(&requestBody)
+	multipartWriter.WriteField("appId", appId)
+	multipartWriter.WriteField("timestamp", timestamp)
+	multipartWriter.WriteField("bizData", sortedData)
+	multipartWriter.Close()
+	// 构建请求
+	req, err := http.NewRequest("POST", apiUrl, &requestBody)
+	// 设置请求头
+	req.Header.Set("sign", signature)
+	req.Header.Set("timestamp", timestamp)
+	req.Header.Set("Content-Type", multipartWriter.FormDataContentType())
+
+	// 调用接口
+	client := &http.Client{}
+	rsp, err := client.Do(req)
+	if err != nil {
+		logger.GetLogger().Errorf("[asign.HttpPost] 调用接口失败:" + err.Error())
+		return
+	}
+	defer rsp.Body.Close()
+	rspBody, err = io.ReadAll(rsp.Body)
 
 	return
 }
@@ -46,14 +96,11 @@ func HttpPost(url string, bizData map[string]interface{}) (rspBody []byte, err e
 //	     log.error( "sdk异常",  e ) ;
 //	     return  ApiRespBody.create ( ApiResponseInfo. _ERROR ) ;
 //	}
-func getSignature(bizData map[string]interface{}, appId, timestamp, privateKey string) (signature string, err error) {
+func getSignature(sortedData string, appId, timestamp, privateKey string) (signature string, err error) {
 	pem10, _ := pem.Decode([]byte(privateKey))
 	privateKey10I, _ := x509.ParsePKCS8PrivateKey(pem10.Bytes)
 	privateKey10 := privateKey10I.(*rsa.PrivateKey)
 
-	// sort by key
-	sortedData := sortMapByKey(bizData)
-
 	// md5(bizData)
 	m := md5.New()
 	m.Write([]byte(sortedData))
@@ -74,6 +121,7 @@ func getSignature(bizData map[string]interface{}, appId, timestamp, privateKey s
 
 	// fmt.Println(signature)
 	signature = base64.StdEncoding.EncodeToString(sign)
+	signature = strings.ReplaceAll(signature, "\r\n", "")
 
 	return
 }

+ 68 - 0
services/asign/models.go

@@ -1 +1,69 @@
 package asign
+
+type RspData interface {
+	PersonBankCard4Rsp | AddPersonalUserRsp | CaptchaVerifyRsp
+}
+
+type Rsp[T RspData] struct {
+	Code int    `json:"code"` // 响应码,100000表示成功,其他表示异常
+	Msg  string `json:"msg"`  // 	响应信息
+	Data T      // 响应数据
+}
+
+// PersonBankCard4Req 个人银行卡四要素认证请求入参
+type PersonBankCard4Req struct {
+	RealName string `json:"realName" binding:"required"` // 真实姓名
+	IdCardNo string `json:"idCardNo" binding:"required"` // 身份证号
+	BankCard string `json:"bankCard" binding:"required"` // 银行卡号(仅限印有“银联”字样的银行卡)
+	Mobile   string `json:"mobile" binding:"required"`   // 手机号码(限中国大陆11位手机号)
+}
+
+// PersonBankCard4Rsp 个人银行卡四要素认证请求出参
+type PersonBankCard4Rsp struct {
+	Result   int    `json:"result"`   // 认证结果 0.暂无结果/认证中 1.成功 2.失败
+	SerialNo string `json:"serialNo"` // 认证流水号
+	Type     string `json:"type"`     // 认证类型
+}
+
+// CaptchaVerifyReq 认证验证码校验入参
+type CaptchaVerifyReq struct {
+	SerialNo string `json:"serialNo" binding:"required"` // 认证流水号
+	Captcha  string `json:"captcha" binding:"required"`  // 短信验证码
+}
+
+// CaptchaVerifyRsp 认证验证码校验出参
+type CaptchaVerifyRsp struct {
+	Result   int    `json:"result"`   // 认证结果 0.暂无结果/认证中 1.成功 2.失败
+	SerialNo string `json:"serialNo"` // 认证流水号
+	Type     string `json:"type"`     // 认证类型
+}
+
+// AddPersonalUserReq 添加个人用户(V2)入参
+type AddPersonalUserReq struct {
+	Account         string `json:"account" binding:"required"` // 用户唯一识别码(请转入UserID)
+	SerialNo        string `json:"serialNo"`                   // 实名认证流水号
+	Name            string `json:"name"`                       // 用户姓名
+	IdCard          string `json:"idCard"`                     // 个人身份证、台胞证、港澳通行证等证件号
+	IdCardType      int    `json:"idCardType"`                 // 证件类型 1:居民身份证 2:台湾居民来往内地通行证 3:港澳居民往来内地通行证 10:武装警察身份证 11:军人身份证 15:警察(警官)证 21:外国人永久居留证 23:护照
+	Mobile          string `json:"mobile"`                     // 手机号码
+	SignPwd         string `json:"signPwd"`                    // 签约密码(MTP2登录密码加密方式),如果为空将随机生成签约密码(当签约方式为“签约密码签约”时会使用到,可通过重置接口修改)
+	IsSignPwdNotice int    `json:"isSignPwdNotice"`            // 是否将签约密码以短信形式通知用户 0:不通知(默认) 1:通知
+	IsNotice        int    `json:"isNotice"`                   // 用户发起合同或需要签署时是否进行短信通知 0:否(默认) 1:是
+}
+
+// AddPersonalUserRsp 添加个人用户(V2)出参
+type AddPersonalUserRsp struct {
+	SealNo string `json:"sealNo"  binding:"required"` // 生成默认印章编号
+}
+
+type Template struct {
+	TemplateNo string `json:"templateNo"` // 合同模板编号
+}
+
+type CreateContractReq struct {
+	ContractNo   string `json:"contractNo" binding:"required"`   // 合同ID,合同唯一编号
+	ContractName string `json:"contractName" binding:"required"` // 合同名称
+	ValidityTime int    `json:"validityTime"`                    // 合同签署剩余天数(系统当前时间+该天数=在此日期之前可以签署合同日期),【注】与合同有效截止日期必传其一,【例】可传剩余天数:15
+	ValidityDate string `json:"validityDate"`                    // 合同有效截止日期(在此日期之前可以签署合同,格式要求:yyyyMMddHHmmss),【注】与合同有效天数必传其一,【例】传值“20231207190000” 为:2023年12月07日19时00分00秒
+	SignOrder    int    `json:"signOrder" binding:"required"`    // 签约方式 1:无序签约(默认) 2:顺序签约
+}