Files
baseapi/platformapi/jdapi/store_page.go
2020-03-02 16:36:25 +08:00

842 lines
29 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"
"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"
)
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 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].*)条记录`)
regexpJDTr = regexp.MustCompile(`<tr>([\s\S]*?)</tr>`)
regexpJDTdInfo = regexp.MustCompile(`<td>([\s\S]*?)</td>`)
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>`)
htmlResponeURLs = []string{
"login-o2o.jddj.com/jpuser/",
"sta-store.jddj.com/store/",
}
)
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)
}
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")
} 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 {
baseapi.SugarLogger.Debugf("jd AccessStorePage failed, jsonResult1:%s", utils.Format4Output(jsonResult1, true))
return platformapi.ErrLevelCodeIsNotOK, newErr
}
})
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
}
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
}
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": 1,
"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))
}
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,
}
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, "")
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
}