Files
baseapi/platformapi/jdapi/store_page.go
邹宗楠 dd9f657333 1
2023-09-25 18:36:23 +08:00

1441 lines
54 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package jdapi
import (
"bytes"
"crypto/md5"
"fmt"
"io/ioutil"
"mime/multipart"
"net/http"
"net/url"
"regexp"
"strings"
"time"
"git.rosy.net.cn/baseapi"
"git.rosy.net.cn/baseapi/platformapi"
"git.rosy.net.cn/baseapi/utils"
)
const (
getStoreURL = "https://daojia.jd.com"
AccessStorePageCookieName = "shop.o2o.jd.com1"
AccessStorePageCookieName2 = "lsp-store1.jddj.com"
accessStorePageCookieName3 = "josl-privilege1.jddj.com"
accessStorePageCookieName4 = "o2o-stock1.jddj.com"
accessStorePageCookieName5 = "sta-store.jddj.com"
)
var (
interfaceMap = map[string][]interface{}{
"bcda6aa3af904158840520d746d97692": []interface{}{"message.djsw.orderAccounting", 0}, //订单应结消息
"c716ba1e882a4334975d773eb2436eb4": []interface{}{"message.djsw.financeAdjustment", -2}, //财务调整单消息
"0becae34d53345febfea238e3785d9fe": []interface{}{"message.djsw.pickFinishOrder", 0}, //拣货完成消息
"e5501ab3bb2d4e6e82cd9affb27f1b12": []interface{}{"message.djsw.deliveryOrder", 0}, //订单开始配送消息
"4acf6346a6b942629ce4b143160ecc0d": []interface{}{"message.djsw.finishOrder", 0}, //订单妥投消息
"4fa7419b8c7440f887b4f4df5bee85fd": []interface{}{"message.djsw.lockOrder", 0}, //订单锁定消息
"e95911589479472e8b6f4d099ad343b5": []interface{}{"message.djsw.userCancelOrder", 0}, //用户取消消息
"f93ddfb7034b468da4d1ef10abe4b3ab": []interface{}{"message.djsw.newOrder", 0}, //创建新订单消息
"29fa5e8542614661ac43410b9273dba6": []interface{}{"message.djsw.applyCancelOrder", 0}, // 用户申请取消消息
"46f6414b799b416c92be9b890cc985ca": []interface{}{"message.djsw.orderAdjust", 0}, // 订单调整消息
"fe2896ec5a394a66ab1bca084c29eb70": []interface{}{"message.djsw.pushDeliveryStatus", 0}, //订单运单状态消息
"baa8f6128b1d4a46a8c969d3a3b2016f": []interface{}{"message.djsw.orderInfoChange", 0}, //订单信息变更消息
"68d84d873729471db4d9c6d987dd8eb8": []interface{}{"message.djsw.orderWaitOutStore", 0}, //订单等待出库消息
"bf3c0d18127b4c2982a806c415a7e0d5": []interface{}{"message.djsw.orderAddTips", 0}, //订单商家小费消息
"7ce971a2a8c24437b4734f805f86bb34": []interface{}{"message.djsw.unlockOrder", 0}, // 订单解锁消息
"2feddf4f8a17447791c4872b9134cdb5": []interface{}{"message.djsw.deliveryCarrierModify", 0}, //订单转自送消息
"052798b978024574af96209e089168ed": []interface{}{"message.djsw.venderAuditApplyCancelOrder", 0}, //商家审核用户取消申请消息
"1cbf43a35fcd4212809414e8c57d400a": []interface{}{"message.djsw.newAfterSaleBill", -3}, //创建售后单消息
"6ebe1528c39b436b8cbf5a2a75d06d8b": []interface{}{"message.djsw.afterSaleBillStatus", 0}, //售后单状态消息
"6b6906f334884aeb88ba7d3ffaa9c688": []interface{}{"message.djsw.newApplyAfterSaleBill", -3}, //创建售后单申请消息
"1f6da863a76b43d3a44dbe737b733240": []interface{}{"message.djsw.updateApplyAfterSaleBill", -3}, //修改售后单申请消息
}
)
type SkuPageImg struct {
Big string `json:"big"`
Share string `json:"share"`
Small string `json:"small"`
}
type CorporationInfo struct {
Scope string `json:"scope"`
OperName string `json:"oper_name"`
Status string `json:"status"`
BelongOrg string `json:"belong_org"`
CreditNo string `json:"credit_no"`
RegNo string `json:"reg_no"`
ID string `json:"id"`
OrgNo string `json:"org_no"`
EconKind string `json:"econ_kind"`
EndDate string `json:"end_date"`
TermEnd string `json:"term_end"`
// NeedID bool `json:"needID"`
Address string `json:"address"`
Partners []struct {
IdentifyType string `json:"identify_type"`
ShouldCapiItems []interface{} `json:"should_capi_items"`
StockType string `json:"stock_type"`
IdentifyNo string `json:"identify_no"`
RealCapiItems []interface{} `json:"real_capi_items"`
Name string `json:"name"`
} `json:"partners"`
Name string `json:"name"`
Province string `json:"province"`
TermStart string `json:"term_start"`
AbnormalItems []interface{} `json:"abnormal_items"`
CheckDate string `json:"check_date"`
RegistCapi string `json:"regist_capi"`
StartDate string `json:"start_date"`
Changerecords []struct {
BeforeContent string `json:"before_content"`
ChangeDate string `json:"change_date"`
ChangeItem string `json:"change_item"`
AfterContent string `json:"after_content"`
} `json:"changerecords"`
Branches []interface{} `json:"branches"`
Employees []struct {
JobTitle string `json:"job_title"`
Name string `json:"name"`
} `json:"employees"`
}
type GetOrderDetailByLicenseImg struct {
Id interface{} `json:"id"`
ApprovalId interface{} `json:"approvalId"`
StationNo interface{} `json:"stationNo"`
VenderId interface{} `json:"venderId"`
QualifyUrl interface{} `json:"qualifyUrl"`
QualifyType int `json:"qualifyType"`
QualifyName string `json:"qualifyName"`
QualifyExpireStart interface{} `json:"qualifyExpireStart"`
QualifyExpireEnd interface{} `json:"qualifyExpireEnd"`
QualifyExpireForever int `json:"qualifyExpireForever"`
QualifyOwner interface{} `json:"qualifyOwner"`
QualifyNumber string `json:"qualifyNumber"`
QualifyAddress string `json:"qualifyAddress"`
CreatePin interface{} `json:"createPin"`
CreateTime interface{} `json:"createTime"`
QualifyPin interface{} `json:"qualifyPin"`
QualifyTime interface{} `json:"qualifyTime"`
Yn interface{} `json:"yn"`
Type interface{} `json:"type"`
LicenceType interface{} `json:"licenceType"`
LicenceName string `json:"licenceName"`
EconKind string `json:"econKind"`
FirmStatus interface{} `json:"firmStatus"`
Scope string `json:"scope"`
QualifyIdList interface{} `json:"qualifyIdList"`
NeedQualifyFlag int `json:"needQualifyFlag"`
QualifyExpireStartForWeb string `json:"qualifyExpireStartForWeb"`
QualifyExpireEndForWeb interface{} `json:"qualifyExpireEndForWeb"`
QualifyNumberList interface{} `json:"qualifyNumberList"`
StationNoList interface{} `json:"stationNoList"`
}
type PageShopInfo struct {
DisCatName string `json:"disCatName"`
DisplayType string `json:"displayType"`
FreightWords string `json:"freightWords"`
IsCart bool `json:"isCart"`
IsJb int `json:"isJb"`
IsWithHome bool `json:"isWithHome"`
LogoURL string `json:"logoUrl"`
StoreActPageList []interface{} `json:"storeActPageList"`
StoreCommentVO struct {
BuyerShowName string `json:"buyerShowName"`
CreateTime string `json:"createTime"`
IsOrgComment int `json:"isOrgComment"`
OrgCommentContent string `json:"orgCommentContent"`
Score4 int `json:"score4"`
Score4Content string `json:"score4Content"`
ScoreAvg float64 `json:"scoreAvg"`
ShowTotalCount bool `json:"showTotalCount"`
Skus []interface{} `json:"skus"`
StoreStar float64 `json:"storeStar"`
TagInfoItemList []string `json:"tagInfoItemList"`
TotalCount int `json:"totalCount"`
} `json:"storeCommentVO"`
StoreDesc string `json:"storeDesc"`
StoreInfo struct {
BackgroundType string `json:"backgroundType"`
CarrierNo int `json:"carrierNo"`
CloseStatus int `json:"closeStatus"`
DeliveryFirst string `json:"deliveryFirst"`
DeliverySecond string `json:"deliverySecond"`
ExpectArrivedTips []struct {
Msg string `json:"msg"`
Type int `json:"type"`
} `json:"expectArrivedTips"`
Flag bool `json:"flag"`
FollowNo string `json:"followNo"`
FreightTag struct {
BelongIndustry int `json:"belongIndustry"`
Type int `json:"type"`
Words string `json:"words"`
} `json:"freightTag"`
FreightWords string `json:"freightWords"`
InSaleNum string `json:"inSaleNum"`
Industry string `json:"industry"`
IsFollow bool `json:"isFollow"`
IsMembership bool `json:"isMembership"`
IsOverZone bool `json:"isOverZone"`
IsTimeFight int `json:"isTimeFight"`
LogoURL string `json:"logoUrl"`
MonthSaleNum string `json:"monthSaleNum"`
OrgCode string `json:"orgCode"`
Params string `json:"params"`
SearchLinkageFlag bool `json:"searchLinkageFlag"`
ServiceTimes []struct {
EndTime string `json:"endTime"`
StartTime string `json:"startTime"`
} `json:"serviceTimes"`
ShowType string `json:"showType"`
StationStatus int `json:"stationStatus"`
StoreAddress string `json:"storeAddress"`
StoreCertificateURL string `json:"storeCertificateUrl"`
StoreID string `json:"storeId"`
StoreName string `json:"storeName"`
StoreTel string `json:"storeTel"`
To string `json:"to"`
UpToSendprice int `json:"upToSendprice"`
} `json:"storeInfo"`
StoreShareURL string `json:"storeShareUrl"`
}
type PageSku struct {
ButtonEnable bool `json:"buttonEnable"`
CatID string `json:"catId"`
FixedStatus bool `json:"fixedStatus"`
FuncIndicatins string `json:"funcIndicatins"`
H5SwichItem struct {
IsLeadApp bool `json:"isLeadApp"`
} `json:"h5SwichItem"`
HasSaleAttr bool `json:"hasSaleAttr"`
IconType int `json:"iconType"`
Image []*SkuPageImg `json:"image"`
InCartCount int `json:"inCartCount"`
IsInScope bool `json:"isInScope"`
IsRemind bool `json:"isRemind"`
MarkingPrice string `json:"markingPrice"`
Name string `json:"name"`
OrgCode string `json:"orgCode"`
Prescription bool `json:"prescription"`
PriceUnit string `json:"priceUnit"`
ProductComment struct {
CommentNum string `json:"commentNum"`
GoodRate float64 `json:"goodRate"`
GoodRating string `json:"goodRating"`
HasMore bool `json:"hasMore"`
TotalScore string `json:"totalScore"`
} `json:"productComment"`
ProductInfoType int `json:"productInfoType"`
ProductType int `json:"productType"`
ProductTypeEnum string `json:"productTypeEnum"`
ShareProductURL string `json:"shareProductUrl"`
ShowState int `json:"showState"`
ShowStateEnum string `json:"showStateEnum"`
ShowStateName string `json:"showStateName"`
ShowTimLine bool `json:"showTimLine"`
SkuID int64 `json:"skuId"`
SkuPriceVO struct {
BasicPrice string `json:"basicPrice"`
MkPrice string `json:"mkPrice"`
Promotion int `json:"promotion"`
RealTimePrice string `json:"realTimePrice"`
SkuID string `json:"skuId"`
} `json:"skuPriceVO"`
Standard string `json:"standard"`
StoreInfo struct {
Show bool `json:"show"`
StoreID string `json:"storeId"`
} `json:"storeInfo"`
Subtitle string `json:"subtitle"`
Tags []string `json:"tags"`
UserActionSku string `json:"userActionSku"`
VenderID string `json:"venderId"`
}
type StoreUserInfo struct {
Cn string `json:"cn"`
CreateApp string `json:"createApp"`
CreatePin string `json:"createPin"`
CreateTime *utils.JavaDate `json:"createTime"`
DefaultPwdType interface{} `json:"defaultPwdType"`
Email interface{} `json:"email"`
ErpAccount interface{} `json:"erpAccount"`
ExtFields struct {
OrgName string `json:"orgName"`
} `json:"extFields"`
ID int `json:"id"`
JdPin interface{} `json:"jdPin"`
LastLoginTime interface{} `json:"lastLoginTime"`
LockStatus string `json:"lockStatus"`
LoginCredentials interface{} `json:"loginCredentials"`
LoginFailCount int `json:"loginFailCount"`
LoginName string `json:"loginName"`
OrgCode string `json:"orgCode"`
OrgID int `json:"orgId"`
PartTimeOrgIds interface{} `json:"partTimeOrgIds"`
Phone string `json:"phone"`
Remark interface{} `json:"remark"`
RoleNameStr string `json:"roleNameStr"`
Roles interface{} `json:"roles"`
SortNo int `json:"sortNo"`
Status int `json:"status"`
SysVersion int `json:"sysVersion"`
UpdatePin interface{} `json:"updatePin"`
UpdateTime interface{} `json:"updateTime"`
UserCode string `json:"userCode"`
}
type ProductInfo struct {
OriginalName string `json:"originalName"`
OriginalSpec string `json:"originalSpec"`
Name string `json:"name"`
Img string `json:"img"`
ImgList []string `json:"imgList"`
SpecQuality float32 `json:"specQuality"`
SpecUnit string `json:"specUnit"`
Unit string `json:"unit"`
Weight float32 `json:"weight"`
Price int `json:"price"`
Categories []string `json:"categories"`
ManName string `json:"manName"` // 生产商
BrandName string `json:"brandName"`
UpcCode string `json:"upcCode"`
}
const (
QualifyTypeCompany = "25" // 营业执照
QualifyTypePerson = "22" // 身份证,个体工商户要求填
QualifyTypeAddInfo = "31" // 附加信息,如果身份证是长期有效,要求身份证背面信息
SaveQualifyActionTypeCommit = 0 // 提交
SaveQualifyActionTypeSave = 1 // 暂时保存
JdUserStatusEnable = 0 //启用
JdUserStatusDisable = 1 //禁用
)
type QualifyItem struct {
QualifyURL string `json:"qualifyUrl"`
QualifyType string `json:"qualifyType"`
QualifyExpireForever int `json:"qualifyExpireForever"` // 0永久有性1非永久有效需要填QualifyExpireEnd
QualifyExpireStart string `json:"qualifyExpireStart"`
QualifyExpireEnd string `json:"qualifyExpireEnd,omitempty"`
QualifyName string `json:"qualifyName,omitempty"`
QualifyOwner string `json:"qualifyOwner,omitempty"`
LicenceType string `json:"licenceType,omitempty"` // -1
QualifyNumber string `json:"qualifyNumber,omitempty"`
QualifyAddress string `json:"qualifyAddress,omitempty"`
LicenceName string `json:"licenceName,omitempty"`
EconKind string `json:"econKind,omitempty"`
Scope string `json:"scope,omitempty"`
}
type JdUserPostResult struct {
Record interface{} `json:"record"`
RecordID string `json:"recordId"`
Status struct {
ErrorCode interface{} `json:"errorCode"`
Message interface{} `json:"message"`
Result string `json:"result"`
} `json:"status"`
}
type JdSkus struct {
Name string `json:name`
UpcCode string `json:upcCode`
ImgList []string `json:imgList`
}
var (
monthSaleNumReg = regexp.MustCompile(`(\d+)([千|万])`)
pageExceedLimitCodes = map[string]int{
"403": 1,
}
pageCanRetryCodes = map[string]int{}
regexpTable = regexp.MustCompile(`<table class="check-container" data-container="list1">([\s\S]*?)</table>`)
regexpTd = regexp.MustCompile(`<td>([0-9].*)</td>`)
regexpJDUserPage = regexp.MustCompile(`共([\s\S].*)页/([\s\S].*)条记录`)
regexpJDStoreSkuPage = regexp.MustCompile(`共1/(.*)页`)
regexpJDTbody = regexp.MustCompile(`<tbody>([\s\S]*?)</tbody>`)
regexpJDTr = regexp.MustCompile(`<tr>([\s\S]*?)</tr>`)
regexpJDTr2 = regexp.MustCompile(`<tr([\s\S]*?)</tr>`)
regexpJDTdInfo = regexp.MustCompile(`<td>([\s\S]*?)</td>`)
regexpJDSkuID = regexp.MustCompile(`sku编码:(.*)`)
regexpJDSkuID2 = regexp.MustCompile(`<p>SKU编码:(.*)</p>`)
regexpJDUserID = regexp.MustCompile(`value="(.*)"`)
regexpJDUserIsManager = regexp.MustCompile(`<div class="list-mask">`)
regexpJDStoreLevel = regexp.MustCompile(`门店分级 (.*)`)
regexpJDSkuDirectPrice = regexp.MustCompile(`<td style="max-width: 80px">([\s\S]*?)</td>`)
regexpJDStoreID = regexp.MustCompile(`<input class="storeInfoId" type="hidden" value="(.*?)"/>`)
regexpAppID = regexp.MustCompile(`onClick="backcode\((.*)\)"`)
htmlResponeURLs = []string{
"login-o2o.jddj.com/jpuser/",
"sta-store.jddj.com/store/",
"pms-store.jddj.com/ware",
"sta-store.jddj.com",
"openo2o.jddj.com",
}
)
const (
KeyImgData = "imgData"
KeyImgName = "imgName"
ResultKeyData = "data"
ResultKeyResult = "result"
JdUserRoleJHYId = "28926"
JdUserRoleJHYName = "【通用】拣货员"
JdUserRolesName = "多角色"
JdUserNoRole = "无角色"
)
func (a *API) SetJdCookie(cookieValue string) {
a.SetCookie(AccessStorePageCookieName, cookieValue)
a.SetCookie(AccessStorePageCookieName2, cookieValue)
a.SetCookie(accessStorePageCookieName3, cookieValue)
a.SetCookie(accessStorePageCookieName4, cookieValue)
a.SetCookie(accessStorePageCookieName5, cookieValue)
}
func (a *API) AccessStorePage2(fullURL string, params map[string]interface{}, isPost bool, resultKey string) (retVal interface{}, err error) {
if a.GetCookieCount() == 0 {
return nil, fmt.Errorf("需要设置Store Cookie才能使用此方法")
}
imgData := params[KeyImgData]
if imgData != nil {
delete(params, KeyImgData)
}
err = platformapi.AccessPlatformAPIWithRetry(a.client,
func() *http.Request {
var request *http.Request
if !isPost {
request, _ = http.NewRequest(http.MethodGet, utils.GenerateGetURL(fullURL, "", params), nil)
} else {
request, _ = http.NewRequest(http.MethodPost, fullURL, strings.NewReader(utils.Map2URLValues(params).Encode()))
if params[KeyImgName] == nil {
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
request.Header.Set("accept", "application/json, text/javascript, */*; q=0.01")
} else {
var b bytes.Buffer
w := multipart.NewWriter(&b)
if fw, err := w.CreateFormFile("uploadFile", params[KeyImgName].(string)); err != nil {
panic(err.Error())
} else {
fw.Write(imgData.([]byte))
}
for k, v := range params {
// baseapi.SugarLogger.Debug(k, " ", v)
w.WriteField(k, url.QueryEscape(fmt.Sprint(v)))
}
w.Close()
// b.WriteString(utils.Map2URLValues(params).Encode())
request, _ = http.NewRequest(http.MethodPost, fullURL, &b)
request.Header.Set("Content-Type", w.FormDataContentType())
}
request.Header.Set("charset", "UTF-8")
}
if err != nil {
return nil
}
a.FillRequestCookies(request)
return request
},
a.config,
func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) {
if jsonResult1 == nil {
return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil")
}
for _, v := range htmlResponeURLs {
if strings.Index(fullURL, v) >= 0 && jsonResult1[platformapi.KeyData] != nil {
retVal = bodyStr
return platformapi.ErrLevelSuccess, nil
}
}
retVal = jsonResult1
var errMsg string
code, ok := jsonResult1["code"].(string)
if !ok {
if statusMap, ok := jsonResult1["status"].(map[string]interface{}); !ok {
if jsonResult1["operTag"] != nil {
return platformapi.ErrLevelSuccess, nil
}
return platformapi.ErrLevelGeneralFail, utils.NewErrorCode(utils.Format4Output(jsonResult1, true), "999")
} else {
code = utils.Int64ToStr(utils.ForceInterface2Int64(statusMap["errorCode"]))
errMsg = utils.Interface2String(statusMap["message"])
}
} else {
errMsg = utils.Interface2String(jsonResult1["msg"])
}
if code == ResponseCodeSuccess {
if resultKey != "" {
retVal = jsonResult1[resultKey]
}
return platformapi.ErrLevelSuccess, nil
}
newErr := utils.NewErrorCode(errMsg, code)
if _, ok := pageExceedLimitCodes[code]; ok {
return platformapi.ErrLevelExceedLimit, newErr
} else if _, ok := pageCanRetryCodes[code]; ok {
return platformapi.ErrLevelRecoverableErr, newErr
} else {
return platformapi.ErrLevelCodeIsNotOK, newErr
}
})
return retVal, err
}
func (a *API) AccessStorePage3(fullURL string, params map[string]interface{}, resultKey string) (retVal interface{}, err error) {
if a.GetCookieCount() == 0 {
return nil, fmt.Errorf("需要设置Store Cookie才能使用此方法")
}
err = platformapi.AccessPlatformAPIWithRetry(a.client,
func() *http.Request {
request, _ := http.NewRequest(http.MethodGet, utils.GenerateGetURL(fullURL, "", params), nil)
if err != nil {
return nil
}
a.FillRequestCookies(request)
return request
},
a.config,
func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) {
if jsonResult1 == nil {
return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil")
}
retVal = jsonResult1
var errMsg string
code, ok := jsonResult1["resultCode"].(string)
if !ok {
if statusMap, ok := jsonResult1["status"].(map[string]interface{}); !ok {
if jsonResult1["operTag"] != nil {
return platformapi.ErrLevelSuccess, nil
}
return platformapi.ErrLevelGeneralFail, utils.NewErrorCode(utils.Format4Output(jsonResult1, true), "999")
} else {
code = utils.Int64ToStr(utils.ForceInterface2Int64(statusMap["errorCode"]))
errMsg = utils.Interface2String(statusMap["message"])
}
} else {
errMsg = utils.Interface2String(jsonResult1["msg"])
}
if code == "200" {
if resultKey != "" {
retVal = jsonResult1[resultKey]
}
return platformapi.ErrLevelSuccess, nil
}
newErr := utils.NewErrorCode(errMsg, code)
if _, ok := pageExceedLimitCodes[code]; ok {
return platformapi.ErrLevelExceedLimit, newErr
} else if _, ok := pageCanRetryCodes[code]; ok {
return platformapi.ErrLevelRecoverableErr, newErr
} else {
return platformapi.ErrLevelCodeIsNotOK, newErr
}
})
return retVal, err
}
func (a *API) AccessStorePage4(fullURL string, values string) (retVal interface{}, err error) {
if a.GetCookieCount() == 0 {
return nil, fmt.Errorf("需要设置Store Cookie才能使用此方法")
}
err = platformapi.AccessPlatformAPIWithRetry(a.client,
func() *http.Request {
request, _ := http.NewRequest(http.MethodPost, fullURL, strings.NewReader(values))
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
request.Header.Set("accept", "application/json, text/javascript, */*; q=0.01")
request.Header.Set("charset", "UTF-8")
a.FillRequestCookies(request)
return request
},
a.config,
func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) {
if jsonResult1 == nil {
return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil")
}
for _, v := range htmlResponeURLs {
if strings.Index(fullURL, v) >= 0 && jsonResult1[platformapi.KeyData] != nil {
retVal = bodyStr
return platformapi.ErrLevelSuccess, nil
}
}
retVal = jsonResult1
var errMsg string
code, ok := jsonResult1["code"].(string)
if !ok {
if statusMap, ok := jsonResult1["status"].(map[string]interface{}); !ok {
if jsonResult1["operTag"] != nil {
return platformapi.ErrLevelSuccess, nil
}
return platformapi.ErrLevelGeneralFail, utils.NewErrorCode(utils.Format4Output(jsonResult1, true), "999")
} else {
code = utils.Int64ToStr(utils.ForceInterface2Int64(statusMap["errorCode"]))
errMsg = utils.Interface2String(statusMap["message"])
}
} else {
errMsg = utils.Interface2String(jsonResult1["msg"])
}
if code == ResponseCodeSuccess {
return platformapi.ErrLevelSuccess, nil
}
newErr := utils.NewErrorCode(errMsg, code)
if _, ok := pageExceedLimitCodes[code]; ok {
return platformapi.ErrLevelExceedLimit, newErr
} else if _, ok := pageCanRetryCodes[code]; ok {
return platformapi.ErrLevelRecoverableErr, newErr
} else {
return platformapi.ErrLevelCodeIsNotOK, newErr
}
})
return retVal, err
}
func (a *API) AccessStorePage5(fullURL string, params map[string]interface{}) (retVal interface{}, err error) {
if a.GetCookieCount() == 0 {
return nil, fmt.Errorf("需要设置Store Cookie才能使用此方法")
}
err = platformapi.AccessPlatformAPIWithRetry(a.client,
func() *http.Request {
request, _ := http.NewRequest(http.MethodPost, fullURL, strings.NewReader(utils.Map2URLValues(params).Encode()))
if err != nil {
return nil
}
request.Header.Set("content-type", "application/x-www-form-urlencoded")
request.Header.Set("referer", "https://mermem-sj.jddj.com/memberQuery/memberQueryTransList")
request.Header.Set("origin", "https://mermem-sj.jddj.com")
a.FillRequestCookies(request)
return request
},
a.config,
func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) {
if jsonResult1 == nil {
return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil")
}
retVal = jsonResult1
if jsonResult1["fakeData"] != nil {
newErr := utils.NewErrorCode("cookie过期了", "code")
baseapi.SugarLogger.Debugf("jd AccessStorePage failed, jsonResult1:%s", utils.Format4Output(jsonResult1, true))
return platformapi.ErrLevelCodeIsNotOK, newErr
}
return "", err
})
return retVal, err
}
func (a *API) AccessStorePage(fullURL string, params map[string]interface{}, isPost bool) (retVal map[string]interface{}, err error) {
result, err := a.AccessStorePage2(fullURL, params, isPost, ResultKeyResult)
if err == nil {
retVal, _ = result.(map[string]interface{})
}
return retVal, err
}
func (a *API) GetRealMobile4Order(orderId, stationNo string) (mobile string, err error) {
retVal, err := a.GetStoreOrderInfo(orderId, stationNo)
if err == nil {
return retVal["mobile"].(string), nil
}
return "", err
}
func (a *API) GetStoreOrderInfo(orderId, stationNo string) (storeOrderInfo map[string]interface{}, err error) {
params := map[string]interface{}{
"pageNo": 1,
"pageSize": 1,
"desc": true,
"param": orderId,
}
if stationNo != "" {
params["stationNo"] = stationNo
}
retVal, err := a.AccessStorePage("http://order.jddj.com/order/newManager/search", params, false)
// baseapi.SugarLogger.Debug(utils.Format4Output(retVal, false))
if err == nil {
newOrderinfoMains := retVal["newOrderinfoMains"].(map[string]interface{})
resultList := newOrderinfoMains["resultList"].([]interface{})
if len(resultList) > 0 {
return resultList[0].(map[string]interface{}), nil
}
return nil, fmt.Errorf("不能找到订单:%s的相关信息", orderId)
}
return nil, err
}
func (a *API) GetStoreOrderInfoList(fromTime, toTime string) (storeOrderList []map[string]interface{}, err error) {
pageSize := 100
pageNo := 1
params := map[string]interface{}{
"o2oOrderType": 10000,
"pageSize": pageSize,
"desc": true,
"startTimeQuery": fromTime,
"endTimeQuery": toTime,
// "stationNo": 0,
}
for {
params["pageNo"] = pageNo
retVal, err := a.AccessStorePage("http://order.jddj.com/order/newManager/tabQuery/all", params, false)
// baseapi.SugarLogger.Debug(utils.Format4Output(retVal, false))
if err == nil {
newOrderinfoMains := retVal["newOrderinfoMains"].(map[string]interface{})
resultList := newOrderinfoMains["resultList"].([]interface{})
storeOrderList = append(storeOrderList, utils.Slice2MapSlice(resultList)...)
if len(storeOrderList) >= int(utils.MustInterface2Int64(newOrderinfoMains["totalCount"])) {
return storeOrderList, nil
}
pageNo++
} else {
return nil, err
}
}
return nil, err
}
func (a *API) GetSkuPageInfo(skuId int64) (skuPageInfo *PageSku, err error) {
skuIDMap := map[string]interface{}{
"skuId": utils.Int64ToStr(skuId),
"storeId": "0",
}
params := map[string]interface{}{
"platCode": "H5",
"functionId": "product/detailV6_0",
"appVersion": "6.7.0",
"body": utils.Format4Output(skuIDMap, true),
}
result, err := a.AccessStorePage("https://daojia.jd.com/client", params, false)
if err == nil {
err = JdMap2StructByJson(result, &skuPageInfo, false)
}
return skuPageInfo, err
}
func (a *API) GetSkuPageImageInfo(skuId int64) (imgList []*SkuPageImg, err error) {
skuPageInfo, err := a.GetSkuPageInfo(skuId)
if err == nil {
imgList = skuPageInfo.Image
}
return imgList, err
}
func (a *API) GetStoreInfo(storeId string) (storeInfo map[string]interface{}, err error) {
body := map[string]interface{}{
"storeId": storeId,
}
params := map[string]interface{}{
"appVersion": "6.1.0",
"functionId": "store/storeDetailV220",
"body": utils.Format4Output(body, true),
}
retVal, err := a.AccessStorePage("https://daojia.jd.com/client", params, false)
return retVal, err
}
func (a *API) GetStoreInfo2(storeID string) (storeInfo *PageShopInfo, err error) {
retVal, err := a.GetStoreInfo(storeID)
if err == nil {
err = JdMap2StructByJson(retVal, &storeInfo, false)
}
return storeInfo, err
}
func signGetStoreList(bodyStr string) (signResult string) {
wb := "923047ae3f8d11d8b19aeb9f3d1bc200"
return fmt.Sprintf("%X", md5.Sum([]byte(bodyStr+wb)))
}
func (a *API) GetStoreList(lng string, lat string) (retVal map[string]interface{}, err error) {
body := map[string]interface{}{
// "channelId": "3997", // 原来
"channelId": "4037", // 菜市场
// "channelId": "4038", // 水果店
"currentPage": 1,
"pageSize": 999,
"coordType": "2",
"platform": "1",
}
bodyStr := utils.Format4Output(body, true)
signResult := signGetStoreList(bodyStr)
params := map[string]interface{}{
"platCode": "H5",
"appVersion": "6.5.0",
"functionId": "zone/recommendStoreList",
"body": utils.Format4Output(body, true),
"signKey": signResult,
"lng": lng,
"lat": lat,
}
retVal, err = a.AccessStorePage("https://daojia.jd.com/client", params, false)
return retVal, err
}
//GetCorporationInfo 根据社会信用编码获取门店的详情(失效)
func (a *API) GetCorporationInfo(stationNo, qualifyNumber string) (corporatonInfo *CorporationInfo, err error) {
result, err := a.AccessStorePage("https://sta-store.jddj.com/store/requestQualify.o2o", map[string]interface{}{
"stationNo": stationNo,
"qualifyNumber": qualifyNumber,
}, true)
if err == nil {
err = JdMap2StructByJson(result, &corporatonInfo, false)
}
return corporatonInfo, err
}
//GetCorporationInfo2 京东根据门店营业执照获取门店信息
func (a *API) GetCorporationInfo2(picUrl string) (data *GetOrderDetailByLicenseImg, err error) {
result, err := a.AccessStorePage("https://store.jddj.com/client", map[string]interface{}{
"appName": "scpc",
"functionId": "storeQualifyNew/getLencenByOcr",
"body": fmt.Sprintf(`{"stationNo":%s,"picUrl":"%s"}`, utils.Int64ToStr(time.Now().Unix()), picUrl),
}, true)
if err != nil {
return nil, err
}
if err := utils.Map2StructByJson(result, &data, false); err != nil {
return nil, err
}
return
}
func MonthSaleNum2Int(monthSaleNumStr string) (monthSaleNum int) {
searchResult := monthSaleNumReg.FindStringSubmatch(monthSaleNumStr)
if searchResult != nil && len(searchResult[1]) > 0 && len(searchResult[2]) > 0 {
monthSaleNum = int(utils.Str2Int64WithDefault(searchResult[1], 0))
if searchResult[2] == "千" {
monthSaleNum *= 1000
} else if searchResult[2] == "万" {
monthSaleNum *= 10000
}
} else {
monthSaleNum = int(utils.Str2Int64WithDefault(monthSaleNumStr, 0))
}
return monthSaleNum
}
func (a *API) StoreUploadImg(imgFileName string, imgBin []byte) (imgURL string, err error) {
result, err := a.AccessStorePage2("https://sta-store.jddj.com/store/uploadImg.json", map[string]interface{}{
KeyImgData: imgBin,
KeyImgName: imgFileName,
}, true, ResultKeyData)
if err == nil {
imgURL = result.(string)
}
return imgURL, err
}
func (a *API) StoreUploadImgByURL(inImgURL string) (imgURL string, err error) {
response, err := http.Get(inImgURL)
if err == nil {
defer func() {
response.Body.Close()
}()
if response.StatusCode == http.StatusOK {
bodyData, err2 := ioutil.ReadAll(response.Body)
if err = err2; err == nil {
imgName := utils.GetUUID()
if lastSlashIndex := strings.LastIndex(inImgURL, "/"); lastSlashIndex >= 0 {
imgName = inImgURL[lastSlashIndex+1:]
}
return a.StoreUploadImg(imgName, bodyData)
}
} else {
err = platformapi.ErrHTTPCodeIsNot200
}
}
return "", err
}
func (a *API) SaveQualify(stationNo string, actionType int, qualifyList []*QualifyItem) (err error) {
_, err = a.AccessStorePage2("https://sta-store.jddj.com/store/saveQualify.o2o", map[string]interface{}{
"stationNo": stationNo,
"actionType": actionType,
"qualifyList": utils.Format4Output(qualifyList, true),
"type": 0,
"degrade": "no",
}, true, "")
return err
}
func (a *API) GetJdUserBindStoreIDs(userID int) (vendorStoreIDs []string, err error) {
body, err := a.AccessStorePage2("https://login-o2o.jddj.com/jpuser/bindStore/"+utils.Int2Str(userID), nil, false, "")
if err != nil {
return nil, err
}
bodyStr := body.(string)
tableStr := regexpTable.FindString(bodyStr)
vendorStoreIDsRegexp := regexpTd.FindAllStringSubmatch(tableStr, -1)
for _, v := range vendorStoreIDsRegexp {
vendorStoreIDs = append(vendorStoreIDs, v[1])
}
return vendorStoreIDs, err
}
// 查询商家中心账号信息接口
// https://login-o2o.jddj.com/jpuser/list?doPage=false&pageNo=1&appCode=lsp-store&pageSize=20&autoCount=false&_=1574936207872
func (a *API) PrivilegeSearchUser(pageNo int) (storeUserList []*StoreUserInfo, totalCount, totalPage int, err error) {
params := map[string]interface{}{
"pageNo": pageNo,
"appCode": "lsp-store",
"doPage": false,
"autoCount": false,
"pageSize": 20,
}
body, err := a.AccessStorePage2("https://login-o2o.jddj.com/jpuser/list", params, false, "")
if err != nil {
return nil, 0, 0, err
}
bodyStr := body.(string)
list := regexpJDTr.FindAllStringSubmatch(bodyStr, -1)
totalCount = int(utils.Str2Int64(regexpJDUserPage.FindStringSubmatch(bodyStr)[2]))
totalPage = int(utils.Str2Int64(regexpJDUserPage.FindStringSubmatch(bodyStr)[1]))
for _, v := range list {
tdList := regexpJDTdInfo.FindAllStringSubmatch(v[1], -1)
if len(tdList) > 0 {
id := regexpJDUserID.FindStringSubmatch(tdList[10][0])[1]
storeUserInfo := &StoreUserInfo{
LoginName: tdList[0][1],
LockStatus: tdList[9][1],
ID: int(utils.Str2Int64(id)),
RoleNameStr: tdList[4][1],
}
storeUserList = append(storeUserList, storeUserInfo)
}
}
return storeUserList, totalCount, totalPage, err
}
// 查询全部商家中心账号信息接口
// https://login-o2o.jddj.com/jpuser/list?doPage=false&pageNo=1&appCode=lsp-store&pageSize=20&autoCount=false&_=1574936207872
func (a *API) PrivilegeSearchUserAll() (storeUserLists []*StoreUserInfo, err error) {
_, _, totalPage, err := a.PrivilegeSearchUser(1)
for i := 1; i <= totalPage; i++ {
storeUserList, _, _, err := a.PrivilegeSearchUser(i)
if err != nil {
return nil, err
}
storeUserLists = append(storeUserLists, storeUserList...)
}
return storeUserLists, err
}
// 禁用/启用商家中心账号信息接口
// https: //login-o2o.jddj.com/jpuser/enable/346408
// https: //login-o2o.jddj.com/jpuser/disable/346408
func (a *API) PrivilegeUpdateJdUserStatus(id int64, status int) (jdUserPostResult JdUserPostResult, err error) {
url := "https://login-o2o.jddj.com/jpuser/"
if status == JdUserStatusEnable {
url += "enable/"
} else {
url += "disable/"
}
url += utils.Int64ToStr(id)
result, err := a.AccessStorePage2(url, nil, true, "responses")
if err == nil {
resultList := result.([]interface{})
resultMap := resultList[0].(map[string]interface{})
utils.Map2StructByJson(resultMap, &jdUserPostResult, true)
}
return jdUserPostResult, err
}
// 更改商家中心账号角色接口
// https://login-o2o.jddj.com/jpuser/binduserrole/346568/update?appCode=lsp-store
//roleIds: 28926拣货员
func (a *API) UpdateJdUserRoles(id int64, roleIDs []string) (jdUserPostResult JdUserPostResult, err error) {
url := "https://login-o2o.jddj.com/jpuser/binduserrole/" + utils.Int64ToStr(id) + "/update"
jdParams := map[string]interface{}{
"appCode": "lsp-store",
"roleIds": strings.Join(roleIDs, ","),
}
result, err := a.AccessStorePage2(url, jdParams, true, "")
if err == nil {
resultMap := result.(map[string]interface{})
utils.Map2StructByJson(resultMap, &jdUserPostResult, true)
}
return jdUserPostResult, err
}
// 查询用户是否是商家管理员接口
// https://login-o2o.jddj.com/jpuser/store/474147?isShow=1
func (a *API) IsJdManagerUser(id int64) (isManager bool, err error) {
url := "https://login-o2o.jddj.com/jpuser/store/" + utils.Int64ToStr(id)
jdParams := map[string]interface{}{
"isShow": 1,
}
body, err := a.AccessStorePage2(url, jdParams, false, "")
if err != nil {
return isManager, err
}
bodyStr := body.(string)
listmask := regexpJDUserIsManager.FindString(bodyStr)
if listmask == "" {
return false, err
} else {
return true, err
}
}
// 查询京东门店等级
// 无法得到总数循环50页后放弃寻找。。
// https://sta-store.jddj.com/store/logquery?venderId=320406&stationNo=11733018&currentPage=1&pageSize=20
func (a *API) GetJdStoreLevel(vendorOrgCode, vendorStoreID string, currentPage int) (level string, err error) {
jdParams := map[string]interface{}{
"venderId": vendorOrgCode,
"stationNo": vendorStoreID,
"currentPage": currentPage,
"pageSize": 20,
}
body, err := a.AccessStorePage2("https://sta-store.jddj.com/store/logquery", jdParams, false, "")
if err != nil {
return "0", err
}
bodyStr := body.(string)
levelList := regexpJDStoreLevel.FindAllStringSubmatch(bodyStr, 1)
if len(levelList) > 0 {
level = levelList[0][1]
}
return level, err
}
// 根据商品名查找京东商品upc编码
// https://pms-store.jddj.com/product/searchProductStd
func (a *API) GetJdUpcCodeByName(name, upcCode string, pageNo, pageSize int) (productInfos []*ProductInfo, err error) {
jdParams := map[string]interface{}{
"searchType": 1,
"firstCategoryId": 0,
"currentPage": pageNo,
"pageSize": pageSize,
"productName": name,
"upcCode": upcCode,
}
result, err := a.AccessStorePage2("https://pms-store.jddj.com/product/searchProductStd", jdParams, true, "")
if err != nil {
return nil, err
}
data := result.(map[string]interface{})
// totalCount = int(utils.Interface2Int64WithDefault(data["total"], 0))
if data["rows"] == nil {
return productInfos, err
}
for _, v := range data["rows"].([]interface{}) {
if v.(map[string]interface{})["upcCode"].(string) != "" {
var ImgList []string
ImgStr := v.(map[string]interface{})["productImageList"].([]interface{})
for _, vv := range ImgStr {
ImgList = append(ImgList, "http://img20.360buyimg.com/vc/"+vv.(string))
}
category, _ := utils.TryInterface2Int64(v.(map[string]interface{})["thirdCategoryId"])
productInfo := &ProductInfo{
OriginalName: v.(map[string]interface{})["name"].(string),
UpcCode: v.(map[string]interface{})["upcCode"].(string),
Weight: float32(utils.Interface2Float64WithDefault(v.(map[string]interface{})["weight"], 0) * 1000),
ImgList: ImgList,
BrandName: v.(map[string]interface{})["brandName"].(string),
Categories: []string{utils.Int64ToStr(category)},
}
productInfos = append(productInfos, productInfo)
}
}
return productInfos, err
}
//获取京东商品的指导价格
//https://stock-store.jddj.com/storeproduct/query
func (a *API) GetJdSkuDirectPrice(skuID int) (price int64, err error) {
jdParams := map[string]interface{}{
"outSkuId": skuID,
"fixedStatus": 1,
"stationNo": "allStation",
"numStatus": 0,
"currentPage": 1,
"pageSize": 1,
}
body, err := a.AccessStorePage2("https://stock-store.jddj.com/storeproduct/query", jdParams, true, "")
if body != nil {
bodyStr := body.(map[string]interface{})["fakeData"].(string)
result := regexpJDSkuDirectPrice.FindAllStringSubmatch(bodyStr, -1)
if len(result) > 0 {
if result[3][1] != "" {
return utils.Float64TwoInt64(utils.Str2Float64(result[3][1]) * 100), err
} else {
return 0, err
}
}
}
return price, err
}
//恢复京东商品库
func (a *API) RefreshJdDepot(skuID int) (result interface{}, err error) {
jdParams := map[string]interface{}{
"wareIds": skuID,
"upcCode": "",
"skuId": "",
"categoryMemoryIds": "",
"fixedStatus": "undefined",
"wareName": "",
"shopCategoryLevel1": -2,
"shopCategoryLevel2": -2,
"shopCategoryLevel3": -2,
"jdPriceLowString": "undefined",
"jdPriceHighString": "undefined",
"deleteTimeStart": "2020-04-22",
"deleteTimeEnd": "2020-04-23",
"wareStatusStr": "onSale",
"orderBy": "undefined",
"page": 1,
}
result, err = a.AccessStorePage2("https://pms-store.jddj.com/ware/updateWareRollBackStatus", jdParams, true, "")
return result, err
}
type SearchDeleteWareResult struct {
SkuID int `json:"skuID"`
JdID int `json:"jdID"`
}
//查询京东回收站
func (a *API) SearchDeleteWare(deleteTimeStart, deleteTimeEnd string, page, pagesize int) (searchDeleteWareResults []*SearchDeleteWareResult, err error) {
jdParams := map[string]interface{}{
"shopCategoryLevel1": -2,
"shopCategoryLevel2": -2,
"shopCategoryLevel3": -2,
"deleteTimeStart": deleteTimeStart,
"deleteTimeEnd": deleteTimeEnd,
"wareStatusStr": "onSale",
"orderBy": "undefined",
"page": page,
"pageSize": pagesize,
}
body, err := a.AccessStorePage2("https://pms-store.jddj.com/ware/searchDeleteWare", jdParams, true, "")
if body != nil {
bodyStr := body.(string)
tbody := regexpJDTbody.FindStringSubmatch(bodyStr)
trs := regexpJDTr.FindAllStringSubmatch(tbody[1], -1)
if len(trs) > 0 {
for _, v := range trs {
tds := regexpJDTdInfo.FindAllStringSubmatch(v[1], -1)
searchDeleteWareResult := &SearchDeleteWareResult{
JdID: int(utils.Str2Int64(regexpJDSkuID.FindStringSubmatch(v[1])[1])),
SkuID: int(utils.Str2Int64(tds[2][1])),
}
searchDeleteWareResults = append(searchDeleteWareResults, searchDeleteWareResult)
}
}
}
return searchDeleteWareResults, err
}
//获取京东的门店信息内部id
//https://sta-store.jddj.com/store/query
func (a *API) GetJdStoreID(storeID int) (jdStoreID int, err error) {
jdParams := map[string]interface{}{
"outSystemId": storeID,
"pageSize": 10,
}
body, err := a.AccessStorePage2("https://sta-store.jddj.com/store/query", jdParams, true, "")
if body != nil {
result := regexpJDStoreID.FindStringSubmatch(body.(string))
if len(result) > 0 {
if result[1] != "" {
return int(utils.Str2Int64(result[1])), err
} else {
return 0, err
}
}
}
return 0, err
}
//更新京东门店营业状态
//https://sta-store.jddj.com/store/updateClosetStatus
func (a *API) UpdateClosetStatus(jdStoreID, closeStatus int) (err error) {
jdParams := map[string]interface{}{
"id": jdStoreID,
"closeStatus": closeStatus,
}
_, err = a.AccessStorePage2("https://sta-store.jddj.com/store/updateClosetStatus", jdParams, true, "")
return err
}
type GetJdShopOrdersResult struct {
SummaryDueAmount float64 `json:"summaryDueAmount"`
BillList struct {
Result []struct {
OrderTypeCode int `json:"orderTypeCode"`
PayChannelName string `json:"payChannelName"`
BaseCommissionInvoiceFee int `json:"baseCommissionInvoiceFee"`
TieredCommissionInvoiceFee int `json:"tieredCommissionInvoiceFee"`
OrderID int64 `json:"orderId"`
Subsidy float64 `json:"subsidy"`
PaymentSubsidies float64 `json:"paymentSubsidies"`
DeliveryTypeStr string `json:"deliveryTypeStr"`
PackageBill float64 `json:"packageBill"`
StoreFreightSubsidy float64 `json:"storeFreightSubsidy"`
OfflineSettlementAmount float64 `json:"offlineSettlementAmount"`
EffectiveGMV int `json:"effectiveGMV"`
SrcOrderID int64 `json:"srcOrderId"`
TieredCommissionFee int `json:"tieredCommissionFee"`
OrgCode int `json:"orgCode"`
AfsAmount int `json:"afsAmount"`
StationName string `json:"stationName"`
Commission float64 `json:"commission"`
ID int `json:"id"`
BusinessFinishTime int64 `json:"businessFinishTime"`
StationID int `json:"stationId"`
SettleOrderIDStr string `json:"settleOrderIdStr"`
FreightBill float64 `json:"freightBill"`
GiftcardBill int `json:"giftcardBill"`
OrgName string `json:"orgName"`
OrderSourceName string `json:"orderSourceName"`
PickupServiceAmount float64 `json:"pickupServiceAmount"`
RelationID int `json:"relationId"`
GoodsBill float64 `json:"goodsBill"`
SettleOrderID string `json:"settleOrderId"`
MarketBill float64 `json:"marketBill"`
StoreFreightAmount float64 `json:"storeFreightAmount"`
BusinessStartTime int64 `json:"businessStartTime"`
OriginalAmount float64 `json:"originalAmount"`
DueAmount float64 `json:"dueAmount"`
BillOrderType int `json:"billOrderType"`
StoreSubsidy float64 `json:"storeSubsidy"`
AccountTime string `json:"accountTime"`
PickupAmount float64 `json:"pickupAmount"`
SettleFinishTime int `json:"settleFinishTime"`
BaseCommissionFee int `json:"baseCommissionFee"`
} `json:"result"`
Total int `json:"total"`
Pages int `json:"pages"`
StartRow int `json:"startRow"`
PageSize int `json:"pageSize"`
EndRow int `json:"endRow"`
PageNum int `json:"pageNum"`
} `json:"billList"`
SummaryGoodsBill float64 `json:"summaryGoodsBill"`
CurrentDueAmount float64 `json:"currentDueAmount"`
SummaryPositiveAmount float64 `json:"summaryPositiveAmount"`
CurrentGoodsBill float64 `json:"currentGoodsBill"`
}
//获取京东商城订单结算价
//https://dfsc.imdada.cn/settle/search/daoJiaBillList
func (a *API) GetJdShopOrders(orderStartTime, orderEndTime, orgCode, loginName string) (getJdShopOrdersResult *GetJdShopOrdersResult, err error) {
jdParams := map[string]interface{}{
"orgCode": orgCode,
"orderStartTime": orderStartTime,
"orderEndTime": orderEndTime,
"pageNum": 1,
"pageSize": 100,
"loginName": loginName,
"jdFusion": true,
}
result, err := a.AccessStorePage3("https://dfsc.imdada.cn/settle/search/daoJiaBillList", jdParams, "")
if err == nil {
utils.Map2StructByJson(result.(map[string]interface{})["content"], &getJdShopOrdersResult, false)
}
return getJdShopOrdersResult, err
}
//获取京东的置顶门店商品
//https://stock-store.jddj.com/storeproduct/query
func (a *API) GetJdTopSkus(vendorStoreID string, currentPage int) (vendorSkuIDs []string, totalCount int, err error) {
jdParams := map[string]interface{}{
"fixedStatus": 1,
"stationNo": vendorStoreID,
"numStatus": 0,
"currentPage": currentPage,
"pageSize": 10,
}
body, err := a.AccessStorePage2("https://stock-store.jddj.com/storeproduct/query", jdParams, true, "")
if body != nil {
bodyStr := body.(map[string]interface{})["fakeData"].(string)
result := regexpJDStoreSkuPage.FindStringSubmatch(bodyStr)
totalCount = utils.Str2Int(result[1])
resultTr := regexpJDTr.FindAllStringSubmatch(bodyStr, -1)
for _, v := range resultTr {
resultSkuID := regexpJDSkuID2.FindStringSubmatch(v[1])
if strings.Contains(v[1], "取消置顶") {
vendorSkuIDs = append(vendorSkuIDs, resultSkuID[1])
}
}
}
return vendorSkuIDs, totalCount, err
}
//获取京东的门店信息
func (a *API) GetJdStoreInfo(vendorStoreID string) (retVal interface{}, err error) {
jdParams := map[string]interface{}{
"_djrandom": time.Now().UnixNano(),
"functionId": "store/storeDetailV220",
"body": `{"refPageSource":"home","storeId":"` + vendorStoreID + `","skuId":"","activityId":"","promotionType":"","longitude":104.0455,"latitude":30.693336,"missionId":"","sourcePage":"","keyWord":"","source":"","cateName":"","channelId":"","pageSource":"store","ref":"home","ctp":"storeinfo"}`,
"appVersion": "8.4.5",
"appName": "paidaojia",
"platCode": "H5",
}
retVal, err = a.AccessStorePage2("http://www.jxc4.com/jd/client", jdParams, false, "")
return retVal, err
}
//订阅京东接口
func (a *API) UpdateInterStatus(interfaceId, interfaceCode string, interfaceType int) (err error) {
jdParams := map[string]interface{}{
"interfaceId": interfaceId,
"interfaceCode": interfaceCode,
"isEnabled": 1,
"interfaceType": interfaceType,
}
_, err = a.AccessStorePage2("https://openo2o.jddj.com/sandBox/updateInterStatus.htm", jdParams, true, "")
return err
}
//设置京东接口地址
func (a *API) SaveMsgUrl(interfaceId, testUrl, formalUrl string, interfaceType int) (err error) {
jdParams := map[string]interface{}{
"interfaceId": interfaceId,
"testUrl": testUrl,
"formalUrl": formalUrl,
"interfaceType": interfaceType,
}
_, err = a.AccessStorePage2("https://openo2o.jddj.com/sandBox/saveMsgUrl.htm", jdParams, true, "")
return err
}
//发送测试消息
func (a *API) ExcuteInvoking(interfaceId string, interfaceType int) (err error) {
jdParams := map[string]interface{}{
"interfaceId": interfaceId,
"interfaceType": interfaceType,
}
_, err = a.AccessStorePage2("https://openo2o.jddj.com/sandBox/excuteInvoking.htm", jdParams, true, "")
return err
}
//上线前,测试接口
func (a *API) SaveCheckedInters() (err error) {
retVal := ""
for k, v := range interfaceMap {
retVal += "interfaceIds[]=" + k + "-" + utils.Int64ToStr(utils.MustInterface2Int64(v[1])) + "&"
}
retVal = retVal[:len(retVal)-1]
_, err = a.AccessStorePage4("https://openo2o.jddj.com/sandBox/saveCheckedInters.htm", retVal)
return err
}
//我要上线
func (a *API) ToOnline() (err error) {
_, err = a.AccessStorePage2("https://openo2o.jddj.com/sandBox/toOnline.htm", nil, true, "")
return err
}
//京东开放平台未授权回填验证码app的id
func (a *API) GetJdNoAuthAppID(vendorOrgCode string) (data string, err error) {
nameMap := make(map[string]string)
result, err := a.AccessStorePage2("https://openo2o.jddj.com/xmanager/listAppBaseAndAuthNoAuth.htm", nil, false, "")
if result != nil {
tbody := regexpJDTbody.FindStringSubmatch(result.(string))
trs := regexpJDTr2.FindAllStringSubmatch(tbody[1], -1)
for _, v := range trs {
tds := regexpJDTdInfo.FindAllStringSubmatch(v[1], -1)
if len(tds) > 0 {
if tds[3][1] != "" {
if len(regexpAppID.FindStringSubmatch(tds[5][1])) > 0 {
name := strings.Map(func(r rune) rune {
switch r {
case 0x000A, 0x000B, 0x000C, 0x000D, 0x0085, 0x2028, 0x2029:
return -1
default:
return r
}
}, tds[3][1])
nameMap[strings.ReplaceAll(name, "\t", "")] = regexpAppID.FindStringSubmatch(tds[5][1])[1]
}
}
}
}
}
if nameMap[vendorOrgCode] != "" {
return nameMap[vendorOrgCode], err
}
return "", err
}
type GetJdAppInfoResult struct {
CallBackURL string `json:"callBackUrl"`
OrgCode string `json:"orgCode"`
AppKey string `json:"appKey"`
AppSecret string `json:"appSecret"`
IsShowUpdateBtn string `json:"isShowUpdateBtn"`
IsIsv string `json:"isIsv"`
IsShow string `json:"isShow"`
}
func (a *API) GetJdAppInfo() (getJdAppInfoResult *GetJdAppInfoResult, err error) {
result, err := a.AccessStorePage2("https://openo2o.jddj.com/xmanager/auto/app/appInfo.htm", nil, true, "")
if err == nil {
utils.Map2StructByJson(result.(map[string]interface{})["data"], &getJdAppInfoResult, false)
}
return getJdAppInfoResult, err
}
// https://openo2o.jddj.com/xmanager/isv/appManage.htm
func (a *API) SetCode(code, jdAppID string) (err error) {
_, err = a.AccessStorePage2("https://openo2o.jddj.com/xmanager/isv/app/accesstoken.htm", map[string]interface{}{
"id": jdAppID,
"code": code,
}, true, "")
return err
}
type QueryMemberTransListByConditionResult struct {
Total int `json:"total"`
Rows []*QueryMemberTransListByConditionList `json:"rows"`
}
type QueryMemberTransListByConditionList struct {
Bindingtypestr string `json:"bindingTypeStr"`
Cardcreatetime string `json:"cardcreateTime"`
Endtimestr string `json:"endTimeStr"`
Fromsourcestr string `json:"fromSourceStr"`
Fromstorename string `json:"fromStoreName,omitempty"`
Merchantcardno string `json:"merchantCardNo"`
Orgcodestr string `json:"orgCodeStr"`
Paymoney string `json:"payMoney"`
Starttimestr string `json:"startTimeStr"`
Validtype int `json:"validType"`
Createtime string `json:"createTime,omitempty"`
Dealstatus int `json:"dealStatus,omitempty"`
Orderid string `json:"orderId,omitempty"`
Orderstatusstr string `json:"orderStatusStr,omitempty"`
Ordertypestr string `json:"orderTypeStr,omitempty"`
}
func (a *API) QueryMemberTransListByCondition(beginTime, endTime string, page, pageSize int) (queryMemberTransListByConditionResult *QueryMemberTransListByConditionResult, err error) {
result, err := a.AccessStorePage5("https://mermem-sj.jddj.com/memberQuery/queryMemberTransListByCondition", map[string]interface{}{
"page": page,
"rows": pageSize,
"merchantCardNo": "",
"fromStoreId": "",
"validType": "",
"fromSource": "",
"orderType": "",
"startTimeTemp": "",
"endTimeTemp": "",
"cardstartTimeTemp": beginTime,
"cardendTimeTemp": endTime,
})
if err == nil {
utils.Map2StructByJson(result.(map[string]interface{}), &queryMemberTransListByConditionResult, false)
}
return queryMemberTransListByConditionResult, err
}