Files
jx-callback/controllers/cms_sync.go
邹宗楠 dc25d0cdc1 1
2024-02-19 13:49:34 +08:00

445 lines
21 KiB
Go
Raw Permalink 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 controllers
import (
"fmt"
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
"github.com/panjf2000/ants"
"io"
"sync"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/jxstore/cms"
"git.rosy.net.cn/jx-callback/business/jxutils"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao"
"github.com/astaxie/beego/server/web"
)
type SyncController struct {
web.Controller
}
// @Title 同步商家商品信息
// @Description 同步商家商品信息
// @Param token header string true "认证token"
// @Param storeIDs formData string true "门店ID列表"
// @Param vendorIDs formData string true "厂商ID列表"
// @Param skuIDs formData string false "SKU ID列表缺省为全部"
// @Param isForce formData bool false "是否强制(设置修改标志)"
// @Param isAsync formData bool true "是否异步操作"
// @Param isContinueWhenError formData bool false "单个同步失败是否继续缺省false"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /SyncStoresSkus [put]
func (c *SyncController) SyncStoresSkus() {
c.callSyncStoresSkus(func(params *tSyncSyncStoresSkusParams) (retVal interface{}, errCode string, err error) {
db := dao.GetDB()
var storeIDs, skuIDs, vendorIDs []int
if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.SkuIDs, &skuIDs, params.VendorIDs, &vendorIDs); err != nil {
return retVal, "", err
}
retVal, err = cms.CurVendorSync.SyncStoresSkus(params.Ctx, nil, 0, db, vendorIDs, storeIDs, skuIDs, params.IsForce, params.IsAsync, params.IsContinueWhenError)
return retVal, "", err
})
}
// @Title 同步商家分类信息
// @Description 同步商家分类信息
// @Param token header string true "认证token"
// @Param storeIDs formData string true "门店ID列表"
// @Param vendorIDs formData string true "厂商ID列表"
// @Param isForce formData bool false "是否强制(设置修改标志)"
// @Param isAsync formData bool true "是否异步操作"
// @Param isContinueWhenError formData bool false "单个同步失败是否继续缺省false"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /SyncStoresCategory [put]
func (c *SyncController) SyncStoresCategory() {
c.callSyncStoresCategory(func(params *tSyncSyncStoresCategoryParams) (retVal interface{}, errCode string, err error) {
db := dao.GetDB()
var storeIDs, vendorIDs []int
if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.VendorIDs, &vendorIDs); err != nil {
return retVal, "", err
}
retVal, err = cms.CurVendorSync.SyncStoresCategory(params.Ctx, db, vendorIDs, storeIDs, params.IsForce, params.IsAsync, params.IsContinueWhenError)
return retVal, "", err
})
}
// @Title 全部刷新所有门店商家ID
// @Description 全部刷新所有门店商家ID
// @Param token header string true "认证token"
// @Param vendorIDs query string true "需要刷新的厂商ID列表"
// @Param isAsync query bool false "起始状态"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /RefreshAllStoresID [put]
func (c *SyncController) RefreshAllStoresID() {
c.callRefreshAllStoresID(func(params *tSyncRefreshAllStoresIDParams) (retVal interface{}, errCode string, err error) {
var vendorIDs []int
if err = utils.UnmarshalUseNumber([]byte(params.VendorIDs), &vendorIDs); err != nil {
return retVal, "", err
}
retVal, err = cms.CurVendorSync.RefreshAllStoresID(params.Ctx, params.IsAsync, vendorIDs)
return retVal, "", err
})
}
// @Title 重新刷新商家SKU ID
// @Description 重新刷新商家SKU ID单门店厂商必须指定storeIDs
// @Param token header string true "认证token"
// @Param vendorIDs query string true "需要刷新的厂商ID列表"
// @Param storeIDs query string false "需要刷新的门店ID列表对于单门店必须指定"
// @Param isAsync query bool false "起始状态"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /RefreshAllSkusID [put]
// func (c *SyncController) RefreshAllSkusID() {
// c.callRefreshAllSkusID(func(params *tSyncRefreshAllSkusIDParams) (retVal interface{}, errCode string, err error) {
// var vendorIDs, storeIDs []int
// if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.VendorIDs, &vendorIDs); err != nil {
// return retVal, "", err
// }
// retVal, err = cms.CurVendorSync.RefreshAllSkusID(params.Ctx, params.IsAsync, vendorIDs, storeIDs)
// return retVal, "", err
// })
// }
// @Title 全新初始化商家商品信息
// @Description 全新初始化商家商品信息(!!!此操作会先清除平台上已有的商品及分类信息),此操作只适用于单门店模式平台
// @Param token header string true "认证token"
// @Param storeIDs formData string true "门店ID列表"
// @Param vendorIDs formData string true "厂商ID列表"
// @Param isAsync formData bool true "是否异步操作"
// @Param isContinueWhenError formData bool false "单个同步失败是否继续缺省false"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /FullSyncStoresSkus [put]
func (c *SyncController) FullSyncStoresSkus() {
c.callFullSyncStoresSkus(func(params *tSyncFullSyncStoresSkusParams) (retVal interface{}, errCode string, err error) {
db := dao.GetDB()
var vendorIDs, storeIDs []int
if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.VendorIDs, &vendorIDs); err != nil {
return retVal, "", err
}
retVal, err = cms.CurVendorSync.FullSyncStoresSkus(params.Ctx, db, vendorIDs, storeIDs, true, nil, params.IsAsync, params.IsContinueWhenError, false)
return retVal, "", err
})
}
// @Title 比较门店中后台商品和运营商后台商品的差异 导出一个Excel 表格
// @Description 由于目前同步会因为类别不同会导致商品每晚无法成功同步 因此在同步功能前新增一个导出查看差异功能 比较商品类别
// @Param token header string true "认证token"
// @Param storeIDs formData string true "门店ID列表"
// @Param vendorIDs formData string true "厂商ID列表"
// @Param isAsync formData bool true "是否异步操作"
// @Param isContinueWhenError formData bool false "单个同步失败是否继续缺省false"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /CompareStoreWithOperator [put]
func (c *SyncController) CompareStoreWithOperator() {
c.callCompareStoreWithOperator(func(params *tSyncCompareStoreWithOperatorParams) (retVal interface{}, errCode string, err error) {
var vendorIDs, storeIDs []int
if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.VendorIDs, &vendorIDs); err != nil {
return retVal, "", err
}
p, _ := ants.NewPoolWithFunc(10, func(data interface{}) {
task := data.(*CompareTask)
task.Do()
})
defer p.Release()
var wg sync.WaitGroup
wg.Add(len(storeIDs))
tasks := make([]*CompareTask, 0, len(storeIDs))
for i := 0; i < len(storeIDs); i++ {
task := &CompareTask{
StoreId: storeIDs[i],
VendorId: vendorIDs[0],
Ctx: params.Ctx,
Wg: &wg,
}
tasks = append(tasks, task)
p.Invoke(task)
}
wg.Wait()
// err = cms.GetVendorStoreSkusToStruct(params.Ctx, storeIDs[0], vendorIDs[0])
return retVal, "", err
})
}
type CompareTask struct {
StoreId int
VendorId int
Ctx *jxcontext.Context
Wg *sync.WaitGroup
}
func (t *CompareTask) Do() {
cms.GetVendorStoreSkusToStruct(t.Ctx, t.StoreId, t.VendorId)
t.Wg.Done()
}
// @Title 删除门店平台商品信息(包括分类)
// @Description 删除门店平台商品信息(包括分类)(!!!此操作会先清除平台上已有的商品及分类信息),此操作只适用于单门店模式平台
// @Param token header string true "认证token"
// @Param storeIDs query string true "门店ID列表"
// @Param vendorIDs query string true "厂商ID列表"
// @Param isAsync query bool true "是否异步操作"
// @Param isContinueWhenError query bool false "单个同步失败是否继续缺省false"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /DeleteRemoteStoreSkus [delete]
func (c *SyncController) DeleteRemoteStoreSkus() {
c.callDeleteRemoteStoreSkus(func(params *tSyncDeleteRemoteStoreSkusParams) (retVal interface{}, errCode string, err error) {
db := dao.GetDB()
var vendorIDs, storeIDs []int
if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.VendorIDs, &vendorIDs); err != nil {
return retVal, "", err
}
retVal, err = cms.CurVendorSync.DeleteRemoteStoreSkus(params.Ctx, db, vendorIDs, storeIDs, params.IsAsync, params.IsContinueWhenError)
return retVal, "", err
})
}
// @Title 同步门店
// @Description 同步门店
// @Param token header string true "认证token"
// @Param vendorIDs formData string false "平台ID(京东0 美团1 饿百3)列表"
// @Param vendorOrgCodes formData string false "平台账号列表"
// @Param storeIDs formData string false "门店ID列表"
// @Param isForce formData bool false "是否强制(设置修改标志)"
// @Param isAsync formData bool false "是否异步"
// @Param isContinueWhenError formData bool false "单个同步失败是否继续缺省false"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /SyncStores [post]
func (c *SyncController) SyncStores() {
c.callSyncStores(func(params *tSyncSyncStoresParams) (retVal interface{}, errCode string, err error) {
var vendorIDs, storeIDs []int
var vendorOrgCodes []string
if err = jxutils.Strings2Objs(params.VendorIDs, &vendorIDs, params.StoreIDs, &storeIDs, params.VendorOrgCodes, &vendorOrgCodes); err == nil {
db := dao.GetDB()
if params.IsForce {
dao.SetStoreMapSyncStatus(db, vendorIDs, storeIDs, model.SyncFlagModifiedMask)
}
retVal, err = cms.CurVendorSync.SyncStore2(params.Ctx, db, vendorIDs, storeIDs, true, params.IsAsync)
}
return retVal, "", err
})
}
// @Title 同步商家分类(多门店平台)
// @Description 同步商家分类(多门店平台)
// @Param token header string true "认证token"
// @Param vendorID formData int false "平台ID(京东0 美团1 饿百3)"
// @Param vendorOrgCode formData string false "平台账号"
// @Param isForce formData bool false "是否强制(设置修改标志)"
// @Param isAsync formData bool false "是否异步"
// @Param isContinueWhenError formData bool false "单个同步失败是否继续缺省false"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /SyncCategories [post]
func (c *SyncController) SyncCategories() {
c.callSyncCategories(func(params *tSyncSyncCategoriesParams) (retVal interface{}, errCode string, err error) {
var vendorIDs []int
if params.MapData["vendorID"] != nil {
vendorIDs = append(vendorIDs, params.VendorID)
}
vendorOrgCodes := jxutils.BatchString2Slice(params.VendorOrgCode)
if params.IsForce {
dao.SetThingMapSyncStatus(dao.GetDB(), vendorIDs, vendorOrgCodes, model.ThingTypeCategory, nil, model.SyncFlagModifiedMask)
}
retVal, err = cms.SyncCategories(params.Ctx, nil, vendorIDs, vendorOrgCodes, nil, params.IsAsync)
return retVal, "", err
})
}
// @Title 同步SkuName多门店平台
// @Description 同步SkuName多门店平台
// @Param token header string true "认证token"
// @Param nameIDs formData string false "name ID列表"
// @Param isForce formData bool false "是否强制(设置修改标志)"
// @Param vendorID formData int false "平台ID(京东0 美团1 饿百3)"
// @Param vendorOrgCode formData string false "平台账号"
// @Param isAsync formData bool false "是否异步"
// @Param isContinueWhenError formData bool false "单个同步失败是否继续缺省false"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /SyncSkuNames [put,post]
func (c *SyncController) SyncSkuNames() {
c.callSyncSkuNames(func(params *tSyncSyncSkuNamesParams) (retVal interface{}, errCode string, err error) {
var nameIDs []int
if err = jxutils.Strings2Objs(params.NameIDs, &nameIDs); err == nil {
var vendorIDs []int
if params.MapData["vendorID"] != nil {
vendorIDs = append(vendorIDs, params.VendorID)
}
vendorOrgCodes := jxutils.BatchString2Slice(params.VendorOrgCode)
if params.IsForce {
dao.SetSkuNameSyncStatus(dao.GetDB(), vendorIDs, vendorOrgCodes, nameIDs, model.SyncFlagModifiedMask)
}
retVal, err = cms.SyncSkus(params.Ctx, nil, vendorIDs, vendorOrgCodes, nameIDs, nil, params.IsAsync)
}
return retVal, "", err
})
}
// @Title 删除本地没有的平台门店商品信息
// @Description 删除本地没有的平台门店商品信息(已废弃)
// @Param token header string true "认证token"
// @Param storeIDs query string true "门店ID列表"
// @Param vendorIDs query string true "厂商ID列表"
// @Param isAsync query bool false "是否异步操作"
// @Param isContinueWhenError query bool false "单个同步失败是否继续缺省false"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /PruneMissingStoreSkus [delete]
func (c *SyncController) PruneMissingStoreSkus() {
c.callPruneMissingStoreSkus(func(params *tSyncPruneMissingStoreSkusParams) (retVal interface{}, errCode string, err error) {
var storeIDs, vendorIDs []int
if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.VendorIDs, &vendorIDs); err == nil {
retVal, err = cms.CurVendorSync.PruneMissingStoreSkus(params.Ctx, vendorIDs, storeIDs, params.IsAsync, params.IsContinueWhenError)
}
return retVal, "", err
})
}
// @Title 把京西有,平台无且没有待创建标记的商品加上待创建标记
// @Description 把京西有,平台无且没有待创建标记的商品加上待创建标记(已废弃)
// @Param token header string true "认证token"
// @Param storeIDs formData string false "门店ID列表"
// @Param vendorIDs formData string false "运营商ID列表(京东0 美团1 饿百3)"
// @Param isAsync formData bool false "是否异步操作"
// @Param isContinueWhenError formData bool false "单个同步失败是否继续缺省false"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /AddCreateFlagForJxStoreSku [post]
func (c *SyncController) AddCreateFlagForJxStoreSku() {
c.callAddCreateFlagForJxStoreSku(func(params *tSyncAddCreateFlagForJxStoreSkuParams) (retVal interface{}, errCode string, err error) {
var storeIDs, vendorIDs []int
if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.VendorIDs, &vendorIDs); err == nil {
retVal, err = cms.CurVendorSync.AddCreateFlagForJxStoreSku(params.Ctx, vendorIDs, storeIDs, params.IsAsync, params.IsContinueWhenError)
}
return retVal, "", err
})
}
// @Title 把京西有,平台无且没有待创建标记的商品加上待创建标记
// @Description 把京西有,平台无且没有待创建标记的商品加上待创建标记
// @Param token header string true "认证token"
// @Param storeIDs formData string false "门店ID列表"
// @Param vendorIDs formData string false "运营商ID列表(京东0 美团1 饿百3)"
// @Param optType formData int true "操作方式"
// @Param isForce formData bool false "是否强制刷新"
// @Param isAsync formData bool false "是否异步操作"
// @Param isContinueWhenError formData bool false "单个同步失败是否继续缺省false"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /AmendAndPruneStoreStuff [post]
func (c *SyncController) AmendAndPruneStoreStuff() {
c.callAmendAndPruneStoreStuff(func(params *tSyncAmendAndPruneStoreStuffParams) (retVal interface{}, errCode string, err error) {
var storeIDs, vendorIDs []int
if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.VendorIDs, &vendorIDs); err == nil {
retVal, err = cms.CurVendorSync.AmendAndPruneStoreStuff(params.Ctx, vendorIDs, storeIDs, params.IsAsync, params.IsContinueWhenError, params.OptType, params.IsForce)
}
return retVal, "", err
})
}
// @Title 初始化多门店平台商品库(及商家分类)
// @Description 初始化多门店平台商品库(及商家分类)
// @Param token header string true "认证token"
// @Param vendorID formData int true "平台ID(京东0 美团1 饿百3)"
// @Param vendorOrgCode formData string true "平台账号"
// @Param storeID formData int false "门店ID"
// @Param isAsync formData bool false "是否异步操作"
// @Param isContinueWhenError formData bool false "单个同步失败是否继续缺省false"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /FullSyncVendorStuff [post]
func (c *SyncController) FullSyncVendorStuff() {
c.callFullSyncVendorStuff(func(params *tSyncFullSyncVendorStuffParams) (retVal interface{}, errCode string, err error) {
retVal, err = cms.FullSyncVendorStuff(params.Ctx, nil, params.StoreID, params.VendorID, params.VendorOrgCode, params.IsAsync, params.IsContinueWhenError)
return retVal, "", err
})
}
// @Title 上传假京东门店与SKU映射表并启动同步
// @Description 上传假京东门店与SKU映射表并启动同步
// @Param token header string false "认证token"
// @Param isSyncNow formData bool false "是否马上同步,一般不建议"
// @Param isAsync formData bool false "是否异步,缺省是同步"
// @Param isContinueWhenError formData bool false "单个同步失败是否继续缺省false"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /UploadFakeJdThingMap [post,get]
func (c *SyncController) UploadFakeJdThingMap() {
if c.Ctx.Input.IsGet() {
w := c.Ctx.ResponseWriter
// 上传页面
w.Header().Add("Content-Type", "text/html")
w.WriteHeader(200)
html := `
<form enctype="multipart/form-data" action="/v2/sync/UploadFakeJdThingMap" method="POST">
Send this file: <input name="userfiles" multiple accept="*" type="file" />
<input type="submit" value="Send File" />
</form>
`
io.WriteString(w, html)
} else if c.Ctx.Input.IsPost() {
c.callUploadFakeJdThingMap(func(params *tSyncUploadFakeJdThingMapParams) (retVal interface{}, errCode string, err error) {
r := c.Ctx.Request
files := r.MultipartForm.File["userfiles"]
if len(files) == 0 {
err = fmt.Errorf("没上传文件")
} else {
fileReader, err2 := files[0].Open()
if err = err2; err == nil {
retVal, err = cms.UploadFakeJdThingMap(params.Ctx, fileReader, params.IsSyncNow, params.IsAsync, params.IsContinueWhenError)
fileReader.Close()
}
}
return retVal, "", err
})
}
}
// @Title 同步银豹到京西商品
// @Description 同步银豹到京西商品
// @Param token header string true "认证token"
// @Param storeIDs formData string false "门店ID列表"
// @Param isAsync formData bool false "是否异步操作"
// @Param isContinueWhenError formData bool false "单个同步失败是否继续缺省false"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /SyncStoreSkusFromYb [put]
func (c *SyncController) SyncStoreSkusFromYb() {
c.callSyncStoreSkusFromYb(func(params *tSyncSyncStoreSkusFromYbParams) (retVal interface{}, errCode string, err error) {
var storeIDs []int
if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs); err == nil {
retVal, err = cms.CurVendorSync.SyncStoreSkusFromYb(params.Ctx, storeIDs, params.IsAsync, params.IsContinueWhenError)
}
return retVal, "", err
})
}
// @Title 同步京东商城门店商品和库存
// @Description 同步京东商城门店商品和库存
// @Param token header string true "认证token"
// @Param storeIDs formData string false "门店ID列表"
// @Param isAsync formData bool false "是否异步操作"
// @Param isContinueWhenError formData bool false "单个同步失败是否继续缺省false"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /SyncJdsStoresSkus [put]
func (c *SyncController) SyncJdsStoresSkus() {
c.callSyncJdsStoresSkus(func(params *tSyncSyncJdsStoresSkusParams) (retVal interface{}, errCode string, err error) {
var storeIDs []int
if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs); err == nil {
retVal, err = cms.CurVendorSync.SyncJdsStoresSkus(params.Ctx, storeIDs, params.IsAsync, params.IsContinueWhenError)
}
return retVal, "", err
})
}