package api import ( "crypto/rand" "crypto/tls" "encoding/base64" "encoding/hex" "encoding/json" "fmt" "math/big" "net/http" "net/url" "strconv" "time" "github.com/tjfoc/gmsm/sm2" "github.com/tjfoc/gmsm/x509" ) // CompanyInfoService 公司信息查询服务 type CompanyInfoService struct { httpClient *HTTPClient userID string privateKey string } // TaxHealthService 税务健康测评服务 type TaxHealthService struct { httpClient *HTTPClient userID string privateKey string } // CompanyInfoRequest 公司信息查询请求 type CompanyInfoRequest struct { Name string `json:"name"` Apis []string `json:"apis"` } // CompanyInfoResponse 公司信息查询响应 type CompanyInfoResponse struct { Code int `json:"code"` Message string `json:"message"` Data map[string]interface{} `json:"data"` } // TaxEvalRequest 税务测评请求 type TaxEvalRequest struct { ReqNo string `json:"req_no"` Callback string `json:"callback,omitempty"` Detail TaxEvalDetail `json:"detail"` } // TaxEvalDetail 税务测评详情 type TaxEvalDetail struct { FileURL string `json:"file_url,omitempty"` Data map[string]interface{} `json:"data,omitempty"` CompanyName string `json:"company_name"` Period string `json:"period"` Year string `json:"year"` IsVerify bool `json:"is_verify,omitempty"` CIT float64 `json:"cit"` VAT float64 `json:"vat"` InputVAT float64 `json:"input_vat"` OutputVAT float64 `json:"output_vat"` PreCIT float64 `json:"pre_cit"` PreVAT float64 `json:"pre_vat"` PreInputVAT float64 `json:"pre_input_vat"` PreOutputVAT float64 `json:"pre_output_vat"` } // TaxEvalResponse 税务测评响应 type TaxEvalResponse struct { Code int `json:"code"` Message string `json:"msg"` Data struct { ReqNo string `json:"req_no"` OrderNo string `json:"order_no"` } `json:"data"` } // TaxEvalQueryResponse 查询税务测评结果响应 type TaxEvalQueryResponse struct { Code int `json:"code"` Message string `json:"msg"` Data struct { Status string `json:"status,omitempty"` Detail struct { Files []string `json:"files,omitempty"` Error string `json:"error,omitempty"` } `json:"detail,omitempty"` } `json:"data"` } // NewCompanyInfoService 创建公司信息查询服务 func NewCompanyInfoService(userID, privateKey string) *CompanyInfoService { tr := &http.Transport{ TLSClientConfig: &tls.Config{ InsecureSkipVerify: true, }, } client := &http.Client{ Transport: tr, Timeout: 30 * time.Second, } httpClient := &HTTPClient{Client: client} return &CompanyInfoService{ httpClient: httpClient, userID: userID, privateKey: privateKey, } } // NewTaxHealthService 创建税务健康测评服务 func NewTaxHealthService(userID, privateKey string) *TaxHealthService { tr := &http.Transport{ TLSClientConfig: &tls.Config{ InsecureSkipVerify: true, }, } client := &http.Client{ Transport: tr, Timeout: 60 * time.Second, } httpClient := &HTTPClient{Client: client} return &TaxHealthService{ httpClient: httpClient, userID: userID, privateKey: privateKey, } } // GetCompanyInfo 查询公司信息 func (s *CompanyInfoService) GetCompanyInfo(companyName string, apis []string) (*CompanyInfoResponse, error) { // 构建查询参数 params := url.Values{} params.Set("name", companyName) params.Set("api", joinAPIParams(apis)) apiURL := "https://a.cmdp.cn/cmds/v1/company/info-rest/custom?" + params.Encode() // 设置请求头 headers := map[string]string{ "Accept": "application/json", } // 发送GET请求 response, err := s.httpClient.Get(apiURL, headers) if err != nil { return nil, fmt.Errorf("发送请求失败: %v", err) } var result CompanyInfoResponse err = json.Unmarshal(response, &result) if err != nil { return nil, fmt.Errorf("解析响应失败: %v", err) } return &result, nil } // EvaluateTaxHealth 执行税务健康测评 func (s *TaxHealthService) EvaluateTaxHealth(request TaxEvalRequest) (*TaxEvalResponse, error) { // 生成随机数和时间戳 nonce := "123456" timestamp := strconv.FormatInt(time.Now().Unix()*1000, 10) apiURL := "https://api.cmdp.cn/v1/eval/tax-risk" // 序列化请求体 jsonData, err := json.Marshal(request) jsonDataStr := string(jsonData) if err != nil { return nil, fmt.Errorf("序列化请求体失败: %v", err) } // 生成签名 signData := s.userID + timestamp + nonce + apiURL + jsonDataStr signature, err := s.generateSignature([]byte(signData)) if err != nil { return nil, fmt.Errorf("生成签名失败: %v", err) } // 设置请求头 headers := map[string]string{ "Content-Type": "application/json", "Accept": "application/json", "x-gi-user-id": s.userID, "x-gi-user-sig": signature, "x-gi-nonce": nonce, "x-gi-timestamp": timestamp, } // 发送POST请求 response, err := s.httpClient.Post(apiURL, []byte(jsonDataStr), "application/json", headers) if err != nil { return nil, fmt.Errorf("发送请求失败: %v", err) } var result TaxEvalResponse err = json.Unmarshal(response, &result) if err != nil { return nil, fmt.Errorf("解析响应失败: %v", err) } return &result, nil } // QueryTaxEvalResult 查询税务测评结果 func (s *TaxHealthService) QueryTaxEvalResult(orderNo string) (*TaxEvalQueryResponse, error) { // 生成随机数和时间戳 nonce := "123456" timestamp := strconv.FormatInt(time.Now().Unix()*1000, 10) apiURL := fmt.Sprintf("https://api.cmdp.cn/v1/eval/order/%s", orderNo) // 生成签名 signData := s.userID + timestamp + nonce + apiURL signature, err := s.generateSignature([]byte(signData)) if err != nil { return nil, fmt.Errorf("生成签名失败: %v", err) } // 设置请求头 headers := map[string]string{ "Accept": "application/json", "x-gi-user-id": s.userID, "x-gi-user-sig": signature, "x-gi-nonce": nonce, "x-gi-timestamp": timestamp, } // 发送GET请求 response, err := s.httpClient.Get(apiURL, headers) if err != nil { return nil, fmt.Errorf("发送请求失败: %v", err) } var result TaxEvalQueryResponse err = json.Unmarshal(response, &result) if err != nil { return nil, fmt.Errorf("解析响应失败: %v", err) } return &result, nil } // generateSignature 生成签名 func (s *CompanyInfoService) generateSignature(plainText []byte) (string, error) { return sign(plainText, s.privateKey) } func sign(data []byte, privateKeyHex string) (string, error) { prvKeyBytes, err := hex.DecodeString(privateKeyHex) if err != nil { return "", fmt.Errorf("failed to decode private key hex: %v", err) } var prvKey *sm2.PrivateKey if pkcs8Key, err := x509.ParsePKCS8PrivateKey(prvKeyBytes, nil); err == nil { prvKey = pkcs8Key } else { prvKey = &sm2.PrivateKey{} prvKey.Curve = sm2.P256Sm2() prvKey.D = new(big.Int).SetBytes(prvKeyBytes) if prvKey.D.Sign() == 0 { return "", fmt.Errorf("failed to parse private key") } prvKey.PublicKey.Curve = sm2.P256Sm2() prvKey.PublicKey.X, prvKey.PublicKey.Y = prvKey.PublicKey.Curve.ScalarBaseMult(prvKey.D.Bytes()) } // 使用空 UID uid := []byte{} r, s, err := sm2.Sm2Sign(prvKey, data, uid, rand.Reader) if err != nil { return "", fmt.Errorf("sign failed: %v", err) } sig, err := sm2.SignDigitToSignData(r, s) if err != nil { return "", fmt.Errorf("marshal signature failed: %v", err) } return base64.StdEncoding.EncodeToString(sig), nil } // generateSignature 生成签名 func (s *TaxHealthService) generateSignature(plainText []byte) (string, error) { return sign(plainText, s.privateKey) } // joinAPIParams 连接API参数 func joinAPIParams(params []string) string { result := "" for i, param := range params { if i > 0 { result += "," } result += param } return result } // 使用示例 func ExampleUsage() { // 替换为实际的用户ID和私钥 userID := "your_user_id" privateKey := "your_private_key_hex" // 创建公司信息查询服务 companyService := NewCompanyInfoService(userID, privateKey) // 查询公司信息 companyInfo, err := companyService.GetCompanyInfo("深圳市致远速联信息技术有限公司", []string{"p_info", "p_biddings_all"}) if err != nil { fmt.Printf("查询公司信息失败: %v\n", err) } else { fmt.Printf("公司信息查询结果: %+v\n", companyInfo) } // 创建税务健康测评服务 taxService := NewTaxHealthService(userID, privateKey) // 准备税务测评请求数据 request := TaxEvalRequest{ ReqNo: "REQ001", Detail: TaxEvalDetail{ CompanyName: "深圳市致远速联信息技术有限公司", Period: "年度", Year: "2024", CIT: 100.0, VAT: 50.0, InputVAT: 30.0, OutputVAT: 80.0, PreCIT: 90.0, PreVAT: 45.0, PreInputVAT: 25.0, PreOutputVAT: 70.0, }, } // 执行税务测评 evalResult, err := taxService.EvaluateTaxHealth(request) if err != nil { fmt.Printf("税务测评失败: %v\n", err) } else { fmt.Printf("税务测评提交结果: %+v\n", evalResult) // 查询测评结果 if evalResult.Data.OrderNo != "" { result, err := taxService.QueryTaxEvalResult(evalResult.Data.OrderNo) if err != nil { fmt.Printf("查询测评结果失败: %v\n", err) } else { fmt.Printf("测评结果: %+v\n", result) } } } }