From bbca52e1c5ebb48bff746e4ecc131311c1c803cc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=A4=A7=E8=82=A5?= <4602058@qq.com>
Date: Fri, 17 Jul 2020 16:28:17 +0800
Subject: [PATCH 1/2] =?UTF-8?q?202007171628=E6=9B=B4=E6=96=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
application/admin/controller/faqueue/Log.php | 35 +
application/admin/controller/shopro/Area.php | 51 +
.../admin/controller/shopro/Category.php | 194 ++
.../admin/controller/shopro/Config.php | 289 +++
.../admin/controller/shopro/Coupons.php | 45 +
.../admin/controller/shopro/Dashboard.php | 125 +
.../admin/controller/shopro/Decorate.php | 574 +++++
application/admin/controller/shopro/Faq.php | 35 +
.../admin/controller/shopro/Feedback.php | 76 +
application/admin/controller/shopro/Goods.php | 528 ++++
.../admin/controller/shopro/GoodsComment.php | 78 +
.../admin/controller/shopro/GoodsService.php | 48 +
.../admin/controller/shopro/GoodsSku.php | 35 +
.../admin/controller/shopro/GoodsSkuPrice.php | 35 +
application/admin/controller/shopro/Link.php | 90 +
.../admin/controller/shopro/Notification.php | 229 ++
.../admin/controller/shopro/Richtext.php | 47 +
.../admin/controller/shopro/UserFake.php | 101 +
.../controller/shopro/UserWalletApply.php | 70 +
.../admin/controller/shopro/Wechat.php | 168 ++
.../controller/shopro/activity/Activity.php | 450 ++++
.../shopro/activity/ActivitySkuPrice.php | 35 +
.../controller/shopro/activity/Groupon.php | 201 ++
.../admin/controller/shopro/app/Live.php | 132 +
.../admin/controller/shopro/app/ScoreShop.php | 307 +++
.../controller/shopro/dispatch/Dispatch.php | 114 +
.../controller/shopro/dispatch/Express.php | 287 +++
.../admin/controller/shopro/order/Order.php | 614 +++++
.../controller/shopro/order/OrderItem.php | 38 +
application/admin/lang/zh-cn/faqueue/log.php | 9 +
.../lang/zh-cn/shopro/activity/activity.php | 14 +
.../shopro/activity/activity_sku_price.php | 12 +
.../lang/zh-cn/shopro/activity/groupon.php | 16 +
.../admin/lang/zh-cn/shopro/app/live.php | 23 +
.../lang/zh-cn/shopro/app/score_shop.php | 9 +
application/admin/lang/zh-cn/shopro/area.php | 7 +
.../admin/lang/zh-cn/shopro/category.php | 13 +
.../admin/lang/zh-cn/shopro/config.php | 67 +
.../admin/lang/zh-cn/shopro/coupons.php | 16 +
.../admin/lang/zh-cn/shopro/decorate.php | 19 +
.../lang/zh-cn/shopro/dispatch/dispatch.php | 14 +
.../lang/zh-cn/shopro/dispatch/express.php | 18 +
application/admin/lang/zh-cn/shopro/faq.php | 9 +
.../admin/lang/zh-cn/shopro/feedback.php | 16 +
application/admin/lang/zh-cn/shopro/goods.php | 35 +
.../admin/lang/zh-cn/shopro/goods_comment.php | 26 +
.../admin/lang/zh-cn/shopro/goods_service.php | 9 +
.../admin/lang/zh-cn/shopro/goods_sku.php | 8 +
.../lang/zh-cn/shopro/goods_sku_price.php | 15 +
.../admin/lang/zh-cn/shopro/goodsservice.php | 7 +
application/admin/lang/zh-cn/shopro/link.php | 10 +
.../admin/lang/zh-cn/shopro/notification.php | 13 +
.../lang/zh-cn/shopro/notification/config.php | 12 +
.../admin/lang/zh-cn/shopro/order/order.php | 51 +
.../lang/zh-cn/shopro/order/order_item.php | 45 +
.../lang/zh-cn/shopro/order/refund_log.php | 20 +
.../admin/lang/zh-cn/shopro/richtext.php | 9 +
.../admin/lang/zh-cn/shopro/user_fake.php | 6 +
.../lang/zh-cn/shopro/user_wallet_apply.php | 20 +
.../admin/lang/zh-cn/shopro/wechat.php | 10 +
.../admin/lang/zh-cn/shopro/wechat/fans.php | 14 +
application/admin/model/faqueue/Log.php | 50 +
application/admin/model/shopro/Area.php | 46 +
application/admin/model/shopro/Category.php | 94 +
application/admin/model/shopro/Config.php | 183 ++
application/admin/model/shopro/Coupons.php | 48 +
application/admin/model/shopro/Decorate.php | 69 +
.../admin/model/shopro/DecorateContent.php | 21 +
.../admin/model/shopro/DecoratePage.php | 23 +
application/admin/model/shopro/Faq.php | 40 +
application/admin/model/shopro/Feedback.php | 53 +
application/admin/model/shopro/Goods.php | 134 +
.../admin/model/shopro/GoodsComment.php | 76 +
.../admin/model/shopro/GoodsService.php | 40 +
application/admin/model/shopro/GoodsSku.php | 41 +
.../admin/model/shopro/GoodsSkuPrice.php | 57 +
application/admin/model/shopro/Link.php | 54 +
.../admin/model/shopro/Notification.php | 48 +
application/admin/model/shopro/Richtext.php | 40 +
application/admin/model/shopro/UserFake.php | 40 +
.../admin/model/shopro/UserWalletApply.php | 63 +
application/admin/model/shopro/Wechat.php | 40 +
application/admin/model/shopro/WechatFans.php | 60 +
.../admin/model/shopro/activity/Activity.php | 115 +
.../shopro/activity/ActivitySkuPrice.php | 40 +
.../admin/model/shopro/activity/Groupon.php | 63 +
.../model/shopro/activity/GrouponLog.php | 59 +
application/admin/model/shopro/app/Live.php | 92 +
.../admin/model/shopro/app/ScoreSkuPrice.php | 40 +
.../admin/model/shopro/dispatch/Dispatch.php | 49 +
.../admin/model/shopro/dispatch/Express.php | 57 +
.../model/shopro/notification/Config.php | 53 +
.../admin/model/shopro/order/Order.php | 124 +
.../admin/model/shopro/order/OrderAction.php | 30 +
.../admin/model/shopro/order/OrderItem.php | 134 +
.../admin/model/shopro/order/RefundLog.php | 58 +
application/admin/validate/shopro/Area.php | 27 +
.../admin/validate/shopro/Category.php | 27 +
application/admin/validate/shopro/Config.php | 27 +
application/admin/validate/shopro/Coupons.php | 27 +
.../admin/validate/shopro/Decorate.php | 27 +
application/admin/validate/shopro/Faq.php | 27 +
.../admin/validate/shopro/Feedback.php | 27 +
application/admin/validate/shopro/Goods.php | 57 +
.../admin/validate/shopro/GoodsComment.php | 27 +
.../admin/validate/shopro/GoodsService.php | 24 +
.../admin/validate/shopro/GoodsSku.php | 27 +
.../admin/validate/shopro/GoodsSkuPrice.php | 27 +
application/admin/validate/shopro/Link.php | 27 +
.../admin/validate/shopro/Notification.php | 27 +
.../validate/shopro/Notification_config.php | 27 +
.../admin/validate/shopro/Richtext.php | 27 +
.../admin/validate/shopro/UserFake.php | 27 +
.../admin/validate/shopro/UserWalletApply.php | 27 +
application/admin/validate/shopro/Wechat.php | 27 +
.../validate/shopro/activity/Activity.php | 27 +
.../shopro/activity/ActivitySkuPrice.php | 27 +
.../validate/shopro/activity/Groupon.php | 27 +
.../admin/validate/shopro/app/Live.php | 27 +
.../validate/shopro/dispatch/Dispatch.php | 27 +
.../validate/shopro/dispatch/Express.php | 27 +
.../validate/shopro/notification/Config.php | 27 +
.../admin/validate/shopro/order/Order.php | 27 +
.../admin/validate/shopro/order/OrderItem.php | 27 +
.../admin/validate/shopro/wechat/Fans.php | 27 +
application/admin/view/faqueue/log/index.html | 22 +
.../view/shopro/activity/activity/add.html | 249 ++
.../view/shopro/activity/activity/edit.html | 263 ++
.../view/shopro/activity/activity/index.html | 559 ++++
.../shopro/activity/activity/recyclebin.html | 25 +
.../view/shopro/activity/activity/select.html | 20 +
.../view/shopro/activity/activity/sku.html | 113 +
.../activity/activity_sku_price/add.html | 46 +
.../activity/activity_sku_price/edit.html | 46 +
.../activity/activity_sku_price/index.html | 35 +
.../activity_sku_price/recyclebin.html | 25 +
.../view/shopro/activity/groupon/add.html | 52 +
.../view/shopro/activity/groupon/detail.html | 201 ++
.../view/shopro/activity/groupon/edit.html | 52 +
.../view/shopro/activity/groupon/index.html | 435 ++++
.../admin/view/shopro/app/live/add.html | 94 +
.../admin/view/shopro/app/live/detail.html | 112 +
.../admin/view/shopro/app/live/edit.html | 94 +
.../admin/view/shopro/app/live/index.html | 36 +
.../view/shopro/app/live/recyclebin.html | 25 +
.../admin/view/shopro/app/live/select.html | 20 +
.../admin/view/shopro/app/score_shop/add.html | 213 ++
.../view/shopro/app/score_shop/edit.html | 205 ++
.../view/shopro/app/score_shop/index.html | 30 +
.../view/shopro/app/score_shop/select.html | 0
.../admin/view/shopro/app/score_shop/sku.html | 115 +
application/admin/view/shopro/area/add.html | 28 +
.../admin/view/shopro/area/area_select.html | 62 +
application/admin/view/shopro/area/edit.html | 28 +
application/admin/view/shopro/area/index.html | 35 +
.../admin/view/shopro/category/add.html | 74 +
.../admin/view/shopro/category/edit.html | 73 +
.../admin/view/shopro/category/index.html | 36 +
.../admin/view/shopro/category/select.html | 26 +
application/admin/view/shopro/config/add.html | 241 ++
.../admin/view/shopro/config/edit.html | 64 +
.../admin/view/shopro/config/index.html | 706 +++++
.../admin/view/shopro/config/platform.html | 618 +++++
.../admin/view/shopro/coupons/add.html | 64 +
.../admin/view/shopro/coupons/edit.html | 64 +
.../admin/view/shopro/coupons/index.html | 35 +
.../admin/view/shopro/coupons/recyclebin.html | 25 +
.../admin/view/shopro/coupons/select.html | 24 +
.../admin/view/shopro/dashboard/index.html | 772 ++++++
.../admin/view/shopro/decorate/add.html | 46 +
.../admin/view/shopro/decorate/custom.html | 275 ++
.../admin/view/shopro/decorate/designer.html | 307 +++
.../view/shopro/decorate/dodecorate.html | 2270 +++++++++++++++++
.../admin/view/shopro/decorate/edit.html | 47 +
.../admin/view/shopro/decorate/index.html | 45 +
.../admin/view/shopro/decorate/lists.html | 404 +++
.../view/shopro/decorate/recyclebin.html | 25 +
.../admin/view/shopro/decorate/select.html | 24 +
.../view/shopro/dispatch/dispatch/add.html | 50 +
.../view/shopro/dispatch/dispatch/edit.html | 37 +
.../view/shopro/dispatch/dispatch/index.html | 35 +
.../shopro/dispatch/dispatch/recyclebin.html | 25 +
.../view/shopro/dispatch/express/add.html | 121 +
.../view/shopro/dispatch/express/edit.html | 119 +
.../view/shopro/dispatch/express/index.html | 35 +
.../shopro/dispatch/express/recyclebin.html | 25 +
application/admin/view/shopro/faq/add.html | 22 +
application/admin/view/shopro/faq/edit.html | 22 +
application/admin/view/shopro/faq/index.html | 35 +
.../admin/view/shopro/faq/recyclebin.html | 25 +
.../admin/view/shopro/feedback/add.html | 66 +
.../admin/view/shopro/feedback/edit.html | 66 +
.../admin/view/shopro/feedback/index.html | 45 +
.../view/shopro/feedback/recyclebin.html | 25 +
application/admin/view/shopro/goods/add.html | 896 +++++++
application/admin/view/shopro/goods/edit.html | 896 +++++++
.../admin/view/shopro/goods/index.html | 419 +++
.../admin/view/shopro/goods/recyclebin.html | 25 +
.../admin/view/shopro/goods/select.html | 29 +
application/admin/view/shopro/goods/sku.html | 194 ++
.../admin/view/shopro/goods/skuedit.html | 144 ++
.../admin/view/shopro/goods_comment/add.html | 84 +
.../admin/view/shopro/goods_comment/edit.html | 73 +
.../view/shopro/goods_comment/index.html | 45 +
.../view/shopro/goods_comment/recyclebin.html | 25 +
.../admin/view/shopro/goods_service/add.html | 36 +
.../admin/view/shopro/goods_service/edit.html | 36 +
.../view/shopro/goods_service/index.html | 35 +
.../view/shopro/goods_service/recyclebin.html | 25 +
.../admin/view/shopro/goods_sku/add.html | 34 +
.../admin/view/shopro/goods_sku/edit.html | 34 +
.../admin/view/shopro/goods_sku/index.html | 35 +
.../view/shopro/goods_sku_price/add.html | 78 +
.../view/shopro/goods_sku_price/edit.html | 78 +
.../view/shopro/goods_sku_price/index.html | 35 +
.../shopro/goods_sku_price/recyclebin.html | 25 +
application/admin/view/shopro/link/add.html | 28 +
application/admin/view/shopro/link/edit.html | 28 +
application/admin/view/shopro/link/index.html | 42 +
.../admin/view/shopro/link/recyclebin.html | 25 +
.../admin/view/shopro/link/select.html | 36 +
.../view/shopro/notification/config.html | 443 ++++
.../admin/view/shopro/notification/edit.html | 40 +
.../admin/view/shopro/notification/index.html | 35 +
.../view/shopro/notification/recyclebin.html | 25 +
.../admin/view/shopro/order/order/add.html | 236 ++
.../admin/view/shopro/order/order/detail.html | 1097 ++++++++
.../admin/view/shopro/order/order/edit.html | 218 ++
.../admin/view/shopro/order/order/index.html | 934 +++++++
.../view/shopro/order/order/recyclebin.html | 25 +
.../view/shopro/order/order_item/add.html | 180 ++
.../view/shopro/order/order_item/edit.html | 180 ++
.../view/shopro/order/order_item/index.html | 46 +
.../shopro/order/order_item/recyclebin.html | 25 +
.../admin/view/shopro/richtext/add.html | 22 +
.../admin/view/shopro/richtext/edit.html | 22 +
.../admin/view/shopro/richtext/index.html | 35 +
.../view/shopro/richtext/recyclebin.html | 25 +
.../admin/view/shopro/richtext/select.html | 35 +
.../admin/view/shopro/user_fake/add.html | 30 +
.../admin/view/shopro/user_fake/edit.html | 30 +
.../admin/view/shopro/user_fake/index.html | 35 +
.../view/shopro/user_wallet_apply/add.html | 82 +
.../view/shopro/user_wallet_apply/edit.html | 82 +
.../view/shopro/user_wallet_apply/index.html | 50 +
.../shopro/user_wallet_apply/recyclebin.html | 25 +
application/admin/view/shopro/wechat/add.html | 28 +
.../admin/view/shopro/wechat/edit.html | 28 +
.../admin/view/shopro/wechat/fans.html | 189 ++
.../admin/view/shopro/wechat/index.html | 35 +
.../admin/view/shopro/wechat/menu.html | 364 +++
application/database.php | 2 +-
application/extra/addons.php | 4 +
public/{admin.php => LyIKhAFtnm.php} | 0
public/assets/js/backend/faqueue/log.js | 60 +
.../js/backend/shopro/activity/activity.js | 915 +++++++
.../shopro/activity/activity_sku_price.js | 116 +
.../js/backend/shopro/activity/groupon.js | 397 +++
public/assets/js/backend/shopro/app/live.js | 262 ++
.../js/backend/shopro/app/score_shop.js | 444 ++++
public/assets/js/backend/shopro/area.js | 232 ++
public/assets/js/backend/shopro/category.js | 227 ++
public/assets/js/backend/shopro/config.js | 139 +
public/assets/js/backend/shopro/coupons.js | 208 ++
public/assets/js/backend/shopro/dashboard.js | 814 ++++++
public/assets/js/backend/shopro/decorate.js | 1646 ++++++++++++
.../js/backend/shopro/dispatch/dispatch.js | 120 +
.../js/backend/shopro/dispatch/express.js | 600 +++++
public/assets/js/backend/shopro/faq.js | 113 +
public/assets/js/backend/shopro/feedback.js | 117 +
public/assets/js/backend/shopro/goods.js | 1043 ++++++++
.../assets/js/backend/shopro/goods_comment.js | 124 +
.../assets/js/backend/shopro/goods_service.js | 114 +
public/assets/js/backend/shopro/goods_sku.js | 53 +
.../js/backend/shopro/goods_sku_price.js | 120 +
.../assets/js/backend/shopro/goodsservice.js | 114 +
public/assets/js/backend/shopro/link.js | 307 +++
.../assets/js/backend/shopro/notification.js | 242 ++
.../assets/js/backend/shopro/order/order.js | 658 +++++
.../js/backend/shopro/order/order_item.js | 231 ++
public/assets/js/backend/shopro/richtext.js | 177 ++
public/assets/js/backend/shopro/user_fake.js | 51 +
.../js/backend/shopro/user_wallet_apply.js | 183 ++
public/assets/js/backend/shopro/wechat.js | 465 ++++
public/nginx.htaccess | 5 +
285 files changed, 37248 insertions(+), 1 deletion(-)
create mode 100644 application/admin/controller/faqueue/Log.php
create mode 100644 application/admin/controller/shopro/Area.php
create mode 100644 application/admin/controller/shopro/Category.php
create mode 100644 application/admin/controller/shopro/Config.php
create mode 100644 application/admin/controller/shopro/Coupons.php
create mode 100644 application/admin/controller/shopro/Dashboard.php
create mode 100644 application/admin/controller/shopro/Decorate.php
create mode 100644 application/admin/controller/shopro/Faq.php
create mode 100644 application/admin/controller/shopro/Feedback.php
create mode 100644 application/admin/controller/shopro/Goods.php
create mode 100644 application/admin/controller/shopro/GoodsComment.php
create mode 100644 application/admin/controller/shopro/GoodsService.php
create mode 100644 application/admin/controller/shopro/GoodsSku.php
create mode 100644 application/admin/controller/shopro/GoodsSkuPrice.php
create mode 100644 application/admin/controller/shopro/Link.php
create mode 100644 application/admin/controller/shopro/Notification.php
create mode 100644 application/admin/controller/shopro/Richtext.php
create mode 100644 application/admin/controller/shopro/UserFake.php
create mode 100644 application/admin/controller/shopro/UserWalletApply.php
create mode 100644 application/admin/controller/shopro/Wechat.php
create mode 100644 application/admin/controller/shopro/activity/Activity.php
create mode 100644 application/admin/controller/shopro/activity/ActivitySkuPrice.php
create mode 100644 application/admin/controller/shopro/activity/Groupon.php
create mode 100644 application/admin/controller/shopro/app/Live.php
create mode 100644 application/admin/controller/shopro/app/ScoreShop.php
create mode 100644 application/admin/controller/shopro/dispatch/Dispatch.php
create mode 100644 application/admin/controller/shopro/dispatch/Express.php
create mode 100644 application/admin/controller/shopro/order/Order.php
create mode 100644 application/admin/controller/shopro/order/OrderItem.php
create mode 100644 application/admin/lang/zh-cn/faqueue/log.php
create mode 100644 application/admin/lang/zh-cn/shopro/activity/activity.php
create mode 100644 application/admin/lang/zh-cn/shopro/activity/activity_sku_price.php
create mode 100644 application/admin/lang/zh-cn/shopro/activity/groupon.php
create mode 100644 application/admin/lang/zh-cn/shopro/app/live.php
create mode 100644 application/admin/lang/zh-cn/shopro/app/score_shop.php
create mode 100644 application/admin/lang/zh-cn/shopro/area.php
create mode 100644 application/admin/lang/zh-cn/shopro/category.php
create mode 100644 application/admin/lang/zh-cn/shopro/config.php
create mode 100644 application/admin/lang/zh-cn/shopro/coupons.php
create mode 100644 application/admin/lang/zh-cn/shopro/decorate.php
create mode 100644 application/admin/lang/zh-cn/shopro/dispatch/dispatch.php
create mode 100644 application/admin/lang/zh-cn/shopro/dispatch/express.php
create mode 100644 application/admin/lang/zh-cn/shopro/faq.php
create mode 100644 application/admin/lang/zh-cn/shopro/feedback.php
create mode 100644 application/admin/lang/zh-cn/shopro/goods.php
create mode 100644 application/admin/lang/zh-cn/shopro/goods_comment.php
create mode 100644 application/admin/lang/zh-cn/shopro/goods_service.php
create mode 100644 application/admin/lang/zh-cn/shopro/goods_sku.php
create mode 100644 application/admin/lang/zh-cn/shopro/goods_sku_price.php
create mode 100644 application/admin/lang/zh-cn/shopro/goodsservice.php
create mode 100644 application/admin/lang/zh-cn/shopro/link.php
create mode 100644 application/admin/lang/zh-cn/shopro/notification.php
create mode 100644 application/admin/lang/zh-cn/shopro/notification/config.php
create mode 100644 application/admin/lang/zh-cn/shopro/order/order.php
create mode 100644 application/admin/lang/zh-cn/shopro/order/order_item.php
create mode 100644 application/admin/lang/zh-cn/shopro/order/refund_log.php
create mode 100644 application/admin/lang/zh-cn/shopro/richtext.php
create mode 100644 application/admin/lang/zh-cn/shopro/user_fake.php
create mode 100644 application/admin/lang/zh-cn/shopro/user_wallet_apply.php
create mode 100644 application/admin/lang/zh-cn/shopro/wechat.php
create mode 100644 application/admin/lang/zh-cn/shopro/wechat/fans.php
create mode 100644 application/admin/model/faqueue/Log.php
create mode 100644 application/admin/model/shopro/Area.php
create mode 100644 application/admin/model/shopro/Category.php
create mode 100644 application/admin/model/shopro/Config.php
create mode 100644 application/admin/model/shopro/Coupons.php
create mode 100644 application/admin/model/shopro/Decorate.php
create mode 100644 application/admin/model/shopro/DecorateContent.php
create mode 100644 application/admin/model/shopro/DecoratePage.php
create mode 100644 application/admin/model/shopro/Faq.php
create mode 100644 application/admin/model/shopro/Feedback.php
create mode 100644 application/admin/model/shopro/Goods.php
create mode 100644 application/admin/model/shopro/GoodsComment.php
create mode 100644 application/admin/model/shopro/GoodsService.php
create mode 100644 application/admin/model/shopro/GoodsSku.php
create mode 100644 application/admin/model/shopro/GoodsSkuPrice.php
create mode 100644 application/admin/model/shopro/Link.php
create mode 100644 application/admin/model/shopro/Notification.php
create mode 100644 application/admin/model/shopro/Richtext.php
create mode 100644 application/admin/model/shopro/UserFake.php
create mode 100644 application/admin/model/shopro/UserWalletApply.php
create mode 100644 application/admin/model/shopro/Wechat.php
create mode 100644 application/admin/model/shopro/WechatFans.php
create mode 100644 application/admin/model/shopro/activity/Activity.php
create mode 100644 application/admin/model/shopro/activity/ActivitySkuPrice.php
create mode 100644 application/admin/model/shopro/activity/Groupon.php
create mode 100644 application/admin/model/shopro/activity/GrouponLog.php
create mode 100644 application/admin/model/shopro/app/Live.php
create mode 100644 application/admin/model/shopro/app/ScoreSkuPrice.php
create mode 100644 application/admin/model/shopro/dispatch/Dispatch.php
create mode 100644 application/admin/model/shopro/dispatch/Express.php
create mode 100644 application/admin/model/shopro/notification/Config.php
create mode 100644 application/admin/model/shopro/order/Order.php
create mode 100644 application/admin/model/shopro/order/OrderAction.php
create mode 100644 application/admin/model/shopro/order/OrderItem.php
create mode 100644 application/admin/model/shopro/order/RefundLog.php
create mode 100644 application/admin/validate/shopro/Area.php
create mode 100644 application/admin/validate/shopro/Category.php
create mode 100644 application/admin/validate/shopro/Config.php
create mode 100644 application/admin/validate/shopro/Coupons.php
create mode 100644 application/admin/validate/shopro/Decorate.php
create mode 100644 application/admin/validate/shopro/Faq.php
create mode 100644 application/admin/validate/shopro/Feedback.php
create mode 100644 application/admin/validate/shopro/Goods.php
create mode 100644 application/admin/validate/shopro/GoodsComment.php
create mode 100644 application/admin/validate/shopro/GoodsService.php
create mode 100644 application/admin/validate/shopro/GoodsSku.php
create mode 100644 application/admin/validate/shopro/GoodsSkuPrice.php
create mode 100644 application/admin/validate/shopro/Link.php
create mode 100644 application/admin/validate/shopro/Notification.php
create mode 100644 application/admin/validate/shopro/Notification_config.php
create mode 100644 application/admin/validate/shopro/Richtext.php
create mode 100644 application/admin/validate/shopro/UserFake.php
create mode 100644 application/admin/validate/shopro/UserWalletApply.php
create mode 100644 application/admin/validate/shopro/Wechat.php
create mode 100644 application/admin/validate/shopro/activity/Activity.php
create mode 100644 application/admin/validate/shopro/activity/ActivitySkuPrice.php
create mode 100644 application/admin/validate/shopro/activity/Groupon.php
create mode 100644 application/admin/validate/shopro/app/Live.php
create mode 100644 application/admin/validate/shopro/dispatch/Dispatch.php
create mode 100644 application/admin/validate/shopro/dispatch/Express.php
create mode 100644 application/admin/validate/shopro/notification/Config.php
create mode 100644 application/admin/validate/shopro/order/Order.php
create mode 100644 application/admin/validate/shopro/order/OrderItem.php
create mode 100644 application/admin/validate/shopro/wechat/Fans.php
create mode 100644 application/admin/view/faqueue/log/index.html
create mode 100644 application/admin/view/shopro/activity/activity/add.html
create mode 100644 application/admin/view/shopro/activity/activity/edit.html
create mode 100644 application/admin/view/shopro/activity/activity/index.html
create mode 100644 application/admin/view/shopro/activity/activity/recyclebin.html
create mode 100644 application/admin/view/shopro/activity/activity/select.html
create mode 100644 application/admin/view/shopro/activity/activity/sku.html
create mode 100644 application/admin/view/shopro/activity/activity_sku_price/add.html
create mode 100644 application/admin/view/shopro/activity/activity_sku_price/edit.html
create mode 100644 application/admin/view/shopro/activity/activity_sku_price/index.html
create mode 100644 application/admin/view/shopro/activity/activity_sku_price/recyclebin.html
create mode 100644 application/admin/view/shopro/activity/groupon/add.html
create mode 100644 application/admin/view/shopro/activity/groupon/detail.html
create mode 100644 application/admin/view/shopro/activity/groupon/edit.html
create mode 100644 application/admin/view/shopro/activity/groupon/index.html
create mode 100644 application/admin/view/shopro/app/live/add.html
create mode 100644 application/admin/view/shopro/app/live/detail.html
create mode 100644 application/admin/view/shopro/app/live/edit.html
create mode 100644 application/admin/view/shopro/app/live/index.html
create mode 100644 application/admin/view/shopro/app/live/recyclebin.html
create mode 100644 application/admin/view/shopro/app/live/select.html
create mode 100644 application/admin/view/shopro/app/score_shop/add.html
create mode 100644 application/admin/view/shopro/app/score_shop/edit.html
create mode 100644 application/admin/view/shopro/app/score_shop/index.html
create mode 100644 application/admin/view/shopro/app/score_shop/select.html
create mode 100644 application/admin/view/shopro/app/score_shop/sku.html
create mode 100644 application/admin/view/shopro/area/add.html
create mode 100644 application/admin/view/shopro/area/area_select.html
create mode 100644 application/admin/view/shopro/area/edit.html
create mode 100644 application/admin/view/shopro/area/index.html
create mode 100644 application/admin/view/shopro/category/add.html
create mode 100644 application/admin/view/shopro/category/edit.html
create mode 100644 application/admin/view/shopro/category/index.html
create mode 100644 application/admin/view/shopro/category/select.html
create mode 100644 application/admin/view/shopro/config/add.html
create mode 100644 application/admin/view/shopro/config/edit.html
create mode 100644 application/admin/view/shopro/config/index.html
create mode 100644 application/admin/view/shopro/config/platform.html
create mode 100644 application/admin/view/shopro/coupons/add.html
create mode 100644 application/admin/view/shopro/coupons/edit.html
create mode 100644 application/admin/view/shopro/coupons/index.html
create mode 100644 application/admin/view/shopro/coupons/recyclebin.html
create mode 100644 application/admin/view/shopro/coupons/select.html
create mode 100644 application/admin/view/shopro/dashboard/index.html
create mode 100644 application/admin/view/shopro/decorate/add.html
create mode 100644 application/admin/view/shopro/decorate/custom.html
create mode 100644 application/admin/view/shopro/decorate/designer.html
create mode 100644 application/admin/view/shopro/decorate/dodecorate.html
create mode 100644 application/admin/view/shopro/decorate/edit.html
create mode 100644 application/admin/view/shopro/decorate/index.html
create mode 100644 application/admin/view/shopro/decorate/lists.html
create mode 100644 application/admin/view/shopro/decorate/recyclebin.html
create mode 100644 application/admin/view/shopro/decorate/select.html
create mode 100644 application/admin/view/shopro/dispatch/dispatch/add.html
create mode 100644 application/admin/view/shopro/dispatch/dispatch/edit.html
create mode 100644 application/admin/view/shopro/dispatch/dispatch/index.html
create mode 100644 application/admin/view/shopro/dispatch/dispatch/recyclebin.html
create mode 100644 application/admin/view/shopro/dispatch/express/add.html
create mode 100644 application/admin/view/shopro/dispatch/express/edit.html
create mode 100644 application/admin/view/shopro/dispatch/express/index.html
create mode 100644 application/admin/view/shopro/dispatch/express/recyclebin.html
create mode 100644 application/admin/view/shopro/faq/add.html
create mode 100644 application/admin/view/shopro/faq/edit.html
create mode 100644 application/admin/view/shopro/faq/index.html
create mode 100644 application/admin/view/shopro/faq/recyclebin.html
create mode 100644 application/admin/view/shopro/feedback/add.html
create mode 100644 application/admin/view/shopro/feedback/edit.html
create mode 100644 application/admin/view/shopro/feedback/index.html
create mode 100644 application/admin/view/shopro/feedback/recyclebin.html
create mode 100644 application/admin/view/shopro/goods/add.html
create mode 100644 application/admin/view/shopro/goods/edit.html
create mode 100644 application/admin/view/shopro/goods/index.html
create mode 100644 application/admin/view/shopro/goods/recyclebin.html
create mode 100644 application/admin/view/shopro/goods/select.html
create mode 100644 application/admin/view/shopro/goods/sku.html
create mode 100644 application/admin/view/shopro/goods/skuedit.html
create mode 100644 application/admin/view/shopro/goods_comment/add.html
create mode 100644 application/admin/view/shopro/goods_comment/edit.html
create mode 100644 application/admin/view/shopro/goods_comment/index.html
create mode 100644 application/admin/view/shopro/goods_comment/recyclebin.html
create mode 100644 application/admin/view/shopro/goods_service/add.html
create mode 100644 application/admin/view/shopro/goods_service/edit.html
create mode 100644 application/admin/view/shopro/goods_service/index.html
create mode 100644 application/admin/view/shopro/goods_service/recyclebin.html
create mode 100644 application/admin/view/shopro/goods_sku/add.html
create mode 100644 application/admin/view/shopro/goods_sku/edit.html
create mode 100644 application/admin/view/shopro/goods_sku/index.html
create mode 100644 application/admin/view/shopro/goods_sku_price/add.html
create mode 100644 application/admin/view/shopro/goods_sku_price/edit.html
create mode 100644 application/admin/view/shopro/goods_sku_price/index.html
create mode 100644 application/admin/view/shopro/goods_sku_price/recyclebin.html
create mode 100644 application/admin/view/shopro/link/add.html
create mode 100644 application/admin/view/shopro/link/edit.html
create mode 100644 application/admin/view/shopro/link/index.html
create mode 100644 application/admin/view/shopro/link/recyclebin.html
create mode 100644 application/admin/view/shopro/link/select.html
create mode 100644 application/admin/view/shopro/notification/config.html
create mode 100644 application/admin/view/shopro/notification/edit.html
create mode 100644 application/admin/view/shopro/notification/index.html
create mode 100644 application/admin/view/shopro/notification/recyclebin.html
create mode 100644 application/admin/view/shopro/order/order/add.html
create mode 100644 application/admin/view/shopro/order/order/detail.html
create mode 100644 application/admin/view/shopro/order/order/edit.html
create mode 100644 application/admin/view/shopro/order/order/index.html
create mode 100644 application/admin/view/shopro/order/order/recyclebin.html
create mode 100644 application/admin/view/shopro/order/order_item/add.html
create mode 100644 application/admin/view/shopro/order/order_item/edit.html
create mode 100644 application/admin/view/shopro/order/order_item/index.html
create mode 100644 application/admin/view/shopro/order/order_item/recyclebin.html
create mode 100644 application/admin/view/shopro/richtext/add.html
create mode 100644 application/admin/view/shopro/richtext/edit.html
create mode 100644 application/admin/view/shopro/richtext/index.html
create mode 100644 application/admin/view/shopro/richtext/recyclebin.html
create mode 100644 application/admin/view/shopro/richtext/select.html
create mode 100644 application/admin/view/shopro/user_fake/add.html
create mode 100644 application/admin/view/shopro/user_fake/edit.html
create mode 100644 application/admin/view/shopro/user_fake/index.html
create mode 100644 application/admin/view/shopro/user_wallet_apply/add.html
create mode 100644 application/admin/view/shopro/user_wallet_apply/edit.html
create mode 100644 application/admin/view/shopro/user_wallet_apply/index.html
create mode 100644 application/admin/view/shopro/user_wallet_apply/recyclebin.html
create mode 100644 application/admin/view/shopro/wechat/add.html
create mode 100644 application/admin/view/shopro/wechat/edit.html
create mode 100644 application/admin/view/shopro/wechat/fans.html
create mode 100644 application/admin/view/shopro/wechat/index.html
create mode 100644 application/admin/view/shopro/wechat/menu.html
rename public/{admin.php => LyIKhAFtnm.php} (100%)
create mode 100644 public/assets/js/backend/faqueue/log.js
create mode 100644 public/assets/js/backend/shopro/activity/activity.js
create mode 100644 public/assets/js/backend/shopro/activity/activity_sku_price.js
create mode 100644 public/assets/js/backend/shopro/activity/groupon.js
create mode 100644 public/assets/js/backend/shopro/app/live.js
create mode 100644 public/assets/js/backend/shopro/app/score_shop.js
create mode 100644 public/assets/js/backend/shopro/area.js
create mode 100644 public/assets/js/backend/shopro/category.js
create mode 100644 public/assets/js/backend/shopro/config.js
create mode 100644 public/assets/js/backend/shopro/coupons.js
create mode 100644 public/assets/js/backend/shopro/dashboard.js
create mode 100644 public/assets/js/backend/shopro/decorate.js
create mode 100644 public/assets/js/backend/shopro/dispatch/dispatch.js
create mode 100644 public/assets/js/backend/shopro/dispatch/express.js
create mode 100644 public/assets/js/backend/shopro/faq.js
create mode 100644 public/assets/js/backend/shopro/feedback.js
create mode 100644 public/assets/js/backend/shopro/goods.js
create mode 100644 public/assets/js/backend/shopro/goods_comment.js
create mode 100644 public/assets/js/backend/shopro/goods_service.js
create mode 100644 public/assets/js/backend/shopro/goods_sku.js
create mode 100644 public/assets/js/backend/shopro/goods_sku_price.js
create mode 100644 public/assets/js/backend/shopro/goodsservice.js
create mode 100644 public/assets/js/backend/shopro/link.js
create mode 100644 public/assets/js/backend/shopro/notification.js
create mode 100644 public/assets/js/backend/shopro/order/order.js
create mode 100644 public/assets/js/backend/shopro/order/order_item.js
create mode 100644 public/assets/js/backend/shopro/richtext.js
create mode 100644 public/assets/js/backend/shopro/user_fake.js
create mode 100644 public/assets/js/backend/shopro/user_wallet_apply.js
create mode 100644 public/assets/js/backend/shopro/wechat.js
create mode 100644 public/nginx.htaccess
diff --git a/application/admin/controller/faqueue/Log.php b/application/admin/controller/faqueue/Log.php
new file mode 100644
index 000000000..150afec08
--- /dev/null
+++ b/application/admin/controller/faqueue/Log.php
@@ -0,0 +1,35 @@
+model = new \app\admin\model\faqueue\Log;
+
+ }
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+
+
+}
diff --git a/application/admin/controller/shopro/Area.php b/application/admin/controller/shopro/Area.php
new file mode 100644
index 000000000..c9d591f84
--- /dev/null
+++ b/application/admin/controller/shopro/Area.php
@@ -0,0 +1,51 @@
+model = new \app\admin\model\shopro\Area;
+
+ }
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+
+
+ public function getCascader() {
+ $area = cache('area-cascader');
+ if ($area) {
+ $area = json_decode($area, true);
+ } else {
+ $area = $this->model->with('children.children')->where('level', 1)->order('id asc')->select();
+ cache('area-cascader', json_encode($area), 86400); // 缓存一天
+ }
+
+ return $this->success('操作成功', null, $area);
+ }
+
+ public function area_select()
+ {
+ return $this->view->fetch();
+ }
+}
diff --git a/application/admin/controller/shopro/Category.php b/application/admin/controller/shopro/Category.php
new file mode 100644
index 000000000..96cd4a8fd
--- /dev/null
+++ b/application/admin/controller/shopro/Category.php
@@ -0,0 +1,194 @@
+系统配置->字典配置中添加
+ */
+class Category extends Backend
+{
+ /**
+ * @var \app\admin\model\shopro\Category
+ */
+ protected $model = null;
+ protected $categorylist = [];
+ protected $noNeedRight = ['selectpage', 'gettree'];
+
+ public function _initialize()
+ {
+ parent::_initialize();
+ $this->model = model('app\admin\model\shopro\Category');
+
+ $this->tree = Tree::instance();
+ $this->tree->init(collection($this->model->order('weigh desc,id desc')->select())->toArray(), 'pid');
+ $this->categorylist = $this->tree->getTreeList($this->tree->getTreeArray(0), 'name');
+ $categorydata = [0 => ['type' => 'all', 'name' => __('None')]];
+ foreach ($this->categorylist as $k => $v) {
+ $categorydata[$v['id']] = $v;
+ }
+ $typeList = CategoryModel::getTypeList();
+ $this->view->assign("flagList", $this->model->getFlagList());
+ $this->view->assign("typeList", $typeList);
+ $this->view->assign("parentList", $categorydata);
+ $this->assignconfig('typeList', $typeList);
+ }
+
+ /**
+ * 选择商品组
+ */
+ public function select()
+ {
+ if ($this->request->isAjax()) {
+ return $this->index();
+ }
+ return $this->view->fetch();
+ }
+
+ /**
+ * 查看
+ */
+ public function index()
+ {
+ //设置过滤方法
+ $this->request->filter(['strip_tags']);
+ if ($this->request->isAjax()) {
+ $search = $this->request->request("search");
+ $type = $this->request->request("type");
+
+ //构造父类select列表选项数据
+ $list = [];
+
+ foreach ($this->categorylist as $k => $v) {
+ if ($search) {
+ if ($v['type'] == $type && stripos($v['name'], $search) !== false || stripos($v['nickname'], $search) !== false) {
+ if ($type == "all" || $type == null) {
+ $list = $this->categorylist;
+ } else {
+ $list[] = $v;
+ }
+ }
+ } else {
+ if ($type == "all" || $type == null) {
+ $list = $this->categorylist;
+ } elseif ($v['type'] == $type) {
+ $list[] = $v;
+ }
+ }
+ }
+
+ $total = count($list);
+ $result = array("total" => $total, "rows" => $list);
+
+ return json($result);
+ }
+ return $this->view->fetch();
+ }
+
+ /**
+ * 编辑
+ */
+ public function edit($ids = null)
+ {
+ $row = $this->model->get($ids);
+ if (!$row) {
+ $this->error(__('No Results were found'));
+ }
+ $adminIds = $this->getDataLimitAdminIds();
+ if (is_array($adminIds)) {
+ if (!in_array($row[$this->dataLimitField], $adminIds)) {
+ $this->error(__('You have no permission'));
+ }
+ }
+ if ($this->request->isPost()) {
+ $params = $this->request->post("row/a");
+ if ($params) {
+ $params = $this->preExcludeFields($params);
+
+ if ($params['pid'] != $row['pid']) {
+ $childrenIds = Tree::instance()->init(collection(\app\common\model\Category::select())->toArray())->getChildrenIds($row['id'], true);
+ if (in_array($params['pid'], $childrenIds)) {
+ $this->error(__('Can not change the parent to child or itself'));
+ }
+ }
+
+ try {
+ //是否采用模型验证
+ if ($this->modelValidate) {
+ $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
+ $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
+ $row->validate($validate);
+ }
+ $result = $row->allowField(true)->save($params);
+ if ($result !== false) {
+ $this->success();
+ } else {
+ $this->error($row->getError());
+ }
+ } catch (\think\exception\PDOException $e) {
+ $this->error($e->getMessage());
+ } catch (\think\Exception $e) {
+ $this->error($e->getMessage());
+ }
+ }
+ $this->error(__('Parameter %s can not be empty', ''));
+ }
+ $this->view->assign("row", $row);
+ return $this->view->fetch();
+ }
+
+
+
+ /**
+ * 获取树形分类
+ */
+ public function gettree() {
+ $category = $this->tree->getTreeArray(0);
+
+ $this->success('获取成功', null, $category);
+ }
+
+
+
+ /**
+ * 【即将废弃】 Selectpage搜索,老的商品添加选择分类
+ *
+ * @internal
+ */
+ public function selectpage()
+ {
+
+ $searchValue = $this->request->post("searchValue", "");
+ $searchValue = array_filter(explode(',', $searchValue));
+ $word = array_filter((array) $this->request->request("q_word/a"));
+
+ $categorylist = [];
+ if ($searchValue) {
+ // 编辑的时候选中
+ foreach ($this->categorylist as $key => $list) {
+ if (in_array($list['id'], $searchValue)) {
+ $categorylist[] = $list;
+ }
+ }
+ } else if ($word) {
+ // 搜索关键字,关键字为数组
+ foreach ($this->categorylist as $key => $list) {
+ foreach ($word as $w) {
+ if (strpos($list['name'], $w) !== false) {
+ $categorylist[] = $list;
+ }
+ }
+ }
+ } else {
+ $categorylist = $this->categorylist;
+ }
+ // return parent::selectpage();
+ return json(['list' => $categorylist, 'total' => count($categorylist)]);
+ }
+}
diff --git a/application/admin/controller/shopro/Config.php b/application/admin/controller/shopro/Config.php
new file mode 100644
index 000000000..96334a838
--- /dev/null
+++ b/application/admin/controller/shopro/Config.php
@@ -0,0 +1,289 @@
+model = model('app\admin\model\shopro\Config');
+ }
+
+ /**
+ * 查看
+ */
+ public function index()
+ {
+ $siteList = [];
+ $groupList = ConfigModel::getGroupList();
+ foreach ($groupList as $k => $v) {
+ $siteList[$k]['name'] = $k;
+ $siteList[$k]['title'] = $v;
+ $siteList[$k]['list'] = [];
+ }
+
+ foreach ($this->model->all() as $k => $v) {
+ if (!isset($siteList[$v['group']])) {
+ continue;
+ }
+ $value = $v->toArray();
+ $value['title'] = __($value['title']);
+ if (in_array($value['type'], ['select', 'selects', 'checkbox', 'radio'])) {
+ $value['value'] = explode(',', $value['value']);
+ }
+ $value['content'] = json_decode($value['content'], true);
+ $value['tip'] = htmlspecialchars($value['tip']);
+ $siteList[$v['group']]['list'][] = $value;
+ }
+ $index = 0;
+ foreach ($siteList as $k => &$v) {
+ $v['active'] = !$index ? true : false;
+ $index++;
+ }
+ $this->view->assign('siteList', $siteList);
+ $this->view->assign('typeList', ConfigModel::getTypeList());
+ $this->view->assign('ruleList', ConfigModel::getRegexList());
+ $this->view->assign('groupList', ConfigModel::getGroupList());
+ return $this->view->fetch();
+ }
+
+ /**
+ * 添加
+ */
+ public function add()
+ {
+ if ($this->request->isPost()) {
+ $this->token();
+ $params = $this->request->post("row/a", [], 'trim');
+ if ($params) {
+ foreach ($params as $k => &$v) {
+ $v = is_array($v) ? implode(',', $v) : $v;
+ }
+ try {
+ if (in_array($params['type'], ['select', 'selects', 'checkbox', 'radio', 'array'])) {
+ $params['content'] = json_encode(ConfigModel::decode($params['content']), JSON_UNESCAPED_UNICODE);
+ } else {
+ $params['content'] = '';
+ }
+ $result = $this->model->create($params);
+ if ($result !== false) {
+// try {
+// $this->refreshFile();
+// } catch (Exception $e) {
+// $this->error($e->getMessage());
+// }
+ $this->success();
+ } else {
+ $this->error($this->model->getError());
+ }
+ } catch (Exception $e) {
+ $this->error($e->getMessage());
+ }
+ }
+ $this->error(__('Parameter %s can not be empty', ''));
+ }
+ return $this->view->fetch();
+ }
+
+ /**
+ * 编辑
+ * @param null $ids
+ */
+ public function edit($ids = null)
+ {
+ if ($this->request->isPost()) {
+ $this->token();
+ $row = $this->request->post("row/a", [], 'trim');
+ if ($row) {
+ $configList = [];
+ foreach ($this->model->all() as $v) {
+ if (isset($row[$v['name']])) {
+ $value = $row[$v['name']];
+ if (is_array($value) && isset($value['field'])) {
+ $value = json_encode(ConfigModel::getArrayData($value), JSON_UNESCAPED_UNICODE);
+ } else {
+ $value = is_array($value) ? implode(',', $value) : $value;
+ }
+ $v['value'] = $value;
+ $configList[] = $v->toArray();
+ }
+ }
+ $this->model->allowField(true)->saveAll($configList);
+ try {
+ } catch (Exception $e) {
+ $this->error($e->getMessage());
+ }
+ $this->success();
+ }
+ $this->error(__('Parameter %s can not be empty', ''));
+ }
+ }
+
+ public function platform($type)
+ {
+ if ($this->request->isPost()) {
+ $this->token();
+ $row = $this->request->post("row/a", [], 'trim');
+ if ($row) {
+ try {
+ $config = $this->model->get(['name' => $type]);
+ $config->value = json_encode($row);
+ $config->save();
+
+
+ } catch (Exception $e) {
+ $this->error($e->getMessage());
+ }
+ $this->success();
+ }
+ $this->error(__('Parameter %s can not be empty', ''));
+ }
+ $config = $this->model->where(['name' => $type])->value('value');
+ $config = json_decode($config, true);
+ if ($type === 'wxOfficialAccount') {
+ //动态解析微信公众号服务端Api Url地址域名
+ $config['url'] = request()->domain() . '/addons/shopro/wechat';
+ }
+ $this->assign('row', $config);
+ return $this->view->fetch();
+
+ }
+
+ /**
+ * 删除
+ * @param string $ids
+ */
+ public function del($ids = "")
+ {
+ $name = $this->request->post('name');
+ $config = ConfigModel::getByName($name);
+ if ($name && $config) {
+ try {
+ $config->delete();
+ $this->refreshFile();
+ } catch (Exception $e) {
+ $this->error($e->getMessage());
+ }
+ $this->success();
+ } else {
+ $this->error(__('Invalid parameters'));
+ }
+ }
+
+ /**
+ * 刷新配置文件
+ */
+ protected function refreshFile()
+ {
+ $config = [];
+ foreach ($this->model->all() as $k => $v) {
+ $value = $v->toArray();
+ if (in_array($value['type'], ['selects', 'checkbox', 'images', 'files'])) {
+ $value['value'] = explode(',', $value['value']);
+ }
+ if ($value['type'] == 'array') {
+ $value['value'] = (array)json_decode($value['value'], true);
+ }
+ $config[$value['name']] = $value['value'];
+ }
+ file_put_contents(
+ APP_PATH . 'extra' . DS . 'site.php',
+ 'request->post("row/a");
+ if ($params) {
+ $config = $this->model->get($params);
+ if (!$config) {
+ return $this->success();
+ } else {
+ return $this->error(__('Name already exist'));
+ }
+ } else {
+ return $this->error(__('Invalid parameters'));
+ }
+ }
+
+ /**
+ * 规则列表
+ * @internal
+ */
+ public function rulelist()
+ {
+ //主键
+ $primarykey = $this->request->request("keyField");
+ //主键值
+ $keyValue = $this->request->request("keyValue", "");
+
+ $keyValueArr = array_filter(explode(',', $keyValue));
+ $regexList = \app\common\model\Config::getRegexList();
+ $list = [];
+ foreach ($regexList as $k => $v) {
+ if ($keyValueArr) {
+ if (in_array($k, $keyValueArr)) {
+ $list[] = ['id' => $k, 'name' => $v];
+ }
+ } else {
+ $list[] = ['id' => $k, 'name' => $v];
+ }
+ }
+ return json(['list' => $list]);
+ }
+
+ /**
+ * 发送测试邮件
+ * @internal
+ */
+ public function emailtest()
+ {
+ $row = $this->request->post('row/a');
+ $receiver = $this->request->post("receiver");
+ if ($receiver) {
+ if (!Validate::is($receiver, "email")) {
+ $this->error(__('Please input correct email'));
+ }
+ \think\Config::set('site', array_merge(\think\Config::get('site'), $row));
+ $email = new Email;
+ $result = $email
+ ->to($receiver)
+ ->subject(__("This is a test mail"))
+ ->message('
' . __('This is a test mail content') . '
')
+ ->send();
+ if ($result) {
+ $this->success();
+ } else {
+ $this->error($email->getError());
+ }
+ } else {
+ return $this->error(__('Invalid parameters'));
+ }
+ }
+
+}
diff --git a/application/admin/controller/shopro/Coupons.php b/application/admin/controller/shopro/Coupons.php
new file mode 100644
index 000000000..232f800e7
--- /dev/null
+++ b/application/admin/controller/shopro/Coupons.php
@@ -0,0 +1,45 @@
+model = new \app\admin\model\shopro\Coupons;
+
+ }
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+
+ /**
+ * 选择优惠券
+ */
+ public function select()
+ {
+ if ($this->request->isAjax()) {
+ return $this->index();
+ }
+ return $this->view->fetch();
+ }
+
+}
diff --git a/application/admin/controller/shopro/Dashboard.php b/application/admin/controller/shopro/Dashboard.php
new file mode 100644
index 000000000..cb290d3e3
--- /dev/null
+++ b/application/admin/controller/shopro/Dashboard.php
@@ -0,0 +1,125 @@
+request->isAjax()) {
+ //如果发送的来源是Selectpage,则转发到Selectpage
+ $datetimerange = explode(' - ', $this->request->request('datetimerange'));
+ $startTime = strtotime($datetimerange[0]);
+ $endTime = strtotime($datetimerange[1]);
+ $this->model = new \app\admin\model\shopro\order\Order;
+ $where = [
+ 'paytime' => ['between', [$startTime, $endTime]]
+ ];
+
+ $list = $this->model
+ ->where($where)
+ ->order('id')
+ ->select();
+
+ foreach ($list as $row) {
+ $row->item = \app\admin\model\shopro\order\OrderItem::all(['order_id' => $row->id]);
+ }
+ $data['orderList'] = $list;
+
+ // 商品列表
+ $goodsList = \addons\shopro\model\Goods::limit(5)->order('sales', 'desc')->select();
+ foreach ($goodsList as $key => $goods) {
+ $result = \app\admin\model\shopro\order\OrderItem::field('sum(goods_num * goods_price) as sale_total_money')->where('goods_id', $goods['id'])
+ ->whereExists(function ($query) use ($goods) {
+ $order_table_name = $this->model->getQuery()->getTable();
+ $table_name = (new \app\admin\model\shopro\order\OrderItem())->getQuery()->getTable();
+
+ $query->table($order_table_name)->where('order_id=' . $order_table_name . '.id')
+ ->where('status', '>', \app\admin\model\shopro\order\Order::STATUS_NOPAY); // 已支付的订单
+ })->find();
+
+ $goods['sale_total_money'] = $result['sale_total_money'] ? : 0;
+ }
+ $data['goodsList'] = $goodsList;
+
+ // 订单数量
+ $data['orderNum'] = $this->model->where([
+ 'createtime' => ['between', [$startTime, $endTime]]
+ ])->count('id');
+
+
+ extract($this->orderScale($startTime, $endTime));
+
+ $data['orderFinish'] = $orderFinish;
+ $data['payedFinish'] = $payedFinish;
+
+ $this->success('数据中心', '', $data);
+ }
+
+ return $this->view->fetch();
+ }
+
+
+
+ private function orderScale ($startTime, $endTime) {
+ $where = [
+ 'createtime' => ['between', [$startTime, $endTime]]
+ ];
+ $list = $this->model
+ ->where($where)
+ ->order('id')
+ ->select();
+
+ $total = count($list);
+ $total_money = array_sum(array_column($list, 'total_fee'));
+
+ $data['orderFinish'] = [
+ 'order_scale' => 0,
+ 'order_user' => 0
+ ];
+ $data['payedFinish'] = [
+ 'payed_scale' => 0,
+ 'payed_money' => 0
+ ];
+
+ // 支付单数
+ $payed_num = 0;
+ // 支付金额
+ $payed_money = 0;
+ // 支付的用户 id
+ $payed_user_ids = [];
+
+ foreach ($list as $key => $order) {
+ if ($order['status'] > 0) {
+ $payed_num++;
+ $payed_money += $order['total_fee'];
+ $payed_user_ids[] = $order['user_id'];
+ }
+ }
+
+ $orderFinish = [
+ 'order_scale' => $total ? round(($payed_num / $total), 2) : 0,
+ 'order_user' => count(array_unique($payed_user_ids)),
+ ];
+
+ $payedFinish = [
+ 'payed_scale' => $total_money ? round(($payed_money / $total_money), 2) : 0,
+ 'payed_money' => round($payed_money, 2)
+ ];
+
+ return compact("orderFinish", "payedFinish");
+ }
+}
diff --git a/application/admin/controller/shopro/Decorate.php b/application/admin/controller/shopro/Decorate.php
new file mode 100644
index 000000000..5e8c3b01e
--- /dev/null
+++ b/application/admin/controller/shopro/Decorate.php
@@ -0,0 +1,574 @@
+model = new \app\admin\model\shopro\Decorate;
+ }
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+
+ public function lists($type = '')
+ {
+ if ($this->request->isAjax()) {
+ $data = $this->model->all(['type' => $type]);
+ return json([
+ 'code' => 1,
+ 'msg' => '模板列表',
+ 'data' => $data
+ ]);
+ }
+ return $this->view->fetch();
+ }
+
+
+ /**
+ * 添加
+ */
+ public function add()
+ {
+ if ($this->request->isPost()) {
+ $params = $this->request->post();
+ // halt($params);
+ if ($params) {
+ $params = $this->preExcludeFields($params);
+
+ if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
+ $params[$this->dataLimitField] = $this->auth->id;
+ }
+ $result = false;
+ Db::startTrans();
+ try {
+ //是否采用模型验证
+ if ($this->modelValidate) {
+ $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
+ $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
+ $this->model->validateFailException(true)->validate($validate);
+ }
+ $result = $this->model->allowField(true)->save($params);
+ //添加默认数据
+ if ($params['type'] === 'shop') {
+ DecorateContent::create([
+ 'type' => 'user',
+ 'category' => 'user',
+ 'name' => '用户卡片',
+ 'content' => '{"name":"用户卡片","image":"","style":1,"color":"#eeeeee"}',
+ 'decorate_id' => $this->model->id
+ ]);
+ }
+ Db::commit();
+ } catch (ValidateException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (PDOException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (Exception $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ }
+ if ($result !== false) {
+ //添加默认模板数据
+ $this->success();
+ } else {
+ $this->error(__('No rows were inserted'));
+ }
+ }
+ $this->error(__('Parameter %s can not be empty', ''));
+ }
+ return $this->view->fetch();
+ }
+
+ /**
+ * 编辑
+ */
+ public function edit($id = null)
+ {
+ $row = $this->model->get($id);
+ if (!$row) {
+ $this->error(__('No Results were found'));
+ }
+ $adminIds = $this->getDataLimitAdminIds();
+ if (is_array($adminIds)) {
+ if (!in_array($row[$this->dataLimitField], $adminIds)) {
+ $this->error(__('You have no permission'));
+ }
+ }
+ if ($this->request->isPost()) {
+ $params = $this->request->post();
+ if ($params) {
+ $params = $this->preExcludeFields($params);
+ //检查是否有同平台冲突的已发布模板
+ if ($row->status === 'normal') {
+ $platformArray = explode(',', $params['platform']);
+ $where = ['deletetime' => null, 'status' => 'normal', 'type' => 'shop', 'id' => ['neq', $id]];
+ foreach ($platformArray as $v) {
+ $publishDecorate = $this->model->where('find_in_set(:platform,platform)', ['platform' => $v])->where($where)->find();
+ if ($publishDecorate) {
+ $this->error(__($v) . ' 已经被使用');
+ }
+ }
+ }
+
+ $result = false;
+ Db::startTrans();
+ try {
+ //是否采用模型验证
+ if ($this->modelValidate) {
+ $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
+ $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
+ $row->validateFailException(true)->validate($validate);
+ }
+ $result = $row->allowField(true)->save($params);
+ Db::commit();
+ } catch (ValidateException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (PDOException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (Exception $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ }
+ if ($result !== false) {
+ $this->success();
+ } else {
+ $this->error(__('No rows were updated'));
+ }
+ }
+ $this->error(__('Parameter %s can not be empty', ''));
+ }
+
+ $this->view->assign("row", $row);
+ return $this->view->fetch();
+ }
+
+ /**
+ * 模板管理 发布
+ * @param string $id
+ * @param int $force
+ */
+ public function publish($id, $force = 0)
+ {
+ $row = $this->model->get($id);
+ if (!$row) {
+ $this->error(__('No Results were found'));
+ }
+ if (empty($row->platform)) {
+ $this->error('请选择模板的发布平台', null, 0);
+ }
+ $platformArray = explode(',', $row->platform);
+ $where = ['deletetime' => null, 'status' => 'normal', 'type' => 'shop'];
+ $existPublish = [];
+ foreach ($platformArray as $v) {
+ $publishDecorate = $this->model->where('find_in_set(:platform,platform)', ['platform' => $v])->where($where)->find();
+ if ($publishDecorate) {
+ if ($force == 1) {
+ $platform = array_diff(explode(',', $publishDecorate->platform), [$v]);
+ $publishDecorate->platform = implode(',', $platform);
+ if ($publishDecorate->platform == '') {
+ $publishDecorate->status = 'hidden';
+ }
+ $publishDecorate->save();
+ } else {
+ $existPublish[$publishDecorate->name][] = __($v);
+ }
+ }
+ }
+
+ if ($existPublish !== [] && $force == 0) {
+ $str = '';
+ foreach ($existPublish as $k => $e) {
+ $str .= $k . ',';
+ }
+ $this->error("${str} 已存在相同的支持平台,确定替换吗?");
+ }
+ $row->status = 'normal';
+ $row->save();
+ $this->success('发布成功');
+ }
+
+ /**
+ * 模板管理 下架
+ * @param string $id
+ */
+ public function down($id)
+ {
+ $row = $this->model->get($id);
+ if (!$row) {
+ $this->error(__('No Results were found'));
+ }
+ $where = ['deletetime' => null, 'status' => 'normal', 'type' => 'shop'];
+ $publishDecorate = $this->model->where($where)->select();
+ if (count($publishDecorate) == 1) {
+ $this->error('您需要至少保留一个发布模板~');
+ }
+
+ $row->status = 'hidden';
+ $row->save();
+ $this->success('下架成功');
+ }
+
+ /**
+ * 模板管理 复制
+ * @param string $id
+ */
+ public function copy($id)
+ {
+ $row = $this->model->get($id);
+ if (!$row) {
+ $this->error(__('No Results were found'));
+ }
+
+ $this->model->save([
+ 'name' => "复制 {$row->name}",
+ 'type' => $row->type,
+ 'memo' => $row->memo,
+ 'image' => $row->image,
+ 'status' => 'hidden',
+ 'platform' => $row->platform,
+ ]);
+ $id = $this->model->id;
+ $content = collection(DecorateContent::where('decorate_id', $row->id)
+ ->order('id asc')
+ ->field("type, category, content, name, $id as decorate_id")
+ ->select())->toArray();
+
+ $decorateContent = new DecorateContent();
+ $decorateContent->saveAll($content);
+ $this->success('复制成功');
+ }
+
+
+ /**
+ * 自定义页面
+ */
+ public function custom()
+ {
+ return $this->view->fetch();
+ }
+
+
+ /**
+ * 页面装修
+ * @param string $id
+ */
+ public function dodecorate($id)
+ {
+ $content = new DecorateContent();
+ $query = $content->where(['decorate_id' => $id]);
+ if ($this->request->isPost()) {
+ $params = $this->request->post("templateData");
+ if ($params) {
+ $params = json_decode($params, true);
+ $result = false;
+ Db::startTrans();
+ try {
+ $decorateArray = [];
+ foreach ($params as $p => $a) {
+ foreach ($a as $c => &$o) {
+ if (isset($o['id'])) {
+ unset($o['id']);
+ }
+ $decorateArray[] = [
+ 'category' => $p,
+ 'content' => json_encode($o['content'], JSON_UNESCAPED_UNICODE),
+ 'decorate_id' => $id,
+ 'name' => $o['name'],
+ 'type' => $o['type']
+ ];
+ }
+ }
+
+ $query->delete();
+ $result = new \app\admin\model\shopro\DecorateContent;
+ $result->saveAll($decorateArray);
+ Db::commit();
+ } catch (ValidateException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (PDOException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (Exception $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ }
+ if ($result !== false) {
+ $this->success();
+ } else {
+ $this->error(__('No rows were updated'));
+ }
+ }
+ $this->error('请完善装修页面');
+ }
+ $template = $query->select();
+ if ($template) {
+ foreach ($template as &$t) {
+ $t['content'] = json_decode($t['content'], true);
+ }
+ } else {
+ $template = [];
+ }
+ $categoryArray = array_column($template, 'category');
+ $templateData = [];
+ foreach ($categoryArray as $k => $c) {
+ $templateData[$c][] = $template[$k];
+ }
+
+ $shopro = json_decode(\app\admin\model\shopro\Config::get(['name' => 'shopro'])->value, true);
+ if (empty($shopro) || empty($shopro['domain'])) {
+ $this->error('请完善您的域名信息');
+ } else {
+ $domain = $shopro['domain'];
+ }
+ // halt($template);
+ $this->assignconfig('templateData', $templateData);
+ $this->assignconfig('preview_id', $id);
+ $this->assignconfig('iframeSrc', $domain . '/?preview_id=' . $id);
+ return $this->view->fetch();
+ }
+
+ /**
+ * 页面装修 保存
+ * @param string $id
+ */
+ public function dodecorate_save($id)
+ {
+ if ($this->request->isPost()) {
+ $decorate = $this->model->get($id);
+
+ if (!$decorate) {
+ $this->error(__('No Results were found'));
+ }
+
+ $params = $this->request->post("templateData");
+ $result = $this->updateDecorateContent($id, $params);
+ if ($result) {
+ // 前端配置
+ $url = "";
+ if ($decorate->type == 'shop') {
+ extract($this->getShopro());
+ $url = "{$domain}?{$decorate->type}_id={$id}&mode=save";
+ }
+ $this->success('保存成功', $url, $decorate);
+ } else {
+ $this->error('保存失败');
+ }
+ }
+ }
+
+ private function updateDecorateContent($id, $params)
+ {
+ $result = false;
+
+ if ($params) {
+ $params = json_decode($params, true);
+ Db::startTrans();
+ try {
+ $decorateArray = [];
+ foreach ($params as $p => $a) {
+ foreach ($a as $c => &$o) {
+ if (isset($o['id'])) {
+ unset($o['id']);
+ }
+ $decorateArray[] = [
+ 'category' => $p,
+ 'content' => json_encode($o['content'], JSON_UNESCAPED_UNICODE),
+ 'decorate_id' => $id,
+ 'name' => $o['name'],
+ 'type' => $o['type']
+ ];
+ }
+ }
+
+ DecorateContent::where(['decorate_id' => $id])->delete();
+ $result = new DecorateContent();
+ $result->saveAll($decorateArray);
+ Db::commit();
+ return $result;
+ } catch (ValidateException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (PDOException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (Exception $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ }
+ }
+ return $result;
+ }
+
+ /**
+ * 页面装修 预览
+ */
+ public function preview($id)
+ {
+ //前端配置
+ extract($this->getShopro());
+
+ //装修数据
+ $decorate = $this->model->get($id);
+ $type = $decorate['type'];
+ //临时预览数据
+ if ($this->request->isPost()) {
+ $row = [
+ 'name' => "临时预览 {$decorate->name}",
+ 'type' => 'preview',
+ 'memo' => date("Y年m月d日 H:i:s", time()) . ' 创建',
+ 'status' => 'normal',
+ 'platform' => $decorate->platform
+ ];
+ $preview = $this->model->where('type', 'preview')->find();
+ if ($preview) {
+ DecorateContent::where('decorate_id', $preview->id)->delete();
+ $preview->delete(true);
+ }
+ $this->model->save($row);
+ $id = $this->model->id;
+ $decorate = $this->model->getData();
+ $params = $this->request->post("templateData");
+ $this->updateDecorateContent($id, $params);
+ }
+ $previewData = array_merge($decorate, $shopro);
+ $this->success($row['name'], "{$domain}?{$type}_id={$id}", $previewData);
+ }
+
+ //设计师模板
+ public function designer()
+ {
+ $designerTemplate = Http::get('http://d.7wpp.com/api/decorate/designer');
+ $res = json_decode($designerTemplate, true);
+ if (isset($res['code']) && $res['code'] === 1) {
+ $this->assignconfig('designerData', $res['data']);
+ }
+ return $this->view->fetch();
+ }
+
+ //使用设计师模板
+ public function use_designer_template($id)
+ {
+ $decorate = Http::get('http://d.7wpp.com/api/decorate/copy?id=' . $id);
+ $res = json_decode($decorate, true);
+ if (isset($res['code']) && $res['code'] === 1) {
+ Db::startTrans();
+ try {
+ $this->model->save([
+ 'type' => 'shop',
+ 'status' => 'hidden',
+ 'image' => $res['data']['image'],
+ 'memo' => $res['data']['memo'],
+ 'name' => $res['data']['name'],
+ 'platform' => $res['data']['platform']
+ ]);
+ foreach ($res['data']['content'] as &$v) {
+ $v['decorate_id'] = $this->model->id;
+ unset($v['id']);
+ }
+ DecorateContent::insertAll($res['data']['content']);
+ Db::commit();
+ } catch (ValidateException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (PDOException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (Exception $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ }
+ } else {
+ $this->error('模板选择错误');
+ }
+ $this->success('模板使用成功');
+ }
+
+ /**
+ * 真实删除
+ */
+ public function destroy($ids = "")
+ {
+ $pk = $this->model->getPk();
+ $adminIds = $this->getDataLimitAdminIds();
+ if (is_array($adminIds)) {
+ $this->model->where($this->dataLimitField, 'in', $adminIds);
+ }
+ if ($ids) {
+ $this->model->where($pk, 'in', $ids);
+ }
+ $count = 0;
+ Db::startTrans();
+ try {
+ $list = $this->model->onlyTrashed()->select();
+ foreach ($list as $k => $v) {
+ DecorateContent::where('decorate_id', $v->id)->delete();
+ $count += $v->delete(true);
+ }
+ Db::commit();
+ } catch (PDOException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (Exception $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ }
+ if ($count) {
+ $this->success();
+ } else {
+ $this->error(__('No rows were deleted'));
+ }
+ $this->error(__('Parameter %s can not be empty', 'ids'));
+ }
+
+ public function select()
+ {
+ if ($this->request->isAjax()) {
+ return $this->index();
+ }
+ return $this->view->fetch();
+ }
+
+
+ // 获取shopro 配置
+ private function getShopro()
+ {
+ $shopro = json_decode(\app\admin\model\shopro\Config::get(['name' => 'shopro'])->value, true);
+ if (empty($shopro) || empty($shopro['domain'])) {
+ $this->error('请在商城配置中完善前端访问地址');
+ } else {
+ //前端域名
+ $domain = $shopro['domain'];
+ }
+
+ return compact("domain", "shopro");
+ }
+}
diff --git a/application/admin/controller/shopro/Faq.php b/application/admin/controller/shopro/Faq.php
new file mode 100644
index 000000000..e92479a1a
--- /dev/null
+++ b/application/admin/controller/shopro/Faq.php
@@ -0,0 +1,35 @@
+model = new \app\admin\model\shopro\Faq;
+
+ }
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+
+
+}
diff --git a/application/admin/controller/shopro/Feedback.php b/application/admin/controller/shopro/Feedback.php
new file mode 100644
index 000000000..97952887e
--- /dev/null
+++ b/application/admin/controller/shopro/Feedback.php
@@ -0,0 +1,76 @@
+model = new \app\admin\model\shopro\Feedback;
+ $this->view->assign("statusList", $this->model->getStatusList());
+ }
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+
+
+ /**
+ * 查看
+ */
+ public function index()
+ {
+ //当前是否为关联查询
+ $this->relationSearch = false;
+ //设置过滤方法
+ $this->request->filter(['strip_tags', 'trim']);
+ if ($this->request->isAjax())
+ {
+ //如果发送的来源是Selectpage,则转发到Selectpage
+ if ($this->request->request('keyField'))
+ {
+ return $this->selectpage();
+ }
+ list($where, $sort, $order, $offset, $limit) = $this->buildparams();
+ $total = $this->model
+
+ ->where($where)
+ ->order($sort, $order)
+ ->count();
+
+ $list = $this->model
+
+ ->where($where)
+ ->order($sort, $order)
+ ->limit($offset, $limit)
+ ->select();
+
+ foreach ($list as $row) {
+ $row->visible(['id','user_id','type','content','images','phone','status','remark','createtime','updatetime','deletetime']);
+
+ }
+ $list = collection($list)->toArray();
+ $result = array("total" => $total, "rows" => $list);
+
+ return json($result);
+ }
+ return $this->view->fetch();
+ }
+}
diff --git a/application/admin/controller/shopro/Goods.php b/application/admin/controller/shopro/Goods.php
new file mode 100644
index 000000000..4562cb22e
--- /dev/null
+++ b/application/admin/controller/shopro/Goods.php
@@ -0,0 +1,528 @@
+model = new \app\admin\model\shopro\Goods;
+ $this->view->assign("typeList", $this->model->getTypeList());
+ $this->view->assign("statusList", $this->model->getStatusList());
+ $this->view->assign("dispatchTypeList", $this->model->getDispatchTypeList());
+ }
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+
+
+ /**
+ * 查看
+ */
+ public function index()
+ {
+ //当前是否为关联查询
+ $this->relationSearch = false;
+ //设置过滤方法
+ $this->request->filter(['strip_tags', 'trim']);
+ if ($this->request->isAjax()) {
+ //如果发送的来源是Selectpage,则转发到Selectpage
+ if ($this->request->request('keyField')) {
+ return $this->selectpage();
+ }
+ // list($where, $sort, $order, $offset, $limit) = $this->buildparams('title');
+ $sort = $this->request->get("sort", !empty($this->model) && $this->model->getPk() ? $this->model->getPk() : 'id');
+ $sort = $sort == 'price' ? 'convert(`price`, DECIMAL)' : $sort;
+ $order = $this->request->get("order", "DESC");
+ $offset = $this->request->get("offset", 0);
+ $limit = $this->request->get("limit", 0);
+
+ $total = $this->buildSearchOrder()
+ ->count();
+
+ $subsql = \app\admin\model\shopro\GoodsSkuPrice::where('status', 'up')->field('sum(stock) as stock, goods_id')->group('goods_id')->buildSql();
+ $goodsTableName = $this->model->getQuery()->getTable();
+
+ $list = $this->buildSearchOrder()
+ ->join([$subsql => 'w'], $goodsTableName . '.id = w.goods_id', 'left')
+ ->orderRaw($sort . ' ' . $order)
+ ->limit($offset, $limit)
+ ->select();
+
+ foreach ($list as $row) {
+ $row->visible(['id', 'type', 'title', 'status', 'weigh', 'category_ids', 'image', 'price', 'likes', 'views', 'sales', 'stock', 'show_sales', 'dispatch_type', 'updatetime']);
+ }
+ $list = collection($list)->toArray();
+ $result = array("total" => $total, "rows" => $list);
+
+ if ($this->request->get("page_type") == 'select') {
+ return json($result);
+ }
+
+ return $this->success('操作成功', null, $result);
+ }
+ return $this->view->fetch();
+ }
+
+ /**
+ * 添加
+ */
+ public function add()
+ {
+ if ($this->request->isPost()) {
+ $params = $this->request->post("row/a");
+ $sku = $this->request->post("sku/a");
+
+ if ($params) {
+ $params = $this->preExcludeFields($params);
+
+ if (!$params['is_sku']) {
+ // 单规格,price 必须是数字
+ if (!preg_match('/^[0-9]+(.[0-9]{1,8})?$/', $params['price'])) {
+ $this->error("请填写正确的价格");
+ }
+ }
+
+ if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
+ $params[$this->dataLimitField] = $this->auth->id;
+ }
+ $result = false;
+ Db::startTrans();
+ try {
+ $result = $this->model->validate('\app\admin\validate\shopro\Goods.add')->allowField(true)->save($params);
+ if (!$result) {
+ $this->error($this->model->getError());
+ }
+ $this->editSku($this->model, $sku, 'add');
+
+
+ Db::commit();
+
+ } catch (ValidateException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (PDOException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (Exception $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ }
+ if ($result !== false) {
+ $this->success("添加成功");
+ } else {
+ $this->error(__('No rows were inserted'));
+ }
+ }
+ $this->error(__('Parameter %s can not be empty', ''));
+ }
+ return $this->view->fetch();
+ }
+
+
+
+ /**
+ * 查看详情
+ */
+ public function detail($ids = null) {
+ $row = $this->model->get($ids);
+ if (!$row) {
+ $this->error(__('No Results were found'));
+ }
+ $row->append(['category_ids_arr', 'params_arr']);
+
+ $result = [];
+
+ if ($row['is_sku']) {
+ $skuList = \app\admin\model\shopro\GoodsSku::all(['pid' => 0, 'goods_id' => $ids]);
+ if ($skuList) {
+ foreach ($skuList as &$s) {
+ $s->children = \app\admin\model\shopro\GoodsSku::all(['pid' => $s->id, 'goods_id' => $ids]);
+ }
+ }
+ $result['skuList'] = $skuList;
+
+ $skuPrice = \app\admin\model\shopro\GoodsSkuPrice::all(['goods_id' => $ids]);
+ $result['skuPrice'] = $skuPrice;
+ } else {
+ // 将单规格的部分数据直接放到 row 上
+ $goodsSkuPrice = \app\admin\model\shopro\GoodsSkuPrice::where('goods_id', $ids)->order('id', 'asc')->find();
+
+ $row['stock'] = $goodsSkuPrice['stock'] ?? 0;
+ $row['sn'] = $goodsSkuPrice['sn'] ?? "";
+ $row['weight'] = $goodsSkuPrice['weight'] ?? 0;
+
+ $result['skuList'] = [];
+ $result['skuPrice'] = [];
+ }
+ $result['detail'] = $row;
+
+ return $this->success('获取成功', null, $result);
+ }
+
+
+
+ /**
+ * 编辑
+ */
+ public function edit($ids = null)
+ {
+ $row = $this->model->get($ids);
+ if (!$row) {
+ $this->error(__('No Results were found'));
+ }
+ $row->updatetime = time();
+
+ $adminIds = $this->getDataLimitAdminIds();
+ if (is_array($adminIds)) {
+ if (!in_array($row[$this->dataLimitField], $adminIds)) {
+ $this->error(__('You have no permission'));
+ }
+ }
+ if ($this->request->isPost()) {
+ $params = $this->request->post("row/a");
+ $sku = $this->request->post("sku/a");
+
+ if ($params) {
+ $this->excludeFields = ['is_sku'];
+ $params = $this->preExcludeFields($params);
+ $result = false;
+ Db::startTrans();
+ try {
+ $result = $row->validate('\app\admin\validate\shopro\Goods.edit')->allowField(true)->save($params);
+ if (!$result) {
+ $this->error($row->getError());
+ } else {
+ $this->editSku($row, $sku, 'edit');
+ Db::commit();
+ }
+ } catch (ValidateException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (PDOException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (Exception $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ }
+ if ($result !== false) {
+ $this->success("编辑成功");
+ } else {
+ $this->error(__('No rows were updated'));
+ }
+ }
+ $this->error(__('Parameter %s can not be empty', ''));
+ }
+ $this->view->assign("row", $row);
+ $skuList = \app\admin\model\shopro\GoodsSku::all(['pid' => 0, 'goods_id' => $ids]);
+ if ($skuList) {
+ foreach ($skuList as &$s) {
+ $s->children = \app\admin\model\shopro\GoodsSku::all(['pid' => $s->id, 'goods_id' => $ids]);
+ }
+ }
+ $this->assignconfig('skuList', $skuList);
+ $skuPrice = \app\admin\model\shopro\GoodsSkuPrice::all(['goods_id' => $ids]);
+ $this->assignconfig('skuPrice', $skuPrice);
+ return $this->view->fetch();
+ }
+
+ public function select()
+ {
+ return $this->view->fetch();
+ }
+
+
+ public function setStatus($ids, $status) {
+ if ($ids) {
+ $pk = $this->model->getPk();
+ $adminIds = $this->getDataLimitAdminIds();
+ if (is_array($adminIds)) {
+ $this->model->where($this->dataLimitField, 'in', $adminIds);
+ }
+ $list = $this->model->where($pk, 'in', $ids)->select();
+
+ $count = 0;
+ Db::startTrans();
+ try {
+ foreach ($list as $k => $v) {
+ $v->status = $status;
+ $count += $v->save();
+ }
+ Db::commit();
+ } catch (PDOException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (Exception $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ }
+ if ($count) {
+ $this->success();
+ } else {
+ $this->error(__('No rows were updated'));
+ }
+ }
+ $this->error(__('Parameter %s can not be empty', 'ids'));
+ }
+
+
+ protected function editSku($goods, $sku, $type = 'add')
+ {
+ if ($goods['is_sku']) {
+ // 多规格
+ $this->editMultSku($goods, $sku, $type);
+ } else {
+ $this->editSimSku($goods, $sku, $type);
+ }
+
+ }
+
+
+ /**
+ * 添加编辑单规格
+ */
+ protected function editSimSku($goods, $sku, $type = 'add') {
+ $params = $this->request->post("row/a");
+
+ $data = [
+ "goods_id" => $goods['id'],
+ "stock" => $params['stock'] ?? 0,
+ "sn" => $params['sn'] ?? "",
+ "weight" => $params['weight'] ?? 0,
+ "price" => $params['price'] ?? 0,
+ "status" => 'up'
+ ];
+
+ if ($type == 'add') {
+ $goodsSkuPrice = new \app\admin\model\shopro\GoodsSkuPrice();
+ } else {
+ // 查询
+ $goodsSkuPrice = \app\admin\model\shopro\GoodsSkuPrice::where('goods_id', $goods['id'])->order('id', 'asc')->find();
+ if (!$goodsSkuPrice) {
+ $goodsSkuPrice = new \app\admin\model\shopro\GoodsSkuPrice();
+ }
+ }
+
+ $goodsSkuPrice->save($data);
+ }
+
+
+ /**
+ * 添加编辑多规格
+ */
+ protected function editMultSku($goods, $sku, $type = 'add') {
+ $skuList = json_decode($sku['listData'], true);
+ $skuPrice = json_decode($sku['priceData'], true);
+ if (count($skuList) < 1) {
+ $this->error('请填写规格列表');
+ }
+ foreach ($skuList as $key => $sku) {
+ if (count($sku['children']) <= 0) {
+ $this->error('主规格至少要有一个子规格');
+ }
+ }
+
+ if (count($skuPrice) < 1) {
+ $this->error('请填写规格价格');
+ }
+
+
+ foreach ($skuPrice as &$price) {
+ if (empty($price['price']) || $price['price'] == 0) {
+ $this->error('请填写规格价格');
+ }
+ if ($price['stock'] === '') {
+ $this->error('请填写规格库存');
+ }
+ if (empty($price['weight'])) {
+ $price['weight'] = 0;
+ }
+ }
+
+ // 编辑保存规格项
+ $allChildrenSku = $this->saveSkuList($goods, $skuList, $type);
+
+ if ($type == 'add') {
+ // 创建新产品,添加规格列表和规格价格
+ foreach ($skuPrice as $s3 => &$k3) {
+ $k3['goods_sku_ids'] = $this->checkRealIds($k3['goods_sku_temp_ids'], $allChildrenSku);
+ $k3['goods_id'] = $goods->id;
+ $k3['goods_sku_text'] = implode(',', $k3['goods_sku_text']);
+ $k3['weight'] = intval($k3['weight']);
+ $k3['createtime'] = time();
+ $k3['updatetime'] = time();
+
+ unset($k3['id']);
+ unset($k3['temp_id']); // 前端临时 id
+ unset($k3['goods_sku_temp_ids']); // 前端临时规格 id,查找真实 id 用
+ }
+ $res = \app\admin\model\shopro\GoodsSkuPrice::insertAll($skuPrice);
+
+
+ } else {
+ // 编辑旧商品,先删除老的不用的 skuPrice
+ $oldSkuPriceIds = array_column($skuPrice, 'id');
+ // 删除当前商品老的除了在基础上修改的skuPrice
+ \app\admin\model\shopro\GoodsSkuPrice::where('goods_id', $goods->id)
+ ->where('id', 'not in', $oldSkuPriceIds)->delete();
+
+ foreach ($skuPrice as $s3 => &$k3) {
+ $data['goods_sku_ids'] = $this->checkRealIds($k3['goods_sku_temp_ids'], $allChildrenSku);
+ $data['goods_id'] = $goods->id;
+ $data['goods_sku_text'] = implode(',', $k3['goods_sku_text']);
+ $data['weigh'] = $k3['weigh'];
+ $data['image'] = $k3['image'];
+ $data['stock'] = $k3['stock'];
+ $data['sn'] = $k3['sn'];
+ $data['weight'] = intval($k3['weight']);
+ $data['price'] = $k3['price'];
+ $data['status'] = $k3['status'];
+ $data['createtime'] = time();
+ $data['updatetime'] = time();
+
+ if ($k3['id']) {
+ // 编辑
+ \app\admin\model\shopro\GoodsSkuPrice::where('id', $k3['id'])->update($data);
+
+ } else {
+ // 新增数据
+ \app\admin\model\shopro\GoodsSkuPrice::insert($data);
+ }
+ }
+ }
+ }
+
+
+ // 根据前端临时 temp_id 获取真实的数据库 id
+ private function checkRealIds($newGoodsSkuIds, $allChildrenSku)
+ {
+ $newIdsArray = [];
+ foreach ($newGoodsSkuIds as $id) {
+ $newIdsArray[] = $allChildrenSku[$id];
+ }
+ return implode(',', $newIdsArray);
+
+ }
+
+
+ // 差异更新 规格规格项(多的删除,少的添加)
+ private function saveSkuList($goods, $skuList, $type = 'add') {
+ $allChildrenSku = [];
+
+ if ($type == 'edit') {
+ // 删除无用老规格
+ // 拿出需要更新的老规格
+ $oldSkuIds = [];
+ foreach ($skuList as $key => $sku) {
+ $oldSkuIds[] = $sku['id'];
+
+ $childSkuIds = [];
+ if ($sku['children']) {
+ // 子项 id
+ $childSkuIds = array_column($sku['children'], 'id');
+ }
+
+ $oldSkuIds = array_merge($oldSkuIds, $childSkuIds);
+ $oldSkuIds = array_unique($oldSkuIds);
+ }
+
+ // 删除老的除了在基础上修改的规格项
+ \app\admin\model\shopro\GoodsSku::where('goods_id', $goods->id)->where('id', 'not in', $oldSkuIds)->delete();
+ }
+
+ foreach ($skuList as $s1 => &$k1) {
+ //添加主规格
+ if ($k1['id']) {
+ // 编辑
+ \app\admin\model\shopro\GoodsSku::where('id', $k1['id'])->update([
+ 'name' => $k1['name'],
+ ]);
+
+ $skuId[$s1] = $k1['id'];
+ } else {
+ // 新增
+ $skuId[$s1] = \app\admin\model\shopro\GoodsSku::insertGetId([
+ 'name' => $k1['name'],
+ 'pid' => 0,
+ 'goods_id' => $goods->id
+ ]);
+ }
+ $k1['id'] = $skuId[$s1];
+ foreach ($k1['children'] as $s2 => &$k2) {
+ if ($k2['id']) {
+ // 编辑
+ \app\admin\model\shopro\GoodsSku::where('id', $k2['id'])->update([
+ 'name' => $k2['name'],
+ ]);
+
+ $skuChildrenId[$s1][$s2] = $k2['id'];
+ } else {
+ $skuChildrenId[$s1][$s2] = \app\admin\model\shopro\GoodsSku::insertGetId([
+ 'name' => $k2['name'],
+ 'pid' => $k1['id'],
+ 'goods_id' => $goods->id
+ ]);
+ }
+
+ $allChildrenSku[$k2['temp_id']] = $skuChildrenId[$s1][$s2];
+ $k2['id'] = $skuChildrenId[$s1][$s2];
+ $k2['pid'] = $k1['id'];
+ }
+ }
+
+ return $allChildrenSku;
+ }
+
+
+
+ // 构建查询条件
+ private function buildSearchOrder()
+ {
+ $search = $this->request->get("search", ''); // 关键字
+ $status = $this->request->get("status", 'all');
+
+ $name = $this->model->getTable();
+ $tableName = $name . '.';
+
+ $goods = $this->model;
+
+ if ($search) {
+ // 模糊搜索字段
+ $searcharr = ['title'];
+ foreach ($searcharr as $k => &$v) {
+ $v = stripos($v, ".") === false ? $tableName . $v : $v;
+ }
+ unset($v);
+ $goods = $goods->where(function ($query) use ($searcharr, $search, $tableName) {
+ $query->where(implode("|", $searcharr), "LIKE", "%{$search}%");
+ });
+ }
+
+ // 商品状态
+ if ($status != 'all') {
+ $goods = $goods->where('status', $status);
+ }
+
+ return $goods;
+ }
+}
diff --git a/application/admin/controller/shopro/GoodsComment.php b/application/admin/controller/shopro/GoodsComment.php
new file mode 100644
index 000000000..8bd2ca20c
--- /dev/null
+++ b/application/admin/controller/shopro/GoodsComment.php
@@ -0,0 +1,78 @@
+model = new \app\admin\model\shopro\GoodsComment;
+ $this->view->assign("statusList", $this->model->getStatusList());
+ }
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+
+
+ /**
+ * 查看
+ */
+ public function index()
+ {
+ //当前是否为关联查询
+ $this->relationSearch = true;
+ //设置过滤方法
+ $this->request->filter(['strip_tags', 'trim']);
+ if ($this->request->isAjax())
+ {
+ //如果发送的来源是Selectpage,则转发到Selectpage
+ if ($this->request->request('keyField'))
+ {
+ return $this->selectpage();
+ }
+ list($where, $sort, $order, $offset, $limit) = $this->buildparams();
+ $total = $this->model
+ ->with(['shoprogoods','user','admin'])
+ ->where($where)
+ ->order($sort, $order)
+ ->count();
+
+ $list = $this->model
+ ->with(['shoprogoods','user','admin'])
+ ->where($where)
+ ->order($sort, $order)
+ ->limit($offset, $limit)
+ ->select();
+
+ foreach ($list as $row) {
+
+ $row->getRelation('shoprogoods')->visible(['id','title']);
+ $row->getRelation('user')->visible(['id','nickname']);
+ $row->getRelation('admin')->visible(['id','nickname']);
+ }
+ $list = collection($list)->toArray();
+ $result = array("total" => $total, "rows" => $list);
+
+ return json($result);
+ }
+ return $this->view->fetch();
+ }
+}
diff --git a/application/admin/controller/shopro/GoodsService.php b/application/admin/controller/shopro/GoodsService.php
new file mode 100644
index 000000000..63fb6eb56
--- /dev/null
+++ b/application/admin/controller/shopro/GoodsService.php
@@ -0,0 +1,48 @@
+model = new \app\admin\model\shopro\GoodsService;
+
+ }
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+
+ /**
+ * 获取所有服务标签
+ */
+ public function all()
+ {
+ if ($this->request->isAjax()) {
+ $sort = $this->request->get("sort", !empty($this->model) && $this->model->getPk() ? $this->model->getPk() : 'id');
+ $order = $this->request->get("order", "DESC");
+
+ $goodsServices = $this->model->order($sort, $order)->select();
+
+ return $this->success('操作成功', null, $goodsServices);
+ }
+ }
+}
diff --git a/application/admin/controller/shopro/GoodsSku.php b/application/admin/controller/shopro/GoodsSku.php
new file mode 100644
index 000000000..2bf411a4b
--- /dev/null
+++ b/application/admin/controller/shopro/GoodsSku.php
@@ -0,0 +1,35 @@
+model = new \app\admin\model\shopro\GoodsSku;
+
+ }
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+
+
+}
diff --git a/application/admin/controller/shopro/GoodsSkuPrice.php b/application/admin/controller/shopro/GoodsSkuPrice.php
new file mode 100644
index 000000000..b60494c52
--- /dev/null
+++ b/application/admin/controller/shopro/GoodsSkuPrice.php
@@ -0,0 +1,35 @@
+model = new \app\admin\model\shopro\GoodsSkuPrice;
+
+ }
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+
+
+}
diff --git a/application/admin/controller/shopro/Link.php b/application/admin/controller/shopro/Link.php
new file mode 100644
index 000000000..b390fa033
--- /dev/null
+++ b/application/admin/controller/shopro/Link.php
@@ -0,0 +1,90 @@
+model = new \app\admin\model\shopro\Link;
+ $groupList = LinkModel::getGroupList();
+ $this->linklist = collection($this->model->select())->toArray();
+ $this->view->assign("groupList", $groupList);
+
+ $this->assignconfig('groupList', $groupList);
+
+
+ }
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+ /**
+ * 查看
+ */
+ public function index()
+ {
+ //设置过滤方法
+ $this->request->filter(['strip_tags']);
+ if ($this->request->isAjax()) {
+ $search = $this->request->request("search");
+ $group = $this->request->request("group");
+
+ //构造父类select列表选项数据
+ $list = [];
+
+ foreach ($this->linklist as $k => $v) {
+ if ($search) {
+ if ($v['group'] == $group && stripos($v['name'], $search) !== false || stripos($v['name'], $search) !== false) {
+ if ($group == "all" || $group == null) {
+ $list = $this->linklist;
+ } else {
+ $list[] = $v;
+ }
+ }
+ } else {
+ if ($group == "all" || $group == null) {
+ $list = $this->linklist;
+ } elseif ($v['group'] == $group) {
+ $list[] = $v;
+ }
+ }
+ }
+
+ $total = count($list);
+ $result = array("total" => $total, "rows" => $list);
+
+ return json($result);
+ }
+ return $this->view->fetch();
+ }
+ /**
+ * 选择链接
+ */
+ public function select()
+ {
+ if ($this->request->isAjax()) {
+ return $this->index();
+ }
+ return $this->view->fetch();
+ }
+
+}
diff --git a/application/admin/controller/shopro/Notification.php b/application/admin/controller/shopro/Notification.php
new file mode 100644
index 000000000..ce3279488
--- /dev/null
+++ b/application/admin/controller/shopro/Notification.php
@@ -0,0 +1,229 @@
+model = new \app\admin\model\shopro\Notification;
+ $this->modelConfig = new \app\admin\model\shopro\notification\Config;
+
+ }
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+
+
+ /**
+ * 查看
+ */
+ public function index()
+ {
+
+ }
+
+ public function config()
+ {
+ if ($this->request->isAjax()) {
+ if (!class_exists(\think\Queue::class)) {
+ $this->error('请安装 topthink/think-queue:v1.1.6 队列扩展');
+ }
+ // 消息类型
+ $notificationType = [
+ \addons\shopro\notifications\Groupon::class,
+ \addons\shopro\notifications\Order::class,
+ \addons\shopro\notifications\Refund::class
+ ];
+
+ // 获取所有要发送的消息
+ $fields = [];
+ foreach ($notificationType as $key => $class) {
+ $currentFields = $class::$returnField;
+ if ($currentFields) {
+ $fields = array_merge($fields, $currentFields);
+ }
+ }
+
+ // 读取数据库相关消息配置项
+ $notificationConfig = $this->modelConfig->select();
+
+ // 组合消息类型和设置值
+ $newFields = [];
+ foreach ($fields as $k => $field) {
+ // 组合每个平台的消息默认值和数据库值
+ $kConfig = $this->getKconfig($notificationConfig, $k, $field);
+
+ $newFields[] = [
+ 'type' => $k,
+ 'name' => $field['name'],
+ 'wxMiniProgram' => $kConfig['wxMiniProgram'] ?? [],
+ 'wxOfficialAccount' => $kConfig['wxOfficialAccount'] ?? [],
+ 'sms' => $kConfig['sms'] ?? []
+ ];
+ }
+
+ $this->success('设置成功', null, $newFields);
+ }
+
+ return $this->view->fetch();
+ }
+
+
+ // 配置状态
+ public function set_status() {
+ $platform = $this->request->post('platform', '');
+ $event = $this->request->post('event', '');
+ $name = $this->request->post('name', '');
+ $status = $this->request->post('status', 0);
+
+ if (!$platform || !$event) {
+ $this->error(__('Parameter %s can not be empty', ''));
+ }
+
+ $config = $this->modelConfig->where([
+ 'platform' => $platform,
+ 'event' => $event
+ ])->find();
+
+ if (!$config) {
+ $config = $this->modelConfig;
+ $config->platform = $platform;
+ $config->event = $event;
+ $config->name = $name;
+ }
+ $config->status = intval($status);
+ $config->save();
+
+ $this->success('设置成功');
+ }
+
+
+ // 配置模板
+ public function set_template()
+ {
+ $platform = $this->request->post('platform');
+ $event = $this->request->post('event');
+ $name = $this->request->post('name');
+ $content = $this->request->post('content', "");
+
+ if (!$platform || !$event) {
+ $this->error(__('Parameter %s can not be empty', ''));
+ }
+
+ $config = $this->modelConfig->where([
+ 'platform' => $platform,
+ 'event' => $event
+ ])->find();
+
+ if (!$config) {
+ $config = $this->modelConfig;
+ $config->platform = $platform;
+ $config->event = $event;
+ $config->name = $name;
+ }
+ $config->content = $content;
+ $config->save();
+
+ $this->success('设置成功');
+ }
+
+
+
+ private function getKConfig($notificationConfig, $k, $field) {
+ // 将默认值中追加 template_field 和 value 空字段
+ foreach ($field['fields'] as &$f) {
+ $f['template_field'] = $f['template_field'] ?? '';
+ $f['value'] = $f['value'] ?? '';
+ }
+
+ // 初始化defalut
+ $kConfig = [
+ 'wxMiniProgram' => [
+ 'id' => 0,
+ 'platform' => 'wxMiniProgram',
+ 'name' => $field['name'],
+ 'event' => $k,
+ 'status' => 0,
+ 'sendnum' => 0,
+ 'content_arr' => [
+ 'template_id' => '',
+ 'fields' => $field['fields']
+ ]
+ ],
+ 'wxOfficialAccount' => [
+ 'id' => 0,
+ 'platform' => 'wxOfficialAccount',
+ 'name' => $field['name'],
+ 'event' => $k,
+ 'status' => 0,
+ 'sendnum' => 0,
+ 'content_arr' => [
+ 'template_id' => '',
+ 'fields' => $field['fields']
+ ]
+ ],
+ 'sms' => [
+ 'id' => 0,
+ 'platform' => 'sms',
+ 'name' => $field['name'],
+ 'event' => $k,
+ 'status' => 0,
+ 'sendnum' => 0,
+ 'content_arr' => [
+ 'template_id' => '',
+ 'fields' => $field['fields']
+ ]
+ ]
+ ];
+
+ // 合并数据库中的设置
+ foreach ($notificationConfig as $config) {
+ if ($config['event'] == $k) {
+ $currentConfig = $config->toArray();
+
+ // 如果数据库中有内容
+ if ($currentConfig['content_arr']) {
+ $contentArr = $currentConfig['content_arr'];
+
+ // 合并,数据库和默认 fields 字段(发送类型增加返回字段时候有用)
+ $contentArrFields = [];
+ if (isset($contentArr['fields']) && $contentArr['fields']) { // 判断数组是否存在 fields 设置
+ $contentArrFields = array_column($contentArr['fields'], null, 'field');
+ }
+ $kConfigFields = array_column($kConfig[$config['platform']]['content_arr']['fields'], null, 'field');
+ $configField = array_merge($kConfigFields, $contentArrFields);
+
+ $contentArr['fields'] = array_values($configField);
+
+ $currentConfig['content_arr'] = $contentArr;
+ } else {
+ // 数据库有记录,但内容是空,(先开启了开关)
+ $currentConfig['content_arr'] = $kConfig[$config['platform']]['content_arr'];
+ }
+
+ $kConfig[$config['platform']] = $currentConfig;
+ }
+ }
+
+ return $kConfig;
+ }
+}
diff --git a/application/admin/controller/shopro/Richtext.php b/application/admin/controller/shopro/Richtext.php
new file mode 100644
index 000000000..8e480e5d5
--- /dev/null
+++ b/application/admin/controller/shopro/Richtext.php
@@ -0,0 +1,47 @@
+model = new \app\admin\model\shopro\Richtext;
+
+ }
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+
+ /**
+ * 选择富文本
+ */
+ public function select()
+ {
+ if ($this->request->isAjax()) {
+ return $this->index();
+ }
+ return $this->view->fetch();
+ }
+
+
+
+}
diff --git a/application/admin/controller/shopro/UserFake.php b/application/admin/controller/shopro/UserFake.php
new file mode 100644
index 000000000..d67a214a7
--- /dev/null
+++ b/application/admin/controller/shopro/UserFake.php
@@ -0,0 +1,101 @@
+model = new \app\admin\model\shopro\UserFake;
+
+ }
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+
+
+ /**
+ * 查看
+ */
+ public function index()
+ {
+ //当前是否为关联查询
+ $this->relationSearch = false;
+ //设置过滤方法
+ $this->request->filter(['strip_tags', 'trim']);
+ if ($this->request->isAjax())
+ {
+ //如果发送的来源是Selectpage,则转发到Selectpage
+ if ($this->request->request('keyField'))
+ {
+ return $this->selectpage();
+ }
+ list($where, $sort, $order, $offset, $limit) = $this->buildparams();
+ $total = $this->model
+
+ ->where($where)
+ ->order($sort, $order)
+ ->count();
+
+ $list = $this->model
+
+ ->where($where)
+ ->order($sort, $order)
+ ->limit($offset, $limit)
+ ->select();
+
+ foreach ($list as $row) {
+ $row->visible(['id','nickname','avatar']);
+
+ }
+ $list = collection($list)->toArray();
+ $result = array("total" => $total, "rows" => $list);
+
+ return json($result);
+ }
+ return $this->view->fetch();
+ }
+
+ /**
+ * 获取随机虚拟用户
+ */
+ public function random_user()
+ {
+ $userFake = $this->model->orderRaw('rand()')->find();
+ if ($userFake) {
+ $result = [
+ 'code' => 1,
+ 'data' => $userFake,
+ 'msg' => ''
+ ];
+ }else{
+ $result = [
+ 'code' => 0,
+ 'data' => null,
+ 'msg' => '资料管理中添加虚拟用户'
+ ];
+
+ }
+ return json($result);
+
+ }
+
+}
diff --git a/application/admin/controller/shopro/UserWalletApply.php b/application/admin/controller/shopro/UserWalletApply.php
new file mode 100644
index 000000000..2d1a50eb8
--- /dev/null
+++ b/application/admin/controller/shopro/UserWalletApply.php
@@ -0,0 +1,70 @@
+model = new \app\admin\model\shopro\UserWalletApply;
+ $this->view->assign("getTypeList", $this->model->getGetTypeList());
+ $this->view->assign("statusList", $this->model->getStatusList());
+ }
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+
+
+ public function applyOper($id)
+ {
+ $status = $this->request->post('status', -1);
+ $status_msg = $this->request->post('status_msg', '');
+
+ $apply = $this->model->get($id);
+
+ if ($apply->status != 0) {
+ $this->error('该提现申请已处理,不能重复处理');
+ }
+
+ $apply = Db::transaction(function () use ($apply, $status, $status_msg) {
+ $apply->status = $status;
+ $apply->status_msg = $status_msg;
+ $apply->save();
+
+ if ($status == -1) {
+ // 把提现的金额重新加回去
+ $total_money = $apply->money + $apply->charge_money;
+ $bank_info = json_decode($apply, true);
+ $ext = array_merge([
+ 'money' => $apply->money,
+ 'charge' => $apply->charge_money
+ ], $bank_info);
+
+ \addons\shopro\model\User::moneyAdd($apply->user_id, $total_money, 'cash_error', $apply->id, $ext);
+ }
+
+ return $apply;
+ });
+
+ return $this->success('操作成功', null, $apply);
+ }
+}
diff --git a/application/admin/controller/shopro/Wechat.php b/application/admin/controller/shopro/Wechat.php
new file mode 100644
index 000000000..d45be5fc7
--- /dev/null
+++ b/application/admin/controller/shopro/Wechat.php
@@ -0,0 +1,168 @@
+model = new \app\admin\model\shopro\Wechat;
+
+ }
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+
+
+ /**
+ * 查看
+ */
+ public function index()
+ {
+ //当前是否为关联查询
+ $this->relationSearch = false;
+ //设置过滤方法
+ $this->request->filter(['strip_tags', 'trim']);
+ if ($this->request->isAjax()) {
+ //如果发送的来源是Selectpage,则转发到Selectpage
+ if ($this->request->request('keyField')) {
+ return $this->selectpage();
+ }
+ list($where, $sort, $order, $offset, $limit) = $this->buildparams();
+ $total = $this->model
+ ->where($where)
+ ->order($sort, $order)
+ ->count();
+
+ $list = $this->model
+ ->where($where)
+ ->order($sort, $order)
+ ->limit($offset, $limit)
+ ->select();
+
+ foreach ($list as $row) {
+ $row->visible(['id', 'type', 'name', 'content', 'createtime', 'updatetime']);
+
+ }
+ $list = collection($list)->toArray();
+ $result = array("total" => $total, "rows" => $list);
+
+ return json($result);
+ }
+ return $this->view->fetch();
+ }
+
+ public function menu($id = 0, $act = '')
+ {
+ //预留后期多菜单管理
+ if ($id == 0) {
+ $wechatMenu = $this->model->where('type', 'menu')->select();
+ } else {
+ $wechatMenu = $this->model->get($id);
+ }
+ if ($this->request->isAjax()) {
+ //菜单详情
+ if ($act === '') {
+ $this->success($wechatMenu->name, '', $wechatMenu);
+ }
+ $content = $this->request->post('content');
+ //保存菜单
+ if ($act === 'save') {
+ $wechatMenu->content = $content;
+ $wechatMenu->save();
+ $this->success('保存成功', '', $wechatMenu);
+ }
+ //保存并发布菜单
+ if ($act === 'publish') {
+ $wechatMenu->content = $content;
+ $wechatMenu->save();
+ $wechat = new \addons\shopro\library\Wechat('wxOfficialAccount');
+ try {
+ $res = $wechat->menu('create', json_decode($content, true));
+ } catch (\Exception $e) { //如书写为(Exception $e)将无效
+ if (strpos($e->getMessage(), 'ip')) {
+ $this->error('请将当前IP地址加入公众号后台IP白名单');
+
+ }
+ }
+
+ if ($res['errcode'] !== 0) {
+ $this->error('格式不正确');
+ }
+ $this->success('发布成功', '', $wechatMenu);
+ }
+ }
+ $shopro = json_decode(\app\admin\model\shopro\Config::get(['name' => 'shopro'])->value, true);
+ $wxMiniProgram = json_decode(\app\admin\model\shopro\Config::get(['name' => 'wxMiniProgram'])->value, true);
+ $this->assignconfig('shopro', $shopro);
+ $this->assignconfig('wxMiniProgram', $wxMiniProgram);
+ return $this->view->fetch();
+ }
+
+ //粉丝管理
+ public function fans()
+ {
+ $params = $this->request->param();
+ extract($params);
+ $wechatFans = new \app\admin\model\shopro\WechatFans;
+
+ if ($this->request->isAjax()) {
+ if (!class_exists(\think\Queue::class)) {
+ $this->error('请安装 topthink/think-queue:v1.1.6 队列扩展');
+ }
+ //同步粉丝使用异步方法
+ if (isset($act) && $act == 'async') {
+ //批量更新粉色关注状态为未关注
+ $wechatFans->where('subscribe', 1)->update(['subscribe' => 0]);
+ $wechat = new \addons\shopro\library\Wechat('wxOfficialAccount');
+ try {
+ $res = $wechat->asyncFans();
+ } catch (\Exception $e) { //如书写为(Exception $e)将无效
+ if (strpos($e->getMessage(), 'ip')) {
+ $this->error('请将当前IP地址加入公众号后台IP白名单');
+ }
+ }
+ $this->success($res['msg']);
+ } else {
+ $fansData = $wechatFans->where('id|nickname|country|province|city', 'like', "%$searchKey%")->page($page)->paginate($limit);
+ $this->success('粉丝数据', '', $fansData);
+ }
+ }
+
+ return $this->view->fetch();
+ }
+
+ public function fans_user()
+ {
+ $get = $this->request->get();
+ $user = \think\Db::name('shopro_user_oauth')->where([
+ 'platform' => 'wxOfficialAccount',
+ 'openid' => $get['openid'],
+ ])->find();
+ if ($user) {
+ $user_id = $user['user_id'];
+ $this->redirect('user/user/index?id=' . $user_id);
+ } else {
+ $this->error('未找到用户');
+ }
+ }
+
+}
diff --git a/application/admin/controller/shopro/activity/Activity.php b/application/admin/controller/shopro/activity/Activity.php
new file mode 100644
index 000000000..52f257f81
--- /dev/null
+++ b/application/admin/controller/shopro/activity/Activity.php
@@ -0,0 +1,450 @@
+model = new \app\admin\model\shopro\activity\Activity;
+ $this->assignconfig("hasRedis", $this->hasRedis()); // 检测是否配置 redis
+ }
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+
+
+ /**
+ * 查看活动列表
+ */
+ public function index()
+ {
+ //设置过滤方法
+ $this->request->filter(['strip_tags']);
+ if ($this->request->isAjax()) {
+ if (!class_exists(\think\Queue::class)) {
+ $this->error('请安装 topthink/think-queue:v1.1.6 队列扩展');
+ }
+ //如果发送的来源是Selectpage,则转发到Selectpage
+ if ($this->request->request('keyField')) {
+ return $this->selectpage();
+ }
+
+ // list($where, $sort, $order, $offset, $limit) = $this->buildparams();
+ $sort = $this->request->get("sort", !empty($this->model) && $this->model->getPk() ? $this->model->getPk() : 'id');
+ $order = $this->request->get("order", "DESC");
+ $offset = $this->request->get("offset", 0);
+ $limit = $this->request->get("limit", 0);
+
+ $total = $this->buildSearch()
+ ->order($sort, $order)
+ ->count();
+
+ $list = $this->buildSearch()
+ ->order($sort, $order)
+ ->limit($offset, $limit)
+ ->select();
+
+ $list = collection($list)->toArray();
+ $result = array("total" => $total, "rows" => $list);
+
+ if ($this->request->get("page_type") == 'select') {
+ return json($result);
+ }
+
+ return $this->success('操作成功', null, $result);
+ }
+ return $this->view->fetch();
+ }
+
+
+ public function all() {
+ if ($this->request->isAjax()) {
+ $type = $this->request->get('type', 'all');
+
+ $sort = $this->request->get("sort", !empty($this->model) && $this->model->getPk() ? $this->model->getPk() : 'id');
+ $order = $this->request->get("order", "DESC");
+
+ $activities = $this->model->withTrashed(); // 包含被删除的
+ if ($type != 'all') {
+ $activities = $activities->where('type', $type);
+ }
+
+ $activities = $activities
+ ->field('id, title, type, starttime, endtime, rules')
+ ->order($sort, $order)
+ ->select();
+
+ $activities = collection($activities)->toArray();
+
+ return $this->success('操作成功', null, $activities);
+ }
+ }
+
+
+ /**
+ * 添加
+ */
+ public function add()
+ {
+ if ($this->request->isPost()) {
+ $params = $this->request->post();
+ if ($params) {
+ if ($params['starttime'] > $params['endtime'] || $params['endtime'] < date('Y-m-d H:i:s')) {
+ $this->error('请设置正确的活动时间');
+ }
+
+ $params = $this->preExcludeFields($params);
+
+ if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
+ $params[$this->dataLimitField] = $this->auth->id;
+ }
+ $result = false;
+ Db::startTrans();
+ try {
+ //是否采用模型验证
+ if ($this->modelValidate) {
+ $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
+ $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
+ $this->model->validateFailException(true)->validate($validate);
+ }
+ if (empty($params['type'])) {
+ $this->error('请选择营销类型');
+ }
+ $params['rules'] = json_encode($params['rules']);
+ $result = $this->model->allowField(true)->save($params);
+ $this->createOrUpdateSku($params['goods_list'], $this->model->id);
+
+ // 活动创建修改后
+ $data = [
+ 'activity' => $this->model
+ ];
+ \think\Hook::listen('activity_update_after', $data);
+
+ Db::commit();
+ } catch (ValidateException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (PDOException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (Exception $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ }
+ if ($result !== false) {
+ $this->success();
+ } else {
+ $this->error(__('No rows were inserted'));
+ }
+ }
+ $this->error(__('Parameter %s can not be empty', ''));
+ }
+
+ return $this->view->fetch();
+ }
+
+ public function createOrUpdateSku($goodsList, $activity_id)
+ {
+ //如果是编辑 先下架所有的规格产品,防止丢失历史销量数据;
+
+ \app\admin\model\shopro\activity\ActivitySkuPrice::where(['activity_id' => $activity_id])->update(['status' => 'down']);
+ $list = [];
+ foreach ($goodsList as $k => $g) {
+ $actSkuPrice[$k] = json_decode($g['actSkuPrice'], true);
+
+ if (!$actSkuPrice[$k]) {
+ $this->error('请完善完整规格');
+ }
+
+ foreach ($actSkuPrice[$k] as $a => $c) {
+ if ($c['id'] == 0) {
+ unset($c['id']);
+ }
+ unset($c['sales']);
+ $c['activity_id'] = $activity_id;
+ $c['goods_id'] = $g['id'];
+ $list[] = $c;
+ }
+ }
+ $act = new \app\admin\model\shopro\activity\ActivitySkuPrice;
+ $act->allowField(true)->saveAll($list);
+ }
+
+
+
+ /**
+ * 获取详情
+ */
+ public function detail ($ids = null) {
+ //详情
+ $row = $this->model->get($ids);
+ if (!$row) {
+ $this->error(__('No Results were found'));
+ }
+
+ $goods_ids_array = explode(',', $row->goods_ids);
+ $goodsList = [];
+ foreach ($goods_ids_array as $k => $g) {
+ $goods[$k] = \app\admin\model\shopro\Goods::field('id,title,image')->where('id', $g)->find();
+ $goods[$k]['actSkuPrice'] = json_encode(\app\admin\model\shopro\activity\ActivitySkuPrice::all(['goods_id' => $g, 'activity_id' => $ids]));
+
+ $goods[$k]['opt'] = 1;
+ $goodsList[] = $goods[$k];
+ }
+
+ $row->goods_list = $goodsList;
+
+ return $this->success('获取成功', null, $row);
+ }
+
+
+ /**
+ * 编辑
+ */
+ public function edit($ids = null)
+ {
+ //编辑
+ $row = $this->model->get($ids);
+ if (!$row) {
+ $this->error(__('No Results were found'));
+ }
+
+ $adminIds = $this->getDataLimitAdminIds();
+ if (is_array($adminIds)) {
+ if (!in_array($row[$this->dataLimitField], $adminIds)) {
+ $this->error(__('You have no permission'));
+ }
+ }
+ if ($this->request->isPost()) {
+ if ($row->starttime < time()) {
+ $this->error("活动正在进行中,不可编辑");
+ }
+
+ $params = $this->request->post();
+ if ($params) {
+ if ($params['starttime'] > $params['endtime'] || $params['endtime'] < date('Y-m-d H:i:s')) {
+ $this->error('请设置正确的活动时间');
+ }
+
+ $params = $this->preExcludeFields($params);
+
+ $result = false;
+ Db::startTrans();
+ try {
+ //是否采用模型验证
+ if ($this->modelValidate) {
+ $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
+ $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
+ $row->validateFailException(true)->validate($validate);
+ }
+
+ $params['rules'] = json_encode($params['rules']);
+
+ $result = $row->allowField(true)->save($params);
+ $this->createOrUpdateSku($params['goods_list'], $row->id);
+
+ // 活动创建修改后
+ $data = [
+ 'activity' => $row
+ ];
+ \think\Hook::listen('activity_update_after', $data);
+
+ Db::commit();
+ } catch (ValidateException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (PDOException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (Exception $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ }
+ if ($result !== false) {
+ $this->success();
+ } else {
+ $this->error(__('No rows were updated'));
+ }
+ }
+ $this->error(__('Parameter %s can not be empty', ''));
+ }
+ $this->assignconfig("activity", $row);
+ $this->view->assign("row", $row);
+ $this->assignconfig('id', $ids);
+
+ return $this->view->fetch();
+ }
+
+
+ /**
+ * 选择活动
+ */
+ public function select()
+ {
+ if ($this->request->isAjax()) {
+ return $this->index();
+ }
+ return $this->view->fetch();
+ }
+
+ public function sku($id, $activity_id, $type = '')
+ {
+ $type = $type ? : 'set';
+ if ($type == 'set') {
+ $act = \app\admin\model\shopro\activity\Activity::where('find_in_set(:id,goods_ids)', ['id' => $id])
+ ->where([
+ // 'starttime' => ['lt', time()],
+ // 'endtime' => ['gt', time()],
+ 'id' => ['neq', $activity_id]
+ ])->find();
+ if ($act) {
+ $this->error('该商品已在别的活动中参与');
+ }
+ }
+ $skuList = \app\admin\model\shopro\GoodsSku::all(['pid' => 0, 'goods_id' => $id]);
+ if ($skuList) {
+ foreach ($skuList as &$s) {
+ $s->children = \app\admin\model\shopro\GoodsSku::all(['pid' => $s->id, 'goods_id' => $id]);
+ }
+ }
+ $skuPrice = \app\admin\model\shopro\GoodsSkuPrice::all(['goods_id' => $id]);
+
+
+ //编辑
+ foreach ($skuPrice as $k => &$p) {
+ $actSkuPrice[$k] = \app\admin\model\shopro\activity\ActivitySkuPrice::get(['sku_price_id' => $p['id'], 'activity_id' => $activity_id]);
+
+ if (!$actSkuPrice[$k]) {
+
+ $actSkuPrice[$k]['id'] = 0;
+ $actSkuPrice[$k]['status'] = 'down';
+ $actSkuPrice[$k]['price'] = '';
+ $actSkuPrice[$k]['stock'] = '';
+ $actSkuPrice[$k]['sales'] = '0';
+ $actSkuPrice[$k]['sku_price_id'] = $p['id'];
+
+ }
+ }
+
+ $this->assignconfig('skuList', $skuList);
+
+ $this->assignconfig('skuPrice', $skuPrice);
+ $this->assignconfig('actSkuPrice', $actSkuPrice);
+
+ return $this->view->fetch();
+
+ }
+
+
+ /**
+ * 删除
+ */
+ public function del($ids = "")
+ {
+ if ($ids) {
+ $pk = $this->model->getPk();
+ $adminIds = $this->getDataLimitAdminIds();
+ if (is_array($adminIds)) {
+ $this->model->where($this->dataLimitField, 'in', $adminIds);
+ }
+ $list = $this->model->where($pk, 'in', $ids)->select();
+
+ $count = 0;
+ Db::startTrans();
+ try {
+ foreach ($list as $k => $v) {
+ $count += $v->delete();
+
+ // 删除之后事件
+ $data = [
+ 'activity' => $v
+ ];
+ \think\Hook::listen('activity_delete_after', $data);
+ }
+ Db::commit();
+ } catch (PDOException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (Exception $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ }
+ if ($count) {
+ $this->success();
+ } else {
+ $this->error(__('No rows were deleted'));
+ }
+ }
+ $this->error(__('Parameter %s can not be empty', 'ids'));
+ }
+
+
+
+ // 构建查询条件
+ private function buildSearch()
+ {
+ $search = $this->request->get("search", ''); // 关键字
+ $type = $this->request->get("type", 'all');
+ $status = $this->request->get("status", 'all');
+
+ $name = $this->model->getTable();
+ $tableName = $name . '.';
+
+ $activities = $this->model;
+
+ if ($search) {
+ // 模糊搜索字段
+ $searcharr = ['title'];
+ foreach ($searcharr as $k => &$v) {
+ $v = stripos($v, ".") === false ? $tableName . $v : $v;
+ }
+ unset($v);
+ $activities = $activities->where(function ($query) use ($searcharr, $search, $tableName) {
+ $query->where(implode("|", $searcharr), "LIKE", "%{$search}%");
+ });
+ }
+
+ // 活动类型
+ if ($type != 'all') {
+ $activities = $activities->where('type', 'like', '%' . $type . '%');
+ }
+ // 活动状态
+ if ($status != 'all') {
+ $where = [];
+ if ($status == 'ing') {
+ $where['starttime'] = ['<', time()];
+ $where['endtime'] = ['>', time()];
+ } else if ($status == 'nostart') {
+ $where['starttime'] = ['>', time()];
+ } else if ($status == 'ended') {
+ $where['endtime'] = ['<', time()];
+ }
+
+ $activities = $activities->where($where);
+ }
+
+ return $activities;
+ }
+
+}
diff --git a/application/admin/controller/shopro/activity/ActivitySkuPrice.php b/application/admin/controller/shopro/activity/ActivitySkuPrice.php
new file mode 100644
index 000000000..82aeb34c3
--- /dev/null
+++ b/application/admin/controller/shopro/activity/ActivitySkuPrice.php
@@ -0,0 +1,35 @@
+model = new \app\admin\model\shopro\activity\ActivitySkuPrice;
+
+ }
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+
+
+}
diff --git a/application/admin/controller/shopro/activity/Groupon.php b/application/admin/controller/shopro/activity/Groupon.php
new file mode 100644
index 000000000..c56f1c720
--- /dev/null
+++ b/application/admin/controller/shopro/activity/Groupon.php
@@ -0,0 +1,201 @@
+model = new \app\admin\model\shopro\activity\Groupon;
+ $this->view->assign("statusList", $this->model->getStatusList());
+ }
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+
+
+ /**
+ * 团列表
+ */
+ public function index()
+ {
+ //当前是否为关联查询
+ $this->relationSearch = false;
+ //设置过滤方法
+ $this->request->filter(['strip_tags', 'trim']);
+ if ($this->request->isAjax())
+ {
+ if (!class_exists(\think\Queue::class)) {
+ $this->error('请安装 topthink/think-queue:v1.1.6 队列扩展');
+ }
+ //如果发送的来源是Selectpage,则转发到Selectpage
+ if ($this->request->request('keyField'))
+ {
+ return $this->selectpage();
+ }
+
+ $sort = $this->request->get("sort", !empty($this->model) && $this->model->getPk() ? $this->model->getPk() : 'id');
+ $order = $this->request->get("order", "DESC");
+ $offset = $this->request->get("offset", 0);
+ $limit = $this->request->get("limit", 0);
+
+ $total = $this->buildSearch()
+ ->order($sort, $order)
+ ->count();
+
+ $list = $this->buildSearch()
+ ->with(['goods', 'user', 'grouponLog'])
+ ->order($sort, $order)
+ ->limit($offset, $limit)
+ ->select();
+
+ $list = collection($list)->toArray();
+ $result = array("total" => $total, "rows" => $list);
+
+ return $this->success('操作成功', null, $result);
+
+ return json($result);
+ }
+ return $this->view->fetch();
+ }
+
+ public function detail($id = null) {
+ if ($this->request->isAjax()){
+ $row = $this->model->with(['goods', 'user', 'grouponLog'])
+ ->where('id', $id)
+ ->find();
+
+ if (!$row) {
+ $this->error(__('No Results were found'));
+ }
+
+ return $this->success('获取成功', null, $row);
+ }
+ $this->assignconfig('id', $id);
+ return $this->view->fetch();
+ }
+
+
+ // 增加虚拟成团人数
+ public function addFictitious($id = null) {
+ $row = $this->model->where('id', $id)->find();
+
+ $avatar = $this->request->post('avatar', '');
+ $nickname = $this->request->post('nickname', '');
+
+ if (!$row) {
+ $this->error(__('No Results were found'));
+ }
+
+ if ($row['status'] != 'ing' || $row['current_num'] > $row['num']) {
+ $this->error('团已完成或已失效');
+ }
+
+ // 增加人数
+ $user = ['avatar' => $avatar, 'nickname' => $nickname];
+ $this->finishFictitiousGroupon($row, 1, [$user]);
+
+ // 重新获取团信息
+ $row = $this->model->with(['goods', 'user', 'grouponLog'])
+ ->where('id', $id)
+ ->find();
+
+ return $this->success('操作成功', null, $row);
+ }
+
+
+ // 解散团
+ public function invalidGroupon ($id = null) {
+ $row = $this->model->where('id', $id)->find();
+
+ if (!$row) {
+ $this->error(__('No Results were found'));
+ }
+
+ if ($row['status'] != 'ing') {
+ $this->error('团已完成或已失效');
+ }
+
+ // 解散团,并退款
+ $this->invalidRefundGroupon($row);
+
+ // 重新获取团信息
+ $row = $this->model->with(['goods', 'user', 'grouponLog'])
+ ->where('id', $id)
+ ->find();
+
+ return $this->success('解散成功', null, $row);
+ }
+
+
+ // 构建查询条件
+ private function buildSearch()
+ {
+ $search = $this->request->get("search", ''); // 关键字
+ $status = $this->request->get("status", 'all');
+ $activity_id = $this->request->get("activity_id", 0);
+
+ $name = $this->model->getTable();
+ $tableName = $name . '.';
+
+ $groupon = $this->model;
+
+ if ($search) {
+ // 模糊搜索字段
+ $groupon = $groupon->where(function ($query) use ($search, $tableName) {
+ $query->where(function ($query) use ($search, $tableName) {
+ $query->whereExists(function ($query) use ($search, $tableName) {
+ $goodsName = (new \app\admin\model\shopro\Goods())->getQuery()->getTable();
+
+ $query->table($goodsName)->where($goodsName . '.id=' . $tableName . 'goods_id')
+ ->where('title', 'like', "%{$search}%");
+ });
+ })
+ ->whereOr(function ($query) use ($search, $tableName) { // 用户
+ $query->whereExists(function ($query) use ($search, $tableName) {
+ $userTableName = (new \app\admin\model\User())->getQuery()->getTable();
+
+ $query->table($userTableName)->where($userTableName . '.id=' . $tableName . 'user_id')
+ ->where(function ($query) use ($search) {
+ $query->where('nickname', 'like', "%{$search}%")
+ ->whereOr('mobile', 'like', "%{$search}%");
+ });
+ });
+ });
+ });
+ }
+
+ // 活动类型
+ if ($activity_id) {
+ $groupon = $groupon->where('activity_id', $activity_id);
+ }
+ // 活动状态
+ if ($status != 'all') {
+ $status = $status == 'finish' ? ['finish', 'finish-fictitious'] : [$status];
+
+ $groupon = $groupon->where('status', 'in', $status);
+ }
+
+ return $groupon;
+ }
+}
diff --git a/application/admin/controller/shopro/app/Live.php b/application/admin/controller/shopro/app/Live.php
new file mode 100644
index 000000000..f038c3d77
--- /dev/null
+++ b/application/admin/controller/shopro/app/Live.php
@@ -0,0 +1,132 @@
+model = new \app\admin\model\shopro\app\Live;
+ $this->view->assign("liveStatusList", $this->model->getLiveStatusList());
+ }
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+
+
+ /**
+ * 查看
+ */
+ public function index()
+ {
+ //当前是否为关联查询
+ $this->relationSearch = false;
+ //设置过滤方法
+ $this->request->filter(['strip_tags', 'trim']);
+ if ($this->request->isAjax())
+ {
+ //如果发送的来源是Selectpage,则转发到Selectpage
+ if ($this->request->request('keyField'))
+ {
+ return $this->selectpage();
+ }
+ list($where, $sort, $order, $offset, $limit) = $this->buildparams();
+ $total = $this->model
+
+ ->where($where)
+ ->order($sort, $order)
+ ->count();
+
+ $list = $this->model
+
+ ->where($where)
+ ->order($sort, $order)
+ ->limit($offset, $limit)
+ ->select();
+
+ foreach ($list as $row) {
+ $row->visible(['id','name','room_id','live_status','starttime','endtime','anchor_name','share_img','createtime','updatetime']);
+
+ }
+ $list = collection($list)->toArray();
+ $result = array("total" => $total, "rows" => $list);
+
+ return json($result);
+ }
+
+ // 自动同步直播间
+ \app\admin\model\shopro\app\Live::autoSyncLive();
+
+ return $this->view->fetch();
+ }
+ /**
+ * 直播详情
+ */
+ public function detail($ids = null)
+ {
+ $row = $this->model->get($ids);
+ if (!$row) {
+ $this->error(__('No Results were found'));
+ }
+ $adminIds = $this->getDataLimitAdminIds();
+ if (is_array($adminIds)) {
+ if (!in_array($row[$this->dataLimitField], $adminIds)) {
+ $this->error(__('You have no permission'));
+ }
+ }
+
+ $this->view->assign("row", $row);
+ $this->view->assign("goods", $row->goods);
+
+ $liveLink = [];
+ if ($row['live_status'] == \app\admin\model\shopro\app\Live::STATUS_LIVED) {
+ // 直播已结束,显示 直播回放地址
+ // 自动同步回放地址
+ \app\admin\model\shopro\app\Live::autoSyncLiveLink($row);
+
+ // 获取回放地址
+ $liveLink = $row->links;
+ }
+
+ $this->view->assign("links", $liveLink);
+
+ return $this->view->fetch();
+ }
+
+
+ public function select()
+ {
+ if ($this->request->isAjax()) {
+ return $this->index();
+ }
+ return $this->view->fetch();
+ }
+
+
+
+ // 手动同步直播间
+ public function syncLive () {
+ // 手动同步直播间
+ \app\admin\model\shopro\app\Live::syncLive();
+
+ $this->success('同步成功');
+ }
+}
diff --git a/application/admin/controller/shopro/app/ScoreShop.php b/application/admin/controller/shopro/app/ScoreShop.php
new file mode 100644
index 000000000..6673481f2
--- /dev/null
+++ b/application/admin/controller/shopro/app/ScoreShop.php
@@ -0,0 +1,307 @@
+model = new \app\admin\model\shopro\Goods;
+ }
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+
+
+ /**
+ * 查看
+ */
+ public function index()
+ {
+ //当前是否为关联查询
+ $this->relationSearch = false;
+ //设置过滤方法
+ $this->request->filter(['strip_tags', 'trim']);
+ $scoreGoodsIds = array_column(\app\admin\model\shopro\app\ScoreSkuPrice::group('goods_id')->field('goods_id')->select(), 'goods_id');
+ if ($this->request->isAjax()) {
+ //如果发送的来源是Selectpage,则转发到Selectpage
+ if ($this->request->request('keyField')) {
+ return $this->selectpage();
+ }
+ list($where, $sort, $order, $offset, $limit) = $this->buildparams();
+ $total = $this->model
+ ->where(['id' => ['in', $scoreGoodsIds]])
+ ->where($where)
+ ->order($sort, $order)
+ ->count();
+
+ $list = $this->model
+ ->where(['id' => ['in', $scoreGoodsIds]])
+ ->where($where)
+ ->order($sort, $order)
+ ->limit($offset, $limit)
+ ->select();
+
+ foreach ($list as $row) {
+ $row->visible(['id', 'title', 'status', 'weigh', 'image']);
+
+ }
+ $list = collection($list)->toArray();
+ $result = array("total" => $total, "rows" => $list);
+
+ return json($result);
+ }
+ return $this->view->fetch();
+ }
+
+ /**
+ * 添加
+ */
+ public function add()
+ {
+ if ($this->request->isPost()) {
+ $params = $this->request->post("row/a");
+ if ($params) {
+ $params = $this->preExcludeFields($params);
+
+ if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
+ $params[$this->dataLimitField] = $this->auth->id;
+ }
+ $result = false;
+ Db::startTrans();
+ try {
+ //是否采用模型验证
+ if ($this->modelValidate) {
+ $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
+ $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
+ $this->model->validateFailException(true)->validate($validate);
+ }
+ $result = $this->createOrUpdateSku($params['goodsList']);
+
+ Db::commit();
+ } catch (ValidateException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (PDOException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (Exception $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ }
+ if ($result !== false) {
+ $this->success();
+ } else {
+ $this->error(__('No rows were inserted'));
+ }
+ }
+ $this->error(__('Parameter %s can not be empty', ''));
+ }
+ return $this->view->fetch();
+ }
+
+ /**
+ * 删除
+ */
+ public function del($ids = "")
+ {
+ if ($ids) {
+ $pk = $this->model->getPk();
+ $adminIds = $this->getDataLimitAdminIds();
+ if (is_array($adminIds)) {
+ $this->model->where($this->dataLimitField, 'in', $adminIds);
+ }
+ $score = new \app\admin\model\shopro\app\ScoreSkuPrice;
+ $list = $score->where('goods_id', 'in', $ids)->select();
+
+ $count = 0;
+ Db::startTrans();
+ try {
+ foreach ($list as $k => $v) {
+ $count += $v->delete();
+ }
+ Db::commit();
+ } catch (PDOException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (Exception $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ }
+ if ($count) {
+ $this->success();
+ } else {
+ $this->error(__('No rows were deleted'));
+ }
+ }
+ $this->error(__('Parameter %s can not be empty', 'ids'));
+ }
+
+
+ /**
+ * 编辑
+ */
+ public function edit($ids = null)
+ {
+ //编辑
+ $row = \app\admin\model\shopro\Goods::field('id,title,image')->where('id', $ids)->find();
+ if (!$row) {
+ $this->error(__('No Results were found'));
+ }
+ $goodsList = [];
+ foreach ([$row->id] as $k => $g) {
+ $goods[$k] = \app\admin\model\shopro\Goods::field('id,title,image')->where('id', $g)->find();
+ $goods[$k]['actSkuPrice'] = json_encode(\app\admin\model\shopro\app\ScoreSkuPrice::all(['goods_id' => $g,'deletetime' => null]));
+
+ $goods[$k]['opt'] = 1;
+ $goodsList[] = $goods[$k];
+ }
+
+
+ $adminIds = $this->getDataLimitAdminIds();
+ if (is_array($adminIds)) {
+ if (!in_array($row[$this->dataLimitField], $adminIds)) {
+ $this->error(__('You have no permission'));
+ }
+ }
+ if ($this->request->isPost()) {
+ $params = $this->request->post("row/a");
+ if ($params) {
+ $params = $this->preExcludeFields($params);
+ $result = false;
+ Db::startTrans();
+ try {
+ //是否采用模型验证
+ if ($this->modelValidate) {
+ $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
+ $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
+ $row->validateFailException(true)->validate($validate);
+ }
+
+
+ $result = $this->createOrUpdateSku($params['goodsList']);
+ Db::commit();
+ } catch (ValidateException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (PDOException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (Exception $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ }
+ if ($result !== false) {
+ $this->success();
+ } else {
+ $this->error(__('No rows were updated'));
+ }
+ }
+ $this->error(__('Parameter %s can not be empty', ''));
+ }
+ $this->assignconfig("goodsList", $goodsList);
+ $this->assignconfig('id', $ids);
+ return $this->view->fetch();
+ }
+
+ public function select()
+ {
+ if ($this->request->isAjax()) {
+ return $this->index();
+ }
+ return $this->view->fetch();
+ }
+
+ public function createOrUpdateSku($goodsList)
+ {
+ $goodsList = json_decode($goodsList, true);
+ $list = [];
+ foreach ($goodsList as $k => $g) {
+ $actSkuPrice[$k] = json_decode($g['actSkuPrice'], true);
+// halt($actSkuPrice[$k]);
+ if (!$actSkuPrice[$k]) {
+ $this->error('请完善完整规格');
+ }
+ \app\admin\model\shopro\app\ScoreSkuPrice::where(['goods_id' => $g['id']])->update(['status' => 'down']);
+
+
+ foreach ($actSkuPrice[$k] as $a => $c) {
+ if ($c['id'] == 0) {
+ unset($c['id']);
+ }
+ unset($c['sales']); //不更新销量
+ $c['goods_id'] = $g['id'];
+ $list[] = $c;
+ }
+ }
+ $score = new \app\admin\model\shopro\app\ScoreSkuPrice;
+ $score->allowField(true)->saveAll($list);
+ }
+
+ public function sku($goods_id,$id =1)
+ {
+ if ($id == 0) {
+ $scoreGoods = \app\admin\model\shopro\app\ScoreSkuPrice::where([
+ 'goods_id' => $goods_id,
+ 'status' => 'up',
+ 'deletetime' => null,
+ ])->find();
+ if ($scoreGoods) {
+ $this->error('该商品已参与积分换购');
+ }
+ }
+
+ $skuList = \app\admin\model\shopro\GoodsSku::all(['pid' => 0, 'goods_id' => $goods_id]);
+ if ($skuList) {
+ foreach ($skuList as &$s) {
+ $s->children = \app\admin\model\shopro\GoodsSku::all(['pid' => $s->id, 'goods_id' => $goods_id]);
+ }
+ }
+ $skuPrice = \app\admin\model\shopro\GoodsSkuPrice::all(['goods_id' => $goods_id]);
+
+
+ //编辑
+ foreach ($skuPrice as $k => &$p) {
+ $actSkuPrice[$k] = \app\admin\model\shopro\app\ScoreSkuPrice::get(['sku_price_id' => $p['id']]);
+
+ if (!$actSkuPrice[$k]) {
+
+ $actSkuPrice[$k]['id'] = 0;
+ $actSkuPrice[$k]['status'] = 'down';
+ $actSkuPrice[$k]['price'] = '';
+ $actSkuPrice[$k]['score'] = '';
+ $actSkuPrice[$k]['stock'] = '';
+ $actSkuPrice[$k]['sales'] = '0';
+ $actSkuPrice[$k]['sku_price_id'] = $p['id'];
+
+ }
+ }
+
+ $this->assignconfig('skuList', $skuList);
+
+ $this->assignconfig('skuPrice', $skuPrice);
+ $this->assignconfig('actSkuPrice', $actSkuPrice);
+
+ return $this->view->fetch();
+
+ }
+}
diff --git a/application/admin/controller/shopro/dispatch/Dispatch.php b/application/admin/controller/shopro/dispatch/Dispatch.php
new file mode 100644
index 000000000..a84111302
--- /dev/null
+++ b/application/admin/controller/shopro/dispatch/Dispatch.php
@@ -0,0 +1,114 @@
+model = new \app\admin\model\shopro\dispatch\Dispatch;
+ $this->view->assign("typeList", $this->model->getTypeList());
+ }
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+
+
+ /**
+ * 查看
+ */
+ public function index()
+ {
+ //当前是否为关联查询
+ $this->relationSearch = false;
+ //设置过滤方法
+ $this->request->filter(['strip_tags', 'trim']);
+ if ($this->request->isAjax())
+ {
+ //如果发送的来源是Selectpage,则转发到Selectpage
+ if ($this->request->request('keyField'))
+ {
+ return $this->selectpage();
+ }
+ list($where, $sort, $order, $offset, $limit) = $this->buildparams();
+ $total = $this->model
+
+ ->where($where)
+ ->order($sort, $order)
+ ->count();
+
+ $list = $this->model
+
+ ->where($where)
+ ->order($sort, $order)
+ ->limit($offset, $limit)
+ ->select();
+
+ foreach ($list as $row) {
+ $row->visible(['id','name','type','type_ids','createtime','updatetime']);
+
+ }
+ $list = collection($list)->toArray();
+ $result = array("total" => $total, "rows" => $list);
+
+ return json($result);
+ }
+ return $this->view->fetch();
+ }
+
+
+ /**
+ * 获取发货类型
+ */
+ public function typeList()
+ {
+ $typeList = $this->model->getTypeList();
+
+ $this->success('获取成功', null, $typeList);
+ }
+
+ /**
+ * 获取所有发货模板
+ */
+ public function all() {
+ if ($this->request->isAjax()) {
+ $type = $this->request->get('type', 'all');
+
+ $sort = $this->request->get("sort", !empty($this->model) && $this->model->getPk() ? $this->model->getPk() : 'id');
+ $order = $this->request->get("order", "DESC");
+
+ $dispatch = $this->model;
+ if ($type != 'all') {
+ $dispatch = $dispatch->where('type', 'in', explode(',', $type));
+ }
+
+ $dispatch = $dispatch->order($sort, $order)->select();
+
+ $newDispatch = [];
+ foreach ($dispatch as $val) {
+ $newDispatch[$val['type']]['name'] = $val['type_text'];
+ $newDispatch[$val['type']]['options'][] = $val;
+ }
+
+ return $this->success('操作成功', null, array_values($newDispatch));
+ }
+ }
+}
diff --git a/application/admin/controller/shopro/dispatch/Express.php b/application/admin/controller/shopro/dispatch/Express.php
new file mode 100644
index 000000000..3ebbb27e2
--- /dev/null
+++ b/application/admin/controller/shopro/dispatch/Express.php
@@ -0,0 +1,287 @@
+model = new \app\admin\model\shopro\dispatch\Express;
+
+
+ $this->view->assign("typeList", $this->model->getTypeList());
+ }
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+ /**
+ * 查看
+ */
+ public function index()
+ {
+ //当前是否为关联查询
+ $this->relationSearch = false;
+ //设置过滤方法
+ $this->request->filter(['strip_tags', 'trim']);
+ if ($this->request->isAjax()) {
+ //如果发送的来源是Selectpage,则转发到Selectpage
+ if ($this->request->request('keyField')) {
+ return $this->selectpage();
+ }
+ list($where, $sort, $order, $offset, $limit) = $this->buildparams();
+ $total = $this->model
+ ->where($where)
+ ->order($sort, $order)
+ ->count();
+
+ $list = $this->model
+ ->where($where)
+ ->order($sort, $order)
+ ->limit($offset, $limit)
+ ->select();
+
+
+ $list = collection($list)->toArray();
+ $result = array("total" => $total, "rows" => $list);
+
+ return json($result);
+ }
+ return $this->view->fetch();
+ }
+
+ /**
+ * 添加
+ */
+ public function add()
+ {
+ if ($this->request->isPost()) {
+ $params = $this->request->post("row/a");
+ if ($params) {
+ $params = $this->preExcludeFields($params);
+
+ if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
+ $params[$this->dataLimitField] = $this->auth->id;
+ }
+ $result = false;
+ Db::startTrans();
+ try {
+ //是否采用模型验证
+ if ($this->modelValidate) {
+ $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
+ $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
+ $this->model->validateFailException(true)->validate($validate);
+ }
+ $areaData = $params['area_data'];
+ $areaArray = json_decode($areaData, true);
+ foreach ($areaArray as $area) {
+ if ($area['name'] === 'province') {
+ $params['province_ids'] = implode(',', $area['value']);
+ }
+ if ($area['name'] === 'city') {
+ $params['city_ids'] = implode(',', $area['value']);
+ }
+ if ($area['name'] === 'area') {
+ $params['area_ids'] = implode(',', $area['value']);
+ }
+ }
+ $result = $this->model->allowField(true)->save($params);
+ Db::commit();
+ } catch (ValidateException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (PDOException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (Exception $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ }
+ if ($result !== false) {
+ $this->success();
+ } else {
+ $this->error(__('No rows were inserted'));
+ }
+ }
+ $this->error(__('Parameter %s can not be empty', ''));
+ }
+
+ $area = Db::name('shopro_area')->select();
+ $pca = [];
+ foreach ($area as $k => &$a) {
+ $a['flagLeft'] = 1;
+ $a['flagRight'] = 0;
+ switch ($a['level']) {
+ case 1:
+ $pca[$a['id']] = $a;
+ break;
+
+ case 2:
+ $pca[$a['pid']]['city'][$a['id']] = $a;
+ break;
+ case 3:
+ $pid = intval(substr($a['id'], 0, 2) . '0000');
+
+
+ $pca[$pid]['city'][$a['pid']]['area'][$a['id']] = $a;
+ }
+ }
+ $newPca = array_values($pca);
+ foreach ($newPca as $k => &$c) {
+ if (!isset($c['city'])) {
+ continue;
+ }
+ $c['city'] = array_values($c['city']);
+ foreach ($newPca[$k]['city'] as &$t) {
+ if (!isset($t['area'])) {
+ continue;
+ }
+ $t['area'] = array_values($t['area']);
+ }
+ }
+ $this->assignconfig('pca', $newPca);
+
+ return $this->view->fetch();
+ }
+
+ /**
+ * 编辑
+ */
+ public function edit($ids = null)
+ {
+ $row = $this->model->get($ids);
+ if (!$row) {
+ $this->error(__('No Results were found'));
+ }
+
+ $adminIds = $this->getDataLimitAdminIds();
+ if (is_array($adminIds)) {
+ if (!in_array($row[$this->dataLimitField], $adminIds)) {
+ $this->error(__('You have no permission'));
+ }
+ }
+ if ($this->request->isPost()) {
+ $params = $this->request->post("row/a");
+ if ($params) {
+ $params = $this->preExcludeFields($params);
+ $result = false;
+ Db::startTrans();
+ try {
+ //是否采用模型验证
+ if ($this->modelValidate) {
+ $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
+ $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
+ $row->validateFailException(true)->validate($validate);
+ }
+ $areaData = $params['area_data'];
+ $areaArray = json_decode($areaData, true);
+ foreach ($areaArray as $area) {
+ if ($area['name'] === 'province') {
+ $params['province_ids'] = implode(',', $area['value']);
+ }
+ if ($area['name'] === 'city') {
+ $params['city_ids'] = implode(',', $area['value']);
+ }
+ if ($area['name'] === 'area') {
+ $params['area_ids'] = implode(',', $area['value']);
+ }
+ }
+ $result = $row->allowField(true)->save($params);
+ Db::commit();
+ } catch (ValidateException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (PDOException $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ } catch (Exception $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ }
+ if ($result !== false) {
+ $this->success();
+ } else {
+ $this->error(__('No rows were updated'));
+ }
+ }
+ $this->error(__('Parameter %s can not be empty', ''));
+ }
+
+ $area = Db::name('shopro_area')->select();
+ $pca = [];
+ foreach ($area as $k => &$a) {
+ $a['flagLeft'] = 1;
+ $a['flagRight'] = 0;
+ switch ($a['level']) {
+ case 1:
+ $pca[$a['id']] = $a;
+ break;
+
+ case 2:
+ $pca[$a['pid']]['city'][$a['id']] = $a;
+ break;
+ case 3:
+ $pid = intval(substr($a['id'], 0, 2) . '0000');
+
+
+ $pca[$pid]['city'][$a['pid']]['area'][$a['id']] = $a;
+ }
+ }
+ $newPca = array_values($pca);
+ foreach ($newPca as $k => &$c) {
+ if (in_array($c['id'], explode(',', $row['province_ids']))) {
+ $c['flagLeft'] = 0;
+ $c['flagRight'] = 1;
+ }
+ $c['city'] = array_values($c['city']);
+ foreach ($newPca[$k]['city'] as &$t) {
+ if (in_array($t['id'], explode(',', $row['city_ids']))) {
+ $t['flagLeft'] = 0;
+ $t['flagRight'] = 1;
+ $c['flagRight'] = 1;
+ }
+ if ($c['flagRight'] === 1) {
+ $t['flagLeft'] = 0;
+ $t['flagRight'] = 1;
+ }
+ $t['area'] = array_values($t['area']);
+ foreach ($t['area'] as &$a) {
+ if (in_array($a['id'], explode(',', $row['area_ids']))) {
+ $a['flagLeft'] = 0;
+ $a['flagRight'] = 1;
+ $t['flagRight'] = 1;
+ $c['flagRight'] = 1;
+ }
+ if ($t['flagRight'] === 1) {
+ $a['flagLeft'] = 0;
+ $a['flagRight'] = 1;
+ }
+ }
+ }
+ }
+ $this->assignconfig('pca', $newPca);
+ $this->view->assign("row", $row);
+ return $this->view->fetch();
+ }
+
+
+}
diff --git a/application/admin/controller/shopro/order/Order.php b/application/admin/controller/shopro/order/Order.php
new file mode 100644
index 000000000..681c3643f
--- /dev/null
+++ b/application/admin/controller/shopro/order/Order.php
@@ -0,0 +1,614 @@
+loadlang('shopro/order/order_item');
+ $this->loadlang('shopro/dispatch/dispatch');
+
+ $this->model = new \app\admin\model\shopro\order\Order;
+ $this->view->assign("typeList", $this->model->getTypeList());
+ $this->view->assign("statusList", $this->model->getStatusList());
+ $this->view->assign("payTypeList", $this->model->getPayTypeList());
+ $this->view->assign("platformList", $this->model->getPlatformList());
+ }
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+
+
+ /**
+ * 查看
+ */
+ public function index()
+ {
+ //当前是否为关联查询
+ $this->relationSearch = true;
+ //设置过滤方法
+ $this->request->filter(['strip_tags', 'trim']);
+ if ($this->request->isAjax()) {
+ //如果发送的来源是Selectpage,则转发到Selectpage
+ if ($this->request->request('keyField')) {
+ return $this->selectpage();
+ }
+ // list($where, $sort, $order, $offset, $limit) = $this->buildparams();
+
+ $sort = $this->request->get("sort", !empty($this->model) && $this->model->getPk() ? $this->model->getPk() : 'id');
+ $order = $this->request->get("order", "DESC");
+ $offset = $this->request->get("offset", 0);
+ $limit = $this->request->get("limit", 0);
+
+ $total = $this->buildSearchOrder()
+ ->order($sort, $order)
+ ->count();
+
+ $list = $this->buildSearchOrder()
+ ->with(['user', 'item'])
+ ->order($sort, $order)
+ ->limit($offset, $limit)
+ ->select();
+
+ // foreach ($list as $row) {
+ // $row->visible(['id','type','order_sn','user','item','user_id','phone','consignee','province_name','city_name','area_name','address','status','memo','remark','total_amount','total_fee','createtime']);
+ // }
+
+ $list = collection($list)->toArray();
+ $result = array("total" => $total, "rows" => $list);
+
+ return $this->success('操作成功', null, $result);
+ }
+ return $this->view->fetch();
+ }
+
+
+ public function export()
+ {
+ $export = new Export();
+
+ $sort = $this->request->get("sort", !empty($this->model) && $this->model->getPk() ? $this->model->getPk() : 'id');
+ $order = $this->request->get("order", "DESC");
+ $list = $this->buildSearchOrder()
+ ->with(['user', 'item'])
+ ->order($sort, $order)
+ ->select();
+
+ $expCellName = [
+ 'order_id' => 'Id',
+ 'order_sn' => '订单号',
+ 'type_text' => '订单类型',
+ 'status_text' => '订单状态',
+ 'pay_type_text' => '支付类型',
+ 'paytime_text' => '支付时间',
+ 'platform_text' => '交易平台',
+ 'user_info' => '用户信息',
+ 'total_amount' => '订单总金额',
+ 'discount_fee' => '优惠金额',
+ 'pay_fee' => '实际支付金额',
+ 'score_fee' => '积分支付数量',
+ 'activity_type_text' => '营销类型',
+ 'goods_title' => '商品名称',
+ 'goods_original_price' => '商品原价',
+ 'goods_price' => '商品价格',
+ 'goods_sku_text' => '商品规格',
+ 'goods_num' => '购买数量',
+ 'dispatch_status_text' => '发货状态',
+ 'dispatch_fee' => '发货费用',
+ 'dispatch_type_text' => '发货方式',
+ 'aftersale_refund' => '售后/退款',
+ 'comment_status_text' => '评价状态',
+ 'refund_fee' => '退款金额',
+ 'refund_msg' => '退款原因',
+ 'express_name' => '快递公司',
+ 'express_no' => '快递单号',
+ ];
+
+ $newList = [];
+ foreach ($list as $key => $order) {
+ $data = [
+ 'order_id' => $order['id'],
+ 'order_sn' => $order['order_sn'],
+ 'type_text' => $order['type_text'],
+ 'status_text' => $order['status_text'],
+ 'pay_type_text' => $order['pay_type_text'],
+ 'paytime_text' => $order['paytime_text'],
+ 'platform_text' => $order['platform_text'],
+ 'user_info' => $order['user'] ? ($order['user']['nickname'] . '-' . $order['user']['mobile']) : '',
+ 'total_amount' => $order['total_amount'],
+ 'discount_fee' => $order['discount_fee'],
+ 'pay_fee' => $order['pay_fee'],
+ 'score_fee' => $order['score_fee'],
+ ];
+ foreach ($order['item'] as $k => $item) {
+ $itemData = [
+ 'activity_type_text' => $item['activity_type_text'],
+ 'goods_title' => $item['goods_title'],
+ 'goods_original_price' => $item['goods_original_price'],
+ 'goods_price' => $item['goods_price'],
+ 'goods_sku_text' => $item['goods_sku_text'],
+ 'goods_num' => $item['goods_num'],
+ 'dispatch_status_text' => $item['dispatch_status_text'],
+ 'dispatch_fee' => $item['dispatch_fee'],
+ 'dispatch_type_text' => $item['dispatch_type_text'],
+ 'aftersale_refund' => $item['aftersale_status_text'] . '/' . $item['refund_status_text'],
+ 'comment_status_text' => $item['comment_status_text'],
+ 'refund_fee' => $item['refund_fee'],
+ 'refund_msg' => $item['refund_msg'],
+ 'express_name' => $item['express_name'],
+ 'express_no' => $item['express_no'],
+ ];
+
+ $newList[] = array_merge($data, $itemData);
+ }
+ }
+
+ // 增加合计
+ $newList[] = [
+ 'order_id' => "订单总数:" . count($list) . ";订单总金额:¥" . array_sum(array_column($list, 'total_amount')) . ";优惠总金额:¥" . array_sum(array_column($list, 'discount_fee')) . ";实际支付总金额:¥" . array_sum(array_column($list, 'pay_fee')) . ";支付总积分:" . array_sum(array_column($list, 'score_fee'))
+ ];
+
+ $export->exportExcel('订单列表-' . date('Y-m-d H:i:s'), $expCellName, $newList);
+ }
+
+
+ // 获取要查询的订单类型
+ public function getType()
+ {
+ $type = $this->model->getTypeList();
+ $pay_type = $this->model->getPayTypeList();
+ $platform = $this->model->getPlatformList();
+ $dispatch_type = (new \app\admin\model\shopro\dispatch\Dispatch)->getTypeList();
+ $activity_type = (new \app\admin\model\shopro\activity\Activity)->getTypeList();
+
+ $result = [
+ 'type' => $type,
+ 'pay_type' => $pay_type,
+ 'platform' => $platform,
+ 'dispatch_type' => $dispatch_type,
+ 'activity_type' => $activity_type,
+ ];
+
+ $data = [];
+ foreach ($result as $key => $list) {
+ $data[$key][] = ['name' => '全部', 'type' => 'all'];
+
+ foreach ($list as $k => $v) {
+ $data[$key][] = [
+ 'name' => $v,
+ 'type' => $k
+ ];
+ }
+ }
+
+ return $this->success('操作成功', null, $data);
+ }
+
+
+ public function detail($id)
+ {
+ $row = $this->model->get($id);
+ $row->user = \app\admin\model\User::get($row->user_id);
+ $list = \app\admin\model\shopro\order\OrderItem::where(['order_id' => $id])->select();
+
+ $this->assignconfig('order', $row);
+ $this->assignconfig('item', $list);
+ return $this->view->fetch();
+ }
+
+ public function send($id, $item_id = '')
+ {
+ if ($this->request->isAjax()) {
+ $express_name = $this->request->post('express_name');
+ $express_no = $this->request->post('express_no');
+
+ $order = $this->model->where('status', \app\admin\model\shopro\order\Order::STATUS_PAYED)
+ ->where('id', $id)->find();
+
+ if (!$order) {
+ $this->error('订单不存在或未支付');
+ }
+
+ $where = ['order_id' => $id];
+ $where['dispatch_status'] = ['in', [
+ \app\admin\model\shopro\order\OrderItem::DISPATCH_STATUS_NOSEND,
+ \app\admin\model\shopro\order\OrderItem::DISPATCH_STATUS_SENDED
+ ]];
+ if ($item_id) {
+ $where['id'] = ['in', explode(',', $item_id)];
+ }
+
+ $item_list = \app\admin\model\shopro\order\OrderItem::where($where)->select();
+
+ if (!$item_list) {
+ $this->error('没有要发货的订单商品');
+ }
+
+ Db::transaction(function () use ($order, $item_list, $express_name, $express_no) {
+ foreach ($item_list as $key => $item) {
+ // 订单发货前
+ $data = ['order' => $order, 'item' => $item];
+ \think\Hook::listen('order_send_before', $data);
+
+ $item->express_name = $express_name;
+ $item->express_no = $express_no;
+ $item->dispatch_status = \app\admin\model\shopro\order\OrderItem::DISPATCH_STATUS_SENDED; // 已发货状态
+ $item->save();
+
+ \addons\shopro\model\OrderAction::operAdd($order, $item, $this->auth->getUserInfo(), 'admin', '管理员发货订单');
+
+ // 订单发货后
+ $data = ['order' => $order, 'item' => $item];
+ \think\Hook::listen('order_send_after', $data);
+ }
+ });
+
+ // 重新获取订单
+ $order = $this->model->with(['item'])->where('id', $id)->find();
+
+ return $this->success('操作成功', null, $order);
+ }
+ }
+
+
+ public function aftersaleFinish($id, $item_id)
+ {
+ if ($this->request->isAjax()) {
+
+ $where = [
+ 'order_id' => $id,
+ 'id' => $item_id,
+ 'aftersale_status' => \app\admin\model\shopro\order\OrderItem::AFTERSALE_STATUS_AFTERING
+ ];
+
+ $order = $this->model->where('status', 'in', [
+ \app\admin\model\shopro\order\Order::STATUS_PAYED,
+ \app\admin\model\shopro\order\Order::STATUS_FINISH
+ ]
+ )
+ ->where('id', $id)->find();
+ $item = \app\admin\model\shopro\order\OrderItem::where($where)->find();
+
+ if (!$order || !$item) {
+ $this->error('订单不存在或不是售后订单');
+ }
+
+ Db::transaction(function () use ($order, $item) {
+ $item->aftersale_status = \app\admin\model\shopro\order\OrderItem::AFTERSALE_STATUS_OK; // 售后完成
+ $item->save();
+
+ \addons\shopro\model\OrderAction::operAdd($order, $item, $this->auth->getUserInfo(), 'admin', '管理员售后完成订单');
+ });
+
+ $item_list = \app\admin\model\shopro\order\OrderItem::where(['order_id' => $id])->select();
+ return $this->success('操作成功', null, $item_list);
+ }
+ }
+
+
+ /**
+ * 拒绝退款
+ */
+ public function refundRefuse($id = 0, $item_id = 0)
+ {
+ if ($this->request->isAjax()) {
+ $refund_msg = $this->request->post('refund_msg');
+
+ $where = [
+ 'order_id' => $id,
+ 'id' => $item_id,
+ 'refund_status' => \app\admin\model\shopro\order\OrderItem::REFUND_STATUS_ING
+ ];
+
+ $order = $this->model->where('status', 'in', [
+ \app\admin\model\shopro\order\Order::STATUS_PAYED,
+ \app\admin\model\shopro\order\Order::STATUS_FINISH
+ ]
+ )->where('id', $id)->find();
+
+ $item = \app\admin\model\shopro\order\OrderItem::where($where)->find();
+
+ if (!$order || !$item) {
+ $this->error('订单不存在或不是退款订单');
+ }
+
+ Db::transaction(function () use ($order, $item, $refund_msg) {
+ // 订单退款拒绝前
+ $data = ['order' => $order, 'item' => $item];
+ \think\Hook::listen('order_refund_refuse_before', $data);
+
+ $item->refund_status = \app\admin\model\shopro\order\OrderItem::REFUND_STATUS_REFUSE; // 拒绝退款
+ $item->refund_msg = $refund_msg;
+ $item->save();
+
+ \addons\shopro\model\OrderAction::operAdd($order, $item, $this->auth->getUserInfo(), 'admin', '管理员拒绝订单退款');
+
+ // 订单退款拒绝后
+ $data = ['order' => $order, 'item' => $item];
+ \think\Hook::listen('order_refund_refuse_after', $data);
+ });
+
+ $item_list = \app\admin\model\shopro\order\OrderItem::where(['order_id' => $id])->select();
+ return $this->success('操作成功', null, $item_list);
+ }
+ }
+
+
+ /**
+ * 同意退款
+ */
+ public function refund($id = 0, $item_id = 0)
+ {
+ if ($this->request->isAjax()) {
+ $refund_money = $this->request->post('refund_money');
+
+ $where = [
+ 'order_id' => $id,
+ 'id' => $item_id,
+ 'refund_status' => \app\admin\model\shopro\order\OrderItem::REFUND_STATUS_ING
+ ];
+
+ $order = $this->model->where('status', 'in', [
+ \app\admin\model\shopro\order\Order::STATUS_PAYED,
+ \app\admin\model\shopro\order\Order::STATUS_FINISH
+ ]
+ )
+ ->where('id', $id)->find();
+ $item = \app\admin\model\shopro\order\OrderItem::where($where)->find();
+
+ if (!$order || !$item) {
+ $this->error('订单不存在或不是退款订单');
+ }
+
+ // 如果退款金额大于订单支付总金额
+ if ($refund_money > $order->total_fee) {
+ $this->error('退款金额不能大于实际支付金额');
+ }
+
+ Db::transaction(function () use ($order, $item, $refund_money) {
+ // 开始退款
+ \app\admin\model\shopro\order\Order::startRefund($order, $item, $refund_money, $this->auth->getUserInfo(), '管理员操作退款');
+ });
+
+ $item_list = \app\admin\model\shopro\order\OrderItem::where(['order_id' => $id])->select();
+ return $this->success('操作成功', null, $item_list);
+ }
+ }
+
+
+ // 取消订单
+ public function cancel($id)
+ {
+ if ($this->request->isAjax()) {
+ $order = $this->model->where('id', $id)->nopay()->find();
+ if (!$order) {
+ $this->error('订单不存在或已取消');
+ }
+
+ $order = $order->doCancel($order, $this->auth->getUserInfo(), 'admin');
+
+ return $this->success('操作成功', null, $order);
+ }
+ }
+
+
+ // 修改收货人信息
+ public function editConsignee($id)
+ {
+ if ($this->request->isAjax()) {
+ $params = $this->request->post();
+ extract($params);
+
+ $row = $this->model->get($id);
+ if (!$row) {
+ $this->error('订单不存在');
+ }
+
+ try {
+ if ($this->modelValidate) {
+ $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
+ $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
+ $row->validateFailException(true)->validate($validate);
+ }
+
+ $result = $row->save([
+ 'consignee' => $consignee,
+ 'phone' => $phone,
+ 'province_id' => $province_id,
+ 'province_name' => $province_name,
+ 'city_id' => $city_id,
+ 'city_name' => $city_name,
+ 'area_id' => $area_id,
+ 'area_name' => $area_name,
+ 'address' => $address,
+ ], ['id' => $id]);
+ } catch (ValidateException $e) {
+ $this->error($e->getMessage());
+ } catch (PDOException $e) {
+ $this->error($e->getMessage());
+ } catch (Exception $e) {
+ $this->error($e->getMessage());
+ }
+ if ($result !== false) {
+ $order = $this->model->get($id);
+ $this->success('修改成功', null, $order);
+ } else {
+ $this->error(__('No rows were updated'));
+ }
+ }
+ }
+
+ // 编辑商家备注
+ public function editMemo($id)
+ {
+ if ($this->request->isAjax()) {
+ $memo = $this->request->post('memo');
+
+ $order = $this->model->get($id);
+ if (!$order) {
+ $this->error('订单不存在');
+ }
+
+ $order->memo = $memo;
+ $order->save();
+
+ \addons\shopro\model\OrderAction::operAdd($order, null, $this->auth->getUserInfo(), 'admin', "修改备注:" . $memo);
+
+ return $this->success('操作成功', null, $order);
+ }
+ }
+
+
+ // 获取订单操作记录
+ public function actions($id)
+ {
+ $actions = \app\admin\model\shopro\order\OrderAction::with('oper')->where('order_id', $id)->select();
+
+ foreach ($actions as $key => $action) {
+ $action = $action->toArray();
+ if ($action['oper_type'] == 'admin') {
+ $oper = [
+ 'id' => $action['oper_id'],
+ 'name' => $action['oper'] ? $action['oper']['nickname'] : ''
+ ];
+ } else if ($action['oper_type'] == 'user') {
+ $oper = [
+ 'id' => $action['oper_id'],
+ 'name' => '用户'
+ ];
+ } else if ($action['oper_type'] == 'system') {
+ $oper = [
+ 'id' => $action['oper_id'],
+ 'name' => '系统'
+ ];
+ } else {
+ $oper = null;
+ }
+
+ $action['oper'] = $oper;
+ $actions[$key] = $action;
+ }
+
+ return $this->success('操作成功', null, $actions);
+ }
+
+
+ // 构建查询条件
+ private function buildSearchOrder()
+ {
+ $search = $this->request->get("search", ''); // 关键字
+ $type = $this->request->get("type", 'all');
+ $pay_type = $this->request->get("pay_type", 'all');
+ $platform = $this->request->get("platform", 'all');
+ $activity_type = $this->request->get("activity_type", 'all');
+ $dispatch_type = $this->request->get("dispatch_type", 'all');
+ $status = $this->request->get("status", 'all');
+ $datetimerange = array_filter(explode(' - ', $this->request->get('datetimerange', '')));
+
+ $name = $this->model->getTable();
+ $tableName = $name . '.';
+
+ $orders = $this->model;
+
+ if ($search) {
+ // 模糊搜索字段
+ $searcharr = ['order_sn', 'consignee', 'phone', 'province_name', 'city_name', 'area_name', 'address'];
+ foreach ($searcharr as $k => &$v) {
+ $v = stripos($v, ".") === false ? $tableName . $v : $v;
+ }
+ unset($v);
+ $orders = $orders->where(function ($query) use ($searcharr, $search, $tableName) {
+ $query->where(implode("|", $searcharr), "LIKE", "%{$search}%")
+ ->whereOr(function ($query) use ($search, $tableName) {
+ $query->whereExists(function ($query) use ($search, $tableName) {
+ $itemTableName = (new \app\admin\model\shopro\order\OrderItem())->getQuery()->getTable();
+
+ $query->table($itemTableName)->where($itemTableName . '.order_id=' . $tableName . 'id')
+ ->where('goods_title', 'like', "%{$search}%");
+ });
+ })
+ ->whereOr(function ($query) use ($search, $tableName) { // 用户
+ $query->whereExists(function ($query) use ($search, $tableName) {
+ $userTableName = (new \app\admin\model\User())->getQuery()->getTable();
+
+ $query->table($userTableName)->where($userTableName . '.id=' . $tableName . 'user_id')
+ ->where(function ($query) use ($search) {
+ $query->where('nickname', 'like', "%{$search}%")
+ ->whereOr('mobile', 'like', "%{$search}%");
+ });
+ });
+ });
+ });
+ }
+
+ // 订单类型
+ if ($type != 'all') {
+ $orders = $orders->where('type', $type);
+ }
+ // 支付类型
+ if ($pay_type != 'all') {
+ $orders = $orders->where('pay_type', $pay_type);
+ }
+ // 下单平台
+ if ($platform != 'all') {
+ $orders = $orders->where('platform', $platform);
+ }
+ // 营销活动
+ if ($activity_type != 'all') {
+ $orders = $orders->where('activity_type', 'like', '%' . $activity_type . '%');
+ }
+ // 快递方式
+ if ($dispatch_type != 'all') {
+ $orders = $orders->whereExists(function ($query) use ($dispatch_type, $tableName) {
+ $itemTableName = (new \app\admin\model\shopro\order\OrderItem())->getQuery()->getTable();
+
+ $query->table($itemTableName)->where($itemTableName . '.order_id=' . $tableName . 'id')
+ ->where('dispatch_type', $dispatch_type);
+ });
+ }
+ // 下单时间
+ if ($datetimerange) {
+ $startTime = strtotime($datetimerange[0]);
+ $endTime = strtotime($datetimerange[1]);
+
+ $orders = $orders->where('createtime', 'between', [$startTime, $endTime]);
+ }
+ // 订单状态
+ if ($status != 'all') {
+ if (in_array($status, ['invalid', 'cancel', 'nopay', 'nosend', 'noget', 'nocomment', 'aftersale', 'refund', 'payed', 'finish'])) {
+ if (in_array($status, ['nosend', 'noget', 'nocomment', 'aftersale', 'refund'])) {
+ $orders = $orders->payed();
+ }
+ $status = $status == 'refund' ? 'refundStatus' : $status;
+ $orders = $orders->{$status}(false);
+ }
+ }
+
+ return $orders;
+ }
+}
diff --git a/application/admin/controller/shopro/order/OrderItem.php b/application/admin/controller/shopro/order/OrderItem.php
new file mode 100644
index 000000000..853959163
--- /dev/null
+++ b/application/admin/controller/shopro/order/OrderItem.php
@@ -0,0 +1,38 @@
+model = new \app\admin\model\shopro\order\OrderItem;
+ $this->view->assign("dispatchStatusList", $this->model->getDispatchStatusList());
+ $this->view->assign("aftersaleStatusList", $this->model->getAftersaleStatusList());
+ $this->view->assign("commentStatusList", $this->model->getCommentStatusList());
+ $this->view->assign("refundStatusList", $this->model->getRefundStatusList());
+ }
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+
+
+}
diff --git a/application/admin/lang/zh-cn/faqueue/log.php b/application/admin/lang/zh-cn/faqueue/log.php
new file mode 100644
index 000000000..c21f59125
--- /dev/null
+++ b/application/admin/lang/zh-cn/faqueue/log.php
@@ -0,0 +1,9 @@
+ '队列名',
+ 'Job' => '执行类',
+ 'Data' => '任务数据',
+ 'Create_time' => '任务完成时间',
+ 'Update_time' => '更新时间'
+];
diff --git a/application/admin/lang/zh-cn/shopro/activity/activity.php b/application/admin/lang/zh-cn/shopro/activity/activity.php
new file mode 100644
index 000000000..6d642c601
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/activity/activity.php
@@ -0,0 +1,14 @@
+ '活动名称',
+ 'Goods_ids' => '商品组',
+ 'Type' => '类型',
+ 'Description' => '活动说明',
+ 'Starttime' => '开始时间',
+ 'Endtime' => '结束时间',
+ 'Rules' => '活动规则',
+ 'Createtime' => '创建时间',
+ 'Updatetime' => '更新时间',
+ 'Deletetime' => '删除时间'
+];
diff --git a/application/admin/lang/zh-cn/shopro/activity/activity_sku_price.php b/application/admin/lang/zh-cn/shopro/activity/activity_sku_price.php
new file mode 100644
index 000000000..214ad9657
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/activity/activity_sku_price.php
@@ -0,0 +1,12 @@
+ '活动 id',
+ 'Sku_price_id' => '规格 id',
+ 'Goods_id' => '所属产品',
+ 'Stock' => '库存',
+ 'Sales' => '已售',
+ 'Price' => '价格',
+ 'Createtime' => '添加时间',
+ 'Updatetime' => '更新时间'
+];
diff --git a/application/admin/lang/zh-cn/shopro/activity/groupon.php b/application/admin/lang/zh-cn/shopro/activity/groupon.php
new file mode 100644
index 000000000..1970560c5
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/activity/groupon.php
@@ -0,0 +1,16 @@
+ '团长',
+ 'Goods_id' => '商品',
+ 'Activity_id' => '活动',
+ 'Num' => '成团人数',
+ 'Current_num' => '当前人数',
+ 'Status' => '状态',
+ 'Status invalid' => '已过期',
+ 'Status ing' => '进行中',
+ 'Status finish' => '已成团',
+ 'Status finish-fictitious' => '虚拟成团',
+ 'Createtime' => '添加时间',
+ 'Updatetime' => '更新时间'
+];
diff --git a/application/admin/lang/zh-cn/shopro/app/live.php b/application/admin/lang/zh-cn/shopro/app/live.php
new file mode 100644
index 000000000..8dc71c33d
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/app/live.php
@@ -0,0 +1,23 @@
+ '房间名',
+ 'Room_id' => '房间 ID',
+ 'Cover_img' => '房间背景',
+ 'Live_status' => '直播状态',
+ 'Live_status 101' => '直播中',
+ 'Live_status 102' => '未开始',
+ 'Live_status 103' => '已结束',
+ 'Live_status 104' => '禁播',
+ 'Live_status 105' => '暂停中',
+ 'Live_status 106' => '异常',
+ 'Live_status 107' => '已过期',
+ 'Starttime' => '开始时间',
+ 'Endtime' => '结束时间',
+ 'Anchor_name' => '主播',
+ 'Anchor_img' => '主播头像',
+ 'Share_img' => '分享封面',
+ 'Createtime' => '创建时间',
+ 'Updatetime' => '更新时间',
+ 'Deletetime' => '删除时间'
+];
diff --git a/application/admin/lang/zh-cn/shopro/app/score_shop.php b/application/admin/lang/zh-cn/shopro/app/score_shop.php
new file mode 100644
index 000000000..cb34e85a0
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/app/score_shop.php
@@ -0,0 +1,9 @@
+ '缩略图',
+ 'Status' => '上架状态',
+ 'Status up' => '上架',
+ 'Status hidden' => '隐藏',
+ 'Status down' => '下架',
+];
diff --git a/application/admin/lang/zh-cn/shopro/area.php b/application/admin/lang/zh-cn/shopro/area.php
new file mode 100644
index 000000000..19db0c3f8
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/area.php
@@ -0,0 +1,7 @@
+ '名称',
+ 'Pid' => '上级',
+ 'Level' => '层级'
+];
diff --git a/application/admin/lang/zh-cn/shopro/category.php b/application/admin/lang/zh-cn/shopro/category.php
new file mode 100644
index 000000000..379f5178c
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/category.php
@@ -0,0 +1,13 @@
+ '分类名称',
+ 'Pid' => '上级分类',
+ 'Weigh' => '排序',
+ 'Image' => '分类图片',
+ 'Shop' => '商城分类',
+ 'Custom' => '自定义商品组',
+ 'Description' => '描述',
+ 'Status' => '状态',
+ 'Createtime' => '创建时间'
+];
diff --git a/application/admin/lang/zh-cn/shopro/config.php b/application/admin/lang/zh-cn/shopro/config.php
new file mode 100644
index 000000000..e14d172e2
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/config.php
@@ -0,0 +1,67 @@
+ '变量名',
+ 'Tip' => '提示信息',
+ 'Group' => '分组',
+ 'Type' => '类型',
+ 'Title' => '变量标题',
+ 'Value' => '变量值',
+ 'Basic' => '基础配置',
+ 'Payment' => '支付配置',
+ 'Wx' => '渠道配置',
+ 'Email' => '邮件配置',
+ 'Attachment' => '附件配置',
+ 'Dictionary' => '字典配置',
+ 'User' => '会员配置',
+ 'Example' => '示例分组',
+ 'Extend' => '扩展属性',
+ 'String' => '字符',
+ 'Text' => '文本',
+ 'Editor' => '编辑器',
+ 'Number' => '数字',
+ 'Date' => '日期',
+ 'Time' => '时间',
+ 'Datetime' => '日期时间',
+ 'Image' => '图片',
+ 'Images' => '图片(多)',
+ 'File' => '文件',
+ 'Files' => '文件(多)',
+ 'Select' => '列表',
+ 'Selects' => '列表(多选)',
+ 'Switch' => '开关',
+ 'Checkbox' => '复选',
+ 'Radio' => '单选',
+ 'Array' => '数组',
+ 'Array key' => '键名',
+ 'Array value' => '键值',
+ 'Custom' => '自定义',
+ 'Content' => '数据列表',
+ 'Rule' => '校验规则',
+ 'Site name' => '站点名称',
+ 'Beian' => '备案号',
+ 'Cdn url' => 'CDN地址',
+ 'Version' => '版本号',
+ 'Timezone' => '时区',
+ 'Forbidden ip' => '禁止IP',
+ 'Languages' => '语言',
+ 'Fixed page' => '后台固定页',
+ 'Category type' => '分类类型',
+ 'Config group' => '配置分组',
+ 'Rule tips' => '校验规则使用请参考Nice-validator文档',
+ 'Extend tips' => '扩展属性支持{id}、{name}、{group}、{title}、{value}、{content}、{rule}替换',
+ 'Mail type' => '邮件发送方式',
+ 'Mail smtp host' => 'SMTP服务器',
+ 'Mail smtp port' => 'SMTP端口',
+ 'Mail smtp user' => 'SMTP用户名',
+ 'Mail smtp password' => 'SMTP密码',
+ 'Mail vertify type' => 'SMTP验证方式',
+ 'Mail from' => '发件人邮箱',
+ 'Name already exist' => '变量名称已经存在',
+ 'Add new config' => '点击添加新的配置',
+ 'Send a test message' => '发送测试邮件',
+ 'This is a test mail content' => '这是一封来自FastAdmin校验邮件,用于校验邮件配置是否正常!',
+ 'This is a test mail' => '这是一封来自FastAdmin的邮件',
+ 'Please input your email' => '请输入测试接收者邮箱',
+ 'Please input correct email' => '请输入正确的邮箱地址',
+];
diff --git a/application/admin/lang/zh-cn/shopro/coupons.php b/application/admin/lang/zh-cn/shopro/coupons.php
new file mode 100644
index 000000000..3780ad449
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/coupons.php
@@ -0,0 +1,16 @@
+ '名称',
+ 'Goods_ids' => '适用商品',
+ 'Amount' => '券面额',
+ 'Enough' => '消费门槛',
+ 'Stock' => '库存',
+ 'Limit' => '每人限制',
+ 'Gettime' => '领取周期',
+ 'Usetime' => '有效期',
+ 'Description' => '描述',
+ 'Createtime' => '创建时间',
+ 'Updatetime' => '更新时间',
+ 'Deletetime' => '删除时间'
+];
diff --git a/application/admin/lang/zh-cn/shopro/decorate.php b/application/admin/lang/zh-cn/shopro/decorate.php
new file mode 100644
index 000000000..6bbbf0813
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/decorate.php
@@ -0,0 +1,19 @@
+ '模板名称',
+ 'Memo' => '备注',
+ 'Status' => '状态',
+ 'Platform' => '适用平台',
+ 'Platform h5' => 'H5',
+ 'Platform wxofficialaccount' => '微信公众号网页',
+ 'Platform wxminiprogram' => '微信小程序',
+ 'Platform app' => 'App',
+ 'Createtime' => '创建时间',
+ 'Updatetime' => '更新时间',
+ 'Deletetime' => '删除时间',
+ 'H5' => 'H5网页',
+ 'wxOfficialAccount' => '微信公众号',
+ 'wxMiniProgram' => '微信小程序',
+ 'App' => 'App'
+];
diff --git a/application/admin/lang/zh-cn/shopro/dispatch/dispatch.php b/application/admin/lang/zh-cn/shopro/dispatch/dispatch.php
new file mode 100644
index 000000000..25576fd2c
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/dispatch/dispatch.php
@@ -0,0 +1,14 @@
+ '名称',
+ 'Type' => '发货方式',
+ 'Type express' => '物流快递',
+ 'Type selfetch' => '用户自提',
+ 'Type store' => '商户配送',
+ 'Type autosend' => '自动发货',
+ 'Type_ids' => '包含模板',
+ 'Createtime' => '创建时间',
+ 'Updatetime' => '更新时间',
+ 'Deletetime' => '删除时间'
+];
diff --git a/application/admin/lang/zh-cn/shopro/dispatch/express.php b/application/admin/lang/zh-cn/shopro/dispatch/express.php
new file mode 100644
index 000000000..0bb537b49
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/dispatch/express.php
@@ -0,0 +1,18 @@
+ '模板名称',
+ 'Type' => '计费方式',
+ 'Type number' => '件数',
+ 'Type weight' => '重量',
+ 'Weigh' => '权重',
+ 'First_price' => '首(重/件)价格',
+ 'Additional_num' => '续(重/件)数',
+ 'Additional_price' => '续(重/件)价格',
+ 'Province_ids' => '省份',
+ 'City_ids' => '市级',
+ 'Area_ids' => '区域',
+ 'Createtime' => '创建时间',
+ 'Updatetime' => '更新时间',
+ 'Deletetime' => '删除时间'
+];
diff --git a/application/admin/lang/zh-cn/shopro/faq.php b/application/admin/lang/zh-cn/shopro/faq.php
new file mode 100644
index 000000000..cd8630d32
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/faq.php
@@ -0,0 +1,9 @@
+ '标题',
+ 'Content' => '内容',
+ 'Createtime' => '创建时间',
+ 'Updatetime' => '更新时间',
+ 'Deletetime' => '删除时间'
+];
diff --git a/application/admin/lang/zh-cn/shopro/feedback.php b/application/admin/lang/zh-cn/shopro/feedback.php
new file mode 100644
index 000000000..54b9e42fd
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/feedback.php
@@ -0,0 +1,16 @@
+ '反馈用户',
+ 'Type' => '反馈类型',
+ 'Content' => '反馈内容',
+ 'Images' => '图片',
+ 'Phone' => '联系电话',
+ 'Status' => '是否处理',
+ 'Status 0' => '未处理',
+ 'Status 1' => '已处理',
+ 'Remark' => '处理备注',
+ 'Createtime' => '创建时间',
+ 'Updatetime' => '更新时间',
+ 'Deletetime' => '删除时间'
+];
diff --git a/application/admin/lang/zh-cn/shopro/goods.php b/application/admin/lang/zh-cn/shopro/goods.php
new file mode 100644
index 000000000..09c374dd7
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/goods.php
@@ -0,0 +1,35 @@
+ '商品类型',
+ 'Type normal' => '实体商品',
+ 'Type virtual' => '虚拟商品',
+ 'Title' => '标题',
+ 'Subtitle' => '副标题',
+ 'Status' => '商品状态',
+ 'Status up' => '上架',
+ 'Status hidden' => '隐藏',
+ 'Status down' => '下架',
+ 'Weigh' => '排序(从大到小)',
+ 'Category_ids' => '所属分类',
+ 'Image' => '商品主图',
+ 'Images' => '轮播图',
+ 'Params' => '参数详情',
+ 'Content' => '图文详情',
+ 'Price' => '价格',
+ 'Original_price' => '原价',
+ 'Likes' => '收藏人数',
+ 'Views' => '浏览人数',
+ 'Sales' => '真实销量',
+ 'Show_sales' => '虚增销量',
+ 'Service_ids' => '服务标签',
+ 'Dispatch_type' => '发货方式',
+ 'Dispatch_type express' => '物流快递',
+ 'Dispatch_type selfetch' => '自提',
+ 'Dispatch_type store' => '商家配送',
+ 'Dispatch_type autosend' => '自动发货',
+ 'Dispatch_ids' => '发货模板',
+ 'Createtime' => '添加时间',
+ 'Updatetime' => '更新时间',
+ 'Deletetime' => '删除时间'
+];
diff --git a/application/admin/lang/zh-cn/shopro/goods_comment.php b/application/admin/lang/zh-cn/shopro/goods_comment.php
new file mode 100644
index 000000000..ea2a6dac5
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/goods_comment.php
@@ -0,0 +1,26 @@
+ '评论 id',
+ 'Goods_id' => '商品',
+ 'Order_id' => '订单',
+ 'Order_item_id' => '订单商品',
+ 'User_id' => '用户',
+ 'Level' => '评价星级',
+ 'Content' => '评价内容',
+ 'Images' => '评价图片',
+ 'Status' => '显示状态',
+ 'Status show' => '显示',
+ 'Status hidden' => '隐藏',
+ 'Admin_id' => '管理员 id',
+ 'Reply_content' => '回复内容',
+ 'Replytime' => '回复时间',
+ 'Createtime' => '评论时间',
+ 'Updatetime' => '更新时间',
+ 'Deletetime' => '删除时间',
+ 'Shoprogoods.title' => '标题',
+ 'User.id' => 'ID',
+ 'User.nickname' => '昵称',
+ 'Admin.id' => 'ID',
+ 'Admin.nickname' => '昵称'
+];
diff --git a/application/admin/lang/zh-cn/shopro/goods_service.php b/application/admin/lang/zh-cn/shopro/goods_service.php
new file mode 100644
index 000000000..23ca86b4b
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/goods_service.php
@@ -0,0 +1,9 @@
+ '名称',
+ 'Image' => '服务标志',
+ 'Description' => '描述',
+ 'Createtime' => '添加时间',
+ 'Updatetime' => '更新时间'
+];
diff --git a/application/admin/lang/zh-cn/shopro/goods_sku.php b/application/admin/lang/zh-cn/shopro/goods_sku.php
new file mode 100644
index 000000000..904f735d6
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/goods_sku.php
@@ -0,0 +1,8 @@
+ '名称',
+ 'Pid' => '所属规格',
+ 'Goods_id' => '产品',
+ 'Weigh' => '排序'
+];
diff --git a/application/admin/lang/zh-cn/shopro/goods_sku_price.php b/application/admin/lang/zh-cn/shopro/goods_sku_price.php
new file mode 100644
index 000000000..405fd5a07
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/goods_sku_price.php
@@ -0,0 +1,15 @@
+ '所属产品',
+ 'Weigh' => '排序',
+ 'Image' => '缩略图',
+ 'Stock' => '库存',
+ 'Sales' => '已售',
+ 'Sn' => '货号',
+ 'Weight' => '重量(kg)',
+ 'Price' => '价格',
+ 'Status' => '状态',
+ 'Createtime' => '添加时间',
+ 'Updatetime' => '更新时间'
+];
diff --git a/application/admin/lang/zh-cn/shopro/goodsservice.php b/application/admin/lang/zh-cn/shopro/goodsservice.php
new file mode 100644
index 000000000..198273d47
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/goodsservice.php
@@ -0,0 +1,7 @@
+ '名称',
+ 'Image' => '服务标志',
+ 'Description' => '描述'
+];
diff --git a/application/admin/lang/zh-cn/shopro/link.php b/application/admin/lang/zh-cn/shopro/link.php
new file mode 100644
index 000000000..adfd82344
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/link.php
@@ -0,0 +1,10 @@
+ '名称',
+ 'Path' => '路径',
+ 'Group' => '所属分组',
+ 'Createtime' => '添加时间',
+ 'Updatetime' => '更新时间',
+ 'Deletetime' => '删除时间',
+];
diff --git a/application/admin/lang/zh-cn/shopro/notification.php b/application/admin/lang/zh-cn/shopro/notification.php
new file mode 100644
index 000000000..3a69186d9
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/notification.php
@@ -0,0 +1,13 @@
+ '消息表',
+ 'Type' => '消息类型',
+ 'Notifiable_id' => '接收人',
+ 'Notifiable_type' => '接收人类型',
+ 'Data' => '数据',
+ 'Readtime' => '是否已读',
+ 'Createtime' => '创建时间',
+ 'Updatetime' => '更新时间',
+ 'Deletetime' => '删除时间'
+];
diff --git a/application/admin/lang/zh-cn/shopro/notification/config.php b/application/admin/lang/zh-cn/shopro/notification/config.php
new file mode 100644
index 000000000..3368d7730
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/notification/config.php
@@ -0,0 +1,12 @@
+ 'ID',
+ 'Platform' => '发送平台',
+ 'Name' => '消息名称',
+ 'Event' => '消息事件',
+ 'Content' => '消息内容',
+ 'Status' => '状态',
+ 'Status 0' => '关闭',
+ 'Status 1' => '启用'
+];
diff --git a/application/admin/lang/zh-cn/shopro/order/order.php b/application/admin/lang/zh-cn/shopro/order/order.php
new file mode 100644
index 000000000..824635a0a
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/order/order.php
@@ -0,0 +1,51 @@
+ '订单类型',
+ 'Type goods' => '商城订单',
+ 'Type score' => '积分订单',
+ 'Order_sn' => '订单号',
+ 'User_id' => '用户',
+ 'Goods_amount' => '商品总价',
+ 'Dispatch_amount' => '总运费',
+ 'Phone' => '联系电话',
+ 'Consignee' => '收货人',
+ 'Province_name' => '省',
+ 'City_name' => '市',
+ 'Area_name' => '区',
+ 'Address' => '详细地址',
+ 'Status' => '订单状态',
+ 'Status -2' => '交易关闭',
+ 'Status -1' => '已取消',
+ 'Status 0' => '未支付',
+ 'Status 1' => '已支付',
+ 'Status 2' => '已完成',
+ 'Memo' => '商户备注',
+ 'Remark' => '用户备注',
+ 'Total_amount' => '订单总金额',
+ 'Score_amount' => '积分总数',
+ 'Total_fee' => '支付金额',
+ 'Discount_fee' => '折扣总金额',
+ 'Coupon_fee' => '优惠券抵用金额',
+ 'Pay_fee' => '实际支付金额',
+ 'Score_fee' => '积分支付数',
+ 'Goods_original_amount' => '商品原价',
+ 'Coupons_id' => '优惠券 id',
+ 'Transaction_id' => '交易单号',
+ 'Payment_json' => '交易原始数据',
+ 'Pay_type' => '支付方式',
+ 'Pay_type wechat' => '微信支付',
+ 'Pay_type alipay' => '支付宝',
+ 'Pay_type wallet' => '钱包支付',
+ 'Pay_type score' => '积分支付',
+ 'Paytime' => '支付时间',
+ 'Ext' => '附加字段',
+ 'Platform' => '平台',
+ 'Platform h5' => 'H5',
+ 'Platform wxofficialaccount' => '公众号',
+ 'Platform wxminiprogram' => '小程序',
+ 'Platform app' => 'App',
+ 'Createtime' => '创建时间',
+ 'Updatetime' => '更新时间',
+ 'Deletetime' => '删除时间'
+];
diff --git a/application/admin/lang/zh-cn/shopro/order/order_item.php b/application/admin/lang/zh-cn/shopro/order/order_item.php
new file mode 100644
index 000000000..5ed6ae168
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/order/order_item.php
@@ -0,0 +1,45 @@
+ '用户',
+ 'Order_id' => '订单',
+ 'Goods_id' => '商品',
+ 'Goods_sku_price_id' => '规格 id',
+ 'Activity_id' => '活动 id',
+ 'Activity_type' => '活动类型',
+ 'Activity_type seckill' => '秒杀',
+ 'Activity_type groupon' => '拼团',
+ 'Item_goods_sku_price_id' => '活动规格|积分商城规格 id',
+ 'Goods_sku_text' => '规格名',
+ 'Goods_title' => '商品名称',
+ 'Goods_image' => '商品图片',
+ 'Goods_original_price' => '商品原价',
+ 'Discount_fee' => '优惠费用',
+ 'Goods_price' => '商品价格',
+ 'Goods_num' => '购买数量',
+ 'Dispatch_status' => '发货状态',
+ 'Dispatch_status 0' => '未发货',
+ 'Dispatch_status 1' => '已发货',
+ 'Dispatch_status 2' => '已收货',
+ 'Dispatch_fee' => '发货费用',
+ 'Dispatch_type' => '发货方式',
+ 'Dispatch_id' => '发货模板',
+ 'Aftersale_status' => '售后状态',
+ 'Aftersale_status 0' => '未申请',
+ 'Aftersale_status 1' => '申请售后',
+ 'Aftersale_status 2' => '售后完成',
+ 'Comment_status' => '评价状态',
+ 'Comment_status 0' => '未评价',
+ 'Comment_status 1' => '已评价',
+ 'Refund_status' => '退款状态',
+ 'Refund_status -1' => '拒绝退款',
+ 'Refund_status 0' => '无',
+ 'Refund_status 1' => '申请中',
+ 'Refund_status 2' => '同意退款',
+ 'Refund_status 3' => '退款完成',
+ 'Express_name' => '快递公司',
+ 'Express_no' => '快递单号',
+ 'Createtime' => '添加时间',
+ 'Updatetime' => '更新时间',
+ 'Deletetime' => '删除时间'
+];
diff --git a/application/admin/lang/zh-cn/shopro/order/refund_log.php b/application/admin/lang/zh-cn/shopro/order/refund_log.php
new file mode 100644
index 000000000..e9e821b92
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/order/refund_log.php
@@ -0,0 +1,20 @@
+ '商户订单号',
+ 'Refund_sn' => '退款单号',
+ 'Order_item_id' => '订单商品',
+ 'Pay_fee' => '支付金额',
+ 'Refund_fee' => '退款金额',
+ 'Pay_type' => '支付方式',
+ 'Pay_type wechat' => '微信支付',
+ 'Pay_type alipay' => '支付宝',
+ 'Pay_type wallet' => '钱包支付',
+ 'Pay_type score' => '积分支付',
+ 'Status' => '退款单状态',
+ 'Status -1' => '退款失败',
+ 'Status 0' => '退款中',
+ 'Status 1' => '退款完成',
+ 'Createtime' => '创建时间',
+ 'Updatetime' => '更新时间'
+];
diff --git a/application/admin/lang/zh-cn/shopro/richtext.php b/application/admin/lang/zh-cn/shopro/richtext.php
new file mode 100644
index 000000000..cd8630d32
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/richtext.php
@@ -0,0 +1,9 @@
+ '标题',
+ 'Content' => '内容',
+ 'Createtime' => '创建时间',
+ 'Updatetime' => '更新时间',
+ 'Deletetime' => '删除时间'
+];
diff --git a/application/admin/lang/zh-cn/shopro/user_fake.php b/application/admin/lang/zh-cn/shopro/user_fake.php
new file mode 100644
index 000000000..bc65cc668
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/user_fake.php
@@ -0,0 +1,6 @@
+ '昵称',
+ 'Avatar' => '头像'
+];
diff --git a/application/admin/lang/zh-cn/shopro/user_wallet_apply.php b/application/admin/lang/zh-cn/shopro/user_wallet_apply.php
new file mode 100644
index 000000000..2bfa90885
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/user_wallet_apply.php
@@ -0,0 +1,20 @@
+ '提现用户',
+ 'Money' => '提现金额',
+ 'Charge_money' => '手续费',
+ 'Service_fee' => '手续费率',
+ 'Get_type' => '收款类型:bank=银行卡',
+ 'Bank_id' => '银行卡',
+ 'Real_name' => '真实姓名',
+ 'Bank_info' => '打款信息',
+ 'Status' => '提现状态',
+ 'Status 0' => '申请中',
+ 'Status 1' => '已打款',
+ 'Status -1' => '已拒绝',
+ 'Status_msg' => '驳回理由',
+ 'Createtime' => '申请时间',
+ 'Updatetime' => '操作时间',
+ 'Deletetime' => '删除时间'
+];
diff --git a/application/admin/lang/zh-cn/shopro/wechat.php b/application/admin/lang/zh-cn/shopro/wechat.php
new file mode 100644
index 000000000..8e544ceb4
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/wechat.php
@@ -0,0 +1,10 @@
+ 'ID',
+ 'Type' => '配置类型',
+ 'Name' => '名称',
+ 'Content' => '内容',
+ 'Createtime' => '创建时间',
+ 'Updatetime' => '更新时间'
+];
diff --git a/application/admin/lang/zh-cn/shopro/wechat/fans.php b/application/admin/lang/zh-cn/shopro/wechat/fans.php
new file mode 100644
index 000000000..21dafc345
--- /dev/null
+++ b/application/admin/lang/zh-cn/shopro/wechat/fans.php
@@ -0,0 +1,14 @@
+ 'ID',
+ 'Name' => '粉丝名称',
+ 'Avatar' => '粉丝头像',
+ 'User_id' => '用户',
+ 'Subscribetime' => '关注时间',
+ 'Createtime' => '创建时间',
+ 'Updatetime' => '更新时间',
+ 'Is_subscribe' => '关注状态',
+ 'Is_subscribe 0' => '取消关注',
+ 'Is_subscribe 1' => '已关注'
+];
diff --git a/application/admin/model/faqueue/Log.php b/application/admin/model/faqueue/Log.php
new file mode 100644
index 000000000..cb554c2e4
--- /dev/null
+++ b/application/admin/model/faqueue/Log.php
@@ -0,0 +1,50 @@
+hasMany(\app\admin\model\shopro\Area::class, 'pid', 'id');
+ }
+
+
+
+
+}
diff --git a/application/admin/model/shopro/Category.php b/application/admin/model/shopro/Category.php
new file mode 100644
index 000000000..7ab2d3b14
--- /dev/null
+++ b/application/admin/model/shopro/Category.php
@@ -0,0 +1,94 @@
+save(['weigh' => $row['id']]);
+ });
+ }
+
+ public function setFlagAttr($value, $data)
+ {
+ return is_array($value) ? implode(',', $value) : $value;
+ }
+
+ /**
+ * 读取分类类型
+ * @return array
+ */
+ public static function getTypeList()
+ {
+ $typeList = [
+ 'shop' => __('shop'),
+ 'custom' => __('custom')
+ ];
+ return $typeList;
+ }
+
+ public function getTypeTextAttr($value, $data)
+ {
+ $value = $value ? $value : $data['type'];
+ $list = $this->getTypeList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+ public function getFlagList()
+ {
+ return ['hot' => __('Hot'), 'index' => __('Index'), 'recommend' => __('Recommend')];
+ }
+
+ public function getFlagTextAttr($value, $data)
+ {
+ $value = $value ? $value : $data['flag'];
+ $valueArr = explode(',', $value);
+ $list = $this->getFlagList();
+ return implode(',', array_intersect_key($list, array_flip($valueArr)));
+ }
+
+ public function getCategoryNameAttr($value, $data)
+ {
+ return $data['name'];
+ }
+
+ /**
+ * 读取分类列表
+ * @param string $type 指定类型
+ * @param string $status 指定状态
+ * @return array
+ */
+ public static function getCategoryArray($type = null, $status = null)
+ {
+ $list = collection(self::where(function ($query) use ($type, $status) {
+ if (!is_null($type)) {
+ $query->where('type', '=', $type);
+ }
+ if (!is_null($status)) {
+ $query->where('status', '=', $status);
+ }
+ })->order('weigh', 'desc')->select())->toArray();
+ return $list;
+ }
+}
diff --git a/application/admin/model/shopro/Config.php b/application/admin/model/shopro/Config.php
new file mode 100644
index 000000000..41688d516
--- /dev/null
+++ b/application/admin/model/shopro/Config.php
@@ -0,0 +1,183 @@
+ __('String'),
+ 'text' => __('Text'),
+ 'editor' => __('Editor'),
+ 'number' => __('Number'),
+ 'date' => __('Date'),
+ 'time' => __('Time'),
+ 'datetime' => __('Datetime'),
+ 'select' => __('Select'),
+ 'selects' => __('Selects'),
+ 'image' => __('Image'),
+ 'images' => __('Images'),
+ 'file' => __('File'),
+ 'files' => __('Files'),
+ 'switch' => __('Switch'),
+ 'checkbox' => __('Checkbox'),
+ 'radio' => __('Radio'),
+ 'array' => __('Array'),
+ 'custom' => __('Custom'),
+ ];
+ return $typeList;
+ }
+
+ public static function getRegexList()
+ {
+ $regexList = [
+ 'required' => '必选',
+ 'digits' => '数字',
+ 'letters' => '字母',
+ 'date' => '日期',
+ 'time' => '时间',
+ 'email' => '邮箱',
+ 'url' => '网址',
+ 'qq' => 'QQ号',
+ 'IDcard' => '身份证',
+ 'tel' => '座机电话',
+ 'mobile' => '手机号',
+ 'zipcode' => '邮编',
+ 'chinese' => '中文',
+ 'username' => '用户名',
+ 'password' => '密码'
+ ];
+ return $regexList;
+ }
+
+ public function getExtendAttr($value, $data)
+ {
+ $result = preg_replace_callback("/\{([a-zA-Z]+)\}/", function ($matches) use ($data) {
+ if (isset($data[$matches[1]])) {
+ return $data[$matches[1]];
+ }
+ }, $data['extend']);
+ return $result;
+ }
+
+ public static function load($name)
+ {
+ $value = self::where(['name' => $name])->value('value');
+ return json_decode($value, true);
+ }
+ /**
+ * 读取分类分组列表
+ * @return array
+ */
+ public static function getGroupList()
+ {
+ $group = self::group('group')->column('group');
+ $groupList = [];
+ foreach ($group as $v) {
+ $groupList[$v] = __($v);
+ }
+
+ return $groupList;
+ }
+
+ public static function getArrayData($data)
+ {
+ if (!isset($data['value'])) {
+ $result = [];
+ foreach ($data as $index => $datum) {
+ $result['field'][$index] = $datum['key'];
+ $result['value'][$index] = $datum['value'];
+ }
+ $data = $result;
+ }
+ $fieldarr = $valuearr = [];
+ $field = isset($data['field']) ? $data['field'] : (isset($data['key']) ? $data['key'] : []);
+ $value = isset($data['value']) ? $data['value'] : [];
+ foreach ($field as $m => $n) {
+ if ($n != '') {
+ $fieldarr[] = $field[$m];
+ $valuearr[] = $value[$m];
+ }
+ }
+ return $fieldarr ? array_combine($fieldarr, $valuearr) : [];
+ }
+
+ /**
+ * 将字符串解析成键值数组
+ * @param string $text
+ * @return array
+ */
+ public static function decode($text, $split = "\r\n")
+ {
+ $content = explode($split, $text);
+ $arr = [];
+ foreach ($content as $k => $v) {
+ if (stripos($v, "|") !== false) {
+ $item = explode('|', $v);
+ $arr[$item[0]] = $item[1];
+ }
+ }
+ return $arr;
+ }
+
+ /**
+ * 将键值数组转换为字符串
+ * @param array $array
+ * @return string
+ */
+ public static function encode($array, $split = "\r\n")
+ {
+ $content = '';
+ if ($array && is_array($array)) {
+ $arr = [];
+ foreach ($array as $k => $v) {
+ $arr[] = "{$k}|{$v}";
+ }
+ $content = implode($split, $arr);
+ }
+ return $content;
+ }
+
+ /**
+ * 本地上传配置信息
+ * @return array
+ */
+ public static function upload()
+ {
+ $uploadcfg = config('upload');
+
+ $upload = [
+ 'cdnurl' => $uploadcfg['cdnurl'],
+ 'uploadurl' => $uploadcfg['uploadurl'],
+ 'bucket' => 'local',
+ 'maxsize' => $uploadcfg['maxsize'],
+ 'mimetype' => $uploadcfg['mimetype'],
+ 'multipart' => [],
+ 'multiple' => $uploadcfg['multiple'],
+ ];
+ return $upload;
+ }
+
+}
diff --git a/application/admin/model/shopro/Coupons.php b/application/admin/model/shopro/Coupons.php
new file mode 100644
index 000000000..52539adf6
--- /dev/null
+++ b/application/admin/model/shopro/Coupons.php
@@ -0,0 +1,48 @@
+ __('Normal'), 'hidden' => __('Hidden')];
+ }
+
+ public function getPlatformList()
+ {
+ return ['H5' => __('Platform h5'), 'wxOfficialAccount' => __('Platform wxofficialaccount'), 'wxMiniProgram' => __('Platform wxminiprogram'), 'App' => __('Platform app')];
+ }
+
+
+ public function getStatusTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['status']) ? $data['status'] : '');
+ $list = $this->getStatusList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+ public function getImageAttr($value, $data)
+ {
+ if (!empty($value)) return cdnurl($value, true);
+ }
+
+ public function getPlatformTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['platform']) ? $data['platform'] : '');
+ $valueArr = explode(',', $value);
+ $list = $this->getPlatformList();
+ return implode(',', array_intersect_key($list, array_flip($valueArr)));
+ }
+
+ protected function setPlatformAttr($value)
+ {
+ return is_array($value) ? implode(',', $value) : $value;
+ }
+
+
+}
diff --git a/application/admin/model/shopro/DecorateContent.php b/application/admin/model/shopro/DecorateContent.php
new file mode 100644
index 000000000..4a2e5fde1
--- /dev/null
+++ b/application/admin/model/shopro/DecorateContent.php
@@ -0,0 +1,21 @@
+ __('Status 0'), '1' => __('Status 1')];
+ }
+
+
+ public function getStatusTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['status']) ? $data['status'] : '');
+ $list = $this->getStatusList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+
+ public function getTypeTextAttr($value, $data)
+ {
+ return isset(\addons\shopro\model\Feedback::$typeAll[$data['type']]) ? \addons\shopro\model\Feedback::$typeAll[$data['type']]['name'] : '';
+ }
+
+
+}
diff --git a/application/admin/model/shopro/Goods.php b/application/admin/model/shopro/Goods.php
new file mode 100644
index 000000000..9ccac4434
--- /dev/null
+++ b/application/admin/model/shopro/Goods.php
@@ -0,0 +1,134 @@
+getPk();
+ // $row->getQuery()->where($pk, $row[$pk])->update(['weigh' => $row[$pk]]);
+ // });
+ }
+
+
+ public function getTypeList()
+ {
+ return ['normal' => __('Type normal'), 'virtual' => __('Type virtual')];
+ }
+
+ public function getStatusList()
+ {
+ return ['up' => __('Status up'), 'hidden' => __('Status hidden'), 'down' => __('Status down')];
+ }
+
+ public function getDispatchTypeList()
+ {
+ return ['express' => __('Dispatch_type express'), 'selfetch' => __('Dispatch_type selfetch'), 'store' => __('Dispatch_type store'), 'autosend' => __('Dispatch_type autosend')];
+ }
+
+
+ public function getTypeTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['type']) ? $data['type'] : '');
+ $list = $this->getTypeList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+
+ public function getStatusTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['status']) ? $data['status'] : '');
+ $list = $this->getStatusList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+
+ public function getDispatchTypeArrAttr($value, $data)
+ {
+ $value = isset($data['dispatch_type']) ? $data['dispatch_type'] : '';
+ $valueArr = explode(',', $value);
+ return $valueArr;
+ }
+
+ public function getDispatchTypeTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['dispatch_type']) ? $data['dispatch_type'] : '');
+ $valueArr = explode(',', $value);
+ $list = $this->getDispatchTypeList();
+ return implode(',', array_intersect_key($list, array_flip($valueArr)));
+ }
+
+
+ public function getCategoryIdsArrAttr($value, $data)
+ {
+ $arr = $data['category_ids'] ? explode(',', $data['category_ids']) : [];
+
+ $category_ids_arr = [];
+ if ($arr) {
+ $tree = Tree::instance();
+ $tree->init(collection(Category::order('weigh desc,id desc')->select())->toArray(), 'pid');
+
+ foreach ($arr as $key => $id) {
+ $category_ids_arr[] = $tree->getParentsIds($id, true);
+ }
+ }
+
+ return $category_ids_arr;
+ }
+
+ public function getServiceIdsArrAttr($value, $data)
+ {
+ return (isset($data['service_ids']) && $data['service_ids']) ? explode(',', $data['service_ids']) : [];
+ }
+
+ public function getDispatchIdsArrAttr($value, $data)
+ {
+ return (isset($data['dispatch_ids']) && $data['dispatch_ids']) ? explode(',', $data['dispatch_ids']) : [];
+ }
+
+ public function getParamsArrAttr($value, $data)
+ {
+ return (isset($data['params']) && $data['params']) ? json_decode($data['params'], true) : [];
+ }
+
+ protected function setDispatchTypeAttr($value)
+ {
+ return is_array($value) ? implode(',', $value) : $value;
+ }
+
+
+
+}
diff --git a/application/admin/model/shopro/GoodsComment.php b/application/admin/model/shopro/GoodsComment.php
new file mode 100644
index 000000000..312d487c6
--- /dev/null
+++ b/application/admin/model/shopro/GoodsComment.php
@@ -0,0 +1,76 @@
+ __('Status show'), 'hidden' => __('Status hidden')];
+ }
+
+
+ public function getStatusTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['status']) ? $data['status'] : '');
+ $list = $this->getStatusList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+
+ public function getReplytimeTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['replytime']) ? $data['replytime'] : '');
+ return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
+ }
+
+ protected function setReplytimeAttr($value)
+ {
+ return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
+ }
+
+
+ public function shoprogoods()
+ {
+ return $this->belongsTo('app\admin\model\shopro\Goods', 'goods_id', 'id', [], 'LEFT')->setEagerlyType(0);
+ }
+
+
+ public function user()
+ {
+ return $this->belongsTo('app\admin\model\User', 'user_id', 'id', [], 'LEFT')->setEagerlyType(0);
+ }
+
+
+ public function admin()
+ {
+ return $this->belongsTo('app\admin\model\Admin', 'admin_id', 'id', [], 'LEFT')->setEagerlyType(0);
+ }
+}
diff --git a/application/admin/model/shopro/GoodsService.php b/application/admin/model/shopro/GoodsService.php
new file mode 100644
index 000000000..d737bca3e
--- /dev/null
+++ b/application/admin/model/shopro/GoodsService.php
@@ -0,0 +1,40 @@
+getPk();
+ $row->getQuery()->where($pk, $row[$pk])->update(['weigh' => $row[$pk]]);
+ });
+ }
+
+
+
+
+}
diff --git a/application/admin/model/shopro/GoodsSkuPrice.php b/application/admin/model/shopro/GoodsSkuPrice.php
new file mode 100644
index 000000000..5199ce153
--- /dev/null
+++ b/application/admin/model/shopro/GoodsSkuPrice.php
@@ -0,0 +1,57 @@
+getPk();
+ // $row->getQuery()->where($pk, $row[$pk])->update(['weigh' => $row[$pk]]);
+ // });
+ }
+
+ public function getImageAttr($value, $data)
+ {
+ if (!empty($value)) return cdnurl($value, true);
+ return $value;
+
+ }
+
+
+
+ public function getGoodsSkuTextAttr($value, $data)
+ {
+ return array_filter(explode(',', $value));
+ }
+
+
+
+
+}
diff --git a/application/admin/model/shopro/Link.php b/application/admin/model/shopro/Link.php
new file mode 100644
index 000000000..efd1716f7
--- /dev/null
+++ b/application/admin/model/shopro/Link.php
@@ -0,0 +1,54 @@
+column('group');
+ $groupList = [];
+ foreach ($group as $v) {
+ $groupList[$v] = $v;
+ }
+ return $groupList;
+ }
+
+
+
+
+
+
+
+
+
+
+}
diff --git a/application/admin/model/shopro/Notification.php b/application/admin/model/shopro/Notification.php
new file mode 100644
index 000000000..94ae5f203
--- /dev/null
+++ b/application/admin/model/shopro/Notification.php
@@ -0,0 +1,48 @@
+ __('Bank')];
+ }
+
+ public function getStatusList()
+ {
+ return ['0' => __('Status 0'), '1' => __('Status 1'), '-1' => __('Status -1')];
+ }
+
+
+ public function getGetTypeTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['get_type']) ? $data['get_type'] : '');
+ $list = $this->getGetTypeList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+
+ public function getStatusTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['status']) ? $data['status'] : '');
+ $list = $this->getStatusList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+
+
+
+}
diff --git a/application/admin/model/shopro/Wechat.php b/application/admin/model/shopro/Wechat.php
new file mode 100644
index 000000000..60c3aed38
--- /dev/null
+++ b/application/admin/model/shopro/Wechat.php
@@ -0,0 +1,40 @@
+ __('Is_subscribe 0'), '1' => __('Is_subscribe 1')];
+ }
+
+
+ public function getSubscribetimeTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['subscribetime']) ? $data['subscribetime'] : '');
+ return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
+ }
+
+
+ public function getIsSubscribeTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['is_subscribe']) ? $data['is_subscribe'] : '');
+ $list = $this->getIsSubscribeList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+ protected function setSubscribetimeAttr($value)
+ {
+ return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
+ }
+
+
+}
diff --git a/application/admin/model/shopro/activity/Activity.php b/application/admin/model/shopro/activity/Activity.php
new file mode 100644
index 000000000..b9ee4cc77
--- /dev/null
+++ b/application/admin/model/shopro/activity/Activity.php
@@ -0,0 +1,115 @@
+ '秒杀', 'groupon' => '拼团'];
+ }
+
+ public function getTypeTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['type']) ? $data['type'] : '');
+ $list = $this->getTypeList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+
+ public function getStarttimeTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['starttime']) ? $data['starttime'] : '');
+ return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
+ }
+
+
+ public function getEndtimeTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['endtime']) ? $data['endtime'] : '');
+ return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
+ }
+
+ protected function setStarttimeAttr($value)
+ {
+ return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
+ }
+
+ protected function setEndtimeAttr($value)
+ {
+ return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
+ }
+
+ protected function getRuleArrAttr($value, $data)
+ {
+ $value = json_decode($data['rules'], true);
+ return $value;
+ }
+
+
+ protected function getStatusAttr($value, $data)
+ {
+ return $this->getStatus($value, $data, 'status');
+ }
+
+
+ protected function getStatusTextAttr($value, $data)
+ {
+ return $this->getStatus($value, $data, 'text');
+ }
+
+ private function getStatus($value, $data, $type = 'status') {
+ $status_text = '';
+ $status = '';
+ $time = time();
+
+ if ($data['starttime'] < $time && $data['endtime'] > $time) {
+ $status_text = '进行中';
+ $status = 'ing';
+ } else if ($data['starttime'] > $time) {
+ $status_text = '未开始';
+ $status = 'nostart';
+ } else if ($data['endtime'] < $time) {
+ $status_text = '已结束';
+ $status = 'ended';
+ }
+
+ return $type == 'status' ? $status : $status_text;
+ }
+
+
+ public function activityGoodsSkuPrice()
+ {
+ return $this->hasMany(\addons\shopro\model\ActivityGoodsSkuPrice::class, 'activity_id', 'id');
+ }
+}
diff --git a/application/admin/model/shopro/activity/ActivitySkuPrice.php b/application/admin/model/shopro/activity/ActivitySkuPrice.php
new file mode 100644
index 000000000..ea302ccd9
--- /dev/null
+++ b/application/admin/model/shopro/activity/ActivitySkuPrice.php
@@ -0,0 +1,40 @@
+ __('Status invalid'), 'ing' => __('Status ing'), 'finish' => __('Status finish'), 'finish-fictitious' => __('Status finish-fictitious')];
+ }
+
+
+ public function getStatusTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['status']) ? $data['status'] : '');
+ $list = $this->getStatusList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+
+ public function grouponLog()
+ {
+ return $this->hasMany(\app\admin\model\shopro\activity\GrouponLog::class, 'groupon_id', 'id');
+ }
+
+
+ public function user()
+ {
+ return $this->belongsTo(\app\admin\model\User::class, 'user_id', 'id');
+ }
+
+ public function goods()
+ {
+ return $this->belongsTo(\app\admin\model\shopro\Goods::class, 'goods_id', 'id');
+ }
+
+}
diff --git a/application/admin/model/shopro/activity/GrouponLog.php b/application/admin/model/shopro/activity/GrouponLog.php
new file mode 100644
index 000000000..98512453d
--- /dev/null
+++ b/application/admin/model/shopro/activity/GrouponLog.php
@@ -0,0 +1,59 @@
+ __('Status invalid'), 'ing' => __('Status ing'), 'finish' => __('Status finish'), 'finish-fictitious' => __('Status finish-fictitious')];
+ }
+
+
+ public function getStatusTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['status']) ? $data['status'] : '');
+ $list = $this->getStatusList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+
+ public function grouponLog()
+ {
+ return $this->hasMany(\addons\shopro\model\ActivityGroupon::class, 'groupon_id', 'id');
+ }
+
+
+ public function user()
+ {
+ return $this->belongsTo(\app\admin\model\User::class, 'user_id', 'id');
+ }
+
+ public function goods()
+ {
+ return $this->belongsTo(\app\admin\model\shopro\Goods::class, 'goods_id', 'id');
+ }
+
+}
diff --git a/application/admin/model/shopro/app/Live.php b/application/admin/model/shopro/app/Live.php
new file mode 100644
index 000000000..b8cec220b
--- /dev/null
+++ b/application/admin/model/shopro/app/Live.php
@@ -0,0 +1,92 @@
+ __('Live_status 101'), '102' => __('Live_status 102'), '103' => __('Live_status 103'), '104' => __('Live_status 104'), '105' => __('Live_status 105'), '106' => __('Live_status 106'), '107' => __('Live_status 107')];
+ }
+
+
+ public function getLiveStatusTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['live_status']) ? $data['live_status'] : '');
+ $list = $this->getLiveStatusList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+
+ public function getStarttimeTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['starttime']) ? $data['starttime'] : '');
+ return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
+ }
+
+
+ public function getEndtimeTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['endtime']) ? $data['endtime'] : '');
+ return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
+ }
+
+ protected function setStarttimeAttr($value)
+ {
+ return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
+ }
+
+ protected function setEndtimeAttr($value)
+ {
+ return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
+ }
+
+
+ public function goods()
+ {
+ return $this->hasMany(\addons\shopro\model\LiveGoods::class, 'live_id', 'id');
+ }
+
+ public function links()
+ {
+ return $this->hasMany(\addons\shopro\model\LiveLink::class, 'live_id', 'id');
+ }
+
+}
diff --git a/application/admin/model/shopro/app/ScoreSkuPrice.php b/application/admin/model/shopro/app/ScoreSkuPrice.php
new file mode 100644
index 000000000..706544c11
--- /dev/null
+++ b/application/admin/model/shopro/app/ScoreSkuPrice.php
@@ -0,0 +1,40 @@
+ __('Type express'), 'selfetch' => __('Type selfetch'), 'store' => __('Type store'), 'autosend' => __('Type autosend')];
+ }
+
+
+ public function getTypeTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['type']) ? $data['type'] : '');
+ $list = $this->getTypeList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+
+
+
+}
diff --git a/application/admin/model/shopro/dispatch/Express.php b/application/admin/model/shopro/dispatch/Express.php
new file mode 100644
index 000000000..8f93c9475
--- /dev/null
+++ b/application/admin/model/shopro/dispatch/Express.php
@@ -0,0 +1,57 @@
+getPk();
+ $row->getQuery()->where($pk, $row[$pk])->update(['weigh' => $row[$pk]]);
+ });
+ }
+
+
+ public function getTypeList()
+ {
+ return ['number' => __('Type number'), 'weight' => __('Type weight')];
+ }
+
+
+ public function getTypeTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['type']) ? $data['type'] : '');
+ $list = $this->getTypeList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+
+
+
+}
diff --git a/application/admin/model/shopro/notification/Config.php b/application/admin/model/shopro/notification/Config.php
new file mode 100644
index 000000000..c21c0d1eb
--- /dev/null
+++ b/application/admin/model/shopro/notification/Config.php
@@ -0,0 +1,53 @@
+ __('Status 0'), '1' => __('Status 1')];
+ }
+
+
+ public function getStatusTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['status']) ? $data['status'] : '');
+ $list = $this->getStatusList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+
+ public function getContentArrAttr($value, $data)
+ {
+ return (isset($data['content']) && $data['content']) ? json_decode($data['content'], true) : [];
+ }
+
+}
diff --git a/application/admin/model/shopro/order/Order.php b/application/admin/model/shopro/order/Order.php
new file mode 100644
index 000000000..ddd162551
--- /dev/null
+++ b/application/admin/model/shopro/order/Order.php
@@ -0,0 +1,124 @@
+ __('Type goods'), 'score' => __('Type score')];
+ }
+
+ public function getStatusList()
+ {
+ return ['-2' => __('Status -2'), '-1' => __('Status -1'), '0' => __('Status 0'), '1' => __('Status 1'), '2' => __('Status 2')];
+ }
+
+ public function getPayTypeList()
+ {
+ return ['wechat' => __('Pay_type wechat'), 'alipay' => __('Pay_type alipay'), 'wallet' => __('Pay_type wallet'), 'score' => __('Pay_type score')];
+ }
+
+ public function getPlatformList()
+ {
+ return ['H5' => __('Platform h5'), 'wxOfficialAccount' => __('Platform wxofficialaccount'), 'wxMiniProgram' => __('Platform wxminiprogram'), 'App' => __('Platform app')];
+ }
+
+
+ public function getTypeTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['type']) ? $data['type'] : '');
+ $list = $this->getTypeList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+
+ public function getStatusTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['status']) ? $data['status'] : '');
+ $list = $this->getStatusList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+
+ public function getPayTypeTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['pay_type']) ? $data['pay_type'] : '');
+ $list = $this->getPayTypeList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+
+ public function getPaytimeTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['paytime']) ? $data['paytime'] : '');
+ return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
+ }
+
+
+ public function getPlatformTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['platform']) ? $data['platform'] : '');
+ $list = $this->getPlatformList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+ protected function setPaytimeAttr($value)
+ {
+ return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
+ }
+
+ public function getExtArrAttr($value, $data)
+ {
+ return (isset($data['ext']) && $data['ext']) ? json_decode($data['ext'], true) : [];
+ }
+
+ public function user ()
+ {
+ return $this->belongsTo(\app\admin\model\User::class, 'user_id');
+ }
+
+ public function item()
+ {
+ return $this->hasMany(\app\admin\model\shopro\order\OrderItem::class, 'order_id');
+ }
+}
diff --git a/application/admin/model/shopro/order/OrderAction.php b/application/admin/model/shopro/order/OrderAction.php
new file mode 100644
index 000000000..feb3c8644
--- /dev/null
+++ b/application/admin/model/shopro/order/OrderAction.php
@@ -0,0 +1,30 @@
+belongsTo(\app\admin\model\Admin::class, 'oper_id', 'id');
+ }
+
+
+}
diff --git a/application/admin/model/shopro/order/OrderItem.php b/application/admin/model/shopro/order/OrderItem.php
new file mode 100644
index 000000000..7c4b85cfa
--- /dev/null
+++ b/application/admin/model/shopro/order/OrderItem.php
@@ -0,0 +1,134 @@
+ __('Dispatch_status 0'), '1' => __('Dispatch_status 1'), '2' => __('Dispatch_status 2')];
+ }
+
+ public function getAftersaleStatusList()
+ {
+ return ['0' => __('Aftersale_status 0'), '1' => __('Aftersale_status 1'), '2' => __('Aftersale_status 2')];
+ }
+
+ public function getCommentStatusList()
+ {
+ return ['0' => __('Comment_status 0'), '1' => __('Comment_status 1')];
+ }
+
+ public function getRefundStatusList()
+ {
+ return ['-1' => __('Refund_status -1'), '0' => __('Refund_status 0'), '1' => __('Refund_status 1'), '2' => __('Refund_status 2'), '3' => __('Refund_status 3')];
+ }
+
+
+ public function getDispatchTypeTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['dispatch_type']) ? $data['dispatch_type'] : '');
+ $list = (new \app\admin\model\shopro\dispatch\Dispatch)->getTypeList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+
+ public function getDispatchStatusTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['dispatch_status']) ? $data['dispatch_status'] : '');
+ $list = $this->getDispatchStatusList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+
+ public function getAftersaleStatusTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['aftersale_status']) ? $data['aftersale_status'] : '');
+ $list = $this->getAftersaleStatusList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+ public function getActivityTypeList()
+ {
+ return ['seckill' => __('Activity_type seckill'), 'groupon' => __('Activity_type groupon')];
+ }
+
+ public function getActivityTypeTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['activity_type']) ? $data['activity_type'] : '');
+ $list = $this->getActivityTypeList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+ public function getCommentStatusTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['comment_status']) ? $data['comment_status'] : '');
+ $list = $this->getCommentStatusList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+
+ public function getRefundStatusTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['refund_status']) ? $data['refund_status'] : '');
+ $list = $this->getRefundStatusList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+
+
+
+}
diff --git a/application/admin/model/shopro/order/RefundLog.php b/application/admin/model/shopro/order/RefundLog.php
new file mode 100644
index 000000000..155e89e06
--- /dev/null
+++ b/application/admin/model/shopro/order/RefundLog.php
@@ -0,0 +1,58 @@
+ __('Status -1'), '0' => __('Status 0'), '1' => __('Status 1')];
+ }
+
+
+ public function getStatusTextAttr($value, $data)
+ {
+ $value = $value ? $value : (isset($data['status']) ? $data['status'] : '');
+ $list = $this->getStatusList();
+ return isset($list[$value]) ? $list[$value] : '';
+ }
+
+
+ // 获取退款单号
+ public static function getSn($user_id)
+ {
+ $rand = $user_id < 9999 ? mt_rand(100000, 99999999) : mt_rand(100, 99999);
+ $order_sn = date('Yhis') . $rand;
+
+ $id = str_pad($user_id, (24 - strlen($order_sn)), '0', STR_PAD_BOTH);
+
+ return 'R' . $order_sn . $id;
+ }
+
+}
diff --git a/application/admin/validate/shopro/Area.php b/application/admin/validate/shopro/Area.php
new file mode 100644
index 000000000..9dece1e32
--- /dev/null
+++ b/application/admin/validate/shopro/Area.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/shopro/Category.php b/application/admin/validate/shopro/Category.php
new file mode 100644
index 000000000..248b01478
--- /dev/null
+++ b/application/admin/validate/shopro/Category.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/shopro/Config.php b/application/admin/validate/shopro/Config.php
new file mode 100644
index 000000000..b7579a63c
--- /dev/null
+++ b/application/admin/validate/shopro/Config.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/shopro/Coupons.php b/application/admin/validate/shopro/Coupons.php
new file mode 100644
index 000000000..9e51d96dc
--- /dev/null
+++ b/application/admin/validate/shopro/Coupons.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/shopro/Decorate.php b/application/admin/validate/shopro/Decorate.php
new file mode 100644
index 000000000..53c394708
--- /dev/null
+++ b/application/admin/validate/shopro/Decorate.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/shopro/Faq.php b/application/admin/validate/shopro/Faq.php
new file mode 100644
index 000000000..679a65e54
--- /dev/null
+++ b/application/admin/validate/shopro/Faq.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/shopro/Feedback.php b/application/admin/validate/shopro/Feedback.php
new file mode 100644
index 000000000..971d6f266
--- /dev/null
+++ b/application/admin/validate/shopro/Feedback.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/shopro/Goods.php b/application/admin/validate/shopro/Goods.php
new file mode 100644
index 000000000..cc07c16e8
--- /dev/null
+++ b/application/admin/validate/shopro/Goods.php
@@ -0,0 +1,57 @@
+ 'require', // 商品标题:必填
+ 'category_ids' => 'require',
+ 'image' => 'require',
+ 'images' => 'require',
+ 'price' => 'require',
+ 'original_price' => 'require',
+ // 'dispatch_type' => 'checkDispatchType', // 发货方式:必填
+ 'dispatch_type' => 'require', // 发货方式:必填
+ 'dispatch_ids' => 'require', // 发货模板:必填
+ 'service_ids' => 'require', // 商品服务
+ ];
+ /**
+ * 提示消息
+ */
+ protected $message = [
+ 'title.require' => '商品名称必须填写',
+ 'category_ids.require' => '所属分类必须选择',
+ 'image.require' => '商品主图必须上传',
+ 'images.require' => '至少上传一张轮播图',
+ 'price.require' => '价格必须填写',
+ 'original_price.require' => '原价必须填写',
+ 'dispatch_type.require' => '发货方式必须选择',
+ 'dispatch_ids.require' => '发货模板必须选择',
+ 'service_ids.require' => '服务标签必须选择',
+ ];
+ /**
+ * 验证场景
+ */
+ protected $scene = [
+ 'add' => ['title', 'dispatch_type', 'dispatch_ids', 'image', 'images', 'category_ids','price', 'original_price', 'service_ids'],
+ 'edit' => ['title', 'dispatch_type', 'dispatch_ids', 'image', 'images', 'category_ids','price', 'original_price', 'service_ids'],
+ ];
+
+
+ // 自定义规则
+ protected function checkDispatchType($value, $rule, $data)
+ {
+ if ($value && count($value) && !empty($value[0])) {
+ return true;
+ }
+
+ return '发货方式必须选择';
+ }
+
+}
diff --git a/application/admin/validate/shopro/GoodsComment.php b/application/admin/validate/shopro/GoodsComment.php
new file mode 100644
index 000000000..ef415c2f5
--- /dev/null
+++ b/application/admin/validate/shopro/GoodsComment.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/shopro/GoodsService.php b/application/admin/validate/shopro/GoodsService.php
new file mode 100644
index 000000000..71f7e2c9d
--- /dev/null
+++ b/application/admin/validate/shopro/GoodsService.php
@@ -0,0 +1,24 @@
+ [],
+ 'edit' => [],
+ ];
+}
diff --git a/application/admin/validate/shopro/GoodsSku.php b/application/admin/validate/shopro/GoodsSku.php
new file mode 100644
index 000000000..17100b4de
--- /dev/null
+++ b/application/admin/validate/shopro/GoodsSku.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/shopro/GoodsSkuPrice.php b/application/admin/validate/shopro/GoodsSkuPrice.php
new file mode 100644
index 000000000..8a3710688
--- /dev/null
+++ b/application/admin/validate/shopro/GoodsSkuPrice.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/shopro/Link.php b/application/admin/validate/shopro/Link.php
new file mode 100644
index 000000000..e9d9d4196
--- /dev/null
+++ b/application/admin/validate/shopro/Link.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/shopro/Notification.php b/application/admin/validate/shopro/Notification.php
new file mode 100644
index 000000000..943dd9ef3
--- /dev/null
+++ b/application/admin/validate/shopro/Notification.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/shopro/Notification_config.php b/application/admin/validate/shopro/Notification_config.php
new file mode 100644
index 000000000..0b610d81c
--- /dev/null
+++ b/application/admin/validate/shopro/Notification_config.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/shopro/Richtext.php b/application/admin/validate/shopro/Richtext.php
new file mode 100644
index 000000000..9c5f8b10d
--- /dev/null
+++ b/application/admin/validate/shopro/Richtext.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/shopro/UserFake.php b/application/admin/validate/shopro/UserFake.php
new file mode 100644
index 000000000..c57b6efb4
--- /dev/null
+++ b/application/admin/validate/shopro/UserFake.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/shopro/UserWalletApply.php b/application/admin/validate/shopro/UserWalletApply.php
new file mode 100644
index 000000000..57aa73c95
--- /dev/null
+++ b/application/admin/validate/shopro/UserWalletApply.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/shopro/Wechat.php b/application/admin/validate/shopro/Wechat.php
new file mode 100644
index 000000000..ca2b48363
--- /dev/null
+++ b/application/admin/validate/shopro/Wechat.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/shopro/activity/Activity.php b/application/admin/validate/shopro/activity/Activity.php
new file mode 100644
index 000000000..28374af6c
--- /dev/null
+++ b/application/admin/validate/shopro/activity/Activity.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/shopro/activity/ActivitySkuPrice.php b/application/admin/validate/shopro/activity/ActivitySkuPrice.php
new file mode 100644
index 000000000..50a0dd2c4
--- /dev/null
+++ b/application/admin/validate/shopro/activity/ActivitySkuPrice.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/shopro/activity/Groupon.php b/application/admin/validate/shopro/activity/Groupon.php
new file mode 100644
index 000000000..5d6b2a0c1
--- /dev/null
+++ b/application/admin/validate/shopro/activity/Groupon.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/shopro/app/Live.php b/application/admin/validate/shopro/app/Live.php
new file mode 100644
index 000000000..873a79c7a
--- /dev/null
+++ b/application/admin/validate/shopro/app/Live.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/shopro/dispatch/Dispatch.php b/application/admin/validate/shopro/dispatch/Dispatch.php
new file mode 100644
index 000000000..e9b210ba3
--- /dev/null
+++ b/application/admin/validate/shopro/dispatch/Dispatch.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/shopro/dispatch/Express.php b/application/admin/validate/shopro/dispatch/Express.php
new file mode 100644
index 000000000..06060a243
--- /dev/null
+++ b/application/admin/validate/shopro/dispatch/Express.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/shopro/notification/Config.php b/application/admin/validate/shopro/notification/Config.php
new file mode 100644
index 000000000..22ea53a9b
--- /dev/null
+++ b/application/admin/validate/shopro/notification/Config.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/shopro/order/Order.php b/application/admin/validate/shopro/order/Order.php
new file mode 100644
index 000000000..c573045cf
--- /dev/null
+++ b/application/admin/validate/shopro/order/Order.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/shopro/order/OrderItem.php b/application/admin/validate/shopro/order/OrderItem.php
new file mode 100644
index 000000000..a327161af
--- /dev/null
+++ b/application/admin/validate/shopro/order/OrderItem.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/shopro/wechat/Fans.php b/application/admin/validate/shopro/wechat/Fans.php
new file mode 100644
index 000000000..e506cb851
--- /dev/null
+++ b/application/admin/validate/shopro/wechat/Fans.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/view/faqueue/log/index.html b/application/admin/view/faqueue/log/index.html
new file mode 100644
index 000000000..278a68e2a
--- /dev/null
+++ b/application/admin/view/faqueue/log/index.html
@@ -0,0 +1,22 @@
+
+
+
+
订单号:{{orderDetail.order_sn}}
+
下单时间:{{moment(orderDetail.createtime*1000).format("YYYY-MM-DD HH:mm:ss")}}
+
订单来源:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
买家已下单,等待付款
+
买家未在规定时间内付款,订单将按照预定时间逾期自动关闭
+
+
+
+
+
买家已付款
+ -有退款 -有售后
+
+
买家已付款,请尽快发货
+
+
+
+
+
商家已发货
+ -有退款 -有售后
+
+
买家若在7天内未确认收货,系统将自动确认收货完成订单。
+
+
+
+
+
交易完成
+
+
订单金额已到店铺余额,请注意查收
+
+
+
+
+
+
+
+
+
交易关闭
+
买家未在规定时间内付款,已自动关闭
+
+
+
+ {{(orderDetail.memo!=null && orderDetail.memo.length>42)?orderDetail.memo.substr(0,42)+'...':orderDetail.memo}}
+ 修改备注
+ 添加备注
+
+
+
+ 确定
+ 取消
+
+
+
+
+
+
+
商品总价: ¥{{orderDetail.goods_amount}}
+
+
运费: ¥{{orderDetail.dispatch_amount}}
+
+
+ 优惠: -¥{{orderDetail.discount_fee}}
+
+
+ 积分: +{{orderDetail.score_amount}}
+
+
订单金额: ¥{{orderDetail.pay_fee}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
商品总价: ¥{{orderDetail.goods_amount}}
+
+
运费: ¥{{orderDetail.dispatch_amount}}
+
+
+ 优惠: -¥{{orderDetail.discount_fee}}
+
+
+ 积分: +{{orderDetail.score_amount}}
+
+
订单金额: ¥{{orderDetail.pay_fee}}
+
+
+
+
+
+ 温馨提示:
+ 请务必等待订单状态变更为“买家已付款,等待卖家发货”后再进行发货
+ 1、如果无法发货,请及时与买家联系并说明情况后进退款;
+ 2、买家申请退款后,须征得买家同意后发货,否则买家有权拒收货物; 3、买家付款后超过7天仍未发货,将自动退款
+ 交易完成,若买家提出售后要求,请积极与买家协商。
+ 买家已取消
+ 买家未在规定时间内付款,已自动关闭
+
+
+
+
+
+
+
+
+
收货信息
+
修改
+
+ 确定
+
复制
+
+
+
收货人:
+
{{orderDetail.consignee}}
+
+
+
+
+
+
+
联系电话:
+
{{orderDetail.phone}}
+
+
+
+
+
+
+
收货地址:
+
+ {{orderDetail.province_name}}{{orderDetail.city_name}}{{orderDetail.area_name}}{{orderDetail.address}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
配送方式:
+
{{orderGoodsList[0].dispatch_type_text}}
+
+
+
买家留言:
+
{{orderDetail.remark}}
+
+
+
+
+
+
+
+
+
+
实付金额:
+
{{orderDetail.pay_fee}}
+
+
+
付款方式:
+
{{orderDetail.pay_type_text}}
+
+
+
付款时间:
+
{{orderDetail.paytime_text}}
+
+
+
+
付款状态:
+
{{orderDetail.status_text}}
+
+
+
+
+
+
+
+
+
+
+
ID :
+
{{orderDetail.user.id}}
+
+
+
昵称:
+
{{orderDetail.user.nickname}}
+
+
+
联系方式:
+
{{orderDetail.user.mobile}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{scope.row.goods_title}}
+
规格:{{scope.row.goods_sku_text}}
+
+
+
+
+
+
+
+ ¥{{scope.row.goods_price}}
+
+
+
+
+
+ {{scope.row.goods_num}}
+
+
+
+
+ ¥{{scope.row.discount_fee}}
+
+
+
+
+
+
¥{{(scope.row.goods_price*scope.row.goods_num).toFixed(2)}}
+
+ +{{orderDetail.score_amount}}积分
+
+
+
+
+ ¥{{(scope.row.goods_price*scope.row.goods_num-scope.row.discount_fee).toFixed(2)}}
+
+ ¥{{(scope.row.goods_price*scope.row.goods_num).toFixed(2)}}
+
+
+
+
+
+
+ {{orderDetail.type_text}}
+
+
+
+
+ {{scope.row.dispatch_status_text}}
+ -
+
+
+
+
+
+
{{scope.row.refund_status_text}}
+
(-{{scope.row.refund_fee}}元)
+
退款
+
拒绝
+
+ -
+
+
+
+
+
+
{{scope.row.aftersale_status_text}}
+
售后中
+
+
+
+
+
+
+ -
+
+
+
+
+
+
{{scope.row.comment_status_text}}
+
查看评价
+
+ -
+
+
+
+
+
+
+
+ 选择商品
+
+
+
+
+
+
+
+
+
+
+ {{scope.row.goods_title}}
+
+
+ 规格: {{scope.row.goods_sku_text}}
+
+
+
+
+
+
+
+
+
+
+
+ {{scope.row.express_no}}
+ -
+
+
+
+
+
+
+
+ 配送方式:{{orderDetail.dispatch_type_text}}
+ {{orderGoodsList[0].dispatch_type_text?orderGoodsList[0].dispatch_type_text:''}}
+
+
+ 收货人:
+ {{orderDetail.consignee}}
+ {{orderDetail.phone}}
+
+
+ 收货地址:
+ {{orderDetail.city_name}}{{orderDetail.area_name}}{{orderDetail.address}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/application/admin/view/shopro/order/order/edit.html b/application/admin/view/shopro/order/order/edit.html
new file mode 100644
index 000000000..461df5290
--- /dev/null
+++ b/application/admin/view/shopro/order/order/edit.html
@@ -0,0 +1,218 @@
+
diff --git a/application/admin/view/shopro/order/order/index.html b/application/admin/view/shopro/order/order/index.html
new file mode 100644
index 000000000..1b416865e
--- /dev/null
+++ b/application/admin/view/shopro/order/order/index.html
@@ -0,0 +1,934 @@
+
+
+
+
+
+
+
+
+
+
+
订单来源
+
+
+ {{item.name}}
+
+
+
配送方式
+
+ {{item.name}}
+
+
+
订单类型
+
+ {{item.name}}
+
+
+
支付方式
+
+ {{item.name}}
+
+
+
营销类型
+
+ {{item.name}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
规格:{{item.goods_sku_text}}
+
单价:{{item.goods_price}}元
+
数量:{{item.goods_num}}
+
+
+
{{item.activity_type_text}}
+
+
拼团-单独购买
+
+
{{item.activity_type_text}}
+
+
+
+
+
+
+ {{props.row.status_text}}
+
+
+
+
+
去发货
+
去发货
+
+ {{item.dispatch_status_text?item.dispatch_status_text:'-'}}
+
+
-
+
+
+
+
+
+ {{item.aftersale_status_text}}
+ -{{item.refund_status_text}}
+
+
-
+
+
+
+
+
+
+
头像 :
+
+
+
+ ID : {{props.row.user?props.row.user.id:''}}
+
+ 手机号 :
+ {{props.row.user?props.row.user.mobile:''}}
+
+
+
+ {{props.row.user.nickname.length>4?props.row.user.nickname.substr(0,4)+'...':props.row.user.nickname}}
+
+
+
+
+
-
+
+
+
+
+ 收货信息:
+
+
+ {{props.row.city_name}}{{props.row.area_name}}{{props.row.address}}
+
+
+
+
+ {{props.row.consignee.length>4?props.row.consignee.substr(0,4)+'...':props.row.consignee}}
+
+ {{props.row.phone}}
+
+
+
+
+ {{props.row.remark.length>4?props.row.remark.substr(0,4)+'...':props.row.remark}}
+ -
+
+
+
+ {{props.row.item[0].dispatch_type_text?props.row.item[0].dispatch_type_text:props.row.item[0].dispatch_type}}
+
+
+
{{props.row.total_amount}}元
+
+ +{{props.row.score_amount}}积分
+
+ (含运费:{{props.row.item[0].dispatch_fee}}元)
+
+
+
+
+
+
+
+
+
+ ID:{{scope.row.id}}
+ 订单号:{{scope.row.order_sn}}下单时间:{{scope.row.paytime_text}}
+ {{scope.row.platform_text}}-{{scope.row.type_text}}
+
+
+
+
+
+ {{scope.row.pay_type_text}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 操作日志
+
+
+
+
+
+
+
+
+
+
+ 选择商品
+
+
+
+
+
+
+
+
+
+
+ {{scope.row.goods_title}}
+
+
+ 规格: {{scope.row.goods_sku_text}}
+
+
+
+
+
+
+
+
+
+
+
+ {{scope.row.express_no}}
+ -
+
+
+
+
+
+
+
+ 配送方式:
+ {{dispatchList.item?dispatchList.item[0].dispatch_type_text:''}}
+
+
+ 收货人:
+ {{dispatchList.consignee}}
+ {{dispatchList.phone}}
+
+
+ 收货地址:
+ {{dispatchList.city_name}}{{dispatchList.area_name}}{{dispatchList.address}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{moment(scope.row.createtime*1000).format("YYYY-MM-DD HH:mm:ss")}}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/application/admin/view/shopro/order/order/recyclebin.html b/application/admin/view/shopro/order/order/recyclebin.html
new file mode 100644
index 000000000..fc50d0851
--- /dev/null
+++ b/application/admin/view/shopro/order/order/recyclebin.html
@@ -0,0 +1,25 @@
+
+ {:build_heading()}
+
+
+
diff --git a/application/admin/view/shopro/order/order_item/add.html b/application/admin/view/shopro/order/order_item/add.html
new file mode 100644
index 000000000..203fe3d91
--- /dev/null
+++ b/application/admin/view/shopro/order/order_item/add.html
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/application/admin/view/shopro/order/order_item/edit.html b/application/admin/view/shopro/order/order_item/edit.html
new file mode 100644
index 000000000..dd66dd952
--- /dev/null
+++ b/application/admin/view/shopro/order/order_item/edit.html
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/application/admin/view/shopro/order/order_item/index.html b/application/admin/view/shopro/order/order_item/index.html
new file mode 100644
index 000000000..a7929ff2e
--- /dev/null
+++ b/application/admin/view/shopro/order/order_item/index.html
@@ -0,0 +1,46 @@
+
+
+ {:build_heading()}
+
+
+
diff --git a/application/admin/view/shopro/order/order_item/recyclebin.html b/application/admin/view/shopro/order/order_item/recyclebin.html
new file mode 100644
index 000000000..3f0be70a1
--- /dev/null
+++ b/application/admin/view/shopro/order/order_item/recyclebin.html
@@ -0,0 +1,25 @@
+
+ {:build_heading()}
+
+
+
diff --git a/application/admin/view/shopro/richtext/add.html b/application/admin/view/shopro/richtext/add.html
new file mode 100644
index 000000000..1e7409922
--- /dev/null
+++ b/application/admin/view/shopro/richtext/add.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+
diff --git a/application/admin/view/shopro/richtext/edit.html b/application/admin/view/shopro/richtext/edit.html
new file mode 100644
index 000000000..068b93174
--- /dev/null
+++ b/application/admin/view/shopro/richtext/edit.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+
diff --git a/application/admin/view/shopro/richtext/index.html b/application/admin/view/shopro/richtext/index.html
new file mode 100644
index 000000000..bce740336
--- /dev/null
+++ b/application/admin/view/shopro/richtext/index.html
@@ -0,0 +1,35 @@
+
+ {:build_heading()}
+
+
+
diff --git a/application/admin/view/shopro/richtext/recyclebin.html b/application/admin/view/shopro/richtext/recyclebin.html
new file mode 100644
index 000000000..51154e86e
--- /dev/null
+++ b/application/admin/view/shopro/richtext/recyclebin.html
@@ -0,0 +1,25 @@
+
+ {:build_heading()}
+
+
+
diff --git a/application/admin/view/shopro/richtext/select.html b/application/admin/view/shopro/richtext/select.html
new file mode 100644
index 000000000..78334c651
--- /dev/null
+++ b/application/admin/view/shopro/richtext/select.html
@@ -0,0 +1,35 @@
+
+ {:build_heading()}
+
+
+
diff --git a/application/admin/view/shopro/user_fake/add.html b/application/admin/view/shopro/user_fake/add.html
new file mode 100644
index 000000000..0baa7d823
--- /dev/null
+++ b/application/admin/view/shopro/user_fake/add.html
@@ -0,0 +1,30 @@
+
+
+
+
+
+
diff --git a/application/admin/view/shopro/user_fake/edit.html b/application/admin/view/shopro/user_fake/edit.html
new file mode 100644
index 000000000..bf3979d3f
--- /dev/null
+++ b/application/admin/view/shopro/user_fake/edit.html
@@ -0,0 +1,30 @@
+
+
+
+
+
+
diff --git a/application/admin/view/shopro/user_fake/index.html b/application/admin/view/shopro/user_fake/index.html
new file mode 100644
index 000000000..2d91c1dcc
--- /dev/null
+++ b/application/admin/view/shopro/user_fake/index.html
@@ -0,0 +1,35 @@
+
+ {:build_heading()}
+
+
+
diff --git a/application/admin/view/shopro/user_wallet_apply/add.html b/application/admin/view/shopro/user_wallet_apply/add.html
new file mode 100644
index 000000000..bc46a3a3e
--- /dev/null
+++ b/application/admin/view/shopro/user_wallet_apply/add.html
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/application/admin/view/shopro/user_wallet_apply/edit.html b/application/admin/view/shopro/user_wallet_apply/edit.html
new file mode 100644
index 000000000..444aa0ab8
--- /dev/null
+++ b/application/admin/view/shopro/user_wallet_apply/edit.html
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/application/admin/view/shopro/user_wallet_apply/index.html b/application/admin/view/shopro/user_wallet_apply/index.html
new file mode 100644
index 000000000..a60827d75
--- /dev/null
+++ b/application/admin/view/shopro/user_wallet_apply/index.html
@@ -0,0 +1,50 @@
+
+
+
+
+ {:build_heading(null,FALSE)}
+
+
+
+
+
+
diff --git a/application/admin/view/shopro/user_wallet_apply/recyclebin.html b/application/admin/view/shopro/user_wallet_apply/recyclebin.html
new file mode 100644
index 000000000..1ed176a7f
--- /dev/null
+++ b/application/admin/view/shopro/user_wallet_apply/recyclebin.html
@@ -0,0 +1,25 @@
+
+ {:build_heading()}
+
+
+
diff --git a/application/admin/view/shopro/wechat/add.html b/application/admin/view/shopro/wechat/add.html
new file mode 100644
index 000000000..b29b275fe
--- /dev/null
+++ b/application/admin/view/shopro/wechat/add.html
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
diff --git a/application/admin/view/shopro/wechat/edit.html b/application/admin/view/shopro/wechat/edit.html
new file mode 100644
index 000000000..3c0fa80af
--- /dev/null
+++ b/application/admin/view/shopro/wechat/edit.html
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
diff --git a/application/admin/view/shopro/wechat/fans.html b/application/admin/view/shopro/wechat/fans.html
new file mode 100644
index 000000000..064c57c1f
--- /dev/null
+++ b/application/admin/view/shopro/wechat/fans.html
@@ -0,0 +1,189 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
未知
+
+
+
{{scope.row.nickname}}
+
+
+
+
+
+
+ {{scope.row.country}} {{scope.row.province}} {{scope.row.city}}
+
+
+
+
+
+ {{scope.row.subscribe==0?'取消关注':'正在关注'}}
+
+
+
+
+ {{moment(scope.row.subscribe_time*1000).format("YYYY-MM-DD HH:mm:ss")}}
+
+
+
+
+ {{moment(scope.row.updatetime*1000).format("YYYY-MM-DD HH:mm:ss")}}
+
+
+
+
+
+ 查看
+
+
+
+
+
+
\ No newline at end of file
diff --git a/application/admin/view/shopro/wechat/index.html b/application/admin/view/shopro/wechat/index.html
new file mode 100644
index 000000000..268342976
--- /dev/null
+++ b/application/admin/view/shopro/wechat/index.html
@@ -0,0 +1,35 @@
+
+ {:build_heading()}
+
+
+
diff --git a/application/admin/view/shopro/wechat/menu.html b/application/admin/view/shopro/wechat/menu.html
new file mode 100644
index 000000000..b7fa0a75a
--- /dev/null
+++ b/application/admin/view/shopro/wechat/menu.html
@@ -0,0 +1,364 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/application/database.php b/application/database.php
index 7b9f8f23b..26c02ff74 100755
--- a/application/database.php
+++ b/application/database.php
@@ -22,7 +22,7 @@ return [
// 用户名
'username' => Env::get('database.username', 'root'),
// 密码
- 'password' => Env::get('database.password', ''),
+ 'password' => Env::get('database.password', 'root'),
// 端口
'hostport' => Env::get('database.hostport', ''),
// 连接dsn
diff --git a/application/extra/addons.php b/application/extra/addons.php
index e96fabfcc..43fdceb06 100644
--- a/application/extra/addons.php
+++ b/application/extra/addons.php
@@ -4,6 +4,10 @@ return array (
'autoload' => false,
'hooks' =>
array (
+ 'app_init' =>
+ array (
+ 0 => 'shopro',
+ ),
),
'route' =>
array (
diff --git a/public/admin.php b/public/LyIKhAFtnm.php
similarity index 100%
rename from public/admin.php
rename to public/LyIKhAFtnm.php
diff --git a/public/assets/js/backend/faqueue/log.js b/public/assets/js/backend/faqueue/log.js
new file mode 100644
index 000000000..ff43390dc
--- /dev/null
+++ b/public/assets/js/backend/faqueue/log.js
@@ -0,0 +1,60 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'faqueue/log/index',
+ del_url: 'faqueue/log/del',
+ table: 'faqueue_log',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'queue', title: __('Queue')},
+ {field: 'job', title: __('Job'),operate:'LIKE %...%'},
+ {field: 'data', title: __('Data'),formatter:function(value,row){
+ if(row.job.indexOf('EmailJob') > -1 || row.job.indexOf('SmsJob') > -1){
+ var div = document.createElement('div');
+ div.innerHTML = value;
+ value = div.innerText || div.textContent;
+ var data = JSON.parse(value);
+ var html = [];
+ for(k in data){
+ html.push(k+':'+data[k].substring(0,20)+'
');
+ }
+ return html.join(' ');
+ }else{
+ return value;
+ }
+ },operate:'LIKE %...%'},
+ {field: 'create_time', title: __('Create_time'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
+ ]
+ ]
+ });
+
+
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/activity/activity.js b/public/assets/js/backend/shopro/activity/activity.js
new file mode 100644
index 000000000..4c987e267
--- /dev/null
+++ b/public/assets/js/backend/shopro/activity/activity.js
@@ -0,0 +1,915 @@
+// requirejs.config({
+// paths: {
+// vue: "/assets/addons/shopro/libs/vue"
+// }
+// })
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 检测是否安装 redis
+ this.checkRedis();
+ var activityIndex = new Vue({
+ el: "#activity-index",
+ data() {
+ return {
+ tipCloseFlag: true,
+ activityType: 'all',
+ activityName: '全部',
+ activityOptions: [{
+ value: 'all',
+ label: '全部'
+ }, {
+ value: 'seckill',
+ label: '秒杀活动'
+ }, {
+ value: 'groupon',
+ label: '拼团活动'
+ }],
+ statusOptins: {
+ '全部': 'all',
+ '未开始': 'nostart',
+ '进行中': 'ing',
+ '已结束': 'ended'
+ },
+ statusName: '全部',
+ statusType: 'all',
+ activityData: [],
+ dialogVisible: false,
+ activityForm: {
+ title: '',
+ type: 'seckill',
+ dateTime: [],
+ starttime: '',
+ endtime: '',
+ // description: '',
+ richtext_id: '',
+ richtext_title:'',
+ goods_list: [],
+ goods_ids: '',
+ rules: {
+ limit_buy: '',
+ order_auto_close: '',
+ activity_auto_close: '',
+ team_num: '',
+ is_alone: 0,
+ is_fictitious: 0,
+ fictitious_num: '',
+ valid_time: '',
+ team_card: 0
+ },
+ limit_buy: '',
+ order_auto_close: '',
+ activity_auto_close: '',
+ team_num: '',
+ is_alone: 0,
+ is_fictitious: 0,
+ fictitious_num: '',
+ valid_time: '',
+ team_card: 0
+ },
+ activityFormType: '',
+ level1Delete: {
+ limit_buy: '',
+ order_auto_close: '',
+ activity_auto_close: '',
+ team_num: '',
+ is_alone: 0,
+ is_fictitious: 0,
+ fictitious_num: '',
+ valid_time: '',
+ dateTime: '',
+ team_card: 0
+ },
+ seckillDelete: {
+ team_num: '',
+ is_alone: 0,
+ is_fictitious: 0,
+ fictitious_num: '',
+ valid_time: '',
+ team_card: 0
+ },
+ rules: {
+ title: [{ required: true, message: '请输入活动名称', trigger: 'blur' }],
+ type: [{ required: true, message: '请选择活动类型', trigger: 'blur' }],
+ dateTime: [{ required: true, message: '请选择活动时间', trigger: 'blur' }],
+ limit_buy: [{required: true, message: '请输入限购件数', trigger: 'blur' }],
+ team_num: [{required: true, message: '请输入每人限购件数', trigger: 'blur' }],
+ goods_list: [{ required: true, message: '请输入选择商品', trigger: 'blur' }],
+ },
+ formSubFlag: false,
+ disabledFlag: false,
+
+ currentPage: 1,//分页
+ totalPage: 0,
+ offset: 0,
+ limit: 10,
+ editId: ''
+ }
+ },
+ mounted() {
+ this.getActivityData()
+ },
+ methods: {
+ tipClose() {
+ this.tipCloseFlag = false
+ },
+ selectChange(val) {
+ this.activityType = val;
+ this.activityName = this.filterActivityType(val);
+ this.offset=0;
+ this.getActivityData();
+ },
+ radioChange(val) {
+ this.statusType = this.statusOptins[val];
+ this.offset=0;
+ this.getActivityData()
+ },
+ getActivityData() {
+ var that = this;
+ that.objClear(that.activityForm)
+ Fast.api.ajax({
+ url: 'shopro/activity/activity/index',
+ loading: true,
+ type: 'GET',
+ data: {
+ sort: 'id',
+ order: 'desc',
+ offset: that.offset,
+ limit: that.limit,
+ type: that.activityType,
+ status: that.statusType,
+ }
+ }, function (ret, res) {
+ that.activityData = res.data.rows;
+ that.totalPage=res.data.total
+ return false;
+ })
+ },
+ foundActivity() {
+ this.dialogVisible = true
+ this.activityFormType = 'add';
+ this.editId=0;
+ },
+ handleClose() {
+ this.dialogVisible = false
+ this.disabledFlag = false
+ this.objClear(this.activityForm)
+ },
+ handleClick(row, handleType) {
+ let that = this;
+ that.activityFormType = handleType
+ switch (handleType) {
+ case 'edit':
+ that.editId = row.id
+ that.reqDetail()
+ that.dialogVisible = true;
+ break;
+ case 'view':
+ that.editId = row.id
+ that.reqDetail()
+ that.dialogVisible = true;
+ that.disabledFlag = true;
+ break;
+ case 'delete':
+ Fast.api.ajax({
+ url: `shopro/activity/activity/del/ids/${row.id}`,
+ loading: true,
+ type: 'POST',
+ data: {}
+ }, function (ret, res) {
+ that.getActivityData()
+ })
+ break;
+ }
+ },
+ chooseMethod() {
+ let that = this;
+ parent.Fast.api.open("shopro/richtext/select", "选择活动说明", {
+ callback: function (data) {
+ that.activityForm.richtext_id = data.data.id;
+ that.activityForm.richtext_title = data.data.title
+ }
+ });
+ },
+ chooseGoods(type) {
+ var that = this;
+ // var type = $(this).data("type") ? $(this).data("type") : null
+ var multiple = true;
+ that.activityForm.goods_list = that.activityForm.goods_list ? that.activityForm.goods_list : []
+ parent.Fast.api.open("shopro/goods/select?multiple=" + multiple + "&type=" + type, "选择商品", {
+ callback: function (data) {
+ if (Array.isArray(data.data)) {
+ data.data.forEach(e => {
+ let flag = true
+ that.activityForm.goods_list.forEach(i => {
+ if (i.id == e.id) {
+ alert("不可重复选择")
+ flag = false
+ throw Error();
+ }
+ })
+ if (flag) {
+ let obj = {
+ actSkuPrice: "",
+ dispatch_type_text: e.dispatch_type_text,
+ id: e.id,
+ image: e.image,
+ opt: 0,
+ status_text: e.status_text,
+ title: e.title,
+ type_text: e.type_text,
+ }
+ that.activityForm.goods_list.push(obj)
+ }
+ })
+ } else {
+ let obj = {
+ actSkuPrice: "",
+ dispatch_type_text: data.data.dispatch_type_text,
+ id: data.data.id,
+ image: data.data.image,
+ opt: 0,
+ status_text: data.data.status_text,
+ title: data.data.title,
+ type_text: data.data.type_text,
+ }
+ let Flag = true
+ that.activityForm.goods_list.forEach(i => {
+ if (i.id == data.data.id) {
+ alert("不可重复选择")
+ Flag = false
+ throw Error();
+ }
+ })
+ that.activityForm.goods_list.push(obj)
+ }
+ }
+ });
+ return false;
+ },
+ chooseActivityPrice(id, idx, actSkuPrice) {
+ var that = this;
+ var multiple = $(this).data("multiple") ? $(this).data("multiple") : false;
+ let type = that.activityFormType == 'view' ? that.activityFormType : ''
+ parent.Fast.api.open("shopro/activity/activity/sku?id=" + id + "&multiple=" + multiple + "&actSkuPrice=" + actSkuPrice + "&activity_id=" + that.editId + "&type=" + type, "设置活动商品", {
+ callback: function (data) {
+ that.$set(that.activityForm.goods_list[idx], "opt", 1)
+ that.$set(that.activityForm.goods_list[idx], "actSkuPrice", data)
+ }
+ });
+ return false;
+ },
+ selectDelete(i) {
+ this.activityForm.goods_list.splice(i, 1)
+ },
+ submitForm(activityForm) {
+ let that = this;
+ that.disabledFlag = false
+ that.$refs[activityForm].validate((valid) => {
+ if (valid) {
+ let subForm = JSON.parse(JSON.stringify(that.activityForm))
+ let ids = []
+ if (subForm.goods_list.length == 0) {
+ alert('请选择参加活动的商品')
+ return false
+ }
+ subForm.goods_list.forEach(i => {
+ ids.push(i.id)
+ })
+ subForm.goods_ids = ids.join(',')
+ // subForm.description = that.textareaToStr(subForm.description);
+ subForm.dateTime.forEach(i => {
+ moment(i).valueOf()
+ });
+ subForm.starttime = subForm.dateTime[0];
+ subForm.endtime = subForm.dateTime[1];
+
+ delete subForm.dateTime
+ for (key in subForm.rules) {
+ subForm.rules[key] = subForm[key]
+ }
+ //删除多余字段
+ for (key in that.level1Delete) {
+ delete subForm[key]
+ }
+ if (subForm.type == "seckill") {
+ for (key in that.seckillDelete) {
+ delete subForm.rules[key]
+ }
+ }
+ switch (that.activityFormType) {
+ case 'add':
+ let addDate = JSON.parse(JSON.stringify(subForm))
+ Fast.api.ajax({
+ url: 'shopro/activity/activity/add',
+ loading: true,
+ type: 'POST',
+ data: addDate
+ }, function (ret, res) {
+ if(res.code==1){
+ that.dialogVisible = false;
+ that.getActivityData()
+ }
+ })
+ break;
+ case 'edit':
+ let editData = JSON.parse(JSON.stringify(subForm))
+ Fast.api.ajax({
+ url: `shopro/activity/activity/edit/ids/${that.editId}`,
+ loading: true,
+ type: 'POST',
+ data: editData
+ }, function (ret, res) {
+ that.editId = ''
+ if(res.code==1){
+ that.dialogVisible = false;
+ that.getActivityData()
+ }
+ })
+ break;
+ }
+ } else {
+ console.log('error submit!!');
+ return false;
+ }
+ });
+ },
+ objClear(obj) {
+ for (key in obj) {
+ if (key == 'rules') {
+ for (j in obj[key]) {
+ obj[key][j] = ''
+ }
+ }else if (key == 'dateTime' || key == 'goods_list') {
+ obj[key] = []
+ }else if (key == 'is_alone' || key == 'is_fictitious' || key == 'team_card') {
+ obj[key] = 0
+ }else if (key == 'type') {
+ obj[key] = 'seckill'
+ }else {
+ obj[key] = ''
+ }
+
+ }
+ },
+ filterActivityType(type) {
+ switch (type) {
+ case 'seckill':
+ return '秒杀活动';
+ break;
+ case 'groupon':
+ return '拼团活动';
+ break;
+ case 'all':
+ return '全部';
+ break;
+ }
+ },
+ changeDateTime(e) {
+ let _this = this
+ _this.$nextTick(() => {
+ _this.$set(_this.activityForm, "dateTime", [e[0], e[1]]);
+ _this.$forceUpdate();
+ });
+ },
+ reqDetail() {
+ let that = this;
+ let id = that.editId
+ Fast.api.ajax({
+ url: `shopro/activity/activity/detail`,
+ loading: true,
+ type: 'GET',
+ data: {
+ ids: id
+ }
+ }, function (ret, res) {
+ let arr = res.data;
+ for (key in that.activityForm) {
+ if (arr[key]) {
+ if (key == 'rules') {
+ // that.activityForm[key]=arr.rule_arr
+ for (kk in that.activityForm[key]) {
+ that.activityForm[key][kk] = arr.rule_arr[kk]
+ }
+ } else {
+ that.activityForm[key] = arr[key]
+ }
+ } else {
+ that.activityForm[key] = arr.rule_arr[key] ? arr.rule_arr[key] : ''
+ }
+ };
+ that.activityForm.dateTime = [];
+ that.activityForm.dateTime.push(moment(that.activityForm.starttime * 1000).format("YYYY-MM-DD HH:mm:ss"));
+ that.activityForm.dateTime.push(moment(that.activityForm.endtime * 1000).format("YYYY-MM-DD HH:mm:ss"));
+ return false;
+ })
+ },
+ handleSizeChange(val) {
+ this.offset = 0
+ this.limit = val
+ this.getActivityData()
+ },
+ handleCurrentChange(val) {
+ this.offset = (val - 1) * this.limit
+ this.getActivityData()
+ },
+ goRecycle(){
+ parent.Fast.api.open("shopro/activity/activity/recyclebin", "查看历史活动");
+ }
+
+ },
+ watch: {
+ activityForm: {
+ handler: function (newVal) {
+ if (newVal.type == 'seckill') {
+ if (newVal.title != '' && newVal.dateTime.length !=0 && newVal.limit_buy != "" && newVal.goods_list.length !=0 && newVal.type != '') {
+ this.formSubFlag = true
+ } else {
+ this.formSubFlag = false
+ }
+ } else {
+ if (newVal.title != '' && newVal.dateTime.length !=0 && newVal.limit_buy != "" && newVal.team_num != "" && newVal.goods_list.length !=0 && newVal.type != '') {
+ this.formSubFlag = true
+ } else {
+ this.formSubFlag = false
+ }
+ }
+
+ },
+ deep: true
+ }
+ }
+
+ })
+ },
+ recyclebin: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ 'dragsort_url': ''
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: 'shopro/activity/activity/recyclebin' + location.search,
+ pk: 'id',
+ sortName: 'id',
+ commonSearch:false,
+ columns: [
+ [
+ { checkbox: true },
+ { field: 'id', title: __('Id') },
+ { field: 'title', title: __('Title'), align: 'left' },
+ {
+ field: 'deletetime',
+ title: __('Deletetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ $(document).on("click", ".radioSelect", function () {
+ $(".select-show").addClass("hide")
+ $("." + $(this).val() + "-show").removeClass("hide")
+ })
+
+ // 检测是否安装 redis
+ this.checkRedis();
+
+ var goods = new Vue({
+ el: "#activityData",
+ data() {
+ return {
+ activity: Config.activity,
+ goodsList: Config.goodsList ? Config.goodsList : [],
+ actSkuPrice: [],
+ }
+ },
+ mounted() {
+ },
+ methods: {
+ selectDelete(i) {
+ this.goodsList.splice(i, 1)
+ }
+ },
+ watch: {
+ goodsList: {
+ handler: function (newVal) {
+ let goods_ids = []
+ newVal.forEach(i => {
+ goods_ids.push(i.id)
+ })
+ goods_ids = goods_ids.join(",")
+ $("#goods_ids").val(goods_ids)
+ },
+ deep: true
+ },
+ }
+ })
+ //添加商品
+ $(document).on("click", ".chooseGoods", function () {
+ var type = $(this).data("type") ? $(this).data("type") : null
+ var multiple = $(this).data("multiple") ? $(this).data("multiple") : false;
+ parent.Fast.api.open("shopro/goods/select?multiple=" + multiple + "&type=" + type, "选择商品", {
+ callback: function (data) {
+ if (Array.isArray(data.data)) {
+ data.data.forEach(e => {
+ let flag = true
+ goods.$data.goodsList.forEach(i => {
+ if (i.id == e.id) {
+ alert("不可重复选择")
+ flag = false
+ throw Error();
+ }
+ })
+ if (flag) {
+ let obj = {
+ actSkuPrice: "",
+ dispatch_type_text: e.dispatch_type_text,
+ id: e.id,
+ image: e.image,
+ opt: 0,
+ status_text: e.status_text,
+ title: e.title,
+ type_text: e.type_text,
+ }
+ goods.$data.goodsList.push(obj)
+ }
+ })
+ } else {
+ let obj = {
+ actSkuPrice: "",
+ dispatch_type_text: data.data.dispatch_type_text,
+ id: data.data.id,
+ image: data.data.image,
+ opt: 0,
+ status_text: data.data.status_text,
+ title: data.data.title,
+ type_text: data.data.type_text,
+ }
+ let Flag = true
+ goods.$data.goodsList.forEach(i => {
+ if (i.id == data.data.id) {
+ alert("不可重复选择")
+ Flag = false
+ throw Error();
+ }
+ })
+ goods.$data.goodsList.push(obj)
+ }
+ }
+ });
+ return false;
+ })
+ $(document).on("click", ".chooseActivityPrice", function () {
+ var multiple = $(this).data("multiple") ? $(this).data("multiple") : false;
+ let id = $(this).attr("data-id")
+ let idx = $(this).attr("data-index")
+ let actSkuPrice = $(this).attr("data-actSkuPrice")
+ let activity_id = 0
+ parent.Fast.api.open("shopro/activity/activity/sku?id=" + id + "&multiple=" + multiple + "&actSkuPrice=" + actSkuPrice + "&activity_id=" + activity_id, "设置活动商品", {
+ callback: function (data) {
+ goods.$set(goods.$data.goodsList[idx], "opt", 1)
+ goods.$set(goods.$data.goodsList[idx], "actSkuPrice", data)
+ }
+ });
+ return false;
+ })
+ $(document).on("click", "#actSub", function () {
+ let subFlag = true;
+ let ordergoodslist = JSON.parse(JSON.stringify(goods.$data.goodsList))
+ ordergoodslist.forEach(i => {
+ if (i.actSkuPrice) {
+ let arr = []
+ JSON.parse(i.actSkuPrice).forEach(e => {
+ if (e.status == 'up') {
+ arr.push(e)
+ }
+ })
+ i.actSkuPrice = JSON.stringify(arr)
+ }
+ })
+ $("#goodsList").val(JSON.stringify(ordergoodslist))
+ if (subFlag) {
+ var that = this;
+ Layer.confirm('确认提交吗', {
+ btn: ['确认', '取消']
+ }, function () {
+ $(that).closest("form").trigger("submit");
+ Layer.closeAll();
+ return true;
+ }, function () {
+ Layer.closeAll();
+ return false;
+ });
+ }
+
+ });
+ Controller.api.bindevent();
+ },
+ sku: function () {
+ var vueSku = new Vue({
+ el: "#skuPrce",
+ data() {
+ return {
+ skuList: Config.skuList,
+ skuPrice: Config.skuPrice,
+ actSkuPrice: Config.actSkuPrice,
+ is_edit: false
+ }
+ },
+ mounted() {
+ let seleSkuPrice = decodeURI(window.location.search.substring(1).split('&')[2].split('=')[1])
+ this.is_edit = decodeURI(window.location.search.substring(1).split('&')[4].split('=')[1]) == 'view' ? true : false
+ if (seleSkuPrice) {
+ JSON.parse(seleSkuPrice).forEach(i => {
+ this.actSkuPrice.forEach(e => {
+ if (i.sku_price_id == e.sku_price_id) {
+ e.price = i.price
+ e.status = i.status
+ e.stock = i.stock
+ }
+ })
+ })
+ }
+
+ },
+ methods: {
+ goJoin(i) {
+ let status = this.actSkuPrice[i].status === 'up' ? 'down' : 'up';
+ this.$set(this.actSkuPrice[i], 'status', status)
+ },
+ },
+
+ })
+ $(document).on("click", "#activitySub", function () {
+ Layer.confirm('确认提交吗', {
+ btn: ['确认', '取消']
+ }, function () {
+ let isSubmit = true
+ isSubmit = !(vueSku.$data.actSkuPrice.every(function (item, index, array) {
+ return item.status == 'down';
+ }))
+ vueSku.$data.actSkuPrice.forEach(i => {
+ if (i.status == 'up' && !i.stock) {
+ isSubmit = false
+ }
+ if (i.status == 'up' && !i.price) {
+ isSubmit = false
+ }
+ })
+ if (isSubmit) {
+ Fast.api.close(JSON.stringify(vueSku.$data.actSkuPrice));
+ return true;
+ } else {
+ layer.msg('请把信息填写完整');
+ }
+ return true;
+ }, function () {
+ Layer.closeAll();
+ return false;
+ });
+ })
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ // 检测是否安装 redis
+ this.checkRedis();
+ var goods = new Vue({
+ el: "#activityData",
+ data() {
+ return {
+ activity: Config.activity,
+ goodsList: Config.goodsList,
+ actSkuPrice: [],
+ }
+ },
+ mounted() {
+ let goods_ids = []
+ this.goodsList.forEach(i => {
+ goods_ids.push(i.id)
+ })
+ goods_ids = goods_ids.join(",")
+ $("#goods_ids").val(goods_ids)
+ $("#goodsList").val(JSON.stringify(this.goodsList))
+
+ },
+ methods: {
+ selectDelete(i) {
+ this.goodsList.splice(i, 1)
+ }
+ },
+ watch: {
+ goodsList: {
+ handler: function (newVal) {
+ let goods_ids = []
+ newVal.forEach(i => {
+ goods_ids.push(i.id)
+ })
+ goods_ids = goods_ids.join(",")
+ $("#goods_ids").val(goods_ids)
+ $("#goodsList").val(JSON.stringify(newVal))
+ },
+ deep: true
+ },
+ }
+ })
+ $(document).on("click", ".chooseGoods", function () {
+ var type = $(this).data("type") ? $(this).data("type") : null
+ var multiple = $(this).data("multiple") ? $(this).data("multiple") : false;
+ parent.Fast.api.open("shopro/goods/select?multiple=" + multiple + "&type=" + type, "选择商品", {
+ callback: function (data) {
+ if (Array.isArray(data.data)) {
+ data.data.forEach(e => {
+ let flag = true
+ goods.$data.goodsList.forEach(i => {
+ if (i.id == e.id) {
+ alert("不可重复选择")
+ flag = false
+ throw Error();
+ }
+ })
+ if (flag) {
+ let obj = {
+ actSkuPrice: "",
+ dispatch_type_text: e.dispatch_type_text,
+ id: e.id,
+ image: e.image,
+ opt: 0,
+ status_text: e.status_text,
+ title: e.title,
+ type_text: e.type_text,
+ }
+ goods.$data.goodsList.push(obj)
+ }
+ })
+ } else {
+ let obj = {
+ actSkuPrice: "",
+ dispatch_type_text: data.data.dispatch_type_text,
+ id: data.data.id,
+ image: data.data.image,
+ opt: 0,
+ status_text: data.data.status_text,
+ title: data.data.title,
+ type_text: data.data.type_text,
+ }
+ let Flag = true
+ goods.$data.goodsList.forEach(i => {
+ if (i.id == data.data.id) {
+ alert("不可重复选择")
+
+ Flag = false
+ throw Error();
+ }
+ })
+ goods.$data.goodsList.push(obj)
+ }
+ }
+ });
+ return false;
+ })
+ $(document).on("click", ".chooseActivityPrice", function () {
+ var multiple = $(this).data("multiple") ? $(this).data("multiple") : false;
+ let id = $(this).attr("data-id")
+ let idx = $(this).attr("data-index")
+ let actSkuPrice = $(this).attr("data-actSkuPrice")
+ let activity_id = goods.$data.activity.id
+ parent.Fast.api.open("shopro/activity/activity/sku?id=" + id + "&multiple=" + multiple + "&actSkuPrice=" + actSkuPrice + "&activity_id=" + activity_id, "设置活动商品", {
+ callback: function (data) {
+ goods.$set(goods.$data.goodsList[idx], "opt", 1)
+ goods.$set(goods.$data.goodsList[idx], "actSkuPrice", data)
+ }
+ });
+ return false;
+ })
+ $(document).on("click", "#actSub", function () {
+ let subFlag = true;
+ let ordergoodslist = JSON.parse(JSON.stringify(goods.$data.goodsList))
+ ordergoodslist.forEach(i => {
+ if (i.actSkuPrice) {
+ let arr = []
+ JSON.parse(i.actSkuPrice).forEach(e => {
+ if (e.status == 'up') {
+ arr.push(e)
+ }
+ })
+ i.actSkuPrice = JSON.stringify(arr)
+ }
+ })
+ $("#goodsList").val(JSON.stringify(ordergoodslist))
+ if (subFlag) {
+ var that = this;
+ Layer.confirm('确认提交吗', {
+ btn: ['确认', '取消']
+ }, function () {
+ $(that).closest("form").trigger("submit");
+ Layer.closeAll();
+ return true;
+ }, function () {
+ Layer.closeAll();
+ return false;
+ });
+ }
+ });
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ },
+ select: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/activity/activity/index?page_type=select&type=' + Backend.api.query('type'),
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ { checkbox: true },
+ { field: 'id', title: __('Id') },
+ { field: 'title', title: __('Title') },
+ { field: 'goods_ids', title: __('Goods_ids') },
+ { field: 'type', title: __('Type') },
+ // { field: 'description', title: __('Description') },
+ { field: 'starttime', title: __('Starttime'), operate: 'RANGE', addclass: 'datetimerange', formatter: Table.api.formatter.datetime },
+ { field: 'endtime', title: __('Endtime'), operate: 'RANGE', addclass: 'datetimerange', formatter: Table.api.formatter.datetime },
+ { field: 'createtime', title: __('Createtime'), operate: 'RANGE', addclass: 'datetimerange', formatter: Table.api.formatter.datetime },
+ { field: 'updatetime', title: __('Updatetime'), operate: 'RANGE', addclass: 'datetimerange', formatter: Table.api.formatter.datetime },
+ {
+ field: 'operate', title: __('Operate'), events: {
+ 'click .btn-chooseone': function (e, value, row, index) {
+ var multiple = Backend.api.query('multiple');
+ multiple = multiple == 'true' ? true : false;
+ Fast.api.close({ data: row, multiple: multiple });
+ },
+ }, formatter: function () {
+ return '
' + __('Choose') + '';
+ }
+ }
+ ]
+ ]
+ });
+
+ // 选中多个
+ $(document).on("click", ".btn-choose-multi", function () {
+ var couponsArr = new Array();
+ $.each(table.bootstrapTable("getAllSelections"), function (i, j) {
+ couponsArr.push(j.id);
+ });
+ var multiple = Backend.api.query('multiple');
+ multiple = multiple == 'true' ? true : false;
+ let row = {}
+ row.ids = couponsArr.join(",")
+ Fast.api.close({ data: row, multiple: multiple });
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ require(['upload'], function (Upload) {
+ Upload.api.plupload($("#toolbar .plupload"), function () {
+ $(".btn-refresh").trigger("click");
+ });
+ });
+
+ },
+ checkRedis: function () {
+ if (!Config.hasRedis) {
+ Layer.confirm('检测到系统未配置 Redis,添加的活动将不能得到有效控制,确定要继续吗?', {
+ btn: ['确认', '取消']
+ }, function () {
+ Layer.closeAll();
+ return true;
+ }, function () {
+ Layer.closeAll();
+ if (window.parent) {
+ window.parent.Layer.closeAll();
+ }
+ return false;
+ });
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/activity/activity_sku_price.js b/public/assets/js/backend/shopro/activity/activity_sku_price.js
new file mode 100644
index 000000000..62240de97
--- /dev/null
+++ b/public/assets/js/backend/shopro/activity/activity_sku_price.js
@@ -0,0 +1,116 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/activity/activity_sku_price/index' + location.search,
+ add_url: 'shopro/activity/activity_sku_price/add',
+ edit_url: 'shopro/activity/activity_sku_price/edit',
+ del_url: 'shopro/activity/activity_sku_price/del',
+ multi_url: 'shopro/activity/activity_sku_price/multi',
+ table: 'shopro_activity_goods_sku_price',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'activity_id', title: __('Activity_id')},
+ {field: 'sku_price_id', title: __('Sku_price_id')},
+ {field: 'goods_id', title: __('Goods_id')},
+ {field: 'stock', title: __('Stock')},
+ {field: 'sales', title: __('Sales')},
+ {field: 'price', title: __('Price'), operate:'BETWEEN'},
+ {field: 'createtime', title: __('Createtime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ recyclebin: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ 'dragsort_url': ''
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: 'shopro/activity/activity_sku_price/recyclebin' + location.search,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {
+ field: 'deletetime',
+ title: __('Deletetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'operate',
+ width: '130px',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ buttons: [
+ {
+ name: 'Restore',
+ text: __('Restore'),
+ classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
+ icon: 'fa fa-rotate-left',
+ url: 'shopro/activity/activity_sku_price/restore',
+ refresh: true
+ },
+ {
+ name: 'Destroy',
+ text: __('Destroy'),
+ classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
+ icon: 'fa fa-times',
+ url: 'shopro/activity/activity_sku_price/destroy',
+ refresh: true
+ }
+ ],
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/activity/groupon.js b/public/assets/js/backend/shopro/activity/groupon.js
new file mode 100644
index 000000000..847d6d654
--- /dev/null
+++ b/public/assets/js/backend/shopro/activity/groupon.js
@@ -0,0 +1,397 @@
+const moment = require("moment");
+
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ var grouponIndex = new Vue({
+ el: "#groupon-index",
+ data() {
+ return {
+ grouponType: '',
+ grouponName: '',
+ grouponOptions: [],
+ statusOptins: {
+ '全部': 'all',
+ '拼团中': 'ing',
+ '已成团': 'finish',
+ '解散&退款': 'invalid',
+ },
+ statusName: '全部',
+ statusType: 'all',
+ grouponData: [],
+ searchKey: '',
+ currentPage: 1,
+ totalPage: 0,
+ offset: 0,
+ limit: 10,
+ dialogTeamDetail: false,
+ grouponGoodsData: [],
+ grouponTeamList: [],
+ is_define_grouponTeamListLeng:'',
+ is_dialog_opt:false,
+ temp:null
+ }
+ },
+ mounted() {
+ this.getgrouponOptions()
+ },
+ methods: {
+ selectChange(val) {
+ this.grouponType = val;
+ this.grouponOptions.forEach(i=>{
+ if(i.id==val){
+ this.grouponName=i.label
+ }
+ })
+ this.offset=0;
+ this.getgrouponData()
+ },
+ radioChange(val) {
+ this.statusType = this.statusOptins[val];
+ this.offset=0;
+ this.getgrouponData()
+ },
+ getgrouponOptions() {
+ let that = this;
+ Fast.api.ajax({
+ url: 'shopro/activity/activity/all',
+ loading: true,
+ type: 'GET',
+ data: {
+ type: 'groupon'
+ }
+ }, function (ret, res) {
+ if(res.data.length){
+ res.data.forEach(i => {
+ that.grouponOptions.push({
+ value: i.id,
+ label: i.title
+ })
+ })
+ that.grouponType = that.grouponOptions[0].value;
+ that.grouponName = that.grouponOptions[0].label;
+ that.getgrouponData();
+ }
+ return false;
+ })
+ },
+ getgrouponData() {
+ var that = this;
+ window.clearInterval(that.temp)
+ that.is_dialog_opt=false
+ Fast.api.ajax({
+ url: 'shopro/activity/groupon/index',
+ loading: true,
+ type: 'GET',
+ data: {
+ sort: 'id',
+ order: 'desc',
+ offset: that.offset,
+ limit: that.limit,
+ activity_id: that.grouponType,
+ status: that.statusType,
+ search: that.searchKey,
+ }
+ }, function (ret, res) {
+ let arrMsg = []
+ res.data.rows.forEach(i => {
+ arrMsg.push({
+ id: i.id,
+ goods_title: i.goods.title,
+ goods_image: i.goods.image,
+ createtime: i.createtime,
+ user_nickname: i.groupon_log[0].user_nickname,
+ arr: i.groupon_log,
+ expiretime: i.expiretime,
+ // expiretime: 1590810077,
+ countDown: '',
+ status: i.status,
+ status_text: i.status_text,
+ num: i.num,
+ current_num: i.current_num
+ })
+ })
+ that.totalPage=res.data.total
+ that.timer(arrMsg)
+ return false;
+ })
+ },
+ timer(arr) {
+ let that = this;
+ that.temp = setInterval(() => {
+ arr.forEach((item, index) => {
+ that.$set(arr[index], 'countDown', that.countDownFun(item.expiretime * 1000));
+ });
+ that.grouponData = arr
+ }, 1000);
+ },
+ countDownFun(time) {
+ time--;
+ let nowTime = new Date().getTime();
+ if (nowTime <= time) {
+ let timediff = Math.round((time - nowTime) / 1000);
+ let day = parseInt(timediff / 3600 / 24)>9?parseInt(timediff / 3600 / 24):'0'+parseInt(timediff / 3600 / 24);
+ let hour = parseInt((timediff / 3600) % 24)>9?parseInt((timediff / 3600) % 24):'0'+parseInt((timediff / 3600) % 24);
+ let minute = parseInt((timediff / 60) % 60)>9?parseInt((timediff / 60) % 60):'0'+parseInt((timediff / 60) % 60);
+ let second = timediff % 60>9?timediff % 60:'0'+timediff % 60;
+ return day + "天" + hour + "时" + minute + "分" + second + "秒";
+ } else {
+ return "-";
+ }
+ },
+ goDetail(id, row) {
+ this.dialogTeamDetail = true
+ this.grouponGoodsData = []
+ this.grouponGoodsData.push(row)
+ this.grouponTeamList = JSON.parse(JSON.stringify(this.grouponGoodsData[0].arr));
+ },
+ handleSizeChange(val) {
+ this.offset = 0
+ this.limit = val
+ this.getgrouponData()
+ },
+ handleCurrentChange(val) {
+ this.offset = (val - 1) * this.limit
+ this.getgrouponData()
+ },
+ handleTeamDetailClose() {
+ this.dialogTeamDetail = false
+ if(this.is_dialog_opt){
+ this.getgrouponData()
+ }
+ },
+ refreshTeamer(index) {
+ let that = this;
+ Fast.api.ajax({
+ url: 'shopro/user_fake/random_user',
+ loading: true,
+ type: 'GET',
+ data: {}
+ }, function (ret, res) {
+ if (index == null) {
+ that.grouponTeamList.push({
+ createtime: Date.parse(new Date()) / 1000,
+ user_nickname: res.data.nickname,
+ is_leader: false,
+ user_avatar: res.data.avatar,
+ is_fictitious: true,
+ id: res.data.id,
+ is_define:true
+ })
+
+ } else {
+ let arr = {
+ createtime: Date.parse(new Date()) / 1000,
+ user_nickname: res.data.nickname,
+ is_leader: false,
+ user_avatar: res.data.avatar,
+ is_fictitious: true,
+ id: res.data.id,
+ is_define:true
+ }
+ for (key in arr) {
+ that.grouponTeamList[index][key] = arr[key]
+ }
+ }
+ let leng=0
+ that.grouponTeamList.forEach(i=>{
+ if(!i.is_define){
+ leng++
+ }
+ })
+ that.is_define_grouponTeamListLeng=leng
+ })
+ },
+ defineTeamer(index, row) {
+ let that = this;
+ Fast.api.ajax({
+ url: `shopro/activity/groupon/addFictitious/id/${that.grouponGoodsData[0].id}`,
+ loading: true,
+ type: 'POST',
+ data: {
+ avatar: row.user_avatar,
+ nickname:row.user_nickname
+ }
+ }, function (ret, res) {
+ that.is_dialog_opt=true
+ that.grouponGoodsData = []
+ res.data.goods_title=res.data.goods.title
+ res.data.goods_image=res.data.goods.image
+ that.grouponGoodsData.push(res.data)
+ that.grouponTeamList = JSON.parse(JSON.stringify(that.grouponGoodsData[0].groupon_log));
+ })
+ },
+ cancelTeamer(index) {
+ this.grouponTeamList.splice(index, 1)
+ },
+ dismissTeam() {
+ let that = this;
+ that.dialogTeamDetail = false
+ Fast.api.ajax({
+ url: `shopro/activity/groupon/invalidGroupon/id/${that.grouponGoodsData[0].id}`,
+ loading: true,
+ type: 'POST',
+ data: {}
+ }, function (ret, res) {
+ that.getgrouponData()
+ })
+ },
+ callSearch(e){
+ var evt = window.event || e;
+ if (evt.keyCode == 13) {
+ this.offset=0;
+ this.getgrouponData();
+ }
+ }
+ },
+ beforeDestroy(){
+ window.clearInterval(this.temp)
+ },
+ })
+ },
+ detail: function () {
+ var vue = new Vue({
+ el: "#groupon-detail",
+ data() {
+ return {
+ grouponGoodsData: [],
+ grouponTeamList: [],
+ is_define_grouponTeamListLeng:'',
+ // is_dialog_opt:false,
+ temp:null
+ }
+ },
+ mounted() {
+ let id = Config.id
+ let that = this;
+ Fast.api.ajax({
+ url: `shopro/activity/groupon/detail/id/${id}`,
+ loading: true,
+ type: 'GET',
+ data: {}
+ }, function (ret, res) {
+ let arrMsg = []
+ let datas = []
+ datas.push(res.data)
+ datas.forEach(i => {
+ arrMsg.push({
+ id: i.id,
+ goods_title: i.goods.title,
+ goods_image: i.goods.image,
+ createtime: i.createtime,
+ user_nickname: i.groupon_log[0].user_nickname,
+ arr: i.groupon_log,
+ expiretime: i.expiretime,
+ status: i.status,
+ status_text: i.status_text,
+ num: i.num,
+ current_num: i.current_num
+ })
+ })
+ that.grouponGoodsData = arrMsg;
+ that.grouponTeamList = JSON.parse(JSON.stringify(that.grouponGoodsData[0].arr));
+ let leng=0
+ that.grouponTeamList.forEach(i=>{
+ if(!i.is_define){
+ leng++
+ }
+ })
+ that.is_define_grouponTeamListLeng=leng
+ return false;
+ })
+ },
+ methods: {
+ refreshTeamer(index) {
+ let that = this;
+ Fast.api.ajax({
+ url: 'shopro/user_fake/random_user',
+ loading: true,
+ type: 'GET',
+ data: {}
+ }, function (ret, res) {
+ if (index == null) {
+ that.grouponTeamList.push({
+ createtime: Date.parse(new Date()) / 1000,
+ user_nickname: res.data.nickname,
+ is_leader: false,
+ user_avatar: res.data.avatar,
+ is_fictitious: true,
+ id: res.data.id,
+ is_define:true
+ })
+
+ } else {
+ let arr = {
+ createtime: Date.parse(new Date()) / 1000,
+ user_nickname: res.data.nickname,
+ is_leader: false,
+ user_avatar: res.data.avatar,
+ is_fictitious: true,
+ id: res.data.id,
+ is_define:true
+ }
+ for (key in arr) {
+ that.grouponTeamList[index][key] = arr[key]
+ }
+ }
+ let leng=0
+ that.grouponTeamList.forEach(i=>{
+ if(!i.is_define){
+ leng++
+ }
+ })
+ that.is_define_grouponTeamListLeng=leng
+ })
+ },
+ defineTeamer(index, row) {
+ let that = this;
+ Fast.api.ajax({
+ url: `shopro/activity/groupon/addFictitious/id/${that.grouponGoodsData[0].id}`,
+ loading: true,
+ type: 'POST',
+ data: {
+ avatar: row.user_avatar,
+ nickname:row.user_nickname
+ }
+ }, function (ret, res) {
+ // that.is_dialog_opt=true
+ that.grouponGoodsData = []
+ res.data.goods_title=res.data.goods.title
+ res.data.goods_image=res.data.goods.image
+ that.grouponGoodsData.push(res.data)
+ that.grouponTeamList = JSON.parse(JSON.stringify(that.grouponGoodsData[0].groupon_log));
+ })
+ },
+ cancelTeamer(index) {
+ this.grouponTeamList.splice(index, 1)
+ },
+ dismissTeam() {
+ let that = this;
+ that.dialogTeamDetail = false
+ Fast.api.ajax({
+ url: `shopro/activity/groupon/invalidGroupon/id/${that.grouponGoodsData[0].id}`,
+ loading: true,
+ type: 'POST',
+ data: {}
+ }, function (ret, res) {
+ Fast.api.close({data:123})
+ })
+ },
+ }
+ })
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/app/live.js b/public/assets/js/backend/shopro/app/live.js
new file mode 100644
index 000000000..f3f8b1a05
--- /dev/null
+++ b/public/assets/js/backend/shopro/app/live.js
@@ -0,0 +1,262 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/app/live/index' + location.search,
+ add_url: 'shopro/app/live/add',
+ edit_url: 'shopro/app/live/edit',
+ detail_url: 'shopro/app/live/detail',
+ del_url: 'shopro/app/live/del',
+ multi_url: 'shopro/app/live/multi',
+ table: 'shopro_live',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'name', title: __('Name')},
+ {field: 'room_id', title: __('Room_id')},
+ {field: 'live_status', title: __('Live_status'), searchList: {"101":__('Live_status 101'),"102":__('Live_status 102'),"103":__('Live_status 103'),"104":__('Live_status 104'),"105":__('Live_status 105'),"106":__('Live_status 106'),"107":__('Live_status 107')}, formatter: Table.api.formatter.status},
+ {field: 'starttime', title: __('Starttime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'endtime', title: __('Endtime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'anchor_name', title: __('Anchor_name')},
+ {field: 'share_img', title: __('Share_img'),events: Table.api.events.image,formatter: Table.api.formatter.image},
+ {field: 'createtime', title: __('Createtime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {
+ field: 'buttons',
+ width: "120px",
+ title: '操作',
+ table: table,
+ operate: false,
+ buttons: [
+ {
+ name: 'status',
+ title: '直播详情',
+ text: '查看详情',
+ classname: 'btn btn-xs btn-info btn-dialog',
+ extend: 'data-area=\'["100%", "100%"]\'',
+ url: function (row) {
+ return 'shopro/app/live/detail?ids=' + row.id
+ },
+
+ success: function (data, ret) {
+ Layer.alert(ret.msg + ",返回数据:" + JSON.stringify(data));
+ },
+ error: function (data, ret) {
+ Layer.alert(ret.msg);
+ return false;
+ }
+ },
+ ],
+ formatter: Table.api.formatter.buttons
+ },
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ $("#refreshStatus").click(function(){
+ Fast.api.ajax({
+ url: 'shopro/app/live/syncLive',
+ loading: true,
+ data: {}
+ }, function (ret, res) {
+ setTimeout(function() {
+ $(".btn-refresh").click()
+ }, 1000);
+
+ })
+ })
+ },
+ detail: function () {
+ Controller.api.bindevent();
+ },
+ select: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/app/live/index',
+ }
+ });
+
+ var idArr = [];
+
+ var table = $("#table");
+
+ table.on('check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table', function (e, row) {
+ if (e.type == 'check' || e.type == 'uncheck') {
+ row = [row];
+ } else {
+ idArr = [];
+ }
+ $.each(row, function (i, j) {
+ if (e.type.indexOf("uncheck") > -1) {
+ var index = idArr.indexOf(j.id);
+ if (index > -1) {
+ idArr.splice(index, 1);
+ }
+ } else {
+ idArr.indexOf(j.url) == -1 && idArr.push(j.id);
+ }
+ });
+ });
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ sortName: 'id',
+ showToggle: false,
+ showExport: false,
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'name', title: __('Name')},
+ {field: 'room_id', title: __('Room_id')},
+ {field: 'live_status', title: __('Live_status'), searchList: {"101":__('Live_status 101'),"102":__('Live_status 102'),"103":__('Live_status 103'),"104":__('Live_status 104'),"105":__('Live_status 105'),"106":__('Live_status 106'),"107":__('Live_status 107')}, formatter: Table.api.formatter.status},
+ {field: 'starttime', title: __('Starttime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'endtime', title: __('Endtime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'anchor_name', title: __('Anchor_name')},
+ {field: 'share_img', title: __('Share_img'),events: Table.api.events.image,formatter: Table.api.formatter.image},
+ {field: 'createtime', title: __('Createtime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {
+ field: 'operate', title: __('Operate'), events: {
+ 'click .btn-chooseone': function (e, value, row, index) {
+ var multiple = Backend.api.query('multiple');
+ multiple = multiple == 'true' ? true : false;
+ row.ids=row.id.toString()
+ Fast.api.close({data: row, multiple: multiple});
+ },
+ }, formatter: function () {
+ return '
' + __('Choose') + '';
+ }
+ }
+ ]
+ ]
+ });
+
+ // 选中多个
+ $(document).on("click", ".btn-choose-multi", function () {
+ // var Arr = new Array();
+ // $.each(table.bootstrapTable("getAllSelections"), function (i, j) {
+ // Arr.push(j.id);
+ // });
+ var multiple = Backend.api.query('multiple');
+ multiple = multiple == 'true' ? true : false;
+ let row={}
+ row.ids=idArr.join(",")
+ Fast.api.close({data: row, multiple: multiple});
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ //绑定TAB事件
+ $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
+ var typeStr = $(this).attr("href").replace('#', '');
+ var options = table.bootstrapTable('getOptions');
+ options.pageNumber = 1;
+ options.queryParams = function (params) {
+ params.type = typeStr;
+
+ return params;
+ };
+ table.bootstrapTable('refresh', {});
+ return false;
+
+ });
+ require(['upload'], function (Upload) {
+ Upload.api.plupload($("#toolbar .plupload"), function () {
+ $(".btn-refresh").trigger("click");
+ });
+ });
+
+ },
+ recyclebin: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ 'dragsort_url': ''
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: 'shopro/app/live/recyclebin' + location.search,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'name', title: __('Name'), align: 'left'},
+ {
+ field: 'deletetime',
+ title: __('Deletetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'operate',
+ width: '130px',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ buttons: [
+ {
+ name: 'Restore',
+ text: __('Restore'),
+ classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
+ icon: 'fa fa-rotate-left',
+ url: 'shopro/app/live/restore',
+ refresh: true
+ },
+ {
+ name: 'Destroy',
+ text: __('Destroy'),
+ classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
+ icon: 'fa fa-times',
+ url: 'shopro/app/live/destroy',
+ refresh: true
+ }
+ ],
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/app/score_shop.js b/public/assets/js/backend/shopro/app/score_shop.js
new file mode 100644
index 000000000..408406407
--- /dev/null
+++ b/public/assets/js/backend/shopro/app/score_shop.js
@@ -0,0 +1,444 @@
+requirejs.config({
+ paths: {
+ vue: "/assets/addons/shopro/libs/vue"
+ }
+})
+define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'vue'], function ($, undefined, Backend, Table, Form, Vue) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/app/score_shop/index' + location.search,
+ add_url: 'shopro/app/score_shop/add',
+ edit_url: 'shopro/app/score_shop/edit',
+ del_url: 'shopro/app/score_shop/del',
+ multi_url: 'shopro/app/score_shop/multi',
+ table: 'shopro_goods',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'weigh',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {
+ field: 'image',
+ title: __('Image'),
+ events: Table.api.events.image,
+ formatter: Table.api.formatter.image
+ },
+ {field: 'title', title: __('Title')},
+ {
+ field: 'status',
+ title: __('Status'),
+ searchList: {
+ "up": __('Status up'),
+ "hidden": __('Status hidden'),
+ "down": __('Status down')
+ },
+ formatter: Table.api.formatter.status
+ },
+ {field: 'weigh', title: __('Weigh')},
+ {
+ field: 'operate',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ recyclebin: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ 'dragsort_url': ''
+ }
+ });
+ var table = $("#table");
+ // 初始化表格
+ table.bootstrapTable({
+ url: 'shopro/goods/recyclebin' + location.search,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'title', title: __('Title'), align: 'left'},
+ {
+ field: 'deletetime',
+ title: __('Deletetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'operate',
+ width: '130px',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ buttons: [
+ {
+ name: 'Restore',
+ text: __('Restore'),
+ classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
+ icon: 'fa fa-rotate-left',
+ url: 'shopro/goods/restore',
+ refresh: true
+ },
+ {
+ name: 'Destroy',
+ text: __('Destroy'),
+ classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
+ icon: 'fa fa-times',
+ url: 'shopro/goods/destroy',
+ refresh: true
+ }
+ ],
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ var vue = new Vue({
+ el: "#selectGoods",
+ data() {
+ return {
+ goodsList: Config.goodsList?Config.goodsList:[],
+ }
+ },
+ mounted() {
+ },
+ methods: {
+ selectDelete(i){
+ this.goodsList.splice(i,1)
+ }
+ },
+ watch:{
+ goodsList: {
+ handler: function (newVal) {
+ $("#goodsList").val(JSON.stringify(newVal))
+ },
+ deep: true
+ },
+ }
+ })
+ //添加商品
+ $(document).on("click", ".chooseGoods", function () {
+ var multiple = $(this).data("multiple") ? $(this).data("multiple") : false;
+ vue.$data.goodsList=[]
+ parent.Fast.api.open("shopro/goods/select?multiple="+multiple, "选择商品", {
+ callback: function (data) {
+ vue.$data.goodsList.push(data.data)
+ }
+ });
+ return false;
+ })
+ $(document).on("click", ".chooseIntegralPrice", function () {
+ var multiple = $(this).data("multiple") ? $(this).data("multiple") : false;
+ let id = $(this).attr("data-id")
+ let idx = $(this).attr("data-index")
+ let actSkuPrice = $(this).attr("data-actSkuPrice")
+ parent.Fast.api.open("shopro/app/score_shop/sku?goods_id=" + id + "&multiple=" + multiple + "&actSkuPrice=" + actSkuPrice+ "&id=0", "设置活动商品", {
+ callback: function (data) {
+ vue.$set(vue.$data.goodsList[idx], "opt", 1)
+ vue.$set(vue.$data.goodsList[idx], "actSkuPrice", data)
+ }
+ });
+ return false;
+ })
+ $(document).on("click", "#scoreBtn", function () {
+ let subFlag = true;
+ let ordergoodslist = JSON.parse(JSON.stringify(vue.$data.goodsList))
+ if(ordergoodslist.length==0){
+ Layer.msg('请选择商品');
+ return false;
+ }
+ let isPrice=false
+ ordergoodslist.forEach(i => {
+ console.log(i.actSkuPrice)
+ if (i.actSkuPrice) {
+ let arr = []
+ JSON.parse(i.actSkuPrice).forEach(e => {
+ if (e.status == 'up') {
+ arr.push(e)
+ }
+ })
+ i.actSkuPrice = JSON.stringify(arr)
+ isPrice=true
+ }
+ })
+ if(!isPrice){
+ Layer.msg('请选择编辑价格');
+ return false;
+ }
+ $("#selectScore").val(JSON.stringify(ordergoodslist))
+ if (subFlag) {
+ var that = this;
+ Layer.confirm('确认提交吗', {
+ btn: ['确认', '取消']
+ }, function () {
+ $(that).closest("form").trigger("submit");
+ Layer.closeAll();
+ return true;
+ }, function () {
+ Layer.closeAll();
+ return false;
+ });
+ }
+ });
+ Controller.api.bindevent();
+
+ },
+ sku: function () {
+ var vueSku = new Vue({
+ el: "#skuPrce",
+ data() {
+ return {
+ skuList: Config.skuList,
+ skuPrice: Config.skuPrice,
+ actSkuPrice: Config.actSkuPrice,
+ }
+ },
+ mounted() {
+ let seleSkuPrice = decodeURI(window.location.search.substring(1).split('&')[2].split('=')[1])
+ if (seleSkuPrice!="undefined") {
+ JSON.parse(seleSkuPrice).forEach(i => {
+ this.actSkuPrice.forEach(e => {
+ if (i.sku_price_id == e.sku_price_id) {
+ e.price = i.price
+ e.status = i.status
+ e.stock = i.stock
+ e.score = i.score
+ }
+ })
+ })
+ }
+ },
+ methods: {
+ goJoin(i) {
+ let status = this.actSkuPrice[i].status === 'up' ? 'down' : 'up';
+ this.$set(this.actSkuPrice[i], 'status', status)
+ },
+ },
+
+ })
+ $(document).on("click", "#sorceSub", function () {
+ Layer.confirm('确认提交吗', {
+ btn: ['确认', '取消']
+ }, function () {
+ let isSubmit = true
+ isSubmit = !(vueSku.$data.actSkuPrice.every(function (item, index, array) {
+ return item.status == 'down';
+ }))
+ vueSku.$data.actSkuPrice.forEach(i => {
+ if (i.status == 'up' && !i.stock) {
+ isSubmit = false
+ }
+ if (i.status == 'up' && !i.price) {
+ isSubmit = false
+ }
+ if (i.status == 'up' && !i.score) {
+ isSubmit = false
+ }
+ })
+ if (isSubmit) {
+ let arr=[]
+ vueSku.$data.actSkuPrice.forEach(i=>{
+ if(i.status=="up"){
+ arr.push(i)
+ }
+ })
+ Fast.api.close(JSON.stringify(arr));
+ return true;
+ } else {
+ layer.msg('请把信息填写完整');
+ }
+ return true;
+ }, function () {
+ Layer.closeAll();
+ return false;
+ });
+ })
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ var vue = new Vue({
+ el: "#skuPrce",
+ data() {
+ return {
+ goodsList: Config.goodsList?Config.goodsList:[],
+ }
+ },
+ mounted() {
+ },
+ methods: {
+ selectDelete(i){
+ this.goodsList.splice(i,1)
+ }
+ },
+ watch:{
+ goodsList: {
+ handler: function (newVal) {
+ $("#goodsList").val(JSON.stringify(newVal))
+ },
+ deep: true
+ },
+ }
+
+ })
+ $(document).on("click", ".chooseGoods", function () {
+ var multiple = $(this).data("multiple") ? $(this).data("multiple") : false;
+ vue.$data.goodsList=[]
+ parent.Fast.api.open("shopro/goods/select?multiple="+multiple, "选择商品", {
+ callback: function (data) {
+ vue.$data.goodsList.push(data.data)
+ }
+ });
+ return false;
+ })
+ $(document).on("click", ".chooseIntegralPrice", function () {
+ var multiple = $(this).data("multiple") ? $(this).data("multiple") : false;
+ let id = $(this).attr("data-id")
+ let idx = $(this).attr("data-index")
+ let actSkuPrice = $(this).attr("data-actSkuPrice")
+ parent.Fast.api.open("shopro/app/score_shop/sku?goods_id=" + id + "&multiple=" + multiple + "&actSkuPrice=" + actSkuPrice, "设置活动商品", {
+ callback: function (data) {
+ vue.$set(vue.$data.goodsList[idx], "opt", 1)
+ vue.$set(vue.$data.goodsList[idx], "actSkuPrice", data)
+ }
+ });
+ return false;
+ })
+ $(document).on("click", "#scoreBtn", function () {
+ let subFlag = true;
+ let ordergoodslist = JSON.parse(JSON.stringify(vue.$data.goodsList))
+ ordergoodslist.forEach(i => {
+ if (i.actSkuPrice) {
+ let arr = []
+ JSON.parse(i.actSkuPrice).forEach(e => {
+ if (e.status == 'up') {
+ arr.push(e)
+ }
+ })
+ i.actSkuPrice = JSON.stringify(arr)
+ }
+ })
+ $("#selectScore").val(JSON.stringify(ordergoodslist))
+ if (subFlag) {
+ var that = this;
+ Layer.confirm('确认提交吗', {
+ btn: ['确认', '取消']
+ }, function () {
+ $(that).closest("form").trigger("submit");
+ Layer.closeAll();
+ return true;
+ }, function () {
+ Layer.closeAll();
+ return false;
+ });
+ }
+ });
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ },
+ select: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/goods/index',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ sortName: 'id',
+ showToggle: false,
+ showExport: false,
+ columns: [
+ [
+ {field: 'state', checkbox: true,},
+ {field: 'title', title: __('Title'), align: 'left'},
+ {field: 'image', title: __('Image'), operate: false, events: Table.api.events.image, formatter: Table.api.formatter.image},
+ {field: 'createtime', title: __('Createtime'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true},
+ {
+ field: 'operate', title: __('Operate'), events: {
+ 'click .btn-chooseone': function (e, value, row, index) {
+ var multiple = Backend.api.query('multiple');
+ multiple = multiple == 'true' ? true : false;
+ row.ids=row.id.toString()
+ Fast.api.close({data: row, multiple: multiple});
+ },
+ }, formatter: function () {
+ return '
' + __('Choose') + '';
+ }
+ }
+ ]
+ ]
+ });
+
+ // 选中多个
+ $(document).on("click", ".btn-choose-multi", function () {
+ var goodsIdArr = new Array();
+ $.each(table.bootstrapTable("getAllSelections"), function (i, j) {
+ goodsIdArr.push(j.id);
+ });
+ var multiple = Backend.api.query('multiple');
+ multiple = multiple == 'true' ? true : false;
+ let row={}
+ row.ids=couponsArr.join(",")
+ Fast.api.close({data: row, multiple: multiple});
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ //绑定TAB事件
+ $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
+ var typeStr = $(this).attr("href").replace('#', '');
+ var options = table.bootstrapTable('getOptions');
+ options.pageNumber = 1;
+ options.queryParams = function (params) {
+ params.type = typeStr;
+
+ return params;
+ };
+ table.bootstrapTable('refresh', {});
+ return false;
+
+ });
+ require(['upload'], function (Upload) {
+ Upload.api.plupload($("#toolbar .plupload"), function () {
+ $(".btn-refresh").trigger("click");
+ });
+ });
+
+ },
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/area.js b/public/assets/js/backend/shopro/area.js
new file mode 100644
index 000000000..dcd700fc7
--- /dev/null
+++ b/public/assets/js/backend/shopro/area.js
@@ -0,0 +1,232 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/area/index' + location.search,
+ add_url: 'shopro/area/add',
+ edit_url: 'shopro/area/edit',
+ del_url: 'shopro/area/del',
+ multi_url: 'shopro/area/multi',
+ table: 'shopro_area',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'name', title: __('Name')},
+ {field: 'pid', title: __('Pid')},
+ {field: 'level', title: __('Level')},
+ {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ area_select: function () {
+ var areaSelect = new Vue({
+ el: "#app",
+ data() {
+ return {
+ pcaData: Config.pca,
+ }
+ },
+ mounted() {
+ },
+ methods: {
+ selectAreaLeft(p, c, a) {
+ if (a === null && c === null) {
+ this.pcaData[p].flagRight = 1
+ this.pcaData[p].city.forEach(element => {
+ this.$set(element, "flagRight", '1')
+ element.area.forEach(item => {
+ this.$set(item, "flagRight", '1')
+
+ })
+
+ });
+ this.pcaData[p].flagLeft = 0
+ this.pcaData[p].city.forEach(element => {
+ this.$set(element, "flagLeft", '0')
+ element.area.forEach(item => {
+ this.$set(item, "flagLeft", '0')
+
+ })
+
+ });
+
+ }
+ if (a === null && c !== null) {
+ this.pcaData[p].flagRight = 1
+ this.pcaData[p].city[c].flagRight = 1
+ this.pcaData[p].city[c].flagLeft = 0
+ let num = 0;
+ this.pcaData[p].city.forEach(i => {
+ if (i.flagLeft == 1) {
+ num++
+ }
+ })
+ if (num == 0) {
+ this.pcaData[p].flagLeft = 0
+ }
+
+ this.pcaData[p].city[c].area.forEach(element => {
+ this.$set(element, "flagRight", '1')
+ });
+
+ }
+ if (a != null && c != null) {
+ this.pcaData[p].flagRight = 1
+ this.pcaData[p].city[c].flagRight = 1
+ this.pcaData[p].city[c].area[a].flagRight = 1
+ this.pcaData[p].city[c].area[a].flagLeft = 0
+ let num2 = 0;
+ this.pcaData[p].city[c].area.forEach(i => {
+ if (i.flagLeft == 1) {
+ num2++
+ }
+ })
+ if (num2 == 0) {
+ this.pcaData[p].city[c].flagLeft = 0
+ let num = 0;
+ this.pcaData[p].city.forEach(i => {
+ if (i.flagLeft == 1) {
+ num++
+ }
+ })
+ if (num == 0) {
+ this.pcaData[p].flagLeft = 0
+ }
+ }
+
+ }
+ },
+ showLeft(p, c, a) {
+ if (a === null && c === null) {
+ this.pcaData[p].city.forEach(element => {
+
+ this.$set(element, "showLeft",element.showLeft==1?0:1 )
+
+ });
+ }
+ if (a === null && c !== null) {
+ this.pcaData[p].city[c].area.forEach(element => {
+ this.$set(element, "showLeft", element.showLeft==1?0:1 )
+
+ });
+
+ }
+
+ },
+ selectAreaRight(p, c, a) {
+ if (a === null && c === null) {
+ this.pcaData[p].flagLeft = 1
+ this.pcaData[p].city.forEach(element => {
+ this.$set(element, "flagLeft", '1')
+ element.area.forEach(item => {
+ this.$set(item, "flagLeft", '1')
+
+ })
+
+ });
+ this.pcaData[p].flagRight = 0
+ this.pcaData[p].city.forEach(element => {
+ this.$set(element, "flagRight ", '0')
+ element.area.forEach(item => {
+ this.$set(item, "flagRight ", '0')
+
+ })
+
+ });
+
+ }
+ if (a === null && c !== null) {
+ this.pcaData[p].flagLeft = 1
+ this.pcaData[p].city[c].flagLeft = 1
+ this.pcaData[p].city[c].flagRight = 0
+ let num = 0;
+ this.pcaData[p].city.forEach(i => {
+ if (i.flagRight == 1) {
+ num++
+ }
+ })
+ if (num == 0) {
+ this.pcaData[p].flagRight = 0
+ }
+
+ this.pcaData[p].city[c].area.forEach(element => {
+ this.$set(element, "flagLeft", '1')
+ });
+
+ }
+ if (a != null && c != null) {
+ this.pcaData[p].flagLeft = 1
+ this.pcaData[p].city[c].flagLeft = 1
+ this.pcaData[p].city[c].area[a].flagLeft = 1
+ this.pcaData[p].city[c].area[a].flagRight = 0
+ let num2 = 0;
+ this.pcaData[p].city[c].area.forEach(i => {
+ if (i.flagRight == 1) {
+ num2++
+ }
+ })
+ if (num2 == 0) {
+ this.pcaData[p].city[c].flagRight = 0
+ let num = 0;
+ this.pcaData[p].city.forEach(i => {
+ if (i.flagRight == 1) {
+ num++
+ }
+ })
+ if (num == 0) {
+ this.pcaData[p].flagRight = 0
+ }
+ }
+
+ }
+ },
+ showRight(p, c, a) {
+ if (a === null && c === null) {
+ this.pcaData[p].city.forEach(element => {
+ this.$set(element, "showRight", element.showRight==1?0:1 )
+
+ });
+
+ }
+ if (a === null && c !== null) {
+ this.pcaData[p].city[c].area.forEach(element => {
+ this.$set(element, "showRight", element.showRight==1?0:1 )
+
+ });
+ }
+ },
+ },
+ })
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/category.js b/public/assets/js/backend/shopro/category.js
new file mode 100644
index 000000000..297eb28f3
--- /dev/null
+++ b/public/assets/js/backend/shopro/category.js
@@ -0,0 +1,227 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/category/index',
+ add_url: 'shopro/category/add',
+ edit_url: 'shopro/category/edit',
+ del_url: 'shopro/category/del',
+ multi_url: 'shopro/category/multi',
+ dragsort_url: 'ajax/weigh',
+ table: 'shopro_category',
+ }
+ });
+
+ var table = $("#table");
+ var tableOptions = {
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ escape: false,
+ pk: 'id',
+ sortName: 'weigh',
+ pagination: false,
+ commonSearch: false,
+ search: false,
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'type', title: __('Type'), operate: false, searchList: Config.searchList, formatter: Table.api.formatter.normal},
+ {field: 'name', title: __('Name'), align: 'left'},
+ {field: 'image', title: __('Image'), operate: false, events: Table.api.events.image, formatter: Table.api.formatter.image},
+ {field: 'weigh', title: __('Weigh')},
+ {field: 'status', title: __('Status'), operate: false, formatter: Table.api.formatter.status},
+ {
+ field: 'id',
+ title: '
',
+ operate: false,
+ formatter: Controller.api.formatter.subnode
+ },
+ {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
+ ]
+ ]
+ };
+ // 初始化表格
+ table.bootstrapTable(tableOptions);
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+
+ //绑定TAB事件
+ $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
+ var typeStr = $(this).attr("href").replace('#', '');
+ var options = table.bootstrapTable('getOptions');
+ options.pageNumber = 1;
+ options.queryParams = function (params) {
+ params.type = typeStr;
+
+ return params;
+ };
+ table.bootstrapTable('refresh', {});
+ return false;
+
+ });
+
+
+
+ // 递归遍历所有子节点切换状态
+ function toggle(obj, status) {
+ // 切换当前元素状态
+ $(obj).closest("tr").toggle(!status);
+
+ var hasChild = $(obj).data('haschild');
+ if (hasChild) {
+ $(obj).parents("tr").nextAll().find("a.btn[data-pid='" + $(obj).data('id') + "']").each(function () {
+ toggle(this, status)
+ })
+ }
+ }
+
+ table.on('post-body.bs.table', function (e, settings, json, xhr) {
+ //显示隐藏子节点
+ $(".btn-node-sub").off("click").on("click", function (e) {
+ var shown = $(this).data("shown");
+ if (shown != undefined) {
+ var status = $(this).data("shown") ? true : false;
+ } else {
+ var status = true;
+ }
+
+ // 在当前节点记录状态
+ $(this).data("shown", !status);
+
+ $(this).parents('tr').nextAll().find("a.btn[data-pid='" + $(this).data('id') + "']").each(function() {
+ toggle(this, status)
+ })
+ });
+
+
+ // 全部展开合并
+ $(".btn-toggle").off("click").on("click", function (e) {
+ var shown = $(this).data("shown");
+ if (shown != undefined) {
+ var status = $(this).data("shown") ? true : false;
+ } else {
+ var status = true;
+ }
+
+ // 在当前节点记录状态
+ $(this).data("shown", !status);
+
+ // 全部切换
+ $("a.btn-node-sub").each(function () {
+ $(this).closest("tr").toggle(!status);
+ });
+
+ // 顶级一直是 true
+ $("a.btn[data-pid=0]").each(function () {
+ $(this).closest("tr").toggle(true);
+ });
+ });
+ });
+ },
+ select: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/category/select',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ escape: false,
+ search: false,
+ sortName: 'id',
+ showToggle: false,
+ showExport: false,
+ columns: [
+ [
+ {field: 'state', checkbox: true,},
+ {field: 'type', title: __('Type'), operate: false, searchList: Config.searchList, formatter: Table.api.formatter.normal},
+ {field: 'name', title: __('Name'), align: 'left'},
+ {field: 'image', title: __('Image'), operate: false, events: Table.api.events.image, formatter: Table.api.formatter.image},
+ {field: 'createtime', title: __('Createtime'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true},
+ {
+ field: 'operate', title: __('Operate'), events: {
+ 'click .btn-chooseone': function (e, value, row, index) {
+ var multiple = Backend.api.query('multiple');
+ multiple = multiple == 'true' ? true : false;
+ Fast.api.close({data: row, multiple: multiple});
+ },
+ }, formatter: function () {
+ return '
' + __('Choose') + '';
+ }
+ }
+ ]
+ ]
+ });
+
+ // 选中多个
+ $(document).on("click", ".btn-choose-multi", function () {
+ var urlArr = new Array();
+ $.each(table.bootstrapTable("getAllSelections"), function (i, j) {
+ urlArr.push(j.url);
+ });
+ var multiple = Backend.api.query('multiple');
+ multiple = multiple == 'true' ? true : false;
+ Fast.api.close({url: urlArr.join(","), multiple: multiple});
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ //绑定TAB事件
+ $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
+ var typeStr = $(this).attr("href").replace('#', '');
+ var options = table.bootstrapTable('getOptions');
+ options.pageNumber = 1;
+ options.queryParams = function (params) {
+ params.type = typeStr;
+
+ return params;
+ };
+ table.bootstrapTable('refresh', {});
+ return false;
+
+ });
+ require(['upload'], function (Upload) {
+ Upload.api.plupload($("#toolbar .plupload"), function () {
+ $(".btn-refresh").trigger("click");
+ });
+ });
+
+ },
+ add: function () {
+ Controller.api.bindevent();
+ setTimeout(function () {
+ $("#c-type").trigger("change");
+ }, 100);
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ formatter: {
+ subnode: function (value, row, index) {
+ return '
';
+ }
+ },
+ bindevent: function () {
+ $(document).on("change", "#c-type", function () {
+ $("#c-pid option[data-type='all']").prop("selected", true);
+ $("#c-pid option").removeClass("hide");
+ $("#c-pid option[data-type!='" + $(this).val() + "'][data-type!='all']").addClass("hide");
+ $("#c-pid").data("selectpicker") && $("#c-pid").selectpicker("refresh");
+ });
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/config.js b/public/assets/js/backend/shopro/config.js
new file mode 100644
index 000000000..e1297fc14
--- /dev/null
+++ b/public/assets/js/backend/shopro/config.js
@@ -0,0 +1,139 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/config/index',
+ add_url: 'shopro/config/add',
+ edit_url: 'shopro/config/edit',
+ del_url: 'shopro/config/del',
+ multi_url: 'shopro/config/multi',
+ table: 'config',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {field: 'state', checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'name', title: __('Name')},
+ {field: 'intro', title: __('Intro')},
+ {field: 'group', title: __('Group')},
+ {field: 'type', title: __('Type')},
+ {
+ field: 'operate',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+
+ $("form.edit-form").data("validator-options", {
+ display: function (elem) {
+ return $(elem).closest('tr').find("td:first").text();
+ }
+ });
+ Form.api.bindevent($("form.edit-form"));
+
+ //不可见的元素不验证
+ $("form#add-form").data("validator-options", {
+ ignore: ':hidden',
+ rules: {
+ content: function () {
+ return ['radio', 'checkbox', 'select', 'selects'].indexOf($("#add-form select[name='row[type]']").val()) > -1;
+ },
+ extend: function () {
+ return $("#add-form select[name='row[type]']").val() == 'custom';
+ }
+ }
+ });
+ Form.api.bindevent($("form#add-form"), function (ret) {
+ setTimeout(function () {
+ location.reload();
+ }, 1500);
+ });
+
+ //切换显示隐藏变量字典列表
+ $(document).on("change", "form#add-form select[name='row[type]']", function (e) {
+ $("#add-content-container").toggleClass("hide", ['select', 'selects', 'checkbox', 'radio'].indexOf($(this).val()) > -1 ? false : true);
+ });
+
+ //选择规则
+ $(document).on("click", ".rulelist > li > a", function () {
+ var ruleArr = $("#rule").val() == '' ? [] : $("#rule").val().split(";");
+ var rule = $(this).data("value");
+ var index = ruleArr.indexOf(rule);
+ if (index > -1) {
+ ruleArr.splice(index, 1);
+ } else {
+ ruleArr.push(rule);
+ }
+ $("#rule").val(ruleArr.join(";"));
+ $(this).parent().toggleClass("active");
+ });
+
+ //添加向发件人发送测试邮件按钮和方法
+ $('input[name="row[mail_from]"]').parent().next().append('
' + __('Send a test message') + ' ');
+ $(document).on("click", ".testmail", function () {
+ var that = this;
+ Layer.prompt({title: __('Please input your email'), formType: 0}, function (value, index) {
+ Backend.api.ajax({
+ url: "shopro/config/emailtest",
+ data: $(that).closest("form").serialize() + "&receiver=" + value
+ });
+ });
+
+ });
+
+ //删除配置
+ $(document).on("click", ".btn-delcfg", function () {
+ var that = this;
+ Layer.confirm(__('Are you sure you want to delete this item?'), {
+ icon: 3,
+ title: '提示'
+ }, function (index) {
+ Backend.api.ajax({
+ url: "shopro/config/del",
+ data: {name: $(that).data("name")}
+ }, function () {
+ $(that).closest("tr").remove();
+ Layer.close(index);
+ });
+ });
+
+ });
+ $("#wxClick").click(function(){
+ })
+ },
+ platform: function () {
+ Controller.api.bindevent();
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/coupons.js b/public/assets/js/backend/shopro/coupons.js
new file mode 100644
index 000000000..e52efb11f
--- /dev/null
+++ b/public/assets/js/backend/shopro/coupons.js
@@ -0,0 +1,208 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/coupons/index' + location.search,
+ add_url: 'shopro/coupons/add',
+ edit_url: 'shopro/coupons/edit',
+ del_url: 'shopro/coupons/del',
+ multi_url: 'shopro/coupons/multi',
+ table: 'shopro_coupons',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'name', title: __('Name')},
+ {field: 'goods_ids', title: __('Goods_ids')},
+ {field: 'amount', title: __('Amount'), operate:'BETWEEN'},
+ {field: 'enough', title: __('Enough'), operate:'BETWEEN'},
+ {field: 'stock', title: __('Stock')},
+ {field: 'limit', title: __('Limit')},
+ {field: 'gettime', title: __('Gettime')},
+ {field: 'usetime', title: __('Usetime')},
+ {field: 'description', title: __('Description')},
+ {field: 'createtime', title: __('Createtime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
+ ]
+ ]
+ });
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ recyclebin: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ 'dragsort_url': ''
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: 'shopro/coupons/recyclebin' + location.search,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'name', title: __('Name'), align: 'left'},
+ {
+ field: 'deletetime',
+ title: __('Deletetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'operate',
+ width: '130px',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ buttons: [
+ {
+ name: 'Restore',
+ text: __('Restore'),
+ classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
+ icon: 'fa fa-rotate-left',
+ url: 'shopro/coupons/restore',
+ refresh: true
+ },
+ {
+ name: 'Destroy',
+ text: __('Destroy'),
+ classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
+ icon: 'fa fa-times',
+ url: 'shopro/coupons/destroy',
+ refresh: true
+ }
+ ],
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ select: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/coupons/select',
+ }
+ });
+
+ var idArr = [];
+ var table = $("#table");
+
+ table.on('check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table', function (e, row) {
+ if (e.type == 'check' || e.type == 'uncheck') {
+ row = [row];
+ } else {
+ idArr = [];
+ }
+ $.each(row, function (i, j) {
+ if (e.type.indexOf("uncheck") > -1) {
+ var index = idArr.indexOf(j.id);
+ if (index > -1) {
+ idArr.splice(index, 1);
+ }
+ } else {
+ idArr.indexOf(j.id) == -1 && idArr.push(j.id);
+ }
+ });
+ });
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ showToggle: false,
+ showExport: false,
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'name', title: __('Name')},
+ {field: 'goods_ids', title: __('Goods_ids')},
+ {field: 'amount', title: __('Amount'), operate:'BETWEEN'},
+ {field: 'enough', title: __('Enough'), operate:'BETWEEN'},
+ {field: 'stock', title: __('Stock')},
+ {field: 'limit', title: __('Limit')},
+ {field: 'gettime', title: __('Gettime')},
+ {field: 'usetime', title: __('Usetime')},
+ {field: 'description', title: __('Description')},
+ {field: 'createtime', title: __('Createtime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {
+ field: 'operate', title: __('Operate'), events: {
+ 'click .btn-chooseone': function (e, value, row, index) {
+ var multiple = Backend.api.query('multiple');
+ multiple = multiple == 'true' ? true : false;
+ row.ids=row.id.toString()
+ Fast.api.close({data: row, multiple: multiple});
+ },
+ }, formatter: function () {
+ return '
' + __('Choose') + '';
+ }
+ }
+ ]
+ ]
+ });
+
+ // 选中多个
+ $(document).on("click", ".btn-choose-multi", function () {
+ // var couponsArr = new Array();
+ // $.each(table.bootstrapTable("getAllSelections"), function (i, j) {
+ // couponsArr.push(j.id);
+ // });
+ var multiple = Backend.api.query('multiple');
+ multiple = multiple == 'true' ? true : false;
+ let row={}
+ row.ids=idArr.join(",")
+ Fast.api.close({data: row, multiple: multiple});
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ require(['upload'], function (Upload) {
+ Upload.api.plupload($("#toolbar .plupload"), function () {
+ $(".btn-refresh").trigger("click");
+ });
+ });
+
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/dashboard.js b/public/assets/js/backend/shopro/dashboard.js
new file mode 100644
index 000000000..67f2d2459
--- /dev/null
+++ b/public/assets/js/backend/shopro/dashboard.js
@@ -0,0 +1,814 @@
+requirejs.config({
+ paths: {
+ // vue: "/assets/addons/shopro/libs/vue",
+ g2: "/assets/addons/shopro/libs/antv"
+ }
+})
+define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'g2'], function ($, undefined, Backend, Table, Form, G2) {
+
+ var Controller = {
+ index: function () {
+ var vueChart = new Vue({
+ el: "#antv-con",
+ data() {
+ return {
+ orderList: [],
+ chartsData: [],
+ dataList: [{
+ title: '支付订单',
+ num: 0,
+ checked: true,
+ id: 1,
+ color: '#F0A70A',
+ back: '#FEF6DE',
+ unit: '笔'
+ }, {
+ title: '支付金额',
+ num: 0,
+ checked: true,
+ id: 5,
+ color: '#4498FF',
+ back: '#E4F0FF',
+ unit: '元'
+ }, {
+ title: '待发货订单',
+ num: 0,
+ checked: false,
+ id: 2,
+ color: '#38C769',
+ back: '#E2F7E9',
+ unit: '笔'
+ }, {
+ title: '下单人数',
+ num: 0,
+ checked: false,
+ id: 6,
+ color: '#B052EA',
+ back: '#F6E9FE',
+ unit: '人'
+ },
+ {
+ title: '售后维权',
+ num: 0,
+ checked: false,
+ id: 3,
+ color: '#627EFC',
+ back: '#EBEEFE',
+ unit: '笔'
+ },
+ {
+ title: '退款订单',
+ num: 0,
+ checked: false,
+ id: 4,
+ color: '#FF826C',
+ back: '#FFEDEB',
+ unit: '笔'
+ }],
+ selectInputs: [],
+ dropdownList: [{
+ date: 'yesterday',
+ name: '昨日'
+ }, {
+ date: 'today',
+ name: '今日'
+ }, {
+ date: 'week',
+ name: '近一周'
+ }, {
+ date: 'month',
+ name: '近一月'
+ }, {
+ date: 'year',
+ name: '近一年'
+ }],
+ dropdownName: '今日',
+ dropdownDate: 'today',
+ searchTime: [new Date(), new Date()],
+ ringRightData: [
+ { item: '微信支付', count: 0, percent: 0 },
+ { item: '支付宝支付', count: 0, percent: 0 },
+ { item: '钱包支付', count: 0, percent: 0 },
+ { item: '其他', count: 0, percent: 0 }
+ ],
+ tableData: [],
+ value2: [new Date(), new Date()],
+ //环图总数
+ allOrderNum: 0,
+ //成交比例
+ tranPeople: 0,
+ tranPeoplescale: 0,
+ //支付比例
+ allOrderPayNum: 0,
+ transcale: 0,
+ orderFinish: {},
+ payedFinish: {},
+ loading: true
+
+
+
+ }
+ },
+ mounted() {
+ //请求数据
+ this.changeTime();
+ },
+ methods: {
+ //折线
+ charts() {
+ $("#main-chart").empty()
+ const chart = new G2.Chart({
+ container: 'main-chart',
+ autoFit: true,
+ height: 360,
+ animate: true,
+ });
+ chart.data(this.chartsData);
+ var dataBoxNum = 0
+ this.selectInputs.forEach(e => {
+ if (e.checked) {
+ dataBoxNum++
+ }
+ })
+ if (dataBoxNum == 1) {
+ let title
+ this.selectInputs.forEach(i => {
+ if (i.checked) {
+ title = i.title
+ }
+ })
+ chart.scale({
+ date: {
+ alias: ' ',
+ },
+ y2: {
+ alias: title,
+ min: 0,
+ sync: true,
+ nice: true,
+ },
+ });
+ chart
+ .area()
+ .position('date*y2')
+ .color(this.selectInputs[0].color).tooltip(false).shape('smooth');
+ chart
+ .line()
+ .position('date*y2')
+ .color(this.selectInputs[0].color).shape('smooth');
+ } else if (dataBoxNum == 2) {
+ chart.scale({
+ date: {
+ alias: ' ',
+ },
+ y2: {
+ alias: this.selectInputs[1].title,
+ sync: true,
+ nice: true,
+ min: 0
+ },
+ y1: {
+ alias: this.selectInputs[0].title,
+ sync: true,
+ nice: true,
+ min: 0
+ },
+ });
+
+ chart
+ .area()
+ .position('date*y1')
+ .color(this.selectInputs[0].color).tooltip(false).shape('smooth');
+ chart
+ .line()
+ .position('date*y1')
+ .color(this.selectInputs[0].color).shape('smooth');
+ chart
+ .area()
+ .position('date*y2')
+ .color(this.selectInputs[1].color).tooltip(false).shape('smooth');
+ chart
+ .line()
+ .position('date*y2')
+ .color(this.selectInputs[1].color).shape('smooth');
+
+ } else {
+ return false
+ }
+ var margin = 1 / this.chartsData.length;
+ chart.axis('date', {
+ range: [margin / 4, 1 - margin / 4]
+
+ });
+ chart.axis('y1', {
+ grid: null,
+ title: {},
+ });
+ chart.axis('y2', {
+ title: {},
+ });
+
+ chart.tooltip({
+ showCrosshairs: true, //展示辅助线
+ shared: true,
+ });
+ chart.render();
+ },
+ //选择显示数据
+ selectLine(idx) {
+ this.dataList[idx].checked = !this.dataList[idx].checked
+ if (this.dataList[idx].checked == true) {
+ this.selectInputs.push(this.dataList[idx]);
+ if (this.selectInputs.length > 2) {
+ this.selectInputs[0].checked = false;
+ this.selectInputs.shift();
+ }
+ } else {
+ this.selectInputs.forEach((item, index) => {
+ if (this.dataList[idx].id == item.id)
+ this.selectInputs.splice(index, 1);
+ })
+ }
+ this.countOrderData()
+ // this.charts()
+ },
+ //环图
+ ringRight() {
+ var that=this;
+ $("#ring-right").empty()
+ const chart = new G2.Chart({
+ container: 'ring-right',
+ autoFit: true,
+ height: 300,
+ width: 260,
+ padding: [0, 0, 50, 0]
+ });
+ chart.data(this.ringRightData);
+ chart.scale('percent', {
+ formatter: (val) => {
+ val = val * 100 + '%';
+ return val;
+ },
+ });
+ chart.coordinate('theta', {
+ radius: 0.85,
+ innerRadius: 0.8,
+ });
+ chart.tooltip({
+ showTitle: false,
+ showMarkers: false,
+ itemTpl: '
{name}: {value}({count})',
+ });
+ // 辅助文本
+ chart
+ .annotation()
+ .text({
+ position: ['50%', '50%'],
+ content: this.allOrderNum,
+ style: {
+ fontSize: 36,
+ fill: '#753ECD',
+ textAlign: 'center',
+ },
+ offsetX: -10,
+ offsetY: -20,
+ })
+ .text({
+ position: ['50%', '50%'],
+ content: '笔',
+ style: {
+ fontSize: 16,
+ fill: '#753ECD',
+ textAlign: 'center',
+ },
+ offsetY: -20,
+ offsetX: 30,
+ })
+ .text({
+ position: ['50%', '50%'],
+ content: '支付单数',
+ style: {
+ fontSize: 16,
+ fill: '#753ECD',
+ textAlign: 'center',
+ },
+ offsetY: 20,
+ });
+ chart
+ .interval()
+ .adjust('stack')
+ .position('percent')
+ .color('item', ['#38C769', '#627EFC', '#FF826C', '#F7B500'])
+ .tooltip('item*percent', (item, percent) => {
+ let counts=Math.round(that.allOrderNum*percent)
+ percent = percent * 100 + '%';
+ return {
+ name: item,
+ value: percent,
+ count:counts
+ };
+ });
+
+ chart.render();
+ },
+ //表格
+ tableRowClassName({ row, rowIndex }) {
+ if (rowIndex % 2 == 0) {
+ return 'gray-row';
+ }
+ return '';
+ },
+ //选择时间段
+ changeTime(index = 1) {
+ this.dropdownDate = this.dropdownList[index].date;
+ this.dropdownName = this.dropdownList[index].name;
+ this.searchTime = this.getTimeSlot();
+ this.getDataInfo();
+ },
+ //选择请求数据
+ getDataInfo() {
+ this.loading = true
+ let that = this
+ let timeSlot = moment(that.searchTime[0]).format("YYYY-MM-DD HH:mm:ss") + ' - ' + moment(that.searchTime[1]).format("YYYY-MM-DD HH:mm:ss");
+ Fast.api.ajax({
+ url: 'shopro/dashboard/index',
+ loading: false,
+ data: {
+ datetimerange: timeSlot
+ },
+ success: function (res, ret) {
+ that.tableData = res.data.goodsList;
+ that.orderList = res.data.orderList;
+ that.orderFinish = res.data.orderFinish
+ that.payedFinish = res.data.payedFinish
+ // 支付订单
+ let payOrderNum = 0
+ let payOrderArr = []
+ //支付金额
+ let payAmountNum = 0
+ let payAmountArr = []
+ // 代发货
+ let noSentNum = 0
+ let noSentArr = []
+ //下单人数
+ let orderNum = that.orderList.length
+ let orderArr = []
+ //售后维权
+ let aftersaleNum = 0
+ let aftersaleArr = []
+ //退款订单
+ let refundNum = 0
+ let refundArr = []
+ //所有下单金额
+ let totalAmount = 0
+ //
+ let tranPeople = 0
+
+ //微信支付
+ let wechatPay = 0
+ //支付宝支付
+ let alipayPay = 0
+ //余额支付
+ let walletPay = 0
+ //所有的支付
+ let allTypePay = 0
+ that.orderList.forEach(e => {
+ orderArr.push({ counter: 1, paytime: e.paytime * 1000, user_id: e.user_id })
+ totalAmount += Number(e.total_amount)
+ if (e.status > 0) {
+ payOrderNum++
+ payOrderArr.push({ counter: 1, paytime: e.paytime * 1000 })
+
+ payAmountNum += Number(e.total_amount)
+ payAmountArr.push({ counter: e.total_amount, paytime: e.paytime * 1000 })
+
+ tranPeople++
+
+ e.item.forEach(i => {
+ if (i.dispatch_status == 0) {
+ noSentNum++
+ noSentArr.push({ counter: 1, paytime: e.paytime * 1000 })
+ }
+ if (i.aftersale_status > 0) {
+ aftersaleNum++
+ aftersaleArr.push({ counter: 1, paytime: e.paytime * 1000 })
+ }
+ if (i.refund_status > 0) {
+ refundNum++
+ refundArr.push({ counter: 1, paytime: e.paytime * 1000 })
+ }
+ })
+ allTypePay++
+ if (e.pay_type == 'wechat') {
+ wechatPay++
+ }
+ if (e.pay_type == 'alipay') {
+ alipayPay++
+ }
+ if (e.pay_type == 'wallet') {
+ walletPay++
+ }
+ }
+ })
+
+ that.dataList[0].num = payOrderNum
+ that.dataList[0].item = payOrderArr
+ that.dataList[1].num = payAmountNum.toFixed(2)
+ that.dataList[1].item = payAmountArr
+ that.dataList[2].num = noSentNum
+ that.dataList[2].item = noSentArr
+ const resorderArr = new Map();
+ const neworderArr = orderArr.reverse().filter(item => !resorderArr.has(item.user_id) && resorderArr.set(item.user_id, 1));
+ that.dataList[3].num = neworderArr.length
+ that.dataList[3].item = neworderArr
+ that.dataList[4].num = aftersaleNum
+ that.dataList[4].item = aftersaleArr
+ that.dataList[5].num = refundNum
+ that.dataList[5].item = refundArr
+
+ that.allOrderNum = allTypePay
+ that.ringRightData[0].count = wechatPay
+ that.ringRightData[0].percent = that.scaleFunc(wechatPay, allTypePay)
+ that.ringRightData[1].count = alipayPay
+ that.ringRightData[1].percent = that.scaleFunc(alipayPay, allTypePay)
+ that.ringRightData[2].count = walletPay
+ that.ringRightData[2].percent = that.scaleFunc(walletPay, allTypePay)
+ that.ringRightData[3].count = allTypePay - wechatPay - alipayPay - walletPay
+ that.ringRightData[3].percent = that.scaleFunc(that.ringRightData[3].count, allTypePay)
+ that.ringRight()
+ //成交比例
+ that.tranPeople = tranPeople
+ that.tranPeoplescale = that.scaleFunc(tranPeople, that.orderList.length) * 100
+ //支付比例
+ that.allOrderPayNum = payAmountNum
+ that.transcale = that.scaleFunc(payAmountNum, totalAmount) * 100
+ //判断是否选中
+ that.selectInputs = []
+ that.dataList.forEach((item, index) => {
+ if (item.checked == true) that.selectInputs.push(item);
+ })
+ // 请求数据
+ that.countOrderData();
+ }
+ })
+ },
+
+ countOrderData() {
+ let that = this;
+ let orderList = JSON.parse(JSON.stringify(that.orderList));
+ let time = (
+ new Date(moment(that.searchTime[1]).format("YYYY-MM-DD HH:mm:ss").replace(/-/g, "/")).getTime() - new Date(moment(that.searchTime[0]).format("YYYY-MM-DD HH:mm:ss").replace(/-/g, "/")).getTime()
+ ) / 1000 + 1;
+ let kld = '';
+ let interval = 0;
+ if (time <= 60 * 60) {
+ interval = parseInt(time / 60);
+
+ kld = 'minutes';
+ } else if (time <= 60 * 60 * 24) {
+ interval = parseInt(time / (60 * 60));
+
+ kld = 'hours';
+ } else if (time <= 60 * 60 * 24 * 30 * 1.5) {
+ interval = parseInt(time / (60 * 60 * 24));
+
+ kld = 'days';
+
+ } else if (time < 60 * 60 * 24 * 30 * 24) {
+ interval = parseInt(time / (60 * 60 * 24 * 30));
+
+ kld = 'months';
+
+ } else if (time >= 60 * 60 * 24 * 30 * 24) {
+ interval = parseInt(time / (60 * 60 * 24 * 30 * 12));
+
+ kld = 'years';
+
+ }
+ this.drawX(interval, kld);
+
+ },
+ drawX(interval, kld) {
+ let that = this
+ let x = [];
+ let selectInputLeng = 0
+ this.selectInputs.forEach(e => {
+ if (e.checked) {
+ selectInputLeng++
+ }
+ })
+ if (selectInputLeng == 1) {
+ for (let i = 0; i <= interval; i++) {
+ if (kld == 'minutes' || kld == 'hours') {
+ x.push({
+ date: moment(that.searchTime[0]).add(i, kld).format("DD HH:mm"),
+ timeStamp: moment(that.searchTime[0]).add(i, kld).valueOf(),
+ y2: 0
+ });
+ } else if (kld == 'days') {
+ x.push({
+ date: moment(that.searchTime[0]).add(i, kld).format("YYYY-MM-DD"),
+ timeStamp: moment(that.searchTime[0]).add(i, kld).valueOf(),
+ y2: 0,
+ y1: 0
+ });
+ } else if (kld == 'months') {
+ x.push({
+ date: moment(that.searchTime[0]).add(i, kld).format("YYYY-MM"),
+ timeStamp: moment(that.searchTime[0]).add(i, kld).valueOf(),
+ y2: 0,
+ y1: 0
+ });
+ } else {
+ x.push({
+ date: moment(that.searchTime[0]).add(i, kld).format("YYYY"),
+ timeStamp: moment(that.searchTime[0]).add(i, kld).valueOf(),
+ y2: 0
+ });
+ }
+ }
+ let flag3 = false
+ for (var y = 0; y < x.length; y++) {
+ let y2 = 0
+ let selectItem = []
+ let id = 0
+ this.selectInputs.forEach(element => {
+ if (element.checked == true) {
+ selectItem = element.item
+ id = element.id
+ }
+ })
+ if (id == 6) {
+ selectItem.forEach(se => {
+ if (flag3) {
+ if (se.paytime > x[0].timeStamp) {
+ y2 += Number(se.counter)
+ }
+ } else {
+ if (se.paytime > x[y].timeStamp && se.paytime <= x[y + 1].timeStamp) {
+ flag3 = true
+ y2 += Number(se.counter)
+ }
+ }
+ })
+ } else {
+ selectItem.forEach(se => {
+ if (y != x.length - 1) {
+ if (se.paytime > x[y].timeStamp && se.paytime <= x[y + 1].timeStamp) {
+ y2 += Number(se.counter)
+ }
+ } else {
+ if (se.paytime > x[y].timeStamp) {
+ y2 += Number(se.counter)
+ }
+ }
+
+ })
+ if(id==5){
+ if(y2>0){
+ y2 =parseFloat(y2.toFixed(2))
+ }
+ }
+ }
+
+ x[y].y2 = y2
+ }
+ }
+ if (selectInputLeng == 2) {
+ for (let i = 0; i <= interval; i++) {
+ if (kld == 'minutes' || kld == 'hours') {
+ x.push({
+ date: moment(that.searchTime[0]).add(i, kld).format("DD HH:mm"),
+ timeStamp: moment(that.searchTime[0]).add(i, kld).valueOf(),
+ y2: 0,
+ y1: 0
+ });
+ } else if (kld == 'days') {
+ x.push({
+ date: moment(that.searchTime[0]).add(i, kld).format("YYYY-MM-DD"),
+ timeStamp: moment(that.searchTime[0]).add(i, kld).valueOf(),
+ y2: 0,
+ y1: 0
+ });
+ } else if (kld == 'months') {
+ x.push({
+ date: moment(that.searchTime[0]).add(i, kld).format("YYYY-MM"),
+ timeStamp: moment(that.searchTime[0]).add(i, kld).valueOf(),
+ y2: 0,
+ y1: 0
+ });
+ } else {
+ x.push({
+ date: moment(that.searchTime[0]).add(i, kld).format("YYYY"),
+ timeStamp: moment(that.searchTime[0]).add(i, kld).valueOf(),
+ y2: 0,
+ y1: 0
+ });
+ }
+ }
+ let flag1 = false
+ let flag2 = false
+ for (var y = 0; y < x.length; y++) {
+ let y1 = 0
+ let y2 = 0
+ if (this.selectInputs[0].id == 6) {
+ this.selectInputs[0].item.forEach(se => {
+ if (flag1) {
+ if (se.paytime > x[0].timeStamp) {
+ y1 += Number(se.counter)
+ }
+ } else {
+ if (se.paytime > x[y].timeStamp && se.paytime <= x[y + 1].timeStamp) {
+ flag1 = true
+ y1 += Number(se.counter)
+ }
+ }
+ })
+
+ } else {
+ this.selectInputs[0].item.forEach(se => {
+ if (y != x.length - 1) {
+ if (se.paytime > x[y].timeStamp && se.paytime <= x[y + 1].timeStamp) {
+ y1 += Number(se.counter)
+ }
+ } else {
+ if (se.paytime > x[y].timeStamp) {
+ y1 += Number(se.counter)
+ }
+ }
+ })
+ if(this.selectInputs[0].id == 5){
+ if(y1>0){
+ y1 =parseFloat(y1.toFixed(2))
+ }
+ }
+ }
+ if (this.selectInputs[1].id == 6) {
+ this.selectInputs[1].item.forEach(se => {
+ if (flag2) {
+ if (se.paytime > x[0].timeStamp) {
+ y2 += Number(se.counter)
+ }
+ } else {
+ if (se.paytime > x[y].timeStamp && se.paytime <= x[y + 1].timeStamp) {
+ flag2 = true
+ y2 += Number(se.counter)
+ }
+ }
+ })
+ } else {
+ this.selectInputs[1].item.forEach(se => {
+ if (y != x.length - 1) {
+ if (se.paytime > x[y].timeStamp && se.paytime <= x[y + 1].timeStamp) {
+ y2 += Number(se.counter)
+ }
+ } else {
+ if (se.paytime > x[y].timeStamp) {
+ y2 += Number(se.counter)
+ }
+ }
+ })
+ if(this.selectInputs[1].id == 5){
+ if(y2>0){
+ y2 =parseFloat(y2.toFixed(2))
+ }
+
+ }
+ }
+ x[y].y1 = y1
+ x[y].y2 = y2
+ }
+ }
+ that.chartsData = x
+ that.loading = false
+ that.charts()
+ },
+ //获取时间
+ getTimeSlot() {
+
+ let beginTime = '';
+ let endTime = moment().format('YYYY-MM-DD');
+ switch (this.dropdownDate) {
+ case 'yesterday':
+ endTime = moment().subtract(1, 'days').format('YYYY-MM-DD')
+ beginTime = endTime
+ break;
+ case 'today':
+ beginTime = endTime;
+ break;
+ case 'week':
+ beginTime = moment().subtract(1, 'weeks').format('YYYY-MM-DD')
+ break;
+ case 'month':
+ beginTime = moment().subtract(1, 'months').format('YYYY-MM-DD')
+ break;
+ case 'year':
+ beginTime = moment().subtract(1, 'years').format('YYYY-MM-DD')
+ break;
+ }
+ let timeSlot = [beginTime + ' 00:00:00', endTime + ' 23:59:59'];
+ return timeSlot;
+ },
+ goDetail(id) {
+ let that = this;
+ let status = ''
+ switch (id) {
+ case 1:
+ status = 'payed'
+ break;
+ case 2:
+ status = 'nosend'
+ break;
+ case 3:
+ status = 'aftersale'
+ break;
+ case 4:
+ status = 'refund'
+ break;
+ }
+ let times = encodeURI(that.searchTime.join(" - "))
+ parent.Fast.api.open("shopro/order/order/index?status=" + status + "&datetimerange=" + times, "查看详情", { callback: function (data) { } });
+ return false;
+ },
+ scaleFunc(a, b) {
+ return (a <= 0 ? 0 : a / b).toFixed(2) - 0
+ }
+ },
+ })
+ },
+ recyclebin: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ 'dragsort_url': ''
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: 'shopro/decorate/recyclebin' + location.search,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ { checkbox: true },
+ { field: 'id', title: __('Id') },
+ { field: 'name', title: __('Name'), align: 'left' },
+ {
+ field: 'deletetime',
+ title: __('Deletetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'operate',
+ width: '130px',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ buttons: [
+ {
+ name: 'Restore',
+ text: __('Restore'),
+ classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
+ icon: 'fa fa-rotate-left',
+ url: 'shopro/decorate/restore',
+ refresh: true
+ },
+ {
+ name: 'Destroy',
+ text: __('Destroy'),
+ classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
+ icon: 'fa fa-times',
+ url: 'shopro/decorate/destroy',
+ refresh: true
+ }
+ ],
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/decorate.js b/public/assets/js/backend/shopro/decorate.js
new file mode 100644
index 000000000..574ec4096
--- /dev/null
+++ b/public/assets/js/backend/shopro/decorate.js
@@ -0,0 +1,1646 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro_decorate/index' + location.search,
+ add_url: 'shopro_decorate/add',
+ edit_url: 'shopro_decorate/edit',
+ del_url: 'shopro_decorate/del',
+ multi_url: 'shopro_decorate/multi',
+ table: 'shopro_decorate',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [{
+ checkbox: true
+ },
+ {
+ field: 'id',
+ title: __('Id')
+ },
+ {
+ field: 'name',
+ title: __('Name')
+ },
+ {
+ field: 'type',
+ title: __('Type'),
+ searchList: {
+ "shop": __('Type shop'),
+ "custom": __('Type custom'),
+ "preview": __('Type preview')
+ },
+ formatter: Table.api.formatter.normal
+ },
+ {
+ field: 'memo',
+ title: __('Memo')
+ },
+ {
+ field: 'status',
+ title: __('Status'),
+ searchList: {
+ "normal": __('Normal'),
+ "hidden": __('Hidden')
+ },
+ formatter: Table.api.formatter.status
+ },
+ {
+ field: 'platform',
+ title: __('Platform'),
+ searchList: {
+ "H5": __('Platform h5'),
+ "wxOfficialAccount": __('Platform wxofficialaccount'),
+ "wxMiniProgram": __('Platform wxminiprogram'),
+ "App": __('Platform app'),
+ "preview": __('Platform preview')
+ },
+ operate: 'FIND_IN_SET',
+ formatter: Table.api.formatter.label
+ },
+ {
+ field: 'createtime',
+ title: __('Createtime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'updatetime',
+ title: __('Updatetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'operate',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ lists: function () {
+ var decorateIndex = new Vue({
+ el: "#decorate-index",
+ data() {
+ return {
+ templateForm: {
+ name: '',
+ platform: [],
+ memo: ''
+ },
+ platform_text: {
+ '微信小程序': 'wxMiniProgram',
+ '微信公众号': 'wxOfficialAccount',
+ 'H5': 'H5',
+ 'App': 'App',
+ },
+ platform_text_reload: {
+ 'wxMiniProgram': '微信小程序',
+ 'wxOfficialAccount': '微信公众号',
+ 'H5': 'H5',
+ 'App': 'App',
+ },
+ createDialog: false,
+ templateList: [],
+ submitId: null,
+ focusi: false
+ }
+ },
+ mounted() {
+ this.getTemplate();
+ },
+ methods: {
+ getTemplate(type) {
+ let that = this;
+ if (type == 'refresh') {
+ that.focusi = true
+ }
+ Fast.api.ajax({
+ url: 'shopro/decorate/lists',
+ loading: true,
+ type: 'GET',
+ data: {
+ type: 'shop'
+ }
+ }, function (ret, res) {
+ that.templateList = res.data;
+ that.focusi = false
+ return false
+ })
+ },
+ operation(type, id) {
+ let that = this;
+ switch (type) {
+ case 'create':
+ that.createDialog = true;
+ that.submitId = id; //创建新的
+ break;
+ case 'edit':
+ that.createDialog = true;
+ that.templateList.forEach(i => {
+ if (i.id == id) {
+ that.templateForm.name = i.name;
+ that.templateForm.memo = i.memo;
+ let arr = []
+ i.platform.split(',').forEach(j => {
+ if (that.platform_text_reload[j]) {
+ arr.push(that.platform_text_reload[j])
+ }
+ })
+ that.templateForm.platform = arr
+ }
+ })
+ that.submitId = id; //编辑id
+ break;
+ case 'decorate':
+ Fast.api.addtabs('shopro/decorate/dodecorate?id=' + id + '&fromtype=shop', '页面管理');
+ break;
+ case 'copy':
+ Fast.api.ajax({
+ url: 'shopro/decorate/copy/id/' + id,
+ loading: true,
+ data: {}
+ }, function (ret, res) {
+ that.getTemplate()
+ })
+ break;
+ case 'release':
+ Fast.api.ajax({
+ url: 'shopro/decorate/publish/id/' + id,
+ loading: true,
+ data: {}
+ }, function (ret, res) {
+ that.getTemplate()
+ },function(ret, res){
+ let code=res.data
+ that.$confirm(res.msg, '提示', {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ type: 'warning'
+ }).then(() => {
+ if(code===0){
+ that.createDialog = true;
+ that.templateList.forEach(i => {
+ if (i.id == id) {
+ that.templateForm.name = i.name;
+ that.templateForm.memo = i.memo;
+ let arr = []
+ i.platform.split(',').forEach(j => {
+ if (that.platform_text_reload[j]) {
+ arr.push(that.platform_text_reload[j])
+ }
+ })
+ that.templateForm.platform = arr
+ }
+ })
+ that.submitId = id;
+ }else{
+ Fast.api.ajax({
+ url: 'shopro/decorate/publish/id/' + id+"/force/1",
+ loading: true,
+ data: {}
+ }, function (ret, res) {
+ that.getTemplate()
+ })
+ }
+ })
+ return false;
+ })
+ break;
+ case 'delete':
+ Fast.api.ajax({
+ url: 'shopro/decorate/del/ids/' + id,
+ loading: true,
+ data: {}
+ }, function (ret, res) {
+ that.getTemplate()
+ })
+ break;
+ case 'down':
+ Fast.api.ajax({
+ url: 'shopro/decorate/down/id/' + id,
+ loading: true,
+ data: {}
+ }, function (ret, res) {
+ that.getTemplate()
+ })
+ break;
+ }
+ },
+ // 修改信息
+ createClose(type) {
+ let that = this;
+ if (type == 'yes') {
+ let arr = []
+ that.templateForm.platform.forEach(i => {
+ arr.push(that.platform_text[i])
+ })
+ if (that.submitId) {
+ Fast.api.ajax({
+ url: 'shopro/decorate/edit/id/' + that.submitId,
+ loading: true,
+ data: {
+ name: that.templateForm.name,
+ platform: arr.join(','),
+ memo: that.templateForm.memo
+ }
+ }, function (ret, res) {
+ that.createDialog = false
+ that.getTemplate();
+ that.templateForm.platform = [];
+ that.templateForm.name = '';
+ that.templateForm.memo = ""
+ })
+ } else {
+ Fast.api.ajax({
+ url: 'shopro/decorate/add',
+ loading: true,
+ data: {
+ name: that.templateForm.name,
+ platform: arr.join(','),
+ memo: that.templateForm.memo,
+ status: 'hidden',
+ type: 'shop'
+ }
+ }, function (ret, res) {
+ that.createDialog = false
+ that.getTemplate();
+ that.templateForm.platform = [];
+ that.templateForm.name = '';
+ that.templateForm.memo = ""
+ })
+ }
+ } else {
+ that.createDialog = false;
+ that.templateForm.platform = [];
+ that.templateForm.name = '';
+ that.templateForm.memo = ""
+ }
+ },
+ goRecycle() {
+ let that = this;
+ Fast.api.open("shopro/decorate/recyclebin", "查看回收站", {
+ callback() {
+ that.getTemplate();
+ }
+ })
+ }
+ },
+ })
+
+ },
+ recyclebin: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ 'dragsort_url': ''
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: 'shopro/decorate/recyclebin' + location.search,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [{
+ checkbox: true
+ },
+ {
+ field: 'id',
+ title: __('Id')
+ },
+ {
+ field: 'name',
+ title: __('Name'),
+ align: 'left'
+ },
+ {
+ field: 'deletetime',
+ title: __('Deletetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'operate',
+ width: '130px',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ buttons: [{
+ name: 'Restore',
+ text: __('Restore'),
+ classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
+ icon: 'fa fa-rotate-left',
+ url: 'shopro/decorate/restore',
+ refresh: true
+ },
+ {
+ name: 'Destroy',
+ text: __('Destroy'),
+ classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
+ icon: 'fa fa-times',
+ url: 'shopro/decorate/destroy',
+ refresh: true
+ }
+ ],
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ dodecorate: function () {
+
+ var vueAdd = new Vue({
+ el: "#decorateApp",
+ data() {
+ return {
+ decorateContent: '',
+ group: "changepull",
+ toolsBox: [{
+ name: "图文",
+ data: [{
+ name: "轮播图",
+ type: "banner",
+ image: "/assets/addons/shopro/img/decorate/banner.png",
+ flag: false
+ }, {
+ name: "广告魔方",
+ type: "adv",
+ image: "/assets/addons/shopro/img/decorate/adv.png",
+ flag: false
+ }, {
+ name: "列表导航",
+ type: "nav-list",
+ image: "/assets/addons/shopro/img/decorate/nav-list.png",
+ flag: false
+ }, {
+ name: "宫格列表",
+ type: "grid-list",
+ image: "/assets/addons/shopro/img/decorate/grid-list.png",
+ flag: false
+ }, {
+ name: "富文本",
+ type: "rich-text",
+ image: "/assets/addons/shopro/img/decorate/rich-text.png",
+ flag: false
+ }, {
+ name: "标题栏",
+ type: "title-block",
+ image: "/assets/addons/shopro/img/decorate/title-block.png",
+ flag: false
+ }, {
+ name: "订单卡片",
+ type: "order-card",
+ image: "/assets/addons/shopro/img/decorate/order-card.png",
+ flag: false
+ }, {
+ name: "资产卡片",
+ type: "wallet-card",
+ image: "/assets/addons/shopro/img/decorate/wallet-card.png",
+ flag: false
+ }]
+ }, {
+ name: "商品组",
+ data: [{
+ name: "商品分类",
+ type: "goods-group",
+ image: "/assets/addons/shopro/img/decorate/goods-group.png",
+ flag: false
+ }, {
+ name: "自定义商品",
+ type: "goods-list",
+ image: "/assets/addons/shopro/img/decorate/goods-list.png",
+ flag: false
+ }, {
+ name: "菜单组",
+ type: "menu",
+ image: "/assets/addons/shopro/img/decorate/menu.png",
+ flag: false
+ }]
+ }, {
+ name: "活动营销",
+ data: [{
+ name: "优惠券",
+ type: "coupons",
+ image: "/assets/addons/shopro/img/decorate/coupon.png",
+ flag: false
+ },
+ {
+ name: "拼团",
+ type: "groupon",
+ image: "/assets/addons/shopro/img/decorate/groupon.png"
+ },
+ {
+ name: "秒杀商品",
+ type: "seckill",
+ image: "/assets/addons/shopro/img/decorate/secKill.png",
+ flag: false
+ }, {
+ name: "小程序直播",
+ type: "live",
+ image: "/assets/addons/shopro/img/decorate/live.png",
+ flag: false
+ }
+ ]
+ }, {
+ name: "其他",
+ data: [{
+ name: "搜索",
+ type: "search",
+ image: "/assets/addons/shopro/img/decorate/search.png",
+ flag: false
+ }]
+ }],
+ templateData: [],
+ centerSelect: null,
+ templateForm: {},
+ advStyleImage: [{
+ src: '/assets/addons/shopro/img/decorate/adv_01.png',
+ num: 1
+ },
+ {
+ src: '/assets/addons/shopro/img/decorate/adv_02.png',
+ num: 2
+ },
+ {
+ src: '/assets/addons/shopro/img/decorate/adv_03.png',
+ num: 3
+ },
+ {
+ src: '/assets/addons/shopro/img/decorate/adv_04.png',
+ num: 3
+ },
+ {
+ src: '/assets/addons/shopro/img/decorate/adv_05.png',
+ num: 3
+ },
+ {
+ src: '/assets/addons/shopro/img/decorate/adv_06.png',
+ num: 3
+ },
+ {
+ src: '/assets/addons/shopro/img/decorate/adv_07.png',
+ num: 5
+ }
+ ],
+ titleBlock: {
+ isSelected: false,
+ data: [{
+ src: 'http://shopro.7wpp.com/imgs/title1.png',
+ selected: false,
+ },
+ {
+ src: 'http://shopro.7wpp.com/imgs/title2.png',
+ selected: false,
+ },
+ {
+ src: 'http://shopro.7wpp.com/imgs/title3.png',
+ selected: false,
+ },
+ {
+ src: 'http://shopro.7wpp.com/imgs/title4.png',
+ selected: false,
+ },
+ {
+ src: 'http://shopro.7wpp.com/imgs/title5.png',
+ selected: false,
+ }
+ ],
+ currentImage: ''
+ },
+ iframeSrc: '',
+ qrcodeSrc: '',
+ iframeTitle: '',
+ iframeCopyright: [],
+ iframePlatform: '',
+ previewDialog: false,
+ isPageType: 'home',
+ advdrawer: false,
+ pageTypeList: [{
+ name: '首页',
+ type: 'home',
+ flag: false
+ },
+ {
+ name: '个人中心',
+ type: 'user',
+ flag: false
+ },
+ {
+ name: '底部导航',
+ type: 'tabbar',
+ flag: false
+ },
+ {
+ name: '弹窗提醒',
+ type: 'popup',
+ flag: false
+ }, {
+ name: '悬浮按钮',
+ type: 'float-button',
+ flag: false
+ }
+ ],
+ homeData: Config.templateData.home ? Config.templateData.home : [],
+ userData: Config.templateData.user,
+ tabbarData: Config.templateData.tabbar ? Config.templateData.tabbar : [{
+ type: 'tabbar',
+ name: '底部导航',
+ content: {
+ style: 1,
+ color: '#000',
+ activeColor: "#999",
+ list: [{
+ name: "",
+ image: "",
+ activeImage: "",
+ path: "",
+ path_name: "",
+ path_type: 1
+ }]
+ }
+ }],
+ popupData: Config.templateData.popup ? Config.templateData.popup : [{
+ type: 'popup',
+ name: '弹窗提醒',
+ content: {
+ list: []
+ }
+ }],
+ floatButtonData: Config.templateData['float-button'] ? Config.templateData['float-button'] : [{
+ type: 'float-button',
+ name: '悬浮按钮',
+ content: {
+ image: '',
+ list: []
+ }
+ }],
+ customData: Config.templateData.custom ? Config.templateData.custom : [{
+ name: "导航背景色",
+ type: "nav-bg",
+ content: {
+ name: "",
+ style: 1,
+ color: '#eeeeee',
+ image: ''
+ }
+ }],
+ fromtype: window.location.search.replace("?", "").split('&')[1].split('=')[1],
+ decorate_id: window.location.search.replace("?", "").split('&')[0].split('=')[1],
+ gg: false,
+ customColors: "#7536D0",
+ percentage: 0,
+ percentageshow: false
+ }
+ },
+ mounted() {
+ if (this.fromtype == 'shop') {
+ this.templateData = this.homeData;
+ this.pageTypeList.forEach(i => {
+ if (i.type == this.isPageType) {
+ i.flag = true;
+ }
+ });
+ } else {
+ this.templateData = this.customData;
+ this.centerSelect = 0
+ this.showForm(this.centerSelect);
+ }
+ },
+ methods: {
+ start(e) {
+ $('.sortable-ghost .hide-item').show();
+ },
+ end(e) {
+ $('.hide-item').hide();
+ },
+ changeDraggable(e) {
+ if (e.added) {
+ this.centerSelect = e.added.newIndex
+ this.templateData[this.centerSelect] = this.judgeType(e.added.element.type)
+ }
+ if (e.moved) {
+ this.centerSelect = e.moved.newIndex
+ }
+ this.showForm(this.centerSelect);
+ },
+ selectTools(type) {
+ let form = this.judgeType(type);
+ if (this.centerSelect == null) {
+ this.centerSelect = this.templateData.length;
+ this.templateData.splice(this.centerSelect, 0, form);
+ } else {
+ this.centerSelect = this.centerSelect + 1;
+ this.templateData.splice(this.centerSelect, 0, form);
+ }
+ this.showForm(this.centerSelect);
+ },
+ centerDel(idx) {
+ this.templateData.splice(idx, 1);
+ this.centerSelect = idx;
+ if (this.centerSelect == 0) {
+ if (this.templateData.length > 1) {
+ this.templateForm = this.templateData[this.centerSelect]
+ } else {
+ this.centerSelect = null;
+ }
+ } else {
+ this.centerSelect = this.centerSelect - 1;
+ this.templateForm = this.templateData[this.centerSelect]
+ }
+ },
+ //删除子元素
+ rightDel(index) {
+ this.templateData[this.centerSelect].content.list.splice(index, 1)
+ },
+ showForm(index) {
+ this.centerSelect = index;
+ this.templateForm = this.templateData[index]
+ },
+ // 添加
+ addForm(type) {
+ let form = {};
+ switch (type) {
+ case 'banner':
+ form = {
+ image: '',
+ path: '',
+ path_type: 1,
+ name: '',
+ bgcolor: '',
+ path_name: ""
+ };
+ break;
+ case 'menu':
+ form = {
+ image: '',
+ path: '',
+ name: '',
+ path_name: '',
+ path_type: 1
+ };
+ break;
+ case 'nav-list':
+ form = {
+ name: "",
+ image: "",
+ path: "",
+ path_name: "",
+ path_type: 1
+ };
+ break;
+ case 'grid-list':
+ form = {
+ name: "",
+ image: "",
+ path: "",
+ path_name: "",
+ path_type: 1
+ };
+ break;
+ case 'tabbar':
+ form = {
+ name: "",
+ image: "",
+ activeImage: "",
+ path: "",
+ path_name: "",
+ path_type: 1
+ }
+ break;
+ case 'popup':
+ form = {
+ image: "",
+ path: "",
+ path_name: "",
+ page: [],
+ page_name: [],
+ path_type: 1,
+ style: 1,
+ }
+ break;
+ case 'float-button':
+ form = {
+ name: "",
+ style: 1,
+ image: '',
+ btnimage: '',
+ path: '',
+ path_name: '',
+ path_type: 1,
+ page: [],
+ page_name: []
+ }
+ break;
+ }
+ this.templateData[this.centerSelect].content.list.push(form)
+ },
+ goPreview() {
+ let that = this;
+ if (that.fromtype == 'shop') {
+ that.tabbarData[0].content.isshow = true;
+ let templateData = {
+ home: that.homeData,
+ popup: that.popupData,
+ tabbar: that.tabbarData,
+ user: that.userData,
+ 'float-button': that.floatButtonData,
+ }
+ templateData = JSON.stringify(templateData)
+ Fast.api.ajax({
+ url: 'shopro/decorate/preview/id/' + that.decorate_id,
+ loading: true,
+ data: {
+ templateData: templateData
+ }
+ }, function (ret, res) {
+ that.iframeSrc = res.url + "&time=" + new Date().getTime();
+ that.qrcodeSrc = 'http://qrcode.7wpp.com?url=' + that.iframeSrc;
+ that.iframeTitle = res.msg;
+ that.iframeCopyright = res.data.copyright;
+ that.iframePlatform = res.data.platform;
+ that.previewDialog = true;
+
+
+ })
+ } else {
+ let templateData = {
+ custom: that.customData,
+ }
+ templateData = JSON.stringify(templateData)
+ Fast.api.ajax({
+ url: 'shopro/decorate/preview/id/' + that.decorate_id,
+ loading: true,
+ data: {
+ templateData: templateData
+ }
+ }, function (ret, res) {
+
+ that.iframeSrc = res.url + "&time=" + new Date().getTime();
+ that.qrcodeSrc = 'http://qrcode.7wpp.com?url=' + that.iframeSrc;
+ that.iframeTitle = res.msg;
+ that.iframeCopyright = res.data.copyright;
+ that.iframePlatform = res.data.platform;
+ that.previewDialog = true;
+
+
+ })
+ }
+ },
+ goPreserve() {
+ let that = this;
+ if (that.fromtype == 'shop') {
+ that.tabbarData[0].content.isshow = true;
+ if (that.tabbarData[0].content.list.length > 6) {
+ const h = this.$createElement;
+ that.$message({
+ message: h('p', null, [
+ h('span', null, '底部导航最多5个 ')
+ ])
+ });
+ return false;
+ } else if (that.tabbarData[0].content.list.length > 0) {
+ let flag = false;
+ if (that.tabbarData[0].content.style == 1) {
+ if (that.tabbarData[0].content.color == '' || that.tabbarData[0].content.activeColor == '') {
+ flag = true
+ }
+ that.tabbarData[0].content.list.forEach(i => {
+ if (i.activeImage == '' || i.image == '' || i.name == '' || i.path == '') {
+ flag = true
+ }
+ })
+
+ } else if (that.tabbarData[0].content.style == 3) {
+ if (that.tabbarData[0].content.color == '' || that.tabbarData[0].content.activeColor == '') {
+ flag = true
+ }
+ that.tabbarData[0].content.list.forEach(i => {
+ if (i.name == '' || i.path == '') {
+ flag = true
+ }
+ })
+ } else if (that.tabbarData[0].content.style == 2) {
+ that.tabbarData[0].content.list.forEach(i => {
+ if (i.activeImage == '' || i.image == '' || i.path == '') {
+ flag = true
+ }
+ })
+ } else {
+ flag = true
+ }
+ if (flag) {
+ that.$message({
+ message: "请完善底部导航"
+ });
+ return false;
+ }
+ }
+ let templateData = {
+ home: that.homeData,
+ popup: that.popupData,
+ tabbar: that.tabbarData,
+ user: that.userData,
+ 'float-button': that.floatButtonData,
+ }
+ templateData = JSON.stringify(templateData);
+ that.percentageshow = true;
+ Fast.api.ajax({
+ url: 'shopro/decorate/dodecorate_save/id/' + that.decorate_id,
+ // loading: true,
+ data: {
+ templateData: templateData
+ }
+ }, function (ret, res) {
+ that.iframeSrc = res.url + "&time=" + new Date().getTime();
+ let timers = setInterval(function () {
+ that.percentage = that.percentage + 2;
+ if (that.percentage > 100) {
+ clearInterval(timers);
+ that.percentage = 100;
+ that.percentageshow = false;
+ }
+ }, 100);
+ return false;
+ })
+ } else {
+ let templateData = {
+ custom: that.customData,
+ }
+ templateData = JSON.stringify(templateData)
+ Fast.api.ajax({
+ url: 'shopro/decorate/dodecorate_save/id/' + that.decorate_id,
+ loading: true,
+ data: {
+ templateData: templateData
+ }
+ }, function (ret, res) {})
+ }
+ },
+ previewClose() {
+ this.previewDialog = false;
+ },
+ selectTitleBlock(index) {
+ if (index != null) {
+ this.titleBlock.isSelected = true
+ this.templateData[this.centerSelect].content.image = this.titleBlock.data[index].src
+ this.titleBlock.currentImage = this.titleBlock.data[index].src
+ } else {
+ this.titleBlock.isSelected = false
+ this.templateData[this.centerSelect].content.image = ''
+ }
+ },
+ chooseAdvPic() {
+ this.advdrawer = true;
+ },
+ changeAdv(index, num) {
+ this.templateData[this.centerSelect].content.list = []
+ this.templateData[this.centerSelect].content.style = index + 1
+ for (let i = 0; i < num; i++) {
+ this.templateData[this.centerSelect].content.list.push({
+ image: "",
+ name: "",
+ path: "",
+ path_name: "",
+ path_type: 1,
+ })
+ }
+ this.templateForm = this.templateData[this.centerSelect]
+ this.advdrawer = false;
+ },
+ selectType(type, index) {
+ let that = this;
+ that.isPageType = type;
+ that.pageTypeList.forEach(i => {
+ i.flag = false
+ });
+ that.pageTypeList[index].flag = true;
+ },
+ selectDate(type) {
+ let that = this;
+ switch (type) {
+ case 'home':
+ that.homeData = that.templateData;
+ break;
+ case 'user':
+ that.userData = that.templateData;
+ break;
+ case 'tabbar':
+ that.tabbarData = that.templateData;
+ break;
+ case 'popup':
+ that.popupData = that.templateData;
+ break;
+ case 'float-button':
+ that.floatButtonData = that.templateData;
+ break;
+ }
+ },
+ selecttoDate(type) {
+ let that = this;
+ switch (type) {
+ case 'home':
+ that.templateData = that.homeData;
+ break;
+ case 'user':
+ that.templateData = that.userData;
+ break;
+ case 'tabbar':
+ that.templateData = that.tabbarData
+ break;
+ case 'popup':
+ that.templateData = that.popupData
+ break;
+ case 'float-button':
+ that.templateData = that.floatButtonData;
+ break;
+ }
+ },
+ //检测类型
+ judgeType(type) {
+ var form;
+ switch (type) {
+ case 'search': //√
+ form = {
+ name: "搜索",
+ content: "",
+ type: "search",
+ };
+ break;
+ case 'banner':
+ form = {
+ name: "轮播图",
+ type: "banner",
+ content: {
+ name: "",
+ style: 1,
+ list: [{
+ name: "",
+ bgcolor: "",
+ image: "",
+ path: "",
+ path_name: "",
+ path_type: 1,
+ }],
+ }
+ };
+ break;
+ case 'menu':
+ form = {
+ name: "菜单组",
+ type: "menu",
+ content: {
+ name: "",
+ style: 4,
+ list: [{
+ name: "",
+ image: "",
+ path: "",
+ path_name: "",
+ path_type: 1
+ }]
+ }
+ };
+ break;
+ case 'live':
+ form = {
+ name: "小程序直播",
+ type: "live",
+ content: {
+ style: 1,
+ ids: '',
+ name: "",
+ }
+ };
+ break;
+ case 'adv':
+ form = {
+ name: "广告魔方",
+ type: "adv",
+ content: {
+ list: [{
+ name: "",
+ image: "",
+ path: "",
+ path_name: "",
+ path_type: 1,
+ }],
+ name: "",
+ style: 1
+ }
+ };
+ break;
+ case 'goods-group':
+ form = {
+ name: "商品分类",
+ type: "goods-group",
+ content: {
+ id: '',
+ name: "",
+ category_name: "",
+ image: "",
+ }
+ };
+ break;
+ case 'goods-list':
+ form = {
+ name: "自定义商品",
+ type: "goods-list",
+ content: {
+ ids: '',
+ image: "",
+ name: "",
+
+ }
+ };
+ break;
+ case 'coupons':
+ form = {
+ name: "优惠券",
+ type: "coupons",
+ content: {
+ ids: '',
+ name: ''
+ }
+ };
+ break;
+ case 'groupon':
+ form = {
+ name: "拼团",
+ type: "groupon",
+ content: {
+ id: '',
+ name: "",
+ groupon_name: '',
+ }
+ };
+ break;
+ case 'seckill':
+ form = {
+ name: "秒杀",
+ type: "seckill",
+ content: {
+ id: '',
+ name: "",
+ seckill_name: '',
+ }
+ };
+ break;
+ case 'nav-list':
+ form = {
+ name: "列表导航",
+ type: "nav-list",
+ content: {
+ name: "",
+ list: [{
+ name: "",
+ image: "",
+ path: "",
+ path_name: "",
+ path_type: 1
+ }]
+ }
+ };
+ break;
+ case 'grid-list':
+ form = {
+ name: "宫格列表",
+ type: "grid-list",
+ content: {
+ name: "",
+ list: [{
+ name: "",
+ image: "",
+ path: "",
+ path_name: "",
+ path_type: 1
+ }]
+ }
+ };
+ break;
+ case 'rich-text':
+ form = {
+ name: "富文本",
+ type: "rich-text",
+ content: {
+ id: '',
+ name: "",
+ }
+ };
+ break;
+ case 'title-block':
+ form = {
+ name: "标题栏",
+ type: "title-block",
+ content: {
+ name: "",
+ color: "#000000",
+ image: '/assets/addons/shopro/img/decorate/title1.png'
+ }
+ };
+ break;
+ case 'order-card':
+ form = {
+ name: "订单卡片",
+ type: "order-card",
+ content: {}
+ };
+ break;
+ case 'wallet-card':
+ form = {
+ name: "资产卡片",
+ type: "wallet-card",
+ content: {}
+ };
+ break;
+ }
+ return form
+ },
+ isweblink(type, index) {
+ this.templateForm.content.list[index].path = '';
+ this.templateForm.content.list[index].path_name = '';
+ }
+ },
+ watch: {
+ templateData: {
+ handler: function (newVal, oldVal) {
+ newVal.length == 0 ? this.templateForm = {} : this.templateForm
+ },
+ deep: true
+ },
+ isPageType(newVal, oldVal) {
+ if (oldVal) {
+ this.selectDate(oldVal)
+ }
+ this.selecttoDate(newVal);
+ if (newVal != 'home') {
+ this.centerSelect = 0;
+ } else {
+ if (this.homeData.length > 0) {
+ this.centerSelect = 0;
+ } else {
+ this.centerSelect = null;
+ }
+ }
+ this.showForm(this.centerSelect);
+ },
+ percentageshow(newVal) {
+ if (!newVal) {
+ setTimeout(() => {
+ this.percentage = 0;
+ }, 100)
+ }
+
+ }
+ }
+ })
+
+ //所有图片选择
+ $(document).on("click", ".choosePicture", function () {
+ var that = this;
+ var multiple = $(this).data("multiple") ? $(this).data("multiple") : false;
+ parent.Fast.api.open("general/attachment/select?multiple=" + multiple, "选择图片", {
+ callback: function (data) {
+ let index = $(that).attr("data-index")
+ switch (index) {
+ case "image":
+ vueAdd.$data.templateData[vueAdd.$data.centerSelect].content.image = data.url;
+ vueAdd.$data.templateForm = vueAdd.$data.templateData[vueAdd.$data.centerSelect];
+ break;
+ case "title-block":
+ vueAdd.$data.templateData[vueAdd.$data.centerSelect].content.image = data.url;
+ vueAdd.$data.titleBlock.currentImage = data.url;
+ vueAdd.$data.templateForm = vueAdd.$data.templateData[vueAdd.$data.centerSelect];
+ break;
+ default:
+ if ($(that).attr("data-active") == 'active') {
+ vueAdd.$data.templateData[vueAdd.$data.centerSelect].content.list[index].activeImage = data.url;
+ } else if ($(that).attr("data-type") == 'btn') {
+ vueAdd.$data.templateData[vueAdd.$data.centerSelect].content.list[index].btnimage = data.url;
+ } else {
+ vueAdd.$data.templateData[vueAdd.$data.centerSelect].content.list[index].image = data.url;
+ }
+ vueAdd.$data.templateForm = vueAdd.$data.templateData[vueAdd.$data.centerSelect]
+ }
+ }
+ });
+ return false;
+ })
+ // 商品分类选择商品
+ $(document).on("click", ".chooseCategory", function () {
+ var that = this;
+ var multiple = $(this).data("multiple") ? $(this).data("multiple") : false;
+ parent.Fast.api.open("shopro/category/select?multiple=" + multiple, "选择分类", {
+ callback: function (data) {
+ vueAdd.$data.templateData[vueAdd.$data.centerSelect].content.category_name = data.data.category_name
+ vueAdd.$data.templateData[vueAdd.$data.centerSelect].content.id = data.data.id
+ vueAdd.$data.templateForm = vueAdd.$data.templateData[vueAdd.$data.centerSelect]
+ }
+ });
+ return false;
+ })
+ //自定义商品选择商品列表
+ $(document).on("click", ".chooseGoods", function () {
+ var that = this;
+ var multiple = true;
+ parent.Fast.api.open("shopro/goods/select?multiple=" + multiple, "选择商品", {
+ callback: function (data) {
+ vueAdd.$data.templateData[vueAdd.$data.centerSelect].content.ids = data.data.ids
+ vueAdd.$data.templateForm = vueAdd.$data.templateData[vueAdd.$data.centerSelect]
+ }
+ });
+ return false;
+ })
+ // 选择优惠券类型(多选)
+ $(document).on("click", ".chooseCoupons", function () {
+ var that = this;
+ parent.Fast.api.open("shopro/coupons/select?multiple=true", "选择优惠券", {
+ callback: function (data) {
+ vueAdd.$data.templateData[vueAdd.$data.centerSelect].content.ids = data.data.ids
+ vueAdd.$data.templateForm = vueAdd.$data.templateData[vueAdd.$data.centerSelect]
+ }
+ });
+ return false;
+ })
+ // 选择活动商品
+ $(document).on("click", ".chooseActivity", function () {
+ var that = this;
+ var multiple = $(this).data("multiple") ? $(this).data("multiple") : false;
+ var type = $(this).attr("data-type")
+ parent.Fast.api.open("shopro/activity/activity/select?multiple=" + multiple + "&type=" + type, "选择活动", {
+ callback: function (data) {
+ vueAdd.$data.templateData[vueAdd.$data.centerSelect].content.id = data.data.id
+ vueAdd.$data.templateData[vueAdd.$data.centerSelect].content[type + '_name'] = data.data.title
+ vueAdd.$data.templateForm = vueAdd.$data.templateData[vueAdd.$data.centerSelect]
+ }
+ });
+ return false;
+ })
+ //选择链接chooseLive
+ $(document).on("click", ".chooseLive", function () {
+ var that = this;
+ var multiple = $(this).data("multiple") ? $(this).data("multiple") : false;
+ parent.Fast.api.open("shopro/app/live/select?multiple=true" + "&type=live", "选择小程序直播", {
+ callback: function (data) {
+ vueAdd.$data.templateData[vueAdd.$data.centerSelect].content.ids = data.data.ids
+ vueAdd.$data.templateForm = vueAdd.$data.templateData[vueAdd.$data.centerSelect]
+ }
+ });
+ return false;
+ })
+ //选择链接Path
+ $(document).on("click", ".choosePath", function () {
+ var that = this;
+ var multiple = $(this).data("multiple") ? $(this).data("multiple") : false;
+ parent.Fast.api.open("shopro/link/select?multiple=" + multiple, "选择链接", {
+ callback: function (data) {
+ var index = $(that).attr("data-index")
+ let page = $(that).attr("data-page")
+ if (page == 'page') {
+ if (data.data.pathId) {
+ vueAdd.$data.templateData[vueAdd.$data.centerSelect].content.list[index].page_name = data.data.pathId.split(',')
+ vueAdd.$data.templateData[vueAdd.$data.centerSelect].content.list[index].page = data.data.path.split(',')
+ vueAdd.$data.templateForm = vueAdd.$data.templateData[vueAdd.$data.centerSelect]
+ } else {
+ vueAdd.$data.templateData[vueAdd.$data.centerSelect].content.list[index].page_name = data.data.path_name.split(',')
+ vueAdd.$data.templateData[vueAdd.$data.centerSelect].content.list[index].page = data.data.path.split(',')
+ vueAdd.$data.templateForm = vueAdd.$data.templateData[vueAdd.$data.centerSelect]
+ }
+
+ } else {
+ vueAdd.$data.templateData[vueAdd.$data.centerSelect].content.list[index].path_name = data.data.path_name
+ vueAdd.$data.templateData[vueAdd.$data.centerSelect].content.list[index].path = data.data.path
+ vueAdd.$data.templateForm = vueAdd.$data.templateData[vueAdd.$data.centerSelect]
+ }
+
+ }
+ });
+ return false;
+ })
+ // 选择富文本chooseRichText
+ $(document).on("click", ".chooseRichText", function () {
+ var that = this;
+ parent.Fast.api.open("shopro/richtext/select?multiple=false", "选择富文本", {
+ callback: function (data) {
+ vueAdd.$data.templateData[vueAdd.$data.centerSelect].content.id = data.data.id
+ vueAdd.$data.templateData[vueAdd.$data.centerSelect].content.name = data.data.title
+ vueAdd.$data.templateForm = vueAdd.$data.templateData[vueAdd.$data.centerSelect]
+ }
+ });
+ return false;
+ })
+ },
+ designer: function () {
+ var decorateDesigner = new Vue({
+ el: "#decorate-designer",
+ data() {
+ return {
+ decorateList: Config.designerData,
+ previewDialog: false,
+ previewData: {},
+ iframeSrc: "",
+ qrcodeSrc: "",
+ }
+ },
+ mounted() {},
+ methods: {
+ operation(type, index, id) {
+ let that = this;
+ that.previewData = that.decorateList[index];
+ switch (type) {
+ case 'preview':
+ that.iframeSrc = window.location.protocol + "//designer.7wpp.com?shop_id=" + id;
+ that.qrcodeSrc = 'http://qrcode.7wpp.com?url=' + that.iframeSrc;
+ that.previewDialog = true;
+ break;
+ case 'use':
+ Fast.api.ajax({
+ url: 'shopro/decorate/use_designer_template?id=' + id,
+ loading: true,
+ data: {}
+ }, function (ret, res) {
+
+ })
+ break;
+ }
+
+ },
+ previewClose() {
+ this.previewDialog = false;
+ },
+ },
+ })
+ },
+ custom: function () {
+ var decorateList = new Vue({
+ el: "#decorate-list",
+ data() {
+ return {
+ decorateList: [],
+ customDialog: false,
+ customTem: {
+ name: '',
+ memo: '',
+ },
+ editId: null
+ }
+ },
+ mounted() {
+ this.getdecorateList();
+ },
+ methods: {
+ getdecorateList() {
+ let that = this;
+ Fast.api.ajax({
+ url: 'shopro/decorate/lists',
+ loading: true,
+ type: 'GET',
+ data: {
+ type: 'custom'
+ }
+ }, function (ret, res) {
+ that.decorateList = res.data;
+ that.decorateList.forEach(i => {
+ i.iseditname = false
+ })
+ return false
+ })
+ },
+ operation(opttype, id, type) {
+ let that = this;
+ switch (opttype) {
+ case 'decorate':
+ Fast.api.addtabs('shopro/decorate/dodecorate?id=' + id + '&type=' + type, '店铺装修');
+ // Fast.api.addtabs('shopro/decorate/dodecorate?id=' + id, '店铺装修')
+ break;
+ case 'delete':
+ Fast.api.ajax({
+ url: 'shopro/decorate/del/ids/' + id,
+ loading: true,
+ data: {}
+ }, function (ret, res) {
+ that.getdecorateList();
+ })
+ break;
+ case 'copy':
+ Fast.api.ajax({
+ url: 'shopro/decorate/copy/id/' + id,
+ loading: true,
+ data: {}
+ }, function (ret, res) {
+ that.getdecorateList();
+ })
+ break;
+ case 'create':
+ this.customDialog = true;
+ this.editId = id;
+ break;
+ case 'edit':
+ this.customDialog = true;
+ this.editId = id;
+ that.decorateList.forEach(i => {
+ if (i.id == that.editId) {
+ that.customTem.name = i.name;
+ that.customTem.memo = i.memo;
+ }
+ })
+ break;
+ }
+ },
+ customClose(type) {
+ let that = this;
+ if (type == 'yes') {
+ if (that.editId) {
+ Fast.api.ajax({
+ url: 'shopro/decorate/edit/id/' + that.editId,
+ loading: true,
+ data: {
+ name: that.customTem.name,
+ memo: that.customTem.memo
+ }
+ }, function (ret, res) {
+ that.getdecorateList();
+ that.customDialog = false;
+ for (var key in that.customTem) {
+ that.customTem[key] = ""
+ }
+ })
+ } else {
+ Fast.api.ajax({
+ url: 'shopro/decorate/add',
+ loading: true,
+ data: {
+ type: 'custom',
+ name: that.customTem.name,
+ memo: that.customTem.memo
+ }
+ }, function (ret, res) {
+ that.getdecorateList();
+ that.customDialog = false;
+ for (var key in that.customTem) {
+ that.customTem[key] = ""
+ }
+ })
+ }
+ } else {
+ for (var key in that.customTem) {
+ that.customTem[key] = ""
+ }
+ that.customDialog = false;
+ }
+ },
+ },
+ })
+
+ },
+ select: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/decorate/index',
+ }
+ });
+ var idArr = [];
+ var table = $("#table");
+ table.on('check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table', function (e, row) {
+ if (e.type == 'check' || e.type == 'uncheck') {
+ row = [row];
+ } else {
+ idArr = [];
+ }
+ $.each(row, function (i, j) {
+ if (e.type.indexOf("uncheck") > -1) {
+ var index = idArr.indexOf(j.id);
+ if (index > -1) {
+ idArr.splice(index, 1);
+ }
+ } else {
+ idArr.indexOf(j.id) == -1 && idArr.push(j.id);
+ }
+ });
+ });
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ showToggle: false,
+ showExport: false,
+ columns: [
+ [{
+ checkbox: true
+ },
+ {
+ field: 'id',
+ title: __('Id')
+ },
+ {
+ field: 'name',
+ title: __('Name')
+ },
+ {
+ field: 'type',
+ title: __('Type'),
+ searchList: {
+ "shop": '商城模板',
+ "custom": '自定义模板',
+ "preview": '预览模板'
+ },
+ formatter: Table.api.formatter.normal
+ },
+ {
+ field: 'updatetime',
+ title: __('Updatetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'operate',
+ title: __('Operate'),
+ events: {
+ 'click .btn-chooseone': function (e, value, row, index) {
+ var multiple = Backend.api.query('multiple');
+ multiple = multiple == 'true' ? true : false;
+ row.ids = row.id.toString()
+ Fast.api.close({
+ data: row,
+ multiple: multiple
+ });
+ },
+ },
+ formatter: function () {
+ return '
' + __('Choose') + '';
+ }
+ }
+ ]
+ ]
+ });
+
+ // 选中多个
+ $(document).on("click", ".btn-choose-multi", function () {
+ // var couponsArr = new Array();
+ // $.each(table.bootstrapTable("getAllSelections"), function (i, j) {
+ // couponsArr.push(j.id);
+ // });
+ var multiple = Backend.api.query('multiple');
+ multiple = multiple == 'true' ? true : false;
+ let row = {}
+ row.ids = idArr.join(",")
+ Fast.api.close({
+ data: row,
+ multiple: multiple
+ });
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ require(['upload'], function (Upload) {
+ Upload.api.plupload($("#toolbar .plupload"), function () {
+ $(".btn-refresh").trigger("click");
+ });
+ });
+
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/dispatch/dispatch.js b/public/assets/js/backend/shopro/dispatch/dispatch.js
new file mode 100644
index 000000000..c5d4fb82e
--- /dev/null
+++ b/public/assets/js/backend/shopro/dispatch/dispatch.js
@@ -0,0 +1,120 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // Hook.init(function() {
+ // Controller.bootIndex()
+ // })
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/dispatch/dispatch/index' + location.search,
+ add_url: 'shopro/dispatch/dispatch/add',
+ edit_url: 'shopro/dispatch/dispatch/edit',
+ del_url: 'shopro/dispatch/dispatch/del',
+ multi_url: 'shopro/dispatch/dispatch/multi',
+ table: 'shopro_dispatch',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'name', title: __('Name')},
+ {field: 'type', title: __('Type'), searchList: {"express":__('Type express'),"selfetch":__('Type selfetch'),"store":__('Type store'),"autosend":__('Type autosend')}, formatter: Table.api.formatter.normal},
+ {field: 'type_ids', title: __('Type_ids')},
+ {field: 'createtime', title: __('Createtime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ recyclebin: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ 'dragsort_url': ''
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: 'shopro/dispatch/dispatch/recyclebin' + location.search,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'name', title: __('Name'), align: 'left'},
+ {
+ field: 'deletetime',
+ title: __('Deletetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'operate',
+ width: '130px',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ buttons: [
+ {
+ name: 'Restore',
+ text: __('Restore'),
+ classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
+ icon: 'fa fa-rotate-left',
+ url: 'shopro/dispatch/dispatch/restore',
+ refresh: true
+ },
+ {
+ name: 'Destroy',
+ text: __('Destroy'),
+ classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
+ icon: 'fa fa-times',
+ url: 'shopro/dispatch/dispatch/destroy',
+ refresh: true
+ }
+ ],
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ $(document).on('change', '#c-type', function() {
+ $("#c-type_ids_text").data("selectPageObject").option.data="shopro/dispatch/"+$(this).val()+"/index"
+ })
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/dispatch/express.js b/public/assets/js/backend/shopro/dispatch/express.js
new file mode 100644
index 000000000..5784268ef
--- /dev/null
+++ b/public/assets/js/backend/shopro/dispatch/express.js
@@ -0,0 +1,600 @@
+requirejs.config({
+ paths: {
+ vue: "/assets/addons/shopro/libs/vue"
+ }
+})
+define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'vue'], function ($, undefined, Backend, Table, Form, Vue) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/dispatch/express/index' + location.search,
+ add_url: 'shopro/dispatch/express/add',
+ edit_url: 'shopro/dispatch/express/edit',
+ del_url: 'shopro/dispatch/express/del',
+ multi_url: 'shopro/dispatch/express/multi',
+ table: 'shopro_dispatch_express',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'weigh',
+ columns: [
+ [
+ { checkbox: true },
+ { field: 'id', title: __('Id') },
+ { field: 'name', title: __('Name') },
+ { field: 'type', title: __('Type'), searchList: { "number": __('Type number'), "weight": __('Type weight') }, formatter: Table.api.formatter.normal },
+ { field: 'weigh', title: __('Weigh') },
+ { field: 'first_price', title: __('First_price'), operate: 'BETWEEN' },
+ { field: 'additional_num', title: __('Additional_num') },
+ { field: 'additional_price', title: __('Additional_price'), operate: 'BETWEEN' },
+ // { field: 'province_ids', title: __('Province_ids') },
+ // { field: 'city_ids', title: __('City_ids') },
+ { field: 'createtime', title: __('Createtime'), operate: 'RANGE', addclass: 'datetimerange', formatter: Table.api.formatter.datetime },
+ { field: 'updatetime', title: __('Updatetime'), operate: 'RANGE', addclass: 'datetimerange', formatter: Table.api.formatter.datetime },
+ { field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ recyclebin: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ 'dragsort_url': ''
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: 'shopro/dispatch/express/recyclebin' + location.search,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ { checkbox: true },
+ { field: 'id', title: __('Id') },
+ { field: 'name', title: __('Name'), align: 'left' },
+ {
+ field: 'deletetime',
+ title: __('Deletetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'operate',
+ width: '130px',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ buttons: [
+ {
+ name: 'Restore',
+ text: __('Restore'),
+ classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
+ icon: 'fa fa-rotate-left',
+ url: 'shopro/dispatch/express/restore',
+ refresh: true
+ },
+ {
+ name: 'Destroy',
+ text: __('Destroy'),
+ classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
+ icon: 'fa fa-times',
+ url: 'shopro/dispatch/express/destroy',
+ refresh: true
+ }
+ ],
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ var vueAdd = new Vue({
+ el: "#app",
+ data() {
+ return {
+ pcaData: Config.pca,
+ }
+ },
+ mounted() {
+ },
+ methods: {
+ allopt(){
+ this.pcaData.forEach(i=>{
+ i.flagRight=1;
+ i.flagLeft=0;
+ })
+ },
+ selectAreaLeft(p, c, a) {
+ if (a === null && c === null) {
+ this.pcaData[p].flagRight = 1
+ this.pcaData[p].city.forEach(element => {
+ this.$set(element, "flagRight", '1')
+ element.area.forEach(item => {
+ this.$set(item, "flagRight", '1')
+
+ })
+
+ });
+ this.pcaData[p].flagLeft = 0
+ this.pcaData[p].city.forEach(element => {
+ this.$set(element, "flagLeft", '0')
+ element.area.forEach(item => {
+ this.$set(item, "flagLeft", '0')
+
+ })
+
+ });
+
+ }
+ if (a === null && c !== null) {
+ this.pcaData[p].flagRight = 1
+ this.pcaData[p].city[c].flagRight = 1
+ this.pcaData[p].city[c].flagLeft = 0
+ let num = 0;
+ this.pcaData[p].city.forEach(i => {
+ if (i.flagLeft == 1) {
+ num++
+ }
+ })
+ if (num == 0) {
+ this.pcaData[p].flagLeft = 0
+ this.pcaData[p].city[c].area.forEach(element => {
+ this.$set(element, "flagRight", 1)
+ });
+ }
+ }
+ if (a != null && c != null) {
+ this.pcaData[p].flagRight = 1
+ this.pcaData[p].city[c].flagRight = 1
+ this.pcaData[p].city[c].area[a].flagRight = 1
+ this.pcaData[p].city[c].area[a].flagLeft = 0
+ let num2 = 0;
+ this.pcaData[p].city[c].area.forEach(i => {
+ if (i.flagLeft == 1) {
+ num2++
+ }
+ })
+ if (num2 == 0) {
+ this.pcaData[p].city[c].flagLeft = 0
+ let num = 0;
+ this.pcaData[p].city.forEach(i => {
+ if (i.flagLeft == 1) {
+ num++
+ }
+ })
+ if (num == 0) {
+ this.pcaData[p].flagLeft = 0
+ }
+ }
+
+ }
+ },
+ showLeft(p, c, a) {
+ if (a === null && c === null) {
+ this.pcaData[p].city.forEach(element => {
+
+ this.$set(element, "showLeft",element.showLeft==1?0:1 )
+
+ });
+ }
+ if (a === null && c !== null) {
+ this.pcaData[p].city[c].area.forEach(element => {
+ this.$set(element, "showLeft", element.showLeft==1?0:1 )
+
+ });
+
+ }
+
+ },
+ selectAreaRight(p, c, a) {
+ if (a === null && c === null) {
+ this.pcaData[p].flagLeft = 1
+ this.pcaData[p].city.forEach(element => {
+ this.$set(element, "flagLeft", 1)
+ element.area.forEach(item => {
+ this.$set(item, "flagLeft", 1)
+
+ })
+
+ });
+ this.pcaData[p].flagRight = 0
+ this.pcaData[p].city.forEach(element => {
+ this.$set(element, "flagRight ", 0)
+ element.area.forEach(item => {
+ this.$set(item, "flagRight ", 0)
+
+ })
+
+ });
+
+ }
+ if (a === null && c !== null) {
+ this.pcaData[p].flagLeft = 1
+ this.pcaData[p].city[c].flagLeft = 1
+ this.pcaData[p].city[c].flagRight = 0
+ let num = 0;
+ this.pcaData[p].city.forEach(i => {
+ if (i.flagRight == 1) {
+ num++
+ }
+ })
+ if (num == 0) {
+ this.pcaData[p].flagRight = 0;
+ this.pcaData[p].city[c].area.forEach(element => {
+ this.$set(element, "flagLeft", 1)
+ });
+ }
+ }
+ if (a != null && c != null) {
+ this.pcaData[p].flagLeft = 1
+ this.pcaData[p].city[c].flagLeft = 1
+ this.pcaData[p].city[c].area[a].flagLeft = 1
+ this.pcaData[p].city[c].area[a].flagRight = 0
+ let num2 = 0;
+ this.pcaData[p].city[c].area.forEach(i => {
+ if (i.flagRight == 1) {
+ num2++
+ }
+ })
+ if (num2 == 0) {
+ this.pcaData[p].city[c].flagRight = 0
+ let num = 0;
+ this.pcaData[p].city.forEach(i => {
+ if (i.flagRight == 1) {
+ num++
+ }
+ })
+ if (num == 0) {
+ this.pcaData[p].flagRight = 0
+ }
+ }
+
+ }
+ },
+ showRight(p, c, a) {
+ if (a === null && c === null) {
+ this.pcaData[p].city.forEach(element => {
+ this.$set(element, "showRight", element.showRight==1?0:1 )
+
+ });
+
+ }
+ if (a === null && c !== null) {
+ this.pcaData[p].city[c].area.forEach(element => {
+ this.$set(element, "showRight", element.showRight==1?0:1 )
+
+ });
+ }
+ },
+ },
+
+ })
+ //为了性能考虑,特意加阻断事件,拼接表单数据
+ $(document).on("click", "#submitBtn", function(){
+ let pri = []
+ let city = []
+ let area = []
+ vueAdd.$data.pcaData.forEach(p => {
+ if (p.flagLeft == 0 && p.flagRight == 1) {
+ pri.push(p.id)
+
+ } else {
+ if (!Array.isArray(p.city)) {
+ return false;
+ }
+ p.city.forEach(c => {
+
+ if (c.flagLeft == 0 && c.flagRight == 1) {
+ city.push(c.id)
+
+ } else {
+ if (!Array.isArray(c.area)) {
+ return false;
+ }
+ c.area.forEach(a => {
+ if (a.flagLeft == 0 && a.flagRight == 1) {
+ area.push(a.id)
+
+ }
+ })
+ }
+ })
+
+ }
+ })
+ let arr=[{
+ name:"province",
+ value:pri
+ },
+ {
+ name:"city",
+ value:city
+ },
+ {
+ name:"area",
+ value:area
+ }]
+ $("#area-data").val(JSON.stringify(arr))
+ var that = this;
+ Layer.confirm('确认提交运费模板吗?', {
+ btn: ['确认','取消'] //按钮
+ }, function(){
+
+ $(that).closest("form").trigger("submit");
+ return true;
+ }, function(){
+ Layer.closeAll();
+ return false;
+ });
+ });
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ var vueAdd = new Vue({
+ el: "#app",
+ data() {
+ return {
+ pcaData: Config.pca,
+ }
+ },
+ mounted() {
+ },
+ methods: {
+ allopt(){
+ this.pcaData.forEach(i=>{
+ i.flagRight=1;
+ i.flagLeft=0;
+ })
+ },
+ selectAreaLeft(p, c, a) {
+ if (a === null && c === null) {
+ this.pcaData[p].flagRight = 1
+ this.pcaData[p].city.forEach(element => {
+ this.$set(element, "flagRight", '1')
+ element.area.forEach(item => {
+ this.$set(item, "flagRight", '1')
+
+ })
+
+ });
+ this.pcaData[p].flagLeft = 0
+ this.pcaData[p].city.forEach(element => {
+ this.$set(element, "flagLeft", '0')
+ element.area.forEach(item => {
+ this.$set(item, "flagLeft", '0')
+
+ })
+
+ });
+
+ }
+ if (a === null && c !== null) {
+ this.pcaData[p].flagRight = 1
+ this.pcaData[p].city[c].flagRight = 1
+ this.pcaData[p].city[c].flagLeft = 0
+ let num = 0;
+ this.pcaData[p].city.forEach(i => {
+ if (i.flagLeft == 1) {
+ num++
+ }
+ })
+ if (num == 0) {
+ this.pcaData[p].flagLeft = 0
+ }
+
+ this.pcaData[p].city[c].area.forEach(element => {
+ this.$set(element, "flagRight", '1')
+ });
+
+ }
+ if (a != null && c != null) {
+ this.pcaData[p].flagRight = 1
+ this.pcaData[p].city[c].flagRight = 1
+ this.pcaData[p].city[c].area[a].flagRight = 1
+ this.pcaData[p].city[c].area[a].flagLeft = 0
+ let num2 = 0;
+ this.pcaData[p].city[c].area.forEach(i => {
+ if (i.flagLeft == 1) {
+ num2++
+ }
+ })
+ if (num2 == 0) {
+ this.pcaData[p].city[c].flagLeft = 0
+ let num = 0;
+ this.pcaData[p].city.forEach(i => {
+ if (i.flagLeft == 1) {
+ num++
+ }
+ })
+ if (num == 0) {
+ this.pcaData[p].flagLeft = 0
+ }
+ }
+
+ }
+ },
+ showLeft(p, c, a) {
+ if (a === null && c === null) {
+ this.pcaData[p].city.forEach(element => {
+
+ this.$set(element, "showLeft",element.showLeft==1?0:1 )
+
+ });
+ }
+ if (a === null && c !== null) {
+ this.pcaData[p].city[c].area.forEach(element => {
+ this.$set(element, "showLeft", element.showLeft==1?0:1 )
+
+ });
+
+ }
+
+ },
+ selectAreaRight(p, c, a) {
+ if (a === null && c === null) {
+ this.pcaData[p].flagLeft = 1
+ this.pcaData[p].city.forEach(element => {
+ this.$set(element, "flagLeft", '1')
+ element.area.forEach(item => {
+ this.$set(item, "flagLeft", '1')
+
+ })
+
+ });
+ this.pcaData[p].flagRight = 0
+ this.pcaData[p].city.forEach(element => {
+ this.$set(element, "flagRight ", '0')
+ element.area.forEach(item => {
+ this.$set(item, "flagRight ", '0')
+
+ })
+
+ });
+
+ }
+ if (a === null && c !== null) {
+ this.pcaData[p].flagLeft = 1
+ this.pcaData[p].city[c].flagLeft = 1
+ this.pcaData[p].city[c].flagRight = 0
+ let num = 0;
+ this.pcaData[p].city.forEach(i => {
+ if (i.flagRight == 1) {
+ num++
+ }
+ })
+ if (num == 0) {
+ this.pcaData[p].flagRight = 0
+ }
+
+ this.pcaData[p].city[c].area.forEach(element => {
+ this.$set(element, "flagLeft", '1')
+ });
+
+ }
+ if (a != null && c != null) {
+ this.pcaData[p].flagLeft = 1
+ this.pcaData[p].city[c].flagLeft = 1
+ this.pcaData[p].city[c].area[a].flagLeft = 1
+ this.pcaData[p].city[c].area[a].flagRight = 0
+ let num2 = 0;
+ this.pcaData[p].city[c].area.forEach(i => {
+ if (i.flagRight == 1) {
+ num2++
+ }
+ })
+ if (num2 == 0) {
+ this.pcaData[p].city[c].flagRight = 0
+ let num = 0;
+ this.pcaData[p].city.forEach(i => {
+ if (i.flagRight == 1) {
+ num++
+ }
+ })
+ if (num == 0) {
+ this.pcaData[p].flagRight = 0
+ }
+ }
+
+ }
+ },
+ showRight(p, c, a) {
+ if (a === null && c === null) {
+ this.pcaData[p].city.forEach(element => {
+ this.$set(element, "showRight", element.showRight==1?0:1 )
+
+ });
+
+ }
+ if (a === null && c !== null) {
+ this.pcaData[p].city[c].area.forEach(element => {
+ this.$set(element, "showRight", element.showRight==1?0:1 )
+
+ });
+ }
+ },
+ },
+
+ })
+ //为了性能考虑,特意加阻断事件,拼接表单数据
+ $(document).on("click", "#submitBtn", function(){
+ let pri = []
+ let city = []
+ let area = []
+ vueAdd.$data.pcaData.forEach(p => {
+ if (p.flagLeft == 0 && p.flagRight == 1) {
+ pri.push(p.id)
+
+ } else {
+ p.city.forEach(c => {
+
+ if (c.flagLeft == 0 && c.flagRight == 1) {
+ city.push(c.id)
+
+ } else {
+ c.area.forEach(a => {
+ if (a.flagLeft == 0 && a.flagRight == 1) {
+ area.push(a.id)
+
+ }
+ })
+ }
+ })
+
+ }
+ })
+ let arr=[{
+ name:"province",
+ value:pri
+ },
+ {
+ name:"city",
+ value:city
+ },
+ {
+ name:"area",
+ value:area
+ }]
+ $("#area-data").val(JSON.stringify(arr))
+ var that = this;
+ Layer.confirm('确认提交运费模板吗?', {
+ btn: ['确认','取消'] //按钮
+ }, function(){
+
+ $(that).closest("form").trigger("submit");
+ return true;
+ }, function(){
+ Layer.closeAll();
+ return false;
+ });
+ });
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/faq.js b/public/assets/js/backend/shopro/faq.js
new file mode 100644
index 000000000..957d35ceb
--- /dev/null
+++ b/public/assets/js/backend/shopro/faq.js
@@ -0,0 +1,113 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/faq/index' + location.search,
+ add_url: 'shopro/faq/add',
+ edit_url: 'shopro/faq/edit',
+ del_url: 'shopro/faq/del',
+ multi_url: 'shopro/faq/multi',
+ table: 'shopro_faq',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'title', title: __('Title')},
+ // {field: 'content', title: __('Content')},
+ {field: 'createtime', title: __('Createtime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ recyclebin: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ 'dragsort_url': ''
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: 'shopro/faq/recyclebin' + location.search,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'title', title: __('Title'), align: 'left'},
+ {
+ field: 'deletetime',
+ title: __('Deletetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'operate',
+ width: '130px',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ buttons: [
+ {
+ name: 'Restore',
+ text: __('Restore'),
+ classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
+ icon: 'fa fa-rotate-left',
+ url: 'shopro/faq/restore',
+ refresh: true
+ },
+ {
+ name: 'Destroy',
+ text: __('Destroy'),
+ classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
+ icon: 'fa fa-times',
+ url: 'shopro/faq/destroy',
+ refresh: true
+ }
+ ],
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/feedback.js b/public/assets/js/backend/shopro/feedback.js
new file mode 100644
index 000000000..6046a9066
--- /dev/null
+++ b/public/assets/js/backend/shopro/feedback.js
@@ -0,0 +1,117 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/feedback/index' + location.search,
+ add_url: 'shopro/feedback/add',
+ edit_url: 'shopro/feedback/edit',
+ del_url: 'shopro/feedback/del',
+ multi_url: 'shopro/feedback/multi',
+ table: 'shopro_feedback',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'user_id', title: __('User_id')},
+ {field: 'type_text', title: __('Type')},
+ {field: 'content', title: __('Content')},
+ {field: 'images', title: __('Images'), events: Table.api.events.image, formatter: Table.api.formatter.images},
+ {field: 'phone', title: __('Phone')},
+ {field: 'status', title: __('Status'), searchList: {"0":__('Status 0'),"1":__('Status 1')}, formatter: Table.api.formatter.status},
+ {field: 'remark', title: __('Remark')},
+ {field: 'createtime', title: __('Createtime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ recyclebin: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ 'dragsort_url': ''
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: 'shopro/feedback/recyclebin' + location.search,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {
+ field: 'deletetime',
+ title: __('Deletetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'operate',
+ width: '130px',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ buttons: [
+ {
+ name: 'Restore',
+ text: __('Restore'),
+ classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
+ icon: 'fa fa-rotate-left',
+ url: 'shopro/feedback/restore',
+ refresh: true
+ },
+ {
+ name: 'Destroy',
+ text: __('Destroy'),
+ classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
+ icon: 'fa fa-times',
+ url: 'shopro/feedback/destroy',
+ refresh: true
+ }
+ ],
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/goods.js b/public/assets/js/backend/shopro/goods.js
new file mode 100644
index 000000000..60322f468
--- /dev/null
+++ b/public/assets/js/backend/shopro/goods.js
@@ -0,0 +1,1043 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'toastr'], function ($, undefined, Backend, Table, Form, Toastr) {
+
+ var Controller = {
+ index: function () {
+ var goodsIndex = new Vue({
+ el: "#goodsIndex",
+ data() {
+ return {
+ goodsData: [],
+ multipleSelection: [],
+ activeStatus: 'all',
+ searchKey: '',
+ sort: 'id',
+ order: 'desc',
+ offset: 0,
+ limit: 10,
+ totalPage: 0,
+ currentPage: 1,
+ rowDel: false,
+ allDel: false,
+
+ upStatus: true,
+ currentIndex: null,
+ }
+ },
+ created() {
+ this.getGoodsData();
+ },
+ methods: {
+ getGoodsData() {
+ let that = this;
+ Fast.api.ajax({
+ url: 'shopro/goods/index',
+ loading: true,
+ type: 'GET',
+ data: {
+ search: that.searchKey,
+ status: that.activeStatus,
+ offset: that.offset,
+ limit: that.limit,
+ sort: that.sort,
+ order: that.order,
+ }
+ }, function (ret, res) {
+ that.goodsData = res.data.rows;
+ that.goodsData.forEach(i => {
+ i.showFlag = false;
+ i.rowDel = false;
+ });
+ that.totalPage = res.data.total;
+ return false;
+ })
+ },
+ tabOpt(tab, event) {
+ this.activeStatus = tab.name
+ },
+ goodsOpt(type, id) {
+ let that = this;
+ switch (type) {
+ case 'create':
+ Fast.api.open('shopro/goods/add', '商品详情', {
+ callback() {
+ that.getGoodsData();
+ }
+ })
+ break;
+ case 'edit':
+ Fast.api.open('shopro/goods/edit/ids/' + id + "?id=" + id + "&type=edit", '商品详情', {
+ callback() {
+ that.getGoodsData();
+ }
+ })
+ break;
+ case 'down':
+ let idArr = []
+ if (that.multipleSelection.length > 0) {
+ that.multipleSelection.forEach(i => {
+ idArr.push(i.id)
+ })
+ let idss = idArr.join(',')
+ that.editStatus(idss, 'down')
+ }
+ break;
+ case 'up':
+ let idArrup = []
+ if (that.multipleSelection.length > 0) {
+ that.multipleSelection.forEach(i => {
+ idArrup.push(i.id)
+ })
+ let idup = idArrup.join(',')
+ that.editStatus(idup, 'up')
+ }
+ break;
+ case 'del':
+ let ids;
+ if (id) {
+ ids = id;
+ } else {
+ let idArr = []
+ if (that.multipleSelection.length > 0) {
+ that.multipleSelection.forEach(i => {
+ idArr.push(i.id)
+ })
+ ids = idArr.join(',')
+ }
+ }
+ if (ids) {
+ that.$confirm('此操作将删除商品, 是否继续?', '提示', {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ type: 'warning'
+ }).then(() => {
+ Fast.api.ajax({
+ url: 'shopro/goods/del/ids/' + ids,
+ loading: true,
+ type: 'GET'
+ }, function (ret, res) {
+ that.getGoodsData();
+ return false;
+ })
+ }).catch(() => {
+ this.$message({
+ type: 'info',
+ message: '已取消删除'
+ });
+ });
+ }
+ break;
+ case 'copy':
+ Fast.api.open('shopro/goods/edit/ids/' + id + "?id=" + id + "&type=copy", '商品详情', {
+ callback() {
+ that.getGoodsData();
+ }
+ })
+ break;
+ default:
+ }
+ },
+ popoverOpt(index) {
+ this.currentIndex = index;
+ },
+ hideup() {
+ this.currentIndex = null;
+ },
+ sortOrder(sort, order) {
+ this.sort = sort;
+ this.order = order;
+ this.getGoodsData();
+ },
+ goRecycle() {
+ Fast.api.open('shopro/goods/recyclebin', '查看回收站')
+ },
+ goRefresh() {
+ this.getGoodsData();
+ },
+ handleSelectionChange(val) {
+ this.multipleSelection = val;
+ },
+ handleSizeChange(val) {
+ this.offset = 0
+ this.limit = val;
+ this.getGoodsData()
+ },
+ handleCurrentChange(val) {
+ this.offset = (val - 1) * this.limit;
+ this.getGoodsData()
+ },
+ editStatus(id, type) {
+ let that = this;
+ Fast.api.ajax({
+ url: `shopro/goods/setStatus/ids/${id}/status/${type}`,
+ loading: true,
+ }, function (ret, res) {
+ that.getGoodsData();
+ that.currentIndex = null;
+ return false;
+ })
+ },
+ },
+ watch: {
+ activeStatus(newVal, oldVal) {
+ if (newVal != oldVal) {
+ this.offset = 0;
+ this.limit = 10;
+ this.getGoodsData();
+ }
+ },
+ searchKey(newVal, oldVal) {
+ if (newVal != oldVal) {
+ this.offset = 0;
+ this.limit = 10;
+ this.getGoodsData();
+ }
+ },
+ },
+ })
+ },
+ recyclebin: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ 'dragsort_url': ''
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: 'shopro/goods/recyclebin' + location.search,
+ pk: 'id',
+ sortName: 'deletetime',
+ columns: [
+ [{
+ checkbox: true
+ },
+ {
+ field: 'id',
+ title: __('Id')
+ },
+ {
+ field: 'title',
+ title: __('Title'),
+ align: 'left'
+ },
+ {
+ field: 'deletetime',
+ title: __('Deletetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'operate',
+ width: '130px',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ buttons: [{
+ name: 'Restore',
+ text: __('Restore'),
+ classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
+ icon: 'fa fa-rotate-left',
+ url: 'shopro/goods/restore',
+ refresh: true
+ },
+ {
+ name: 'Destroy',
+ text: __('Destroy'),
+ classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
+ icon: 'fa fa-times',
+ url: 'shopro/goods/destroy',
+ refresh: true
+ }
+ ],
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ Controller.initAddEdit(null, null, [], []);
+ },
+ edit: function () {
+ let id = window.location.search.replace("?", '').split('&')[0].split('=')[1];
+ let type = window.location.search.replace("?", '').split('&')[1].split('=')[1];
+ Controller.initAddEdit(id, type, Config.skuList, Config.skuPrice);
+ },
+ select: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/goods/index?page_type=select',
+ }
+ });
+
+ var idArr = [];
+ var selectArr = [];
+ var table = $("#table");
+
+ table.on('check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table', function (e, row) {
+ if (e.type == 'check' || e.type == 'uncheck') {
+ row = [row];
+ } else {
+ idArr = [];
+ selectArr = []
+ }
+ $.each(row, function (i, j) {
+ if (e.type.indexOf("uncheck") > -1) {
+ var index = idArr.indexOf(j.id);
+ var indexall = idArr.indexOf(j);
+ if (index > -1) {
+ idArr.splice(index, 1);
+ }
+ if (indexall > -1) {
+ selectArr.splice(index, 1);
+ }
+ } else {
+ idArr.indexOf(j.id) == -1 && idArr.push(j.id);
+ selectArr.indexOf(j) == -1 && selectArr.push(j);
+ }
+ });
+ });
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ sortName: 'id',
+ showToggle: false,
+ showExport: false,
+ columns: [
+ [{
+ field: 'state',
+ checkbox: true,
+ },
+ {
+ field: 'title',
+ title: __('Title'),
+ align: 'left'
+ },
+ {
+ field: 'image',
+ title: __('Image'),
+ operate: false,
+ events: Table.api.events.image,
+ formatter: Table.api.formatter.image
+ },
+ {
+ field: 'status_text',
+ title: __('Status'),
+ // formatter: Table.api.formatter.status,
+ },
+ {
+ field: 'createtime',
+ title: __('Createtime'),
+ formatter: Table.api.formatter.datetime,
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ sortable: true
+ },
+ {
+ field: 'operate',
+ title: __('Operate'),
+ events: {
+ 'click .btn-chooseone': function (e, value, row, index) {
+ var multiple = Backend.api.query('multiple');
+ multiple = multiple == 'true' ? true : false;
+ row.ids = row.id.toString()
+ Fast.api.close({
+ data: row,
+ multiple: multiple
+ });
+ },
+ },
+ formatter: function () {
+ return '
' + __('Choose') + '';
+ }
+ }
+ ]
+ ]
+ });
+
+ // 选中多个
+ $(document).on("click", ".btn-choose-multi", function () {
+ if (Backend.api.query('type') == 'activity') {
+ var multiple = Backend.api.query('multiple');
+ multiple = multiple == 'true' ? true : false;
+ Fast.api.close({
+ data: selectArr,
+ multiple: multiple
+ });
+ } else {
+ let row = {}
+ var multiple = Backend.api.query('multiple');
+ multiple = multiple == 'true' ? true : false;
+ row.ids = idArr.join(",")
+ Fast.api.close({
+ data: row,
+ multiple: multiple
+ });
+ }
+
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ //绑定TAB事件
+ $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
+ // var options = table.bootstrapTable(tableOptions);
+ var typeStr = $(this).attr("href").replace('#', '');
+ var options = table.bootstrapTable('getOptions');
+ options.pageNumber = 1;
+ options.queryParams = function (params) {
+ // params.filter = JSON.stringify({type: typeStr});
+ params.type = typeStr;
+ params.status = typeStr.replace('t-', '');
+ return params;
+ };
+ table.bootstrapTable('refresh', {});
+ return false;
+
+ });
+ require(['upload'], function (Upload) {
+ Upload.api.plupload($("#toolbar .plupload"), function () {
+ $(".btn-refresh").trigger("click");
+ });
+ });
+
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ },
+ initAddEdit: function (id, type, skuList, skuPrice) {
+ //vue Sku添加页 添加规格和价格数据
+ var goodsDetail = new Vue({
+ el: "#goodsDetail",
+ data() {
+ return {
+ editId: id,
+ type: type,
+
+ stepActive: 1,
+ goodsDetail: {},
+ goodsDetailMsg: {
+ category_ids: '',
+ category_ids_arr: [],
+ content: '',
+ dispatch_ids: '',
+ dispatch_ids_arr: [],
+ dispatch_type: '',
+ dispatch_type_arr: [],
+ image: '',
+ images: '',
+ // images_arr: [],
+ is_sku: 0,
+ original_price: '',
+ params: '',
+ params_arr: [],
+ price: '',
+ service_ids: '',
+ service_ids_arr: [],
+ show_sales: '',
+ status: 'up',
+ subtitle: '',
+ title: '',
+ type: 'normal',
+ views: '',
+ weigh: '',
+ weight: '',
+ stock: '',
+ sn: '',
+ },
+ rules: {
+ title: [{
+ required: true,
+ message: '请输入商品标题',
+ trigger: 'blur'
+ }],
+ subtitle: [{
+ required: true,
+ message: '请输入商品副标题',
+ trigger: 'blur'
+ }],
+ status: [{
+ required: true,
+ message: '请选择商品状态',
+ trigger: 'blur'
+ }],
+ image: [{
+ required: true,
+ message: '请上传商品主图',
+ trigger: 'change'
+ }],
+ images: [{
+ required: true,
+ message: '请上传商品轮播图',
+ trigger: 'change'
+ }],
+ category_ids_arr: [{
+ required: true,
+ message: '请选择商品分类',
+ trigger: 'change'
+ }],
+ dispatch_type: [{
+ required: true,
+ message: '请选择配送方式',
+ trigger: 'blur'
+ }],
+ dispatch_ids_arr: [{
+ required: true,
+ message: '请选择运费模板',
+ trigger: 'blur'
+ }],
+ is_sku: [{
+ required: true,
+ message: '请选择商品规格',
+ trigger: 'blur'
+ }],
+ price: [{
+ required: true,
+ message: '请输入价格',
+ trigger: 'blur'
+ }],
+ original_price: [{
+ required: true,
+ message: '请输入原价',
+ trigger: 'blur'
+ }],
+ weight: [{
+ required: true,
+ message: '请输入重量',
+ trigger: 'blur'
+ }],
+ stock: [{
+ required: true,
+ message: '请输入库存',
+ trigger: 'blur'
+ }],
+ sn: [{
+ required: true,
+ message: '请输入编号',
+ trigger: 'blur'
+ }],
+ service_ids_arr: [{
+ required: true,
+ message: '请选择服务标签',
+ trigger: 'blur'
+ }]
+ },
+ //选择分类
+ categoryOptions: [],
+
+ //服务
+ serviceOptions: [],
+ dispatchType: [],
+ dispatchOptions: [],
+
+ upload: Config.moduleurl,
+ editor: null,
+
+ //多规格
+ skuList: [],
+ // skuListLeng:0,
+ skuPrice: [],
+ skuListData: '',
+ skuPriceData: '',
+ skuModal: '',
+ childrenModal: [],
+ countId: 1,
+ allEditSkuName: '',
+ isEditInit: false, // 编辑时候初始化是否完成
+ isResetSku: 0,
+ allEditPopover: {
+ price: false,
+ stock: false,
+ weight: false,
+ sn: false,
+ },
+ allEditDatas: "",
+ }
+ },
+ created() {
+ if (this.editId) {
+ this.getEditData();
+ } else {
+ this.goodsDetail = JSON.parse(JSON.stringify(this.goodsDetailMsg));
+ this.getInit([], [])
+ }
+ this.getServiceOptions();
+ this.getDispatchType();
+ this.getCategoryOptions();
+ },
+ methods: {
+ getInit(skuList, skuPrice) {
+ // 记录每个规格项真实 id,对应的临时 id
+ let tempIdArr = {};
+ for (let i in skuList) {
+ // 为每个 规格增加当前页面自增计数器,比较唯一用
+ skuList[i]['temp_id'] = this.countId++
+ for (let j in skuList[i]['children']) {
+ // 为每个 规格项增加当前页面自增计数器,比较唯一用
+ skuList[i]['children'][j]['temp_id'] = this.countId++
+
+ // 记录规格项真实 id 对应的 临时 id
+ tempIdArr[skuList[i]['children'][j]['id']] = skuList[i]['children'][j]['temp_id']
+ }
+ }
+ // for (let i in skuPrice) {
+ for (var i=0;i
{
+ // 延迟触发更新下面列表
+ this.isEditInit = true;
+ }, 200)
+ },
+ getEditData() {
+ let that = this;
+ Fast.api.ajax({
+ url: 'shopro/goods/detail/ids/' + that.editId,
+ loading: true,
+ }, function (ret, res) {
+ that.goodsDetail = res.data.detail;
+ that.getInit(res.data.skuList, res.data.skuPrice);
+ return false;
+ })
+ },
+ submitForm(formName) {
+ this.$refs[formName].validate((valid) => {
+ if (valid) {
+ let that = this;
+ let arrForm = JSON.parse(JSON.stringify(that.goodsDetail));
+ let categoryArr = []
+ arrForm.category_ids_arr.forEach(i => {
+ categoryArr.push(i[i.length - 1])
+ })
+ arrForm.category_ids = categoryArr.join(',');
+ arrForm.params = JSON.stringify(arrForm.params_arr);
+ arrForm.content=$("#c-content").val();
+ delete arrForm.deletetime;
+ delete arrForm.updatetime;
+ delete arrForm.createtime;
+ if (arrForm.is_sku == 0) {
+ that.skuList = [];
+ that.skuPrice = [];
+ }
+ if (that.editId && that.type == 'edit') {
+ Fast.api.ajax({
+ url: 'shopro/goods/edit/ids/' + that.editId,
+ loading: true,
+ data: {
+ row: arrForm,
+ sku: {
+ listData: JSON.stringify(that.skuList),
+ priceData: JSON.stringify(that.skuPrice)
+ }
+ }
+ }, function (ret, res) {
+ Fast.api.close();
+ })
+ } else {
+ if (this.type == 'copy') {
+ delete arrForm.id
+ }
+ Fast.api.ajax({
+ url: 'shopro/goods/add',
+ loading: true,
+ data: {
+ row: arrForm,
+ sku: {
+ listData: JSON.stringify(that.skuList),
+ priceData: JSON.stringify(that.skuPrice)
+ }
+ }
+ }, function (ret, res) {
+ Fast.api.close();
+ })
+ }
+
+ } else {
+ console.log('error submit!!');
+ return false;
+ }
+ });
+ },
+ resetForm(formName) {
+ this.$refs[formName].resetFields();
+ },
+ addImg(type, index, multiple) {
+ let that = this;
+ parent.Fast.api.open("general/attachment/select?multiple=" + multiple, "选择图片", {
+ callback: function (data) {
+ switch (type) {
+ case "image":
+ that.goodsDetail.image = data.url;
+ break;
+ case "images":
+ that.goodsDetail.images = that.goodsDetail.images ? that.goodsDetail.images + ',' + data.url : data.url;
+ break;
+ case "sku":
+ that.skuPrice[index].image = data.url;
+ break;
+ }
+ }
+ });
+ return false;
+ },
+ delImg(type, index) {
+ let that = this;
+ switch (type) {
+ case "image":
+ that.goodsDetail.image = '';
+ break;
+ case "images":
+ let arr = that.goodsDetail.images.split(',');
+ arr.splice(index, 1);
+ that.goodsDetail.images = arr.join(',')
+ break;
+ case "sku":
+ that.skuPrice[index].image = '';
+ break;
+
+ }
+ },
+ changeGoodsType(type) {
+ this.goodsDetail.type = type;
+ this.getDispatchOptions();
+ this.goodsDetail.dispatch_ids_arr = [];
+ this.goodsDetail.dispatch_ids = '';
+ },
+ categoryChange(val) {
+ this.goodsDetail.category_ids = val.join(',');
+ },
+ serviceChange(val) {
+ this.goodsDetail.service_ids = val.join(',');
+ },
+ dispatchChange(val) {
+ this.goodsDetail.dispatch_ids = val.join(',');
+ },
+ dispatchTypeChange(val) {
+ this.goodsDetail.dispatch_type = val.join(',');
+ this.getDispatchOptions();
+ },
+ getCategoryOptions() {
+ let that = this;
+ Fast.api.ajax({
+ url: 'shopro/category/getTree',
+ loading: false,
+ }, function (ret, res) {
+ that.categoryOptions = res.data
+ return false;
+ })
+ },
+ getDispatchType() {
+ let that = this;
+ Fast.api.ajax({
+ url: 'shopro/dispatch/dispatch/typeList',
+ loading: false,
+ }, function (ret, res) {
+ let arr = []
+ for (key in res.data) {
+ arr.push({
+ id: key,
+ name: res.data[key]
+ })
+ }
+ that.dispatchType = arr;
+ return false;
+ })
+ },
+ getDispatchOptions() {
+ let that = this;
+ Fast.api.ajax({
+ url: 'shopro/dispatch/dispatch/all',
+ loading: false,
+ type: 'GET',
+ data: {
+ type: that.goodsDetail.dispatch_type
+ }
+ }, function (ret, res) {
+ that.dispatchOptions = res.data
+ return false;
+ })
+ },
+ getServiceOptions() {
+ let that = this;
+ Fast.api.ajax({
+ url: 'shopro/goods_service/all',
+ loading: false,
+ }, function (ret, res) {
+ that.serviceOptions = res.data
+ return false;
+ })
+ },
+ gotoback(formName) {
+ this.$refs[formName].validate((valid) => {
+ if (valid) {
+ this.stepActive++;
+ } else {
+ console.log('error submit!!');
+ return false;
+ }
+ });
+ },
+ gonextback() {
+ this.stepActive--;
+ },
+ addParams() {
+ this.goodsDetail.params_arr.push({
+ title: '',
+ content: ''
+ })
+ },
+ delParams(index) {
+ this.goodsDetail.params_arr.splice(index, 1)
+ },
+
+ //添加主规格
+ addMainSku() {
+ // if (this.skuModal !== '') {
+ this.skuList.push({
+ id: 0,
+ temp_id: this.countId++,
+ name: this.skuModal,
+ pid: 0,
+ children: []
+ })
+ this.skuModal = '';
+ // this.skuPrice = [] // 新添加的主规格不清空 skuPrice,当添加主规格第一个子规格的时候清空
+ this.buildSkuPriceTable()
+ // }
+ },
+ //添加子规格
+ addChildrenSku(k) {
+ // if (this.childrenModal[k] !== '') {
+ // 检测当前子规格是否已经被添加过了
+ let isExist = false
+ this.skuList[k].children.forEach(e => {
+ if (e.name == this.childrenModal[k] && e.name != "") {
+ isExist = true
+ }
+ })
+
+ if (isExist) {
+ Toastr.error('子规格已存在');
+ return false;
+ }
+
+ this.skuList[k].children.push({
+ id: 0,
+ temp_id: this.countId++,
+ name: this.childrenModal[k],
+ pid: this.skuList[k].id,
+ })
+
+ this.childrenModal[k] = '';
+
+ // 如果是添加的第一个子规格,清空 skuPrice
+ if (this.skuList[k].children.length == 1) {
+ this.skuPrice = [] // 规格大变化,清空skuPrice
+ this.isResetSku = 1; // 重置规格
+ }
+
+ this.buildSkuPriceTable()
+ // }
+ },
+ //删除主规格
+ deleteMainSku(k) {
+ let data = this.skuList[k]
+
+ // 删除主规格
+ this.skuList.splice(k, 1)
+
+ // 如果当前删除的主规格存在子规格,则清空 skuPrice, 不存在子规格则不清空
+ if (data.children.length > 0) {
+ this.skuPrice = [] // 规格大变化,清空skuPrice
+ this.isResetSku = 1; // 重置规格
+ }
+
+ this.buildSkuPriceTable()
+ },
+ //删除子规格
+ deleteChildrenSku(k, i) {
+ let data = this.skuList[k].children[i]
+ this.skuList[k].children.splice(i, 1)
+
+ // 查询 skuPrice 中包含被删除的的子规格的项,然后移除
+ let deleteArr = []
+ this.skuPrice.forEach((item, index) => {
+ item.goods_sku_text.forEach((e, i) => {
+ if (e == data.name) {
+ deleteArr.push(index)
+ }
+ })
+ })
+ deleteArr.sort(function (a, b) {
+ return b - a;
+ })
+ // 移除有相关子规格的项
+ deleteArr.forEach((i, e) => {
+ this.skuPrice.splice(i, 1)
+ })
+
+ // 当前规格项,所有子规格都被删除,清空 skuPrice
+ if (this.skuList[k].children.length <= 0) {
+ this.skuPrice = [] // 规格大变化,清空skuPrice
+ this.isResetSku = 1; // 重置规格
+ }
+ this.buildSkuPriceTable()
+ },
+ editStatus(i) {
+ if (this.skuPrice[i].status == 'up') {
+ this.skuPrice[i].status = 'down'
+ } else {
+ this.skuPrice[i].status = 'up'
+ }
+
+ },
+ //组合新的规格价格库存重量编码图片
+ buildSkuPriceTable() {
+ let arr = [];
+ //遍历sku子规格生成新数组,然后执行递归笛卡尔积
+ this.skuList.forEach((s1, k1) => {
+ let children = s1.children;
+ let childrenIdArray = [];
+ if (children.length > 0) {
+ children.forEach((s2, k2) => {
+ childrenIdArray.push(s2.temp_id);
+ })
+
+ // 如果 children 子规格数量为 0,则不渲染当前规格, (相当于没有这个主规格)
+ arr.push(childrenIdArray);
+ }
+ })
+
+ this.recursionSku(arr, 0, []);
+ },
+ //递归找笛卡尔规格集合
+ recursionSku(arr, k, temp) {
+ if (k == arr.length && k != 0) {
+ let tempDetail = []
+ let tempDetailIds = []
+
+ temp.forEach((item, index) => {
+ for (let sku of this.skuList) {
+ for (let child of sku.children) {
+ if (item == child.temp_id) {
+ tempDetail.push(child.name)
+ tempDetailIds.push(child.temp_id)
+ }
+ }
+ }
+ })
+
+ let flag = false // 默认添加新的
+ for (let i = 0; i < this.skuPrice.length; i++) {
+ if (this.skuPrice[i].goods_sku_temp_ids.join(',') == tempDetailIds.join(',')) {
+ flag = i
+ break;
+ }
+ }
+
+ if (flag === false) {
+ this.skuPrice.push({
+ id: 0,
+ temp_id: this.skuPrice.length + 1,
+ goods_sku_ids: '',
+ goods_id: 0,
+ weigh: 0,
+ image: '',
+ stock: 0,
+ price: 0,
+ sn: '',
+ weight: 0,
+ status: 'up',
+ goods_sku_text: tempDetail,
+ goods_sku_temp_ids: tempDetailIds,
+ });
+ } else {
+ this.skuPrice[flag].goods_sku_text = tempDetail
+ this.skuPrice[flag].goods_sku_temp_ids = tempDetailIds
+ }
+
+ return;
+ }
+ if (arr.length) {
+ for (let i = 0; i < arr[k].length; i++) {
+ temp[k] = arr[k][i]
+ this.recursionSku(arr, k + 1, temp)
+ }
+ }
+ },
+ allEditData(type, opt) {
+ switch (opt) {
+ case 'define':
+ this.skuPrice.forEach(i => {
+ i[type] = this.allEditDatas;
+ })
+ this.allEditDatas = ''
+ this.allEditPopover[type] = false;
+ break;
+ case 'cancel':
+ this.allEditDatas = ''
+ this.allEditPopover[type] = false;
+ break;
+ }
+ }
+ },
+ watch: {
+ stepActive(newVal) {
+ this.editor = null;
+ },
+ goodsDetail: {
+ handler: function (newVal, oldVal) {
+ if (newVal.dispatch_type != oldVal.dispatch_type) {
+ this.getDispatchOptions();
+ }
+ },
+ deep: true
+ },
+ skuList: {
+ handler(newName, oldName) {
+ if (this.isEditInit) { // 编辑初始化的时候会修改 skuList 但这时候不触发更新
+ this.buildSkuPriceTable();
+ }
+ },
+ deep: true
+ }
+ },
+ })
+ Controller.api.bindevent();
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/goods_comment.js b/public/assets/js/backend/shopro/goods_comment.js
new file mode 100644
index 000000000..cb2711f97
--- /dev/null
+++ b/public/assets/js/backend/shopro/goods_comment.js
@@ -0,0 +1,124 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/goods_comment/index' + location.search,
+ add_url: 'shopro/goods_comment/add',
+ edit_url: 'shopro/goods_comment/edit',
+ del_url: 'shopro/goods_comment/del',
+ multi_url: 'shopro/goods_comment/multi',
+ table: 'shopro_goods_comment',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'goods_id', title: __('Goods_id') ,visible: false},
+ {field: 'shoprogoods.title', title: __('商品')},
+ {field: 'user.nickname', title: __('评论用户')},
+ {field: 'order_id', title: __('Order_id') ,visible: false},
+ {field: 'order_item_id', title: __('Order_item_id') ,visible: false},
+ {field: 'user_id', title: __('User_id') ,visible: false},
+ {field: 'level', title: __('Level')},
+ {field: 'content', title: __('Content')},
+ {field: 'images', title: __('Images'), events: Table.api.events.image, formatter: Table.api.formatter.images},
+ {field: 'status', title: __('Status'), searchList: {"show":__('Status show'),"hidden":__('Status hidden')}, formatter: Table.api.formatter.status},
+ // {field: 'admin_id', title: __('Admin_id') ,visible: false},
+ // {field: 'admin.nickname', title: __('回复员工')},
+ // {field: 'reply_content', title: __('Reply_content')},
+ // {field: 'replytime', title: __('Replytime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'createtime', title: __('Createtime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ recyclebin: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ 'dragsort_url': ''
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: 'shopro/goods_comment/recyclebin' + location.search,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {
+ field: 'deletetime',
+ title: __('Deletetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'operate',
+ width: '130px',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ buttons: [
+ {
+ name: 'Restore',
+ text: __('Restore'),
+ classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
+ icon: 'fa fa-rotate-left',
+ url: 'shopro/goods_comment/restore',
+ refresh: true
+ },
+ {
+ name: 'Destroy',
+ text: __('Destroy'),
+ classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
+ icon: 'fa fa-times',
+ url: 'shopro/goods_comment/destroy',
+ refresh: true
+ }
+ ],
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/goods_service.js b/public/assets/js/backend/shopro/goods_service.js
new file mode 100644
index 000000000..878c07174
--- /dev/null
+++ b/public/assets/js/backend/shopro/goods_service.js
@@ -0,0 +1,114 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/goods_service/index' + location.search,
+ add_url: 'shopro/goods_service/add',
+ edit_url: 'shopro/goods_service/edit',
+ del_url: 'shopro/goods_service/del',
+ multi_url: 'shopro/goods_service/multi',
+ table: 'shopro_goods_service',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'name', title: __('Name')},
+ {field: 'image', title: __('Image'), events: Table.api.events.image, formatter: Table.api.formatter.image},
+ {field: 'description', title: __('Description')},
+ {field: 'createtime', title: __('Createtime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ recyclebin: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ 'dragsort_url': ''
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: 'shopro/goods_service/recyclebin' + location.search,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'name', title: __('Name'), align: 'left'},
+ {
+ field: 'deletetime',
+ title: __('Deletetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'operate',
+ width: '130px',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ buttons: [
+ {
+ name: 'Restore',
+ text: __('Restore'),
+ classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
+ icon: 'fa fa-rotate-left',
+ url: 'shopro/goods_service/restore',
+ refresh: true
+ },
+ {
+ name: 'Destroy',
+ text: __('Destroy'),
+ classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
+ icon: 'fa fa-times',
+ url: 'shopro/goods_service/destroy',
+ refresh: true
+ }
+ ],
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/goods_sku.js b/public/assets/js/backend/shopro/goods_sku.js
new file mode 100644
index 000000000..5192617f7
--- /dev/null
+++ b/public/assets/js/backend/shopro/goods_sku.js
@@ -0,0 +1,53 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/goods_sku/index' + location.search,
+ add_url: 'shopro/goods_sku/add',
+ edit_url: 'shopro/goods_sku/edit',
+ del_url: 'shopro/goods_sku/del',
+ multi_url: 'shopro/goods_sku/multi',
+ table: 'shopro_goods_sku',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'weigh',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'name', title: __('Name')},
+ {field: 'pid', title: __('Pid')},
+ {field: 'goods_id', title: __('Goods_id')},
+ {field: 'weigh', title: __('Weigh')},
+ {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/goods_sku_price.js b/public/assets/js/backend/shopro/goods_sku_price.js
new file mode 100644
index 000000000..bf6713109
--- /dev/null
+++ b/public/assets/js/backend/shopro/goods_sku_price.js
@@ -0,0 +1,120 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/goods_sku_price/index' + location.search,
+ add_url: 'shopro/goods_sku_price/add',
+ edit_url: 'shopro/goods_sku_price/edit',
+ del_url: 'shopro/goods_sku_price/del',
+ multi_url: 'shopro/goods_sku_price/multi',
+ table: 'shopro_goods_sku_price',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'weigh',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'goods_sku_ids', title: __('Goods_sku_ids')},
+ {field: 'goods_id', title: __('Goods_id')},
+ {field: 'weigh', title: __('Weigh')},
+ {field: 'image', title: __('Image'), events: Table.api.events.image, formatter: Table.api.formatter.image},
+ {field: 'stock', title: __('Stock')},
+ {field: 'sales', title: __('Sales')},
+ {field: 'sn', title: __('Sn')},
+ {field: 'weight', title: __('Weight')},
+ {field: 'price', title: __('Price'), operate:'BETWEEN'},
+ {field: 'status', title: __('Status'), formatter: Table.api.formatter.status},
+ {field: 'createtime', title: __('Createtime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ recyclebin: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ 'dragsort_url': ''
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: 'shopro/goods_sku_price/recyclebin' + location.search,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {
+ field: 'deletetime',
+ title: __('Deletetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'operate',
+ width: '130px',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ buttons: [
+ {
+ name: 'Restore',
+ text: __('Restore'),
+ classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
+ icon: 'fa fa-rotate-left',
+ url: 'shopro/goods_sku_price/restore',
+ refresh: true
+ },
+ {
+ name: 'Destroy',
+ text: __('Destroy'),
+ classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
+ icon: 'fa fa-times',
+ url: 'shopro/goods_sku_price/destroy',
+ refresh: true
+ }
+ ],
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/goodsservice.js b/public/assets/js/backend/shopro/goodsservice.js
new file mode 100644
index 000000000..e836f33a0
--- /dev/null
+++ b/public/assets/js/backend/shopro/goodsservice.js
@@ -0,0 +1,114 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/goodsservice/index' + location.search,
+ add_url: 'shopro/goodsservice/add',
+ edit_url: 'shopro/goodsservice/edit',
+ del_url: 'shopro/goodsservice/del',
+ multi_url: 'shopro/goodsservice/multi',
+ table: 'shopro_goods_service',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'name', title: __('Name')},
+ {field: 'image', title: __('Image'), events: Table.api.events.image, formatter: Table.api.formatter.image},
+ {field: 'description', title: __('Description')},
+ {field: 'createtime', title: __('Createtime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ recyclebin: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ 'dragsort_url': ''
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: 'shopro/goodsservice/recyclebin' + location.search,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'name', title: __('Name'), align: 'left'},
+ {
+ field: 'deletetime',
+ title: __('Deletetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'operate',
+ width: '130px',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ buttons: [
+ {
+ name: 'Restore',
+ text: __('Restore'),
+ classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
+ icon: 'fa fa-rotate-left',
+ url: 'shopro/goodsservice/restore',
+ refresh: true
+ },
+ {
+ name: 'Destroy',
+ text: __('Destroy'),
+ classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
+ icon: 'fa fa-times',
+ url: 'shopro/goodsservice/destroy',
+ refresh: true
+ }
+ ],
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/link.js b/public/assets/js/backend/shopro/link.js
new file mode 100644
index 000000000..2e313807b
--- /dev/null
+++ b/public/assets/js/backend/shopro/link.js
@@ -0,0 +1,307 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/link/index' + location.search,
+ add_url: 'shopro/link/add',
+ edit_url: 'shopro/link/edit',
+ del_url: 'shopro/link/del',
+ multi_url: 'shopro/link/multi',
+ table: 'shopro_link',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ { checkbox: true },
+ { field: 'id', title: __('Id') },
+ { field: 'name', title: __('Name') },
+ { field: 'path', title: __('Path') },
+ { field: 'group', title: __('Group') },
+ { field: 'createtime', title: __('Createtime'), operate: 'RANGE', addclass: 'datetimerange', formatter: Table.api.formatter.datetime },
+ { field: 'updatetime', title: __('Updatetime'), operate: 'RANGE', addclass: 'datetimerange', formatter: Table.api.formatter.datetime },
+ { field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+
+ //绑定TAB事件
+ $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
+ // var options = table.bootstrapTable(tableOptions);
+ var typeStr = $(this).attr("href").replace('#', '');
+ var options = table.bootstrapTable('getOptions');
+ options.pageNumber = 1;
+ options.queryParams = function (params) {
+ // params.filter = JSON.stringify({type: typeStr});
+ params.group = typeStr;
+
+ return params;
+ };
+ table.bootstrapTable('refresh', {});
+ return false;
+
+ });
+
+ },
+ select: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/link/select',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ sortName: 'id',
+ showToggle: false,
+ showExport: false,
+ columns: [
+ [
+ { field: 'state', checkbox: true, },
+ { field: 'group', title: '组名', operate: false, searchList: Config.searchList, formatter: Table.api.formatter.normal },
+ { field: 'name', title: __('Name'), align: 'left' },
+ { field: 'path', title: '路径' },
+ {
+ field: 'operate', title: __('Operate'), events: {
+ 'click .btn-chooseone': function (e, value, row, index) {
+ var multiple = Backend.api.query('multiple');
+ multiple = multiple == 'true' ? true : false;
+ row.path_name=row.group?row.group+'-'+row.name:row.name
+ switch (row.path) {
+ case '/pages/app/coupon/detail':
+ Fast.api.open("shopro/coupons/select", __('Choose'), {
+ callback: function (data) {
+ row.path_name +='-'+data.data.name
+ row.path +='?id=' + data.data.id.toString()
+ Fast.api.close({ data: row, multiple: multiple });
+ }
+ });
+ break;
+ case '/pages/goods/list':
+ Fast.api.open("shopro/category/select", __('Choose'), {
+ callback: function (data) {
+ row.path_name +='-'+data.data.category_name
+ row.path +='?id=' + data.data.id.toString()
+ Fast.api.close({ data: row, multiple: multiple });
+ }
+ });
+ break;
+ case '/pages/goods/detail/index':
+ Fast.api.open("shopro/goods/select", __('Choose'), {
+ callback: function (data) {
+ row.path_name +=data.data.name?'-'+data.data.name:''
+ row.path +='?id=' + data.data.id.toString()
+ Fast.api.close({ data: row, multiple: multiple });
+ }
+ });
+ break;
+ case '/pages/public/richtext':
+ Fast.api.open("shopro/richtext/select", __('Choose'), {
+ callback: function (data) {
+ row.path_name +=data.data.name?'-'+data.data.name:''
+ row.path +='?id=' + data.data.id.toString()
+ Fast.api.close({ data: row, multiple: multiple });
+ }
+ });
+ break;
+ case '/pages/public/poster/index':
+ layer.open({
+ title:"海报信息",
+ type: 1,
+ skin: 'layui-layer-rim', //加上边框
+ area: ['300px', '200px'], //宽高
+ content: `
+ `
+ });
+ $(document).on("click","#user",function(){
+ $("#user").css({'color':"#f00"});
+ $("#goods").css({'color':"#000"})
+ row.path_name ='个人海报'
+ row.path=row.path+'?posterType=user'
+ Fast.api.close({ data: row, multiple: multiple });
+ })
+ $(document).on("click","#goods",function(){
+ $("#goods").css({'color':"#f00"});
+ $("#user").css({'color':"#000"})
+ Fast.api.open("shopro/goods/select", __('Choose'), {
+ callback: function (data) {
+ row.path_name ='商品海报'
+ row.path +='?posterType=goods&id=' + data.data.id.toString()
+ Fast.api.close({ data: row, multiple: multiple });
+ }
+ });
+ })
+ break;
+ case '/pages/index/view':
+ Fast.api.open("shopro/decorate/select?type=custom", __('Choose'), {
+ callback: function (data) {
+ row.name +=data.data.name?'-'+data.data.name:'';
+ row.path_name=row.name
+ row.path +='?id=' + data.data.id.toString()
+ Fast.api.close({ data: row, multiple: multiple });
+ }
+ });
+ break;
+
+ default:
+ Fast.api.close({ data: row, multiple: multiple });
+
+
+ }
+ },
+ }, formatter: function () {
+ return ' ' + __('Choose') + ' ';
+ }
+ }
+ ]
+ ]
+ });
+
+ // 选中多个
+ $(document).on("click", ".btn-choose-multi", function () {
+ var pathArr = new Array();
+ var pathId= new Array();
+ $.each(table.bootstrapTable("getAllSelections"), function (i, j) {
+ pathArr.push(j.path);
+ pathId.push(j.id)
+ });
+ var multiple = Backend.api.query('multiple');
+ multiple = multiple == 'true' ? true : false;
+ let data={
+ path:pathArr.join(","),
+ pathId:pathId.join(",")
+ }
+ Fast.api.close({ data, multiple: multiple });
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ //绑定TAB事件
+ $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
+ // var options = table.bootstrapTable(tableOptions);
+ var typeStr = $(this).attr("href").replace('#', '');
+ var options = table.bootstrapTable('getOptions');
+ options.pageNumber = 1;
+ options.queryParams = function (params) {
+ // params.filter = JSON.stringify({type: typeStr});
+ params.group = typeStr;
+
+ return params;
+ };
+ table.bootstrapTable('refresh', {});
+ return false;
+
+ });
+ require(['upload'], function (Upload) {
+ Upload.api.plupload($("#toolbar .plupload"), function () {
+ $(".btn-refresh").trigger("click");
+ });
+ });
+
+ },
+ recyclebin: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ 'dragsort_url': ''
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: 'shopro/link/recyclebin' + location.search,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ { checkbox: true },
+ { field: 'id', title: __('Id') },
+ { field: 'name', title: __('Name'), align: 'left' },
+ {
+ field: 'deletetime',
+ title: __('Deletetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'operate',
+ width: '130px',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ buttons: [
+ {
+ name: 'Restore',
+ text: __('Restore'),
+ classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
+ icon: 'fa fa-rotate-left',
+ url: 'shopro/link/restore',
+ refresh: true
+ },
+ {
+ name: 'Destroy',
+ text: __('Destroy'),
+ classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
+ icon: 'fa fa-times',
+ url: 'shopro/link/destroy',
+ refresh: true
+ }
+ ],
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ $(document).on("click", ".goods-select", function () {
+ $(this).css("border", "1px solid #fb6638")
+ })
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/notification.js b/public/assets/js/backend/shopro/notification.js
new file mode 100644
index 000000000..afa352780
--- /dev/null
+++ b/public/assets/js/backend/shopro/notification.js
@@ -0,0 +1,242 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/notification/config/index' + location.search,
+ add_url: 'shopro/notification/config/add',
+ edit_url: 'shopro/notification/config/edit',
+ del_url: 'shopro/notification/config/del',
+ multi_url: 'shopro/notification/config/multi',
+ table: 'shopro_notification_config',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [{
+ checkbox: true
+ },
+ {
+ field: 'id',
+ title: __('Id')
+ },
+ {
+ field: 'platform',
+ title: __('Platform')
+ },
+ {
+ field: 'name',
+ title: __('Name')
+ },
+ {
+ field: 'event',
+ title: __('Event')
+ },
+ {
+ field: 'status',
+ title: __('Status'),
+ searchList: {
+ "0": __('Status 0'),
+ "1": __('Status 1')
+ },
+ formatter: Table.api.formatter.status
+ },
+ {
+ field: 'createtime',
+ title: __('Createtime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'updatetime',
+ title: __('Updatetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'operate',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ config: function () {
+ var notification_index = new Vue({
+ el: "#notification-index",
+ data() {
+ return {
+ tipCloseFlag: true,
+ notificationDialog: false,
+ notificationData: [],
+ notificationForm: {},
+ editIndex:null
+ }
+ },
+ mounted() {
+ this.getnotificationData();
+ },
+ methods: {
+ getnotificationData(){
+ let that=this;
+ Fast.api.ajax({
+ url: 'shopro/notification/config',
+ type:'GET',
+ loading: true,
+ data: {}
+ }, function (ret, res) {
+ that.notificationData=res.data;
+ return false;
+ })
+ },
+ tipClose() {
+ this.tipCloseFlag = false;
+ },
+ changeStatua(platform, event, name, status) {
+ let that = this;
+ Fast.api.ajax({
+ url: 'shopro/notification/set_status',
+ loading: true,
+ type: "POST",
+ data: {
+ platform: platform,
+ event: event,
+ name: name,
+ status: status
+ }
+ }, function (ret, res) {
+ that.getnotificationData();
+ })
+ },
+ fieldDel(index){
+ this.notificationForm.fields.splice(index,1)
+ },
+ notificationClose(type) {
+ let that = this;
+ that.notificationForm.template_id=that.notificationForm.template_id.replace(/\s*/g,"");
+ if (type == 'yes') {
+ Fast.api.ajax({
+ url: 'shopro/notification/set_template',
+ loading: true,
+ data: {
+ platform: that.editMsg.platform,
+ event: that.editMsg.event,
+ name: that.editMsg.name,
+ content: JSON.stringify(that.notificationForm)
+ }
+ }, function (ret, res) {
+ that.getnotificationData();
+ that.notificationDialog = false;
+ that.notificationForm = {};
+ that.editMsg={};
+ })
+ } else {
+ that.notificationForm = {};
+ that.editMsg={};
+ that.notificationDialog = false;
+ }
+ },
+ edit(index, type) {
+ this.editMsg=this.notificationData[index][type];
+ this.notificationForm = JSON.parse(JSON.stringify(this.notificationData[index][type].content_arr));
+ this.notificationDialog = true;
+ },
+ addfield() {
+ this.notificationForm.fields.push({
+ 'name': '',
+ 'template_field': '',
+ 'value': '',
+ });
+ },
+ },
+ })
+ },
+ recyclebin: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ 'dragsort_url': ''
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: 'shopro/notification/recyclebin' + location.search,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [{
+ checkbox: true
+ },
+ {
+ field: 'id',
+ title: __('Id')
+ },
+ {
+ field: 'deletetime',
+ title: __('Deletetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'operate',
+ width: '130px',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ buttons: [{
+ name: 'Restore',
+ text: __('Restore'),
+ classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
+ icon: 'fa fa-rotate-left',
+ url: 'shopro/notification/restore',
+ refresh: true
+ },
+ {
+ name: 'Destroy',
+ text: __('Destroy'),
+ classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
+ icon: 'fa fa-times',
+ url: 'shopro/notification/destroy',
+ refresh: true
+ }
+ ],
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/order/order.js b/public/assets/js/backend/shopro/order/order.js
new file mode 100644
index 000000000..51283e4f8
--- /dev/null
+++ b/public/assets/js/backend/shopro/order/order.js
@@ -0,0 +1,658 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ var vueOrder = new Vue({
+ el: "#order-con",
+ data() {
+ return {
+ screenType: false,
+ activeScreen: [],
+ selectDate: [],
+ orderScreenList: {},
+ orderSelectType: ['all', 'all', 'all', 'all', 'all'],
+ tableOrderStatus: '全部',
+ orderList: [],
+ multipleSelection: [],
+ searchKey: '',
+ dialogVisible: false,
+ deliverForm: {
+ express_ids: '',
+ express_name: '',
+ express_no: ''
+ },
+ disabledBtn: false,
+ //分页
+ currentPage: 1,
+ totalPage: 0,
+ offset: 0,
+ limit: 10,
+ dispatchList: [],
+ dispatchListItem: [],
+ orderStatus: {
+ '全部': 'all',
+ '已失效': 'invalid',
+ '已取消': 'cancel',
+ '待付款': 'nopay',
+ '已发货': 'noget',
+ '待发货': 'nosend',
+ '未评价': 'nocomment',
+ '售后': 'aftersale',
+ '已支付': 'payed',
+ '已完成': 'finish',
+ '退款': 'refund'
+ },
+ orderStatusSend: {
+ 'nosend': '待发货',
+ 'aftersale': '售后',
+ 'payed': '已支付',
+ 'refund': '退款'
+ },
+ totalStatus: '',
+ dialogOptVisible: false,
+ optList: [],
+ focusi: false,
+ }
+ },
+ mounted() {
+ if (decodeURI(window.location.search.substring(1).split('&')[0].split('=')[0]) == 'status') {
+ this.selectDate = decodeURI(window.location.search.substring(1).split('&')[1].split('=')[1]).split(' - ')
+ this.tableOrderStatus = this.orderStatusSend[decodeURI(window.location.search.substring(1).split('&')[0].split('=')[1])]
+ }
+ this.reqOrderList()
+ this.reqOrderScreenList()
+ },
+ methods: {
+ //筛选
+ changeSwitch() {
+ if (this.screenType) {
+ this.orderSelectType = ['all', 'all', 'all', 'all', 'all']
+ } else {
+ this.orderSelectType = []
+ }
+ },
+ changeSelectType(listIndex, findex, index) {
+ this.$set(this.orderSelectType, findex, this.orderScreenList[listIndex][index].type)
+ },
+ reqOrderScreenList() {
+ var that = this;
+ Fast.api.ajax({
+ url: 'shopro/order/order/getType',
+ loading: true,
+ type: 'GET',
+ data: {}
+ }, function (ret, res) {
+ that.orderScreenList = res.data
+ return false;
+ })
+ },
+ //导出
+ goExport() {
+ var that = this;
+ let selectDates = that.selectDate ? (that.selectDate.length > 0 ? moment(that.selectDate[0]).format("YYYY-MM-DD HH:mm:ss") + ' - ' + moment(that.selectDate[1]).format("YYYY-MM-DD HH:mm:ss") : '') : '';
+ window.location.href = "order/export?sort=id&order=desc&search=" + that.searchKey + "&offset=" + that.offset + "&limit=" + that.limit + "&type=" + that.orderSelectType[2] + "&pay_type=" + that.orderSelectType[3] + "&platform=" + that.orderSelectType[0] + "&activity_type=" + that.orderSelectType[4] + "&dispatch_type=" + that.orderSelectType[1] + "&status=" + that.orderStatus[that.tableOrderStatus] + "&datetimerange=" + selectDates;
+ },
+ //请求
+ reqOrderList() {
+ var that = this;
+ let selectDates = that.selectDate ? (that.selectDate.length > 0 ? moment(that.selectDate[0]).format("YYYY-MM-DD HH:mm:ss") + ' - ' + moment(that.selectDate[1]).format("YYYY-MM-DD HH:mm:ss") : '') : '';
+ Fast.api.ajax({
+ url: 'shopro/order/order/index',
+ loading: true,
+ type: 'GET',
+ data: {
+ sort: 'id',
+ order: 'desc',
+ search: that.searchKey,
+ offset: that.offset,
+ limit: that.limit,
+ type: that.orderSelectType[2],
+ pay_type: that.orderSelectType[3],
+ platform: that.orderSelectType[0],
+ activity_type: that.orderSelectType[4],
+ dispatch_type: that.orderSelectType[1],
+ status: that.orderStatus[that.tableOrderStatus],
+ datetimerange: selectDates
+ }
+ }, function (ret, res) {
+
+ that.orderList = res.data.rows;
+ that.totalPage = res.data.total;
+ that.focusi = false;
+ return false;
+ })
+ },
+ screenEmpty() {
+ this.orderSelectType = ['all', 'all', 'all', 'all', 'all']
+ },
+ handleSelectionChange(val) {
+ this.multipleSelection = val;
+ },
+ //分页(更换页面显示条数)
+ handleSizeChange(val) {
+ this.offset = 0
+ this.limit = val
+ this.reqOrderList()
+ },
+ //当前是第几页
+ handleCurrentChange(val) {
+ this.offset = (val - 1) * this.limit
+ this.reqOrderList()
+ },
+ goDetail(id) {
+ Fast.api.open('shopro/order/order/detail?id=' + id, "查看详情");
+
+ },
+ godeliver(item, index) {
+ this.dispatchList = item
+ this.dispatchListItem = []
+ this.dispatchListItem.push(item.item[index])
+ this.dialogVisible = true
+ },
+ handleClose() {
+ this.dialogVisible = false
+ this.deliverForm.express_ids = ''
+ this.deliverForm.express_name = '',
+ this.deliverForm.express_no = ''
+ },
+ deliverSubmit() {
+ this.dialogVisible = false
+ var that = this;
+ Fast.api.ajax({
+ url: `shopro/order/order/send/id/${that.dispatchList.id}/item_id/${that.deliverForm.express_ids}`,
+ loading: true,
+ data: {
+ express_name: that.deliverForm.express_name,
+ express_no: that.deliverForm.express_no
+ }
+ }, function (ret, res) {
+ that.orderGoodsList = [];
+ res.data.item.forEach(item => {
+ that.orderGoodsList.push(item)
+ });
+ that.reqOrderList();
+ that.deliverForm.express_ids = '';
+ that.deliverForm.express_name = '';
+ that.deliverForm.express_no = '';
+ })
+ },
+ deliverSelectionChange(val) {
+ let express_ids = []
+ val.forEach(i => {
+ express_ids.push(i.id)
+
+ })
+ this.deliverForm.express_ids = express_ids.join(',')
+ },
+ objectSpanMethod({
+ row,
+ column,
+ rowIndex,
+ columnIndex
+ }) {
+ if (columnIndex !== 0) {
+ // return [3, 4];
+ }
+ },
+ goGroupon(type, id) {
+ let that = this;
+ if (id == 0) {
+ return false;
+ }
+ if (type == "groupon") {
+ parent.Fast.api.open(`shopro/activity/groupon/detail/id/${id}`, "查看详情", {
+ callback(data) {
+ that.reqOrderList()
+ }
+ });
+ }
+ },
+ optHandle(id) {
+ let that = this;
+ Fast.api.ajax({
+ url: `shopro/order/order/actions/id/${id}`,
+ loading: true,
+ data: {}
+ }, function (ret, res) {
+ that.optList = res.data;
+ that.dialogOptVisible = true
+ return false;
+ })
+ },
+ goOrderRefresh() {
+ this.focusi = true;
+ this.reqOrderList()
+ }
+ },
+ watch: {
+ deliverForm: {
+ handler: function (newVal) {
+ if (newVal.express_ids && newVal.express_name && newVal.express_no) {
+ this.disabledBtn = true
+ } else {
+ this.disabledBtn = false
+ }
+ },
+ deep: true
+ },
+ searchKey(newval, val) {
+ if (newval != val) {
+ this.offset = 0;
+ this.reqOrderList()
+ }
+ },
+ tableOrderStatus(newval, val) {
+ if (newval != val) {
+ this.offset = 0;
+ this.reqOrderList()
+ }
+ },
+ selectDate: {
+ handler: function (newval, val) {
+ if (newval != val) {
+ this.offset = 0;
+ this.reqOrderList()
+ }
+ },
+ deep: true
+ }
+ }
+ })
+ },
+ recyclebin: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ 'dragsort_url': ''
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: 'shopro/order/order/recyclebin' + location.search,
+ pk: 'type',
+ sortName: 'type',
+ columns: [
+ [{
+ checkbox: true
+ },
+ {
+ field: 'type',
+ title: __('type')
+ },
+ {
+ field: 'deletetime',
+ title: __('Deletetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'operate',
+ wtypeth: '130px',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ buttons: [{
+ name: 'Restore',
+ text: __('Restore'),
+ classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
+ icon: 'fa fa-rotate-left',
+ url: 'shopro/order/order/restore',
+ refresh: true
+ },
+ {
+ name: 'Destroy',
+ text: __('Destroy'),
+ classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
+ icon: 'fa fa-times',
+ url: 'shopro/order/order/destroy',
+ refresh: true
+ }
+ ],
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ detail: function () {
+ var vue = new Vue({
+ el: "#orderDetail",
+ data() {
+ return {
+ orderDetail: Config.order,
+ orderDetailCopy: JSON.parse(JSON.stringify(Config.order)),
+ orderGoodsList: Config.item,
+ orderFrom: {},
+ express_name: "",
+ express_no: "",
+ isexpress: true,
+ stepActive: 0,
+ activeName: 'first',
+ deliveryActive: 0,
+ deliveryFlag: false,
+ refund_statusFlag: false,
+ aftersale_statusFlag: false,
+ deliverForm: {
+ express_name: '',
+ express_no: '',
+ express_ids: ''
+ },
+ deliveryEditFlag: false,
+ disabledBtn: false,
+ dialogVisible: false,
+ refund_money: '',
+ refuse_reason: "",
+ refund_dialog: false,
+ refund_orderId: '',
+ refund_itemId: '',
+ refund_type: '',
+ addMemoFlag: false,
+ receivingAddress: [],
+ receivingAddressName: [],
+ areaList: [],
+ gg: '此订单有问题,待议此订单有问题,待议此订单有问题,待议此订单有问题,待议此订单有问题,待议此订单有问题,待议'
+ }
+ },
+ mounted() {
+ if (this.orderDetail.status <= 0) {
+ this.stepActive = 1
+ } else if (this.orderDetail.status == 1) {
+ this.orderGoodsList.forEach(i => {
+ if (i.dispatch_status == 1 || i.dispatch_status == 2) {
+ this.deliveryFlag = true
+ }
+ if (i.dispatch_status == 0) {
+ this.deliveryFlag = false
+ }
+ if (i.refund_status == 1) {
+ this.refund_statusFlag = true
+ }
+ if (i.aftersale_status == 1) {
+ this.aftersale_statusFlag = true
+ }
+ })
+ this.stepActive = this.deliveryFlag ? 3 : 2;
+ } else {
+ this.stepActive = 4
+ }
+ this.receivingAddress.push(this.orderDetail.province_id);
+ this.receivingAddress.push(this.orderDetail.city_id);
+ this.receivingAddress.push(this.orderDetail.area_id)
+ this.receivingAddressName.push(this.orderDetail.province_name);
+ this.receivingAddressName.push(this.orderDetail.city_name);
+ this.receivingAddressName.push(this.orderDetail.area_name)
+ },
+ methods: {
+ handleClick(tab, event) {},
+ godeliver() {
+ this.dialogVisible = true
+ },
+ deliverSelectionChange(val) {
+ let express_ids = []
+ val.forEach(i => {
+ express_ids.push(i.id)
+ })
+ this.deliverForm.express_ids = express_ids.join(',')
+ },
+ deliverSubmit() {
+ this.dialogVisible = false
+ var that = this;
+ Fast.api.ajax({
+ url: `shopro/order/order/send/id/${that.orderDetail.id}/item_id/${that.deliverForm.express_ids}`,
+ loading: true,
+ data: {
+ express_name: that.deliverForm.express_name,
+ express_no: that.deliverForm.express_no
+ }
+ }, function (ret, res) {
+ that.orderDetail = res.data
+ that.orderGoodsList = res.data.item
+ that.deliveryFlag = false
+ that.orderGoodsList.forEach(i => {
+ if (i.dispatch_status == 1 || i.dispatch_status == 2) {
+ that.deliveryFlag = true
+ }
+ if (i.dispatch_status == 0) {
+ that.deliveryFlag = false
+ }
+ })
+ that.stepActive = that.deliveryFlag ? 3 : 2
+ for (let key in that.deliverForm) {
+ that.deliverForm[key] = ''
+ }
+ })
+ },
+ handleClose() {
+ this.dialogVisible = false;
+ for (let key in this.deliverForm) {
+ this.deliverForm[key] = ''
+ };
+ this.refund_money = '';
+ this.refund_dialog = false;
+ },
+ finishService(orderId, itemId) {
+ var that = this
+ Fast.api.ajax({
+ url: `shopro/order/order/aftersaleFinish/id/${orderId}/item_id/${itemId}`,
+ loading: true,
+ data: {}
+ }, function (ret, res) {
+ that.orderGoodsList = []
+ res.data.forEach(item => {
+ that.orderGoodsList.push(item)
+ })
+ that.aftersale_statusFlag = false
+ that.orderGoodsList.forEach(i => {
+ if (i.aftersale_status == 1) {
+ that.aftersale_statusFlag = true
+ }
+ })
+ })
+ },
+ refundHandle(orderId, itemId, type) {
+ this.refund_dialog = true
+ this.refund_orderId = orderId
+ this.refund_itemId = itemId
+ this.refund_type = type
+ },
+ reqRefund() {
+ let that = this
+ if (this.refund_type == 'agree') {
+ Fast.api.ajax({
+ url: `shopro/order/order/refund/id/${that.refund_orderId}/item_id/${that.refund_itemId}`,
+ loading: true,
+ data: {
+ refund_money: that.refund_money
+ }
+ }, function (ret, res) {
+ that.refund_statusFlag = false
+ that.orderGoodsList = []
+ res.data.forEach(item => {
+ that.orderGoodsList.push(item)
+ })
+ that.refund_dialog = false;
+ that.refund_money = "";
+ that.orderGoodsList.forEach(i => {
+ if (i.refund_status == 1) {
+ that.refund_statusFlag = true
+ }
+ })
+ })
+ } else {
+ Fast.api.ajax({
+ url: `shopro/order/order/refundRefuse/id/${that.refund_orderId}/item_id/${that.refund_itemId}`,
+ loading: true,
+ data: {
+ refund_msg: that.refuse_reason
+ }
+ }, function (ret, res) {
+ that.refund_statusFlag = false
+ that.orderGoodsList = []
+ res.data.forEach(item => {
+ that.orderGoodsList.push(item)
+ })
+ that.refund_dialog = false;
+ that.refuse_reason = "";
+ that.orderGoodsList.forEach(i => {
+ if (i.refund_status == 1) {
+ that.refund_statusFlag = true
+ }
+ })
+ })
+ }
+
+ },
+ reqCancel() {
+ this.refund_dialog = false;
+ this.refund_money = "";
+ this.refuse_reason = ""
+ },
+ copyMsg() {
+ let clipboard = new Clipboard('.copy-msg')
+ clipboard.on('success', function () {
+ alert("复制成功")
+ });
+ clipboard.on('error', function () {
+ alert("复制失败")
+ });
+ },
+ deliveryEdit() {
+ var that = this;
+ Fast.api.ajax({
+ url: `shopro/area/getCascader`,
+ loading: true,
+ data: {}
+ }, function (ret, res) {
+ that.areaList = res.data;
+ that.deliveryEditFlag = true;
+ return false;
+ })
+ },
+ deliveryDefine() {
+ let that = this;
+ Fast.api.ajax({
+ url: `shopro/order/order/editConsignee/id/${that.orderDetail.id}`,
+ loading: true,
+ data: {
+ consignee: that.orderDetail.consignee,
+ phone: that.orderDetail.phone,
+ province_id: that.receivingAddress[0],
+ province_name: that.receivingAddressName[0],
+ city_id: that.receivingAddress[1],
+ city_name: that.receivingAddressName[1],
+ area_id: that.receivingAddress[2],
+ area_name: that.receivingAddressName[2],
+ address: that.orderDetail.address,
+ }
+ }, function (ret, res) {
+ that.orderDetail = res.data
+ that.deliveryEditFlag = false;
+ })
+ },
+ changeAddress(value) {
+ let that = this;
+ that.receivingAddress = value
+ let arr = []
+ that.areaList.forEach((i, index) => {
+ if (i.id == that.receivingAddress[0]) {
+ arr.push(i.label)
+ if (i.children.length > 0) {
+ i.children.forEach((j, inde) => {
+ if (j.id == that.receivingAddress[1]) {
+ arr.push(j.label)
+ if (j.children.length > 0) {
+ j.children.forEach(k => {
+ if (k.id == that.receivingAddress[2]) {
+ arr.push(k.label)
+ }
+ })
+ }
+ }
+ })
+ }
+ }
+ })
+ that.receivingAddressName = arr
+ },
+ viewEvaluation(order_item_id) {
+ parent.Fast.api.open("shopro/goods_comment/index?order_item_id=" + order_item_id, "查看评价");
+ },
+ addMemo(type) {
+ if (type == 'cancel') {
+ this.addMemoFlag = false;
+ this.orderDetail.memo = this.orderDetailCopy.memo;
+ } else {
+ this.addMemoFlag = true;
+ }
+ },
+ addMemoreq(id) {
+ var that = this;
+ Fast.api.ajax({
+ url: `shopro/order/order/editMemo/id/${id}`,
+ loading: true,
+ data: {
+ memo: that.orderDetail.memo,
+ }
+ }, function (ret, res) {
+ that.orderDetail = res.data;
+ that.addMemoFlag = false
+ })
+ },
+ cancelOrder(id) {
+ var that = this;
+ Fast.api.ajax({
+ url: `shopro/order/order/cancel/id/${id}`,
+ loading: true,
+ data: {}
+ }, function (ret, res) {
+ that.orderDetail = res.data;
+ })
+ }
+
+ },
+ watch: {
+ deliverForm: {
+ handler: function (newVal) {
+ if (newVal.express_ids && newVal.express_name && newVal.express_no) {
+ this.disabledBtn = true
+ } else {
+ this.disabledBtn = false
+ }
+ },
+ deep: true
+ },
+ }
+ })
+ $('.more-ellipsis').each(function (i, obj) {
+ var lineHeight = parseInt($(this).css("line-height"));
+ var height = parseInt($(this).height());
+ if ((height / lineHeight) > 2) {
+ $(this).addClass("more-ellipsis-after")
+ $(this).css("height", "36px");
+ } else {
+ $(this).removeClass("more-ellipsis-after");
+ }
+ });
+ Controller.api.bindevent();
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/order/order_item.js b/public/assets/js/backend/shopro/order/order_item.js
new file mode 100644
index 000000000..942ec2942
--- /dev/null
+++ b/public/assets/js/backend/shopro/order/order_item.js
@@ -0,0 +1,231 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/order/order_item/index' + location.search,
+ add_url: 'shopro/order/order_item/add',
+ edit_url: 'shopro/order/order_item/edit',
+ del_url: 'shopro/order/order_item/del',
+ multi_url: 'shopro/order/order_item/multi',
+ table: 'shopro_order_item',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ { checkbox: true },
+ { field: 'id', title: __('Id') },
+ { field: 'user_id', title: __('User_id') },
+ { field: 'order_id', title: __('Order_id') },
+ { field: 'goods_id', title: __('Goods_id') },
+ { field: 'goods_sku_price_id', title: __('Goods_sku_price_id') },
+ { field: 'activity_id', title: __('Activity_id') },
+ { field: 'activity_type', title: __('Activity_type') },
+ { field: 'item_goods_sku_price_id', title: __('Item_goods_sku_price_id') },
+ { field: 'goods_sku_text', title: __('Goods_sku_text') },
+ { field: 'goods_title', title: __('Goods_title') },
+ { field: 'goods_image', title: __('Goods_image'), events: Table.api.events.image, formatter: Table.api.formatter.image },
+ { field: 'goods_original_price', title: __('Goods_original_price'), operate: 'BETWEEN' },
+ { field: 'discount_fee', title: __('Discount_fee'), operate: 'BETWEEN' },
+ { field: 'goods_price', title: __('Goods_price'), operate: 'BETWEEN' },
+ { field: 'goods_num', title: __('Goods_num') },
+ {
+ field: 'dispatch_status', title: __('Dispatch_status'), searchList: { "0": __('Dispatch_status 0'), "1": __('Dispatch_status 1'), "2": __('Dispatch_status 2') },
+ formatter: function (value, row) {
+ return `
+
+
+ ${value}
+
+
+ `
+ },
+ },
+ { field: 'dispatch_fee', title: __('Dispatch_fee'), operate: 'BETWEEN' },
+ { field: 'dispatch_type', title: __('Dispatch_type') },
+ { field: 'dispatch_id', title: __('Dispatch_id') },
+ { field: 'aftersale_status', title: __('Aftersale_status'), searchList: { "0": __('Aftersale_status 0'), "1": __('Aftersale_status 1') }, formatter: Table.api.formatter.status },
+ { field: 'comment_status', title: __('Comment_status'), searchList: { "0": __('Comment_status 0'), "1": __('Comment_status 1') }, formatter: Table.api.formatter.status },
+ { field: 'refund_status', title: __('Refund_status'),
+ formatter: function (value, row) {
+ return `
+
+
+ ${value}
+
+
+ `
+ }},
+
+ // searchList: { "-1": __('Refund_status -1'), "0": __('Refund_status 0'), "1": __('Refund_status 1'), "2": __('Refund_status 2') }, formatter: Table.api.formatter.status },
+ {
+ field: 'express_name', title: __('Express_name'),
+
+ },
+ {
+ field: 'express_no', title: __('Express_no'),
+ formatter: function (value, row) {
+ return `${value == null ? '' : value}
`
+ }
+ },
+ { field: 'createtime', title: __('Createtime'), operate: 'RANGE', addclass: 'datetimerange', formatter: Table.api.formatter.datetime },
+ { field: 'updatetime', title: __('Updatetime'), operate: 'RANGE', addclass: 'datetimerange', formatter: Table.api.formatter.datetime },
+ { field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate }
+ ]
+ ]
+ });
+ //申请退货
+ $(document).on("click", ".express_ajax", function () {
+ var that = this;
+ var id=$(this).children("span")[0].innerHTML
+ Layer.confirm(
+ __('确认退款?',),
+ {icon: 3, title: __('Warning'), offset: 0, shadeClose: true},
+ function (index) {
+ Backend.api.ajax({
+ url: "acc/bdd/delexp",
+ data: $(that).closest("form").serialize()
+ });
+ table.bootstrapTable('refresh');
+ Layer.close(index);
+ }
+ );
+ });
+ $(".popover-options").blur(function(){
+ console.log(123)
+ $('.popover').css("display","none");
+ });
+ $('.popover-options').on('shown.bs.popover', function () {
+ alert("当显示时警告消息");
+ })
+ // $(document).on("click",function(){
+ // $('.popover').css("display","none");
+ // })
+ //统一发货
+ $(document).on("click", ".sendAll", function () {
+ var id = $(this).children("span")[0].innerHTML
+ var that = this;
+ layer.open({
+ type: 1,
+ area: ['300px', '300px'],
+ shadeClose: false, //点击遮罩关闭
+ content: ``
+ });
+ $(".sendAllBtn").click(function () {
+ var ggg = $(".ggg").val()
+ var fff = $(".fff").val()
+ Backend.api.ajax({
+ url: "general/config/emailtest?id=" + value,
+ data: $(that).closest("form").serialize()
+
+ });
+ table.bootstrapTable('refresh');
+ Layer.close(index);
+ })
+ });
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ recyclebin: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ 'dragsort_url': ''
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: 'shopro/order/order_item/recyclebin' + location.search,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ { checkbox: true },
+ { field: 'id', title: __('Id') },
+ {
+ field: 'deletetime',
+ title: __('Deletetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'operate',
+ width: '130px',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ buttons: [
+ {
+ name: 'Restore',
+ text: __('Restore'),
+ classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
+ icon: 'fa fa-rotate-left',
+ url: 'shopro/order/order_item/restore',
+ refresh: true
+ },
+ {
+ name: 'Destroy',
+ text: __('Destroy'),
+ classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
+ icon: 'fa fa-times',
+ url: 'shopro/order/order_item/destroy',
+ refresh: true
+ }
+ ],
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/richtext.js b/public/assets/js/backend/shopro/richtext.js
new file mode 100644
index 000000000..51dbbfa2f
--- /dev/null
+++ b/public/assets/js/backend/shopro/richtext.js
@@ -0,0 +1,177 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/richtext/index' + location.search,
+ add_url: 'shopro/richtext/add',
+ edit_url: 'shopro/richtext/edit',
+ del_url: 'shopro/richtext/del',
+ multi_url: 'shopro/richtext/multi',
+ table: 'shopro_richtext',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'title', title: __('Title')},
+ // {field: 'content', title: __('Content')},
+ {field: 'createtime', title: __('Createtime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ recyclebin: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ 'dragsort_url': ''
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: 'shopro/richtext/recyclebin' + location.search,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'title', title: __('Title'), align: 'left'},
+ {
+ field: 'deletetime',
+ title: __('Deletetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'operate',
+ width: '130px',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ buttons: [
+ {
+ name: 'Restore',
+ text: __('Restore'),
+ classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
+ icon: 'fa fa-rotate-left',
+ url: 'shopro/richtext/restore',
+ refresh: true
+ },
+ {
+ name: 'Destroy',
+ text: __('Destroy'),
+ classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
+ icon: 'fa fa-times',
+ url: 'shopro/richtext/destroy',
+ refresh: true
+ }
+ ],
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ select: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/richtext/index',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ // sortName: 'id',
+ pk: 'id',
+ sortName: 'id',
+ showToggle: false,
+ showExport: false,
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'title', title: __('Title')},
+ // {field: 'content', title: __('Content')},
+ {field: 'createtime', title: __('Createtime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {
+ field: 'operate', title: __('Operate'), events: {
+ 'click .btn-chooseone': function (e, value, row, index) {
+ var multiple = Backend.api.query('multiple');
+ multiple = multiple == 'true' ? true : false;
+ row.ids=row.id.toString()
+ Fast.api.close({data: row, multiple: multiple});
+ },
+ }, formatter: function () {
+ return ' ' + __('Choose') + ' ';
+ }
+ }
+ ]
+ ]
+ });
+
+ // 选中多个
+ $(document).on("click", ".btn-choose-multi", function () {
+ var couponsArr = new Array();
+ $.each(table.bootstrapTable("getAllSelections"), function (i, j) {
+ couponsArr.push(j.id);
+ });
+ var multiple = Backend.api.query('multiple');
+ multiple = multiple == 'true' ? true : false;
+ let row={}
+ row.ids=couponsArr.join(",")
+ Fast.api.close({data: row, multiple: multiple});
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ require(['upload'], function (Upload) {
+ Upload.api.plupload($("#toolbar .plupload"), function () {
+ $(".btn-refresh").trigger("click");
+ });
+ });
+
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/user_fake.js b/public/assets/js/backend/shopro/user_fake.js
new file mode 100644
index 000000000..cbfade43d
--- /dev/null
+++ b/public/assets/js/backend/shopro/user_fake.js
@@ -0,0 +1,51 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/user_fake/index' + location.search,
+ add_url: 'shopro/user_fake/add',
+ edit_url: 'shopro/user_fake/edit',
+ del_url: 'shopro/user_fake/del',
+ multi_url: 'shopro/user_fake/multi',
+ table: 'shopro_user_fake',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'nickname', title: __('Nickname')},
+ {field: 'avatar', title: __('Avatar'), events: Table.api.events.image, formatter: Table.api.formatter.image},
+ {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/user_wallet_apply.js b/public/assets/js/backend/shopro/user_wallet_apply.js
new file mode 100644
index 000000000..0e4ad6632
--- /dev/null
+++ b/public/assets/js/backend/shopro/user_wallet_apply.js
@@ -0,0 +1,183 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/user_wallet_apply/index' + location.search,
+ add_url: 'shopro/user_wallet_apply/add',
+ edit_url: 'shopro/user_wallet_apply/edit',
+ del_url: 'shopro/user_wallet_apply/del',
+ multi_url: 'shopro/user_wallet_apply/multi',
+ table: 'shopro_user_wallet_apply',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {field: 'user_id', title: __('User_id')},
+ {field: 'money', title: __('Money'), operate:'BETWEEN'},
+ {field: 'charge_money', title: __('Charge_money'), operate:'BETWEEN'},
+ {field: 'service_fee', title: __('Service_fee'), operate:'BETWEEN'},
+ // {field: 'get_type', title: __('Get_type'),
+ // searchList: {"bank":__('Bank')},
+ // formatter: function (value, row) {
+ // return `
+ //
${row.get_type_text}
+ //
`
+ // }
+ // },
+ {field: 'real_name', title: __('Real_name')},
+ {field: 'bank_info', title: __('Bank_info'),
+ formatter: function (value, row) {
+ let bankInfo = JSON.parse(row.bank_info);
+ return `
+
${bankInfo.bank_name}
+
${bankInfo.card_no}
+
`
+ }
+ },
+ {field: 'status', title: __('Status'), searchList: {"0":__('Status 0'),"1":__('Status 1'),"-1":__('Status -1')}, formatter: Table.api.formatter.status},
+ {field: 'status_msg', title: __('Status_msg')},
+ {field: 'createtime', title: __('Createtime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ {
+ field: 'buttons',
+ width: "120px",
+ title: '提现操作',
+ table: table,
+ operate: false,
+ formatter: function (value, row) {
+ if(row.status==0){
+ return `
+ 同意
+ 拒绝
+
`
+ }else{
+ return `已完成
`
+ }
+
+ },
+ },
+ {field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
+ ]
+ ]
+ });
+ $(document).on("click", ".withdrawrefuse", function () {
+ let id = $(this).attr("data-id")
+ let sta=$(this).attr("data-sta")
+ Layer.prompt({title: __('请输入驳回理由'), formType: 0}, function (value, index) {
+ Backend.api.ajax({
+ url: "shopro/user_wallet_apply/applyOper/id/" + id,
+ data: {
+ status:sta,
+ status_msg:value
+ },
+
+ }, function () {
+ table.bootstrapTable('refresh');
+ Layer.close(index);
+ });
+
+ });
+ });
+ $(document).on("click", ".withdrawreal", function () {
+ let id = $(this).attr("data-id")
+ let sta=$(this).attr("data-sta")
+ Backend.api.ajax({
+ url: "shopro/user_wallet_apply/applyOper/id/" + id,
+ data: {
+ status:sta,
+ status_msg:''
+ },
+
+ }, function () {
+ table.bootstrapTable('refresh');
+ });
+
+ });
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ recyclebin: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ 'dragsort_url': ''
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: 'shopro/user_wallet_apply/recyclebin' + location.search,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ {checkbox: true},
+ {field: 'id', title: __('Id')},
+ {
+ field: 'deletetime',
+ title: __('Deletetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'operate',
+ width: '130px',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ buttons: [
+ {
+ name: 'Restore',
+ text: __('Restore'),
+ classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
+ icon: 'fa fa-rotate-left',
+ url: 'shopro/user_wallet_apply/restore',
+ refresh: true
+ },
+ {
+ name: 'Destroy',
+ text: __('Destroy'),
+ classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
+ icon: 'fa fa-times',
+ url: 'shopro/user_wallet_apply/destroy',
+ refresh: true
+ }
+ ],
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/assets/js/backend/shopro/wechat.js b/public/assets/js/backend/shopro/wechat.js
new file mode 100644
index 000000000..48576e4fd
--- /dev/null
+++ b/public/assets/js/backend/shopro/wechat.js
@@ -0,0 +1,465 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'shopro/wechat/index' + location.search,
+ add_url: 'shopro/wechat/add',
+ edit_url: 'shopro/wechat/edit',
+ del_url: 'shopro/wechat/del',
+ multi_url: 'shopro/wechat/multi',
+ table: 'shopro_wechat',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [{
+ checkbox: true
+ },
+ {
+ field: 'id',
+ title: __('Id')
+ },
+ {
+ field: 'type',
+ title: __('Type')
+ },
+ {
+ field: 'name',
+ title: __('Name')
+ },
+ {
+ field: 'createtime',
+ title: __('Createtime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'updatetime',
+ title: __('Updatetime'),
+ operate: 'RANGE',
+ addclass: 'datetimerange',
+ formatter: Table.api.formatter.datetime
+ },
+ {
+ field: 'operate',
+ title: __('Operate'),
+ table: table,
+ events: Table.api.events.operate,
+ formatter: Table.api.formatter.operate
+ }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ menu: function () {
+ var wechat_menu = new Vue({
+ el: "#wechat-menu",
+ data() {
+ return {
+ menuData: [],
+ rightData: {},
+ selectedIndex1: null,
+ selectedIndex2: null,
+ selectLevel: null,
+ rightShow: false,
+ menuTitle: '',
+ edit_id: null,
+ viewUrl: Config.shopro.domain,
+ wxMiniProgramapp_id: Config.wxMiniProgram.app_id
+ }
+ },
+ mounted() {
+ this.getmenuData();
+ },
+ methods: {
+ getmenuData() {
+ var that = this;
+ Fast.api.ajax({
+ url: 'shopro/wechat/menu?id=1',
+ loading: true,
+ type: 'GET',
+ data: {}
+ }, function (ret, res) {
+ if (res.data.content) {
+ that.menuData = JSON.parse(res.data.content);
+ that.menuData.forEach(i => {
+ i.selected = false;
+ i.show = false;
+ if(!i.appid){
+ i.appid = '';
+ i.pagepath='';
+ }
+ if (i.sub_button) {
+ i.sub_button.forEach(j => {
+ j.selected = false;
+ if(!j.appid){
+ j.appid = '';
+ j.pagepath='';
+ }
+ })
+ } else {
+ i.sub_button = []
+ }
+ })
+ } else {
+ that.menuData = []
+ }
+ that.edit_id = res.data.id;
+ that.menuTitle = res.data.name;
+ return false;
+ })
+ },
+ changeRadio(e) {
+ this.rightData.url = "";
+ this.rightData.appid = "";
+ this.rightData.pagepath = "";
+ },
+ menuSelect(index1, index2) {
+ this.selectedIndex1 = index1;
+ this.selectedIndex2 = index2;
+ this.rightShow = true;
+ this.menuData.forEach(i => {
+ i.selected = false;
+ i.show = false;
+ if (i.sub_button) {
+ i.sub_button.forEach(j => {
+ j.selected = false;
+ })
+ }
+ });
+ this.menuData[index1].show = true;
+ //选择1
+ if (index2 == null) {
+ this.selectLevel = 1;
+ this.menuData[index1].selected = true;
+ this.menuData[index1].show = true;
+ this.rightData = this.menuData[index1];
+ } else {
+ this.selectLevel = 2;
+ this.menuData[index1].sub_button[index2].selected = true;
+ this.rightData = this.menuData[index1].sub_button[index2];
+ }
+ },
+ addMenu(index, level) {
+ //右侧显示
+ this.rightShow = true;
+ this.selectLevel = level;
+ if (index != null) {
+ this.selectedIndex1 = index;
+ this.menuData.forEach(i => {
+ i.selected = false;
+ if (i.sub_button) {
+ i.sub_button.forEach(j => {
+ j.selected = false;
+ })
+ }
+ });
+ this.menuData[index].sub_button.push({
+ name: '添加子菜单',
+ type: 'view',
+ selected: true,
+ url: '',
+ appid: '',
+ pagepath:''
+
+ })
+ this.rightData = this.menuData[index].sub_button[this.menuData[index].sub_button.length - 1];
+ this.selectedIndex2 = this.menuData[index].sub_button.length - 1;
+ } else {
+ this.menuData.forEach(i => {
+ i.selected = false;
+ i.show = false;
+ });
+ this.menuData.push({
+ name: '添加菜单',
+ selected: true,
+ show: true,
+ type: 'view',
+ url: '',
+ appid: '',
+ pagepath:'',
+ sub_button: []
+ })
+ this.selectedIndex1 = this.menuData.length - 1;
+ this.rightData = this.menuData[this.menuData.length - 1];
+ }
+ },
+ delMenu() {
+ if (this.selectedIndex2 != null) {
+ this.menuData[this.selectedIndex1].sub_button.splice(this.selectedIndex2, 1);
+ if (this.menuData[this.selectedIndex1].sub_button.length > 0) {
+ if (this.selectedIndex2 == 0) {
+ this.menuData[this.selectedIndex1].sub_button[0].selected = true;
+ this.rightData = this.menuData[this.selectedIndex1].sub_button[0];
+ } else {
+ this.menuData[this.selectedIndex1].sub_button[this.selectedIndex2 - 1].selected = true;
+ this.rightData = this.menuData[this.selectedIndex1].sub_button[this.selectedIndex2 - 1];
+ this.selectedIndex2--
+ }
+ } else {
+ this.rightData = {};
+ this.rightShow = false;
+ }
+ } else {
+ this.menuData.splice(this.selectedIndex1, 1);
+ if (this.menuData.length > 0) {
+ if (this.selectedIndex1 == 0) {
+ this.menuData[0].selected = true;
+ this.menuData[0].show = true;
+ this.rightData = this.menuData[0];
+ } else {
+ this.menuData[this.selectedIndex1 - 1].selected = true;
+ this.menuData[this.selectedIndex1 - 1].show = true;
+ this.rightData = this.menuData[this.selectedIndex1 - 1];
+ this.selectedIndex1--
+ }
+
+ } else {
+ this.rightData = {};
+ this.rightShow = false;
+ }
+ }
+ },
+ choosePath() {
+ let that = this;
+ let multiple = $(this).data("multiple") ? $(this).data("multiple") : false;
+ parent.Fast.api.open("shopro/link/select?multiple=" + multiple, "选择路径", {
+ callback: function (data) {
+ if (that.selectedIndex2 != null) {
+ if (that.menuData[that.selectedIndex1].sub_button[that.selectedIndex2].type == 'view') {
+ that.menuData[that.selectedIndex1].sub_button[that.selectedIndex2].url = that.viewUrl + data.data.path;
+ } else {
+ that.menuData[that.selectedIndex1].sub_button[that.selectedIndex2].pagepath = data.data.path;
+ that.menuData[that.selectedIndex1].sub_button[that.selectedIndex2].url = that.viewUrl + data.data.path;
+ that.menuData[that.selectedIndex1].sub_button[that.selectedIndex2].appid = that.wxMiniProgramapp_id;
+ that.rightData.appid = that.wxMiniProgramapp_id;
+ }
+ that.rightData.url = that.menuData[that.selectedIndex1].sub_button[that.selectedIndex2].url;
+ } else {
+ if (that.menuData[that.selectedIndex1].type == 'view') {
+ that.menuData[that.selectedIndex1].url = that.viewUrl + data.data.path;
+ } else {
+ that.menuData[that.selectedIndex1].url = that.viewUrl + data.data.path;
+ that.menuData[that.selectedIndex1].pagepath = data.data.path;
+ that.menuData[that.selectedIndex1].appid = that.wxMiniProgramapp_id;
+ that.rightData.appid = that.wxMiniProgramapp_id;
+ }
+ that.rightData.url = that.menuData[that.selectedIndex1].url;
+ that.rightData.pagepath = that.menuData[that.selectedIndex1].pagepath;
+ }
+
+ }
+ });
+ },
+ menuHide() {
+ this.selectedIndex1 = null;
+ this.selectedIndex2 = null;
+ this.menuData.forEach(i => {
+ i.selected = false;
+ i.show = false;
+ if (i.sub_button.length > 0) {
+ i.sub_button.forEach(j => {
+ j.selected = false;
+ })
+ }
+ });
+ this.rightShow = false;
+ },
+ menuShow() {
+ this.rightShow = true;
+ },
+ subData(type) {
+ let that = this;
+ let savemenuData=JSON.parse(JSON.stringify(that.menuData))
+ savemenuData.forEach(i => {
+ delete i.show;
+ delete i.selected;
+ if (i.sub_button.length > 0) {
+ delete i.url;
+ delete i.appid;
+ delete i.pagepath;
+ delete i.type;
+ i.sub_button.forEach(j => {
+ delete j.selected;
+ if (j.type == 'view') {
+ delete j.appid;
+ delete j.pagepath;
+ }
+ })
+ } else {
+ delete i.sub_button;
+ if (i.type) {
+ if (i.type == 'view') {
+ delete i.appid;
+ delete i.pagepath;
+ }
+ }
+ }
+ })
+ Fast.api.ajax({
+ url: 'shopro/wechat/menu?id=' + that.edit_id + '&act=' + type,
+ loading: true,
+ type: 'POST',
+ data: {
+ content: JSON.stringify(savemenuData)
+ }
+ }, function (ret, res) {
+ if (res.code == 1) {
+ if (res.data.content) {
+ that.menuData = JSON.parse(res.data.content);
+ that.menuData.forEach(i => {
+ i.selected = false;
+ i.show = false;
+ if (i.sub_button) {
+ i.sub_button.forEach(j => {
+ j.selected = false;
+ })
+ } else {
+ i.sub_button = []
+ }
+ })
+
+ } else {
+ that.menuData = []
+ }
+ that.edit_id = res.data.id;
+ that.menuTitle = res.data.name;
+ }
+ that.rightShow = false;
+
+ })
+ },
+ },
+ watch:{
+ rightData: {
+ handler: function (newVal) {
+ if(this.selectLevel==1){
+ let name=newVal.name;
+ let num=0;
+ for(var i=0;i=20 && name[i].charCodeAt()<=127){
+ num++
+ }else{
+ num+=2
+ }
+ if(num>8){
+ newVal.name=newVal.name.substr(0,i)
+ }
+ }
+ }else if(this.selectLevel==2){
+ let name=newVal.name;
+ let num=0;
+ for(var i=0;i=20 && name[i].charCodeAt()<=127){
+ num++
+ }else{
+ num+=2
+ }
+ if(num>16){
+ newVal.name=newVal.name.substr(0,i)
+ }
+ }
+ }
+ },
+ deep: true
+ }
+ }
+ })
+ },
+ fans: function () {
+ var fans_index = new Vue({
+ el: "#fans-index",
+ data() {
+ return {
+ searchKey: '',
+ fansList: [],
+ currentPage: 1,
+ totalPage: 0,
+ page: 1,
+ limit: 10,
+ }
+ },
+ mounted() {
+ this.getfansList();
+ },
+ methods: {
+ getfansList() {
+ var that = this;
+ Fast.api.ajax({
+ url: 'shopro/wechat/fans',
+ loading: true,
+ type: 'GET',
+ data: {
+ page: that.page,
+ limit: that.limit,
+ searchKey: that.searchKey,
+ }
+ }, function (ret, res) {
+ that.fansList = res.data.data;
+ that.totalPage = res.data.total;
+ return false;
+ })
+ },
+ handleSizeChange(val) {
+ this.limit = val
+ this.getfansList()
+ },
+ handleCurrentChange(val) {
+ this.page = val
+ this.getfansList()
+ },
+ viewBtn(openid) {
+ Fast.api.open('shopro/wechat/fans_user?openid='+openid,"查看详情")
+ },
+ getSync() {
+ var that = this;
+ Fast.api.ajax({
+ url: 'shopro/wechat/fans?act=async',
+ loading: true,
+ type: 'GET',
+ data: {}
+ }, function (ret, res) {
+ if (res.code == 1) {
+ that.getfansList();
+ }
+ })
+ }
+ },
+ watch: {
+ searchKey(newVal, oldVal) {
+ if (newVal != oldVal) {
+ this.page = 1;
+ this.getfansList();
+ }
+ }
+ },
+ })
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
\ No newline at end of file
diff --git a/public/nginx.htaccess b/public/nginx.htaccess
new file mode 100644
index 000000000..b8c527532
--- /dev/null
+++ b/public/nginx.htaccess
@@ -0,0 +1,5 @@
+location / {
+ if (!-e $request_filename){
+ rewrite ^(.*)$ /index.php?s=$1 last; break;
+ }
+}
\ No newline at end of file
--
Gitee
From a920b95022216ab8cdfc3d9c0086675e7a4c80dc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=A4=A7=E8=82=A5?= <4602058@qq.com>
Date: Fri, 17 Jul 2020 17:03:22 +0800
Subject: [PATCH 2/2] =?UTF-8?q?202007171703=E6=9B=B4=E6=96=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
application/database.php | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/application/database.php b/application/database.php
index 26c02ff74..c13a445e0 100755
--- a/application/database.php
+++ b/application/database.php
@@ -16,13 +16,13 @@ return [
// 数据库类型
'type' => Env::get('database.type', 'mysql'),
// 服务器地址
- 'hostname' => Env::get('database.hostname', '127.0.0.1'),
+ 'hostname' => Env::get('database.hostname', '122.152.210.29'),
// 数据库名
- 'database' => Env::get('database.database', 'fastadmin'),
+ 'database' => Env::get('database.database', 'fastadmin_deyuel'),
// 用户名
- 'username' => Env::get('database.username', 'root'),
+ 'username' => Env::get('database.username', 'fastadmin_deyuel'),
// 密码
- 'password' => Env::get('database.password', 'root'),
+ 'password' => Env::get('database.password', 'PtbG4d4iyRyGN2jS'),
// 端口
'hostport' => Env::get('database.hostport', ''),
// 连接dsn
--
Gitee
+- {:__('Set to normal')}
+ - {:__('Set to hidden')}
+
+