diff --git a/constant/param_type.go b/constant/param_type.go deleted file mode 100644 index ff3c047..0000000 --- a/constant/param_type.go +++ /dev/null @@ -1,3 +0,0 @@ -package constant - -type () diff --git a/constant/request_code.go b/constant/request_code.go deleted file mode 100644 index 0267b0d..0000000 --- a/constant/request_code.go +++ /dev/null @@ -1,13 +0,0 @@ -package constant - -type RequestCode string - -const ( - GetAccountBalance RequestCode = "SKBALQRY" -) - -type ResponseCode string - -const ( - Success ResponseCode = "AAAAAAA" -) diff --git a/entity/account_center.go b/entity/account_center.go deleted file mode 100644 index f3c0f6b..0000000 --- a/entity/account_center.go +++ /dev/null @@ -1,15 +0,0 @@ -package entity - -type ( - GetAccountBalanceResp []struct { - AccountNo string `json:"accountNo" comment:"账号" ` - AccountName string `json:"accountName" comment:"账户名称"` - UsableBalance float64 `json:"usableBalance" comment:"可用账户余额"` //可操作的账户余额 - Balance float64 `json:"Balance" comment:"账号余额"` //该账户中全部余额,包含冻结金额、可操作余额等 - FraAmt float64 `json:"fraAmt" comment:"冻结余额"` - LastUdtTms string `json:"lastUdtTms" comment:"更新时间"` - DataSrc string `json:"dataSrc" comment:"数据来源"` //直联、非直联-人工等 - CurrencyID string `json:"currencyID" comment:"币种"` //CNY:人民币 USD:美元 - Date string `json:"date" comment:"日期"` - } -) diff --git a/go.mod b/go.mod index 032999b..4948146 100644 --- a/go.mod +++ b/go.mod @@ -37,6 +37,7 @@ require ( gitea.cdlsxd.cn/self-tools/l_request v1.0.7 // indirect github.com/aliyun/alibaba-cloud-sdk-go v1.61.18 // indirect github.com/buger/jsonparser v1.1.1 // indirect + github.com/clbanning/mxj v1.8.4 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-errors/errors v1.0.1 // indirect github.com/go-kratos/aegis v0.2.0 // indirect diff --git a/pkg/func.go b/pkg/func.go index af94aec..455eacb 100644 --- a/pkg/func.go +++ b/pkg/func.go @@ -3,17 +3,19 @@ package pkg import ( "bytes" "encoding/json" - "encoding/xml" "fmt" - "gitea.cdlsxd.cn/self-tools/tysk/constant" + "gitea.cdlsxd.cn/self-tools/tysk/tysk_constant" + "github.com/clbanning/mxj" + "reflect" + "strconv" "strings" ) // XmlRequest 定义请求结构 type XmlRequest struct { - Action constant.RequestCode `xml:"action"` - UserName string `xml:"userName"` - ExtraFields map[string]interface{} `xml:"-"` // 忽略此字段,手动处理 + Action tysk_constant.RequestCode `xml:"action"` + UserName string `xml:"userName"` + ExtraFields map[string]interface{} `xml:"-"` // 忽略此字段,手动处理 } // MarshalToXML 将XmlRequest转换为指定格式的XML字节流 @@ -31,16 +33,16 @@ func (req XmlRequest) MarshalToXML() ([]byte, error) { // 处理ExtraFields for key, value := range req.ExtraFields { switch v := value.(type) { - case string: - // 空字符串特殊处理(根据示例输出,有些空字段也需要输出) - buf.WriteString(fmt.Sprintf("<%s>%s\n", key, v, key)) case []map[string]interface{}: // 处理列表数据 buf.WriteString(fmt.Sprintf("\n", key)) for _, row := range v { + if len(row) == 0 { + continue + } buf.WriteString("\n") for rowKey, rowValue := range row { - buf.WriteString(fmt.Sprintf("<%s>%v\n", rowKey, rowValue, rowKey)) + buf.WriteString(fmt.Sprintf("<%s>%s\n", rowKey, ToString(rowValue), rowKey)) } buf.WriteString("\n") } @@ -51,11 +53,34 @@ func (req XmlRequest) MarshalToXML() ([]byte, error) { buf.WriteString(fmt.Sprintf("\n", key)) buf.WriteString("\n") for _, row := range v { - + buf.WriteString(fmt.Sprintf("<%s>%s\n", key, row, key)) } buf.WriteString("\n") buf.WriteString("\n") // 可以根据需要添加其他类型的处理 + case map[string]interface{}: + // 处理列表数据 + buf.WriteString(fmt.Sprintf("\n", key)) + + for rowKey, row := range v { + switch row.(type) { + case []interface{}: + for _, rowValue := range row.([]interface{}) { + buf.WriteString("\n") + buf.WriteString(fmt.Sprintf("<%s>%s\n", rowKey, rowValue, rowKey)) + buf.WriteString("\n") + } + default: + buf.WriteString("\n") + buf.WriteString(fmt.Sprintf("<%s>%s\n", key, row, key)) + buf.WriteString("\n") + } + } + + buf.WriteString("\n") + // 可以根据需要添加其他类型的处理 + default: + buf.WriteString(fmt.Sprintf("<%s>%s\n", key, ToString(v), key)) } } @@ -63,22 +88,141 @@ func (req XmlRequest) MarshalToXML() ([]byte, error) { return buf.Bytes(), nil } -func XMLToByte(xmlData string) ([]byte, error) { - // 1. 定义一个通用接口来存储解析后的XML - var data interface{} - - // 2. 使用xml.Unmarshal解析XML - decoder := xml.NewDecoder(strings.NewReader(xmlData)) - err := decoder.Decode(&data) - if err != nil { - return nil, fmt.Errorf("xml decode error: %v", err) +func XMLToByte(xmlBytes []byte) ([]byte, error) { + // 去掉XML声明 + if idx := bytes.Index(xmlBytes, []byte("?>")); idx != -1 { + xmlBytes = xmlBytes[idx+2:] } - - // 3. 将解析后的数据转换为JSON - jsonData, err := json.Marshal(data) + // 解析XML + mv, err := mxj.NewMapXml(xmlBytes) if err != nil { - return nil, fmt.Errorf("json encode error: %v", err) + return nil, fmt.Errorf("XML 解析失败: %v", err) + } + // 获取stream节点 + stream, ok := mv["stream"].(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("无效的XML结构: 缺少stream节点") + } + // 处理list节点 + if lists, ok := stream["list"].([]interface{}); ok { + for _, listItem := range lists { + if listMap, ok := listItem.(map[string]interface{}); ok { + // 获取name属性 + if name, ok := listMap["-name"].(string); ok && name != "" { + // 用name作为key,替换原来的list数组 + if rowList, ok := listMap["row"].(map[string]interface{}); ok { + stream[name] = []map[string]interface{}{rowList} + } else { + stream[name] = listMap["row"] + } + + } + } + } + // 删除原始的list节点 + delete(stream, "list") + } + // 转换为JSON + jsonData, err := json.Marshal(stream) + if err != nil { + return nil, fmt.Errorf("JSON序列化失败: %v", err) } return jsonData, nil } + +func SliceToMap(list []interface{}) (listMap []map[string]interface{}) { + listMap = make([]map[string]interface{}, len(list)) + //for _, accountNo := range list { + // listMap = append(list, map[string]interface{}{"accountNo": accountNo}) + //} + return +} + +func IsStruct(v interface{}) bool { + if v == nil { + return false + } + t := reflect.TypeOf(v) + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + return t.Kind() == reflect.Struct +} + +// StructToMap 将一个struct转换为map[string]interface{} +func StructToMap(obj interface{}) map[string]interface{} { + // 获取obj的类型 + val := reflect.ValueOf(obj) + if val.Kind() == reflect.Ptr { + val = val.Elem() + } + + // 确保obj是一个struct + if val.Kind() != reflect.Struct { + return nil + } + + // 创建一个map来保存结果 + data := make(map[string]interface{}) + + // 遍历struct的字段 + for i := 0; i < val.NumField(); i++ { + // 获取字段的类型和值 + valueField := val.Field(i) + typeField := val.Type().Field(i) + jsonTag := typeField.Tag.Get("json") + if idx := strings.Index(jsonTag, ","); idx != -1 { + // 如果有逗号,则取逗号之前的部分 + jsonTag = jsonTag[:idx] + } + // 忽略未导出的字段(字段名首字母小写) + if !typeField.IsExported() { + continue + } + + // 将字段名和值添加到map中 + data[jsonTag] = valueField.Interface() + } + + return data +} + +func ToString(v interface{}) string { + switch v := v.(type) { + case int: + return strconv.Itoa(v) + case float64: + return strconv.FormatFloat(v, 'f', -1, 64) + case bool: + return strconv.FormatBool(v) + case string: + return v + case fmt.Stringer: // 实现了 String() 接口的类型 + return v.String() + default: + return fmt.Sprintf("%v", v) // 其他类型 fallback + } +} + +// BuildNestedMap 通用方法:根据动态路径(如 "userDataList.rcptNum")构造嵌套 map +func BuildNestedMap(path string, value interface{}) (map[string]interface{}, string) { + keys := strings.Split(path, ".") + result := make(map[string]interface{}) + current := result + + // 迭代处理每一级 key + for i, key := range keys { + if i == len(keys)-1 { + // 最后一层,赋值 + current[key] = value + } else { + // 非最后一层,创建嵌套 map + newMap := make(map[string]interface{}) + current[key] = newMap + current = newMap + } + } + + return result, keys[0] +} diff --git a/request.go b/request.go index fbb197e..09207ed 100644 --- a/request.go +++ b/request.go @@ -4,12 +4,23 @@ import ( "encoding/json" "fmt" "gitea.cdlsxd.cn/self-tools/l_request" - "gitea.cdlsxd.cn/self-tools/tysk/constant" - "gitea.cdlsxd.cn/self-tools/tysk/entity" "gitea.cdlsxd.cn/self-tools/tysk/pkg" + "gitea.cdlsxd.cn/self-tools/tysk/tysk_constant" + "gitea.cdlsxd.cn/self-tools/tysk/tysk_entity" + "github.com/duke-git/lancet/v2/convertor" ) -func (g *Tysk) handleRequest(Action constant.RequestCode, requestData map[string]interface{}, result interface{}) (err error) { +func (g *Tysk) getRequestUrl() string { + switch g.Env { + case "dev": + return "http://192.168.6.81:6789" + default: + return "" + } + +} + +func (g *Tysk) handleRequest(Action tysk_constant.RequestCode, requestData map[string]interface{}, result interface{}) (err error) { reqData := pkg.XmlRequest{ Action: Action, UserName: g.UserName, @@ -25,31 +36,56 @@ func (g *Tysk) handleRequest(Action constant.RequestCode, requestData map[string Xml: gbkXML, } response, err := req.Send() + response.Content, err = convertor.GbkToUtf8(response.Content) + response.Text = string(response.Content) if err != nil { return } - resByte, err := pkg.XMLToByte(response.Text) + resByte, err := pkg.XMLToByte(response.Content) if err != nil { return } - var commonResponse entity.RespCommon + var commonResponse tysk_entity.RespCommon err = json.Unmarshal(resByte, &commonResponse) if err != nil { return } - if commonResponse.Status != string(constant.Success) { - return fmt.Errorf("请求失败,错误码:%s,错误信息:%s", commonResponse.Status, commonResponse.FailReason) + if commonResponse.Status != string(tysk_constant.Success) { + return fmt.Errorf("请求失败,错误码:%s, 失败类型:%s,失败原因:%s", commonResponse.Status, commonResponse.StatusText, commonResponse.FailReason) + } + if result == nil { + return } - return json.Unmarshal(resByte, result) } -func (g *Tysk) getRequestUrl() string { - switch g.Env { - case "dev": - return "http://127.0.0.1:6789" - default: - return "" +func (g *Tysk) handleReqStructToMap(reqStruct interface{}) (requestData map[string]interface{}) { + if !pkg.IsStruct(reqStruct) { + return nil + } + var reqMap map[string]interface{} + reqJsonByte, err := json.Marshal(reqStruct) + if err != nil { + return nil + } + err = json.Unmarshal(reqJsonByte, &reqMap) + if err != nil { + return nil + } + requestData = make(map[string]interface{}) + for k, v := range reqMap { + if v == nil { + continue + } + switch v.(type) { + case []interface{}: + a, k0 := pkg.BuildNestedMap(k, v) + requestData[k0] = a[k0] + default: + requestData[k] = v + } + } + return } diff --git a/tysk.go b/tysk.go index 16b2a32..72cc04f 100644 --- a/tysk.go +++ b/tysk.go @@ -1,8 +1,8 @@ package tysk import ( - "gitea.cdlsxd.cn/self-tools/tysk/constant" - "gitea.cdlsxd.cn/self-tools/tysk/entity" + "gitea.cdlsxd.cn/self-tools/tysk/tysk_constant" + "gitea.cdlsxd.cn/self-tools/tysk/tysk_entity" ) type Tysk struct { @@ -10,7 +10,7 @@ type Tysk struct { Env string // 环境,测试:dev,不传默认正式 } -func NewTysk(userName string, opts ...Option) TyskFacecade { +func NewTysk(userName string, opts ...Option) TyskFacade { tysk := &Tysk{UserName: userName} for _, opt := range opts { opt(tysk) // 应用选项 @@ -26,7 +26,56 @@ func WithEnvTest() Option { } } -func (g *Tysk) GetAccountBalance(accountList []string) (res entity.GetAccountBalanceResp, err error) { - err = g.handleRequest(constant.GetAccountBalance, map[string]interface{}{"accountNo": accountList}, &res) +func (g *Tysk) GetAccountBalance(accountList tysk_entity.GetAccountBalanceReq) (res map[tysk_constant.AccountNo]tysk_entity.GetAccountBalanceList, err error) { + var result tysk_entity.AccountBalance + + err = g.handleRequest(tysk_constant.GetAccountBalance, g.handleReqStructToMap(accountList), &result) + if err != nil { + return + } + res = make(map[tysk_constant.AccountNo]tysk_entity.GetAccountBalanceList, len(result.List.Row)) + for _, row := range result.List.Row { + res[row.AccountNo] = row + } + return +} + +func (g *Tysk) GetTodayTransHis(todayTransHisReq tysk_entity.TodayTransHisReq) (res tysk_entity.TodayTransHisResp, err error) { + err = g.handleRequest(tysk_constant.GetTodayTransHis, g.handleReqStructToMap(todayTransHisReq), &res) + if err != nil { + return + } + return +} + +func (g *Tysk) GetAccountInfo(accountInfoReq tysk_entity.AccountInfoReq) (res tysk_entity.AccountInfoResp, err error) { + err = g.handleRequest(tysk_constant.GetAccountInfo, g.handleReqStructToMap(accountInfoReq), &res) + if err != nil { + return + } + return +} + +func (g *Tysk) ReceiptApply(receiptApplyReq tysk_entity.ReceiptApplyReq) (success bool, err error) { + err = g.handleRequest(tysk_constant.ReceiptApply, g.handleReqStructToMap(receiptApplyReq), nil) + if err != nil { + return + } + return true, nil +} + +func (g *Tysk) ReceiptQuery(receiptQueryReq tysk_entity.ReceiptQueryReq) (res tysk_entity.ReceiptQueryResp, err error) { + err = g.handleRequest(tysk_constant.ReceiptQuery, g.handleReqStructToMap(receiptQueryReq), &res) + if err != nil { + return + } + return +} + +func (g *Tysk) ReceiptDownload(receiptDownloadReq tysk_entity.ReceiptDownloadReq) (res tysk_entity.ReceiptDownloadResp, err error) { + err = g.handleRequest(tysk_constant.ReceiptDownload, g.handleReqStructToMap(receiptDownloadReq), &res) + if err != nil { + return + } return } diff --git a/tyskFacecade.go b/tyskFacecade.go index d7292b4..b46be55 100644 --- a/tyskFacecade.go +++ b/tyskFacecade.go @@ -1,8 +1,73 @@ package tysk -import "gitea.cdlsxd.cn/self-tools/tysk/entity" +import ( + "gitea.cdlsxd.cn/self-tools/tysk/tysk_constant" + "gitea.cdlsxd.cn/self-tools/tysk/tysk_entity" +) -type TyskFacecade interface { - // GetAccountBalance 账户余额查询 - GetAccountBalance(accountList []string) (res entity.GetAccountBalanceResp, err error) +// TyskFacade 定义了司库系统的外观接口 +type TyskFacade interface { + Account +} + +// Account 定义了账户相关的操作接口 +type Account interface { + // GetAccountBalance 账户余额查询 + // 查询司库中活期账户的实时余额信息。 + // 注意事项: + // 1. 请求使用的银企直联用户需有相关账号的查询权限; + // 2. 每次支持不多于20个账户的查询,返回当前司库同步到的账户余额信息; + // 如果账户余额尚未查询到,司库统一返回金额字段为空。 + GetAccountBalance(accountList tysk_entity.GetAccountBalanceReq) (res map[tysk_constant.AccountNo]tysk_entity.GetAccountBalanceList, err error) + + // GetTodayTransHis 当日交易明细查询 + // 用于查询账户的当日交易明细信息。 + // 注意事项: + // 1. 请求使用的银企直联用户需有相关账号的查询权限; + // 2. 使用分页查询,起始记录号从1开始,每页最多显示100条记录; + // 报文中的交易流水号sumTranNo由司库系统产生,用于标识客户交易明细数据唯一性。 + GetTodayTransHis(todayTransHisReq tysk_entity.TodayTransHisReq) (res tysk_entity.TodayTransHisResp, err error) + + // GetAccountInfo 账户信息查询 + // 用于查询客户在司库系统中维护的账号信息。 + // 注意事项: + // 1. 请求使用的银企直联用户需有相关账号的查询权限; + // 2. 使用分页查询,起始记录号从1开始,每页最多显示20条记录。 + GetAccountInfo(accountInfoReq tysk_entity.AccountInfoReq) (res tysk_entity.AccountInfoResp, err error) + + // ReceiptApply 电子回单申请 + // 实现司库电子回单查询申请,申请成功后需使用SKEDDQRY接口查询回单文件状态。 + // 注意事项: + // 1. 账号需提前在司库系统内维护并为直联用户赋予查询权限; + // 2. 电子回单下载需三步操作: + // - SKEDDRSQ 提交查询申请 + // - SKEDDQRY 查询回单准备状态 + // - SKEDCDTD 下载回单文件 + // 3. 接口限流:每台服务同时处理2笔交易,等待时间1秒 + // 4. 访问限制:同客户每天1000次 + // 5. 时间间隔最大为30天 + // 6. 支持当日回单的银行:中信、招商、平安、浦发、民生、中国银行、工商银行; + // 不支持的银行返回错误码SE01100,并默认返回T-1日回单。 + ReceiptApply(receiptApplyReq tysk_entity.ReceiptApplyReq) (success bool, err error) + + // ReceiptQuery 电子回单查询 + // 客户可使用该接口,查询SKEDDRSQ(司库电子回单查询申请)接口发出的交易请求的处理结果。若查询返回成功,可根据查询出的回单编号在SKEDCDTD(司库电子回单文件下载)接口下载对应的回单文件。交易将返回明确成功、处理中、失败等状态 + // 注意事项: + //1.账号需提前在司库系统内维护并为直联用户赋予查询权限; + //2.司库电子回单下载获取需通过三部操作完成:1. SKEDDRSQ(司库电子回单查询申请)提交所需账号的电子回单查询申请;2. SKEDDQRY(司库电子回单文件查询)查询第一步中查询的电子回单信息是否准备完成,如完成则根据查询提供的分页信息返回相应的回单编号,如未完成则继续轮训该接口(若涉及的电子回单信息较多时建议适当延长轮训间隔);3. SKEDCDTD(司库电子回单文件下载)根据回单编号对需要的回单文件进行下载。 + //3.接口限流机制:每台服务同时处理2笔交易,等待时间1秒 + //4.接口访问限制:同客户每分钟30次 + ReceiptQuery(receiptQueryReq tysk_entity.ReceiptQueryReq) (res tysk_entity.ReceiptQueryResp, err error) + + // ReceiptDownload 电子回单下载 + //客户可使用该接口,查询SKEDDRSQ(电子回单查询)接口发出的交易请求的处理结果。若查询返回成功,可根据查询出的回单编号在SKEDCDTD(司库电子回单文件下载)接口下载对应的回单文件。交易将返回明确成功、处理中、失败等状态 + // 注意事项: + //1.账号需提前在司库系统内维护并为直联用户赋予查询权限; + //2.司库电子回单下载获取需通过三部操作完成:1. SKEDDRSQ(司库电子回单查询申请)提交所需账号的电子回单查询申请;2. SKEDDQRY(司库电子回单文件查询)查询第一步中查询的电子回单信息是否准备完成,如完成则根据查询提供的分页信息返回相应的回单编号,如未完成则继续轮训该接口(若涉及的电子回单信息较多时建议适当延长轮训间隔);3. SKEDCDTD(司库电子回单文件下载)根据回单编号对需要的回单文件进行下载。 + //3.接口限流机制:每台服务同时处理2笔交易,等待时间3秒 + //4.接口访问限制:同客户每分钟30次 + //5.每次数量为:20条 + //6.文件压缩后最大大小为:2M + //7.在输入中新增“文件格式”字段,非必输,字典项为“OFD优先”、“PDF优先”。 + ReceiptDownload(receiptDownloadReq tysk_entity.ReceiptDownloadReq) (res tysk_entity.ReceiptDownloadResp, err error) } diff --git a/tysk_constant/bank_code.go b/tysk_constant/bank_code.go new file mode 100644 index 0000000..bf6d898 --- /dev/null +++ b/tysk_constant/bank_code.go @@ -0,0 +1,252 @@ +package tysk_constant + +// BankNameBankCode 中文名称存到储银行代码的映射 +var BankNameBankCode = map[string]BankCode{ + "南京银行": NJCB, + "招商银行": CSK, + "中国工商银行": ICBC, + "天津银行": TCCB, + "攀枝花市商业银行": PZHCB, + "汉口银行": HKB, + "华夏银行": HB, + "中国农业银行": ABC, + "中国银行": BOC, + "中国建设银行": CCB, + "杭州银行": HCCB, + "渤海银行": CBHB, + "宁波银行": NBCB, + "郑州银行": ZZB, + "中国民生银行": CSKC, + "广东发展银行": GDB, + "兴业银行": CIB, + "江苏银行": JSB, + "浙商银行": CZB, + "国家开发银行": CDB, + "北京银行": BCCB, + "中信银行": CITIC, + "交通银行": BCM, + "上海浦东发展银行": SPDB, + "中国邮政储蓄银行": PSBC, + "晋商银行": JSHB, + "青岛城阳农村合作银行": QDCY, + "汇丰银行": HSBC, + "长沙银行": BCS, + "乌鲁木齐市商业银行": UCCB, + "富滇银行": FUDIAN, + "成都银行": BOCD, + "福建海峡银行": FJHX, + "台州银行": TZB, + "恒丰银行": HFB, + "重庆银行": CQCB, + "渣打银行": SCB, + "澳新银行": ANZ, + "美国银行": BOA, + "光大银行": CEB, + "平安银行": SZDB, + "摩根银行": JPM, + "上海银行": BOS, + "厦门银行": XMCCB, + "徽商银行": HSHB, + "张家港商业农村银行": ZRCB, + "北京农村商业银行": BJRCB, + "兰州银行": LZB, + "北部湾银行": BBG, + "东亚银行": BEA, + "瑞穗实业银行": MIB, + "温州银行": WZCB, + "华润银行": CRBC, + "三菱银行": MUFG, + "广东省农村信用社联合社": GDRC, + "紫金农商银行": ZJRCB, + "厦门国际银行": XIB, + "包商银行": BSB, + "桂林银行": GLB, + "哈尔滨银行": HRBCB, + "张家口银行": ZJKB, + "曲靖市商业银行": QJCCB, + "龙江银行": LJB, + "盛京银行": SJB, + "云南农信社": YNRCC, + "甘肃银行": GSB, + "华融湘江银行": HRXJB, + "武汉农商行": WHRCB, + "网商银行": MYB, + "西安银行": XACB, + "福建农村信用社联合社": FJNX, + "苏州农村商业银行": WJRCB, + "武汉众邦银行": ZB, + "苏州银行": SZB, + "长安银行": CAB, + "华侨银行": OCBC, + "广州银行": GZCB, + "稠州商行银行": CZCB, + "三井住友": SJZY, +} + +// BankCodeBankName 存储银行代码到中文名称的映射 +var BankCodeBankName = map[BankCode]string{ + NJCB: "南京银行", + CSK: "招商银行", + ICBC: "中国工商银行", + TCCB: "天津银行", + PZHCB: "攀枝花市商业银行", + HKB: "汉口银行", + HB: "华夏银行", + ABC: "中国农业银行", + BOC: "中国银行", + CCB: "中国建设银行", + HCCB: "杭州银行", + CBHB: "渤海银行", + NBCB: "宁波银行", + ZZB: "郑州银行", + CSKC: "中国民生银行", + GDB: "广东发展银行", + CIB: "兴业银行", + JSB: "江苏银行", + CZB: "浙商银行", + CDB: "国家开发银行", + BCCB: "北京银行", + CITIC: "中信银行", + BCM: "交通银行", + SPDB: "上海浦东发展银行", + PSBC: "中国邮政储蓄银行", + JSHB: "晋商银行", + QDCY: "青岛城阳农村合作银行", + HSBC: "汇丰银行", + BCS: "长沙银行", + UCCB: "乌鲁木齐市商业银行", + FUDIAN: "富滇银行", + BOCD: "成都银行", + FJHX: "福建海峡银行", + TZB: "台州银行", + HFB: "恒丰银行", + CQCB: "重庆银行", + SCB: "渣打银行", + ANZ: "澳新银行", + BOA: "美国银行", + CEB: "光大银行", + SZDB: "平安银行", + JPM: "摩根银行", + BOS: "上海银行", + XMCCB: "厦门银行", + HSHB: "徽商银行", + ZRCB: "张家港商业农村银行", + BJRCB: "北京农村商业银行", + LZB: "兰州银行", + BBG: "北部湾银行", + BEA: "东亚银行", + MIB: "瑞穗实业银行", + WZCB: "温州银行", + CRBC: "华润银行", + MUFG: "三菱银行", + GDRC: "广东省农村信用社联合社", + ZJRCB: "紫金农商银行", + XIB: "厦门国际银行", + BSB: "包商银行", + GLB: "桂林银行", + HRBCB: "哈尔滨银行", + ZJKB: "张家口银行", + QJCCB: "曲靖市商业银行", + LJB: "龙江银行", + SJB: "盛京银行", + YNRCC: "云南农信社", + GSB: "甘肃银行", + HRXJB: "华融湘江银行", + WHRCB: "武汉农商行", + MYB: "网商银行", + XACB: "西安银行", + FJNX: "福建农村信用社联合社", + WJRCB: "苏州农村商业银行", + ZB: "武汉众邦银行", + SZB: "苏州银行", + CAB: "长安银行", + OCBC: "华侨银行", + GZCB: "广州银行", + CZCB: "稠州商行银行", + SJZY: "三井住友", +} + +// BankCode 银行代码常量 +type BankCode string + +const ( + NJCB BankCode = "NJCB" // 南京银行 + CSK BankCode = "CSK" // 招商银行 + ICBC BankCode = "ICBC" // 中国工商银行 + TCCB BankCode = "TCCB" // 天津银行 + PZHCB BankCode = "PZHCB" // 攀枝花市商业银行 + HKB BankCode = "HKB" // 汉口银行 + HB BankCode = "HB" // 华夏银行 + ABC BankCode = "ABC" // 中国农业银行 + BOC BankCode = "BOC" // 中国银行 + CCB BankCode = "CCB" // 中国建设银行 + HCCB BankCode = "HCCB" // 杭州银行 + CBHB BankCode = "CBHB" // 渤海银行 + NBCB BankCode = "NBCB" // 宁波银行 + ZZB BankCode = "ZZB" // 郑州银行 + CSKC BankCode = "CSKC" // 中国民生银行 + GDB BankCode = "GDB" // 广东发展银行 + CIB BankCode = "CIB" // 兴业银行 + JSB BankCode = "JSB" // 江苏银行 + CZB BankCode = "CZB" // 浙商银行 + CDB BankCode = "CDB" // 国家开发银行 + BCCB BankCode = "BCCB" // 北京银行 + CITIC BankCode = "CITIC" // 中信银行 + BCM BankCode = "BCM" // 交通银行 + SPDB BankCode = "SPDB" // 上海浦东发展银行 + PSBC BankCode = "PSBC" // 中国邮政储蓄银行 + JSHB BankCode = "JSHB" // 晋商银行 + QDCY BankCode = "QDCY" // 青岛城阳农村合作银行 + HSBC BankCode = "HSBC" // 汇丰银行 + BCS BankCode = "BCS" // 长沙银行 + UCCB BankCode = "UCCB" // 乌鲁木齐市商业银行 + FUDIAN BankCode = "FUDIAN" // 富滇银行 + BOCD BankCode = "BOCD" // 成都银行 + FJHX BankCode = "FJHX" // 福建海峡银行 + TZB BankCode = "TZB" // 台州银行 + HFB BankCode = "HFB" // 恒丰银行 + CQCB BankCode = "CQCB" // 重庆银行 + SCB BankCode = "SCB" // 渣打银行 + ANZ BankCode = "ANZ" // 澳新银行 + BOA BankCode = "BOA" // 美国银行 + CEB BankCode = "CEB" // 光大银行 + SZDB BankCode = "SZDB" // 平安银行 + JPM BankCode = "JPM" // 摩根银行 + BOS BankCode = "BOS" // 上海银行 + XMCCB BankCode = "XMCCB" // 厦门银行 + HSHB BankCode = "HSHB" // 徽商银行 + ZRCB BankCode = "ZRCB" // 张家港商业农村银行 + BJRCB BankCode = "BJRCB" // 北京农村商业银行 + LZB BankCode = "LZB" // 兰州银行 + BBG BankCode = "BBG" // 北部湾银行 + BEA BankCode = "BEA" // 东亚银行 + MIB BankCode = "MIB" // 瑞穗实业银行 + WZCB BankCode = "WZCB" // 温州银行 + CRBC BankCode = "CRBC" // 华润银行 + MUFG BankCode = "MUFG" // 三菱银行 + GDRC BankCode = "GDRC" // 广东省农村信用社联合社 + ZJRCB BankCode = "ZJRCB" // 紫金农商银行 + XIB BankCode = "XIB" // 厦门国际银行 + BSB BankCode = "BSB" // 包商银行 + GLB BankCode = "GLB" // 桂林银行 + HRBCB BankCode = "HRBCB" // 哈尔滨银行 + ZJKB BankCode = "ZJKB" // 张家口银行 + QJCCB BankCode = "QJCCB" // 曲靖市商业银行 + LJB BankCode = "LJB" // 龙江银行 + SJB BankCode = "SJB" // 盛京银行 + YNRCC BankCode = "YNRCC" // 云南农信社 + GSB BankCode = "GSB" // 甘肃银行 + HRXJB BankCode = "HRXJB" // 华融湘江银行 + WHRCB BankCode = "WHRCB" // 武汉农商行 + MYB BankCode = "MYB" // 网商银行 + XACB BankCode = "XACB" // 西安银行 + FJNX BankCode = "FJNX" // 福建农村信用社联合社 + WJRCB BankCode = "WJRCB" // 苏州农村商业银行 + ZB BankCode = "ZB" // 武汉众邦银行 + SZB BankCode = "SZB" // 苏州银行 + CAB BankCode = "CAB" // 长安银行 + OCBC BankCode = "OCBC" // 华侨银行 + GZCB BankCode = "GZCB" // 广州银行 + CZCB BankCode = "CZCB" // 稠州商行银行 + SJZY BankCode = "SJZY" // 三井住友 +) diff --git a/tysk_constant/param_type.go b/tysk_constant/param_type.go new file mode 100644 index 0000000..4dcd2f9 --- /dev/null +++ b/tysk_constant/param_type.go @@ -0,0 +1,155 @@ +package tysk_constant + +type AccountNo string + +// TranType 交易类型 +type TranType string + +const ( + All TranType = "01" //所有 + Out TranType = "02" //支出<借> + In TranType = "03" //收入<贷> +) + +var TranTypeMap = map[TranType]string{ + All: "所有", + Out: "支出<借>", + In: "收入<贷>", +} + +// AccCgyId 账户性质(原:账户类型) +type AccCgyId string + +const ( + AccCgyIdMapNormal AccCgyId = "1" //一般账户 + AccCgyIdMapBasic AccCgyId = "2" //基本账户 + AccCgyIdMapExclusive AccCgyId = "3" //专用账户 + AccCgyIdMapTentative AccCgyId = "4" //临时账户 +) + +var AccCgyIdMap = map[AccCgyId]string{ + AccCgyIdMapNormal: "一般账户", + AccCgyIdMapBasic: "基本账户", + AccCgyIdMapExclusive: "专用账户", + AccCgyIdMapTentative: "临时账户", +} + +// AccTpId 存款类型(原:账户种类) +type AccTpId string + +const ( + AccTpIdCurrent AccTpId = "1" //活期 + AccTpIdRegular AccTpId = "2" //定期 + AccTpIdNotice AccTpId = "3" //通知 + AccTpIdCurrentBond AccTpId = "4" //活期保证金 + AccTpIdRegularBond AccTpId = "5" //定期保证金 +) + +var AccTpIdMap = map[AccTpId]string{ + AccTpIdCurrent: "活期", + AccTpIdRegular: "定期", + AccTpIdNotice: "通知", + AccTpIdCurrentBond: "活期保证金", + AccTpIdRegularBond: "定期保证金", +} + +// AccStatId 账户状态 +type AccStatId string + +const ( + AccStatIdMapNormal AccStatId = "1" //正常 + AccStatIdMapCancel AccStatId = "2" //销户 + AccStatIdMapJudicialFreeze AccStatId = "3" //司法冻结 + AccStatIdMapNormalFreeze AccStatId = "4" //普通冻结 + AccStatIdMapSleep AccStatId = "5" //睡眠 + AccStatIdMapReportLoss AccStatId = "6" //挂失 + AccStatIdMapFreeze AccStatId = "7" //冻结 +) + +var AccStatIdMap = map[AccStatId]string{ + AccStatIdMapNormal: "正常", + AccStatIdMapCancel: "销户", + AccStatIdMapJudicialFreeze: "司法冻结", + AccStatIdMapNormalFreeze: "普通冻结", + AccStatIdMapSleep: "睡眠", + AccStatIdMapReportLoss: "挂失", //定期保证金 + AccStatIdMapFreeze: "冻结", //定期保证金 +} + +// IsOpnDirconId 联网方式(原:是否直联) +type IsOpnDirconId string + +const ( + IsOpnDirconIs IsOpnDirconId = "1" //直联 + IsOpnDirconNot IsOpnDirconId = "2" //非直联 + IsOpnDirconSWIFT IsOpnDirconId = "3" //SWIFT +) + +var IsOpnDirconIdMap = map[IsOpnDirconId]string{ + IsOpnDirconIs: "直联", + IsOpnDirconNot: "非直联", + IsOpnDirconSWIFT: "SWIFT", +} + +// AccCharId 账户属性 +type AccCharId string + +const ( + AccCharIdAcc AccCharId = "1" //实账户 + AccCharIdBook AccCharId = "2" //登记簿 + +) + +var AccCharIdMap = map[AccCharId]string{ + AccCharIdAcc: "实账户", + AccCharIdBook: "登记簿", +} + +// AccStyId 账户类型 +type AccStyId string + +const ( + AccStyIdNormal AccStyId = "0" //境内普通账户 + AccStyIdFTE AccStyId = "1" //FTE + AccStyIdNRA AccStyId = "2" //NRA + AccStyIdFTN AccStyId = "3" //FTN + AccStyIdOSA AccStyId = "4" //OSA + AccStyIdOther AccStyId = "5" //境外其他账户 + +) + +var AccStyIdMap = map[AccStyId]string{ + AccStyIdNormal: "境内普通账户", + AccStyIdFTE: "FTE", + AccStyIdNRA: "NRA", + AccStyIdFTN: "FTN", + AccStyIdOSA: "OSA", + AccStyIdOther: "境外其他账户", +} + +// IsFrgnAccId 账户类型 +type IsFrgnAccId string + +const ( + IsFrgnAccIn IsFrgnAccId = "0" //境内 + IsFrgnAccOut IsFrgnAccId = "1" //境外 + +) + +var IsFrgnAccIdMap = map[IsFrgnAccId]string{ + IsFrgnAccIn: "境内", + IsFrgnAccOut: "境外", +} + +// FileType 账户类型 +type FileType string + +const ( + FileTypePDF FileType = "PDF优先" + IsFrgnAccOFD FileType = "OFD优先" +) + +var FileTypeMap = map[FileType]string{ + FileTypePDF: "PDF优先", + IsFrgnAccOFD: "OFD优先", +} diff --git a/tysk_constant/request_code.go b/tysk_constant/request_code.go new file mode 100644 index 0000000..8e7a3e9 --- /dev/null +++ b/tysk_constant/request_code.go @@ -0,0 +1,18 @@ +package tysk_constant + +type RequestCode string + +const ( + GetAccountBalance RequestCode = "SKBALQRY" + GetTodayTransHis RequestCode = "SKTRNCOL" + GetAccountInfo RequestCode = "SKBACQRY" + ReceiptApply RequestCode = "SKEDDRSQ" + ReceiptQuery RequestCode = "SKEDDQRY" + ReceiptDownload RequestCode = "SKEDCDTD" +) + +type ResponseCode string + +const ( + Success ResponseCode = "AAAAAAA" +) diff --git a/entity/common.go b/tysk_entity/common.go similarity index 91% rename from entity/common.go rename to tysk_entity/common.go index b959854..48495f2 100644 --- a/entity/common.go +++ b/tysk_entity/common.go @@ -1,4 +1,4 @@ -package entity +package tysk_entity type ( RespCommon struct { diff --git a/tysk_entity/sk_req.go b/tysk_entity/sk_req.go new file mode 100644 index 0000000..c6e573e --- /dev/null +++ b/tysk_entity/sk_req.go @@ -0,0 +1,62 @@ +package tysk_entity + +import ( + "gitea.cdlsxd.cn/self-tools/tysk/tysk_constant" +) + +type ( + AccountList []tysk_constant.AccountNo + + Page struct { + StartRecord int32 `json:"startRecord"` //查询开始的记录编号,从1开始,超过最大记录数将返回空列表 + PageNumber int32 `json:"pageNumber"` //每次查询请求的记录数量,最多支持100条记录 + } + + GetAccountBalanceReq struct { + AccountNo AccountList `json:"userDataList.accountNo"` // 用户有查询权限的银行账号 + } + + TodayTransHisReq struct { + AccountNo AccountList `json:"userDataList.accountNo"` + TranType tysk_constant.TranType `json:"tranType"` //01:所有 02:账户支出(借) 03:账户收入(贷) + StartRecord int32 `json:"startRecord"` //查询开始的记录编号,从1开始,超过最大记录数将返回空列表 + PageNumber int32 `json:"pageNumber"` //每次查询请求的记录数量,最多支持100条记录 + } + + AccountInfoReq struct { + StartRecord int32 `json:"startRecord"` //查询开始的记录编号,从1开始,超过最大记录数将返回空列表 + PageNumber int32 `json:"pageNumber"` //每次查询请求的记录数量,最多支持100条记录 + BlngBnkId *tysk_constant.BankCode `json:"blngBnkId,omitempty"` //所属银行 + AccCgyId *tysk_constant.AccCgyId `json:"tranType,omitempty"` //账户性质(原:账户类型),1:一般账户 2:基本账户 3:专用账户 4:临时账户,默认为全部 + AccTpId *tysk_constant.AccTpId `json:"accTpId,omitempty"` //存款类型(原:账户种类),1:活期 2:定期 3:通知 4:活期保证金 5:定期保证金,默认为全部 + AccStatId *tysk_constant.AccStatId `json:"accStatId,omitempty"` //账户状态,1:正常 2:销户 3:司法冻结 4:普通冻结 5:睡眠 6:挂失 7:冻结,默认为全部 + IsOpnDirconId *tysk_constant.IsOpnDirconId `json:"IsOpnDirconId,omitempty"` //联网方式(原:是否直联),1:直联 2:非直联 3:SWIFT,默认为全部 + AccCharId *tysk_constant.AccCharId `json:"accCharId,omitempty"` //联网方式(原:是否直联),1:实账户 2:登记簿,默认为全部 + AccStyId *tysk_constant.AccStyId `json:"accStyId,omitempty"` //账户类型,0:境内普通账户 1:FTE 2:NRA 3:FTN 4:OSA 5:境外其他账户,默认为全部 + IsFrgnAccId *tysk_constant.IsFrgnAccId `json:"isFrgnAccId,omitempty"` //境内/境外,0:境内 1:境外,默认为全部 + } + + // Request 表示银企直联接口请求参数 + ReceiptApplyReq struct { + ClientID string `json:"clientID" validate:"required,max=20"` // 客户查询自定义的流水号,用于查询结果信息,需唯一 + AccountNo tysk_constant.AccountNo `json:"userDataList.accountNo"` // 用户有查询权限的银行账号 + StartDate string `json:"startDate"` // 查询起始日期(格式:YYYYMMDD) + EndDate string `json:"endDate"` // 查询终止日期(格式:YYYYMMDD) + } + + // ReceiptQueryReq 电子回单文件查询请求参数 + ReceiptQueryReq struct { + ClientID string `json:"clientID" comment:"记录申请编号" validate:"required,max=20"` // SKEDDRSQ交易流水号(varchar(20),必填,仅支持数字或字母组合) + StartDate string `json:"startDate,omitempty" comment:"查询起始日期"` // 查询开始日期(char(8),选填,yyyyMMdd格式,默认取申请单起始日期,与结束日期间隔≤30天) + EndDate string `json:"endDate,omitempty" comment:"查询结束日期"` // 查询结束日期(char(8),选填,yyyyMMdd格式,默认取申请单结束日期,与开始日期间隔≤30天) + TranType tysk_constant.TranType `json:"tranType,omitempty" comment:"交易类型"` // 交易类型(char(2),选填:01-全部交易/02-账户支出/03-账户收入) + StartRecord int32 `json:"startRecord" comment:"起始记录号" validate:"required,numeric,min=1"` // 查询起始记录编号(char(4),必填,从1开始) + PageNumber int32 `json:"pageNumber" comment:"请求记录条数" validate:"required,numeric,max=100"` // 每页记录数(char(4),必填,最大100条) + } + + // ReceiptDownloadReq 银企直联接口请求参数 + ReceiptDownloadReq struct { + FileType tysk_constant.FileType `json:"fileType,omitempty" comment:"文件格式"` // 文件格式(char(1),选填):PDF/OFD,默认PDF + RcptNums []string `json:"userDataList.rcptNum" comment:"回单下载列表" validate:"required,dive"` // 回单下载列表(必填) + } +) diff --git a/tysk_entity/sk_res.go b/tysk_entity/sk_res.go new file mode 100644 index 0000000..f962f1f --- /dev/null +++ b/tysk_entity/sk_res.go @@ -0,0 +1,178 @@ +package tysk_entity + +import "gitea.cdlsxd.cn/self-tools/tysk/tysk_constant" + +type ( + AccountBalance struct { + List struct { + Name string `json:"-name"` + Row []GetAccountBalanceList `json:"row"` + } `json:"list"` + } + GetAccountBalanceList struct { + AccountNo tysk_constant.AccountNo `json:"accountNo" comment:"账号" ` + AccountName string `json:"accountName" comment:"账户名称"` + UsableBalance string `json:"usableBalance" comment:"可用账户余额"` //可操作的账户余额 + Balance string `json:"Balance" comment:"账号余额"` //该账户中全部余额,包含冻结金额、可操作余额等 + FraAmt string `json:"fraAmt" comment:"冻结余额"` + LastUdtTms string `json:"lastUdtTms" comment:"更新时间"` + DataSrc string `json:"dataSrc" comment:"数据来源"` //直联、非直联-人工等 + CurrencyID string `json:"currencyID" comment:"币种"` //CNY:人民币 USD:美元 + Date string `json:"date" comment:"日期"` + } + + TodayTransHisResp struct { + List struct { + Name string `json:"-name"` + Row []TodayTransHisList `json:"row"` + } `json:"list"` + ReturnRecords string `json:"returnRecords"` //登陆用户本次查询获取到的账户明细数量 + TotalRecords string `json:"totalRecords" comment:"已查询到的回单总记录条数"` //交易成功时返回,返回该登陆用户具有查询权限的所有账户数量 + } + + TodayTransHisList struct { + AccCgyId string `json:"accCgyId" comment:"本方账户的账户性质"` //1一般账户 2基本账户 3专用账户 4临时账户 5其他 + AccDtlId string `json:"accDtlId" comment:"系统交易流水号"` //司库系统内该笔明细的唯一性标识,与sumTranNo保持一致 + AccStatId string `json:"accStatId" comment:"银行账户状态"` //1正常 2销户 3司法冻结 4普通冻结 5久悬 6挂失 7冻结 + AccTpId string `json:"accTpId" comment:"存款类型"` //1活期 2定期 3通知 4活期保证金 5定期保证金 6其他 + AccountName string `json:"accountName" comment:"本方户名"` + AccountNo string `json:"accountNo" comment:"本方账号"` + AccountingDate string `json:"accountingDate" comment:"记账日期"` //银行起息记账日期,使用yyyyMMdd格式 + Balance string `json:"balance" comment:"账户余额"` //该账户中全部余额,包含冻结金额、可操作余额 + BankName string `json:"bankName" comment:"本方所属银行"` //本方所属银行名称 + BnkSrlnum string `json:"bnkSrlnum" comment:"银行流水号"` + CashTfrId string `json:"cashTfrId" comment:"现转标识"` //0现金 1转账 + CurrencyID string `json:"currencyID" comment:"币种"` //CNY:人民币 USD:美元 + DataSource string `json:"dataSource" comment:"数据来源"` // 交易数据查询来源,1:接口查询(通过各行银企直联或中信网银);2:用户导入(自行导入的交易数据) + ExtendRemark string `json:"extendRemark" comment:"拓展字段1"` //仅支持兴业银行,别的银行为空 + ExternalBatNum string `json:"externalBatNum" comment:"外部请求批次号"` //对方行支持明细对账、且为批量支付生成时返回 + ExternalNum string `json:"externalNum" comment:"外部请求流水号"` //对方行支持明细对账时返回 + HdlTms string `json:"hdlTms" comment:"直联获取时间"` //系统存储时间,格式为:yyyy-MM-dd HH:mm:ss + InstCode string `json:"instCode" comment:"机构编码"` + InstName string `json:"instName" comment:"机构名称"` + IsFrgnAccId string `json:"isFrgnAccId" comment:"境内/境外账户"` //0境内 1境外 + IsOpnDirconId string `json:"isOpnDirconId" comment:"联网方式"` //0非直联 1直联 + Lvmsg string `json:"lvmsg" comment:"附言"` + OpenBankName string `json:"openBankName" comment:"本方开户行"` + OppAccountName string `json:"oppAccountName" comment:"对方账户名称"` + OppAccountNo string `json:"oppAccountNo" comment:"对方账号"` + OppOpenBankName string `json:"oppOpenBankName" comment:"对方开户行名"` + OppOpenBankNo string `json:"oppOpenBankNo" comment:"对方开户行联行号"` + OriginalSrlNum string `json:"originalSrlNum" comment:"原始银行流水号"` //交易明细流水号(目前仅支持平安银行) + Purpose string `json:"purpose" comment:"用途"` + Rmrk string `json:"rmrk" comment:"备注"` + Rrtanid string `json:"rrtanid" comment:"退汇标识"` //0已退汇 1非退汇 2手工退汇 + Smy string `json:"smy" comment:"摘要"` + SumTranNo string `json:"sumTranNo" comment:"系统交易流水号"` //司库系统内该笔明细的唯一性标识 + TranAmount string `json:"tranAmount" comment:"交易金额"` + TranDate string `json:"tranDate" comment:"交易日期"` + TranTime string `json:"tranTime" comment:"交易时间"` + TranType string `json:"tranType" comment:"交易类型(借贷方向)"` //01:全部交易;02:账户支出(借);03:账户收入(贷) + TxnSrlnum string `json:"txnSrlnum" comment:"交易流水号"` + } + + AccountInfoResp struct { + List struct { + Name string `json:"-name"` + Row []AccountInfoList `json:"row"` + } `json:"list"` + ReturnRecords string `json:"returnRecords"` //登陆用户本次查询获取到的账户明细数量 + TotalRecords string `json:"totalRecords"` //登陆用户具有查询权限的所有账户明细数量 + } + + AccountInfoList struct { + AccCgy string `json:"accCgy" comment:"账户性质(原:账户类型)"` // 交易成功且查询到账户时返回,取值:1一般账户 2基本账户 3专用账户 4临时账户 5其他 + AccChar string `json:"accChar" comment:"账户属性"` // 交易成功且查询到账户时返回,取值:1实账户 2登记簿 + AccId string `json:"accId" comment:"账户ID"` // 交易成功且查询到账户时返回,系统内唯一标识 + AccNm string `json:"accNm" comment:"账户名称"` // 交易成功且查询到账户时返回 + AccPayRst string `json:"accPayRst" comment:"账户支付限制状态"` // 交易成功且查询到账户时返回 + AccSrc string `json:"accSrc" comment:"账户来源"` // 交易成功且查询到账户时返回 + AccStatId string `json:"accStatId" comment:"银行账户状态"` // 交易成功且查询到账户时返回,取值:1正常 2销户 3司法冻结 4普通冻结 5久悬 6挂失 7冻结 + AccSty string `json:"accSty" comment:"账户样式"` // 交易成功且查询到账户时返回 + AccTp string `json:"accTp" comment:"存款类型"` // 交易成功且查询到账户时返回,取值:1活期 2定期 3通知 4活期保证金 5定期保证金 6其他 + AccountNo string `json:"accountNo" comment:"本方账号"` // 交易成功且查询到账户时返回 + Accuse string `json:"accuse" comment:"账户用途"` // 交易成功且查询到账户时返回 + ActInstCode string `json:"actInstCode" comment:"实际机构编码"` // 交易成功且查询到账户时返回 + ActInstId string `json:"actInstId" comment:"实际机构ID"` // 交易成功且查询到账户时返回 + ActInstName string `json:"actInstName" comment:"实际机构名称"` // 交易成功且查询到账户时返回 + AgrmLmt string `json:"agrmLmt" comment:"协议限额"` // 交易成功且查询到账户时返回 + BlngBnkId string `json:"blngBnkId" comment:"所属银行ID"` // 交易成功且查询到账户时返回 + BnkCodeId string `json:"bnkCodeId" comment:"银行编码"` // 交易成功且查询到账户时返回 + CnclacctDt string `json:"cnclacctDt" comment:"销户日期"` // 交易成功且查询到账户状态为销户时返回,格式:yyyyMMdd + CrnAcc string `json:"crnAcc" comment:"货币账号"` // 交易成功且查询到账户时返回 + CurrencyId string `json:"currencyId" comment:"币种"` // 交易成功且查询到账户时返回,格式:char(5) + DepbnkCtyId string `json:"depbnkCtyId" comment:"开户银行所在国家ID"` // 交易成功且查询到账户时返回 + InstCode string `json:"instCode" comment:"机构编码"` // 交易成功且查询到账户时返回 + InstId string `json:"instId" comment:"机构ID"` // 交易成功且查询到账户时返回 + InstName string `json:"instName" comment:"机构名称"` // 交易成功且查询到账户时返回 + IsFrgnAcc string `json:"isFrgnAcc" comment:"境内/境外账户标识"` // 交易成功且查询到账户时返回,取值:0境内 1境外 + IsMoreCurrAccId string `json:"isMoreCurrAccId" comment:"是否多币种账户"` // 交易成功且查询到账户时返回 + IsOsaId string `json:"isOsaId" comment:"是否OSA账户"` // 交易成功且查询到账户时返回 + Isopndircon string `json:"isopndircon" comment:"联网方式"` // 交易成功且查询到账户时返回,取值:0非直联 1直联 + LastUdtTms string `json:"lastUdtTms" comment:"最后更新时间"` // 交易成功且查询到账户时返回,格式:yyyy-MM-dd HH:mm:ss + MainAccId string `json:"mainAccId" comment:"主账户ID"` // 交易成功且查询到账户时返回 + MainAccNm string `json:"mainAccNm" comment:"主账户名称"` // 交易成功且查询到账户时返回 + MainAccNum string `json:"mainAccNum" comment:"主账户账号"` // 交易成功且查询到账户时返回 + OpnacctBrBic string `json:"opnacctBrBic" comment:"开户支行BIC码"` // 交易成功且查询到账户时返回 + OpnacctBrId string `json:"opnacctBrId" comment:"开户支行ID"` // 交易成功且查询到账户时返回 + OpnacctBrIdChar string `json:"opnacctBrIdChar" comment:"开户支行字符ID"` // 交易成功且查询到账户时返回 + OpnacctBrIdnum string `json:"opnacctBrIdnum" comment:"开户支行数字ID"` // 交易成功且查询到账户时返回 + OpnacctCityId string `json:"opnacctCityId" comment:"开户城市ID"` // 交易成功且查询到账户时返回 + OpnacctDt string `json:"opnacctDt" comment:"开户日期"` // 交易成功且查询到账户时返回,格式:yyyyMMdd + OpnacctProvId string `json:"opnacctProvId" comment:"开户省份ID"` // 交易成功且查询到账户时返回 + } + + ReceiptQueryResp struct { + Status string `json:"status" comment:"交易状态"` // 交易状态 + StatusText string `json:"statusText" comment:"交易状态信息"` // 交易状态结果描述 + FailReason string `json:"failReason" comment:"错误信息展示"` // 校验失败时,失败原因展示(可选) + TotRcptStat string `json:"totRcptStat" comment:"总回单查询状态"` // 总回单查询状态:1-全部成功(终态);2-部分成功;3-部分成功部分失败(终态) + TotalRecords string `json:"totalRecords" comment:"回单总记录条数"` // 交易成功时返回,用户有查询权限的所有账户数量(可选) + ReturnRecords string `json:"returnRecords" comment:"返回记录条数"` // 交易成功时返回,本次查询获取到的账户数量(可选) + UserDataList []UserData `json:"userDataList" comment:"回单数据列表"` // 成功查询的回单数据列表 + UserUnsuccList []UnsuccData `json:"userUnsuccList" comment:"查询失败数据列表"` // 查询失败的回单数据列表 + } + + // UserData 回单明细数据 + UserData struct { + Date string `json:"date" comment:"回单日期"` // 回单日期(可选) + RcptNum string `json:"rcptNum" comment:"回单编号"` // 回单编号(可选) + ExternalNum string `json:"externalNum" comment:"外部请求流水号"` // 对方行支持明细对账时返回(可选) + ExternalBatNum string `json:"externalBatNum" comment:"外部请求批次号"` // 对方行支持明细对账且批量支付时返回(可选) + BnkSrlnum string `json:"bnkSrlnum" comment:"银行流水号"` // 交易成功且查询到回单时返回(可选) + TxnDt string `json:"txnDt" comment:"交易时间"` // 交易时间(yyyymmdd格式) + PyAccnum string `json:"pyAccnum" comment:"本方账号"` // 本方账号 + OpnBnkNm string `json:"opnBnkNm" comment:"本方开户行"` // 本方开户行 + PyAccnm string `json:"pyAccnm" comment:"本方户名"` // 本方户名 + RcvpyAccnum string `json:"rcvpyAccnum" comment:"对方账号"` // 对方账号(可选) + RcvpyAccnm string `json:"rcvpyAccnm" comment:"对方户名"` // 对方户名(可选) + CptBnkNm string `json:"cptBnkNm" comment:"对方开户行"` // 对方开户行(可选) + TxnTp string `json:"txnTp" comment:"交易类型"` // 交易类型 + TxnAmt string `json:"txnAmt" comment:"交易金额"` // 交易金额(格式如:132134.3230) + Curr string `json:"curr" comment:"币种"` // 币种(人民币、美元等) + Lvmsg string `json:"lvmsg" comment:"附言"` // 附言(可选) + Smy string `json:"smy" comment:"摘要"` // 摘要(可选) + } + + UnsuccData struct { + Date string `json:"date" comment:"数据日期"` // 数据日期 + RcptStat string `json:"rcptStat" comment:"回单状态"` // 回单状态:1-查询中;2-查询失败 + Message string `json:"message" comment:"未查询数据原因"` // 未查询数据原因 + } + + // BankEnterpriseDownloadResponse 银企直联回单下载响应参数 + ReceiptDownloadResp struct { + TotalRecords string `json:"totalRecords" comment:"总记录条数"` // 成功时返回,用户具有查询权限的所有账户数量(int,选填) + ReturnRecords string `json:"returnRecords" comment:"返回记录条数"` // 成功时返回,本次查询获取到的账户数量(int,选填) + List []DownloadResRow `json:"list" comment:"回单文件列表"` // 回单文件明细列表(选填) + FileContent string `json:"fileContent" comment:"回单汇总文件内容"` // Base64编码的压缩文件内容(varchar(2097152),选填) + FileName string `json:"fileName" comment:"回单汇总文件名称"` // 汇总文件名(varchar(128),选填) + Size string `json:"size" comment:"文件大小"` // 文件大小(单位:字节,int,选填) + } + + // DownloadRow 单个回单文件信息 + DownloadResRow struct { + RcptNum string `json:"rcptNum" comment:"回单编号"` // 回单编号(varchar(200),选填) + PdfName string `json:"pdfName" comment:"回单文件名称"` // 单个回单文件名(varchar(256),选填) + } +) diff --git a/tysk_test.go b/tysk_test.go index aeae607..8ec90c8 100644 --- a/tysk_test.go +++ b/tysk_test.go @@ -1,12 +1,69 @@ package tysk -import "testing" +import ( + "gitea.cdlsxd.cn/self-tools/tysk/tysk_constant" + "gitea.cdlsxd.cn/self-tools/tysk/tysk_entity" + "testing" +) const UserName = "LSXDWL003_ZL" var g = NewTysk(UserName, WithEnvTest()) func Test_GetAccountBalance(t *testing.T) { - res, err := g.GetAccountBalance([]string{"8110701013301269598", "8110701012401269599", "8110701013801269600"}) + req := tysk_entity.GetAccountBalanceReq{ + AccountNo: []tysk_constant.AccountNo{"8110701013301269598", "8110701012401269599", "8110701013801269600"}, + } + res, err := g.GetAccountBalance(req) + t.Log(res, err) +} + +func Test_GetTodayTransHis(t *testing.T) { + req := tysk_entity.TodayTransHisReq{ + AccountNo: []tysk_constant.AccountNo{"8110701013301269598", "8110701012401269599", "8110701013801269600"}, + TranType: tysk_constant.TranType("01"), + StartRecord: 1, + PageNumber: 10, + } + res, err := g.GetTodayTransHis(req) + t.Log(res, err) +} + +func Test_GetAccountInfo(t *testing.T) { + req := tysk_entity.AccountInfoReq{ + StartRecord: 1, + PageNumber: 10, + } + res, err := g.GetAccountInfo(req) + t.Log(res, err) +} + +func Test_ReceiptApply(t *testing.T) { + req := tysk_entity.ReceiptApplyReq{ + ClientID: "test123123", + AccountNo: "8110701012401269599", + StartDate: "20250730", + EndDate: "20250801", + } + res, err := g.ReceiptApply(req) + t.Log(res, err) +} + +func Test_ReceiptQuery(t *testing.T) { + req := tysk_entity.ReceiptQueryReq{ + ClientID: "test123123", + StartRecord: 1, + PageNumber: 10, + } + res, err := g.ReceiptQuery(req) + t.Log(res, err) +} + +func Test_ReceiptDownload(t *testing.T) { + req := tysk_entity.ReceiptDownloadReq{ + FileType: tysk_constant.FileTypePDF, + RcptNums: []string{"8110701012401269599_20250730SG0D0000084253000001"}, + } + res, err := g.ReceiptDownload(req) t.Log(res, err) }