From accb629e14a6d8b0caef71d8cf248224de464b55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8B=8F=E5=B0=B9=E5=B2=9A?= <770236076@qq.com> Date: Wed, 14 Oct 2020 11:57:12 +0800 Subject: [PATCH] shan --- business/jxcallback/orderman/financial.go | 262 - business/jxcallback/orderman/order.go | 1903 ------ business/jxcallback/orderman/order_afs.go | 424 -- business/jxcallback/orderman/order_comment.go | 213 - business/jxcallback/orderman/orderman.go | 180 - business/jxcallback/orderman/orderman_ext.go | 1343 ----- business/jxcallback/orderman/orderman_test.go | 17 - business/jxcallback/orderman/waybill.go | 265 - business/jxstore/cms/cms.go | 73 +- business/jxstore/cms/job.go | 23 +- business/jxstore/cms/sku.go | 2735 --------- business/jxstore/cms/store.go | 3758 ------------ business/jxstore/cms/store_sku.go | 5125 ----------------- business/jxstore/cms/store_sku_check.go | 1353 ----- business/jxstore/cms/store_test.go | 35 - business/jxstore/cms/sync.go | 1369 ----- business/jxstore/cms/sync2.go | 604 -- business/jxstore/cms/sync_store.go | 59 - business/jxstore/cms/sync_store_sku.go | 1445 ----- business/jxstore/cms/sync_store_sku_test.go | 44 - business/jxstore/cms/user2.go | 4 +- business/jxutils/jxutils.go | 43 +- business/jxutils/jxutils_cms.go | 121 - business/model/Store_Alert_Inform.go | 112 - business/model/bill.go | 1 + business/model/const.go | 7 - business/model/dao/Store_Alert_Inform.go | 51 - business/model/dao/act.go | 228 +- business/model/dao/dao_order.go | 1479 ----- business/model/dao/dao_order_test.go | 57 - business/model/dao/dao_user.go | 84 +- business/model/dao/job.go | 10 +- business/model/dao/report.go | 360 -- business/model/dao/sensitive_words.go | 71 - business/model/dao/sku.go | 441 -- business/model/dao/sku_test.go | 16 - business/model/dao/store.go | 915 --- business/model/dao/store_score.go | 106 - business/model/dao/store_sku.go | 1747 ------ business/model/dao/store_sku_sales.go | 78 - business/model/dao/store_sku_test.go | 38 - business/model/dao/store_test.go | 48 - business/model/dao/thing_map.go | 77 - business/model/job.go | 26 + business/model/sensitive_words.go | 7 - business/model/sku.go | 326 -- business/model/store.go | 759 --- business/model/store_score.go | 72 - business/model/store_sku.go | 215 - business/model/store_sku_sales.go | 17 - business/model/sync_map.go | 31 - business/model/user.go | 13 +- business/partner/delivery/dada/waybill.go | 399 -- .../partner/delivery/dada/waybill_test.go | 47 - business/partner/delivery/delivery.go | 149 - business/partner/delivery/jdeclp/waybill.go | 104 - .../partner/delivery/jdeclp/waybill_test.go | 7 - business/partner/delivery/mtps/store.go | 141 - business/partner/delivery/mtps/waybill.go | 333 -- .../partner/delivery/mtps/waybill_test.go | 36 - business/partner/partner.go | 307 - business/partner/partner_act.go | 130 - business/partner/partner_api.go | 14 - business/partner/partner_delivery.go | 80 - business/partner/partner_err.go | 89 - business/partner/partner_order.go | 67 - business/partner/partner_printer.go | 89 - business/partner/partner_store.go | 20 - business/partner/partner_store_sku.go | 204 - business/partner/pay/pay.go | 51 - business/partner/pay/wxpay/callback.go | 60 - business/partner/pay/wxpay/wxpay.go | 74 - business/partner/printer/feie/feie.go | 278 - business/partner/printer/feie/feie_test.go | 44 - business/partner/printer/xiaowm/xiaowm.go | 368 -- .../partner/printer/xiaowm/xiaowm_test.go | 44 - .../partner/printer/yilianyun/yilianyun.go | 291 - .../printer/yilianyun/yilianyun_test.go | 46 - business/partner/printer/zhongwu/zhongwu.go | 258 - .../partner/printer/zhongwu/zhongwu_test.go | 44 - business/partner/purchase/ebai/act.go | 340 -- business/partner/purchase/ebai/act_page.go | 117 - .../partner/purchase/ebai/act_page_test.go | 28 - business/partner/purchase/ebai/callback.go | 45 - business/partner/purchase/ebai/common.go | 47 - business/partner/purchase/ebai/common_test.go | 12 - business/partner/purchase/ebai/ebai.go | 143 - business/partner/purchase/ebai/ebai_test.go | 32 - business/partner/purchase/ebai/financial.go | 288 - .../partner/purchase/ebai/financial_test.go | 40 - .../partner/purchase/ebai/net_spider_test.go | 1 - business/partner/purchase/ebai/order.go | 722 --- business/partner/purchase/ebai/order_afs.go | 227 - .../partner/purchase/ebai/order_comment.go | 102 - business/partner/purchase/ebai/order_test.go | 27 - business/partner/purchase/ebai/store.go | 552 -- business/partner/purchase/ebai/store_sku2.go | 596 -- .../partner/purchase/ebai/store_sku2_test.go | 46 - .../partner/purchase/ebai/store_sku_test.go | 57 - business/partner/purchase/ebai/store_test.go | 34 - business/partner/purchase/ebai/waybill.go | 88 - business/partner/purchase/elm/act.go | 11 - business/partner/purchase/elm/elm.go | 101 - business/partner/purchase/elm/order.go | 334 -- business/partner/purchase/elm/order_afs.go | 28 - .../partner/purchase/elm/order_comment.go | 10 - .../partner/purchase/elm/order_legacy_urge.go | 52 - business/partner/purchase/elm/order_test.go | 23 - business/partner/purchase/elm/store.go | 25 - business/partner/purchase/elm/waybill.go | 67 - business/partner/purchase/jd/act.go | 422 -- business/partner/purchase/jd/callback.go | 33 - business/partner/purchase/jd/financial.go | 244 - .../partner/purchase/jd/financial_test.go | 17 - business/partner/purchase/jd/jd.go | 86 - business/partner/purchase/jd/jd_test.go | 11 - .../partner/purchase/jd/net_spider_test.go | 1 - business/partner/purchase/jd/order.go | 617 -- business/partner/purchase/jd/order_afs.go | 225 - business/partner/purchase/jd/order_comment.go | 51 - business/partner/purchase/jd/order_test.go | 61 - business/partner/purchase/jd/sku.go | 480 -- business/partner/purchase/jd/sku2.go | 485 -- business/partner/purchase/jd/sku_test.go | 61 - business/partner/purchase/jd/store.go | 520 -- business/partner/purchase/jd/store_sku2.go | 300 - .../partner/purchase/jd/store_sku2_test.go | 40 - business/partner/purchase/jd/store_test.go | 95 - business/partner/purchase/jd/waybill.go | 70 - business/partner/purchase/jdshop/act.go | 11 - business/partner/purchase/jdshop/callback.go | 314 - business/partner/purchase/jdshop/jds.go | 69 - business/partner/purchase/jdshop/key.go | 51 - business/partner/purchase/jdshop/order.go | 243 - business/partner/purchase/jdshop/order_afs.go | 134 - .../partner/purchase/jdshop/order_comment.go | 5 - business/partner/purchase/jdshop/store.go | 204 - business/partner/purchase/jdshop/store_sku.go | 896 --- business/partner/purchase/jx/act.go | 11 - business/partner/purchase/jx/jx.go | 34 - business/partner/purchase/jx/localjx/order.go | 2134 ------- .../partner/purchase/jx/localjx/order_test.go | 26 - .../purchase/jx/localjx/tonglianpay.go | 182 - business/partner/purchase/jx/localjx/user.go | 65 - business/partner/purchase/jx/localjx/wxpay.go | 152 - business/partner/purchase/jx/order.go | 134 - business/partner/purchase/jx/order_afs.go | 170 - business/partner/purchase/jx/order_comment.go | 10 - .../partner/purchase/jx/phpjx/callback.go | 55 - .../purchase/jx/phpjx/callback_test.go | 52 - business/partner/purchase/jx/phpjx/jxapi.go | 99 - .../partner/purchase/jx/phpjx/jxapi_order.go | 45 - .../purchase/jx/phpjx/jxapi_order_test.go | 21 - business/partner/purchase/jx/phpjx/order.go | 84 - .../partner/purchase/jx/phpjx/order_afs.go | 130 - business/partner/purchase/jx/sku.go | 82 - business/partner/purchase/jx/store.go | 44 - business/partner/purchase/jx/store_sku2.go | 36 - business/partner/purchase/mtwm/act.go | 260 - business/partner/purchase/mtwm/callback.go | 38 - business/partner/purchase/mtwm/financial.go | 252 - .../partner/purchase/mtwm/financial_test.go | 54 - business/partner/purchase/mtwm/mtwm.go | 225 - business/partner/purchase/mtwm/mtwm_test.go | 28 - business/partner/purchase/mtwm/order.go | 797 --- business/partner/purchase/mtwm/order_afs.go | 213 - .../partner/purchase/mtwm/order_comment.go | 112 - business/partner/purchase/mtwm/order_test.go | 35 - business/partner/purchase/mtwm/store.go | 317 - business/partner/purchase/mtwm/store_sku2.go | 676 --- .../partner/purchase/mtwm/store_sku2_test.go | 64 - .../partner/purchase/mtwm/store_sku_test.go | 46 - business/partner/purchase/mtwm/store_test.go | 45 - business/partner/purchase/mtwm/waybill.go | 56 - business/partner/purchase/weimob/wsc/act.go | 11 - .../partner/purchase/weimob/wsc/callback.go | 18 - business/partner/purchase/weimob/wsc/order.go | 309 - .../partner/purchase/weimob/wsc/order_afs.go | 28 - .../purchase/weimob/wsc/order_comment.go | 10 - business/partner/purchase/weimob/wsc/store.go | 25 - .../partner/purchase/weimob/wsc/store_sku2.go | 203 - .../purchase/weimob/wsc/store_sku_test.go | 25 - business/partner/purchase/weimob/wsc/wsc.go | 76 - .../partner/purchase/weimob/wsc/wsc_test.go | 29 - business/partner/purchase/yb/act.go | 11 - business/partner/purchase/yb/order.go | 76 - business/partner/purchase/yb/order_comment.go | 5 - business/partner/purchase/yb/store.go | 52 - business/partner/purchase/yb/store_sku.go | 602 -- business/partner/purchase/yb/yb.go | 43 - business/partner/putils/store_sku.go | 403 -- conf/app.conf | 2 +- controllers/cms_store_sku.go | 919 --- controllers/cms_user2.go | 17 - controllers/job_controller.go | 14 + controllers/order_controller.go | 6 +- globals/beegodb/beegodb.go | 4 +- main.go | 1 - routers/commentsRouter_controllers.go | 18 +- routers/router.go | 5 - 200 files changed, 206 insertions(+), 51995 deletions(-) delete mode 100644 business/jxcallback/orderman/financial.go delete mode 100644 business/jxcallback/orderman/order.go delete mode 100644 business/jxcallback/orderman/order_afs.go delete mode 100644 business/jxcallback/orderman/order_comment.go delete mode 100644 business/jxcallback/orderman/orderman.go delete mode 100644 business/jxcallback/orderman/orderman_ext.go delete mode 100644 business/jxcallback/orderman/orderman_test.go delete mode 100644 business/jxcallback/orderman/waybill.go delete mode 100644 business/jxstore/cms/sku.go delete mode 100644 business/jxstore/cms/store.go delete mode 100644 business/jxstore/cms/store_sku.go delete mode 100644 business/jxstore/cms/store_sku_check.go delete mode 100644 business/jxstore/cms/store_test.go delete mode 100644 business/jxstore/cms/sync2.go delete mode 100644 business/jxstore/cms/sync_store.go delete mode 100644 business/jxstore/cms/sync_store_sku.go delete mode 100644 business/jxstore/cms/sync_store_sku_test.go delete mode 100644 business/model/Store_Alert_Inform.go delete mode 100644 business/model/dao/Store_Alert_Inform.go delete mode 100644 business/model/dao/dao_order_test.go delete mode 100644 business/model/dao/report.go delete mode 100644 business/model/dao/sensitive_words.go delete mode 100644 business/model/dao/sku.go delete mode 100644 business/model/dao/sku_test.go delete mode 100644 business/model/dao/store.go delete mode 100644 business/model/dao/store_score.go delete mode 100644 business/model/dao/store_sku.go delete mode 100644 business/model/dao/store_sku_sales.go delete mode 100644 business/model/dao/store_sku_test.go delete mode 100644 business/model/dao/store_test.go delete mode 100644 business/model/dao/thing_map.go delete mode 100644 business/model/sensitive_words.go delete mode 100644 business/model/sku.go delete mode 100644 business/model/store.go delete mode 100644 business/model/store_score.go delete mode 100644 business/model/store_sku.go delete mode 100644 business/model/store_sku_sales.go delete mode 100644 business/model/sync_map.go delete mode 100644 business/partner/delivery/dada/waybill.go delete mode 100644 business/partner/delivery/dada/waybill_test.go delete mode 100644 business/partner/delivery/delivery.go delete mode 100644 business/partner/delivery/jdeclp/waybill.go delete mode 100644 business/partner/delivery/jdeclp/waybill_test.go delete mode 100644 business/partner/delivery/mtps/store.go delete mode 100644 business/partner/delivery/mtps/waybill.go delete mode 100644 business/partner/delivery/mtps/waybill_test.go delete mode 100644 business/partner/partner.go delete mode 100644 business/partner/partner_act.go delete mode 100644 business/partner/partner_api.go delete mode 100644 business/partner/partner_delivery.go delete mode 100644 business/partner/partner_err.go delete mode 100644 business/partner/partner_order.go delete mode 100644 business/partner/partner_printer.go delete mode 100644 business/partner/partner_store.go delete mode 100644 business/partner/partner_store_sku.go delete mode 100644 business/partner/pay/pay.go delete mode 100644 business/partner/pay/wxpay/callback.go delete mode 100644 business/partner/pay/wxpay/wxpay.go delete mode 100644 business/partner/printer/feie/feie.go delete mode 100644 business/partner/printer/feie/feie_test.go delete mode 100644 business/partner/printer/xiaowm/xiaowm.go delete mode 100644 business/partner/printer/xiaowm/xiaowm_test.go delete mode 100644 business/partner/printer/yilianyun/yilianyun.go delete mode 100644 business/partner/printer/yilianyun/yilianyun_test.go delete mode 100644 business/partner/printer/zhongwu/zhongwu.go delete mode 100644 business/partner/printer/zhongwu/zhongwu_test.go delete mode 100644 business/partner/purchase/ebai/act.go delete mode 100644 business/partner/purchase/ebai/act_page.go delete mode 100644 business/partner/purchase/ebai/act_page_test.go delete mode 100644 business/partner/purchase/ebai/callback.go delete mode 100644 business/partner/purchase/ebai/common.go delete mode 100644 business/partner/purchase/ebai/common_test.go delete mode 100644 business/partner/purchase/ebai/ebai.go delete mode 100644 business/partner/purchase/ebai/ebai_test.go delete mode 100644 business/partner/purchase/ebai/financial.go delete mode 100644 business/partner/purchase/ebai/financial_test.go delete mode 100644 business/partner/purchase/ebai/net_spider_test.go delete mode 100644 business/partner/purchase/ebai/order.go delete mode 100644 business/partner/purchase/ebai/order_afs.go delete mode 100644 business/partner/purchase/ebai/order_comment.go delete mode 100644 business/partner/purchase/ebai/order_test.go delete mode 100644 business/partner/purchase/ebai/store.go delete mode 100644 business/partner/purchase/ebai/store_sku2.go delete mode 100644 business/partner/purchase/ebai/store_sku2_test.go delete mode 100644 business/partner/purchase/ebai/store_sku_test.go delete mode 100644 business/partner/purchase/ebai/store_test.go delete mode 100644 business/partner/purchase/ebai/waybill.go delete mode 100644 business/partner/purchase/elm/act.go delete mode 100644 business/partner/purchase/elm/elm.go delete mode 100644 business/partner/purchase/elm/order.go delete mode 100644 business/partner/purchase/elm/order_afs.go delete mode 100644 business/partner/purchase/elm/order_comment.go delete mode 100644 business/partner/purchase/elm/order_legacy_urge.go delete mode 100644 business/partner/purchase/elm/order_test.go delete mode 100644 business/partner/purchase/elm/store.go delete mode 100644 business/partner/purchase/elm/waybill.go delete mode 100644 business/partner/purchase/jd/act.go delete mode 100644 business/partner/purchase/jd/callback.go delete mode 100644 business/partner/purchase/jd/financial.go delete mode 100644 business/partner/purchase/jd/financial_test.go delete mode 100644 business/partner/purchase/jd/jd.go delete mode 100644 business/partner/purchase/jd/jd_test.go delete mode 100644 business/partner/purchase/jd/net_spider_test.go delete mode 100644 business/partner/purchase/jd/order.go delete mode 100644 business/partner/purchase/jd/order_afs.go delete mode 100644 business/partner/purchase/jd/order_comment.go delete mode 100644 business/partner/purchase/jd/order_test.go delete mode 100644 business/partner/purchase/jd/sku.go delete mode 100644 business/partner/purchase/jd/sku2.go delete mode 100644 business/partner/purchase/jd/sku_test.go delete mode 100644 business/partner/purchase/jd/store.go delete mode 100644 business/partner/purchase/jd/store_sku2.go delete mode 100644 business/partner/purchase/jd/store_sku2_test.go delete mode 100644 business/partner/purchase/jd/store_test.go delete mode 100644 business/partner/purchase/jd/waybill.go delete mode 100644 business/partner/purchase/jdshop/act.go delete mode 100644 business/partner/purchase/jdshop/callback.go delete mode 100644 business/partner/purchase/jdshop/jds.go delete mode 100644 business/partner/purchase/jdshop/key.go delete mode 100644 business/partner/purchase/jdshop/order.go delete mode 100644 business/partner/purchase/jdshop/order_afs.go delete mode 100644 business/partner/purchase/jdshop/order_comment.go delete mode 100644 business/partner/purchase/jdshop/store.go delete mode 100644 business/partner/purchase/jdshop/store_sku.go delete mode 100644 business/partner/purchase/jx/act.go delete mode 100644 business/partner/purchase/jx/jx.go delete mode 100644 business/partner/purchase/jx/localjx/order.go delete mode 100644 business/partner/purchase/jx/localjx/order_test.go delete mode 100644 business/partner/purchase/jx/localjx/tonglianpay.go delete mode 100644 business/partner/purchase/jx/localjx/user.go delete mode 100644 business/partner/purchase/jx/localjx/wxpay.go delete mode 100644 business/partner/purchase/jx/order.go delete mode 100644 business/partner/purchase/jx/order_afs.go delete mode 100644 business/partner/purchase/jx/order_comment.go delete mode 100644 business/partner/purchase/jx/phpjx/callback.go delete mode 100644 business/partner/purchase/jx/phpjx/callback_test.go delete mode 100644 business/partner/purchase/jx/phpjx/jxapi.go delete mode 100644 business/partner/purchase/jx/phpjx/jxapi_order.go delete mode 100644 business/partner/purchase/jx/phpjx/jxapi_order_test.go delete mode 100644 business/partner/purchase/jx/phpjx/order.go delete mode 100644 business/partner/purchase/jx/phpjx/order_afs.go delete mode 100644 business/partner/purchase/jx/sku.go delete mode 100644 business/partner/purchase/jx/store.go delete mode 100644 business/partner/purchase/jx/store_sku2.go delete mode 100644 business/partner/purchase/mtwm/act.go delete mode 100644 business/partner/purchase/mtwm/callback.go delete mode 100644 business/partner/purchase/mtwm/financial.go delete mode 100644 business/partner/purchase/mtwm/financial_test.go delete mode 100644 business/partner/purchase/mtwm/mtwm.go delete mode 100644 business/partner/purchase/mtwm/mtwm_test.go delete mode 100644 business/partner/purchase/mtwm/order.go delete mode 100644 business/partner/purchase/mtwm/order_afs.go delete mode 100644 business/partner/purchase/mtwm/order_comment.go delete mode 100644 business/partner/purchase/mtwm/order_test.go delete mode 100644 business/partner/purchase/mtwm/store.go delete mode 100644 business/partner/purchase/mtwm/store_sku2.go delete mode 100644 business/partner/purchase/mtwm/store_sku2_test.go delete mode 100644 business/partner/purchase/mtwm/store_sku_test.go delete mode 100644 business/partner/purchase/mtwm/store_test.go delete mode 100644 business/partner/purchase/mtwm/waybill.go delete mode 100644 business/partner/purchase/weimob/wsc/act.go delete mode 100644 business/partner/purchase/weimob/wsc/callback.go delete mode 100644 business/partner/purchase/weimob/wsc/order.go delete mode 100644 business/partner/purchase/weimob/wsc/order_afs.go delete mode 100644 business/partner/purchase/weimob/wsc/order_comment.go delete mode 100644 business/partner/purchase/weimob/wsc/store.go delete mode 100644 business/partner/purchase/weimob/wsc/store_sku2.go delete mode 100644 business/partner/purchase/weimob/wsc/store_sku_test.go delete mode 100644 business/partner/purchase/weimob/wsc/wsc.go delete mode 100644 business/partner/purchase/weimob/wsc/wsc_test.go delete mode 100644 business/partner/purchase/yb/act.go delete mode 100644 business/partner/purchase/yb/order.go delete mode 100644 business/partner/purchase/yb/order_comment.go delete mode 100644 business/partner/purchase/yb/store.go delete mode 100644 business/partner/purchase/yb/store_sku.go delete mode 100644 business/partner/purchase/yb/yb.go delete mode 100644 business/partner/putils/store_sku.go delete mode 100644 controllers/cms_store_sku.go diff --git a/business/jxcallback/orderman/financial.go b/business/jxcallback/orderman/financial.go deleted file mode 100644 index c9b9a3b61..000000000 --- a/business/jxcallback/orderman/financial.go +++ /dev/null @@ -1,262 +0,0 @@ -package orderman - -import ( - "math" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" -) - -const ( - TotalRate = 200 // 总费率(千分之200)= 第三方平台费+京西品牌费+京西服务费,现阶段都是合计200‰ - MaxFreightMoneyFromJxByShop = 7 // 商家自送实际转美团/达达后由商家承担的运费金额上限 -) - -// 处理正向订单结账信息 -func (c *OrderManager) SaveOrderFinancialInfo(order *model.OrderFinancial, operation string) (err error) { - db := dao.GetDB() - dao.Begin(db) - defer func() { - if r := recover(); r != nil || err != nil { - dao.Rollback(db) - if r != nil { - panic(r) - } - } - }() - if operation == partner.UpdatedPeration { - // db := orm.NewOrm() - err = utils.CallFuncLogError(func() error { - _, err = dao.ExecuteSQL(db, "DELETE FROM order_financial WHERE vendor_order_id = ? AND vendor_id = ?", order.VendorOrderID, order.VendorID) - return err - }, "SaveOrderFinancialInfo delete order_financial, orderID:%s", order.VendorOrderID) - if err != nil { - return err - } - err = utils.CallFuncLogError(func() error { - _, err = dao.ExecuteSQL(db, "DELETE FROM order_sku_financial WHERE vendor_order_id = ? AND vendor_id = ? AND is_afs_order = 0", order.VendorOrderID, order.VendorID) - return err - }, "SaveOrderFinancialInfo delete order_sku_financial, orderID:%s", order.VendorOrderID) - if err != nil { - return err - } - err = utils.CallFuncLogError(func() error { - _, err = dao.ExecuteSQL(db, "DELETE FROM order_discount_financial WHERE vendor_order_id = ? AND vendor_id = ?", order.VendorOrderID, order.VendorID) - return err - }, "SaveOrderFinancialInfo delete order_discount_financial, orderID:%s", order.VendorOrderID) - if err != nil { - return err - } - } - for _, activity := range order.Discounts { - if err = dao.CreateEntity(db, activity); err != nil { - if !dao.IsDuplicateError(err) { - globals.SugarLogger.Warnf("On SaveOrderDiscountFinancialInfo order.VendorOrderID:%s err: order is err", order.VendorOrderID) - return err - } - dao.Rollback(db) - return nil - } - } - order.ShopMoneyByCal = order.SalePriceMoney - order.TotalDiscountMoney - order.PointsDeductionMoney + order.PmFreightDiscountMoney - order.DistanceFreightMoney - order.FreightTipsMoney - order.DonationMoney + order.SelfDeliveryDiscountMoney + order.PmSubsidyMoney + order.SkuBoxMoney + order.BoxMoney - order.PmMoney - order.JxPmMoney = utils.Float64TwoInt64(float64(order.ShopMoney+order.PmMoney)*TotalRate/1000) - order.PmMoney // 京西平台费 = 总金额*20%-第三方平台费 - if order.JxPmMoney < 0 { // 如果算出京西平台费为负数,则置0 - order.JxPmMoney = 0 - } - - order.JxShopMoney = order.ShopMoney - order.JxPmMoney + order.JxSubsidyMoney - order.JxFreightMoneyByShop - // 订单结算金额拆分计算,拆分到单条sku - // 先获取订单主体优惠金额 - platOrderGoodsDiscountMoney := order.PmSubsidyMoney - order.PmSkuSubsidyMoney + order.SelfDeliveryDiscountMoney - // 结算平台扣除项汇总---平台佣金,商家设置运费减免,远距离费,小费,公益捐款、、、、 - deductionsByPm := order.FreightDiscountMoney + order.DistanceFreightMoney + order.FreightTipsMoney + order.DonationMoney + order.PmMoney - // 结算京西扣除项汇总---京西佣金,京西配送运费 - deductionsByJx := order.JxPmMoney + order.JxFreightMoneyByShop - for _, sku := range order.Skus[1:] { - // 用户支付菜品金额,用户为这一条sku支付的菜品金额 - sku.UserMoney = utils.Float64TwoInt64(float64(order.SalePriceMoney-order.DiscountMoney-order.PointsDeductionMoney+order.BoxMoney+order.SkuBoxMoney) * float64(sku.SalePrice*int64(sku.Count)+sku.SkuBoxMoney) / float64(order.SalePriceMoney+order.SkuBoxMoney)) // 林峰确认,比如49-2满减,算餐盒费满49元,不算餐盒费不足49元,是可以参加满减活动的,那么餐盒费也应该和商品金额一起进行折算 - order.Skus[0].UserMoney += sku.UserMoney - // 计算平台订单主体补贴拆分到单条sku的金额 + sku.PmSubsidyMoneyForSku - sku.PmSubsidyMoney = sku.PmSkuSubsidyMoney + utils.Float64TwoInt64(float64(platOrderGoodsDiscountMoney*sku.SalePrice*int64(sku.Count)+sku.SkuBoxMoney)/float64(order.SalePriceMoney+order.SkuBoxMoney)) - order.Skus[0].PmSubsidyMoney += sku.PmSubsidyMoney - // 计算京西满减补贴拆分到单条sku的金额 + sku.JxSubsidyMoneyForSku - sku.JxSubsidyMoney = sku.JxSkuSubsidyMoney + utils.Float64TwoInt64(float64(order.JxSubsidyMoney-order.PmSkuSubsidyMoney)*float64(sku.SalePrice*int64(sku.Count)+sku.SkuBoxMoney)/float64(order.SalePriceMoney+order.SkuBoxMoney)) - order.Skus[0].JxSubsidyMoney += sku.JxSubsidyMoney - // 计算单条sku需要承担的平台扣费金额 - sku.PmDeductionsMoney = utils.Float64TwoInt64(float64(deductionsByPm) * (float64(sku.UserMoney + sku.PmSubsidyMoney)) / (float64(order.SalePriceMoney + order.BoxMoney + order.SkuBoxMoney - order.DiscountMoney - order.PointsDeductionMoney + order.PmSubsidyMoney))) - order.Skus[0].PmDeductionsMoney += sku.PmDeductionsMoney - // 计算单条sku平台应该结算给京西的金额 - sku.ShopMoneyByCal = sku.UserMoney + sku.PmSubsidyMoney - sku.PmDeductionsMoney - order.Skus[0].ShopMoneyByCal += sku.ShopMoneyByCal - // j计算单条sku需要承担的京西扣费金额 - sku.JxDeductionsMoney = utils.Float64TwoInt64(float64(deductionsByJx*sku.ShopMoneyByCal) / float64(order.ShopMoney)) - order.Skus[0].JxDeductionsMoney += sku.JxDeductionsMoney - // 计算单条sku京西应该结算给商家的金额 - sku.JxShopMoney = sku.ShopMoneyByCal + sku.JxSubsidyMoney - sku.JxDeductionsMoney - order.Skus[0].JxShopMoney += sku.JxShopMoney - if sku.SkuID >= math.MaxInt32 { - sku.SkuID = sku.JxSkuID - } - if err = dao.CreateEntity(db, sku); err != nil { - if !dao.IsDuplicateError(err) { - globals.SugarLogger.Warnf("On SaveOrderSkuFinancialInfo order.VendorOrderID:%s err:%v", order.VendorOrderID, err) - return err - } - dao.Rollback(db) - return nil - } - } - if len(order.Skus) > 0 { - sku := order.Skus[0] - if sku.SkuID > math.MaxInt32 { - sku.SkuID = sku.JxSkuID - } - sku.UserMoney = order.SalePriceMoney - order.DiscountMoney - sku.UserMoney - sku.PmSubsidyMoney = platOrderGoodsDiscountMoney + order.SelfDeliveryDiscountMoney - sku.PmSubsidyMoney - sku.JxSubsidyMoney = order.JxSubsidyMoney - sku.JxSubsidyMoney - sku.PmDeductionsMoney = deductionsByPm - sku.PmDeductionsMoney - sku.ShopMoneyByCal = order.ShopMoney - sku.ShopMoneyByCal - sku.JxDeductionsMoney = deductionsByJx - sku.JxDeductionsMoney - sku.JxShopMoney = order.JxShopMoney - sku.JxShopMoney - if err = dao.CreateEntity(db, sku); err != nil { - if !dao.IsDuplicateError(err) { - globals.SugarLogger.Warnf("On SaveOrderSkuFinancialInfo order.VendorOrderID:%s err:%v", order.VendorOrderID, err) - return err - } - dao.Rollback(db) - return nil - } - } else { - globals.SugarLogger.Warnf("On SaveOrderSkuFinancialInfo order.VendorOrderID:%s err: order have no sku", order.VendorOrderID) - } - // 加上京西对单条sku的补贴,再存数据库 - order.JxSubsidyMoney += order.JxSkuSubsidyMoney - if err = dao.CreateEntity(db, order); err != nil { - if !dao.IsDuplicateError(err) { - globals.SugarLogger.Warnf("On SaveOrderFinancialInfo order.VendorOrderID:%s err: order is err", order.VendorOrderID) - return err - } - dao.Rollback(db) - return nil - } - dao.Commit(db) - return err -} - -// 处理售后订单结账信息 -func (c *OrderManager) SaveAfsOrderFinancialInfo(afsOrder *model.AfsOrder) (err error) { - globals.SugarLogger.Debug(afsOrder.AfsOrderID) - db := dao.GetDB() - dao.Begin(db) - defer func() { - if r := recover(); r != nil || err != nil { - dao.Rollback(db) - if r != nil { - panic(r) - } - } - }() - // 平台结算扣除汇总--平台补贴,售后产生运费,平台收包装费,同城运费、、、 - deductionsByPm := afsOrder.PmSubsidyMoney + afsOrder.AfsFreightMoney + afsOrder.BoxMoney + afsOrder.TongchengFreightMoney - afsOrder.RefundMoneyByCal = afsOrder.SkuUserMoney + afsOrder.FreightUserMoney + deductionsByPm - afsOrder.PmRefundMoney - // order.TotalMoney += order.SkuJxMoney // 退款单京西补贴部分先不作计算 - if err = dao.CreateEntity(db, afsOrder); err != nil { - if !dao.IsDuplicateError(err) { - globals.SugarLogger.Warnf("On SaveAfsOrderFinancialInfo afsOrder.AfsOrderID:%s err: SaveAfsOrder is err", afsOrder.AfsOrderID) - return err - } - dao.Rollback(db) - return nil - } - - // 京西结算扣除汇总,先不作计算,计算单条sku最终扣款金额(+该条sku承担的平台结算扣除金额) - for _, orderSku := range afsOrder.Skus[1:] { - orderSku.RefundMoneyByCal = orderSku.PmSkuSubsidyMoney + - utils.Float64TwoInt64(float64(afsOrder.RefundMoneyByCal-afsOrder.PmSkuSubsidyMoney)*float64(orderSku.UserMoney+orderSku.PmSubsidyMoney-orderSku.PmSkuSubsidyMoney)/float64(afsOrder.SkuUserMoney+afsOrder.PmSubsidyMoney-afsOrder.PmSkuSubsidyMoney)) - afsOrder.Skus[0].RefundMoneyByCal += orderSku.RefundMoneyByCal - if err = dao.CreateEntity(db, orderSku); err != nil { - if !dao.IsDuplicateError(err) { - globals.SugarLogger.Warnf("On SaveAfsOrderFinancialInfo afsOrder.AfsOrderID:%s err: SaveAfsOrderSku is err", afsOrder.AfsOrderID) - return err - } - dao.Rollback(db) - return nil - } - } - if len(afsOrder.Skus) > 0 { - orderSku := afsOrder.Skus[0] - orderSku.RefundMoneyByCal = afsOrder.RefundMoneyByCal - orderSku.RefundMoneyByCal - if err = dao.CreateEntity(db, orderSku); err != nil { - if !dao.IsDuplicateError(err) { - globals.SugarLogger.Warnf("On SaveAfsOrderFinancialInfo afsOrder.AfsOrderID:%s err: SaveAfsOrderSku is err", afsOrder.AfsOrderID) - return err - } - dao.Rollback(db) - return nil - } - } else { - globals.SugarLogger.Warnf("On SaveAfsOrderFinancialInfo afsOrder.AfsOrderID:%s err: afsOrder have no sku", afsOrder.AfsOrderID) - } - dao.Commit(db) - return err -} - -// 转自送实际使用美团/达达配送,调用此方法 -func (c *OrderManager) UpdataOrderFinancialInfo(orderFinancial *model.OrderFinancial, wayBill *model.Waybill) (err error) { - // 通过本地数据库去取是否转美团/达达,并计算运费,写在上级调用函数里面传递过来 - // wayBill, err2 := partner.CurOrderManager.LoadWaybill(orderFinancial.VendorOrderID, orderFinancial.VendorID) - // if err = err2; err == nil { - // orderFinancial.JxFreightMoney = wayBill.DesiredFee - // } - db := dao.GetDB() - dao.Begin(db) - defer func() { - if r := recover(); r != nil || err != nil { - dao.Rollback(db) - if r != nil { - panic(r) - } - } - }() - orderFinancial.JxFreightMoney = wayBill.DesiredFee - if (orderFinancial.JxFreightMoney - orderFinancial.SelfDeliveryDiscountMoney) > MaxFreightMoneyFromJxByShop { - orderFinancial.JxFreightMoneyByShop = orderFinancial.SelfDeliveryDiscountMoney + MaxFreightMoneyFromJxByShop - } else if (orderFinancial.JxFreightMoney - orderFinancial.SelfDeliveryDiscountMoney) < 0 { - orderFinancial.JxFreightMoneyByShop = orderFinancial.SelfDeliveryDiscountMoney - } else { - orderFinancial.JxFreightMoneyByShop = orderFinancial.JxFreightMoney - } - orderFinancial.JxShopMoney -= orderFinancial.JxFreightMoneyByShop - // orderFinancial.JxFreightMoneyByShop 的改变直接影响到单条sku的京西结算金额的改变 - jxDecMoney := orderFinancial.JxFreightMoneyByShop - for _, sku := range orderFinancial.Skus[1:] { - // 重新计算单条sku京西应该结算的金额 - skuJxDecMoney := utils.Float64TwoInt64(float64(jxDecMoney*sku.SalePrice*int64(sku.Count)+sku.SkuBoxMoney) / float64(orderFinancial.SalePriceMoney+orderFinancial.SkuBoxMoney)) - sku.JxDeductionsMoney += skuJxDecMoney - sku.JxShopMoney -= skuJxDecMoney - jxDecMoney -= skuJxDecMoney - if _, err = dao.UpdateEntity(db, sku); err != nil { - return err - } - } - if len(orderFinancial.Skus) > 0 { - sku := orderFinancial.Skus[0] - sku.JxDeductionsMoney += jxDecMoney - sku.JxShopMoney -= jxDecMoney - if _, err = dao.UpdateEntity(db, sku); err != nil { - return err - } - } - if err = dao.CreateEntity(db, orderFinancial); err != nil { - globals.SugarLogger.Warnf("On SaveOrderFinancialInfo err: order is err") - return err - } - dao.Commit(db) - // orderFinancial 和 OrderSkuFinancial 数据计算完毕,准备进行更新 - return err -} - - diff --git a/business/jxcallback/orderman/order.go b/business/jxcallback/orderman/order.go deleted file mode 100644 index 4730651ef..000000000 --- a/business/jxcallback/orderman/order.go +++ /dev/null @@ -1,1903 +0,0 @@ -package orderman - -import ( - "crypto/md5" - "errors" - "fmt" - "math" - "strings" - "time" - - "git.rosy.net.cn/baseapi/platformapi/jdeclpapi" - - "git.rosy.net.cn/jx-callback/business/jxstore/common" - "git.rosy.net.cn/jx-callback/business/jxutils/ddmsg" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/partner/purchase/jdshop" - "git.rosy.net.cn/jx-callback/globals/api" - - "git.rosy.net.cn/baseapi" - "git.rosy.net.cn/baseapi/platformapi/dingdingapi" - "git.rosy.net.cn/baseapi/platformapi/jdshopapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" - "github.com/astaxie/beego/orm" -) - -var ( - orderNoBeginTimestamp int64 -) - -func init() { - orderNoBeginTimestamp = utils.Str2Time("2010-01-01 00:00:00").Unix() -} - -type tSkuCountPrice struct { - Count int `json:"count"` - SalePrice int64 `json:"salePrice"` -} - -// msgVendorStatus的意思是事件本身的类型,类似有时收到NewOrder事件去取,订单状态不一定就是New的 -// OnOrderAdjust也类似,而OrderStatus要记录的是消息,所以添加这个 -func (c *OrderManager) OnOrderNew(order *model.GoodsOrder, orderStatus *model.OrderStatus) (err error) { - globals.SugarLogger.Debugf("OnOrderNew orderID:%s", order.VendorOrderID) - if order.ConsigneeMobile2 == "" && jxutils.IsStringLikeMobile(order.ConsigneeMobile) { - order.ConsigneeMobile2 = order.ConsigneeMobile - } - - db := dao.GetDB() - dao.Begin(db) - defer func() { - globals.SugarLogger.Debugf("OnOrderNew exit orderID:%s", order.VendorOrderID) - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - if order.Status == model.OrderStatusUnknown { - order.Status = model.OrderStatusNew - } - - var isDuplicated bool - if order.Status == model.OrderStatusNew && order.VendorID == model.VendorIDJX && !model.IsOrderJXTemp(order) { - isDuplicated, _, err = c.addOrderStatus(orderStatus, db) - } else { - isDuplicated, err = addOrderOrWaybillStatus(orderStatus, db) - if err == nil && !isDuplicated { - isDuplicated, err = c.SaveOrder(order, false, db) - } - } - if err == nil { - dao.Commit(db) - if !isDuplicated { - err = scheduler.CurrentScheduler.OnOrderNew(order, false) - } - } else { - dao.Rollback(db) - } - return err -} - -// todo 调整单的处理可能还需要再细化一点,当前只是简单的删除重建 -func (c *OrderManager) OnOrderAdjust(order *model.GoodsOrder, orderStatus *model.OrderStatus) (err error) { - globals.SugarLogger.Debugf("OnOrderAdjust orderID:%s, status:%d", order.VendorOrderID, order.Status) - if order.ConsigneeMobile2 == "" && jxutils.IsStringLikeMobile(order.ConsigneeMobile) { - order.ConsigneeMobile2 = order.ConsigneeMobile - } - - db := dao.GetDB() - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - // 出现过调整单后,状态回到新订单状态,比如:911350836000622 - // 不完全确定,加一个处理 - if order.Status < model.OrderStatusAccepted { - order.Status = model.OrderStatusAccepted - } - isDuplicated, err := addOrderOrWaybillStatus(orderStatus, db) - if err == nil && !isDuplicated { - err = utils.CallFuncLogError(func() error { - _, err = db.Db.Raw("DELETE FROM order_sku WHERE vendor_order_id = ? AND vendor_id = ?", order.VendorOrderID, order.VendorID).Exec() - return err - }, "OnAdjustOrder delete order, orderID:%s", order.VendorOrderID) - if err != nil { - return err - } - adjustCount := int8(0) - previousOrder := &model.GoodsOrder{ - VendorOrderID: order.VendorOrderID, - VendorID: order.VendorID, - } - if err = dao.GetEntity(db, previousOrder, model.FieldVendorOrderID, model.FieldVendorID); err != nil && !dao.IsNoRowsError(err) { - globals.SugarLogger.Warnf("OnOrderAdjust, order:%s GetEntity failed with error:%v", order.VendorOrderID, err) - return err - } - if err == nil { - adjustCount = previousOrder.AdjustCount - if _, err = dao.DeleteEntity(db, previousOrder); err != nil { - return err - } - order.VendorWaybillID = previousOrder.VendorWaybillID - order.WaybillVendorID = previousOrder.WaybillVendorID - } else { - globals.SugarLogger.Warnf("OnOrderAdjust, but previous order:%s doesn't exist", order.VendorOrderID) - } - // err = utils.CallFuncLogError(func() error { - // _, err = db.Db.Raw("DELETE FROM goods_order WHERE vendor_order_id = ? AND vendor_id = ?", order.VendorOrderID, order.VendorID).Exec() - // return err - // }, "OnAdjustOrder delete order_sku, orderID:%s", order.VendorOrderID) - order.AdjustCount = adjustCount + 1 - //扣点的订单需要修改订单的totalshopmoney - if err == nil && order.EarningType == model.EarningTypePoints { - order2, _ := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID).GetOrder(order.VendorOrgCode, order.VendorOrderID) - order.TotalShopMoney = order2.TotalShopMoney - } - isDuplicated, err = c.SaveOrder(order, true, db) - } - if err == nil { - dao.Commit(db) - if !isDuplicated { - // 因为订单调度器需要的是真实状态,所以用order的状态 - _ = scheduler.CurrentScheduler.OnOrderNew(order, false) - _ = scheduler.CurrentScheduler.OnOrderStatusChanged(order, orderStatus, false) - } - } else { - dao.Rollback(db) - } - return err -} - -func (c *OrderManager) OnOrderStatusChanged(vendorOrgCode string, orderStatus *model.OrderStatus) (err error) { - // 有些平台(比如美团外卖),在新订单事件没有成功返回,但在重发订单消息前,订单状态转换,则不会再重发新订单事件,特殊处理一下 - if orderStatus.Status == model.OrderStatusAccepted { - if _, err2 := c.LoadOrder(orderStatus.VendorOrderID, orderStatus.VendorID); err2 == ErrCanNotFindOrder { - if handler := partner.GetPurchaseOrderHandlerFromVendorID(orderStatus.VendorID); handler != nil { - if order, err2 := handler.GetOrder(vendorOrgCode, orderStatus.VendorOrderID); err2 == nil { - c.OnOrderNew(order, orderStatus) - } - } - } - } - - db := dao.GetDB() - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - isDuplicated, order, err := c.addOrderStatus(orderStatus, db) - if err == nil { - dao.Commit(db) - if orderStatus.Status == model.OrderStatusWaybillTipChanged { - if order, err2 := c.LoadOrder(orderStatus.VendorOrderID, orderStatus.VendorID); err2 == nil { - if handler := partner.GetWaybillTipUpdater(orderStatus.RefVendorID); handler != nil { - tipFee, err2 := handler.GetWaybillTip(jxcontext.AdminCtx, vendorOrgCode, order.VendorStoreID, orderStatus.RefVendorOrderID, orderStatus.VendorOrderID, "") - if err2 == nil { - order.WaybillTipMoney = tipFee - c.UpdateOrderFields(order, []string{"WaybillTipMoney"}) - } - } - } - } else if orderStatus.Status == model.OrderStatusFinished { - if order, err2 := c.LoadOrder(orderStatus.VendorOrderID, orderStatus.VendorID); err2 == nil { - // 当前只针对三方运单更新配送费信息 - if order.WaybillVendorID >= 0 && order.VendorWaybillID != "" && order.WaybillVendorID != order.VendorID { - if waybill, err2 := c.LoadWaybill(order.VendorWaybillID, order.WaybillVendorID); err2 == nil { - if handler := partner.GetWaybillTipUpdater(waybill.WaybillVendorID); handler != nil { - tipFee, err2 := handler.GetWaybillTip(jxcontext.AdminCtx, waybill.VendorOrgCode, "", order.VendorOrderID, waybill.VendorWaybillID, waybill.VendorWaybillID2) - if err2 == nil && waybill.TipFee != tipFee { - waybill.ActualFee += tipFee - waybill.TipFee - waybill.TipFee = tipFee - dao.UpdateEntity(db, waybill, "TipFee", "ActualFee") - } - } - } - } - //更新订单new_earning_price - if order.EarningType == model.EarningTypePoints { - waybill, _ := c.LoadWaybill(order.VendorWaybillID, order.WaybillVendorID) - store, _ := c.LoadStoreDetail(jxutils.GetSaleStoreIDFromOrder(order), order.VendorID) - if waybill == nil { - if (order.NewEarningPrice == 0 || order.NewEarningPrice != order.TotalShopMoney*int64(100-store.PayPercentage/2)/int64(100)) && store.PayPercentage <= 50 { - order.NewEarningPrice = order.TotalShopMoney * int64(100-store.PayPercentage/2) / int64(100) - } - } else { - if (order.NewEarningPrice == 0 || order.NewEarningPrice != (order.TotalShopMoney-waybill.DesiredFee)*int64(100-store.PayPercentage/2)/int64(100)) && store.PayPercentage <= 50 { - order.NewEarningPrice = order.TotalShopMoney*int64(100-store.PayPercentage/2)/int64(100) - waybill.DesiredFee - } - } - dao.UpdateEntity(db, order, "NewEarningPrice") - } - } - } else if orderStatus.Status == model.OrderStatusCanceled { - //如果取消订单则要把库存加回去 - if order, err2 := c.LoadOrder(orderStatus.VendorOrderID, orderStatus.VendorID); err2 == nil { - ModifyOrderSkusStock(db, order, true) - } - } - if !isDuplicated { - if order != nil { - order.Skus = c.loadOrderSku(db, order.VendorOrderID, order.VendorID) - _ = scheduler.CurrentScheduler.OnOrderStatusChanged(order, orderStatus, false) - } - } - } else { - dao.Rollback(db) - } - return err -} - -func (c *OrderManager) ChangeOrderInfo(order *model.GoodsOrder) (err error) { - db := dao.GetDB() - _, err = dao.UpdateEntity(db, order, "ConsigneeAddress", "ConsigneeName", "ConsigneeMobile", "ConsigneeLat", "ConsigneeLng", "BuyerComment") - return err -} - -func (c *OrderManager) OnOrderMsg(order *model.GoodsOrder, vendorStatus, remark string) (err error) { - _, _, err = c.addOrderStatus(&model.OrderStatus{ - VendorOrderID: order.VendorOrderID, - VendorID: order.VendorID, - OrderType: model.OrderTypeOrder, - RefVendorOrderID: order.VendorOrderID, - RefVendorID: order.VendorID, - - VendorStatus: vendorStatus, - Status: model.OrderStatusMsg, - StatusTime: time.Now(), - Remark: utils.LimitUTF8StringLen(remark, 255), - }, nil) - return err -} - -func setFakeOrderFlag(db *dao.DaoDB, order *model.GoodsOrder) { - if order.DeliveryType == model.OrderDeliveryTypeSelfTake { - if realMobile := jxutils.GetRealMobile4Order(order); realMobile != "" { - if configList, err := dao.QueryConfigs(db, model.ConfigSysFakeOrderMobiles, model.ConfigTypeSys, ""); err == nil && len(configList) > 0 { - isMatch := false - mobileList := strings.Split(configList[0].Value, ",") - for _, v := range mobileList { - if jxutils.TrimDecorationChar(v) == realMobile { - isMatch = true - break - } - } - if isMatch { - order.Flag |= model.OrderFlagMaskFake - } - } - } - } -} - -func (c *OrderManager) SaveOrder(order *model.GoodsOrder, isAdjust bool, db *dao.DaoDB) (isDuplicated bool, err error) { - globals.SugarLogger.Debugf("SaveOrder orderID:%s, VendorStoreID:%s, status:%d", order.VendorOrderID, order.VendorStoreID, order.Status) - // 忽略查找JX信息错误 - c.updateOrderOtherInfo(order, db) - order.ID = 0 - order.WaybillVendorID = model.VendorIDUnknown - order.OrderFinishedAt = utils.DefaultTimeValue - - setFakeOrderFlag(db, order) - // cms.HandleOrder4Consignee(order) - - dao.Begin(db) - defer func() { - if r := recover(); r != nil || err != nil { - dao.Rollback(db) - if r != nil { - panic(r) - } - } - }() - // todo hardcode 兼容京东消息错序问题 - if true { //order.VendorID == model.VendorIDJD { - orderStatus := &model.OrderStatus{} - if dao.GetRow(db, orderStatus, ` - SELECT * - FROM order_status - WHERE order_type = ? AND vendor_order_id = ? AND vendor_id = ? AND status > 0 - ORDER BY status_time DESC - LIMIT 1 - `, model.OrderTypeOrder, order.VendorOrderID, order.VendorID) == nil { - if orderStatus.Status > order.Status { - order.Status = orderStatus.Status - order.VendorStatus = orderStatus.VendorStatus - order.StatusTime = orderStatus.StatusTime - - // jxutils.RefreshOrderSkuRelated(order) - } - } - } - - filterOrderInfo(order) - created, _, err2 := db.Db.ReadOrCreate(order, "VendorOrderID", "VendorID") - if err = err2; err == nil { - originalOrder := &model.GoodsOrderOriginal{ - VendorOrderID: order.VendorOrderID, - VendorID: order.VendorID, - OrderCreatedAt: order.OrderCreatedAt, - OriginalData: order.OriginalData, - } - if _, _, err = db.Db.ReadOrCreate(originalOrder, "VendorOrderID", "VendorID"); err == nil { - if created { - if err = dao.CreateMultiEntities(db, order.Skus); err != nil { - baseapi.SugarLogger.Warnf("saveOrder orderID:%s, save order_sku failed with error:%v", order.VendorOrderID, err) - } - } else { - isDuplicated = true - order.DuplicatedCount++ - db.Db.Update(order, "DuplicatedCount") - baseapi.SugarLogger.Infof("saveOrder duplicated orderid:%s msg received", order.VendorOrderID) - } - } - //修改商品库存 - if err == nil { - err = ModifyOrderSkusStock(db, order, false) - } - } else { - globals.SugarLogger.Warnf("saveOrder create order:%v, error:%v", order, err) - } - if err == nil { - dao.Commit(db) - } - return isDuplicated, err -} - -func ModifyOrderSkusStock(db *dao.DaoDB, order *model.GoodsOrder, isAdd bool) (err error) { - skus := order.Skus - for _, sku := range skus { - storeSkus, _ := dao.GetStoresSkusInfo(db, []int{jxutils.GetSaleStoreIDFromOrder(order)}, []int{sku.SkuID}) - if len(storeSkus) == 0 { - if !isAdd { - globals.SugarLogger.Warnf("此订单商品没得storsku,%v,%v", order.VendorOrderID, sku.SkuID) - } - continue - } - storeSku, stock := storeSkus[0], 0 - if storeSku.Stock == 0 { - if !isAdd { - // globals.SugarLogger.Warnf("此订单商品库存为0,%v,%v", order.VendorOrderID, sku.SkuID) - } - continue - } - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - if isAdd { - stock = storeSku.Stock + sku.Count - } else { - stock = storeSku.Stock - sku.Count - //如果是进货的订单,进货方门店对应商品要加上这么多库存 - if order.OrderType == model.OrderTypeSupplyGoods { - storeSkus2, _ := dao.GetStoresSkusInfo(db, []int{order.FromStoreID}, []int{sku.SkuID}) - if len(storeSkus2) > 0 { - storeSku3 := storeSkus2[0] - storeSku3.Stock = storeSku3.Stock + sku.Count - dao.UpdateEntity(db, storeSku3, "Stock") - } - } - realStock := checkPriceDefendOrderByStock(db, jxutils.GetSaleStoreIDFromOrder(order), sku.SkuID, stock, storeSku.JxPrice) - if realStock != -1 { - stock = realStock - } - } - storeSku.Stock = stock - dao.UpdateEntity(db, storeSku, "Stock") - if order.VendorID != model.VendorIDJX { - dao.SetStoreSkuSyncStatus(db, order.VendorID, []int{jxutils.GetSaleStoreIDFromOrder(order)}, []int{sku.SkuID}, model.SyncFlagStockMask) - } - dao.Commit(db) - } - return err -} - -func filterOrderInfo(order *model.GoodsOrder) { - order.ConsigneeName = utils.LimitUTF8StringLen2(order.ConsigneeName, 32) - order.ConsigneeAddress = utils.LimitUTF8StringLen2(order.ConsigneeAddress, 255) - order.ConsigneeAddress = strings.ReplaceAll(order.ConsigneeAddress, "·", "") -} - -func checkPriceDefendOrderByStock(db *dao.DaoDB, storeID, skuID, stock, jxPrice int) (realStock int) { - var ( - sumStock = 0 - ) - priceDefends, _ := dao.GetPriceDefendOrder(db, "", []int{storeID}, []int{skuID}, []int{jxutils.GetDefendPriceIssue()}, 0, 1, 0, 1, "", utils.ZeroTimeValue, utils.ZeroTimeValue, false) - if len(priceDefends) == 0 { - return -1 - } - for _, v := range priceDefends { - sumStock += v.Count - } - //如果现库存小于等于用户守价的库存,就要开始了 - //如果小于,要按照守价时间的先后来决定 - //如果等于,就刚好全部成功,然后库存清0 - if stock < sumStock { - tStock := stock - for _, v := range priceDefends { - if tStock <= v.Count { - tStock -= v.Count - v.IsSuccess = model.YES - v.RealPrice = int64(jxPrice) - dao.UpdateEntity(db, v, "IsSuccess", "RealPrice") - } else { - continue - } - } - realStock = tStock - } else if stock == sumStock { - for _, v := range priceDefends { - v.IsSuccess = model.YES - v.RealPrice = int64(jxPrice) - dao.UpdateEntity(db, v, "IsSuccess", "RealPrice") - } - realStock = 0 //库存清0 - } else { - realStock = -1 - } - return realStock -} - -func (c *OrderManager) updateOrderSkuOtherInfo(order *model.GoodsOrder, db *dao.DaoDB, storePayPercentage, changePriceType int) (err error) { - globals.SugarLogger.Debugf("updateOrderSkuOtherInfo orderID:%s, VendorStoreID:%s", order.VendorOrderID, order.VendorStoreID) - jxStoreID := jxutils.GetShowStoreIDFromOrder(order) - var opNumStr string - if time.Now().Sub(order.OrderCreatedAt) < 1*time.Hour && order.VendorID != model.VendorIDJD { - opNumStr = "2" - } else { - opNumStr = "2" - } - - if jxStoreID == 0 { - return nil - } - orderSkus := order.Skus - - var vendorSkuIDs []string - for _, v := range orderSkus { - if v.VendorSkuID != "" { - vendorSkuIDs = append(vendorSkuIDs, v.VendorSkuID) - } - } - if len(vendorSkuIDs) > 0 { - var vendorStoreID string - if order.VendorID == model.VendorIDJDShop { - vendorStoreID = model.JdShopMainVendorStoreID - } else { - vendorStoreID = order.VendorStoreID - } - l, err := dao.GetStoreSkuPriceAndWeight(db, vendorStoreID, order.VendorID, vendorSkuIDs) - if err != nil { - globals.SugarLogger.Warnf("updateOrderSkuOtherInfo orderID:%s failed with err:%v", order.VendorOrderID, err) - return err - } - skumapper := storeSkuPriceAndWeight2Map(l) - for _, v := range orderSkus { - v.VendorOrderID = order.VendorOrderID - v.VendorID = order.VendorID - - intVendorSkuID := utils.Str2Int64WithDefault(v.VendorSkuID, 0) - if intVendorSkuID != 0 && v.VendorSkuID != "-70000" { // todo hard code - skuBindInfo := skumapper[v.VendorSkuID] - if skuBindInfo == nil { - if v.ShopPrice == 0 { - v.ShopPrice = v.SalePrice * 70 / 100 - } - globals.SugarLogger.Infof("updateOrderSkuOtherInfo [运营%s]%s订单sku找不到门店价格(或商品映射),orderID:%s, StoreID:%d, VendorSkuID:%s, sku:%v", opNumStr, model.VendorChineseNames[order.VendorID], order.VendorOrderID, jxStoreID, v.VendorSkuID, v) - } else { - // TODO 客户端当前逻辑认为SkuID为0为赠品 - if v.SkuID == 0 { - v.SkuID = v.JxSkuID - } - v.JxSkuID = skuBindInfo.SkuID - //京东商城的话,门店里可能取不到对应商品 - if order.VendorID == model.VendorIDJDShop { - if v.SkuID == 0 && v.JxSkuID != 0 { - v.SkuID = v.JxSkuID - } - // v.JxSkuID = v.SkuID - storeSkus, _ := dao.GetStoresSkusInfo(db, []int{order.StoreID}, []int{v.SkuID}) - if len(storeSkus) > 0 { - v.ShopPrice = int64(storeSkus[0].Price) - } else { - v.ShopPrice = v.SalePrice * 70 / 100 - } - } else { - v.ShopPrice = int64(skuBindInfo.Price) - if v.ShopPrice == 0 { - v.ShopPrice = v.SalePrice * 70 / 100 - } - } - v.SkuName = jxutils.ComposeSkuNameOriginal(skuBindInfo.Prefix, skuBindInfo.Name, skuBindInfo.Comment, skuBindInfo.Unit, skuBindInfo.SpecQuality, skuBindInfo.SpecUnit, 0) - v.Weight = skuBindInfo.Weight // 以本地信息中的WEIGHT为准 - //饿鲜达的订单做一下处理 - if strings.Contains(order.StoreName, model.ExdStoreName) { - if v.SkuID == 0 && !strings.Contains(v.SkuName, "免费") { - v.SkuID = v.JxSkuID - } - } - if skuBindInfo.Price == 0 { - globals.SugarLogger.Infof("updateOrderSkuOtherInfo [运营%s]%s订单sku门店价格为零(一般原因为没有门店价格信息),orderID:%s, StoreID:%d, SkuID:%d, sku:%v", opNumStr, model.VendorChineseNames[order.VendorID], order.VendorOrderID, jxStoreID, v.JxSkuID, v) - } - } - } - // 直营店始终按比例结算,不考虑活动与结算表 - salePrice := v.SalePrice - if changePriceType == model.StoreChangePriceTypeManagedStore && v.ShopPrice != 0 { - salePrice = 0 - } - v.EarningPrice = jxutils.CaculateSkuEarningPrice(v.ShopPrice, salePrice, storePayPercentage) - } - // 直营店始终按比例结算,不考虑活动与结算表 - if changePriceType != model.StoreChangePriceTypeManagedStore { - updateSingleOrderEarningPrice(order, db) - } - //TODO 重复购买有活动且结算价大于0的商品需要拆分,第一个商品按结算价,后面的商品按shopprice 或者 saleprice, 2020-05-06 - //TODO 京东美团的订单,做活动的商品之前就会拆分出来,所以只做更新,饿百暂时不管, 2020-05-07 - //TODO 不根据商品是否拆分,直接根据该商品做了活动,并且他的vendorPrice 和 salePrice 相等,就按新规则结算, 2020-05-11 - //TODO 现在不判断商品做没做活动,只要vendorPrice和salePrice不等,就默认为做了活动,不做活动的商品就按新规则结算,2020-05-18 - if order.VendorID == model.VendorIDJD || order.VendorID == model.VendorIDMTWM { - for _, v := range orderSkus { - if v.EarningPrice > 0 { - // var storeID int - // if order.StoreID == 0 { - // storeID = order.JxStoreID - // } else { - // storeID = order.StoreID - // } - // result, err := dao.GetEffectiveActStoreSkuInfo2(db, 0, []int{order.VendorID}, []int{model.ActSkuSecKill, model.ActSkuDirectDown}, []int{storeID}, []int{v.SkuID}, order.OrderCreatedAt, order.OrderCreatedAt) - // if (len(result) > 0 && err == nil) || v.IsVendorAct == model.YES { - if v.VendorPrice == v.SalePrice { - var earningPrice = 0 - if v.ShopPrice < v.SalePrice { - if v.ShopPrice == 0 { - earningPrice = int(utils.Float64TwoInt64(math.Round(utils.Int2Float64(int(v.SalePrice)) * utils.Int2Float64(storePayPercentage) / 100))) - } else { - earningPrice = int(utils.Float64TwoInt64(math.Round(utils.Int2Float64(int(v.ShopPrice)) * utils.Int2Float64(storePayPercentage) / 100))) - } - } else { - earningPrice = int(utils.Float64TwoInt64(math.Round(utils.Int2Float64(int(v.SalePrice)) * utils.Int2Float64(storePayPercentage) / 100))) - } - v.EarningPrice = int64(earningPrice) - // v.StoreSubID = 0 - } - // } - } - } - } - } - return nil -} - -func storeSkuPriceAndWeight2Map(l []*dao.StoreSkuPriceAndWeight) (skuMapper map[string]*dao.StoreSkuPriceAndWeight) { - skuMapper = make(map[string]*dao.StoreSkuPriceAndWeight) - for _, v := range l { - skuMapper[v.VendorSkuID] = v - } - return skuMapper -} - -func updateSingleOrderEarningPrice(order *model.GoodsOrder, db *dao.DaoDB) { - jxStoreID := jxutils.GetShowStoreIDFromOrder(order) - skuIDMap := make(map[int]int) - for _, v := range order.Skus { - if skuID := jxutils.GetSkuIDFromOrderSku(v); skuID > 0 { - skuIDMap[skuID] = 1 - } - } - if len(skuIDMap) > 0 { - actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, 0, []int{order.VendorID}, model.ActTypeAll, []int{jxStoreID}, jxutils.IntMap2List(skuIDMap), order.OrderCreatedAt, order.OrderCreatedAt) - if err != nil { - globals.SugarLogger.Errorf("updateOrderSkuOtherInfo can not get sku promotion info for error:%v", err) - } - if actStoreSkuMap := jxutils.NewActStoreSkuMap(actStoreSkuList, false); actStoreSkuMap != nil { - for _, v := range order.Skus { - if skuID := jxutils.GetSkuIDFromOrderSku(v); skuID > 0 { - if actStoreSku := actStoreSkuMap.GetActStoreSku(jxStoreID, skuID, order.VendorID); actStoreSku != nil { - v.EarningPrice = actStoreSku.EarningPrice - if true { //v.StoreSubName != "" { // 之前这里为什么要加判断? - v.StoreSubID = actStoreSku.ActID - } - } - } - } - } - } -} - -func (c *OrderManager) updateOrderOtherInfo(order *model.GoodsOrder, db *dao.DaoDB) (err error) { - globals.SugarLogger.Debugf("updateOrderOtherInfo orderID:%s, VendorStoreID:%s", order.VendorOrderID, order.VendorStoreID) - - payPercentage := 0 - changePriceType := model.StoreChangePriceTypeDirect - storeDetail, err := dao.GetStoreDetailByVendorStoreID(db, order.VendorStoreID, order.VendorID) - if err != nil { - if !dao.IsNoRowsError(err) { - globals.SugarLogger.Warnf("updateOrderOtherInfo GetStoreDetailByVendorStoreID orderID:%s, VendorStoreID:%s, error:%v", order.VendorOrderID, order.VendorStoreID, err) - return err - } - if time.Now().Sub(order.OrderCreatedAt) < 1*time.Hour { - globals.SugarLogger.Infof("updateOrderOtherInfo [运营]订单在京西与平台都找不到京西门店信息,订单:%s,平台门店ID:%s,平台:%s", order.VendorOrderID, order.VendorStoreID, model.VendorChineseNames[order.VendorID]) - } - err = nil - } else { - order.JxStoreID = storeDetail.Store.ID - payPercentage = storeDetail.PayPercentage - changePriceType = int(storeDetail.ChangePriceType) - if payPercentage < 50 { - order.EarningType = model.EarningTypePoints - } else { - order.EarningType = model.EarningTypeQuote - } - order.OrderPayPercentage = payPercentage - } - if err = c.updateOrderSkuOtherInfo(order, db, payPercentage, changePriceType); err == nil { - jxutils.RefreshOrderSkuRelated(order) - //EarningPrice2, 新规则,门店结算比例在50以下的做新规则计算 - jxutils.RefreshOrderEarningPrice2(order, payPercentage) - // caculateOrderEarningPrice(order, payPercentage) - } - return err -} - -// 计算结算给门店的金额 -// func caculateOrderEarningPrice(order *model.GoodsOrder, storePayPercentage int) { -// order.EarningPrice = 0 -// for _, v := range order.Skus { -// skuEarningPrice := v.EarningPrice -// if skuEarningPrice == 0 { -// skuEarningPrice = jxutils.CaculateSkuEarningPrice(v.ShopPrice, v.SalePrice, storePayPercentage) -// } -// order.EarningPrice += skuEarningPrice * int64(v.Count) -// } -// } - -func (c *OrderManager) addOrderStatus(orderStatus *model.OrderStatus, db *dao.DaoDB) (isDuplicated bool, order *model.GoodsOrder, err error) { - globals.SugarLogger.Debugf("addOrderStatus refOrderID:%s, orderID:%s", orderStatus.RefVendorOrderID, orderStatus.VendorOrderID) - if db == nil { - db = dao.GetDB() - } - isDuplicated, err = addOrderOrWaybillStatus(orderStatus, db) - if err == nil && !isDuplicated && (orderStatus.Status != model.OrderStatusUnknown && orderStatus.Status != model.OrderStatusMsg) { - order = &model.GoodsOrder{ - VendorOrderID: orderStatus.VendorOrderID, - VendorID: orderStatus.VendorID, - } - if err = db.Db.ReadForUpdate(order, "VendorOrderID", "VendorID"); err == nil { - // todo 美团在订单完成后,还可能收到订单取消(应该当成售后单处理才合适),强制忽略这种情况,比如订单:80662201436073600 - // 后来又发现有订单(81710104014426376)在完成后,直接再被取消的情况,不能生成售后单,还是再允许完成后取消。。。 - // if orderStatus.VendorID == model.VendorIDMTWM && model.IsOrderFinalStatus(order.Status) { - // return false, order, nil - // } - if (model.IsOrderLockStatus(orderStatus.Status) || model.IsOrderUnlockStatus(orderStatus.Status)) || - (model.IsOrderMainStatus(orderStatus.Status) && orderStatus.Status >= order.Status) { // todo 要求status不能回绕 - order.VendorStatus = orderStatus.VendorStatus - updateFields := []string{ - "VendorStatus", - "UpdatedAt", - } - if model.IsOrderMainStatus(orderStatus.Status) { - order.Status = orderStatus.Status - order.StatusTime = orderStatus.StatusTime - updateFields = append(updateFields, "Status", "StatusTime") - if model.IsOrderFinalStatus(orderStatus.Status) { - order.OrderFinishedAt = orderStatus.StatusTime - updateFields = append(updateFields, "OrderFinishedAt") - if order.LockStatus != model.OrderStatusUnknown { - order.LockStatus = model.OrderStatusUnknown - updateFields = append(updateFields, "LockStatus") - } - } - } else { - if model.IsOrderUnlockStatus(orderStatus.Status) { - order.LockStatus = model.OrderStatusUnknown - updateFields = append(updateFields, "LockStatus") - } else if model.IsOrderLockStatus(orderStatus.Status) { - if order.LockStatus != model.OrderStatusUnknown { - globals.SugarLogger.Warnf("addOrderStatus refOrderID:%s, orderID:%s, order.LockStatus:%d, status.LockStatus:%d", orderStatus.RefVendorOrderID, orderStatus.VendorOrderID, order.LockStatus, orderStatus.Status) - } - order.Flag &= ^model.OrderFlagMaskUserApplyCancel - order.LockStatus = orderStatus.Status - order.LockStatusTime = orderStatus.StatusTime - updateFields = append(updateFields, "LockStatus", "LockStatusTime", "Flag") - } - } - utils.CallFuncLogError(func() error { - _, err = db.Db.Update(order, updateFields...) - return err - }, "addOrderStatus update orderID:%s, status:%v", order.VendorOrderID, orderStatus) - } else { - isDuplicated = true - } - } else { - order = nil - if dao.IsNoRowsError(err) { // todo 消息错序 - err = nil - } else { - globals.SugarLogger.Warnf("addOrderStatus orderID:%s read failed with error:%v", order.VendorOrderID, err) - } - } - } - return isDuplicated, order, err -} - -func (c *OrderManager) loadOrderSku(db *dao.DaoDB, vendorOrderID string, vendorID int) (orderSkus []*model.OrderSku) { - utils.CallFuncLogError(func() (err error) { - _, err = db.Db.QueryTable("order_sku").Filter("vendor_order_id", vendorOrderID).Filter("vendor_id", vendorID).All(&orderSkus) - return err - }, "loadOrderSku orderID:%s", vendorOrderID) - return orderSkus -} - -func (c *OrderManager) LoadStoreDetail(storeID, vendorID int) (storeDetail *dao.StoreDetail, err error) { - var ( - db = dao.GetDB() - ) - storeDetail, err = dao.GetStoreDetail(db, storeID, vendorID) - return storeDetail, err -} - -func (c *OrderManager) loadOrder(vendorOrderID, vendorOrderID2 string, vendorID int) (order *model.GoodsOrder, err error) { - db1 := dao.GetDB() - db := db1.Db - order = &model.GoodsOrder{ - VendorOrderID: vendorOrderID, - VendorOrderID2: vendorOrderID2, - VendorID: vendorID, - } - keyFields := []string{ - model.FieldVendorID, - } - if vendorOrderID != "" { - keyFields = append(keyFields, model.FieldVendorOrderID) - } - if vendorOrderID2 != "" { - keyFields = append(keyFields, model.FieldVendorOrderID2) - } - if err = db.Read(order, keyFields...); err == nil { - vendorOrderID = order.VendorOrderID - order.Skus = c.loadOrderSku(db1, vendorOrderID, vendorID) - } - if err != nil { - order = nil - if err == orm.ErrNoRows { - err = ErrCanNotFindOrder - } - globals.SugarLogger.Infof("LoadOrder orderID:%s failed with error:%v", vendorOrderID, err) - } - return order, err -} - -func (c *OrderManager) LoadOrder(vendorOrderID string, vendorID int) (order *model.GoodsOrder, err error) { - return c.loadOrder(vendorOrderID, "", vendorID) -} - -func (c *OrderManager) LoadOrder2(vendorOrderID2 string, vendorID int) (order *model.GoodsOrder, err error) { - return c.loadOrder("", vendorOrderID2, vendorID) -} - -func (c *OrderManager) LoadOrderFinancial(vendorOrderID string, vendorID int) (order *model.OrderFinancial, err error) { - return c.loadOrderFinancial(vendorOrderID, "", vendorID) -} - -func (c *OrderManager) LoadOrderFinancial2(vendorOrderID2 string, vendorID int) (order *model.OrderFinancial, err error) { - return c.loadOrderFinancial("", vendorOrderID2, vendorID) -} - -func (c *OrderManager) loadOrderFinancial(vendorOrderID, vendorOrderID2 string, vendorID int) (order *model.OrderFinancial, err error) { - db := orm.NewOrm() - order = &model.OrderFinancial{ - VendorOrderID: vendorOrderID, - VendorOrderID2: vendorOrderID2, - VendorID: vendorID, - } - keyFields := []string{ - model.FieldVendorID, - } - if vendorOrderID != "" { - keyFields = append(keyFields, model.FieldVendorOrderID) - } - if vendorOrderID2 != "" { - keyFields = append(keyFields, model.FieldVendorOrderID2) - } - - // 这块不知道怎么写了、、、标注一下 - if err = db.Read(order, keyFields...); err == nil { - vendorOrderID = order.VendorOrderID - err = utils.CallFuncLogError(func() error { - _, err = db.QueryTable("order_sku_financial").Filter("vendor_order_id", vendorOrderID).Filter("vendor_id", vendorID).Filter("is_afs_order", 0).All(&order.Skus) - return err - }, "LoadOrder orderID:%s", vendorOrderID) - } - if err != nil { - order = nil - if err == orm.ErrNoRows { - err = ErrCanNotFindOrder - } - globals.SugarLogger.Infof("LoadOrderFinancial orderID:%s failed with error:%v", vendorOrderID, err) - } - return order, err -} - -func (c *OrderManager) UpdateOrderStatusAndDeliveryFlag(order *model.GoodsOrder) (err error) { - return c.UpdateOrderFields(order, []string{"Status", "DeliveryFlag"}) -} - -func (c *OrderManager) UpdateOrderFields(order *model.GoodsOrder, fieldList []string) (err error) { - db := dao.GetDB() - utils.CallFuncLogError(func() error { - if order.ID == 0 { - order2 := *order - if err = dao.GetEntity(db, &order2, model.FieldVendorOrderID, model.FieldVendorID); err == nil { - order.ID = order2.ID - } else if dao.IsNoRowsError(err) { - err = nil // 强制忽略订单不存在错误 - } - } - if err == nil && order.ID != 0 { - _, err = db.Db.Update(order, fieldList...) - } - return err - }, "UpdateOrderFields orderID:%s failed with error:%v", order.VendorOrderID, err) - return err -} - -func (c *OrderManager) RefreshHistoryOrdersEarningPrice(ctx *jxcontext.Context, vendorOrderID string, actID int, vendorIDs []int, storeID int, fromDate, toDate string, isAsync, isContinueWhenError bool) (hint string, errCode string, err error) { - var ( - orderList []*model.GoodsOrder - fromDateParam time.Time - toDateParam time.Time - beginAt time.Time - endAt time.Time - ) - db := dao.GetDB() - if actID > 0 { - if fromDate != "" && toDate != "" { - fromDateParam = utils.Str2Time(fromDate) - toDateParam = utils.Str2Time(toDate) - actList, _ := dao.QueryActs(db, actID, 0, math.MaxInt32, 0, "", -1, nil, nil, nil, 0, nil, 0, utils.DefaultTimeValue, utils.DefaultTimeValue, utils.DefaultTimeValue, utils.DefaultTimeValue) - if len(actList.Data) > 0 { - actBeginAt := actList.Data[0].BeginAt - actEndAt := actList.Data[0].EndAt - if fromDateParam.Sub(actBeginAt) > 0 && fromDateParam.Sub(actEndAt) > 0 { - return "", model.ErrCodeGeneralFailed, errors.New(fmt.Sprintf("结算活动有效时间范围与订单创建时间范围不一致!,活动时间范围:[%v] 至 [%v] ,订单创建时间范围 :[%v] 至 [%v]", actBeginAt, actEndAt, fromDateParam, toDateParam)) - } - if actBeginAt.Sub(toDateParam) > 0 && actEndAt.Sub(toDateParam) > 0 { - return "", model.ErrCodeGeneralFailed, errors.New(fmt.Sprintf("结算活动有效时间范围与订单创建时间范围不一致!,活动时间范围:[%v] 至 [%v] ,订单创建时间范围 :[%v] 至 [%v]", actBeginAt, actEndAt, fromDateParam, toDateParam)) - } - if fromDateParam.Sub(actBeginAt) > 0 { - beginAt = fromDateParam - if toDateParam.Sub(actEndAt) > 0 { - endAt = actEndAt - } else { - endAt = toDateParam - } - } else { - beginAt = actBeginAt - if toDateParam.Sub(actEndAt) > 0 { - endAt = actEndAt - } else { - endAt = toDateParam - } - } - orderList, _ = dao.QueryOrders(db, vendorOrderID, actID, vendorIDs, storeID, beginAt, endAt) - } else { - return "", model.ErrCodeGeneralFailed, errors.New(fmt.Sprintf("未查询到相关结算活动,活动ID:[%d]", actID)) - } - } else if fromDate == "" && toDate == "" { - actList, _ := dao.QueryActs(db, actID, 0, math.MaxInt32, 0, "", -1, nil, nil, nil, 0, nil, 0, utils.DefaultTimeValue, utils.DefaultTimeValue, utils.DefaultTimeValue, utils.DefaultTimeValue) - if len(actList.Data) > 0 { - orderList, _ = dao.QueryOrders(db, vendorOrderID, actID, vendorIDs, storeID, actList.Data[0].BeginAt, actList.Data[0].EndAt) - if len(orderList) == 0 { - return "", model.ErrCodeGeneralFailed, errors.New(fmt.Sprintf("未查询到相关订单!开始时间:[%v],结束时间:[%v]", actList.Data[0].BeginAt, actList.Data[0].EndAt)) - } - } else { - return "", model.ErrCodeGeneralFailed, errors.New(fmt.Sprintf("未查询到相关结算活动,活动ID:[%d]", actID)) - } - } else { - return "", model.ErrCodeGeneralFailed, errors.New(fmt.Sprintf("间隔时间必须完整!时间范围:[%v] 至 [%v]", fromDate, toDate)) - } - } else { - if fromDate != "" && toDate != "" { - fromDateParam = utils.Str2Time(fromDate) - toDateParam = utils.Str2Time(toDate) - //若未传入活动ID,且时间间隔大于10天则不允许查询 - if math.Ceil(toDateParam.Sub(fromDateParam).Hours()/24) > 10 { - return "", model.ErrCodeGeneralFailed, errors.New(fmt.Sprintf("查询间隔时间不允许大于10天!时间范围:[%v] 至 [%v]", fromDate, toDate)) - } - orderList, _ = dao.QueryOrders(db, vendorOrderID, actID, vendorIDs, storeID, fromDateParam, toDateParam) - } else { - return "", model.ErrCodeGeneralFailed, errors.New(fmt.Sprintf("若不按活动查询则间隔时间必须完整!时间范围:[%v] 至 [%v]", fromDate, toDate)) - } - } - if len(orderList) <= 0 { - return "", model.ErrCodePoint, errors.New(fmt.Sprintf("所选活动没有要更新结算价的订单!,vendorOrderID : %s, actID : %d, 时间范围:[%v] 至 [%v]", vendorOrderID, actID, fromDate, toDate)) - } - task := tasksch.NewParallelTask("刷新历史订单结算价", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - order := batchItemList[0].(*model.GoodsOrder) - db := dao.GetDB() - updateSingleOrderEarningPrice(order, db) - dao.Begin(db) - defer func() { - if r := recover(); r != nil || err != nil { - dao.Rollback(db) - if r != nil { - panic(r) - } - } - }() - for _, value := range order.Skus { - // storeID := 0 - // if order.StoreID == 0 { - // storeID = order.JxStoreID - // } else { - // storeID = order.StoreID - // } - // result, _ := dao.GetEffectiveActStoreSkuInfo(db, 0, nil, 0, []int{storeID}, []int{value.SkuID}, order.OrderCreatedAt, order.OrderCreatedAt) - // if len(result) > 0 { - // if result[0].EarningPrice != 0 { - // var ( - // storePayPercentage int - // ) - // stores, _ := dao.GetStoreList(db, []int{order.StoreID}, nil, nil, nil, "") - // if len(stores) > 0 { - // storePayPercentage = stores[0].PayPercentage - // } else { - // storePayPercentage = 70 - // } - // sku := value - // sku.Count = value.Count - 1 - // value.Count = 1 - // if value.ShopPrice < value.SalePrice { - // sku.EarningPrice = value.ShopPrice * int64(storePayPercentage) - // } else { - // sku.EarningPrice = value.SalePrice * int64(storePayPercentage) - // } - // order.Skus = append(order.Skus, sku) - // } - // } - if _, err = dao.UpdateEntity(db, value, "EarningPrice", "StoreSubID"); err != nil { - return nil, err - } - } - jxutils.RefreshOrderSkuRelated(order) - storeID := 0 - if order.StoreID == 0 { - storeID = order.JxStoreID - } else { - storeID = order.StoreID - } - store, _ := dao.GetStoreDetail(db, storeID, order.VendorID) - payPercentage := store.PayPercentage - if payPercentage <= 50 { - order.NewEarningPrice = order.TotalShopMoney * int64((100 - payPercentage/2)) / 100 - } else { - order.NewEarningPrice = order.EarningPrice - } - num, err := dao.UpdateEntity(db, order, "EarningPrice", "NewEarningPrice") - if err != nil { - return nil, err - } - dao.Commit(db) - retVal = []string{utils.Int64ToStr(num)} - return retVal, err - }, orderList) - tasksch.HandleTask(task, nil, true).Run() - if !isAsync { - resultNum, err2 := task.GetResult(0) - if err = err2; err == nil { - hint = resultNum[0].(string) - } - } else { - hint = task.GetID() - } - return hint, model.ErrCodeSuccess, err -} - -func RefreshOrdersWithoutJxStoreID(ctx *jxcontext.Context, fromDate, toDate string, isAsync, isContinueWhenError bool) (hint string, err error) { - var ( - fromDateParam time.Time - toDateParam time.Time - ) - if fromDate != "" { - fromDateParam = utils.Str2Time(fromDate) - } - if toDate != "" { - toDateParam = utils.Str2Time(toDate) - } - db := dao.GetDB() - task := tasksch.NewParallelTask("订单门店归属补漏", tasksch.NewParallelConfig().SetParallelCount(1), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - _, err = dao.UpdateOrdersWithoutJxStoreID(db, fromDateParam, toDateParam) - return retVal, err - }, []int{0}) - tasksch.HandleTask(task, nil, true).Run() - if !isAsync { - _, err = task.GetResult(0) - hint = "1" - } else { - hint = task.GetID() - } - return hint, err -} - -func GetOrdersSupplement(ctx *jxcontext.Context, storIDs, vendorIDs, statuss []int, vendorOrderID, fromTime, toTime string, stype, IsReverse, offset, pageSize int) (pageInfo *model.PagedInfo, err error) { - var ( - db = dao.GetDB() - fromTimeP time.Time - toTimeP time.Time - ) - if fromTime != "" { - fromTimeP = utils.Str2Time(fromTime) - } - if toTime != "" { - toTimeP = utils.Str2Time(toTime) - } - if fromTimeP.After(toTimeP) { - return nil, fmt.Errorf("时间范围不合法!开始时间:[%v],结束时间:[%v]", fromTimeP, toTimeP) - } - result, totalCount, err := dao.GetOrdersSupplement(db, storIDs, vendorIDs, statuss, vendorOrderID, fromTimeP, toTimeP, stype, IsReverse, offset, pageSize) - pageInfo = &model.PagedInfo{ - Data: result, - TotalCount: totalCount, - } - return pageInfo, err -} - -func AddUpdateOrdersSupplement(ctx *jxcontext.Context, ordersSupplement *model.OrderSupplementFee) (num int64, err error) { - var ( - db = dao.GetDB() - id = ordersSupplement.ID - ) - now := time.Now() - ordersSupplement.SupplementTime = &now - defer func() { - if r := recover(); r != nil || err != nil { - dao.Rollback(db) - if r != nil { - panic(r) - } - } - }() - if id > 0 { - orderSupplementFee, _ := dao.GetOrdersSupplementNoPage(db, id, nil, nil, nil, "", utils.ZeroTimeValue, utils.ZeroTimeValue, 0, 0) - if len(orderSupplementFee) > 2 || len(orderSupplementFee) == 0 { - return 0, fmt.Errorf("查询扣款记录有误,请联系技术部!") - } - if orderSupplementFee[0].Status == 1 { - return 0, fmt.Errorf("已结账的扣款信息不允许修改!门店ID:[%v],订单号:[%v]", ordersSupplement.StoreID, ordersSupplement.VendorOrderID) - } - ordersSupplement.UpdatedAt = time.Now() - ordersSupplement.LastOperator = ctx.GetUserName() - ordersSupplement.CreatedAt = orderSupplementFee[0].CreatedAt - if ordersSupplement.Status == -1 { - ordersSupplement.DeletedAt = time.Now() - } else { - ordersSupplement.DeletedAt = utils.DefaultTimeValue - } - num, err = dao.UpdateEntity(db, ordersSupplement) - } else { - dao.WrapAddIDCULDEntity(ordersSupplement, ctx.GetUserName()) - err = dao.CreateEntity(db, ordersSupplement) - } - dao.Commit(db) - return num, err -} - -func RefreshOrdersPriceInfo(ctx *jxcontext.Context, fromTime, toTime time.Time, isAsync, isContinueWhenError bool) (hint string, err error) { - if utils.IsTimeZero(fromTime) { - return "", fmt.Errorf("必须指定起始时间") - } - if utils.IsTimeZero(toTime) { - toTime = fromTime - } - - db := dao.GetDB() - orderList, err := dao.QueryOrders(db, "", 0, nil, 0, fromTime, toTime) - if err == nil && len(orderList) > 0 { - task := tasksch.NewParallelTask("RefreshOrdersPriceInfo", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - curOrder := batchItemList[0].(*model.GoodsOrder) - newOrder, err := FixedOrderManager.LoadOrder(curOrder.VendorOrderID, curOrder.VendorID) - if err == nil { - db := dao.GetDB() - if err = FixedOrderManager.updateOrderOtherInfo(newOrder, db); err == nil { - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - if _, err = dao.UpdateEntity(db, newOrder); err != nil { - dao.Rollback(db) - return nil, err - } - - for _, sku := range newOrder.Skus { - if _, err = dao.UpdateEntity(db, sku); err != nil { - dao.Rollback(db) - return nil, err - } - } - dao.Commit(db) - } - } - return retVal, err - }, orderList) - tasksch.HandleTask(task, nil, true).Run() - if isAsync { - hint = task.GetID() - } else { - _, err = task.GetResult(0) - hint = "1" - } - } - return hint, err -} - -type GetOrderSimpleInfoResult struct { - VendorOrderID string `orm:"column(vendor_order_id)" json:"vendorOrderID"` - Status int `json:"status"` - WaybillVendorID int `orm:"column(waybill_vendor_id)" json:"waybillVendorID"` - CourierName string `json:"courierName"` - CourierMobile string `json:"courierMobile"` - Tel1 string `json:"tel1"` - MarketManPhone string `json:"marketManPhone"` -} - -func GetOrderSimpleInfo(ctx *jxcontext.Context, vendorOrderID string) (getOrderSimpleInfoResult *GetOrderSimpleInfoResult, err error) { - db := dao.GetDB() - sql := ` - SELECT a.vendor_order_id, a.status, a.waybill_vendor_id, c.courier_name, c.courier_mobile, b.tel1, b.market_man_phone - FROM goods_order a - JOIN store b ON IF(a.store_id <> '', a.store_id, a.jx_store_id) = b.id - LEFT JOIN waybill c ON c.vendor_order_id = a.vendor_order_id - WHERE a.vendor_order_id = ? - ` - sqlParams := []interface{}{vendorOrderID} - err = dao.GetRow(db, &getOrderSimpleInfoResult, sql, sqlParams) - if getOrderSimpleInfoResult == nil { - return getOrderSimpleInfoResult, fmt.Errorf("未查询到该订单的信息!") - } - - return getOrderSimpleInfoResult, err -} - -func SaveJdsOrders(ctx *jxcontext.Context, orderCreatedStart, orderCreatedEnd time.Time) (err error) { - var ( - pageSize = 20 - ) - orderResult, err := jdshop.CurPurchaseHandler.GetJdsOrders(ctx, utils.Time2Str(orderCreatedStart), utils.Time2Str(orderCreatedEnd), 1, pageSize) - if err != nil { - noticeMsg := fmt.Sprintf("京东商城保存订单出错!(多半是cookie过期了),err :[%v]", err) - ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "DDC5657B43EE11E9A9FF525400E86DC0", "cookie", noticeMsg) - ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "1439B3E07D3911EA881A525400E86DC0", "cookie", noticeMsg) - return err - } - orders, err := result2Orders(ctx, orderResult) - if orderResult.TotalCount > pageSize { - for pageNO := 2; pageNO < orderResult.TotalCount/pageSize+1; pageNO++ { - orderResult, _ := jdshop.CurPurchaseHandler.GetJdsOrders(ctx, utils.Time2Str(orderCreatedStart), utils.Time2Str(orderCreatedEnd), pageNO, pageSize) - orders2, _ := result2Orders(ctx, orderResult) - orders = append(orders, orders2...) - } - } - for _, order := range orders { - order.StoreID = 102919 - order.JxStoreID = 102919 - order.StoreName = "商城模板(成都发货)" - order.VendorStoreID = model.JdShopMainVendorStoreID - partner.CurOrderManager.OnOrderNew(order, model.Order2Status(order)) - globals.SugarLogger.Debugf("SaveJdsOrders, order: [%v]", utils.Format4Output(order, false)) - noticeMsg := fmt.Sprintf("京东商城新订单,订单号:[%v] ,将要发到的门店id:[%v] , 门店名:[%v]", order.VendorOrderID, order.StoreID, order.StoreName) - ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "DDC5657B43EE11E9A9FF525400E86DC0", "京东商城来新订单了!", noticeMsg) - ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "1439B3E07D3911EA881A525400E86DC0", "京东商城来新订单了!", noticeMsg) - } - return err -} - -func result2Orders(ctx *jxcontext.Context, result *jdshopapi.AllOrdersResult) (orders []*model.GoodsOrder, err error) { - for _, jdsOrder := range result.OrderList { - //等待付款的排除 - if jdsOrder.OrderStatus != jdshopapi.JdsOrderStatusWaittingExport && jdsOrder.OrderStatus != jdshopapi.JdsOrderStatusPause { - continue - } - //有可能是库里已经有这个订单了 - orderE, err := partner.CurOrderManager.LoadOrder(utils.Int64ToStr(jdsOrder.OrderID)+"000001", model.VendorIDJDShop) - if orderE != nil { - continue - } - orderDetail, err := api.JdShopAPI.OrderDetail(utils.Int64ToStr(jdsOrder.OrderID)) - if err != nil { - globals.SugarLogger.Debugf("jds OrderDetail error: %v", err.Error()) - continue - } - order := &model.GoodsOrder{ - VendorOrderID2: utils.Int64ToStr(jdsOrder.OrderID), - VendorOrderID: utils.Int64ToStr(jdsOrder.OrderID) + "000001", - VendorID: model.VendorIDJDShop, - BaseFreightMoney: jxutils.StandardPrice2Int(jdsOrder.Freight), - VendorStatus: utils.Int2Str(jdsOrder.OrderStatus), - VendorUserID: jdsOrder.UserPin, - BuyerComment: jdsOrder.UserRemark, - PickDeadline: utils.DefaultTimeValue, - OriginalData: string(utils.MustMarshal(jdsOrder)), - StoreName: jdsOrder.StoreName, - OrderCreatedAt: utils.Str2Time(jdsOrder.OrderCreateTime + ":00"), - ConsigneeAddress: orderDetail.ConsigneeAddress, - ConsigneeName: orderDetail.ConsigneeName, - ActualPayPrice: orderDetail.ActualPayPrice, - Status: model.OrderStatusNew, - TotalShopMoney: utils.Float64TwoInt64(math.Round(utils.Int64ToFloat64(orderDetail.ActualPayPrice) * jdshopapi.JdsPayPercentage)), - DeliveryFlag: model.OrderDeliveryFlagMaskScheduleDisabled, - DeliveryType: model.OrderDeliveryTypeStoreSelf, - StatusTime: utils.Str2Time(jdsOrder.OrderCreateTime + ":00"), - OrderSeq: 0, - } - //获取真实手机号 - fakeMobile, err := api.JdShopAPI.PhoneSensltiveInfo(order.VendorOrderID2, orderDetail.MobileKey) - if err != nil { - globals.SugarLogger.Debugf("jds PhoneSensltiveInfo error: %v", err.Error()) - continue - } else { - order.ConsigneeMobile = jxutils.DecryptDESECB([]byte(fakeMobile), []byte(jdshopapi.JdsMobileKey)) - } - if order.TotalShopMoney < 100 { - order.TotalShopMoney = 100 - } - if order.ConsigneeAddress != "" { - lng, lat, _ := api.AutonaviAPI.GetCoordinateFromAddress(order.ConsigneeAddress, "") - order.ConsigneeLng = jxutils.StandardCoordinate2Int(lng) - order.ConsigneeLat = jxutils.StandardCoordinate2Int(lat) - } - storeList, err := common.GetStoreListByLocation(ctx, jxutils.IntCoordinate2Standard(order.ConsigneeLng), jxutils.IntCoordinate2Standard(order.ConsigneeLat), 5000, false, true) - if err != nil { - globals.SugarLogger.Debugf("jds GetStoreListByLocation error: %v", err.Error()) - continue - } - order.StoreID = storeList[0].ID - order.StoreName = storeList[0].Name - storeMaps, _ := dao.GetStoresMapList(dao.GetDB(), []int{model.VendorIDJDShop}, []int{order.StoreID}, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "") - if len(storeMaps) > 0 { - order.VendorStoreID = storeMaps[0].VendorStoreID - } - //如果是暂停,表示是预订单 - if jdsOrder.OrderStatus == jdshopapi.JdsOrderStatusPause { - order.BusinessType = model.BusinessTypeDingshida - order.ExpectedDeliveredTime = utils.Str2Time(orderDetail.ExpectedDeliveredTime) - order.PickDeadline = order.ExpectedDeliveredTime.Add(-time.Hour) - } else if jdsOrder.OrderStatus == jdshopapi.JdsOrderStatusWaittingExport { - order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour) - order.BusinessType = model.BusinessTypeImmediate - } else { - globals.SugarLogger.Errorf("未知的京东商城订单状态!status : %v", jdsOrder.OrderStatus) - } - - //结算类型 - storeDetail, _ := dao.GetStoreDetail(dao.GetDB(), order.StoreID, model.VendorIDJDShop) - if storeDetail != nil { - if storeDetail.PayPercentage < 50 { - order.EarningType = model.EarningTypePoints - } else { - order.EarningType = model.EarningTypeQuote - } - } - setJdsOrderSeq(order) - for _, v := range jdsOrder.OrderItems { - sku := &model.OrderSku{ - VendorID: model.VendorIDJDShop, - VendorOrderID: order.VendorOrderID, - Count: v.SkuNum, - VendorSkuID: utils.Int64ToStr(v.SkuID), - SkuName: v.SkuName, - VendorPrice: jxutils.StandardPrice2Int(v.JdPrice), - SalePrice: jxutils.StandardPrice2Int(v.JdPrice), - } - var storeSku *model.StoreSkuBind - sql := ` - SELECT * FROM store_sku_bind WHERE store_id = ? AND jds_id = ? AND deleted_at = ? - ` - sqlParams := []interface{}{model.JdShopMainStoreID, v.SkuID, utils.DefaultTimeValue} - err = dao.GetRow(dao.GetDB(), &storeSku, sql, sqlParams) - if storeSku != nil { - sku.SkuID = storeSku.SkuID - } - _, _, _, specUnit, _, specQuality := jxutils.SplitSkuName(v.SkuName) - sku.Weight = jxutils.FormatSkuWeight(specQuality, specUnit) - order.Skus = append(order.Skus, sku) - } - orders = append(orders, order) - } - return orders, err -} - -func setJdsOrderSeq(order *model.GoodsOrder) (err error) { - type tCount struct { - Count int `json:"count"` - } - var counts []*tCount - sql := ` - SELECT count(*) count FROM goods_order WHERE store_id = ? AND order_created_at >= ? AND order_created_at <= ? AND vendor_id = ? - ` - sqlParams := []interface{}{ - order.StoreID, utils.Time2Date(time.Now()), utils.Time2Date(time.Now().AddDate(0, 0, 1)), order.VendorID, - } - err = dao.GetRows(dao.GetDB(), &counts, sql, sqlParams) - order.OrderSeq = counts[0].Count + 1 - return err -} - -func MergeJdsOrders(ctx *jxcontext.Context, vendorOrderIDs []string) (vendorOrderIDJds string, err error) { - globals.SugarLogger.Debugf("jds MergeJdsOrders vendorOrderIDs: %v", vendorOrderIDs) - var ( - db = dao.GetDB() - orders []*model.GoodsOrder - orderSkus []*model.OrderSku - orderIDs []string - storeDuplicate = make(map[int]int) - storeID int - ) - for _, vendorOrderID := range vendorOrderIDs { - order, _ := dao.GetSimpleOrder(db, vendorOrderID) - if err != nil || order == nil { - return "", fmt.Errorf("未查询到该订单!订单号:[%v]", vendorOrderID) - } - if order.Status >= model.OrderStatusDelivering && order.Status != model.OrderStatusCanceled { - return "", fmt.Errorf("暂不支持此状态的订单进行转移!订单号:[%v]", vendorOrderID) - } - if order.VendorID != model.VendorIDJDShop { - return "", fmt.Errorf("暂不支持非京狗的订单进行转移!订单号:[%v]", vendorOrderID) - } - storeDuplicate[jxutils.GetSaleStoreIDFromOrder(order)] = jxutils.GetSaleStoreIDFromOrder(order) - orders = append(orders, order) - - //订单商品 - skus, _ := dao.GetSimpleOrderSkus(db, order.VendorOrderID, nil) - orderSkus = append(orderSkus, skus...) - - orderIDs = append(orderIDs, vendorOrderID) - } - if len(storeDuplicate) > 1 { - return "", fmt.Errorf("只能选择相同门店的订单进行合并!") - } else { - storeID = jxutils.GetSaleStoreIDFromOrder(orders[0]) - } - for _, order := range orders { - var waybill *model.Waybill - //将订单和运单取消 - waybills, err := dao.GetWaybills(db, order.VendorOrderID) - if err != nil { - return "", err - } - if len(waybills) > 0 { - for _, v := range waybills { - if v.Status != model.WaybillStatusCanceled { - waybill = v - } - } - if waybill != nil { - if waybill.WaybillVendorID != model.VendorIDJDWL { - if handler := partner.GetDeliveryPlatformFromVendorID(waybill.WaybillVendorID); handler != nil { - err = handler.Handler.CancelWaybill(waybill, 0, "订单合并被取消") - } - } - } - } - if err = jdshop.ChangeOrderStatus(order.VendorOrderID, model.OrderStatusCanceled, "订单合并被取消"); err != nil { - return "", err - } - } - //重新构建order的数据 - storeMaps, err := dao.GetStoresMapList(db, []int{model.VendorIDJDShop}, []int{storeID}, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "") - if err != nil || len(storeMaps) == 0 { - return "", fmt.Errorf("该门店未绑定京狗平台,请先绑定后再转移!门店:[%v]", storeID) - } - stores, _ := dao.GetStoreList(db, []int{storeID}, nil, nil, nil, "") - var ( - newEarningPrice int64 - actualPrice int64 - shopPrice int64 - salePrice int64 - totalShop int64 - ) - for _, v := range orders { - newEarningPrice += v.NewEarningPrice - actualPrice += v.ActualPayPrice - shopPrice += v.ShopPrice - salePrice += v.SalePrice - totalShop += v.TotalShopMoney - } - store := stores[0] - order := orders[0] - order.ID = 0 - order.NewEarningPrice = newEarningPrice - order.ActualPayPrice = actualPrice - order.SalePrice = salePrice - order.ShopPrice = shopPrice - order.TotalShopMoney = totalShop - order.VendorOrderID = utils.Int64ToStr(utils.Str2Int64(orders[0].VendorOrderID2)*10000) + utils.Int2Str(time.Now().Second()) - if len(order.VendorOrderID) < 18 { - order.VendorOrderID = order.VendorOrderID + "0" - } - order.VendorOrderID2 = strings.Join(orderIDs, ",") - order.Status = model.OrderStatusNew - setJdsOrderSeq(order) - if order.BusinessType == model.BusinessTypeImmediate { - var ( - opentime1 = jxutils.JxOperationTime2TimeByDate(store.OpenTime1, order.CreatedAt) - opentime2 = jxutils.JxOperationTime2TimeByDate(store.OpenTime2, order.CreatedAt) - closetime1 = jxutils.JxOperationTime2TimeByDate(store.CloseTime1, order.CreatedAt) - closetime2 = jxutils.JxOperationTime2TimeByDate(store.CloseTime2, order.CreatedAt) - orderCreatedAt = order.CreatedAt - ) - if store.OpenTime1 == 0 || store.CloseTime1 == 0 { - return "", fmt.Errorf("该门店没有营业时间,不能接单!门店:[%v]", storeID) - } - if !(orderCreatedAt.Sub(opentime1) >= 0 && orderCreatedAt.Sub(closetime1) <= 0) { - if store.OpenTime2 != 0 && store.CloseTime2 != 0 { - if !(orderCreatedAt.Sub(opentime2) >= 0 && orderCreatedAt.Sub(closetime2) <= 0) { - if orderCreatedAt.Sub(opentime1) < 0 { - order.ExpectedDeliveredTime = opentime1 - order.BusinessType = model.BusinessTypeDingshida - } else { - if orderCreatedAt.Sub(opentime2) < 0 { - order.ExpectedDeliveredTime = opentime2 - } else { - order.ExpectedDeliveredTime = opentime1.AddDate(0, 0, 1) - } - order.BusinessType = model.BusinessTypeDingshida - } - } - } else { - if orderCreatedAt.Sub(opentime1) < 0 { - order.ExpectedDeliveredTime = opentime1 - } else { - order.ExpectedDeliveredTime = opentime1.AddDate(0, 0, 1) - } - order.BusinessType = model.BusinessTypeDingshida - } - } - } - //结算类型 - if store.PayPercentage < 50 { - order.EarningType = model.EarningTypePoints - } else { - order.EarningType = model.EarningTypeQuote - } - if storeID != model.JdShopMainStoreID { - order.DeliveryFlag = model.NO - } - //skus - for _, sku := range orderSkus { - sku.VendorOrderID = order.VendorOrderID - sku.ID = 0 - } - order.Skus = orderSkus - err = partner.CurOrderManager.OnOrderNew(order, model.Order2Status(order)) - vendorOrderIDJds = order.VendorOrderID - return vendorOrderIDJds, err -} - -func TransferJdsOrder(ctx *jxcontext.Context, vendorOrderID string, storeID int) (vendorOrderIDJds string, err error) { - globals.SugarLogger.Debugf("jds TransferJdsOrder vendorOrderID: %v, storeID : %v", vendorOrderID, storeID) - var ( - db = dao.GetDB() - waybill *model.Waybill - ) - order, err := dao.GetSimpleOrder(db, vendorOrderID) - if err != nil || order == nil { - return "", fmt.Errorf("未查询到该订单!订单号:[%v]", vendorOrderID) - } - if order.Status >= model.OrderStatusDelivering && order.Status != model.OrderStatusCanceled { - return "", fmt.Errorf("暂不支持此状态的订单进行转移!") - } - if order.VendorID != model.VendorIDJDShop && order.VendorID != model.VendorIDJX { - return "", fmt.Errorf("暂不支持该平台的订单进行转移!") - } - skus, err := dao.GetSimpleOrderSkus(db, vendorOrderID, nil) - if err != nil || order == nil { - return "", fmt.Errorf("未查询到该订单商品!订单号:[%v]", vendorOrderID) - } - //将订单和运单取消 - waybills, err := dao.GetWaybills(db, vendorOrderID) - if err != nil { - return "", err - } - if len(waybills) > 0 { - for _, v := range waybills { - if v.Status != model.WaybillStatusCanceled { - waybill = v - } - } - if waybill != nil { - if handler := partner.GetDeliveryPlatformFromVendorID(waybill.WaybillVendorID); handler != nil { - err = handler.Handler.CancelWaybill(waybill, 0, "订单转移被取消") - } - } - } - //重新构建order的数据 - storeMaps, err := dao.GetStoresMapList(db, []int{order.VendorID}, []int{storeID}, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "") - if err != nil || len(storeMaps) == 0 { - return "", fmt.Errorf("该门店未绑定平台,请先绑定后再转移!门店:[%v]", storeID) - } - stores, err := dao.GetStoreList(db, []int{storeID}, nil, nil, nil, "") - if len(storeMaps) > 0 && len(stores) > 0 { - if storeMaps[0].VendorStoreID == "" { - return "", fmt.Errorf("该门店未绑定平台,或绑定有误,请联系技术部!门店:[%v]", storeID) - } - order.StoreID = storeID - order.StoreName = stores[0].Name - order.VendorStoreID = storeMaps[0].VendorStoreID - //如果是立即达的订单,要判断一下下单时间是否在门店营业时间范围内 - //若没有,则要把这个订单变成定时达,预计送达时间改为门店的营业时间 - //如果门店没有营业时间,则直接报错 - if order.BusinessType == model.BusinessTypeImmediate { - store := stores[0] - var ( - opentime1 = jxutils.JxOperationTime2TimeByDate(store.OpenTime1, order.OrderCreatedAt) - opentime2 = jxutils.JxOperationTime2TimeByDate(store.OpenTime2, order.OrderCreatedAt) - closetime1 = jxutils.JxOperationTime2TimeByDate(store.CloseTime1, order.OrderCreatedAt) - closetime2 = jxutils.JxOperationTime2TimeByDate(store.CloseTime2, order.OrderCreatedAt) - orderCreatedAt = order.OrderCreatedAt - ) - if store.OpenTime1 == 0 || store.CloseTime1 == 0 { - return "", fmt.Errorf("该门店没有营业时间,不能接单!门店:[%v]", storeID) - } - if closetime1.Sub(opentime1) <= time.Hour { - return "", fmt.Errorf("该门店营业时间间隔过小,请确认!门店:[%v]", storeID) - } - if !(orderCreatedAt.Sub(opentime1) >= 0 && orderCreatedAt.Sub(closetime1) <= 0) { - if store.OpenTime2 != 0 && store.CloseTime2 != 0 { - if !(orderCreatedAt.Sub(opentime2) >= 0 && orderCreatedAt.Sub(closetime2) <= 0) { - if orderCreatedAt.Sub(opentime1) < 0 { - order.ExpectedDeliveredTime = opentime1 - order.BusinessType = model.BusinessTypeDingshida - } else { - if orderCreatedAt.Sub(opentime2) < 0 { - order.ExpectedDeliveredTime = opentime2 - } else { - order.ExpectedDeliveredTime = opentime1.AddDate(0, 0, 1) - } - order.BusinessType = model.BusinessTypeDingshida - } - } - } else { - if orderCreatedAt.Sub(opentime1) < 0 { - order.ExpectedDeliveredTime = opentime1 - } else { - order.ExpectedDeliveredTime = opentime1.AddDate(0, 0, 1) - } - order.BusinessType = model.BusinessTypeDingshida - } - } - } - //结算类型 - if stores[0].PayPercentage < 50 { - order.EarningType = model.EarningTypePoints - } else { - order.EarningType = model.EarningTypeQuote - } - } else { - return "", fmt.Errorf("未查询到该门店对应的平台信息!门店:[%v]", order.StoreID) - } - if order.VendorID == model.VendorIDJDShop { - if len(order.VendorOrderID) > 12 { - var goodsOrders []*model.GoodsOrder - sql := ` - SELECT * FROM goods_order WHERE vendor_order_id2 = ? ORDER BY vendor_order_id DESC - ` - sqlParams := []interface{}{order.VendorOrderID2} - err = dao.GetRows(db, &goodsOrders, sql, sqlParams) - if goodsOrders[0].Status != model.OrderStatusCanceled { - err = jdshop.ChangeOrderStatus(goodsOrders[0].VendorOrderID, model.OrderStatusCanceled, "订单转移被取消") - } - // suffix := utils.Str2Int(goodsOrders[0].VendorOrderID[12:len(goodsOrders[0].VendorOrderID)]) - // suffix++ - if len(order.VendorOrderID2) > 18 { - order.VendorOrderID2 = order.VendorOrderID2[0:12] - } - order.VendorOrderID = utils.Int64ToStr(utils.Str2Int64(order.VendorOrderID2)*10000) + utils.Int2Str(time.Now().Second()) - if len(order.VendorOrderID) < 18 { - order.VendorOrderID = order.VendorOrderID + "0" - } - } - if storeID != model.JdShopMainStoreID { - order.DeliveryFlag = model.NO - } - err = jdshop.ChangeOrderStatus(vendorOrderID, model.OrderStatusCanceled, "订单转移被取消") - if err != nil { - return "", err - } - order.Status = model.OrderStatusNew - } else { - order.VendorOrderID2 = order.VendorOrderID - order.VendorOrderID = utils.Int64ToStr(jxutils.GenOrderNo()) - order.DeliveryFlag = model.NO - orderStatus := &model.OrderStatus{ - VendorOrderID: vendorOrderID, - VendorID: model.VendorIDJX, - OrderType: model.OrderTypeOrder, - RefVendorOrderID: vendorOrderID, - RefVendorID: model.VendorIDJX, - VendorStatus: utils.Int2Str(model.OrderStatusCanceled), - Status: model.OrderStatusCanceled, - StatusTime: time.Now(), - Remark: "订单转移被取消", - } - jxutils.CallMsgHandlerAsync(func() { - err = partner.CurOrderManager.OnOrderStatusChanged("", orderStatus) - }, jxutils.ComposeUniversalOrderID(vendorOrderID, model.VendorIDJX)) - if err != nil { - return "", err - } - order.Status = model.OrderStatusAccepted - } - for _, sku := range skus { - sku.VendorOrderID = order.VendorOrderID - sku.ID = 0 - order.Skus = append(order.Skus, sku) - } - setJdsOrderSeq(order) - err = partner.CurOrderManager.OnOrderNew(order, model.Order2Status(order)) - vendorOrderIDJds = order.VendorOrderID - return vendorOrderIDJds, err -} - -func SendJdwlForJdsOrder(ctx *jxcontext.Context, vendorOrderID string) (err error) { - db := dao.GetDB() - order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, model.VendorIDJDShop) - if order == nil || err != nil { - return fmt.Errorf("目前只支持京狗订单创建!") - } - if order.Status >= model.OrderStatusDelivering { - return fmt.Errorf("订单当前状态不支持创建!") - } - waybill := &model.Waybill{} - waybills, err := dao.GetWaybills(db, vendorOrderID) - if err != nil { - return err - } - if len(waybills) > 0 { - for _, v := range waybills { - if v.Status != model.WaybillStatusCanceled { - waybill = v - } - } - if handler := partner.GetDeliveryPlatformFromVendorID(model.VendorIDJDWL); handler != nil { - err = handler.Handler.CancelWaybill(waybill, 0, "订单已发送其他物流") - } - if err != nil { - return err - } - } - var vendorWaybillID string - if order.StoreID == model.JdShopMainStoreID { - var ( - goodsNos []string - prices []string - quantities []string - ) - for _, v := range order.Skus { - skus, err := dao.GetSkus(db, []int{v.SkuID}, nil, nil, nil, nil) - if err != nil || len(skus) == 0 { - continue - } - goodsNos = append(goodsNos, skus[0].EclpID) - prices = append(prices, "0") - quantities = append(quantities, utils.Int2Str(v.Count)) - } - eclpSoNo, err := api.JdEclpAPI.AddOrder(&jdeclpapi.AddOrderParam{ - IsvUUID: order.VendorOrderID, - IsvSource: jdeclpapi.IsvSource, - ShopNo: jdeclpapi.ShopNo, - DepartmentNo: jdeclpapi.DepartmentNo, - WarehouseNo: jdeclpapi.WarehouseNo, - SalesPlatformOrderNo: order.VendorOrderID, - SalePlatformSource: jdeclpapi.SalePlatformSource, - ConsigneeName: order.ConsigneeName, - ConsigneeMobile: order.ConsigneeMobile, - ConsigneeAddress: order.ConsigneeAddress, - OrderMark: jdeclpapi.OrderMark, - GoodsNo: strings.Join(goodsNos, ","), - Price: strings.Join(prices, ","), - Quantity: strings.Join(quantities, ","), - }) - waybill := &model.Waybill{ - VendorOrderID: order.VendorOrderID, - OrderVendorID: model.VendorIDJX, - VendorWaybillID: eclpSoNo, - WaybillVendorID: model.VendorIDJDWL, - Status: model.WaybillStatusDelivering, - WaybillCreatedAt: time.Now(), - StatusTime: time.Now(), - WaybillFinishedAt: utils.DefaultTimeValue, - DeliveryFlag: model.OrderDeliveryFlagMaskScheduleDisabled, - } - dao.CreateEntity(db, waybill) - if err != nil { - return err - } - order.EclpOutID = eclpSoNo - dao.UpdateEntity(db, order, "EclpOutID") - vendorWaybillID = eclpSoNo - } else { - if handler := partner.GetDeliveryPlatformFromVendorID(model.VendorIDJDWL); handler != nil { - waybill2, err := handler.Handler.CreateWaybill(order, 0) - if err != nil { - return err - } - vendorWaybillID = waybill2.VendorWaybillID - } - } - jdshop.CurPurchaseHandler.OrderExport(ctx, vendorOrderID, vendorWaybillID, false) - return err -} - -func AdjustJdsOrderSimple(ctx *jxcontext.Context, vendorOrderID string, skuID int) (err error) { - var ( - db = dao.GetDB() - ) - orderSkus, err := dao.GetSimpleOrderSkus(db, vendorOrderID, []int{skuID}) - order, err := dao.GetSimpleOrder(db, vendorOrderID) - //如果不是商城模板店 - if jxutils.GetSaleStoreIDFromOrder(order) != model.JdShopMainStoreID { - return fmt.Errorf("目前只支持商城模板店的简单售前删除!") - } - orderSkus2, err := dao.GetSimpleOrderSkus(db, vendorOrderID, nil) - if len(orderSkus2) == 1 { - return fmt.Errorf("这一单只剩这最后一个商品了,不允许删除!") - } - if len(orderSkus) == 0 { - return fmt.Errorf("未查询到该订单商品!") - } - if order.Status > model.OrderStatusAccepted { - return fmt.Errorf("目前只支持待拣货状态前的订单售前调整!") - } - orderSku := orderSkus[0] - if orderSku.Count > 1 { - orderSku.Count-- - _, err = dao.UpdateEntity(db, orderSku, "Count") - } else { - _, err = dao.DeleteEntity(db, orderSku) - } - - return err -} - -func UpdateWaybillDesiredFee(ctx *jxcontext.Context, vendorOrderID string, desiredFee int) (err error) { - var ( - db = dao.GetDB() - ) - order, _ := dao.GetSimpleOrder(db, vendorOrderID) - if order == nil { - return fmt.Errorf("未找到该订单!orderID: %v", vendorOrderID) - } - bill, _ := partner.CurOrderManager.LoadWaybill(order.VendorWaybillID, order.WaybillVendorID) - if bill == nil { - waybill := &model.Waybill{ - VendorOrderID: order.VendorOrderID, - OrderVendorID: order.VendorID, - VendorWaybillID: utils.Int64ToStr(GenOrderNo(ctx)), - WaybillVendorID: -1, - Status: model.WaybillStatusDelivered, - WaybillCreatedAt: time.Now(), - StatusTime: time.Now(), - WaybillFinishedAt: utils.DefaultTimeValue, - DeliveryFlag: model.OrderDeliveryFlagMaskScheduleDisabled, - DesiredFee: int64(desiredFee), - } - dao.CreateEntity(db, waybill) - order.VendorWaybillID = waybill.VendorWaybillID - dao.UpdateEntity(db, order, "VendorWaybillID") - } else { - bill.DesiredFee = int64(desiredFee) - _, err = dao.UpdateEntity(db, bill, "DesiredFee") - if order.EarningType == model.EarningTypePoints { - order.NewEarningPrice = order.NewEarningPrice - int64(desiredFee) - _, err = dao.UpdateEntity(db, order, "NewEarningPrice") - } - } - return err -} - -func AcceptOrRefuseOrder(ctx *jxcontext.Context, vendorOrderID string, vendorID int, isAccept bool) (err error) { - order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, vendorID) - handler := partner.GetPurchaseOrderHandlerFromVendorID(vendorID) - return handler.AcceptOrRefuseOrder(order, isAccept, ctx.GetUserName()) -} - -func GenOrderNo(ctx *jxcontext.Context) (orderNo int64) { - const prefix = 88 - const randPartNum = 1000 - orderNo = time.Now().Unix() - orderNoBeginTimestamp - // fmt.Println(orderNo) - orderNo = orderNo * randPartNum - md5Bytes := md5.Sum([]byte(utils.GetUUID())) - randPart := 0 - for k, v := range md5Bytes { - randPart += int(v) << ((k % 3) * 8) - } - orderNo += int64(randPart % randPartNum) - orderNo += int64(math.Pow10(int(math.Log10(float64(orderNo)))+1)) * prefix - return orderNo -} - -func RefreshJdsOrderConsigneeInfo(ctx *jxcontext.Context, vendorOrderID string) (err error) { - order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, model.VendorIDJDShop) - if order == nil { - return fmt.Errorf("未查询到此京东商城订单!") - } - waybill, err := partner.CurOrderManager.LoadWaybill(order.VendorWaybillID, order.WaybillVendorID) - if waybill != nil { - return fmt.Errorf("已经创建了三方运单不允许修改联系人信息!") - } - jdsOrder, err := jdshop.GetJdsOrder(order.VendorOrderID2) - if err != nil { - return err - } - if jdsOrder == nil { - return fmt.Errorf("未查询到对应的京东商城订单!") - } - order.ConsigneeAddress = jdshop.Decrypt(jdsOrder.ConsigneeInfo.FullAddress) - order.ConsigneeName = jdshop.Decrypt(jdsOrder.ConsigneeInfo.Fullname) - order.ConsigneeMobile = jdshop.Decrypt(jdsOrder.ConsigneeInfo.Mobile) - order.ConsigneeMobile2 = jdshop.Decrypt(jdsOrder.ConsigneeInfo.Telephone) - order.BuyerComment = jdsOrder.OrderRemark - if order.ConsigneeAddress != "" { - lng, lat, _ := api.AutonaviAPI.GetCoordinateFromAddress(order.ConsigneeAddress, "") - order.ConsigneeLng = jxutils.StandardCoordinate2Int(lng) - order.ConsigneeLat = jxutils.StandardCoordinate2Int(lat) - } - partner.CurOrderManager.UpdateOrderFields(order, []string{"ConsigneeAddress", "ConsigneeName", "ConsigneeMobile", "ConsigneeMobile2", "BuyerComment", "ConsigneeLng", "ConsigneeLat"}) - return err -} - -func UpdateOrderInfo(ctx *jxcontext.Context, vendorOrderID string, vendorID int, payload map[string]interface{}) (num int64, err error) { - var ( - db = dao.GetDB() - ) - order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, vendorID) - valid := dao.StrictMakeMapByStructObject(payload, order, ctx.GetUserName()) - if len(valid) > 0 { - if payload["consigneeLng"] != nil || payload["consigneeLat"] != nil { - intLng := jxutils.StandardCoordinate2Int(utils.Interface2Float64WithDefault(payload["consigneeLng"], 0.0)) - intLat := jxutils.StandardCoordinate2Int(utils.Interface2Float64WithDefault(payload["consigneeLat"], 0.0)) - if intLng != 0 && intLng != order.ConsigneeLng { - valid["consigneeLng"] = intLng - } - if intLat != 0 && intLat != order.ConsigneeLat { - valid["consigneeLat"] = intLat - } - } - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - if num, err = dao.UpdateEntityByKV(db, order, valid, nil); err != nil { - dao.Rollback(db) - return 0, err - } - dao.Commit(db) - } - return num, err -} diff --git a/business/jxcallback/orderman/order_afs.go b/business/jxcallback/orderman/order_afs.go deleted file mode 100644 index 1c5ca6fbf..000000000 --- a/business/jxcallback/orderman/order_afs.go +++ /dev/null @@ -1,424 +0,0 @@ -package orderman - -import ( - "strings" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler" - "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" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" - "github.com/astaxie/beego/orm" -) - -func (c *OrderManager) LoadAfsOrder(vendorAfsOrderID string, vendorID int) (afsOrder *model.AfsOrder, err error) { - return c.loadAfsOrder(dao.GetDB(), vendorAfsOrderID, vendorID) -} - -func (c *OrderManager) loadAfsOrder(db *dao.DaoDB, vendorAfsOrderID string, vendorID int) (afsOrder *model.AfsOrder, err error) { - afsOrder = &model.AfsOrder{ - AfsOrderID: vendorAfsOrderID, - VendorID: vendorID, - } - if err = dao.GetEntity(db, afsOrder, "AfsOrderID", "VendorID"); err != nil { - afsOrder = nil - } - return afsOrder, err -} - -func (c *OrderManager) OnAfsOrderAdjust(afsOrder *model.AfsOrder, orderStatus *model.OrderStatus) (err error) { - return c.onAfsOrderNew(afsOrder, orderStatus, true) -} - -func (c *OrderManager) OnAfsOrderNew(afsOrder *model.AfsOrder, orderStatus *model.OrderStatus) (err error) { - return c.onAfsOrderNew(afsOrder, orderStatus, false) -} - -func (c *OrderManager) onAfsOrderNew(afsOrder *model.AfsOrder, orderStatus *model.OrderStatus, isAdjust bool) (err error) { - db := dao.GetDB() - globals.SugarLogger.Debugf("onAfsOrderNew1 orderID:%s", afsOrder.VendorOrderID) - c.setAfsOrderID(db, orderStatus) - if afsOrder.AfsOrderID == "" { - afsOrder.AfsOrderID = orderStatus.VendorOrderID - } - if afsOrder.VendorStatus == "" { - afsOrder.VendorStatus = orderStatus.VendorStatus - } - if afsOrder.Status == model.OrderStatusUnknown { - afsOrder.Status = orderStatus.Status - } - globals.SugarLogger.Debugf("onAfsOrderNew2 orderID:%s", afsOrder.VendorOrderID) - // - if order, _ := c.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID); order != nil { - if order.ConsigneeMobile2 == "" { - if handler := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID); handler != nil { - if order2, _ := handler.GetOrder(order.VendorOrgCode, order.VendorOrderID); order2 != nil && order.ConsigneeMobile != order2.ConsigneeMobile { - order.ConsigneeMobile = order2.ConsigneeMobile - c.UpdateOrderFields(order, []string{"ConsigneeMobile"}) - } - } - } - } - // - dao.Begin(db) - defer func() { - if r := recover(); r != nil || err != nil { - dao.Rollback(db) - panic(r) - } - }() - isDuplicated, err := addOrderOrWaybillStatus(orderStatus, db) - globals.SugarLogger.Debugf("onAfsOrderNew afsOrderID:%s, isDuplicated:%t", afsOrder.AfsOrderID, isDuplicated) - if err != nil || isDuplicated { - if err == nil { - dao.Commit(db) - } - return err - } - var existAfsOrder *model.AfsOrder - if existAfsOrder, err = c.loadAfsOrder(db, afsOrder.AfsOrderID, afsOrder.VendorID); err != nil { - if !dao.IsNoRowsError(err) { - return err - } - } - if existAfsOrder != nil { - // todo 可能导致状态回绕 - existAfsOrder.Status = afsOrder.Status - existAfsOrder.VendorStatus = afsOrder.VendorStatus - if _, err = dao.UpdateEntity(db, existAfsOrder, "Status", "VendorStatus"); err != nil { - return err - } - afsOrder = existAfsOrder - } else { - // 全退都要先全删除再建 - if afsOrder.RefundType == model.AfsTypeFullRefund { - isAdjust = true - } - if err = c.SaveAfsOrder(db, afsOrder, isAdjust); err != nil { - return err - } - } - - dao.Commit(db) - scheduler.CurrentScheduler.OnAfsOrderNew(afsOrder, false) - return err -} - -func (c *OrderManager) SaveAfsOrder(db *dao.DaoDB, afsOrder *model.AfsOrder, isDeleteFirst bool) (err error) { - globals.SugarLogger.Debug(afsOrder.AfsOrderID) - if db == nil { - db = dao.GetDB() - } - if err = c.updateAfsOrderOtherInfo(db, afsOrder); err != nil { - return err - } - dao.Begin(db) - defer func() { - if r := recover(); r != nil || err != nil { - dao.Rollback(db) - if r != nil { - panic(r) - } - } - }() - if isDeleteFirst { - err = utils.CallFuncLogError(func() error { - _, err = dao.DeleteEntity(db, afsOrder, "VendorOrderID", "VendorID") - return err - }, "SaveAfsOrder delete AfsOrder, afsOrderID:%s", afsOrder.AfsOrderID) - if err != nil { - return err - } - err = utils.CallFuncLogError(func() error { - _, err = dao.DeleteEntity(db, &model.OrderSkuFinancial{ - VendorOrderID: afsOrder.VendorOrderID, - VendorID: afsOrder.VendorID, - IsAfsOrder: 1, - }, "VendorOrderID", "VendorID", "IsAfsOrder") - return err - }, "SaveAfsOrder delete OrderSkuFinancial, afsOrderID:%s", afsOrder.AfsOrderID) - if err != nil { - return err - } - } - // 平台结算扣除汇总--平台补贴,售后产生运费,平台收包装费,同城运费、、、 - deductionsByPm := afsOrder.PmSubsidyMoney + afsOrder.AfsFreightMoney + afsOrder.BoxMoney + afsOrder.TongchengFreightMoney - afsOrder.RefundMoneyByCal = afsOrder.SkuUserMoney + afsOrder.FreightUserMoney + deductionsByPm - afsOrder.PmRefundMoney - // order.TotalMoney += order.SkuJxMoney // 退款单京西补贴部分先不作计算 - if err = dao.CreateEntity(db, afsOrder); err != nil { - globals.SugarLogger.Warnf("On SaveAfsOrder afsOrder.AfsOrderID:%s err:%v", afsOrder.AfsOrderID, err) - return err - } - - // 京西结算扣除汇总,先不作计算,计算单条sku最终扣款金额(+该条sku承担的平台结算扣除金额) - for _, orderSku := range afsOrder.Skus[1:] { - orderSku.RefundMoneyByCal = orderSku.PmSkuSubsidyMoney + - utils.Float64TwoInt64(float64(afsOrder.RefundMoneyByCal-afsOrder.PmSkuSubsidyMoney)*float64(orderSku.UserMoney+orderSku.PmSubsidyMoney-orderSku.PmSkuSubsidyMoney)/float64(afsOrder.SkuUserMoney+afsOrder.PmSubsidyMoney-afsOrder.PmSkuSubsidyMoney)) - afsOrder.Skus[0].RefundMoneyByCal += orderSku.RefundMoneyByCal - if err = dao.CreateEntity(db, orderSku); err != nil { - globals.SugarLogger.Warnf("On SaveAfsOrder afsOrder.AfsOrderID:%s err:%v, orderSku:%s", afsOrder.AfsOrderID, err, utils.Format4Output(orderSku, true)) - return err - } - } - if len(afsOrder.Skus) > 0 { - orderSku := afsOrder.Skus[0] - orderSku.RefundMoneyByCal = afsOrder.RefundMoneyByCal - orderSku.RefundMoneyByCal - if err = dao.CreateEntity(db, orderSku); err != nil { - globals.SugarLogger.Warnf("On SaveAfsOrder afsOrder.AfsOrderID:%s err:%v, orderSku:%s", afsOrder.AfsOrderID, err, utils.Format4Output(orderSku, true)) - return err - } - } else { - globals.SugarLogger.Warnf("On SaveAfsOrder afsOrder.AfsOrderID:%s err: afsOrder have no sku", afsOrder.AfsOrderID) - } - dao.Commit(db) - return err -} - -func (c *OrderManager) OnAfsOrderStatusChanged(orderStatus *model.OrderStatus) (err error) { - db := dao.GetDB() - c.setAfsOrderID(db, orderStatus) - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - isDuplicated, afsOrder, err := c.addAfsOrderStatus(db, orderStatus) - if err != nil || isDuplicated { - if err == nil { - dao.Commit(db) - } else { - dao.Rollback(db) - } - return err - } - dao.Commit(db) - scheduler.CurrentScheduler.OnAfsOrderStatusChanged(afsOrder, orderStatus, false) - return err -} - -func (c *OrderManager) addAfsOrderStatus(db *dao.DaoDB, orderStatus *model.OrderStatus) (isDuplicated bool, order *model.AfsOrder, err error) { - globals.SugarLogger.Debugf("addAfsOrderStatus refOrderID:%s, orderID:%s", orderStatus.RefVendorOrderID, orderStatus.VendorOrderID) - if db == nil { - db = dao.GetDB() - } - isDuplicated, err = addOrderOrWaybillStatus(orderStatus, db) - if err == nil && !isDuplicated && (orderStatus.Status != model.OrderStatusUnknown && orderStatus.Status != model.OrderStatusMsg) { - order = &model.AfsOrder{ - AfsOrderID: orderStatus.VendorOrderID, - VendorID: orderStatus.VendorID, - } - if err = db.Db.ReadForUpdate(order, "AfsOrderID", "VendorID"); err == nil { - if orderStatus.Status > model.OrderStatusUnknown { // todo 要求status不能回绕 - order.VendorStatus = orderStatus.VendorStatus - order.Status = orderStatus.Status - updateFields := []string{ - "VendorStatus", - "Status", - } - if model.IsAfsOrderFinalStatus(orderStatus.Status) { - order.AfsFinishedAt = orderStatus.StatusTime - updateFields = append(updateFields, "AfsFinishedAt") - } - utils.CallFuncLogError(func() error { - _, err = dao.UpdateEntity(db, order, updateFields...) - return err - }, "addAfsOrderStatus update orderID:%s, status:%v", order.VendorOrderID, orderStatus) - } else { - isDuplicated = true - } - } else { - if dao.IsNoRowsError(err) { // todo 消息错序 - err = nil - } else { - globals.SugarLogger.Warnf("addAfsOrderStatus orderID:%s read failed with error:%v", order.VendorOrderID, err) - } - } - } - return isDuplicated, order, err -} - -func (c *OrderManager) updateAfsOrderSkuOtherInfo(db *dao.DaoDB, order *model.AfsOrder) (err error) { - globals.SugarLogger.Debugf("updateAfsOrderSkuOtherInfo orderID:%s, VendorStoreID:%s", order.VendorOrderID, order.VendorStoreID) - jxStoreID := jxutils.GetSaleStoreIDFromAfsOrder(order) - opNumStr := "2" - if jxStoreID == 0 { - globals.SugarLogger.Infof("updateAfsOrderSkuOtherInfo [运营%s]订单在京西与平台都找不到京西门店信息orderID:%s, VendorStoreID:%s", opNumStr, order.VendorOrderID, order.VendorStoreID) - return nil - } - orderSkus := order.Skus - var vendorSkuIDs []string - skuIDMap := make(map[int]int) - for _, v := range orderSkus { - if v.VendorSkuID != "" { - vendorSkuIDs = append(vendorSkuIDs, v.VendorSkuID) - } - - if skuID := jxutils.GetSkuIDFromOrderSkuFinancial(v); skuID > 0 { - skuIDMap[skuID] = 1 - } - } - if len(vendorSkuIDs) > 0 { - var vendorStoreID string - if order.VendorID == model.VendorIDJDShop { - vendorStoreID = model.JdShopMainVendorStoreID - } else { - vendorStoreID = order.VendorStoreID - } - l, err := dao.GetStoreSkuPriceAndWeight(db, vendorStoreID, order.VendorID, vendorSkuIDs) - if err != nil { - globals.SugarLogger.Warnf("updateAfsOrderSkuOtherInfo orderID:%s failed with err:%v", order.VendorOrderID, err) - return err - } - skumapper := storeSkuPriceAndWeight2Map(l) - - var actStoreSkuMap *jxutils.ActStoreSkuMap - if len(skuIDMap) > 0 { - if order2, err2 := c.LoadOrder(order.VendorOrderID, order.VendorID); err2 == nil { - actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, 0, []int{order.VendorID}, model.ActTypeAll, []int{jxStoreID}, jxutils.IntMap2List(skuIDMap), order2.OrderCreatedAt, order2.OrderCreatedAt) - if err != nil { - globals.SugarLogger.Errorf("updateAfsOrderSkuOtherInfo can not get sku promotion info for error:%v", err) - return err - } - actStoreSkuMap = jxutils.NewActStoreSkuMap(actStoreSkuList, false) - } - } - for _, v := range orderSkus { - v.AfsOrderID = order.AfsOrderID - v.VendorID = order.VendorID - v.VendorOrderID = order.VendorOrderID - v.IsAfsOrder = 1 - v.VendorStoreID = order.VendorStoreID - v.StoreID = order.StoreID - v.JxStoreID = jxStoreID - - intVendorSkuID := utils.Str2Int64WithDefault(v.VendorSkuID, 0) - if intVendorSkuID != 0 && v.VendorSkuID != "-70000" { // todo hard code - skuBindInfo := skumapper[v.VendorSkuID] - if skuBindInfo == nil { - globals.SugarLogger.Infof("updateAfsOrderSkuOtherInfo [运营%s]%s订单sku找不到门店价格(或商品映射),orderID:%s, StoreID:%d, VendorSkuID:%s, sku:%v", opNumStr, model.VendorChineseNames[order.VendorID], order.VendorOrderID, jxStoreID, v.VendorSkuID, v) - } else { - v.JxSkuID = skuBindInfo.SkuID - v.ShopPrice = int64(skuBindInfo.Price) - } - } - if actStoreSkuMap != nil { - if skuID := jxutils.GetSkuIDFromOrderSkuFinancial(v); skuID > 0 && v.StoreSubName != "" { - if actStoreSku := actStoreSkuMap.GetActStoreSku(jxStoreID, skuID, order.VendorID); actStoreSku != nil { - v.StoreSubID = actStoreSku.ActID - } - } - } - } - } - return nil -} - -func (c *OrderManager) updateAfsOrderOtherInfo(db *dao.DaoDB, afsOrder *model.AfsOrder) (err error) { - globals.SugarLogger.Debugf("updateAfsOrderOtherInfo orderID:%s, VendorStoreID:%s", afsOrder.VendorOrderID, afsOrder.VendorStoreID) - if afsOrder.VendorStoreID != "" { - if storeDetail, err := dao.GetStoreDetailByVendorStoreID(db, afsOrder.VendorStoreID, 0); err == nil { - afsOrder.JxStoreID = storeDetail.Store.ID - } - } - if afsOrder.StoreID == 0 && afsOrder.JxStoreID == 0 { - if order, err2 := c.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID); err2 == nil { - afsOrder.JxStoreID = order.JxStoreID - if afsOrder.StoreID == 0 { - afsOrder.StoreID = order.StoreID - } - if afsOrder.VendorStoreID == "" { - afsOrder.VendorStoreID = order.VendorStoreID - } - } - } - if err == nil { - if err = c.updateAfsOrderSkuOtherInfo(db, afsOrder); err == nil { - jxutils.RefreshAfsOrderSkuRelated(afsOrder) - } - } - return err -} - -func (c *OrderManager) UpdateAfsOrderFields(afsOrder *model.AfsOrder, fieldList []string) (err error) { - db := orm.NewOrm() - utils.CallFuncLogError(func() error { - _, err = db.Update(afsOrder, fieldList...) - return err - }, "UpdateAfsOrderFields orderID:%s failed with error:%v", afsOrder.VendorOrderID, err) - return err -} - -func (c *OrderManager) setAfsOrderID(db *dao.DaoDB, orderStatus *model.OrderStatus) { - // globals.SugarLogger.Debugf("setAfsOrderID1 orderStatus:%v", utils.Format4Output(orderStatus, true)) - if dao.IsVendorThingIDEmpty(orderStatus.VendorOrderID) { - index := 1 - if afsOrderList, err2 := dao.GetAfsOrders(db, orderStatus.RefVendorID, orderStatus.RefVendorOrderID, ""); err2 == nil { - if len(afsOrderList) > 0 { - list := strings.Split(afsOrderList[0].AfsOrderID, "-") - if len(list) > 1 { - index = int(utils.Str2Int64WithDefault(list[1], 0)) - if afsOrderList[0].Status >= model.AfsOrderStatusFinished { - index++ - } - } - } - } else { - globals.SugarLogger.Warnf("setAfsOrderID err2:%v", err2) - } - orderStatus.VendorOrderID = composeAfsOrderID(orderStatus.RefVendorOrderID, index) - } - // globals.SugarLogger.Debugf("setAfsOrderID2 orderStatus:%v", utils.Format4Output(orderStatus, true)) -} - -func composeAfsOrderID(vendorOrderID string, index int) (afsOrderID string) { - return strings.Join([]string{ - vendorOrderID, - utils.Int2Str(index), - }, "-") -} - -func (c *OrderManager) CreateAfsOrderFromOrder(vendorOrderID string, vendorID int) (afsOrder *model.AfsOrder, err error) { - order, err := c.LoadOrder(vendorOrderID, vendorID) - // globals.SugarLogger.Debug(utils.Format4Output(order, false)) - if err == nil { - afsOrder = &model.AfsOrder{ - VendorID: vendorID, - VendorOrderID: vendorOrderID, - JxStoreID: order.JxStoreID, - VendorStoreID: order.VendorStoreID, - StoreID: order.StoreID, - VendorOrgCode: order.VendorOrgCode, - } - } else { - globals.SugarLogger.Warnf("CreateAfsOrderFromOrder, orderID:%s is not found from partner.CurOrderManager.LoadOrder", vendorOrderID) - return nil, err - } - - for _, sku := range order.Skus { - orderSkuFinancial := &model.OrderSkuFinancial{ - VendorID: sku.VendorID, - VendorOrderID: sku.VendorOrderID, - // OrderFinancialID: sku.VendorOrderID, - // ConfirmTime: afsOrder.AfsCreateAt, - VendorStoreID: afsOrder.VendorStoreID, - StoreID: afsOrder.StoreID, - JxStoreID: afsOrder.JxStoreID, - VendorSkuID: sku.VendorSkuID, - SkuID: sku.SkuID, - PromotionType: sku.PromotionType, - Name: sku.SkuName, - ShopPrice: sku.ShopPrice, - SalePrice: sku.SalePrice, - Count: sku.Count, - // UserMoney: sku.UserMoney, - // PmSubsidyMoney: sku.PmSubsidyMoney, - IsAfsOrder: 1, - } - afsOrder.Skus = append(afsOrder.Skus, orderSkuFinancial) - } - return afsOrder, nil -} diff --git a/business/jxcallback/orderman/order_comment.go b/business/jxcallback/orderman/order_comment.go deleted file mode 100644 index 8a9e2c23a..000000000 --- a/business/jxcallback/orderman/order_comment.go +++ /dev/null @@ -1,213 +0,0 @@ -package orderman - -import ( - "fmt" - "math/rand" - "time" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/weixinmsg" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/model/legacymodel" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" -) - -const ( - COMMENT_NOT_RESOLVED = 0 //未解决的差评状态 - COMMENT_RESOLVED = 1 //已解决的差评状态 - - JX_BAD_COMMENTS_MAX_LEVEL = 2 // 差评最大分 - JX_MIDDLE_COMMENTS_MAX_LEVEL = 4 // 中评最大分 - - COMMENTS_SCORE_ONE_ORTWO_BEGIN_DELAY_TIME = 1 * 60 //评论回复一星或二星回复延迟开始时间区间 - COMMENTS_SCORE_ONE_ORTWO_END_DELAY_TIME = 3 * 60 //评论回复一星或二星回复延迟结束时间区间 - COMMENTS_SCORE_THREE_BEGIN_DELAY_TIME = 2 * 60 //评论回复三星回复延迟开始时间区间 - COMMENTS_SCORE_THREE_END_DELAY_TIME = 4 * 60 //评论回复三星回复延迟结束时间区间 - COMMENTS_SCORE_FOUR_ORFIVE_BEGIN_DELAY_TIME = 2 * 60 //评论回复四星或五星回复延迟开始时间区间 - COMMENTS_SCORE_FOUR_ORFIVE_END_DELAY_TIME = 5 * 60 //评论回复四星或五星回复延迟结束时间区间 - - MAX_REAPLY_TIME = 18 * time.Hour -) - -type tReplyConfig struct { - delayGapBegin int - delayGapEnd int - comments []string -} - -var ( - replyConfig = map[int]*tReplyConfig{ - 1: &tReplyConfig{ - delayGapBegin: COMMENTS_SCORE_ONE_ORTWO_BEGIN_DELAY_TIME, - delayGapEnd: COMMENTS_SCORE_ONE_ORTWO_END_DELAY_TIME, - comments: []string{ - "非常抱歉让您没有得到十分满意的购物体验,我们会及时与您联系进行确认并解决问题!", - }, - }, - 3: &tReplyConfig{ - delayGapBegin: COMMENTS_SCORE_THREE_BEGIN_DELAY_TIME, - delayGapEnd: COMMENTS_SCORE_THREE_END_DELAY_TIME, - comments: []string{ - "感谢您对我们的肯定,祝您生活愉快!欢迎再次光临,谢谢!", - fmt.Sprintf("感谢您对%s的关照,我们会更加精益求精。", globals.StoreName), - "感谢您的光临,您的支持是我们前进的动力!", - }, - }, - 4: &tReplyConfig{ - delayGapBegin: COMMENTS_SCORE_FOUR_ORFIVE_BEGIN_DELAY_TIME, - delayGapEnd: COMMENTS_SCORE_FOUR_ORFIVE_END_DELAY_TIME, - comments: []string{ - "感谢您的信赖!我们会不断提升菜品质量以及优质的服务,期待与您的再次相遇!", - "感谢您的支持,愿您天天好心情!", - "感谢您的认可!您的支持是我们前进的动力。", - "感谢您的肯定与支持!我们会坚持把最好的服务带给您,期待和您的再次相遇!", - }, - }, - } -) - -func (c *OrderManager) OnOrderComments(orderCommentList []*model.OrderComment) (err error) { - globals.SugarLogger.Debug("OnOrderComments") - db := dao.GetDB() - for _, orderComment := range orderCommentList { - globals.SugarLogger.Debugf("OnOrderComments, orderID:%s", orderComment.VendorOrderID) - comment2 := &legacymodel.JxBadComments{ - OrderId: orderComment.VendorOrderID, - } - err = dao.GetEntity(db, comment2, "OrderId") - if err == nil || dao.IsNoRowsError(err) { - isNewComment := false - if dao.IsNoRowsError(err) { - err = nil - isNewComment = true - if orderComment.IsReplied == 0 && time.Now().Sub(orderComment.CommentCreatedAt) < time.Duration(orderComment.ModifyDuration)*time.Hour { - if storeDetail, err2 := dao.GetStoreDetail(db, orderComment.StoreID, orderComment.VendorID); err2 == nil { - if storeDetail.AutoReplyType == model.AutoReplyAll || - orderComment.Score > JX_BAD_COMMENTS_MAX_LEVEL && storeDetail.AutoReplyType == model.AutoReplyGoodComment { - c.replyOrderComment(storeDetail.VendorOrgCode, orderComment) - } - } - } - } - if isNewComment /*&& orderComment.Score <= JX_BAD_COMMENTS_MAX_LEVEL*/ || !isNewComment && orderComment.Score > JX_BAD_COMMENTS_MAX_LEVEL { // 如果是直接非差评,或补评仍然是差评,忽略 - if isNewComment { - comment2.Createtime = utils.Time2Str(orderComment.CommentCreatedAt) - comment2.Score = int(orderComment.Score) - comment2.Scorecontent = orderComment.Content - comment2.Vendertags = orderComment.TagList - comment2.Msg = orderComment.OriginalMsg - - comment2.Status = COMMENT_NOT_RESOLVED - comment2.OrderFlag = utils.Int2Str(orderComment.VendorID) - comment2.Maxmodifytime = int(orderComment.ModifyDuration) - - order, _ := partner.CurOrderManager.LoadOrder(orderComment.VendorOrderID, orderComment.VendorID) - if order != nil { - orderComment.StoreID = jxutils.GetSaleStoreIDFromOrder(order) - if order.ConsigneeMobile2 != "" { - orderComment.ConsigneeMobile = order.ConsigneeMobile2 - } else { - if handler := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID); handler != nil { - if order2, _ := handler.GetOrder(order.VendorOrgCode, order.VendorOrderID); order2 != nil && order.ConsigneeMobile != order2.ConsigneeMobile { - order.ConsigneeMobile = order2.ConsigneeMobile - partner.CurOrderManager.UpdateOrderFields(order, []string{"ConsigneeMobile"}) - } - } - orderComment.ConsigneeMobile = order.ConsigneeMobile - } - } else { - if storeDetail, err := dao.GetStoreDetailByVendorStoreID(db, orderComment.VendorStoreID, orderComment.VendorID); err == nil { - orderComment.StoreID = storeDetail.ID - } - } - if orderComment.StoreID > 0 { - comment2.Jxstoreid = utils.Int2Str(orderComment.StoreID) - } - comment2.Userphone = orderComment.ConsigneeMobile - if comment2.Jxstoreid != "" && orderComment.Score <= JX_MIDDLE_COMMENTS_MAX_LEVEL && time.Now().Sub(orderComment.CommentCreatedAt) < MAX_REAPLY_TIME { - comment2.LastPushTime = utils.Time2Str(time.Now()) - comment2.PushNo = 1 - weixinmsg.PushJDBadCommentToWeiXin(comment2, orderComment.Score <= JX_BAD_COMMENTS_MAX_LEVEL, order) - } - } else { // 修改评价,高于JX_BAD_COMMENTS_MAX_LEVEL - if orderComment.CommentCreatedAt.Sub(str2Time(comment2.Createtime)) == 0 || - orderComment.CommentCreatedAt.Sub(str2Time(comment2.Updatetime)) == 0 { - comment2 = nil // 重复 - } else { - comment2.Updatetime = utils.Time2Str(orderComment.CommentCreatedAt) - comment2.UpdatedMsg = orderComment.OriginalMsg - comment2.UpdatedScore = int(orderComment.Score) - comment2.UpdatedScorecontent = orderComment.Content - comment2.UpdatedVendertags = orderComment.TagList - comment2.Status = COMMENT_RESOLVED - - if comment2.Jxstoreid != "" && orderComment.Score <= JX_MIDDLE_COMMENTS_MAX_LEVEL && time.Now().Sub(orderComment.CommentCreatedAt) < MAX_REAPLY_TIME { - comment2.LastPushTime = utils.Time2Str(time.Now()) - comment2.PushNo++ - - comment3 := *comment2 - comment3.Createtime = comment2.Updatetime - comment3.Score = comment2.UpdatedScore - comment3.Scorecontent = comment2.UpdatedScorecontent - comment3.Vendertags = comment2.UpdatedVendertags - order, _ := partner.CurOrderManager.LoadOrder(orderComment.VendorOrderID, orderComment.VendorID) - weixinmsg.PushJDBadCommentToWeiXin(&comment3, orderComment.Score <= JX_BAD_COMMENTS_MAX_LEVEL, order) - } - } - } - if err == nil { - if isNewComment { - err = dao.CreateEntity(db, comment2) - } else if comment2 != nil { - _, err = dao.UpdateEntity(db, comment2) - } - } - } - } - if err != nil { - globals.SugarLogger.Warnf("OnOrderComments orderID:%s failed with error:%v", orderComment.VendorOrderID, err) - break - } - } - return err -} - -func (c *OrderManager) replyOrderComment(vendorOrgCode string, orderComment *model.OrderComment) (err error) { - score := int(orderComment.Score) - if score <= 2 { - score = 1 - } else if score >= 5 { - score = 4 - } - config := replyConfig[score] - delaySeconds := config.delayGapBegin + rand.Intn(config.delayGapEnd-config.delayGapBegin) - content := config.comments[rand.Intn(len(config.comments))] - globals.SugarLogger.Debugf("replyOrderComment orderID:%s, delaySeconds:%d, content:%s", orderComment.VendorOrderID, delaySeconds, content) - utils.AfterFuncWithRecover(time.Duration(delaySeconds)*time.Second, func() { - if handler := partner.GetPurchaseOrderHandlerFromVendorID(orderComment.VendorID); handler != nil { - if err = handler.ReplyOrderComment(jxcontext.AdminCtx, vendorOrgCode, orderComment, content); err != nil { - globals.SugarLogger.Debugf("replyOrderComment orderID:%s, error:%v", orderComment.VendorOrderID, err) - } - } else { - globals.SugarLogger.Warnf("replyOrderComment can not find handler orderID:%s", orderComment.VendorOrderID) - } - }) - // todo 这里直接延时,可以导致服务器重启时漏掉回复,但如果用管理任务,又会导致大量评价任务存在与任务列表中 - // task := tasksch.NewParallelTask(fmt.Sprintf("回复订单:%s评价", orderComment.VendorOrderID), nil, jxcontext.AdminCtx, - // func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - // return retVal, err - // }, []int{0}) - // tasksch.HandleTask(task, nil, true).Run() - return err -} - -func str2Time(timeStr string) time.Time { - if timeStr == "" { - return utils.DefaultTimeValue - } - return utils.Str2Time(timeStr) -} diff --git a/business/jxcallback/orderman/orderman.go b/business/jxcallback/orderman/orderman.go deleted file mode 100644 index e6c385406..000000000 --- a/business/jxcallback/orderman/orderman.go +++ /dev/null @@ -1,180 +0,0 @@ -package orderman - -import ( - "errors" - "sort" - "time" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler" - "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" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" -) - -const ( - pendingOrderGapMax = 2 * 24 * time.Hour // 每次重启机子时,要检查几天内的订单状态 - maxTimeHandlePendingOrder = 2 * time.Second //处理pending order的最长时间 - maxSleepGapHandlePendingOrder = 5 * time.Millisecond // 每个pending order的最长时间间隙 -) - -var ( - ErrCanNotFindOrder = errors.New("找不到相应订单") - ErrCanNotFindWaybill = errors.New("找不到相应运单") -) - -var ( - FixedOrderManager *OrderManager -) - -// 所有公共接口调用前,要求在order里或status中设置合适的Status -type OrderManager struct { -} - -func NewOrderManager() *OrderManager { - return &OrderManager{} -} - -type IStatusTimer interface { - GetStatusTime() time.Time -} - -type StatusTimerSlice []IStatusTimer - -func (s StatusTimerSlice) Len() int { - return len(s) -} - -func (s StatusTimerSlice) Less(i, j int) bool { - return s[i].GetStatusTime().Sub(s[j].GetStatusTime()) < 0 -} - -func (s StatusTimerSlice) Swap(i, j int) { - tmp := s[i] - s[i] = s[j] - s[j] = tmp -} - -func init() { - FixedOrderManager = NewOrderManager() - partner.InitOrderManager(FixedOrderManager) -} - -func addOrderOrWaybillStatus(status *model.OrderStatus, db *dao.DaoDB) (isDuplicated bool, err error) { - if status.OrderType == model.OrderTypeOrder { - globals.SugarLogger.Debugf("addOrderStatus order:%v", status) - } else if status.OrderType == model.OrderTypeWaybill { - globals.SugarLogger.Debugf("addOrderStatus waybill:%v", status) - } else { - globals.SugarLogger.Debugf("addOrderStatus afsOrder:%v", status) - } - dao.Begin(db) - defer func() { - if r := recover(); r != nil || err != nil { - globals.SugarLogger.Debug("rollback") - dao.Rollback(db) - if r != nil { - panic(r) - } - } - }() - status.ID = 0 - status.Remark = utils.LimitUTF8StringLen(status.Remark, 255) - created, _, err := db.Db.ReadOrCreate(status, "VendorOrderID", "VendorID", "OrderType", "Status", "VendorStatus", "StatusTime") - if err == nil { - if !created { - globals.SugarLogger.Debugf("duplicated event:%v", status) - isDuplicated = true - status.DuplicatedCount++ - utils.CallFuncLogError(func() error { - _, err = db.Db.Update(status, "DuplicatedCount") - return err - }, "addOrderOrWaybillStatus update DuplicatedCount, status:%v", status) - } - } - if err != nil { - // todo 这里居然会有主键重复错误,逻辑上是不应该的 - globals.SugarLogger.Warnf("addOrderOrWaybillStatus status:%v, access db error:%v", status, err) - } else { - dao.Commit(db) - } - return isDuplicated, err -} - -func (c *OrderManager) GetStatusDuplicatedCount(status *model.OrderStatus) (duplicatedCount int) { - if status == nil { - return 0 - } - db := dao.GetDB() - if err := dao.GetEntity(db, status, "VendorOrderID", "VendorID", "OrderType", "VendorStatus", "StatusTime"); err == nil { - return status.DuplicatedCount - } - return 0 -} - -// todo 最好还是改成全事件回放算了 -func LoadPendingOrders() { - orders, err := dao.LoadPendingOrders(dao.GetDB(), time.Now().Add(-pendingOrderGapMax), model.OrderStatusEndBegin) - globals.SugarLogger.Infof("LoadPendingOrders orders count:%d, err:%v", len(orders), err) - if err != nil { - return - } - - ordersCount := len(orders) - if ordersCount > 0 { - bills := FixedOrderManager.LoadPendingWaybills() - globals.SugarLogger.Infof("LoadPendingOrders waybills count:%d", len(bills)) - var sortOrders StatusTimerSlice - orderMap := make(map[string]*model.GoodsOrder) - for _, order := range orders { - if order.Status > model.OrderStatusNew { - status := model.Order2Status(order) - sortOrders = append(sortOrders, status) - } - // order.Status = model.OrderStatusNew // 就是要以实际order状态来调用scheduler.OnOrderNew - order.StatusTime = order.OrderCreatedAt - sortOrders = append(sortOrders, order) - orderMap[jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID)] = order - } - for _, bill := range bills { - if bill.Status > model.WaybillStatusNew { - bill2 := *bill - sortOrders = append(sortOrders, &bill2) - } - bill.Status = model.WaybillStatusNew - bill.StatusTime = bill.WaybillCreatedAt - sortOrders = append(sortOrders, bill) - } - sort.Sort(sortOrders) - sleepGap := maxTimeHandlePendingOrder / time.Duration(ordersCount) - if sleepGap > maxSleepGapHandlePendingOrder { - sleepGap = maxSleepGapHandlePendingOrder - } - lastTime := time.Now() - for _, item := range sortOrders { - if order, ok := item.(*model.GoodsOrder); ok { - jxutils.CallMsgHandlerAsync(func() { - scheduler.CurrentScheduler.OnOrderNew(order, true) - }, jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID)) - } else if status, ok := item.(*model.OrderStatus); ok { - jxutils.CallMsgHandlerAsync(func() { - order := orderMap[jxutils.ComposeUniversalOrderID(status.VendorOrderID, status.VendorID)] - scheduler.CurrentScheduler.OnOrderStatusChanged(order, status, true) - }, jxutils.ComposeUniversalOrderID(status.RefVendorOrderID, status.RefVendorID)) - } else { - bill := item.(*model.Waybill) - jxutils.CallMsgHandlerAsync(func() { - scheduler.CurrentScheduler.OnWaybillStatusChanged(bill, true) - }, jxutils.ComposeUniversalOrderID(bill.VendorOrderID, bill.OrderVendorID)) - } - curTime := time.Now() - timeout := sleepGap - curTime.Sub(lastTime) - if timeout > 0 { - time.Sleep(timeout) - } - lastTime = curTime - } - } -} diff --git a/business/jxcallback/orderman/orderman_ext.go b/business/jxcallback/orderman/orderman_ext.go deleted file mode 100644 index b2954410f..000000000 --- a/business/jxcallback/orderman/orderman_ext.go +++ /dev/null @@ -1,1343 +0,0 @@ -package orderman - -import ( - "fmt" - "math" - "strconv" - "strings" - "time" - - "github.com/astaxie/beego" - - "git.rosy.net.cn/jx-callback/globals/api" - - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/excel" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api/apimanager" - "github.com/astaxie/beego/orm" -) - -const ( - maxLastHours = 7 * 24 // 最多只能查询7天内的订单数据 - defLastHours = 2 * 24 // 缺省是两天内的订单 - - orderSubTimeImmediatelyArrive = 8 - orderSubTimeDelayArrive = 5 -) - -type tWaybillExt struct { - model.Waybill - StoreName string `json:"storeName"` - StoreID int `json:"storeID" orm:"column(store_id)"` -} - -type StoresOrderSaleInfo struct { - StoreID int `orm:"column(store_id)" json:"storeID"` - VendorID int `orm:"column(vendor_id)" json:"vendorID"` - Status int `json:"status"` - Count int `json:"count"` - ShopPrice int64 `json:"shopPrice"` - VendorPrice int64 `json:"vendorPrice"` - SalePrice int64 `json:"salePrice"` - ActualPayPrice int64 `json:"actualPayPrice"` - - EarningPrice int64 `json:"earningPrice"` // 预估结算给门店老板的钱 -} - -type OrderSkusAccept struct { - model.SkuAndName - SumWeight int `json:"sumWeight"` - SumCount int `json:"sumCount"` - Img string `json:"img"` -} - -type OrderCount struct { - Count int `json:"count"` //销量 - Flag bool `json:"flag"` //true表示可以买 -} - -func (c *OrderManager) GetStoreOrderCountInfo(ctx *jxcontext.Context, storeID, lastHours, lastMinutes int, isIncludeFake bool) (countInfo []*model.GoodsOrderCountInfo, err error) { - globals.SugarLogger.Debugf("GetStoreOrderCountInfo storeID:%d", storeID) - if lastHours > maxLastHours { - lastHours = maxLastHours - } else if lastHours == 0 && lastMinutes == 0 { - lastHours = defLastHours - } - - db := dao.GetDB() - sql := ` - SELECT t1.lock_status, t1.status, COUNT(*) count - FROM goods_order t1 - WHERE t1.vendor_id <> 2 AND IF(t1.jx_store_id != 0, t1.jx_store_id, t1.store_id) = ? - AND t1.order_created_at >= ?` - sqlParams := []interface{}{ - storeID, - // time.Now().Add(-time.Duration(lastHours) * time.Hour), - } - if lastMinutes != 0 { - sqlParams = append(sqlParams, time.Now().Add(-time.Duration(lastMinutes)*time.Minute)) - } else { - sqlParams = append(sqlParams, time.Now().Add(-time.Duration(lastHours)*time.Hour)) - } - if !isIncludeFake { - sql += " AND (t1.flag & ?) = 0" - sqlParams = append(sqlParams, model.OrderFlagMaskFake) - } - sql += ` - GROUP BY 1,2 - ORDER BY 1,2` - err = dao.GetRows(db, &countInfo, sql, sqlParams...) - if err == nil { - return countInfo, nil - } - globals.SugarLogger.Infof("GetStoreOrderCountInfo storeID:%d failed with error:%v", storeID, err) - return nil, err -} - -func (c *OrderManager) GetOrderSkuInfo(ctx *jxcontext.Context, vendorOrderID string, vendorID int) (skus []*model.OrderSkuExt, err error) { - globals.SugarLogger.Debugf("GetOrderSkuInfo orderID:%s", vendorOrderID) - - fullSkuNameSQL := "t1.sku_name" - if vendorID == model.VendorIDJD { - fullSkuNameSQL = "CONCAT(t1.sku_name, IF(t3.is_spu = 1 AND LOCATE(';', t1.sku_name) = 0, CONCAT('[约', t2.spec_quality, t2.spec_unit, '/', t3.unit, ']'), ''))" - } - // IF(t1.shop_price = 0, t1.sale_price, t1.shop_price) shop_price, - sql := fmt.Sprintf(` - SELECT - t1.id, - t1.vendor_order_id, - t1.vendor_id, - t1.count, - t1.vendor_sku_id, - t1.sku_id, - t1.jx_sku_id, - t1.sku_name, - t1.sale_price, - t1.shop_price, - CAST(IF(t1.earning_price <> 0, t1.earning_price, IF(t1.shop_price <> 0 && t1.shop_price < t1.sale_price, t1.shop_price, t1.sale_price) * IF(t5.pay_percentage > 0, t5.pay_percentage, ?) / 100) AS SIGNED) earning_price, - t1.weight, - t1.sku_type, - t1.promotion_type, - t1.order_created_at, - t1.store_sub_id, - t1.store_sub_name, - t1.vendor_price, - %s full_sku_name, - t2.name_id, - t3.img image - FROM order_sku t1 - LEFT JOIN goods_order t6 ON t6.vendor_order_id = t1.vendor_order_id AND t6.vendor_id = t1.vendor_id - LEFT JOIN store t5 ON t5.id = IF(t6.jx_store_id <> 0, t6.jx_store_id, t6.store_id) - LEFT JOIN sku t2 ON IF(t1.jx_sku_id != 0, t1.jx_sku_id, t1.sku_id) = t2.id/* AND t2.deleted_at = ?*/ - LEFT JOIN sku_name t3 ON t2.name_id = t3.id/* AND t3.deleted_at = ?*/ - WHERE t1.vendor_order_id = ? AND t1.vendor_id = ? - ORDER BY t1.sku_name - `, fullSkuNameSQL) - err = dao.GetRows(dao.GetDB(), &skus, sql /*, utils.DefaultTimeValue, utils.DefaultTimeValue*/, model.DefaultEarningPricePercentage, vendorOrderID, vendorID) - if err != nil { - globals.SugarLogger.Infof("GetOrderSkuInfo orderID:%s vendorID:%d failed with error:%v", vendorOrderID, vendorID, err) - return nil, err - } - if len(skus) == 0 { - return nil, ErrCanNotFindOrder - } - return skus, nil -} - -func (c *OrderManager) GetOrderInfo(ctx *jxcontext.Context, vendorOrderID string, vendorID int, isRefresh bool) (order *model.GoodsOrderExt, err error) { - globals.SugarLogger.Debugf("GetOrderInfo orderID:%s", vendorOrderID) - db := orm.NewOrm() - orders := []*model.GoodsOrderExt{} - - // 这里用QueryRows而不用QueryRow的原因是用QueryRow在这种情况下不能将数据读出,很奇怪。大概的原因是QueryRow对于GoodsOrderExt这种有嵌入的struct处理有问题 - num, err := db.Raw(` - SELECT t3.*,ROUND(t3.shop_sum_price/t3.count) avg_price, t1.*, t2.status waybill_status, t2.courier_name, t2.courier_mobile, t2.desired_fee, - CAST(t1.consignee_lng AS DECIMAL(15,6))/1000000 float_lng, - CAST(t1.consignee_lat AS DECIMAL(15,6))/1000000 float_lat - FROM goods_order t1 - LEFT JOIN waybill t2 ON t1.vendor_waybill_id = t2.vendor_waybill_id AND t1.waybill_vendor_id = t2.waybill_vendor_id - JOIN ( - SELECT count(a.vendor_order_id) count,SUM(a.shop_price) - - IFNULL(SUM(c.sku_user_money+c.freight_user_money+c.afs_freight_money+c.box_money+c.tongcheng_freight_money+c.sku_box_money),0) shop_sum_price,a.vendor_user_id,count(d.score < 3 or NULL) bad_comment_count - FROM goods_order a - LEFT JOIN afs_order c ON a.vendor_order_id = c.vendor_order_id AND c.vendor_id = a.vendor_id - LEFT JOIN jx_bad_comments d ON d.order_id = a.vendor_order_id AND d.order_flag = a.vendor_id - WHERE a.vendor_user_id = (SELECT vendor_user_id FROM goods_order WHERE vendor_order_id = ?) - GROUP BY a.vendor_user_id - )t3 ON t3.vendor_user_id = t1.vendor_user_id - WHERE t1.vendor_order_id = ? AND vendor_id = ? - `, vendorOrderID, vendorOrderID, vendorID).QueryRows(&orders) - if err == nil && num > 0 { - order = orders[0] - if isRefresh && vendorID == model.VendorIDJD { - tmpOrder, err2 := partner.GetPurchaseOrderHandlerFromVendorID(vendorID).GetOrder(order.VendorOrgCode, vendorOrderID) - if err = err2; err == nil { - order.CurrentConsigneeMobile = tmpOrder.ConsigneeMobile - } else { - order.CurrentConsigneeMobile = "Error" - globals.SugarLogger.Infof("GetOrderInfo GetOrder failed with error:%v", err2) - } - } - return order, nil - } - if err == nil { - err = ErrCanNotFindOrder - } - globals.SugarLogger.Infof("GetOrderInfo orderID:%s failed with error:%v", vendorOrderID, err) - return nil, err -} - -func (c *OrderManager) GetOrderWaybillInfo(ctx *jxcontext.Context, vendorOrderID string, vendorID int, isNotEnded, isGetPos bool) (bills []*model.WaybillExt, err error) { - globals.SugarLogger.Debugf("GetOrderWaybillInfo orderID:%s", vendorOrderID) - db := dao.GetDB() - sql := ` - SELECT t1.* - FROM waybill t1 - WHERE t1.vendor_order_id = ? AND order_vendor_id = ? - ` - sqlParams := []interface{}{ - vendorOrderID, - vendorID, - } - if isNotEnded { - sql += " AND t1.status < ?" - sqlParams = append(sqlParams, model.OrderStatusEndBegin) - } - err = dao.GetRows(db, &bills, sql, sqlParams...) - if err == nil && isGetPos { - var taskBills []*model.WaybillExt - for _, v := range bills { - if true /*v.Status >= model.WaybillStatusAccepted && v.Status <= model.WaybillStatusDelivering*/ { - if handler := partner.GetRidderPositionGetter(v.WaybillVendorID); handler != nil { - taskBills = append(taskBills, v) - } - } - } - if len(taskBills) > 0 { - task := tasksch.NewParallelTask("GetOrderWaybillInfo", nil, ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - waybill := batchItemList[0].(*model.WaybillExt) - waybill.Lng, waybill.Lat, err = partner.GetRidderPositionGetter(waybill.WaybillVendorID).GetRidderPosition(ctx, waybill.VendorOrderID, waybill.VendorOrderID, waybill.VendorWaybillID, waybill.VendorWaybillID2) - return nil, err - }, taskBills) - tasksch.HandleTask(task, nil, false).Run() - task.GetResult(0) - } - } - return bills, err -} - -func (c *OrderManager) ExportMTWaybills(ctx *jxcontext.Context, fromDateStr, toDateStr string) (excelContent []byte, err error) { - globals.SugarLogger.Debugf("ExportMTWaybills from:%s to:%s", fromDateStr, toDateStr) - - fromDate, err := utils.TryStr2Time(fromDateStr) - if err != nil { - return nil, err - } - if toDateStr == "" { - toDateStr = fromDateStr - } - toDate, err := utils.TryStr2Time(toDateStr) - if err != nil { - return nil, err - } - toDate = toDate.Add(24 * time.Hour) - var waybills []*tWaybillExt - sql := ` - SELECT t1.*, t2.store_name, IF(t1.jx_store_id != 0, t1.jx_store_id, t1.store_id) store_id - FROM waybill t1 - JOIN goods_order t2 ON t1.vendor_order_id = t2.vendor_order_id - WHERE t1.waybill_vendor_id = 102 AND t1.status = 105 AND t1.waybill_created_at >= ? AND t1.waybill_created_at <= ? - ORDER BY t1.id - ` - db := dao.GetDB() - if err = dao.GetRows(db, &waybills, sql, fromDate, toDate); err == nil { - config := []*excel.Obj2ExcelSheetConfig{ - &excel.Obj2ExcelSheetConfig{ - Title: "Sheet1", - Data: waybills, - CaptionList: []string{ - "vendorWaybillID", - "waybillVendorID", - "vendorOrderID", - "orderVendorID", - "storeName", - "storeID", - "courierName", - "status", - "desiredFee", - "waybillCreatedAt", - }, - }, - } - return excel.Obj2Excel(config), nil - } - return nil, err -} - -func (c *OrderManager) GetOrders(ctx *jxcontext.Context, isIncludeFake bool, fromDateStr, toDateStr string, isDateFinish bool, skuIDs []int, isJxFirst bool, params map[string]interface{}, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) { - globals.SugarLogger.Debugf("GetOrders from:%s to:%s", fromDateStr, toDateStr) - orders, totalCount, err := dao.GetOrders(dao.GetDB(), nil, false, isIncludeFake, fromDateStr, toDateStr, isDateFinish, skuIDs, isJxFirst, "", params, offset, pageSize) - if err == nil { - pagedInfo = &model.PagedInfo{ - TotalCount: totalCount, - Data: orders, - } - } - return pagedInfo, err -} - -func (c *OrderManager) ExportOrders(ctx *jxcontext.Context, fromDateStr, toDateStr string, mapParams map[string]interface{}) (hint string, err error) { - globals.SugarLogger.Debugf("ExportOrders from:%s to:%s", fromDateStr, toDateStr) - var ( - orders []*model.GoodsOrderExt - afsSkuMap map[string]map[int]*model.OrderSkuFinancial - excelBin []byte - ) - task := tasksch.NewSeqTask("导出订单SKU信息", ctx, - func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - orders, _, err = dao.GetOrders(dao.GetDB(), nil, true, true, fromDateStr, toDateStr, true, nil, false, "", mapParams, 0, model.UnlimitedPageSize) - globals.SugarLogger.Debugf("orders:%d, er:%v", len(orders), err) - case 1: - afsSkuMap, err = c.getAfsOrderSkuInfo4ExportOrders(ctx, fromDateStr, toDateStr) - case 2: - var order *model.GoodsOrderExt - var orders2 []*model.GoodsOrderExt - for _, v := range orders { - if afsInfo := afsSkuMap[jxutils.ComposeUniversalOrderID(v.VendorOrderID, v.VendorID)]; afsInfo != nil { - if afsInfo[v.SkuID] != nil && afsInfo[v.SkuID].Count > 0 { - minus := afsInfo[v.SkuID].Count - if minus > v.SkuCount2 { - minus = v.SkuCount2 - } - v.SkuCount2 -= minus - afsInfo[v.SkuID].Count -= minus - } - } - if v.SkuCount2 > 0 { - var skuStr string - if beego.BConfig.RunMode == "jxgy" { - skuStr = strings.Join([]string{ - utils.Int2Str(v.SkuID), - utils.Int2Str(v.SkuCount2), - utils.Int2Str(v.SkuShopPrice), - utils.Int2Str(v.SkuSalePrice), - utils.Int2Str(v.SkuEarningPrice), - }, ",") - } else { - if v.EarningType == model.EarningTypeQuote { - skuStr = strings.Join([]string{ - utils.Int2Str(v.SkuID), - utils.Int2Str(v.SkuCount2), - utils.Int2Str(v.SkuEarningPrice), - utils.Int2Str(v.SkuSalePrice), - utils.Int2Str(v.SkuShopPrice), - }, ",") - } else { - skuStr = strings.Join([]string{ - utils.Int2Str(v.SkuID), - utils.Int2Str(v.SkuCount2), - utils.Int2Str(v.SkuShopPrice), - utils.Int2Str(v.SkuSalePrice), - utils.Int2Str(v.SkuEarningPrice), - }, ",") - } - } - if order == nil || v.ID != order.ID { - order = v - v.CourierVendorName = model.VendorChineseNames[v.WaybillVendorID] - v.Status2 = model.OrderStatusName[v.Status] - v.SkuInfo = skuStr - orders2 = append(orders2, v) - } else { - order.SkuInfo += ";" + skuStr - } - } - } - orders = orders2 - case 3: - excelConf := &excel.Obj2ExcelSheetConfig{ - Title: "订单导出", - Data: orders, - CaptionList: []string{ - "vendorOrderID", - "vendorOrderID2", - "vendorID", - "vendorStoreID", - "jxStoreID", - "storeName", - "salePrice", - "shopPrice", - "weight", - "consigneeName", - "consigneeMobile", - "consigneeMobile2", - "consigneeAddress", - "skuCount", - "status", - "orderSeq", - "buyerComment", - "businessType", - "expectedDeliveredTime", - "vendorWaybillID", - "waybillVendorID", - "orderCreatedAt", - "orderFinishedAt", - "courierVendorName", - "courierName", - "courierMobile", - "courierMobile", - "desiredFee", - "waybillCreatedAt", - "waybillFinishedAt", - "status2", - "skuInfo", - "waybillTipMoney", - // "skuInfo2", - }, - } - excelBin = excel.Obj2Excel([]*excel.Obj2ExcelSheetConfig{excelConf}) - case 4: - keyPart := []string{ - ctx.GetUserName(), - } - if fromDateStr != "" { - keyPart = append(keyPart, fromDateStr) - } - if toDateStr != "" { - keyPart = append(keyPart, toDateStr) - } - keyPart = append(keyPart, time.Now().Format("20060102T150405")+".xlsx") - key := "export/" + strings.Join(keyPart, "_") - excelURL, err2 := jxutils.UploadExportContent(excelBin, key) - if err = err2; err == nil { - task.SetNoticeMsg(excelURL) - } - globals.SugarLogger.Debugf("导出订单SKU信息excelURL:%s, err:%v", excelURL, err) - } - return nil, err - }, 5) - tasksch.ManageTask(task).Run() - hint = task.GetID() - return hint, err -} - -func (c *OrderManager) GetWaybills(ctx *jxcontext.Context, fromDateStr, toDateStr string, params map[string]interface{}, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) { - globals.SugarLogger.Debugf("GetWaybills from:%s to:%s", fromDateStr, toDateStr) - - fromDate, err := utils.TryStr2Time(fromDateStr) - if err != nil { - return nil, err - } - if toDateStr == "" { - toDateStr = fromDateStr - } - toDate, err := utils.TryStr2Time(toDateStr) - if err != nil { - return nil, err - } - toDate = toDate.Add(24 * time.Hour) - pageSize = jxutils.FormalizePageSize(pageSize) - offset = jxutils.FormalizePageOffset(offset) - - sql := ` - SELECT SQL_CALC_FOUND_ROWS t1.*, t2.store_name, IF(t1.jx_store_id != 0, t1.jx_store_id, t1.store_id) store_id - FROM waybill t1 - JOIN goods_order t2 ON t1.vendor_order_id = t2.vendor_order_id - WHERE t1.status = 105 AND t1.waybill_created_at >= ? AND t1.waybill_created_at < ? - ` - sqlParams := []interface{}{ - fromDate, - toDate, - } - if params["keyword"] != nil { - keyword := params["keyword"].(string) - keywordLike := "%" + keyword + "%" - sql += ` - AND (t2.store_name LIKE ? OR t1.vendor_order_id LIKE ? - OR t2.vendor_waybill_id LIKE ? OR t2.courier_name LIKE ? OR t2.courier_mobile LIKE ? - ` - sqlParams = append(sqlParams, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike) - if keywordInt64, err2 := strconv.ParseInt(keyword, 10, 64); err2 == nil { - sql += " OR t2.store_id = ? OR t2.jx_store_id = ?" - sqlParams = append(sqlParams, keywordInt64, keywordInt64) - } - sql += ")" - } - - if params["waybillVendorIDs"] != nil { - var waybillVendorIDs []int - if err = utils.UnmarshalUseNumber([]byte(params["waybillVendorIDs"].(string)), &waybillVendorIDs); err != nil { - return nil, err - } - if len(waybillVendorIDs) > 0 { - sql += " AND t2.waybill_vendor_id IN (" + dao.GenQuestionMarks(len(waybillVendorIDs)) + ")" - sqlParams = append(sqlParams, waybillVendorIDs) - } - } - if params["statuss"] != nil { - var statuss []int - if err = utils.UnmarshalUseNumber([]byte(params["statuss"].(string)), &statuss); err != nil { - return nil, err - } - if len(statuss) > 0 { - sql += " AND t1.status IN (" + dao.GenQuestionMarks(len(statuss)) + ")" - sqlParams = append(sqlParams, statuss) - } - } - sql += ` - ORDER BY t1.id - LIMIT ? OFFSET ? - ` - sqlParams = append(sqlParams, pageSize, offset) - var waybills []*tWaybillExt - db := dao.GetDB() - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - if err = dao.GetRows(db, &waybills, sql, sqlParams...); err == nil { - pagedInfo = &model.PagedInfo{ - TotalCount: dao.GetLastTotalRowCount(db), - Data: waybills, - } - } - dao.Commit(db) - return pagedInfo, err -} - -func (c *OrderManager) GetOrderStatusList(ctx *jxcontext.Context, vendorOrderID string, vendorID int, orderType int) (statusList []*model.OrderStatus, err error) { - sql := ` - SELECT * - FROM order_status t1 - WHERE t1.ref_vendor_order_id = ? AND t1.ref_vendor_id = ? - ` - sqlParams := []interface{}{ - vendorOrderID, - vendorID, - } - if orderType > 0 { - sql += " AND t1.order_type = ?" - sqlParams = append(sqlParams, orderType) - } - sql += " ORDER BY t1.status_time, t1.order_type DESC, t1.status" - - db := dao.GetDB() - if err = dao.GetRows(db, &statusList, sql, sqlParams...); err != nil { - return nil, err - } - return statusList, nil -} - -func (c *OrderManager) GetOrdersFinancial(ctx *jxcontext.Context, fromDateStr, toDateStr string, params map[string]interface{}, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) { - globals.SugarLogger.Debugf("GetOrdersFinancial from:%s to:%s", fromDateStr, toDateStr) - pageSize = jxutils.FormalizePageSize(pageSize) - offset = jxutils.FormalizePageOffset(offset) - sql := ` - SELECT SQL_CALC_FOUND_ROWS t1.*, - t2.store_name,t2.vendor_store_id,t2.store_id,t2.jx_store_id,t2.status,t2.order_finished_at - FROM order_financial t1 - LEFT JOIN goods_order t2 ON t1.vendor_order_id = t2.vendor_order_id - ` - var ( - sqlWhere string - sqlParams []interface{} - ) - if params["orderID"] != nil { - sqlWhere = " WHERE (t1.vendor_order_id = ? OR t1.vendor_order_id2 = ?)" - sqlParams = []interface{}{ - params["orderID"], - params["orderID"], - } - } else { - fromDate, err2 := utils.TryStr2Time(fromDateStr) - if err = err2; err != nil { - return nil, err - } - if toDateStr == "" { - toDateStr = fromDateStr - } - toDate, err2 := utils.TryStr2Time(toDateStr) - if err = err2; err != nil { - return nil, err - } - toDate = toDate.Add(24 * time.Hour) - - // order_finished_at - sqlWhere = ` - WHERE t2.order_created_at >= ? AND t2.order_created_at < ? - ` - sqlParams = []interface{}{ - fromDate, - toDate, - } - if params["vendorIDs"] != nil { - var vendorIDs []int - if err = utils.UnmarshalUseNumber([]byte(params["vendorIDs"].(string)), &vendorIDs); err != nil { - return nil, err - } - if len(vendorIDs) > 0 { - sqlWhere += " AND t1.vendor_id IN (" + dao.GenQuestionMarks(len(vendorIDs)) + ")" - sqlParams = append(sqlParams, vendorIDs) - } - } - if params["storeIDs"] != nil { - var storeIDs []int - if err = utils.UnmarshalUseNumber([]byte(params["storeIDs"].(string)), &storeIDs); err != nil { - return nil, err - } - if len(storeIDs) > 0 { - sqlWhere += " AND IF(t2.jx_store_id != 0, t2.jx_store_id, t2.store_id) IN (" + dao.GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - } - if params["statuss"] != nil { - var statuss []int - if err = utils.UnmarshalUseNumber([]byte(params["statuss"].(string)), &statuss); err != nil { - return nil, err - } - if len(statuss) > 0 { - sqlWhere += " AND t2.status IN (" + dao.GenQuestionMarks(len(statuss)) + ")" - sqlParams = append(sqlParams, statuss) - } - } - if params["cities"] != nil { - var cities []int - if err = utils.UnmarshalUseNumber([]byte(params["cities"].(string)), &cities); err != nil { - return nil, err - } - if len(cities) > 0 { - sql += "JOIN store st ON t2.store_id = st.id" - sqlWhere += " AND st.city_code IN (" + dao.GenQuestionMarks(len(cities)) + ")" - sqlParams = append(sqlParams, cities) - } - } - } - sql += sqlWhere - sql += ` - ORDER BY t2.order_created_at DESC - LIMIT ? OFFSET ? - ` - sqlParams = append(sqlParams, pageSize, offset) - - var orders []*model.OrderFinancialExt - db := dao.GetDB() - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - if err = dao.GetRows(db, &orders, sql, sqlParams...); err == nil { - pagedInfo = &model.PagedInfo{ - TotalCount: dao.GetLastTotalRowCount(db), - Data: orders, - } - } - dao.Commit(db) - - return pagedInfo, err -} - -func (c *OrderManager) GetStoresOrderSaleInfo(ctx *jxcontext.Context, storeIDList []int, fromTime time.Time, toTime time.Time, statusList []int) (saleInfoList []*dao.StoresOrderSaleInfo, err error) { - // if globals.IsProductEnv() { - // return dao.GetStoresOrderSaleInfo(dao.GetDB(), storeIDList, fromTime, toTime, statusList) - // } - return c.GetStoresOrderSaleInfoNew(ctx, storeIDList, fromTime, toTime, statusList) -} - -func (c *OrderManager) GetStoresOrderSaleInfoNew(ctx *jxcontext.Context, storeIDList []int, fromTime time.Time, toTime time.Time, statusList []int) (saleInfoList []*dao.StoresOrderSaleInfo, err error) { - db := dao.GetDB() - // var isFinish = true - // if toTime.Sub(fromTime).Hours() > 24 { - // isFinish = false - // } - orderSkuList, err := dao.GetStoreOrderSkuList(db, storeIDList, fromTime, toTime, statusList, true) - if err != nil { - return nil, err - } - afsSkuList, err := dao.GetStoreAfsOrderSkuList(db, storeIDList, fromTime, toTime, []int{model.AfsOrderStatusFinished}, true) - if err != nil { - return nil, err - } - orderSkuList4Afs, err := dao.GetStoreOrderSkuList4Afs(db, storeIDList, fromTime, toTime, true) - if err != nil { - return nil, err - } - orderSkuHandler := func(skuList []*dao.OrderSkuWithActualPayPrice) (orderMap map[string]*model.GoodsOrder, orderSkuMap map[string]*dao.OrderSkuWithActualPayPrice, saleInfoMap map[int64]*dao.StoresOrderSaleInfo) { - orderMap = make(map[string]*model.GoodsOrder) - orderSkuMap = make(map[string]*dao.OrderSkuWithActualPayPrice) - saleInfoMap = make(map[int64]*dao.StoresOrderSaleInfo) - var flagVendorOrderID string - if len(skuList) > 0 { - flagVendorOrderID = skuList[0].VendorOrderID - } - for k, v := range skuList { - if v.EarningPrice == 0 { - v.EarningPrice = jxutils.CaculateSkuEarningPrice(v.ShopPrice, v.SalePrice, v.PayPercentage) - } - - status := v.Status - if status < model.OrderStatusEndBegin { - status = 0 - } - index := jxutils.Combine2Int(v.StoreID, v.VendorID)*1000 + int64(status) - saleInfo := saleInfoMap[index] - if saleInfo == nil { - saleInfo = &dao.StoresOrderSaleInfo{ - StoreID: v.StoreID, - VendorID: v.VendorID, - Status: status, - } - saleInfoMap[index] = saleInfo - } - if v.EarningType == model.EarningTypeQuote { - saleInfo.RealEarningPrice += v.ShopPrice * int64(v.Count) - } - saleInfo.ShopPrice += v.ShopPrice * int64(v.Count) - saleInfo.VendorPrice += v.VendorPrice * int64(v.Count) - saleInfo.SalePrice += v.SalePrice * int64(v.Count) - // saleInfo.EarningPrice += v.EarningPrice * int64(v.Count) - if v.VendorOrderID == flagVendorOrderID { - if k == 0 { - saleInfo.EarningPrice = v.NewEarningPrice - if v.EarningType == model.EarningTypePoints { - saleInfo.RealEarningPrice += v.NewEarningPrice - } - } - } else { - flagVendorOrderID = v.VendorOrderID - saleInfo.EarningPrice += v.NewEarningPrice - if v.EarningType == model.EarningTypePoints { - saleInfo.RealEarningPrice += v.NewEarningPrice - } - } - - universalOrderID := jxutils.ComposeUniversalOrderID(v.VendorOrderID, v.VendorID) - if orderMap[universalOrderID] == nil { - orderMap[universalOrderID] = &model.GoodsOrder{ - StoreID: v.StoreID, - VendorID: v.VendorID, - ActualPayPrice: v.ActualPayPrice, - } - saleInfo.ActualPayPrice += v.ActualPayPrice - saleInfo.Count++ - - saleInfo.DistanceFreightMoney += v.DistanceFreightMoney - saleInfo.WaybillTipMoney += v.WaybillTipMoney - } - orderMap[universalOrderID].SkuCount += v.Count - - universalOrderSkuID := universalOrderID + "/" + utils.Int2Str(jxutils.GetSkuIDFromOrderSku(&v.OrderSku)) - if orderSkuMap[universalOrderSkuID] == nil { - orderSkuMap[universalOrderSkuID] = v - } - } - return orderMap, orderSkuMap, saleInfoMap - } - _, _, saleInfoMap := orderSkuHandler(orderSkuList) - orderMap, orderSkuMap, _ := orderSkuHandler(orderSkuList4Afs) - - afsOrderMap := make(map[string]*model.GoodsOrder) - for _, v := range afsSkuList { - universalOrderID := jxutils.ComposeUniversalOrderID(v.VendorOrderID, v.VendorID) - universalOrderSkuID := universalOrderID + "/" + utils.Int2Str(jxutils.GetSkuIDFromOrderSkuFinancial(v)) - order := afsOrderMap[universalOrderID] - if order == nil { - order = &model.GoodsOrder{ - StoreID: v.JxStoreID, - VendorID: v.VendorID, - } - if order.StoreID == 0 { - order.StoreID = v.StoreID - } - if orderSku := orderSkuMap[universalOrderSkuID]; orderSku != nil { - order.ActualPayPrice = orderSku.ActualPayPrice - } - afsOrderMap[universalOrderID] = order - } - order.SkuCount += v.Count - - if orderSku := orderSkuMap[universalOrderSkuID]; orderSku != nil { - order.ShopPrice += orderSku.ShopPrice * int64(v.Count) - order.VendorPrice += orderSku.VendorPrice * int64(v.Count) - order.SalePrice += orderSku.SalePrice * int64(v.Count) - order.EarningPrice += orderSku.EarningPrice * int64(v.Count) - } else { - // globals.SugarLogger.Debug(utils.Format4Output(v, true)) - } - } - for universalOrderID, v := range afsOrderMap { - if orderMap[universalOrderID] != nil && orderMap[universalOrderID].SkuCount == v.SkuCount { - v.EarningPrice = orderMap[universalOrderID].ActualPayPrice - } - status := -1 - index := jxutils.Combine2Int(v.StoreID, v.VendorID)*1000 + int64(status) - saleInfo := saleInfoMap[index] - if saleInfo == nil { - saleInfo = &dao.StoresOrderSaleInfo{ - StoreID: v.StoreID, - VendorID: v.VendorID, - Status: status, - } - saleInfoMap[index] = saleInfo - } - saleInfo.ActualPayPrice += v.ActualPayPrice - saleInfo.ShopPrice += v.ShopPrice - saleInfo.VendorPrice += v.VendorPrice - saleInfo.SalePrice += v.SalePrice - saleInfo.EarningPrice += v.EarningPrice - saleInfo.Count++ - } - for _, v := range saleInfoMap { - saleInfoList = append(saleInfoList, v) - } - return saleInfoList, err -} - -func (c *OrderManager) GetAfsOrders(ctx *jxcontext.Context, keyword, afsOrderID, vendorOrderID string, vendorIDList, appealTypeList, storeIDList, statusList, skuIDs []int, fromTime, toTime time.Time, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) { - globals.SugarLogger.Debugf("GetAfsOrders") - - pageSize = jxutils.FormalizePageSize(pageSize) - offset = jxutils.FormalizePageOffset(offset) - sql := ` - SELECT SQL_CALC_FOUND_ROWS - t1.* - FROM afs_order t1 - ` - var ( - sqlWhere string - sqlParams []interface{} - ) - // 如果搜索关键字可能为订单或售后单号,则当成订单或售后单查询 - if keyword != "" { - if jxutils.GetPossibleVendorIDFromAfsOrderID(keyword) > model.VendorIDUnknown && afsOrderID == "" { - afsOrderID = keyword - } - if jxutils.GetPossibleVendorIDFromVendorOrderID(keyword) > model.VendorIDUnknown && vendorOrderID == "" { - vendorOrderID = keyword - } - } - if vendorOrderID != "" || afsOrderID != "" { - sqlWhere = "WHERE (0 = 1" - if vendorOrderID != "" { - sqlWhere += " OR (t1.vendor_order_id = ? OR t1.vendor_order_id2 = ?)" - sqlParams = append(sqlParams, []interface{}{ - vendorOrderID, - vendorOrderID, - }) - } - if afsOrderID != "" { - sqlWhere += " OR (t1.afs_order_id = ?)" - sqlParams = append(sqlParams, []interface{}{ - afsOrderID, - }) - } - sqlWhere += ")" - } else { - if toTime.Sub(fromTime) > 24*time.Hour*60 { - return nil, fmt.Errorf("售后单查询时间不能超过60天") - } - sqlWhere = ` - WHERE t1.afs_created_at >= ? AND t1.afs_created_at <= ? - ` - sqlParams = []interface{}{ - fromTime, - toTime, - } - if keyword != "" { - keywordLike := "%" + keyword + "%" - sqlWhere += ` - AND (t1.vendor_order_id2 LIKE ? OR t1.vendor_order_id LIKE ? OR t1.afs_order_id LIKE ? - OR t1.vendor_store_id LIKE ? OR t1.reason_desc LIKE ? - ` - sqlParams = append(sqlParams, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike) - if keywordInt64 := utils.Str2Int64WithDefault(keyword, 0); keywordInt64 > 0 { - sqlWhere += " OR t1.store_id = ? OR t1.jx_store_id = ?" - sqlParams = append(sqlParams, keywordInt64, keywordInt64) - } - sqlWhere += ")" - } - if len(storeIDList) > 0 { - sqlWhere += " AND IF(t1.jx_store_id != 0, t1.jx_store_id, t1.store_id) IN (" + dao.GenQuestionMarks(len(storeIDList)) + ")" - sqlParams = append(sqlParams, storeIDList) - } - if len(statusList) > 0 { - sqlWhere += " AND t1.status IN (" + dao.GenQuestionMarks(len(statusList)) + ")" - sqlParams = append(sqlParams, statusList) - } - if len(appealTypeList) > 0 { - sqlWhere += " AND t1.appeal_type IN (" + dao.GenQuestionMarks(len(appealTypeList)) + ")" - sqlParams = append(sqlParams, appealTypeList) - } - if len(skuIDs) > 0 { - sqlWhere += " AND (SELECT COUNT(*) FROM order_sku_financial t11 WHERE t11.is_afs_order = 1 AND t11.afs_order_id = t1.afs_order_id AND t11.vendor_id = t1.vendor_id AND t11.jx_sku_id IN (" + dao.GenQuestionMarks(len(skuIDs)) + ")) > 0" - sqlParams = append(sqlParams, skuIDs) - } - if len(vendorIDList) > 0 { - sqlWhere += " AND t1.vendor_id IN (" + dao.GenQuestionMarks(len(vendorIDList)) + ")" - sqlParams = append(sqlParams, vendorIDList) - } - } - sql += sqlWhere - sql += ` - ORDER BY t1.afs_created_at DESC - LIMIT ? OFFSET ? - ` - sqlParams = append(sqlParams, pageSize, offset) - - var orders []*model.AfsOrder - db := dao.GetDB() - dao.Begin(db) - defer func() { - if r := recover(); r != nil || err != nil { - dao.Rollback(db) - if r != nil { - panic(r) - } - } - }() - if err = dao.GetRows(db, &orders, sql, sqlParams...); err == nil { - pagedInfo = &model.PagedInfo{ - TotalCount: dao.GetLastTotalRowCount(db), - Data: orders, - } - dao.Commit(db) - } - return pagedInfo, err -} - -func (c *OrderManager) getAfsOrderSkuInfo4ExportOrders(ctx *jxcontext.Context, fromDateStr, toDateStr string) (skuMap map[string]map[int]*model.OrderSkuFinancial, err error) { - fromDate, err2 := utils.TryStr2Time(fromDateStr) - if err = err2; err != nil { - return nil, err - } - if utils.IsTimeZero(fromDate) { - return nil, fmt.Errorf("在没有指定订单号时,必须指定查询日期范围") - } - if toDateStr == "" { - toDateStr = fromDateStr - } - toDate, err2 := utils.TryStr2Time(toDateStr) - if err = err2; err != nil { - return nil, err - } - toDate = toDate.Add(7 * 24 * time.Hour) // todo 售后单最多只可能延后7天吧 - sql := ` - SELECT t2.* - FROM afs_order t1 - JOIN order_sku_financial t2 ON t2.vendor_order_id = t1.vendor_order_id AND t2.vendor_id = t1.vendor_id AND t2.is_afs_order = 1 AND t1.afs_order_id = t2.afs_order_id - WHERE t1.afs_finished_at >= ? AND t1.afs_finished_at <= ? AND t1.status = ? - ` - sqlParams := []interface{}{ - fromDate, - toDate, - model.AfsOrderStatusFinished, - } - var skus []*model.OrderSkuFinancial - if err = dao.GetRows(dao.GetDB(), &skus, sql, sqlParams...); err == nil { - skuMap = make(map[string]map[int]*model.OrderSkuFinancial) - for _, v := range skus { - key := jxutils.ComposeUniversalOrderID(v.VendorOrderID, v.VendorID) - if skuMap[key] == nil { - skuMap[key] = make(map[int]*model.OrderSkuFinancial) - } - if skuID := jxutils.GetSkuIDFromOrderSkuFinancial(v); skuID > 0 { - if skuMap[key][skuID] == nil { - skuMap[key][skuID] = v - } else { - skuMap[key][skuID].Count += v.Count - } - } - } - } - return skuMap, err -} - -func (c *OrderManager) GetStoreAfsOrderCountInfo(ctx *jxcontext.Context, storeID, lastHours int) (countInfo []*model.GoodsOrderCountInfo, err error) { - globals.SugarLogger.Debugf("GetStoreAfsOrderCountInfo storeID:%d", storeID) - if lastHours > maxLastHours { - lastHours = maxLastHours - } else if lastHours == 0 { - lastHours = defLastHours - } - - db := dao.GetDB() - err = dao.GetRows(db, &countInfo, ` - SELECT 0 lock_status, t1.status, COUNT(*) count - FROM afs_order t1 - WHERE t1.vendor_id <> 2 AND IF(t1.jx_store_id != 0, t1.jx_store_id, t1.store_id) = ? - AND t1.afs_created_at >= ? - GROUP BY 1,2 - ORDER BY 1,2 - `, storeID, time.Now().Add(-time.Duration(lastHours)*time.Hour)) - if err == nil { - return countInfo, nil - } - globals.SugarLogger.Infof("GetStoreAfsOrderCountInfo storeID:%d failed with error:%v", storeID, err) - return nil, err -} - -func (c *OrderManager) AmendMissingOrders(ctx *jxcontext.Context, vendorIDs []int, storeID int, fromDate, toDate time.Time, isAsync, isContinueWhenError bool) (hint string, err error) { - if utils.IsTimeZero(fromDate) { - return "", fmt.Errorf("fromDate必须指定") - } - if len(vendorIDs) == 0 { - for vendorID := range partner.PurchasePlatformHandlers { - vendorIDs = append(vendorIDs, vendorID) - } - } - if len(vendorIDs) == 0 { - return "", fmt.Errorf("找不到指定的平台") - } - - fromDate = utils.Time2Date(fromDate) - if utils.IsTimeZero(toDate) { - toDate = fromDate - } - toDate = utils.Time2Date(toDate) - curDate := utils.Time2Date(time.Now()) - if toDate.Sub(curDate) > 0 { - toDate = curDate - } - if toDate.Sub(fromDate) > 7*24*time.Hour { - return "", fmt.Errorf("最多一次一周,请调整时间") - } - - type tDateVendorPair struct { - QueryDate time.Time - VendorID int - VendorOrgCode string - } - var dateVendorList []*tDateVendorPair - for _, vendorID := range vendorIDs { - for _, vendorOrgCode := range apimanager.CurAPIManager.GetAppOrgCodeList(vendorID) { - for tmpDate := fromDate; tmpDate.Sub(toDate) <= 0; tmpDate = tmpDate.Add(24 * time.Hour) { - dateVendorList = append(dateVendorList, &tDateVendorPair{ - QueryDate: tmpDate, - VendorID: vendorID, - VendorOrgCode: vendorOrgCode, - }) - } - } - } - type tOrderVendorPair struct { - VendorOrderID string - VendorID int - VendorOrgCode string - } - if len(dateVendorList) > 0 { - var missingOrderList []*tOrderVendorPair - var updateOrderStatusList []*model.GoodsOrder - db := dao.GetDB() - vendorStoreIDMap := make(map[int]string) - if storeID > 0 { - for _, vendorID := range vendorIDs { - storeDetail, err2 := dao.GetStoreDetail(db, storeID, vendorID) - if err = err2; err != nil { - return "", err - } - vendorStoreIDMap[vendorID] = storeDetail.VendorStoreID - } - } - task := tasksch.NewSeqTask("AmendMissingOrders", ctx, - func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - task1 := tasksch.NewParallelTask("AmendMissingOrders ListOrders", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - vendorDate := batchItemList[0].(*tDateVendorPair) - if handler, _ := partner.GetPurchaseOrderHandlerFromVendorID(vendorDate.VendorID).(partner.IPurchasePlatformStoreSkuHandler); handler != nil { - orderIDs, err2 := handler.ListOrders(ctx, vendorDate.VendorOrgCode, task, vendorDate.QueryDate, vendorStoreIDMap[vendorDate.VendorID]) - if err = err2; err == nil && len(orderIDs) > 0 { - var orderList []*tOrderVendorPair - for _, v := range orderIDs { - orderList = append(orderList, &tOrderVendorPair{ - VendorOrderID: v, - VendorID: vendorDate.VendorID, - VendorOrgCode: vendorDate.VendorOrgCode, - }) - } - retVal = orderList - } - } - return retVal, err - }, dateVendorList) - tasksch.HandleTask(task1, task, true).Run() - orderList, err2 := task1.GetResult(0) - if err = err2; err != nil && !isContinueWhenError { - return "", err - } - localOrders, err2 := dao.QueryOrders(db, "", 0, vendorIDs, storeID, fromDate, toDate.Add(24*time.Hour-time.Second)) - if err = err2; err != nil { - return "", err - } - localOrderMap := make(map[string]*model.GoodsOrder) - for _, v := range localOrders { - localOrderMap[jxutils.ComposeUniversalOrderID(v.VendorOrderID, v.VendorID)] = v - } - - for _, v := range orderList { - pair := v.(*tOrderVendorPair) - goodsOrder := localOrderMap[jxutils.ComposeUniversalOrderID(pair.VendorOrderID, pair.VendorID)] - if goodsOrder == nil { - missingOrderList = append(missingOrderList, pair) - } else { - if !model.IsOrderFinalStatus(goodsOrder.Status) { - if goodsOrder.BusinessType == model.BusinessTypeImmediate { - if time.Now().Sub(goodsOrder.CreatedAt).Hours() >= orderSubTimeImmediatelyArrive { - updateOrderStatusList = append(updateOrderStatusList, goodsOrder) - } - } else { - if time.Now().Sub(goodsOrder.ExpectedDeliveredTime).Hours() >= orderSubTimeDelayArrive { - updateOrderStatusList = append(updateOrderStatusList, goodsOrder) - } - } - } - } - } - case 1: - task2 := tasksch.NewParallelTask("AmendMissingOrders GetOrders", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - pair := batchItemList[0].(*tOrderVendorPair) - if handler := partner.GetPurchaseOrderHandlerFromVendorID(pair.VendorID); handler != nil { - order, err2 := handler.GetOrder(pair.VendorOrgCode, pair.VendorOrderID) - if err = err2; err == nil { - isDuplicated, err2 := c.SaveOrder(order, false, dao.GetDB()) - if err2 == nil && !isDuplicated { - retVal = []int{1} - if order.Status == model.OrderStatusNew { - err = handler.AcceptOrRefuseOrder(order, true, ctx.GetUserName()) - } - } - } - } - return retVal, err - }, missingOrderList) - tasksch.HandleTask(task2, task, true).Run() - result, err = task2.GetResult(0) - case 2: - task3 := tasksch.NewParallelTask("AmendMissingOrders UpdateOrders", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - goodsOrder := batchItemList[0].(*model.GoodsOrder) - if handler := partner.GetPurchaseOrderHandlerFromVendorID(goodsOrder.VendorID); handler != nil { - order, err2 := handler.GetOrder(goodsOrder.VendorOrgCode, goodsOrder.VendorOrderID) - if err = err2; err == nil { - if model.IsOrderFinalStatus(order.Status) { - goodsOrder.Status = order.Status - goodsOrder.OrderFinishedAt = order.OrderFinishedAt - _, err = dao.UpdateEntity(db, goodsOrder, "Status", "OrderFinishedAt") - } - } - } - return retVal, err - }, updateOrderStatusList) - tasksch.HandleTask(task3, task, true).Run() - _, err = task3.GetResult(0) - } - return result, err - }, 3) - tasksch.HandleTask(task, nil, true).Run() - if !isAsync { - result, err2 := task.GetResult(0) - if err = err2; err == nil { - hint = utils.Int2Str(len(result)) - } - } else { - hint = task.GetID() - } - } - return hint, err -} - -func (c *OrderManager) RefreshOrderFinancial(ctx *jxcontext.Context, fromTime, toTime time.Time, isAsync, isContinueWhenError bool) (hint string, err error) { - sql := ` - SELECT * - FROM goods_order - WHERE status = ? AND total_shop_money = 0 - ` - sqlParams := []interface{}{ - model.OrderStatusFinished, - } - if !utils.IsTimeZero(fromTime) { - sql += " AND order_created_at >= ?" - sqlParams = append(sqlParams, fromTime) - } - if !utils.IsTimeZero(toTime) { - sql += " AND order_created_at <= ?" - sqlParams = append(sqlParams, toTime) - } - var orderList []*model.GoodsOrder - db := dao.GetDB() - if err = dao.GetRows(db, &orderList, sql, sqlParams...); err == nil && len(orderList) > 0 { - task := tasksch.NewParallelTask("RefreshOrderFinancial", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - order := batchItemList[0].(*model.GoodsOrder) - handler := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID) - if handler != nil { - remoteOrder, err2 := handler.GetOrder(order.VendorOrgCode, order.VendorOrderID) - if err = err2; err == nil { - order.TotalShopMoney = remoteOrder.TotalShopMoney - order.PmSubsidyMoney = remoteOrder.PmSubsidyMoney - err = partner.CurOrderManager.UpdateOrderFields(order, []string{"TotalShopMoney", "PmSubsidyMoney"}) - } - } - return nil, err - }, orderList) - tasksch.HandleTask(task, nil, true).Run() - hint = task.ID - if !isAsync { - _, err = task.GetResult(0) - } - } - return hint, err -} - -func GetOrdersAccept(ctx *jxcontext.Context, storeID int) (result []*OrderSkusAccept, err error) { - db := dao.GetDB() - sql := ` - SELECT SUM(a.count) sum_count, SUM(a.weight*a.count) sum_weight, c.*, d.name, d.unit, d.prefix, d.img - FROM order_sku a - JOIN goods_order b ON b.vendor_order_id = a.vendor_order_id AND b.vendor_id = a.vendor_id - JOIN sku c ON c.id = a.sku_id - JOIN sku_name d ON d.id = c.name_id - WHERE IF(b.store_id = 0,b.jx_store_id,b.store_id) = ? - AND b.status = ? - AND b.order_created_at <= NOW() AND b.order_created_at >= ? - GROUP BY 3 - ORDER BY sum_weight DESC - ` - sqlParams := []interface{}{ - storeID, - model.OrderStatusAccepted, - time.Now().AddDate(0, 0, -1), - } - err = dao.GetRows(db, &result, sql, sqlParams) - return result, err -} - -func GetMatterStoreOrderCount(ctx *jxcontext.Context, storeID int) (result *OrderCount, err error) { - var ( - db = dao.GetDB() - orderPays []*model.OrderPay - orderCount = &OrderCount{} - orderTime time.Time - flag = false - ) - sql := ` - SELECT b.* - FROM goods_order a - JOIN order_pay b ON a.vendor_order_id = b.vendor_order_id - WHERE IF(a.store_id = 0, a.jx_store_id, a.store_id) = 666666 - AND a.from_store_id = ? - AND a.status >= ? AND a.status <> ? - AND b.status = ? - ORDER BY b.pay_finished_at DESC - LIMIT 1 - ` - sqlParams := []interface{}{storeID, model.OrderStatusDelivering, model.OrderStatusCanceled, model.PayStatusYes} - err = dao.GetRows(db, &orderPays, sql, sqlParams) - if len(orderPays) != 0 { - orderPay := orderPays[0] - stores, _ := dao.GetStoreList(db, []int{storeID}, nil, nil, nil, "") - if len(stores) > 0 { - store := stores[0] - if store.IsBoughtMatter == model.YES { - flag = false - } else { - flag = true - } - } else { - flag = false - } - orderTime = *orderPay.PayFinishedAt - } else { - orderTime = time.Now().AddDate(0, -1, 0) - flag = true - } - sql2 := ` - SELECT COUNT(*) count - FROM goods_order - WHERE IF(store_id = 0,jx_store_id,store_id) = ? - AND order_created_at <= NOW() AND order_created_at >= ? - AND status = ? - ` - sqlParams2 := []interface{}{ - storeID, - orderTime, - model.OrderStatusFinished, - } - err = dao.GetRow(db, &orderCount, sql2, sqlParams2) - if err != nil { - return nil, err - } - orderCount.Count = int(utils.Float64TwoInt64(math.Ceil(utils.Int2Float64(orderCount.Count) * 1.5))) - orderCount.Flag = flag - // orderCount.Count = 1000 - return orderCount, err -} - -func RefreshJdShopOrdersEarningPrice(ctx *jxcontext.Context, orderStartTime, orderEndTime string) (err error) { - var ( - db = dao.GetDB() - ) - results, err := api.JdAPI.GetJdShopOrders(orderStartTime, orderEndTime, globals.JdOrgCode, globals.JdLoginName) - if err != nil { - return err - } - for _, v := range results.BillList.Result { - if v.DueAmount != 0 { - order, _ := partner.CurOrderManager.LoadOrder(utils.Int64ToStr(v.OrderID), model.VendorIDJD) - stores, _ := dao.GetStoreList(db, []int{jxutils.GetSaleStoreIDFromOrder(order)}, nil, nil, nil, "") - if len(stores) > 0 { - store := stores[0] - if order.NewEarningPrice == 0 { - jxutils.RefreshOrderEarningPrice2(order, store.PayPercentage) - } - if order.TotalShopMoney == 0 { - order.TotalShopMoney = utils.Float64TwoInt64(v.DueAmount * 100) - } - dao.UpdateEntity(db, order, "TotalShopMoney", "NewEarningPrice") - } - } - } - return err -} - -func GetOrderUserBuyFirst(ctx *jxcontext.Context, vendorOrderID string) (isFirst bool, err error) { - var orderPays []*model.OrderPay - sql := ` - SELECT b.* - FROM goods_order a, order_pay b - WHERE a.vendor_order_id = b.vendor_order_id - AND a.vendor_id = b.vendor_id - AND b.pay_finished_at <> 0 - AND a.vendor_id = ? - AND a.user_id = ( - SELECT user_id - FROM goods_order WHERE vendor_order_id = ?) - AND a.vendor_order_id <> ? - ` - sqlParams := []interface{}{model.VendorIDJX, vendorOrderID, vendorOrderID} - err = dao.GetRows(dao.GetDB(), &orderPays, sql, sqlParams) - if len(orderPays) > 0 { - return false, err - } else { - return true, err - } - return isFirst, err -} diff --git a/business/jxcallback/orderman/orderman_test.go b/business/jxcallback/orderman/orderman_test.go deleted file mode 100644 index b01dd8492..000000000 --- a/business/jxcallback/orderman/orderman_test.go +++ /dev/null @@ -1,17 +0,0 @@ -package orderman - -import ( - "git.rosy.net.cn/jx-callback/globals/api2" - "git.rosy.net.cn/jx-callback/globals/testinit" - - _ "git.rosy.net.cn/jx-callback/business/partner/purchase/ebai" - _ "git.rosy.net.cn/jx-callback/business/partner/purchase/elm" - _ "git.rosy.net.cn/jx-callback/business/partner/purchase/jd" - _ "git.rosy.net.cn/jx-callback/business/partner/purchase/mtwm" - _ "git.rosy.net.cn/jx-callback/business/partner/purchase/weimob/wsc" -) - -func init() { - testinit.Init() - api2.Init() -} diff --git a/business/jxcallback/orderman/waybill.go b/business/jxcallback/orderman/waybill.go deleted file mode 100644 index 8d8ab2d9c..000000000 --- a/business/jxcallback/orderman/waybill.go +++ /dev/null @@ -1,265 +0,0 @@ -package orderman - -import ( - "fmt" - "time" - - "git.rosy.net.cn/jx-callback/business/partner" - - "git.rosy.net.cn/baseapi/platformapi/dadaapi" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/globals" - "github.com/astaxie/beego/orm" -) - -var ( - waybillOrderStatusMap = map[int]int{ - model.WaybillStatusApplyFailedGetGoods: model.OrderStatusApplyFailedGetGoods, - model.WaybillStatusAgreeFailedGetGoods: model.OrderStatusAgreeFailedGetGoods, - model.WaybillStatusRefuseFailedGetGoods: model.OrderStatusRefuseFailedGetGoods, - model.WaybillStatusDeliverFailed: model.OrderStatusDeliverFailed, - } - complaintReasonsMap = map[int]string{ - 1: "骑手态度恶劣", - 2: "骑手接单后未取货", - 3: "骑手取货太慢", - 4: "骑手送货太慢", - 5: "货品未送达", - 6: "货品有损坏", - 7: "骑手违规收取顾客其他费用", - 69: "骑手恶意取消订单", - 71: "骑手提前点击取货/送达", - } -) - -func (w *OrderManager) LoadPendingWaybills() []*model.Waybill { - db := orm.NewOrm() - var bills []*model.Waybill - tillTime := time.Now().Add(-pendingOrderGapMax) - _, err := db.Raw(` - SELECT t1.* - FROM waybill t1 - JOIN goods_order t2 ON t2.vendor_order_id = t1.vendor_order_id - AND t2.vendor_id = t1.order_vendor_id - AND t2.order_created_at >= ? - AND t2.status < ? - WHERE t1.waybill_created_at >= ? - AND t1.status < ? - `, tillTime, model.OrderStatusEndBegin, tillTime, model.WaybillStatusEndBegin).QueryRows(&bills) - if err != nil { - globals.SugarLogger.Warnf("LoadPendingWaybills load pending waybills error:%v", err) - return nil - } - return bills -} - -func (w *OrderManager) onWaybillNew(bill2 *model.Waybill, db *dao.DaoDB) (isDuplicated bool, err error) { - globals.SugarLogger.Debugf("onWaybillNew bill:%v", bill2) - isDuplicated, err = addOrderOrWaybillStatus(model.Waybill2Status(bill2), db) - if err == nil && !isDuplicated { - bill2.ID = 0 - bill2.WaybillCreatedAt = bill2.StatusTime - bill2.WaybillFinishedAt = utils.DefaultTimeValue - billCopied := *bill2 - bill := &billCopied - created, _, err2 := db.Db.ReadOrCreate(bill, "VendorWaybillID", "WaybillVendorID") - if err = err2; err == nil { - if !created { - bill.DuplicatedCount++ - if bill2.VendorOrderID == bill2.VendorWaybillID { // 购物平台(比如京东)重新建的运单,单号始终是与订单相同的 - globals.SugarLogger.Infof("onWaybillNew duplicated1, DuplicatedCount:%d, bill:%v msg received", bill2.DuplicatedCount, bill2) - bill2.ID = bill.ID - bill2.CreatedAt = bill.CreatedAt - bill2.DuplicatedCount = bill.DuplicatedCount - err = utils.CallFuncLogError(func() error { - _, err = db.Db.Update(bill2) //更新所有字段 - return err - }, "onWaybillNew Update1") - } else { - globals.SugarLogger.Infof("onWaybillNew duplicated2 DuplicatedCount:%d, bill:%v msg received", bill.DuplicatedCount, bill2) - isDuplicated = true - err = utils.CallFuncLogError(func() error { - _, err = db.Db.Update(bill, "DuplicatedCount") - return err - }, "onWaybillNew Update2") - } - } else { - *bill2 = *bill - globals.SugarLogger.Debugf("onWaybillNew created bill:%v", bill2) - } - } else { - globals.SugarLogger.Warnf("onWaybillNew create bill:%v, error:%v", bill2, err) - } - } - return isDuplicated, err -} - -func (w *OrderManager) OnWaybillStatusChanged(bill *model.Waybill) (err error) { - var isDuplicated bool - if bill.ActualFee == 0 { - bill.ActualFee = bill.DesiredFee + bill.TipFee - } - bill.CourierMobile = jxutils.FormalizeMobile(bill.CourierMobile) - db := dao.GetDB() - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - duplicatedCount := 0 - if bill.Status == model.WaybillStatusNew { - isDuplicated, err = w.onWaybillNew(bill, db) - if isDuplicated { - duplicatedCount = 1 - } - } else { - existingBill, err2 := w.LoadWaybill(bill.VendorWaybillID, bill.WaybillVendorID) - // todo - if err2 == nil { - bill.DeliveryFlag = existingBill.DeliveryFlag - } - if bill.Status == model.WaybillStatusAccepted { // 处理美团配送丢失新运单消息的情况 - if err2 != nil { - if dao.IsNoRowsError(err2) || err2 == ErrCanNotFindWaybill { - existingBill = bill - billCopy := *bill - billCopy.Status = model.WaybillStatusNew - if isDuplicated, err = w.onWaybillNew(&billCopy, db); err != nil { - dao.Rollback(db) - return err - } - dao.Commit(db) - // 进运单调度器OnWaybillStatusChanged之前要确保事务是提交了的,否则会导致死锁 - scheduler.CurrentScheduler.OnWaybillStatusChanged(&billCopy, false) - dao.Begin(db) - } else { - dao.Rollback(db) - return err2 - } - } - // 运单消息错序,之前已经结束了,直接返回 - if existingBill.Status >= model.WaybillStatusEndBegin { - dao.Commit(db) - return nil - } - } - addParams := orm.Params{} - if bill.Status >= model.WaybillStatusAccepted { - if bill.Status == model.WaybillStatusAccepted { - if bill.DesiredFee > 0 { - addParams["desired_fee"] = bill.DesiredFee - } - if bill.ActualFee > 0 { - addParams["actual_fee"] = bill.ActualFee - } - } - if bill.CourierMobile != "" { - addParams["courier_name"] = bill.CourierName - addParams["courier_mobile"] = bill.CourierMobile - } - if bill.Status >= model.WaybillStatusEndBegin { - addParams["waybill_finished_at"] = bill.StatusTime - } - } - duplicatedCount, err = w.addWaybillStatus(bill, db, addParams) - if err != nil { - dao.Rollback(db) - return err - } - } - if err == nil { - dao.Commit(db) - if duplicatedCount == 0 { - scheduler.CurrentScheduler.OnWaybillStatusChanged(bill, false) - } - } else { - dao.Rollback(db) - } - if bill.VendorOrderID == bill.VendorWaybillID { - if status, ok := waybillOrderStatusMap[bill.Status]; ok { - fakeOrderStatus := &model.OrderStatus{ - VendorOrderID: bill.VendorOrderID, - VendorID: bill.OrderVendorID, - OrderType: model.OrderTypeOrder, - RefVendorOrderID: bill.VendorOrderID, - RefVendorID: bill.OrderVendorID, - Status: status, - VendorStatus: bill.VendorStatus, - StatusTime: bill.StatusTime, - Remark: bill.Remark, - } - w.OnOrderStatusChanged(bill.VendorOrgCode, fakeOrderStatus) - } - } - return err -} - -func (w *OrderManager) addWaybillStatus(bill *model.Waybill, db *dao.DaoDB, addParams orm.Params) (duplicatedCount int, err error) { - waybillStatus := model.Waybill2Status(bill) - isDuplicated, err := addOrderOrWaybillStatus(waybillStatus, db) - if err == nil && !isDuplicated { - if waybillStatus.Status > model.WaybillStatusUnknown { // todo 这里应该和addOrderStatus一样的改法,状态不能回绕 - params := utils.MergeMaps(orm.Params{ - "status": bill.Status, - "vendor_status": bill.VendorStatus, - "status_time": bill.StatusTime, - }, addParams) - utils.CallFuncLogError(func() error { - _, err = db.Db.QueryTable("waybill").Filter("vendor_waybill_id", bill.VendorWaybillID).Filter("waybill_vendor_id", bill.WaybillVendorID).Filter("status__lte", bill.Status).Update(params) - return err - }, "addWaybillStatus update waybill status, bill:%v", bill) - } else { - duplicatedCount = -1 - } - } else { - duplicatedCount = 1 - } - return duplicatedCount, err -} - -func (c *OrderManager) LoadWaybill(vendorWaybillID string, waybillVendorID int) (bill *model.Waybill, err error) { - db := orm.NewOrm() - bill = &model.Waybill{ - VendorWaybillID: vendorWaybillID, - WaybillVendorID: waybillVendorID, - } - if err = db.Read(bill, "VendorWaybillID", "WaybillVendorID"); err != nil { - bill = nil - if err == orm.ErrNoRows { - err = ErrCanNotFindWaybill - } - globals.SugarLogger.Infof("LoadWaybill vendorWaybillID:%s failed with error:%v", vendorWaybillID, err) - } - return bill, err -} - -func GetComplaintReasons() (complaintReasonList []*dadaapi.ComplaintReason) { - for k, v := range complaintReasonsMap { - complaintReason := &dadaapi.ComplaintReason{ - ID: k, - Reason: v, - } - complaintReasonList = append(complaintReasonList, complaintReason) - } - return complaintReasonList -} - -func ComplaintRider(ctx *jxcontext.Context, vendorOrderID string, vendorID, waybillVendorID, complaintID int) (err error) { - db := dao.GetDB() - p := partner.GetDeliveryPlatformFromVendorID(waybillVendorID).Handler - wayBillList, err := dao.GetWayBillByOrderID(db, 0, vendorID, waybillVendorID, vendorOrderID) - if err == nil && len(wayBillList) > 0 { - err = p.ComplaintRider(wayBillList[0], complaintID, complaintReasonsMap[complaintID]) - } else { - return fmt.Errorf("未查询到到相关订单!订单号:[%v] ,厂商:[%v],运送厂商:[%v]", vendorOrderID, vendorID, waybillVendorID) - } - return err -} diff --git a/business/jxstore/cms/cms.go b/business/jxstore/cms/cms.go index da514bc19..ceccd8f3b 100644 --- a/business/jxstore/cms/cms.go +++ b/business/jxstore/cms/cms.go @@ -137,7 +137,6 @@ func InitServiceInfo(version string, buildTime time.Time, gitCommit string) { "actCreateTypeName": model.ActCreateTypeName, "storeAuditStatusName": model.StoreAuditStatusName, "configTypeName": model.ConfigTypeName, - "autoSaleAt": AutoSaleAtStr, "userTypeName": model.UserTypeName, "storePriceTypeName": model.StorePriceTypeName, "payStatusName": model.PayStatusName, @@ -190,34 +189,6 @@ func GetPlaces(ctx *jxcontext.Context, keyword string, includeDisabled bool, par return places, dao.GetRows(nil, &places, sql, sqlParams) } -func UpdatePlaces(ctx *jxcontext.Context, places []map[string]interface{}, userName string) (num int64, err error) { - if len(places) == 0 { - return 0, ErrMissingInput - } - updateFields := []string{} - for k := range places[0] { - if allowUpdatePlaceFieldsMap[k] { - updateFields = append(updateFields, k) - } - } - for _, place := range places { - if place["code"] == nil { - return 0, ErrMissingInput - } - placeid := &model.Place{} - valid := dao.NormalMakeMapByFieldList(place, updateFields, userName) - if num, err = dao.UpdateEntityLogically(nil, placeid, valid, userName, utils.Params2Map("Code", place["code"])); err != nil { - return num, err - } - } - return num, err -} - -func UpdatePlace(ctx *jxcontext.Context, placeCode int, payload map[string]interface{}, userName string) (num int64, err error) { - payload["code"] = placeCode - return UpdatePlaces(ctx, []map[string]interface{}{payload}, userName) -} - func GetCoordinateDistrictCode(ctx *jxcontext.Context, lng, lat float64) (code int, err error) { return api.AutonaviAPI.GetCoordinateDistrictCode(lng, lat), nil } @@ -510,49 +481,7 @@ func UpdateConfig(ctx *jxcontext.Context, key, configType, value string) (hint s } switch configType { case model.ConfigTypePricePack: - storeMapList, err := dao.GetStoresMapList(db, nil, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, key, "") - if err != nil { - dao.Rollback(db) - return "", err - } - dao.Commit(db) - vendorStoreMap := make(map[int][]int) - for _, v := range storeMapList { - vendorStoreMap[v.VendorID] = append(vendorStoreMap[v.VendorID], v.StoreID) - } - for vendorID, storeIDs := range vendorStoreMap { - if vendorID != model.VendorIDJX { - dao.SetStoreSkuSyncStatus(db, vendorID, storeIDs, nil, model.SyncFlagPriceMask) - } else { - hint, err = ReCalculateJxPrice(db, ctx, storeIDs) - } - } - case model.ConfigTypeFreightPack: - dao.Commit(db) - storeMapList, err := dao.GetStoresMapList(db, nil, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, "", "") - if err != nil { - return "", err - } - for _, v := range storeMapList { - var storeMapList2 []*model.StoreMap - if v.FreightDeductionPack == key { - storeMapList2 = append(storeMapList2, v) - } - if len(storeMapList2) > 0 { - task := tasksch.NewParallelTask("同步门店配送免运", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeMap := batchItemList[0].(*model.StoreMap) - _, err = CurVendorSync.SyncStore(ctx, db, storeMap.VendorID, storeMap.StoreID, false, ctx.GetUserName()) - return retVal, err - }, storeMapList2) - tasksch.HandleTask(task, nil, true).Run() - if len(storeMapList2) < 5 { - _, err = task.GetResult(0) - } else { - hint = task.GetID() - } - } - } + default: dao.Commit(db) } diff --git a/business/jxstore/cms/job.go b/business/jxstore/cms/job.go index 520a8b441..946e22a61 100644 --- a/business/jxstore/cms/job.go +++ b/business/jxstore/cms/job.go @@ -2,6 +2,7 @@ package cms import ( "fmt" + "time" "git.rosy.net.cn/baseapi/utils" @@ -14,9 +15,16 @@ import ( "git.rosy.net.cn/jx-callback/business/model/dao" ) +const ( + AcceptMaxCount = 2 +) + func PublishJob(ctx *jxcontext.Context, job *model.Job) (err error) { var ( - db = dao.GetDB() + db = dao.GetDB() + timeNow = utils.Time2Date(time.Now()) + fromTime = utils.Time2Str(timeNow) + "00:00:00" + toTime = utils.Time2Str(timeNow) + "23:59:59" ) //需根据任务类型做一些参数判断,比如门店商品链接,地址 // switch job.JobCategoryID { @@ -28,6 +36,19 @@ func PublishJob(ctx *jxcontext.Context, job *model.Job) (err error) { if job.Count <= 0 { return fmt.Errorf("任务数量不能为0!") } + if job.UserID == "" { + return fmt.Errorf("任务发起人不能为空!") + } + jobs, err := dao.GetJobsNoPage(db, []string{job.UserID}, nil, utils.Str2Time(fromTime), utils.Str2Time(toTime), false) + if len(jobs) > 0 { + members, err := dao.GetUserMember(db, job.UserID, 0, 0, true) + if err != nil { + return err + } + if len(members) <= 0 { + return fmt.Errorf("非会员一天只能发布一起任务,请确认!") + } + } if job.Address != "" && (job.Lng == 0 || job.Lat == 0) { lng, lat, err := api.AutonaviAPI.GetCoordinateFromAddressByPage(job.Address) if err != nil { diff --git a/business/jxstore/cms/sku.go b/business/jxstore/cms/sku.go deleted file mode 100644 index ba4b1fdd9..000000000 --- a/business/jxstore/cms/sku.go +++ /dev/null @@ -1,2735 +0,0 @@ -package cms - -import ( - "errors" - "fmt" - "io" - "mime/multipart" - "net/http" - "regexp" - "strconv" - "strings" - "time" - - "github.com/astaxie/beego" - - "git.rosy.net.cn/baseapi/platformapi/aliupcapi" - "git.rosy.net.cn/baseapi/utils" - - "git.rosy.net.cn/baseapi" - "git.rosy.net.cn/baseapi/platformapi/dingdingapi" - "git.rosy.net.cn/baseapi/platformapi/ebaiapi" - "github.com/360EntSecGroup-Skylar/excelize" - - "git.rosy.net.cn/jx-callback/business/jxutils/ddmsg" - "git.rosy.net.cn/jx-callback/business/jxutils/excel" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - - "git.rosy.net.cn/baseapi/platformapi/jdapi" - - "git.rosy.net.cn/jx-callback/globals/api" - "git.rosy.net.cn/jx-callback/globals/refutil" - - "git.rosy.net.cn/baseapi/utils/errlist" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/datares" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" -) - -type SkuNamesInfo struct { - TotalCount int `json:"totalCount"` - SkuNames []*model.SkuNameExt `json:"skuNames"` -} - -type CreateUpcSkuByExcelErr struct { - Upc string `json:"商品条码"` - Name string `json:"商品名称"` - Unit string `json:"单位"` - SpecQuality string `json:"重量(g)"` - Price int `json:"售价"` - Err string `json:"错误原因"` -} - -var ( - ErrInputCatsDoesntMatch = errors.New("输入的类别列表不合法,需要输入一个父ID下的所有子类别") -) - -var ( - ebaiUploadRTFShopID string // 饿百找一个店用于调用SkuUploadRTF -) - -var ( - sendNoCatSkusMobile = []string{ - "18048531223", - "18982250714", - } -) - -// func getAndSetEbaiUploadRTFShopID() (shopID string) { -// if ebaiUploadRTFShopID == "" { -// if storeDetail, err := dao.GetStoreDetail(dao.GetDB(), 0, model.VendorIDEBAI); err == nil { -// ebaiUploadRTFShopID = utils.Int2Str(storeDetail.Store.ID) -// } -// } -// return ebaiUploadRTFShopID -// } - -// parentID 为-1表示所有 -func GetVendorCategories(ctx *jxcontext.Context, vendorID int, parentID string) (vendorCats []*model.SkuVendorCategory, err error) { - cond := map[string]interface{}{ - model.FieldVendorID: vendorID, - } - if parentID != "-1" { - cond[model.FieldParentID] = parentID - } - return vendorCats, dao.GetEntitiesByKV(nil, &vendorCats, cond, false) -} - -// parentID 为-1表示所有 -func GetCategories(ctx *jxcontext.Context, parentID int, isExd bool) (catList []*dao.SkuCategoryWithVendor, err error) { - db := dao.GetDB() - cats, err := dao.GetCategories(db, parentID, 0, nil, isExd) - if err == nil { - var ids []int - for _, v := range cats { - ids = append(ids, v.ID) - } - thingMapMap, err2 := dao.GetThingMapMap(db, model.ThingTypeCategory, nil, ids) - // globals.SugarLogger.Debug(utils.Format4Output(thingMapMap, false)) - if err = err2; err == nil { - for _, v := range cats { - catList = append(catList, &dao.SkuCategoryWithVendor{ - SkuCategory: v, - MapList: thingMapMap[int64(v.ID)], - }) - } - } - } - return catList, err -} - -func AddCategory(ctx *jxcontext.Context, cat *model.SkuCategory, userName string) (outCat *model.SkuCategory, err error) { - db := dao.GetDB() - if cat.Level < 0 || cat.Level > 3 { - return nil, errors.New("Level必须为1或2,3") - } else if cat.Level == 1 && cat.ParentID != 0 { - return nil, errors.New("Level1的分类其父分类必须为0") - } else if cat.Level == 2 { - if cat.ParentID == 0 { - return nil, errors.New("Level2的分类其父分类必须不为0") - } - parentCat := &model.SkuCategory{} - parentCat.ID = cat.ParentID - if err = dao.GetEntity(db, parentCat); err != nil { - return nil, err - } - if parentCat.Level != 1 { - return nil, errors.New("Level2的分类其父分类必须为Level1分类") - } - } else if cat.Level == 3 { - if cat.ParentID == 0 { - return nil, errors.New("Level3的分类其父分类必须不为0") - } - parentCat := &model.SkuCategory{} - parentCat.ID = cat.ParentID - if err = dao.GetEntity(db, parentCat); err != nil { - return nil, err - } - if parentCat.Level != 2 { - return nil, errors.New("Level3的分类其父分类必须为Level2分类") - } - } - - dao.WrapAddIDCULDEntity(cat, userName) - // cat.JdSyncStatus = model.SyncFlagNewMask - // cat.JdID = 0 - cat.Status = model.CategoryStatusEnable - cat.Name = strings.Trim(cat.Name, " ") - if cat.Img != "" { - _, err2 := datares.TryRegisterDataResource(ctx, cat.Name, cat.Img, model.ImgTypeLocal, false) - if err = err2; err != nil { - return nil, err - } - } - - if cat.Seq <= 0 { - var maxSeq struct { - MaxSeq int - } - if err = dao.GetRow(db, &maxSeq, "SELECT MAX(seq) max_seq FROM sku_category t1 WHERE level = ?", cat.Level); err != nil { - return nil, err - } - cat.Seq = maxSeq.MaxSeq + 1 - } - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - if err = dao.CreateEntity(db, cat); err != nil { - dao.Rollback(db) - return nil, err - } - if cat.IsExdSpec == model.NO { - if err = OnCreateThing(ctx, db, nil, int64(cat.ID), model.ThingTypeCategory); err != nil { - dao.Rollback(db) - return nil, err - } - } - dao.Commit(db) - outCat = cat - - _, err = CurVendorSync.SyncCategory(ctx, nil, cat.ID, false, userName) - return outCat, err -} - -func UpdateCategory(ctx *jxcontext.Context, categoryID int, payload map[string]interface{}, userName string) (num int64, err error) { - cat := &model.SkuCategory{} - cat.ID = categoryID - db := dao.GetDB() - if err = dao.GetEntity(db, cat); err != nil { - return 0, err - } - for k, v := range payload { - if v == nil { - delete(payload, k) - } - } - valid := dao.StrictMakeMapByStructObject(payload, cat, userName) - if len(valid) > 0 { - // syncStatus := 0 - // if valid["name"] != nil { - // valid["name"] = strings.Trim(valid["name"].(string), " ") - // syncStatus = model.SyncFlagModifiedMask - // valid[model.FieldJdSyncStatus] = int8(syncStatus) | cat.JdSyncStatus - // } - if valid["status"] != nil { - if utils.Interface2Int64WithDefault(valid["status"], -1) == model.CategoryStatusDisabled { - if skuList, err2 := dao.GetSkuByCats(db, []int{categoryID}); err2 == nil && len(skuList) > 0 { - return 0, fmt.Errorf("暂不允许禁用分类下有商品的分类!") - } - } - } - - if valid["img"] != nil { - if imgStr := utils.Interface2String(valid["img"]); imgStr != "" { - _, err2 := datares.TryRegisterDataResource(ctx, cat.Name, utils.Interface2String(valid["img"]), model.ImgTypeLocal, false) - if err = err2; err != nil { - return 0, err - } - } - } - - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - if num, err = dao.UpdateEntityLogically(db, cat, valid, userName, nil); err != nil { - dao.Rollback(db) - return 0, err - } - if cat.IsExdSpec == model.NO { - if err = OnUpdateThing(ctx, db, nil, int64(categoryID), model.ThingTypeCategory); err != nil { - dao.Rollback(db) - return 0, err - } - } - dao.Commit(db) - - SetStoreCategorySyncStatus2(db, nil, []int{categoryID}, model.SyncFlagModifiedMask) - var skuIDs []int - if valid["jdCategoryID"] != nil || valid["ebaiCategoryID"] != nil || valid["mtwmCategoryID"] != nil || - valid["jdPricePercentage"] != nil || valid["ebaiPricePercentage"] != nil || valid["mtwmPricePercentage"] != nil { - if skuList, err2 := dao.GetSkuByCats(db, []int{categoryID}); err2 == nil && len(skuList) > 0 { - for _, sku := range skuList { - skuIDs = append(skuIDs, sku.ID) - } - if valid["jdCategoryID"] != nil { - dao.SetSkuSyncStatus(db, model.VendorIDJD, skuIDs, model.SyncFlagModifiedMask) - } - - // todo 如下逻辑,在不同平台同时改pricePercentage与平台分类映射时,会不必要的打上多余的标记 - var vendorIDs []int - syncStatus := model.SyncFlagModifiedMask - if valid["jdPricePercentage"] != nil { - vendorIDs = append(vendorIDs, model.VendorIDJD) - syncStatus |= model.SyncFlagPriceMask - } - - if valid["ebaiPricePercentage"] != nil { - vendorIDs = append(vendorIDs, model.VendorIDEBAI) - syncStatus |= model.SyncFlagPriceMask - } else if valid["ebaiCategoryID"] != nil { - vendorIDs = append(vendorIDs, model.VendorIDEBAI) - } - - if valid["mtwmPricePercentage"] != nil { - vendorIDs = append(vendorIDs, model.VendorIDMTWM) - syncStatus |= model.SyncFlagPriceMask - } else if valid["mtwmCategoryID"] != nil { - vendorIDs = append(vendorIDs, model.VendorIDMTWM) - } - if len(vendorIDs) > 0 { - SetStoreSkuSyncStatus2(db, nil, vendorIDs, skuIDs, syncStatus) - } - } - } - _, err = CurVendorSync.SyncCategory(ctx, db, categoryID, false, userName) - if len(skuIDs) > 0 { - CurVendorSync.SyncSkus(ctx, db, nil, skuIDs, true, true, userName) - } - } - return num, err -} - -func SetStoreCategorySyncStatus2(db *dao.DaoDB, storeIDs []int, catIDs []int, syncStatus int) (num int64, err error) { - for _, vendorID := range partner.GetSingleStoreVendorIDs() { - num2, err2 := dao.SetStoreCategorySyncStatus(db, vendorID, storeIDs, catIDs, syncStatus) - if err = err2; err != nil { - return 0, err - } - num += num2 - } - return num, nil -} - -func ReorderCategories(ctx *jxcontext.Context, parentID int, categoryIDs []int, userName string, isExd bool) (err error) { - var cats []*model.SkuCategory - db := dao.GetDB() - if err = dao.GetEntitiesByKV(db, &cats, utils.Params2Map(model.FieldParentID, parentID), false); err == nil { - catsLen := len(cats) - if !isExd { - for _, v := range cats { - if v.IsExdSpec == 1 { - catsLen-- - } - } - } - if catsLen != len(categoryIDs) { - return ErrInputCatsDoesntMatch - } - catsMap := make(map[int]*model.SkuCategory, catsLen) - for _, cat := range cats { - catsMap[cat.ID] = cat - } - - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - for k, v := range categoryIDs { - if catsMap[v] == nil { - dao.Rollback(db) - return fmt.Errorf("分类:%d不在%d分类下", v, parentID) - } - if isExd { - catsMap[v].ExdSeq = k - } else { - catsMap[v].Seq = k - } - catsMap[v].LastOperator = ctx.GetUserName() - if _, err = dao.UpdateEntity(db, catsMap[v]); err != nil { - dao.Rollback(db) - return err - } - if catsMap[v].IsExdSpec == model.NO { - if err = OnUpdateThing(ctx, db, nil, int64(catsMap[v].ID), model.ThingTypeCategory); err != nil { - dao.Rollback(db) - return err - } - } - } - dao.Commit(db) - SetStoreCategorySyncStatus2(db, nil, categoryIDs, model.SyncFlagModifiedMask) - if err == nil { - _, err = CurVendorSync.SyncReorderCategories(ctx, db, parentID, false, userName) - CurVendorSync.SyncStoresCategory(ctx, db, nil, nil, false, true, true) - } - } - return err -} - -func DeleteCategory(ctx *jxcontext.Context, categoryID int, userName string) (num int64, err error) { - cat := &model.SkuCategory{} - cat.ID = categoryID - var countInfos []*struct{ Ct int } - db := dao.GetDB() - if err = dao.GetRows(db, &countInfos, ` - SELECT COUNT(*) ct - FROM sku t1 - WHERE t1.category_id = ? AND t1.deleted_at = ? - UNION ALL - SELECT COUNT(*) ct - FROM sku_name t1 - WHERE t1.category_id = ? AND t1.deleted_at = ? - UNION ALL - SELECT COUNT(*) ct - FROM sku_category t1 - WHERE t1.parent_id = ? AND t1.deleted_at = ? - `, categoryID, utils.DefaultTimeValue, categoryID, utils.DefaultTimeValue, categoryID, utils.DefaultTimeValue, &countInfos); err == nil { - if countInfos[0].Ct != 0 { - return 0, errors.New("还有商品使用此类别,不能删除") - } else if countInfos[1].Ct != 0 { - return 0, errors.New("还有商品名使用此类别,不能删除") - } else if countInfos[2].Ct != 0 { - return 0, errors.New("还有商品类别使用此类别,不能删除") - } - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - if _, err = DeleteCategoryMap(ctx, db, categoryID); err != nil { - dao.Rollback(db) - return 0, err - } - if err = OnDeleteThing(ctx, db, nil, int64(categoryID), model.ThingTypeCategory); err != nil { - dao.Rollback(db) - return 0, err - } - if num, err = dao.DeleteEntityLogically(db, cat, map[string]interface{}{ - // model.FieldJdSyncStatus: model.SyncFlagDeletedMask, - model.FieldStatus: 0, - }, userName, nil); err != nil { - dao.Rollback(db) - return 0, err - } - dao.Commit(db) - _, err = CurVendorSync.SyncCategory(ctx, db, cat.ID, false, userName) - } - return num, err -} - -func DeleteCategoryMap(ctx *jxcontext.Context, db *dao.DaoDB, categoryID int) (num int64, err error) { - if db == nil { - db = dao.GetDB() - } - catMap := &model.StoreSkuCategoryMap{} - return dao.DeleteEntityLogically(db, catMap, map[string]interface{}{ - model.FieldEbaiSyncStatus: model.SyncFlagDeletedMask, - model.FieldMtwmSyncStatus: model.SyncFlagDeletedMask, - }, ctx.GetUserName(), map[string]interface{}{ - model.FieldCategoryID: categoryID, - model.FieldDeletedAt: utils.DefaultTimeValue, - }) -} - -func GetSkuNames(ctx *jxcontext.Context, keyword string, isBySku, isQueryMidPrice bool, params map[string]interface{}, offset, pageSize int) (skuNamesInfo *SkuNamesInfo, err error) { - db := dao.GetDB() - sql := ` - FROM sku_name t1 - LEFT JOIN sku t2 ON t1.id = t2.name_id AND t2.deleted_at = ? - LEFT JOIN sku_name_place_bind t3 ON t1.id = t3.name_id - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - } - if isQueryMidPrice { - sql += ` LEFT JOIN price_refer_snapshot t4 ON t4.city_code = ? AND t4.snapshot_at = ? AND t4.name_id = t1.id` - sqlParams = append(sqlParams, 0, utils.Time2Date(time.Now().AddDate(0, 0, -1))) - } - sql += " WHERE t1.deleted_at = ?" - sqlParams = append(sqlParams, utils.DefaultTimeValue) - if keyword != "" { - keywordLike := "%" + keyword + "%" - sql += ` - AND (t1.name LIKE ? OR t1.prefix LIKE ? OR t2.comment LIKE ? OR t1.upc LIKE ? OR t1.img LIKE ? - OR (SELECT COUNT(*) FROM thing_map tm WHERE tm.vendor_thing_id LIKE ? AND tm.thing_type = ? AND tm.thing_id = t2.id AND tm.deleted_at = ?) > 0` - sqlParams = append(sqlParams, - keywordLike, keywordLike, keywordLike, keywordLike, keywordLike, - keywordLike, model.ThingTypeSku, utils.DefaultTimeValue) - if keywordInt64, err2 := strconv.ParseInt(keyword, 10, 64); err2 == nil { - sql += " OR t1.id = ? OR t2.id = ? OR t1.category_id = ?" - sqlParams = append(sqlParams, keywordInt64, keywordInt64, keywordInt64) - } - sql += ")" - } - if params["isSpu"] != nil { - sql += " AND t1.is_spu = ?" - sqlParams = append(sqlParams, utils.Bool2Int(params["isSpu"].(bool))) - } - if params["nameID"] != nil { - sql += " AND t1.id = ?" - sqlParams = append(sqlParams, params["nameID"].(int)) - } - if params["nameIDs"] != nil { - var nameIDs []int - if ids, ok := params["nameIDs"].([]int); ok { - nameIDs = ids - } else { - if err = utils.UnmarshalUseNumber([]byte(params["nameIDs"].(string)), &nameIDs); err != nil { - return nil, err - } - } - if len(nameIDs) > 0 { - sql += " AND t1.id IN (" + dao.GenQuestionMarks(len(nameIDs)) + ")" - sqlParams = append(sqlParams, nameIDs) - } - } - if params["isExd"] != nil { - var idExd = params["isExd"].(bool) - if idExd { - sql += " AND t2.exd_sku_id <> ''" - } else { - sql += " AND t2.exd_sku_id = ''" - } - } else { - sql += " AND t2.exd_sku_id = ''" - } - if params["categoryID"] != nil { - cat := &model.SkuCategory{} - cat.ID = params["categoryID"].(int) - if err = dao.GetEntity(db, cat); err != nil { - return nil, err - } - sql += " AND (t1.category_id = ?" - sqlParams = append(sqlParams, cat.ID) - if cat.Level == 1 { - sql += " OR t1.category_id IN (SELECT id FROM sku_category WHERE parent_id = ?)" - sqlParams = append(sqlParams, cat.ID) - } - sql += ")" - } - if params["skuCategoryID"] != nil { - cat := &model.SkuCategory{} - cat.ID = params["skuCategoryID"].(int) - if err = dao.GetEntity(db, cat); err != nil { - return nil, err - } - sql += " AND (t2.category_id = ?" - sqlParams = append(sqlParams, cat.ID) - if cat.Level == 1 { - sql += " OR t2.category_id IN (SELECT id FROM sku_category WHERE parent_id = ?)" - sqlParams = append(sqlParams, cat.ID) - } - sql += ")" - } - if params["vendorSkuIDs"] != nil { - var vendorSkuIDs []int - if err = utils.UnmarshalUseNumber([]byte(params["vendorSkuIDs"].(string)), &vendorSkuIDs); err != nil { - return nil, err - } - if len(vendorSkuIDs) > 0 { - sql += " AND (SELECT COUNT(*) FROM thing_map tm WHERE tm.thing_type = ? AND tm.thing_id = t2.id AND tm.deleted_at = ? AND tm.vendor_thing_id IN (" + dao.GenQuestionMarks(len(vendorSkuIDs)) + ")) > 0" - sqlParams = append(sqlParams, utils.DefaultTimeValue, vendorSkuIDs) - } - } - if params["name"] != nil { - sql += " AND t1.name LIKE ?" - sqlParams = append(sqlParams, "%"+params["name"].(string)+"%") - } - if params["prefix"] != nil { - sql += " AND t1.prefix LIKE ?" - sqlParams = append(sqlParams, "%"+params["prefix"].(string)+"%") - } - if params["unit"] != nil { - sql += " AND t1.unit = ?" - sqlParams = append(sqlParams, params["unit"].(string)) - } - if placeCond := strings.ToUpper(utils.Interface2String(params["placeCond"])); placeCond == "AND" || placeCond == "OR" { - sqlPlaceCond := "" - if placeCond == "AND" { - sqlPlaceCond += " AND ( 1 = 1" - } else { - sqlPlaceCond += " AND ( 1 = 0" - } - if params["placeCode"] != nil { - sqlPlaceCond += " " + placeCond + " t3.place_code = ?" - sqlParams = append(sqlParams, params["placeCode"].(int)) - } - if params["isGlobal"] != nil { - if params["isGlobal"].(bool) { - sqlPlaceCond += " " + placeCond + " t1.is_global = 1" - } else { - sqlPlaceCond += " " + placeCond + " t1.is_global = 0" - } - } - if sqlPlaceCond != " AND ( 1 = 0" { - sql += sqlPlaceCond + ")" - } - } - if params["skuID"] != nil { - sql += " AND t2.id = ?" - sqlParams = append(sqlParams, params["skuID"].(int)) - } - if params["skuIDs"] != nil { - var skuIDs []int - if err = utils.UnmarshalUseNumber([]byte(params["skuIDs"].(string)), &skuIDs); err != nil { - return nil, err - } - if len(skuIDs) > 0 { - sql += " AND t2.id IN (" + dao.GenQuestionMarks(len(skuIDs)) + ")" - sqlParams = append(sqlParams, skuIDs) - } - } - if params["fromStatus"] != nil { - fromStatus := params["fromStatus"].(int) - toStatus := fromStatus - if params["toStatus"] != nil { - toStatus = params["toStatus"].(int) - } - sql += " AND t2.status >= ? AND t2.status <= ?" - sqlParams = append(sqlParams, fromStatus, toStatus) - } - sql += ` - GROUP BY - t1.id, - t1.created_at, - t1.updated_at, - t1.last_operator, - t1.deleted_at, - t1.prefix, - t1.name, - t1.brand_id, - t1.category_id, - t1.jd_category_id, - t1.is_global, - t1.unit, - t1.price, - t1.img, - t1.img2, - t1.img3, - t1.img_watermark, - t1.img_mix, - t1.status, - t1.is_spu, - t1.desc_img, - t1.upc, - t1.ex_prefix, - t1.ex_prefix_begin, - t1.ex_prefix_end, - t1.yb_name_suffix, - t1.jds_stock_switch, - t1.preparation_time, - t1.best_seller - ` - if isQueryMidPrice { - sql += `, - t4.mid_unit_price` - } - if isBySku { - sql += `, - t2.id` - } - sqlData := ` - SELECT - SQL_CALC_FOUND_ROWS - t1.id, - t1.created_at, - t1.updated_at, - t1.last_operator, - t1.deleted_at, - t1.prefix, - t1.name, - t1.brand_id, - t1.category_id, - t1.jd_category_id, - t1.is_global, - t1.unit, - t1.price, - t1.img, - t1.img2, - t1.img3, - t1.img_watermark, - t1.img_mix, - t1.status, - t1.is_spu, - t1.desc_img, - t1.upc, - /* - t1.jd_id, - t1.jd_sync_status, - */ - t1.ex_prefix, - t1.ex_prefix_begin, - t1.ex_prefix_end, - t1.yb_name_suffix, - t1.jds_stock_switch, - t1.preparation_time, - t1.best_seller, - ` - if isQueryMidPrice { - sqlData += " t4.mid_unit_price," - } - sqlData += - ` - CONCAT("[", GROUP_CONCAT(DISTINCT CONCAT('{"id":', t2.id, ',"comment":"', t2.comment, '","status":', t2.status, - ',"createdAt":"', CONCAT(REPLACE(t2.created_at," ","T"),"+08:00"), '","updatedAt":"', CONCAT(REPLACE(t2.updated_at," ","T"),"+08:00"), - '","lastOperator":"', t2.last_operator, '","specQuality":', t2.spec_quality, ',"specUnit":"', t2.spec_unit, - '","exdSkuID":"', t2.exd_sku_id, - '","eclpID":"', t2.eclp_id, - '","weight":', t2.weight, ',"categoryID":', t2.category_id, ',"nameID":', t2.name_id, - ', "seq":', t2.seq, - ', "minOrderCount":', t2.min_order_count, - ', "ladderBoxNum":', t2.ladder_box_num, - ', "ladderBoxPrice":', t2.ladder_box_price, - "}")), "]") skus_str, - CONCAT("[", GROUP_CONCAT(DISTINCT t3.place_code), "]") places_str - ` + sql + ` - ORDER BY MIN(t2.seq), t1.id DESC - LIMIT ? OFFSET ?` - pageSize = jxutils.FormalizePageSize(pageSize) - offset = jxutils.FormalizePageOffset(offset) - - sqlParams = append(sqlParams, pageSize, offset) - skuNamesInfo = &SkuNamesInfo{} - dao.Begin(db) // todo 这里用事务的原因是,SQL_CALC_FOUND_ROWS会出错 - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - // globals.SugarLogger.Debug(sqlData) - // globals.SugarLogger.Debug(utils.Format4Output(sqlParams, false)) - if err = dao.GetRows(db, &skuNamesInfo.SkuNames, sqlData, sqlParams...); err == nil { - skuNamesInfo.TotalCount = dao.GetLastTotalRowCount(db) - dao.Commit(db) - - var skuIDs []int - for _, skuName := range skuNamesInfo.SkuNames { - skuName.FullName = jxutils.ComposeSkuName(skuName.Prefix, skuName.Name, "", "", 0, "", 0, skuName.ExPrefix, skuName.ExPrefixBegin, skuName.ExPrefixEnd) - if skuName.SkusStr != "" { - if err = utils.UnmarshalUseNumber([]byte(skuName.SkusStr), &skuName.Skus); err != nil { - dao.Rollback(db) - return nil, err - } - for _, v := range skuName.Skus { - skuIDs = append(skuIDs, v.ID) - } - } - if skuName.PlacesStr != "" { - if err = utils.UnmarshalUseNumber([]byte(skuName.PlacesStr), &skuName.Places); err != nil { - dao.Rollback(db) - return nil, err - } - } - skuVendorCats, _ := dao.GetSkuVendorCategoryMaps(db, []int{skuName.ID}, []int{model.VendorIDMTWM, model.VendorIDEBAI, model.VendorIDJDShop, model.VendorIDJD}, nil) - if len(skuVendorCats) > 0 { - for _, v := range skuVendorCats { - if v.VendorID == model.VendorIDJD { - skuName.JdCategoryID = v.VendorCategoryID - } - if v.VendorID == model.VendorIDEBAI { - skuName.EbaiCategoryID = v.VendorCategoryID - } - if v.VendorID == model.VendorIDMTWM { - skuName.MtwmCategoryID = v.VendorCategoryID - } - if v.VendorID == model.VendorIDJDShop { - skuName.JdsCategoryID = v.VendorCategoryID - } - } - } - } - if len(skuIDs) > 0 { - thingMapMap, err2 := dao.GetThingMapMap(db, model.ThingTypeSku, nil, skuIDs) - if err = err2; err == nil { - for _, skuName := range skuNamesInfo.SkuNames { - for _, v := range skuName.Skus { - v.MapList = thingMapMap[int64(v.ID)] - } - } - } - } - } else { - dao.Rollback(db) - } - return skuNamesInfo, err -} - -func CheckHasSensitiveWord(word string) (bool, error) { - if hasSensitiveWord, sensitiveWord := IsSensitiveWordInList(word); hasSensitiveWord { - return true, errors.New(fmt.Sprintf("不能包含敏感词:[%s]", sensitiveWord)) - } - - return false, nil -} - -func IsSensitiveWordInList(str string) (bool, string) { - wordList, err := dao.GetSensitiveWordList(-1) - if err == nil { - for _, value := range wordList { - keyWord := value.Word - if value.VendorID != -2 { - checkHas := strings.Contains(str, keyWord) - if checkHas { - return true, keyWord - } - } else { - var index int - for index > 0 { - index = strings.Index(keyWord, ",") - keyWord = keyWord[:index-1] - globals.SugarLogger.Debug("keyWord", keyWord) - checkHas := strings.Contains(str, keyWord) - if checkHas { - return true, keyWord - } - } - } - - } - } - - return false, "" -} - -func AddSkuName(ctx *jxcontext.Context, skuNameExt *model.SkuNameExt, userName string) (outSkuNameExt *model.SkuNameExt, err error) { - if skuNameExt.CategoryID == 0 { - return nil, errors.New("CategoryID不能为空") - } - if len(skuNameExt.Skus) == 0 { - return nil, errors.New("创建SKU NAME时必须至少创建一个SKU") - } else if skuNameExt.Unit != model.SpecialUnit { - if len(skuNameExt.Skus) != 1 { - return nil, errors.New("不为份的SKU NAME只能有一个SKU") - } - } - - skuNameExt.Name = utils.TrimBlankChar(skuNameExt.Name) - if hasSensitiveWord, err := CheckHasSensitiveWord(skuNameExt.Name); hasSensitiveWord { - return nil, err - } - upc := utils.Pointer2String(skuNameExt.Upc) - if upc == "" { - skuNameExt.Upc = nil - } else if !jxutils.IsUpcValid(upc) { - return nil, fmt.Errorf("upc:%s不合法,请仔细检查", upc) - } - - db := dao.GetDB() - skuNameExt.SkuName.Status = model.SkuStatusNormal - if skuNameExt.IsSpu == 1 { - return nil, fmt.Errorf("不允许创建多规格商品") - // skuNameExt.SkuName.JdSyncStatus = model.SyncFlagNewMask - } - if skuNameExt.Unit == model.SpecialUnit { - skuNameExt.SpecQuality = float32(model.SpecialSpecQuality) - skuNameExt.SpecUnit = model.SpecialSpecUnit - } else { - skuNameExt.SpecQuality = skuNameExt.Skus[0].SpecQuality - skuNameExt.SpecUnit = skuNameExt.Skus[0].SpecUnit - } - - if skuNameExt.YbNameSuffix == "" { - var name *model.SkuName - sql := "SELECT * FROM sku_name WHERE yb_name_suffix <> '' ORDER BY yb_name_suffix DESC LIMIT 1" - dao.GetRow(db, &name, sql, nil) - if name != nil { - if skuNameExt.Unit == model.UnitNames[0] { - prefix := utils.Int64ToStr(utils.Str2Int64(name.YbNameSuffix) + 1) - realPrefix := prefix - for i := 0; i < 4-len(prefix); i++ { - realPrefix = "0" + realPrefix - } - skuNameExt.YbNameSuffix = realPrefix - if utils.Str2Int64(prefix) > 9999 { - return nil, fmt.Errorf("银豹的商品后缀已超过9999!") - } - } - } - } - - picType := true - for _, imgName := range []string{skuNameExt.Img, skuNameExt.Img2} { - if imgName != "" { - dataRes, err2 := datares.TryRegisterDataResource(ctx, skuNameExt.Name, imgName, model.ImgTypeMain, false) - if err = err2; err != nil { - return nil, err - } - if dataRes.ResourceType == model.MimeTypeJpeg || dataRes.ResourceType == model.MimeTypePng { - picType = false - } - } - } - - if picType { - return nil, fmt.Errorf("商品图片应至少包含一张非gif格式的图片!") - } - - if skuNameExt.DescImg != "" { - dataRes, err2 := datares.TryRegisterDataResource(ctx, skuNameExt.Name+"desc", skuNameExt.DescImg, model.ImgTypeDesc, false) - if err = err2; err != nil { - return nil, err - } - if dataRes.ResourceType == model.MimeTypeGif { - return nil, fmt.Errorf("商品详情图片不能上传gif格式的图片!") - } - } - - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - dao.WrapAddIDCULDEntity(&skuNameExt.SkuName, userName) - if err = dao.CreateEntity(db, &skuNameExt.SkuName); err != nil { - dao.Rollback(db) - return nil, err - } - if err = OnCreateThing(ctx, db, nil, int64(skuNameExt.SkuName.ID), model.ThingTypeSkuName); err != nil { - dao.Rollback(db) - return nil, err - } - for _, v := range skuNameExt.Skus { - sku := v.Sku - dao.WrapAddIDCULDEntity(sku, userName) - sku.NameID = skuNameExt.ID - if beego.BConfig.RunMode == "jxgy" { - sku.LadderBoxPrice = 50 - } else if beego.BConfig.RunMode == "prod" { - sku.LadderBoxPrice = 30 - } - sku.LadderBoxNum = 1 - if err = dao.CreateEntity(db, sku); err != nil { - dao.Rollback(db) - return nil, err - } - if sku.EclpID == "" { - if err = OnCreateThing(ctx, db, nil, int64(sku.ID), model.ThingTypeSku); err != nil { - dao.Rollback(db) - return nil, err - } - } - } - for _, placeCode := range skuNameExt.Places { - placeBind := &model.SkuNamePlaceBind{} - dao.WrapAddIDCULEntity(placeBind, userName) - placeBind.NameID = skuNameExt.ID - placeBind.PlaceCode = placeCode - if err = dao.CreateEntity(db, placeBind); err != nil { - dao.Rollback(db) - return nil, err - } - } - dao.Commit(db) - - tmpInfo, err := GetSkuNames(ctx, "", false, false, utils.Params2Map("nameID", skuNameExt.SkuName.ID), 0, 1) - if err != nil { - return nil, err - } - if tmpInfo.TotalCount != 1 { - return nil, ErrEntityNotExist - } - outSkuNameExt = tmpInfo.SkuNames[0] - _, err = CurVendorSync.SyncSku(ctx, db, outSkuNameExt.SkuName.ID, -1, false, false, userName) - - updateOrCreateSkuVendorCategoryMap(db, ctx, outSkuNameExt.SkuName.ID, nil, skuNameExt, false) - return outSkuNameExt, err -} - -func UpdateSkuName(ctx *jxcontext.Context, nameID int, payload map[string]interface{}, isExd bool) (num int64, err error) { - userName := ctx.GetUserName() - skuName := &model.SkuName{} - skuName.ID = nameID - db := dao.GetDB() - if err = dao.GetEntity(db, skuName); err != nil { - return 0, err - } - var beforSkuName = *skuName - if payload["name"] != nil { - newSkuName := utils.TrimBlankChar(utils.Interface2String(payload["name"])) - if hasSensitiveWord, err := CheckHasSensitiveWord(newSkuName); hasSensitiveWord { - return 0, err - } - payload["name"] = newSkuName - } - - delete(payload, "isSpu") - delete(payload, "seq") - - valid := dao.StrictMakeMapByStructObject(payload, skuName, userName) - valid = utils.RemoveGeneralMapKeys(valid, model.FieldSpecQuality, model.FieldSpecUnit) - _, hasPlaces := payload["places"] - flag := updateOrCreateSkuVendorCategoryMap(db, ctx, nameID, payload, nil, false) - if len(valid) > 0 || hasPlaces || flag { - if valid["Upc"] != nil { - if upc, _ := valid["Upc"].(string); upc == "" { - valid["Upc"] = nil - } else if !jxutils.IsUpcValid(upc) { - return 0, fmt.Errorf("upc:%s不合法,请仔细检查", upc) - } - } - globals.SugarLogger.Debugf("UpdateSkuName valid:%s", utils.Format4Output(valid, false)) - for _, imgName := range []string{"img", "img2", "img3"} { - if valid[imgName] != nil { - if imgStr := utils.Interface2String(valid[imgName]); imgStr != "" { - _, err2 := datares.TryRegisterDataResource(ctx, skuName.Name, valid[imgName].(string), model.ImgTypeMain, true) - if err = err2; err != nil { - return 0, err - } - } - } - } - - if valid["descImg"] != nil { - descImg := valid["descImg"].(string) - if descImg != "" { - _, err2 := datares.TryRegisterDataResource(ctx, skuName.Name+"_desc", descImg, model.ImgTypeDesc, false) - if err = err2; err != nil { - return 0, err - } - } - } - var eclpID string - if payload["eclpID"] != nil { - eclpID = payload["eclpID"].(string) - } - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - // valid[model.FieldJdSyncStatus] = model.SyncFlagModifiedMask | skuName.JdSyncStatus - if num, err = dao.UpdateEntityLogically(db, skuName, valid, userName, nil); err != nil { - dao.Rollback(db) - return 0, err - } - if !isExd && eclpID == "" { - if err = OnUpdateThing(ctx, db, nil, int64(nameID), model.ThingTypeSkuName); err != nil { - dao.Rollback(db) - return 0, err - } - } - if utils.Interface2Int64WithDefault(payload["isGlobal"], 0) == 0 && payload["places"] != nil { - if places, ok := payload["places"].([]interface{}); ok { - if _, err = dao.DeleteSkuNamePlace(db, nameID, nil); err != nil { - dao.Rollback(db) - return 0, err - } - for _, placeCode := range places { - placeBind := &model.SkuNamePlaceBind{} - placeBind.PlaceCode = int(utils.Interface2Int64WithDefault(placeCode, 0)) - if placeBind.PlaceCode > 0 { - dao.WrapAddIDCULEntity(placeBind, userName) - placeBind.NameID = nameID - err = dao.CreateEntity(db, placeBind) - } else { - dao.Rollback(db) - return 0, errors.New("地点代码非法") - } - } - } - } - skuList, err2 := dao.GetSkus(db, nil, []int{nameID}, nil, nil, nil) - if err = err2; err == nil { - for _, v := range skuList { - sku := &v.Sku - // sku.JdSyncStatus |= model.SyncFlagModifiedMask - sku.LastOperator = userName - sku.UpdatedAt = time.Now() - if _, err = dao.UpdateEntity(db, sku); err != nil { - dao.Rollback(db) - return 0, err - } - if sku.ExdSkuID == "" && sku.EclpID == "" { - if err = OnUpdateThing(ctx, db, nil, int64(v.ID), model.ThingTypeSku); err != nil { - dao.Rollback(db) - return 0, err - } - } - } - } - skuIDs, err2 := dao.GetSkuIDByNames(db, []int{nameID}) - if err = err2; err != nil { - dao.Rollback(db) - return 0, err - } - if len(skuIDs) > 0 { - if _, err = SetStoreSkuSyncStatus2(db, nil, partner.GetSingleStoreVendorIDs(), skuIDs, model.SyncFlagModifiedMask); err != nil { - dao.Rollback(db) - return 0, err - } - if valid["jdsStockSwitch"] != nil { - if _, err = SetStoreSkuSyncStatus2(db, []int{model.JdShopMainStoreID}, []int{model.VendorIDJDShop}, skuIDs, model.SyncFlagSaleMask); err != nil { - dao.Rollback(db) - return 0, err - } - } - } - dao.Commit(db) - - errList := errlist.New() - errList.AddErr(err) - _, err = CurVendorSync.SyncSku(ctx, db, nameID, -1, false, false, userName) - errList.AddErr(err) - err = errList.GetErrListAsOne() - if globals.IsAddEvent { - mapBefore := refutil.FindMapAndStructMixed(valid, beforSkuName) - err = AddEventDetail(db, ctx, model.OperateUpdate, nameID, model.ThingTypeSkuName, 0, BuildDiffData(mapBefore), BuildDiffData(valid)) - } - } - return num, err -} - -func updateOrCreateSkuVendorCategoryMap(db *dao.DaoDB, ctx *jxcontext.Context, nameID int, payload map[string]interface{}, skuNameExt *model.SkuNameExt, isDelete bool) (flag bool) { - if isDelete { - skuVendorCatMaps, _ := dao.GetSkuVendorCategoryMaps(db, []int{nameID}, nil, nil) - for _, v := range skuVendorCatMaps { - v.DeletedAt = time.Now() - v.LastOperator = ctx.GetUserName() - dao.UpdateEntity(db, v, "DeletedAt", "LastOperator") - } - flag = true - } else { - updateOrCreate := func(vendorID, nameID int, vendorCatID string) { - skuVendorCatMaps, _ := dao.GetSkuVendorCategoryMaps(db, []int{nameID}, []int{vendorID}, nil) - if len(skuVendorCatMaps) > 0 { - skuVendorCatMaps[0].VendorCategoryID = vendorCatID - dao.UpdateEntity(db, skuVendorCatMaps[0], "VendorCategoryID") - } else { - skuVendorCatMap := &model.SkuVendorCategoryMap{ - NameID: nameID, - VendorID: vendorID, - VendorCategoryID: vendorCatID, - } - dao.WrapAddIDCULDEntity(skuVendorCatMap, ctx.GetUserName()) - dao.CreateEntity(db, skuVendorCatMap) - } - } - if skuNameExt != nil { - if skuNameExt.JdCategoryID != "" { - updateOrCreate(model.VendorIDJD, nameID, skuNameExt.JdCategoryID) - flag = true - } - if skuNameExt.JdsCategoryID != "" { - updateOrCreate(model.VendorIDJDShop, nameID, skuNameExt.JdsCategoryID) - flag = true - } - if skuNameExt.EbaiCategoryID != "" { - updateOrCreate(model.VendorIDEBAI, nameID, skuNameExt.EbaiCategoryID) - flag = true - } - if skuNameExt.MtwmCategoryID != "" { - updateOrCreate(model.VendorIDMTWM, nameID, skuNameExt.MtwmCategoryID) - flag = true - } - } else { - if payload["jdCategoryID"] != nil { - updateOrCreate(model.VendorIDJD, nameID, payload["jdCategoryID"].(string)) - flag = true - } - if payload["jdsCategoryID"] != nil { - updateOrCreate(model.VendorIDJDShop, nameID, payload["jdsCategoryID"].(string)) - flag = true - } - if payload["ebaiCategoryID"] != nil { - updateOrCreate(model.VendorIDEBAI, nameID, payload["ebaiCategoryID"].(string)) - flag = true - } - if payload["mtwmCategoryID"] != nil { - updateOrCreate(model.VendorIDMTWM, nameID, payload["mtwmCategoryID"].(string)) - flag = true - } - } - } - return flag -} - -func SetStoreSkuSyncStatus2(db *dao.DaoDB, storeIDs []int, vendorIDs, skuIDs []int, syncStatus int) (num int64, err error) { - for _, vendorID := range vendorIDs { - num2, err2 := dao.SetStoreSkuSyncStatus(db, vendorID, storeIDs, skuIDs, syncStatus) - if err = err2; err != nil { - return 0, err - } - num += num2 - } - return num, nil -} - -func DeleteSkuName(ctx *jxcontext.Context, nameID int, userName string) (num int64, err error) { - db := dao.GetDB() - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - - if _, err := dao.DeleteSkuNamePlace(db, nameID, nil); err != nil { - dao.Rollback(db) - return 0, err - } - if _, err = DeleteStoreSku(ctx, db, nameID, 0); err != nil { - dao.Rollback(db) - return 0, err - } - - skuList, err2 := dao.GetSkus(db, nil, []int{nameID}, nil, nil, nil) - if err = err2; err == nil { - for _, v := range skuList { - sku := &v.Sku - if err = OnDeleteThing(ctx, db, nil, int64(v.ID), model.ThingTypeSku); err != nil { - dao.Rollback(db) - return 0, err - } - if _, err = dao.DeleteEntityLogically(db, sku, map[string]interface{}{ - // model.FieldJdSyncStatus: model.SyncFlagDeletedMask, - model.FieldStatus: model.SkuStatusDeleted, - }, userName, nil); err != nil { - dao.Rollback(db) - return 0, err - } - } - } - - if err = OnDeleteThing(ctx, db, nil, int64(nameID), model.ThingTypeSkuName); err != nil { - dao.Rollback(db) - return 0, err - } - - skuName := &model.SkuName{} - skuName.ID = nameID - if num, err = dao.DeleteEntityLogically(db, skuName, map[string]interface{}{ - // model.FieldJdSyncStatus: model.SyncFlagDeletedMask, - model.FieldStatus: model.SkuStatusDeleted, - }, userName, nil); err != nil { - dao.Rollback(db) - return 0, err - } - dao.Commit(db) - - if len(skuList) > 0 { - _, err = CurVendorSync.SyncSku(ctx, db, skuName.ID, -1, false, false, userName) - } - updateOrCreateSkuVendorCategoryMap(db, ctx, nameID, nil, nil, true) - return num, err -} - -func AddSku(ctx *jxcontext.Context, nameID int, sku *model.Sku, userName string) (outSkuNameExt *model.SkuNameExt, err error) { - db := dao.GetDB() - skuName := &model.SkuName{} - skuName.ID = nameID - if err = dao.GetEntity(db, skuName); err != nil { - return nil, err - } - if skuName.Unit != model.SpecialUnit { - return nil, errors.New("不为份的SKU NAME只能有一个SKU") - } - - dao.WrapAddIDCULDEntity(sku, userName) - // sku.JdSyncStatus = model.SyncFlagNewMask - // sku.JdID = 0 - sku.NameID = nameID - if beego.BConfig.RunMode == "jxgy" { - sku.LadderBoxPrice = 50 - } else if beego.BConfig.RunMode == "prod" { - sku.LadderBoxPrice = 30 - } - sku.LadderBoxNum = 1 - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - if err = dao.CreateEntity(db, sku); err != nil { - dao.Rollback(db) - return nil, err - } - if err = OnCreateThing(ctx, db, nil, int64(sku.ID), model.ThingTypeSku); err != nil { - dao.Rollback(db) - return nil, err - } - dao.Commit(db) - - result, err2 := GetSkuNames(ctx, "", false, false, utils.Params2Map("skuID", sku.ID), 0, 0) - if err = err2; err == nil { - if result.TotalCount == 1 { - outSkuNameExt = result.SkuNames[0] - _, err = CurVendorSync.SyncSku(ctx, db, outSkuNameExt.SkuName.ID, sku.ID, false, false, userName) - } else { - err = ErrEntityNotExist - } - } - //增加规格则同步到门店,目前只做了京东商城的。 - storeSkus, err := dao.GetStoreSkusByNameIDs(db, []int{model.JdShopMainStoreID}, nameID) - if len(storeSkus) > 0 { - storeIDs := make(map[int]int) - storeMaps, err2 := dao.GetStoresMapList(db, []int{model.VendorIDJDShop}, nil, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "") - err = err2 - for _, v := range storeMaps { - storeSkus2, err2 := dao.GetStoreSkusByNameIDs(db, []int{v.StoreID}, nameID) - err = err2 - if len(storeSkus2) > 0 { - storeIDs[v.StoreID] = v.StoreID - } - } - skuBindInfos := []*StoreSkuBindInfo{} - for _, v := range storeIDs { - skus2 := []*StoreSkuBindSkuInfo{} - skuBindInfo := &StoreSkuBindInfo{ - StoreID: v, - } - sku2 := &StoreSkuBindSkuInfo{ - SkuID: sku.ID, - } - skus2 = append(skus2, sku2) - skuBindInfo.Skus = skus2 - skuBindInfos = append(skuBindInfos, skuBindInfo) - } - FocusStoreSkusBySku(ctx, skuBindInfos, true, true) - } - return outSkuNameExt, err -} - -func UpdateSku(ctx *jxcontext.Context, skuID int, payload map[string]interface{}) (num int64, err error) { - userName := ctx.GetUserName() - sku := &model.Sku{} - sku.ID = skuID - db := dao.GetDB() - if err = dao.GetEntity(db, sku); err != nil { - return 0, err - } - var beforSku = *sku - valid := dao.StrictMakeMapByStructObject(payload, sku, userName) - if len(valid) > 0 { - // globals.SugarLogger.Debug(utils.Format4Output(valid, false)) - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - maskValue := int8(model.SyncFlagModifiedMask) - if valid["specQuality"] != nil || valid["specUnit"] != nil { - maskValue |= model.SyncFlagSpecMask - } - // valid[model.FieldJdSyncStatus] = maskValue | sku.JdSyncStatus - if num, err = dao.UpdateEntityLogically(db, sku, valid, userName, nil); err != nil || num == 0 { - dao.Rollback(db) - if err == nil { - err = ErrEntityNotExist - } - return 0, err - } - if _, err = dao.ExecuteSQL(db, ` - UPDATE sku_name t1 - JOIN sku t2 ON t1.id = t2.name_id - SET t1.spec_quality = t2.spec_quality, - t1.spec_unit = t2.spec_unit - WHERE t1.deleted_at = ? AND t2.id = ? AND t1.unit <> ? - `, utils.DefaultTimeValue, skuID, model.SpecialUnit); err != nil { - dao.Rollback(db) - if err == nil { - err = ErrEntityNotExist - } - return 0, err - } - if sku.ExdSkuID == "" && sku.EclpID == "" { - if err = OnUpdateThing(ctx, db, nil, int64(skuID), model.ThingTypeSku); err != nil { - dao.Rollback(db) - return 0, err - } - } - dao.Commit(db) - - if _, err = SetStoreSkuSyncStatus2(db, nil, partner.GetSingleStoreVendorIDs(), []int{skuID}, model.SyncFlagModifiedMask); err == nil { - if maskValue&model.SyncFlagSpecMask != 0 { - err = refreshStoreSkuPrice(ctx, db, skuID) - } - if valid["status"] != nil { - SetStoreSkuSyncStatus2(db, nil, partner.GetSingleStoreVendorIDs(), []int{skuID}, model.SyncFlagSaleMask) - } - } - errList := errlist.New() - errList.AddErr(err) - _, err = CurVendorSync.SyncSku(ctx, db, -1, sku.ID, false, false, userName) - errList.AddErr(err) - err = errList.GetErrListAsOne() - if globals.IsAddEvent { - mapBefore := refutil.FindMapAndStructMixed(valid, beforSku) - err = AddEventDetail(db, ctx, model.OperateUpdate, skuID, model.ThingTypeSku, 0, BuildDiffData(mapBefore), BuildDiffData(valid)) - } - } - return num, err -} - -func refreshStoreSkuPrice(ctx *jxcontext.Context, db *dao.DaoDB, skuID int) (err error) { - list, err := dao.GetStoreSkusAndSkuName(db, nil, []int{skuID}, nil) - task := tasksch.NewParallelTask("refreshStoreSkuPrice", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(true), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - v := batchItemList[0].(*dao.StoreSkuAndName) - storeID := v.StoreID - storeDetail, _ := dao.GetStoreDetail(db, storeID, model.VendorIDJX) - if storeDetail == nil { - return retVal, err - } - storeSku := &model.StoreSkuBind{} - storeSku.ID = v.BindID - storeSku.JdSyncStatus = v.JdSyncStatus | model.SyncFlagPriceMask - storeSku.MtwmSyncStatus = v.MtwmSyncStatus | model.SyncFlagPriceMask - storeSku.EbaiSyncStatus = v.EbaiSyncStatus | model.SyncFlagPriceMask - storeSku.Price = jxutils.CaculateSkuPrice(int(v.UnitPrice), v.SpecQuality, v.SpecUnit, v.Unit) - storeSku.JxPrice = jxutils.CaculatePriceByPricePack(storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage), int(storeSku.Price)) - storeSku.LastOperator = ctx.GetUserName() - storeSku.UpdatedAt = time.Now() - dao.Begin(db) - defer func() { - if r := recover(); r != nil || err != nil { - dao.Rollback(db) - if r != nil { - panic(r) - } - } - }() - dao.UpdateEntity(db, storeSku, "Price", "JdSyncStatus", "MtwmSyncStatus", "EbaiSyncStatus", "JxPrice", "LastOperator") - dao.Commit(db) - return retVal, err - }, list) - tasksch.HandleTask(task, nil, true).Run() - _, err = task.GetResult(0) - return err -} - -func DeleteSku(ctx *jxcontext.Context, skuID int, userName string) (num int64, err error) { - db := dao.GetDB() - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - - if _, err = DeleteStoreSku(ctx, db, 0, skuID); err != nil { - dao.Rollback(db) - return 0, err - } - if err = OnDeleteThing(ctx, db, nil, int64(skuID), model.ThingTypeSku); err != nil { - dao.Rollback(db) - return 0, err - } - sku := &model.Sku{} - sku.ID = skuID - if num, err = dao.DeleteEntityLogically(db, sku, map[string]interface{}{ - model.FieldStatus: model.SkuStatusDeleted, - // model.FieldJdSyncStatus: model.SyncFlagDeletedMask, - }, userName, nil); err != nil { - dao.Rollback(db) - return 0, err - } - dao.Commit(db) - if num == 1 { - _, err = CurVendorSync.SyncSku(ctx, db, -1, sku.ID, false, false, userName) - } - err = deleteJdsSku(db, skuID) - return num, err -} - -func DeleteStoreSku(ctx *jxcontext.Context, db *dao.DaoDB, nameID, skuID int) (num int64, err error) { - if db == nil { - db = dao.GetDB() - } - - sql := ` - SELECT * - FROM sku t1 - WHERE 1 = 1 - ` - sqlParams := []interface{}{} - if nameID > 0 { - sql += " AND t1.name_id = ?" - sqlParams = append(sqlParams, nameID) - } else { - sql += " AND t1.id = ?" - sqlParams = append(sqlParams, skuID) - } - - var skuList []*model.Sku - if err = dao.GetRows(db, &skuList, sql, sqlParams); err == nil { - num = int64(len(skuList)) - for _, v := range skuList { - storeSkuBind := &model.StoreSkuBind{} - _, err = dao.DeleteEntityLogically(db, storeSkuBind, map[string]interface{}{ - model.FieldJdSyncStatus: model.SyncFlagDeletedMask, - model.FieldMtwmSyncStatus: model.SyncFlagDeletedMask, - model.FieldEbaiSyncStatus: model.SyncFlagDeletedMask, - model.FieldJdsSyncStatus: model.SyncFlagDeletedMask, - }, ctx.GetUserName(), map[string]interface{}{ - model.FieldSkuID: v.ID, - model.FieldDeletedAt: utils.DefaultTimeValue, - }) - if err != nil { - break - } - } - } - return num, err -} - -func AddSkuNamePlace(ctx *jxcontext.Context, nameID, placeCode int, userName string) (outPlaceBind *model.SkuNamePlaceBind, err error) { - db := dao.GetDB() - placeBind := &model.SkuNamePlaceBind{ - NameID: nameID, - PlaceCode: placeCode, - } - dao.WrapAddIDCULEntity(placeBind, userName) - - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - if err = dao.CreateEntity(db, placeBind); err != nil { - dao.Rollback(db) - return nil, err - } - if err = OnUpdateThing(ctx, db, nil, int64(nameID), model.ThingTypeSkuName); err != nil { - dao.Rollback(db) - return nil, err - } - dao.Commit(db) - - _, err = CurVendorSync.SyncSku(ctx, db, nameID, -1, false, false, userName) - return placeBind, err -} - -func DeleteSkuNamePlace(ctx *jxcontext.Context, nameID, placeCode int, userName string) (num int64, err error) { - db := dao.GetDB() - placeBind := &model.SkuNamePlaceBind{} - placeBind.NameID = nameID - placeBind.PlaceCode = placeCode - - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - if num, err = dao.DeleteEntity(db, placeBind, model.FieldNameID, model.FieldPlaceCode); err != nil || num == 0 { - dao.Rollback(db) - if err == nil { - err = ErrEntityNotExist - } - return 0, err - } - if err = OnUpdateThing(ctx, db, nil, int64(nameID), model.ThingTypeSkuName); err != nil { - dao.Rollback(db) - return 0, err - } - dao.Commit(db) - - _, err = CurVendorSync.SyncSku(ctx, db, nameID, -1, false, false, userName) - return num, err -} - -// func GetVendorSku(ctx *jxcontext.Context, vendorID int, vendorOrgCode, vendorSkuID string) (skuNameInfo *model.SkuNameExt, err error) { -// if handler := CurVendorSync.GetMultiStoreHandler(vendorID); handler != nil { -// return handler.ReadSku(ctx, vendorOrgCode, vendorSkuID) -// } -// return nil, ErrCanNotFindVendor -// } - -func SortCategorySkus(ctx *jxcontext.Context, catID int, skuIDList []int) (err error) { - db := dao.GetDB() - userName := ctx.GetUserName() - var skuList []*model.Sku - if skuList, err = dao.GetSkuByCats(db, []int{catID}); err == nil && len(skuList) > 0 { - if len(skuList) != len(skuIDList) { - return errors.New("商品数量不匹配!") - } - skuIDMap := make(map[int]int) - for index, id := range skuIDList { - skuIDMap[id] = index + 1 - } - for _, value := range skuList { - if _, ok := skuIDMap[value.ID]; !ok { - return errors.New("商品数据不匹配!") - } - } - - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - nameIDList := []int{} - for _, value := range skuList { - seq := skuIDMap[value.ID] - if value.Seq != seq { - kvs := map[string]interface{}{ - model.FieldSkuSeq: seq, - //model.FieldJdSyncStatus: (value.JdSyncStatus | model.SyncFlagModifiedMask), - } - dao.UpdateEntityLogically(db, value, kvs, userName, nil) - nameIDList = append(nameIDList, value.NameID) - } - } - //_, err = CurVendorSync.SyncSkus(ctx, db, nameIDList, []int{}, false, false, userName) - - if err == nil && len(nameIDList) > 0 { - dao.Commit(db) - skuIDs, err2 := dao.GetSkuIDByNames(db, nameIDList) - if err = err2; err == nil && len(skuIDs) > 0 { - _, err = SetStoreSkuSyncStatus2(db, nil, partner.GetSingleStoreVendorIDs(), skuIDs, model.SyncFlagModifiedMask) - } - } else { - dao.Rollback(db) - } - } - return err -} - -func GetJdUpcCodeByCode(ctx *jxcontext.Context, upcCode string) (productInfos []*jdapi.ProductInfo, err error) { - productInfo, err := api.JdAPI.GetJdUpcCodeByName("", upcCode, 1, 30) - if err != nil { - return nil, err - } - for _, v := range productInfo { - _, name, _, specUnit, unit, specQuality := jxutils.SplitSkuName(v.OriginalName) - v.Name = name - v.SpecQuality = specQuality - v.SpecUnit = specUnit - v.Unit = unit - } - return productInfo, err -} - -func GetJdUpcCodeByName(ctx *jxcontext.Context, name, upcCode string) (productInfos []*jdapi.ProductInfo, err error) { - if name != "" { - var ( - pageNo = 5 - pageSize = 30 - pageNoList []int - ) - if name == "" && upcCode == "" { - return nil, fmt.Errorf("至少输入一个条件查询,商品名或者upc码!") - } - for i := 1; i < pageNo+1; i++ { - pageNoList = append(pageNoList, i) - } - task := tasksch.NewParallelTask("获取京东商品", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - pageNum := batchItemList[0].(int) - productInfo, err := api.JdAPI.GetJdUpcCodeByName(name, upcCode, pageNum, pageSize) - if err != nil { - return retVal, err - } - for _, v := range productInfo { - _, name, _, specUnit, unit, specQuality := jxutils.SplitSkuName(v.OriginalName) - v.Name = name - v.SpecQuality = specQuality - v.SpecUnit = specUnit - v.Unit = unit - } - retVal = productInfo - return retVal, err - }, pageNoList) - tasksch.HandleTask(task, nil, true).Run() - productInfoInterface, err2 := task.GetResult(0) - err = err2 - for _, v := range productInfoInterface { - productInfos = append(productInfos, v.(*jdapi.ProductInfo)) - } - } else { - productInfos, err = GetJdUpcCodeByCode(ctx, upcCode) - } - return productInfos, err -} - -func UpdateSkuNamesExPrefix(ctx *jxcontext.Context, nameIDs []int, imgWaterMark string, vendorID int, exPrefix, fromTime, toTime string, isAsync, isContinueWhenError bool) (hint string, err error) { - var ( - fromTimeP time.Time - toTimeP time.Time - db = dao.GetDB() - ) - if fromTime != "" { - fromTimeP = utils.Time2Date(utils.Str2Time(fromTime)) - } - if toTime != "" { - toTimeP = utils.Time2Date(utils.Str2Time(toTime)) - } - if toTimeP.Before(fromTimeP) { - return "", fmt.Errorf("结束时间不可以小于开始时间!开始时间:[%v],结束时间:[%v]", fromTimeP, toTimeP) - } - task := tasksch.NewParallelTask("批量设置商品前缀", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - step := batchItemList[0].(int) - now := utils.Time2Date(time.Now()) - switch step { - case 0: - task := tasksch.NewParallelTask("批量设置商品前缀", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - nameID := batchItemList[0].(int) - payload := map[string]interface{}{ - "exPrefix": exPrefix, - "exPrefixBegin": fromTimeP, - "exPrefixEnd": toTimeP, - "imgWaterMark": imgWaterMark, - "exVendorID": vendorID, - } - if now.Sub(toTimeP) <= 0 && now.Sub(fromTimeP) <= 0 { - _, err = UpdateSkuName(ctx, nameID, payload, false) - } else if now.Sub(fromTimeP) > 0 && now.Sub(toTimeP) > 0 { - payload["exPrefixBegin"] = nil - payload["exPrefixEnd"] = nil - payload["imgWaterMark"] = nil - payload["exVendorID"] = nil - _, err = UpdateSkuName(ctx, nameID, payload, false) - } else { - skuList, err := dao.GetSkus(db, nil, []int{nameID}, nil, nil, nil) - if err == nil && len(skuList) > 0 { - if skuList[0].ExPrefixBegin != nil { - _, err = UpdateSkuName(ctx, nameID, payload, false) - CurVendorSync.SyncStoresSkus2(ctx, nil, 0, db, []int{vendorID}, nil, false, []int{skuList[0].ID}, nil, model.SyncFlagModifiedMask, true, true) - } else { - skuName := &model.SkuName{ - ExPrefix: exPrefix, - ExPrefixBegin: &fromTimeP, - ExPrefixEnd: &toTimeP, - ImgWatermark: imgWaterMark, - ExVendorID: vendorID, - } - skuName.ID = nameID - skuName.LastOperator = ctx.GetLoginID() - skuName.UpdatedAt = time.Now() - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - _, err = dao.UpdateEntity(db, skuName, "ImgWatermark", "ExVendorID", "ExPrefix", "ExPrefixBegin", "ExPrefixEnd", "LastOperator", "UpdatedAt") - dao.Commit(db) - } - } - } - return retVal, err - }, nameIDs) - tasksch.HandleTask(task, nil, true).Run() - _, err = task.GetResult(0) - case 1: - if (now.Sub(toTimeP) <= 0 && now.Sub(fromTimeP) >= 0) || (now.Sub(fromTimeP) > 0 && now.Sub(toTimeP) > 0) { - var skuIDs []int - skuList, err2 := dao.GetSkus(db, nil, nameIDs, nil, nil, nil) - if err = err2; err == nil { - if len(skuList) > 0 { - for _, v := range skuList { - skuIDs = append(skuIDs, v.ID) - } - CurVendorSync.SyncStoresSkus2(ctx, nil, 0, db, []int{vendorID}, nil, false, skuIDs, nil, model.SyncFlagModifiedMask, true, true) - } - } - } - } - return retVal, err - }, []int{0, 1}) - tasksch.HandleTask(task, nil, true).Run() - if !isAsync { - _, err = task.GetResult(0) - hint = "1" - } else { - hint = task.GetID() - } - return hint, err -} - -func SetSingleStoreSkuSyncModifyStatus(db *dao.DaoDB, vendorIDs []int) (err error) { - _, err = dao.UpdateStoreSkuBindSyncStatusForExPrefix(db, vendorIDs) - return err -} - -func SetMultiStoreSkuSyncModifyStatus(db *dao.DaoDB, vendorIDs []int) (err error) { - _, err = dao.UpdateSkuSyncStatusForExPrefix(db, vendorIDs) - return err -} - -func DeleteSkuNameExPrefixOverdue(db *dao.DaoDB) (err error) { - _, err = dao.DeleteSkuNameExPrefixOverdue(db) - return err -} - -func SumExianDaDepot(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (hint string, err error) { - db := dao.GetDB() - results, err := api.EbaiAPI.GetExianDaSkuDepot("") - taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - v := batchItemList[0].(*ebaiapi.ExianDaSkus) - skus, err := api.EbaiAPI.GetExianDaSku(utils.Str2Int64(v.ElemeGoodsID)) - if err != nil || skus == nil { - globals.SugarLogger.Debugf("GetExianDaSku,[%v]", v.ElemeGoodsID) - return result, err - } - // sku := &model.Sku{} - // sku.ExdSkuID = v.ElemeGoodsID - // sku.DeletedAt = utils.DefaultTimeValue - // dao.GetEntity(db, sku, "ExdSkuID","DeletedAt") - skuNameExt := &model.SkuName{} - sql2 := ` - SELECT a.* - FROM sku_name a - JOIN sku b ON b.name_id = a.id - WHERE a.upc = ? - AND a.deleted_at = ? AND b.deleted_at = ? - ` - sqlParams2 := []interface{}{ - skus.UpcIds[0], - utils.DefaultTimeValue, utils.DefaultTimeValue, - } - dao.GetRow(db, skuNameExt, sql2, sqlParams2) - prefix, _, _, specUnit, unit, specQuality := jxutils.SplitSkuName(v.GoodsName) - //京西库中存在此商品 - if skuNameExt.ID != 0 { - var flag = false - if skuNameExt.Name != v.GoodsName { - skuNameExt.Name = v.GoodsName - skuNameExt.Prefix = prefix - skuNameExt.SpecUnit = specUnit - skuNameExt.Unit = unit - skuNameExt.SpecQuality = specQuality - flag = true - } - if skuNameExt.Img != v.ImageURL { - skuNameExt.Img = v.ImageURL - flag = true - } - if flag { - _, err = dao.UpdateEntity(db, skuNameExt, "Name", "Prefix", "SpecUnit", "Unit", "SpecQuality", "Img") - if err != nil { - return result, err - } - } - } else { - skuName := &model.SkuName{ - Prefix: prefix, - Name: v.GoodsName, - IsGlobal: model.YES, - Unit: unit, - SpecQuality: specQuality, - SpecUnit: specUnit, - Price: 100, - Img: v.ImageURL, - Upc: &v.UpcID, - Status: model.SkuStatusNormal, - } - skuName.CategoryID = model.NoCatCatgoryID //默认给了个分类 - dao.WrapAddIDCULDEntity(skuName, ctx.GetUserName()) - err = dao.CreateEntity(db, skuName) - if err != nil { - return result, err - } - sku := &model.Sku{ - NameID: skuName.ID, - SpecQuality: specQuality, - SpecUnit: specUnit, - Weight: int(utils.Str2Int64(skus.Weight)), - Status: model.SkuStatusNormal, - ExdSkuID: v.ElemeGoodsID, - ExdCategoryThirdID: skus.CategoryIDThird, - } - dao.WrapAddIDCULDEntity(sku, ctx.GetUserName()) - err = dao.CreateEntity(db, sku) - if err != nil { - return result, err - } - } - return retVal, err - } - taskParallel := tasksch.NewParallelTask("更新京西上饿鲜达商品库", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, taskFunc, results) - tasksch.HandleTask(taskParallel, task, true).Run() - _, err = taskParallel.GetResult(0) - case 1: - } - return result, err - } - taskSeq := tasksch.NewSeqTask2("合并饿鲜达商品库", ctx, isContinueWhenError, taskSeqFunc, 2) - tasksch.HandleTask(taskSeq, nil, true).Run() - if !isAsync { - _, err = taskSeq.GetResult(0) - hint = "1" - } else { - hint = taskSeq.GetID() - } - return hint, err -} - -func UpdateExianDaSkuCategory(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (hint string, err error) { - var ( - db = dao.GetDB() - skus []*model.SkuName - ) - sql := ` - SELECT a.* - FROM sku_name a - JOIN sku b ON b.name_id = a.id - WHERE b.exd_sku_id <> '' - AND a.deleted_at = ? - AND b.deleted_at = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, utils.DefaultTimeValue, - } - err = dao.GetRows(db, &skus, sql, sqlParams...) - task := tasksch.NewParallelTask("更新京西上饿鲜达商品分类", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - v := batchItemList[0].(*model.SkuName) - skuList, err := api.Ebai2API.GetEbaiDepotSku(ebaiapi.EbaiWholeCountryStore, *v.Upc) - if err != nil || len(skuList) == 0 || skuList[0] == nil { - return retVal, err - } - sku, err := api.Ebai2API.GetEbaiSku(skuList[0].UpcID, ebaiapi.EbaiWholeCountryStore) - if err != nil || sku == nil || sku.CustomCatName == "" { - return retVal, err - } - skuCat := &model.SkuCategory{} - sql := ` - SELECT * - FROM sku_category - WHERE exd_name like ? - ` - sqlParams := []interface{}{ - "%" + sku.CustomCatName + "%", - } - err = dao.GetRow(db, skuCat, sql, sqlParams) - v.CategoryID = skuCat.ID - _, err = dao.UpdateEntity(db, v, "CategoryID") - if err != nil { - return retVal, err - } - return retVal, err - }, skus) - tasksch.HandleTask(task, nil, true).Run() - if !isAsync { - _, err = task.GetResult(0) - hint = "1" - } else { - hint = task.GetID() - } - return hint, err -} - -func SendNoCatSkusToOperater(ctx *jxcontext.Context) (err error) { - var ( - db = dao.GetDB() - skuNames []*model.SkuName - ) - globals.SugarLogger.Debugf("SendNoCatSkusToOperater") - sql := ` - SELECT * FROM sku_name WHERE deleted_at = ? AND (category_id = ? OR img = ?) AND unit <> ? - ` - sqlParams := []interface{}{utils.DefaultTimeValue, model.NoCatCatgoryID, model.NOSkuNameImg, model.UnitNames[0]} - err = dao.GetRows(db, &skuNames, sql, sqlParams) - if err != nil { - return err - } - if len(skuNames) > 10 { - noticeMsg := "有超过10个标品未进行分类和未设置图片!" - for _, v := range skuNames { - noticeMsg += "NameID:" + utils.Int2Str(v.ID) + ",商品名:" + v.Name + "," - } - for _, mobile := range sendNoCatSkusMobile { - if user, err := dao.GetUserByID(db, "mobile", mobile); err != nil { - ddmsg.SendUserMessage(dingdingapi.MsgTyeText, user.UserID, "标品未分类和未设置图片", noticeMsg) - } - } - } - return err -} - -func buildCreateUpcSkuByExcelErr(v *model.SkuName, errMsg string) (createUpcSkuByExcelErr *CreateUpcSkuByExcelErr) { - createUpcSkuByExcelErr = &CreateUpcSkuByExcelErr{ - Upc: *v.Upc, - Name: v.Name, - Unit: v.Unit, - SpecQuality: utils.Float64ToStr(float64(v.SpecQuality)), - Price: v.Price / 100, - Err: errMsg, - } - return createUpcSkuByExcelErr -} - -func CreateUpcSkuByExcel(ctx *jxcontext.Context, files []*multipart.FileHeader, categoryID int) (hint string, err error) { - if len(files) == 0 { - return "", errors.New("没有文件上传!") - } - fileHeader := files[0] - file, err := fileHeader.Open() - hint, err = CreateUpcSkuByExcelBin(ctx, file, categoryID) - file.Close() - return hint, err -} - -func CreateUpcSkuByExcelBin(ctx *jxcontext.Context, reader io.Reader, categoryID int) (hint string, err error) { - var ( - db = dao.GetDB() - skuParams []*model.SkuName - createUpcSkuByExcelErrList []*CreateUpcSkuByExcelErr - createUpcSkuByExcelErrListInterface []interface{} - excelTitle = []string{ - "商品条码", - "商品名称", - "单位", - "重量(g)", - "售价", - "错误原因", - } - upcRegexp = regexp.MustCompile(`(^\d{12,13}$)`) - ) - taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result2 interface{}, err error) { - switch step { - case 0: - xlsx, err := excelize.OpenReader(reader) - if err != nil { - return result2, err - } - rows, _ := xlsx.GetRows(xlsx.GetSheetName(1)) - for rowNum, row := range rows { - if rowNum < 1 { - continue - } - var ( - skuParam = &model.SkuName{} - upc string - unit string - specQuality float32 - price int - name string - ) - for k, cell := range row { - if cell != "" { - if k == 0 { - upc = cell - } - if k == 1 { - name = cell - } - if k == 2 { - unit = cell - } - if k == 3 { - specQuality = float32(utils.Str2Float64WithDefault(cell, 0)) - } - if k == 4 { - price = int(utils.Str2Float64WithDefault(cell, 0) * 100) - } - } - } - skuParam.Upc = &upc - skuParam.Unit = unit - skuParam.SpecQuality = specQuality - skuParam.Price = price - skuParam.Name = name - skuParams = append(skuParams, skuParam) - } - case 1: - taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - var ( - v = batchItemList[0].(*model.SkuName) - skuNames []model.SkuName - skuName = &model.SkuNameExt{ - SkuName: model.SkuName{}, - Skus: []*model.SkuWithVendor{ - &model.SkuWithVendor{ - Sku: &model.Sku{}, - }, - }, - } - ) - if v.Upc != nil { - upc := upcRegexp.FindString(*v.Upc) - if upc == "" { - retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, "请输入正确的商品条码!")} - return retVal, err - } - skuName.Upc = v.Upc - } else { - retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, "商品的条码不能为空!")} - return retVal, err - } - sql := ` - SELECT * FROM sku_name WHERE upc = ? AND deleted_at = ? - ` - sqlParams := []interface{}{*v.Upc, utils.DefaultTimeValue} - err = dao.GetRows(db, &skuNames, sql, sqlParams) - if len(skuNames) > 0 { - retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, "商品在京西库中已存在!")} - return retVal, err - } - productInfos, err := GetJdUpcCodeByCode(ctx, *v.Upc) - if err != nil { - retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, err.Error())} - return retVal, err - } - if len(productInfos) == 0 { - var result *aliupcapi.GetAliUpcInfoResult - upcDepot, err := dao.GetUpcDepot(db, *v.Upc) - if upcDepot == nil { - result, err = api.AliUpcAPI.GetAliUpcInfo(*v.Upc) - if err == nil { - err = dao.InsertUpcDepot(db, result) - } - } else { - result = upcDepot - } - if result == nil { - retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, "未在标品库查到此商品,请手动创建!")} - return retVal, err - } - if result.Img != "" { - downloadURL, err := uploadImgStandard(skuName.Img) - if err != nil { - retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, err.Error())} - return retVal, err - } - skuName.Img = downloadURL - // if resBinary, _, err := jxutils.DownloadFileByURL(result.Img); err == nil { - // if downloadURL, err := jxutils.UploadExportContent(resBinary, utils.Int64ToStr(time.Now().Unix())+"origin"+result.Img[strings.LastIndex(result.Img, "/")+1:len(result.Img)]); err == nil { - // resBinary2, _, err := jxutils.DownloadFileByURL(downloadURL + model.SkuNameImgStandard) - // downloadURL2, err := jxutils.UploadExportContent(resBinary2, utils.Int64ToStr(time.Now().Unix())+downloadURL[strings.LastIndex(downloadURL, "/")+1:len(downloadURL)]) - // if err == nil { - // skuName.Img = downloadURL2 - // } else { - // retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, err.Error())} - // return retVal, err - // } - // } else { - // retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, err.Error())} - // return retVal, err - // } - // } else { - // retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, err.Error())} - // return retVal, err - // } - } else { - skuName.Img = model.NOSkuNameImg - } - if v.Name != "" { - skuName.Name = v.Name - } else { - skuName.Name = result.GoodsName - } - if v.Price == 0 { - if result.Price == "" { - retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, "未查询到商品售价,请补充商品的售价!")} - return retVal, err - } else { - skuName.Price = int(utils.Str2Int64(result.Price) * 100) - } - } else { - skuName.Price = v.Price - } - getNetUpcInfo, err := api.AliUpcAPI.GetNetUpcInfo(*v.Upc) - if v.Unit != "" { - if v.Unit == model.UnitNames[0] { - retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, "标品的单位不能为份!")} - return retVal, err - } - skuName.Unit = v.Unit - } else { - if getNetUpcInfo.Unit != "" { - skuName.Unit = getNetUpcInfo.Unit - } else { - retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, "未查询到商品单位,请补充商品单位!")} - return retVal, err - } - } - if v.SpecQuality != 0 { - skuName.Skus[0].SpecQuality = v.SpecQuality - skuName.Skus[0].Weight = utils.Float32ToInt(v.SpecQuality) - skuName.Skus[0].SpecUnit = model.SpecUnitNames[0] - } else { - _, _, _, specUnit, _, specQuality := jxutils.SplitSkuName(v.Name) - if specQuality != 0 { - skuName.Skus[0].SpecQuality = specQuality - if specUnit == model.SpecUnitNames[1] || specUnit == model.SpecUnitNames[2] { - skuName.Skus[0].Weight = int(utils.Str2Int64(utils.Float64ToStr(float64(specQuality) * 1000))) - } else { - skuName.Skus[0].Weight = utils.Float32ToInt(specQuality) - } - } else { - if getNetUpcInfo.SpecQuality != 0 { - if getNetUpcInfo.SpecUnit == model.SpecUnitNames[1] || getNetUpcInfo.SpecUnit == model.SpecUnitNames[2] || - getNetUpcInfo.SpecUnit == "KG" || getNetUpcInfo.SpecUnit == "l" { - skuName.Skus[0].Weight = int(utils.Str2Int64(utils.Float64ToStr(float64(getNetUpcInfo.SpecQuality) * 1000))) - } else { - skuName.Skus[0].Weight = utils.Float32ToInt(getNetUpcInfo.SpecQuality) - } - skuName.Skus[0].SpecQuality = getNetUpcInfo.SpecQuality - } else { - retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, "未查询到商品重量,请补充商品重量!")} - return retVal, err - } - } - if getNetUpcInfo.SpecUnit != "" { - skuName.Skus[0].SpecUnit = getNetUpcInfo.SpecUnit - } else { - skuName.Skus[0].SpecUnit = model.SpecUnitNames[0] - } - } - } else { - productInfo := productInfos[0] - if productInfo.Name == "" { - if v.Name != "" { - productInfo.Name = v.Name - } else { - retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, "需要填上一个合适的商品名!")} - return retVal, err - } - } - skuNames2, _ := dao.GetSkuNames(db, nil, nil, productInfo.Name, false) - if len(skuNames2) > 1 { - retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, "此商品名在京西库中查询出了大于1个商品!")} - return retVal, err - } - //表示查到了,需要把upc更新上去,没查到就要新建 - if len(skuNames2) == 1 && (productInfo.SpecQuality == skuNames2[0].SpecQuality && productInfo.SpecUnit == skuNames2[0].SpecUnit) { - skuNames2[0].Upc = v.Upc - dao.UpdateEntity(db, skuNames2[0], "Upc") - return retVal, err - } else { - if v.Price == 0 { - result, err := api.AliUpcAPI.GetAliUpcInfo(*v.Upc) - if err != nil { - retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, err.Error())} - return retVal, err - } - if result.Price == "" { - retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, "未查询到商品售价,请补充商品售价!")} - return retVal, err - } else { - skuName.Price = int(utils.Str2Int64(result.Price) * 100) - } - } else { - skuName.Price = v.Price - } - skuName.Name = productInfo.Name - getNetUpcInfo, err := api.AliUpcAPI.GetNetUpcInfo(*v.Upc) - if v.Unit != "" { - skuName.Unit = v.Unit - } else { - if productInfo.Unit == "" { - if getNetUpcInfo.Unit != "" { - skuName.Unit = getNetUpcInfo.Unit - } else { - retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, "未查询到商品单位,请补充商品单位!")} - return retVal, err - } - } else { - skuName.Unit = productInfo.Unit - } - } - if v.SpecQuality != 0 { - skuName.Skus[0].SpecQuality = v.SpecQuality - skuName.Skus[0].Weight = utils.Float32ToInt(v.SpecQuality) - skuName.Skus[0].SpecUnit = model.SpecUnitNames[0] - } else { - _, _, _, specUnit, _, specQuality := jxutils.SplitSkuName(v.Name) - if specQuality != 0 { - skuName.Skus[0].SpecQuality = specQuality - if specUnit == model.SpecUnitNames[1] || specUnit == model.SpecUnitNames[2] { - skuName.Skus[0].Weight = int(utils.Str2Int64(utils.Float64ToStr(float64(specQuality) * 1000))) - } else { - skuName.Skus[0].Weight = utils.Float32ToInt(specQuality) - } - } else { - if productInfo.SpecQuality == 0 { - if getNetUpcInfo.SpecQuality != 0 { - if getNetUpcInfo.SpecUnit == model.SpecUnitNames[1] || getNetUpcInfo.SpecUnit == model.SpecUnitNames[2] || - getNetUpcInfo.SpecUnit == "KG" || getNetUpcInfo.SpecUnit == "l" { - skuName.Skus[0].Weight = int(utils.Str2Int64(utils.Float64ToStr(float64(getNetUpcInfo.SpecQuality) * 1000))) - } else { - skuName.Skus[0].Weight = utils.Float32ToInt(getNetUpcInfo.SpecQuality) - } - skuName.Skus[0].SpecQuality = getNetUpcInfo.SpecQuality - } else { - retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, "未查询到商品重量,请补充商品重量!")} - return retVal, err - } - } else { - if productInfo.Weight != 0 { - skuName.Skus[0].Weight = int(utils.Str2Int64(utils.Float64ToStr(float64(productInfo.Weight)))) - } else { - skuName.Skus[0].Weight = utils.Float32ToInt(v.SpecQuality) - } - skuName.Skus[0].SpecQuality = productInfo.SpecQuality - } - } - if productInfo.SpecUnit == "" { - if getNetUpcInfo.SpecUnit != "" { - skuName.Skus[0].SpecUnit = getNetUpcInfo.SpecUnit - } else { - skuName.Skus[0].SpecUnit = model.SpecUnitNames[0] - } - } else { - skuName.Skus[0].SpecUnit = productInfo.SpecUnit - } - } - if len(productInfo.ImgList) > 0 { - skuName.Img = productInfo.ImgList[0] - } else { - skuName.Img = model.NOSkuNameImg - } - } - } - if skuName.Img == "" { - retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, "未查询到商品图片,请联系开发!")} - return retVal, err - } - suffix := skuName.Img[strings.LastIndex(skuName.Img, "."):] - if suffix != ".jpg" && suffix != ".png" && suffix != ".jpeg" && suffix != ".gif" { - retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, fmt.Sprintf("暂不支持的图片格式:[%v]", skuName.Img))} - return retVal, err - } - //需要把图片传到七牛云上 - if !strings.Contains(skuName.Img, "image.jxc4.com") { - downloadURL, err := uploadImgStandard(skuName.Img) - if err != nil { - retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, err.Error())} - return retVal, err - } - skuName.Img = downloadURL - // if resBinary, _, err := jxutils.DownloadFileByURL(skuName.Img); err == nil { - // if downloadURL, err := jxutils.UploadExportContent(resBinary, utils.Int64ToStr(time.Now().Unix())+"origin"+skuName.Img[strings.LastIndex(skuName.Img, "/")+1:len(skuName.Img)]); err == nil { - // if img, _, err := datares.Binary2Image(resBinary, http.DetectContentType(resBinary)); err == nil { - // if img.Bounds().Dx() != datares.MainImgWidth || img.Bounds().Dy() != datares.MainImgHeight { - // if resBinary2, _, err := jxutils.DownloadFileByURL(downloadURL + model.SkuNameImgStandard); err == nil { - // if downloadURL2, err := jxutils.UploadExportContent(resBinary2, utils.Int64ToStr(time.Now().Unix())+skuName.Img[strings.LastIndex(skuName.Img, "/")+1:len(skuName.Img)]); err == nil { - // skuName.Img = downloadURL2 - // } else { - // retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, err.Error())} - // return retVal, err - // } - // } else { - // retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, err.Error())} - // return retVal, err - // } - // } else { - // skuName.Img = downloadURL - // } - // } else { - // retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, err.Error())} - // return retVal, err - // } - // } else { - // retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, err.Error())} - // return retVal, err - // } - // } else { - // retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, err.Error())} - // return retVal, err - // } - } - skuName.Status = model.SkuStatusNormal - skuName.IsGlobal = model.YES - if categoryID == 0 { - skuName.CategoryID = model.NoCatCatgoryID - } else { - skuName.CategoryID = categoryID - } - skuName.Skus[0].Status = model.SkuStatusNormal - _, err = AddSkuName(ctx, skuName, ctx.GetUserName()) - if err != nil { - retVal = []*CreateUpcSkuByExcelErr{buildCreateUpcSkuByExcelErr(v, err.Error())} - return retVal, err - } - return retVal, err - } - taskParallel := tasksch.NewParallelTask("创建标品中", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, taskFunc, skuParams) - tasksch.HandleTask(taskParallel, task, true).Run() - createUpcSkuByExcelErrListInterface, err = taskParallel.GetResult(0) - case 2: - if len(createUpcSkuByExcelErrListInterface) > 0 { - for _, v := range createUpcSkuByExcelErrListInterface { - createUpcSkuByExcelErrList = append(createUpcSkuByExcelErrList, v.(*CreateUpcSkuByExcelErr)) - } - if len(createUpcSkuByExcelErrList) > 0 { - err = writeToExcel(excelTitle, createUpcSkuByExcelErrList, ctx) - } - } - } - return result2, err - } - taskSeq := tasksch.NewSeqTask2("根据excel创建标品-序列任务", ctx, true, taskSeqFunc, 3) - tasksch.HandleTask(taskSeq, nil, true).Run() - hint = taskSeq.GetID() - return hint, err -} - -func writeToExcel(excelTitle []string, dataList interface{}, ctx *jxcontext.Context) (err error) { - var sheetList []*excel.Obj2ExcelSheetConfig - var downloadURL, fileName string - excelConf := &excel.Obj2ExcelSheetConfig{ - Title: "sheet1", - Data: dataList, - CaptionList: excelTitle, - } - sheetList = append(sheetList, excelConf) - if excelConf != nil { - downloadURL, fileName, err = jxutils.UploadExeclAndPushMsg(sheetList, "创建标品错误") - } else { - baseapi.SugarLogger.Debug("WriteToExcel: dataSuccess is nil!") - } - if err != nil { - baseapi.SugarLogger.Errorf("WriteToExcel:upload %s , %s failed error:%v", fileName, err) - } else { - noticeMsg := fmt.Sprintf("[详情点我]%s/billshow/?normal=true&path=%s \n", globals.BackstageHost, downloadURL) - ddmsg.SendUserMessage(dingdingapi.MsgTyeText, ctx.GetUserID(), "异步任务完成", noticeMsg) - baseapi.SugarLogger.Debug("WriteToExcel: dataSuccess downloadURL: [%v]", downloadURL) - } - return err -} - -//恢复京东回收站,修改京西的京东id -func RefreshJdDepot(ctx *jxcontext.Context) (err error) { - var ( - pageSize = 20 - searchResults []*jdapi.SearchDeleteWareResult - db = dao.GetDB() - // pageList []int - // skuIDs []int - ) - for page := 1; page < 2; page++ { - searchDeleteWareResults, err := api.JdAPI.SearchDeleteWare("2020-04-22", "2020-04-22", page, pageSize) - if err == nil && len(searchDeleteWareResults) > 0 { - searchResults = append(searchResults, searchDeleteWareResults...) - } - } - - for _, v := range searchResults { - param := &jdapi.OpSkuParam{ - TraceID: ctx.GetTrackInfo(), - OutSkuID: utils.Int2Str(v.SkuID), - FixedStatus: jdapi.SkuFixedStatusDeleted, - } - time.Sleep(time.Second * 1) - _, err = api.JdAPI.UpdateSku2(param) - if err != nil { - globals.SugarLogger.Debugf("RefreshJdDepot UpdateSku2", err.Error()) - continue - } - api.JdAPI.RefreshJdDepot(v.JdID) - sql := ` - UPDATE thing_map SET vendor_thing_id = ?, sync_status = ?, updated_at = NOW() - WHERE thing_type = ? AND vendor_id = ? AND vendor_org_code = ? AND deleted_at = ? AND thing_id = ? - ` - sqlParams := []interface{}{v.JdID, model.SyncFlagModifiedMask, model.ThingTypeSku, model.VendorIDJD, "320406", utils.DefaultTimeValue, v.SkuID} - dao.ExecuteSQL(db, sql, sqlParams) - _, err = SyncSkus(ctx, nil, []int{0}, []string{"320406"}, nil, []int{v.SkuID}, false) - time.Sleep(time.Second * 1) - // skuIDs = append(skuIDs, v.SkuID) - } - return err -} - -//标准化上传图片。 -//图片是非京西图片上传到七牛云转换为京西图片 -func uploadImgStandard(imgUrl string) (downloadResult string, err error) { - if resBinary, _, err := jxutils.DownloadFileByURL(imgUrl); err == nil { - if downloadURL, err := jxutils.UploadExportContent(resBinary, utils.Int64ToStr(time.Now().Unix())+"origin"+imgUrl[strings.LastIndex(imgUrl, "/")+1:len(imgUrl)]); err == nil { - if img, _, err := datares.Binary2Image(resBinary, http.DetectContentType(resBinary)); err == nil { - if img.Bounds().Dx() != datares.MainImgWidth || img.Bounds().Dy() != datares.MainImgHeight { //如果不是标准的800x800就再把图片格式化上传 - if resBinary2, _, err := jxutils.DownloadFileByURL(downloadURL + model.SkuNameImgStandard); err == nil { - if downloadURL2, err := jxutils.UploadExportContent(resBinary2, utils.Int64ToStr(time.Now().Unix())+imgUrl[strings.LastIndex(imgUrl, "/")+1:len(imgUrl)]); err == nil { - downloadResult = downloadURL2 - } else { - return downloadResult, err - } - } else { - return downloadResult, err - } - } else { - downloadResult = downloadURL - } - } else { - return downloadResult, err - } - } else { - return downloadResult, err - } - } else { - return downloadResult, err - } - return downloadResult, err -} - -func AddSkuNameByUpc(ctx *jxcontext.Context, upc string, store *dao.StoreDetail, v *partner.SkuNameInfo) (err error) { - var ( - db = dao.GetDB() - // skuBindInfos []*StoreSkuBindInfo - ) - skuNames, err := dao.GetSkuNames(db, nil, []string{upc}, "", false) - if err != nil { - return err - } - //表示我们商品库中没有这个upc商品,如果有就直接关注上 - if len(skuNames) == 0 { - skuNameExt := &model.SkuNameExt{ - SkuName: model.SkuName{ - Upc: &upc, - Status: model.SkuStatusNormal, - CategoryID: model.NoCatCatgoryID, - IsGlobal: model.YES, - Price: int(v.SkuList[0].VendorPrice), - }, - Skus: []*model.SkuWithVendor{ - &model.SkuWithVendor{ - Sku: &model.Sku{ - Status: model.SkuStatusNormal, - }, - }, - }, - } - //我们商品库中有这个商品,但是upc没有填,则尝试用upc去查一下 - productInfos, err2 := GetJdUpcCodeByName(ctx, "", upc) - getNetUpcInfo, err2 := api.AliUpcAPI.GetNetUpcInfo(upc) - err = err2 - //表示用upc也没有找到这个商品 - if len(productInfos) == 0 { - if getNetUpcInfo == nil || getNetUpcInfo.SpecQuality == 0 || getNetUpcInfo.Unit == "" { - return fmt.Errorf("此商品无规格无法创建,upc :[%s] , unit: [%s], specQuality : [%v]", upc, getNetUpcInfo.Unit, getNetUpcInfo.SpecQuality) - } - if len(v.PictureList) > 0 { - skuNameExt.Img = v.PictureList[0] - } else { - img := getImgFromNet(db, upc) - if img != "" { - skuNameExt.Img = img - } else { - skuNameExt.Img = model.NOSkuNameImg - } - } - if skuNameExt.Name == "" { - skuNameExt.Name = v.SkuList[0].SkuName - } else { - skuNameExt.Name = v.Name - } - skuNameExt.Name = v.Name - skuNameExt.Unit = getNetUpcInfo.Unit - skuNameExt.Skus[0].SpecQuality = getNetUpcInfo.SpecQuality - skuNameExt.Skus[0].SpecUnit = getNetUpcInfo.SpecUnit - skuNameExt.Skus[0].Weight = utils.Float32ToInt(getNetUpcInfo.SpecQuality) - } else { - productInfo := productInfos[0] - if (productInfo.SpecQuality == 0 || productInfo.Unit == "") && (getNetUpcInfo == nil || getNetUpcInfo.SpecQuality == 0 || getNetUpcInfo.Unit == "") { - return fmt.Errorf("此商品无规格无法创建,upc :[%s] , unit: [%s], specQuality : [%v]", upc, getNetUpcInfo.Unit, getNetUpcInfo.SpecQuality) - } - if productInfo.SpecQuality == 0 { - skuNameExt.Skus[0].SpecQuality = getNetUpcInfo.SpecQuality - skuNameExt.Skus[0].Weight = utils.Float32ToInt(getNetUpcInfo.SpecQuality) - } else { - skuNameExt.Skus[0].SpecQuality = productInfo.SpecQuality - skuNameExt.Skus[0].Weight = utils.Float32ToInt(productInfo.SpecQuality) - } - if productInfo.SpecUnit == "" { - skuNameExt.Skus[0].SpecUnit = getNetUpcInfo.SpecUnit - } else { - skuNameExt.Skus[0].SpecUnit = productInfo.SpecUnit - } - if len(productInfo.ImgList) > 0 { - skuNameExt.Img = productInfo.ImgList[0] - } else { - img := getImgFromNet(db, upc) - if img != "" { - skuNameExt.Img = img - } else { - skuNameExt.Img = model.NOSkuNameImg - } - } - if productInfo.Name == "" { - if v.Name == "" { - skuNameExt.Name = v.SkuList[0].SkuName - } else { - skuNameExt.Name = v.Name - } - } else { - skuNameExt.Name = productInfo.Name - } - if productInfo.Unit == "" { - skuNameExt.Unit = getNetUpcInfo.Unit - } else { - skuNameExt.Unit = productInfo.Unit - } - } - if flag := checkAndUpdateUpc(ctx, db, skuNameExt, v, store); !flag { - if !strings.Contains(skuNameExt.Img, "image.jxc4.com") { - downloadURL, err := uploadImgStandard(skuNameExt.Img) - if err != nil { - skuNameExt.Img = model.NOSkuNameImg - } else { - skuNameExt.Img = downloadURL - } - } - if resBinary, _, err := jxutils.DownloadFileByURL(skuNameExt.Img); err == nil { - if model.ValidMimeTypes[http.DetectContentType(resBinary)] == 0 { - skuNameExt.Img = model.NOSkuNameImg - } - } - if skuNameExt.Skus[0].SpecUnit == model.SpecUnitNames[1] || skuNameExt.Skus[0].SpecUnit == model.SpecUnitNames[2] || - skuNameExt.Skus[0].SpecUnit == "KG" || skuNameExt.Skus[0].SpecUnit == "l" { - skuNameExt.Skus[0].Weight = skuNameExt.Skus[0].Weight * 1000 - } - outSkuNameExt, err := AddSkuName(ctx, skuNameExt, ctx.GetUserName()) - if err != nil { - return err - } - // skuBindInfo := &StoreSkuBindInfo{ - // NameID: outSkuNameExt.SkuName.ID, - // IsFocus: 1, - // UnitPrice: outSkuNameExt.SkuName.Price, - // } - // skuBindInfos = append(skuBindInfos, skuBindInfo) - // updateStoresSkusWithoutSync(ctx, db, []int{store.ID}, skuBindInfos, false) - buildStoreSkuBindInfosAndFocus(ctx, db, store, v, outSkuNameExt.ID) - } - } else { - // skuBindInfo := &StoreSkuBindInfo{ - // NameID: skuNames[0].ID, - // IsFocus: 1, - // UnitPrice: skuNames[0].Price, - // } - // skuBindInfos = append(skuBindInfos, skuBindInfo) - // updateStoresSkusWithoutSync(ctx, db, []int{store.ID}, skuBindInfos, false) - buildStoreSkuBindInfosAndFocus(ctx, db, store, v, skuNames[0].ID) - } - return err -} - -//该商品名,规格在库中能查询出则更新upc不插入 -func checkAndUpdateUpc(ctx *jxcontext.Context, db *dao.DaoDB, skuNameExt *model.SkuNameExt, v *partner.SkuNameInfo, store *dao.StoreDetail) (flag bool) { - skuNames2, err := dao.GetSkuNames(db, nil, nil, skuNameExt.Name, false) - if err != nil { - return false - } - if len(skuNames2) == 0 { - return false - } - //表示查到了,需要把upc更新上去,没查到就要新建 - if skuNameExt.SpecQuality == skuNames2[0].SpecQuality { - skuNames2[0].Upc = skuNameExt.Upc - dao.UpdateEntity(db, skuNames2[0], "Upc") - // var skuBindInfos []*StoreSkuBindInfo - // skuBindInfo := &StoreSkuBindInfo{ - // NameID: skuNames2[0].ID, - // IsFocus: 1, - // UnitPrice: skuNames2[0].Price, - // } - // skuBindInfos = append(skuBindInfos, skuBindInfo) - // updateStoresSkusWithoutSync(ctx, db, []int{store.ID}, skuBindInfos, false) - buildStoreSkuBindInfosAndFocus(ctx, db, store, v, skuNames2[0].ID) - return true - } - return false -} - -func getImgFromNet(db *dao.DaoDB, upc string) (img string) { - var result *aliupcapi.GetAliUpcInfoResult - upcDepot, err := dao.GetUpcDepot(db, upc) - if upcDepot == nil { - result, err = api.AliUpcAPI.GetAliUpcInfo(upc) - if err == nil { - err = dao.InsertUpcDepot(db, result) - } - } else { - result = upcDepot - } - img = result.Img - return img -} - -func deleteJdsSku(db *dao.DaoDB, skuID int) (err error) { - storeBinds, err := dao.GetStoresSkusInfo(db, []int{model.JdShopMainStoreID}, []int{skuID}) - if err == nil && len(storeBinds) > 0 { - err = api.JdShopAPI.DeleteSku(storeBinds[0].JdsID) - } - return err -} - -func UpdateSkuExinfoMap(ctx *jxcontext.Context, nameIDs []int, imgWaterMark string, vendorID int, exPrefix, fromTime, toTime string, isAsync, isContinueWhenError bool) (hint string, err error) { - var ( - fromTimeP time.Time - toTimeP time.Time - db = dao.GetDB() - // skuIDs []int - ) - if fromTime != "" { - fromTimeP = utils.Time2Date(utils.Str2Time(fromTime)) - } - if toTime != "" { - toTimeP = utils.Time2Date(utils.Str2Time(toTime)) - } - if toTimeP.Before(fromTimeP) { - return "", fmt.Errorf("结束时间不可以小于开始时间!开始时间:[%v],结束时间:[%v]", fromTimeP, toTimeP) - } - task := tasksch.NewParallelTask("刷新商品前缀水印图", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - nameID := batchItemList[0].(int) - skuEx := &model.SkuExinfoMap{ - NameID: nameID, - ImgWatermark: imgWaterMark, - ExPrefix: exPrefix, - VendorID: vendorID, - BeginAt: fromTimeP, - EndAt: toTimeP, - } - dao.WrapAddIDCULDEntity(skuEx, ctx.GetUserName()) - skuExs, _ := dao.GetSkuExinfos(db, []int{nameID}, []int{vendorID}, "", utils.ZeroTimeValue, utils.ZeroTimeValue) - if len(skuExs) > 0 { - skuEx2 := skuExs[0] - skuEx2.DeletedAt = time.Now() - skuEx2.LastOperator = ctx.GetUserName() - dao.UpdateEntity(db, skuEx2, "DeletedAt", "LastOperator") - dao.CreateEntity(db, skuEx) - } else { - dao.CreateEntity(db, skuEx) - } - now := utils.Time2Date(time.Now()) - if now.Sub(fromTimeP) >= 0 && now.Sub(toTimeP) <= 0 { - var skuIDs []int - skuList, err2 := dao.GetSkus(db, nil, []int{nameID}, nil, nil, nil) - if err = err2; err == nil { - if len(skuList) > 0 { - for _, v := range skuList { - skuIDs = append(skuIDs, v.ID) - } - if partner.IsMultiStore(vendorID) { - for _, v := range skuIDs { - OnUpdateThing(ctx, db, nil, int64(v), model.ThingTypeSku) - } - } else { - SetStoreSkuSyncStatus2(db, nil, []int{vendorID}, skuIDs, model.SyncFlagModifiedMask) - } - } - } - } - return retVal, err - }, nameIDs) - tasksch.HandleTask(task, nil, true).Run() - if isAsync { - hint = task.GetID() - } else { - _, err = task.GetResult(0) - hint = "1" - } - return hint, err -} diff --git a/business/jxstore/cms/store.go b/business/jxstore/cms/store.go deleted file mode 100644 index b823d2076..000000000 --- a/business/jxstore/cms/store.go +++ /dev/null @@ -1,3758 +0,0 @@ -package cms - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "io" - "math" - "mime/multipart" - "sort" - "strconv" - "strings" - "time" - "unicode/utf8" - - "git.rosy.net.cn/jx-callback/business/authz" - - "git.rosy.net.cn/baseapi/platformapi/yinbaoapi" - - "git.rosy.net.cn/jx-callback/globals/refutil" - - "github.com/360EntSecGroup-Skylar/excelize" - - "git.rosy.net.cn/baseapi" - "git.rosy.net.cn/jx-callback/business/authz/autils" - "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" - - "git.rosy.net.cn/baseapi/platformapi/autonavi" - "git.rosy.net.cn/baseapi/platformapi/baidunavi" - "git.rosy.net.cn/baseapi/platformapi/dingdingapi" - "git.rosy.net.cn/baseapi/platformapi/jdapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/baseapi/utils/errlist" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/ddmsg" - "git.rosy.net.cn/jx-callback/business/jxutils/excel" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/msg" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/model/legacymodel" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/business/partner/purchase/ebai" - "git.rosy.net.cn/jx-callback/business/partner/purchase/jd" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -const ( - GET_BAD_COMMENTS_TYPE = 0 //获取差评的标志 - GET_ALL_COMMENTS_TYPE = 1 //获取所有评论的标志 - GET_FIXED_COMMENTS_TYPE = 2 //获取已解决评论的标志 -) - -type StoreExt struct { - model.Store - - MarketManName string `orm:"size(8)" json:"marketManName"` // 市场负责人姓名 - OperatorName string `orm:"size(8)" json:"operatorName"` // 京东运营人姓名 - OperatorName2 string `orm:"size(8)" json:"operatorName2"` // 美团运营人姓名 - OperatorName3 string `orm:"size(8)" json:"operatorName3"` // 饿百运营人姓名 - - FloatLng float64 `json:"lng"` - FloatLat float64 `json:"lat"` - - ProvinceCode int `json:"provinceCode"` - ProvinceName string `json:"provinceName"` - CityName string `json:"cityName"` - DistrictName string `json:"districtName"` - StoreMapStr string `json:"-"` - CourierMapStr string `json:"-"` - PayeeBankName string `json:"payeeBankName"` // 开户行名称 - LinkStoreCount int `json:"linkStoreCount"` - // StoreMaps []map[string]interface{} `orm:"-"` - // CourierMaps []map[string]interface{} `orm:"-"` - StoreMaps []*model.StoreMap `json:"StoreMaps"` - CourierMaps []*model.StoreCourierMap `json:"CourierMaps"` - - OrderCount int `json:"orderCount"` -} - -type StoresInfo struct { - TotalCount int `json:"totalCount"` - MapCenterLng float64 `json:"mapCenterLng"` - MapCenterLat float64 `json:"mapCenterLat"` - Stores []*StoreExt `json:"stores"` -} - -type JxBadCommentsExt struct { - legacymodel.JxBadComments - StoreName string `json:"storeName"` - CityName string `json:"cityName"` - - VendorOrderID2 string `orm:"column(vendor_order_id2);size(48);index" json:"vendorOrderID2"` -} - -type VendorStoreExcel struct { - StoreID int `json:"门店ID"` - VendorStoreName string `json:"门店名"` - Status string `json:"营业状态"` - Tel1 string `json:"电话1"` - Tel2 string `json:"电话2"` - CityName string `json:"城市名"` - Address string `json:"地址"` - MarketManName string `json:"市场负责人"` - OperatorName string `json:"运营负责人"` - OperatorName2 string `json:"运营负责人2"` - OperatorName3 string `json:"运营负责人3"` -} - -type JdStoreLevelExt struct { - Level string `json:"level` - PageNo int `json:"pageNo"` -} - -var ( - ErrMissingInput = errors.New("没有有效的输入参数") - ErrCanNotFindVendor = errors.New("vendorID参数不合法") -) - -var ( - storeKeyPropertyMap = map[string]int{ - "name": 1, - "cityCode": 1, - "districtCode": 1, - "address": 1, - "tel1": 1, - "tel2": 1, - "openTime1": 1, - "closeTime1": 1, - "openTime2": 1, - "closeTime2": 1, - "lng": 1, - "lat": 1, - "deliveryRangeType": 1, - "deliveryRange": 1, - "status": 1, - "promoteInfo": 1, - } - - storeMapKeyPropertyMap = map[string]int{ - "status": 1, - "freightDeductionPack": 1, - "vendorStoreName": 1, - "boxFee": 1, - } - - WatchVendorStoreTimeList = []string{ - "9:00:00", - "10:00:00", - "11:00:00", - "15:00:00", - "20:00:00", - } - titleListStore = []string{ - "门店ID", - "门店名", - "营业状态", - "电话1", - "电话2", - "城市名", - "地址", - "市场负责人", - "运营负责人", - "运营负责人2", - } - roleMap = map[string]string{ - // "marketManPhone": "市场负责人电话", - // "marketManRole": "市场负责人组(角色,单人)", - "jxBrandFeeFactor": "京西品牌费因子", - "marketAddFeeFactor": "市场附加费因子", - "payeeName": "收款人姓名", - "payeeAccountNo": "收款账号", - "payeeBankBranchName": "开户支行", - "payeeBankCode": "开户行代码", - "payPercentage": "支付比例", - } - roleMoblieMap = map[string]string{ - "17380734342": "17380734342", //漆云的手机 ,用于判断updatestore的权限 - "18328080405": "18328080405", //肖娜娜的手机 - "13350726500": "13350726500", //谭翔心 - "15928865396": "15928865396", //何佳梦 - "18048531223": "18048531223", //石老板 - "18982250714": "18982250714", //赵敏夫 - } - - marketManPhoneRoleMap = map[string]string{ - "marketManPhone": "市场负责人电话", - } - - marketManPhoneRoleMoblieMap = map[string]string{ - "13684045763": "13684045763", - "18160030913": "18160030913", - "18048531223": "18048531223", - "18328080405": "18328080405", - "17380734342": "17380734342", - "15208271238": "15208271238", - "18583684218": "18583684218", - } -) - -func getStoresSql(ctx *jxcontext.Context, keyword string, params map[string]interface{}, orderTimeFrom, orderTimeTo time.Time) (sql string, sqlParams []interface{}, sqlFrom string, sqlFromParams []interface{}, err error) { - sqlFrom = ` - FROM store t1 - LEFT JOIN new_config bank ON bank.deleted_at = ? AND bank.type = ? AND bank.key = t1.payee_bank_code - LEFT JOIN place city ON t1.city_code = city.code AND city.level = 2 - LEFT JOIN place province ON province.code = city.parent_code AND province.level = 1 - LEFT JOIN place district ON t1.district_code = district.code AND district.level = 3 - /* - LEFT JOIN store_map m1 ON t1.id = m1.store_id AND m1.deleted_at = ? - LEFT JOIN store_courier_map m2 ON t1.id = m2.store_id AND m2.deleted_at = ? - */ - LEFT JOIN user mm ON mm.mobile <> '' AND mm.mobile = t1.market_man_phone AND mm.deleted_at = ? - LEFT JOIN user om ON om.mobile <> '' AND om.mobile = t1.operator_phone AND om.deleted_at = ? - LEFT JOIN user om2 ON om2.mobile <> '' AND om2.mobile = t1.operator_phone2 AND om2.deleted_at = ? - LEFT JOIN user om3 ON om3.mobile <> '' AND om3.mobile = t1.operator_phone3 AND om3.deleted_at = ? - ` - sqlFromParams = []interface{}{ - utils.DefaultTimeValue, - model.ConfigTypeBank, - // utils.DefaultTimeValue, - // utils.DefaultTimeValue, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - } - sqlWhere := ` - WHERE t1.deleted_at = ? - ` - sqlWhereParams := []interface{}{ - utils.DefaultTimeValue, - } - for mapCondKey, tableName := range map[string]string{ - "vendorStoreCond": "store_map", - "courierStoreCond": "store_courier_map", - } { - if mapCond := strings.ToUpper(utils.Interface2String(params[mapCondKey])); mapCond == "AND" || mapCond == "OR" { - mapCondsStr := utils.Interface2String(params[mapCondKey+"s"]) - if mapCondsStr != "" { - var vendorStoreConds map[string]interface{} - if err = utils.UnmarshalUseNumber([]byte(mapCondsStr), &vendorStoreConds); err != nil { - return "", nil, "", nil, err - } - sqlVendorStoreCond := "" - for vendor, cond2 := range vendorStoreConds { - var cond string - if condStr, ok := cond2.(string); !ok { - cond = utils.Int64ToStr(utils.ForceInterface2Int64(cond2)) - } else { - cond = condStr - } - - tableAlias := tableName + vendor - if cond != "0" && cond != "" { - if sqlVendorStoreCond == "" { - if mapCond == "AND" { - sqlVendorStoreCond += " AND ( 1 = 1" - } else { - sqlVendorStoreCond += " AND ( 1 = 0" - } - } - sqlFrom += "\nLEFT JOIN " + tableName + " " + tableAlias + " ON " + tableAlias + ".vendor_id = ? AND " + - tableAlias + ".store_id = t1.id AND " + tableAlias + ".deleted_at = ? AND " + - tableAlias + ".is_sync <> 0 " - sqlFromParams = append(sqlFromParams, vendor, utils.DefaultTimeValue) - if cond == "1" { - sqlVendorStoreCond += " " + mapCond + " " + tableAlias + ".id IS NOT NULL" - } else if cond == "-1" { - sqlVendorStoreCond += " " + mapCond + " " + tableAlias + ".id IS NULL" - } else { - sqlFrom += " AND " + tableAlias + ".vendor_org_code = ?" - sqlFromParams = append(sqlFromParams, cond) - sqlVendorStoreCond += " " + mapCond + " " + tableAlias + ".id IS NOT NULL" - } - } - } - if sqlVendorStoreCond != "" { - sqlWhere += sqlVendorStoreCond + ")" - } - } - } - } - if keyword != "" { - keywordLike := "%" + keyword + "%" - sqlWhere += ` AND (t1.name LIKE ? OR t1.tel1 LIKE ? OR t1.tel2 LIKE ? OR t1.operator_phone LIKE ? OR t1.operator_phone2 LIKE ? OR t1.operator_phone3 LIKE ? OR t1.market_man_phone LIKE ? - OR t1.last_operator LIKE ? OR city.name LIKE ? OR t1.address LIKE ? OR t1.printer_sn LIKE ? OR t1.licence_code LIKE ? OR t1.id_code LIKE ?` - sqlWhereParams = append(sqlWhereParams, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike, - keywordLike, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike) - - if keywordInt64, err2 := strconv.ParseInt(keyword, 10, 64); err2 == nil { - if true { // jxutils.IsLegalMobileNumber(keywordInt64) { - sqlWhere += ` OR ( - SELECT COUNT(*) - FROM casbin_rule t11 - JOIN user t12 ON t12.user_id = t11.v0 AND t12.mobile LIKE ? - WHERE t11.v1 <> '' AND (t11.v1 = CONCAT(?, t1.id) OR t11.v1 = CONCAT(?, t1.market_man_role) OR t11.v1 = CONCAT(?, t1.operator_role) OR t11.v1 = CONCAT(?, t1.operator_role2) OR t11.v1 = CONCAT(?, t1.operator_role3)) - ) > 0` - prefix := autils.NewRole("", 0).GetFullName() - sqlWhereParams = append(sqlWhereParams, keyword+"%", autils.NewStoreBossRole(-1).GetFullName(), prefix, prefix, prefix, prefix) // 必须要前缀,不然不能用过些会很慢 - } - sqlWhere += " OR t1.id = ? OR t1.city_code = ? OR t1.district_code = ? OR t1.link_store_id = ?" - sqlWhereParams = append(sqlWhereParams, keywordInt64, keywordInt64, keywordInt64, keywordInt64) - if jxutils.GuessVendorIDFromVendorStoreID(keywordInt64) != model.VendorIDUnknown { - sqlWhere += ` - OR (SELECT COUNT(*) FROM store_map tsm WHERE t1.id = tsm.store_id AND tsm.deleted_at = ? AND tsm.vendor_store_id = ?) > 0 - OR (SELECT COUNT(*) FROM store_courier_map tsm WHERE t1.id = tsm.store_id AND tsm.deleted_at = ? AND tsm.vendor_store_id = ?) > 0 - ` - sqlWhereParams = append(sqlWhereParams, utils.DefaultTimeValue, keyword, utils.DefaultTimeValue, keyword) - } - } - sqlWhere += ")" - } - - if params["storeID"] != nil || params["storeIDs"] != nil { - var storeIDs []int - if params["storeIDs"] != nil { - if err = jxutils.Strings2Objs(utils.Interface2String(params["storeIDs"]), &storeIDs); err != nil { - return "", nil, "", nil, err - } - } - if params["storeID"] != nil { - storeIDs = append(storeIDs, params["storeID"].(int)) - } - if len(storeIDs) > 0 { - sqlWhere += " AND t1.id IN (" + dao.GenQuestionMarks(len(storeIDs)) + ")" - sqlWhereParams = append(sqlWhereParams, storeIDs) - } - } - if params["startStoreID"] != nil { - sqlWhere += " AND t1.id >= ?" - sqlWhereParams = append(sqlWhereParams, params["startStoreID"]) - } - if params["name"] != nil { - sqlWhere += " AND t1.name LIKE ?" - sqlWhereParams = append(sqlWhereParams, "%"+params["name"].(string)+"%") - } - if params["placeID"] != nil { - level := 2 - if params["placeLevel"] != nil { - level = params["placeLevel"].(int) - } - if level == 2 { - sqlWhere += " AND t1.city_code = ?" - } else { - sqlWhere += " AND t1.district_code = ?" - } - sqlWhereParams = append(sqlWhereParams, params["placeID"].(int)) - } - if params["address"] != nil { - sqlWhere += " AND t1.address LIKE ?" - sqlWhereParams = append(sqlWhereParams, "%"+params["address"].(string)+"%") - } - if params["marketManPhone"] != nil { - sqlWhere += " AND t1.market_man_phone = ?" - sqlWhereParams = append(sqlWhereParams, params["marketManPhone"].(string)) - } - if params["tel"] != nil { - sqlWhere += " AND (t1.tel1 LIKE ? OR t1.tel2 LIKE ?)" - sqlWhereParams = append(sqlWhereParams, "%"+params["tel"].(string)+"%") - sqlWhereParams = append(sqlWhereParams, "%"+params["tel"].(string)+"%") - } - if params["earningType"] != nil { - if params["earningType"].(int) != 0 { - if params["earningType"].(int) == 1 { - sqlWhere += " AND t1.pay_percentage = 100" - } else { - sqlWhere += " AND t1.pay_percentage < 50" - } - } - } - - if params["statuss"] != nil { - var statuss []int - if err = utils.UnmarshalUseNumber([]byte(params["statuss"].(string)), &statuss); err != nil { - return "", nil, "", nil, err - } - if len(statuss) > 0 { - sqlWhere += " AND t1.status IN (" + dao.GenQuestionMarks(len(statuss)) + ")" - sqlWhereParams = append(sqlWhereParams, statuss) - } - } - if params["marketManPhones"] != nil { - var phones []string - if err = utils.UnmarshalUseNumber([]byte(params["marketManPhones"].(string)), &phones); err != nil { - return "", nil, "", nil, err - } - if len(phones) > 0 { - sqlWhere += " AND t1.market_man_phone IN (" + dao.GenQuestionMarks(len(phones)) + ")" - sqlWhereParams = append(sqlWhereParams, phones) - } - } - if params["storeLevels"] != nil { - var storeLevels []string - if err = jxutils.Strings2Objs(utils.Interface2String(params["storeLevels"]), &storeLevels); err != nil { - return "", nil, "", nil, err - } - if len(storeLevels) > 0 { - sqlWhere += " AND t1.store_level IN (" + dao.GenQuestionMarks(len(storeLevels)) + ")" - sqlWhereParams = append(sqlWhereParams, storeLevels) - } - } - - sql = sqlFrom + sqlWhere - sqlParams = append(sqlParams, sqlFromParams...) - sqlParams = append(sqlParams, sqlWhereParams...) - return sql, sqlParams, sqlFrom, sqlFromParams, nil -} - -func setStoreMapInfo(ctx *jxcontext.Context, db *dao.DaoDB, storesInfo *StoresInfo, storeIDs []int, briefLevel int) (err error) { - storeMapList, err := dao.GetStoresMapList(db, nil, storeIDs, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "") - if err != nil { - return err - } - storeCourierList, err := dao.GetStoreCourierList(db, storeIDs, nil, model.StoreStatusAll, model.StoreAuditStatusAll) - if err != nil { - return err - } - - storeMapMap := dao.StoreMapList2Map(storeMapList) - storeCourierMap := dao.StoreCourierList2Map(storeCourierList) - - for _, v := range storesInfo.Stores { - if briefLevel > 0 { - v.DeliveryRange = "" - v.IDCardFront = "" - v.IDCardBack = "" - v.IDCardHand = "" - v.Licence = "" - v.Licence2Image = "" - } - for _, v2 := range storeMapMap[v.ID] { - v.StoreMaps = append(v.StoreMaps, v2) - } - for _, v2 := range storeCourierMap[v.ID] { - v.CourierMaps = append(v.CourierMaps, v2) - } - } - return nil -} - -// todo 门店绑定信息可以考虑以数组形式返回,而不是现在这样 -func GetStores(ctx *jxcontext.Context, keyword string, params map[string]interface{}, offset, pageSize int, orderTimeFrom, orderTimeTo time.Time, orderCountFrom, orderCountTo int) (retVal *StoresInfo, err error) { - briefLevel := int(utils.ForceInterface2Int64(params["briefLevel"])) - sql, sqlParams, _, _, err := getStoresSql(ctx, keyword, params, orderTimeFrom, orderTimeTo) - - if err != nil { - return nil, err - } - sql = ` - SELECT - DISTINCT t1.*, - CAST(t1.lng AS DECIMAL(15,6))/1000000 float_lng, - CAST(t1.lat AS DECIMAL(15,6))/1000000 float_lat, - IF(mm.name <> '', mm.name, mm.user_id2) market_man_name, - bank.value payee_bank_name, - IF(om.name <> '', om.name, om.user_id2) operator_name, - IF(om2.name <> '', om2.name, om2.user_id2) operator_name2, - IF(om3.name <> '', om3.name, om3.user_id2) operator_name3, - province.code province_code, - province.name province_name, - city.name city_name, - district.name district_name, - (SELECT COUNT(*) FROM store t11 WHERE t11.link_store_id = t1.id) link_store_count - ` + sql + ` - ORDER BY t1.id DESC - ` - db := dao.GetDB() - retVal = &StoresInfo{} - - var storeIDs []int - var storeList []*StoreExt - offset = jxutils.FormalizePageOffset(offset) - pageSize = jxutils.FormalizePageSize(pageSize) - mapLimit := false - // globals.SugarLogger.Debug(sql) - // globals.SugarLogger.Debug(utils.Format4Output(sqlParams, false)) - - if err = dao.GetRows(db, &storeList, sql, sqlParams...); err == nil { - // 地图区域限制过滤 - if mapLongitude2, ok := params["mapLongitude"].(string); ok { - var ( - mapLatitude, mapLongitude float64 - mapRadius int - ) - mapLimit = true - mapLongitude = utils.Str2Float64(mapLongitude2) - mapLatitude = utils.Str2Float64(params["mapLatitude"].(string)) - mapRadius = params["mapRadius"].(int) - for _, v := range storeList { - valid := !mapLimit - if mapLimit { - valid = jxutils.EarthDistance(mapLongitude, mapLatitude, v.FloatLng, v.FloatLat)*1000 <= float64(mapRadius) - } - if valid { - retVal.Stores = append(retVal.Stores, v) - } - } - } else { - retVal.Stores = storeList - } - - // 订单情况过滤 - storeList, err = filterStoreByOrderInfo(db, retVal.Stores, orderTimeFrom, orderTimeTo, orderCountFrom, orderCountTo) - if err != nil { - return nil, err - } - - // 分页 - retVal.TotalCount = len(storeList) - retVal.Stores = nil - for i := offset; i < offset+pageSize && i < len(storeList); i++ { - storeIDs = append(storeIDs, storeList[i].ID) - retVal.Stores = append(retVal.Stores, storeList[i]) - } - if len(storeIDs) == 0 { - return retVal, nil - } - - // 导出门店地图标信息时,可能会需要转换门店坐标 - needConver2Baidu := int(utils.Interface2Int64WithDefault(params["coordinateType"], 0)) == model.CoordinateTypeBaiDu - if needConver2Baidu { - task := tasksch.NewParallelTask("坐标转换", tasksch.NewParallelConfig().SetParallelCount(4).SetBatchSize(autonavi.MaxConvertCount), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - var coords []*baidunavi.Coordinate - for _, v := range batchItemList { - store := v.(*StoreExt) - coords = append(coords, &baidunavi.Coordinate{ - Lng: store.FloatLng, - Lat: store.FloatLat, - }) - } - coords, err = api.BaiDuNaviAPI.BatchCoordinateConvert(coords, baidunavi.CoordSysGCJ02, baidunavi.CoordSysBaiDu) - if err == nil { - for k, v := range batchItemList { - store := v.(*StoreExt) - coord := coords[k] - store.FloatLng = coord.Lng - store.FloatLat = coord.Lat - } - } - return retVal, err - }, retVal.Stores) - task.Run() - task.GetResult(0) - } - } else { - return nil, err - } - - if len(retVal.Stores) > 0 { - setStoreMapInfo(ctx, db, retVal, storeIDs, briefLevel) - retVal.MapCenterLng, retVal.MapCenterLat = getMapCenter(retVal.Stores) - } - return retVal, err -} - -func filterStoreByOrderInfo(db *dao.DaoDB, inStores []*StoreExt, orderTimeFrom, orderTimeTo time.Time, orderCountFrom, orderCountTo int) (outStores []*StoreExt, err error) { - if len(inStores) > 0 && !utils.IsTimeZero(orderTimeFrom) { - storeIDs := make([]int, len(inStores)) - for k, v := range inStores { - storeIDs[k] = v.ID - } - orderSaleList, err2 := dao.GetStoresOrderSaleInfo(dao.GetDB(), storeIDs, orderTimeFrom, orderTimeTo, []int{model.OrderStatusFinished}) - if err = err2; err != nil { - return nil, err - } - storeOrderCountMap := make(map[int]int) - for _, v := range orderSaleList { - storeOrderCountMap[v.StoreID] += v.Count - } - - for _, v := range inStores { - orderCount := storeOrderCountMap[v.ID] - if orderCount >= orderCountFrom && orderCount <= orderCountTo { - v.OrderCount = orderCount - outStores = append(outStores, v) - } - } - } else { - outStores = inStores - } - return outStores, err -} - -func getMapCenter(storeList []*StoreExt) (lng, lat float64) { - globals.SugarLogger.Debugf("getMapCenter len(storeList):%d", len(storeList)) - if len(storeList) == 0 { - return 0, 0 - } - - lngAvg := float64(0) - latAvg := float64(0) - storeListLenFloat := float64(len(storeList)) - for _, store := range storeList { - lngAvg += store.FloatLng - latAvg += store.FloatLat - } - lngAvg = lngAvg / storeListLenFloat - latAvg = latAvg / storeListLenFloat - - distAvg := float64(0) - for _, store := range storeList { - distAvg += math.Sqrt((store.FloatLng-lngAvg)*(store.FloatLng-lngAvg) + (store.FloatLat-latAvg)*(store.FloatLat-latAvg)) - } - distAvg = (distAvg / storeListLenFloat) - maxDist := distAvg * 5 - newStoreList := []*StoreExt{} - for _, store := range storeList { - dist := math.Sqrt((store.FloatLng-lngAvg)*(store.FloatLng-lngAvg) + (store.FloatLat-latAvg)*(store.FloatLat-latAvg)) - if dist <= maxDist { - lng += store.FloatLng - lat += store.FloatLat - newStoreList = append(newStoreList, store) - } - } - if len(newStoreList) == len(storeList) { - lng = lng / float64(len(newStoreList)) - lat = lat / float64(len(newStoreList)) - // for _, store := range storeList { - // globals.SugarLogger.Debugf("store:%s, lng:%f, lat:%f", store.Name, store.FloatLng, store.FloatLat) - // } - // globals.SugarLogger.Debugf("lng:%f, lat:%f", lng, lat) - return lng, lat - } - return getMapCenter(newStoreList) -} - -func GetVendorStore(ctx *jxcontext.Context, vendorID int, vendorOrgCode, vendorStoreID string) (retVal *StoreExt, err error) { - if vendorID == model.VendorIDJDShop && vendorStoreID == model.JdShopMainVendorStoreID { - return nil, err - } - if handler := CurVendorSync.GetStoreHandler(vendorID); handler != nil { - result, err2 := handler.ReadStore(ctx, vendorOrgCode, vendorStoreID) - if err = err2; err == nil { - retVal = &StoreExt{ - Store: result.Store, - FloatLng: jxutils.IntCoordinate2Standard(result.Lng), - FloatLat: jxutils.IntCoordinate2Standard(result.Lat), - } - db := dao.GetDB() - if city, err2 := dao.GetPlaceByCode(db, result.CityCode); err2 == nil { - retVal.CityName = city.Name - } - if district, err2 := dao.GetPlaceByCode(db, result.DistrictCode); err2 == nil { - retVal.DistrictName = district.Name - } - if !jxutils.IsLegalStoreID(retVal.ID) { - retVal.ID = 0 - } - return retVal, nil - } - return nil, err - } - return nil, ErrCanNotFindVendor -} - -func isUpdateStoreNeedSync(valid map[string]interface{}) bool { - for k := range valid { - if storeKeyPropertyMap[k] == 1 { - return true - } - } - return false -} - -func checkBankBranch(payeeBankBranchName string) (err error) { - if payeeBankBranchName != "" { - if strings.Index(payeeBankBranchName, "支行") == -1 && strings.Index(payeeBankBranchName, "分行") == -1 { - err = fmt.Errorf("支行信息异常,你可能没有在使用最新的版本,请强制刷新浏览器或联系开发") - } - } - return err -} - -func checkCreateStore(store *model.Store) (err error) { - if store.Lng == 0 || store.Lat == 0 || store.Address == "" { - err = fmt.Errorf("必须设置地址信息") - } - return err -} - -func checkStoreDeliveryRange(deliveryRange string) (err error) { - if deliveryRange != "" { - points := jxutils.CoordinateStr2Points(deliveryRange) - for _, point := range points { - for _, coord := range point { - if coord == 0 || math.IsNaN(coord) { - return fmt.Errorf("坐标点数据非法:%s", deliveryRange) - } - } - } - } - return err -} - -func UpdateStore(ctx *jxcontext.Context, storeID int, payload map[string]interface{}, userName string) (num int64, err error) { - globals.SugarLogger.Debugf("UpdateStore storeID:%d, payload:%s", storeID, utils.Format4Output(payload, true)) - if err = checkBankBranch(utils.Interface2String(payload["payeeBankBranchName"])); err != nil { - return 0, err - } - db := dao.GetDB() - store := &model.Store{} - store.ID = storeID - if err = dao.GetEntity(db, store); err != nil { - return 0, err - } - var outStore *model.Store - var beforStore = *store - if payload["autoEnableAt"] != nil { - payload["autoEnableAt"] = utils.Time2Date(utils.Str2Time(utils.Interface2String(payload["autoEnableAt"]))) - } - valid := dao.StrictMakeMapByStructObject2(payload, store, &outStore, userName) - if err = checkStoreDeliveryRange(utils.Interface2String(valid["deliveryRange"])); err != nil { - return 0, err - } - if globals.EnableWXAuth2 { - if err = dao.ValidateRoles(db, utils.Interface2String(valid["marketManRole"]), utils.Interface2String(valid["operatorRole"]), utils.Interface2String(valid["operatorRole2"])); err != nil { - return 0, err - } - } - if payload["lng"] != nil || payload["lat"] != nil { - intLng := jxutils.StandardCoordinate2Int(utils.Interface2Float64WithDefault(payload["lng"], 0.0)) - intLat := jxutils.StandardCoordinate2Int(utils.Interface2Float64WithDefault(payload["lat"], 0.0)) - if intLng != 0 && intLng != store.Lng { - valid["lng"] = intLng - } - if intLat != 0 && intLat != store.Lng { - valid["lat"] = intLat - } - } - - if valid["originalName"] != nil { - delete(valid, "originalName") - } - if valid["printerBindInfo"] != nil { - delete(valid, "printerBindInfo") - } - syncStatus := model.SyncFlagModifiedMask - if valid["name"] != nil { - valid["name"] = jxutils.FormalizeName(valid["name"].(string)) - store.Name = valid["name"].(string) - syncStatus |= model.SyncFlagStoreName - } - // globals.SugarLogger.Debug(utils.Format4Output(valid, false)) - printerVendorID := int(utils.Interface2Int64WithDefault(valid["printerVendorID"], 0)) - if printerVendorID == 0 { - printerVendorID = store.PrinterVendorID - } - if printerVendorID == model.VendorIDXiaoWM { - delete(valid, "printerKey") - } - // 网络打印机处理 - if valid["printerVendorID"] != nil || valid["printerSN"] != nil || valid["printerKey"] != nil { - if valid["printerVendorID"] == nil { - valid["printerVendorID"] = store.PrinterVendorID - } - if printerVendorID := int(utils.Interface2Int64WithDefault(valid["printerVendorID"], 0)); printerVendorID > 0 { - handler := partner.GetPrinterPlatformFromVendorID(printerVendorID) - if handler == nil { - return 0, fmt.Errorf("不支持的打印机厂商ID:%d", printerVendorID) - } - if valid["printerSN"] == nil { - valid["printerSN"] = store.PrinterSN - } - if valid["printerKey"] == nil { - valid["printerKey"] = store.PrinterKey - } - newID1, newID2, err2 := handler.RegisterPrinter(ctx, valid["printerSN"].(string), valid["printerKey"].(string), store.Name) - if err = err2; err != nil { - return 0, err - } - handler.EmptyPrintList(ctx, newID1, newID2) - if newID1 != "" { - valid["printerSN"] = newID1 - } - if newID2 != "" { - valid["printerKey"] = newID2 - } - } else { - valid["printerVendorID"] = 0 - valid["printerSN"] = "" - valid["printerKey"] = "" - } - valid["printerBindInfo"] = "" - if handler := partner.GetPrinterPlatformFromVendorID(store.PrinterVendorID); handler != nil { - handler.UnregisterPrinter(ctx, store.PrinterSN, store.PrinterKey) - } - } - if valid["soundPercentage"] != nil && valid["printerSN"] != nil { - handler := partner.GetPrinterPlatformFromVendorID(printerVendorID) - if handler == nil { - return 0, fmt.Errorf("不支持的打印机厂商ID:%d", printerVendorID) - } - err = handler.SetSound(ctx, store.PrinterSN, store.PrinterKey, jxutils.TranslateSoundSize(printerVendorID, int(utils.Interface2Int64WithDefault(valid["soundPercentage"], 50)))) - if err != nil { - return 0, err - } - } - if valid["linkStoreID"] != nil { - linkStoreID := int(utils.Interface2Int64WithDefault(valid["linkStoreID"], 0)) - linkStoreID, err = dao.GetRealLinkStoreID(db, linkStoreID) - if err != nil { - return 0, err - } - if err = checkStoreHaveLinkedStore(storeID, linkStoreID); err != nil { - return 0, err - } - valid["linkStoreID"] = linkStoreID - // globals.SugarLogger.Debug(linkStoreID) - } - - // globals.SugarLogger.Debug(utils.Format4Output(valid, false)) - for _, v := range []string{ - "lng", - "lat", - "cityCode", - "address", - "deliveryRange", - } { - if valid[v] != nil { - syncStatus |= model.SyncFlagStoreAddress - break - } - } - status := 0 - if valid["status"] != nil || valid["autoEnableAt"] != nil { - if valid["status"] != nil { - syncStatus |= model.SyncFlagStoreStatus - status = int(utils.Interface2Int64WithDefault(valid["status"], 0)) - if status == model.StoreStatusDisabled { - valid["deliveryRangeType"] = model.DeliveryRangeTypeRadius - valid["deliveryRange"] = "1" - } - } else { - status = store.Status - } - - if status != model.StoreStatusClosed && status != model.StoreStatusHaveRest { - valid["autoEnableAt"] = nil - } else { - if valid["autoEnableAt"] != nil { - status = model.StoreStatusHaveRest - } else { - status = model.StoreStatusClosed - valid["autoEnableAt"] = nil - } - valid["status"] = status - } - } - - if valid["deliveryRange"] != nil { - valid["deliveryRange"] = strings.Trim(valid["deliveryRange"].(string), ";") - } - - //时间校验 - if outStore != nil { - if outStore.OpenTime1 != 0 && outStore.CloseTime1 != 0 { - if err := ValidateStructPartial(outStore, "OpenTime1", "CloseTime1"); err != nil { - return 0, errors.New(fmt.Sprintf("门店营业时间1设置不合法!时间范围1 :[%v] 至 [%v]", outStore.OpenTime1, outStore.CloseTime1)) - } - } - if (outStore.OpenTime1 == 0 && outStore.CloseTime1 != 0) || (outStore.OpenTime1 != 0 && outStore.CloseTime1 == 0) { - return 0, errors.New(fmt.Sprintf("门店营业时间1设置不合法!时间范围1 :[%v] 至 [%v]", outStore.OpenTime1, outStore.CloseTime1)) - } - if outStore.OpenTime2 != 0 && outStore.CloseTime2 != 0 { - if err := ValidateStructPartial(outStore, "OpenTime2", "CloseTime2"); err != nil { - return 0, errors.New(fmt.Sprintf("门店营业时间2设置不合法!时间范围2 :[%v] 至 [%v]", outStore.OpenTime2, outStore.CloseTime2)) - } - } - if (outStore.OpenTime2 == 0 && outStore.CloseTime2 != 0) || (outStore.OpenTime2 != 0 && outStore.CloseTime2 == 0) { - return 0, errors.New(fmt.Sprintf("门店营业时间2设置不合法!时间范围2 :[%v] 至 [%v]", outStore.OpenTime1, outStore.CloseTime1)) - } - if outStore.OpenTime1 != 0 && outStore.CloseTime1 != 0 && outStore.OpenTime2 != 0 && outStore.CloseTime2 != 0 { - if outStore.OpenTime2 < outStore.CloseTime1 { - return 0, errors.New(fmt.Sprintf("门店营业时间设置不合法!第二段营业时间应该在第一段营业时间之后!")) - } - } - if beginAt, endAt := GetTimeMixByInt(outStore.OpenTime1, outStore.CloseTime1, outStore.OpenTime2, outStore.CloseTime2); beginAt != 0 && endAt != 0 { - return 0, errors.New(fmt.Sprintf("两段门店营业时间不可交叉!时间范围1 :[%v] 至 [%v], 时间范围2 :[%v] 至 [%v]", outStore.OpenTime1, outStore.CloseTime1, outStore.OpenTime2, outStore.CloseTime2)) - } - } - - if valid["promoteInfo"] != nil { - valid["promoteInfo"] = strings.ReplaceAll(valid["promoteInfo"].(string), "{phone}", store.Tel1) - } - - for k, _ := range valid { - if roleMap[k] != "" { - if authInfo, err := ctx.GetV2AuthInfo(); err == nil { - if roleMoblieMap[authInfo.Mobile] == "" { - return 0, errors.New(fmt.Sprintf("当前用户 [%v] 无权限修改 [%v] 字段!", authInfo.Name, roleMap[k])) - } - } - } - if marketManPhoneRoleMap[k] != "" { - if authInfo, err := ctx.GetV2AuthInfo(); err == nil { - if marketManPhoneRoleMoblieMap[authInfo.Mobile] == "" { - return 0, errors.New(fmt.Sprintf("当前用户 [%v] 无权限修改 [%v] 字段!", authInfo.Name, roleMap[k])) - } - } - } - } - - // districtCode := 0 - // if valid["districtCode"] != nil { - // districtCode = int(utils.MustInterface2Int64(valid["districtCode"])) - // } - // if districtCode == 0 && store.DistrictCode == 0 { - // if lng == 0 { - // lng = jxutils.IntCoordinate2Standard(store.Lng) - // lat = jxutils.IntCoordinate2Standard(store.Lat) - // } - // valid["districtCode"] = api.AutonaviAPI.GetCoordinateDistrictCode(lng, lat) - // } - globals.SugarLogger.Debugf("UpdateStore track:%s, storeID:%d, valid:%s", ctx.GetTrackInfo(), storeID, utils.Format4Output(valid, true)) - if len(valid) > 0 { - if globals.IsAddEvent { - mapBefore := refutil.FindMapAndStructMixed(valid, beforStore) - err = AddEventDetail(db, ctx, model.OperateUpdate, storeID, model.ThingTypeStore, storeID, BuildDiffData(mapBefore), BuildDiffData(valid)) - } - dao.Begin(db) - defer func() { - dao.Rollback(db) - }() - if num, err = dao.UpdateEntityLogically(db, store, valid, userName, nil); err == nil && num == 1 { - if isUpdateStoreNeedSync(valid) { - dummy := &model.StoreMap{} - kv := make(map[string]interface{}) - if valid["status"] != nil { - if syncStatus&model.SyncFlagStoreStatus != 0 && status == model.StoreStatusOpened { - kv[model.FieldStatus] = status - } - } - _, err2 := dao.UpdateEntityLogicallyAndUpdateSyncStatus(db, dummy, kv, userName, map[string]interface{}{ - model.FieldStoreID: store.ID, - }, model.FieldSyncStatus, syncStatus) - if err = err2; err == nil { - dao.Commit(db) - globals.SugarLogger.Debugf("UpdateStore track:%s, before call SyncStore", ctx.GetTrackInfo()) - _, err = CurVendorSync.SyncStore(ctx, db, -1, store.ID, false, userName) - if valid["tel1"] != nil || valid["tel2"] != nil { - TryAddStoreBossRole4StoreByMobile(ctx, store.ID, []string{utils.Interface2String(valid["tel1"]), utils.Interface2String(valid["tel2"])}) - } - if syncStatus&model.SyncFlagStoreAddress != 0 || valid["tel1"] != nil || valid["payeeName"] != nil { - updateCourierStores(ctx, storeID) - } - } - } else { - dao.Commit(db) - } - notifyStoreOperatorChanged(store.ID, "京东运营", store.OperatorPhone, valid["operatorPhone"]) - notifyStoreOperatorChanged(store.ID, "美团运营", store.OperatorPhone2, valid["operatorPhone2"]) - notifyStoreOperatorChanged(store.ID, "饿百运营", store.OperatorPhone3, valid["operatorPhone3"]) - notifyStoreOperatorChanged(store.ID, "市场", store.MarketManPhone, valid["marketManPhone"]) - if err == nil { - if valid["openTime1"] != 0 || valid["closeTime1"] != 0 || valid["openTime2"] != 0 || valid["closeTime2"] != 0 { - err = CurVendorSync.ChangeStoreSkuSaleStatus(ctx, storeID, true, true) - } - } - } - } else { - globals.SugarLogger.Debugf("UpdateStore track:%s, store:%s", ctx.GetTrackInfo(), utils.Format4Output(store, true)) - } - return num, err -} - -func notifyStoreOperatorChanged(storeID int, operatorRoleName, phone string, newPhone interface{}) { - if phone != "" && newPhone != nil { - db := dao.GetDB() - if user, err := dao.GetUserByID(db, "mobile", phone); err == nil { - curUserName := "" - if newOperator := utils.Interface2String(newPhone); newOperator != "" { - if curUser, err := dao.GetUserByID(db, "mobile", newOperator); err == nil { - curUserName = curUser.GetName() - } - } - ddmsg.SendUserMessage(dingdingapi.MsgTyeText, user.GetID(), fmt.Sprintf("门店%s变更", operatorRoleName), fmt.Sprintf("门店:%d,原%s:%s,变更为:%s", storeID, operatorRoleName, user.GetName(), curUserName)) - } - } -} - -func SetStoreStatus(ctx *jxcontext.Context, storeID, status int) (err error) { - payload := map[string]interface{}{ - "status": status, - } - _, err = UpdateStore(ctx, storeID, payload, ctx.GetUserName()) - return err -} - -func EnableHaveRestStores(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (hint string, err error) { - storeInfo, err := GetStores(ctx, "", map[string]interface{}{ - "statuss": string(utils.MustMarshal([]int{model.StoreStatusHaveRest})), - }, 0, model.UnlimitedPageSize, utils.DefaultTimeValue, utils.DefaultTimeValue, 0, 0) - if err != nil { - return "", err - } - if len(storeInfo.Stores) == 0 { - return "0", nil - } - - task := tasksch.NewParallelTask("EnableHaveRestStores", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - store := batchItemList[0].(*StoreExt) - var autoEnableAt time.Time - if store.AutoEnableAt != nil { - autoEnableAt = *store.AutoEnableAt - } else { - autoEnableAt = utils.Time2Date(time.Now().Add(12 * time.Hour)) // 临时休息,但没有设置恢复营业时间,缺省是第二天 - } - if time.Now().Sub(autoEnableAt) >= -2*time.Hour { - err = SetStoreStatus(ctx, store.ID, model.StoreStatusOpened) - } - return nil, err - }, storeInfo.Stores) - tasksch.ManageTask(task).Run() - if !isAsync { - if _, err = task.GetResult(0); err == nil { - hint = utils.Int2Str(len(storeInfo.Stores)) - } - } else { - hint = task.GetID() - } - return hint, err -} - -func checkStoreHaveLinkedStore(storeID, linkStoreID int) (err error) { - if linkStoreID != 0 { - if storeID == linkStoreID { - err = fmt.Errorf("不能自我关联") - } else { - storeList, err2 := dao.GetStoreLinkStores(dao.GetDB(), storeID) - if err = err2; err == nil { - if len(storeList) > 0 { - var storeInfo []string - for _, v := range storeList { - storeInfo = append(storeInfo, utils.Int2Str(v.ID)) - } - err = fmt.Errorf("门店%d已经被其它门店(%s)关联,不能再关联至其它门店", storeID, strings.Join(storeInfo, ",")) - } - } - } - } - return err -} - -func CreateStore(ctx *jxcontext.Context, storeExt *StoreExt, userName string) (id int, err error) { - globals.SugarLogger.Debugf("CreateStore storeExt:%s", utils.Format4Output(storeExt, false)) - if err = checkBankBranch(storeExt.PayeeBankBranchName); err != nil { - return 0, err - } - store := &storeExt.Store - if store.ID != 0 && !jxutils.IsLegalStoreID(store.ID) { - return 0, fmt.Errorf("ID:%d不是合法的京西门店编号", store.ID) - } - db := dao.GetDB() - if globals.EnableWXAuth2 { - if err = dao.ValidateRoles(db, store.MarketManRole, store.OperatorRole, store.OperatorRole2, store.OperatorRole3); err != nil { - return 0, err - } - } - realLinkStoreID, err := dao.GetRealLinkStoreID(db, storeExt.LinkStoreID) - if err != nil { - return 0, err - } - if err = checkStoreHaveLinkedStore(storeExt.ID, realLinkStoreID); err != nil { - return 0, err - } - storeExt.LinkStoreID = realLinkStoreID - - existingID := store.ID - store.Lng = jxutils.StandardCoordinate2Int(storeExt.FloatLng) - store.Lat = jxutils.StandardCoordinate2Int(storeExt.FloatLat) - if err = checkCreateStore(&storeExt.Store); err != nil { - return 0, err - } - store.Name = jxutils.FormalizeName(store.Name) - store.DeliveryRange = strings.Trim(store.DeliveryRange, ";") - if store.PrinterSN != "" { - handler := partner.GetPrinterPlatformFromVendorID(store.PrinterVendorID) - if handler == nil { - return 0, fmt.Errorf("不支持的打印机厂商ID:%d", store.PrinterVendorID) - } - newID1, newID2, err2 := handler.RegisterPrinter(ctx, store.PrinterSN, store.PrinterKey, store.Name) - if err = err2; err != nil { - return 0, err - } - handler.EmptyPrintList(ctx, newID1, newID2) - if newID1 != "" { - store.PrinterSN = newID1 - } - if newID2 != "" { - store.PrinterKey = newID2 - } - } - dao.WrapAddIDCULDEntity(store, userName) - store.ID = existingID - if err = dao.CreateEntity(db, store); err == nil { - if globals.IsAddEvent { - err = AddEventDetail(db, ctx, model.OperateAdd, store.ID, model.ThingTypeStore, store.ID, "", "") - } - UpdateOrCreateCourierStores(ctx, store.ID, false, false, false) - TryAddStoreBossRole4StoreByMobile(ctx, storeExt.ID, []string{storeExt.Tel1, storeExt.Tel2}) - // InsertStoreCategories(ctx, db, store.ID) - AddStoreVendorMap(ctx, db, model.VendorIDJX, "", store.ID, &model.StoreMap{ - VendorStoreID: utils.Int2Str(store.ID), - AutoPickup: 1, - DeliveryCompetition: 1, - PricePercentage: 100, - IsSync: 1, - Status: model.StoreStatusOpened, - PricePercentagePack: "京西100-100", - VendorID: model.VendorIDJX, - }) - return store.ID, err - } - return 0, err -} - -func GetStoreVendorMaps(ctx *jxcontext.Context, db *dao.DaoDB, storeID int, vendorID int) (storeMaps []*model.StoreMap, err error) { - cond := map[string]interface{}{ - model.FieldStoreID: storeID, - } - if vendorID != -1 { - cond[model.FieldVendorID] = vendorID - } - return storeMaps, dao.GetEntitiesByKV(db, &storeMaps, cond, false) -} - -// todo 需要对字段做有效性检查 -func AddStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, vendorID int, vendorOrgCode string, storeID int, storeMap *model.StoreMap) (outStoreMap *model.StoreMap, err error) { - if storeID == 0 { - return nil, fmt.Errorf("storeID不能为0") - } - if vendorID != model.VendorIDJD && (storeMap.AutoPickup == 0) { - return nil, fmt.Errorf("非京东平台要求必须自动拣货") - } - userName := ctx.GetUserName() - storeMap.StoreID = storeID - storeMap.VendorID = vendorID - storeMap.VendorOrgCode = vendorOrgCode - storeMap.Status = model.StoreStatusOpened - storeMap.DeliveryType = model.StoreDeliveryTypeByStore - storeMap.SyncStatus = 0 - if vendorID != model.VendorIDJX && vendorID != model.VendorIDYB && vendorID != model.VendorIDJDShop { - if storeMap.VendorOrgCode == "" { - return nil, fmt.Errorf("必须指定平台分账号信息") - } - if handler := CurVendorSync.GetStoreHandler(vendorID); handler != nil { - store, err2 := handler.ReadStore(ctx, vendorOrgCode, storeMap.VendorStoreID) - if err = err2; err == nil || storeMap.IsSync == 0 { - if store != nil { - storeMap.DeliveryType = store.DeliveryType - storeMap.Status = store.Status - } - err = nil - storeMap.SyncStatus = model.SyncFlagModifiedMask | model.SyncFlagStoreName | model.SyncFlagStoreAddress // 新增绑定门店是修改的概念 - } - } else { - err = ErrCanNotFindVendor - } - storeDetail, _ := dao.GetStoreDetailByVendorStoreID(db, storeMap.VendorStoreID, storeMap.VendorID) - if storeDetail != nil { - return nil, fmt.Errorf("此平台门店ID已在京西有绑定,请先解除绑定,平台门店ID :[%v]", storeMap.VendorStoreID) - } - } else if vendorID == model.VendorIDJX { - ReCalculateJxPriceLight(db, ctx, storeID) - } else if vendorID == model.VendorIDYB { - err = checkYbParams(db, storeMap, storeID) - if err != nil { - return nil, err - } - } else if vendorID == model.VendorIDJDShop { - if storeMap.VendorStoreID == "" { - storeMap.SyncStatus = model.SyncFlagNewMask //京东商城要去建店 - } else { - if handler := CurVendorSync.GetStoreHandler(vendorID); handler != nil { - store, err2 := handler.ReadStore(ctx, vendorOrgCode, storeMap.VendorStoreID) - if err = err2; err == nil || storeMap.IsSync == 0 { - if store != nil { - storeMap.Status = store.Status - } - err = nil - storeMap.SyncStatus = model.SyncFlagModifiedMask | model.SyncFlagStoreName | model.SyncFlagStoreAddress - } else { - return nil, err - } - } else { - err = ErrCanNotFindVendor - } - } - } - storeMapList, err := dao.GetStoresMapList2(db, []int{vendorID}, []int{storeID}, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "", true) - if len(storeMapList) > 0 { - _, err = CurVendorSync.SyncStore(ctx, db, storeMap.VendorID, storeID, false, userName) - } else { - if err == nil { - dao.WrapAddIDCULDEntity(storeMap, userName) - if db == nil { - db = dao.GetDB() - } - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - if err = dao.CreateEntity(db, storeMap); err == nil { - dao.Commit(db) - outStoreMap = storeMap - _, err = CurVendorSync.SyncStore(ctx, db, storeMap.VendorID, storeID, false, userName) - } else { - dao.Rollback(db) - } - } - } - if err != nil { - return outStoreMap, err - } - if vendorID == model.VendorIDJDShop { - //绑定京东商城后,需要对绑定的门店现有的和模板店相同且可售的商品设置京东商城的门店库存 - //TODO SyncFlagSaleMask对京东商城来说,修改门店商品状态就是修改库存 - if _, err = SetStoreSkuSyncStatus2(db, []int{storeID}, []int{model.VendorIDJDShop}, findSkusBetweenJdsMainStore(db, storeID), model.SyncFlagSaleMask); err == nil { - // CurVendorSync.SyncStoresSkus(ctx, nil, 0, db, nil, []int{storeID}, nil, false, true, true) - } - } - if globals.IsAddEvent { - err = AddEventDetail(db, ctx, model.OperateAdd, vendorID, model.ThingTypeStore, storeID, "", `{"VendorID":`+utils.Int2Str(vendorID)+`}`) - } - _, err = CurVendorSync.FullSyncStoresSkus(ctx, db, []int{vendorID}, []int{storeID}, true, nil, true, true) - return outStoreMap, err -} - -func DeleteStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, storeID, vendorID int, userName string) (num int64, err error) { - if db == nil { - db = dao.GetDB() - } - storeMap := &model.StoreMap{ - StoreID: storeID, - VendorID: vendorID, - } - storeMap.DeletedAt = utils.DefaultTimeValue - if err = dao.GetEntity(db, storeMap, model.FieldStoreID, model.FieldVendorID, model.FieldDeletedAt); err == nil { - if handler := partner.GetPurchasePlatformFromVendorID(vendorID); handler != nil { - handler.UpdateStoreCustomID(ctx, storeMap.VendorOrgCode, storeMap.VendorStoreID, utils.Str2Int64WithDefault(storeMap.VendorStoreID, 0)) - } - storeMap.FakeOpenStart = 0 - storeMap.FakeOpenStop = 0 - num, err = dao.DeleteEntityLogically(db, storeMap, map[string]interface{}{ - model.FieldStatus: model.StoreStatusDisabled, - }, userName, nil) - if globals.IsAddEvent { - err = AddEventDetail(db, ctx, model.OperateDelete, vendorID, model.ThingTypeStore, storeID, "", `{"VendorID":`+utils.Int2Str(vendorID)+`}`) - } - } - return num, err -} - -func isStoreMapNeedSync(vendorID int, valid map[string]interface{}) bool { - if vendorID != model.VendorIDJX { - for k := range valid { - if storeMapKeyPropertyMap[k] == 1 { - return true - } - } - } - return false -} - -func UpdateStoreVendorMap(ctx *jxcontext.Context, db *dao.DaoDB, storeID, vendorID int, payload map[string]interface{}, userName string) (num int64, err error) { - if vendorID != model.VendorIDJD { - if autoPickup, ok := payload["autoPickup"]; ok && autoPickup == 0 { - return 0, fmt.Errorf("非京东平台要求必须自动拣货") - } - } - var storeHandler partner.IPurchasePlatformHandler - if vendorID != model.VendorIDJX { - storeHandler = CurVendorSync.GetStoreHandler(vendorID) - if storeHandler == nil { - return 0, ErrCanNotFindVendor - } - } - // 暂时不开放isSync - if isSync, ok := payload["isSync"].(int); ok && isSync == 0 { - delete(payload, "isSync") - } - if db == nil { - db = dao.GetDB() - } - storeMap := &model.StoreMap{ - StoreID: storeID, - VendorID: vendorID, - } - storeMap.DeletedAt = utils.DefaultTimeValue - if err = dao.GetEntity(db, storeMap, model.FieldStoreID, model.FieldVendorID, model.FieldDeletedAt); err != nil { - return 0, err - } - var beforeStoreMap = *storeMap - syncStatus := model.SyncFlagModifiedMask - valid := dao.StrictMakeMapByStructObject(payload, storeMap, userName) - if valid["status"] != nil { - syncStatus |= model.SyncFlagStoreStatus - } - //修改分类开关需要打同步标志 - if valid["isSysCat"] != nil { - SetStoreCategorySyncStatus2(db, []int{storeID}, nil, model.SyncFlagModifiedMask) - } - if vendorStoreName, ok := valid["vendorStoreName"].(string); ok { - if utf8.RuneCountInString(vendorStoreName) > jdapi.MaxStoreNameLen && vendorID == model.VendorIDJD { - return 0, fmt.Errorf("门店名称不允许超过13位!") - } - syncStatus |= model.SyncFlagStoreName - } - for _, v := range [][]string{ - []string{ - "pricePercentagePack", - model.ConfigTypePricePack, - }, - []string{ - "freightDeductionPack", - model.ConfigTypeFreightPack, - }, - } { - if valid[v[0]] != nil { - if value := utils.Interface2String(valid[v[0]]); value != "" { - _, err2 := dao.QueryConfigs(db, value, v[1], "") - if err = err2; err != nil { - return 0, err - } - } - } - } - - if vendorID != model.VendorIDJX && vendorID != model.VendorIDYB { - if vendorStoreID := utils.Interface2String(valid["vendorStoreID"]); vendorStoreID != "" { - vendorStoreInfo, err2 := storeHandler.ReadStore(ctx, storeMap.VendorOrgCode, vendorStoreID) - if err = err2; err == nil { - valid["deliveryType"] = vendorStoreInfo.DeliveryType - } - err = nil // todo 忽略读不到DeliveryType的错误 - } - } - - if err == nil { - // globals.SugarLogger.Debug(utils.Format4Output(valid, false)) - if len(valid) > 0 { - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - if isStoreMapNeedSync(vendorID, valid) { // 对于store vendor map,只有Status改变才需要同步到厂商 - num, err = dao.UpdateEntityLogicallyAndUpdateSyncStatus(db, storeMap, valid, userName, map[string]interface{}{ - model.FieldStoreID: storeID, - model.FieldVendorID: vendorID, - }, model.FieldSyncStatus, syncStatus) - } else { - num, err = dao.UpdateEntityLogically(db, storeMap, valid, userName, map[string]interface{}{ - model.FieldStoreID: storeID, - model.FieldVendorID: vendorID, - }) - } - if err != nil { - dao.Rollback(db) - return 0, err - } - if num > 0 { - if globals.IsAddEvent { - mapBefore := refutil.FindMapAndStructMixed(valid, beforeStoreMap) - err = AddEventDetail(db, ctx, model.OperateUpdate, vendorID, model.ThingTypeStore, storeID, BuildDiffData(mapBefore), BuildDiffData(valid)) - } - if vendorID != model.VendorIDJX { - if valid["pricePercentage"] != nil || valid["pricePercentagePack"] != nil { - storeSkuBind := &model.StoreSkuBind{} - if num, err = dao.UpdateEntityLogicallyAndUpdateSyncStatus(db, storeSkuBind, nil, userName, map[string]interface{}{ - model.FieldStoreID: storeID, - }, dao.GetSyncStatusStructField(model.VendorNames[vendorID]), model.SyncFlagPriceMask); err != nil { - dao.Rollback(db) - return 0, err - } - } - } else { - if valid["pricePercentage"] != nil || valid["pricePercentagePack"] != nil { - ReCalculateJxPriceLight(db, ctx, storeID) - } - } - } - dao.Commit(db) - if isStoreMapNeedSync(vendorID, valid) { - _, err = CurVendorSync.SyncStore(ctx, db, vendorID, storeID, false, userName) - } - } - } - return num, err -} - -func DeleteStore(ctx *jxcontext.Context, storeID int) (num int64, err error) { - db := dao.GetDB() - - store := &model.Store{} - store.ID = storeID - if err = dao.GetEntity(db, store); err != nil { - return 0, err - } - if store.Status == model.StoreStatusOpened { - return 0, fmt.Errorf("删除京西门店前必须将所有门店解绑且门店处于关店状态") - } - - sql := ` - SELECT (SELECT COUNT(*) FROM store_map t1 WHERE t1.store_id = ? AND t1.deleted_at = ?) - + (SELECT COUNT(*) FROM store_courier_map t1 WHERE t1.store_id = ? AND t1.deleted_at = ?) ct - ` - ct := 0 - if err = dao.GetRow(db, &ct, sql, storeID, utils.DefaultTimeValue, storeID, utils.DefaultTimeValue); err != nil { - return 0, err - } - globals.SugarLogger.Debugf("DeleteStore storeID:%d, ct=%d", storeID, ct) - if ct > 0 { - return 0, fmt.Errorf("删除京西门店前必须将所有门店解绑且门店处于关店状态") - } - - dao.Begin(db) - defer dao.Rollback(db) - now := time.Now() - - for _, tableName := range []string{"store_sku_bind", "store_sku_category_map", "store_op_request"} { - sql = fmt.Sprintf(` - UPDATE %s t1 - SET t1.deleted_at = ?, - t1.updated_at = ?, - t1.last_operator = ? - WHERE t1.store_id = ? AND t1.deleted_at = ? - `, tableName) - if _, err = dao.ExecuteSQL(db, sql, now, now, ctx.GetUserName(), storeID, utils.DefaultTimeValue); err != nil { - return 0, err - } - } - - if num, err = dao.DeleteEntityLogically(db, store, nil, ctx.GetUserName(), nil); err != nil { - return 0, err - } - if globals.IsAddEvent { - err = AddEventDetail(db, ctx, model.OperateDelete, storeID, model.ThingTypeStore, storeID, "", "") - } - DeleteStoreCategroies(ctx, db, storeID) - dao.Commit(db) - return num, err - // return 0, errors.New("暂不支持删除京西门店") -} - -// 状态是未解决,且初始是2星以下 -func TmpGetJxBadCommentsNo(ctx *jxcontext.Context, storeID int) (count int, err error) { - db := dao.GetDB() - var ctInfo struct { - Ct int - } - if err = dao.GetRow(db, &ctInfo, ` - SELECT COUNT(*) ct - FROM jx_bad_comments - WHERE status = ? AND jxstoreid = ? AND score <= ? - `, orderman.COMMENT_NOT_RESOLVED, utils.Int2Str(storeID), orderman.JX_BAD_COMMENTS_MAX_LEVEL); err == nil { - count = ctInfo.Ct - } - return count, err -} - -func TmpGetJxBadCommentsByStoreId(ctx *jxcontext.Context, keyword string, storeIDs []int, offset, pageSize, commentType int, fromTime, toTime time.Time) (retVal map[string]interface{}, err error) { - db := dao.GetDB() - sql := ` - SELECT SQL_CALC_FOUND_ROWS - t1.*, t2.name store_name, t3.name city_name, - t4.vendor_order_id2 - FROM jx_bad_comments t1 - LEFT JOIN store t2 ON t2.id = t1.jxstoreid - LEFT JOIN place t3 ON t3.code = t2.city_code - LEFT JOIN goods_order t4 ON t4.vendor_order_id = t1.order_id AND t4.vendor_id = t1.order_flag - WHERE 1 = 1 - ` - sqlParams := []interface{}{} - if keyword != "" { - keywordLike := "%" + keyword + "%" - sql += ` - AND (t1.order_id LIKE ? OR t1.jxstoreid LIKE ? OR t1.userphone LIKE ? OR t1.scorecontent LIKE ? OR t1.vendertags LIKE ? OR t1.updated_scorecontent LIKE ? - OR t1.updated_vendertags LIKE ? OR t2.name LIKE ?)` - sqlParams = append(sqlParams, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike) - } - if len(storeIDs) > 0 { - sql += " AND t1.jxstoreid IN (" + dao.GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - if commentType != GET_ALL_COMMENTS_TYPE { - sql += " AND t1.status = ?" - if commentType == GET_BAD_COMMENTS_TYPE { - sql += " AND t1.score <= ?" - sqlParams = append(sqlParams, orderman.COMMENT_NOT_RESOLVED, orderman.JX_BAD_COMMENTS_MAX_LEVEL) - } else { - sqlParams = append(sqlParams, orderman.COMMENT_RESOLVED) - } - } - if !utils.IsTimeZero(fromTime) { - sql += " AND t1.createtime >= ?" - sqlParams = append(sqlParams, fromTime) - } - if !utils.IsTimeZero(toTime) { - sql += " AND t1.createtime < ?" - sqlParams = append(sqlParams, toTime) - } - sql += " ORDER BY t1.createtime DESC" - pageSize = jxutils.FormalizePageSize(pageSize) - offset = jxutils.FormalizePageOffset(offset) - sql += " LIMIT ? OFFSET ?" - sqlParams = append(sqlParams, pageSize, offset) - var commentList []*JxBadCommentsExt - dao.Begin(db) - defer func() { - dao.Rollback(db) - }() - // globals.SugarLogger.Debug(sql) - // globals.SugarLogger.Debug(utils.Format4Output(sqlParams, false)) - if err = dao.GetRows(db, &commentList, sql, sqlParams...); err == nil { - retVal = map[string]interface{}{ - "total": dao.GetLastTotalRowCount(db), - "list": commentList, - } - dao.Commit(db) - } - return retVal, err -} - -type GetStoreCourierMapsResult struct { - storeCourierMaps *model.StoreCourierMap - CourierAddress string `json:"courierAddress"` - CourierPhone string `json:"courierPhone"` -} - -func GetStoreCourierMaps(ctx *jxcontext.Context, db *dao.DaoDB, storeID int, vendorID int) (storeCourierMaps []*model.StoreCourierMap, err error) { - cond := map[string]interface{}{ - model.FieldStoreID: storeID, - } - if vendorID != -1 { - cond[model.FieldVendorID] = vendorID - } - err = dao.GetEntitiesByKV(db, &storeCourierMaps, cond, false) - globals.SugarLogger.Debug("之前的storeCourierMaps") - globals.SugarLogger.Debug(utils.Format4Output(storeCourierMaps, false)) - if len(storeCourierMaps) != 0 { - //同步美团配送与否状态及美团门店是否存在 - for _, v := range storeCourierMaps { - if v.VendorID != model.VendorIDMTPS { - continue - } else { - SetMTPSStatus(jxcontext.AdminCtx, v.StoreID, v.Status) - globals.SugarLogger.Debug("之后的storeCourierMaps") - globals.SugarLogger.Debug(v) - break - } - } - } - return storeCourierMaps, err -} - -func AddStoreCourierMap(ctx *jxcontext.Context, db *dao.DaoDB, storeID, vendorID int, storeCourierMap *model.StoreCourierMap) (outStoreCourierMap *model.StoreCourierMap, err error) { - return addStoreCourierMap(ctx, db, storeID, vendorID, storeCourierMap, true) -} - -func addStoreCourierMap(ctx *jxcontext.Context, db *dao.DaoDB, storeID, vendorID int, storeCourierMap *model.StoreCourierMap, isNeedUpdateRemote bool) (outStoreCourierMap *model.StoreCourierMap, err error) { - storeCourierMap.StoreID = storeID - storeCourierMap.VendorID = vendorID - storeCourierMap.VendorStatus = storeCourierMap.Status - globals.SugarLogger.Debugf("addStoreCourierMap %s, storeCourierMap:%s, isNeedUpdateRemote:%t", model.VendorChineseNames[vendorID], utils.Format4Output(storeCourierMap, true), isNeedUpdateRemote) - - if handler := partner.GetDeliveryPlatformFromVendorID(vendorID); handler != nil { - if db == nil { - db = dao.GetDB() - } - if isNeedUpdateRemote { - storeDetail, err2 := dao.GetStoreDetail2(db, storeID, "", vendorID) - if err = err2; err != nil { - return nil, err - } - if storeDetail.VendorStoreID != "" { - return nil, fmt.Errorf("门店已经绑定了%s, ID:%s, 如需重新绑定, 请先解绑", model.VendorChineseNames[vendorID], storeDetail.VendorStoreID) - } - storeDetail.VendorID = vendorID - storeDetail.VendorStoreID = storeCourierMap.VendorStoreID - if err = updateCourierStore(ctx, storeDetail); err != nil { - if vendorID != model.VendorIDMTPS { - return nil, err - } - // 如果是美团配送,强制忽略更新错 - globals.SugarLogger.Infof("addStoreCourierMap storeID:%d, vendorID:%d failed with err:%v", storeID, vendorID, err) - err = nil - } - } - dao.WrapAddIDCULDEntity(storeCourierMap, ctx.GetUserName()) - if err = dao.CreateEntity(db, storeCourierMap); err != nil { - return nil, err - } - if globals.IsAddEvent { - err = AddEventDetail(db, ctx, model.OperateAdd, vendorID, model.ThingTypeStore, storeID, "", `{"VendorID":`+utils.Int2Str(vendorID)+`}`) - } - outStoreCourierMap = storeCourierMap - } else { - err = ErrCanNotFindVendor - } - //同步美团配送与否状态及美团门店是否存在 - // if outStoreCourierMap.VendorID == model.VendorIDMTPS { - // SetMTPSStatus(jxcontext.AdminCtx, outStoreCourierMap.StoreID, outStoreCourierMap.Status) - // } - return outStoreCourierMap, err -} - -func DeleteStoreCourierMap(ctx *jxcontext.Context, db *dao.DaoDB, storeID, vendorID int, userName string) (num int64, err error) { - if db == nil { - db = dao.GetDB() - } - storeCourierMap := &model.StoreCourierMap{} - num, err = dao.DeleteEntityLogically(db, storeCourierMap, map[string]interface{}{ - model.FieldStatus: model.StoreStatusDisabled, - model.FieldVendorStatus: model.StoreStatusDisabled, - }, userName, map[string]interface{}{ - model.FieldStoreID: storeID, - model.FieldVendorID: vendorID, - }) - if globals.IsAddEvent { - err = AddEventDetail(db, ctx, model.OperateDelete, vendorID, model.ThingTypeStore, storeID, "", `{"VendorID":`+utils.Int2Str(vendorID)+`}`) - } - return num, err -} - -func UpdateStoreCourierMap(ctx *jxcontext.Context, db *dao.DaoDB, storeID, vendorID int, payload map[string]interface{}, userName string) (num int64, err error) { - if db == nil { - db = dao.GetDB() - } - storeCourier := &model.StoreCourierMap{ - StoreID: storeID, - VendorID: vendorID, - } - storeCourier.DeletedAt = utils.DefaultTimeValue - if err = dao.GetEntity(db, storeCourier, model.FieldStoreID, model.FieldVendorID, model.FieldDeletedAt); err != nil { - return 0, err - } - var beforeStoreCourier = *storeCourier - delete(payload, "auditStatus") // 不允许直接修改auditStatus的值 - valid := dao.NormalMakeMapByStructObject(payload, storeCourier, userName) - if len(valid) > 0 { - if storeCourier.AuditStatus != model.StoreAuditStatusOnline { - if status := utils.Interface2Int64WithDefault(valid["status"], 0); status == model.StoreStatusOpened { - // 没有通过审核的禁止改状态为正常 - return 0, fmt.Errorf("此快递门店还没有通过审核,不启用") - } - } - num, err = dao.UpdateEntityLogically(db, storeCourier, valid, userName, nil) - if globals.IsAddEvent { - mapBefore := refutil.FindMapAndStructMixed(valid, beforeStoreCourier) - err = AddEventDetail(db, ctx, model.OperateUpdate, vendorID, model.ThingTypeStore, storeID, BuildDiffData(mapBefore), BuildDiffData(valid)) - } - } - return num, err -} - -func updateCourierStore(ctx *jxcontext.Context, storeDetail *dao.StoreDetail2) (err error) { - globals.SugarLogger.Debugf("updateCourierStore %s, storeID:%d, vendorStoreID:%s", model.VendorChineseNames[storeDetail.VendorID], storeDetail.ID, storeDetail.VendorStoreID) - - if handlerInfo := partner.GetDeliveryPlatformFromVendorID(storeDetail.VendorID); handlerInfo != nil && handlerInfo.Use4CreateWaybill { - if updateHandler, ok := handlerInfo.Handler.(partner.IDeliveryUpdateStoreHandler); ok { - err = updateHandler.UpdateStore(ctx, formalizeStore4Courier(storeDetail)) - } - } else { - err = fmt.Errorf("配送平台:%s不被支持", model.VendorChineseNames[storeDetail.VendorID]) - } - return err -} - -func updateCourierStores(ctx *jxcontext.Context, storeID int) (err error) { - globals.SugarLogger.Debugf("updateCourierStores storeID:%d", storeID) - - db := dao.GetDB() - errList := errlist.New() - for k, v := range partner.DeliveryPlatformHandlers { - if v.Use4CreateWaybill { - if _, ok := v.Handler.(partner.IDeliveryUpdateStoreHandler); ok { - storeDetail, err2 := dao.GetStoreDetail2(db, storeID, "", k) - if err = err2; err2 == nil { - if storeDetail.VendorStoreID != "" && storeDetail.AuditStatus == model.StoreAuditStatusOnline { - err = updateCourierStore(ctx, storeDetail) - } - } - errList.AddErr(err) - } - } - } - return errList.GetErrListAsOne() -} - -func updateOrCreateCourierStore(ctx *jxcontext.Context, storeDetail *dao.StoreDetail2) (isCreated bool, err error) { - globals.SugarLogger.Debugf("updateOrCreateCourierStore %s, storeID:%d, vendorStoreID:%s", model.VendorChineseNames[storeDetail.VendorID], storeDetail.ID, storeDetail.VendorStoreID) - - if handlerInfo := partner.GetDeliveryPlatformFromVendorID(storeDetail.VendorID); handlerInfo != nil && handlerInfo.Use4CreateWaybill { - if storeDetail.DistrictName == "" { - return false, fmt.Errorf("门店的区码有问题,请检查") - } - if storeDetail.CityName == "" { - return false, fmt.Errorf("门店的城市码有问题,请检查") - } - formalizeStore4Courier(storeDetail) - needUpdate := false - remoteStoreDetail, err2 := handlerInfo.Handler.GetStore(ctx, 0, storeDetail.VendorStoreID) - if err = err2; err != nil { - if handlerInfo.Handler.IsErrStoreNotExist(err) { - storeDetail.VendorStoreID, storeDetail.AuditStatus, err = handlerInfo.Handler.CreateStore(ctx, storeDetail) - if err == nil { - isCreated = true - } else if handlerInfo.Handler.IsErrStoreExist(err) { - storeDetail.AuditStatus = model.StoreAuditStatusCreated - err = nil - } - } - } else { - storeDetail.CourierStatus = remoteStoreDetail.CourierStatus - storeDetail.AuditStatus = remoteStoreDetail.AuditStatus - needUpdate = true - } - if err == nil && needUpdate { - if updateHandler, _ := handlerInfo.Handler.(partner.IDeliveryUpdateStoreHandler); updateHandler != nil { - err = updateHandler.UpdateStore(ctx, storeDetail) - } else { - // err = fmt.Errorf("快递平台%s不支持更新门店信息,请手动处理", model.VendorChineseNames[storeDetail.VendorID]) - } - } - if err != nil { - err = fmt.Errorf("门店ID:%d,门店名:%s,错误描述:%s", storeDetail.Store.ID, storeDetail.Name, err.Error()) - globals.SugarLogger.Debugf("updateOrCreateCourierStore storeID:%d failed with error:%v", storeDetail.ID, err) - } - } - return isCreated, err -} - -func UpdateOrCreateCourierStores(ctx *jxcontext.Context, storeID int, isForceUpdate, isAsync, isContinueWhenError bool) (hint string, err error) { - globals.SugarLogger.Debugf("UpdateOrCreateCourierStores storeID:%d", storeID) - - var storeIDs []int - if storeID != 0 { - storeIDs = []int{storeID} - } else { - storesInfo, err2 := GetStores(ctx, "", map[string]interface{}{}, 0, -1, utils.DefaultTimeValue, utils.DefaultTimeValue, 0, 0) - if err = err2; err != nil { - return "", err - } - for _, v := range storesInfo.Stores { - storeIDs = append(storeIDs, v.ID) - } - } - - task := tasksch.NewParallelTask("UpdateOrCreateCourierStores", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - var resultList []interface{} - storeID := batchItemList[0].(int) - errList := errlist.New() - db := dao.GetDB() - for vendorID, v := range partner.DeliveryPlatformHandlers { - if v.Use4CreateWaybill { - if _, ok := v.Handler.(partner.IDeliveryUpdateStoreHandler); ok { - storeDetail, err2 := dao.GetStoreDetail2(db, storeID, "", vendorID) - if err = err2; err2 == nil { - isNeedAdd := storeDetail.VendorStoreID == "" - if isForceUpdate || isNeedAdd { - if isNeedAdd { - storeDetail.VendorID = vendorID - storeDetail.VendorStoreID = utils.Int2Str(storeDetail.ID) - } - if _, err = updateOrCreateCourierStore(ctx, storeDetail); err == nil && isNeedAdd { - storeCourier := &model.StoreCourierMap{ - VendorStoreID: storeDetail.VendorStoreID, - Status: model.StoreStatusOpened, - AuditStatus: storeDetail.AuditStatus, - } - if storeDetail.AuditStatus != model.StoreAuditStatusOnline { - storeCourier.Status = model.StoreStatusDisabled - } - if _, err = addStoreCourierMap(ctx, db, storeDetail.ID, storeDetail.VendorID, storeCourier, false); err == nil { - resultList = append(resultList, 1) - } - } - } - } - errList.AddErr(err) - } - } - } - return resultList, errList.GetErrListAsOne() - }, storeIDs) - tasksch.HandleTask(task, nil, len(storeIDs) > 1).Run() - if !isAsync { - resultList, err2 := task.GetResult(0) - if err = err2; err == nil { - hint = utils.Int2Str(len(resultList)) - } - } else { - hint = task.ID - } - return hint, err -} - -func formalizeStore4Courier(storeDetail *dao.StoreDetail2) *dao.StoreDetail2 { - storeDetail.Name = fmt.Sprintf("%s-%s-%s", model.ShopChineseNames[model.VendorIDJD], storeDetail.CityName, storeDetail.Name) - if storeDetail.PayeeName == "" { - storeDetail.PayeeName = "店主" - } - return storeDetail -} - -type EbaiStoreHealthy struct { - RealShopID int `json:"门店ID"` - MerchantID string `json:"平台门店ID"` - MerchantName string `json:"平台门店名"` - SkuNum string `json:"日均在架且有库存的商品数"` - IsSku string `json:"商品数是否达标"` - HasPhotoRate string `json:"有图率"` - IsYoutu string `json:"有图率是否达标"` - Hours string `json:"日均营业时长"` - IsYinye string `json:"营业时长是否达标"` - UnvalidOrderNum string `json:"商家原因取消订单数"` - IsJiedan string `json:"取消数是否达标"` - BadOrderRate string `json:"差评订单率"` - IsCp string `json:"差评率是否达标"` - RestaurantSubsidy string `json:"商家补贴金额(元)"` - IsButie string `json:"补贴是否达标"` - IsHealthy string `json:"商户是否健康"` -} - -func ExportShopsHealthInfo(ctx *jxcontext.Context, vendorIDs, storeIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { - db := dao.GetDB() - vendorID := model.VendorIDEBAI - storeMapList, err := dao.GetStoresMapList(db, []int{vendorID}, storeIDs, nil, model.StoreStatusAll, model.StoreIsSyncYes, "", "") - if err != nil { - return "", err - } - storeMap2 := make(map[string]*model.StoreMap) - for _, v := range storeMapList { - storeMap2[v.VendorStoreID] = v - } - if len(storeMapList) > 0 { - var healthInfoList []interface{} - var excelBin []byte - var excelURL string - task := tasksch.NewSeqTask(fmt.Sprintf("ExportShopHealthInfo[%s]", model.VendorChineseNames[vendorID]), ctx, - func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - subTask := tasksch.NewParallelTask(fmt.Sprintf("ExportShopHealthInfo2[%s]", model.VendorChineseNames[vendorID]), tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeMap := batchItemList[0].(*model.StoreMap) - healthInfo, err := ebai.CurPurchaseHandler.GetShopHealthInfo(storeMap.VendorStoreID) - if err == nil { - retVal = []map[string]interface{}{healthInfo} - } - return retVal, err - }, storeMapList) - tasksch.AddChild(task, subTask).Run() - healthInfoList, err = subTask.GetResult(0) - if isContinueWhenError && err != nil && len(healthInfoList) > 0 { - err = nil - } - case 1: - var healthInfoList2 []map[string]interface{} - for _, v := range healthInfoList { - mapInfo := v.(map[string]interface{}) - mapInfo["real_shop_id"] = storeMap2[utils.Interface2String(mapInfo["merchant_id"])].StoreID - healthInfoList2 = append(healthInfoList2, mapInfo) - } - var healthyList []*EbaiStoreHealthy - for _, v := range healthInfoList2 { - healthy := &EbaiStoreHealthy{ - RealShopID: v["real_shop_id"].(int), - MerchantID: v["merchant_id"].(string), - MerchantName: v["merchant_name"].(string), - SkuNum: v["sku_num"].(string), - IsSku: v["is_sku"].(string), - HasPhotoRate: v["has_photo_rate"].(string), - IsYoutu: v["is_youtu"].(string), - Hours: v["hours"].(string), - IsYinye: v["is_yinye"].(string), - UnvalidOrderNum: v["unvalid_order_num"].(string), - IsJiedan: v["is_jiedan"].(string), - BadOrderRate: v["bad_order_rate"].(string), - IsCp: v["is_cp"].(string), - RestaurantSubsidy: v["restaurant_subsidy"].(string), - IsButie: v["is_butie"].(string), - IsHealthy: v["is_healthy"].(string), - } - healthyList = append(healthyList, healthy) - } - excelConf := &excel.Obj2ExcelSheetConfig{ - Title: "饿百门店情况导出", - Data: healthyList, - CaptionList: []string{ - "门店ID", - "平台门店ID", - "平台门店名", - "日均在架且有库存的商品数", - "商品数是否达标", - "有图率", - "有图率是否达标", - "日均营业时长", - "营业时长是否达标", - "商家原因取消订单数", - "取消数是否达标", - "差评订单率", - "差评率是否达标", - "商家补贴金额(元)", - "补贴是否达标", - "商户是否健康", - }, - } - excelBin = excel.Obj2Excel([]*excel.Obj2ExcelSheetConfig{excelConf}) - case 2: - keyPart := []string{ - ctx.GetUserName(), - "饿百门店情况", - } - keyPart = append(keyPart, time.Now().Format("20060102T150405")+".xlsx") - key := "export/" + strings.Join(keyPart, "_") - excelURL, err = jxutils.UploadExportContent(excelBin, key) - if err == nil { - task.SetNoticeMsg(excelURL) - } - globals.SugarLogger.Debugf("导出饿百门店情况excelURL:%s, err:%v", excelURL, err) - } - return nil, err - }, 3) - tasksch.HandleTask(task, nil, true).Run() - if !isAsync { - _, err = task.GetResult(0) - if err == nil { - hint = excelURL - } - } else { - hint = task.GetID() - } - } - return hint, err -} - -func GetCorporationInfo(ctx *jxcontext.Context, licenceCode string) (corporationInfo *jdapi.CorporationInfo, err error) { - // 门店ID随便一个合法的京东门店ID就可以 - corporationInfo, err = api.JdAPI.GetCorporationInfo("11734851", licenceCode) - return corporationInfo, err -} - -func GetStoresVendorSnapshot(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorIDs, storeIDs []int) (vendorStoreSnapshotList []*model.VendorStoreSnapshot, err error) { - db := dao.GetDB() - storeMapList, err := dao.GetStoresMapList(db, vendorIDs, storeIDs, nil, model.StoreStatusAll, model.StoreIsSyncYes, "", "") - if err != nil { - return nil, err - } - task := tasksch.NewParallelTask("GetStoresVendorSnapshot", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeMap := batchItemList[0].(*model.StoreMap) - if model.IsVendorRemote(storeMap.VendorID) { - if handler := partner.GetPurchasePlatformFromVendorID(storeMap.VendorID); handler != nil { - store, err2 := handler.ReadStore(ctx, storeMap.VendorOrgCode, storeMap.VendorStoreID) - if err = err2; err == nil { - retVal = []interface{}{&model.VendorStoreSnapshot{ - StoreID: storeMap.StoreID, - VendorID: storeMap.VendorID, - VendorStoreID: storeMap.VendorStoreID, - - Status: store.Status, - OpenTime1: store.OpenTime1, - CloseTime1: store.CloseTime1, - OpenTime2: store.OpenTime2, - CloseTime2: store.CloseTime2, - - DeliveryType: store.DeliveryType, - StoreName: store.OriginalName, - IsAutoOrder: store.IsAutoOrder, - }} - } - } - } - return retVal, err - }, storeMapList) - tasksch.HandleTask(task, parentTask, true).Run() - resultList, err := task.GetResult(0) - if len(resultList) > 0 { - for _, v := range resultList { - dao.WrapAddIDCULDEntity(v, ctx.GetUserName()) - vendorStoreSnapshotList = append(vendorStoreSnapshotList, v.(*model.VendorStoreSnapshot)) - } - } - return vendorStoreSnapshotList, err -} - -func getCurrentSnapshotAt(now time.Time) (snapshotAt time.Time) { - return jxutils.GetLastTimeFromList(now, WatchVendorStoreTimeList) -} - -func updateVendorStoreStatusBySnapshot(db *dao.DaoDB, curSnapshotList []*model.VendorStoreSnapshot) (err error) { - storeMapList, err := dao.GetStoresMapList(db, nil, nil, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "") - if err != nil { - return err - } - snapshotMap := make(map[int64]*model.VendorStoreSnapshot) - for _, v := range curSnapshotList { - snapshotMap[jxutils.Combine2Int(v.StoreID, v.VendorID)] = v - } - dao.Begin(db) - defer func() { - if r := recover(); r != nil || err != nil { - dao.Rollback(db) - if r != nil { - panic(r) - } - } - }() - for _, v := range storeMapList { - if snapshot := snapshotMap[jxutils.Combine2Int(v.StoreID, v.VendorID)]; snapshot != nil && - (v.Status != snapshot.Status || v.DeliveryType != snapshot.DeliveryType || v.StoreName != snapshot.StoreName) { - v.Status = snapshot.Status - v.DeliveryType = snapshot.DeliveryType - v.StoreName = snapshot.StoreName - if _, err = dao.UpdateEntity(db, v, model.FieldStatus, "DeliveryType", "StoreName"); err != nil { - return err - } - } - } - dao.Commit(db) - - utils.CallFuncAsync(func() { - for _, v := range storeMapList { - if snapshot := snapshotMap[jxutils.Combine2Int(v.StoreID, v.VendorID)]; snapshot != nil { - if snapshot.IsAutoOrder == 1 { - if handler, ok := partner.GetPurchasePlatformFromVendorID(snapshot.VendorID).(partner.IStoreHandler); ok { - handler.EnableAutoAcceptOrder(jxcontext.AdminCtx, v.VendorOrgCode, v.StoreID, v.VendorStoreID, false) - } - } - } - } - }) - return err -} - -func SaveStoresVendorSnapshot(db *dao.DaoDB, snapshotAt time.Time, curSnapshotList []*model.VendorStoreSnapshot) (err error) { - dao.Begin(db) - defer func() { - if r := recover(); r != nil || err != nil { - dao.Rollback(db) - if r != nil { - panic(r) - } - } - }() - if err = dao.DeleteVendorStoreSnapshot(db, snapshotAt.Add(-48*time.Hour)); err != nil { - return err - } - for _, v := range curSnapshotList { - v.SnapshotAt = snapshotAt - - dao.DeleteEntity(db, v, "VendorStoreID", "VendorID", "SnapshotAt") - if err = dao.CreateEntity(db, v); err != nil { - return err - } - } - dao.Commit(db) - return err -} - -func isVendorStoresStatusNotOk(storeMapList []*model.VendorStoreSnapshot) bool { - statusMap := make(map[int]int) - maxStatus := model.StoreStatusClosed - for _, v := range storeMapList { - statusMap[v.Status] = 1 - if v.Status > maxStatus { - maxStatus = v.Status - } - } - return len(statusMap) > 1 && maxStatus == model.StoreStatusOpened -} - -func getAllUsers4Store(ctx *jxcontext.Context, db *dao.DaoDB, store *model.Store) (userList []*model.User) { - storeID := store.ID - var userIDs []string - userMap := make(map[string]int) - - // 门店老板 - if roleUserIDList, err := GetRoleUserList(ctx, autils.NewStoreBossRole(storeID)); err == nil && len(roleUserIDList) > 0 { - userIDs = append(userIDs, roleUserIDList...) - } - - // 全局相关角色(市场或运营) - for _, v := range []string{store.MarketManRole, store.OperatorRole, store.OperatorRole2, store.OperatorRole3} { - if v != "" { - if roleUserIDList, err := GetRoleUserList(ctx, autils.NewRole(v, 0)); err == nil && len(roleUserIDList) > 0 { - userIDs = append(userIDs, roleUserIDList...) - } - } - } - - if len(userIDs) > 0 { - userList, _, _ = dao.GetUsers(db, 0, "", userIDs, nil, nil, 0, -1) - for _, v := range userList { - userMap[v.GetID()] = 1 - } - } - - // 直接电话信息相关人员 - for _, mobile := range []string{store.Tel1, store.Tel2, store.MarketManPhone, store.OperatorPhone, store.OperatorPhone2, store.OperatorPhone3} { - if mobile != "" { - if user, err2 := dao.GetUserByID(db, "mobile", mobile); err2 == nil { - if userMap[user.GetID()] == 0 { - userMap[user.GetID()] = 1 - userList = append(userList, user) - } - } - } - } - return userList -} - -type tStoreIDList struct { - StoreIDList []int - StoreMap map[int]*model.Store -} - -func (l *tStoreIDList) Len() int { - return len(l.StoreIDList) -} - -func (l *tStoreIDList) Less(i, j int) bool { - storei := l.StoreMap[l.StoreIDList[i]] - storej := l.StoreMap[l.StoreIDList[j]] - if storei.CityCode == storej.CityCode { - return storei.ID < storej.ID - } - return storei.CityCode < storej.CityCode -} - -func (l *tStoreIDList) Swap(i, j int) { - l.StoreIDList[i], l.StoreIDList[j] = l.StoreIDList[j], l.StoreIDList[i] -} - -func SendAlarmVendorSnapshot(ctx *jxcontext.Context, parentTask tasksch.ITask, prevSnapshotList, curSnapshotList []*model.VendorStoreSnapshot) (err error) { - if len(prevSnapshotList) == 0 { - return nil - } - - prevSnapshotMap := make(map[string]*model.VendorStoreSnapshot) - prevSnapshotMap2 := make(map[int]map[int]*model.VendorStoreSnapshot) - for _, v := range prevSnapshotList { - prevSnapshotMap[v.GenMapKey()] = v - if prevSnapshotMap2[v.StoreID] == nil { - prevSnapshotMap2[v.StoreID] = make(map[int]*model.VendorStoreSnapshot) - } - prevSnapshotMap2[v.StoreID][v.VendorID] = v - } - curSnapshotMap := make(map[string]*model.VendorStoreSnapshot) - curSnapshotMap2 := make(map[int]map[int]*model.VendorStoreSnapshot) - curSnapshotGroupMap := make(map[int][]*model.VendorStoreSnapshot) - - alarmSnapshotMap := make(map[int][]*model.VendorStoreSnapshot) - txtAlarmSnapshotMap := make(map[int][]*model.VendorStoreSnapshot) - // 之前是开店当前是关店的,或营业时间缩短的 - for _, v := range curSnapshotList { - curSnapshotGroupMap[v.StoreID] = append(curSnapshotGroupMap[v.StoreID], v) - if curSnapshotMap2[v.StoreID] == nil { - curSnapshotMap2[v.StoreID] = make(map[int]*model.VendorStoreSnapshot) - } - curSnapshotMap2[v.StoreID][v.VendorID] = v - - curSnapshotMap[v.GenMapKey()] = v - prevSnapshot := prevSnapshotMap[v.GenMapKey()] - if prevSnapshot != nil { - if (prevSnapshot.Status == model.StoreStatusOpened && v.Status != model.StoreStatusOpened) || - v.CompareOperationTime(prevSnapshot) < 0 { - alarmSnapshotMap[v.StoreID] = append(alarmSnapshotMap[v.StoreID], v) - - txtAlarmSnapshotMap[prevSnapshot.StoreID] = append(txtAlarmSnapshotMap[prevSnapshot.StoreID], prevSnapshot) - } - } - } - - //当前门店,不同平台门店状态不一致的 - for storeID, list := range curSnapshotGroupMap { - if isVendorStoresStatusNotOk(list) { - alarmSnapshotMap[storeID] = list - } - } - - // 之前有店(且是开店状态),当前无店的 - for _, v := range prevSnapshotList { - if v.Status == model.StoreStatusOpened && curSnapshotMap[v.GenMapKey()] == nil { - alarmSnapshotMap[v.StoreID] = append(alarmSnapshotMap[v.StoreID], v) - - txtAlarmSnapshotMap[v.StoreID] = append(txtAlarmSnapshotMap[v.StoreID], v) - } - } - - db := dao.GetDB() - storeDetailMap := make(map[int]*dao.StoreDetail) - userMap2 := make(map[string]*model.User) - userMap := make(map[string]map[int]int) - userMapTxt := make(map[string][]*model.VendorStoreSnapshot) - for storeID, list := range alarmSnapshotMap { - storeDetail, _ := dao.GetStoreDetail(db, storeID, list[0].VendorID) - if storeDetail != nil { - storeDetailMap[storeID] = storeDetail - userList := getAllUsers4Store(ctx, db, &storeDetail.Store) - for _, user := range userList { - userID := user.GetID() - if userMap[userID] == nil { - userMap[userID] = make(map[int]int) - userMap2[userID] = user - } - userMap[userID][storeID] = 1 - if txtAlarmSnapshotMap[storeID] != nil { - userMapTxt[userID] = append(userMapTxt[userID], txtAlarmSnapshotMap[storeID]...) - } - } - } - } - var userList []*model.User - for _, user := range userMap2 { - userList = append(userList, user) - } - - if len(userList) > 0 { - allStores, err := dao.GetStoreList(db, nil, nil, nil, nil, "") - if err != nil { - return err - } - allStoreMap := make(map[int]*model.Store) - for _, v := range allStores { - allStoreMap[v.ID] = v - } - - const fixTitle = "门店状态变化" - title := fmt.Sprintf("%s:%s-->%s", fixTitle, utils.Time2Str(prevSnapshotList[0].SnapshotAt), utils.Time2Str(curSnapshotList[0].SnapshotAt)) - task := tasksch.NewParallelTask("SendAlarmVendorSnapshot", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - user := batchItemList[0].(*model.User) - var excelURL string - if user.Type&model.UserTypeOperator != 0 { - var dataList []map[string]interface{} - captionList := []string{"京西门店ID", "门店名", "城市"} - isFirstRow := true - - storeIDList := &tStoreIDList{ - StoreMap: allStoreMap, - } - for storeID := range userMap[user.GetID()] { - storeIDList.StoreIDList = append(storeIDList.StoreIDList, storeID) - } - sort.Sort(storeIDList) - for _, storeID := range storeIDList.StoreIDList { - prevAlarmMap := prevSnapshotMap2[storeID] - curAlarmMap := curSnapshotMap2[storeID] - data := map[string]interface{}{ - "京西门店ID": storeID, - "门店名": storeDetailMap[storeID].Store.Name, - "城市": storeDetailMap[storeID].CityName, - } - for _, vendorID := range []int{model.VendorIDJD, model.VendorIDEBAI, model.VendorIDMTWM} { - if isFirstRow { - captionList = append(captionList, model.VendorChineseNames[vendorID]+"ID", - model.VendorChineseNames[vendorID]+"之前状态", model.VendorChineseNames[vendorID]+"当前状态", - model.VendorChineseNames[vendorID]+"之前营业时间", model.VendorChineseNames[vendorID]+"当前营业时间") - } - if prevAlarmMap != nil { - data[model.VendorChineseNames[vendorID]+"当前状态"] = "" - data[model.VendorChineseNames[vendorID]+"当前营业时间"] = "" - if prevSnapshot := prevAlarmMap[vendorID]; prevSnapshot != nil { - data[model.VendorChineseNames[vendorID]+"ID"] = prevSnapshot.VendorStoreID - data[model.VendorChineseNames[vendorID]+"之前状态"] = model.StoreStatusName[prevSnapshot.Status] - data[model.VendorChineseNames[vendorID]+"之前营业时间"] = jxutils.OperationTimeStr4VendorStore(prevSnapshot) - if snapshot := curSnapshotMap[prevSnapshot.GenMapKey()]; snapshot != nil { - data[model.VendorChineseNames[vendorID]+"当前状态"] = model.StoreStatusName[snapshot.Status] - data[model.VendorChineseNames[vendorID]+"当前营业时间"] = jxutils.OperationTimeStr4VendorStore(snapshot) - } - } else { - data[model.VendorChineseNames[vendorID]+"ID"] = "" - data[model.VendorChineseNames[vendorID]+"之前状态"] = "" - data[model.VendorChineseNames[vendorID]+"之前营业时间"] = "" - } - } else if curAlarmMap != nil { - data[model.VendorChineseNames[vendorID]+"之前状态"] = "" - data[model.VendorChineseNames[vendorID]+"之前营业时间"] = "" - if curSnapshot := curAlarmMap[vendorID]; curSnapshot != nil { - data[model.VendorChineseNames[vendorID]+"ID"] = curSnapshot.VendorStoreID - data[model.VendorChineseNames[vendorID]+"当前状态"] = model.StoreStatusName[curSnapshot.Status] - data[model.VendorChineseNames[vendorID]+"当前营业时间"] = jxutils.OperationTimeStr4VendorStore(curSnapshot) - } else { - data[model.VendorChineseNames[vendorID]+"ID"] = "" - data[model.VendorChineseNames[vendorID]+"当前状态"] = "" - data[model.VendorChineseNames[vendorID]+"当前营业时间"] = "" - } - } - } - dataList = append(dataList, data) - - isFirstRow = false - } - excelConf := &excel.Obj2ExcelSheetConfig{ - Title: fixTitle, - Data: dataList, - CaptionList: captionList, - } - excelBin := excel.Obj2Excel([]*excel.Obj2ExcelSheetConfig{excelConf}) - keyPart := []string{ - "store_status", - user.GetMobile(), - time.Now().Format("20060102T150405") + ".xlsx", - } - key := "export/" + strings.Join(keyPart, "_") - excelURL, err = jxutils.UploadExportContent(excelBin, key) - if err != nil { - globals.SugarLogger.Warnf("SendAlarmVendorSnapshot, %s upload %s failed with error:%v", user.GetName(), key, err) - } - var txtAlarm []string - - for _, v := range userMapTxt[user.GetID()] { - curSnapshot := curSnapshotMap[v.GenMapKey()] - storeDetail := storeDetailMap[v.StoreID] - curStoreStatus := "无店" - curOpTimeStr := "无店" - if curSnapshot != nil { - curStoreStatus = model.StoreStatusName[curSnapshot.Status] - curOpTimeStr = jxutils.OperationTimeStr4VendorStore(curSnapshot) - } - txtAlarm = append(txtAlarm, fmt.Sprintf(`## 门店: %s(%d) -- 城市: %s -- 平台: %s -- 平台ID: %s -- 之前状态: %s -- 当前状态: %s -- 之前营业时间: %s -- 当前营业时间: %s -`, storeDetail.Store.Name, v.StoreID, storeDetail.CityName, model.VendorChineseNames[v.VendorID], v.VendorStoreID, model.StoreStatusName[v.Status], curStoreStatus, jxutils.OperationTimeStr4VendorStore(v), curOpTimeStr)) - } - alarmTextStr := "# " + title + " \n" + fmt.Sprintf("[详情点我](%s/billshow/?normal=true&path=%s) \n", globals.BackstageHost, excelURL) + strings.Join(txtAlarm, " \n") - sendStoreStatusInfo2Mobile(user, dingdingapi.MsgTypeMarkdown, title, alarmTextStr) - } else if len(userMapTxt[user.GetID()]) > 0 { - var txtAlarm []string - for _, v := range userMapTxt[user.GetID()] { - curSnapshot := curSnapshotMap[v.GenMapKey()] - // storeDetail := storeDetailMap[v.StoreID] - curStoreStatus := "下线" - if curSnapshot != nil { - curStoreStatus = model.StoreStatusName[curSnapshot.Status] - } - txtAlarm = append(txtAlarm, fmt.Sprintf("您的门店:%s,平台:%s,%s了", v.StoreName, model.VendorChineseNames[v.VendorID], curStoreStatus)) - } - alarmTextStr := strings.Join(txtAlarm, ",\n") - sendStoreStatusInfo2Mobile(user, dingdingapi.MsgTyeText, title, alarmTextStr) - } - return nil, nil - }, userList) - tasksch.HandleTask(task, parentTask, true).Run() - _, err = task.GetResult(0) - } - return err -} - -func sendStoreStatusInfo2Mobile(user *model.User, msgType, title, txtAlarm string) { - msg.SendUserMessage(msgType, user, title, txtAlarm) -} - -func SaveAndSendAlarmVendorSnapshot(ctx *jxcontext.Context, vendorIDs, storeIDs []int, isAsync bool) (err error) { - curSnapshotAt := getCurrentSnapshotAt(time.Now()) - prevSnapshotAt := getCurrentSnapshotAt(curSnapshotAt.Add(-1 * time.Second)) - db := dao.GetDB() - var curSnapshotList, prevSnapshotList []*model.VendorStoreSnapshot - task := tasksch.NewParallelTask("SaveAndSendAlarmVendorSnapshot", tasksch.NewParallelConfig().SetIsContinueWhenError(true).SetParallelCount(1), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - step := batchItemList[0].(int) - switch step { - case 0: - curSnapshotList, err = GetStoresVendorSnapshot(ctx, task, vendorIDs, storeIDs) - if len(curSnapshotList) == 0 { - task.Cancel() - } else { - updateVendorStoreStatusBySnapshot(db, curSnapshotList) - } - case 1: - err = SaveStoresVendorSnapshot(db, curSnapshotAt, curSnapshotList) - case 2: - prevSnapshotList, err = dao.GetVendorStoreSnapshot(db, prevSnapshotAt) - case 3: - err = SendAlarmVendorSnapshot(ctx, task, prevSnapshotList, curSnapshotList) - } - return nil, err - }, []int{0, 1, 2, 3}) - tasksch.ManageTask(task).Run() - if !isAsync { - _, err = task.GetResult(0) - } - return err -} - -func SyncStoresCourierInfo(ctx *jxcontext.Context, storeIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { - db := dao.GetDB() - storeList2, err := dao.GetStoreList(db, storeIDs, nil, nil, nil, "") - var storeList []*model.Store - for _, v := range storeList2 { - if v.Status != model.StoreStatusDisabled { - storeList = append(storeList, v) - } - } - if err == nil && len(storeList) > 0 { - task := tasksch.NewParallelTask(fmt.Sprintf("同步门店快递信息1:%v", storeIDs), - tasksch.NewParallelConfig().SetParallelCount(2).SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - store := batchItemList[0].(*model.Store) - subTask := tasksch.NewParallelTask(fmt.Sprintf("同步门店快递信息2:%d", store.ID), - tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - vendorID := batchItemList[0].(int) - storeDetail2, err := dao.GetStoreDetail2(db, store.ID, "", vendorID) - if err == nil && storeDetail2.VendorStoreID != "" /*&& storeDetail2.CourierStatus != model.StoreStatusDisabled*/ { - if handler := partner.GetDeliveryPlatformFromVendorID(vendorID); handler != nil { - if updateHandler, ok := handler.Handler.(partner.IDeliveryUpdateStoreHandler); ok { - updateHandler.UpdateStore(ctx, storeDetail2) - } - storeCourier, err2 := handler.Handler.GetStore(ctx, store.ID, storeDetail2.VendorStoreID) - if err = err2; err == nil { - if storeDetail2.AuditStatus == model.StoreAuditStatusCreated { // 如果已经通过审核,更新本地状态 - partner.CurStoreManager.OnCourierStoreStatusChanged(ctx, storeCourier.VendorStoreID, vendorID, storeCourier.AuditStatus) - } - - distance := jxutils.EarthDistance(jxutils.IntCoordinate2Standard(store.Lng), jxutils.IntCoordinate2Standard(store.Lat), jxutils.IntCoordinate2Standard(storeCourier.Lng), jxutils.IntCoordinate2Standard(storeCourier.Lat)) - params := map[string]interface{}{ - "Lng": storeCourier.Lng, - "Lat": storeCourier.Lat, - "Remark": fmt.Sprintf("%d", int(distance*1000)), - } - _, err = dao.UpdateEntityLogically(dao.GetDB(), &model.StoreCourierMap{}, params, ctx.GetUserName(), map[string]interface{}{ - "StoreID": store.ID, - "VendorID": vendorID, - }) - if distance > 0.2 { - globals.SugarLogger.Infof("SyncStoresCourierInfo [运营2]门店:%s-%d的%s配送门店坐标不一致,京西:%d,%d,平台:%d,%d,距离:%f公里", store.Name, store.ID, model.VendorChineseNames[vendorID], store.Lng, store.Lat, storeCourier.Lng, storeCourier.Lat, distance) - retVal = [][]interface{}{ - []interface{}{ - store, - storeDetail2, - }, - } - } - } else if handler.Handler.IsErrStoreNotExist(err) { - if storeDetail2.AuditStatus == model.StoreAuditStatusCreated { - err = nil - } else { - globals.SugarLogger.Infof("SyncStoresCourierInfo [运营2]门店:%s-%d的%s配送门店%s获取出错:%v", store.Name, store.ID, model.VendorChineseNames[vendorID], storeDetail2.VendorStoreID, err) - } - } - } - } else if dao.IsNoRowsError(err) { - err = nil - } - return retVal, err - }, partner.UseableDeliveryVendorIDs) - tasksch.HandleTask(subTask, task, true).Run() - retVal, err = subTask.GetResult(0) - return retVal, err - }, storeList) - tasksch.HandleTask(task, nil, true).Run() - if isAsync { - hint = task.GetID() - } else { - resultList, err2 := task.GetResult(0) - if err = err2; err == nil { - hint = utils.Int2Str(len(resultList)) - } - } - } - return hint, err -} - -func SyncStoresQualify(ctx *jxcontext.Context, storeIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { - if len(storeIDs) > 0 { - db := dao.GetDB() - task := tasksch.NewParallelTask(fmt.Sprintf("上传门店资质:%v", storeIDs), tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - vendorID := model.VendorIDJD - if handler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IStoreSyncQualifyHandler); handler != nil { - storeID := batchItemList[0].(int) - storeDetail, err2 := dao.GetStoreDetail(db, storeID, vendorID) - if err = err2; err == nil { - if err = handler.SyncQualify(ctx, storeDetail); err == nil { - retVal = []int{1} - } - } - } else { - err = fmt.Errorf("平台%s不支持此操作", model.VendorChineseNames[vendorID]) - } - return retVal, err - }, storeIDs) - tasksch.HandleTask(task, nil, true).Run() - if isAsync { - hint = task.GetID() - } else { - resultList, err2 := task.GetResult(0) - if err = err2; err == nil { - hint = utils.Int2Str(len(resultList)) - } - } - } - return hint, err -} - -func JdStoreInfoCoordinateRecover(ctx *jxcontext.Context, vendorOrgCode string, files []*multipart.FileHeader) (err error) { - if len(files) == 0 { - return errors.New("没有文件上传!") - } - fileHeader := files[0] - file1, err := fileHeader.Open() - defer file1.Close() - - db := dao.GetDB() - storeList, err := dao.GetStoresMapList(db, []int{model.VendorIDJD}, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, "", "") - if err == nil { - var validStoreList []*dao.StoreDetail - for _, v := range storeList { - if v.Status != model.StoreStatusDisabled && v.CreatedAt.Sub(utils.Str2Time("2019-10-01")) > 0 { - storeInfo, err := jd.GetAPI(vendorOrgCode).GetStoreInfoByStationNo2(v.VendorStoreID) - if err == nil && storeInfo.CreateTime.GoTime().Sub(utils.Str2Time("2019-10-25")) > 0 { - if storeDetail, err := dao.GetStoreDetail(db, v.StoreID, v.VendorID); err == nil { - validStoreList = append(validStoreList, storeDetail) - } - } - } - } - getStoreList := func(lng, lat, lng2, lat2 int) (vendorStoreIDs []string) { - for _, v := range validStoreList { - if v.Lng >= lng && v.Lng <= lng2 && v.Lat >= lat && v.Lat <= lat2 { - vendorStoreIDs = append(vendorStoreIDs, v.VendorStoreID) - } - } - return vendorStoreIDs - } - sheetName := "老格明细" - file, err2 := excelize.OpenReader(file1) - if err = err2; err == nil { - rows, err2 := file.GetRows(sheetName) - if err = err2; err == nil { - str2Coords := func(str string) (lng, lat int) { - list := strings.Split(str, ",") - if len(list) >= 2 { - lng, lat = jxutils.StandardCoordinate2Int(utils.Str2Float64WithDefault(list[1], 0)), jxutils.StandardCoordinate2Int(utils.Str2Float64WithDefault(list[0], 0)) - } - return lng, lat - } - for i := 1; i < len(rows); i++ { - lng, lat := str2Coords(rows[i][8]) - lng2, lat2 := str2Coords(rows[i][7]) - vendorStoreIDs := getStoreList(lng, lat, lng2, lat2) - countInfo := fmt.Sprintf("京西已拓%d", len(vendorStoreIDs)) - axis, _ := excelize.CoordinatesToCellName(5, i+1) - file.SetCellStr(sheetName, axis, countInfo) - axis2, _ := excelize.CoordinatesToCellName(6, i+1) - file.SetCellStr(sheetName, axis2, strings.Join(vendorStoreIDs, ",")) - } - filename := ExecuteFileName(fileHeader.Filename) - buf := bytes.NewBuffer(nil) - if _, err = io.Copy(buf, file1); err != nil { - return err - } - baseapi.SugarLogger.Debugf("WriteToExcel:save %s success", filename) - downloadURL, err := jxutils.UploadExportContent(buf.Bytes(), filename) - if err != nil { - baseapi.SugarLogger.Errorf("WriteToExcel:upload %s, failed error:%v", filename, err) - } else { - if authInfo, err := ctx.GetV2AuthInfo(); err == nil { - noticeMsg := fmt.Sprintf("path=%s\n", downloadURL) - ddmsg.SendUserMessage(dingdingapi.MsgTyeText, authInfo.UserID, "导出老格恢复拓店进度成功", noticeMsg) - } - baseapi.SugarLogger.Debugf("WriteToExcel:upload %s success, downloadURL:%s", filename, downloadURL) - } - } - } - } - return err -} - -func ExecuteFileName(filename string) (name string) { - filePrefix := filename[strings.LastIndex(filename, "."):len(filename)] - fileRealName := filename[0:strings.LastIndex(filename, ".")] - name = fileRealName + utils.Int64ToStr(time.Now().Unix()) + filePrefix - return name -} - -func GetVendorStoreInfo(ctx *jxcontext.Context, vendorIDList []int, isAsync, isContinueWhenError bool) (hint string, err error) { - var ( - storeListJD []VendorStoreExcel - storeListMT []VendorStoreExcel - storeListEB []VendorStoreExcel - storeIDs []string - ) - taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - for _, vendorID := range vendorIDList { - iStoreHandler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IStoreHandler) - if vendorID == model.VendorIDEBAI { - storeIDs, err = ebai.CurPurchaseHandler.GetShopIDsByPage() - } else { - storeIDs, err = iStoreHandler.GetAllStoresVendorID(ctx, "") - } - if err != nil { - return "", err - } - taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - var storeDetail *dao.StoreDetail - storeID := batchItemList[0].(string) - if partner.IsMultiStore(vendorID) { - multiHandler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IMultipleStoresHandler) - storeDetail, err = multiHandler.ReadStore(ctx, "", storeID) - if err != nil { - return retVal, err - } - } else { - singleHandler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreHandler) - storeDetail, err = singleHandler.ReadStore(ctx, "", storeID) - if err != nil { - return retVal, err - } - } - db := dao.GetDB() - storeDetail2, err := dao.GetStoreDetailByVendorStoreID(db, storeDetail.VendorStoreID, vendorID) - if err != nil { - return "", err - } - if storeDetail.Status != model.StoreStatusOpened { - if storeDetail2 != nil { - var storeExcel = VendorStoreExcel{ - StoreID: storeDetail2.ID, - VendorStoreName: storeDetail.Name, - Tel1: storeDetail.Tel1, - Tel2: storeDetail.Tel2, - Address: storeDetail.Address, - Status: StoreStatus2Chinese(storeDetail.Status), - CityName: storeDetail.CityName, - MarketManName: storeDetail2.MarketManName, - OperatorName: storeDetail2.OperatorName, - OperatorName2: storeDetail2.OperatorName2, - OperatorName3: storeDetail2.OperatorName3, - } - retVal = []VendorStoreExcel{storeExcel} - } - } - return retVal, err - } - taskParallel := tasksch.NewParallelTask("获取各平台未营业门店", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, taskFunc, storeIDs) - tasksch.HandleTask(taskParallel, task, true).Run() - storeList, _ := taskParallel.GetResult(0) - for _, v := range storeList { - if vendorID == model.VendorIDJD { - storeListJD = append(storeListJD, v.(VendorStoreExcel)) - } - if vendorID == model.VendorIDEBAI { - storeListEB = append(storeListEB, v.(VendorStoreExcel)) - } - if vendorID == model.VendorIDMTWM { - storeListMT = append(storeListMT, v.(VendorStoreExcel)) - } - } - } - case 1: - WriteToExcelStore(task, storeListJD, storeListMT, storeListEB) - } - return result, err - } - taskSeq := tasksch.NewSeqTask2("导出各平台未营业门店-序列任务", ctx, isContinueWhenError, taskSeqFunc, 2) - tasksch.HandleTask(taskSeq, nil, true).Run() - if !isAsync { - _, err = taskSeq.GetResult(0) - hint = "1" - } else { - hint = taskSeq.GetID() - } - return hint, err -} - -func WriteToExcelStore(task *tasksch.SeqTask, storeListJD, storeListMT, storeListEB []VendorStoreExcel) (err error) { - var sheetList []*excel.Obj2ExcelSheetConfig - var downloadURL, fileName string - if len(storeListJD) > 0 { - excelConf := &excel.Obj2ExcelSheetConfig{ - Title: "京东平台", - Data: storeListJD, - CaptionList: titleListStore, - } - sheetList = append(sheetList, excelConf) - } - if len(storeListMT) > 0 { - excelConf := &excel.Obj2ExcelSheetConfig{ - Title: "美团平台", - Data: storeListMT, - CaptionList: titleListStore, - } - sheetList = append(sheetList, excelConf) - } - if len(storeListEB) > 0 { - excelConf := &excel.Obj2ExcelSheetConfig{ - Title: "饿百平台", - Data: storeListEB, - CaptionList: titleListStore, - } - sheetList = append(sheetList, excelConf) - } - if len(sheetList) == 0 { - return errors.New("所选平台没有未营业的门店!") - } else { - downloadURL, fileName, err = jxutils.UploadExeclAndPushMsg(sheetList, "各平台未营业门店统计") - if err != nil { - baseapi.SugarLogger.Errorf("WriteToExcel:upload %s failed error:%v", fileName, err) - } else { - noticeMsg := fmt.Sprintf("[详情点我]path=%s \n", downloadURL) - task.SetNoticeMsg(noticeMsg) - baseapi.SugarLogger.Debugf("WriteToExcel:upload %s success, downloadURL:%s", fileName, downloadURL) - } - } - return err -} - -func StoreStatus2Chinese(status int) (str string) { - if status == model.StoreStatusOpened { - return "正常营业" - } else if status == model.StoreStatusDisabled { - return "暂停营业" - } else if status == model.StoreStatusClosed { - return "休息中" - } else { - return "未知的营业状态" - } -} - -func GetStorePriceScore(ctx *jxcontext.Context, storeIDs, vendorIDs []int, fromScore, toScore, sort int, snapDate string, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) { - var snapDateParam time.Time - db := dao.GetDB() - if snapDate != "" { - snapDateParam = utils.Str2Time(snapDate) - } - storePriceScore, totalCount, err := dao.GetStorePriceScore(db, storeIDs, vendorIDs, fromScore, toScore, sort, snapDateParam, offset, pageSize) - pagedInfo = &model.PagedInfo{ - Data: storePriceScore, - TotalCount: totalCount, - } - return pagedInfo, err -} - -func CreateStorePriceScore(ctx *jxcontext.Context) (err error) { - db := dao.GetDB() - var snapshotAt time.Time - snapshotAt = utils.Time2Date(time.Now().AddDate(0, 0, -1)) - storePriceScoreSnapshot, err := dao.GetStorePriceScoreSnapshot(db, snapshotAt) - if len(storePriceScoreSnapshot) > 0 { - dao.Begin(db) - defer func() { - if r := recover(); r != nil || err != nil { - dao.Rollback(db) - if r != nil { - panic(r) - } - } - }() - priceReferSnapshotDeleteHis := &model.StorePriceScoreSnapshot{SnapshotAt: snapshotAt.AddDate(0, 0, -7)} - priceReferSnapshotDelete := &model.StorePriceScoreSnapshot{SnapshotAt: snapshotAt} - dao.DeleteEntity(db, priceReferSnapshotDeleteHis, "SnapshotAt") - dao.DeleteEntity(db, priceReferSnapshotDelete, "SnapshotAt") - for _, v := range storePriceScoreSnapshot { - dao.WrapAddIDCULDEntity(v, ctx.GetUserName()) - v.SnapshotAt = snapshotAt - if err = dao.CreateEntity(db, v); err != nil { - return err - } - } - dao.Commit(db) - globals.SugarLogger.Debugf("CreateStorePriceScore") - } - return err -} - -func RefreshJdLevel(ctx *jxcontext.Context) (err error) { - db := dao.GetDB() - storeMapList, err := dao.GetStoresMapList(db, []int{model.VendorIDJD}, nil, nil, model.StoreStatusOpened, -1, "", "") - if len(storeMapList) > 0 { - dao.Begin(db) - defer func() { - if r := recover(); r != nil || err != nil { - dao.Rollback(db) - if r != nil { - panic(r) - } - } - }() - task := tasksch.NewParallelTask("更新京东门店等级", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - v := batchItemList[0].(*model.StoreMap) - var ( - pageLimit = 5 - pageNo = 1 - level string - ) - for ; pageNo < pageLimit+1; pageNo++ { - level, err = jd.GetAPI(v.VendorOrgCode).GetJdStoreLevel(v.VendorOrgCode, v.VendorStoreID, pageNo) - if err != nil { - return retVal, err - } - if level != "" { - break - } - if pageNo == pageLimit { - level = "" - } - } - v.JdStoreLevel = level - _, err = dao.UpdateEntity(db, v, "JdStoreLevel") - return retVal, err - }, storeMapList) - tasksch.HandleTask(task, nil, true).Run() - _, err = task.GetResult(0) - dao.Commit(db) - } - return err -} - -type tJdStoreInfo struct { - model.Store - VendorOrgCode string `orm:"size(32)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空 - - FreightDeductionPack string `orm:"size(32)" json:"freightDeductionPack"` // - - JdCityCode int - JdDistrictCode int - JdStoreStatus int - VendorStoreID string `orm:"column(vendor_store_id)"` - RealLastOperator string - SyncStatus int - VendorStoreName string -} - -func UpdateJdStoreNameAll(ctx *jxcontext.Context) (err error) { - storeMap := map[int]int{ - 100345: 100345, - 100347: 100347, - 100852: 100852, - 101689: 101689, - 102654: 102654, - 102381: 102381, - 102500: 102500, - 102810: 102810, - } - db := dao.GetDB() - userName := ctx.GetUserName() - for _, v := range storeMap { - var stores []*tJdStoreInfo - sql := ` - SELECT - t1.*, city.jd_code jd_city_code, district.jd_code jd_district_code, - t2.status jd_store_status, t2.vendor_store_id, IF(t1.updated_at > t2.updated_at, t1.last_operator, - t2.last_operator) real_last_operator, - t2.sync_status, t2.freight_deduction_pack, t2.vendor_org_code, t2.vendor_store_name - FROM store t1 - JOIN store_map t2 ON t1.id = t2.store_id AND t2.vendor_id = ? - LEFT JOIN place city ON t1.city_code = city.code - LEFT JOIN place district ON t1.district_code = district.code - WHERE t1.id = ? - ORDER BY t2.updated_at - ` - if err = dao.GetRows(db, &stores, sql, model.VendorIDJD, v); err == nil { - for _, store := range stores { - a := jd.GetAPI(store.VendorOrgCode) - storeParams := &jdapi.OpStoreParams{ - StationNo: store.VendorStoreID, - Operator: userName, - Phone: store.Tel1, - Mobile: store.Tel2, - } - if store.SyncStatus&model.SyncFlagDeletedMask == 0 { - storeParams.OutSystemID = utils.Int2Str(int(store.ID)) - } else { - storeParams.OutSystemID = store.VendorStoreID - } - if store.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreName) != 0 { - if store.VendorStoreName != "" { - storeParams.StationName = store.VendorStoreName - } else { - storeParams.StationName = jxutils.ComposeStoreName(store.Name, model.VendorIDJD) - } - storeParams.StationName = utils.LimitUTF8StringLen(storeParams.StationName, jdapi.MaxStoreNameLen) - } - if store.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreAddress) != 0 { - storeParams.StationAddress = store.Address - storeParams.CoordinateType = jdapi.CoordinateTypeAutonavi // 一直用高德 - storeParams.Lng = jxutils.IntCoordinate2Standard(store.Lng) - storeParams.Lat = jxutils.IntCoordinate2Standard(store.Lat) - if store.JdCityCode != 0 { - storeParams.City = store.JdCityCode - } - if store.JdDistrictCode != 0 { - storeParams.County = store.JdDistrictCode - } - } - // if specialDistrictMap[storeParams.County] != 0 { - // storeParams.City = storeParams.County - // storeParams.County = specialDistrictMap[storeParams.County] - // } - storeParams.StoreNotice = store.PromoteInfo - modifyCloseStatus := false - if store.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagDeletedMask|model.SyncFlagStoreStatus) != 0 { - modifyCloseStatus = true - _, storeParams.CloseStatus = jd.JxStoreStatus2JdStatus(jxutils.MergeStoreStatus(store.Status, store.JdStoreStatus)) - } - // fillOpTimeParams(storeParams, store.GetOpTimeList()) - // globals.SugarLogger.Debug(utils.Format4Output(storeParams, false)) - errList := errlist.New() - if globals.EnableJdStoreWrite { - errList.AddErr(a.UpdateStoreInfo4Open2(storeParams, modifyCloseStatus)) - } - err = errList.GetErrListAsOne() - } - } - } - return err -} - -func DeletePrinterSeq(ctx *jxcontext.Context, storeIDs []int) (err error) { - db := dao.GetDB() - for _, v := range storeIDs { - stores, err := dao.GetStoreList(db, []int{v}, nil, nil, nil, "") - if err != nil || len(stores) == 0 { - return err - } - vendorID := stores[0].PrinterVendorID - if vendorID == model.NO { - return fmt.Errorf("该门店没有绑定打印机,ID:[%v],名字:[%v]", stores[0].ID, stores[0].Name) - } - if vendorID == model.VendorIDXiaoWM { - return fmt.Errorf("暂不支持该打印机品牌清空打印队列,[%v]", model.VendorChineseNames[model.VendorIDXiaoWM]) - } - handler := partner.GetPrinterPlatformFromVendorID(vendorID) - err = handler.EmptyPrintList(ctx, stores[0].PrinterSN, stores[0].PrinterKey) - } - return err -} - -func checkYbParams(db *dao.DaoDB, storeMap *model.StoreMap, storeID int) (err error) { - var ( - appID = storeMap.YbAppID - appKey = storeMap.YbAppKey - yinbaoCookie string - storeMap2 *model.StoreMap - ) - if appID == "" { - return fmt.Errorf("绑定银豹平台必须输入appID!") - } - if appKey == "" { - return fmt.Errorf("绑定银豹平台必须输入appKey!") - } - api.YinBaoAPI = yinbaoapi.New(appKey, appID) - _, err = api.YinBaoAPI.QueryProductByBarcode("") - if err != nil { - if errCode, ok := err.(*utils.ErrorWithCode); ok { - if errCode.Code() == yinbaoapi.AppIDErrCode { - return fmt.Errorf("请输入正确的银豹appID!,[%v]", appID) - } - if errCode.Code() == yinbaoapi.AppKeyErrCode { - return fmt.Errorf("请输入正确的银豹appKey!,[%v]", appKey) - } - } - } - storeMaps, err := dao.GetStoresMapList2(db, []int{model.VendorIDYB}, nil, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "", false) - if len(storeMaps) > 0 { - for _, v := range storeMaps { - if v.YbAppID == appID { - return fmt.Errorf("appID和已有店铺重复![%v]", v.StoreID) - } - if v.YbAppKey == appKey { - return fmt.Errorf("appKey和已有店铺重复![%v]", v.StoreID) - } - } - } - stores, err := dao.GetStoreList(db, []int{storeID}, nil, nil, nil, "") - if len(stores) > 0 { - if configs, err := dao.QueryConfigs(dao.GetDB(), "yinbaoCookie", model.ConfigTypeCookie, ""); err == nil { - yinbaoCookie = configs[0].Value - } - api.YinBaoAPI.SetCookie(".POSPALAUTH30220", yinbaoCookie) - result, err := loadSubStoresByUserIdDDLJson() - if err != nil { - return err - } - flag := false - for _, v := range result { - if v.Company == stores[0].Name { - storeMap.VendorStoreID = utils.Int2Str(v.ID) - flag = true - break - } - } - if !flag { - return fmt.Errorf("未在平台上找到该门店,请确保京西门店名和银豹门店名相同!") - } - } - sql := "SELECT * FROM store_map WHERE vendor_id = ? and deleted_at = ? ORDER BY yb_store_prefix DESC LIMIT 1" - sqlParams := []interface{}{model.VendorIDYB, utils.DefaultTimeValue} - err = dao.GetRow(db, &storeMap2, sql, sqlParams) - if err == nil { - prefix := utils.Int64ToStr(utils.Str2Int64(storeMap2.YbStorePrefix) + 1) - realPrefix := prefix - for i := 0; i < 3-len(prefix); i++ { - realPrefix = "0" + realPrefix - } - storeMap.YbStorePrefix = realPrefix - } - return err -} - -func loadSubStoresByUserIdDDLJson() (result []*yinbaoapi.LoadSubStoresByUserIdDDLJsonResult, err error) { - for { - result, err = api.YinBaoAPI.LoadSubStoresByUserIdDDLJson() - if err == nil { - break - } else { - if yinbaoapi.IsErrCookie(err) { - err = ChangeYbCookie() - if err != nil { - break - } - result, err = loadSubStoresByUserIdDDLJson() - } else { - break - } - } - } - return result, err -} - -func ChangeYbCookie() (err error) { - cookie, err := api.YinBaoAPI.TryGetCookie() - if err != nil { - return err - } - api.YinBaoAPI.SetCookie(".POSPALAUTH30220", cookie) - UpdateConfig(jxcontext.AdminCtx, "yinbaoCookie", model.ConfigTypeCookie, cookie) - return err -} - -func GetStoreCategoryMap(ctx *jxcontext.Context, parentID, level int, storeID int) (storeCatMaps []*model.StoreCategoryMap, err error) { - db := dao.GetDB() - storeCatMaps, err = dao.GetStoreCategoryMap(db, parentID, level, storeID, 0) - if err != nil { - return nil, err - } - return storeCatMaps, err -} - -func AddStoreCategoryMap(ctx *jxcontext.Context, storeCategoryMap *model.StoreCategoryMap) (result *model.StoreCategoryMap, err error) { - var ( - db = dao.GetDB() - ) - if storeCategoryMap.Level != 1 { - storeCatMaps, _ := dao.GetStoreCategoryMap(db, -1, 0, storeCategoryMap.StoreID, storeCategoryMap.CategoryID) - if len(storeCatMaps) > 0 { - return nil, fmt.Errorf("已存在绑定的京西分类,分类名:[%v]", storeCatMaps[0].StoreCategoryName) - } - } - storeCategoryMap.StoreCategoryName = strings.Trim(storeCategoryMap.StoreCategoryName, " ") - dao.WrapAddIDCULDEntity(storeCategoryMap, ctx.GetUserName()) - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - if err = dao.CreateEntity(db, storeCategoryMap); err != nil { - dao.Rollback(db) - return nil, err - } - dao.Commit(db) - result = storeCategoryMap - if storeCategoryMap.CategoryID != 0 { - SetStoreCategorySyncStatus2(db, []int{storeCategoryMap.StoreID}, []int{storeCategoryMap.CategoryID}, model.SyncFlagModifiedMask) - } - // _, err = CurVendorSync.SyncCategory(ctx, nil, cat.ID, false, userName) - return result, err -} - -func UpdateStoreCategoryMap(ctx *jxcontext.Context, ID int, storeCategoryMap *model.StoreCategoryMap, isDelete bool) (num int64, err error) { - var ( - db = dao.GetDB() - valid = make(map[string]interface{}) - storeCategoryMap2 = &model.StoreCategoryMap{} - ) - storeCategoryMap2.ID = ID - if err = dao.GetEntity(db, storeCategoryMap2); err != nil { - return 0, err - } - if storeCategoryMap.StoreCategoryName != "" { - valid["storeCategoryName"] = storeCategoryMap.StoreCategoryName - } - if storeCategoryMap.CategoryID != 0 { - valid["categoryID"] = storeCategoryMap.CategoryID - if !isDelete { - storeCatMaps, _ := dao.GetStoreCategoryMap(db, -1, 0, storeCategoryMap2.StoreID, storeCategoryMap.CategoryID) - if len(storeCatMaps) > 0 { - for _, v := range storeCatMaps { - if v.ID != ID { - return 0, fmt.Errorf("已存在绑定的京西分类,分类名:[%v]", storeCatMaps[0].StoreCategoryName) - } - } - } - } - } - if storeCategoryMap.Level != 0 { - valid["level"] = storeCategoryMap.Level - if storeCategoryMap.Level == 2 { - cat2, _ := dao.GetCategories(db, -1, 0, []int{storeCategoryMap.CategoryID}, false) - if len(cat2) > 0 { - if cat2[0].ParentID != storeCategoryMap.ParentID { - return 0, fmt.Errorf("此二级分类只能绑定到对应一级分类下!") - - } - } - } - } - if isDelete { - valid["deletedAt"] = time.Now() - valid["updatedAt"] = time.Now() - valid["lastOperator"] = ctx.GetUserName() - //如果是1级分类则删除下面的子分类 - var catIDs []int - if storeCategoryMap2.Level == 1 { - storeCatMaps, _ := dao.GetStoreCategoryMap(db, storeCategoryMap2.CategoryID, 2, storeCategoryMap2.StoreID, 0) - if len(storeCatMaps) > 0 { - for _, v := range storeCatMaps { - catIDs = append(catIDs, v.CategoryID) - v.DeletedAt = time.Now() - v.LastOperator = ctx.GetUserName() - dao.UpdateEntity(db, v, "DeletedAt", "LastOperator") - } - } - } - // var storeSkus []*model.StoreSkuBind - // sql := ` - // SELECT a.* - // FROM store_sku_bind a - // JOIN sku b ON a.sku_id = b.id - // JOIN sku_name c ON c.id = b.name_id - // WHERE a.deleted_at = ? AND b.deleted_at = ? AND c.deleted_at = ? - // AND c.category_id = ? AND a.store_id = ? - // UNION ALL - // SELECT a.* - // FROM store_sku_bind a - // JOIN sku b ON a.sku_id = b.id - // JOIN sku_name c ON c.id = b.name_id - // JOIN sku_category d ON d.id = c.category_id - // JOIN sku_category e ON e.id = d.parent_id - // WHERE a.deleted_at = ? AND b.deleted_at = ? AND c.deleted_at = ? - // AND e.id = ? AND a.store_id = ? - // ` - // sqlParams := []interface{}{ - // utils.DefaultTimeValue, utils.DefaultTimeValue, utils.DefaultTimeValue, - // storeCategoryMap2.CategoryID, storeCategoryMap2.StoreID, - // utils.DefaultTimeValue, utils.DefaultTimeValue, utils.DefaultTimeValue, - // storeCategoryMap2.CategoryID, storeCategoryMap2.StoreID, - // } - // if err = dao.GetRows(db, &storeSkus, sql, sqlParams); err != nil { - // return 0, err - // } - // if len(storeSkus) > 0 { - // return 0, fmt.Errorf("该分类下或该分类的子分类下有关注的商品,不可删除!分类名:[%v]", storeCategoryMap2.StoreCategoryName) - // } - catIDs = append(catIDs, storeCategoryMap.CategoryID) - SetStoreCategorySyncStatus2(db, []int{storeCategoryMap2.StoreID}, catIDs, model.SyncFlagModifiedMask) - } else { - SetStoreCategorySyncStatus2(db, []int{storeCategoryMap2.StoreID}, []int{storeCategoryMap.CategoryID, storeCategoryMap2.CategoryID}, model.SyncFlagModifiedMask) - } - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - if num, err = dao.UpdateEntityLogically(db, storeCategoryMap2, valid, ctx.GetUserName(), nil); err != nil { - dao.Rollback(db) - return 0, err - } - dao.Commit(db) - return num, err -} - -func ReorderStoreCategories(ctx *jxcontext.Context, parentID, storeID int, categoryIDs []int) (err error) { - var ( - storeCatsMap []*model.StoreCategoryMap - ) - db := dao.GetDB() - storeCatsMap, err = dao.GetStoreCategoryMap(db, parentID, 0, storeID, 0) - catsLen := len(storeCatsMap) - if catsLen != len(categoryIDs) { - return ErrInputCatsDoesntMatch - } - catsMap := make(map[int]*model.StoreCategoryMap, catsLen) - for _, cat := range storeCatsMap { - catsMap[cat.CategoryID] = cat - } - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - for k, v := range categoryIDs { - if catsMap[v] == nil { - dao.Rollback(db) - return fmt.Errorf("分类:%d不在%d分类下", v, parentID) - } - catsMap[v].StoreCategorySeq = k - catsMap[v].LastOperator = ctx.GetUserName() - if _, err = dao.UpdateEntity(db, catsMap[v]); err != nil { - dao.Rollback(db) - return err - } - } - dao.Commit(db) - SetStoreCategorySyncStatus2(db, nil, categoryIDs, model.SyncFlagModifiedMask) - if err == nil { - CurVendorSync.SyncStoresCategory(ctx, db, nil, nil, false, true, true) - } - return err -} - -func CopyStoreCategories(ctx *jxcontext.Context, fromStoreID int, toStoreIDs, categoryIDs []int, isContinueWhenError, isAsync bool) (hint string, err error) { - var ( - db = dao.GetDB() - ) - storeCatList, err := dao.GetStoreCategoryMap(db, -1, 0, fromStoreID, 0) - if err != nil { - return "", err - } - if len(storeCatList) == 0 { - return "", fmt.Errorf("原门店无分类信息!storeID: %v", fromStoreID) - } - task := tasksch.NewParallelTask("CopyStoreCategories", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeID := batchItemList[0].(int) - //证明是要全复制 - if len(categoryIDs) == 0 { - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - sql := ` - DELETE FROM store_category_map WHERE store_id = ? - ` - sqlParams := []interface{}{storeID} - if _, err = dao.ExecuteSQL(db, sql, sqlParams); err != nil { - return retVal, err - } - sql2 := ` - INSERT INTO store_category_map(created_at,updated_at,last_operator,deleted_at,store_id,category_id,store_category_name,store_category_seq,level,parent_id) - SELECT ?, ?, ?, ?, ?, category_id, store_category_name, store_category_seq, level, parent_id - FROM store_category_map - WHERE store_id = ? AND deleted_at = ? - ` - sqlParams2 := []interface{}{ - time.Now(), time.Now(), ctx.GetUserName(), utils.DefaultTimeValue, storeID, - fromStoreID, utils.DefaultTimeValue, - } - if _, err = dao.ExecuteSQL(db, sql2, sqlParams2); err != nil { - return retVal, err - } - dao.Commit(db) - } else { - for _, v := range categoryIDs { - list, err := dao.GetStoreCategoryMap(db, -1, 0, storeID, v) - if err != nil { - return retVal, err - } - if len(list) > 0 { - return retVal, fmt.Errorf("该门店已有重复绑定的京西分类!storeID: %v,categroyID: %v", storeID, v) - } else { - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - sql2 := ` - INSERT INTO store_category_map(created_at,updated_at,last_operator,deleted_at,store_id,category_id,store_category_name,store_category_seq,level,parent_id) - SELECT ?, ?, ?, ?, ?, category_id, store_category_name, store_category_seq, level, parent_id - FROM store_category_map - WHERE store_id = ? AND deleted_at = ? AND category_id = ? - ` - sqlParams2 := []interface{}{ - time.Now(), time.Now(), ctx.GetUserName(), utils.DefaultTimeValue, storeID, - fromStoreID, utils.DefaultTimeValue, v, - } - if _, err = dao.ExecuteSQL(db, sql2, sqlParams2); err != nil { - return retVal, err - } - dao.Commit(db) - } - } - } - return retVal, err - }, toStoreIDs) - tasksch.HandleTask(task, nil, true).Run() - if isAsync { - hint = task.GetID() - } else { - _, err = task.GetResult(0) - hint = "1" - } - return hint, err -} - -func DisabledStoreWithoutVendor(ctx *jxcontext.Context, isContinueWhenError, isAsync bool) (hint string, err error) { - var ( - db = dao.GetDB() - ) - stores, err := dao.GetStoreList(db, nil, nil, []int{model.StoreStatusClosed, model.StoreStatusHaveRest, model.StoreStatusOpened}, nil, "") - task := tasksch.NewParallelTask("DisabledStoreWithoutVendor", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - store := batchItemList[0].(*model.Store) - storeMaps, err := dao.GetStoresMapList(db, []int{model.VendorIDYB, model.VendorIDJD, model.VendorIDJX, model.VendorIDEBAI, model.VendorIDMTWM}, []int{store.ID}, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "") - if len(storeMaps) == 0 { - store.Status = model.StoreStatusDisabled - dao.UpdateEntity(db, store, "Status") - } - return retVal, err - }, stores) - tasksch.HandleTask(task, nil, true).Run() - if isAsync { - hint = task.GetID() - } else { - _, err = task.GetResult(0) - hint = "1" - } - return hint, err -} - -func CleanStoreIsBoughtMatter(ctx *jxcontext.Context) (err error) { - //每周一凌晨1点清空 - if int(time.Now().Weekday()) != 1 { - return err - } - db := dao.GetDB() - sql := ` - UPDATE store SET is_bought_matter = ? - ` - sqlParam := []interface{}{model.NO} - _, err = dao.ExecuteSQL(db, sql, sqlParam) - return err -} - -func InsertStoreCategories(ctx *jxcontext.Context, db *dao.DaoDB, storeID int) (err error) { - err = dao.InsertStoreCategories(db, ctx.GetUserName(), storeID) - return err -} - -func DeleteStoreCategroies(ctx *jxcontext.Context, db *dao.DaoDB, storeID int) (err error) { - err = dao.DeleteStoreCategroies(db, ctx.GetUserName(), storeID) - return err -} - -func findSkusBetweenJdsMainStore(db *dao.DaoDB, storeID int) (skus []int) { - var skuMap = make(map[int]int) - storeSkus1, _ := dao.GetStoresSkusInfo(db, []int{model.JdShopMainStoreID}, nil) - storeSkus2, _ := dao.GetStoresSkusInfo(db, []int{storeID}, nil) - for _, v := range storeSkus1 { - if v.Status == model.SkuStatusNormal { - skuMap[v.SkuID] = 1 - } - } - for _, v := range storeSkus2 { - if v.Status == model.SkuStatusNormal && skuMap[v.SkuID] != 0 { - skus = append(skus, v.SkuID) - } - } - return skus -} - -func UpdateStorePricePack(ctx *jxcontext.Context, storeID, vendorID int, pricePack, value string) (err error) { - if err = checkConfig(model.SyncFlagModifiedMask, model.ConfigTypePricePack, pricePack, value); err != nil { - return err - } - db := dao.GetDB() - storeDetail, _ := dao.GetStoreDetail(db, storeID, vendorID) - if storeDetail.PayPercentage > 50 { - return fmt.Errorf("目前只允许扣点的门店修改调价包!") - } - - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - //证明是门店自己的调价包 - if strings.Contains(pricePack, utils.Int2Str(storeID)) { - obj := dao.PricePercentagePack2Obj(value) - realValue, _ := json.Marshal(obj) - // _, err = UpdateConfig(ctx, pricePack, model.ConfigTypePricePack, string(realValue)) - configList, err := dao.QueryConfigs(db, pricePack, model.ConfigTypePricePack, "") - if err != nil { - dao.Rollback(db) - return err - } - if _, err = dao.UpdateEntityLogically(db, configList[0], map[string]interface{}{ - "Value": string(realValue), - }, ctx.GetUserName(), nil); err != nil { - dao.Rollback(db) - return err - } - } else { - //表示门店要改他原有的调价包 - //1、调价包名字要加上门店编号门店名等 - //2、添加config - //3、更新storeVendorMap - //4、同步相关 - pricePack = pricePack + "_" + utils.Int2Str(storeID) + "_" + storeDetail.Name - if err = AddConfig(ctx, pricePack, model.ConfigTypePricePack, value); err != nil { - dao.Rollback(db) - return err - } - storeMapList, err := dao.GetStoresMapList(db, []int{vendorID}, []int{storeID}, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "") - if err != nil { - dao.Rollback(db) - return err - } - if len(storeMapList) > 0 { - storeMapList[0].PricePercentagePack = pricePack - dao.UpdateEntity(db, storeMapList[0], "PricePercentagePack") - } - } - dao.Commit(db) - storeMapList, err := dao.GetStoresMapList(db, nil, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, pricePack, "") - if err != nil { - dao.Rollback(db) - return err - } - vendorStoreMap := make(map[int][]int) - for _, v := range storeMapList { - vendorStoreMap[v.VendorID] = append(vendorStoreMap[v.VendorID], v.StoreID) - } - for vendorID, storeIDs := range vendorStoreMap { - dao.SetStoreSkuSyncStatus(db, vendorID, storeIDs, nil, model.SyncFlagPriceMask) - } - return err -} - -func GetJdDeliveryArea(ctx *jxcontext.Context, storeIDs []int) (err error) { - type tmp struct { - JdID string `json:"jdID"` - S int `json:"s"` - } - type SpecialtyStoreSkus struct { - StoreID int `json:"门店ID"` - StoreName string `json:"门店名"` - City string `json:"城市"` - Area int `json:"面积"` - } - var ( - ss []*tmp - excelTitle = []string{ - "门店ID", - "门店名", - "城市", - "面积", - } - sheetList []*excel.Obj2ExcelSheetConfig - specialtyStoreSkus []*SpecialtyStoreSkus - downloadURL, fileName string - ) - storeMaps, _ := dao.GetStoresMapList(dao.GetDB(), []int{model.VendorIDJD}, storeIDs, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "") - for _, v := range storeMaps { - time.Sleep(time.Second / 3) - station, err := jd.GetAPI("320406").GetDeliveryRangeByStationNo2(v.VendorStoreID) - if err != nil { - continue - } - if station.DeliveryRangeType == 2 { - strs := strings.Split(station.DeliveryRange, ";") - ss = append(ss, &tmp{ - JdID: v.VendorStoreID, - S: utils.Float64TwoInt(math.Ceil((jxutils.ComputeSignedArea(strs[:len(strs)-1])))), - }) - } - } - for i := 0; i < len(ss)-1; i++ { - for j := 0; j < len(ss)-1-i; j++ { - if ss[j].S > ss[j+1].S { - temp := ss[j] - ss[j] = ss[j+1] - ss[j+1] = temp - } - } - } - for _, v := range ss { - storeDetail, _ := dao.GetStoreDetailByVendorStoreID(dao.GetDB(), v.JdID, model.VendorIDJD) - place, _ := dao.GetPlaceByCode(dao.GetDB(), storeDetail.CityCode) - specialtyStoreSku := &SpecialtyStoreSkus{ - StoreID: storeDetail.ID, - StoreName: storeDetail.Name, - City: place.Name, - Area: v.S, - } - specialtyStoreSkus = append(specialtyStoreSkus, specialtyStoreSku) - } - excelConf := &excel.Obj2ExcelSheetConfig{ - Title: "sheet1", - Data: specialtyStoreSkus, - CaptionList: excelTitle, - } - sheetList = append(sheetList, excelConf) - if excelConf != nil { - downloadURL, fileName, err = jxutils.UploadExeclAndPushMsg(sheetList, "面积") - } else { - baseapi.SugarLogger.Debug("WriteToExcel: dataSuccess is nil!") - } - if err != nil { - baseapi.SugarLogger.Errorf("WriteToExcel:upload %s , %s failed error:%v", fileName, err) - } else { - noticeMsg := fmt.Sprintf("[详情点我]%s/billshow/?normal=true&path=%s \n", globals.BackstageHost, downloadURL) - ddmsg.SendUserMessage(dingdingapi.MsgTyeText, ctx.GetUserID(), "异步任务完成", noticeMsg) - baseapi.SugarLogger.Debug("WriteToExcel: dataSuccess downloadURL: [%v]", downloadURL) - } - return err -} - -func UpdateStorePushClient(ctx *jxcontext.Context, storeID int, cID string) (err error) { - var ( - db = dao.GetDB() - ) - storePushClients, err := dao.GetStorePushClient(db, storeID, cID) - if err != nil { - return err - } - if len(storePushClients) == 0 { - storePushClient := &model.StorePushClient{ - StoreID: storeID, - ClientID: cID, - } - dao.WrapAddIDCULDEntity(storePushClient, ctx.GetUserName()) - dao.CreateEntity(db, storePushClient) - } - return err -} - -func CreateStoreAudit(ctx *jxcontext.Context, storeAudit *model.StoreAudit) (err error) { - var ( - db = dao.GetDB() - ) - storeAudits, err := dao.GetStoreAudit(db, []int{model.StoreAuditStatusOnline}, storeAudit.UserID, "") - if len(storeAudits) > 0 { - return fmt.Errorf("您已申请过入驻,请不要重复申请!") - } - if storeAudit.Address == "" { - return fmt.Errorf("门店地址必填!") - } - if storeAudit.Lng == 0 || storeAudit.Lat == 0 { - lng, lat, _ := api.AutonaviAPI.GetCoordinateFromAddressByPage(storeAudit.Address) - if lng != 0 && lat != 0 { - storeAudit.Lng = jxutils.StandardCoordinate2Int(lng) - storeAudit.Lat = jxutils.StandardCoordinate2Int(lat) - } else { - return fmt.Errorf("请填写正确的门店地址!") - } - } - - if storeAudit.UserID == "" { - storeAudit.UserID = ctx.GetUserID() - } - dao.WrapAddIDCULDEntity(storeAudit, ctx.GetUserName()) - dao.CreateEntity(db, storeAudit) - return err -} - -func GetStoreAudit(ctx *jxcontext.Context, statuss []int, keyword, applyTimeStart, applyTimeEnd, auditTimeStart, auditTimeEnd string, pageSize, offset int) (pagedInfo *model.PagedInfo, err error) { - var ( - applyTimeStartp, applyTimeEndp, auditTimeStartp, auditTimeEndp time.Time - db = dao.GetDB() - ) - if applyTimeStart != "" { - applyTimeStartp = utils.Str2Time(applyTimeStart) - } - if applyTimeEnd != "" { - applyTimeEndp = utils.Str2Time(applyTimeEnd) - } - if auditTimeStart != "" { - auditTimeStartp = utils.Str2Time(auditTimeStart) - } - if auditTimeEnd != "" { - auditTimeEndp = utils.Str2Time(auditTimeEnd) - } - pagedInfo, err = dao.GetStoreAuditPage(db, statuss, keyword, applyTimeStartp, applyTimeEndp, auditTimeStartp, auditTimeEndp, pageSize, offset) - return pagedInfo, err -} - -func StoreAudit(ctx *jxcontext.Context, storeAudits []*model.StoreAudit, status int) (hint string, err error) { - db := dao.GetDB() - if status != model.StoreAuditStatusCreated && status != model.StoreAuditStatusRejected { - return "", fmt.Errorf("审核标志不正确!") - } - task := tasksch.NewParallelTask("StoreAudit", tasksch.NewParallelConfig().SetParallelCount(5).SetIsContinueWhenError(true), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeAudit := batchItemList[0].(*model.StoreAudit) - storeAudits, err := dao.GetStoreAudit(db, []int{model.StoreAuditStatusOnline}, storeAudit.UserID, "") - if len(storeAudits) == 0 || err != nil { - return retVal, fmt.Errorf("未查询到待审核信息!") - } - if len(storeAudits) > 1 { - return retVal, fmt.Errorf("查询到该用户的待审核信息大于1条!userID: [%s]", storeAudit.UserID) - } - //审核通过 - if status == model.StoreAuditStatusCreated { - storeAudits[0].AuditStatus = model.StoreAuditStatusCreated - //添加门店 - storeExt := &StoreExt{} - if data, err := json.Marshal(&storeAudits[0]); err == nil { - utils.UnmarshalUseNumber(data, &storeExt) - } - storeExt.ID = 0 - storeExt.Store.StoreLevel = "C" - storeExt.FloatLng = jxutils.IntCoordinate2Standard(utils.Float64TwoInt(storeExt.FloatLng)) - storeExt.FloatLat = jxutils.IntCoordinate2Standard(utils.Float64TwoInt(storeExt.FloatLat)) - storeExt.Status = model.StoreStatusDisabled - storeID, err := CreateStore(ctx, storeExt, ctx.GetUserName()) - if err != nil { - return retVal, fmt.Errorf(err.Error()) - } - err = AddUsers4Role(ctx, autils.NewRole(authz.StoreRoleBoss, storeID), []string{storeAudit.UserID}) - if err != nil { - return retVal, fmt.Errorf(err.Error()) - } - } else if status == model.StoreAuditStatusRejected { - storeAudits[0].AuditStatus = model.StoreAuditStatusRejected - } else { - return retVal, fmt.Errorf("审核标志不正确!") - } - storeAudits[0].LastOperator = ctx.GetUserName() - storeAudits[0].Remark = storeAudit.Remark - _, err = dao.UpdateEntity(db, storeAudits[0], "LastOperator", "AuditStatus", "Remark") - //是否推送app消息 - if err == nil { - - } - return retVal, err - }, storeAudits) - tasksch.HandleTask(task, nil, true).Run() - hint = task.GetID() - return hint, err -} - -func GetDiffJxStoreAndMTWMStoreInfo(ctx *jxcontext.Context, storeIDs []int) (err error) { - type TmpDiffStore struct { - StoreID int `json:"门店ID"` - StoreName string `json:"门店名"` - City string `json:"城市"` - Coordinate string `json:"坐标"` - Address string `json:"地址"` - Phone string `json:"电话"` - CoordinateMT string `json:"坐标(美团)"` - AddressMT string `json:"地址(美团)"` - PhoneMT string `json:"电话(美团)"` - Comment string `json:"对比情况"` - } - var ( - excelTitle = []string{ - "门店ID", - "门店名", - "城市", - "坐标", - "地址", - "电话", - "坐标(美团)", - "地址(美团)", - "电话(美团)", - "对比情况", - } - sheetList []*excel.Obj2ExcelSheetConfig - tmpDiffStoreList []*TmpDiffStore - downloadURL, fileName string - db = dao.GetDB() - ) - courierStoreList, _ := dao.GetStoreCourierList(db, storeIDs, []int{model.VendorIDMTPS}, model.StoreStatusAll, model.StoreAuditStatusAll) - for _, v := range courierStoreList { - comment := "" - tmpDiffStore := &TmpDiffStore{ - StoreID: v.StoreID, - } - stores, err := dao.GetStoreList(db, []int{v.StoreID}, nil, nil, nil, "") - store := stores[0] - place, _ := dao.GetPlaceByCode(db, store.CityCode) - tmpDiffStore.City = place.Name - tmpDiffStore.StoreName = store.Name - tmpDiffStore.Coordinate = utils.Float64ToStr(jxutils.IntCoordinate2Standard(store.Lng)) + "," + utils.Float64ToStr(jxutils.IntCoordinate2Standard(store.Lat)) - tmpDiffStore.Address = store.Address - tmpDiffStore.Phone = store.Tel1 - shopInfo, err := api.MtpsAPI.ShopQuery(v.VendorStoreID) - if err != nil { - tmpDiffStore.Comment += err.Error() - tmpDiffStoreList = append(tmpDiffStoreList, tmpDiffStore) - continue - } - tmpDiffStore.CoordinateMT = utils.Float64ToStr(jxutils.IntCoordinate2Standard(shopInfo.ShopLng)) + "," + utils.Float64ToStr(jxutils.IntCoordinate2Standard(shopInfo.ShopLat)) - tmpDiffStore.AddressMT = shopInfo.ShopAddress - tmpDiffStore.PhoneMT = shopInfo.ContactPhone - if tmpDiffStore.Coordinate != tmpDiffStore.CoordinateMT { - comment += "坐标不同;" - } - if tmpDiffStore.Address != tmpDiffStore.AddressMT { - comment += "地址不同;" - } - if tmpDiffStore.Phone != tmpDiffStore.PhoneMT { - comment += "电话不同;" - } - tmpDiffStore.Comment = comment - if comment != "" { - tmpDiffStoreList = append(tmpDiffStoreList, tmpDiffStore) - } - } - - excelConf := &excel.Obj2ExcelSheetConfig{ - Title: "sheet1", - Data: tmpDiffStoreList, - CaptionList: excelTitle, - } - sheetList = append(sheetList, excelConf) - if excelConf != nil { - downloadURL, fileName, err = jxutils.UploadExeclAndPushMsg(sheetList, "美团配送信息对比") - } else { - baseapi.SugarLogger.Debug("WriteToExcel: dataSuccess is nil!") - } - if err != nil { - baseapi.SugarLogger.Errorf("WriteToExcel:upload %s , %s failed error:%v", fileName, err) - } else { - noticeMsg := fmt.Sprintf("[详情点我]%s/billshow/?normal=true&path=%s \n", globals.BackstageHost, downloadURL) - ddmsg.SendUserMessage(dingdingapi.MsgTyeText, ctx.GetUserID(), "异步任务完成", noticeMsg) - baseapi.SugarLogger.Debug("WriteToExcel: dataSuccess downloadURL: [%v]", downloadURL) - } - return err -} diff --git a/business/jxstore/cms/store_sku.go b/business/jxstore/cms/store_sku.go deleted file mode 100644 index 4158ee3ce..000000000 --- a/business/jxstore/cms/store_sku.go +++ /dev/null @@ -1,5125 +0,0 @@ -package cms - -import ( - "errors" - "fmt" - "io" - "math" - "mime/multipart" - "sort" - "strconv" - "strings" - "sync" - "time" - "unicode" - - "git.rosy.net.cn/jx-callback/business/auth2" - - "github.com/astaxie/beego" - - "git.rosy.net.cn/baseapi/platformapi/jdshopapi" - - "git.rosy.net.cn/jx-callback/globals/api" - - "git.rosy.net.cn/jx-callback/globals/refutil" - - "git.rosy.net.cn/jx-callback/business/jxstore/event" - - "git.rosy.net.cn/baseapi" - - "git.rosy.net.cn/jx-callback/business/jxutils/ddmsg" - "git.rosy.net.cn/jx-callback/business/jxutils/excel" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/partner/purchase/jd" - "git.rosy.net.cn/jx-callback/globals/api/apimanager" - - "git.rosy.net.cn/jx-callback/business/partner" - - "git.rosy.net.cn/baseapi/platformapi/dingdingapi" - "git.rosy.net.cn/baseapi/platformapi/jdapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/baseapi/utils/errlist" - "git.rosy.net.cn/jx-callback/business/auth2/authprovider/weixin" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/weixinmsg" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/globals" - "github.com/360EntSecGroup-Skylar/excelize" - "github.com/astaxie/beego/orm" -) - -const ( - MaxSkuUnitPrice = 500000 - - CopyStoreSkuModeFresh = "fresh" // 全新复制 - CopyStoreSkuModeUpdate = "update" // 增量复制 - CopyStoreSkuModeUpdatePrice = "updatePrice" // 增量复制价格 -) - -//通用写入Excel -type ExcelParam struct { - DataList interface{} - SheetName string - TitleList []string -} - -// UpdateStoreSku用,API调用时 -type StoreSkuBindSkuInfo struct { - SkuID int `json:"skuID"` - IsSale int `json:"isSale,omitempty"` // -1:不可售,0:忽略,1:可售 - Stock *int `json:"stock"` - // ElmID int64 `json:"elmID,omitempty"` - // EbaiID int64 `json:"ebaiID,omitempty"` -} - -// UpdateStoreSku用,API调用时 -type StoreSkuBindInfo struct { - StoreID int `json:"storeID"` - NameID int `json:"nameID"` - UnitPrice int `json:"unitPrice"` // 对于是份的SKU就是单价(每斤价格),其它则为总价 - IsFocus int `json:"isFocus"` // -1:不关注,0:忽略,1:关注 - IsSale int `json:"isSale"` // -1:不可售,0:忽略,1:可售 - SubStoreID int `json:"subStoreID,omitempty"` - StatusSaleBegin int16 `json:"statusSaleBegin" validate:"max=2359,min=1,ltfield=StatusSaleEnd"` //商品可售时间范围 - StatusSaleEnd int16 `json:"statusSaleEnd" validate:"max=2359,min=1"` - Skus []*StoreSkuBindSkuInfo `json:"skus,omitempty"` -} - -type tStoreSkuBindAndSpec struct { - model.StoreSkuBind - SkuStatus int - SkuNameStatus int - Name string - SpecQuality float32 - SpecUnit string - SkuNamePrice int - SkuNameUnit string - RealSkuID int `orm:"column(real_sku_id)"` - ExdSkuID string `orm:"column(exd_sku_id)"` - StoreName string - ChangePriceType int8 `json:"changePriceType"` // 修改价格类型,即是否需要审核 - NameID int `orm:"column(name_id)" json:"nameID"` -} - -type SkuSaleInfo struct { - StoreID int `orm:"column(store_id)"` - SkuID int `orm:"column(sku_id)"` - Times int // 销售的次数 - Count int // 销售的总份数 -} - -type StoreOpRequestInfo struct { - model.StoreOpRequest - StoreName string `json:"storeName"` - SkuNamePrefix string `json:"skuNamePrefix"` - SkuNameName string `json:"skuNameName"` - UnitPrice int `json:"unitPrice"` -} - -type tStoreNameBind struct { - StoreID int `orm:"column(store_id)"` - NameID int `orm:"column(name_id)"` - Name string -} - -type tGetStoresSkusInfo struct { - StoreID int `orm:"column(store_id)"` - StoreName string - - model.SkuName - PayPercentage int `json:"-"` - dao.StoreSkuExt - RealMidUnitPrice int `json:"realMidUnitPrice"` //真实的该商品的全国中位价 - YbSkuName string - AuditUnitPrice int -} - -type SheetParam struct { - OutSkuIDCol int - SkuNameIDCol int - SkuPriceCol int - SkuNameCol int - SkuUnitCol int - SkuRow int -} - -type DataVendorStoreSkuPrice struct { - StoreID string `json:"门店ID"` - StoreName string `json:"门店名"` - SkuID int `json:"商品ID"` - SkuName string `json:"商品名"` - VendorPrice string `json:"平台价"` -} - -type DataSuccess struct { - NameID int `json:"商品NameID"` - Name string `json:"商品名称"` - Unit string `json:"单位"` - OrgPrice float64 `json:"原价"` - NowPrice float64 `json:"现价"` - MixPrice float64 `json:"涨跌"` -} - -type DataFailed struct { - NameID int `json:"商品NameID"` - Name string `json:"商品名称"` - Comment string `json:"备注"` -} - -type DataLock struct { - dataSuccessList []DataSuccess - dataFailedList []DataFailed - locker sync.RWMutex -} - -type tUpdateStoresSkus struct { - StoreID int - SkuBindInfos []*StoreSkuBindInfo -} - -type tStoreSkusSecKill struct { - StoreID int `orm:"column(store_id)"` - VendorID int `orm:"column(vendor_id)"` - SecKillCount int - SecKillCount2 int - OperatorPhoneList []string - MarketManPhone string - NoticeMsg string -} - -type JdStoreSkus struct { - JdStoreID int `json:"jdStoreID"` - JdSkuID int `json:"jdSkuID"` - Price int `json:"price"` -} - -type tUpdateSkuSpecTag struct { - StoreID int `json:"storeID"` - SkuID int `json:"skuID"` - IsSpec int `json:"isSpec"` -} - -type MatterStock struct { - SkuID int `json:"skuID"` - SkuNameID int `json:"skuNameID"` - Name string `json:"name"` - Stock int `json:"stock"` -} - -type ActStoreSkuParam struct { - model.ActStoreSku - - ActualActPrice int64 `json:"actualActPrice,omitempty"` // 单品级活动用,创建活动时商品的活动价格 - VendorPrice int64 `json:"vendorPrice,omitempty"` // 创建活动时的平台价格 - ErrMsg string `json:"errMsg,omitempty"` -} - -const ( - maxStoreNameBind = 10000 // 最大门店SkuName bind个数 - maxStoreNameBind2 = 10000 // 最大门店乘SkuName个数 - - AutoSaleAtStr = "22:00:00" -) - -var ( - asyncOpMobileMap = map[string]int{ - "18982250714": 1, // 老赵 - "18180948107": 1, // 徐 - // "13684045763": 1, // 周 - } - dataLock DataLock - titleListVendorStoreSkuPrice = []string{ - "门店ID", - "门店名", - "商品ID", - "商品名", - "平台价", - } - titleListSuccess = []string{ - "商品NameID", - "商品名称", - "单位", - "原价", - "现价", - "涨跌", - } - titleListFailed = []string{ - "商品NameID", - "商品名称", - "备注", - } - autoNotFoucsStoreMap = map[int]int{ - 667088: 667088, - model.MatterStoreID: model.MatterStoreID, - 103038: 103038, - 300397: 300397, - } -) - -func GetStoreSkus(ctx *jxcontext.Context, storeID int, skuIDs []int, isFocus bool, keyword string, isBySku, isAct bool, params map[string]interface{}, offset, pageSize int) (skuNamesInfo *dao.StoreSkuNamesInfo, err error) { - return GetStoresSkus(ctx, []int{storeID}, skuIDs, isFocus, false, 0, keyword, isBySku, isAct, params, offset, pageSize) -} - -func getGetStoresSkusBaseSQL(db *dao.DaoDB, storeIDs, skuIDs []int, isFocus bool, keyword string, isBySku, isAct, isHighPrice bool, priceType int, actVendorID int, params map[string]interface{}) (sql string, sqlParams []interface{}, err error) { - sql = ` - FROM sku_name t1 - JOIN sku t2 FORCE INDEX(PRIMARY) ON t1.id = t2.name_id AND t2.deleted_at = ?/* AND t2.status = ?*/ - JOIN store t3 ON t3.deleted_at = ? - LEFT JOIN store_map sm ON sm.store_id = t3.id AND sm.vendor_id = ? AND sm.deleted_at = ? - LEFT JOIN store_map smm ON smm.store_id = t3.id AND smm.deleted_at = ? AND smm.vendor_id = ? - LEFT JOIN thing_map t2m ON t2m.thing_type = ? AND t2m.thing_id = t2.id AND t2m.vendor_id = sm.vendor_id AND t2m.vendor_org_code = sm.vendor_org_code AND t2m.deleted_at = ? - ` - sqlParams = []interface{}{ - utils.DefaultTimeValue, - // model.SkuStatusNormal, - utils.DefaultTimeValue, - model.VendorIDJD, utils.DefaultTimeValue, // TODO 这里直接用JD有问题 - utils.DefaultTimeValue, model.VendorIDYB, - model.ThingTypeSku, utils.DefaultTimeValue, - } - if isFocus { - if isAct { - sql += ` - JOIN ( - SELECT t2.store_id, t2.sku_id, - MIN(IF(t3.actual_act_price <= 0, NULL, t3.actual_act_price)) actual_act_price, /*non-zero min value*/ - MIN(IF(t2.earning_price <= 0, NULL, t2.earning_price)) earning_price /*non-zero min value*/ - FROM act t1 - JOIN act_store_sku t2 ON t2.act_id = t1.id AND t2.deleted_at = ? - JOIN act_store_sku_map t3 ON t3.bind_id = t2.id AND t3.act_id = t1.id AND (t3.sync_status & ? = 0 OR t1.type = ?) - JOIN act_map t4 ON t4.act_id = t1.id AND t4.vendor_id = t3.vendor_id AND t4.deleted_at = ? AND (t4.sync_status & ? = 0 OR t1.type = ?) - WHERE t1.deleted_at = ? AND t1.status = ? AND NOT (t1.begin_at > ? OR t1.end_at < ?)` - sqlParams = append(sqlParams, []interface{}{ - utils.DefaultTimeValue, - model.SyncFlagNewMask, - model.ActSkuFake, - utils.DefaultTimeValue, - model.SyncFlagNewMask, - model.ActSkuFake, - utils.DefaultTimeValue, - model.ActStatusCreated, - time.Now(), - time.Now(), - }) - if actVendorID >= 0 { - sql += " AND t1.vendor_mask & ? <> 0" - sqlParams = append(sqlParams, model.GetVendorMask(actVendorID)) - } - if len(storeIDs) > 0 { - sql += " AND t2.store_id IN (" + dao.GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - if len(skuIDs) > 0 { - sql += " AND t2.sku_id IN (" + dao.GenQuestionMarks(len(skuIDs)) + ")" - sqlParams = append(sqlParams, skuIDs) - } - sql += ` - GROUP BY 1,2 - ) ta ON ta.store_id = t3.id AND ta.sku_id = t2.id` - } - } else { - sql += " LEFT" - } - sql += ` - JOIN store_sku_bind t4 ON t4.store_id = t3.id AND t4.sku_id = t2.id AND t4.deleted_at = ? - LEFT JOIN sku_name_place_bind t5 ON t1.id = t5.name_id AND t3.city_code = t5.place_code - LEFT JOIN price_refer_snapshot t6 ON t6.city_code = ? AND t6.sku_id = t2.id AND t6.snapshot_at = ? - LEFT JOIN store_sku_audit t7 ON t7.store_id = t3.id AND t7.name_id = t1.id AND t7.status = ? AND t7.deleted_at = ? - WHERE t1.deleted_at = ? AND (t1.is_global = 1 OR t5.id IS NOT NULL OR 1 = ?)/* AND t1.status = ?*/ - ` - sqlParams = append(sqlParams, []interface{}{ - utils.DefaultTimeValue, - 0, utils.Time2Date(time.Now().AddDate(0, 0, -1)), - model.StoreAuditStatusOnline, utils.DefaultTimeValue, - utils.DefaultTimeValue, - utils.Bool2Int(isFocus), - }) - if isHighPrice || priceType == 1 { - sql += " AND t4.unit_price > t6.mid_unit_price / IF(t3.pay_percentage < 50 , 70, t3.pay_percentage) * 1.2 * 100" - } - if priceType == -1 { - sql += " AND t4.unit_price < t6.mid_unit_price / IF(t3.pay_percentage < 50 , 70, t3.pay_percentage) / 1.2 * 100" - } - if isFocus { - sql += " AND ((t2.status = ? AND t1.status = ?) OR t4.status = ?)" - sqlParams = append(sqlParams, model.SkuStatusNormal, model.SkuStatusNormal, model.SkuStatusNormal) - } else { - sql += " AND t4.sku_id IS NULL AND (t2.status = ? AND t1.status = ?)" - sqlParams = append(sqlParams, model.SkuStatusNormal, model.SkuStatusNormal) - } - if keyword != "" { - keywordLike := "%" + keyword + "%" - sql += " AND (t1.name LIKE ? OR t1.prefix LIKE ? OR t1.upc LIKE ? OR t2.comment LIKE ?" - sqlParams = append(sqlParams, keywordLike, keywordLike, keywordLike, keywordLike) - - if keywordInt64, err2 := strconv.ParseInt(keyword, 10, 64); err2 == nil { - sql += ` - OR t1.id = ? OR t2.id = ? - OR (SELECT COUNT(*) FROM thing_map tm WHERE tm.vendor_org_code = sm.vendor_org_code AND tm.thing_type = ? AND tm.thing_id = t2.id AND tm.deleted_at = ? AND tm.vendor_thing_id = ?) > 0 - ` - sqlParams = append(sqlParams, - keywordInt64, keywordInt64, - model.ThingTypeSku, utils.DefaultTimeValue, keywordInt64) - if isFocus { - sql += " OR t4.ebai_id = ? OR t4.mtwm_id = ?" - sqlParams = append(sqlParams, keywordInt64, keywordInt64) - } - } - sql += ")" - } - - if params["nameID"] != nil { - sql += " AND t1.id = ?" - sqlParams = append(sqlParams, params["nameID"].(int)) - } - if params["nameIDs"] != nil { - var nameIDs []int - if err = utils.UnmarshalUseNumber([]byte(params["nameIDs"].(string)), &nameIDs); err != nil { - return "", nil, err - } - if len(nameIDs) > 0 { - sql += " AND t1.id IN (" + dao.GenQuestionMarks(len(nameIDs)) + ")" - sqlParams = append(sqlParams, nameIDs) - } - } - if params["categoryID"] != nil { - cat := &model.SkuCategory{} - cat.ID = params["categoryID"].(int) - if err = dao.GetEntity(db, cat); err != nil { - return "", nil, err - } - sql += " AND (t1.category_id = ?" - sqlParams = append(sqlParams, cat.ID) - if cat.Level == 1 { - sql += " OR t1.category_id IN (SELECT id FROM sku_category WHERE parent_id = ?)" - sqlParams = append(sqlParams, cat.ID) - } - sql += ")" - } - if params["name"] != nil { - sql += " AND t1.name LIKE ?" - sqlParams = append(sqlParams, "%"+params["name"].(string)+"%") - } - if params["prefix"] != nil { - sql += " AND t1.prefix LIKE ?" - sqlParams = append(sqlParams, "%"+params["prefix"].(string)+"%") - } - if params["unit"] != nil { - sql += " AND t1.unit = ?" - sqlParams = append(sqlParams, params["unit"].(string)) - } - if len(storeIDs) > 0 { - sql += " AND t3.id IN (" + dao.GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - if len(storeIDs) == 1 { - sql += " AND IF(INSTR(t3.name,'" + model.ExdStoreName + "') > 0, t2.exd_sku_id <> '', t2.exd_sku_id = '')" - } - } - if len(skuIDs) > 0 { - sql += " AND t2.id IN (" + dao.GenQuestionMarks(len(skuIDs)) + ")" - sqlParams = append(sqlParams, skuIDs) - } else if params["skuID"] != nil { - skuID, ok := params["skuID"].(int) - if ok { - skuIDs = append(skuIDs, skuID) - sql += " AND t2.id = ?" - sqlParams = append(sqlParams, skuID) - } - } - if lockTimeStr, ok := params["lockTime"].(string); ok && lockTimeStr != "" { - if timeList, err2 := jxutils.BatchStr2Time(lockTimeStr); err2 == nil { - sql += " AND (t4.jd_lock_time > ? OR t4.mtwm_lock_time > ? OR t4.ebai_lock_time > ? OR t4.jx_lock_time > ?)" - sqlParams = append(sqlParams, timeList[0], timeList[0], timeList[0], timeList[0]) - } - } - if isFocus { - if params["fromStatus"] != nil { - fromStatus := params["fromStatus"].(int) - toStatus := fromStatus - if params["toStatus"] != nil { - toStatus = params["toStatus"].(int) - } - sql += " AND t4.status >= ? AND t4.status <= ?" - sqlParams = append(sqlParams, fromStatus, toStatus) - } - if params["jdSyncStatus"] != nil || params["ebaiSyncStatus"] != nil || params["mtwmSyncStatus"] != nil { - realVendorMap, err2 := getValidStoreVendorMap(db, storeIDs) - if err = err2; err != nil { - return "", nil, err - } - sql += " AND ( 1 = 0" - if params["jdSyncStatus"] != nil && realVendorMap[model.VendorIDJD] == 1 { - sql += " OR (t4.jd_sync_status & ? <> 0 AND t1.status = ? AND t2.status = ?)" - sqlParams = append(sqlParams, params["jdSyncStatus"], model.SkuStatusNormal, model.SkuStatusNormal) - } - if params["ebaiSyncStatus"] != nil && realVendorMap[model.VendorIDEBAI] == 1 { - sql += " OR (t4.ebai_sync_status & ? <> 0 AND NOT (t4.ebai_sync_status & ? <> 0 AND (t4.status <> ? OR t2.status <> ?)) )" - sqlParams = append(sqlParams, params["ebaiSyncStatus"], model.SyncFlagNewMask, model.SkuStatusNormal, model.SkuStatusNormal) - } - if params["mtwmSyncStatus"] != nil && realVendorMap[model.VendorIDMTWM] == 1 { - sql += " OR (t4.mtwm_sync_status & ? <> 0 AND NOT (t4.mtwm_sync_status & ? <> 0 AND (t4.status <> ? OR t2.status <> ?)) )" - sqlParams = append(sqlParams, params["mtwmSyncStatus"], model.SyncFlagNewMask, model.SkuStatusNormal, model.SkuStatusNormal) - } - sql += ")" - } - } - if isFocus { - /*前台传入的最大值和最小值设置*/ - if params["highestPrice"] != "" && params["highestPrice"] != nil { - //highestPrice := utils.Interface2Float64WithDefault(params["highestPrice"], 0) * 100 - sql += " AND t4.unit_price <= ? " - sqlParams = append(sqlParams, params["highestPrice"]) - } - if params["minimumPrice"] != "" && params["minimumPrice"] != nil { - //minimumPrice := utils.Interface2Float64WithDefault(params["minimumPrice"], 0) * 100 - sql += " AND t4.unit_price >= ? " - sqlParams = append(sqlParams, params["minimumPrice"]) - } - } - return sql, sqlParams, err -} - -func GetStoresSkus(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus, isHighPrice bool, priceType int, keyword string, isBySku, isAct bool, params map[string]interface{}, offset, pageSize int) (skuNamesInfo *dao.StoreSkuNamesInfo, err error) { - return GetStoresSkusNew(ctx, storeIDs, skuIDs, isFocus, isHighPrice, priceType, keyword, isBySku, isAct, params, offset, pageSize) -} - -func GetStoresSkusNew(ctx *jxcontext.Context, storeIDs, skuIDs []int, isFocus, isHighPrice bool, priceType int, keyword string, isBySku, isAct bool, params map[string]interface{}, offset, pageSize int) (skuNamesInfo *dao.StoreSkuNamesInfo, err error) { - if !isFocus && !isBySku && (len(storeIDs) > 1 || len(storeIDs) == 0) { - return nil, fmt.Errorf("未关注按SkuName只能查询单店") - } - if len(storeIDs) == 0 && len(skuIDs) == 0 && pageSize == -1 { - return nil, fmt.Errorf("GetStoresSkus必须指定storeIDs或skuIDs或分页") - } - actVendorID := -1 - if params["actVendorID"] != nil { - actVendorID = int(utils.Interface2Int64WithDefault(params["actVendorID"], -1)) - } - var highestPrice, minimumPrice float64 - if params["highestPrice"] != nil { - if highestPrice, err = strconv.ParseFloat(params["highestPrice"].(string), 64); err != nil { - delete(params, "highestPrice") - } else { - params["highestPrice"] = highestPrice * 100 - } - } - if params["minimumPrice"] != nil { - if minimumPrice, err = strconv.ParseFloat(params["minimumPrice"].(string), 64); err != nil { - delete(params, "minimumPrice") - } else { - params["minimumPrice"] = minimumPrice * 100 - } - } - if !(highestPrice > 0 && highestPrice > minimumPrice) || !(highestPrice > 0) { - delete(params, "highestPrice") - } - if !(minimumPrice >= 0 && highestPrice > 0 && highestPrice > minimumPrice) || !(minimumPrice >= 0) { - delete(params, "minimumPrice") - } - db := dao.GetDB() - sql, sqlParams, err := getGetStoresSkusBaseSQL(db, storeIDs, skuIDs, isFocus, keyword, isBySku, isAct, isHighPrice, priceType, actVendorID, params) - if err != nil { - return nil, err - } - pageSize = jxutils.FormalizePageSize(pageSize) - offset = jxutils.FormalizePageOffset(offset) - sqlOffset := offset - sqlPageSize := pageSize - isSaleInfo := params["stFromTime"] != nil - if isSaleInfo { - sqlOffset = 0 - sqlPageSize = jxutils.FormalizePageSize(-1) - } - sqlParamsPage := []interface{}{sqlPageSize, sqlOffset} - - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - catOrderBy := "" - if params["categoryID"] != nil { - catOrderBy = "t2.seq, " - } - - skuNamesInfo = &dao.StoreSkuNamesInfo{} - if !isBySku && sqlPageSize != model.UnlimitedPageSize { - sql2 := ` - SELECT SQL_CALC_FOUND_ROWS - t3.id store_id, t1.id name_id - ` + sql + ` - GROUP BY 1, 2 - ORDER BY 1, 2 - LIMIT ? OFFSET ? - ` - sqlParams2 := append([]interface{}{}, sqlParams...) - sqlParams2 = append(sqlParams2, sqlParamsPage) - var storeNameList []*tStoreNameBind - beginTime := time.Now() - if err = dao.GetRows(db, &storeNameList, sql2, sqlParams2...); err != nil { - dao.Rollback(db) - return nil, err - } - globals.SugarLogger.Debugf("GetStoresSkusNew get result1:%v", time.Now().Sub(beginTime)) - skuNamesInfo.TotalCount = dao.GetLastTotalRowCount(db) - sql += " AND (1 = 0" - for _, v := range storeNameList { - sql += " OR (t1.id = ? AND t3.id = ?)" - sqlParams = append(sqlParams, v.NameID, v.StoreID) - } - sql += fmt.Sprintf(`) - ORDER BY %s t3.id, t2.name_id, t2.id`, catOrderBy) - } else { - if isFocus { - sql += fmt.Sprintf(` - ORDER BY %s t3.id, t2.name_id, t2.id`, catOrderBy) - } - sql += ` - LIMIT ? OFFSET ?` - sqlParams = append(sqlParams, sqlParamsPage) - } - sql = ` - SELECT SQL_CALC_FOUND_ROWS - t3.id store_id, t3.name store_name, t3.pay_percentage, - t1.*, - t2.name_id, t2.id sku_id, t2.spec_quality sku_spec_quality, t2.spec_unit sku_spec_unit, t2.weight, t2m.vendor_thing_id sku_jd_id, - t2.comment, t2.category_id sku_category_id, t2.status sku_status, t2.eclp_id, - t4.created_at bind_created_at, t4.updated_at bind_updated_at, t4.last_operator bind_last_operator, t4.deleted_at bind_deleted_at, - t4.sub_store_id, t4.price bind_price, IF(t4.unit_price IS NOT NULL, t4.unit_price, t1.price) unit_price, t4.status store_sku_status, t4.auto_sale_at, - t4.ebai_id, t4.mtwm_id, t4.yb_id, CONCAT(smm.yb_store_prefix,t1.yb_name_suffix) yb_sku_name, t4.jds_id, t4.jds_ware_id, - t4.jd_sync_status, t4.ebai_sync_status, t4.mtwm_sync_status, t4.yb_sync_status, t4.jds_sync_status, - t4.jd_price, t4.ebai_price, t4.mtwm_price, t4.jx_price, t4.yb_price, t4.jds_price, - t4.jd_lock_time, t4.ebai_lock_time, t4.mtwm_lock_time, t4.jx_lock_time, t4.yb_lock_time, t4.jds_lock_time, - t4.status_sale_begin, t4.status_sale_end, t4.stock, - t6.mid_unit_price real_mid_unit_price, - t7.unit_price audit_unit_price - ` + sql - if isHighPrice || priceType != 0 { - sql += " , t4.unit_price DESC LIMIT 99" - } - var tmpList []*tGetStoresSkusInfo - beginTime := time.Now() - if err = dao.GetRows(db, &tmpList, sql, sqlParams...); err != nil { - dao.Rollback(db) - return nil, err - } - if isBySku { - skuNamesInfo.TotalCount = dao.GetLastTotalRowCount(db) - } - dao.Commit(db) - globals.SugarLogger.Debugf("GetStoresSkusNew get result2:%v", time.Now().Sub(beginTime)) - storeNameMap := make(map[int64]*dao.StoreSkuNameExt) - for _, v := range tmpList { - var storeName *dao.StoreSkuNameExt - index := jxutils.Combine2Int(v.StoreID, v.ID) - if isBySku || storeNameMap[index] == nil { - storeName = &dao.StoreSkuNameExt{ - StoreID: v.StoreID, - StoreName: v.StoreName, - SkuName: v.SkuName, - UnitPrice: v.UnitPrice, - PayPercentage: v.PayPercentage, - RealMidUnitPrice: v.RealMidUnitPrice, - YbSkuName: v.YbSkuName, - AuditUnitPrice: v.AuditUnitPrice, - } - if !isBySku { - storeNameMap[index] = storeName - } - skuNamesInfo.SkuNames = append(skuNamesInfo.SkuNames, storeName) - } else { - storeName = storeNameMap[index] - } - storeName.Skus = append(storeName.Skus, &v.StoreSkuExt) - } - if err == nil { - if isFocus { - if isSaleInfo { - beginTime := time.Now() - err = updateSaleInfo4StoreSkuName(ctx, db, storeIDs, skuIDs, params, skuNamesInfo, offset, pageSize) - globals.SugarLogger.Debugf("GetStoresSkusNew updateSaleInfo4StoreSkuName:%v", time.Now().Sub(beginTime)) - } - if err == nil { - if true { //!(offset == 0 && pageSize == model.UnlimitedPageSize) { - storeIDs, skuIDs = GetStoreAndSkuIDsFromInfo(skuNamesInfo) - } - beginTime := time.Now() - err = dao.UpdateActPrice4StoreSkuNameNew(db, storeIDs, skuIDs, skuNamesInfo, actVendorID) - globals.SugarLogger.Debugf("GetStoresSkusNew updateActPrice4StoreSkuName:%v", time.Now().Sub(beginTime)) - } - } else { - err = updateUnitPrice4StoreSkuNameNew(db, skuNamesInfo) - } - } - // globals.SugarLogger.Debug(utils.Format4Output(skuNamesInfo, false)) - return skuNamesInfo, err -} - -func GetStoreAndSkuIDsFromInfo(skuNamesInfo *dao.StoreSkuNamesInfo) (storeIDs, skuIDs []int) { - storeIDMap := make(map[int]int) - skuIDMap := make(map[int]int) - for _, skuName := range skuNamesInfo.SkuNames { - storeIDMap[skuName.StoreID] = 1 - for _, sku := range skuName.Skus { - skuIDMap[sku.SkuID] = 1 - } - } - return jxutils.IntMap2List(storeIDMap), jxutils.IntMap2List(skuIDMap) -} - -// 根据已经部分关注的商品,得到已经存在的门店商品单价 -func updateUnitPrice4StoreSkuNameNew(db *dao.DaoDB, skuNamesInfo *dao.StoreSkuNamesInfo) (err error) { - storeIDMap := make(map[int]int) - skuNameIDMap := make(map[int]int) - for _, skuName := range skuNamesInfo.SkuNames { - storeIDMap[skuName.StoreID] = 1 - skuNameIDMap[skuName.SkuName.ID] = 1 - } - storeSkuNameInfo, err := dao.GetExistingStoreSkuNameInfo(db, jxutils.IntMap2List(storeIDMap), jxutils.IntMap2List(skuNameIDMap)) - if err == nil { - infoMap := make(map[int64]*dao.StoreSkuNameInfo) - for _, v := range storeSkuNameInfo { - infoMap[jxutils.Combine2Int(v.StoreID, v.NameID)] = v - } - for _, skuName := range skuNamesInfo.SkuNames { - if tmpInfo := infoMap[jxutils.Combine2Int(skuName.StoreID, skuName.SkuName.ID)]; tmpInfo != nil { - skuName.UnitPrice = int(tmpInfo.UnitPrice) - } - } - } - return err -} - -func updateSaleInfo4StoreSkuName(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs, skuIDs []int, params map[string]interface{}, skuNamesInfo *dao.StoreSkuNamesInfo, offset, pageSize int) (err error) { - var ( - saleInfoList []*SkuSaleInfo - timeList []time.Time - fromCount, toCount int - ) - saleInfoMap := make(map[int64]*SkuSaleInfo) - - toTimeStr := "" - if params["stToTime"] != nil { - toTimeStr = params["stToTime"].(string) - } - if timeList, err = jxutils.BatchStr2Time(params["stFromTime"].(string), toTimeStr); err != nil { - return err - } - if params["stFromCount"] != nil { - fromCount = params["stFromCount"].(int) - } - toCount = math.MaxInt32 - if params["stToCount"] != nil { - toCount = params["stToCount"].(int) - } - // 不能用SQL筛除,否则不能区分是没有销量,还是不在条件中 - if saleInfoList, err = GetStoresSkusSaleInfo(ctx, storeIDs, skuIDs, timeList[0], timeList[1], 0, math.MaxInt32); err != nil { - return err - } - for _, saleInfo := range saleInfoList { - saleInfoMap[jxutils.Combine2Int(saleInfo.StoreID, saleInfo.SkuID)] = saleInfo - } - var newSkuNames []*dao.StoreSkuNameExt - for _, skuName := range skuNamesInfo.SkuNames { - var newSkus []*dao.StoreSkuExt - for _, sku := range skuName.Skus { - saleInfo := saleInfoMap[jxutils.Combine2Int(skuName.StoreID, sku.SkuID)] - if saleInfo == nil && fromCount == 0 { - saleInfo = &SkuSaleInfo{} - } - if saleInfo != nil && saleInfo.Count >= fromCount && saleInfo.Count <= toCount { - sku.Times = saleInfo.Times - sku.Count = saleInfo.Count - newSkus = append(newSkus, sku) - } - } - if len(newSkus) > 0 { - skuName.Skus = newSkus - newSkuNames = append(newSkuNames, skuName) - } - } - skuNamesInfo.TotalCount = len(newSkuNames) - skuNamesInfo.SkuNames = nil - if offset < skuNamesInfo.TotalCount { - endIndex := offset + pageSize - if endIndex > skuNamesInfo.TotalCount { - endIndex = skuNamesInfo.TotalCount - } - skuNamesInfo.SkuNames = newSkuNames[offset:endIndex] - } - return err -} - -func getValidStoreVendorMap(db *dao.DaoDB, storeIDs []int) (realVendorMap map[int]int, err error) { - storeMapList, err := dao.GetStoresMapList(db, nil, storeIDs, nil, model.StoreStatusAll, model.StoreIsSyncYes, "", "") - if err != nil { - return nil, err - } - realVendorMap = make(map[int]int) - for _, v := range storeMapList { - if v.IsSync != 0 { - realVendorMap[v.VendorID] = 1 - } - } - return realVendorMap, nil -} - -func GetStoreAbnormalSkuCount(ctx *jxcontext.Context, storeID, syncStatus int, isBySku bool, params map[string]interface{}) (count int, err error) { - db := dao.GetDB() - realVendorMap, err2 := getValidStoreVendorMap(db, []int{storeID}) - if err = err2; err != nil { - return 0, err - } - - sql := ` - SELECT COUNT(*) ct` - if !isBySku { - sql += ` - FROM ( - SELECT DISTINCT t3.id` - } - sql += ` - FROM store_sku_bind t1 - JOIN sku t2 ON t2.id = t1.sku_id AND t2.deleted_at = ? - JOIN sku_name t3 ON t3.id = t2.name_id AND t3.deleted_at = ? - WHERE t1.deleted_at = ? AND t1.store_id = ? AND - ((t2.status = ? AND t3.status = ?) OR t1.status = ?) AND - (1 = 0` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - storeID, - model.SkuStatusNormal, - model.SkuStatusNormal, - model.SkuStatusNormal, - } - for _, vendorID := range []int{model.VendorIDJD, model.VendorIDEBAI, model.VendorIDMTWM} { - if realVendorMap[vendorID] != 0 { - prefix := dao.ConvertDBFieldPrefix(model.VendorNames[vendorID]) - sql += fmt.Sprintf(" OR (t1.%s_sync_status & ? <> 0 AND t1.%s_sync_status & ? = 0", prefix, prefix) - sqlParams = append(sqlParams, syncStatus, model.SyncFlagDeletedMask|model.SyncFlagNewMask) - if model.MultiStoresVendorMap[vendorID] == 1 { - sql += fmt.Sprintf(" AND t2.%s_id <> 0 AND t2.status = ? AND t3.status = ?", prefix) - sqlParams = append(sqlParams, model.SkuStatusNormal, model.SkuStatusNormal) - } - sql += ")" - } - } - sql += ")" - if params["fromStatus"] != nil { - fromStatus := params["fromStatus"].(int) - toStatus := fromStatus - if params["toStatus"] != nil { - toStatus = params["toStatus"].(int) - } - sql += " AND t1.status >= ? AND t1.status <= ?" - sqlParams = append(sqlParams, fromStatus, toStatus) - } - if !isBySku { - sql += ` - ) t1` - } - err = dao.GetRow(db, &count, sql, sqlParams...) - return count, err -} - -func GetStoresSkusSaleInfo(ctx *jxcontext.Context, storeIDs []int, skuIDs []int, fromTime, toTime time.Time, fromCount, toCount int) (saleInfoList []*SkuSaleInfo, err error) { - globals.SugarLogger.Debugf("GetStoresSkusSaleInfo storeIDs:%v, fromTime:%v, toTime:%v, fromCount:%d, toCount:%d", storeIDs, fromTime, toTime, fromCount, toCount) - - db := dao.GetDB() - sql := ` - SELECT IF(t2.jx_store_id <> 0, jx_store_id, store_id) store_id, t1.sku_id, COUNT(*) times, SUM(count) count - FROM order_sku t1 - JOIN goods_order t2 ON t1.vendor_order_id = t2.vendor_order_id AND t1.vendor_id = t2.vendor_id AND t2.status = ? - WHERE t1.order_created_at >= ? AND t1.order_created_at <= ? - ` - if utils.IsTimeZero(toTime) { - toTime = time.Now() - } - sqlParams := []interface{}{ - model.OrderStatusFinished, - fromTime, - toTime, - } - if len(storeIDs) > 0 { - sql += ` - AND IF(t2.jx_store_id <> 0, jx_store_id, store_id) IN (` + dao.GenQuestionMarks(len(storeIDs)) + `) - ` - sqlParams = append(sqlParams, storeIDs) - } - if len(skuIDs) > 0 { - sql += ` - AND IF(t1.jx_sku_id <> 0, t1.jx_sku_id, t1.sku_id) IN (` + dao.GenQuestionMarks(len(skuIDs)) + `)` - sqlParams = append(sqlParams, skuIDs) - } - sql += ` - GROUP BY 1,2 - HAVING count >= ? AND count <= ? - ` - sqlParams = append(sqlParams, fromCount, toCount) - if err = dao.GetRows(db, &saleInfoList, sql, sqlParams...); err == nil { - // globals.SugarLogger.Debug(utils.Format4Output(saleInfoList, false)) - return saleInfoList, nil - } - return nil, err -} - -func asyncStoreSkuOpFilter(ctx *jxcontext.Context, isAsync bool) bool { - if !isAsync { - authType := ctx.GetLoginInfo().GetAuthType() - if authType == weixin.AuthTypeMini || authType == weixin.AuthTypeMP { - userMobile, _ := ctx.GetMobileAndUserID() - isAsync = asyncOpMobileMap[userMobile] == 0 - } - } - return isAsync -} - -func UpdateStoreSku(ctx *jxcontext.Context, causeFlag, storeID int, skuBindInfo *StoreSkuBindInfo, isAsync, isContinueWhenError bool) (hint string, err error) { - return UpdateStoreSkus(ctx, causeFlag, storeID, []*StoreSkuBindInfo{skuBindInfo}, isAsync, isContinueWhenError) -} - -func UpdateStoreSkus(ctx *jxcontext.Context, causeFlag, storeID int, skuBindInfos []*StoreSkuBindInfo, isAsync, isContinueWhenError bool) (hint string, err error) { - return UpdateStoresSkus(ctx, causeFlag, []int{storeID}, skuBindInfos, false, false, isAsync, isContinueWhenError) -} - -func UpdateStoresSkus(ctx *jxcontext.Context, causeFlag int, storeIDs []int, skuBindInfos []*StoreSkuBindInfo, isScale, isRefreshHigh, isAsync, isContinueWhenError bool) (hint string, err error) { - globals.SugarLogger.Debugf("UpdateStoresSkus:%s, storeIDs:%v, skuBindInfos:%s", ctx.GetTrackInfo(), storeIDs, utils.Format4Output(skuBindInfos, true)) - if beego.BConfig.RunMode == "jxgy" { - var num int64 - db := dao.GetDB() - skuIDs, err := updateStoresSkusWithoutSync(ctx, db, storeIDs, skuBindInfos, isScale, isRefreshHigh) - if err != nil { - return "", err - } - isAsync = asyncStoreSkuOpFilter(ctx, isAsync) - num = int64(len(skuIDs)) - if num > 0 { - hint, err = CurVendorSync.SyncStoresSkus(ctx, nil, causeFlag, db, nil, storeIDs, skuIDs, false, isAsync, isContinueWhenError) - } - if num == 0 || !isAsync || hint == "" { - hint = utils.Int64ToStr(num) - } - } else { - flag, _ := doStoreSkuAudit(ctx, storeIDs, skuBindInfos) - if !flag { - var num int64 - db := dao.GetDB() - skuIDs, err := updateStoresSkusWithoutSync(ctx, db, storeIDs, skuBindInfos, isScale, isRefreshHigh) - if err != nil { - return "", err - } - isAsync = asyncStoreSkuOpFilter(ctx, isAsync) - num = int64(len(skuIDs)) - if num > 0 { - hint, err = CurVendorSync.SyncStoresSkus(ctx, nil, causeFlag, db, nil, storeIDs, skuIDs, false, isAsync, isContinueWhenError) - } - if num == 0 || !isAsync || hint == "" { - hint = utils.Int64ToStr(num) - } - } - } - return hint, err -} - -func UpdateStoresSkusWithoutSync(ctx *jxcontext.Context, storeIDs []int, skuBindInfos []*StoreSkuBindInfo, isRefreshHigh bool) (err error) { - db := dao.GetDB() - if len(storeIDs) == 0 { - stores, _ := dao.GetStoreList(db, nil, nil, nil, nil, "") - for _, v := range stores { - storeIDs = append(storeIDs, v.ID) - } - } - updateStoresSkusWithoutSync(ctx, db, storeIDs, skuBindInfos, false, isRefreshHigh) - return err -} - -func UpdateStoresSkusByBind(ctx *jxcontext.Context, parentTask tasksch.ITask, skuBindInfos []*StoreSkuBindInfo, isAsync, isContinueWhenError, isFos bool) (hint string, err error) { - // if len(skuBindInfos) > maxStoreNameBind { - // return "", fmt.Errorf("门店商品信息大于%d", maxStoreNameBind) - // } - skuBindInfosMap := make(map[int][]*StoreSkuBindInfo) - storeIDMap := make(map[int]int) - for _, v := range skuBindInfos { - if v.StoreID > 0 { - skuBindInfosMap[v.StoreID] = append(skuBindInfosMap[v.StoreID], v) - storeIDMap[v.StoreID] = 1 - } - } - storeIDs := jxutils.IntMap2List(storeIDMap) - sort.Ints(storeIDs) - var num int64 - skuIDMap := make(map[int]int) - db := dao.GetDB() - // dao.Begin(db) - // defer func() { - // if r := recover(); r != nil { - // dao.Rollback(db) - // panic(r) - // } - // }() - for _, storeID := range storeIDs { - skuIDs, err2 := updateStoresSkusWithoutSync(ctx, db, []int{storeID}, skuBindInfosMap[storeID], false, false) - if err = err2; err != nil { - // dao.Rollback(db) - return "", err - } - for _, v := range skuIDs { - skuIDMap[v] = 1 - } - num += int64(len(skuIDs)) - } - // dao.Commit(db) - isAsync = asyncStoreSkuOpFilter(ctx, isAsync) - if num > 0 { - skuIDs := jxutils.IntMap2List(skuIDMap) - hint, err = CurVendorSync.SyncStoresSkus(ctx, parentTask, 0, db, nil, storeIDs, skuIDs, isFos, isAsync, isContinueWhenError) - } - if num == 0 || !isAsync || hint == "" { - hint = utils.Int64ToStr(num) - } - return hint, err -} - -func checkStoresSkusSaleCity(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs []int, skuBindInfos []*StoreSkuBindInfo) (err error) { - sql := ` - SELECT t1.id store_id, t2.id name_id, t2.name - FROM store t1 - JOIN sku_name t2 ON t2.is_global = 0 AND t2.deleted_at = ? - LEFT JOIN sku_name_place_bind t3 ON t2.id = t3.name_id AND t1.city_code = t3.place_code - WHERE t3.id IS NULL - ` - sql += " AND t1.id IN (" + dao.GenQuestionMarks(len(storeIDs)) + ")" - nameIDs := make([]int, 0) - for _, v := range skuBindInfos { - if v.IsFocus == 1 { - nameIDs = append(nameIDs, v.NameID) - } else { - for _, v2 := range v.Skus { - if v2.IsSale == 1 { - nameIDs = append(nameIDs, v.NameID) - break - } - } - } - } - if len(nameIDs) == 0 { - return nil - } - sql += " AND t2.id IN (" + dao.GenQuestionMarks(len(nameIDs)) + ")" - var invalidList []*tStoreNameBind - if err = dao.GetRows(db, &invalidList, sql, utils.DefaultTimeValue, storeIDs, nameIDs); err == nil { - if len(invalidList) > 0 { - errMsg := "" - for _, v := range invalidList { - errMsg += fmt.Sprintf("门店:%d,Name:%d(%s)销售区域错误!\n", v.StoreID, v.NameID, v.Name) - } - err = errors.New(errMsg) - } - } - return err -} - -func uniqueStoreIDs(storeIDs []int) []int { - storeIDMap := make(map[int]int) - for _, v := range storeIDs { - storeIDMap[v] = 1 - } - return jxutils.IntMap2List(storeIDMap) -} - -func uniqueStoreNameBind(skuBindInfos []*StoreSkuBindInfo) (outSkuBindInfos []*StoreSkuBindInfo) { - nameIDMap := make(map[int]int) - for _, v := range skuBindInfos { - if nameIDMap[v.NameID] != 1 { - outSkuBindInfos = append(outSkuBindInfos, v) - nameIDMap[v.NameID] = 1 - } - } - return outSkuBindInfos -} - -func updateStoresSkusWithoutSync(ctx *jxcontext.Context, db *dao.DaoDB, storeIDs []int, skuBindInfos []*StoreSkuBindInfo, isScale, isRefreshHigh bool) (needSyncSkus []int, err error) { - // if len(storeIDs)*len(skuBindInfos) > maxStoreNameBind2 { - // return nil, fmt.Errorf("门店商品信息大于%d", maxStoreNameBind2) - // } - - storeIDs = uniqueStoreIDs(storeIDs) - skuBindInfos = uniqueStoreNameBind(skuBindInfos) - - sort.Ints(storeIDs) - // globals.SugarLogger.Debugf("updateStoresSkusWithoutSync, storeIDs:%v, skuBindInfos:%s", storeIDs, utils.Format4Output(skuBindInfos, false)) - if db == nil { - db = dao.GetDB() - } - // if err = checkStoresSkusSaleCity(ctx, db, storeIDs, skuBindInfos); err != nil { - // return nil, err - // } - // globals.SugarLogger.Debugf("updateStoresSkusWithoutSync2, storeIDs:%v, skuBindInfos:%s", storeIDs, utils.Format4Output(skuBindInfos, false)) - isUserCanDirectChangePrice := true - if user := ctx.GetFullUser(); user != nil { - isUserCanDirectChangePrice = user.Type&model.UserTypeOperator != 0 - } - userName := ctx.GetUserName() - needSyncIDMap := make(map[int]int) - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - for _, storeID := range storeIDs { - // todo 可以考虑在需要更新价格再获取 - storeDetail, err := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDJX) - if err != nil || storeDetail == nil { - continue - } - scaleFactor := float64(1) - if isScale { - scaleFactor = 100 / float64(jxutils.ConstrainPayPercentage(storeDetail.PayPercentage)) - } - for _, skuBindInfo := range skuBindInfos { - // 关注且没有给价时,需要尝试从store_sku_bind中得到已有的单价 - needGetExistingUnitPrice := skuBindInfo.UnitPrice == 0 && skuBindInfo.IsFocus == 1 - inSkuBinds := skuBindInfo.Skus - var allBinds []*tStoreSkuBindAndSpec - sql := ` - SELECT - t2.*, - t1.id real_sku_id, t1.status sku_status, t1.spec_quality, t1.spec_unit, t1.exd_sku_id,` - if needGetExistingUnitPrice { - sql += " IF(t5.unit_price > 0, t5.unit_price, t3.price) sku_name_price," - } - sql += ` - t3.unit sku_name_unit, t3.name, t3.status sku_name_status, t3.id name_id, - ts.change_price_type, ts.name store_name - FROM sku t1 - JOIN store ts ON ts.id = ? AND ts.deleted_at = ? - LEFT JOIN store_sku_bind t2 ON t2.sku_id = t1.id AND t2.store_id = ts.id AND t2.deleted_at = ? - JOIN sku_name t3 ON t1.name_id = t3.id AND t3.deleted_at = ?` - sqlParams := []interface{}{ - storeID, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - } - if needGetExistingUnitPrice { - sql += ` - LEFT JOIN ( - SELECT t7.store_id, t8.name_id, CAST(AVG(t7.unit_price) AS SIGNED) unit_price - FROM store_sku_bind t7 - JOIN sku t8 ON t8.id = t7.sku_id AND t8.name_id = ? - WHERE t7.deleted_at = ? AND t7.store_id = ? - GROUP BY 1,2 - ) t5 ON t5.store_id = ts.id AND t5.name_id = t1.name_id` - sqlParams = append(sqlParams, skuBindInfo.NameID, utils.DefaultTimeValue, storeID) - } - sql += ` - WHERE t1.name_id = ? AND t1.deleted_at = ? - FOR UPDATE` - sqlParams = append(sqlParams, skuBindInfo.NameID, utils.DefaultTimeValue) - // globals.SugarLogger.Debug(sql) - if err = dao.GetRows(db, &allBinds, sql, sqlParams...); err == nil { - if len(allBinds) > 0 { - // globals.SugarLogger.Debug(utils.Format4Output(allBinds, false)) - inSkuBinsMap := make(map[int]*StoreSkuBindSkuInfo, len(inSkuBinds)) - for _, v := range inSkuBinds { - inSkuBinsMap[v.SkuID] = v - } - unitPrice := 0 - if skuBindInfo.UnitPrice != 0 { - if skuBindInfo.UnitPrice > MaxSkuUnitPrice { - dao.Rollback(db) - return nil, fmt.Errorf("商品:%s价格:%s太夸张", allBinds[0].Name, jxutils.IntPrice2StandardCurrencyString(int64(skuBindInfo.UnitPrice))) - } - unitPrice = skuBindInfo.UnitPrice - if isRefreshHigh { - if allBinds[0].UnitPrice <= unitPrice { - continue - } - } - } else { - unitPrice = allBinds[0].UnitPrice - if unitPrice == 0 { - unitPrice = allBinds[0].SkuNamePrice - } - } - unitPrice = int(float64(unitPrice) * scaleFactor) - for _, v := range allBinds { - var num int64 - inSkuBind := inSkuBinsMap[v.RealSkuID] - isCanChangePrice := (isUserCanDirectChangePrice || jxutils.TranslateStorePriceType(v.ChangePriceType) != model.StoreChangePriceTypeBossDisabled) - // globals.SugarLogger.Debug(utils.Format4Output(inSkuBind, false)) - var skuBind *model.StoreSkuBind - if v.ID == 0 { - // if v.ExdSkuID == "" { - if (strings.Contains(v.StoreName, model.ExdStoreName) && v.ExdSkuID != "") || (!strings.Contains(v.StoreName, model.ExdStoreName) && v.ExdSkuID == "") { - if skuBindInfo.IsFocus == 1 && v.SkuNameStatus == model.SkuStatusNormal && v.SkuStatus == model.SkuStatusNormal && isCanChangePrice { - skuBind = &model.StoreSkuBind{ - StoreID: storeID, - SkuID: v.RealSkuID, - SubStoreID: skuBindInfo.SubStoreID, // todo 这个应该从用户信息中自动获得 - UnitPrice: unitPrice, - Price: jxutils.CaculateSkuPrice(unitPrice, v.SpecQuality, v.SpecUnit, v.SkuNameUnit), - Status: model.StoreSkuBindStatusDontSale, // 缺省不可售? - } - skuBind.JxPrice = jxutils.CaculatePriceByPricePack(storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage), skuBind.Price) - if tmpStatus := getSkuSaleStatus(inSkuBind, skuBindInfo); tmpStatus != model.StoreSkuBindStatusNA { - skuBind.Status = tmpStatus - if inSkuBind != nil { - if inSkuBind.Stock != nil { - skuBind.Stock = *inSkuBind.Stock - } else { - if tmpStatus == model.StoreSkuBindStatusNormal { - skuBind.Stock = model.MaxStoreSkuStockQty - } else { - skuBind.Stock = 0 - } - } - } else { - if tmpStatus == model.StoreSkuBindStatusNormal { - skuBind.Stock = model.MaxStoreSkuStockQty - } else { - skuBind.Stock = 0 - } - } - } - if globals.IsAddEvent { - err = AddEventDetail(db, ctx, model.OperateAdd, v.RealSkuID, model.ThingTypeSku, storeID, "", utils.Int2Str(skuBind.UnitPrice)) - } - setStoreSkuBindStatus(skuBind, model.SyncFlagNewMask) - dao.WrapAddIDCULDEntity(skuBind, userName) - // globals.SugarLogger.Debug(utils.Format4Output(skuBind, false)) - if deletedSku := dao.GetDeletedStoreSkuBind(db, skuBind.StoreID, skuBind.SkuID); deletedSku == nil { - if err = dao.CreateEntity(db, skuBind); err != nil { - dao.Rollback(db) - return nil, err - } - num = 1 - } else { - // 需要处理,在删除某个门店商品,同步失败的情况下,又把商品重新关注。 - // 所以统一处理成恢复删除的记录,这样避免问题 - skuBind.ID = deletedSku.ID - // vendorSkuID的赋值意义不大 - skuBind.MtwmID = deletedSku.MtwmID - skuBind.EbaiID = deletedSku.EbaiID - if num, err = dao.UpdateEntity(db, skuBind); err != nil { - dao.Rollback(db) - return nil, err - } - } - } - } - } else { - beforeMsg := *v - skuBind = &v.StoreSkuBind - if skuBindInfo.IsFocus == -1 && isCanChangePrice { - if globals.IsAddEvent { - err = AddEventDetail(db, ctx, model.OperateDelete, skuBind.SkuID, model.ThingTypeSku, storeID, "", "") - } - if globals.IsStoreSkuAct { - dao.DeleteEntity(db, &model.StoreSkuAct{ - StoreID: skuBind.StoreID, - SkuID: skuBind.SkuID, - }, "StoreID", "SkuID") - } - if num, err = dao.DeleteEntityLogically(db, skuBind, map[string]interface{}{ - model.FieldStatus: model.StoreSkuBindStatusDeleted, - model.FieldJdSyncStatus: model.SyncFlagDeletedMask, - model.FieldEbaiSyncStatus: model.SyncFlagDeletedMask, - model.FieldMtwmSyncStatus: model.SyncFlagDeletedMask, - model.FieldYbSyncStatus: model.SyncFlagDeletedMask, - model.FieldJdsSyncStatus: model.SyncFlagDeletedMask, - }, userName, nil); err != nil { - dao.Rollback(db) - return nil, err - } - //删除待审核商品信息 - storeAudits, err := dao.GetStoreSkuAuditLight(db, []int{storeID}, []int{v.NameID}, model.StoreAuditStatusOnline) - if len(storeAudits) > 0 { - storeAudits[0].DeletedAt = time.Now() - if _, err = dao.UpdateEntity(db, storeAudits[0], "DeletedAt"); err != nil { - dao.Rollback(db) - return nil, err - } - } - } else { - // 用了SELECT FOR UPDATE后,只更新修改字段是没有必要的,暂时保留 - updateFieldMap := make(map[string]interface{}) - if skuBindInfo.IsFocus == 1 { // 关注之后再关注不操作 - // skuBind.Status = model.StoreSkuBindStatusDontSale // 缺省不可售? - // skuBind.DeletedAt = utils.DefaultTimeValue - // skuBind.UnitPrice = unitPrice - // skuBind.Price = jxutils.CaculateSkuPrice(unitPrice, v.SpecQuality, v.SpecUnit, v.SkuNameUnit) - // setStoreSkuBindStatus(skuBind, model.SyncFlagPriceMask|model.SyncFlagSaleMask) - // updateFieldMap[model.FieldStatus] = 1 - // updateFieldMap[model.FieldDeletedAt] = 1 - // updateFieldMap["UnitPrice"] = 1 - // updateFieldMap["Price"] = 1 - } - if tmpStatus := getSkuSaleStatus(inSkuBind, skuBindInfo); tmpStatus != model.StoreSkuBindStatusNA { - if tmpStatus != skuBind.Status { - updateFieldMap[model.FieldStatus] = 1 - } - skuBind.Status = tmpStatus - setStoreSkuBindStatus(skuBind, model.SyncFlagSaleMask) - setStoreSkuBindStatus(skuBind, model.SyncFlagStockMask) - if tmpStatus == model.StoreSkuBindStatusNormal { - skuBind.Stock = model.MaxStoreSkuStockQty - } else { - skuBind.Stock = 0 - } - } - if inSkuBind != nil { - if inSkuBind.Stock != nil { - updateFieldMap["Stock"] = 1 - skuBind.Stock = *inSkuBind.Stock - setStoreSkuBindStatus(skuBind, model.SyncFlagStockMask) - } - } - if skuBindInfo.UnitPrice != 0 && isCanChangePrice { // 这里是否需要加此条件限制 - price := jxutils.CaculateSkuPrice(unitPrice, v.SpecQuality, v.SpecUnit, v.SkuNameUnit) - jxPrice := jxutils.CaculatePriceByPricePack(storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage), price) - if unitPrice != skuBind.UnitPrice || price != skuBind.Price || jxPrice != skuBind.JxPrice { - if price != skuBind.Price { - setStoreSkuBindStatus(skuBind, model.SyncFlagPriceMask) - updateFieldMap["Price"] = 1 - } - skuBind.UnitPrice = unitPrice - skuBind.Price = price - skuBind.JxPrice = jxPrice - updateFieldMap["UnitPrice"] = 1 - updateFieldMap["JxPrice"] = 1 - - //TODO 2020-09-08 如果改价时商品在做直降,要取消这个商品的直降,再通过改价比例修改活动价,再上这个直降 - // checkActDirectDown(ctx, skuBind, beforeMsg) - } - } - if skuBindInfo.StatusSaleBegin != 0 && skuBindInfo.StatusSaleEnd != 0 { - if err := ValidateStruct(skuBindInfo); err != nil { - globals.SugarLogger.Infof("更改商品:%s, 可售时间不合法!时间范围:[%v] 至 [%v]", allBinds[0].Name, skuBindInfo.StatusSaleBegin, skuBindInfo.StatusSaleEnd) - } else { - if skuBind.StatusSaleBegin != skuBindInfo.StatusSaleBegin || skuBind.StatusSaleEnd != skuBindInfo.StatusSaleEnd { - updateFieldMap["StatusSaleBegin"] = 1 - updateFieldMap["StatusSaleEnd"] = 1 - } - skuBind.StatusSaleBegin = skuBindInfo.StatusSaleBegin - skuBind.StatusSaleEnd = skuBindInfo.StatusSaleEnd - } - } - if skuBindInfo.StatusSaleBegin == 0 && skuBindInfo.StatusSaleEnd == 0 { - if skuBind.StatusSaleBegin != skuBindInfo.StatusSaleBegin || skuBind.StatusSaleEnd != skuBindInfo.StatusSaleEnd { - updateFieldMap["StatusSaleBegin"] = 1 - updateFieldMap["StatusSaleEnd"] = 1 - } - skuBind.StatusSaleBegin = skuBindInfo.StatusSaleBegin - skuBind.StatusSaleEnd = skuBindInfo.StatusSaleEnd - } - - if globals.IsAddEvent { - if len(updateFieldMap) > 0 { - mapAfter := refutil.FindMapAndStructMixed(updateFieldMap, skuBind) - mapBefore := refutil.FindMapAndStructMixed(updateFieldMap, beforeMsg) - err = AddEventDetail(db, ctx, model.OperateUpdate, v.RealSkuID, model.ThingTypeSku, storeID, BuildDiffData(mapBefore), BuildDiffData(mapAfter)) - } - } - if len(updateFieldMap) > 0 { - updateFieldMap[model.FieldJdSyncStatus] = 1 - updateFieldMap[model.FieldEbaiSyncStatus] = 1 - updateFieldMap[model.FieldMtwmSyncStatus] = 1 - updateFieldMap[model.FieldUpdatedAt] = 1 - updateFieldMap[model.FieldLastOperator] = 1 - - dao.WrapUpdateULEntity(skuBind, userName) - if skuBind.Status == model.SkuStatusNormal { - updateFieldMap["AutoSaleAt"] = 1 - skuBind.AutoSaleAt = utils.DefaultTimeValue - } - if num, err = dao.UpdateEntity(db, skuBind /*, utils.Map2KeySlice(updateFieldMap)...*/); err != nil { - dao.Rollback(db) - return nil, err - } - } - } - } - if skuBind != nil && num == 1 { - needSyncIDMap[skuBind.SkuID] = 1 - } - } - } - } else { - dao.Rollback(db) - return nil, err - } - } - } - dao.Commit(db) - skuIDs := jxutils.IntMap2List(needSyncIDMap) - return skuIDs, err -} - -// func checkActDirectDown(ctx *jxcontext.Context, skuBind *model.StoreSkuBind, beforeSkuBind tStoreSkuBindAndSpec) (err error) { -// var ( -// originPrice = beforeSkuBind.Price -// price = skuBind.Price -// db = dao.GetDB() -// pageSize = 9999 -// // percent = price / originPrice -// ) -// if paged, _ := dao.QueryActs(db, 0, 0, pageSize, -1, "", -1, []int{model.ActStatusCreated}, []int{model.ActSkuDirectDown}, nil, skuBind.StoreID, []int{skuBind.SkuID}, 0, utils.ZeroTimeValue, utils.ZeroTimeValue, time.Now().AddDate(0, -2, 0), time.Now()); len(paged.Data) > 0 { -// for _, act := range paged.Data { -// if _, actStoreSkus, err := dao.GetActStoreSkuVendorList(db, act.ID, nil, []int{skuBind.StoreID}, []int{skuBind.SkuID}, "", 0, pageSize); err == nil && len(actStoreSkus) > 0 { -// var ( -// handler = partner.GetPurchasePlatformFromVendorID(actStoreSkus[0].VendorID).(partner.IPurchasePlatformActHandler) -// actStoreSkuParam []*ActStoreSkuParam -// ) -// for _, actStoreSku := range actStoreSkus { -// aa := &ActStoreSkuParam{ -// ActStoreSku: model.ActStoreSku{ -// StoreID: skuBind.StoreID, -// SkuID: actStoreSku.SkuID, -// ActID: act.ID, -// }, -// } -// actStoreSkuParam = append(actStoreSkuParam, aa) -// } -// DeleteActStoreSkuBind(ctx, db, act.ID, actStoreSkuParam) -// actMap, err := dao.GetActVendorInfo(db, act.ID, []int{actStoreSkus[0].VendorID}) -// if err != nil { -// return err -// } -// actStoreSkuMap, err := dao.GetActStoreSkuVendorInfo(db, act.ID, nil, nil, nil) -// if err != nil { -// return err -// } -// handler.SyncAct(ctx, nil, actMap[actStoreSkus[0].VendorID], nil, actStoreSkuMap[actStoreSkus[0].VendorID]) -// } -// } -// } -// return err -// } - -func getSkuSaleStatus(inSkuBind *StoreSkuBindSkuInfo, skuNameBindInfo *StoreSkuBindInfo) int { - tempSale := 0 - if inSkuBind != nil { - tempSale = inSkuBind.IsSale - } - if tempSale == 0 { - tempSale = skuNameBindInfo.IsSale - } - if tempSale == -1 { - return model.StoreSkuBindStatusDontSale - } else if tempSale == 1 { - return model.StoreSkuBindStatusNormal - } - return model.StoreSkuBindStatusNA -} - -func AddEventDetail(db *dao.DaoDB, ctx *jxcontext.Context, operateType, thingID, thingType, storeID int, beforeData, afterData string) (err error) { - if ctx.GetUserName() == "jxadmin" { - return err - } - operateEventDetail := &model.OperateEventDetail{ - OperateType: operateType, - ThingID: thingID, - ThingType: thingType, - StoreID: storeID, - AccessUUID: ctx.GetTrackInfo()[0:strings.Index(ctx.GetTrackInfo(), ",")], - BeforeData: beforeData, - AfterData: afterData, - } - err = event.AddOperateEventDetail(db, operateEventDetail) - return err -} - -func formatAutoSaleTime(autoSaleTime time.Time) (outAutoSaleTime time.Time) { - if utils.IsTimeZero(autoSaleTime) { - outAutoSaleTime = utils.DefaultTimeValue - } else { - outAutoSaleTime = jxutils.GetNextTimeFromList(time.Now(), []string{AutoSaleAtStr}) - } - return outAutoSaleTime -} - -// todo 应该用updateStoresSkusWithoutSync实现 -func updateStoreSkusSaleWithoutSync(ctx *jxcontext.Context, storeID int, skuBindSkuInfos []*StoreSkuBindSkuInfo, autoSaleTime time.Time, ignoreDontSale bool, userName string) (needSyncSkus []int, err error) { - var num int64 - db := dao.GetDB() - needSyncIDMap := make(map[int]int) - skuIDMap := make(map[int]int) - skuBindSkuInfosMap := make(map[int]*StoreSkuBindSkuInfo) - for _, v := range skuBindSkuInfos { - skuIDMap[v.SkuID] = 1 - skuBindSkuInfosMap[v.SkuID] = v - } - - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - storeSkuList, err := dao.GetStoresSkusInfo(db, []int{storeID}, jxutils.IntMap2List(skuIDMap)) - if err != nil { - dao.Rollback(db) - return nil, err - } - autoSaleTime = formatAutoSaleTime(autoSaleTime) - for _, skuBind := range storeSkuList { - if v := skuBindSkuInfosMap[skuBind.SkuID]; v != nil && v.IsSale != 0 { - if !(!utils.IsTimeZero(autoSaleTime) && ignoreDontSale && skuBind.Status == model.StoreSkuBindStatusDontSale) { - statusResult := skuBind.Status - if v.IsSale == -1 || !utils.IsTimeZero(autoSaleTime) { - skuBind.Status = model.StoreSkuBindStatusDontSale - } else if v.IsSale == 1 { - skuBind.Status = model.StoreSkuBindStatusNormal - } - kvs := map[string]interface{}{ - model.FieldLastOperator: ctx.GetUserName(), - model.FieldUpdatedAt: time.Now(), - model.FieldStatus: skuBind.Status, - model.FieldJdSyncStatus: skuBind.JdSyncStatus | model.SyncFlagSaleMask, - model.FieldEbaiSyncStatus: skuBind.EbaiSyncStatus | model.SyncFlagSaleMask, - model.FieldMtwmSyncStatus: skuBind.MtwmSyncStatus | model.SyncFlagSaleMask, - } - if utils.IsTimeZero(autoSaleTime) || skuBind.Status == model.SkuStatusNormal { - kvs["AutoSaleAt"] = utils.DefaultTimeValue - } else { - kvs["AutoSaleAt"] = autoSaleTime - } - if globals.IsAddEvent { - var status int - if v.IsSale == -1 { - status = model.StoreSkuBindStatusDontSale - } else { - status = model.StoreSkuBindStatusNormal - } - if status != statusResult { - mapAfter := make(map[string]interface{}) - mapAfter["Status"] = status - mapBefore := make(map[string]interface{}) - mapBefore["Status"] = statusResult - err = AddEventDetail(db, ctx, model.OperateUpdate, v.SkuID, model.ThingTypeSku, storeID, BuildDiffData(mapBefore), BuildDiffData(mapAfter)) - } - } - if num, err = dao.UpdateEntityLogically(db, skuBind, kvs, userName, nil); err != nil { - dao.Rollback(db) - return nil, err - } - if num == 1 { - needSyncIDMap[v.SkuID] = 1 - } - } - } - } - dao.Commit(db) - needSyncSkus = jxutils.IntMap2List(needSyncIDMap) - return needSyncSkus, err -} - -func BuildDiffData(mapData map[string]interface{}) string { - dd := utils.MustMarshal(mapData) - result := utils.LimitUTF8StringLen(string(dd), 3200) - return result -} - -func uniqueStoreSkuBind(skuBindSkuInfos []*StoreSkuBindSkuInfo) (outSkuBindSkuInfos []*StoreSkuBindSkuInfo) { - skuIDMap := make(map[int]int) - for _, v := range skuBindSkuInfos { - if skuIDMap[v.SkuID] != 1 { - outSkuBindSkuInfos = append(outSkuBindSkuInfos, v) - skuIDMap[v.SkuID] = 1 - } - } - return outSkuBindSkuInfos -} - -func UpdateStoresSkusSale(ctx *jxcontext.Context, storeIDs []int, skuBindSkuInfos []*StoreSkuBindSkuInfo, autoSaleTime time.Time, ignoreDontSale bool, userName string, isAsync, isContinueWhenError bool) (hint string, err error) { - storeIDs = uniqueStoreIDs(storeIDs) - skuBindSkuInfos = uniqueStoreSkuBind(skuBindSkuInfos) - - var num int64 - for _, storeID := range storeIDs { - skuIDs, err2 := updateStoreSkusSaleWithoutSync(ctx, storeID, skuBindSkuInfos, autoSaleTime, ignoreDontSale, userName) - if err = err2; err != nil { - return "", err - } - num += int64(len(skuIDs)) - } - isAsync = asyncStoreSkuOpFilter(ctx, isAsync) - if num > 0 { - skuIDs := make([]int, 0) - for _, v := range skuBindSkuInfos { - skuIDs = append(skuIDs, v.SkuID) - } - db := dao.GetDB() - hint, err = CurVendorSync.SyncStoresSkus(ctx, nil, 0, db, nil, storeIDs, skuIDs, false, isAsync, isContinueWhenError) - } - if num == 0 || !isAsync || hint == "" { - hint = utils.Int64ToStr(num) - } - return hint, err -} - -func CopyStoreSkus(ctx *jxcontext.Context, fromStoreID int, toStoreIDs []int, copyMode string, isScale bool, params map[string]interface{}, userName string) (num int64, err error) { - if copyMode != CopyStoreSkuModeFresh && copyMode != CopyStoreSkuModeUpdate && copyMode != CopyStoreSkuModeUpdatePrice { - return 0, fmt.Errorf("不支持的拷贝模式:%s", copyMode) - } - db := dao.GetDB() - fromStore, err := checkStoreExisting(db, fromStoreID) - if err != nil { - return 0, err - } - sqlCatAndSku := "" - sqlCatAndSkuParams := make([]interface{}, 0) - if params["categoryIDs"] != nil { - var cats []int - if err = utils.UnmarshalUseNumber([]byte(params["categoryIDs"].(string)), &cats); err != nil { - return 0, err - } - if len(cats) > 0 { - sqlCatAndSku += " AND (t3.category_id IN (" + dao.GenQuestionMarks(len(cats)) + ") OR t4.parent_id IN (" + dao.GenQuestionMarks(len(cats)) + "))" - sqlCatAndSkuParams = append(sqlCatAndSkuParams, cats, cats) - } - } - if params["skuIDs"] != nil { - var skus []int - if err = utils.UnmarshalUseNumber([]byte(params["skuIDs"].(string)), &skus); err != nil { - return 0, err - } - if len(skus) > 0 { - sqlCatAndSku += " AND t1.sku_id IN (" + dao.GenQuestionMarks(len(skus)) + ")" - sqlCatAndSkuParams = append(sqlCatAndSkuParams, skus) - } - } - pricePercentage := 100 - if params["pricePercentage"] != nil { - pricePercentage = params["pricePercentage"].(int) - } - errList := errlist.New() - for _, toStoreID := range toStoreIDs { - toStore, err := checkStoreExisting(db, toStoreID) - if err != nil { - errList.AddErr(err) - break - } - now := time.Now() - if fromStoreID == toStoreID { - sql := ` - UPDATE store_sku_bind t1 - JOIN sku t2 ON t1.sku_id = t2.id AND t2.deleted_at = ? - JOIN sku_name t3 ON t2.name_id = t3.id AND t2.deleted_at = ? - LEFT JOIN sku_category t4 ON t3.category_id = t4.id AND t2.deleted_at = ? - SET t1.last_operator = ?, - t1.updated_at = ?, - t1.price = t1.price * ? / 100, - t1.jx_price = t1.jx_price * ? / 100, - t1.unit_price = t1.unit_price * ? / 100, - t1.jd_sync_status = t1.jd_sync_status | ?, - t1.mtwm_sync_status = t1.mtwm_sync_status | ?, - t1.ebai_sync_status = t1.ebai_sync_status | ? - WHERE t1.store_id = ? AND t1.deleted_at = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - userName, - now, - pricePercentage, - pricePercentage, - pricePercentage, - model.SyncFlagPriceMask, - model.SyncFlagPriceMask, - model.SyncFlagPriceMask, - toStoreID, - utils.DefaultTimeValue, - } - sql += sqlCatAndSku - sqlParams = append(sqlParams, sqlCatAndSkuParams) - num2, err2 := dao.ExecuteSQL(db, sql, sqlParams) - if err2 != nil { - errList.AddErr(err2) - } else { - num += num2 - } - break - } - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - if copyMode == CopyStoreSkuModeFresh { - // 将toStore中存在,但fromStore中不存在的置删除标志 - sqlDelete := ` - UPDATE store_sku_bind t1 - LEFT JOIN store_sku_bind t0 ON t0.store_id = ? AND t0.sku_id = t1.sku_id AND t0.deleted_at = ? - JOIN sku t2 ON t1.sku_id = t2.id/* AND t2.deleted_at = ?*/ - JOIN sku_name t3 ON t2.name_id = t3.id/* AND t2.deleted_at = ?*/ - LEFT JOIN sku_category t4 ON t3.category_id = t4.id AND t2.deleted_at = ? - SET - t1.deleted_at = ?, - t1.updated_at = ?, - t1.last_operator = ?, - t1.status = ?, - t1.jd_sync_status = IF((t1.jd_sync_status & ?) <> 0, 0, ?), - t1.mtwm_sync_status = IF((t1.mtwm_sync_status & ?) <> 0, 0, ?), - t1.ebai_sync_status = IF((t1.ebai_sync_status & ?) <> 0, 0, ?) - WHERE t1.store_id = ? AND t1.deleted_at = ? AND t0.id IS NULL - ` - sqlDeleteParams := []interface{}{ - fromStoreID, - utils.DefaultTimeValue, - // utils.DefaultTimeValue, - // utils.DefaultTimeValue, - utils.DefaultTimeValue, - now, - now, - userName, - model.StoreSkuBindStatusDeleted, - model.SyncFlagNewMask, - model.SyncFlagDeletedMask, - model.SyncFlagNewMask, - model.SyncFlagDeletedMask, - model.SyncFlagNewMask, - model.SyncFlagDeletedMask, - toStoreID, - utils.DefaultTimeValue, - } - sqlDelete += sqlCatAndSku - sqlDeleteParams = append(sqlDeleteParams, sqlCatAndSkuParams) - // globals.SugarLogger.Debug(sqlDelete) - num2, err2 := dao.ExecuteSQL(db, sqlDelete, sqlDeleteParams) - if err = err2; err != nil { - errList.AddErr(err) - dao.Rollback(db) - break - } - num += num2 - globals.SugarLogger.Debugf("CopyStoreSkus fromStoreID:%d, toStoreID:%d, trackInfo:%s num1:%d", fromStoreID, toStoreID, ctx.GetTrackInfo(), num2) - } - isModifyStatus := 1 - syncStatus := model.SyncFlagStoreSkuOnlyMask - if copyMode == CopyStoreSkuModeUpdatePrice { - isModifyStatus = 0 - syncStatus = model.SyncFlagPriceMask - } - scaleFactor := float64(1) - if isScale { - fromPayPercentage := jxutils.ConstrainPayPercentage(fromStore.PayPercentage) - toPayPercentage := jxutils.ConstrainPayPercentage(toStore.PayPercentage) - scaleFactor = float64(fromPayPercentage) / float64(toPayPercentage) - } - // 处理toStore中与fromStore中都存在的 - sql := ` - UPDATE store_sku_bind t1 - JOIN store t11 ON t11.id = t1.store_id - LEFT JOIN store_sku_bind t0 ON t0.store_id = ? AND t0.sku_id = t1.sku_id AND t0.deleted_at = ? - JOIN store t01 ON t01.id = t0.store_id - JOIN sku t2 ON t1.sku_id = t2.id/* AND t2.deleted_at = ?*/ - JOIN sku_name t3 ON t2.name_id = t3.id/* AND t3.deleted_at = ?*/ - LEFT JOIN sku_category t4 ON t3.category_id = t4.id AND t4.deleted_at = ? - SET - t1.last_operator = ?, - t1.updated_at = ?, - t1.sub_store_id = 0, - t1.price = IF(t0.price * ? / 100 > 0, t0.price * ? / 100, 1) * ?, - t1.jx_price = IF(t0.jx_price * ? / 100 > 0, t0.jx_price * ? / 100, 1) * ?, - t1.unit_price = IF(t0.unit_price * ? / 100 > 0, t0.unit_price * ? / 100, 1) * ?, - t1.status = IF(? = 0, t1.status, t0.status), - t1.jd_sync_status = t1.jd_sync_status | ?, - t1.mtwm_sync_status = t1.mtwm_sync_status | ?, - t1.ebai_sync_status = t1.ebai_sync_status | ?, - t1.stock = t0.stock - WHERE t1.store_id = ? AND t1.deleted_at = ? AND t0.id IS NOT NULL - ` - sqlParams := []interface{}{ - fromStoreID, - utils.DefaultTimeValue, - // utils.DefaultTimeValue, - // utils.DefaultTimeValue, - utils.DefaultTimeValue, - userName, - now, - pricePercentage, - pricePercentage, - scaleFactor, - pricePercentage, - pricePercentage, - scaleFactor, - pricePercentage, - pricePercentage, - scaleFactor, - isModifyStatus, - syncStatus, - syncStatus, - syncStatus, - toStoreID, - utils.DefaultTimeValue, - } - sql += sqlCatAndSku - sqlParams = append(sqlParams, sqlCatAndSkuParams) - // globals.SugarLogger.Debug(sql) - num2, err2 := dao.ExecuteSQL(db, sql, sqlParams) - globals.SugarLogger.Debugf("CopyStoreSkus fromStoreID:%d, toStoreID:%d, trackInfo:%s num2:%d", fromStoreID, toStoreID, ctx.GetTrackInfo(), num2) - if err = err2; err != nil { - errList.AddErr(err) - dao.Rollback(db) - break - } - num += num2 - // 添加toStore中不存在,但fromStore存在的 - sql = ` - INSERT INTO store_sku_bind(created_at, updated_at, last_operator, deleted_at, store_id, sku_id, sub_store_id, price, jx_price, unit_price, status, - jd_sync_status, ebai_sync_status, mtwm_sync_status, stock) - SELECT ?, ?, ?, ?, ?, - t1.sku_id, 0, - IF(t1.price * ? / 100 > 0, t1.price * ? / 100, 1) * ?, - IF(t1.jx_price * ? / 100 > 0, t1.jx_price * ? / 100, 1) * ?, - IF(t1.unit_price * ? / 100 > 0, t1.unit_price * ? / 100, 1) * ?, - IF(? = 0, ?, t1.status), ?, ?, ?, t1.stock - FROM store_sku_bind t1 - JOIN sku t2 ON t1.sku_id = t2.id AND t2.deleted_at = ? - JOIN sku_name t3 ON t2.name_id = t3.id AND t3.deleted_at = ? - LEFT JOIN sku_category t4 ON t3.category_id = t4.id AND t4.deleted_at = ? - LEFT JOIN store_sku_bind t0 ON t1.sku_id = t0.sku_id AND t0.store_id = ? AND t0.deleted_at = ? - WHERE t1.store_id = ? AND t1.deleted_at = ? - ` - sqlParams = []interface{}{ - now, now, userName, utils.DefaultTimeValue, toStoreID, - pricePercentage, - pricePercentage, - scaleFactor, - pricePercentage, - pricePercentage, - scaleFactor, - pricePercentage, - pricePercentage, - scaleFactor, - isModifyStatus, - model.SkuStatusDontSale, - model.SyncFlagNewMask, - model.SyncFlagNewMask, - model.SyncFlagNewMask, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - toStoreID, - utils.DefaultTimeValue, - fromStoreID, - utils.DefaultTimeValue, - } - sql += sqlCatAndSku + " AND t0.id IS NULL" - sqlParams = append(sqlParams, sqlCatAndSkuParams) - num2, err = dao.ExecuteSQL(db, sql, sqlParams) - if err != nil { - errList.AddErr(err) - dao.Rollback(db) - break - } - num += num2 - //上方insert会无视目标门店中未关注的商品(以前关注,后来取消关注),所以这里批量删一下 - sql2 := ` - DELETE FROM store_sku_bind - WHERE store_id = ? AND sku_id IN ( - SELECT b.sku_id FROM ( - SELECT store_id,sku_id,count(*) - FROM store_sku_bind - WHERE store_id = ? - GROUP BY 1,2 - HAVING count(*) > 1)b - ) - AND deleted_at <> ? - ` - sqlParams2 := []interface{}{ - toStoreID, toStoreID, utils.DefaultTimeValue, - } - _, err = dao.ExecuteSQL(db, sql2, sqlParams2) - if err != nil { - errList.AddErr(err) - dao.Rollback(db) - break - } - globals.SugarLogger.Debugf("CopyStoreSkus fromStoreID:%d, toStoreID:%d, trackInfo:%s num3:%d", fromStoreID, toStoreID, ctx.GetTrackInfo(), num2) - dao.Commit(db) - - //同一商品若源门店的规格少于要复制到的门店,则在复制的门店里的其他规格的unitprice不会变, - //导致复制的门店的商品unitprice不尽相同,这里先处理一下 - type tStore struct { - NameID int `orm:"column(name_id)"` - StoreID int `orm:"column(store_id)"` - } - var resultList []*tStore - sql3 := ` - SELECT a.name_id, a.store_id FROM ( - SELECT DISTINCT a.unit_price, b.name_id, a.store_id FROM store_sku_bind a, sku b, store c - WHERE a.sku_id = b.id - AND c.id = a.store_id - AND c.deleted_at = ? - AND a.store_id = ? - AND a.deleted_at = ?)a - GROUP BY 1, 2 - HAVING COUNT(a.unit_price) > 1 - ` - sqlParams3 := []interface{}{utils.DefaultTimeValue, toStoreID, utils.DefaultTimeValue} - err = dao.GetRows(db, &resultList, sql3, sqlParams3) - if len(resultList) > 0 { - var skuBindInfos []*StoreSkuBindInfo - for _, v := range resultList { - storeSkus, _ := dao.GetStoreSkusByNameIDs(db, []int{v.StoreID}, v.NameID) - unitPirce := storeSkus[0].UnitPrice - skuBindInfo := &StoreSkuBindInfo{ - StoreID: v.StoreID, - NameID: v.NameID, - UnitPrice: int(unitPirce), - } - skuBindInfos = append(skuBindInfos, skuBindInfo) - } - _, err = updateStoresSkusWithoutSync(ctx, db, []int{toStoreID}, skuBindInfos, false, false) - } - } - if globals.IsAddEvent { - mapAfter := make(map[string]interface{}) - mapAfter["ToStoreIDs"] = toStoreIDs - mapAfter["CopyMode"] = copyMode - mapAfter["IsScale"] = isScale - mapAfter["PricePercentage"] = pricePercentage - mapBefore := make(map[string]interface{}) - mapBefore["FromStoreID"] = fromStoreID - err = AddEventDetail(db, ctx, model.OperateCopyStoreSkus, 0, model.ThingTypeSku, fromStoreID, BuildDiffData(mapBefore), BuildDiffData(mapAfter)) - } - return num, errList.GetErrListAsOne() -} - -func shouldPendingStorePriceChange(ctx *jxcontext.Context, storeID int, skuBindInfo *StoreSkuBindInfo) (shouldPending bool, err error) { - if globals.EnablePendingChange { - if skuBindInfo.IsFocus != 1 && (ctx.GetLoginType() == weixin.AuthTypeMP || ctx.GetLoginType() == weixin.AuthTypeMini || ctx.GetUserName() == "fakeboss") { - db := dao.GetDB() - store := &model.Store{} - store.ID = storeID - if err = dao.GetEntity(db, store); err != nil { - return false, err - } - return jxutils.TranslateStorePriceType(store.ChangePriceType) == model.StoreChangePriceTypeNeedApprove, nil - } - } - return false, nil -} - -func filterStorePriceChange(ctx *jxcontext.Context, storeIDs []int, skuBindInfos []*StoreSkuBindInfo) (filteredStoreIDs []int, filteredSkuBindInfos []*StoreSkuBindInfo, err error) { - globals.SugarLogger.Debug("filterStorePriceChange") - if globals.EnablePendingChange { - db := dao.GetDB() - dao.Begin(db) - defer dao.Rollback(db) - for _, storeID := range storeIDs { - for _, skuBindInfo := range skuBindInfos { - shouldPending, err2 := shouldPendingStorePriceChange(ctx, storeID, skuBindInfo) - if err = err2; err != nil { - return nil, nil, err - } - if shouldPending && (skuBindInfo.UnitPrice != 0 || skuBindInfo.IsFocus == 1) { - var ( - opInfoList []*StoreOpRequestInfo - sql string - sqlParams []interface{} - opType int8 - ) - - if skuBindInfo.IsFocus == 1 { - opType = model.RequestTypeFocusSkuName - sql = ` - SELECT DISTINCT t1.*, t3.unit_price - FROM store_op_request t1 - JOIN sku t2 ON t2.name_id = t1.item_id AND t2.deleted_at = ? - LEFT JOIN store_sku_bind t3 ON t3.store_id = t1.store_id AND t3.sku_id = t2.id AND t3.deleted_at = ? - WHERE t1.store_id = ? AND t1.item_id = ? AND t1.deleted_at = ? AND t1.type IN (?, ?)` - sqlParams = []interface{}{ - utils.DefaultTimeValue, - utils.DefaultTimeValue, - storeID, - skuBindInfo.NameID, - utils.DefaultTimeValue, - model.RequestTypeChangePrice, - model.RequestTypeFocusSkuName, - } - } else { - opType = model.RequestTypeChangePrice - sql = ` - SELECT DISTINCT t3.*, t1.unit_price - FROM store_sku_bind t1 - JOIN sku t2 ON t2.id = t1.sku_id AND t2.name_id = ? AND t2.deleted_at = ? - LEFT JOIN store_op_request t3 ON t3.store_id = t1.store_id AND t3.item_id = t2.name_id AND t3.deleted_at = ? AND t3.type IN (?, ?) - WHERE t1.store_id = ? AND t1.deleted_at = ?` - sqlParams = []interface{}{ - skuBindInfo.NameID, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - model.RequestTypeChangePrice, - model.RequestTypeFocusSkuName, - storeID, - utils.DefaultTimeValue, - } - } - - if err = dao.GetRows(db, &opInfoList, sql, sqlParams...); err != nil { - return nil, nil, err - } - if len(opInfoList) > 1 { - panic(fmt.Sprintf("filterStorePriceChange more than one row, storeID:%d, skuBindInfo:%s, result:%s", storeID, utils.Format4Output(skuBindInfo, false), utils.Format4Output(opInfoList, false))) - } - existRow := len(opInfoList) == 1 - existRequestOp := existRow && opInfoList[0].ID != 0 - var changeReq *model.StoreOpRequest - if existRequestOp { - if opInfoList[0].Type != opType { - return nil, nil, fmt.Errorf("filterStorePriceChange,关注与修改价格只应该存在一个待审核请求,已存在的:%s,新来的,storeID:%d, skuBindInfo:%s", utils.Format4Output(opInfoList[0], false), storeID, utils.Format4Output(skuBindInfo, false)) - } - changeReq = &opInfoList[0].StoreOpRequest - } else { - changeReq = &model.StoreOpRequest{} - } - if existRequestOp && opInfoList[0].UnitPrice == skuBindInfo.UnitPrice { - changeReq.Status = model.RequestStatusCanceled - changeReq.DeletedAt = time.Now() - } else { - changeReq.Status = model.RequestStatusNew - changeReq.Type = opType - changeReq.StoreID = storeID - changeReq.ItemID = skuBindInfo.NameID - changeReq.UserID = ctx.GetUserName() - changeReq.IntParam1 = skuBindInfo.UnitPrice - changeReq.IntParam2 = skuBindInfo.IsSale - if len(skuBindInfo.Skus) > 0 { - changeReq.JsonParam = string(utils.MustMarshal(skuBindInfo.Skus)) - } - } - if existRequestOp { - dao.WrapUpdateULEntity(changeReq, ctx.GetUserName()) - if _, err = dao.UpdateEntity(db, changeReq); err != nil { - return nil, nil, err - } - } else { - if !existRow || opInfoList[0].UnitPrice != skuBindInfo.UnitPrice { - dao.WrapAddIDCULDEntity(changeReq, ctx.GetUserName()) - if err = dao.CreateEntity(db, changeReq); err != nil { - return nil, nil, err - } - } - } - // 去除价格相关的部分 - if skuBindInfo.IsFocus == 1 { - skuBindInfo.IsFocus = 0 - } - skuBindInfo.UnitPrice = 0 - } - } - } - dao.Commit(db) - } - return storeIDs, skuBindInfos, nil -} - -func AcceptStoreOpRequests(ctx *jxcontext.Context, reqIDs []int) (err error) { - if globals.EnablePendingChange { - if len(reqIDs) > 0 { - subErrors := make(map[int]error) - infoMap, err2 := getStoreOpRequestsInfo(reqIDs) - if err = err2; err != nil { - return err - } - for reqID, op := range infoMap { - if op.Status == model.RequestStatusNew { - skuBindInfo := &StoreSkuBindInfo{ - NameID: op.ItemID, - UnitPrice: op.IntParam1, - IsSale: op.IntParam2, - } - if op.Type == model.RequestTypeFocusSkuName { - skuBindInfo.IsFocus = 1 - } - if op.JsonParam != "" { - if err2 = utils.UnmarshalUseNumber([]byte(op.JsonParam), &skuBindInfo.Skus); err2 != nil { - subErrors[reqID] = err2 - } - } - if err2 == nil { - _, err2 := UpdateStoresSkus(ctx, 0, []int{op.StoreID}, []*StoreSkuBindInfo{skuBindInfo}, false, false, false, false) - isLocalSucess := true - if err2 != nil { - subErrors[reqID] = err2 - if !isSyncError(err2) { - isLocalSucess = false - } - } - if isLocalSucess { - weixinmsg.NotifyStoreOpRequestStatus(true, op.StoreID, op.ItemID, jxutils.ComposeSpuName(op.SkuNamePrefix, op.SkuNameName, 0), op.UnitPrice, op.IntParam1, "") - if err2 := changeStoreOpStatus(ctx, []int{reqID}, model.RequestStatusAccepted, ""); err2 != nil { - subErrors[reqID] = err2 - } - } - } - } - } - if len(subErrors) > 0 { - errMsg := "" - for k, v := range subErrors { - errMsg += fmt.Sprintf("req:%d, error:%s\n", k, v.Error()) - } - err = errors.New(errMsg) - } - } - } - return err -} - -func RejectStoreOpRequests(ctx *jxcontext.Context, reqIDs []int, rejectReason string) (err error) { - infoMap, err := getStoreOpRequestsInfo(reqIDs) - if err != nil { - return err - } - if err = changeStoreOpStatus(ctx, reqIDs, model.RequestStatusRejected, rejectReason); err == nil { - for _, info := range infoMap { - weixinmsg.NotifyStoreOpRequestStatus(false, info.StoreID, info.ItemID, jxutils.ComposeSpuName(info.SkuNamePrefix, info.SkuNameName, 0), info.UnitPrice, info.IntParam1, rejectReason) - } - } - return err -} - -// 当前些函数只针对type为: RequestTypeChangePrice与RequestTypeFocusSkuName的查询才有效 -func GetStoreOpRequests(ctx *jxcontext.Context, fromTime, toTime time.Time, keyword string, storeIDs, itemIDs, typeList, statusList []int, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) { - if globals.EnablePendingChange { - sql := ` - SELECT SQL_CALC_FOUND_ROWS - t1.id, t1.created_at, t1.updated_at, t1.last_operator, t1.deleted_at, - t1.type, t1.store_id, t1.item_id, t1.status, t1.user_id, t1.int_param1, t1.int_param2, t1.remark, - t2.name store_name, t3.prefix sku_name_prefix, t3.name sku_name_name, MAX(IF(t1.status = ?, t5.unit_price, t1.int_param0)) unit_price - FROM store_op_request t1 - JOIN store t2 ON t1.store_id = t2.id - JOIN sku_name t3 ON t1.item_id = t3.id AND t3.deleted_at = ? - JOIN sku t4 ON t3.id = t4.name_id AND t4.deleted_at = ? - LEFT JOIN store_sku_bind t5 ON t1.store_id = t5.store_id AND t4.id = t5.sku_id AND t5.deleted_at = ? - WHERE 1 = 1` - sqlParams := []interface{}{ - model.RequestStatusNew, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - } - if keyword != "" { - keywordLike := "%" + keyword + "%" - sql += " AND ( t2.name LIKE ? OR t3.name LIKE ?" - sqlParams = append(sqlParams, keywordLike, keywordLike) - if keywordInt64, err2 := strconv.ParseInt(keyword, 10, 64); err2 == nil { - sql += " OR t1.store_id = ? OR t1.item_id = ?" - sqlParams = append(sqlParams, keywordInt64, keywordInt64) - } - sql += ")" - } - if fromTime != utils.DefaultTimeValue { - sql += " AND t1.created_at >= ?" - sqlParams = append(sqlParams, fromTime) - } - if toTime != utils.DefaultTimeValue { - sql += " AND t1.created_at <= ?" - sqlParams = append(sqlParams, toTime) - } - if len(storeIDs) > 0 { - sql += " AND t1.store_id IN (" + dao.GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - if len(itemIDs) > 0 { - sql += " AND t1.item_id IN (" + dao.GenQuestionMarks(len(itemIDs)) + ")" - sqlParams = append(sqlParams, itemIDs) - } - if len(typeList) > 0 { - sql += " AND t1.type IN (" + dao.GenQuestionMarks(len(typeList)) + ")" - sqlParams = append(sqlParams, typeList) - } - if len(statusList) > 0 { - sql += " AND t1.status IN (" + dao.GenQuestionMarks(len(statusList)) + ")" - sqlParams = append(sqlParams, statusList) - } - - sql += ` - GROUP BY 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 - ORDER BY 1 DESC - LIMIT ? OFFSET ?` - pageSize = jxutils.FormalizePageSize(pageSize) - sqlOffset := offset - sqlPageSize := pageSize - sqlParams = append(sqlParams, sqlPageSize, sqlOffset) - db := dao.GetDB() - // globals.SugarLogger.Debug(sql) - // globals.SugarLogger.Debug(utils.Format4Output(sqlParams, false)) - var requestList []*StoreOpRequestInfo - dao.Begin(db) - defer dao.Commit(db) - if err = dao.GetRows(db, &requestList, sql, sqlParams...); err == nil { - return &model.PagedInfo{ - TotalCount: dao.GetLastTotalRowCount(db), - Data: requestList, - }, nil - } - } - return nil, err -} - -func getStoreOpRequestsInfo(reqIDs []int) (infoMap map[int]*StoreOpRequestInfo, err error) { - infoMap = make(map[int]*StoreOpRequestInfo) - if len(reqIDs) > 0 { - sql := ` - SELECT DISTINCT t1.*, t4.name store_name, t2.prefix sku_name_prefix, t2.name sku_name_name, t3.unit_price - FROM store_op_request t1 - JOIN sku_name t2 ON t2.id = t1.item_id - JOIN sku t5 ON t5.name_id = t1.item_id AND t5.deleted_at = ? - LEFT JOIN store_sku_bind t3 ON t3.store_id = t1.store_id AND t3.sku_id = t5.id AND t3.deleted_at = ? - JOIN store t4 ON t4.id = t1.store_id - WHERE t1.id IN (` + dao.GenQuestionMarks(len(reqIDs)) + ")" - sqlParams := []interface{}{ - utils.DefaultTimeValue, - utils.DefaultTimeValue, - reqIDs, - } - db := dao.GetDB() - var infoList []*StoreOpRequestInfo - if err = dao.GetRows(db, &infoList, sql, sqlParams...); err == nil { - for _, v := range infoList { - infoMap[v.ID] = v - } - if len(reqIDs) > len(infoMap) { - missingReqIDs := []int{} - for _, reqID := range reqIDs { - if infoMap[reqID] == nil { - missingReqIDs = append(missingReqIDs, reqID) - } - } - err = fmt.Errorf("不能找到如下的请求ID:%s", utils.Format4Output(missingReqIDs, true)) - } - } - } else { - err = errors.New("没有找到指定的请求ID") - } - return infoMap, err -} - -func changeStoreOpStatus(ctx *jxcontext.Context, reqIDs []int, status int8, rejectReason string) (err error) { - globals.SugarLogger.Debugf("changeStoreOpStatus, reqIDs:%v", reqIDs) - if globals.EnablePendingChange { - if len(reqIDs) > 0 { - infoMap, err2 := getStoreOpRequestsInfo(reqIDs) - if err = err2; err != nil { - return err - } - db := dao.GetDB() - dao.Begin(db) - defer dao.Rollback(db) - for _, reqID := range reqIDs { - op := &model.StoreOpRequest{} - op.Remark = rejectReason - op.Status = status - if infoMap[reqID] != nil { - op.IntParam0 = infoMap[reqID].UnitPrice - } - dao.WrapUpdateULEntity(op, ctx.GetUserName()) - op.DeletedAt = time.Now() - op.ID = reqID - // globals.SugarLogger.Debug(utils.Format4Output(op, false)) - if _, err = dao.UpdateEntity(db, op, "IntParam0", "Remark", "Status", "DeletedAt", "LastOperator", "UpdatedAt"); err != nil { - return err - } - } - dao.Commit(db) - } - } - return err -} - -func setStoreSkuBindStatus(skuBind *model.StoreSkuBind, status int8) { - skuBind.JdSyncStatus |= status - skuBind.EbaiSyncStatus |= status - skuBind.MtwmSyncStatus |= status - skuBind.YbSyncStatus |= status - skuBind.JdsSyncStatus |= status -} - -func checkStoreExisting(db *dao.DaoDB, storeID int) (store *model.Store, err error) { - store = &model.Store{} - store.ID = storeID - if err = dao.GetEntity(db, store); err != nil { - if err == orm.ErrNoRows { - return nil, fmt.Errorf("门店:%d不存在", storeID) - } - return nil, err - } - return store, nil -} - -func RefreshStoresSkuByVendor(ctx *jxcontext.Context, storeIDs []int, vendorID int, isAsync bool) (hint string, err error) { - if vendorID != model.VendorIDJD { - return "", fmt.Errorf("此功能当前只支持京东到家平台") - } - db := dao.GetDB() - storeMapList, err := dao.GetStoresMapList(db, []int{vendorID}, storeIDs, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "") - if err != nil { - return "", err - } - if len(storeMapList) != len(storeIDs) { - return "", fmt.Errorf("门店绑定信息不匹配,请确定门店绑定且只绑定了京东平台") - } - storeMap := make(map[int]*dao.StoreDetail) - for _, v := range storeMapList { - if v.VendorID != vendorID { - return "", fmt.Errorf("门店%d绑定的不(只)是京东", v.StoreID) - } - storeMap[v.StoreID], err = dao.GetStoreDetail(db, v.StoreID, v.VendorID) - if err != nil { - return "", err - } - } - skuList, err := dao.GetSkusWithVendor(db, []int{vendorID}, nil, nil, nil, false) - if err != nil { - return "", err - } - skuNameMap := make(map[int]*model.SkuName) - skuMap := make(map[int]*dao.StoreSkuSyncInfo) - bareStoreSkuMap := make(map[string][]*partner.StoreSkuInfo) - for _, sku := range skuList { - if skuNameMap[sku.NameID] == nil { - skuNameMap[sku.NameID] = &model.SkuName{ - Unit: sku.Unit, - } - } - skuMap[sku.ID] = sku - - bareStoreSkuMap[sku.VendorOrgCode] = append(bareStoreSkuMap[sku.VendorOrgCode], &partner.StoreSkuInfo{ - SkuID: sku.ID, - VendorSkuID: sku.VendorSkuID, - }) - } - - handler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IPurchasePlatformStoreSkuHandler) - var storeSkuList []*model.StoreSkuBind - rootTask := tasksch.NewParallelTask(fmt.Sprintf("根据厂家门店商品信息相应刷新本地数据:%v", storeIDs), tasksch.NewParallelConfig().SetParallelCount(1), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - oneStoreMap := batchItemList[0].(*model.StoreMap) - subTask := tasksch.NewSeqTask(fmt.Sprintf("根据厂家门店商品信息相应刷新本地数据:%s", model.VendorChineseNames[oneStoreMap.VendorID]), ctx, - func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - bareStoreSkuList, err2 := handler.GetStoreSkusBareInfo(ctx, oneStoreMap.VendorOrgCode, task, oneStoreMap.StoreID, oneStoreMap.VendorStoreID, bareStoreSkuMap[oneStoreMap.VendorOrgCode]) - // globals.SugarLogger.Debug(utils.Format4Output(bareStoreSkuList, false)) - if err = err2; err == nil || len(bareStoreSkuList) > 0 { - err = nil // todo 如果部分失败,强制忽略错误 - for _, v := range bareStoreSkuList { - storeSkuList = append(storeSkuList, &model.StoreSkuBind{ - StoreID: oneStoreMap.StoreID, - SkuID: v.SkuID, - Status: v.Status, - Price: int(v.VendorPrice), - }) - } - } - case 1: - if len(storeSkuList) > 0 { - for _, v := range storeSkuList { - sku := skuMap[v.SkuID] - skuName := skuNameMap[sku.NameID] - if skuName.IsGlobal == 0 && (jxutils.IsSkuSpecial(sku.SpecQuality, sku.SpecUnit) || skuName.Unit != model.SpecialUnit) { - skuName.Price = v.Price // 标准价 - skuName.IsGlobal = 1 - } - } - for _, v := range storeSkuList { - sku := skuMap[v.SkuID] - skuName := skuNameMap[sku.NameID] - if skuName.IsGlobal == 0 { - if skuName.Price == 0 { - skuName.Price = jxutils.CaculateUnitPrice(v.Price, sku.SpecQuality, sku.SpecUnit, skuName.Unit) - } else { - skuName.Price = (skuName.Price + jxutils.CaculateUnitPrice(v.Price, sku.SpecQuality, sku.SpecUnit, skuName.Unit)) / 2 - } - } - } - for _, v := range storeSkuList { - pricePercentage, priceAdd := jxutils.GetPricePercentageByVendorPrice(storeMap[v.StoreID].PricePercentagePackObj, v.Price, int(storeMap[v.StoreID].PricePercentage)) - skuName := skuNameMap[skuMap[v.SkuID].NameID] - v.Price = jxutils.CaculateSkuPriceFromVendor(v.Price, pricePercentage, priceAdd) - v.UnitPrice = jxutils.CaculateSkuPriceFromVendor(skuName.Price, pricePercentage, priceAdd) - dao.WrapAddIDCULDEntity(v, ctx.GetUserName()) - setStoreSkuBindStatus(v, model.SyncFlagNewMask) - v.JdSyncStatus = 0 - } - } - case 2: - if len(storeSkuList) > 0 { - dao.Begin(db) - defer func() { - if r := recover(); r != nil || err != nil { - dao.Rollback(db) - if r != nil { - panic(r) - } - } - }() - if _, err = dao.ExecuteSQL(db, ` - DELETE t1 - FROM store_sku_bind t1 - WHERE t1.store_id IN ( - `+dao.GenQuestionMarks(len(storeIDs))+")", storeIDs); err == nil { - if err = dao.CreateMultiEntities(db, storeSkuList); err == nil { - hint = utils.Int2Str(len(storeSkuList)) - dao.Commit(db) - } - } - } - } - return nil, err - }, 3) - tasksch.HandleTask(subTask, task, true).Run() - _, err = subTask.GetResult(0) - return retVal, err - }, storeMapList) - tasksch.ManageTask(rootTask).Run() - if isAsync { - hint = rootTask.GetID() - } else { - _, err = rootTask.GetResult(0) - } - return hint, err -} - -func GetVendorStoreSkusInfo(ctx *jxcontext.Context, storeID int, vendorIDs, skuIDs []int, isContinueWhenError bool) (skuVendorMap map[int][]*partner.StoreSkuInfo, err error) { - globals.SugarLogger.Debugf("GetVendorStoreSkusInfo, storeID:%d, vendorIDs:%v, skuID:%v", storeID, vendorIDs, skuIDs) - db := dao.GetDB() - var locker sync.RWMutex - skuVendorMap = make(map[int][]*partner.StoreSkuInfo) - _, err = CurVendorSync.LoopStoresMap(ctx, db, fmt.Sprintf("GetVendorStoreSkusInfo storeID:%d", storeID), false, false, vendorIDs, []int{storeID}, - func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) { - loopMapInfo := batchItemList[0].(*LoopStoreMapInfo) - if handler, _ := partner.GetPurchasePlatformFromVendorID(loopMapInfo.VendorID).(partner.IPurchasePlatformStoreSkuHandler); handler != nil { - storeSkuList, err2 := dao.GetStoreSkus2(db, loopMapInfo.VendorID, storeID, skuIDs, false) - if err = err2; err == nil && len(storeSkuList) > 0 { - bareStoreSkuInfoList := make([]*partner.StoreSkuInfo, len(skuIDs)) - for k, v := range storeSkuList { - bareStoreSkuInfoList[k] = &partner.StoreSkuInfo{ - SkuID: v.SkuID, - VendorSkuID: v.VendorSkuID, - } - } - outBareStoreSkuInfoList, err2 := handler.GetStoreSkusBareInfo(ctx, loopMapInfo.StoreMapList[0].VendorOrgCode, t, loopMapInfo.StoreMapList[0].StoreID, loopMapInfo.StoreMapList[0].VendorStoreID, bareStoreSkuInfoList) - if err = err2; err == nil && outBareStoreSkuInfoList != nil { - locker.Lock() - defer locker.Unlock() - skuVendorMap[loopMapInfo.VendorID] = outBareStoreSkuInfoList - } - } - } - return nil, err - }, true) - if err != nil { - skuVendorMap = nil - } - return skuVendorMap, err -} - -func SyncJdStoreProducts(ctx *jxcontext.Context, storeIDs, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { - db := dao.GetDB() - isManageIt := len(storeIDs) != 1 || len(skuIDs) == 0 || len(skuIDs) > 8 - hint, err = CurVendorSync.LoopStoresMap(ctx, db, fmt.Sprintf("京东商家商品状态同步:%v", storeIDs), isAsync, isManageIt, []int{model.VendorIDJD}, storeIDs, - func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - loopMapInfo := batchItemList[0].(*LoopStoreMapInfo) - if handler := partner.GetPurchasePlatformFromVendorID(loopMapInfo.VendorID); handler != nil { - jdHandler := handler.(*jd.PurchaseHandler) - hint, err2 := jdHandler.SyncStoreProducts(ctx, loopMapInfo.StoreMapList[0].VendorOrgCode, t, loopMapInfo.StoreMapList[0].StoreID, skuIDs, false, isContinueWhenError) - if err = err2; err == nil { - retVal = []interface{}{hint} - } - } - return retVal, partner.AddVendorInfo2Err(err, loopMapInfo.VendorID) - }, isContinueWhenError) - return hint, err -} - -func GetMissingStoreSkuFromOrder(ctx *jxcontext.Context, fromTime time.Time) (missingList []*StoreSkuBindInfo, err error) { - storeSkuList, err := dao.GetMissingStoreSkuFromOrder(dao.GetDB(), nil, fromTime) - if err == nil { - storeSkuNameMap := make(map[int64]*StoreSkuBindInfo) - for _, v := range storeSkuList { - skuName := storeSkuNameMap[jxutils.Combine2Int(v.StoreID, v.NameID)] - if skuName == nil { - skuName = &StoreSkuBindInfo{ - StoreID: v.StoreID, - NameID: v.NameID, - IsFocus: 1, - IsSale: 1, - // 这里没有考虑平台价格比例 - UnitPrice: jxutils.CaculateUnitPrice(v.RefPrice, v.SpecQuality, v.SpecUnit, v.Unit), - } - missingList = append(missingList, skuName) - } - skuName.Skus = append(skuName.Skus, &StoreSkuBindSkuInfo{ - SkuID: v.SkuID, - }) - } - } - return missingList, err -} - -func AutoSaleStoreSku(ctx *jxcontext.Context, storeIDs []int, isNeedSync bool) (err error) { - db := dao.GetDB() - storeSkuList, err := dao.GetAutoSaleStoreSku(db, storeIDs) - if err != nil { - return err - } - storeSkuMap := make(map[int][]*model.StoreSkuBind) - for _, v := range storeSkuList { - storeSkuMap[v.StoreID] = append(storeSkuMap[v.StoreID], v) - } - now := time.Now() - for storeID, storeSkuList := range storeSkuMap { - var skuIDs []int - for _, storeSku := range storeSkuList { - if now.Sub(storeSku.AutoSaleAt) > 0 { - storeSku.AutoSaleAt = utils.DefaultTimeValue - if storeSku.Status != model.SkuStatusNormal { - storeSku.Status = model.SkuStatusNormal - skuIDs = append(skuIDs, storeSku.SkuID) - } - if _, err = dao.UpdateEntity(db, storeSku, "AutoSaleAt", model.FieldStatus); err != nil { - return err - } - } - } - if isNeedSync && len(skuIDs) > 0 { - if _, err = CurVendorSync.SyncStoresSkus(ctx, nil, model.SyncFlagSaleMask, db, nil, []int{storeID}, skuIDs, false, true, true); err != nil { - return err - } - } - } - return err -} - -func ReCalculateJxPrice(db *dao.DaoDB, ctx *jxcontext.Context, storeIDs []int) (hint string, err error) { - task := tasksch.NewParallelTask("刷新京西平台价格", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeID := batchItemList[0].(int) - if storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDJX); err == nil { - if storeSkuList, err := dao.GetStoresSkusInfo(db, []int{storeID}, nil); err == nil { - for _, skuBind := range storeSkuList { - skuBind.JxPrice = jxutils.CaculatePriceByPricePack(storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage), skuBind.Price) - dao.UpdateEntity(db, skuBind, "JxPrice") - } - } else { - return nil, err - } - } else { - return nil, err - } - return retVal, err - }, storeIDs) - tasksch.HandleTask(task, nil, true).Run() - hint = task.GetID() - return hint, err -} - -func ReCalculateJxPriceLight(db *dao.DaoDB, ctx *jxcontext.Context, storeID int) (err error) { - if storeID != 0 { - if storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDJX); err == nil { - if storeSkuList, err := dao.GetStoresSkusInfo(db, []int{storeID}, nil); err == nil { - for _, skuBind := range storeSkuList { - skuBind.JxPrice = jxutils.CaculatePriceByPricePack(storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage), skuBind.Price) - dao.UpdateEntity(db, skuBind) - } - } else { - return err - } - } else { - return err - } - } - return err -} - -func GetTopSkusByStoreIDs(ctx *jxcontext.Context, storeIDs []int) (storeSkuNameExt2 []*dao.StoreSkuNameExt, err error) { - var ( - db = dao.GetDB() - skuMap = make(map[int]*dao.StoreSkuNameExt) - ) - if len(storeIDs) == 0 { - return storeSkuNameExt2, err - } - storeSkuNameExt, err := dao.GetTopSkusByStoreIDs(db, storeIDs) - if err != nil { - return nil, err - } - for _, v := range storeSkuNameExt { - if skuMap[v.SkuID] == nil { - skuMap[v.SkuID] = v - } - if skuMap[v.SkuID] != nil && v.Count != 0 { - skuMap[v.SkuID] = v - } - } - for _, v := range skuMap { - storeSkuNameExt2 = append(storeSkuNameExt2, v) - } - for i := 0; i < len(storeSkuNameExt2)-1; i++ { - for j := 0; j < len(storeSkuNameExt2)-i-1; j++ { - if storeSkuNameExt2[j].Count < storeSkuNameExt2[j+1].Count { - tmp := storeSkuNameExt2[j] - storeSkuNameExt2[j] = storeSkuNameExt2[j+1] - storeSkuNameExt2[j+1] = tmp - } - } - } - return storeSkuNameExt2, err -} - -func GetTopSkusByCityCode(ctx *jxcontext.Context, cityCode, storeID int) (skuNameAndPlaceList []*dao.SkuNameAndPlace, err error) { - db := dao.GetDB() - orderCreate := time.Now().AddDate(0, -1, 0) - var skuNameAndPlace []*dao.SkuNameAndPlace - if cityCode > 0 { - skuNameAndPlace, err = dao.GetTopSkusByCityCode(db, cityCode, orderCreate) - } else { - skuNameAndPlace, err = dao.GetTopSkusByNoCityCode(db) - } - if storeID > 0 { - var skuNameList []*model.SkuName - //不可售的商品nameID列表 - sql := ` - SELECT DISTINCT b.name_id id - FROM store_sku_bind a - JOIN sku b ON a.sku_id = b.id AND b.deleted_at = ? - WHERE a.deleted_at = ? - AND a.store_id = ? - AND a.status <> ? - AND b.name_id NOT IN(SELECT DISTINCT b.name_id - FROM store_sku_bind a - JOIN sku b ON a.sku_id = b.id AND b.deleted_at = ? - WHERE a.deleted_at = ? - AND a.store_id = ? - AND a.status = ?) - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - utils.DefaultTimeValue, - storeID, - model.StoreSkuBindStatusNormal, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - storeID, - model.StoreSkuBindStatusNormal, - } - err = dao.GetRows(db, &skuNameList, sql, sqlParams...) - var skuNameMap = make(map[int]*model.SkuName) - for _, v := range skuNameList { - skuNameMap[v.ID] = v - } - store, err := dao.GetStoreDetail(db, storeID, -1) - if err != nil { - return nil, err - } - var payPercentage int - if store.PayPercentage < 50 { - payPercentage = 70 - } else { - payPercentage = store.PayPercentage - } - for _, v := range skuNameAndPlace { - if skuNameMap[v.ID] != nil { - var skuList []*model.SkuAndName - storeSkuSyncInfo, _ := dao.GetStoreSkusAndSkuName(db, []int{storeID}, nil, []int{v.ID}) - for _, storeSkuSync := range storeSkuSyncInfo { - sku, _ := dao.GetSkus(db, []int{storeSkuSync.ID}, nil, nil, nil, nil) - sku[0].Price = int(storeSkuSync.Price) - skuList = append(skuList, sku...) - } - v.UnitPrice = int(storeSkuSyncInfo[0].UnitPrice) - v.Skus = skuList - for _, vv := range skuList { - var ( - storeSkuNameExt []*dao.StoreSkuNameExt - skusList []*dao.StoreSkuExt - ) - vv.StoreSkuStatus = model.StoreSkuBindStatusDontSale - skus := &dao.StoreSkuExt{ - SkuID: vv.ID, - BindPrice: vv.Price, - } - skusList = append(skusList, skus) - storeSkuName := &dao.StoreSkuNameExt{ - Skus: skusList, - StoreID: storeID, - PayPercentage: payPercentage, - } - storeSkuNameExt = append(storeSkuNameExt, storeSkuName) - skuNamesInfo := &dao.StoreSkuNamesInfo{ - SkuNames: storeSkuNameExt, - } - dao.UpdateActPrice4StoreSkuNameNew(db, []int{storeID}, []int{vv.ID}, skuNamesInfo, -1) - if skuNamesInfo.SkuNames[0].Skus[0] != nil { - vv.ActPrice = skuNamesInfo.SkuNames[0].Skus[0].ActPrice - vv.ActID = skuNamesInfo.SkuNames[0].Skus[0].ActID - vv.ActType = skuNamesInfo.SkuNames[0].Skus[0].ActType - vv.EarningPrice = skuNamesInfo.SkuNames[0].Skus[0].EarningPrice - vv.EarningActID = skuNamesInfo.SkuNames[0].Skus[0].EarningActID - } - } - skuNameAndPlaceList = append(skuNameAndPlaceList, v) - } - } - } else { - skuNameAndPlaceList = append(skuNameAndPlaceList, skuNameAndPlace...) - } - i := 1 - for _, v := range skuNameAndPlaceList { - v.Sequence = i - i++ - } - if len(skuNameAndPlaceList) <= 100 { - return skuNameAndPlaceList, err - } else { - return skuNameAndPlaceList[0:100], err - } -} - -func GetTopCategoriesByStoreIDs(ctx *jxcontext.Context, storeIDs []int) (skuCategory []*model.SkuCategory, err error) { - var ( - skuCategory2 []*model.SkuCategory - skuCategoryMap = make(map[int]*model.SkuCategory) - limit = 10 - ) - if len(storeIDs) == 0 { - return skuCategory, err - } - db := dao.GetDB() - skuCategory, err = dao.GetTopCategoriesByStoreIDs(db, storeIDs, limit) - //若大于等于10个就不用做下面的操作 - if len(skuCategory) >= limit { - return skuCategory, err - } - if len(skuCategory) > 0 { - for _, v := range skuCategory { - skuCategoryMap[v.ID] = v - } - } - //推荐分类,若不满10个,则填满10个 - if (len(skuCategory) < limit && len(skuCategory) > 0) || len(skuCategory) == 0 { - skuCategory2, err = dao.GetCategories(db, -1, 1, nil, false) - if len(skuCategory2) > 0 { - for _, v := range skuCategory2 { - if skuCategoryMap[v.ID] == nil { - if !strings.Contains(v.Name, "赠品") { - skuCategory = append(skuCategory, v) - } - } - if len(skuCategory) >= limit { - break - } - } - } - } - if err != nil { - return nil, err - } - return skuCategory, err -} - -func RefershStoreSkusMidPrice(ctx *jxcontext.Context, storeIDs []int, isCountry bool) (err error) { - db := dao.GetDB() - if len(storeIDs) == 0 { - return err - } - for _, v := range storeIDs { - var skuBindInfos []*StoreSkuBindInfo - store, err := dao.GetStoreDetail(db, v, -1) - if err != nil { - return err - } - var payPercentage int - if store.PayPercentage < 50 { - payPercentage = 70 - } else { - payPercentage = store.PayPercentage - } - storeSkuList, err := dao.GetStoresSkusInfo(db, []int{v}, nil) - for _, storeSku := range storeSkuList { - var priceReferList []*model.PriceReferSnapshot - if isCountry { - priceReferList, err = dao.GetPriceReferSnapshotNoPage(db, []int{0}, []int{storeSku.SkuID}, nil, utils.Time2Date(time.Now().AddDate(0, 0, -1))) - } else { - priceReferList, err = dao.GetPriceReferSnapshotNoPage(db, []int{store.CityCode}, []int{storeSku.SkuID}, nil, utils.Time2Date(time.Now().AddDate(0, 0, -1))) - } - if err != nil { - return err - } - if len(priceReferList) > 0 { - //TODO 高于中位价20%才刷, 2020-05-08 - if priceReferList[0].MidUnitPrice >= 500 { - if storeSku.UnitPrice > priceReferList[0].MidUnitPrice/payPercentage*120 { - skuBindInfo := &StoreSkuBindInfo{ - NameID: priceReferList[0].NameID, - UnitPrice: priceReferList[0].MidUnitPrice / payPercentage * 120, - } - skuBindInfos = append(skuBindInfos, skuBindInfo) - } - } - } - } - updateStoresSkusWithoutSync(ctx, db, []int{v}, skuBindInfos, false, false) - } - if err == nil { - CreateStorePriceScore(ctx) - } - return err -} - -func RefreshJxPriceByExcel(ctx *jxcontext.Context, storeIDs []int, files []*multipart.FileHeader, isAsync, isContinueWhenError bool) (hint string, err error) { - if len(files) == 0 { - return "", errors.New("没有文件上传!") - } - if len(storeIDs) == 0 { - return "", errors.New("请选择至少一个门店!") - } - fileHeader := files[0] - file, err := fileHeader.Open() - hint, err = RefreshJxPriceByExcelBin(ctx, storeIDs, file, true, true) - file.Close() - return hint, err -} - -func RefreshJxPriceByExcelBin(ctx *jxcontext.Context, storeIDs []int, reader io.Reader, isAsync, isContinueWhenError bool) (hint string, err error) { - var ( - storeSkuNamePriceList []*model.StoreSkuNamePrice - storeSkuNamePriceListUpdate []*model.StoreSkuNamePrice - skuBindInfosInter []interface{} - skuBindInfoList []*StoreSkuBindInfo - errMsg string - isErr bool = false - nameMap = make(map[string]string) - ) - dataLock.dataFailedList = dataLock.dataFailedList[0:0] - dataLock.dataSuccessList = dataLock.dataSuccessList[0:0] - sheetParam := &SheetParam{ - SkuNameIDCol: 5, - SkuPriceCol: 3, - SkuNameCol: 1, - SkuRow: 1, - SkuUnitCol: 2, - OutSkuIDCol: 0, - } - taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - // xlsx, err := excelize.OpenFile("111.xlsx") - xlsx, err := excelize.OpenReader(reader) - if err != nil { - return "", err - } - rows, _ := xlsx.GetRows(xlsx.GetSheetName(1)) - for rowNum, row := range rows { - if rowNum < sheetParam.SkuRow { - continue - } - storeSkuNamePrice := &model.StoreSkuNamePrice{} - errMsg += GetCellIntoStruct(rowNum, row, sheetParam, storeSkuNamePrice, nameMap) - storeSkuNamePriceList = append(storeSkuNamePriceList, storeSkuNamePrice) - } - if errMsg != "" { - return "", errors.New(errMsg) - } else { - isErr = true - } - case 1: - db := dao.GetDB() - storeSkuNamePriceListOrg, _ := dao.GetStoreSkuNamePrice(db) - CreateOrUpdateStoreSkuNamePriceByExcel(db, ctx, storeSkuNamePriceList, storeSkuNamePriceListOrg) - storeSkuNamePriceListNew, _ := dao.GetStoreSkuNamePrice(db) - storeSkuNamePriceMapNew := StoreSkuNamePriceList2Map(ctx, storeSkuNamePriceListNew) - for _, v := range storeSkuNamePriceList { - if storeSkuNamePriceMapNew[v.OutSkuID] != nil { - storeSkuNamePriceListUpdate = append(storeSkuNamePriceListUpdate, storeSkuNamePriceMapNew[v.OutSkuID]) - } - } - taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeSkuNamePrice := batchItemList[0].(*model.StoreSkuNamePrice) - var skuBindInfos []*StoreSkuBindInfo - nameIDGroup := strings.Split(storeSkuNamePrice.NameIDGroup, ",") - for _, v := range nameIDGroup { - if v != "" { - nameID := int(utils.Str2Int64(v)) - for _, vv := range storeIDs { - skuList, err2 := dao.GetStoreSkusByNameIDs(db, []int{vv}, nameID) - err = err2 - if len(skuList) > 0 { - unitPrice := 0 - if skuList[0].Unit == model.UnitNames[0] { - if storeSkuNamePrice.Unit == "KG" { - unitPrice = storeSkuNamePrice.Price / 2 - } else { - unitPrice = storeSkuNamePrice.Price - } - } else { - unitPrice = storeSkuNamePrice.Price - } - storeSkuBindInfo := &StoreSkuBindInfo{ - NameID: nameID, - UnitPrice: unitPrice, - } - skuBindInfos = append(skuBindInfos, storeSkuBindInfo) - outSuccess := DataSuccess{ - NameID: nameID, - Name: skuList[0].Name, - Unit: storeSkuNamePrice.Unit, - OrgPrice: utils.Str2Float64(utils.Int64ToStr(skuList[0].UnitPrice)) / 100, - NowPrice: utils.Str2Float64(utils.Int64ToStr(int64(unitPrice))) / 100, - MixPrice: utils.Str2Float64(utils.Int64ToStr(int64(unitPrice)-skuList[0].UnitPrice)) / 100, - } - dataLock.AppendDataSuccess(outSuccess) - } else { - //京西xx门店没有关注该商品 - outFailed := DataFailed{ - NameID: nameID, - Name: storeSkuNamePrice.Name, - Comment: fmt.Sprintf("京西[%v]门店没有关注该商品,商品nameID[%v],Excel上商品名[%v]", vv, nameID, storeSkuNamePrice.Name), - } - dataLock.AppendDataFailed(outFailed) - } - } - } else { - //nameID为空,还未填写nameID - outFailed := DataFailed{ - NameID: 0, - Name: storeSkuNamePrice.Name, - Comment: fmt.Sprintf("商品nameID为空!,还未填写商品nameID,Excel上商品名[%v]", storeSkuNamePrice.Name), - } - dataLock.AppendDataFailed(outFailed) - } - } - retVal = skuBindInfos - return retVal, err - } - taskParallel := tasksch.NewParallelTask("刷新京西价", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, taskFunc, storeSkuNamePriceListUpdate) - tasksch.HandleTask(taskParallel, task, true).Run() - skuBindInfosInter, err = taskParallel.GetResult(0) - case 2: - //更新京西价 - for _, v := range skuBindInfosInter { - skuBindInfoList = append(skuBindInfoList, v.(*StoreSkuBindInfo)) - } - if isErr { - UpdateStoresSkus(ctx, 0, storeIDs, skuBindInfoList, false, false, isAsync, isContinueWhenError) - } - case 3: - //写Excel - WriteToExcelJx(task, dataLock.dataSuccessList, dataLock.dataFailedList) - } - return result, err - } - taskSeq := tasksch.NewSeqTask2("根据Excel刷新京西价", ctx, isContinueWhenError, taskSeqFunc, 4) - tasksch.HandleTask(taskSeq, nil, true).Run() - if !isAsync { - _, err = taskSeq.GetResult(0) - hint = "1" - } else { - hint = taskSeq.GetID() - } - return hint, err -} - -func WriteToExcelJx(task *tasksch.SeqTask, dataSuccess []DataSuccess, dataFailed []DataFailed) (err error) { - var sheetList1 []*excel.Obj2ExcelSheetConfig - var sheetList2 []*excel.Obj2ExcelSheetConfig - var downloadURL1, downloadURL2, fileName1, fileName2 string - excelConf1 := &excel.Obj2ExcelSheetConfig{ - Title: "sheet1", - Data: dataSuccess, - CaptionList: titleListSuccess, - } - sheetList1 = append(sheetList1, excelConf1) - excelConf2 := &excel.Obj2ExcelSheetConfig{ - Title: "sheet1", - Data: dataFailed, - CaptionList: titleListFailed, - } - sheetList2 = append(sheetList2, excelConf2) - if excelConf1 != nil { - downloadURL1, fileName1, err = jxutils.UploadExeclAndPushMsg(sheetList1, "京西已更新商品") - } else { - baseapi.SugarLogger.Debug("WriteToExcel: dataSuccess is nil!") - } - if excelConf2 != nil { - downloadURL2, fileName2, err = jxutils.UploadExeclAndPushMsg(sheetList2, "未更新商品") - } else { - baseapi.SugarLogger.Debug("WriteToExcel: dataFailed is nil!") - } - if err != nil { - baseapi.SugarLogger.Errorf("WriteToExcel:upload %s , %s failed error:%v", fileName1, fileName2, err) - } else { - noticeMsg := fmt.Sprintf("[详情点我]path1=%s, path2=%s \n", downloadURL1, downloadURL2) - task.SetNoticeMsg(noticeMsg) - baseapi.SugarLogger.Debugf("WriteToExcel:upload %s ,%s success, downloadURL1:%s ,downloadURL2:%s", fileName1, fileName2, downloadURL1, downloadURL2) - } - return err -} - -func CreateOrUpdateStoreSkuNamePriceByExcel(db *dao.DaoDB, ctx *jxcontext.Context, storeSkuNamePriceList []*model.StoreSkuNamePrice, storeSkuNamePriceListOrg []*model.StoreSkuNamePrice) (err error) { - storeSkuNamePriceMap := StoreSkuNamePriceList2Map(ctx, storeSkuNamePriceListOrg) - dao.Begin(db) - defer func() { - if r := recover(); r != nil || err != nil { - dao.Rollback(db) - if r != nil { - panic(r) - } - } - }() - for _, v := range storeSkuNamePriceList { - dao.WrapAddIDCULDEntity(v, ctx.GetUserName()) - if storeSkuNamePriceMap[v.OutSkuID] != nil { - v.ID = storeSkuNamePriceMap[v.OutSkuID].ID - v.UpdatedAt = time.Now() - dao.UpdateEntity(db, v) - } else { - dao.CreateEntity(db, v) - } - } - dao.Commit(db) - return err -} - -func StoreSkuNamePriceList2Map(ctx *jxcontext.Context, storeSkuNamePriceList []*model.StoreSkuNamePrice) (result map[string]*model.StoreSkuNamePrice) { - result = make(map[string]*model.StoreSkuNamePrice, len(storeSkuNamePriceList)) - for _, v := range storeSkuNamePriceList { - result[v.OutSkuID] = v - } - return result -} - -func GetCellIntoStruct(rowNum int, row []string, sheetParam *SheetParam, storeSkuNamePrice *model.StoreSkuNamePrice, nameMap map[string]string) (errMsg string) { - for k, cell := range row { - if k == sheetParam.OutSkuIDCol { - if IsChineseChar(cell) { - return fmt.Sprintf("Excel格式排版发生了变化!在[%v]列,[%v]行附近可能增加或减少了一列", k+1, rowNum+1) - } - storeSkuNamePrice.OutSkuID = cell - } - if k == sheetParam.SkuNameCol { - storeSkuNamePrice.Name = cell - } - if k == sheetParam.SkuNameIDCol { - cellReplace := strings.ReplaceAll(cell, ",", ",") - if cellReplace != "" { - if cellReplace[len(cellReplace)-1:len(cellReplace)] == "," { - cellReplace = cellReplace[0 : len(cellReplace)-1] - } - nameIDs := strings.Split(cellReplace, ",") - for _, v := range nameIDs { - if nameMap[v] != "" { - return fmt.Sprintf(" Excel中含有重复的nameID![%v]列,[%v]行,nameID [%v]\n", k+1, rowNum+1, v) - } else { - nameMap[v] = v - } - } - } - storeSkuNamePrice.NameIDGroup = cellReplace - } - if k == sheetParam.SkuPriceCol { - if IsChineseChar(cell) { - return fmt.Sprintf("Excel格式排版发生了变化!在[%v]列,[%v]行附近可能增加或减少了一列", k+1, rowNum+1) - } - storeSkuNamePrice.Price = int(utils.Float64TwoInt64(utils.Str2Float64(cell) * 100)) - } - if k == sheetParam.SkuUnitCol { - storeSkuNamePrice.Unit = cell - } - } - return errMsg -} - -func (d *DataLock) AppendDataSuccess(dataSuccess DataSuccess) { - d.locker.Lock() - defer d.locker.Unlock() - d.dataSuccessList = append(d.dataSuccessList, dataSuccess) -} - -func (d *DataLock) AppendDataFailed(dataFailed DataFailed) { - d.locker.Lock() - defer d.locker.Unlock() - d.dataFailedList = append(d.dataFailedList, dataFailed) -} - -func IsChineseChar(str string) bool { - for _, r := range str { - if unicode.Is(unicode.Scripts["Han"], r) { - return true - } - } - return false -} - -func GetStoreCategories(ctx *jxcontext.Context, storeID, parentID int) (catList []*model.SkuCategory, err error) { - return dao.GetStoreSkuCategories(dao.GetDB(), storeID, parentID) -} - -func GetVendorStoreSkuPrice(ctx *jxcontext.Context, vendorIDs []int, skuID int, isAsync, isContinueWhenError bool) (hint string, err error) { - var ( - storeSkuListJD []DataVendorStoreSkuPrice - storeSkuListMT []DataVendorStoreSkuPrice - storeSkuListEB []DataVendorStoreSkuPrice - excelParamList []ExcelParam - ) - taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - for _, v := range vendorIDs { - vendorID := v - handler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IPurchasePlatformStoreSkuHandler) - handlerStore := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IStoreHandler) - for _, v := range apimanager.CurAPIManager.GetAppOrgCodeList(vendorID) { - vendorStoreIDs, err2 := handlerStore.GetAllStoresVendorID(ctx, v) - err = err2 - taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - vendorStoreID := batchItemList[0].(string) - var ( - inStoreSkuList []*partner.StoreSkuInfo - storeDetail *dao.StoreDetail - inStoreSku = &partner.StoreSkuInfo{} - outStoreSkuList []*partner.StoreSkuInfo - ) - db := dao.GetDB() - skuList, err := dao.GetSkusWithVendor(db, []int{vendorID}, []string{v}, nil, []int{skuID}, false) - if err != nil { - return retVal, err - } - if partner.IsMultiStore(vendorID) { - multiHandler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IMultipleStoresHandler) - storeDetail, err = multiHandler.ReadStore(ctx, v, vendorStoreID) - if len(skuList) > 0 { - inStoreSku.VendorSkuID = skuList[0].VendorSkuID - } - } else { - singleHandler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreHandler) - storeDetail, err = singleHandler.ReadStore(ctx, v, vendorStoreID) - inStoreSku.SkuID = skuID - } - inStoreSkuList = append(inStoreSkuList, inStoreSku) - storeDetail2, err := dao.GetStoreDetailByVendorStoreID(db, vendorStoreID, vendorID) - if storeDetail2 != nil { - outStoreSkuList, err = handler.GetStoreSkusBareInfo(ctx, v, task, storeDetail2.ID, vendorStoreID, inStoreSkuList) - } else { - outStoreSkuList, err = handler.GetStoreSkusBareInfo(ctx, v, task, 0, vendorStoreID, inStoreSkuList) - } - if storeDetail != nil { - if len(outStoreSkuList) == 0 { - data := DataVendorStoreSkuPrice{ - StoreID: vendorStoreID, - StoreName: storeDetail.Name, - SkuID: skuID, - SkuName: skuList[0].Name, - VendorPrice: "", - } - retVal = []DataVendorStoreSkuPrice{data} - } else { - data := DataVendorStoreSkuPrice{ - StoreID: vendorStoreID, - StoreName: storeDetail.Name, - SkuID: skuID, - SkuName: skuList[0].Name, - VendorPrice: utils.Float64ToStr(utils.Str2Float64(utils.Int64ToStr(outStoreSkuList[0].VendorPrice)) / 100), - } - retVal = []DataVendorStoreSkuPrice{data} - } - } - return retVal, err - } - taskParallel := tasksch.NewParallelTask("获取各平台所有门店某商品价格", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, taskFunc, vendorStoreIDs) - tasksch.HandleTask(taskParallel, task, true).Run() - storeSkuList, _ := taskParallel.GetResult(0) - for _, v := range storeSkuList { - if vendorID == model.VendorIDJD { - storeSkuListJD = append(storeSkuListJD, v.(DataVendorStoreSkuPrice)) - } - if vendorID == model.VendorIDEBAI { - storeSkuListEB = append(storeSkuListEB, v.(DataVendorStoreSkuPrice)) - } - if vendorID == model.VendorIDMTWM { - storeSkuListMT = append(storeSkuListMT, v.(DataVendorStoreSkuPrice)) - } - } - } - } - excelParam1 := ExcelParam{ - DataList: storeSkuListJD, - TitleList: titleListVendorStoreSkuPrice, - SheetName: "京东平台", - } - excelParam2 := ExcelParam{ - DataList: storeSkuListEB, - TitleList: titleListVendorStoreSkuPrice, - SheetName: "饿百平台", - } - excelParam3 := ExcelParam{ - DataList: storeSkuListMT, - TitleList: titleListVendorStoreSkuPrice, - SheetName: "美团平台", - } - excelParamList = append(excelParamList, excelParam1, excelParam2, excelParam3) - case 1: - WriteToExcelNormal(task, "各平台"+utils.Int2Str(skuID)+"商品所有门店价格", excelParamList) - } - return result, err - } - taskSeq := tasksch.NewSeqTask2("获取各平台所有门店某商品价格-序列任务", ctx, isContinueWhenError, taskSeqFunc, 2) - tasksch.HandleTask(taskSeq, nil, true).Run() - if !isAsync { - _, err = taskSeq.GetResult(0) - hint = "1" - } else { - hint = taskSeq.GetID() - } - return hint, err -} - -func WriteToExcelNormal(task *tasksch.SeqTask, fileName string, excelParam []ExcelParam) (err error) { - var sheetList []*excel.Obj2ExcelSheetConfig - for _, v := range excelParam { - if v.DataList != nil { - excelConf := &excel.Obj2ExcelSheetConfig{ - Title: v.SheetName, - Data: v.DataList, - CaptionList: v.TitleList, - } - sheetList = append(sheetList, excelConf) - } - } - downloadURL, fileNameResult, err := jxutils.UploadExeclAndPushMsg(sheetList, fileName) - if err != nil { - baseapi.SugarLogger.Errorf("WriteToExcel:upload %s failed error:%v", fileNameResult, err) - } else { - noticeMsg := fmt.Sprintf("[详情点我]path=%s \n", downloadURL) - task.SetNoticeMsg(noticeMsg) - baseapi.SugarLogger.Debugf("WriteToExcel:upload %s success, downloadURL:%s", fileNameResult, downloadURL) - } - return err -} - -func FocusStoreSkusByExcel(ctx *jxcontext.Context, files []*multipart.FileHeader, isAsync, isContinueWhenError bool) (hint string, err error) { - if len(files) == 0 { - return "", errors.New("没有文件上传!") - } - fileHeader := files[0] - file, err := fileHeader.Open() - hint, err = FocusStoreSkusByExcelBin(ctx, file, isAsync, isContinueWhenError) - file.Close() - return hint, err -} - -func FocusStoreSkusByExcelBin(ctx *jxcontext.Context, reader io.Reader, isAsync, isContinueWhenError bool) (hint string, err error) { - var ( - skuMap = make(map[int]int) - db = dao.GetDB() - skuIDs []int - result1 []interface{} - ) - sheetParam := &SheetParam{ - OutSkuIDCol: 1, - SkuPriceCol: 3, - SkuRow: 1, - } - taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - // xlsx, err := excelize.OpenFile("111.xlsx") - xlsx, err := excelize.OpenReader(reader) - if err != nil { - return result, err - } - rows, _ := xlsx.GetRows(xlsx.GetSheetName(1)) - for rowNum, row := range rows { - if rowNum < sheetParam.SkuRow { - continue - } - GetCellForFocusStoreSkus(db, rowNum, row, sheetParam, skuMap) - } - case 1: - for k, _ := range skuMap { - skuIDs = append(skuIDs, k) - } - skuList, err := dao.GetSkus(db, skuIDs, nil, nil, nil, nil) - storeList, err := dao.GetStoreList(db, nil, nil, nil, nil, "") - if err != nil && len(skuList) == 0 { - return result, err - } - taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - store := batchItemList[0].(*model.Store) - var ( - skuNameMap = make(map[int]int) - skuInfoMap = make(map[int][]*StoreSkuBindSkuInfo) - ) - for _, v := range skuList { - var ( - price int - specQuality float64 - ) - focusList, _ := dao.GetStoreSkuBindByNameID(db, store.ID, v.NameID, model.StoreSkuBindStatusNormal) - //有关注过 - if len(focusList) > 0 { - price = focusList[0].UnitPrice - skuInfoMap[v.NameID] = append(skuInfoMap[v.NameID], &StoreSkuBindSkuInfo{ - SkuID: v.ID, - IsSale: 1, - }) - skuNameMap[v.NameID] = price - } else { - if v.Unit == model.SpecialUnit { - if v.SpecUnit == model.SpecUnitNames[1] || v.SpecUnit == model.SpecUnitNames[2] { - specQuality = float64(v.SpecQuality) * 1000 - } else { - specQuality = float64(v.SpecQuality) - } - price = int(utils.Float64TwoInt64(utils.Int2Float64(model.SpecialSpecQuality) / specQuality * utils.Int2Float64(skuMap[v.ID]))) - } else { - price = skuMap[v.ID] - } - if skuNameMap[v.NameID] < price { - skuNameMap[v.NameID] = price - } - } - } - var storeSkuBindInfo []*StoreSkuBindInfo - for k, v := range skuNameMap { - skuBindInfo := &StoreSkuBindInfo{ - StoreID: store.ID, - NameID: k, - UnitPrice: v, - IsFocus: 1, - IsSale: 1, - Skus: skuInfoMap[k], - } - storeSkuBindInfo = append(storeSkuBindInfo, skuBindInfo) - } - retVal = storeSkuBindInfo - return retVal, err - } - taskParallel := tasksch.NewParallelTask("根据skuID关注商品", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, taskFunc, storeList) - tasksch.HandleTask(taskParallel, task, true).Run() - result1, _ = taskParallel.GetResult(0) - case 2: - var skuBindInfos []*StoreSkuBindInfo - for _, v := range result1 { - skuBindInfos = append(skuBindInfos, v.(*StoreSkuBindInfo)) - } - UpdateStoresSkusByBind(ctx, task, skuBindInfos, true, true, false) - } - return result, err - } - taskSeq := tasksch.NewSeqTask2("根据Excel中skuID批量关注商品", ctx, isContinueWhenError, taskSeqFunc, 3) - tasksch.HandleTask(taskSeq, nil, true).Run() - if !isAsync { - _, err = taskSeq.GetResult(0) - hint = "1" - } else { - hint = taskSeq.GetID() - } - return hint, err -} - -func GetCellForFocusStoreSkus(db *dao.DaoDB, rowNum int, row []string, sheetParam *SheetParam, skuMap map[int]int) { - var ( - skuID int - price int - ) - for k, cell := range row { - if k == sheetParam.OutSkuIDCol { - skuID = int(utils.Str2Int64(cell)) - } - if k == sheetParam.SkuPriceCol { - price = int(utils.Float64TwoInt64(utils.Str2Float64(cell) * 100)) - } - } - skuMap[skuID] = price -} - -func FocusStoreSkusBySku(ctx *jxcontext.Context, skuBindInfos []*StoreSkuBindInfo, isAsync, isContinueWhenError bool) (hint string, err error) { - var result1 []interface{} - db := dao.GetDB() - taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - var ( - price int - payPercentage int - ) - skuBindInfo := batchItemList[0].(*StoreSkuBindInfo) - storeID := skuBindInfo.StoreID - skuID := skuBindInfo.Skus[0].SkuID - store, err := dao.GetStoreDetail(db, storeID, -1) - if err != nil { - return retVal, err - } - skuList, err := dao.GetSkus(db, []int{skuID}, nil, nil, nil, nil) - if err != nil { - return retVal, err - } - if len(skuList) == 0 { - return retVal, fmt.Errorf("未查询到此商品!商品id :[%d]", skuID) - } - focusList, _ := dao.GetStoreSkuBindByNameID(db, storeID, skuList[0].NameID, model.StoreSkuBindStatusNormal) - //有关注过 - if len(focusList) > 0 { - price = focusList[0].UnitPrice - } else { - if store.PayPercentage < 50 { - payPercentage = 70 - } else { - payPercentage = store.PayPercentage - } - priceReferList, _ := dao.GetPriceReferSnapshotNoPage(db, []int{0}, nil, []int{skuList[0].NameID}, utils.Time2Date(time.Now().AddDate(0, 0, -1))) - if len(priceReferList) > 0 { - if payPercentage == 100 { - price = priceReferList[0].MidUnitPrice * payPercentage / 100 - } else { - price = priceReferList[0].MidUnitPrice / payPercentage * 100 - } - } - } - skuBindSkuInfo := &StoreSkuBindSkuInfo{ - SkuID: skuID, - IsSale: 1, - } - var skuBindSkuInfos []*StoreSkuBindSkuInfo - skuBindSkuInfos = append(skuBindSkuInfos, skuBindSkuInfo) - skuBindInfo2 := &StoreSkuBindInfo{ - StoreID: storeID, - NameID: skuList[0].NameID, - UnitPrice: price, - IsFocus: 1, - Skus: skuBindSkuInfos, - } - retVal = []*StoreSkuBindInfo{skuBindInfo2} - return retVal, err - } - taskParallel := tasksch.NewParallelTask("根据skuID部分关注商品", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, taskFunc, skuBindInfos) - tasksch.HandleTask(taskParallel, task, true).Run() - result1, _ = taskParallel.GetResult(0) - case 1: - var skuBindInfos []*StoreSkuBindInfo - for _, v := range result1 { - skuBindInfos = append(skuBindInfos, v.(*StoreSkuBindInfo)) - } - hint, err = UpdateStoresSkusByBind(ctx, task, skuBindInfos, isAsync, isContinueWhenError, true) - } - return result, err - } - taskSeq := tasksch.NewSeqTask2("根据skuID批量部分关注商品", ctx, isContinueWhenError, taskSeqFunc, 2) - tasksch.HandleTask(taskSeq, nil, true).Run() - if !isAsync { - _, err = taskSeq.GetResult(0) - hint = "1" - } else { - hint = taskSeq.GetID() - } - return hint, err -} - -func AutoFocusStoreSkusForTopSkus(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (hint string, err error) { - db := dao.GetDB() - var ( - result1 []interface{} - ) - storeList, err := dao.GetStoreList(db, nil, nil, nil, nil, "") - taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - v := batchItemList[0].(*model.Store) - var ( - skuName []*model.SkuName - skuNameMap = make(map[int]int) - ) - //物料店不自动关注畅销品 - if autoNotFoucsStoreMap[v.ID] != 0 { - return retVal, err - } - sql := ` - SELECT DISTINCT a.name_id id - FROM sku a - LEFT JOIN (SELECT DISTINCT b.name_id - FROM store_sku_bind a - JOIN sku b ON a.sku_id = b.id - WHERE a.deleted_at = ? - AND store_id = ?)b ON a.name_id = b.name_id - WHERE a.status = ? - AND a.deleted_at = ? - AND b.name_id IS NULL - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - v.ID, - model.SkuStatusNormal, - utils.DefaultTimeValue, - } - err = dao.GetRows(db, &skuName, sql, sqlParams...) - for _, name := range skuName { - skuNameMap[name.ID] = name.ID - } - skuNameAndPlaceList, err2 := GetTopSkusByCityCode(ctx, 0, 0) - //skuNameAndPlaceList, err2 := GetTopSkusByCityCode(ctx, v.CityCode, 0) - if err2 != nil { - return retVal, err2 - } - var payPercentage int - if v.PayPercentage < 50 { - payPercentage = 70 - } else { - payPercentage = v.PayPercentage - } - if len(skuNameAndPlaceList) > 0 { - var skuBindInfoList []*StoreSkuBindInfo - for _, vv := range skuNameAndPlaceList { - if skuNameMap[vv.ID] != 0 { - globals.SugarLogger.Debugf("testAutoFocusStoreSkusForTopSkus,storeID:%v,nameID:%v", v.ID, vv.ID) - storeSkuBindInfo := &StoreSkuBindInfo{ - StoreID: v.ID, - NameID: vv.ID, - // UnitPrice: priceReferList[0].MidUnitPrice * payPercentage / 100, - IsFocus: 1, - IsSale: 0, - } - priceReferList, err := dao.GetPriceReferSnapshotNoPage(db, []int{vv.CityCode}, nil, []int{vv.ID}, utils.Time2Date(time.Now().AddDate(0, 0, -1))) - if err == nil && len(priceReferList) > 0 { - storeSkuBindInfo.UnitPrice = priceReferList[0].MidUnitPrice / payPercentage * 100 - } - skuBindInfoList = append(skuBindInfoList, storeSkuBindInfo) - } - } - retVal = skuBindInfoList - } - return retVal, err - } - taskParallel := tasksch.NewParallelTask("自动关注畅销品-设置数据", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, taskFunc, storeList) - tasksch.HandleTask(taskParallel, task, true).Run() - result1, _ = taskParallel.GetResult(0) - case 1: - var skuBindInfos []*StoreSkuBindInfo - for _, v := range result1 { - skuBindInfos = append(skuBindInfos, v.(*StoreSkuBindInfo)) - } - hint, err = UpdateStoresSkusByBind(ctx, nil, skuBindInfos, isAsync, isContinueWhenError, false) - } - return result, err - } - taskSeq := tasksch.NewSeqTask2("自动关注畅销品", ctx, isContinueWhenError, taskSeqFunc, 2) - tasksch.HandleTask(taskSeq, nil, true).Run() - if !isAsync { - _, err = taskSeq.GetResult(0) - hint = "1" - } else { - hint = taskSeq.GetID() - } - return hint, err -} - -func AutoFocusStoreSkusWithoutFocus(ctx *jxcontext.Context, skuIDs []int, isSync bool) (err error) { - var ( - nameMap = make(map[int]*StoreSkuBindInfo) - ) - db := dao.GetDB() - storeList, err := dao.GetStoreList(db, nil, nil, nil, nil, "") - for _, v := range storeList { - storeSkuList, _ := dao.GetStoreSkusAndSkuName(db, []int{v.ID}, skuIDs, nil) - for _, vv := range storeSkuList { - if nameMap[vv.ID] != nil { - nameMap[vv.ID].Skus = append(nameMap[vv.ID].Skus, &StoreSkuBindSkuInfo{ - SkuID: vv.SkuID, - }) - } else { - skuBindInfo := &StoreSkuBindInfo{ - UnitPrice: int(vv.UnitPrice), - NameID: vv.NameID, - StoreID: v.ID, - Skus: []*StoreSkuBindSkuInfo{}, - } - nameMap[vv.ID] = skuBindInfo - } - } - } - for _, v := range nameMap { - var skuBindInfoList []*StoreSkuBindInfo - skuBindInfoResult := &StoreSkuBindInfo{ - NameID: v.NameID, - UnitPrice: v.UnitPrice, - IsFocus: 1, - } - var skuBindSkuList []*StoreSkuBindSkuInfo - skuMap := make(map[int]int) - skuList, _ := dao.GetSkus(db, nil, []int{v.NameID}, nil, nil, nil) - if len(v.Skus) != len(skuList) { - for _, skus := range v.Skus { - skuMap[skus.SkuID] = 1 - } - for _, vv := range skuList { - if skuMap[vv.ID] != 1 { - continue - } - skuBindSkuList = append(skuBindSkuList, &StoreSkuBindSkuInfo{ - SkuID: vv.ID, - IsSale: 0, - }) - } - } - skuBindInfoList = append(skuBindInfoList, skuBindInfoResult) - if isSync { - UpdateStoreSkus(ctx, 0, v.StoreID, skuBindInfoList, true, true) - } else { - updateStoresSkusWithoutSync(ctx, db, []int{v.StoreID}, skuBindInfoList, false, false) - } - } - return err -} - -func UpdateStoreSkusSpecTag(ctx *jxcontext.Context, vendorIDs []int, files []*multipart.FileHeader, isAsync, isContinueWhenError bool) (hint string, err error) { - if len(files) == 0 { - return "", errors.New("没有文件上传!") - } - fileHeader := files[0] - file, err := fileHeader.Open() - hint, err = UpdateStoreSkusSpecTagBin(ctx, file, vendorIDs, isAsync, isContinueWhenError) - file.Close() - return hint, err -} - -func UpdateStoreSkusSpecTagBin(ctx *jxcontext.Context, reader io.Reader, vendorIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { - var ( - db = dao.GetDB() - results []*tUpdateSkuSpecTag - ) - taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - // xlsx, err := excelize.OpenFile("111.xlsx") - xlsx, err := excelize.OpenReader(reader) - if err != nil { - return result, err - } - rows, _ := xlsx.GetRows(xlsx.GetSheetName(1)) - for rowNum, row := range rows { - if rowNum < 1 { - continue - } - var ( - skuMap = &tUpdateSkuSpecTag{} - storeID int - skuID int - isSpec int - ) - for k, cell := range row { - if cell != "" { - if k == 0 { - storeID = int(utils.Str2Int64(cell)) - } - if k == 1 { - skuID = int(utils.Str2Int64(cell)) - } - if k == 2 { - isSpec = int(utils.Str2Int64(cell)) - } - } - } - skuMap.SkuID = skuID - skuMap.IsSpec = isSpec - skuMap.StoreID = storeID - results = append(results, skuMap) - } - case 1: - for i := 0; i < len(results)/2; i++ { - tmp := results[i] - results[i] = results[len(results)-i-1] - results[len(results)-i-1] = tmp - } - for _, v := range results { - store, err := dao.GetStoreDetail(db, v.StoreID, model.VendorIDMTWM) - if err != nil || store == nil { - continue - } - food, err := api.MtwmAPI.RetailGet(store.VendorStoreID, utils.Int2Str(v.SkuID)) - if err != nil || food == nil { - continue - } - var foodData = make(map[string]interface{}) - if v.IsSpec != 0 && v.IsSpec == -1 { - v.IsSpec = 0 - } - foodData["is_specialty"] = v.IsSpec - foodData["price"] = food.Price - if globals.EnableMtwmStoreWrite { - err = api.MtwmAPI.RetailInitData(ctx.GetTrackInfo(), store.VendorStoreID, utils.Int2Str(v.SkuID), foodData) - } - } - } - return result, err - } - taskSeq := tasksch.NewSeqTask2("修改平台力荐商品", ctx, isContinueWhenError, taskSeqFunc, 2) - tasksch.HandleTask(taskSeq, nil, true).Run() - if !isAsync { - _, err = taskSeq.GetResult(0) - hint = "1" - } else { - hint = taskSeq.GetID() - } - return hint, err -} - -func SendSeckillSkusCountMsg(ctx *jxcontext.Context, vendorIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { - // 1. 如果爆品低于8个,报警 type1 - // 2. 爆品价格低于1元商品小于5个,报警 type2 - var ( - type1Count = 8 - type2Count = 5 - ddMsgresult []interface{} - ) - db := dao.GetDB() - storeList, err := dao.GetStoresMapList(db, vendorIDs, nil, []int{model.StoreStatusClosed, model.StoreStatusHaveRest, model.StoreStatusOpened}, model.StoreStatusOpened, model.StoreIsSyncAll, "", "") - taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - store := batchItemList[0].(*model.StoreMap) - var type1, type2 int - switch store.VendorID { - case model.VendorIDEBAI: - result, _ := api.EbaiAPI.GetStoresShowWindowSkus(utils.Str2Int64(store.VendorStoreID)) - for _, v := range result { - type1++ - if v.SalePrice < 1 { - type2++ - } - } - case model.VendorIDMTWM: - handler := partner.GetPurchasePlatformFromVendorID(store.VendorID).(partner.ISingleStoreStoreSkuHandler) - remoteSkuList, err := handler.GetStoreSkusFullInfo(ctx, nil, store.StoreID, store.VendorStoreID, nil) - if err != nil { - return retVal, err - } - for _, v := range remoteSkuList { - for _, vv := range v.SkuList { - if vv.IsSpecialty == 1 { - type1++ - } - if vv.IsSpecialty == 1 && vv.VendorPrice < 100 { - type2++ - } - } - } - case model.VendorIDJD: - var storeSecKill []*tStoreSkusSecKill - sql := ` - SELECT t1.store_id,count(*) sec_kill_count, count(t1.price < 100 or NULL) sec_kill_count2 - FROM( - SELECT a.store_id, a.sku_id, d.type, MIN(e.actual_act_price) price - FROM store_sku_bind a - LEFT JOIN act_store_sku b ON a.store_id = b.store_id AND b.sku_id = a.sku_id - LEFT JOIN act_map c ON c.act_id = b.act_id - LEFT JOIN act d ON d.id = c.act_id - LEFT JOIN act_store_sku_map e ON e.store_id = a.store_id AND e.sku_id = a.sku_id AND e.vendor_id = c.vendor_id AND e.act_id = d.id - WHERE 1=1 - AND a.store_id = ? - AND c.vendor_id = ? - AND NOW() BETWEEN d.begin_at AND d.end_at - AND d.type = ? - AND a.status = ? - AND a.deleted_at = ? - AND e.actual_act_price <> 0 - GROUP BY 1,2,3)t1 - GROUP BY 1 - ` - sqlParams := []interface{}{ - store.StoreID, store.VendorID, - model.ActSkuSecKill, model.StoreSkuBindStatusNormal, - utils.DefaultTimeValue, - } - err = dao.GetRows(db, &storeSecKill, sql, sqlParams...) - if len(storeSecKill) > 0 { - type1 = storeSecKill[0].SecKillCount - type2 = storeSecKill[0].SecKillCount2 - } else { - type1 = 0 - type2 = 0 - } - } - if type1 < type1Count || type2 < type2Count { - storeDetail, _ := dao.GetStoreDetail(db, store.StoreID, store.VendorID) - var ( - type1Str = "爆品数量低于8个!" - type2Str = "爆品价格小于1元的爆品数量低于5个!" - typeResult = "" - ) - operatorNameList := jxutils.BatchString2Slice(storeDetail.OperatorName, storeDetail.OperatorName2, storeDetail.OperatorName3) - operatorPhoneList := jxutils.BatchString2Slice(storeDetail.OperatorPhone, storeDetail.OperatorPhone2, storeDetail.OperatorPhone3) - - if type1 < type1Count { - typeResult += type1Str - } - if type2 < type2Count { - typeResult += type2Str - } - var result = &tStoreSkusSecKill{} - noticeMsg := fmt.Sprintf("运营负责人:[%v],市场负责人:[%v],门店ID:[%v],平台门店ID[%v],门店名:[%v],平台:[%v],警告类型:[%v]\n", strings.Join(operatorNameList, ","), storeDetail.MarketManName, store.StoreID, storeDetail.VendorStoreID, store.StoreName, model.VendorChineseNames[store.VendorID], typeResult) - result.OperatorPhoneList = operatorPhoneList - result.MarketManPhone = storeDetail.MarketManPhone - result.NoticeMsg = noticeMsg - retVal = []*tStoreSkusSecKill{result} - } - return retVal, err - } - taskParallel := tasksch.NewParallelTask("获取各平台爆品数量", tasksch.NewParallelConfig().SetParallelCount(parallelCount), ctx, taskFunc, storeList) - tasksch.HandleTask(taskParallel, task, true).Run() - ddMsgresult, err = taskParallel.GetResult(0) - case 1: - var ( - operaterMap = make(map[string]string) - marketMap = make(map[string]string) - ) - for _, v := range ddMsgresult { - ddm := v.(*tStoreSkusSecKill) - for _, phone := range ddm.OperatorPhoneList { - if operaterMap[phone] != "" { - operaterMap[phone] += ddm.NoticeMsg - } else { - operaterMap[phone] = ddm.NoticeMsg - } - } - if marketMap[ddm.MarketManPhone] != "" { - marketMap[ddm.MarketManPhone] += ddm.NoticeMsg - } else { - marketMap[ddm.MarketManPhone] = ddm.NoticeMsg - } - } - for k, v := range operaterMap { - if marketMap[k] != "" { - continue - } - user, err := dao.GetUserByID(db, "mobile", k) - if user != nil && err == nil { - ddmsg.SendUserMessage(dingdingapi.MsgTyeText, user.UserID, "警告!门店爆品数量异常!", v) - } - globals.SugarLogger.Debugf("SendSeckillSkusCountMsg: [%v]", v) - } - for k, v := range marketMap { - if operaterMap[k] != "" { - continue - } - user, err := dao.GetUserByID(db, "mobile", k) - if user != nil && err == nil { - ddmsg.SendUserMessage(dingdingapi.MsgTyeText, user.UserID, "警告!门店爆品数量异常!", v) - } - globals.SugarLogger.Debugf("SendSeckillSkusCountMsg: [%v]", v) - } - } - return result, err - } - taskSeq := tasksch.NewSeqTask2("爆品预警", ctx, isContinueWhenError, taskSeqFunc, 2) - tasksch.HandleTask(taskSeq, nil, true).Run() - if !isAsync { - _, err = taskSeq.GetResult(0) - hint = "1" - } else { - hint = taskSeq.GetID() - } - return hint, err -} - -func RefreshJxPriceByVendor(ctx *jxcontext.Context, jdStoreSkus []*JdStoreSkus, vendorID int, ignoreLow, isAsync, isContinueWhenError bool) (hint string, err error) { - var ( - db = dao.GetDB() - jdMap = make(map[int][]*JdStoreSkus) - jxMap = make(map[int]map[int]int) - param []*StoreSkuBindInfo - ) - taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - if vendorID == model.VendorIDJD { - for _, v := range jdStoreSkus { - var ( - pricePercentagePack []*model.PricePercentageItem - cats []*model.ThingMap - skus []*model.SkuAndName - vendorPrice int - specQuality float64 - ) - sql := ` - SELECT t1.* - FROM thing_map t1 - WHERE t1.deleted_at = ? AND t1.thing_type = ? - AND t1.vendor_thing_id = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - model.ThingTypeSku, - v.JdSkuID, - } - err = dao.GetRows(db, &cats, sql, sqlParams...) - if len(cats) > 0 { - skus, err = dao.GetSkus(db, []int{int(cats[0].ThingID)}, nil, nil, nil, nil) - if err != nil || len(skus) == 0 { - return result, fmt.Errorf("没有找到该京西skuID!,京西skuID :[%v]", cats[0].ThingID) - } - } else { - return result, fmt.Errorf("没有找到该京东skuID对应的京西skuID!,京东skuID :[%v]", v.JdSkuID) - } - store, err := dao.GetStoreDetailByVendorStoreID(db, utils.Int2Str(v.JdStoreID), vendorID) - if err != nil || store == nil { - return result, fmt.Errorf("没有找到该京东门店对应的京西门店!,京东门店ID :[%v]", v.JdStoreID) - } - err = jxutils.Strings2Objs(store.PricePercentagePackStr, &pricePercentagePack) - if skus[0].Unit == model.SpecialUnit { - if skus[0].SpecUnit == model.SpecUnitNames[1] || skus[0].SpecUnit == model.SpecUnitNames[2] { - specQuality = float64(skus[0].SpecQuality) * 1000 - } else { - specQuality = float64(skus[0].SpecQuality) - } - vendorPrice = int(utils.Float64TwoInt64(specQuality / utils.Int2Float64(model.SpecialSpecQuality) * utils.Int2Float64(v.Price))) - } else { - vendorPrice = v.Price - } - jxPrice := jxutils.CaculateJxPriceByPricePack(pricePercentagePack, 0, vendorPrice) - if skus[0].Unit == model.SpecialUnit { - jxPrice = int(utils.Float64TwoInt64(utils.Int2Float64(jxPrice) * utils.Int2Float64(model.SpecialSpecQuality) / specQuality)) - } - jdMap[store.ID] = append(jdMap[store.ID], &JdStoreSkus{ - JdSkuID: skus[0].NameID, - Price: jxPrice, - }) - } - for k, v := range jdMap { - var skuNameMap = make(map[int]int) - for _, vv := range v { - if skuNameMap[vv.JdSkuID] != 0 { - if skuNameMap[vv.JdSkuID] > vv.Price { - skuNameMap[vv.JdSkuID] = vv.Price - } - } else { - skuNameMap[vv.JdSkuID] = vv.Price - } - } - jxMap[k] = skuNameMap - } - for k, v := range jxMap { - for kk, vv := range v { - result, err := dao.GetStoreSkuBindByNameID(db, k, kk, model.SkuStatusNormal) - if len(result) > 0 && err == nil { - if ignoreLow { - if result[0].UnitPrice > vv { - storeSkuBindInfo := &StoreSkuBindInfo{ - StoreID: k, - NameID: kk, - UnitPrice: vv, - } - param = append(param, storeSkuBindInfo) - } - } else { - storeSkuBindInfo := &StoreSkuBindInfo{ - StoreID: k, - NameID: kk, - UnitPrice: vv, - } - param = append(param, storeSkuBindInfo) - } - } - } - } - } else if vendorID == model.VendorIDMTWM { - for _, v := range jdStoreSkus { - var ( - pricePercentagePack []*model.PricePercentageItem - vendorPrice int - specQuality float64 - ) - skus, _ := dao.GetSkus(db, []int{v.JdSkuID}, nil, nil, nil, nil) - if len(skus) == 0 { - continue - } - store, _ := dao.GetStoreDetail(db, v.JdStoreID, vendorID) - err = jxutils.Strings2Objs(store.PricePercentagePackStr, &pricePercentagePack) - if skus[0].Unit == model.SpecialUnit { - if skus[0].SpecUnit == model.SpecUnitNames[1] || skus[0].SpecUnit == model.SpecUnitNames[2] { - specQuality = float64(skus[0].SpecQuality) * 1000 - } else { - specQuality = float64(skus[0].SpecQuality) - } - vendorPrice = int(utils.Float64TwoInt64(specQuality / utils.Int2Float64(model.SpecialSpecQuality) * utils.Int2Float64(v.Price))) - } else { - vendorPrice = v.Price - } - jxPrice := jxutils.CaculateJxPriceByPricePack(pricePercentagePack, 0, vendorPrice) - if skus[0].Unit == model.SpecialUnit { - jxPrice = int(utils.Float64TwoInt64(utils.Int2Float64(jxPrice) * utils.Int2Float64(model.SpecialSpecQuality) / specQuality)) - } - jdMap[v.JdStoreID] = append(jdMap[v.JdStoreID], &JdStoreSkus{ - JdSkuID: skus[0].NameID, - Price: jxPrice, - }) - } - for k, v := range jdMap { - var skuNameMap = make(map[int]int) - for _, vv := range v { - if skuNameMap[vv.JdSkuID] != 0 { - if skuNameMap[vv.JdSkuID] > vv.Price { - skuNameMap[vv.JdSkuID] = vv.Price - } - } else { - skuNameMap[vv.JdSkuID] = vv.Price - } - } - jxMap[k] = skuNameMap - } - for k, v := range jxMap { - for kk, vv := range v { - result, err := dao.GetStoreSkuBindByNameID(db, k, kk, model.SkuStatusNormal) - if len(result) > 0 && err == nil { - if ignoreLow { - if result[0].UnitPrice > vv { - storeSkuBindInfo := &StoreSkuBindInfo{ - StoreID: k, - NameID: kk, - UnitPrice: vv, - } - param = append(param, storeSkuBindInfo) - } - } else { - storeSkuBindInfo := &StoreSkuBindInfo{ - StoreID: k, - NameID: kk, - UnitPrice: vv, - } - param = append(param, storeSkuBindInfo) - } - } - } - } - } - case 1: - _, err = UpdateStoresSkusByBind(ctx, nil, param, isAsync, isContinueWhenError, false) - } - return result, err - } - taskSeq := tasksch.NewSeqTask2("根据京东平台价刷新京西平台价", ctx, isContinueWhenError, taskSeqFunc, 2) - tasksch.HandleTask(taskSeq, nil, true).Run() - if !isAsync { - _, err = taskSeq.GetResult(0) - hint = "1" - } else { - hint = taskSeq.GetID() - } - return hint, err -} - -func RefreshJxPriceByVendor2(ctx *jxcontext.Context, storeIDs []int, vendorID int, isAsync, isContinueWhenError bool) (hint string, err error) { - var ( - db = dao.GetDB() - param []*StoreSkuBindInfo - ) - taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - for _, storeID := range storeIDs { - var ( - pricePercentagePack []*model.PricePercentageItem - skuNameMap = make(map[int]int64) - ) - storeDetail, _ := dao.GetStoreDetail(db, storeID, vendorID) - err = jxutils.Strings2Objs(storeDetail.PricePercentagePackStr, &pricePercentagePack) - if partner.IsMultiStore(vendorID) { - mulitStoreSkuHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IPurchasePlatformStoreSkuHandler) - skuList, err := dao.GetSkusWithVendor(db, []int{vendorID}, nil, nil, nil, false) - if err != nil { - return "", err - } - bareStoreSkuMap := make(map[string][]*partner.StoreSkuInfo) - for _, sku := range skuList { - bareStoreSkuMap[sku.VendorOrgCode] = append(bareStoreSkuMap[sku.VendorOrgCode], &partner.StoreSkuInfo{ - SkuID: sku.ID, - VendorSkuID: sku.VendorSkuID, - }) - } - for _, orgCode := range apimanager.CurAPIManager.GetAppOrgCodeList(vendorID) { - outStoreSkuList, _ := mulitStoreSkuHandler.GetStoreSkusBareInfo(ctx, orgCode, task, storeID, storeDetail.VendorStoreID, bareStoreSkuMap[orgCode]) - for _, sku := range outStoreSkuList { - price, nameID := GetSkuNamePrice(db, sku.SkuID, sku.VendorPrice) - if skuNameMap[nameID] < price { - skuNameMap[nameID] = price - } - } - for k, v := range skuNameMap { - unitPrice := jxutils.CaculateJxPriceByPricePack(pricePercentagePack, 0, int(v)) - storeSkuBindInfo := &StoreSkuBindInfo{ - StoreID: storeID, - NameID: k, - UnitPrice: unitPrice, - } - param = append(param, storeSkuBindInfo) - } - } - } else { - singleStoreHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreStoreSkuHandler) - outSkuNameList, _ := singleStoreHandler.GetStoreSkusFullInfo(ctx, task, storeID, storeDetail.VendorStoreID, nil) - for _, skuName := range outSkuNameList { - sku := skuName.SkuList[0] - price, nameID := GetSkuNamePrice(db, sku.SkuID, sku.VendorPrice) - if skuNameMap[nameID] < price { - skuNameMap[nameID] = price - } - } - for k, v := range skuNameMap { - unitPrice := jxutils.CaculateJxPriceByPricePack(pricePercentagePack, 0, int(v)) - storeSkuBindInfo := &StoreSkuBindInfo{ - StoreID: storeID, - NameID: k, - UnitPrice: unitPrice, - } - param = append(param, storeSkuBindInfo) - } - } - } - case 1: - _, err = UpdateStoresSkusByBind(ctx, nil, param, isAsync, isContinueWhenError, false) - } - return result, err - } - taskSeq := tasksch.NewSeqTask2("根据平台价刷新京西平台价", ctx, isContinueWhenError, taskSeqFunc, 2) - tasksch.HandleTask(taskSeq, nil, true).Run() - if !isAsync { - _, err = taskSeq.GetResult(0) - hint = "1" - } else { - hint = taskSeq.GetID() - } - return hint, err -} - -func GetSkuNamePrice(db *dao.DaoDB, skuID int, orgPrice int64) (price int64, nameID int) { - var ( - specQuality float64 - ) - skuList, _ := dao.GetSkus(db, []int{skuID}, nil, nil, nil, nil) - for _, v := range skuList { - if v.Unit == model.SpecialUnit { - if v.SpecUnit == model.SpecUnitNames[1] || v.SpecUnit == model.SpecUnitNames[2] { - specQuality = float64(v.SpecQuality) * 1000 - } else { - specQuality = float64(v.SpecQuality) - } - price = utils.Float64TwoInt64(utils.Int2Float64(model.SpecialSpecQuality) / specQuality * utils.Int2Float64(int(orgPrice))) - } else { - price = orgPrice - } - nameID = v.NameID - } - return price, nameID -} - -func BackUpStoreSkuBind(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (hint string, err error) { - var ( - db = dao.GetDB() - snapshotAt = utils.Time2Date(time.Now()) - ) - storeSkuBindHis := &model.StoreSkuBindHistory{ - SnapshotAt: snapshotAt.AddDate(0, 0, -5), - } - dao.DeleteEntity(db, storeSkuBindHis, "SnapshotAt") - storeList, err := dao.GetStoreList(db, nil, nil, nil, nil, "") - task := tasksch.NewParallelTask("BackUpStoreSkuBind", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - store := batchItemList[0].(*model.Store) - storeSku, err := dao.GetStoresSkusInfo(db, []int{store.ID}, nil) - var storeSkuBindHiss []*model.StoreSkuBindHistory - for _, v := range storeSku { - storeSkuBindHis := &model.StoreSkuBindHistory{} - storeSkuBindHis.StoreSkuBind = *v - storeSkuBindHis.StoreSkuBindID = v.ID - storeSkuBindHis.StoreSkuBind.ID = 0 - storeSkuBindHis.SnapshotAt = utils.Time2Date(snapshotAt) - storeSkuBindHiss = append(storeSkuBindHiss, storeSkuBindHis) - } - if len(storeSkuBindHiss) > 0 { - dao.CreateMultiEntities(db, storeSkuBindHiss) - } - return retVal, err - }, storeList) - tasksch.HandleTask(task, nil, true).Run() - if isAsync { - hint = task.GetID() - } else { - _, err = task.GetResult(0) - hint = "1" - } - return hint, err -} - -func ReturnStoreSkuBind(ctx *jxcontext.Context, snapshotAt string, storeIDs, skuIDs []int) (err error) { - var ( - spAt = utils.Time2Date(utils.Str2Time(snapshotAt)) - db = dao.GetDB() - ) - if len(storeIDs) == 0 { - return fmt.Errorf("必须选择一个门店!") - } - if len(storeIDs) > 1 { - return fmt.Errorf("暂时只支持一次操作一个门店!") - } - //删除原门店商品 - sql := `DELETE FROM store_sku_bind WHERE store_id IN(` + dao.GenQuestionMarks(len(storeIDs)) + `)` - sqlParams := []interface{}{storeIDs} - if len(skuIDs) > 0 { - sql += " AND sku_id IN(" + dao.GenQuestionMarks(len(skuIDs)) + ")" - sqlParams = append(sqlParams, skuIDs) - } - _, err = dao.ExecuteSQL(db, sql, sqlParams) - //查询备份的门店商品 - var storeHiss []*model.StoreSkuBindHistory - sql2 := `SELECT * FROM store_sku_bind_history WHERE snapshot_at = ? AND store_id IN(` + dao.GenQuestionMarks(len(storeIDs)) + `)` - sqlParams2 := []interface{}{spAt, storeIDs} - if len(skuIDs) > 0 { - sql2 += " AND sku_id IN(" + dao.GenQuestionMarks(len(skuIDs)) + ")" - sqlParams2 = append(sqlParams2, skuIDs) - } - err = dao.GetRows(db, &storeHiss, sql2, sqlParams2) - //插入到现在 - var storeSkus []*model.StoreSkuBind - for _, v := range storeHiss { - storeSku := &model.StoreSkuBind{} - storeSku = &v.StoreSkuBind - storeSku.ID = v.StoreSkuBindID - storeSkus = append(storeSkus, storeSku) - } - if len(storeSkus) > 0 { - dao.CreateMultiEntities(db, storeSkus) - } - return err -} - -func RefreshMatterStock(ctx *jxcontext.Context, skuID int) (err error) { - var ( - db = dao.GetDB() - skuBindInfos []*StoreSkuBindInfo - ) - if skuID != 0 { - skus, err := dao.GetSkus(db, []int{skuID}, nil, nil, nil, nil) - if err != nil || len(skus) == 0 { - return err - } - result, err := api.JdEclpAPI.QueryStock(skus[0].EclpID) - if err != nil || result == nil { - return err - } - var isSale = 0 - if len(result) == 0 { - isSale = -1 - } else { - if result[0].UsableNum > 0 { - isSale = 1 - } else { - isSale = -1 - } - } - storeSkuList, _ := dao.GetStoresSkusInfo(db, nil, []int{skuID}) - for _, vv := range storeSkuList { - var storeSkuBindSkus []*StoreSkuBindSkuInfo - storeSkuBindSku := &StoreSkuBindSkuInfo{ - SkuID: vv.SkuID, - IsSale: isSale, - } - storeSkuBindSkus = append(storeSkuBindSkus, storeSkuBindSku) - storeSkuBind := &StoreSkuBindInfo{ - StoreID: vv.StoreID, - // NameID: v.SkuNameID, - Skus: storeSkuBindSkus, - } - skuBindInfos = append(skuBindInfos, storeSkuBind) - } - } else { - result, err := api.JdEclpAPI.QueryStock("") - if err != nil { - return err - } - for _, v := range result { - skus, err := dao.GetSkus(db, nil, nil, nil, nil, []string{v.GoodsNo}) - if err != nil || len(skus) == 0 { - continue - } - var isSale = 0 - if v.UsableNum > 0 { - isSale = 1 - } else { - isSale = -1 - } - storeSkuList, _ := dao.GetStoresSkusInfo(db, nil, []int{skus[0].ID}) - for _, vv := range storeSkuList { - var storeSkuBindSkus []*StoreSkuBindSkuInfo - storeSkuBindSku := &StoreSkuBindSkuInfo{ - SkuID: vv.SkuID, - IsSale: isSale, - } - storeSkuBindSkus = append(storeSkuBindSkus, storeSkuBindSku) - storeSkuBind := &StoreSkuBindInfo{ - StoreID: vv.StoreID, - NameID: skus[0].NameID, - Skus: storeSkuBindSkus, - } - skuBindInfos = append(skuBindInfos, storeSkuBind) - } - } - } - //物料店666666 - updateStoresSkusWithoutSync(ctx, db, []int{666666}, skuBindInfos, false, false) - return err -} - -func buildStoreSkuBindInfosAndFocus(ctx *jxcontext.Context, db *dao.DaoDB, store *dao.StoreDetail, v *partner.SkuNameInfo, nameID int) (err error) { - var ( - pricePercentagePack []*model.PricePercentageItem - pricePercentagePack2 []*model.PricePercentageItem - jxPrice = 0 - ) - skus, _ := dao.GetSkus(db, nil, []int{nameID}, nil, nil, nil) - err = jxutils.Strings2Objs(store.PricePercentagePackStr, &pricePercentagePack) - price := jxutils.CaculateJxPriceByPricePack(pricePercentagePack, 0, int(v.SkuList[0].VendorPrice)) - store2, _ := dao.GetStoreDetail(db, store.ID, model.VendorIDJX) - if store2 != nil { - err = jxutils.Strings2Objs(store2.PricePercentagePackStr, &pricePercentagePack2) - jxPrice = jxutils.CaculatePriceByPricePack(pricePercentagePack2, 0, price) - } - skuBind := &model.StoreSkuBind{ - StoreID: store.ID, - UnitPrice: price, - Price: price, - Status: model.StoreSkuBindStatusNormal, - YbID: utils.Str2Int64(v.SkuList[0].VendorSkuID), - YbPrice: int(v.SkuList[0].VendorPrice), - JxPrice: jxPrice, - YbSyncStatus: 0, - MtwmSyncStatus: model.SyncFlagNewMask, - JdSyncStatus: model.SyncFlagNewMask, - EbaiSyncStatus: model.SyncFlagNewMask, - } - if len(skus) > 0 { - skuBind.SkuID = skus[0].ID - } - dao.WrapAddIDCULDEntity(skuBind, ctx.GetUserName()) - err = dao.CreateEntity(db, skuBind) - return err -} - -func CreateSkusAndFocusFromWx(ctx *jxcontext.Context, productInfo *jdapi.ProductInfo, price, storeID int) (err error) { - var ( - db = dao.GetDB() - skuBindInfos []*StoreSkuBindInfo - ) - if productInfo == nil { - return fmt.Errorf("未查询到相关商品!") - } - if price == 0 { - return fmt.Errorf("请输入商品价格!") - } - focusSku := func(nameID int) { - skuBindInfo := &StoreSkuBindInfo{ - StoreID: storeID, - NameID: nameID, - UnitPrice: price, - IsFocus: 1, - IsSale: 1, - } - skuBindInfos = append(skuBindInfos, skuBindInfo) - _, err := UpdateStoresSkusByBind(ctx, nil, skuBindInfos, true, true, false) - if err != nil { - err = nil - } - } - skuNames, err := dao.GetSkuNames(db, nil, []string{productInfo.UpcCode}, "", false) - if err != nil { - return err - } - if len(skuNames) == 0 { - skuNames2, err := dao.GetSkuNames(db, nil, nil, productInfo.Name, false) - if err != nil { - return err - } - if productInfo.Name == "" { - return fmt.Errorf("暂时无法创建此商品,[%v]", productInfo.Name) - } - if len(skuNames2) > 1 { - return fmt.Errorf("此商品名在京西库中查询出了大于1个商品,[%v]", productInfo.Name) - } - //表示查到了,需要把upc更新上去,没查到就要新建 - if len(skuNames2) == 1 && (productInfo.SpecQuality == skuNames2[0].SpecQuality && productInfo.SpecUnit == skuNames2[0].SpecUnit) { - skuNames2[0].Upc = &productInfo.UpcCode - dao.UpdateEntity(db, skuNames2[0], "Upc") - focusSku(skuNames2[0].ID) - } else { - skuNameExt := &model.SkuNameExt{ - SkuName: model.SkuName{ - Name: productInfo.Name, - Upc: &productInfo.UpcCode, - Status: model.SkuStatusNormal, - CategoryID: model.NoCatCatgoryID, - IsGlobal: model.YES, - Unit: productInfo.Unit, - }, - Skus: []*model.SkuWithVendor{ - &model.SkuWithVendor{ - Sku: &model.Sku{}, - }, - }, - // Places: []int{510100}, //默认成都 - } - skuNameExt.Price = price - skuNameExt.Skus[0].SpecQuality = productInfo.SpecQuality - skuNameExt.Skus[0].SpecUnit = productInfo.SpecUnit - skuNameExt.Skus[0].Weight = int(utils.Str2Int64(utils.Float64ToStr(float64(productInfo.Weight)))) - skuNameExt.Skus[0].Status = model.SkuStatusNormal - if len(productInfo.ImgList) > 0 { - skuNameExt.Img = productInfo.ImgList[0] - } - outSkuNameExt, err := AddSkuName(ctx, skuNameExt, ctx.GetUserName()) - if err != nil { - if _, ok := err.(*SyncError); ok { - err = nil - } else { - return err - } - } else { - focusSku(outSkuNameExt.ID) - } - } - } else { - focusSku(skuNames[0].ID) - } - return err -} - -func SyncMatterC4ToGy(ctx *jxcontext.Context, isContinueWhenError, isAsync bool) (hint string, err error) { - var ( - db = dao.GetDB() - skus []*model.Sku - skusgy []*model.Sku - eclpIDs []string - addMatters []*model.Sku - deleteMatters []*model.Sku - updateMatters []*model.Sku - ) - if globals.IsMainProductEnv() { - return "", fmt.Errorf("此接口只允许在果园上调用!") - } - task := tasksch.NewParallelTask("同步物料商品从菜市到果园", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - step := batchItemList[0].(int) - var ( - skusMap = make(map[string]*model.Sku) - skusgyMap = make(map[string]*model.Sku) - ) - switch step { - case 0: - sql := "SELECT * FROM jxd_dev_0.sku WHERE deleted_at = ? AND eclp_id <> ''" - sqlParams := []interface{}{utils.DefaultTimeValue} - err = dao.GetRows(db, &skus, sql, sqlParams) - for _, c4 := range skus { - eclpIDs = append(eclpIDs, c4.EclpID) - skusMap[c4.EclpID] = c4 - } - sql2 := "SELECT * FROM sku WHERE deleted_at = ? AND eclp_id IN (" + dao.GenQuestionMarks(len(eclpIDs)) + ")" - sqlParams = append(sqlParams, eclpIDs) - err = dao.GetRows(db, &skusgy, sql2, sqlParams) - for _, gy := range skusgy { - skusgyMap[gy.EclpID] = gy - if skusMap[gy.EclpID] == nil { - deleteMatters = append(deleteMatters, skusgyMap[gy.EclpID]) - } - } - for _, c4 := range skus { - if skusgyMap[c4.EclpID] == nil { - addMatters = append(addMatters, skusMap[c4.EclpID]) - } else { - updateMatters = append(updateMatters, skusMap[c4.EclpID]) - } - } - case 1: - if len(deleteMatters) > 0 { - for _, v := range deleteMatters { - _, err = DeleteSkuName(ctx, v.NameID, ctx.GetUserName()) - } - } - if len(addMatters) > 0 { - for _, v := range addMatters { - var ( - skuName *model.SkuName - skuNames []*model.SkuName - ) - sql := ` - SELECT t1.* - FROM jxd_dev_0.sku_name t1 - WHERE t1.deleted_at = ? - AND t1.id = ? - ` - sqlParams := []interface{}{utils.DefaultTimeValue, v.NameID} - err = dao.GetRows(db, &skuNames, sql, sqlParams) - if len(skuNames) > 0 { - skuName = skuNames[0] - } - skuNameExt := &model.SkuNameExt{ - SkuName: model.SkuName{}, - Skus: []*model.SkuWithVendor{ - &model.SkuWithVendor{ - Sku: &model.Sku{}, - }, - }, - } - skuNameExt.Unit = skuName.Unit - skuNameExt.Name = skuName.Name - skuNameExt.Upc = skuName.Upc - skuNameExt.Img = skuName.Img - skuNameExt.Img2 = skuName.Img2 - skuNameExt.DescImg = skuName.DescImg - skuNameExt.Price = skuName.Price - skuNameExt.IsGlobal = model.YES - skuNameExt.Status = model.SkuStatusNormal - // skuNameExt.ID = v.NameID - skuNameExt.CategoryID = 3024 //默认全放物料分类下 - skuNameExt.DeletedAt = utils.DefaultTimeValue - skuNameExt.CreatedAt = time.Now() - skuNameExt.LastOperator = ctx.GetUserName() - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - if err = dao.CreateEntity(db, &skuNameExt.SkuName); err != nil { - dao.Rollback(db) - return retVal, err - } - // skuNameExt.Skus[0].ID = v.ID - skuNameExt.Skus[0].SpecQuality = v.SpecQuality - skuNameExt.Skus[0].SpecUnit = v.SpecUnit - skuNameExt.Skus[0].EclpID = v.EclpID - skuNameExt.Skus[0].Status = model.SkuStatusNormal - skuNameExt.Skus[0].NameID = skuNameExt.ID - skuNameExt.Skus[0].DeletedAt = utils.DefaultTimeValue - skuNameExt.Skus[0].CreatedAt = time.Now() - skuNameExt.Skus[0].LastOperator = ctx.GetUserName() - if err = dao.CreateEntity(db, skuNameExt.Skus[0].Sku); err != nil { - dao.Rollback(db) - return retVal, err - } - dao.Commit(db) - focusC4Matters(ctx, db, v) - } - } - if len(updateMatters) > 0 { - for _, v := range updateMatters { - var ( - skuName *model.SkuName - skuNames []*model.SkuName - ) - sql := ` - SELECT t1.* - FROM jxd_dev_0.sku_name t1, jxd_dev_0.sku t2 - WHERE t1.id = t2.name_id - AND t1.deleted_at = ? - AND t2.eclp_id = ? - ` - sqlParams := []interface{}{utils.DefaultTimeValue, v.EclpID} - err = dao.GetRows(db, &skuNames, sql, sqlParams) - if len(skuNames) > 0 { - skuName = skuNames[0] - } - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - if v != nil { - sql := ` - UPDATE sku SET spec_quality = ?, spec_unit = ?, eclp_id = ?, last_operator = ? - WHERE eclp_id = ? - AND deleted_at = ? - ` - sqlParams := []interface{}{v.SpecQuality, v.SpecUnit, v.EclpID, ctx.GetUserName(), v.EclpID, utils.DefaultTimeValue} - if _, err = dao.ExecuteSQL(db, sql, sqlParams); err != nil { - dao.Rollback(db) - return retVal, err - } - } - if skuName != nil { - sql := ` - UPDATE sku_name a - JOIN sku b ON a.id = b.name_id - SET a.name = ?, a.img = ?, a.img2 = ?, a.desc_img = ?, a.unit = ?, a.price = ?, a.last_operator = ? - WHERE b.eclp_id = ? - AND a.deleted_at = ? - AND 1=1 - ` - sqlParams := []interface{}{skuName.Name, skuName.Img, skuName.Img2, skuName.DescImg, skuName.Unit, skuName.Price, - ctx.GetUserName(), v.EclpID, utils.DefaultTimeValue} - if _, err = dao.ExecuteSQL(db, sql, sqlParams); err != nil { - dao.Rollback(db) - return retVal, err - } - } - dao.Commit(db) - focusC4Matters(ctx, db, v) - } - } - } - return retVal, err - }, []int{0, 1}) - tasksch.HandleTask(task, nil, true).Run() - if !isAsync { - _, err = task.GetResult(0) - hint = "1" - } else { - hint = task.GetID() - } - return hint, err -} - -func focusC4Matters(ctx *jxcontext.Context, db *dao.DaoDB, v *model.Sku) (err error) { - var storeSkus []*model.StoreSkuBind - sql := ` - SELECT * - FROM jxd_dev_0.store_sku_bind a, jxd_dev_0.sku b - WHERE a.sku_id = b.id - AND a.store_id = ? - AND b.eclp_id = ? - AND a.deleted_at = ? - ` - sqlParams2 := []interface{}{model.MatterStoreID, v.EclpID, utils.DefaultTimeValue} - err = dao.GetRows(db, &storeSkus, sql, sqlParams2) - if err != nil { - return err - } - if len(storeSkus) > 0 { - var ( - skuBindInfos []*StoreSkuBindInfo - skuName2 *model.SkuName - ) - sql := ` - SELECT a.* FROM sku_name a, sku b WHERE a.id = b.name_id AND b.eclp_id = ? AND a.deleted_at = ? - ` - sqlParams := []interface{}{v.EclpID, utils.DefaultTimeValue} - err = dao.GetRow(db, &skuName2, sql, sqlParams) - if skuName2 != nil { - skuBindInfo := &StoreSkuBindInfo{ - NameID: skuName2.ID, - IsFocus: 1, - UnitPrice: skuName2.Price, - } - skuBindInfos = append(skuBindInfos, skuBindInfo) - } - updateStoresSkusWithoutSync(ctx, db, []int{model.MatterStoreID}, skuBindInfos, false, false) - } - return err -} - -func RefreshJdsSkusStatus(ctx *jxcontext.Context) (err error) { - handler := partner.GetPurchasePlatformFromVendorID(model.VendorIDJDShop).(partner.ISingleStoreStoreSkuHandler) - remoteSkuList, err := handler.GetStoreSkusFullInfo(ctx, nil, 0, "", nil) - for _, v := range remoteSkuList { - if v.Status == jdshopapi.JdsSkuStatus2 { - reason, err := api.JdShopAPI.FindOpReason(utils.Str2Int64(v.VendorNameID)) - if err == nil && reason == jdshopapi.PassReason { - err = api.JdShopAPI.UpOrDown(utils.Str2Int64(v.VendorNameID), jdshopapi.JdsSkuStatus1) - } - } - } - return err -} - -func GetStoreSkuAudit(ctx *jxcontext.Context, storeIDs, nameIDs, skuIDs, statuss, types []int, name, remark, keyword, cityName, marketManPhone, applyTimeStart, applyTimeEnd, auditTimeStart, auditTimeEnd string, pageSize, offset int) (pagedInfo *model.PagedInfo, err error) { - var ( - applyTimeStartp, applyTimeEndp, auditTimeStartp, auditTimeEndp time.Time - ) - if applyTimeStart != "" { - applyTimeStartp = utils.Str2Time(applyTimeStart) - } - if applyTimeEnd != "" { - applyTimeEndp = utils.Str2Time(applyTimeEnd) - } - if auditTimeStart != "" { - auditTimeStartp = utils.Str2Time(auditTimeStart) - } - if auditTimeEnd != "" { - auditTimeEndp = utils.Str2Time(auditTimeEnd) - } - pagedInfo, err = dao.GetStoreSkuAudit(dao.GetDB(), storeIDs, nameIDs, skuIDs, statuss, types, name, remark, keyword, marketManPhone, cityName, applyTimeStartp, applyTimeEndp, auditTimeStartp, auditTimeEndp, pageSize, offset) - return pagedInfo, err -} - -func doStoreSkuAudit(ctx *jxcontext.Context, storeIDs []int, skuBindInfos []*StoreSkuBindInfo) (isAudit bool, err error) { - globals.SugarLogger.Debugf("doStoreSkuAudit storeIDs: %v", storeIDs) - time.Sleep(time.Second / 5) - db := dao.GetDB() - for _, storeID := range storeIDs { - stores, _ := dao.GetStoreList(db, []int{storeID}, nil, nil, nil, "") - //扣点的门店改价不进审核 - if len(stores) > 0 { - if stores[0].PayPercentage <= 50 || stores[0].StoreLevel == "E" || stores[0].StoreLevel == "D" { - globals.SugarLogger.Debugf("doStoreSkuAudit return0 storeID : %v", storeID) - return false, err - } - } - for _, skuBindInfo := range skuBindInfos { - globals.SugarLogger.Debugf("doStoreSkuAudit storeID: %v , nameID: %v", storeID, skuBindInfo.NameID) - storeAudits, err := dao.GetStoreSkuAuditLight(db, []int{storeID}, []int{skuBindInfo.NameID}, model.StoreAuditStatusOnline) - //取消关注,可售排除 - if skuBindInfo.IsFocus == -1 || skuBindInfo.IsSale != 0 || skuBindInfo.UnitPrice == 0 { - globals.SugarLogger.Debugf("doStoreSkuAudit return1 storeID : %v nameID: %v", storeID, skuBindInfo.NameID) - return false, err - } - //运营排除 - // if (ctx.GetFullUser().Type & model.UserTypeOperator) != 0 { - // if len(storeAudits) > 0 { - // storeAudits[0].DeletedAt = time.Now() - // dao.UpdateEntity(db, storeAudits[0], "DeletedAt") - // } - // globals.SugarLogger.Debugf("doStoreSkuAudit return2 storeID : %v nameID: %v", storeID, skuBindInfo.NameID) - // return false, err - // } - if ctx.GetLoginType() != weixin.AuthTypeMP && ctx.GetLoginType() != weixin.AuthTypeMini && ctx.GetLoginType() != weixin.AuthTypeWxApp && ctx.GetLoginType() != auth2.AuthTypeMobile { - globals.SugarLogger.Debugf("doStoreSkuAudit return3 storeID : %v loginType: %v", storeID, ctx.GetLoginType()) - authInfo, err := ctx.GetV2AuthInfo() - if err == nil && authInfo != nil { - if len(storeAudits) > 0 { - storeAudits[0].DeletedAt = time.Now() - dao.UpdateEntity(db, storeAudits[0], "DeletedAt") - // if globals.IsProductEnv() { - // skuAndNames, err := dao.GetSkus(db, nil, []int{skuBindInfo.NameID}, nil, nil, nil) - // if len(skuAndNames) > 0 && err == nil { - // weixinmsg.NotifyStoreOpRequestStatus(true, storeID, skuBindInfo.NameID, jxutils.ComposeSpuName(skuAndNames[0].Prefix, skuAndNames[0].Name, 0), storeAudits[0].OriginUnitPrice, skuBindInfo.UnitPrice, "") - // } - // } - } - globals.SugarLogger.Debugf("doStoreSkuAudit return3 storeID : %v nameID: %v", storeID, skuBindInfo.NameID) - return false, err - } - } - storeSkuAudit := &model.StoreSkuAudit{ - StoreID: storeID, - NameID: skuBindInfo.NameID, - Status: model.StoreAuditStatusOnline, - UnitPrice: skuBindInfo.UnitPrice, - } - //如果是关注改价 - if skuBindInfo.IsFocus == 1 { - if len(storeAudits) > 0 { - storeAudits[0].DeletedAt = time.Now() - dao.UpdateEntity(db, storeAudits[0], "DeletedAt") - } - storeSkuAudit.Type = model.StoreSkuAuditTypeFocus - } else { - storeSkus, err := dao.GetStoreSkusByNameIDs(db, []int{storeID}, skuBindInfo.NameID) - if len(storeSkus) > 0 { - //如果改的价比原价低排除 - if skuBindInfo.UnitPrice <= int(storeSkus[0].UnitPrice) { - if len(storeAudits) > 0 { - storeAudits[0].DeletedAt = time.Now() - dao.UpdateEntity(db, storeAudits[0], "DeletedAt") - } - globals.SugarLogger.Debugf("doStoreSkuAudit return4 storeID : %v nameID: %v", storeID, skuBindInfo.NameID) - return false, err - } else { - if len(storeAudits) > 0 { - storeAudits[0].DeletedAt = time.Now() - dao.UpdateEntity(db, storeAudits[0], "DeletedAt") - } - globals.SugarLogger.Debugf("doStoreSkuAudit cover storeID : %v nameID: %v", storeID, skuBindInfo.NameID) - } - } else { - return false, fmt.Errorf("未查询到该门店商品价,storeID: %v, nameID: %V", storeID, skuBindInfo.NameID) - } - storeSkuAudit.Type = model.StoreSkuAuditTypePrice - storeSkuAudit.OriginUnitPrice = int(storeSkus[0].UnitPrice) - } - dao.WrapAddIDCULDEntity(storeSkuAudit, ctx.GetUserName()) - err = dao.CreateEntity(db, storeSkuAudit) - } - } - return true, err -} - -func StoreSkuPriceAudit(ctx *jxcontext.Context, storeSkuAudits []*model.StoreSkuAudit, status int, isAsync, isContinueWhenError bool) (storeSkuAudits2 []*model.StoreSkuAudit, hint string, err error) { - db := dao.GetDB() - if status == model.StoreAuditStatusOnline { - return nil, "", fmt.Errorf("审核标志不正确!") - } - //证明是预审核 - if status == 2 { - for _, v := range storeSkuAudits { - skuList, _ := dao.GetStoreSkusByNameIDs(db, []int{v.StoreID}, v.NameID) - if len(skuList) > 0 { - if int64(v.AuditPrice) > skuList[0].UnitPrice*2 { - storeSkuAudits2 = append(storeSkuAudits2, v) - } - } - } - return storeSkuAudits2, "", err - } - deletedDuplicateWaitAuditData(ctx, db) - task := tasksch.NewParallelTask("StoreSkuPriceAudit", tasksch.NewParallelConfig().SetParallelCount(5).SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeAudit := batchItemList[0].(*model.StoreSkuAudit) - storeAudits, err := dao.GetStoreSkuAuditLight(db, []int{storeAudit.StoreID}, []int{storeAudit.NameID}, model.StoreAuditStatusOnline) - if len(storeAudits) == 0 || err != nil { - return retVal, fmt.Errorf("未查询到该门店该商品的待审核信息!storeID: %v, nameID: %v", storeAudit.StoreID, storeAudit.NameID) - } - if len(storeAudits) > 1 { - return retVal, fmt.Errorf("查询到该门店该商品的待审核信息大于1条!storeID: %v, nameID: %v", storeAudit.StoreID, storeAudit.NameID) - } - //审核通过 - if status == model.StoreAuditStatusCreated { - storeAudits[0].UserID = ctx.GetUserID() - storeAudits[0].Status = model.StoreAuditStatusCreated - storeAudits[0].Remark = storeAudit.Remark - storeAudits[0].AuditPrice = storeAudit.AuditPrice - _, err = dao.UpdateEntity(db, storeAudits[0], "UserID", "Status", "Remark", "AuditPrice") - var skuBindInfos = []*StoreSkuBindInfo{ - &StoreSkuBindInfo{ - NameID: storeAudit.NameID, - UnitPrice: storeAudits[0].UnitPrice, - }, - } - //证明填了额外的审核价格 - if storeAudit.AuditPrice != 0 { - skuBindInfos[0].UnitPrice = storeAudit.AuditPrice - } - //如果是关注改价 - if storeAudits[0].Type == model.StoreSkuAuditTypeFocus { - skuBindInfos[0].IsFocus = 1 - } - var num int64 - db := dao.GetDB() - skuIDs, err := updateStoresSkusWithoutSync(ctx, db, []int{storeAudit.StoreID}, skuBindInfos, false, false) - if err != nil { - return "", err - } - isAsync = asyncStoreSkuOpFilter(ctx, isAsync) - num = int64(len(skuIDs)) - if num > 0 { - hint, err = CurVendorSync.SyncStoresSkus(ctx, nil, 0, db, nil, []int{storeAudit.StoreID}, skuIDs, false, isAsync, isContinueWhenError) - } - if num == 0 || !isAsync || hint == "" { - hint = utils.Int64ToStr(num) - } - } else if status == model.StoreAuditStatusRejected { - storeAudits[0].UserID = ctx.GetUserID() - storeAudits[0].Status = model.StoreAuditStatusRejected - storeAudits[0].Remark = storeAudit.Remark - _, err = dao.UpdateEntity(db, storeAudits[0], "UserID", "Status", "Remark") - } else { - return retVal, fmt.Errorf("审核标志不正确!") - } - //TODO 暂时先不推消息了 - if err == nil { - // if globals.IsProductEnv() { - // skuAndNames, err := dao.GetSkus(db, nil, []int{storeAudit.NameID}, nil, nil, nil) - // if len(skuAndNames) > 0 && err == nil { - // price := 0 - // if storeAudit.AuditPrice != 0 { - // price = storeAudit.AuditPrice - // } else { - // price = storeAudits[0].UnitPrice - // } - // weixinmsg.NotifyStoreOpRequestStatus(flag, storeAudit.StoreID, storeAudit.NameID, jxutils.ComposeSpuName(skuAndNames[0].Prefix, skuAndNames[0].Name, 0), storeAudits[0].OriginUnitPrice, price, storeAudit.Remark) - // } - // } - } - return retVal, err - }, storeSkuAudits) - tasksch.HandleTask(task, nil, true).Run() - if isAsync { - hint = task.GetID() - } else { - _, err = task.GetResult(0) - hint = "1" - } - return nil, hint, err -} - -func deletedDuplicateWaitAuditData(ctx *jxcontext.Context, db *dao.DaoDB) { - var ( - duplicateDatas []*model.StoreSkuAudit - duplicateStore = make(map[int][]*model.StoreSkuAudit) - ) - sql := ` - SELECT a.* - FROM store_sku_audit a , - ( - SELECT count(*), store_id ,name_id ,status, deleted_at - FROM store_sku_audit - WHERE status = 0 - AND deleted_at = ? - GROUP BY 2,3,4,5 - HAVING count(*) > 1 - ) b - WHERE a.store_id = b.store_id - AND a.name_id = b.name_id - AND a.status= b.status - AND a.deleted_at = b.deleted_at - ` - sqlParams := []interface{}{utils.DefaultTimeValue} - dao.GetRows(db, &duplicateDatas, sql, sqlParams) - for _, v := range duplicateDatas { - duplicateStore[v.StoreID] = append(duplicateStore[v.StoreID], v) - } - for _, v := range duplicateStore { - duplicateSkuName := make(map[int][]*model.StoreSkuAudit) - for _, vv := range v { - duplicateSkuName[vv.NameID] = append(duplicateSkuName[vv.NameID], vv) - } - for _, vv := range duplicateSkuName { - for i := 0; i < len(vv)-1; i++ { - dao.DeleteEntity(db, vv[i]) - } - } - } -} - -func GetSpecialtyStoreSkus(ctx *jxcontext.Context, storeIDs, vendorIDs []int) (err error) { - type SpecialtyStoreSkus struct { - StoreID int `json:"门店ID"` - StoreName string `json:"门店名"` - SkuID int `json:"SkuID"` - SkuName string `json:"商品名"` - Price float64 `json:"平台价"` - VendorName string `json:"平台名"` - } - var ( - db = dao.GetDB() - specialtyStoreSkus []*SpecialtyStoreSkus - excelTitle = []string{ - "门店ID", - "门店名", - "SkuID", - "商品名", - "平台价", - "平台名", - } - sheetList []*excel.Obj2ExcelSheetConfig - downloadURL, fileName string - ) - for _, v := range vendorIDs { - for _, vv := range storeIDs { - storeDetail, err := dao.GetStoreDetail(db, vv, v) - if err != nil || storeDetail == nil { - continue - } - if partner.IsMultiStore(v) { - var ( - page = 1 - vendorSkuIDs []string - ) - _, totalCount, _ := api.JdPageAPI.GetJdTopSkus(storeDetail.VendorStoreID, page) - for ; page < totalCount/10+1; page++ { - result, _, _ := api.JdPageAPI.GetJdTopSkus(storeDetail.VendorStoreID, page) - vendorSkuIDs = append(vendorSkuIDs, result...) - } - for _, vvv := range vendorSkuIDs { - thingMap := &model.ThingMap{} - sql := ` - SELECT * FROM thing_map WHERE thing_type = 3 AND vendor_thing_id = ? AND vendor_org_code = 320406 - AND deleted_at = ? - ` - sqlParams := []interface{}{ - vvv, utils.DefaultTimeValue, - } - dao.GetRow(db, &thingMap, sql, sqlParams) - skus, _ := dao.GetSkus(db, []int{int(thingMap.ThingID)}, nil, nil, nil, nil) - specialtyStoreSku := &SpecialtyStoreSkus{ - StoreID: vv, - StoreName: storeDetail.Name, - SkuID: int(thingMap.ThingID), - SkuName: skus[0].Name, - Price: 0, - VendorName: model.VendorNames[v], - } - specialtyStoreSkus = append(specialtyStoreSkus, specialtyStoreSku) - } - } else { - handler := partner.GetPurchasePlatformFromVendorID(v).(partner.ISingleStoreStoreSkuHandler) - skuList, _ := handler.GetStoreSkusFullInfo(ctx, nil, vv, storeDetail.VendorStoreID, nil) - for _, sku := range skuList { - if sku.SkuList[0].IsSpecialty == model.YES { - specialtyStoreSku := &SpecialtyStoreSkus{ - StoreID: vv, - StoreName: storeDetail.Name, - SkuID: sku.SkuList[0].SkuID, - SkuName: sku.Name, - Price: float64(sku.SkuList[0].VendorPrice) / 100, - VendorName: model.VendorNames[v], - } - specialtyStoreSkus = append(specialtyStoreSkus, specialtyStoreSku) - } - } - } - } - } - excelConf := &excel.Obj2ExcelSheetConfig{ - Title: "sheet1", - Data: specialtyStoreSkus, - CaptionList: excelTitle, - } - sheetList = append(sheetList, excelConf) - if excelConf != nil { - downloadURL, fileName, err = jxutils.UploadExeclAndPushMsg(sheetList, "力荐或置顶商品") - } else { - baseapi.SugarLogger.Debug("WriteToExcel: dataSuccess is nil!") - } - if err != nil { - baseapi.SugarLogger.Errorf("WriteToExcel:upload %s , %s failed error:%v", fileName, err) - } else { - noticeMsg := fmt.Sprintf("[详情点我]%s/billshow/?normal=true&path=%s \n", globals.BackstageHost, downloadURL) - ddmsg.SendUserMessage(dingdingapi.MsgTyeText, ctx.GetUserID(), "异步任务完成", noticeMsg) - baseapi.SugarLogger.Debug("WriteToExcel: dataSuccess downloadURL: [%v]", downloadURL) - } - return err -} - -func checkActUpdate(actID int, actMap map[int]*model.Act2) (err error) { - if len(actMap) == 0 { - return fmt.Errorf("活动%d不存在或已被取消", actID) - } - errList := errlist.New() - for vendorID, act := range actMap { - if vendorID == model.VendorIDEBAI && act.CreateType != model.ActCreateTypeAPI { - errList.AddErr(fmt.Errorf("饿百平台不支持修改或取消网页活动")) - } - } - return errList.GetErrListAsOne() -} - -func DeleteActStoreSkuBind(ctx *jxcontext.Context, db *dao.DaoDB, actID int, actStoreSkuParam []*ActStoreSkuParam) (originSyncStatus int8, err error) { - actMap, err := dao.GetActVendorInfo(db, actID, nil) - if err != nil { - return 0, err - } - if err = checkActUpdate(actID, actMap); err != nil { - return 0, err - } - - actStoreSkuMap, err := dao.GetActStoreSkuVendorInfo(db, actID, nil, nil, nil) - if err != nil { - return 0, err - } - act := actMap[partner.GetVendorIDsFromActMap(actMap)[0]] - if act.Status != model.ActStatusCreated || time.Now().Sub(act.EndAt) > 0 { - return 0, fmt.Errorf("当前活动状态:%s,不能进行此操作,或已过期", model.ActStatusName[act.Status]) - } - - dao.Begin(db) - defer func() { - if r := recover(); r != nil || err != nil { - dao.Rollback(db) - if r != nil { - panic(r) - } - } - }() - actStoreSkuParamMap := make(map[int64]*ActStoreSkuParam) - for _, v := range actStoreSkuParam { - actStoreSkuParamMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] = v - if _, err = dao.DeleteEntityLogically(db, &model.ActStoreSku{}, nil, ctx.GetUserName(), - map[string]interface{}{ - model.FieldActID: actID, - model.FieldStoreID: v.StoreID, - model.FieldSkuID: v.SkuID, - }); err != nil { - return 0, err - } - } - - isNeedCancelAct := true - for vendorID, act := range actMap { - originSyncStatus |= act.SyncStatus - isDeleteAll := true - isDeleteAtLeastOne := false - if true { //actStoreSkuParam != nil { - actStoreSkuMap := partner.SplitActStoreSku(actStoreSkuMap[vendorID]) - for storeID := range actStoreSkuMap { - for _, actStoreSku := range actStoreSkuMap[storeID] { - if actStoreSkuParam == nil || actStoreSkuParamMap[jxutils.Combine2Int(actStoreSku.StoreID, actStoreSku.SkuID)] != nil { - if act.Type == model.ActSkuFake { - _, err = dao.DeleteEntityLogically(db, &model.ActStoreSkuMap{}, nil, ctx.GetUserName(), - map[string]interface{}{ - model.FieldActID: actID, - model.FieldStoreID: actStoreSku.StoreID, - model.FieldSkuID: actStoreSku.SkuID, - }) - } else { - _, err = dao.UpdateEntityLogically(db, partner.ActStoreSku2ActStoreSkuMap(actStoreSku), - map[string]interface{}{ - model.FieldSyncStatus: actStoreSku.SyncStatus | model.SyncFlagDeletedMask, - }, ctx.GetUserName(), nil) - } - if err != nil { - return 0, err - } - isDeleteAtLeastOne = true - } else { - isNeedCancelAct = false - isDeleteAll = false - } - } - } - } else { - isDeleteAll = true - isDeleteAtLeastOne = true - } - if isDeleteAll || isDeleteAtLeastOne { - syncStatus := int8(model.SyncFlagModifiedMask) - if isDeleteAll { - syncStatus = model.SyncFlagDeletedMask - } - syncStatus |= act.SyncStatus - if act.Type != model.ActSkuFake && vendorID != model.VendorIDJX { - if _, err = dao.UpdateEntityLogically(db, partner.Act2ActMap(act), - map[string]interface{}{ - model.FieldSyncStatus: syncStatus, - }, ctx.GetUserName(), nil); err != nil { - return 0, err - } - } - } - if isDeleteAll != isNeedCancelAct { - globals.SugarLogger.Warnf("deleteActStoreBind, actID:%d isDeleteAll:%t != isNeedCancelAct:%t", act.ID, isDeleteAll, isNeedCancelAct) - } - } - - if isNeedCancelAct { - act := &model.Act{} - act.ID = actID - if _, err = dao.UpdateEntityLogically(db, act, - map[string]interface{}{ - model.FieldStatus: model.ActStatusCanceled, - }, ctx.GetUserName(), nil); err != nil { - return 0, err - } - } - dao.Commit(db) - return originSyncStatus, err -} diff --git a/business/jxstore/cms/store_sku_check.go b/business/jxstore/cms/store_sku_check.go deleted file mode 100644 index 5db430f44..000000000 --- a/business/jxstore/cms/store_sku_check.go +++ /dev/null @@ -1,1353 +0,0 @@ -package cms - -import ( - "fmt" - "strings" - "sync" - "time" - - "git.rosy.net.cn/baseapi/platformapi/dingdingapi" - "git.rosy.net.cn/jx-callback/business/jxutils/ddmsg" - "github.com/astaxie/beego" - - "git.rosy.net.cn/jx-callback/business/model/dao" - - "git.rosy.net.cn/baseapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/excel" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api/apimanager" -) - -const ( - canWriteTolocal = false - needStatistic = false - isFilterToBeCreateAndNotSale = true - parallelCount = 5 - fileExt = ".xlsx" -) - -//错误类型 -const ( - DatAanalyse1 = "京西门店未关注,应删除对应的平台门店商品" - DatAanalyse2 = "平台商品库未创建成功(可能无经营许可等) " - DatAanalyse3 = "商品名不同 " - DatAanalyse4 = "商品可售状态不同 " - DatAanalyse5 = "京西商品库没有,平台商品库有 " - DatAanalyse6 = "京西商品库有,平台商品库没有" - DatAanalyse7 = "同步状态异常" - DatAanalyse8 = "平台门店未关注或平台门店商品库存为0,应添加对应的平台门店商品" - DatAanalyse9 = "平台门店价格与京西商品库价格不一致" - DatAanalyse10 = "平台商品的VendorSkuID与京西的VendorSkuID不一致" -) - -var ( - diffFileName = map[bool]string{ - true: "export/JXCSAndVendorSkuDiff", - false: "export/JXGYAndVendorSkuDiff", - } - vendorNameList = map[int]string{ - model.VendorIDMTWM: model.VendorChineseNames[model.VendorIDMTWM], - model.VendorIDEBAI: model.VendorChineseNames[model.VendorIDEBAI], - model.VendorIDJD: model.VendorChineseNames[model.VendorIDJD], - } - titleList = []string{ - "京西门店ID", - "平台门店ID", - "门店名", - "SkuID", - "京西美团外卖ID", - "京西饿百ID", - "同步状态", - "待创建", - "待删除", - "京西商品名", - "平台商品名", - "京西可售状态", - "平台可售状态", - "京西价格", - "平台价格", - "数据分析", - } - - deoptTitleList = []string{ - "SkuID", - "京西商品名", - "平台商品名", - "京西可售状态", - "平台可售状态", - "数据分析", - } - - statisticTitleList = []string{ - "京西和平台商品状态", - "待创建", - "京西可售状态", - "数量", - "占比", - } - statisticDataList = [][]string{ - {"京西有,平台无", "是", "下架"}, - {"京西有,平台无", "是", "上架"}, - {"京西有,平台无", "否", "下架"}, - {"京西有,平台无", "否", "上架"}, - - {"京西无,平台有", "N/A", "N/A"}, - - {"京西有,平台有", "是", "下架"}, - {"京西有,平台有", "是", "上架"}, - {"京西有,平台有", "否", "下架"}, - {"京西有,平台有", "否", "上架"}, - } - diffData DiffDataLock - depotDiffData DeoptDiffDataLock - - multiStoreAllSkuInfoMap map[int]map[string]map[int]*partner.SkuNameInfo - multiStoreAllSkuInfoList map[int]map[string][]*partner.StoreSkuInfo - - skuNameInfoList []*partner.SkuNameInfo - filterVendorDepotUnSaleSkuIds []int - filterJxDepotUnSaleSkuIds []int -) - -type DiffDataLock struct { - diffDataMap map[int][]DiffData - locker sync.RWMutex -} - -type DeoptDiffDataLock struct { - diffDataMap map[int][]DepotDiffData - locker sync.RWMutex -} - -type DepotDiffData struct { - SkuID string `json:"SkuID"` - JxSkuName string `json:"京西商品名"` - VendorSkuName string `json:"平台商品名"` - JxStatus string `json:"京西可售状态"` - VendorStatus string `json:"平台可售状态"` - DatAanalyse string `json:"数据分析"` -} - -type DiffData struct { - JxStoreID string `json:"京西门店ID"` - VendorStoreID string `json:"平台门店ID"` - VendorStoreName string `json:"门店名"` - SkuID string `json:"SkuID"` - MtwmID string `json:"京西美团外卖ID"` - EbaiID string `json:"京西饿百ID"` - SyncStatus string `json:"同步状态"` - ToBeCreate string `json:"待创建"` - ToBeDel string `json:"待删除"` - JxSkuName string `json:"京西商品名"` - VendorSkuName string `json:"平台商品名"` - JxStatus string `json:"京西可售状态"` - VendorStatus string `json:"平台可售状态"` - JxSkuPrice string `json:"京西价格"` /*哇,不能小写,不然会搞事情*/ - VendorPrice string `json:"平台价格"` - DatAanalyse string `json:"数据分析"` -} - -type StatisticData struct { - JxVendorStatus string `json:"京西和平台商品状态"` - ToBeCreate string `json:"待创建"` - JxSaleStatus string `json:"京西可售状态"` - Count string `json:"数量"` - Percent string `json:"占比"` -} - -func (d *DeoptDiffDataLock) AppendData2(vendorID int, depotDiffData DepotDiffData) { - d.locker.Lock() - defer d.locker.Unlock() - d.diffDataMap[vendorID] = append(d.diffDataMap[vendorID], depotDiffData) -} - -func (d *DeoptDiffDataLock) InitData2() { - d.diffDataMap = make(map[int][]DepotDiffData) -} - -func (d *DiffDataLock) AppendData(vendorID int, diffData DiffData) { - d.locker.Lock() - defer d.locker.Unlock() - d.diffDataMap[vendorID] = append(d.diffDataMap[vendorID], diffData) -} - -func (d *DiffDataLock) InitData() { - d.diffDataMap = make(map[int][]DiffData) -} - -func InitMultiStoreData() { - multiStoreAllSkuInfoMap = make(map[int]map[string]map[int]*partner.SkuNameInfo) - multiStoreAllSkuInfoList = make(map[int]map[string][]*partner.StoreSkuInfo) -} - -func GetMultiStoreAllSkuInfoMap(vendorID int, vendorOrgCode string) (retVal map[int]*partner.SkuNameInfo) { - if multiStoreAllSkuInfoMap[vendorID] != nil { - retVal = multiStoreAllSkuInfoMap[vendorID][vendorOrgCode] - } - return retVal -} - -func GetMultiStoreAllSkuInfoList(vendorID int, vendorOrgCode string) (retVal []*partner.StoreSkuInfo) { - if multiStoreAllSkuInfoList[vendorID] != nil { - retVal = multiStoreAllSkuInfoList[vendorID][vendorOrgCode] - } - return retVal -} - -//过滤掉平台下架的 -func StoreSkuFullList2BareFilter(storeSkuFull []*partner.SkuNameInfo) (bareStoreSkuList []*partner.StoreSkuInfo) { - for _, v := range storeSkuFull { - for _, v2 := range v.SkuList { - if v2.Status > model.SkuStatusDontSale { - bareStoreSkuList = append(bareStoreSkuList, &v2.StoreSkuInfo) - } - } - } - return bareStoreSkuList -} - -func GetMultiStoreAllSkuInfo(ctx *jxcontext.Context, vendorMap map[int]bool) { - InitMultiStoreData() - filterVendorDepotUnSaleSkuIds = filterVendorDepotUnSaleSkuIds[0:0] - for vendorID, _ := range vendorNameList { - //filter for vendorID - if len(vendorMap) > 0 { - if _, ok := vendorMap[vendorID]; !ok { - continue - } - } - if partner.IsMultiStore(vendorID) { - multiHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IMultipleStoresHandler) - for _, vendorOrgCode := range apimanager.CurAPIManager.GetAppOrgCodeList(vendorID) { - allSkuNameInfoList, err := multiHandler.GetSkus(ctx, vendorOrgCode, 0, "") - skuNameInfoList = allSkuNameInfoList - if err != nil { - baseapi.SugarLogger.Errorf("GetMultiStoreAllSkuInfo error:%v", err) - } else { - if multiStoreAllSkuInfoList[vendorID] != nil { - multiStoreAllSkuInfoList[vendorID][vendorOrgCode] = StoreSkuFullList2BareFilter(allSkuNameInfoList) //map[平台ID:[]StoreSkuInfo1,StoreSkuInfo2...] - } else { - multiStoreAllSkuInfoList = make(map[int]map[string][]*partner.StoreSkuInfo) - multiStoreAllSkuInfoList[vendorID] = make(map[string][]*partner.StoreSkuInfo) - multiStoreAllSkuInfoList[vendorID][vendorOrgCode] = StoreSkuFullList2BareFilter(allSkuNameInfoList) //map[平台ID:[]StoreSkuInfo1,StoreSkuInfo2...] - } - tempMap := make(map[int]*partner.SkuNameInfo) - for _, value := range allSkuNameInfoList { - for _, skuInfo := range value.SkuList { - //表示平台商品库未下架的 - if skuInfo.Status > model.SkuStatusDontSale { - filterVendorDepotUnSaleSkuIds = append(filterVendorDepotUnSaleSkuIds, skuInfo.SkuID) - tempMap[skuInfo.SkuID] = value - } - } - } - multiStoreAllSkuInfoMap[vendorID] = make(map[string]map[int]*partner.SkuNameInfo) - multiStoreAllSkuInfoMap[vendorID][vendorOrgCode] = tempMap //map[平台ID][map[skuID1:SkuNameInfo1,skuID2:SkuNameInfo2]...] - } - } - } - } -} - -func GetFilterJxSkuInfoMap(jxSkuInfoList []*dao.StoreSkuNameExt) map[int]*dao.StoreSkuNameExt { - filterJxSkuInfoMap := make(map[int]*dao.StoreSkuNameExt) - for _, value := range jxSkuInfoList { - for _, skuInfo := range value.Skus { - filterJxSkuInfoMap[skuInfo.SkuID] = value - } - } - - return filterJxSkuInfoMap -} - -func GetFilterVendorSkuInfoMap(vendorSkuInfoList []*partner.SkuNameInfo) map[int]*partner.SkuNameInfo { - filterVendorSkuInfoMap := make(map[int]*partner.SkuNameInfo) - for _, value := range vendorSkuInfoList { - for _, skuInfo := range value.SkuList { - filterVendorSkuInfoMap[skuInfo.SkuID] = value - } - } - - return filterVendorSkuInfoMap -} - -func GetFilterJxSkuInfoMap2(jxSkuInfoList []*model.SkuAndName) map[int]*model.SkuAndName { - filterVendorSkuInfoMap := make(map[int]*model.SkuAndName) - for _, value := range jxSkuInfoList { - filterVendorSkuInfoMap[value.ID] = value - } - return filterVendorSkuInfoMap -} - -func GetFilterMultiStoreSkuInfoMap(vendorID int, vendorOrgCode string, skuInfoList []*partner.StoreSkuInfo) map[int]*partner.SkuNameInfo { - allSkuInfoMap := GetMultiStoreAllSkuInfoMap(vendorID, vendorOrgCode) - filterSkuInfoMap := make(map[int]*partner.SkuNameInfo) - for _, value := range skuInfoList { - if value.Stock > 0 { - filterSkuInfoMap[value.SkuID] = allSkuInfoMap[value.SkuID] - } - } - - return filterSkuInfoMap -} - -func GetFilterStoreList(storeList []*StoreExt, vendorMap, storeIDMap map[int]bool) (outStoreList []*StoreExt) { - for _, storeInfo := range storeList { - storeID := storeInfo.ID - //filter for storeID - if len(storeIDMap) > 0 { - if _, ok := storeIDMap[storeID]; !ok { - continue - } - } - if storeInfo.StoreMaps != nil { - var tempStoreMaps []*model.StoreMap - for _, vendorStoreInfo := range storeInfo.StoreMaps { - vendorID := vendorStoreInfo.VendorID - isSyncStoreSku := int(vendorStoreInfo.IsSync) - if isSyncStoreSku == 0 { - continue - } - //filter for vendorID - if len(vendorMap) > 0 { - if _, ok := vendorMap[vendorID]; !ok { - continue - } - } - if _, ok := vendorNameList[vendorID]; !ok { - continue - } - tempStoreMaps = append(tempStoreMaps, vendorStoreInfo) - } - if len(tempStoreMaps) > 0 { - storeInfo.StoreMaps = tempStoreMaps - outStoreList = append(outStoreList, storeInfo) - } - } - } - - return outStoreList -} - -func GetSkuSaleStatusName(status int) string { - return model.SkuStatusName[status] -} - -func GetBoolName(flag bool) string { - if flag { - return "是" - } else { - return "否" - } -} - -func IsSkuCanSale(saleStatus int) bool { - return saleStatus == model.SkuStatusNormal -} - -//京西平台和其他平台商品的对比 -//storeIDStr 京西商家id ,vendorStoreID 平台商家id ,isJd 京东比较的标记 0不是,1是 -func CompareJxAndVendor(vendorID int, storeIDStr, vendorStoreID, storeName string, filterJxSkuInfoMap map[int]*dao.StoreSkuNameExt, filterVendorSkuInfoMap map[int]*partner.SkuNameInfo, isJd int) { - //utils.Writelog("进入 CompareJxAndVendor 方法") - for skuID, jxSkuInfo := range filterJxSkuInfoMap { - skuIDStr := utils.Int2Str(skuID) - /*写京西skuIDStr*/ - //utils.Writelog("skuIDStr" + skuIDStr) - var jxSkuDetailName string - //jxSkuDetailName : 前缀 ([荐]) + 分类名(xxx水饺) + 数量单位(约..g/份) + 注释 (补充..) - jxSkuDetailName = jxutils.ComposeSkuNameOriginal(jxSkuInfo.SkuName.Prefix, jxSkuInfo.SkuName.Name, jxSkuInfo.Skus[0].Comment, jxSkuInfo.SkuName.Unit, jxSkuInfo.Skus[0].SkuSpecQuality, jxSkuInfo.Skus[0].SkuSpecUnit, 0) - //utils.Writelog("jxSkuDetailName:" + jxSkuDetailName) - //jxSkuSaleStatus : 商品状态 ,skustatus 优先级高于 StoreSkuStatus - jxSkuSaleStatus := jxutils.MergeSkuStatus(jxSkuInfo.Skus[0].SkuStatus, jxSkuInfo.Skus[0].StoreSkuStatus) - jxSkuSaleStatusName := GetSkuSaleStatusName(jxSkuSaleStatus + 3) - /*京西价格*/ - jxSkuPrice := fmt.Sprintf("%.2f", float64(jxSkuInfo.Skus[0].JxPrice)/float64(100)) - /*饿了吗编码*/ - ebaiid := jxSkuInfo.Skus[0].EbaiID - /*美团编码*/ - mtwmid := jxSkuInfo.Skus[0].MtwmID - //jxSkuPrice := strconv.Itoa(jxSkuInfo.Skus[0].JxPrice) - vendorSkuInfo := filterVendorSkuInfoMap[skuID] - var status int8 - if vendorID == model.VendorIDMTWM { - status = jxSkuInfo.Skus[0].MtwmSyncStatus - } else if vendorID == model.VendorIDEBAI { - status = jxSkuInfo.Skus[0].EbaiSyncStatus - } else if vendorID == model.VendorIDJD { - status = jxSkuInfo.Skus[0].JdSyncStatus - } - syncStatus := utils.Int2Str(int(status)) - toBeCreate := GetBoolName(model.IsSyncStatusNeedCreate(status)) - toBeDel := GetBoolName(model.IsSyncStatusNeedDelete(status)) - - if vendorSkuInfo != nil { - vendorSkuDetailName := vendorSkuInfo.SkuList[0].SkuName - vendorSkuSaleStatusName := GetSkuSaleStatusName(vendorSkuInfo.SkuList[0].Status + 3) - /* 供货商价格 */ - vendorPrice := fmt.Sprintf("%.2f", float64(vendorSkuInfo.SkuList[0].StoreSkuInfo.VendorPrice)/float64(100)) - var IdMark bool - if isJd == 0 { - IdMark = skuIDStr != ebaiid && skuIDStr != mtwmid - } else { - IdMark = false - } - isSaleStatusDiff := jxSkuSaleStatusName != vendorSkuSaleStatusName - isNameDiff := jxSkuDetailName != vendorSkuDetailName - /*比较价格*/ - isPriceDiff := vendorPrice != jxSkuPrice - //utils.Writelog("isSaleStatusDiff:" + strconv.FormatBool(isSaleStatusDiff)) - //utils.Writelog("isNameDiff:" + strconv.FormatBool(isNameDiff)) - if jxSkuDetailName != "" && vendorSkuDetailName != "" && strings.Contains(jxSkuDetailName, vendorSkuDetailName) { - isNameDiff = false - } - if isSaleStatusDiff || isNameDiff || isPriceDiff { - reason := "" - if isNameDiff { - reason += DatAanalyse3 - } - if isSaleStatusDiff { - reason += DatAanalyse4 - } - if isPriceDiff { - reason += DatAanalyse9 - } - if IdMark { - reason += DatAanalyse10 - } - if status != model.SkuStatusDontSale { - reason += DatAanalyse7 - } - outPutData := DiffData{storeIDStr, vendorStoreID, storeName, skuIDStr, mtwmid, ebaiid, syncStatus, toBeCreate, toBeDel, jxSkuDetailName, vendorSkuDetailName, jxSkuSaleStatusName, vendorSkuSaleStatusName, jxSkuPrice, vendorPrice, reason} - diffData.AppendData(vendorID, outPutData) - } - if !isSaleStatusDiff && !isNameDiff { - if status != model.SkuStatusDontSale { - outPutData := DiffData{storeIDStr, vendorStoreID, storeName, skuIDStr, mtwmid, ebaiid, syncStatus, toBeCreate, toBeDel, jxSkuDetailName, vendorSkuDetailName, jxSkuSaleStatusName, vendorSkuSaleStatusName, jxSkuPrice, vendorPrice, DatAanalyse7} - diffData.AppendData(vendorID, outPutData) - } - } - } else { - if isFilterToBeCreateAndNotSale && model.IsSyncStatusNeedCreate(status) && !IsSkuCanSale(jxSkuSaleStatus) { - continue - } - reason := "" - if status == model.SkuStatusDontSale { - reason = DatAanalyse8 - } else { - reason = DatAanalyse2 - } - if status != model.SkuStatusDontSale { - reason += DatAanalyse7 - } - outPutData := DiffData{storeIDStr, vendorStoreID, storeName, skuIDStr, mtwmid, ebaiid, syncStatus, toBeCreate, toBeDel, jxSkuDetailName, "", jxSkuSaleStatusName, "", jxSkuPrice, "", reason} - diffData.AppendData(vendorID, outPutData) - } - } - for skuID, vendorSkuInfo := range filterVendorSkuInfoMap { - if vendorSkuInfo != nil { - if len(vendorSkuInfo.SkuList) > 0 { - skuIDStr := utils.Int2Str(skuID) - vendorSkuDetailName := vendorSkuInfo.SkuList[0].SkuName - vendorSkuSaleStatusName := GetSkuSaleStatusName(vendorSkuInfo.SkuList[0].Status + 3) - /* 供货商价格 */ - vendorPrice := fmt.Sprintf("%.2f", float64(vendorSkuInfo.SkuList[0].StoreSkuInfo.VendorPrice)/float64(100)) - /* 供货商价格 */ - jxSkuInfo := filterJxSkuInfoMap[skuID] - /*平台有,京西没有*/ - if jxSkuInfo == nil { - outPutData := DiffData{storeIDStr, vendorStoreID, "", "", storeName, skuIDStr, "", "", "", "", vendorSkuDetailName, "", vendorSkuSaleStatusName, "", vendorPrice, DatAanalyse1} - diffData.AppendData(vendorID, outPutData) - } - } else { - globals.SugarLogger.Debugf("CompareJxAndVendor vendorSkuInfo.SkuList:%d is nil", skuID) - } - } else { - globals.SugarLogger.Debugf("CompareJxAndVendor skuID:%d is nil", skuID) - } - } -} - -func FilterJxDepotUnSaleSkuID() { - db := dao.GetDB() - filterJxDepotUnSaleSkuIds = filterJxDepotUnSaleSkuIds[0:0] - skuList, _ := dao.GetSkus(db, filterVendorDepotUnSaleSkuIds, []int{}, []int{}, []int{}, nil) - filterJxSkuInfoMap2 := GetFilterJxSkuInfoMap2(skuList) - for skuid, jxSkuInfo := range filterJxSkuInfoMap2 { - //过滤掉平台库下架,且京西库下架的商品,为下面比较门店商品用 - if jxSkuInfo.Status != model.SkuStatusDontSale { - filterJxDepotUnSaleSkuIds = append(filterJxDepotUnSaleSkuIds, skuid) - } - } -} - -func CompareJxAndMultiVenderDepot(ctx *jxcontext.Context, vendorMap map[int]bool) { - db := dao.GetDB() - for vendorID, _ := range vendorNameList { - //filter for vendorID - if len(vendorMap) > 0 { - if _, ok := vendorMap[vendorID]; !ok { - continue - } - } - if partner.IsMultiStore(vendorID) { - FilterJxDepotUnSaleSkuID() - filterVendorSkuInfoMap := GetFilterVendorSkuInfoMap(skuNameInfoList) - skuNameInfoList = skuNameInfoList[0:0] - skuList, _ := dao.GetSkus(db, []int{}, []int{}, []int{}, []int{}, nil) - filterJxSkuInfoMap2 := GetFilterJxSkuInfoMap2(skuList) - for skuid, jxSkuInfo := range filterJxSkuInfoMap2 { - var jxSkuDetailName string - //多规格商品不用比较数量单位 - if jxSkuInfo.IsSpu == 0 { - jxSkuDetailName = jxutils.ComposeSkuNameOriginal(jxSkuInfo.Prefix, jxSkuInfo.Name, jxSkuInfo.Comment, jxSkuInfo.Unit, jxSkuInfo.SpecQuality, jxSkuInfo.SpecUnit, 0) - } else { - jxSkuDetailName = jxutils.ComposeSkuNameOriginal(jxSkuInfo.Prefix, jxSkuInfo.Name, jxSkuInfo.Comment, "", jxSkuInfo.SpecQuality, "", 0) - } - - vendorSkuInfoMap := filterVendorSkuInfoMap[skuid] - jxSkuSaleStatus := jxSkuInfo.Status - jxSkuSaleStatusName := GetSkuSaleStatusName(jxSkuSaleStatus) - skuIDStr := utils.Int2Str(skuid) - if vendorSkuInfoMap != nil { - vendorSkuSaleStatusName := GetSkuSaleStatusName(vendorSkuInfoMap.SkuList[0].Status) - vendorSkuDetailName := vendorSkuInfoMap.SkuList[0].SkuName - isSaleStatusDiff := jxSkuSaleStatusName != vendorSkuSaleStatusName - isNameDiff := strings.Compare(jxSkuDetailName, vendorSkuDetailName) != 0 - if isNameDiff || isSaleStatusDiff { - reason := "" - if isNameDiff { - reason += DatAanalyse3 - } - if isSaleStatusDiff { - reason += DatAanalyse4 - } - outPutData := DepotDiffData{skuIDStr, jxSkuDetailName, vendorSkuDetailName, jxSkuSaleStatusName, vendorSkuSaleStatusName, reason} - depotDiffData.AppendData2(vendorID, outPutData) - } - } else { - outPutData := DepotDiffData{skuIDStr, jxSkuDetailName, "", jxSkuSaleStatusName, "", DatAanalyse6} - depotDiffData.AppendData2(vendorID, outPutData) - } - } - for skuID, vendorSkuInfo := range filterVendorSkuInfoMap { - if vendorSkuInfo != nil { - if len(vendorSkuInfo.SkuList) > 0 { - skuIDStr := utils.Int2Str(skuID) - vendorSkuDetailName := vendorSkuInfo.SkuList[0].SkuName - vendorSkuSaleStatusName := GetSkuSaleStatusName(vendorSkuInfo.SkuList[0].Status + 3) - - jxSkuInfo := filterJxSkuInfoMap2[skuID] - if jxSkuInfo == nil { - outPutData := DepotDiffData{skuIDStr, "", vendorSkuDetailName, "", vendorSkuSaleStatusName, DatAanalyse5} - depotDiffData.AppendData2(vendorID, outPutData) - } - } else { - globals.SugarLogger.Debugf("CompareJxAndMultiVenderDepot vendorSkuInfo.SkuList:%d is nil", skuID) - } - } else { - globals.SugarLogger.Debugf("CompareJxAndMultiVenderDepot skuID:%d is nil", skuID) - } - } - } - } -} - -func StoreOpenAll(ctx *jxcontext.Context) { - AutoFocusStoreSkusForTopSkus(ctx, true, true) - //globals.SugarLogger.Debug("StoreOpenAll skuID is start") - ///*获取美团门店信息*/ - //StoreInfoList, _ := api.MtpsAPI.GetStoreStatusAll() - //StoreInfoList2 := make(map[string]string) - //for _, store := range StoreInfoList { - // for _, data := range store.DataList { - // StoreInfoList2[data.OuterPoiID] = data.PoiName - // } - //} - //db := dao.GetDB() - ///*比较营业状态*/ - ///*把获取的京西状态和名称存一下*/ - //StoreCourierList, _ := dao.GetStoreCourierList(db, []int{}, model.StoreStatusAll, model.StoreStatusAll) - ///*循环美团*/ - //for _, StoreInfoList1 := range StoreInfoList { - // for _, StoreInfoList11 := range StoreInfoList1.DataList { - // /*循环京西*/ - // for _, StoreCourierList1 := range StoreCourierList { - // /*只比较美团*/ - // if StoreCourierList1.VendorID != model.VendorIDMTPS { - // continue - // } - // /*如果门店ID相同的时候进入判断,一个门店只用判断一次就行*/ - // if StoreCourierList1.VendorStoreID == StoreInfoList11.OuterPoiID { - // if StoreCourierList1.Status != StoreInfoList11.OpenType { - // sl := make(map[string]interface{}) - // sl["vendorStoreID"] = StoreInfoList11.OuterPoiID - // sl["status"] = StoreInfoList11.OpenType - // sl["vendorStatus"] = StoreInfoList11.OpenType - // globals.SugarLogger.Debugf("被修改配送状态的VendorStoreID是:%s,名称是:%s,美团状态是:%s,本地状态是:%s", - // StoreInfoList11.OuterPoiID, StoreInfoList11.PoiName, strconv.Itoa(StoreInfoList11.OpenType), strconv.Itoa(StoreCourierList1.Status)) - // UpdateStoreCourierMap(ctx, nil, StoreCourierList1.StoreID, StoreCourierList1.VendorID, sl, ctx.GetUserName()) - // break - // } - // } - // } - // } - //} - ///* 美团配送的门店是否存在,调用美团配送的api(有可能接了),查询京西门店对应的美团配送门店是否存在,若不存在则要在京西这边解绑美团配送门店 - // 怎么解绑可以在网页上门店管理那点一下看看调的什么接口,传的什么参数*/ - ///*获取所有门店信息*/ - ////test: - //for _, StoreCourierList1 := range StoreCourierList { - // diff := false - // StoreLists, _ := dao.GetStoreList(db, []int{StoreCourierList1.StoreID}, nil, nil, nil, "") - // if StoreLists == nil { - // globals.SugarLogger.Debugf("StoreID为:%s,在store表未找到", StoreCourierList1.StoreID) - // continue - // } - // if StoreCourierList1.VendorID != model.VendorIDMTPS || StoreCourierList1.VendorStoreID == "" { - // continue - // } - // if StoreCourierList1.Status == model.StoreStatusDisabled || StoreCourierList1.Status == model.StoreStatusClosed { - // continue - // } - // /*京西不为空,容错*/ - // //if { - // /*调用API获取美团的商店信息*/ - // MTPSInfo := new(mtpsapi.ShopInfo) - // MTPSInfo, _ = api.MtpsAPI.ShopQuery(StoreCourierList1.VendorStoreID) - // if MTPSInfo == nil { - // globals.SugarLogger.Debug("美团未找到该门店," + StoreLists[0].Name + strconv.Itoa(StoreCourierList1.StoreID) + " 被解绑,关联的ID为:" + StoreCourierList1.VendorStoreID) - // diff = true - // } - // if MTPSInfo != nil && MTPSInfo.ShopName == "" { - // MTPSInfo.ShopName = StoreInfoList2[MTPSInfo.ShopID] - // } - // if MTPSInfo != nil && MTPSInfo.ShopLng != StoreCourierList1.Lng && MTPSInfo.ShopLat == StoreCourierList1.Lat { - // /*平台上但是坐标不同,解绑*/ - // globals.SugarLogger.Debug("商店与美团配送上的坐标不同," + StoreLists[0].Name + strconv.Itoa(StoreCourierList1.StoreID) + " 被解绑,关联的ID为:" + StoreCourierList1.VendorStoreID) - // if _, err := DeleteStoreCourierMap(ctx, db, StoreCourierList1.StoreID, StoreCourierList1.VendorID, ctx.GetUserName()); err != nil { - // globals.SugarLogger.Debug(err.Error()) - // return - // } - // diff = true - // } - // if diff { - // if _, err := DeleteStoreCourierMap(ctx, db, StoreCourierList1.StoreID, StoreCourierList1.VendorID, ctx.GetUserName()); err != nil { - // globals.SugarLogger.Debug(err.Error()) - // return - // } - // //break test - // } - //} - //globals.SugarLogger.Debug("StoreOpenAll skuID is Complete") -} - -//func StoreOpenAll(ctx *jxcontext.Context) { -//db := dao.GetDB() -///*获取所有门店信息*/ -//StoreLists, err := dao.GetStoreList(db, nil, nil, []int{}, nil, "") -//if err != nil { -// globals.SugarLogger.Debugf("商店列表获取失败") -//} -///*距离结构体*/ -//type Distance struct { -// StoreID string `json:"门店ID"` -// StoreStatus string `json:"门店状态"` -// StoreName string `json:"门店名"` -// Tel string `json:"电话"` -// City string `json:"城市"` -// Address string `json:"地址"` -// DistanceId string `json:"附近门店ID"` -// DistanceStatus string `json:"附近门店状态"` -// DistanceName string `json:"附近门店名"` -// DistanceAddress string `json:"附近门店地址"` -// DistanceValue string `json:"距离附近门店距离(m)"` -//} -//distanceStore := make(map[int][]Distance) -//var isCloud []string -//var CloudBool bool -//for _, StoreList := range StoreLists { -// /*循环内部声明,1对多*/ -// var a []Distance -// lng := jxutils.IntCoordinate2Standard(StoreList.Lng) -// lat := jxutils.IntCoordinate2Standard(StoreList.Lat) -// for _, StoreList1 := range StoreLists { -// if StoreList1.ID == StoreList.ID { -// continue -// } -// /*把s与提前存好的字段对比,如果相同说明 A+B=B+A的情况,直接跳过*/ -// s := strconv.Itoa(StoreList1.ID) + strconv.Itoa(StoreList.ID) -// for _, x := range isCloud { -// if s == x { -// CloudBool = true -// break -// } -// } -// if CloudBool == true{ -// CloudBool = false -// continue -// } -// lng1 := jxutils.IntCoordinate2Standard(StoreList1.Lng) -// lat1 := jxutils.IntCoordinate2Standard(StoreList1.Lat) -// if jxutils.EarthDistance(lng, lat, lng1, lat1) < 0.5 { -// //门店ID,门店名,电话,城市,地址,附近门店ID,附近门店名,距离附近门店距离(m) -// b := &Distance{ -// strconv.Itoa(StoreList.ID), -// strconv.Itoa(StoreList.Status), -// StoreList.Name, -// StoreList.Tel1, -// strconv.Itoa(StoreList.CityCode), -// StoreList.Address, -// strconv.Itoa(StoreList1.ID), -// strconv.Itoa(StoreList1.Status), -// StoreList1.Name, -// StoreList1.Address, -// fmt.Sprintf("%.2f", jxutils.EarthDistance(lng, lat, lng1, lat1)*1000), -// } -// a = append(a, *b) -// distanceStore[StoreList.ID] = a -// isCloud = append(isCloud, strconv.Itoa(StoreList.ID)+strconv.Itoa(StoreList1.ID)) -// } -// } -//} -// -////DistanceTitle := []string{ -//// "门店ID", -//// "门店名", -//// "电话", -//// "城市", -//// "地址", -//// "附近门店ID", -//// "附近门店名", -//// "距离附近门店距离(m)", -////} -//fmt.Println(len(distanceStore)) -//xlsx := excelize.NewFile() -//index := xlsx.NewSheet("Sheet1") -//xlsx.SetCellValue("Sheet1", "A1", "门店ID") -//xlsx.SetCellValue("Sheet1", "B1", "门店状态") -//xlsx.SetCellValue("Sheet1", "C1", "门店名") -//xlsx.SetCellValue("Sheet1", "D1", "电话") -//xlsx.SetCellValue("Sheet1", "E1", "城市") -//xlsx.SetCellValue("Sheet1", "F1", "地址") -//xlsx.SetCellValue("Sheet1", "G1", "附近门店ID") -//xlsx.SetCellValue("Sheet1", "H1", "附近门店状态") -//xlsx.SetCellValue("Sheet1", "I1", "附近门店名") -//xlsx.SetCellValue("Sheet1", "J1", "附近门店地址") -//xlsx.SetCellValue("Sheet1", "K1", "距离附近门店距离(M)") -//i := 2 -//for _, value := range distanceStore { -// for _, value1 := range value { -// xlsx.SetCellValue("Sheet1", "A"+strconv.Itoa(i), value1.StoreID) -// xlsx.SetCellValue("Sheet1", "B"+strconv.Itoa(i), value1.StoreStatus) -// xlsx.SetCellValue("Sheet1", "C"+strconv.Itoa(i), value1.StoreName) -// xlsx.SetCellValue("Sheet1", "D"+strconv.Itoa(i), value1.Tel) -// xlsx.SetCellValue("Sheet1", "E"+strconv.Itoa(i), value1.City) -// xlsx.SetCellValue("Sheet1", "F"+strconv.Itoa(i), value1.Address) -// xlsx.SetCellValue("Sheet1", "G"+strconv.Itoa(i), value1.DistanceId) -// xlsx.SetCellValue("Sheet1", "H"+strconv.Itoa(i), value1.DistanceStatus) -// xlsx.SetCellValue("Sheet1", "I"+strconv.Itoa(i), value1.DistanceName) -// xlsx.SetCellValue("Sheet1", "J"+strconv.Itoa(i), value1.DistanceAddress) -// xlsx.SetCellValue("Sheet1", "K"+strconv.Itoa(i), value1.DistanceValue) -// i++ -// } -//} -//// Set active sheet of the workbook. -//xlsx.SetActiveSheet(index) -//// Save xlsx file by the given path. -//err = xlsx.SaveAs("C:\\Users\\86159\\Desktop\\WorkForTemp\\距离小于500米门店信息.xlsx") -//if err != nil { -// fmt.Println(err) -//} -//var sheetList []*excel.Obj2ExcelSheetConfig -//sheetName := "附近500米门店信息" -//for _, value := range distanceStore { -// excelConf := &excel.Obj2ExcelSheetConfig{ -// Title: sheetName, -// Data: value, -// CaptionList: DistanceTitle, -// } -// file,err := os.OpenFile("C:\\Users\\86159\\Desktop\\WorkForTemp\\haha.txt",os.O_APPEND|os.O_RDWR,6660) -// if err != nil{ -// fmt.Println(err.Error()) -// } -// file.WriteString(fmt.Sprintln(excelConf.Data)) -// sheetList = append(sheetList, excelConf) -// baseapi.SugarLogger.Debugf("WriteToExcel:append:%s count:%d", sheetName, len(value)) -//} -//if len(sheetList) > 0 { -// excelBin := excel.Obj2Excel(sheetList) -// sheetList = nil -// timeStr := utils.Int64ToStr(time.Now().Unix()) -// diffFullFileName := "附近500米门店信息数据" + timeStr + fileExt -// baseapi.SugarLogger.Debugf("WriteToExcel:save %s success", diffFullFileName) -// //上传 -// downloadURL, err := jxutils.UploadExportContent(excelBin, diffFullFileName) -// if err != nil { -// baseapi.SugarLogger.Errorf("WriteToExcel:upload %s failed error:%v", diffFullFileName, err) -// } else { -// baseapi.SugarLogger.Debugf("WriteToExcel:upload %s success, downloadURL: %s", diffFullFileName, downloadURL) -// /*************发送钉钉消息**************/ -// //ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "", "异步任务完成", "附近500米门店信息数据上传成功:Excel下载地址是 "+downloadURL) -// } -//} else { -// baseapi.SugarLogger.Debug("WriteToExcel:No diff data!!!") -//} -//} - -//func StoreOpenAll(ctx *jxcontext.Context) { -// db := dao.GetDB() -// StoreLists, err := dao.GetStoreList(db, nil, nil, []int{1}, nil, "") -// if err != nil { -// globals.SugarLogger.Debugf("商店列表获取失败") -// } -// var StoreMapLists []*model.StoreMap -// for _, StoreList := range StoreLists { -// if StoreList.StoreLevel == "E" { -// continue -// } -// if StoreMapLists, err = dao.GetStoresMapList(db, []int{0, 1, 3}, []int{StoreList.ID}, nil, 1, -1, "", ""); err != nil { -// globals.SugarLogger.Debugf("商店列表获取失败") -// } -// if len(StoreMapLists) > 0 { -// /*将map查询的结果全部放进数组*/ -// for _, StoreMapList := range StoreMapLists { -// /*二元运算符*/ -// StoreMapList.SyncStatus = StoreMapList.SyncStatus | model.SyncFlagModifiedMask -// StoreMapList.UpdatedAt = time.Now() -// StoreMapList.LastOperator = ctx.GetUserName() -// dao.UpdateEntity(db, StoreMapList, "SyncStatus", "UpdatedAt", "LastOperator") -// //} -// /*同步*/ -// if _, err = CurVendorSync.SyncStore(ctx, db, StoreMapList.VendorID, StoreList.ID, false, ctx.GetUserName()); err != nil { -// globals.SugarLogger.Debugf("同步失败") -// } -// } -// } -// if StoreMapLists, err = dao.GetStoresMapList(db, []int{9}, []int{StoreList.ID}, nil, 1, -1, "", ""); err != nil { -// globals.SugarLogger.Debugf("商店列表获取失败") -// } -// if len(StoreMapLists) == 0 { -// /*遍历,绑定*/ -// Map := &model.StoreMap{} -// Map.VendorStoreID = strconv.Itoa(StoreList.ID) -// Map.AutoPickup = 1 -// Map.DeliveryCompetition = 1 -// Map.PricePercentage = 100 -// Map.IsSync = 1 -// Map.PricePercentagePack = "京西100-100" -// Map.DeliveryFeeDeductionSill = 0 -// Map.DeliveryFeeDeductionFee = 0 -// Map.IsOrder = 0 -// if _, err := AddStoreVendorMap(ctx, db, 9, "", StoreList.ID, Map); err != nil { -// globals.SugarLogger.Debugf("AddStoreVendorMap调用出错,StoreID是" + strconv.Itoa(StoreList.ID)) -// globals.SugarLogger.Debugf(err.Error()) -// } -// } -// /*改配送范围*/ -// //deliverrangetype 3 -// //deliverrange 3000 -// StoreList.DeliveryRange = "3000" -// StoreList.DeliveryRangeType = 3 -// StoreList.UpdatedAt = time.Now() -// StoreList.LastOperator = ctx.GetUserName() -// dao.UpdateEntity(db, StoreList, "DeliveryRange", "DeliveryRangeType", "LastOperator", "UpdatedAt") -// } -// globals.SugarLogger.Debug("StoreOpenAll skuID is Complete") -//} - -func TestDiff(ctx *jxcontext.Context, vendorIDList []int, storeIDList []int) { - baseapi.SugarLogger.Debugf("CheckSkuDiffBetweenJxAndVendor start time: %v", time.Now()) - startProcessTime := time.Now().Unix() - vendorMap := make(map[int]bool) - for _, vendorID := range vendorIDList { - vendorMap[vendorID] = true //map[平台ID:true] - } - storeIDMap := make(map[int]bool) - for _, storeID := range storeIDList { - storeIDMap[storeID] = true //map[门店ID:true] - } - /************************************************update**************************************************/ - //自己存值 - a := func() { - for vendorID, _ := range vendorNameList { - //filter for vendorID - if len(vendorMap) > 0 { - if _, ok := vendorMap[vendorID]; !ok { - continue - } - } - if partner.IsMultiStore(vendorID) { - multiHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IMultipleStoresHandler) - for _, vendorOrgCode := range apimanager.CurAPIManager.GetAppOrgCodeList(vendorID) { - allSkuNameInfoList, err := multiHandler.GetSkus(ctx, vendorOrgCode, 0, "") - //获取单个表格对比的物品信息列表 - skuNameInfoList = allSkuNameInfoList - if err != nil { - fmt.Println("allSkuNameInfoList赋值错误,error信息" + err.Error()) - continue - } - //*partner.StoreSkuInfo skuNameList []*SkuNameInfo - var bareStoreSkuList []*partner.StoreSkuInfo - for _, v := range allSkuNameInfoList { - for _, v2 := range v.SkuList { - if v2.Status > model.SkuStatusDontSale { - for _, v2 := range v.SkuList { - bareStoreSkuList = append(bareStoreSkuList, &v2.StoreSkuInfo) - } - } - } - } - //if multiStoreAllSkuInfoList[vendorID][vendorOrgCode] != nil && bareStoreSkuList != nil { - if multiStoreAllSkuInfoList[vendorID] != nil && bareStoreSkuList != nil { - multiStoreAllSkuInfoList[vendorID][vendorOrgCode] = bareStoreSkuList - //}else if multiStoreAllSkuInfoList[vendorID][vendorOrgCode] == nil{ - } else if multiStoreAllSkuInfoList[vendorID] == nil { - multiStoreAllSkuInfoList = make(map[int]map[string][]*partner.StoreSkuInfo) - multiStoreAllSkuInfoList[vendorID] = make(map[string][]*partner.StoreSkuInfo) - multiStoreAllSkuInfoList[vendorID][vendorOrgCode] = bareStoreSkuList - } - tempMap := make(map[int]*partner.SkuNameInfo) - for _, value := range allSkuNameInfoList { - for _, skuInfo := range value.SkuList { - //表示平台商品库未下架的 - if skuInfo.Status > model.SkuStatusDontSale { - filterVendorDepotUnSaleSkuIds = append(filterVendorDepotUnSaleSkuIds, skuInfo.SkuID) - tempMap[skuInfo.SkuID] = value - } - } - } - //商品信息 - if multiStoreAllSkuInfoMap[vendorID] == nil { - multiStoreAllSkuInfoMap = make(map[int]map[string]map[int]*partner.SkuNameInfo) - multiStoreAllSkuInfoMap[vendorID] = make(map[string]map[int]*partner.SkuNameInfo) - //multiStoreAllSkuInfoMap[vendorID][vendorOrgCode] = make(map[int]*partner.SkuNameInfo) - multiStoreAllSkuInfoMap[vendorID][vendorOrgCode] = tempMap - } else { - multiStoreAllSkuInfoMap[vendorID][vendorOrgCode] = tempMap - } - } - } - } - } - - /************************************************update****************************************************/ - //1.获取京西本地所有门店信息 store、place、user表联查 jxStoreInfoList - //2.过滤所有门店信息,只留下传进来的vendorMap,storeIDMap中对应的平台和门台信息 filterStoreList - //3.判断是否多平台门店,两种情况两种处理 - b := func() { - jxStoreInfoList, err := GetStores(ctx, "", map[string]interface{}{}, 0, -1, utils.DefaultTimeValue, utils.DefaultTimeValue, 0, 0) - if err != nil { - baseapi.SugarLogger.Errorf("CheckSkuDiffBetweenJxAndVendor GetStores error:%v", err) - } else { - //获取总共几个门店任务 - filterStoreList := GetFilterStoreList(jxStoreInfoList.Stores, vendorMap, storeIDMap) - diffData.InitData() - for i := range filterStoreList { - jxStoreInfoListValue := filterStoreList[i] - storeID := jxStoreInfoListValue.ID - storeIDStr := utils.Int2Str(storeID) - storeName := jxStoreInfoListValue.Name - jxSkuInfoDataSingle := &dao.StoreSkuNamesInfo{} - jxSkuInfoDataMulti := &dao.StoreSkuNamesInfo{} - if jxStoreInfoListValue.StoreMaps != nil { - var multiFlag = false - var singleFlag = false - var filterJxSkuInfoMapSingle map[int]*dao.StoreSkuNameExt - var filterJxSkuInfoMapMulti map[int]*dao.StoreSkuNameExt - for _, vendorListValue := range jxStoreInfoListValue.StoreMaps { - vendorID := vendorListValue.VendorID - if partner.IsMultiStore(vendorID) { - if multiFlag == false { - jxSkuInfoDataMulti, _ = GetStoreSkus(ctx, storeID, filterJxDepotUnSaleSkuIds, true, "", true, false, map[string]interface{}{}, 0, -1) - /*重新计算价格*/ - SetJxPrice(jxSkuInfoDataMulti, storeID, vendorID) - filterJxSkuInfoMapMulti = GetFilterJxSkuInfoMap(jxSkuInfoDataMulti.SkuNames) //map[京西商品ID:StoreSkuNameExt] - multiFlag = true - } - } else { - if singleFlag == false { - jxSkuInfoDataSingle, _ = GetStoreSkus(ctx, storeID, nil, true, "", true, false, map[string]interface{}{}, 0, -1) - /*重新计算价格*/ - SetJxPrice(jxSkuInfoDataSingle, storeID, vendorID) - filterJxSkuInfoMapSingle = GetFilterJxSkuInfoMap(jxSkuInfoDataSingle.SkuNames) //map[京西商品ID:StoreSkuNameExt] - singleFlag = true - } - } - vendorStoreID := vendorListValue.VendorStoreID - baseapi.SugarLogger.Debugf("CheckSkuDiffBetweenJxAndVendor storeID:%d vendorID:%d vendorStoreID:%s vendorListValue:%v", storeID, vendorID, vendorStoreID, vendorListValue) - - if partner.IsMultiStore(vendorID) { - singleStoreHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IPurchasePlatformStoreSkuHandler) - allSkuInfoList := GetMultiStoreAllSkuInfoList(vendorID, vendorListValue.VendorOrgCode) - skuBareInfoList, err := singleStoreHandler.GetStoreSkusBareInfo(ctx, vendorListValue.VendorOrgCode, nil, storeID, vendorStoreID, allSkuInfoList) - if err != nil { - baseapi.SugarLogger.Infof("CheckSkuDiffBetweenJxAndVendor GetStoreSkusBareInfo error:%v", err) - } else if len(skuBareInfoList) > 0 { - //获取京东的商品 - filterSkuInfoMap := GetFilterMultiStoreSkuInfoMap(vendorID, vendorListValue.VendorOrgCode, skuBareInfoList) //map[京东商品ID:SkuNameInfo] - CompareJxAndVendor(vendorID, storeIDStr, vendorStoreID, storeName, filterJxSkuInfoMapMulti, filterSkuInfoMap, 1) - } - } else { - singleStoreHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreStoreSkuHandler) - vendorSkuInfoList, err := singleStoreHandler.GetStoreSkusFullInfo(ctx, nil, storeID, vendorStoreID, nil) - if err != nil { - baseapi.SugarLogger.Infof("CheckSkuDiffBetweenJxAndVendor GetStoreSkusFullInfo error:%v", err) - } else if len(vendorSkuInfoList) > 0 { - //获取京东的商品 - filterVendorSkuInfoMap := GetFilterVendorSkuInfoMap(vendorSkuInfoList) //map[平台商品ID:SkuNameInfo] - CompareJxAndVendor(vendorID, storeIDStr, vendorStoreID, storeName, filterJxSkuInfoMapSingle, filterVendorSkuInfoMap, 0) - } - } - } - } - } - } - } - - /********************************第三步****************************/ - c := func(data map[int][]DiffData, depotData map[int][]DepotDiffData) { - var sheetList []*excel.Obj2ExcelSheetConfig - for key, value := range data { - sheetName := vendorNameList[key] - if partner.IsMultiStore(key) { - excelConfDepot := &excel.Obj2ExcelSheetConfig{ - Title: sheetName + "商品库与京西商品库对比", - Data: depotData[key], - CaptionList: deoptTitleList, - } - sheetList = append(sheetList, excelConfDepot) - } - excelConf := &excel.Obj2ExcelSheetConfig{ - Title: sheetName, - Data: value, - CaptionList: titleList, - } - sheetList = append(sheetList, excelConf) - if needStatistic { - statisticSheet := AddStatisticSheet(sheetName, value) - sheetList = append(sheetList, statisticSheet) - } - baseapi.SugarLogger.Debugf("WriteToExcel:append:%s count:%d", sheetName, len(value)) - } - - if len(sheetList) > 0 { - excelBin := excel.Obj2Excel(sheetList) - sheetList = nil - timeStr := utils.Int64ToStr(time.Now().Unix()) - diffFullFileName := diffFileName[IsJXCS()] + timeStr + fileExt - if canWriteTolocal { - jxutils.WriteFile(diffFullFileName, excelBin) - } - baseapi.SugarLogger.Debugf("WriteToExcel:save %s success", diffFullFileName) - //上传 - downloadURL, err := jxutils.UploadExportContent(excelBin, diffFullFileName) - if err != nil { - baseapi.SugarLogger.Errorf("WriteToExcel:upload %s failed error:%v", diffFullFileName, err) - } else { - baseapi.SugarLogger.Debugf("WriteToExcel:upload %s success, downloadURL: %s", diffFullFileName, downloadURL) - /*************发送钉钉消息**************/ - ddmsg.SendUserMessage(dingdingapi.MsgTyeText, ctx.GetUserID(), "异步任务完成", "京西平台对比数据上传成功:Excel下载地址是 "+downloadURL) - } - } else { - baseapi.SugarLogger.Debug("WriteToExcel:No diff data!!!") - } - //} - endProcessTime := time.Now().Unix() - diff := endProcessTime - startProcessTime - baseapi.SugarLogger.Debugf("CheckSkuDiffBetweenJxAndVendor end time: %v", time.Now()) - baseapi.SugarLogger.Debugf("CheckSkuDiffBetweenJxAndVendor cost time: %d sec", diff) - } - apiover := make(chan int, 1) - compover := make(chan int, 1) - over := false - /********************************第三步****************************/ - /*异步任务*/ - /************************************************************************************/ - go func() { - defer func() { - if recover() != nil { - beego.Info("执行任务失败") - panic("API调用失败") - } - }() - a() - depotDiffData.InitData2() - CompareJxAndMultiVenderDepot(ctx, vendorMap) - apiover <- 0 - }() - /*a等待a现成执行完*/ - go func() { - for !over { - select { - case <-apiover: - /*第二步 为了获取 filterJxDepotUnSaleSkuIds*/ - go func() { - defer func() { - if recover() != nil { - beego.Info("比较任务失败") - panic("比较任务失败") - } - }() - b() - compover <- 0 //比较任务完成 - }() - /*第二步*/ - case <-compover: - go func() { - defer func() { - if recover() != nil { - beego.Info("写入任务失败") - panic("写入任务失败") - } - }() - c(diffData.diffDataMap, depotDiffData.diffDataMap) - fmt.Println("任务执行完成") - over = true - }() - break - } - } - }() - /************************************************************************************/ -} - -//入口函数,校验本地商品京西和其他平台的差异 -func CheckSkuDiffBetweenJxAndVendor(ctx *jxcontext.Context, vendorIDList []int, storeIDList []int) { - startProcessTime := time.Now().Unix() - baseapi.SugarLogger.Debugf("CheckSkuDiffBetweenJxAndVendor start time: %v", time.Now()) - vendorMap := make(map[int]bool) - for _, vendorID := range vendorIDList { - vendorMap[vendorID] = true //map[平台ID:true] - } - storeIDMap := make(map[int]bool) - for _, storeID := range storeIDList { - storeIDMap[storeID] = true //map[门店ID:true] - } - taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - //获取所有多门店平台的商品信息 - //1.循环传进来的平台id,如果是多门店的平台,查询该门店京东到家平台的所有商品 - //2.为multiStoreAllSkuInfoList 和 multiStoreAllSkuInfoMap 赋值 - GetMultiStoreAllSkuInfo(ctx, vendorMap) - case 1: - //对比京西库和多门店平台的库的信息 - depotDiffData.InitData2() - CompareJxAndMultiVenderDepot(ctx, vendorMap) - case 2: - //1.获取京西本地所有门店信息 store、place、user表联查 jxStoreInfoList - //2.过滤所有门店信息,只留下传进来的vendorMap,storeIDMap中对应的平台和门台信息 filterStoreList - //3.判断是否多平台门店,两种情况两种处理 - jxStoreInfoList, err := GetStores(ctx, "", map[string]interface{}{}, 0, -1, utils.DefaultTimeValue, utils.DefaultTimeValue, 0, 0) - if err != nil { - baseapi.SugarLogger.Errorf("CheckSkuDiffBetweenJxAndVendor GetStores error:%v", err) - } else { - filterStoreList := GetFilterStoreList(jxStoreInfoList.Stores, vendorMap, storeIDMap) - diffData.InitData() - //循环门店store - taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - jxStoreInfoListValue := batchItemList[0].(*StoreExt) - storeID := jxStoreInfoListValue.ID - storeIDStr := utils.Int2Str(storeID) - storeName := jxStoreInfoListValue.Name - jxSkuInfoDataSingle := &dao.StoreSkuNamesInfo{} - jxSkuInfoDataMulti := &dao.StoreSkuNamesInfo{} - if jxStoreInfoListValue.StoreMaps != nil { - var multiFlag = false - var singleFlag = false - var filterJxSkuInfoMapSingle map[int]*dao.StoreSkuNameExt - var filterJxSkuInfoMapMulti map[int]*dao.StoreSkuNameExt - for _, vendorListValue := range jxStoreInfoListValue.StoreMaps { - vendorID := vendorListValue.VendorID - if partner.IsMultiStore(vendorID) { - if multiFlag == false { - jxSkuInfoDataMulti, _ = GetStoreSkus(ctx, storeID, filterJxDepotUnSaleSkuIds, true, "", true, false, map[string]interface{}{}, 0, -1) - filterJxSkuInfoMapMulti = GetFilterJxSkuInfoMap(jxSkuInfoDataMulti.SkuNames) //map[京西商品ID:StoreSkuNameExt] - multiFlag = true - } - } else { - if singleFlag == false { - jxSkuInfoDataSingle, _ = GetStoreSkus(ctx, storeID, nil, true, "", true, false, map[string]interface{}{}, 0, -1) - filterJxSkuInfoMapSingle = GetFilterJxSkuInfoMap(jxSkuInfoDataSingle.SkuNames) //map[京西商品ID:StoreSkuNameExt] - singleFlag = true - } - } - - vendorStoreID := vendorListValue.VendorStoreID - baseapi.SugarLogger.Debugf("CheckSkuDiffBetweenJxAndVendor storeID:%d vendorID:%d vendorStoreID:%s vendorListValue:%v", storeID, vendorID, vendorStoreID, vendorListValue) - - if partner.IsMultiStore(vendorID) { - singleStoreHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IPurchasePlatformStoreSkuHandler) - allSkuInfoList := GetMultiStoreAllSkuInfoList(vendorID, vendorListValue.VendorOrgCode) - skuBareInfoList, err := singleStoreHandler.GetStoreSkusBareInfo(ctx, vendorListValue.VendorOrgCode, task, storeID, vendorStoreID, allSkuInfoList) - if err != nil { - baseapi.SugarLogger.Infof("CheckSkuDiffBetweenJxAndVendor GetStoreSkusBareInfo error:%v", err) - } else if len(skuBareInfoList) > 0 { - filterSkuInfoMap := GetFilterMultiStoreSkuInfoMap(vendorID, vendorListValue.VendorOrgCode, skuBareInfoList) //map[京东商品ID:SkuNameInfo] - CompareJxAndVendor(vendorID, storeIDStr, vendorStoreID, storeName, filterJxSkuInfoMapMulti, filterSkuInfoMap, 1) - } - } else { - singleStoreHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreStoreSkuHandler) - vendorSkuInfoList, err := singleStoreHandler.GetStoreSkusFullInfo(ctx, task, storeID, vendorStoreID, nil) - if err != nil { - baseapi.SugarLogger.Infof("CheckSkuDiffBetweenJxAndVendor GetStoreSkusFullInfo error:%v", err) - } else if len(vendorSkuInfoList) > 0 { - filterVendorSkuInfoMap := GetFilterVendorSkuInfoMap(vendorSkuInfoList) //map[平台商品ID:SkuNameInfo] - CompareJxAndVendor(vendorID, storeIDStr, vendorStoreID, storeName, filterJxSkuInfoMapSingle, filterVendorSkuInfoMap, 0) - } - } - } - } - return retVal, err - } - taskParallel := tasksch.NewParallelTask("京西和平台商品差异对比-门店商品对比", tasksch.NewParallelConfig().SetParallelCount(parallelCount), ctx, taskFunc, filterStoreList) - tasksch.HandleTask(taskParallel, task, true).Run() - _, err = taskParallel.GetResult(0) - if err != nil { - baseapi.SugarLogger.Debugf("CheckSkuDiffBetweenJxAndVendor taskParallel error:%v", err) - } - } - case 3: - WriteToExcel(task, diffData.diffDataMap, depotDiffData.diffDataMap) - endProcessTime := time.Now().Unix() - diff := endProcessTime - startProcessTime - baseapi.SugarLogger.Debugf("CheckSkuDiffBetweenJxAndVendor end time: %v", time.Now()) - baseapi.SugarLogger.Debugf("CheckSkuDiffBetweenJxAndVendor cost time: %d sec", diff) - } - return result, err - } - taskSeq := tasksch.NewSeqTask("京西和平台商品差异对比-序列任务", ctx, taskSeqFunc, 4) - tasksch.HandleTask(taskSeq, nil, true).Run() -} - -func IsJXCS() bool { - return globals.IsMainProductEnv() -} - -func AddStatisticSheet(sheetName string, data []DiffData) (sheet *excel.Obj2ExcelSheetConfig) { - statisticData := make([]StatisticData, 9) - var count [9]int - var percent [9]float32 - totalCount := len(data) - for _, rowData := range data { - if rowData.JxSkuName != "" && rowData.VendorSkuName == "" { - if rowData.ToBeCreate == "是" { - if rowData.JxStatus == "下架" { - count[0]++ - } else if rowData.JxStatus == "上架" { - count[1]++ - } - } else if rowData.ToBeCreate == "否" { - if rowData.JxStatus == "下架" { - count[2]++ - } else if rowData.JxStatus == "上架" { - count[3]++ - } - } - } else if rowData.JxSkuName == "" && rowData.VendorSkuName != "" { - if rowData.ToBeCreate == "" && rowData.JxStatus == "" { - count[4]++ - } - } else if rowData.JxSkuName != "" && rowData.VendorSkuName != "" { - if rowData.ToBeCreate == "是" { - if rowData.JxStatus == "下架" { - count[5]++ - } else if rowData.JxStatus == "上架" { - count[6]++ - } - } else if rowData.ToBeCreate == "否" { - if rowData.JxStatus == "下架" { - count[7]++ - } else if rowData.JxStatus == "上架" { - count[8]++ - } - } - } - } - for index, value := range count { - percent[index] = float32(value*100) / float32(totalCount) - countStr := utils.Int2Str(value) - percentStr := fmt.Sprintf("%.2f%%", percent[index]) - subStatisticData := statisticDataList[index] - statisticData[index] = StatisticData{subStatisticData[0], subStatisticData[1], subStatisticData[2], countStr, percentStr} - } - sheetName = sheetName + "统计" - sheet = &excel.Obj2ExcelSheetConfig{ - Title: sheetName, - Data: statisticData, - CaptionList: statisticTitleList, - } - - return sheet -} - -func WriteToExcel(task *tasksch.SeqTask, data map[int][]DiffData, depotData map[int][]DepotDiffData) { - var sheetList []*excel.Obj2ExcelSheetConfig - for key, value := range data { - sheetName := vendorNameList[key] - if partner.IsMultiStore(key) { - excelConfDepot := &excel.Obj2ExcelSheetConfig{ - Title: sheetName + "商品库与京西商品库对比", - Data: depotData[key], - CaptionList: deoptTitleList, - } - sheetList = append(sheetList, excelConfDepot) - } - excelConf := &excel.Obj2ExcelSheetConfig{ - Title: sheetName, - Data: value, - CaptionList: titleList, - } - sheetList = append(sheetList, excelConf) - if needStatistic { - statisticSheet := AddStatisticSheet(sheetName, value) - sheetList = append(sheetList, statisticSheet) - } - baseapi.SugarLogger.Debugf("WriteToExcel:append:%s count:%d", sheetName, len(value)) - } - - if len(sheetList) > 0 { - excelBin := excel.Obj2Excel(sheetList) - sheetList = nil - timeStr := utils.Int64ToStr(time.Now().Unix()) - diffFullFileName := diffFileName[IsJXCS()] + timeStr + fileExt - if canWriteTolocal { - jxutils.WriteFile(diffFullFileName, excelBin) - } - baseapi.SugarLogger.Debugf("WriteToExcel:save %s success", diffFullFileName) - //上传 - downloadURL, err := jxutils.UploadExportContent(excelBin, diffFullFileName) - if err != nil { - baseapi.SugarLogger.Errorf("WriteToExcel:upload %s failed error:%v", diffFullFileName, err) - } else { - noticeMsg := fmt.Sprintf("[详情点我]%s/billshow/?normal=true&path=%s \n", globals.BackstageHost, downloadURL) - task.SetNoticeMsg(noticeMsg) - baseapi.SugarLogger.Debugf("WriteToExcel:upload %s success, downloadURL:%s", diffFullFileName, downloadURL) - } - } else { - baseapi.SugarLogger.Debug("WriteToExcel:No diff data!!!") - } -} - -func SetJxPrice(jxSkuInfoDataMulti *dao.StoreSkuNamesInfo, storeId int, vendorid int) (err error) { - db := dao.GetDB() - storeDetail, err := dao.GetStoreDetail(dao.GetDB(), storeId, vendorid) - if err != nil { - dao.Rollback(db) - return err - } - /*重新计算京西价格*/ - for _, values := range jxSkuInfoDataMulti.SkuNames { - for _, value := range values.Skus { - value.JxPrice = jxutils.CaculatePriceByPricePack(storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage), value.BindPrice) - } - } - /*重新计算京西价格*/ - return nil -} diff --git a/business/jxstore/cms/store_test.go b/business/jxstore/cms/store_test.go deleted file mode 100644 index bb39605e4..000000000 --- a/business/jxstore/cms/store_test.go +++ /dev/null @@ -1,35 +0,0 @@ -package cms - -import ( - "testing" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" -) - -func TestGetStoresVendorSnapshot(t *testing.T) { - result, err := GetStoresVendorSnapshot(jxcontext.AdminCtx, nil, []int{model.VendorIDEBAI}, nil) - if err != nil { - t.Fatal(err) - } - t.Log(utils.Format4Output(result, false)) - t.Log(len(result)) -} - -func TestSendAlarmVendorSnapshot(t *testing.T) { - db := dao.GetDB() - prevSnapshotList, _ := dao.GetVendorStoreSnapshot(db, utils.Str2Time("2019-09-19 11:00:00")) - curSnapshotList, _ := dao.GetVendorStoreSnapshot(db, utils.Str2Time("2019-09-19 15:00:00")) - err := SendAlarmVendorSnapshot(jxcontext.AdminCtx, nil, prevSnapshotList, curSnapshotList) - if err != nil { - t.Fatal(err) - } -} - -func TestUpdateVendorStoreStatusBySnapshot(t *testing.T) { - db := dao.GetDB() - curSnapshotList, _ := dao.GetVendorStoreSnapshot(db, utils.Str2Time("2019-07-30 08:00:00")) - updateVendorStoreStatusBySnapshot(db, curSnapshotList) -} diff --git a/business/jxstore/cms/sync.go b/business/jxstore/cms/sync.go index db3b86369..9212cba25 100644 --- a/business/jxstore/cms/sync.go +++ b/business/jxstore/cms/sync.go @@ -3,28 +3,12 @@ package cms import ( "errors" "fmt" - "strconv" - "strings" "sync" - "time" - "git.rosy.net.cn/baseapi/platformapi/mtpsapi" - - "git.rosy.net.cn/jx-callback/business/partner/putils" - "git.rosy.net.cn/jx-callback/globals/api" - - "git.rosy.net.cn/baseapi" - "git.rosy.net.cn/baseapi/platformapi/dingdingapi" "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/ddmsg" - "git.rosy.net.cn/jx-callback/business/jxutils/excel" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" ) type SyncErrResult struct { @@ -92,646 +76,6 @@ var ( syncErrResultLock SyncErrResultLock ) -// func (p *MultiStoreHandlerWrapper) DeleteCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) (err error) { -// if jxutils.IsEmptyID(cat.JdID) { -// return nil -// } -// return p.IMultipleStoresHandler.DeleteCategory(db, cat, userName) -// } - -// func (p *MultiStoreHandlerWrapper) UpdateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) (err error) { -// if jxutils.IsEmptyID(cat.JdID) { -// globals.SugarLogger.Warnf("UpdateCategory fakeid cat:%s should not get here", utils.Format4Output(cat, true)) -// return nil -// } -// return p.IMultipleStoresHandler.UpdateCategory(db, cat, userName) -// } - -// func (p *MultiStoreHandlerWrapper) DeleteSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) { -// globals.SugarLogger.Debugf("wrapper DeleteSku, sku:%s", utils.Format4Output(sku, false)) -// if jxutils.IsEmptyID(sku.JdID) { -// return nil -// } -// return p.IMultipleStoresHandler.DeleteSku(db, sku, userName) -// } - -// func (p *MultiStoreHandlerWrapper) UpdateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) { -// if jxutils.IsEmptyID(sku.JdID) { -// globals.SugarLogger.Warnf("UpdateSku fakeid sku:%s should not get here", utils.Format4Output(sku, true)) -// return nil -// } -// return p.IMultipleStoresHandler.UpdateSku(db, sku, userName) -// } - -func (v *VendorSync) GetStoreHandler(vendorID int) partner.IPurchasePlatformHandler { - return partner.GetPurchasePlatformFromVendorID(vendorID) -} - -func (v *VendorSync) GetMultiStoreHandler(vendorID int) partner.IMultipleStoresHandler { - if handler, ok := v.GetStoreHandler(vendorID).(partner.IMultipleStoresHandler); ok { - return handler - } - return nil -} - -func (v *VendorSync) GetSingleStoreHandler(vendorID int) partner.ISingleStoreHandler { - if handler, ok := v.GetStoreHandler(vendorID).(partner.ISingleStoreHandler); ok { - return handler - } - return nil -} - -// func (v *VendorSync) syncCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorID int, db *dao.DaoDB, cats []*model.SkuCategory, userName string) (err error) { -// multiStoresHandler := v.GetMultiStoreHandler(vendorID) -// syncStatusFieldName := dao.GetSyncStatusStructField(model.VendorNames[vendorID]) -// task := tasksch.NewParallelTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[vendorID]), nil, ctx, -// func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) { -// cat := batchItemList[0].(*model.SkuCategory) -// updateFields := []string{syncStatusFieldName} -// syncStatus := refutil.GetObjFieldByName(cat, syncStatusFieldName).(int8) -// if (syncStatus & model.SyncFlagDeletedMask) != 0 { //删除 -// if (syncStatus & model.SyncFlagNewMask) == 0 { -// err = multiStoresHandler.DeleteCategory(db, cat, userName) -// } -// } else if (syncStatus & model.SyncFlagNewMask) != 0 { // 新增 -// err = multiStoresHandler.CreateCategory(db, cat, userName) -// updateFields = append(updateFields, dao.GetVendorThingIDStructField(model.VendorNames[multiStoresHandler.GetVendorID()])) -// } else if (syncStatus & model.SyncFlagModifiedMask) != 0 { // 修改 -// err = multiStoresHandler.UpdateCategory(db, cat, userName) -// if intErr, ok := err.(*utils.ErrorWithCode); ok && intErr.IntCode() == -3 { -// err = nil -// } -// } -// if err == nil { -// refutil.SetObjFieldByName(cat, syncStatusFieldName, int8(0)) -// _, err = dao.UpdateEntity(db, cat, updateFields...) -// } -// return nil, err -// }, cats) -// tasksch.HandleTask(task, parentTask, false).Run() -// _, err = task.GetResult(0) -// return err -// } - -func (v *VendorSync) SyncCategory(ctx *jxcontext.Context, db *dao.DaoDB, categoryID int, isAsync bool, userName string) (hint string, err error) { - return SyncCategories(ctx, nil, nil, nil, []int{categoryID}, isAsync) -} - -// func (v *VendorSync) oldSyncCategory(ctx *jxcontext.Context, db *dao.DaoDB, categoryID int, isAsync bool, userName string) (hint string, err error) { -// globals.SugarLogger.Debug("SyncCategory") -// hint, err = v.LoopMultiStoresVendors(ctx, db, fmt.Sprintf("同步分类信息:%d", categoryID), isAsync, false, -// func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) { -// vendorInfo := batchItemList[0].(*MultiStoreVendorInfo) -// var cats []*model.SkuCategory -// cond := make(map[string]interface{}) -// if categoryID > 0 { -// cond[model.FieldID] = categoryID -// } else { -// cond[model.FieldLevel] = 1 -// } -// err := dao.GetEntitiesByKV(db, &cats, cond, true) -// if err == nil { -// err = v.syncCategories(ctx, t, vendorInfo.VendorID, db, cats, userName) -// } -// if err != nil || categoryID > 0 { -// return nil, err -// } -// cond[model.FieldLevel] = 2 -// err = dao.GetEntitiesByKV(db, &cats, cond, true) -// if err == nil { -// err = v.syncCategories(ctx, t, vendorInfo.VendorID, db, cats, userName) -// } -// return nil, err -// }) -// return "", err -// } - -func (v *VendorSync) SyncReorderCategories(ctx *jxcontext.Context, db *dao.DaoDB, categoryID int, isAsync bool, userName string) (hint string, err error) { - return SyncReorderCategories(ctx, categoryID, isAsync) -} - -// func (v *VendorSync) oldSyncReorderCategories(ctx *jxcontext.Context, db *dao.DaoDB, categoryID int, isAsync bool, userName string) (hint string, err error) { -// hint, err = v.LoopMultiStoresVendors(ctx, db, fmt.Sprintf("分类重排序:%d", categoryID), isAsync, false, func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) { -// vendorInfo := batchItemList[0].(*MultiStoreVendorInfo) -// multiStoresHandler := v.GetMultiStoreHandler(vendorInfo.VendorID) -// err2 := multiStoresHandler.ReorderCategories(db, categoryID, userName) -// if err2 == nil { -// cat := &model.SkuCategory{} -// _, err2 = dao.UpdateEntityByKV(db, cat, utils.Params2Map(dao.GetSyncStatusStructField(model.VendorNames[multiStoresHandler.GetVendorID()]), 0), utils.Params2Map(model.FieldParentID, categoryID)) -// return nil, err2 -// } -// return nil, err2 -// }) -// return "", err -// } - -func (v *VendorSync) SyncStore2(ctx *jxcontext.Context, db *dao.DaoDB, vendorIDs, storeIDs []int, mustDirty, isAsync bool) (hint string, err error) { - globals.SugarLogger.Debugf("SyncStore2, storeIDs:%d", storeIDs) - userName := ctx.GetUserName() - isManageIt := len(storeIDs) == 0 || len(storeIDs) > 5 - _, hint, err = v.LoopStoresMap2(ctx, nil, db, fmt.Sprintf("同步门店信息:%v", storeIDs), isAsync, isManageIt, vendorIDs, storeIDs, mustDirty, func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (resultList interface{}, err error) { - loopMapInfo := batchItemList[0].(*LoopStoreMapInfo) - var failedList []*partner.StoreSkuInfoWithErr - handler := v.GetStoreHandler(loopMapInfo.VendorID) - if handler != nil { - if len(loopMapInfo.StoreMapList) > 1 { - loopStoreTask := tasksch.NewParallelTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[loopMapInfo.VendorID]), tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - var resultList []interface{} - var vendorStoreID string - storeMap := batchItemList[0].(*model.StoreMap) - db2 := db - if len(loopMapInfo.StoreMapList) > 1 { - db2 = dao.GetDB() - } - if model.IsSyncStatusNew(storeMap.SyncStatus) { - if vendorStoreID, err = handler.CreateStore2(db2, storeMap.StoreID, userName); err == nil { - resultList = append(resultList, 1) - } else { - failedList = putils.GetErrMsg2FailedSingleList(nil, err, storeMap.StoreID, model.VendorChineseNames[storeMap.VendorID], "创建门店") - } - } else if model.IsSyncStatusDelete(storeMap.SyncStatus) { - if err = handler.DeleteStore(db2, storeMap.StoreID, userName); err == nil { - resultList = append(resultList, 1) - } else { - failedList = putils.GetErrMsg2FailedSingleList(nil, err, storeMap.StoreID, model.VendorChineseNames[storeMap.VendorID], "删除门店") - } - } else { - if err = handler.UpdateStore(db2, storeMap.StoreID, userName); err == nil { - resultList = append(resultList, 1) - } else { - failedList = putils.GetErrMsg2FailedSingleList(nil, err, storeMap.StoreID, model.VendorChineseNames[storeMap.VendorID], "更新门店") - } - } - if err == nil { - if model.IsSyncStatusNew(storeMap.SyncStatus) { - storeMap.VendorStoreID = vendorStoreID - storeMap.SyncStatus = 0 - _, err = dao.UpdateEntity(db, storeMap, "VendorStoreID", model.FieldSyncStatus) - } else { - storeMap.SyncStatus = 0 - _, err = dao.UpdateEntity(db, storeMap, model.FieldSyncStatus) - } - } - return resultList, err - }, loopMapInfo.StoreMapList) - t.AddChild(loopStoreTask).Run() - resultList, err = loopStoreTask.GetResult(0) - } else { - var resultList []interface{} - db2 := db - var vendorStoreID string - storeMap := loopMapInfo.StoreMapList[0] - if model.IsSyncStatusNew(storeMap.SyncStatus) { - if vendorStoreID, err = handler.CreateStore2(db2, storeMap.StoreID, userName); err == nil { - resultList = append(resultList, 1) - } else { - failedList = putils.GetErrMsg2FailedSingleList(nil, err, storeMap.StoreID, model.VendorChineseNames[storeMap.VendorID], "创建门店") - } - } else if model.IsSyncStatusDelete(storeMap.SyncStatus) { - if err = handler.DeleteStore(db2, storeMap.StoreID, userName); err == nil { - resultList = append(resultList, 1) - } else { - failedList = putils.GetErrMsg2FailedSingleList(nil, err, storeMap.StoreID, model.VendorChineseNames[storeMap.VendorID], "删除门店") - } - } else { - if err = handler.UpdateStore(db, storeMap.StoreID, userName); err == nil { - resultList = append(resultList, 1) - } else { - failedList = putils.GetErrMsg2FailedSingleList(nil, err, storeMap.StoreID, model.VendorChineseNames[storeMap.VendorID], "更新门店") - } - } - if err == nil { - resultList = []interface{}{1} - if model.IsSyncStatusNew(storeMap.SyncStatus) { - storeMap.VendorStoreID = vendorStoreID - storeMap.SyncStatus = 0 - _, err = dao.UpdateEntity(db, storeMap, "VendorStoreID", model.FieldSyncStatus) - } else { - storeMap.SyncStatus = 0 - _, err = dao.UpdateEntity(db, storeMap, model.FieldSyncStatus) - } - } - } - err = partner.AddVendorInfo2Err(err, loopMapInfo.VendorID) - } - if len(failedList) > 0 { - t.AddFailedList(failedList) - } - return resultList, err - }, true) - return hint, makeSyncError(err) -} - -func (v *VendorSync) SyncStore(ctx *jxcontext.Context, db *dao.DaoDB, vendorID, storeID int, isAsync bool, userName string) (hint string, err error) { - var vendorIDs []int - if vendorID != -1 { - vendorIDs = []int{ - vendorID, - } - } - return v.SyncStore2(ctx, db, vendorIDs, []int{storeID}, false, isAsync) -} - -func (v *VendorSync) SyncSku(ctx *jxcontext.Context, db *dao.DaoDB, nameID, skuID int, isAsync, isContinueWhenError bool, userName string) (hint string, err error) { - var ( - nameIDs []int - skuIDs []int - ) - if nameID != -1 { - nameIDs = []int{nameID} - } - if skuID != -1 { - skuIDs = []int{skuID} - } - return v.SyncSkus(ctx, db, nameIDs, skuIDs, isAsync, isContinueWhenError, userName) -} - -func (v *VendorSync) SyncSkus(ctx *jxcontext.Context, db *dao.DaoDB, nameIDs []int, skuIDs []int, isAsync, isContinueWhenError bool, userName string) (hint string, err error) { - return SyncSkus(ctx, nil, nil, nil, nameIDs, skuIDs, isAsync) -} - -// func (v *VendorSync) oldSyncSkus(ctx *jxcontext.Context, db *dao.DaoDB, nameIDs []int, skuIDs []int, isAsync, isContinueWhenError bool, userName string) (hint string, err error) { -// globals.SugarLogger.Debugf("SyncSku trackInfo:%s, nameIDs:%v, skuIDs:%v, userName:%s", ctx.GetTrackInfo(), nameIDs, skuIDs, userName) -// isManagedIt := !(len(nameIDs) > 0 && len(nameIDs) <= 2 || len(skuIDs) > 0 && len(skuIDs) < 8) -// return v.LoopMultiStoresVendors(ctx, db, fmt.Sprintf("同步商品信息, nameIDs:%v, skuIDs:%v", nameIDs, skuIDs), isAsync, isManagedIt, -// func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) { -// var resultList []interface{} -// vendorInfo := batchItemList[0].(*MultiStoreVendorInfo) -// multiStoresHandler := v.GetMultiStoreHandler(vendorInfo.VendorID) -// syncStatusFieldName := dao.GetSyncStatusStructField(model.VendorNames[multiStoresHandler.GetVendorID()]) -// dbField := dao.ConvertDBFieldPrefix(model.VendorNames[multiStoresHandler.GetVendorID()]) -// skuMap := make(map[int]bool) -// sql := fmt.Sprintf(` -// SELECT DISTINCT t2.* -// FROM sku t1 -// JOIN sku_name t2 ON t2.id = t1.name_id -// WHERE t1.%s_sync_status <> 0 -// `, dbField) -// sqlParams := []interface{}{} -// if len(nameIDs) > 0 { -// sql += " AND t1.name_id IN (" + dao.GenQuestionMarks(len(nameIDs)) + ")" -// sqlParams = append(sqlParams, nameIDs) -// } -// if len(skuIDs) > 0 { -// sql += " AND t1.id IN(" + dao.GenQuestionMarks(len(skuIDs)) + ")" -// sqlParams = append(sqlParams, skuIDs) - -// } -// for _, v := range skuIDs { -// skuMap[v] = true -// } -// sql += " ORDER BY t2.id" - -// var skuNameList []*model.SkuName -// err := dao.GetRows(db, &skuNameList, sql, sqlParams...) -// if err == nil && len(skuNameList) > 0 { -// // todo 同一skuName下的sku顺序处理的原因是京东SPU特殊类型必须要序列化同步才能正常处理, db可能会有多线程问题 -// task := tasksch.NewParallelTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[vendorInfo.VendorID]), tasksch.NewParallelConfig().SetParallelCount(10).SetIsContinueWhenError(isContinueWhenError), ctx, -// func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) { -// var resultList []interface{} -// skuName := batchItemList[0].(*model.SkuName) -// var skuList []*model.Sku -// if err = dao.GetRows(db, &skuList, fmt.Sprintf(` -// SELECT * -// FROM sku -// WHERE name_id = ? AND %s_sync_status <> 0 -// ORDER BY IF(spec_unit IN('kg', 'L'), 1000, 1) * spec_quality -// `, dbField), skuName.ID); err == nil && len(skuList) > 0 { -// for _, sku := range skuList { -// syncStatus := refutil.GetObjFieldByName(sku, syncStatusFieldName).(int8) -// globals.SugarLogger.Debugf("SyncSku trackInfo2:%s, skuID:%d, syncStatus:%d", ctx.GetTrackInfo(), sku.ID, syncStatus) -// if (len(skuIDs) == 0 || skuMap[sku.ID]) && (syncStatus != 0) { -// updateFields := []string{syncStatusFieldName} -// if syncStatus&model.SyncFlagDeletedMask != 0 { // 删除 -// if syncStatus&model.SyncFlagNewMask == 0 { -// err = multiStoresHandler.DeleteSku(db, sku, userName) -// } -// } else if syncStatus&model.SyncFlagNewMask != 0 { // 新增 -// if err = multiStoresHandler.CreateSku(db, sku, userName); err == nil { -// var tmpStruct struct { -// MaxIndex int -// } -// // todo hard code 得到京东spu中sku的顺序(以方便以后修改销售属性),这个必须要每次重新从数据库取 -// if dao.GetRow(db, &tmpStruct, "SELECT MAX(sku_index) max_index FROM sku WHERE name_id = ? AND jd_id > 0 AND jd_id < 4024012631406 ", sku.NameID) == nil { -// sku.SkuIndex = tmpStruct.MaxIndex + 1 -// updateFields = append(updateFields, "SkuIndex") -// } -// updateFields = append(updateFields, dao.GetVendorThingIDStructField(model.VendorNames[multiStoresHandler.GetVendorID()])) -// } -// } else if syncStatus&model.SyncFlagModifiedMask != 0 { // 修改 -// err = multiStoresHandler.UpdateSku(db, sku, userName) -// } -// if err == nil { -// refutil.SetObjFieldByName(sku, syncStatusFieldName, int8(0)) -// if _, err = dao.UpdateEntity(db, sku, updateFields...); err != nil { -// break -// } else { -// resultList = append(resultList, 1) -// } -// } -// } -// } -// } -// if err == nil { -// refutil.SetObjFieldByName(skuName, syncStatusFieldName, int8(0)) -// _, err = dao.UpdateEntity(db, skuName, syncStatusFieldName) -// } -// return resultList, err -// }, skuNameList) -// t.AddChild(task).Run() -// result, err2 := task.GetResult(0) -// if err = err2; err == nil { -// resultList = append(resultList, result...) -// } -// } -// return resultList, err -// }) -// } - -func (v *VendorSync) SyncStoresCategory(ctx *jxcontext.Context, db *dao.DaoDB, vendorIDs []int, storeIDs []int, isForce, isAsync, isContinueWhenError bool) (hint string, err error) { - globals.SugarLogger.Debug("SyncStoresCategory") - isManageIt := len(storeIDs) != 1 - hint, err = v.LoopStoresMap(ctx, db, fmt.Sprintf("同步门店分类信息:%v", storeIDs), isAsync, isManageIt, vendorIDs, storeIDs, - func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) { - loopMapInfo := batchItemList[0].(*LoopStoreMapInfo) - if handler := v.GetSingleStoreHandler(loopMapInfo.VendorID); handler != nil { - if isForce { - dao.SetStoreCategorySyncStatus(db, loopMapInfo.VendorID, storeIDs, nil, model.SyncFlagModifiedMask) - } - if len(loopMapInfo.StoreMapList) > 1 { - loopStoreTask := tasksch.NewParallelTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[loopMapInfo.VendorID]), - tasksch.NewParallelConfig().SetParallelCount(5).SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeMap := batchItemList[0].(*model.StoreMap) - _, err = SyncStoreCategories(ctx, task, storeMap.VendorID, storeMap.StoreID, storeMap.VendorStoreID, nil, nil, false, isContinueWhenError) - return nil, err - }, loopMapInfo.StoreMapList) - t.AddChild(loopStoreTask).Run() - _, err = loopStoreTask.GetResult(0) - } else { - storeMap := loopMapInfo.StoreMapList[0] - _, err = SyncStoreCategories(ctx, t, storeMap.VendorID, storeMap.StoreID, storeMap.VendorStoreID, nil, nil, false, isContinueWhenError) - } - } - return nil, partner.AddVendorInfo2Err(err, loopMapInfo.VendorID) - }, isContinueWhenError) - return hint, makeSyncError(err) -} - -// -func (v *VendorSync) SyncStoresSkus2(ctx *jxcontext.Context, parentTask tasksch.ITask, causeFlag int, db *dao.DaoDB, vendorIDs []int, storeIDs []int, syncDisabled bool, skuIDs, excludeSkuIDs []int, setSyncStatus int, isAsync, isContinueWhenError bool) (hint string, err error) { - globals.SugarLogger.Debug("SyncStoresSkus2") - isManageIt := len(storeIDs) != 1 || len(skuIDs) == 0 || len(skuIDs) > 8 - task, hint, err := v.LoopStoresMap2(ctx, parentTask, db, fmt.Sprintf("同步门店商品信息:%v", storeIDs), isAsync, isManageIt, vendorIDs, storeIDs, false, - func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) { - loopMapInfo := batchItemList[0].(*LoopStoreMapInfo) - if handler := v.GetStoreHandler(loopMapInfo.VendorID); handler != nil { - parallelCount := 5 - if model.MultiStoresVendorMap[loopMapInfo.VendorID] == 1 { - parallelCount = 2 - } - loopStoreTask := tasksch.NewParallelTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[loopMapInfo.VendorID]), - tasksch.NewParallelConfig().SetParallelCount(parallelCount).SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeMap := batchItemList[0].(*model.StoreMap) - if syncDisabled || storeMap.Status > model.StoreStatusDisabled { - if setSyncStatus != 0 { - dao.SetStoreSkuSyncStatus(db, storeMap.VendorID, []int{storeMap.StoreID}, skuIDs, setSyncStatus) - } - if _, err = SyncStoreSkuNew(ctx, task, causeFlag, storeMap.VendorID, storeMap.StoreID, storeMap.VendorStoreID, nil, skuIDs, excludeSkuIDs, false, isContinueWhenError); err != nil { - globals.SugarLogger.Debugf("SyncStoresSkus2 failed2 store:%d failed with error:%v", storeMap.StoreID, err) - } - } - return nil, err - }, loopMapInfo.StoreMapList) - t.AddChild(loopStoreTask).Run() - _, err = loopStoreTask.GetResult(0) - } - return nil, partner.AddVendorInfo2Err(err, loopMapInfo.VendorID) - }, isContinueWhenError) - if task != nil { - err = makeSyncError(err) - } - return hint, err -} - -func (v *VendorSync) SyncStoresSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, causeFlag int, db *dao.DaoDB, vendorIDs []int, storeIDs []int, skuIDs []int, isForce, isAsync, isContinueWhenError bool) (hint string, err error) { - setSyncStatus := 0 - if isForce { - setSyncStatus = model.SyncFlagStoreSkuModifiedMask - } - return v.SyncStoresSkus2(ctx, parentTask, causeFlag, db, vendorIDs, storeIDs, true, skuIDs, nil, setSyncStatus, isAsync, isContinueWhenError) -} - -func (v *VendorSync) FullSyncStoresSkus(ctx *jxcontext.Context, db *dao.DaoDB, vendorIDs []int, storeIDs []int, syncDisabled bool, excludeSkuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { - globals.SugarLogger.Debug("FullSyncStoresSkus") - hint, err = v.LoopStoresMap(ctx, db, fmt.Sprintf("初始化门店商品信息:%v", storeIDs), isAsync, true, vendorIDs, storeIDs, - func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) { - loopMapInfo := batchItemList[0].(*LoopStoreMapInfo) - if handler := v.GetStoreHandler(loopMapInfo.VendorID); handler != nil { - parallelCount := 5 - if model.MultiStoresVendorMap[loopMapInfo.VendorID] == 1 { - parallelCount = 1 - } - loopStoreTask := tasksch.NewParallelTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[loopMapInfo.VendorID]), - tasksch.NewParallelConfig().SetParallelCount(parallelCount).SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeMap := batchItemList[0].(*model.StoreMap) - if syncDisabled || storeMap.Status > model.StoreStatusDisabled { - if _, err = FullSyncStoreSkuNew(ctx, task, storeMap.VendorID, storeMap.StoreID, storeMap.VendorStoreID, excludeSkuIDs, false, isContinueWhenError); err != nil { - globals.SugarLogger.Debugf("FullSyncStoresSkus failed2 store:%d failed with error:%v", storeMap.StoreID, err) - } - } - return nil, err - }, loopMapInfo.StoreMapList) - t.AddChild(loopStoreTask).Run() - _, err = loopStoreTask.GetResult(0) - } - return nil, partner.AddVendorInfo2Err(err, loopMapInfo.VendorID) - }, isContinueWhenError) - return hint, makeSyncError(err) -} - -func (v *VendorSync) DeleteRemoteStoreSkus(ctx *jxcontext.Context, db *dao.DaoDB, vendorIDs []int, storeIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { - globals.SugarLogger.Debug("DeleteRemoteStoreSkus") - hint, err = v.LoopStoresMap(ctx, db, fmt.Sprintf("删除远程门店商品信息:%v", storeIDs), isAsync, true, vendorIDs, storeIDs, - func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) { - loopMapInfo := batchItemList[0].(*LoopStoreMapInfo) - if len(loopMapInfo.StoreMapList) > 1 { - loopStoreTask := tasksch.NewSeqTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[loopMapInfo.VendorID]), ctx, - func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - storeMap := loopMapInfo.StoreMapList[step] - _, err = ClearRemoteStoreStuffAndSetNew(ctx, task, storeMap.VendorID, storeMap.StoreID, storeMap.VendorStoreID, false, isContinueWhenError) - return nil, err - }, len(loopMapInfo.StoreMapList)) - t.AddChild(loopStoreTask).Run() - _, err = loopStoreTask.GetResult(0) - } else { - _, err = ClearRemoteStoreStuffAndSetNew(ctx, t, loopMapInfo.StoreMapList[0].VendorID, loopMapInfo.StoreMapList[0].StoreID, loopMapInfo.StoreMapList[0].VendorStoreID, false, isContinueWhenError) - } - return nil, partner.AddVendorInfo2Err(err, loopMapInfo.VendorID) - }, isContinueWhenError) - return hint, makeSyncError(err) -} - -// 将平台有,但本地没有的门店商品清除 -// todo,京东到家也应该支持 -func (v *VendorSync) PruneMissingStoreSkus(ctx *jxcontext.Context, vendorIDs []int, storeIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { - globals.SugarLogger.Debug("PruneMissingStoreSkus") - hint, err = v.LoopStoresMap(ctx, dao.GetDB(), fmt.Sprintf("删除远程无关联的门店商品信息:%v", storeIDs), isAsync, true, vendorIDs, storeIDs, - func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) { - loopMapInfo := batchItemList[0].(*LoopStoreMapInfo) - if len(loopMapInfo.StoreMapList) > 1 { - loopStoreTask := tasksch.NewParallelTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[loopMapInfo.VendorID]), - tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetParallelCount(5), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeMap := batchItemList[0].(*model.StoreMap) - _, err = PruneMissingStoreSkus(ctx, task, loopMapInfo.VendorID, storeMap.StoreID, storeMap.VendorStoreID, false, isContinueWhenError) - return nil, err - }, loopMapInfo.StoreMapList) - t.AddChild(loopStoreTask).Run() - _, err = loopStoreTask.GetResult(0) - } else { - _, err = PruneMissingStoreSkus(ctx, t, loopMapInfo.VendorID, loopMapInfo.StoreMapList[0].StoreID, loopMapInfo.StoreMapList[0].VendorStoreID, false, isContinueWhenError) - } - return nil, partner.AddVendorInfo2Err(err, loopMapInfo.VendorID) - }, isContinueWhenError) - return hint, makeSyncError(err) -} - -// 把京西有,平台无且没有待创建标记的商品加上待创建标记 -// todo,京东到家也应该支持 -func (v *VendorSync) AddCreateFlagForJxStoreSku(ctx *jxcontext.Context, vendorIDs []int, storeIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { - globals.SugarLogger.Debug("AddCreateFlagForJxStoreSku") - hint, err = v.LoopStoresMap(ctx, dao.GetDB(), fmt.Sprintf("处理京西有,平台无且没有待创建标记的商品加上待创建标记:%v", storeIDs), isAsync, true, vendorIDs, storeIDs, - func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) { - loopMapInfo := batchItemList[0].(*LoopStoreMapInfo) - if len(loopMapInfo.StoreMapList) > 1 { - loopStoreTask := tasksch.NewParallelTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[loopMapInfo.VendorID]), - tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetParallelCount(5), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeMap := batchItemList[0].(*model.StoreMap) - _, err = AddCreateFlagForJxStoreSku(ctx, task, loopMapInfo.VendorID, storeMap.StoreID, storeMap.VendorStoreID, false, isContinueWhenError) - return nil, err - }, loopMapInfo.StoreMapList) - t.AddChild(loopStoreTask).Run() - _, err = loopStoreTask.GetResult(0) - } else { - _, err = AddCreateFlagForJxStoreSku(ctx, t, loopMapInfo.VendorID, loopMapInfo.StoreMapList[0].StoreID, loopMapInfo.StoreMapList[0].VendorStoreID, false, isContinueWhenError) - } - return nil, partner.AddVendorInfo2Err(err, loopMapInfo.VendorID) - }, isContinueWhenError) - return hint, makeSyncError(err) -} - -func (v *VendorSync) AmendAndPruneStoreStuff(ctx *jxcontext.Context, vendorIDs []int, storeIDs []int, isAsync, isContinueWhenError bool, optType int, isForceUpdate bool) (hint string, err error) { - globals.SugarLogger.Debug("AmendAndPruneStoreStuff") - hint, err = v.LoopStoresMap(ctx, dao.GetDB(), fmt.Sprintf("处理京西平台商家分类与商品差异:%v", storeIDs), isAsync, true, vendorIDs, storeIDs, - func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) { - loopMapInfo := batchItemList[0].(*LoopStoreMapInfo) - if len(loopMapInfo.StoreMapList) > 1 { - loopStoreTask := tasksch.NewParallelTask(fmt.Sprintf("处理平台%s", model.VendorChineseNames[loopMapInfo.VendorID]), - tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError).SetParallelCount(5), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeMap := batchItemList[0].(*model.StoreMap) - _, err = amendAndPruneStoreStuff(ctx, task, loopMapInfo.VendorID, storeMap.StoreID, storeMap.VendorStoreID, false, isContinueWhenError, optType, isForceUpdate) - return nil, err - }, loopMapInfo.StoreMapList) - t.AddChild(loopStoreTask).Run() - _, err = loopStoreTask.GetResult(0) - } else { - _, err = amendAndPruneStoreStuff(ctx, t, loopMapInfo.VendorID, loopMapInfo.StoreMapList[0].StoreID, loopMapInfo.StoreMapList[0].VendorStoreID, false, isContinueWhenError, optType, isForceUpdate) - } - return nil, partner.AddVendorInfo2Err(err, loopMapInfo.VendorID) - }, isContinueWhenError) - return hint, makeSyncError(err) -} - -func (v *VendorSync) LoopStoresMap2(ctx *jxcontext.Context, parentTask tasksch.ITask, db *dao.DaoDB, taskName string, isAsync, isManageIt bool, vendorIDs []int, storeIDs []int, mustDirty bool, handler tasksch.WorkFunc, isContinueWhenError bool) (task tasksch.ITask, hint string, err error) { - var storeMapList []*model.StoreMap - if storeMapList, err = dao.GetStoresMapList2(db, vendorIDs, storeIDs, nil, model.StoreStatusAll, model.StoreIsSyncYes, "", "", mustDirty); err != nil { - return nil, "", err - } - if len(storeMapList) == 0 { - return nil, "", nil - } - vendorStoreMap := make(map[int][]*model.StoreMap) - for _, v := range storeMapList { - vendorStoreMap[v.VendorID] = append(vendorStoreMap[v.VendorID], v) - } - loopInfoList := make([]*LoopStoreMapInfo, len(vendorStoreMap)) - index := 0 - for k, v := range vendorStoreMap { - loopInfoList[index] = &LoopStoreMapInfo{ - VendorID: k, - StoreMapList: v, - } - index++ - } - if len(loopInfoList) == 1 { - taskName = fmt.Sprintf("%s,处理平台%s", taskName, model.VendorChineseNames[loopInfoList[0].VendorID]) - } - // 临时把京东的并发改为2 - task = tasksch.NewParallelTask(taskName, tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, handler, loopInfoList) - if isAsync { - buildSetFinishHook(task, ctx) - } - tasksch.HandleTask(task, parentTask, isManageIt).Run() - if !isAsync { - resultList, err2 := task.GetResult(0) - if len(task.GetFailedList()) > 0 { - err2 = buildErrMsg(task) - err = err2 - } - if err = err2; err == nil { - if len(resultList) == 0 { - hint = "1" // todo 暂时这样 - } else { - hint = jxutils.TaskResult2Hint(resultList) - } - } - } else { - hint = task.GetID() - } - return task, hint, err -} - -func buildSetFinishHook(task tasksch.ITask, ctx *jxcontext.Context) { - task.SetFinishHook(func(task tasksch.ITask) { - var noticeMsg = "您此次的同步任务错误详情返回如下: \n" - if ctx.GetUserName() != "jxadmin" { - if len(task.GetFailedList()) > 10 { - downloadURL, _, _ := WirteToExcelBySyncFailed(task) - noticeMsg += fmt.Sprintf("[详情点我]%s/billshow/?normal=true&path=%s \n", globals.BackstageHost, downloadURL) - } else if len(task.GetFailedList()) > 0 && len(task.GetFailedList()) <= 10 { - if task.GetErr() != nil { - noticeMsg += utils.Format4Output(buildErrMsgJson(task), true) - } - } else { - noticeMsg = "您的同步任务执行完成,没有错误返回。" - } - if authInfo, err := ctx.GetV2AuthInfo(); err == nil { - ddmsg.SendUserMessage(dingdingapi.MsgTyeText, authInfo.UserID, "同步错误返回", noticeMsg) - } else { - globals.SugarLogger.Debugf("同步错误发送钉钉消息失败, authinfo [%v] , [%v]", *authInfo, err) - } - } - // else { - // if len(task.GetFailedList()) > 1 { - // if time.Now().Hour() >= 20 || time.Now().Hour() < 7 { - // downloadURL, _, _ := WirteToExcelBySyncFailed(task) - // user, err := dao.GetUserByID(dao.GetDB(), "mobile", "18160030913") - // noticeMsg += fmt.Sprintf("[详情点我]%s/billshow/?normal=true&path=%s \n", globals.BackstageHost, downloadURL) - // if user != nil && err == nil { - // ddmsg.SendUserMessage(dingdingapi.MsgTyeText, user.UserID, "同步错误返回", noticeMsg) - // } - // } - // } - // } - }) -} - func buildErrMsg(task tasksch.ITask) (err error) { err = fmt.Errorf(utils.Format4Output(buildErrMsgJson(task), true)) return makeSpecSyncError(err) @@ -764,61 +108,6 @@ func buildErrMsgJson(task tasksch.ITask) (resultL []*SyncErrResult) { return resultL } -func (v *VendorSync) LoopStoresMap(ctx *jxcontext.Context, db *dao.DaoDB, taskName string, isAsync, isManageIt bool, vendorIDs []int, storeIDs []int, handler tasksch.WorkFunc, isContinueWhenError bool) (hint string, err error) { - _, hint, err = v.LoopStoresMap2(ctx, nil, db, taskName, isAsync, isManageIt, vendorIDs, storeIDs, false, handler, isContinueWhenError) - return hint, err -} - -func (v *VendorSync) LoopMultiStoresVendors(ctx *jxcontext.Context, db *dao.DaoDB, taskName string, isAsync bool, isManageIt bool, handler tasksch.WorkFunc) (hint string, err error) { - task := tasksch.NewParallelTask(taskName, tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, handler, getMultiStoreVendorInfoList()) - tasksch.HandleTask(task, nil, isManageIt).Run() - if !isAsync { - result, err2 := task.GetResult(0) - if err = err2; err == nil { - hint = utils.Int2Str(len(result)) - } - } else { - hint = task.ID - } - return hint, makeSyncError(err) -} - -// func (v *VendorSync) RefreshAllSkusID(ctx *jxcontext.Context, isAsync bool, vendorIDs []int, storeIDs []int) (hint string, err error) { -// task := tasksch.NewParallelTask("RefreshAllSkusID", nil, ctx, -// func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { -// vendorID := batchItemList[0].(int) -// if handler := v.GetStoreHandler(vendorID); handler != nil { -// if multiHandler, ok := handler.(partner.IMultipleStoresHandler); ok { -// _, err = multiHandler.RefreshAllSkusID(ctx, task, false) -// } else if singleHandler, ok := handler.(partner.ISingleStoreHandler); ok { -// _, err = singleHandler.RefreshStoresAllSkusID(ctx, task, false, storeIDs) -// } -// } -// return nil, err -// }, vendorIDs) -// tasksch.HandleTask(task, nil, true).Run() -// if !isAsync { -// _, err = task.GetResult(0) -// } -// return task.ID, err -// } - -func (v *VendorSync) RefreshAllStoresID(ctx *jxcontext.Context, isAsync bool, vendorIDs []int) (hint string, err error) { - task := tasksch.NewParallelTask("RefreshAllStoresID", nil, ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - vendorID := batchItemList[0].(int) - if handler := v.GetStoreHandler(vendorID); handler != nil { - _, err = handler.RefreshAllStoresID(ctx, task, false) - } - return nil, err - }, vendorIDs) - tasksch.HandleTask(task, nil, true).Run() - if !isAsync { - _, err = task.GetResult(0) - } - return task.ID, err -} - func makeSyncError(err error) (newErr error) { if err != nil { if _, ok := err.(*SyncError); !ok { @@ -848,661 +137,3 @@ func (e *SpecSyncError) Error() string { func (e *SyncError) Error() string { return fmt.Sprintf("本地数据修改成功,但同步失败,请根据错误提示处理!,同步错误信息:%s", e.Original.Error()) } - -func isSyncError(err error) bool { - _, ok := err.(*SyncError) - return ok -} - -func (v *VendorSync) SyncSkuNames(ctx *jxcontext.Context, nameIDs []int, isForce, isAsync, isContinueWhenError bool) (hint string, err error) { - return SyncSkus(ctx, nil, nil, nil, nameIDs, nil, isAsync) -} - -func (v *VendorSync) oldSyncSkuNames(ctx *jxcontext.Context, nameIDs []int, isForce, isAsync, isContinueWhenError bool) (hint string, err error) { - db := dao.GetDB() - if isForce { - dao.SetSkuNameSyncStatus(db, nil, nil, nameIDs, model.SyncFlagModifiedMask) - } - return v.SyncSkus(ctx, db, nameIDs, nil, isAsync, isContinueWhenError, ctx.GetUserName()) -} - -func (v *VendorSync) ChangeStoreSkuSaleStatus(ctx *jxcontext.Context, storeID int, isAsync, isContinueWhenError bool) (err error) { - var ( - storeIDs []int - skuIDs []int - ) - db := dao.GetDB() - storeSkuList, err := dao.GetStoresSkusInfoBySaleTime(db, storeID) - if len(storeSkuList) < 1 || err != nil { - return nil - } - for _, v := range storeSkuList { - storeIDs = append(storeIDs, v.StoreID) - skuIDs = append(skuIDs, v.SkuID) - } - vendorIDs := partner.GetPurchasePlatformVendorIDs() - dao.UpdateStoreSkuBindSyncStatusForSaleStatus(db, vendorIDs, storeID) - v.SyncStoresSkus(ctx, nil, model.SyncFlagSaleMask, db, vendorIDs, storeIDs, skuIDs, false, isAsync, isContinueWhenError) - return err -} - -func GetTimeMixByInt(begin1, end1, begin2, end2 int16) (beginAt, endAt int16) { - if (begin1 > begin2 && begin1 > end2) || (begin2 > end1 && end2 > end1) { - return 0, 0 - } - if begin1 > begin2 { - beginAt = begin1 - if end1 > end2 { - endAt = end2 - } else { - endAt = end1 - } - } else { - beginAt = begin2 - if end1 > end2 { - endAt = end2 - } else { - endAt = end1 - } - } - return beginAt, endAt -} - -func WirteToExcelBySyncFailed(task tasksch.ITask) (downloadURL, fileName string, err error) { - var ( - sheetList1 []*excel.Obj2ExcelSheetConfig - ) - syncErrResultLock.syncErrResult = syncErrResultLock.syncErrResult[0:0] - list := buildErrMsgJson(task) - for _, v := range list { - syncErrResultLock.AppendData(*v) - } - excelConf1 := &excel.Obj2ExcelSheetConfig{ - Title: "同步错误", - Data: syncErrResultLock.syncErrResult, - CaptionList: SyncErrResultTitle, - } - sheetList1 = append(sheetList1, excelConf1) - if excelConf1 != nil { - downloadURL, fileName, err = jxutils.UploadExeclAndPushMsg(sheetList1, time.Now().Format("200601021504")+"同步错误返回") - baseapi.SugarLogger.Debug("WriteToExcel: download is [%v]", downloadURL) - } else { - baseapi.SugarLogger.Debug("WriteToExcel: dataSuccess is nil!") - } - if err != nil { - baseapi.SugarLogger.Errorf("WriteToExcel:upload %s , failed error:%v", fileName, err) - } - return downloadURL, fileName, err -} - -func (d *SyncErrResultLock) AppendData(syncErrResult SyncErrResult) { - d.locker.Lock() - defer d.locker.Unlock() - d.syncErrResult = append(d.syncErrResult, syncErrResult) -} - -func (v *VendorSync) SyncStoreSkusFromYb(ctx *jxcontext.Context, storeIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { - var ( - vendorID = model.VendorIDYB - ) - hint, err = v.LoopStoresMap(ctx, dao.GetDB(), fmt.Sprintf("同步银豹到京西:%v", storeIDs), isAsync, true, []int{vendorID}, storeIDs, - func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) { - loopMapInfo := batchItemList[0].(*LoopStoreMapInfo) - for _, v := range loopMapInfo.StoreMapList { - hint, err = syncStoreSkusFromYb(ctx, v.StoreID, vendorID, v.VendorStoreID, isAsync, isContinueWhenError) - } - return nil, partner.AddVendorInfo2Err(err, loopMapInfo.VendorID) - }, isContinueWhenError) - return hint, err -} - -func syncStoreSkusFromYb(ctx *jxcontext.Context, storeID, vendorID int, vendorStoreID string, isAsync, isContinueWhenError bool) (hint string, err error) { - var ( - db = dao.GetDB() - localSkuMap = make(map[string]*dao.StoreSkuSyncInfo) - vendorSkuMap = make(map[string]*partner.SkuNameInfo) - // skuBindInfosDel []*StoreSkuBindInfo - // skuBindInfosUpt []*StoreSkuBindInfo - addList []*partner.SkuNameInfo - updateList []*partner.SkuNameInfo - deleteList []*dao.StoreSkuSyncInfo - ) - handler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreStoreSkuHandler) - - localSkuList, err := dao.GetStoreSkus2(db, vendorID, storeID, nil, false) - if err != nil { - return "", err - } - for _, v := range localSkuList { - localSkuMap[v.VendorSkuID] = v - } - remoteSkuList, err := handler.GetStoreSkusFullInfo(ctx, nil, storeID, vendorStoreID, nil) - if err != nil { - return "", err - } - for _, v := range remoteSkuList { - if localSkuMap[v.SkuList[0].VendorSkuID] == nil { - if len(v.YbBarCode) > 7 { - addList = append(addList, v) - } - } else { - updateList = append(updateList, v) - } - vendorSkuMap[v.SkuList[0].VendorSkuID] = v - } - for _, v := range localSkuList { - if vendorSkuMap[v.VendorSkuID] == nil { - deleteList = append(deleteList, v) - } - } - fmt.Println("remoteSkuList", len(remoteSkuList)) - fmt.Println("addList", len(addList)) - fmt.Println("updateList", utils.Format4Output(updateList, false)) - fmt.Println("deleteList", utils.Format4Output(deleteList, false)) - // taskSeqFunc := func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - // store, _ := dao.GetStoreDetail(db, storeID, vendorID) - // switch step { - // case 0: - // if len(addList) > 0 { - // taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - // var ( - // v = batchItemList[0].(*partner.SkuNameInfo) - // upc = v.YbBarCode - // ) - // err = AddSkuNameByUpc(ctx, upc, store, v) - // if err != nil { - // task.AddFailedList(putils.GetErrMsg2FailedSingleList(nil, err, storeID, model.VendorChineseNames[vendorID], "根据upc创建京西商品")) - // } - // return retVal, err - // } - // taskParallel := tasksch.NewParallelTask("创建商品", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, taskFunc, addList) - // tasksch.HandleTask(taskParallel, task, true).Run() - // _, err = taskParallel.GetResult(0) - // } - // case 1: - // if len(deleteList) > 0 { - // taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - // var ( - // v = batchItemList[0].(*dao.StoreSkuSyncInfo) - // ) - // skuBindInfo := &StoreSkuBindInfo{ - // NameID: v.NameID, - // IsFocus: -1, - // } - // retVal = []*StoreSkuBindInfo{skuBindInfo} - // return retVal, err - // } - // taskParallel := tasksch.NewParallelTask("删除商品", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, taskFunc, deleteList) - // tasksch.HandleTask(taskParallel, task, true).Run() - // resultDel, _ := taskParallel.GetResult(0) - // for _, v := range resultDel { - // skuBindInfosDel = append(skuBindInfosDel, v.(*StoreSkuBindInfo)) - // } - // _, err = updateStoresSkusWithoutSync(ctx, db, []int{storeID}, skuBindInfosDel, false, false) - // } - // case 2: - // if len(updateList) > 0 { - // taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - // var ( - // v = batchItemList[0].(*partner.SkuNameInfo) - // skuBindInfo = &StoreSkuBindInfo{} - // storeSkus []*dao.StoreSkuExt - // pricePercentagePack []*model.PricePercentageItem - // ) - // sql := ` - // SELECT a.*, c.id name_id - // FROM store_sku_bind a - // JOIN sku b ON a.sku_id = b.id - // JOIN sku_name c ON c.id = b.name_id - // WHERE a.store_id = ? AND a.yb_id = ? AND a.deleted_at = ? - // ` - // sqlParams := []interface{}{storeID, v.SkuList[0].VendorSkuID, utils.DefaultTimeValue} - // err = dao.GetRows(db, &storeSkus, sql, sqlParams) - // if len(storeSkus) > 0 { - // if storeSkus[0].YbPrice != int(v.SkuList[0].VendorPrice) { - // err = jxutils.Strings2Objs(store.PricePercentagePackStr, &pricePercentagePack) - // skuBindInfo.UnitPrice = jxutils.CaculateJxPriceByPricePack(pricePercentagePack, 0, int(v.SkuList[0].VendorPrice)) - // } - // } else { - // return retVal, fmt.Errorf("未查询到门店商品,yb_id [%v]", v.SkuList[0].VendorSkuID) - // } - // if v.SkuList[0].Stock < 1 { - // skuBindInfo.IsSale = model.StoreSkuBindStatusDontSale - // } else { - // skuBindInfo.IsSale = model.StoreSkuBindStatusNormal - // } - // skuBindInfo.NameID = storeSkus[0].NameID - // retVal = []*StoreSkuBindInfo{skuBindInfo} - // return retVal, err - // } - // taskParallel := tasksch.NewParallelTask("更新商品价格和库存", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, taskFunc, updateList) - // tasksch.HandleTask(taskParallel, task, true).Run() - // resultUpt, _ := taskParallel.GetResult(0) - // for _, v := range resultUpt { - // skuBindInfosUpt = append(skuBindInfosUpt, v.(*StoreSkuBindInfo)) - // } - // _, err = updateStoresSkusWithoutSync(ctx, db, []int{storeID}, skuBindInfosUpt, false, false) - // } - // case 3: - // _, err = CurVendorSync.SyncStoresSkus2(jxcontext.AdminCtx, nil, 0, db, []int{0, 1, 3}, nil, false, nil, nil, 0, true, true) - // } - // return result, err - // } - // taskSeq := tasksch.NewSeqTask2("同步银豹商品到京西", ctx, true, taskSeqFunc, 3) - // tasksch.HandleTask(taskSeq, nil, true).Run() - // hint = taskSeq.GetID() - return hint, err -} - -func (v *VendorSync) SyncJdsStoresSkus(ctx *jxcontext.Context, storeIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { - var ( - db = dao.GetDB() - ) - // storeSkus, _ := dao.GetStoresSkusInfo(db, []int{model.JdShopMainStoreID}, nil) - _, hint, err = v.LoopStoresMap2(ctx, nil, db, fmt.Sprintf("同步京东商城门店的可售信息:%v", storeIDs), isAsync, true, []int{model.VendorIDJDShop}, storeIDs, false, - func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (interface{}, error) { - loopMapInfo := batchItemList[0].(*LoopStoreMapInfo) - if handler := v.GetStoreHandler(loopMapInfo.VendorID); handler != nil { - for _, storeMap := range loopMapInfo.StoreMapList { - if storeMap.Status > model.StoreStatusDisabled && storeMap.StoreID != model.JdShopMainStoreID && storeMap.SyncRule != 0 { - err = syncJdsStoresSkus(ctx, db, t, storeMap, isAsync, isContinueWhenError) - } - // err = syncJdsStoreStock(ctx, db, t, storeSkus, storeMap, isAsync, isContinueWhenError) - } - } - return nil, partner.AddVendorInfo2Err(err, loopMapInfo.VendorID) - }, isContinueWhenError) - return hint, err -} - -func syncJdsStoreStock(ctx *jxcontext.Context, db *dao.DaoDB, parentTask tasksch.ITask, storeSkus []*model.StoreSkuBind, storeMap *model.StoreMap, isAsync, isContinueWhenError bool) (err error) { - task := tasksch.NewParallelTask("syncJdsStoreStock", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeSku := batchItemList[0].(*model.StoreSkuBind) - stock := 0 - storeSku2, _ := dao.GetStoresSkusInfo(db, []int{storeMap.StoreID}, []int{storeSku.SkuID}) - if storeSku.JdsID != 0 { - if len(storeSku2) > 0 { - if storeSku2[0].Status == model.StoreSkuBindStatusNormal && storeSku.Status == model.StoreSkuBindStatusNormal { - stock = 9999 - } - if storeMap.VendorStoreID != "" { - err = api.JdShopAPI.UpdateSkuSiteStock(storeSku.JdsID, stock, utils.Str2Int(storeMap.VendorStoreID)) - } - } else { - err = api.JdShopAPI.UpdateSkuSiteStock(storeSku.JdsID, 0, utils.Str2Int(storeMap.VendorStoreID)) - } - } - return retVal, err - }, storeSkus) - tasksch.HandleTask(task, parentTask, true).Run() - _, err = task.GetResult(0) - return err -} - -func SyncJdsStoreStock(ctx *jxcontext.Context, isAsync, isContinueWhenError bool) (err error) { - var ( - db = dao.GetDB() - storeMaps []*model.StoreMap - ) - sql := ` - SELECT * FROM store_map WHERE vendor_id = ? AND vendor_store_id <> '' AND store_id <> ? - ` - sqlParams := []interface{}{ - model.VendorIDJDShop, model.JdShopMainStoreID, - } - err = dao.GetRows(db, &storeMaps, sql, sqlParams) - storeSkus, err := dao.GetStoresSkusInfo(db, []int{model.JdShopMainStoreID}, nil) - if err != nil { - return err - } - task1 := tasksch.NewParallelTask("syncJdsStoreStock1", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, - func(task1 *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeMap := batchItemList[0].(*model.StoreMap) - task2 := tasksch.NewParallelTask("syncJdsStoreStock2", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, - func(task2 *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeSku := batchItemList[0].(*model.StoreSkuBind) - stock := 0 - storeSku2, _ := dao.GetStoresSkusInfo(db, []int{storeMap.StoreID}, []int{storeSku.SkuID}) - if storeSku.JdsID != 0 { - if len(storeSku2) > 0 { - if storeSku2[0].Status == model.StoreSkuBindStatusNormal && storeSku.Status == model.StoreSkuBindStatusNormal { - stock = 9999 - } - if storeMap.VendorStoreID != "" { - err = api.JdShopAPI.UpdateSkuSiteStock(storeSku.JdsID, stock, utils.Str2Int(storeMap.VendorStoreID)) - } - } else { - err = api.JdShopAPI.UpdateSkuSiteStock(storeSku.JdsID, 0, utils.Str2Int(storeMap.VendorStoreID)) - } - } - return retVal, err - }, storeSkus) - tasksch.HandleTask(task2, task1, true).Run() - _, err = task2.GetResult(0) - return retVal, err - }, storeMaps) - tasksch.HandleTask(task1, nil, true).Run() - _, err = task1.GetResult(0) - return err -} - -func syncJdsStoresSkus(ctx *jxcontext.Context, db *dao.DaoDB, parentTask tasksch.ITask, storeMap *model.StoreMap, isAsync, isContinueWhenError bool) (err error) { - globals.SugarLogger.Debugf("syncJdsStoresSkus") - var ( - mainSkusMap = make(map[int][]*dao.StoreSkuSyncInfo) - skusMap = make(map[int][]*dao.StoreSkuSyncInfo) - updateList []*dao.StoreSkuSyncInfo - addList []*dao.StoreSkuSyncInfo - skuBindInfos1 []*StoreSkuBindInfo - skuBindInfos2 []*StoreSkuBindInfo - ) - storeSkusMain, err := dao.GetStoreSkusByNameIDs(db, []int{model.JdShopMainStoreID}, 0) - for _, v := range storeSkusMain { - mainSkusMap[v.NameID] = append(mainSkusMap[v.NameID], v) - } - storeSkus, err := dao.GetStoreSkusByNameIDs(db, []int{storeMap.StoreID}, 0) - for _, v := range storeSkus { - skusMap[v.NameID] = append(skusMap[v.NameID], v) - } - for k, v := range skusMap { - if mainSkusMap[k] != nil { - flag := false - for _, storeSku := range v { - if storeSku.StoreSkuStatus == model.StoreSkuBindStatusNormal { - flag = true - } - } - if !flag { - continue - } - for _, storeSku := range v { - for _, storeSkuMain := range mainSkusMap[k] { - if storeSkuMain.StoreSkuStatus == model.StoreSkuBindStatusNormal && storeSku.StoreSkuStatus == model.StoreSkuBindStatusDontSale && - storeSkuMain.SkuID == storeSku.SkuID { - updateList = append(updateList, storeSkuMain) - } - } - } - } - } - for k, v := range mainSkusMap { - if skusMap[k] == nil { - if storeMap.SyncRule == 2 { - for _, storeSkuMain := range v { - addList = append(addList, storeSkuMain) - } - } - } - } - // fmt.Println("updateList", utils.Format4Output(updateList, false)) - // fmt.Println("addList", utils.Format4Output(addList, false)) - if len(updateList) > 0 { - for _, v := range updateList { - skuBindInfos1 = append(skuBindInfos1, buildStoreSkuBindInfo(db, storeMap.StoreID, v, false)) - } - UpdateStoresSkusByBind(ctx, parentTask, skuBindInfos1, isAsync, isContinueWhenError, false) - } - - if len(addList) > 0 { - for _, v := range addList { - skuBindInfos2 = append(skuBindInfos2, buildStoreSkuBindInfo(db, storeMap.StoreID, v, true)) - } - UpdateStoresSkusByBind(ctx, parentTask, skuBindInfos2, isAsync, isContinueWhenError, false) - } - return err -} - -func buildStoreSkuBindInfo(db *dao.DaoDB, storeID int, storeBind *dao.StoreSkuSyncInfo, isFocus bool) (skuBindInfo *StoreSkuBindInfo) { - skus := []*StoreSkuBindSkuInfo{ - &StoreSkuBindSkuInfo{ - SkuID: storeBind.SkuID, - }, - } - skuBindInfo = &StoreSkuBindInfo{ - StoreID: storeID, - NameID: storeBind.NameID, - } - if isFocus { - skuBindInfo.IsFocus = 1 - } - if storeBind.StoreSkuStatus == model.SkuStatusNormal { - skus[0].IsSale = 1 - } else { - skus[0].IsSale = -1 - } - skuBindInfo.Skus = skus - return skuBindInfo -} - -func SyncSkuExperfixAndWatermark(ctx *jxcontext.Context) (err error) { - var ( - db = dao.GetDB() - ) - skuExinfos, err := dao.GetSkuExinfos(db, nil, []int{model.VendorIDMTWM, model.VendorIDEBAI, model.VendorIDJD, model.VendorIDJDShop}, "", utils.ZeroTimeValue, utils.ZeroTimeValue) - task := tasksch.NewParallelTask("SyncSkuExperfixAndWatermark", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - skuExinfo := batchItemList[0].(*model.SkuExinfoMap) - if utils.Time2Date(time.Now().Add(6*time.Hour)).Sub(skuExinfo.EndAt) > 0 { - skuExinfo.DeletedAt = time.Now() - dao.UpdateEntity(db, skuExinfo, "DeletedAt") - goto setModifiyFlag - } - if utils.Time2Date(time.Now().Add(6*time.Hour)).Sub(skuExinfo.BeginAt) == 0 { - goto setModifiyFlag - } - setModifiyFlag: - { - skus, _ := dao.GetSkus(db, nil, []int{skuExinfo.NameID}, nil, nil, nil) - var skuIDs []int - for _, v := range skus { - skuIDs = append(skuIDs, v.ID) - } - if partner.IsMultiStore(skuExinfo.VendorID) { - for _, v := range skuIDs { - OnUpdateThing(ctx, db, nil, int64(v), model.ThingTypeSku) - } - } else { - if len(skuIDs) > 0 { - SetStoreSkuSyncStatus2(db, nil, []int{skuExinfo.VendorID}, skuIDs, model.SyncFlagModifiedMask) - } - } - } - return retVal, err - }, skuExinfos) - tasksch.HandleTask(task, nil, true).Run() - _, err = task.GetResult(0) - return err -} - -func SetMTPSStatus(ctx *jxcontext.Context, storeId, courierStatus int) { - globals.SugarLogger.Debug("SetMTPSStatus is start ") - globals.SugarLogger.Debug("StoreId", "CourierStatus", storeId, courierStatus) - /*获取美团门店信息*/ - //&& CourierStatus != 0 - if storeId != 0 { - var ShopName string - StoreLists, _ := dao.GetStoreList(nil, []int{storeId}, nil, nil, nil, "") - ShopName = StoreLists[0].Name - StoreInfoList := new(mtpsapi.GetStoreStatusResultAll) - StoreInfoList, _ = api.MtpsAPI.GetStoreStatus(ShopName) - /*通过名字找到了,正常情况*/ - if StoreInfoList != nil && StoreInfoList.DataList != nil { - goto ifExist - } else { - /*如果通过名字找不到,那就先通过ID去找名字*/ - ShopInfo, _ := api.MtpsAPI.GetStoreInfo(storeId) - if ShopInfo != nil { - ShopName = ShopInfo[0].PoiName - if ShopName == "" { - ShopName = StoreLists[0].Name[:len(StoreLists[0].Name)-3] - } - StoreInfoList, _ = api.MtpsAPI.GetStoreStatus(ShopName) - if StoreInfoList != nil && StoreInfoList.DataList != nil { - goto ifExist - } else { - /*如果通过API返回的名字也找不到*/ - goto ifNotExist - } - } else { - StoreCourierList, _ := dao.GetStoreCourierList(dao.GetDB(), []int{storeId}, []int{model.VendorIDMTPS}, model.StoreStatusAll, model.StoreAuditStatusAll) - if len(StoreCourierList) > 0 { - ShopInfo, _ := api.MtpsAPI.GetStoreInfo(utils.Str2Int(StoreCourierList[0].VendorStoreID)) - if ShopInfo != nil { - ShopName = ShopInfo[0].PoiName - StoreInfoList, _ = api.MtpsAPI.GetStoreStatus(ShopName) - if StoreInfoList != nil && StoreInfoList.DataList != nil { - goto ifExist - } else { - /*如果通过API返回的名字也找不到*/ - goto ifNotExist - } - } - } else { - /*如果通过ID找不到,那就直接去判断名字*/ - goto NameProblem - } - } - NameProblem: - { - var NotOpen int - if strings.Contains(StoreLists[0].Name, "不做") || strings.Contains(StoreLists[0].Name, "不想做") { - NotOpen = strings.Index(StoreLists[0].Name, "-") - if strings.Index(StoreLists[0].Name, "-") > 0 { - StoreLists[0].Name = StoreLists[0].Name[:NotOpen-1] - } - NotOpen = strings.Index(StoreLists[0].Name, "不") - if strings.Index(StoreLists[0].Name, "不") > 0 { - StoreLists[0].Name = StoreLists[0].Name[:NotOpen-1] - } - NotOpen = strings.Index(StoreLists[0].Name, "(") - if strings.Index(StoreLists[0].Name, "(") > 0 { - StoreLists[0].Name = StoreLists[0].Name[:NotOpen-1] - } - NotOpen = strings.Index(StoreLists[0].Name, "(") - if strings.Index(StoreLists[0].Name, "(") > 0 { - StoreLists[0].Name = StoreLists[0].Name[:NotOpen-1] - } - NotOpen = strings.Index(StoreLists[0].Name, " ") - if NotOpen > 0 { - StoreLists[0].Name = StoreLists[0].Name[:NotOpen-1] - } - ShopName = StoreLists[0].Name - StoreInfoList, _ = api.MtpsAPI.GetStoreStatus(ShopName) - if StoreInfoList != nil && StoreInfoList.DataList != nil { - goto ifExist - } else { - goto ifNotExist - } - } - } - } - ifNotExist: - { - sl := make(map[string]interface{}) - sl["vendorStatus"] = 0 - globals.SugarLogger.Debug("因为没找到被修改配送状态的VendorStoreID是", ShopName, storeId) - UpdateStoreCourierMap(ctx, nil, storeId, model.VendorIDMTPS, sl, ctx.GetUserName()) - return - } - ifExist: - { - if StoreInfoList.DataList[0].OuterPoiID != "" { - //若存在且名字不为空,就是找到了 - // if StoreInfoList.DataList[0].OpenType != courierStatus ||{ - sl := make(map[string]interface{}) - sl["vendorStoreID"] = StoreInfoList.DataList[0].OuterPoiID - sl["status"] = StoreInfoList.DataList[0].OpenType - sl["vendorStatus"] = StoreInfoList.DataList[0].OpenType - globals.SugarLogger.Debugf("被修改配送状态的VendorStoreID是:%s,名称是:%s,美团状态是:%s,本地状态是:%s", - StoreInfoList.DataList[0].OuterPoiID, StoreInfoList.DataList[0].PoiName, strconv.Itoa(StoreInfoList.DataList[0].OpenType), strconv.Itoa(StoreLists[0].Status)) - UpdateStoreCourierMap(ctx, nil, storeId, model.VendorIDMTPS, sl, ctx.GetUserName()) - // } - } - } - } else { - StoreInfoList, _ := api.MtpsAPI.GetStoreStatusAll() - StoreInfoList2 := make(map[string]string) - for _, store := range StoreInfoList { - for _, data := range store.DataList { - StoreInfoList2[data.OuterPoiID] = data.PoiName - } - } - db := dao.GetDB() - /*比较营业状态*/ - /*把获取的京西状态和名称存一下*/ - StoreCourierList, _ := dao.GetStoreCourierList(db, []int{}, nil, model.StoreStatusAll, model.StoreStatusAll) - /*循环美团*/ - for _, StoreInfoList1 := range StoreInfoList { - for _, StoreInfoList11 := range StoreInfoList1.DataList { - /*循环京西*/ - for _, StoreCourierList1 := range StoreCourierList { - /*只比较美团*/ - if StoreCourierList1.VendorID != model.VendorIDMTPS { - continue - } - /*如果门店ID相同的时候进入判断,一个门店只用判断一次就行*/ - if StoreCourierList1.VendorStoreID == StoreInfoList11.OuterPoiID { - if StoreCourierList1.Status != StoreInfoList11.OpenType { - sl := make(map[string]interface{}) - sl["vendorStoreID"] = StoreInfoList11.OuterPoiID - sl["status"] = StoreInfoList11.OpenType - sl["vendorStatus"] = StoreInfoList11.OpenType - globals.SugarLogger.Debugf("被修改配送状态的VendorStoreID是:%s,名称是:%s,美团状态是:%s,本地状态是:%s", - StoreInfoList11.OuterPoiID, StoreInfoList11.PoiName, strconv.Itoa(StoreInfoList11.OpenType), strconv.Itoa(StoreCourierList1.Status)) - UpdateStoreCourierMap(ctx, nil, StoreCourierList1.StoreID, StoreCourierList1.VendorID, sl, ctx.GetUserName()) - break - } - } - } - } - } - /* 美团配送的门店是否存在,调用美团配送的api(有可能接了),查询京西门店对应的美团配送门店是否存在,若不存在则要在京西这边解绑美团配送门店 - 怎么解绑可以在网页上门店管理那点一下看看调的什么接口,传的什么参数*/ - /*获取所有门店信息*/ - //test: - for _, StoreCourierList1 := range StoreCourierList { - diff := false - StoreLists, _ := dao.GetStoreList(db, []int{StoreCourierList1.StoreID}, nil, nil, nil, "") - if StoreLists == nil { - globals.SugarLogger.Debugf("StoreID为:%s,在store表未找到", StoreCourierList1.StoreID) - continue - } - if StoreCourierList1.VendorID != model.VendorIDMTPS || StoreCourierList1.VendorStoreID == "" { - continue - } - if StoreCourierList1.Status == model.StoreStatusDisabled || StoreCourierList1.Status == model.StoreStatusClosed { - continue - } - /*京西不为空,容错*/ - //if { - /*调用API获取美团的商店信息*/ - MTPSInfo := new(mtpsapi.ShopInfo) - MTPSInfo, _ = api.MtpsAPI.ShopQuery(StoreCourierList1.VendorStoreID) - if MTPSInfo == nil { - globals.SugarLogger.Debug("美团未找到该门店," + StoreLists[0].Name + strconv.Itoa(StoreCourierList1.StoreID) + " 被解绑,关联的ID为:" + StoreCourierList1.VendorStoreID) - diff = true - } - if MTPSInfo != nil && MTPSInfo.ShopName == "" { - MTPSInfo.ShopName = StoreInfoList2[MTPSInfo.ShopID] - } - if MTPSInfo != nil && MTPSInfo.ShopLng != StoreCourierList1.Lng && MTPSInfo.ShopLat == StoreCourierList1.Lat { - /*平台上但是坐标不同,解绑*/ - globals.SugarLogger.Debug("商店与美团配送上的坐标不同," + StoreLists[0].Name + strconv.Itoa(StoreCourierList1.StoreID) + " 被解绑,关联的ID为:" + StoreCourierList1.VendorStoreID) - if _, err := DeleteStoreCourierMap(ctx, db, StoreCourierList1.StoreID, StoreCourierList1.VendorID, ctx.GetUserName()); err != nil { - globals.SugarLogger.Debug(err.Error()) - return - } - diff = true - } - if diff { - if _, err := DeleteStoreCourierMap(ctx, db, StoreCourierList1.StoreID, StoreCourierList1.VendorID, ctx.GetUserName()); err != nil { - globals.SugarLogger.Debug(err.Error()) - return - } - //break test - } - } - } - globals.SugarLogger.Debug("SetMTPSStatus is Complete") -} diff --git a/business/jxstore/cms/sync2.go b/business/jxstore/cms/sync2.go deleted file mode 100644 index 9bbd8aef8..000000000 --- a/business/jxstore/cms/sync2.go +++ /dev/null @@ -1,604 +0,0 @@ -package cms - -import ( - "fmt" - "time" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/baseapi/utils/errlist" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/business/partner/putils" - "git.rosy.net.cn/jx-callback/globals" -) - -type MultiStoreVendorInfo struct { - VendorID int - OrgCode string -} - -func CombineVendorIDAndOrgCode(vendorID int, orgCode string) string { - return fmt.Sprintf("%d-%s", vendorID, orgCode) -} - -func getMultiStoreVendorInfoList() (list []*MultiStoreVendorInfo) { - vendorIDs := partner.GetMultiStoreVendorIDs() - for _, vendorID := range vendorIDs { - orgCodeList := partner.CurAPIManager.GetAppOrgCodeList(vendorID) - for _, v := range orgCodeList { - list = append(list, &MultiStoreVendorInfo{ - VendorID: vendorID, - OrgCode: v, - }) - } - } - return list -} - -func syncCategories(ctx *jxcontext.Context, db *dao.DaoDB, parentTask tasksch.ITask, catList []*dao.SkuStoreCatInfo, isAsync bool) (hint string, err error) { - if len(catList) > 0 { - // todo 按vendorID orgCode合并操作 - task := tasksch.NewParallelTask(fmt.Sprintf("同步分类2:%d", len(catList)), tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - catVendorInfo := batchItemList[0].(*dao.SkuStoreCatInfo) - if catVendorInfo.Level != 1 && catVendorInfo.ParentVendorCatID == "" { - return nil, fmt.Errorf("%d的父目录%d没有同步", catVendorInfo.ID, catVendorInfo.ParentID) - } - if catVendorInfo.MapID == 0 { - return nil, fmt.Errorf("分类:%d的数据异常", catVendorInfo.ID) - } - if multiStoresHandler, ok := partner.GetPurchasePlatformFromVendorID(catVendorInfo.VendorID).(partner.IMultipleStoresHandler); ok { - if model.IsSyncStatusDelete(catVendorInfo.CatSyncStatus) { //删除 - if !dao.IsVendorThingIDEmpty(catVendorInfo.VendorCatID) && - model.IsSyncStatusNeedDelete(catVendorInfo.CatSyncStatus) { - err = multiStoresHandler.DeleteCategory2(ctx, catVendorInfo.VendorOrgCode, catVendorInfo.VendorCatID) - } - } else if model.IsSyncStatusNew(catVendorInfo.CatSyncStatus) { // 新增 - err = multiStoresHandler.CreateCategory2(ctx, catVendorInfo) - } else if model.IsSyncStatusUpdate(catVendorInfo.CatSyncStatus) { // 修改 - err = multiStoresHandler.UpdateCategory2(ctx, catVendorInfo) - } - } else { - err = fmt.Errorf("平台:%d不合法", catVendorInfo.VendorID) - } - if err = OnThingSync(ctx, dao.GetDB(), SkuCategoryVendor2ThingMap(catVendorInfo), err); err == nil { - retVal = []int{1} - } - return retVal, err - }, catList) - tasksch.HandleTask(task, parentTask, len(catList) == 0 || len(catList) > 10).Run() - if isAsync { - hint = task.GetID() - } else { - resultList, err2 := task.GetResult(0) - if err = err2; err == nil { - hint = utils.Int2Str(len(resultList)) - } - } - } - return hint, err -} - -func SyncCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorIDs []int, appOrgCodes []string, catIDs []int, isAsync bool) (hint string, err error) { - globals.SugarLogger.Debugf("SyncCategories vendorIDs:%v, appOrgCodes:%v, catIDs:%v", vendorIDs, appOrgCodes, catIDs) - db := dao.GetDB() - catList, err := dao.GetSkuCategoryWithVendor(db, vendorIDs, appOrgCodes, -1, catIDs, true) - if err == nil && len(catList) > 0 { - // TODO 同一平台不同账号会有影响needSyncParentIDs,暂不处理 - var needSyncParentIDs []int - for _, cat := range catList { - if cat.Level == 2 && cat.ParentVendorCatID == "" && cat.IsExdSpec == model.NO { - needSyncParentIDs = append(needSyncParentIDs, cat.ParentID) - } - } - if len(needSyncParentIDs) > 0 { - task := tasksch.NewSeqTask(fmt.Sprintf("同步分类1:%v", catIDs), ctx, - func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - catList2, err := dao.GetSkuCategoryWithVendor(db, vendorIDs, appOrgCodes, -1, needSyncParentIDs, true) - if err == nil { - _, err = syncCategories(ctx, db, task, catList2, false) - } - case 1: - catList2, err := dao.GetSkuCategoryWithVendor(db, vendorIDs, appOrgCodes, -1, catIDs, true) - if err == nil { - _, err = syncCategories(ctx, db, task, catList2, false) - } - } - return result, err - }, 2) - tasksch.HandleTask(task, parentTask, len(catIDs) == 0 || len(catIDs) > 10).Run() - if isAsync { - hint = task.GetID() - } else { - resultList, err2 := task.GetResult(0) - if err = err2; err == nil { - hint = utils.Int2Str(len(resultList)) - } - } - } else { - hint, err = syncCategories(ctx, db, parentTask, catList, false) - } - } - return hint, err -} - -func SyncSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorIDs []int, appOrgCodes []string, nameIDs, skuIDs []int, isAsync bool) (hint string, err error) { - globals.SugarLogger.Debugf("SyncSkus vendorIDs:%v, appOrgCodes:%v, nameIDs:%v, skuIDs:%v", vendorIDs, appOrgCodes, nameIDs, skuIDs) - db := dao.GetDB() - skuList, err := dao.GetSkusWithVendor(db, vendorIDs, appOrgCodes, nameIDs, skuIDs, true) - if err == nil && len(skuList) > 0 { - // todo 按vendorID orgCode合并操作 - task := tasksch.NewParallelTask(fmt.Sprintf("同步商品:%v,%v", nameIDs, skuIDs), tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - skuVendorInfo := batchItemList[0].(*dao.StoreSkuSyncInfo) - var failedList []*partner.StoreSkuInfoWithErr - if skuVendorInfo.VendorCatID == "" { - return nil, fmt.Errorf("商品:%d的商家分类没有同步", skuVendorInfo.SkuID) - } - if skuVendorInfo.BindID == 0 { - return nil, fmt.Errorf("商品:%d的数据异常", skuVendorInfo.SkuID) - } - if skuVendorInfo.ExdSkuID != "" { - return nil, err - } - if skuVendorInfo.SkuVendorMapCatID != "" { - skuVendorInfo.VendorVendorCatID = utils.Str2Int64(skuVendorInfo.SkuVendorMapCatID) - } - skuVendorInfo.SkuName = jxutils.ComposeSkuNameSync(skuVendorInfo.Prefix, skuVendorInfo.Name, skuVendorInfo.Comment, skuVendorInfo.Unit, skuVendorInfo.SpecQuality, skuVendorInfo.SpecUnit, 0, skuVendorInfo.ExPrefix, skuVendorInfo.ExPrefixBegin, skuVendorInfo.ExPrefixEnd) - skuVendorInfo.SkuNameOrigin = jxutils.ComposeSkuNameOriginal(skuVendorInfo.Prefix, skuVendorInfo.Name, skuVendorInfo.Comment, skuVendorInfo.Unit, skuVendorInfo.SpecQuality, skuVendorInfo.SpecUnit, 0) - if skuVendorInfo.ImgWatermark != "" { - downLoad, _ := uploadImgStandard(skuVendorInfo.ImgWatermark) - skuVendorInfo.ImgMix = jxutils.MixWatermarkImg(downLoad, skuVendorInfo.Img, skuVendorInfo.ExPrefixBegin, skuVendorInfo.ExPrefixEnd) - } - skuVendorInfo.MergedStatus = jxutils.MergeSkuStatus(skuVendorInfo.Status, skuVendorInfo.NameStatus) - if multiStoresHandler, ok := partner.GetPurchasePlatformFromVendorID(skuVendorInfo.VendorID).(partner.IMultipleStoresHandler); ok { - if model.IsSyncStatusDelete(skuVendorInfo.SkuSyncStatus) { //删除 - if !dao.IsVendorThingIDEmpty(skuVendorInfo.VendorSkuID) && - model.IsSyncStatusNeedDelete(skuVendorInfo.SkuSyncStatus) { - err = multiStoresHandler.DeleteSku2(ctx, skuVendorInfo.VendorOrgCode, storeSkuSyncInfo2Bare(skuVendorInfo)) - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(skuVendorInfo, err, 0, model.VendorChineseNames[skuVendorInfo.VendorID], "删除商品") - } - } - } else if model.IsSyncStatusNew(skuVendorInfo.SkuSyncStatus) { // 新增 - err = multiStoresHandler.CreateSku2(ctx, skuVendorInfo) - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(skuVendorInfo, err, 0, model.VendorChineseNames[skuVendorInfo.VendorID], "新增商品") - } - } else if model.IsSyncStatusUpdate(skuVendorInfo.SkuSyncStatus) { // 修改 - err = multiStoresHandler.UpdateSku2(ctx, skuVendorInfo) - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(skuVendorInfo, err, 0, model.VendorChineseNames[skuVendorInfo.VendorID], "修改商品") - } - } - } else { - err = fmt.Errorf("平台:%d不合法", skuVendorInfo.VendorID) - } - if len(failedList) > 0 { - task.AddFailedList(failedList) - } - if err = OnThingSync(ctx, dao.GetDB(), SkuVendor2ThingMap(skuVendorInfo), err); err == nil { - retVal = []int{1} - } - return retVal, err - }, skuList) - if isAsync { - buildSetFinishHook(task, ctx) - } - tasksch.HandleTask(task, parentTask, len(skuList) == 0 || len(skuList) > 10).Run() - if isAsync { - hint = task.GetID() - } else { - resultList, err2 := task.GetResult(0) - if len(task.GetFailedList()) > 0 { - err2 = buildErrMsg(task) - err2 = makeSyncError(err2) - } - if err = err2; err == nil { - hint = utils.Int2Str(len(resultList)) - } - } - } - return hint, err -} - -func SyncReorderCategories(ctx *jxcontext.Context, parentCatID int, isAsync bool) (hint string, err error) { - globals.SugarLogger.Debugf("SyncReorderCategories parentCatID:%d", parentCatID) - db := dao.GetDB() - hint, err = CurVendorSync.LoopMultiStoresVendors(ctx, db, fmt.Sprintf("分类重排序:%d", parentCatID), isAsync, false, - func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - vendorInfo := batchItemList[0].(*MultiStoreVendorInfo) - multiStoresHandler := CurVendorSync.GetMultiStoreHandler(vendorInfo.VendorID) - if multiStoresHandler != nil { - catList, err2 := dao.GetSkuCategoryWithVendor(db, []int{vendorInfo.VendorID}, []string{vendorInfo.OrgCode}, parentCatID, nil, false) - if err = err2; err == nil { - var vendorCatIDList []string - for _, v := range catList { - if v.VendorCatID != "" { - vendorCatIDList = append(vendorCatIDList, v.VendorCatID) - } - } - if len(vendorCatIDList) > 0 { - if err = multiStoresHandler.ReorderCategories2(ctx, vendorInfo.OrgCode, catList[0].ParentVendorCatID, vendorCatIDList); err == nil { - retVal = []int{len(vendorCatIDList)} - } - } - } - } else { - err = fmt.Errorf("非法平台:%d", vendorInfo.VendorID) - } - return retVal, err - }) - return hint, err -} - -func getThingMap(db *dao.DaoDB, thingMap *model.ThingMap) (err error) { - return dao.GetEntity(db, thingMap, "ThingID", "ThingType", "VendorID", "VendorOrgCode", model.FieldDeletedAt) -} - -func OnCreateThing(ctx *jxcontext.Context, db *dao.DaoDB, vendorInfoList []*MultiStoreVendorInfo, thingID int64, thingType int8) (err error) { - if thingType == model.ThingTypeSkuName { - return nil - } - if len(vendorInfoList) == 0 { - vendorInfoList = getMultiStoreVendorInfoList() - } - errList := errlist.New() - for _, v := range vendorInfoList { - thingMap := &model.ThingMap{ - ThingID: thingID, - ThingType: thingType, - VendorID: v.VendorID, - VendorOrgCode: v.OrgCode, - SyncStatus: model.SyncFlagNewMask, - } - dao.WrapAddIDCULDEntity(thingMap, ctx.GetUserName()) - if err2 := dao.CreateEntity(db, thingMap); err2 != nil { - if dao.IsDuplicateError(err2) { - errList.AddErr(onUpdateThing(ctx, db, vendorInfoList, thingID, thingType, model.SyncFlagNewMask)) - } else { - errList.AddErr(err2) - } - } - updateThingMapEntity(db, thingMap) - } - err = errList.GetErrListAsOne() - return err -} - -func onUpdateThing(ctx *jxcontext.Context, db *dao.DaoDB, vendorInfoList []*MultiStoreVendorInfo, thingID int64, thingType int8, syncStatus int8) (err error) { - if thingType == model.ThingTypeSkuName { - return nil - } - if len(vendorInfoList) == 0 { - vendorInfoList = getMultiStoreVendorInfoList() - } - errList := errlist.New() - for _, v := range vendorInfoList { - thingMap := &model.ThingMap{ - ThingID: thingID, - ThingType: thingType, - VendorID: v.VendorID, - VendorOrgCode: v.OrgCode, - } - thingMap.DeletedAt = utils.DefaultTimeValue - if err2 := getThingMap(db, thingMap); err2 == nil { - thingMap.SyncStatus |= syncStatus - thingMap.LastOperator = ctx.GetUserName() - _, err2 = dao.UpdateEntity(db, thingMap) - errList.AddErr(err2) - - updateThingMapEntity(db, thingMap) - } else { - errList.AddErr(err2) - } - } - err = errList.GetErrListAsOne() - return err -} - -func OnUpdateThing(ctx *jxcontext.Context, db *dao.DaoDB, vendorInfoList []*MultiStoreVendorInfo, thingID int64, thingType int8) (err error) { - return onUpdateThing(ctx, db, vendorInfoList, thingID, thingType, model.SyncFlagModifiedMask) -} - -func OnDeleteThing(ctx *jxcontext.Context, db *dao.DaoDB, vendorInfoList []*MultiStoreVendorInfo, thingID int64, thingType int8) (err error) { - if thingType == model.ThingTypeSkuName { - return nil - } - if len(vendorInfoList) == 0 { - vendorInfoList = getMultiStoreVendorInfoList() - } - errList := errlist.New() - for _, v := range vendorInfoList { - thingMap := &model.ThingMap{ - ThingID: thingID, - ThingType: thingType, - VendorID: v.VendorID, - VendorOrgCode: v.OrgCode, - } - thingMap.DeletedAt = utils.DefaultTimeValue - if err2 := getThingMap(db, thingMap); err2 == nil { - if model.IsSyncStatusNew(thingMap.SyncStatus) { - thingMap.SyncStatus = 0 - thingMap.DeletedAt = time.Now() - } else { - thingMap.SyncStatus |= model.SyncFlagDeletedMask - } - thingMap.LastOperator = ctx.GetUserName() - _, err2 = dao.UpdateEntity(db, thingMap) - errList.AddErr(err2) - - updateThingMapEntity(db, thingMap) - } else if !dao.IsNoRowsError(err2) { - errList.AddErr(err2) - } - } - err = errList.GetErrListAsOne() - return err -} - -func SkuCategoryVendor2ThingMap(cat *dao.SkuStoreCatInfo) (thingMap *model.ThingMap) { - thingMap = &model.ThingMap{ - ThingID: int64(cat.ID), - ThingType: model.ThingTypeCategory, - VendorID: cat.VendorID, - VendorOrgCode: cat.VendorOrgCode, - - SyncStatus: cat.CatSyncStatus, - VendorThingID: cat.VendorCatID, - } - thingMap.ID = cat.MapID // 一定要赋值 - return thingMap -} - -func SkuVendor2ThingMap(sku *dao.StoreSkuSyncInfo) (thingMap *model.ThingMap) { - thingMap = &model.ThingMap{ - ThingID: int64(sku.SkuID), - ThingType: model.ThingTypeSku, - VendorID: sku.VendorID, - VendorOrgCode: sku.VendorOrgCode, - - SyncStatus: sku.SkuSyncStatus, - VendorThingID: sku.VendorSkuID, - } - thingMap.DeletedAt = utils.DefaultTimeValue - thingMap.ID = sku.BindID // 一定要赋值 - return thingMap -} - -func OnThingSync(ctx *jxcontext.Context, db *dao.DaoDB, thingMap *model.ThingMap, syncErr error) (err error) { - globals.SugarLogger.Debugf("OnThingSync thingMap:%s", utils.Format4Output(thingMap, true)) - if syncErr != nil { - err = syncErr - thingMap.Remark = utils.LimitUTF8StringLen(err.Error(), 255) - dao.UpdateEntity(db, thingMap, "Remark") - } else { - updateFields := []string{ - model.FieldSyncStatus, - model.FieldUpdatedAt, - model.FieldLastOperator, - "Remark", - } - if model.IsSyncStatusDelete(thingMap.SyncStatus) { //删除 - thingMap.DeletedAt = time.Now() - thingMap.VendorThingID = "" - updateFields = append(updateFields, "VendorThingID", model.FieldDeletedAt) - } else if model.IsSyncStatusNew(thingMap.SyncStatus) { // 新增 - updateFields = append(updateFields, "VendorThingID") - } - thingMap.SyncStatus = 0 - thingMap.LastOperator = ctx.GetUserName() - thingMap.UpdatedAt = time.Now() - thingMap.Remark = "" - _, err = dao.UpdateEntity(db, thingMap, updateFields...) - - updateThingMapEntity(db, thingMap) - } - return err -} - -func updateThingMapEntity(db *dao.DaoDB, thingMap *model.ThingMap) { - // if thingMap.VendorOrgCode == globals.JdOrgCode { - // if thingMap.ThingType == model.ThingTypeCategory { - // cat := &model.SkuCategory{ - // JdID: utils.Str2Int64WithDefault(thingMap.VendorThingID, 0), - // JdSyncStatus: thingMap.SyncStatus, - // } - // cat.ID = int(thingMap.ThingID) - // dao.UpdateEntity(db, cat, "JdID", "JdSyncStatus") - // } else if thingMap.ThingType == model.ThingTypeSku { - // sku := &model.Sku{ - // JdID: utils.Str2Int64WithDefault(thingMap.VendorThingID, 0), - // JdSyncStatus: thingMap.SyncStatus, - // } - // sku.ID = int(thingMap.ThingID) - // dao.UpdateEntity(db, sku, "JdID", "JdSyncStatus") - // } - // } -} - -func amendAndPruneVendorStuff(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorID int, vendorOrgCode string, isAsync, isContinueWhenError bool, opType int, isForceUpdate bool) (hint string, err error) { - handler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IMultipleStoresHandler) - if handler == nil { - return "", fmt.Errorf("平台:%s不支持此操作", model.VendorChineseNames[vendorID]) - } - db := dao.GetDB() - vendorInfo := []*MultiStoreVendorInfo{ - &MultiStoreVendorInfo{ - VendorID: vendorID, - OrgCode: vendorOrgCode, - }, - } - var sku2Delete []*partner.StoreSkuInfo - var cat2Delete []*partner.BareCategoryInfo - task := tasksch.NewParallelTask(fmt.Sprintf("平台:%s,账号:%s上的商品与商家分类", model.VendorChineseNames[vendorID], vendorOrgCode), - tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - step := batchItemList[0].(int) - switch step { - case 0: - localSkuList, err := dao.GetSkusWithVendor(db, []int{vendorID}, []string{vendorOrgCode}, nil, nil, false) - if err != nil { - return nil, err - } - localSkuMap := make(map[string]*dao.StoreSkuSyncInfo) - for _, v := range localSkuList { - if v.VendorSkuID != "" { - localSkuMap[v.VendorSkuID] = v - } - } - - remoteSkuList, err2 := handler.GetSkus(ctx, vendorOrgCode, 0, "") - if err = err2; err == nil { - remoteSkuMap := make(map[string]int) - for _, v := range remoteSkuList { - if vendorSkuID := v.SkuList[0].VendorSkuID; vendorSkuID != "" { - if localSkuMap[vendorSkuID] == nil { - sku2Delete = append(sku2Delete, &partner.StoreSkuInfo{ - SkuID: v.SkuList[0].SkuID, - VendorSkuID: vendorSkuID, - }) - } else { - remoteSkuMap[vendorSkuID] = 1 - } - } else if v.VendorNameID != "" { - sku2Delete = append(sku2Delete, &partner.StoreSkuInfo{ - SkuID: v.NameID, - VendorSkuID: v.VendorNameID, - }) - } - } - - if opType == AmendPruneOnlyAmend || opType == AmendPruneAll { - for _, v := range localSkuList { - if v.ExdSkuID == "" { - if v.BindID != 0 { - if !model.IsSyncStatusDelete(v.SkuSyncStatus) { - if remoteSkuMap[v.VendorSkuID] == 0 { - if !model.IsSyncStatusNew(v.SkuSyncStatus) { - OnCreateThing(ctx, db, vendorInfo, int64(v.SkuID), model.ThingTypeSku) - } - } else if isForceUpdate { - OnUpdateThing(ctx, db, vendorInfo, int64(v.SkuID), model.ThingTypeSku) - } - } - } else { - OnCreateThing(ctx, db, vendorInfo, int64(v.SkuID), model.ThingTypeSku) - } - } - } - } - } - case 1: - if (opType == AmendPruneOnlyPrune || opType == AmendPruneAll) && len(sku2Delete) > 0 { - _, err = putils.FreeBatchStoreSkuInfo("删除商品", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) { - if err = handler.DeleteSku2(ctx, vendorOrgCode, batchedStoreSkuList[0]); err == nil { - successCount = 1 - } - return nil, successCount, err - }, ctx, task, sku2Delete, 1, isContinueWhenError) - } - sku2Delete = nil - case 2: - localCatList, err := dao.GetSkuCategoryWithVendor(db, []int{vendorID}, []string{vendorOrgCode}, -1, nil, false) - if err != nil { - return nil, err - } - localCatMap := make(map[string]*dao.SkuStoreCatInfo) - for _, v := range localCatList { - localCatMap[v.VendorCatID] = v - localCatMap[v.Name] = v - localCatMap[utils.Int2Str(v.ID)] = v - } - - remoteCatList, err2 := handler.GetAllCategories(ctx, vendorOrgCode) - if err = err2; err == nil { - remoteCatMap := make(map[string]int) - cat2Delete = checkRemoteCatExist(remoteCatMap, localCatMap, remoteCatList) - - for _, v := range localCatList { - if v.IsExdSpec == model.NO { - if v.MapID != 0 { - if !model.IsSyncStatusDelete(v.CatSyncStatus) { - if remoteCatMap[v.VendorCatID] == 0 { - if !model.IsSyncStatusNew(v.CatSyncStatus) { - OnCreateThing(ctx, db, vendorInfo, int64(v.ID), model.ThingTypeCategory) - } - } else if isForceUpdate && !model.IsSyncStatusUpdate(v.CatSyncStatus) { - OnUpdateThing(ctx, db, vendorInfo, int64(v.ID), model.ThingTypeCategory) - } - } - } else { - OnCreateThing(ctx, db, vendorInfo, int64(v.ID), model.ThingTypeCategory) - } - } - } - } - case 3: - if (opType == AmendPruneOnlyPrune || opType == AmendPruneAll) && len(cat2Delete) > 0 { - for i := 0; i < 2; i++ { - level := 2 - i - var levelCat2Delete []*partner.BareCategoryInfo - for _, v := range cat2Delete { - if v.Level == level { - levelCat2Delete = append(levelCat2Delete, v) - } - } - if len(levelCat2Delete) > 0 { - task4Delete := tasksch.NewParallelTask(fmt.Sprintf("删除商家分类,level:%d", level), tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - cat := batchItemList[0].(*partner.BareCategoryInfo) - err = handler.DeleteCategory2(ctx, vendorOrgCode, cat.VendorCatID) - return nil, err - }, levelCat2Delete) - tasksch.HandleTask(task4Delete, task, true).Run() - _, err = task4Delete.GetResult(0) - } - } - } - cat2Delete = nil - } - return nil, err - }, []int{0, 1, 2, 3}) - tasksch.HandleTask(task, parentTask, true).Run() - if !isAsync { - _, err = task.GetResult(0) - hint = "1" - } else { - hint = task.ID - } - return hint, err -} - -func FullSyncVendorStuff(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorID int, vendorOrgCode string, isAsync, isContinueWhenError bool) (hint string, err error) { - multiStoreHandler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IMultipleStoresHandler) - if multiStoreHandler == nil { - return "", fmt.Errorf("vendorID:%d不是多门店平台", vendorID) - } - task := tasksch.NewParallelTask("FullSyncStoreSkuNew", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(false), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - step := batchItemList[0].(int) - switch step { - case 0: - _, err = amendAndPruneVendorStuff(ctx, task, vendorID, vendorOrgCode, false, isContinueWhenError, AmendPruneAll, false) - case 1: - _, err = SyncCategories(ctx, task, []int{vendorID}, []string{vendorOrgCode}, nil, false) - case 2: - _, err = SyncSkus(ctx, task, []int{vendorID}, []string{vendorOrgCode}, nil, nil, false) - } - return retVal, err - }, []int{0, 1, 2}) - tasksch.HandleTask(task, parentTask, true).Run() - if !isAsync { - _, err = task.GetResult(0) - } else { - hint = task.GetID() - } - return hint, err -} diff --git a/business/jxstore/cms/sync_store.go b/business/jxstore/cms/sync_store.go deleted file mode 100644 index 5c76fe676..000000000 --- a/business/jxstore/cms/sync_store.go +++ /dev/null @@ -1,59 +0,0 @@ -package cms - -import ( - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" -) - -// 如果京西门为打开,打开状态为非营业的平台门店 -func OpenRemoteStoreByJxStatus(ctx *jxcontext.Context, vendorIDs, storeIDs []int, isForce, isAsync, isContinueWhenError bool) (hint string, err error) { - db := dao.GetDB() - status := model.StoreStatusAll - if !isForce { - status = model.StoreStatusClosed - } - storeMapList, err := dao.GetStoresMapList(db, vendorIDs, storeIDs, nil, status, model.StoreIsSyncYes, "", "") - if err != nil { - return "", err - } - vendorIDMap := make(map[int]int) - if len(vendorIDs) == 0 { - for k := range partner.PurchasePlatformHandlers { - vendorIDMap[k] = 1 - } - } else { - for _, v := range vendorIDs { - vendorIDMap[v] = 1 - } - } - task := tasksch.NewParallelTask("OpenRemoteStoreByJxStatus", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeMap := batchItemList[0].(*model.StoreMap) - if handler, _ := partner.GetPurchasePlatformFromVendorID(storeMap.VendorID).(partner.IStoreHandler); handler != nil { - storeDetail, err := dao.GetStoreDetail(db, storeMap.StoreID, storeMap.VendorID) - if err == nil && storeDetail.Status == model.StoreStatusOpened { - if err = handler.UpdateStoreStatus(ctx, storeMap.VendorOrgCode, storeMap.StoreID, storeMap.VendorStoreID, model.StoreStatusOpened); err == nil { - storeMap.Status = model.StoreStatusOpened - dao.UpdateEntity(db, storeMap, model.FieldStatus) - retVal = []int{1} - } - } - } - return retVal, err - }, storeMapList) - tasksch.HandleTask(task, nil, true).Run() - - if isAsync { - hint = task.GetID() - } else { - resultList, err2 := task.GetResult(0) - if err = err2; err == nil { - hint = utils.Int2Str(len(resultList)) - } - } - return hint, err -} diff --git a/business/jxstore/cms/sync_store_sku.go b/business/jxstore/cms/sync_store_sku.go deleted file mode 100644 index 32c9c8364..000000000 --- a/business/jxstore/cms/sync_store_sku.go +++ /dev/null @@ -1,1445 +0,0 @@ -package cms - -import ( - "errors" - "fmt" - "regexp" - "sort" - "strings" - "time" - - "git.rosy.net.cn/baseapi/platformapi/yinbaoapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - - "git.rosy.net.cn/jx-callback/business/partner/putils" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" - "git.rosy.net.cn/jx-callback/globals/refutil" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" -) - -const ( - AmendPruneOnlyAmend = 1 - AmendPruneOnlyPrune = 2 - AmendPruneAll = 3 -) - -var ( - subSensitiveWordRegexp = regexp.MustCompile(`[^\[\]\"\}]`) - - specailAutoEnableAt = utils.Str2Time("2222-01-01 00:00:00") -) - -func CreateStoreCategoryByStoreSku(ctx *jxcontext.Context, vendorID, storeID int, vendorStoreID string, nameIDs, skuIDs []int) (err error) { - globals.SugarLogger.Debugf("CreateStoreCategoryByStoreSku vendorID:%d, storeID:%d", vendorID, storeID) - db := dao.GetDB() - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - for i := 0; i < 2; i++ { - localCats, err2 := dao.GetSkusCategories(db, vendorID, storeID, skuIDs, i+1) - if err = err2; err != nil { - return err - } - if len(localCats) > 0 { - dao.Begin(db) - for _, v := range localCats { - if v.MapID == 0 { - if err = dao.AddStoreCategoryMap(db, storeID, v.ID, vendorID, "", model.SyncFlagNewMask, ctx.GetUserName()); err != nil { - dao.Rollback(db) - return err - } - } - } - dao.Commit(db) - } - } - return err -} - -func SyncStoreCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorID, storeID int, vendorStoreID string, nameIDs, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { - globals.SugarLogger.Debugf("SyncStoreCategories %s storeID:%d, %s, userName:%s", model.VendorChineseNames[vendorID], storeID, vendorStoreID, ctx.GetUserName()) - handler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreStoreSkuHandler) - num := 0 - db := dao.GetDB() - rootTask := tasksch.NewSeqTask(fmt.Sprintf("%s SyncStoreCategory step1", model.VendorChineseNames[vendorID]), ctx, - func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - level := step + 1 - catList, err := dao.GetDirtyStoreCategories(db, vendorID, storeID, level, skuIDs) - if len(catList) > 0 { - num += len(catList) - task := tasksch.NewParallelTask(fmt.Sprintf("%s SyncStoreCategory step2, level=%d", model.VendorChineseNames[vendorID], level), - tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - updateFields := []string{dao.GetSyncStatusStructField(model.VendorNames[vendorID])} - idFieldName := dao.GetVendorThingIDStructField(model.VendorNames[vendorID]) - catInfo := batchItemList[0].(*dao.SkuStoreCatInfo) - storeCatMap := &model.StoreSkuCategoryMap{} - storeCatMap.ID = catInfo.MapID - var failedList []*partner.StoreSkuInfoWithErr - if catInfo.IsExdSpec == model.YES { - if vendorID != model.VendorIDEBAI { - return nil, err - } - } - if vendorID != model.VendorIDJD && vendorID != model.VendorIDJDShop { - if catInfo.IsSysCat == model.YES && catInfo.StoreCatID != 0 { - catInfo.Name = catInfo.StoreCatName - catInfo.Seq = catInfo.StoreCatSeq - } - } - if model.IsSyncStatusDelete(catInfo.CatSyncStatus) { // 删除 - if model.IsSyncStatusDelete(catInfo.CatSyncStatus) && !dao.IsVendorThingIDEmpty(catInfo.VendorCatID) { - err = handler.DeleteStoreCategory(ctx, storeID, vendorStoreID, catInfo.VendorCatID, level) - if err != nil && handler.IsErrCategoryNotExist(err) { - err = nil - } else if err != nil && !handler.IsErrCategoryNotExist(err) { - failedList = putils.GetErrMsg2FailedSingleList(nil, err, storeID, model.VendorChineseNames[vendorID], "删除分类") - } - } - } else if model.IsSyncStatusNew(catInfo.CatSyncStatus) { // 新增 - err = handler.CreateStoreCategory(ctx, storeID, vendorStoreID, catInfo) - if err != nil && handler.IsErrCategoryExist(err) { - if cat, err2 := handler.GetStoreCategory(ctx, storeID, vendorStoreID, catInfo.Name); err2 == nil { - catInfo.VendorCatID = cat.VendorCatID - err = nil - } - } else if err != nil && !handler.IsErrCategoryExist(err) { - failedList = putils.GetErrMsg2FailedSingleList(nil, err, storeID, model.VendorChineseNames[vendorID], "新增分类") - } - if err == nil { - updateFields = append(updateFields, idFieldName) - // if vendorID == model.VendorIDMTWM { - // storeCatMap.LastOperator = utils.Time2Str(time.Now()) - // updateFields = append(updateFields, model.FieldLastOperator) - // } - } - } else if model.IsSyncStatusUpdate(catInfo.CatSyncStatus) { // 修改 - err = handler.UpdateStoreCategory(ctx, storeID, vendorStoreID, catInfo) - if err == nil { - updateFields = append(updateFields, idFieldName) - } else { - failedList = putils.GetErrMsg2FailedSingleList(nil, err, storeID, model.VendorChineseNames[vendorID], "修改分类") - } - } - if len(failedList) > 0 { - for _, v := range failedList { - v.CategoryName = catInfo.Name - } - task.AddFailedList(failedList) - } - if err == nil { - if vendorID == model.VendorIDMTWM { - refutil.SetObjFieldByName(storeCatMap, idFieldName, catInfo.VendorCatID) - } else { - refutil.SetObjFieldByName(storeCatMap, idFieldName, utils.Str2Int64WithDefault(catInfo.VendorCatID, 0)) - } - _, err = dao.UpdateEntity(db, storeCatMap, updateFields...) - } - return nil, err - }, catList) - rootTask.AddChild(task).Run() - _, err = task.GetResult(0) - } - return nil, err - }, 2) - tasksch.AddChild(parentTask, rootTask).Run() - if !isAsync { - _, err = rootTask.GetResult(0) - } else { - hint = rootTask.GetID() - } - return hint, err -} - -func SyncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, causeFlag int, vendorID, storeID int, vendorStoreID string, nameIDs, skuIDs, excludeSkuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { - return SyncStoreSkuNew2(ctx, parentTask, causeFlag, vendorID, storeID, vendorStoreID, nameIDs, skuIDs, excludeSkuIDs, false, isAsync, isContinueWhenError) -} - -func SyncStoreSkuNew2(ctx *jxcontext.Context, parentTask tasksch.ITask, causeFlag int, vendorID, storeID int, vendorStoreID string, nameIDs, skuIDs, excludeSkuIDs []int, useVendorPriceDirectly, isAsync, isContinueWhenError bool) (hint string, err error) { - singleStoreHandler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreStoreSkuHandler) - if singleStoreHandler != nil { - if err = CreateStoreCategoryByStoreSku(ctx, vendorID, storeID, vendorStoreID, nameIDs, skuIDs); err != nil { - return "", err - } - } - task := tasksch.NewSeqTask(fmt.Sprintf("SyncStoreSkuNew, storeID:%d", storeID), ctx, - func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - if singleStoreHandler != nil { - _, err = SyncStoreCategories(ctx, task, vendorID, storeID, vendorStoreID, nameIDs, skuIDs, false, isContinueWhenError) - } - case 1: - err = syncStoreSkuNew(ctx, task, causeFlag, false, vendorID, storeID, nameIDs, skuIDs, excludeSkuIDs, useVendorPriceDirectly, isContinueWhenError) - } - return result, err - }, 2) - tasksch.HandleTask(task, parentTask, true).Run() - if !isAsync { - _, err = task.GetResult(0) - } else { - hint = task.GetID() - } - return hint, err -} - -func FullSyncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorID, storeID int, vendorStoreID string, excludeSkuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { - singleStoreHandler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreStoreSkuHandler) - task := tasksch.NewParallelTask("FullSyncStoreSkuNew", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - step := batchItemList[0].(int) - switch step { - case 0: - if singleStoreHandler != nil { - // _, err = ClearRemoteStoreStuffAndSetNew(ctx, task, vendorID, storeID, vendorStoreID, false, isContinueWhenError) - _, err = amendAndPruneStoreStuff(ctx, parentTask, vendorID, storeID, vendorStoreID, false, isContinueWhenError, AmendPruneAll, true) - } else { - _, err = dao.SetStoreSkuSyncStatus(dao.GetDB(), vendorID, []int{storeID}, nil, model.SyncFlagStoreSkuOnlyMask) - } - case 1: - if singleStoreHandler != nil { - _, err = SyncStoreSkuNew(ctx, task, 0, vendorID, storeID, vendorStoreID, nil, nil, excludeSkuIDs, false, isContinueWhenError) - } else { - err = syncStoreSkuNew(ctx, task, 0, true, vendorID, storeID, nil, nil, excludeSkuIDs, false, isContinueWhenError) - } - } - return retVal, err - }, []int{0, 1}) - tasksch.HandleTask(task, parentTask, true).Run() - if !isAsync { - _, err = task.GetResult(0) - } else { - hint = task.GetID() - } - return hint, err -} - -func isStoreSkuSyncNeedDelete(storeSku *dao.StoreSkuSyncInfo) bool { - if model.IsSyncStatusDelete(storeSku.SkuSyncStatus) || - storeSku.BindDeletedAt != utils.DefaultTimeValue || storeSku.BindID == 0 || - storeSku.NameID == 0 || storeSku.NameStatus != model.SkuStatusNormal { - return true - } - // if storeSku.Status != model.SkuStatusNormal { - // storeSku.IsDeletedBySku = true - // return true - // } - return false -} - -func storeSkuSyncInfo2Bare(inSku *dao.StoreSkuSyncInfo) (outSku *partner.StoreSkuInfo) { - outSku = &partner.StoreSkuInfo{ - SkuID: inSku.SkuID, - VendorSkuID: inSku.VendorSkuID, - NameID: inSku.NameID, - VendorNameID: inSku.VendorNameID, - - Status: inSku.MergedStatus, - VendorPrice: inSku.VendorPrice, - Seq: inSku.Seq, - JxPrice: inSku.Price, - JxUnitPrice: inSku.UnitPrice, - VendorSkuID2: utils.Int64ToStr(inSku.JdsWareID), - JdsStockSwitch: inSku.JdsStockSwitch, - IsDeletedBySku: inSku.IsDeletedBySku, - Stock: inSku.Stock, - } - // if !isStoreSkuSyncNeedDelete(inSku) { - // outSku.Stock = model.MaxStoreSkuStockQty - // } - return outSku -} - -func calVendorPrice4StoreSku(inSku *dao.StoreSkuSyncInfo, pricePercentagePack model.PricePercentagePack, pricePercentage int) (outSku *dao.StoreSkuSyncInfo) { - if inSku.VendorPrice <= 0 { // 避免重新计算 - inSku.VendorPrice = int64(jxutils.CaculatePriceByPricePack(pricePercentagePack, pricePercentage, int(inSku.Price))) - if inSku.VendorPrice <= 0 { - inSku.VendorPrice = 1 // 最少1分钱 - } - } - return inSku -} - -func getSkuBoxFee(vendorID int) (boxFee int64) { - if vendorID == model.VendorIDMTWM { - boxFee, _ = dao.GetSysConfigAsInt64(dao.GetDB(), model.ConfigSysMtwmSkuBoxFee) - } - return boxFee -} - -func formalizeStoreSkuListForJds(inSkuList []*dao.StoreSkuSyncInfo) []*dao.StoreSkuSyncInfo { - if len(inSkuList) > 0 { - for _, skuItem := range inSkuList { - skuItem.SkuName = jxutils.ComposeSkuNameSync2(skuItem.Prefix, skuItem.Name, skuItem.Comment, skuItem.Unit, skuItem.SpecQuality, skuItem.SpecUnit, 0, skuItem.ExPrefix, skuItem.ExPrefixBegin, skuItem.ExPrefixEnd) - } - } - return inSkuList -} - -func formalizeStoreSkuList(inSkuList []*dao.StoreSkuSyncInfo) []*dao.StoreSkuSyncInfo { - if len(inSkuList) > 0 { - boxFee := getSkuBoxFee(inSkuList[0].VendorID) - for _, skuItem := range inSkuList { - if skuItem.VendorPrice > skuItem.BoxFee { - skuItem.BoxFee = boxFee - } - //如果商品上绑定了映射,就用商品上的 - if skuItem.SkuVendorMapCatID != "" { - skuItem.VendorVendorCatID = utils.Str2Int64(skuItem.SkuVendorMapCatID) - } - skuItem.MergedStatus = jxutils.MergeSkuStatus(jxutils.MergeSkuStatus(skuItem.NameStatus, skuItem.Status), skuItem.StoreSkuStatus) - skuItem.SkuName = jxutils.ComposeSkuNameSync(skuItem.Prefix, skuItem.Name, skuItem.Comment, skuItem.Unit, skuItem.SpecQuality, skuItem.SpecUnit, 0, skuItem.ExPrefix, skuItem.ExPrefixBegin, skuItem.ExPrefixEnd) - skuItem.SkuNameOrigin = jxutils.ComposeSkuNameOriginal(skuItem.Prefix, skuItem.Name, skuItem.Comment, skuItem.Unit, skuItem.SpecQuality, skuItem.SpecUnit, 0) - if skuItem.ImgWatermark != "" && model.IsSyncStatusUpdate(skuItem.SkuSyncStatus) && skuItem.VendorID != model.VendorIDJD { - if utils.Time2Date(time.Now().Add(6*time.Hour)).Sub(*skuItem.ExPrefixBegin) == 0 { - // if utils.Time2Date(time.Now().Add(6*time.Hour)).Sub(*skuItem.ExPrefixBegin) >= 0 && utils.Time2Date(time.Now()).Sub(*skuItem.ExPrefixEnd) <= 0 { - // downLoad, _ := uploadImgStandard(skuItem.ImgWatermark) - skuItem.ImgMix = jxutils.MixWatermarkImg(skuItem.ImgWatermark, skuItem.ImgOrigin, skuItem.ExPrefixBegin, skuItem.ExPrefixEnd) - } - if utils.Time2Date(time.Now().Add(6*time.Hour)).Sub(*skuItem.ExPrefixEnd) > 0 { - skuItem.ImgMix = "" - } - } - } - } - return inSkuList -} - -func sku2Update(vendorID int, sku *dao.StoreSkuSyncInfo, syncStatus int8) (item *dao.KVUpdateItem) { - kvs := map[string]interface{}{} - if !isSkuLockTimeValid(sku) { - kvs[dao.GetVendorLockTimeStructField(model.VendorNames[vendorID])] = nil - } - if syncStatus&(model.SyncFlagDeletedMask|model.SyncFlagNewMask|model.SyncFlagModifiedMask) != 0 { - if model.IsSyncStatusNew(syncStatus) { - sku.SkuSyncStatus = 0 - kvs[dao.GetVendorThingIDStructField(model.VendorNames[vendorID])] = utils.Str2Int64WithDefault(sku.VendorSkuID, 0) - } else if model.IsSyncStatusDelete(syncStatus) { - sku.SkuSyncStatus = 0 - if utils.IsTimeZero(sku.BindDeletedAt) && (sku.NameID == 0) { - kvs[model.FieldDeletedAt] = time.Now() - } - if !dao.IsVendorThingIDEmpty(sku.VendorSkuID) && !partner.IsMultiStore(vendorID) { - kvs[dao.GetVendorThingIDStructField(model.VendorNames[vendorID])] = 0 - } - } else { - sku.SkuSyncStatus = sku.SkuSyncStatus & model.SyncFlagPriceMask - } - } else if syncStatus&model.SyncFlagStockMask != 0 { - if isStoreSkuSyncNeedDelete(sku) { - sku.SkuSyncStatus = 0 - } else { - sku.SkuSyncStatus = sku.SkuSyncStatus & (model.SyncFlagPriceMask | model.SyncFlagSaleMask) - } - } else { - sku.SkuSyncStatus = sku.SkuSyncStatus & ^syncStatus - } - kvs[dao.GetSyncStatusStructField(model.VendorNames[vendorID])] = sku.SkuSyncStatus - if sku.VendorPrice > 0 { - kvs[dao.GetVendorPriceStructField(model.VendorNames[vendorID])] = sku.VendorPrice - } - storeSku := &model.StoreSkuBind{} - storeSku.ID = sku.BindID - item = &dao.KVUpdateItem{ - Item: storeSku, - KVs: kvs, - } - return item -} - -func updateStoreSku(db *dao.DaoDB, vendorID int, storeSkuList []*dao.StoreSkuSyncInfo, syncStatus int8) (num int64, err error) { - if len(storeSkuList) > 0 { - // defer func() { - // if r := recover(); r != nil { - // globals.SugarLogger.Debugf("updateStoreSku panic, vendorID:%d, len:%d, storeID0:%d, skuID0:%d, syncStatus:%d", vendorID, len(storeSkuList), storeSkuList[0].StoreID, storeSkuList[0].SkuID, syncStatus) - // panic(r) - // } - // }() - if vendorID == model.VendorIDJDShop { - if syncStatus != model.SyncFlagPriceMask && syncStatus != model.SyncFlagSaleMask { - for _, v := range storeSkuList { - updateItemList := make([]*dao.KVUpdateItem, len(v.StoreSkuSyncInfoJds)) - for k, vv := range v.StoreSkuSyncInfoJds { - updateItemList[k] = sku2Update(vendorID, vv, syncStatus) - err = updateJdsWareID(db, vv) - } - num, err = dao.BatchUpdateEntityByKV(db, updateItemList) - } - } else { - updateItemList := make([]*dao.KVUpdateItem, len(storeSkuList)) - for k, v := range storeSkuList { - updateItemList[k] = sku2Update(vendorID, v, syncStatus) - } - num, err = dao.BatchUpdateEntityByKV(db, updateItemList) - } - } else { - updateItemList := make([]*dao.KVUpdateItem, len(storeSkuList)) - for k, v := range storeSkuList { - updateItemList[k] = sku2Update(vendorID, v, syncStatus) - } - num, err = dao.BatchUpdateEntityByKV(db, updateItemList) - if vendorID == model.VendorIDYB { - err = updateYbOhterSku(db, storeSkuList) - } - } - } - return num, err -} - -func updateJdsWareID(db *dao.DaoDB, storeSku *dao.StoreSkuSyncInfo) (err error) { - return dao.UpdateJdsWareID(db, storeSku) -} - -func updateYbOhterSku(db *dao.DaoDB, storeSkuList []*dao.StoreSkuSyncInfo) (err error) { - for _, v := range storeSkuList { - err = dao.UpdateYbOtherSku(db, v) - } - return err -} - -func isSkuLockTimeValid(sku *dao.StoreSkuSyncInfo) bool { - return sku.LockTime != nil && time.Now().Sub(*sku.LockTime) < 0 -} - -func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, causeFlag int, isFull bool, vendorID, storeID int, nameIDs, skuIDs, excludeSkuIDs []int, useVendorPriceDirectly, isContinueWhenError bool) (err error) { - globals.SugarLogger.Debugf("syncStoreSkuNew causeFlag:%d", causeFlag) - db := dao.GetDB() - storeDetail, err := dao.GetStoreDetail(db, storeID, vendorID) - if err != nil { - return err - } - vendorStoreID := storeDetail.VendorStoreID - var skus []*dao.StoreSkuSyncInfo - if isFull { - skus, err = dao.GetFullStoreSkus(db, vendorID, storeID) - } else { - skus, err = dao.GetStoreSkus(db, vendorID, storeID, skuIDs) - } - if err != nil || len(skus) == 0 { - return err - } - if len(excludeSkuIDs) > 0 { - excludeSkuMap := jxutils.IntList2Map(excludeSkuIDs) - var skus2 []*dao.StoreSkuSyncInfo - for _, v := range skus { - if excludeSkuMap[v.SkuID] == 0 { - skus2 = append(skus2, v) - } - } - skus = skus2 - } - formalizeStoreSkuList(skus) - //京东商城的商品名规则不同 - // name,空格,comment,约xxg - // if vendorID == model.VendorIDJDShop { - // formalizeStoreSkuListForJds(skus) - // } - singleStoreHandler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreStoreSkuHandler) - storeSkuHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IPurchasePlatformStoreSkuHandler) - reorderHandler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IStoreSkuSorter) - - var ( - createList, updateList []*dao.StoreSkuSyncInfo - deleteList, stockList, onlineList, offlineList, priceList []*partner.StoreSkuInfo - updateItems []*dao.KVUpdateItem - reorderSkuMap map[string][]*dao.StoreSkuSyncInfo - ) - skuMap := make(map[*partner.StoreSkuInfo]*dao.StoreSkuSyncInfo) - if reorderHandler != nil { - reorderSkuMap = make(map[string][]*dao.StoreSkuSyncInfo) - } - now := jxutils.OperationTime2HourMinuteFormat(time.Now()) - var failedList []*partner.StoreSkuInfoWithErr - for _, sku := range skus { - if vendorID == model.VendorIDJDShop && storeID != model.JdShopMainStoreID { - return - } - if !useVendorPriceDirectly && - !isSkuLockTimeValid(sku) { - sku.VendorPrice = 0 - } - sku.MergedStatus = MergeSkuSaleStatusWithStoreOpTime(sku, storeDetail, now) - if vendorID == model.VendorIDMTWM && storeDetail.Status != model.StoreStatusOpened && storeDetail.AutoEnableAt != nil && storeDetail.AutoEnableAt.Sub(specailAutoEnableAt) == 0 && sku.MergedStatus == model.SkuStatusNormal { - sku.MergedStatus = model.SkuStatusDontSale - } - var bareSku *partner.StoreSkuInfo - isNeedReorder := false - if isStoreSkuSyncNeedDelete(sku) { - if !dao.IsVendorThingIDEmpty(sku.VendorSkuID) { - bareSku = storeSkuSyncInfo2Bare(sku) - if singleStoreHandler == nil { - bareSku.Stock = 0 - stockList = append(stockList, bareSku) - } else { - deleteList = append(deleteList, bareSku) - } - } else { - updateItems = append(updateItems, sku2Update(vendorID, sku, model.SyncFlagDeletedMask)) - } - } else if model.IsSyncStatusNew(sku.SkuSyncStatus) { - calVendorPrice4StoreSku(sku, storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage)) - if singleStoreHandler == nil { - if dao.IsVendorThingIDEmpty(sku.VendorSkuID) { - // todo 多平台商品库没有正常创建,直接跳过 - } else { - sku.SkuSyncStatus |= model.SyncFlagSaleMask | model.SyncFlagPriceMask - bareSku = storeSkuSyncInfo2Bare(sku) - stockList = append(stockList, bareSku) - priceList = append(priceList, bareSku) - if sku.MergedStatus == model.SkuStatusNormal { - onlineList = append(onlineList, bareSku) - } else { - offlineList = append(offlineList, bareSku) - } - } - } else { - if sku.MergedStatus == model.SkuStatusNormal { - if dao.IsVendorThingIDEmpty(sku.VendorCatID) && !strings.Contains(sku.StoreName, model.ExdStoreName) && vendorID != model.VendorIDYB && vendorID != model.VendorIDJDShop { - // globals.SugarLogger.Warnf("syncStoreSkuNew 创建门店:%d商品:%d,但没有平台分类ID", storeID, sku.SkuID) - } else if dao.IsVendorThingIDEmpty(utils.Int64ToStr(sku.VendorVendorCatID)) && vendorID == model.VendorIDJDShop { - // globals.SugarLogger.Warnf("syncStoreSkuNew 创建门店:%d商品:%d,但没有映射的平台ID", storeID, sku.SkuID) - } else { - createList = append(createList, sku) - } - } - } - isNeedReorder = true - } else { - if dao.IsVendorThingIDEmpty(sku.VendorSkuID) && vendorID != model.VendorIDJDShop { - // err = fmt.Errorf("门店:%d,修改没有创建的商品:%d", storeID, sku.SkuID) - if vendorID != model.VendorIDJDShop || (vendorID == model.VendorIDJDShop && storeID == model.JdShopMainStoreID && sku.StoreSkuStatus != model.SkuStatusDontSale) { - err = utils.NewErrorCode(fmt.Sprintf("门店:%d,修改没有创建的商品:%d", storeID, sku.SkuID), "-1", 0) - failedList = putils.GetErrMsg2FailedSingleList(nil, err, storeID, model.VendorChineseNames[vendorID], "异常同步错误") - if parentTask == nil { - return err - } - parentTask.AddBatchErr(err) - parentTask.AddFailedList(failedList) - } - } else { - isAdded2Update := false - // 修改商品信息时不改价(以免活动引起的失败),而用单独的改价来改 - if (model.IsSyncStatusUpdate(sku.SkuSyncStatus) || (model.IsSyncStatusSeq(sku.SkuSyncStatus) && reorderHandler == nil)) && singleStoreHandler != nil { - if dao.IsVendorThingIDEmpty(sku.VendorCatID) && !strings.Contains(sku.StoreName, model.ExdStoreName) && vendorID != model.VendorIDYB && vendorID != model.VendorIDJDShop { - // globals.SugarLogger.Warnf("syncStoreSkuNew 修改门店:%d商品:%d,但没有平台分类ID", storeID, sku.SkuID) - } else { - isAdded2Update = true - updateList = append(updateList, calVendorPrice4StoreSku(sku, storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage))) - } - } - if model.IsSyncStatusPrice(sku.SkuSyncStatus) { - bareSku = storeSkuSyncInfo2Bare(calVendorPrice4StoreSku(sku, storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage))) - priceList = append(priceList, bareSku) - } - if !isAdded2Update { - if model.IsSyncStatusUpdate(sku.SkuSyncStatus) && singleStoreHandler == nil { // 正常就不应该进到这里 - if bareSku == nil { - bareSku = storeSkuSyncInfo2Bare(sku) - } - updateItems = append(updateItems, sku2Update(vendorID, sku, model.SyncFlagStockMask)) - } - if model.IsSyncStatusSale(sku.SkuSyncStatus) { - if bareSku == nil { - bareSku = storeSkuSyncInfo2Bare(sku) - } - if sku.MergedStatus == model.SkuStatusNormal { - onlineList = append(onlineList, bareSku) - // stockList = append(stockList, bareSku) - } else { - offlineList = append(offlineList, bareSku) - // 因为京东平台以是否有库存表示是否关注,所以不论是否可售,都要设置库存 - // if singleStoreHandler == nil { - // stockList = append(stockList, bareSku) - // } - } - } - if model.IsSyncStatusStock(sku.SkuSyncStatus) { - if bareSku == nil { - bareSku = storeSkuSyncInfo2Bare(sku) - } - stockList = append(stockList, bareSku) - } - } - isNeedReorder = model.IsSyncStatusSeq(sku.SkuSyncStatus) - } - } - if isNeedReorder && reorderHandler != nil && sku.VendorCatID != "" { - reorderSkuMap[sku.VendorCatID] = append(reorderSkuMap[sku.VendorCatID], sku) - } - if bareSku != nil { - skuMap[bareSku] = sku - } - } - if _, err = dao.BatchUpdateEntityByKV(db, updateItems); err != nil { - return err - } - bareSku2Sync := func(bareSkuList []*partner.StoreSkuInfo) (skuList []*dao.StoreSkuSyncInfo) { - if len(bareSkuList) > 0 { - skuList = make([]*dao.StoreSkuSyncInfo, len(bareSkuList)) - for k, v := range bareSkuList { - skuList[k] = skuMap[v] - } - } - return skuList - } - isContinueWhenError2 := true - //如果是银豹平台,则要按照商品skuname维度同步 - if vendorID == model.VendorIDYB { - if len(createList) > 0 { - rList1, _ := changeList2Yb(createList, nil) - createList = createList[:] - createList = rList1 - for _, v := range createList { - v.YbBarCode = storeDetail.YbStorePrefix + v.YbNameSuffix - v.VendorPrice = int64(jxutils.CaculatePriceByPricePack(storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage), int(v.UnitPrice))) - price, _ := GetSkuNamePrice(db, v.SkuID, v.Price) - v.Price = price - } - } - if len(updateList) > 0 { - rList1, _ := changeList2Yb(updateList, nil) - updateList = updateList[:] - updateList = rList1 - for _, v := range updateList { - v.YbBarCode = storeDetail.YbStorePrefix + v.YbNameSuffix - } - } - if len(priceList) > 0 { - _, rList2 := changeList2Yb(nil, priceList) - priceList = priceList[:] - priceList = rList2 - for _, v := range priceList { - v.VendorPrice = int64(jxutils.CaculatePriceByPricePack(storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage), int(v.JxUnitPrice))) - price, _ := GetSkuNamePrice(db, v.SkuID, v.JxPrice) - v.JxPrice = price - } - } - api.YinBaoAPI = yinbaoapi.New(storeDetail.YbAppKey, storeDetail.YbAppID) - if configs, err := dao.QueryConfigs(dao.GetDB(), "yinbaoCookie", model.ConfigTypeCookie, ""); err == nil { - yinbaoCookie := configs[0].Value - api.YinBaoAPI.SetCookie(".POSPALAUTH30220", yinbaoCookie) - } - } - //如果平台是京东商城,则按商品skuname创建 - if vendorID == model.VendorIDJDShop { - if len(createList) > 0 { - rList := changeList2Jds(createList) - createList = createList[:] - createList = rList - } - if len(updateList) > 0 { - rList2 := changeList2Jds(updateList) - updateList = updateList[:] - updateList = rList2 - } - } - - task := tasksch.NewParallelTask("syncStoreSkuNew", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError2), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - step := batchItemList[0].(int) - // globals.SugarLogger.Debugf("step:%d", step) - switch step { - case 0: - if len(deleteList) > 0 { - _, err = putils.FreeBatchStoreSkuInfo("删除门店商品", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) { - var failedList []*partner.StoreSkuInfoWithErr - if failedList, err = singleStoreHandler.DeleteStoreSkus(ctx, storeID, vendorStoreID, batchedStoreSkuList); singleStoreHandler.IsErrSkuNotExist(err) { - err = nil - failedList = nil // 因为batchSize为1,可以这样处理 - } - failedList, err = buildFailedListAndErr(failedList, err, batchedStoreSkuList, nil, storeID, vendorID, "删除门店商品") - if len(failedList) > 0 { - task.AddFailedList(failedList) - } - if err != nil { - offlineList = append(offlineList, batchedStoreSkuList...) - } - successList := putils.UnselectStoreSkuListByVendorSkuIDs(batchedStoreSkuList, GetVendorSkuIDList(failedList)) - if len(successList) > 0 { - updateStoreSku(dao.GetDB(), vendorID, bareSku2Sync(successList), model.SyncFlagDeletedMask) - } - return nil, len(successList), err - }, ctx, task, deleteList, 1 /*singleStoreHandler.GetStoreSkusBatchSize(partner.FuncDeleteStoreSkus)*/, isContinueWhenError2) - } - case 1: - if len(createList) > 0 { - _, err = putils.FreeBatchStoreSkuSyncInfo("创建门店商品", func(task tasksch.ITask, batchedStoreSkuList []*dao.StoreSkuSyncInfo) (result interface{}, successCount int, err error) { - var failedList []*partner.StoreSkuInfoWithErr - if failedList, err = singleStoreHandler.CreateStoreSkus(ctx, storeID, vendorStoreID, batchedStoreSkuList); singleStoreHandler.IsErrSkuExist(err) { - if skuNameList, err2 := singleStoreHandler.GetStoreSkusFullInfo(ctx, task, storeID, vendorStoreID, []*partner.StoreSkuInfo{ - &partner.StoreSkuInfo{ - SkuID: batchedStoreSkuList[0].SkuID, - VendorSkuID: batchedStoreSkuList[0].VendorSkuID, - }, - }); err2 == nil && len(skuNameList) > 0 { - batchedStoreSkuList[0].VendorNameID = skuNameList[0].VendorNameID - batchedStoreSkuList[0].VendorSkuID = skuNameList[0].SkuList[0].VendorSkuID - - // 如果创建商品时已经存在,需要更新 - updateList = append(updateList, calVendorPrice4StoreSku(batchedStoreSkuList[0], storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage))) - err = nil - failedList = nil // 因为batchSize为1,可以这样处理 - } else if err2 != nil { - failedList = append(failedList, putils.GetErrMsg2FailedSingleList(batchedStoreSkuList, err2, storeID, model.VendorChineseNames[vendorID], "查询是否有该商品")...) - } - } - failedList, err = buildFailedListAndErr(failedList, err, nil, batchedStoreSkuList, storeID, vendorID, "创建门店商品") - if len(failedList) > 0 { - task.AddFailedList(failedList) - } - if err != nil { - //handle error for sensitive words, if find, then insert to table sensitive_words - if sensitiveWord := GetSensitiveWord(singleStoreHandler, err.Error()); sensitiveWord != "" { - dao.InsertSensitiveWord(sensitiveWord, vendorID, ctx.GetUserName()) - // words, _ := dao.GetSensitiveWordList(vendorID) - // word := words[0] - // word.Word = word.Word + "," + sensitiveWord - // dao.UpdateSensitiveWord(word, vendorID, 0, ctx.GetUserName()) - } - } - successList := putils.UnselectStoreSkuSyncListByVendorSkuIDs(batchedStoreSkuList, GetVendorSkuIDList(failedList)) - if len(successList) > 0 { - updateStoreSku(dao.GetDB(), vendorID, successList, model.SyncFlagNewMask) - } - return nil, len(successList), err - }, ctx, task, createList, 1 /*singleStoreHandler.GetStoreSkusBatchSize(partner.FuncCreateStoreSkus)*/, isContinueWhenError2) - } - case 2: - if len(updateList) > 0 { - _, err = putils.FreeBatchStoreSkuSyncInfo("更新门店商品基础信息", func(task tasksch.ITask, batchedStoreSkuList []*dao.StoreSkuSyncInfo) (result interface{}, successCount int, err error) { - var failedList []*partner.StoreSkuInfoWithErr - failedList, err = singleStoreHandler.UpdateStoreSkus(ctx, storeID, vendorStoreID, batchedStoreSkuList) - failedList, err = buildFailedListAndErr(failedList, err, nil, batchedStoreSkuList, storeID, vendorID, "更新门店商品基础信息") - if len(failedList) > 0 { - task.AddFailedList(failedList) - } - successList := putils.UnselectStoreSkuSyncListByVendorSkuIDs(batchedStoreSkuList, GetVendorSkuIDList(failedList)) - if len(successList) > 0 { - updateStoreSku(dao.GetDB(), vendorID, successList, model.SyncFlagModifiedMask) - } - return nil, len(successList), err - }, ctx, task, updateList, singleStoreHandler.GetStoreSkusBatchSize(partner.FuncUpdateStoreSkus), isContinueWhenError2) - } - case 3: - for k, list := range [][]*partner.StoreSkuInfo{stockList /*, onlineList*/} { - if len(list) > 0 { - _, err = putils.FreeBatchStoreSkuInfo("更新门店商品库存", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) { - var failedList []*partner.StoreSkuInfoWithErr - failedList, err = storeSkuHandler.UpdateStoreSkusStock(ctx, storeDetail.VendorOrgCode, storeID, vendorStoreID, batchedStoreSkuList) - failedList, err = buildFailedListAndErr(failedList, err, batchedStoreSkuList, nil, storeID, vendorID, "更新门店商品库存") - if len(failedList) > 0 { - task.AddFailedList(failedList) - } - successList := putils.UnselectStoreSkuListByVendorSkuIDs(batchedStoreSkuList, GetVendorSkuIDList(failedList)) - if k == 0 && len(successList) > 0 { - updateStoreSku(dao.GetDB(), vendorID, bareSku2Sync(successList), model.SyncFlagStockMask) - } - return nil, len(successList), err - }, ctx, task, list, storeSkuHandler.GetStoreSkusBatchSize(partner.FuncUpdateStoreSkusStock), isContinueWhenError2) - } - } - case 4, 5: - statusList := onlineList - status := model.SkuStatusNormal - name := "可售门店商品" - if step == 5 { - statusList = offlineList - status = model.SkuStatusDontSale - name = "不可售门店商品" - } - if len(statusList) > 0 { - _, err = putils.FreeBatchStoreSkuInfo(name, func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) { - var failedList []*partner.StoreSkuInfoWithErr - failedList, err = storeSkuHandler.UpdateStoreSkusStatus(ctx, storeDetail.VendorOrgCode, storeID, vendorStoreID, batchedStoreSkuList, status) - failedList, err = buildFailedListAndErr(failedList, err, batchedStoreSkuList, nil, storeID, vendorID, "更新门店商品状态") - if len(failedList) > 0 { - task.AddFailedList(failedList) - } - successList := putils.UnselectStoreSkuListByVendorSkuIDs(batchedStoreSkuList, GetVendorSkuIDList(failedList)) - if len(successList) > 0 { - updateStoreSku(dao.GetDB(), vendorID, bareSku2Sync(successList), model.SyncFlagSaleMask) - } - return nil, len(successList), err - }, ctx, task, statusList, storeSkuHandler.GetStoreSkusBatchSize(partner.FuncUpdateStoreSkusStatus), isContinueWhenError2) - } - case 6: - if len(priceList) > 0 { - _, err = putils.FreeBatchStoreSkuInfo("更新门店商品价格", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) { - if isNeedHandleAct(causeFlag) { - cancelStoreSkuActs(ctx, task, vendorID, storeDetail.VendorOrgCode, storeID, vendorStoreID, batchedStoreSkuList, true) - } - var failedList []*partner.StoreSkuInfoWithErr - failedList, err = storeSkuHandler.UpdateStoreSkusPrice(ctx, storeDetail.VendorOrgCode, storeID, vendorStoreID, batchedStoreSkuList) - failedList, err = buildFailedListAndErr(failedList, err, batchedStoreSkuList, nil, storeID, vendorID, "更新门店商品价格") - if len(failedList) > 0 { - task.AddFailedList(failedList) - } - successList := putils.UnselectStoreSkuListByVendorSkuIDs(batchedStoreSkuList, GetVendorSkuIDList(failedList)) - if len(successList) > 0 { - updateStoreSku(dao.GetDB(), vendorID, bareSku2Sync(successList), model.SyncFlagPriceMask) - } - if isNeedHandleAct(causeFlag) { - createStoreSkuActs(ctx, task, vendorID, storeDetail.VendorOrgCode, storeID, vendorStoreID, batchedStoreSkuList, true) - } - return nil, len(successList), err - }, ctx, task, priceList, storeSkuHandler.GetStoreSkusBatchSize(partner.FuncUpdateStoreSkusPrice), isContinueWhenError2) - } - case 7: - if len(reorderSkuMap) > 0 { - var vendorCatIDs []string - for vendorCatID := range reorderSkuMap { - vendorCatIDs = append(vendorCatIDs, vendorCatID) - } - reorderTask := tasksch.NewParallelTask("门店商品排序", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError2), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - vendorCatID := batchItemList[0].(string) - skuList := reorderSkuMap[vendorCatID] - var bareList []*partner.StoreSkuInfo - for _, v := range skuList { - bareList = append(bareList, storeSkuSyncInfo2Bare(calVendorPrice4StoreSku(v, storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage)))) - } - sort.Sort(partner.BareStoreSkuInfoList(bareList)) - if err = reorderHandler.ReorderStoreSkus(ctx, storeID, vendorStoreID, vendorCatID, bareList); err == nil { - updateStoreSku(dao.GetDB(), vendorID, skuList, model.SyncFlagSeqMask) - } - return retVal, err - }, vendorCatIDs) - tasksch.HandleTask(reorderTask, task, true).Run() - _, err = reorderTask.GetResult(0) - } - } - return retVal, err - }, []int{0, 1, 2, 3, 4, 5, 6, 7}) - tasksch.HandleTask(task, parentTask, true).Run() - _, err = task.GetResult(0) - return err -} - -func buildFailedListAndErr(failedList []*partner.StoreSkuInfoWithErr, err error, list1 []*partner.StoreSkuInfo, list2 []*dao.StoreSkuSyncInfo, storeID, vendorID int, syncType string) (result []*partner.StoreSkuInfoWithErr, err2 error) { - if err != nil && len(failedList) == 0 { - if list1 != nil { - for _, v := range list1 { - failed := &partner.StoreSkuInfoWithErr{ - StoreSkuInfo: v, - VendoreID: vendorID, - StoreID: storeID, - SyncType: syncType, - ErrMsg: err.Error(), - } - failedList = append(failedList, failed) - } - } - if list2 != nil { - for _, v := range list2 { - storeSkuInfo := &partner.StoreSkuInfo{ - SkuID: v.SkuID, - VendorSkuID: v.VendorSkuID, - NameID: v.NameID, - VendorNameID: v.VendorNameID, - VendorPrice: v.VendorPrice, - Status: v.Status, - } - failed := &partner.StoreSkuInfoWithErr{ - StoreSkuInfo: storeSkuInfo, - VendoreID: vendorID, - StoreID: storeID, - SyncType: syncType, - ErrMsg: err.Error(), - } - failedList = append(failedList, failed) - } - } - return failedList, err - } else if err == nil && len(failedList) > 0 { - var errMsgList []string - for _, v := range failedList { - errMsgList = append(errMsgList, utils.Int2Str(v.StoreID)) - errMsgList = append(errMsgList, utils.Int2Str(v.StoreSkuInfo.SkuID)) - errMsgList = append(errMsgList, v.ErrMsg) - } - err2 := errors.New(strings.Join(errMsgList, ",")) - return failedList, err2 - } - return failedList, err -} - -func isNeedHandleAct(causeFlag int) bool { - return globals.IsStoreSkuAct && (causeFlag&model.SyncFlagPriceMask != 0) -} - -func checkRemoteCatExist(outRemoteCatMap map[string]int, localCatMap map[string]*dao.SkuStoreCatInfo, remoteCatList []*partner.BareCategoryInfo) (cat2Delete []*partner.BareCategoryInfo) { - for _, v := range remoteCatList { - localCat := localCatMap[v.VendorCatID] - // if localCat == nil { - // localCat = localCatMap[v.Name] - // } - if localCat == nil || v.Level != int(localCat.Level) { - cat2Delete = append(cat2Delete, v) - } else { - outRemoteCatMap[v.VendorCatID] = 1 - } - cat2Delete = append(cat2Delete, checkRemoteCatExist(outRemoteCatMap, localCatMap, v.Children)...) - } - return cat2Delete -} - -// 清除京西没有,平台有的商品与商家分类 -// todo !!!,因为美团外卖分类当前是用的名字关联的,所以改名后如果没有及时同步,这个函数会导致美团平台的分类被误删 -func PruneMissingStoreSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorID, storeID int, vendorStoreID string, isAsync, isContinueWhenError bool) (hint string, err error) { - return amendAndPruneStoreStuff(ctx, parentTask, vendorID, storeID, vendorStoreID, isAsync, isContinueWhenError, AmendPruneOnlyPrune, false) -} - -func amendAndPruneStoreStuff(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorID, storeID int, vendorStoreID string, isAsync, isContinueWhenError bool, opType int, isForceUpdate bool) (hint string, err error) { - handler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreStoreSkuHandler) - if handler == nil { - return "", fmt.Errorf("平台:%s不支持此操作", model.VendorChineseNames[vendorID]) - } - db := dao.GetDB() - storeDetail, err := dao.GetStoreDetail(db, storeID, vendorID) - if err != nil { - return "", err - } - - var sku2Delete []*partner.StoreSkuInfo - var cat2Delete []*partner.BareCategoryInfo - task := tasksch.NewParallelTask(fmt.Sprintf("修补门店:%d,平台:%s上的商品与商家分类", storeID, model.VendorChineseNames[vendorID]), - tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - step := batchItemList[0].(int) - switch step { - case 0: - localSkuList, err := dao.GetStoreSkus2(db, vendorID, storeID, nil, false) - if err != nil { - return nil, err - } - localSkuMap := make(map[string]*dao.StoreSkuSyncInfo) - for _, v := range localSkuList { - localSkuMap[v.VendorSkuID] = v - } - - remoteSkuList, err2 := handler.GetStoreSkusFullInfo(ctx, task, storeID, vendorStoreID, nil) - if err = err2; err == nil { - remoteSkuMap := make(map[string]int) - for _, v := range remoteSkuList { - if vendorSkuID := v.SkuList[0].VendorSkuID; vendorSkuID != "" { - if localSkuMap[vendorSkuID] == nil || - remoteSkuMap[vendorSkuID] == 1 /*skuID在平台重复,典型的是美团可能会出现此类情况*/ { - sku2Delete = append(sku2Delete, &partner.StoreSkuInfo{ - SkuID: v.SkuList[0].SkuID, - VendorSkuID: vendorSkuID, - }) - } else { - remoteSkuMap[vendorSkuID] = 1 - } - } else if v.VendorNameID != "" { - sku2Delete = append(sku2Delete, &partner.StoreSkuInfo{ - SkuID: v.NameID, - VendorSkuID: v.VendorNameID, - }) - } - } - if opType == AmendPruneOnlyAmend || opType == AmendPruneAll { - for _, v := range localSkuList { - if !model.IsSyncStatusDelete(v.SkuSyncStatus) && v.BindID != 0 { - syncStatus := int8(0) - if remoteSkuMap[v.VendorSkuID] == 0 { - if !model.IsSyncStatusNew(v.SkuSyncStatus) { - syncStatus = model.SyncFlagNewMask - } - } else if isForceUpdate { - syncStatus = model.SyncFlagStoreSkuModifiedMask - } - if syncStatus != 0 { - skuBind := &model.StoreSkuBind{} - skuBind.ID = v.BindID - // skuBind.LastOperator = ctx.GetUserName() - // skuBind.UpdatedAt = time.Now() - dao.SetStoreSkuBindSyncStatus(skuBind, vendorID, syncStatus|v.SkuSyncStatus) - dao.UpdateEntity(db, skuBind, dao.GetSyncStatusStructField(model.VendorNames[vendorID]) /*, model.FieldLastOperator, model.FieldUpdatedAt*/) - } - } - } - } - } - case 1: - if (opType == AmendPruneOnlyPrune || opType == AmendPruneAll) && len(sku2Delete) > 0 { - _, err = putils.FreeBatchStoreSkuInfo("删除门店商品", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) { - if _, err = handler.DeleteStoreSkus(ctx, storeID, vendorStoreID, batchedStoreSkuList); err != nil { - if batchedStoreSkuList[0].Status == model.SkuStatusNormal { - // 如果删除失败,尝试设置不可售,假定删除批处理SIZE小于等于设置门店商品可售批处理SIZE - handler.UpdateStoreSkusStatus(ctx, storeDetail.VendorOrgCode, storeID, vendorStoreID, batchedStoreSkuList, model.SkuStatusDontSale) - } - } - return nil, 0, err - }, ctx, task, sku2Delete, 1 /*handler.GetStoreSkusBatchSize(partner.FuncDeleteStoreSkus)*/, isContinueWhenError) - } - sku2Delete = nil - case 2: - localCatList, err := dao.GetStoreCategories(db, vendorID, storeID, nil, 0, false) - if err != nil { - return nil, err - } - localCatMap := make(map[string]*dao.SkuStoreCatInfo) - for _, v := range localCatList { - localCatMap[v.VendorCatID] = v - localCatMap[v.Name] = v - localCatMap[utils.Int2Str(v.ID)] = v - } - - remoteCatList, err2 := handler.GetStoreAllCategories(ctx, storeID, vendorStoreID) - if err = err2; err == nil { - remoteCatMap := make(map[string]int) - cat2Delete = checkRemoteCatExist(remoteCatMap, localCatMap, remoteCatList) - - for _, v := range localCatList { - if !model.IsSyncStatusDelete(v.CatSyncStatus) && v.MapID != 0 { - syncStatus := int8(0) - if remoteCatMap[v.VendorCatID] == 0 { - if !model.IsSyncStatusNew(v.CatSyncStatus) { - syncStatus = model.SyncFlagNewMask - } - } else if isForceUpdate && !model.IsSyncStatusUpdate(v.CatSyncStatus) { - syncStatus = model.SyncFlagModifiedMask - } - if syncStatus != 0 { - catBind := &model.StoreSkuCategoryMap{} - catBind.ID = v.MapID - // catBind.LastOperator = ctx.GetUserName() - // catBind.UpdatedAt = time.Now() - dao.SetStoreCatMapSyncStatus(catBind, vendorID, syncStatus|v.CatSyncStatus) - dao.UpdateEntity(db, catBind, dao.GetSyncStatusStructField(model.VendorNames[vendorID]) /*, model.FieldLastOperator, model.FieldUpdatedAt*/) - } - } - } - } - case 3: - if (opType == AmendPruneOnlyPrune || opType == AmendPruneAll) && len(cat2Delete) > 0 { - for i := 0; i < 2; i++ { - level := 2 - i - var levelCat2Delete []*partner.BareCategoryInfo - for _, v := range cat2Delete { - if v.Level == level { - levelCat2Delete = append(levelCat2Delete, v) - } - } - if len(levelCat2Delete) > 0 { - task4Delete := tasksch.NewParallelTask(fmt.Sprintf("删除商家分类,level:%d", level), tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - cat := batchItemList[0].(*partner.BareCategoryInfo) - err = handler.DeleteStoreCategory(ctx, storeID, vendorStoreID, cat.VendorCatID, level) - return nil, err - }, levelCat2Delete) - tasksch.HandleTask(task4Delete, task, true).Run() - _, err = task4Delete.GetResult(0) - } - } - } - cat2Delete = nil - } - return nil, err - }, []int{0, 1, 2, 3}) - tasksch.HandleTask(task, parentTask, true).Run() - if !isAsync { - _, err = task.GetResult(0) - hint = "1" - } else { - hint = task.ID - } - return hint, err -} - -// 把京西有,平台无且没有待创建标记的商品加上待创建标记 -func AddCreateFlagForJxStoreSku(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorID, storeID int, vendorStoreID string, isAsync, isContinueWhenError bool) (hint string, err error) { - return amendAndPruneStoreStuff(ctx, parentTask, vendorID, storeID, vendorStoreID, isAsync, isContinueWhenError, AmendPruneOnlyAmend, false) -} - -func ClearRemoteStoreStuffAndSetNew(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorID, storeID int, vendorStoreID string, isAsync, isContinueWhenError bool) (hint string, err error) { - userName := ctx.GetUserName() - globals.SugarLogger.Debugf("ClearRemoteStoreStuffAndSetNew storeID:%d, isContinueWhenError:%t, userName:%s", storeID, isContinueWhenError, userName) - handler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.ISingleStoreStoreSkuHandler) - if handler == nil { - return "", fmt.Errorf("平台:%s不支持此操作", model.VendorChineseNames[vendorID]) - } - - db := dao.GetDB() - task := tasksch.NewParallelTask(fmt.Sprintf("删除门店:%d,平台:%s上的商品与商家分类", storeID, model.VendorChineseNames[vendorID]), - tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - step := batchItemList[0].(int) - switch step { - case 0: - err = handler.DeleteStoreAllSkus(ctx, task, storeID, vendorStoreID, isContinueWhenError) - case 1: - _, err = dao.SetStoreSkuSyncStatus(db, vendorID, []int{storeID}, nil, model.SyncFlagNewMask) - case 2: - err = handler.DeleteStoreAllCategories(ctx, task, storeID, vendorStoreID, isContinueWhenError) - case 3: - _, err = dao.SetStoreCategorySyncStatus(db, vendorID, []int{storeID}, nil, model.SyncFlagNewMask) - } - return nil, err - }, []int{0, 1, 2, 3}) - tasksch.HandleTask(task, parentTask, true).Run() - if !isAsync { - _, err = task.GetResult(0) - hint = "1" - } else { - hint = task.ID - } - return hint, err -} - -func GetSensitiveWord(singleStoreHandler partner.ISingleStoreStoreSkuHandler, str string) string { - sensitiveWordRegexp := singleStoreHandler.GetSensitiveWordRegexp() - findResult := sensitiveWordRegexp.FindStringSubmatch(str) - if findResult != nil && len(findResult) > 1 { - findSubResult := subSensitiveWordRegexp.FindAllString(findResult[1], -1) - return strings.Join(findSubResult, "") - } - - return "" -} - -func MergeSkuSaleStatusWithStoreOpTime(sku *dao.StoreSkuSyncInfo, storeDetail *dao.StoreDetail, now int16) (outStatus int) { - if sku.MergedStatus == model.SkuStatusNormal && - sku.StatusSaleBegin > 0 && sku.StatusSaleEnd > 0 && - storeDetail.Status == model.StoreStatusOpened { - //商品可售时间的差集与门店营业时间的交集为不可售,其余为原本状态 - var openTime int16 - var closeTime int16 - saleBeginTime := sku.StatusSaleBegin - saleEndTime := sku.StatusSaleEnd - if storeDetail.OpenTime2 != 0 && storeDetail.CloseTime2 != 0 { - if storeDetail.OpenTime1 < storeDetail.OpenTime2 { - openTime = storeDetail.OpenTime1 - } else { - openTime = storeDetail.OpenTime2 - } - if storeDetail.CloseTime1 > storeDetail.CloseTime2 { - closeTime = storeDetail.CloseTime1 - } else { - closeTime = storeDetail.CloseTime2 - } - } else { - openTime = storeDetail.OpenTime1 - closeTime = storeDetail.CloseTime1 - } - beginAt1, endAt1 := GetTimeMixByInt(0, saleBeginTime, openTime, closeTime) - beginAt2, endAt2 := GetTimeMixByInt(saleEndTime, 2400, openTime, closeTime) - if beginAt1 != 0 && endAt1 != 0 { - if now >= beginAt1 && now < endAt1 { - return model.SkuStatusDontSale - } - } - if beginAt2 != 0 && endAt2 != 0 { - if now >= beginAt2 && now < endAt2 { - return model.SkuStatusDontSale - } - } - } - return sku.MergedStatus -} - -func GetVendorSkuIDList(l []*partner.StoreSkuInfoWithErr) (vendorSkuIDs []string) { - if len(l) > 0 { - for _, v := range l { - if v.StoreSkuInfo != nil { - vendorSkuIDs = append(vendorSkuIDs, v.StoreSkuInfo.VendorSkuID) - } - } - } - return vendorSkuIDs -} - -func skuAct2Update(storeSkuAct *model.StoreSkuAct, isCreateAct bool) (item *dao.KVUpdateItem) { - storeSkuAct.SyncStatus = 0 - if !isCreateAct { - storeSkuAct.VendorActID = "" - } - kvs := map[string]interface{}{ - "VendorActID": storeSkuAct.VendorActID, - "VendorActPrice": storeSkuAct.VendorActPrice, - "SyncStatus": storeSkuAct.SyncStatus, - } - item = &dao.KVUpdateItem{ - Item: storeSkuAct, - KVs: kvs, - } - return item -} - -func updateStoreSkuAct(db *dao.DaoDB, vendorID int, storeSkuActList []*model.StoreSkuAct, isCreateAct bool) (num int64, err error) { - if len(storeSkuActList) > 0 { - updateItemList := make([]*dao.KVUpdateItem, len(storeSkuActList)) - for k, v := range storeSkuActList { - updateItemList[k] = skuAct2Update(v, isCreateAct) - } - num, err = dao.BatchUpdateEntityByKV(db, updateItemList) - } - return num, err -} - -func bareSku2StoreSkuAct(storeSkuActMap map[int]*model.StoreSkuAct, storeSkuList []*partner.StoreSkuInfo) (storeSkuActList []*model.StoreSkuAct) { - for _, v := range storeSkuList { - storeSkuAct := storeSkuActMap[v.SkuID] - storeSkuAct.VendorActID = v.VendorActID - storeSkuAct.VendorActPrice = v.ActPrice - storeSkuActList = append(storeSkuActList, storeSkuAct) - } - return storeSkuActList -} - -func parseStoreSkuActList(isCreateAct bool, storeSkuList []*partner.StoreSkuInfo, storeSkuActList []*model.StoreSkuAct) (outStoreSkuList []*partner.StoreSkuInfo, storeSkuActMap map[int]*model.StoreSkuAct) { - storeSkuMap := make(map[int]*partner.StoreSkuInfo) - for _, v := range storeSkuList { - storeSkuMap[v.SkuID] = v - } - - storeSkuActMap = make(map[int]*model.StoreSkuAct) - for _, v := range storeSkuActList { - if isCreateAct && v.VendorActID == "" && v.ActPercentage > 0 || - !isCreateAct && v.VendorActID != "" { - storeSku := storeSkuMap[v.SkuID] - if isCreateAct { - storeSku.ActPrice = int64(jxutils.CaculateSkuVendorPrice(int(storeSku.VendorPrice), v.ActPercentage, 0)) - } else { - storeSku.VendorActID = v.VendorActID - } - outStoreSkuList = append(outStoreSkuList, storeSku) - storeSkuActMap[v.SkuID] = v - } - } - - return outStoreSkuList, storeSkuActMap -} - -func createStoreSkuActs(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorID int, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, isChangePrice bool) (err error) { - globals.SugarLogger.Debugf("createStoreSkuActs vendorID:%d, storeID:%d, storeSkuList:%s", vendorID, storeID, utils.Format4Output(storeSkuList, true)) - skuIDs := putils.StoreSkuList2IDs(storeSkuList) - db := dao.GetDB() - storeSkuActList, err := dao.GetStoresSkusAct(db, 0, false, []int{storeID}, skuIDs, []int{vendorID}, false, 1, 0) - if err == nil { - if isChangePrice && vendorID == model.VendorIDJD { - time.Sleep(1 * time.Second) // 改价后马上建活动可能失败 - } - err = createStoreSkuActs2(ctx, parentTask, vendorID, vendorOrgCode, storeID, vendorStoreID, storeSkuList, storeSkuActList) - } - return err -} - -func cancelStoreSkuActs(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorID int, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, isChangePrice bool) (err error) { - globals.SugarLogger.Debugf("cancelStoreSkuActs vendorID:%d, storeID:%d, storeSkuList:%s", vendorID, storeID, utils.Format4Output(storeSkuList, true)) - skuIDs := putils.StoreSkuList2IDs(storeSkuList) - db := dao.GetDB() - storeSkuActList, err := dao.GetStoresSkusAct(db, 0, false, []int{storeID}, skuIDs, []int{vendorID}, true, 0, 0) - if err == nil { - err = cancelStoreSkuActs2(ctx, parentTask, vendorID, vendorOrgCode, storeID, vendorStoreID, storeSkuList, storeSkuActList) - if err == nil && isChangePrice && vendorID == model.VendorIDJD { - time.Sleep(1 * time.Second) // 取消活动后马上改价可能失败 - } - } - return err -} - -func createStoreSkuActs2(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorID int, vendorOrgCode string, storeID int, vendorStoreID string, - storeSkuList []*partner.StoreSkuInfo, storeSkuActList []*model.StoreSkuAct) (err error) { - globals.SugarLogger.Debugf("createStoreSkuActs vendorID:%d, storeID:%d, storeSkuList:%s", vendorID, storeID, utils.Format4Output(storeSkuList, true)) - storeSkuList2, storeSkuActMap := parseStoreSkuActList(true, storeSkuList, storeSkuActList) - if len(storeSkuList2) > 0 { - storeSkuHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IPurchasePlatformStoreSkuHandler) - _, err = putils.FreeBatchStoreSkuInfo(fmt.Sprintf("创建门店%d直降活动", storeID), func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) { - var failedList []*partner.StoreSkuInfoWithErr - failedList, err = storeSkuHandler.CreateStoreSkusAct(ctx, vendorOrgCode, storeID, vendorStoreID, batchedStoreSkuList) - if len(failedList) > 0 { - task.AddFailedList(failedList) - } - successList := putils.UnselectStoreSkuListBySkuIDs(batchedStoreSkuList, putils.StoreSkuInfoWithErrList2SkuIDs(failedList)) - if len(successList) > 0 { - updateStoreSkuAct(dao.GetDB(), vendorID, bareSku2StoreSkuAct(storeSkuActMap, successList), true) - } - return nil, len(successList), err - }, ctx, parentTask, storeSkuList2, storeSkuHandler.GetStoreSkusBatchSize(partner.FuncCancelActs), true) - } - return err -} - -func cancelStoreSkuActs2(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorID int, vendorOrgCode string, storeID int, vendorStoreID string, - storeSkuList []*partner.StoreSkuInfo, storeSkuActList []*model.StoreSkuAct) (err error) { - globals.SugarLogger.Debugf("cancelStoreSkuActs vendorID:%d, storeID:%d, storeSkuList:%s", vendorID, storeID, utils.Format4Output(storeSkuList, true)) - storeSkuList2, storeSkuActMap := parseStoreSkuActList(false, storeSkuList, storeSkuActList) - if len(storeSkuList2) > 0 { - storeSkuHandler := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IPurchasePlatformStoreSkuHandler) - _, err = putils.FreeBatchStoreSkuInfo(fmt.Sprintf("取消门店%d直降活动", storeID), func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) { - var failedList []*partner.StoreSkuInfoWithErr - failedList, err = storeSkuHandler.CancelActs(ctx, vendorOrgCode, storeID, vendorStoreID, batchedStoreSkuList) - if len(failedList) > 0 { - task.AddFailedList(failedList) - } - successList := putils.UnselectStoreSkuListBySkuIDs(batchedStoreSkuList, putils.StoreSkuInfoWithErrList2SkuIDs(failedList)) - if len(successList) > 0 { - updateStoreSkuAct(dao.GetDB(), vendorID, bareSku2StoreSkuAct(storeSkuActMap, successList), false) - } - return nil, len(successList), err - }, ctx, parentTask, storeSkuList2, storeSkuHandler.GetStoreSkusBatchSize(partner.FuncCancelActs), true) - } - return err -} - -func SyncStoreSkuBindAct(ctx *jxcontext.Context, parentTask tasksch.ITask, isCreate bool, hintActID int, storeIDs, skuIDs []int) (err error) { - db := dao.GetDB() - var mustHaveVendorActID bool - var minActPercentage int - if isCreate { - mustHaveVendorActID = false - minActPercentage = 1 - } else { - mustHaveVendorActID = true - minActPercentage = 0 - } - storeSkuActList, err := dao.GetStoresSkusAct(db, hintActID, true, storeIDs, skuIDs, nil, mustHaveVendorActID, minActPercentage, 0) - if err != nil || len(storeSkuActList) == 0 { - return err - } - - storeMap := make(map[int]int) - skuMap := make(map[int]int) - storeVendorMap := make(map[int]map[int]int) - storeSkuActMap := make(map[int]map[int][]*model.StoreSkuAct) - for _, v := range storeSkuActList { - storeMap[v.StoreID] = 1 - skuMap[v.SkuID] = 1 - - if storeVendorMap[v.StoreID] == nil { - storeVendorMap[v.StoreID] = make(map[int]int) - } - storeVendorMap[v.StoreID][v.VendorID] = 1 - - if storeSkuActMap[v.StoreID] == nil { - storeSkuActMap[v.StoreID] = make(map[int][]*model.StoreSkuAct) - } - storeSkuActMap[v.StoreID][v.VendorID] = append(storeSkuActMap[v.StoreID][v.VendorID], v) - } - - storeIDs = jxutils.IntMap2List(storeMap) - storeSkuList, err := dao.GetStoresSkusInfo(db, storeIDs, jxutils.IntMap2List(skuMap)) - if err != nil || len(storeSkuList) == 0 { - return err - } - storeSkuMap := make(map[int]map[int][]*partner.StoreSkuInfo) - for _, v := range storeSkuList { - if storeSkuMap[v.StoreID] == nil { - storeSkuMap[v.StoreID] = make(map[int][]*partner.StoreSkuInfo) - } - for vendorID := range storeVendorMap[v.StoreID] { - storeSku := &partner.StoreSkuInfo{ - SkuID: v.SkuID, - VendorPrice: int64(dao.GetStoreSkuBindVendorPrice(v, vendorID)), - } - storeSkuMap[v.StoreID][vendorID] = append(storeSkuMap[v.StoreID][vendorID], storeSku) - } - } - - var taskName string - if isCreate { - taskName = "创建门店绑定活动" - } else { - taskName = "取消门店绑定活动" - } - task := tasksch.NewParallelTask(taskName, nil, ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeID := batchItemList[0].(int) - vendorIDs := jxutils.IntMap2List(storeVendorMap[storeID]) - subTask := tasksch.NewParallelTask(fmt.Sprintf("%s门店:%d", taskName, storeID), nil, ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - vendorID := batchItemList[0].(int) - storeDetail, err := dao.GetStoreDetail(db, storeID, vendorID) - if err == nil { - if isCreate { - err = createStoreSkuActs2(ctx, task, vendorID, storeDetail.VendorOrgCode, storeID, storeDetail.VendorStoreID, storeSkuMap[storeID][vendorID], storeSkuActMap[storeID][vendorID]) - } else { - err = cancelStoreSkuActs2(ctx, task, vendorID, storeDetail.VendorOrgCode, storeID, storeDetail.VendorStoreID, storeSkuMap[storeID][vendorID], storeSkuActMap[storeID][vendorID]) - } - } - return retVal, err - }, vendorIDs) - tasksch.HandleTask(subTask, task, true).Run() - _, err = subTask.GetResult(0) - return retVal, err - }, storeIDs) - tasksch.HandleTask(task, parentTask, true).Run() - _, err = task.GetResult(0) - - return err -} - -func FullSyncStoreSkuBindAct(ctx *jxcontext.Context, parentTask tasksch.ITask, hintActID int, storeIDs, skuIDs []int) (err error) { - task := tasksch.NewParallelTask("同步门店商品绑定活动", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(true), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - step := batchItemList[0] - switch step { - case 0: - err = SyncStoreSkuBindAct(ctx, task, false, hintActID, storeIDs, skuIDs) - case 1: - err = SyncStoreSkuBindAct(ctx, task, true, hintActID, storeIDs, skuIDs) - } - return retVal, err - }, []int{0, 1}) - tasksch.HandleTask(task, parentTask, true).Run() - _, err = task.GetResult(0) - return err -} - -func changeList2Yb(list1 []*dao.StoreSkuSyncInfo, list2 []*partner.StoreSkuInfo) (rList1 []*dao.StoreSkuSyncInfo, rList2 []*partner.StoreSkuInfo) { - var ( - skuNameMap = make(map[int]*dao.StoreSkuSyncInfo) - skuNameMap2 = make(map[int]*partner.StoreSkuInfo) - ) - for _, v := range list1 { - skuNameMap[v.NameID] = v - } - for _, v := range skuNameMap { - rList1 = append(rList1, v) - } - for _, v := range list2 { - skuNameMap2[v.NameID] = v - } - for _, v := range skuNameMap2 { - rList2 = append(rList2, v) - } - return rList1, rList2 -} - -func changeList2Jds(list []*dao.StoreSkuSyncInfo) (rList []*dao.StoreSkuSyncInfo) { - var ( - skuNameMap = make(map[int][]*dao.StoreSkuSyncInfo) - ) - for _, v := range list { - skuNameMap[v.NameID] = append(skuNameMap[v.NameID], v) - } - for k, v := range skuNameMap { - storeSku := &dao.StoreSkuSyncInfo{ - StoreSkuSyncInfoJds: v, - } - storeSku.NameID = k - storeSku.Name = v[0].Name - storeSku.VendorCatID = v[0].VendorCatID - storeSku.VendorVendorCatID = v[0].VendorVendorCatID - storeSku.UnitPrice = v[0].UnitPrice - storeSku.Img = v[0].Img - storeSku.Img2 = v[0].Img2 - storeSku.DescImg = v[0].DescImg - storeSku.JdsWareID = v[0].JdsWareID - storeSku.CategoryName = v[0].CategoryName - rList = append(rList, storeSku) - } - return rList -} diff --git a/business/jxstore/cms/sync_store_sku_test.go b/business/jxstore/cms/sync_store_sku_test.go deleted file mode 100644 index 23c8cbd6d..000000000 --- a/business/jxstore/cms/sync_store_sku_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package cms - -import ( - "fmt" - "testing" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/business/partner/putils" -) - -func TestFreeBatchStoreSkuInfo(t *testing.T) { - var sku2Delete []*partner.StoreSkuInfo - for i := 0; i < 123; i++ { - sku2Delete = append(sku2Delete, &partner.StoreSkuInfo{ - SkuID: i + 1, - }) - } - - ctx := jxcontext.AdminCtx - var parentTask tasksch.ITask - isContinueWhenError := true - handler, _ := partner.GetPurchasePlatformFromVendorID(model.VendorIDEBAI).(partner.ISingleStoreStoreSkuHandler) - _, err := putils.FreeBatchStoreSkuInfo("删除门店商品", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) { - t.Log(len(batchedStoreSkuList)) - return nil, 0, err - }, ctx, parentTask, sku2Delete, handler.GetStoreSkusBatchSize(partner.FuncDeleteStoreSkus), isContinueWhenError) - if err != nil { - t.Fatal(err) - } -} - -func TestGetTimeMixByInt(t *testing.T) { - const ( - time1 = 1100 - time2 = 2300 - time3 = 1200 - time4 = 2400 - ) - a, b := GetTimeMixByInt(time1, time2, time3, time4) - fmt.Println(a, b) -} diff --git a/business/jxstore/cms/user2.go b/business/jxstore/cms/user2.go index 37e823bc4..22ad6d821 100644 --- a/business/jxstore/cms/user2.go +++ b/business/jxstore/cms/user2.go @@ -782,7 +782,7 @@ func GetSelfInfo(ctx *jxcontext.Context) (getSelfInfoResult *dao.GetSelfInfoResu tokenInfo, err := auth2.GetTokenInfo(ctx.GetToken()) if err == nil { if getSelfInfoResult, err = dao.GetUserByIDWithMembers(dao.GetDB(), "user_id", tokenInfo.GetID()); err == nil { - if userMembers, err3 := dao.GetUserMember(dao.GetDB(), getSelfInfoResult.UserID, "", 0, model.YES); err3 == nil { + if userMembers, err3 := dao.GetUserMember(dao.GetDB(), getSelfInfoResult.UserID, 0, 0, true); err3 == nil { getSelfInfoResult.UserMembers = userMembers } else { err = err3 @@ -1135,7 +1135,7 @@ func RefreshUserMemberStatus(ctx *jxcontext.Context) (err error) { var ( db = dao.GetDB() ) - userMembers, err := dao.GetUserMember(db, "", "", model.MemberTypeDiscountCard, -1) + userMembers, err := dao.GetUserMember(db, "", 0, 0, true) for _, userMember := range userMembers { if time.Now().Sub(userMember.EndAt) > 0 { userMember.DeletedAt = time.Now() diff --git a/business/jxutils/jxutils.go b/business/jxutils/jxutils.go index 2fe3d5aa0..68d80e79e 100644 --- a/business/jxutils/jxutils.go +++ b/business/jxutils/jxutils.go @@ -797,14 +797,6 @@ func OperationTime2Str2(openTime, closeTime int16) (str string) { return str } -func OperationTimeStr4VendorStore(v *model.VendorStoreSnapshot) (str string) { - str = fmt.Sprintf("%s", OperationTime2Str2(v.OpenTime1, v.CloseTime1)) - if v.OpenTime2 > 0 && v.CloseTime2 > 0 { - str += fmt.Sprintf(",%s", OperationTime2Str2(v.OpenTime2, v.CloseTime2)) - } - return str -} - func OperationTime2HourMinuteFormat(time time.Time) (i int16) { return int16(time.Hour()*100 + time.Minute()) } @@ -895,30 +887,23 @@ func GetOneEmailFromStr(str string) (email string) { // 计算一个坐标点距离一个门店的距离,单位为米,如果不在有效范围内,则返回0 func Point2StoreDistance(lng, lat float64, intStoreLng, intStoreLat int, deliveryRangeType int8, deliveryRange string) (distance int) { - storeLng := IntCoordinate2Standard(intStoreLng) - storeLat := IntCoordinate2Standard(intStoreLat) - if deliveryRangeType == model.DeliveryRangeTypeRadius { - maxDistance := int(utils.Str2Int64WithDefault(deliveryRange, 0)) - distance = int(EarthDistance(lng, lat, storeLng, storeLat) * 1000) - if distance > maxDistance { - distance = 0 - } - } else { - points := CoordinateStr2Points(deliveryRange) - if utils.IsPointInPolygon(lng, lat, points) { - distance = int(EarthDistance(lng, lat, storeLng, storeLat) * 1000) - } - } + // storeLng := IntCoordinate2Standard(intStoreLng) + // storeLat := IntCoordinate2Standard(intStoreLat) + // if deliveryRangeType == model.DeliveryRangeTypeRadius { + // maxDistance := int(utils.Str2Int64WithDefault(deliveryRange, 0)) + // distance = int(EarthDistance(lng, lat, storeLng, storeLat) * 1000) + // if distance > maxDistance { + // distance = 0 + // } + // } else { + // points := CoordinateStr2Points(deliveryRange) + // if utils.IsPointInPolygon(lng, lat, points) { + // distance = int(EarthDistance(lng, lat, storeLng, storeLat) * 1000) + // } + // } return distance } -func TranslateStorePriceType(storePriceType int8) int8 { - if storePriceType == model.StoreChangePriceTypeManagedStore { - storePriceType = model.StoreChangePriceTypeBossDisabled - } - return storePriceType -} - func TranslateSoundSize(vendorID, soundPercentage int) (soundSize string) { if vendorID == model.VendorIDYiLianYun || vendorID == model.VendorIDFeiE { if soundPercentage == 0 { diff --git a/business/jxutils/jxutils_cms.go b/business/jxutils/jxutils_cms.go index ed6c506d8..86233cf57 100644 --- a/business/jxutils/jxutils_cms.go +++ b/business/jxutils/jxutils_cms.go @@ -216,42 +216,6 @@ func RegularizeSkuQuality(specQuality float32, specUnit string) (g int) { return int(specQuality) } -// 计算SKU价格,unitPrice为一斤的单价,specQuality为质量,单位为克 -func CaculateSkuPrice(unitPrice int, specQuality float32, specUnit string, skuNameUnit string) int { - if skuNameUnit != model.SpecialUnit { - return unitPrice - } - specQuality2 := RegularizeSkuQuality(specQuality, specUnit) - floatPrice := float64(unitPrice) * float64(specQuality2) / float64(model.SpecialSpecQuality) - // if specQuality2 < 250 { - // floatPrice = floatPrice * 110 / 100 - // } else if specQuality2 < 500 { - // floatPrice = floatPrice * 105 / 100 - // } - if floatPrice <= 1 { - floatPrice = 1 - } - return int(math.Round(floatPrice)) -} - -// 计算SKU标准价格,CaculateSkuPrice的逆过程 -func CaculateUnitPrice(skuPrice int, specQuality float32, specUnit string, skuNameUnit string) (unitPrice int) { - if skuNameUnit != model.SpecialUnit { - return skuPrice - } - specQuality2 := RegularizeSkuQuality(specQuality, specUnit) - unitPrice = skuPrice * model.SpecialSpecQuality / specQuality2 - // if specQuality2 < 250 { - // unitPrice = unitPrice * 100 / 110 - // } else if specQuality2 < 500 { - // unitPrice = unitPrice * 100 / 105 - // } - if unitPrice <= 1 { - unitPrice = 1 - } - return unitPrice -} - func ConstrainPricePercentage(percentage int) int { if percentage < model.MinVendorPricePercentage || percentage > model.MaxVendorPricePercentage { percentage = model.DefVendorPricePercentage @@ -287,65 +251,6 @@ func CaculateSkuPriceFromVendor(vendorPrice, percentage, priceAdd int) (price in return price } -func GetPricePercentage(l model.PricePercentagePack, price int, defPricePercentage int) (pricePercentage, priceAdd int) { - pricePercentage = defPricePercentage - itemLen := len(l) - if itemLen > 0 { - low := 0 - high := itemLen - 1 - mid := 0 - for low <= high { - mid = low + (high-low)/2 - if mid < 0 || mid >= itemLen-1 { - break - } - if price >= l[mid].BeginPrice { - if price < l[mid+1].BeginPrice { - break - } else { - low = mid + 1 - } - } else { - high = mid - 1 - } - } - if mid >= 0 && mid <= itemLen-1 && low <= high { - pricePercentage = l[mid].PricePercentage - priceAdd = l[mid].PriceAdd - } - } - return pricePercentage, priceAdd -} - -func GetPricePercentageByVendorPrice(l model.PricePercentagePack, vendorPrice int, defPricePercentage int) (pricePercentage, priceAdd int) { - pricePercentage = defPricePercentage - if len(l) > 0 { - var lastItem *model.PricePercentageItem - for _, v := range l { - if CaculateSkuVendorPrice(v.BeginPrice, v.PricePercentage, v.PriceAdd) > vendorPrice { - break - } - lastItem = v - } - if lastItem != nil { - pricePercentage = lastItem.PricePercentage - priceAdd = lastItem.PriceAdd - } - } - return pricePercentage, priceAdd -} - -func CaculatePriceByPricePack(l model.PricePercentagePack, defPricePercentage, price int) (outPrice int) { - pricePercentage, priceAdd := GetPricePercentage(l, price, defPricePercentage) - return CaculateSkuVendorPrice(price, pricePercentage, priceAdd) -} - -func CaculateJxPriceByPricePack(l model.PricePercentagePack, defPricePercentage, vendorPrice int) (jxPrice int) { - pricePercentage, priceAdd := GetPricePercentageByVendorPrice(l, vendorPrice, defPricePercentage) - jxPrice = CaculateSkuPriceFromVendor(vendorPrice, pricePercentage, priceAdd) - return jxPrice -} - func ConstrainPayPercentage(payPerCentage int) int { if payPerCentage <= 50 { payPerCentage = 70 @@ -353,10 +258,6 @@ func ConstrainPayPercentage(payPerCentage int) int { return payPerCentage } -func IsSkuSpecial(specQuality float32, specUnit string) bool { - return int(specQuality) == model.SpecialSpecQuality && (specUnit == model.SpecialSpecUnit || specUnit == model.SpecialSpecUnit2) -} - var lastFakeID int64 var lastFakeIDMutex sync.RWMutex @@ -440,28 +341,6 @@ func FormatSkuWeight(specQuality float32, specUnit string) int { return RegularizeSkuQuality(specQuality, specUnit) } -type SkuList []*model.Sku - -func (s SkuList) Len() int { - return len(s) -} - -func (s SkuList) Less(i, j int) bool { - if s[i].NameID == s[j].NameID { - if s[i].SpecUnit == s[j].SpecUnit { - return s[i].SpecQuality < s[j].SpecQuality - } - return s[i].SpecUnit < s[j].SpecUnit - } - return s[i].NameID < s[j].NameID -} - -func (s SkuList) Swap(i, j int) { - tmp := s[i] - s[i] = s[j] - s[j] = tmp -} - func DownloadFileByURL(fileURL string) (bodyData []byte, fileMD5 string, err error) { response, err := http.Get(fileURL) if err == nil { diff --git a/business/model/Store_Alert_Inform.go b/business/model/Store_Alert_Inform.go deleted file mode 100644 index bc9701edd..000000000 --- a/business/model/Store_Alert_Inform.go +++ /dev/null @@ -1,112 +0,0 @@ -package model - -import "time" - -const ( - FieldPickTimeDaDa = "PickTimeDaDa" - FieldBadComment = "BadComment" - FieldAbsentGoods = "AbsentGoods" - FieldPickTimeDaDaOneWeek = "PickTimeDaDaOneWeek" - FieldBadCommentOneWeek = "BadCommentOneWeek" - FieldAbsentGoodsOneWeek = "AbsentGoodsOneWeek" - FieldStandardFinishTimeSelfDelivery = "StandardFinishTimeSelfDelivery" - FieldStandardPickUpTimeDaDa = "StandardPickUpTimeDaDa" - - FieldNoOrderInMonth = "NoOrderInMonth" - FieldRiskOrderCount = "RiskOrderCount" - - FieldYellowStatus = "YellowStatus" - FieldRedStatus = "RedStatus" - FieldExtraRedStatus = "ExtraRedStatus" -) - -const ( - FlagPickTimeDaDa = 1 - FlagBadComment = 2 - FlagAbsentGoods = 4 - FlagPickTimeDaDaOneWeek = 8 - FlagBadCommentOneWeek = 16 - FlagAbsentGoodsOneWeek = 32 - FlagStandardFinishTimeSelfDelivery = 64 - FlagStandardPickUpTimeDaDa = 128 - FlagNoOrderInMonth = 256 - FlagRiskOrderCount = 512 -) - -type StoreAlert struct { - ID int `orm:"column(id)" json:"id"` - CreatedTime time.Time `orm:"auto_now_add;type(datetime)" json:"createdTime"` - AlertDate time.Time `orm:"auto_now_add;type(datetime)" json:"alertDate"` - StoreID int `orm:"column(store_id)" json:"storeID"` - - PickTimeDaDa int `orm:"column(pick_time_order_dada)" json:"pickTimeDaDa"` - BadComment int `orm:"column(bad_comment)" json:"badComment"` - AbsentGoods int `orm:"column(absent_goods)" json:"absentGoods"` - PickTimeDaDaOneWeek int `orm:"column(pick_time_dada_oneweek)" json:"pickTimeDaDaOneWeek"` - BadCommentOneWeek int `orm:"column(bad_comment_oneweek)" json:"badCommentOneWeek"` - AbsentGoodsOneWeek int `orm:"column(absent_goods_oneweek)" json:"absentGoodsOneWeek"` - StandardFinishTimeSelfDelivery int `orm:"column(standard_finish_time_selfdelivery)" json:"standardFinishTimeSelfDelivery"` - StandardPickUpTimeDaDa int `orm:"column(standard_pickup_time_dada)" json:"standardPickUpTimeDaDa"` - - NoOrderInMonth int `json:"noOrderInMonth"` - RiskOrderCount int `json:"riskOrderCount"` - - YellowStatus int - RedStatus int - ExtraRedStatus int -} - -type StoreAlertEx struct { - StoreAlert - StoreName string `orm:"column(store_name)" json:"storeName"` - CityName string `orm:"column(city_name)" json:"cityName"` -} - -type StoreAlertProperty struct { - Value string `json:"value"` - Color string `json:"color"` -} - -type StoreAlertAdvanced struct { - ID int `json:"id"` - CreatedTime time.Time `json:"createdTime"` - AlertDate time.Time `json:"alertDate"` - StoreID int `json:"storeID"` - StoreName string `json:"storeName"` - CityName string `json:"cityName"` - - PickTimeDaDa StoreAlertProperty - BadComment StoreAlertProperty - AbsentGoods StoreAlertProperty - PickTimeDaDaOneWeek StoreAlertProperty - BadCommentOneWeek StoreAlertProperty - AbsentGoodsOneWeek StoreAlertProperty - StandardFinishTimeSelfDelivery StoreAlertProperty - StandardPickUpTimeDaDa StoreAlertProperty - - NoOrderInMonth StoreAlertProperty - RiskOrderCount StoreAlertProperty -} - -type StoreAlertData struct { - StoreAlertList []*StoreAlertAdvanced `json:"storeAlertList"` - TotalCount int `json:"totalCount"` -} - -type StoreOrderTime struct { - StoreID int `orm:"column(store_id)"` - OrderCreateTime time.Time `orm:"column(order_created_at)"` - OrderFinishedTime time.Time `orm:"column(order_finished_at)"` -} - -type StoreOrderStatus struct { - StoreID int `orm:"column(store_id)"` - VendorOrderID string `orm:"column(vendor_order_id)"` - StatusTime time.Time `orm:"column(status_time)"` - Status int `orm:"column(status)"` -} - -type StoreOrder struct { - StoreID int `orm:"column(store_id)"` - VendorOrderID string `orm:"column(vendor_order_id)"` -} diff --git a/business/model/bill.go b/business/model/bill.go index c01b8fe72..e587793a4 100644 --- a/business/model/bill.go +++ b/business/model/bill.go @@ -39,6 +39,7 @@ type UserBill struct { BillID int64 `orm:"column(bill_id)" json:"billID"` //账单ID UserID string `orm:"column(user_id)" json:"userID"` //用户ID AccountBalance int `json:"accountBalance"` //账户余额 + DepositBalance int `json:"DepositBalance"` //保证金余额 } func (v *UserBill) TableIndex() [][]string { diff --git a/business/model/const.go b/business/model/const.go index 8db090d7f..0a8e0fb12 100644 --- a/business/model/const.go +++ b/business/model/const.go @@ -116,13 +116,6 @@ var ( // OperateCopyStoreSkus: "复制门店商品", } - ThingTypeName = map[int]string{ - ThingTypeCategory: "分类", - ThingTypeSku: "门店商品", - ThingTypeSkuName: "商品库", - ThingTypeStore: "门店", - } - ApiFunctionName = map[string]string{ "UpdateStoresSkus": "门店商品管理", "UpdateStoresSkusSale": "门店商品可售状态修改", diff --git a/business/model/dao/Store_Alert_Inform.go b/business/model/dao/Store_Alert_Inform.go deleted file mode 100644 index 690ccc464..000000000 --- a/business/model/dao/Store_Alert_Inform.go +++ /dev/null @@ -1,51 +0,0 @@ -package dao - -import ( - "fmt" - "time" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/model" -) - -func InsertStoreAlert(storeAlert *model.StoreAlert) error { - storeAlert.CreatedTime = time.Now() - return CreateEntity(nil, storeAlert) -} - -func GetStoreAlertList(db *DaoDB, storeIDList []int, cityCode int, keyWord string, dateTime time.Time) (storeAlertList []*model.StoreAlertEx, err error) { - sql := ` - SELECT t1.*, t2.name store_name, t3.name city_name - FROM store_alert t1 - JOIN store t2 ON t1.store_id = t2.id - JOIN place t3 ON t2.city_code = t3.code - WHERE t1.alert_date >= ? AND t1.alert_date <= ? - ` - beginTime, endTime := utils.GetTimeRange(dateTime, 1, true) - sqlParams := []interface{}{ - beginTime, - endTime, - } - if len(storeIDList) > 0 { - sql += ` - AND t2.id in (` + GenQuestionMarks(len(storeIDList)) + `)` - sqlParams = append(sqlParams, storeIDList) - } - if cityCode > 0 { - sql += ` - AND t3.code = ?` - sqlParams = append(sqlParams, cityCode) - } - if keyWord != "" { - sql += ` - AND (t2.id LIKE ? OR t2.name LIKE ? OR t3.name LIKE ?)` - keyWord = fmt.Sprintf("%%%s%%", keyWord) - sqlParams = append(sqlParams, keyWord, keyWord, keyWord) - } - sql += ` - ORDER BY t1.store_id - ` - err = GetRows(db, &storeAlertList, sql, sqlParams) - - return storeAlertList, err -} diff --git a/business/model/dao/act.go b/business/model/dao/act.go index a40220d8d..1dbd1692c 100644 --- a/business/model/dao/act.go +++ b/business/model/dao/act.go @@ -72,90 +72,90 @@ func GetActVendorInfo(db *DaoDB, actID int, vendorIDs []int) (actMap map[int]*mo } func GetActStoreSkuVendorList(db *DaoDB, actID int, vendorIDs, storeIDs, skuIDs []int, keyword string, offset, pageSize int) (totalCount int, actStoreSkuList []*model.ActStoreSku2, err error) { - globals.SugarLogger.Debugf("GetActStoreSkuVendorList actID:%d", actID) - offset = jxutils.FormalizePageOffset(offset) - pageSize = jxutils.FormalizePageSize(pageSize) + // globals.SugarLogger.Debugf("GetActStoreSkuVendorList actID:%d", actID) + // offset = jxutils.FormalizePageOffset(offset) + // pageSize = jxutils.FormalizePageSize(pageSize) - leftOrEmpty := "" - if len(vendorIDs) == 1 && (vendorIDs[0] == -1 || vendorIDs[0] == model.VendorIDJX) { - leftOrEmpty = "LEFT" - } - sql := fmt.Sprintf(` - SELECT SQL_CALC_FOUND_ROWS - t1.*, - t2.id map_id, t2.vendor_id, t2.vendor_act_id, t2.sync_status, t2.actual_act_price, t2.vendor_price, t2.trend_type, t2.trend_price, - t3.vendor_store_id, - CASE t2.vendor_id - WHEN 0 THEN - t4m.vendor_thing_id - WHEN 1 THEN - t5.mtwm_id - WHEN 3 THEN - t5.ebai_id - ELSE - '' - END vendor_sku_id, - t4.comment, t4.spec_quality, t4.spec_unit, - t6.name store_name, - t7.name sku_name_name, t7.unit, t7.prefix, t7.ex_prefix, t7.ex_prefix_begin, t7.ex_prefix_end - FROM act_store_sku t1 - %s JOIN act_store_sku_map t2 ON t2.act_id = ? AND t2.bind_id = t1.id AND t2.deleted_at = ?`, leftOrEmpty) - sqlParams := []interface{}{ - actID, - utils.DefaultTimeValue, - } + // leftOrEmpty := "" + // if len(vendorIDs) == 1 && (vendorIDs[0] == -1 || vendorIDs[0] == model.VendorIDJX) { + // leftOrEmpty = "LEFT" + // } + // sql := fmt.Sprintf(` + // SELECT SQL_CALC_FOUND_ROWS + // t1.*, + // t2.id map_id, t2.vendor_id, t2.vendor_act_id, t2.sync_status, t2.actual_act_price, t2.vendor_price, t2.trend_type, t2.trend_price, + // t3.vendor_store_id, + // CASE t2.vendor_id + // WHEN 0 THEN + // t4m.vendor_thing_id + // WHEN 1 THEN + // t5.mtwm_id + // WHEN 3 THEN + // t5.ebai_id + // ELSE + // '' + // END vendor_sku_id, + // t4.comment, t4.spec_quality, t4.spec_unit, + // t6.name store_name, + // t7.name sku_name_name, t7.unit, t7.prefix, t7.ex_prefix, t7.ex_prefix_begin, t7.ex_prefix_end + // FROM act_store_sku t1 + // %s JOIN act_store_sku_map t2 ON t2.act_id = ? AND t2.bind_id = t1.id AND t2.deleted_at = ?`, leftOrEmpty) + // sqlParams := []interface{}{ + // actID, + // utils.DefaultTimeValue, + // } - if len(vendorIDs) > 0 { - sql += " AND t2.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" - sqlParams = append(sqlParams, vendorIDs) - } - sql += ` - LEFT JOIN store_map t3 ON t3.store_id = t1.store_id AND t3.vendor_id = t2.vendor_id AND t3.deleted_at = ? - JOIN sku t4 ON t4.id = t1.sku_id - LEFT JOIN thing_map t4m ON t4m.vendor_id = ? AND t4m.thing_id = t4.id AND t4m.thing_type = ? AND t4m.vendor_id = t2.vendor_id AND t4m.vendor_org_code = t3.vendor_org_code AND t4m.deleted_at = ? - LEFT JOIN store_sku_bind t5 ON t5.sku_id = t1.sku_id AND t5.store_id = t1.store_id AND t5.deleted_at = ? - LEFT JOIN store t6 ON t6.id = t1.store_id - JOIN sku_name t7 ON t7.id = t4.name_id - WHERE t1.act_id = ? - ` - sqlParams = append(sqlParams, - utils.DefaultTimeValue, - model.VendorIDJD, model.ThingTypeSku, utils.DefaultTimeValue, - utils.DefaultTimeValue, - actID, - ) - if keyword != "" { - keywordLike := "%" + keyword + "%" - sql += " AND (t7.name LIKE ? OR t6.name LIKE ?" - sqlParams = append(sqlParams, keywordLike, keywordLike) - if intKeyword := int(utils.Str2Int64WithDefault(keyword, 0)); intKeyword > 0 { - sql += " OR t1.sku_id = ? OR t1.store_id = ?" - sqlParams = append(sqlParams, intKeyword, intKeyword) - } - sql += ")" - } - if leftOrEmpty != "" { - sql += " AND t1.deleted_at = ?" - sqlParams = append(sqlParams, utils.DefaultTimeValue) - } - if len(storeIDs) > 0 { - sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - if len(skuIDs) > 0 { - sql += " AND t1.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" - sqlParams = append(sqlParams, skuIDs) - } - sql += " LIMIT ? OFFSET ?;" - sqlParams = append(sqlParams, pageSize, offset) - // globals.SugarLogger.Debug(sql) - // globals.SugarLogger.Debug(utils.Format4Output(sqlParams, false)) - // globals.SugarLogger.Debug(utils.Format4Output(actStoreSkuList, false)) - Begin(db) - defer Commit(db) - if err = GetRows(db, &actStoreSkuList, sql, sqlParams...); err == nil { - totalCount = GetLastTotalRowCount(db) - } + // if len(vendorIDs) > 0 { + // sql += " AND t2.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" + // sqlParams = append(sqlParams, vendorIDs) + // } + // sql += ` + // LEFT JOIN store_map t3 ON t3.store_id = t1.store_id AND t3.vendor_id = t2.vendor_id AND t3.deleted_at = ? + // JOIN sku t4 ON t4.id = t1.sku_id + // LEFT JOIN thing_map t4m ON t4m.vendor_id = ? AND t4m.thing_id = t4.id AND t4m.thing_type = ? AND t4m.vendor_id = t2.vendor_id AND t4m.vendor_org_code = t3.vendor_org_code AND t4m.deleted_at = ? + // LEFT JOIN store_sku_bind t5 ON t5.sku_id = t1.sku_id AND t5.store_id = t1.store_id AND t5.deleted_at = ? + // LEFT JOIN store t6 ON t6.id = t1.store_id + // JOIN sku_name t7 ON t7.id = t4.name_id + // WHERE t1.act_id = ? + // ` + // sqlParams = append(sqlParams, + // utils.DefaultTimeValue, + // model.VendorIDJD, model.ThingTypeSku, utils.DefaultTimeValue, + // utils.DefaultTimeValue, + // actID, + // ) + // if keyword != "" { + // keywordLike := "%" + keyword + "%" + // sql += " AND (t7.name LIKE ? OR t6.name LIKE ?" + // sqlParams = append(sqlParams, keywordLike, keywordLike) + // if intKeyword := int(utils.Str2Int64WithDefault(keyword, 0)); intKeyword > 0 { + // sql += " OR t1.sku_id = ? OR t1.store_id = ?" + // sqlParams = append(sqlParams, intKeyword, intKeyword) + // } + // sql += ")" + // } + // if leftOrEmpty != "" { + // sql += " AND t1.deleted_at = ?" + // sqlParams = append(sqlParams, utils.DefaultTimeValue) + // } + // if len(storeIDs) > 0 { + // sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" + // sqlParams = append(sqlParams, storeIDs) + // } + // if len(skuIDs) > 0 { + // sql += " AND t1.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" + // sqlParams = append(sqlParams, skuIDs) + // } + // sql += " LIMIT ? OFFSET ?;" + // sqlParams = append(sqlParams, pageSize, offset) + // // globals.SugarLogger.Debug(sql) + // // globals.SugarLogger.Debug(utils.Format4Output(sqlParams, false)) + // // globals.SugarLogger.Debug(utils.Format4Output(actStoreSkuList, false)) + // Begin(db) + // defer Commit(db) + // if err = GetRows(db, &actStoreSkuList, sql, sqlParams...); err == nil { + // totalCount = GetLastTotalRowCount(db) + // } return totalCount, actStoreSkuList, err } @@ -607,67 +607,3 @@ func GetStoresSkusAct(db *DaoDB, hintActID int, mustDirty bool, storeIDs, skuIDs err = GetRows(db, &storeSkuActList, sql, sqlParams...) return storeSkuActList, err } - -func GetStoresSkusAndActInfo(db *DaoDB, storeIDs, skuIDs, vendorIDs []int, minActPercentage, maxActPercentage int) (storeSkuAndActList []*StoreSkuAndAct, err error) { - storeSkuList, err := GetStoresSkusInfo(db, storeIDs, skuIDs) - if err == nil && len(storeSkuList) > 0 { - storeSkuActList, err2 := GetStoresSkusAct(db, 0, false, storeIDs, skuIDs, vendorIDs, false, minActPercentage, maxActPercentage) - if err = err2; err == nil { - actMap := make(map[int64][]*model.StoreSkuAct) - for _, v := range storeSkuActList { - actMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] = append(actMap[jxutils.Combine2Int(v.StoreID, v.SkuID)], v) - } - for _, v := range storeSkuList { - storeSkuAct := &StoreSkuAndAct{ - StoreSkuBind: v, - ActMap: make(map[int]*model.StoreSkuAct), - } - for _, vv := range actMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] { - storeSkuAct.ActMap[vv.VendorID] = vv - } - storeSkuAndActList = append(storeSkuAndActList, storeSkuAct) - } - } - } - return storeSkuAndActList, err -} - -// func GetConflictStoreSkuActInfo(db *DaoDB, vendorIDs []int, inStoreSkuActList []*model.StoreSkuAct) (outStoreSkuActList []*model.StoreSkuAct, err error) { -// storeIDMap := make(map[int]int) -// skuIDMap := make(map[int]int) -// inStoreSkuActMap := make(map[int64]*model.StoreSkuAct) -// for _, v := range inStoreSkuActList { -// storeIDMap[v.StoreID] = 1 -// skuIDMap[v.SkuID] = 1 -// inStoreSkuActMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] = v -// } -// storeIDs := jxutils.IntMap2List(storeIDMap) -// skuIDs := jxutils.IntMap2List(skuIDMap) - -// sql := ` -// SELECT * -// FROM store_sku_act t1 -// WHERE -// t1.store_id IN (` + GenQuestionMarks(len(storeIDs)) + `) -// AND t1.sku_id IN (` + GenQuestionMarks(len(skuIDs)) + `) -// ` -// sqlParams := []interface{}{ -// storeIDs, -// skuIDs, -// } -// if len(vendorIDs) > 0 { -// sql += ` AND t1.vendor_Id IN (` + GenQuestionMarks(len(storeIDs)) + `)` -// sqlParams = append(sqlParams, vendorIDs) -// } - -// var tmpStoreSkuActList []*model.StoreSkuAct -// if err = GetRows(db, &tmpStoreSkuActList, sql, sqlParams...); err == nil { -// for _, v := range tmpStoreSkuActList { -// tmpStoreSkuAct := inStoreSkuActMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] -// if tmpStoreSkuAct != nil && (tmpStoreSkuAct.ActualActPrice > 0 && v.ActID != 0 && v.SyncStatus == 0 || tmpStoreSkuAct.EarningPrice > 0 && v.EarningActID != 0) { -// outStoreSkuActList = append(outStoreSkuActList, v) -// } -// } -// } -// return outStoreSkuActList, err -// } diff --git a/business/model/dao/dao_order.go b/business/model/dao/dao_order.go index c46002c47..07a0cc0fc 100644 --- a/business/model/dao/dao_order.go +++ b/business/model/dao/dao_order.go @@ -1,1480 +1 @@ package dao - -import ( - "fmt" - "strconv" - "time" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/globals" -) - -const ( - AfsOrderStatus = -1 -) - -type StoresOrderSaleInfo struct { - StoreID int `orm:"column(store_id)" json:"storeID"` - VendorID int `orm:"column(vendor_id)" json:"vendorID"` - Status int `json:"status"` - - Count int `json:"count"` - ShopPrice int64 `json:"shopPrice"` - VendorPrice int64 `json:"vendorPrice"` - SalePrice int64 `json:"salePrice"` - ActualPayPrice int64 `json:"actualPayPrice"` - - EarningPrice int64 `json:"earningPrice"` // 预估结算给门店老板的钱 - NewEarningPrice int64 `json:"newEarningPrice"` // 预估结算给门店老板的钱(新规则) - - DistanceFreightMoney int64 `json:"distanceFreightMoney"` // 商户承担的远距离配送费(当前只有京东到家有值) - WaybillTipMoney int64 `json:"waybillTipMoney"` // 京西加的平台配送小费 - - RealEarningPrice int64 `json:"realEarningPrice"` -} - -type OrderSkuWithActualPayPrice struct { - model.OrderSku - - ActualPayPrice int64 `json:"actualPayPrice"` // 单位为分 顾客实际支付 - DistanceFreightMoney int64 `json:"distanceFreightMoney"` // 商户承担的远距离配送费(当前只有京东到家有值) - WaybillTipMoney int64 `json:"waybillTipMoney"` // 京西加的平台配送小费 - - StoreID int `orm:"column(store_id)" json:"storeID"` // 外部系统里记录的 jxstoreid - Status int `json:"status"` // 参见OrderStatus*相关的常量定义 - - PayPercentage int `json:"payPercentage"` - NewEarningPrice int64 `json:"newEarningPrice"` - EarningType int `json:"earningType"` -} - -type tGoodsAndOrder struct { - model.GoodsOrder - OrderSkuID int64 `orm:"column(order_sku_id)" json:"orderSkuID"` - StoreSubID int `orm:"column(store_sub_id)" json:"storeSubID"` // 当前这个字段被当成结算活动ID用 - StoreSubName string `orm:"size(64)" json:"storeSubName"` // 当前这个字段被用作vendorActType - Count int `json:"count"` - VendorSkuID string `orm:"column(vendor_sku_id);size(48)" json:"vendorSkuID"` - SkuID int `orm:"column(sku_id)" json:"skuID"` // 外部系统里记录的 jxskuid - JxSkuID int `orm:"column(jx_sku_id)" json:"jxSkuID"` // 根据VendorSkuID在本地系统里查询出来的 jxskuid - SkuName string `orm:"size(255)" json:"skuName"` - SkuShopPrice int64 `json:"shopPrice"` // 京西价 - SkuVendorPrice int64 `json:"vendorPrice"` // 平台价 - SkuSalePrice int64 `json:"salePrice"` // 售卖价 - SkuEarningPrice int64 `json:"earningPrice"` // 活动商品设置,结算给门店老板的钱,如果结算活动ID为0,是按结算比例算的,否则就是结算表中的值 - Weight int `json:"weight"` // 单位为克 - SkuType int `json:"skuType"` // 当前如果为gift就为1,否则缺省为0 - PromotionType int `json:"promotionType"` // todo 当前是用于记录京东的PromotionType(生成jxorder用),没有做转换 -} - -type GoodsOrderPay struct { - model.GoodsOrder - TransactionID string `orm:"column(transaction_id)" json:"transactionID"` -} - -//actID指结算活动的id -func QueryOrders(db *DaoDB, vendorOrderID string, actID int, vendorIDs []int, storeID int, fromDate, toDate time.Time) (orderList []*model.GoodsOrder, err error) { - sqlParams := []interface{}{} - var ( - orderNewList []*tGoodsAndOrder - orderNewMap map[string][]*model.OrderSku - ) - sql := ` - SELECT a.*, - b.id order_sku_id, b.store_sub_id, b.store_sub_name, b.count, b.vendor_sku_id, b.sku_id, b.jx_sku_id, b.sku_name, b.shop_price sku_shop_price, - b.vendor_price sku_vendor_price, b.sale_price sku_sale_price, b.earning_price sku_earning_price, b.weight, b.sku_type, b.promotion_type - FROM goods_order a - JOIN order_sku b ON a.vendor_order_id = b.vendor_order_id - ` - if actID > 0 { - sql += ` - JOIN ( SELECT t4.vendor_order_id, t4.vendor_id - FROM act t1 - JOIN act_store_sku t2 ON t2.act_id = t1.id - JOIN order_sku t3 ON t3.sku_id = t2.sku_id - JOIN goods_order t4 ON t4.vendor_order_id = t3.vendor_order_id - AND t4.vendor_id = t3.vendor_id - AND t2.store_id = IF(t4.jx_store_id <> 0, t4.jx_store_id, t4.store_id) - AND t4.order_created_at BETWEEN t1.begin_at AND t1.end_at - WHERE t1.status = 1 - AND t1.id = ? - GROUP BY 1,2 - )s ON s.vendor_order_id = a.vendor_order_id AND s.vendor_id = a.vendor_id - ` - sqlParams = append(sqlParams, actID) - } - sql += ` - WHERE 1=1 - ` - if vendorOrderID != "" { - sql += " AND a.vendor_order_id = ?" - sqlParams = append(sqlParams, vendorOrderID) - } - if len(vendorIDs) > 0 { - sql += " AND a.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" - sqlParams = append(sqlParams, vendorIDs) - } - if storeID > 0 { - sql += " AND IF(a.jx_store_id <> 0, a.jx_store_id, a.store_id) = ?" - sqlParams = append(sqlParams, storeID) - } - if !utils.IsTimeZero(fromDate) && !utils.IsTimeZero(toDate) { - sql += " AND a.order_created_at BETWEEN ? AND ?" - sqlParams = append(sqlParams, fromDate, toDate) - } - err = GetRows(db, &orderNewList, sql, sqlParams...) - if len(orderNewList) > 0 { - orderNewMap = make(map[string][]*model.OrderSku) - for _, v := range orderNewList { - if orderNewMap[v.VendorOrderID] == nil { - orderList = append(orderList, &v.GoodsOrder) - } - orderNewMap[v.VendorOrderID] = append(orderNewMap[v.VendorOrderID], &model.OrderSku{ - ID: v.OrderSkuID, - VendorOrderID: v.VendorOrderID, - VendorID: v.VendorID, - StoreSubID: v.StoreSubID, - StoreSubName: v.StoreSubName, - Count: v.Count, - VendorSkuID: v.VendorSkuID, - SkuID: v.SkuID, - JxSkuID: v.JxSkuID, - SkuName: v.SkuName, - ShopPrice: v.SkuShopPrice, - VendorPrice: v.SkuVendorPrice, - SalePrice: v.SkuSalePrice, - EarningPrice: v.SkuEarningPrice, - Weight: v.Weight, - SkuType: v.SkuType, - PromotionType: v.PromotionType, - }) - } - for _, v := range orderList { - v.Skus = orderNewMap[v.VendorOrderID] - } - } - - return orderList, err -} - -// func QueryOrders(db *DaoDB, vendorOrderID string, vendorIDs []int, storeID int, orderCreatedAtBegin, orderCreatedAtEnd time.Time) (orderList []*model.GoodsOrder, err error) { -// sql := ` -// SELECT t1.* -// FROM goods_order t1 -// WHERE t1.order_created_at >= ?` -// sqlParams := []interface{}{ -// orderCreatedAtBegin, -// } -// if vendorOrderID != "" { -// sql += " AND t1.vendor_order_id = ?" -// sqlParams = append(sqlParams, vendorOrderID) -// } -// if len(vendorIDs) > 0 { -// sql += " AND t1.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" -// sqlParams = append(sqlParams, vendorIDs) -// } -// if storeID > 0 { -// sql += " AND IF(t1.jx_store_id <> 0, t1.jx_store_id, t1.store_id) = ?" -// sqlParams = append(sqlParams, storeID) -// } -// if !utils.IsTimeZero(orderCreatedAtEnd) { -// sql += " AND t1.order_created_at <= ?" -// sqlParams = append(sqlParams, orderCreatedAtEnd) -// } -// // sql += " ORDER BY t1.order_created_at DESC, t1.id DESC;" -// return orderList, GetRows(db, &orderList, sql, sqlParams...) -// } - -func GetStoreOrderAfterTime(db *DaoDB, storeID int, orderTime time.Time, lastOrderSeqID int64) (orderList []*model.GoodsOrderExt, err error) { - sql := ` - SELECT t1.*, - t2.status waybill_status, t2.courier_name, t2.courier_mobile, - t2.actual_fee, t2.desired_fee, t2.waybill_created_at, t2.waybill_finished_at - FROM goods_order t1 - LEFT JOIN waybill t2 ON t1.vendor_waybill_id = t2.vendor_waybill_id AND t1.waybill_vendor_id = t2.waybill_vendor_id - WHERE IF(t1.jx_store_id <> 0, t1.jx_store_id, t1.store_id) = ? AND t1.order_created_at >= ? AND t1.id > ? AND t1.status >= ? AND t1.status < ? - AND (t1.flag & ?) = 0 - ORDER BY t1.order_created_at DESC, t1.id DESC; - ` - sqlParams := []interface{}{ - storeID, - orderTime, - lastOrderSeqID, - model.OrderStatusNew, - model.OrderStatusEndBegin, - model.OrderFlagMaskFake, - } - return orderList, GetRows(db, &orderList, sql, sqlParams...) -} - -func SetOrderPrintFlag(db *DaoDB, userName string, vendorOrderID string, vendorID int, isPrinted bool) (err error) { - if isPrinted { - err = SetOrderFlag(db, userName, vendorOrderID, vendorID, model.OrderFlagMaskPrinted) - } else { - err = SetOrderFlag(db, userName, vendorOrderID, vendorID, ^model.OrderFlagMaskPrinted) - } - return err -} - -func SetOrderFlag(db *DaoDB, userName string, vendorOrderID string, vendorID int, flag int) (err error) { - _, err = ExecuteSQL(db, ` - UPDATE goods_order - SET flag = flag | ? - WHERE vendor_order_id = ? AND vendor_id = ? - `, flag, vendorOrderID, vendorID) - return err -} - -func ClearOrderFlag(db *DaoDB, userName string, vendorOrderID string, vendorID int, flag int) (err error) { - _, err = ExecuteSQL(db, ` - UPDATE goods_order - SET flag = flag & ? - WHERE vendor_order_id = ? AND vendor_id = ? - `, ^flag, vendorOrderID, vendorID) - return err -} - -func ClearOrderFlag2(db *DaoDB, userName string, vendorOrderID string, vendorID int, flag int) (err error) { - _, err = ExecuteSQL(db, ` - UPDATE goods_order - SET flag = ? - WHERE vendor_order_id = ? AND vendor_id = ? - `, flag, vendorOrderID, vendorID) - return err -} - -func SetAfsOrderFlag(db *DaoDB, userName string, afsOrderID string, vendorID int, flag int) (err error) { - _, err = ExecuteSQL(db, ` - UPDATE afs_order - SET flag = flag | ? - WHERE afs_order_id = ? AND vendor_id = ? - `, flag, afsOrderID, vendorID) - return err -} - -func GetAfsOrders(db *DaoDB, vendorID int, vendorOrderID, afsOrderID string) (afsOrderList []*model.AfsOrder, err error) { - sql := ` - SELECT * - FROM afs_order t1 - WHERE t1.vendor_id = ? - ` - sqlParams := []interface{}{ - vendorID, - } - if vendorOrderID != "" { - sql += " AND t1.vendor_order_id = ?" - sqlParams = append(sqlParams, vendorOrderID) - } - if afsOrderID != "" { - sql += " AND t1.afs_order_id = ?" - sqlParams = append(sqlParams, afsOrderID) - } - sql += " ORDER BY t1.afs_order_id DESC" - err = GetRows(db, &afsOrderList, sql, sqlParams...) - return afsOrderList, err -} - -// 时间范围是订单完成时间 -func GetStoresOrderSaleInfo(db *DaoDB, storeIDList []int, fromTime time.Time, toTime time.Time, statusList []int) (saleInfoList []*StoresOrderSaleInfo, err error) { - if utils.IsTimeZero(fromTime) { - return nil, fmt.Errorf("查询订单信息必须指定起始时间") - } - if utils.IsTimeZero(toTime) { - toTime = time.Now() - } - if toTime.Sub(fromTime) > time.Hour*24*60 { - return nil, fmt.Errorf("查询时间范围不能超过60天") - } - - // 用int64类型去取float型的数据库返回值,会取不到 - // order_finished_at - sql := fmt.Sprintf(` - SELECT IF(t1.jx_store_id > 0, t1.jx_store_id, t1.store_id) store_id, t1.vendor_id, IF(t1.status < ?, 0, t1.status) status, - COUNT(*) count, SUM(t1.shop_price) shop_price, SUM(t1.vendor_price) vendor_price, SUM(t1.sale_price) sale_price, SUM(t1.actual_pay_price) actual_pay_price, - CAST(SUM(IF(t1.earning_price <> 0, t1.earning_price, IF(t1.shop_price <> 0 && t1.shop_price < t1.sale_price, t1.shop_price, t1.sale_price) * IF(t5.pay_percentage > 0, t5.pay_percentage, %d) / 100)) AS SIGNED) earning_price - FROM goods_order t1 - LEFT JOIN store t5 ON t5.id = IF(t1.jx_store_id <> 0, t1.jx_store_id, t1.store_id) - WHERE t1.order_created_at >= ? AND t1.order_created_at <= ? - `, model.DefaultEarningPricePercentage) - sqlParams := []interface{}{ - model.OrderStatusEndBegin, - fromTime, - toTime, - } - if len(storeIDList) > 0 { - sql += " AND IF(t1.jx_store_id > 0, t1.jx_store_id, t1.store_id) IN (" + GenQuestionMarks(len(storeIDList)) + ")" - sqlParams = append(sqlParams, storeIDList) - } - if len(statusList) > 0 { - sql += " AND t1.status IN (" + GenQuestionMarks(len(statusList)) + ")" - sqlParams = append(sqlParams, statusList) - } - sql += ` - GROUP BY 1,2,3` - sql += fmt.Sprintf(` - UNION - SELECT IF(t0.jx_store_id > 0, t0.jx_store_id, t0.store_id) store_id, t0.vendor_id, -1 status, - COUNT(DISTINCT(t0.id)) count, SUM(t1.shop_price) shop_price, SUM(t1.vendor_price) vendor_price, SUM(t1.sale_price) sale_price, 0 actual_pay_price, - CAST(SUM(IF(t1.earning_price <> 0, t1.earning_price, IF(t1.shop_price <> 0 && t1.shop_price < t1.sale_price, t1.shop_price, t1.sale_price) * IF(t5.pay_percentage > 0, t5.pay_percentage, %d) / 100)) AS SIGNED) earning_price - FROM afs_order t0 - JOIN order_sku_financial t2 ON t2.afs_order_id = t0.afs_order_id AND t2.vendor_id = t0.vendor_id AND t2.is_afs_order = 1 - JOIN order_sku t1 ON t1.vendor_order_id = t2.vendor_order_id AND t1.vendor_id = t2.vendor_id AND t1.sku_id = t2.sku_id - LEFT JOIN store t5 ON t5.id = IF(t0.jx_store_id <> 0, t0.jx_store_id, t0.store_id) - WHERE t0.afs_finished_at >= ? AND t0.afs_finished_at <= ?`, model.DefaultEarningPricePercentage) - sqlParams = append(sqlParams, []interface{}{ - fromTime, - toTime, - }) - if len(storeIDList) > 0 { - sql += " AND IF(t0.jx_store_id > 0, t0.jx_store_id, t0.store_id) IN (" + GenQuestionMarks(len(storeIDList)) + ")" - sqlParams = append(sqlParams, storeIDList) - } - sql += ` - GROUP BY 1,2,3` - - sql += " ORDER BY 1,2,3" - // globals.SugarLogger.Debug(sql) - err = GetRows(db, &saleInfoList, sql, sqlParams...) - return saleInfoList, err -} - -func GetAfsOrderSkuInfo(db *DaoDB, vendorOrderID, afsOrderID string, vendorID int, isNotFaild bool) (skus []*model.OrderFinancialSkuExt, err error) { - if vendorOrderID == "" && afsOrderID == "" { - return nil, fmt.Errorf("必须指定订单或售后单ID") - } - sql := ` - SELECT t1.*, t3.img image - FROM order_sku_financial t1 - LEFT JOIN sku t2 ON t2.id = IF(t1.jx_sku_id <> 0, t1.jx_sku_id, t1.sku_id) - LEFT JOIN sku_name t3 ON t3.id = t2.name_id - LEFT JOIN afs_order t4 ON t4.afs_order_id = t1.afs_order_id - WHERE t1.is_afs_order = 1 AND t1.vendor_id = ?` - sqlParams := []interface{}{ - vendorID, - } - - if vendorOrderID != "" { - sql += " AND t1.vendor_order_id = ?" - sqlParams = append(sqlParams, vendorOrderID) - } - if afsOrderID != "" { - sql += " AND t1.afs_order_id = ?" - sqlParams = append(sqlParams, afsOrderID) - } - if isNotFaild { - sql += " AND t4.status <> ?" - sqlParams = append(sqlParams, model.AfsOrderStatusFailed) - } - err = GetRows(db, &skus, sql, sqlParams...) - return skus, err -} - -func GetStoreOrderSkuList(db *DaoDB, storeIDs []int, finishedAtBegin, finishedAtEnd time.Time, statusList []int, isFinish bool) (skuList []*OrderSkuWithActualPayPrice, err error) { - // order_finished_at - sql := ` - SELECT t1.*, - IF(t2.jx_store_id > 0, t2.jx_store_id, t2.store_id) store_id, t2.status, t2.actual_pay_price, t2.distance_freight_money, t2.waybill_tip_money, t2.new_earning_price, - t3.pay_percentage, t2.earning_type - FROM order_sku t1 - JOIN goods_order t2 ON t2.vendor_order_id = t1.vendor_order_id AND t2.vendor_id = t1.vendor_id - LEFT JOIN store t3 ON t3.id = IF(t2.jx_store_id > 0, t2.jx_store_id, t2.store_id) - WHERE 1=1` - if isFinish { - sql += " AND t2.order_finished_at >= ? AND t2.order_finished_at <= ?" - } else { - sql += " AND t2.order_created_at >= ? AND t2.order_created_at <= ?" - } - sqlParams := []interface{}{ - finishedAtBegin, - finishedAtEnd, - } - if len(storeIDs) > 0 { - sql += " AND IF(t2.jx_store_id > 0, t2.jx_store_id, t2.store_id) IN (" + GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - if len(statusList) > 0 { - sql += " AND t2.status IN (" + GenQuestionMarks(len(statusList)) + ")" - sqlParams = append(sqlParams, statusList) - } - err = GetRows(db, &skuList, sql, sqlParams...) - return skuList, err -} - -func GetStoreOrderSkuList4Afs(db *DaoDB, storeIDs []int, finishedAtBegin, finishedAtEnd time.Time, isFinish bool) (skuList []*OrderSkuWithActualPayPrice, err error) { - sql := ` - SELECT t1.*, - t2.actual_pay_price, t2.status, IF(t2.jx_store_id > 0, t2.jx_store_id, t2.store_id) store_id, t2.new_earning_price, - t3.pay_percentage - FROM order_sku t1 - JOIN goods_order t2 ON t2.vendor_order_id = t1.vendor_order_id AND t2.vendor_id = t1.vendor_id - LEFT JOIN store t3 ON t3.id = IF(t2.jx_store_id > 0, t2.jx_store_id, t2.store_id) - JOIN ( - SELECT t12.* - FROM afs_order t12 - WHERE IF(t12.jx_store_id > 0, t12.jx_store_id, t12.store_id) IN (` + GenQuestionMarks(len(storeIDs)) - if isFinish { - sql += ") AND t12.afs_finished_at >= ? AND t12.afs_finished_at <= ?" - } else { - sql += ") AND t12.afs_created_at >= ? AND t12.afs_created_at <= ?" - } - sql += ") t4 ON t4.vendor_order_id = t2.vendor_order_id AND t4.vendor_id = t2.vendor_id" - sqlParams := []interface{}{ - storeIDs, - finishedAtBegin, - finishedAtEnd, - } - err = GetRows(db, &skuList, sql, sqlParams...) - return skuList, err -} - -func GetStoreAfsOrderSkuList(db *DaoDB, storeIDs []int, finishedAtBegin, finishedAtEnd time.Time, statusList []int, isFinish bool) (afsSkuList []*model.OrderSkuFinancial, err error) { - sql := ` - SELECT t1.* - FROM order_sku_financial t1 - JOIN afs_order t2 ON t2.vendor_order_id = t1.vendor_order_id AND t2.vendor_id = t1.vendor_id AND t2.afs_order_id = t1.afs_order_id - WHERE t1.is_afs_order = 1 - ` - if isFinish { - sql += " AND t2.afs_finished_at >= ? AND t2.afs_finished_at <= ?" - } else { - sql += " AND t2.afs_created_at >= ? AND t2.afs_created_at <= ?" - } - sqlParams := []interface{}{ - finishedAtBegin, - finishedAtEnd, - } - if len(storeIDs) > 0 { - sql += " AND IF(t2.jx_store_id > 0, t2.jx_store_id, t2.store_id) IN (" + GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - if len(statusList) > 0 { - sql += " AND t2.status IN (" + GenQuestionMarks(len(statusList)) + ")" - sqlParams = append(sqlParams, statusList) - } - err = GetRows(db, &afsSkuList, sql, sqlParams...) - return afsSkuList, err -} - -func GetDailyFinishOrderList(db *DaoDB, storeID int, dateTime time.Time) (orderList []*model.OrderPickupTime, err error) { - sql := ` - SELECT t2.status_time, t1.pick_deadline - FROM goods_order t1 - JOIN order_status t2 ON t1.vendor_order_id = t2.vendor_order_id AND t1.vendor_id = t2.vendor_id - WHERE t1.jx_store_id = ? AND t2.order_type = ? AND t2.status = ? AND DATE(t1.order_finished_at) = DATE(?) - ` - sqlParams := []interface{}{ - storeID, - model.OrderTypeOrder, - model.OrderStatusFinishedPickup, - dateTime, - } - return orderList, GetRows(db, &orderList, sql, sqlParams...) -} - -func GetDailyBadCommentOrderCount(db *DaoDB, dateTime time.Time) (storeCountList []*model.StoreCount, err error) { - beginTime, endTime := utils.GetTimeRange(dateTime, 1, true) - return GetBadCommentOrderCount(db, beginTime, endTime) -} - -func GetBadCommentOrderCountByDayNum(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) { - beginTime, endTime := utils.GetTimeRange(utils.GetCurDate(), dayNum, includeToday) - return GetBadCommentOrderCount(db, beginTime, endTime) -} - -func GetBadCommentOrderCount(db *DaoDB, beginTime, endTime time.Time) (storeCountList []*model.StoreCount, err error) { - sql := ` - SELECT jxstoreid store_id, COUNT(*) count - FROM jx_bad_comments - WHERE createtime >= ? AND createtime <= ? - GROUP BY jxstoreid - ` - sqlParams := []interface{}{ - beginTime, - endTime, - } - err = GetRows(db, &storeCountList, sql, sqlParams) - - return storeCountList, err -} - -func GetDailyUnFinishOrderCount(db *DaoDB, dateTime time.Time) (storeCountList []*model.StoreCount, err error) { - beginTime, endTime := utils.GetTimeRange(dateTime, 1, true) - return GetUnFinishOrderCount(db, beginTime, endTime) -} - -func GetDailyFinishOrderCount(db *DaoDB, dateTime time.Time) (storeCountList []*model.StoreCount, err error) { - beginTime, endTime := utils.GetTimeRange(dateTime, 1, true) - return GetFinishOrderCount(db, beginTime, endTime) -} - -func GetDailyAbsentGoodsOrderCount(db *DaoDB, dateTime time.Time) (storeCountList []*model.StoreCount, err error) { - beginTime, endTime := utils.GetTimeRange(dateTime, 1, true) - return GetAbsentGoodsOrderCount(db, beginTime, endTime) -} - -func GetUnFinishOrderCount(db *DaoDB, beginTime, endTime time.Time) (storeCountList []*model.StoreCount, err error) { - return GetEndOrderCount(db, []int{model.OrderStatusCanceled}, false, beginTime, endTime) -} - -func GetFinishOrderCount(db *DaoDB, beginTime, endTime time.Time) (storeCountList []*model.StoreCount, err error) { - return GetEndOrderCount(db, []int{model.OrderStatusFinished}, false, beginTime, endTime) -} - -func GetAbsentGoodsOrderCount(db *DaoDB, beginTime, endTime time.Time) (storeCountList []*model.StoreCount, err error) { - return GetEndOrderCount(db, []int{model.OrderStatusFinished}, true, beginTime, endTime) -} - -func GetUnFinishOrderCountByDayNum(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) { - return GetEndOrderCountByDayNum(db, []int{model.OrderStatusCanceled}, false, dayNum, includeToday) -} - -func GetFinishOrderCountByDayNum(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) { - return GetEndOrderCountByDayNum(db, []int{model.OrderStatusFinished}, false, dayNum, includeToday) -} - -func GetAbsentGoodsOrderCountByDayNum(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) { - return GetEndOrderCountByDayNum(db, []int{model.OrderStatusFinished}, true, dayNum, includeToday) -} - -func GetEndOrderCountByDayNum(db *DaoDB, statusList []int, checkAbsentOrder bool, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) { - beginTime, endTime := utils.GetTimeRange(utils.GetCurDate(), dayNum, includeToday) - return GetEndOrderCount(db, statusList, checkAbsentOrder, beginTime, endTime) -} - -func GetEndOrderCount(db *DaoDB, statusList []int, checkAbsentOrder bool, beginTime, endTime time.Time) (storeCountList []*model.StoreCount, err error) { - sql := ` - SELECT jx_store_id store_id, COUNT(*) count - FROM goods_order - WHERE order_finished_at >= ? AND order_finished_at <= ? - ` - sqlParams := []interface{}{ - beginTime, - endTime, - } - if len(statusList) > 0 { - sql += ` AND status IN (` + GenQuestionMarks(len(statusList)) + `)` - sqlParams = append(sqlParams, statusList) - } - if checkAbsentOrder { - sql += ` - AND adjust_count > 0 - ` - } - sql += ` - GROUP BY jx_store_id` - err = GetRows(db, &storeCountList, sql, sqlParams) - - return storeCountList, err -} - -func GetFinishOrderCountByDaDa(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) { - return GetFinishOrderCountByWayBillVendorID(db, model.VendorIDDada, dayNum, includeToday) -} - -func GetFinishOrderCountBySelfDelivery(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) { - return GetFinishOrderCountByWayBillVendorID(db, model.VendorIDUnknown, dayNum, includeToday) -} - -//通过运单平台ID来统计完成的订单量 -func GetFinishOrderCountByWayBillVendorID(db *DaoDB, wayBillVendorID, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) { - sql := ` - SELECT jx_store_id store_id, COUNT(*) count - FROM goods_order - where order_finished_at >= ? AND order_finished_at <= ? - AND status = ? - AND waybill_vendor_id = ? - GROUP BY jx_store_id - ` - beginTime, endTime := utils.GetTimeRange(utils.GetCurDate(), dayNum, includeToday) - sqlParams := []interface{}{ - beginTime, - endTime, - model.OrderStatusFinished, - wayBillVendorID, - } - - return storeCountList, GetRows(db, &storeCountList, sql, sqlParams) -} - -//拣货履约订单量, 仅统计达达专送 -func GetStandardPickTimeOrderCountByDaDa(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) { - sql := ` - SELECT t1.jx_store_id store_id, COUNT(*) count - FROM goods_order t1 - JOIN order_status t2 ON t1.vendor_order_id = t2.vendor_order_id AND t1.vendor_id = t2.vendor_id - WHERE t1.order_finished_at >= ? AND t1.order_finished_at <= ? - AND t1.status = ? - AND t1.waybill_vendor_id = ? - AND t2.order_type = ? - AND t2.status = ? - AND t2.status_time <= t1.pick_deadline - GROUP BY t1.jx_store_id - ` - beginTime, endTime := utils.GetTimeRange(utils.GetCurDate(), dayNum, includeToday) - sqlParams := []interface{}{ - beginTime, - endTime, - model.OrderStatusFinished, - model.VendorIDDada, - model.OrderTypeOrder, - model.OrderStatusFinishedPickup, - } - - return storeCountList, GetRows(db, &storeCountList, sql, sqlParams) -} - -//按时履约订单量, 仅统计商家自送门店 -func GetStandardFinishTimeOrderCountBySelfDelivery(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) { - sql := ` - SELECT jx_store_id store_id, order_created_at, order_finished_at - FROM goods_order - WHERE order_finished_at >= ? AND order_finished_at <= ? - AND status = ? - AND waybill_vendor_id = ? - ` - beginTime, endTime := utils.GetTimeRange(utils.GetCurDate(), dayNum, includeToday) - sqlParams := []interface{}{ - beginTime, - endTime, - model.OrderStatusFinished, - model.VendorIDUnknown, - } - - standardTime := int64(3600) - var storeOrderTimeList []*model.StoreOrderTime - storeOrderTimeMapData := make(map[int]int) - err = GetRows(db, &storeOrderTimeList, sql, sqlParams) - if err == nil && len(storeOrderTimeList) > 0 { - for _, value := range storeOrderTimeList { - if value.OrderFinishedTime.Unix()-value.OrderCreateTime.Unix() <= standardTime { - storeOrderTimeMapData[value.StoreID]++ - } - } - for storeID, count := range storeOrderTimeMapData { - storeCountList = append(storeCountList, &model.StoreCount{storeID, count}) - } - } - - return storeCountList, err -} - -//10分钟取货完成订单量, 仅统计达达专送 -func GetStandardPickUpTimeOrderCountByDaDa(db *DaoDB, dayNum int, includeToday bool) (storeCountList []*model.StoreCount, err error) { - sql := ` - SELECT t1.jx_store_id store_id, t1.vendor_order_id, t2.status_time, t2.status - FROM goods_order t1 - JOIN order_status t2 ON t1.vendor_order_id = t2.vendor_order_id AND t1.vendor_id = t2.vendor_id - WHERE t1.order_finished_at >= ? AND t1.order_finished_at <= ? - AND t1.status = ? - AND t1.waybill_vendor_id = ? - AND t2.status in (?, ?) - ORDER BY t1.vendor_order_id, t2.status_time - ` - beginTime, endTime := utils.GetTimeRange(utils.GetCurDate(), dayNum, includeToday) - sqlParams := []interface{}{ - beginTime, - endTime, - model.OrderStatusFinished, - model.VendorIDDada, - model.OrderStatusFinishedPickup, - model.OrderStatusDelivering, - } - - standardTime := int64(600) - var storeOrderStatusList []*model.StoreOrderStatus - storeOrderTimeMapData := make(map[int][]*model.StoreOrderStatus) - err = GetRows(db, &storeOrderStatusList, sql, sqlParams) - if err == nil && len(storeOrderStatusList) > 0 { - for _, value := range storeOrderStatusList { - if storeOrderTimeMapData[value.StoreID] == nil { - storeOrderTimeMapData[value.StoreID] = []*model.StoreOrderStatus{} - } - storeOrderTimeMapData[value.StoreID] = append(storeOrderTimeMapData[value.StoreID], value) - } - for storeID, valueList := range storeOrderTimeMapData { - count := 0 - vendorOrderID := "" - statusBeginTime := int64(0) - statusEndTime := int64(0) - for _, value := range valueList { - if vendorOrderID != value.VendorOrderID { - if statusBeginTime != 0 && statusEndTime != 0 { - if statusEndTime-statusBeginTime <= standardTime { - count++ - } - } - vendorOrderID = value.VendorOrderID - statusBeginTime = int64(0) - statusEndTime = int64(0) - } - if value.Status == model.OrderStatusFinishedPickup { - statusBeginTime = value.StatusTime.Unix() - } else if value.Status == model.OrderStatusDelivering { - statusEndTime = value.StatusTime.Unix() - } - } - if statusBeginTime != 0 && statusEndTime != 0 { - if statusEndTime-statusBeginTime <= standardTime { - count++ - } - } - if count > 0 { - storeCountList = append(storeCountList, &model.StoreCount{storeID, count}) - } - } - } - - return storeCountList, err -} - -//风控定单(门店相关人员在自己的门店下单) -func GetRiskOrderCount(db *DaoDB, dayNum int, includeToday bool) (storeOrderList []*model.StoreOrder, err error) { - sql := ` - SELECT t1.jx_store_id store_id, t1.vendor_order_id - FROM goods_order t1 - JOIN store t2 ON t2.id = t1.jx_store_id - WHERE t1.order_finished_at >= ? AND t1.order_finished_at <= ? - AND t1.consignee_mobile2 <> "" - AND (t1.consignee_mobile2 = t2.tel1 or t1.consignee_mobile2 = t2.tel2) - GROUP BY t1.jx_store_id - ` - beginTime, endTime := utils.GetTimeRange(utils.GetCurDate(), dayNum, includeToday) - sqlParams := []interface{}{ - beginTime, - endTime, - } - - return storeOrderList, GetRows(db, &storeOrderList, sql, sqlParams) -} - -func GetOrderPayList(db *DaoDB, vendorOrderID string, vendorID int) (payList []*model.OrderPay, err error) { - sql := ` - SELECT t1.* - FROM order_pay t1 - WHERE t1.deleted_at = ? AND t1.vendor_order_id = ? AND t1.vendor_id = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - vendorOrderID, - vendorID, - } - return payList, GetRows(db, &payList, sql, sqlParams) -} - -func GetOrders(db *DaoDB, ids []int64, isIncludeSku, isIncludeFake bool, fromDateStr, toDateStr string, isDateFinish bool, skuIDs []int, isJxFirst bool, userID string, params map[string]interface{}, offset, pageSize int) (orders []*model.GoodsOrderExt, totalCount int, err error) { - globals.SugarLogger.Debugf("dao GetOrders ids:%v from:%s to:%s", ids, fromDateStr, toDateStr) - pageSize = jxutils.FormalizePageSize(pageSize) - offset = jxutils.FormalizePageOffset(offset) - - sql := fmt.Sprintf(` - SELECT SQL_CALC_FOUND_ROWS - t1.*, - CAST(IF(t1.earning_price <> 0, t1.earning_price, IF(t1.shop_price <> 0 && t1.shop_price < t1.sale_price, t1.shop_price, t1.sale_price) * IF(t5.pay_percentage > 0, t5.pay_percentage, %d) / 100) AS SIGNED) earning_price, - t2.status waybill_status, t2.courier_name, t2.courier_mobile, - t2.actual_fee, t2.desired_fee, t2.waybill_created_at, t2.waybill_finished_at, - t5.pay_percentage, t5.old_pay_percentage, - city.name city_name, district.name district_name`, model.DefaultEarningPricePercentage) - if isIncludeSku { - sql += `, - IF(t3.jx_sku_id > 0, t3.jx_sku_id, t3.sku_id) sku_id, - t3.count sku_count2, - t3.shop_price sku_shop_price, - IF(t3.store_sub_id = 0, 0, t3.earning_price) sku_earning_price, - t3.sale_price sku_sale_price, - t3.sku_name` - } - sql += ` - FROM goods_order t1 - LEFT JOIN waybill t2 ON t1.vendor_waybill_id = t2.vendor_waybill_id AND t1.waybill_vendor_id = t2.waybill_vendor_id AND t1.vendor_order_id = t2.vendor_order_id - LEFT JOIN store t5 ON t5.id = IF(t1.jx_store_id <> 0, t1.jx_store_id, t1.store_id) - LEFT JOIN place city ON city.code = t5.city_code - LEFT JOIN place district ON district.code = t5.district_code` - if isIncludeSku { - sql += ` - JOIN order_sku t3 ON t3.vendor_order_id = t1.vendor_order_id AND t3.vendor_id = t1.vendor_id` - } - sqlWhere := " WHERE 1 = 1" - var ( - sqlParams []interface{} - ) - if len(ids) > 0 { // 如果给定了ids,忽略其它所有条件 - sqlWhere += " AND t1.id IN (" + GenQuestionMarks(len(ids)) + ")" - sqlParams = append(sqlParams, ids) - } else { - // 如果搜索关键字可能为订单号,则当成订单号查询 - if params["keyword"] != nil { - if jxutils.GetPossibleVendorIDFromVendorOrderID(params["keyword"].(string)) > model.VendorIDUnknown { - params["vendorOrderID"] = params["keyword"] - } - } - if params["orderID"] != nil || params["vendorOrderID"] != nil { - sqlWhere += " AND (t1.vendor_order_id = ? OR t1.vendor_order_id2 = ?)" - vendorOrderID := params["vendorOrderID"] - if vendorOrderID == nil { - vendorOrderID = params["orderID"] - } - sqlParams = []interface{}{ - vendorOrderID, - vendorOrderID, - } - } else { - timeList, err2 := jxutils.BatchStr2Time(fromDateStr, toDateStr) - if err = err2; err != nil { - return nil, 0, err - } - if utils.IsTimeZero(timeList[0]) { - return nil, 0, fmt.Errorf("在没有指定订单号时,必须指定查询日期范围") - } - if utils.IsTimeZero(timeList[1]) { - timeList[1] = timeList[0] - } - timeList[1] = timeList[1].Add(24 * time.Hour) - if isDateFinish { - sqlWhere += ` - AND t1.order_finished_at >= ? AND t1.order_finished_at < ?` - } else { - sqlWhere += ` - AND t1.order_created_at >= ? AND t1.order_created_at < ?` - } - sqlParams = []interface{}{ - timeList[0], - timeList[1], - } - if params["keyword"] != nil { - keyword := params["keyword"].(string) - keywordLike := "%" + keyword + "%" - sqlWhere += ` - AND (t1.store_name LIKE ? OR t1.vendor_order_id LIKE ? OR t1.vendor_order_id2 LIKE ? OR t1.vendor_store_id LIKE ? - OR t1.consignee_name LIKE ? OR t1.consignee_mobile LIKE ? OR t1.consignee_mobile2 LIKE ? OR t1.consignee_address LIKE ? - OR t2.vendor_waybill_id LIKE ? OR t2.courier_name LIKE ? OR t2.courier_mobile LIKE ? - ` - sqlParams = append(sqlParams, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike) - if keywordInt64, err2 := strconv.ParseInt(keyword, 10, 64); err2 == nil { - sqlWhere += " OR t1.store_id = ? OR t1.jx_store_id = ?" - sqlParams = append(sqlParams, keywordInt64, keywordInt64) - } - sqlWhere += ")" - } - if params["waybillVendorIDs"] != nil { - var waybillVendorIDs []int - if err = utils.UnmarshalUseNumber([]byte(params["waybillVendorIDs"].(string)), &waybillVendorIDs); err != nil { - return nil, 0, err - } - if len(waybillVendorIDs) > 0 { - sqlWhere += " AND t1.waybill_vendor_id IN (" + GenQuestionMarks(len(waybillVendorIDs)) + ")" - sqlParams = append(sqlParams, waybillVendorIDs) - } - } - if params["storeIDs"] != nil { - var storeIDs []int - if err = utils.UnmarshalUseNumber([]byte(params["storeIDs"].(string)), &storeIDs); err != nil { - return nil, 0, err - } - if len(storeIDs) > 0 { - if storeIDs[0] == 0 { // 容错 - sqlWhere += " AND 1 = 0" - } else { - sqlWhere += " AND IF(t1.jx_store_id != 0, t1.jx_store_id, t1.store_id) IN (" + GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - } - } - if params["statuss"] != nil { - var statuss []int - if err = utils.UnmarshalUseNumber([]byte(params["statuss"].(string)), &statuss); err != nil { - return nil, 0, err - } - if len(statuss) > 0 { - sqlWhere += " AND t1.status IN (" + GenQuestionMarks(len(statuss)) + ")" - sqlParams = append(sqlParams, statuss) - } - } - if params["lockStatuss"] != nil { - var lockStatuss []int - if err = utils.UnmarshalUseNumber([]byte(params["lockStatuss"].(string)), &lockStatuss); err != nil { - return nil, 0, err - } - if len(lockStatuss) > 0 { - sqlWhere += " AND t1.lock_status IN (" + GenQuestionMarks(len(lockStatuss)) + ")" - sqlParams = append(sqlParams, lockStatuss) - } - } - if params["cities"] != nil { - var cities []int - if err = utils.UnmarshalUseNumber([]byte(params["cities"].(string)), &cities); err != nil { - return nil, 0, err - } - if len(cities) > 0 { - sqlWhere += " AND t5.city_code IN (" + GenQuestionMarks(len(cities)) + ") AND t5.id IS NOT NULL" - sqlParams = append(sqlParams, cities) - } - } - if !isIncludeFake { - sqlWhere += " AND (t1.flag & ?) = 0" - sqlParams = append(sqlParams, model.OrderFlagMaskFake) - } - if len(skuIDs) > 0 { - sqlWhere += " AND (SELECT COUNT(*) FROM order_sku t11 WHERE t11.vendor_order_id = t1.vendor_order_id AND t11.vendor_id = t1.vendor_id AND t11.jx_sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")) > 0" - sqlParams = append(sqlParams, skuIDs) - } - if params["adjustCount"] != nil { - sqlWhere += " AND t1.adjust_count >= ?" - sqlParams = append(sqlParams, params["adjustCount"]) - } - if mustInvoice, ok := params["mustInvoice"].(bool); ok && mustInvoice { - sqlWhere += " AND t1.invoice_taxer_id <> ''" - } - } - if params["vendorIDs"] != nil { - var vendorIDs []int - if err = utils.UnmarshalUseNumber([]byte(params["vendorIDs"].(string)), &vendorIDs); err != nil { - return nil, 0, err - } - if len(vendorIDs) > 0 { - sqlWhere += " AND t1.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" - sqlParams = append(sqlParams, vendorIDs) - } - } - if userID != "" { - sqlWhere += " AND t1.user_id = ?" - sqlParams = append(sqlParams, userID) - } - } - sql += sqlWhere - if isJxFirst { - sql += ` - ORDER BY IF(t1.status < ?, IF(t1.vendor_id = ?, 0, 1), 0), t1.order_created_at DESC` - sqlParams = append(sqlParams, model.OrderStatusEndBegin, model.VendorIDJX) - } else { - if isIncludeSku && userID == "" && len(ids) == 0 { - sql += ` - ORDER BY t1.id` - } else { - sql += ` - ORDER BY t1.order_created_at DESC` - } - } - sql += ` - LIMIT ? OFFSET ?` - sqlParams = append(sqlParams, pageSize, offset) - - Begin(db) - defer Commit(db) - if err = GetRows(db, &orders, sql, sqlParams...); err == nil { - totalCount = GetLastTotalRowCount(db) - } - return orders, totalCount, err -} - -func UpdateOrdersWithoutJxStoreID(db *DaoDB, fromDate, toDate time.Time) (count int64, err error) { - sql := ` - UPDATE goods_order t1 - JOIN store_map a ON a.vendor_store_id = t1.vendor_store_id AND a.vendor_id = t1.vendor_id - SET t1.jx_store_id = a.store_id - WHERE t1.jx_store_id = 0 - AND a.deleted_at = ? - AND t1.order_created_at >= ? AND t1.order_created_at <= ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - } - if !utils.IsTimeZero(fromDate) { - sqlParams = append(sqlParams, fromDate) - if !utils.IsTimeZero(toDate) { - sqlParams = append(sqlParams, toDate) - } else { - sqlParams = append(sqlParams, time.Now()) - } - } else { - if !utils.IsTimeZero(toDate) { - sqlParams = append(sqlParams, toDate.AddDate(0, 0, -5)) - sqlParams = append(sqlParams, toDate) - } else { - sqlParams = append(sqlParams, time.Now().AddDate(0, 0, -5)) - sqlParams = append(sqlParams, time.Now()) - } - } - return ExecuteSQL(db, sql, sqlParams) -} - -func GetMyOrderCountInfo(db *DaoDB, userID string, fromDate, toDate time.Time, statuss []int) (countInfo []*model.GoodsOrderCountInfo, err error) { - if utils.IsTimeZero(fromDate) { - return nil, fmt.Errorf("必须指定开始日期") - } - if !utils.IsTimeZero(fromDate) { - fromDate = utils.Time2Date(fromDate) - if utils.IsTimeZero(toDate) { - toDate = fromDate - } - } - if !utils.IsTimeZero(toDate) { - toDate = utils.Time2Date(toDate) - toDate = toDate.Add(24 * time.Hour) - } - - sql := ` - SELECT t1.lock_status, t1.status, COUNT(*) count - FROM goods_order t1 - WHERE t1.user_id = ? AND t1.vendor_id = ? - AND t1.order_created_at >= ? AND t1.order_created_at < ? - ` - sqlParams := []interface{}{ - userID, - model.VendorIDJX, - fromDate, toDate, - } - if len(statuss) > 0 { - sql += " AND t1.status IN (" + GenQuestionMarks(len(statuss)) + ")" - sqlParams = append(sqlParams, statuss) - } - sql += " GROUP BY 1,2" - err = GetRows(db, &countInfo, sql, sqlParams...) - return countInfo, err -} - -func GetPendingFakeOrders(db *DaoDB, vendorIDs []int, orderCreatedAfter, orderCreatedBefore time.Time) (orderList []*model.GoodsOrder, err error) { - sql := ` - SELECT t1.* - FROM goods_order t1 - JOIN new_config t2 ON t2.type = ? AND t2.key = ? AND t2.deleted_at = ? - AND LOCATE(IF(t1.consignee_mobile2 <> '', t1.consignee_mobile2, t1.consignee_mobile), t2.value) > 0 - WHERE t1.order_created_at >= ? AND t1.order_created_at <= ? - AND t1.delivery_type = ? - AND t1.status >= ? AND t1.status < ? - ` - sqlParams := []interface{}{ - model.ConfigTypeSys, - model.ConfigSysFakeOrderMobiles, - utils.DefaultTimeValue, - orderCreatedAfter, - orderCreatedBefore, - model.OrderDeliveryTypeSelfTake, - model.OrderStatusAccepted, - model.OrderStatusEndBegin, - } - if len(vendorIDs) > 0 { - sql += " AND t1.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" - sqlParams = append(sqlParams, vendorIDs) - } - // globals.SugarLogger.Debug(sql) - err = GetRows(db, &orderList, sql, sqlParams...) - return orderList, err -} - -// 不会有Skus信息 -func LoadPendingOrders(db *DaoDB, orderCreatedAfter time.Time, beforStatus int) (orderList []*model.GoodsOrder, err error) { - sql := ` - SELECT * - FROM goods_order - WHERE order_created_at >= ? - AND status < ?` - sqlParams := []interface{}{orderCreatedAfter, beforStatus} - err = GetRows(db, &orderList, sql, sqlParams...) - return orderList, err -} - -func GetWayBillByOrderID(db *DaoDB, orderStatus, vendorID, waybillVendorID int, vendorOrderID string) (wayBillList []*model.Waybill, err error) { - sql := ` - SELECT b.* - FROM goods_order a - JOIN waybill b ON IF(a.waybill_vendor_id = -1,a.vendor_order_id,a.vendor_waybill_id) = b.vendor_waybill_id AND b.order_vendor_id = a.vendor_id - WHERE a.vendor_order_id = ? - AND a.vendor_id = ? - ` - sqlParams := []interface{}{ - vendorOrderID, - vendorID, - } - if orderStatus > 0 { - sql += ` AND a.status = ?` - sqlParams = append(sqlParams, orderStatus) - } - if waybillVendorID > 0 { - sql += ` AND b.waybill_vendor_id = ?` - sqlParams = append(sqlParams, waybillVendorID) - } - err = GetRows(db, &wayBillList, sql, sqlParams...) - return wayBillList, err -} - -func GetOrdersSupplement(db *DaoDB, storIDs, vendorIDs, statuss []int, vendorOrderID string, fromTime, toTime time.Time, stype, IsReverse, offset, pageSize int) (orderSupplementFee []*model.OrderSupplementFee, totalCount int, err error) { - sql := ` - SELECT SQL_CALC_FOUND_ROWS * - FROM order_supplement_fee - WHERE 1=1 - AND deleted_at = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - } - if !utils.IsTimeZero(fromTime) { - sql += " AND supplement_time >= ?" - sqlParams = append(sqlParams, fromTime) - } - if !utils.IsTimeZero(toTime) { - sql += " AND supplement_time <= ?" - sqlParams = append(sqlParams, toTime) - } - if len(storIDs) > 0 { - sql += " AND store_id IN (" + GenQuestionMarks(len(storIDs)) + ")" - sqlParams = append(sqlParams, storIDs) - } - if len(vendorIDs) > 0 { - sql += " AND vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" - sqlParams = append(sqlParams, vendorIDs) - } - if vendorOrderID != "" { - sql += " AND vendor_order_id = ?" - sqlParams = append(sqlParams, vendorOrderID) - } - if len(statuss) > 0 { - sql += " AND status IN (" + GenQuestionMarks(len(statuss)) + ")" - sqlParams = append(sqlParams, statuss) - } - if stype > 0 { - sql += " AND type = ?" - sqlParams = append(sqlParams, stype) - } - if IsReverse == -1 { - sql += " AND link_id = 0" - } else if IsReverse == 1 { - sql += " AND link_id <> 0" - } - sql += " ORDER BY supplement_time DESC" - sql += " LIMIT ? OFFSET ?" - sqlParams = append(sqlParams, pageSize, offset) - Begin(db) - defer Commit(db) - if err = GetRows(db, &orderSupplementFee, sql, sqlParams...); err == nil { - totalCount = GetLastTotalRowCount(db) - } - return orderSupplementFee, totalCount, err -} - -func GetOrdersSupplementNoPage(db *DaoDB, ID int, storIDs, vendorIDs, statuss []int, vendorOrderID string, fromTime, toTime time.Time, stype, IsReverse int) (orderSupplementFee []*model.OrderSupplementFee, err error) { - sql := ` - SELECT * - FROM order_supplement_fee - WHERE 1=1 - AND deleted_at = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - } - if !utils.IsTimeZero(fromTime) { - sql += " AND supplement_time >= ?" - sqlParams = append(sqlParams, fromTime) - } - if !utils.IsTimeZero(toTime) { - sql += " AND supplement_time <= ?" - sqlParams = append(sqlParams, toTime) - } - if len(storIDs) > 0 { - sql += " AND store_id IN (" + GenQuestionMarks(len(storIDs)) + ")" - sqlParams = append(sqlParams, storIDs) - } - if len(vendorIDs) > 0 { - sql += " AND vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" - sqlParams = append(sqlParams, vendorIDs) - } - if vendorOrderID != "" { - sql += " AND vendor_order_id = ?" - sqlParams = append(sqlParams, vendorOrderID) - } - if len(statuss) > 0 { - sql += " AND status IN (" + GenQuestionMarks(len(statuss)) + ")" - sqlParams = append(sqlParams, statuss) - } - if stype > 0 { - sql += " AND type = ?" - sqlParams = append(sqlParams, stype) - } - if ID > 0 { - sql += " AND id = ?" - sqlParams = append(sqlParams, ID) - } - if IsReverse == -1 { - sql += " AND link_id = 0" - } else if IsReverse == 1 { - sql += " AND link_id <> 0" - } - err = GetRows(db, &orderSupplementFee, sql, sqlParams...) - return orderSupplementFee, err -} - -func GetJxOrderCount(db *DaoDB, storeID int, orderID string, date time.Time) (count int, err error) { - if utils.IsTimeZero(date) { - date = time.Now() - } - sql := ` - SELECT COUNT(*) ct - FROM goods_order t1 - WHERE t1.vendor_id = ? AND t1.jx_store_id = ? AND (t1.status >= ? OR t1.order_seq > 0) AND t1.order_created_at >= ? AND t1.order_created_at < ? - ` - sqlParams := []interface{}{ - model.VendorIDJX, - storeID, - model.OrderStatusNew, - utils.Time2Date(date), - utils.Time2Date(date).Add(24 * time.Hour), - } - - if orderID != "" { - sql += " AND t1.vendor_order_id != ?" - sqlParams = append(sqlParams, orderID) - } - err = GetRow(db, &count, sql, sqlParams...) - return count, err -} - -func GetOrdersForJxPay(db *DaoDB, finishTimeBegin, finishTimeEnd time.Time) (goods []*GoodsOrderPay, err error) { - sql := ` - SELECT a.*,b.transaction_id - FROM goods_order a - JOIN order_pay b ON a.vendor_order_id = b.vendor_order_id AND a.vendor_id = b.vendor_id - JOIN user c ON c.user_id = a.user_id - WHERE a.vendor_id = ? - AND a.order_finished_at >= ? - AND a.order_finished_at <= ? - AND a.status = ? - AND c.parent_mobile <> '' - AND a.store_id <> ? - ` - sqlParams := []interface{}{ - model.VendorIDJX, - finishTimeBegin, - finishTimeEnd, - model.OrderStatusFinished, - model.MatterStoreID, - } - err = GetRows(db, &goods, sql, sqlParams...) - return goods, err -} - -func GetWaybills(db *DaoDB, vendorOrderID string) (waybills []*model.Waybill, err error) { - sql := `SELECT * - FROM waybill - WHERE vendor_order_id = ? - ` - sqlParams := []interface{}{vendorOrderID} - err = GetRows(db, &waybills, sql, sqlParams) - return waybills, err -} - -func GetMatterChildOrders(db *DaoDB, vendorOrderID string) (goods []*model.GoodsOrder, err error) { - sql := `SELECT * - FROM goods_order - WHERE vendor_order_id LIKE ? OR vendor_order_id LIKE ? OR vendor_order_id LIKE ? - AND vendor_id = ? - ORDER BY vendor_order_id DESC - ` - sqlParams := []interface{}{ - vendorOrderID + "0%", vendorOrderID + "1%", vendorOrderID + "2%", - model.VendorIDJX, - } - err = GetRows(db, &goods, sql, sqlParams) - return goods, err -} - -func GetSimpleOrder(db *DaoDB, vendorOrderID string) (goods *model.GoodsOrder, err error) { - sql := ` - SELECT * - FROM goods_order - WHERE vendor_order_id = ? - ` - sqlParams := []interface{}{vendorOrderID} - err = GetRow(db, &goods, sql, sqlParams) - return goods, err -} - -func GetSimpleOrderSkus(db *DaoDB, vendorOrderID string, skuIDs []int) (skus []*model.OrderSku, err error) { - sql := ` - SELECT * - FROM order_sku - WHERE vendor_order_id = ? - ` - sqlParams := []interface{}{vendorOrderID} - if len(skuIDs) > 0 { - sql += " AND sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" - sqlParams = append(sqlParams, skuIDs) - } - err = GetRows(db, &skus, sql, sqlParams) - return skus, err -} - -func GetAfsOrdersByPage(db *DaoDB, vendorOrderID, afsOrderID, userID string, fromTime, toTime time.Time, offset, pageSize int) (afsOrderList []*model.AfsOrder, totalCount int, err error) { - pageSize = jxutils.FormalizePageSize(pageSize) - offset = jxutils.FormalizePageOffset(offset) - sql := ` - SELECT SQL_CALC_FOUND_ROWS t1.* - FROM afs_order t1 - LEFT JOIN goods_order t2 ON t2.vendor_order_id = t1.vendor_order_id AND t2.vendor_id = t1.vendor_id - WHERE 1 = 1 - ` - sqlParams := []interface{}{} - if vendorOrderID != "" { - sql += " AND t1.vendor_order_id = ?" - sqlParams = append(sqlParams, vendorOrderID) - } - if afsOrderID != "" { - sql += " AND t1.afs_order_id = ?" - sqlParams = append(sqlParams, afsOrderID) - } - if !utils.IsTimeZero(fromTime) { - sql += " AND t1.afs_created_at >= ?" - sqlParams = append(sqlParams, fromTime) - } - if !utils.IsTimeZero(toTime) { - sql += " AND t1.afs_created_at <= ?" - sqlParams = append(sqlParams, toTime) - } - if userID != "" { - sql += " AND t2.user_id = ?" - sqlParams = append(sqlParams, userID) - } - sql += ` ORDER BY t1.afs_order_id DESC - LIMIT ? OFFSET ? - ` - sqlParams = append(sqlParams, pageSize, offset) - Begin(db) - defer Commit(db) - if err = GetRows(db, &afsOrderList, sql, sqlParams...); err == nil { - totalCount = GetLastTotalRowCount(db) - } - return afsOrderList, totalCount, err -} - -func GetOrderStoreSkusCount(db *DaoDB, storeID, skuID int, fromTime, toTime time.Time) (count int64, err error) { - tmpOrderSku := &model.OrderSku{} - sql := ` - SELECT SUM(a.count) count - FROM order_sku a - JOIN goods_order b ON a.vendor_order_id = b.vendor_order_id AND a.vendor_id = b.vendor_id - WHERE IF(b.store_id = 0, b.jx_store_id, b.store_id) = ? - AND a.sku_id = ? - AND b.order_created_at BETWEEN ? AND ? - AND b.status >= ? - ` - sqlParams := []interface{}{ - storeID, - skuID, - fromTime, - toTime, - model.OrderStatusDelivering, - } - if err = GetRow(db, &tmpOrderSku, sql, sqlParams); err == nil { - return int64(tmpOrderSku.Count), nil - } - return count, err -} - -type GetSupplySupportStoreSkusResult struct { - SkuID int `orm:"column(sku_id)" json:"skuID"` - Count int `json:"count"` - SalePrice int `json:"salePrice"` - Stock int `json:"stock"` - model.SkuName -} - -func GetSupplySupportStoreSkus(db *DaoDB, fromDate, toDate time.Time, fromStoreID, storeID int, percentage float64) (getSupplySupportStoreSkusResult []*GetSupplySupportStoreSkusResult, err error) { - sql := ` - SELECT c.sku_id,CEIL(c.count) count,CEIL(c.count) * d.jx_price sale_price, d.stock, f.* - FROM - ( - SELECT a.sku_id,SUM(a.count * ? ) count FROM order_sku a - JOIN goods_order b ON b.vendor_order_id = a.vendor_order_id AND a.vendor_id = b.vendor_id - WHERE b.order_created_at > ? - AND b.order_created_at < ? - AND a.sku_id <> ? - AND IF(b.store_id = 0,b.jx_store_id,b.store_id) = ? - GROUP BY 1 - )c - JOIN store_sku_bind d ON d.store_id = ? AND d.sku_id = c.sku_id AND d.deleted_at = ? - JOIN sku e ON e.id = d.sku_id - JOIN sku_name f ON f.id = e.name_id - WHERE d.status <> ? - AND d.stock <> ? - ORDER BY c.count desc - ` - sqlParams := []interface{}{ - percentage, - fromDate, - toDate, - 6039481, //葱姜蒜 - fromStoreID, - storeID, utils.DefaultTimeValue, - model.StoreSkuBindStatusDontSale, - 0, - } - if err = GetRows(db, &getSupplySupportStoreSkusResult, sql, sqlParams); err == nil { - return getSupplySupportStoreSkusResult, err - } - return getSupplySupportStoreSkusResult, err -} - -func GetPriceDefendOrder(db *DaoDB, vendorOrderID string, storeIDs, skuIDs, issues []int, defendPrice, isBuyNowPrice, isSuccess, isPay int, userID string, beginAt, EndAt time.Time, isDesc bool) (priceDefendOrders []*model.PriceDefendOrder, err error) { - sql := ` - SELECT a.* - FROM price_defend_order a - JOIN user_delivery_address b ON a.address_id = b.id AND b.deleted_at = ? - WHERE 1 = 1 - AND a.deleted_at = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - utils.DefaultTimeValue, - } - if vendorOrderID != "" { - sql += " AND a.vendor_order_id = ?" - sqlParams = append(sqlParams, vendorOrderID) - } - if len(storeIDs) > 0 { - sql += " AND a.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - if len(skuIDs) > 0 { - sql += " AND a.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" - sqlParams = append(sqlParams, skuIDs) - } - if len(issues) > 0 { - sql += " AND a.issue IN (" + GenQuestionMarks(len(issues)) + ")" - sqlParams = append(sqlParams, issues) - } - if defendPrice != 0 { - sql += " AND a.defend_price = ?" - sqlParams = append(sqlParams, defendPrice) - } - if isBuyNowPrice != -1 { - sql += " AND a.is_buy_now_price = ?" - sqlParams = append(sqlParams, isBuyNowPrice) - } - if isSuccess != -1 { - sql += " AND a.is_success = ?" - sqlParams = append(sqlParams, isSuccess) - } - if isPay != -1 { - sql += " AND a.is_pay = ?" - sqlParams = append(sqlParams, isPay) - } - if userID != "" { - sql += " AND b.user_id = ?" - sqlParams = append(sqlParams, userID) - } - if beginAt != utils.ZeroTimeValue { - sql += " AND a.created_at >= ?" - sqlParams = append(sqlParams, beginAt) - } - if EndAt != utils.ZeroTimeValue { - sql += " AND a.created_at <= ?" - sqlParams = append(sqlParams, EndAt) - } - if isDesc { - sql += " ORDER BY a.created_at DESC" - } else { - sql += " ORDER BY a.created_at" - } - err = GetRows(db, &priceDefendOrders, sql, sqlParams) - return priceDefendOrders, err -} diff --git a/business/model/dao/dao_order_test.go b/business/model/dao/dao_order_test.go deleted file mode 100644 index 539001f27..000000000 --- a/business/model/dao/dao_order_test.go +++ /dev/null @@ -1,57 +0,0 @@ -package dao - -import ( - "testing" - "time" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/globals" -) - -func TestGetAfsOrderSkuInfo(t *testing.T) { - afsSkus, err := GetAfsOrderSkuInfo(GetDB(), "", "", 0) - if err == nil { - t.Fatal("应该要报错") - } - afsSkus, err = GetAfsOrderSkuInfo(GetDB(), "", "23148482", 0) - if err != nil { - t.Fatal(err) - } - globals.SugarLogger.Debug(utils.Format4Output(afsSkus, false)) - afsSkus, err = GetAfsOrderSkuInfo(GetDB(), "916829559000841", "", 0) - if err != nil { - t.Fatal(err) - } - globals.SugarLogger.Debug(utils.Format4Output(afsSkus, false)) -} - -func TestGetStoreOrderSkuList(t *testing.T) { - skuList, err := GetStoreOrderSkuList(GetDB(), []int{100118}, time.Now().Add(-30*time.Hour), time.Now(), nil, false) - if err != nil { - t.Fatal(err) - } - t.Log(utils.Format4Output(skuList, false)) - - afsSkuList, err := GetStoreOrderSkuList(GetDB(), []int{100118}, time.Now().Add(-30*time.Hour), time.Now(), nil, false) - if err != nil { - t.Fatal(err) - } - t.Log(utils.Format4Output(afsSkuList, false)) - -} - -func TestGetPendingFakeOrders(t *testing.T) { - orderList, err := GetPendingFakeOrders(GetDB(), nil, time.Now().Add(-48*time.Hour), time.Now().Add(-30*time.Minute)) - if err != nil { - t.Fatal(err) - } - t.Log(len(orderList)) -} - -func TestGetJxOrderSeq(t *testing.T) { - count, err := GetJxOrderCount(GetDB(), 100118, "23423", time.Now()) - if err != nil { - t.Fatal(err) - } - t.Log(count) -} diff --git a/business/model/dao/dao_user.go b/business/model/dao/dao_user.go index bb2fac270..8b3594fe4 100644 --- a/business/model/dao/dao_user.go +++ b/business/model/dao/dao_user.go @@ -9,11 +9,6 @@ import ( "git.rosy.net.cn/jx-callback/business/model" ) -type StoreWithCityName struct { - model.Store - CityName string `json:"cityName"` -} - type UserDeliveryAddressEx struct { model.UserDeliveryAddress @@ -121,62 +116,6 @@ func DeleteUsers(db *DaoDB, userIDs []string) (num int64, err error) { return num, err } -// func GetStoreListByMobile(db *DaoDB, mobile string) (storeList []*StoreWithCityName, err error) { -// if mobile != "" { -// sql := ` -// SELECT -// DISTINCT t1.*, t2.name city_name -// FROM ( -// SELECT * -// FROM store t1 -// WHERE (t1.market_man_phone = ? OR t1.operator_phone = ? OR t1.operator_phone2 = ? OR t1.operator_phone3 = ?) -// UNION DISTINCT -// SELECT t1.* -// FROM store t1 -// JOIN weixins t2 ON t2.jxstoreid = t1.id AND t2.parentid = -1 -// LEFT JOIN weixins t3 ON t3.parentid = t2.id -// WHERE (t2.tel = ? OR t3.tel = ?) -// ) t1 -// LEFT JOIN place t2 ON t2.code = t1.city_code -// WHERE t1.deleted_at = ? -// ORDER BY t1.name` -// sqlParams := []interface{}{ -// mobile, mobile, mobile, mobile, -// mobile, mobile, -// utils.DefaultTimeValue, -// } -// err = GetRows(db, &storeList, sql, sqlParams...) -// } -// return storeList, err -// } - -func GetStoreListByMobileOrStoreIDs(db *DaoDB, mobile string, shortRoleNameList []string, storeIDs []int) (storeList []*StoreWithCityName, err error) { - sql := ` - SELECT t1.*, t2.name city_name - FROM store t1 - LEFT JOIN place t2 ON t2.code = t1.city_code - WHERE t1.deleted_at = ? AND ( 1 = 0` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - } - if mobile != "" { - sql += " OR t1.tel1 = ? OR t1.tel2 = ? OR t1.market_man_phone = ? OR t1.operator_phone = ? OR t1.operator_phone2 = ? OR t1.operator_phone3 = ?" - sqlParams = append(sqlParams, mobile, mobile, mobile, mobile, mobile, mobile) - } - if len(shortRoleNameList) > 0 { - questionMarks := GenQuestionMarks(len(shortRoleNameList)) - sql += " OR t1.market_man_role IN (" + questionMarks + ") OR t1.operator_role IN (" + questionMarks + ") OR t1.operator_role2 IN (" + questionMarks + ") OR t1.operator_role3 IN (" + questionMarks + ")" - sqlParams = append(sqlParams, shortRoleNameList, shortRoleNameList, shortRoleNameList, shortRoleNameList) - } - if len(storeIDs) > 0 { - sql += " OR t1.id IN (" + GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - sql += ")" - err = GetRows(db, &storeList, sql, sqlParams...) - return storeList, err -} - func QueryUserDeliveryAddress(db *DaoDB, addressID int64, userIDs []string, offset, pageSize int) (addressList []*UserDeliveryAddressEx, totalCount int, err error) { sql := ` SELECT SQL_CALC_FOUND_ROWS @@ -280,27 +219,28 @@ func GetUserOrderSMS(db *DaoDB, mobile, name string) (userOrderSms *model.UserOr return userOrderSms, err } -func GetUserMember(db *DaoDB, userID, vendorOrderID string, memberType, isPay int) (userMembers []*model.UserMember, err error) { +func GetUserMember(db *DaoDB, userID string, orderID int64, memberType int, isPay bool) (userMembers []*model.UserMember, err error) { sql := ` - SELECT * - FROM user_member - WHERE deleted_at = ? + SELECT a.* + FROM user_member a + JOIN order b ON b.id = a.order_id + WHERE a.deleted_at = ? ` sqlParams := []interface{}{utils.DefaultTimeValue} if userID != "" { - sql += " AND user_id = ?" + sql += " AND a.user_id = ?" sqlParams = append(sqlParams, userID) } - if vendorOrderID != "" { - sql += " AND vendor_order_id = ?" - sqlParams = append(sqlParams, vendorOrderID) + if orderID != 0 { + sql += " AND a.order_id = ?" + sqlParams = append(sqlParams, orderID) } if memberType != 0 { - sql += " AND member_type = ?" + sql += " AND a.member_type = ?" sqlParams = append(sqlParams, memberType) } - if isPay != -1 { - sql += " AND is_pay = ?" + if isPay { + sql += " AND b.status = ?" sqlParams = append(sqlParams, isPay) } err = GetRows(db, &userMembers, sql, sqlParams) diff --git a/business/model/dao/job.go b/business/model/dao/job.go index 4586f2958..512934637 100644 --- a/business/model/dao/job.go +++ b/business/model/dao/job.go @@ -80,7 +80,7 @@ func GetJobs(db *DaoDB, userIDs []string, categoryIDs []int, includeStep bool, f return pagedInfo, err } -func GetJobsNoPage(db *DaoDB, userIDs []string, categoryIDs []int, includeStep bool) (jobs []*GetJobsResult, err error) { +func GetJobsNoPage(db *DaoDB, userIDs []string, categoryIDs []int, fromTime, toTime time.Time, includeStep bool) (jobs []*GetJobsResult, err error) { sql := ` SELECT a.*, b.name FROM job a @@ -96,6 +96,14 @@ func GetJobsNoPage(db *DaoDB, userIDs []string, categoryIDs []int, includeStep b sql += ` AND a.job_category_id IN (` + GenQuestionMarks(len(categoryIDs)) + `)` sqlParams = append(sqlParams, categoryIDs) } + if fromTime != utils.ZeroTimeValue { + sql += ` AND a.created_at >= ?` + sqlParams = append(sqlParams, fromTime) + } + if toTime != utils.ZeroTimeValue { + sql += ` AND a.created_at <= ?` + sqlParams = append(sqlParams, toTime) + } err = GetRows(db, &jobs, sql, sqlParams...) if includeStep { for _, v := range jobs { diff --git a/business/model/dao/report.go b/business/model/dao/report.go deleted file mode 100644 index ca0e7542e..000000000 --- a/business/model/dao/report.go +++ /dev/null @@ -1,360 +0,0 @@ -package dao - -import ( - "time" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/model" -) - -type StatisticsForOrdersExists struct { - StoreID int `orm:"column(store_id)" json:"storeId"` -} - -type StatisticsReportForOrdersList struct { - StatisticsForOrdersExists - StoreName string `json:"name"` //门店名 - OrderCounts int `json:"orderCounts"` //订单数 - SalePrice int `json:"salePrice"` //GMV(售卖价) - ActualPayPrice int `json:"actualPayPrice"` //实付 - ShopPrice int `json:"shopPrice"` //京西 - DiscountMoney int `json:"discountMoney"` //优惠 - DesiredFee int `json:"desiredFee"` //配送费 - DistanceFreightMoney int `json:"distanceFreightMoney"` //远距离 - WaybillTipMoney int `json:"waybillTipMoney"` //小费 - TotalShopMoney int `json:"totalShopMoney"` //平台结算 - PmSubsidyMoney int `json:"pmSubsidyMoney"` //平台补贴 - EarningPrice int `json:"earningPrice"` //门店收益(预计收益) - TotalGrossProfit int `json:"totalGrossProfit"` //总毛利 - ComGrossProfit float32 `json:"comGrossProfit"` //公司毛利 - CityManagerGrossProfit float32 `json:"cityManagerGrossProfit"` //城市经理毛利 - MarketManName string `json:"marketManName"` //市场负责人 - OperatorName string `json:"operatorName"` //运营负责人 - OperatorName2 string `json:"operatorName2"` - OperatorName3 string `json:"operatorName3"` - - CityName string `json:"cityName"` - Status int `json:"status"` - Tel1 string `orm:"size(32);index" json:"tel1"` -} - -type PriceReferSnapshotExt struct { - model.PriceReferSnapshot - CityName string `json:"cityName"` - SkuName string `json:"skuName"` - SpecQuality float32 - Unit string - SpecUnit string -} - -//查询统计订单信息 -func GetStatisticsReportForOrders(db *DaoDB, storeIDs []int, fromDate time.Time, toDate time.Time) (statisticsReportForOrdersList []*StatisticsReportForOrdersList, err error) { - sql := ` - SELECT - c.id store_id, - c.name store_name, - s.order_counts, - s.sale_price, - s.actual_pay_price, - s.shop_price, - s.discount_money, - s.desired_fee, - s.distance_freight_money, - s.waybill_tip_money, - s.total_shop_money, - s.pm_subsidy_money, - s.earning_price, - s.total_gross_profit, - IF(c.jx_brand_fee_factor = 0 AND c.market_add_fee_factor = 0,total_gross_profit,(total_gross_profit*c.jx_brand_fee_factor)/(c.jx_brand_fee_factor+market_add_fee_factor)) com_gross_profit, - IF(c.jx_brand_fee_factor = 0 AND c.market_add_fee_factor = 0,0,(total_gross_profit*c.market_add_fee_factor)/(c.jx_brand_fee_factor+market_add_fee_factor)) city_manager_gross_profit, - c.status, c.tel1, - IF(mm.name <> '', mm.name, mm.user_id2) market_man_name, - IF(om.name <> '', om.name, om.user_id2) operator_name, - IF(om2.name <> '', om2.name, om2.user_id2) operator_name2, - IF(om3.name <> '', om3.name, om3.user_id2) operator_name3, - p.name city_name - FROM store c - LEFT JOIN place p ON p.code = c.city_code - LEFT JOIN user mm ON mm.mobile <> '' AND mm.mobile = c.market_man_phone - LEFT JOIN user om ON om.mobile <> '' AND om.mobile = c.operator_phone - LEFT JOIN user om2 ON om2.mobile <> '' AND om2.mobile = c.operator_phone2 - LEFT JOIN user om3 ON om3.mobile <> '' AND om3.mobile = c.operator_phone3 - LEFT JOIN - ( - SELECT - IF(a.jx_store_id <> 0,a.jx_store_id,store_id) store_id, - COUNT(*) order_counts, - SUM(sale_price) sale_price, - SUM(actual_pay_price) actual_pay_price, - SUM(shop_price) shop_price, - SUM(discount_money) discount_money, - SUM(desired_fee) desired_fee, - SUM(distance_freight_money) distance_freight_money, - SUM(IF(a.vendor_id = a.waybill_vendor_id,waybill_tip_money,0)) waybill_tip_money, - SUM(total_shop_money) total_shop_money, - SUM(pm_subsidy_money) pm_subsidy_money, - SUM(earning_price) earning_price, - SUM(total_shop_money-earning_price-desired_fee-distance_freight_money-waybill_tip_money-80) total_gross_profit - FROM goods_order a - LEFT JOIN waybill b ON IF(a.waybill_vendor_id = -1,a.vendor_order_id,a.vendor_waybill_id) = b.vendor_waybill_id - WHERE a.status != ? - ` - sqlParams := []interface{}{ - model.OrderStatusCanceled, //排除已取消的订单 - } - if !utils.IsTimeZero(fromDate) && !utils.IsTimeZero(toDate) { - sql += ` AND a.order_created_at BETWEEN ? AND ?` - sqlParams = append(sqlParams, fromDate, toDate) - } - if len(storeIDs) > 0 { - sql += ` AND IF(a.jx_store_id != 0, a.jx_store_id, a.store_id) IN(` + GenQuestionMarks(len(storeIDs)) + `)` - sqlParams = append(sqlParams, storeIDs) - } - sql += ` - GROUP BY 1 - )s - ON s.store_id = c.id - ` - if len(storeIDs) > 0 { - sql += ` WHERE c.id IN (` + GenQuestionMarks(len(storeIDs)) + `)` - sqlParams = append(sqlParams, storeIDs) - } - if err = GetRows(db, &statisticsReportForOrdersList, sql, sqlParams...); err == nil { - return statisticsReportForOrdersList, nil - } - return nil, err -} - -//查询统计售后单信息 -func GetGetStatisticsReportForAfsOrders(db *DaoDB, storeIDs []int, fromDate time.Time, toDate time.Time) (statisticsReportForOrdersList []*StatisticsReportForOrdersList, err error) { - sql := ` - SELECT - c.id store_id, - c.name store_name, - s.order_counts, - s.sale_price, - s.actual_pay_price, - s.shop_price, - s.discount_money, - s.desired_fee, - s.distance_freight_money, - s.waybill_tip_money, - s.total_shop_money, - s.pm_subsidy_money, - s.earning_price, - s.total_gross_profit, - IF(c.jx_brand_fee_factor = 0 AND c.market_add_fee_factor = 0,total_gross_profit,(total_gross_profit*c.jx_brand_fee_factor)/(c.jx_brand_fee_factor+market_add_fee_factor)) com_gross_profit, - IF(c.jx_brand_fee_factor = 0 AND c.market_add_fee_factor = 0,0,(total_gross_profit*c.market_add_fee_factor)/(c.jx_brand_fee_factor+market_add_fee_factor)) city_manager_gross_profit, - c.status, c.tel1, - IF(mm.name <> '', mm.name, mm.user_id2) market_man_name, - IF(om.name <> '', om.name, om.user_id2) operator_name, - IF(om2.name <> '', om2.name, om2.user_id2) operator_name2, - IF(om3.name <> '', om3.name, om3.user_id2) operator_name3, - p.name city_name - FROM store c - LEFT JOIN place p ON p.code = c.city_code - LEFT JOIN user mm ON mm.mobile <> '' AND mm.mobile = c.market_man_phone - LEFT JOIN user om ON om.mobile <> '' AND om.mobile = c.operator_phone - LEFT JOIN user om2 ON om2.mobile <> '' AND om2.mobile = c.operator_phone2 - LEFT JOIN user om3 ON om3.mobile <> '' AND om3.mobile = c.operator_phone3 - LEFT JOIN - ( - SELECT - IF(a.jx_store_id <> 0,a.jx_store_id,store_id) store_id, - COUNT(*) order_counts, - SUM(sale_price) sale_price, - SUM(actual_pay_price) actual_pay_price, - SUM(shop_price) shop_price, - SUM(discount_money) discount_money, - SUM(afs_freight_money) desired_fee, - SUM(distance_freight_money) distance_freight_money, - SUM(IF(a.vendor_id = a.waybill_vendor_id,waybill_tip_money,0)) waybill_tip_money, - SUM(total_shop_money) total_shop_money, - SUM(b.pm_subsidy_money) pm_subsidy_money, - SUM(earning_price) earning_price, - SUM(total_shop_money-earning_price-afs_freight_money-distance_freight_money-waybill_tip_money-80) total_gross_profit - FROM goods_order a JOIN afs_order b ON a.vendor_order_id = b.vendor_order_id - WHERE a.status != ? - ` - sqlParams := []interface{}{ - model.OrderStatusCanceled, //排除已取消的订单 - } - if !utils.IsTimeZero(fromDate) && !utils.IsTimeZero(toDate) { - sql += ` AND a.order_created_at BETWEEN ? AND ?` - sqlParams = append(sqlParams, fromDate, toDate) - } - if len(storeIDs) > 0 { - sql += ` AND IF(a.jx_store_id != 0, a.jx_store_id, a.store_id) IN(` + GenQuestionMarks(len(storeIDs)) + `)` - sqlParams = append(sqlParams, storeIDs) - } - sql += ` - GROUP BY 1 - )s - ON s.store_id = c.id - ` - if len(storeIDs) > 0 { - sql += ` WHERE c.id IN (` + GenQuestionMarks(len(storeIDs)) + `)` - sqlParams = append(sqlParams, storeIDs) - } - if err = GetRows(db, &statisticsReportForOrdersList, sql, sqlParams...); err == nil { - return statisticsReportForOrdersList, nil - } - return nil, err -} - -func GetStatisticsReportForStoreSkusPrice(db *DaoDB, cityCodes, skuIDs []int) (priceReferSnapshot []*model.PriceReferSnapshot, err error) { - var sql string - sql1 := ` - SELECT a.sku_id, c.name_id, - ` - sql2 := ` - MAX(a.jd_price) max_jd_price, - MIN(a.jd_price) min_jd_price, - ROUND(AVG(a.jd_price)) avg_jd_price, - ROUND(SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(a.jd_price ORDER BY a.jd_price),',',Count(1)/2),',',-1),2) mid_jd_price, - MAX(a.ebai_price) max_ebai_price, - MIN(a.ebai_price) min_ebai_price, - ROUND(AVG(a.ebai_price)) avg_ebai_price, - ROUND(SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(a.ebai_price ORDER BY a.ebai_price),',',Count(1)/2),',',-1),2) mid_ebai_price, - MAX(a.mtwm_price) max_mtwm_price, - MIN(a.mtwm_price) min_mtwm_price, - ROUND(AVG(a.mtwm_price)) avg_mtwm_price, - ROUND(SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(a.mtwm_price ORDER BY a.mtwm_price),',',Count(1)/2),',',-1),2) mid_mtwm_price, - t1.max_sale_price, - t1.min_sale_price, - t1.avg_sale_price, - t1.max_vendor_price, - t1.min_vendor_price, - t1.avg_vendor_price - FROM store_sku_bind a - JOIN store b ON a.store_id = b.id AND b.deleted_at = ? AND b.status != ? - JOIN sku c ON a.sku_id = c.id - LEFT JOIN ( - SELECT SUM(t1.count),t1.sku_id,MAX(t1.sale_price) max_sale_price,MIN(t1.sale_price) min_sale_price,ROUND(AVG(t1.sale_price)) avg_sale_price,MAX(t1.vendor_price) max_vendor_price,MIN(t1.vendor_price) min_vendor_price,ROUND(AVG(t1.vendor_price)) avg_vendor_price - FROM order_sku t1 - WHERE t1.order_created_at BETWEEN ? AND NOW() - GROUP BY 2 - )t1 ON t1.sku_id = a.sku_id - WHERE a.deleted_at = ? - ` - sql = sql1 + "b.city_code, " + sql2 - sqlParams := []interface{}{ - utils.DefaultTimeValue, - model.StoreStatusDisabled, - time.Now().AddDate(0, -1, 0), - utils.DefaultTimeValue, - } - if len(skuIDs) > 0 { - sql += " AND a.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" - sqlParams = append(sqlParams, skuIDs) - } - if len(cityCodes) > 0 { - sql += " AND b.city_code IN (" + GenQuestionMarks(len(cityCodes)) + ")" - sqlParams = append(sqlParams, cityCodes) - } - sql += ` GROUP BY 1,2,3 - UNION ` - sql += sql1 + "0 city_code," + sql2 - if len(skuIDs) > 0 { - sql += " AND a.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" - sqlParams = append(sqlParams, skuIDs) - } - if len(cityCodes) > 0 { - sql += " AND b.city_code IN (" + GenQuestionMarks(len(cityCodes)) + ")" - sqlParams = append(sqlParams, cityCodes) - } - sql += " GROUP BY 1,2" - sqlParams = append(sqlParams, sqlParams...) - if err = GetRows(db, &priceReferSnapshot, sql, sqlParams...); err == nil { - return priceReferSnapshot, nil - } - return nil, err -} - -func GetPriceReferSnapshot(db *DaoDB, cityCodes, skuIDs []int, skuNameID int, snapDate time.Time, offset, pageSize int) (priceReferSnapshot []*PriceReferSnapshotExt, totalCount int, err error) { - sql := ` - SELECT SQL_CALC_FOUND_ROWS a.*,IF(a.city_code = 0,'全国',b.name) city_name - FROM price_refer_snapshot a - LEFT JOIN place b ON a.city_code = b.code - WHERE 1=1 - AND a.deleted_at = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - } - if skuNameID > 0 { - sql += " AND a.name_id = ?" - sqlParams = append(sqlParams, skuNameID) - } - if len(skuIDs) > 0 { - sql += " AND a.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" - sqlParams = append(sqlParams, skuIDs) - } - if len(cityCodes) > 0 { - sql += " AND a.city_code IN (" + GenQuestionMarks(len(cityCodes)) + ")" - sqlParams = append(sqlParams, cityCodes) - } - if !utils.IsTimeZero(snapDate) { - sql += " AND a.snapshot_at = ?" - sqlParams = append(sqlParams, snapDate) - } - sql += " LIMIT ? OFFSET ?" - sqlParams = append(sqlParams, pageSize, offset) - Begin(db) - defer Commit(db) - if err = GetRows(db, &priceReferSnapshot, sql, sqlParams...); err == nil { - totalCount = GetLastTotalRowCount(db) - } - for _, v := range priceReferSnapshot { - skuList, err2 := GetSkus(db, []int{v.SkuID}, nil, nil, nil, nil) - err = err2 - if len(skuList) > 0 { - skuAndName := skuList[0] - jxSkuDetailName := jxutils.ComposeSkuNameOriginal(skuAndName.Prefix, skuAndName.Name, skuAndName.Comment, skuAndName.Unit, skuAndName.SpecQuality, skuAndName.SpecUnit, 0) - v.SkuName = jxSkuDetailName - } - } - return priceReferSnapshot, totalCount, err -} - -func GetPriceReferSnapshotNoPage(db *DaoDB, cityCodes, skuIDs, skuNameIDs []int, snapDate time.Time) (priceReferSnapshot []*model.PriceReferSnapshot, err error) { - sql := ` - SELECT a.* - FROM price_refer_snapshot a - WHERE 1=1 - AND a.deleted_at = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - } - if len(skuNameIDs) > 0 { - sql += " AND a.name_id IN (" + GenQuestionMarks(len(skuNameIDs)) + ")" - sqlParams = append(sqlParams, skuNameIDs) - } - if len(skuIDs) > 0 { - sql += " AND a.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" - sqlParams = append(sqlParams, skuIDs) - } - if len(cityCodes) > 0 { - sql += " AND a.city_code IN (" + GenQuestionMarks(len(cityCodes)) + ")" - sqlParams = append(sqlParams, cityCodes) - } - if !utils.IsTimeZero(snapDate) { - sql += " AND a.snapshot_at = ?" - sqlParams = append(sqlParams, snapDate) - } - err = GetRows(db, &priceReferSnapshot, sql, sqlParams...) - return priceReferSnapshot, err -} - -func DeletePriceReferHistory(db *DaoDB, snapDate time.Time) (num int64, err error) { - sql := ` - DELETE FROM price_refer_snapshot - WHERE snapshot_at <= ? - ` - sqlParams := []interface{}{ - snapDate, - } - return ExecuteSQL(db, sql, sqlParams...) -} diff --git a/business/model/dao/sensitive_words.go b/business/model/dao/sensitive_words.go deleted file mode 100644 index 1b75629b4..000000000 --- a/business/model/dao/sensitive_words.go +++ /dev/null @@ -1,71 +0,0 @@ -package dao - -import ( - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/globals" - "time" -) - -/*VendorID = -2 的时候是通用,-1 查询所有,保留之前的1,看后面会不会有扩展*/ -func GetSensitiveWordList(vendorID int) (wordList []*model.SensitiveWord, err error) { - if vendorID == 0 { - vendorID = -2 - } - if vendorID == -1 { - sql := `SELECT * FROM sensitive_word WHERE deleted_at = ?` - err = GetRows(nil, &wordList, sql, utils.DefaultTimeValue) - } else { - sql := `SELECT * FROM sensitive_word WHERE deleted_at = ? AND vendor_id = ?` - err = GetRows(nil, &wordList, sql, utils.DefaultTimeValue, vendorID) - } - return wordList, err -} - -func InsertSensitiveWord(word string, vendorID int, userName string) error { - if vendorID == 0 { - vendorID = -2 - } - sensitiveWord := &model.SensitiveWord{Word: word, VendorID: vendorID} - WrapAddIDCULDEntity(sensitiveWord, userName) - return CreateEntity(nil, sensitiveWord) -} - -func DeleteSensitiveWord(wordList *model.SensitiveWord, id int, userName string, vendorID int) (word *model.SensitiveWord, err error) { - if vendorID == 0 { - vendorID = -2 - } - if id != 0 { - wordList.ID = id - } - wordList.VendorID = id - wordList.DeletedAt = time.Now() - wordList.LastOperator = userName - if _, err := UpdateEntity(nil, wordList, "deleted_at", "id", "last_operator", "vendor_id"); err != nil { - return nil, err - } - return wordList, nil -} - -func UpdateSensitiveWord(wordList *model.SensitiveWord, vendorID int, id int, userName string) (word *model.SensitiveWord, err error) { - if vendorID == 0 { - vendorID = -2 - } - if id != 0 { - wordList.ID = id - } - wordList.VendorID = vendorID - wordList.UpdatedAt = time.Now() - wordList.LastOperator = userName - globals.SugarLogger.Debug("wordList:", wordList) - if id != 0 { - if _, err := UpdateEntity(nil, wordList, "id", "word", "vendor_id", "last_operator"); err != nil { - return nil, err - } - } else { - if _, err := UpdateEntity(nil, wordList, "word", "vendor_id", "last_operator"); err != nil { - return nil, err - } - } - return wordList, err -} diff --git a/business/model/dao/sku.go b/business/model/dao/sku.go deleted file mode 100644 index ada9feefe..000000000 --- a/business/model/dao/sku.go +++ /dev/null @@ -1,441 +0,0 @@ -package dao - -import ( - "time" - - "git.rosy.net.cn/baseapi/platformapi/aliupcapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/model" -) - -type SkuCategoryWithVendor struct { - *model.SkuCategory - MapList []*model.ThingMap `json:"mapList"` -} - -type SkuNamePlace struct { - model.Place - NameID int `orm:"column(name_id)" json:"nameID"` - SkuID int `orm:"column(sku_id)" json:"skuID"` -} - -func GetSellCities(db *DaoDB, nameID int, vendorID int) (cities []*model.Place, err error) { - cities = []*model.Place{} - sql := ` - SELECT DISTINCT t3.* - FROM sku_name_place_bind t1 - JOIN place t2 ON t1.place_code = t2.code - JOIN place t3 ON (t2.level = 2 AND t2.code = t3.code) OR (t2.level = 1 AND t2.code = t3.parent_code) - WHERE t1.name_id = ? - ` - if vendorID == model.VendorIDJD { - sql += "AND t3.jd_code <> 0\n" - } - return cities, GetRows(db, &cities, sql, nameID) -} - -func DeleteSkuNamePlace(db *DaoDB, nameID int, placeCodes []int) (num int64, err error) { - sql := ` - DELETE - FROM sku_name_place_bind - WHERE name_id = ? - ` - sqlParams := []interface{}{ - nameID, - } - if len(placeCodes) > 0 { - sql += " AND place_code IN (" + GenQuestionMarks(len(placeCodes)) + ")" - sqlParams = append(sqlParams, placeCodes) - } - return ExecuteSQL(db, sql, sqlParams...) -} - -func GetCategories(db *DaoDB, parentID, level int, catIDs []int, isExd bool) (cats []*model.SkuCategory, err error) { - sql := ` - SELECT t1.* - FROM sku_category t1 - WHERE t1.deleted_at = ?` - params := []interface{}{ - utils.DefaultTimeValue, - } - if parentID != -1 { - sql += " AND t1.parent_id = ?" - params = append(params, parentID) - } - if len(catIDs) > 0 { - sql += " AND t1.id IN (" + GenQuestionMarks(len(catIDs)) + ")" - params = append(params, catIDs) - } - if level > 0 { - sql += " AND t1.level = ?" - params = append(params, level) - } - if isExd { - sql += " ORDER BY t1.level, t1.exd_seq" - } else { - sql += ` AND t1.is_exd_spec = 0 - ORDER BY t1.level, t1.seq` - } - return cats, GetRows(db, &cats, sql, params) -} - -func GetSkus(db *DaoDB, skuIDs, nameIDs, statuss, catIDs []int, eclpIDs []string) (skuList []*model.SkuAndName, err error) { - sql := ` - SELECT t1.*, t2.name, t2.unit, t2.prefix, t2.is_spu, t2.ex_prefix, t2.ex_prefix_begin, t2.ex_prefix_end, t2.upc - FROM sku t1 - JOIN sku_name t2 ON t2.id = t1.name_id AND t2.deleted_at = ? - ` - sqlWhere := ` - WHERE t1.deleted_at = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - utils.DefaultTimeValue, - } - if len(skuIDs) > 0 { - sqlWhere += " AND t1.id IN (" + GenQuestionMarks(len(skuIDs)) + ")" - sqlParams = append(sqlParams, skuIDs) - } - if len(nameIDs) > 0 { - sqlWhere += " AND t1.name_id IN (" + GenQuestionMarks(len(nameIDs)) + ")" - sqlParams = append(sqlParams, nameIDs) - } - if len(statuss) > 0 { - sqlWhere += " AND t1.status IN (" + GenQuestionMarks(len(statuss)) + ") AND t2.status IN (" + GenQuestionMarks(len(statuss)) + ")" - sqlParams = append(sqlParams, statuss, statuss) - } - if len(catIDs) > 0 { - sql += ` - JOIN sku_category t3 ON t3.id = t2.category_id - LEFT JOIN sku_category t3p ON t3p.id = t3.parent_id - ` - sqlWhere += " AND (t3.id IN (" + GenQuestionMarks(len(catIDs)) + ")" - sqlWhere += " OR t3p.id IN (" + GenQuestionMarks(len(catIDs)) + ") )" - sqlParams = append(sqlParams, catIDs, catIDs) - } - if len(eclpIDs) > 0 { - sqlWhere += " AND t1.eclp_id IN (" + GenQuestionMarks(len(eclpIDs)) + ")" - sqlParams = append(sqlParams, eclpIDs) - } - sql += sqlWhere - if err = GetRows(db, &skuList, sql, sqlParams...); err == nil { - return skuList, nil - } - return nil, err -} - -func GetSkuNames(db *DaoDB, nameIDs []int, upcs []string, name string, isExd bool) (skuNameList []*model.SkuName, err error) { - sql := ` - SELECT t1.* - FROM sku_name t1 - LEFT JOIN sku t2 ON t2.name_id = t1.id - WHERE t1.deleted_at = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - } - if len(nameIDs) > 0 { - sql += " AND t1.id IN (" + GenQuestionMarks(len(nameIDs)) + ")" - sqlParams = append(sqlParams, nameIDs) - } - if len(upcs) > 0 { - sql += " AND t1.upc IN (" + GenQuestionMarks(len(upcs)) + ")" - sqlParams = append(sqlParams, upcs) - } - if name != "" { - sql += " AND t1.name LIKE ?" - sqlParams = append(sqlParams, "%"+name+"%") - } - if isExd { - sql += " AND t2.exd_sku_id <> ''" - } - if err = GetRows(db, &skuNameList, sql, sqlParams...); err == nil { - return skuNameList, nil - } - return nil, err -} - -func GetSkuIDByNames(db *DaoDB, nameIDs []int) (skuIDs []int, err error) { - skuList, err := GetSkus(db, nil, nameIDs, nil, nil, nil) - if err == nil { - for _, sku := range skuList { - skuIDs = append(skuIDs, sku.ID) - } - } - return skuIDs, err -} - -func GetSkuByCats(db *DaoDB, catIDs []int) (skuList []*model.Sku, err error) { - skuExList, err := GetSkus(db, nil, nil, nil, catIDs, nil) - if err == nil { - for _, v := range skuExList { - skuList = append(skuList, &v.Sku) - } - } - return skuList, err -} - -// todo, GetSkuCategoryWithVendor与GetSkusWithVendor, -// 如果mustDirty为true,应该是要thing_map为基表,LEFT JOIN原始实体表,否则当原始实体记录在未同步前被物理删除后,无法真正同步 - -// 多门店平台使用,当前只有京东 -func GetSkuCategoryWithVendor(db *DaoDB, vendorIDs []int, appOrgCodes []string, parentCatID int, catIDs []int, mustDirty bool) (catList []*SkuStoreCatInfo, err error) { - sql := ` - SELECT - t1m.vendor_id, t1m.vendor_org_code, - - t1m.id map_id, - t1.*, - t1m.vendor_thing_id vendor_cat_id, - t1m.sync_status cat_sync_status, - - t1pm.id parent_map_id, - t1p.name parent_cat_name, - t1pm.vendor_thing_id parent_vendor_cat_id, - t1pm.sync_status parent_cat_sync_status - FROM sku_category t1 - LEFT JOIN thing_map t1m ON t1m.thing_id = t1.id AND t1m.thing_type = ? AND t1m.deleted_at = ?` - sqlParams := []interface{}{ - model.ThingTypeCategory, - utils.DefaultTimeValue, - } - if len(vendorIDs) > 0 { - sql += " AND t1m.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" - sqlParams = append(sqlParams, vendorIDs) - } - if len(appOrgCodes) > 0 { - sql += " AND t1m.vendor_org_code IN (" + GenQuestionMarks(len(appOrgCodes)) + ")" - sqlParams = append(sqlParams, appOrgCodes) - } - sql += ` - LEFT JOIN sku_category t1p ON t1p.id = t1.parent_id - LEFT JOIN thing_map t1pm ON t1pm.thing_id = t1p.id AND t1pm.thing_type = ? AND t1m.deleted_at = ? - AND t1pm.vendor_id = t1m.vendor_id AND t1pm.vendor_org_code = t1m.vendor_org_code - WHERE 1 = 1 - AND t1.is_sync <> ? - ` - sqlParams = append(sqlParams, model.ThingTypeCategory, utils.DefaultTimeValue, model.YES) - if mustDirty { - sql += " AND t1m.sync_status IS NOT NULL AND t1m.sync_status <> 0" - } else { - sql += " AND t1.deleted_at = ?" - sqlParams = append(sqlParams, utils.DefaultTimeValue) - } - if len(catIDs) > 0 { - sql += " AND t1.id IN (" + GenQuestionMarks(len(catIDs)) + ")" - sqlParams = append(sqlParams, catIDs) - } - if parentCatID >= 0 { - sql += " AND t1.parent_id = ?" - sqlParams = append(sqlParams, parentCatID) - } - sql += " ORDER BY t1.seq" - err = GetRows(db, &catList, sql, sqlParams...) - return catList, err -} - -// 多门店平台使用,当前只有京东 -func GetSkusWithVendor(db *DaoDB, vendorIDs []int, appOrgCodes []string, nameIDs, skuIDs []int, mustDirty bool) (skuList []*StoreSkuSyncInfo, err error) { - sql := ` - SELECT - t1m.vendor_id, t1m.vendor_org_code, - - t1m.id bind_id, - t1.*, - t1.id sku_id, - t1m.vendor_thing_id vendor_sku_id, - t1m.sync_status sku_sync_status, - - t2.price, - t2.price unit_price, - t2.prefix, - t2.name, - t2.unit, - t2.upc, - t2.is_global, - t2.status name_status, - IF(t11.resource_type IS NULL OR t11.resource_type <> ?, t2.img, '') img, - IF(t12.resource_type IS NULL OR t12.resource_type <> ?, t2.img2, '') img2, - t2.desc_img, - t3.jd_category_id vendor_vendor_cat_id, - tsu.ex_prefix, tsu.begin_at ex_prefix_begin, tsu.end_at ex_prefix_end, tsu.img_watermark, - t3m.sync_status cat_sync_status, - t3m.vendor_thing_id vendor_cat_id, - tsy.vendor_category_id sku_vendor_map_cat_id - - FROM sku t1 - LEFT JOIN thing_map t1m ON t1m.thing_id = t1.id AND t1m.thing_type = ? AND t1m.deleted_at = ?` - sqlParams := []interface{}{ - model.MimeTypeGif, - model.MimeTypeGif, - model.ThingTypeSku, - utils.DefaultTimeValue, - } - if len(vendorIDs) > 0 { - sql += " AND t1m.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" - sqlParams = append(sqlParams, vendorIDs) - } - if len(appOrgCodes) > 0 { - sql += " AND t1m.vendor_org_code IN (" + GenQuestionMarks(len(appOrgCodes)) + ")" - sqlParams = append(sqlParams, appOrgCodes) - } - sql += ` - JOIN sku_name t2 ON t2.id = t1.name_id - LEFT JOIN sku_category t3 ON t3.id = t2.category_id - LEFT JOIN thing_map t3m ON t3m.thing_id = t3.id AND t3m.thing_type = ? AND t3m.deleted_at = ? - AND t3m.vendor_id = t1m.vendor_id AND t3m.vendor_org_code = t1m.vendor_org_code - LEFT JOIN data_resource t11 ON t11.main_url = t2.img - LEFT JOIN data_resource t12 ON t12.main_url = t2.img2 - LEFT JOIN sku_exinfo_map tsu ON tsu.name_id = t2.id AND tsu.deleted_at = ? AND tsu.vendor_id = t1m.vendor_id - LEFT JOIN sku_vendor_category_map tsy ON tsy.name_id = t2.id AND tsy.vendor_id = ? AND tsy.deleted_at = ? - WHERE 1 = 1 - ` - sqlParams = append(sqlParams, model.ThingTypeCategory, utils.DefaultTimeValue, utils.DefaultTimeValue, model.VendorIDJD, utils.DefaultTimeValue) - if mustDirty { - sql += " AND t1m.sync_status IS NOT NULL AND t1m.sync_status <> 0" - } else { - sql += " AND t1.deleted_at = ?" - sqlParams = append(sqlParams, utils.DefaultTimeValue) - } - if len(nameIDs) > 0 { - sql += " AND t1.name_id IN (" + GenQuestionMarks(len(nameIDs)) + ")" - sqlParams = append(sqlParams, nameIDs) - } - if len(skuIDs) > 0 { - sql += " AND t1.id IN (" + GenQuestionMarks(len(skuIDs)) + ")" - sqlParams = append(sqlParams, skuIDs) - } - sql += " ORDER BY t1.seq" - if err = GetRows(db, &skuList, sql, sqlParams...); err == nil { - skuPlaceList, err2 := GetSkuNamePlaces(db, nameIDs, skuIDs) - if err = err2; err == nil { - skuPlaceMap := make(map[int][]*SkuNamePlace) - for _, v := range skuPlaceList { - skuPlaceMap[v.SkuID] = append(skuPlaceMap[v.SkuID], v) - } - for _, v := range skuList { - if v.IsGlobal == 0 { - for _, v2 := range skuPlaceMap[v.SkuID] { - // 京东到家 - if v2.JdCode > 0 { - v.SellCities = append(v.SellCities, utils.Int2Str(v2.JdCode)) - } - } - } - } - } - } - return skuList, err -} - -func GetSkuNamePlaces(db *DaoDB, nameIDs, skuIDs []int) (skuPlaceList []*SkuNamePlace, err error) { - sql := ` - SELECT - t4.*, - t2.id sku_id, t2.name_id - FROM sku t2 - JOIN sku_name_place_bind t3 ON t3.name_id = t2.name_id - JOIN place t4 ON t4.code = t3.place_code - WHERE t2.deleted_at = ? - ` - sqlParams := []interface{}{utils.DefaultTimeValue} - if len(nameIDs) > 0 { - sql += " AND t2.name_id IN (" + GenQuestionMarks(len(nameIDs)) + ")" - sqlParams = append(sqlParams, nameIDs) - } - if len(skuIDs) > 0 { - sql += " AND t2.id IN (" + GenQuestionMarks(len(skuIDs)) + ")" - sqlParams = append(sqlParams, skuIDs) - } - err = GetRows(db, &skuPlaceList, sql, sqlParams...) - return skuPlaceList, err -} - -func GetUpcDepot(db *DaoDB, upc string) (result *aliupcapi.GetAliUpcInfoResult, err error) { - sql := ` - SELECT * FROM upc_depot WHERE code = ? - ` - sqlParams := []interface{}{upc} - err = GetRow(db, &result, sql, sqlParams...) - return result, err -} - -func InsertUpcDepot(db *DaoDB, result *aliupcapi.GetAliUpcInfoResult) (err error) { - sql := ` - INSERT INTO upc_depot (code, goods_name, manu_name, manu_address, spec, price, img, goods_type, ycg, trade_mark, remark) - VALUES (?,?,?,?,?,?,?,?,?,?,?) - ` - sqlParams := []interface{}{ - result.Code, - result.GoodsName, - result.ManuName, - result.ManuAddress, - result.Spec, - result.Price, - result.Img, - result.GoodsType, - result.Ycg, - result.Trademark, - result.Remark, - } - _, err = ExecuteSQL(db, sql, sqlParams) - return err -} - -func GetSkuExinfos(db *DaoDB, nameIDs []int, vendorIDs []int, exPrefix string, fromTime, toTime time.Time) (skuExinfoMaps []*model.SkuExinfoMap, err error) { - sql := ` - SELECT * - FROM sku_exinfo_map - WHERE deleted_at = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - } - if len(nameIDs) > 0 { - sql += " AND name_id IN (" + GenQuestionMarks(len(nameIDs)) + ")" - sqlParams = append(sqlParams, nameIDs) - } - if len(vendorIDs) > 0 { - sql += " AND vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" - sqlParams = append(sqlParams, vendorIDs) - } - if exPrefix != "" { - sql += " AND ex_prefix LIKE ?" - sqlParams = append(sqlParams, "%"+exPrefix+"%") - } - if fromTime != utils.ZeroTimeValue && toTime != utils.ZeroTimeValue { - sql += " AND NOT (begin_at > ? OR end_at < ?)" - sqlParams = append(sqlParams, toTime, fromTime) - } - if err = GetRows(db, &skuExinfoMaps, sql, sqlParams...); err == nil { - return skuExinfoMaps, nil - } - return nil, err -} - -func GetSkuVendorCategoryMaps(db *DaoDB, nameIDs, vendorIDs []int, vendorCategoryIDs []string) (skuVendorCategoryMaps []*model.SkuVendorCategoryMap, err error) { - sql := ` - SELECT * - FROM sku_vendor_category_map - WHERE deleted_at = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - } - if len(nameIDs) > 0 { - sql += " AND name_id IN (" + GenQuestionMarks(len(nameIDs)) + ")" - sqlParams = append(sqlParams, nameIDs) - } - if len(vendorIDs) > 0 { - sql += " AND vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" - sqlParams = append(sqlParams, vendorIDs) - } - if len(vendorCategoryIDs) > 0 { - sql += " AND vendor_category_id IN (" + GenQuestionMarks(len(vendorCategoryIDs)) + ")" - sqlParams = append(sqlParams, vendorCategoryIDs) - } - if err = GetRows(db, &skuVendorCategoryMaps, sql, sqlParams...); err == nil { - return skuVendorCategoryMaps, nil - } - return nil, err -} diff --git a/business/model/dao/sku_test.go b/business/model/dao/sku_test.go deleted file mode 100644 index 50e7e45e0..000000000 --- a/business/model/dao/sku_test.go +++ /dev/null @@ -1,16 +0,0 @@ -package dao - -import ( - "testing" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/globals" -) - -func TestGetSkusWithVendor(t *testing.T) { - skuList, err := GetSkusWithVendor(GetDB(), nil, nil, []int{17368}, nil, true) - if err != nil { - t.Fatal(err) - } - globals.SugarLogger.Debug(utils.Format4Output(skuList, false)) -} diff --git a/business/model/dao/store.go b/business/model/dao/store.go deleted file mode 100644 index b3d914b41..000000000 --- a/business/model/dao/store.go +++ /dev/null @@ -1,915 +0,0 @@ -package dao - -import ( - "sort" - "time" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/globals" -) - -// 带购物平台信息的 -type StoreDetail struct { - model.Store - - VendorOrgCode string `orm:"size(32)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空 - - VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"` - VendorStoreName string `json:"vendorStoreName"` - VendorStatus int `json:"vendor_status"` // 取值同Store.Status - DeliveryFeeDeductionSill int `json:"deliveryFeeDeductionSill"` - DeliveryFeeDeductionFee int `json:"deliveryFeeDeductionFee"` - SyncStatus int8 `orm:"default(2)" json:"syncStatus"` - - PricePercentage int16 `orm:"default(100)" json:"pricePercentage"` // todo 厂商价格相对于本地价格的百分比,这个字段的修改会比较特殊,因为可能需要刷新厂商价格 - PricePercentagePackStr string `orm:"size(4096)" json:"-"` // - PricePercentagePackObj model.PricePercentagePack `orm:"-" json:"-"` - - FreightDeductionPackStr string `orm:"size(4096)" json:"-"` // - FreightDeductionPackObj *model.FreightDeductionPack `orm:"-" json:"-"` - - AutoPickup int8 `orm:"default(1)" json:"autoPickup"` // 是否自动拣货 - DeliveryType int8 `orm:"default(0)" json:"deliveryType"` // 配送类型 - DeliveryCompetition int8 `orm:"default(1)" json:"deliveryCompetition"` // 是否支持配送竞争 - IsSync int8 `orm:"default(1)" json:"isSync"` // 是否同步 - - DistrictName string `json:"districtName"` - CityName string `json:"cityName"` - ProvinceName string `json:"provinceName"` //省名 - JdCode int `json:"jdCode"` - JdsCode int `json:"jdsCode"` //京东商城地址代码 - JdsStreetCode int `json:"jdsStreetCode"` //京东商城直辖市街道code - JdsStreetName string `json:"jdsStreetName"` //京东商城直辖市街道 - - IsAutoOrder int8 `json:"isAutoOrder"` // 平台是否自动接单,-1:否,0:未知,1:是 - MarketManName string `json:"marketManName"` //市场负责人 - OperatorName string `json:"operatorName"` //运营负责人 - OperatorName2 string `json:"operatorName2"` - OperatorName3 string `json:"operatorName3"` - - JdStoreLevel string `json:"jdStoreLevel"` //京东门店等级 - IsOrder int `json:"isOrder"` //是否是下预订单门店 - IsSupplyGoods int `json:"isSupplyGoods"` - - YbAppID string `orm:"column(yb_app_id)" json:"ybAppID"` - YbAppKey string `json:"ybAppKey"` - YbStorePrefix string `json:"ybStorePrefix"` -} - -// 带快递门店信息的 -type StoreDetail2 struct { - model.Store - - VendorID int `orm:"column(vendor_id)" json:"vendorID"` - VendorStoreID string `orm:"column(vendor_store_id)" json:"vendorStoreID"` // 这个其实是京西快递门店ID的概念 - CourierStatus int `json:"courierStatus"` - AuditStatus int `json:"auditStatus"` - - DistrictName string `json:"districtName"` - CityName string `json:"cityName"` -} - -type CityBrankBranch struct { - CityCode int - PayeeBankBranchName string `orm:"size(255)" json:"payeeBankBranchName"` // 开户支行 - PayeeBankCode string `orm:"size(8)" json:"payeeBankCode"` // 开户行代码 -} - -type StorePriceScore struct { - StoreID int `orm:"column(store_id)" json:"storeID"` - StoreName string `json:"storeName"` - StoreScore float64 `json:"storeScore"` - CityName string `json:"cityName"` - DirectDownCount int `json:"directDownCount"` - SecKillCount int `json:"secKillCount"` -} - -type StorePriceScoreEx struct { - StorePriceScoreList []*StorePriceScore `json:"storePriceScoreList"` - TotalCount int `json:"totalCount"` -} - -func (s *StoreDetail) GetPricePerentage(price int) (pricePercentage int) { - return pricePercentage -} - -func getStoreDetail(db *DaoDB, storeID, vendorID int, vendorStoreID string) (storeDetail *StoreDetail, err error) { - sql := ` - SELECT t1.*, - t2.vendor_store_id, t2.status vendor_status, t2.delivery_fee_deduction_sill, t2.delivery_fee_deduction_fee, t2.sync_status, t2.vendor_org_code, - t2.price_percentage, t2.auto_pickup, t2.delivery_type, t2.delivery_competition, t2.is_sync, t2.vendor_store_name, t2.is_order, t2.yb_app_id, t2.yb_app_key, t2.yb_store_prefix, - t2.jds_street_code, t2.jds_street_name, t2.is_supply_goods, - t3.value price_percentage_pack_str, - t4.value freight_deduction_pack_str, - province.name province_name, - district.name district_name, - district.jds_code jds_code, - district.jd_code jd_code, - city.name city_name, - IF(mm.name <> '', mm.name, mm.user_id2) market_man_name, - IF(om.name <> '', om.name, om.user_id2) operator_name, - IF(om2.name <> '', om2.name, om2.user_id2) operator_name2, - IF(om3.name <> '', om3.name, om3.user_id2) operator_name3 - FROM store t1 - LEFT JOIN store_map t2 ON t1.id = t2.store_id AND t2.vendor_id = ? AND t2.deleted_at = ? - LEFT JOIN place city ON city.code = t1.city_code - LEFT JOIN place district ON district.code = t1.district_code - LEFT JOIN place province ON city.parent_code = province.code - LEFT JOIN new_config t3 ON t3.key = t2.price_percentage_pack AND t3.type = ? AND t3.deleted_at = ? - LEFT JOIN new_config t4 ON t4.key = t2.freight_deduction_pack AND t4.type = ? AND t4.deleted_at = ? - LEFT JOIN user mm ON mm.mobile <> '' AND mm.mobile = t1.market_man_phone - LEFT JOIN user om ON om.mobile <> '' AND om.mobile = t1.operator_phone - LEFT JOIN user om2 ON om2.mobile <> '' AND om2.mobile = t1.operator_phone2 - LEFT JOIN user om3 ON om3.mobile <> '' AND om3.mobile = t1.operator_phone3 - WHERE t1.deleted_at = ? - ` - sqlParams := []interface{}{ - vendorID, - utils.DefaultTimeValue, - model.ConfigTypePricePack, - utils.DefaultTimeValue, - model.ConfigTypeFreightPack, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - } - // if vendorID != model.VendorIDJX { - // sql += " AND t2.id IS NOT NULL" - // } - if storeID > 0 { - sql += " AND t1.id = ?" - sqlParams = append(sqlParams, storeID) - } - if vendorStoreID != "" { - sql += " AND t2.vendor_store_id = ?" - sqlParams = append(sqlParams, vendorStoreID) - } - if err = GetRow(db, &storeDetail, sql, sqlParams...); err == nil { - storeDetail.PricePercentagePackObj = PricePercentagePack2Obj(storeDetail.PricePercentagePackStr) - storeDetail.FreightDeductionPackObj = FreightDeductionPack2Obj(storeDetail.FreightDeductionPackStr) - // if storeDetail.VendorStoreID == "" { - // storeDetail.VendorStatus = storeDetail.Status - // storeDetail.PricePercentage = model.DefVendorPricePercentage - // storeDetail.AutoPickup = 1 - // storeDetail.DeliveryType = model.StoreDeliveryTypeByStore - // storeDetail.DeliveryCompetition = 1 - // if vendorID == model.VendorIDJX { - // storeDetail.IsSync = 1 - // } - // } - return storeDetail, nil - } - return nil, err -} - -func GetStoreDetail(db *DaoDB, storeID, vendorID int) (storeDetail *StoreDetail, err error) { - return getStoreDetail(db, storeID, vendorID, "") -} - -func GetStoreDetailByVendorStoreID(db *DaoDB, vendorStoreID string, vendorID int) (storeDetail *StoreDetail, err error) { - if vendorID != model.VendorIDJX { - return getStoreDetail(db, 0, vendorID, vendorStoreID) - } - if storeDetail, err = getStoreDetail(db, int(utils.Str2Int64WithDefault(vendorStoreID, 0)), vendorID, ""); err == nil { - storeDetail.VendorStoreID = vendorStoreID - } - return storeDetail, err -} - -// 这个返回的地点信息是城市 -func GetStoreDetail2(db *DaoDB, storeID int, vendorStoreID string, vendorID int) (storeDetail *StoreDetail2, err error) { - sql := ` - SELECT t1.*, - city.name city_name, district.name district_name, - t3.vendor_store_id, t3.vendor_id, t3.status courier_status, t3.audit_status - FROM store t1 - LEFT JOIN place city ON city.code = t1.city_code - LEFT JOIN place district ON district.code = t1.district_code - LEFT JOIN store_courier_map t3 ON t3.store_id = t1.id AND t3.vendor_id = ? AND t3.deleted_at = ? - WHERE t1.deleted_at = ?` - sqlParams := []interface{}{ - vendorID, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - } - if storeID != 0 { - sql += " AND t1.id = ?" - sqlParams = append(sqlParams, storeID) - } - if vendorStoreID != "" { - sql += " AND t3.vendor_store_id = ?" - sqlParams = append(sqlParams, vendorStoreID) - } - err = GetRow(db, &storeDetail, sql, sqlParams...) - return storeDetail, err -} - -func GetStoreCourierList(db *DaoDB, storeIDs, vendorIDs []int, status, auditStatus int) (courierStoreList []*model.StoreCourierMap, err error) { - sql := ` - SELECT t1.* - FROM store_courier_map t1 - WHERE t1.deleted_at = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - } - if len(storeIDs) > 0 { - sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - if len(vendorIDs) > 0 { - sql += " AND t1.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" - sqlParams = append(sqlParams, vendorIDs) - } - if status != model.StoreStatusAll { - sql += " AND t1.status = ?" - sqlParams = append(sqlParams, status) - } - if auditStatus != model.StoreAuditStatusAll { - sql += " AND t1.audit_status = ?" - sqlParams = append(sqlParams, auditStatus) - } - if err = GetRows(db, &courierStoreList, sql, sqlParams...); err == nil { - return courierStoreList, nil - } - return nil, err -} - -func GetStoresMapList2(db *DaoDB, vendorIDs, storeIDs, storeStatuss []int, status, isSync int, pricePack, name string, mustDirty bool) (storeMapList []*model.StoreMap, err error) { - sql := ` - SELECT t1.* - FROM store_map t1 - JOIN store t2 ON t2.id = t1.store_id AND t2.deleted_at = ? - WHERE t1.deleted_at = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - utils.DefaultTimeValue, - } - if len(vendorIDs) > 0 { - sql += " AND t1.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" - sqlParams = append(sqlParams, vendorIDs) - } - if len(storeIDs) > 0 { - sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - if len(storeStatuss) > 0 { - sql += " AND t2.status IN (" + GenQuestionMarks(len(storeStatuss)) + ")" - sqlParams = append(sqlParams, storeStatuss) - } - if status != model.StoreStatusAll { - sql += " AND t1.status = ?" - sqlParams = append(sqlParams, status) - } - if isSync != model.StoreIsSyncAll { - sql += " AND t1.is_sync = ?" - sqlParams = append(sqlParams, isSync) - } - if pricePack != "" { - sql += " AND t1.price_percentage_pack = ?" - sqlParams = append(sqlParams, pricePack) - } - if name != "" { - sql += " AND t2.name LIKE ?" - sqlParams = append(sqlParams, "%"+name+"%") - } - if mustDirty { - sql += " AND t1.sync_status <> 0" - } - sql += " ORDER BY t1.store_id , t1.vendor_id" - if err = GetRows(db, &storeMapList, sql, sqlParams...); err == nil { - return storeMapList, nil - } - return nil, err -} - -func SetStoresMapSyncStatus(db *DaoDB, vendorIDs, storeIDs []int, syncStatus int8) (err error) { - sql := ` - UPDATE store_map t1 - JOIN store t2 ON t2.id = t1.store_id AND t2.deleted_at = ? - SET t1.sync_status = t1.sync_status | ? - WHERE t1.deleted_at = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - syncStatus, - utils.DefaultTimeValue, - } - if len(vendorIDs) > 0 { - sql += " AND t1.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" - sqlParams = append(sqlParams, vendorIDs) - } - if len(storeIDs) > 0 { - sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - _, err = ExecuteSQL(db, sql, sqlParams...) - return err -} - -func GetStoresMapList(db *DaoDB, vendorIDs, storeIDs, storeStatuss []int, status, isSync int, pricePack, name string) (storeMapList []*model.StoreMap, err error) { - return GetStoresMapList2(db, vendorIDs, storeIDs, storeStatuss, status, isSync, pricePack, name, false) -} - -func StoreMapList2Map(storeMapList []*model.StoreMap) (storeMapMap map[int][]*model.StoreMap) { - storeMapMap = make(map[int][]*model.StoreMap) - for _, v := range storeMapList { - storeMapMap[v.StoreID] = append(storeMapMap[v.StoreID], v) - } - return storeMapMap -} - -func StoreCourierList2Map(storeCourierList []*model.StoreCourierMap) (storeCourierMap map[int][]*model.StoreCourierMap) { - storeCourierMap = make(map[int][]*model.StoreCourierMap) - for _, v := range storeCourierList { - storeCourierMap[v.StoreID] = append(storeCourierMap[v.StoreID], v) - } - return storeCourierMap -} - -// 此函数在检测到一个门店的所有平台状态一样,且不为StoreStatusOpened时, -// 将平台门店状态全部改为StoreStatusOpened,则把京西门店状态改为之前那个统一的平台门店状态 -func FormalizeStoreStatus(db *DaoDB, storeID, storeStatus int) (err error) { - sql := ` - SELECT DISTINCT t1.status - FROM store_map t1 - WHERE t1.deleted_at = ? AND t1.store_id = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - storeID, - } - var statusList []int - if err = GetRows(db, &statusList, sql, sqlParams...); err == nil { - if len(statusList) == 1 { - if statusList[0] != model.StoreStatusOpened { - Begin(db) - defer func() { - if r := recover(); r != nil || err != nil { - Rollback(db) - if r != nil { - panic(r) - } - } - }() - if storeStatus != statusList[0] { - store := &model.Store{} - store.ID = storeID - if _, err = UpdateEntityLogically(db, store, map[string]interface{}{ - model.FieldStatus: statusList[0], - }, model.AdminName, nil); err != nil { - return err - } - } - if _, err = UpdateEntityLogically(db, &model.StoreMap{}, map[string]interface{}{ - model.FieldStatus: model.StoreStatusOpened, - }, model.AdminName, map[string]interface{}{ - model.FieldStoreID: storeID, - model.FieldDeletedAt: utils.DefaultTimeValue, - }); err != nil { - return err - } - Commit(db) - } - } - } - return err -} - -func GetVendorStoreSnapshot(db *DaoDB, snapshotAt time.Time) (snapshotList []*model.VendorStoreSnapshot, err error) { - sql := ` - SELECT t1.* - FROM vendor_store_snapshot t1 - LEFT JOIN store t2 ON t2.id = t1.store_id - WHERE t1.snapshot_at = ? - ORDER BY t2.city_code, t1.store_id, t1.vendor_id` - err = GetRows(db, &snapshotList, sql, snapshotAt) - return snapshotList, err -} - -func DeleteVendorStoreSnapshot(db *DaoDB, minSnapshotAt time.Time) (err error) { - _, err = ExecuteSQL(db, ` - DELETE t1 - FROM vendor_store_snapshot t1 - WHERE t1.snapshot_at < ? - `, minSnapshotAt) - return err -} - -func GetRebindPrinterStoreList(db *DaoDB) (storeList []*model.Store, err error) { - err = GetRows(db, &storeList, ` - SELECT * - FROM store t1 - WHERE t1.deleted_at = ? AND printer_vendor_id >= ? AND printer_bind_info <> '' - `, utils.DefaultTimeValue, model.VendorIDPrinterBegin) - return storeList, err -} - -// 容错用 -type tPricePercentageItemFloat struct { - BeginPrice float64 `json:"beginPrice"` // 起始价格区间(包括) - PricePercentage float64 `json:"pricePercentage"` // 调价比例 - PriceAdd float64 `json:"priceAdd"` // 调价额定值 -} - -func PricePercentagePack2Obj(packStr string) (obj model.PricePercentagePack) { - if packStr != "" { - var floatObj []*tPricePercentageItemFloat - if err := utils.UnmarshalUseNumber([]byte(packStr), &floatObj); err == nil { - if len(floatObj) > 0 { - obj = make(model.PricePercentagePack, len(floatObj)) - for k, v := range floatObj { - if v.PricePercentage >= 500 || v.PricePercentage <= 80 { - return nil - } - obj[k] = &model.PricePercentageItem{ - BeginPrice: int(v.BeginPrice), - PricePercentage: int(v.PricePercentage), - PriceAdd: int(v.PriceAdd), - } - } - sort.Sort(obj) - } - } - } - return obj -} - -func AddStoreCategoryMap(db *DaoDB, storeID, categoryID int, vendorID int, vendorCategoryID string, status int8, userName string) (err error) { - storeCat := &model.StoreSkuCategoryMap{ - StoreID: storeID, - CategoryID: categoryID, - MtwmSyncStatus: model.SyncFlagNewMask, - EbaiSyncStatus: model.SyncFlagNewMask, - YbSyncStatus: model.SyncFlagNewMask, - } - storeCat.DeletedAt = utils.DefaultTimeValue - if err = GetEntity(db, storeCat, model.FieldStoreID, model.FieldCategoryID, model.FieldDeletedAt); err != nil && !IsNoRowsError(err) { - return err - } - if vendorID == model.VendorIDMTWM { - storeCat.MtwmID = vendorCategoryID - storeCat.MtwmSyncStatus = status - } else if vendorID == model.VendorIDEBAI { - storeCat.EbaiID = utils.Str2Int64WithDefault(vendorCategoryID, 0) - storeCat.EbaiSyncStatus = status - } else if vendorID == model.VendorIDYB { - storeCat.YbID = utils.Str2Int64WithDefault(vendorCategoryID, 0) - storeCat.YbSyncStatus = status - } else if vendorID == model.VendorIDJDShop { - storeCat.JdsID = utils.Str2Int64WithDefault(vendorCategoryID, 0) - storeCat.JdsSyncStatus = status - } else { - panic("unsupported vendor") - } - if storeCat.ID == 0 { - WrapAddIDCULDEntity(storeCat, userName) - if err = CreateEntity(db, storeCat); IsDuplicateError(err) { - err = nil - } - } else { - WrapUpdateULEntity(storeCat, userName) - _, err = UpdateEntity(db, storeCat) - } - return err -} - -func GetOpenedStoreCouriersByStoreID(db *DaoDB, storeID, vendorID int) (storeMaps []*model.StoreCourierMap, err error) { - if db == nil { - db = GetDB() - } - if err = utils.CallFuncLogError(func() error { - sql := ` - SELECT * - FROM store_courier_map - WHERE store_id = ? AND status = ? AND deleted_at = ? - ` - sqlParams := []interface{}{ - storeID, - model.StoreStatusOpened, - utils.DefaultTimeValue, - } - if vendorID != -1 { - sql += " AND vendor_id = ?" - sqlParams = append(sqlParams, vendorID) - } - return GetRows(db, &storeMaps, sql, sqlParams...) - }, "GetStoreCouriersByStoreID storeID:%d, vendorID:%d", storeID, vendorID); err != nil { - return nil, err - } - return storeMaps, nil -} - -func GetStoreList(db *DaoDB, idList, cityCodes, statuss []int, mobileList []string, shortRoleName string) (storeList []*model.Store, err error) { - sql := ` - SELECT t1.* - FROM store t1 - WHERE t1.deleted_at = ?` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - } - if len(idList) > 0 { - sql += " AND t1.id IN (" + GenQuestionMarks(len(idList)) + ")" - sqlParams = append(sqlParams, idList) - } - if len(cityCodes) > 0 { - sql += " AND t1.city_code IN (" + GenQuestionMarks(len(cityCodes)) + ")" - sqlParams = append(sqlParams, cityCodes) - } - if len(statuss) > 0 { - sql += " AND t1.status IN (" + GenQuestionMarks(len(statuss)) + ")" - sqlParams = append(sqlParams, statuss) - } - if len(mobileList) > 0 { - sql += " AND (t1.tel1 IN (" + GenQuestionMarks(len(mobileList)) + ") OR t1.tel2 IN (" + GenQuestionMarks(len(mobileList)) + "))" - sqlParams = append(sqlParams, mobileList, mobileList) - } - if shortRoleName != "" { - sql += " AND (t1.market_man_role = ? OR t1.operator_role = ? OR t1.operator_role2 = ? OR t1.operator_role3 = ?)" - sqlParams = append(sqlParams, shortRoleName, shortRoleName, shortRoleName, shortRoleName) - } - err = GetRows(db, &storeList, sql, sqlParams...) - return storeList, err -} - -func GetCityBankBranches(db *DaoDB, cityCode int, bankCode string) (list []*CityBrankBranch, err error) { - sql := ` - SELECT payee_bank_code, city_code, payee_bank_branch_name - FROM store - WHERE payee_bank_branch_name <> ''` - sqlParams := []interface{}{} - if cityCode > 0 { - sql += " AND city_code = ?" - sqlParams = append(sqlParams, cityCode) - } else { - sql += " AND city_code <> 0" - } - if bankCode != "" { - sql += " AND payee_bank_code = ?" - sqlParams = append(sqlParams, bankCode) - } else { - sql += " AND payee_bank_code <> ''" - } - sql += " GROUP BY 1,2,3;" - err = GetRows(db, &list, sql, sqlParams...) - return list, err -} - -func FreightDeductionPack2Obj(packStr string) (obj *model.FreightDeductionPack) { - if packStr != "" { - if err := utils.UnmarshalUseNumber([]byte(packStr), &obj); err == nil { - sort.Sort(obj) - } - } - return obj -} - -func GetStoreMapsListWithoutDisabled(db *DaoDB, vendorIDs []int, status int) (storeMapList []*model.StoreMap, err error) { - sql := ` - SELECT * - FROM store_map - WHERE 1=1 - ` - sqlParams := []interface{}{} - if len(vendorIDs) > 0 { - sql += " AND vendor_id in (" + GenQuestionMarks(len(vendorIDs)) + ")" - sqlParams = append(sqlParams, vendorIDs) - } - if status != model.StoreStatusAll { - sql += " AND status != ?" - sqlParams = append(sqlParams, status) - } - err = GetRows(db, &storeMapList, sql, sqlParams...) - return storeMapList, err -} - -func GetStorePriceScore(db *DaoDB, storeIDs, vendorIDs []int, fromScore, toScore, sort int, snapDate time.Time, offset, pageSize int) (StorePriceScore []*StorePriceScore, totalCount int, err error) { - sql := ` - SELECT SQL_CALC_FOUND_ROWS a.store_id, score store_score, e.name city_name, b.name store_name, t2.direct_down_count, t2.sec_kill_count - FROM store_price_score_snapshot a - JOIN store b ON b.id = a.store_id - JOIN place e ON e.code = b.city_code - LEFT JOIN (SELECT t1.store_id,count(t1.type = ? OR NULL) direct_down_count, count(t1.type = ? OR NULL) sec_kill_count - FROM( - SELECT a.store_id, a.sku_id,d.type - FROM store_sku_bind a - LEFT JOIN act_store_sku b ON a.store_id = b.store_id AND b.sku_id = a.sku_id - LEFT JOIN act_map c ON c.act_id = b.act_id - LEFT JOIN act d ON d.id = c.act_id - WHERE 1=1 - AND d.status = ? - ` - sqlParams := []interface{}{ - model.ActSkuDirectDown, model.ActSkuSecKill, model.ActStatusCreated, - } - if len(storeIDs) > 0 { - sql += " AND a.store_id IN(" + GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - if len(vendorIDs) > 0 { - sql += " AND c.vendor_id IN(" + GenQuestionMarks(len(vendorIDs)) + ")" - sqlParams = append(sqlParams, vendorIDs) - } - sql += ` - AND NOW() BETWEEN d.begin_at AND d.end_at - AND a.status = ? - AND a.deleted_at = ? AND b.deleted_at = ? AND c.deleted_at = ? AND d.deleted_at = ? - GROUP BY 1,2,3)t1 - GROUP BY 1)t2 ON t2.store_id = a.store_id - WHERE 1=1 - ` - sqlParams = append(sqlParams, model.StoreSkuBindStatusNormal, utils.DefaultTimeValue, utils.DefaultTimeValue, utils.DefaultTimeValue, utils.DefaultTimeValue) - if fromScore != 0 || toScore != 0 { - sql += " AND a.score BETWEEN ? AND ?" - sqlParams = append(sqlParams, fromScore, toScore) - } - if len(storeIDs) > 0 { - sql += " AND a.store_id IN(" + GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - if !utils.IsTimeZero(snapDate) { - sql += " AND a.snapshot_at = ?" - sqlParams = append(sqlParams, snapDate) - } - if sort == 1 { - sql += " ORDER BY a.score" - } else if sort == -1 { - sql += " ORDER BY a.score DESC" - } else if sort == 2 { - sql += " ORDER BY t2.direct_down_count" - } else if sort == -2 { - sql += " ORDER BY t2.direct_down_count DESC" - } else if sort == 3 { - sql += " ORDER BY t2.sec_kill_count" - } else if sort == -3 { - sql += " ORDER BY t2.sec_kill_count DESC" - } - sql += " LIMIT ? OFFSET ?" - sqlParams = append(sqlParams, pageSize, offset) - Begin(db) - defer Commit(db) - if err = GetRows(db, &StorePriceScore, sql, sqlParams...); err == nil { - totalCount = GetLastTotalRowCount(db) - } - return StorePriceScore, totalCount, err -} - -func GetStorePriceScoreSnapshot(db *DaoDB, snapDate time.Time) (storePriceScoreSnapshot []*model.StorePriceScoreSnapshot, err error) { - sql := ` - SELECT c.store_id,ROUND(count(c.unit_price * IF(d.pay_percentage < 50 , 70, d.pay_percentage) / 100 <= a.mid_unit_price or NULL)/count(*)*100,2) score - FROM price_refer_snapshot a - JOIN store_sku_bind c ON c.sku_id = a.sku_id AND c.deleted_at = ? - JOIN store d ON c.store_id = d.id AND d.city_code = a.city_code AND d.deleted_at = ? AND d.status != ? - WHERE 1=1 - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - utils.DefaultTimeValue, model.StoreStatusDisabled, - } - if !utils.IsTimeZero(snapDate) { - sql += " AND a.snapshot_at = ?" - sqlParams = append(sqlParams, snapDate) - } - sql += ` - GROUP BY c.store_id - ` - err = GetRows(db, &storePriceScoreSnapshot, sql, sqlParams...) - return storePriceScoreSnapshot, err -} - -func SetStoreMapSyncStatus(db *DaoDB, vendorIDs, storeIDs []int, syncStatus int) (num int64, err error) { - globals.SugarLogger.Debugf("SetStoreMapSyncStatus, vendorIDs:%v, storeIDs:%v", vendorIDs, storeIDs) - - sql := ` - UPDATE store_map t1 - SET t1.sync_status = t1.sync_status | ? - ` - sqlParams := []interface{}{ - syncStatus, - } - sql += " WHERE t1.is_sync <> 0 AND t1.deleted_at = ? AND t1.sync_status & ? = 0" - sqlParams = append(sqlParams, utils.DefaultTimeValue, model.SyncFlagDeletedMask) - if len(vendorIDs) > 0 { - sql += " AND t1.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" - sqlParams = append(sqlParams, vendorIDs) - } - if len(storeIDs) > 0 { - sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - return ExecuteSQL(db, sql, sqlParams...) -} - -func GetOrderNotifyPhones(db *DaoDB, storeID int) (phoneList []string) { - store := &model.Store{} - store.ID = storeID - if err := GetEntity(db, store); err == nil { - if store.SMSNotify != 0 { - telMap := make(map[string]int) - for _, v := range []string{store.Tel1, store.Tel2} { - if v != "" { - telMap[v] = 1 - } - } - phoneList = jxutils.StringMap2List(telMap) - } - } - return phoneList -} - -func GetStoreLinkStores(db *DaoDB, storeID int) (storeList []*model.Store, err error) { - sql := ` - SELECT t1.* - FROM store t1 - WHERE t1.link_store_id = ? AND t1.deleted_at = ? - ` - sqlParams := []interface{}{ - storeID, - utils.DefaultTimeValue, - } - err = GetRows(db, &storeList, sql, sqlParams...) - return storeList, err -} - -func GetRealLinkStoreID(db *DaoDB, linkStoreID int) (realLinkStoreID int, err error) { - realLinkStoreID = linkStoreID - if linkStoreID != 0 { - store := &model.Store{} - store.ID = linkStoreID - if err = GetEntity(db, store); err == nil { - if store.LinkStoreID != 0 { - realLinkStoreID = store.LinkStoreID - } else { - realLinkStoreID = linkStoreID - } - } - } - return realLinkStoreID, err -} - -func GetStoreCategoryMap(db *DaoDB, parentID, level, storeID, categoryID int) (storeCatMaps []*model.StoreCategoryMap, err error) { - sql := ` - SELECT a.* - FROM store_category_map a - WHERE a.deleted_at = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - } - if parentID >= 0 { - sql += " AND a.parent_id = ?" - sqlParams = append(sqlParams, parentID) - } - if level > 0 { - sql += " AND a.level = ?" - sqlParams = append(sqlParams, level) - } - if storeID > 0 { - sql += " AND a.store_id = ?" - sqlParams = append(sqlParams, storeID) - } - if categoryID > 0 { - sql += " AND a.category_id = ?" - sqlParams = append(sqlParams, categoryID) - } - err = GetRows(db, &storeCatMaps, sql, sqlParams) - if err != nil { - return nil, err - } - return storeCatMaps, err -} - -func InsertStoreCategories(db *DaoDB, userName string, storeID int) (err error) { - sql := ` - INSERT INTO store_category_map - (created_at, updated_at, last_operator, deleted_at, store_id, category_id, store_category_name, store_category_seq) - SELECT ?, ?, ?, ?, ?, id, name, seq - FROM sku_category - WHERE deleted_at = ? - AND is_exd_spec = ? - ` - sqlParams := []interface{}{ - time.Now(), time.Now(), userName, utils.DefaultTimeValue, storeID, - utils.DefaultTimeValue, model.NO, - } - _, err = ExecuteSQL(db, sql, sqlParams) - return err -} - -func DeleteStoreCategroies(db *DaoDB, userName string, storeID int) (err error) { - sql := ` - UPDATE store_category_map - SET deleted_at = ?, last_operator = ? - WHERE deleted_at <> ? - AND store_id = ? - ` - sqlParams := []interface{}{ - time.Now(), userName, - utils.DefaultTimeValue, - storeID, - } - _, err = ExecuteSQL(db, sql, sqlParams) - return err -} - -func GetStorePushClient(db *DaoDB, storeID int, cID string) (storePushClient []*model.StorePushClient, err error) { - sql := ` - SELECT * - FROM store_push_client - WHERE deleted_at = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - } - if storeID > 0 { - sql += " AND store_id = ?" - sqlParams = append(sqlParams, storeID) - } - if cID != "" { - sql += " AND client_id = ?" - sqlParams = append(sqlParams, cID) - } - err = GetRows(db, &storePushClient, sql, sqlParams) - if err != nil { - return nil, err - } - return storePushClient, err -} - -func GetStoreAudit(db *DaoDB, auditStatuss []int, userID, keyword string) (storeAudit []*model.StoreAudit, err error) { - sql := ` - SELECT * - FROM store_audit - WHERE deleted_at = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - } - if len(auditStatuss) > 0 { - sql += " AND audit_status IN (" + GenQuestionMarks(len(auditStatuss)) + ")" - sqlParams = append(sqlParams, auditStatuss) - } - if userID != "" { - sql += " AND user_id = ?" - sqlParams = append(sqlParams, userID) - } - if keyword != "" { - sql += " AND (user_id LIKE ? OR name LIKE ? OR tel1 LIKE ? OR tel2 LIKE ? OR address LIKE ?)" - sqlParams = append(sqlParams, "%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%") - } - err = GetRows(db, &storeAudit, sql, sqlParams) - if err != nil { - return nil, err - } - return storeAudit, err -} - -type tStoreAudit struct { - model.StoreAudit - UserName string `json:"userName"` - CityName string `json:"cityName"` -} - -func GetStoreAuditPage(db *DaoDB, statuss []int, keyword string, applyTimeStart, applyTimeEnd, auditTimeStart, auditTimeEnd time.Time, pageSize, offset int) (pagedInfo *model.PagedInfo, err error) { - var requestList []*tStoreAudit - sql := ` - SELECT SQL_CALC_FOUND_ROWS DISTINCT a.*, b.name user_name, c.name city_name - FROM store_audit a - JOIN user b ON b.user_id = a.user_id - JOIN place c ON c.code = a.city_code - WHERE a.deleted_at = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - } - if len(statuss) > 0 { - sql += " AND a.audit_status IN (" + GenQuestionMarks(len(statuss)) + ")" - sqlParams = append(sqlParams, statuss) - } - if applyTimeStart != utils.ZeroTimeValue && applyTimeEnd != utils.ZeroTimeValue { - sql += " AND a.created_at BETWEEN ? AND ?" - sqlParams = append(sqlParams, applyTimeStart, applyTimeEnd) - } - if auditTimeStart != utils.ZeroTimeValue && auditTimeEnd != utils.ZeroTimeValue { - sql += " AND a.updated_at BETWEEN ? AND ?" - sqlParams = append(sqlParams, auditTimeStart, auditTimeEnd) - } - if keyword != "" { - sql += " AND (a.user_id LIKE ? OR a.name LIKE ? OR a.tel1 LIKE ? OR a.tel2 LIKE ? OR a.address LIKE ?)" - sqlParams = append(sqlParams, "%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%") - } - sql += " ORDER BY a.updated_at LIMIT ? OFFSET ?" - pageSize = jxutils.FormalizePageSize(pageSize) - sqlParams = append(sqlParams, pageSize, offset) - Begin(db) - defer Commit(db) - if err = GetRows(db, &requestList, sql, sqlParams...); err == nil { - return &model.PagedInfo{ - TotalCount: GetLastTotalRowCount(db), - Data: requestList, - }, nil - } - return pagedInfo, err -} diff --git a/business/model/dao/store_score.go b/business/model/dao/store_score.go deleted file mode 100644 index 1e1251c00..000000000 --- a/business/model/dao/store_score.go +++ /dev/null @@ -1,106 +0,0 @@ -package dao - -import ( - "fmt" - "time" - - "git.rosy.net.cn/jx-callback/business/model" -) - -func InsertStoreScore(storeScore *model.StoreScore) error { - storeScore.CreatedAt = time.Now() - return CreateEntity(nil, storeScore) -} - -func GetWeeklyStoreScoreList(db *DaoDB, storeID, weekNum int) (storeScoreList []*model.StoreScoreEx, err error) { - sql := ` - SELECT t2.name store_name, t1.* FROM store_score t1 - JOIN store t2 ON t1.store_id = t2.id - WHERE t1.store_id = ? - AND DATE(t1.score_date) >= DATE_SUB( - DATE_SUB( - CURDATE(), - INTERVAL - IF ( - DAYOFWEEK(CURDATE()) - 1 = 0, - 7, - DAYOFWEEK(CURDATE()) - 1 - ) DAY - ), - INTERVAL ? DAY - ) - AND DATE(t1.score_date) <= DATE_SUB( - CURDATE(), - INTERVAL - IF ( - DAYOFWEEK(CURDATE()) - 1 = 0, - 7, - DAYOFWEEK(CURDATE()) - 1 - ) DAY - ) - ORDER BY score_date DESC - ` - if weekNum <= 0 { - weekNum = 1 - } - diffDays := weekNum*7 - 1 - sqlParams := []interface{}{ - storeID, - diffDays, - } - err = GetRows(db, &storeScoreList, sql, sqlParams) - return storeScoreList, err -} - -func CheckHasStoreScoreData(db *DaoDB, dateTime time.Time) (hasStoreScoreData bool, err error) { - sql := ` - SELECT COUNT(*) count - FROM store_score - WHERE DATE(score_date) = DATE(?) - ` - sqlParams := []interface{}{ - dateTime, - } - count := 0 - err = GetRow(db, &count, sql, sqlParams) - hasStoreScoreData = count > 0 - return hasStoreScoreData, err -} - -func GetStoreTotalScoreList(db *DaoDB, storeIDList []int, cityCode int, keyWord string, beginTime, endTime time.Time) (storeTotalScoreList []*model.StoreTotalScore, err error) { - sql := ` - SELECT t2.id store_id, t2.name store_name, t3.name city_name, - SUM(t1.store_open_time + t1.sale_sku_count + t1.average_pickup_time + t1.bad_comment_order + t1.unfinish_order - + t1.absent_Goods_order + t1.promotion_sku + t1.full_vendor + t1.store_range + t1.sale_sku_price) store_score - FROM store_score t1 - JOIN store t2 ON t1.store_id = t2.id - JOIN place t3 ON t2.city_code = t3.code - WHERE DATE(t1.score_date) >= DATE(?) AND DATE(t1.score_date) <= DATE(?) - ` - sqlParams := []interface{}{ - beginTime, - endTime, - } - if len(storeIDList) > 0 { - sql += ` - AND t2.id in (` + GenQuestionMarks(len(storeIDList)) + `)` - sqlParams = append(sqlParams, storeIDList) - } - if cityCode > 0 { - sql += ` - AND t3.code = ?` - sqlParams = append(sqlParams, cityCode) - } - if keyWord != "" { - sql += ` - AND (t2.id LIKE ? OR t2.name LIKE ? OR t3.name LIKE ?)` - keyWord = fmt.Sprintf("%%%s%%", keyWord) - sqlParams = append(sqlParams, keyWord, keyWord, keyWord) - } - sql += ` - GROUP BY t1.store_id, t1.score_date - ` - err = GetRows(db, &storeTotalScoreList, sql, sqlParams) - - return storeTotalScoreList, err -} diff --git a/business/model/dao/store_sku.go b/business/model/dao/store_sku.go deleted file mode 100644 index e6d380909..000000000 --- a/business/model/dao/store_sku.go +++ /dev/null @@ -1,1747 +0,0 @@ -package dao - -import ( - "errors" - "fmt" - "strings" - "time" - - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/globals/refutil" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/globals" -) - -type StoreSkuAndAct struct { - *model.StoreSkuBind - ActMap map[int]*model.StoreSkuAct -} - -var ( - dataResFieldMap = map[int]string{ - model.VendorIDMTWM: "mtwm_url", - model.VendorIDEBAI: "ebai_url", - model.VendorIDJDShop: "jds_url", - } - salePriceLimit = 100 -) - -type SkuStoreCatInfo struct { - VendorID int `orm:"column(vendor_id)" json:"vendorID"` - VendorOrgCode string `orm:"size(32)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空 - - MapID int `orm:"column(map_id)"` // 这个主要用于判断是否有store_sku_category_map - model.SkuCategory - VendorCatID string `orm:"column(vendor_cat_id)"` - CatSyncStatus int8 - - ParentMapID int `orm:"column(parent_map_id)"` // 这个主要用于判断是否有父store_sku_category_map - ParentCatName string - ParentVendorCatID string `orm:"column(parent_vendor_cat_id)"` - ParentCatSyncStatus int8 - - StoreCatID int `orm:"column(store_category_id)"` - StoreCatName string - StoreCatSeq int - StoreParentCatName string - IsSysCat int -} - -type StoreSkuSyncInfo struct { - StoreSkuSyncInfoJds []*StoreSkuSyncInfo - VendorID int `orm:"column(vendor_id)" json:"vendorID"` - VendorOrgCode string `orm:"size(32)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空 - - // 平台无关的store sku信息 - BindID int `orm:"column(bind_id)"` // 换名的原因是与Sku.ID同名区别 - StoreID int `orm:"column(store_id)"` - SkuID int `orm:"column(sku_id)"` // 这个与Sku.ID的区别是SkuID是必然存在的 - - BoxFee int64 - - Price int64 - UnitPrice int64 - Stock int - - // 平台相关的store sku信息 - StoreSkuStatus int - SkuSyncStatus int8 - VendorSkuID string `orm:"column(vendor_sku_id)"` - JdsWareID int64 `orm:"column(jds_ware_id)" json:"jdsWareID"` - BindDeletedAt time.Time `orm:"type(datetime)" json:"bindDeletedAt"` - - model.Sku - ExdSkuID string `orm:"column(exd_sku_id)"` - ExdCategoryThirdID int `orm:"column(exd_category_third_id)"` - StoreName string - - // sku_name - Prefix string - ExPrefix string - ExPrefixBegin *time.Time - ExPrefixEnd *time.Time - - // NameID int `orm:"column(name_id)"` - VendorNameID string `orm:"column(vendor_name_id)"` // 暂时无用 - Name string - Unit string - Upc string - IsGlobal int8 `orm:"default(1)" json:"isGlobal"` // 是否是全部(全国)可见,如果否的话,可见性由SkuPlace决定 - NameStatus int - SellCities []string - NameCategoryID int `orm:"column(name_category_id)"` - YbNameSuffix string //银豹的商品条码后缀 - YbBarCode string //银豹的商品条码 - JdsStockSwitch int - PreparationTime int - - // 平台相关的图片信息 - Img string - Img2 string - Img3 string - DescImg string - ImgWatermark string `json:"imgWatermark"` //图片水印 - ImgMix string //合成水印后的图片 - ImgOrigin string //skuname里的img - - VendorVendorCatID int64 `orm:"column(vendor_vendor_cat_id)"` // 平台商品分类(叶子结点) - CategoryName string `json:"categoryName"` //分类名 - // sku的商家分类信息 - SkuCatSyncStatus int8 - SkuVendorCatID string `orm:"column(sku_vendor_cat_id)"` - - // sku_name的商家分类信息 - CatSyncStatus int8 - VendorCatID string `orm:"column(vendor_cat_id)"` - SkuVendorMapCatID string `orm:"column(sku_vendor_map_cat_id)"` - - VendorPrice int64 - LockTime *time.Time - - MergedStatus int - SkuName string - SkuNameOrigin string - StatusSaleBegin int16 `json:"statusSaleBegin"` //商品可售时间范围 - StatusSaleEnd int16 `json:"statusSaleEnd"` - - VendorActID string `orm:"column(vendor_act_id);size(48)" json:"vendorActID"` - ActPercentage int `json:"actPercentage"` // 直降活动百分比 - ActSyncStatus int8 `orm:"default(2)" json:"actSyncStatus"` - VendorActPrice int64 `json:"vendorActPrice"` // 保存数据用,实际的活动价 - - IsDeletedBySku bool `json:"isDeletedBySku"` //京东商城用,同步下架的商品库里的sku时,要做区分来决定调的api -} - -type MissingStoreSkuInfo struct { - StoreID int `orm:"column(store_id)"` - NameID int `orm:"column(name_id)"` - SkuID int `orm:"column(sku_id)"` - SpecQuality float32 - SpecUnit string - Unit string - RefPrice int -} - -type StoreSkuBindWithVendorInfo struct { - model.StoreSkuBind - - VendorStoreID string `orm:"column(vendor_store_id)"` - VendorSkuID string `orm:"column(vendor_sku_id)"` -} - -type StoreSkuNameInfo struct { - StoreID int `orm:"column(store_id)"` - NameID int `orm:"column(name_id)"` - UnitPrice int64 -} - -// GetStoreSkus用 -type StoreSkuNameExt struct { - StoreID int `orm:"column(store_id)" json:"storeID"` - StoreName string `json:"storeName"` - SkuID int `orm:"column(sku_id)" json:"skuID"` - model.SkuName - PayPercentage int `json:"-"` - UnitPrice int `json:"unitPrice"` - Skus []*StoreSkuExt `orm:"-" json:"skus,omitempty"` - SkusStr string `json:"-"` - - PendingOpType int8 `json:"pendingOpType"` // 取值同 StoreOpRequest.Type - PendingUnitPrice int `json:"pendingUnitPrice"` // 这个是待审核的价格申请 - RealMidUnitPrice int `json:"realMidUnitPrice"` - Count int `json:"count"` - YbSkuName string `json:"ybSkuName"` - AuditUnitPrice int `json:"auditUnitPrice"` //审核价格 -} - -// GetStoreSkus用 -type StoreSkuNamesInfo struct { - TotalCount int `json:"totalCount"` - SkuNames []*StoreSkuNameExt `json:"skuNames"` -} - -type StoreSkuVendorInfo struct { - VendorID int `orm:"column(vendor_id)" json:"vendorID"` - - VendorSkuID string `orm:"column(vendor_sku_id)" json:"vendorSkuID"` - SyncStatus int8 `json:"syncStatus"` - VendorPrice int `json:"vendorPrice"` - LockTime *time.Time `json:"lockTime,omitempty"` - - ActPrice int `json:"actPrice"` - ActID int `orm:"column(act_id)" json:"actID"` - ActType int `orm:"column(act_type)" json:"actType"` - - EarningPrice int `json:"earningPrice"` - EarningActID int `orm:"column(earning_act_id)" json:"earningActID"` - - // 新活动信息 - VendorActID string `orm:"column(vendor_act_id);size(48)" json:"vendorActID"` - HintActID int `orm:"column(hint_act_id);size(48);index" json:"hintActID"` - ActPercentage int `json:"actPercentage"` // 直降活动百分比 - ActSyncStatus int8 `orm:"default(2)" json:"actSyncStatus"` - VendorActPrice int64 `json:"vendorActPrice"` // 保存数据用,实际的活动价 -} - -type StoreSkuExt struct { - NameID int `orm:"column(name_id)" json:"nameID"` - SkuID int `orm:"column(sku_id)" json:"id"` - Comment string `orm:"size(255)" json:"comment"` - SkuCategoryID int `orm:"column(sku_category_id)" json:"categoryID"` - SkuSpecQuality float32 `json:"specQuality"` - SkuSpecUnit string `orm:"size(8)" json:"specUnit"` // 质量或容量 - Weight int `json:"weight"` // 重量/质量,单位为克,当相应的SkuName的SpecUnit为g或kg时,必须等于SpecQuality - SkuStatus int `json:"status"` - Stock int `json:"stock"` - - BindCreatedAt time.Time `orm:"auto_now_add;type(datetime)" json:"createdAt"` - BindUpdatedAt time.Time `orm:"auto_now;type(datetime)" json:"updatedAt"` - BindLastOperator string `orm:"size(32)" json:"lastOperator"` // 最后操作员 - BindDeletedAt time.Time `orm:"type(datetime)" json:"deletedAt"` - SubStoreID int `orm:"column(sub_store_id)" json:"subStoreID"` - BindPrice int `json:"price"` // 单位为分,不用int64的原因是这里不需要累加 - UnitPrice int `json:"unitPrice"` // 这个是一斤的门店商品价,放在这里的原因是避免额外增加一张store sku_name表,逻辑上要保证同一SKU NAME中的所有SKU这个字段的数据一致 - StoreSkuStatus int `json:"storeSkuStatus"` - AutoSaleAt time.Time `orm:"type(datetime);null" json:"autoSaleAt"` - - StatusSaleBegin int16 `json:"statusSaleBegin"` //商品可售时间范围 - StatusSaleEnd int16 `json:"statusSaleEnd"` - - Count int `json:"count"` - Times int `json:"times"` - - // VendorInfoMap用于替换其之下的所有信息 - VendorInfoMap map[int]*StoreSkuVendorInfo `json:"vendorInfoMap,omitempty"` - - JdID string `orm:"column(sku_jd_id);null;index" json:"jdID"` - EbaiID string `orm:"column(ebai_id);index" json:"ebaiID"` - MtwmID string `orm:"column(mtwm_id)" json:"mtwmID"` // 这个也不是必须的,只是为了DAO取数据语句一致 - YbID string `orm:"column(yb_id);index" json:"ybID"` - JdsID string `orm:"column(jds_id);index" json:"jdsID"` - - JdSyncStatus int8 `orm:"default(2)" json:"jdSyncStatus"` - EbaiSyncStatus int8 `orm:"default(2)" json:"ebaiSyncStatus"` - MtwmSyncStatus int8 `orm:"default(2)" json:"mtwmSyncStatus"` - YbSyncStatus int8 `orm:"default(2)" json:"ybSyncStatus"` - JdsSyncStatus int8 `orm:"default(2)" json:"jdsSyncStatus"` //京东商城 - - JdPrice int `json:"jdPrice"` - EbaiPrice int `json:"ebaiPrice"` - MtwmPrice int `json:"mtwmPrice"` - JxPrice int `json:"jxPrice"` - YbPrice int `json:"ybPrice"` - JdsPrice int `json:"jdsPrice"` - - JdLockTime *time.Time `orm:"null" json:"jdLockTime,omitempty"` - JdsLockTime *time.Time `orm:"null" json:"jdsLockTime,omitempty"` - EbaiLockTime *time.Time `orm:"null" json:"ebaiLockTime,omitempty"` - MtwmLockTime *time.Time `orm:"null" json:"mtwmLockTime,omitempty"` - JxLockTime *time.Time `orm:"null" json:"jxLockTime,omitempty"` - YbLockTime *time.Time `orm:"null" json:"ybLockTime,omitempty"` - - ActPrice int `json:"actPrice"` - ActID int `orm:"column(act_id)" json:"actID"` - ActType int `orm:"column(act_type)" json:"actType"` - DiscountType int `json:"discountType"` - DiscountValue1 int `json:"discountValue1"` - DiscountValue2 int `json:"discountValue2"` - - EarningPrice int `json:"earningPrice"` - EarningActID int `orm:"column(earning_act_id)" json:"earningActID"` - - EclpID string `orm:"column(eclp_id)" json:"eclpID"` - TrendType int `json:"trendType"` - TrendPrice int `json:"trendPrice"` -} - -type SkuNameAndPlace struct { - model.SkuName - UnitPrice int `json:"unitPrice"` - CityCode int `json:"cityCode"` - CityName string `json:"cityName"` - Sequence int `json:"sequence"` - Count int `json:"count"` - Type int `json:"type"` - Skus []*model.SkuAndName `json:"skus"` -} - -type StoreSkuPriceAndWeight struct { - VendorSkuID string `orm:"column(vendor_sku_id)"` - SkuID int `orm:"column(sku_id)"` - Weight int - Price int - Prefix string - Name string - Unit string - Comment string - SpecQuality float32 - SpecUnit string -} - -type StoreSkuAndName struct { - StoreSkuSyncInfo - JdSyncStatus int8 `orm:"default(2)"` - MtwmSyncStatus int8 `orm:"default(2)"` - EbaiSyncStatus int8 `orm:"default(2)"` -} - -// todo 应该通过需要同步的skuid来驱动同步分类,而不是当前这种分开的逻辑 -// 单门店模式厂商适用 -// 从store_sku_bind中,得到所有依赖的商家分类信息 -func GetSkusCategories(db *DaoDB, vendorID, storeID int, skuIDs []int, level int) (cats []*SkuStoreCatInfo, err error) { - sql := ` - SELECT DISTINCT t4.*, - t5.id map_id, t5.%s_id vendor_cat_id, t5.%s_sync_status cat_sync_status, - t4p.name parent_cat_name, - t5p.id parent_map_id, t5p.%s_id parent_vendor_cat_id, t5p.%s_sync_status parent_cat_sync_status - FROM store_sku_bind t1 - JOIN sku t2 ON t1.sku_id = t2.id AND t2.deleted_at = ? - JOIN sku_name t3 ON t2.name_id = t3.id AND t3.deleted_at = ? - ` - if level == 2 { - sql += ` - JOIN sku_category t4 ON (t3.category_id = t4.id OR t2.category_id = t4.id) AND t4.level = 2 AND t4.deleted_at = ? - ` - } else { - sql += ` - LEFT JOIN sku_category t4c ON (t3.category_id = t4c.id OR t2.category_id = t4c.id) - JOIN sku_category t4 ON (t4.id = t4c.parent_id OR (t3.category_id = t4.id OR t2.category_id = t4.id)) AND t4.level = 1 AND t4.deleted_at = ? - ` - } - sql += ` - LEFT JOIN store_sku_category_map t5 ON t4.id = t5.category_id AND t5.store_id = t1.store_id AND t5.deleted_at = ? - LEFT JOIN sku_category t4p ON t4.parent_id = t4p.id - LEFT JOIN store_sku_category_map t5p ON t4p.id = t5p.category_id AND t5p.store_id = t1.store_id AND t5p.deleted_at = ? - WHERE t1.deleted_at = ? AND t1.%s_sync_status & ? = 0 AND t1.store_id = ? AND ((t1.status = ? AND t2.status = ? AND t3.status = ?) OR (t1.%s_sync_status & ? = 0)) - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - model.SyncFlagDeletedMask, - storeID, - model.SkuStatusNormal, - model.SkuStatusNormal, - model.SkuStatusNormal, - model.SyncFlagNewMask, - } - if len(skuIDs) > 0 { - sql += " AND t1.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" - sqlParams = append(sqlParams, skuIDs) - } - fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID]) - sql = fmt.Sprintf(sql, fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix) - if err = GetRows(db, &cats, sql, sqlParams...); err != nil { - return nil, err - } - return cats, err -} - -// 单门店模式厂商适用 -// 单纯的从已经创建的store_sku_category_map中,得到相关的同步信息 -func GetStoreCategories(db *DaoDB, vendorID, storeID int, skuIDs []int, level int, mustDirty bool) (cats []*SkuStoreCatInfo, err error) { - fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID]) - sql := ` - SELECT t4.*, ts.store_category_name store_cat_name, ts.store_category_seq store_cat_seq, ts.id store_category_id, - t5.id map_id, t5.%s_id vendor_cat_id, t5.%s_sync_status cat_sync_status, - t4p.name parent_cat_name, - tsp.store_category_name store_parent_cat_name, - t5p.id parent_map_id, t5p.%s_id parent_vendor_cat_id, t5p.%s_sync_status parent_cat_sync_status, - t1.is_sys_cat - FROM store_sku_category_map t5 - JOIN sku_category t4 ON t5.category_id = t4.id AND t4.deleted_at = ? - LEFT JOIN store_category_map ts ON ts.store_id = t5.store_id AND ts.category_id = t4.id AND ts.deleted_at = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - utils.DefaultTimeValue, - } - fieldPrefixParams := []interface{}{fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix} - if len(skuIDs) > 0 { - sql += ` - LEFT JOIN ( - SELECT DISTINCT b.category_id - FROM sku a - JOIN sku_name b ON a.name_id = b.id AND b.deleted_at = ? - WHERE a.id IN (` + GenQuestionMarks(len(skuIDs)) + `) - AND a.deleted_at = ? - ) t6 ON t6.category_id = t4.id - ` - sqlParams = append(sqlParams, utils.DefaultTimeValue, skuIDs, utils.DefaultTimeValue) - } - sql += ` - LEFT JOIN sku_category t4p ON t4.parent_id = t4p.id - LEFT JOIN store_category_map tsp ON tsp.store_id = t5.store_id AND tsp.category_id = t4p.id AND tsp.deleted_at = ? - LEFT JOIN store_sku_category_map t5p ON t4p.id = t5p.category_id AND t5.store_id = t5p.store_id AND t5p.deleted_at = ? - LEFT JOIN store_map t1 ON t1.store_id = t5.store_id AND t1.vendor_id = ? - WHERE t5.store_id = ? AND t5.deleted_at = ? AND t4.is_sync <> ?` - sqlParams = append(sqlParams, utils.DefaultTimeValue, utils.DefaultTimeValue, vendorID, storeID, utils.DefaultTimeValue, model.YES) - if mustDirty { - sql += " AND t5.%s_sync_status <> 0" - fieldPrefixParams = append(fieldPrefixParams, fieldPrefix) - } - if level > 0 { - sql += " AND t4.level = ?" - sqlParams = append(sqlParams, level) - } - if err = GetRows(db, &cats, fmt.Sprintf(sql, fieldPrefixParams...), sqlParams...); err != nil { - return nil, err - } - return cats, err -} - -func GetDirtyStoreCategories(db *DaoDB, vendorID, storeID int, level int, skuIDs []int) (cats []*SkuStoreCatInfo, err error) { - return GetStoreCategories(db, vendorID, storeID, skuIDs, level, true) -} - -// 以store_sku_bind为基础来做同步,正常情况下使用 -// 单多门店模式厂商通用 -func GetStoreSkus2(db *DaoDB, vendorID, storeID int, skuIDs []int, mustDirty bool) (skus []*StoreSkuSyncInfo, err error) { - if vendorID < 0 { - panic("vendorID<0") - } - isSingleStorePF := model.MultiStoresVendorMap[vendorID] != 1 - fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID]) - skuVendorIDField := fmt.Sprintf("t1.%s_id", fieldPrefix) - if !isSingleStorePF { - skuVendorIDField = "t2m.vendor_thing_id" - } - sql := ` - SELECT - t14.vendor_id, t14.vendor_org_code, - t1.id bind_id, t1.sku_id, t1.price, t1.unit_price, t1.status store_sku_status, - %s vendor_sku_id, t1.%s_sync_status sku_sync_status, t1.%s_price vendor_price, t1.%s_lock_time lock_time, - t1.store_id, t1.deleted_at bind_deleted_at,t1.status_sale_begin,t1.status_sale_end, t1.jds_ware_id, t1.stock, - t2.*, - t3.id name_id, t3.prefix, t3.name, t3.unit, t3.upc, t3.status name_status, t3.category_id name_category_id, t3.yb_name_suffix, - t3.jds_stock_switch, t3.preparation_time, t3.img_watermark, t3.ex_vendor_id, t3.img img_origin, - IF(t11.%s <> '', t11.%s, t3.img) img, - IF(t12.%s <> '', t12.%s, t3.img2) img2, - IF(t15.%s <> '', t15.%s, t3.img3) img3, - IF(t13.%s <> '', t13.%s, t3.desc_img) desc_img, - t4.%s_category_id vendor_vendor_cat_id, - t4.name category_name, - ts.name store_name, - tsu.ex_prefix, tsu.begin_at ex_prefix_begin, tsu.end_at ex_prefix_end, tsu.img_watermark, - tsu1.vendor_category_id sku_vendor_map_cat_id` - fmtParams := []interface{}{ - skuVendorIDField, fieldPrefix, fieldPrefix, fieldPrefix, - GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), - GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), - GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), - GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), - fieldPrefix, - } - if isSingleStorePF { - sql += `, - t5.%s_sync_status cat_sync_status, t5.%s_id vendor_cat_id, - t5sku.%s_sync_status sku_cat_sync_status, t5sku.%s_id sku_vendor_cat_id` - fmtParams = append(fmtParams, fieldPrefix, fieldPrefix, fieldPrefix, fieldPrefix) - } else { - sql += `, - t4m.vendor_thing_id vendor_cat_id, - t5skum.vendor_thing_id sku_vendor_cat_id` - } - if globals.IsStoreSkuAct { - sql += `, - act.vendor_act_id, act.act_percentage, act.sync_status act_sync_status, act.vendor_act_price` - } - sql += ` - FROM store_sku_bind t1 - JOIN store_map t14 ON t14.store_id = t1.store_id AND t14.vendor_id = ? AND t14.deleted_at = ? - LEFT JOIN store ts ON ts.id = t1.store_id AND ts.deleted_at = ? - LEFT JOIN sku t2 ON t1.sku_id = t2.id AND t2.deleted_at = ?/* AND t2.status = ?*/ - LEFT JOIN sku_name t3 ON t2.name_id = t3.id AND t3.deleted_at = ?/* AND t3.status = ?*/ - LEFT JOIN sku_category t4 ON t3.category_id = t4.id AND t4.deleted_at = ? - LEFT JOIN data_resource t11 ON t11.main_url = t3.img - LEFT JOIN data_resource t12 ON t12.main_url = t3.img2 - LEFT JOIN data_resource t15 ON t15.main_url = t3.img3 - LEFT JOIN data_resource t13 ON t13.main_url = t3.desc_img - LEFT JOIN sku_exinfo_map tsu ON tsu.name_id = t3.id AND tsu.deleted_at = ? AND tsu.vendor_id = t14.vendor_id - LEFT JOIN sku_vendor_category_map tsu1 ON tsu1.name_id = t3.id AND tsu1.deleted_at = ? AND tsu1.vendor_id = t14.vendor_id - ` - sqlParams := []interface{}{ - vendorID, utils.DefaultTimeValue, - utils.DefaultTimeValue, // model.SkuStatusNormal, - utils.DefaultTimeValue, // model.SkuStatusNormal, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - } - if globals.IsStoreSkuAct { - sql += ` - LEFT JOIN store_sku_act act ON act.store_id = t1.store_id AND act.sku_id = t1.sku_id AND act.vendor_id = ?` - sqlParams = append(sqlParams, vendorID) - } - if isSingleStorePF { - sql += ` - LEFT JOIN store_sku_category_map t5 ON t4.id = t5.category_id AND t5.store_id = t1.store_id AND t5.deleted_at = ? - LEFT JOIN store_sku_category_map t5sku ON t2.category_id = t5sku.category_id AND t5sku.store_id = t1.store_id AND t5sku.deleted_at = ?` - sqlParams = append(sqlParams, utils.DefaultTimeValue, utils.DefaultTimeValue) - } else { - sql += ` - LEFT JOIN sku_category t5sku ON t5sku.id = t2.category_id - JOIN thing_map t2m ON t2m.thing_id = t1.sku_id AND t2m.vendor_org_code = t14.vendor_org_code AND t2m.thing_type = ? AND t2m.vendor_id = ? AND t2m.deleted_at = ? - LEFT JOIN thing_map t4m ON t4m.thing_id = t3.category_id AND t4m.vendor_org_code = t14.vendor_org_code AND t4m.thing_type = ? AND t4m.vendor_id = ? AND t4m.deleted_at = ? - LEFT JOIN thing_map t5skum ON t5skum.thing_id = t5sku.id AND t5skum.vendor_org_code = t14.vendor_org_code AND t5skum.thing_type = ? AND t5skum.vendor_id = ? AND t5skum.deleted_at = ? - ` - sqlParams = append(sqlParams, - model.ThingTypeSku, vendorID, utils.DefaultTimeValue, - model.ThingTypeCategory, vendorID, utils.DefaultTimeValue, - model.ThingTypeCategory, vendorID, utils.DefaultTimeValue) - } - sql += " WHERE 1 = 1" - if storeID > 0 { - sql += " AND t1.store_id = ?" - sqlParams = append(sqlParams, storeID) - } - if mustDirty { - sql += " AND (t1.%s_sync_status <> 0 OR (%s <> %s AND t3.id IS NULL)" - fmtParams = append(fmtParams, fieldPrefix, skuVendorIDField) - if isSingleStorePF { - fmtParams = append(fmtParams, "0") - } else { - fmtParams = append(fmtParams, "''") - } - // if globals.IsStoreSkuAct { - // sql += " OR act.sync_status <> 0" - // } - sql += ")" - } else { - sql += " AND t1.deleted_at = ?" - sqlParams = append(sqlParams, utils.DefaultTimeValue) - } - if len(skuIDs) > 0 { - sql += " AND t1.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" - sqlParams = append(sqlParams, skuIDs) - } - // 多门店平台没有成功创建的商品,不直接过滤,让上层同步时报错 - // if !isSingleStorePF { - // sql += " AND t2.%s_id <> 0" - // fmtParams = append(fmtParams, fieldPrefix) - // } - sql = fmt.Sprintf(sql, fmtParams...) - sql += " ORDER BY t1.price" - // globals.SugarLogger.Debug(sql) - if err = GetRows(db, &skus, sql, sqlParams...); err != nil { - return nil, err - } - return skus, err -} - -func GetStoreSkus(db *DaoDB, vendorID, storeID int, skuIDs []int) (skus []*StoreSkuSyncInfo, err error) { - return GetStoreSkus2(db, vendorID, storeID, skuIDs, true) -} - -// 以sku为基础来做全同步, -// 多门店模式厂商适用 -func GetFullStoreSkus(db *DaoDB, vendorID, storeID int) (skus []*StoreSkuSyncInfo, err error) { - globals.SugarLogger.Debugf("GetFullStoreSkus, storeID:%d, vendorID:%d", storeID, vendorID) - - // 对于多门店平台,商品库删除后,不需要操作门店商品,所以sku_name用JOIN, sku与sku_name也可以直接排除下架的 - sql := ` - SELECT - sm.vendor_id, sm.vendor_org_code, sm.yb_app_id, sm.yb_app_key, - t1.id bind_id, t1.price, t1.unit_price, t1.status store_sku_status, - t1.%s_sync_status sku_sync_status, t1.%s_price vendor_price, t1.%s_lock_time lock_time, - t1.store_id, t1.deleted_at bind_deleted_at, t1.stock, - t2.*, t2.id sku_id, t2m.vendor_thing_id vendor_sku_id, - t3.id name_id, t3.prefix, t3.name, t3.unit, t3.upc, t3.status name_status, t3.ex_prefix, t3.ex_prefix_begin, t3.ex_prefix_end, t3.category_id name_category_id, - IF(t11.%s <> '', t11.%s, t3.img) img, - IF(t12.%s <> '', t12.%s, t3.img2) img2, - IF(t13.%s <> '', t13.%s, t3.desc_img) desc_img, - t4.%s_category_id vendor_vendor_cat_id, - t4m.sync_status cat_sync_status, t4m.vendor_thing_id vendor_cat_id, - t5skum.sync_status sku_cat_sync_status, t5skum.vendor_thing_id sku_vendor_cat_id - FROM sku t2 - JOIN sku_name t3 ON t2.name_id = t3.id AND t3.deleted_at = ?/* AND t3.status = ?*/ - JOIN sku_category t4 ON t3.category_id = t4.id AND t4.deleted_at = ? - JOIN store_map sm ON sm.vendor_id = ? AND sm.store_id = ? AND sm.deleted_at = ? - JOIN thing_map t2m ON t2m.thing_id = t2.id AND t2m.vendor_org_code = sm.vendor_org_code AND t2m.thing_type = ? AND t2m.vendor_id = ? AND t2m.deleted_at = ? - JOIN thing_map t4m ON t4m.thing_id = t3.category_id AND t4m.vendor_org_code = sm.vendor_org_code AND t4m.thing_type = ? AND t4m.vendor_id = ? AND t4m.deleted_at = ? - LEFT JOIN store_sku_bind t1 ON sm.store_id = t1.store_id AND t1.sku_id = t2.id AND t1.deleted_at = ? - LEFT JOIN sku_category t5sku ON t2.category_id = t5sku.id - LEFT JOIN thing_map t5skum ON t5skum.thing_id = t2.category_id AND t5skum.vendor_org_code = sm.vendor_org_code AND t5skum.thing_type = ? AND t5skum.vendor_id = ? AND t5skum.deleted_at = ? - LEFT JOIN data_resource t11 ON t11.main_url = t3.img - LEFT JOIN data_resource t12 ON t12.main_url = t3.img2 - LEFT JOIN data_resource t13 ON t13.main_url = t3.desc_img - WHERE t2.deleted_at = ?/* AND t2.status = ?*/ AND t2m.vendor_thing_id <> '' - ORDER BY t1.price DESC` - sqlParams := []interface{}{ - utils.DefaultTimeValue, // model.SkuStatusNormal, - utils.DefaultTimeValue, - vendorID, storeID, utils.DefaultTimeValue, - model.ThingTypeSku, vendorID, utils.DefaultTimeValue, - model.ThingTypeCategory, vendorID, utils.DefaultTimeValue, - utils.DefaultTimeValue, - model.ThingTypeCategory, vendorID, utils.DefaultTimeValue, - utils.DefaultTimeValue, // model.SkuStatusNormal, - } - fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID]) - sql = fmt.Sprintf(sql, - fieldPrefix, fieldPrefix, fieldPrefix, - GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), - GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), - GetDataResFieldName(vendorID), GetDataResFieldName(vendorID), - fieldPrefix) - // globals.SugarLogger.Debug(sql) - // globals.SugarLogger.Debug(utils.Format4Output(sqlParams, false)) - if err = GetRows(db, &skus, sql, sqlParams...); err != nil { - return nil, err - } - return skus, err -} - -func GetStoreSkuPriceAndWeight(db *DaoDB, vendorStoreID string, vendorID int, vendorSkuIDs []string) (l []*StoreSkuPriceAndWeight, err error) { - var vendorSkuIDField, sqlThingMap string - var thingMapParams []interface{} - if vendorID == model.VendorIDJX { - vendorSkuIDField = "t1.id" - } else if model.MultiStoresVendorMap[vendorID] != 0 { - sqlThingMap = ` - JOIN thing_map t4 ON t4.thing_type = ? AND t4.thing_id = t1.id AND t4.deleted_at = ? AND t4.vendor_id = t3.vendor_id AND t4.vendor_org_code = t3.vendor_org_code` - thingMapParams = []interface{}{ - model.ThingTypeSku, utils.DefaultTimeValue, - } - vendorSkuIDField = "t4.vendor_thing_id" - } else { - vendorSkuIDField = fmt.Sprintf("t2.%s_id", ConvertDBFieldPrefix(model.VendorNames[vendorID])) - } - sql := fmt.Sprintf(` - SELECT %s vendor_sku_id, t1.id sku_id, t2.price, t1.weight, - t5.prefix, t5.name, t1.comment, t5.unit, t1.spec_quality, t1.spec_unit - FROM sku t1 - JOIN store_sku_bind t2 ON t2.sku_id = t1.id AND t2.deleted_at = ? - JOIN store_map t3 ON t3.store_id = t2.store_id AND t3.vendor_id = ? AND t3.vendor_store_id = ? AND t3.deleted_at = ? - JOIN sku_name t5 ON t5.id = t1.name_id - %s - WHERE %s IN (`+GenQuestionMarks(len(vendorSkuIDs))+`)`, vendorSkuIDField, sqlThingMap, vendorSkuIDField) - sqlParams := []interface{}{ - utils.DefaultTimeValue, - vendorID, vendorStoreID, utils.DefaultTimeValue, - } - sqlParams = append(sqlParams, thingMapParams...) - if vendorID == model.VendorIDJX { - sqlParams = append(sqlParams, utils.StringSlice2Int(vendorSkuIDs)) - } else { - sqlParams = append(sqlParams, vendorSkuIDs) - } - err = GetRows(db, &l, sql, sqlParams...) - return l, err -} - -// 这个函数之前是要设置没有删除或同步标志不为0的,会导致将同步标志不为0且删除了的把标志去掉,现在改为只设置没有删除的 -func SetStoreSkuSyncStatus(db *DaoDB, vendorID int, storeIDs []int, skuIDs []int, syncStatus int) (num int64, err error) { - globals.SugarLogger.Debugf("SetStoreSkuSyncStatus, storeIDs:%v, vendorID:%d", storeIDs, vendorID) - - isSingleStorePF := model.MultiStoresVendorMap[vendorID] != 1 - fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID]) - sql := ` - UPDATE store_sku_bind t1 - SET t1.%s_sync_status = t1.%s_sync_status | ? - ` - fmtParams := []interface{}{ - fieldPrefix, - fieldPrefix, - } - sqlParams := []interface{}{ - syncStatus, - } - if isSingleStorePF && (syncStatus&model.SyncFlagNewMask) != 0 { - sql += `, - t1.%s_id = 0 - ` - fmtParams = append(fmtParams, fieldPrefix) - } - sql += " WHERE t1.deleted_at = ? AND t1.%s_sync_status & ? = 0" - fmtParams = append(fmtParams, fieldPrefix) - sqlParams = append(sqlParams, utils.DefaultTimeValue, model.SyncFlagDeletedMask) - if len(storeIDs) > 0 { - sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - if len(skuIDs) > 0 { - sql += " AND t1.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" - sqlParams = append(sqlParams, skuIDs) - } - sql = fmt.Sprintf(sql, fmtParams...) - return ExecuteSQL(db, sql, sqlParams...) -} - -func SetStoreCategorySyncStatus(db *DaoDB, vendorID int, storeIDs []int, catIDs []int, syncStatus int) (num int64, err error) { - globals.SugarLogger.Debugf("SetStoreCategorySyncStatus, storeIDs:%v, vendorID:%d", storeIDs, vendorID) - - isSingleStorePF := model.MultiStoresVendorMap[vendorID] != 1 - fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID]) - sql := ` - UPDATE store_sku_category_map t1 - SET t1.%s_sync_status = IF(t1.deleted_at = ?, t1.%s_sync_status | ?, 0) - ` - fmtParams := []interface{}{ - fieldPrefix, - fieldPrefix, - } - sqlParams := []interface{}{ - utils.DefaultTimeValue, - syncStatus, - } - if isSingleStorePF && (syncStatus&model.SyncFlagNewMask) != 0 { - sql += `, - t1.%s_id = 0 - ` - fmtParams = append(fmtParams, fieldPrefix) - } - sql += " WHERE (t1.deleted_at = ? OR t1.%s_sync_status <> 0)" - fmtParams = append(fmtParams, fieldPrefix) - sqlParams = append(sqlParams, utils.DefaultTimeValue) - if len(storeIDs) > 0 { - sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - if len(catIDs) > 0 { - sql += " AND t1.category_id IN (" + GenQuestionMarks(len(catIDs)) + ")" - sqlParams = append(sqlParams, catIDs) - } - sql = fmt.Sprintf(sql, fmtParams...) - return ExecuteSQL(db, sql, sqlParams...) -} - -// func GetImgFieldName(vendorID int) (fieldName string) { -// fieldName = imgFieldMap[vendorID] -// if fieldName == "" { -// fieldName = "img" -// } -// return fieldName -// } - -func GetDataResFieldName(vendorID int) (fieldName string) { - fieldName = dataResFieldMap[vendorID] - if fieldName == "" { - fieldName = "main_url" - } - return fieldName -} - -// func GetDescImgFieldName(vendorID int) (fieldName string) { -// fieldName = descImgFieldMap[vendorID] -// if fieldName == "" { -// fieldName = "desc_img" -// } -// return fieldName -// } - -func GetStoresSkusInfo(db *DaoDB, storeIDs, skuIDs []int) (storeSkuList []*model.StoreSkuBind, err error) { - sql := ` - SELECT * - FROM store_sku_bind t1 - WHERE t1.deleted_at = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - } - if len(storeIDs) > 0 { - sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - if len(skuIDs) > 0 { - sql += " AND t1.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" - sqlParams = append(sqlParams, skuIDs) - } - err = GetRows(db, &storeSkuList, sql, sqlParams...) - return storeSkuList, err -} - -// vendorID, vendorStoreIDs和vendorSkuIDs都是必须参数 -func GetStoresSkusInfoByVendorInfo(db *DaoDB, vendorID int, vendorStoreIDs, vendorSkuIDs []string) (storeSkuList []*StoreSkuBindWithVendorInfo, err error) { - if len(vendorStoreIDs) == 0 || len(vendorSkuIDs) == 0 { - return nil, nil - } - - sql := ` - SELECT t1.*, - %s.%s_id vendor_sku_id, t2.vendor_store_id - FROM store_sku_bind t1 - JOIN store_map t2 ON t2.store_id = t1.store_id AND t2.vendor_id = ? AND t2.deleted_at = ? - JOIN sku t3 ON t3.id = t1.sku_id - WHERE t1.deleted_at = ? AND t2.vendor_store_id IN (` + GenQuestionMarks(len(vendorStoreIDs)) + `) - AND %s.%s_id IN (` + GenQuestionMarks(len(vendorSkuIDs)) + `)` - sqlParams := []interface{}{ - vendorID, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - vendorStoreIDs, - vendorSkuIDs, - } - - isSingleStorePF := model.MultiStoresVendorMap[vendorID] != 1 - tableName := "t1" - if !isSingleStorePF { - tableName = "t3" - } - fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[vendorID]) - sql = fmt.Sprintf(sql, tableName, fieldPrefix, tableName, fieldPrefix) - err = GetRows(db, &storeSkuList, sql, sqlParams...) - return storeSkuList, err -} - -func GetMissingStoreSkuFromOrder(db *DaoDB, storeIDs []int, fromTime time.Time) (storeSkuList []*MissingStoreSkuInfo, err error) { - if time.Now().Sub(fromTime) > 24*time.Hour*60 { - return nil, fmt.Errorf("GetMissingStoreSkuFromOrder,时间超过60天") - } - sql := ` - SELECT IF(t2.jx_store_id <> 0, t2.jx_store_id, t2.store_id) store_id, t4.name_id, t1.sku_id, - t4.spec_quality, t4.spec_unit, t5.unit, - COUNT(*) ct, CAST(AVG(IF(t1.vendor_price <> 0, t1.vendor_price, t1.sale_price)) AS SIGNED) ref_price - FROM order_sku t1 - JOIN goods_order t2 ON t2.vendor_order_id = t1.vendor_order_id - LEFT JOIN store_sku_bind t3 ON t3.store_id = IF(t2.jx_store_id <> 0, t2.jx_store_id, t2.store_id) AND - t3.sku_id = t1.sku_id AND t3.deleted_at = ? - JOIN sku t4 ON t4.id = t1.sku_id - JOIN sku_name t5 ON t5.id = t4.name_id - WHERE t2.status = ? AND IF(t2.jx_store_id <> 0, t2.jx_store_id, t2.store_id) > 0 AND t1.sku_id > 0 AND t1.shop_price = 0 AND - t1.order_created_at > ? AND t3.id IS NULL - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - model.OrderStatusFinished, - fromTime, - } - if len(storeIDs) > 0 { - sql += " AND IF(t2.jx_store_id <> 0, t2.jx_store_id, t2.store_id) IN (" + GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - sql += ` - GROUP BY 1,2,3,4,5,6 - ORDER BY 1,2,3,4,5,6 - ` - err = GetRows(db, &storeSkuList, sql, sqlParams...) - return storeSkuList, err -} - -func GetAutoSaleStoreSku(db *DaoDB, storeIDs []int) (storeSkuList []*model.StoreSkuBind, err error) { - sql := ` - SELECT * - FROM store_sku_bind t1 - WHERE t1.deleted_at = ? AND t1.auto_sale_at <> ?` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - utils.DefaultTimeValue, - } - if len(storeIDs) > 0 { - sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - err = GetRows(db, &storeSkuList, sql, sqlParams...) - return storeSkuList, err -} - -func GetExistingStoreSkuNameInfo(db *DaoDB, storeIDs, skuNameIDs []int) (storeSkuNameList []*StoreSkuNameInfo, err error) { - if len(storeIDs) == 0 || len(skuNameIDs) == 0 { - return nil, nil - } - sql := ` - SELECT t1.store_id, t2.name_id, MAX(t1.unit_price) unit_price - FROM store_sku_bind t1 - JOIN sku t2 ON t2.id = t1.sku_id - WHERE t1.deleted_at = ? AND t1.store_id IN (` + GenQuestionMarks(len(storeIDs)) + `) - AND t2.name_id IN (` + GenQuestionMarks(len(skuNameIDs)) + `) - GROUP BY 1, 2` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - storeIDs, - skuNameIDs, - } - err = GetRows(db, &storeSkuNameList, sql, sqlParams...) - return storeSkuNameList, err -} - -func (s *StoreSkuSyncInfo) GetSeq() int { - if s.Seq > 0 { - return s.Seq - } - return int(s.VendorPrice) -} - -func GetStoresSkusInfoBySaleTime(db *DaoDB, storeID int) (storeSkuBindList []*model.StoreSkuBind, err error) { - sql := ` - SELECT t1.* - FROM store_sku_bind t1 - WHERE t1.status_sale_begin <> 0 AND t1.status_sale_end <> 0 - AND t1.status = ? - AND t1.deleted_at = ? - ` - sqlParams := []interface{}{ - model.SkuStatusNormal, - utils.DefaultTimeValue, - } - if storeID > 0 { - sql += ` AND t1.store_id = ?` - sqlParams = append(sqlParams, storeID) - } - err = GetRows(db, &storeSkuBindList, sql, sqlParams...) - return storeSkuBindList, err -} - -func UpdateStoreSkuBindSyncStatusForSaleStatus(db *DaoDB, vendorIDs []int, storeID int) (num int64, err error) { - sql := ` - UPDATE store_sku_bind - SET - ` - fmtParams := []interface{}{} - sqlParams := []interface{}{} - if len(vendorIDs) > 0 { - for _, v := range vendorIDs { - fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[v]) - sql += ` %s_sync_status = ?,` - fmtParams = append(fmtParams, fieldPrefix) - sqlParams = append(sqlParams, model.SyncFlagSaleMask) - } - } else { - return 0, errors.New("取平台ID名有错误!partner.GetPurchasePlatformVendorIDs()") - } - sql = sql[0:strings.LastIndex(sql, ",")] - sql = fmt.Sprintf(sql, fmtParams...) - sql += ` WHERE status = ? - AND deleted_at = ? - AND status_sale_begin <> 0 - AND status_sale_end <> 0 - ` - sqlParams = append(sqlParams, model.StoreSkuBindStatusNormal, utils.DefaultTimeValue) - if storeID > 0 { - sql += ` AND store_id = ?` - sqlParams = append(sqlParams, storeID) - } - return ExecuteSQL(db, sql, sqlParams...) -} - -func UpdateStoreSkuBindSyncStatusForExPrefix(db *DaoDB, vendorIDs []int) (num int64, err error) { - sql := ` - UPDATE store_sku_bind a - JOIN sku b ON a.sku_id = b.id AND b.deleted_at = ? - JOIN sku_name c ON c.id = b.name_id AND c.deleted_at = ? - SET - ` - fmtParams := []interface{}{} - sqlParams := []interface{}{ - utils.DefaultTimeValue, - utils.DefaultTimeValue, - } - if len(vendorIDs) > 0 { - for _, v := range vendorIDs { - fieldPrefix := ConvertDBFieldPrefix(model.VendorNames[v]) - sql += ` %s_sync_status = %s_sync_status | ?,` - fmtParams = append(fmtParams, fieldPrefix, fieldPrefix) - sqlParams = append(sqlParams, model.SyncFlagModifiedMask) - } - } else { - return 0, errors.New("取平台ID名有错误!partner.GetPurchasePlatformVendorIDs()") - } - sql = sql[0:strings.LastIndex(sql, ",")] - sql = fmt.Sprintf(sql, fmtParams...) - sql += ` WHERE a.deleted_at = ? - AND c.ex_prefix != "" - AND (c.ex_prefix_begin = DATE_FORMAT(DATE_ADD(NOW(),INTERVAL '6' HOUR),'%Y-%m-%d 00:00:00') - OR c.ex_prefix_end = DATE_FORMAT(NOW(),'%Y-%m-%d 00:00:00')) - ` - sqlParams = append(sqlParams, utils.DefaultTimeValue) - return ExecuteSQL(db, sql, sqlParams...) -} - -func UpdateSkuSyncStatusForExPrefix(db *DaoDB, vendorIDs []int) (num int64, err error) { - sql := ` - UPDATE thing_map t1 - JOIN sku t2 ON t2.id = t1.thing_id AND t2.deleted_at = ? - JOIN sku_name t3 ON t3.id = t2.name_id AND t3.deleted_at = ? - AND t3.ex_prefix <> '' AND (t3.ex_prefix_begin = DATE_FORMAT(DATE_ADD(NOW(),INTERVAL '6' HOUR),'%Y-%m-%d 00:00:00') - OR t3.ex_prefix_end = DATE_FORMAT(NOW(),'%Y-%m-%d 00:00:00')) - SET - t1.sync_status = t1.sync_status | ? - WHERE t1.deleted_at = ? AND t1.thing_type = ? AND t1.sync_status & ? <> 0 - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - utils.DefaultTimeValue, - model.SyncFlagModifiedMask, - utils.DefaultTimeValue, model.ThingTypeSku, model.SyncFlagDeletedMask, - } - if len(vendorIDs) > 0 { - sql += " AND t1.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" - sqlParams = append(sqlParams, vendorIDs) - } - return ExecuteSQL(db, sql, sqlParams...) -} - -func DeleteSkuNameExPrefixOverdue(db *DaoDB) (num int64, err error) { - sql := ` - UPDATE sku_name - SET ex_prefix_begin = null,ex_prefix_end = null - WHERE deleted_at = ? - AND DATE_FORMAT(DATE_ADD(NOW(),INTERVAL '6' HOUR),'%Y-%m-%d 00:00:00') >= ex_prefix_end - ` - sqlParams := []interface{}{utils.DefaultTimeValue} - return ExecuteSQL(db, sql, sqlParams...) -} - -func GetStoreSkusByNameIDs(db *DaoDB, storeIDs []int, nameID int) (skuList []*StoreSkuSyncInfo, err error) { - sql := ` - SELECT a.*, c.unit, c.name, b.name_id, a.status store_sku_status - FROM store_sku_bind a - JOIN sku b ON a.sku_id = b.id - JOIN sku_name c ON b.name_id = c.id - WHERE 1=1 - AND a.deleted_at = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - } - if nameID != 0 { - sql += " AND b.name_id = ?" - sqlParams = append(sqlParams, nameID) - } - if len(storeIDs) > 0 { - sql += " AND a.store_id in (" + GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - sql += ` AND a.status != ? - ORDER BY a.updated_at DESC - ` - sqlParams = append(sqlParams, model.SkuStatusDeleted) - err = GetRows(db, &skuList, sql, sqlParams...) - return skuList, err -} - -func GetTopSkusByStoreIDs(db *DaoDB, storeIDs []int) (storeSkuNameExt []*StoreSkuNameExt, err error) { - sql := ` - SELECT t1.count, t2.id sku_id, t3.*, t1.store_id, t1.store_name - FROM( - SELECT SUM(b.count) count,c.id,a.store_id,d.name store_name - FROM goods_order a - JOIN order_sku b ON a.vendor_order_id = b.vendor_order_id AND a.vendor_id = b.vendor_id - JOIN sku c ON b.sku_id = c.id AND c.deleted_at = ? - JOIN sku_name t1 ON t1.id = c.name_id AND t1.deleted_at = ? - STRAIGHT_JOIN store_sku_bind t4 ON t4.store_id = IF(a.jx_store_id = 0,a.store_id,a.jx_store_id) AND t4.sku_id = b.sku_id AND t4.status = ? AND t4.deleted_at = ? - JOIN store d ON d.id = a.store_id - WHERE 1=1 - AND a.order_created_at BETWEEN ? and NOW() - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - utils.DefaultTimeValue, - model.SkuStatusNormal, - utils.DefaultTimeValue, - time.Now().AddDate(0, -1, 0), - } - if len(storeIDs) > 0 { - sql += " AND a.store_id IN(" + GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - sql += ` - AND b.sale_price > ? - GROUP BY 2,3,4)t1 - JOIN sku t2 ON t2.id = t1.id - JOIN sku_name t3 ON t3.id = t2.name_id - UNION - SELECT 0 count, a.sku_id, g.*, a.store_id, e.name store_name - FROM store_sku_bind a - LEFT JOIN act_store_sku b ON a.store_id = b.store_id AND b.sku_id = a.sku_id - LEFT JOIN act_map c ON c.act_id = b.act_id - LEFT JOIN act d ON d.id = c.act_id - JOIN store e ON e.id = a.store_id - JOIN sku f ON a.sku_id = f.id AND f.deleted_at = ? - JOIN sku_name g ON g.id = f.name_id AND g.deleted_at = ? - WHERE 1=1 - ` - sqlParams = append(sqlParams, salePriceLimit, utils.DefaultTimeValue, utils.DefaultTimeValue) - if len(storeIDs) > 0 { - sql += " AND a.store_id IN(" + GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - sql += - ` - AND NOW() BETWEEN d.begin_at AND d.end_at - AND a.status = ? - AND a.deleted_at = ? - AND (d.type = ? OR d.type = ?) - UNION - SELECT 0 count, a.sku_id, c.*, a.store_id, d.name store_name - FROM store_sku_bind a - JOIN sku b ON a.sku_id = b.id AND b.deleted_at = ? AND b.status = ? - JOIN sku_name c ON b.name_id = c.id AND c.deleted_at = ? AND c.status = ? - JOIN store d ON d.id = a.store_id AND d.deleted_at = ? AND d.status <> ? - WHERE a.store_id IN (` + GenQuestionMarks(len(storeIDs)) + `) - AND a.deleted_at = ? AND a.status = ? - ORDER BY 1 DESC - LIMIT ? - ` - sqlParams = append(sqlParams, model.StoreSkuBindStatusNormal, utils.DefaultTimeValue, model.ActSkuDirectDown, model.ActSkuSecKill, - utils.DefaultTimeValue, model.SkuStatusNormal, utils.DefaultTimeValue, model.SkuStatusNormal, utils.DefaultTimeValue, model.StoreStatusDisabled, - storeIDs, utils.DefaultTimeValue, model.StoreSkuBindStatusNormal, 30) - err = GetRows(db, &storeSkuNameExt, sql, sqlParams...) - var skuNamesInfo = &StoreSkuNamesInfo{ - SkuNames: storeSkuNameExt, - } - for _, v := range storeSkuNameExt { - var skus []*StoreSkuExt - sql2 := ` - SELECT a.id sku_id,a.*,t4.created_at bind_created_at, t4.updated_at bind_updated_at, t4.last_operator bind_last_operator, t4.deleted_at bind_deleted_at, - t4.sub_store_id, t4.price bind_price, IF(t4.unit_price IS NOT NULL, t4.unit_price, t1.price) unit_price, t4.status store_sku_status, t4.auto_sale_at, - t4.ebai_id, t4.mtwm_id, - t4.ebai_sync_status, t4.mtwm_sync_status, - t4.jd_price, t4.ebai_price, t4.mtwm_price, t4.jx_price, t4.stock, - a.spec_quality sku_spec_quality, a.spec_unit sku_spec_unit - FROM sku a - JOIN sku_name t1 ON a.name_id = t1.id AND t1.deleted_at = ? - JOIN store_sku_bind t4 ON t4.sku_id = a.id AND t4.deleted_at = ? - WHERE a.id = ? - AND a.deleted_at = ? - ` - sqlParams2 := []interface{}{ - utils.DefaultTimeValue, - utils.DefaultTimeValue, - v.SkuID, - utils.DefaultTimeValue, - } - if len(storeIDs) > 0 { - sql2 += " AND t4.store_id IN(" + GenQuestionMarks(len(storeIDs)) + ")" - sqlParams2 = append(sqlParams2, storeIDs) - } - err = GetRows(db, &skus, sql2, sqlParams2...) - v.Skus = skus - err = UpdateActPrice4StoreSkuNameNew(db, storeIDs, []int{v.SkuID}, skuNamesInfo, model.VendorIDJX) - } - return storeSkuNameExt, err -} - -func GetTopSkusByCityCode(db *DaoDB, cityCode int, orderCreate time.Time) (skuNameAndPlace []*SkuNameAndPlace, err error) { - sql := ` - SELECT SUM(b.count) count, e.name city_name, d.city_code, f.* - FROM goods_order a - JOIN order_sku b ON a.vendor_order_id = b.vendor_order_id AND a.vendor_id = b.vendor_id - JOIN sku c ON b.sku_id = c.id AND c.deleted_at = ? - JOIN sku_name f ON f.id = c.name_id - JOIN store d ON d.id = IF(a.jx_store_id = 0,a.store_id,a.jx_store_id) AND d.deleted_at = ? AND d.city_code = ? - JOIN place e ON e.code = d.city_code - WHERE 1=1 - AND b.sale_price > ? - AND a.order_created_at BETWEEN ? and NOW() - GROUP BY 2,3,4 - ORDER BY count DESC - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - utils.DefaultTimeValue, - cityCode, - salePriceLimit, - orderCreate, - } - err = GetRows(db, &skuNameAndPlace, sql, sqlParams...) - return skuNameAndPlace, err -} - -func GetTopCategoriesByStoreIDs(db *DaoDB, storeIDs []int, limit int) (skuCategory []*model.SkuCategory, err error) { - sql := ` - SELECT DISTINCT t5.* FROM( - SELECT d.* - FROM ( - SELECT t3.*,t1.count - FROM( - SELECT SUM(b.count) count,d.category_id - FROM goods_order a - JOIN order_sku b ON a.vendor_order_id = b.vendor_order_id AND a.vendor_id = b.vendor_id - JOIN sku c ON b.sku_id = c.id AND c.deleted_at = ? - JOIN sku_name d ON d.id = c.name_id AND d.deleted_at = ? - JOIN store e ON e.id = IF(a.jx_store_id = 0,a.store_id,a.jx_store_id) AND e.status != -2 - JOIN (SELECT city_code FROM store WHERE 1=1 - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - utils.DefaultTimeValue, - } - if len(storeIDs) > 0 { - sql += " AND id IN(" + GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - - sql += ` - )t6 ON t6.city_code = e.city_code - WHERE 1=1 - AND a.order_created_at BETWEEN ? and NOW() - AND b.sale_price > ? - GROUP BY d.category_id)t1 - JOIN sku_category t3 ON t1.category_id = t3.id - AND t3.level = ? - AND t3.deleted_at = ? - ORDER BY t1.count DESC)t4 - JOIN sku_category d ON d.id = t4.parent_id - AND d.level = ? - Order by t4.count DESC)t5 - LIMIT ? - ` - sqlParams = append(sqlParams, time.Now().AddDate(0, -1, 0), salePriceLimit, 2, utils.DefaultTimeValue, 1, limit) - err = GetRows(db, &skuCategory, sql, sqlParams...) - return skuCategory, err -} - -func GetStoreSkuCategories(db *DaoDB, storeID, parentID int) (catList []*model.SkuCategory, err error) { - sql := ` - SELECT - t1.* - FROM sku_category t1 - JOIN - ( - SELECT DISTINCT t3.category_id - FROM store_sku_bind t1 - JOIN sku t2 ON t2.id = t1.sku_id AND t2.deleted_at = ? AND t2.status = ? - JOIN sku_name t3 ON t3.id = t2.name_id AND t3.deleted_at = ? AND t3.status = ? - WHERE t1.deleted_at = ? AND t1.status = ? AND t1.store_id = ? - ) t2 ON t2.category_id = t1.id - WHERE t1.deleted_at = ?` - sqlParams := []interface{}{ - utils.DefaultTimeValue, model.SkuStatusNormal, - utils.DefaultTimeValue, model.SkuStatusNormal, - utils.DefaultTimeValue, model.SkuStatusNormal, storeID, - utils.DefaultTimeValue, - } - if parentID >= 0 { - sql += " AND t1.parent_id = ?" - sqlParams = append(sqlParams, parentID) - } - sql += " ORDER BY t1.level, t1.seq" - if err = GetRows(db, &catList, sql, sqlParams...); err == nil && len(catList) > 0 { - parentIDMap := make(map[int]int) - for _, v := range catList { - parentIDMap[v.ParentID] = 1 - } - paretnCats, err2 := GetCategories(db, -1, 0, jxutils.IntMap2List(parentIDMap), false) - if err = err2; err == nil { - catList = append(catList, paretnCats...) - } else { - catList = nil - } - } - return catList, err -} - -func GetStoreSkuNamePrice(db *DaoDB) (storeSkuNamePriceList []*model.StoreSkuNamePrice, err error) { - sql := ` - SELECT * - FROM store_sku_name_price - WHERE deleted_at = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - } - err = GetRows(db, &storeSkuNamePriceList, sql, sqlParams...) - if err != nil { - return nil, err - } - return storeSkuNamePriceList, err -} - -func SetStoreSkuBindVendorPrice(storeSkuBind *model.StoreSkuBind, vendorID int, vendorPrice int, lockTime time.Time) { - pLockTime := utils.Time2Pointer(lockTime) - switch vendorID { - case model.VendorIDJD: - storeSkuBind.JdPrice = vendorPrice - storeSkuBind.JdLockTime = pLockTime - case model.VendorIDMTWM: - storeSkuBind.MtwmPrice = vendorPrice - storeSkuBind.MtwmLockTime = pLockTime - case model.VendorIDEBAI: - storeSkuBind.EbaiPrice = vendorPrice - storeSkuBind.EbaiLockTime = pLockTime - case model.VendorIDJX: - storeSkuBind.JxPrice = vendorPrice - storeSkuBind.JxLockTime = pLockTime - } -} - -func GetStoreSkuBindVendorPrice(storeSkuBind *model.StoreSkuBind, vendorID int) (vendorPrice int) { - switch vendorID { - case model.VendorIDJD: - vendorPrice = storeSkuBind.JdPrice - case model.VendorIDMTWM: - vendorPrice = storeSkuBind.MtwmPrice - case model.VendorIDEBAI: - vendorPrice = storeSkuBind.EbaiPrice - case model.VendorIDJX: - vendorPrice = storeSkuBind.JxPrice - } - return vendorPrice -} - -func SetStoreSkuBindSyncStatus(storeSkuBind *model.StoreSkuBind, vendorID int, syncStatus int8) { - switch vendorID { - case model.VendorIDJD: - storeSkuBind.JdSyncStatus = syncStatus - case model.VendorIDMTWM: - storeSkuBind.MtwmSyncStatus = syncStatus - case model.VendorIDEBAI: - storeSkuBind.EbaiSyncStatus = syncStatus - } -} - -func GetStoreSkuBindSyncStatus(storeSkuBind *model.StoreSkuBind, vendorID int) (syncStatus int8) { - switch vendorID { - case model.VendorIDJD: - syncStatus = storeSkuBind.JdSyncStatus - case model.VendorIDMTWM: - syncStatus = storeSkuBind.MtwmSyncStatus - case model.VendorIDEBAI: - syncStatus = storeSkuBind.EbaiSyncStatus - } - return syncStatus -} - -func SetStoreCatMapSyncStatus(storeCatMap *model.StoreSkuCategoryMap, vendorID int, syncStatus int8) { - switch vendorID { - case model.VendorIDMTWM: - storeCatMap.MtwmSyncStatus = syncStatus - case model.VendorIDEBAI: - storeCatMap.EbaiSyncStatus = syncStatus - } -} - -// skuIDs为空,会导致性能极低,所以要skuIDs必须有值 -func UpdateActPrice4StoreSkuNameNew(db *DaoDB, storeIDs, skuIDs []int, skuNamesInfo *StoreSkuNamesInfo, actVendorID int) (err error) { - if len(storeIDs) == 0 || len(skuIDs) == 0 { - return nil - } - - var vendorIDs []int - var storeMapMap map[int][]*model.StoreMap - var storeSkuActMap map[int64]*model.StoreSkuAct - if !globals.IsStoreSkuAct { - if actVendorID >= 0 { - vendorIDs = []int{actVendorID} - } - } else { - storeMapList, err := GetStoresMapList(db, nil, storeIDs, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "") - if err != nil { - return err - } - storeMapMap = StoreMapList2Map(storeMapList) - storeSkuActList, err2 := GetStoresSkusAct(db, 0, false, storeIDs, skuIDs, nil, false, 0, 0) - if err = err2; err != nil { - return err - } - storeSkuActMap = make(map[int64]*model.StoreSkuAct) - for _, v := range storeSkuActList { - storeSkuActMap[jxutils.Combine2Int(int(jxutils.Combine2Int(v.StoreID, v.SkuID)), v.VendorID)] = v - } - } - - actStoreSkuList, err := GetEffectiveActStoreSkuInfo(db, 0, vendorIDs, model.ActTypeAll, storeIDs, skuIDs, time.Now(), time.Now()) - if err != nil { - globals.SugarLogger.Errorf("updateActPrice4StoreSkuNameNew can not get sku promotion info for error:%v", err) - return err - } - actStoreSkuMap4Act := jxutils.NewActStoreSkuMap(actStoreSkuList, true) - actStoreSkuMap4EarningPrice := jxutils.NewActStoreSkuMap(actStoreSkuList, false) - - for _, skuName := range skuNamesInfo.SkuNames { - if len(skuName.Skus) > 0 { - for _, v := range skuName.Skus { - if actStoreSku := actStoreSkuMap4Act.GetActStoreSku(skuName.StoreID, v.SkuID, -1); actStoreSku != nil { - v.ActPrice = int(actStoreSku.ActualActPrice) - v.ActID = actStoreSku.ActID - v.ActType = actStoreSku.Type - v.EarningPrice = int(jxutils.CaculateSkuEarningPrice(int64(v.BindPrice), int64(v.ActPrice), skuName.PayPercentage)) - v.TrendType = actStoreSku.TrendType - v.TrendPrice = actStoreSku.TrendPrice - v.DiscountType = actStoreSku.DiscountType - v.DiscountValue1 = actStoreSku.DiscountValue1 - v.DiscountValue2 = actStoreSku.DiscountValue2 - } - if actStoreSku := actStoreSkuMap4EarningPrice.GetActStoreSku(skuName.StoreID, v.SkuID, -1); actStoreSku != nil { - v.EarningPrice = int(actStoreSku.EarningPrice) - v.EarningActID = actStoreSku.ActID - } else { - earningPrice := int(jxutils.CaculateSkuEarningPrice(int64(v.BindPrice), int64(v.BindPrice), skuName.PayPercentage)) - if v.EarningPrice == 0 || earningPrice < v.EarningPrice { - v.EarningPrice = earningPrice - } - } - - if globals.IsStoreSkuAct { - v.VendorInfoMap = make(map[int]*StoreSkuVendorInfo) - for _, storeMap := range storeMapMap[skuName.StoreID] { - vendorID := storeMap.VendorID - vendorInfo := &StoreSkuVendorInfo{ - VendorID: vendorID, - } - vendorInfo.VendorPrice = refutil.GetObjFieldByName(v, GetVendorPriceStructField(model.VendorNames[vendorID])).(int) - lockTime, _ := refutil.GetObjFieldByName(v, GetVendorLockTimeStructField(model.VendorNames[vendorID])).(*time.Time) - vendorInfo.LockTime = lockTime - if vendorID != model.VendorIDJX { - vendorInfo.VendorSkuID = refutil.GetObjFieldByName(v, GetVendorThingIDStructField(model.VendorNames[vendorID])).(string) - vendorInfo.SyncStatus = refutil.GetObjFieldByName(v, GetSyncStatusStructField(model.VendorNames[vendorID])).(int8) - } else { - vendorInfo.VendorSkuID = utils.Int2Str(v.SkuID) - } - if storeSkuAct := storeSkuActMap[jxutils.Combine2Int(int(jxutils.Combine2Int(skuName.StoreID, v.SkuID)), vendorID)]; storeSkuAct != nil { - vendorInfo.VendorActID = storeSkuAct.VendorActID - vendorInfo.ActPercentage = storeSkuAct.ActPercentage - vendorInfo.ActSyncStatus = storeSkuAct.SyncStatus - vendorInfo.VendorActPrice = storeSkuAct.VendorActPrice - vendorInfo.HintActID = storeSkuAct.HintActID - } - - if actStoreSku := actStoreSkuMap4Act.GetActStoreSku(skuName.StoreID, v.SkuID, vendorID); actStoreSku != nil { - vendorInfo.ActPrice = int(actStoreSku.ActualActPrice) - vendorInfo.ActID = actStoreSku.ActID - vendorInfo.ActType = actStoreSku.Type - vendorInfo.EarningPrice = int(jxutils.CaculateSkuEarningPrice(int64(v.BindPrice), int64(v.ActPrice), skuName.PayPercentage)) - } - if actStoreSku := actStoreSkuMap4EarningPrice.GetActStoreSku(skuName.StoreID, v.SkuID, vendorID); actStoreSku != nil { - vendorInfo.EarningPrice = int(actStoreSku.EarningPrice) - vendorInfo.EarningActID = actStoreSku.ActID - } else { - earningPrice := int(jxutils.CaculateSkuEarningPrice(int64(v.BindPrice), int64(v.BindPrice), skuName.PayPercentage)) - if v.EarningPrice == 0 || earningPrice < v.EarningPrice { - vendorInfo.EarningPrice = earningPrice - } - } - v.VendorInfoMap[vendorID] = vendorInfo - } - } - } - } else { - skuName.UnitPrice = skuName.Price - } - } - return err -} - -func GetDeletedStoreSkuBind(db *DaoDB, storeID, skuID int) (storeSkuBind *model.StoreSkuBind) { - sql := ` - SELECT a.* - FROM store_sku_bind a - WHERE a.store_id = ? AND a.sku_id = ? - ORDER BY a.deleted_at DESC` - sqlParams := []interface{}{ - storeID, skuID, - } - if err := GetRow(db, &storeSkuBind, sql, sqlParams...); err != nil { - storeSkuBind = nil - } - return storeSkuBind -} - -func GetStoreSkuBindByNameID(db *DaoDB, storeID, nameID, status int) (storeSkuBind []*model.StoreSkuBind, err error) { - sql := ` - SELECT c.* - FROM sku a - JOIN store_sku_bind c ON c.sku_id = a.id - WHERE c.store_id = ? - AND a.name_id = ? - AND c.deleted_at = ? - AND a.deleted_at = ? - ` - sqlParams := []interface{}{ - storeID, - nameID, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - } - err = GetRows(db, &storeSkuBind, sql, sqlParams...) - return storeSkuBind, err -} - -func GetPriceReferPrice(db *DaoDB, cityCode int, skuID int, snapDate time.Time) (result *PriceReferSnapshotExt, err error) { - var ( - pRefer *PriceReferSnapshotExt - priceRefer = &PriceReferSnapshotExt{} - ) - sql := ` - SELECT a.max_unit_price, a.min_unit_price, a.avg_unit_price, a.mid_unit_price, a.sku_id id, b.spec_quality, c.unit, b.spec_unit - FROM price_refer_snapshot a - JOIN sku b ON a.sku_id = b.id - JOIN sku_name c ON c.id = b.name_id - WHERE 1=1 - AND a.snapshot_at = ? - AND a.city_code = ? - ` - sqlParams := []interface{}{ - snapDate, - cityCode, - } - if skuID > 0 { - sql += " AND a.sku_id = ?" - sqlParams = append(sqlParams, skuID) - } - err = GetRow(db, &pRefer, sql, sqlParams...) - if err != nil { - return nil, err - } - if pRefer != nil { - var ( - specQuality float64 - ) - if pRefer.Unit == model.SpecialUnit { - if pRefer.SpecUnit == model.SpecUnitNames[1] || pRefer.SpecUnit == model.SpecUnitNames[2] { - specQuality = float64(pRefer.SpecQuality) * 1000 - } else { - specQuality = float64(pRefer.SpecQuality) - } - priceRefer.MaxPrice = int(utils.Float64TwoInt64(specQuality / utils.Int2Float64(model.SpecialSpecQuality) * utils.Int2Float64(pRefer.MaxUnitPrice))) - priceRefer.MinPrice = int(utils.Float64TwoInt64(specQuality / utils.Int2Float64(model.SpecialSpecQuality) * utils.Int2Float64(pRefer.MinUnitPrice))) - priceRefer.AvgPrice = int(utils.Float64TwoInt64(specQuality / utils.Int2Float64(model.SpecialSpecQuality) * utils.Int2Float64(pRefer.AvgUnitPrice))) - priceRefer.MidPrice = int(utils.Float64TwoInt64(specQuality / utils.Int2Float64(model.SpecialSpecQuality) * utils.Int2Float64(pRefer.MidUnitPrice))) - } else { - priceRefer.MaxPrice = pRefer.MaxUnitPrice - priceRefer.MinPrice = pRefer.MinUnitPrice - priceRefer.AvgPrice = pRefer.AvgUnitPrice - priceRefer.MidPrice = pRefer.MidUnitPrice - } - } - return priceRefer, err -} - -func GetStoreSkusAndSkuName(db *DaoDB, storeIDs, skuIDs, nameIDs []int) (storeSkuAndName []*StoreSkuAndName, err error) { - sql := ` - SELECT a.id bind_id, a.store_id, a.jd_sync_status, a.mtwm_sync_status, a.ebai_sync_status, a.unit_price, a.price, - c.id name_id, c.unit, b.* - FROM store_sku_bind a - JOIN sku b ON b.id = a.sku_id AND b.deleted_at = ? - JOIN sku_name c ON c.id = b.name_id AND c.deleted_at = ? - WHERE a.deleted_at = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - utils.DefaultTimeValue, - utils.DefaultTimeValue, - } - if len(storeIDs) > 0 { - sql += " AND a.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - if len(skuIDs) > 0 { - sql += " AND a.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" - sqlParams = append(sqlParams, skuIDs) - } - if len(nameIDs) > 0 { - sql += " AND b.name_id IN (" + GenQuestionMarks(len(nameIDs)) + ")" - sqlParams = append(sqlParams, nameIDs) - } - err = GetRows(db, &storeSkuAndName, sql, sqlParams...) - return storeSkuAndName, err -} - -func UpdateYbOtherSku(db *DaoDB, storeSkuSyncInfo *StoreSkuSyncInfo) (err error) { - sql := ` - UPDATE store_sku_bind a - JOIN sku b ON a.sku_id = b.id AND b.name_id = ? - JOIN (SELECT * FROM store_sku_bind WHERE sku_id = ?)c ON c.store_id = a.store_id - SET a.yb_id = c.yb_id,a.yb_sync_status = c.yb_sync_status,a.yb_price = c.yb_price - WHERE a.store_id = ? - AND a.yb_sync_status <> ? - ` - sqlParams := []interface{}{ - storeSkuSyncInfo.NameID, - storeSkuSyncInfo.SkuID, - storeSkuSyncInfo.StoreID, - 0, - } - _, err = ExecuteSQL(db, sql, sqlParams) - return err -} - -func UpdateJdsWareID(db *DaoDB, storeSkuSyncInfo *StoreSkuSyncInfo) (err error) { - sql := ` - UPDATE store_sku_bind - SET jds_ware_id = ?, jds_id = ? - WHERE store_id = ? - AND sku_id = ? - AND deleted_at = ? - ` - sqlParams := []interface{}{ - storeSkuSyncInfo.JdsWareID, - storeSkuSyncInfo.VendorSkuID, - storeSkuSyncInfo.StoreID, - storeSkuSyncInfo.SkuID, - utils.DefaultTimeValue, - } - _, err = ExecuteSQL(db, sql, sqlParams) - return err -} - -type tStoreSkuAudit struct { - model.StoreSkuAudit - SkuName string `orm:"size(255)" json:"skuName"` - StoreName string `json:"storeName"` - Prefix string `orm:"size(255)" json:"prefix"` - Unit string `orm:"size(8)" json:"unit"` - SpecQuality float32 `json:"-"` // 为份必然为500,这个主要作用只是用于确保SkuName的唯一性 - SpecUnit string `orm:"size(8)" json:"-"` // 为份必然为克,这个主要作用只是用于确保SkuName的唯一性 - Img string `orm:"size(512)" json:"img"` - Name string `json:"name"` - MidUnitPrice int `json:"midUnitPrice"` - CityName string `json:"cityName"` - PayPercentage int `json:"payPercentage"` - StoreLevel string `json:"storeLevel"` -} - -func GetStoreSkuAudit(db *DaoDB, storeIDs, nameIDs, skuIDs, statuss, types []int, name, remark, keyword, marketManPhone, cityName string, applyTimeStart, applyTimeEnd, auditTimeStart, auditTimeEnd time.Time, pageSize, offset int) (pagedInfo *model.PagedInfo, err error) { - var requestList []*tStoreSkuAudit - sql := ` - SELECT SQL_CALC_FOUND_ROWS DISTINCT a.*, - c.name sku_name, c.prefix, c.unit, c.spec_quality, c.spec_unit, c.img, - d.name store_name, b.name, e.mid_unit_price, f.name city_name, d.pay_percentage, d.store_level - FROM store_sku_audit a - LEFT JOIN user b ON a.user_id = b.user_id - LEFT JOIN sku_name c ON c.id = a.name_id AND c.deleted_at = ? - LEFT JOIN store d ON d.id = a.store_id AND d.deleted_at = ? - LEFT JOIN place f ON f.code = d.city_code - LEFT JOIN price_refer_snapshot e ON e.name_id = c.id AND e.city_code = ? AND e.snapshot_at = ? - WHERE a.deleted_at = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, utils.DefaultTimeValue, - 0, utils.Time2Date(time.Now().AddDate(0, 0, -1)), - utils.DefaultTimeValue} - if len(storeIDs) > 0 { - sql += " AND a.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - if len(nameIDs) > 0 { - sql += " AND a.name_id IN (" + GenQuestionMarks(len(nameIDs)) + ")" - sqlParams = append(sqlParams, nameIDs) - } - if len(statuss) > 0 { - sql += " AND a.status IN (" + GenQuestionMarks(len(statuss)) + ")" - sqlParams = append(sqlParams, statuss) - } - if remark != "" { - sql += " AND a.remark LIKE ? " - sqlParams = append(sqlParams, "%"+remark+"%") - } - if name != "" { - sql += " AND b.name LIKE ? " - sqlParams = append(sqlParams, "%"+name+"%") - } - if applyTimeStart != utils.ZeroTimeValue && applyTimeEnd != utils.ZeroTimeValue { - sql += " AND a.created_at BETWEEN ? AND ?" - sqlParams = append(sqlParams, applyTimeStart, applyTimeEnd) - } - if auditTimeStart != utils.ZeroTimeValue && auditTimeEnd != utils.ZeroTimeValue { - sql += " AND a.updated_at BETWEEN ? AND ?" - sqlParams = append(sqlParams, auditTimeStart, auditTimeEnd) - } - if len(types) > 0 { - sql += " AND a.type IN (" + GenQuestionMarks(len(types)) + ")" - sqlParams = append(sqlParams, types) - } - if keyword != "" { - sql += " AND (b.name LIKE ? OR a.remark LIKE ? OR a.name_id LIKE ? OR a.user_id LIKE ? OR a.store_id LIKE ? OR f.name LIKE ?)" - sqlParams = append(sqlParams, "%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%") - } - if marketManPhone != "" { - sql += " AND d.market_man_phone LIKE ? " - sqlParams = append(sqlParams, "%"+marketManPhone+"%") - } - if cityName != "" { - sql += " AND f.name LIKE ? " - sqlParams = append(sqlParams, "%"+cityName+"%") - } - sql += " ORDER BY a.updated_at LIMIT ? OFFSET ?" - pageSize = jxutils.FormalizePageSize(pageSize) - sqlParams = append(sqlParams, pageSize, offset) - Begin(db) - defer Commit(db) - if err = GetRows(db, &requestList, sql, sqlParams...); err == nil { - return &model.PagedInfo{ - TotalCount: GetLastTotalRowCount(db), - Data: requestList, - }, nil - } - return pagedInfo, err -} - -func GetStoreSkuAuditLight(db *DaoDB, storeIDs, nameIDs []int, status int) (storeSkuAudit []*model.StoreSkuAudit, err error) { - sql := ` - SELECT a.* - FROM store_sku_audit a - WHERE a.deleted_at = ? - ` - sqlParams := []interface{}{utils.DefaultTimeValue} - if len(storeIDs) > 0 { - sql += " AND a.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - if len(nameIDs) > 0 { - sql += " AND a.name_id IN (" + GenQuestionMarks(len(nameIDs)) + ")" - sqlParams = append(sqlParams, nameIDs) - } - if status != model.StoreAuditStatusAll { - sql += " AND a.status = ? " - sqlParams = append(sqlParams, status) - } - err = GetRows(db, &storeSkuAudit, sql, sqlParams...) - return storeSkuAudit, err -} - -func GetTopSkusByNoCityCode(db *DaoDB) (skuNameAndPlace []*SkuNameAndPlace, err error) { - var skuName1 []model.SkuName - _, err = db.Db.QueryTable("sku_name").Filter("best_seller", "1").All(&skuName1) - for k, _ := range skuName1 { - skuNameAndPlace1 := &SkuNameAndPlace{ - SkuName: skuName1[k], - } - skuNameAndPlace = append(skuNameAndPlace, skuNameAndPlace1) - } - return skuNameAndPlace, err -} - -func GetStoreSkuHistory(db *DaoDB, storeIDs, skuIDs []int, status int, snapShot time.Time) (storeSkuHistory []*model.StoreSkuBindHistory, err error) { - sql := ` - SELECT a.* - FROM store_sku_bind_history a - WHERE a.deleted_at = ? - ` - sqlParams := []interface{}{utils.DefaultTimeValue} - if len(storeIDs) > 0 { - sql += " AND a.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")" - sqlParams = append(sqlParams, storeIDs) - } - if len(skuIDs) > 0 { - sql += " AND a.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")" - sqlParams = append(sqlParams, skuIDs) - } - if status != model.StoreAuditStatusAll { - sql += " AND a.status = ? " - sqlParams = append(sqlParams, status) - } - if !utils.IsTimeZero(snapShot) { - sql += " AND a.snapshot_at = ? " - sqlParams = append(sqlParams, snapShot) - } - err = GetRows(db, &storeSkuHistory, sql, sqlParams...) - return storeSkuHistory, err -} diff --git a/business/model/dao/store_sku_sales.go b/business/model/dao/store_sku_sales.go deleted file mode 100644 index 5c8b05940..000000000 --- a/business/model/dao/store_sku_sales.go +++ /dev/null @@ -1,78 +0,0 @@ -package dao - -import ( - "time" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/model" -) - -func GetSkuSalesCntList(db *DaoDB, storeID, cityCode, dayNum, limit int, skuIDs []int) (skuCountList []*model.SkuCount, err error) { - sql := ` - SELECT t2.jx_sku_id sku_id, SUM(t2.count) count - FROM goods_order t1 - JOIN order_sku t2 on t1.vendor_order_id = t2.vendor_order_id and t1.vendor_id = t2.vendor_id - JOIN store t3 on t1.jx_store_id = t3.id - WHERE t1.order_finished_at >= ? AND t1.order_finished_at < ? - AND t1.status = ? - AND t2.jx_sku_id <> 0 - AND t3.city_code = ? - ` - if dayNum < 0 { - dayNum = 30 - } - beginTime := utils.GetCurDate().Add(-time.Hour * 24 * time.Duration(dayNum)) - endTime := utils.GetCurDate() - sqlParams := []interface{}{ - beginTime, - endTime, - model.OrderStatusFinished, - cityCode, - } - if storeID > 0 { - sql += ` - AND t1.jx_store_id = ? - ` - sqlParams = append(sqlParams, storeID) - } - if len(skuIDs) > 0 { - sql += ` - AND t2.jx_sku_id IN (` + GenQuestionMarks(len(skuIDs)) + `)` - sqlParams = append(sqlParams, skuIDs) - } - sql += ` - GROUP BY jx_sku_id - ORDER BY count DESC - ` - if limit > 0 { - sql += ` - LIMIT ? - ` - sqlParams = append(sqlParams, limit) - } - err = GetRows(db, &skuCountList, sql, sqlParams) - return skuCountList, err -} - -func GetSkuBadCommentCntList(db *DaoDB, storeID, dayNum int) (skuCountList []*model.SkuCount, err error) { - sql := ` - SELECT t2.jx_sku_id sku_id, COUNT(*) count - FROM jx_bad_comments t1 - JOIN order_sku t2 ON t1.order_id = t2.vendor_order_id - WHERE t1.createtime >= ? AND t1.createtime < ? - AND t1.jxstoreid = ? - GROUP BY t2.jx_sku_id - ` - if dayNum < 0 { - dayNum = 30 - } - beginTime := utils.GetCurDate().Add(-time.Hour * 24 * time.Duration(dayNum)) - endTime := utils.GetCurDate() - sqlParams := []interface{}{ - beginTime, - endTime, - storeID, - } - err = GetRows(db, &skuCountList, sql, sqlParams) - return skuCountList, err -} diff --git a/business/model/dao/store_sku_test.go b/business/model/dao/store_sku_test.go deleted file mode 100644 index 8a5d5ed3c..000000000 --- a/business/model/dao/store_sku_test.go +++ /dev/null @@ -1,38 +0,0 @@ -package dao - -import ( - "testing" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/globals" -) - -func TestGetFullStoreSkus(t *testing.T) { - skuList, err := GetFullStoreSkus(GetDB(), model.VendorIDJD, 100118) - if err != nil { - t.Fatal(err) - } - globals.SugarLogger.Debug(utils.Format4Output(skuList, false)) -} - -func TestGetStoreSkus(t *testing.T) { - skuList, err := GetStoreSkus(GetDB(), model.VendorIDMTWM, 100134, nil) - if err != nil { - t.Fatal(err) - } - globals.SugarLogger.Debug(utils.Format4Output(skuList, false)) -} - -func TestGetDeletedStoreSkuBind(t *testing.T) { - storeSkuBind := GetDeletedStoreSkuBind(GetDB(), 100123, 30648) - globals.SugarLogger.Debug(utils.Format4Output(storeSkuBind, false)) -} - -func TestGetStoreSkuPriceAndWeight(t *testing.T) { - storeSkuBind, err := GetStoreSkuPriceAndWeight(GetDB(), "11863739", model.VendorIDJD, []string{"2023508979"}) - if err != nil { - t.Fatal(err) - } - globals.SugarLogger.Debug(utils.Format4Output(storeSkuBind, false)) -} diff --git a/business/model/dao/store_test.go b/business/model/dao/store_test.go deleted file mode 100644 index 049f82bd8..000000000 --- a/business/model/dao/store_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package dao - -import ( - "testing" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/globals" -) - -func TestGetStoreDetail(t *testing.T) { - storeDetail, err := GetStoreDetailByVendorStoreID(GetDB(), "11733077", 0) - if err != nil { - t.Fatal(err) - } - globals.SugarLogger.Debug(utils.Format4Output(storeDetail, false)) -} - -func TestGetStoreCourierList(t *testing.T) { - storeCourierList, err := GetStoreCourierList(GetDB(), []int{100119}, nil, model.StoreStatusOpened, model.StoreAuditStatusOnline) - if err != nil { - t.Fatal(err) - } - globals.SugarLogger.Debug(utils.Format4Output(storeCourierList, false)) -} - -func TestFormalizeStoreStatus(t *testing.T) { - err := FormalizeStoreStatus(GetDB(), 100119, model.StoreStatusOpened) - if err != nil { - t.Fatal(err) - } -} - -func TestGetStoreList4Role(t *testing.T) { - storeList, err := GetStoreList(GetDB(), nil, nil, nil, nil, "NiuBi") - t.Log(utils.Format4Output(storeList, false)) - if err != nil { - t.Fatal(err) - } -} - -func TestGetStoresMapList(t *testing.T) { - storeList, err := GetStoresMapList(GetDB(), nil, nil, nil, model.StoreStatusClosed, model.StoreIsSyncYes, "") - t.Log(utils.Format4Output(storeList, false)) - if err != nil { - t.Fatal(err) - } -} diff --git a/business/model/dao/thing_map.go b/business/model/dao/thing_map.go deleted file mode 100644 index 15f312ac4..000000000 --- a/business/model/dao/thing_map.go +++ /dev/null @@ -1,77 +0,0 @@ -package dao - -import ( - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/globals" -) - -func GetThingMapList(db *DaoDB, thingType int, vendorIDs, thingIDs []int) (cats []*model.ThingMap, err error) { - sql := ` - SELECT t1.* - FROM thing_map t1 - WHERE t1.deleted_at = ? AND t1.thing_type = ? - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, - thingType, - } - if len(thingIDs) > 0 { // 必须要指定ID - sql += " AND t1.thing_id IN (" + GenQuestionMarks(len(thingIDs)) + ")" - sqlParams = append(sqlParams, thingIDs) - err = GetRows(db, &cats, sql, sqlParams...) - } - return cats, err -} - -func GetThingMapMap(db *DaoDB, thingType int, vendorIDs, thingIDs []int) (thingMapMap map[int64][]*model.ThingMap, err error) { - thingMapList, err := GetThingMapList(db, thingType, vendorIDs, thingIDs) - if err == nil { - thingMapMap = make(map[int64][]*model.ThingMap) - for _, thingMap := range thingMapList { - thingMapMap[thingMap.ThingID] = append(thingMapMap[thingMap.ThingID], thingMap) - } - } - return thingMapMap, err -} - -func SetThingMapSyncStatus(db *DaoDB, vendorIDs []int, vendorOrgCodes []string, thingType int, thingIDs []int, syncStatus int8) (num int64, err error) { - sql := ` - UPDATE thing_map t1 - SET t1.sync_status = t1.sync_status | ? - WHERE t1.deleted_at = ? AND t1.thing_type = ? - ` - sqlParams := []interface{}{ - syncStatus, - utils.DefaultTimeValue, - thingType, - } - if len(vendorIDs) > 0 { - sql += " AND t1.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")" - sqlParams = append(sqlParams, vendorIDs) - } - if len(vendorOrgCodes) > 0 { - sql += " AND t1.vendor_org_code IN (" + GenQuestionMarks(len(vendorOrgCodes)) + ")" - sqlParams = append(sqlParams, vendorOrgCodes) - } - if len(thingIDs) > 0 { - sql += " AND t1.thing_id IN (" + GenQuestionMarks(len(thingIDs)) + ")" - sqlParams = append(sqlParams, thingIDs) - } - num, err = ExecuteSQL(db, sql, sqlParams...) - return num, err -} - -func SetSkuNameSyncStatus(db *DaoDB, vendorIDs []int, vendorOrgCodes []string, nameIDs []int, syncStatus int8) (num int64, err error) { - skuIDs, err2 := GetSkuIDByNames(db, nameIDs) - if err = err2; err == nil { - num, err = SetThingMapSyncStatus(db, vendorIDs, vendorOrgCodes, model.ThingTypeSku, skuIDs, syncStatus) - } - return num, err -} - -func SetSkuSyncStatus(db *DaoDB, vendorID int, skuIDs []int, syncStatus int8) (num int64, err error) { - globals.SugarLogger.Debugf("SetSkuSyncStatus, vendorID:%d", vendorID) - num, err = SetThingMapSyncStatus(db, []int{vendorID}, nil, model.ThingTypeSku, skuIDs, syncStatus) - return num, err -} diff --git a/business/model/job.go b/business/model/job.go index 0f9b38a56..ae3b99da3 100644 --- a/business/model/job.go +++ b/business/model/job.go @@ -5,6 +5,13 @@ import "time" const ( JobStatusDoing = 0 JobStatusFinished = 1 + + JobOrderStatusAccept = 5 + JobOrderStatusWaitAudit = 10 + JobOrderStatusAuditPass = 15 + JobOrderStatusAuditUnPass = 20 + JobOrderStatusFinish = 110 + JobOrderStatusCancel = 115 ) type Job struct { @@ -62,3 +69,22 @@ func (v *JobStep) TableIndex() [][]string { []string{"JobID"}, } } + +type JobOrder struct { + ModelIDCUL + + JobID int `orm:"column(job_id)" json:"jobID"` //任务ID + UserID string `orm:"column(user_id)" json:"thingID"` //接任务人ID + Status int `json:"status"` //任务订单状态,接单,待审核,已审核,已结算等 + SubmitAuditAt time.Time `json:"submitAuditTime"` //提交审核日期 + AuditAt time.Time `json:"auditAt"` //审核日期 + Content string `josn:"content"` //任务审核内容 + Img string `json:"img"` //任务审核图片 +} + +func (v *JobOrder) TableIndex() [][]string { + return [][]string{ + []string{"JobID"}, + []string{"UserID"}, + } +} diff --git a/business/model/sensitive_words.go b/business/model/sensitive_words.go deleted file mode 100644 index 5c791b3cb..000000000 --- a/business/model/sensitive_words.go +++ /dev/null @@ -1,7 +0,0 @@ -package model - -type SensitiveWord struct { - ModelIDCULD - VendorID int `orm:"column(vendor_id)" json:"vendorID"` - Word string `orm:"size(30);unique" json:"word"` -} diff --git a/business/model/sku.go b/business/model/sku.go deleted file mode 100644 index 508efd581..000000000 --- a/business/model/sku.go +++ /dev/null @@ -1,326 +0,0 @@ -package model - -import "time" - -const ( - SkuCategoryNormal = 0 - SkuCategorySpecial = 1 -) - -const ( - SpecUnitG = 0 - SpecUnitKG = 1 - SpecUnitL = 2 - SpecUnitML = 3 -) - -const ( - NoCatCatgoryID = 291 - NOSkuNameImg = "https://image.jxc4.com/noGoodsImg.jpg" - SkuNameImgStandard = "?imageMogr2/thumbnail/!800x800r/gravity/Center/crop/800x800" - SkuNameImgToPng = "?imageView2/0/format/png/q/75" -) - -const ( - SkuStatusDeleted = -1 - SkuStatusDontSale = 0 - SkuStatusNormal = 1 -) - -const ( - CategoryStatusDisabled = 0 - CategoryStatusEnable = 1 -) - -var ( - SpecUnitNames = []string{ - "g", - "kg", - "L", - "ml", - } -) - -var ( - UnitNames = []string{ - "份", - "袋", - "瓶", - "只", - "组", - "个", - "盒", - "把", - "半只", - "包", - "条", - "根", - "箱", - "听", - "套", - "罐", - "件", - "块", - "片", - "支", - "杯", - "桶", - "串", - } - SkuNamePrefixNames = []string{ - "新鲜", - "组合菜", - "熟食", - "鲜活现杀", - "冰冻", - "净菜", - "非熟食", - } - - SpecialUnit = "份" - SpecialSpecQuality = 500 - SpecialSpecUnit = "g" - SpecialSpecUnit2 = "ml" -) - -var ( - CategoryTypeName = map[int]string{ - SkuCategoryNormal: "普通类别", - SkuCategorySpecial: "特殊类别", - } - SkuStatusName = map[int]string{ - SkuStatusDeleted: "删除", - SkuStatusDontSale: "下架", - SkuStatusNormal: "上架", - 2: "删除", - 3: "不可售", - 4: "可售", - } -) - -// 这个指的是厂商(比如京东到家,饿百)自已的商品分类,与商家自己的商品分类是两回事 -type SkuVendorCategory struct { - ModelIDCUL - - VendorCategoryID string `orm:"size(48);column(vendor_category_id)" json:"vendorCategoryID"` - VendorID int `orm:"column(vendor_id)" json:"vendorID"` - Name string `orm:"size(255);index" json:"name"` - IsLeaf int8 `json:"isLeaf"` - Level int `json:"level"` - ParentID string `orm:"column(parent_id);size(48);index" json:"parentID"` // 父ID,引用的是VendorCategoryID而不是ID -} - -func (*SkuVendorCategory) TableUnique() [][]string { - return [][]string{ - []string{"VendorCategoryID", "VendorID"}, - } -} - -// 基础数据,除了商家商品类别外,基本都以京东到家为准 -type SkuCategory struct { - ModelIDCULD - - Name string `orm:"size(255)" json:"name"` - ParentID int `orm:"column(parent_id)" json:"parentID"` - Level int8 `json:"level"` - Type int8 `json:"type"` // 类别类型,即是普通类别还是特殊用于做活动的类别 - Seq int `json:"seq"` - - JdCategoryID int64 `orm:"column(jd_category_id)" json:"jdCategoryID"` // 这个是指对应的京东商品类别 - EbaiCategoryID int64 `orm:"column(ebai_category_id)" json:"ebaiCategoryID"` // 这个是指对应的饿百商品类别 - MtwmCategoryID int64 `orm:"column(mtwm_category_id)" json:"mtwmCategoryID"` // 这个是指对应的美团外卖商品类别 - YbCategoryID int64 `orm:"column(yb_category_id)" json:"ybCategoryID"` // 这个是指对应的银豹商品类别 - JdsCategoryID int64 `orm:"column(jds_category_id)" json:"jdsCategoryID"` // 这个是指对应的京东商城类别 - - // ElmCategoryID int64 `orm:"column(elm_category_id)" json:"elmCategoryID"` // 这个是指对应的饿了么商品类别 - // WscCategoryID int64 `orm:"column(wsc_category_id)" json:"wscCategoryID"` // 这个是指对应的美团外卖商品类别 - Status int8 `orm:"default(1)" json:"status"` //分类状态,0表示禁用,1表示启用 - Img string `orm:"size(512)" json:"img"` //分类图片 - - ExdName string `json:"exdName"` //饿鲜达对应分类名 - ExdSeq int `json:"exdSeq"` - IsExdSpec int `json:"isExdSpec"` //是否是饿鲜达特有新建的分类 - // JdID int64 `orm:"column(jd_id);index" json:"jdID"` // 这个是指商家自己的商品类别在京东平台上的ID - // JdSyncStatus int8 `orm:"default(2)" json:"jdSyncStatus"` - IsSync int `json:"isSync"` //是否同步到平台 -} - -func (*SkuCategory) TableUnique() [][]string { - return [][]string{ - []string{"Name", "Level", "DeletedAt"}, - } -} - -type SkuName struct { - ModelIDCULD - - Prefix string `orm:"size(255)" json:"prefix"` - Name string `orm:"size(255)" json:"name"` - - ExPrefix string `orm:"size(255)" json:"exPrefix"` - ExPrefixBegin *time.Time `orm:"null" json:"exPrefixBegin"` - ExPrefixEnd *time.Time `orm:"null" json:"exPrefixEnd"` - ExVendorID int `orm:"column(ex_vendor_id)" json:"exVendorID"` - - BrandID int `orm:"column(brand_id);default(0)" json:"brandID"` // todo,此属性暂时没有使用,且有问题,应该是不同平台都有一个brandid - CategoryID int `orm:"column(category_id);index" json:"categoryID"` // 标准类别 - JdCategoryID int64 `orm:"column(jd_category_id)" json:"jdCategoryID"` // 这个是指对应的京东商品类别 - - IsGlobal int8 `orm:"default(1)" json:"isGlobal"` // 是否是全部(全国)可见,如果否的话,可见性由SkuPlace决定 - Unit string `orm:"size(8)" json:"unit"` - SpecQuality float32 `json:"-"` // 为份必然为500,这个主要作用只是用于确保SkuName的唯一性 - SpecUnit string `orm:"size(8)" json:"-"` // 为份必然为克,这个主要作用只是用于确保SkuName的唯一性 - Price int `json:"price"` // 单位为分,标准价,不为份的就为实际标准价,为份的为每市斤价,实际还要乘质量。todo 为份的确定必须有质量 - - Img string `orm:"size(512)" json:"img"` - Img2 string `orm:"size(512)" json:"img2"` // 第二张图片 - Img3 string `orm:"size(512)" json:"img3"` //第三张图片 - ImgWatermark string `orm:"size(512)" json:"imgWatermark"` //图片水印 - ImgMix string `orm:"size(512)" json:"imgMix"` //图片混合水印的图片 - // ImgEbai string `orm:"size(255)" json:"imgEbai"` // 饿百图片地址 - // ImgHashCode string `orm:"size(255);index" json:"img_hash_code"` - - DescImg string `orm:"size(255)" json:"descImg"` // 商品详情图片描述 - // DescImgEbai string `orm:"size(255)" json:"descImgEbai"` // 饿百的商品详情图片描述RTF - - Upc *string `orm:"size(20)"` - Status int `orm:"default(1)" json:"status"` // skuname状态,取值同sku.Status - IsSpu int8 `orm:"column(is_spu)" json:"isSpu"` // 用于指明是否SKUNAME当成SPU - - // JdID int64 `orm:"column(jd_id);null;index" json:"jdID"` - // JdSyncStatus int8 `orm:"default(2)" json:"jdSyncStatus"` - - // LinkID int `orm:"column(link_id);null;index" json:"linkID"` - YbNameSuffix string `json:"ybNameSuffix"` //银豹商品后缀 - JdsStockSwitch int8 `orm:"default(1)" json:"jdsStockSwitch"` //京东商城总库存 - PreparationTime int `orm:"default(1)" json:"preparationTime"` //商品准备时长 - BestSeller int `json:"bestSeller"` //畅销品 0不是 1是 -} - -func (*SkuName) TableUnique() [][]string { - return [][]string{ - []string{"Name", "Prefix", "SpecQuality", "SpecUnit", "Unit", "IsSpu", "DeletedAt"}, - []string{"Upc", "DeletedAt"}, - } -} - -func (*SkuName) TableIndex() [][]string { - return [][]string{ - []string{"ExPrefix", "ExPrefixBegin", "ExPrefixEnd", "DeletedAt"}, - } -} - -type Sku struct { - ModelIDCULD - - CategoryID int `orm:"column(category_id)" json:"categoryID"` // 特殊类别,一般用于秒杀,特价之类的特殊类别 - NameID int `orm:"column(name_id)" json:"nameID"` // todo 这个索引应该要求唯一 - SkuIndex int `json:"-"` - Comment string `orm:"size(255)" json:"comment"` - SpecQuality float32 `json:"specQuality"` - SpecUnit string `orm:"size(8)" json:"specUnit"` // 质量或容量 - Weight int `json:"weight"` // 重量/质量,单位为克,当相应的SkuName的SpecUnit为g或kg时,必须等于SpecQuality - Status int `json:"status"` - Seq int `json:"seq"` - - ExdSkuID string `orm:"column(exd_sku_id)" json:"exdSkuID"` //饿鲜达商品ID - ExdCategoryThirdID int `orm:"column(exd_category_third_id)" json:"exdCategoryThirdID"` - EclpID string `orm:"column(eclp_id)" json:"eclpID"` //eclp物料商品ID - MinOrderCount int `json:"minOrderCount"` //最少起购份数,美团用 - LadderBoxNum int `json:"ladderBoxNum"` //包装费x件 ,美团用 - LadderBoxPrice int `json:"ladderBoxPrice"` //包装费y元 ,美团用 - // JdID int64 `orm:"column(jd_id);null;index" json:"jdID"` - // JdSyncStatus int8 `orm:"default(2)" json:"jdSyncStatus"` - - // LinkID int `orm:"column(link_id);null;index" json:"linkID"` -} - -type SkuAndName struct { - Sku - Name string `json:"name"` - Unit string `json:"unit"` - Prefix string `json:"prefix"` - IsSpu int `json:"isSpu"` - Upc string `json:"upc"` - ExPrefix string `json:"exPrefix"` - ExPrefixBegin *time.Time `json:"exPrefixBegin"` - ExPrefixEnd *time.Time `json:"eExPrefixEndxPrefixEnd"` - Price int `json:"price"` - StoreSkuStatus int `json:"storeSkuStatus"` - ActPrice int `json:"actPrice"` - ActID int `orm:"column(act_id)" json:"actID"` - ActType int `orm:"column(act_type)" json:"actType"` - - EarningPrice int `json:"earningPrice"` - EarningActID int `orm:"column(earning_act_id)" json:"earningActID"` -} - -func (*Sku) TableUnique() [][]string { - return [][]string{ - []string{"NameID", "SpecQuality", "SpecUnit", "DeletedAt"}, - } -} - -type SkuNamePlaceBind struct { - ModelIDCUL - - NameID int `orm:"column(name_id)"` - PlaceCode int -} - -func (*SkuNamePlaceBind) TableUnique() [][]string { - return [][]string{ - []string{"NameID", "PlaceCode"}, - } -} - -type SkuWithVendor struct { - *Sku - MapList []*ThingMap `json:"mapList"` -} - -type SkuNameExt struct { - SkuName - Skus []*SkuWithVendor `orm:"-" json:"skus"` - SkusStr string `json:"-"` - FullName string `json:"fullName"` - Places []int `orm:"-" json:"places"` - PlacesStr string `json:"-"` - MidUnitPrice int `json:"midUnitPrice"` - - JdCategoryID string `json:"jdCategoryID"` - JdsCategoryID string `json:"jdsCategoryID"` - EbaiCategoryID string `json:"ebaiCategoryID"` - MtwmCategoryID string `json:"mtwmCategoryID"` -} - -type SkuExinfoMap struct { - ModelIDCULD - - NameID int `orm:"column(name_id)" json:"nameID"` - VendorID int `orm:"column(vendor_id)" json:"vendorID"` - BeginAt time.Time `orm:"type(datetime);index" json:"beginAt"` //设置起始时间 - EndAt time.Time `orm:"type(datetime);index" json:"endAt"` //设置结束时间 - ExPrefix string `orm:"size(255)" json:"exPrefix"` //额外前缀 - ImgWatermark string `orm:"size(512)" json:"imgWatermark"` //图片水印 -} - -func (*SkuExinfoMap) TableIndex() [][]string { - return [][]string{ - []string{"NameID", "VendorID", "BeginAt", "EndAt"}, - } -} - -type SkuVendorCategoryMap struct { - ModelIDCULD - - NameID int `orm:"column(name_id)" json:"nameID"` - VendorID int `orm:"column(vendor_id)" json:"vendorID"` - VendorCategoryID string `orm:"column(vendor_category_id)" json:"vendorCategoryID"` -} - -func (*SkuVendorCategoryMap) TableIndex() [][]string { - return [][]string{ - []string{"NameID", "VendorID"}, - } -} diff --git a/business/model/store.go b/business/model/store.go deleted file mode 100644 index 8b513e42a..000000000 --- a/business/model/store.go +++ /dev/null @@ -1,759 +0,0 @@ -package model - -import ( - "time" - - "git.rosy.net.cn/baseapi/utils" -) - -const ( - StoreStatusAll = -9 - StoreStatusDisabled = -2 - StoreStatusClosed = -1 - StoreStatusHaveRest = 0 - StoreStatusOpened = 1 - - StoreIsSyncAll = -1 - StoreIsSyncNo = 0 - StoreIsSyncYes = 1 -) - -const ( - StoreAuditStatusCreated = 1 - StoreAuditStatusOnline = 0 - StoreAuditStatusRejected = -1 - StoreAuditStatusAll = -9 -) - -const ( - StoreSkuAuditTypePrice = 1 //改价 - StoreSkuAuditTypeFocus = 2 //关注 -) - -const ( - MainSubStoreName = "本店" - MainSubStoreAddress = "本店" -) - -// 配送范围类型,此定义与京东到家相同,除非特殊说明,本系统中的坐标都是火星坐标 -const ( - DeliveryRangeTypePolygon = 2 - DeliveryRangeTypeRadius = 3 -) - -const ( - StoreDeliveryTypeCrowdSourcing = 0 //缺省,平台众包配送,可转自送 - StoreDeliveryTypeByPlatform = 1 //平台专送 - StoreDeliveryTypeByStore = 2 //完全门店自送 -) - -const ( - StoreChangePriceTypeDirect = 0 // 普通门店 - StoreChangePriceTypeNeedApprove = 1 // 改价需要审核,暂时没用 - StoreChangePriceTypeBossDisabled = 2 // 完全禁止改价 - StoreChangePriceTypeManagedStore = 3 // 直营门店,禁止改价 -) - -const ( - AutoReplyAll = 0 // 全部自动回复 - AutoReplyGoodComment = 1 // 禁止差评自动回复 - AutoReplyDisabled = 2 // 禁止自动回复 -) - -const ( - ExdStoreName = "饿鲜达" - MatterStoreID = 666666 - JdShopMainVendorStoreID = "999999" - JdShopMainStoreID = 102919 - - VendorStoreTel = "18011597879" -) - -var ( - StoreStatusName = map[int]string{ - StoreStatusDisabled: "禁用", - StoreStatusClosed: "休息", - StoreStatusHaveRest: "临时休息", - StoreStatusOpened: "营业中", - } - DeliveryRangeTypeName = map[int]string{ - DeliveryRangeTypePolygon: "多边形", - DeliveryRangeTypeRadius: "圆", - } - DeliveryTypeName = map[int]string{ - StoreDeliveryTypeCrowdSourcing: "平台众包", - StoreDeliveryTypeByPlatform: "平台专送", - StoreDeliveryTypeByStore: "门店自送", - } - BankName = map[string]string{ - "CDB": "国家开发银行", - "ICBC": "中国工商银行", - "ABC": "中国农业银行", - "BOC": "中国银行", - "CCB": "中国建设银行", - "PSBC": "中国邮政储蓄银行", - "COMM": "交通银行", - "CMB": "招商银行", - "SPDB": "上海浦东发展银行", - "CIB": "兴业银行", - "HXBANK": "华夏银行", - "GDB": "广发银行", //0724 - "CMBC": "民生银行", - "CITIC": "中信银行", - "CEB": "光大银行", //0724 - "EGBANK": "恒丰银行", - "CZBANK": "浙商银行", - "BOHAIB": "渤海银行", - "SPABANK": "平安银行", - "SHRCB": "上海农村商业银行", - "YXCCB": "玉溪市商业银行", - "YDRCB": "尧都农商行", - "BJBANK": "北京银行", - "SHBANK": "上海银行", - "JSBANK": "江苏银行", - "HZCB": "杭州银行", - "NJCB": "南京银行", - "NBBANK": "宁波银行", - "HSBANK": "徽商银行", - "CSCB": "长沙银行", - "CDCB": "成都银行", - "CQBANK": "重庆银行", - "DLB": "大连银行", - "NCB": "南昌银行", - "FJHXBC": "福建海峡银行", - "HKB": "汉口银行", - "WZCB": "温州银行", - "QDCCB": "青岛银行", - "TZCB": "台州银行", - "JXBANK": "嘉兴银行", - "CSRCB": "常熟农村商业银行", - "NHB": "南海农村信用联社", - "CZRCB": "常州农村信用联社", - "H3CB": "内蒙古银行", - "SXCB": "绍兴银行", - "SDEB": "顺德农商银行", - "WJRCB": "吴江农商银行", - "ZBCB": "齐商银行", - "GYCB": "贵阳市商业银行", - "ZYCBANK": "遵义市商业银行", - "HZCCB": "湖州市商业银行", - "DAQINGB": "龙江银行", - "JINCHB": "晋城银行JCBANK", - "ZJTLCB": "浙江泰隆商业银行", - "GDRCC": "广东省农村信用社联合社", - "DRCBCL": "东莞农村商业银行", - "MTBANK": "浙江民泰商业银行", - "GCB": "广州银行", - "LYCB": "辽阳市商业银行", - "JSRCU": "江苏省农村信用联合社", - "LANGFB": "廊坊银行", - "CZCB": "浙江稠州商业银行", - "DYCB": "德阳商业银行", - "JZBANK": "晋中市商业银行", - "BOSZ": "苏州银行", - "GLBANK": "桂林银行", - "URMQCCB": "乌鲁木齐市商业银行", - "CDRCB": "成都农商银行", - "ZRCBANK": "张家港农村商业银行", - "BOD": "东莞银行", - "LSBANK": "莱商银行", - "BJRCB": "北京农村商业银行", - "TRCB": "天津农商银行", - "SRBANK": "上饶银行", - "FDB": "富滇银行", - "CRCBANK": "重庆农村商业银行", - "ASCB": "鞍山银行", - "NXBANK": "宁夏银行", - "BHB": "河北银行", - "HRXJB": "华融湘江银行", - "ZGCCB": "自贡市商业银行", - "YNRCC": "云南省农村信用社", - "JLBANK": "吉林银行", - "DYCCB": "东营市商业银行", - "KLB": "昆仑银行", - "ORBANK": "鄂尔多斯银行", - "XTB": "邢台银行", - "JSB": "晋商银行", - "TCCB": "天津银行", - "BOYK": "营口银行", - "JLRCU": "吉林农信", - "SDRCU": "山东农信", - "XABANK": "西安银行", - "HBRCU": "河北省农村信用社", - "NXRCU": "宁夏黄河农村商业银行", - "GZRCU": "贵州省农村信用社", - "FXCB": "阜新银行", - "HBHSBANK": "湖北银行黄石分行", - "ZJNX": "浙江省农村信用社联合社", - "XXBANK": "新乡银行", - "HBYCBANK": "湖北银行宜昌分行", - "LSCCB": "乐山市商业银行", - "TCRCB": "江苏太仓农村商业银行", - "BZMD": "驻马店银行", - "GZB": "赣州银行", - "WRCB": "无锡农村商业银行", - "BGB": "广西北部湾银行", - "GRCB": "广州农商银行", - "JRCB": "江苏江阴农村商业银行", - "BOP": "平顶山银行", - "TACCB": "泰安市商业银行", - "CGNB": "南充市商业银行", - "CCQTGB": "重庆三峡银行", - "XLBANK": "中山小榄村镇银行", - "HDBANK": "邯郸银行", - "KORLABANK": "库尔勒市商业银行", - "BOJZ": "锦州银行", - "QLBANK": "齐鲁银行", - "BOQH": "青海银行", - "YQCCB": "阳泉银行", - "SJBANK": "盛京银行", - "FSCB": "抚顺银行", - "ZZBANK": "郑州银行", - "SRCB": "深圳农村商业银行", - "BANKWF": "潍坊银行", - "JJBANK": "九江银行", - "JXRCU": "江西省农村信用", - "HNRCU": "河南省农村信用", - "GSRCU": "甘肃省农村信用", - "SCRCU": "四川省农村信用", - "GXRCU": "广西省农村信用", - "SXRCCU": "陕西信合", - "WHRCB": "武汉农村商业银行", - "YBCCB": "宜宾市商业银行", - "KSRB": "昆山农村商业银行", - "SZSBK": "石嘴山银行", - "HSBK": "衡水银行", - "XYBANK": "信阳银行", - "NBYZ": "鄞州银行", - "ZJKCCB": "张家口市商业银行", - "XCYH": "许昌银行", - "JNBANK": "济宁银行", - "CBKF": "开封市商业银行", - "WHCCB": "威海市商业银行", - "HBC": "湖北银行", - "BOCD": "承德银行", - "BODD": "丹东银行", - "JHBANK": "金华银行", - "BOCY": "朝阳银行", - "LSBC": "临商银行", - "BSB": "包商银行", - "LZYH": "兰州银行", - "BOZK": "周口银行", - "DZBANK": "德州银行", - "SCCB": "三门峡银行", - "AYCB": "安阳银行", - "ARCU": "安徽省农村信用社", - "HURCB": "湖北省农村信用社", - "HNRCC": "湖南省农村信用社", - "NYNB": "广东南粤银行", - "LYBANK": "洛阳银行", - "NHQS": "农信银清算中心", - "CBBQS": "城市商业银行资金清算中心", - } - StoreAuditStatusName = map[int]string{ - StoreAuditStatusCreated: "待审核", - StoreAuditStatusOnline: "上线", - StoreAuditStatusRejected: "拒绝", - } - StorePriceTypeName = map[int]string{ - StoreChangePriceTypeDirect: "普通门店", - StoreChangePriceTypeBossDisabled: "普通门店禁止改价", - StoreChangePriceTypeManagedStore: "直营门店禁止改价", - } - AutoReplyTypeName = map[int]string{ - AutoReplyAll: "全部自动回复", - AutoReplyGoodComment: "禁止差评自动回复", - AutoReplyDisabled: "禁止自动回复", - } -) - -type Store struct { - ModelIDCULD - - OriginalName string `orm:"-" json:"originalName"` - Name string `orm:"size(255)" json:"name"` - CityCode int `orm:"default(0);null" json:"cityCode"` // todo ? - DistrictCode int `orm:"default(0);null" json:"districtCode"` // todo ? - Address string `orm:"size(255)" json:"address"` - Tel1 string `orm:"size(32);index" json:"tel1"` - Tel2 string `orm:"size(32);index" json:"tel2"` - OpenTime1 int16 `json:"openTime1" validate:"max=2359,min=1,ltfield=CloseTime1"` // 930就表示9点半,用两个的原因是为了支持中午休息,1与2的时间段不能交叉,为0表示没有 - CloseTime1 int16 `json:"closeTime1" validate:"max=2359,min=1` // 格式同上 - OpenTime2 int16 `json:"openTime2" validate:"max=2359,min=1,ltfield=CloseTime2"` // 格式同上 - CloseTime2 int16 `json:"closeTime2" validate:"max=2359,min=1` // 格式同上 - Lng int `json:"-"` // 乘了10的6次方 - Lat int `json:"-"` // 乘了10的6次方 - DeliveryRangeType int8 `json:"deliveryRangeType"` // 参见相关常量定义 - DeliveryRange string `orm:"type(text)" json:"deliveryRange"` // 如果DeliveryRangeType为DeliveryRangeTypePolygon,则为逗号分隔坐标,分号分隔的坐标点(坐标与Lng和Lat一样,都是整数),比如 121361504,31189308;121420555,31150238。否则为半径,单位为米 - Status int `json:"status"` - AutoEnableAt *time.Time `orm:"type(datetime);null" json:"autoEnableAt"` // 自动营业时间(临时休息用) - ChangePriceType int8 `json:"changePriceType"` // 修改价格类型,即是否需要审核 - SMSNotify int8 `orm:"column(sms_notify);" json:"smsNotify"` // 是否通过短信接收订单消息(每天只推一条) - SMSNotifyMark int8 `orm:"column(sms_notify_mark);" json:"smsNotifyMark"` //今天是否已经推送过订单消息 - AutoReplyType int8 `json:"autoReplyType"` // 订单评价自动回复类型 - LinkStoreID int `orm:"column(link_store_id);default(0);index" json:"linkStoreID"` // 关联门店ID - StoreLevel string `orm:"default(C);size(32)" json:"storeLevel"` // 门店等级(筛选用,京西的) - - PrinterDisabled int8 `orm:"default(0)" json:"printerDisabled"` // 是否禁用网络打印机 - PrinterFontSize int8 `orm:"default(0)" json:"printerFontSize"` // 打印字体-1:小,0:正常,1:大 - PrinterVendorID int `orm:"column(printer_vendor_id);" json:"printerVendorID"` - PrinterSN string `orm:"size(32);column(printer_sn);index" json:"printerSN"` - PrinterKey string `orm:"size(64)" json:"printerKey"` - PrinterBindInfo string `orm:"size(1024)" json:"-"` - - IDCardFront string `orm:"size(255);column(id_card_front)" json:"idCardFront"` - IDCardBack string `orm:"size(255);column(id_card_back)" json:"idCardBack"` - IDCardHand string `orm:"size(255);column(id_card_hand)" json:"idCardHand"` - Licence string `orm:"size(255)" json:"licence"` // 营业执照图片 - LicenceCode string `orm:"size(32)" json:"licenceCode"` - - LicenceType int8 `json:"licenceType"` // 营业执照类型,0:个人,1:公司 - LicenceCorpName string `orm:"size(64)" json:"licenceCorpName"` // 营业执照公司名称 - LicenceOwnerName string `orm:"size(8)" json:"licenceOwnerName"` // 法人姓名 - LicenceAddress string `orm:"size(255)" json:"licenceAddress"` // 地址 - LicenceValid string `orm:"size(32)" json:"licenceValid"` // 有效期开始 - LicenceExpire string `orm:"size(32)" json:"licenceExpire"` // 有效期结束 - - IDName string `orm:"size(8);column(id_name)" json:"idName"` // 身份证姓名 - IDCode string `orm:"size(32);column(id_code)" json:"idCode"` // 身份证号 - IDValid string `orm:"column(id_valid);size(32)" json:"idValid"` // 有效期开始 - IDExpire string `orm:"column(id_expire);size(32)" json:"idExpire"` // 有效期结束 - - Licence2Image string `orm:"size(255)" json:"licence2Image"` // 食品经营许可证 - Licence2Code string `orm:"size(32)" json:"licence2Code"` // 食品经营许可证编号 - Licence2Valid string `orm:"size(32)" json:"licence2Valid"` // 有效期开始 - Licence2Expire string `orm:"size(32)" json:"licence2Expire"` // 有效期结束 - - // MarketManName string `orm:"size(8)" json:"marketManName"` // 市场负责人姓名 - MarketManPhone string `orm:"size(16)" json:"marketManPhone"` // 市场负责人电话 - MarketManRole string `orm:"size(32)" json:"marketManRole"` // 市场负责人组(角色,单人) - - JxBrandFeeFactor int `json:"jxBrandFeeFactor"` // 京西品牌费因子 - MarketAddFeeFactor int `json:"marketAddFeeFactor"` // 市场附加费因子 - - PayeeName string `orm:"size(8)" json:"payeeName"` // 收款人姓名 - PayeeAccountNo string `orm:"size(255)" json:"payeeAccountNo"` // 收款账号 - PayeeBankBranchName string `orm:"size(255)" json:"payeeBankBranchName"` // 开户支行 - PayeeBankCode string `orm:"size(8)" json:"payeeBankCode"` // 开户行代码 - PayPercentage int `json:"payPercentage"` - OldPayPercentage int `json:"oldPayPercentage"` - - // OperatorName string `orm:"size(8)" json:"operatorName"` // 运营人姓名 - OperatorPhone string `orm:"size(16)" json:"operatorPhone"` // 京东运营人电话 - OperatorRole string `orm:"size(32)" json:"operatorRole"` // 京东运营人组(角色) - - OperatorPhone2 string `orm:"size(16)" json:"operatorPhone2"` // 美团运营人电话 - OperatorRole2 string `orm:"size(32)" json:"operatorRole2"` // 美团运营人组(角色) - - OperatorPhone3 string `orm:"size(16)" json:"operatorPhone3"` // 饿百运营人电话 - OperatorRole3 string `orm:"size(32)" json:"operatorRole3"` // 饿百运营人组(角色) - - PromoteInfo string `orm:"size(255)" json:"promoteInfo"` //门店公告(所有平台统一的公告) - IsBoughtMatter int `json:"isBoughtMatter"` //这周是否申请过物料 - SoundPercentage int `json:"soundPercentage"` //打印机声音大小比例 - Banner string `orm:"size(9999)" json:"banner"` //门店商城bannar图 -} - -func (*Store) TableUnique() [][]string { - return [][]string{ - []string{"Name", "DeletedAt"}, - } -} - -func (*Store) TableIndex() [][]string { - return [][]string{ - []string{"Lng", "Lat"}, - } -} - -func (s *Store) IsPrinterDisabled() bool { - return s.PrinterDisabled == 1 -} - -func (s *Store) GetOpTimeList() (opTimeList []int16) { - opTimeList = []int16{s.OpenTime1, s.CloseTime1} - if s.OpenTime2 != 0 { - opTimeList = append(opTimeList, s.OpenTime2, s.CloseTime2) - } - return opTimeList -} - -func (s *Store) SetOpTime(opTimeList []int16) { - if len(opTimeList) >= 2 { - s.OpenTime1, s.CloseTime1 = opTimeList[0], opTimeList[1] - if len(opTimeList) >= 4 { - s.OpenTime2, s.CloseTime2 = opTimeList[2], opTimeList[3] - } - } -} - -type StoreSub struct { - ModelIDCULD - - StoreID int `orm:"column(store_id)"` - Index int // 子店序号,为0表示主店 - Name string `orm:"size(255);index"` - Address string `orm:"size(255)"` - Status int // 取值同Store.Status - Mobile1 string `orm:"size(32)"` - Mobile2 string `orm:"size(32)"` - Mobile3 string `orm:"size(32)"` -} - -func (*StoreSub) TableUnique() [][]string { - return [][]string{ - []string{"StoreID", "Index", "DeletedAt"}, - } -} - -type StoreMap struct { - ModelIDCULD - - StoreID int `orm:"column(store_id)" json:"storeID"` - VendorID int `orm:"column(vendor_id)" json:"vendorID"` - VendorOrgCode string `orm:"size(32)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空 - - VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"` - Status int `json:"status"` // 取值同Store.Status - StoreName string `orm:"size(255)" json:"storeName"` // 平台门店的名字,由平台到京西 - VendorStoreName string `orm:"size(255)" json:"vendorStoreName"` //平台门店名,由京西到平台 - - PricePercentage int16 `orm:"default(100)" json:"pricePercentage"` // todo 厂商价格相对于本地价格的百分比,这个字段的修改会比较特殊,因为可能需要刷新厂商价格 - PricePercentagePack string `orm:"size(32)" json:"pricePercentagePack"` // - - FreightDeductionPack string `orm:"size(32)" json:"freightDeductionPack"` // - - AutoPickup int8 `orm:"default(1)" json:"autoPickup"` // 是否自动拣货 - DeliveryType int8 `orm:"default(0)" json:"deliveryType"` // 配送类型 - DeliveryFeeDeductionSill int `json:"deliveryFeeDeductionSill"` - DeliveryFeeDeductionFee int `json:"deliveryFeeDeductionFee"` - DeliveryCompetition int8 `orm:"default(1)" json:"deliveryCompetition"` // 是否支持配送竞争 - - SyncStatus int8 `orm:"default(2)" json:"syncStatus"` - IsSync int8 `orm:"default(1)" json:"isSync"` // 是否同步 - SyncRule int8 `orm:"default(0)" json:"syncRule"` //目前用于京东商城晚上的同步规则,0表示关闭,1表示小同步,2表示大同步 - FakeOpenStart int16 `orm:"default(0)" json:"fakeOpenStart"` // 假开店开始 - FakeOpenStop int16 `orm:"default(0)" json:"fakeOpenStop"` // 假开店结束 - JdStoreLevel string `orm:"size(32)" json:"jdStoreLevel"` //京东门店等级 - JdsStreetCode int `orm:"default(0)" json:"jdsStreetCode"` //京东商城直辖市街道code - JdsStreetName string `orm:"size(32)" json:"jdsStreetName"` //京东商城直辖市街道 - - IsOrder int `orm:"default(0)" json:"isOrder"` //是否是下预订单门店 - IsSysCat int `orm:"default(0)" json:"isSysCat"` //是否使用京西分类 - IsSupplyGoods int `orm:"default(0)" json:"isSupplyGoods"` // 是否是货源门店 - - YbAppID string `orm:"column(yb_app_id);size(255)" json:"ybAppID"` - YbAppKey string `orm:"size(255)" json:"ybAppKey"` - YbStorePrefix string `orm:"size(255)" json:"ybStorePrefix"` -} - -func (*StoreMap) TableUnique() [][]string { - return [][]string{ - []string{"StoreID", "VendorID", "DeletedAt"}, - []string{"VendorStoreID", "VendorID", "DeletedAt"}, - } -} - -type StoreCourierMap struct { - ModelIDCULD - - StoreID int `orm:"column(store_id)" json:"storeID"` - VendorID int `orm:"column(vendor_id)" json:"vendorID"` - VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"` - Status int `json:"status"` - AuditStatus int `json:"auditStatus"` - VendorStatus int `json:"vendorStatus"` - // 以下数据仅用于同步使用 - Lng int `json:"-"` // 乘了10的6次方 - Lat int `json:"-"` // 乘了10的6次方 - Remark string `orm:"size(255)" json:"-"` -} - -func (*StoreCourierMap) TableUnique() [][]string { - return [][]string{ - []string{"StoreID", "VendorID", "DeletedAt"}, - } -} - -func (*StoreCourierMap) TableIndex() [][]string { - return [][]string{ - []string{"VendorStoreID", "VendorID", "DeletedAt"}, - } -} - -type PriceReferSnapshot struct { - ModelIDCULD - SnapshotAt time.Time `orm:"type(datetime)" json:"snapshotAt"` // 这个不同于CreatedAt,SnapshotAt是逻辑上的时间,CreatedAt是实际存储的时间 - CityCode int `json:"cityCode"` - SkuID int `orm:"column(sku_id)" json:"skuId"` - NameID int `orm:"column(name_id)" json:"nameID"` - MaxPrice int `json:"maxPrice"` - MinPrice int `json:"minPrice"` - AvgPrice int `json:"avgPrice"` - MidPrice int `json:"midPrice"` - MaxUnitPrice int `json:"maxUnitPrice"` - MinUnitPrice int `json:"minUnitPrice"` - AvgUnitPrice int `json:"avgUnitPrice"` - MidUnitPrice int `json:"midUnitPrice"` - MaxJdPrice int `json:"maxJdPrice"` - MinJdPrice int `json:"minJdPrice"` - AvgJdPrice int `json:"avgJdPrice"` - MidJdPrice int `json:"midJdPrice"` - MaxEbaiPrice int `json:"maxEbaiPrice"` - MinEbaiPrice int `json:"minEbaiPrice"` - AvgEbaiPrice int `json:"avgEbaiPrice"` - MidEbaiPrice int `json:"midEbaiPrice"` - MaxMtwmPrice int `json:"maxMtwmPrice"` - MinMtwmPrice int `json:"minMtwmPrice"` - AvgMtwmPrice int `json:"avgMtwmPrice"` - MidMtwmPrice int `json:"midMtwmPrice"` - MaxSalePrice int `json:"maxSalePrice"` - MinSalePrice int `json:"minSalePrice"` - AvgSalePrice int `json:"avgSalePrice"` - MaxVendorPrice int `json:"maxVendorPrice"` - MinVendorPrice int `json:"minVendorPrice"` - AvgVendorPrice int `json:"avgVendorPrice"` - JdDirectPrice int `json:"jdDirectPrice"` -} - -func (*PriceReferSnapshot) TableUnique() [][]string { - return [][]string{ - []string{"CityCode", "NameID", "SkuID", "SnapshotAt"}, - } -} - -func (*PriceReferSnapshot) TableIndex() [][]string { - return [][]string{ - []string{"CityCode", "SnapshotAt", "SkuID"}, - } -} - -type StorePriceScoreSnapshot struct { - ModelIDCULD - SnapshotAt time.Time `orm:"type(datetime)" json:"snapshotAt"` // 这个不同于CreatedAt,SnapshotAt是逻辑上的时间,CreatedAt是实际存储的时间 - StoreID int `orm:"column(store_id)" json:"storeID"` - Score float64 `json:"score"` -} - -func (*StorePriceScoreSnapshot) TableUnique() [][]string { - return [][]string{ - []string{"StoreID", "Score", "SnapshotAt"}, - } -} - -func (*StorePriceScoreSnapshot) TableIndex() [][]string { - return [][]string{ - []string{"SnapshotAt"}, - } -} - -type StoreSkuNamePrice struct { - ModelIDCULD - OutSkuID string `orm:"column(out_sku_id)" json:"outSkuID"` - Name string `json:"name"` - Price int `json:"price"` - Unit string `json:"unit"` - NameIDGroup string `orm:"column(name_id_group)" json:"nameIDGroup"` -} - -func (*StoreSkuNamePrice) TableUnique() [][]string { - return [][]string{ - []string{"OutSkuID", "Price", "NameIDGroup"}, - } -} - -func (*StoreSkuNamePrice) TableIndex() [][]string { - return [][]string{ - []string{"OutSkuID"}, - } -} - -type VendorStoreSnapshot struct { - ModelIDCULD - - VendorOrgCode string `orm:"size(32)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空 - StoreID int `orm:"column(store_id)" json:"storeID"` - VendorID int `orm:"column(vendor_id)" json:"vendorID"` - VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"` - SnapshotAt time.Time `orm:"type(datetime)" json:"snapshotAt"` // 这个不同于CreatedAt,SnapshotAt是逻辑上的时间,CreatedAt是实际存储的时间 - - Status int `json:"status"` // 取值同Store.Status - OpenTime1 int16 `json:"openTime1"` // 930就表示9点半,用两个的原因是为了支持中午休息,1与2的时间段不能交叉,为0表示没有 - CloseTime1 int16 `json:"closeTime1"` // 格式同上 - OpenTime2 int16 `json:"openTime2"` // 格式同上 - CloseTime2 int16 `json:"closeTime2"` // 格式同上 - DeliveryType int8 `orm:"default(0)" json:"deliveryType"` // 配送类型 - StoreName string `orm:"size(255)" json:"storeName"` // 平台门店的名字 - IsAutoOrder int8 `json:"isAutoOrder"` // 平台是否自动接单,-1:否,0:未知,1:是 - JdStoreLevel string `orm:"size(32)" json:"jdStoreLevel"` //京东门店等级 -} - -func (*VendorStoreSnapshot) TableUnique() [][]string { - return [][]string{ - []string{"VendorStoreID", "VendorID", "SnapshotAt"}, - } -} - -func (*VendorStoreSnapshot) TableIndex() [][]string { - return [][]string{ - []string{"SnapshotAt"}, - } -} - -func (v *VendorStoreSnapshot) GenMapKey() string { - return v.VendorStoreID + utils.Int2Str(v.VendorID) -} - -func (v *VendorStoreSnapshot) CompareOperationTime(s2 *VendorStoreSnapshot) int { - if s2 == nil { - return 1 - } - if v.OpenTime1 == s2.OpenTime1 && v.CloseTime1 == s2.CloseTime1 && - v.OpenTime2 == s2.OpenTime2 && v.CloseTime2 == s2.CloseTime2 { - return 0 - } else if v.OpenTime1 > s2.OpenTime1 || v.CloseTime1 < s2.CloseTime2 { - return -1 - } - return 1 -} - -type PricePercentageItem struct { - BeginPrice int `json:"beginPrice"` // 起始价格区间(包括) - PricePercentage int `json:"pricePercentage"` // 调价比例 - PriceAdd int `json:"priceAdd"` // 调价额定值 -} - -type PricePercentagePack []*PricePercentageItem - -func (l PricePercentagePack) Len() int { - return len(l) -} - -// Less reports whether the element with -// index i should sort before the element with index j. -func (l PricePercentagePack) Less(i, j int) bool { - return l[i].BeginPrice < l[j].BeginPrice -} - -// Swap swaps the elements with indexes i and j. -func (l PricePercentagePack) Swap(i, j int) { - tmp := l[i] - l[i] = l[j] - l[j] = tmp -} - -type FreightDeductionItem struct { - BeginPrice int `json:"beginPrice"` // 起始价格区间(包括) - DeductFreight int `json:"deductFreight"` // 减免运费 -} - -type FreightDeductionPack struct { - StartPrice int `json:"startPrice"` // 起送价 - FreightDeductionList []*FreightDeductionItem `json:"freightDeductionList"` -} - -func (l *FreightDeductionPack) Len() int { - return len(l.FreightDeductionList) -} - -// Less reports whether the element with -// index i should sort before the element with index j. -func (l *FreightDeductionPack) Less(i, j int) bool { - return l.FreightDeductionList[i].BeginPrice < l.FreightDeductionList[j].BeginPrice -} - -// Swap swaps the elements with indexes i and j. -func (l *FreightDeductionPack) Swap(i, j int) { - l2 := l.FreightDeductionList - tmp := l2[i] - l2[i] = l2[j] - l2[j] = tmp -} - -type StoreCategoryMap struct { - ModelIDCULD - StoreID int `orm:"column(store_id)" json:"storeID"` - CategoryID int `orm:"column(category_id)" json:"categoryID"` // 这个是指对应的sku_category - StoreCategoryName string `orm:"size(255)" json:"storeCategoryName"` // 门店类别单独的名字 - StoreCategorySeq int `orm:"default(0)" json:"storeCategorySeq"` // 门店类别单独的序号 - Level int `json:"level"` // 门店类别单独的等级 - ParentID int `orm:"column(parent_id)" json:"parentID"` //门店类别父ID,和sku_category一致 -} - -func (*StoreCategoryMap) TableUnique() [][]string { - return [][]string{ - []string{"StoreID", "CategoryID", "DeletedAt"}, - } -} - -type StorePushClient struct { - ModelIDCULD - StoreID int `orm:"column(store_id)" json:"storeID"` - ClientID string `orm:"column(client_id);size(255)" json:"clientID"` -} - -func (*StorePushClient) TableUnique() [][]string { - return [][]string{ - []string{"StoreID", "ClientID"}, - } -} - -type StoreAudit struct { - ModelIDCULD - - Name string `orm:"size(255)" json:"name"` - CityCode int `orm:"default(0);null" json:"cityCode"` // todo ? - DistrictCode int `orm:"default(0);null" json:"districtCode"` // todo ? - Address string `orm:"size(255)" json:"address"` - Tel1 string `orm:"size(32);index" json:"tel1"` - Tel2 string `orm:"size(32);index" json:"tel2"` - OpenTime1 int16 `json:"openTime1" validate:"max=2359,min=1,ltfield=CloseTime1"` // 930就表示9点半,用两个的原因是为了支持中午休息,1与2的时间段不能交叉,为0表示没有 - CloseTime1 int16 `json:"closeTime1" validate:"max=2359,min=1` // 格式同上 - OpenTime2 int16 `json:"openTime2" validate:"max=2359,min=1,ltfield=CloseTime2"` // 格式同上 - CloseTime2 int16 `json:"closeTime2" validate:"max=2359,min=1` // 格式同上 - Lng int `json:"lng"` // 乘了10的6次方 - Lat int `json:"lat"` // 乘了10的6次方 - DeliveryRangeType int8 `json:"deliveryRangeType"` // 参见相关常量定义 - DeliveryRange string `orm:"type(text)" json:"deliveryRange"` // 如果DeliveryRangeType为DeliveryRangeTypePolygon,则为逗号分隔坐标,分号分隔的坐标点(坐标与Lng和Lat一样,都是整数),比如 121361504,31189308;121420555,31150238。否则为半径,单位为米 - Status int `json:"status"` - SMSNotify int8 `orm:"column(sms_notify);" json:"smsNotify"` // 是否通过短信接收订单消息(每天只推一条) - - IDCardFront string `orm:"size(255);column(id_card_front)" json:"idCardFront"` - IDCardBack string `orm:"size(255);column(id_card_back)" json:"idCardBack"` - IDCardHand string `orm:"size(255);column(id_card_hand)" json:"idCardHand"` - Licence string `orm:"size(255)" json:"licence"` // 营业执照图片 - LicenceCode string `orm:"size(32)" json:"licenceCode"` - - LicenceType int8 `json:"licenceType"` // 营业执照类型,0:个人,1:公司 - LicenceCorpName string `orm:"size(64)" json:"licenceCorpName"` // 营业执照公司名称 - LicenceOwnerName string `orm:"size(8)" json:"licenceOwnerName"` // 法人姓名 - LicenceAddress string `orm:"size(255)" json:"licenceAddress"` // 地址 - LicenceValid string `orm:"size(32)" json:"licenceValid"` // 有效期开始 - LicenceExpire string `orm:"size(32)" json:"licenceExpire"` // 有效期结束 - - IDName string `orm:"size(8);column(id_name)" json:"idName"` // 身份证姓名 - IDCode string `orm:"size(32);column(id_code)" json:"idCode"` // 身份证号 - IDValid string `orm:"column(id_valid);size(32)" json:"idValid"` // 有效期开始 - IDExpire string `orm:"column(id_expire);size(32)" json:"idExpire"` // 有效期结束 - - Licence2Image string `orm:"size(255)" json:"licence2Image"` // 食品经营许可证 - Licence2Code string `orm:"size(32)" json:"licence2Code"` // 食品经营许可证编号 - Licence2Valid string `orm:"size(32)" json:"licence2Valid"` // 有效期开始 - Licence2Expire string `orm:"size(32)" json:"licence2Expire"` // 有效期结束 - - UserID string `orm:"column(user_id);size(32)" json:"userID"` //谁发起的审核就把谁添加到这个门店里 - AuditStatus int `json:"auditStatus"` //0是待审核,1是通过,-1是不通过 - Remark string `orm:"size(255)" json:"remark"` //不通过原因 -} - -func (*StoreAudit) TableUnique() [][]string { - return [][]string{ - []string{"Name"}, - } -} - -func (*StoreAudit) TableIndex() [][]string { - return [][]string{ - []string{"UserID"}, - } -} diff --git a/business/model/store_score.go b/business/model/store_score.go deleted file mode 100644 index b9e10857a..000000000 --- a/business/model/store_score.go +++ /dev/null @@ -1,72 +0,0 @@ -package model - -import "time" - -const ( - FieldStoreOpenTime = "StoreOpenTime" - FieldSaleSkuCount = "SaleSkuCount" - FieldAveragePickupTime = "AveragePickupTime" - FieldBadCommentOrder = "BadCommentOrder" - FieldUnfinishOrder = "UnfinishOrder" - FieldAbsentGoodsOrder = "AbsentGoodsOrder" - FieldPromotionSku = "PromotionSku" - FieldFullVendor = "FullVendor" - FieldStoreRange = "StoreRange" - FieldSaleSkuPrice = "SaleSkuPrice" - - FieldTotalScore = "TotalScore" -) - -type StoreScore struct { - ID int `orm:"column(id)" json:"id"` - CreatedAt time.Time `orm:"auto_now_add;type(datetime)" json:"createdAt"` - ScoreDate time.Time `orm:"auto_now_add;type(datetime)" json:"scoreDate"` - StoreID int `orm:"column(store_id)" json:"storeID"` - - StoreOpenTime int `orm:"column(store_open_time)" json:"storeOpenTime"` - SaleSkuCount int `orm:"column(sale_sku_count)" json:"saleSkuCount"` - AveragePickupTime int `orm:"column(average_pickup_time)" json:"averagePickupTime"` - BadCommentOrder int `orm:"column(bad_comment_order)" json:"badCommentOrder"` - UnfinishOrder int `orm:"column(unfinish_order)" json:"unfinishOrder"` - AbsentGoodsOrder int `orm:"column(absent_Goods_order)" json:"absentGoodsOrder"` - PromotionSku int `orm:"column(promotion_sku)" json:"promotionSku"` - FullVendor int `orm:"column(full_vendor)" json:"fullVendor"` - StoreRange int `orm:"column(store_range)" json:"storeRange"` - SaleSkuPrice int `orm:"column(sale_sku_price)" json:"saleSkuPrice"` -} - -type StoreScoreEx struct { - StoreScore - StoreName string `json:"storeName"` -} - -type WeeklyStoreScore struct { - StoreScoreEx - BeginTime time.Time `json:"beginTime"` - EndTime time.Time `json:"endTime"` - TotalScore int `json:"totalScore"` - ItemTotalScore int `json:"itemTotalScore"` - Level int `json:"level"` -} - -type StoreTotalScore struct { - StoreID int `orm:"column(store_id)" json:"storeID"` - StoreName string `orm:"column(store_name)" json:"storeName"` - StoreScore int `orm:"column(store_score)" json:"storeScore"` - CityName string `orm:"column(city_name)" json:"cityName"` -} - -type StoreTotalScoreEx struct { - StoreTotalScoreList []*StoreTotalScore `json:"storeTotalScoreList"` - TotalCount int `json:"totalCount"` -} - -type StoreCount struct { - StoreID int `orm:"column(store_id)"` - Count int -} - -type OrderPickupTime struct { - StatusTime time.Time - PickDeadline time.Time -} diff --git a/business/model/store_sku.go b/business/model/store_sku.go deleted file mode 100644 index 9b924990e..000000000 --- a/business/model/store_sku.go +++ /dev/null @@ -1,215 +0,0 @@ -package model - -import "time" - -const ( - StoreSkuBindStatusNA = -2 - StoreSkuBindStatusDeleted = -1 - StoreSkuBindStatusDontSale = 0 - StoreSkuBindStatusNormal = 1 -) - -const ( - MaxStoreSkuStockQty = 99999 -) - -const ( - RequestTypeChangePrice = 1 - RequestTypeFocusSkuName = 2 -) - -const ( - RequestStatusNew = 0 - RequestStatusRejected = -1 - RequestStatusAccepted = 1 - RequestStatusCanceled = 3 -) - -var ( - RequestTypeName = map[int]string{ - RequestTypeChangePrice: "更改价格", - RequestTypeFocusSkuName: "关注商品", - } - RequestStatusName = map[int]string{ - RequestStatusNew: "待审核", - RequestStatusRejected: "拒绝", - RequestStatusAccepted: "已批准", - } -) - -type StoreSkuCategoryMap struct { - ModelIDCULD - - StoreID int `orm:"column(store_id)"` - CategoryID int `orm:"column(category_id)"` - - // ElmID int64 `orm:"column(elm_id);index"` - EbaiID int64 `orm:"column(ebai_id);index"` - MtwmID string `orm:"column(mtwm_id);index;size(16)"` - // WscID int64 `orm:"column(wsc_id);index"` - - // ElmSyncStatus int8 `orm:"default(2)"` - EbaiSyncStatus int8 `orm:"default(2)"` - MtwmSyncStatus int8 `orm:"default(2)"` - // WscSyncStatus int8 `orm:"default(2)"` - YbID int64 `orm:"column(yb_id);index"` - YbSyncStatus int8 `orm:"default(2)"` - JdsID int64 `orm:"column(jds_id);index"` - JdsSyncStatus int8 `orm:"default(2)"` -} - -func (*StoreSkuCategoryMap) TableUnique() [][]string { - return [][]string{ - []string{"StoreID", "CategoryID", "DeletedAt"}, - } -} - -func (*StoreSkuCategoryMap) TableIndex() [][]string { - return [][]string{ - []string{"CategoryID", "StoreID", "DeletedAt"}, - } -} - -// type StoreSkuCategoryMap2 struct { -// ModelIDCULD - -// StoreID int `orm:"column(store_id)"` -// VendorID int `orm:"column(vendor_id)"` -// CategoryID int `orm:"column(category_id)"` - -// VendorCatID string `orm:"column(vendor_cat_id);size(48)" json:"vendorCatID"` -// SyncStatus int8 `orm:"default(2)"` -// } - -// func (*StoreSkuCategoryMap2) TableUnique() [][]string { -// return [][]string{ -// []string{"StoreID", "VendorID", "CategoryID", "DeletedAt"}, -// } -// } - -type StoreSkuBind struct { - ModelIDCULD - - StoreID int `orm:"column(store_id)"` - SkuID int `orm:"column(sku_id)"` - SubStoreID int `orm:"column(sub_store_id)"` - Price int // 单位为分,不用int64的原因是这里不需要累加 - UnitPrice int // 这个是一斤的门店商品价,放在这里的原因是避免额外增加一张store sku_name表,逻辑上要保证同一SKU NAME中的所有SKU这个字段的数据一致 - Stock int `json:"stock"` //门店商品库存 - Status int - - // ElmID int64 `orm:"column(elm_id);index"` - MtwmID int64 `orm:"column(mtwm_id);index"` - EbaiID int64 `orm:"column(ebai_id);index"` - YbID int64 `orm:"column(yb_id);index"` - JdsID int64 `orm:"column(jds_id);index"` - JdsWareID int64 `orm:"column(jds_ware_id)"` - // WscID int64 `orm:"column(wsc_id);index"` // 表示微盟skuId - // WscID2 int64 `orm:"column(wsc_id2);index"` // 表示微盟goodsId - - // ElmSyncStatus int8 `orm:"default(2)"` - JdSyncStatus int8 `orm:"default(2)"` - MtwmSyncStatus int8 `orm:"default(2)"` - EbaiSyncStatus int8 `orm:"default(2)"` - YbSyncStatus int8 `orm:"default(2)"` - JdsSyncStatus int8 `orm:"default(2)"` //京东商城 - // WscSyncStatus int8 `orm:"default(2)"` - - JdPrice int `json:"jdPrice"` - MtwmPrice int `json:"mtwmPrice"` - EbaiPrice int `json:"ebaiPrice"` - JxPrice int `json:"jxPrice"` - YbPrice int `json:"ybPrice"` - JdsPrice int `json:"jdsPrice"` - - JdLockTime *time.Time `orm:"null" json:"jdLockTime"` - JdsLockTime *time.Time `orm:"null" json:"jdsLockTime"` - MtwmLockTime *time.Time `orm:"null" json:"mtwmLockTime"` - EbaiLockTime *time.Time `orm:"null" json:"ebaiLockTime"` - JxLockTime *time.Time `orm:"null" json:"jxLockTime"` - YbLockTime *time.Time `orm:"null" json:"ybLockTime"` - - AutoSaleAt time.Time `orm:"type(datetime);null" json:"autoSaleAt"` - - StatusSaleBegin int16 //商品可售时间范围 - StatusSaleEnd int16 -} - -func (*StoreSkuBind) TableUnique() [][]string { - return [][]string{ - []string{"StoreID", "SkuID", "DeletedAt"}, - } -} - -func (*StoreSkuBind) TableIndex() [][]string { - return [][]string{ - []string{"SkuID", "StoreID", "DeletedAt"}, - // []string{"AutoSaleAt", "DeletedAt", "StoreID"}, - } -} - -type StoreSkuBindHistory struct { - StoreSkuBind - StoreSkuBindID int `orm:"column(store_sku_bind_id)"` - SnapshotAt time.Time `orm:"type(datetime);null;index" json:"snapshotAt"` -} - -func (*StoreSkuBindHistory) TableUnique() [][]string { - return [][]string{ - []string{"StoreID", "SkuID", "DeletedAt", "SnapshotAt"}, - } -} - -func (*StoreSkuBindHistory) TableIndex() [][]string { - return [][]string{ - []string{"SkuID", "StoreID", "DeletedAt"}, - } -} - -type StoreOpRequest struct { - ModelIDCULD // DeletedAt用于表示请求操作结束,而并不一定是删除 - - Type int8 `json:"type"` - StoreID int `orm:"column(store_id)" json:"storeID"` - ItemID int `orm:"column(item_id)" json:"itemID"` // 这个根据type不同,可能是SKUNAME ID或SKU ID - Status int8 `json:"status"` - UserID string `orm:"size(48);column(user_id)" json:"userID"` - IntParam0 int `json:"intParam0"` // 表示原价 - IntParam1 int `json:"intParam1"` - IntParam2 int `json:"intParam2"` - JsonParam string `orm:"size(3000)" json:"jsonParam"` - Remark string `orm:"size(255)" json:"remark"` -} - -func (*StoreOpRequest) TableUnique() [][]string { - return [][]string{ - []string{"StoreID", "Type", "ItemID", "DeletedAt"}, - } -} - -func (*StoreOpRequest) TableIndex() [][]string { - return [][]string{ - []string{"DeletedAt"}, - []string{"StoreID", "Status", "Type"}, - } -} - -type StoreSkuAudit struct { - ModelIDCULD // DeletedAt用于表示请求操作结束,而并不一定是删除 - - Type int8 `json:"type"` //1为改价 - StoreID int `orm:"column(store_id)" json:"storeID"` - NameID int `orm:"column(name_id)" json:"nameID"` // 这个根据type不同,可能是SKUNAME ID或SKU ID - Status int8 `json:"status"` // - UserID string `orm:"size(48);column(user_id)" json:"userID"` - OriginUnitPrice int `json:"originPrice"` // 表示原价 - UnitPrice int `json:"unitPrice"` //老板申请的审核价格 - AuditPrice int `json:"auditPrice"` //运营录入的审核价格 - Remark string `orm:"size(255)" json:"remark"` -} - -func (*StoreSkuAudit) TableIndex() [][]string { - return [][]string{ - []string{"StoreID", "Type", "NameID", "Status", "DeletedAt"}, - } -} diff --git a/business/model/store_sku_sales.go b/business/model/store_sku_sales.go deleted file mode 100644 index 2f6bc3bba..000000000 --- a/business/model/store_sku_sales.go +++ /dev/null @@ -1,17 +0,0 @@ -package model - -type StoreSkuSales struct { - SkuID int `json:"skuID"` - SkuName string `json:"skuName"` - SkuImage string `json:"skuImage"` - SkuPrice string `json:"skuPrice"` - SkuAvgPrice string `json:"skuAvgPrice"` - BadCommentCnt int `json:"badCommentCnt"` - StoreSkuSalesCnt int `json:"storeSkuSalesCnt"` - CitySkuSalesCnt int `json:"citySkuSalesCnt"` -} - -type SkuCount struct { - SkuID int `orm:"column(sku_id)"` - Count int -} diff --git a/business/model/sync_map.go b/business/model/sync_map.go deleted file mode 100644 index 6fc3a7d09..000000000 --- a/business/model/sync_map.go +++ /dev/null @@ -1,31 +0,0 @@ -package model - -const ( - ThingTypeCategory = 1 - ThingTypeSkuName = 2 - ThingTypeSku = 3 - ThingTypeStore = 4 - ThingTypeUser = 5 - ThingTypeOrder = 6 -) - -type ThingMap struct { - ModelIDCULD - - ThingID int64 `orm:"column(thing_id)" json:"thingID"` - ThingType int8 `json:"thingType"` - VendorID int `orm:"column(vendor_id)" json:"vendorID"` - VendorOrgCode string `orm:"size(32)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空 - - VendorThingID string `orm:"size(32);column(vendor_thing_id);index" json:"vendorThingID"` - SyncStatus int8 `orm:"default(2)" json:"syncStatus"` - - Remark string `orm:"size(255)" json:"remark"` -} - -func (*ThingMap) TableUnique() [][]string { - return [][]string{ - []string{"ThingID", "ThingType", "VendorID", "VendorOrgCode", "DeletedAt"}, - // []string{"VendorThingID", "ThingType", "VendorID", "VendorOrgCode", "DeletedAt"}, - } -} diff --git a/business/model/user.go b/business/model/user.go index f78cb0489..b836b15a1 100644 --- a/business/model/user.go +++ b/business/model/user.go @@ -206,18 +206,17 @@ func (*UserOrderSms) TableUnique() [][]string { type UserMember struct { ModelIDCULD - VendorOrderID string `orm:"column(vendor_order_id);size(48)" json:"vendorOrderID"` //和order_pay关联的,不知道有没用,先加上把 - UserID string `orm:"size(48);column(user_id)" json:"userID"` //内部唯一标识 - MemberType int `json:"memberType"` //会员类型, 1为折扣卡 - MemberTypeID int `orm:"column(member_type_id)" json:"memberTypeID"` //会员类型ID,折扣卡的话代表几档 - EndAt time.Time `json:"endAt"` //会员过期时间 - IsPay int `json:"isPay"` + OrderID string `orm:"column(order_id);size(48)" json:"orderID"` //和order_pay关联的,不知道有没用,先加上把 + UserID string `orm:"size(48);column(user_id)" json:"userID"` //内部唯一标识 + MemberType int `json:"memberType"` //会员类型, 1为折扣卡 + MemberTypeID int `orm:"column(member_type_id)" json:"memberTypeID"` //会员类型ID,折扣卡的话代表几档 + EndAt time.Time `json:"endAt"` //会员过期时间 } func (v *UserMember) TableIndex() [][]string { return [][]string{ []string{"UserID"}, - []string{"CreatedAt"}, + []string{"OrderID"}, } } diff --git a/business/partner/delivery/dada/waybill.go b/business/partner/delivery/dada/waybill.go deleted file mode 100644 index c66233cf1..000000000 --- a/business/partner/delivery/dada/waybill.go +++ /dev/null @@ -1,399 +0,0 @@ -package dada - -import ( - "errors" - "fmt" - - "git.rosy.net.cn/baseapi/platformapi/dadaapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/business/partner/delivery" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" - "github.com/astaxie/beego" -) - -const ( - maxOrderPrice = 6399 // 单位为分,达达最大价格,超过这个价格配送费会增加 - maxOrderWeight = 5000 // 5公斤 -) - -var ( - ErrCanNotFindDadaCityCode = errors.New("不能找到美团配送站点配置") - ErrExceedMaxDiffFee2Mtps = errors.New("与美团配送超价太多") -) - -var ( - CurDeliveryHandler *DeliveryHandler - - dadaDistrictMap = map[string]string{ - "苏州工业园区": "工业园区", - "郫都区": "郫县", - "管城回族区": "管城区", - "昆山市": "1", - "常熟市": "1", - "太仓市": "1", - "虞山街道": "虞山镇", - "常福街道": "虞山镇", - } -) - -type DeliveryHandler struct { -} - -func init() { - CurDeliveryHandler = new(DeliveryHandler) - partner.RegisterDeliveryPlatform(CurDeliveryHandler, true) -} - -func OnWaybillMsg(msg *dadaapi.CallbackMsg) (retVal *dadaapi.CallbackResponse) { - return CurDeliveryHandler.OnWaybillMsg(msg) -} - -func (c *DeliveryHandler) GetVendorID() int { - return model.VendorIDDada -} - -func (c *DeliveryHandler) OnWaybillMsg(msg *dadaapi.CallbackMsg) (retVal *dadaapi.CallbackResponse) { - jxutils.CallMsgHandler(func() { - retVal = c.onWaybillMsg(msg) - }, jxutils.ComposeUniversalOrderID(msg.OrderID, model.VendorIDDada)) - return retVal -} - -func (c *DeliveryHandler) onWaybillMsg(msg *dadaapi.CallbackMsg) (retVal *dadaapi.CallbackResponse) { - order := c.callbackMsg2Waybill(msg) - switch msg.OrderStatus { - case dadaapi.OrderStatusWaitingForAccept: - if dadaOrder, err := api.DadaAPI.QueryOrderInfo(msg.OrderID); err == nil { - order.ActualFee = jxutils.StandardPrice2Int(dadaOrder.ActualFee) - order.DesiredFee = jxutils.StandardPrice2Int(dadaOrder.DeliveryFee) - } - order.Status = model.WaybillStatusNew - case dadaapi.OrderStatusAccepted: - order.Status = model.WaybillStatusAccepted - case dadaapi.OrderStatusDelivering: - order.Status = model.WaybillStatusDelivering - case dadaapi.OrderStatusFinished: - order.Status = model.WaybillStatusDelivered - case dadaapi.OrderStatusCanceled, dadaapi.OrderStatusExpired: - order.Status = model.WaybillStatusCanceled - case dadaapi.OrderStatusAddOrderFailed: - order.Status = model.WaybillStatusFailed - default: - order.Status = model.WaybillStatusUnknown - } - return dadaapi.Err2CallbackResponse(partner.CurOrderManager.OnWaybillStatusChanged(order), utils.Int2Str(order.Status)) -} - -func (c *DeliveryHandler) callbackMsg2Waybill(msg *dadaapi.CallbackMsg) (retVal *model.Waybill) { - retVal = &model.Waybill{ - VendorWaybillID: msg.ClientID, - WaybillVendorID: model.VendorIDDada, - CourierName: msg.DmName, - CourierMobile: msg.DmMobile, - VendorStatus: utils.Int2Str(msg.OrderStatus), - Remark: msg.CancelReason, - // StatusTime: utils.Timestamp2Time(int64(msg.UpdateTime)), - } - // dada太扯了,不同消息过来的时间格式不一样 - updateTime := int64(msg.UpdateTime) - if updateTime > 2511789475 { - updateTime = updateTime / 1000 - } - retVal.StatusTime = utils.Timestamp2Time(updateTime) - retVal.VendorOrderID, retVal.OrderVendorID = jxutils.SplitUniversalOrderID(msg.OrderID) - return retVal -} - -func StoreDetail2ShopInfo(storeDetail *dao.StoreDetail2) (shopInfo *dadaapi.ShopInfo) { - lng := jxutils.IntCoordinate2Standard(storeDetail.Lng) - lat := jxutils.IntCoordinate2Standard(storeDetail.Lat) - cityName := storeDetail.CityName - districtName := storeDetail.DistrictName - if dadaDistrictMap[districtName] != "" { - if dadaDistrictMap[districtName] == "1" { // 区镇信息 - cityName = districtName - districtName, _ = api.AutonaviAPI.GetCoordinateTownInfo(lng, lat) - } - if dadaDistrictMap[districtName] != "" { - districtName = dadaDistrictMap[storeDetail.DistrictName] - } - } - shopInfo = &dadaapi.ShopInfo{ - OriginShopID: storeDetail.VendorStoreID, - StationName: globals.StoreName + "-" + storeDetail.Name, - Business: dadaapi.BusinessTypeConvStore, // 故意设置成这个的 - CityName: cityName, - AreaName: districtName, - StationAddress: storeDetail.Address, - Lng: lng, - Lat: lat, - ContactName: storeDetail.PayeeName, - Phone: storeDetail.Tel1, - } - if storeDetail.CourierStatus >= model.StoreStatusClosed { - shopInfo.Status = dadaapi.ShopStatusOnline - } else { - shopInfo.Status = dadaapi.ShopStatusOffline - } - return shopInfo -} - -func (c *DeliveryHandler) CreateStore(ctx *jxcontext.Context, storeDetail *dao.StoreDetail2) (vendorStoreID string, status int, err error) { - if globals.EnableStoreWrite { - vendorStoreID, err = api.DadaAPI.ShopAdd(StoreDetail2ShopInfo(storeDetail)) - if err == nil { - status = model.StoreAuditStatusOnline - } - } else { - vendorStoreID = utils.Int64ToStr(jxutils.GenFakeID()) - status = model.StoreAuditStatusOnline - } - return vendorStoreID, status, err -} - -func (c *DeliveryHandler) UpdateStore(ctx *jxcontext.Context, storeDetail *dao.StoreDetail2) (err error) { - if globals.EnableStoreWrite { - err = api.DadaAPI.ShopUpdate(StoreDetail2ShopInfo(storeDetail)) - } - return err -} - -func dadaStatus2Jx(dadaStatus int) int { - if dadaStatus == dadaapi.ShopStatusOnline { - return model.StoreStatusOpened - } - return model.StoreStatusDisabled -} - -func (c *DeliveryHandler) GetStore(ctx *jxcontext.Context, storeID int, vendorStoreID string) (storeDetail *dao.StoreDetail2, err error) { - shopInfo, err := api.DadaAPI.ShopDetail(vendorStoreID) - if err == nil { - storeDetail = &dao.StoreDetail2{ - Store: model.Store{ - Name: shopInfo.StationName, - Address: shopInfo.StationAddress, - Lng: jxutils.StandardCoordinate2Int(shopInfo.Lng), - Lat: jxutils.StandardCoordinate2Int(shopInfo.Lat), - PayeeName: shopInfo.ContactName, - Tel1: shopInfo.Phone, - }, - VendorID: model.VendorIDDada, - VendorStoreID: shopInfo.OriginShopID, - CourierStatus: dadaStatus2Jx(shopInfo.Status), - AuditStatus: model.StoreAuditStatusOnline, - CityName: shopInfo.CityName, - DistrictName: shopInfo.AreaName, - } - } - return storeDetail, err -} - -func (c *DeliveryHandler) IsErrStoreNotExist(err error) bool { - return dadaapi.IsErrShopNotExist(err) -} - -func (c *DeliveryHandler) IsErrStoreExist(err error) bool { - return dadaapi.IsErrShopExist(err) -} - -func (c *DeliveryHandler) GetWaybillFee(order *model.GoodsOrder) (deliveryFeeInfo *partner.WaybillFeeInfo, err error) { - db := dao.GetDB() - deliveryFeeInfo = &partner.WaybillFeeInfo{} - billParams, err := c.getBillParams(db, order) - if err == nil { - var result *dadaapi.CreateOrderResponse - if result, err = api.DadaAPI.QueryDeliverFee(billParams); err != nil { - return nil, err - } - deliveryFeeInfo.DeliveryFee = jxutils.StandardPrice2Int(result.Fee) - deliveryFeeInfo.RefDeliveryFee = deliveryFeeInfo.DeliveryFee - } - return deliveryFeeInfo, err -} - -func (c *DeliveryHandler) getBillParams(db *dao.DaoDB, order *model.GoodsOrder) (billParams *dadaapi.OperateOrderParams, err error) { - billParams = &dadaapi.OperateOrderParams{ - OriginID: jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID), - CargoPrice: jxutils.IntPrice2Standard(limitOrderPrice(order.ActualPayPrice)), - IsPrepay: 0, - ReceiverName: utils.FilterMb4(order.ConsigneeName), - ReceiverAddress: utils.FilterMb4(order.ConsigneeAddress), - ReceiverPhone: order.ConsigneeMobile, - } - if billParams.ShopNo, err = c.getDadaShopID(order, db); err == nil { - if billParams.CityCode, err = c.getDataCityCodeFromOrder(order, db); err == nil { - // storeTel := "" - // storeID := jxutils.GetSaleStoreIDFromOrder(order) - // storeDeatail, _ := dao.GetStoreDetail(db, storeID, order.VendorID) - // if storeDeatail.Tel2 != "" { - // storeTel = ",门店电话:" + storeDeatail.Tel2 - // } - billParams.ReceiverLng, billParams.ReceiverLat, _ = jxutils.IntCoordinate2MarsStandard(order.ConsigneeLng, order.ConsigneeLat, order.CoordinateType) - billParams.Info = fmt.Sprintf("%s第%d号订单, %s", model.VendorChineseNames[order.VendorID], order.OrderSeq, utils.FilterMb4("客户电话:"+order.ConsigneeMobile+","+order.BuyerComment+"取货失败或配送遇到问题请联系18048531223,禁止未配送直接完成定单!")) - billParams.CargoType = dadaapi.CargoTypeFresh - billParams.CargoWeight = float64(jxutils.IntWeight2Float(limitOrderWeight(order.Weight))) - billParams.CargoNum = order.GoodsCount - } - } - return billParams, err -} - -// IDeliveryPlatformHandler -func (c *DeliveryHandler) CreateWaybill(order *model.GoodsOrder, maxDeliveryFee int64) (bill *model.Waybill, err error) { - db := dao.GetDB() - billParams, err := c.getBillParams(db, order) - if err == nil { - if globals.EnableStoreWrite { - // 达达要求第二次创建运单,调用函数不同。所以查找两天内有无相同订单号的运单 - var waybillList []*model.Waybill - err2 := dao.GetRows(db, &waybillList, ` - SELECT * - FROM waybill - WHERE waybill_created_at > DATE_ADD(NOW(), interval -2 day) - AND vendor_order_id = ? - AND waybill_vendor_id = ? - ORDER BY id DESC - `, jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID), model.VendorIDDada) - var result *dadaapi.CreateOrderResponse - if err = err2; err == nil && len(waybillList) > 0 && waybillList[0].Status != model.WaybillStatusFailed { - // 再次创建 - globals.SugarLogger.Debugf("CreateWaybill orderID:%s len(waybillList)=%d use ReaddOrder", order.VendorOrderID, len(waybillList)) - if err = delivery.CallCreateWaybillPolicy(waybillList[0].ActualFee, maxDeliveryFee, order, model.VendorIDDada); err != nil { - return nil, err - } - // result, err = api.DadaAPI.ReaddOrder(billParams, addParams) - result, err = api.DadaAPI.ReaddOrder(billParams) - } else { - // 第一次创建 - if err != nil { - globals.SugarLogger.Warnf("CreateWaybill orderID:%s error:%v", order.VendorOrderID, err) - } - if false { - result, err = api.DadaAPI.AddOrder(billParams) - } else { - if result, err = api.DadaAPI.QueryDeliverFee(billParams); err != nil { - return nil, err - } - if err = delivery.CallCreateWaybillPolicy(jxutils.StandardPrice2Int(result.Fee), maxDeliveryFee, order, model.VendorIDDada); err != nil { - return nil, err - } - err = api.DadaAPI.AddOrderAfterQuery(result.DeliveryNo) - } - } - if err == nil && result != nil { - bill = &model.Waybill{ - VendorOrderID: order.VendorOrderID, - OrderVendorID: order.VendorID, - WaybillVendorID: model.VendorIDDada, - DesiredFee: jxutils.StandardPrice2Int(result.Fee), - ActualFee: jxutils.StandardPrice2Int(result.Fee), - } - delivery.OnWaybillCreated(bill) - } - } else { - err = fmt.Errorf("测试环境不能真正创建运单") - } - } - return bill, err -} - -func (c *DeliveryHandler) CancelWaybill(bill *model.Waybill, cancelReasonID int, cancelReason string) (err error) { - switch cancelReasonID { - case partner.CancelWaybillReasonNotAcceptIntime: - cancelReasonID = dadaapi.ReasonIDNobodyAccept - case partner.CancelWaybillReasonSwitch2SelfFailed: - cancelReasonID = dadaapi.ReasonIDClientDontWantItAnymore - default: - cancelReasonID = dadaapi.ReasonIDOther - } - _, err = api.DadaAPI.CancelOrder(bill.VendorOrderID, cancelReasonID, cancelReason) - return err -} - -func (c *DeliveryHandler) getDataCityCodeFromOrder(order *model.GoodsOrder, db *dao.DaoDB) (retVal string, err error) { - jxStoreID := jxutils.GetSaleStoreIDFromOrder(order) - sql := ` - SELECT t2.tel_code - FROM store t1 - JOIN place t2 on t1.city_code = t2.code - WHERE t1.id = ? - ` - codeInfo := &struct { - TelCode string - }{} - if err = dao.GetRow(db, codeInfo, sql, jxStoreID); err != nil { - globals.SugarLogger.Errorf("GetDataCityCodeFromOrder can not find store info for vendorID:%d, store:%s, error:%v", order.VendorID, order.VendorStoreID, err) - if err == nil { - err = ErrCanNotFindDadaCityCode - } - return "", err - } - return codeInfo.TelCode, nil -} - -func (c *DeliveryHandler) getDadaShopID(order *model.GoodsOrder, db *dao.DaoDB) (retVal string, err error) { - saleStoreID := jxutils.GetSaleStoreIDFromOrder(order) - storeCourierList, err2 := dao.GetOpenedStoreCouriersByStoreID(db, saleStoreID, model.VendorIDDada) - if err = err2; err != nil && !dao.IsNoRowsError(err) { - return "", err - } - if len(storeCourierList) == 0 { - return "", partner.ErrStoreHaveNoCourier - } - retVal = storeCourierList[0].VendorStoreID - if beego.BConfig.RunMode == "dev" { - retVal = "test_0001" - } - return retVal, nil -} - -func limitOrderPrice(price int64) int64 { - if price > maxOrderPrice { - return maxOrderPrice - } - return price -} - -func limitOrderWeight(weight int) int { - if weight > maxOrderWeight { - return maxOrderWeight - } - return weight -} - -func (c *DeliveryHandler) ComplaintRider(bill *model.Waybill, resonID int, resonContent string) (err error) { - if globals.EnableStoreWrite { - err = api.DadaAPI.ComplaintRider(bill.VendorOrderID, resonID) - } - return err -} - -func (c *DeliveryHandler) GetWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2 string) (tipFee int64, err error) { - order, err := api.DadaAPI.QueryOrderInfo(vendorOrderID) - if err == nil { - tipFee = jxutils.StandardPrice2Int(order.Tips) - } - return tipFee, err -} - -func (c *DeliveryHandler) UpdateWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2, cityCode string, tipFee int64) (err error) { - if globals.EnableStoreWrite { - err = api.DadaAPI.AddTip(vendorOrderID, jxutils.IntPrice2Standard(tipFee), cityCode, "") - } - return err -} - -func (c *DeliveryHandler) GetRidderPosition(ctx *jxcontext.Context, vendorOrgCode, vendorOrderID, vendorWaybillID, vendorWaybillID2 string) (lng, lat float64, err error) { - order, err := api.DadaAPI.QueryOrderInfo(vendorOrderID) - if err == nil { - lng = utils.Str2Float64WithDefault(order.TransporterLng, 0) - lat = utils.Str2Float64WithDefault(order.TransporterLat, 0) - } - return lng, lat, err -} diff --git a/business/partner/delivery/dada/waybill_test.go b/business/partner/delivery/dada/waybill_test.go deleted file mode 100644 index a7a680f69..000000000 --- a/business/partner/delivery/dada/waybill_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package dada - -import ( - "testing" - "time" - - _ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals/testinit" -) - -func init() { - testinit.Init() -} - -func TestCreateWaybill(t *testing.T) { - orderID := "817540316000041" - if order, err := partner.CurOrderManager.LoadOrder(orderID, model.VendorIDJD); err == nil { - // globals.SugarLogger.Debug(order) - _, err = CurDeliveryHandler.CreateWaybill(order, 0) - if err == nil { - time.Sleep(1 * time.Second) - bill := &model.Waybill{ - VendorOrderID: orderID, - WaybillVendorID: model.VendorIDDada, - } - err = CurDeliveryHandler.CancelWaybill(bill, partner.CancelWaybillReasonOther, "") - if err != nil { - t.Fatal(err.Error()) - } - } else { - t.Fatal(err.Error()) - } - } else { - t.Fatal(err.Error()) - } -} - -func TestGetRidderPosition(t *testing.T) { - lng, lat, err := CurDeliveryHandler.GetRidderPosition(jxcontext.AdminCtx, "", "80704840263399812", "", "") - if err != nil { - t.Fatal(err) - } - t.Logf("lng:%f, lat:%f", lng, lat) -} diff --git a/business/partner/delivery/delivery.go b/business/partner/delivery/delivery.go deleted file mode 100644 index 1602fe3b7..000000000 --- a/business/partner/delivery/delivery.go +++ /dev/null @@ -1,149 +0,0 @@ -package delivery - -import ( - "fmt" - "math" - "time" - - "git.rosy.net.cn/baseapi/utils" - "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" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" -) - -const ( - warningDistance = 10 // 公里 - warningWeight = 50 * 1000 // 克 - // maxDiffFee2Mtps = 200 // 与美团配送最多差价 - // maxAddFee = 200 // 最大增加费用,单位为分,超过不发三方配送了 - defMaxDeliveryFee = 10000 // 创建运单最高价 - alarmFee = 1500 // 配送费报警阈值 -) - -func CallCreateWaybillPolicy(deliveryFee, maxDeliveryFee int64, order *model.GoodsOrder, waybillVendorID int) (err error) { - if maxDeliveryFee <= 0 || maxDeliveryFee > defMaxDeliveryFee { - maxDeliveryFee = defMaxDeliveryFee - } - if deliveryFee > maxDeliveryFee { - errStr := fmt.Sprintf("超最高限价, 所需运费:%s, 最高限价:%s", jxutils.IntPrice2StandardCurrencyString(deliveryFee), jxutils.IntPrice2StandardCurrencyString(maxDeliveryFee)) - err = fmt.Errorf(errStr) - globals.SugarLogger.Debugf("CallCreateWaybillPolicy orderID:%s, 平台:%s运单,创建出错:%s", order.VendorOrderID, model.VendorChineseNames[waybillVendorID], errStr) - } - return err -} - -func CalculateDeliveryFee(db *dao.DaoDB, jxStoreID int, hint string, consigneeLng, consigneeLat, coordinateType, weight int, billTime time.Time) (deliveryFee, addFee int64, err error) { - globals.SugarLogger.Debugf("CalculateOrderDeliveryFee orderID:%s", hint) - if db == nil { - db = dao.GetDB() - } - var lng, lat float64 - priceInfo := &struct { - CityPrice int64 - DistrictPrice int64 - Lng int - Lat int - }{} - if err = dao.GetRow(db, priceInfo, ` - SELECT - t2.mtps_price city_price, t2.mtps_price district_price, t1.lng, t1.lat - FROM store t1 - LEFT JOIN place t2 ON t2.level = 2 AND t2.code = t1.city_code - LEFT JOIN place t3 ON t3.level = 3 AND t2.code = t1.district_code - WHERE t1.id = ? AND t1.deleted_at = ? - `, jxStoreID, utils.DefaultTimeValue); err != nil { - return 0, 0, err - } - lng = jxutils.IntCoordinate2Standard(priceInfo.Lng) - lat = jxutils.IntCoordinate2Standard(priceInfo.Lat) - if deliveryFee = priceInfo.DistrictPrice; deliveryFee == 0 { - deliveryFee = priceInfo.CityPrice - } - if deliveryFee == 0 { - // globals.SugarLogger.Warnf("CalculateOrderDeliveryFee 查不到美团配送价格 orderID:%s", hint) - deliveryFee = 650 - } - if lng == 0 || lat == 0 { - globals.SugarLogger.Infof("[运营]计算订单配送费orderID:%s,门店:%d没有坐标信息", hint, jxStoreID) - return 0, 0, fmt.Errorf("找不到门店:%d的坐标", jxStoreID) - } - lng2, lat2, _ := jxutils.IntCoordinate2MarsStandard(consigneeLng, consigneeLat, coordinateType) - - var distanceAddFee, weightAddFee, timeAddFee int64 - - // 距离加价 - distance := jxutils.WalkingDistance(lng, lat, lng2, lat2) - if distance > warningDistance { - globals.SugarLogger.Infof("[运营]计算订单配送费orderID:%s,距离%.3fkm太远,请检查门店坐标信息", hint, distance) - } - distanceAddFee = int64(jxutils.CalcStageValue([][]float64{ - []float64{ - 7, - 300, - }, - []float64{ - 5, - 200, - }, - []float64{ - 3, - 100, - }, - }, distance)) - - // 重量加价 - if weight > warningWeight { - globals.SugarLogger.Infof("[运营]计算订单配送费orderID:%s,重量:%dg太重,请检查商品属性", hint, weight) - } - weightAddFee = int64(jxutils.CalcStageValue([][]float64{ - []float64{ - 20, - 200, - }, - []float64{ - 10, - 100, - }, - []float64{ - 5, - 50, - }, - }, float64(weight)/1000)) - - // 其它加价 - hour, min, sec := billTime.Clock() - totalSeconds := hour*3600 + min*60 + sec - // 午高峰加价 - if totalSeconds >= 11*3600 && totalSeconds <= 14*3600 { // 11:00 -- 14:00 - timeAddFee = jxutils.StandardPrice2Int(2) - } else if totalSeconds >= 21*3600 || totalSeconds <= 6*3600 { // 21:00 -- 06:00 夜间加价 - timeAddFee = jxutils.StandardPrice2Int(3) - } - addFee = distanceAddFee + weightAddFee + timeAddFee - globals.SugarLogger.Debugf("CalculateOrderDeliveryFee orderID:%s, deliveryFee:%d addFee:%d, distance:%.3fkm distanceAddFee:%d, weight:%dg weightAddFee:%d, time:%s timeAddFee:%d", - hint, deliveryFee, addFee, distance, distanceAddFee, weight, weightAddFee, utils.Time2TimeStr(billTime), timeAddFee) - return deliveryFee + addFee, addFee, nil -} - -func CalculateOrderDeliveryFee(order *model.GoodsOrder, billTime time.Time, db *dao.DaoDB) (deliveryFee, addFee int64, err error) { - return CalculateDeliveryFee(db, jxutils.GetSaleStoreIDFromOrder(order), order.VendorOrderID, order.ConsigneeLng, order.ConsigneeLat, order.CoordinateType, order.Weight, billTime) -} - -func CalculateBillDeliveryFee(bill *model.Waybill) (deliveryFee, addFee int64) { - order, err := partner.CurOrderManager.LoadOrder(bill.VendorOrderID, bill.OrderVendorID) - if err != nil { - return 0, 0 - } - deliveryFee, addFee, _ = CalculateOrderDeliveryFee(order, bill.StatusTime, nil) - return deliveryFee, addFee -} - -func OnWaybillCreated(waybill *model.Waybill) { - deliveryFee := int64(math.Max(float64(waybill.DesiredFee), float64(waybill.ActualFee))) - if deliveryFee > alarmFee { - globals.SugarLogger.Infof("[运营]%s订单, orderID:%s, 成功创建%s运单:%s, 配送费:%s太高(大于%s),请知悉!", model.VendorChineseNames[waybill.OrderVendorID], waybill.VendorOrderID, - model.VendorChineseNames[waybill.WaybillVendorID], waybill.VendorWaybillID, jxutils.IntPrice2StandardCurrencyString(deliveryFee), jxutils.IntPrice2StandardCurrencyString(alarmFee)) - } -} diff --git a/business/partner/delivery/jdeclp/waybill.go b/business/partner/delivery/jdeclp/waybill.go deleted file mode 100644 index c88bf0b47..000000000 --- a/business/partner/delivery/jdeclp/waybill.go +++ /dev/null @@ -1,104 +0,0 @@ -package jdeclp - -import ( - "fmt" - "time" - - "git.rosy.net.cn/baseapi/platformapi/jdeclpapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals/api" -) - -var ( - CurDeliveryHandler *DeliveryHandler -) - -type DeliveryHandler struct { -} - -func init() { - CurDeliveryHandler = new(DeliveryHandler) - partner.RegisterDeliveryPlatform(CurDeliveryHandler, true) -} - -func (c *DeliveryHandler) GetVendorID() int { - return model.VendorIDJDWL -} - -func OnWaybillMsg() { -} - -func (c *DeliveryHandler) OnWaybillMsg() { - -} - -func (c *DeliveryHandler) CreateStore(ctx *jxcontext.Context, storeDetail *dao.StoreDetail2) (vendorStoreID string, status int, err error) { - return vendorStoreID, status, err -} -func (c *DeliveryHandler) GetStore(ctx *jxcontext.Context, storeID int, vendorStoreID string) (storeDetail *dao.StoreDetail2, err error) { - return storeDetail, err -} -func (c *DeliveryHandler) IsErrStoreNotExist(err error) bool { - return false -} -func (c *DeliveryHandler) IsErrStoreExist(err error) bool { - return false -} -func (c *DeliveryHandler) CreateWaybill(order *model.GoodsOrder, maxDeliveryFee int64) (bill *model.Waybill, err error) { - storeID := jxutils.GetShowStoreIDFromOrder(order) - stores, err := dao.GetStoreList(dao.GetDB(), []int{storeID}, nil, nil, nil, "") - if len(stores) == 0 || err != nil { - return bill, fmt.Errorf("未查询到该门店! 门店id :[%v]", storeID) - } - vendorWaybillID, err := api.JdEclpAPI.WaybillReceive(&jdeclpapi.WaybillReceiveParam{ - SalePlat: jdeclpapi.SalePlatSourceDelivery, - CustomerCode: jdeclpapi.CustomerCode, - OrderID: order.VendorOrderID, - SenderName: order.StoreName, - SenderAddress: stores[0].Address, - SenderTel: stores[0].Tel1, - ReceiveName: order.ConsigneeName, - ReceiveAddress: order.ConsigneeAddress, - ReceiveTel: order.ConsigneeMobile, - Weight: order.Weight, - Vloumn: order.Weight, - PackageCount: 1, - Description: "生鲜", - Aging: 5, - PromiseTimeType: 1, //特惠送 - }) - waybill := &model.Waybill{ - VendorOrderID: order.VendorOrderID, - OrderVendorID: model.VendorIDJDShop, - VendorWaybillID: vendorWaybillID, - WaybillVendorID: model.VendorIDJDWL, - Status: model.WaybillStatusDelivering, - WaybillCreatedAt: time.Now(), - StatusTime: time.Now(), - WaybillFinishedAt: utils.DefaultTimeValue, - DeliveryFlag: model.OrderDeliveryFlagMaskScheduleDisabled, - } - dao.CreateEntity(dao.GetDB(), waybill) - return waybill, err -} -func (c *DeliveryHandler) CancelWaybill(bill *model.Waybill, cancelReasonID int, cancelReason string) (err error) { - err = api.JdEclpAPI.CancelWayBill(&jdeclpapi.CancelWayBillParam{ - WaybillCode: bill.VendorWaybillID, - CustomerCode: jdeclpapi.CustomerCode, - Source: "JOS", - CancelReason: cancelReason, - OperatorName: "jxadmin", - }) - return err -} -func (c *DeliveryHandler) GetWaybillFee(order *model.GoodsOrder) (deliveryFeeInfo *partner.WaybillFeeInfo, err error) { - return deliveryFeeInfo, err -} -func (c *DeliveryHandler) ComplaintRider(bill *model.Waybill, resonID int, resonContent string) (err error) { - return err -} diff --git a/business/partner/delivery/jdeclp/waybill_test.go b/business/partner/delivery/jdeclp/waybill_test.go deleted file mode 100644 index b954e8be9..000000000 --- a/business/partner/delivery/jdeclp/waybill_test.go +++ /dev/null @@ -1,7 +0,0 @@ -package jdeclp - -import "git.rosy.net.cn/jx-callback/globals/testinit" - -func init() { - testinit.Init() -} diff --git a/business/partner/delivery/mtps/store.go b/business/partner/delivery/mtps/store.go deleted file mode 100644 index 9664c736e..000000000 --- a/business/partner/delivery/mtps/store.go +++ /dev/null @@ -1,141 +0,0 @@ -package mtps - -import ( - "git.rosy.net.cn/baseapi/platformapi/mtpsapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -const ( - fakeContactEmail = "fakeemail@163.com" -) - -var ( - auditStatusMap = map[int]int{ - mtpsapi.ShopStatusAuditCreated: model.StoreAuditStatusCreated, - mtpsapi.ShopStatusAuditRejected: model.StoreAuditStatusRejected, - mtpsapi.ShopStatusAuditPassed: model.StoreAuditStatusCreated, - mtpsapi.ShopStatusAuditOnline: model.StoreAuditStatusOnline, - } -) - -func getAuditStatus(vendorAuditStatus int) int { - if auditStatus, ok := auditStatusMap[vendorAuditStatus]; ok { - return auditStatus - } - return model.StoreAuditStatusCreated -} - -func OnStoreStatus(msg *mtpsapi.CallbackShopStatusMsg) (retVal *mtpsapi.CallbackResponse) { - return curDeliveryHandler.OnStoreStatus(msg) -} - -func (c *DeliveryHandler) OnStoreStatus(msg *mtpsapi.CallbackShopStatusMsg) (retVal *mtpsapi.CallbackResponse) { - globals.SugarLogger.Debugf("mtps OnStoreStatus, msg:%s", utils.Format4Output(msg, true)) - err := partner.CurStoreManager.OnCourierStoreStatusChanged(jxcontext.AdminCtx, msg.ShopID, model.VendorIDMTPS, getAuditStatus(msg.Status)) - retVal = mtpsapi.Err2CallbackResponse(err, "mtps OnStoreStatus") - return retVal -} - -func (c *DeliveryHandler) CreateStore(ctx *jxcontext.Context, storeDetail *dao.StoreDetail2) (vendorStoreID string, status int, err error) { - if globals.EnableStoreWrite { - businessHours := []*mtpsapi.BusinessHour{ - &mtpsapi.BusinessHour{ - BeginTime: "06:00", - EndTime: "22:00", - }, - } - shopInfo := &mtpsapi.ShopInfo{ - ShopID: storeDetail.VendorStoreID, - ShopName: storeDetail.Name, - Category: mtpsapi.ShopCategoryFruit, - SecondCategory: mtpsapi.ShopCategoryFruitFruit, - ContactName: storeDetail.PayeeName, - ContactPhone: storeDetail.Tel1, - ContactEmail: fakeContactEmail, - ShopAddress: storeDetail.Address, - ShopLng: storeDetail.Lng, - ShopLat: storeDetail.Lat, - CoordinateType: mtpsapi.CoordinateTypeMars, - BusinessHours: string(utils.MustMarshal(businessHours)), - } - shopStatus := mtpsapi.ShopStatusAuditCreated - if globals.EnableStoreWrite { - shopStatus, err = api.MtpsAPI.ShopCreate(shopInfo) - if err == nil { - vendorStoreID = shopInfo.ShopID - status = getAuditStatus(shopStatus) - } - } else { - vendorStoreID = utils.Int64ToStr(jxutils.GenFakeID()) - status = model.StoreAuditStatusOnline - } - } - return vendorStoreID, status, err -} - -func (c *DeliveryHandler) GetStore(ctx *jxcontext.Context, storeID int, vendorStoreID string) (storeDetail *dao.StoreDetail2, err error) { - shopInfo, err := api.MtpsAPI.ShopQuery(vendorStoreID) - if err == nil { - storeDetail = &dao.StoreDetail2{ - Store: model.Store{ - Name: shopInfo.ShopName, - CityCode: shopInfo.City, - PayeeName: shopInfo.ContactName, - Tel1: shopInfo.ContactPhone, - Address: shopInfo.ShopAddress, - Lng: shopInfo.ShopLng, - Lat: shopInfo.ShopLat, - }, - VendorID: model.VendorIDMTPS, - VendorStoreID: shopInfo.ShopID, - // CourierStatus: model.StoreStatusOpened, - // AuditStatus: model.StoreAuditStatusOnline, - } - result, err := api.MtpsAPI.GetStoreStatus(shopInfo.ShopName) - if err == nil { - storeDetail.AuditStatus = mtpsOpenTypeToJx(result.DataList[0].OpenType) - storeDetail.CourierStatus = mtpsOpenTypeToJx2(result.DataList[0].OpenType) - } - } - return storeDetail, err -} - -func mtpsOpenTypeToJx(openType int) (status int) { - if openType == 0 { - status = model.StoreAuditStatusRejected - } else { - status = model.StoreAuditStatusOnline - } - return status -} - -func mtpsOpenTypeToJx2(openType int) (status int) { - if openType == 0 { - status = model.StoreStatusClosed - } else { - status = model.StoreStatusOpened - } - return status -} - -func (c *DeliveryHandler) IsErrStoreNotExist(err error) bool { - return mtpsapi.IsErrShopNotExist(err) -} - -func (c *DeliveryHandler) IsErrStoreExist(err error) bool { - return mtpsapi.IsErrShopExist(err) -} - -func (c *DeliveryHandler) UpdateStore(ctx *jxcontext.Context, storeDetail *dao.StoreDetail2) (err error) { - // if globals.EnableStoreWrite { - // err = api.MtpsAPI.PagePoiUpdate(storeDetail.VendorStoreID, storeDetail.PayeeName, storeDetail.Tel1, fakeContactEmail) - // } - return err -} diff --git a/business/partner/delivery/mtps/waybill.go b/business/partner/delivery/mtps/waybill.go deleted file mode 100644 index bdb727f75..000000000 --- a/business/partner/delivery/mtps/waybill.go +++ /dev/null @@ -1,333 +0,0 @@ -package mtps - -import ( - "crypto/sha1" - "errors" - "fmt" - "net/http" - "net/url" - "sort" - "strings" - "time" - - "git.rosy.net.cn/baseapi/platformapi/mtpsapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/business/partner/delivery" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" - "github.com/astaxie/beego" - "github.com/astaxie/beego/orm" -) - -const ( - // maxOrderPrice = 6399 // 单位为分,达达最大价格,超过这个价格配送费会增加 - maxOrderWeight = 5000 // 5公斤 -) - -var ( - ErrCanNotFindMTPSStore = errors.New("不能找到美团配送站点配置") - ErrStoreNoPriceInfo = errors.New("找不到门店的美团配送价格信息") -) - -var ( - curDeliveryHandler *DeliveryHandler -) - -type DeliveryHandler struct { -} - -func init() { - if api.MtpsAPI != nil { - curDeliveryHandler = new(DeliveryHandler) - partner.RegisterDeliveryPlatform(curDeliveryHandler, true) - } -} - -func (c *DeliveryHandler) GetVendorID() int { - return model.VendorIDMTPS -} - -func OnWaybillMsg(msg *mtpsapi.CallbackOrderMsg) (retVal *mtpsapi.CallbackResponse) { - return curDeliveryHandler.OnWaybillMsg(msg) -} - -func OnWaybillExcept(msg *mtpsapi.CallbackOrderExceptionMsg) (retVal *mtpsapi.CallbackResponse) { - return curDeliveryHandler.OnWaybillExcept(msg) -} - -func (c *DeliveryHandler) OnWaybillMsg(msg *mtpsapi.CallbackOrderMsg) (retVal *mtpsapi.CallbackResponse) { - jxutils.CallMsgHandler(func() { - retVal = c.onWaybillMsg(msg) - }, jxutils.ComposeUniversalOrderID(msg.OrderID, model.VendorIDMTPS)) - return retVal -} - -func (c *DeliveryHandler) OnWaybillExcept(msg *mtpsapi.CallbackOrderExceptionMsg) (retVal *mtpsapi.CallbackResponse) { - jxutils.CallMsgHandler(func() { - order := &model.Waybill{ - VendorWaybillID: msg.MtPeisongID, - VendorWaybillID2: utils.Int64ToStr(msg.DeliveryID), - WaybillVendorID: model.VendorIDMTPS, - CourierName: msg.CourierName, - CourierMobile: msg.CourierPhone, - Status: model.WaybillStatusUnknown, // todo 这里要再确定一下是否只要收到订单异常消息就只简单当成一个消息 - VendorStatus: utils.Int2Str(msg.ExceptionCode), - StatusTime: utils.Timestamp2Time(msg.Timestamp), - } - order.VendorOrderID, order.OrderVendorID = jxutils.SplitUniversalOrderID(msg.OrderID) - retVal = mtpsapi.Err2CallbackResponse(partner.CurOrderManager.OnWaybillStatusChanged(order), "mtps OnWaybillExcept") - }, jxutils.ComposeUniversalOrderID(msg.OrderID, model.VendorIDDada)) - return retVal -} - -func (c *DeliveryHandler) onWaybillMsg(msg *mtpsapi.CallbackOrderMsg) (retVal *mtpsapi.CallbackResponse) { - order := c.callbackMsg2Waybill(msg) - switch msg.Status { - case mtpsapi.OrderStatusWaitingForSchedule: - order.DesiredFee, _ = delivery.CalculateBillDeliveryFee(order) - order.Status = model.WaybillStatusNew - case mtpsapi.OrderStatusAccepted: - order.DesiredFee, _ = delivery.CalculateBillDeliveryFee(order) // 美团外卖可能会丢失新运单事件,这里补一下 - order.Status = model.WaybillStatusAccepted - case mtpsapi.OrderStatusPickedUp: - order.Status = model.WaybillStatusDelivering - case mtpsapi.OrderStatusDeliverred: - order.Status = model.WaybillStatusDelivered - case mtpsapi.OrderStatusCanceled: - order.Status = model.WaybillStatusCanceled - default: - globals.SugarLogger.Warnf("onWaybillMsg unknown msg:%v", msg) - return mtpsapi.SuccessResponse - } - order2, _ := partner.CurOrderManager.LoadOrder(order.VendorOrderID, order.OrderVendorID) - // order2, _ := dao.GetSimpleOrder(dao.GetDB(), order.VendorOrderID) - //查不到订单可能就是果园的订单 - if order2 == nil { - c.pushToGy(msg) - return mtpsapi.SuccessResponse - } - return mtpsapi.Err2CallbackResponse(partner.CurOrderManager.OnWaybillStatusChanged(order), order.VendorStatus) -} - -func (c *DeliveryHandler) pushToGy(msg *mtpsapi.CallbackOrderMsg) { - cl := http.Client{} - params := make(map[string]interface{}) - params["mt_peisong_id"] = msg.MtPeisongID - params["courier_name"] = msg.CourierName - params["delivery_id"] = msg.DeliveryID - params["appkey"] = msg.AppKey - params["order_id"] = msg.OrderID - params["courier_phone"] = msg.CourierPhone - params["status"] = msg.Status - params["timestamp"] = msg.Timestamp - params["cancel_reason_id"] = msg.CancelReasonId - params["cancel_reason"] = msg.CancelReason - urls := utils.Map2URLValues(params) - sign := signParams(urls) - params["sign"] = sign - globals.SugarLogger.Debugf("pushToGy", utils.Format4Output(msg, false)) - request, err := http.NewRequest(http.MethodPost, "http://callback-jxgy.jxc4.com/mtps/status", strings.NewReader(utils.Map2URLValues(params).Encode())) - if err != nil { - return - } - request.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8") - cl.Do(request) -} - -func signParams(params url.Values) string { - keys := make([]string, 0) - for k := range params { - if k != "sign" { - keys = append(keys, k) - } - } - - sort.Strings(keys) - finalStr := "b1M}9?:sTbsB[OF2gNORnN(|(iy9rB8(`7]|[wGLnbmt`evfM>E:A90DjHAW:UPE" - for _, key := range keys { - valStr := strings.Join(params[key], "") - if valStr != "" { - finalStr += key + valStr - } - } - - // baseapi.SugarLogger.Debug(finalStr) - return fmt.Sprintf("%x", sha1.Sum([]byte(finalStr))) -} - -func (c *DeliveryHandler) callbackMsg2Waybill(msg *mtpsapi.CallbackOrderMsg) (retVal *model.Waybill) { - retVal = &model.Waybill{ - VendorWaybillID: msg.MtPeisongID, - VendorWaybillID2: utils.Int64ToStr(msg.DeliveryID), - WaybillVendorID: model.VendorIDMTPS, - CourierName: msg.CourierName, - CourierMobile: msg.CourierPhone, - VendorStatus: utils.Int2Str(msg.Status), - StatusTime: utils.Timestamp2Time(msg.Timestamp), - Remark: msg.CancelReason, - } - retVal.VendorOrderID, retVal.OrderVendorID = jxutils.SplitUniversalOrderID(msg.OrderID) - return retVal -} - -func (c *DeliveryHandler) GetWaybillFee(order *model.GoodsOrder) (deliveryFeeInfo *partner.WaybillFeeInfo, err error) { - db := dao.GetDB() - deliveryFeeInfo = &partner.WaybillFeeInfo{} - deliveryFeeInfo.RefDeliveryFee, deliveryFeeInfo.RefAddFee, err = delivery.CalculateOrderDeliveryFee(order, time.Now(), db) - if err == nil { - if _, err = c.getMTPSShopID(order, db); err == nil { - deliveryFeeInfo.DeliveryFee = deliveryFeeInfo.RefDeliveryFee - } - } - return deliveryFeeInfo, err -} - -// IDeliveryPlatformHandler -func (c *DeliveryHandler) CreateWaybill(order *model.GoodsOrder, maxDeliveryFee int64) (bill *model.Waybill, err error) { - db := dao.GetDB() - deliveryFee, _, err := delivery.CalculateOrderDeliveryFee(order, time.Now(), db) - if err == nil { - if err = delivery.CallCreateWaybillPolicy(deliveryFee, maxDeliveryFee, order, model.VendorIDMTPS); err != nil { - return nil, err - } - // 忽略坐标转换错误,即使是转换出错,也只能当成转换成功来处理,底层会有错误日志输出 - lngFloat, latFloat, _ := jxutils.IntCoordinate2MarsStandard(order.ConsigneeLng, order.ConsigneeLat, order.CoordinateType) - billParams := &mtpsapi.CreateOrderByShopParam{ - OrderID: jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID), - DeliveryServiceCode: mtpsapi.DeliveryServiceCodeRapid, - ReceiverName: utils.FilterMb4(order.ConsigneeName), - ReceiverAddress: utils.FilterMb4(order.ConsigneeAddress), - ReceiverPhone: order.ConsigneeMobile, - CoordinateType: model.CoordinateTypeMars, - ReceiverLng: jxutils.StandardCoordinate2Int(lngFloat), - ReceiverLat: jxutils.StandardCoordinate2Int(latFloat), - GoodsValue: jxutils.IntPrice2Standard(order.ActualPayPrice), // todo 超价处理 - GoodsWeight: float64(jxutils.IntWeight2Float(limitOrderWeight(order.Weight))), - // ExpectedDeliveryTime: order.ExpectedDeliveredTime.Unix(), - OrderType: mtpsapi.OrderTypeASAP, - } - if billParams.DeliveryID, err = c.getDeliveryID(order, db); err == nil { - if billParams.ShopID, err = c.getMTPSShopID(order, db); err == nil { - globals.SugarLogger.Debug(billParams.ShopID) - goods := &mtpsapi.GoodsDetail{ - Goods: []*mtpsapi.GoodsItem{}, - } - goodItemMap := map[string]*mtpsapi.GoodsItem{} - for _, sku := range order.Skus { - goodItem := &mtpsapi.GoodsItem{ - GoodCount: sku.Count, - GoodPrice: jxutils.IntPrice2Standard(sku.SalePrice), - } - goodItem.GoodName, goodItem.GoodUnit = jxutils.GetNameAndUnitFromSkuName(sku.SkuName) - // 好像SKU名不能重复,否则会报错,尝试处理一下 - if item, ok := goodItemMap[goodItem.GoodName]; !ok { - goods.Goods = append(goods.Goods, goodItem) - goodItemMap[goodItem.GoodName] = goodItem - } else { - item.GoodCount += goodItem.GoodCount - } - } - // addParams := map[string]interface{}{ - // "note": utils.FilterMb4(order.BuyerComment), - // "goods_detail": string(utils.MustMarshal(goods)), - // "goods_pickup_info": fmt.Sprintf("%s第%d号单", model.VendorChineseNames[order.VendorID], order.OrderSeq), - // "poi_seq": fmt.Sprintf("#%d", order.OrderSeq), - // } - // storeTel := "" - // storeID := jxutils.GetSaleStoreIDFromOrder(order) - // storeDeatail, _ := dao.GetStoreDetail(db, storeID, order.VendorID) - // if storeDeatail.Tel2 != "" { - // storeTel = ",门店电话:" + storeDeatail.Tel2 - // } - billParams.Note = utils.FilterMb4("客户电话:" + order.ConsigneeMobile + "," + order.BuyerComment + ",取货失败或配送遇到问题请联系18048531223,禁止未配送直接完成定单!") - billParams.GoodsDetail = string(utils.MustMarshal(goods)) - billParams.GoodsPickupInfo = fmt.Sprintf("%s第%d号单", model.VendorChineseNames[order.VendorID], order.OrderSeq) - billParams.PoiSeq = fmt.Sprintf("#%d", order.OrderSeq) - if globals.EnableStoreWrite { - result, err2 := api.MtpsAPI.CreateOrderByShop2(billParams) - if err = err2; err == nil { - bill = &model.Waybill{ - VendorOrderID: order.VendorOrderID, - OrderVendorID: order.VendorID, - VendorWaybillID: result.MtPeisongID, - VendorWaybillID2: utils.Int64ToStr(result.DeliveryID), - WaybillVendorID: model.VendorIDMTPS, - DesiredFee: deliveryFee, - } - delivery.OnWaybillCreated(bill) - } else { - globals.SugarLogger.Debugf("CreateWaybill failed, orderID:%s, billParams:%v, error:%v", order.VendorOrderID, billParams, err) - } - } else { - err = fmt.Errorf("测试环境不能真正创建运单") - } - } - } - } - return bill, err -} - -func (c *DeliveryHandler) CancelWaybill(bill *model.Waybill, cancelReasonID int, cancelReason string) (err error) { - // switch cancelReasonID { - // case partner.CancelWaybillReasonNotAcceptIntime: - // cancelReasonID = mtpsapi.CancelReasonRideerMtpsOther - // case partner.CancelWaybillReasonSwitch2SelfFailed: - // cancelReasonID = mtpsapi.CancelReasonMerchantOther - // default: - // cancelReasonID = mtpsapi.CancelReasonRideerOther - // } - cancelReasonID = mtpsapi.CancelReasonMerchantOther - cancelReason = "" - _, err = api.MtpsAPI.CancelOrder(utils.Str2Int64(bill.VendorWaybillID2), bill.VendorWaybillID, cancelReasonID, cancelReason) - return nil -} - -func (c *DeliveryHandler) getDeliveryID(order *model.GoodsOrder, db *dao.DaoDB) (retVal int64, err error) { - // jxorder表当前已经有50多万条记录了,加100万避免冲突 - // 508505 - return order.ID + 1000000, nil -} - -func (c *DeliveryHandler) getMTPSShopID(order *model.GoodsOrder, db *dao.DaoDB) (retVal string, err error) { - saleStoreID := jxutils.GetSaleStoreIDFromOrder(order) - storeCourierList, err2 := dao.GetOpenedStoreCouriersByStoreID(db, saleStoreID, model.VendorIDMTPS) - if err = err2; err != nil && err != orm.ErrNoRows { - return "", err - } - if len(storeCourierList) == 0 { - return "", partner.ErrStoreHaveNoCourier - } - retVal = storeCourierList[0].VendorStoreID - if beego.BConfig.RunMode == "dev" { - retVal = "test_0001" - } - return retVal, nil -} - -func limitOrderWeight(weight int) int { - if weight > maxOrderWeight { - return maxOrderWeight - } - return weight -} - -func (c *DeliveryHandler) ComplaintRider(bill *model.Waybill, resonID int, resonContent string) (err error) { - if globals.EnableStoreWrite { - err = api.MtpsAPI.EvaluateRider(utils.Str2Int64(bill.VendorWaybillID2), bill.VendorWaybillID, 1, resonContent) - } - return err -} - -func (c *DeliveryHandler) GetRidderPosition(ctx *jxcontext.Context, vendorOrgCode, vendorOrderID, vendorWaybillID, vendorWaybillID2 string) (lng, lat float64, err error) { - intLng, intLat, err := api.MtpsAPI.RiderLocation(utils.Str2Int64(vendorWaybillID2), vendorWaybillID) - if err == nil { - lng = jxutils.IntCoordinate2Standard(intLng) - lat = jxutils.IntCoordinate2Standard(intLat) - } - return lng, lat, err -} diff --git a/business/partner/delivery/mtps/waybill_test.go b/business/partner/delivery/mtps/waybill_test.go deleted file mode 100644 index ea4e191c0..000000000 --- a/business/partner/delivery/mtps/waybill_test.go +++ /dev/null @@ -1,36 +0,0 @@ -package mtps - -import ( - "testing" - - _ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals/testinit" -) - -func init() { - testinit.Init() -} - -func TestCreateWaybill(t *testing.T) { - orerID := "817109342000022" - order, _ := partner.CurOrderManager.LoadOrder(orerID, model.VendorIDJD) - // globals.SugarLogger.Debug(order) - c := new(DeliveryHandler) - _, err := c.CreateWaybill(order, nil) - if err != nil { - t.Fatal(err.Error()) - } -} - -func TestCancelWaybill(t *testing.T) { - bill := &model.Waybill{ - VendorWaybillID: "1532332342088966", - VendorWaybillID2: "55", - } - c := new(DeliveryHandler) - if err := c.CancelWaybill(bill, partner.CancelWaybillReasonOther, ""); err != nil { - t.Fatal(err.Error()) - } -} diff --git a/business/partner/partner.go b/business/partner/partner.go deleted file mode 100644 index 030d2fe75..000000000 --- a/business/partner/partner.go +++ /dev/null @@ -1,307 +0,0 @@ -package partner - -import ( - "errors" - "fmt" - "time" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" -) - -const ( - StoreNameSeparator = "-" -) - -const ( - CreatedPeration = "create" - UpdatedPeration = "update" -) - -const ( - CancelWaybillReasonNotAcceptIntime = 1 - CancelWaybillReasonSwitch2SelfFailed = 2 - CancelWaybillReasonOther = 10 -) - -const ( - AfsApproveTypeRefund = 1 // 退款 - AfsApproveTypeReturnGoods = 2 // 退货 - AfsApproveTypeRefused = 3 // 驳回 -) - -const ( - TimerTypeNoOverride = 0 // GetStatusActionConfig 返回表示不修改缺省配置 - TimerTypeByPass = 1 - TimerTypeBaseNow = 2 - TimerTypeBaseStatusTime = 3 - TimerTypeBaseOrderCreatedAt = 4 -) - -type StatusActionParams struct { - TimerType int // 参见上面的相关常量定义 - Timeout time.Duration // 超时时间,0在GetStatusActionConfig返回时表示不修改缺省 - TimeoutGap int // 以秒为单位的随机时间,0在GetStatusActionConfig返回时表示不修改缺省 -} - -type OrderInFoChange struct { -} - -func (s *StatusActionParams) GetRefTimeout(statusTime time.Time, orderCreatedAt time.Time) (timeout time.Duration) { - switch s.TimerType { - case TimerTypeBaseNow: - timeout = s.Timeout - case TimerTypeBaseStatusTime: - timeout = statusTime.Sub(time.Now()) + s.Timeout - case TimerTypeBaseOrderCreatedAt: - timeout = orderCreatedAt.Sub(time.Now()) + s.Timeout - default: - timeout = 0 - } - if timeout < 0 { - timeout = 0 - } - return timeout -} - -var ( - CancelWaybillReasonStrNotAcceptIntime = "没有及时抢单" - CancelWaybillReasonStrSwitch2SelfFailed = "转自送失败" - CancelWaybillReasonStrOrderAlreadyFinished = "订单已经结束" - CancelWaybillReasonStrActive = "操作由人员主动发起" - CancelWaybillReasonNotInStoreOpenTime = "不在门店的营业时间范围内" -) - -var ( - ErrCanNotFindItem = errors.New("没有找到指定的东西") - ErrStoreHaveNoCourier = errors.New("门店没有绑定相应的配送信息") -) - -var ( - CurOrderManager IOrderManager - CurStoreManager IStoreManager - - PurchasePlatformHandlers map[int]IPurchasePlatformHandler - PurchaseOrderHandlers map[int]IPurchasePlatformOrderHandler -) - -type IOrderManager interface { - SaveOrder(order *model.GoodsOrder, isAdjust bool, db *dao.DaoDB) (isDuplicated bool, err error) - - OnOrderNew(order *model.GoodsOrder, orderStatus *model.OrderStatus) (err error) - OnOrderAdjust(order *model.GoodsOrder, orderStatus *model.OrderStatus) (err error) - OnOrderStatusChanged(vendorOrgCode string, orderStatus *model.OrderStatus) (err error) - OnOrderMsg(order *model.GoodsOrder, vendorStatus, remark string) (err error) - - OnWaybillStatusChanged(bill *model.Waybill) (err error) - - CreateAfsOrderFromOrder(vendorOrderID string, vendorID int) (afsOrder *model.AfsOrder, err error) - LoadOrder(vendorOrderID string, vendorID int) (order *model.GoodsOrder, err error) - LoadOrder2(vendorOrderID2 string, vendorID int) (order *model.GoodsOrder, err error) - - LoadOrderFinancial(vendorOrderID string, vendorID int) (order *model.OrderFinancial, err error) - LoadOrderFinancial2(vendorOrderID2 string, vendorID int) (order *model.OrderFinancial, err error) - - UpdateOrderStatusAndDeliveryFlag(order *model.GoodsOrder) (err error) - UpdateOrderFields(order *model.GoodsOrder, fieldList []string) (err error) - LoadStoreDetail(storeID, vendorID int) (storeDetail *dao.StoreDetail, err error) - - LoadWaybill(vendorWaybillID string, waybillVendorID int) (bill *model.Waybill, err error) - OnOrderComments(orderCommentList []*model.OrderComment) (err error) - - SaveOrderFinancialInfo(order *model.OrderFinancial, operation string) (err error) - SaveAfsOrderFinancialInfo(afsOrder *model.AfsOrder) (err error) - - GetOrderWaybillInfo(ctx *jxcontext.Context, vendorOrderID string, vendorID int, isNotEnded, isGetPos bool) (bills []*model.WaybillExt, err error) - - ChangeOrderInfo(order *model.GoodsOrder) (err error) - // afs order - OnAfsOrderAdjust(afsOrder *model.AfsOrder, orderStatus *model.OrderStatus) (err error) - OnAfsOrderNew(afsOrder *model.AfsOrder, orderStatus *model.OrderStatus) (err error) - OnAfsOrderStatusChanged(orderStatus *model.OrderStatus) (err error) - LoadAfsOrder(vendorAfsOrderID string, vendorID int) (afsOrder *model.AfsOrder, err error) - UpdateAfsOrderFields(afsOrder *model.AfsOrder, fieldList []string) (err error) - - GetStatusDuplicatedCount(status *model.OrderStatus) (duplicatedCount int) -} - -type IStoreManager interface { - OnStoreStatusChanged(vendorStoreID string, vendorID int, storeStatus int) (err error) - OnCourierStoreStatusChanged(ctx *jxcontext.Context, vendorStoreID string, vendorID int, auditStatus int) (err error) -} - -// purchase handler中 -// 所有Sync,Refresh开头的函数都必须自己清理sync_status标记 -// 所有非以Sync,Refresh开头的函数不用自己清理sync_status标记(VendorSync统一处理) - -type IPurchasePlatformHandler interface { - IPurchasePlatformActHandler - IPurchasePlatformOrderHandler - - GetVendorID() int - - // 只与平台相关 - GetVendorCategories(ctx *jxcontext.Context) (vendorCats []*model.SkuVendorCategory, err error) - - //////// - // Store - ReadStore(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string) (store *dao.StoreDetail, err error) - UpdateStore(db *dao.DaoDB, storeID int, userName string) (err error) - CreateStore2(db *dao.DaoDB, storeID int, userName string) (vendorStoreID string, err error) - DeleteStore(db *dao.DaoDB, storeID int, userName string) (err error) - GetStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (storeStatus int, err error) - UpdateStoreCustomID(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string, storeID int64) (err error) - - RefreshAllStoresID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) - - UploadImg(ctx *jxcontext.Context, vendorOrgCode, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) -} - -// db *dao.DaoDB, -type IMultipleStoresHandler interface { - IPurchasePlatformHandler - GetAllCategories(ctx *jxcontext.Context, vendorOrgCode string) (cats []*BareCategoryInfo, err error) - - // CreateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) (err error) - // UpdateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) error - // DeleteCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) error - // ReorderCategories(db *dao.DaoDB, parentCatID int, userName string) (err error) - - CreateCategory2(ctx *jxcontext.Context, cat *dao.SkuStoreCatInfo) (err error) - UpdateCategory2(ctx *jxcontext.Context, cat *dao.SkuStoreCatInfo) (err error) - DeleteCategory2(ctx *jxcontext.Context, vendorOrgCode, vendorCatID string) (err error) - ReorderCategories2(ctx *jxcontext.Context, vendorOrgCode, vendorParentCatID string, vendorCatIDList []string) (err error) - - // sku - // CreateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) - // UpdateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) - // DeleteSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) - - // ReadSku(ctx *jxcontext.Context, vendorOrgCode, vendorSkuID string) (skuNameExt *model.SkuNameExt, err error) - CreateSku2(ctx *jxcontext.Context, sku *dao.StoreSkuSyncInfo) (err error) - UpdateSku2(ctx *jxcontext.Context, sku *dao.StoreSkuSyncInfo) (err error) - DeleteSku2(ctx *jxcontext.Context, vendorOrgCode string, sku *StoreSkuInfo) (err error) - - // RefreshAllSkusID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) - - GetSkus(ctx *jxcontext.Context, vendorOrgCode string, skuID int, vendorSkuID string) (skuNameList []*SkuNameInfo, err error) -} - -type ISingleStoreHandler interface { - IPurchasePlatformHandler - ISingleStoreStoreSkuHandler - // SyncStoreCategory(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, isAsync bool) (hint string, err error) - - // RefreshStoresAllSkusID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool, storeIDs []int) (hint string, err error) -} - -type BasePurchasePlatform struct { -} - -func (p *BasePurchasePlatform) GetStatusActionTimeout(order *model.GoodsOrder, statusType, status int) (params *StatusActionParams) { - return params -} - -func (c *BasePurchasePlatform) CanSwitch2SelfDeliver(order *model.GoodsOrder) (isCan bool, err error) { - return true, nil -} - -func init() { - PurchasePlatformHandlers = make(map[int]IPurchasePlatformHandler) - PurchaseOrderHandlers = make(map[int]IPurchasePlatformOrderHandler) - DeliveryPlatformHandlers = make(map[int]*DeliveryPlatformHandlerInfo) -} - -func InitOrderManager(curOrderManager IOrderManager) { - CurOrderManager = curOrderManager -} - -func InitStoreManager(curStoreManager IStoreManager) { - CurStoreManager = curStoreManager -} - -func RegisterPurchasePlatform(handler IPurchasePlatformHandler) { - vendorID := handler.GetVendorID() - if !(model.IsPurchaseVendorExist(vendorID)) { - panic(fmt.Sprintf("purchase vendor:%d is illegal", vendorID)) - } - if _, ok := PurchasePlatformHandlers[vendorID]; ok { - panic(fmt.Sprintf("purchase vendor:%d, already exists", vendorID)) - } - _, isSingleStore := handler.(ISingleStoreHandler) - _, isMultiStore := handler.(IMultipleStoresHandler) - if !isSingleStore && !isMultiStore { - panic(fmt.Sprintf("platform:%d type is wrong!", vendorID)) - } - PurchasePlatformHandlers[vendorID] = handler -} - -func RegisterPurchaseOrderHandler(vendorID int, handler IPurchasePlatformOrderHandler) { - PurchaseOrderHandlers[vendorID] = handler -} - -func GetPurchasePlatformFromVendorID(vendorID int) IPurchasePlatformHandler { - return PurchasePlatformHandlers[vendorID] -} - -func GetPurchaseOrderHandlerFromVendorID(vendorID int) (handler IPurchasePlatformOrderHandler) { - handler = PurchasePlatformHandlers[vendorID] - if handler == nil { - handler = PurchaseOrderHandlers[vendorID] - } - return handler -} - -func GetPurchasePlatformVendorIDs() (vendorIDs []int) { - for k := range PurchasePlatformHandlers { - vendorIDs = append(vendorIDs, k) - } - return vendorIDs -} - -func GetMultiStoreVendorIDs() (vendorIDs []int) { - for k, v := range PurchasePlatformHandlers { - if _, ok := v.(IMultipleStoresHandler); ok { - vendorIDs = append(vendorIDs, k) - } - } - return vendorIDs -} - -func GetSingleStoreVendorIDs() (vendorIDs []int) { - for k, v := range PurchasePlatformHandlers { - if _, ok := v.(ISingleStoreHandler); ok { - vendorIDs = append(vendorIDs, k) - } - } - return vendorIDs -} - -func IsMultiStore(vendorID int) bool { - if _, ok := GetPurchasePlatformFromVendorID(vendorID).(IMultipleStoresHandler); ok { - return true - } - return false -} - -func GetRidderPositionGetter(vendorID int) (handler IRidderPositionGetter) { - if handlerInfo := GetDeliveryPlatformFromVendorID(vendorID); handlerInfo != nil { - if handler, _ = handlerInfo.Handler.(IRidderPositionGetter); handler != nil { - return handler - } - } - handler, _ = GetPurchasePlatformFromVendorID(vendorID).(IRidderPositionGetter) - return handler -} - -func GetWaybillTipUpdater(vendorID int) (handler IAddWaybillTip) { - if handlerInfo := GetDeliveryPlatformFromVendorID(vendorID); handlerInfo != nil { - if handler, _ = handlerInfo.Handler.(IAddWaybillTip); handler != nil { - return handler - } - } - handler, _ = GetPurchasePlatformFromVendorID(vendorID).(IAddWaybillTip) - return handler -} diff --git a/business/partner/partner_act.go b/business/partner/partner_act.go deleted file mode 100644 index e4db7ec86..000000000 --- a/business/partner/partner_act.go +++ /dev/null @@ -1,130 +0,0 @@ -package partner - -import ( - "time" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" -) - -type IActManager interface { - IsVendorActExist(ctx *jxcontext.Context, vendorActID string, vendorID int) (isExist bool) - CreateActFromVendor(ctx *jxcontext.Context, act2 *model.Act2, actStoreSku []*model.ActStoreSku2) (actID int, err error) -} - -type IPurchasePlatformActHandler interface { - // // 如果是单品级活动,actOrderRules为空 - // // 如果是订单级活动,actStoreSku可以为空(表示不限制SKU) - // CreateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSku []*model.ActStoreSku2) (err error) - // UpdateAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSku []*model.ActStoreSku2) (err error) - // // 取消整个京西活动 - // CancelAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreSku []*model.ActStoreSku2) (err error) - - SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSkuList []*model.ActStoreSku2) (err error) -} - -type IPurchasePlatformPageActHandler interface { - GetPageActList(ctx *jxcontext.Context, createdFrom time.Time) (actList []*model.Act2, err error) - GetPageActSkuList(ctx *jxcontext.Context, vendorPageActID string) (actStoreSkuList []*model.ActStoreSku2, err error) -} - -var ( - CurActManager IActManager -) - -func InitActManager(p IActManager) { - CurActManager = p -} - -func SplitActStoreSku(actStoreSkuList []*model.ActStoreSku2) (actStoreSkuMap map[int][]*model.ActStoreSku2) { - actStoreSkuMap = make(map[int][]*model.ActStoreSku2) - for _, v := range actStoreSkuList { - actStoreSkuMap[v.StoreID] = append(actStoreSkuMap[v.StoreID], v) - } - return actStoreSkuMap -} - -func SplitActStoreSku2List(actStoreSkuList []*model.ActStoreSku2) (actStoreSkuListList [][]*model.ActStoreSku2) { - actStoreSkuMap := SplitActStoreSku(actStoreSkuList) - for _, v := range actStoreSkuMap { - actStoreSkuListList = append(actStoreSkuListList, v) - } - return actStoreSkuListList -} - -func Act2ActMap(act *model.Act2) (actMap *model.ActMap) { - actMap = &model.ActMap{} - actMap.ID = act.MapID - return actMap -} - -func ActStoreSku2ActStoreSkuMap(actStoreSku *model.ActStoreSku2) (actStoreSkuMap *model.ActStoreSkuMap) { - actStoreSkuMap = &model.ActStoreSkuMap{ - ModelIDCULD: actStoreSku.ModelIDCULD, - BindID: actStoreSku.MapID, - - ActID: actStoreSku.ActID, - StoreID: actStoreSku.StoreID, - SkuID: actStoreSku.SkuID, - VendorID: actStoreSku.VendorID, - VendorActID: actStoreSku.VendorActID, - SyncStatus: actStoreSku.SyncStatus, - VendorPrice: actStoreSku.VendorPrice, - ActualActPrice: actStoreSku.ActualActPrice, - - EarningPrice: actStoreSku.EarningPrice, - } - actStoreSkuMap.ID = actStoreSku.MapID - return actStoreSkuMap -} - -func Act2Update(ctx *jxcontext.Context, act *model.Act2, syncStatus int) (item *dao.KVUpdateItem) { - kvs := map[string]interface{}{ - model.FieldSyncStatus: 0, - model.FieldUpdatedAt: time.Now(), - model.FieldLastOperator: ctx.GetUserName(), - } - if syncStatus == model.SyncFlagDeletedMask { - kvs[model.FieldDeletedAt] = time.Now() - } else if syncStatus == model.SyncFlagNewMask { - kvs[model.FieldVendorActID] = act.VendorActID - } - item = &dao.KVUpdateItem{ - Item: Act2ActMap(act), - KVs: kvs, - } - return item -} - -func ActStoreSku2Update(ctx *jxcontext.Context, actStoreSkuList []*model.ActStoreSku2, syncStatus int) (items []*dao.KVUpdateItem) { - for _, v := range actStoreSkuList { - v.SyncStatus = 0 - v.UpdatedAt = time.Now() - v.LastOperator = ctx.GetUserName() - kvs := map[string]interface{}{ - model.FieldSyncStatus: v.SyncStatus, - model.FieldUpdatedAt: v.UpdatedAt, - model.FieldLastOperator: v.LastOperator, - } - if syncStatus == model.SyncFlagDeletedMask { - v.DeletedAt = time.Now() - kvs[model.FieldDeletedAt] = v.DeletedAt - } else if syncStatus == model.SyncFlagNewMask { - kvs[model.FieldVendorActID] = v.VendorActID - } - items = append(items, &dao.KVUpdateItem{ - Item: ActStoreSku2ActStoreSkuMap(v), - KVs: kvs, - }) - } - return items -} - -func GetVendorIDsFromActMap(actMap map[int]*model.Act2) (vendorIDs []int) { - for vendorID := range actMap { - vendorIDs = append(vendorIDs, vendorID) - } - return vendorIDs -} diff --git a/business/partner/partner_api.go b/business/partner/partner_api.go deleted file mode 100644 index 386527933..000000000 --- a/business/partner/partner_api.go +++ /dev/null @@ -1,14 +0,0 @@ -package partner - -type IAPIManager interface { - GetAPI(vendorID int, appOrgCode string) interface{} - GetAppOrgCodeList(vendorID int) (appOrgCodeList []string) -} - -var ( - CurAPIManager IAPIManager -) - -func InitAPIManager(curAPIManager IAPIManager) { - CurAPIManager = curAPIManager -} diff --git a/business/partner/partner_delivery.go b/business/partner/partner_delivery.go deleted file mode 100644 index 36a45b563..000000000 --- a/business/partner/partner_delivery.go +++ /dev/null @@ -1,80 +0,0 @@ -package partner - -import ( - "fmt" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" -) - -const ( - WaybillFeeErrCodeCourierNotOpen = 1 //配送门店没有启用 - WaybillFeeErrCodeCourierNotSupported = 2 //配送门店不被系统支持 - WaybillFeeErrCodeCourierForbidden = 3 //配送门店内部禁用 - WaybillFeeErrCodeCourierOthers = 10 //其它错误 -) - -type WaybillFeeInfo struct { - ErrCode int `json:"errCode"` - ErrStr string `json:"errStr"` - RefDeliveryFee int64 `json:"refDeliveryFee"` // 无用,待删除 - RefAddFee int64 `json:"refAddFee"` // 无用,待删除 - DeliveryFee int64 `json:"deliveryFee"` - TimeoutSecond int `json:"timeoutSecond"` // 系统会自动发运单的倒计时 - Waybill *model.Waybill `json:"waybill"` -} - -type CreateWaybillPolicyFunc func(refDeliveryFee, refAddFee, deliveryFee int64) (errStr string) - -type IDeliveryPlatformHandler interface { - GetVendorID() int - - CreateStore(ctx *jxcontext.Context, storeDetail *dao.StoreDetail2) (vendorStoreID string, status int, err error) - GetStore(ctx *jxcontext.Context, storeID int, vendorStoreID string) (storeDetail *dao.StoreDetail2, err error) - IsErrStoreNotExist(err error) bool - IsErrStoreExist(err error) bool - - CreateWaybill(order *model.GoodsOrder, maxDeliveryFee int64) (bill *model.Waybill, err error) - CancelWaybill(bill *model.Waybill, cancelReasonID int, cancelReason string) (err error) - GetWaybillFee(order *model.GoodsOrder) (deliveryFeeInfo *WaybillFeeInfo, err error) - //投诉骑手 - ComplaintRider(bill *model.Waybill, resonID int, resonContent string) (err error) -} - -type IDeliveryUpdateStoreHandler interface { - UpdateStore(ctx *jxcontext.Context, storeDetail *dao.StoreDetail2) (err error) -} - -type DeliveryPlatformHandlerInfo struct { - Handler IDeliveryPlatformHandler - Use4CreateWaybill bool -} - -var ( - DeliveryPlatformHandlers map[int]*DeliveryPlatformHandlerInfo - UseableDeliveryVendorIDs []int -) - -func init() { - DeliveryPlatformHandlers = make(map[int]*DeliveryPlatformHandlerInfo) -} - -func RegisterDeliveryPlatform(handler IDeliveryPlatformHandler, isUse4CreateWaybill bool) { - vendorID := handler.GetVendorID() - if !(model.IsDeliveryVendorExist(vendorID)) { - panic(fmt.Sprintf("delivery vendor:%d is illegal", vendorID)) - } - if _, ok := DeliveryPlatformHandlers[vendorID]; ok { - panic(fmt.Sprintf("delivery vendor:%d, already exists", vendorID)) - } - DeliveryPlatformHandlers[vendorID] = &DeliveryPlatformHandlerInfo{ - Handler: handler, - Use4CreateWaybill: isUse4CreateWaybill, - } - UseableDeliveryVendorIDs = append(UseableDeliveryVendorIDs, vendorID) -} - -func GetDeliveryPlatformFromVendorID(vendorID int) *DeliveryPlatformHandlerInfo { - return DeliveryPlatformHandlers[vendorID] -} diff --git a/business/partner/partner_err.go b/business/partner/partner_err.go deleted file mode 100644 index e4c1e6504..000000000 --- a/business/partner/partner_err.go +++ /dev/null @@ -1,89 +0,0 @@ -package partner - -import ( - "fmt" - - "git.rosy.net.cn/jx-callback/business/model" -) - -const ( - ErrCodeUnknown = 1 - ErrCodeChangePriceFailed = 100 -) - -type ErrorWithCode struct { - errMsg string - intCode int - vendorID int - storeID int - skuID int -} - -func NewErrorCode(errMsg string, code, vendorID int) *ErrorWithCode { - retVal := &ErrorWithCode{ - errMsg: errMsg, - intCode: code, - vendorID: vendorID, - } - return retVal -} - -func (e *ErrorWithCode) SetStoreID(storeID int) { - e.storeID = storeID -} - -func (e *ErrorWithCode) SetSkuID(skuID int) { - e.skuID = skuID -} - -func (e *ErrorWithCode) Error() string { - return fmt.Sprintf("平台:%s, code:%d, %s", model.VendorChineseNames[e.VendorID()], e.intCode, e.errMsg) -} - -func (e *ErrorWithCode) String() string { - return e.Error() -} - -func (e *ErrorWithCode) Code() int { - return e.intCode -} - -func (e *ErrorWithCode) ErrMsg() string { - return e.errMsg -} - -func (e *ErrorWithCode) VendorID() int { - return e.vendorID -} - -func (e *ErrorWithCode) StoreID() int { - return e.storeID -} - -func (e *ErrorWithCode) SkuID() int { - return e.skuID -} - -func IsErrChangePriceFailed(err error) *ErrorWithCode { - if vendorErr, ok := err.(*ErrorWithCode); ok && vendorErr.Code() == ErrCodeChangePriceFailed { - return vendorErr - } - return nil -} - -func IsErrVendorError(err error) *ErrorWithCode { - if vendorErr, ok := err.(*ErrorWithCode); ok { - return vendorErr - } - return nil -} - -func AddVendorInfo2Err(inErr error, vendorID int) (outErr error) { - outErr = inErr - if inErr != nil { - if IsErrVendorError(inErr) == nil { - outErr = NewErrorCode(inErr.Error(), ErrCodeUnknown, vendorID) - } - } - return outErr -} diff --git a/business/partner/partner_order.go b/business/partner/partner_order.go deleted file mode 100644 index dace71dc7..000000000 --- a/business/partner/partner_order.go +++ /dev/null @@ -1,67 +0,0 @@ -package partner - -import ( - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" -) - -type OrderPhoneNumberInfo struct { - VendorOrderID string - PhoneNumber string -} - -type IPurchasePlatformOrderHandler interface { - Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) - GetOrder(vendorOrgCode, vendorOrderID string) (order *model.GoodsOrder, err error) - GetOrderStatus(vendorOrgCode, vendorOrderID string) (status int, err error) - GetStatusActionTimeout(order *model.GoodsOrder, statusType, status int) (params *StatusActionParams) - - AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) - PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) - - AcceptOrRefuseFailedGetOrder(ctx *jxcontext.Context, order *model.GoodsOrder, isAcceptIt bool) (err error) - CallCourier(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) // 取货失败后再次招唤平台配送 - ConfirmReceiveGoods(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) // 投递失败后确认收到退货 - - // 是否可能转商家自送 - CanSwitch2SelfDeliver(order *model.GoodsOrder) (isCan bool, err error) - // 将订单从购物平台配送转为自送 - Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) - - // 将订单从购物平台配送转为自送后又送达 - Swtich2SelfDelivered(order *model.GoodsOrder, userName string) (err error) - - // 完全自送的门店表示开始配送 - SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) - - // 完全自送的门店表示配送完成 - SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) - - GetOrderRealMobile(ctx *jxcontext.Context, order *model.GoodsOrder) (mobile string, err error) - - ReplyOrderComment(ctx *jxcontext.Context, vendorOrgCode string, orderComment *model.OrderComment, replyComment string) (err error) - - AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) - CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) - // order.Skus要包含原始订单中的Sku信息,removedSkuList中是要移除的Sku信息 - AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) - - // 售后 - // 发起全款退款 - RefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) - // 发起部分退款 - PartRefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, refundSkuList []*model.OrderSku, reason string) (err error) - // 审核售后单申请 - AgreeOrRefuseRefund(ctx *jxcontext.Context, order *model.AfsOrder, approveType int, reason string) (err error) - // // 确认收到退货 - ConfirmReceivedReturnGoods(ctx *jxcontext.Context, order *model.AfsOrder) (err error) -} - -type IAddWaybillTip interface { - GetWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2 string) (tipFee int64, err error) - UpdateWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2, cityCode string, tipFee int64) (err error) -} - -type IRidderPositionGetter interface { - GetRidderPosition(ctx *jxcontext.Context, vendorOrgCode, vendorOrderID, vendorWaybillID, vendorWaybillID2 string) (lng, lat float64, err error) -} diff --git a/business/partner/partner_printer.go b/business/partner/partner_printer.go deleted file mode 100644 index d72388153..000000000 --- a/business/partner/partner_printer.go +++ /dev/null @@ -1,89 +0,0 @@ -package partner - -import ( - "fmt" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" -) - -const ( - PrinterStatusUnknown = 0 - PrinterStatusOffline = 1 - PrinterStatusOnlineOK = 2 - PrinterStatusOnlineAbnormal = 3 -) - -const ( - PrintResultSuccess = 0 // 成功 - PrintResultNoPrinter = 1 // 没有配置网络打印机 -) - -const ( - PrinterFontSizeNormal = int8(0) //正常大小 - PrinterFontSizeBig = int8(1) //两倍大小 -) - -var ( - PrinterStatusName = map[int]string{ - PrinterStatusUnknown: "未知", - PrinterStatusOffline: "离线", - PrinterStatusOnlineOK: "正常", - PrinterStatusOnlineAbnormal: "异常", - } -) - -type PrinterStatus struct { - PrintResult int `json:"printResult"` - PrinterStatus int `json:"printerStatus"` - Printed int `json:"printed"` // 已经打印的单数 - Waiting int `json:"waiting"` // 等待打印的单数,超过1一般不太正常 -} - -type BindPrinterResult struct { - PrinterSN string `json:"printerSN"` - PrinterKey string `json:"printerKey"` - PrinterKey2 string `json:"printerKey2"` - ExpiresAt int64 `json:"expiresAt"` -} - -type IPrinterHandler interface { - GetVendorID() int - PrintMsg(ctx *jxcontext.Context, id1, id2, msgTitle, msgContent string) (printerStatus *PrinterStatus, err error) - GetPrinterStatus(ctx *jxcontext.Context, id1, id2 string) (printerStatus *PrinterStatus, err error) - - RegisterPrinter(ctx *jxcontext.Context, id1, id2, printerName string) (newID1, newID2 string, err error) - UnregisterPrinter(ctx *jxcontext.Context, id1, id2 string) (err error) - - BindPrinter(ctx *jxcontext.Context, mapData map[string]interface{}) (bindResult *BindPrinterResult, err error) - RebindPrinter(ctx *jxcontext.Context, lastBindResult *BindPrinterResult) (bindResult *BindPrinterResult, err error) - - PrintOrder(ctx *jxcontext.Context, store *model.Store, order *model.GoodsOrder) (printerStatus *PrinterStatus, err error) - - EmptyPrintList(ctx *jxcontext.Context, id1, id2 string) (err error) - PlayText(ctx *jxcontext.Context, id1, id2, orderID, text string) (printerStatus *PrinterStatus, err error) - SetSound(ctx *jxcontext.Context, id1, id2, sound string) (err error) -} - -var ( - PrinterPlatformHandlers map[int]IPrinterHandler -) - -func init() { - PrinterPlatformHandlers = make(map[int]IPrinterHandler) -} - -func RegisterPrinterPlatform(handler IPrinterHandler) { - vendorID := handler.GetVendorID() - if !(model.IsPrinterVendorExist(vendorID)) { - panic(fmt.Sprintf("printer vendor:%d is illegal", vendorID)) - } - if _, ok := PrinterPlatformHandlers[vendorID]; ok { - panic(fmt.Sprintf("printer vendor:%d, already exists", vendorID)) - } - PrinterPlatformHandlers[vendorID] = handler -} - -func GetPrinterPlatformFromVendorID(vendorID int) IPrinterHandler { - return PrinterPlatformHandlers[vendorID] -} diff --git a/business/partner/partner_store.go b/business/partner/partner_store.go deleted file mode 100644 index f7292476c..000000000 --- a/business/partner/partner_store.go +++ /dev/null @@ -1,20 +0,0 @@ -package partner - -import ( - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model/dao" -) - -type IStoreHandler interface { - GetAllStoresVendorID(ctx *jxcontext.Context, vendorOrgCode string) (vendorStoreIDs []string, err error) - - EnableAutoAcceptOrder(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, isSetEnable bool) (err error) - UpdateStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, status int) (err error) - // opTime格式为整数1130代表11:30 - UpdateStoreOpTime(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, opTimeList []int16) (err error) -} - -// 同步资质信息至平台 -type IStoreSyncQualifyHandler interface { - SyncQualify(ctx *jxcontext.Context, storeDetail *dao.StoreDetail) (err error) -} diff --git a/business/partner/partner_store_sku.go b/business/partner/partner_store_sku.go deleted file mode 100644 index 004d026b2..000000000 --- a/business/partner/partner_store_sku.go +++ /dev/null @@ -1,204 +0,0 @@ -package partner - -import ( - "math" - "regexp" - "time" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" -) - -const ( - // FuncGetStoreSkusBareInfo = 1 // 此接口要求实现为不限制批处理大小的 - FuncUpdateStoreSkusStock = 2 - FuncUpdateStoreSkusStatus = 3 - FuncUpdateStoreSkusPrice = 4 - - FuncGetStoreSkusFullInfo = 6 - FuncCreateStoreSkus = 7 - FuncUpdateStoreSkus = 8 - FuncDeleteStoreSkus = 9 - - FuncCreateActs = 10 - FuncCancelActs = 11 -) - -const ( - UnlimitedBatchSize = math.MaxInt32 - - MaxStoreSkuStock = model.MaxStoreSkuStockQty - UnlimitedStoreSkuStock = -1 -) - -type StoreSkuInfo struct { - SkuID int `json:"skuID,omitempty"` - VendorSkuID string `json:"vendorSkuID,omitempty"` - NameID int `json:"nameID,omitempty"` - VendorNameID string `json:"vendorNameID,omitempty"` - - Stock int `json:"stock,omitempty"` - VendorPrice int64 `json:"price,omitempty"` - Status int `json:"status,omitempty"` - - Seq int `json:"seq,omitempty"` - - ActPrice int64 `json:"actPrice,omitempty"` - VendorActID string `json:"vendorActID,omitempty"` - IsSpecialty int `json:"isSpecialty,omitempty"` - JxPrice int64 `json:"jxPrice,omitempty"` - JxUnitPrice int64 `json:"jxUnitPrice,omitempty"` - VendorSkuID2 string `json:"vendorSkuID2,omitempty"` - JdsStockSwitch int `json:"jdsStockSwitch"` - IsDeletedBySku bool `json:"isDeletedBySku"` -} - -type StoreSkuInfoWithErr struct { - StoreSkuInfo *StoreSkuInfo - CategoryName string - VendoreID int - VendoreName string - StoreID int - SyncType string - ErrMsg string -} - -type SkuInfo struct { - StoreSkuInfo - SkuName string - Comment string - SpecQuality float64 - SpecUnit string - Weight int - ActPrice int64 -} - -type SkuNameInfo struct { - NameID int `json:"nameID,omitempty"` - VendorNameID string `json:"vendorNameID,omitempty"` - - Prefix string - Name string - Description string - Unit string - VendorCatIDList []string - PictureList []string - Status int `json:"status,omitempty"` - YbBarCode string - SkuList []*SkuInfo -} - -type BareStoreSkuInfoList []*StoreSkuInfo - -func (l BareStoreSkuInfoList) GetVendorSkuIDList() (vendorSkuIDList []string) { - for _, v := range l { - if !dao.IsVendorThingIDEmpty(v.VendorSkuID) { - vendorSkuIDList = append(vendorSkuIDList, v.VendorSkuID) - } - } - return vendorSkuIDList -} - -func (l BareStoreSkuInfoList) GetVendorSkuIDIntList() (vendorSkuIDIntList []int64) { - for _, v := range l { - if !dao.IsVendorThingIDEmpty(v.VendorSkuID) { - vendorSkuIDIntList = append(vendorSkuIDIntList, utils.Str2Int64(v.VendorSkuID)) - } - } - return vendorSkuIDIntList -} - -func (l BareStoreSkuInfoList) GetSkuIDList() (skuIDList []int) { - for k, v := range l { - if v.SkuID > 0 { - skuIDList[k] = v.SkuID - } - } - return skuIDList -} - -func (l BareStoreSkuInfoList) Len() int { - return len(l) -} - -func (l BareStoreSkuInfoList) Less(i, j int) bool { - if l[i].Seq != l[j].Seq { - return l[i].Seq < l[j].Seq - } - return l[i].VendorPrice < l[j].VendorPrice -} - -func (l BareStoreSkuInfoList) Swap(i, j int) { - l[i], l[j] = l[j], l[i] -} - -type BareCategoryInfo struct { - VendorCatID string `json:"vendorCatID"` - - Level int `json:"level"` - Name string `json:"name"` - Seq int `json:"seq,omitempty"` - Children []*BareCategoryInfo `json:"children,omitempty"` -} - -// 批处理函数,如果是部分失败的情况会返回失败,successedList中会返回成功的列表 - -type IPurchasePlatformStoreSkuHandler interface { - GetStoreSkusBatchSize(funcID int) int - - ListOrders(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, queryDate time.Time, vendorStoreID string) (vendorOrderIDs []string, err error) - - // 此接口要求实现为不限制批处理大小的 - GetStoreSkusBareInfo(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, storeID int, vendorStoreID string, inStoreSkuList []*StoreSkuInfo) (outStoreSkuList []*StoreSkuInfo, err error) - UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo) (failedList []*StoreSkuInfoWithErr, err error) - UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo, status int) (failedList []*StoreSkuInfoWithErr, err error) - UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo) (failedList []*StoreSkuInfoWithErr, err error) - - CreateStoreSkusAct(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo) (failedList []*StoreSkuInfoWithErr, err error) - CancelActs(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo) (failedList []*StoreSkuInfoWithErr, err error) - UpdateStoreSkusSpecTag(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo) (err error) -} - -type ISingleStoreStoreSkuHandler interface { - IPurchasePlatformStoreSkuHandler - - GetStoreSkusFullInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo) (outSkuNameList []*SkuNameInfo, err error) - CreateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*StoreSkuInfoWithErr, err error) - UpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*StoreSkuInfoWithErr, err error) - DeleteStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo) (failedList []*StoreSkuInfoWithErr, err error) - DeleteStoreAllSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, isContinueWhenError bool) (err error) - IsErrSkuExist(err error) (isExist bool) - IsErrSkuNotExist(err error) (isNotExist bool) - - GetStoreAllCategories(ctx *jxcontext.Context, storeID int, vendorStoreID string) (cats []*BareCategoryInfo, err error) - GetStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID, catName string) (cat *BareCategoryInfo, err error) - CreateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) - UpdateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) - DeleteStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID, vendorCatID string, level int) (err error) - DeleteStoreAllCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, isContinueWhenError bool) (err error) - - IsErrCategoryExist(err error) (isExist bool) - IsErrCategoryNotExist(err error) (isNotExist bool) - - GetSensitiveWordRegexp() *regexp.Regexp -} - -type IStoreSkuSorter interface { - ReorderStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, vendorCatID string, storeSkuList []*StoreSkuInfo) (err error) -} - -func BuildSkuName(skuID int, vendorSkuID string) (skuName *SkuNameInfo) { - return &SkuNameInfo{ - SkuList: []*SkuInfo{ - &SkuInfo{ - StoreSkuInfo: StoreSkuInfo{ - SkuID: skuID, - VendorSkuID: vendorSkuID, - }, - }, - }, - } -} diff --git a/business/partner/pay/pay.go b/business/partner/pay/pay.go deleted file mode 100644 index 246d86afa..000000000 --- a/business/partner/pay/pay.go +++ /dev/null @@ -1,51 +0,0 @@ -package pay - -import ( - "time" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" -) - -type PayOpStatus int - -const ( - OpStatusFailed PayOpStatus = 0 - OpStatusSuccessed PayOpStatus = 1 -) - -type CreatePayParam struct { - PayOrderID string - VendorPayType string - - VendorOrderID string - ProductDesc string - ProductDetail string - FeeType string - TotalFee int - TimeStart time.Time - TimeExpire time.Time - - UserData string -} - -type PayOpResult struct { - Status PayOpStatus - VendorStatus string - ErrMsg string - - ID string - VendorID string - - OriginalData string -} - -type ResponseHandler interface { - OnCreatePay(vendorID int, result *PayOpResult) (err error) - OnRefundPay(vendorID int, result *PayOpResult) (err error) -} - -type IPayPlatformHandler interface { - CreatePay(ctx *jxcontext.Context, param *CreatePayParam, isOffline bool) (prepayID, qrCodeURL string, err error) - ClosePay(ctx *jxcontext.Context, payOrderID, vendorPayOrderID string) (err error) - RefundPay(ctx *jxcontext.Context, payOrderID, vendorPayOrderID, refundID, reason string, totalFee, refundFee int) (vendorRefundID string, err error) -} diff --git a/business/partner/pay/wxpay/callback.go b/business/partner/pay/wxpay/callback.go deleted file mode 100644 index e76447652..000000000 --- a/business/partner/pay/wxpay/callback.go +++ /dev/null @@ -1,60 +0,0 @@ -package wxpay - -import ( - "git.rosy.net.cn/baseapi/platformapi/wxpayapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner/pay" - "git.rosy.net.cn/jx-callback/globals" -) - -func OnCallback(msg *wxpayapi.CallbackMsg) (err error) { - globals.SugarLogger.Debugf("wxpay OnCallback msg:%s", utils.Format4Output(msg, true)) - switch msg.MsgType { - case wxpayapi.MsgTypePay: - err = onWxpayFinished(msg.Data.(*wxpayapi.PayResultMsg)) - case wxpayapi.MsgTypeRefund: - err = onWxpayRefund(msg.Data.(*wxpayapi.RefundResultMsg)) - } - return err -} - -func onWxpayFinished(msg *wxpayapi.PayResultMsg) (err error) { - opResult := &pay.PayOpResult{ - OriginalData: string(utils.MustMarshal(msg)), - } - if msg.ReturnCode == wxpayapi.ResponseCodeSuccess { - opResult.Status = pay.OpStatusSuccessed - opResult.ID = msg.OutTradeNo - if msg.ResultCode == wxpayapi.ResponseCodeSuccess { - opResult.VendorID = msg.TransactionID - } else { - opResult.VendorStatus = msg.ErrCode - opResult.ErrMsg = msg.ErrCodeDes - } - } else { - opResult.Status = pay.OpStatusFailed - } - err = payHandler.responseHandler.OnCreatePay(model.VendorIDWXPay, opResult) - return err -} - -func onWxpayRefund(msg *wxpayapi.RefundResultMsg) (err error) { - opResult := &pay.PayOpResult{ - OriginalData: string(utils.MustMarshal(msg)), - } - if msg.ReturnCode == wxpayapi.ResponseCodeSuccess { - opResult.Status = pay.OpStatusSuccessed - if msg.ResultCode == wxpayapi.ResponseCodeSuccess { - opResult.ID = msg.ReqInfoObj.OutRefundNo - opResult.VendorID = msg.ReqInfoObj.RefundID - } else { - opResult.VendorStatus = msg.ErrCode - opResult.ErrMsg = msg.ErrCodeDes - } - } else { - opResult.Status = pay.OpStatusFailed - } - err = payHandler.responseHandler.OnRefundPay(model.VendorIDWXPay, opResult) - return err -} diff --git a/business/partner/pay/wxpay/wxpay.go b/business/partner/pay/wxpay/wxpay.go deleted file mode 100644 index b0f1d767a..000000000 --- a/business/partner/pay/wxpay/wxpay.go +++ /dev/null @@ -1,74 +0,0 @@ -package wxpay - -import ( - "git.rosy.net.cn/baseapi/platformapi/wxpayapi" - "git.rosy.net.cn/jx-callback/business/auth2/authprovider/weixin" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/partner/pay" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -type PayHandler struct { - responseHandler pay.ResponseHandler -} - -var ( - payHandler *PayHandler -) - -func New(responseHandler pay.ResponseHandler) (handler *PayHandler) { - return &PayHandler{ - responseHandler: responseHandler, - } -} - -func vendorPayType2WxpayType(vendorPayType string) string { - return vendorPayType -} - -func (p *PayHandler) CreatePay(ctx *jxcontext.Context, createParam *pay.CreatePayParam, isOffline bool) (prepayID, qrCodeURL string, err error) { - param := &wxpayapi.CreateOrderParam{ - OutTradeNo: createParam.PayOrderID, - Body: createParam.ProductDesc, - NotifyURL: globals.WxpayNotifyURL, - SpbillCreateIP: ctx.GetRealRemoteIP(), - TradeType: vendorPayType2WxpayType(createParam.VendorPayType), - TotalFee: createParam.TotalFee, - - TimeStart: wxpayapi.Time2PayTime(createParam.TimeStart), - TimeExpire: wxpayapi.Time2PayTime(createParam.TimeExpire), - ProfitSharing: wxpayapi.OptYes, - } - if isOffline { - param.TradeType = wxpayapi.TradeTypeNative - } - if authInfo, err := ctx.GetV2AuthInfo(); err == nil && authInfo.GetAuthType() == weixin.AuthTypeMini { - param.OpenID = authInfo.GetAuthID() - } - if result, err := api.WxpayAPI.CreateUnifiedOrder(param); err == nil { - prepayID = result.PrepayID - qrCodeURL = result.CodeURL - } - return prepayID, qrCodeURL, err -} - -func (p *PayHandler) ClosePay(ctx *jxcontext.Context, payOrderID, vendorPayOrderID string) (err error) { - return api.WxpayAPI.CloseOrder(payOrderID) -} - -func (p *PayHandler) RefundPay(ctx *jxcontext.Context, payOrderID, vendorPayOrderID, refundID, reason string, totalFee, refundFee int) (vendorRefundID string, err error) { - param := &wxpayapi.PayRefundParam{ - OutTradeNo: payOrderID, - NotifyURL: globals.WxpayNotifyURL, - OutRefundNo: refundID, - TotalFee: totalFee, - RefundFee: refundFee, - RefundDesc: wxpayapi.CData(reason), - } - retVal, err := api.WxpayAPI.PayRefund(param) - if err == nil { - vendorRefundID = retVal.RefundID - } - return vendorRefundID, err -} diff --git a/business/partner/printer/feie/feie.go b/business/partner/printer/feie/feie.go deleted file mode 100644 index 95df6cd28..000000000 --- a/business/partner/printer/feie/feie.go +++ /dev/null @@ -1,278 +0,0 @@ -package feie - -import ( - "fmt" - "strings" - "time" - - "git.rosy.net.cn/baseapi/platformapi/feieapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -var ( - CurPrinterHandler *PrinterHandler -) - -type PrinterHandler struct { -} - -func init() { - CurPrinterHandler = new(PrinterHandler) - partner.RegisterPrinterPlatform(CurPrinterHandler) -} - -func (c *PrinterHandler) getOrderContent(order *model.GoodsOrder, storeTel string) (content string) { - expectedDeliveryTime := order.ExpectedDeliveredTime - if utils.IsTimeZero(expectedDeliveryTime) { - expectedDeliveryTime = order.OrderCreatedAt.Add(1 * time.Hour) - } - getCode := "" - if order.VendorID == model.VendorIDEBAI { - getCode = fmt.Sprintf("饿百取货码:%s

\n", jxutils.GetEbaiOrderGetCode(order)) - } - orderFmt := ` -%s

-手机买菜上京西
-极速到家送惊喜
---------------------------------
-下单时间: %s
-预计送达: %s
-订单编号: %s
-
- -%s#%d

-%s
-` + getCode + - `客户: %s
-电话: %s
-地址: %s
-
-客户备注:
-%s
-
- -
-商品明细:
-品名 数量 单价 小计
---------------------------------
` - // 实际支付:%s
- orderParams := []interface{}{ - globals.StoreName, - utils.Time2Str(order.OrderCreatedAt), - utils.Time2Str(expectedDeliveryTime), - order.VendorOrderID, - jxutils.GetVendorName(order.VendorID), - order.OrderSeq, - order.VendorOrderID, - order.ConsigneeName, - order.ConsigneeMobile, - order.ConsigneeAddress, - order.BuyerComment, - // jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice), - } - - for _, sku := range order.Skus { - orderFmt += `%s
` - orderFmt += `%8s%10s%10s
` - orderParams = append(orderParams, sku.SkuName, "x"+utils.Int2Str(sku.Count), jxutils.IntPrice2StandardCurrencyString(sku.SalePrice), jxutils.IntPrice2StandardCurrencyString(sku.SalePrice*int64(sku.Count))) - } - orderFmt += `
-共%d种%d件商品 -
---------------------------------
-商品质量问题请联系:
-%s:%s

-
-更多信息请关注官方微信: %s
-
-

---------------------------------
---------------------------------
-

-` - // http://weixin.qq.com/r/tkkDGzTERmk5rXB49xyk - orderParams = append(orderParams, order.SkuCount, order.GoodsCount, order.StoreName, storeTel, globals.StoreName) - return fmt.Sprintf(strings.Replace(orderFmt, "\n", "", -1), orderParams...) -} - -func (c *PrinterHandler) getOrderContentBig(order *model.GoodsOrder, storeTel string) (content string) { - expectedDeliveryTime := order.ExpectedDeliveredTime - if utils.IsTimeZero(expectedDeliveryTime) { - expectedDeliveryTime = order.OrderCreatedAt.Add(1 * time.Hour) - } - getCode := "" - if order.VendorID == model.VendorIDEBAI { - getCode = fmt.Sprintf("饿百取货码:%s

\n", jxutils.GetEbaiOrderGetCode(order)) - } - orderFmt := ` -%s

-手机买菜上京西
-极速到家送惊喜
---------------------------------
-下单时间: %s


-预计送达: %s


-订单编号: %s
-
- -%s#%d

-%s
-` + getCode + - `客户: %s
-电话: %s
-地址: %s
-
-客户备注:
-%s
-
- -
-商品明细:
-品名数量单价小计
---------------------------------
` - // 实际支付:%s
- orderParams := []interface{}{ - globals.StoreName, - utils.Time2Str(order.OrderCreatedAt), - utils.Time2Str(expectedDeliveryTime), - order.VendorOrderID, - jxutils.GetVendorName(order.VendorID), - order.OrderSeq, - order.VendorOrderID, - order.ConsigneeName, - order.ConsigneeMobile, - order.ConsigneeAddress, - order.BuyerComment, - // jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice), - } - - for _, sku := range order.Skus { - orderFmt += `%s
` - orderFmt += `%s %s %s

` - orderParams = append(orderParams, sku.SkuName, "x"+utils.Int2Str(sku.Count), jxutils.IntPrice2StandardCurrencyString(sku.SalePrice), jxutils.IntPrice2StandardCurrencyString(sku.SalePrice*int64(sku.Count))) - } - orderFmt += `
-共%d种%d件商品 -
---------------------------------
-商品质量问题请联系:
-%s:%s

-
-更多信息请关注官方微信: %s
-
-

---------------------------------
---------------------------------
-

-` - // http://weixin.qq.com/r/tkkDGzTERmk5rXB49xyk - orderParams = append(orderParams, order.SkuCount, order.GoodsCount, order.StoreName, storeTel, globals.StoreName) - return fmt.Sprintf(strings.Replace(orderFmt, "\n", "", -1), orderParams...) -} - -func (c *PrinterHandler) GetVendorID() int { - return model.VendorIDFeiE -} - -func (c *PrinterHandler) PrintMsg(ctx *jxcontext.Context, id1, id2, msgTitle, msgContent string) (printerStatus *partner.PrinterStatus, err error) { - globals.SugarLogger.Debugf("PrintMsg id1:%s", id1) - if id1 != "" { - if globals.EnableStoreWrite { - _, err = api.FeieAPI.PrintMsg(id1, msgContent, 1) - } - if err == nil { - printerStatus, err = c.GetPrinterStatus(ctx, id1, id2) - } - } else { - printerStatus = &partner.PrinterStatus{ - PrintResult: partner.PrintResultNoPrinter, - } - } - return printerStatus, err -} - -func (c *PrinterHandler) GetPrinterStatus(ctx *jxcontext.Context, printerSN, printerKey string) (printerStatus *partner.PrinterStatus, err error) { - tmpStatus, err := api.FeieAPI.QueryPrinterStatus(printerSN) - if err == nil { - printerStatus = &partner.PrinterStatus{ - PrinterStatus: tmpStatus, - PrintResult: partner.PrintResultSuccess, - } - printerStatus.Printed, printerStatus.Waiting, err = api.FeieAPI.QueryOrderInfoByDate(printerSN, time.Now()) - } - return printerStatus, err -} - -func (c *PrinterHandler) PrintOrder(ctx *jxcontext.Context, store *model.Store, order *model.GoodsOrder) (printerStatus *partner.PrinterStatus, err error) { - globals.SugarLogger.Debugf("feie PrintOrderByOrder orderID:%s, storeID:%d", order.VendorOrderID, store.ID) - content := "" - if store.PrinterFontSize == partner.PrinterFontSizeBig { - content = c.getOrderContentBig(order, store.Tel1) - } else { - content = c.getOrderContent(order, store.Tel1) - } - return c.PrintMsg(ctx, store.PrinterSN, store.PrinterKey, order.VendorOrderID, content) -} - -func (c *PrinterHandler) RegisterPrinter(ctx *jxcontext.Context, printerSN, printerKey, printerName string) (notUsed1, notUsed2 string, err error) { - var no map[string]string - if globals.EnableStoreWrite { - _, no, err = api.FeieAPI.PrinterAddList([]*feieapi.PrinterInfo{ - &feieapi.PrinterInfo{ - SN: printerSN, - Key: printerKey, - Name: printerName, - }, - }) - } else { - no = make(map[string]string) - } - if err == nil { - if no[printerSN] != "" { - if no[printerSN] == feieapi.ErrMsgAlredyAdded { - api.FeieAPI.PrinterEdit(printerSN, printerName, "") - } else { - err = fmt.Errorf("添加打印机出错:%s", no[printerSN]) - } - } - } - return "", "", err -} - -func (c *PrinterHandler) UnregisterPrinter(ctx *jxcontext.Context, printerSN, notUsed string) (err error) { - if globals.EnableStoreWrite { - _, _, err = api.FeieAPI.PrinterDelList([]string{printerSN}) - } - return err -} - -func (c *PrinterHandler) BindPrinter(ctx *jxcontext.Context, mapData map[string]interface{}) (bindResult *partner.BindPrinterResult, err error) { - return nil, fmt.Errorf("%s打印机当前不支持扫码绑定", model.VendorChineseNames[model.VendorIDFeiE]) -} - -func (c *PrinterHandler) RebindPrinter(ctx *jxcontext.Context, lastBindResult *partner.BindPrinterResult) (bindResult *partner.BindPrinterResult, err error) { - return nil, fmt.Errorf("%s打印机当前不支持扫码绑定", model.VendorChineseNames[model.VendorIDFeiE]) -} - -func (c *PrinterHandler) EmptyPrintList(ctx *jxcontext.Context, id1, id2 string) (err error) { - if globals.EnableStoreWrite { - err = api.FeieAPI.DelPrinterSqs(id1) - } - return err -} - -func (c *PrinterHandler) PlayText(ctx *jxcontext.Context, id1, id2, orderID, text string) (printerStatus *partner.PrinterStatus, err error) { - return c.GetPrinterStatus(ctx, id1, id2) -} - -func (c *PrinterHandler) SetSound(ctx *jxcontext.Context, id1, id2, sound string) (err error) { - if globals.EnableStoreWrite { - err = api.FeieAPI.SetSound(id1, sound) - } - return err -} diff --git a/business/partner/printer/feie/feie_test.go b/business/partner/printer/feie/feie_test.go deleted file mode 100644 index d4088eab6..000000000 --- a/business/partner/printer/feie/feie_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package feie - -import ( - "testing" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - - "git.rosy.net.cn/baseapi/utils" - - "git.rosy.net.cn/jx-callback/business/partner" - - _ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" - _ "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler/defsch" - "git.rosy.net.cn/jx-callback/globals/testinit" -) - -func init() { - testinit.Init() -} - -func TestPrintMsg(t *testing.T) { - orderID := "910838879000442" - vendorID := 0 - order, err := partner.CurOrderManager.LoadOrder(orderID, vendorID) - if err != nil { - t.Fatal(err) - } - - context := CurPrinterHandler.getOrderContent(order, "13412345678") - //context := CurPrinterHandler.getOrderContentBig(order, "13412345678") - status, err := CurPrinterHandler.PrintMsg(jxcontext.AdminCtx, "218510310", "ztdpveyg", "test", context) - t.Log(utils.Format4Output(status, false)) - if err != nil { - t.Fatal(err) - } -} - -func TestRegisterPrinter(t *testing.T) { - newID1, newID2, err := CurPrinterHandler.RegisterPrinter(jxcontext.AdminCtx, "218510310", "ztdpveyg", "title") - t.Log(newID1 + "," + newID2) - if err != nil { - t.Fatal(err) - } -} diff --git a/business/partner/printer/xiaowm/xiaowm.go b/business/partner/printer/xiaowm/xiaowm.go deleted file mode 100644 index bad1498fd..000000000 --- a/business/partner/printer/xiaowm/xiaowm.go +++ /dev/null @@ -1,368 +0,0 @@ -package xiaowm - -import ( - "fmt" - "strings" - "time" - - "git.rosy.net.cn/baseapi/platformapi/xiaowmapi" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -var ( - CurPrinterHandler *PrinterHandler -) - -type PrinterHandler struct { -} - -func init() { - CurPrinterHandler = new(PrinterHandler) - partner.RegisterPrinterPlatform(CurPrinterHandler) -} - -func (c *PrinterHandler) getOrderContent(order *model.GoodsOrder, storeTel string) (content string) { - expectedDeliveryTime := order.ExpectedDeliveredTime - if utils.IsTimeZero(expectedDeliveryTime) { - expectedDeliveryTime = order.OrderCreatedAt.Add(1 * time.Hour) - } - getCode := "" - if order.VendorID == model.VendorIDEBAI { - getCode = fmt.Sprintf("饿百取货码:%s**\n", jxutils.GetEbaiOrderGetCode(order)) - } - buyerComment := order.BuyerComment - if buyerComment == "" { - buyerComment = " " - } - orderFmt := ` - %s** - 手机买菜上京西* - 极速到家送惊喜* -------------------------------* -下单时间: %s* -预计送达: %s* -订单编号: %s* -* -%s\#%d** -%s* -` + getCode + - `客户: %s* -电话: %s* -地址: %s* -* -客户备注: * -%s* -商品明细: * -品名 数量 单价 小计 ---------------------------------* -` - // 实际支付: %s* - orderParams := []interface{}{ - globals.StoreName, - utils.Time2Str(order.OrderCreatedAt), - utils.Time2Str(expectedDeliveryTime), - order.VendorOrderID, - jxutils.GetVendorName(order.VendorID), - order.OrderSeq, - order.VendorOrderID, - order.ConsigneeName, - order.ConsigneeMobile, - order.ConsigneeAddress, - buyerComment, - // jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice), - } - for _, sku := range order.Skus { - orderFmt += `%s*` - orderFmt += `%8s%10s%10s*` - orderParams = append(orderParams, sku.SkuName, "x"+utils.Int2Str(sku.Count), jxutils.IntPrice2StandardCurrencyString(sku.SalePrice), jxutils.IntPrice2StandardCurrencyString(sku.SalePrice*int64(sku.Count))) - } - orderFmt += ` -* -共%d种%d件商品* ---------------------------------* -商品质量问题请联系:* -%s:%s* -* -更多信息请关注官方微信: %s* --------------------------------- --------------------------------- -** -` - // http://weixin.qq.com/r/tkkDGzTERmk5rXB49xyk - orderParams = append(orderParams, order.SkuCount, order.GoodsCount, order.StoreName, storeTel, globals.StoreName) - content = fmt.Sprintf(strings.Replace(orderFmt, "\n", "", -1), escapeString4Printer(orderParams)...) - // globals.SugarLogger.Debugf("xiaowm orderParams:%s\n", utils.Format4Output(orderParams, false)) - // globals.SugarLogger.Debugf("xiaowm getOrderContent:%s\n", content) - return content -} - -func (c *PrinterHandler) getOrderContentBig(order *model.GoodsOrder, storeTel string) (content string) { - expectedDeliveryTime := order.ExpectedDeliveredTime - if utils.IsTimeZero(expectedDeliveryTime) { - expectedDeliveryTime = order.OrderCreatedAt.Add(1 * time.Hour) - } - getCode := "" - if order.VendorID == model.VendorIDEBAI { - getCode = fmt.Sprintf("饿百取货码:%s**\n", jxutils.GetEbaiOrderGetCode(order)) - } - buyerComment := order.BuyerComment - if buyerComment == "" { - buyerComment = " " - } - orderFmt := ` - %s** - 手机买菜上京西* - 极速到家送惊喜* -------------------------------* -下单时间: %s** -预计送达: %s** -订单编号: %s* -* -%s\#%d* -%s* -` + getCode + - `客户: %s* -电话: %s* -地址: %s* -* -客户备注: * -%s* -商品明细: * -品名数量单价小计* ---------------------------------* -` - // 实际支付: %s* - orderParams := []interface{}{ - globals.StoreName, - utils.Time2Str(order.OrderCreatedAt), - utils.Time2Str(expectedDeliveryTime), - order.VendorOrderID, - jxutils.GetVendorName(order.VendorID), - order.OrderSeq, - order.VendorOrderID, - order.ConsigneeName, - order.ConsigneeMobile, - order.ConsigneeAddress, - buyerComment, - // jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice), - } - for _, sku := range order.Skus { - orderFmt += `%s*` - orderFmt += `%s %s %s*` - orderParams = append(orderParams, sku.SkuName, "x"+utils.Int2Str(sku.Count), jxutils.IntPrice2StandardCurrencyString(sku.SalePrice), jxutils.IntPrice2StandardCurrencyString(sku.SalePrice*int64(sku.Count))) - } - orderFmt += ` -共%d种%d件商品* ---------------------------------* -商品质量问题请联系:* -%s:%s* -* -更多信息请关注官方微信: %s* --------------------------------- --------------------------------- -** -` - // http://weixin.qq.com/r/tkkDGzTERmk5rXB49xyk - orderParams = append(orderParams, order.SkuCount, order.GoodsCount, order.StoreName, storeTel, globals.StoreName) - content = fmt.Sprintf(strings.Replace(orderFmt, "\n", "", -1), escapeString4Printer(orderParams)...) - // globals.SugarLogger.Debugf("xiaowm orderParams:%s\n", utils.Format4Output(orderParams, false)) - // globals.SugarLogger.Debugf("xiaowm getOrderContent:%s\n", content) - return content -} - -func (c *PrinterHandler) getOrderContent2(order *model.GoodsOrder, storeTel string) (content string) { - expectedDeliveryTime := order.ExpectedDeliveredTime - if utils.IsTimeZero(expectedDeliveryTime) { - expectedDeliveryTime = order.OrderCreatedAt.Add(1 * time.Hour) - } - getCode := "" - if order.VendorID == model.VendorIDEBAI { - getCode = fmt.Sprintf("|7饿百取货码:%s\n\n", jxutils.GetEbaiOrderGetCode(order)) - } - buyerComment := order.BuyerComment - if buyerComment == "" { - buyerComment = " " - } - orderFmt := ` -|7 %s -|5 手机买菜上京西 -|5 极速到家送惊喜 -|5-------------------------------- -|5下单时间: %s -|5预计送达: %s -|5订单编号: %s -|5 -|7%s\#%d -` + getCode + `|5 -|2%s -|5客户: %s -|5电话: %s -|5地址: %s -|5 -|5客户备注: -|7%s -|5 -|5 -|5商品明细: -|5品名 数量 -|5-------------------------------- -` - // |6实际支付: %s - orderParams := []interface{}{ - globals.StoreName, - utils.Time2Str(order.OrderCreatedAt), - utils.Time2Str(expectedDeliveryTime), - order.VendorOrderID, - jxutils.GetVendorName(order.VendorID), - order.OrderSeq, - order.VendorOrderID, - order.ConsigneeName, - order.ConsigneeMobile, - order.ConsigneeAddress, - buyerComment, - // jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice), - } - for _, sku := range order.Skus { - orderFmt += `|5%s` - orderFmt += `|5%8s` - orderParams = append(orderParams, sku.SkuName, "x"+utils.Int2Str(sku.Count)) - // jxutils.IntPrice2StandardCurrencyString(sku.SalePrice), jxutils.IntPrice2StandardCurrencyString(sku.SalePrice*int64(sku.Count)) - } - orderFmt += ` -|5 -|6共%d种%d件商品 -|5-------------------------------- -|5商品质量问题请联系: -|5%s:%s -|5 -|5更多信息请关注官方微信: %s -|5-------------------------------- -|5-------------------------------- -` - orderParams = append(orderParams, order.SkuCount, order.GoodsCount, order.StoreName, storeTel, globals.StoreName) - return fmt.Sprintf(orderFmt, escapeString4Printer(orderParams)...) -} - -func (c *PrinterHandler) GetVendorID() int { - return model.VendorIDXiaoWM -} - -func (c *PrinterHandler) PrintMsg(ctx *jxcontext.Context, printerNumber, printerToken, msgTitle, msgContent string) (printerStatus *partner.PrinterStatus, err error) { - globals.SugarLogger.Debugf("PrintMsg printerNumber:%s", printerNumber) - if printerNumber != "" { - if globals.EnableStoreWrite { - _, err = api.XiaoWMAPI.SendMsg(printerNumber, printerToken, msgContent) - } - if err == nil { - printerStatus, err = c.GetPrinterStatus(ctx, printerNumber, printerToken) - } - } else { - printerStatus = &partner.PrinterStatus{ - PrintResult: partner.PrintResultNoPrinter, - } - } - return printerStatus, err -} - -func (c *PrinterHandler) GetPrinterStatus(ctx *jxcontext.Context, printerNumber, printerToken string) (printerStatus *partner.PrinterStatus, err error) { - runningState, paperState, err := api.XiaoWMAPI.GetPrinterStatus(printerNumber, printerToken) - if err == nil { - printerStatus = &partner.PrinterStatus{ - PrintResult: partner.PrintResultSuccess, - } - if runningState == xiaowmapi.RunningStateOffline { - printerStatus.PrinterStatus = partner.PrinterStatusOffline - } else { - if paperState == xiaowmapi.PaperStateLackPaper { - printerStatus.PrinterStatus = partner.PrinterStatusOnlineAbnormal - } else { - printerStatus.PrinterStatus = partner.PrinterStatusOnlineOK - } - } - } - return printerStatus, err -} - -func (c *PrinterHandler) PrintOrder(ctx *jxcontext.Context, store *model.Store, order *model.GoodsOrder) (printerStatus *partner.PrinterStatus, err error) { - globals.SugarLogger.Debugf("xiaowm PrintOrderByOrder orderID:%s, storeID:%d", order.VendorOrderID, store.ID) - var content string - if isV500(store.PrinterSN) { - content = c.getOrderContent2(order, store.Tel1) - } else { - if store.PrinterFontSize == partner.PrinterFontSizeBig { - content = c.getOrderContentBig(order, store.Tel1) - } else { - content = c.getOrderContent(order, store.Tel1) - } - } - return c.PrintMsg(ctx, store.PrinterSN, store.PrinterKey, order.VendorOrderID, content) -} - -func isV500(printerNo string) bool { - printerNoNum := utils.Str2Int64WithDefault("1"+printerNo, 0) - return printerNoNum > 1000000000 -} - -func (c *PrinterHandler) RegisterPrinter(ctx *jxcontext.Context, printerNumber, notUsed, printerName string) (newID1, printerToken string, err error) { - globals.SugarLogger.Debugf("xiaowm RegisterPrinter printerNumber:%s", printerNumber) - if printerNumber == "" { //len(printerNumber) != len("7JizmSyiXNzkggaqU") { - err = fmt.Errorf("外卖管家打印机设备编号:%s长度不合法", printerNumber) - } else { - if globals.EnableStoreWrite { - printerToken, err = api.XiaoWMAPI.AuthPrinter(printerNumber, "", "") - } - if err == nil { - if _, err = c.GetPrinterStatus(ctx, printerNumber, printerToken); err != nil { - if globals.EnableStoreWrite { - c.UnregisterPrinter(ctx, printerNumber, printerToken) - } - } - } - } - globals.SugarLogger.Debugf("xiaowm RegisterPrinter printerNumber:%s, error:%v", printerNumber, err) - return "", printerToken, err -} - -func (c *PrinterHandler) UnregisterPrinter(ctx *jxcontext.Context, printerNumber, printerToken string) (err error) { - if globals.EnableStoreWrite { - err = api.XiaoWMAPI.DelPrinter(printerNumber, printerToken) - } - return err -} - -func escapeString4Printer(params []interface{}) []interface{} { - for k, v := range params { - if vStr, ok := v.(string); ok { - vStr = strings.Replace(vStr, "*", "\\*", -1) - params[k] = strings.Replace(vStr, "#", "\\#", -1) - } - } - return params -} - -func (c *PrinterHandler) BindPrinter(ctx *jxcontext.Context, mapData map[string]interface{}) (bindResult *partner.BindPrinterResult, err error) { - return nil, fmt.Errorf("%s打印机当前不支持扫码绑定", model.VendorChineseNames[model.VendorIDXiaoWM]) -} - -func (c *PrinterHandler) RebindPrinter(ctx *jxcontext.Context, lastBindResult *partner.BindPrinterResult) (bindResult *partner.BindPrinterResult, err error) { - return nil, fmt.Errorf("%s打印机当前不支持扫码绑定", model.VendorChineseNames[model.VendorIDXiaoWM]) -} - -func (c *PrinterHandler) EmptyPrintList(ctx *jxcontext.Context, id1, id2 string) (err error) { - return err -} - -func (c *PrinterHandler) PlayText(ctx *jxcontext.Context, id1, id2, orderID, text string) (printerStatus *partner.PrinterStatus, err error) { - return c.GetPrinterStatus(ctx, id1, id2) -} - -func (c *PrinterHandler) SetSound(ctx *jxcontext.Context, id1, id2, sound string) (err error) { - return fmt.Errorf("%s打印机当前不支持设置声音", model.VendorChineseNames[model.VendorIDXiaoWM]) -} diff --git a/business/partner/printer/xiaowm/xiaowm_test.go b/business/partner/printer/xiaowm/xiaowm_test.go deleted file mode 100644 index 50d62c110..000000000 --- a/business/partner/printer/xiaowm/xiaowm_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package xiaowm - -import ( - "testing" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - - "git.rosy.net.cn/baseapi/utils" - - "git.rosy.net.cn/jx-callback/business/partner" - - _ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" - _ "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler/defsch" - "git.rosy.net.cn/jx-callback/globals/testinit" -) - -func init() { - testinit.Init() -} - -func TestPrintMsg(t *testing.T) { - orderID := "910838879000442" - vendorID := 0 - order, err := partner.CurOrderManager.LoadOrder(orderID, vendorID) - if err != nil { - t.Fatal(err) - } - - // context := CurPrinterHandler.getOrderContent(order, "13412345678") - context := CurPrinterHandler.getOrderContentBig(order, "13412345678") - status, err := CurPrinterHandler.PrintMsg(jxcontext.AdminCtx, "7JizmSyiXNzkggaqU", "177f213277dd842ba2b53f6c926a48ea", "test", context) - t.Log(utils.Format4Output(status, false)) - if err != nil { - t.Fatal(err) - } -} - -func TestRegisterPrinter(t *testing.T) { - newID1, newID2, err := CurPrinterHandler.RegisterPrinter(jxcontext.AdminCtx, "7JizmSyiXNzkggaqU", "", "title") - t.Log(newID1 + "," + newID2) - if err != nil { - t.Fatal(err) - } -} diff --git a/business/partner/printer/yilianyun/yilianyun.go b/business/partner/printer/yilianyun/yilianyun.go deleted file mode 100644 index c6fa09a19..000000000 --- a/business/partner/printer/yilianyun/yilianyun.go +++ /dev/null @@ -1,291 +0,0 @@ -package yilianyun - -import ( - "fmt" - "strings" - "time" - - "git.rosy.net.cn/baseapi/platformapi/yilianyunapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -var ( - CurPrinterHandler *PrinterHandler -) - -type PrinterHandler struct { -} - -func init() { - CurPrinterHandler = new(PrinterHandler) - partner.RegisterPrinterPlatform(CurPrinterHandler) -} - -func (c *PrinterHandler) getOrderContent(order *model.GoodsOrder, storeTel string) (content string) { - expectedDeliveryTime := order.ExpectedDeliveredTime - if utils.IsTimeZero(expectedDeliveryTime) { - expectedDeliveryTime = order.OrderCreatedAt.Add(1 * time.Hour) - } - getCode := "" - if order.VendorID == model.VendorIDEBAI { - getCode = fmt.Sprintf("饿百取货码:%s\\n\n", jxutils.GetEbaiOrderGetCode(order)) - } - //TODO 去掉单价和小计,2020-06-18 - orderFmt := ` -
%s
\n\n -
手机买菜上京西
-
极速到家送惊喜
\n --------------------------------- -下单时间: %s\n -预计送达: %s\n -订单编号: %s\n -\n -%s#%d\n\n -%s -` + getCode + `\n -客户: %s\n -电话: %s\n -地址: %s\n -\n -客户备注: \n -%s\n -\n -\n -商品明细: \n -品名 数量 单价 小计\n ---------------------------------\n` - // 实际支付:%s\n - orderParams := []interface{}{ - globals.StoreName, - utils.Time2Str(order.OrderCreatedAt), - utils.Time2Str(expectedDeliveryTime), - order.VendorOrderID, - jxutils.GetVendorName(order.VendorID), - order.OrderSeq, - order.VendorOrderID, - order.ConsigneeName, - order.ConsigneeMobile, - order.ConsigneeAddress, - order.BuyerComment, - // jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice), - } - - for _, sku := range order.Skus { - orderFmt += `%s\n` - orderFmt += `%8s%10s%10s\n` - orderParams = append(orderParams, sku.SkuName, "x"+utils.Int2Str(sku.Count), jxutils.IntPrice2StandardCurrencyString(sku.SalePrice), jxutils.IntPrice2StandardCurrencyString(sku.SalePrice*int64(sku.Count))) - } - orderFmt += `\n -共%d种%d件商品 -\n ---------------------------------\n -
商品质量问题请联系:
-
%s:%s
\n -更多信息请关注官方微信: %s\n ---------------------------------\n ---------------------------------\n -` - // http://weixin.qq.com/r/tkkDGzTERmk5rXB49xyk - orderParams = append(orderParams, order.SkuCount, order.GoodsCount, order.StoreName, storeTel, globals.StoreName) - return strings.Replace(fmt.Sprintf(strings.Replace(orderFmt, "\n", "", -1), orderParams...), "\\n", "\r\n", -1) -} - -func (c *PrinterHandler) getOrderContentBig(order *model.GoodsOrder, storeTel string) (content string) { - expectedDeliveryTime := order.ExpectedDeliveredTime - if utils.IsTimeZero(expectedDeliveryTime) { - expectedDeliveryTime = order.OrderCreatedAt.Add(1 * time.Hour) - } - getCode := "" - if order.VendorID == model.VendorIDEBAI { - getCode = fmt.Sprintf("饿百取货码:%s\\n\n", jxutils.GetEbaiOrderGetCode(order)) - } - orderFmt := ` -
%s
\n\n -
手机买菜上京西
-
极速到家送惊喜
\n --------------------------------- -下单时间: %s\n\n -预计送达: %s\n\n -订单编号: %s\n -\n -%s#%d\n\n -%s -` + getCode + `\n -客户: %s\n -电话: %s\n -地址: %s\n -\n -客户备注: \n -%s\n -\n -\n -商品明细: \n -品名数量单价小计\n ---------------------------------\n` - // 实际支付:%s\n - orderParams := []interface{}{ - globals.StoreName, - utils.Time2Str(order.OrderCreatedAt), - utils.Time2Str(expectedDeliveryTime), - order.VendorOrderID, - jxutils.GetVendorName(order.VendorID), - order.OrderSeq, - order.VendorOrderID, - order.ConsigneeName, - order.ConsigneeMobile, - order.ConsigneeAddress, - order.BuyerComment, - // jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice), - } - - for _, sku := range order.Skus { - orderFmt += `%s\n` - orderFmt += `%s %s %s\n\n` - orderParams = append(orderParams, sku.SkuName, "x"+utils.Int2Str(sku.Count), jxutils.IntPrice2StandardCurrencyString(sku.SalePrice), jxutils.IntPrice2StandardCurrencyString(sku.SalePrice*int64(sku.Count))) - } - orderFmt += `\n -共%d种%d件商品 -\n ---------------------------------\n -
商品质量问题请联系:
-
%s:%s
\n -更多信息请关注官方微信: %s\n ---------------------------------\n ---------------------------------\n -` - // http://weixin.qq.com/r/tkkDGzTERmk5rXB49xyk - orderParams = append(orderParams, order.SkuCount, order.GoodsCount, order.StoreName, storeTel, globals.StoreName) - return strings.Replace(fmt.Sprintf(strings.Replace(orderFmt, "\n", "", -1), orderParams...), "\\n", "\r\n", -1) -} - -func (c *PrinterHandler) GetVendorID() int { - return model.VendorIDYiLianYun -} - -func (c *PrinterHandler) PrintMsg(ctx *jxcontext.Context, machineCode, possibleToken, msgTitle, msgContent string) (printerStatus *partner.PrinterStatus, err error) { - globals.SugarLogger.Debugf("PrintMsg machineCode:%s", machineCode) - if machineCode != "" { - if globals.EnableStoreWrite { - err = getApiByToken(possibleToken).PrintMsgWithToken(machineCode, msgTitle, msgContent, possibleToken) - } - if err == nil { - printerStatus, err = c.GetPrinterStatus(ctx, machineCode, possibleToken) - } - } else { - printerStatus = &partner.PrinterStatus{ - PrintResult: partner.PrintResultNoPrinter, - } - } - return printerStatus, err -} - -func (c *PrinterHandler) GetPrinterStatus(ctx *jxcontext.Context, machineCode, possibleToken string) (printerStatus *partner.PrinterStatus, err error) { - status, err := getApiByToken(possibleToken).GetPrintStatusWithToken(machineCode, possibleToken) - if err == nil { - printerStatus = &partner.PrinterStatus{ - PrintResult: partner.PrintResultSuccess, - } - if status == yilianyunapi.PrintStatusOffline { - printerStatus.PrinterStatus = partner.PrinterStatusOffline - } else if status == yilianyunapi.PrintStatusOnline { - printerStatus.PrinterStatus = partner.PrinterStatusOnlineOK - } else { - printerStatus.PrinterStatus = partner.PrinterStatusOnlineAbnormal - } - } - return printerStatus, err -} - -func (c *PrinterHandler) PrintOrder(ctx *jxcontext.Context, store *model.Store, order *model.GoodsOrder) (printerStatus *partner.PrinterStatus, err error) { - globals.SugarLogger.Debugf("yilianyun PrintOrderByOrder orderID:%s, storeID:%d", order.VendorOrderID, store.ID) - content := "" - if store.PrinterFontSize == partner.PrinterFontSizeBig { - content = c.getOrderContentBig(order, store.Tel1) - } else { - content = c.getOrderContent(order, store.Tel1) - } - return c.PrintMsg(ctx, store.PrinterSN, store.PrinterKey, order.VendorOrderID, content) -} - -func (c *PrinterHandler) RegisterPrinter(ctx *jxcontext.Context, machineCode, secret, printerName string) (notUsed1, notUsed2 string, err error) { - if globals.EnableStoreWrite { - err = api.YilianyunAPI.AddPrinter(machineCode, secret, printerName) - } - return "", "", err -} - -func (c *PrinterHandler) UnregisterPrinter(ctx *jxcontext.Context, machineCode, notUsed string) (err error) { - if globals.EnableStoreWrite { - err = api.YilianyunAPI.DeletePrinter(machineCode) - } - return err -} - -func (c *PrinterHandler) BindPrinter(ctx *jxcontext.Context, mapData map[string]interface{}) (bindResult *partner.BindPrinterResult, err error) { - machineCode := utils.Interface2String(mapData["machineCode"]) - qrKey := utils.Interface2String(mapData["qrKey"]) - if machineCode == "" || qrKey == "" { - return nil, fmt.Errorf("易联云扫描数据格式不正确") - } - tokenInfo, err := api.YilianyunAPI2.GetPrinterToken(machineCode, qrKey) - if err != nil { - return nil, err - } - return yilianyunToken2BindResult(tokenInfo), nil -} - -func (c *PrinterHandler) RebindPrinter(ctx *jxcontext.Context, lastBindResult *partner.BindPrinterResult) (bindResult *partner.BindPrinterResult, err error) { - var tokenInfo *yilianyunapi.TokenInfo - if globals.EnableStoreWrite { - tokenInfo, err = api.YilianyunAPI2.RefreshToken(lastBindResult.PrinterKey2) - } else { - tokenInfo = &yilianyunapi.TokenInfo{} - } - if err == nil { - bindResult = yilianyunToken2BindResult(tokenInfo) - } - return bindResult, err -} - -func yilianyunToken2BindResult(tokenInfo *yilianyunapi.TokenInfo) (bindResult *partner.BindPrinterResult) { - return &partner.BindPrinterResult{ - PrinterSN: tokenInfo.MachineCode, - PrinterKey: tokenInfo.AccessToken, - PrinterKey2: tokenInfo.RefreshToken, - ExpiresAt: time.Now().Add(time.Duration(tokenInfo.ExpiresIn) * time.Second).Unix(), - } -} - -func getApiByToken(possibleToken string) *yilianyunapi.API { - if yilianyunapi.IsStrToken(possibleToken) { - return api.YilianyunAPI2 - } - return api.YilianyunAPI -} - -func (c *PrinterHandler) EmptyPrintList(ctx *jxcontext.Context, id1, id2 string) (err error) { - if globals.EnableStoreWrite { - err = api.YilianyunAPI.CancelAll(id1, id2) - } - return err -} - -func (c *PrinterHandler) PlayText(ctx *jxcontext.Context, id1, id2, orderID, text string) (printerStatus *partner.PrinterStatus, err error) { - if globals.EnableStoreWrite { - err = api.YilianyunAPI.PlayText(id1, orderID, text, id2) - } - return nil, err -} - -func (c *PrinterHandler) SetSound(ctx *jxcontext.Context, id1, id2, sound string) (err error) { - if globals.EnableStoreWrite { - err = api.YilianyunAPI.SetSound(id1, sound) - } - return err -} diff --git a/business/partner/printer/yilianyun/yilianyun_test.go b/business/partner/printer/yilianyun/yilianyun_test.go deleted file mode 100644 index 5b67f77ca..000000000 --- a/business/partner/printer/yilianyun/yilianyun_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package yilianyun - -import ( - "testing" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - - "git.rosy.net.cn/baseapi/utils" - - "git.rosy.net.cn/jx-callback/business/partner" - - _ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" - _ "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler/defsch" - "git.rosy.net.cn/jx-callback/globals/testinit" - "git.rosy.net.cn/jx-callback/globals/api" -) - -func init() { - testinit.Init() - api.YilianyunAPI.SetToken("8d54951744984b7a8908251c3063b445") -} - -func TestPrintMsg(t *testing.T) { - orderID := "910838879000442" - vendorID := 0 - order, err := partner.CurOrderManager.LoadOrder(orderID, vendorID) - if err != nil { - t.Fatal(err) - } - - // context := CurPrinterHandler.getOrderContent(order, "13412345678") - context := CurPrinterHandler.getOrderContentBig(order, "13412345678") - status, err := CurPrinterHandler.PrintMsg(jxcontext.AdminCtx, "4004600675", "fem2ukwvduik", "test", context) - t.Log(utils.Format4Output(status, false)) - if err != nil { - t.Fatal(err) - } -} - -func TestRegisterPrinter(t *testing.T) { - newID1, newID2, err := CurPrinterHandler.RegisterPrinter(jxcontext.AdminCtx, "4004600675", "fem2ukwvduik", "title") - t.Log(newID1 + "," + newID2) - if err != nil { - t.Fatal(err) - } -} diff --git a/business/partner/printer/zhongwu/zhongwu.go b/business/partner/printer/zhongwu/zhongwu.go deleted file mode 100644 index 9eff3d4e1..000000000 --- a/business/partner/printer/zhongwu/zhongwu.go +++ /dev/null @@ -1,258 +0,0 @@ -package zhongwu - -import ( - "fmt" - "strings" - "time" - - "git.rosy.net.cn/baseapi/platformapi/zhongwuapi" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -var ( - CurPrinterHandler *PrinterHandler -) - -type PrinterHandler struct { -} - -func init() { - CurPrinterHandler = new(PrinterHandler) - partner.RegisterPrinterPlatform(CurPrinterHandler) -} - -func (c *PrinterHandler) getOrderContent(order *model.GoodsOrder, storeTel string) (content string) { - expectedDeliveryTime := order.ExpectedDeliveredTime - if utils.IsTimeZero(expectedDeliveryTime) { - expectedDeliveryTime = order.OrderCreatedAt.Add(1 * time.Hour) - } - getCode := "" - if order.VendorID == model.VendorIDEBAI { - getCode = fmt.Sprintf("饿百取货码:%s\n", jxutils.GetEbaiOrderGetCode(order)) - } - orderFmt := ` -%s -手机买菜上京西 -极速到家送惊喜 -******************************** -下单时间: %s -预计送达: %s -订单编号: %s - -%s#%d -%s -` + getCode + ` -客户: %s -电话: %s -地址: %s - -客户备注: -%s - - -商品明细: -品名 数量 -********************************` - // 实际支付:%s - orderParams := []interface{}{ - globals.StoreName, - utils.Time2Str(order.OrderCreatedAt), - utils.Time2Str(expectedDeliveryTime), - order.VendorOrderID, - jxutils.GetVendorName(order.VendorID), - order.OrderSeq, - order.VendorOrderID, - order.ConsigneeName, - order.ConsigneeMobile, - order.ConsigneeAddress, - order.BuyerComment, - // jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice), - } - - for _, sku := range order.Skus { - orderFmt += `%s` - orderFmt += `%8s` - orderParams = append(orderParams, sku.SkuName, "x"+utils.Int2Str(sku.Count)) - //jxutils.IntPrice2StandardCurrencyString(sku.SalePrice), jxutils.IntPrice2StandardCurrencyString(sku.SalePrice*int64(sku.Count)) - } - orderFmt += ` -共%d种%d件商品 - -******************************** -

商品质量问题请联系:

-

%s:%s

-更多信息请关注官方微信: %s -******************************** -******************************** -` - // http://weixin.qq.com/r/tkkDGzTERmk5rXB49xyk - orderParams = append(orderParams, order.SkuCount, order.GoodsCount, order.StoreName, storeTel, globals.StoreName) - return fmt.Sprintf(strings.Replace(orderFmt, "\n", "", -1), orderParams...) -} - -func (c *PrinterHandler) getOrderContentBig(order *model.GoodsOrder, storeTel string) (content string) { - expectedDeliveryTime := order.ExpectedDeliveredTime - if utils.IsTimeZero(expectedDeliveryTime) { - expectedDeliveryTime = order.OrderCreatedAt.Add(1 * time.Hour) - } - getCode := "" - if order.VendorID == model.VendorIDEBAI { - getCode = fmt.Sprintf("饿百取货码:%s\n", jxutils.GetEbaiOrderGetCode(order)) - } - orderFmt := ` -%s -手机买菜上京西 -极速到家送惊喜 -******************************** -下单时间: %s -预计送达: %s -订单编号: %s - -%s#%d -%s -` + getCode + ` -客户: %s -电话: %s -地址: %s - -客户备注: -%s - - -商品明细: -品名 数量 -********************************` - // 实际支付:%s - orderParams := []interface{}{ - globals.StoreName, - utils.Time2Str(order.OrderCreatedAt), - utils.Time2Str(expectedDeliveryTime), - order.VendorOrderID, - jxutils.GetVendorName(order.VendorID), - order.OrderSeq, - order.VendorOrderID, - order.ConsigneeName, - order.ConsigneeMobile, - order.ConsigneeAddress, - order.BuyerComment, - // jxutils.IntPrice2StandardCurrencyString(order.ActualPayPrice), - } - - for _, sku := range order.Skus { - orderFmt += `%s` - orderFmt += `%s` - orderParams = append(orderParams, sku.SkuName, "x"+utils.Int2Str(sku.Count)) - //jxutils.IntPrice2StandardCurrencyString(sku.SalePrice), jxutils.IntPrice2StandardCurrencyString(sku.SalePrice*int64(sku.Count)) - } - orderFmt += ` -共%d种%d件商品 - -******************************** -

商品质量问题请联系:

-

%s:%s

-更多信息请关注官方微信: %s -******************************** -******************************** -` - // http://weixin.qq.com/r/tkkDGzTERmk5rXB49xyk - orderParams = append(orderParams, order.SkuCount, order.GoodsCount, order.StoreName, storeTel, globals.StoreName) - return fmt.Sprintf(strings.Replace(orderFmt, "\n", "", -1), orderParams...) -} - -func (c *PrinterHandler) GetVendorID() int { - return model.VendorIDZhongWu -} - -func (c *PrinterHandler) PrintMsg(ctx *jxcontext.Context, deviceID, deviceSecret, msgTitle, msgContent string) (printerStatus *partner.PrinterStatus, err error) { - globals.SugarLogger.Debugf("PrintMsg deviceID:%s", deviceID) - if deviceID != "" { - var status int - if globals.EnableStoreWrite { - _, status, err = api.ZhongwuAPI.PrintMsg(deviceID, deviceSecret, msgContent) - } - if err == nil { - printerStatus = c.translateStatus(status) - } - } else { - printerStatus = &partner.PrinterStatus{ - PrintResult: partner.PrintResultNoPrinter, - } - } - return printerStatus, err -} - -func (c *PrinterHandler) GetPrinterStatus(ctx *jxcontext.Context, deviceID, deviceSecret string) (printerStatus *partner.PrinterStatus, err error) { - status, err := api.ZhongwuAPI.GetPrinterStatus(deviceID, deviceSecret) - if err == nil { - printerStatus = c.translateStatus(status) - } - return printerStatus, err -} - -func (c *PrinterHandler) PrintOrder(ctx *jxcontext.Context, store *model.Store, order *model.GoodsOrder) (printerStatus *partner.PrinterStatus, err error) { - globals.SugarLogger.Debugf("zhongwu PrintOrderByOrder orderID:%s, storeID:%d", order.VendorOrderID, store.ID) - content := "" - if store.PrinterFontSize == partner.PrinterFontSizeBig { - content = c.getOrderContentBig(order, store.Tel1) - } else { - content = c.getOrderContent(order, store.Tel1) - } - return c.PrintMsg(ctx, store.PrinterSN, store.PrinterKey, order.VendorOrderID, content) -} - -func (c *PrinterHandler) RegisterPrinter(ctx *jxcontext.Context, deviceID, deviceSecret, printerName string) (notUsed1, notUsed2 string, err error) { - if deviceID == "" || deviceSecret == "" { - err = fmt.Errorf("打印机ID与打印机密钥都不能为空") - } - _, err = c.GetPrinterStatus(ctx, deviceID, deviceSecret) - return "", "", err -} - -func (c *PrinterHandler) UnregisterPrinter(ctx *jxcontext.Context, deviceID, deviceSecret string) (err error) { - // 中午云不需要注册 - return err -} - -func (c *PrinterHandler) translateStatus(status int) (printerStatus *partner.PrinterStatus) { - printerStatus = &partner.PrinterStatus{ - PrintResult: partner.PrintResultSuccess, - } - if status == zhongwuapi.PrinterStatusOnline { - printerStatus.PrinterStatus = partner.PrinterStatusOnlineOK - } else if status == zhongwuapi.PrinterStatusLackPaper { - printerStatus.PrinterStatus = partner.PrinterStatusOnlineAbnormal - } else { - printerStatus.PrinterStatus = partner.PrinterStatusOffline - } - return printerStatus -} - -func (c *PrinterHandler) BindPrinter(ctx *jxcontext.Context, mapData map[string]interface{}) (bindResult *partner.BindPrinterResult, err error) { - return nil, fmt.Errorf("%s打印机当前不支持扫码绑定", model.VendorChineseNames[model.VendorIDZhongWu]) -} - -func (c *PrinterHandler) RebindPrinter(ctx *jxcontext.Context, lastBindResult *partner.BindPrinterResult) (bindResult *partner.BindPrinterResult, err error) { - return nil, fmt.Errorf("%s打印机当前不支持扫码绑定", model.VendorChineseNames[model.VendorIDZhongWu]) -} - -func (c *PrinterHandler) EmptyPrintList(ctx *jxcontext.Context, id1, id2 string) (err error) { - if globals.EnableStoreWrite { - _, err = api.ZhongwuAPI.EmptyPrintQueue(id1, id2) - } - return err -} - -func (c *PrinterHandler) PlayText(ctx *jxcontext.Context, id1, id2, orderID, text string) (printerStatus *partner.PrinterStatus, err error) { - return c.GetPrinterStatus(ctx, id1, id2) -} - -func (c *PrinterHandler) SetSound(ctx *jxcontext.Context, id1, id2, sound string) (err error) { - return fmt.Errorf("%s打印机当前不支持设置声音", model.VendorChineseNames[model.VendorIDZhongWu]) -} diff --git a/business/partner/printer/zhongwu/zhongwu_test.go b/business/partner/printer/zhongwu/zhongwu_test.go deleted file mode 100644 index 6db9d9805..000000000 --- a/business/partner/printer/zhongwu/zhongwu_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package zhongwu - -import ( - "testing" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - - "git.rosy.net.cn/baseapi/utils" - - "git.rosy.net.cn/jx-callback/business/partner" - - _ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" - _ "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler/defsch" - "git.rosy.net.cn/jx-callback/globals/testinit" -) - -func init() { - testinit.Init() -} - -func TestPrintMsg(t *testing.T) { - orderID := "910838879000442" - vendorID := 0 - order, err := partner.CurOrderManager.LoadOrder(orderID, vendorID) - if err != nil { - t.Fatal(err) - } - - // context := CurPrinterHandler.getOrderContent(order, "13412345678") - context := CurPrinterHandler.getOrderContentBig(order, "13412345678") - status, err := CurPrinterHandler.PrintMsg(jxcontext.AdminCtx, "12364142", "v7rvjv9b", "test", context) - t.Log(utils.Format4Output(status, false)) - if err != nil { - t.Fatal(err) - } -} - -func TestRegisterPrinter(t *testing.T) { - newID1, newID2, err := CurPrinterHandler.RegisterPrinter(jxcontext.AdminCtx, "12364142", "v7rvjv9b", "title") - t.Log(newID1 + "," + newID2) - if err != nil { - t.Fatal(err) - } -} diff --git a/business/partner/purchase/ebai/act.go b/business/partner/purchase/ebai/act.go deleted file mode 100644 index beda910c4..000000000 --- a/business/partner/purchase/ebai/act.go +++ /dev/null @@ -1,340 +0,0 @@ -package ebai - -import ( - "git.rosy.net.cn/baseapi/platformapi/ebaiapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -func actType2Ebai(actType int) int { - if actType < model.ActOrderBegin { - return ebaiapi.ActivityTypeDirectDown - } - return ebaiapi.ActivityTypeFullDiscount -} - -func actOrderRules2Ebai(actOrderRules []*model.ActOrderRule) (ebaiRules []*ebaiapi.ActivityRule) { - for _, v := range actOrderRules { - ebaiRules = append(ebaiRules, &ebaiapi.ActivityRule{ - Accords: int(jxutils.IntPrice2Standard(v.SalePrice)), - Sale: int(jxutils.IntPrice2Standard(v.DeductPrice)), - }) - } - return ebaiRules -} - -func actStoreSu2Ebai4Add(oneStoreActSku []*model.ActStoreSku2) (skus []*ebaiapi.ActivitySkuInfo4Add) { - for _, v := range oneStoreActSku { - if v.VendorSkuID != "" { - if model.IsSyncStatusNeedCreate(v.SyncStatus) { - skus = append(skus, &ebaiapi.ActivitySkuInfo4Add{ - SkuID: v.VendorSkuID, - SpecialPrice: v.ActualActPrice, - Stock: v.Stock, - }) - } - } - } - return skus -} - -func actStoreSu2Ebai4Update(oneStoreActSku []*model.ActStoreSku2) (skus []*ebaiapi.ActivitySkuInfo4Update) { - for _, v := range oneStoreActSku { - if v.VendorSkuID != "" { - if model.IsSyncStatusNeedUpdate(v.SyncStatus) { - skus = append(skus, &ebaiapi.ActivitySkuInfo4Update{ - ShopID: utils.Int2Str(v.StoreID), - SkuID: v.VendorSkuID, - SpecialPrice: v.ActPrice, - Stock: v.Stock, - }) - } - } - } - return skus -} - -func actStoreSu2Ebai4Delete(oneStoreActSku []*model.ActStoreSku2) (skus []string) { - for _, v := range oneStoreActSku { - if v.VendorSkuID != "" { - if model.IsSyncStatusNeedDelete(v.SyncStatus) { - skus = append(skus, v.VendorSkuID) - } - } - } - return skus -} - -func act2EbaiActivity(act *model.Act2, actOrderRules []*model.ActOrderRule) (activity *ebaiapi.ActivityInfo) { - activity = &ebaiapi.ActivityInfo{ - ActivityName: utils.LimitMixedStringLen(act.GetRealActName(), ebaiapi.MaxActivityNameLength), - ActivityType: actType2Ebai(act.Type), - StartTime: act.BeginAt.Unix(), - EndTime: act.EndAt.Unix(), - OpenTime: "00:00", - CloseTime: "23:59", - WeekDay: "0,1,2,3,4,5,6", - ActivityDesc: act.Advertising, - ShowCategory: model.ActTypeName[act.Type], - PromotionSkuDesc: utils.LimitMixedStringLen(act.Advertising, ebaiapi.MaxActivityDescLength), - DayLimit: act.LimitDaily, - ActivityPlatform: ebaiapi.ActivityPFAll, - } - if act.LimitCount > 0 { - activity.OrderLimit = act.LimitCount - } - if activity.DayLimit == 0 { - activity.DayLimit = 999 - } - if actOrderRules != nil { - activity.Rule = actOrderRules2Ebai(actOrderRules) - } - return activity -} - -func createOneShopAct(act *model.Act2, shopID string, oneStoreActSku []*model.ActStoreSku2) (ebaiActIDStr string, err error) { - globals.SugarLogger.Debugf("ebai createOneShopAct") - activity := act2EbaiActivity(act, nil) - if globals.EnableEbaiStoreWrite { - ebaiActID, err2 := api.EbaiAPI.ActivityCreate(shopID, 0, 0, activity) - if err = err2; err == nil { - ebaiActIDStr = utils.Int64ToStr(ebaiActID) - if _, err = ActivitySkuAddBatch(ebaiActID, shopID, 0, activity.ActivityType, actStoreSu2Ebai4Add(oneStoreActSku), false); err != nil { - ActivityDisable(ebaiActID, shopID, 0, 0) - } - } - } else { - ebaiActIDStr = utils.Int64ToStr(jxutils.GenFakeID()) - } - return ebaiActIDStr, err -} - -func ActivitySkuAddBatch(activityID int64, shopID string, baiduShopID int64, activityType int, skuList []*ebaiapi.ActivitySkuInfo4Add, isSkuIDCustom bool) (successIDs []string, err error) { - globals.SugarLogger.Debugf("ebai ActivitySkuAddBatch") - if globals.EnableEbaiStoreWrite { - successIDs, err = api.EbaiAPI.ActivitySkuAddBatch(activityID, shopID, baiduShopID, activityType, skuList, isSkuIDCustom) - } else { - for _, v := range skuList { - successIDs = append(successIDs, v.SkuID) - } - } - return successIDs, err -} - -func ActivitySkuDeleteBatch(activityID int64, shopID string, baiduShopID int64, skuIDs []string, isSkuIDCustom bool) (successIDs []string, err error) { - globals.SugarLogger.Debugf("ebai ActivitySkuDeleteBatch") - if globals.EnableEbaiStoreWrite { - successIDs, err = api.EbaiAPI.ActivitySkuDeleteBatch(activityID, shopID, baiduShopID, skuIDs, isSkuIDCustom) - } else { - successIDs = append([]string{}, skuIDs...) - } - return successIDs, err -} - -func ActivitySkuUpdateBatch(activityID int64, actSkuInfoList []*ebaiapi.ActivitySkuInfo4Update) (faildInfoList []string, err error) { - globals.SugarLogger.Debugf("ebai ActivitySkuUpdateBatch") - if globals.EnableEbaiStoreWrite { - faildInfoList, err = api.EbaiAPI.ActivitySkuUpdateBatch(activityID, actSkuInfoList) - } - return faildInfoList, err -} - -func ActivityDisable(activityID int64, shopID string, baiduShopID, supplierID int64) (err error) { - globals.SugarLogger.Debugf("ebai ActivityDisable") - if globals.EnableEbaiStoreWrite { - err = api.EbaiAPI.ActivityDisable(activityID, shopID, baiduShopID, supplierID) - } - return err -} - -func getActStoreSkuFromTaskResult(taskReslt []interface{}) (list []*model.ActStoreSku2) { - for _, v := range taskReslt { - actStoreSkuList := v.([]*model.ActStoreSku2) - list = append(list, actStoreSkuList...) - } - return list -} - -func createSkuAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreSku []*model.ActStoreSku2) (createdList []*model.ActStoreSku2, err error) { - globals.SugarLogger.Debugf("ebai createSkuAct") - actStoreSkuListList := partner.SplitActStoreSku2List(actStoreSku) - task := tasksch.NewParallelTask("ebai createSkuAct", nil, ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - list := batchItemList[0].([]*model.ActStoreSku2) - var vendorActID string - if vendorActID, err = createOneShopAct(act, utils.Int2Str(list[0].StoreID), list); err == nil { - for _, v := range list { - v.VendorActID = vendorActID - } - retVal = []interface{}{list} - } - return retVal, err - }, actStoreSkuListList) - tasksch.HandleTask(task, parentTask, true).Run() - result, err := task.GetResult(0) - return getActStoreSkuFromTaskResult(result), err -} - -func cancelSkuAct(ctx *jxcontext.Context, parentTask tasksch.ITask, actStoreSkuMap map[string][]*model.ActStoreSku2) (canceledList []*model.ActStoreSku2, err error) { - globals.SugarLogger.Debugf("ebai cancelSkuAct") - var vendorActIDs []string - for k := range actStoreSkuMap { - vendorActIDs = append(vendorActIDs, k) - } - task := tasksch.NewParallelTask("ebai cancelSkuAct", nil, ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - vendorActID := batchItemList[0].(string) - actStoreSkuList := actStoreSkuMap[vendorActID] - if vendorActID != "" { - err = ActivityDisable(utils.Str2Int64(vendorActID), utils.Int2Str(actStoreSkuList[0].StoreID), 0, 0) - } - if err == nil { - retVal = []interface{}{actStoreSkuList} - } - return retVal, err - }, vendorActIDs) - tasksch.HandleTask(task, parentTask, true).Run() - result, err := task.GetResult(0) - return getActStoreSkuFromTaskResult(result), err -} - -func deleteSkuActSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, actStoreSkuMap, vendorActInfoMap map[string][]*model.ActStoreSku2) (deletedList []*model.ActStoreSku2, err error) { - globals.SugarLogger.Debugf("ebai deleteSkuActSkus") - var vendorActIDs []string - for k := range actStoreSkuMap { - if k != "" { - vendorActIDs = append(vendorActIDs, k) - } - } - if len(vendorActIDs) > 0 { - task := tasksch.NewParallelTask("ebai deleteSkuAct", nil, ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - vendorActID := batchItemList[0].(string) - actStoreSkuList := actStoreSkuMap[vendorActID] - vendorActStoreSkuList := vendorActInfoMap[vendorActID] - if len(actStoreSkuList) < len(vendorActStoreSkuList) { - if list := actStoreSu2Ebai4Delete(actStoreSkuList); len(list) > 0 { - _, err = ActivitySkuDeleteBatch(utils.Str2Int64(vendorActID), utils.Int2Str(actStoreSkuList[0].StoreID), 0, list, false) - } - } else { - err = ActivityDisable(utils.Str2Int64(vendorActID), utils.Int2Str(actStoreSkuList[0].StoreID), 0, 0) - } - if err == nil { - retVal = []interface{}{actStoreSkuList} - } - return retVal, err - }, vendorActIDs) - tasksch.HandleTask(task, parentTask, true).Run() - result, err2 := task.GetResult(0) - err = err2 - deletedList = getActStoreSkuFromTaskResult(result) - } - return deletedList, err -} - -func addSkuActSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreSku []*model.ActStoreSku2, vendorActIDMap map[int]string) (addedList []*model.ActStoreSku2, err error) { - globals.SugarLogger.Debugf("ebai addSkuActSkus, actID:%d", act.ID) - actStoreSkuListList := partner.SplitActStoreSku2List(actStoreSku) - if len(actStoreSkuListList) > 0 { - task := tasksch.NewParallelTask("ebai addSkuActSkus", nil, ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - actStoreSkuList := batchItemList[0].([]*model.ActStoreSku2) - vendorActID := vendorActIDMap[actStoreSkuList[0].StoreID] - if vendorActID != "" { - if list := actStoreSu2Ebai4Add(actStoreSkuList); len(list) > 0 { - _, err = ActivitySkuAddBatch(utils.Str2Int64(vendorActID), utils.Int2Str(actStoreSkuList[0].StoreID), 0, actType2Ebai(act.Type), list, false) - } - } else { - vendorActID, err = createOneShopAct(act, utils.Int2Str(actStoreSkuList[0].StoreID), actStoreSkuList) - } - if err == nil { - for _, v := range actStoreSkuList { - v.VendorActID = vendorActID - } - retVal = []interface{}{actStoreSkuList} - } - return retVal, err - }, actStoreSkuListList) - tasksch.HandleTask(task, parentTask, true).Run() - result, err2 := task.GetResult(0) - err = err2 - addedList = getActStoreSkuFromTaskResult(result) - } - return addedList, err -} - -func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSkuList []*model.ActStoreSku2) (err error) { - globals.SugarLogger.Debugf("ebai SyncAct, actID:%d", act.ID) - vendorActInfoMap := make(map[string][]*model.ActStoreSku2) - deleteActInfoMap := make(map[string][]*model.ActStoreSku2) - vendorActIDMap := make(map[int]string) - var actStoreSkuList4Create []*model.ActStoreSku2 - var updateItems []*dao.KVUpdateItem - - actStoreSkuMap := partner.SplitActStoreSku(actStoreSkuList) - for storeID := range actStoreSkuMap { - for _, actStoreSku := range actStoreSkuMap[storeID] { - vendorActInfoMap[actStoreSku.VendorActID] = append(vendorActInfoMap[actStoreSku.VendorActID], actStoreSku) - if vendorActIDMap[storeID] == "" && actStoreSku.VendorActID != "" { - vendorActIDMap[storeID] = actStoreSku.VendorActID - } - if model.IsSyncStatusDelete(actStoreSku.SyncStatus) { - vendorActID := actStoreSku.VendorActID - if vendorActID == "" { - vendorActID = act.VendorActID - } - deleteActInfoMap[vendorActID] = append(deleteActInfoMap[vendorActID], actStoreSku) - } else if model.IsSyncStatusNew(actStoreSku.SyncStatus) { - actStoreSkuList4Create = append(actStoreSkuList4Create, actStoreSku) - } - } - } - err = func() (err error) { - if model.IsSyncStatusDelete(act.SyncStatus) { - canceledList, err2 := cancelSkuAct(ctx, nil, vendorActInfoMap) - updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, canceledList, model.SyncFlagModifiedMask)...) - if err = err2; err == nil { - updateItems = append(updateItems, partner.Act2Update(ctx, act, model.SyncFlagModifiedMask)) - } - } else if model.IsSyncStatusNew(act.SyncStatus) { - createdList, err2 := createSkuAct(ctx, nil, act, actStoreSkuList4Create) - updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, createdList, model.SyncFlagNewMask)...) - if err = err2; err == nil { - updateItems = append(updateItems, partner.Act2Update(ctx, act, model.SyncFlagNewMask)) - } - } else if model.IsSyncStatusUpdate(act.SyncStatus) { - // globals.SugarLogger.Debug(utils.Format4Output(updateItems, false)) - if len(actStoreSkuList4Create) > 0 { - addedList, err2 := addSkuActSkus(ctx, nil, act, actStoreSkuList4Create, vendorActIDMap) - updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, addedList, model.SyncFlagNewMask)...) - if err = err2; err != nil { - return err - } - } - if len(deleteActInfoMap) > 0 { - deletedList, err2 := deleteSkuActSkus(ctx, nil, deleteActInfoMap, vendorActInfoMap) - updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, deletedList, model.SyncFlagDeletedMask)...) - if err = err2; err != nil { - return err - } - } - if err == nil { - updateItems = append(updateItems, partner.Act2Update(ctx, act, model.SyncFlagModifiedMask)) - } - } - return err - }() - db := dao.GetDB() - _, err2 := dao.BatchUpdateActEntity(db, model.IsSyncStatusDelete(act.SyncStatus), updateItems) - if err == nil { - err = err2 - } - return err -} diff --git a/business/partner/purchase/ebai/act_page.go b/business/partner/purchase/ebai/act_page.go deleted file mode 100644 index 4327faf40..000000000 --- a/business/partner/purchase/ebai/act_page.go +++ /dev/null @@ -1,117 +0,0 @@ -package ebai - -import ( - "fmt" - "time" - - "git.rosy.net.cn/jx-callback/business/jxutils" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/globals/api" - - "git.rosy.net.cn/baseapi/platformapi/ebaiapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/model" -) - -type tShowStatusAndTypeInfo struct { - ShowStatus int - ActivityType int -} - -func ebaiPageActType2Jx(activityType int) int { - if activityType == ebaiapi.PageActivityTypeSkuDiscount || activityType == ebaiapi.PageActivityTypeSkuDirectDown { - return model.ActSkuDirectDown - } else if activityType == ebaiapi.PageActivityTypeSkuSpecialPrice { - return model.ActSkuSecKill - } - return 0 -} - -func ebaiPageActStatus2Jx(status int) int { - if status == ebaiapi.PageActivityStatusWaiting || status == ebaiapi.PageActivityStatusOnGoing { - return model.ActStatusCreated - } else if status == ebaiapi.PageActivityStatusEnded { - return model.ActStatusEnded - } - return model.ActStatusNA -} - -func (c *PurchaseHandler) GetPageActList(ctx *jxcontext.Context, createdFrom time.Time) (actList []*model.Act2, err error) { - var typeAndStatusList []*tShowStatusAndTypeInfo - for _, showStatus := range []int{ - ebaiapi.PageActivityShowStatusWaiting, - ebaiapi.PageActivityShowStatusOnGoing, - // ebaiapi.PageActivityStatusEnded, - } { - for _, activityType := range []int{ - ebaiapi.PageActivityTypeSkuDiscount, - ebaiapi.PageActivityTypeSkuSpecialPrice, - ebaiapi.PageActivityTypeSkuDirectDown, - } { - typeAndStatusList = append(typeAndStatusList, &tShowStatusAndTypeInfo{ - ShowStatus: showStatus, - ActivityType: activityType, - }) - } - } - - task := tasksch.NewParallelTask("ebai GetPageActList", tasksch.NewParallelConfig().SetParallelCount(10), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - info := batchItemList[0].(*tShowStatusAndTypeInfo) - list, err := api.EbaiAPI.BegetActivityList(info.ShowStatus, info.ActivityType, 0, api.EbaiAPI.GetSupplierID()) - if err == nil { - retVal = list - } - return retVal, err - }, typeAndStatusList) - task.Run() - list, err := task.GetResult(0) - if len(list) > 0 { - for _, v := range list { - ebaiAct := v.(*ebaiapi.PageActItem) - if utils.Timestamp2Time(ebaiAct.CreateTime).Sub(createdFrom) > 0 { - act := &model.Act2{ - Act: model.Act{ - Name: fmt.Sprintf("%s-%s", ebaiAct.ActivityName, ebaiAct.ActivityID), - Type: ebaiPageActType2Jx(ebaiAct.ActivityType), - Status: ebaiPageActStatus2Jx(ebaiAct.Status), - Source: ebaiAct.User, - CreateType: model.ActCreateTypeSpider, - BeginAt: utils.Timestamp2Time(ebaiAct.StartTime), - EndAt: utils.Timestamp2Time(ebaiAct.EndTime), - VendorMask: model.GetVendorMask(model.VendorIDEBAI), - LimitCount: 1, - }, - VendorID: model.VendorIDEBAI, - VendorOrgCode: api.EbaiAPI.GetSource(), - VendorActID: ebaiAct.ActivityID, - } - actList = append(actList, act) - } - } - } - return actList, err -} - -func (c *PurchaseHandler) GetPageActSkuList(ctx *jxcontext.Context, vendorPageActID string) (actStoreSkuList []*model.ActStoreSku2, err error) { - skus, err := api.EbaiAPI.BegetActSkuList(utils.Str2Int64(vendorPageActID), 0, api.EbaiAPI.GetSupplierID()) - if err != nil { - return nil, err - } - for _, v := range skus { - actStoreSku := &model.ActStoreSku2{ - ActStoreSku: model.ActStoreSku{ - Stock: v.Stock, - OriginalPrice: jxutils.StandardPrice2Int(v.OriginalPrice), - }, - VendorStoreID: utils.Int64ToStr(v.Wid), - VendorSkuID: v.SkuID, - VendorActID: v.ActivityID, - ActualActPrice: jxutils.StandardPrice2Int(v.PromotionPrice), - } - actStoreSkuList = append(actStoreSkuList, actStoreSku) - } - return actStoreSkuList, nil -} diff --git a/business/partner/purchase/ebai/act_page_test.go b/business/partner/purchase/ebai/act_page_test.go deleted file mode 100644 index ffa801884..000000000 --- a/business/partner/purchase/ebai/act_page_test.go +++ /dev/null @@ -1,28 +0,0 @@ -package ebai - -import ( - "testing" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - - _ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" - _ "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler/defsch" -) - -func TestGetPageActList(t *testing.T) { - actList, err := new(PurchaseHandler).GetPageActList(jxcontext.AdminCtx, utils.DefaultTimeValue) - if err != nil { - t.Fatal(err) - } - t.Log(utils.Format4Output(actList, false)) - t.Log(len(actList)) -} - -func TestGetPageActSkuList(t *testing.T) { - actList, err := new(PurchaseHandler).GetPageActSkuList(jxcontext.AdminCtx, "3000000001477429") - if err != nil { - t.Fatal(err) - } - t.Log(utils.Format4Output(actList, false)) -} diff --git a/business/partner/purchase/ebai/callback.go b/business/partner/purchase/ebai/callback.go deleted file mode 100644 index fd7c41714..000000000 --- a/business/partner/purchase/ebai/callback.go +++ /dev/null @@ -1,45 +0,0 @@ -package ebai - -import ( - "git.rosy.net.cn/baseapi/platformapi/ebaiapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/globals" -) - -func OnCallbackMsg(msg *ebaiapi.CallbackMsg) (response *ebaiapi.CallbackResponse) { - globals.SugarLogger.Debugf("ebai OnCallbackMsg msg:%s", utils.Format4Output(msg, true)) - if CurPurchaseHandler != nil { - if orderID := GetOrderIDFromMsg(msg); orderID != "" { - jxutils.CallMsgHandler(func() { - switch msg.Cmd { - case ebaiapi.CmdOrderCreate, ebaiapi.CmdOrderStatus, ebaiapi.CmdOrderUserCancel, ebaiapi.CmdOrderPartRefund: - response = CurPurchaseHandler.onOrderMsg(msg) - case ebaiapi.CmdOrderDeliveryStatus: - response = CurPurchaseHandler.onWaybillMsg(msg) - } - }, jxutils.ComposeUniversalOrderID(orderID, model.VendorIDEBAI)) - } - if /*msg.Cmd == ebaiapi.CmdOrderPartRefund || msg.Cmd == ebaiapi.CmdOrderUserCancel || */ msg.Cmd == ebaiapi.CmdOrderDeliveryStatus { - response = CurPurchaseHandler.OnFinancialMsg(msg) - } else if msg.Cmd == ebaiapi.CmdShopMsgPush { - response = CurPurchaseHandler.onShopMsgPush(msg) - } - } - return response -} - -func GetOrderIDFromMsg(msg *ebaiapi.CallbackMsg) string { - return GetOrderIDFromMap(msg.Body) -} - -func GetOrderIDFromMap(orderMap map[string]interface{}) string { - if orderID := orderMap["order_id"]; orderID != nil { - if tryOrderID, ok := orderID.(string); ok { - return tryOrderID - } - return utils.Int64ToStr(utils.MustInterface2Int64(orderID)) - } - return "" -} diff --git a/business/partner/purchase/ebai/common.go b/business/partner/purchase/ebai/common.go deleted file mode 100644 index 08f849c25..000000000 --- a/business/partner/purchase/ebai/common.go +++ /dev/null @@ -1,47 +0,0 @@ -package ebai - -import ( - "git.rosy.net.cn/baseapi/platformapi/ebaiapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -func (p *PurchaseHandler) UpdatePlaces() (err error) { - provinces, err := api.EbaiAPI.CommonShopCities(0) - if err == nil { - task := tasksch.NewParallelTask("UpdatePlaces", nil, jxcontext.AdminCtx, - func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - province := batchItemList[0].(*ebaiapi.CityInfo) - retSlice := make([]*ebaiapi.CityInfo, 0) - if province.IsOpen != 0 { - retSlice = append(retSlice, province) - cities, err := api.EbaiAPI.CommonShopCities(province.ID) - for _, city := range cities { - if city.IsOpen != 0 { - retSlice = append(retSlice, city) - districts, err2 := api.EbaiAPI.CommonShopCities(city.ID) - if err = err2; err == nil { - for _, district := range districts { - if district.IsOpen != 0 { - retSlice = append(retSlice, district) - } - } - } else { - break - } - } - } - } - return retSlice, err - }, provinces) - task.Run() - places, err2 := task.GetResult(0) - if err = err2; err == nil { - globals.SugarLogger.Debug(utils.Format4Output(places, false)) - } - } - return err -} diff --git a/business/partner/purchase/ebai/common_test.go b/business/partner/purchase/ebai/common_test.go deleted file mode 100644 index 8057b39b7..000000000 --- a/business/partner/purchase/ebai/common_test.go +++ /dev/null @@ -1,12 +0,0 @@ -package ebai - -import ( - "testing" -) - -func TestUpdatePlacese(t *testing.T) { - err := new(PurchaseHandler).UpdatePlaces() - if err != nil { - t.Fatal(err.Error()) - } -} diff --git a/business/partner/purchase/ebai/ebai.go b/business/partner/purchase/ebai/ebai.go deleted file mode 100644 index 3a222d025..000000000 --- a/business/partner/purchase/ebai/ebai.go +++ /dev/null @@ -1,143 +0,0 @@ -package ebai - -import ( - "sync" - - "git.rosy.net.cn/baseapi/platformapi/ebaiapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/business/partner/putils" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -var ( - CurPurchaseHandler *PurchaseHandler -) - -type PurchaseHandler struct { - partner.BasePurchasePlatform - putils.DefSingleStorePlatform - - shopList []*ebaiapi.ShopInfo - locker sync.RWMutex -} - -func init() { - if api.EbaiAPI != nil { - CurPurchaseHandler = New() - partner.RegisterPurchasePlatform(CurPurchaseHandler) - } -} - -func New() (obj *PurchaseHandler) { - obj = new(PurchaseHandler) - obj.ISingleStoreStoreSkuHandler = obj - return obj -} - -func EbaiBusStatus2JxStatus(ebaiStatus int) int { - if ebaiStatus == ebaiapi.ShopBusStatusHaveRest { - return model.StoreStatusClosed - } - if ebaiStatus == ebaiapi.ShopBusStatusSuspended { - return model.StoreStatusDisabled - } - return model.StoreStatusOpened -} - -func (p *PurchaseHandler) GetVendorID() int { - return model.VendorIDEBAI -} - -func (p *PurchaseHandler) UploadImg(ctx *jxcontext.Context, vendorOrgCode, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) { - globals.SugarLogger.Debugf("ebai UploadImg imgURL:%s, imgName:%s, imgType:%d", imgURL, imgName, imgType) - if globals.EnableEbaiStoreWrite { - if imgType == model.ImgTypeMain { - imgHint, err = api.EbaiAPI.PictureUpload(imgURL, imgData) - } else if imgType == model.ImgTypeDesc { - imgHint, err = api.EbaiAPI.SkuUploadRTF(p.getShopID4UploadRTF(), ebaiapi.BuildRFTFromImgs(imgURL)) - } - } else { - imgHint = imgURL + ".ebai" - } - return imgHint, err -} - -func getShopIDFromList(shopList []*ebaiapi.ShopInfo) (shopID string) { - if len(shopList) > 0 { - shopID = shopList[0].ShopID - } - return shopID -} - -func (p *PurchaseHandler) getShopID4UploadRTF() (shopID string) { - var shopList []*ebaiapi.ShopInfo - p.locker.RLock() - shopList = p.shopList - p.locker.RUnlock() - if len(shopList) > 0 { - return getShopIDFromList(shopList) - } - - p.locker.Lock() - shopList = p.shopList - if len(shopList) > 0 { - p.locker.Unlock() - return getShopIDFromList(shopList) - } - - defer p.locker.Unlock() - shopList, err := api.EbaiAPI.ShopList(ebaiapi.SysStatusAll) - if err == nil { - if len(shopList) > 0 { - p.shopList = shopList - shopID = getShopIDFromList(shopList) - } else { - // p.shopList = []*ebaiapi.ShopInfo{ - // &ebaiapi.ShopInfo{ - // ShopID: "", - // }, - // } - } - } - return shopID -} - -func (p *PurchaseHandler) getVendorCategories(level int, pid int64) (vendorCats []*model.SkuVendorCategory, err error) { - cats, err := api.EbaiAPI.SkuCategoryList("", level, pid) - if err != nil { - return nil, err - } - for _, v := range cats { - cat := &model.SkuVendorCategory{ - VendorID: model.VendorIDEBAI, - Name: v.CatName, - Level: level, - VendorCategoryID: v.CatID, - } - if level > 1 { - cat.ParentID = v.ParentID - if level == 3 { - cat.IsLeaf = 1 - } - } - vendorCats = append(vendorCats, cat) - if level < 3 { - childVendorCats, err2 := p.getVendorCategories(level+1, utils.Str2Int64(v.CatID)) - if err2 == nil && len(childVendorCats) > 0 { - vendorCats = append(vendorCats, childVendorCats...) - } else { - cat.IsLeaf = 1 - } - } - } - return vendorCats, nil -} - -func (p *PurchaseHandler) GetVendorCategories(ctx *jxcontext.Context) (vendorCats []*model.SkuVendorCategory, err error) { - vendorCats, err = p.getVendorCategories(1, 0) - return vendorCats, err -} diff --git a/business/partner/purchase/ebai/ebai_test.go b/business/partner/purchase/ebai/ebai_test.go deleted file mode 100644 index 7cef6541f..000000000 --- a/business/partner/purchase/ebai/ebai_test.go +++ /dev/null @@ -1,32 +0,0 @@ -package ebai - -import ( - "testing" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - - _ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" - _ "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler/defsch" - "git.rosy.net.cn/jx-callback/globals/testinit" -) - -const ( - // testShopBaiduID = "2233976901" - // testShopID = 100077 - - testShopBaiduID = "2267254343" - testShopID = 2 -) - -func init() { - testinit.Init() -} - -func TestGetVendorCategories(t *testing.T) { - catList, err := new(PurchaseHandler).GetVendorCategories(jxcontext.AdminCtx) - if err != nil { - t.Fatal(err) - } - t.Log(utils.Format4Output(catList, false)) -} diff --git a/business/partner/purchase/ebai/financial.go b/business/partner/purchase/ebai/financial.go deleted file mode 100644 index fe014b08f..000000000 --- a/business/partner/purchase/ebai/financial.go +++ /dev/null @@ -1,288 +0,0 @@ -package ebai - -import ( - "git.rosy.net.cn/baseapi/platformapi/ebaiapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -func (p *PurchaseHandler) OnFinancialMsg(msg *ebaiapi.CallbackMsg) (response *ebaiapi.CallbackResponse) { - utils.CallFuncAsync(func() { - response = p.onFinancialMsg(msg) - }) - return response -} - -// 存储饿百退款订单结账信息 -func (p *PurchaseHandler) onFinancialMsg(msg *ebaiapi.CallbackMsg) (response *ebaiapi.CallbackResponse) { - var err error - if msg.Cmd == ebaiapi.CmdOrderPartRefund { // 部分退款处理 - if int(utils.MustInterface2Int64(msg.Body["status"])) == ebaiapi.OrderPartRefundSuccess { - // 获取到部分退款订单id - afsOrderID := GetOrderIDFromMsg(msg) - // 处理部分退款信息 - orderData, err2 := api.EbaiAPI.OrderPartRefundGet(afsOrderID) - if err = err2; err == nil { - afsOrder := CurPurchaseHandler.AfsOrderDetail2Financial(orderData) - err = partner.CurOrderManager.SaveAfsOrderFinancialInfo(afsOrder) - } - } - } else if msg.Cmd == ebaiapi.CmdOrderUserCancel { // 全额退款处理 - messageType := int(utils.MustInterface2Int64(msg.Body["type"])) - if int(utils.MustInterface2Int64(msg.Body["cancel_type"])) == ebaiapi.OrderUserCancelTypeAfterSale && - (messageType == ebaiapi.OrderUserCancelCSAgreed || messageType == ebaiapi.OrderUserCancelMerchantAgreed) { - afsOrderID := GetOrderIDFromMsg(msg) - // 获得退款订单ID,去本地数据库拿?饿百消息推送只给了订单号,但是没有查询全额退款的接口,只有部分退款才可以查询 - orderFinancial, err := partner.CurOrderManager.LoadOrderFinancial(afsOrderID, model.VendorIDEBAI) - if err == nil { - globals.SugarLogger.Debug(utils.Format4Output(orderFinancial, false)) - err = partner.CurOrderManager.SaveAfsOrderFinancialInfo(CurPurchaseHandler.OrderFinancialDetail2Refund(orderFinancial, msg)) - } else { - globals.SugarLogger.Warnf("ebai OnFinancialMsg, afsOrderID:%s is not found from partner.CurOrderManager.LoadOrderFinancial", afsOrderID) - } - } - } else if msg.Cmd == ebaiapi.CmdOrderDeliveryStatus { // 转自送调整 - if utils.Int64ToStr(utils.MustInterface2Int64(msg.Body["status"])) == ebaiapi.WaybillStatusSelfDelivery { - vendorOrderID := GetOrderIDFromMsg(msg) - orderMap, err := api.EbaiAPI.OrderGet(vendorOrderID) - if err == nil { - err = CurPurchaseHandler.OnOrderDetail(orderMap, partner.UpdatedPeration) - } - } - } - return api.EbaiAPI.Err2CallbackResponse(msg.Cmd, err, msg.Cmd) -} - -func (p *PurchaseHandler) OrderFinancialDetail2Refund(orderFinancial *model.OrderFinancial, msg *ebaiapi.CallbackMsg) (afsOrder *model.AfsOrder) { - afsOrder = &model.AfsOrder{ - VendorID: model.VendorIDEBAI, - AfsOrderID: GetOrderIDFromMsg(msg), - VendorOrderID: GetOrderIDFromMsg(msg), - AfsCreatedAt: utils.Timestamp2Time(msg.Timestamp), - // BoxMoney: orderFinancial.BoxMoney, // 饿百的餐盒费已经拆分到单条Sku里面,退款时直接计算用户支付sku金额就好了 - // SkuBoxMoney: orderFinancial.SkuBoxMoney, - FreightUserMoney: orderFinancial.FreightMoney, - SkuUserMoney: orderFinancial.ActualPayMoney - orderFinancial.FreightMoney, - PmSubsidyMoney: orderFinancial.PmSubsidyMoney, - } - // if msg.Body["timestamp"] != nil { - // afsOrder.AfsCreateAt = utils.Timestamp2Time(utils.Str2Int64(utils.Interface2String(msg.Body["timestamp"]))) - // } else { - // globals.SugarLogger.Warnf("ebai OrderFinancialDetail2Refund timestamp is not found in afsOrder:%s", afsOrder.AfsOrderID) - // afsOrder.AfsCreateAt = time.Now() - // } - order, err := partner.CurOrderManager.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID) - globals.SugarLogger.Debug(utils.Format4Output(order, false)) - if err == nil { - afsOrder.JxStoreID = order.JxStoreID - afsOrder.VendorStoreID = order.VendorStoreID - afsOrder.StoreID = order.StoreID - } else { - globals.SugarLogger.Warnf("ebai AfsOrderDetail2Financial, afsOrderID:%s is not found from partner.CurOrderManager.LoadOrder", afsOrder.VendorOrderID) - err = nil - } - for _, sku := range orderFinancial.Skus { - orderSkuFinancial := &model.OrderSkuFinancial{ - VendorID: sku.VendorID, - VendorOrderID: sku.VendorOrderID, - AfsOrderID: sku.VendorOrderID, - // ConfirmTime: afsOrder.AfsCreateAt, - VendorStoreID: afsOrder.VendorStoreID, - StoreID: afsOrder.StoreID, - JxStoreID: afsOrder.JxStoreID, - VendorSkuID: sku.VendorSkuID, - SkuID: sku.SkuID, - PromotionType: sku.PromotionType, - Name: sku.Name, - ShopPrice: sku.ShopPrice, - SalePrice: sku.SalePrice, - Count: sku.Count, - SkuBoxMoney: sku.SkuBoxMoney, - UserMoney: sku.UserMoney, - PmSubsidyMoney: sku.PmSubsidyMoney, - IsAfsOrder: 1, - } - afsOrder.Skus = append(afsOrder.Skus, orderSkuFinancial) - } - return afsOrder -} - -func (p *PurchaseHandler) AfsOrderDetail2Financial(orderData map[string]interface{}) (afsOrder *model.AfsOrder) { - afsOrder = &model.AfsOrder{ - VendorID: model.VendorIDEBAI, - AfsOrderID: GetOrderIDFromMap(orderData), - VendorOrderID: GetOrderIDFromMap(orderData), - } - order, err := partner.CurOrderManager.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID) - if err == nil { - afsOrder.JxStoreID = order.JxStoreID - } else { - globals.SugarLogger.Warnf("ebai AfsOrderDetail2Financial, afsOrderID:%s is not found from partner.CurOrderManager.LoadOrder", afsOrder.VendorOrderID) - err = nil - } - // 部分退款订单,第三方平台佣金会变化,金额为 orderData["commission"],是否将该字段更新到正向订单结算表中 - // 不作更新的话,商户可以得到的钱会少几毛钱,最终京西受益 - // 如果要更新,总佣金,京西佣金是否都要更新,而其它一系列连锁反应,是否需要考虑更新 - // 或者换个思路,不考虑变更之前的正向订单,在佣金上入手,退款金额减去佣金减少的部分 - orderFinancial, err := partner.CurOrderManager.LoadOrderFinancial(afsOrder.VendorOrderID, model.VendorIDEBAI) - if err == nil { - afsOrder.PmRefundMoney = orderFinancial.PmMoney - utils.MustInterface2Int64(orderData["commission"]) - } else { - // 此处应该报错 - // globals.SugarLogger.Warnf("ebai AfsOrderDetail2Financial, afsOrderID:%s is not found from partner.CurOrderManager.LoadOrderFinancial", afsOrder.VendorOrderID) - err = nil - } - if orderData["refund_detail"] != nil { - refundDetail := orderData["refund_detail"].([]interface{}) - for _, refundInfo := range refundDetail { - xMap := refundInfo.(map[string]interface{}) - orderSkuFinancial := &model.OrderSkuFinancial{ - VendorID: model.VendorIDEBAI, - AfsOrderID: afsOrder.AfsOrderID, - VendorOrderID: afsOrder.VendorOrderID, - // ConfirmTime: getTimeFromInterface(xMap["apply_time"]), - VendorSkuID: utils.Interface2String(xMap["sku_id"]), - SkuID: int(utils.Str2Int64WithDefault(utils.Interface2String(xMap["custom_sku_id"]), 0)), - Name: utils.Interface2String(xMap["name"]), - UserMoney: utils.MustInterface2Int64(xMap["total_refund"]), - PmSubsidyMoney: utils.MustInterface2Int64(xMap["shop_ele_refund"]), - IsAfsOrder: 1, - } - afsOrder.Skus = append(afsOrder.Skus, orderSkuFinancial) - afsOrder.SkuUserMoney += orderSkuFinancial.UserMoney - afsOrder.PmSubsidyMoney += orderSkuFinancial.PmSubsidyMoney - } - if len(refundDetail) > 0 { - afsOrder.AfsCreatedAt = getTimeFromInterface(refundDetail[0].(map[string]interface{})["apply_time"]) - } else { - globals.SugarLogger.Warnf("ebai AfsOrderDetail2Financial, orderID:%s have no refund_detail", afsOrder.VendorOrderID) - } - } else { - globals.SugarLogger.Warnf("ebai AfsOrderDetail2Financial, orderID:% refund_detail is nil", afsOrder.VendorOrderID) - } - return afsOrder -} - -// 存储饿百正向订单结账信息 -func (p *PurchaseHandler) OnOrderDetail(result map[string]interface{}, operation string) (err error) { - err = partner.CurOrderManager.SaveOrderFinancialInfo(p.OrderDetail2Financial(result), operation) - return err -} - -// func (p *PurchaseHandler) GetTrueEbaiOrder(result1 map[string]interface{}) (result2 map[string]interface{}) { -// order := result1["order"].(map[string]interface{}) -// if utils.MustInterface2Int64(order["down_flag"]) == 1 { -// result, err := api.EbaiAPI.OrderGet(GetOrderIDFromMap(order)) -// if err == nil { -// return p.GetTrueEbaiOrder(result) -// } -// } -// return result1 -// } - -func (p *PurchaseHandler) OrderDetail2Financial(result map[string]interface{}) (orderFinancial *model.OrderFinancial) { - orderFinancial = &model.OrderFinancial{ - VendorID: model.VendorIDEBAI, - } - order1 := result["order"].(map[string]interface{}) - orderFinancial.VendorOrderID = GetOrderIDFromMap(order1) - orderFinancial.VendorOrderID2 = utils.Interface2String(order1["eleme_order_id"]) - // orderFinancial.DeliveryConfirmTime = getTimeFromInterface(order1["finished_time"]) - orderFinancial.TotalDiscountMoney = utils.MustInterface2Int64(order1["discount_fee"]) - orderFinancial.ReceivableFreight = utils.MustInterface2Int64(order1["send_fee"]) - orderFinancial.DownFlag = int8(utils.MustInterface2Int64(order1["down_flag"])) - - if int(getInt64FromInterface(order1["delivery_party"])) == ebaiapi.DeliveryPartyFengElmSelf { - orderFinancial.SelfDeliveryDiscountMoney = orderFinancial.ReceivableFreight - orderFinancial.DistanceFreightMoney = 0 - // 通过本地数据库去取是否转美团/达达,并计算运费 - // wayBill, err := partner.CurOrderManager.LoadWaybill(orderFinancial.VendorOrderID, orderFinancial.VendorID) - // if err == nil { - // orderFinancial.JxFreightMoney = wayBill.DesiredFee - // } - } - orderFinancial.BoxMoney = utils.ForceInterface2Int64(order1["package_fee"]) - orderFinancial.ActualPayMoney = utils.ForceInterface2Int64(order1["user_fee"]) - orderFinancial.PmMoney = utils.ForceInterface2Int64(order1["commission"]) - orderFinancial.ShopMoney = utils.ForceInterface2Int64(order1["shop_fee"]) - order, err := partner.CurOrderManager.LoadOrder(orderFinancial.VendorOrderID, orderFinancial.VendorID) - storeID := 0 - jxStoreID := 0 - if err == nil { - storeID = order.StoreID - jxStoreID = order.JxStoreID - skus := order.Skus - if skus != nil { - for _, x := range skus { - orderFinancial.ShopPriceMoney += x.ShopPrice * int64(x.Count) - } - } - } else { - globals.SugarLogger.Warnf("ebai OrderDetail2Financial, orderID:%s is not found from partner.CurOrderManager.LoadOrder", orderFinancial.VendorOrderID) - err = nil - } - shop := result["shop"].(map[string]interface{}) - if result["products"] != nil { - products := result["products"].([]interface{}) - for _, x := range products { - for _, y := range x.([]interface{}) { - product := y.(map[string]interface{}) - orderSkuFinancial := &model.OrderSkuFinancial{ - VendorID: orderFinancial.VendorID, - VendorOrderID: orderFinancial.VendorOrderID, - // OrderFinancialID: orderFinancial.VendorOrderID, - // ConfirmTime: getTimeFromInterface(order1["create_time"]), - VendorStoreID: utils.Interface2String(shop["baidu_shop_id"]), - StoreID: storeID, - JxStoreID: jxStoreID, - VendorSkuID: utils.Interface2String(product["baidu_product_id"]), - SkuID: int(utils.Str2Int64WithDefault(utils.Interface2String(product["custom_sku_id"]), 0)), - Name: utils.Interface2String(product["product_name"]), - SalePrice: utils.MustInterface2Int64(product["product_price"]), - Count: int(utils.MustInterface2Int64(product["product_amount"])), - SkuBoxMoney: utils.MustInterface2Int64(product["package_fee"]), - IsAfsOrder: 0, - } - orderFinancial.Skus = append(orderFinancial.Skus, orderSkuFinancial) - orderFinancial.SalePriceMoney += orderSkuFinancial.SalePrice * int64(orderSkuFinancial.Count) - orderFinancial.SkuBoxMoney += orderSkuFinancial.SkuBoxMoney - orderFinancial.BoxMoney -= orderSkuFinancial.SkuBoxMoney - } - } - } - if result["discount"] != nil { - discount := result["discount"].([]interface{}) - for _, x := range discount { - xMap := x.(map[string]interface{}) - discountPrice := utils.MustInterface2Int64(xMap["fee"]) - orderFinancial.DiscountMoney += discountPrice - orderFinancial.PmSubsidyMoney += utils.MustInterface2Int64(xMap["baidu_rate"]) // 平台承担补贴 - activity := &model.OrderDiscountFinancial{ - VendorID: orderFinancial.VendorID, - VendorOrderID: orderFinancial.VendorOrderID, - // ActivityName: utils.Interface2String(xMap["desc"]), - // ActivityMoney: discountPrice, - VendorActivityID: utils.Interface2String(xMap["activity_id"]), - Type: utils.Interface2String(xMap["type"]), - } - orderFinancial.Discounts = append(orderFinancial.Discounts, activity) - // 通过活动Id去取,京西活动补贴 - // orderFinancial.JxSubsidyMoney += - } - } - orderFinancial.FreightDiscountMoney = orderFinancial.TotalDiscountMoney - orderFinancial.DiscountMoney - return orderFinancial -} - -func getInt64FromInterface(strOrNum interface{}) int64 { - var resultNum int64 - if resultStr, ok := strOrNum.(string); ok { - resultNum = utils.Str2Int64WithDefault(resultStr, 0) - } else { - resultNum = utils.Interface2Int64WithDefault(strOrNum, 0) - } - return resultNum -} diff --git a/business/partner/purchase/ebai/financial_test.go b/business/partner/purchase/ebai/financial_test.go deleted file mode 100644 index dd8b99cd5..000000000 --- a/business/partner/purchase/ebai/financial_test.go +++ /dev/null @@ -1,40 +0,0 @@ -package ebai - -import ( - "encoding/json" - "fmt" - "testing" - "time" - - "git.rosy.net.cn/baseapi/platformapi/ebaiapi" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals/api" -) - -func TestOnFinancialMsg(t *testing.T) { - msg := &ebaiapi.CallbackMsg{ - Timestamp: time.Now().Unix(), - Body: make(map[string]interface{}), - } - msg.Body["order_id"] = "1554939646172038357" - - // 部分退款 - msg.Cmd = "order.partrefund.push" - msg.Body["status"] = json.Number("20") - - // 全单退款 - // msg.Cmd = "order.user.cancel" - // msg.Body["type"] = json.Number("40") - // msg.Body["cancel_type"] = json.Number("2") - - res := CurPurchaseHandler.onAfsOrderMsg(msg) - fmt.Println(res) -} - -func TestOnOrderDetail(t *testing.T) { - orderID := "1554939646172038357" - result, err := api.EbaiAPI.OrderGet(orderID) - if err == nil { - new(PurchaseHandler).OnOrderDetail(result, partner.CreatedPeration) - } -} diff --git a/business/partner/purchase/ebai/net_spider_test.go b/business/partner/purchase/ebai/net_spider_test.go deleted file mode 100644 index bc276159e..000000000 --- a/business/partner/purchase/ebai/net_spider_test.go +++ /dev/null @@ -1 +0,0 @@ -package ebai diff --git a/business/partner/purchase/ebai/order.go b/business/partner/purchase/ebai/order.go deleted file mode 100644 index 0b2e6ec8c..000000000 --- a/business/partner/purchase/ebai/order.go +++ /dev/null @@ -1,722 +0,0 @@ -package ebai - -import ( - "fmt" - "math" - "strings" - "time" - - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - - "git.rosy.net.cn/baseapi/platformapi/ebaiapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -const ( - // acceptOrderDelay = 180 * time.Second - // pickupOrderDelay = 260 * time.Second - pickupOrderDelay = 1 * time.Minute - - callDeliveryDelay = 10 * time.Minute - callDeliveryDelayGap = 30 - - fakeAcceptOrder = "fake_accept_order" - fakeOrderAdjustFinished = "fake_order_adjust_finished" - fakeOrderCanceled = "fake_order_canceled" -) - -// 饿百的接单会直接召唤配送,为了统一将饿百的接单影射成拣货完成,然后模拟一个接单消息 - -var ( - VendorStatus2StatusMap = map[string]int{ - ebaiapi.CmdOrderCreate: model.OrderStatusWaitAccepted, - ebaiapi.OrderStatusNew: model.OrderStatusWaitAccepted, - fakeAcceptOrder: model.OrderStatusAccepted, - ebaiapi.OrderStatusAccepted: model.OrderStatusFinishedPickup, - ebaiapi.OrderStatusCourierAccepted: model.OrderStatusDelivering, - ebaiapi.OrderStatusCourierPickedup: model.OrderStatusDelivering, - ebaiapi.OrderStatusFinished: model.OrderStatusFinished, - ebaiapi.OrderStatusCanceled: model.OrderStatusCanceled, - - fakeOrderAdjustFinished: model.OrderStatusAdjust, - fakeOrderCanceled: model.OrderStatusCanceled, - } - - skuActTypeMap = map[string]int{ - ebaiapi.OrderSkuDiscountTypeZhe: 1, - ebaiapi.OrderSkuDiscountTypeReduce: 1, - ebaiapi.OrderSkuDiscountTypeTe: 1, - } - deliveryTypeMap = map[int]string{ - ebaiapi.DeliveryPartyFengElmSelf: model.OrderDeliveryTypeStoreSelf, - } -) - -func mapDeliveryType(ebaiDeliveryParty int, businessType int) (deliveryType string) { - if businessType == ebaiapi.DeliveryBusinessTypeZT { - return model.OrderDeliveryTypeSelfTake - } else { - deliveryType = deliveryTypeMap[ebaiDeliveryParty] - if deliveryType == "" { - deliveryType = model.OrderDeliveryTypePlatform - } - } - return deliveryType -} - -func (p *PurchaseHandler) getStatusFromVendorStatus(vendorStatus string) int { - if status, ok := VendorStatus2StatusMap[vendorStatus]; ok { - return status - } - return model.OrderStatusUnknown -} - -func (p *PurchaseHandler) GetOrder(vendorOrgCode, vendorOrderID string) (order *model.GoodsOrder, err error) { - order, _, err = p.getOrder(vendorOrderID) - return order, err -} - -func (p *PurchaseHandler) GetOrderStatus(vendorOrgCode, vendorOrderID string) (status int, err error) { - status, err = api.EbaiAPI.OrderStatusGet(vendorOrderID) - if err == nil { - status = p.getStatusFromVendorStatus(utils.Int2Str(status)) - } - return status, err -} - -func (p *PurchaseHandler) getOrder(vendorOrderID string) (order *model.GoodsOrder, orderMap map[string]interface{}, err error) { - for i := 0; i < 2; i++ { - orderMap, err = api.EbaiAPI.OrderGet(vendorOrderID) - if err == nil { - order = p.Map2Order(orderMap) - // 饿百订单有时会出现取不到baidu_shop_id的情况,重试 - if order.VendorStoreID != "" { - break - } - } - time.Sleep(100 * time.Millisecond) - } - return order, orderMap, err -} - -func (p *PurchaseHandler) GetOrder4PartRefund(vendorOrderID string) (order *model.GoodsOrder, err error) { - taskIDs := []int{1, 2} - var ( - err1, err2 error - result1, result2 map[string]interface{} - ) - task := tasksch.NewParallelTask("GetOrder4PartRefund", nil, jxcontext.AdminCtx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - taskID := batchItemList[0].(int) - if taskID == 1 { - result1, err1 = api.EbaiAPI.OrderGet(vendorOrderID) - } else if taskID == 2 { - result2, err2 = api.EbaiAPI.OrderPartRefundGet(vendorOrderID) - } - return nil, nil - }, taskIDs) - task.Run() - task.GetResult(0) - if err1 == nil { - order = p.Map2Order(result1) - if err2 == nil { - order.Skus = p.partRefund2OrderDetailSkuList(utils.Interface2String(result2["order_id"]), result2["order_detail"]) - giftSkus, discountMoney := getZengSkus(vendorOrderID, result1) - order.DiscountMoney = discountMoney - order.Skus = append(order.Skus, giftSkus...) - order.ActualPayPrice = utils.MustInterface2Int64(result2["user_fee"]) - order.TotalShopMoney = utils.MustInterface2Int64(result2["shop_fee"]) - jxutils.RefreshOrderSkuRelated(order) - } else if err2Ext, ok := err2.(*utils.ErrorWithCode); !ok || err2Ext.IntCode() != ebaiapi.ErrOrderIsNotPartRefund { - err = err2 - } - } else { - err = err1 - } - return order, err -} - -func getZengSkus(orderID string, orderMan map[string]interface{}) (skus []*model.OrderSku, discountMoney int64) { - discounts, _ := orderMan["discount"].([]interface{}) - for _, v := range discounts { - discount := v.(map[string]interface{}) - discountType := utils.Interface2String(discount["type"]) - if discountType == ebaiapi.OrderSkuDiscountTypeZeng { - sku := &model.OrderSku{ - VendorOrderID: orderID, - VendorID: model.VendorIDEBAI, - Count: 1, - SkuID: 0, - VendorSkuID: "", - SkuName: utils.Interface2String(discount["desc"]), - VendorPrice: 0, - } - skus = append(skus, sku) - } - discountMoney += utils.Interface2Int64WithDefault(discount["fee"], 0) - } - return skus, discountMoney -} - -func (p *PurchaseHandler) partRefund2OrderDetailSkuList(orderID string, orderDetail2 interface{}) (skuList []*model.OrderSku) { - orderDetail := orderDetail2.([]interface{}) - for _, product2 := range orderDetail { - product := product2.(map[string]interface{}) - skuName := product["name"].(string) - _, _, _, specUnit, _, specQuality := jxutils.SplitSkuName(skuName) - number := int(utils.MustInterface2Int64(product["number"])) - sku := &model.OrderSku{ - VendorOrderID: orderID, - VendorID: model.VendorIDEBAI, - Count: number, - SkuID: int(utils.Str2Int64WithDefault(utils.Interface2String(product[ebaiapi.KeyCustomSkuID]), 0)), - VendorSkuID: utils.Interface2String(product[ebaiapi.KeySkuID]), - SkuName: skuName, - // Weight: int(utils.Interface2Int64WithDefault(product["total_weight"], 0)) / number, // 退单这里的total_weight有BUG,这里的total_weight还是没有退单时的值 - VendorPrice: utils.MustInterface2Int64(product["product_price"]), - } - sku.SalePrice, _, sku.StoreSubName = getSkuSalePrice(product) - if sku.Weight == 0 { - sku.Weight = jxutils.FormatSkuWeight(specQuality, specUnit) // 订单信息里没有重量,只有名字里尝试找 - } - skuList = append(skuList, sku) - } - return skuList -} - -func getExpectedDeliveredTime(orderMap map[string]interface{}) (expectedTime time.Time) { - expectedTime = getTimeFromInterface(orderMap["latest_send_time"]) - if utils.IsTimeZero(expectedTime) { - expectedTime = getTimeFromInterface(orderMap["send_time"]) - } - return expectedTime -} - -func (p *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) { - result := orderData - shopMap := result["shop"].(map[string]interface{}) - orderMap := result["order"].(map[string]interface{}) - userMap := result["user"].(map[string]interface{}) - vendorOrderID := orderMap["order_id"].(string) - order = &model.GoodsOrder{ - VendorOrderID: vendorOrderID, - VendorOrderID2: utils.Interface2String(orderMap["eleme_order_id"]), - VendorID: model.VendorIDEBAI, - VendorStoreID: utils.Interface2String(shopMap["baidu_shop_id"]), - StoreID: int(utils.Str2Int64WithDefault(utils.Interface2String(shopMap["id"]), 0)), - StoreName: utils.Interface2String(shopMap["name"]), - VendorUserID: utils.Interface2String(userMap["user_id"]), - ConsigneeName: utils.Interface2String(userMap["name"]), - ConsigneeMobile: jxutils.FormalizeMobile(utils.Interface2String(userMap["phone"])), - ConsigneeAddress: utils.Interface2String(userMap["address"]), - CoordinateType: model.CoordinateTypeMars, - BuyerComment: utils.TrimBlankChar(utils.Interface2String(orderMap["remark"])), - ExpectedDeliveredTime: getExpectedDeliveredTime(orderMap), - PickDeadline: utils.DefaultTimeValue, - VendorStatus: utils.Int64ToStr(utils.MustInterface2Int64(orderMap["status"])), - OrderSeq: int(utils.ForceInterface2Int64(orderMap["order_index"])), - StatusTime: getTimeFromInterface(orderMap["create_time"]), - OrderCreatedAt: getTimeFromInterface(orderMap["create_time"]), - // OrderFinishedAt: getTimeFromInterface(orderMap["finished_time"]), - OriginalData: string(utils.MustMarshal(result)), - ActualPayPrice: utils.ForceInterface2Int64(orderMap["user_fee"]), - BaseFreightMoney: utils.ForceInterface2Int64(orderMap["send_fee"]), - TotalShopMoney: utils.ForceInterface2Int64(orderMap["shop_fee"]), - DeliveryType: mapDeliveryType(int(utils.ForceInterface2Int64(orderMap["delivery_party"])), int(utils.ForceInterface2Int64(orderMap["business_type"]))), - - InvoiceTitle: utils.Interface2String(orderMap["invoice_title"]), - InvoiceTaxerID: utils.Interface2String(orderMap["taxer_id"]), - InvoiceEmail: jxutils.GetOneEmailFromStr(utils.Interface2String(orderMap["remark"])), - - VendorOrgCode: utils.Interface2String(result["source"]), - } - finishTime := getTimeFromInterface(orderMap["finished_time"]) - if finishTime == utils.ZeroTimeValue { - order.OrderFinishedAt = utils.DefaultTimeValue - } else { - order.OrderFinishedAt = finishTime - } - if utils.IsTimeZero(order.PickDeadline) && !utils.IsTimeZero(order.StatusTime) { - order.PickDeadline = order.StatusTime.Add(pickupOrderDelay) // 饿百要求在5分钟内拣货,不然订单会被取消 - } - if order.ConsigneeMobile == "" { - if mobileInfo, err := api.EbaiAPI.OrderPrivateInfo(vendorOrderID); err == nil { - order.ConsigneeMobile = jxutils.FormalizeMobile(mobileInfo.ShortNumber) - } - } - if order.StoreID > math.MaxInt32 { - order.StoreID = 0 - } - order.Status = p.getStatusFromVendorStatus(order.VendorStatus) - if utils.MustInterface2Int64(orderMap["send_immediately"]) == 1 { - order.BusinessType = model.BusinessTypeImmediate - } else { - order.BusinessType = model.BusinessTypeDingshida - if utils.IsTimeZero(order.ExpectedDeliveredTime) { - order.ExpectedDeliveredTime = getTimeFromInterface(orderMap["latest_send_time"]) - } - } - - deliveryGeo := userMap["coord_amap"].(map[string]interface{}) - originalLng := utils.Interface2Float64WithDefault(deliveryGeo["longitude"], 0.0) // 饿百的订单在过一段时间后,经纬度信息会变成字符串"**" - originalLat := utils.Interface2Float64WithDefault(deliveryGeo["latitude"], 0.0) - // lng, lat, err2 := api.AutonaviAPI.CoordinateConvert(originalLng, originalLat, autonavi.CoordSysBaidu) - // if err2 == nil { - // originalLng = lng - // originalLat = lat - // order.CoordinateType = model.CoordinateTypeMars - // } - order.ConsigneeLng = jxutils.StandardCoordinate2Int(originalLng) - order.ConsigneeLat = jxutils.StandardCoordinate2Int(originalLat) - - products := result["products"].([]interface{})[0].([]interface{}) - for _, product2 := range products { - product := product2.(map[string]interface{}) - skuName := product["product_name"].(string) - _, _, _, specUnit, _, specQuality := jxutils.SplitSkuName(skuName) - productAmount := int(utils.MustInterface2Int64(product["product_amount"])) - sku := &model.OrderSku{ - VendorOrderID: order.VendorOrderID, - VendorID: model.VendorIDEBAI, - Count: productAmount, - SkuID: int(utils.Str2Int64WithDefault(utils.Interface2String(product[ebaiapi.KeyCustomSkuID]), 0)), - VendorSkuID: utils.Interface2String(product["baidu_product_id"]), - SkuName: skuName, - Weight: int(utils.Interface2Int64WithDefault(product["total_weight"], 0)) / productAmount, - VendorPrice: utils.MustInterface2Int64(product["product_price"]), - } - var baiduRate int64 - sku.SalePrice, baiduRate, sku.StoreSubName = getSkuSalePrice(product) - order.PmSubsidyMoney += baiduRate - if sku.Weight == 0 { - sku.Weight = jxutils.FormatSkuWeight(specQuality, specUnit) // 订单信息里没有重量,只有名字里尝试找 - } - // if product["isGift"].(bool) { - // sku.SkuType = 1 - // } - order.Skus = append(order.Skus, sku) - } - giftSkus, discountMoney := getZengSkus(vendorOrderID, orderData) - order.DiscountMoney = discountMoney - order.Skus = append(order.Skus, giftSkus...) - jxutils.RefreshOrderSkuRelated(order) - return order -} - -func getSkuSalePrice(product map[string]interface{}) (salePrice, baiduRate int64, vendorActType string) { - var product2 *ebaiapi.OrderProductInfo - if err := utils.Map2StructByJson(product, &product2, true); err != nil { - return utils.MustInterface2Int64(product["product_price"]), 0, "" - } - return getSkuSalePrice2(product2) -} - -func getSkuSalePrice2(product *ebaiapi.OrderProductInfo) (salePrice, baiduRate int64, vendorActType string) { - salePrice = int64(product.ProductPrice) - if product.ProductSubsidy != nil { - for _, v := range product.ProductSubsidy.DiscountDetail { - if skuActTypeMap[v.Type] == 1 { - skuCount := product.ProductAmount - if skuCount == 0 { - skuCount = product.Number - } - salePrice -= int64(math.Round(float64(v.BaiduRate+v.ShopRate) / float64(skuCount))) // 饿百同一SKU的优惠与非优惠没有拆开,平均摊销处理 - vendorActType = v.Type - } - baiduRate += int64(v.BaiduRate) - } - } - return salePrice, baiduRate, vendorActType -} - -func (p *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) { - globals.SugarLogger.Debugf("ebai AcceptOrRefuseOrder orderID:%s, isAcceptIt:%t", order.VendorOrderID, isAcceptIt) - if isAcceptIt { - if globals.EnableEbaiStoreWrite { - err = api.EbaiAPI.OrderConfirm(order.VendorOrderID) - utils.AfterFuncWithRecover(time.Minute, func() { - err = api.EbaiAPI.OrderPickComplete(order.VendorOrderID) - }) - } - p.postFakeMsg(order.VendorOrderID, fakeAcceptOrder) - } else { - if globals.EnableEbaiStoreWrite { - err = api.EbaiAPI.OrderCancel(order.VendorOrderID, ebaiapi.CancelTypeCustom, "bu") - } - } - return err -} - -func (p *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) { - globals.SugarLogger.Debugf("ebai PickupGoods orderID:%s, isSelfDelivery:%t", order.VendorOrderID, isSelfDelivery) - if globals.EnableEbaiStoreWrite { - // err = api.EbaiAPI.OrderPickComplete(order.VendorOrderID) - } - if err == nil { - p.postFakeMsg(order.VendorOrderID, ebaiapi.OrderStatusAccepted) - } - return err -} - -func (p *PurchaseHandler) AcceptOrRefuseFailedGetOrder(ctx *jxcontext.Context, order *model.GoodsOrder, isAcceptIt bool) (err error) { - return err -} - -func (p *PurchaseHandler) CallCourier(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 拣货失败后再次招唤平台配送 - return err -} - -func (p *PurchaseHandler) ConfirmReceiveGoods(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 投递失败后确认收到退货 - return err -} - -// 将订单从购物平台配送转为自送 -func (p *PurchaseHandler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) { - globals.SugarLogger.Debugf("ebai Swtich2SelfDeliver orderID:%s", order.VendorOrderID) - if globals.EnableEbaiStoreWrite { - if err = api.EbaiAPI.OrderSwitchselfdelivery(order.VendorOrderID); err != nil { - if utils.IsErrMatch(err, "301251", nil) { - if deliveryStatus, err2 := api.EbaiAPI.OrderDeliveryGet(order.VendorOrderID); err2 == nil { - deliveryStatus := utils.Int64ToStr(utils.MustInterface2Int64(deliveryStatus["status"])) - if deliveryStatus == ebaiapi.WaybillStatusSelfDelivery { - err = nil - } else if deliveryStatus == ebaiapi.WaybillStatusDeliveryCancled { - p.trySyncCancelStatus(order.VendorOrderID) - } - } - } - } - } - if err == nil { - // 饿百不会发送配送中,模拟发送 - p.postFakeMsg(order.VendorOrderID, ebaiapi.OrderStatusCourierAccepted) - } - return err -} - -func (p *PurchaseHandler) trySyncCancelStatus(vendorOrderID string) (err error) { - orderInfo, err := api.EbaiAPI.OrderGet2(vendorOrderID) - if err == nil { - if utils.Int2Str(orderInfo.Order.Status) == ebaiapi.OrderStatusCanceled { - p.postFakeMsg(vendorOrderID, fakeOrderCanceled) - } - } - return err -} - -// 将订单从购物平台配送转为自送后又送达 -func (p *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName string) (err error) { - globals.SugarLogger.Debugf("ebai Swtich2SelfDelivered orderID:%s", order.VendorOrderID) - // todo 饿百转商家自送后,没有确认送达的概念,空操作 - return err -} - -// 完全自送的门店表示开始配送 -func (p *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) { - globals.SugarLogger.Debugf("ebai SelfDeliverDelivering orderID:%s", order.VendorOrderID) - if globals.EnableEbaiStoreWrite { - err = api.EbaiAPI.OrderSendOut(order.VendorOrderID, userName) - } - if err == nil { - // 饿百不会发送配送中,模拟发送 - p.postFakeMsg(order.VendorOrderID, ebaiapi.OrderStatusCourierAccepted) - } - return err -} - -// 完全自送的门店表示配送完成 -func (p *PurchaseHandler) SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) { - globals.SugarLogger.Debugf("ebai SelfDeliverDelivered orderID:%s", order.VendorOrderID) - if globals.EnableEbaiStoreWrite { - err = api.EbaiAPI.OrderComplete(order.VendorOrderID, userName) - } - return err -} - -// -func (c *PurchaseHandler) onOrderMsg(msg *ebaiapi.CallbackMsg) (retVal *ebaiapi.CallbackResponse) { - if c.isAfsMsg(msg) { - retVal = c.onAfsOrderMsg(msg) - } else { - status := c.callbackMsg2Status(msg) - if partner.CurOrderManager.GetStatusDuplicatedCount(status) > 0 { - return nil - } - if ebaiapi.CmdOrderCreate == msg.Cmd { - retVal = c.onOrderNew(msg, status) - } else { - var err error - if status != nil { - if status.Status == model.OrderStatusAdjust { - var order *model.GoodsOrder - if order, err = c.GetOrder4PartRefund(GetOrderIDFromMsg(msg)); err == nil { - err = partner.CurOrderManager.OnOrderAdjust(order, status) - } - } else { - // 处理饿百降级订单的情况 - // 是否降级;1:是,0:否;极少数订单因网络或信息交互异常,导致订单部分字段(如订单金额)生成延迟,此时订单会被标记为“已降级”状态,需开发者重新调用查看订单详情接口获取完整订单数据。 - // toto sku是否也需要处理? - if status.Status == model.OrderStatusDelivering || status.Status == model.OrderStatusFinished { - if order, err2 := partner.CurOrderManager.LoadOrder(status.VendorOrderID, status.VendorID); err2 == nil { - if order.TotalShopMoney == 0 { - if order2, err2 := c.GetOrder(msg.Source, status.VendorOrderID); err2 == nil { - order.TotalShopMoney = order2.TotalShopMoney - order.PmSubsidyMoney = order2.PmSubsidyMoney - partner.CurOrderManager.UpdateOrderFields(order, []string{"TotalShopMoney", "PmSubsidyMoney"}) - } - } - } - } - err = partner.CurOrderManager.OnOrderStatusChanged(msg.Source, status) - } - } - retVal = api.EbaiAPI.Err2CallbackResponse(msg.Cmd, err, nil) - } - } - return retVal -} - -func (c *PurchaseHandler) onOrderNew(msg *ebaiapi.CallbackMsg, orderStatus *model.OrderStatus) (response *ebaiapi.CallbackResponse) { - vendorOrderID := GetOrderIDFromMsg(msg) - order, orderMap, err := c.getOrder(vendorOrderID) - if err == nil { - // 饿百订单有时会出现取不到baidu_shop_id的情况,返回错误让服务器重试 - if order.VendorStoreID == "" { - return api.EbaiAPI.Err2CallbackResponse(msg.Cmd, fmt.Errorf("订单%s的baidu_shop_id为空", order.VendorOrderID), "") - } - if err = partner.CurOrderManager.OnOrderNew(order, orderStatus); err == nil { - utils.CallFuncAsync(func() { - c.OnOrderDetail(orderMap, partner.CreatedPeration) - }) - } - } - return api.EbaiAPI.Err2CallbackResponse(msg.Cmd, err, map[string]interface{}{ - "source_order_id": vendorOrderID, - }) -} - -func (c *PurchaseHandler) callbackMsg2Status(msg *ebaiapi.CallbackMsg) (orderStatus *model.OrderStatus) { - orderID := GetOrderIDFromMsg(msg) - orderStatus = &model.OrderStatus{ - VendorOrderID: orderID, - VendorID: model.VendorIDEBAI, - OrderType: model.OrderTypeOrder, - RefVendorOrderID: orderID, - RefVendorID: model.VendorIDEBAI, - StatusTime: utils.Timestamp2Time(msg.Timestamp), - VendorStatus: msg.Cmd, - } - if msg.Cmd == ebaiapi.CmdOrderUserCancel { - msgType := int(utils.MustInterface2Int64(msg.Body["type"])) - cancelType := int(utils.MustInterface2Int64(msg.Body["cancel_type"])) - orderStatus.Remark = buildFullReason(utils.Interface2String(msg.Body["cancel_reason"]), utils.Interface2String(msg.Body["addition_reason"])) - orderStatus.VendorStatus = msg.Cmd + "-" + utils.Int2Str(msgType) - if cancelType == ebaiapi.OrderUserCancelTypeBeforeSale { - if msgType == ebaiapi.OrderUserCancelApply /* || msgType == ebaiapi.OrderUserCancelCSIntervene */ { - orderStatus.Status = model.OrderStatusApplyCancel - } else if msgType == ebaiapi.OrderUserCancelCSRefused || - msgType == ebaiapi.OrderUserCancelMerchantRefused { - orderStatus.Status = model.OrderStatusVendorRejectCancel - } else if msgType == ebaiapi.OrderUserCancelInvalid { - orderStatus.Status = model.OrderStatusUndoApplyCancel - } else if msgType == ebaiapi.OrderUserCancelCSAgreed || - msgType == ebaiapi.OrderUserCancelMerchantAgreed { - orderStatus.Status = model.OrderStatusVendorAgreeCancel - } - } - } else if msg.Cmd == ebaiapi.CmdOrderPartRefund { - msgType := int(utils.MustInterface2Int64(msg.Body["type"])) - status := int(utils.MustInterface2Int64(msg.Body["status"])) - orderStatus.Remark = buildFullReason(utils.Interface2String(msg.Body["reason"]), utils.Interface2String(msg.Body["addition_reason"])) - if msgType == ebaiapi.OrderPartRefuncTypeMerchant && status == ebaiapi.OrderPartRefundSuccess { - orderStatus.VendorStatus = fakeOrderAdjustFinished - } - } else if status, ok := msg.Body["status"]; ok { - if vendorStatus, ok := status.(string); ok { - orderStatus.VendorStatus = vendorStatus - } else { - orderStatus.VendorStatus = utils.Int64ToStr(utils.MustInterface2Int64(status)) - } - orderStatus.Remark = utils.Interface2String(msg.Body["reason"]) - } - if orderStatus.Status == 0 { - orderStatus.Status = c.getStatusFromVendorStatus(orderStatus.VendorStatus) - } - return orderStatus -} - -func buildFullReason(reason, addReason string) (fullReason string) { - fullReason = reason - if addReason != "" { - fullReason += ",额外原因:" + addReason - } - return fullReason -} - -func (c *PurchaseHandler) GetStatusActionTimeout(order *model.GoodsOrder, statusType, status int) (params *partner.StatusActionParams) { - if statusType == scheduler.TimerStatusTypeOrder && status == model.OrderStatusAccepted { - params = &partner.StatusActionParams{ // PickDeadline没有设置时才有效,饿百要求在5分钟内拣货,不然订单会被取消 - Timeout: pickupOrderDelay, - } - } else if statusType == scheduler.TimerStatusTypeOrder && status == model.OrderStatusFinishedPickup { - params = &partner.StatusActionParams{ // 立即达订单有效,自配送延时召唤配送 - Timeout: callDeliveryDelay, - TimeoutGap: callDeliveryDelayGap, - } - } - return params -} - -func (c *PurchaseHandler) getOrderStoreDeliveryType(order *model.GoodsOrder) (deliveryType int) { - sql := ` - SELECT * - FROM store_map t1 - WHERE t1.vendor_store_id = ? - AND t1.vendor_id = ? - AND t1.deleted_at = ? - ` - db := dao.GetDB() - var storeMap *model.StoreMap - if err := dao.GetRow(db, &storeMap, sql, order.VendorStoreID, model.VendorIDEBAI, utils.DefaultTimeValue); err == nil { - return int(storeMap.DeliveryType) - } else if !dao.IsNoRowsError(err) { - globals.SugarLogger.Warnf("getOrderStoreDeliveryType orderID:%s failed with error:%v", order.VendorOrderID, err) - } - return scheduler.StoreDeliveryTypeByPlatform -} - -func (c *PurchaseHandler) postFakeMsg(vendorOrderID, vendorStatus string) { - msg := &ebaiapi.CallbackMsg{ - Cmd: ebaiapi.CmdOrderStatus, - Timestamp: time.Now().Unix(), - Body: map[string]interface{}{ - "status": vendorStatus, - "order_id": vendorOrderID, - }, - } - utils.CallFuncAsync(func() { - OnCallbackMsg(msg) - }) -} - -func getTimeFromInterface(timeValue interface{}) time.Time { - var timeStamp int64 - if timeStr, ok := timeValue.(string); ok { - timeStamp = utils.Str2Int64WithDefault(timeStr, 0) - } else { - timeStamp = utils.Interface2Int64WithDefault(timeValue, 0) - } - if timeStamp < 1538103149 { // 立即达订单给的是1(而不是空,0),1538103149不是特殊值,只是一个任意之前的时间,这样写可以处理 - return utils.DefaultTimeValue - } - return utils.Timestamp2Time(timeStamp) -} - -func (c *PurchaseHandler) GetOrderRealMobile(ctx *jxcontext.Context, order *model.GoodsOrder) (mobile string, err error) { - mobile, err = api.EbaiAPI.GetRealMobile4Order(order.VendorOrderID) - return mobile, err -} - -func (c *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) { - if globals.EnableEbaiStoreWrite { - if isAgree { - err = api.EbaiAPI.OrderAgreeRefund(order.VendorOrderID) - } else { - err = api.EbaiAPI.OrderDisagreeRefund(order.VendorOrderID, reason) - } - } - return err -} - -func (c *PurchaseHandler) CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) { - if globals.EnableEbaiStoreWrite { - err = api.EbaiAPI.OrderCancel(order.VendorOrderID, ebaiapi.CancelTypeCustom, reason) - } - return err -} - -func (c *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) { - // 饿百必须要确认订单后才能调整单 - if order.Status < model.OrderStatusFinishedPickup { - err = c.PickupGoods(order, false, ctx.GetUserName()) - } - if err == nil { - var skuList []*ebaiapi.RefundSku - for _, sku := range removedSkuList { - skuList = append(skuList, &ebaiapi.RefundSku{ - CustomeSkuID: utils.Int2Str(jxutils.GetSkuIDFromOrderSku(sku)), - Number: utils.Int2Str(sku.Count), - }) - } - if globals.EnableEbaiStoreWrite { - err = api.EbaiAPI.OrderPartRefund(order.VendorOrderID, skuList) - } - } - return err -} - -func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, queryDate time.Time, vendorStoreID string) (vendorOrderIDs []string, err error) { - if utils.IsTimeZero(queryDate) { - return nil, fmt.Errorf("queryDate必须指定") - } - fromDate := utils.Time2Date(queryDate) - toDate := fromDate.Add(24*time.Hour - 1) - var vendorStoreIDs []string - if vendorStoreID == "" { - vendorStoreIDs, err = c.GetAllStoresVendorID(ctx, "") - if err != nil { - return nil, err - } - } else { - vendorStoreIDs = []string{vendorStoreID} - } - task := tasksch.NewParallelTask("ebai ListOrders", nil, ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - vendorStoreID := batchItemList[0].(string) - orderList, err := api.EbaiAPI.OrderListAll("", utils.Str2Int64(vendorStoreID), fromDate.Unix(), toDate.Unix(), 0) - if err == nil { - retVal = orderList - } - return retVal, err - }, vendorStoreIDs) - tasksch.HandleTask(task, parentTask, true).Run() - orderList, err := task.GetResult(0) - if err == nil && len(orderList) > 0 { - vendorOrderIDs = make([]string, len(orderList)) - for k, v := range orderList { - orderInfo := v.(*ebaiapi.ListOrderItemInfo) - vendorOrderIDs[k] = orderInfo.OrderID - } - } - return vendorOrderIDs, err -} - -func (c *PurchaseHandler) GetWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2 string) (tipFee int64, err error) { - orderInfo, err := api.EbaiAPI.GetStoreOrderInfo(vendorOrderID) - if err == nil { - if orderBasic, _ := orderInfo["order_basic"].(map[string]interface{}); orderBasic != nil { - tipFee = jxutils.StandardPrice2Int(utils.Interface2Float64WithDefault(orderBasic["delivery_tip_amount"], 0)) - } - } - return tipFee, err -} - -func (c *PurchaseHandler) UpdateWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2, cityCode string, tipFee int64) (err error) { - if globals.EnableEbaiStoreWrite { - err = api.EbaiAPI.ModifyTip4OrderWaybill(vendorOrderID, "", jxutils.IntPrice2Standard(tipFee), 0) - if err != nil { - if strings.Contains(err.Error(), "HTTP code is not 200") { - return fmt.Errorf("饿百此订单暂不支持加小费!") - } - } - } - return err -} diff --git a/business/partner/purchase/ebai/order_afs.go b/business/partner/purchase/ebai/order_afs.go deleted file mode 100644 index f9f67f0c7..000000000 --- a/business/partner/purchase/ebai/order_afs.go +++ /dev/null @@ -1,227 +0,0 @@ -package ebai - -import ( - "fmt" - "strings" - - "git.rosy.net.cn/baseapi/platformapi/ebaiapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -var ( - AfsVendorStatus2Status4PartRefundMap = map[int]int{ - ebaiapi.OrderPartRefundApply: model.AfsOrderStatusWait4Approve, - ebaiapi.OrderPartRefundSuccess: model.AfsOrderStatusFinished, - ebaiapi.OrderPartRefundUserApplyArbitration: model.OrderStatusUnknown, // 是否是中间状态 - ebaiapi.OrderPartRefundFailed: model.AfsOrderStatusFailed, - ebaiapi.OrderPartRefundMerchantRefused: model.AfsOrderStatusFailed, // 是否是中间状态 - } - AfsVendorStatus2Status4UserCancel = map[int]int{ - ebaiapi.OrderUserCancelApply: model.AfsOrderStatusWait4Approve, - ebaiapi.OrderUserCancelCSIntervene: model.OrderStatusUnknown, - ebaiapi.OrderUserCancelCSRefused: model.AfsOrderStatusFailed, - ebaiapi.OrderUserCancelCSAgreed: model.AfsOrderStatusFinished, - ebaiapi.OrderUserCancelMerchantRefused: model.AfsOrderStatusFailed, - ebaiapi.OrderUserCancelMerchantAgreed: model.AfsOrderStatusFinished, - ebaiapi.OrderUserCancelInvalid: model.AfsOrderStatusFailed, - } -) - -func (c *PurchaseHandler) isAfsMsg(msg *ebaiapi.CallbackMsg) bool { - if msg.Cmd == ebaiapi.CmdOrderPartRefund { - msgType := int(utils.MustInterface2Int64(msg.Body["type"])) - return msgType == ebaiapi.OrderPartRefuncTypeCustomer - } else if msg.Cmd == ebaiapi.CmdOrderUserCancel { - cancelType := int(utils.MustInterface2Int64(msg.Body["cancel_type"])) - return cancelType == ebaiapi.OrderUserCancelTypeAfterSale - } - return false -} - -func (c *PurchaseHandler) OnAfsOrderMsg(msg *ebaiapi.CallbackMsg) (retVal *ebaiapi.CallbackResponse) { - jxutils.CallMsgHandlerAsync(func() { - retVal = c.onAfsOrderMsg(msg) - }, jxutils.ComposeUniversalOrderID(GetOrderIDFromMsg(msg), model.VendorIDEBAI)) - return retVal -} - -func (c *PurchaseHandler) onAfsOrderMsg(msg *ebaiapi.CallbackMsg) (retVal *ebaiapi.CallbackResponse) { - if orderStatus := c.callbackAfsMsg2Status(msg); orderStatus != nil { - var err error - if orderStatus.Status == model.AfsOrderStatusWait4Approve || orderStatus.Status == model.AfsOrderStatusNew { - var afsOrder *model.AfsOrder - if msg.Cmd == ebaiapi.CmdOrderPartRefund { - partRefundData := msg.Data.(*ebaiapi.CBPartRefundInfo) - afsOrder = &model.AfsOrder{ - VendorID: model.VendorIDEBAI, - AfsOrderID: orderStatus.VendorOrderID, - VendorOrderID: orderStatus.RefVendorOrderID, - VendorStoreID: "", - StoreID: 0, - AfsCreatedAt: utils.Timestamp2Time(msg.Timestamp), - VendorAppealType: "", - AppealType: model.AfsAppealTypeRefund, - VendorReasonType: partRefundData.ReasonType, - ReasonType: c.convertAfsReasonType(partRefundData.ReasonType), - ReasonDesc: utils.LimitUTF8StringLen(buildFullReason(partRefundData.Reason, partRefundData.AdditionReason), 1024), - ReasonImgList: utils.LimitUTF8StringLen(strings.Join(partRefundData.Photos, ","), 1024), - RefundType: model.AfsTypePartRefund, - - VendorOrgCode: msg.Source, - // FreightUserMoney: afsInfo.OrderFreightMoney, - // AfsFreightMoney: afsInfo.AfsFreight, - // BoxMoney: afsInfo.PackagingMoney, - // TongchengFreightMoney: afsInfo.TongchengFreightMoney, - // SkuBoxMoney: afsInfo.MealBoxMoney, - } - for _, sku := range partRefundData.RefundProducts { - orderSku := &model.OrderSkuFinancial{ - // VendorID: model.VendorIDEBAI, - // AfsOrderID: afsOrder.AfsOrderID, - // VendorOrderID: afsOrder.VendorOrderID, - // VendorStoreID: afsOrder.VendorStoreID, - // StoreID: afsOrder.StoreID, - // IsAfsOrder: 1, - - Count: sku.Number, - // ConfirmTime: afsOrder.AfsCreateAt, - VendorSkuID: sku.SkuID, - SkuID: int(utils.Str2Int64WithDefault(sku.CustomSkuID, 0)), - Name: sku.Name, - UserMoney: sku.TotalRefund, - PmSkuSubsidyMoney: sku.ShopEleRefund, - } - afsOrder.SkuUserMoney += orderSku.UserMoney - afsOrder.PmSubsidyMoney += orderSku.PmSubsidyMoney - afsOrder.Skus = append(afsOrder.Skus, orderSku) - } - } else if msg.Cmd == ebaiapi.CmdOrderUserCancel { - if afsOrder = c.createAfsOrder(msg); afsOrder != nil { - // if orderFinancial, err2 := partner.CurOrderManager.LoadOrderFinancial(orderStatus.RefVendorOrderID, model.VendorIDEBAI); err2 == nil { - // afsOrder = c.OrderFinancialDetail2Refund(orderFinancial, msg) - cancelData := msg.Data.(*ebaiapi.CBUserCancelInfo) - afsOrder.AfsOrderID = orderStatus.VendorOrderID - afsOrder.RefundType = model.AfsTypeFullRefund - afsOrder.AppealType = model.AfsAppealTypeRefund - afsOrder.VendorReasonType = "" - afsOrder.ReasonType = model.AfsReasonNotOthers - afsOrder.ReasonDesc = utils.LimitUTF8StringLen(buildFullReason(cancelData.CancelReason, cancelData.AdditionReason), 1024) - afsOrder.ReasonImgList = utils.LimitUTF8StringLen(strings.Join(cancelData.Pictures, ","), 1024) - } - } - if afsOrder != nil { - err = partner.CurOrderManager.OnAfsOrderNew(afsOrder, orderStatus) - } - } else { - err = partner.CurOrderManager.OnAfsOrderStatusChanged(orderStatus) - } - retVal = api.EbaiAPI.Err2CallbackResponse(msg.Cmd, err, nil) - } - return retVal -} - -func (p *PurchaseHandler) createAfsOrder(msg *ebaiapi.CallbackMsg) (afsOrder *model.AfsOrder) { - cancelData := msg.Data.(*ebaiapi.CBUserCancelInfo) - afsOrder, err := partner.CurOrderManager.CreateAfsOrderFromOrder(utils.Int64ToStr(cancelData.OrderID), model.VendorIDEBAI) - if err == nil { - afsOrder.AfsOrderID = afsOrder.VendorOrderID - afsOrder.AfsCreatedAt = utils.Timestamp2Time(msg.Timestamp) - } else { - afsOrder = nil - } - return afsOrder -} - -func (c *PurchaseHandler) convertAfsReasonType(vendorReasonType string) int8 { - return model.AfsReasonNotOthers -} - -func (c *PurchaseHandler) GetAfsStatusFromVendorStatus4PartRefund(vendorStatus int) int { - return AfsVendorStatus2Status4PartRefundMap[vendorStatus] -} - -func (c *PurchaseHandler) GetAfsStatusFromVendorStatus4UserCancel(vendorStatus int) int { - return AfsVendorStatus2Status4UserCancel[vendorStatus] -} - -func (c *PurchaseHandler) callbackAfsMsg2Status(msg *ebaiapi.CallbackMsg) (orderStatus *model.OrderStatus) { - if msg.Cmd == ebaiapi.CmdOrderPartRefund { - partRefundData := msg.Data.(*ebaiapi.CBPartRefundInfo) - orderStatus = &model.OrderStatus{ - VendorOrderID: partRefundData.RefundID, // 是售后单ID,不是订单ID,订单ID在RefVendorOrderID中 - VendorID: model.VendorIDEBAI, - OrderType: model.OrderTypeAfsOrder, - RefVendorOrderID: utils.Int64ToStr(partRefundData.OrderID), - RefVendorID: model.VendorIDEBAI, - VendorStatus: utils.Int2Str(partRefundData.Status), - Status: c.GetAfsStatusFromVendorStatus4PartRefund(partRefundData.Status), - StatusTime: utils.Timestamp2Time(msg.Timestamp), - Remark: buildFullReason(partRefundData.Reason, partRefundData.AdditionReason), - } - if orderStatus.Status == model.AfsOrderStatusWait4Approve && partRefundData.Type != ebaiapi.OrderPartRefuncTypeCustomer { - orderStatus.Status = model.AfsOrderStatusNew - } - } else if msg.Cmd == ebaiapi.CmdOrderUserCancel { - cancelData := msg.Data.(*ebaiapi.CBUserCancelInfo) - orderStatus = &model.OrderStatus{ - VendorOrderID: utils.Int64ToStr(cancelData.OrderID), // 是售后单ID,不是订单ID,订单ID在RefVendorOrderID中 - VendorID: model.VendorIDEBAI, - OrderType: model.OrderTypeAfsOrder, - RefVendorOrderID: utils.Int64ToStr(cancelData.OrderID), - RefVendorID: model.VendorIDEBAI, - VendorStatus: utils.Int2Str(cancelData.Type), - Status: c.GetAfsStatusFromVendorStatus4UserCancel(cancelData.Type), - StatusTime: utils.Timestamp2Time(msg.Timestamp), - Remark: buildFullReason(cancelData.CancelReason, cancelData.AdditionReason), - } - } - return orderStatus -} - -// 审核售后单申请 -func (c *PurchaseHandler) AgreeOrRefuseRefund(ctx *jxcontext.Context, order *model.AfsOrder, approveType int, reason string) (err error) { - if globals.EnableEbaiStoreWrite { - if approveType == partner.AfsApproveTypeRefused { - err = api.EbaiAPI.OrderDisagreeRefund(order.VendorOrderID, reason) - } else { - err = api.EbaiAPI.OrderAgreeRefund(order.VendorOrderID) - } - } - return err -} - -// 确认收到退货 -func (c *PurchaseHandler) ConfirmReceivedReturnGoods(ctx *jxcontext.Context, order *model.AfsOrder) (err error) { - err = fmt.Errorf("内部错误,饿百平台不支持确认收到退货操作") - return err -} - -// 发起全款退款 -func (c *PurchaseHandler) RefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) { - return c.PartRefundOrder(ctx, order, order.Skus, reason) -} - -// 发起部分退款 -func (c *PurchaseHandler) PartRefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, refundSkuList []*model.OrderSku, reason string) (err error) { - if globals.EnableEbaiStoreWrite { - err = api.EbaiAPI.OrderPartRefund(order.VendorOrderID, orderSkus2AfsSkus(refundSkuList)) - } - return err -} - -func orderSkus2AfsSkus(refundSkuList []*model.OrderSku) (removeSkuList []*ebaiapi.RefundSku) { - for _, v := range refundSkuList { - refundSku := &ebaiapi.RefundSku{ - CustomeSkuID: utils.Int2Str(v.SkuID), - Number: utils.Int2Str(v.Count), - } - removeSkuList = append(removeSkuList, refundSku) - } - return removeSkuList -} diff --git a/business/partner/purchase/ebai/order_comment.go b/business/partner/purchase/ebai/order_comment.go deleted file mode 100644 index eef56da63..000000000 --- a/business/partner/purchase/ebai/order_comment.go +++ /dev/null @@ -1,102 +0,0 @@ -package ebai - -import ( - "time" - - "git.rosy.net.cn/baseapi/platformapi/ebaiapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -// 饿百的评价不是一点一点出来的,而是一下把前一天的全部崩出来。。。 - -const ( - RefreshCommentTime = 84 * time.Hour - RefreshCommentTimeInterval = 60 * time.Minute - EBAI_BAD_COMMENTS_MAX_MODIFY_TIME = 24 // 小时 -) - -func (c *PurchaseHandler) StartRefreshComment() { - utils.AfterFuncWithRecover(5*time.Second, func() { - c.refreshCommentOnce() - }) -} - -func (c *PurchaseHandler) refreshCommentOnce() { - c.RefreshComment(time.Now().Add(-RefreshCommentTime), time.Now()) - utils.AfterFuncWithRecover(RefreshCommentTimeInterval, func() { - c.refreshCommentOnce() - }) -} - -func (c *PurchaseHandler) RefreshComment(fromTime, toTime time.Time) (err error) { - globals.SugarLogger.Debugf("RefreshComment fromTime:%s, toTime:%s", utils.Time2Str(fromTime), utils.Time2Str(toTime)) - var orderCommentList []*model.OrderComment - stepGap := 24 * time.Hour - stepFromTime := fromTime - for { - stepToTime := stepFromTime.Add(stepGap - time.Second) - if stepToTime.Sub(toTime) > 0 { - stepToTime = toTime - } - if stepToTime.Sub(stepFromTime) == 0 { - break - } - resultList, err2 := api.EbaiAPI.GetEleCommentList(stepFromTime, stepToTime, "", "", ebaiapi.ReplyStatusAll, ebaiapi.CommentLevelAll, ebaiapi.CommentContentAll) - if err = err2; err == nil { - for _, result := range resultList { - orderComment := &model.OrderComment{ - VendorOrderID: utils.Interface2String(result["order_id"]), - VendorID: model.VendorIDELM, - UserCommentID: utils.Int64ToStr(utils.MustInterface2Int64(result["comment_id"])), - // VendorStoreID: utils.Int64ToStr(utils.MustInterface2Int64(result["shop_id"])), // 这个shop_id是饿了么ID,不是饿百ID - TagList: "", - Score: int8(utils.MustInterface2Int64(result["service_rating"])), - Content: utils.Interface2String(result["content"]), - CommentCreatedAt: utils.Str2Time(utils.Interface2String(result["create_time"])), - IsReplied: int8(1 - utils.MustInterface2Int64(result["can_reply"])), - ModifyDuration: EBAI_BAD_COMMENTS_MAX_MODIFY_TIME, - OriginalMsg: string(utils.MustMarshal(result)), - } - // 直接得到的订单是饿了么的,尝试统一成饿百 - if order, err := partner.CurOrderManager.LoadOrder2(orderComment.VendorOrderID, model.VendorIDEBAI); err == nil { - orderComment.VendorOrderID = order.VendorOrderID - orderComment.VendorOrderID2 = order.VendorOrderID2 - orderComment.VendorID = model.VendorIDEBAI - - orderComment.VendorStoreID = order.VendorStoreID - orderComment.StoreID = jxutils.GetSaleStoreIDFromOrder(order) - orderComment.ConsigneeMobile = order.ConsigneeMobile - } else { - globals.SugarLogger.Infof("RefreshComment, load orderID:%s failed", orderComment.VendorOrderID) - } - orderCommentList = append(orderCommentList, orderComment) - } - } else { - // globals.SugarLogger.Warnf("RefreshComment stepFromTime:%s, stepToTime:%s failed with error:%v", utils.Time2Str(stepFromTime), utils.Time2Str(stepToTime), err) - // break //? - } - if stepToTime.Sub(toTime) == 0 { - break - } - stepFromTime = stepToTime.Add(time.Second) - } - if err == nil && len(orderCommentList) > 0 { - err = partner.CurOrderManager.OnOrderComments(orderCommentList) - } - return err -} - -func (c *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, vendorOrgCode string,orderComment *model.OrderComment, replyComment string) (err error) { - if orderComment.VendorStoreID != "" && orderComment.UserCommentID != "" { - if globals.EnableEbaiStoreWrite { - err = api.EbaiAPI.OrderRatesReply("", utils.Str2Int64(orderComment.VendorStoreID), orderComment.UserCommentID, replyComment) - } - } - return err -} diff --git a/business/partner/purchase/ebai/order_test.go b/business/partner/purchase/ebai/order_test.go deleted file mode 100644 index 239b3d356..000000000 --- a/business/partner/purchase/ebai/order_test.go +++ /dev/null @@ -1,27 +0,0 @@ -package ebai - -import ( - "testing" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - - "git.rosy.net.cn/baseapi/utils" -) - -func TestGetOrder4PartRefund(t *testing.T) { - order, err := CurPurchaseHandler.GetOrder4PartRefund("1556529608021993938") - if err != nil { - t.Fatal(err.Error()) - } else { - t.Log(utils.Format4Output(order, false)) - } -} - -func TestListOrders(t *testing.T) { - order, err := CurPurchaseHandler.ListOrders(jxcontext.AdminCtx, "", nil, utils.GetCurDate(), "") - if err != nil { - t.Fatal(err.Error()) - } else { - t.Log(utils.Format4Output(order, false)) - } -} diff --git a/business/partner/purchase/ebai/store.go b/business/partner/purchase/ebai/store.go deleted file mode 100644 index e2591a6b7..000000000 --- a/business/partner/purchase/ebai/store.go +++ /dev/null @@ -1,552 +0,0 @@ -package ebai - -import ( - "fmt" - "strings" - - "git.rosy.net.cn/baseapi/platformapi/autonavi" - "git.rosy.net.cn/baseapi/platformapi/ebaiapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -type tEbaiStoreInfo struct { - model.Store - VendorOrgCode string `orm:"size(32)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空 - VendorStoreID string `orm:"column(vendor_store_id)"` - RealLastOperator string - EbaiStoreStatus int - SyncStatus int - - ProvinceID int `orm:"column(province_id)"` - CityID int `orm:"column(city_id)"` - DistrictID int `orm:"column(district_id)"` - VendorStoreName string -} - -func (p *PurchaseHandler) CreateStore(db *dao.DaoDB, storeID int, userName string) (vendorStoreID string, err error) { - var store tEbaiStoreInfo - sql := ` - SELECT t1.*, t2.status ebai_store_status, t2.vendor_store_id, - IF(t1.updated_at > t2.updated_at, t1.last_operator, t2.last_operator) real_last_operator, t2.sync_status, - province.ebai_code province_id, city.ebai_code city_id, district.ebai_code district_id - FROM store t1 - LEFT JOIN store_map t2 ON t1.id = t2.store_id AND t2.vendor_id = ? AND t2.deleted_at = ? - JOIN place district ON t1.district_code = district.code - JOIN place city ON t1.city_code = city.code - JOIN place province ON city.parent_code = province.code - WHERE t1.id = ? AND t2.id IS NULL; - ` - if err = dao.GetRow(db, &store, sql, model.VendorIDEBAI, utils.DefaultTimeValue, storeID); err == nil { - params := genStoreMapFromStore(&store) - params["shop_id"] = store.ID - params["business_form_id"] = "179" - params["service_phone"] = store.Tel1 - params["invoice_support"] = 2 - params["package_box_price"] = 0 - params["encrypt"] = "" - - params["category1"] = "" - params["category2"] = "" - params["category3"] = "" - if globals.EnableEbaiStoreWrite { - intVendorStoreID, err2 := api.EbaiAPI.ShopCreate(params) - if err = err2; err == nil { - return utils.Int64ToStr(intVendorStoreID), err - } - } else { - return utils.Int64ToStr(jxutils.GenFakeID()), nil - } - } - return "", err -} - -// 2019-07-26 疑似饿百将门店返回的坐标类型从float64改为string了 -func getCoordintate(data interface{}) float64 { - if str, ok := data.(string); ok { - return utils.Str2Float64WithDefault(str, 0) - } - return utils.MustInterface2Float64(data) -} - -func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string) (*dao.StoreDetail, error) { - baiduShopID := utils.Str2Int64WithDefault(vendorStoreID, 0) - if baiduShopID == 0 { - return nil, fmt.Errorf("饿百门店ID:%s非法,应该是一个整数", vendorStoreID) - } - result, err := api.EbaiAPI.ShopGet("", baiduShopID) - if err == nil { - // globals.SugarLogger.Debug(utils.Format4Output(result, false)) - retVal := &dao.StoreDetail{ - Store: model.Store{ - Address: utils.Interface2String(result["address"]), - Tel1: utils.Interface2String(result["phone"]), - }, - } - retVal.OriginalName = utils.Interface2String(result["name"]) - _, retVal.Name = jxutils.SplitStoreName(retVal.OriginalName, partner.StoreNameSeparator, globals.StoreNameEbai) - retVal.DeliveryType = EbaiDeliveryType2Jx(utils.Interface2String(result["delivery_type"])) - - retVal.SetOpTime(ebaiOpTime2Jx(result["business_time"])) - retVal.Status, _ = p.GetStoreStatus(ctx, vendorOrgCode, 0, vendorStoreID) - - tel2 := utils.Interface2String(result["ivr_phone"]) - if tel2 != "" && tel2 != retVal.Tel1 { - retVal.Tel2 = tel2 - } - - lng := getCoordintate(result["longitude"]) - lat := getCoordintate(result["latitude"]) - if utils.Interface2String(result["coord_type"]) == ebaiapi.CoordTypeBaidu { - var err2 error - if lng, lat, err2 = api.AutonaviAPI.CoordinateConvert(lng, lat, autonavi.CoordSysBaidu); err2 != nil { - return nil, err2 - } - } - retVal.Lng = jxutils.StandardCoordinate2Int(lng) - retVal.Lat = jxutils.StandardCoordinate2Int(lat) - - db := dao.GetDB() - if city, err2 := dao.GetPlaceByName(db, utils.Interface2String(result["city"]), model.PlaceLevelCity, 0); err2 == nil { - retVal.CityCode = city.Code - retVal.CityName = utils.Interface2String(result["city"]) - districtName := utils.Interface2String(result["county"]) - if retVal.CityCode != 0 && districtName != "" { - if district, err2 := dao.GetPlaceByName(db, utils.Interface2String(result["county"]), model.PlaceLevelDistrict, city.Code); err2 == nil { - retVal.DistrictCode = district.Code - } - } - } - if retVal.DistrictCode == 0 { - retVal.DistrictCode = api.AutonaviAPI.GetCoordinateDistrictCode(lng, lat) - if retVal.CityCode == 0 { - if district, err := dao.GetPlaceByCode(db, retVal.DistrictCode); err == nil { - retVal.CityCode = district.ParentCode - } - } - } - retVal.VendorStoreID = vendorStoreID - retVal.ID = int(utils.Str2Int64WithDefault(utils.Interface2String(result["shop_id"]), 0)) - retVal.DeliveryRangeType = model.DeliveryRangeTypePolygon - retVal.DeliveryRange = EbaiDeliveryRegion2Jx(result["delivery_region"]) - - return retVal, nil - } - return nil, err -} - -func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName string) (err error) { - globals.SugarLogger.Debugf("ebai UpdateStore storeID:%d, userName:%s", storeID, userName) - - var stores []*tEbaiStoreInfo - sql := ` - SELECT - t1.*, - t2.status ebai_store_status, t2.vendor_store_id, t2.vendor_org_code, - IF(t1.updated_at > t2.updated_at, t1.last_operator, t2.last_operator) real_last_operator, t2.sync_status, t2.vendor_store_name - FROM store t1 - JOIN store_map t2 ON t1.id = t2.store_id AND t2.vendor_id = ? AND (t2.deleted_at = ?) - WHERE t1.id = ? - ORDER BY t2.updated_at - ` - if err = dao.GetRows(db, &stores, sql, model.VendorIDEBAI, utils.DefaultTimeValue, storeID); err == nil { - for _, store := range stores { - if globals.EnableEbaiStoreWrite { - shopID := 0 - if store.SyncStatus&model.SyncFlagDeletedMask == 0 { - shopID = store.ID - } - store2, err2 := p.ReadStore(jxcontext.AdminCtx, store.VendorOrgCode, store.VendorStoreID) - // globals.SugarLogger.Debugf("ebai UpdateStore2 store2:%s, err2:%v", utils.Format4Output(store2, true), err2) - if err = err2; err == nil { - if store2.ID == store.ID { - shopID = -1 - } - } - if err == nil { - if shopID > 0 { - err = p.UpdateStoreCustomID(jxcontext.AdminCtx, "", store.VendorStoreID, int64(shopID)) - } else if shopID == 0 { - // todo remove out shop id - } - } - if err == nil { - if store.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreStatus) != 0 { - mergeStatus := jxutils.MergeStoreStatus(store.Status, store.EbaiStoreStatus) - if err = p.UpdateStoreStatus(jxcontext.AdminCtx, store.VendorOrgCode, storeID, store.VendorStoreID, mergeStatus); err != nil { - return err - } - } - params := genStoreMapFromStore(store) - if err = api.EbaiAPI.ShopUpdate(params); err == nil { - if store.PromoteInfo != "" { - err = api.EbaiAPI.ShopAnnouncementSet("", utils.Str2Int64(store.VendorStoreID), store.PromoteInfo) - } - } - } - } - } - } - return err -} - -func isStoreStatusSame(status1, status2 int) bool { - if status1 == model.StoreStatusHaveRest { - status1 = model.StoreStatusClosed - } - if status2 == model.StoreStatusHaveRest { - status2 = model.StoreStatusClosed - } - return status1 == status2 -} - -func (p *PurchaseHandler) RefreshAllStoresID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) { - globals.SugarLogger.Debugf("ebai RefreshAllStoresID") - const batchSize = 50 - const stepCount = 3 - var stores []*tEbaiStoreInfo - db := dao.GetDB() - rootTask := tasksch.NewSeqTask("ebai RefreshAllStoresID", ctx, - func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - err = dao.GetRows(db, &stores, ` - SELECT t1.*, t2.vendor_store_id - FROM store t1 - JOIN store_map t2 ON t1.id = t2.store_id AND t2.deleted_at = ? AND t2.vendor_id = ? - WHERE t1.deleted_at = ? - `, utils.DefaultTimeValue, model.VendorIDEBAI, utils.DefaultTimeValue) - default: - taskName := "ebai RefreshAllStoresID update to custom id" - if step != stepCount-1 { - taskName = "ebai RefreshAllStoresID update to uuid" - } - task1 := tasksch.NewParallelTask(taskName, tasksch.NewParallelConfig().SetBatchSize(batchSize), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - baiduShopIDs := make([]string, len(batchItemList)) - shopIDs := make([]string, len(batchItemList)) - for k, v := range batchItemList { - store := v.(*tEbaiStoreInfo) - baiduShopIDs[k] = store.VendorStoreID - shopIDs[k] = utils.Int2Str(store.ID) - if step != stepCount-1 { - shopIDs[k] = utils.GetUUID() - } - } - if globals.EnableEbaiStoreWrite { - err = api.EbaiAPI.ShopIDBatchUpdate(baiduShopIDs, shopIDs) - } - return nil, err - }, stores) - task.AddChild(task1).Run() - _, err = task1.GetResult(0) - } - return nil, err - }, stepCount) - - tasksch.HandleTask(rootTask, parentTask, false).Run() - if !isAsync { - _, err = rootTask.GetResult(0) - } - return rootTask.ID, err -} - -// todo 此函数只考虑了在饿了么侧开店的情况 -func EbaiDeliveryType2Jx(deliveryType string) int8 { - spIndex := strings.Index(deliveryType, "|") - elmDeliveryType := utils.Str2Int64(deliveryType[:spIndex]) - switch elmDeliveryType { - case ebaiapi.DeliveryTypeElmFengNiaoZS, - ebaiapi.DeliveryTypeElmFengNiaoZSKA, - ebaiapi.DeliveryTypeElmFengNiaoKS, - ebaiapi.DeliveryTypeElmNewRetail, - ebaiapi.DeliveryTypeElmEPeiSong, - ebaiapi.DeliveryTypeElmFengNiaoHybrid, - ebaiapi.DeliveryTypeElmFengNiaoNiubee: - return scheduler.StoreDeliveryTypeByPlatform - case ebaiapi.DeliveryTypeElmXingHuoZBTrial, - ebaiapi.DeliveryTypeElmXingHuoZB, - ebaiapi.DeliveryTypeElmXingHuoZBKA: - return scheduler.StoreDeliveryTypeCrowdSourcing - case ebaiapi.DeliveryTypeElmNone, - ebaiapi.DeliveryTypeElmXingHuoTrial, - ebaiapi.DeliveryTypeElmXingHuo, - ebaiapi.DeliveryTypeElmEBase, - ebaiapi.DeliveryTypeElmXingHuoKA: - return scheduler.StoreDeliveryTypeByStore - default: - return scheduler.StoreDeliveryTypeCrowdSourcing - } -} - -func EbaiDeliveryRegion2Jx(deliveryRegion interface{}) string { - realDeliveryRegion := deliveryRegion.([]interface{}) - if len(realDeliveryRegion) > 0 { - region := deliveryRegion.([]interface{})[0].(map[string]interface{})["region"].([]interface{})[0].([]interface{}) - coords := make([]string, len(region)) - for k, v := range region { - mapV := v.(map[string]interface{}) - coords[k] = fmt.Sprintf("%.6f,%.6f", utils.MustInterface2Float64(mapV["longitude"]), utils.MustInterface2Float64(mapV["latitude"])) - } - return strings.Join(coords, ";") - } - return "" -} - -func JxDeliveryRegion2Ebai(store *model.Store) (deliveryRegion interface{}) { - rangeStr := strings.Trim(store.DeliveryRange, ";") - if store.DeliveryRangeType == model.DeliveryRangeTypeRadius { - if utils.Str2Int64WithDefault(store.DeliveryRange, 0) > 100 { // todo 如果小于100米,表示禁用,不更新 - rangeStr = jxutils.GetPolygonFromCircleStr(jxutils.IntCoordinate2Standard(store.Lng), jxutils.IntCoordinate2Standard(store.Lat), utils.Str2Float64(store.DeliveryRange), 8) - } else { - rangeStr = "" - } - } - rangeStr = "" // todo 暂时禁止同步配送区域 - if rangeStr != "" { - pointPairs := strings.Split(rangeStr, ";") - region := make([]map[string]interface{}, 0) - for _, v := range pointPairs { - pointPair := strings.Split(v, ",") - if len(pointPair) == 2 { - region = append(region, map[string]interface{}{ - "longitude": utils.Str2Float64(pointPair[0]), - "latitude": utils.Str2Float64(pointPair[1]), - }) - } - } - deliveryRegion = []interface{}{ - map[string]interface{}{ - "name": "主要配送区", - "delivery_fee": 600, - "delivery_time": "60", - "min_buy_free": "0", - "min_order_price": "0", - "region": []interface{}{ - region, - }, - }, - } - } - return deliveryRegion -} - -func fillOpTimeParams(params map[string]interface{}, opTimeList []int16) map[string]interface{} { - if params == nil { - params = make(map[string]interface{}) - } - var pairList []map[string]string - opTimeListLen := len(opTimeList) - if opTimeListLen > 4 { - opTimeListLen = 4 - } - opTimeListLen = opTimeListLen / 2 * 2 - for k := 0; k < len(opTimeList); k += 2 { - if opTimeList[k] != 0 { - pairList = append(pairList, map[string]string{ - "start": jxutils.JxOperationTime2StrTime(opTimeList[k]), - "end": jxutils.JxOperationTime2StrTime(opTimeList[k+1]), - }) - } else { - break - } - } - params["business_time"] = pairList - return params -} - -func ebaiOpTime2Jx(businessTime interface{}) (opTimeList []int16) { - businessTimeList, _ := businessTime.([]interface{}) - for _, v := range businessTimeList { - vMap := v.(map[string]interface{}) - opTimeList = append(opTimeList, jxutils.StrTime2JxOperationTime(utils.Interface2String(vMap["start"])+":00", 700), - jxutils.StrTime2JxOperationTime(utils.Interface2String(vMap["end"])+":00", 2000)) - } - return opTimeList -} - -func genStoreMapFromStore(store *tEbaiStoreInfo) map[string]interface{} { - params := fillOpTimeParams(nil, store.GetOpTimeList()) - // tel := store.Tel1 - // if tel == "" { - // tel = store.Tel2 - // } - // if tel != "" { - // // params["phone"] = tel // 外卖客服联系电话,这个有时能修改,有时不能修改,暂时统一不改 - // params["ivr_phone"] = tel // 订单提醒电话 - // } - phone := "" - if store.MarketManPhone != "" { - phone = store.MarketManPhone - } else { - phone = model.VendorStoreTel - } - params["ivr_phone"] = phone //统一改为这个电话 - - if store.VendorStoreID != "" { - params["baidu_shop_id"] = store.VendorStoreID - } - if false { //store.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreName) != 0 { - if store.VendorStoreName != "" { - params["name"] = store.VendorStoreName - } else { - params["name"] = jxutils.ComposeStoreName(store.Name, model.VendorIDEBAI) - } - } - boxFee, _ := dao.GetSysConfigAsInt64(dao.GetDB(), model.ConfigSysEbaiBoxFee) - params["package_box_price"] = jxutils.IntPrice2Standard(boxFee) - params["service_phone"] = store.Tel1 - params["address"] = store.Address - // todo 饿百 开店审核通过后不允许修改商户信息 - if store.SyncStatus&(model.SyncFlagNewMask /*|model.SyncFlagStoreAddress*/) != 0 { - // todo 这里应该要做坐标转换吧 - params["longitude"] = jxutils.IntCoordinate2Standard(store.Lng) - params["latitude"] = jxutils.IntCoordinate2Standard(store.Lat) - params["coord_type"] = ebaiapi.CoordTypeAutonavi - // if deliveryRegion := JxDeliveryRegion2Ebai(&store.Store); deliveryRegion != nil { - // params["delivery_region"] = deliveryRegion - // } - if store.ProvinceID != 0 { - params["province"] = store.ProvinceID - } - if store.CityID != 0 { - params["city"] = store.CityID - } - if store.DistrictID != 0 { - params["county"] = store.DistrictID - } - } - return params -} - -func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (storeStatus int, err error) { - ebaiStatus, err := api.EbaiAPI.ShopBusStatusGet("", utils.Str2Int64(vendorStoreID), ebaiapi.PlatformFlagElm) - if err == nil { - storeStatus = EbaiBusStatus2JxStatus(ebaiStatus) - } - return storeStatus, err -} - -func (c *PurchaseHandler) onShopMsgPush(msg *ebaiapi.CallbackMsg) (response *ebaiapi.CallbackResponse) { - var err error - vendorStoreID := utils.Interface2String(msg.Body["baidu_shop_id"]) - storeID := int(utils.Interface2Int64WithDefault(msg.Body["shop_id"], 0)) - storeStatus := model.StoreStatusOpened - switch utils.Interface2String(msg.Body["msg_type"]) { - case "online", "offline": - storeStatus, err = c.GetStoreStatus(jxcontext.AdminCtx, "", storeID, vendorStoreID) - case "shop_open", "shop_pause", "shop_close": - if int(utils.ForceInterface2Int64(msg.Body["business_ele"])) == 1 { - storeStatus = model.StoreStatusOpened - } else { - storeStatus = model.StoreStatusClosed - } - } - if err == nil { - err = partner.CurStoreManager.OnStoreStatusChanged(vendorStoreID, model.VendorIDEBAI, storeStatus) - } - return api.EbaiAPI.Err2CallbackResponse(msg.Cmd, err, nil) -} - -func (c *PurchaseHandler) GetShopHealthInfo(vendorShopID string) (shopHealthInfo map[string]interface{}, err error) { - result, err := api.EbaiAPI.GetShopHealthByDetail(utils.Str2Int64(vendorShopID)) - if err == nil { - shopHealthInfo = utils.Struct2FlatMap(result) - } - return shopHealthInfo, err -} - -func (p *PurchaseHandler) EnableAutoAcceptOrder(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, isSetEnable bool) (err error) { - return err -} - -func (c *PurchaseHandler) UpdateStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, status int) (err error) { - if globals.EnableEbaiStoreWrite { - if status == model.StoreStatusOpened { - err = api.EbaiAPI.ShopOpen("", utils.Str2Int64(vendorStoreID)) - } else if status == model.StoreStatusHaveRest || status == model.StoreStatusClosed { - err = api.EbaiAPI.ShopClose("", utils.Str2Int64(vendorStoreID)) - } else if status == model.StoreStatusDisabled { - err = api.EbaiAPI.ShopClose("", utils.Str2Int64(vendorStoreID)) - // err = api.EbaiAPI.ShopOffline("", utils.Str2Int64(vendorStoreID)) - } - if err != nil { - if remoteStatus, err2 := c.GetStoreStatus(ctx, vendorOrgCode, storeID, vendorStoreID); err2 == nil && remoteStatus == status { - err = nil - } else if intErr, ok := err.(*utils.ErrorWithCode); ok && intErr.IntCode() == 201100 || intErr.IntCode() == 201101 { // 兼容假错误:商户开业饿了么侧成功 - err = nil - } - } - } - return err -} - -func (c *PurchaseHandler) UpdateStoreOpTime(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, opTimeList []int16) (err error) { - params := map[string]interface{}{ - ebaiapi.KeyBaiduShopID: vendorStoreID, - } - fillOpTimeParams(params, opTimeList) - if globals.EnableEbaiStoreWrite { - api.EbaiAPI.ShopUpdate(params) - } - return err -} - -func (c *PurchaseHandler) GetAllStoresVendorID(ctx *jxcontext.Context, vendorOrgCode string) (vendorStoreIDs []string, err error) { - shopList, err := api.EbaiAPI.ShopList(ebaiapi.SysStatusAll) - if err == nil && len(shopList) > 0 { - vendorStoreIDs = make([]string, len(shopList)) - for k, v := range shopList { - vendorStoreIDs[k] = utils.Int64ToStr(v.BaiduShopID) - } - } - return vendorStoreIDs, err -} - -func (c *PurchaseHandler) UpdateStoreCustomID(ctx *jxcontext.Context, vendorOrgCode string, vendorStoreID string, storeID int64) (err error) { - if globals.EnableJdStoreWrite { - err = api.EbaiAPI.ShopIDBatchUpdate([]string{vendorStoreID}, []string{utils.Int64ToStr(storeID)}) - } - return err -} - -func (c *PurchaseHandler) GetShopListByPage(status, proxy_business_state int) (shopList []*ebaiapi.ShopList, err error) { - var ( - pageCount = 500 - pageNum = 1 - ) - for { - shopListPage, _, err2 := api.EbaiAPI.GetShopListByPage(status, proxy_business_state, pageCount, pageNum) - err = err2 - shopList = append(shopList, shopListPage...) - if len(shopList) < pageCount { - break - } - pageNum++ - } - return shopList, err -} - -func (c *PurchaseHandler) GetShopIDsByPage() (vendorStoreIDs []string, err error) { - shopList, err := c.GetShopListByPage(ebaiapi.ShopStatusOnLine, ebaiapi.ProxyBusinessState) - for _, v := range shopList { - vendorStoreIDs = append(vendorStoreIDs, v.Wid) - } - return vendorStoreIDs, err -} - -func (p *PurchaseHandler) CreateStore2(db *dao.DaoDB, storeID int, userName string) (vendorStoreID string, err error) { - return vendorStoreID, err -} - -func (p *PurchaseHandler) DeleteStore(db *dao.DaoDB, storeID int, userName string) (err error) { - return err -} diff --git a/business/partner/purchase/ebai/store_sku2.go b/business/partner/purchase/ebai/store_sku2.go deleted file mode 100644 index 22b40fc7a..000000000 --- a/business/partner/purchase/ebai/store_sku2.go +++ /dev/null @@ -1,596 +0,0 @@ -package ebai - -import ( - "regexp" - "strings" - "time" - - "git.rosy.net.cn/baseapi/platformapi/ebaiapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/business/partner/putils" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -const ( - defVendorCatID = 201222934 // 其他蔬菜 -) - -var ( - sensitiveWordRegexp = regexp.MustCompile(`商品名称中含有敏感词(\[.*\])`) - categoryCheck = map[int]string{ - 175: "赠品专区", - 18: "烧烤吧台", - } - - //果园果切的饿百分类ID - gygqVendorCatID = map[int]int{ - 201227732: 1, - 201220933: 1, - 201223525: 1, - 201220334: 1, - } -) - -func (p *PurchaseHandler) GetStoreSkusBatchSize(funcID int) (batchSize int) { - switch funcID { - case partner.FuncUpdateStoreSkusStock, partner.FuncUpdateStoreSkusStatus, partner.FuncUpdateStoreSkusPrice, partner.FuncDeleteStoreSkus: - batchSize = ebaiapi.MaxStoreSkuBatchSize - case partner.FuncCreateStoreSkus, partner.FuncUpdateStoreSkus: - batchSize = 1 - case partner.FuncGetStoreSkusFullInfo: - batchSize = 1 - case partner.FuncCreateActs, partner.FuncCancelActs: - batchSize = 1 - } - return batchSize -} - -// 门店分类 -func (p *PurchaseHandler) GetStoreAllCategories(ctx *jxcontext.Context, storeID int, vendorStoreID string) (cats []*partner.BareCategoryInfo, err error) { - remoteCats, err := api.EbaiAPI.ShopCategoryGet(utils.Int2Str(storeID)) - if err == nil { - cats = convertVendorCatList(remoteCats) - } - return cats, err -} - -func convertVendorCatList(remoteCats []*ebaiapi.CategoryInfo) (cats []*partner.BareCategoryInfo) { - for _, rCat := range remoteCats { - cat := &partner.BareCategoryInfo{ - VendorCatID: utils.Int64ToStr(rCat.CategoryID), - Name: rCat.Name, - Level: rCat.Level, - Seq: jxCatSeq2Ebai(rCat.Rank), - Children: convertVendorCatList(rCat.Children), - } - cats = append(cats, cat) - } - return cats -} - -func (p *PurchaseHandler) IsErrCategoryExist(err error) (isExist bool) { - return ebaiapi.IsErrCategoryExist(err) -} - -func (p *PurchaseHandler) IsErrCategoryNotExist(err error) (isNotExist bool) { - return ebaiapi.IsErrCategoryNotExist(err) -} - -func getCheckExdStoreNameAndSeq(storeID int, storeCat *dao.SkuStoreCatInfo) (name string, seq int, isCheck bool) { - store, err := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDEBAI) - if err != nil || store == nil { - return storeCat.Name, storeCat.Seq, false - } - if strings.Contains(store.Name, model.ExdStoreName) { - if categoryCheck[storeCat.ID] != "" { - return storeCat.ExdName, storeCat.ExdSeq, true - } else { - return storeCat.ExdName, storeCat.ExdSeq, false - } - } else { - return storeCat.Name, storeCat.Seq, false - } - return name, seq, false -} - -func (p *PurchaseHandler) CreateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) { - var vendorCatID int64 - if globals.EnableEbaiStoreWrite { - if catName, catSeq, isCheck := getCheckExdStoreNameAndSeq(storeID, storeCat); !isCheck { - vendorCatID, err = api.EbaiAPI.ShopCategoryCreate(utils.Int2Str(storeID), utils.Str2Int64WithDefault(storeCat.ParentVendorCatID, 0), formatCatName(catName), jxCatSeq2Ebai(catSeq)) - } - } else { - vendorCatID = jxutils.GenFakeID() - } - storeCat.VendorCatID = utils.Int64ToStr(vendorCatID) - return err -} - -func (p *PurchaseHandler) UpdateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) { - if globals.EnableEbaiStoreWrite { - if catName, catSeq, isCheck := getCheckExdStoreNameAndSeq(storeID, storeCat); !isCheck { - err = api.EbaiAPI.ShopCategoryUpdate(utils.Int2Str(storeID), utils.Str2Int64WithDefault(storeCat.VendorCatID, 0), formatCatName(catName), jxCatSeq2Ebai(catSeq)) - } - // todo, 饿百将一个分类重复改名,也会报分类名重复错,特殊处理一下,不过因为GetStoreCategory其实会拉取所有的门店分类,是比较耗时的操作 - if utils.IsErrMatch(err, "1", []string{"分类名称已经存在"}) { - if cat, err2 := p.GetStoreCategory(ctx, storeID, vendorStoreID, storeCat.Name); err2 == nil { - if cat.VendorCatID == storeCat.VendorCatID { - err = nil - } - } - } - } - return err -} - -func (p *PurchaseHandler) DeleteStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID, vendorCatID string, level int) (err error) { - if globals.EnableEbaiStoreWrite { - err = api.EbaiAPI.ShopCategoryDelete(utils.Int2Str(storeID), utils.Str2Int64WithDefault(vendorCatID, 0)) - } - return err -} - -// 门店商品 - -// 多门店平台不需要实现这个接口 - -func (p *PurchaseHandler) IsErrSkuExist(err error) (isExist bool) { - return ebaiapi.IsErrSkuExist(err) -} - -func (p *PurchaseHandler) IsErrSkuNotExist(err error) (isNotExist bool) { - return ebaiapi.IsErrSkuNotExist(err) -} - -func (p *PurchaseHandler) updateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo, isNeedMapCat bool) (failedList []*partner.StoreSkuInfoWithErr, err error) { - storeSku := storeSkuList[0] - strStoreID := utils.Int2Str(storeID) - isExd := false - if strings.Contains(storeSku.StoreName, model.ExdStoreName) { - isExd = true - } - params := genSkuParamsFromStoreSkuInfo2(storeSku, false, isExd) - if globals.EnableEbaiStoreWrite { - _, err = api.EbaiAPI.SkuUpdate(ctx.GetTrackInfo(), strStoreID, utils.Str2Int64(storeSku.VendorSkuID), params) - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDEBAI], "更新商品基础信息") - } - if isNeedMapCat && !isExd { - utils.CallFuncAsync(func() { - api.EbaiAPI.SkuShopCategoryMap(strStoreID, utils.Str2Int64(storeSku.VendorSkuID), "", utils.Str2Int64(storeSku.VendorCatID), genSkuCatRank(storeSku)) - }) - } - err = nil - } - return failedList, err -} - -func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - return p.updateStoreSkus(ctx, storeID, vendorStoreID, storeSkuList, true) -} - -// 对于多门店平台来说,storeSkuList中只有SkuID与VendorSkuID有意义 -func (p *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - storeSku := storeSkuList[0] - var ( - vendorSkuID int64 - isExd bool = false - customSkuID int64 - ) - if strings.Contains(storeSku.StoreName, model.ExdStoreName) { - isExd = true - if storeSku.ExdSkuID == "" { - customSkuID = 0 - } else { - customSkuID = utils.Str2Int64(storeSku.ExdSkuID) - } - } else { - isExd = false - customSkuID = int64(storeSku.SkuID) - } - params := genSkuParamsFromStoreSkuInfo2(storeSku, true, isExd) - if globals.EnableEbaiStoreWrite { - strStoreID := utils.Int2Str(storeID) - if vendorSkuID, err = api.EbaiAPI.SkuCreate(ctx.GetTrackInfo(), strStoreID, customSkuID, params); err == nil && !isExd { - utils.AfterFuncWithRecover(5*time.Second, func() { - api.EbaiAPI.SkuShopCategoryMap(strStoreID, vendorSkuID, "", utils.Str2Int64(storeSku.VendorCatID), genSkuCatRank(storeSku)) - // 饿百平台有BUG,会导致新建一个之前删除的商品时,信息不会及时更新,强制刷新一下 - // 比如门店:100887, skuID:33805,订单:1577176719141226065 - p.updateStoreSkus(ctx, storeID, vendorStoreID, storeSkuList, false) - }) - } else { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDEBAI], "创建商品") - } - } else { - vendorSkuID = jxutils.GenFakeID() - } - err = nil - storeSku.VendorSkuID = utils.Int64ToStr(vendorSkuID) - return failedList, err -} - -func getFailedVendorSkuIDsFromOpResult(opResult *ebaiapi.BatchOpResult) (skuIDs []string) { - if opResult != nil { - for _, v := range opResult.FailedList { - skuIDs = append(skuIDs, utils.Int64ToStr(v.SkuID)) - } - } - return skuIDs -} - -func (p *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - if globals.EnableEbaiStoreWrite { - opResult, err2 := api.EbaiAPI.SkuDelete(ctx.GetTrackInfo(), utils.Int2Str(storeID), partner.BareStoreSkuInfoList(storeSkuList).GetVendorSkuIDIntList(), nil) - if err = err2; err2 != nil && opResult != nil { - // if len(storeSkuList) > len(opResult.FailedList) { - failedList = SelectStoreSkuListByOpResult(storeSkuList, opResult, storeID, model.VendorChineseNames[model.VendorIDEBAI], "删除商品") - // successList = putils.UnselectStoreSkuListByVendorSkuIDs(storeSkuList, getFailedVendorSkuIDsFromOpResult(opResult)) - // } - } - err = nil - } - return failedList, err -} - -func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (failedList []*partner.StoreSkuInfoWithErr, err error) { - vendorSkuIDs := partner.BareStoreSkuInfoList(storeSkuList).GetVendorSkuIDIntList() - if globals.EnableEbaiStoreWrite { - var opResult *ebaiapi.BatchOpResult - if status == model.SkuStatusNormal { - if len(vendorSkuIDs) > 1 { - opResult, err = api.EbaiAPI.SkuOnline(ctx.GetTrackInfo(), utils.Int2Str(storeID), vendorSkuIDs, nil, nil) - } else if len(vendorSkuIDs) == 1 { - err = api.EbaiAPI.SkuOnlineOne(ctx.GetTrackInfo(), utils.Int2Str(storeID), vendorSkuIDs[0], "", "") - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDEBAI], "更新商品状态") - } - return failedList, err - } - } else { - if len(vendorSkuIDs) > 1 { - opResult, err = api.EbaiAPI.SkuOffline(ctx.GetTrackInfo(), utils.Int2Str(storeID), vendorSkuIDs, nil, nil) - } else if len(vendorSkuIDs) == 1 { - err = api.EbaiAPI.SkuOfflineOne(ctx.GetTrackInfo(), utils.Int2Str(storeID), vendorSkuIDs[0], "", "") - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDEBAI], "更新商品状态") - } - return failedList, err - } - } - if err != nil && opResult != nil { - failedList = SelectStoreSkuListByOpResult(storeSkuList, opResult, storeID, model.VendorChineseNames[model.VendorIDEBAI], "更新商品状态") - // failedList = putils.UnselectStoreSkuListByVendorSkuIDs(storeSkuList, getFailedVendorSkuIDsFromOpResult(opResult)) - } - err = nil - } - return failedList, err -} - -func StoreSkuInfoList2Ebai(storeSkuList []*partner.StoreSkuInfo) (outList ebaiapi.ShopSkuInfoList) { - outList = make(ebaiapi.ShopSkuInfoList, len(storeSkuList)) - for k, v := range storeSkuList { - outList[k] = &ebaiapi.ShopSkuInfo{ - SkuID: utils.Str2Int64WithDefault(v.VendorSkuID, 0), - // CustomSkuID: utils.Int2Str(v.SkuID), - SalePrice: v.VendorPrice, - Stock: v.Stock, - } - } - return outList -} - -func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - if globals.EnableEbaiStoreWrite { - if len(storeSkuList) > 1 { - opResult, err2 := api.EbaiAPI.SkuPriceUpdateBatch(ctx.GetTrackInfo(), utils.Int2Str(storeID), StoreSkuInfoList2Ebai(storeSkuList), ebaiapi.SkuIDTypeSkuID) - if err = err2; err != nil && opResult != nil { - failedList = SelectStoreSkuListByOpResult(storeSkuList, opResult, storeID, model.VendorChineseNames[model.VendorIDEBAI], "更新商品价格") - } - } else if len(storeSkuList) == 1 { - _, err := api.EbaiAPI.SkuPriceUpdateOne(ctx.GetTrackInfo(), utils.Int2Str(storeID), StoreSkuInfoList2Ebai(storeSkuList)[0]) - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDEBAI], "更新商品价格") - } - } - err = nil - } - return failedList, err -} - -func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - if globals.EnableEbaiStoreWrite { - if len(storeSkuList) > 1 { - opResult, err2 := api.EbaiAPI.SkuStockUpdateBatch(ctx.GetTrackInfo(), utils.Int2Str(storeID), StoreSkuInfoList2Ebai(storeSkuList), ebaiapi.SkuIDTypeSkuID) - if err = err2; err != nil && opResult != nil { - failedList = SelectStoreSkuListByOpResult(storeSkuList, opResult, storeID, model.VendorChineseNames[model.VendorIDEBAI], "更新商品库存") - // successList = putils.UnselectStoreSkuListByVendorSkuIDs(storeSkuList, getFailedVendorSkuIDsFromOpResult(opResult)) - } - } else if len(storeSkuList) == 1 { - err = api.EbaiAPI.SkuStockUpdateOne(ctx.GetTrackInfo(), utils.Int2Str(storeID), StoreSkuInfoList2Ebai(storeSkuList)[0]) - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDEBAI], "更新商品库存") - } - } - err = nil - } - return failedList, err -} - -func genSkuParamsFromStoreSkuInfo2(storeSku *dao.StoreSkuSyncInfo, isCreate, isExd bool) (params map[string]interface{}) { - var img string - if storeSku.ImgMix != "" { - img = storeSku.ImgMix - } else { - img = storeSku.Img - } - photos := []map[string]interface{}{ - map[string]interface{}{ - "is_master": true, - "url": img, - }, - } - if storeSku.Img2 != "" { - photos = append(photos, map[string]interface{}{ - "is_master": false, - "url": storeSku.Img2, - }) - } - if storeSku.Img3 != "" { - photos = append(photos, map[string]interface{}{ - "is_master": false, - "url": storeSku.Img3, - }) - } - params = map[string]interface{}{ - // "name": utils.LimitMixedStringLen(storeSku.SkuName, ebaiapi.MaxSkuNameByteCount), - "left_num": model.MaxStoreSkuStockQty, - // "category_id": utils.Str2Int64(storeSku.VendorCatID), - "predict_cat": 0, // 不使用推荐类目 - // "cat3_id": getEbaiCat(storeSku.VendorVendorCatID), - "weight": storeSku.Weight, - "photos": photos, - "preparation_time": storeSku.PreparationTime, - } - if !isExd { - params["category_id"] = utils.Str2Int64(storeSku.VendorCatID) - params["name"] = utils.LimitMixedStringLen(storeSku.SkuName, ebaiapi.MaxSkuNameByteCount) - params["cat3_id"] = getEbaiCat(storeSku.VendorVendorCatID) - } else { - params["upc"] = storeSku.Upc - params["name"] = storeSku.Name - params["cat3_id"] = storeSku.ExdCategoryThirdID - params["category_id"] = utils.Str2Int64WithDefault(storeSku.VendorCatID, 0) - } - //证明是果园的几个果切分类,需要填加工服务 - if gygqVendorCatID[int(storeSku.VendorVendorCatID)] == 1 { - params["process_type"] = model.YES - processDetail := []map[string]interface{}{ - map[string]interface{}{ - "type": "去皮", - "time": 2, - }, - map[string]interface{}{ - "type": "不加工", - "time": 0, - }, - } - params["process_detail"] = processDetail - } - if storeSku.DescImg != "" { - params["rtf"] = storeSku.DescImg - } - if isCreate /*storeSku.SkuSyncStatus&(model.SyncFlagPriceMask| model.SyncFlagNewMask) != 0 */ { - params["sale_price"] = storeSku.VendorPrice - } - if storeSku.SkuSyncStatus&(model.SyncFlagSaleMask|model.SyncFlagNewMask) != 0 { - params["status"] = jxSkuStatus2Ebai(storeSku.MergedStatus) - } - // todo 饿百如果给的UPC是空要报错,但如果我要删除UPC怎么弄? - // if storeSku.Upc != "" { - // params["upc"] = storeSku.Upc - // } - return params -} - -func ebaiSkuStatus2Jx(ebaiSkuStatus int) (jxSkuStatus int) { - if ebaiSkuStatus == ebaiapi.SkuStatusOnline { - jxSkuStatus = model.SkuStatusNormal - } else if ebaiSkuStatus == ebaiapi.SkuStatusOffline { - jxSkuStatus = model.SkuStatusDontSale - } else if ebaiSkuStatus == ebaiapi.SkuStatusOnline { - jxSkuStatus = model.SkuStatusDeleted - } - return jxSkuStatus -} - -func jxSkuStatus2Ebai(status int) int { - if status <= 0 { - return ebaiapi.SkuStatusOffline - } - return ebaiapi.SkuStatusOnline -} - -func getEbaiCat(catID int64) int64 { - if catID == 0 { - return defVendorCatID - } - return catID -} - -// 饿百的排序是从大到小 -func genSkuCatRank(storeSku *dao.StoreSkuSyncInfo) int { - return int(ebaiapi.MaxSkuCatRank - storeSku.GetSeq()) -} - -// 饿百的排序是从大到小 -func jxCatSeq2Ebai(seq int) int { - return ebaiapi.MaxCatCatRank - seq -} - -func formatCatName(name string) string { - return utils.LimitUTF8StringLen(name, ebaiapi.MaxCategoryNameLen) -} - -func (p *PurchaseHandler) GetStoreSkusFullInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (skuNameList []*partner.SkuNameInfo, err error) { - params := &ebaiapi.SkuListParams{ - PageSize: ebaiapi.MaxSkuListPageSize, - } - if len(storeSkuList) == 1 { - if storeSkuList[0].SkuID > 0 { - params.CustomSkuID = utils.Int2Str(storeSkuList[0].SkuID) - } - if storeSkuList[0].VendorSkuID != "" { - params.SkuID = utils.Str2Int64WithDefault(storeSkuList[0].VendorSkuID, 0) - } - } - page1, err := api.EbaiAPI.SkuList(utils.Int2Str(storeID), params) - if err == nil { - skuNameList = append(skuNameList, vendorSkuList2Jx(page1.List)...) - if page1.Pages > 1 { - pages := make([]int, page1.Pages-1) - for i := 2; i <= page1.Pages; i++ { - pages[i-2] = i - } - task := tasksch.NewParallelTask("ebai GetStoreSkusFullInfo", nil, ctx, - func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - callParams := &ebaiapi.SkuListParams{ - PageSize: ebaiapi.MaxSkuListPageSize, - Page: batchItemList[0].(int), - } - pageSku, err2 := api.EbaiAPI.SkuList(utils.Int2Str(storeID), callParams) - if err2 == nil { - return pageSku.List, err2 - } - return nil, err2 - }, pages) - tasksch.HandleTask(task, parentTask, true).Run() - result, err2 := task.GetResult(0) - if err = err2; err == nil { - for _, v := range result { - skuNameList = append(skuNameList, vendorSku2Jx(v.(*ebaiapi.SkuInfo))) - } - } - } - } - return skuNameList, err -} - -func vendorSku2Jx(vendorSku *ebaiapi.SkuInfo) (skuName *partner.SkuNameInfo) { - prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(vendorSku.Name) - weight := vendorSku.Weight - if weight <= 0 { - weight = jxutils.FormatSkuWeight(specQuality, specUnit) - } - skuID := int(utils.Str2Int64WithDefault(vendorSku.CustomSkuID, 0)) - vendorSkuID := utils.Int64ToStr(vendorSku.SkuID) - skuName = &partner.SkuNameInfo{ - NameID: skuID, - VendorNameID: vendorSkuID, - - Prefix: prefix, - Name: name, - Unit: unit, - SkuList: []*partner.SkuInfo{ - &partner.SkuInfo{ - StoreSkuInfo: partner.StoreSkuInfo{ - VendorSkuID: vendorSkuID, - SkuID: skuID, - - Stock: vendorSku.LeftNum, - VendorPrice: vendorSku.SalePrice, - Status: ebaiSkuStatus2Jx(vendorSku.Status), - }, - SkuName: vendorSku.Name, - Comment: comment, - SpecQuality: float64(specQuality), - SpecUnit: specUnit, - Weight: weight, - }, - }, - } - for _, v := range vendorSku.Photos { - skuName.PictureList = append(skuName.PictureList, v.URL) - } - // todo, 看起来饿百只返回了最低一级的商家分类信息 - for _, v := range vendorSku.CustomCatList { - skuName.VendorCatIDList = append(skuName.VendorCatIDList, v.CustomCatID) - } - return skuName -} - -func vendorSkuList2Jx(vendorSkuList []*ebaiapi.SkuInfo) (skuNameList []*partner.SkuNameInfo) { - for _, vendorSku := range vendorSkuList { - skuNameList = append(skuNameList, vendorSku2Jx(vendorSku)) - } - return skuNameList -} - -func (p *PurchaseHandler) GetSensitiveWordRegexp() *regexp.Regexp { - return sensitiveWordRegexp -} - -//饿百api返回 -func SelectStoreSkuListByOpResult(storeSkuList []*partner.StoreSkuInfo, opResult *ebaiapi.BatchOpResult, storeID int, vendorName string, syncType string) (selectedStoreSkuList []*partner.StoreSkuInfoWithErr) { - opResultMap := make(map[int64]string) - if len(opResult.FailedList) > 0 { - for _, v := range opResult.FailedList { - if !(syncType == "删除商品" && ebaiapi.IsMsgSkuNotExist(v.ErrorMsg)) { - opResultMap[v.SkuID] = v.ErrorMsg - } - } - for _, v := range storeSkuList { - if opResultMap[utils.Str2Int64(v.VendorSkuID)] != "" { - opFailed := &partner.StoreSkuInfoWithErr{ - StoreSkuInfo: v, - ErrMsg: opResultMap[utils.Str2Int64(v.VendorSkuID)], - StoreID: storeID, - VendoreName: vendorName, - SyncType: syncType, - } - selectedStoreSkuList = append(selectedStoreSkuList, opFailed) - } - } - } - return selectedStoreSkuList -} - -func (p *PurchaseHandler) CreateStoreSkusAct(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - for _, v := range storeSkuList { - if vendorActID, err2 := createOneShopAct(putils.GetFixDirectDownAct(vendorOrgCode, storeID, v.SkuID), utils.Int2Str(storeID), putils.StoreSku2ActStoreSku(model.SyncFlagNewMask, vendorStoreID, []*partner.StoreSkuInfo{v})); err2 != nil { - failedList = append(failedList, &partner.StoreSkuInfoWithErr{ - StoreSkuInfo: v, - VendoreID: model.VendorIDEBAI, - StoreID: storeID, - ErrMsg: err2.Error(), - }) - } else { - v.VendorActID = vendorActID - } - } - return failedList, err -} - -func (p *PurchaseHandler) CancelActs(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - for _, v := range storeSkuList { - if err2 := ActivityDisable(utils.Str2Int64(v.VendorActID), utils.Int2Str(storeID), 0, 0); err2 != nil { - failedList = append(failedList, &partner.StoreSkuInfoWithErr{ - StoreSkuInfo: v, - VendoreID: model.VendorIDJD, - StoreID: storeID, - ErrMsg: err2.Error(), - }) - } - } - return failedList, err -} - -func (p *PurchaseHandler) UpdateStoreSkusSpecTag(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (err error) { - return err -} diff --git a/business/partner/purchase/ebai/store_sku2_test.go b/business/partner/purchase/ebai/store_sku2_test.go deleted file mode 100644 index 93e652bb2..000000000 --- a/business/partner/purchase/ebai/store_sku2_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package ebai - -import ( - "testing" - - "git.rosy.net.cn/jx-callback/business/partner" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" -) - -func TestGetStoreSkusFullInfo(t *testing.T) { - skuNameList, err := CurPurchaseHandler.GetStoreSkusFullInfo(jxcontext.AdminCtx, nil, testShopID, testShopBaiduID, []*partner.StoreSkuInfo{ - &partner.StoreSkuInfo{ - SkuID: 4256, - }, - }) - if err != nil { - t.Fatal(err.Error()) - } - t.Log(utils.Format4Output(skuNameList, false)) - t.Log(len(skuNameList)) -} - -func TestGetStoreSkusBareInfo(t *testing.T) { - storeSkuList, err := CurPurchaseHandler.GetStoreSkusBareInfo(jxcontext.AdminCtx, "", nil, testShopID, testShopBaiduID, nil) - if err != nil { - t.Fatal(err.Error()) - } - t.Log(utils.Format4Output(storeSkuList, false)) - t.Log(len(storeSkuList)) -} - -func TestDeleteStoreAllSkus(t *testing.T) { - err := CurPurchaseHandler.DeleteStoreAllSkus(jxcontext.AdminCtx, nil, testShopID, testShopBaiduID, true) - if err != nil { - t.Fatal(err) - } -} - -func TestDeleteStoreAllCategories(t *testing.T) { - err := CurPurchaseHandler.DeleteStoreAllCategories(jxcontext.AdminCtx, nil, testShopID, testShopBaiduID, true) - if err != nil { - t.Fatal(err) - } -} diff --git a/business/partner/purchase/ebai/store_sku_test.go b/business/partner/purchase/ebai/store_sku_test.go deleted file mode 100644 index 136c1f111..000000000 --- a/business/partner/purchase/ebai/store_sku_test.go +++ /dev/null @@ -1,57 +0,0 @@ -package ebai - -import ( - "testing" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" -) - -// func TestSyncStoresSkus(t *testing.T) { -// skus := make([]int, 100) -// for i := 0; i < 100; i++ { -// skus[i] = i + 1 -// } -// _, err := CurPurchaseHandler.SyncStoreSkus(jxcontext.AdminCtx, nil, testShopID, skus, false, false) -// if err != nil { -// t.Fatal(err.Error()) -// } -// time.Sleep(4 * time.Second) -// } - -// func TestSyncOneStoreCategoriesFromRemote2Local(t *testing.T) { -// db := dao.GetDB() -// err := CurPurchaseHandler.SyncLocalStoreCategory(db, testShopID, "autotest") -// if err != nil { -// t.Fatal(err.Error()) -// } -// } - -// func TestSyncOneStoreCategoriesFromLocal2Remote(t *testing.T) { -// _, err := CurPurchaseHandler.SyncStoreCategory(jxcontext.AdminCtx, nil, testShopID, false) -// if err != nil { -// t.Fatal(err.Error()) -// } -// } - -func TestGetAllRemoteSkus(t *testing.T) { - result, err := CurPurchaseHandler.GetStoreSkusFullInfo(jxcontext.AdminCtx, nil, testShopID, testShopBaiduID, nil) - if err != nil { - t.Fatal(err.Error()) - } else { - t.Log(len(result)) - } -} - -func TestDeleteRemoteSkus(t *testing.T) { - err := CurPurchaseHandler.DeleteStoreAllSkus(jxcontext.AdminCtx, nil, testShopID, testShopBaiduID, true) - if err != nil { - t.Fatal(err.Error()) - } -} - -func TestDeleteRemoteCategories(t *testing.T) { - err := new(PurchaseHandler).DeleteStoreAllCategories(jxcontext.AdminCtx, nil, testShopID, testShopBaiduID, true) - if err != nil { - t.Fatal(err.Error()) - } -} diff --git a/business/partner/purchase/ebai/store_test.go b/business/partner/purchase/ebai/store_test.go deleted file mode 100644 index c24f5ba3b..000000000 --- a/business/partner/purchase/ebai/store_test.go +++ /dev/null @@ -1,34 +0,0 @@ -package ebai - -import ( - "testing" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/model/dao" -) - -func TestReadStore(t *testing.T) { - result, err := CurPurchaseHandler.ReadStore(jxcontext.AdminCtx, "", testShopBaiduID) - if err != nil { - t.Fatal(err.Error()) - } - t.Log(utils.Format4Output(result, false)) -} - -func TestUpdateStore(t *testing.T) { - db := dao.GetDB() - err := CurPurchaseHandler.UpdateStore(db, testShopID, "autotest") - if err != nil { - t.Fatal(err.Error()) - } -} - -func TestCreateStore(t *testing.T) { - db := dao.GetDB() - _, err := CurPurchaseHandler.CreateStore(db, 1, "autotest") - if err != nil { - t.Fatal(err.Error()) - } -} diff --git a/business/partner/purchase/ebai/waybill.go b/business/partner/purchase/ebai/waybill.go deleted file mode 100644 index ba25910dd..000000000 --- a/business/partner/purchase/ebai/waybill.go +++ /dev/null @@ -1,88 +0,0 @@ -package ebai - -import ( - "time" - - "git.rosy.net.cn/baseapi/platformapi/ebaiapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -const ( - timeout4WaybillCancel = 10 * time.Minute // 饿百发送运单取消消息10分钟后,如果没有转自送,就要取消订单,且不再发送订单取消消息 -) - -var ( - VendorWaybillStatus2StatusMap = map[string]int{ - ebaiapi.WaybillStatusNew: model.WaybillStatusUnknown, - ebaiapi.WaybillStatusRequestDelivery: model.WaybillStatusUnknown, - ebaiapi.WaybillStatusWait4Courier: model.WaybillStatusNew, - ebaiapi.WaybillStatusCourierAccepted: model.WaybillStatusAccepted, - ebaiapi.WaybillStatusCourierPickedup: model.WaybillStatusDelivering, - ebaiapi.WaybillStatusDeliveryCancled: model.WaybillStatusCanceled, - ebaiapi.WaybillStatusFinished: model.WaybillStatusDelivered, - // ebaiapi.WaybillStatusExceptional: model.WaybillStatusCanceled, // 饿百的配送异常不应该当成取消来处理,比如:1568651453228834871 - ebaiapi.WaybillStatusSelfDelivery: model.WaybillStatusUnknown, - ebaiapi.WaybillStatusDontDeliver: model.WaybillStatusCanceled, - ebaiapi.WaybillStatusDeliveryRejected: model.WaybillStatusCanceled, - ebaiapi.WaybillStatusCourierArrived: model.WaybillStatusCourierArrived, - } -) - -func (p *PurchaseHandler) GetWaybillStatusFromVendorStatus(vendorStatus string) int { - if status, ok := VendorWaybillStatus2StatusMap[vendorStatus]; ok { - return status - } - return model.WaybillStatusUnknown -} - -func (c *PurchaseHandler) onWaybillMsg(msg *ebaiapi.CallbackMsg) (retVal *ebaiapi.CallbackResponse) { - order := c.callbackMsg2Waybill(msg) - globals.SugarLogger.Debugf("ebai onWaybillMsg orderID:%s", order.VendorOrderID) - if order.Status == model.WaybillStatusNew || order.Status == model.WaybillStatusAccepted { // 饿百新运单事件要查询快递员信息,因为可能事件错序 - if result, err := api.EbaiAPI.OrderDeliveryGet(order.VendorOrderID); err != nil { - globals.SugarLogger.Warnf("ebai onWaybillMsg orderID:%s OrderDeliveryGet failed with error:%v", order.VendorOrderID, err) - return api.EbaiAPI.Err2CallbackResponse(msg.Cmd, err, order.VendorOrderID) - } else { - order.CourierName = utils.Interface2String(result["name"]) - order.CourierMobile = utils.Interface2String(result["phone"]) - } - if order.Status == model.WaybillStatusNew { - order2, _ := partner.CurOrderManager.LoadOrder(order.VendorOrderID, order.WaybillVendorID) - if order2.Status == model.OrderStatusWaitAccepted { - order2.Status = model.OrderStatusNew - scheduler.CurrentScheduler.OnOrderNew(order2, false) - } - } - } else if order.Status == model.WaybillStatusCanceled { - utils.AfterFuncWithRecover(timeout4WaybillCancel, func() { - if localOrder, err2 := partner.CurOrderManager.LoadOrder(order.VendorOrderID, model.VendorIDEBAI); err2 == nil { - if localOrder.Status < model.OrderStatusEndBegin { - c.trySyncCancelStatus(order.VendorOrderID) - } - } - }) - } - return api.EbaiAPI.Err2CallbackResponse(msg.Cmd, partner.CurOrderManager.OnWaybillStatusChanged(order), order.VendorStatus) -} - -func (c *PurchaseHandler) callbackMsg2Waybill(msg *ebaiapi.CallbackMsg) (retVal *model.Waybill) { - vendorStatus := utils.Int64ToStr(utils.MustInterface2Int64(msg.Body["status"])) - orderID := GetOrderIDFromMsg(msg) - retVal = &model.Waybill{ - VendorOrderID: orderID, - OrderVendorID: model.VendorIDEBAI, - VendorWaybillID: orderID, - WaybillVendorID: model.VendorIDEBAI, - Status: c.GetWaybillStatusFromVendorStatus(vendorStatus), - VendorStatus: vendorStatus, - StatusTime: utils.Timestamp2Time(msg.Timestamp), - - VendorOrgCode: msg.Source, - } - return retVal -} diff --git a/business/partner/purchase/elm/act.go b/business/partner/purchase/elm/act.go deleted file mode 100644 index d2ea0ea42..000000000 --- a/business/partner/purchase/elm/act.go +++ /dev/null @@ -1,11 +0,0 @@ -package elm - -import ( - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" -) - -func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSkuList []*model.ActStoreSku2) (err error) { - return nil -} diff --git a/business/partner/purchase/elm/elm.go b/business/partner/purchase/elm/elm.go deleted file mode 100644 index d2cbf40c6..000000000 --- a/business/partner/purchase/elm/elm.go +++ /dev/null @@ -1,101 +0,0 @@ -package elm - -import ( - "fmt" - - "git.rosy.net.cn/baseapi/platformapi/elmapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals/api" -) - -var ( - curPurchaseHandler *PurchaseHandler -) - -type PurchaseHandler struct { - partner.BasePurchasePlatform -} - -func init() { - if api.ElmAPI != nil { - curPurchaseHandler = new(PurchaseHandler) - // partner.RegisterPurchasePlatform(curPurchaseHandler) - } -} - -func (c *PurchaseHandler) GetVendorID() int { - return model.VendorIDELM -} - -func OnCallbackMsg(msg *elmapi.CallbackMsg) (retVal *elmapi.CallbackResponse) { - if curPurchaseHandler != nil { - retVal = curPurchaseHandler.OnCallbackMsg(msg) - } - return retVal -} - -func (c *PurchaseHandler) OnCallbackMsg(msg *elmapi.CallbackMsg) (retVal *elmapi.CallbackResponse) { - if msg.Type == elmapi.MsgTypeOrderValid { - innerMsg := make(map[string]interface{}) - err := utils.UnmarshalUseNumber([]byte(msg.Message), &innerMsg) - if err != nil { - retVal = elmapi.Err2CallbackResponse(err, "") - } else { - innerMsg["msgType"] = msg.Type - retVal = c.OnOrderNewMsg(innerMsg) - } - } else if msg.Type > elmapi.MsgTypeOrderValid && msg.Type < elmapi.MsgTypeUserApplyCancel { - var innerMsg elmapi.CallbackOrderStatusMsg - err := utils.UnmarshalUseNumber([]byte(msg.Message), &innerMsg) - if err != nil { - retVal = elmapi.Err2CallbackResponse(err, "") - } else { - innerMsg.MsgType = msg.Type - retVal = c.OnOrderStatusMsg(&innerMsg) - } - } else if msg.Type >= elmapi.MsgTypeUserApplyCancel && msg.Type < elmapi.MsgTypeUserUrgeOrder { - var innerMsg elmapi.CallbackOrderCancelRefundMsg - err := utils.UnmarshalUseNumber([]byte(msg.Message), &innerMsg) - if err != nil { - retVal = elmapi.Err2CallbackResponse(err, "") - } else { - innerMsg.MsgType = msg.Type - retVal = c.OnOrderCancelRefundMsg(&innerMsg) - } - } else if msg.Type == elmapi.MsgTypeUserUrgeOrder { - var innerMsg elmapi.CallbackOrderUrgeMsg - err := utils.UnmarshalUseNumber([]byte(msg.Message), &innerMsg) - if err != nil { - retVal = elmapi.Err2CallbackResponse(err, "") - } else { - innerMsg.MsgType = msg.Type - jxutils.CallMsgHandler(func() { - retVal = c.onOrderUserUrgeOrder(&innerMsg) - }, jxutils.ComposeUniversalOrderID(innerMsg.OrderID, model.VendorIDELM)) - } - } else if msg.Type >= elmapi.MsgTypeWaybillWait4DeliveryVendor && msg.Type <= elmapi.MsgTypeRejectedSystemError { - var innerMsg elmapi.CallbackWaybillStatusMsg - err := utils.UnmarshalUseNumber([]byte(msg.Message), &innerMsg) - if err != nil { - retVal = elmapi.Err2CallbackResponse(err, "") - } else { - innerMsg.MsgType = msg.Type - retVal = c.OnWaybillStatusMsg(&innerMsg) - } - } else { - retVal = elmapi.SuccessResponse - } - return retVal -} - -func (p *PurchaseHandler) UploadImg(ctx *jxcontext.Context, vendorOrgCode, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) { - return imgHint, err -} - -func (p *PurchaseHandler) GetVendorCategories(ctx *jxcontext.Context) (vendorCats []*model.SkuVendorCategory, err error) { - return nil, fmt.Errorf("平台%s不支持此操作", jxutils.GetVendorName(model.VendorIDELM)) -} diff --git a/business/partner/purchase/elm/order.go b/business/partner/purchase/elm/order.go deleted file mode 100644 index 4d94b4600..000000000 --- a/business/partner/purchase/elm/order.go +++ /dev/null @@ -1,334 +0,0 @@ -package elm - -import ( - "errors" - "fmt" - "math" - "strings" - "time" - - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" - - "git.rosy.net.cn/baseapi/platformapi/elmapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" -) - -const ( - acceptOrderDelay = 270 * time.Second - fakePickedUp = "fakefinishedpickup" -) - -var ( - VendorStatus2StatusMap = map[string]int{ - elmapi.OrderStatusUnprocessed: model.OrderStatusNew, - elmapi.OrderStatusValid: model.OrderStatusAccepted, - elmapi.OrderStatusPending: model.OrderStatusNew, - // elmapi.OrderStatusRefunding: model.OrderStatusApplyRefund, - elmapi.OrderStatusInvalid: model.OrderStatusCanceled, - elmapi.OrderStatusSettled: model.OrderStatusFinished, - } -) - -func (c *PurchaseHandler) OnOrderStatusMsg(msg *elmapi.CallbackOrderStatusMsg) (retVal *elmapi.CallbackResponse) { - jxutils.CallMsgHandler(func() { - retVal = c.onOrderStatusMsg(msg) - }, jxutils.ComposeUniversalOrderID(msg.OrderID, model.VendorIDELM)) - return retVal -} - -func (c *PurchaseHandler) OnOrderNewMsg(msg map[string]interface{}) (retVal *elmapi.CallbackResponse) { - jxutils.CallMsgHandler(func() { - retVal = c.onOrderNew(msg) - }, jxutils.ComposeUniversalOrderID(msg["orderId"].(string), model.VendorIDELM)) - return retVal -} - -func (c *PurchaseHandler) OnOrderCancelRefundMsg(msg *elmapi.CallbackOrderCancelRefundMsg) (retVal *elmapi.CallbackResponse) { - jxutils.CallMsgHandler(func() { - retVal = c.onOrderCancelRefundMsg(msg) - }, jxutils.ComposeUniversalOrderID(msg.OrderID, model.VendorIDELM)) - return retVal -} - -func (c *PurchaseHandler) orderStatusMsg2Status(msg *elmapi.CallbackOrderStatusMsg) *model.OrderStatus { - orderStatus := &model.OrderStatus{ - VendorOrderID: msg.OrderID, - VendorID: model.VendorIDELM, - OrderType: model.OrderTypeOrder, - RefVendorOrderID: msg.OrderID, - RefVendorID: model.VendorIDELM, - VendorStatus: c.stateAndType2Str(msg.State, msg.MsgType), - StatusTime: utils.Timestamp2Time(msg.UpdateTime), - } - return orderStatus -} - -func (c *PurchaseHandler) cancelRefundMsg2Status(msg *elmapi.CallbackOrderCancelRefundMsg) *model.OrderStatus { - orderStatus := &model.OrderStatus{ - VendorOrderID: msg.OrderID, - VendorID: model.VendorIDELM, - OrderType: model.OrderTypeOrder, - RefVendorOrderID: msg.OrderID, - RefVendorID: model.VendorIDELM, - VendorStatus: c.stateAndType2Str(msg.RefundStatus, msg.MsgType), - StatusTime: utils.Timestamp2Time(msg.UpdateTime), - } - return orderStatus -} - -func (c *PurchaseHandler) onOrderStatusMsg(msg *elmapi.CallbackOrderStatusMsg) (retVal *elmapi.CallbackResponse) { - status := c.orderStatusMsg2Status(msg) - switch msg.MsgType { - case elmapi.MsgTypeOrderAccepted: - status.Status = model.OrderStatusAccepted - case elmapi.MsgTypeOrderCanceled, elmapi.MsgTypeOrderInvalid, elmapi.MsgTypeOrderForceInvalid: - status.Status = model.OrderStatusCanceled - case elmapi.MsgTypeOrderFinished: - status.Status = model.OrderStatusFinished - default: - globals.SugarLogger.Warnf("onOrderStatusMsg elm msg:%v not handled", msg) - return elmapi.SuccessResponse - } - err := partner.CurOrderManager.OnOrderStatusChanged("", status) - - // 直接跳到拣货完成 - if msg.MsgType == elmapi.MsgTypeOrderAccepted { - status.Status = model.OrderStatusFinishedPickup - status.VendorStatus = fakePickedUp - err = partner.CurOrderManager.OnOrderStatusChanged("", status) - } - // if globals.HandleLegacyJxOrder && err == nil { - // c.legacyElmOrderStatusChanged(status) - // } - return elmapi.Err2CallbackResponse(err, status.VendorStatus) -} - -func (c *PurchaseHandler) onOrderCancelRefundMsg(msg *elmapi.CallbackOrderCancelRefundMsg) (retVal *elmapi.CallbackResponse) { - status := c.cancelRefundMsg2Status(msg) - switch msg.MsgType { - case elmapi.MsgTypeUserApplyCancel: - status.Status = model.OrderStatusApplyCancel - case elmapi.MsgTypeUserApplyRefund: - // status.Status = model.OrderStatusApplyRefund - default: - status.Status = model.OrderStatusUnknown - } - return elmapi.Err2CallbackResponse(partner.CurOrderManager.OnOrderStatusChanged("", status), status.VendorStatus) -} - -func (c *PurchaseHandler) GetOrder(vendorOrgCode, orderID string) (order *model.GoodsOrder, err error) { - result, err := api.ElmAPI.GetOrder(orderID) - if err == nil { - order = c.Map2Order(result) - } - return order, err -} - -func (c *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) { - result := orderData - orderID := result["id"].(string) - phoneList := result["phoneList"].([]interface{}) - consigneeMobile := "" - if len(phoneList) > 0 { - consigneeMobile = utils.Interface2String(phoneList[0]) - } - - // globals.SugarLogger.Debug(result) - order = &model.GoodsOrder{ - VendorOrderID: orderID, - VendorID: model.VendorIDELM, - VendorStoreID: utils.Int64ToStr(utils.MustInterface2Int64(result["shopId"])), - StoreID: int(utils.Str2Int64WithDefault(utils.Interface2String(result["openId"]), 0)), - StoreName: result["shopName"].(string), - ConsigneeName: result["consignee"].(string), - ConsigneeMobile: jxutils.FormalizeMobile(consigneeMobile), - ConsigneeAddress: result["address"].(string), - BuyerComment: utils.TrimBlankChar(utils.Interface2String(result["description"])), - ExpectedDeliveredTime: utils.Str2TimeWithDefault(utils.Interface2String(result["deliverTime"]), utils.DefaultTimeValue), - PickDeadline: utils.DefaultTimeValue, - VendorStatus: utils.Interface2String(result["status"]), // 取订单的原始status,不合并消息类型(因为当前消息类型没有意义) - OrderSeq: int(utils.MustInterface2Int64(result["daySn"])), - StatusTime: utils.Str2Time(result["activeAt"].(string)), - OriginalData: string(utils.MustMarshal(result)), - ActualPayPrice: jxutils.StandardPrice2Int(utils.MustInterface2Float64(result["totalPrice"])), - Skus: []*model.OrderSku{}, - } - order.Status = c.getStatusFromVendorStatus(order.VendorStatus) - if result["book"].(bool) { - order.BusinessType = model.BusinessTypeDingshida - } else { - order.BusinessType = model.BusinessTypeImmediate - } - deliveryGeo := strings.Split(utils.Interface2String(result["deliveryGeo"]), ",") - if len(deliveryGeo) == 2 { - order.CoordinateType = model.CoordinateTypeMars - order.ConsigneeLng = jxutils.StandardCoordinate2Int(utils.Str2Float64(deliveryGeo[0])) - order.ConsigneeLat = jxutils.StandardCoordinate2Int(utils.Str2Float64(deliveryGeo[1])) - } - - for _, group2 := range result["groups"].([]interface{}) { - group := group2.(map[string]interface{}) - for _, product2 := range group["items"].([]interface{}) { - product := product2.(map[string]interface{}) - sku := &model.OrderSku{ - VendorOrderID: orderID, - VendorID: model.VendorIDELM, - Count: int(utils.MustInterface2Int64(product["quantity"])), - SkuID: int(utils.Str2Int64WithDefault(utils.Interface2String(product["extendCode"]), 0)), - VendorSkuID: utils.Int64ToStr(utils.Interface2Int64WithDefault(product["vfoodId"], 0)), - SkuName: product["name"].(string), - SalePrice: jxutils.StandardPrice2Int(utils.MustInterface2Float64(product["price"])), - Weight: int(math.Round(utils.Interface2Float64WithDefault(product["weight"], 0.0))), - } - if dao.IsVendorThingIDEmpty(sku.VendorSkuID) { - sku.VendorSkuID = utils.Int64ToStr(utils.MustInterface2Int64(product["id"])) // 2018-09-28日,饿了么迁移到饿百后,这个字段发生了变化 - } - order.Skus = append(order.Skus, sku) - } - } - jxutils.RefreshOrderSkuRelated(order) - return order -} - -// -func (c *PurchaseHandler) onOrderNew(msg map[string]interface{}) (response *elmapi.CallbackResponse) { - // todo 这里应该可以直接用msg里的内容,而不用再次去查 - order, err := c.GetOrder("", msg["orderId"].(string)) - if err == nil { - order.VendorStatus = c.stateAndType2Str(order.VendorStatus, elmapi.MsgTypeOrderValid) - err = partner.CurOrderManager.OnOrderNew(order, nil) - // if globals.HandleLegacyJxOrder && err == nil { - // c.legacyWriteElmOrder(order) - // } - } - return elmapi.Err2CallbackResponse(err, "elm onOrderNew") -} - -func (c *PurchaseHandler) onOrderUserUrgeOrder(msg *elmapi.CallbackOrderUrgeMsg) *elmapi.CallbackResponse { - status := &model.OrderStatus{ - VendorOrderID: msg.OrderID, - VendorID: model.VendorIDELM, - OrderType: model.OrderTypeOrder, - RefVendorOrderID: msg.OrderID, - RefVendorID: model.VendorIDELM, - Status: model.OrderStatusApplyUrgeOrder, - VendorStatus: utils.Int2Str(msg.MsgType), - StatusTime: utils.Timestamp2Time(msg.UpdateTime), - } - c.ClientUrgeOrder(msg.OrderID) - return elmapi.Err2CallbackResponse(partner.CurOrderManager.OnOrderStatusChanged("", status), status.VendorStatus) -} - -func (c *PurchaseHandler) stateAndType2Str(state string, msgType int) string { - return fmt.Sprintf("%s-%d", state, msgType) -} - -func (c *PurchaseHandler) spliltCompositeState(compositeState string) (state string, msgType int) { - index := strings.Index(compositeState, "-") - if index >= 0 { - msgType = int(utils.Str2Int64(compositeState[index+1:])) - if msgType == 0 { - globals.SugarLogger.Debug(compositeState) - } - return compositeState[:index], msgType - } - return compositeState, 0 -} - -// IPurchasePlatformHandler -func (c *PurchaseHandler) getStatusFromVendorStatus(vendorStatus string) int { - state, _ := c.spliltCompositeState(vendorStatus) - if status, ok := VendorStatus2StatusMap[state]; ok { - return status - } - return model.OrderStatusUnknown -} - -func (c *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) { - globals.SugarLogger.Debugf("elm AcceptOrRefuseOrder orderID:%s", order.VendorOrderID) - // if globals.EnableElmStoreWrite { - // if isAcceptIt { - // err = api.ElmAPI.ConfirmOrder(order.VendorOrderID) - // } else { - // err = api.ElmAPI.CancelOrder(order.VendorOrderID, elmapi.CancelOrderTypeOthers, "") - // } - // } - return err -} - -// 饿了么没有拣货这个状态,直接返回成功 -// 真实流程中也不会调用这个方法,因为接收订单后状态会直接转移到已拣货 -func (c *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) { - return nil -} - -func (p *PurchaseHandler) AcceptOrRefuseFailedGetOrder(ctx *jxcontext.Context, order *model.GoodsOrder, isAcceptIt bool) (err error) { - return err -} - -func (p *PurchaseHandler) CallCourier(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 拣货失败后再次招唤平台配送 - return err -} - -func (p *PurchaseHandler) ConfirmReceiveGoods(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 投递失败后确认收到退货 - return err -} - -func (c *PurchaseHandler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) { - // if globals.EnableElmStoreWrite { - // err = api.ElmAPI.DeliveryBySelfLite(order.VendorOrderID) - // } - return err -} - -// 饿了么转商家自送后,没有确认送达的概念,空操作 -func (c *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName string) (err error) { - return nil -} - -func (c *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) { - // if globals.EnableElmStoreWrite { - // err = api.ElmAPI.StartDeliveryBySelf(order.VendorOrderID, order.ConsigneeMobile) - // } - return err -} - -func (c *PurchaseHandler) SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) { - // if globals.EnableElmStoreWrite { - // err = api.ElmAPI.CompleteDeliveryBySelf(order.VendorOrderID, order.ConsigneeMobile) - // } - return err -} - -func (c *PurchaseHandler) GetStatusActionTimeout(order *model.GoodsOrder, statusType, status int) (params *partner.StatusActionParams) { - if statusType == scheduler.TimerStatusTypeOrder && status == model.OrderStatusNew { - params = &partner.StatusActionParams{ // 饿了么开了专送店的订单没有拣货状态,接单后就为拣货完成,所以要延迟接单,否则门店来不及备货 - Timeout: acceptOrderDelay, - } - } - return params -} - -func (c *PurchaseHandler) GetOrderRealMobile(ctx *jxcontext.Context, order *model.GoodsOrder) (mobile string, err error) { - err = errors.New("饿了么还未实现GetOrderRealMobile") - return mobile, err -} - -func (c *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) { - return err -} - -func (c *PurchaseHandler) CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) { - return err -} - -func (c *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) { - return err -} diff --git a/business/partner/purchase/elm/order_afs.go b/business/partner/purchase/elm/order_afs.go deleted file mode 100644 index cade24f3d..000000000 --- a/business/partner/purchase/elm/order_afs.go +++ /dev/null @@ -1,28 +0,0 @@ -package elm - -import ( - "fmt" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" -) - -// 审核售后单申请 -func (c *PurchaseHandler) AgreeOrRefuseRefund(ctx *jxcontext.Context, order *model.AfsOrder, approveType int, reason string) (err error) { - return err -} - -// 确认收到退货 -func (c *PurchaseHandler) ConfirmReceivedReturnGoods(ctx *jxcontext.Context, order *model.AfsOrder) (err error) { - return err -} - -// 发起全款退款 -func (c *PurchaseHandler) RefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) { - return fmt.Errorf("饿了么不支持全款退款") -} - -// 发起部分退款 -func (c *PurchaseHandler) PartRefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, refundSkuList []*model.OrderSku, reason string) (err error) { - return fmt.Errorf("饿了么不支持部分退款") -} diff --git a/business/partner/purchase/elm/order_comment.go b/business/partner/purchase/elm/order_comment.go deleted file mode 100644 index 18cba44d6..000000000 --- a/business/partner/purchase/elm/order_comment.go +++ /dev/null @@ -1,10 +0,0 @@ -package elm - -import ( - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" -) - -func (c *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, vendorOrgCode string, orderComment *model.OrderComment, replyComment string) (err error) { - return err -} diff --git a/business/partner/purchase/elm/order_legacy_urge.go b/business/partner/purchase/elm/order_legacy_urge.go deleted file mode 100644 index 2d0017e6d..000000000 --- a/business/partner/purchase/elm/order_legacy_urge.go +++ /dev/null @@ -1,52 +0,0 @@ -package elm - -import ( - aliyunsmsclient "github.com/KenmyZhang/aliyun-communicate" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" -) - -const ( - ELM_SMS_REMINDERS_DAIPEISHONG_TEMPLATECODE = "SMS_175573181" //饿了么待配送模板ID - ELM_SMS_REMINDERS_PEISHOGNZHONG_TEMPLATECODE = "SMS_175583155" //饿了么配送中模板ID -) - -func (c *PurchaseHandler) ClientUrgeOrder(orderID string) (err error) { - utils.CallFuncAsync(func() { - var err error - globals.SugarLogger.Debugf("ClientUrgeOrder orderID:%s", orderID) - order, err2 := partner.CurOrderManager.LoadOrder(orderID, model.VendorIDELM) - if err = err2; err == nil { - templateCode := "" - var templateParams map[string]interface{} - if order.Status == model.OrderStatusFinishedPickup { - templateCode = ELM_SMS_REMINDERS_DAIPEISHONG_TEMPLATECODE - templateParams = map[string]interface{}{ - "name": order.ConsigneeName, - } - } else if order.Status == model.OrderStatusDelivering { - bill, err2 := partner.CurOrderManager.LoadWaybill(order.VendorWaybillID, order.WaybillVendorID) - if err = err2; err == nil { - templateCode = ELM_SMS_REMINDERS_PEISHOGNZHONG_TEMPLATECODE - templateParams = map[string]interface{}{ - "name": order.ConsigneeName, - "number": bill.CourierMobile, - } - } - } - if templateCode != "" { - smsClient := aliyunsmsclient.New("http://dysmsapi.aliyuncs.com/") - if globals.ReallyCallPlatformAPI { - _, err = smsClient.Execute(globals.AliKey, globals.AliSecret, order.ConsigneeMobile, globals.SMSSignName, templateCode, string(utils.MustMarshal(templateParams))) - } - } - } - if err != nil { - globals.SugarLogger.Warnf("ClientUrgeOrder orderID:%s failed with error:%v", orderID, err) - } - }) - return err -} diff --git a/business/partner/purchase/elm/order_test.go b/business/partner/purchase/elm/order_test.go deleted file mode 100644 index 1a3f7b704..000000000 --- a/business/partner/purchase/elm/order_test.go +++ /dev/null @@ -1,23 +0,0 @@ -package elm - -import ( - "testing" - - _ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" - "git.rosy.net.cn/jx-callback/globals/testinit" -) - -func init() { - testinit.Init() -} - -func TestGetOrder(t *testing.T) { - orderID := "3025427524410871880" - order, err := new(PurchaseHandler).GetOrder("", orderID) - if err != nil { - t.Fatal(err.Error()) - } - if order.VendorOrderID != orderID { - t.Fatal(err.Error()) - } -} diff --git a/business/partner/purchase/elm/store.go b/business/partner/purchase/elm/store.go deleted file mode 100644 index ff863d62a..000000000 --- a/business/partner/purchase/elm/store.go +++ /dev/null @@ -1,25 +0,0 @@ -package elm - -import ( - "errors" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model/dao" -) - -func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorOrgCode string, vendorStoreID string) (*dao.StoreDetail, error) { - return nil, errors.New("饿了么还没实现") -} - -func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName string) error { - return nil -} - -func (p *PurchaseHandler) RefreshAllStoresID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) { - return hint, err -} - -func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (storeStatus int, err error) { - return storeStatus, err -} diff --git a/business/partner/purchase/elm/waybill.go b/business/partner/purchase/elm/waybill.go deleted file mode 100644 index 3396bad59..000000000 --- a/business/partner/purchase/elm/waybill.go +++ /dev/null @@ -1,67 +0,0 @@ -package elm - -import ( - "fmt" - - "git.rosy.net.cn/baseapi/platformapi/elmapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals/api" -) - -func (c *PurchaseHandler) OnWaybillStatusMsg(msg *elmapi.CallbackWaybillStatusMsg) (retVal *elmapi.CallbackResponse) { - jxutils.CallMsgHandler(func() { - retVal = c.onWaybillStatusMsg(msg) - }, jxutils.ComposeUniversalOrderID(msg.OrderID, model.VendorIDELM)) - return retVal -} - -func (c *PurchaseHandler) onWaybillStatusMsg(msg *elmapi.CallbackWaybillStatusMsg) (retVal *elmapi.CallbackResponse) { - order := c.callbackMsg2Waybill(msg) - if msg.MsgType == elmapi.MsgTypeWaybillWait4Courier { //MsgTypeWaybillWait4Courier事件与JD的新运单事件的时间机制更相似 - order.Status = model.WaybillStatusNew - } else if msg.MsgType == elmapi.MsgTypeWaybillPickingUp { - if result, err := api.ElmAPI.GetOrder(msg.OrderID); err == nil { - order.DesiredFee = jxutils.StandardPrice2Int(utils.Interface2Float64WithDefault(result["deliverFee"], 0.0) + - utils.Interface2Float64WithDefault(result["vipDeliveryFeeDiscount"], 0.0)) - } - order.Status = model.WaybillStatusAccepted - } else if msg.MsgType == elmapi.MsgTypeWaybillCourierArrived { - order.Status = model.WaybillStatusCourierArrived - } else if msg.MsgType == elmapi.MsgTypeWaybillDelivering { - order.Status = model.WaybillStatusDelivering - } else if msg.MsgType == elmapi.MsgTypeWaybillDelivered { - order.Status = model.WaybillStatusDelivered - } else if msg.MsgType >= elmapi.MsgTypeWaybillCanceledByMerchant && msg.MsgType <= elmapi.MsgTypeWaybillCanceledBySystem { - order.Status = model.WaybillStatusCanceled - } else if msg.MsgType >= elmapi.MsgTypeWaybillFailedCallLate && - msg.MsgType <= elmapi.MsgTypeRejectedSystemError && - msg.MsgType != elmapi.MsgTypeDeiverBySelf { - order.Status = model.WaybillStatusFailed - } else { - // MsgTypeWaybillWait4DeliveryVendor - // MsgTypeDeiverBySelf - order.Status = model.WaybillStatusUnknown - } - return elmapi.Err2CallbackResponse(partner.CurOrderManager.OnWaybillStatusChanged(order), order.VendorStatus) -} - -func (c *PurchaseHandler) callbackMsg2Waybill(msg *elmapi.CallbackWaybillStatusMsg) (retVal *model.Waybill) { - retVal = &model.Waybill{ - VendorOrderID: msg.OrderID, - OrderVendorID: model.VendorIDELM, - VendorWaybillID: msg.OrderID, - WaybillVendorID: model.VendorIDELM, - CourierName: msg.Name, - CourierMobile: msg.Phone, - VendorStatus: c.composeState(msg.State, msg.SubState, msg.MsgType), - StatusTime: utils.Timestamp2Time(msg.UpdateAt / 1000), - } - return retVal -} - -func (c *PurchaseHandler) composeState(state, subState string, msgType int) string { - return fmt.Sprintf("%s-%d", state, msgType) -} diff --git a/business/partner/purchase/jd/act.go b/business/partner/purchase/jd/act.go deleted file mode 100644 index 03b82487e..000000000 --- a/business/partner/purchase/jd/act.go +++ /dev/null @@ -1,422 +0,0 @@ -package jd - -import ( - "fmt" - "time" - - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - - "git.rosy.net.cn/jx-callback/business/jxutils" - - "git.rosy.net.cn/jx-callback/globals" - - "git.rosy.net.cn/baseapi/platformapi/jdapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/baseapi/utils/errlist" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" -) - -const ( - actMapDuration = 2 * time.Hour -) - -type LogicUpdateInfo struct { - Item interface{} - KVs map[string]interface{} - Condition map[string]interface{} -} - -var ( - jdSkuActStatusMap = map[int]int{ - jdapi.PromotionStateNotConfirm: model.ActStatusNA, - jdapi.PromotionStateConfirmed: model.ActStatusCreated, - jdapi.PromotionStateCanceled: model.ActStatusCanceled, - jdapi.PromotionStateEnded: model.ActStatusEnded, - } - - actMap jxutils.SyncMapWithTimeout -) - -// 是否按单一门店商品维度创建活动 -func isCreateTypeSingleStoreSku() bool { - return false - // return !globals.IsProductEnv() -} - -func splitPromotionSku(skus []*jdapi.PromotionSku, maxCount int) (skusList [][]*jdapi.PromotionSku) { - for { - skusLen := len(skus) - if skusLen <= maxCount { - skusList = append(skusList, skus) - break - } - skusList = append(skusList, skus[:maxCount]) - skus = skus[maxCount:] - } - return skusList -} - -func jdSkuActType2Jx(actType int) int { - if actType == jdapi.PromotionTypeDirectDown { - return model.ActSkuDirectDown - } else if actType == jdapi.PromotionTypeSeckill || actType == jdapi.PromotionTypeLimitedTime { - return model.ActSkuSecKill - } - return 0 -} - -func jdSkuActStatus2Jx(jdActState int) int { - return jdSkuActStatusMap[jdActState] -} - -func CreatePromotionInfos(vendorOrgCode string, promotionType int, name string, beginDate, endDate time.Time, outInfoId, advertising, traceId string) (infoId int64, err error) { - if globals.EnableJdStoreWrite { - if promotionType == model.ActSkuDirectDown { - infoId, err = getAPI(vendorOrgCode).CreatePromotionInfosSingle(name, beginDate, endDate, outInfoId, advertising, traceId) - } else { - infoId, err = getAPI(vendorOrgCode).CreatePromotionInfosLimitTime(name, beginDate, endDate, outInfoId, advertising, traceId) - } - } else { - infoId = jxutils.GenFakeID() - } - if err == nil { - actMap.StoreWithTimeout(infoId, 1, actMapDuration) - } - return infoId, err -} - -func CreatePromotionRules(vendorOrgCode string, promotionType int, infoId int64, outInfoId string, limitDevice, limitPin, limitCount, limitDaily int, traceId string) (err error) { - if globals.EnableJdStoreWrite { - if promotionType == model.ActSkuDirectDown { - err = getAPI(vendorOrgCode).CreatePromotionRulesSingle(infoId, outInfoId, limitDevice, limitPin, limitCount, limitDaily, traceId) - } else { - err = getAPI(vendorOrgCode).CreatePromotionRulesLimitTime(infoId, outInfoId, limitDevice, limitPin, limitCount, limitDaily, traceId) - } - } - return err -} - -func CreatePromotionSku(vendorOrgCode string, promotionType int, infoId int64, outInfoId string, skus []*jdapi.PromotionSku, traceId string) (skusResult []*jdapi.PromotionSku, err error) { - if globals.EnableJdStoreWrite { - for _, batchSkus := range splitPromotionSku(skus, jdapi.MaxPromotionSkuCount) { - var tmpSkusResult []*jdapi.PromotionSku - var tmpErr error - if promotionType == model.ActSkuDirectDown { - tmpSkusResult, tmpErr = getAPI(vendorOrgCode).CreatePromotionSkuSingle(infoId, outInfoId, batchSkus, traceId) - } else { - tmpSkusResult, tmpErr = getAPI(vendorOrgCode).CreatePromotionSkuLimitTime(infoId, outInfoId, batchSkus, traceId) - } - if err = tmpErr; err != nil { - break - } - skusResult = append(skusResult, tmpSkusResult...) - } - } - return skusResult, err -} - -func CancelPromotionSku(vendorOrgCode string, promotionType int, infoId int64, outInfoId string, skus []*jdapi.PromotionSku, traceId string) (err error) { - if globals.EnableJdStoreWrite { - for _, batchSkus := range splitPromotionSku(skus, jdapi.MaxPromotionSkuCount) { - var tmpErr error - if promotionType == model.ActSkuDirectDown { - tmpErr = getAPI(vendorOrgCode).CancelPromotionSkuSingle(infoId, outInfoId, batchSkus, traceId) - } else { - tmpErr = getAPI(vendorOrgCode).CancelPromotionSkuLimitTime(infoId, outInfoId, batchSkus, traceId) - } - if err = tmpErr; err != nil { - break - } - } - } - return err -} - -func ConfirmPromotion(vendorOrgCode string, promotionType int, infoId int64, outInfoId, traceId string) (err error) { - if globals.EnableJdStoreWrite { - if promotionType == model.ActSkuDirectDown { - return getAPI(vendorOrgCode).ConfirmPromotionSingle(infoId, outInfoId, traceId) - } else { - return getAPI(vendorOrgCode).ConfirmPromotionLimitTime(infoId, outInfoId, traceId) - } - } - return err -} - -func CancelPromotion(vendorOrgCode string, promotionType int, infoId int64, outInfoId, traceId string) (err error) { - if globals.EnableJdStoreWrite { - if promotionType == model.ActSkuDirectDown { - err = getAPI(vendorOrgCode).CancelPromotionSingle(infoId, outInfoId, traceId) - } else { - err = getAPI(vendorOrgCode).CancelPromotionLimitTime(infoId, outInfoId, traceId) - } - } - return err -} - -func AdjustPromotionTime(vendorOrgCode string, promotionType int, infoId int64, outInfoId string, endDate time.Time, traceId string) (err error) { - if globals.EnableJdStoreWrite { - if promotionType == model.ActSkuDirectDown { - err = getAPI(vendorOrgCode).AdjustPromotionTimeSingle(infoId, outInfoId, endDate, traceId) - } else { - err = getAPI(vendorOrgCode).AdjustPromotionTimeLimitTime(infoId, outInfoId, endDate, traceId) - } - } - return err -} - -func AdjustPromotionSku(vendorOrgCode string, promotionType int, infoId int64, outInfoId string, skus []*jdapi.PromotionSku, traceId string) (skusResult []*jdapi.PromotionSku, err error) { - if globals.EnableJdStoreWrite { - if promotionType == model.ActSkuDirectDown { - skusResult, err = getAPI(vendorOrgCode).AdjustPromotionSkuSingle(infoId, outInfoId, skus, traceId) - } else { - skusResult, err = getAPI(vendorOrgCode).AdjustPromotionSkuLimitTime(infoId, outInfoId, skus, traceId) - } - } - return skusResult, err -} - -func storeSku2Jd(actStoreSku []*model.ActStoreSku2, handler func(syncStatus int8) bool) (jdActStoreSku []*jdapi.PromotionSku) { - for _, v := range actStoreSku { - if handler(v.SyncStatus) { - if v.VendorStoreID != "" && v.VendorSkuID != "" { - jdActStoreSku = append(jdActStoreSku, &jdapi.PromotionSku{ - StationNo: utils.Str2Int64(v.VendorStoreID), - SkuID: utils.Str2Int64(v.VendorSkuID), - PromotionPrice: v.ActualActPrice, - LimitSkuCount: v.Stock, - }) - } - } - } - return jdActStoreSku -} - -func createSkuAct(ctx *jxcontext.Context, act *model.Act2, actStoreSku []*model.ActStoreSku2) (vendorActID string, err error) { - traceInfo := ctx.GetTrackInfo() - outInfoID := "" - if act.VendorActID == "" { - outInfoID = utils.Int2Str(act.ID) - } - infoID, err2 := CreatePromotionInfos(act.VendorOrgCode, act.Type, act.GetRealActName(), act.BeginAt, act.EndAt, outInfoID, act.Advertising, traceInfo) - if err = err2; err == nil { - vendorActID = utils.Int64ToStr(infoID) - if err = CreatePromotionRules(act.VendorOrgCode, act.Type, infoID, "", act.LimitUser, act.LimitUser, act.LimitCount, 1, traceInfo); err == nil { - if _, err = CreatePromotionSku(act.VendorOrgCode, act.Type, infoID, utils.Int2Str(act.ID), storeSku2Jd(actStoreSku, model.IsSyncStatusNeedCreate), traceInfo); err == nil { - if err = ConfirmPromotion(act.VendorOrgCode, act.Type, infoID, "", traceInfo); err == nil { - for _, v := range actStoreSku { - v.VendorActID = vendorActID - } - } - } - } - if err != nil { - CancelPromotion(act.VendorOrgCode, act.Type, infoID, "", traceInfo) - } - } - return vendorActID, err -} - -func proxyCreateSkuAct(ctx *jxcontext.Context, act *model.Act2, actStoreSku []*model.ActStoreSku2) (vendorActID string, err error) { - if isCreateTypeSingleStoreSku() && len(actStoreSku) > 1 { - errList := errlist.New() - vendorActID := act.VendorActID - act.VendorActID = "placeholder" - for _, v := range actStoreSku { - _, err := createSkuAct(ctx, act, []*model.ActStoreSku2{v}) - errList.AddErr(err) - } - act.VendorActID = vendorActID - err = errList.GetErrListAsOne() - } else { - vendorActID, err = createSkuAct(ctx, act, actStoreSku) - } - return vendorActID, err -} - -func cancelSkuActSkus(ctx *jxcontext.Context, act *model.Act2, vendorActID string, actStoreSku []*model.ActStoreSku2) (err error) { - if vendorActID != "" { - if skuList := storeSku2Jd(actStoreSku, model.IsSyncStatusNeedDelete); len(skuList) > 0 { - err = CancelPromotionSku(act.VendorOrgCode, act.Type, utils.Str2Int64(vendorActID), "", skuList, ctx.GetTrackInfo()) - } - } - return err -} - -func cancelSkuAct(ctx *jxcontext.Context, act *model.Act2, vendorActID string) (err error) { - if vendorActID != "" { - err = CancelPromotion(act.VendorOrgCode, act.Type, utils.Str2Int64(vendorActID), "", ctx.GetTrackInfo()) - } - return err -} - -func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSkuList []*model.ActStoreSku2) (err error) { - globals.SugarLogger.Debugf("jd SyncAct, actID:%d", act.ID) - vendorActInfoMap := make(map[string][]*model.ActStoreSku2) - deleteActInfoMap := make(map[string][]*model.ActStoreSku2) - var actStoreSkuList4Create []*model.ActStoreSku2 - var updateItems []*dao.KVUpdateItem - - actStoreSkuMap := partner.SplitActStoreSku(actStoreSkuList) - actSkuCount := 0 - toDelActSkuCount := 0 - for storeID := range actStoreSkuMap { - for _, actStoreSku := range actStoreSkuMap[storeID] { - vendorActID := actStoreSku.VendorActID - if vendorActID == "" { - vendorActID = act.VendorActID - } - actSkuCount++ - vendorActInfoMap[vendorActID] = append(vendorActInfoMap[vendorActID], actStoreSku) - if model.IsSyncStatusDelete(actStoreSku.SyncStatus) { - toDelActSkuCount++ - deleteActInfoMap[vendorActID] = append(deleteActInfoMap[vendorActID], actStoreSku) - } else if model.IsSyncStatusNew(actStoreSku.SyncStatus) { - actStoreSkuList4Create = append(actStoreSkuList4Create, actStoreSku) - } - } - } - // 如果是全删,直接添加删除(即取消)标志 - if actSkuCount == toDelActSkuCount { - act.SyncStatus |= model.SyncFlagDeletedMask - } - db := dao.GetDB() - err = func() (err error) { - if model.IsSyncStatusDelete(act.SyncStatus) { - errList := errlist.New() - for vendorActID := range vendorActInfoMap { - if vendorActID != "" { - if err = cancelSkuAct(ctx, act, vendorActID); err == nil { - updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, vendorActInfoMap[vendorActID], model.SyncFlagModifiedMask)...) - } else { - errList.AddErr(err) - } - } - } - if err = errList.GetErrListAsOne(); err == nil { - updateItems = append(updateItems, partner.Act2Update(ctx, act, model.SyncFlagModifiedMask)) - } - } else if model.IsSyncStatusNew(act.SyncStatus) { - if act.VendorActID, err = proxyCreateSkuAct(ctx, act, actStoreSkuList4Create); err == nil { - updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, actStoreSkuList4Create, model.SyncFlagNewMask)...) - updateItems = append(updateItems, partner.Act2Update(ctx, act, model.SyncFlagNewMask)) - } else { - if act.VendorActID != "" { - actMap := partner.Act2ActMap(act) - dao.UpdateEntity(db, actMap, model.FieldVendorActID) - } - } - } else if model.IsSyncStatusUpdate(act.SyncStatus) { - errList := errlist.New() - if len(actStoreSkuList4Create) > 0 { - if _, err = proxyCreateSkuAct(ctx, act, actStoreSkuList4Create); err == nil { - updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, actStoreSkuList4Create, model.SyncFlagNewMask)...) - } else { - errList.AddErr(err) - } - } - for vendorActID := range deleteActInfoMap { - if vendorActID != "" { - if len(vendorActInfoMap[vendorActID]) == len(deleteActInfoMap[vendorActID]) { - err = cancelSkuAct(ctx, act, vendorActID) - } else { - err = cancelSkuActSkus(ctx, act, vendorActID, deleteActInfoMap[vendorActID]) - } - if err == nil { - updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, deleteActInfoMap[vendorActID], model.SyncFlagDeletedMask)...) - } else { - errList.AddErr(err) - } - } else { - updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, deleteActInfoMap[vendorActID], model.SyncFlagDeletedMask)...) - } - } - if err = errList.GetErrListAsOne(); err == nil { - updateItems = append(updateItems, partner.Act2Update(ctx, act, model.SyncFlagModifiedMask)) - } - } - return err - }() - // globals.SugarLogger.Debug(utils.Format4Output(updateItems, false)) - _, err2 := dao.BatchUpdateActEntity(db, model.IsSyncStatusDelete(act.SyncStatus), updateItems) - if err == nil { - err = err2 - } - return err -} - -func OnActMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { - jxutils.CallMsgHandler(func() { - retVal = CurPurchaseHandler.onActMsg(msg) - }, jxutils.ComposeUniversalOrderID(msg.BillID, model.VendorIDJD)) - return retVal -} - -func (c *PurchaseHandler) onActMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { - if msg.StatusID == jdapi.PromotionStatusSingleOK || msg.StatusID == jdapi.PromotionStatusLimitTimeOK { - promotionID := msg.BillID - intPromotionID := utils.Str2Int64(promotionID) - if _, ok := actMap.Load(intPromotionID); !ok { - utils.CallFuncAsync(func() { - if !partner.CurActManager.IsVendorActExist(jxcontext.AdminCtx, promotionID, model.VendorIDJD) { - act, actStoreSkuList, err := getActFromJD(AppKey2OrgCode(msg.AppKey), promotionID) - if err == nil && len(actStoreSkuList) > 0 { - _, err = partner.CurActManager.CreateActFromVendor(jxcontext.AdminCtx, act, actStoreSkuList) - } - if err != nil { - retVal = jdapi.Err2CallbackResponse(err, promotionID) - } - } - }) - } else { - actMap.Delete(intPromotionID) - } - } - return retVal -} - -func getActFromJD(vendorOrgCode, promotionID string) (act *model.Act2, actStoreSkuList []*model.ActStoreSku2, err error) { - result, err := getAPI(vendorOrgCode).QueryPromotionInfo(utils.Str2Int64(promotionID)) - if err == nil && len(result.SkuResultList) > 0 { - act = &model.Act2{ - Act: model.Act{ - Name: fmt.Sprintf("%s-%d", result.Source, result.PromotionInfoID), - Type: jdSkuActType2Jx(result.PromotionType), - Status: jdSkuActStatus2Jx(result.PromotionState), - BeginAt: result.SkuResultList[0].BeginTime.GoTime(), - EndAt: result.SkuResultList[0].EndTime.GoTime(), - Source: result.Source, - CreateType: model.ActCreateTypeCallback, - PricePercentage: 0, - LimitDaily: result.SkuResultList[0].LimitDaily, - LimitCount: 1, - }, - VendorID: model.VendorIDJD, - VendorOrgCode: vendorOrgCode, - VendorActID: promotionID, - } - if utils.IsTimeZero(act.BeginAt) { - act.BeginAt = result.BeginTime.GoTime() - } - if utils.IsTimeZero(act.EndAt) { - act.EndAt = result.EndTime.GoTime().Add(24*time.Hour - 1*time.Second) - } - if result.SkuResultList[0].LimitPin == 1 || result.SkuResultList[0].LimitDevice == 1 { - act.LimitUser = 1 - } - - for _, v := range result.SkuResultList { - if v.PromotionState != jdapi.PromotionStateCanceled { - actStoreSkuList = append(actStoreSkuList, &model.ActStoreSku2{ - VendorStoreID: utils.Int64ToStr(v.StationNo), - VendorSkuID: utils.Int64ToStr(v.SkuID), - ActualActPrice: int64(v.PromotionPrice), - }) - } - } - } - return act, actStoreSkuList, err -} diff --git a/business/partner/purchase/jd/callback.go b/business/partner/purchase/jd/callback.go deleted file mode 100644 index f4d45bd51..000000000 --- a/business/partner/purchase/jd/callback.go +++ /dev/null @@ -1,33 +0,0 @@ -package jd - -import ( - "git.rosy.net.cn/baseapi/platformapi/jdapi" -) - -func OnOrderMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { - if CurPurchaseHandler != nil { - retVal = CurPurchaseHandler.OnOrderMsg(AppKey2OrgCode(msg.AppKey), msg) - } - return retVal -} - -func OnWaybillMsg(msg *jdapi.CallbackDeliveryStatusMsg) (retVal *jdapi.CallbackResponse) { - if CurPurchaseHandler != nil { - retVal = CurPurchaseHandler.OnWaybillMsg(AppKey2OrgCode(msg.AppKey), msg) - } - return retVal -} - -func OnStoreMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { - if CurPurchaseHandler != nil { - retVal = CurPurchaseHandler.OnStoreMsg(AppKey2OrgCode(msg.AppKey), msg) - } - return retVal -} - -func OnOrderInfoChangeMsg(msg *jdapi.CallbackOrderInfoChangeMsg) (retVal *jdapi.CallbackResponse) { - if CurPurchaseHandler != nil { - retVal = CurPurchaseHandler.OnOrderInfoChangeMsg(AppKey2OrgCode(msg.AppKey), msg) - } - return retVal -} diff --git a/business/partner/purchase/jd/financial.go b/business/partner/purchase/jd/financial.go deleted file mode 100644 index 814b750e4..000000000 --- a/business/partner/purchase/jd/financial.go +++ /dev/null @@ -1,244 +0,0 @@ -package jd - -import ( - "math" - - "git.rosy.net.cn/baseapi/platformapi/jdapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" -) - -func (p *PurchaseHandler) OnFinancialMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { - utils.CallFuncAsync(func() { - retVal = p.onFinancialMsg(msg) - }) - return retVal -} - -// 京东正向/退款订单类型处理--存储 -func (p *PurchaseHandler) onFinancialMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { - var err error - a := getAPI(AppKey2OrgCode(msg.AppKey)) - // if msg.StatusID == jdapi.OrderStatusPayFinishedSettle || msg.StatusID == jdapi.OrderStatusTipChanged || msg.StatusID == jdapi.OrderStatusSwitch2SelfSettle { // 如果是正向单 - if msg.StatusID == jdapi.OrderStatusPayFinishedSettle || msg.StatusID == jdapi.OrderStatusTipChanged || msg.StatusID == jdapi.OrderStatusAdjustSettle || msg.StatusID == jdapi.OrderStatusSwitch2SelfSettle { // 如果是正向单 - order, err2 := partner.CurOrderManager.LoadOrder(msg.BillID, model.VendorIDJD) - if err = err2; err == nil { - orderData, err2 := a.QuerySingleOrder(msg.BillID) - if err = err2; err == nil { - orderFinancial, err2 := CurPurchaseHandler.OrderDetail2Financial(a, orderData, false, order) - if err = err2; err == nil { - if msg.StatusID == jdapi.OrderStatusPayFinishedSettle { - err = partner.CurOrderManager.SaveOrderFinancialInfo(orderFinancial, partner.CreatedPeration) - } else { - err = partner.CurOrderManager.SaveOrderFinancialInfo(orderFinancial, partner.UpdatedPeration) - } - } - } - } else { - err = nil - } - } else if msg.StatusID == jdapi.AfsServiceStateRefundSuccess || msg.StatusID == jdapi.AfsServiceStateReturnGoodsSuccess { // 如果是退款单 - orderData, err2 := a.GetAfsService(msg.BillID) - if err = err2; err == nil { - err = partner.CurOrderManager.SaveAfsOrderFinancialInfo(CurPurchaseHandler.AfsOrderDetail2Financial(orderData)) - } - } - return jdapi.Err2CallbackResponse(nil, "jd OnFinancialMsg") // todo 强制返回成功 -} - -// 处理京东正向订单信息 -func (p *PurchaseHandler) OrderDetail2Financial(a *jdapi.API, orderData map[string]interface{}, isFromOrderDetail bool, order *model.GoodsOrder) (orderFinancial *model.OrderFinancial, err error) { - orderFinancial = &model.OrderFinancial{ - VendorID: model.VendorIDJD, - VendorOrderID: utils.Int64ToStr(utils.MustInterface2Int64(orderData["orderId"])), - ReceivableFreight: utils.MustInterface2Int64(orderData["orderReceivableFreight"]), - FreightMoney: utils.MustInterface2Int64(orderData["orderFreightMoney"]), - ActualPayMoney: utils.MustInterface2Int64(orderData["orderBuyerPayableMoney"]), - DiscountMoney: utils.MustInterface2Int64(orderData["orderDiscountMoney"]), - DistanceFreightMoney: utils.MustInterface2Int64(orderData["merchantPaymentDistanceFreightMoney"]), - FreightTipsMoney: utils.MustInterface2Int64(orderData["tips"]), - PointsDeductionMoney: utils.MustInterface2Int64(orderData["platformPointsDeductionMoney"]), - // BoxMoney: utils.MustInterface2Int64(orderData["packagingMoney"]), // 京东包装(塑料袋)由京东提供,相应钱款也归京东,不记录/记录之后优化算法 - } - skus := order.Skus - if skus != nil { - for _, x := range skus { - orderFinancial.ShopPriceMoney += x.ShopPrice * int64(x.Count) - } - } - if orderData["product"] != nil { - product := orderData["product"].([]interface{}) - for _, x := range product { - xMap := x.(map[string]interface{}) - orderSkuFinancial := &model.OrderSkuFinancial{ - VendorID: orderFinancial.VendorID, - VendorOrderID: orderFinancial.VendorOrderID, - // OrderFinancialID: orderFinancial.VendorOrderID, - // ConfirmTime: utils.Str2Time(utils.Interface2String(orderData["orderStartTime"])), - VendorStoreID: utils.Interface2String(orderData["deliveryStationNo"]), - StoreID: int(utils.Str2Int64WithDefault(utils.Interface2String(orderData["deliveryStationNoIsv"]), 0)), - JxStoreID: order.JxStoreID, - VendorSkuID: utils.Int64ToStr(utils.MustInterface2Int64(xMap["skuId"])), - // SkuID: int(utils.Str2Int64(utils.Interface2String(xMap["skuIdIsv"]))), - PromotionType: int(utils.MustInterface2Int64(xMap["promotionType"])), - Name: utils.Interface2String(xMap["skuName"]), - ShopPrice: utils.MustInterface2Int64(xMap["skuStorePrice"]), - SalePrice: utils.MustInterface2Int64(xMap["skuJdPrice"]), - Count: int(utils.MustInterface2Int64(xMap["skuCount"])), - IsAfsOrder: 0, - // MealBoxMoney: utils.MustInterface2Int64(xMap["canteenMoney"]), // 京东的目前不考虑结算餐盒费,因为都归京东所有 - } - - // PromotionType 是一个关键数据,可能某商品活动限购,用户超出限购数量,超出部分不享受优惠,那么除了要在活动表根据skuId,活动起止日期,活动城市来查询,还需要判断活动类型PromotionType - // 平台/京西单条sku补贴金额,应该去京西后台活动库去取,活动里针对单条SKU,如果京东/京西有补贴,应该有记录 - // orderSkuFinancial.PmSubsidyMoneyForSku = - // orderSkuFinancial.JxSubsidyMoneyForSku = - // orderFinancial.JxSubsidyMoneyToSku += orderSkuFinancial.JxSubsidyMoneyForSku - // orderFinancial.JxSubsidyMoney += orderSkuFinancial.JxSubsidyMoneyForSku - orderFinancial.SalePriceMoney += orderSkuFinancial.SalePrice * int64(orderSkuFinancial.Count) - orderSkuFinancial.SkuID = int(utils.Str2Int64WithDefault(utils.Interface2String(xMap["skuIdIsv"]), 0)) - if orderSkuFinancial.SkuID > math.MaxInt32 { - orderSkuFinancial.SkuID = orderSkuFinancial.JxSkuID - } - orderFinancial.Skus = append(orderFinancial.Skus, orderSkuFinancial) - } - } - // orderFinancial.DeliveryConfirmTime = utils.Str2TimeWithDefault(utils.Interface2String(orderData["deliveryConfirmTime"]), utils.DefaultTimeValue) - if int(utils.Str2Int64WithDefault(utils.Interface2String(orderData["deliveryCarrierNo"]), 0)) == jdapi.CarrierNoSelfDelivery { - // 如果为自配送,自配送补贴=订单初始运费,远距离费=0 - orderFinancial.SelfDeliveryDiscountMoney = utils.MustInterface2Int64(orderData["orderReceivableFreight"]) - orderFinancial.DistanceFreightMoney = 0 - orderFinancial.FreightTipsMoney = 0 - // 通过本地数据库去取是否转美团/达达,并计算运费 - // wayBill, err2 := partner.CurOrderManager.LoadWaybill(orderFinancial.VendorOrderID, orderFinancial.VendorID) - // if err = err2; err == nil { - // orderFinancial.JxFreightMoney = wayBill.DesiredFee - // } - } - if orderData["discount"] != nil { - discount := orderData["discount"].([]interface{}) - for _, x := range discount { - xMap := x.(map[string]interface{}) - discountPrice := utils.MustInterface2Int64(xMap["discountPrice"]) - discountType := int(utils.MustInterface2Int64(xMap["discountType"])) - if discountType == jdapi.FreightDiscountTypeByShop { - orderFinancial.FreightDiscountMoney = discountPrice - } else if discountType == jdapi.FreightDiscountTypeByVip || discountType == jdapi.FreightDiscountTypeByActivity { - orderFinancial.PmFreightDiscountMoney = discountPrice - } else if discountType == jdapi.FreightDiscountTypeByCoupons { - if xMap["platPayMoney"] == nil { - orderFinancial.PmFreightDiscountMoney = discountPrice - } else { - orderFinancial.PmFreightDiscountMoney = int64(utils.MustInterface2Float64(xMap["platPayMoney"])) - orderFinancial.FreightDiscountMoney = discountPrice - orderFinancial.PmFreightDiscountMoney - } - } - orderFinancial.TotalDiscountMoney += discountPrice - if xMap["orderShareRatioData"] != nil { - orderShareRatioData, _ := utils.HTTPBody2Values([]byte(utils.Interface2String(xMap["orderShareRatioData"])), false) - if promotionID := orderShareRatioData.Get("promotionId"); promotionID != "" { - activity := &model.OrderDiscountFinancial{ - VendorID: orderFinancial.VendorID, - VendorOrderID: orderFinancial.VendorOrderID, - VendorActivityID: promotionID, // utils.Interface2String(orderShareRatioData["promotionId"][0]), - Type: utils.Int64ToStr(int64(discountType)), - // ActivityName: utils.Interface2String(xMap["discountName"]), - // ActivityMoney: discountPrice, - // Remark: utils.Interface2String(xMap["orderShareRatioData"]), - } - orderFinancial.Discounts = append(orderFinancial.Discounts, activity) - // 通过活动Id去取,京西活动补贴 - // orderFinancial.JxSubsidyMoney += - } - } - } - // globals.SugarLogger.Debug(utils.Format4Output(orderFinancial.Discounts, false)) - } - order1, err2 := a.OrderShoudSettlementService(orderFinancial.VendorOrderID) - if err = err2; err == nil { - orderFinancial.ShopMoney = utils.Interface2Int64WithDefault(order1["settlementAmount"], 0) - orderFinancial.PmMoney += utils.Interface2Int64WithDefault(order1["goodsCommission"], 0) - orderFinancial.PmMoney += utils.Interface2Int64WithDefault(order1["freightCommission"], 0) - orderFinancial.PmMoney += utils.Interface2Int64WithDefault(order1["packageCommission"], 0) - orderFinancial.PmMoney += utils.Interface2Int64WithDefault(order1["guaranteedCommission"], 0) - orderFinancial.PmSkuSubsidyMoney = utils.Interface2Int64WithDefault(order1["platSkuGoodsDiscountMoney"], 0) - orderFinancial.PmSubsidyMoney = utils.Interface2Int64WithDefault(order1["platOrderGoodsDiscountMoney"], 0) + orderFinancial.PmSkuSubsidyMoney - } - return orderFinancial, err -} - -// 处理京东售后订单结账信息 -func (p *PurchaseHandler) AfsOrderDetail2Financial(orderData map[string]interface{}) (afsOrder *model.AfsOrder) { - afsOrder = &model.AfsOrder{ - VendorID: model.VendorIDJD, - AfsOrderID: utils.Interface2String(orderData["afsServiceOrder"]), - VendorOrderID: utils.Interface2String(orderData["orderId"]), - VendorStoreID: utils.Interface2String(orderData["stationId"]), - StoreID: int(utils.Str2Int64WithDefault(utils.Interface2String(orderData["stationNumOutSystem"]), 0)), - AfsCreatedAt: utils.Timestamp2Time(utils.MustInterface2Int64(orderData["updateTime"].(map[string]interface{})["time"]) / 1000), - FreightUserMoney: utils.MustInterface2Int64(orderData["orderFreightMoney"]), - AfsFreightMoney: utils.MustInterface2Int64(orderData["afsFreight"]), - BoxMoney: utils.MustInterface2Int64(orderData["packagingMoney"]), - TongchengFreightMoney: utils.MustInterface2Int64(orderData["tongchengFreightMoney"]), - SkuBoxMoney: utils.MustInterface2Int64(orderData["mealBoxMoney"]), - VendorOrgCode: utils.Interface2String(orderData["venderId"]), - } - order, err := partner.CurOrderManager.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID) - if err == nil { - afsOrder.JxStoreID = order.JxStoreID - } else { - globals.SugarLogger.Warnf("jd AfsOrderDetail2Financial, afsOrderID:%s is not found from partner.CurOrderManager.LoadOrder", afsOrder.VendorOrderID) - } - if orderData["afsDetailList"] != nil { - refundDetail := orderData["afsDetailList"].([]interface{}) - for _, x := range refundDetail { - xMap := x.(map[string]interface{}) - orderSku := &model.OrderSkuFinancial{ - VendorID: model.VendorIDJD, - AfsOrderID: afsOrder.AfsOrderID, - VendorOrderID: afsOrder.VendorOrderID, - VendorStoreID: afsOrder.VendorStoreID, - StoreID: afsOrder.StoreID, - // ConfirmTime: afsOrder.AfsCreateAt, - VendorSkuID: utils.Int64ToStr(utils.MustInterface2Int64(xMap["wareId"])), - SkuID: int(utils.Str2Int64WithDefault(utils.Interface2String(xMap["skuIdIsv"]), 0)), - Name: utils.Interface2String(xMap["wareName"]), - UserMoney: utils.MustInterface2Int64(xMap["afsMoney"]), - PmSkuSubsidyMoney: utils.MustInterface2Int64(xMap["platPayMoney"]), - IsAfsOrder: 1, - } - afsOrder.PmSkuSubsidyMoney += orderSku.PmSkuSubsidyMoney - orderSku.PmSubsidyMoney += orderSku.PmSkuSubsidyMoney - - if xMap["afsSkuDiscountList"] != nil { - afsSkuDiscountList := xMap["afsSkuDiscountList"].([]interface{}) - for _, y := range afsSkuDiscountList { - orderSku.PmSubsidyMoney += utils.MustInterface2Int64(y.(map[string]interface{})["platPayMoney"]) - } - } - - afsOrder.SkuUserMoney += orderSku.UserMoney - afsOrder.PmSubsidyMoney += orderSku.PmSubsidyMoney - afsOrder.Skus = append(afsOrder.Skus, orderSku) - } - if len(refundDetail) <= 0 { - globals.SugarLogger.Warnf("jd AfsOrderDetail2Financial, orderID:%s have no refund_detail", afsOrder.VendorOrderID) - } - } else { - globals.SugarLogger.Warnf("jd AfsOrderDetail2Financial, orderID:% refund_detail is nil", afsOrder.VendorOrderID) - } - return afsOrder -} - -func (p *PurchaseHandler) OnOrderDetail(a *jdapi.API, orderDetail map[string]interface{}, peration string) (err error) { - order, err := partner.CurOrderManager.LoadOrder(utils.Int64ToStr(utils.MustInterface2Int64(orderDetail["orderId"])), model.VendorIDJD) - if err == nil { - orderFinancial, err2 := CurPurchaseHandler.OrderDetail2Financial(a, orderDetail, true, order) - if err = err2; err == nil { - err = partner.CurOrderManager.SaveOrderFinancialInfo(orderFinancial, peration) - } - } - return err -} diff --git a/business/partner/purchase/jd/financial_test.go b/business/partner/purchase/jd/financial_test.go deleted file mode 100644 index cf93074cc..000000000 --- a/business/partner/purchase/jd/financial_test.go +++ /dev/null @@ -1,17 +0,0 @@ -package jd - -import ( - "fmt" - "testing" - - "git.rosy.net.cn/baseapi/platformapi/jdapi" -) - -func TestOnFinancialMsg(t *testing.T) { - msg := &jdapi.CallbackOrderMsg{ - BillID: "907315020000322", - StatusID: "330902", - } - res := CurPurchaseHandler.onFinancialMsg(msg) - fmt.Println(res) -} diff --git a/business/partner/purchase/jd/jd.go b/business/partner/purchase/jd/jd.go deleted file mode 100644 index c463e2f95..000000000 --- a/business/partner/purchase/jd/jd.go +++ /dev/null @@ -1,86 +0,0 @@ -package jd - -import ( - "git.rosy.net.cn/baseapi/platformapi/jdapi" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" -) - -type PurchaseHandler struct { - partner.BasePurchasePlatform -} - -var ( - CurPurchaseHandler *PurchaseHandler -) - -func init() { - globals.SugarLogger.Debug("init jd") - CurPurchaseHandler = new(PurchaseHandler) - partner.RegisterPurchasePlatform(CurPurchaseHandler) -} - -func getAPI(appOrgCode string) (apiObj *jdapi.API) { - if appOrgCode == "" { - globals.SugarLogger.Warnf("getAPI appOrgCode is empty") - } - return partner.CurAPIManager.GetAPI(model.VendorIDJD, appOrgCode).(*jdapi.API) -} - -func GetAPI(appOrgCode string) (apiObj *jdapi.API) { - return getAPI(appOrgCode) -} - -func AppKey2OrgCode(appKey string) (vendorOrgCode string) { - apiList := partner.CurAPIManager.GetAppOrgCodeList(model.VendorIDJD) - for _, v := range apiList { - jdAPI := partner.CurAPIManager.GetAPI(model.VendorIDJD, v).(*jdapi.API) - if jdAPI.GetAppKey() == appKey { - vendorOrgCode = v - break - } - } - if vendorOrgCode == "" { - globals.SugarLogger.Warnf("AppKey2OrgCode appKey:%s get empty vendorOrgCode", appKey) - } - return vendorOrgCode -} - -func (c *PurchaseHandler) GetVendorID() int { - return model.VendorIDJD -} - -func JdOperationTime2JxOperationTime(value1 int) int16 { - value := int16(value1) - return (value/2)*100 + (value%2)*30 -} - -func JxOperationTime2JdOperationTime(value int16) int16 { - return (value/100)*2 + (value%100)/30 -} - -func JdStoreStatus2JxStatus(yn, closeStatus int) int { - if yn == 1 { - return model.StoreStatusDisabled - } else if closeStatus == 1 { - return model.StoreStatusClosed - } - return model.StoreStatusOpened -} - -func JxStoreStatus2JdStatus(status int) (yn, closeStatus int) { - switch status { - case model.StoreStatusDisabled: - return 1, 1 - case model.StoreStatusHaveRest, model.StoreStatusClosed: - return 0, 1 - default: - return 0, 0 - } -} - -func (p *PurchaseHandler) UploadImg(ctx *jxcontext.Context, vendorOrgCode, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) { - return imgHint, err -} diff --git a/business/partner/purchase/jd/jd_test.go b/business/partner/purchase/jd/jd_test.go deleted file mode 100644 index fc850f98c..000000000 --- a/business/partner/purchase/jd/jd_test.go +++ /dev/null @@ -1,11 +0,0 @@ -package jd - -import ( - _ "git.rosy.net.cn/jx-callback/globals/api/apimanager" - - "git.rosy.net.cn/jx-callback/globals/testinit" -) - -func init() { - testinit.Init() -} diff --git a/business/partner/purchase/jd/net_spider_test.go b/business/partner/purchase/jd/net_spider_test.go deleted file mode 100644 index fdd9350f9..000000000 --- a/business/partner/purchase/jd/net_spider_test.go +++ /dev/null @@ -1 +0,0 @@ -package jd diff --git a/business/partner/purchase/jd/order.go b/business/partner/purchase/jd/order.go deleted file mode 100644 index 7bcb7d284..000000000 --- a/business/partner/purchase/jd/order.go +++ /dev/null @@ -1,617 +0,0 @@ -package jd - -import ( - "fmt" - "regexp" - "strings" - "time" - - "git.rosy.net.cn/jx-callback/business/jxutils/weixinmsg" - - "git.rosy.net.cn/jx-callback/business/model/dao" - - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - - "git.rosy.net.cn/baseapi/platformapi/autonavi" - "git.rosy.net.cn/baseapi/platformapi/jdapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -var ( - VendorStatus2StatusMap = map[string]int{ - jdapi.OrderStatusPurchased: model.OrderStatusNew, - jdapi.OrderStatusWaitOutStore: model.OrderStatusAccepted, - jdapi.StatusIDWaitOutStore: model.OrderStatusAccepted, - jdapi.OrderStatusFinishedPickup: model.OrderStatusFinishedPickup, - jdapi.OrderStatusDelivering: model.OrderStatusDelivering, - jdapi.OrderStatusDelivered: model.OrderStatusFinished, - jdapi.OrderStatusFinished: model.OrderStatusFinished, // todo 这个状态不是真正都完成的意思? - jdapi.OrderStatusCanceled: model.OrderStatusCanceled, - - jdapi.OrderStatusAdjust: model.OrderStatusAdjust, - jdapi.OrderStatusUserApplyCancel: model.OrderStatusApplyCancel, - jdapi.OrderStatusLocked: model.OrderStatusLocked, - jdapi.OrderStatusUnlocked: model.OrderStatusUnlocked, - - jdapi.OrderStatusVenderAgreeCancel: model.OrderStatusVendorAgreeCancel, - jdapi.OrderStatusVenderRejectCancel: model.OrderStatusVendorRejectCancel, - jdapi.CallbackMsgOrderAddTips: model.OrderStatusWaybillTipChanged, - } - deliveryTypeMap = map[int]string{ - jdapi.CarrierNoCrowdSourcing: model.OrderDeliveryTypePlatform, - jdapi.CarrierNoSelfDelivery: model.OrderDeliveryTypeStoreSelf, - jdapi.CarrierNoSelfTake: model.OrderDeliveryTypeSelfTake, - } - - selfTakeCodeReg = regexp.MustCompile(`等待用户凭提货码(\d+)于`) - - afsMsgMap = map[string]bool{ - jdapi.CallbackMsgNewApplyAfterSaleBill: true, - jdapi.CallbackMsgUpdateApplyAfterSaleBill: true, - jdapi.CallbackMsgNewAfterSaleBill: true, - jdapi.CallbackMsgAfterSaleBillStatus: true, - } -) - -func (c *PurchaseHandler) OnOrderMsg(vendorOrgCode string, msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { - jxutils.CallMsgHandler(func() { - retVal = c.onOrderMsg(vendorOrgCode, msg) - }, jxutils.ComposeUniversalOrderID(msg.BillID, model.VendorIDJD)) - return retVal -} - -func (c *PurchaseHandler) updateOrderFinancialInfo(a *jdapi.API, orderID string) (err error) { - order := &model.GoodsOrder{ - VendorOrderID: orderID, - VendorID: model.VendorIDJD, - } - orderSettlement, err := a.OrderShoudSettlementService2(orderID) - if err == nil { - if orderSettlement != nil { - updateOrderBySettleMent(order, orderSettlement) - globals.SugarLogger.Debugf("updateOrderBySettleMent: %v , %v", order.NewEarningPrice, order.TotalShopMoney) - err = partner.CurOrderManager.UpdateOrderFields(order, []string{ /*"WaybillTipMoney", */ "TotalShopMoney", "PmSubsidyMoney", "NewEarningPrice"}) - } - } - return err -} - -func (c *PurchaseHandler) onOrderMsg(vendorOrgCode string, msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { - a := getAPI(vendorOrgCode) - if afsMsgMap[msg.MsgURL] { - retVal = c.OnAfsOrderMsg(a, msg) - } else { - status := c.callbackMsg2Status(msg) - if jdapi.StatusIDNewOrder == msg.StatusID { - status.Status = model.OrderStatusNew // 因为京东将事件32000与状态32000混用,事件32000可能是新订单,也可能是已接单,统一当成新订单处理 - } - if partner.CurOrderManager.GetStatusDuplicatedCount(status) > 0 { - return nil - } - if msg.MsgURL == jdapi.CallbackMsgOrderAccounting { - retVal = c.OnFinancialMsg(msg) - retVal = jdapi.Err2CallbackResponse(c.updateOrderFinancialInfo(a, msg.BillID), status.VendorStatus) - } else { - // 新订单事件,与订单状态有点冲突 - if jdapi.StatusIDNewOrder == msg.StatusID { - retVal = c.onOrderNew(a, msg, status) - } else if jdapi.OrderStatusAdjust == msg.StatusID { - retVal = c.onOrderAdjust(a, msg, status) - } else { - if msg.StatusID == jdapi.OrderStatusAddComment || msg.StatusID == jdapi.OrderStatusModifyComment { - utils.CallFuncAsync(func() { - c.onOrderComment2(a, msg) - }) - } - // if msg.StatusID == jdapi.OrderStatusVenderAgreeCancel { - // order := &model.GoodsOrder{ - // VendorOrgCode: vendorOrgCode, - // VendorOrderID: msg.BillID, - // } - // err2 := c.PickupGoods(order, false, jxcontext.AdminCtx.GetUserName()) - // if err2 != nil { - // globals.SugarLogger.Warnf("京东取消拣货:%v", err2) - // } - // } - err := partner.CurOrderManager.OnOrderStatusChanged(vendorOrgCode, status) - retVal = jdapi.Err2CallbackResponse(err, status.VendorStatus) - } - } - } - return retVal -} - -func (c *PurchaseHandler) OnOrderInfoChangeMsg(vendorOrgCode string, msg *jdapi.CallbackOrderInfoChangeMsg) (retVal *jdapi.CallbackResponse) { - jxutils.CallMsgHandler(func() { - retVal = c.onOrderInfoChangeMsg(vendorOrgCode, msg) - }, jxutils.ComposeUniversalOrderID(msg.BillID, model.VendorIDJD)) - return retVal -} - -func (c *PurchaseHandler) onOrderInfoChangeMsg(vendorOrgCode string, msg *jdapi.CallbackOrderInfoChangeMsg) (retVal *jdapi.CallbackResponse) { - db := dao.GetDB() - order, err := dao.GetSimpleOrder(db, msg.BillID) - if err == nil { - globals.SugarLogger.Debugf("onOrderInfoChangeMsg msg:%v", utils.Format4Output(msg, false)) - if msg.BuyerFullAddress != "" { - order.ConsigneeAddress = msg.BuyerFullAddress - } - if msg.BuyerFullName != "" { - order.ConsigneeName = msg.BuyerFullName - } - if msg.BuyerMobile != "" { - order.ConsigneeMobile = msg.BuyerMobile - } - if msg.BuyerLat != "" { - order.ConsigneeLat = jxutils.StandardCoordinate2Int(utils.Str2Float64(msg.BuyerLat)) - } - if msg.BuyerLng != "" { - order.ConsigneeLng = jxutils.StandardCoordinate2Int(utils.Str2Float64(msg.BuyerLng)) - } - if msg.OrderBuyerRemark != "" { - order.BuyerComment = msg.OrderBuyerRemark - } - _, err = dao.UpdateEntity(db, order, "ConsigneeAddress", "ConsigneeName", "ConsigneeMobile", "ConsigneeLat", "ConsigneeLng", "BuyerComment") - weixinmsg.NotifyOrderChanged(order) - } - return jdapi.SuccessResponse -} - -func updateOrderBySettleMent(order *model.GoodsOrder, orderSettlement *jdapi.OrderSettlementInfo) { - if orderSettlement != nil { - order.TotalShopMoney = orderSettlement.SettlementAmount - order.PmSubsidyMoney = orderSettlement.PlatOrderGoodsDiscountMoney + orderSettlement.PlatSkuGoodsDiscountMoney - if order.TotalShopMoney > 0 { - if jxutils.GetSaleStoreIDFromOrder(order) != 0 { - storeDetail, err := partner.CurOrderManager.LoadStoreDetail(jxutils.GetSaleStoreIDFromOrder(order), order.VendorID) - if storeDetail != nil && err == nil { - jxutils.RefreshOrderEarningPrice2(order, storeDetail.PayPercentage) - } - } else { - order2, err := partner.CurOrderManager.LoadOrder(order.VendorOrderID, order.VendorID) - if order2 != nil && err == nil { - storeDetail, err := partner.CurOrderManager.LoadStoreDetail(jxutils.GetSaleStoreIDFromOrder(order2), order.VendorID) - if storeDetail != nil && err == nil { - jxutils.RefreshOrderEarningPrice2(order, storeDetail.PayPercentage) - } - } - } - } else { - order.NewEarningPrice = order.EarningPrice - } - } -} - -func (c *PurchaseHandler) getOrder(a *jdapi.API, orderID string) (order *model.GoodsOrder, orderMap map[string]interface{}, err error) { - globals.SugarLogger.Debugf("jd getOrder orderID:%s", orderID) - var ( - realMobile string - orderSettlement *jdapi.OrderSettlementInfo - ) - task := tasksch.NewParallelTask("jd getOrder", tasksch.NewParallelConfig().SetIsContinueWhenError(true), jxcontext.AdminCtx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - taskIndex := batchItemList[0].(int) - switch taskIndex { - case 0: - orderMap, err = a.QuerySingleOrder(orderID) - if err == nil { - order = c.Map2Order(orderMap) - realMobile, _ = a.GetRealMobile4Order(orderID, order.VendorStoreID) - if realMobile != "" { - order.ConsigneeMobile2 = jxutils.FormalizeMobile(realMobile) - } - } - case 1: - orderSettlement, _ = a.OrderShoudSettlementService2(orderID) - } - return nil, err - }, []int{0, 1}) - task.Run() - _, err = task.GetResult(0) - if order != nil && orderSettlement != nil { - updateOrderBySettleMent(order, orderSettlement) - err = partner.CurOrderManager.UpdateOrderFields(order, []string{"NewEarningPrice"}) - } - return order, orderMap, err -} - -func (c *PurchaseHandler) GetOrder(vendorOrgCode, orderID string) (order *model.GoodsOrder, err error) { - order, _, err = c.getOrder(getAPI(vendorOrgCode), orderID) - return order, err -} - -func (p *PurchaseHandler) GetOrderStatus(vendorOrgCode, vendorOrderID string) (status int, err error) { - order, err := getAPI(vendorOrgCode).QuerySingleOrder2(vendorOrderID) - if err == nil { - status = getStatusFromVendorStatus(utils.Int2Str(order.OrderStatus)) - } - return status, err -} - -func (c *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) { - return Map2Order(orderData) -} - -func Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) { - result := orderData - orderID := utils.Int64ToStr(utils.MustInterface2Int64(result["orderId"])) - globals.SugarLogger.Debugf("jd Map2Order orderID:%s", orderID) - - const defaultStatusTimeField = "orderPurchaseTime" - statusTimeField := defaultStatusTimeField - if result[statusTimeField] == nil { // 814560888003021 orderPurchaseTime为空 - statusTimeField = "orderStartTime" - } - order = &model.GoodsOrder{ - VendorOrderID: orderID, - VendorID: model.VendorIDJD, - VendorStoreID: utils.Interface2String(result["produceStationNo"]), - StoreID: int(utils.Str2Int64WithDefault(utils.Interface2String(result["produceStationNoIsv"]), 0)), - StoreName: utils.Interface2String(result["produceStationName"]), - VendorUserID: utils.Interface2String(result["buyerPin"]), - ConsigneeName: utils.Interface2String(result["buyerFullName"]), - ConsigneeMobile: jxutils.FormalizeMobile(utils.Interface2String(result["buyerMobile"])), - ConsigneeAddress: utils.Interface2String(result["buyerFullAddress"]), - CoordinateType: model.CoordinateTypeMars, - BuyerComment: utils.TrimBlankChar(utils.Interface2String(result["orderBuyerRemark"])), - ExpectedDeliveredTime: utils.Str2TimeWithDefault(utils.Interface2String(result["orderPreEndDeliveryTime"]), utils.DefaultTimeValue), - PickDeadline: utils.Str2TimeWithDefault(utils.Interface2String(result["pickDeadline"]), utils.DefaultTimeValue), // 813951615000022 pickDeadline为空 - VendorStatus: utils.Int64ToStr(utils.MustInterface2Int64(result["orderStatus"])), - OrderSeq: int(utils.MustInterface2Int64(result["orderNum"])), - StatusTime: utils.Str2Time(result[statusTimeField].(string)), - OrderCreatedAt: utils.Str2Time(result[statusTimeField].(string)), - // OrderFinishedAt: utils.Str2Time(result["orderStatusTime"].(string)), - OriginalData: string(utils.MustMarshal(result)), - ActualPayPrice: utils.MustInterface2Int64(result["orderBuyerPayableMoney"]), - BaseFreightMoney: utils.Interface2Int64WithDefault(result["orderBaseFreightMoney"], 0), - DistanceFreightMoney: utils.Interface2Int64WithDefault(result["merchantPaymentDistanceFreightMoney"], 0), - DeliveryType: deliveryTypeMap[int(utils.Str2Int64WithDefault(utils.Interface2String(result["deliveryCarrierNo"]), 0))], - VendorOrgCode: utils.Interface2String(result["orgCode"]), - } - if orderInvoice, ok := result["orderInvoice"].(map[string]interface{}); ok && orderInvoice != nil { - order.InvoiceTitle = utils.Interface2String(orderInvoice["invoiceTitle"]) - order.InvoiceTaxerID = utils.Interface2String(orderInvoice["invoiceDutyNo"]) - order.InvoiceEmail = utils.Interface2String(orderInvoice["invoiceMail"]) - } - order.Status = getStatusFromVendorStatus(order.VendorStatus) - businessTage := utils.Interface2String(result["businessTag"]) - if strings.Index(businessTage, "dj_aging_immediately") >= 0 { - order.BusinessType = model.BusinessTypeImmediate - } else { - order.BusinessType = model.BusinessTypeDingshida - } - coordinateType := utils.Interface2Int64WithDefault(result["buyerCoordType"], 1) - originalLng := utils.MustInterface2Float64(result["buyerLng"]) - originalLat := utils.MustInterface2Float64(result["buyerLat"]) - if coordinateType == 1 { - lng, lat, err2 := api.AutonaviAPI.CoordinateConvert(originalLng, originalLat, autonavi.CoordSysGPS) - if err2 == nil { - originalLng = lng - originalLat = lat - } else { - // 如果没有转成功,保留原始数据 - order.CoordinateType = model.CoordinateTypeGPS - } - } - order.ConsigneeLng = jxutils.StandardCoordinate2Int(originalLng) - order.ConsigneeLat = jxutils.StandardCoordinate2Int(originalLat) - discounts, _ := result["discount"].([]interface{}) - for _, v := range discounts { - discount := v.(map[string]interface{}) - order.DiscountMoney += utils.Interface2Int64WithDefault(discount["discountPrice"], 0) - } - for _, product2 := range result["product"].([]interface{}) { - product := product2.(map[string]interface{}) - sku := &model.OrderSku{ - VendorOrderID: orderID, - VendorID: model.VendorIDJD, - Count: int(utils.MustInterface2Int64(product["skuCount"])), - SkuID: int(utils.Str2Int64WithDefault(utils.Interface2String(product["skuIdIsv"]), 0)), - VendorSkuID: utils.Int64ToStr(utils.MustInterface2Int64(product["skuId"])), - SkuName: product["skuName"].(string), - Weight: jxutils.FloatWeight2Int(float32(utils.MustInterface2Float64(product["skuWeight"]))), - VendorPrice: utils.MustInterface2Int64(product["skuStorePrice"]), - SalePrice: utils.MustInterface2Int64(product["skuJdPrice"]), - } - if jdPromotionType := int(utils.MustInterface2Int64(product["promotionType"])); jdPromotionType != 0 && jdPromotionType != jdapi.PromotionTypeNormal { - sku.StoreSubName = utils.Int2Str(jdPromotionType) - } - if skuCostumeProperty, ok := product["skuCostumeProperty"]; ok { - sku.SkuName += skuCostumeProperty.(string) - } - if isGift, ok := product["isGift"].(bool); ok && isGift { - sku.SkuType = 1 - } - order.Skus = append(order.Skus, sku) - } - jxutils.RefreshOrderSkuRelated(order) - return order -} - -// -func (c *PurchaseHandler) onOrderNew(a *jdapi.API, msg *jdapi.CallbackOrderMsg, orderStatus *model.OrderStatus) (response *jdapi.CallbackResponse) { - globals.SugarLogger.Debugf("onOrderNew orderID:%s", msg.BillID) - order, orderMap, err := c.getOrder(a, msg.BillID) - if err == nil { - globals.SugarLogger.Debugf("onOrderNew2 orderID:%s", msg.BillID) - if err = partner.CurOrderManager.OnOrderNew(order, orderStatus); err == nil { - utils.CallFuncAsync(func() { - c.OnOrderDetail(a, orderMap, partner.CreatedPeration) - }) - } - } - return jdapi.Err2CallbackResponse(err, "jd onOrderNew") -} - -func (c *PurchaseHandler) onOrderAdjust(a *jdapi.API, msg *jdapi.CallbackOrderMsg, orderStatus *model.OrderStatus) *jdapi.CallbackResponse { - order, orderMap, err := c.getOrder(a, msg.BillID) - if err == nil { - err = partner.CurOrderManager.OnOrderAdjust(order, orderStatus) - if err == nil { - utils.CallFuncAsync(func() { - c.OnOrderDetail(a, orderMap, partner.UpdatedPeration) - }) - } - } - return jdapi.Err2CallbackResponse(err, "jd onOrderAdjust") -} - -func (c *PurchaseHandler) callbackMsg2Status(msg *jdapi.CallbackOrderMsg) *model.OrderStatus { - orderStatus := &model.OrderStatus{ - VendorOrderID: msg.BillID, - VendorID: model.VendorIDJD, - OrderType: model.OrderTypeOrder, - RefVendorOrderID: msg.BillID, - RefVendorID: model.VendorIDJD, - VendorStatus: msg.StatusID, - StatusTime: utils.Str2Time(msg.Timestamp), - Remark: msg.Remark, - } - if msg.MsgURL == jdapi.CallbackMsgOrderAddTips { - orderStatus.VendorStatus = jdapi.CallbackMsgOrderAddTips - } - orderStatus.Status = getStatusFromVendorStatus(orderStatus.VendorStatus) - return orderStatus -} - -func (c *PurchaseHandler) postFakeMsg(vendorOrgCode, vendorOrderID, vendorStatus string) { - msg := &jdapi.CallbackOrderMsg{ - CallbackMsg: &jdapi.CallbackMsg{ - AppKey: getAPI(vendorOrgCode).GetAppKey(), - }, - BillID: vendorOrderID, - StatusID: vendorStatus, - Timestamp: utils.Time2Str(time.Now()), - } - utils.CallFuncAsync(func() { - OnOrderMsg(msg) - }) -} - -// IPurchasePlatformHandler -func getStatusFromVendorStatus(vendorStatus string) int { - if status, ok := VendorStatus2StatusMap[vendorStatus]; ok { - return status - } - return model.OrderStatusUnknown -} - -func (c *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) { - globals.SugarLogger.Debugf("jd AcceptOrRefuseOrder orderID:%s, isAcceptIt:%t", order.VendorOrderID, isAcceptIt) - if globals.EnableJdStoreWrite { - err = getAPI(order.VendorOrgCode).OrderAcceptOperate(order.VendorOrderID, isAcceptIt, userName) - if isAcceptIt && err == nil { - c.postFakeMsg(order.VendorOrgCode, order.VendorOrderID, jdapi.StatusIDWaitOutStore) - } - } else { - if isAcceptIt { - c.postFakeMsg(order.VendorOrgCode, order.VendorOrderID, jdapi.StatusIDWaitOutStore) - } else { - - c.postFakeMsg(order.VendorOrgCode, order.VendorOrderID, jdapi.OrderStatusCanceled) - } - } - return err -} - -func (c *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) { - globals.SugarLogger.Debugf("jd PickupGoods orderID:%s, isSelfDelivery:%t", order.VendorOrderID, isSelfDelivery) - if !isSelfDelivery && globals.EnableJdStoreWrite { - _, err = getAPI(order.VendorOrgCode).OrderJDZBDelivery(order.VendorOrderID, userName) - } else { - c.postFakeMsg(order.VendorOrgCode, order.VendorOrderID, jdapi.OrderStatusFinishedPickup) - } - if err == nil { - orderSettlement, _ := getAPI(order.VendorOrgCode).OrderShoudSettlementService2(order.VendorOrderID) - updateOrderBySettleMent(order, orderSettlement) - globals.SugarLogger.Debugf("jd PickupGoods, %v", order.NewEarningPrice) - err = partner.CurOrderManager.UpdateOrderFields(order, []string{"NewEarningPrice"}) - } - return err -} - -func (p *PurchaseHandler) AcceptOrRefuseFailedGetOrder(ctx *jxcontext.Context, order *model.GoodsOrder, isAcceptIt bool) (err error) { - if globals.EnableJdStoreWrite { - err = getAPI(order.VendorOrgCode).ReceiveFailedAudit(order.VendorOrderID, isAcceptIt, ctx.GetUserName(), "") - } - return err -} - -func (p *PurchaseHandler) CallCourier(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 拣货失败后再次招唤平台配送 - if globals.EnableJdStoreWrite { - err = getAPI(order.VendorOrgCode).UrgeDispatching(order.VendorOrderID, ctx.GetUserName()) - } - return err -} - -func (p *PurchaseHandler) ConfirmReceiveGoods(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 投递失败后确认收到退货 - if globals.EnableJdStoreWrite { - err = getAPI(order.VendorOrgCode).ConfirmReceiveGoods(order.VendorOrderID) - } - return err -} - -func (c *PurchaseHandler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) { - globals.SugarLogger.Debugf("jd Swtich2SelfDeliver orderID:%s", order.VendorOrderID) - if globals.EnableJdStoreWrite { - _, err = getAPI(order.VendorOrgCode).ModifySellerDelivery(order.VendorOrderID, userName) - if err != nil { - if errWithCode, ok := err.(*utils.ErrorWithCode); ok && errWithCode.Level() == 1 { - globals.SugarLogger.Infof("Swtich2SelfDeliver failed with error:%v try get current status", err) - if order2, err2 := c.GetOrder(order.VendorOrgCode, order.VendorOrderID); err2 == nil { - var mapData map[string]interface{} - if err2 = utils.UnmarshalUseNumber([]byte(order2.OriginalData), &mapData); err2 == nil { - if utils.Interface2String(mapData["deliveryCarrierNo"]) == "2938" { // 当前已经是自送状态了 - err = nil - } - } - } - } - } - } - return err -} - -func (c *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName string) (err error) { - globals.SugarLogger.Debugf("jd Swtich2SelfDelivered orderID:%s", order.VendorOrderID) - if globals.EnableJdStoreWrite { - _, err = getAPI(order.VendorOrgCode).DeliveryEndOrder(order.VendorOrderID, userName) - } - return err -} - -func (c *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) { - globals.SugarLogger.Debugf("jd SelfDeliverDelivering orderID:%s", order.VendorOrderID) - if globals.EnableJdStoreWrite { - _, err = getAPI(order.VendorOrgCode).OrderSerllerDelivery(order.VendorOrderID, userName) - } - return err -} - -// 京东送达接口都是一样的 -func (c *PurchaseHandler) SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) { - globals.SugarLogger.Debugf("jd SelfDeliverDelivered orderID:%s", order.VendorOrderID) - if globals.EnableJdStoreWrite { - err = c.Swtich2SelfDelivered(order, userName) - } - return err -} - -func (c *PurchaseHandler) GetOrderRealMobile(ctx *jxcontext.Context, order *model.GoodsOrder) (mobile string, err error) { - mobile, err = getAPI(order.VendorOrgCode).GetRealMobile4Order(order.VendorOrderID, order.VendorStoreID) - return mobile, err -} - -func (c *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) { - if globals.EnableJdStoreWrite { - err = getAPI(order.VendorOrgCode).OrderCancelOperate(order.VendorOrderID, isAgree, ctx.GetUserName(), reason) - } - return err -} - -func (c *PurchaseHandler) CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) { - if globals.EnableJdStoreWrite { - err1 := c.Swtich2SelfDeliver(order, ctx.GetUserName()) - if err = getAPI(order.VendorOrgCode).CancelAndRefund(order.VendorOrderID, ctx.GetUserName(), reason); err != nil { - if err1 != nil { - err = fmt.Errorf("取消订单失败,京东取消订单是要先转为自送再处理,转自送失败:%v", err1) - } - } - } - return err -} - -func (c *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) { - order = jxutils.RemoveSkuFromOrder(order, removedSkuList) - var oaosAdjustDTOList []*jdapi.OAOSAdjustDTO - dtoMap := make(map[int]*jdapi.OAOSAdjustDTO) - for _, sku := range order.Skus { - skuID := jxutils.GetSkuIDFromOrderSku(sku) - if dtoMap[skuID] == nil { - dtoMap[skuID] = &jdapi.OAOSAdjustDTO{ - OutSkuID: utils.Int2Str(skuID), - SkuCount: sku.Count, - } - oaosAdjustDTOList = append(oaosAdjustDTOList, dtoMap[skuID]) - } else { - dtoMap[skuID].SkuCount += sku.Count - } - } - if globals.EnableJdStoreWrite { - err = getAPI(order.VendorOrgCode).AdjustOrder(order.VendorOrderID, ctx.GetUserName(), reason, oaosAdjustDTOList) - } - return err -} - -func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, queryDate time.Time, vendorStoreID string) (vendorOrderIDs []string, err error) { - if utils.IsTimeZero(queryDate) { - return nil, fmt.Errorf("queryDate必须指定") - } - fromDate := utils.Time2Date(queryDate) - toDate := fromDate.Add(24*time.Hour - 1) - queryParam := &jdapi.OrderQueryParam{ - OrderPurchaseTimeBegin: utils.Time2Str(fromDate), - OrderPurchaseTimeEnd: utils.Time2Str(toDate), - PageNo: jdapi.AllPage, - } - if vendorStoreID != "" { - queryParam.DeliveryStationNo = vendorStoreID - } - orderList, _, err := getAPI(vendorOrgCode).OrderQuery2(queryParam) - if err == nil { - vendorOrderIDs = make([]string, len(orderList)) - for k, v := range orderList { - vendorOrderIDs[k] = utils.Int64ToStr(v.OrderID) - } - } - return vendorOrderIDs, err -} - -func (c *PurchaseHandler) GetWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2 string) (tipFee int64, err error) { - orderInfo, err := getAPI(vendorOrgCode).QuerySingleOrder2(vendorOrderID) - if err == nil { - tipFee = int64(orderInfo.Tips) - } - return tipFee, err -} - -func (c *PurchaseHandler) UpdateWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2, cityCode string, tipFee int64) (err error) { - curTipFee, err := c.GetWaybillTip(ctx, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2) - if err == nil { - if tipFee2Add := tipFee - curTipFee; tipFee2Add > 0 { - if globals.EnableJdStoreWrite { - err = getAPI(vendorOrgCode).OrderAddTips(vendorOrderID, int(tipFee2Add), ctx.GetUserName()) - } - } - } - return err -} - -func (c *PurchaseHandler) GetSelfTakeCode(ctx *jxcontext.Context, order *model.GoodsOrder) (selfTakeCode string, err error) { - orderTrackList, err := getAPI(order.VendorOrgCode).GetByOrderNoForOaos(order.VendorOrderID) - if err == nil { - for _, v := range orderTrackList { - if v.TagCode == 180 { - searchResult := selfTakeCodeReg.FindStringSubmatch(v.MsgContent) - if searchResult != nil && len(searchResult[1]) > 0 { - selfTakeCode = searchResult[1] - } - break - } - } - } - return selfTakeCode, err -} - -func (c *PurchaseHandler) ConfirmSelfTake(ctx *jxcontext.Context, order *model.GoodsOrder, selfTakeCode string) (err error) { - if globals.EnableJdStoreWrite { - err = getAPI(order.VendorOrgCode).CheckSelfPickCode(selfTakeCode, order.VendorOrderID, ctx.GetUserName()) - } - return err -} diff --git a/business/partner/purchase/jd/order_afs.go b/business/partner/purchase/jd/order_afs.go deleted file mode 100644 index c8695c0ff..000000000 --- a/business/partner/purchase/jd/order_afs.go +++ /dev/null @@ -1,225 +0,0 @@ -package jd - -import ( - "git.rosy.net.cn/baseapi/platformapi/jdapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" -) - -var ( - AfsVendorStatus2StatusMap = map[string]int{ - jdapi.AfsServiceStateWaiting4Audit: model.AfsOrderStatusWait4Approve, // 需要审核 - - jdapi.AfsServiceStateWaiting4CSFeedback: model.AfsOrderStatusNew, - jdapi.AfsServiceStateRefundProcessing: model.AfsOrderStatusNew, - jdapi.AfsServiceStateWaiting4DirectCompensate: model.AfsOrderStatusNew, - jdapi.AfsServiceStateWaiting4ReturnGoods: model.AfsOrderStatusNew, - - jdapi.AfsServiceStateWaiting4MerchantReceiveGoods: model.AfsOrderStatusWait4ReceiveGoods, - - jdapi.AfsServiceStateRefundSuccess: model.AfsOrderStatusFinished, - jdapi.AfsServiceStateSolved: model.AfsOrderStatusFinished, - jdapi.AfsServiceStateDirectCompensateSuccess: model.AfsOrderStatusFinished, - jdapi.AfsServiceStateReturnGoodsSuccess: model.AfsOrderStatusFinished, - - jdapi.AfsServiceStateRefundFailed: model.AfsOrderStatusFailed, - jdapi.AfsServiceStateAuditRefused: model.AfsOrderStatusFailed, - jdapi.AfsServiceStateUserCanceled: model.AfsOrderStatusFailed, - jdapi.AfsServiceStateMerchantFailedReceiveGoods: model.AfsOrderStatusFailed, - jdapi.AfsServiceStateDirectCompensateFailed: model.AfsOrderStatusFailed, - jdapi.AfsServiceStateReturnGoodsFailed: model.AfsOrderStatusFailed, - } - - afsReasonTypeMap = map[int]int8{ - jdapi.AfsReasonTypeGoodsQuality: model.AfsReasonTypeGoodsQuality, - jdapi.AfsReasonTypeWrongGoods: model.AfsReasonTypeWrongGoods, - jdapi.AfsReasonTypeMissingGoods: model.AfsReasonTypeMissingGoods, - jdapi.AfsReasonTypeNoGoods: model.AfsReasonTypeNoGoods, - jdapi.AfsReasonTypeDamagedGoods: model.AfsReasonTypeDamagedGoods, - jdapi.AfsReasonTypeGoodsQuantity: model.AfsReasonTypeGoodsQuantity, - jdapi.AfsReasonTypeGoodsAbsent: model.AfsReasonTypeGoodsAbsent, - jdapi.AfsReasonTypeGoodsSizeNoSame: model.AfsReasonTypeGoodsNoSame, - jdapi.AfsReasonTypeGoodsColorNoSame: model.AfsReasonTypeGoodsNoSame, - jdapi.AfsReasonWrongPurchase: model.AfsReasonWrongPurchase, - jdapi.AfsReasonNotReceivedIntime: model.AfsReasonNotReceivedIntime, - } - afsAppealTypeMap = map[string]int8{ - jdapi.AfsDealTypeRefund: model.AfsAppealTypeRefund, - jdapi.AfsDealTypeReturnGoodsRefund: model.AfsAppealTypeReturnAndRefund, - jdapi.AfsDealTypeDirectCompensate: model.AfsAppealTypeNewGoods, - } - afsApproveTypeMap = map[int]int{ - partner.AfsApproveTypeRefund: jdapi.AfsApproveTypeRefund, - partner.AfsApproveTypeReturnGoods: jdapi.AfsApproveTypeReturnGoods, - partner.AfsApproveTypeRefused: jdapi.AfsApproveTypeRefused, - } -) - -func (c *PurchaseHandler) OnAfsOrderMsg(a *jdapi.API, msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { - jxutils.CallMsgHandlerAsync(func() { - retVal = c.onAfsOrderMsg(a, msg) - }, jxutils.ComposeUniversalOrderID(msg.BillID, model.VendorIDJD)) - return retVal -} - -func (c *PurchaseHandler) onAfsOrderMsg(a *jdapi.API, msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { - afsInfo, err := a.GetAfsService2(msg.BillID) - if err == nil { - status := c.callbackAfsMsg2Status(msg, afsInfo) - if partner.CurOrderManager.GetStatusDuplicatedCount(status) > 0 { - return nil - } - if status.Status == model.AfsOrderStatusWait4Approve || status.Status == model.AfsOrderStatusNew { - afsOrder := c.buildAfsOrder(afsInfo) - err = partner.CurOrderManager.OnAfsOrderNew(afsOrder, status) - } else { - err = partner.CurOrderManager.OnAfsOrderStatusChanged(status) - } - retVal = jdapi.Err2CallbackResponse(err, status.VendorStatus) - } - return retVal -} - -func (c *PurchaseHandler) callbackAfsMsg2Status(msg *jdapi.CallbackOrderMsg, afsInfo *jdapi.AfsServiceResponse) *model.OrderStatus { - orderStatus := &model.OrderStatus{ - VendorOrderID: msg.BillID, // 是售后单ID,不是订单ID,订单ID在RefVendorOrderID中 - VendorID: model.VendorIDJD, - OrderType: model.OrderTypeAfsOrder, - RefVendorOrderID: afsInfo.OrderID, - RefVendorID: model.VendorIDJD, - VendorStatus: msg.StatusID, - Status: c.GetAfsStatusFromVendorStatus(msg.StatusID), - StatusTime: utils.Str2Time(msg.Timestamp), - Remark: msg.Remark, - } - return orderStatus -} - -func (c *PurchaseHandler) GetAfsStatusFromVendorStatus(vendorStatus string) int { - if status, ok := AfsVendorStatus2StatusMap[vendorStatus]; ok { - return status - } - return model.OrderStatusUnknown -} - -func (c *PurchaseHandler) convertAfsReasonType(vendorReasonType int) int8 { - if status, ok := afsReasonTypeMap[vendorReasonType]; ok { - return status - } - return model.AfsReasonNotOthers -} - -func (c *PurchaseHandler) convertAfsAppealType(vendorAppealType string) int8 { - if status, ok := afsAppealTypeMap[vendorAppealType]; ok { - return status - } - globals.SugarLogger.Warnf("jd convertAfsAppealType unknown vendorAppealType:%d", vendorAppealType) - return 0 -} - -func (c *PurchaseHandler) buildAfsOrder(afsInfo *jdapi.AfsServiceResponse) (afsOrder *model.AfsOrder) { - afsOrder = &model.AfsOrder{ - VendorID: model.VendorIDJD, - AfsOrderID: afsInfo.AfsServiceOrder, - VendorOrderID: afsInfo.OrderID, - VendorStoreID: afsInfo.StationID, - StoreID: int(utils.Str2Int64WithDefault(afsInfo.StationNumOutSystem, 0)), - AfsCreatedAt: afsInfo.CreateTime.GoTime(), - FreightUserMoney: afsInfo.OrderFreightMoney, - AfsFreightMoney: afsInfo.AfsFreight, - BoxMoney: afsInfo.PackagingMoney, - TongchengFreightMoney: afsInfo.TongchengFreightMoney, - SkuBoxMoney: afsInfo.MealBoxMoney, - - VendorStatus: utils.Int2Str(afsInfo.AfsServiceState), - VendorReasonType: utils.Int2Str(afsInfo.QuestionTypeCid), - ReasonType: c.convertAfsReasonType(afsInfo.QuestionTypeCid), - ReasonDesc: utils.LimitUTF8StringLen(afsInfo.QuestionDesc, 1024), - ReasonImgList: utils.LimitUTF8StringLen(jdapi.ProcessQuestionPic(afsInfo.QuestionPic), 1024), - VendorAppealType: afsInfo.ApplyDeal, - AppealType: c.convertAfsAppealType(afsInfo.ApplyDeal), - VendorOrgCode: afsInfo.VenderID, - } - afsOrder.Status = c.GetAfsStatusFromVendorStatus(afsOrder.VendorStatus) - - for _, x := range afsInfo.AfsDetailList { - orderSku := &model.OrderSkuFinancial{ - // VendorID: model.VendorIDJD, - // AfsOrderID: afsOrder.AfsOrderID, - // VendorOrderID: afsOrder.VendorOrderID, - // VendorStoreID: afsOrder.VendorStoreID, - // StoreID: afsOrder.StoreID, - // IsAfsOrder: 1, - - Count: x.SkuCount, - // ConfirmTime: afsOrder.AfsCreateAt, - VendorSkuID: utils.Int64ToStr(x.WareID), - SkuID: int(utils.Str2Int64WithDefault(x.SkuIDIsv, 0)), - Name: x.WareName, - UserMoney: x.AfsMoney, - PmSkuSubsidyMoney: x.PlatPayMoney, - } - if x.PromotionType != 0 && x.PromotionType != jdapi.PromotionTypeNormal { - orderSku.StoreSubName = utils.Int2Str(x.PromotionType) - } - afsOrder.PmSkuSubsidyMoney += orderSku.PmSkuSubsidyMoney - orderSku.PmSubsidyMoney += orderSku.PmSkuSubsidyMoney - - for _, y := range x.AfsSkuDiscountList { - orderSku.PmSubsidyMoney += y.PlatPayMoney - } - - afsOrder.SkuUserMoney += orderSku.UserMoney - afsOrder.PmSubsidyMoney += orderSku.PmSubsidyMoney - afsOrder.Skus = append(afsOrder.Skus, orderSku) - } - return afsOrder -} - -// 审核售后单申请 -func (c *PurchaseHandler) AgreeOrRefuseRefund(ctx *jxcontext.Context, order *model.AfsOrder, approveType int, reason string) (err error) { - if globals.EnableJdStoreWrite { - err = getAPI(order.VendorOrgCode).AfsOpenApprove(order.AfsOrderID, afsApproveTypeMap[approveType], reason, ctx.GetUserName()) - } - return err -} - -// 确认收到退货 -func (c *PurchaseHandler) ConfirmReceivedReturnGoods(ctx *jxcontext.Context, order *model.AfsOrder) (err error) { - if globals.EnableJdStoreWrite { - err = getAPI(order.VendorOrgCode).ConfirmReceipt(order.AfsOrderID, ctx.GetUserName()) - } - return err -} - -func orderSkus2AfsSkus(refundSkuList []*model.OrderSku) (list []*jdapi.VenderAfsSkuDTO) { - for _, v := range refundSkuList { - actType := int(utils.Str2Int64WithDefault(v.StoreSubName, 0)) - if actType == 0 { //!(actType == jdapi.PromotionTypeOverflowGiveGift || actType == jdapi.PromotionTypeBuyGiveGift) { - actType = 1 - } - list = append(list, &jdapi.VenderAfsSkuDTO{ - SkuID: utils.Str2Int64(v.VendorSkuID), - SkuCount: v.Count, - PromotionType: actType, - }) - } - return list -} - -// 发起全款退款 -func (c *PurchaseHandler) RefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) { - return c.PartRefundOrder(ctx, order, order.Skus, reason) -} - -// 发起部分退款 -func (c *PurchaseHandler) PartRefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, refundSkuList []*model.OrderSku, reason string) (err error) { - if globals.EnableJdStoreWrite { - _, err = getAPI(order.VendorOrgCode).AfsSubmit(order.VendorOrderID, ctx.GetUserName(), utils.Int2Str(jdapi.AfsReasonTypeWrongGoods), reason, "", order.ConsigneeName, order.ConsigneeMobile, order.ConsigneeAddress, orderSkus2AfsSkus(refundSkuList)) - } - return err -} diff --git a/business/partner/purchase/jd/order_comment.go b/business/partner/purchase/jd/order_comment.go deleted file mode 100644 index ab77a1e2f..000000000 --- a/business/partner/purchase/jd/order_comment.go +++ /dev/null @@ -1,51 +0,0 @@ -package jd - -import ( - "git.rosy.net.cn/baseapi/platformapi/jdapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" -) - -const ( - JDDJ_BAD_COMMENTS_MAX_MODIFY_TIME = 72 // 小时 -) - -func (c *PurchaseHandler) onOrderComment2(a *jdapi.API, msg *jdapi.CallbackOrderMsg) (err error) { - intOrderID := utils.Str2Int64(msg.BillID) - result, err := a.GetCommentByOrderId2(intOrderID) - if err == nil { - globals.SugarLogger.Debugf("onOrderComment comment:%s", utils.Format4Output(result, true)) - orderCommend := &model.OrderComment{ - VendorOrderID: utils.Int64ToStr(result.OrderID), - VendorID: model.VendorIDJD, - UserCommentID: "", - VendorStoreID: utils.Int64ToStr(result.StoreID), - TagList: string(utils.MustMarshal(result.VenderTags)), - Score: int8(result.Score4), - Content: result.Score4Content, - ModifyDuration: JDDJ_BAD_COMMENTS_MAX_MODIFY_TIME, - OriginalMsg: string(utils.MustMarshal(result)), - } - if result.CreateTime != nil { - orderCommend.CommentCreatedAt = result.CreateTime.GoTime() - } - if result.OrgCommentContent != "" { - orderCommend.IsReplied = 1 - } - err = partner.CurOrderManager.OnOrderComments([]*model.OrderComment{orderCommend}) - } - if err != nil { - globals.SugarLogger.Warnf("onOrderComment orderID:%s failed with error:%v", msg.BillID, err) - } - return err -} - -func (c *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, vendorOrgCode string, orderComment *model.OrderComment, replyComment string) (err error) { - if globals.EnableJdStoreWrite { - err = getAPI(vendorOrgCode).OrgReplyComment(utils.Str2Int64(orderComment.VendorOrderID), orderComment.VendorStoreID, replyComment, ctx.GetUserName()) - } - return err -} diff --git a/business/partner/purchase/jd/order_test.go b/business/partner/purchase/jd/order_test.go deleted file mode 100644 index 34aa07ea9..000000000 --- a/business/partner/purchase/jd/order_test.go +++ /dev/null @@ -1,61 +0,0 @@ -package jd - -import ( - "testing" - "time" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - - _ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" -) - -func TestSwitch2SelfDeliver(t *testing.T) { - orderID := "817540316000041" - if order, err := partner.CurOrderManager.LoadOrder(orderID, model.VendorIDJD); err == nil { - // globals.SugarLogger.Debug(order) - if err = CurPurchaseHandler.Swtich2SelfDeliver(order, ""); err == nil { - } else { - t.Fatal(err.Error()) - } - } else { - t.Fatal(err.Error()) - } -} - -func TestGetOrder(t *testing.T) { - _, err := CurPurchaseHandler.GetOrder("", "815536199000222") - if err != nil { - t.Fatal(err.Error()) - } -} - -func TestGetOrderStatus(t *testing.T) { - status, err := CurPurchaseHandler.GetOrderStatus("", "929203144000041") - if err != nil { - t.Fatal(err.Error()) - } - t.Log(status) -} - -func TestListOrders(t *testing.T) { - result, err := CurPurchaseHandler.ListOrders(jxcontext.AdminCtx, "", nil, time.Now(), "") - if err != nil { - t.Fatal(err.Error()) - } - t.Log(utils.Format4Output(result, false)) -} - -func TestGetSelfTakeCode(t *testing.T) { - order, err := partner.CurOrderManager.LoadOrder("921160248000222", model.VendorIDJD) - if err != nil { - t.Fatal(err) - } - selfTakeCode, err := CurPurchaseHandler.GetSelfTakeCode(jxcontext.AdminCtx, order) - if err != nil { - t.Fatal(err.Error()) - } - t.Log(selfTakeCode) -} diff --git a/business/partner/purchase/jd/sku.go b/business/partner/purchase/jd/sku.go deleted file mode 100644 index 5643a4c7b..000000000 --- a/business/partner/purchase/jd/sku.go +++ /dev/null @@ -1,480 +0,0 @@ -package jd - -// 这里函数取得的信息,除了与自身实体相关的ID(比如PARENT ID),都已经转换成了本地ID了 - -// type tSkuInfoExt struct { -// model.SkuName -// JdCatID int64 `orm:"column(jd_cat_id)"` // 商家类别 -// JdCategoryID int `orm:"column(jd_category_id)"` // 到家类别 -// SkuCatID int64 `orm:"column(sku_cat_id)"` // 商家特殊类别 -// Comment string `orm:"size(255)" json:"comment"` -// } - -// var ( -// skuAddParamsKeyMap = map[string]int{ -// jdapi.KeyUpcCode: 1, -// } -// ) - -// func (p *PurchaseHandler) CreateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) (err error) { -// var jdPid int64 -// if cat.ParentID != 0 { -// pCat := &model.SkuCategory{} -// pCat.ID = cat.ParentID -// if err = dao.GetEntity(db, pCat); err == nil { -// jdPid = pCat.JdID -// } else { -// return err -// } -// } -// if globals.EnableJdStoreWrite { -// result, err2 := getAPI("").AddShopCategory(jdPid, cat.Name, int(cat.Level), cat.Seq, userName) -// if err = err2; err == nil { -// if jdID := utils.Str2Int64WithDefault(result, 0); jdID != 0 { -// cat.JdID = jdID -// } -// } -// } else { -// cat.JdID = jxutils.GenFakeID() -// } -// return err -// } - -// func (p *PurchaseHandler) UpdateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) error { -// if globals.EnableJdStoreWrite { -// return getAPI("").UpdateShopCategory(cat.JdID, cat.Name) -// } -// return nil -// } - -// func (p *PurchaseHandler) DeleteCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) error { -// if globals.EnableJdStoreWrite { -// return getAPI("").DelShopCategory(cat.JdID) -// } -// return nil -// } - -// func (p *PurchaseHandler) ReorderCategories(db *dao.DaoDB, parentCatID int, userName string) (err error) { -// var parentJDID int64 -// if parentCatID != 0 { -// cat := &model.SkuCategory{} -// cat.ID = parentCatID -// if err = dao.GetEntity(db, cat); err != nil { -// return err -// } -// parentJDID = cat.JdID -// } -// var cats []*model.SkuCategory -// if err = dao.GetRows(db, &cats, ` -// SELECT * -// FROM sku_category -// WHERE parent_id = ? AND deleted_at = ? -// ORDER BY seq`, parentCatID, utils.DefaultTimeValue); err == nil { -// jdCatIDs := make([]int64, len(cats)) -// for k, v := range cats { -// jdCatIDs[k] = v.JdID -// } -// if globals.EnableJdStoreWrite { -// err = getAPI("").ChangeShopCategoryOrder(parentJDID, jdCatIDs) -// } -// } -// return err -// } - -// func (p *PurchaseHandler) cuSku(db *dao.DaoDB, sku *model.Sku, handler func(skuExt *tSkuInfoExt, price int, skuName string, shopCategories []int64, addParams map[string]interface{}) (string, error)) (err error) { -// var skuInfoExt tSkuInfoExt -// err = dao.GetRow(nil, &skuInfoExt, ` -// SELECT -// t2.*, IF(t2.jd_category_id > 0, t2.jd_category_id, t3.jd_category_id) jd_category_id, -// t3.jd_id jd_cat_id, -// t4.jd_id sku_cat_id -// FROM sku t1 -// JOIN sku_name t2 ON t1.name_id = t2.id -// JOIN sku_category t3 ON t2.category_id = t3.id -// LEFT JOIN sku_category t4 ON t1.category_id = t4.id -// WHERE t1.id = ? -// `, sku.ID) -// if err == nil { -// shopCategories := []int64{skuInfoExt.JdCatID} -// // SPU只支持SPU的商家分类,不支持单独SKU的,去除SKU的分类 -// // if skuInfoExt.SkuCatID != 0 { -// // shopCategories = append(shopCategories, skuInfoExt.SkuCatID) -// // } -// if skuInfoExt.JdCategoryID == 0 { -// skuInfoExt.JdCategoryID = getDefJdCategoryID() -// } -// if skuInfoExt.BrandID == 0 { -// skuInfoExt.BrandID = DefBrandID -// } -// addParams := map[string]interface{}{} - -// if skuInfoExt.IsGlobal == 0 { //如果不是全国可售,要查可售区域 -// sellPlaces, err2 := dao.GetSellCities(db, skuInfoExt.ID, model.VendorIDJD) -// if err = err2; err == nil && len(sellPlaces) > 0 { -// sellCites := make([]int, len(sellPlaces)) -// for k, v := range sellPlaces { -// sellCites[k] = v.JdCode -// } -// addParams["sellCities"] = sellCites -// } -// } -// if addParams["sellCities"] == nil { -// addParams["sellCities"] = []int{0} -// } -// if skuInfoExt.DescImg != "" { -// addParams[jdapi.KeyProductDesc] = fmt.Sprintf(`一张图片`, skuInfoExt.DescImg) -// addParams[jdapi.KeyIfViewDesc] = 0 -// } else { -// addParams[jdapi.KeyIfViewDesc] = 1 -// } -// if err == nil { -// skuName := jxutils.ComposeSkuName(skuInfoExt.Prefix, skuInfoExt.Name, sku.Comment, skuInfoExt.Unit, sku.SpecQuality, sku.SpecUnit, jdapi.MaxSkuNameCharCount) -// skuPrice := jxutils.CaculateSkuPrice(skuInfoExt.Price, sku.SpecQuality, sku.SpecUnit, skuInfoExt.Unit) -// if skuInfoExt.Upc != "" { -// addParams[jdapi.KeyUpcCode] = skuInfoExt.Upc -// } -// result, err2 := handler(&skuInfoExt, skuPrice, skuName, shopCategories, addParams) -// if err = err2; err == nil { -// if jdID := utils.Str2Int64WithDefault(result, 0); jdID != 0 { -// sku.JdID = jdID -// } -// } -// } -// } -// return err -// } - -// func (p *PurchaseHandler) CreateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) { -// return p.cuSku(db, sku, func(skuExt *tSkuInfoExt, price int, skuName string, shopCategories []int64, addParams map[string]interface{}) (vendorSkuID string, err error) { -// if skuExt.IsSpu == 0 { -// if globals.EnableJdStoreWrite { -// vendorSkuID, err = getAPI("").AddSku(utils.Int2Str(sku.ID), skuExt.JdCategoryID, shopCategories, skuExt.BrandID, skuName, price, jxutils.IntWeight2Float(sku.Weight), jxutils.BatchString2Slice(skuExt.Img, skuExt.Img2), jxStatus2jdStatus(sku.Status), true, addParams) -// if err != nil { -// if jdSkuID := jdapi.GetJdSkuIDFromError(err); jdSkuID > 0 { -// vendorSkuID = utils.Int64ToStr(jdSkuID) -// err = nil -// } -// } -// } else { -// vendorSkuID = utils.Int64ToStr(jxutils.GenFakeID()) -// } -// } else { -// vendorSkuID, err = p.syncSkuNameAsSpu(db, sku, skuExt, price, skuName, shopCategories, addParams) -// } -// return vendorSkuID, err -// }) -// } - -// // func (p *PurchaseHandler) ReadSku(ctx *jxcontext.Context, vendorOrgCode, vendorSkuID string) (skuNameExt *model.SkuNameExt, err error) { -// // jdSkuID := utils.Str2Int64(vendorSkuID) -// // a := getAPI(vendorOrgCode) -// // skuList, _, err := a.QuerySkuInfos(&jdapi.QuerySkuParam{ -// // SkuID: jdSkuID, -// // }) -// // if err == nil { -// // if len(skuList) >= 1 { -// // skuNameExt = &model.SkuNameExt{} -// // if imgList, err2 := a.QueryListBySkuIds(&jdapi.QueryListBySkuIdsParam{ -// // SkuIDs: []int64{jdSkuID}, -// // }); err2 == nil && len(imgList) > 0 { -// // skuNameExt.Img = imgList[0].SourceImgURL -// // } -// // sku := skuList[0] -// // prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(sku.SkuName) -// // if name == "" { -// // name = sku.SkuName -// // unit = "份" -// // specUnit = "g" -// // } -// // skuNameExt.Prefix = prefix -// // skuNameExt.Name = name -// // skuNameExt.Unit = unit -// // skuNameExt.Price = sku.SkuPrice -// // skuNameExt.Skus = []*model.SkuWithVendor{ -// // &model.SkuWithVendor{ -// // Sku: &model.Sku{ -// // SpecQuality: specQuality, -// // SpecUnit: specUnit, -// // Weight: jxutils.FloatWeight2Int(float32(sku.Weight)), -// // JdID: sku.SkuID, -// // Status: jdStatus2jxStatus(sku.FixedStatus), -// // Comment: comment, -// // }, -// // }, -// // } -// // skuNameExt.Skus[0].ID = int(utils.Str2Int64(sku.OutSkuID)) - -// // db := dao.GetDB() -// // shopCategories := sku.ShopCategories -// // if len(shopCategories) > 0 { -// // skuCat := &model.SkuCategory{} -// // skuCat.JdID = shopCategories[0] -// // if dao.GetEntity(db, skuCat, "JdID") == nil { -// // skuNameExt.CategoryID = skuCat.ID -// // } -// // } -// // sellCities := sku.SellCities -// // for _, v := range sellCities { -// // if v == 0 { -// // skuNameExt.IsGlobal = 1 -// // } -// // } -// // if len(sellCities) == 0 || skuNameExt.IsGlobal == 1 { -// // skuNameExt.IsGlobal = 1 -// // } else { -// // var places []*model.Place -// // if err = dao.GetRows(db, &places, "SELECT * FROM place WHERE jd_code IN ("+dao.GenQuestionMarks(len(sellCities))+") AND level = 2", sellCities); err == nil { -// // skuNameExt.Places = make([]int, len(places)) -// // for k, v := range places { -// // skuNameExt.Places[k] = v.Code -// // } -// // } -// // } -// // } else { -// // err = partner.ErrCanNotFindItem -// // } -// // } -// // return skuNameExt, err -// // } - -// func (p *PurchaseHandler) UpdateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) { -// return p.cuSku(db, sku, func(skuExt *tSkuInfoExt, price int, skuName string, shopCategories []int64, addParams map[string]interface{}) (vendorSkuID string, err error) { -// params := utils.MergeMaps(addParams) -// params[jdapi.KeyCategoryId] = skuExt.JdCategoryID -// params[jdapi.KeyShopCategories] = shopCategories -// params[jdapi.KeyBrandId] = skuExt.BrandID -// params[jdapi.KeySkuName] = skuName -// params[jdapi.KeyWeight] = jxutils.IntWeight2Float(sku.Weight) -// params[jdapi.KeyImages] = jxutils.BatchString2Slice(skuExt.Img, skuExt.Img2) -// params[jdapi.KeyFixedStatus] = jxStatus2jdStatus(sku.Status) -// if skuExt.IsSpu == 0 { -// if globals.EnableJdStoreWrite { -// vendorSkuID, err = getAPI("").UpdateSku(utils.Int2Str(sku.ID), params) -// } -// } else { -// vendorSkuID, err = p.syncSkuNameAsSpu(db, sku, skuExt, price, skuName, shopCategories, addParams) -// } -// return vendorSkuID, err -// }) -// } - -// func (p *PurchaseHandler) DeleteSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) { -// params := map[string]interface{}{ -// jdapi.KeyFixedStatus: jdapi.SkuFixedStatusDeleted, -// } -// sql := ` -// SELECT t2.* -// FROM sku t1 -// JOIN sku_name t2 ON t1.name_id = t2.id -// WHERE t1.id = ? -// ` -// var skuExt tSkuInfoExt -// err = dao.GetRow(db, &skuExt, sql, sku.ID) -// if err == nil { -// if skuExt.IsSpu == 0 { -// if globals.EnableJdStoreWrite { -// _, err = getAPI("").UpdateSku(utils.Int2Str(sku.ID), params) -// } -// } else { -// _, err = p.syncSkuNameAsSpu(db, sku, &skuExt, 0, "", nil, nil) -// } -// } -// return err -// } - -// // func (p *PurchaseHandler) RefreshAllSkusID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) { -// // globals.SugarLogger.Debugf("jd RefreshAllSkusID") - -// // db := dao.GetDB() -// // var skuPairs []*jdapi.SkuIDPair -// // const stepCount = 2 - -// // rootTask := tasksch.NewSeqTask("jd RefreshAllSkusID", ctx, -// // func(rootTask *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { -// // switch step { -// // case 0: -// // err = dao.GetRows(db, &skuPairs, ` -// // SELECT t1.id out_sku_id, t1.jd_id sku_id -// // FROM sku t1 -// // WHERE t1.deleted_at = ? -// // `, utils.DefaultTimeValue) -// // default: -// // taskName := "RefreshAllSkusID update id" -// // if step != stepCount-1 { -// // taskName = "RefreshAllSkusID update uuid" -// // } -// // task1 := tasksch.NewParallelTask(taskName, tasksch.NewParallelConfig().SetIsContinueWhenError(true).SetBatchSize(jdapi.MaxBatchSize4BatchUpdateOutSkuId), ctx, -// // func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { -// // skuPairs := make([]*jdapi.SkuIDPair, len(batchItemList)) -// // for k, v := range batchItemList { -// // pair := v.(*jdapi.SkuIDPair) -// // skuPairs[k] = &jdapi.SkuIDPair{ -// // SkuId: pair.SkuId, -// // OutSkuId: pair.OutSkuId, -// // } -// // if step != stepCount-1 { -// // skuPairs[k].OutSkuId = utils.GetUUID() -// // } -// // } -// // globals.SugarLogger.Debug(utils.Format4Output(skuPairs, false)) -// // if globals.EnableJdStoreWrite { -// // _, err = getAPI("").BatchUpdateOutSkuId(skuPairs) -// // } -// // return nil, err -// // }, skuPairs) -// // rootTask.AddChild(task1).Run() -// // _, err = task1.GetResult(0) -// // } -// // return nil, err -// // }, stepCount) -// // tasksch.HandleTask(rootTask, parentTask, false).Run() -// // if !isAsync { -// // _, err = rootTask.GetResult(0) -// // } -// // return rootTask.ID, err -// // } - -// func splitAddParams(addParams map[string]interface{}) (spuAddParams, skuAddParams map[string]interface{}) { -// if addParams != nil { -// spuAddParams = make(map[string]interface{}) -// skuAddParams = make(map[string]interface{}) -// for key := range addParams { -// if skuAddParamsKeyMap[key] == 1 { -// skuAddParams[key] = addParams[key] -// } else { -// spuAddParams[key] = addParams[key] -// } -// } -// } -// return spuAddParams, skuAddParams -// } - -// // 这个处理JD SPU,补丁形式 -// func (p *PurchaseHandler) syncSkuNameAsSpu(db *dao.DaoDB, sku *model.Sku, skuExt *tSkuInfoExt, price int, skuName string, shopCategories []int64, addParams map[string]interface{}) (vendorSkuID string, err error) { -// // SPU的SKU NAME不需要规格信息 -// skuName = jxutils.ComposeSkuName(skuExt.Prefix, skuExt.Name, sku.Comment, "", 0, "", 0) -// skuNameJdID := skuExt.JdID -// globals.SugarLogger.Debugf("syncSkuNameAsSpu1 sku.id=%d, bareSkuName:%s, skuName:%s, skuNameJdID:%d", sku.ID, skuExt.Name, skuName, skuNameJdID) -// spuAddParams, skuAddParams := splitAddParams(addParams) -// if !jxutils.IsEmptyID(skuNameJdID) && sku.JdSyncStatus&model.SyncFlagDeletedMask != 0 { // 删除SKU -// if globals.EnableJdStoreWrite { -// err = getAPI("").UpdateSkuBaseInfo(utils.Int2Str(skuExt.ID), utils.Int2Str(sku.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusDeleted)) -// } -// } -// if err == nil { -// updateFields := []string{} -// if skuExt.JdSyncStatus&model.SyncFlagDeletedMask != 0 { -// sql := ` -// SELECT COUNT(*) ct -// FROM sku t1 -// WHERE t1.name_id = ? AND (t1.status <> ? OR t1.jd_sync_status <> 0) -// ` -// var count struct { -// Ct int -// } -// if err = dao.GetRow(db, &count, sql, sku.NameID, model.SkuStatusDeleted); err != nil { -// return "", err -// } -// if count.Ct <= 1 && sku.JdSyncStatus&model.SyncFlagDeletedMask != 0 { // 1就是最后删的那个 -// updateFields = append(updateFields, model.FieldJdSyncStatus) -// if globals.EnableJdStoreWrite { -// if err = getAPI("").UpdateSpu(utils.Int2Str(skuExt.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusOffline)); err == nil { -// err = getAPI("").UpdateSpu(utils.Int2Str(skuExt.ID), utils.Params2Map(jdapi.KeyFixedStatus, jdapi.SkuFixedStatusDeleted)) -// } -// } -// } -// } else if skuExt.JdSyncStatus&model.SyncFlagNewMask != 0 && jxutils.IsEmptyID(skuNameJdID) { -// if globals.EnableJdStoreWrite { -// spuName := jxutils.ComposeSpuName(skuExt.Prefix, skuExt.Name, 0) -// skus := []map[string]interface{}{ -// map[string]interface{}{ -// jdapi.KeyOutSkuId: utils.Int2Str(sku.ID), -// jdapi.KeySkuName: skuName, -// jdapi.KeyFixedStatus: jxStatus2jdStatus(sku.Status), -// jdapi.KeySkuPrice: price, -// jdapi.KeyWeight: jxutils.IntWeight2Float(sku.Weight), -// jdapi.KeyIsSale: true, -// jdapi.FakeKeySpecAttr: composeSkuSpec(sku.SpecQuality, sku.SpecUnit, skuExt.Unit), -// }, -// } -// skus[0] = utils.MergeMaps(skus[0], skuAddParams) -// updateFields = append(updateFields, model.FieldJdSyncStatus) -// if globals.EnableJdStoreWrite { -// vendorSpuID, skuPairs, err2 := getAPI("").AddSpu(utils.Int2Str(skuExt.ID), skuExt.JdCategoryID, shopCategories, skuExt.BrandID, spuName, []string{skuExt.Img}, jxStatus2jdStatus(skuExt.Status), spuAddParams, skus) -// if err = err2; err == nil { -// skuExt.JdID = vendorSpuID -// // skuNameJdID = skuExt.JdID // 这个是故意去掉的,这样之后的首次SKU修改操作就会被忽略,下一条语句也就可以不用了 -// // sku.JdSyncStatus &= ^model.SyncFlagNewMask -// vendorSkuID = utils.Int64ToStr(skuPairs[0].SkuId) -// updateFields = append(updateFields, model.FieldJdID) -// } -// } -// } -// } else if skuExt.JdSyncStatus&model.SyncFlagModifiedMask != 0 { -// params := utils.MergeMaps(map[string]interface{}{ -// jdapi.KeySpuName: jxutils.ComposeSpuName(skuExt.Prefix, skuExt.Name, 0), -// jdapi.KeyShopCategories: shopCategories, -// jdapi.KeyCategoryId: skuExt.JdCategoryID, -// jdapi.KeyBrandId: skuExt.BrandID, -// jdapi.KeyImages: []string{skuExt.Img}, -// jdapi.KeyFixedStatus: jxStatus2jdStatus(skuExt.Status), -// }, spuAddParams) -// updateFields = append(updateFields, model.FieldJdSyncStatus) -// if globals.EnableJdStoreWrite { -// err = getAPI("").UpdateSpu(utils.Int2Str(skuExt.ID), params) -// } -// } -// if err == nil { -// if skuExt.JdSyncStatus != 0 && len(updateFields) > 0 { -// skuExt.JdSyncStatus = 0 -// _, err = dao.UpdateEntity(db, &skuExt.SkuName, updateFields...) -// globals.SugarLogger.Debugf("syncSkuNameAsSpu4 sku.id=%d, skuName:%s, skuName:%s", sku.ID, skuExt.Name, utils.Format4Output(&skuExt.SkuName, false)) -// } -// } -// } -// if err == nil && !jxutils.IsEmptyID(skuNameJdID) { -// if sku.JdSyncStatus&model.SyncFlagNewMask != 0 { // 非首次新增SKU -// if globals.EnableJdStoreWrite { -// vendorSkuID2, err2 := getAPI("").AppendSku(utils.Int2Str(skuExt.ID), utils.Int2Str(sku.ID), skuName, price, jxutils.IntWeight2Float(sku.Weight), []string{skuExt.Img}, jxStatus2jdStatus(sku.Status), true, composeSkuSpec(sku.SpecQuality, sku.SpecUnit, skuExt.Unit), skuAddParams) -// if err = err2; err == nil { -// vendorSkuID = utils.Int64ToStr(vendorSkuID2) -// } -// } -// } else if sku.JdSyncStatus&model.SyncFlagModifiedMask != 0 { -// params := make(map[string]interface{}) -// params[jdapi.KeySkuName] = skuName -// params[jdapi.KeyImages] = []string{skuExt.Img} -// params[jdapi.KeyFixedStatus] = jxStatus2jdStatus(sku.Status) -// params[jdapi.KeyWeight] = jxutils.IntWeight2Float(sku.Weight) -// params[jdapi.KeySkuPrice] = price -// if globals.EnableJdStoreWrite { -// err = getAPI("").UpdateSkuBaseInfo(utils.Int2Str(skuExt.ID), utils.Int2Str(sku.ID), utils.MergeMaps(params, skuAddParams)) -// if sku.JdSyncStatus&model.SyncFlagSpecMask != 0 { -// skuIndex := sku.SkuIndex -// if skuIndex > 0 { -// saleAttrValue := composeSkuSpec(sku.SpecQuality, sku.SpecUnit, skuExt.Unit) -// globals.SugarLogger.Debugf("syncSkuNameAsSpu outSuperId:%d, saleAttrId:%d, saleAttrValueId:%d, saleAttrValueName:%s", skuExt.ID, jdapi.SaleAttrIDBase, jdapi.SaleAttrValueIDBase+skuIndex-1, saleAttrValue) -// err = getAPI("").UpdateSpuSaleAttr(utils.Int2Str(skuExt.ID), utils.Int2Str(jdapi.SaleAttrIDBase), "", utils.Int2Str(jdapi.SaleAttrValueIDBase+skuIndex-1), saleAttrValue) -// } -// } -// } -// } -// if err == nil { -// sku.JdSyncStatus = 0 -// } -// } -// return vendorSkuID, err -// } - -// func composeSkuSpec(specQuality float32, specUnit, unit string) string { -// prefix := "" -// if unit == model.SpecialUnit { -// prefix = "约" -// } -// value := prefix + jxutils.ComposeSkuSpec(specQuality, specUnit) -// suffix := "/" + unit -// if utf8.RuneCountInString(value) <= 8-utf8.RuneCountInString(suffix) { -// value += suffix -// } -// return value -// } diff --git a/business/partner/purchase/jd/sku2.go b/business/partner/purchase/jd/sku2.go deleted file mode 100644 index c6593b44a..000000000 --- a/business/partner/purchase/jd/sku2.go +++ /dev/null @@ -1,485 +0,0 @@ -package jd - -import ( - "fmt" - - "git.rosy.net.cn/baseapi/platformapi/jdapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" - "github.com/astaxie/beego" -) - -const ( - DefBrandID = 35247 - - DefJdCategoryID = 20362 - DefJdCategoryID4Jxgy = 22410 // 其他国产水果 -) - -func getDefJdCategoryID() int { - if beego.BConfig.RunMode == "jxgy" { - return DefJdCategoryID4Jxgy - } - return DefJdCategoryID -} - -func jdCat2Jx(jdCat *jdapi.CategoryInfo) (jxCat *partner.BareCategoryInfo) { - return &partner.BareCategoryInfo{ - VendorCatID: utils.Int64ToStr(jdCat.Id), - Level: jdCat.Level, - Name: jdCat.Name, - Seq: jdCat.Sort, - } -} - -func (p *PurchaseHandler) GetAllCategories(ctx *jxcontext.Context, vendorOrgCode string) (cats []*partner.BareCategoryInfo, err error) { - result, err := getAPI(vendorOrgCode).QueryCategoriesByOrgCode() - if err == nil { - catMap := make(map[int64]*partner.BareCategoryInfo) - level := 1 - for { - processedCount := 0 - for _, jdCat := range result { - if jdCat.Level == level { - processedCount++ - jxCat := jdCat2Jx(jdCat) - if level == 1 { - cats = append(cats, jxCat) - } else { - parentCat := catMap[jdCat.ParentId] - if parentCat != nil { - parentCat.Children = append(parentCat.Children, jxCat) - } - } - catMap[jdCat.Id] = jxCat - } - } - if processedCount == 0 { - break - } - level++ - } - } - return cats, err -} - -func (p *PurchaseHandler) CreateCategory2(ctx *jxcontext.Context, cat *dao.SkuStoreCatInfo) (err error) { - globals.SugarLogger.Debugf("CreateCategory2 cat:%s", utils.Format4Output(cat, true)) - parentID := int64(0) - if cat.Level != 1 { - parentID = utils.Str2Int64(cat.ParentVendorCatID) - } - if globals.EnableJdStoreWrite { - result, err2 := getAPI(cat.VendorOrgCode).AddShopCategory(parentID, cat.Name, int(cat.Level), cat.Seq, ctx.GetUserName()) - if err = err2; err == nil { - if jdID := utils.Str2Int64WithDefault(result, 0); jdID != 0 { - cat.VendorCatID = utils.Int64ToStr(jdID) - } - } - } else { - cat.VendorCatID = utils.Int64ToStr(jxutils.GenFakeID()) - } - return err -} - -func (p *PurchaseHandler) UpdateCategory2(ctx *jxcontext.Context, cat *dao.SkuStoreCatInfo) (err error) { - globals.SugarLogger.Debugf("UpdateCategory2 cat:%s", utils.Format4Output(cat, true)) - if globals.EnableJdStoreWrite { - err = getAPI(cat.VendorOrgCode).UpdateShopCategory(utils.Str2Int64(cat.VendorCatID), cat.Name) - } - return err -} - -func (p *PurchaseHandler) DeleteCategory2(ctx *jxcontext.Context, vendorOrgCode, vendorCatID string) (err error) { - globals.SugarLogger.Debugf("DeleteCategory2 vendorOrgCode:%s, vendorCatID:%s", vendorOrgCode, vendorCatID) - if globals.EnableJdStoreWrite { - err = getAPI(vendorOrgCode).DelShopCategory(utils.Str2Int64(vendorCatID)) - } - return err -} - -func (p *PurchaseHandler) ReorderCategories2(ctx *jxcontext.Context, vendorOrgCode, vendorParentCatID string, vendorCatIDList []string) (err error) { - if globals.EnableJdStoreWrite { - err = getAPI(vendorOrgCode).ChangeShopCategoryOrder(utils.Str2Int64WithDefault(vendorParentCatID, 0), utils.StringSlice2Int64(vendorCatIDList)) - } - return err -} - -func (p *PurchaseHandler) getVendorCategories(level int, pid int64) (vendorCats []*model.SkuVendorCategory, err error) { - // 得到平台的分类,不需要指定分账号 - cats, err := api.JdAPI.QueryChildCategoriesForOP(pid) - if err != nil { - return nil, err - } - for _, v := range cats { - if v.Status == 1 { - cat := &model.SkuVendorCategory{ - VendorID: model.VendorIDJD, - Name: v.Name, - Level: level, - VendorCategoryID: utils.Int64ToStr(v.Id), - } - if level > 1 { - cat.ParentID = utils.Int64ToStr(v.ParentId) - if level == 3 { - cat.IsLeaf = 1 - } - } - vendorCats = append(vendorCats, cat) - if level < 3 { - childVendorCats, err2 := p.getVendorCategories(level+1, v.Id) - if err2 == nil && len(childVendorCats) > 0 { - vendorCats = append(vendorCats, childVendorCats...) - } else { - cat.IsLeaf = 1 - } - } - } - } - return vendorCats, nil -} - -func (p *PurchaseHandler) GetVendorCategories(ctx *jxcontext.Context) (vendorCats []*model.SkuVendorCategory, err error) { - vendorCats, err = p.getVendorCategories(1, 0) - return vendorCats, err -} - -func skuInfo2Param(ctx *jxcontext.Context, sku *dao.StoreSkuSyncInfo) (param *jdapi.OpSkuParam) { - param = &jdapi.OpSkuParam{ - TraceID: ctx.GetTrackInfo(), - OutSkuID: utils.Int2Str(sku.SkuID), - ShopCategories: []int64{utils.Str2Int64(sku.VendorCatID)}, - CategoryID: sku.VendorVendorCatID, - BrandID: DefBrandID, - SkuName: utils.LimitUTF8StringLen(sku.SkuName, jdapi.MaxSkuNameCharCount), - SkuPrice: int(sku.Price), - Weight: float64(jxutils.IntWeight2Float(sku.Weight)), - FixedStatus: jxStatus2jdStatus(sku.MergedStatus), - IsSale: jdapi.IsSaleNo, // todo ? - - Upc: sku.Upc, - // Images: jxutils.BatchString2Slice(sku.Img, sku.Img2), - } - if sku.ImgMix != "" { - param.Images = jxutils.BatchString2Slice(sku.ImgMix, sku.Img2) - } else { - param.Images = jxutils.BatchString2Slice(sku.Img, sku.Img2) - } - - if param.CategoryID == 0 { - param.CategoryID = int64(getDefJdCategoryID()) - } - // 京东强制要求upc的商品,如果没有设置upc,自动生成一个假的 - if param.Upc == "" && isSkuMustHaveUpc(sku.Unit, param.CategoryID) { - param.Upc = jxutils.GenFakeUPC(sku.SkuID) - } - if sku.IsGlobal == 0 && len(sku.SellCities) > 0 { - param.SellCities = utils.StringSlice2Int64(sku.SellCities) - } - if sku.DescImg != "" { - param.ProductDesc = fmt.Sprintf(`一张图片`, sku.DescImg) - } - return param -} - -func (p *PurchaseHandler) CreateSku2(ctx *jxcontext.Context, sku *dao.StoreSkuSyncInfo) (err error) { - globals.SugarLogger.Debugf("CreateSku2 sku:%s", utils.Format4Output(sku, true)) - param := skuInfo2Param(ctx, sku) - if globals.EnableJdStoreWrite { - sku.VendorSkuID, err = getAPI(sku.VendorOrgCode).AddSku2(param) - } else { - sku.VendorSkuID = utils.Int64ToStr(jxutils.GenFakeID()) - } - return err -} - -func (p *PurchaseHandler) UpdateSku2(ctx *jxcontext.Context, sku *dao.StoreSkuSyncInfo) (err error) { - globals.SugarLogger.Debugf("UpdateSku2 sku:%s", utils.Format4Output(sku, true)) - param := skuInfo2Param(ctx, sku) - if globals.EnableJdStoreWrite { - _, err = getAPI(sku.VendorOrgCode).UpdateSku2(param) - } - return err -} - -func (p *PurchaseHandler) DeleteSku2(ctx *jxcontext.Context, vendorOrgCode string, sku *partner.StoreSkuInfo) (err error) { - globals.SugarLogger.Debugf("DeleteSku2 vendorOrgCode:%s, sku:%s", vendorOrgCode, utils.Format4Output(sku, true)) - - // 京东到家只能通过商家ID删除SKU,如果没有的话,先绑定,再删除 - if sku.SkuID == 0 { - skuPairList := []*jdapi.SkuIDPair{ - &jdapi.SkuIDPair{ - SkuId: utils.Str2Int64(sku.VendorSkuID), - OutSkuId: sku.VendorSkuID, - }, - } - if globals.EnableJdStoreWrite { - _, err = getAPI(vendorOrgCode).BatchUpdateOutSkuId(skuPairList) - if err != nil { - return err - } - sku.SkuID = int(utils.Str2Int64(sku.VendorSkuID)) - } - } - param := &jdapi.OpSkuParam{ - TraceID: ctx.GetTrackInfo(), - OutSkuID: utils.Int2Str(sku.SkuID), - FixedStatus: jdapi.SkuFixedStatusDeleted, - } - if globals.EnableJdStoreWrite { - _, err = getAPI(vendorOrgCode).UpdateSku2(param) - } - return err -} - -func (p *PurchaseHandler) GetSkus(ctx *jxcontext.Context, vendorOrgCode string, skuID int, vendorSkuID string) (skuNameList []*partner.SkuNameInfo, err error) { - param := &jdapi.QuerySkuParam{ - SkuID: utils.Str2Int64WithDefault(vendorSkuID, 0), - IsFilterDel: jdapi.IsFilterDelTrue, - PageNo: 1, - PageSize: jdapi.MaxSkuIDsCount4QueryListBySkuIds, // 为了同时取图,这个值不要大于jdapi.MaxSkuIDsCount4QueryListBySkuIds - } - for { - skuList, _, err2 := getAPI(vendorOrgCode).QuerySkuInfos(param) - if err = err2; err != nil { - return nil, err - } - if len(skuList) > 0 { - batchSkuNameList := make([]*partner.SkuNameInfo, len(skuList)) - for k, v := range skuList { - batchSkuNameList[k] = vendorSku2Jx(v) - } - setSkuNameListPic(vendorOrgCode, batchSkuNameList) - skuNameList = append(skuNameList, batchSkuNameList...) - } - if len(skuList) < param.PageSize { - break - } - param.PageNo++ - } - return skuNameList, err -} - -func setSkuNameListPic(vendorOrgCode string, skuNameList []*partner.SkuNameInfo) []*partner.SkuNameInfo { - jdSkuIDs := make([]int64, len(skuNameList)) - for k, v := range skuNameList { - jdSkuIDs[k] = utils.Str2Int64(v.SkuList[0].VendorSkuID) - } - - imgMap := make(map[int64]*jdapi.ImgHandleQueryResult) - if imgList, err2 := getAPI(vendorOrgCode).QueryListBySkuIds(&jdapi.QueryListBySkuIdsParam{ - SkuIDs: jdSkuIDs, - }); err2 == nil { - for _, v := range imgList { - if v.ImgType == jdapi.ImgTypeMain { - imgResult := imgMap[v.SkuID] - if imgResult == nil || imgResult.IsMain < v.IsMain { - imgMap[v.SkuID] = v - } - } - } - } - - // 使用扒页面方式获取商品图片 - if false { - var leftJdSkuIDs []int64 - for _, v := range jdSkuIDs { - if imgMap[v] == nil { - leftJdSkuIDs = append(leftJdSkuIDs, v) - } - } - task := tasksch.NewParallelTask("jd setSkuNameListPic", nil, jxcontext.AdminCtx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - jdSkuID := batchItemList[0].(int64) - imgList, err := getAPI(vendorOrgCode).GetSkuPageImageInfo(jdSkuID) - if err == nil && len(imgList) > 0 { - retVal = [][]string{ - []string{utils.Int64ToStr(jdSkuID), imgList[0].Big}, - } - } - return retVal, err - }, leftJdSkuIDs) - task.Run() - if resultList, err := task.GetResult(0); err == nil { - for _, v := range resultList { - strList := v.([]string) - imgMap[utils.Str2Int64(strList[0])] = &jdapi.ImgHandleQueryResult{ - SourceImgURL: strList[1], - } - } - } - } - - // 设置商品图片 - for _, v := range skuNameList { - if imgResult := imgMap[utils.Str2Int64(v.SkuList[0].VendorSkuID)]; imgResult != nil { - v.PictureList = []string{imgResult.SourceImgURL} - } - } - return skuNameList -} - -func vendorSku2Jx(vendorSku *jdapi.SkuMain) (skuName *partner.SkuNameInfo) { - prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(vendorSku.SkuName) - weight := int(vendorSku.Weight * 1000) - if weight <= 0 { - weight = jxutils.FormatSkuWeight(specQuality, specUnit) - } - skuID := int(utils.Str2Int64WithDefault(vendorSku.OutSkuID, 0)) - vendorSkuID := utils.Int64ToStr(vendorSku.SkuID) - skuName = &partner.SkuNameInfo{ - NameID: skuID, - VendorNameID: vendorSkuID, - VendorCatIDList: []string{utils.Int64ToStr(vendorSku.CategoryID)}, - - Prefix: prefix, - Name: name, - Unit: unit, - SkuList: []*partner.SkuInfo{ - &partner.SkuInfo{ - StoreSkuInfo: partner.StoreSkuInfo{ - VendorSkuID: vendorSkuID, - SkuID: skuID, - - VendorPrice: int64(vendorSku.SkuPrice), - Status: jdStatus2jxStatus(vendorSku.FixedStatus), - }, - SkuName: vendorSku.SkuName, - Comment: comment, - SpecQuality: float64(specQuality), - SpecUnit: specUnit, - Weight: weight, - }, - }, - } - return skuName -} - -func jdStatus2jxStatus(jdStatus int) (jxStatus int) { - switch jdStatus { - case jdapi.SkuFixedStatusOnline: - jxStatus = model.SkuStatusNormal - case jdapi.SkuFixedStatusOffline: - jxStatus = model.SkuStatusDontSale - case jdapi.SkuFixedStatusDeleted: - jxStatus = model.SkuStatusDeleted - } - return jxStatus -} - -func jxStatus2jdStatus(jxStatus int) (jdStatus int) { - switch jxStatus { - case model.SkuStatusNormal: - jdStatus = jdapi.SkuFixedStatusOnline - case model.SkuStatusDontSale: - jdStatus = jdapi.SkuFixedStatusOffline - case model.SkuStatusDeleted: - jdStatus = jdapi.SkuFixedStatusDeleted - } - return jdStatus -} - -func isSkuMustHaveUpc(unit string, vendorVendorCatID int64) bool { - return unit != model.SpecialUnit || !upcLessMap[vendorVendorCatID] -} - -var ( - upcLessMap = map[int64]bool{ - 20250: true, - 20252: true, - 20258: true, - 20259: true, - 20261: true, - 20262: true, - 20263: true, - 20264: true, - 20265: true, - 20266: true, - 20267: true, - 22822: true, - 20269: true, - 20270: true, - 20271: true, - 20272: true, - 20273: true, - 20275: true, - 20276: true, - 20277: true, - 20278: true, - 20279: true, - 20281: true, - 20282: true, - 20283: true, - 20285: true, - 20286: true, - 20287: true, - 22821: true, - 20289: true, - 20290: true, - 23018: true, - 20354: true, - 20355: true, - 20357: true, - 20359: true, - 23019: true, - 20294: true, - 20295: true, - 20296: true, - 20297: true, - 20298: true, - 20299: true, - 20300: true, - 20302: true, - 20303: true, - 20304: true, - 22840: true, - 22841: true, - 20317: true, - 20320: true, - 20321: true, - 20323: true, - 20325: true, - 20326: true, - 20328: true, - 20329: true, - 20331: true, - 20335: true, - 20337: true, - 20338: true, - 20339: true, - 22842: true, - 22843: true, - 23020: true, - 20309: true, - 20310: true, - 20311: true, - 20312: true, - 20313: true, - 20314: true, - 20315: true, - 22410: true, - 23050: true, - 20319: true, - 20322: true, - 20330: true, - 20332: true, - 20334: true, - 20336: true, - 20340: true, - 20342: true, - 23049: true, - 20356: true, - 20358: true, - 20360: true, - 20361: true, - 20362: true, - 20364: true, - } -) diff --git a/business/partner/purchase/jd/sku_test.go b/business/partner/purchase/jd/sku_test.go deleted file mode 100644 index d3ced1fdd..000000000 --- a/business/partner/purchase/jd/sku_test.go +++ /dev/null @@ -1,61 +0,0 @@ -package jd - -import ( - "testing" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" -) - -func TestCreateSku(t *testing.T) { - // t.Log(beego.BConfig.RunMode) - skuID := 21741 - sku := &model.Sku{} - sku.ID = skuID - dao.GetEntity(nil, sku) - t.Log(sku) - // err := CurPurchaseHandler.CreateSku(sku) - // if err != nil { - // t.Fatal(err.Error()) - // } -} - -func TestGetAllCategories(t *testing.T) { - result, err := CurPurchaseHandler.GetAllCategories(jxcontext.AdminCtx, "") - if err != nil || len(result) == 0 { - t.Fatal(err.Error()) - } - t.Log(utils.Format4Output(result, false)) -} - -// func TestReadSku(t *testing.T) { -// skuName, err := CurPurchaseHandler.ReadSku(jxcontext.AdminCtx, "", "2005582952") -// t.Log(utils.Format4Output(skuName, false)) -// if err != nil { -// t.Fatal(err.Error()) -// } -// if skuName.Name != "味事达酱香鲜特级酿造酱油" || skuName.Skus[0].SpecUnit != "ml" { -// t.Fatal("ReadSku return data wrong") -// t.Log(string(utils.MustMarshal(skuName))) -// } -// } - -func TestGetVendorCategories(t *testing.T) { - catList, err := CurPurchaseHandler.GetVendorCategories(jxcontext.AdminCtx) - if err != nil { - t.Fatal(err.Error()) - } - t.Log(utils.Format4Output(catList, false)) -} - -func TestGetSkus(t *testing.T) { - skuNameList, err := CurPurchaseHandler.GetSkus(jxcontext.AdminCtx, "", 0, "2023747677") - t.Log(utils.Format4Output(skuNameList, false)) - t.Log(len(skuNameList)) - if err != nil { - t.Fatal(err.Error()) - } -} diff --git a/business/partner/purchase/jd/store.go b/business/partner/purchase/jd/store.go deleted file mode 100644 index 886d5ce63..000000000 --- a/business/partner/purchase/jd/store.go +++ /dev/null @@ -1,520 +0,0 @@ -package jd - -import ( - "fmt" - "strings" - "time" - - "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" - - "git.rosy.net.cn/baseapi/platformapi/jdapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/baseapi/utils/errlist" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/globals/api" -) - -type tJdStoreInfo struct { - model.Store - VendorOrgCode string `orm:"size(32)" json:"vendorOrgCode"` // 同一平台下不同的商户代码,如果只有一个,可以为空 - - FreightDeductionPack string `orm:"size(32)" json:"freightDeductionPack"` // - - JdCityCode int - JdDistrictCode int - JdStoreStatus int - VendorStoreID string `orm:"column(vendor_store_id)"` - RealLastOperator string - SyncStatus int - VendorStoreName string -} - -var ( - specialDistrictMap = map[int]int{ - 13989: 310032, - } -) - -func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string) (*dao.StoreDetail, error) { - a := getAPI(vendorOrgCode) - result, err := a.GetStoreInfoByStationNo2(vendorStoreID) - if err == nil { - retVal := &dao.StoreDetail{ - Store: model.Store{ - Address: result.StationAddress, - OpenTime1: JdOperationTime2JxOperationTime(result.ServiceTimeStart1), - CloseTime1: JdOperationTime2JxOperationTime(result.ServiceTimeEnd1), - OpenTime2: JdOperationTime2JxOperationTime(result.ServiceTimeStart2), - CloseTime2: JdOperationTime2JxOperationTime(result.ServiceTimeEnd2), - Status: JdStoreStatus2JxStatus(int(result.Yn), result.CloseStatus), - Tel1: result.Phone, - }, - } - if result.IsAutoOrder == 0 { - retVal.IsAutoOrder = 1 - } else { - retVal.IsAutoOrder = -1 - } - retVal.OriginalName = result.StationName - _, retVal.Name = jxutils.SplitStoreName(retVal.OriginalName, partner.StoreNameSeparator, globals.StoreName) - retVal.DeliveryType = JdDeliveryType2Jx(result.CarrierNo) - - tel2 := result.Mobile - if tel2 != "" && tel2 != retVal.Tel1 { - retVal.Tel2 = tel2 - } - lng := result.Lng - lat := result.Lat - retVal.Lng = jxutils.StandardCoordinate2Int(lng) - retVal.Lat = jxutils.StandardCoordinate2Int(lat) - - db := dao.GetDB() - cityCode := result.City - if cityCode != 0 { - if place, err2 := dao.GetPlaceByJdCode(db, cityCode); err2 == nil { - if place.Level == model.PlaceLevelCity { - retVal.CityCode = place.Code - retVal.CityName = utils.Interface2String(result.CityName) - districtName := result.CountyName // 京东的市区号码与通用数据完全无法关联,只有通过名字来关联 - if retVal.CityCode != 0 && districtName != "" { - if district, err2 := dao.GetPlaceByName(db, districtName, 3, place.Code); err2 == nil { - retVal.DistrictCode = district.Code - } - } - } else if place.Level == model.PlaceLevelDistrict { - retVal.CityCode = place.ParentCode - retVal.DistrictCode = place.Code - } else { - globals.SugarLogger.Warnf("门店:%s的城市码:%d异常", vendorStoreID, cityCode) - } - } - } - if retVal.DistrictCode == 0 { - retVal.DistrictCode = api.AutonaviAPI.GetCoordinateDistrictCode(lng, lat) - if retVal.CityCode == 0 { - if district, err := dao.GetPlaceByCode(db, retVal.DistrictCode); err == nil { - retVal.CityCode = district.ParentCode - } - } - } - retVal.VendorStoreID = vendorStoreID - retVal.ID = int(utils.Str2Int64WithDefault(result.OutSystemID, 0)) - deliveryRange, err2 := a.GetDeliveryRangeByStationNo2(vendorStoreID) - if err = err2; err == nil { - retVal.DeliveryRangeType = int8(deliveryRange.DeliveryRangeType) - if retVal.DeliveryRangeType == model.DeliveryRangeTypePolygon { - retVal.DeliveryRange = strings.Trim(deliveryRange.DeliveryRange, ";") - } else { - retVal.DeliveryRange = utils.Int2Str(deliveryRange.DeliveryRangeRadius) - } - return retVal, nil - } - } - return nil, err -} - -// stoerIDs为nil表示所有 -func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName string) (err error) { - var stores []*tJdStoreInfo - sql := ` - SELECT - t1.*, city.jd_code jd_city_code, district.jd_code jd_district_code, - t2.status jd_store_status, t2.vendor_store_id, IF(t1.updated_at > t2.updated_at, t1.last_operator, - t2.last_operator) real_last_operator, - t2.sync_status, t2.freight_deduction_pack, t2.vendor_org_code, t2.vendor_store_name - FROM store t1 - JOIN store_map t2 ON t1.id = t2.store_id AND t2.vendor_id = ? AND (t2.deleted_at = ?) - LEFT JOIN place city ON t1.city_code = city.code - LEFT JOIN place district ON t1.district_code = district.code - WHERE t1.id = ? - ORDER BY t2.updated_at - ` - if err = dao.GetRows(db, &stores, sql, model.VendorIDJD, utils.DefaultTimeValue, storeID); err == nil { - for _, store := range stores { - a := getAPI(store.VendorOrgCode) - // phone := "" - // if store.MarketManPhone != "" { - // phone = store.MarketManPhone - // } else { - // phone = model.VendorStoreTel - // } - storeParams := &jdapi.OpStoreParams{ - StationNo: store.VendorStoreID, - Operator: userName, - Phone: store.Tel1, - Mobile: store.Tel1, - } - if store.SyncStatus&model.SyncFlagDeletedMask == 0 { - storeParams.OutSystemID = utils.Int2Str(int(store.ID)) - } else { - storeParams.OutSystemID = store.VendorStoreID - } - if store.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreName) != 0 { - if store.VendorStoreName != "" { - storeParams.StationName = store.VendorStoreName - } else { - storeParams.StationName = jxutils.ComposeStoreName(store.Name, model.VendorIDJD) - } - storeParams.StationName = utils.LimitUTF8StringLen(storeParams.StationName, jdapi.MaxStoreNameLen) - } - if store.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreAddress) != 0 { - storeParams.StationAddress = store.Address - storeParams.CoordinateType = jdapi.CoordinateTypeAutonavi // 一直用高德 - storeParams.Lng = jxutils.IntCoordinate2Standard(store.Lng) - storeParams.Lat = jxutils.IntCoordinate2Standard(store.Lat) - if store.JdCityCode != 0 { - storeParams.City = store.JdCityCode - } - if store.JdDistrictCode != 0 { - storeParams.County = store.JdDistrictCode - //TODO 彭州市做特殊处理 2020-05-25 - if store.JdDistrictCode == 49318 { - storeParams.City = 49318 - storeParams.County = 310045 - } - } - - // storeParams.DeliveryRangeType = store.DeliveryRangeType - // if store.DeliveryRangeType == model.DeliveryRangeTypePolygon { - // storeParams.CoordinatePoints = store.DeliveryRange - // } else { - // storeParams.DeliveryRangeRadius = int(utils.Str2Int64WithDefault(store.DeliveryRange, 0)) - // } - } - if specialDistrictMap[storeParams.County] != 0 { - storeParams.City = storeParams.County - storeParams.County = specialDistrictMap[storeParams.County] - } - storeParams.StoreNotice = store.PromoteInfo - modifyCloseStatus := false - if store.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagDeletedMask|model.SyncFlagStoreStatus) != 0 { - modifyCloseStatus = true - _, storeParams.CloseStatus = JxStoreStatus2JdStatus(jxutils.MergeStoreStatus(store.Status, store.JdStoreStatus)) - } - fillOpTimeParams(storeParams, store.GetOpTimeList()) - // globals.SugarLogger.Debug(utils.Format4Output(storeParams, false)) - errList := errlist.New() - if globals.EnableJdStoreWrite { - errList.AddErr(a.UpdateStoreInfo4Open2(storeParams, modifyCloseStatus)) - } - if store.FreightDeductionPack != "" { - storeDetail, err2 := dao.GetStoreDetail(db, store.ID, model.VendorIDJD) - if err2 == nil { - if storeDetail.FreightDeductionPackObj != nil { - freightParams := &jdapi.UpdateStoreFreightParam{ - StationNo: store.VendorStoreID, - UserPin: userName, - OpenDistanceFreight: true, - StartCharge: int64(storeDetail.FreightDeductionPackObj.StartPrice), - } - if len(storeDetail.FreightDeductionPackObj.FreightDeductionList) > 0 { - for _, v := range storeDetail.FreightDeductionPackObj.FreightDeductionList { - if v.DeductFreight > 0 { - freightParams.FreeFreightInfoList = append(freightParams.FreeFreightInfoList, &jdapi.FreeFreightInfo{ - FullFreeMoney: int64(v.BeginPrice), - FreeType: jdapi.FreightFreeTypePartBase, - FreeMoney: int64(v.DeductFreight), - FreeFreightTimes: []*jdapi.FreeFreightTime{ - &jdapi.FreeFreightTime{ - FreeBeginTime: utils.Time2Str(time.Now()), - FreeEndTime: utils.Time2Str(time.Now().Add(24 * time.Hour * 365 * 2)), - }, - }, - }) - break // 京东只能设置一个满减,之前理解有误 - } - } - } - freightParams.IsFullFree = len(freightParams.FreeFreightInfoList) > 0 - // globals.SugarLogger.Debug(utils.Format4Output(freightParams, false)) - if globals.EnableJdStoreWrite { - errList.AddErr(a.UpdateStoreFreightConfigNew(freightParams)) - } - } - } - } - err = errList.GetErrListAsOne() - } - } - return err -} - -func (p *PurchaseHandler) RefreshAllStoresID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) { - globals.SugarLogger.Debugf("jd RefreshAllStoresID") - const stepCount = 3 - var stores []*tJdStoreInfo - db := dao.GetDB() - rootTask := tasksch.NewSeqTask("jd RefreshAllStoresID", ctx, - func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - switch step { - case 0: - err = dao.GetRows(db, &stores, ` - SELECT t1.*, t2.vendor_store_id - FROM store t1 - JOIN store_map t2 ON t1.id = t2.store_id AND t2.deleted_at = ? AND t2.vendor_id = ? - WHERE t1.deleted_at = ? - `, utils.DefaultTimeValue, model.VendorIDJD, utils.DefaultTimeValue) - default: - taskName := "jd RefreshAllStoresID update outSystemId" - if step != stepCount-1 { - taskName = "jd RefreshAllStoresID update to uuid" - } - task1 := tasksch.NewParallelTask(taskName, nil, ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - store := batchItemList[0].(*tJdStoreInfo) - storeParams := &jdapi.OpStoreParams{ - StationNo: store.VendorStoreID, - Operator: ctx.GetUserName(), - OutSystemID: utils.Int2Str(int(store.ID)), - } - if step != stepCount-1 { - storeParams.OutSystemID = store.VendorStoreID - } - if globals.EnableJdStoreWrite { - err = getAPI(store.VendorOrgCode).UpdateStoreInfo4Open2(storeParams, false) - } - return nil, err - }, stores) - task.AddChild(task1).Run() - _, err = task1.GetResult(0) - } - return nil, err - }, stepCount) - - tasksch.HandleTask(rootTask, parentTask, false).Run() - if !isAsync { - _, err = rootTask.GetResult(0) - } - return rootTask.ID, err -} - -func JdDeliveryType2Jx(deliveryType int) int8 { - if deliveryType == jdapi.CarrierNoSelfDelivery { - return scheduler.StoreDeliveryTypeByStore - } else if deliveryType == jdapi.CarrierNoCrowdSourcing { - return scheduler.StoreDeliveryTypeCrowdSourcing - } - return scheduler.StoreDeliveryTypeByPlatform -} - -func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (storeStatus int, err error) { - result, err := getAPI(vendorOrgCode).GetStoreInfoByStationNo2(vendorStoreID) - if err == nil { - storeStatus = JdStoreStatus2JxStatus(int(result.Yn), result.CloseStatus) - } - return storeStatus, err -} - -// 当前京东的storeCrud消息不会在门店状态改变时发送,所以意义不大,先放在这里 -func (c *PurchaseHandler) OnStoreMsg(vendorOrgCode string, msg *jdapi.CallbackOrderMsg) (response *jdapi.CallbackResponse) { - var err error - // if msg.StatusID == jdapi.StatusIDUpdateStore { - // var storeStatus int - // vendorStoreID := msg.BillID - // if storeStatus, err = c.GetStoreStatus(jxcontext.AdminCtx, vendorStoreID); err == nil { - // err = partner.CurStoreManager.OnStoreStatusChanged(vendorStoreID, model.VendorIDJD, storeStatus) - // } else { - // // 可能在门店删除的情况下会出查不到门店的错误 - // if errExt, ok := err.(*utils.ErrorWithCode); ok && errExt.IntCode() == 4 { - // err = nil - // } - // } - // } - return jdapi.Err2CallbackResponse(err, "") -} - -func (p *PurchaseHandler) EnableAutoAcceptOrder(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, isSetEnable bool) (err error) { - _, err = getAPI(vendorOrgCode).UpdateStoreConfig4Open(vendorStoreID, isSetEnable) - return err -} - -func (c *PurchaseHandler) UpdateStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, status int) (err error) { - _, closeStatus := JxStoreStatus2JdStatus(status) - if globals.EnableJdStoreWrite { - err = getAPI(vendorOrgCode).UpdateStoreInfo4Open2(&jdapi.OpStoreParams{ - StationNo: vendorStoreID, - Operator: ctx.GetUserName(), - CloseStatus: closeStatus, - }, true) - } - return err -} - -func fillOpTimeParams(params *jdapi.OpStoreParams, opTimeList []int16) { - index := 1 - opTimeListLen := len(opTimeList) - if opTimeListLen > 4 { - opTimeListLen = 4 - } - opTimeListLen = opTimeListLen / 2 * 2 - for k := 0; k < len(opTimeList); k += 2 { - if opTimeList[k] != 0 { - if index == 1 { - params.ServiceTimeStart1 = int(JxOperationTime2JdOperationTime(int16(opTimeList[k]))) - params.ServiceTimeEnd1 = int(JxOperationTime2JdOperationTime(int16(opTimeList[k+1]))) - } else { - params.ServiceTimeStart2 = int(JxOperationTime2JdOperationTime(int16(opTimeList[k]))) - params.ServiceTimeEnd2 = int(JxOperationTime2JdOperationTime(int16(opTimeList[k+1]))) - } - } else { - break - } - index++ - } -} - -func (c *PurchaseHandler) UpdateStoreOpTime(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, opTimeList []int16) (err error) { - params := &jdapi.OpStoreParams{ - StationNo: vendorStoreID, - Operator: ctx.GetUserName(), - } - fillOpTimeParams(params, opTimeList) - if globals.EnableJdStoreWrite { - err = getAPI(vendorOrgCode).UpdateStoreInfo4Open2(params, false) - } - return err -} - -func (c *PurchaseHandler) GetAllStoresVendorID(ctx *jxcontext.Context, vendorOrgCode string) (vendorStoreIDs []string, err error) { - vendorStoreIDs, err = getAPI(vendorOrgCode).GetStationsByVenderId() - return vendorStoreIDs, err -} - -func (c *PurchaseHandler) storeUploadImgByURL(vendorOrgCode, inImgURL string) (imgURL string, err error) { - if globals.EnableJdStoreWrite { - if vendorOrgCode == globals.JdOrgCode { - imgURL, err = api.JdPageAPI.StoreUploadImgByURL(inImgURL) - } else { - imgURL, err = getAPI(vendorOrgCode).StoreUploadImgByURL(inImgURL) - } - } else { - imgURL = utils.GetUUID() - } - return imgURL, err -} - -func addStoreInfo2Err(err error, storeID int) error { - if err != nil { - errExt, _ := err.(*utils.ErrorWithCode) - if errExt == nil { - errExt = utils.NewErrorCode(err.Error(), "999") - } - errExt.AddPrefixMsg(fmt.Sprintf("门店%d", storeID)) - err = errExt - } - return err -} - -func (c *PurchaseHandler) SyncQualify(ctx *jxcontext.Context, storeDetail *dao.StoreDetail) (err error) { - if storeDetail.LicenceCode == "" || storeDetail.Licence == "" { - return addStoreInfo2Err(fmt.Errorf("营业执照信息不全"), storeDetail.ID) - } - if storeDetail.IDCode == "" || storeDetail.IDCardFront == "" || storeDetail.IDCardBack == "" || storeDetail.IDValid == "" { - return addStoreInfo2Err(fmt.Errorf("个人信息不全"), storeDetail.ID) - } - var qualifyList []*jdapi.QualifyItem - licenceDetail, err := api.JdPageAPI.GetCorporationInfo(storeDetail.VendorStoreID, storeDetail.LicenceCode) - if err != nil { - return addStoreInfo2Err(err, storeDetail.ID) - } - licenceURL, err := c.storeUploadImgByURL(storeDetail.VendorOrgCode, storeDetail.Licence) - if err != nil { - return addStoreInfo2Err(err, storeDetail.ID) - } - expireStart, err := utils.TryStr2Time(licenceDetail.StartDate) - if err != nil { - return addStoreInfo2Err(fmt.Errorf("执照有效开始时间:%s非法,请手动处理", licenceDetail.StartDate), storeDetail.ID) - } - qualifyList = append(qualifyList, &jdapi.QualifyItem{ - QualifyType: jdapi.QualifyTypeCompany, - QualifyURL: licenceURL, - QualifyExpireStart: utils.Time2Str(expireStart), - QualifyExpireForever: 0, - QualifyName: licenceDetail.OperName, - LicenceType: "-1", - QualifyNumber: storeDetail.LicenceCode, - QualifyAddress: licenceDetail.Address, - LicenceName: licenceDetail.Name, - EconKind: licenceDetail.EconKind, - Scope: licenceDetail.Scope, - }) - - idFrondURL, err := c.storeUploadImgByURL(storeDetail.VendorOrgCode, storeDetail.IDCardFront) - if err != nil { - return addStoreInfo2Err(err, storeDetail.ID) - } - // 个体经营,个体工商户 - if storeDetail.LicenceType == 0 { // 个人 - personQualify := &jdapi.QualifyItem{ - QualifyType: jdapi.QualifyTypePerson, - QualifyURL: idFrondURL, - QualifyExpireStart: utils.Time2Str(utils.Str2Time(storeDetail.IDValid)), - QualifyExpireForever: 0, - - QualifyNumber: storeDetail.IDCode, - QualifyOwner: storeDetail.LicenceOwnerName, - } - if storeDetail.IDExpire != "" { - personQualify.QualifyExpireForever = 1 - personQualify.QualifyExpireEnd = utils.Time2Str(utils.Str2Time(storeDetail.IDExpire)) - } - qualifyList = append(qualifyList, personQualify) - } else { - addInfo := &jdapi.QualifyItem{ - QualifyType: jdapi.QualifyTypeAddInfo, - QualifyURL: idFrondURL, - QualifyExpireStart: utils.Time2Str(utils.Str2Time(storeDetail.IDValid)), - QualifyExpireForever: 0, - } - if storeDetail.IDExpire != "" { - addInfo.QualifyExpireForever = 1 - addInfo.QualifyExpireEnd = utils.Time2Str(utils.Str2Time(storeDetail.IDExpire)) - } - qualifyList = append(qualifyList, addInfo) - } - if storeDetail.IDExpire == "" { - idBackURL, err := c.storeUploadImgByURL(storeDetail.VendorOrgCode, storeDetail.IDCardBack) - if err != nil { - return addStoreInfo2Err(err, storeDetail.ID) - } - qualifyList = append(qualifyList, &jdapi.QualifyItem{ - QualifyType: jdapi.QualifyTypeAddInfo, - QualifyURL: idBackURL, - QualifyExpireStart: utils.Time2Str(utils.Str2Time(storeDetail.IDValid)), - QualifyExpireForever: 0, - }) - } - globals.SugarLogger.Debug(utils.Format4Output(qualifyList, false)) - if globals.EnableJdStoreWrite { - globals.SugarLogger.Debugf("SaveQualifyTest4,[%v]", utils.Format4Output(qualifyList, false)) - err = api.JdPageAPI.SaveQualify(storeDetail.VendorStoreID, jdapi.SaveQualifyActionTypeCommit, qualifyList) - // err = api.JdPageAPI.SaveQualify(storeDetail.VendorStoreID, jdapi.SaveQualifyActionTypeSave, qualifyList) - } - return addStoreInfo2Err(err, storeDetail.ID) -} - -func (c *PurchaseHandler) UpdateStoreCustomID(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string, storeID int64) (err error) { - if globals.EnableJdStoreWrite { - err = getAPI(vendorOrgCode).UpdateStoreInfo4Open2( - &jdapi.OpStoreParams{ - StationNo: vendorStoreID, - Operator: ctx.GetUserName(), - OutSystemID: utils.Int2Str(int(storeID)), - }, false) - } - return err -} - -func (p *PurchaseHandler) CreateStore2(db *dao.DaoDB, storeID int, userName string) (vendorStoreID string, err error) { - return vendorStoreID, err -} - -func (p *PurchaseHandler) DeleteStore(db *dao.DaoDB, storeID int, userName string) (err error) { - return err -} diff --git a/business/partner/purchase/jd/store_sku2.go b/business/partner/purchase/jd/store_sku2.go deleted file mode 100644 index 0cd83d594..000000000 --- a/business/partner/purchase/jd/store_sku2.go +++ /dev/null @@ -1,300 +0,0 @@ -package jd - -import ( - "git.rosy.net.cn/baseapi/platformapi/jdapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/business/partner/putils" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api/apimanager" -) - -func (p *PurchaseHandler) GetStoreSkusBatchSize(funcID int) (batchSize int) { - switch funcID { - case partner.FuncUpdateStoreSkusStock, partner.FuncUpdateStoreSkusStatus, partner.FuncUpdateStoreSkusPrice: - batchSize = jdapi.MaxStoreSkuBatchSize - case partner.FuncCreateActs, partner.FuncCancelActs: - batchSize = 1 - } - return batchSize -} - -func (p *PurchaseHandler) getStoreSkusBareInfoLimitSize(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, storeID int, vendorStoreID string, inStoreSkuList []*partner.StoreSkuInfo) (outStoreSkuList []*partner.StoreSkuInfo, err error) { - var batchSkuInfoList []*jdapi.BaseStockCenterRequest - batchSkuList := partner.BareStoreSkuInfoList(inStoreSkuList).GetVendorSkuIDIntList() - for _, v := range inStoreSkuList { - if !dao.IsVendorThingIDEmpty(v.VendorSkuID) { - batchSkuInfoList = append(batchSkuInfoList, &jdapi.BaseStockCenterRequest{ - StationNo: vendorStoreID, - SkuId: utils.Str2Int64(v.VendorSkuID), - }) - } - } - if len(batchSkuInfoList) > 0 { - var stockInfo []*jdapi.QueryStockResponse - var priceInfo []*jdapi.StorePriceInfo - task := tasksch.NewParallelTask("获取京东到家平台门店商品信息", tasksch.NewParallelConfig().SetParallelCount(2), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - subTaskID := batchItemList[0].(int) - if subTaskID == 0 { - stockInfo, err = getAPI(vendorOrgCode).QueryOpenUseable(batchSkuInfoList) - } else { - priceInfo, err = getAPI(vendorOrgCode).GetStationInfoList(vendorStoreID, batchSkuList) - } - return nil, err - }, []int{0, 1}) - tasksch.HandleTask(task, parentTask, false).Run() - _, err = task.GetResult(0) - if err == nil { - storeSkuMap := putils.StoreSkuList2MapByVendorSkuID(inStoreSkuList) - for _, v := range stockInfo { - sku := storeSkuMap[utils.Int64ToStr(v.SkuID)] - sku.Status = jdStoreSkuStatus2Jx(v.Vendibility) - sku.Stock = v.UsableQty - if sku.Stock > 0 { - outStoreSkuList = append(outStoreSkuList, sku) - } - } - for _, v := range priceInfo { - sku := storeSkuMap[utils.Int64ToStr(v.SkuID)] - sku.VendorPrice = v.Price - } - } - } - return outStoreSkuList, err -} - -func (p *PurchaseHandler) GetStoreSkusBareInfo(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, storeID int, vendorStoreID string, inStoreSkuList []*partner.StoreSkuInfo) (outStoreSkuList []*partner.StoreSkuInfo, err error) { - result, err := putils.FreeBatchStoreSkuInfo("获取门店商品信息", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) { - list, err := p.getStoreSkusBareInfoLimitSize(ctx, vendorOrgCode, task, storeID, vendorStoreID, batchedStoreSkuList) - if err == nil { - result = list - } - return result, len(list), err - }, ctx, parentTask, inStoreSkuList, jdapi.MaxStoreSkuBatchSize, true) - for _, v := range result { - outStoreSkuList = append(outStoreSkuList, v.(*partner.StoreSkuInfo)) - } - return outStoreSkuList, err -} - -func jdStoreSkuStatus2Jx(jdStoreSkuStatus int) (jxSkuStatus int) { - if jdStoreSkuStatus == 0 { - jxSkuStatus = model.SkuStatusNormal - } else { - jxSkuStatus = model.SkuStatusDontSale - } - return jxSkuStatus -} - -func jxStoreSkuStatus2Jd(jxStoreSkuStatus int) (isSale bool) { - return jxStoreSkuStatus == model.SkuStatusNormal -} - -func isErrPartialFailed(err error) bool { - if errExt, ok := err.(*utils.ErrorWithCode); ok && errExt.Code() == jdapi.ResponseInnerCodePartialFailed { - return true - } - return false -} - -func getStrOutSkuIDs(l []*jdapi.StoreSkuBatchUpdateResponse, isSuccess bool) (outSkuIDs []string) { - for _, v := range l { - if isSuccess && jdapi.IsCodeSuccess(v.Code) { - outSkuIDs = append(outSkuIDs, v.OutSkuID) - } else if !isSuccess && !jdapi.IsCodeSuccess(v.Code) { - outSkuIDs = append(outSkuIDs, v.OutSkuID) - } - } - return outSkuIDs -} - -func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (failedList []*partner.StoreSkuInfoWithErr, err error) { - var skuVendibilityList []*jdapi.StockVendibility - jdStatus := jxStoreSkuStatus2Jd(status) - for _, v := range storeSkuList { - skuVendibilityList = append(skuVendibilityList, &jdapi.StockVendibility{ - OutSkuId: utils.Int2Str(v.SkuID), - DoSale: jdStatus, - }) - } - if globals.EnableJdStoreWrite { - var responseList []*jdapi.StoreSkuBatchUpdateResponse - var err2 error - if vendorOrgCode != apimanager.FakeJdOrgCode { - responseList, err2 = getAPI(vendorOrgCode).BatchUpdateVendibility(ctx.GetTrackInfo(), "", vendorStoreID, skuVendibilityList, ctx.GetUserName()) - } else { - responseList, err2 = getAPI(vendorOrgCode).FakeBatchUpdateVendibility(ctx.GetTrackInfo(), "", vendorStoreID, skuVendibilityList, ctx.GetUserName()) - } - if err = err2; err != nil { - failedList = SelectStoreSkuListByResponseList(storeSkuList, responseList, storeID, model.VendorChineseNames[model.VendorIDJD], "更新商品状态") - // successList = putils.UnselectStoreSkuListBySkuIDs(storeSkuList, utils.StringSlice2Int(getStrOutSkuIDs(responseList, false))) - } - } - err = nil - return failedList, err -} - -func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - if len(storeSkuList) == 1 && vendorOrgCode != apimanager.FakeJdOrgCode { - if globals.EnableJdStoreWrite { - _, err = getAPI(vendorOrgCode).UpdateStationPrice(ctx.GetTrackInfo(), utils.Str2Int64WithDefault(storeSkuList[0].VendorSkuID, 0), vendorStoreID, int(storeSkuList[0].VendorPrice)) - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJD], "更新商品价格") - } - } else { - var skuPriceInfoList []*jdapi.SkuPriceInfo - for _, v := range storeSkuList { - skuPriceInfoList = append(skuPriceInfoList, &jdapi.SkuPriceInfo{ - OutSkuId: utils.Int2Str(v.SkuID), - Price: int(v.VendorPrice), - }) - } - if globals.EnableJdStoreWrite { - var responseList []*jdapi.StoreSkuBatchUpdateResponse - var err2 error - if vendorOrgCode != apimanager.FakeJdOrgCode { - responseList, err2 = getAPI(vendorOrgCode).UpdateVendorStationPrice(ctx.GetTrackInfo(), "", vendorStoreID, skuPriceInfoList) - } else { - responseList, err2 = getAPI(vendorOrgCode).FakeUpdateVendorStationPrice(ctx.GetTrackInfo(), "", vendorStoreID, skuPriceInfoList) - } - if err = err2; err != nil { - failedList = SelectStoreSkuListByResponseList(storeSkuList, responseList, storeID, model.VendorChineseNames[model.VendorIDJD], "更新商品价格") - } - } - } - err = nil - return failedList, err -} - -func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - if len(storeSkuList) == 1 && vendorOrgCode != apimanager.FakeJdOrgCode { - if globals.EnableJdStoreWrite { - err = getAPI(vendorOrgCode).UpdateCurrentQty(ctx.GetTrackInfo(), vendorStoreID, utils.Str2Int64WithDefault(storeSkuList[0].VendorSkuID, 0), storeSkuList[0].Stock) - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJD], "更新商品库存") - } - } else { - var skuStockList []*jdapi.SkuStock - for _, v := range storeSkuList { - skuStockList = append(skuStockList, &jdapi.SkuStock{ - OutSkuId: utils.Int2Str(v.SkuID), - StockQty: v.Stock, - }) - } - if globals.EnableJdStoreWrite { - var responseList []*jdapi.StoreSkuBatchUpdateResponse - var err2 error - if vendorOrgCode != apimanager.FakeJdOrgCode { - responseList, err2 = getAPI(vendorOrgCode).BatchUpdateCurrentQtys(ctx.GetTrackInfo(), "", vendorStoreID, skuStockList, ctx.GetUserName()) - } else { - responseList, err2 = getAPI(vendorOrgCode).FakeBatchUpdateCurrentQtys(ctx.GetTrackInfo(), "", vendorStoreID, skuStockList, ctx.GetUserName()) - } - if err = err2; err != nil { - failedList = SelectStoreSkuListByResponseList(storeSkuList, responseList, storeID, model.VendorChineseNames[model.VendorIDJD], "更新商品库存") - // successList = putils.UnselectStoreSkuListBySkuIDs(storeSkuList, utils.StringSlice2Int(getStrOutSkuIDs(responseList, false))) - } - } - } - err = nil - return failedList, err -} - -func (p *PurchaseHandler) SyncStoreProducts(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, storeID int, skuIDs []int, isAsync, isContinueWhenError bool) (hint string, err error) { - globals.SugarLogger.Debugf("jd SyncStoreProducts, storeID:%d", storeID) - db := dao.GetDB() - storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDJD) - if err != nil { - return "", err - } - storeSkuList, err := dao.GetStoreSkus2(db, model.VendorIDJD, storeID, skuIDs, false) - if err != nil { - return "", err - } - task := tasksch.NewParallelTask("SyncStoreProducts京东", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeSku := batchItemList[0].(*dao.StoreSkuSyncInfo) - if storeSku.VendorSkuID != "" && storeSku.StoreSkuStatus == model.SkuStatusNormal { - if globals.EnableJdStoreWrite { - synchronized, err2 := getAPI(vendorOrgCode).SyncProduct(storeDetail.VendorStoreID, storeSku.VendorSkuID) - if err = err2; err == nil && synchronized { - retVal = []int{1} - } - } else { - retVal = []int{1} - } - } - return retVal, err - }, storeSkuList) - tasksch.HandleTask(task, parentTask, true).Run() - if !isAsync { - result, err2 := task.GetResult(0) - if err = err2; err == nil { - hint = utils.Int2Str(len(result)) - } - } else { - hint = task.GetID() - } - return hint, err -} - -//京东api返回 -func SelectStoreSkuListByResponseList(storeSkuList []*partner.StoreSkuInfo, responseList []*jdapi.StoreSkuBatchUpdateResponse, storeID int, vendorName, syncType string) (selectedStoreSkuList []*partner.StoreSkuInfoWithErr) { - responseMap := make(map[string]string) - if len(responseList) > 0 { - for _, v := range responseList { - if v.Code != "0" { - responseMap[v.OutSkuID] = v.Msg - } - } - for _, v := range storeSkuList { - if responseMap[utils.Int2Str(v.SkuID)] != "" { - respFailed := &partner.StoreSkuInfoWithErr{ - StoreSkuInfo: v, - ErrMsg: responseMap[utils.Int2Str(v.SkuID)], - StoreID: storeID, - VendoreName: vendorName, - SyncType: syncType, - } - selectedStoreSkuList = append(selectedStoreSkuList, respFailed) - } - } - } - return selectedStoreSkuList -} - -func (p *PurchaseHandler) CreateStoreSkusAct(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - for _, v := range storeSkuList { - if vendorActID, err2 := createSkuAct(ctx, putils.GetFixDirectDownAct(vendorOrgCode, storeID, v.SkuID), putils.StoreSku2ActStoreSku(model.SyncFlagNewMask, vendorStoreID, []*partner.StoreSkuInfo{v})); err2 != nil { - failedList = append(failedList, &partner.StoreSkuInfoWithErr{ - StoreSkuInfo: v, - VendoreID: model.VendorIDJD, - StoreID: storeID, - ErrMsg: err2.Error(), - }) - } else { - v.VendorActID = vendorActID - } - } - return failedList, err -} - -func (p *PurchaseHandler) CancelActs(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - for _, v := range storeSkuList { - if err2 := cancelSkuAct(ctx, putils.GetFixDirectDownAct(vendorOrgCode, storeID, v.SkuID), v.VendorActID); err2 != nil { - failedList = append(failedList, &partner.StoreSkuInfoWithErr{ - StoreSkuInfo: v, - VendoreID: model.VendorIDJD, - StoreID: storeID, - ErrMsg: err2.Error(), - }) - } - } - return failedList, err -} - -func (p *PurchaseHandler) UpdateStoreSkusSpecTag(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (err error) { - return err -} diff --git a/business/partner/purchase/jd/store_sku2_test.go b/business/partner/purchase/jd/store_sku2_test.go deleted file mode 100644 index 82d780ba4..000000000 --- a/business/partner/purchase/jd/store_sku2_test.go +++ /dev/null @@ -1,40 +0,0 @@ -package jd - -import ( - "testing" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/business/partner/putils" -) - -func TestGetStoreSkusBareInfo(t *testing.T) { - // list := []*partner.StoreSkuInfo{ - // &partner.StoreSkuInfo{ - // SkuID: 2212, - // VendorSkuID: "2019458103", - // }, - // } - // for i := 0; i < 30-1; i++ { - // list = append(list, list[0]) - // } - skuNameList, err := CurPurchaseHandler.GetSkus(jxcontext.AdminCtx, "", 0, "") - if err != nil { - t.Fatal(err) - } - list := putils.StoreSkuFullList2Bare(skuNameList) - - storeSkuList, err := CurPurchaseHandler.GetStoreSkusBareInfo(jxcontext.AdminCtx, "", nil, 2, "11053496", list) - if err != nil { - t.Fatal(err.Error()) - } - var focusedStoreSkuList []*partner.StoreSkuInfo - for _, v := range storeSkuList { - if v.Stock > 0 { - focusedStoreSkuList = append(focusedStoreSkuList, v) - } - } - t.Log(utils.Format4Output(focusedStoreSkuList, false)) - t.Log(len(focusedStoreSkuList)) -} diff --git a/business/partner/purchase/jd/store_test.go b/business/partner/purchase/jd/store_test.go deleted file mode 100644 index 255a03d90..000000000 --- a/business/partner/purchase/jd/store_test.go +++ /dev/null @@ -1,95 +0,0 @@ -package jd - -import ( - "strings" - "testing" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/model/dao" -) - -const ( - TestStoreNo = 100164 - TestJdStoreNo = "11736989" -) - -func TestReadStore(t *testing.T) { - result, err := new(PurchaseHandler).ReadStore(jxcontext.AdminCtx, "", TestJdStoreNo) - if err != nil { - t.Fatal(err.Error()) - } - t.Log(utils.Format4Output(result, false)) -} - -func TestUpdateStore(t *testing.T) { - handler := new(PurchaseHandler) - result, err := handler.ReadStore(jxcontext.AdminCtx, "", TestJdStoreNo) - - // result := &model.Store{} - // result.ID = 100164 - // err := dao.GetEntity(nil, result) - db := dao.GetDB() - if err != nil { - t.Fatal(err.Error()) - } - result.Name += "h" - newName := result.Name - err = handler.UpdateStore(db, TestStoreNo, "autotest") - if err != nil { - t.Fatal(err.Error()) - } - - // same - result, err = handler.ReadStore(jxcontext.AdminCtx, "", TestJdStoreNo) - if result.Name != newName { - t.Fatalf("result is not same, desired newName:%s, newName:%s", newName, result.Name) - } - - // restore - result.Name = strings.Trim(result.Name, "h") - err = handler.UpdateStore(db, TestStoreNo, "autotest") - if err != nil { - t.Fatal(err.Error()) - } -} - -func TestUpdateStore2(t *testing.T) { - handler := new(PurchaseHandler) - - // result := &model.Store{} - // result.ID = 100164 - // err := dao.GetEntity(nil, result) - db := dao.GetDB() - // restore - err := handler.UpdateStore(db, 1, "autotest") - if err != nil { - t.Fatal(err.Error()) - } -} - -// func TestCoordRangeConversion(t *testing.T) { -// jxRange := "108841759,34332892;108842271,34330820;108846013,34331422;108846110,34333189;108847722,34331853;108856703,34331729;108866149,34327507;108873423,34320980;108877737,34312856;108877727,34299624;108870105,34287988;108855137,34290911;108867884,34286298;108858260,34281316;108854162,34283490;108853803,34280145;108846110,34279291;108830587,34282539;108818806,34291500;108814493,34299624;108813596,34308465;108818797,34320980;108830582,34329941;108841759,34332892" -// jdRange := "108.841759,34.332892;108.842271,34.330820;108.846013,34.331422;108.846110,34.333189;108.847722,34.331853;108.856703,34.331729;108.866149,34.327507;108.873423,34.320980;108.877737,34.312856;108.877727,34.299624;108.870105,34.287988;108.855137,34.290911;108.867884,34.286298;108.858260,34.281316;108.854162,34.283490;108.853803,34.280145;108.846110,34.279291;108.830587,34.282539;108.818806,34.291500;108.814493,34.299624;108.813596,34.308465;108.818797,34.320980;108.830582,34.329941;108.841759,34.332892" - -// if JdRange2JxRange(jdRange) != jxRange { -// t.Fatal("result doesn't match") -// } - -// if JxRange2JdRange(jxRange) != jdRange { -// t.Fatal("result doesn't match") -// } -// } - -func TestSyncQualify(t *testing.T) { - storeDetail, err := dao.GetStoreDetail(dao.GetDB(), 102610, model.VendorIDJD) - if err != nil { - t.Fatal(err.Error()) - } - err = CurPurchaseHandler.SyncQualify(jxcontext.AdminCtx, storeDetail) - if err != nil { - t.Fatal(err.Error()) - } -} diff --git a/business/partner/purchase/jd/waybill.go b/business/partner/purchase/jd/waybill.go deleted file mode 100644 index 4b1068f0f..000000000 --- a/business/partner/purchase/jd/waybill.go +++ /dev/null @@ -1,70 +0,0 @@ -package jd - -import ( - "git.rosy.net.cn/baseapi/platformapi/jdapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" -) - -func (c *PurchaseHandler) OnWaybillMsg(vendorOrgCode string, msg *jdapi.CallbackDeliveryStatusMsg) (retVal *jdapi.CallbackResponse) { - jxutils.CallMsgHandler(func() { - retVal = c.onWaybillMsg(vendorOrgCode, msg) - }, jxutils.ComposeUniversalOrderID(msg.OrderID, model.VendorIDJD)) - return retVal -} - -func (c *PurchaseHandler) onWaybillMsg(vendorOrgCode string, msg *jdapi.CallbackDeliveryStatusMsg) (retVal *jdapi.CallbackResponse) { - order := c.callbackMsg2Waybill(msg) - switch msg.DeliveryStatus { - case jdapi.DeliveryStatusWait4Grap: - order.Status = model.WaybillStatusNew - case jdapi.DeliveryStatusAccepted, jdapi.DeliveryStatusCourierChaged: // 将更换配送员也当成接单消息 - // todo 性能问题,暂时取消调用 - // if result, err := getAPI(vendorOrgCode).QuerySingleOrder(msg.OrderID); err == nil { - // // 默认配送费=订单应付运费(orderReceivableFreight) - // //订单应付运费为未优惠前应付运费(满免优惠,运费优惠券,VIP免基础运费,用户小费)ps:用户小费是用户给配送员的小费 - // order.DesiredFee = utils.Interface2Int64WithDefault(result["orderReceivableFreight"], 0) + - // utils.Interface2Int64WithDefault(result["merchantPaymentDistanceFreightMoney"], 0) + - // utils.Interface2Int64WithDefault(result["tips"], 0) - // } - order.Status = model.WaybillStatusAccepted - case jdapi.DeliveryStatusCourierCanceled: - order.Status = model.WaybillStatusAcceptCanceled - case jdapi.DeliveryStatusCourierArrived: - order.Status = model.WaybillStatusCourierArrived - case jdapi.DeliveryStatusFailedGetGoodsWaiting: - order.Status = model.WaybillStatusApplyFailedGetGoods - case jdapi.DeliveryStatusFailedGetGoodsRejected: - order.Status = model.WaybillStatusRefuseFailedGetGoods - case jdapi.DeliveryStatusFailedGetGoods: - order.Status = model.WaybillStatusAgreeFailedGetGoods - case jdapi.DeliveryStatusGotGoods: - order.Status = model.WaybillStatusDelivering - case jdapi.DeliveryStatusFailedDelivery: - order.Status = model.WaybillStatusDeliverFailed - case jdapi.DeliveryStatusFinished: - order.Status = model.WaybillStatusDelivered - default: - order.Status = model.WaybillStatusUnknown - } - return jdapi.Err2CallbackResponse(partner.CurOrderManager.OnWaybillStatusChanged(order), order.VendorStatus) -} - -func (c *PurchaseHandler) callbackMsg2Waybill(msg *jdapi.CallbackDeliveryStatusMsg) (retVal *model.Waybill) { - retVal = &model.Waybill{ - VendorOrderID: msg.OrderID, - OrderVendorID: model.VendorIDJD, - VendorWaybillID: msg.OrderID, - WaybillVendorID: model.VendorIDJD, - CourierName: msg.DeliveryManName, - CourierMobile: msg.DeliveryManPhone, - VendorStatus: msg.DeliveryStatus, - StatusTime: utils.Str2Time(msg.DeliveryStatusTime), - Remark: msg.Remark, - - VendorOrgCode: AppKey2OrgCode(msg.AppKey), - } - return retVal -} diff --git a/business/partner/purchase/jdshop/act.go b/business/partner/purchase/jdshop/act.go deleted file mode 100644 index d155fefd8..000000000 --- a/business/partner/purchase/jdshop/act.go +++ /dev/null @@ -1,11 +0,0 @@ -package jdshop - -import ( - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" -) - -func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSkuList []*model.ActStoreSku2) (err error) { - return err -} diff --git a/business/partner/purchase/jdshop/callback.go b/business/partner/purchase/jdshop/callback.go deleted file mode 100644 index 9c5fb6146..000000000 --- a/business/partner/purchase/jdshop/callback.go +++ /dev/null @@ -1,314 +0,0 @@ -package jdshop - -import ( - "bytes" - "encoding/base64" - "encoding/hex" - "fmt" - "math" - "strings" - "time" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - - "git.rosy.net.cn/baseapi/platformapi/dingdingapi" - "git.rosy.net.cn/baseapi/platformapi/jcqapi" - "git.rosy.net.cn/baseapi/platformapi/jdshopapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxstore/common" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/ddmsg" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -func OnCallbackMsg(msg *jdshopapi.CallBackResult) (err error) { - msgType := msg.MsgType - switch msgType { - case jcqapi.TopicOrderPay: - utils.CallFuncAsync(func() { - SaveJdsOrders(msg) - }) - case jcqapi.TopicOrderCancel: - utils.CallFuncAsync(func() { - order := getRealOrderID(msg.OrderID) - if order != nil { - if order.Status != model.OrderStatusCanceled { - CurPurchaseHandler.CancelOrder(jxcontext.AdminCtx, order, "系统取消") - } - } - }) - case jcqapi.TopicOrderOut: - utils.CallFuncAsync(func() { - globals.SugarLogger.Debugf("jdsOrderOut", utils.Format4Output(msg, false)) - orders := getAllRealOrderID(msg.OrderID) - if len(orders) > 0 { - for _, order := range orders { - if order.ActualPayPrice == 0 { - if jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderPayment)) == 0 { - order.ActualPayPrice = jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderTotalPrice) + utils.Str2Float64(msg.FreightPrice) - utils.Str2Float64(msg.SellerDiscount)) - } else { - order.ActualPayPrice = jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderPayment)) - } - order.TotalShopMoney = utils.Float64TwoInt64(float64(order.ActualPayPrice) * jdshopapi.JdsPayPercentage) - partner.CurOrderManager.UpdateOrderFields(order, []string{"ActualPayPrice", "TotalShopMoney"}) - } - } - } - }) - default: - return fmt.Errorf("暂不支持的topic类型!topic: %v", msgType) - } - return err -} - -func SaveJdsOrders(msg *jdshopapi.CallBackResult) (err error) { - order, err := result2Orders(msg) - if err != nil || order == nil { - return err - } - partner.CurOrderManager.OnOrderNew(order, model.Order2Status(order)) - noticeMsg := fmt.Sprintf("京东商城新订单,订单号:[%v] ,将要发到的门店id:[%v] , 门店名:[%v]", order.VendorOrderID, order.StoreID, order.StoreName) - if order.OrderType == model.OrderTypeAddressErr { - noticeMsg += " 此订单地址有问题,需要矫正坐标!" - } - ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "DDC5657B43EE11E9A9FF525400E86DC0", "京东商城来新订单了!", noticeMsg) - ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "1439B3E07D3911EA881A525400E86DC0", "京东商城来新订单了!", noticeMsg) - return err -} - -func result2Orders(msg *jdshopapi.CallBackResult) (order *model.GoodsOrder, err error) { - //有可能是库里已经有这个订单了 - orderE, err := partner.CurOrderManager.LoadOrder(msg.OrderID+"000001", model.VendorIDJDShop) - if orderE != nil { - return order, fmt.Errorf("已经存在此订单!") - } - order = &model.GoodsOrder{ - VendorOrderID2: msg.OrderID, - VendorOrderID: msg.OrderID + "000001", - VendorID: model.VendorIDJDShop, - BaseFreightMoney: jxutils.StandardPrice2Int(utils.Str2Float64(msg.FreightPrice)), - VendorStatus: msg.OrderState, - VendorUserID: msg.Pin, - BuyerComment: msg.OrderRemark, - PickDeadline: utils.DefaultTimeValue, - OriginalData: string(utils.MustMarshal(msg)), - OrderCreatedAt: utils.Str2Time(msg.OrderStartTime), - ConsigneeAddress: Decrypt(msg.ConsigneeInfo.FullAddress), - ConsigneeName: Decrypt(msg.ConsigneeInfo.Fullname), - ConsigneeMobile: Decrypt(msg.ConsigneeInfo.Mobile), - ConsigneeMobile2: Decrypt(msg.ConsigneeInfo.Telephone), - ActualPayPrice: jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderPayment)), - Status: model.OrderStatusNew, - TotalShopMoney: utils.Float64TwoInt64(math.Round(float64(jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderPayment))) * jdshopapi.JdsPayPercentage)), - DeliveryType: model.OrderDeliveryTypeStoreSelf, - StatusTime: utils.Str2Time(msg.OrderStartTime), - OrderSeq: 0, - } - if order.TotalShopMoney < 100 { - order.TotalShopMoney = 100 - } - if order.ConsigneeAddress != "" { - lng, lat, err2 := api.AutonaviAPI.GetCoordinateFromAddressByPage(order.ConsigneeAddress) - if err = err2; err != nil { - globals.SugarLogger.Infof("高德page err: %v", err) - } - lng2, lat2, _ := api.AutonaviAPI.GetCoordinateFromAddress(order.ConsigneeAddress, "") - distance := jxutils.EarthDistance(lng, lat, lng2, lat2) - if distance > 1 { - order.OrderType = model.OrderTypeAddressErr - } - if err == nil && lng != 0 && lat != 0 { - order.ConsigneeLng = jxutils.StandardCoordinate2Int(lng) - order.ConsigneeLat = jxutils.StandardCoordinate2Int(lat) - } else { - order.ConsigneeLng = jxutils.StandardCoordinate2Int(lng2) - order.ConsigneeLat = jxutils.StandardCoordinate2Int(lat2) - } - order.CoordinateType = model.CoordinateTypeMars - } - for _, v := range msg.ItemInfoList { - sku := &model.OrderSku{ - VendorID: model.VendorIDJDShop, - VendorOrderID: order.VendorOrderID, - Count: utils.Str2Int(v.ItemTotal), - VendorSkuID: v.SkuID, - SkuName: v.SkuName, - VendorPrice: jxutils.StandardPrice2Int(utils.Str2Float64(v.JdPrice)), - SalePrice: jxutils.StandardPrice2Int(utils.Str2Float64(v.JdPrice)), - // SkuID: utils.Str2Int(v.OuterSkuID), - } - if v.OuterSkuID != "" { - sku.SkuID = utils.Str2Int(v.OuterSkuID) - } - _, _, _, specUnit, _, specQuality := jxutils.SplitSkuName(v.SkuName) - sku.Weight = jxutils.FormatSkuWeight(specQuality, specUnit) - order.Skus = append(order.Skus, sku) - } - storeList, err := common.GetStoreListByLocation(jxcontext.AdminCtx, jxutils.IntCoordinate2Standard(order.ConsigneeLng), jxutils.IntCoordinate2Standard(order.ConsigneeLat), 3000, false, true) - if err != nil { - globals.SugarLogger.Debugf("jds GetStoreListByLocation error: %v", err.Error()) - return order, err - } - if len(storeList) > 0 { - for _, store := range storeList { - order.StoreID = store.ID - order.JxStoreID = store.ID - order.StoreName = store.Name - globals.SugarLogger.Debugf("jds GetStoreListByLocation, orderID: %v storeID :%v", order.VendorOrderID, order.StoreID) - //结算类型 - storeDetail, _ := dao.GetStoreDetail(dao.GetDB(), order.StoreID, model.VendorIDJDShop) - if storeDetail != nil { - if storeDetail.PayPercentage < 50 { - order.EarningType = model.EarningTypePoints - } else { - order.EarningType = model.EarningTypeQuote - } - } - var ( - shopPriceSum int - saleNormalSum int - ) - for _, sku := range order.Skus { - storeSkuList, _ := dao.GetStoresSkusInfo(dao.GetDB(), []int{order.StoreID}, []int{sku.SkuID}) - if len(storeSkuList) > 0 { - if storeSkuList[0].Status == model.StoreSkuBindStatusNormal { - saleNormalSum += 1 - } - shopPriceSum += storeSkuList[0].Price * sku.Count - } - } - //可售数小于一半就不行 - if math.Mod(float64(len(order.Skus)), float64(2)) == 0 { - if saleNormalSum < len(order.Skus)/2 { - buildOrderTo102919(order) - continue - } else { - if order.EarningType == model.EarningTypeQuote && shopPriceSum+700 > int(order.TotalShopMoney) { - buildOrderTo102919(order) - continue - } - } - } else { - if saleNormalSum <= len(order.Skus)/2 { - buildOrderTo102919(order) - continue - } else { - if order.EarningType == model.EarningTypeQuote && shopPriceSum+700 > int(order.TotalShopMoney) { - buildOrderTo102919(order) - continue - } - } - } - break - } - } else { - buildOrderTo102919(order) - } - storeMaps, _ := dao.GetStoresMapList(dao.GetDB(), []int{model.VendorIDJDShop}, []int{order.StoreID}, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "") - if len(storeMaps) > 0 { - order.VendorStoreID = storeMaps[0].VendorStoreID - } - // 如果是暂停,表示是预订单g - if msg.OrderState == jdshopapi.OrderStatusPause || msg.OrderState == jdshopapi.OrderStatusPopPause { - order.BusinessType = model.BusinessTypeDingshida - if time2, err := api.JdShopAPI.GetOrderExtInfoByOrderId(order.VendorOrderID2); err == nil { - if time2 == "" { - order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour) - } else { - order.ExpectedDeliveredTime = utils.Str2Time(time2).Add(-time.Minute * 30) - } - } - order.PickDeadline = order.ExpectedDeliveredTime.Add(-time.Hour) - } else if msg.OrderState == jdshopapi.OrderStatusWait { - order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour) - order.BusinessType = model.BusinessTypeImmediate - } else { - globals.SugarLogger.Debugf("暂不支持的京东商城订单类型!type: %v", msg.OrderState) - return nil, err - } - if msg.IDSopShipmenttype == jdshopapi.IdSopShipmenttypeTC { - if time2, err := api.JdShopAPI.GetOrderExtInfoByOrderId(order.VendorOrderID2); err == nil { - order.BusinessType = model.BusinessTypeDingshida - order.ExpectedDeliveredTime = utils.Str2Time(time2).Add(-time.Minute * 30) - } - } - setJdsOrderSeq(order) - if order.OrderType == model.OrderTypeAddressErr { - buildOrderTo102919(order) - } - return order, err -} - -func buildOrderTo102919(order *model.GoodsOrder) { - order.StoreID = 102919 - order.JxStoreID = 102919 - order.StoreName = "商城模板(成都发货)" - order.VendorStoreID = model.JdShopMainVendorStoreID - order.DeliveryFlag = model.OrderDeliveryFlagMaskScheduleDisabled -} - -func setJdsOrderSeq(order *model.GoodsOrder) (err error) { - type tCount struct { - Count int `json:"count"` - } - var count = &tCount{} - sql := ` - SELECT count(*) count FROM goods_order WHERE store_id = ? AND order_create_at >= ? AND order_create_at <= ? AND vendor_id = ? - ` - sqlParams := []interface{}{ - order.StoreID, utils.Time2Date(time.Now()), utils.Time2Date(time.Now().AddDate(0, 0, 1)), order.VendorID, - } - err = dao.GetRow(dao.GetDB(), &count, sql, sqlParams) - order.OrderSeq = count.Count + 1 - return err -} - -func Decrypt(p string) (result string) { - if p == "" { - return "" - } - data, _ := base64.StdEncoding.DecodeString(strings.ReplaceAll(p, " ", "+")) - key := GetKey(hex.EncodeToString(data)[4:36]) - globals.SugarLogger.Debugf("Decrypt keys : %v", key) - data2, _ := base64.StdEncoding.DecodeString(key) - b := bytes.NewBuffer(data) - b.Next(18) - iv := make([]byte, 16) - b.Read(iv) - main := make([]byte, len(data)-18-16) - b.Read(main) - decryptedData, _ := utils.AESCBCDecpryt(main, data2[:16], iv) - return string(decryptedData) -} - -func getRealOrderID(orderID string) (order *model.GoodsOrder) { - var ( - db = dao.GetDB() - ) - sql := ` - SELECT * FROM goods_order WHERE vendor_order_id2 = ? ORDER BY vendor_order_id DESC LIMIT 1 - ` - sqlParams := []interface{}{ - orderID, - } - dao.GetRow(db, &order, sql, sqlParams) - return order -} - -func getAllRealOrderID(orderID string) (orders []*model.GoodsOrder) { - var ( - db = dao.GetDB() - ) - sql := ` - SELECT * FROM goods_order WHERE vendor_order_id2 = ? - ` - sqlParams := []interface{}{ - orderID, - } - dao.GetRows(db, &orders, sql, sqlParams) - return orders -} diff --git a/business/partner/purchase/jdshop/jds.go b/business/partner/purchase/jdshop/jds.go deleted file mode 100644 index 8f73f40d4..000000000 --- a/business/partner/purchase/jdshop/jds.go +++ /dev/null @@ -1,69 +0,0 @@ -package jdshop - -import ( - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/business/partner/putils" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -var ( - CurPurchaseHandler *PurchaseHandler -) - -type PurchaseHandler struct { - partner.BasePurchasePlatform - putils.DefSingleStorePlatform -} - -func init() { - if api.JdShopAPI != nil { - CurPurchaseHandler = New() - partner.RegisterPurchasePlatform(CurPurchaseHandler) - } -} - -func New() (obj *PurchaseHandler) { - obj = new(PurchaseHandler) - obj.ISingleStoreStoreSkuHandler = obj - return obj -} - -func (p *PurchaseHandler) GetVendorID() int { - return model.VendorIDJDShop -} - -func (p *PurchaseHandler) UploadImg(ctx *jxcontext.Context, vendorOrgCode, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) { - if globals.EnableJdShopWrite { - if imgType > model.ImgTypeLocal { - result, err := api.JdShopAPI.UploadPicture(imgData, 0, imgName) - if err == nil { - imgHint = result.PictureURL - } - } - } else { - imgHint = utils.GetUpperUUID() - } - return imgHint, err -} - -func (p *PurchaseHandler) GetVendorCategories(ctx *jxcontext.Context) (vendorCats []*model.SkuVendorCategory, err error) { - result, err := api.JdShopAPI.FindVendorCategories() - for _, v := range result { - cat := &model.SkuVendorCategory{ - VendorID: model.VendorIDJDShop, - Name: v.Name, - Level: v.Lev, - VendorCategoryID: utils.Int2Str(v.ID), - } - if v.Lev > 1 { - cat.ParentID = utils.Int2Str(v.Fid) - cat.IsLeaf = 1 - } - vendorCats = append(vendorCats, cat) - } - return vendorCats, err -} diff --git a/business/partner/purchase/jdshop/key.go b/business/partner/purchase/jdshop/key.go deleted file mode 100644 index 2ecee39f7..000000000 --- a/business/partner/purchase/jdshop/key.go +++ /dev/null @@ -1,51 +0,0 @@ -package jdshop - -import ( - "encoding/base64" - "encoding/hex" - "encoding/json" - - "git.rosy.net.cn/jx-callback/globals" - - "git.rosy.net.cn/jx-callback/globals/api" -) - -var ( - KeyList []*Key -) - -type Key struct { - ID string `json:"id"` - KeyExp int64 `json:"key_exp"` - KeyStatus int `json:"key_status"` - KeyDigest string `json:"key_digest"` - KeyType string `json:"key_type"` - KeyString string `json:"key_string"` - KeyEffective int64 `json:"key_effective"` - Version int `json:"version"` -} - -func InitKey() { - keyResult, err := api.JdShopAPI.KeyGet() - if err != nil { - return - } - for _, v := range keyResult.Response.ServiceKeyList[0].Keys { - data, _ := json.Marshal(v) - vv := &Key{} - err = json.Unmarshal(data, &vv) - KeyList = append(KeyList, vv) - } - globals.SugarLogger.Debugf("jdshop key refreshed..") -} - -func GetKey(keySign string) (key string) { - for _, v := range KeyList { - data, _ := base64.StdEncoding.DecodeString(v.ID) - if keySign == hex.EncodeToString(data) { - return v.KeyString - } - } - globals.SugarLogger.Debugf("no key can equal..") - return key -} diff --git a/business/partner/purchase/jdshop/order.go b/business/partner/purchase/jdshop/order.go deleted file mode 100644 index e56bc527f..000000000 --- a/business/partner/purchase/jdshop/order.go +++ /dev/null @@ -1,243 +0,0 @@ -package jdshop - -import ( - "fmt" - "net/http" - "strings" - "time" - - "git.rosy.net.cn/jx-callback/business/model/dao" - - "git.rosy.net.cn/baseapi" - "git.rosy.net.cn/baseapi/platformapi" - "git.rosy.net.cn/baseapi/platformapi/jdshopapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals/api" -) - -func (p *PurchaseHandler) AcceptOrRefuseFailedGetOrder(ctx *jxcontext.Context, order *model.GoodsOrder, isAcceptIt bool) (err error) { - return err -} - -func (p *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) { - result := &jdshopapi.AllOrdersResult{} - utils.Map2StructByJson(orderData, &result, false) - jdsOrder := result.OrderList[0] - order = &model.GoodsOrder{ - VendorOrderID: utils.Int64ToStr(jdsOrder.OrderID), - VendorID: model.VendorIDJDShop, - BaseFreightMoney: jxutils.StandardPrice2Int(jdsOrder.Freight), - VendorStatus: utils.Int2Str(jdsOrder.OrderStatus), - VendorUserID: jdsOrder.UserPin, - BuyerComment: jdsOrder.UserRemark, - PickDeadline: utils.DefaultTimeValue, - OriginalData: string(utils.MustMarshal(jdsOrder)), - } - return order -} -func (p *PurchaseHandler) GetOrder(vendorOrgCode, vendorOrderID string) (order *model.GoodsOrder, err error) { - resultOrders, err := api.JdShopAPI.AllOrders(&jdshopapi.AllOrdersParam{ - OrderID: vendorOrderID, - Current: 1, - PageSize: 1, - }) - return p.Map2Order(utils.Struct2FlatMap(resultOrders)), err -} -func (p *PurchaseHandler) GetOrderStatus(vendorOrgCode, vendorOrderID string) (status int, err error) { - jdsOrder, err := GetJdsOrder(vendorOrderID) - return status2Jxstatus(jdsOrder.OrderState), err -} - -func (p *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) { - var status int - if isAcceptIt { - status = model.OrderStatusAccepted - } else { - status = model.OrderStatusCanceled - } - return ChangeOrderStatus(order.VendorOrderID, status, "") -} -func (p *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) { - status, err := p.GetOrderStatus("", order.VendorOrderID2) - //说明此时该订单在平台上已经取消了 - if status == model.OrderStatusCanceled { - err = ChangeOrderStatus(order.VendorOrderID, model.OrderStatusCanceled, "订单在京东商城已被取消!") - } else { - err = ChangeOrderStatus(order.VendorOrderID, model.OrderStatusFinishedPickup, "自动拣货完成") - err = p.OrderExport(jxcontext.AdminCtx, order.VendorOrderID, order.VendorOrderID, true) - } - return err -} - -func (p *PurchaseHandler) CallCourier(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { - return err -} // 取货失败后再次招唤平台配送 -func (p *PurchaseHandler) ConfirmReceiveGoods(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { - return err -} // 投递失败后确认收到退货 -func (p *PurchaseHandler) CanSwitch2SelfDeliver(order *model.GoodsOrder) (isCan bool, err error) { - return isCan, err -} -func (p *PurchaseHandler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) { - return err -} -func (p *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName string) (err error) { - return err -} -func (p *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) { - ChangeOrderStatus(order.VendorOrderID, model.OrderStatusDelivering, "") - return err -} -func (p *PurchaseHandler) SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) { - ChangeOrderStatus(order.VendorOrderID, model.OrderStatusFinished, "") - return err -} -func (p *PurchaseHandler) GetOrderRealMobile(ctx *jxcontext.Context, order *model.GoodsOrder) (mobile string, err error) { - return mobile, err -} -func (p *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, vendorOrgCode string, orderComment *model.OrderComment, replyComment string) (err error) { - return err -} -func (p *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) { - return err -} -func (p *PurchaseHandler) CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) { - ChangeOrderStatus(order.VendorOrderID, model.OrderStatusCanceled, reason) - if order.EclpOutID != "" { - _, err = api.JdEclpAPI.CancelOrder(order.EclpOutID) - } - return err -} -func (p *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) { - var ( - db = dao.GetDB() - diffShopPrice int64 - diffSalePrice int64 - ) - if order.Status >= model.OrderStatusDelivering { - return fmt.Errorf("配送中以后的订单无法进行售前退款!") - } - //1、删除原order_sku 中售前调整的商品 - for _, sku := range removedSkuList { - sql := `DELETE FROM order_sku WHERE vendor_order_id = ? AND vendor_id = ? AND sku_id = ?` - sqlParams := []interface{}{order.VendorOrderID, order.VendorID, sku.SkuID} - dao.ExecuteSQL(db, sql, sqlParams) - - diffShopPrice += sku.ShopPrice - diffSalePrice += sku.SalePrice - } - //2、修改goods_order 中的shopprice,若是扣点的订单,还要改new_earning_price和total_shop_money - order.AdjustCount += 1 - order.ShopPrice = order.ShopPrice - diffShopPrice - if order.EarningType == model.EarningTypePoints { - order.TotalShopMoney = utils.Float64TwoInt64(float64(float64(order.TotalShopMoney)/jdshopapi.JdsPayPercentage-float64(diffSalePrice)) * jdshopapi.JdsPayPercentage) - jxutils.RefreshOrderEarningPrice2(order, order.OrderPayPercentage) - partner.CurOrderManager.UpdateOrderFields(order, []string{"TotalShopMoney", "NewEarningPrice"}) - } - partner.CurOrderManager.UpdateOrderFields(order, []string{"AdjustCount", "ShopPrice"}) - return err -} - -func (p *PurchaseHandler) GetJdsOrders(ctx *jxcontext.Context, orderCreatedStart, orderCreatedEnd string, current, pageSize int) (orderResult *jdshopapi.AllOrdersResult, err error) { - orderResult, err = api.JdShopAPI.AllOrders(&jdshopapi.AllOrdersParam{ - Current: current, - PageSize: pageSize, - OrderCreateDateRange: []string{orderCreatedStart, orderCreatedEnd}, - }) - return orderResult, err -} - -func ChangeOrderStatus(vendorOrderID string, status int, remark string) (err error) { - orderStatus := &model.OrderStatus{ - VendorOrderID: vendorOrderID, - VendorID: model.VendorIDJDShop, - OrderType: model.OrderTypeOrder, - RefVendorOrderID: vendorOrderID, - RefVendorID: model.VendorIDJDShop, - VendorStatus: utils.Int2Str(status), - Status: status, - StatusTime: time.Now(), - Remark: remark, - } - jxutils.CallMsgHandlerAsync(func() { - err = partner.CurOrderManager.OnOrderStatusChanged("", orderStatus) - }, jxutils.ComposeUniversalOrderID(vendorOrderID, model.VendorIDJDShop)) - return err -} - -func (p *PurchaseHandler) OrderExport(ctx *jxcontext.Context, vendorOrderID, vendorWaybillID string, isAuto bool) (err error) { - companyID := jdshopapi.JdsDeliveryCompany3rd - //表示是门店手动发京东 - if !isAuto { - companyID = jdshopapi.JdsDeliveryCompanyJD - } - err = api.JdShopAPI.OrderShipment(utils.Str2Int64(vendorOrderID[:12]), companyID, vendorWaybillID) - return err -} - -func (p *PurchaseHandler) OrderTransfer(ctx *jxcontext.Context, vendorOrderID, vendorWaybillID string, isAuto bool) (err error) { - companyID := jdshopapi.JdsDeliveryCompany3rd - //表示是门店手动发京东 - if !isAuto { - companyID = jdshopapi.JdsDeliveryCompanyJD - } - err = api.JdShopAPI.UpdateWaybill(vendorOrderID[:12], companyID, vendorOrderID) - return err -} - -func status2Jxstatus(status string) (statusJx int) { - if status == jdshopapi.OrderStatusPopPause || status == jdshopapi.OrderStatusPause { - statusJx = model.OrderStatusNew - } else if status == jdshopapi.OrderStatusWait { - statusJx = model.OrderStatusAccepted - } else if status == jdshopapi.OrderStatusCancel { - statusJx = model.OrderStatusCanceled - } - return statusJx -} - -const ( - ProdURL = "http://116.196.82.188:8080/v2/" -) - -func apiToYd(url string, params map[string]interface{}) (retVal map[string]interface{}, err error) { - cl := &http.Client{} - err = platformapi.AccessPlatformAPIWithRetry(cl, - func() *http.Request { - request, _ := http.NewRequest(http.MethodPost, ProdURL+url, strings.NewReader(utils.Map2URLValues(params).Encode())) - request.Header.Set("Content-Type", "application/x-www-form-urlencoded") - return request - }, - nil, - 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") - } - if err == nil { - if jsonResult1["code"] != nil { - if utils.Interface2Int64WithDefault(jsonResult1["code"], 0) != 0 { - errLevel = platformapi.ErrLevelGeneralFail - err = utils.NewErrorCode(jsonResult1["desc"].(string), jsonResult1["code"].(string)) - baseapi.SugarLogger.Debugf("yd AccessAPI failed, jsonResult1:%s", utils.Format4Output(jsonResult1, true)) - } - } - retVal = jsonResult1 - } - return errLevel, err - }) - return retVal, err -} - -func GetJdsOrder(vendorOrderID string) (jdsOrder *jdshopapi.GetOrderResult, err error) { - params := make(map[string]interface{}) - params["orderID"] = vendorOrderID - params["token"] = jdshopapi.JdsYdToken - result, err := apiToYd("order/GetJdsOrder", params) - jdsOrder2 := &jdshopapi.GetOrderResult{} - err = utils.UnmarshalUseNumber([]byte(strings.ReplaceAll(result["data"].(string), "\\", "")), &jdsOrder2) - return jdsOrder2, err -} diff --git a/business/partner/purchase/jdshop/order_afs.go b/business/partner/purchase/jdshop/order_afs.go deleted file mode 100644 index bc0c8ec51..000000000 --- a/business/partner/purchase/jdshop/order_afs.go +++ /dev/null @@ -1,134 +0,0 @@ -package jdshop - -import ( - "crypto/md5" - "fmt" - "math" - "time" - - "git.rosy.net.cn/jx-callback/business/model/dao" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" -) - -func (c *PurchaseHandler) AgreeOrRefuseRefund(ctx *jxcontext.Context, afsOrder *model.AfsOrder, approveType int, reason string) (err error) { - var status int - if approveType == partner.AfsApproveTypeRefused { - status = model.AfsOrderStatusFailed - } else { - status = model.AfsOrderStatusFinished - - } - orderStatus := &model.OrderStatus{ - VendorOrderID: afsOrder.AfsOrderID, // 是售后单ID,不是订单ID,订单ID在RefVendorOrderID中 - VendorID: afsOrder.VendorID, - OrderType: model.OrderTypeAfsOrder, - RefVendorOrderID: afsOrder.VendorOrderID, - RefVendorID: afsOrder.VendorID, - VendorStatus: utils.Int2Str(status), - Status: status, - StatusTime: time.Now(), - Remark: reason, - } - partner.CurOrderManager.OnAfsOrderStatusChanged(orderStatus) - return err -} - -// 确认收到退货 -func (c *PurchaseHandler) ConfirmReceivedReturnGoods(ctx *jxcontext.Context, order *model.AfsOrder) (err error) { - err = fmt.Errorf("京东商城当前不支持ConfirmReceivedReturnGoods") - return err -} - -// 发起全款退款 -func (c *PurchaseHandler) RefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) { - err = c.PartRefundOrder(ctx, order, order.Skus, reason) - return err -} - -// 发起部分退款 -func (c *PurchaseHandler) PartRefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, refundSkuList []*model.OrderSku, reason string) (err error) { - globals.SugarLogger.Debugf("PartRefundOrder jdshop, orderID :%v", order.VendorOrderID) - var ( - skuMap = make(map[int]*model.OrderSku) - salePrice int64 - db = dao.GetDB() - ) - for _, sku := range order.Skus { - skuMap[sku.SkuID] = sku - } - orderStatus := buildOrderStatus(ctx, order, reason) - afsOrder := &model.AfsOrder{ - VendorID: order.VendorID, - AfsOrderID: orderStatus.VendorOrderID, - VendorOrderID: orderStatus.RefVendorOrderID, - // VendorStoreID: order.VendorStoreID, - // StoreID: jxutils.GetSaleStoreIDFromOrder(order), - AfsCreatedAt: time.Now(), - VendorAppealType: "", - AppealType: model.AfsAppealTypeRefund, - VendorReasonType: utils.Int2Str(model.AfsReasonNotOthers), - ReasonType: model.AfsReasonNotOthers, - ReasonDesc: utils.LimitUTF8StringLen(reason, 1024), - ReasonImgList: "", - RefundType: model.AfsTypePartRefund, - - VendorOrgCode: "", - } - for _, sku := range refundSkuList { - orderSku := &model.OrderSkuFinancial{ - Count: sku.Count, - VendorSkuID: utils.Int2Str(sku.SkuID), - SkuID: sku.SkuID, - } - storeSkus, _ := dao.GetStoresSkusInfo(db, []int{model.JdShopMainStoreID}, []int{sku.SkuID}) - if len(storeSkus) > 0 { - orderSku.VendorSkuID = utils.Int64ToStr(storeSkus[0].JdsID) - } - if skuMap[sku.SkuID] != nil { - orderSku.Name = skuMap[sku.SkuID].SkuName - orderSku.UserMoney = skuMap[sku.SkuID].SalePrice * int64(sku.Count) - salePrice += skuMap[sku.SkuID].SalePrice * int64(sku.Count) - } - afsOrder.SkuUserMoney += orderSku.UserMoney - afsOrder.Skus = append(afsOrder.Skus, orderSku) - } - err = partner.CurOrderManager.OnAfsOrderNew(afsOrder, orderStatus) - return err -} - -func buildOrderStatus(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (orderStatus *model.OrderStatus) { - orderStatus = &model.OrderStatus{ - VendorOrderID: utils.Int64ToStr(GenAfsOrderNo(ctx)), // 是售后单ID,不是订单ID,订单ID在RefVendorOrderID中 - VendorID: order.VendorID, - OrderType: model.OrderTypeAfsOrder, - RefVendorOrderID: order.VendorOrderID, - RefVendorID: order.VendorID, - VendorStatus: utils.Int2Str(model.AfsOrderStatusWait4Approve), - Status: model.AfsOrderStatusWait4Approve, - StatusTime: time.Now(), - Remark: reason, - } - orderStatus.Status = model.AfsOrderStatusWait4Approve - return orderStatus -} - -func GenAfsOrderNo(ctx *jxcontext.Context) (orderNo int64) { - const prefix = 70 - const randPartNum = 100 - orderNoBeginTimestamp := utils.Str2Time("2010-01-01 00:00:00").Unix() - orderNo = time.Now().Unix() - orderNoBeginTimestamp - orderNo = orderNo * randPartNum - md5Bytes := md5.Sum([]byte(utils.GetUUID())) - randPart := 0 - for k, v := range md5Bytes { - randPart += int(v) << ((k % 3) * 8) - } - orderNo += int64(randPart % randPartNum) - orderNo += int64(math.Pow10(int(math.Log10(float64(orderNo)))+1)) * prefix - return orderNo -} diff --git a/business/partner/purchase/jdshop/order_comment.go b/business/partner/purchase/jdshop/order_comment.go deleted file mode 100644 index 6505fdb3c..000000000 --- a/business/partner/purchase/jdshop/order_comment.go +++ /dev/null @@ -1,5 +0,0 @@ -package jdshop - -func (c *PurchaseHandler) StartRefreshComment() { - -} diff --git a/business/partner/purchase/jdshop/store.go b/business/partner/purchase/jdshop/store.go deleted file mode 100644 index da7fd3231..000000000 --- a/business/partner/purchase/jdshop/store.go +++ /dev/null @@ -1,204 +0,0 @@ -package jdshop - -import ( - "encoding/base64" - "encoding/json" - "fmt" - "strings" - - "git.rosy.net.cn/baseapi/platformapi/jdshopapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/globals/api" -) - -func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string) (storeDetail *dao.StoreDetail, err error) { - // result, err := api.JdShopAPI.NewInfoList(utils.Str2Int64(vendorStoreID)) - // storeDetail.VendorStoreID = vendorStoreID - // storeDetail.Status = JdsStatus2jxStatus(result.StoreStatus) - result2, err := api.JdShopAPI.QueryEntityStore(utils.Str2Int64(vendorStoreID)) - if result2 == nil { - return storeDetail, fmt.Errorf("未查询到该平台门店,平台门店ID:[%v]", vendorStoreID) - } - storeDetail = &dao.StoreDetail{} - storeDetail.ID = utils.Str2Int(result2.ExStoreID) - storeDetail.Name = result2.StoreName - storeDetail.Address = result2.Address - storeDetail.Tel1 = result2.Phone - storeDetail.DistrictCode = result2.AddrCode - zbs := strings.Split(result2.Coordinate, ",") - storeDetail.Lat = jxutils.StandardCoordinate2Int(utils.Str2Float64(zbs[0])) - storeDetail.Lng = jxutils.StandardCoordinate2Int(utils.Str2Float64(zbs[1])) - return storeDetail, err -} - -// stoerIDs为nil表示所有 -func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName string) (err error) { - store, err := dao.GetStoreDetail(db, storeID, model.VendorIDJDShop) - if err != nil { - return err - } - data, _, err := jxutils.DownloadFileByURL(jdshopapi.JdsStoreImg) - timeMap := map[string]string{ - "businessBeginTime": int2TimeStr(int(store.OpenTime1)), - "businessEndTime": int2TimeStr(int(store.CloseTime1)), - } - timeJSON, _ := json.Marshal(timeMap) - updateEntityStoreParam := &jdshopapi.UpdateEntityStoreParam{ - StoreID: utils.Str2Int(store.VendorStoreID), - Name: store.Name, - AddCode: store.JdsCode, - AddCodeName: store.DistrictName, - AddName: store.ProvinceName + store.CityName + store.DistrictName + "@!" + store.Address, - Coordinate: utils.Float64ToStr(jxutils.IntCoordinate2Standard(store.Lat)) + "," + utils.Float64ToStr(jxutils.IntCoordinate2Standard(store.Lng)), - Phone: store.Tel1, - ExtendJSON: string(timeJSON), - ImageFile: base64.StdEncoding.EncodeToString(data), - CustomerID: utils.Int2Str(store.ID), - } - if store.JdsStreetCode != 0 { - updateEntityStoreParam.AddCode = store.JdsStreetCode - } - if updateEntityStoreParam.AddCode == 0 { - updateEntityStoreParam.AddCode = store.JdCode - } - err = api.JdShopAPI.UpdateEntityStore(updateEntityStoreParam) - if err == nil { - // if store.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreStatus) != 0 { - // mergeStatus := jxutils.MergeStoreStatus(store.Status, store.VendorStatus) - // err = api.JdShopAPI.UpdateStoreStatus(utils.Str2Int(store.VendorStoreID), jxStatus2JdsStatus(mergeStatus)) - // } - } - return err -} - -func (p *PurchaseHandler) CreateStore2(db *dao.DaoDB, storeID int, userName string) (vendorStoreID string, err error) { - store, err := dao.GetStoreDetail(db, storeID, model.VendorIDJDShop) - if err != nil { - return vendorStoreID, err - } - data, _, err := jxutils.DownloadFileByURL(jdshopapi.JdsStoreImg) - timeMap := map[string]string{ - "businessBeginTime": int2TimeStr(int(store.OpenTime1)), - "businessEndTime": int2TimeStr(int(store.CloseTime1)), - } - timeJSON, _ := json.Marshal(timeMap) - createEntityStoreParam := &jdshopapi.CreateEntityStoreParam{ - Name: store.Name, - AddCode: store.JdsCode, - AddCodeName: store.DistrictName, - AddName: store.ProvinceName + store.CityName + store.DistrictName + "@!" + store.Address, - Coordinate: utils.Float64ToStr(jxutils.IntCoordinate2Standard(store.Lat)) + "," + utils.Float64ToStr(jxutils.IntCoordinate2Standard(store.Lng)), - Phone: store.Tel1, - ExtendJSON: string(timeJSON), - ImageFile: base64.StdEncoding.EncodeToString(data), - CategoryName: jdshopapi.JdsStoreCategoryName, - CustomerID: utils.Int2Str(store.ID), - } - if store.JdsStreetCode != 0 { - createEntityStoreParam.AddCode = store.JdsStreetCode - } - if createEntityStoreParam.AddCode == 0 { - createEntityStoreParam.AddCode = store.JdCode - } - //证明这个店可能隶属直辖市或者东莞 - if model.ZXCityCodeMap[store.CityCode] != "" { - result, _ := api.AutonaviAPI.GetCoordinateAreaInfo(jxutils.IntCoordinate2Standard(store.Lng), jxutils.IntCoordinate2Standard(store.Lat)) - if result["regeocode"] != nil { - street := result["regeocode"].(map[string]interface{})["addressComponent"].(map[string]interface{})["township"].(string) - if street != "" { - result1, _ := api.JdShopAPI.GetProvince() - for _, v := range result1 { - if strings.Contains(store.CityName, v.AreaName) { - result2, _ := api.JdShopAPI.GetCity(v.AreaID) - for _, vv := range result2 { - if strings.Contains(store.DistrictName, vv.AreaName) { - result3, _ := api.JdShopAPI.GetCounty(vv.AreaID) - for _, vvv := range result3 { - if street == vvv.AreaName { - createEntityStoreParam.AddCode = vvv.AreaID - break - } - } - } - } - } - } - } - } - } - vendorStoreID, err = api.JdShopAPI.CreateEntityStore(createEntityStoreParam) - return vendorStoreID, err -} - -func (p *PurchaseHandler) DeleteStore(db *dao.DaoDB, storeID int, userName string) (err error) { - // store, err := dao.GetStoreDetail(db, storeID, model.VendorIDJDShop) - // if err != nil { - // return err - // } - // err = api.JdShopAPI.DeleteStoresByID(utils.Str2Int64(store.VendorStoreID)) - return err -} - -func (p *PurchaseHandler) RefreshAllStoresID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) { - return hint, err -} - -func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (storeStatus int, err error) { - return storeStatus, err -} - -func (p *PurchaseHandler) EnableAutoAcceptOrder(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, isSetEnable bool) (err error) { - return err -} - -func (c *PurchaseHandler) UpdateStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, status int) (err error) { - return err -} - -func (c *PurchaseHandler) UpdateStoreOpTime(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, opTimeList []int16) (err error) { - return err -} - -func (c *PurchaseHandler) GetAllStoresVendorID(ctx *jxcontext.Context, vendorOrgCode string) (vendorStoreIDs []string, err error) { - return vendorStoreIDs, err -} - -func (c *PurchaseHandler) UpdateStoreCustomID(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string, storeID int64) (err error) { - return err -} - -func int2TimeStr(time int) (str string) { - str += utils.Int2Str(time / 1000) - str += utils.Int2Str(time % 1000 / 100) - str += ":" - str += utils.Int2Str(time % 100 / 10) - str += utils.Int2Str(time % 10) - return str -} - -func jxStatus2JdsStatus(status int) (result int) { - if status == model.StoreStatusOpened { - result = jdshopapi.JdsStoreStatusOnline - } else if status == model.StoreStatusHaveRest || status == model.StoreStatusClosed { - result = jdshopapi.JdsStoreStatusRest - } else { - result = jdshopapi.JdsStoreStatusDisable - } - return result -} - -func JdsStatus2jxStatus(status int) (result int) { - if status == jdshopapi.JdsStoreStatusOnline { - result = model.StoreStatusOpened - } else if status == jdshopapi.JdsStoreStatusRest { - result = model.StoreStatusClosed - } else { - result = model.StoreStatusDisabled - } - return result -} diff --git a/business/partner/purchase/jdshop/store_sku.go b/business/partner/purchase/jdshop/store_sku.go deleted file mode 100644 index 0f994e1dd..000000000 --- a/business/partner/purchase/jdshop/store_sku.go +++ /dev/null @@ -1,896 +0,0 @@ -package jdshop - -import ( - "fmt" - "math" - "regexp" - "strings" - "time" - - "git.rosy.net.cn/baseapi/platformapi/jdshopapi" - - "git.rosy.net.cn/jx-callback/globals/api" - - "git.rosy.net.cn/baseapi/platformapi/yinbaoapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/business/partner/putils" - "git.rosy.net.cn/jx-callback/globals" -) - -const ( - deleteErr1 = "已经删除的不能直接下架" - deleteErr2 = "SKU" - deleteErr3 = "已删除" -) - -var ( - sensitiveWordRegexp = regexp.MustCompile(`商品名称中含有敏感词(\[.*\])`) -) - -func (p *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - if globals.EnableJdShopWrite && vendorStoreID == model.JdShopMainVendorStoreID { - for _, v := range storeSkuList { - //判断京东商城上是否有这个商品了,如果有就是添加规格而不是创建商品 - name := filterSensitiveWord(v.Name) - flag := false - result, err := api.JdShopAPI.SearchWare4Valid(name, 1, 100) - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品") - return failedList, err - } - for _, v := range result.Data { - if v.Title == name { - flag = true - break - } - } - if result.TotalItem > 0 && len(result.Data) > 0 && flag { - for _, vv := range v.StoreSkuSyncInfoJds { - v.JdsWareID = result.Data[0].WareID - vv.JdsWareID = result.Data[0].WareID - updateSkusParam, err := buildUpdateSkusParam(v, vv, true) - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品") - return failedList, err - } - vendorSkuID, err := api.JdShopAPI.UpdateSkus(updateSkusParam) - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品") - return failedList, err - } - vv.VendorSkuID = vendorSkuID - } - } else { - createSkuParamWare, createSkuParamSkus, err := buildCreateWareParam(v) - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品") - return failedList, err - } - createSkuResult, err := api.JdShopAPI.CreateWare(createSkuParamWare, createSkuParamSkus) - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "创建商品") - return failedList, err - } else { - //追加商品透图 - imageURL := "" - img := v.Img - if img != "" { - suffix := img[strings.LastIndex(img, "."):] - if suffix != ".png" { - if resBinary, _, _ := jxutils.DownloadFileByURL(img + model.SkuNameImgToPng); err == nil { - downloadURL, _ := jxutils.UploadExportContent(resBinary, utils.Int64ToStr(time.Now().Unix())) - imageURL, _ = uploadImg(downloadURL, name, "tou") - } - } else { - imageURL, _ = uploadImg(img, name, "tou") - } - } - api.JdShopAPI.TransparentImageAdd(createSkuResult.WareID, imageURL) - } - var paramAttrs = make(map[string]*jdshopapi.CreateSkuParamSkus) - var resultAttrs = make(map[string]int64) - for _, vv := range createSkuParamSkus { - for _, vvv := range vv.SaleAttrs { - paramAttrs[vvv.AttrValues[0]] = vv - } - } - for _, vv1 := range createSkuResult.Skus { - for _, vvv1 := range vv1.SaleAttrs { - if paramAttrs[vvv1.AttrValues[0]] != nil { - resultAttrs[paramAttrs[vvv1.AttrValues[0]].OuterID] = vv1.SkuID - } - } - } - for _, vv2 := range v.StoreSkuSyncInfoJds { - vv2.JdsWareID = createSkuResult.WareID - if resultAttrs[utils.Int2Str(vv2.SkuID)] != 0 { - vv2.VendorSkuID = utils.Int64ToStr(resultAttrs[utils.Int2Str(vv2.SkuID)]) - } - } - } - } - } - return failedList, err -} - -func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - if globals.EnableJdShopWrite && vendorStoreID == model.JdShopMainVendorStoreID { - for _, v := range storeSkuList { - name := filterSensitiveWord(v.Name) - updateWareParam := &jdshopapi.UpdateWareParam{ - WareID: v.JdsWareID, - Title: name, - VenderID: jdshopapi.VenderID, - // PromiseID: jdshopapi.JdsPromiseID, - ShopCategorys: []int{utils.Str2Int(v.VendorCatID)}, - JdPrice: jxutils.IntPrice2Standard(v.UnitPrice), - } - if v.VendorVendorCatID != jdshopapi.JdsOtherMeatCatID { - updateWareParam.PromiseID = jdshopapi.JdsPromiseID - } - var desc string - if v.DescImg != "" { - pic3, err2 := uploadImg2(v.DescImg, name, "desc") - err = err2 - desc = `



` - } else { - desc = `



` - } - updateWareParam.Introduction = desc - updateWareParam.MobileDesc = desc - img := "" - if v.ImgMix != "" { - img = v.ImgMix - } else { - img = v.Img - } - if img != "" { - pic1, err2 := uploadImg2(img, name, "1") - err = err2 - err = api.JdShopAPI.ImageUpdate(v.JdsWareID, 1, pic1) - if v.Img2 != "" { - pic2, err2 := uploadImg2(v.Img2, name, "2") - err = err2 - err = api.JdShopAPI.ImageUpdate(v.JdsWareID, 2, pic2) - } else { - err = api.JdShopAPI.ImageUpdate(v.JdsWareID, 2, pic1) - } - err = api.JdShopAPI.ImageUpdate(v.JdsWareID, 3, pic1) - } - var features = []*jdshopapi.CreateSkuParamFeatures{ - &jdshopapi.CreateSkuParamFeatures{ - Key: "is7ToReturn", //不支持7天无理由退货 - Value: "0", - }, - &jdshopapi.CreateSkuParamFeatures{ - Key: "tssp", //支持自提 - Value: "", - }, - // &jdshopapi.CreateSkuParamFeatures{ - // Key: "fdms", //分单? - // Value: "1", - // }, - } - updateWareParam.Features = features - err = api.JdShopAPI.UpdateWare(updateWareParam) - if err == nil { - //追加商品透图 - imageURL := "" - img := v.Img - if img != "" { - suffix := img[strings.LastIndex(img, "."):] - if suffix != ".png" { - if resBinary, _, err := jxutils.DownloadFileByURL(img + model.SkuNameImgToPng); err == nil { - downloadURL, err2 := jxutils.UploadExportContent(resBinary, utils.Int64ToStr(time.Now().Unix())) - err = err2 - imageURL, err = uploadImg(downloadURL, name, "tou") - } - } else { - imageURL, err = uploadImg(img, name, "tou") - } - } - api.JdShopAPI.TransparentImageAdd(v.JdsWareID, imageURL) - } - for _, vv := range v.StoreSkuSyncInfoJds { - updateSkusParam, err := buildUpdateSkusParam(v, vv, false) - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "更新商品基础信息") - return failedList, err - } - _, err = api.JdShopAPI.UpdateSkus(updateSkusParam) - } - } - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "更新商品基础信息") - } - } - return failedList, err -} - -func (p *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - if globals.EnableJdShopWrite && vendorStoreID == model.JdShopMainVendorStoreID { - for _, v := range storeSkuList { - if v.IsDeletedBySku { - err = api.JdShopAPI.DeleteSku(utils.Str2Int64(v.VendorSkuID)) - } else { - err = api.JdShopAPI.UpOrDown(utils.Str2Int64(v.VendorSkuID2), 2) - if err == nil { - err = api.JdShopAPI.DeleteWare(utils.Str2Int(v.VendorSkuID2)) - } - } - if err != nil { - failedList = append(failedList, putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "删除商品")...) - } - } - } - return failedList, err -} - -func (p *PurchaseHandler) GetStoreSkusFullInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (skuNameList []*partner.SkuNameInfo, err error) { - var ( - pageNo = 1 - pageSize = 20 - ) - _, totalCount, err := api.JdShopAPI.SearchSkuList(pageNo, pageSize) - for ; pageNo <= totalCount/pageSize+1; pageNo++ { - result, _, err := api.JdShopAPI.SearchSkuList(pageNo, pageSize) - if err == nil { - for _, v := range result { - if skuName := vendorSku2Jx(v); skuName != nil { - skuNameList = append(skuNameList, skuName) - } - } - } - } - return skuNameList, err -} - -func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (failedList []*partner.StoreSkuInfoWithErr, err error) { - if globals.EnableJdShopWrite { - var stock = 0 - for _, v := range storeSkuList { - if storeID == model.JdShopMainStoreID { - if status == model.SkuStatusNormal { - stock = 9999 - } - if v.JdsStockSwitch == model.NO { - stock = 0 - } - err = api.JdShopAPI.UpdateSkuStock(utils.Str2Int(v.VendorSkuID), stock) - } else { - storeSkus, err2 := dao.GetStoresSkusInfo(dao.GetDB(), []int{model.JdShopMainStoreID}, []int{v.SkuID}) - err = err2 - if len(storeSkus) > 0 { - if storeSkus[0].JdsID != 0 && vendorStoreID != "" { - if storeSkus[0].Status == model.SkuStatusNormal { - stock = 9999 - } - err = api.JdShopAPI.UpdateSkuSiteStock(storeSkus[0].JdsID, stock, utils.Str2Int(vendorStoreID)) - } - } - } - } - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "修改商品库存") - } - } - return failedList, err -} - -func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - if globals.EnableJdShopWrite && vendorStoreID == model.JdShopMainVendorStoreID { - for _, v := range storeSkuList { - err = api.JdShopAPI.UpdateSkuJdPrice(utils.Str2Int(v.VendorSkuID), jxutils.IntPrice2Standard(v.VendorPrice)) - if err != nil { - failedList = append(failedList, putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDJDShop], "修改商品价格")...) - } - } - } - return failedList, err -} - -func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - if globals.EnableJdShopWrite { - - } - return failedList, err -} - -func (p *PurchaseHandler) GetStoreAllCategories(ctx *jxcontext.Context, storeID int, vendorStoreID string) (cats []*partner.BareCategoryInfo, err error) { - result, err := api.JdShopAPI.FindShopCategories() - for _, v := range result { - var cat = &partner.BareCategoryInfo{ - VendorCatID: utils.Int64ToStr(v.CID), - Name: v.Name, - } - if v.ParentCID == 0 { - cat.Level = 1 - } else { - cat.Level = 2 - } - cats = append(cats, cat) - } - return cats, err -} - -func (p *PurchaseHandler) CreateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) { - if globals.EnableJdShopWrite && vendorStoreID == model.JdShopMainVendorStoreID { - status, err2 := updateOrCreateCategories(storeCat, true) - err = err2 - if status == -1 { - return fmt.Errorf("京东商城店内分类创建失败!") - } - if err != nil { - return err - } - time.Sleep(time.Second * 2) - // flag := false - // for { - result, err := api.JdShopAPI.FindShopCategories() - if err != nil { - return err - } - for _, v := range result { - if v.Name == storeCat.Name { - storeCat.VendorCatID = utils.Int64ToStr(v.CID) - // flag = true - break - } - } - if storeCat.VendorCatID == "" { - return fmt.Errorf("京东商城店内分类创建可能失败了!storeID: %v", storeID) - } - // if flag { - // break - // } - // } - } - return err -} - -func (p *PurchaseHandler) UpdateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) { - if globals.EnableJdShopWrite && vendorStoreID == model.JdShopMainVendorStoreID { - status, err2 := updateOrCreateCategories(storeCat, false) - err = err2 - if status == -1 { - return fmt.Errorf("京东商城店内分类更新失败!") - } - } - return err -} - -func (p *PurchaseHandler) DeleteStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID, vendorCatID string, level int) (err error) { - if globals.EnableJdShopWrite && vendorStoreID == model.JdShopMainVendorStoreID { - _, err = api.JdShopAPI.DeleteShopCategory(utils.Str2Int64(vendorCatID)) - } - return err -} - -func (p *PurchaseHandler) IsErrSkuExist(err error) (isExist bool) { - return false -} - -func (p *PurchaseHandler) IsErrCategoryExist(err error) (isExist bool) { - return false -} - -func (p *PurchaseHandler) IsErrCategoryNotExist(err error) (isNotExist bool) { - return false -} - -func (p *PurchaseHandler) GetStoreSkusBatchSize(funcID int) (batchSize int) { - return 1 -} - -func (p *PurchaseHandler) GetSensitiveWordRegexp() *regexp.Regexp { - return sensitiveWordRegexp -} - -func (p *PurchaseHandler) IsErrSkuNotExist(err error) (isNotExist bool) { - if strings.Contains(err.Error(), deleteErr1) || (strings.Contains(err.Error(), deleteErr2) && strings.Contains(err.Error(), deleteErr3)) { - return true - } - return false -} - -func ybSkuStatus2Jx(ybStatus int) (jxSkuStatus int) { - if ybStatus == yinbaoapi.SkuStatusEnable { - jxSkuStatus = model.SkuStatusNormal - } else if ybStatus == yinbaoapi.SkuStatusDisabled { - jxSkuStatus = model.SkuStatusDontSale - } else if ybStatus == yinbaoapi.SkuStatusDeleted { - jxSkuStatus = model.SkuStatusDeleted - } - return jxSkuStatus -} - -func vendorSku2Jx(result *jdshopapi.SearchSkuListResult) (skuName *partner.SkuNameInfo) { - if result == nil { - globals.SugarLogger.Warnf("vendorSku2Jx, strange result:%s", utils.Format4Output(result, true)) - return nil - } - skuName = &partner.SkuNameInfo{ - VendorNameID: utils.Int64ToStr(result.WareID), - SkuList: []*partner.SkuInfo{ - &partner.SkuInfo{ - StoreSkuInfo: partner.StoreSkuInfo{ - SkuID: utils.Str2Int(result.OuterID), - VendorSkuID: utils.Int64ToStr(result.SkuID), - VendorNameID: utils.Int64ToStr(result.WareID), - Stock: result.StockNum, - VendorPrice: utils.Float64TwoInt64(result.JdPrice * 100), - }, - Comment: result.SaleAttrs[0].AttrValueAlias[0], - }, - }, - } - return skuName -} - -func updateOrCreateCategories(storeCat *dao.SkuStoreCatInfo, isCreate bool) (status int64, err error) { - var createShopCategoryParams []*jdshopapi.CreateShopCategoryParam - result, err := api.JdShopAPI.FindShopCategories() - if err != nil { - return -1, err - } - for _, v := range result { - createShopCategoryParam := &jdshopapi.CreateShopCategoryParam{ - HomeShow: "0", - ID: utils.Int64ToStr(v.CID), - Open: "", - OrderNo: utils.Int2Str(v.OrderNo), - ParentID: utils.Int64ToStr(v.ParentCID), - Title: v.Name, - Type: jdshopapi.UpdateCatType, - } - createShopCategoryParams = append(createShopCategoryParams, createShopCategoryParam) - } - createShopCategoryParam2 := &jdshopapi.CreateShopCategoryParam{ - HomeShow: "0", - Open: "", - OrderNo: utils.Int2Str(storeCat.Seq), - ParentID: storeCat.ParentVendorCatID, - Title: storeCat.Name, - } - if isCreate { - createShopCategoryParam2.Type = jdshopapi.CreateCatType - createShopCategoryParam2.ID = "1" - createShopCategoryParams = append(createShopCategoryParams, createShopCategoryParam2) - } else { - for _, v := range createShopCategoryParams { - if v.ID == storeCat.VendorCatID { - v.Title = createShopCategoryParam2.Title - v.OrderNo = createShopCategoryParam2.OrderNo - } - } - } - status, err = api.JdShopAPI.CreateShopCategory(createShopCategoryParams) - return status, err -} - -func buildCreateWareParam(storeSku *dao.StoreSkuSyncInfo) (createSkuParamWare *jdshopapi.CreateSkuParamWare, createSkuParamSkus []*jdshopapi.CreateSkuParamSkus, err error) { - var ( - images []*jdshopapi.CreateSkuParamImages - vendorCatID int - ) - if storeSku.VendorCatID == "0" { - resultCat, _ := api.JdShopAPI.FindShopCategories() - for _, v := range resultCat { - if v.Name == storeSku.CategoryName { - vendorCatID = int(v.CID) - break - } - } - } else { - vendorCatID = utils.Str2Int(storeSku.VendorCatID) - } - name := filterSensitiveWord(storeSku.Name) - createSkuParamWare = &jdshopapi.CreateSkuParamWare{ - Title: name, - ShopCategorys: []int{vendorCatID}, - CategoryID: int(storeSku.VendorVendorCatID), - BrandID: jdshopapi.JxBrandId, - // TransportID: jdshopapi.TransportID, - WareStatus: 8, //上架待审核 - OuterID: utils.Int2Str(storeSku.NameID), - VenderID: jdshopapi.VenderID, - Length: 100, - Width: 100, - Height: 100, - Weight: 0.5, - JdPrice: jxutils.IntPrice2Standard(storeSku.UnitPrice), - // MarketPrice: jxutils.IntPrice2Standard(storeSku.UnitPrice), - // PromiseID: jdshopapi.JdsPromiseID, - } - - if storeSku.VendorVendorCatID != jdshopapi.JdsOtherMeatCatID { - createSkuParamWare.PromiseID = jdshopapi.JdsPromiseID - } - - if storeSku.VendorVendorCatID == jdshopapi.JdsBeefCatID { - createSkuParamWare.MultiCategoryID = jdshopapi.JdsBeefLastCatID - } - - //上传京东图片 - //规则,有两张就传两张,没有就重复传一张 - pic1, err := uploadImg(storeSku.Img, name, "1") - img1 := &jdshopapi.CreateSkuParamImages{ - ColorID: "0000000000", - ImgIndex: 1, - ImgURL: pic1, - } - img2 := &jdshopapi.CreateSkuParamImages{ - ColorID: "0000000000", - ImgIndex: 2, - } - if storeSku.Img2 == "" { - img2.ImgURL = pic1 - } else { - pic2, err2 := uploadImg(storeSku.Img, name, "2") - err = err2 - img2.ImgURL = pic2 - } - img3 := &jdshopapi.CreateSkuParamImages{ - ColorID: "0000000000", - ImgIndex: 3, - ImgURL: pic1, - } - images = append(images, img1) - images = append(images, img2) - images = append(images, img3) - createSkuParamWare.Images = images - //商品详情拼接 - var desc string - if storeSku.DescImg != "" { - pic3, err2 := uploadImg(storeSku.DescImg, name, "desc") - err = err2 - desc = `



` - } else { - desc = `



` - } - createSkuParamWare.MobileDesc = desc - createSkuParamWare.Introduction = desc - - //设置商品属性值 - var ( - attrIDs = make(map[string]int) //贮存方式,净含量,保质期IDs - zctjValueID int64 //贮存条件冷藏0-4的id - gcjkValueID int64 //国产,进口的id - lbValueID int64 //类别的ID - bcztValueID int64 //保存状态ID - rmsjValueID int64 //热卖时间ID - attrsProp []*jdshopapi.CreateSkuParamAttrs - ) - attrs, err := api.JdShopAPI.FindAttrs(int(storeSku.VendorVendorCatID)) - for _, v := range attrs { - if v.Name == "保质期" { - attrIDs[v.Name] = v.ID - } else if v.Name == "贮存条件" { - attrIDs[v.Name] = v.ID - } else if v.Name == "净含量" { - attrIDs[v.Name] = v.ID - } else if v.Name == "规格" { - attrIDs[v.Name] = v.ID - } else if v.Name == "国产/进口" { - attrIDs[v.Name] = v.ID - } else if v.Name == "类别" { - attrIDs[v.Name] = v.ID - } else if v.Name == "保存状态" { - attrIDs[v.Name] = v.ID - } else if v.Name == "热卖时间" { - attrIDs[v.Name] = v.ID - } - } - values, _, err := api.JdShopAPI.FindValuesByAttrId(attrIDs["贮存条件"]) - for _, v := range values { - if v.Name == "冷藏 0-4℃" { - zctjValueID = v.ID - } - } - if attrIDs["国产/进口"] != 0 { - values2, _, err2 := api.JdShopAPI.FindValuesByAttrId(attrIDs["国产/进口"]) - err = err2 - for _, v := range values2 { - if v.Name == "国产" { - gcjkValueID = v.ID - } - } - attrgcjk := &jdshopapi.CreateSkuParamAttrs{ - AttrID: utils.Int2Str(attrIDs["国产/进口"]), - AttrValues: []string{utils.Int64ToStr(gcjkValueID)}, - } - attrsProp = append(attrsProp, attrgcjk) - } - if attrIDs["保存状态"] != 0 { - values2, _, err2 := api.JdShopAPI.FindValuesByAttrId(attrIDs["保存状态"]) - err = err2 - for _, v := range values2 { - if v.Name == "冷藏" || v.Name == "活鲜" { - bcztValueID = v.ID - } - } - attrbczt := &jdshopapi.CreateSkuParamAttrs{ - AttrID: utils.Int2Str(attrIDs["保存状态"]), - AttrValues: []string{utils.Int64ToStr(bcztValueID)}, - } - attrsProp = append(attrsProp, attrbczt) - } - if attrIDs["热卖时间"] != 0 { - values2, _, err2 := api.JdShopAPI.FindValuesByAttrId(attrIDs["热卖时间"]) - err = err2 - for _, v := range values2 { - if v.Name == "12月" { - rmsjValueID = v.ID - } - } - attrrmsj := &jdshopapi.CreateSkuParamAttrs{ - AttrID: utils.Int2Str(attrIDs["热卖时间"]), - AttrValues: []string{utils.Int64ToStr(rmsjValueID)}, - } - attrsProp = append(attrsProp, attrrmsj) - } - if storeSku.VendorVendorCatID == jdshopapi.JdsBeefCatID { - var exValueID int64 - values2, _, err2 := api.JdShopAPI.FindValuesByAttrId(150390) - err = err2 - for _, v := range values2 { - if v.Name == "其它" { - exValueID = v.ID - } - } - attrex := &jdshopapi.CreateSkuParamAttrs{ - AttrID: utils.Int2Str(150390), - AttrValues: []string{utils.Int64ToStr(exValueID)}, - } - attrsProp = append(attrsProp, attrex) - } - attrZctj := &jdshopapi.CreateSkuParamAttrs{ - AttrID: utils.Int2Str(attrIDs["贮存条件"]), - AttrValues: []string{utils.Int64ToStr(zctjValueID)}, - } - attrJhl := &jdshopapi.CreateSkuParamAttrs{ - AttrID: utils.Int2Str(attrIDs["净含量"]), - AttrValues: []string{"0.5"}, - } - attrBzq := &jdshopapi.CreateSkuParamAttrs{ - AttrID: utils.Int2Str(attrIDs["保质期"]), - AttrValues: []string{"5"}, - } - attrsProp = append(attrsProp, attrZctj) - attrsProp = append(attrsProp, attrJhl) - attrsProp = append(attrsProp, attrBzq) - createSkuParamWare.MultiCateProps = attrsProp - var features = []*jdshopapi.CreateSkuParamFeatures{ - &jdshopapi.CreateSkuParamFeatures{ - Key: "is7ToReturn", //不支持7天无理由退货 - Value: "0", - }, - &jdshopapi.CreateSkuParamFeatures{ - Key: "tssp", //支持自提 - Value: "", - }, - // &jdshopapi.CreateSkuParamFeatures{ - // Key: "fdms", //分单? - // Value: "1", - // }, - } - createSkuParamWare.Features = features - //组合sku - var vendorPrice int64 = 0 - for _, v := range storeSku.StoreSkuSyncInfoJds { - var ( - ggValueID int64 //规格的属性id - attrsPropSku []*jdshopapi.CreateSkuParamAttrs - multiPropSku []*jdshopapi.CreateSkuParamAttrs - specQuality string - ) - valuesSku, maxNo, _ := api.JdShopAPI.FindValuesByAttrId(attrIDs["规格"]) - if v.SpecUnit == model.SpecUnitNames[1] || v.SpecUnit == model.SpecUnitNames[2] { - specQuality = strings.TrimRight(fmt.Sprintf("%.2f", float64(v.SpecQuality)), "0.") + v.SpecUnit - } else { - specQuality = utils.Float64ToStr(float64(v.SpecQuality)) + v.SpecUnit - } - if v.Comment != "" { - specQuality = v.Comment - } - for _, v := range valuesSku { - if v.Name == specQuality { - ggValueID = v.ID - } - } - if ggValueID == 0 { //说明没有建这个规格,要建上 - catID, _ := api.JdShopAPI.SaveVenderAttrValue(specQuality, attrIDs["规格"], int(storeSku.VendorVendorCatID), maxNo+1) - ggValueID = catID - } - attrSku := &jdshopapi.CreateSkuParamAttrs{ - AttrID: utils.Int2Str(attrIDs["规格"]), - AttrValues: []string{utils.Int64ToStr(ggValueID)}, - } - attrsPropSku = append(attrsPropSku, attrSku) - sku := &jdshopapi.CreateSkuParamSkus{ - JdPrice: jxutils.IntPrice2Standard(v.VendorPrice), - // StockNum: 9999, - Type: "com.jd.pop.ware.ic.api.domain.sku", - Type2: "com.jd.pop.ware.ic.api.domain.Sku", - OuterID: utils.Int2Str(v.SkuID), - } - sku.SaleAttrs = attrsPropSku - if attrIDs["类别"] != 0 { - values2, _, err2 := api.JdShopAPI.FindValuesByAttrId(attrIDs["类别"]) - err = err2 - lbValueID = values2[len(values2)-1].ID - attrlb := &jdshopapi.CreateSkuParamAttrs{ - AttrID: utils.Int2Str(attrIDs["类别"]), - AttrValues: []string{utils.Int64ToStr(lbValueID)}, - } - multiPropSku = append(multiPropSku, attrlb) - } - sku.MultiCateProps = multiPropSku - createSkuParamSkus = append(createSkuParamSkus, sku) - - if v.VendorPrice > vendorPrice { - vendorPrice = v.VendorPrice - } - if v.Status == model.SkuStatusNormal { - sku.StockNum = 9999 - } else { - sku.StockNum = 0 - } - } - //市场价固定500 - createSkuParamWare.MarketPrice = 500 - return createSkuParamWare, createSkuParamSkus, err -} - -//京东商城上传图片,若平台上已经有了这个图就直接拿来用了 -func uploadImg(img, name, index string) (imgURL string, err error) { - result, err := api.JdShopAPI.QueryPicture(name + index) - if len(result) > 0 { - imgURL = result[0].PictureURL - } else { - data, _, err := jxutils.DownloadFileByURL(img) - if err != nil { - return imgURL, err - } - uploadResult, err := api.JdShopAPI.UploadPicture(data, 0, name+index) - if err != nil { - return imgURL, err - } - imgURL = uploadResult.PictureURL - } - return imgURL, err -} - -func uploadImg2(img, name, index string) (imgURL string, err error) { - data, _, err := jxutils.DownloadFileByURL(img) - if err != nil { - return imgURL, err - } - uploadResult, err := api.JdShopAPI.UploadPicture(data, 0, name+index) - if err != nil { - return imgURL, err - } - imgURL = uploadResult.PictureURL - return imgURL, err -} - -func filterSensitiveWord(name string) (result string) { - for _, v := range jdshopapi.SensitiveWordMap { - if strings.Contains(name, v) { - return strings.ReplaceAll(name, v, "") - } - } - return name -} - -func buildUpdateSkusParam(storeSku *dao.StoreSkuSyncInfo, v *dao.StoreSkuSyncInfo, isCreate bool) (updateSkusParam *jdshopapi.UpdateSkusParam, err error) { - var ( - ggValueID int64 //规格的属性id - attrsPropSku []*jdshopapi.CreateSkuParamAttrs - skus []*jdshopapi.UpdateSkusParamSkus - multiPropSku []*jdshopapi.CreateSkuParamAttrs - specQuality string - ) - updateSkusParam = &jdshopapi.UpdateSkusParam{ - WareID: storeSku.JdsWareID, - } - sku := &jdshopapi.UpdateSkusParamSkus{ - WareID: storeSku.JdsWareID, - JdPrice: jxutils.IntPrice2Standard(v.VendorPrice), - Type: "com.jd.pop.ware.ic.api.domain.sku", - Type2: "com.jd.pop.ware.ic.api.domain.Sku", - OuterID: utils.Int2Str(v.SkuID), - } - //库存设置 - if v.StoreSkuStatus == model.SkuStatusNormal { - sku.StockNum = "9999" - } else { - sku.StockNum = "0" - } - //规格类别设置 - attrIDs := make(map[string]int) - attrs, err := api.JdShopAPI.FindAttrs(int(storeSku.VendorVendorCatID)) - for _, v := range attrs { - if v.Name == "规格" { - attrIDs[v.Name] = v.ID - } else if v.Name == "类别" { - attrIDs[v.Name] = v.ID - } - } - if attrIDs["类别"] != 0 { - values2, _, err2 := api.JdShopAPI.FindValuesByAttrId(attrIDs["类别"]) - err = err2 - lbValueID := values2[len(values2)-1].ID - attrlb := &jdshopapi.CreateSkuParamAttrs{ - AttrID: utils.Int2Str(attrIDs["类别"]), - AttrValues: []string{utils.Int64ToStr(lbValueID)}, - } - multiPropSku = append(multiPropSku, attrlb) - } - sku.MultiCateProps = multiPropSku - if v.SpecUnit == model.SpecUnitNames[1] || v.SpecUnit == model.SpecUnitNames[2] { - if math.Mod(float64(v.SpecQuality), 10) != 0 { - specQuality = strings.TrimRight(fmt.Sprintf("%.2f", float64(v.SpecQuality)), "0.") + v.SpecUnit - } else { - specQuality = utils.Float64ToStr(float64(v.SpecQuality)) + v.SpecUnit - } - } else { - specQuality = utils.Float64ToStr(float64(v.SpecQuality)) + v.SpecUnit - } - valuesSku, maxNo, _ := api.JdShopAPI.FindValuesByAttrId(attrIDs["规格"]) - if isCreate { - for _, vv := range valuesSku { - if vv.Name == specQuality { - ggValueID = vv.ID - break - } - } - if ggValueID == 0 { //说明没有建这个规格,要建上 - catID, _ := api.JdShopAPI.SaveVenderAttrValue(specQuality, attrIDs["规格"], int(storeSku.VendorVendorCatID), maxNo+1) - ggValueID = catID - } - attrSku := &jdshopapi.CreateSkuParamAttrs{ - AttrID: utils.Int2Str(attrIDs["规格"]), - AttrValues: []string{utils.Int64ToStr(ggValueID)}, - } - attrsPropSku = append(attrsPropSku, attrSku) - sku.SaleAttrs = attrsPropSku - } else { - vendorSku, err2 := api.JdShopAPI.FindSkuById(utils.Str2Int64(v.VendorSkuID)) - err = err2 - vendorAttrValue := vendorSku.SaleAttrs[0].AttrValueAlias[0] - if v.Comment != "" { - specQuality = v.Comment - } - if v.Comment != vendorAttrValue { - err = api.JdShopAPI.UpdateWareSaleAttrvalueAlias(&jdshopapi.UpdateWareSaleAttrvalueAliasParam{ - WareID: v.JdsWareID, - Props: []*jdshopapi.CreateSkuParamAttrs2{ - &jdshopapi.CreateSkuParamAttrs2{ - AttrID: vendorSku.SaleAttrs[0].AttrID, - AttrValues: []string{vendorSku.SaleAttrs[0].AttrValues[0]}, - AttrValueAlias: []string{specQuality}, - Type: "com.jd.pop.ware.ic.api.domain.prop", - Type2: "com.jd.pop.ware.ic.api.domain.Prop", - }, - }, - }) - sku.SkuID = utils.Str2Int64(v.VendorSkuID) - } - attrSku := &jdshopapi.CreateSkuParamAttrs{ - AttrID: vendorSku.SaleAttrs[0].AttrID, - AttrValues: []string{vendorSku.SaleAttrs[0].AttrValues[0]}, - } - attrsPropSku = append(attrsPropSku, attrSku) - sku.SaleAttrs = attrsPropSku - } - skus = append(skus, sku) - updateSkusParam.Skus = skus - return updateSkusParam, err -} diff --git a/business/partner/purchase/jx/act.go b/business/partner/purchase/jx/act.go deleted file mode 100644 index 6894b5b4a..000000000 --- a/business/partner/purchase/jx/act.go +++ /dev/null @@ -1,11 +0,0 @@ -package jx - -import ( - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" -) - -func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSkuList []*model.ActStoreSku2) (err error) { - return err -} diff --git a/business/partner/purchase/jx/jx.go b/business/partner/purchase/jx/jx.go deleted file mode 100644 index 24dc7beeb..000000000 --- a/business/partner/purchase/jx/jx.go +++ /dev/null @@ -1,34 +0,0 @@ -package jx - -import ( - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" -) - -type PurchaseHandler struct { - partner.BasePurchasePlatform -} - -var ( - CurPurchaseHandler *PurchaseHandler -) - -func init() { - globals.SugarLogger.Debug("init jx") - if true { - CurPurchaseHandler = new(PurchaseHandler) - // 不能注册京西 - // partner.RegisterPurchasePlatform(CurPurchaseHandler) - partner.RegisterPurchaseOrderHandler(CurPurchaseHandler.GetVendorID(), CurPurchaseHandler) - } -} - -func (c *PurchaseHandler) GetVendorID() int { - return model.VendorIDJX -} - -func (p *PurchaseHandler) UploadImg(ctx *jxcontext.Context, vendorOrgCode, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) { - return imgHint, err -} diff --git a/business/partner/purchase/jx/localjx/order.go b/business/partner/purchase/jx/localjx/order.go deleted file mode 100644 index c00cf41c5..000000000 --- a/business/partner/purchase/jx/localjx/order.go +++ /dev/null @@ -1,2134 +0,0 @@ -package localjx - -import ( - "fmt" - "math" - "regexp" - "strings" - "time" - - "git.rosy.net.cn/baseapi/platformapi/jdshopapi" - - "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" - - "git.rosy.net.cn/jx-callback/business/jxstore/event" - "git.rosy.net.cn/jx-callback/globals" - - "git.rosy.net.cn/baseapi/platformapi/jdeclpapi" - "git.rosy.net.cn/baseapi/platformapi/wxpayapi" - - "git.rosy.net.cn/jx-callback/globals/api" - - "git.rosy.net.cn/jx-callback/business/jxutils/ddmsg" - "git.rosy.net.cn/jx-callback/business/jxutils/netprinter" - - "git.rosy.net.cn/baseapi/platformapi/dingdingapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/baseapi/utils/errlist" - "git.rosy.net.cn/jx-callback/business/jxstore/cms" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" -) - -const ( - OrderCreateTypePre = 0 // 预创建 - OrderCreateTypeNormal = 1 // 正常创建 - - PayWaitingTime = 10 * time.Minute // 等待支付的最长时间 - DingShiDaMinTime = 1 * time.Hour - - specialStoreID = 100274 - specialFreightPrice = 1500 - - wxAppID = "wx4b5930c13f8b1170" - - autoCancelOrderReason = "支付超时,系统自动取消!" - cancelMatterOrderReason = "失败重发!" - settleDiscountActRefundReason = "守价订单生成补退款" - - splitMatterOrderMinWeight = 4500 //物料订单分包最少要4.5kg - jxwxfMatterEclpID = "EMG4418113943423" //京西五香粉物料编码 -) - -type JxSkuInfo struct { - SkuID int `json:"skuID"` - Count int `json:"count"` - - Price int64 `json:"price,omitempty"` // 原价 - SalePrice int64 `json:"salePrice,omitempty"` // 售卖价 - - Name string `json:"name"` - Weight int `json:"weight"` - GroupSign bool `json:"groupSign"` - - DefendPrice int64 `json:"defendPrice"` //守价 -} - -type JxSkuInfo2 struct { - SkuID int `json:"skuID"` - Count int `json:"count"` - - Price int64 `json:"price,omitempty"` // 原价 - SalePrice int64 `json:"salePrice,omitempty"` // 售卖价 - - Name string `json:"name"` - Weight int `json:"weight"` - GroupSign bool `json:"groupSign"` -} - -type JxSkuInfoList []*JxSkuInfo - -func (l JxSkuInfoList) Len() int { - return len(l) -} - -func (l JxSkuInfoList) Less(i, j int) bool { - if l[i].SkuID == l[j].SkuID { - return l[i].SalePrice < l[j].SalePrice - } - return l[i].SkuID < l[j].SkuID -} - -func (l JxSkuInfoList) Swap(i, j int) { - l[i], l[j] = l[j], l[i] -} - -type JxOrderInfo struct { - BuyerComment string `json:"buyerComment"` - StoreID int `json:"storeID"` - Skus []*JxSkuInfo `json:"skus"` - - ExpectedDeliveredTimestamp int64 `json:"expectedDeliveredTimestamp"` // 预期送达时间 - - TotalPrice int64 `json:"totalPrice"` // 单位为分 订单总价 - FreightPrice int64 `json:"freightPrice"` // 单位为分 订单配送费 - OrderPrice int64 `json:"orderPrice"` // 单位为分 订单商品价格 - ActualPayPrice int64 `json:"actualPayPrice"` // 单位为分 顾客实际支付 - - OrderID int64 `json:"orderID"` - StoreName string `json:"storeName"` - Weight int `json:"weight"` - FromStoreID int `json:"fromStoreID"` - EarningType int `json:"earningType"` - OrderType int `json:"orderType"` - IsBuyNowPrice int `json:"isBuyNowPrice"` - IsPriceDefend int `json:"isPriceDefend"` - OrderID2 string `json:"-"` - UserID string `json:"userID"` -} - -type DeliveryTimeItem struct { - ViewTime string `json:"viewTime"` - UnixTime int64 `json:"unixTime"` - ViewShippingFee string `json:"viewShippingFee"` -} - -type DeliveryDayTimeInfo struct { - Date string `json:"date"` - TimeList []*DeliveryTimeItem `json:"timeList"` -} - -type MatterOrderStatus struct { - Time time.Time `json:"time"` - Status string `json:"status"` - Name string `json:"name"` - Sign int `sign` -} - -var ( - weekdayMap = map[int]string{ - 1: "一", - 2: "二", - 3: "三", - 4: "四", - 5: "五", - 6: "六", - 0: "日", - } - dayList = []string{"今天", "明天", "后天"} - - bagMap = map[int]int{ - 6039382: 100, - 6039383: 200, - 6039384: 200, - 6039387: 200, - 6039390: 200, - } - - regexpCnameAndCmobile = regexp.MustCompile(`配送员,(.*),手机号,(.*)`) - regexpCnameAndCmobile2 = regexp.MustCompile(`(快递员:(.*),联系电话:(.*))`) - - bagSkuMap = map[int]int{ //京西物料袋子skuid - 6039382: 6039382, - 6039383: 6039383, - 6039384: 6039384, - 6039387: 6039387, - 6039390: 6039390, - } -) - -func init() { -} - -func GetMyOrders(ctx *jxcontext.Context, fromDateStr, toDateStr string, params map[string]interface{}, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) { - db := dao.GetDB() - params["vendorIDs"] = string(utils.MustMarshal([]int{model.VendorIDJX})) - tmpOrderList, totalCount, err := dao.GetOrders(db, nil, false, false, fromDateStr, toDateStr, false, nil, false, ctx.GetUserID(), params, offset, pageSize) - if err == nil { - pagedInfo = &model.PagedInfo{ - TotalCount: totalCount, - } - if totalCount > 0 { - var ids []int64 - for _, v := range tmpOrderList { - ids = append(ids, v.ID) - } - orderSkuList, _, err2 := dao.GetOrders(db, ids, true, false, "", "", false, nil, false, "", nil, 0, model.UnlimitedPageSize) - if err = err2; err == nil { - orderMap := make(map[string]*model.GoodsOrderExt) - var orderList []*model.GoodsOrderExt - for _, v := range orderSkuList { - universalOrderID := jxutils.ComposeUniversalOrderID(v.VendorOrderID, v.VendorID) - if orderMap[universalOrderID] == nil { - orderMap[universalOrderID] = v - orderList = append(orderList, v) - } - orderMap[universalOrderID].SkuList = append(orderMap[universalOrderID].SkuList, &v.ShortSkuInfo) - } - pagedInfo.Data = orderList - } else { - pagedInfo = nil - } - } - } - return pagedInfo, err -} - -func GetMyAfsOrders(ctx *jxcontext.Context, vendorOrderID, afsOrderID, userID, fromTime, toTime string, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) { - afsOrderList, totalCount, err := dao.GetAfsOrdersByPage(dao.GetDB(), vendorOrderID, afsOrderID, userID, utils.Str2Time(fromTime), utils.Str2Time(toTime), offset, pageSize) - pagedInfo = &model.PagedInfo{ - TotalCount: totalCount, - Data: afsOrderList, - } - return pagedInfo, err -} - -func GetMyOrderCountInfo(ctx *jxcontext.Context, fromDate, toDate time.Time, statuss []int) (countInfo []*model.GoodsOrderCountInfo, err error) { - countInfo, err = dao.GetMyOrderCountInfo(dao.GetDB(), ctx.GetUserID(), fromDate, toDate, statuss) - return countInfo, err -} - -//fromStoreID 为0 表示非物料订单(京西商城订单等) -//fromStoreID 为 门店ID ,表示是物料订单,fromStoreID表示是哪个门店申请的物料,或者进货方门店 -//fromStoreID 为-1 表示也是物料订单,但是不是门店申请,是个人申请的 -//fromStoreID 在后面 generateOrder中有用 -//IsAuto 是否是守价结算而自动创建的守价订单 -func CreateOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, addressID int64, createType int, fromStoreID int, IsDeliverySelf bool) (outJxOrder *JxOrderInfo, err error) { - outJxOrder, deliveryAddress, err := generateOrder(ctx, jxOrder, addressID, fromStoreID, "", IsDeliverySelf) - if err != nil { - return nil, err - } - if jxOrder.OrderType == model.OrderTypeMatter { - checkMatterDeliveryAddress(deliveryAddress) - } - if createType == OrderCreateTypeNormal { - if jxOrder.OrderType == model.OrderTypeDefendPrice && jxOrder.IsPriceDefend != model.YES { - vendorOrderID := buildDefendPriceOrder(ctx, jxOrder, addressID) - outJxOrder.OrderID = utils.Str2Int64(vendorOrderID) - return outJxOrder, err - } - if outJxOrder.TotalPrice != jxOrder.TotalPrice && jxOrder.IsPriceDefend != model.YES { - return nil, fmt.Errorf("商品或配送信息发生改变,请重新下单") - } - if jxOrder.IsPriceDefend == model.YES { - outJxOrder.OrderID = jxOrder.OrderID - } else { - outJxOrder.OrderID = jxutils.GenOrderNo() - } - order, err2 := jxOrder2GoodsOrder(ctx, outJxOrder, deliveryAddress, "", IsDeliverySelf) - if err = err2; err == nil { - order.AddressID = addressID - if jxOrder.IsPriceDefend == model.YES { - order.Status = model.OrderStatusAccepted - } else { - order.Status = model.OrderStatusWait4Pay - } - callNewOrder(order) - } - } - return outJxOrder, err -} - -func buildDefendPriceOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, addressID int64) (vendorOrderID string) { - var ( - issue = 0 - db = dao.GetDB() - ) - issue = jxutils.GetDefendPriceIssue() - priceDefendOrder := &model.PriceDefendOrder{ - VendorOrderID: utils.Int64ToStr(jxutils.GenOrderNo()), - StoreID: jxOrder.StoreID, - SkuID: jxOrder.Skus[0].SkuID, - AddressID: addressID, - Count: jxOrder.Skus[0].Count, - DefendPrice: jxOrder.Skus[0].DefendPrice, - OriginPrice: jxOrder.Skus[0].Price, - IsBuyNowPrice: jxOrder.IsBuyNowPrice, - Issue: issue, - IsSuccess: model.NO, //默认是不成功 - IsPay: model.NO, - } - dao.WrapAddIDCULDEntity(priceDefendOrder, ctx.GetUserName()) - priceDefendOrder.ActualPayPrice = int64(priceDefendOrder.Count)*jxOrder.Skus[0].Price + jxOrder.FreightPrice - dao.CreateEntity(db, priceDefendOrder) - return priceDefendOrder.VendorOrderID -} - -// 买家取消(或申请取消)订单 -func BuyerCancelOrder(ctx *jxcontext.Context, orderID int64, reason string) (canceled bool, err error) { - order, err := partner.CurOrderManager.LoadOrder(utils.Int64ToStr(orderID), model.VendorIDJX) - if err == nil { - if order.Status < model.OrderStatusNew { - order.Status = model.OrderStatusCanceled - order.VendorStatus = utils.Int2Str(model.OrderStatusCanceled) - if err = partner.CurOrderManager.UpdateOrderFields(order, []string{model.FieldStatus, "VendorStatus"}); err == nil { - canceled = true - } - } else { - err = fmt.Errorf("暂不支持自行取消订单,请联系商家取消") - // err = changeOrderStatus(utils.Int64ToStr(orderID), model.OrderStatusApplyCancel, fmt.Sprintf("用户%s主动取消", ctx.GetUserName())) - } - } - return canceled, err -} - -func Pay4Order(ctx *jxcontext.Context, orderID int64, payType int, vendorPayType string) (orderPay *model.OrderPay, err error) { - var ( - db = dao.GetDB() - ) - order, err := partner.CurOrderManager.LoadOrder(utils.Int64ToStr(orderID), model.VendorIDJX) - if err == nil { - switch payType { - case model.PayTypeWX: - if orderPay, err = pay4OrderByWX(ctx, order, vendorPayType); err == nil { - dao.WrapAddIDCULDEntity(orderPay, ctx.GetUserName()) - err = dao.CreateEntity(dao.GetDB(), orderPay) - } - case model.PayTypeTL: - if orderPay, err = pay4OrderByTL(ctx, order, payType, vendorPayType); err == nil && orderPay != nil { - dao.WrapAddIDCULDEntity(orderPay, ctx.GetUserName()) - err = dao.CreateEntity(dao.GetDB(), orderPay) - } - default: - err = fmt.Errorf("支付方式:%d当前不支持", payType) - } - } else { - priceDefendOrders, _ := dao.GetPriceDefendOrder(db, utils.Int64ToStr(orderID), nil, nil, []int{jxutils.GetDefendPriceIssue()}, 0, -1, -1, 0, "", utils.ZeroTimeValue, utils.ZeroTimeValue, false) - if len(priceDefendOrders) == 0 { - err = fmt.Errorf("未查询到待支付订单!order_id: %v", orderID) - } - order2 := &model.GoodsOrder{ - VendorOrderID: priceDefendOrders[0].VendorOrderID, - ActualPayPrice: priceDefendOrders[0].ActualPayPrice, - VendorID: model.VendorIDJX, - } - if orderPay, err = pay4OrderByTL(ctx, order2, payType, vendorPayType); err == nil && orderPay != nil { - dao.WrapAddIDCULDEntity(orderPay, ctx.GetUserName()) - err = dao.CreateEntity(dao.GetDB(), orderPay) - } - } - return orderPay, err -} - -func Pay4User(ctx *jxcontext.Context, thingID, payType int, vendorPayType string) (orderPay *model.OrderPay, err error) { - var ( - db = dao.GetDB() - order *model.GoodsOrder - dicountCards []*model.DiscountCard - vendorOrderID string - ) - switch payType { - case model.PayTypeTL_DiscountCard: - if configList, err := dao.QueryConfigs(db, "会员折扣卡", model.ConfigTypeDiscountCard, ""); err == nil { - jxutils.Strings2Objs(configList[0].Value, &dicountCards) - if err != nil { - return nil, err - } - discountCard := findDiscountCard(dicountCards, thingID) - flag, userMemberOrigin, err := checkMember(db, ctx.GetUserID(), discountCard) - if err != nil { - return nil, err - } - vendorOrderID = utils.Int64ToStr(jxutils.GenOrderNo()) - order = &model.GoodsOrder{ - VendorOrderID: vendorOrderID, - ActualPayPrice: int64(discountCard.Price), - VendorID: model.VendorIDJX, - } - if orderPay, err = pay4OrderByTL(ctx, order, payType, vendorPayType); err == nil && orderPay != nil { - dao.WrapAddIDCULDEntity(orderPay, ctx.GetUserName()) - err = dao.CreateEntity(dao.GetDB(), orderPay) - } - userMember := &model.UserMember{ - VendorOrderID: vendorOrderID, - UserID: ctx.GetUserID(), - MemberType: model.MemberTypeDiscountCard, - EndAt: utils.Str2Time(time.Now().AddDate(0, 1, 0).AddDate(0, 0, -1).Format("2006-01-02") + " 23:59:59"), - MemberTypeID: thingID, - IsPay: model.NO, - } - dao.WrapAddIDCULDEntity(userMember, ctx.GetUserName()) - if flag == 0 { - dao.CreateEntity(db, userMember) - } else if flag == 1 { - userMemberOrigin.EndAt = userMemberOrigin.EndAt.AddDate(0, 1, 0) - dao.UpdateEntity(db, userMemberOrigin, "EndAt") - } - } - default: - err = fmt.Errorf("支付方式:%d当前不支持", payType) - } - return orderPay, err -} - -//flag -//0 正常购买 -//1 续费 -//-1 不能购买 -func checkMember(db *dao.DaoDB, userID string, discountCard *model.DiscountCard) (flag int, userMember *model.UserMember, err error) { - userMembers, err := dao.GetUserMember(db, userID, "", model.MemberTypeDiscountCard, model.YES) - if len(userMembers) > 0 { - userMember = userMembers[0] - if userMember.ID < discountCard.ID { - return 0, userMember, err - } else if userMember.ID == discountCard.ID { - return 1, userMember, err - } else { - return -1, userMember, fmt.Errorf("已购买更高档次的会员,无法继续购买!") - } - } - return 0, userMember, err -} - -func time2ShortTimeStr(t time.Time) string { - return t.Format("15:04") -} - -func findDiscountCard(dicountCards []*model.DiscountCard, thingID int) (dicountCard *model.DiscountCard) { - for _, v := range dicountCards { - if v.ID == thingID { - return v - } - } - return dicountCard -} - -func GetAvailableDeliverTime(ctx *jxcontext.Context, storeID int) (deliverTimerList []*DeliveryDayTimeInfo, err error) { - db := dao.GetDB() - storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDJX) - if err != nil { - return nil, err - } - if storeDetail.Status != model.StoreStatusOpened { - return nil, fmt.Errorf("门店:%s不是营业状态,状态是:%s", storeDetail.Name, model.StoreStatusName[storeDetail.Status]) - } - // now := utils.Str2Time(timeStr) - now := time.Now() - // beginDate := utils.Time2Date(utils.Str2Time(timeStr)) - beginDate := utils.Time2Date(now) - minDingShiDaTime := now.Add(DingShiDaMinTime) - viewShippingFee := "约6.6元配送费" - if storeID == specialStoreID { - viewShippingFee = "免费配送" - } - var isOrder = false - if storeDetail.IsOrder == model.YES { - isOrder = true - beginDate = beginDate.AddDate(0, 0, 1) - } - for i, dayStr := range dayList { - if isOrder { - isOrder = false - continue - } - openTime1 := jxutils.JxOperationTime2TimeByDate(storeDetail.OpenTime1, beginDate) - closeTime1 := jxutils.JxOperationTime2TimeByDate(storeDetail.CloseTime1, beginDate) - openTime2 := jxutils.JxOperationTime2TimeByDate(storeDetail.OpenTime2, beginDate) - closeTime2 := jxutils.JxOperationTime2TimeByDate(storeDetail.CloseTime2, beginDate) - timeInfo := &DeliveryDayTimeInfo{ - Date: fmt.Sprintf("%s(周%s)", dayStr, weekdayMap[int(beginDate.Weekday())]), - } - if i == 0 { - if isTimeInOpTime(storeDetail.OpenTime1, storeDetail.CloseTime1, storeDetail.OpenTime2, storeDetail.CloseTime2, now) { - timeInfo.TimeList = append(timeInfo.TimeList, &DeliveryTimeItem{ - ViewTime: "立即送出", - UnixTime: 0, - ViewShippingFee: viewShippingFee, - }) - } - } - for j := 0; j < 24*3; j++ { - deliveryTime := beginDate.Add(time.Duration(j) * 20 * time.Minute) - if deliveryTime.Sub(minDingShiDaTime) >= 0 { - if (deliveryTime.Sub(openTime1) >= 0 && deliveryTime.Sub(closeTime1) <= 0) || - (storeDetail.OpenTime2 > 0 && deliveryTime.Sub(openTime2) >= 0 && deliveryTime.Sub(closeTime2) <= 0) { - timeInfo.TimeList = append(timeInfo.TimeList, &DeliveryTimeItem{ - ViewTime: time2ShortTimeStr(deliveryTime), - UnixTime: deliveryTime.Unix(), - ViewShippingFee: viewShippingFee, - }) - } - } - } - if len(timeInfo.TimeList) > 0 { - deliverTimerList = append(deliverTimerList, timeInfo) - } - beginDate = beginDate.Add(24 * time.Hour) - } - if len(deliverTimerList) > 0 { - if deliverTimerList[0].TimeList[0].UnixTime != 0 { - deliverTimerList[0].TimeList[0].ViewTime = "营业即送" - } - } - return deliverTimerList, err -} - -func OnPayFinished(orderPay *model.OrderPay) (err error) { - order, err := partner.CurOrderManager.LoadOrder(orderPay.VendorOrderID, orderPay.VendorID) - if err == nil { - db := dao.GetDB() - dao.UpdateEntity(db, orderPay) - if count, err2 := dao.GetJxOrderCount(db, jxutils.GetSaleStoreIDFromOrder(order), order.VendorOrderID, order.OrderCreatedAt); err2 == nil { - order.OrderSeq = count + 1 - partner.CurOrderManager.UpdateOrderFields(order, []string{"OrderSeq"}) - } - order.Status = model.OrderStatusNew - order.VendorStatus = utils.Int2Str(model.OrderStatusNew) - order.StatusTime = *orderPay.PayFinishedAt - err = callNewOrder(order) - //如果是物料的订单,直接到拣货完成,配送中的状态 - if order.OrderType != model.OrderTypeNormal { - // if order.FromStoreID != 0 { - if order.OrderType != model.OrderTypeDefendPrice { - netprinter.PrintOrderByOrder(jxcontext.AdminCtx, order) - } - PickupGoods(order, false, "jxadmin") - // } - } - } else { - switch orderPay.PayType { - case model.PayTypeTL_DiscountCard: - userMembers, _ := dao.GetUserMember(dao.GetDB(), "", orderPay.VendorOrderID, model.MemberTypeDiscountCard, model.NO) - if len(userMembers) > 0 { - userMembers[0].IsPay = model.YES - dao.UpdateEntity(dao.GetDB(), userMembers[0], "IsPay") - err = nil - } - default: - priceDefendOrders, _ := dao.GetPriceDefendOrder(dao.GetDB(), orderPay.VendorOrderID, nil, nil, []int{jxutils.GetDefendPriceIssue()}, 0, -1, -1, 0, "", utils.ZeroTimeValue, utils.ZeroTimeValue, false) - if len(priceDefendOrders) > 0 { - priceDefendOrders[0].IsPay = model.YES - dao.UpdateEntity(dao.GetDB(), priceDefendOrders[0], "IsPay") - err = nil - } - } - } - return err -} - -func GenPayOrderID(order *model.GoodsOrder) (payOrderID int64) { - return utils.Str2Int64(order.VendorOrderID) -} - -func GenRefundID(order *model.GoodsOrder) (refundID int64) { - const suffix = 100000 - refundID = utils.Str2Int64(order.VendorOrderID) * suffix - refundID += int64(time.Now().Sub(order.OrderFinishedAt) / time.Minute) - return refundID -} - -func formalizeSkus(skus []*JxSkuInfo) (outSkus []*JxSkuInfo) { - skuMap := make(map[int]int) - for _, v := range skus { - skuMap[v.SkuID] += v.Count - } - for skuID, skuCount := range skuMap { - outSkus = append(outSkus, &JxSkuInfo{ - SkuID: skuID, - Count: skuCount, - }) - } - return outSkus -} - -func isTimeInOpTime(openTime1, closeTime1, openTime2, closeTime2 int16, time2Check time.Time) bool { - timeStrList := []string{ - jxutils.OperationTime2StrWithSecond(openTime1), - jxutils.OperationTime2StrWithSecond(closeTime1), - } - if openTime1 > 0 { - timeStrList = append(timeStrList, - jxutils.OperationTime2StrWithSecond(openTime2), - jxutils.OperationTime2StrWithSecond(closeTime2), - ) - } - checkTimeStr := utils.Time2TimeStr(time2Check) - for i := 0; i < len(timeStrList); i += 2 { - if checkTimeStr >= timeStrList[i] && checkTimeStr <= timeStrList[i+1] { - return true - } - } - return false -} - -func generateOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, addressID int64, fromStoreID int, userID string, IsDeliverySelf bool) (outJxOrder *JxOrderInfo, deliveryAddress *dao.UserDeliveryAddressEx, err error) { - db := dao.GetDB() - if jxOrder.StoreID == 0 { - return nil, nil, fmt.Errorf("没有指定门店信息") - } - // 配送范围检查 - storeDetail, err := dao.GetStoreDetail(db, jxOrder.StoreID, model.VendorIDJX) - if err != nil { - return nil, nil, err - } - var addressList []*dao.UserDeliveryAddressEx - if userID == "" { - addressList, _, err = dao.QueryUserDeliveryAddress(db, addressID, nil, 0, 0) - } else { - addressList, _, err = dao.QueryUserDeliveryAddress(db, addressID, []string{userID}, 0, 0) - } - if err != nil { - return nil, nil, err - } - if len(addressList) == 0 { - return nil, nil, fmt.Errorf("地址ID不正确") - } - deliveryAddress = addressList[0] - if distance := jxutils.Point2StoreDistance(deliveryAddress.Lng, deliveryAddress.Lat, storeDetail.Lng, storeDetail.Lat, storeDetail.DeliveryRangeType, storeDetail.DeliveryRange); distance == 0 { - return nil, nil, fmt.Errorf("当前送货地址不在门店%s的配送范围", storeDetail.Name) - } - - //结算类型 - if storeDetail.PayPercentage < 50 { - jxOrder.EarningType = model.EarningTypePoints - } else { - jxOrder.EarningType = model.EarningTypeQuote - } - - // 营业状态及时间检查 - if storeDetail.Status != model.StoreStatusOpened { // model.StoreStatusDisabled { - return nil, nil, fmt.Errorf("门店:%s状态是:%s", storeDetail.Name, model.StoreStatusName[storeDetail.Status]) - } - checkTime := time.Now() - if jxOrder.ExpectedDeliveredTimestamp == 0 { - if storeDetail.Status != model.StoreStatusOpened { - return nil, nil, fmt.Errorf("门店:%s不是营业状态,状态是:%s", storeDetail.Name, model.StoreStatusName[storeDetail.Status]) - } - } else { - checkTime = utils.Timestamp2Time(jxOrder.ExpectedDeliveredTimestamp) - if checkTime.Sub(time.Now()) < DingShiDaMinTime { - return nil, nil, fmt.Errorf("预订单只能在1小时后") - } - if utils.Time2Date(time.Now()).Sub(utils.Time2Date(checkTime)) > 24*time.Hour { - return nil, nil, fmt.Errorf("预订单只能预定当天或第二天") - } - } - outJxOrder2 := *jxOrder - outJxOrder2.Skus = nil - outJxOrder2.OrderPrice = 0 - outJxOrder2.Weight = 0 - outJxOrder = &outJxOrder2 - outJxOrder.StoreName = storeDetail.Name - skus := formalizeSkus(jxOrder.Skus) - // 允许空商品列表(一般用于测试配送地址,门店信息是否合适) - if len(skus) > 0 { - var skuIDs []int - for _, v := range skus { - skuIDs = append(skuIDs, v.SkuID) - } - storeSkuInfo, err := cms.GetStoreSkus(ctx, jxOrder.StoreID, skuIDs, true, "", true, false, map[string]interface{}{ - "actVendorID": model.VendorIDJX, - }, 0, model.UnlimitedPageSize) - if err != nil { - return nil, nil, err - } - storeSkuMap := make(map[int]*dao.StoreSkuExt) - for _, v1 := range storeSkuInfo.SkuNames { - for _, v2 := range v1.Skus { - if v2.StoreSkuStatus != model.SkuStatusNormal { - return nil, nil, fmt.Errorf("此商品已下架,请联系管理员!skuID:[%v]", v2.SkuID) - } - storeSkuMap[v2.SkuID] = v2 - } - } - - skuList, err := dao.GetSkus(db, skuIDs, nil, nil, nil, nil) - if err != nil { - return nil, nil, err - } - skuMap := make(map[int]*model.SkuAndName) - for _, v := range skuList { - // if fromStoreID != 0 { - - // } - if jxOrder.OrderType == model.OrderTypeMatter { - if v.EclpID == "" { - return nil, nil, fmt.Errorf("此商品物料编码为空,请联系管理员!skuID:[%v]", v.ID) - } - } - skuMap[v.ID] = v - } - var ( - result *orderman.OrderCount - sum int //申请物料的店的最近销量,以下会根据销量计算具体袋子的价格 - flag = false //新店袋子拆分当个参数 - ) - // if fromStoreID != 0 && fromStoreID != -1 { - // result, _ = orderman.GetMatterStoreOrderCount(nil, fromStoreID) - // sum = result.Count - // } - if jxOrder.OrderType == model.OrderTypeMatter && fromStoreID != -1 { - result, _ = orderman.GetMatterStoreOrderCount(nil, fromStoreID) - sum = result.Count - } - if jxOrder.Weight == 0 { - for _, v := range jxOrder.Skus { - v.Weight = storeSkuMap[v.SkuID].Weight - jxOrder.Weight += v.Weight * v.Count - } - } - for _, v := range skus { - if storeSkuBind := storeSkuMap[v.SkuID]; storeSkuBind != nil { - // if fromStoreID != 0 { - if jxOrder.OrderType == model.OrderTypeMatter { - result2, _ := api.JdEclpAPI.QueryStock(storeSkuBind.EclpID) - if len(result2) > 0 { - if result2[0].UsableNum < v.Count { - return nil, nil, fmt.Errorf("此商品库存不足无法购买,请联系管理员!skuID:[%v]", v.SkuID) - } - } - } - // } - if sku := skuMap[v.SkuID]; sku != nil { - jxSku := &JxSkuInfo{ - SkuID: v.SkuID, - Price: int64(storeSkuBind.JxPrice), - Count: v.Count, - SalePrice: int64(storeSkuBind.JxPrice), // todo 考虑活动价 - Weight: sku.Weight, - Name: jxutils.ComposeSkuName(sku.Prefix, sku.Name, sku.Comment, sku.Unit, sku.SpecQuality, sku.SpecUnit, 0, sku.ExPrefix, sku.ExPrefixBegin, sku.ExPrefixEnd), - } - if fromStoreID != -1 && storeSkuBind.ActType != model.ActSkuDiscount { - //活动商品要拆分,一分钱的单独列一个(count为1),正常价格的列在一起(count叠加) - if storeSkuBind.ActPrice != 0 && storeSkuBind.ActPrice < storeSkuBind.JxPrice { - jxSku.SalePrice = int64(storeSkuBind.ActPrice) - jxSku.Count = 1 - - outJxOrder.Skus = append(outJxOrder.Skus, jxSku) - outJxOrder.OrderPrice += int64(jxSku.Count) * jxSku.SalePrice - outJxOrder.Weight += jxSku.Count * jxSku.Weight - if v.Count-1 > 0 { - jxSku2 := *jxSku - jxSku2.SalePrice = jxSku.Price - jxSku2.Count = v.Count - 1 - - jxSku = &jxSku2 - } else { - jxSku = nil - } - } - } else if storeSkuBind.ActType == model.ActSkuDiscount && jxOrder.OrderType != model.OrderTypeDefendPrice { //守价的订单是支付原价 - jxSku.SalePrice = int64(storeSkuBind.ActPrice) - } - if jxSku != nil { - // if fromStoreID == 0 || fromStoreID == -1 { - if jxOrder.OrderType != model.OrderTypeMatter || (jxOrder.OrderType == model.OrderTypeMatter && fromStoreID == -1) { - outJxOrder.Skus = append(outJxOrder.Skus, jxSku) - outJxOrder.OrderPrice += int64(jxSku.Count) * jxSku.SalePrice - } else { //以下else为物料订单袋子金额和数量处理 - if !result.Flag { //只要flag是false就按原价申请,是true再按订单量 - outJxOrder.Skus = append(outJxOrder.Skus, jxSku) - outJxOrder.OrderPrice += int64(jxSku.Count) * jxSku.SalePrice - } else { - if result.Count == 0 { //这个条件被认为是新店,袋子限量 - if bagMap[jxSku.SkuID] != 0 { //如果他买了袋子,第一个袋子算1分钱,其余按原价(包括所有袋子) - if !flag { - salePirce := jxSku.SalePrice - count := jxSku.Count - jxSku.SalePrice = 1 - jxSku.Count = 1 - outJxOrder.Skus = append(outJxOrder.Skus, jxSku) - outJxOrder.OrderPrice += int64(jxSku.Count) * jxSku.SalePrice - if count > 1 { - jxSku2 := *jxSku - jxSku2.SalePrice = salePirce - jxSku2.Count = count - 1 - outJxOrder.Skus = append(outJxOrder.Skus, &jxSku2) - outJxOrder.OrderPrice += int64(jxSku2.Count) * jxSku2.SalePrice - outJxOrder.Weight += jxSku2.Count * jxSku2.Weight - } - flag = true - } else { - outJxOrder.Skus = append(outJxOrder.Skus, jxSku) - outJxOrder.OrderPrice += int64(jxSku.Count) * jxSku.SalePrice - } - } else { - outJxOrder.Skus = append(outJxOrder.Skus, jxSku) - outJxOrder.OrderPrice += int64(jxSku.Count) * jxSku.SalePrice - } - } else { - //袋子总数小于等于销量就是1分钱,只要大于销量其他就按原价 - //这个袋子规格是一份100个 - if jxSku.SkuID == 6039382 { - if bagMap[jxSku.SkuID] != 0 { - if sum > 0 { - if bagMap[jxSku.SkuID]*jxSku.Count <= sum+100 { - jxSku.SalePrice = 1 - outJxOrder.Skus = append(outJxOrder.Skus, jxSku) - outJxOrder.OrderPrice += int64(1 * jxSku.Count) - } else { - jxSku2 := *jxSku - jxSku2.SalePrice = jxSku.SalePrice - jxSku2.Count = int(int64(jxSku.Count) - utils.Float64TwoInt64(math.Ceil(utils.Int2Float64(sum)/100))) - outJxOrder.Weight += jxSku2.Count * jxSku2.Weight - jxSku.SalePrice = 1 - jxSku.Count = int(utils.Float64TwoInt64(math.Ceil(utils.Int2Float64(sum) / 100))) - outJxOrder.Skus = append(outJxOrder.Skus, jxSku) - outJxOrder.Skus = append(outJxOrder.Skus, &jxSku2) - outJxOrder.OrderPrice += jxSku.SalePrice * int64(jxSku.Count) - outJxOrder.OrderPrice += jxSku2.SalePrice * int64(jxSku2.Count) - } - } else { - outJxOrder.Skus = append(outJxOrder.Skus, jxSku) - outJxOrder.OrderPrice += int64(jxSku.Count) * jxSku.SalePrice - } - sum = sum - bagMap[jxSku.SkuID]*jxSku.Count - } - } else if jxSku.SkuID == 6039383 || jxSku.SkuID == 6039384 || jxSku.SkuID == 6039387 || jxSku.SkuID == 6039390 { //这些袋子是一份200个 - if bagMap[jxSku.SkuID] != 0 { - if sum > 0 { - if bagMap[jxSku.SkuID]*jxSku.Count <= sum+200 { - jxSku.SalePrice = 1 - outJxOrder.Skus = append(outJxOrder.Skus, jxSku) - outJxOrder.OrderPrice += int64(1 * jxSku.Count) - } else { - jxSku2 := *jxSku - jxSku2.SalePrice = jxSku.SalePrice - jxSku2.Count = int(int64(jxSku.Count) - utils.Float64TwoInt64(math.Ceil(utils.Int2Float64(sum)/200))) - outJxOrder.Weight += jxSku2.Count * jxSku2.Weight - jxSku.SalePrice = 1 - jxSku.Count = int(utils.Float64TwoInt64(math.Ceil(utils.Int2Float64(sum) / 200))) - outJxOrder.Skus = append(outJxOrder.Skus, jxSku) - outJxOrder.Skus = append(outJxOrder.Skus, &jxSku2) - outJxOrder.OrderPrice += jxSku.SalePrice * int64(jxSku.Count) - outJxOrder.OrderPrice += jxSku2.SalePrice * int64(jxSku2.Count) - } - } else { - outJxOrder.Skus = append(outJxOrder.Skus, jxSku) - outJxOrder.OrderPrice += int64(jxSku.Count) * jxSku.SalePrice - } - sum = sum - bagMap[jxSku.SkuID]*jxSku.Count - } - } else { - outJxOrder.Skus = append(outJxOrder.Skus, jxSku) - outJxOrder.OrderPrice += int64(jxSku.Count) * jxSku.SalePrice - } - } - } - } - outJxOrder.Weight += jxSku.Count * jxSku.Weight - } - } - } - } - // if fromStoreID == 0 { - // sort.Sort(JxSkuInfoList(outJxOrder.Skus)) - // outJxOrder.FreightPrice, _, err = delivery.CalculateDeliveryFee(dao.GetDB(), jxOrder.StoreID, "", - // jxutils.StandardCoordinate2Int(deliveryAddress.Lng), jxutils.StandardCoordinate2Int(deliveryAddress.Lat), - // model.CoordinateTypeMars, outJxOrder.Weight, checkTime) - //TODO 2020-08-06 配送费固定5元 - outJxOrder.FreightPrice = 500 - // } - //如果是守价的订单,需要查询本期中该用户是否已经守价过,如果守价过就只算一次运费 - if jxOrder.OrderType == model.OrderTypeDefendPrice { - priceDefendOrders, _ := dao.GetPriceDefendOrder(db, "", nil, nil, []int{jxutils.GetDefendPriceIssue()}, 0, -1, -1, 1, deliveryAddress.UserID, utils.ZeroTimeValue, utils.ZeroTimeValue, false) - if len(priceDefendOrders) > 0 { - flag2 := false - for _, v := range priceDefendOrders { - if v.StoreID != jxOrder.StoreID { - flag2 = true - } - } - if flag2 { - return nil, nil, fmt.Errorf("同一期不允许相同用户在不同门店进行守价!") - } - outJxOrder.FreightPrice = 0 - } - } - } else { - outJxOrder.FreightPrice = 0 - } - //表示此订单为物料配送订单 - if jxOrder.OrderType != model.OrderTypeNormal { - // if fromStoreID != 0 { - storeDetail2, err2 := dao.GetStoreDetail(db, fromStoreID, model.VendorIDJX) - if err = err2; err != nil { - return nil, nil, fmt.Errorf("fromStoreID有误,[%v]", fromStoreID) - } - outJxOrder.FromStoreID = fromStoreID - if jxOrder.OrderType == model.OrderTypeMatter { - //TODO 修改配送费规则,2020-04-28 - //3kg 5元,每多1kg加2元 - //配送费要按分包规则计算 - if outJxOrder.Weight <= 3000 { - outJxOrder.FreightPrice = 500 - } else if outJxOrder.Weight > 3000 && outJxOrder.Weight <= splitMatterOrderMinWeight { - outJxOrder.FreightPrice = utils.Float64TwoInt64(500 + math.Ceil((utils.Int2Float64(outJxOrder.Weight)-3000)/1000)*200) - } else { - _, freightPrice, _ := tryToSplitMatterOrder(jxOrder) - outJxOrder.FreightPrice = freightPrice - } - } - //要求配送人姓名填门店名 - if fromStoreID != -1 { - deliveryAddress.ConsigneeName = storeDetail2.Name - } - } else { - if outJxOrder.FreightPrice > specialFreightPrice { - outJxOrder.FreightPrice = specialFreightPrice - } - if outJxOrder.OrderPrice >= int64(storeDetail.DeliveryFeeDeductionSill) { - outJxOrder.FreightPrice -= int64(storeDetail.DeliveryFeeDeductionFee) - if outJxOrder.FreightPrice < 0 || IsDeliverySelf { - outJxOrder.FreightPrice = 0 - } - } - if IsDeliverySelf { - outJxOrder.FreightPrice = 0 - } - } - if err == nil { - if jxOrder.OrderType == model.OrderTypeNormal { - outJxOrder.TotalPrice = outJxOrder.OrderPrice + outJxOrder.FreightPrice - // 判断用户是否是会员 - var ( - tuserID string - dicountCards []*model.DiscountCard - ) - if userID == "" { - tuserID = deliveryAddress.UserID - } else { - tuserID = userID - } - userMembers, _ := dao.GetUserMember(db, tuserID, "", model.MemberTypeDiscountCard, model.YES) - if len(userMembers) > 0 { - if configList, err := dao.QueryConfigs(db, "会员折扣卡", model.ConfigTypeDiscountCard, ""); err == nil { - jxutils.Strings2Objs(configList[0].Value, &dicountCards) - discountCard := findDiscountCard(dicountCards, userMembers[0].MemberTypeID) - outJxOrder.OrderPrice = utils.Float64TwoInt64(math.Round(float64(outJxOrder.OrderPrice) * float64(int64(discountCard.PicePercentage)) / float64(100))) - } - } - outJxOrder.ActualPayPrice = outJxOrder.OrderPrice + outJxOrder.FreightPrice - } else if jxOrder.OrderType == model.OrderTypeDefendPrice { - outJxOrder.Skus[0].DefendPrice = jxOrder.Skus[0].DefendPrice - } else { - outJxOrder.TotalPrice = outJxOrder.OrderPrice + outJxOrder.FreightPrice - outJxOrder.ActualPayPrice = outJxOrder.TotalPrice - } - if jxOrder.UserID != "" { - outJxOrder.UserID = jxOrder.UserID - } - } else { - outJxOrder = nil - deliveryAddress = nil - } - return outJxOrder, deliveryAddress, err -} - -//根据销量限制门店申请袋子数,现暂不使用该判断,万一以后要用就先没删 -func matterSkusLimited(skus []*JxSkuInfo, storeID int) (err error) { - result, err := orderman.GetMatterStoreOrderCount(nil, storeID) - sum := 0 - if result.Count != 0 { - for _, sku := range skus { - if sku.SkuID == 6039382 { - sum1 := 0 - if bagMap[sku.SkuID] != 0 { - sum1 += bagMap[sku.SkuID] * sku.Count - sum += sum1 - } - if utils.Int2Float64(sum1/100) >= math.Ceil(utils.Int2Float64(result.Count)/100) { - return fmt.Errorf("订单100个一份背心袋订购数量过多,请按照实际销量购买!,大概销量:[%v],购买数量:[%v]", result.Count, sum1) - } - } - if sku.SkuID == 6039383 || sku.SkuID == 6039384 || sku.SkuID == 6039387 || sku.SkuID == 6039390 { - sum2 := 0 - if bagMap[sku.SkuID] != 0 { - sum2 += bagMap[sku.SkuID] * sku.Count - sum += sum2 - } - if utils.Int2Float64(sum2/200) >= math.Ceil(utils.Int2Float64(result.Count)/200) { - return fmt.Errorf("订单200个一份背心袋订购数量过多,请按照实际销量购买!,大概销量:[%v],购买数量:[%v]", result.Count, sum2) - } - } - } - if sum-result.Count > 100 { - return fmt.Errorf("订单背心袋订购数量过多,请按照实际销量购买!,大概销量:[%v],购买数量:[%v]", result.Count, sum) - } - } - return err -} - -func jxOrder2GoodsOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, deliveryAddress *dao.UserDeliveryAddressEx, userID string, IsDeliverySelf bool) (order *model.GoodsOrder, err error) { - order = &model.GoodsOrder{ - VendorOrderID: utils.Int64ToStr(jxOrder.OrderID), - VendorID: model.VendorIDJX, - VendorStoreID: utils.Int2Str(jxOrder.StoreID), - StoreID: jxOrder.StoreID, - StoreName: jxOrder.StoreName, - // UserID: ctx.GetUserID(), - - ConsigneeName: deliveryAddress.ConsigneeName, - ConsigneeMobile: deliveryAddress.ConsigneeMobile, - ConsigneeMobile2: deliveryAddress.ConsigneeMobile, - ConsigneeAddress: fmt.Sprintf("%s%s", deliveryAddress.Address, deliveryAddress.DetailAddress), - CoordinateType: model.CoordinateTypeMars, - ConsigneeLng: jxutils.StandardCoordinate2Int(deliveryAddress.Lng), - ConsigneeLat: jxutils.StandardCoordinate2Int(deliveryAddress.Lat), - - Status: model.OrderStatusUnknown, - VendorStatus: "realnew", - OrderSeq: 0, - BuyerComment: jxOrder.BuyerComment, - - DeliveryType: model.OrderDeliveryTypeStoreSelf, - StatusTime: time.Now(), - EarningType: jxOrder.EarningType, - OrderType: jxOrder.OrderType, - VendorOrderID2: jxOrder.OrderID2, - } - if userID == "" { - order.UserID = ctx.GetUserID() - } else { - order.UserID = userID - } - order.OrderCreatedAt = order.StatusTime - order.VendorUserID = order.UserID - if order.UserID == "" && order.VendorUserID == "" { - if jxOrder.UserID != "" { - order.UserID = jxOrder.UserID - order.VendorUserID = jxOrder.UserID - } - } - if jxOrder.ExpectedDeliveredTimestamp != 0 { - order.ExpectedDeliveredTime = utils.Timestamp2Time(jxOrder.ExpectedDeliveredTimestamp) - order.BusinessType = model.BusinessTypeDingshida - } else { - order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour) - order.BusinessType = model.BusinessTypeImmediate - } - for _, sku := range jxOrder.Skus { - order.Skus = append(order.Skus, &model.OrderSku{ - Count: sku.Count, - VendorSkuID: utils.Int2Str(sku.SkuID), - SkuID: sku.SkuID, - SkuName: sku.Name, - VendorPrice: sku.Price, - SalePrice: sku.SalePrice, - }) - order.TotalShopMoney += int64(sku.Count) * sku.SalePrice - } - order.TotalShopMoney += jxOrder.FreightPrice - order.ActualPayPrice = jxOrder.ActualPayPrice - order.TotalShopMoney = utils.Float64TwoInt64(float64(order.TotalShopMoney) * jdshopapi.JdsPayPercentage) - if jxOrder.FromStoreID != 0 { - order.FromStoreID = jxOrder.FromStoreID - order.DeliveryFlag = model.OrderDeliveryFlagMaskScheduleDisabled - order.Flag = 1 - if jxOrder.OrderType == model.OrderTypeMatter { - order.WaybillVendorID = model.VendorIDJDWL - order.ConsigneeAddress = deliveryAddress.Address - } - } - //如果是自提单就设置 - if IsDeliverySelf { - order.DeliveryType = model.OrderDeliveryTypeSelfTake - } - return order, err -} - -func AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) { - var status int - if isAcceptIt { - status = model.OrderStatusAccepted - } else { - status = model.OrderStatusCanceled - } - return changeOrderStatus(order.VendorOrderID, status, "") -} - -func AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) { - return err -} - -func PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) { - err = changeOrderStatus(order.VendorOrderID, model.OrderStatusFinishedPickup, "") - //如果是物料订单则直接进行京东物流的发单,并且状态直接变为配送中 - //如果是进货的订单,直接变为配送中 - if order.OrderType != model.OrderTypeNormal { - err = orderSolutionForWuLiao(order) - } - return err -} - -func orderSolutionForWuLiao(order *model.GoodsOrder) (err error) { - // if order.FromStoreID != 0 { - err = changeOrderStatus(order.VendorOrderID, model.OrderStatusDelivering, "") - if order.OrderType == model.OrderTypeMatter { - var ( - db = dao.GetDB() - ) - goods, err := dao.QueryOrders(db, order.VendorOrderID, -1, []int{model.VendorIDJX}, -1, utils.ZeroTimeValue, utils.ZeroTimeValue) - if err != nil || len(goods) == 0 { - return err - } - order.WaybillVendorID = model.VendorIDJDWL - dao.UpdateEntity(db, order, "WaybillVendorID") - orderSkus := goods[0].Skus - if order.Weight <= splitMatterOrderMinWeight { //2020-04-26, 从5kg 改为小于4.5kg - var ( - goodsNos []string - prices []string - quantities []string - countSum int - ) - for _, v := range orderSkus { - skus, err := dao.GetSkus(db, []int{v.SkuID}, nil, nil, nil, nil) - if err != nil || len(skus) == 0 { - continue - } - goodsNos = append(goodsNos, skus[0].EclpID) - prices = append(prices, "0") - quantities = append(quantities, utils.Int2Str(v.Count)) - countSum += v.Count - } - //总订单不足3kg && 商品数量不足3个 && 五香粉有库存,要送五香粉,补足3个 - stockResult, err := api.JdEclpAPI.QueryStock(jxwxfMatterEclpID) - if err == nil && len(stockResult) > 0 && stockResult[0].UsableNum > 0 { - if order.Weight < 3000 && countSum < 3 { - //要判断他本身买没买五香粉EMG4418113943423 - var index = 9999 - for k, v := range goodsNos { - if v == jxwxfMatterEclpID { - index = k - } - } - //说明他买了五香粉 - if index != 9999 { - quantities[index] = utils.Int2Str(utils.Str2Int(quantities[index]) + 3 - countSum) - } else { - goodsNos = append(goodsNos, jxwxfMatterEclpID) - prices = append(prices, "0") - quantities = append(quantities, utils.Int2Str(3-countSum)) - } - } - } - result, err := api.JdEclpAPI.AddOrder(&jdeclpapi.AddOrderParam{ - IsvUUID: order.VendorOrderID, - IsvSource: jdeclpapi.IsvSource, - ShopNo: jdeclpapi.ShopNo, - DepartmentNo: jdeclpapi.DepartmentNo, - WarehouseNo: jdeclpapi.WarehouseNo, - SalesPlatformOrderNo: order.VendorOrderID, - SalePlatformSource: jdeclpapi.SalePlatformSource, - ConsigneeName: order.ConsigneeName, - ConsigneeMobile: order.ConsigneeMobile, - ConsigneeAddress: order.ConsigneeAddress, - OrderMark: jdeclpapi.OrderMark, - GoodsNo: strings.Join(goodsNos, ","), - Price: strings.Join(prices, ","), - Quantity: strings.Join(quantities, ","), - }) - if err != nil { - return err - } - order.EclpOutID = result - dao.UpdateEntity(db, order, "EclpOutID") - waybill := &model.Waybill{ - VendorOrderID: order.VendorOrderID, - OrderVendorID: model.VendorIDJX, - VendorWaybillID: order.EclpOutID, - WaybillVendorID: model.VendorIDJDWL, - Status: model.WaybillStatusDelivering, - WaybillCreatedAt: time.Now(), - StatusTime: time.Now(), - WaybillFinishedAt: utils.DefaultTimeValue, - DeliveryFlag: model.OrderDeliveryFlagMaskScheduleDisabled, - } - dao.CreateEntity(db, waybill) - } else { //如果重量超过5kg则需要进行拆单分包,商品分包规则。最后一个包不超过5kg,其他包不超过3kg - outOrders, _, _ := tryToSplitMatterOrder(buildJxOrderInfo(order, orderSkus)) - //以下为仿照CreateOrder,改了一些参数 - for k, v := range outOrders { - v.OrderType = model.OrderTypeMatter - v.FromStoreID = order.FromStoreID - outJxOrder, deliveryAddress, err := generateOrder(jxcontext.AdminCtx, v, order.AddressID, order.FromStoreID, order.UserID, false) - if err != nil { - return err - } - //分包后的子订单ID默认是后面加两位(目前的规则),要改的话要注意取消订单那的判断 - outJxOrder.OrderID = utils.Str2Int64(order.VendorOrderID)*100 + int64(k+1) - checkMatterDeliveryAddress(deliveryAddress) - order2, err2 := jxOrder2GoodsOrder(jxcontext.AdminCtx, outJxOrder, deliveryAddress, order.UserID, false) - if err = err2; err == nil { - order2.FromStoreID = v.FromStoreID - order2.AddressID = order.AddressID - order2.Status = model.OrderStatusDelivering - err = partner.CurOrderManager.OnOrderNew(order2, model.Order2Status(order2)) - orderSolutionForWuLiao(order2) - } - } - //刷新一下库存 - for _, v := range goods[0].Skus { - cms.RefreshMatterStock(jxcontext.AdminCtx, v.SkuID) - } - } - for _, v := range order.Skus { - if bagSkuMap[v.SkuID] != 0 { - stores, _ := dao.GetStoreList(db, []int{order.FromStoreID}, nil, nil, nil, "") - if len(stores) > 0 { - store := stores[0] - store.IsBoughtMatter = model.YES - dao.UpdateEntity(db, store, "IsBoughtMatter") - } - } - } - } - return err -} - -func SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) { - return changeOrderStatus(order.VendorOrderID, model.OrderStatusDelivering, "") -} - -func SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) { - return changeOrderStatus(order.VendorOrderID, model.OrderStatusFinished, "") -} - -func CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) { - if true { //order.Status < model.OrderStatusDelivering { - errList := errlist.New() - db := dao.GetDB() - payList, err2 := dao.GetOrderPayList(db, order.VendorOrderID, jxutils.GetPossibleVendorIDFromVendorOrderID(order.VendorOrderID)) - if err = err2; err == nil { - for _, orderPay := range payList { - if orderPay.Status == model.PayStatusYes { - // refundID := utils.Int64ToStr(GenRefundID(order)) - refundID := order.VendorOrderID - var orderPayRefund *model.OrderPayRefund - if orderPay.PayType == model.PayTypeWX { - orderPayRefund, err = refundOrderByWX(ctx, orderPay, refundID, orderPay.TotalFee, reason) - if err == nil { - dao.WrapAddIDCULDEntity(orderPayRefund, ctx.GetUserName()) - errList.AddErr(dao.CreateEntity(dao.GetDB(), orderPayRefund)) - } else { - errList.AddErr(err) - } - } else if orderPay.PayType == model.PayTypeTL { - orderPayRefund, err = RefundOrderByTL(ctx, orderPay, refundID, orderPay.TotalFee, reason) - if err != nil { - errList.AddErr(err) - } - } - if err == nil { - MarkArrears(db, order, orderPay) - err2 := CancelMatterOrder(db, order, reason) - errList.AddErr(err2) - } - } else { - orderPay.Status = model.PayStatusCanceled - _, err2 := dao.UpdateEntity(db, orderPay) - errList.AddErr(err2) - } - } - } else if dao.IsNoRowsError(err) { - err = nil - } else { - errList.AddErr(err) - } - if errList.GetErrListAsOne() == nil { - errList.AddErr(changeOrderStatus(order.VendorOrderID, model.OrderStatusCanceled, reason)) - } - err = errList.GetErrListAsOne() - if len(payList) == 0 { - err = CancelMatterOrder(db, order, "") - } - } else { - err = fmt.Errorf("当前订单状态:%s不允许取消", model.OrderStatusName[order.Status]) - } - return err -} - -func CancelMatterOrder(db *dao.DaoDB, order *model.GoodsOrder, reason string) (err error) { - // if order.FromStoreID != 0 { - if order.OrderType == model.OrderTypeMatter { - if order.EclpOutID != "" { - //表示是京西的物料订单的子订单(拆分后的订单) - if len(order.VendorOrderID) == 16 && order.VendorID == model.VendorIDJX { - return fmt.Errorf("不允许取消该子订单,请取消主订单进行退货退款!主订单ID :[%v]", order.VendorOrderID[:len(order.VendorOrderID)-2]) - } - _, err = api.JdEclpAPI.CancelOrder(order.EclpOutID) - } else { - goodsList, err := dao.GetMatterChildOrders(db, order.VendorOrderID) - if err == nil && len(goodsList) > 0 { - for _, v := range goodsList { - _, err = api.JdEclpAPI.CancelOrder(v.EclpOutID) - changeOrderStatus(v.VendorOrderID, model.OrderStatusCanceled, reason) - } - } - } - stores, _ := dao.GetStoreList(db, []int{order.FromStoreID}, nil, nil, nil, "") - if len(stores) > 0 { - //如果这周还买过其他物料,则不刷新是否购买标志 - var ( - orderPays []*model.OrderPay - day int - ) - sql := ` - SELECT b.* - FROM goods_order a - JOIN order_pay b ON a.vendor_order_id = b.vendor_order_id - WHERE IF(a.store_id = 0, a.jx_store_id, a.store_id) = 666666 - AND a.from_store_id = ? - AND a.status >= ? AND a.status <> ? - AND b.status = ? - AND b.pay_finished_at <= NOW() AND b.pay_finished_at >= ? - ` - weekInt := int(time.Now().Weekday()) - if weekInt == 0 { - day = 7 - } else { - day = weekInt - } - lastTime := utils.Str2Time(time.Now().AddDate(0, 0, -(day-1)).Format("2006-01-02") + " 01:00:00") - sqlParams := []interface{}{order.FromStoreID, model.OrderStatusDelivering, model.OrderStatusCanceled, model.PayStatusYes, lastTime} - err = dao.GetRows(db, &orderPays, sql, sqlParams) - if len(orderPays) == 0 { - store := stores[0] - store.IsBoughtMatter = model.NO - dao.UpdateEntity(db, store, "IsBoughtMatter") - } - } - } - return err -} - -func MarkArrears(db *dao.DaoDB, order *model.GoodsOrder, orderPay *model.OrderPay) { - //退款后,若此订单下单用户有推广人,则需要将分给推广人的金额记录到该推广人的欠款中 - orders, _ := dao.QueryOrders(db, order.VendorOrderID, 0, []int{model.VendorIDJX}, 0, utils.DefaultTimeValue, utils.DefaultTimeValue) - if len(orders) > 0 { - user, _ := dao.GetUserByID(db, "user_id", orders[0].UserID) - if user.ParentMobile != "" { - user2, _ := dao.GetUserByID(db, "mobile", user.ParentMobile) - user2.Arrears = user2.Arrears + (orderPay.TotalFee * user2.DividePercentage / 100) - dao.UpdateEntity(db, user2, "Arrears") - if user2.ParentMobile != "" { - user3, _ := dao.GetUserByID(db, "mobile", user2.ParentMobile) - user3.Arrears = user3.Arrears + ((orderPay.TotalFee - user2.Arrears) * user3.DividePercentage / 100) - dao.UpdateEntity(db, user3, "Arrears") - } - } - } -} - -func AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) { - if isAgree { - err = CancelOrder(ctx, order, reason) - } else { - err = changeOrderStatus(order.VendorOrderID, model.OrderStatusVendorRejectCancel, reason) - } - return err -} - -// todo 消息用异步可能导致丢失,单同步又有重入相关的问题 -func callNewOrder(order *model.GoodsOrder) (err error) { - jxutils.CallMsgHandlerAsync(func() { - err = partner.CurOrderManager.OnOrderNew(order, model.Order2Status(order)) - }, jxutils.ComposeUniversalOrderID(order.VendorOrderID, model.VendorIDJX)) - return err -} - -func changeOrderStatus(vendorOrderID string, status int, remark string) (err error) { - orderStatus := &model.OrderStatus{ - VendorOrderID: vendorOrderID, - VendorID: model.VendorIDJX, - OrderType: model.OrderTypeOrder, - RefVendorOrderID: vendorOrderID, - RefVendorID: model.VendorIDJX, - VendorStatus: utils.Int2Str(status), - Status: status, - StatusTime: time.Now(), - Remark: remark, - } - jxutils.CallMsgHandlerAsync(func() { - err = partner.CurOrderManager.OnOrderStatusChanged("", orderStatus) - }, jxutils.ComposeUniversalOrderID(vendorOrderID, model.VendorIDJX)) - return err -} - -func GetOrderPay(ctx *jxcontext.Context, vendorOrderID string) (payList []*model.OrderPay, err error) { - db := dao.GetDB() - payList, err = dao.GetOrderPayList(db, vendorOrderID, jxutils.GetPossibleVendorIDFromVendorOrderID(vendorOrderID)) - return payList, err -} - -func PayForPopluarMan(ctx *jxcontext.Context, vendorOrderID, userID string, price int) (err error) { - db := dao.GetDB() - user, err := dao.GetUserByID(db, "user_id", userID) - if user == nil { - return fmt.Errorf("未找到此用户!用户ID:[%v]\n", userID) - } - auth, err := dao.GetUserBindAuthInfo(db, userID, model.AuthBindTypeAuth, []string{"weixinmini"}, "", "", "wx4b5930c13f8b1170") - if len(auth) == 0 { - return fmt.Errorf("未找到此用户的微信验证方式!用户ID:[%v]\n", userID) - } - goods, err := dao.QueryOrders(db, vendorOrderID, 0, []int{model.VendorIDJX}, 0, utils.ZeroTimeValue, utils.ZeroTimeValue) - if len(goods) == 0 { - return fmt.Errorf("未找到此订单!订单ID:[%v]\n", vendorOrderID) - } - param := &wxpayapi.TransfersParam{ - CheckName: wxpayapi.CheckName, - PartnerTradeNo: vendorOrderID, - Desc: "每日推广人订单分成分到个人", - SpbillCreateIP: ctx.GetRealRemoteIP(), - OpenID: auth[0].AuthID, - Amount: price, - } - _, err = api.WxpayAPI.Transfers(param) - return err -} - -//自动打款给市场推广人 -func AutoPayForPopluarMan(ctx *jxcontext.Context) (err error) { - var ( - errMsg string - errCode string - db = dao.GetDB() - fromDateStr = time.Now().AddDate(0, 0, -1).Format("2006-1-2") + " 00:00:00" - toDateStr = time.Now().AddDate(0, 0, -1).Format("2006-1-2") + " 23:59:59" - mapResult = make(map[string]interface{}) - ) - result, err := dao.GetOrdersForJxPay(db, utils.Str2Time(fromDateStr), utils.Str2Time(toDateStr)) - for _, goods := range result { - var ( - param = &wxpayapi.TransfersParam{ - CheckName: wxpayapi.CheckName, - Desc: "每日推广人订单分成分到个人", - SpbillCreateIP: ctx.GetRealRemoteIP(), - } - payPrice1 int - payPrice2 int - ) - user, err := dao.GetUserByID(db, "user_id", goods.UserID) - if user.ParentMobile == "" { - return err - } - user2, err := dao.GetUserByID(db, "mobile", user.ParentMobile) - auths, err := dao.GetUserBindAuthInfo(db, user2.UserID, model.AuthBindTypeAuth, []string{"weixinmini"}, "", "", "wx4b5930c13f8b1170") - if err != nil { - return err - } - if len(auths) == 0 { - errMsg += fmt.Sprintf("打款失败!未找到此用户的微信验证方式!订单号:[%v],用户ID:[%v]\n", goods.VendorOrderID, user2.UserID) - } else { - var openID string - for _, auth := range auths { - if auth.TypeID == wxAppID { - openID = auth.AuthID - } - } - payPrice1 = int(goods.ActualPayPrice) * user2.DividePercentage / 100 - //表示这个人之前有欠款,意思是取消订单退款时,这个推广人的分成收不回来,算作欠款,打钱的时候要扣除 - //表示这个人之前有小于3毛钱的款没有打(微信付款api付款最低3毛),记录下来加到以后的款项中 - rPrice := payPrice1 - user2.Arrears + user2.Profit - err = updateUserAndTransfers(db, param, user2, openID, rPrice) - if err != nil { - errMsg += err.Error() - } - mapResult["打款人1"] = user2.Name - mapResult["打款人金额1"] = rPrice - mapResult["打款人电话1"] = user2.Mobile - mapResult["打款人1userID"] = user2.UserID - } - if user2.ParentMobile != "" { - user3, err := dao.GetUserByID(db, "mobile", user2.ParentMobile) - auths, err := dao.GetUserBindAuthInfo(db, user3.UserID, model.AuthBindTypeAuth, []string{"weixinmini"}, "", "", "wx4b5930c13f8b1170") - if err != nil { - return err - } - if len(auths) == 0 { - errMsg += fmt.Sprintf("打款失败!未找到此用户的微信验证方式!订单号:[%v],用户ID:[%v]\n", goods.VendorOrderID, user3.UserID) - } else { - var openID string - for _, auth := range auths { - if auth.TypeID == wxAppID { - openID = auth.AuthID - } - } - payPrice2 = (int(goods.ActualPayPrice) - payPrice1) * user3.DividePercentage / 100 - rPrice := payPrice2 - user3.Arrears + user3.Profit - err = updateUserAndTransfers(db, param, user3, openID, rPrice) - if err != nil { - errMsg += err.Error() - } - mapResult["打款人2"] = user3.Name - mapResult["打款人金额2"] = rPrice - mapResult["打款人电话2"] = user3.Mobile - mapResult["打款人2userID"] = user3.UserID - } - } - } - user, _ := dao.GetUserByID(dao.GetDB(), "mobile", "18160030913") - if user != nil && errMsg != "" { - ddmsg.SendUserMessage(dingdingapi.MsgTyeText, user.UserID, "每日打款错误", errMsg) - } - if err != nil || errMsg != "" { - errMsg += err.Error() - errCode = model.ErrCodeGeneralFailed - } else { - errCode = model.ErrCodeSuccess - } - err = event.AddOperateEvent(ctx, ctx.GetTrackInfo(), cms.BuildDiffData(mapResult), errCode, errMsg, 0, "AutoPayForPopluarMan") - globals.SugarLogger.Debugf("每日订单打款:[%v]", cms.BuildDiffData(mapResult)) - return err -} - -func updateUserAndTransfers(db *dao.DaoDB, param *wxpayapi.TransfersParam, user *model.User, authID string, rPrice int) (err error) { - if rPrice >= 30 { - param.OpenID = authID - param.Amount = rPrice - param.PartnerTradeNo = utils.GetUUID() - _, err = api.WxpayAPI.Transfers(param) - user.ProfitSum = user.ProfitSum + rPrice - user.Profit = 0 - user.Arrears = 0 - } else if rPrice >= 0 && rPrice < 30 { - user.Profit = rPrice - user.Arrears = 0 - } else { - user.Profit = 0 - user.Arrears = int(utils.Float64TwoInt64(math.Abs(utils.Int2Float64(rPrice)))) - } - _, err = dao.UpdateEntity(db, user, "ProfitSum", "Profit", "Arrears") - return err -} - -func CancelPayTimeOutOrder(ctx *jxcontext.Context) (err error) { - db := dao.GetDB() - var orders []*model.GoodsOrder - sql := ` - SELECT * - FROM goods_order - WHERE order_created_at >= ? AND order_created_at <= NOW() - AND status = ? - AND vendor_id = ? - ` - sqlParams := []interface{}{ - time.Now().Add(-time.Minute * 30), - model.OrderStatusWait4Pay, - model.VendorIDJX, - } - err = dao.GetRows(db, &orders, sql, sqlParams) - for _, v := range orders { - if v.OrderCreatedAt.Add(PayWaitingTime).Before(time.Now()) { - err2 := changeOrderStatus(v.VendorOrderID, model.OrderStatusCanceled, autoCancelOrderReason) - err = err2 - } - } - return err -} - -func GetHalfHoursList() (strs []string) { - for k := 0; k < 3; k++ { - for i := 0; i < 10; i++ { - for j := 0; j < 4; j += 3 { - if k == 2 && i > 3 { - break - } - strs = append(strs, utils.Int2Str(k)+utils.Int2Str(i)+":"+utils.Int2Str(j)+"0"+":00") - } - } - } - return strs -} - -func GetDiscountActHoursList() (str []string) { - for k := 1; k < 3; k++ { - for i := 0; i < 10; i++ { - for j := 0; j < 6; j++ { - if k == 1 && i == 0 && j == 0 { - continue - } - if k == 2 && i > 2 { - break - } - if k == 2 && i == 2 && j > 0 { - break - } - str = append(str, utils.Int2Str(k)+utils.Int2Str(i)+":"+utils.Int2Str(j)+"0"+":00") - } - } - } - return str -} - -func RefreshAllMatterOrderStatus(ctx *jxcontext.Context) (err error) { - var ( - db = dao.GetDB() - goodsList []*model.GoodsOrder - realTime time.Time - ) - realTime = time.Now().AddDate(0, 0, -7) - //有分包的主订单 - sql := ` - SELECT * FROM goods_order WHERE store_id = 666666 AND order_created_at >= ? AND status < ? AND vendor_id = ? AND LENGTH(vendor_order_id) = 14 - ` - sqlParams := []interface{}{realTime, model.OrderStatusEndBegin, model.VendorIDJX} - err = dao.GetRows(db, &goodsList, sql, sqlParams) - for _, v := range goodsList { - if v.EclpOutID == "" { - var ( - goodsList2 []*model.GoodsOrder - cancelCount int - deliveringCount int - ) - sql2 := "SELECT * FROM goods_order WHERE vendor_order_id LIKE ? OR vendor_order_id LIKE ? AND vendor_id = ? AND eclp_out_id <> '' AND LENGTH(vendor_order_id) = 16" - sqlParams2 := []interface{}{v.VendorOrderID + "0%", v.VendorOrderID + "1%", model.VendorIDJX} - err = dao.GetRows(db, &goodsList2, sql2, sqlParams2) - for _, vv := range goodsList2 { - if vv.Status < model.OrderStatusFinished { - queryOrderStatus, err := api.JdEclpAPI.QueryOrderStatus(vv.EclpOutID) - if err != nil || queryOrderStatus == nil { - continue - } - if len(queryOrderStatus.OrderStatusList) > 0 { - if queryOrderStatus.OrderStatusList[len(queryOrderStatus.OrderStatusList)-1].SoStatusCode == jdeclpapi.SoStatusCode10034 { - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - vv.Status = model.OrderStatusFinished - dao.UpdateEntity(db, vv, "Status") - waybills, err := dao.GetWaybills(db, vv.VendorOrderID) - if err == nil && len(waybills) > 0 { - waybills[0].Status = model.WaybillStatusDelivered - dao.UpdateEntity(db, waybills[0], "Status") - } - dao.Commit(db) - changeOrderStatus(vv.VendorOrderID, model.OrderStatusFinished, "") - getTrackMessagePlusByOrderResult, _ := api.JdEclpAPI.GetTrackMessagePlusByOrder(vv.VendorOrderID) - updateJdWayBillInfo(db, vv, getTrackMessagePlusByOrderResult) - } else { - deliveringCount++ - } - } - } else if vv.Status == model.OrderStatusCanceled { - cancelCount++ - } - } - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - if deliveringCount == 0 { - v.Status = model.OrderStatusFinished - } else { - if cancelCount == len(goodsList2) { - v.Status = model.OrderStatusCanceled - } - } - if v.Status < model.OrderStatusDelivering { - v.Status = model.OrderStatusCanceled - } - dao.UpdateEntity(db, v, "Status") - dao.Commit(db) - changeOrderStatus(v.VendorOrderID, v.Status, "") - } else { - queryOrderStatus, _ := api.JdEclpAPI.QueryOrderStatus(v.EclpOutID) - getTrackMessagePlusByOrderResult, _ := api.JdEclpAPI.GetTrackMessagePlusByOrder(v.VendorOrderID) - updateMatterOrderStatus(db, v, queryOrderStatus) - updateJdWayBillInfo(db, v, getTrackMessagePlusByOrderResult) - } - } - return err -} - -func GetMatterOrderStatus(ctx *jxcontext.Context, vendorOrderID string) (result []*MatterOrderStatus, err error) { - var ( - db = dao.GetDB() - ) - order, err := dao.GetSimpleOrder(db, vendorOrderID) - if err != nil { - return nil, err - } - if order.EclpOutID == "" { - return nil, err - } - queryOrderStatus, err := api.JdEclpAPI.QueryOrderStatus(order.EclpOutID) - getTrackMessagePlusByOrderResult, err := api.JdEclpAPI.GetTrackMessagePlusByOrder(vendorOrderID) - if err != nil || queryOrderStatus == nil { - return nil, err - } - if len(queryOrderStatus.OrderStatusList) > 0 { - for _, v := range queryOrderStatus.OrderStatusList { - matter := &MatterOrderStatus{} - matter.Time = utils.Str2Time(v.OperateTime) - matter.Status = v.SoStatusName - matter.Name = v.SoStatusName - matter.Sign = 1 - result = append(result, matter) - } - } - - if len(getTrackMessagePlusByOrderResult.ResultData) > 0 { - for _, vv := range getTrackMessagePlusByOrderResult.ResultData { - matter := &MatterOrderStatus{} - matter.Time = utils.Str2Time(strings.ReplaceAll(vv.OpeTime, "/", "-")) - matter.Status = vv.OpeTitle - matter.Name = vv.OpeRemark - matter.Sign = 2 - result = append(result, matter) - } - } - for i := 0; i < len(result)-1; i++ { - for j := 0; j < len(result)-i-1; j++ { - if result[j].Time.Unix() > result[j+1].Time.Unix() || (result[j].Time.Unix() == result[j+1].Time.Unix() && result[j].Sign > result[j+1].Sign) { - tmp := result[j] - result[j] = result[j+1] - result[j+1] = tmp - } - } - } - if len(queryOrderStatus.OrderStatusList) > 0 { - updateMatterOrderStatus(db, order, queryOrderStatus) - } - if len(getTrackMessagePlusByOrderResult.ResultData) > 0 { - updateJdWayBillInfo(db, order, getTrackMessagePlusByOrderResult) - } - return result, err -} - -func updateMatterOrderStatus(db *dao.DaoDB, order *model.GoodsOrder, queryOrderStatus *jdeclpapi.QueryOrderStatusResult) { - code := queryOrderStatus.OrderStatusList[len(queryOrderStatus.OrderStatusList)-1].SoStatusCode - if code == jdeclpapi.SoStatusCode10034 || code == jdeclpapi.SoStatusCode10038 { - dao.Begin(db) - defer func() { - if r := recover(); r != nil { - dao.Rollback(db) - panic(r) - } - }() - order.Status = model.OrderStatusFinished - dao.UpdateEntity(db, order, "Status") - waybills, err := dao.GetWaybills(db, order.VendorOrderID) - if err == nil && len(waybills) > 0 { - waybills[0].Status = model.WaybillStatusDelivered - dao.UpdateEntity(db, waybills[0], "Status") - } - dao.Commit(db) - changeOrderStatus(order.VendorOrderID, model.OrderStatusFinished, "") - } -} - -func updateJdWayBillInfo(db *dao.DaoDB, order *model.GoodsOrder, getTrackMessagePlusByOrderResult *jdeclpapi.GetTrackMessagePlusByOrderResult) (err error) { - var ( - waybillCode string - cName string - cMobile string - waybills []*model.Waybill - ) - if len(getTrackMessagePlusByOrderResult.ResultData) > 0 { - waybillCode = getTrackMessagePlusByOrderResult.ResultData[0].WaybillCode - } else { - return err - } - for _, vv := range getTrackMessagePlusByOrderResult.ResultData { - if vv.OpeTitle == "配送员收货" { - result := regexpCnameAndCmobile.FindAllStringSubmatch(vv.OpeRemark, -1) - if len(result) > 0 { - cName = result[0][1] - cMobile = result[0][2] - } else { - result2 := regexpCnameAndCmobile2.FindAllStringSubmatch(vv.OpeRemark, -1) - if len(result2) > 0 { - cName = result2[0][1] - cMobile = result2[0][2] - } - } - break - } - } - waybills, err = dao.GetWaybills(db, order.VendorOrderID) - if len(waybills) > 0 { - waybills[0].VendorWaybillID = waybillCode - waybills[0].CourierName = cName - waybills[0].CourierMobile = cMobile - order.VendorWaybillID = waybillCode - order.WaybillVendorID = model.VendorIDJDWL - dao.UpdateEntity(db, order, "VendorWaybillID", "WaybillVendorID") - dao.UpdateEntity(db, waybills[0], "VendorWaybillID", "CourierName", "CourierMobile") - } - return err -} - -func tryToSplitMatterOrder(jxOrder *JxOrderInfo) (outOrders []*JxOrderInfo, freightPrice int64, err error) { - var ( - skus = jxOrder.Skus - weightList []*JxSkuInfo2 - ) - //我的思路为把所有商品依次按重量销量从大到小排列,然后第一个包尽量分出3kg,后面分出4.5kg - //但是我把JxSkuInfo放进list的时候,想根据一个参数GroupSign判断是否这个商品已经分出去了 - //但是在list中同一个商品通过以下方式放进去的地址是一样的,我改了一个商品的GroupSign,所有的都变了,所以只有分出一个JxSkuInfo2去弄。。 - //要做优化的话更好 - for _, v := range skus { - for i := 0; i < v.Count; i++ { - var sku2 = &JxSkuInfo2{} - sku2.Count = v.Count - sku2.Name = v.Name - sku2.Price = v.Price - sku2.SalePrice = v.SalePrice - sku2.Weight = v.Weight - sku2.SkuID = v.SkuID - weightList = append(weightList, sku2) - } - } - for i := 0; i < len(weightList)-1; i++ { - for j := 0; j < len(weightList)-i-1; j++ { - if weightList[j].Weight < weightList[j+1].Weight { - tmp := weightList[j] - weightList[j] = weightList[j+1] - weightList[j+1] = tmp - } - } - } - weight := jxOrder.Weight - for { - //每拿出一组就删掉list里的值 - outOrders = append(outOrders, loop2(weightList, jxOrder.StoreID, &weight)) - for i := 0; i < len(weightList); { - if weightList[i].GroupSign { - var weightList3 []*JxSkuInfo2 - weightList3 = append(weightList[:i], weightList[i+1:]...) - weightList = weightList3 - } else { - i++ - } - } - if len(weightList) == 0 { - break - } - } - for _, v := range outOrders { - if v.Weight <= 3000 { - freightPrice += 500 - } else if v.Weight > 3000 && v.Weight <= splitMatterOrderMinWeight { - freightPrice += utils.Float64TwoInt64(500 + math.Ceil((utils.Int2Float64(v.Weight)-3000)/1000)*200) - } - } - return outOrders, freightPrice, err -} - -func jxOrderChange(sku2 *JxSkuInfo2) *JxSkuInfo { - sku := &JxSkuInfo{} - sku.Count = 1 - sku.Name = sku2.Name - sku.Price = sku2.Price - sku.SalePrice = sku2.SalePrice - sku.SkuID = sku2.SkuID - sku.Weight = sku2.Weight - return sku -} - -//TODO 修改为4.5kg 2020-04-2? -//商品分包规则2。最后一个包不超过5kg,其他包不超过3kg -// 举例1:5.1kg,分为 2.5kg,2.6kg,确保每个包不超过3kg,最后一个包不超过5kg -// 举例2:4kg,分为4kg -// 举例3:10kg,分为 3kg,3kg,4kg -// 举例4:8.1kg,分为 3kg,3kg,2.1kg ; 不能分为3kg,5.1kg -//sum3表示3kg的计算 -func loop2(weightList []*JxSkuInfo2, storeID int, weight *int) (outOrder *JxOrderInfo) { - outOrder = &JxOrderInfo{} - outOrder.StoreID = storeID - sum3 := 0 - if *weight <= splitMatterOrderMinWeight { - for i := 0; i < len(weightList); i++ { - buildOutOrderSkus(weightList[i], outOrder) - } - } else { - for i := 0; i < len(weightList); i++ { - if weightList[i].Weight+sum3 <= 3000 { - sum3 += weightList[i].Weight - *weight -= weightList[i].Weight - buildOutOrderSkus(weightList[i], outOrder) - } else { - if sum3 >= 3000 { - break - } - continue - } - } - } - return outOrder -} - -func buildOutOrderSkus(weightp *JxSkuInfo2, outOrder *JxOrderInfo) { - weightp.GroupSign = true - outOrder.Weight += weightp.Weight - if len(outOrder.Skus) > 0 { - var flag = false - for _, v := range outOrder.Skus { - if v.SkuID == weightp.SkuID { - v.Count++ - flag = true - } - } - if !flag { - outOrder.Skus = append(outOrder.Skus, jxOrderChange(weightp)) - } - } else { - outOrder.Skus = append(outOrder.Skus, jxOrderChange(weightp)) - } -} - -func checkMatterDeliveryAddress(deliveryAddress *dao.UserDeliveryAddressEx) { - var ( - db = dao.GetDB() - ) - if !strings.Contains(deliveryAddress.Address, "区") { - deliveryAddress.Address = deliveryAddress.DistrictName + deliveryAddress.Address - } - if !strings.Contains(deliveryAddress.Address, "市") { - deliveryAddress.Address = deliveryAddress.CityName + deliveryAddress.Address - } - if !strings.Contains(deliveryAddress.Address, "省") { - if place1, err := dao.GetPlaceByCode(db, deliveryAddress.CityCode); err == nil { - if place2, err2 := dao.GetPlaceByCode(db, place1.ParentCode); err2 == nil { - deliveryAddress.Address = place2.Name + deliveryAddress.Address - } - } - } -} - -func SendFailedMatterOrder(ctx *jxcontext.Context, vendorOrderID string) (err error) { - var ( - db = dao.GetDB() - ) - order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, model.VendorIDJX) - if err != nil { - return err - } - if order == nil || order.StoreID != model.MatterStoreID || order.FromStoreID == 0 { - return fmt.Errorf("只允许物料店重发物料订单调用此接口!") - } - err = CancelMatterOrder(db, order, cancelMatterOrderReason) - // queryOrderStatus, err := api.JdEclpAPI.QueryOrderStatus(order.EclpOutID) - // if len(queryOrderStatus.OrderStatusList) > 0 { - // code := queryOrderStatus.OrderStatusList[len(queryOrderStatus.OrderStatusList)-1].SoStatusCode - // if code == jdeclpapi.SoStatusCode10022 || code == jdeclpapi.SoStatusCode10038 { //表示该订单在京东物流为暂停或已经逆向发货完成 - if len(order.VendorOrderID) == 14 && order.EclpOutID != "" { //这是不分包的订单 - _, err = createMatterOrder(buildJxOrderInfo(order, order.Skus), order, int64(01)) - if err != nil { - globals.SugarLogger.Debugf("SendFailedMatterOrder err : [%v]", err) - return err - } - changeOrderStatus(order.VendorOrderID, model.OrderStatusCanceled, cancelMatterOrderReason) - for _, v := range order.Skus { - cms.RefreshMatterStock(jxcontext.AdminCtx, v.SkuID) - } - } else if len(order.VendorOrderID) == 14 && order.EclpOutID == "" { //这是分包的主订单 - goodsList, err := dao.GetMatterChildOrders(db, order.VendorOrderID) - if err != nil { - return err - } - if len(goodsList) > 0 { - for _, v := range goodsList { - cOrder, err := partner.CurOrderManager.LoadOrder(v.VendorOrderID, model.VendorIDJX) - if err != nil { - return err - } - suffix := utils.Str2Int64(cOrder.VendorOrderID[len(cOrder.VendorOrderID)-2:]) + int64(len(goodsList)) - _, err = createMatterOrder(buildJxOrderInfo(cOrder, cOrder.Skus), order, suffix) - for _, v := range cOrder.Skus { - cms.RefreshMatterStock(jxcontext.AdminCtx, v.SkuID) - } - } - } - changeOrderStatus(order.VendorOrderID, model.OrderStatusCanceled, cancelMatterOrderReason) - } else if len(order.VendorOrderID) == 16 && order.EclpOutID != "" { // 这是分包的子订单 - return fmt.Errorf("请重发主订单!主订单号:[%v]", order.VendorOrderID[len(order.VendorOrderID)-2:]) - } - // } else { - // return fmt.Errorf("只允许物流订单为暂停或逆向完成才能调用此接口!") - // } - // } - return err -} - -func createMatterOrder(jxOrder *JxOrderInfo, order *model.GoodsOrder, newOrderIDSuffix int64) (order2 *model.GoodsOrder, err error) { - outJxOrder, deliveryAddress, err := generateOrder(jxcontext.AdminCtx, jxOrder, order.AddressID, order.FromStoreID, order.UserID, false) - if err != nil { - return nil, err - } - outJxOrder.OrderID = utils.Str2Int64(order.VendorOrderID)*100 + newOrderIDSuffix - checkMatterDeliveryAddress(deliveryAddress) - order2, err2 := jxOrder2GoodsOrder(jxcontext.AdminCtx, outJxOrder, deliveryAddress, order.UserID, false) - if err = err2; err == nil { - order2.AddressID = order.AddressID - order2.Status = model.OrderStatusDelivering - err = partner.CurOrderManager.OnOrderNew(order2, model.Order2Status(order2)) - err = orderSolutionForWuLiao(order2) - } - return order2, err -} - -func buildJxOrderInfo(order *model.GoodsOrder, orderSkus []*model.OrderSku) (jxOrder *JxOrderInfo) { - jxOrder = &JxOrderInfo{} - jxOrder.StoreID = order.StoreID - weight := 0 - var skus []*JxSkuInfo - for _, v := range orderSkus { - weight += v.Weight * v.Count - sku := &JxSkuInfo{} - sku.SkuID = v.SkuID - sku.SalePrice = v.SalePrice - sku.Name = v.SkuName - sku.Weight = v.Weight - sku.Count = v.Count - skus = append(skus, sku) - } - jxOrder.Skus = skus - jxOrder.Weight = weight - jxOrder.OrderType = model.OrderTypeMatter - return jxOrder -} - -func GetSupplySupportStoreSkus(ctx *jxcontext.Context, fromDate, toDate string, fromStoreID, storeID int, percentage string) (orderSkus []*dao.GetSupplySupportStoreSkusResult, err error) { - var ( - db = dao.GetDB() - ) - orderSkus, err = dao.GetSupplySupportStoreSkus(db, utils.Str2Time(fromDate), utils.Str2Time(toDate), fromStoreID, storeID, utils.Str2Float64(percentage)) - return orderSkus, err -} - -func CreateOrderByPriceDefend(ctx *jxcontext.Context) (err error) { - var ( - db = dao.GetDB() - userOrderMap = make(map[int64][]*model.PriceDefendOrder) - ) - globals.SugarLogger.Debugf("CreateOrderByPriceDefend Begin:") - priceDefends, _ := dao.GetPriceDefendOrder(db, "", nil, nil, []int{jxutils.GetLastDefendPriceIssue()}, 0, -1, 1, 1, "", utils.ZeroTimeValue, utils.ZeroTimeValue, false) - if len(priceDefends) > 0 { - for _, v := range priceDefends { - userOrderMap[v.AddressID] = append(userOrderMap[v.AddressID], v) - } - for kk, vv := range userOrderMap { - addressList, _, _ := dao.QueryUserDeliveryAddress(db, kk, nil, 0, 0) - address := addressList[0] - if len(vv) == 1 { - jxOrder := &JxOrderInfo{ - BuyerComment: "守价订单", - StoreID: vv[0].StoreID, - Skus: []*JxSkuInfo{ - &JxSkuInfo{ - SkuID: vv[0].SkuID, - Count: vv[0].Count, - }, - }, - IsPriceDefend: model.YES, - OrderID: utils.Str2Int64(vv[0].VendorOrderID), - UserID: address.UserID, - } - if _, err := CreateOrder(ctx, jxOrder, kk, OrderCreateTypeNormal, 0, false); err == nil { - err = SettleDiscountActByPriceDefend(ctx, vv[0], false) - } - } else { - var ( - skus []*JxSkuInfo - orderIDs []string - ) - jxOrder := &JxOrderInfo{ - BuyerComment: "守价订单", - StoreID: vv[0].StoreID, - IsPriceDefend: model.YES, - OrderID: jxutils.GenOrderNo(), - UserID: address.UserID, - } - for _, priceDefend := range vv { - sku := &JxSkuInfo{ - SkuID: priceDefend.SkuID, - Count: priceDefend.Count, - } - skus = append(skus, sku) - orderIDs = append(orderIDs, priceDefend.VendorOrderID) - err = SettleDiscountActByPriceDefend(ctx, priceDefend, false) - } - jxOrder.Skus = skus - jxOrder.OrderID2 = strings.Join(orderIDs, ",") - if _, err := CreateOrder(ctx, jxOrder, kk, OrderCreateTypeNormal, 0, false); err == nil { - } - } - } - } - priceDefends2, _ := dao.GetPriceDefendOrder(db, "", nil, nil, []int{jxutils.GetLastDefendPriceIssue()}, 0, -1, 0, 1, "", utils.ZeroTimeValue, utils.ZeroTimeValue, false) - if len(priceDefends2) > 0 { - for _, v := range priceDefends2 { - err = SettleDiscountActByPriceDefend(ctx, v, true) - } - } - return err -} - -//结算因京西折扣活动而参与守价的订单 -func SettleDiscountActByPriceDefend(ctx *jxcontext.Context, order *model.PriceDefendOrder, isFull bool) (err error) { - var ( - db = dao.GetDB() - ) - payList, err2 := dao.GetOrderPayList(db, order.VendorOrderID, jxutils.GetPossibleVendorIDFromVendorOrderID(order.VendorOrderID)) - if err = err2; err == nil { - for _, orderPay := range payList { - if orderPay.Status == model.PayStatusYes { - refundID := order.VendorOrderID - if orderPay.PayType == model.PayTypeTL { - if !isFull { - minusPrice := int(order.OriginPrice - order.RealPrice) - _, err = RefundOrderByTL(ctx, orderPay, refundID, order.Count*minusPrice, settleDiscountActRefundReason) - } else { - _, err = RefundOrderByTL(ctx, orderPay, refundID, int(order.ActualPayPrice), settleDiscountActRefundReason) - } - } - } else { - orderPay.Status = model.PayStatusCanceled - _, err = dao.UpdateEntity(db, orderPay) - } - } - } - return err -} - -func GetMyPriceDefendOrders(ctx *jxcontext.Context, fromTime, toTime string) (priceDefendOrders []*model.PriceDefendOrder, err error) { - var ( - db = dao.GetDB() - userID = ctx.GetUserID() - ) - priceDefendOrders, err = dao.GetPriceDefendOrder(db, "", nil, nil, nil, 0, -1, -1, -1, userID, utils.Str2Time(fromTime), utils.Str2Time(toTime), true) - return priceDefendOrders, err -} diff --git a/business/partner/purchase/jx/localjx/order_test.go b/business/partner/purchase/jx/localjx/order_test.go deleted file mode 100644 index 6965e1146..000000000 --- a/business/partner/purchase/jx/localjx/order_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package localjx - -import ( - "testing" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/globals/testinit" -) - -func init() { - testinit.Init() -} - -func TestGenOrderNo(t *testing.T) { - orderNo := GenOrderNo(jxcontext.AdminCtx) - t.Log(orderNo) -} - -func TestGetAvailableDeliverTime(t *testing.T) { - timeInfo, err := GetAvailableDeliverTime(jxcontext.AdminCtx, 100118) - if err != nil { - t.Fatal(err) - } - t.Log(utils.Format4Output(timeInfo, false)) -} diff --git a/business/partner/purchase/jx/localjx/tonglianpay.go b/business/partner/purchase/jx/localjx/tonglianpay.go deleted file mode 100644 index 933b368af..000000000 --- a/business/partner/purchase/jx/localjx/tonglianpay.go +++ /dev/null @@ -1,182 +0,0 @@ -package localjx - -import ( - "encoding/json" - "strings" - "time" - - "git.rosy.net.cn/jx-callback/globals" - - "git.rosy.net.cn/baseapi/platformapi/tonglianpayapi" - "git.rosy.net.cn/baseapi/utils" - - "git.rosy.net.cn/jx-callback/business/auth2/authprovider/weixin" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/globals/api" -) - -func pay4OrderByTL(ctx *jxcontext.Context, order *model.GoodsOrder, payType int, vendorPayType string) (orderPay *model.OrderPay, err error) { - // if order.FromStoreID != 0 { - // result, _ := orderman.GetMatterStoreOrderCount(nil, order.FromStoreID) - // if !result.Flag { - // return nil, fmt.Errorf("该门店[%v]已在一周内申请过物料,请勿重复申请!", order.FromStoreID) - // } - // } - payCreatedAt := time.Now() - param := &tonglianpayapi.CreateUnitorderOrderParam{ - Trxamt: int(order.ActualPayPrice), - NotifyUrl: globals.TLPayNotifyURL, - Reqsn: order.VendorOrderID, - PayType: vendorPayType, - } - //暂时做兼容处理 - if vendorPayType == "JSAPI" { - param.PayType = tonglianpayapi.PayTypeWxXcx - } - if vendorPayType == tonglianpayapi.PayTypeWxXcx { - if authInfo, err := ctx.GetV2AuthInfo(); err == nil && authInfo.GetAuthType() == weixin.AuthTypeMini { - param.Acct = authInfo.GetAuthID() - } - } - if vendorPayType == tonglianpayapi.PayTypeH5 { - param2 := &tonglianpayapi.CreateH5UnitorderOrderParam{ - Trxamt: int(order.ActualPayPrice), - NotifyUrl: globals.TLPayNotifyURL, - Body: "京西菜市", - Charset: "UTF-8", - } - err = api.TLpayAPI.CreateH5UnitorderOrder(param2) - } else { - result, err := api.TLpayAPI.CreateUnitorderOrder(param) - if err == nil { - var result2 tonglianpayapi.PayInfo - json.Unmarshal([]byte(result.PayInfo), &result2) - prePayID := result2.Package[strings.LastIndex(result2.Package, "=")+1 : len(result2.Package)] - orderPay = &model.OrderPay{ - PayOrderID: param.Reqsn, - PayType: payType, - VendorPayType: vendorPayType, - TransactionID: result.TrxID, - VendorOrderID: order.VendorOrderID, - VendorID: order.VendorID, - Status: 0, - PayCreatedAt: payCreatedAt, - PrepayID: prePayID, - CodeURL: utils.LimitUTF8StringLen(result.PayInfo, 3200), - TotalFee: int(order.ActualPayPrice), - } - } - } - return orderPay, err -} - -func OnTLPayCallback(call *tonglianpayapi.CallBackResult) (err error) { - globals.SugarLogger.Debugf("OnTLPayCallback msg:%s", utils.Format4Output(call, true)) - switch call.TrxCode { - case tonglianpayapi.MsgTypePay: - err = onTLpayFinished(call) - case tonglianpayapi.MsgTypeRefund: - err = onTLpayRefund(call) - } - return err -} - -func onTLpayFinished(call *tonglianpayapi.CallBackResult) (err error) { - orderPay := &model.OrderPay{ - PayOrderID: call.CusorderID, - // PayType: model.PayTypeTL, - } - orderPay.DeletedAt = utils.DefaultTimeValue - db := dao.GetDB() - if err = dao.GetEntity(db, orderPay, "PayOrderID", "DeletedAt"); err == nil { - if orderPay.Status != 0 { - globals.SugarLogger.Debugf("already pay msg:%s, err:%v", utils.Format4Output(call, true), err) - return err - } - loc, _ := time.LoadLocation("Local") - t1, _ := time.ParseInLocation("20060102150405", call.PayTime, loc) - orderPay.PayFinishedAt = utils.Time2Pointer(t1) - // orderPay.TransactionID = call.ChnlTrxID - orderPay.OriginalData = utils.Format4Output(call, true) - if call.TrxStatus == tonglianpayapi.TrxStatusSuccess { - orderPay.Status = model.PayStatusYes - } else { - orderPay.Status = model.PayStatusFailed - } - dao.UpdateEntity(db, orderPay) - if call.TrxStatus == tonglianpayapi.TrxStatusSuccess { - err = OnPayFinished(orderPay) - } - } else { - globals.SugarLogger.Debugf("onTLpayFinished msg:%s, err:%v", utils.Format4Output(call, true), err) - } - return err -} - -func onTLpayRefund(call *tonglianpayapi.CallBackResult) (err error) { - orderPayRefund := &model.OrderPayRefund{ - RefundID: call.CusorderID, - } - db := dao.GetDB() - if err = dao.GetEntity(db, orderPayRefund, "RefundID"); err == nil { - if call.TrxStatus == tonglianpayapi.TrxStatusSuccess { - orderPayRefund.Status = model.RefundStatusYes - } else { - orderPayRefund.Status = model.RefundStatusFailed - } - orderPayRefund.OriginalData = utils.Format4Output(call, true) - dao.UpdateEntity(db, orderPayRefund) - } else if dao.IsNoRowsError(err) { - globals.SugarLogger.Warnf("收到异常的退款事件, call:%s", utils.Format4Output(call, true)) - } - - orderPay := &model.OrderPay{ - VendorOrderID: orderPayRefund.VendorOrderID, - VendorID: jxutils.GetPossibleVendorIDFromVendorOrderID(orderPayRefund.VendorOrderID), - PayType: model.PayTypeWX, - Status: model.PayStatusYes, - } - orderPay.DeletedAt = utils.DefaultTimeValue - if err = dao.GetEntity(db, orderPay, "VendorOrderID", "VendorID", "PayType", "Status", "DeletedAt"); err == nil { - orderPay.Status = model.PayStatusRefund - dao.UpdateEntity(db, orderPay) - } - return err -} - -func RefundOrderByTL(ctx *jxcontext.Context, orderPay *model.OrderPay, refundID string, refundFee int, refundDesc string) (orderPayRefund *model.OrderPayRefund, err error) { - result, err := api.TLpayAPI.PayRefund(&tonglianpayapi.PayRefundParam{ - Trxamt: refundFee, - Reqsn: utils.GetUUID(), - Remark: refundDesc, - OldTrxID: orderPay.TransactionID, - }) - if err == nil { - orderPayRefund = &model.OrderPayRefund{ - RefundID: refundID, - VendorRefundID: result.TrxID, - VendorOrderID: orderPay.VendorOrderID, - VendorID: orderPay.VendorID, - Status: model.RefundStatusNo, - TransactionID: orderPay.TransactionID, - RefundFee: refundFee, - RefundCreatedAt: time.Now(), - } - dao.WrapAddIDCULDEntity(orderPayRefund, ctx.GetUserName()) - db := dao.GetDB() - if result.TrxStatus == tonglianpayapi.TrxStatusSuccess { - orderPayRefund.Status = model.RefundStatusYes - } else { - orderPayRefund.Status = model.RefundStatusFailed - } - orderPayRefund.OriginalData = utils.Format4Output(result, true) - dao.CreateEntity(db, orderPayRefund) - - orderPay.Status = model.PayStatusRefund - dao.UpdateEntity(db, orderPay) - } - return orderPayRefund, err -} diff --git a/business/partner/purchase/jx/localjx/user.go b/business/partner/purchase/jx/localjx/user.go deleted file mode 100644 index 06017baee..000000000 --- a/business/partner/purchase/jx/localjx/user.go +++ /dev/null @@ -1,65 +0,0 @@ -package localjx - -import ( - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/globals/api" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/model" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" -) - -type GetJxShopUsersResult struct { - model.User - BuyCount int `json:"buyCount"` - ActualPayPrice int `json:"actualPayPrice"` - GoodCommentCount int `json:"goodCommentCount"` - BadCommentCount int `json:"badCommentCount"` - UserMembers []*model.UserMember `json:"userMembers"` -} - -func GetJxShopUsers(ctx *jxcontext.Context, keyword string, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) { - var ( - requestList []*GetJxShopUsersResult - db = dao.GetDB() - ) - sql := ` - SELECT SQL_CALC_FOUND_ROWS DISTINCT a.*, b.buy_count, b.actual_pay_price - FROM user a, - (SELECT a.user_id, COUNT(*) buy_count, SUM(c.actual_pay_price) actual_pay_price - FROM user a - JOIN auth_bind b ON b.user_id = a.user_id AND b.deleted_at = ? AND b.type_id = ? - JOIN goods_order c ON c.user_id = a.user_id AND c.status <> ? AND c.store_id <> ? - WHERE a.deleted_at = ? - GROUP BY 1) b - WHERE a.user_id = b.user_id - ` - sqlParams := []interface{}{ - utils.DefaultTimeValue, api.WeixinMiniAppID2, - model.OrderStatusCanceled, model.MatterStoreID, - utils.DefaultTimeValue, - } - if keyword != "" { - sql += " AND (a.user_id LIKE ? OR a.name LIKE ? OR a.mobile LIKE ? OR a.user_id2 LIKE ?)" - sqlParams = append(sqlParams, "%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%") - } - sql += "LIMIT ? OFFSET ?" - pageSize = jxutils.FormalizePageSize(pageSize) - sqlParams = append(sqlParams, pageSize, offset) - dao.Begin(db) - defer dao.Commit(db) - if err = dao.GetRows(db, &requestList, sql, sqlParams...); err == nil { - pagedInfo = &model.PagedInfo{ - TotalCount: dao.GetLastTotalRowCount(db), - // Data: requestList, - } - for _, v := range requestList { - userMembers, _ := dao.GetUserMember(db, v.UserID, "", model.MemberTypeDiscountCard, model.YES) - v.UserMembers = userMembers - } - pagedInfo.Data = requestList - } - return pagedInfo, err -} diff --git a/business/partner/purchase/jx/localjx/wxpay.go b/business/partner/purchase/jx/localjx/wxpay.go deleted file mode 100644 index edebf972e..000000000 --- a/business/partner/purchase/jx/localjx/wxpay.go +++ /dev/null @@ -1,152 +0,0 @@ -package localjx - -import ( - "fmt" - "time" - - "git.rosy.net.cn/baseapi/platformapi/wxpayapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/auth2/authprovider/weixin" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -func vendorPayType2WxpayType(vendorPayType string) string { - return vendorPayType -} - -func getOrderBrief(order *model.GoodsOrder) string { - return fmt.Sprintf("%s等共%d件商品", order.Skus[0].SkuName, order.GoodsCount) -} - -func pay4OrderByWX(ctx *jxcontext.Context, order *model.GoodsOrder, vendorPayType string) (orderPay *model.OrderPay, err error) { - payCreatedAt := time.Now() - param := &wxpayapi.CreateOrderParam{ - OutTradeNo: utils.Int64ToStr(GenPayOrderID(order)), - Body: getOrderBrief(order), - NotifyURL: globals.WxpayNotifyURL, - SpbillCreateIP: ctx.GetRealRemoteIP(), - TradeType: vendorPayType2WxpayType(vendorPayType), - TotalFee: int(order.ActualPayPrice), - - TimeStart: wxpayapi.Time2PayTime(payCreatedAt), - // TimeExpire: wxpayapi.Time2PayTime(payCreatedAt.Add(PayWaitingTime)), - ProfitSharing: wxpayapi.OptYes, - } - if authInfo, err := ctx.GetV2AuthInfo(); err == nil && authInfo.GetAuthType() == weixin.AuthTypeMini { - param.OpenID = authInfo.GetAuthID() - } - result, err := api.WxpayAPI.CreateUnifiedOrder(param) - if err == nil { - orderPay = &model.OrderPay{ - PayOrderID: param.OutTradeNo, - PayType: model.PayTypeWX, - VendorPayType: vendorPayType, - - VendorOrderID: order.VendorOrderID, - VendorID: order.VendorID, - Status: 0, - PayCreatedAt: payCreatedAt, - PrepayID: result.PrepayID, - CodeURL: result.CodeURL, - TotalFee: int(order.ActualPayPrice), - } - } - return orderPay, err -} - -func OnWxPayCallback(msg *wxpayapi.CallbackMsg) (err error) { - globals.SugarLogger.Debugf("OnWxPayCallback msg:%s", utils.Format4Output(msg, true)) - switch msg.MsgType { - case wxpayapi.MsgTypePay: - err = onWxpayFinished(msg.Data.(*wxpayapi.PayResultMsg)) - case wxpayapi.MsgTypeRefund: - err = onWxpayRefund(msg.Data.(*wxpayapi.RefundResultMsg)) - } - return err -} - -func onWxpayFinished(msg *wxpayapi.PayResultMsg) (err error) { - orderPay := &model.OrderPay{ - PayOrderID: msg.OutTradeNo, - PayType: model.PayTypeWX, - } - orderPay.DeletedAt = utils.DefaultTimeValue - db := dao.GetDB() - if err = dao.GetEntity(db, orderPay, "PayOrderID", "PayType", "DeletedAt"); err == nil { - orderPay.PayFinishedAt = utils.Time2Pointer(wxpayapi.PayTime2Time(msg.TimeEnd)) - orderPay.TransactionID = msg.TransactionID - orderPay.OriginalData = utils.Format4Output(msg, true) - if msg.ResultCode == wxpayapi.ResponseCodeSuccess { - orderPay.Status = model.PayStatusYes - } else { - orderPay.Status = model.PayStatusFailed - } - dao.UpdateEntity(db, orderPay) - if msg.ResultCode == wxpayapi.ResponseCodeSuccess { - err = OnPayFinished(orderPay) - } - } else { - globals.SugarLogger.Debugf("onWxpayFinished msg:%s, err:%v", utils.Format4Output(msg, true), err) - } - return err -} - -func onWxpayRefund(msg *wxpayapi.RefundResultMsg) (err error) { - orderPayRefund := &model.OrderPayRefund{ - RefundID: msg.ReqInfoObj.OutRefundNo, - } - db := dao.GetDB() - if err = dao.GetEntity(db, orderPayRefund, "RefundID"); err == nil { - if msg.ResultCode == wxpayapi.ResponseCodeSuccess { - orderPayRefund.Status = model.RefundStatusYes - } else { - orderPayRefund.Status = model.RefundStatusFailed - } - orderPayRefund.OriginalData = utils.Format4Output(msg, true) - dao.UpdateEntity(db, orderPayRefund) - } else if dao.IsNoRowsError(err) { - globals.SugarLogger.Warnf("收到异常的退款事件, msg:%s", utils.Format4Output(msg, true)) - } - - orderPay := &model.OrderPay{ - VendorOrderID: orderPayRefund.VendorOrderID, - VendorID: jxutils.GetPossibleVendorIDFromVendorOrderID(orderPayRefund.VendorOrderID), - PayType: model.PayTypeWX, - Status: model.PayStatusYes, - } - orderPay.DeletedAt = utils.DefaultTimeValue - if err = dao.GetEntity(db, orderPay, "VendorOrderID", "VendorID", "PayType", "Status", "DeletedAt"); err == nil { - orderPay.Status = model.PayStatusRefund - dao.UpdateEntity(db, orderPay) - } - return err -} - -func refundOrderByWX(ctx *jxcontext.Context, orderPay *model.OrderPay, refundID string, refundFee int, refundDesc string) (orderPayRefund *model.OrderPayRefund, err error) { - result, err := api.WxpayAPI.PayRefund(&wxpayapi.PayRefundParam{ - OutTradeNo: orderPay.VendorOrderID, - NotifyURL: globals.WxpayNotifyURL, - OutRefundNo: refundID, - TotalFee: orderPay.TotalFee, - RefundFee: refundFee, - RefundDesc: wxpayapi.CData(refundDesc), - }) - if err == nil { - orderPayRefund = &model.OrderPayRefund{ - RefundID: refundID, - VendorRefundID: result.RefundID, - VendorOrderID: orderPay.VendorOrderID, - VendorID: orderPay.VendorID, - Status: model.RefundStatusNo, - TransactionID: orderPay.TransactionID, - RefundFee: orderPay.TotalFee, - RefundCreatedAt: time.Now(), - } - } - return orderPayRefund, err -} diff --git a/business/partner/purchase/jx/order.go b/business/partner/purchase/jx/order.go deleted file mode 100644 index 4c36f9c25..000000000 --- a/business/partner/purchase/jx/order.go +++ /dev/null @@ -1,134 +0,0 @@ -package jx - -import ( - "time" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/business/partner/purchase/jx/localjx" - "git.rosy.net.cn/jx-callback/business/partner/purchase/jx/phpjx" -) - -func (c *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) { - return order -} - -func (c *PurchaseHandler) GetOrder(vendorOrgCode, orderID string) (order *model.GoodsOrder, err error) { - order, err = partner.CurOrderManager.LoadOrder(orderID, model.VendorIDJX) - return order, err -} - -func (p *PurchaseHandler) GetOrderStatus(vendorOrgCode, vendorOrderID string) (status int, err error) { - order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, model.VendorIDJX) - if err == nil { - status = order.Status - } - return status, err -} - -func (c *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) { - var status int - if isAcceptIt { - status = model.OrderStatusAccepted - } else { - status = model.OrderStatusCanceled - } - if model.IsOrderJXTemp(order) { - err = phpjx.NotifyOrderStatusChanged(order, status) - } else { - err = localjx.AcceptOrRefuseOrder(order, isAcceptIt, userName) - } - return err -} - -func (c *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) { - if model.IsOrderJXTemp(order) { - err = phpjx.NotifyOrderStatusChanged(order, model.OrderStatusFinishedPickup) - } else { - err = localjx.PickupGoods(order, isSelfDelivery, userName) - } - return err -} - -func (p *PurchaseHandler) AcceptOrRefuseFailedGetOrder(ctx *jxcontext.Context, order *model.GoodsOrder, isAcceptIt bool) (err error) { - return err -} - -func (p *PurchaseHandler) CallCourier(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 拣货失败后再次招唤平台配送 - return err -} - -func (p *PurchaseHandler) ConfirmReceiveGoods(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 投递失败后确认收到退货 - return err -} - -func (c *PurchaseHandler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) { - return err -} - -func (c *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName string) (err error) { - return err -} - -func (c *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) { - if model.IsOrderJXTemp(order) { - err = phpjx.NotifyOrderStatusChanged(order, model.OrderStatusDelivering) - } else { - err = localjx.SelfDeliverDelivering(order, userName) - } - return err -} - -func (c *PurchaseHandler) SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) { - if model.IsOrderJXTemp(order) { - err = phpjx.NotifyOrderStatusChanged(order, model.OrderStatusFinished) - } else { - err = localjx.SelfDeliverDelivered(order, userName) - } - return err -} - -func (c *PurchaseHandler) GetOrderRealMobile(ctx *jxcontext.Context, order *model.GoodsOrder) (mobile string, err error) { - return mobile, err -} - -func (c *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) { - if model.IsOrderJXTemp(order) { - } else { - err = localjx.AgreeOrRefuseCancel(ctx, order, isAgree, reason) - } - return err -} - -func (c *PurchaseHandler) CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) { - if model.IsOrderJXTemp(order) { - err = phpjx.NotifyOrderStatusChanged(order, model.OrderStatusCanceled) - } else { - err = localjx.CancelOrder(ctx, order, reason) - } - return err -} - -func (c *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) { - if model.IsOrderJXTemp(order) { - } else { - err = localjx.AdjustOrder(ctx, order, removedSkuList, reason) - } - return err -} - -func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, queryDate time.Time, vendorStoreID string) (vendorOrderIDs []string, err error) { - return vendorOrderIDs, err -} - -func (c *PurchaseHandler) ConfirmSelfTake(ctx *jxcontext.Context, vendorOrderID, selfTakeCode string) (err error) { - order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, model.VendorIDJX) - if err == nil { - if model.IsOrderJXTemp(order) { - err = phpjx.NotifyOrderStatusChanged(order, model.OrderStatusFinished) - } - } - return err -} diff --git a/business/partner/purchase/jx/order_afs.go b/business/partner/purchase/jx/order_afs.go deleted file mode 100644 index c67602161..000000000 --- a/business/partner/purchase/jx/order_afs.go +++ /dev/null @@ -1,170 +0,0 @@ -package jx - -import ( - "fmt" - "strings" - "time" - - "git.rosy.net.cn/jx-callback/business/jxutils" - - "git.rosy.net.cn/jx-callback/globals" - - "git.rosy.net.cn/jx-callback/business/model/dao" - - "git.rosy.net.cn/jx-callback/globals/api" - - "git.rosy.net.cn/jx-callback/business/partner/purchase/jx/localjx" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" -) - -// 审核售后单申请 -func (c *PurchaseHandler) AgreeOrRefuseRefund(ctx *jxcontext.Context, order *model.AfsOrder, approveType int, reason string) (err error) { - var status int - if approveType == partner.AfsApproveTypeRefused { - status = model.AfsOrderStatusFailed - } else { - status = model.AfsOrderStatusFinished - } - orderStatus := &model.OrderStatus{ - VendorOrderID: order.AfsOrderID, // 是售后单ID,不是订单ID,订单ID在RefVendorOrderID中 - VendorID: order.VendorID, - OrderType: model.OrderTypeAfsOrder, - RefVendorOrderID: order.VendorOrderID, - RefVendorID: order.VendorID, - VendorStatus: utils.Int2Str(status), - Status: status, - StatusTime: time.Now(), - Remark: reason, - } - if status == model.AfsOrderStatusFinished { - orderPays, err := dao.GetOrderPayList(dao.GetDB(), order.VendorOrderID, order.VendorID) - if err == nil { - _, err = localjx.RefundOrderByTL(ctx, orderPays[0], order.VendorOrderID, int(order.SkuUserMoney), reason) - if err != nil { - return err - } else { - partner.CurOrderManager.OnAfsOrderStatusChanged(orderStatus) - } - } - } else { - partner.CurOrderManager.OnAfsOrderStatusChanged(orderStatus) - } - return err -} - -// 确认收到退货 -func (c *PurchaseHandler) ConfirmReceivedReturnGoods(ctx *jxcontext.Context, order *model.AfsOrder) (err error) { - err = fmt.Errorf("京西商城当前不支持ConfirmReceivedReturnGoods") - return err -} - -// 发起全款退款 -func (c *PurchaseHandler) RefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) { - err = c.PartRefundOrder(ctx, order, order.Skus, reason) - return err -} - -// 发起部分退款 -func (c *PurchaseHandler) PartRefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, refundSkuList []*model.OrderSku, reason string) (err error) { - globals.SugarLogger.Debugf("PartRefundOrder jx, orderID :%v", order.VendorOrderID) - var ( - skuMap = make(map[int]*model.OrderSku) - appID = "" - salePrice int64 - db = dao.GetDB() - ) - if time.Now().Sub(order.OrderCreatedAt) > 24*time.Hour { - return fmt.Errorf("已超过售后申请时间,如有疑问请联系门店!") - } - referer := ctx.GetRequest().Referer() - index := strings.Index(referer, "//") - if index > 0 { - list := strings.Split(referer[index+2:], "/") - if len(list) >= 2 { - appID = list[1] - } - } - for _, sku := range order.Skus { - skuMap[sku.SkuID] = sku - } - orderStatus := buildOrderStatus(ctx, order, reason, isJxShop(appID)) - afsOrder := &model.AfsOrder{ - VendorID: order.VendorID, - AfsOrderID: orderStatus.VendorOrderID, - VendorOrderID: orderStatus.RefVendorOrderID, - VendorStoreID: order.VendorStoreID, - StoreID: order.StoreID, - AfsCreatedAt: time.Now(), - VendorAppealType: "", - AppealType: model.AfsAppealTypeRefund, - VendorReasonType: utils.Int2Str(model.AfsReasonNotOthers), - ReasonType: model.AfsReasonNotOthers, - ReasonDesc: utils.LimitUTF8StringLen(reason, 1024), - ReasonImgList: "", - RefundType: model.AfsTypePartRefund, - - VendorOrgCode: "", - } - for _, sku := range refundSkuList { - orderSku := &model.OrderSkuFinancial{ - Count: sku.Count, - VendorSkuID: utils.Int2Str(sku.SkuID), - SkuID: sku.SkuID, - } - if skuMap[sku.SkuID] != nil { - orderSku.Name = skuMap[sku.SkuID].SkuName - orderSku.UserMoney = skuMap[sku.SkuID].SalePrice * int64(sku.Count) - salePrice += skuMap[sku.SkuID].SalePrice * int64(sku.Count) - } - afsOrder.SkuUserMoney += orderSku.UserMoney - afsOrder.Skus = append(afsOrder.Skus, orderSku) - } - - if !isJxShop(appID) { - orderPays, err := dao.GetOrderPayList(db, order.VendorOrderID, order.VendorID) - if err == nil { - _, err = localjx.RefundOrderByTL(ctx, orderPays[0], order.VendorOrderID, int(salePrice), reason) - if err != nil { - return err - } else { - if afsOrder != nil { - err = partner.CurOrderManager.OnAfsOrderNew(afsOrder, orderStatus) - } - } - } - } else { - err = partner.CurOrderManager.OnAfsOrderNew(afsOrder, orderStatus) - } - return err -} - -func buildOrderStatus(ctx *jxcontext.Context, order *model.GoodsOrder, reason string, isJxShop bool) (orderStatus *model.OrderStatus) { - orderStatus = &model.OrderStatus{ - VendorOrderID: utils.Int64ToStr(jxutils.GenAfsOrderNo()), // 是售后单ID,不是订单ID,订单ID在RefVendorOrderID中 - VendorID: order.VendorID, - OrderType: model.OrderTypeAfsOrder, - RefVendorOrderID: order.VendorOrderID, - RefVendorID: order.VendorID, - VendorStatus: utils.Int2Str(model.AfsOrderStatusWait4Approve), - // Status: model.AfsOrderStatusWait4Approve, - StatusTime: time.Now(), - Remark: reason, - } - if isJxShop { - orderStatus.Status = model.AfsOrderStatusWait4Approve - } else { - orderStatus.Status = model.AfsOrderStatusFinished - } - return orderStatus -} - -func isJxShop(appID string) bool { - if appID == api.WeixinMiniAppID2 { - return true - } - return false -} diff --git a/business/partner/purchase/jx/order_comment.go b/business/partner/purchase/jx/order_comment.go deleted file mode 100644 index 20553a214..000000000 --- a/business/partner/purchase/jx/order_comment.go +++ /dev/null @@ -1,10 +0,0 @@ -package jx - -import ( - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" -) - -func (c *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, vendorOrgCode string, orderComment *model.OrderComment, replyComment string) (err error) { - return err -} diff --git a/business/partner/purchase/jx/phpjx/callback.go b/business/partner/purchase/jx/phpjx/callback.go deleted file mode 100644 index 49dc06968..000000000 --- a/business/partner/purchase/jx/phpjx/callback.go +++ /dev/null @@ -1,55 +0,0 @@ -package phpjx - -import ( - "fmt" - "time" - - "git.rosy.net.cn/baseapi/utils" -) - -const ( - appKey = "4A86853D-E4B6-454E-940A-B68ECDA2B73E" - - MsgTypeOrder = "order" - MsgTypeAfsOrder = "afsOrder" -) - -type CallbackResponse struct { - Code int `json:"code"` - Data string `json:"data"` -} - -type CallbackMsg struct { - AppKey string `json:"appKey"` - MsgType string `json:"msgType"` - SubMsgType string `json:"subMsgType"` - ThingID string `json:"thingID"` - ThingID2 string `json:"thingID2"` - Data string `json:"data"` - Timestamp int64 `json:"timestamp"` -} - -func OnCallbackMsg(msg *CallbackMsg) (retVal, errCode string, err error) { - if msg.AppKey != appKey { - return retVal, errCode, fmt.Errorf("无效的AppKey:%s", msg.AppKey) - } - if msg.MsgType == MsgTypeOrder { - retVal, errCode, err = OnOrderMsg(msg) - } else if msg.MsgType == MsgTypeAfsOrder { - err = OnAfsOrderMsg(msg) - } - return retVal, errCode, err -} - -func postFakeMsg(orderNo string, status int) { - msg := &CallbackMsg{ - AppKey: appKey, - MsgType: MsgTypeOrder, - SubMsgType: utils.Int2Str(status), - ThingID: orderNo, - Timestamp: time.Now().Unix(), - } - utils.CallFuncAsync(func() { - OnCallbackMsg(msg) - }) -} diff --git a/business/partner/purchase/jx/phpjx/callback_test.go b/business/partner/purchase/jx/phpjx/callback_test.go deleted file mode 100644 index 361777628..000000000 --- a/business/partner/purchase/jx/phpjx/callback_test.go +++ /dev/null @@ -1,52 +0,0 @@ -package phpjx - -import ( - "testing" - - _ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals/testinit" -) - -func init() { - testinit.Init() -} - -func TestBuildNewJxOrder(t *testing.T) { - order, err := partner.CurOrderManager.LoadOrder("920931913000041", model.VendorIDJD) - if err != nil { - t.Fatal(err) - } - order.VendorID = model.VendorIDJX - order.VendorStoreID = utils.Int2Str(order.StoreID) - for _, sku := range order.Skus { - sku.VendorID = model.VendorIDJX - sku.VendorSkuID = utils.Int2Str(sku.SkuID) - } - order2 := &Data4Neworder{ - GoodsOrder: *order, - Skus: order.Skus, - } - msg := &CallbackMsg{ - AppKey: appKey, - MsgType: MsgTypeOrder, - SubMsgType: utils.Int2Str(model.OrderStatusNew), - ThingID: order.VendorOrderID, - Data: utils.Format4Output(order2, true), - } - t.Logf("\n%s", msg.AppKey) - t.Logf("\n%s", msg.MsgType) - t.Logf("\n%s", msg.SubMsgType) - t.Logf("\n%s", msg.ThingID) - t.Logf("\n%s", msg.Data) - - var order3 *model.GoodsOrder - err = utils.UnmarshalUseNumber([]byte(msg.Data), &order3) - if err != nil { - t.Fatal(err) - } - t.Log(order3.OrderCreatedAt) -} diff --git a/business/partner/purchase/jx/phpjx/jxapi.go b/business/partner/purchase/jx/phpjx/jxapi.go deleted file mode 100644 index 1c6cd25a4..000000000 --- a/business/partner/purchase/jx/phpjx/jxapi.go +++ /dev/null @@ -1,99 +0,0 @@ -package phpjx - -import ( - "fmt" - "net/http" - "strings" - - "git.rosy.net.cn/baseapi" - "git.rosy.net.cn/baseapi/platformapi" - "git.rosy.net.cn/baseapi/utils" -) - -type API struct { - token string - appKey string - appSecret string - client *http.Client - config *platformapi.APIConfig -} - -const ( - ResponseCodeSuccess = 200 -) - -const ( - prodURL = "https://www.jingxicaishi.com/index.php/Weimendian/index" -) - -var ( - exceedLimitCodes = map[int]int{} - canRetryCodes = map[int]int{} -) - -var ( - jxAPI *API -) - -func NewAPI(token, appKey, appSecret string, config ...*platformapi.APIConfig) *API { - curConfig := platformapi.DefAPIConfig - if len(config) > 0 { - curConfig = *config[0] - } - return &API{ - token: token, - appKey: appKey, - appSecret: appSecret, - client: &http.Client{Timeout: curConfig.ClientTimeout}, - config: &curConfig, - } -} - -func init() { - jxAPI = NewAPI("", "", "") -} - -func (a *API) AccessAPI(apiStr string, jxParams map[string]interface{}, traceInfo string) (retVal map[string]interface{}, err error) { - err = platformapi.AccessPlatformAPIWithRetry(a.client, - func() *http.Request { - params := utils.MergeMaps(jxParams, map[string]interface{}{ - "timestamp": utils.GetCurTimeStr(), - }) - var request *http.Request - if false { - - } else { - fullURL := prodURL + "/" + apiStr - // baseapi.SugarLogger.Debug(utils.Map2URLValues(params).Encode()) - request, _ = http.NewRequest(http.MethodPost, fullURL, strings.NewReader(utils.Map2URLValues(params).Encode())) - request.Header.Set("charset", "UTF-8") - request.Header.Set("Content-Type", "application/x-www-form-urlencoded") - } - if traceInfo != "" { - request.Header.Set(platformapi.KeyTrackInfo, traceInfo) - } - // request.Close = true //todo 为了性能考虑还是不要关闭 - 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") - } - code := int(utils.Interface2Int64WithDefault(jsonResult1["code"], 0)) - if code == ResponseCodeSuccess { - retVal = jsonResult1 - return platformapi.ErrLevelSuccess, nil - } - newErr := utils.NewErrorIntCode(jsonResult1["msg"].(string), code) - if _, ok := exceedLimitCodes[code]; ok { - return platformapi.ErrLevelExceedLimit, newErr - } else if _, ok := canRetryCodes[code]; ok { - return platformapi.ErrLevelRecoverableErr, newErr - } else { - baseapi.SugarLogger.Debugf("jx AccessAPI failed, jsonResult1:%s", utils.Format4Output(jsonResult1, true)) - return platformapi.ErrLevelCodeIsNotOK, newErr - } - }) - return retVal, err -} diff --git a/business/partner/purchase/jx/phpjx/jxapi_order.go b/business/partner/purchase/jx/phpjx/jxapi_order.go deleted file mode 100644 index ef2befb2f..000000000 --- a/business/partner/purchase/jx/phpjx/jxapi_order.go +++ /dev/null @@ -1,45 +0,0 @@ -package phpjx - -import ( - "git.rosy.net.cn/jx-callback/business/model" -) - -var ( - orderStatusMap = map[int]int{ - model.OrderStatusFinishedPickup: 7, - model.OrderStatusDelivering: 8, - // 4, - model.OrderStatusFinished: 3, - model.OrderStatusCanceled: 3, - } -) - -func translateOrderStatus(status int) (outStatus int) { - return status //orderStatusMap[status] -} - -func (a *API) NotifyOrderStatusChanged(order *model.GoodsOrder) (err error) { - status := translateOrderStatus(order.Status) - if status > 0 { - _, err = a.AccessAPI("orderChangeStatus", map[string]interface{}{ - "orderid": order.VendorOrderID, - "status": status, - "data": "", //string(utils.MustMarshal(order)), - }, "") - } - return err -} - -func (a *API) NotifyAfsOrderStatusChanged(afsOrder *model.AfsOrder) (err error) { - status := translateOrderStatus(afsOrder.Status) - if status > 0 { - _, err = a.AccessAPI("afsOrderChangeStatus", map[string]interface{}{ - "orderid": afsOrder.VendorOrderID, - "afsOrderID": afsOrder.AfsOrderID, - "status": status, - "data": "", //string(utils.MustMarshal(order)), - }, "") - } - return err -} - diff --git a/business/partner/purchase/jx/phpjx/jxapi_order_test.go b/business/partner/purchase/jx/phpjx/jxapi_order_test.go deleted file mode 100644 index d74be9133..000000000 --- a/business/partner/purchase/jx/phpjx/jxapi_order_test.go +++ /dev/null @@ -1,21 +0,0 @@ -package phpjx - -import ( - "testing" - - _ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" - - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" -) - -func TestNotifyOrderStatusChanged(t *testing.T) { - order, err := partner.CurOrderManager.LoadOrder("920931913000041", model.VendorIDJX) - if err != nil { - t.Fatal(err) - } - err = jxAPI.NotifyOrderStatusChanged(order) - if err != nil { - t.Fatal(err) - } -} diff --git a/business/partner/purchase/jx/phpjx/order.go b/business/partner/purchase/jx/phpjx/order.go deleted file mode 100644 index c4dd0b068..000000000 --- a/business/partner/purchase/jx/phpjx/order.go +++ /dev/null @@ -1,84 +0,0 @@ -package phpjx - -import ( - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" -) - -func NotifyOrderStatusChanged(order *model.GoodsOrder, status int) (err error) { - orderMsg := *order - orderMsg.Status = status - if err = jxAPI.NotifyOrderStatusChanged(&orderMsg); err == nil { - postFakeMsg(orderMsg.VendorOrderID, orderMsg.Status) - } - return err -} - -type Data4Neworder struct { - model.GoodsOrder - Skus []*model.OrderSku `json:"skus"` -} - -func OnOrderMsg(msg *CallbackMsg) (retVal, errCode string, err error) { - jxutils.CallMsgHandler(func() { - retVal, errCode, err = onOrderMsg(msg) - }, jxutils.ComposeUniversalOrderID(msg.ThingID, model.VendorIDJX)) - return retVal, errCode, err -} - -func onOrderMsg(msg *CallbackMsg) (retVal, errCode string, err error) { - subMsgType := int(utils.Str2Int64WithDefault(msg.SubMsgType, 0)) - if subMsgType == model.OrderStatusNew || subMsgType == model.OrderStatusAdjust { - var order *Data4Neworder - if err = utils.UnmarshalUseNumber([]byte(msg.Data), &order); err == nil { - if order.VendorStatus == "" { - order.VendorStatus = utils.Int2Str(order.Status) - } - retVal, errCode, err = onOrderNew(msg, subMsgType, order) - } - } else { - status := callbackMsg2Status(msg) - err = partner.CurOrderManager.OnOrderStatusChanged("", status) - } - return retVal, errCode, err -} - -func callbackMsg2Status(msg *CallbackMsg) *model.OrderStatus { - orderStatus := &model.OrderStatus{ - VendorOrderID: msg.ThingID, - VendorID: model.VendorIDJX, - OrderType: model.OrderTypeOrder, - RefVendorOrderID: msg.ThingID, - RefVendorID: model.VendorIDJX, - VendorStatus: msg.SubMsgType, - Status: int(utils.Str2Int64WithDefault(msg.SubMsgType, 0)), - StatusTime: utils.Timestamp2Time(msg.Timestamp), - Remark: "", - } - return orderStatus -} - -func onOrderNew(msg *CallbackMsg, subMsgType int, order *Data4Neworder) (retVal, errCode string, err error) { - globals.SugarLogger.Debugf("onOrderNew orderID:%s", msg.ThingID) - order.StoreID = int(utils.Str2Int64WithDefault(order.VendorStoreID, 0)) - if order.DeliveryType == "" { - order.DeliveryType = model.OrderDeliveryTypeStoreSelf - } - order.GoodsOrder.Skus = order.Skus - order.VendorID = model.VendorIDJX - order.Flag = model.OrderFlagMaskTempJX - for _, v := range order.GoodsOrder.Skus { - v.SkuID = int(utils.Str2Int64WithDefault(v.VendorSkuID, 0)) - } - jxutils.RefreshOrderSkuRelated(&order.GoodsOrder) - orderStatus := model.Order2Status(&order.GoodsOrder) - if subMsgType == model.OrderStatusNew { - err = partner.CurOrderManager.OnOrderNew(&order.GoodsOrder, orderStatus) - } else if subMsgType == model.OrderStatusAdjust { - err = partner.CurOrderManager.OnOrderAdjust(&order.GoodsOrder, orderStatus) - } - return retVal, errCode, err -} diff --git a/business/partner/purchase/jx/phpjx/order_afs.go b/business/partner/purchase/jx/phpjx/order_afs.go deleted file mode 100644 index 2e2fbd109..000000000 --- a/business/partner/purchase/jx/phpjx/order_afs.go +++ /dev/null @@ -1,130 +0,0 @@ -package phpjx - -import ( - "time" - - "git.rosy.net.cn/baseapi/platformapi/jdapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" -) - -type Data4AfsOrderSku struct { - VendorSkuID string `orm:"column(vendor_sku_id);size(48)" json:"vendorSkuID"` // 平台skuid - PromotionType int `json:"promotionType"` // 商品级别促销类型 (1、无优惠;2、秒杀(已经下线);3、单品直降;4、限时抢购;1202、加价购;1203、满赠(标识商品);6、买赠(买A送B,标识B);9999、表示一个普通商品参与捆绑促销,设置的捆绑类型;9998、表示一个商品参与了捆绑促销,并且还参与了其他促销类型;9997、表示一个商品参与了捆绑促销,但是金额拆分不尽,9996:组合购,8001:轻松购会员价,8:第二件N折,9:拼团促销) - Name string `orm:"size(255)" json:"name"` // 商品名 - SalePrice int64 `json:"salePrice"` // 售卖价 - Count int `json:"count"` // 订单下单数量 -} - -type Data4AfsOrder struct { - VendorOrderID string `orm:"column(vendor_order_id);size(48)" json:"vendorOrderID"` // 关联原始订单ID - AfsOrderID string `orm:"column(afs_order_id);size(48)" json:"afsOrderID"` // 售后订单ID - AfsCreatedAt time.Time `orm:"type(datetime);null;index" json:"afsCreatedAt"` // 售后单生成时间 - VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"` // 外部系统里记录的storeid - - VendorStatus string `orm:"size(255)" json:"vendorStatus"` - VendorReasonType string `orm:"size(255)" json:"vendorReasonType"` // 原始售后原因 - ReasonDesc string `orm:"size(1024)" json:"reasonDesc"` // 售后原因描述 - ReasonImgList string `orm:"size(1024)" json:"reasonImgList"` // 售后描述图片 - VendorAppealType string `orm:"size(255)" json:"vendorAppealType"` // 原始售后方式 - Skus []*Data4AfsOrderSku -} - -func OnAfsOrderMsg(msg *CallbackMsg) (err error) { - jxutils.CallMsgHandlerAsync(func() { - err = onAfsOrderMsg(msg) - }, jxutils.ComposeUniversalOrderID(msg.ThingID, model.VendorIDJX)) - return err -} - -func buildAfsOrder(msg *CallbackMsg) (outAfsOrder *model.AfsOrder, err error) { - var afsOrder *Data4AfsOrder - if err = utils.UnmarshalUseNumber([]byte(msg.Data), &afsOrder); err == nil { - outAfsOrder = &model.AfsOrder{ - VendorID: model.VendorIDJX, - AfsOrderID: afsOrder.AfsOrderID, - VendorOrderID: afsOrder.VendorOrderID, - VendorStoreID: afsOrder.VendorStoreID, - StoreID: int(utils.Str2Int64WithDefault(afsOrder.VendorStoreID, 0)), - AfsCreatedAt: afsOrder.AfsCreatedAt, - - VendorStatus: afsOrder.VendorStatus, - VendorReasonType: afsOrder.VendorReasonType, - ReasonType: int8(utils.Str2Int64WithDefault(afsOrder.VendorReasonType, 0)), - ReasonDesc: utils.LimitUTF8StringLen(afsOrder.ReasonDesc, 1024), - ReasonImgList: afsOrder.ReasonImgList, - VendorAppealType: afsOrder.VendorAppealType, - AppealType: int8(utils.Str2Int64WithDefault(afsOrder.VendorAppealType, 0)), - Flag: model.OrderFlagMaskTempJX, - } - outAfsOrder.Status = int(utils.Str2Int64WithDefault(afsOrder.VendorStatus, 0)) - - for _, x := range afsOrder.Skus { - orderSku := &model.OrderSkuFinancial{ - Count: x.Count, - VendorSkuID: x.VendorSkuID, - SkuID: int(utils.Str2Int64WithDefault(x.VendorSkuID, 0)), - Name: x.Name, - } - if x.PromotionType != 0 && x.PromotionType != jdapi.PromotionTypeNormal { - orderSku.StoreSubName = utils.Int2Str(x.PromotionType) - } - outAfsOrder.Skus = append(outAfsOrder.Skus, orderSku) - } - } - return outAfsOrder, err -} - -func callbackAfsMsg2Status(msg *CallbackMsg) *model.OrderStatus { - orderStatus := &model.OrderStatus{ - VendorOrderID: msg.ThingID2, // 是售后单ID,不是订单ID,订单ID在RefVendorOrderID中 - VendorID: model.VendorIDJX, - OrderType: model.OrderTypeAfsOrder, - RefVendorOrderID: msg.ThingID, - RefVendorID: model.VendorIDJX, - VendorStatus: msg.SubMsgType, - Status: int(utils.Str2Int64WithDefault(msg.SubMsgType, 0)), - StatusTime: utils.Timestamp2Time(msg.Timestamp), - Remark: "", - } - return orderStatus -} - -func onAfsOrderMsg(msg *CallbackMsg) (err error) { - subMsgType := int(utils.Str2Int64WithDefault(msg.SubMsgType, 0)) - status := callbackAfsMsg2Status(msg) - if subMsgType == model.AfsOrderStatusWait4Approve || subMsgType == model.AfsOrderStatusNew { - afsOrder, err2 := buildAfsOrder(msg) - if err = err2; err == nil { - err = partner.CurOrderManager.OnAfsOrderNew(afsOrder, status) - } - } else { - err = partner.CurOrderManager.OnOrderStatusChanged("", status) - } - return err -} - -func postFakeAfsMsg(orderNo, afsOrderID string, status int) { - msg := &CallbackMsg{ - AppKey: appKey, - MsgType: MsgTypeAfsOrder, - SubMsgType: utils.Int2Str(status), - ThingID: orderNo, - ThingID2: afsOrderID, - Timestamp: time.Now().Unix(), - } - utils.CallFuncAsync(func() { - OnCallbackMsg(msg) - }) -} - -func NotifyAfsOrderStatusChanged(order *model.AfsOrder, status int) (err error) { - orderMsg := *order - orderMsg.Status = status - if err = jxAPI.NotifyAfsOrderStatusChanged(&orderMsg); err == nil { - postFakeAfsMsg(orderMsg.VendorOrderID, orderMsg.AfsOrderID, orderMsg.Status) - } - return err -} diff --git a/business/partner/purchase/jx/sku.go b/business/partner/purchase/jx/sku.go deleted file mode 100644 index 32daa9b18..000000000 --- a/business/partner/purchase/jx/sku.go +++ /dev/null @@ -1,82 +0,0 @@ -package jx - -// 这里函数取得的信息,除了与自身实体相关的ID(比如PARENT ID),都已经转换成了本地ID了 - -import ( - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" -) - -// func (p *PurchaseHandler) CreateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) (err error) { -// return err -// } - -func (p *PurchaseHandler) GetAllCategories(ctx *jxcontext.Context, vendorOrgCode string) (cats []*partner.BareCategoryInfo, err error) { - return cats, err -} - -// func (p *PurchaseHandler) UpdateCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) error { -// return nil -// } - -// func (p *PurchaseHandler) DeleteCategory(db *dao.DaoDB, cat *model.SkuCategory, userName string) error { -// return nil -// } - -// func (p *PurchaseHandler) ReorderCategories(db *dao.DaoDB, parentCatID int, userName string) (err error) { -// return err -// } - -func (p *PurchaseHandler) CreateCategory2(ctx *jxcontext.Context, cat *dao.SkuStoreCatInfo) (err error) { - return err -} - -func (p *PurchaseHandler) UpdateCategory2(ctx *jxcontext.Context, cat *dao.SkuStoreCatInfo) (err error) { - return err -} - -func (p *PurchaseHandler) DeleteCategory2(ctx *jxcontext.Context, vendorOrgCode, vendorCatID string) (err error) { - return err -} - -func (p *PurchaseHandler) ReorderCategories2(ctx *jxcontext.Context, vendorOrgCode, vendorParentCatID string, vendorCatIDList []string) (err error) { - return err -} - -// func (p *PurchaseHandler) CreateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) { -// return err -// } - -// func (p *PurchaseHandler) ReadSku(ctx *jxcontext.Context, vendorOrgCode, vendorSkuID string) (skuNameExt *model.SkuNameExt, err error) { -// return skuNameExt, err -// } - -// func (p *PurchaseHandler) UpdateSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) { -// return err -// } - -// func (p *PurchaseHandler) DeleteSku(db *dao.DaoDB, sku *model.Sku, userName string) (err error) { -// return err -// } - -func (p *PurchaseHandler) CreateSku2(ctx *jxcontext.Context, sku *dao.StoreSkuSyncInfo) (err error) { - return err -} - -func (p *PurchaseHandler) UpdateSku2(ctx *jxcontext.Context, sku *dao.StoreSkuSyncInfo) (err error) { - return err -} - -func (p *PurchaseHandler) DeleteSku2(ctx *jxcontext.Context, vendorOrgCode string, sku *partner.StoreSkuInfo) (err error) { - return err -} - -func (p *PurchaseHandler) GetVendorCategories(ctx *jxcontext.Context) (vendorCats []*model.SkuVendorCategory, err error) { - return vendorCats, err -} - -func (p *PurchaseHandler) GetSkus(ctx *jxcontext.Context, vendorOrgCode string, skuID int, vendorSkuID string) (skuNameList []*partner.SkuNameInfo, err error) { - return skuNameList, err -} diff --git a/business/partner/purchase/jx/store.go b/business/partner/purchase/jx/store.go deleted file mode 100644 index c5b1c17d5..000000000 --- a/business/partner/purchase/jx/store.go +++ /dev/null @@ -1,44 +0,0 @@ -package jx - -import ( - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model/dao" -) - -func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string) (storeDetail *dao.StoreDetail, err error) { - return storeDetail, err -} - -// stoerIDs为nil表示所有 -func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName string) (err error) { - return err -} - -func (p *PurchaseHandler) RefreshAllStoresID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) { - return hint, err -} - -func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (storeStatus int, err error) { - return storeStatus, err -} - -func (p *PurchaseHandler) EnableAutoAcceptOrder(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, isSetEnable bool) (err error) { - return err -} - -func (c *PurchaseHandler) UpdateStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, status int) (err error) { - return err -} - -func (c *PurchaseHandler) UpdateStoreOpTime(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, opTimeList []int16) (err error) { - return err -} - -func (c *PurchaseHandler) GetAllStoresVendorID(ctx *jxcontext.Context, vendorOrgCode string) (vendorStoreIDs []string, err error) { - return vendorStoreIDs, err -} - -func (c *PurchaseHandler) UpdateStoreCustomID(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string, storeID int64) (err error) { - return err -} diff --git a/business/partner/purchase/jx/store_sku2.go b/business/partner/purchase/jx/store_sku2.go deleted file mode 100644 index b9d87af6a..000000000 --- a/business/partner/purchase/jx/store_sku2.go +++ /dev/null @@ -1,36 +0,0 @@ -package jx - -import ( - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/partner" -) - -func (p *PurchaseHandler) GetStoreSkusBatchSize(funcID int) (batchSize int) { - batchSize = 1 - return batchSize -} - -func (p *PurchaseHandler) GetStoreSkusBareInfo(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, storeID int, vendorStoreID string, inStoreSkuList []*partner.StoreSkuInfo) (outStoreSkuList []*partner.StoreSkuInfo, err error) { - return outStoreSkuList, err -} - -func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (successList []*partner.StoreSkuInfo, err error) { - return successList, err -} - -func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (successList []*partner.StoreSkuInfo, err error) { - return successList, err -} - -func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (successList []*partner.StoreSkuInfo, err error) { - return successList, err -} - -func (p *PurchaseHandler) CreateStoreSkusAct(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - return failedList, err -} - -func (p *PurchaseHandler) CancelActs(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - return failedList, err -} diff --git a/business/partner/purchase/mtwm/act.go b/business/partner/purchase/mtwm/act.go deleted file mode 100644 index 939b854cc..000000000 --- a/business/partner/purchase/mtwm/act.go +++ /dev/null @@ -1,260 +0,0 @@ -package mtwm - -import ( - "git.rosy.net.cn/baseapi/platformapi/mtwmapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/business/partner/putils" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -func jxActType2Mtwm(actType int) int { - if actType == model.ActSkuDirectDown { - actType = mtwmapi.RetailActTypeDirectDown - } else if actType == model.ActSkuSecKill { - actType = mtwmapi.RetailActTypeSecKill - } else { - actType = 0 - } - return actType -} - -func actOrderRules2Mtwm(actOrderRules []*model.ActOrderRule) (actDetails []*mtwmapi.FullDiscountActDetail) { - for _, v := range actOrderRules { - actDetails = append(actDetails, &mtwmapi.FullDiscountActDetail{ - OriginalPrice: jxutils.IntPrice2Standard(v.SalePrice), - ActPrice: jxutils.IntPrice2Standard(v.DeductPrice), - }) - } - return actDetails -} - -func storeSku2ActData(act *model.Act2, actStoreSku []*model.ActStoreSku2, handler func(int8) bool) (actData []*mtwmapi.RetailDiscountActData) { - orderLimit := 1 - if act.LimitCount > 0 { - orderLimit = act.LimitCount - } - for _, v := range actStoreSku { - if handler == nil || handler(v.SyncStatus) { - dayLimit := -1 - if v.Stock > 0 { - dayLimit = v.Stock - } - actData = append(actData, &mtwmapi.RetailDiscountActData{ - AppFoodCode: utils.Int2Str(v.SkuID), - // UserType: 0, - StartTime: act.BeginAt.Unix(), - EndTime: act.EndAt.Unix(), - OrderLimit: orderLimit, - DayLimit: dayLimit, - // Period: "", - // WeeksTime: "", - SettingType: mtwmapi.SettingTypeAsPrice, - ActPrice: jxutils.IntPrice2Standard(v.ActualActPrice), - // DiscountCoefficient: 0, - // Sequence: int(v.ActPrice), // 此字段不允许重复 - // ItemID: utils.Str2Int64WithDefault(v.VendorActID, 0), - }) - } - } - return actData -} - -func storeSku2ActData4Delete(actStoreSku []*model.ActStoreSku2, handler func(int8) bool) (actIDList []string) { - for _, v := range actStoreSku { - if handler == nil || handler(v.SyncStatus) { - if v.VendorActID != "" { - actIDList = append(actIDList, v.VendorActID) - } - } - } - return actIDList -} - -func isCreateOrUpdate(syncStatus int8) bool { - return model.IsSyncStatusNeedCreate(syncStatus) || model.IsSyncStatusNeedUpdate(syncStatus) -} - -func createOneShopAct(act *model.Act2, vendorStoreID string, actStoreSku []*model.ActStoreSku2) (failedList []*partner.StoreSkuInfoWithErr, err error) { - actData := storeSku2ActData(act, actStoreSku, isCreateOrUpdate) - if len(actData) > 0 { - if globals.EnableMtwmStoreWrite { - actResult, faileInfoList, err2 := api.MtwmAPI.RetailDiscountBatchSave2(vendorStoreID, jxActType2Mtwm(act.Type), actData) - err = err2 - // 忽略错误,都放在failedList里 - // if err != nil { - // return nil, err - // } - // globals.SugarLogger.Debugf("mtwm createOneShopAct actResult:%s, faileInfoList:%s err2:%v", utils.Format4Output(actResult, true), utils.Format4Output(faileInfoList, true), err2) - actStoreSkuMap := make(map[int]*model.ActStoreSku2) - for _, v := range actStoreSku { - actStoreSkuMap[v.SkuID] = v - } - - for _, v := range actResult { - if v2 := actStoreSkuMap[int(utils.Str2Int64WithDefault(v.AppFoodCode, 0))]; v2 != nil { - v2.VendorActID = utils.Int64ToStr(v.ActID) - } - } - for _, v := range faileInfoList { - if v2 := actStoreSkuMap[int(utils.Str2Int64WithDefault(v.AppFoodCode, 0))]; v2 != nil { - failedList = append(failedList, &partner.StoreSkuInfoWithErr{ - StoreSkuInfo: &partner.StoreSkuInfo{ - SkuID: v2.SkuID, - }, - VendoreID: model.VendorIDMTWM, - StoreID: int(utils.Str2Int64WithDefault(vendorStoreID, 0)), - ErrMsg: v.ErrorMsg, - }) - } - } - } else { - for _, v := range actStoreSku { - v.VendorActID = utils.Int64ToStr(jxutils.GenFakeID()) - } - } - } - return failedList, err -} - -func cancelOneShopAct(act *model.Act2, vendorStoreID string, actStoreSku []*model.ActStoreSku2) (failedList []*partner.StoreSkuInfoWithErr, err error) { - if list := storeSku2ActData4Delete(actStoreSku, nil /*model.IsSyncStatusNeedDelete*/); len(list) > 0 { - if globals.EnableMtwmStoreWrite { - failedList2, err2 := api.MtwmAPI.RetailDiscountDelete2(vendorStoreID, jxActType2Mtwm(act.Type), list) - actStoreSkuMap := make(map[string]*model.ActStoreSku2) - for _, v := range actStoreSku { - actStoreSkuMap[v.VendorActID] = v - } - for _, v := range failedList2 { - if !mtwmapi.CanDeleteActErrMsgIgnore(v.ErrorMsg) { - failedList = append(failedList, &partner.StoreSkuInfoWithErr{ - StoreSkuInfo: &partner.StoreSkuInfo{ - SkuID: actStoreSkuMap[utils.Int64ToStr(v.ActID)].SkuID, - }, - StoreID: int(utils.Str2Int64WithDefault(vendorStoreID, 0)), - ErrMsg: v.ErrorMsg, - VendoreID: model.VendorIDMTWM, - }) - } - } - err = err2 - err = nil // 强制不返回错误,使用部分错误 - } - } - return failedList, err -} - -func getActStoreSkuFromTaskResult(taskReslt []interface{}) (list []*model.ActStoreSku2) { - for _, v := range taskReslt { - actStoreSkuList := v.([]*model.ActStoreSku2) - list = append(list, actStoreSkuList...) - } - return list -} - -func createSkuAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreSku []*model.ActStoreSku2) (createdList []*model.ActStoreSku2, err error) { - globals.SugarLogger.Debugf("mtwm createSkuAct") - actStoreSkuListList := partner.SplitActStoreSku2List(actStoreSku) - task := tasksch.NewParallelTask("mtwm createSkuAct", nil, ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - list := batchItemList[0].([]*model.ActStoreSku2) - failedList, err2 := createOneShopAct(act, list[0].VendorStoreID, list) - if err = err2; err2 == nil { - if len(failedList) > 0 { - failedMap := putils.StoreSkuInfoWithErrList2MapBySku(failedList) - list = []*model.ActStoreSku2{} - for _, v := range actStoreSku { - if failedMap[v.SkuID] == nil { - list = append(list, v) - } - } - list = []*model.ActStoreSku2{} - } - retVal = []interface{}{list} - } - return retVal, err - }, actStoreSkuListList) - tasksch.HandleTask(task, parentTask, true).Run() - result, err := task.GetResult(0) - return getActStoreSkuFromTaskResult(result), err -} - -func cancelSkuAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreSku []*model.ActStoreSku2) (canceledList []*model.ActStoreSku2, err error) { - globals.SugarLogger.Debugf("mtwm cancelSkuAct") - actStoreSkuListList := partner.SplitActStoreSku2List(actStoreSku) - task := tasksch.NewParallelTask("mtwm cancelSkuAct", nil, ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - actStoreSkuList := batchItemList[0].([]*model.ActStoreSku2) - if _, err = cancelOneShopAct(act, actStoreSkuList[0].VendorStoreID, actStoreSkuList); err == nil { - retVal = []interface{}{actStoreSkuList} - } - return retVal, err - }, actStoreSkuListList) - tasksch.HandleTask(task, parentTask, true).Run() - result, err := task.GetResult(0) - return getActStoreSkuFromTaskResult(result), err -} - -func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSkuList []*model.ActStoreSku2) (err error) { - globals.SugarLogger.Debugf("mtwm SyncAct, actID:%d", act.ID) - var actStoreSkuList4Create, actStoreSkuList4Delete []*model.ActStoreSku2 - var updateItems []*dao.KVUpdateItem - - actStoreSkuMap := partner.SplitActStoreSku(actStoreSkuList) - for storeID := range actStoreSkuMap { - for _, actStoreSku := range actStoreSkuMap[storeID] { - if model.IsSyncStatusDelete(actStoreSku.SyncStatus) { - actStoreSkuList4Delete = append(actStoreSkuList4Delete, actStoreSku) - } else if model.IsSyncStatusNew(actStoreSku.SyncStatus) { - actStoreSkuList4Create = append(actStoreSkuList4Create, actStoreSku) - } - } - } - err = func() (err error) { - if model.IsSyncStatusDelete(act.SyncStatus) { - canceledList, err2 := cancelSkuAct(ctx, nil, act, actStoreSkuList) - updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, canceledList, model.SyncFlagModifiedMask)...) - if err = err2; err == nil { - updateItems = append(updateItems, partner.Act2Update(ctx, act, model.SyncFlagModifiedMask)) - } - } else if model.IsSyncStatusNew(act.SyncStatus) { - createdList, err2 := createSkuAct(ctx, nil, act, actStoreSkuList4Create) - updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, createdList, model.SyncFlagNewMask)...) - if err = err2; err == nil { - updateItems = append(updateItems, partner.Act2Update(ctx, act, model.SyncFlagNewMask)) - } - } else if model.IsSyncStatusUpdate(act.SyncStatus) { - // globals.SugarLogger.Debug(utils.Format4Output(updateItems, false)) - if len(actStoreSkuList4Create) > 0 { - addedList, err2 := createSkuAct(ctx, nil, act, actStoreSkuList4Create) - updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, addedList, model.SyncFlagNewMask)...) - if err = err2; err != nil { - return err - } - } - if len(actStoreSkuList4Delete) > 0 { - deletedList, err2 := cancelSkuAct(ctx, nil, act, actStoreSkuList4Delete) - updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, deletedList, model.SyncFlagDeletedMask)...) - if err = err2; err != nil { - return err - } - } - if err == nil { - updateItems = append(updateItems, partner.Act2Update(ctx, act, model.SyncFlagModifiedMask)) - } - } - return err - }() - db := dao.GetDB() - _, err2 := dao.BatchUpdateActEntity(db, model.IsSyncStatusDelete(act.SyncStatus), updateItems) - if err == nil { - err = err2 - } - return err -} diff --git a/business/partner/purchase/mtwm/callback.go b/business/partner/purchase/mtwm/callback.go deleted file mode 100644 index 17087b0b3..000000000 --- a/business/partner/purchase/mtwm/callback.go +++ /dev/null @@ -1,38 +0,0 @@ -package mtwm - -import ( - "git.rosy.net.cn/baseapi/platformapi/mtwmapi" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/model" -) - -func OnCallbackMsg(msg *mtwmapi.CallbackMsg) (response *mtwmapi.CallbackResponse) { - if CurPurchaseHandler != nil { - if msg.Cmd == mtwmapi.MsgTypeStoreStatusChanged { - response = CurPurchaseHandler.onStoreStatusChanged(msg) - } else if msg.Cmd == mtwmapi.MsgTypePrivateNumberDowngrade { - response = CurPurchaseHandler.onNumberDowngrade(msg) - } else { - if orderID := GetOrderIDFromMsg(msg); orderID != "" { - jxutils.CallMsgHandler(func() { - switch msg.Cmd { - case mtwmapi.MsgTypeWaybillStatus: - response = CurPurchaseHandler.onWaybillMsg(msg) - default: - response = CurPurchaseHandler.onOrderMsg(msg) - } - }, jxutils.ComposeUniversalOrderID(orderID, model.VendorIDMTWM)) - } - /*if msg.Cmd == mtwmapi.MsgTypeOrderRefund || msg.Cmd == mtwmapi.MsgTypeOrderPartialRefund { - utils.CallFuncAsync(func() { - OnFinancialMsg(msg) - }) - } */ - } - } - return response -} - -func GetOrderIDFromMsg(msg *mtwmapi.CallbackMsg) string { - return msg.FormData.Get(mtwmapi.KeyOrderID) -} diff --git a/business/partner/purchase/mtwm/financial.go b/business/partner/purchase/mtwm/financial.go deleted file mode 100644 index af8a4c3eb..000000000 --- a/business/partner/purchase/mtwm/financial.go +++ /dev/null @@ -1,252 +0,0 @@ -package mtwm - -import ( - "net/url" - - "git.rosy.net.cn/baseapi/platformapi/mtwmapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" -) - -const ( - PublicWelfareDonation = 1 // 美团公益捐款金额现阶段是每单一分钱 -) - -// 存储美团退款订单结账信息 -func OnFinancialMsg(msg *mtwmapi.CallbackMsg) (err error) { - if msg.Cmd == mtwmapi.MsgTypeOrderPartialRefund { // 部分退款处理 - orderData := msg.FormData - if orderData.Get("notify_type") == mtwmapi.NotifyTypeSuccess { - err = partner.CurOrderManager.SaveAfsOrderFinancialInfo(CurPurchaseHandler.AfsOrderDetail2Financial(orderData)) - } - } - if msg.Cmd == mtwmapi.MsgTypeOrderRefund { // todo 全额退款处理 - orderData := msg.FormData - if orderData.Get("notify_type") == mtwmapi.NotifyTypeSuccess { - globals.SugarLogger.Debug(orderData.Get("order_id")) // 获得退款订单ID,去本地数据库拿?饿百消息推送只给了订单号,也没有通过订单号查询退款信息的接口 - afsOrderID := orderData.Get("order_id") - orderFinancial, err := partner.CurOrderManager.LoadOrderFinancial(afsOrderID, model.VendorIDMTWM) - if err == nil { - globals.SugarLogger.Debug(utils.Format4Output(orderFinancial, false)) - err = partner.CurOrderManager.SaveAfsOrderFinancialInfo(CurPurchaseHandler.OrderFinancialDetail2Refund(orderFinancial, orderData)) - } else { - globals.SugarLogger.Warnf("mtwm OnFinancialMsg, afsOrderID:%s is not found from partner.CurOrderManager.LoadOrderFinancial", afsOrderID) - } - } - } - return err -} - -func (p *PurchaseHandler) OrderFinancialDetail2Refund(orderFinancial *model.OrderFinancial, orderData url.Values) (afsOrder *model.AfsOrder) { - afsOrder = &model.AfsOrder{ - VendorID: model.VendorIDMTWM, - AfsOrderID: orderData.Get("refund_id"), - VendorOrderID: orderData.Get("order_id"), - AfsCreatedAt: utils.Timestamp2Time(utils.Str2Int64(orderData.Get("timestamp"))), - // BoxMoney: orderFinancial.BoxMoney, - // SkuBoxMoney: orderFinancial.SkuBoxMoney, // 美团的餐盒费已经拆到单条SKU里面去了,退款时直接计算用户支付sku金额就好了 - FreightUserMoney: orderFinancial.FreightMoney, - SkuUserMoney: orderFinancial.ActualPayMoney - orderFinancial.FreightMoney, - PmSubsidyMoney: orderFinancial.PmSubsidyMoney, - } - order, err := partner.CurOrderManager.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID) - globals.SugarLogger.Debug(utils.Format4Output(order, false)) - if err == nil { - afsOrder.JxStoreID = order.JxStoreID - afsOrder.VendorStoreID = order.VendorStoreID - afsOrder.StoreID = order.StoreID - } else { - globals.SugarLogger.Warnf("mtwm AfsOrderDetail2Financial, afsOrderID:%s is not found from partner.CurOrderManager.LoadOrder", afsOrder.VendorOrderID) - err = nil - } - for _, sku := range orderFinancial.Skus { - orderSkuFinancial := &model.OrderSkuFinancial{ - VendorID: sku.VendorID, - VendorOrderID: sku.VendorOrderID, - // OrderFinancialID: sku.VendorOrderID, - // ConfirmTime: afsOrder.AfsCreateAt, - VendorStoreID: afsOrder.VendorStoreID, - StoreID: afsOrder.StoreID, - JxStoreID: afsOrder.JxStoreID, - VendorSkuID: sku.VendorSkuID, - SkuID: sku.SkuID, - PromotionType: sku.PromotionType, - Name: sku.Name, - ShopPrice: sku.ShopPrice, - SalePrice: sku.SalePrice, - Count: sku.Count, - UserMoney: sku.UserMoney, - PmSubsidyMoney: sku.PmSubsidyMoney, - IsAfsOrder: 1, - } - afsOrder.Skus = append(afsOrder.Skus, orderSkuFinancial) - } - return afsOrder -} - -func (p *PurchaseHandler) AfsOrderDetail2Financial(orderData url.Values) (afsOrder *model.AfsOrder) { - afsOrder = &model.AfsOrder{ - VendorID: model.VendorIDMTWM, - AfsOrderID: orderData.Get("order_id"), - VendorOrderID: orderData.Get("order_id"), - AfsCreatedAt: utils.Timestamp2Time(utils.Str2Int64(orderData.Get("timestamp"))), - RefundMoney: jxutils.StandardPrice2Int(utils.Str2Float64(orderData.Get("money"))), - } - // if orderData.Get("timestamp") != "" { - // afsOrder.AfsCreateAt = utils.Timestamp2Time(utils.Str2Int64(orderData.Get("timestamp"))) - // } else { - // globals.SugarLogger.Warnf("ebai OrderFinancialDetail2Refund timestamp is not found in afsOrder:%s", afsOrder.AfsOrderID) - // afsOrder.AfsCreateAt = time.Now() - // } - order, err := partner.CurOrderManager.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID) - if err == nil { - afsOrder.JxStoreID = order.JxStoreID - } else { - globals.SugarLogger.Warnf("mtwm AfsOrderDetail2Financial, afsOrderID:%s is not found from partner.CurOrderManager.LoadOrder", afsOrder.VendorOrderID) - err = nil - } - food := orderData.Get("food") - var refundDetail []map[string]interface{} - utils.UnmarshalUseNumber([]byte(food), &refundDetail) - for _, xMap := range refundDetail { - orderSkuFinancial := &model.OrderSkuFinancial{ - VendorID: model.VendorIDMTWM, - AfsOrderID: afsOrder.AfsOrderID, - VendorOrderID: afsOrder.VendorOrderID, - // ConfirmTime: afsOrder.AfsCreateAt, - VendorSkuID: utils.Interface2String(xMap["app_food_code"]), - SkuID: int(utils.Str2Int64WithDefault(utils.Interface2String(xMap["sku_id"]), 0)), - Name: utils.Interface2String(xMap["food_name"]), - UserMoney: jxutils.StandardPrice2Int(utils.MustInterface2Float64(xMap["refund_price"]))*utils.MustInterface2Int64(xMap["count"]) + jxutils.StandardPrice2Int(utils.MustInterface2Float64(xMap["box_price"]))*int64(utils.MustInterface2Float64(xMap["box_num"])), - IsAfsOrder: 1, - } - afsOrder.Skus = append(afsOrder.Skus, orderSkuFinancial) - afsOrder.SkuUserMoney += orderSkuFinancial.UserMoney - // afsOrder.PmSubsidyMoney += orderSkuFinancial.PmSubsidyMoney // 美团只给了一个扣款金额,很尴尬、、 - } - afsOrder.PmSubsidyMoney += afsOrder.RefundMoney - afsOrder.SkuUserMoney - if len(refundDetail) <= 0 { - globals.SugarLogger.Warnf("mtwm AfsOrderDetail2Financial, orderID:%s have no refund_detail", afsOrder.VendorOrderID) - } - return afsOrder -} - -// 存储美团正向订单结账信息 -func (p *PurchaseHandler) OnOrderDetail(result map[string]interface{}, operation string) (err error) { - globals.SugarLogger.Debug(utils.Int64ToStr(utils.MustInterface2Int64(result["order_id"]))) - err = partner.CurOrderManager.SaveOrderFinancialInfo(p.OrderDetail2Financial(result), operation) - return err -} - -func (p *PurchaseHandler) OrderDetail2Financial(result map[string]interface{}) (orderFinancial *model.OrderFinancial) { - orderFinancial = &model.OrderFinancial{ - VendorID: model.VendorIDMTWM, - VendorOrderID: utils.Int64ToStr(utils.MustInterface2Int64(result["order_id"])), - } - // orderFinancial.DeliveryConfirmTime = utils.Str2TimeWithDefault(utils.Interface2String(result["order_completed_time"]), utils.DefaultTimeValue) - order, err := partner.CurOrderManager.LoadOrder(orderFinancial.VendorOrderID, orderFinancial.VendorID) - jxStoreID := 0 - if err == nil { - jxStoreID = order.JxStoreID - if order.Skus != nil { - for _, x := range order.Skus { - orderFinancial.ShopPriceMoney += x.ShopPrice * int64(x.Count) - } - } - } else { - globals.SugarLogger.Warnf("mtwm OrderDetail2Financial, orderID:%s is not found from partner.CurOrderManager.LoadOrder", orderFinancial.VendorOrderID) - err = nil - } - if result["package_bag_money"] != nil { - orderFinancial.BoxMoney = utils.MustInterface2Int64(result["package_bag_money"]) - } - detail := result["detail"] - if detail != nil { - var data []map[string]interface{} - utils.UnmarshalUseNumber([]byte(utils.Interface2String(detail)), &data) - for _, x := range data { - orderSkuFinancial := &model.OrderSkuFinancial{ - VendorID: orderFinancial.VendorID, - VendorOrderID: orderFinancial.VendorOrderID, - // OrderFinancialID: orderFinancial.VendorOrderID, - // ConfirmTime: utils.Str2TimeWithDefault(utils.Interface2String(result["ctime"]), utils.DefaultTimeValue), - VendorStoreID: result["app_poi_code"].(string), - StoreID: 0, - JxStoreID: jxStoreID, - VendorSkuID: utils.Interface2String(x["sku_id"]), - SkuID: int(utils.Str2Int64WithDefault(utils.Interface2String(x["sku_id"]), 0)), - Name: utils.Interface2String(x["food_name"]), - SalePrice: jxutils.StandardPrice2Int(utils.MustInterface2Float64(x["price"])), - Count: int(utils.MustInterface2Int64(x["quantity"])), - SkuBoxMoney: jxutils.StandardPrice2Int(utils.MustInterface2Float64(x["box_price"])) * jxutils.StandardPrice2Int(utils.MustInterface2Float64(x["box_num"])), - IsAfsOrder: 0, - } - orderFinancial.Skus = append(orderFinancial.Skus, orderSkuFinancial) - orderFinancial.SalePriceMoney += orderSkuFinancial.SalePrice * int64(orderSkuFinancial.Count) - orderFinancial.SkuBoxMoney += orderSkuFinancial.SkuBoxMoney - } - } else { - globals.SugarLogger.Warnf("mtwm OrderDetail2Financial, orderID:%s have no detail", orderFinancial.VendorOrderID) - } - extras := result["extras"] - if extras != nil { - var data []map[string]interface{} - utils.UnmarshalUseNumber([]byte(utils.Interface2String(extras)), &data) - for _, x := range data { - if x["rider_fee"] == nil { - activity := &model.OrderDiscountFinancial{ - VendorID: orderFinancial.VendorID, - VendorOrderID: orderFinancial.VendorOrderID, - // ActivityName: utils.Interface2String(x["remark"]), - // ActivityMoney: jxutils.StandardPrice2Int(utils.MustInterface2Float64(x["reduce_fee"])), - // VendorActivityID: utils.Int64ToStr(utils.MustInterface2Int64(x["act_detail_id"])), - } - if x["act_detail_id"] != nil { // 容错处理 - activity.VendorActivityID = utils.Int64ToStr(utils.MustInterface2Int64(x["act_detail_id"])) - orderFinancial.Discounts = append(orderFinancial.Discounts, activity) - } - // 通过活动Id去取,京西活动补贴 - // orderFinancial.JxSubsidyMoney += - } - } - } - poiReceiveDetail := result["poi_receive_detail"] - if poiReceiveDetail != nil { - var data map[string]interface{} - utils.UnmarshalUseNumber([]byte(utils.Interface2String(poiReceiveDetail)), &data) - orderFinancial.ReceivableFreight = utils.MustInterface2Int64(data["logisticsFee"]) - orderFinancial.FreightMoney = utils.MustInterface2Int64(data["logisticsFee"]) - orderFinancial.ActualPayMoney = utils.MustInterface2Int64(data["onlinePayment"]) - orderFinancial.PmMoney = utils.MustInterface2Int64(data["foodShareFeeChargeByPoi"]) - orderFinancial.ShopMoney = utils.MustInterface2Int64(data["wmPoiReceiveCent"]) - for _, x := range data["actOrderChargeByMt"].([]interface{}) { - orderFinancial.TotalDiscountMoney += utils.MustInterface2Int64(x.(map[string]interface{})["moneyCent"]) - orderFinancial.PmSubsidyMoney += utils.MustInterface2Int64(x.(map[string]interface{})["moneyCent"]) - } - for _, x := range data["actOrderChargeByPoi"].([]interface{}) { - orderFinancial.TotalDiscountMoney += utils.MustInterface2Int64(x.(map[string]interface{})["moneyCent"]) - } - } else { - globals.SugarLogger.Warnf("mtwm OrderDetail2Financial, orderID:%s have no poi_receive_detail", orderFinancial.VendorOrderID) - } - if utils.MustInterface2Int64(result["is_third_shipping"]) == SelfDeliveryCarrierNo { // is_third_shipping int 是否是第三方配送平台配送,0表否,1表是) - orderFinancial.SelfDeliveryDiscountMoney = orderFinancial.ReceivableFreight - orderFinancial.DistanceFreightMoney = 0 - // 通过本地数据库去取是否转美团/达达,并计算运费 - // wayBill, err := partner.CurOrderManager.LoadWaybill(orderFinancial.VendorOrderID, orderFinancial.VendorID) - // if err == nil { - // orderFinancial.JxFreightMoney = wayBill.DesiredFee - // } - } - // // 美团订单单独处理部分,美团正向订单接口推送时总结算金额没有计算公益捐款一分钱,是否在这里直接提前扣除? - // // 3/18之后的订单一直都不显示公益捐款金额,而且结算现在结算到了3/18之后的订单,没有的已经不计算了,先注释 - // // 2019-04-03 10.52 询问赵mf, 此计划是必须参加的,而且是长期的,每单固定扣除一分钱 - orderFinancial.DonationMoney = PublicWelfareDonation - // 不应该对第三方结账金额做更改,就算有异常,也要保留异常,知道问题出在哪里 - // orderFinancial.ShopMoney -= PublicWelfareDonation - globals.SugarLogger.Debug(orderFinancial.VendorOrderID) - return orderFinancial -} diff --git a/business/partner/purchase/mtwm/financial_test.go b/business/partner/purchase/mtwm/financial_test.go deleted file mode 100644 index 1cf96e2e8..000000000 --- a/business/partner/purchase/mtwm/financial_test.go +++ /dev/null @@ -1,54 +0,0 @@ -package mtwm - -import ( - "fmt" - "net/url" - "testing" - "time" - - "git.rosy.net.cn/baseapi/platformapi/mtwmapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/partner" -) - -func TestOnFinancialMsg(t *testing.T) { - msg := &mtwmapi.CallbackMsg{ - Cmd: "orderRefund", - FormData: url.Values{}, - } - msg.FormData.Set("timestamp", utils.Int64ToStr(time.Now().Unix())) - msg.FormData.Set("order_id", "33762863167364867") - msg.FormData.Set("notify_type", "agree") - msg.FormData.Set("money", "23.56") - food := []map[string]interface{}{ - map[string]interface{}{ - "app_food_code": "123", - "food_name": "商品1", - "sku_id": "123", - "refund_price": 3.14, - "count": 2, - "box_num": 1, - "box_price": 1, - }, - map[string]interface{}{ - "app_food_code": "124", - "food_name": "商品2", - "sku_id": "124", - "refund_price": 3.15, - "count": 2, - "box_num": 1, - "box_price": 1, - }, - } - msg.FormData.Set("food", string(utils.MustMarshal(food))) - res := CurPurchaseHandler.onAfsOrderMsg(msg) - fmt.Println(res) -} - -func TestOnOrderDetail(t *testing.T) { - result := map[string]interface{}{ - "app_order_code": "", "app_poi_code": "2828472", "avg_send_time": 2410, "backup_recipient_phone": "[\"13164714130_7645\"]", "caution": " 【如遇缺货】: 缺货时电话与我沟通 收餐人隐私号 13049813276_5307,手机号 139****5027", "city_id": 440300, "ctime": 1555036346, "day_seq": 1, "delivery_time": 0, "detail": "[{\"app_food_code\":\"27262\",\"box_num\":0,\"box_price\":0,\"cart_id\":0,\"food_discount\":1,\"food_name\":\"红管鱿鱼约250g/份\",\"food_property\":\"\",\"price\":23.54,\"quantity\":1,\"sku_id\":\"27262\",\"spec\":\"250g\",\"unit\":\"份\"},{\"app_food_code\":\"24987\",\"box_num\":0,\"box_price\":0,\"cart_id\":0,\"food_discount\":1,\"food_name\":\"带皮猪梅花肉约250g/份\",\"food_property\":\"\",\"price\":15.84,\"quantity\":1,\"sku_id\":\"24987\",\"spec\":\"250g\",\"unit\":\"份\"},{\"app_food_code\":\"27179\",\"box_num\":0,\"box_price\":0,\"cart_id\":0,\"food_discount\":1,\"food_name\":\"[畅销]龙骨约250g/份\",\"food_property\":\"\",\"price\":18.59,\"quantity\":1,\"sku_id\":\"27179\",\"spec\":\"250g\",\"unit\":\"份\"}]", "dinners_number": 0, "expect_deliver_time": 0, "extras": "[{\"act_detail_id\":664795195,\"mt_charge\":0,\"poi_charge\":5,\"reduce_fee\":5,\"remark\":\"满46.0元减5.0元\",\"type\":2},{\"act_detail_id\":665051798,\"mt_charge\":0,\"poi_charge\":4,\"reduce_fee\":4,\"remark\":\"减配送费4.0元\",\"type\":25},{\"act_detail_id\":274839715,\"mt_charge\":0.5,\"poi_charge\":0,\"reduce_fee\":0.5,\"remark\":\"用户使用了支付红包减0.5元\",\"type\":9},{\"mt_charge\":0,\"poi_charge\":0,\"reduce_fee\":0,\"remark\":\"送30元商家代金券\",\"type\":100},{}]", "has_invoiced": 0, "invoice_title": "", "is_favorites": false, "is_poi_first_order": true, "is_pre": 0, "is_third_shipping": 0, "latitude": 22.530194, "logistics_code": "1001", "longitude": 114.08372, "order_id": 28284722536001020, "order_send_time": 1555036356, "original_price": 63.97, "package_bag_money": 0, "pay_type": 2, "pick_type": 0, "poi_receive_detail": "{\"actOrderChargeByMt\":[{\"comment\":\"活动款\",\"feeTypeDesc\":\"活动款\",\"feeTypeId\":10019,\"moneyCent\":50}],\"actOrderChargeByPoi\":[{\"comment\":\"满46.0元减5.0元\",\"feeTypeDesc\":\"活动款\",\"feeTypeId\":10019,\"moneyCent\":500},{\"comment\":\"减配送费4.0元\",\"feeTypeDesc\":\"活动款\",\"feeTypeId\":10019,\"moneyCent\":400}],\"foodShareFeeChargeByPoi\":490,\"logisticsFee\":600,\"onlinePayment\":5447,\"wmPoiReceiveCent\":4406}", "recipient_address": "汇港名苑 (南2区1005)@#广东省深圳市福田区滨河大道滨河大道3119号汇港名苑", "recipient_name": "颜(女士)", "recipient_phone": "13049813276_5307", "remark": "", "result": "ok", "shipper_phone": "", "shipping_fee": 6, "shipping_type": 0, "source_id": 3, "status": 2, "taxpayer_id": "", "total": 54.47, "utime": 1555036346, "wm_order_id_view": 28284722536001020, "wm_poi_address": "深圳市福田区南园街道南华社区滨河路2037号下小庙南区70栋101号滨河街市场", "wm_poi_id": 2828472, "wm_poi_name": "京西菜市(华强南店)", "wm_poi_phone": "13724313878", - } - err := new(PurchaseHandler).OnOrderDetail(result, partner.CreatedPeration) - fmt.Println(err) -} diff --git a/business/partner/purchase/mtwm/mtwm.go b/business/partner/purchase/mtwm/mtwm.go deleted file mode 100644 index 09bce7a52..000000000 --- a/business/partner/purchase/mtwm/mtwm.go +++ /dev/null @@ -1,225 +0,0 @@ -package mtwm - -import ( - "fmt" - "strings" - "sync" - - "git.rosy.net.cn/baseapi/platformapi/mtwmapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/business/partner/putils" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -var ( - CurPurchaseHandler *PurchaseHandler -) - -type PurchaseHandler struct { - partner.BasePurchasePlatform - putils.DefSingleStorePlatform - - storeIDs []string - locker sync.RWMutex -} - -func init() { - if api.MtwmAPI != nil { - CurPurchaseHandler = New() - partner.RegisterPurchasePlatform(CurPurchaseHandler) - } -} - -func New() (obj *PurchaseHandler) { - obj = new(PurchaseHandler) - obj.ISingleStoreStoreSkuHandler = obj - return obj -} - -func (c *PurchaseHandler) GetVendorID() int { - return model.VendorIDMTWM -} - -func (p *PurchaseHandler) GetVendorCategories(ctx *jxcontext.Context) (vendorCats []*model.SkuVendorCategory, err error) { - cats, err := api.MtwmAPI.RetailGetSpTagIds() - if err != nil { - return nil, err - } - vendorCatMapList := make([]map[string]*model.SkuVendorCategory, 3) - manID := 10000 - for i := 0; i < 3; i++ { - vendorCatMapList[i] = make(map[string]*model.SkuVendorCategory) - for _, v := range cats { - if v.Level == 3 { - namePathList := strings.Split(strings.Trim(v.NamePath, ","), ",") - if len(namePathList) != 3 { - panic(fmt.Sprintf("%s没有三级结构", v.NamePath)) - } - name := namePathList[i] - if _, ok := vendorCatMapList[i][name]; !ok { - cat := &model.SkuVendorCategory{ - VendorID: model.VendorIDMTWM, - Name: name, //utils.Interface2String(v["name"]), - Level: i + 1, //int(utils.MustInterface2Int64(v["level"])), - } - vendorCats = append(vendorCats, cat) - vendorCatMapList[i][name] = cat - if i == 2 { - cat.IsLeaf = 1 - cat.VendorCategoryID = utils.Int64ToStr(v.ID) - } else { - cat.VendorCategoryID = utils.Int2Str(manID) // 非叶子结点编码没有实际使用 - manID++ - } - if i > 0 { - cat.ParentID = vendorCatMapList[i-1][namePathList[i-1]].VendorCategoryID - } - } - } - } - } - return vendorCats, nil -} - -func rangeMtwm2JX(areaStr string) string { - var area []interface{} - if err := utils.UnmarshalUseNumber([]byte(areaStr), &area); err == nil { - if len(area) > 0 { - coordList := make([]string, len(area)) - for k, v := range area { - vv := v.(map[string]interface{}) - coordList[k] = fmt.Sprintf("%.6f,%.6f", jxutils.IntCoordinate2Standard(int(utils.ForceInterface2Int64(vv["x"]))), jxutils.IntCoordinate2Standard(int(utils.ForceInterface2Int64(vv["y"])))) - } - return strings.Join(coordList, ";") - } - } - return "" -} - -func rangeJX2Mtwm(coords string) string { - pairs := strings.Split(strings.Trim(coords, ";"), ";") - if len(pairs) > 0 { - coordList := make([]map[string]interface{}, len(pairs)) - for k, v := range pairs { - pair := strings.Split(v, ",") - coordList[k] = map[string]interface{}{ - "x": jxutils.StandardCoordinate2Int(utils.Str2Float64(pair[0])), - "y": jxutils.StandardCoordinate2Int(utils.Str2Float64(pair[1])), - } - } - return string(utils.MustMarshal(coordList)) - } - return "" -} - -func openTimeMtwm2JX(vendorOpenTime string) (opTimeList []int16) { - timePairs := strings.Split(vendorOpenTime, ",") - for _, v := range timePairs { - times := strings.Split(v, "-") - if len(times) >= 2 { - opTimeList = append(opTimeList, jxutils.StrTime2JxOperationTime(times[0]+":00", 700), jxutils.StrTime2JxOperationTime(times[1]+":00", 2000)) - } - } - return opTimeList -} - -func openTimeJX2Mtwm(opTimeList []int16) string { - timesLen := len(opTimeList) / 2 * 2 - var strPairs []string - for i := 0; i < timesLen; i += 2 { - if opTimeList[i] != 0 { - strPairs = append(strPairs, jxutils.JxOperationTime2StrTime(opTimeList[i])+"-"+jxutils.JxOperationTime2StrTime(opTimeList[i+1])) - } else { - break - } - } - return strings.Join(strPairs, ",") -} - -func bizStatusMtwm2JX(openLevel, online int) int { - if online != mtwmapi.PoiStatusOnline { - return model.StoreStatusDisabled - } else { - if openLevel == mtwmapi.PoiOpenLevelHaveRest { - return model.StoreStatusClosed - } - } - return model.StoreStatusOpened -} - -func bizStatusJX2Mtwm(status int) (openLevel, online int) { - if status == model.StoreStatusDisabled { - return mtwmapi.PoiOpenLevelHaveRest, mtwmapi.PoiStatusOnline //mtwmapi.PoiStatusOffline - } else if status == model.StoreStatusHaveRest || status == model.StoreStatusClosed { - return mtwmapi.PoiOpenLevelHaveRest, mtwmapi.PoiStatusOnline - } - return mtwmapi.PoiOpenLevelNormal, mtwmapi.PoiStatusOnline -} - -func skuStatusJX2Mtwm(status int) int { - if status == model.SkuStatusNormal { - return mtwmapi.SellStatusOnline - } - return mtwmapi.SellStatusOffline -} - -func (p *PurchaseHandler) UploadImg(ctx *jxcontext.Context, vendorOrgCode, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) { - globals.SugarLogger.Debugf("mtwm UploadImg imgURL:%s, imgName:%s", imgURL, imgName) - poiCode4UploadImg := p.getUploadImgPoiCode() - if poiCode4UploadImg == "" { - return "", fmt.Errorf("找不到一个美团门店来上传图片") - } - if globals.EnableMtwmStoreWrite { - if imgType > model.ImgTypeLocal { - if imgData != nil { - imgHint, err = api.MtwmAPI.ImageUpload(poiCode4UploadImg, imgName, imgData) - } else { - imgHint, err = api.MtwmAPI.ImageUploadByURL(poiCode4UploadImg, imgName, imgURL) - } - } - } else { - imgHint = utils.GetUpperUUID() - } - return imgHint, err -} - -func getStoreIDFromList(storeIDs []string) (poiCode string) { - if len(storeIDs) > 0 { - poiCode = storeIDs[0] - } - return poiCode -} - -func (p *PurchaseHandler) getUploadImgPoiCode() (poiCode string) { - var storeIDs []string - p.locker.RLock() - storeIDs = p.storeIDs - p.locker.RUnlock() - if len(storeIDs) > 0 { - return getStoreIDFromList(storeIDs) - } - - p.locker.Lock() - storeIDs = p.storeIDs - if len(storeIDs) > 0 { - p.locker.Unlock() - return getStoreIDFromList(storeIDs) - } - - defer p.locker.Unlock() - storeIDs, err := api.MtwmAPI.PoiGetIDs() - if err == nil { - if len(storeIDs) > 0 { - p.storeIDs = storeIDs - poiCode = getStoreIDFromList(storeIDs) - } else { - // p.storeIDs = []string{""} - } - } - return poiCode -} diff --git a/business/partner/purchase/mtwm/mtwm_test.go b/business/partner/purchase/mtwm/mtwm_test.go deleted file mode 100644 index 804e9ed1b..000000000 --- a/business/partner/purchase/mtwm/mtwm_test.go +++ /dev/null @@ -1,28 +0,0 @@ -package mtwm - -import ( - "testing" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - - "git.rosy.net.cn/baseapi/utils" - _ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" - "git.rosy.net.cn/jx-callback/globals/testinit" -) - -const ( - testShopVendorID = "2523687" - testShopID = 2 -) - -func init() { - testinit.Init() -} - -func TestGetVendorCategories(t *testing.T) { - result, err := new(PurchaseHandler).GetVendorCategories(jxcontext.AdminCtx) - if err != nil { - t.Fatal(err) - } - t.Log(utils.Format4Output(result, false)) -} diff --git a/business/partner/purchase/mtwm/order.go b/business/partner/purchase/mtwm/order.go deleted file mode 100644 index 14cdc26b4..000000000 --- a/business/partner/purchase/mtwm/order.go +++ /dev/null @@ -1,797 +0,0 @@ -package mtwm - -import ( - "errors" - "fmt" - "math" - "net/url" - "regexp" - "strings" - "time" - - "git.rosy.net.cn/baseapi/platformapi/mtwmapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -const ( - FakeMsgType = "fakeMsgType" - - fakeFinishedPickup = "fake_finished_pickup" - fakeUserApplyCancel = "fake_user_apply_cancel" - fakeMerchantAgreeApplyCancel = "fake_merchant_agree_apply_cancel" - fakeRefuseUserApplyCancel = "fake_refuse_user_apply_cancel" - fakeUserUndoApplyCancel = "fake_user_undo_apply_cancel" - fakeOrderAdjustFinished = "fake_order_adjust_finished" - - keyVendorOrgCode = "vendorOrgCode" -) - -const ( - SelfDeliveryCarrierNo = 1 // 美团配送方式:0-美团专送,1-商家自送 -) - -const ( -// pickupOrderDelay = 260 * time.Second -// pickupOrderDelay = 1 * time.Second - -// callDeliveryDelay = 10 * time.Minute -// callDeliveryDelayGap = 30 -) - -var ( - specPat = regexp.MustCompile(`(\d+)(.+)`) -) - -var ( - VendorStatus2StatusMap = map[string]int{ - mtwmapi.OrderStatusUserCommitted: model.OrderStatusUnknown, - mtwmapi.OrderStatusNew: model.OrderStatusNew, - // mtwmapi.OrderStatusReceived: model.OrderStatusAccepted, - // mtwmapi.OrderStatusAccepted: model.OrderStatusFinishedPickup, - mtwmapi.OrderStatusAccepted: model.OrderStatusAccepted, - - mtwmapi.OrderStatusDelivering: model.OrderStatusDelivering, - mtwmapi.OrderStatusDelivered: model.OrderStatusUnknown, // 以mtwmapi.OrderStatusFinished为结束状态,这个当成一个中间状态(且很少看到这个状态) - mtwmapi.OrderStatusFinished: model.OrderStatusFinished, - mtwmapi.OrderStatusCanceled: model.OrderStatusCanceled, - - fakeFinishedPickup: model.OrderStatusFinishedPickup, - fakeOrderAdjustFinished: model.OrderStatusAdjust, - fakeRefuseUserApplyCancel: model.OrderStatusVendorRejectCancel, - fakeUserApplyCancel: model.OrderStatusApplyCancel, - fakeUserUndoApplyCancel: model.OrderStatusUndoApplyCancel, - fakeMerchantAgreeApplyCancel: model.OrderStatusCanceled, - } - - skuActTypeMap = map[int]int{ - mtwmapi.ExtrasPromotionTypeTeJiaCai: 1, - mtwmapi.ExtrasPromotionTypeZheKouCai: 1, - mtwmapi.ExtrasPromotionTypeSecondHalfPrice: 1, - } -) - -func (p *PurchaseHandler) getStatusFromVendorStatus(vendorStatus string) int { - if status, ok := VendorStatus2StatusMap[vendorStatus]; ok { - return status - } - return model.OrderStatusUnknown -} - -func (p *PurchaseHandler) getOrder(vendorOrgCode, vendorOrderID string) (order *model.GoodsOrder, orderMap map[string]interface{}, err error) { - result, err := api.MtwmAPI.OrderGetOrderDetail(utils.Str2Int64(vendorOrderID), true) - if err == nil { - result[keyVendorOrgCode] = vendorOrgCode - order = p.Map2Order(result) - } - return order, result, err -} - -func (p *PurchaseHandler) GetOrder(vendorOrgCode, vendorOrderID string) (order *model.GoodsOrder, err error) { - order, _, err = p.getOrder(vendorOrgCode, vendorOrderID) - return order, err -} - -func (p *PurchaseHandler) GetOrderStatus(vendorOrgCode, vendorOrderID string) (status int, err error) { - status, err = api.MtwmAPI.OrderViewStatus(utils.Str2Int64(vendorOrderID)) - if err == nil { - status = p.getStatusFromVendorStatus(utils.Int2Str(status)) - } - return status, err -} - -func (p *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) { - result := orderData - vendorOrderID := utils.Int64ToStr(utils.MustInterface2Int64(result["order_id"])) - // 因为美团外卖不能自动设置商家门店号,且只能通过商家门店号来访问门店, - // 为了在后台设置简单一致,把app_poi_code直接当成平台门店号使用(即在后台设置时,平台门店号与商家门店号一样) - // 订单中wm_poi_id实际来平台门店号,app_poi_code为商家门店号,这样一来,这两个就相同了 - order = &model.GoodsOrder{ - VendorOrderID: vendorOrderID, - // VendorOrderID2: utils.Int64ToStr(utils.MustInterface2Int64(result["wm_order_id_view"])), - VendorID: model.VendorIDMTWM, - VendorStoreID: result["app_poi_code"].(string), - StoreID: 0, - // VendorStoreID: utils.Int64ToStr(utils.MustInterface2Int64(result["wm_poi_id"])), - // StoreID: int(utils.Str2Int64WithDefault(utils.Interface2String(result["app_poi_code"]), 0)), - StoreName: result["wm_poi_name"].(string), - ConsigneeName: result["recipient_name"].(string), - ConsigneeMobile: jxutils.FormalizeMobile(result["recipient_phone"].(string)), - ConsigneeAddress: result["recipient_address"].(string), - CoordinateType: model.CoordinateTypeMars, - BuyerComment: utils.TrimBlankChar(utils.Interface2String(result["caution"])), - ExpectedDeliveredTime: getTimeFromTimestamp(utils.Interface2Int64WithDefault(result["delivery_time"], 0)), - PickDeadline: utils.DefaultTimeValue, - VendorStatus: utils.Int64ToStr(utils.MustInterface2Int64(result["status"])), - OrderSeq: int(utils.MustInterface2Int64(result["day_seq"])), - StatusTime: getTimeFromTimestamp(utils.MustInterface2Int64(result["ctime"])), - OrderCreatedAt: getTimeFromTimestamp(utils.MustInterface2Int64(result["ctime"])), - // OrderFinishedAt: getTimeFromTimestamp(utils.MustInterface2Int64(result["order_completed_time"])), - OriginalData: string(utils.MustMarshal(result)), - ActualPayPrice: jxutils.StandardPrice2Int(utils.MustInterface2Float64(result["total"])), - BaseFreightMoney: jxutils.StandardPrice2Int(utils.Interface2Float64WithDefault(result["shipping_fee"], 0)), - - InvoiceTitle: utils.Interface2String(result["invoice_title"]), - InvoiceTaxerID: utils.Interface2String(result["taxpayer_id"]), - InvoiceEmail: jxutils.GetOneEmailFromStr(utils.Interface2String(result["caution"])), - - VendorOrgCode: utils.Interface2String(result[keyVendorOrgCode]), - } - if result["order_completed_time"] != nil { - order.OrderFinishedAt = getTimeFromTimestamp(utils.MustInterface2Int64(result["order_completed_time"])) - } else { - order.OrderFinishedAt = utils.DefaultTimeValue - } - pickType := int(utils.Interface2Int64WithDefault(result["pick_type"], 0)) - if pickType == mtwmapi.OrderPickTypeSelf { - order.DeliveryType = model.OrderDeliveryTypeSelfTake - } else { - logisticsCode := utils.Interface2String(result["logistics_code"]) - if logisticsCode == mtwmapi.PeiSongTypeSelf { - order.DeliveryType = model.OrderDeliveryTypeStoreSelf - } else { - order.DeliveryType = model.OrderDeliveryTypePlatform - } - } - openUID := utils.Interface2Int64WithDefault(result["openUid"], 0) - if openUID > 0 { - order.VendorUserID = utils.Int64ToStr(openUID) - } - // 不设置最晚拣货时间,以缺省值为准 - // if utils.IsTimeZero(order.PickDeadline) && !utils.IsTimeZero(order.StatusTime) { - // order.PickDeadline = order.StatusTime.Add(pickupOrderDelay) // 美团外卖要求在5分钟内拣货,不然订单会被取消 - // } - order.Status = p.getStatusFromVendorStatus(order.VendorStatus) - if utils.IsTimeZero(order.ExpectedDeliveredTime) { - order.BusinessType = model.BusinessTypeImmediate - } else { - order.BusinessType = model.BusinessTypeDingshida - } - - originalLng := utils.MustInterface2Float64(result["longitude"]) - originalLat := utils.MustInterface2Float64(result["latitude"]) - order.ConsigneeLng = jxutils.StandardCoordinate2Int(originalLng) - order.ConsigneeLat = jxutils.StandardCoordinate2Int(originalLat) - - var detail []map[string]interface{} - if err := utils.UnmarshalUseNumber([]byte(result["detail"].(string)), &detail); err != nil { - panic(fmt.Sprintf("mtwm Map2Order vendorID:%s failed with error:%v", vendorOrderID, err)) - } - - // 添加需要赠送的东西 - if result["extras"] != nil { - var extraList []*mtwmapi.OrderExtraInfo - if err := utils.UnmarshalUseNumber([]byte(result["extras"].(string)), &extraList); err != nil { - panic(fmt.Sprintf("mtwm Map2Order vendorID:%s failed with error:%v", vendorOrderID, err)) - } - for _, extra := range extraList { - order.DiscountMoney += jxutils.StandardPrice2Int(extra.ReduceFee) - if extra.Type == mtwmapi.ExtrasPromotionTypeTaoCanZeng || extra.Type == mtwmapi.ExtrasPromotionTypeManZeng { - sku := &model.OrderSku{ - VendorOrderID: order.VendorOrderID, - VendorID: model.VendorIDMTWM, - Count: 1, - SkuID: 0, - VendorSkuID: "", - SkuName: extra.Remark, - Weight: 0, - SalePrice: 0, - StoreSubName: utils.Int2Str(extra.Type), - } - order.Skus = append(order.Skus, sku) - } - } - } - - if poiReceiveDetailStr := utils.Interface2String(result["poi_receive_detail"]); poiReceiveDetailStr != "" { - var poiReceiveDetail *mtwmapi.PoiReceiveDetailInfo - utils.UnmarshalUseNumber([]byte(poiReceiveDetailStr), &poiReceiveDetail) - if poiReceiveDetail != nil { - order.TotalShopMoney = poiReceiveDetail.WmPoiReceiveCent - for _, v := range poiReceiveDetail.ActOrderChargeByMt { - order.PmSubsidyMoney += v.MoneyCent - } - } - } - - var skuBenefitDetailMap map[string]*mtwmapi.SkuBenefitDetailInfo - if skuBenefitDetai := utils.Interface2String(result["sku_benefit_detail"]); skuBenefitDetai != "" { - skuBenefitDetailMap = make(map[string]*mtwmapi.SkuBenefitDetailInfo) - var skuBenefitDetailList []*mtwmapi.SkuBenefitDetailInfo - utils.UnmarshalUseNumber([]byte(skuBenefitDetai), &skuBenefitDetailList) - for _, v := range skuBenefitDetailList { - skuBenefitDetailMap[v.SkuID] = v - } - } - ignoreSkuMap := make(map[int]int) - // detail := result["detail"].([]interface{}) - multiSkuMap := make(map[int]int) - for _, product := range detail { - // product := product2.(map[string]interface{}) - skuName := product["food_name"].(string) - skuID := utils.Interface2String(product["sku_id"]) - sku := &model.OrderSku{ - VendorOrderID: order.VendorOrderID, - VendorID: model.VendorIDMTWM, - Count: int(utils.MustInterface2Float64(product["quantity"])), - SkuID: int(utils.Str2Int64WithDefault(skuID, 0)), - VendorSkuID: skuID, - SkuName: skuName, - Weight: getSkuWeight(product), - VendorPrice: jxutils.StandardPrice2Int(utils.MustInterface2Float64(product["price"])), - SalePrice: jxutils.StandardPrice2Int(utils.MustInterface2Float64(product["price"])), - } - if sku.Weight == 0 { - sku.Weight = 222 // 如果名字里找不到缺省给半斤左右的一个特别值 - } - if skuBenefitDetailMap != nil && skuBenefitDetailMap[sku.VendorSkuID] != nil && ignoreSkuMap[sku.SkuID] == 0 /* && sku.Count == 1 */ { - for _, v := range skuBenefitDetailMap[sku.VendorSkuID].WmAppOrderActDetails { - if /*skuActTypeMap[v.Type] == 1 && */ strings.Index(v.Remark, skuName) >= 0 && sku.Count == v.Count { - if sku.SalePrice-jxutils.StandardPrice2Int(v.MtCharge+v.PoiCharge) < 0 { - continue - } else { - ignoreSkuMap[sku.SkuID] = 1 - sku.SalePrice -= jxutils.StandardPrice2Int(v.MtCharge + v.PoiCharge) - } - sku.StoreSubName = utils.Int2Str(v.Type) - } - } - } - if sku.SalePrice < 0 { - sku.SalePrice = jxutils.StandardPrice2Int(utils.MustInterface2Float64(product["price"])) - } - // if product["isGift"].(bool) { - // sku.SkuType = 1 - // } - order.Skus = append(order.Skus, sku) - multiSkuMap[sku.SkuID]++ - } - for _, v := range order.Skus { - if multiSkuMap[v.SkuID] > 1 && v.SalePrice == v.VendorPrice { - v.IsVendorAct = model.YES - } - } - - jxutils.RefreshOrderSkuRelated(order) - return order -} - -func getRefundSkuDetailList(msg *mtwmapi.CallbackMsg) (skuList []*mtwmapi.RefundSkuDetail, err error) { - if false { - skuList = api.MtwmAPI.GetRefundSkuDetailFromMsg(msg) - } else { - refundOrderDetailList, err2 := api.MtwmAPI.GetOrderRefundDetail(utils.Str2Int64(GetOrderIDFromMsg(msg)), mtwmapi.RefundTypePart) - if err = err2; err == nil { - for _, v := range refundOrderDetailList { - skuList = append(skuList, v.WmAppRetailForOrderPartRefundList...) - } - } - } - globals.SugarLogger.Debugf("getRefundSkuDetailList orderID:%s skuList:%s", GetOrderIDFromMsg(msg), utils.Format4Output(skuList, true)) - return skuList, err -} - -func getSkuWeight(product map[string]interface{}) (weight int) { - if weight = int(utils.Interface2Int64WithDefault(product["weight"], 0)); weight == 0 { - searchResult := specPat.FindStringSubmatch(product["spec"].(string)) - if len(searchResult) == 3 { - weight = jxutils.FormatSkuWeight(float32(utils.Str2Float64WithDefault(searchResult[1], 0)), utils.TrimBlankChar(searchResult[2])) - } - if weight == 0 { - _, _, _, specUnit, _, specQuality := jxutils.SplitSkuName(product["food_name"].(string)) - weight = jxutils.FormatSkuWeight(specQuality, specUnit) - } - } - return weight -} - -func (c *PurchaseHandler) onOrderMsg(msg *mtwmapi.CallbackMsg) (response *mtwmapi.CallbackResponse) { - var err error - if c.isAfsMsg(msg) { - response = c.OnAfsOrderMsg(msg) - } else { - status := c.callbackMsg2Status(msg) - if partner.CurOrderManager.GetStatusDuplicatedCount(status) > 0 { - return nil - } - if msg.Cmd == mtwmapi.MsgTypeNewOrder { - order, orderMap, err2 := c.getOrder(msg.AppID, GetOrderIDFromMsg(msg)) - if err = err2; err == nil { - err = partner.CurOrderManager.OnOrderNew(order, c.callbackMsg2Status(msg)) - if err == nil { - utils.CallFuncAsync(func() { - if msg.Cmd == mtwmapi.MsgTypeNewOrder { - c.OnOrderDetail(orderMap, partner.CreatedPeration) - } else { - c.OnOrderDetail(orderMap, partner.UpdatedPeration) - } - }) - } - } - } else { - if status != nil { - if status.Status == model.OrderStatusAdjust { - var order *model.GoodsOrder - if order, err = c.GetOrder(msg.AppID, GetOrderIDFromMsg(msg)); err == nil { - skuList, err2 := getRefundSkuDetailList(msg) - if err = err2; err == nil { - var removedSkuList []*model.OrderSku - for _, mtwmSku := range skuList { - order.ActualPayPrice -= jxutils.StandardPrice2Int(mtwmSku.RefundPrice) * int64(mtwmSku.Count) - removedSkuList = append(removedSkuList, &model.OrderSku{ - SkuID: int(utils.Str2Int64WithDefault(mtwmSku.SkuID, 0)), - Count: mtwmSku.Count, - }) - } - order = jxutils.RemoveSkuFromOrder(order, removedSkuList) - jxutils.RefreshOrderSkuRelated(order) - err = partner.CurOrderManager.OnOrderAdjust(order, status) - } - } - } else { - if status.Status == model.OrderStatusDelivering { - // 美团订单即使时在配送状态时,如果之前没有调用过拣货完成,也会对门店指标生成影响,这里强制再调用拣货完成,且忽略错误 - utils.CallFuncAsync(func() { - if globals.EnableMtwmStoreWrite { - err = api.MtwmAPI.PreparationMealComplete(utils.Str2Int64(status.VendorOrderID)) - } - }) - } - err = partner.CurOrderManager.OnOrderStatusChanged(msg.AppID, status) - if err == nil && msg.Cmd == mtwmapi.MsgTypeOrderFinished { - utils.CallFuncAsync(func() { - orderMap, err := api.MtwmAPI.OrderGetOrderDetail(utils.Str2Int64(GetOrderIDFromMsg(msg)), true) - if err == nil && utils.MustInterface2Int64(orderMap["is_third_shipping"]) == SelfDeliveryCarrierNo { - c.OnOrderDetail(orderMap, partner.UpdatedPeration) - } - }) - } - } - } - } - } - return mtwmapi.Err2CallbackResponse(err, "") -} - -func (c *PurchaseHandler) callbackMsg2Status(msg *mtwmapi.CallbackMsg) (orderStatus *model.OrderStatus) { - orderID := GetOrderIDFromMsg(msg) - vendorStatus := msg.Cmd - remark := "" - statusTime := utils.Str2Int64(msg.FormData.Get("timestamp")) - switch msg.Cmd { - case mtwmapi.MsgTypeUserUrgeOrder, mtwmapi.MsgTypeOrderModified, mtwmapi.MsgTypeOrderFinancial: - vendorStatus = msg.Cmd - case mtwmapi.MsgTypeOrderCanceled: - vendorStatus = mtwmapi.OrderStatusCanceled - remark = msg.FormData.Get("reason") - case FakeMsgType, mtwmapi.MsgTypeNewOrder, mtwmapi.MsgTypeOrderAccepted, mtwmapi.MsgTypeOrderFinished: - vendorStatus = msg.FormData.Get("status") - statusTime = utils.Str2Int64(msg.FormData.Get("utime")) - case mtwmapi.MsgTypeOrderRefund, mtwmapi.MsgTypeOrderPartialRefund: - notifyType := msg.FormData.Get("notify_type") - vendorStatus = msg.Cmd + "-" + notifyType - if true { // 已经提前判断了,到这里的都是售中 - remark = msg.FormData.Get("reason") - if msg.Cmd == mtwmapi.MsgTypeOrderPartialRefund { - if notifyType == mtwmapi.NotifyTypePartyApply { - if globals.EnableMtwmStoreWrite { - // goods, err := dao.GetSimpleOrder(dao.GetDB(), orderID) - // if err == nil { - // if goods.Status < model.OrderStatusDelivering { - api.MtwmAPI.OrderRefundAgree(utils.Str2Int64(orderID), "自动确认退款") - // } else { - // api.MtwmAPI.OrderRefundReject(utils.Str2Int64(orderID), "商品配送中,请联系门店。") // todo 京东与饿百都没有售前用户提出订单调整的,自动拒绝调整单 - // } - // } - } - } else if notifyType == mtwmapi.NotifyTypeSuccess { - vendorStatus = fakeOrderAdjustFinished - } - } else if msg.Cmd == mtwmapi.MsgTypeOrderRefund { - if notifyType == mtwmapi.NotifyTypeApply { - vendorStatus = fakeUserApplyCancel - } else if notifyType == mtwmapi.NotifyTypeCancelRefund || notifyType == mtwmapi.NotifyTypeCancelRefundComplaint { - vendorStatus = fakeUserUndoApplyCancel - } else if notifyType == mtwmapi.NotifyTypeReject { - vendorStatus = fakeRefuseUserApplyCancel - } else if notifyType == mtwmapi.NotifyTypeSuccess { - vendorStatus = fakeMerchantAgreeApplyCancel // todo 可能导致订单取消消息重复 - } - } - } - default: - globals.SugarLogger.Errorf("mtwm unkonw msg:%s", utils.Format4Output(msg, false)) - } - if vendorStatus != "" { - orderStatus = &model.OrderStatus{ - VendorOrderID: orderID, - VendorID: model.VendorIDMTWM, - OrderType: model.OrderTypeOrder, - RefVendorOrderID: orderID, - RefVendorID: model.VendorIDMTWM, - VendorStatus: vendorStatus, - Status: c.getStatusFromVendorStatus(vendorStatus), - StatusTime: getTimeFromTimestamp(statusTime), - Remark: remark, - } - } - return orderStatus -} - -func (c *PurchaseHandler) postFakeMsg(vendorOrderID, cmd, vendorStatus string) { - msg := &mtwmapi.CallbackMsg{ - Cmd: cmd, - FormData: make(url.Values), - } - timeStr := utils.Int64ToStr(time.Now().Unix()) - msg.FormData.Set(mtwmapi.KeyOrderID, vendorOrderID) - msg.FormData.Set("status", vendorStatus) - msg.FormData.Set("timestamp", timeStr) - msg.FormData.Set("utime", timeStr) - utils.CallFuncAsync(func() { - c.onOrderMsg(msg) - }) -} - -func (c *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) { - globals.SugarLogger.Debugf("mtwm AcceptOrRefuseOrder orderID:%s, isAcceptIt:%t", order.VendorOrderID, isAcceptIt) - if isAcceptIt { - if globals.EnableMtwmStoreWrite { - // err = api.MtwmAPI.OrderReceived(utils.Str2Int64(order.VendorOrderID)) - err = api.MtwmAPI.OrderConfirm(utils.Str2Int64(order.VendorOrderID)) - if err != nil { - if utils.IsErrMatch(err, utils.Int2Str(mtwmapi.ErrCodeOpFailed), []string{ - "订单已经确认过了", - }) { - err = nil - } else { - globals.SugarLogger.Warnf("mtwm AcceptOrRefuseOrder orderID:%s failed with err:%v", order.VendorOrderID, err) - } - } - } - // if err == nil { - // c.postFakeMsg(order.VendorOrderID, FakeMsgType, mtwmapi.OrderStatusReceived) - // } - } else { - if globals.EnableMtwmStoreWrite { - err = c.CancelOrder(jxcontext.AdminCtx, order, "bu") - } - } - return err -} - -func (c *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) { - globals.SugarLogger.Debugf("mtwm PickupGoods orderID:%s, isSelfDelivery:%t", order.VendorOrderID, isSelfDelivery) - if !isSelfDelivery { - if globals.EnableMtwmStoreWrite { - // err = api.MtwmAPI.OrderConfirm(utils.Str2Int64(order.VendorOrderID)) - err = api.MtwmAPI.PreparationMealComplete(utils.Str2Int64(order.VendorOrderID)) - } - } - if err == nil { - c.postFakeMsg(order.VendorOrderID, FakeMsgType, fakeFinishedPickup) - } - return err -} - -func (p *PurchaseHandler) AcceptOrRefuseFailedGetOrder(ctx *jxcontext.Context, order *model.GoodsOrder, isAcceptIt bool) (err error) { - return err -} - -func (p *PurchaseHandler) CallCourier(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 拣货失败后再次招唤平台配送 - return err -} - -func (p *PurchaseHandler) ConfirmReceiveGoods(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 投递失败后确认收到退货 - return err -} - -// 美团预定单不能转商家自送 -func (c *PurchaseHandler) CanSwitch2SelfDeliver(order *model.GoodsOrder) (isCan bool, err error) { - return order.BusinessType != model.BusinessTypeDingshida, nil -} - -func (c *PurchaseHandler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) { - globals.SugarLogger.Debugf("mtwm Swtich2SelfDeliver orderID:%s", order.VendorOrderID) - if globals.EnableMtwmStoreWrite { - err = api.MtwmAPI.OrderLogisticsChange2Self(utils.Str2Int64(order.VendorOrderID)) - } - return err -} - -func (c *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName string) (err error) { - globals.SugarLogger.Debugf("mtwm Swtich2SelfDelivered orderID:%s", order.VendorOrderID) - if globals.EnableMtwmStoreWrite { - // 您好,之前的答复已经更正为,调用变更配送状态的接口,会校验门店的配送类型。美团配送的门店即便转自配后因门店配送类型是美团配送所以无法调用接口变更配送状态。可提醒顾客点击确认收货。谢谢 - // 非自配送门店订单调用OrderArrived好像会报错:{"data":"ng","error":{"code":1038,"msg":"只允许商家配送调用该接口"}} - // err = api.MtwmAPI.OrderArrived(utils.Str2Int64(order.VendorOrderID)) - } - return err -} - -func (c *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) { - globals.SugarLogger.Debugf("mtwm SelfDeliverDelivering orderID:%s", order.VendorOrderID) - if globals.EnableMtwmStoreWrite { - err = api.MtwmAPI.OrderDelivering(utils.Str2Int64(order.VendorOrderID)) - } - return err -} - -func (c *PurchaseHandler) SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) { - globals.SugarLogger.Debugf("mtwm SelfDeliverDelivered orderID:%s", order.VendorOrderID) - if globals.EnableMtwmStoreWrite { - err = api.MtwmAPI.OrderArrived(utils.Str2Int64(order.VendorOrderID)) - } - return err -} - -func getTimeFromTimestamp(timeStamp int64) time.Time { - if timeStamp < 1538103149 { // 立即达订单给的是1(而不是空,0),1538103149不是特殊值,只是一个任意之前的时间,这样写可以处理 - return utils.DefaultTimeValue - } - return utils.Timestamp2Time(timeStamp) -} - -func (c *PurchaseHandler) GetOrderRealMobile(ctx *jxcontext.Context, order *model.GoodsOrder) (mobile string, err error) { - err = errors.New("美团外卖还未实现GetOrderRealMobile") - return mobile, err -} - -func (c *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) { - if globals.EnableMtwmStoreWrite { - if isAgree { - err = api.MtwmAPI.OrderRefundAgree(utils.Str2Int64(order.VendorOrderID), reason) - } else { - err = api.MtwmAPI.OrderRefundReject(utils.Str2Int64(order.VendorOrderID), reason) - } - } - return err -} - -func (c *PurchaseHandler) CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) { - if globals.EnableMtwmStoreWrite { - if err = api.MtwmAPI.OrderCancel(utils.Str2Int64(order.VendorOrderID), reason, mtwmapi.CancelReasonOther); err == nil { - // 调用开放平台接口取消订单,不推送取消订单消息和退款消息。 - c.postFakeMsg(order.VendorOrderID, mtwmapi.MsgTypeOrderCanceled, mtwmapi.OrderStatusCanceled) - } - } - return err -} - -func (c *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) { - // 美团外卖必须要确认订单后才能调整单 - if order.Status < model.OrderStatusFinishedPickup { - err = c.PickupGoods(order, false, ctx.GetUserName()) - } - if err == nil { - var skuList []*mtwmapi.RefundSku - for _, sku := range removedSkuList { - skuID := utils.Int2Str(jxutils.GetSkuIDFromOrderSku(sku)) - skuList = append(skuList, &mtwmapi.RefundSku{ - AppFoodCode: skuID, - SkuID: skuID, - Count: sku.Count, - }) - } - if globals.EnableMtwmStoreWrite { - err = api.MtwmAPI.OrderApplyPartRefund(utils.Str2Int64(order.VendorOrderID), reason, skuList) - } - } - return err -} - -func (c *PurchaseHandler) ListOrders(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, queryDate time.Time, vendorStoreID string) (vendorOrderIDs []string, err error) { - if utils.IsTimeZero(queryDate) { - return nil, fmt.Errorf("queryDate必须指定") - } - queryDate = utils.Time2Date(queryDate) - - var vendorStoreIDs []string - if vendorStoreID == "" { - vendorStoreIDs, err = c.GetAllStoresVendorID(ctx, "") - if err != nil { - return nil, err - } - } else { - vendorStoreIDs = []string{vendorStoreID} - } - task := tasksch.NewParallelTask("mtwm ListOrders", nil, ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - vendorStoreID := batchItemList[0].(string) - var orderIDs []string - seqStart := 1 - i := 0 - for { - batchSize := int(math.Min(math.Pow(2, float64(i*3)), float64(mtwmapi.MaxGap4GetOrderIdByDaySeq))) - seqEnd := seqStart + batchSize - 1 - var tmpOrderIDs []int64 - if seqStart == seqEnd { - if vendorOderID, err2 := api.MtwmAPI.GetOrderIdByDaySeqSingle(vendorStoreID, queryDate, seqStart); err2 == nil { - tmpOrderIDs = []int64{vendorOderID} - } - } else { - tmpOrderIDs, err = api.MtwmAPI.GetOrderIdByDaySeq(vendorStoreID, queryDate, seqStart, seqEnd) - } - if len(tmpOrderIDs) > 0 { - for _, v := range tmpOrderIDs { - orderIDs = append(orderIDs, utils.Int64ToStr(v)) - } - } - if err != nil || len(tmpOrderIDs) < batchSize { - err = nil - break - } - seqStart = seqEnd + 1 - i++ - } - retVal = orderIDs - return retVal, nil - }, vendorStoreIDs) - tasksch.HandleTask(task, parentTask, true).Run() - orderList, err := task.GetResult(0) - if err == nil && len(orderList) > 0 { - vendorOrderIDs = make([]string, len(orderList)) - for k, v := range orderList { - vendorOrderIDs[k] = v.(string) - } - } - return vendorOrderIDs, err -} - -// func (c *PurchaseHandler) UpdateWaybillTip(ctx *jxcontext.Context, order *model.GoodsOrder, tipFee int64) (err error) { -// if globals.EnableMtwmStoreWrite { -// err = api.MtwmAPI.OrderUpdateTip(utils.Str2Int64(order.VendorOrderID), jxutils.IntPrice2Standard(tipFee)) -// } -// return err -// } - -func (p *PurchaseHandler) GetOrderConsigneeNumber(ctx *jxcontext.Context, storeID int, vendorStoreID string) (numberList []*partner.OrderPhoneNumberInfo, err error) { - offset := 0 - for { - result, err2 := api.MtwmAPI.OrderBatchPullPhoneNumber(vendorStoreID, offset, mtwmapi.MaxBatchPullPhoneNumberLimit) - if err = err2; err == nil { - for _, v := range result { - v2 := &partner.OrderPhoneNumberInfo{ - VendorOrderID: utils.Int64ToStr(v.OrderID), - PhoneNumber: v.RealPhoneNumber, - } - if v2.PhoneNumber == "" { - v2.PhoneNumber = v.RealOrderPhoneNumber - } - numberList = append(numberList, v2) - } - if len(result) <= mtwmapi.MaxBatchPullPhoneNumberLimit { - break - } - offset += mtwmapi.MaxBatchPullPhoneNumberLimit - } else { - break - } - } - return numberList, err -} - -func (p *PurchaseHandler) GetOrderCourierNumber(ctx *jxcontext.Context, storeID int, vendorStoreID string) (numberList []*partner.OrderPhoneNumberInfo, err error) { - offset := 0 - for { - result, err2 := api.MtwmAPI.OrderGetRiderInfoPhoneNumber(vendorStoreID, offset, mtwmapi.MaxBatchPullPhoneNumberLimit) - if err = err2; err == nil { - for _, v := range result { - numberList = append(numberList, &partner.OrderPhoneNumberInfo{ - VendorOrderID: utils.Int64ToStr(v.OrderID), - PhoneNumber: v.RiderRealPhoneNumber, - }) - } - if len(result) <= mtwmapi.MaxBatchPullPhoneNumberLimit { - break - } - offset += mtwmapi.MaxBatchPullPhoneNumberLimit - } else { - break - } - } - return numberList, err -} - -func (p *PurchaseHandler) onNumberDowngrade(msg *mtwmapi.CallbackMsg) (response *mtwmapi.CallbackResponse) { - userNumberMap := make(map[string]*partner.OrderPhoneNumberInfo) - courierNumberMap := make(map[string]*partner.OrderPhoneNumberInfo) - orderMap := make(map[string]int) - ctx := jxcontext.AdminCtx - task := tasksch.NewParallelTask("美团外卖平台处理隐私号降级通知", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(true), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - step := batchItemList[0].(int) - switch step { - case 0: - userNumberList, err2 := p.GetOrderConsigneeNumber(ctx, 0, "") - if err = err2; err == nil { - for _, v := range userNumberList { - userNumberMap[v.VendorOrderID] = v - orderMap[v.VendorOrderID] = 1 - } - } - case 1: - courierNumberList, err2 := p.GetOrderCourierNumber(ctx, 0, "") - if err = err2; err == nil { - for _, v := range courierNumberList { - courierNumberMap[v.VendorOrderID] = v - orderMap[v.VendorOrderID] = 1 - } - } - case 2: - orderList := jxutils.StringMap2List(orderMap) - if len(orderList) > 0 { - updateTask := tasksch.NewParallelTask("美团外卖平台处理隐私号降级通知/处理订单", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(true), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - vendorOrderID := batchItemList[0].(string) - db := dao.GetDB() - if userNumberMap[vendorOrderID] != nil { - _, err = dao.UpdateEntityByKV(db, &model.GoodsOrder{}, map[string]interface{}{ - "ConsigneeMobile": userNumberMap[vendorOrderID].PhoneNumber, - "ConsigneeMobile2": userNumberMap[vendorOrderID].PhoneNumber, - }, map[string]interface{}{ - model.FieldVendorOrderID: vendorOrderID, - model.FieldVendorID: model.VendorIDMTWM, - }) - } - if courierNumberMap[vendorOrderID] != nil { - _, err = dao.UpdateEntityByKV(db, &model.Waybill{}, map[string]interface{}{ - "CourierMobile": courierNumberMap[vendorOrderID].PhoneNumber, - }, map[string]interface{}{ - "VendorWaybillID": vendorOrderID, - "WaybillVendorID": model.VendorIDMTWM, - }) - } - return retVal, err - }, orderList) - tasksch.HandleTask(updateTask, task, true).Run() - _, err = updateTask.GetResult(0) - } - } - return retVal, err - }, []int{0, 1, 2}) - tasksch.HandleTask(task, nil, true).Run() - return response -} - -func (c *PurchaseHandler) GetWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2 string) (tipFee int64, err error) { - orderInfo, err := api.MtwmAPI.GetDistributeOrderDetail(vendorOrderID, vendorStoreID) - if err == nil { - tipFee = jxutils.StandardPrice2Int(orderInfo.TipAmount) - } - return tipFee, err -} - -func (c *PurchaseHandler) UpdateWaybillTip(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID, vendorOrderID, vendorWaybillID, vendorWaybillID2, cityCode string, tipFee int64) (err error) { - if globals.EnableMtwmStoreWrite { - err = api.MtwmAPI.OrderModityTips(vendorOrderID, vendorStoreID, jxutils.IntPrice2Standard(tipFee)) - } - return err -} diff --git a/business/partner/purchase/mtwm/order_afs.go b/business/partner/purchase/mtwm/order_afs.go deleted file mode 100644 index 0aaaaf1f0..000000000 --- a/business/partner/purchase/mtwm/order_afs.go +++ /dev/null @@ -1,213 +0,0 @@ -package mtwm - -import ( - "fmt" - "net/url" - "strings" - - "git.rosy.net.cn/baseapi/platformapi/mtwmapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -var ( - // AfsVendorStatus2StatusMap = map[int]int{ - // mtwmapi.ResTypePending: model.AfsOrderStatusWait4Approve, - // mtwmapi.ResTypeMerchantRefused: model.AfsOrderStatusFailed, - // mtwmapi.ResTypeMerchantAgreed: model.AfsOrderStatusFinished, - // mtwmapi.ResTypeCSRefused: model.AfsOrderStatusFailed, - // mtwmapi.ResTypeCSAgreed: model.AfsOrderStatusFinished, - // mtwmapi.ResTypeTimeoutAutoAgreed: model.AfsOrderStatusFinished, - // mtwmapi.ResTypeAutoAgreed: model.AfsOrderStatusFinished, - // mtwmapi.ResTypeUserCancelApply: model.AfsOrderStatusFailed, - // mtwmapi.ResTypeUserCancelComplain: model.AfsOrderStatusFailed, - // } - AfsVendorStatus2StatusMap = map[string]int{ - mtwmapi.NotifyTypeApply: model.AfsOrderStatusWait4Approve, - mtwmapi.NotifyTypePartyApply: model.AfsOrderStatusWait4Approve, - mtwmapi.NotifyTypeSuccess: model.AfsOrderStatusFinished, - mtwmapi.NotifyTypeReject: model.AfsOrderStatusFailed, - mtwmapi.NotifyTypeCancelRefund: model.AfsOrderStatusFailed, - mtwmapi.NotifyTypeCancelRefundComplaint: model.AfsOrderStatusFailed, - } -) - -func (c *PurchaseHandler) isAfsMsg(msg *mtwmapi.CallbackMsg) bool { - if msg.Cmd == mtwmapi.MsgTypeOrderRefund || msg.Cmd == mtwmapi.MsgTypeOrderPartialRefund { - // refundData := msg.Data.(*mtwmapi.CallbackRefundInfo) - orderID := utils.Str2Int64(GetOrderIDFromMsg(msg)) - status, err := api.MtwmAPI.OrderViewStatus(orderID) - if err == nil { - return utils.Int2Str(status) == mtwmapi.OrderStatusFinished - } - globals.SugarLogger.Warnf("mtwm isAfsMsg OrderGetOrderDetail2 orderID:%d failed with error:%v", orderID, err) - } - return false -} - -func (c *PurchaseHandler) OnAfsOrderMsg(msg *mtwmapi.CallbackMsg) (retVal *mtwmapi.CallbackResponse) { - jxutils.CallMsgHandlerAsync(func() { - retVal = c.onAfsOrderMsg(msg) - }, jxutils.ComposeUniversalOrderID(GetOrderIDFromMsg(msg), model.VendorIDEBAI)) - return retVal -} - -// todo 对于退款与部分退款,order.go与这个文件中对于状态的处理不一致 -func (c *PurchaseHandler) onAfsOrderMsg(msg *mtwmapi.CallbackMsg) (retVal *mtwmapi.CallbackResponse) { - var err error - orderStatus := c.callbackAfsMsg2Status(msg) - needCallNew := orderStatus.Status == model.AfsOrderStatusWait4Approve || orderStatus.Status == model.AfsOrderStatusNew - if !needCallNew { - _, err := partner.CurOrderManager.LoadAfsOrder(orderStatus.VendorOrderID, orderStatus.VendorID) - if err != nil { - if dao.IsNoRowsError(err) { - needCallNew = true - } else { - return mtwmapi.Err2CallbackResponse(err, "") - } - } - } - - if needCallNew { - var afsOrder *model.AfsOrder - refundData := msg.Data.(*mtwmapi.CallbackRefundInfo) - if msg.Cmd == mtwmapi.MsgTypeOrderPartialRefund { - afsOrder = &model.AfsOrder{ - VendorID: model.VendorIDMTWM, - AfsOrderID: orderStatus.VendorOrderID, - VendorOrderID: orderStatus.RefVendorOrderID, - VendorStoreID: "", - StoreID: 0, - AfsCreatedAt: utils.Timestamp2Time(refundData.Timestamp), - VendorAppealType: "", - AppealType: model.AfsAppealTypeRefund, - VendorReasonType: "", - ReasonType: model.AfsReasonNotOthers, - ReasonDesc: utils.LimitUTF8StringLen(refundData.Reason, 1024), - ReasonImgList: utils.LimitUTF8StringLen(strings.Join(refundData.PictureList, ","), 1024), - RefundType: model.AfsTypePartRefund, - - VendorOrgCode: msg.AppID, - // FreightUserMoney: afsInfo.OrderFreightMoney, - // AfsFreightMoney: afsInfo.AfsFreight, - // BoxMoney: afsInfo.PackagingMoney, - // TongchengFreightMoney: afsInfo.TongchengFreightMoney, - // SkuBoxMoney: afsInfo.MealBoxMoney, - } - for _, sku := range refundData.FoodList { - orderSku := &model.OrderSkuFinancial{ - // VendorID: model.VendorIDMTWM, - // AfsOrderID: afsOrder.AfsOrderID, - // VendorOrderID: afsOrder.VendorOrderID, - // VendorStoreID: afsOrder.VendorStoreID, - // StoreID: afsOrder.StoreID, - // IsAfsOrder: 1, - - Count: sku.Count, - // ConfirmTime: afsOrder.AfsCreateAt, - VendorSkuID: sku.SkuID, - SkuID: int(utils.Str2Int64WithDefault(sku.SkuID, 0)), - Name: sku.FoodName, - UserMoney: jxutils.StandardPrice2Int(sku.RefundPrice)*int64(sku.Count) + jxutils.StandardPrice2Int(sku.BoxPrice)*int64(sku.BoxNum), - } - afsOrder.SkuUserMoney += orderSku.UserMoney - afsOrder.Skus = append(afsOrder.Skus, orderSku) - } - afsOrder.PmSubsidyMoney += afsOrder.RefundMoney - afsOrder.SkuUserMoney - } else { - if afsOrder = c.createAfsOrder(msg.FormData); afsOrder != nil { - // if orderFinancial, err2 := partner.CurOrderManager.LoadOrderFinancial(orderStatus.RefVendorOrderID, model.VendorIDMTWM); err2 == nil { - // afsOrder = c.OrderFinancialDetail2Refund(orderFinancial, msg.FormData) - afsOrder.AfsOrderID = orderStatus.VendorOrderID - afsOrder.RefundType = model.AfsTypeFullRefund - afsOrder.AppealType = model.AfsAppealTypeRefund - afsOrder.VendorReasonType = "" - afsOrder.ReasonType = model.AfsReasonNotOthers - afsOrder.ReasonDesc = utils.LimitUTF8StringLen(refundData.Reason, 1024) - afsOrder.ReasonImgList = utils.LimitUTF8StringLen(strings.Join(refundData.PictureList, ","), 1024) - } - } - if afsOrder != nil { - err = partner.CurOrderManager.OnAfsOrderNew(afsOrder, orderStatus) - } - } else { - err = partner.CurOrderManager.OnAfsOrderStatusChanged(orderStatus) - } - return mtwmapi.Err2CallbackResponse(err, "") -} - -func (p *PurchaseHandler) createAfsOrder(orderData url.Values) (afsOrder *model.AfsOrder) { - afsOrder, err := partner.CurOrderManager.CreateAfsOrderFromOrder(orderData.Get("order_id"), model.VendorIDMTWM) - if err == nil { - afsOrder.AfsOrderID = orderData.Get("refund_id") - afsOrder.AfsCreatedAt = utils.Timestamp2Time(utils.Str2Int64(orderData.Get("timestamp"))) - if afsOrder.AfsOrderID == "" { - afsOrder.AfsOrderID = afsOrder.VendorOrderID - } - } else { - afsOrder = nil - } - return afsOrder -} - -func (c *PurchaseHandler) callbackAfsMsg2Status(msg *mtwmapi.CallbackMsg) (orderStatus *model.OrderStatus) { - refundData := msg.Data.(*mtwmapi.CallbackRefundInfo) - orderStatus = &model.OrderStatus{ - VendorID: model.VendorIDMTWM, - OrderType: model.OrderTypeAfsOrder, - RefVendorOrderID: utils.Int64ToStr(refundData.OrderID), - RefVendorID: model.VendorIDMTWM, - VendorStatus: fmt.Sprintf("%s:%d", refundData.NotifyType, refundData.ResType), - Status: c.GetAfsStatusFromVendorStatus(refundData.ResType, refundData.NotifyType), - StatusTime: utils.Timestamp2Time(refundData.Timestamp), - Remark: refundData.Reason, - } - if refundData.RefundID > 0 { - orderStatus.VendorOrderID = utils.Int64ToStr(refundData.RefundID) - } else { - orderStatus.VendorOrderID = orderStatus.RefVendorOrderID - } - return orderStatus -} - -func (c *PurchaseHandler) GetAfsStatusFromVendorStatus(resType int, notifyType string) int { - status := AfsVendorStatus2StatusMap[notifyType] - if status == model.AfsOrderStatusWait4Approve && resType != mtwmapi.ResTypePending { - status = model.AfsOrderStatusNew - } - return status -} - -// 审核售后单申请 -func (c *PurchaseHandler) AgreeOrRefuseRefund(ctx *jxcontext.Context, order *model.AfsOrder, approveType int, reason string) (err error) { - if globals.EnableMtwmStoreWrite { - if approveType == partner.AfsApproveTypeRefused { - err = api.MtwmAPI.OrderRefundReject(utils.Str2Int64(order.VendorOrderID), reason) - } else { - err = api.MtwmAPI.OrderRefundAgree(utils.Str2Int64(order.VendorOrderID), reason) - } - } - return err -} - -// 确认收到退货 -func (c *PurchaseHandler) ConfirmReceivedReturnGoods(ctx *jxcontext.Context, order *model.AfsOrder) (err error) { - err = fmt.Errorf("内部错误,美团外卖平台不支持确认收到退货操作") - return err -} - -// 发起全款退款 -func (c *PurchaseHandler) RefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) { - return fmt.Errorf("%s不支持售后全额退款,请让买家发起退款", model.VendorChineseNames[model.VendorIDMTWM]) -} - -// 发起部分退款 -func (c *PurchaseHandler) PartRefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, refundSkuList []*model.OrderSku, reason string) (err error) { - return c.AdjustOrder(ctx, order, refundSkuList, reason) -} diff --git a/business/partner/purchase/mtwm/order_comment.go b/business/partner/purchase/mtwm/order_comment.go deleted file mode 100644 index 702682933..000000000 --- a/business/partner/purchase/mtwm/order_comment.go +++ /dev/null @@ -1,112 +0,0 @@ -package mtwm - -import ( - "strings" - "time" - - "git.rosy.net.cn/baseapi/platformapi/mtwmapi" - - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/partner" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -const ( - RefreshCommentTime = 7 * 24 * time.Hour // 此值必须大于24小时 - RefreshCommentTimeInterval = 60 * time.Minute - BAD_COMMENTS_MAX_MODIFY_TIME = 24 * 6 // 小时 -) - -func (c *PurchaseHandler) StartRefreshComment() { - utils.AfterFuncWithRecover(5*time.Second, func() { - c.refreshCommentOnce() - }) -} - -func (c *PurchaseHandler) refreshCommentOnce() { - c.RefreshComment(time.Now().Add(-RefreshCommentTime), time.Now()) - utils.AfterFuncWithRecover(RefreshCommentTimeInterval, func() { - c.refreshCommentOnce() - }) -} - -func formalizeTagList(mtwmTagList string) (outTagList string) { - if mtwmTagList != "" { - outTagList = string(utils.Format4Output(strings.Split(mtwmTagList, ","), true)) - } - return outTagList -} - -func (c *PurchaseHandler) RefreshComment(fromTime, toTime time.Time) (err error) { - storeMapList, err2 := dao.GetStoresMapList(dao.GetDB(), []int{model.VendorIDMTWM}, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, "", "") - if err = err2; err != nil { - return err - } - task := tasksch.NewParallelTask("mtwm RefreshComment", nil, jxcontext.AdminCtx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - storeMap := batchItemList[0].(*model.StoreMap) - endDateStr := time.Now().Add(-24 * time.Hour).Format("20060102") - startDateStr := time.Now().Add(-RefreshCommentTime).Format("20060102") - commentList, err2 := api.MtwmAPI.CommentQuery(storeMap.VendorStoreID, startDateStr, endDateStr, 0, 0, mtwmapi.CommentReplyStatusAll) - - var orderCommentList []*model.OrderComment - if err = err2; err != nil { - return nil, err - } - for _, mtwmComment := range commentList { - createdTime, err := utils.TryStr2Time(mtwmComment.CommentTime) - if err == nil { - orderComment := &model.OrderComment{ - VendorOrderID: utils.Int64ToStr(mtwmComment.CommentID), // 美团评价不能得到订单号,以评价ID代替 - VendorID: model.VendorIDMTWM, - UserCommentID: utils.Int64ToStr(mtwmComment.CommentID), - VendorStoreID: storeMap.VendorStoreID, - TagList: formalizeTagList(mtwmComment.CommentLables), - Score: int8(mtwmComment.FoodCommentScore), - ModifyDuration: BAD_COMMENTS_MAX_MODIFY_TIME, - OriginalMsg: string(utils.MustMarshal(mtwmComment)), - IsReplied: int8(mtwmComment.ReplyStatus), - } - if orderComment.IsReplied == 0 { - orderComment.Content = mtwmComment.CommentContent - orderComment.CommentCreatedAt = createdTime - } else { - orderComment.Content = mtwmComment.AddComment - if updatedTime, err := utils.TryStr2Time(mtwmComment.CommentTime); err == nil { - orderComment.CommentCreatedAt = updatedTime - } - } - orderCommentList = append(orderCommentList, orderComment) - } - } - return orderCommentList, nil - }, storeMapList) - task.Run() - resultList, err2 := task.GetResult(0) - if err = err2; err != nil { - return err - } - var orderCommentList []*model.OrderComment - for _, result := range resultList { - orderComment := result.(*model.OrderComment) - orderCommentList = append(orderCommentList, orderComment) - } - if len(orderCommentList) > 0 { - err = partner.CurOrderManager.OnOrderComments(orderCommentList) - } - return err -} - -func (c *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, vendorOrgCode string, orderComment *model.OrderComment, replyComment string) (err error) { - globals.SugarLogger.Debugf("mtwm ReplyOrderComment, orderComment:%s, replyComment:%s", utils.Format4Output(orderComment, true), replyComment) - if globals.EnableMtwmStoreWrite { - err = api.MtwmAPI.CommentAddReply(orderComment.VendorStoreID, utils.Str2Int64(orderComment.UserCommentID), replyComment) - } - return err -} diff --git a/business/partner/purchase/mtwm/order_test.go b/business/partner/purchase/mtwm/order_test.go deleted file mode 100644 index a7e62f6fe..000000000 --- a/business/partner/purchase/mtwm/order_test.go +++ /dev/null @@ -1,35 +0,0 @@ -package mtwm - -import ( - "testing" - "time" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - - "git.rosy.net.cn/baseapi/utils" - _ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" -) - -func TestGetOrder(t *testing.T) { - result, err := CurPurchaseHandler.GetOrder("", "33437032333978492") - if err != nil { - t.Fatal(err) - } - t.Log(utils.Format4Output(result, false)) -} - -func TestGetOrderStatus(t *testing.T) { - result, err := CurPurchaseHandler.GetOrderStatus("", "71884881906304496") - if err != nil { - t.Fatal(err) - } - t.Log(utils.Format4Output(result, false)) -} - -func TestListOrders(t *testing.T) { - result, err := CurPurchaseHandler.ListOrders(jxcontext.AdminCtx, "", nil, time.Now(), "4626746") - if err != nil { - t.Fatal(err) - } - t.Log(utils.Format4Output(result, false)) -} diff --git a/business/partner/purchase/mtwm/store.go b/business/partner/purchase/mtwm/store.go deleted file mode 100644 index c834465d2..000000000 --- a/business/partner/purchase/mtwm/store.go +++ /dev/null @@ -1,317 +0,0 @@ -package mtwm - -import ( - "errors" - "math" - "regexp" - "strings" - - "git.rosy.net.cn/baseapi/platformapi/mtwmapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/baseapi/utils/errlist" - "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -var ( - opTimeErrReg = regexp.MustCompile(`当前配送营业时间为:([\d:~,]*)`) -) - -type tEbaiStoreInfo struct { - model.Store - VendorStoreID string `orm:"column(vendor_store_id)"` - RealLastOperator string - EbaiStoreStatus int - SyncStatus int - - ProvinceID int `orm:"column(province_id)"` - CityID int `orm:"column(city_id)"` - DistrictID int `orm:"column(district_id)"` -} - -func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string) (retVal *dao.StoreDetail, err error) { - result, err := api.MtwmAPI.PoiGet(vendorStoreID) - if err == nil { - // globals.SugarLogger.Debug(utils.Format4Output(result, false)) - retVal = &dao.StoreDetail{ - Store: model.Store{ - Address: result.Address, - Tel1: result.Phone, - }, - } - retVal.OriginalName = result.Name - _, retVal.Name = jxutils.SplitStoreName(retVal.OriginalName, partner.StoreNameSeparator, globals.StoreNameMtwm) - - retVal.SetOpTime(openTimeMtwm2JX(result.ShippingTime)) - retVal.Status = bizStatusMtwm2JX(result.OpenLevel, result.IsOnline) - - tel2 := result.StandbyTel - if tel2 != "" && tel2 != retVal.Tel1 { - retVal.Tel2 = tel2 - } - - retVal.Lng = int(result.Longitude) - retVal.Lat = int(result.Latitude) - - lng := jxutils.IntCoordinate2Standard(retVal.Lng) - lat := jxutils.IntCoordinate2Standard(retVal.Lat) - db := dao.GetDB() - retVal.DistrictCode = api.AutonaviAPI.GetCoordinateDistrictCode(lng, lat) - city, err := dao.GetPlaceByCode(db, result.CityID) - retVal.CityName = city.Name - retVal.CityCode = result.CityID - - poiCode := result.AppPoiCode - retVal.VendorStoreID = vendorStoreID - retVal.ID = int(utils.Str2Int64WithDefault(poiCode, 0)) - retVal.DeliveryRangeType = model.DeliveryRangeTypePolygon - var deliveryRangeInfo []map[string]interface{} - deliveryRangeInfo, err = api.MtwmAPI.ShippingFetch(poiCode) - if err != nil { - deliveryRangeInfo, err = api.MtwmAPI.ShippingList(poiCode) - } - if err == nil { - if len(deliveryRangeInfo) > 0 { - retVal.DeliveryRange = rangeMtwm2JX(deliveryRangeInfo[0]["area"].(string)) - logisticsCode := utils.Interface2String(deliveryRangeInfo[0]["logistics_code"]) - if logisticsCode == "" || logisticsCode == mtwmapi.PeiSongTypeSelf { - retVal.DeliveryType = scheduler.StoreDeliveryTypeByStore - } else { - retVal.DeliveryType = scheduler.StoreDeliveryTypeByPlatform - } - } - } - return retVal, nil - } - return nil, err -} -func (p *PurchaseHandler) CreateStore(db *dao.DaoDB, storeID int, userName string) (err error) { - return p.UpdateStore(db, storeID, userName) -} - -func (p *PurchaseHandler) CreateStore2(db *dao.DaoDB, storeID int, userName string) (vendorStoreID string, err error) { - return vendorStoreID, err -} - -func (p *PurchaseHandler) DeleteStore(db *dao.DaoDB, storeID int, userName string) (err error) { - return err -} - -func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName string) (err error) { - var name string - if db == nil { - db = dao.GetDB() - } - storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDMTWM) - if err != nil { - return err - } - errList := errlist.New() - - remoteStoreInfo, err := api.MtwmAPI.PoiGet(storeDetail.VendorStoreID) - if err != nil { - return err - } - mergedStoreStatus := jxutils.MergeStoreStatus(storeDetail.Status, storeDetail.VendorStatus) - name = remoteStoreInfo.Name - if storeDetail.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreName) != 0 { - if storeDetail.VendorStoreName != "" { - name = storeDetail.VendorStoreName - } - // else { - // name = jxutils.ComposeStoreName(storeDetail.Store.Name, model.VendorIDMTWM) - // } - } - // openLevel, isOnline := bizStatusJX2Mtwm(mergedStoreStatus) - //TODO 美团暂时不用那个电话 - phone := storeDetail.Tel1 - // if storeDetail.MarketManPhone != "" { - // phone = storeDetail.MarketManPhone - // } else { - // phone = model.VendorStoreTel - // } - params := map[string]interface{}{ - "name": name, //jxutils.ComposeStoreName(storeDetail.Store.Name, model.VendorIDMTWM), - "address": storeDetail.Address, // 美团好像地址也不能改的? - "longitude": jxutils.IntCoordinate2Standard(int(remoteStoreInfo.Longitude)), - "latitude": jxutils.IntCoordinate2Standard(int(remoteStoreInfo.Latitude)), - "phone": phone, - "shipping_fee": remoteStoreInfo.ShippingFee, - "shipping_time": remoteStoreInfo.ShippingTime, - "open_level": remoteStoreInfo.OpenLevel, - "is_online": remoteStoreInfo.IsOnline, - "third_tag_name": remoteStoreInfo.ThirdTagName, - "promotion_info": storeDetail.PromoteInfo, - } - // globals.SugarLogger.Debug(utils.Format4Output(params, false)) - if globals.EnableMtwmStoreWrite { - errList.AddErr(api.MtwmAPI.PoiSave(storeDetail.VendorStoreID, params)) - } - // PoiSave有时会报错:商家已接入美团配送,不可修改门店配送相关信息,这里放弃信息修改 - // if err != nil { - // if utils.IsErrMatch(err, utils.Int2Str(mtwmapi.ErrCodeCanNotModifyStoreDeliveryInfo), nil) { - // globals.SugarLogger.Infof("mtwm UpdateStore vendorStoreID:%s, params:%s failed with err:%v", storeDetail.VendorStoreID, utils.Format4Output(params, true), err) - // if storeDetail.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreStatus) != 0 { - // err = p.UpdateStoreStatus(jxcontext.AdminCtx, storeDetail.VendorOrgCode, storeID, storeDetail.VendorStoreID, mergedStoreStatus) - // } else { - // err = nil - // } - // } - // errList.AddErr(err) - // } - if storeDetail.SyncStatus&(model.SyncFlagNewMask|model.SyncFlagStoreStatus) != 0 { - errList.AddErr(p.UpdateStoreStatus(jxcontext.AdminCtx, storeDetail.VendorOrgCode, storeID, storeDetail.VendorStoreID, mergedStoreStatus)) - } - errList.AddErr(p.UpdateStoreOpTime(jxcontext.AdminCtx, storeDetail.VendorOrgCode, storeID, storeDetail.VendorStoreID, storeDetail.GetOpTimeList())) - errList.AddErr(p.UpdateStoreBoxFee(jxcontext.AdminCtx, storeDetail.VendorOrgCode, storeID, storeDetail.VendorStoreID)) - return errList.GetErrListAsOne() -} - -func (p *PurchaseHandler) RefreshAllStoresID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) { - return "", errors.New("美团外卖不支持此操作") -} - -func (p *PurchaseHandler) onStoreStatusChanged(msg *mtwmapi.CallbackMsg) (response *mtwmapi.CallbackResponse) { - var err error - poiStatus := int(utils.Str2Int64(msg.FormData.Get("poi_status"))) - vendorStoreID := msg.FormData.Get("app_poi_code") - storeStatus := 0 - if poiStatus == mtwmapi.MsgPoiStatusOpened { - storeStatus = model.StoreStatusOpened - } else if poiStatus == mtwmapi.MsgPoiStatusClosed { - storeStatus = model.StoreStatusClosed - } else if poiStatus == mtwmapi.MsgPoiStatusOffline { - storeStatus = model.StoreStatusDisabled - } else { - storeStatus, err = p.GetStoreStatus(jxcontext.AdminCtx, "", 0, vendorStoreID) - } - if err == nil { - err = partner.CurStoreManager.OnStoreStatusChanged(vendorStoreID, model.VendorIDMTWM, storeStatus) - } - response = mtwmapi.Err2CallbackResponse(err, "") - return response -} - -func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (storeStatus int, err error) { - result, err := api.MtwmAPI.PoiGet(vendorStoreID) - if err == nil { - return bizStatusMtwm2JX(result.OpenLevel, result.IsOnline), nil - } - return 0, err -} - -func (p *PurchaseHandler) EnableAutoAcceptOrder(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, isSetEnable bool) (err error) { - return err -} - -func (c *PurchaseHandler) UpdateStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, status int) (err error) { - openLevel, isOnline := bizStatusJX2Mtwm(status) - if globals.EnableMtwmStoreWrite { - if isOnline != mtwmapi.PoiStatusOnline { - err = api.MtwmAPI.PoiOffline(vendorStoreID) - } else { - if err = api.MtwmAPI.PoiOnline(vendorStoreID); err == nil { // 这个函数成功返回也并不表示上线成功。。。 - remoteStoreInfo, err2 := api.MtwmAPI.PoiGet(vendorStoreID) - if err = err2; err != nil { - return err - } - if remoteStoreInfo.IsOnline == mtwmapi.PoiStatusOnline { - if openLevel == mtwmapi.PoiOpenLevelHaveRest { - err = api.MtwmAPI.PoiClose(vendorStoreID) - } else { - err = api.MtwmAPI.PoiOpen(vendorStoreID) - } - } else { - err = errors.New("门店还未上线,不能修改营业状态") - } - } - } - } - return err -} - -func errOpStr2Int16(str string) []int16 { - list := strings.Split(str, "~") - if len(list) >= 2 { - return []int16{jxutils.StrTime2JxOperationTime(list[0]+":00", 0), jxutils.StrTime2JxOperationTime(list[1]+":00", 2359)} - } - return nil -} - -func getOpTimeListFromErr(err error) (opTimeList []int16) { - if errExt, ok := err.(*utils.ErrorWithCode); ok && errExt.IntCode() == mtwmapi.ErrCodeOpFailed { - if result := opTimeErrReg.FindStringSubmatch(errExt.ErrMsg()); len(result) >= 2 { - timeStrList := strings.Split(result[1], ",") - for _, v := range timeStrList { - v = utils.TrimBlankChar(v) - if len(v) == len("00:00~02:00") { - opTimeList = append(opTimeList, errOpStr2Int16(v)...) - } - } - } - } - return opTimeList -} - -// 此函数只是简单实现,不支持区间切分,只做单一区间限制 -func constrainOpTimeList(opTimeList, validOpTimeList []int16) (newOpTimeList []int16) { - for k := 0; k < len(opTimeList); k += 2 { - beginTime := opTimeList[k] - endTime := opTimeList[k+1] - for k2 := 0; k2 < len(validOpTimeList); k2 += 2 { - beginTime2 := validOpTimeList[k2] - endTime2 := validOpTimeList[k2+1] - if beginTime >= beginTime2 && beginTime <= endTime2 { - newOpTimeList = append(newOpTimeList, beginTime) - newOpTimeList = append(newOpTimeList, int16(math.Min(float64(endTime), float64(endTime2)))) - } else if beginTime2 >= beginTime && beginTime2 <= endTime { - newOpTimeList = append(newOpTimeList, beginTime2) - newOpTimeList = append(newOpTimeList, int16(math.Min(float64(endTime), float64(endTime2)))) - } - } - } - return newOpTimeList -} - -func (c *PurchaseHandler) UpdateStoreOpTime(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, opTimeList []int16) (err error) { - shippingTime := openTimeJX2Mtwm(opTimeList) - if globals.EnableMtwmStoreWrite { - err = api.MtwmAPI.PoiShipTimeUpdate(vendorStoreID, shippingTime) - if err != nil { - shippingTime = "" - if validOpTimeList := getOpTimeListFromErr(err); len(validOpTimeList) > 0 { - shippingTime = openTimeJX2Mtwm(constrainOpTimeList(opTimeList, validOpTimeList)) - } - if shippingTime != "" { - err = api.MtwmAPI.PoiShipTimeUpdate(vendorStoreID, shippingTime) - } - } - } - return err -} - -func (c *PurchaseHandler) GetAllStoresVendorID(ctx *jxcontext.Context, vendorOrgCode string) (vendorStoreIDs []string, err error) { - vendorStoreIDs, err = api.MtwmAPI.PoiGetIDs() - return vendorStoreIDs, err -} - -func (c *PurchaseHandler) UpdateStoreCustomID(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string, storeID int64) (err error) { - return err -} - -func (c *PurchaseHandler) UpdateStoreBoxFee(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (err error) { - boxFee, err := dao.GetSysConfigAsInt64(dao.GetDB(), model.ConfigSysMtwmBoxFee) - if err == nil { - if globals.EnableMtwmStoreWrite && globals.IsProductEnv() { - err = api.MtwmAPI.PackagePriceUpdate(vendorStoreID, 1, int(boxFee)) - } - } - return err -} diff --git a/business/partner/purchase/mtwm/store_sku2.go b/business/partner/purchase/mtwm/store_sku2.go deleted file mode 100644 index 7d4ff6a52..000000000 --- a/business/partner/purchase/mtwm/store_sku2.go +++ /dev/null @@ -1,676 +0,0 @@ -package mtwm - -import ( - "encoding/json" - "regexp" - "strings" - - "git.rosy.net.cn/baseapi/platformapi/mtwmapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/business/partner/putils" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -const ( - updateTypeStock = iota - updateTypeStatus - updateTypePrice -) - -const ( - defVendorCatID = 200001903 // 生菜 - - specialStoreID = "8171010" - // specialStoreID = "2523687" -) - -var ( - sensitiveWordRegexp = regexp.MustCompile(`包含敏感词:(\[.*\])`) -) - -func (p *PurchaseHandler) GetStoreSkusBatchSize(funcID int) (batchSize int) { - switch funcID { - case partner.FuncUpdateStoreSkusStock, partner.FuncUpdateStoreSkusStatus, partner.FuncUpdateStoreSkusPrice: - batchSize = mtwmapi.MaxStoreSkuBatchSize - case partner.FuncDeleteStoreSkus: - batchSize = mtwmapi.MaxBatchDeleteSize - case partner.FuncCreateStoreSkus: - batchSize = 1 // 可考虑用批量操作 - case partner.FuncUpdateStoreSkus: - batchSize = 1 // mtwmapi.MaxStoreSkuBatchSize - case partner.FuncGetStoreSkusFullInfo: - batchSize = 1 - case partner.FuncCreateActs: - batchSize = mtwmapi.MaxRetailDiscountCreateBatchSize - case partner.FuncCancelActs: - batchSize = mtwmapi.MaxRetailDiscountDeleteBatchSize - } - return batchSize -} - -// 门店分类 -func (p *PurchaseHandler) GetStoreAllCategories(ctx *jxcontext.Context, storeID int, vendorStoreID string) (cats []*partner.BareCategoryInfo, err error) { - remoteCats, err := api.MtwmAPI.RetailCatList(vendorStoreID) - if err == nil { - cats = convertVendorCatList(remoteCats) - } - return cats, err -} - -func convertVendorCatList(remoteCats []*mtwmapi.RetailCategoryInfo) (cats []*partner.BareCategoryInfo) { - for _, rCat := range remoteCats { - cat := &partner.BareCategoryInfo{ - VendorCatID: rCat.Code, - Name: rCat.Name, - Level: rCat.Level, - Seq: rCat.Sequence, - Children: convertVendorCatList(rCat.Children), - } - if cat.VendorCatID == "" { - cat.VendorCatID = rCat.Name - } - cats = append(cats, cat) - } - return cats -} - -func (p *PurchaseHandler) IsErrCategoryExist(err error) (isExist bool) { - return mtwmapi.IsErrCategoryExist(err) -} - -func (p *PurchaseHandler) IsErrCategoryNotExist(err error) (isNotExist bool) { - return mtwmapi.IsErrCategoryNotExist(err) -} - -func catCode2Str(catCode int) (catCodeStr string) { - if catCode > 0 { - catCodeStr = utils.Int2Str(catCode) - } - return catCodeStr -} - -func tryCatName2Code(originName string) (catCodeStr string) { - if intValue := utils.Str2Int64WithDefault(originName, 0); intValue > 0 { - catCodeStr = utils.Int64ToStr(intValue) - if catCodeStr != originName { - catCodeStr = "" - } - } - return catCodeStr -} - -func (p *PurchaseHandler) CreateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) { - level := 1 - if storeCat.ParentCatName != "" { - level = 2 - } - originName := "" - catName := storeCat.Name - catCode := storeCat.ID - - subCatName := "" - subCatCode := 0 - if storeCat.CatSyncStatus&model.SyncFlagNewMask == 0 { - // 修改一级分类 - originName = storeCat.VendorCatID - } - if level == 2 { // 二级分类 - // 创建二级分类 - originName = storeCat.ParentVendorCatID - catName = storeCat.ParentCatName - catCode = storeCat.ParentID - subCatName = storeCat.Name - subCatCode = storeCat.ID - if storeCat.CatSyncStatus&model.SyncFlagNewMask == 0 { - // 修改二级分类 - originName = storeCat.VendorCatID - catName = storeCat.Name - catCode = storeCat.ID - subCatName = "" - subCatCode = 0 - } - } - if catName == "" { - panic("catName is empty") - } - catName = utils.FilterEmoji(catName) - subCatName = utils.FilterEmoji(subCatName) - globals.SugarLogger.Debugf("mtwm CreateStoreCategory vendorStoreID:%s, originName:%s, catCode:%d, catName:%s, subCatCode:%d, subCatName:%s, seq:%d", - vendorStoreID, originName, catCode, catName, subCatCode, subCatName, storeCat.Seq) - if globals.EnableMtwmStoreWrite { - // err = api.MtwmAPI.RetailCatUpdate2(vendorStoreID, tryCatName2Code(originName), originName, catCode2Str(catCode), catName, catCode2Str(subCatCode), subCatName, storeCat.Seq) - param4Update := &mtwmapi.Param4UpdateCat{ - CategoryCodeOrigin: tryCatName2Code(originName), - CategoryNameOrigin: originName, - CategoryCode: catCode2Str(catCode), - SecondaryCategoryCode: catCode2Str(subCatCode), - SecondaryCategoryName: subCatName, - Sequence: storeCat.Seq, - } - err = api.MtwmAPI.RetailCatUpdate(vendorStoreID, catName, param4Update) - if storeCat.CatSyncStatus&model.SyncFlagNewMask == 0 && // 修改分类名,但分类不存在 - p.IsErrCategoryNotExist(err) && originName != "" { - storeCat.CatSyncStatus |= model.SyncFlagNewMask - err = p.CreateStoreCategory(ctx, storeID, vendorStoreID, storeCat) - } - } - if err == nil { - // storeCat.VendorCatID = utils.FilterEmoji(storeCat.Name) - storeCat.VendorCatID = utils.Int2Str(storeCat.ID) - } - return err -} - -func (p *PurchaseHandler) UpdateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) { - return p.CreateStoreCategory(ctx, storeID, vendorStoreID, storeCat) -} - -func (p *PurchaseHandler) DeleteStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID, vendorCatID string, level int) (err error) { - if false { - if globals.EnableMtwmStoreWrite { - err = api.MtwmAPI.RetailCatDelete(vendorStoreID, tryCatName2Code(vendorCatID), vendorCatID) - } - } else { - var catCodes []string - if catCode := tryCatName2Code(vendorCatID); catCode != "" { - catCodes = []string{catCode} - } - if globals.EnableMtwmStoreWrite { - if level == 1 { - err = api.MtwmAPI.RetailCatSkuBatchDelete2(ctx.GetTrackInfo(), vendorStoreID, catCodes, []string{vendorCatID}, nil, nil, nil) - } else { - err = api.MtwmAPI.RetailCatSkuBatchDelete2(ctx.GetTrackInfo(), vendorStoreID, nil, nil, catCodes, []string{vendorCatID}, nil) - } - } - } - return err -} - -// 门店商品 - -// 多门店平台不需要实现这个接口 - -func (p *PurchaseHandler) IsErrSkuExist(err error) (isExist bool) { - return false -} - -func (p *PurchaseHandler) IsErrSkuNotExist(err error) (isNotExist bool) { - return mtwmapi.IsErrSkuNotExist(err) -} - -// func duplicateStoreSkuList(storeSkuList []*dao.StoreSkuSyncInfo, index int) (newStoreSkuList []*dao.StoreSkuSyncInfo) { -// newStoreSkuList = make([]*dao.StoreSkuSyncInfo, len(storeSkuList)) -// for k, v := range storeSkuList { -// tmp := *v -// tmp.SkuName = fmt.Sprintf("%s.%d", tmp.SkuName, index) -// tmp.SkuID = index*1000000 + tmp.SkuID -// newStoreSkuList[k] = &tmp -// } -// return newStoreSkuList -// } - -func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - failedList, err = p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, storeSkuList, false) - // if err == nil && vendorStoreID == specialStoreID { - // for i := 0; i < 2; i++ { - // p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, duplicateStoreSkuList(storeSkuList, i+1), true) - // } - // } - return failedList, err -} - -func (p *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - failedList, err = p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, storeSkuList, true) - // if err == nil && vendorStoreID == specialStoreID { - // for i := 0; i < 2; i++ { - // p.createOrUpdateStoreSkus(ctx, storeID, vendorStoreID, duplicateStoreSkuList(storeSkuList, i+1), true) - // } - // } - return failedList, err -} - -// 对于多门店平台来说,storeSkuList中只有SkuID与VendorSkuID有意义 -func (p *PurchaseHandler) createOrUpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo, isCreate bool) (failedList []*partner.StoreSkuInfoWithErr, err error) { - var syncType string - foodDataList := make([]map[string]interface{}, len(storeSkuList)) - if isCreate { - syncType = "创建商品" - } else { - syncType = "更新商品" - } - for i, storeSku := range storeSkuList { - isNeedUpdatePrice := isCreate //storeSku.SkuSyncStatus&(model.SyncFlagPriceMask|model.SyncFlagNewMask) != 0 - foodData := make(map[string]interface{}) - foodDataList[i] = foodData - foodData[mtwmapi.KeyAppFoodCode] = utils.Int2Str(storeSku.SkuID) - skus := []map[string]interface{}{ - map[string]interface{}{ - "sku_id": foodData[mtwmapi.KeyAppFoodCode], - }, - } - foodData["skus"] = skus - foodData["name"] = utils.LimitUTF8StringLen(utils.FilterEmoji(storeSku.SkuName), mtwmapi.MaxSkuNameCharCount) - foodData["description"] = storeSku.Comment - if isNeedUpdatePrice { - foodData["price"] = jxutils.IntPrice2Standard(storeSku.VendorPrice) - } - if storeSku.MinOrderCount != 0 { - foodData["min_order_count"] = storeSku.MinOrderCount - } else { - foodData["min_order_count"] = 1 - } - foodData["unit"] = storeSku.Unit - attr := switchAttr(storeSku.VendorVendorCatID) - if attr != "" { - foodData["common_attr_value"] = attr - } - catCode := tryCatName2Code(storeSku.VendorCatID) - if catCode != "" { - foodData["category_code"] = catCode - } else { - foodData["category_name"] = storeSku.VendorCatID - } - foodData["is_sold_out"] = skuStatusJX2Mtwm(storeSku.MergedStatus) - if true { // vendorStoreID == specialStoreID { - img2 := storeSku.Img2 - if img2 == "" { - img2 = storeSku.Img - } - if storeSku.ImgMix != "" { - foodData["picture"] = strings.Join(jxutils.BatchString2Slice(storeSku.ImgMix, img2, storeSku.ImgMix, storeSku.ImgMix, storeSku.ImgMix), ",") - } else { - foodData["picture"] = strings.Join(jxutils.BatchString2Slice(storeSku.Img, img2, storeSku.Img, storeSku.Img, storeSku.Img), ",") - } - } else { - foodData["picture"] = strings.Join(jxutils.BatchString2Slice(storeSku.Img, storeSku.Img2), ",") - } - if storeSku.DescImg != "" { - foodData["picture_contents"] = storeSku.DescImg - } - foodData["sequence"] = storeSku.GetSeq() - if storeSku.VendorVendorCatID != 0 { - foodData["tag_id"] = utils.Int64ToStr(storeSku.VendorVendorCatID) - } else { - // foodData["tag_id"] = utils.Int64ToStr(defVendorCatID) - } - skus[0]["spec"] = jxutils.ComposeSkuSpec(storeSku.SpecQuality, storeSku.SpecUnit) - if isNeedUpdatePrice { - skus[0]["price"] = foodData["price"] - } - skus[0]["stock"] = stockCount2Mtwm(model.MaxStoreSkuStockQty) - if storeSku.Upc != "" { - skus[0]["upc"] = storeSku.Upc - } - skus[0]["ladder_box_num"] = storeSku.LadderBoxNum - skus[0]["ladder_box_price"] = jxutils.IntPrice2Standard(int64(storeSku.LadderBoxPrice)) - if foodData["tag_id"] != nil { - skus[0]["weight"] = storeSku.Weight // weight字段仅限服饰鞋帽、美妆、日用品、母婴、生鲜果蔬、生活超市下的便利店/超市门店品类的商家使用 - } - } - if globals.EnableMtwmStoreWrite { - if len(foodDataList) == 1 { - foodDataList[0]["skus"] = string(utils.MustMarshal(foodDataList[0]["skus"])) - err = api.MtwmAPI.RetailInitData(ctx.GetTrackInfo(), vendorStoreID, utils.Int2Str(storeSkuList[0].SkuID), foodDataList[0]) - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDMTWM], syncType) - } else if len(foodDataList) > 0 { - failedFoodList, err2 := api.MtwmAPI.RetailBatchInitData(ctx.GetTrackInfo(), vendorStoreID, foodDataList) - if err = err2; err == nil { - if err = putils.GenPartialFailedErr(failedFoodList, len(failedFoodList)); err != nil { - failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorChineseNames[model.VendorIDMTWM], syncType) - // successList = putils.UnselectStoreSkuSyncListByVendorSkuIDs(storeSkuList, getAppFoodCodeList(failedFoodList)) - } - } else if err2 != nil && len(failedFoodList) == 0 { - if errExt, ok := err2.(*utils.ErrorWithCode); ok { - err = utils.UnmarshalUseNumber([]byte(errExt.ErrMsg()), &failedFoodList) - failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorChineseNames[model.VendorIDMTWM], syncType) - } - err = nil - } - } - } - for _, storeSku := range storeSkuList { - storeSku.VendorSkuID = utils.Int2Str(storeSku.SkuID) - } - return failedList, err -} - -func getAppFoodCodeList(l []*mtwmapi.AppFoodResult) (vendorSkuIDs []string) { - if len(l) > 0 { - vendorSkuIDs = make([]string, len(l)) - for k, v := range l { - vendorSkuIDs[k] = v.AppFoodCode - } - } - return vendorSkuIDs -} - -func (p *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - if globals.EnableMtwmStoreWrite { - if len(storeSkuList) == 1 { - err = api.MtwmAPI.RetailDelete(ctx.GetTrackInfo(), vendorStoreID, storeSkuList[0].VendorSkuID) - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDMTWM], "删除商品") - } else { - // todo 部分失败 - err = api.MtwmAPI.RetailCatSkuBatchDelete2(ctx.GetTrackInfo(), vendorStoreID, nil, nil, nil, nil, partner.BareStoreSkuInfoList(storeSkuList).GetVendorSkuIDList()) - if err != nil { - if errExt, ok := err.(*utils.ErrorWithCode); ok { - myMap := make(map[string][]*mtwmapi.AppFoodResult) - json.Unmarshal([]byte(errExt.ErrMsg()), &myMap) - failedList = SelectStoreSkuListByFoodList(storeSkuList, myMap["retail_error_list"], storeID, model.VendorChineseNames[model.VendorIDMTWM], "批量删除商品") - } - } - err = nil - } - } - return failedList, err -} - -func switchAttr(vendorCatID int64) (attrs string) { - switch vendorCatID { - case 200002727: - return mtwmapi.MtwmSkuAttr200002727 - case 200001555: - return mtwmapi.MtwmSkuAttr200001555 - case 200002728: - return mtwmapi.MtwmSkuAttr200002728 - case 200001519, 200000592: - return mtwmapi.MtwmSkuAttr200000592 - case 200002704, 200002731: - return mtwmapi.MtwmSkuAttr200002731 - case 200002716: - return mtwmapi.MtwmSkuAttr200002716 - case 200002667, 200002713, 200002670: - return mtwmapi.MtwmSkuAttr200002670 - case 200002680: - return mtwmapi.MtwmSkuAttr200002680 - default: - return "" - } - return attrs -} - -func stockCount2Mtwm(stock int) (mtwmStock string) { - return utils.Int2Str(stock) -} - -func storeSku2Mtwm(storeSkuList []*partner.StoreSkuInfo, updateType int) (skuList []*mtwmapi.BareStoreFoodInfo) { - for _, storeSku := range storeSkuList { - skuInfo := &mtwmapi.BareStoreFoodInfo{ - AppFoodCode: storeSku.VendorSkuID, - Skus: []*mtwmapi.BareStoreSkuInfo{ - &mtwmapi.BareStoreSkuInfo{ - SkuID: storeSku.VendorSkuID, - }, - }, - } - if updateType == updateTypeStock { - skuInfo.Skus[0].Stock = stockCount2Mtwm(storeSku.Stock) - } else if updateType == updateTypePrice { - skuInfo.Skus[0].Price = jxutils.IntPrice2StandardString(storeSku.VendorPrice) - } else { - skuInfo.Skus = nil - } - skuList = append(skuList, skuInfo) - } - return skuList -} - -func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (failedList []*partner.StoreSkuInfoWithErr, err error) { - skuList := storeSku2Mtwm(storeSkuList, updateTypeStatus) - mtwmStatus := skuStatusJX2Mtwm(status) - if globals.EnableMtwmStoreWrite { - failedFoodList, err2 := api.MtwmAPI.RetailSellStatus(ctx.GetTrackInfo(), vendorStoreID, skuList, mtwmStatus) - if err = err2; err == nil { - if len(failedFoodList) > 0 { - failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorChineseNames[model.VendorIDMTWM], "更新商品状态") - // successList = putils.UnselectStoreSkuListByVendorSkuIDs(storeSkuList, getAppFoodCodeList(failedFoodList)) - } - } else if err2 != nil && len(failedFoodList) == 0 { - if errExt, ok := err2.(*utils.ErrorWithCode); ok { - err = utils.UnmarshalUseNumber([]byte(errExt.ErrMsg()), &failedFoodList) - failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorChineseNames[model.VendorIDMTWM], "更新商品状态") - } - err = nil - } - } - return failedList, err -} - -func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - priceList := storeSku2Mtwm(storeSkuList, updateTypePrice) - if globals.EnableMtwmStoreWrite { - failedFoodList, err2 := api.MtwmAPI.RetailSkuPrice(ctx.GetTrackInfo(), vendorStoreID, priceList) - if err = err2; err == nil { - if len(failedFoodList) > 0 { - failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorChineseNames[model.VendorIDMTWM], "更新商品价格") - } - } else if err2 != nil && len(failedFoodList) == 0 { - if errExt, ok := err2.(*utils.ErrorWithCode); ok { - err = utils.UnmarshalUseNumber([]byte(errExt.ErrMsg()), &failedFoodList) - failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorChineseNames[model.VendorIDMTWM], "更新商品价格") - } - err = nil - } - } - return failedList, err -} - -func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - stockList := storeSku2Mtwm(storeSkuList, updateTypeStock) - if globals.EnableMtwmStoreWrite { - failedFoodList, err2 := api.MtwmAPI.RetailSkuStock(ctx.GetTrackInfo(), vendorStoreID, stockList) - if err = err2; err == nil { - if len(failedFoodList) > 0 { - failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorChineseNames[model.VendorIDMTWM], "更新商品库存") - } - //if err = putils.GenPartialFailedErr(failedFoodList, len(failedFoodList)); err != nil { - // successList = putils.UnselectStoreSkuListByVendorSkuIDs(storeSkuList, getAppFoodCodeList(failedFoodList)) - // } - } else if err2 != nil && len(failedFoodList) == 0 { - if errExt, ok := err2.(*utils.ErrorWithCode); ok { - err = utils.UnmarshalUseNumber([]byte(errExt.ErrMsg()), &failedFoodList) - failedList = SelectStoreSkuListByFoodList(storeSkuList, failedFoodList, storeID, model.VendorChineseNames[model.VendorIDMTWM], "更新商品库存") - } - err = nil - } - } - return failedList, err -} - -func mtwmSkuStatus2Jx(mtwmSkuStatus int) (jxSkuStatus int) { - if mtwmSkuStatus == mtwmapi.SellStatusOnline { - jxSkuStatus = model.SkuStatusNormal - } else { - jxSkuStatus = model.SkuStatusDontSale - } - return jxSkuStatus -} - -func (p *PurchaseHandler) GetStoreSkusFullInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (skuNameList []*partner.SkuNameInfo, err error) { - if len(storeSkuList) == 1 { - skuInfo, err := api.MtwmAPI.RetailGet(vendorStoreID, utils.Int2Str(storeSkuList[0].SkuID)) - if err != nil { - return nil, err - } - if skuName := vendorSku2Jx(skuInfo); skuName != nil { - skuNameList = append(skuNameList, skuName) - } - } else { - var storeSkuMap map[string]*partner.StoreSkuInfo - if storeSkuList != nil { - storeSkuMap = putils.StoreSkuList2MapByVendorSkuID(storeSkuList) - } - for { - // todo 待优化获取速度 - result, err := api.MtwmAPI.RetailList(vendorStoreID, len(skuNameList), mtwmapi.GeneralMaxLimit) - if err != nil { - return nil, err - } - if storeSkuMap == nil { - skuNameList = append(skuNameList, vendorSkuList2Jx(result)...) - } else { - for _, v := range result { - if storeSkuMap[v.AppFoodCode] != nil { - if skuName := vendorSku2Jx(v); skuName != nil { - skuNameList = append(skuNameList, skuName) - } - } - } - } - if len(result) < mtwmapi.GeneralMaxLimit { - break - } - } - } - return skuNameList, err -} - -func vendorSku2Jx(appFood *mtwmapi.AppFood) (skuName *partner.SkuNameInfo) { - if len(appFood.SkuList) == 0 { - globals.SugarLogger.Warnf("vendorSku2Jx, strange appFood:%s", utils.Format4Output(appFood, true)) - return nil - } - prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(appFood.Name) - vendorSku := appFood.SkuList[0] - weight := int(utils.Str2Int64WithDefault(vendorSku.Weight, 0)) - if weight <= 0 { - weight = jxutils.FormatSkuWeight(specQuality, specUnit) - } - skuID := int(utils.Str2Int64WithDefault(vendorSku.SkuID, 0)) - skuName = &partner.SkuNameInfo{ - NameID: int(utils.Str2Int64WithDefault(appFood.AppFoodCode, 0)), - VendorNameID: appFood.AppFoodCode, - - Prefix: prefix, - Name: name, - Unit: unit, - SkuList: []*partner.SkuInfo{ - &partner.SkuInfo{ - StoreSkuInfo: partner.StoreSkuInfo{ - VendorSkuID: vendorSku.SkuID, - SkuID: skuID, - IsSpecialty: appFood.IsSpecialty, - Stock: int(utils.Str2Int64WithDefault(vendorSku.Stock, partner.UnlimitedStoreSkuStock)), - VendorPrice: jxutils.StandardPrice2Int(utils.Str2Float64WithDefault(vendorSku.Price, 0)), - Status: mtwmSkuStatus2Jx(appFood.IsSoldOut), - }, - SkuName: appFood.Name, - Comment: comment, - SpecQuality: float64(specQuality), - SpecUnit: specUnit, - Weight: weight, - }, - }, - PictureList: appFood.PictureList, - } - if appFood.CategoryName != "" { - // todo, 因为当前我们用的是分类名操作这种方式,所以要返回分类名(而不是分类code) - skuName.VendorCatIDList = []string{appFood.CategoryName} - if appFood.SecondaryCategoryName != "" { - skuName.VendorCatIDList = append(skuName.VendorCatIDList, appFood.SecondaryCategoryName) - } - } - return skuName -} - -func vendorSkuList2Jx(appFoodList []*mtwmapi.AppFood) (skuNameList []*partner.SkuNameInfo) { - for _, appFood := range appFoodList { - if skuName := vendorSku2Jx(appFood); skuName != nil { - skuNameList = append(skuNameList, skuName) - } - } - return skuNameList -} - -func (p *PurchaseHandler) GetSensitiveWordRegexp() *regexp.Regexp { - return sensitiveWordRegexp -} - -//美团api返回 -func SelectStoreSkuListByFoodList(storeSkuList interface{}, foodList []*mtwmapi.AppFoodResult, storeID int, vendorName, syncType string) (selectedStoreSkuList []*partner.StoreSkuInfoWithErr) { - foodMap := make(map[string]string) - if len(foodList) > 0 { - for _, v := range foodList { - foodMap[v.AppFoodCode] = v.ErrorMsg - } - if storeSkuLists, ok := storeSkuList.([]*partner.StoreSkuInfo); ok { - for _, v := range storeSkuLists { - if foodMap[v.VendorSkuID] != "" { - foodFailed := &partner.StoreSkuInfoWithErr{ - StoreSkuInfo: v, - ErrMsg: foodMap[v.VendorSkuID], - StoreID: storeID, - VendoreName: vendorName, - SyncType: syncType, - } - selectedStoreSkuList = append(selectedStoreSkuList, foodFailed) - } - } - } - if storeSkuLists, ok := storeSkuList.([]*dao.StoreSkuSyncInfo); ok { - for _, v := range storeSkuLists { - if foodMap[v.VendorSkuID] != "" { - storeSkuInfo := &partner.StoreSkuInfo{ - SkuID: v.SkuID, - VendorSkuID: v.VendorSkuID, - NameID: v.NameID, - VendorNameID: v.VendorNameID, - VendorPrice: v.VendorPrice, - Status: v.Status, - } - foodFailed := &partner.StoreSkuInfoWithErr{ - StoreSkuInfo: storeSkuInfo, - ErrMsg: foodMap[v.VendorSkuID], - StoreID: storeID, - VendoreName: vendorName, - SyncType: syncType, - } - selectedStoreSkuList = append(selectedStoreSkuList, foodFailed) - } - } - } - } - return selectedStoreSkuList -} - -func (p *PurchaseHandler) CreateStoreSkusAct(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - actStoreSkuList := putils.StoreSku2ActStoreSku(model.SyncFlagNewMask, vendorStoreID, storeSkuList) - failedList, err = createOneShopAct(putils.GetFixDirectDownAct(vendorOrgCode, storeID, 0), vendorStoreID, actStoreSkuList) - storeSkuMap := putils.StoreSkuList2MapBySkuID(storeSkuList) - for _, v := range actStoreSkuList { - storeSkuMap[v.SkuID].VendorActID = v.VendorActID - } - return failedList, err -} - -func (p *PurchaseHandler) CancelActs(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - return cancelOneShopAct(putils.GetFixDirectDownAct(vendorOrgCode, storeID, 0), vendorStoreID, putils.StoreSku2ActStoreSku(model.SyncFlagDeletedMask, vendorStoreID, storeSkuList)) -} - -func (p *PurchaseHandler) UpdateStoreSkusSpecTag(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (err error) { - var foodDataList = []map[string]interface{}{} - for _, v := range storeSkuList { - var foodData = make(map[string]interface{}) - if v.IsSpecialty != 0 && v.IsSpecialty == -1 { - v.IsSpecialty = 0 - } - foodData["is_specialty"] = v.IsSpecialty - foodData["app_food_code"] = v.SkuID - foodDataList = append(foodDataList, foodData) - } - if globals.EnableMtwmStoreWrite { - if len(foodDataList) == 1 { - err = api.MtwmAPI.RetailInitData(ctx.GetTrackInfo(), vendorStoreID, utils.Int2Str(storeSkuList[0].SkuID), foodDataList[0]) - } else if len(foodDataList) > 0 { - _, err = api.MtwmAPI.RetailBatchInitData(ctx.GetTrackInfo(), vendorStoreID, foodDataList) - } - } - return err -} diff --git a/business/partner/purchase/mtwm/store_sku2_test.go b/business/partner/purchase/mtwm/store_sku2_test.go deleted file mode 100644 index 095fbe242..000000000 --- a/business/partner/purchase/mtwm/store_sku2_test.go +++ /dev/null @@ -1,64 +0,0 @@ -package mtwm - -import ( - "testing" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/partner" - // _ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" -) - -func TestGetStoreSkusFullInfo(t *testing.T) { - skuNameList, err := CurPurchaseHandler.GetStoreSkusFullInfo(jxcontext.AdminCtx, nil, 2, "2523687", nil) - if err != nil { - t.Fatal(err) - } - t.Log(utils.Format4Output(skuNameList, false)) - t.Log(len(skuNameList)) -} - -func TestGetStoreSkusBareInfo(t *testing.T) { - storeSkuList, err := CurPurchaseHandler.GetStoreSkusBareInfo(jxcontext.AdminCtx, "", nil, 2, "2523687", []*partner.StoreSkuInfo{ - &partner.StoreSkuInfo{ - SkuID: 969, - }, - &partner.StoreSkuInfo{ - SkuID: 1306, - }, - }) - if err != nil { - t.Fatal(err.Error()) - } - t.Log(utils.Format4Output(storeSkuList, false)) - t.Log(len(storeSkuList)) -} - -func TestDeleteStoreAllSkus(t *testing.T) { - err := CurPurchaseHandler.DeleteStoreAllSkus(jxcontext.AdminCtx, nil, 2, "2523687", true) - if err != nil { - t.Fatal(err) - } -} - -func TestDeleteStoreAllCategories(t *testing.T) { - err := CurPurchaseHandler.DeleteStoreAllCategories(jxcontext.AdminCtx, nil, 2, "2523687", true) - if err != nil { - t.Fatal(err) - } -} - -func TestGetStoreCategory(t *testing.T) { - _, err := CurPurchaseHandler.GetStoreCategory(jxcontext.AdminCtx, 2, "2523687", "不存在的分类") - if err == nil { - t.Fatal("应该找不到这个分类") - } - catName := "小月饼" - cat, err := CurPurchaseHandler.GetStoreCategory(jxcontext.AdminCtx, 2, "2523687", catName) - if err != nil { - t.Fatal(err) - } else if cat.Name != catName { - t.Fatal("没有找到正确的商家分类") - } - t.Log(utils.Format4Output(cat, false)) -} diff --git a/business/partner/purchase/mtwm/store_sku_test.go b/business/partner/purchase/mtwm/store_sku_test.go deleted file mode 100644 index c702627c6..000000000 --- a/business/partner/purchase/mtwm/store_sku_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package mtwm - -import ( - "testing" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - // _ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" -) - -// func TestSyncStoreCategory(t *testing.T) { -// hint, err := CurPurchaseHandler.SyncStoreCategory(jxcontext.AdminCtx, nil, testShopID, false) -// if err != nil { -// t.Fatal(err) -// } -// t.Log(hint) -// } - -// func TestSyncLocalStoreCategory(t *testing.T) { -// hint, err := CurPurchaseHandler.SyncLocalStoreCategory(jxcontext.AdminCtx, nil, testShopID, true, nil) -// if err != nil { -// t.Fatal(err) -// } -// t.Log(hint) -// } - -// func TestSyncStoreSkus(t *testing.T) { -// hint, err := CurPurchaseHandler.SyncStoreSkus(jxcontext.AdminCtx, nil, testShopID, nil, false, true) -// if err != nil { -// t.Fatal(err) -// } -// t.Log(hint) -// } - -func TestDeleteRemoteSkus(t *testing.T) { - err := CurPurchaseHandler.DeleteStoreAllSkus(jxcontext.AdminCtx, nil, testShopID, testShopVendorID, true) - if err != nil { - t.Fatal(err) - } -} - -func TestDeleteRemoteCategories(t *testing.T) { - err := CurPurchaseHandler.DeleteStoreAllCategories(jxcontext.AdminCtx, nil, testShopID, testShopVendorID, true) - if err != nil { - t.Fatal(err) - } -} diff --git a/business/partner/purchase/mtwm/store_test.go b/business/partner/purchase/mtwm/store_test.go deleted file mode 100644 index daecbef8f..000000000 --- a/business/partner/purchase/mtwm/store_test.go +++ /dev/null @@ -1,45 +0,0 @@ -package mtwm - -import ( - "testing" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - - "git.rosy.net.cn/baseapi/platformapi/mtwmapi" - "git.rosy.net.cn/baseapi/utils" - // _ "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" -) - -func TestReadStore(t *testing.T) { - store, err := CurPurchaseHandler.ReadStore(jxcontext.AdminCtx, "", "4351018") - if err != nil { - t.Fatal(err) - } - t.Log(utils.Format4Output(store, false)) -} - -func TestUpdateStore(t *testing.T) { - err := CurPurchaseHandler.UpdateStore(nil, 100002, "test") - if err != nil { - t.Fatal(err) - } -} - -func TestConstrainOpTimeList(t *testing.T) { - timeList := constrainOpTimeList([]int16{830, 1800}, []int16{ - 0, - 200, - 930, - 1700, - }) - t.Log(utils.Format4Output(timeList, false)) - if timeList[0] != 930 || timeList[1] != 1700 { - t.Fatal("constrainOpTimeList failed") - } -} - -func TestGetOpTimeListFromErr(t *testing.T) { - err := utils.NewErrorIntCode("当前配送营业时间为:07:00~24:00", mtwmapi.ErrCodeOpFailed) - list := getOpTimeListFromErr(err) - t.Log(list) -} diff --git a/business/partner/purchase/mtwm/waybill.go b/business/partner/purchase/mtwm/waybill.go deleted file mode 100644 index 432e02db4..000000000 --- a/business/partner/purchase/mtwm/waybill.go +++ /dev/null @@ -1,56 +0,0 @@ -package mtwm - -import ( - "git.rosy.net.cn/baseapi/platformapi/mtwmapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" -) - -var ( - VendorWaybillStatus2StatusMap = map[string]int{ - mtwmapi.WaybillStatusWait4Delivery: model.WaybillStatusNew, - mtwmapi.WaybillStatusPending: model.WaybillStatusPending, - mtwmapi.WaybillStatusAccepted: model.WaybillStatusAccepted, - mtwmapi.WaybillStatusCourierArrived: model.WaybillStatusCourierArrived, - mtwmapi.WaybillStatusPickedup: model.WaybillStatusDelivering, - mtwmapi.WaybillStatusDelivered: model.WaybillStatusDelivered, - mtwmapi.WaybillStatusCanceled: model.WaybillStatusCanceled, - } -) - -func (p *PurchaseHandler) GetWaybillStatusFromVendorStatus(vendorStatus string) int { - if status, ok := VendorWaybillStatus2StatusMap[vendorStatus]; ok { - return status - } - return model.WaybillStatusUnknown -} - -func (c *PurchaseHandler) onWaybillMsg(msg *mtwmapi.CallbackMsg) (response *mtwmapi.CallbackResponse) { - waybill := c.callbackMsg2Waybill(msg) - err := partner.CurOrderManager.OnWaybillStatusChanged(waybill) - if err == nil && waybill.Status == model.WaybillStatusDelivering { - c.postFakeMsg(waybill.VendorOrderID, FakeMsgType, mtwmapi.OrderStatusDelivering) - } - return mtwmapi.Err2CallbackResponse(err, "") -} - -func (c *PurchaseHandler) callbackMsg2Waybill(msg *mtwmapi.CallbackMsg) (retVal *model.Waybill) { - orderID := GetOrderIDFromMsg(msg) - vendorStatus := msg.FormData.Get("logistics_status") - retVal = &model.Waybill{ - VendorOrderID: orderID, - OrderVendorID: model.VendorIDMTWM, - VendorWaybillID: orderID, - WaybillVendorID: model.VendorIDMTWM, - CourierName: msg.FormData.Get("dispatcher_name"), - CourierMobile: msg.FormData.Get("dispatcher_mobile"), - VendorStatus: vendorStatus, - Status: c.GetWaybillStatusFromVendorStatus(vendorStatus), - StatusTime: getTimeFromTimestamp(utils.Str2Int64(msg.FormData.Get("time"))), - Remark: "", - - VendorOrgCode: msg.AppID, - } - return retVal -} diff --git a/business/partner/purchase/weimob/wsc/act.go b/business/partner/purchase/weimob/wsc/act.go deleted file mode 100644 index 1210cab88..000000000 --- a/business/partner/purchase/weimob/wsc/act.go +++ /dev/null @@ -1,11 +0,0 @@ -package wsc - -import ( - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" -) - -func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSkuList []*model.ActStoreSku2) (err error) { - return nil -} diff --git a/business/partner/purchase/weimob/wsc/callback.go b/business/partner/purchase/weimob/wsc/callback.go deleted file mode 100644 index f1cccb9bd..000000000 --- a/business/partner/purchase/weimob/wsc/callback.go +++ /dev/null @@ -1,18 +0,0 @@ -package wsc - -import ( - "git.rosy.net.cn/baseapi/platformapi/weimobapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/model" -) - -func OnCallbackMsg(msg *weimobapi.CallbackMsg) (response *weimobapi.CallbackResponse) { - if curPurchaseHandler != nil { - orderID := utils.Int64ToStr(msg.OrderNo) - jxutils.CallMsgHandler(func() { - response = curPurchaseHandler.onOrderMsg(msg) - }, jxutils.ComposeUniversalOrderID(orderID, model.VendorIDWSC)) - } - return response -} diff --git a/business/partner/purchase/weimob/wsc/order.go b/business/partner/purchase/weimob/wsc/order.go deleted file mode 100644 index 7978f3b62..000000000 --- a/business/partner/purchase/weimob/wsc/order.go +++ /dev/null @@ -1,309 +0,0 @@ -package wsc - -import ( - "errors" - "fmt" - "time" - - "git.rosy.net.cn/baseapi/platformapi/weimobapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/business/partner/delivery/dada" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -const ( - FakeOrderStatusAccepted = "fakeaccepted" - FakeOrderStatusFinishedPickup = "fakefinishedpickup" -) - -const ( - maxAddFee = 300 // 最大增加费用,单位为分,超过不发三方配送了 -) - -var ( - VendorStatus2StatusMap = map[string]int{ - utils.Int2Str(weimobapi.OrderStatusWait4Pay): model.OrderStatusWait4Pay, - utils.Int2Str(weimobapi.OrderStatusPayed): model.OrderStatusNew, - FakeOrderStatusAccepted: model.OrderStatusAccepted, - FakeOrderStatusFinishedPickup: model.OrderStatusFinishedPickup, - utils.Int2Str(weimobapi.OrderStatusDelivering): model.OrderStatusDelivering, - utils.Int2Str(weimobapi.OrderStatusFinished): model.OrderStatusFinished, - utils.Int2Str(weimobapi.OrderStatusCanceled): model.OrderStatusCanceled, - - weimobapi.MsgEventCreateRights: model.OrderStatusLocked, - } -) - -func (p *PurchaseHandler) onOrderMsg(msg *weimobapi.CallbackMsg) (response *weimobapi.CallbackResponse) { - var ( - err error - status *model.OrderStatus - orderMapData map[string]interface{} - ) - if msg.IsFake || weimobapi.MsgEventCreateOrder == msg.Event || weimobapi.MsgEventOrderStatusChange == msg.Event { - orderMapData, err = api.WeimobAPI.QueryOrderDetail(msg.OrderNo, false) - if err == nil { - status = p.callbackMsg2Status(msg, orderMapData) - if msg.Event == weimobapi.MsgEventCreateOrder || status.Status == model.OrderStatusNew { - order := p.Map2Order(orderMapData) - order.StatusTime = msg.StatusTime - err = partner.CurOrderManager.OnOrderNew(order, status) - } else { - err = partner.CurOrderManager.OnOrderStatusChanged("", status) - } - } - } - return weimobapi.Err2CallbackResponse(err, "") -} - -func (p *PurchaseHandler) callbackMsg2Status(msg *weimobapi.CallbackMsg, orderMapData map[string]interface{}) (orderStatus *model.OrderStatus) { - orderID := utils.Int64ToStr(msg.OrderNo) - var vendorStatus string - if msg.IsFake { - vendorStatus = msg.Event - } else { - if msg.Event == weimobapi.MsgEventCreateRights { - vendorStatus = msg.Event - } else { - vendorStatus = p.getOrderStatus(orderMapData) - } - } - orderStatus = &model.OrderStatus{ - VendorOrderID: orderID, - VendorID: model.VendorIDWSC, - OrderType: model.OrderTypeOrder, - RefVendorOrderID: orderID, - RefVendorID: model.VendorIDWSC, - VendorStatus: vendorStatus, - Status: p.getStatusFromVendorStatus(vendorStatus), - StatusTime: msg.StatusTime, - Remark: "", - } - return orderStatus -} - -func (p *PurchaseHandler) getOrderStatus(orderMapData map[string]interface{}) (status string) { - return utils.Int64ToStr(utils.MustInterface2Int64(orderMapData["orderStatus"])) -} - -func (p *PurchaseHandler) getStatusFromVendorStatus(vendorStatus string) int { - if status, ok := VendorStatus2StatusMap[vendorStatus]; ok { - return status - } - return model.OrderStatusUnknown -} - -func (p *PurchaseHandler) GetOrder(vendorOrgCode, vendorOrderID string) (order *model.GoodsOrder, err error) { - globals.SugarLogger.Debugf("wsc GetOrder orderID:%s", vendorOrderID) - result, err := api.WeimobAPI.QueryOrderDetail(utils.Str2Int64(vendorOrderID), false) - if err != nil { - return nil, err - } - order = p.Map2Order(result) - return order, err -} - -func (p *PurchaseHandler) GetOrderStatus(vendorOrgCode, vendorOrderID string) (status int, err error) { - return 0, fmt.Errorf("未实现") -} - -func (p *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) { - result := orderData - vendorOrderID := utils.Int64ToStr(utils.MustInterface2Int64(result["orderNo"])) - deliveryDetail := result["deliveryDetail"].(map[string]interface{}) - logisticsDeliveryDetail, _ := deliveryDetail["logisticsDeliveryDetail"].(map[string]interface{}) - // paymentInfo := result["paymentInfo"].(map[string]interface{}) - order = &model.GoodsOrder{ - VendorOrderID: vendorOrderID, - VendorID: model.VendorIDWSC, - VendorStoreID: utils.Int64ToStr(utils.MustInterface2Int64(result["processStoreId"])), // 这个不是通常意义上的vendor store id - // StoreID - BuyerComment: utils.Interface2String(result["buyerRemark"]), - ExpectedDeliveredTime: utils.DefaultTimeValue, - PickDeadline: utils.DefaultTimeValue, - VendorStatus: utils.Int64ToStr(utils.MustInterface2Int64(result["orderStatus"])), - StatusTime: utils.Timestamp2Time(utils.MustInterface2Int64(result["createTime"]) / 1000), - OrderCreatedAt: utils.Timestamp2Time(utils.MustInterface2Int64(result["createTime"]) / 1000), - OriginalData: string(utils.MustMarshal(result)), - ActualPayPrice: jxutils.StandardPrice2Int(utils.MustInterface2Float64(result["totalAmount"])), - BusinessType: model.BusinessTypeImmediate, - } - if logisticsDeliveryDetail != nil { - order.StoreName = utils.Interface2String(logisticsDeliveryDetail["processStoreTitle"]) - order.ConsigneeName = utils.Interface2String(logisticsDeliveryDetail["receiverName"]) - order.ConsigneeMobile = utils.Interface2String(logisticsDeliveryDetail["receiverMobile"]) - order.ConsigneeAddress = utils.Interface2String(logisticsDeliveryDetail["receiverAddress"]) - order.ConsigneeLng = jxutils.StandardCoordinate2Int(utils.Str2Float64(utils.Interface2String(logisticsDeliveryDetail["receiverLongitude"]))) - order.ConsigneeLat = jxutils.StandardCoordinate2Int(utils.Str2Float64(utils.Interface2String(logisticsDeliveryDetail["receiverLatitude"]))) - order.CoordinateType = model.CoordinateTypeMars - // if expectDeliveryTimeStr, ok := logisticsDeliveryDetail["expectDeliveryTime"].(string); ok { - // if expectDeliveryTimeStr = - // } - } else { - selfPickupDetail, _ := deliveryDetail["selfPickupDetail"].(map[string]interface{}) - if selfPickupDetail != nil { - order.StoreName = utils.Interface2String(selfPickupDetail["selfPickupSiteName"]) - } - } - order.Status = p.getStatusFromVendorStatus(order.VendorStatus) - itemList := result["itemList"].([]interface{}) - for _, v := range itemList { - item := v.(map[string]interface{}) - skuName := utils.Interface2String(item["goodsTitle"]) - _, _, _, specUnit, _, specQuality := jxutils.SplitSkuName(skuName) - sku := &model.OrderSku{ - VendorOrderID: vendorOrderID, - VendorID: model.VendorIDWSC, - Count: int(utils.MustInterface2Int64(item["skuNum"])), - SkuID: int(utils.Str2Int64WithDefault(utils.Interface2String(item["skuCode"]), 0)), - VendorSkuID: utils.Int64ToStr(utils.MustInterface2Int64(item["skuId"])), - SkuName: skuName, - Weight: jxutils.FormatSkuWeight(specQuality, specUnit), // 订单信息里没有重量,只有名字里尝试找 - SalePrice: jxutils.StandardPrice2Int(utils.MustInterface2Float64(item["price"])), - } - order.Skus = append(order.Skus, sku) - } - jxutils.RefreshOrderSkuRelated(order) - if logisticsDeliveryDetail != nil { - p.arrangeSaleStore(order, utils.Interface2String(logisticsDeliveryDetail["receiverCity"]), utils.Interface2String(logisticsDeliveryDetail["receiverProvince"])) - } - p.setStoreOrderSeq(order) - globals.SugarLogger.Debug(utils.Format4Output(order, false)) - return order -} - -func (p *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) { - globals.SugarLogger.Debugf("wsc AcceptOrRefuseOrder orderID:%s, isAcceptIt:%t", order.VendorOrderID, isAcceptIt) - if !isAcceptIt { - if globals.EnableWscStoreWrite { - err = api.WeimobAPI.CancelOrder(utils.Str2Int64(order.VendorOrderID), "") - } - } else { - if jxutils.GetSaleStoreIDFromOrder(order) != 0 { - // 微商城没有确认,只有取消,模拟接受 - p.postFakeMsg(utils.Str2Int64(order.VendorOrderID), FakeOrderStatusAccepted) - } else { - globals.SugarLogger.Debugf("weimob AcceptOrRefuseOrder orderID:%s can not find sale store", order.VendorOrderID) - if globals.EnableWscStoreWrite { - err = api.WeimobAPI.CancelOrder(utils.Str2Int64(order.VendorOrderID), "没有找到合适的配送店") - } - } - } - return err -} - -func (p *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) { - globals.SugarLogger.Debugf("wsc PickupGoods orderID:%s, isSelfDelivery:%t", order.VendorOrderID, isSelfDelivery) - if globals.EnableWscStoreWrite && !isSelfDelivery { - _, err = dada.CurDeliveryHandler.CreateWaybill(order, 0) - } - // 微商城没有拣货完成,模拟 - p.postFakeMsg(utils.Str2Int64(order.VendorOrderID), FakeOrderStatusFinishedPickup) - return err -} - -func (p *PurchaseHandler) AcceptOrRefuseFailedGetOrder(ctx *jxcontext.Context, order *model.GoodsOrder, isAcceptIt bool) (err error) { - return err -} - -func (p *PurchaseHandler) CallCourier(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 拣货失败后再次招唤平台配送 - return err -} - -func (p *PurchaseHandler) ConfirmReceiveGoods(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 投递失败后确认收到退货 - return err -} - -// 将订单从购物平台配送转为自送 -func (p *PurchaseHandler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) { - globals.SugarLogger.Debugf("wsc Swtich2SelfDeliver orderID:%s", order.VendorOrderID) - if globals.EnableWscStoreWrite { - err = api.WeimobAPI.DeliveryOrder(&weimobapi.DeliveryOrder{ - OrderNo: utils.Str2Int64(order.VendorOrderID), - }) - } - return err -} - -// 将订单从购物平台配送转为自送后又送达 -func (p *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName string) (err error) { - globals.SugarLogger.Debugf("wsc Swtich2SelfDelivered orderID:%s", order.VendorOrderID) - return err -} - -// 完全自送的门店表示开始配送 -func (p *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) { - globals.SugarLogger.Debugf("wsc SelfDeliverDelivering orderID:%s", order.VendorOrderID) - if globals.EnableWscStoreWrite { - err = api.WeimobAPI.DeliveryOrder(&weimobapi.DeliveryOrder{ - OrderNo: utils.Str2Int64(order.VendorOrderID), - }) - } - return err -} - -// 完全自送的门店表示配送完成 -func (p *PurchaseHandler) SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) { - globals.SugarLogger.Debugf("wsc SelfDeliverDelivered orderID:%s", order.VendorOrderID) - return err -} - -func (p *PurchaseHandler) postFakeMsg(orderNo int64, fakeStatus string) { - msg := &weimobapi.CallbackMsg{ - IsFake: true, - Event: fakeStatus, - OrderNo: orderNo, - StatusTime: time.Now(), - } - utils.CallFuncAsync(func() { - OnCallbackMsg(msg) - }) -} - -func (p *PurchaseHandler) arrangeSaleStore(order *model.GoodsOrder, cityName, provinceName string) { - -} - -func (p *PurchaseHandler) setStoreOrderSeq(order *model.GoodsOrder) { - if order.StoreID > 0 { - year, month, day := order.StatusTime.Date() - dateBegin := time.Date(year, month, day, 0, 0, 0, 0, order.StatusTime.Location()) - // dateEnd := date1.Add(time.Hour * 24) - sql := ` - SELECT COUNT(*) ct - FROM goods_order t1 - WHERE t1.store_id = ? AND t1.order_created_at >= ? AND t1.vendor_id = ? - ` - var count int - db := dao.GetDB() - if err := dao.GetRow(db, &count, sql, order.StoreID, dateBegin, model.VendorIDWSC); err == nil { - order.OrderSeq = count + 1 - globals.SugarLogger.Debugf("setStoreOrderSeq orderID:%s, dateBegin:%s, orderSeq:%d", order.VendorOrderID, utils.Time2Str(dateBegin), order.OrderSeq) - } else { - globals.SugarLogger.Errorf("setStoreOrderSeq orderID:%s failed with error:%v", order.VendorOrderID, err) - } - } -} - -func (c *PurchaseHandler) GetOrderRealMobile(ctx *jxcontext.Context, order *model.GoodsOrder) (mobile string, err error) { - err = errors.New("微盟微商城还未实现GetOrderRealMobile") - return mobile, err -} - -func (c *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) { - return err -} - -func (c *PurchaseHandler) CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) { - return err -} - -func (c *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) { - return err -} diff --git a/business/partner/purchase/weimob/wsc/order_afs.go b/business/partner/purchase/weimob/wsc/order_afs.go deleted file mode 100644 index 153a2a739..000000000 --- a/business/partner/purchase/weimob/wsc/order_afs.go +++ /dev/null @@ -1,28 +0,0 @@ -package wsc - -import ( - "fmt" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" -) - -// 审核售后单申请 -func (c *PurchaseHandler) AgreeOrRefuseRefund(ctx *jxcontext.Context, order *model.AfsOrder, approveType int, reason string) (err error) { - return err -} - -// 确认收到退货 -func (c *PurchaseHandler) ConfirmReceivedReturnGoods(ctx *jxcontext.Context, order *model.AfsOrder) (err error) { - return err -} - -// 发起全款退款 -func (c *PurchaseHandler) RefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) { - return fmt.Errorf("微商城不支持全款退款") -} - -// 发起部分退款 -func (c *PurchaseHandler) PartRefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, refundSkuList []*model.OrderSku, reason string) (err error) { - return fmt.Errorf("微商城不支持部分退款") -} diff --git a/business/partner/purchase/weimob/wsc/order_comment.go b/business/partner/purchase/weimob/wsc/order_comment.go deleted file mode 100644 index 6dce36b84..000000000 --- a/business/partner/purchase/weimob/wsc/order_comment.go +++ /dev/null @@ -1,10 +0,0 @@ -package wsc - -import ( - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" -) - -func (c *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, vendorOrgCode string, orderComment *model.OrderComment, replyComment string) (err error) { - return err -} diff --git a/business/partner/purchase/weimob/wsc/store.go b/business/partner/purchase/weimob/wsc/store.go deleted file mode 100644 index 28bf44197..000000000 --- a/business/partner/purchase/weimob/wsc/store.go +++ /dev/null @@ -1,25 +0,0 @@ -package wsc - -import ( - "errors" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model/dao" -) - -func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string) (*dao.StoreDetail, error) { - return nil, errors.New("微盟微商城还没实现") -} - -func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName string) error { - return nil -} - -func (p *PurchaseHandler) RefreshAllStoresID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) { - return hint, err -} - -func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (storeStatus int, err error) { - return 0, err -} diff --git a/business/partner/purchase/weimob/wsc/store_sku2.go b/business/partner/purchase/weimob/wsc/store_sku2.go deleted file mode 100644 index 8c5bf18d2..000000000 --- a/business/partner/purchase/weimob/wsc/store_sku2.go +++ /dev/null @@ -1,203 +0,0 @@ -package wsc - -import ( - "fmt" - "math/rand" - - "git.rosy.net.cn/baseapi/platformapi/weimobapi" - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -const ( - DefFreightTemplateId = 6537248 - DefDeliveryTypeId = 177445 - DefVendorCategoryId = 35 - DefCatImg = "https://image-c.weimobwmc.com/openruntime/249b77ced5da4736a56641ebcf4875ec.png" -) - -// 门店分类 -func (p *PurchaseHandler) GetStoreAllCategories(ctx *jxcontext.Context, vendorStoreID string) (cats []*partner.BareCategoryInfo, err error) { - remoteCats, err := api.WeimobAPI.QueryClassifyInfoList() - if err == nil { - cats = convertVendorCatList(remoteCats) - } - return cats, err -} - -func convertVendorCatList(remoteCats []*weimobapi.GoodsClassify) (cats []*partner.BareCategoryInfo) { - for _, rCat := range remoteCats { - cat := &partner.BareCategoryInfo{ - VendorCatID: utils.Int64ToStr(rCat.ClassifyID), - Name: rCat.Title, - Level: rCat.Level, - Seq: 0, - Children: convertVendorCatList(rCat.ChildrenClassify), - } - cats = append(cats, cat) - } - return cats -} - -func (p *PurchaseHandler) CreateStoreCategory(ctx *jxcontext.Context, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) { - var vendorCatID int64 - if globals.EnableWscStoreWrite { - vendorCatID, err = api.WeimobAPI.AddClassify(storeCat.Name, utils.Str2Int64WithDefault(storeCat.ParentVendorCatID, 0), "") - } else { - vendorCatID = jxutils.GenFakeID() - } - storeCat.VendorCatID = utils.Int64ToStr(vendorCatID) - return err -} - -func (p *PurchaseHandler) UpdateStoreCategory(ctx *jxcontext.Context, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) { - if globals.EnableWscStoreWrite { - err = api.WeimobAPI.UpdateClassify(utils.Str2Int64WithDefault(storeCat.VendorCatID, 0), storeCat.Name, "") - } - return err -} - -func (p *PurchaseHandler) DeleteStoreCategory(ctx *jxcontext.Context, vendorStoreID, vendorCatID string, level int) (err error) { - if globals.EnableWscStoreWrite { - err = api.WeimobAPI.UpdateClassify(utils.Str2Int64WithDefault(vendorCatID, 0), composeFakeDelName(vendorCatID), "") - } - return err -} - -// 门店商品 - -// 多门店平台不需要实现这个接口 -func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (err error) { - storeSku := storeSkuList[0] - goodsInfo := genSkuParams(storeSku) - if globals.EnableWscStoreWrite { - _, _, err = api.WeimobAPI.UpdateGoods2(goodsInfo) - } - return err -} - -// 通用 - -func (p *PurchaseHandler) GetStoreSkusBatchSize(funcID int) int { - return 1 -} - -func genSkuParams(storeSku *dao.StoreSkuSyncInfo) (goodsInfo *weimobapi.PendingSaveGoodsVo) { - outerGoodsCode := utils.Int2Str(storeSku.NameID) - isPutAway := storeSku.StoreSkuStatus == model.SkuStatusNormal - categoryId := storeSku.VendorVendorCatID - if categoryId == 0 { - categoryId = DefVendorCategoryId - } - classifyIdList := []int64{utils.Str2Int64WithDefault(storeSku.VendorCatID, 0)} - if storeSku.SkuVendorCatID != "" { - if int64Value := utils.Str2Int64WithDefault(storeSku.SkuVendorCatID, 0); int64Value > 0 { - classifyIdList = append(classifyIdList, int64Value) - } - } - b2cGoods := []*weimobapi.PendingSaveB2CGoodsVo{ - &weimobapi.PendingSaveB2CGoodsVo{ - FreightTemplateId: DefFreightTemplateId, - DeliveryTypeIdList: []int64{DefDeliveryTypeId}, - B2cGoodsType: weimobapi.GoodsTypeNormal, - }, - } - salePrice := int64(storeSku.Price) - goodsInfo = &weimobapi.PendingSaveGoodsVo{ - Title: storeSku.Name, - OuterGoodsCode: outerGoodsCode, - IsMultiSku: 0, - GoodsImageURL: []string{storeSku.Img}, - InitialSales: 0, - IsPutAway: utils.Bool2Int(!isPutAway), - Sort: int(storeSku.Price), - CategoryID: categoryId, - B2cGoods: b2cGoods, - SkuList: []*weimobapi.PendingSaveSkuVo{ - &weimobapi.PendingSaveSkuVo{ - OuterSkuCode: utils.Int2Str(storeSku.SkuID), - ImageURL: storeSku.Img, - SalePrice: jxutils.IntPrice2Standard(salePrice), - CostPrice: jxutils.IntPrice2Standard(salePrice * 8 / 10), - OriginalPrice: jxutils.IntPrice2Standard(salePrice * 10 / (6 + rand.Int63n(4))), - EditStockNum: 0, - B2cSku: &weimobapi.PendingSaveB2CSkuVo{ - Weight: jxutils.IntWeight2Float(storeSku.Weight), - }, - }, - }, - } - return goodsInfo -} - -// 对于多门店平台来说,storeSkuList中只有SkuID与VendorSkuID有意义 -func (p *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (err error) { - storeSku := storeSkuList[0] - goodsInfo := genSkuParams(storeSku) - var goodsID, vendorSkuID int64 - if globals.EnableWscStoreWrite { - var skuMap map[string]int64 - if goodsID, skuMap, err = api.WeimobAPI.AddGoods2(goodsInfo); err == nil { - vendorSkuID = skuMap[utils.Int2Str(storeSku.SkuID)] - } - } else { - goodsID = jxutils.GenFakeID() - vendorSkuID = jxutils.GenFakeID() - } - storeSku.VendorSkuID = utils.Int64ToStr(vendorSkuID) - storeSku.VendorNameID = utils.Int64ToStr(goodsID) - return err -} - -func (p *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (err error) { - storeSku := storeSkuList[0] - goodsID := utils.Str2Int64(storeSku.VendorNameID) - if globals.EnableWscStoreWrite { - if err = api.WeimobAPI.UpdateGoodsShelfStatus([]int64{goodsID}, false); err == nil { - err = api.WeimobAPI.UpdateGoodsTitle(goodsID, composeFakeDelName(storeSku.VendorNameID)) - } else if intErr, ok := err.(*utils.ErrorWithCode); ok && intErr.Code() == "1001930300001" { // 商品不存在错 - err = nil // 强制忽略 - } - } - return err -} - -func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (err error) { - var validGoodsIDList, invalidGoodsIDList []int64 - for _, storeSku := range storeSkuList { - if storeSku.Status == model.SkuStatusNormal { - validGoodsIDList = append(validGoodsIDList, utils.Str2Int64(storeSku.VendorSkuID)) - } else { - invalidGoodsIDList = append(invalidGoodsIDList, utils.Str2Int64(storeSku.VendorSkuID)) - } - } - if globals.EnableWscStoreWrite { - if len(validGoodsIDList) > 0 { - err = api.WeimobAPI.UpdateGoodsShelfStatus(validGoodsIDList, true) - } - if err == nil && len(invalidGoodsIDList) > 0 { - err = api.WeimobAPI.UpdateGoodsShelfStatus(invalidGoodsIDList, false) - } - } - return err -} - -func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (err error) { - err = fmt.Errorf("内部错误,微商城不支持UpdateStoreSkusPrice!") - return err -} - -func (p *PurchaseHandler) GetStoreSkusInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, inStoreSkuList []*partner.StoreSkuInfo) (outStoreSkuList []*partner.StoreSkuInfo, err error) { - return outStoreSkuList, err -} - -func composeFakeDelName(name string) string { - return "del_" + name -} diff --git a/business/partner/purchase/weimob/wsc/store_sku_test.go b/business/partner/purchase/weimob/wsc/store_sku_test.go deleted file mode 100644 index b31c557c2..000000000 --- a/business/partner/purchase/weimob/wsc/store_sku_test.go +++ /dev/null @@ -1,25 +0,0 @@ -package wsc - -// func TestSyncLocalStoreCategory(t *testing.T) { -// hint, err := new(PurchaseHandler).SyncLocalStoreCategory(jxcontext.AdminCtx, nil, 100077, false) -// if err != nil { -// t.Fatal(err) -// } -// t.Log(hint) -// } - -// func TestSyncStoreCategory(t *testing.T) { -// hint, err := new(PurchaseHandler).SyncStoreCategory(jxcontext.AdminCtx, nil, 100077, false) -// if err != nil { -// t.Fatal(err) -// } -// t.Log(hint) -// } - -// func TestSyncStoreSkus(t *testing.T) { -// hint, err := new(PurchaseHandler).SyncStoreSkus(jxcontext.AdminCtx, nil, 100077, nil, false, true) -// if err != nil { -// t.Fatal(err) -// } -// t.Log(hint) -// } diff --git a/business/partner/purchase/weimob/wsc/wsc.go b/business/partner/purchase/weimob/wsc/wsc.go deleted file mode 100644 index 457b53a5b..000000000 --- a/business/partner/purchase/weimob/wsc/wsc.go +++ /dev/null @@ -1,76 +0,0 @@ -package wsc - -import ( - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -// 对于微盟来说,只有一个展示商品的商家,但有多个拣货的商家 -// 订单中的 -// VendorStoreID表示在微盟上的商家编码 -// JxStoreID表示的是展示商品的商家 -// StoreID才是实际派单的商家 - -var ( - curPurchaseHandler *PurchaseHandler -) - -type PurchaseHandler struct { - partner.BasePurchasePlatform -} - -func init() { - if api.WeimobAPI != nil { - curPurchaseHandler = new(PurchaseHandler) - // partner.RegisterPurchasePlatform(curPurchaseHandler) - } -} - -func (c *PurchaseHandler) GetVendorID() int { - return model.VendorIDWSC -} - -func (p *PurchaseHandler) GetVendorCategories(ctx *jxcontext.Context) (vendorCats []*model.SkuVendorCategory, err error) { - rootCats, err := api.WeimobAPI.QueryCategoryTree() - catList := rootCats - if err != nil { - return nil, err - } - for _, v := range rootCats { - cats, err := api.WeimobAPI.QueryChildrenCategory(v.CategoryID) - if err != nil { - return nil, err - } - catList = append(catList, cats...) - } - vendorCats = make([]*model.SkuVendorCategory, len(catList)) - for k, v := range catList { - vendorCats[k] = &model.SkuVendorCategory{ - VendorCategoryID: vendorCategoryID2String(v.CategoryID), - VendorID: model.VendorIDWSC, - Name: v.Title, - IsLeaf: int8(v.Level - 1), - Level: v.Level, - ParentID: vendorCategoryID2String(v.ParentID), - } - } - return vendorCats, nil -} - -func vendorCategoryID2String(catID int64) string { - if catID > 0 { - return utils.Int64ToStr(catID) - } - return "" -} - -func (p *PurchaseHandler) UploadImg(ctx *jxcontext.Context, vendorOrgCode, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) { - if globals.EnableWscStoreWrite { - imgHint, err = api.WeimobAPI.UploadImg(imgData, imgName) - } - return imgHint, err -} diff --git a/business/partner/purchase/weimob/wsc/wsc_test.go b/business/partner/purchase/weimob/wsc/wsc_test.go deleted file mode 100644 index c14454fee..000000000 --- a/business/partner/purchase/weimob/wsc/wsc_test.go +++ /dev/null @@ -1,29 +0,0 @@ -package wsc - -import ( - "testing" - - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils/tasks" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/testinit" -) - -func init() { - testinit.Init() - - if err := tasks.RefreshWeimobToken(); err != nil { - globals.SugarLogger.Errorf("RefreshWeimobToken failed with error:%s", err) - return - } -} - -func TestGetVendorCategories(t *testing.T) { - vendorCatList, err := new(PurchaseHandler).GetVendorCategories(jxcontext.AdminCtx) - if err != nil { - t.Fatal(err.Error()) - } - globals.SugarLogger.Debug(utils.Format4Output(vendorCatList, false)) -} diff --git a/business/partner/purchase/yb/act.go b/business/partner/purchase/yb/act.go deleted file mode 100644 index 4434fa15a..000000000 --- a/business/partner/purchase/yb/act.go +++ /dev/null @@ -1,11 +0,0 @@ -package yb - -import ( - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" -) - -func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSkuList []*model.ActStoreSku2) (err error) { - return err -} diff --git a/business/partner/purchase/yb/order.go b/business/partner/purchase/yb/order.go deleted file mode 100644 index f8cace49e..000000000 --- a/business/partner/purchase/yb/order.go +++ /dev/null @@ -1,76 +0,0 @@ -package yb - -import ( - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" -) - -func (p *PurchaseHandler) AcceptOrRefuseFailedGetOrder(ctx *jxcontext.Context, order *model.GoodsOrder, isAcceptIt bool) (err error) { - return err -} - -func (p *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) { - return order -} -func (p *PurchaseHandler) GetOrder(vendorOrgCode, vendorOrderID string) (order *model.GoodsOrder, err error) { - return order, err -} -func (p *PurchaseHandler) GetOrderStatus(vendorOrgCode, vendorOrderID string) (status int, err error) { - return status, err -} - -func (p *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) { - return err -} -func (p *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) { - return err -} - -func (p *PurchaseHandler) CallCourier(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { - return err -} // 取货失败后再次招唤平台配送 -func (p *PurchaseHandler) ConfirmReceiveGoods(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { - return err -} // 投递失败后确认收到退货 -func (p *PurchaseHandler) CanSwitch2SelfDeliver(order *model.GoodsOrder) (isCan bool, err error) { - return isCan, err -} -func (p *PurchaseHandler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) { - return err -} -func (p *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName string) (err error) { - return err -} -func (p *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) { - return err -} -func (p *PurchaseHandler) SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) { - return err -} -func (p *PurchaseHandler) GetOrderRealMobile(ctx *jxcontext.Context, order *model.GoodsOrder) (mobile string, err error) { - return mobile, err -} -func (p *PurchaseHandler) ReplyOrderComment(ctx *jxcontext.Context, vendorOrgCode string, orderComment *model.OrderComment, replyComment string) (err error) { - return err -} -func (p *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) { - return err -} -func (p *PurchaseHandler) CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) { - return err -} -func (p *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) { - return err -} -func (p *PurchaseHandler) RefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) { - return err -} -func (p *PurchaseHandler) PartRefundOrder(ctx *jxcontext.Context, order *model.GoodsOrder, refundSkuList []*model.OrderSku, reason string) (err error) { - return err -} -func (p *PurchaseHandler) AgreeOrRefuseRefund(ctx *jxcontext.Context, order *model.AfsOrder, approveType int, reason string) (err error) { - return err -} -func (p *PurchaseHandler) ConfirmReceivedReturnGoods(ctx *jxcontext.Context, order *model.AfsOrder) (err error) { - return err -} diff --git a/business/partner/purchase/yb/order_comment.go b/business/partner/purchase/yb/order_comment.go deleted file mode 100644 index 7206382e9..000000000 --- a/business/partner/purchase/yb/order_comment.go +++ /dev/null @@ -1,5 +0,0 @@ -package yb - -func (c *PurchaseHandler) StartRefreshComment() { - -} diff --git a/business/partner/purchase/yb/store.go b/business/partner/purchase/yb/store.go deleted file mode 100644 index af4aa04a2..000000000 --- a/business/partner/purchase/yb/store.go +++ /dev/null @@ -1,52 +0,0 @@ -package yb - -import ( - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model/dao" -) - -func (p *PurchaseHandler) ReadStore(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string) (storeDetail *dao.StoreDetail, err error) { - return storeDetail, err -} - -// stoerIDs为nil表示所有 -func (p *PurchaseHandler) UpdateStore(db *dao.DaoDB, storeID int, userName string) (err error) { - return err -} - -func (p *PurchaseHandler) CreateStore2(db *dao.DaoDB, storeID int, userName string) (vendorStoreID string, err error) { - return vendorStoreID, err -} - -func (p *PurchaseHandler) DeleteStore(db *dao.DaoDB, storeID int, userName string) (err error) { - return err -} - -func (p *PurchaseHandler) RefreshAllStoresID(ctx *jxcontext.Context, parentTask tasksch.ITask, isAsync bool) (hint string, err error) { - return hint, err -} - -func (p *PurchaseHandler) GetStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string) (storeStatus int, err error) { - return storeStatus, err -} - -func (p *PurchaseHandler) EnableAutoAcceptOrder(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, isSetEnable bool) (err error) { - return err -} - -func (c *PurchaseHandler) UpdateStoreStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, status int) (err error) { - return err -} - -func (c *PurchaseHandler) UpdateStoreOpTime(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, opTimeList []int16) (err error) { - return err -} - -func (c *PurchaseHandler) GetAllStoresVendorID(ctx *jxcontext.Context, vendorOrgCode string) (vendorStoreIDs []string, err error) { - return vendorStoreIDs, err -} - -func (c *PurchaseHandler) UpdateStoreCustomID(ctx *jxcontext.Context, vendorOrgCode, vendorStoreID string, storeID int64) (err error) { - return err -} diff --git a/business/partner/purchase/yb/store_sku.go b/business/partner/purchase/yb/store_sku.go deleted file mode 100644 index 695970895..000000000 --- a/business/partner/purchase/yb/store_sku.go +++ /dev/null @@ -1,602 +0,0 @@ -package yb - -import ( - "fmt" - "regexp" - "strings" - - "git.rosy.net.cn/baseapi/platformapi/yinbaoapi" - "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/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/business/partner/putils" - "git.rosy.net.cn/jx-callback/globals" - "git.rosy.net.cn/jx-callback/globals/api" -) - -var ( - sensitiveWordRegexp = regexp.MustCompile(`商品名称中含有敏感词(\[.*\])`) -) - -const ( - addErr1 = "商品已存在" -) - -func (p *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - if globals.EnableYbStoreWrite { - storeSku := storeSkuList[0] - var result *yinbaoapi.AddProductInfoResult - flag, err2 := checkYbSku(storeSku) //flag为true表示是标品,标品不用更新称编码 - if err2 != nil { - err = err2 - } else { - result, err = api.YinBaoAPI.AddProductInfo(buildProductInfoParam(storeSku)) - } - if err != nil { - if errExt, ok := err.(*utils.ErrorWithCode); ok { - if strings.Contains(errExt.ErrMsg(), addErr1) { - queryProductByBarcodeResult, _ := api.YinBaoAPI.QueryProductByBarcodes([]string{storeSku.YbBarCode}) - if len(queryProductByBarcodeResult) > 0 { - api.YinBaoAPI.BatchUpdateProductEnable(vendorStoreID, utils.Int64ToStr(queryProductByBarcodeResult[0].UID), model.SkuStatusNormal) - storeSku.VendorSkuID = utils.Int64ToStr(queryProductByBarcodeResult[0].UID) - } - } else { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDYB], "创建商品") - } - } else { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDYB], "创建商品") - } - } else { - storeSku.VendorSkuID = utils.Int64ToStr(result.UID) - err = uploadYbImage(vendorStoreID, storeSku.YbBarCode, storeSku.Img) - if !flag { - err = updateYbSku(vendorStoreID, storeSku.YbBarCode, nil) - } - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDYB], "创建商品") - } - } - } - return failedList, err -} - -func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - if globals.EnableYbStoreWrite { - for _, v := range storeSkuList { - saveProductParam := &yinbaoapi.SaveProductParam{ - CategoryUid: v.VendorCatID, - } - _, err = checkYbSku(v) - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDYB], "修改商品") - return failedList, err - } - err = updateYbImage(vendorStoreID, v) - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDYB], "修改商品") - return failedList, err - } - err = updateYbSku(vendorStoreID, v.YbBarCode, saveProductParam) - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDYB], "修改商品") - } - } - } - return failedList, err -} - -func (p *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - if globals.EnableYbStoreWrite { - for _, v := range storeSkuList { - var productInfo = &yinbaoapi.ProductInfo{ - UID: utils.Str2Int64(v.VendorSkuID), - Enable: utils.Int2Pointer(yinbaoapi.SkuStatusDeleted), - } - err = api.YinBaoAPI.UpdateProductInfo(productInfo) - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDYB], "删除商品") - } - } - } - return failedList, err -} - -func (p *PurchaseHandler) GetStoreSkusFullInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (skuNameList []*partner.SkuNameInfo, err error) { - storeDetail, _ := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDYB) - api.YinBaoAPI = yinbaoapi.New(storeDetail.YbAppKey, storeDetail.YbAppID) - if configs, err := dao.QueryConfigs(dao.GetDB(), "yinbaoCookie", model.ConfigTypeCookie, ""); err == nil { - yinbaoCookie := configs[0].Value - api.YinBaoAPI.SetCookie(".POSPALAUTH30220", yinbaoCookie) - } - if storeSkuList != nil { - if len(storeSkuList) == 1 { - storeSku := storeSkuList[0] - result, err := api.YinBaoAPI.QueryProductByBarcode(storeSku.VendorSkuID) - if err != nil || result == nil { - return nil, err - } - resultp, err := api.YinBaoAPI.QueryProductImagesByBarcode(result.Barcode) - // resultp, err := getProductImages(vendorStoreID, storeSku.VendorSkuID) - if err != nil { - return nil, err - } - if skuName := vendorSku2Jx(result, resultp); skuName != nil { - skuNameList = append(skuNameList, skuName) - } - } else { - var barcodes []string - for _, v := range storeSkuList { - barcodes = append(barcodes, v.VendorSkuID) - } - results, err := api.YinBaoAPI.QueryProductByBarcodes(barcodes) - if err != nil { - return nil, err - } - for _, v := range results { - resultp, err := api.YinBaoAPI.QueryProductImagesByBarcode(v.Barcode) - // resultp, err := getProductImages(vendorStoreID, v.Barcode) - if err != nil { - return nil, err - } - if skuName := vendorSku2Jx(v, resultp); skuName != nil { - skuNameList = append(skuNameList, skuName) - } - } - } - } else { - result, err := api.YinBaoAPI.QueryProductPages(nil) - if err != nil { - return nil, err - } - if len(result.Result) < result.PageSize { - for _, v := range result.Result { - resultp, err := api.YinBaoAPI.QueryProductImagesByBarcode(v.Barcode) - // resultp, err := getProductImages(vendorStoreID, v.Barcode) - if err != nil { - return nil, err - } - vv := &yinbaoapi.QueryProductByBarcodeResult{} - err = utils.Map2StructByJson(utils.Struct2MapByJson(v), vv, false) - if skuName := vendorSku2Jx(vv, resultp); skuName != nil { - skuNameList = append(skuNameList, skuName) - } - } - } else { - for _, v := range result.Result { - resultp, err := api.YinBaoAPI.QueryProductImagesByBarcode(v.Barcode) - // resultp, err := getProductImages(vendorStoreID, v.Barcode) - if err != nil { - return nil, err - } - vv := &yinbaoapi.QueryProductByBarcodeResult{} - err = utils.Map2StructByJson(utils.Struct2MapByJson(v), vv, false) - if skuName := vendorSku2Jx(vv, resultp); skuName != nil { - skuNameList = append(skuNameList, skuName) - } - } - loopPages(result.PostBackParameter.ParameterType, result.PostBackParameter.ParameterValue, &skuNameList, vendorStoreID) - } - } - return skuNameList, err -} - -func getProductImages(vendorStoreID, barCode string) (findProductResult *yinbaoapi.FindProductResult, err error) { - for { - ybSkuID, err := api.YinBaoAPI.LoadProductsByPage(vendorStoreID, barCode) - findProductResult, err = api.YinBaoAPI.FindProduct(ybSkuID) - if err == nil { - break - } else { - if yinbaoapi.IsErrCookie(err) { - err = cms.ChangeYbCookie() - if err != nil { - break - } - findProductResult, err = getProductImages(vendorStoreID, barCode) - } else { - break - } - } - } - return findProductResult, err -} - -func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (failedList []*partner.StoreSkuInfoWithErr, err error) { - if globals.EnableYbStoreWrite { - for _, v := range storeSkuList { - var productInfo = &yinbaoapi.ProductInfo{ - UID: utils.Str2Int64(v.VendorSkuID), - Enable: utils.Int2Pointer(ybSkuStatus2Jx(v.Status)), - } - err = api.YinBaoAPI.UpdateProductInfo(productInfo) - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDYB], "更新商品状态") - } - } - } - return failedList, err -} - -func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - if globals.EnableYbStoreWrite { - for _, v := range storeSkuList { - var productInfo = &yinbaoapi.ProductInfo{ - UID: utils.Str2Int64(v.VendorSkuID), - SellPrice: utils.Float64ToPointer(jxutils.IntPrice2Standard(v.VendorPrice)), - BuyPrice: utils.Float64ToPointer(jxutils.IntPrice2Standard(v.JxPrice)), - } - err = api.YinBaoAPI.UpdateProductInfo(productInfo) - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDYB], "更新商品价格") - } - } - } - return failedList, err -} - -func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) { - if globals.EnableYbStoreWrite { - for _, v := range storeSkuList { - var productInfo = &yinbaoapi.ProductInfo{ - UID: utils.Str2Int64(v.VendorSkuID), - Stock: utils.Float64ToPointer(utils.Str2Float64(utils.Int2Str(v.Stock))), - } - err = api.YinBaoAPI.UpdateProductInfo(productInfo) - if err != nil { - failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDYB], "更新商品库存") - } - } - } - return failedList, err -} - -func (p *PurchaseHandler) GetStoreAllCategories(ctx *jxcontext.Context, storeID int, vendorStoreID string) (cats []*partner.BareCategoryInfo, err error) { - remoteCats, err := loadCategorysWithOption(vendorStoreID) - cats = convertVendorCatList(remoteCats) - return cats, err -} - -func loadCategorysWithOption(vendorStoreID string) (remoteCats []*yinbaoapi.LoadCategorysWithOptionResult, err error) { - for { - remoteCats, err = api.YinBaoAPI.LoadCategorysWithOption(vendorStoreID) - if err == nil { - break - } else { - if yinbaoapi.IsErrCookie(err) { - err = cms.ChangeYbCookie() - if err != nil { - break - } - remoteCats, err = loadCategorysWithOption(vendorStoreID) - } else { - break - } - } - } - return remoteCats, err -} - -func (p *PurchaseHandler) CreateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) { - if globals.EnableYbStoreWrite { - var ( - catName = utils.FilterEmoji(storeCat.Name) - parentCatName = utils.FilterEmoji(storeCat.ParentCatName) - ) - vendorCatID, err := addNewCategory(vendorStoreID, catName, parentCatName) - if err == nil { - storeCat.VendorCatID = vendorCatID - } - return err - } - return err -} - -func addNewCategory(vendorStoreID, catName, parentCatName string) (vendorCatID string, err error) { - for { - vendorCatID, err = api.YinBaoAPI.AddNewCategory(vendorStoreID, catName, parentCatName) - if err == nil { - break - } else { - if yinbaoapi.IsErrCookie(err) { - err = cms.ChangeYbCookie() - if err != nil { - break - } - vendorCatID, err = addNewCategory(vendorStoreID, catName, parentCatName) - } else { - break - } - } - } - return vendorCatID, err -} - -func (p *PurchaseHandler) UpdateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) { - if globals.EnableYbStoreWrite { - var ( - catName = utils.FilterEmoji(storeCat.Name) - parentCatName = utils.FilterEmoji(storeCat.ParentCatName) - ) - err = updateCategory(vendorStoreID, storeCat.VendorCatID, catName, parentCatName) - } - return err -} - -func updateCategory(vendorStoreID, vendorCatID, catName, parentCatName string) (err error) { - for { - err = api.YinBaoAPI.UpdateCategory(vendorStoreID, vendorCatID, catName, parentCatName) - if err == nil { - break - } else { - if yinbaoapi.IsErrCookie(err) { - err = cms.ChangeYbCookie() - if err != nil { - break - } - err = updateCategory(vendorStoreID, vendorCatID, catName, parentCatName) - } else { - break - } - } - } - return err -} - -func (p *PurchaseHandler) DeleteStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID, vendorCatID string, level int) (err error) { - if globals.EnableYbStoreWrite { - err = deleteCategory(vendorStoreID, []string{vendorCatID}) - } - return err -} - -func deleteCategory(vendorStoreID string, vendorCatIDs []string) (err error) { - for { - err = api.YinBaoAPI.DeleteCategory(vendorStoreID, vendorCatIDs) - if err == nil { - break - } else { - if yinbaoapi.IsErrCookie(err) { - err = cms.ChangeYbCookie() - if err != nil { - break - } - err = api.YinBaoAPI.DeleteCategory(vendorStoreID, vendorCatIDs) - } else { - break - } - } - } - return err -} - -func (p *PurchaseHandler) IsErrSkuExist(err error) (isExist bool) { - return yinbaoapi.IsErrSkuExist(err) -} - -func (p *PurchaseHandler) IsErrCategoryExist(err error) (isExist bool) { - return yinbaoapi.IsErrCategoryExist(err) -} - -func (p *PurchaseHandler) IsErrCategoryNotExist(err error) (isNotExist bool) { - return false -} - -func (p *PurchaseHandler) GetStoreSkusBatchSize(funcID int) (batchSize int) { - return 1 -} - -func (p *PurchaseHandler) GetSensitiveWordRegexp() *regexp.Regexp { - return sensitiveWordRegexp -} - -func (p *PurchaseHandler) IsErrSkuNotExist(err error) (isNotExist bool) { - return yinbaoapi.IsErrSkuNotExist(err) -} - -func ybSkuStatus2Jx(ybStatus int) (jxSkuStatus int) { - if ybStatus == yinbaoapi.SkuStatusEnable { - jxSkuStatus = model.SkuStatusNormal - } else if ybStatus == yinbaoapi.SkuStatusDisabled { - jxSkuStatus = model.SkuStatusDontSale - } else if ybStatus == yinbaoapi.SkuStatusDeleted { - jxSkuStatus = model.SkuStatusDeleted - } - return jxSkuStatus -} - -func vendorSku2Jx(result *yinbaoapi.QueryProductByBarcodeResult, resultp []*yinbaoapi.QueryProductImagesByBarcodeResult) (skuName *partner.SkuNameInfo) { - var picList []string - if result == nil { - globals.SugarLogger.Warnf("vendorSku2Jx, strange result:%s", utils.Format4Output(result, true)) - return nil - } - if len(resultp) > 0 { - if resultp[0].ImageURL != "" { - // for _, v := range resultp.Productimages { - picList = append(picList, resultp[0].ImageURL) - // } - } - } - prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(result.Name) - skuName = &partner.SkuNameInfo{ - Prefix: prefix, - Name: name, - Unit: unit, - YbBarCode: result.Barcode, - SkuList: []*partner.SkuInfo{ - &partner.SkuInfo{ - StoreSkuInfo: partner.StoreSkuInfo{ - VendorSkuID: utils.Int64ToStr(result.UID), - Stock: int(utils.Float64TwoInt64(result.Stock)), - VendorPrice: jxutils.StandardPrice2Int(result.SellPrice), - Status: ybSkuStatus2Jx(result.Enable), - }, - SkuName: result.Name, - Comment: comment, - SpecQuality: float64(specQuality), - SpecUnit: specUnit, - Weight: int(utils.Float64TwoInt64(float64(specQuality))), - }, - }, - PictureList: picList, - } - return skuName -} - -func loopPages(parameterType, parameterValue string, skuNameList *[]*partner.SkuNameInfo, vendorStoreID string) (err error) { - var postBackParameter = &yinbaoapi.PostBackParameter{ - ParameterType: parameterType, - ParameterValue: parameterValue, - } - resultPages, err := api.YinBaoAPI.QueryProductPages(postBackParameter) - if err != nil { - return err - } - for _, v := range resultPages.Result { - // resultp, err := api.YinBaoAPI.QueryProductImagesByBarcode(v.Barcode) - // resultp, err := getProductImages(vendorStoreID, v.Barcode) - if err != nil { - return err - } - var resultp []*yinbaoapi.QueryProductImagesByBarcodeResult - vv := &yinbaoapi.QueryProductByBarcodeResult{} - err = utils.Map2StructByJson(utils.Struct2MapByJson(v), vv, false) - if skuName := vendorSku2Jx(vv, resultp); skuName != nil { - *skuNameList = append(*skuNameList, skuName) - } - } - if len(resultPages.Result) >= resultPages.PageSize { - err = loopPages(resultPages.PostBackParameter.ParameterType, resultPages.PostBackParameter.ParameterValue, skuNameList, vendorStoreID) - } - return err -} - -func buildProductInfoParam(storeSku *dao.StoreSkuSyncInfo) (productInfoParam *yinbaoapi.ProductInfoParam) { - var ( - buyPrice float64 = utils.Str2Float64(utils.Int64ToStr(storeSku.Price)) / 100 - sellPrice float64 = utils.Str2Float64(utils.Int64ToStr(storeSku.VendorPrice)) / 100 - // _, name, _, _, _, _ = jxutils.SplitSkuName() - ) - productInfoParam = &yinbaoapi.ProductInfoParam{} - productInfo := &yinbaoapi.ProductInfo{ - Stock: utils.Float64ToPointer(utils.Str2Float64(utils.Int2Str(model.MaxStoreSkuStockQty))), - Name: storeSku.Name, - Barcode: storeSku.YbBarCode, - BuyPrice: &buyPrice, - SellPrice: &sellPrice, - CategoryUID: utils.Str2Int64(storeSku.VendorCatID), - } - productInfoParam.ProductInfo = productInfo - return productInfoParam -} - -func convertVendorCatList(remoteCats []*yinbaoapi.LoadCategorysWithOptionResult) (cats []*partner.BareCategoryInfo) { - for _, rCat := range remoteCats { - cat := &partner.BareCategoryInfo{ - VendorCatID: rCat.TxtUID, - Name: rCat.Name, - } - if rCat.TxtParentUID == "" { - cat.Level = 1 - } else { - cat.Level = 2 - } - cats = append(cats, cat) - } - return cats -} - -func updateYbSku(vendorStoreID, ybBarCode string, saveProductParam *yinbaoapi.SaveProductParam) (err error) { - for { - err = api.YinBaoAPI.SaveProduct(vendorStoreID, ybBarCode, saveProductParam) - if err == nil { - break - } else { - if yinbaoapi.IsErrCookie(err) { - err = cms.ChangeYbCookie() - if err != nil { - break - } - err = updateYbSku(vendorStoreID, ybBarCode, saveProductParam) - } else { - break - } - } - } - return err -} - -func checkYbSku(storeSku *dao.StoreSkuSyncInfo) (flag bool, err error) { - skuID := storeSku.SkuID - skus, _ := dao.GetSkus(dao.GetDB(), []int{skuID}, nil, nil, nil, nil) - if len(skus) > 0 { - if skus[0].Unit != model.UnitNames[0] { - flag = true - if skus[0].Upc == "" { - return flag, fmt.Errorf("标品必须指定upc码,skuID[%v]", skuID) - } else { - storeSku.YbBarCode = skus[0].Upc - } - } - } - return flag, err -} - -func uploadYbImage(vendorStoreID, ybBarCode, img string) (err error) { - ybSkuID, err := api.YinBaoAPI.LoadProductsByPage(vendorStoreID, ybBarCode) - resBinary, _, err := jxutils.DownloadFileByURL(img) - fileName := img[strings.LastIndex(img, "/")+1:] - err = uploadYbImageLoop(vendorStoreID, ybSkuID, resBinary, fileName) - return err -} - -func uploadYbImageLoop(vendorStoreID, ybSkuID string, resBinary []byte, fileName string) (err error) { - for { - err = api.YinBaoAPI.UploadProductImage(vendorStoreID, ybSkuID, resBinary, fileName) - if err == nil { - break - } else { - if yinbaoapi.IsErrCookie(err) { - err = cms.ChangeYbCookie() - if err != nil { - break - } - err = uploadYbImageLoop(vendorStoreID, ybSkuID, resBinary, fileName) - } else { - break - } - } - } - return err -} - -func updateYbImage(vendorStoreID string, v *dao.StoreSkuSyncInfo) (err error) { - err = uploadYbImage(vendorStoreID, v.YbBarCode, v.Img) - err = resetCoverImageLoop(vendorStoreID, v.YbBarCode) - return err -} - -func resetCoverImageLoop(vendorStoreID, ybBarCode string) (err error) { - for { - err = api.YinBaoAPI.ResetCoverImage(vendorStoreID, ybBarCode) - if err == nil { - break - } else { - if yinbaoapi.IsErrCookie(err) { - err = cms.ChangeYbCookie() - if err != nil { - break - } - err = resetCoverImageLoop(vendorStoreID, ybBarCode) - } else { - break - } - } - } - return err -} diff --git a/business/partner/purchase/yb/yb.go b/business/partner/purchase/yb/yb.go deleted file mode 100644 index 9c52f8b18..000000000 --- a/business/partner/purchase/yb/yb.go +++ /dev/null @@ -1,43 +0,0 @@ -package yb - -import ( - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/model" - "git.rosy.net.cn/jx-callback/business/partner" - "git.rosy.net.cn/jx-callback/business/partner/putils" - "git.rosy.net.cn/jx-callback/globals/api" -) - -var ( - CurPurchaseHandler *PurchaseHandler -) - -type PurchaseHandler struct { - partner.BasePurchasePlatform - putils.DefSingleStorePlatform -} - -func init() { - if api.YinBaoAPI != nil { - CurPurchaseHandler = New() - partner.RegisterPurchasePlatform(CurPurchaseHandler) - } -} - -func New() (obj *PurchaseHandler) { - obj = new(PurchaseHandler) - obj.ISingleStoreStoreSkuHandler = obj - return obj -} - -func (p *PurchaseHandler) GetVendorID() int { - return model.VendorIDYB -} - -func (p *PurchaseHandler) UploadImg(ctx *jxcontext.Context, vendorOrgCode, imgURL string, imgData []byte, imgName string, imgType int) (imgHint string, err error) { - return imgHint, err -} - -func (p *PurchaseHandler) GetVendorCategories(ctx *jxcontext.Context) (vendorCats []*model.SkuVendorCategory, err error) { - return vendorCats, err -} diff --git a/business/partner/putils/store_sku.go b/business/partner/putils/store_sku.go deleted file mode 100644 index c1405762a..000000000 --- a/business/partner/putils/store_sku.go +++ /dev/null @@ -1,403 +0,0 @@ -package putils - -import ( - "fmt" - "sort" - "time" - - "git.rosy.net.cn/jx-callback/business/jxutils" - "git.rosy.net.cn/jx-callback/business/model" - - "git.rosy.net.cn/baseapi/utils" - "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" - "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" - "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner" -) - -type DefSingleStorePlatform struct { - partner.ISingleStoreStoreSkuHandler -} - -func (p *DefSingleStorePlatform) DeleteStoreAllSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, isContinueWhenError bool) (err error) { - skuNameList, err := p.GetStoreSkusFullInfo(ctx, parentTask, storeID, vendorStoreID, nil) - if err != nil || len(skuNameList) == 0 { - return err - } - storeStoreList := make([]*partner.StoreSkuInfo, len(skuNameList)) - for k, v := range skuNameList { - storeStoreList[k] = &partner.StoreSkuInfo{ - SkuID: v.SkuList[0].SkuID, - VendorSkuID: v.SkuList[0].VendorSkuID, - } - } - _, err = FreeBatchStoreSkuInfo("删除门店商品", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) { - _, err = p.DeleteStoreSkus(ctx, storeID, vendorStoreID, batchedStoreSkuList) - return nil, 0, err - }, ctx, parentTask, storeStoreList, p.GetStoreSkusBatchSize(partner.FuncDeleteStoreSkus), isContinueWhenError) - return err -} - -func (p *DefSingleStorePlatform) DeleteStoreAllCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, isContinueWhenError bool) (err error) { - catList, err := p.GetStoreAllCategories(ctx, storeID, vendorStoreID) - if err != nil { - return err - } - catListMap := make(map[int][]*partner.BareCategoryInfo) - flattedCatList := flatCatList(catList) - for _, v := range flattedCatList { - catListMap[v.Level] = append(catListMap[v.Level], v) - } - var levelList []int - for k := range catListMap { - levelList = append(levelList, k) - } - sort.Sort(sort.Reverse(sort.IntSlice(levelList))) - task1 := tasksch.NewSeqTask2(fmt.Sprintf("DeleteStoreAllCategories1, vendorStoreID:%s", vendorStoreID), ctx, true, - func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { - vendorCatIDs := make([]string, len(catListMap[levelList[step]])) - for k, v := range catListMap[levelList[step]] { - vendorCatIDs[k] = v.VendorCatID - } - err = FreeBatchCategoryIDOp(func(vendorCatID string) (err error) { - err2 := p.DeleteStoreCategory(ctx, storeID, vendorStoreID, vendorCatID, step) - return err2 - }, ctx, task, vendorCatIDs, isContinueWhenError) - return nil, err - }, len(levelList)) - tasksch.HandleTask(task1, parentTask, true).Run() - _, err = task1.GetResult(0) - return err -} - -func flatCatList(catList []*partner.BareCategoryInfo) (flattedCatList []*partner.BareCategoryInfo) { - flattedCatList = append(flattedCatList, catList...) - for _, v := range catList { - flattedCatList = append(flattedCatList, flatCatList(v.Children)...) - } - return flattedCatList -} - -func (p *DefSingleStorePlatform) GetStoreSkusBareInfo(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, storeID int, vendorStoreID string, inStoreSkuList []*partner.StoreSkuInfo) (outStoreSkuList []*partner.StoreSkuInfo, err error) { - resultList, err := FreeBatchStoreSkuInfo("获取门店商品信息", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) { - result, err = p.GetStoreSkusFullInfo(ctx, parentTask, storeID, vendorStoreID, batchedStoreSkuList) - return result, successCount, err - }, ctx, parentTask, inStoreSkuList, p.GetStoreSkusBatchSize(partner.FuncGetStoreSkusFullInfo), true) - if err != nil || len(resultList) == 0 { - return nil, err - } - inStoreSkuMap := make(map[string]*partner.StoreSkuInfo) - for _, v := range inStoreSkuList { - if v.VendorSkuID != "" { - inStoreSkuMap[v.VendorNameID] = v - } - } - for _, v := range resultList { - skuName := v.(*partner.SkuNameInfo) - for _, v2 := range skuName.SkuList { - storeSkuBareInfo := &v2.StoreSkuInfo - if storeSkuBareInfo.SkuID == 0 && inStoreSkuMap[storeSkuBareInfo.VendorSkuID] != nil { - storeSkuBareInfo.SkuID = inStoreSkuMap[storeSkuBareInfo.VendorSkuID].SkuID - storeSkuBareInfo.NameID = inStoreSkuMap[storeSkuBareInfo.VendorSkuID].NameID - } - outStoreSkuList = append(outStoreSkuList, storeSkuBareInfo) - } - } - return outStoreSkuList, err -} - -func StoreSkuFullList2Bare(storeSkuFull []*partner.SkuNameInfo) (bareStoreSkuList []*partner.StoreSkuInfo) { - for _, v := range storeSkuFull { - for _, v2 := range v.SkuList { - bareStoreSkuList = append(bareStoreSkuList, &v2.StoreSkuInfo) - } - } - return bareStoreSkuList -} - -func findCategoryByName(catList []*partner.BareCategoryInfo, catName string) (cat *partner.BareCategoryInfo) { - catName2 := utils.FilterEmoji(catName) - for _, v := range catList { - if v.Name == catName || v.Name == catName2 { - cat = v - break - } - if cat = findCategoryByName(v.Children, catName); cat != nil { - break - } - } - return cat -} -func (p *DefSingleStorePlatform) GetStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID, catName string) (cat *partner.BareCategoryInfo, err error) { - catList, err := p.GetStoreAllCategories(ctx, storeID, vendorStoreID) - if err == nil { - if cat = findCategoryByName(catList, catName); cat == nil { - err = fmt.Errorf("门店:%d,%s不能找到商家分类:%s", storeID, vendorStoreID, catName) - } - } - return cat, err -} - -func FreeBatchStoreSkuInfo(name string, handler func(tasksch.ITask, []*partner.StoreSkuInfo) (interface{}, int, error), ctx *jxcontext.Context, parentTask tasksch.ITask, storeSkuList []*partner.StoreSkuInfo, batchSize int, isContinueWhenError bool) (resultList []interface{}, err error) { - if true { //len(storeSkuList) > batchSize { - task := tasksch.NewParallelTask2(fmt.Sprintf("FreeBatchStoreSkuInfo:%s", name), tasksch.NewParallelConfig().SetParallelCount(1).SetBatchSize(batchSize).SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, successCount int, err error) { - batchStoreSkuList := make([]*partner.StoreSkuInfo, len(batchItemList)) - for k, v := range batchItemList { - batchStoreSkuList[k] = v.(*partner.StoreSkuInfo) - } - retVal, successCount, err = handler(task, batchStoreSkuList) - if err != nil { - retVal = nil - } - return retVal, successCount, err - }, storeSkuList) - tasksch.HandleTask(task, parentTask, false).Run() - resultList, err = task.GetResult(0) - } else { - result, _, err2 := handler(parentTask, storeSkuList) - if err = err2; err == nil { - resultList = utils.Interface2Slice(result) - } - } - return resultList, err -} - -func FreeBatchStoreSkuSyncInfo(name string, handler func(tasksch.ITask, []*dao.StoreSkuSyncInfo) (interface{}, int, error), ctx *jxcontext.Context, parentTask tasksch.ITask, storeSkuList []*dao.StoreSkuSyncInfo, batchSize int, isContinueWhenError bool) (resultList []interface{}, err error) { - if true { //len(storeSkuList) > batchSize { - task := tasksch.NewParallelTask2(fmt.Sprintf("FreeBatchStoreSkuSyncInfo:%s", name), tasksch.NewParallelConfig().SetParallelCount(1).SetBatchSize(batchSize).SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, successCount int, err error) { - batchStoreSkuList := make([]*dao.StoreSkuSyncInfo, len(batchItemList)) - for k, v := range batchItemList { - batchStoreSkuList[k] = v.(*dao.StoreSkuSyncInfo) - } - retVal, successCount, err = handler(task, batchStoreSkuList) - if err != nil { - retVal = nil - } - return retVal, successCount, err - }, storeSkuList) - tasksch.HandleTask(task, parentTask, false).Run() - resultList, err = task.GetResult(0) - } else { - result, _, err2 := handler(parentTask, storeSkuList) - if err = err2; err == nil { - resultList = utils.Interface2Slice(result) - } - } - return resultList, err -} - -func FreeBatchCategoryIDOp(handler func(vendorCatID string) (err error), ctx *jxcontext.Context, parentTask tasksch.ITask, vendorCatIDs []string, isContinueWhenError bool) (err error) { - if len(vendorCatIDs) > 1 { - task := tasksch.NewParallelTask("FreeBatchCategoryIDOp", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx, - func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { - err = handler(batchItemList[0].(string)) - return nil, err - }, vendorCatIDs) - tasksch.HandleTask(task, parentTask, false).Run() - _, err = task.GetResult(0) - } else if len(vendorCatIDs) > 0 { - err = handler(vendorCatIDs[0]) - } - return err -} - -func StoreSkuList2MapByVendorSkuID(storeSkuList []*partner.StoreSkuInfo) (storeSkuMap map[string]*partner.StoreSkuInfo) { - storeSkuMap = make(map[string]*partner.StoreSkuInfo) - for _, v := range storeSkuList { - storeSkuMap[v.VendorSkuID] = v - } - return storeSkuMap -} - -func StoreSkuList2MapBySkuID(storeSkuList []*partner.StoreSkuInfo) (storeSkuMap map[int]*partner.StoreSkuInfo) { - storeSkuMap = make(map[int]*partner.StoreSkuInfo) - for _, v := range storeSkuList { - storeSkuMap[v.SkuID] = v - } - return storeSkuMap -} - -func StoreSkuList2IDs(storeSkuList []*partner.StoreSkuInfo) (ids []int) { - ids = make([]int, len(storeSkuList)) - for k, v := range storeSkuList { - ids[k] = v.SkuID - } - return ids -} - -func UnselectStoreSkuListByVendorSkuIDs(storeSkuList []*partner.StoreSkuInfo, vendorSkuIDs []string) (selectedStoreSkuList []*partner.StoreSkuInfo) { - if len(vendorSkuIDs) > 0 { - vendorSkuIDMap := jxutils.StringList2Map(vendorSkuIDs) - for _, v := range storeSkuList { - if vendorSkuIDMap[v.VendorSkuID] == 0 { - selectedStoreSkuList = append(selectedStoreSkuList, v) - } - } - } else { - selectedStoreSkuList = storeSkuList - } - return selectedStoreSkuList -} - -func GetErrMsg2FailedSingleList(storeSkuList interface{}, err error, storeID int, vendorName, syncType string) (failedList []*partner.StoreSkuInfoWithErr) { - if err != nil { - var errMsg string - if errExt, ok := err.(*utils.ErrorWithCode); ok { - errMsg = errExt.ErrMsg() - } else { - errMsg = err.Error() - } - if storeSkuLists, ok := storeSkuList.([]*partner.StoreSkuInfo); ok { - storeSkuInfoWithErr := &partner.StoreSkuInfoWithErr{ - StoreSkuInfo: storeSkuLists[0], - ErrMsg: errMsg, - StoreID: storeID, - VendoreName: vendorName, - SyncType: syncType, - } - failedList = append(failedList, storeSkuInfoWithErr) - } else if storeSkuLists, ok := storeSkuList.([]*dao.StoreSkuSyncInfo); ok { - storeSkuInfo := &partner.StoreSkuInfo{ - SkuID: storeSkuLists[0].SkuID, - VendorSkuID: storeSkuLists[0].VendorSkuID, - NameID: storeSkuLists[0].NameID, - VendorNameID: storeSkuLists[0].VendorNameID, - VendorPrice: storeSkuLists[0].VendorPrice, - Status: storeSkuLists[0].Status, - } - storeSkuInfoWithErr := &partner.StoreSkuInfoWithErr{ - StoreSkuInfo: storeSkuInfo, - ErrMsg: errMsg, - StoreID: storeID, - VendoreName: vendorName, - SyncType: syncType, - } - failedList = append(failedList, storeSkuInfoWithErr) - } else if storeSku, ok := storeSkuList.(*dao.StoreSkuSyncInfo); ok { - storeSkuInfo := &partner.StoreSkuInfo{ - SkuID: storeSku.SkuID, - VendorSkuID: storeSku.VendorSkuID, - NameID: storeSku.NameID, - VendorNameID: storeSku.VendorNameID, - VendorPrice: storeSku.VendorPrice, - Status: storeSku.Status, - } - storeSkuInfoWithErr := &partner.StoreSkuInfoWithErr{ - StoreSkuInfo: storeSkuInfo, - ErrMsg: errMsg, - StoreID: storeID, - VendoreName: vendorName, - SyncType: syncType, - } - failedList = append(failedList, storeSkuInfoWithErr) - } else { - storeSkuInfoWithErr := &partner.StoreSkuInfoWithErr{ - ErrMsg: errMsg, - StoreID: storeID, - VendoreName: vendorName, - SyncType: syncType, - } - failedList = append(failedList, storeSkuInfoWithErr) - } - } - return failedList -} - -func UnselectStoreSkuSyncListByVendorSkuIDs(storeSkuList []*dao.StoreSkuSyncInfo, vendorSkuIDs []string) (selectedStoreSkuList []*dao.StoreSkuSyncInfo) { - if len(vendorSkuIDs) > 0 { - vendorSkuIDMap := jxutils.StringList2Map(vendorSkuIDs) - for _, v := range storeSkuList { - if vendorSkuIDMap[v.VendorSkuID] == 0 { - selectedStoreSkuList = append(selectedStoreSkuList, v) - } - } - } else { - selectedStoreSkuList = storeSkuList - } - return selectedStoreSkuList -} - -func UnselectStoreSkuListBySkuIDs(storeSkuList []*partner.StoreSkuInfo, skuIDs []int) (selectedStoreSkuList []*partner.StoreSkuInfo) { - if len(skuIDs) > 0 { - skuIDMap := jxutils.IntList2Map(skuIDs) - for _, v := range storeSkuList { - if skuIDMap[v.SkuID] == 0 { - selectedStoreSkuList = append(selectedStoreSkuList, v) - } - } - } else { - selectedStoreSkuList = storeSkuList - } - return selectedStoreSkuList -} - -func GenPartialFailedErr(failedInfo interface{}, failedCount int) (err error) { - if failedCount > 0 { - err = fmt.Errorf("部分失败了%d个:%s", failedCount, utils.Format4Output(failedInfo, true)) - } - return err -} - -func StoreSku2ActStoreSku(syncStatus int8, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (actStoreSku []*model.ActStoreSku2) { - for _, v := range storeSkuList { - actStoreSku = append(actStoreSku, &model.ActStoreSku2{ - ActStoreSku: model.ActStoreSku{ - SkuID: v.SkuID, - Stock: 200, - }, - VendorStoreID: vendorStoreID, - VendorSkuID: v.VendorSkuID, - VendorActID: v.VendorActID, - ActualActPrice: v.ActPrice, - SyncStatus: syncStatus, - }) - } - return actStoreSku -} - -func UpdateStoreSkuByActStoreSku(storeSkuList []*partner.StoreSkuInfo, actStoreSku []*model.ActStoreSku2) []*partner.StoreSkuInfo { - storeSkuMap := StoreSkuList2MapBySkuID(storeSkuList) - for _, v := range actStoreSku { - if storeSku := storeSkuMap[v.SkuID]; storeSku != nil { - storeSku.VendorActID = v.VendorActID - } - } - return storeSkuList -} - -func GetFixDirectDownAct(vendorOrgCode string, storeID, skuID int) (act *model.Act2) { - name := fmt.Sprintf("自动直降活动%d:%d:%d", storeID, skuID, time.Now().Unix()) - act = &model.Act2{ - Act: model.Act{ - Name: name, - Advertising: name, - Type: model.ActSkuDirectDown, - Status: model.ActStatusCreated, - LimitUser: 1, - LimitCount: 1, - BeginAt: utils.Time2Date(time.Now()), - EndAt: utils.Time2Date(time.Now().Add(50 * 24 * time.Hour)), // 饿百平台要求只能是2个月长的活动 - }, - VendorOrgCode: vendorOrgCode, - } - return act -} - -func StoreSkuInfoWithErrList2SkuIDs(list []*partner.StoreSkuInfoWithErr) (skuIDs []int) { - for _, v := range list { - if v.StoreSkuInfo != nil && v.StoreSkuInfo.SkuID > 0 { - skuIDs = append(skuIDs, v.StoreSkuInfo.SkuID) - } - } - return skuIDs -} - -func StoreSkuInfoWithErrList2MapBySku(list []*partner.StoreSkuInfoWithErr) (mapInfo map[int]*partner.StoreSkuInfoWithErr) { - mapInfo = make(map[int]*partner.StoreSkuInfoWithErr) - for _, v := range list { - mapInfo[v.StoreSkuInfo.SkuID] = v - } - return mapInfo -} diff --git a/conf/app.conf b/conf/app.conf index 0223e293f..1154d9d97 100644 --- a/conf/app.conf +++ b/conf/app.conf @@ -1,6 +1,6 @@ appname = jx-callback httpport = 8080 -runmode = rsm +runmode = dev autorender = false copyrequestbody = true EnableDocs = true diff --git a/controllers/cms_store_sku.go b/controllers/cms_store_sku.go deleted file mode 100644 index 41b74b5a6..000000000 --- a/controllers/cms_store_sku.go +++ /dev/null @@ -1,919 +0,0 @@ -package controllers - -import ( - "math" - "time" - - "git.rosy.net.cn/jx-callback/business/model" - - "git.rosy.net.cn/baseapi/platformapi/jdapi" - - "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/dao" - "github.com/astaxie/beego" -) - -type StoreSkuController struct { - beego.Controller -} - -// @Title 得到商家商品信息 -// @Description 得到商家商品信息,如下条件之间是与的关系。对于没有认领的商品,按城市限制。但对于已经认领的商品就不限制了,因为已经在平台上可售,可以操作(改价等等) -// @Param token header string true "认证token" -// @Param storeID query int true "门店ID" -// @Param isFocus query bool true "是否已关注(认领)" -// @Param keyword query string false "查询关键字(可以为空,为空表示不限制)" -// @Param nameID query int false "SkuName ID" -// @Param nameIDs query string false "SkuName ID列表对象" -// @Param skuID query int false "Sku ID" -// @Param skuIDs query string false "Sku ID列表对象" -// @Param name query string false "商品名称(不要求完全一致)" -// @Param prefix query string false "商品前缀(不要求完全一致)" -// @Param categoryID query int false "商品所属类别ID" -// @Param unit query string false "商品单位" -// @Param fromStatus query int false "查询起始状态(0:不可售,1:可售)" -// @Param toStatus query int false "查询结束状态(0:不可售,1:可售)" -// @Param stFromTime query string false "统计SKU开始时间" -// @Param stToTime query string false "统计SKU结束时间" -// @Param stFromCount query int false "统计SKU,结果集起始数量(包括)" -// @Param stToCount query int false "统计SKU,结果集结束数量(包括)" -// @Param isGetOpRequest query bool false "是否返回相应的待审核变动请求,缺省为false不返回" -// @Param offset query int false "门店列表起始序号(以0开始,缺省为0)" -// @Param pageSize query int false "门店列表页大小(缺省为50,-1表示全部)" -// @Param isBySku query bool false "是否按SKU分拆" -// @Param isAct query bool false "是否活动商品(包括正常活动与补贴)" -// @Param actVendorID query int false "要得到哪个平台的活动信息(缺省不限制,非零最小值)" -// @Param jdSyncStatus query int false "京东同步标识" -// @Param ebaiSyncStatus query int false "饿百同步标识" -// @Param mtwmSyncStatus query int false "美团外卖同步标识" -// @Param lockTime query string false "价格锁定时间" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /GetStoreSkus [get] -func (c *StoreSkuController) GetStoreSkus() { - c.callGetStoreSkus(func(params *tStoreSkuGetStoreSkusParams) (retVal interface{}, errCode string, err error) { - var skuIDs []int - if err = jxutils.Strings2Objs(params.SkuIDs, &skuIDs); err == nil { - retVal, err = cms.GetStoreSkus(params.Ctx, params.StoreID, skuIDs, params.IsFocus, params.Keyword, params.IsBySku, params.IsAct, params.MapData, params.Offset, params.PageSize) - } - return retVal, "", err - }) -} - -// @Title 得到商家商品信息 -// @Description 得到商家商品信息,如下条件之间是与的关系。对于没有认领的商品,按城市限制。但对于已经认领的商品就不限制了,因为已经在平台上可售,可以操作(改价等等) -// @Param token header string false "认证token" -// @Param storeIDs query string false "门店ID" -// @Param isFocus query bool true "是否已关注(认领)" -// @Param keyword query string false "查询关键字(可以为空,为空表示不限制)" -// @Param nameIDs query string false "SkuName ID列表对象" -// @Param skuIDs query string false "Sku ID列表对象" -// @Param name query string false "商品名称(不要求完全一致)" -// @Param prefix query string false "商品前缀(不要求完全一致)" -// @Param categoryID query int false "商品所属类别ID" -// @Param unit query string false "商品单位" -// @Param fromStatus query int false "查询起始状态(0:不可售,1:可售)" -// @Param toStatus query int false "查询结束状态(0:不可售,1:可售)" -// @Param stFromTime query string false "统计SKU开始时间" -// @Param stToTime query string false "统计SKU结束时间" -// @Param stFromCount query int false "统计SKU,结果集起始数量(包括)" -// @Param stToCount query int false "统计SKU,结果集结束数量(包括)" -// @Param isGetOpRequest query bool false "是否返回相应的待审核变动请求,缺省为false不返回" -// @Param offset query int false "门店列表起始序号(以0开始,缺省为0)" -// @Param pageSize query int false "门店列表页大小(缺省为50,-1表示全部)" -// @Param isBySku query bool false "是否按SKU分拆" -// @Param isAct query bool false "是否活动商品(包括正常活动与补贴)" -// @Param actVendorID query int false "要得到哪个平台的活动信息(缺省不限制,非零最小值)" -// @Param jdSyncStatus query int false "京东同步标识" -// @Param ebaiSyncStatus query int false "饿百同步标识" -// @Param mtwmSyncStatus query int false "美团外卖同步标识" -// @Param lockTime query string false "价格锁定时间" -// @Param isHighPrice query bool false "是否查过高价格商品,0是忽略,1是高价,-1是低价" -// @Param priceType query int false "是否查过高价格商品,0是忽略,1是高价,-1是低价" -// @Param highestPrice query string false "查询最高价" -// @Param minimumPrice query string false "查询最低价" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /GetStoresSkus [get,post] -func (c *StoreSkuController) GetStoresSkus() { - c.callGetStoresSkus(func(params *tStoreSkuGetStoresSkusParams) (retVal interface{}, errCode string, err error) { - var storeIDs, skuIDs []int - if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.SkuIDs, &skuIDs); err == nil { - retVal, err = cms.GetStoresSkus(params.Ctx, storeIDs, skuIDs, params.IsFocus, params.IsHighPrice, params.PriceType, params.Keyword, params.IsBySku, params.IsAct, params.MapData, params.Offset, params.PageSize) - } - return retVal, "", err - }) -} - -// @Title 得到异常门店商品数量 -// @Description 得到异常门店商品数量 -// @Param token header string true "认证token" -// @Param storeID query int true "门店ID" -// @Param syncStatus query int true "同步标志掩码" -// @Param isBySku query bool false "是否按SKU分拆" -// @Param fromStatus query int false "查询起始状态(0:不可售,1:可售)" -// @Param toStatus query int false "查询结束状态(0:不可售,1:可售)" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /GetStoreAbnormalSkuCount [get] -func (c *StoreSkuController) GetStoreAbnormalSkuCount() { - c.callGetStoreAbnormalSkuCount(func(params *tStoreSkuGetStoreAbnormalSkuCountParams) (retVal interface{}, errCode string, err error) { - retVal, err = cms.GetStoreAbnormalSkuCount(params.Ctx, params.StoreID, params.SyncStatus, params.IsBySku, params.MapData) - return retVal, "", err - }) -} - -// @Title 得到门店商品全信息 -// @Description 得到异常门店商品数量 -// @Param token header string true "认证token" -// @Param storeID query int true "门店ID" -// @Param vendorIDs query string false "厂商ID列表" -// @Param skuIDs query string true "Sku ID列表对象" -// @Param isContinueWhenError query bool false "单个同步失败是否继续,缺省false" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /GetVendorStoreSkusInfo [get] -func (c *StoreSkuController) GetVendorStoreSkusInfo() { - c.callGetVendorStoreSkusInfo(func(params *tStoreSkuGetVendorStoreSkusInfoParams) (retVal interface{}, errCode string, err error) { - var vendorIDs, skuIDs []int - err = jxutils.Strings2Objs(params.VendorIDs, &vendorIDs, params.SkuIDs, &skuIDs) - if err == nil { - retVal, err = cms.GetVendorStoreSkusInfo(params.Ctx, params.StoreID, vendorIDs, skuIDs, params.IsContinueWhenError) - } - return retVal, "", err - }) -} - -// @Title 修改商家商品绑定 -// @Description 修改商家商品绑定,请换用UpdateStoresSkus -// @Param token header string true "认证token" -// @Param storeID formData int true 门店ID" -// @Param payload formData string true "json数据,StoreSkuBindInfo对象" -// @Param causeFlag formData int false "操作类型" -// @Param isContinueWhenError formData bool false "单个同步失败是否继续,缺省false" -// @Param isAsync formData bool false "是否异步操作" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /UpdateStoreSku [put] -func (c *StoreSkuController) UpdateStoreSku() { - c.callUpdateStoreSku(func(params *tStoreSkuUpdateStoreSkuParams) (retVal interface{}, errCode string, err error) { - var skuBindInfo cms.StoreSkuBindInfo - if err = jxutils.Strings2Objs(params.Payload, &skuBindInfo); err == nil { - retVal, err = cms.UpdateStoreSku(params.Ctx, params.CauseFlag, params.StoreID, &skuBindInfo, params.IsAsync, params.IsContinueWhenError) - } - return retVal, "", err - }) -} - -// @Title 批量修改商家商品绑定 -// @Description 批量修改商家商品绑定,请换用UpdateStoresSkus -// @Param token header string true "认证token" -// @Param storeID formData int true "门店ID" -// @Param payload formData string true "json数据,StoreSkuBindInfo对象数组" -// @Param causeFlag formData int false "操作类型" -// @Param isContinueWhenError formData bool false "单个同步失败是否继续,缺省false" -// @Param isAsync formData bool false "是否异步操作" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /UpdateStoreSkus [put] -func (c *StoreSkuController) UpdateStoreSkus() { - c.callUpdateStoreSkus(func(params *tStoreSkuUpdateStoreSkusParams) (retVal interface{}, errCode string, err error) { - var skuBindInfos []*cms.StoreSkuBindInfo - if err = jxutils.Strings2Objs(params.Payload, &skuBindInfos); err == nil { - retVal, err = cms.UpdateStoreSkus(params.Ctx, params.CauseFlag, params.StoreID, skuBindInfos, params.IsAsync, params.IsContinueWhenError) - } - return retVal, "", err - }) -} - -// @Title 同步商家商品信息 -// @Description 同步商家商品信息 -// @Param token header string true "认证token" -// @Param vendorIDs formData string false "厂商ID列表" -// @Param storeIDs formData string false "门店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 *StoreSkuController) SyncStoresSkus() { - c.callSyncStoresSkus(func(params *tStoreSkuSyncStoresSkusParams) (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 payload formData string true "json数据,StoreSkuBindInfo对象数组" -// @Param isScale formData bool false "是否按门店结算比例缩放" -// @Param causeFlag formData int false "操作类型" -// @Param isRefreshHigh formData bool false "是否只刷门店价高于给的价" -// @Param isContinueWhenError formData bool false "单个同步失败是否继续,缺省false" -// @Param isAsync formData bool false "是否异步操作" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /UpdateStoresSkus [put] -func (c *StoreSkuController) UpdateStoresSkus() { - c.callUpdateStoresSkus(func(params *tStoreSkuUpdateStoresSkusParams) (retVal interface{}, errCode string, err error) { - var storeIDs []int - var skuBindInfos []*cms.StoreSkuBindInfo - if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.Payload, &skuBindInfos); err != nil { - return retVal, "", err - } - retVal, err = cms.UpdateStoresSkus(params.Ctx, params.CauseFlag, storeIDs, skuBindInfos, params.IsScale, params.IsRefreshHigh, params.IsAsync, params.IsContinueWhenError) - return retVal, "", err - }) -} - -// @Title 批量修改多商家商品绑定(不同步) -// @Description 批量修改多商家商品绑定(不同步) -// @Param token header string true "认证token" -// @Param storeIDs formData string false "门店ID列表" -// @Param payload formData string true "json数据,StoreSkuBindInfo对象数组" -// @Param isRefreshHigh formData bool true "是否只刷门店价高于给的价" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /UpdateStoresSkusWithoutSync [put] -func (c *StoreSkuController) UpdateStoresSkusWithoutSync() { - c.callUpdateStoresSkusWithoutSync(func(params *tStoreSkuUpdateStoresSkusWithoutSyncParams) (retVal interface{}, errCode string, err error) { - var storeIDs []int - var skuBindInfos []*cms.StoreSkuBindInfo - if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.Payload, &skuBindInfos); err != nil { - return retVal, "", err - } - err = cms.UpdateStoresSkusWithoutSync(params.Ctx, storeIDs, skuBindInfos, params.IsRefreshHigh) - return retVal, "", err - }) -} - -// @Title 按门店商品维度批量修改多商家商品绑定 -// @Description 按门店商品维度批量修改多商家商品绑定 -// @Param token header string true "认证token" -// @Param payload formData string true "json数据,StoreSkuBindInfo对象数组" -// @Param isContinueWhenError formData bool false "单个同步失败是否继续,缺省false" -// @Param isAsync formData bool false "是否异步操作" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /UpdateStoresSkusByBind [put] -func (c *StoreSkuController) UpdateStoresSkusByBind() { - c.callUpdateStoresSkusByBind(func(params *tStoreSkuUpdateStoresSkusByBindParams) (retVal interface{}, errCode string, err error) { - var skuBindInfos []*cms.StoreSkuBindInfo - if err = jxutils.Strings2Objs(params.Payload, &skuBindInfos); err != nil { - return retVal, "", err - } - retVal, err = cms.UpdateStoresSkusByBind(params.Ctx, nil, skuBindInfos, params.IsAsync, params.IsContinueWhenError, false) - return retVal, "", err - }) -} - -// @Title 拷贝门店SKU信息 -// @Description 拷贝门店SKU信息(此函数当前只是本地数据操作,要同步到远端需要调用SyncStoresSkus) -// @Param token header string true "认证token" -// @Param fromStoreID formData int true "源门店ID" -// @Param toStoreID formData int false "目标门店ID" -// @Param toStoreIDs formData string false "目标门店ID列表" -// @Param copyMode formData string true "拷贝模式,fresh:目标门店数据全部清除后拷贝,update:确保指定的源数据全部拷贝,已有的忽略" -// @Param pricePercentage formData int false "价格调整百分比,缺省为100%" -// @Param categoryIDs formData string false "json数据,skuName所属的类别,[1,2,3]" -// @Param skuIDs formData string false "json数据,skuID列表,[1,2,3]" -// @Param isScale formData bool false "是否按门店结算比例缩放" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /CopyStoreSkus [post] -func (c *StoreSkuController) CopyStoreSkus() { - c.callCopyStoreSkus(func(params *tStoreSkuCopyStoreSkusParams) (retVal interface{}, errCode string, err error) { - var toStoreIDs []int - if err = jxutils.Strings2Objs(params.ToStoreIDs, &toStoreIDs); err == nil { - if params.ToStoreID > 0 { - toStoreIDs = append(toStoreIDs, params.ToStoreID) - } - retVal, err = cms.CopyStoreSkus(params.Ctx, params.FromStoreID, toStoreIDs, params.CopyMode, params.IsScale, params.MapData, params.Ctx.GetUserName()) - } - return retVal, "", err - }) -} - -// @Title 批量修改多商家商品可售状态 -// @Description 批量修改多商家商品可售状态 -// @Param token header string true "认证token" -// @Param storeIDs formData string true "门店ID列表" -// @Param payload formData string true "json数据,StoreSkuBindSkuInfo对象数组" -// @Param isContinueWhenError formData bool false "单个同步失败是否继续,缺省false" -// @Param autoSaleAt formData string false "临时不可售到期时间" -// @Param ignoreDontSale formData bool false "在临时不可售时,是否忽略当前是不可售的商品" -// @Param isAsync formData bool false "是否异步操作" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /UpdateStoresSkusSale [put] -func (c *StoreSkuController) UpdateStoresSkusSale() { - c.callUpdateStoresSkusSale(func(params *tStoreSkuUpdateStoresSkusSaleParams) (retVal interface{}, errCode string, err error) { - var storeIDs []int - var skuBindSkuInfos []*cms.StoreSkuBindSkuInfo - if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.Payload, &skuBindSkuInfos); err != nil { - return retVal, "", err - } - timeList, err := jxutils.BatchStr2Time(params.AutoSaleAt) - if err != nil { - return retVal, "", err - } - retVal, err = cms.UpdateStoresSkusSale(params.Ctx, storeIDs, skuBindSkuInfos, timeList[0], params.IgnoreDontSale, params.Ctx.GetUserName(), params.IsAsync, params.IsContinueWhenError) - return retVal, "", err - }) -} - -// @Title 得到商家商品销售情况 -// @Description 得到商家商品销售情况 -// @Param token header string true "认证token" -// @Param storeIDs query string true "门店ID列表" -// @Param skuIDs query string true "Sku ID列表" -// @Param stFromTime query string true "统计SKU开始时间" -// @Param stToTime query string false "统计SKU结束时间" -// @Param stFromCount query int false "统计SKU,结果集起始数量(包括)" -// @Param stToCount query int false "统计SKU,结果集结束数量(包括)" -// @Param offset query int false "门店列表起始序号(以0开始,缺省为0)" -// @Param pageSize query int false "门店列表页大小(缺省为50,-1表示全部)" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /GetStoresSkusSaleInfo [get] -func (c *StoreSkuController) GetStoresSkusSaleInfo() { - c.callGetStoresSkusSaleInfo(func(params *tStoreSkuGetStoresSkusSaleInfoParams) (retVal interface{}, errCode string, err error) { - var ( - storeIDs, skuIDs []int - timeList []time.Time - ) - if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.SkuIDs, &skuIDs); err != nil { - return retVal, "", err - } - if timeList, err = jxutils.BatchStr2Time(params.StFromTime, params.StToTime); err != nil { - return retVal, "", err - } - if params.MapData["stToToCount"] == nil { - params.StToCount = math.MaxInt32 - } - retVal, err = cms.GetStoresSkusSaleInfo(params.Ctx, storeIDs, skuIDs, timeList[0], timeList[1], params.StFromCount, params.StToCount) - return retVal, "", err - }) -} - -// // @Title 得到商家商品修改价格请求信息 -// // @Description 得到商家商品修改价格请求信息 -// // @Param token header string true "认证token" -// // @Param fromTime query string false "申请开始时间" -// // @Param toTime query string false "申请结束时间" -// // @Param keyword query string false "查询关键字(可以为空,为空表示不限制)" -// // @Param storeIDs query string false "门店ID列表" -// // @Param itemIDs query string false "id列表对象,当前指skuname id" -// // @Param types query string false "类型列表对象" -// // @Param statuss query string false "状态列表对象" -// // @Param offset query int false "门店列表起始序号(以0开始,缺省为0)" -// // @Param pageSize query int false "门店列表页大小(缺省为50,-1表示全部)" -// // @Success 200 {object} controllers.CallResult -// // @Failure 200 {object} controllers.CallResult -// // @router /GetStoreOpRequests [get] -// func (c *StoreSkuController) GetStoreOpRequests() { -// c.callGetStoreOpRequests(func(params *tStoreSkuGetStoreOpRequestsParams) (retVal interface{}, errCode string, err error) { -// var ( -// timeList []time.Time -// storeIDs, typeList, statusList, itemIDs []int -// ) -// if timeList, err = jxutils.BatchStr2Time(params.FromTime, params.ToTime); err != nil { -// return retVal, "", err -// } -// if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.Types, &typeList, params.Statuss, &statusList, params.ItemIDs, &itemIDs); err != nil { -// return retVal, "", err -// } -// retVal, err = cms.GetStoreOpRequests(params.Ctx, timeList[0], timeList[1], params.Keyword, storeIDs, itemIDs, typeList, statusList, params.Offset, params.PageSize) -// return retVal, "", err -// }) -// } - -// // @Title 处理商家商品价格申请 -// // @Description 处理商家商品价格申请 -// // @Param token header string true "认证token" -// // @Param reqIDs formData string true "请求ID列表对象" -// // @Param handleType formData int true "-1拒绝,1批准" -// // @Param rejectReason formData string false "拒绝理由,拒绝时要求" -// // @Success 200 {object} controllers.CallResult -// // @Failure 200 {object} controllers.CallResult -// // @router /HandleStoreOpRequest [put] -// func (c *StoreSkuController) HandleStoreOpRequest() { -// c.callHandleStoreOpRequest(func(params *tStoreSkuHandleStoreOpRequestParams) (retVal interface{}, errCode string, err error) { -// var reqIDs []int -// if err = jxutils.Strings2Objs(params.ReqIDs, &reqIDs); err != nil { -// return retVal, "", err -// } -// if params.HandleType == 1 { -// err = cms.AcceptStoreOpRequests(params.Ctx, reqIDs) -// } else if params.HandleType == -1 { -// err = cms.RejectStoreOpRequests(params.Ctx, reqIDs, params.RejectReason) -// } else { -// err = fmt.Errorf("handleType=%d是非法值", params.HandleType) -// } -// return retVal, "", err -// }) -// } - -// @Title 根据厂家门店商品信息相应刷新本地数据 -// @Description 根据厂家门店商品信息相应刷新本地数据 -// @Param token header string true "认证token" -// @Param storeIDs formData string true "门店ID列表" -// @Param vendorID formData int true "厂商ID(当前只支持京东)" -// @Param isAsync formData bool false "是否异步操作" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /RefreshStoresSkuByVendor [put] -func (c *StoreSkuController) RefreshStoresSkuByVendor() { - c.callRefreshStoresSkuByVendor(func(params *tStoreSkuRefreshStoresSkuByVendorParams) (retVal interface{}, errCode string, err error) { - var storeIDList []int - if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDList); err == nil { - retVal, err = cms.RefreshStoresSkuByVendor(params.Ctx, storeIDList, params.VendorID, params.IsAsync) - } - return retVal, "", err - }) -} - -// @Title 京东商家商品状态同步 -// @Description 京东商家商品状态同步 -// @Param token header string true "认证token" -// @Param storeIDs formData string true "门店ID列表" -// @Param skuIDs formData string false "SKU ID列表,缺省为全部" -// @Param isAsync formData bool false "是否异步操作" -// @Param isContinueWhenError formData bool false "单个同步失败是否继续,缺省false" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /SyncJdStoreProducts [put] -func (c *StoreSkuController) SyncJdStoreProducts() { - c.callSyncJdStoreProducts(func(params *tStoreSkuSyncJdStoreProductsParams) (retVal interface{}, errCode string, err error) { - var storeIDList, skuIDList []int - err = jxutils.Strings2Objs(params.StoreIDs, &storeIDList, params.SkuIDs, &skuIDList) - if err == nil { - retVal, err = cms.SyncJdStoreProducts(params.Ctx, storeIDList, skuIDList, params.IsAsync, params.IsContinueWhenError) - } - return retVal, "", err - }) -} - -// @Title 从订单得到本地没有关注的商品信息 -// @Description 从订单得到本地没有关注的商品信息 -// @Param token header string true "认证token" -// @Param fromTime query string true "扫描的订单开始时间" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /GetMissingStoreSkuFromOrder [get] -func (c *StoreSkuController) GetMissingStoreSkuFromOrder() { - c.callGetMissingStoreSkuFromOrder(func(params *tStoreSkuGetMissingStoreSkuFromOrderParams) (retVal interface{}, errCode string, err error) { - timeList, err := jxutils.BatchStr2Time(params.FromTime) - if err == nil { - retVal, err = cms.GetMissingStoreSkuFromOrder(params.Ctx, timeList[0]) - } - return retVal, "", err - }) -} - -// @Title 根据门店信息查找推荐商品(按销量) -// @Description 根据门店信息查找推荐商品(按销量) -// @Param token header string false "认证token" -// @Param storeIDs query string true "门店列表" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /GetTopSkusByStoreIDs [get] -func (c *StoreSkuController) GetTopSkusByStoreIDs() { - var storeIDList []int - c.callGetTopSkusByStoreIDs(func(params *tStoreSkuGetTopSkusByStoreIDsParams) (retVal interface{}, errCode string, err error) { - if jxutils.Strings2Objs(params.StoreIDs, &storeIDList); err == nil { - retVal, err = cms.GetTopSkusByStoreIDs(params.Ctx, storeIDList) - } - return retVal, "", err - }) -} - -// @Title 根据城市信息查找推荐商品(按销量) -// @Description 根据城市信息查找推荐商品(按销量) -// @Param token header string true "认证token" -// @Param cityCode query int false "城市id" -// @Param storeID query int false "门店id" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /GetTopSkusByCityCode [get] -func (c *StoreSkuController) GetTopSkusByCityCode() { - c.callGetTopSkusByCityCode(func(params *tStoreSkuGetTopSkusByCityCodeParams) (retVal interface{}, errCode string, err error) { - retVal, err = cms.GetTopSkusByCityCode(params.Ctx, params.CityCode, params.StoreID) - return retVal, "", err - }) -} - -// @Title 根据门店信息查找推荐分类(按商品销量) -// @Description 根据门店信息查找推荐分类(按商品销量) -// @Param token header string false "认证token" -// @Param storeIDs query string true "门店列表" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /GetTopCategoriesByStoreIDs [get] -func (c *StoreSkuController) GetTopCategoriesByStoreIDs() { - var storeIDList []int - c.callGetTopCategoriesByStoreIDs(func(params *tStoreSkuGetTopCategoriesByStoreIDsParams) (retVal interface{}, errCode string, err error) { - if jxutils.Strings2Objs(params.StoreIDs, &storeIDList); err == nil { - retVal, err = cms.GetTopCategoriesByStoreIDs(params.Ctx, storeIDList) - } - return retVal, "", err - }) -} - -// @Title 根据门店刷新中位价 -// @Description 根据门店刷新中位价 -// @Param token header string true "认证token" -// @Param isCountry formData bool true "是否按全国中位价刷新" -// @Param storeIDs formData string true "门店列表" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /RefershStoreSkusMidPrice [put] -func (c *StoreSkuController) RefershStoreSkusMidPrice() { - var storeIDList []int - c.callRefershStoreSkusMidPrice(func(params *tStoreSkuRefershStoreSkusMidPriceParams) (retVal interface{}, errCode string, err error) { - if jxutils.Strings2Objs(params.StoreIDs, &storeIDList); err == nil { - err = cms.RefershStoreSkusMidPrice(params.Ctx, storeIDList, params.IsCountry) - } - return retVal, "", err - }) -} - -// @Title 根据Excel刷新京西门店商品价 -// @Description 根据Excel刷新京西门店商品价 -// @Param token header string true "认证token" -// @Param storeIDs formData string true "门店列表" -// @Param isAsync formData bool true "是否异步,缺省是同步" -// @Param isContinueWhenError formData bool true "单个同步失败是否继续,缺省false" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /RefreshJxPriceByExcel [post] -func (c *StoreSkuController) RefreshJxPriceByExcel() { - var storeIDList []int - c.callRefreshJxPriceByExcel(func(params *tStoreSkuRefreshJxPriceByExcelParams) (retVal interface{}, errCode string, err error) { - if jxutils.Strings2Objs(params.StoreIDs, &storeIDList); err == nil { - r := c.Ctx.Request - files := r.MultipartForm.File["userfiles"] - retVal, err = cms.RefreshJxPriceByExcel(params.Ctx, storeIDList, files, params.IsAsync, params.IsContinueWhenError) - } - return retVal, "", err - }) -} - -// @Title 根据Excel中SkuID批量关注商品 -// @Description 根据Excel中SkuID批量关注商品 -// @Param token header string true "认证token" -// @Param isAsync formData bool true "是否异步,缺省是同步" -// @Param isContinueWhenError formData bool true "单个同步失败是否继续,缺省false" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /FocusStoreSkusByExcel [post] -func (c *StoreSkuController) FocusStoreSkusByExcel() { - c.callFocusStoreSkusByExcel(func(params *tStoreSkuFocusStoreSkusByExcelParams) (retVal interface{}, errCode string, err error) { - r := c.Ctx.Request - files := r.MultipartForm.File["userfiles"] - retVal, err = cms.FocusStoreSkusByExcel(params.Ctx, files, params.IsAsync, params.IsContinueWhenError) - return retVal, "", err - }) -} - -// @Title 得到门店的分类列表 -// @Description 得到门店的分类列表(按商品销量) -// @Param token header string false "认证token" -// @Param storeID query int true "门店ID" -// @Param parentID query int false "父分类id" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /GetStoreCategories [get] -func (c *StoreSkuController) GetStoreCategories() { - c.callGetStoreCategories(func(params *tStoreSkuGetStoreCategoriesParams) (retVal interface{}, errCode string, err error) { - if params.MapData["parentID"] == nil { - params.ParentID = -1 - } - retVal, err = cms.GetStoreCategories(params.Ctx, params.StoreID, params.ParentID) - return retVal, "", err - }) -} - -// @Title 获取各平台所有门店某商品的价格 -// @Description 获取各平台所有门店某商品的价格 -// @Param token header string true "认证token" -// @Param skuID formData int true "商品ID" -// @Param vendorIDs formData string true "厂商ID列表" -// @Param isAsync formData bool true "是否异步,缺省是同步" -// @Param isContinueWhenError formData bool true "单个同步失败是否继续,缺省false" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /GetVendorStoreSkuPrice [post] -func (c *StoreSkuController) GetVendorStoreSkuPrice() { - var vendorIDList []int - c.callGetVendorStoreSkuPrice(func(params *tStoreSkuGetVendorStoreSkuPriceParams) (retVal interface{}, errCode string, err error) { - if jxutils.Strings2Objs(params.VendorIDs, &vendorIDList); err == nil { - retVal, err = cms.GetVendorStoreSkuPrice(params.Ctx, vendorIDList, params.SkuID, params.IsAsync, params.IsContinueWhenError) - } - return retVal, "", err - }) -} - -// @Title 根据skuID关注商品,价格为中位价,部分可售 -// @Description 根据skuID关注商品,价格为中位价,部分可售 -// @Param token header string true "认证token" -// @Param payload formData string true "json数据,StoreSkuBindInfo对象数组" -// @Param isAsync formData bool true "是否异步,缺省是同步" -// @Param isContinueWhenError formData bool true "单个同步失败是否继续,缺省false" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /FocusStoreSkusBySku [post] -func (c *StoreSkuController) FocusStoreSkusBySku() { - var skuBindInfos []*cms.StoreSkuBindInfo - c.callFocusStoreSkusBySku(func(params *tStoreSkuFocusStoreSkusBySkuParams) (retVal interface{}, errCode string, err error) { - if err = jxutils.Strings2Objs(params.Payload, &skuBindInfos); err != nil { - return retVal, "", err - } - retVal, err = cms.FocusStoreSkusBySku(params.Ctx, skuBindInfos, params.IsAsync, params.IsContinueWhenError) - return retVal, "", err - }) -} - -// @Title 自动关注畅销品 -// @Description 自动关注畅销品 -// @Param token header string true "认证token" -// @Param isAsync formData bool true "是否异步,缺省是同步" -// @Param isContinueWhenError formData bool true "单个同步失败是否继续,缺省false" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /AutoFocusStoreSkusForTopSkus [post] -func (c *StoreSkuController) AutoFocusStoreSkusForTopSkus() { - c.callAutoFocusStoreSkusForTopSkus(func(params *tStoreSkuAutoFocusStoreSkusForTopSkusParams) (retVal interface{}, errCode string, err error) { - retVal, err = cms.AutoFocusStoreSkusForTopSkus(params.Ctx, params.IsAsync, params.IsContinueWhenError) - return retVal, "", err - }) -} - -// @Title 设置平台商品力荐标志 -// @Description 设置平台商品力荐标志 -// @Param token header string true "认证token" -// @Param vendorIDs formData string true "厂商ID列表" -// @Param isAsync formData bool true "是否异步,缺省是同步" -// @Param isContinueWhenError formData bool true "单个同步失败是否继续,缺省false" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /UpdateStoreSkusSpecTag [post] -func (c *StoreSkuController) UpdateStoreSkusSpecTag() { - var vendorIDList []int - c.callUpdateStoreSkusSpecTag(func(params *tStoreSkuUpdateStoreSkusSpecTagParams) (retVal interface{}, errCode string, err error) { - r := c.Ctx.Request - files := r.MultipartForm.File["userfiles"] - if jxutils.Strings2Objs(params.VendorIDs, &vendorIDList); err == nil { - retVal, err = cms.UpdateStoreSkusSpecTag(params.Ctx, vendorIDList, files, params.IsAsync, params.IsContinueWhenError) - } - return retVal, "", err - }) -} - -// @Title 手动爆品预警 -// @Description 手动爆品预警 -// @Param token header string true "认证token" -// @Param vendorIDs formData string true "厂商ID列表" -// @Param isAsync formData bool true "是否异步,缺省是同步" -// @Param isContinueWhenError formData bool true "单个同步失败是否继续,缺省false" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /SendSeckillSkusCountMsg [post] -func (c *StoreSkuController) SendSeckillSkusCountMsg() { - var vendorIDList []int - c.callSendSeckillSkusCountMsg(func(params *tStoreSkuSendSeckillSkusCountMsgParams) (retVal interface{}, errCode string, err error) { - if jxutils.Strings2Objs(params.VendorIDs, &vendorIDList); err == nil { - retVal, err = cms.SendSeckillSkusCountMsg(params.Ctx, vendorIDList, params.IsAsync, params.IsContinueWhenError) - } - return retVal, "", err - }) -} - -// @Title 根据平台价反算京西价 -// @Description 根据平台价反算京西价 -// @Param token header string true "认证token" -// @Param payload formData string true "json数据,JdStoreSkus对象" -// @Param vendorID formData int true "厂商ID" -// @Param ignoreLow formData bool true "是否忽略低价商品" -// @Param isAsync formData bool true "是否异步,缺省是同步" -// @Param isContinueWhenError formData bool true "单个同步失败是否继续,缺省false" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /RefreshJxPriceByVendor [put] -func (c *StoreSkuController) RefreshJxPriceByVendor() { - var skuBindInfos []*cms.JdStoreSkus - c.callRefreshJxPriceByVendor(func(params *tStoreSkuRefreshJxPriceByVendorParams) (retVal interface{}, errCode string, err error) { - if err = jxutils.Strings2Objs(params.Payload, &skuBindInfos); err != nil { - return retVal, "", err - } - retVal, err = cms.RefreshJxPriceByVendor(params.Ctx, skuBindInfos, params.VendorID, params.IgnoreLow, params.IsAsync, params.IsContinueWhenError) - return retVal, "", err - }) -} - -// @Title 根据平台价反算京西价2 -// @Description 根据平台价反算京西价2 -// @Param token header string true "认证token" -// @Param storeIDs formData string true "门店列表" -// @Param vendorID formData int true "厂商ID" -// @Param isAsync formData bool false "是否异步,缺省是同步" -// @Param isContinueWhenError formData bool false "单个同步失败是否继续,缺省false" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /RefreshJxPriceByVendor2 [put] -func (c *StoreSkuController) RefreshJxPriceByVendor2() { - var storeIDs []int - c.callRefreshJxPriceByVendor2(func(params *tStoreSkuRefreshJxPriceByVendor2Params) (retVal interface{}, errCode string, err error) { - if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs); err != nil { - return retVal, "", err - } - retVal, err = cms.RefreshJxPriceByVendor2(params.Ctx, storeIDs, params.VendorID, params.IsAsync, params.IsContinueWhenError) - return retVal, "", err - }) -} - -// @Title 生成门店商品备份表 -// @Description 生成门店商品备份表 -// @Param token header string true "认证token" -// @Param isAsync formData bool false "是否异步,缺省是同步" -// @Param isContinueWhenError formData bool false "单个同步失败是否继续,缺省false" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /BackUpStoreSkuBind [post] -func (c *StoreSkuController) BackUpStoreSkuBind() { - c.callBackUpStoreSkuBind(func(params *tStoreSkuBackUpStoreSkuBindParams) (retVal interface{}, errCode string, err error) { - retVal, err = cms.BackUpStoreSkuBind(params.Ctx, params.IsAsync, params.IsContinueWhenError) - return retVal, "", err - }) -} - -// @Title 恢复门店商品表 -// @Description 恢复门店商品表 -// @Param token header string true "认证token" -// @Param snapshotAt formData string true "日期,格式2020-03-06 00:00:00" -// @Param storeIDs formData string true "门店列表" -// @Param skuIDs formData string false "商品列表" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /ReturnStoreSkuBind [post] -func (c *StoreSkuController) ReturnStoreSkuBind() { - c.callReturnStoreSkuBind(func(params *tStoreSkuReturnStoreSkuBindParams) (retVal interface{}, errCode string, err error) { - var storeIDs, skuIDs []int - if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.SkuIDs, &skuIDs); err != nil { - return retVal, "", err - } - err = cms.ReturnStoreSkuBind(params.Ctx, params.SnapshotAt, storeIDs, skuIDs) - return retVal, "", err - }) -} - -// @Title 物料库存刷新(物料店商品上下架) -// @Description 物料库存刷新(物料店商品上下架) -// @Param token header string false "认证token" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /RefreshMatterStock [post] -func (c *StoreSkuController) RefreshMatterStock() { - c.callRefreshMatterStock(func(params *tStoreSkuRefreshMatterStockParams) (retVal interface{}, errCode string, err error) { - err = cms.RefreshMatterStock(params.Ctx, 0) - return retVal, "", err - }) -} - -// @Title 从银豹上拉取标品到京西创建 -// @Description 从银豹上拉取标品到京西创建 -// @Param token header string true "认证token" -// @Param isAsync formData bool false "是否异步,缺省是同步" -// @Param isContinueWhenError formData bool false "单个同步失败是否继续,缺省false" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /CreateSkusAndFocusFromYb [post] -func (c *StoreSkuController) CreateSkusAndFocusFromYb() { - c.callCreateSkusAndFocusFromYb(func(params *tStoreSkuCreateSkusAndFocusFromYbParams) (retVal interface{}, errCode string, err error) { - // retVal, err = cms.CreateSkusAndFocusFromYb(params.Ctx, params.IsAsync, params.IsContinueWhenError) - return retVal, "", err - }) -} - -// @Title 从微信上扫码标品到京西创建或关注 -// @Description 从微信上扫码标品到京西创建或关注 -// @Param token header string true "认证token" -// @Param payload formData string true "json数据,ProductInfo对象" -// @Param storeID formData int true "门店ID" -// @Param price formData int true "商品价格" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /CreateSkusAndFocusFromWx [post] -func (c *StoreSkuController) CreateSkusAndFocusFromWx() { - var productInfo *jdapi.ProductInfo - c.callCreateSkusAndFocusFromWx(func(params *tStoreSkuCreateSkusAndFocusFromWxParams) (retVal interface{}, errCode string, err error) { - if err = jxutils.Strings2Objs(params.Payload, &productInfo); err != nil { - return retVal, "", err - } - err = cms.CreateSkusAndFocusFromWx(params.Ctx, productInfo, params.Price, params.StoreID) - return retVal, "", err - }) -} - -// @Title 同步菜市物料到果园 -// @Description 同步菜市物料到果园 -// @Param token header string true "认证token" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /SyncMatterC4ToGy [post] -func (c *StoreSkuController) SyncMatterC4ToGy() { - c.callSyncMatterC4ToGy(func(params *tStoreSkuSyncMatterC4ToGyParams) (retVal interface{}, errCode string, err error) { - retVal, err = cms.SyncMatterC4ToGy(params.Ctx, true, true) - return retVal, "", err - }) -} - -// @Title 查询商品审核信息 -// @Description 查询商品审核信息 -// @Param token header string true "认证token" -// @Param applyTimeStart query string false "申请开始时间" -// @Param applyTimeEnd query string false "申请结束时间" -// @Param auditTimeStart query string false "审核开始时间" -// @Param auditTimeEnd query string false "审核结束时间" -// @Param name query string false "审核人" -// @Param remark query string false "不通过原因" -// @Param storeIDs query string false "门店ID列表" -// @Param nameIDs query string false "id列表对象,当前指skuname id" -// @Param statuss query string false "审核状态" -// @Param types query string false "改价类型,1是普通改价,2是关注" -// @Param keyword query string false "关键字" -// @Param marketManPhone query string false "市场负责人电话" -// @Param cityName query string false "城市名" -// @Param offset query int false "门店列表起始序号(以0开始,缺省为0)" -// @Param pageSize query int false "门店列表页大小(缺省为50,-1表示全部)" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /GetStoreSkuAudit [get] -func (c *StoreSkuController) GetStoreSkuAudit() { - c.callGetStoreSkuAudit(func(params *tStoreSkuGetStoreSkuAuditParams) (retVal interface{}, errCode string, err error) { - var ( - storeIDs, nameIDs, statuss, types []int - ) - if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.NameIDs, &nameIDs, params.Statuss, &statuss, params.Types, &types); err != nil { - return retVal, "", err - } - retVal, err = cms.GetStoreSkuAudit(params.Ctx, storeIDs, nameIDs, nil, statuss, types, params.Name, params.Remark, params.Keyword, params.MarketManPhone, params.CityName, params.ApplyTimeStart, params.ApplyTimeEnd, params.AuditTimeStart, params.AuditTimeEnd, params.PageSize, params.Offset) - return retVal, "", err - }) -} - -// @Title 审核商品 -// @Description 审核商品 -// @Param token header string true "认证token" -// @Param payload formData string true "json数据,storeskuaudit对象" -// @Param status formData int false "审核标志,1通过,-1 不通过,2 预审核" -// @Param isAsync formData bool false "是否异步,缺省是同步" -// @Param isContinueWhenError formData bool false "单个同步失败是否继续,缺省false" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /StoreSkuPriceAudit [post] -func (c *StoreSkuController) StoreSkuPriceAudit() { - c.callStoreSkuPriceAudit(func(params *tStoreSkuStoreSkuPriceAuditParams) (retVal interface{}, errCode string, err error) { - var storeSkuAudits []*model.StoreSkuAudit - if err = jxutils.Strings2Objs(params.Payload, &storeSkuAudits); err != nil { - return retVal, "", err - } - retVal, hint, err := cms.StoreSkuPriceAudit(params.Ctx, storeSkuAudits, params.Status, params.IsAsync, params.IsContinueWhenError) - if hint != "" { - return hint, "", err - } else { - return retVal, "", err - } - }) -} - -// @Title 查看美团力荐或京东置顶商品 -// @Description 查看美团力荐或京东置顶商品 -// @Param token header string true "认证token" -// @Param vendorIDs formData string true "平台ids" -// @Param storeIDs formData string true "门店IDs" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /GetSpecialtyStoreSkus [post] -func (c *StoreSkuController) GetSpecialtyStoreSkus() { - c.callGetSpecialtyStoreSkus(func(params *tStoreSkuGetSpecialtyStoreSkusParams) (retVal interface{}, errCode string, err error) { - var ( - storeIDs, vendorIDs []int - ) - if err = jxutils.Strings2Objs(params.StoreIDs, &storeIDs, params.VendorIDs, &vendorIDs); err != nil { - return retVal, "", err - } - err = cms.GetSpecialtyStoreSkus(params.Ctx, storeIDs, vendorIDs) - return retVal, "", err - }) -} diff --git a/controllers/cms_user2.go b/controllers/cms_user2.go index 702ea35fa..a52dbf392 100644 --- a/controllers/cms_user2.go +++ b/controllers/cms_user2.go @@ -12,7 +12,6 @@ import ( "git.rosy.net.cn/jx-callback/business/jxutils/jsonerr" "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/business/model/dao" - "git.rosy.net.cn/jx-callback/business/partner/purchase/jx/localjx" "github.com/astaxie/beego" ) @@ -534,19 +533,3 @@ func (c *User2Controller) GetUserAgreement() { return retVal, "", err }) } - -// @Title 查询京西商城用户信息 -// @Description 查询京西商城用户信息 -// @Param token header string true "认证token" -// @Param keyword query string false "关键字" -// @Param offset query int false "结果起始序号(以0开始,缺省为0)" -// @Param pageSize query int false "结果页大小(缺省为50,-1表示全部)" -// @Success 200 {object} controllers.CallResult -// @Failure 200 {object} controllers.CallResult -// @router /GetJxShopUsers [get] -func (c *User2Controller) GetJxShopUsers() { - c.callGetJxShopUsers(func(params *tUser2GetJxShopUsersParams) (retVal interface{}, errCode string, err error) { - retVal, err = localjx.GetJxShopUsers(params.Ctx, params.Keyword, params.Offset, params.PageSize) - return retVal, "", err - }) -} diff --git a/controllers/job_controller.go b/controllers/job_controller.go index 86a6de697..0490ba4a3 100644 --- a/controllers/job_controller.go +++ b/controllers/job_controller.go @@ -82,3 +82,17 @@ func (c *JobController) GetJobDetail() { return retVal, "", err }) } + +// @Title 接任务 +// @Description 接任务 +// @Param token header string true "认证token" +// @Param jobID formData int true "jobID" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /AcceptJob [post] +func (c *JobController) AcceptJob() { + c.callAcceptJob(func(params *tJobAcceptJobParams) (retVal interface{}, errCode string, err error) { + + return retVal, "", err + }) +} diff --git a/controllers/order_controller.go b/controllers/order_controller.go index bfcd1074e..28156623b 100644 --- a/controllers/order_controller.go +++ b/controllers/order_controller.go @@ -11,8 +11,10 @@ type OrderController struct { // @Title 支付 // @Description 支付 // @Param token header string true "认证token" -// @Param userID query string true "用户ID" -// @Param roleList query string true "角色列表" +// @Param type formData int true "支付类型/账单类型" +// @Param price formData int true "支付金额" +// @Param payType formData int true "支付平台类型" +// @Param vendorPayType formData string true "平台支付类型" // @Success 200 {object} controllers.CallResult // @Failure 200 {object} controllers.CallResult // @router /Pay [post] diff --git a/globals/beegodb/beegodb.go b/globals/beegodb/beegodb.go index 344a424ff..81f6516af 100644 --- a/globals/beegodb/beegodb.go +++ b/globals/beegodb/beegodb.go @@ -13,12 +13,14 @@ func Init() { //用户 orm.RegisterModel(&model.AuthBind{}, &model.User{}) + orm.RegisterModel(&model.UserMember{}) //账单 orm.RegisterModel(&model.UserBill{}, &model.BillIncome{}, &model.BillExpend{}) //支付订单 orm.RegisterModel(&model.Order{}) - //发布任务 + //任务 orm.RegisterModel(&model.Job{}, &model.JobCategory{}, &model.JobStep{}) + orm.RegisterModel(&model.JobOrder{}) orm.RegisterModel(&model.NewConfig{}, &legacymodel.Config{}) // create table diff --git a/main.go b/main.go index b00e64e88..ca0137693 100644 --- a/main.go +++ b/main.go @@ -24,7 +24,6 @@ import ( _ "git.rosy.net.cn/jx-callback/business/partner/purchase/ebai" _ "git.rosy.net.cn/jx-callback/business/partner/purchase/jd" - _ "git.rosy.net.cn/jx-callback/business/partner/purchase/jx" _ "git.rosy.net.cn/jx-callback/business/partner/purchase/mtwm" _ "git.rosy.net.cn/jx-callback/business/partner/purchase/weimob/wsc" diff --git a/routers/commentsRouter_controllers.go b/routers/commentsRouter_controllers.go index a4c3d4cd1..779b75c2a 100644 --- a/routers/commentsRouter_controllers.go +++ b/routers/commentsRouter_controllers.go @@ -151,6 +151,15 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:JobController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:JobController"], + beego.ControllerComments{ + Method: "AcceptJob", + Router: `/AcceptJob`, + AllowHTTPMethods: []string{"post"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:JobController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:JobController"], beego.ControllerComments{ Method: "GetJobCategories", @@ -682,15 +691,6 @@ func init() { Filters: nil, Params: nil}) - beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:User2Controller"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:User2Controller"], - beego.ControllerComments{ - Method: "GetJxShopUsers", - Router: `/GetJxShopUsers`, - AllowHTTPMethods: []string{"get"}, - MethodParams: param.Make(), - Filters: nil, - Params: nil}) - beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:User2Controller"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:User2Controller"], beego.ControllerComments{ Method: "GetMyJxStoreList", diff --git a/routers/router.go b/routers/router.go index 4201623ed..d34824c2a 100644 --- a/routers/router.go +++ b/routers/router.go @@ -16,11 +16,6 @@ import ( func init() { ns := beego.NewNamespace("/v2", - beego.NSNamespace("/store/sku", - beego.NSInclude( - &controllers.StoreSkuController{}, - ), - ), beego.NSNamespace("/task", beego.NSInclude( &controllers.TaskController{},