1441 lines
54 KiB
Go
1441 lines
54 KiB
Go
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¤tPage=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
|
||
}
|