package qiyuesuosdk import ( "encoding/json" "fmt" "net/url" "strconv" "strings" "time" "git.sxidc.com/student-physical-examination/contract_lock_sdk/model/common" user_request "git.sxidc.com/student-physical-examination/contract_lock_sdk/model/user/request" v2auth_request "git.sxidc.com/student-physical-examination/contract_lock_sdk/model/v2auth/request" v2auth_response "git.sxidc.com/student-physical-examination/contract_lock_sdk/model/v2auth/response" ) // FindUserByAccountNo 按 accountNo(通常等于 openUserId)查询用户。 func (c *Client) FindUserByAccountNo(accountNo string) (*UserInfo, error) { type result struct { Name string `json:"name"` } var resp struct { apiResponse Result result `json:"result"` } q := url.Values{"accountNo": {accountNo}} if err := c.getQuery("/user", q, &resp); err != nil { return nil, err } if err := resp.err(); err != nil { return nil, err } if resp.Result.Name == "" { return nil, nil } return &UserInfo{Name: resp.Result.Name}, nil } // CreateInternalUser 在契约锁创建内部用户。 func (c *Client) CreateInternalUser(p CreateUserParams) error { req := user_request.UserV2CreateRequest{ Name: p.Name, OpenUserId: p.OpenUserID, AccountNo: p.AccountNo, Password: p.Password, Mobile: p.Mobile, } if req.AccountNo == "" { req.AccountNo = p.OpenUserID } var resp apiResponse if err := c.postJSON("/user/v2/create", req, &resp); err != nil { return err } return resp.err() } // CreateInternalUserSkipMobileConflict 创建用户;手机号冲突时去掉手机号重试(旧系统行为)。 func (c *Client) CreateInternalUserSkipMobileConflict(p CreateUserParams) error { err := c.CreateInternalUser(p) if err == nil { return nil } if p.Mobile != "" && strings.Contains(err.Error(), "手机号已被其他用户绑定") { p.Mobile = "" return c.CreateInternalUser(p) } return err } // UserSignSilentURL 获取个人签名静默授权页;authEnd 为空则默认 10 个月。 func (c *Client) UserSignSilentURL(openUserID string, authEnd time.Time, completeToPage string) (string, error) { if authEnd.IsZero() { authEnd = time.Now().Add(DefaultPersonalAuthDuration) } timeEditable := false req := v2auth_request.V2AuthPersonalsignsilentUrlRequest{ AuthUser: &common.SilentUserRequest{OpenUserId: openUserID}, AuthEndDate: authEnd.Format("2006-01-02"), AuthTimeModifiable: &timeEditable, AuthorizedMode: []string{"FACEAUTH", "PINAUTH"}, CompleteToPage: completeToPage, } var resp struct { apiResponse Result v2auth_response.V2AuthPersonalsignsilentUrlResponse `json:"result"` } if err := c.postJSON("/v2/auth/personalsignsilent/url", req, &resp); err != nil { return "", err } if err := resp.err(); err != nil { return "", err } return resp.Result.Url, nil } // QueryPersonalSignAuthRecords 查询个人静默授权记录。 func (c *Client) QueryPersonalSignAuthRecords(openUserID, status string) ([]AuthRecord, error) { req := v2auth_request.V2AuthSignsilentRecordRequest{ AuthUser: &common.UserInfoRequest{OpenUserId: openUserID}, Status: status, } var resp struct { apiResponse Result []v2auth_response.V2AuthSignsilentRecordResponse `json:"result"` } if err := c.postJSON("/v2/auth/signSilent/record", req, &resp); err != nil { return nil, err } if err := resp.err(); err != nil { return nil, err } out := make([]AuthRecord, 0, len(resp.Result)) for _, item := range resp.Result { out = append(out, AuthRecord{ Status: item.Status, EndTime: item.AuthEndDate, AuthScope: item.AuthScope, }) } return out, nil } // IsUserSignAuthorized 是否存在有效个人静默授权。 func (c *Client) IsUserSignAuthorized(openUserID string) (bool, error) { records, err := c.QueryPersonalSignAuthRecords(openUserID, "EFFECT") if err != nil { return false, err } return len(records) > 0, nil } // structFormFields 将 struct 转为 multipart 表单字段(与旧系统 HttpMultipart 行为一致)。 func structFormFields(v any, arrayConnector string) (map[string]string, error) { b, err := json.Marshal(v) if err != nil { return nil, err } var raw map[string]any if err = json.Unmarshal(b, &raw); err != nil { return nil, err } out := make(map[string]string, len(raw)) for k, val := range raw { switch t := val.(type) { case nil: continue case string: out[k] = t case bool: out[k] = strconv.FormatBool(t) case float64: out[k] = strconv.FormatInt(int64(t), 10) case []any: parts := make([]string, 0, len(t)) for _, item := range t { parts = append(parts, fmt.Sprint(item)) } out[k] = strings.Join(parts, arrayConnector) default: out[k] = fmt.Sprint(val) } } return out, nil }