作者 何书鹏

first commit

正在显示 58 个修改的文件 包含 4635 行增加44 行删除

要显示太多修改。

为保证性能只显示 58 of 58+ 个文件。

/nbproject/
/thinkphp/
/vendor/
/runtime/*
/addons/*
/application/admin/command/Install/*.lock
/public/assets/libs/
/public/assets/addons/*
/public/uploads/*
.idea
composer.lock
... ... @@ -14,4 +8,4 @@ composer.lock
!.gitkeep
.env
.svn
.vscode
.vscode
\ No newline at end of file
... ...
{"license":"extended","licenseto":"10789","licensekey":"hfnkMvz8W9Ul0Le5 UPLoZfiYHIxPZpBqdTk7qA==","menus":["shopro","shopro\/config","shopro\/config\/index","shopro\/config\/add","shopro\/config\/edit","shopro\/config\/del","shopro\/config\/multi","shopro\/config\/platform","shopro\/decorate","shopro\/decorate\/lists","shopro\/decorate\/add","shopro\/decorate\/edit","shopro\/decorate\/del","shopro\/decorate\/multi","shopro\/decorate\/recyclebin","shopro\/decorate\/destroy","shopro\/decorate\/restore","shopro\/decorate\/dodecorate","shopro\/decorate\/preview","shopro\/decorate\/designer","shopro\/decorate\/use_designer_template","shopro\/decorate\/custom","shopro\/decorate\/publish","shopro\/decorate\/dodecorate_save","shopro\/decorate\/copy","shopro\/decorate\/index","shopro\/decorate\/down","shopro\/coupons","shopro\/coupons\/index","shopro\/coupons\/recyclebin","shopro\/coupons\/add","shopro\/coupons\/edit","shopro\/coupons\/del","shopro\/coupons\/destroy","shopro\/coupons\/restore","shopro\/coupons\/multi","shopro\/coupons\/select","shopro\/dispatch","shopro\/dispatch\/dispatch","shopro\/dispatch\/dispatch\/index","shopro\/dispatch\/dispatch\/recyclebin","shopro\/dispatch\/dispatch\/add","shopro\/dispatch\/dispatch\/edit","shopro\/dispatch\/dispatch\/del","shopro\/dispatch\/dispatch\/destroy","shopro\/dispatch\/dispatch\/restore","shopro\/dispatch\/dispatch\/multi","shopro\/dispatch\/dispatch\/select","shopro\/dispatch\/selfetch","shopro\/dispatch\/selfetch\/index","shopro\/dispatch\/selfetch\/add","shopro\/dispatch\/selfetch\/edit","shopro\/dispatch\/selfetch\/del","shopro\/dispatch\/selfetch\/recyclebin","shopro\/dispatch\/selfetch\/restore","shopro\/dispatch\/selfetch\/destroy","shopro\/dispatch\/express","shopro\/dispatch\/express\/index","shopro\/dispatch\/express\/add","shopro\/dispatch\/express\/edit","shopro\/dispatch\/express\/del","shopro\/dispatch\/express\/recyclebin","shopro\/dispatch\/express\/restore","shopro\/dispatch\/express\/destroy","shopro\/dispatch\/store","shopro\/dispatch\/store\/index","shopro\/dispatch\/store\/add","shopro\/dispatch\/store\/edit","shopro\/dispatch\/store\/del","shopro\/dispatch\/store\/recyclebin","shopro\/dispatch\/store\/restore","shopro\/dispatch\/store\/destroy","shopro\/dispatch\/autosend","shopro\/dispatch\/autosend\/index","shopro\/dispatch\/autosend\/add","shopro\/dispatch\/autosend\/edit","shopro\/dispatch\/autosend\/recyclebin","shopro\/dispatch\/autosend\/restore","shopro\/dispatch\/autosend\/destroy","shopro\/dispatch\/autosend\/del","shopro\/express","shopro\/express\/index","shopro\/express\/add","shopro\/express\/edit","shopro\/express\/del","shopro\/express\/multi","shopro\/express\/select","shopro\/product","shopro\/category","shopro\/category\/index","shopro\/category\/add","shopro\/category\/edit","shopro\/category\/del","shopro\/category\/multi","shopro\/category\/select","shopro\/category\/update","shopro\/goods\/goods","shopro\/goods\/goods\/index","shopro\/goods\/goods\/recyclebin","shopro\/goods\/goods\/add","shopro\/goods\/goods\/edit","shopro\/goods\/goods\/del","shopro\/goods\/goods\/destroy","shopro\/goods\/goods\/restore","shopro\/goods\/goods\/multi","shopro\/goods\/goods\/select","shopro\/goods\/goods\/detail","shopro\/goods\/goods\/setstatus","shopro\/goods\/service","shopro\/goods\/service\/index","shopro\/goods\/service\/recyclebin","shopro\/goods\/service\/add","shopro\/goods\/service\/edit","shopro\/goods\/service\/del","shopro\/goods\/service\/destroy","shopro\/goods\/service\/restore","shopro\/goods\/service\/multi","shopro\/goods\/comment","shopro\/goods\/comment\/index","shopro\/goods\/comment\/recyclebin","shopro\/goods\/comment\/add","shopro\/goods\/comment\/edit","shopro\/goods\/comment\/del","shopro\/goods\/comment\/destroy","shopro\/goods\/comment\/restore","shopro\/goods\/comment\/multi","shopro\/material","shopro\/richtext","shopro\/richtext\/index","shopro\/richtext\/recyclebin","shopro\/richtext\/add","shopro\/richtext\/edit","shopro\/richtext\/del","shopro\/richtext\/destroy","shopro\/richtext\/restore","shopro\/richtext\/multi","shopro\/richtext\/select","shopro\/link","shopro\/link\/index","shopro\/link\/recyclebin","shopro\/link\/add","shopro\/link\/edit","shopro\/link\/del","shopro\/link\/destroy","shopro\/link\/restore","shopro\/link\/multi","shopro\/link\/select","shopro\/area","shopro\/area\/index","shopro\/area\/add","shopro\/area\/edit","shopro\/area\/del","shopro\/area\/multi","shopro\/area\/select","shopro\/faq","shopro\/faq\/index","shopro\/faq\/recyclebin","shopro\/faq\/add","shopro\/faq\/edit","shopro\/faq\/del","shopro\/faq\/destroy","shopro\/faq\/restore","shopro\/faq\/multi","shopro\/user_fake","shopro\/user_fake\/index","shopro\/user_fake\/add","shopro\/user_fake\/edit","shopro\/user_fake\/del","shopro\/user_fake\/multi","shopro\/user_fake\/random_user","shopro\/activity","shopro\/activity\/activity","shopro\/activity\/activity\/index","shopro\/activity\/activity\/recyclebin","shopro\/activity\/activity\/add","shopro\/activity\/activity\/edit","shopro\/activity\/activity\/del","shopro\/activity\/activity\/destroy","shopro\/activity\/activity\/restore","shopro\/activity\/activity\/multi","shopro\/activity\/activity\/createorupdatesku","shopro\/activity\/activity\/select","shopro\/activity\/activity\/sku","shopro\/activity\/activity\/detail","shopro\/activity\/activity\/all","shopro\/activity\/activity_sku_price","shopro\/activity\/activity_sku_price\/index","shopro\/activity\/activity_sku_price\/recyclebin","shopro\/activity\/activity_sku_price\/add","shopro\/activity\/activity_sku_price\/edit","shopro\/activity\/activity_sku_price\/del","shopro\/activity\/activity_sku_price\/destroy","shopro\/activity\/activity_sku_price\/restore","shopro\/activity\/activity_sku_price\/multi","shopro\/activity\/groupon","shopro\/activity\/groupon\/index","shopro\/activity\/groupon\/add","shopro\/activity\/groupon\/edit","shopro\/activity\/groupon\/del","shopro\/activity\/groupon\/multi","shopro\/activity\/groupon\/detail","shopro\/activity\/groupon\/addfictitious","shopro\/app","shopro\/app\/score_shop","shopro\/app\/score_shop\/index","shopro\/app\/score_shop\/add","shopro\/app\/score_shop\/del","shopro\/app\/score_shop\/edit","shopro\/app\/score_shop\/select","shopro\/app\/score_shop\/createorupdatesku","shopro\/app\/score_shop\/sku","shopro\/app\/score_shop\/recyclebin","shopro\/app\/score_shop\/destroy","shopro\/app\/score_shop\/restore","shopro\/app\/score_shop\/multi","shopro\/app\/live","shopro\/app\/live\/select","shopro\/app\/live\/index","shopro\/app\/live\/detail","shopro\/app\/live\/synclive","shopro\/app\/live\/recyclebin","shopro\/app\/live\/add","shopro\/app\/live\/edit","shopro\/app\/live\/del","shopro\/app\/live\/destroy","shopro\/app\/live\/restore","shopro\/app\/live\/multi","shopro\/user_wallet_apply","shopro\/user_wallet_apply\/index","shopro\/user_wallet_apply\/recyclebin","shopro\/user_wallet_apply\/add","shopro\/user_wallet_apply\/edit","shopro\/user_wallet_apply\/del","shopro\/user_wallet_apply\/destroy","shopro\/user_wallet_apply\/restore","shopro\/user_wallet_apply\/multi","shopro\/user_wallet_apply\/applyoper","shopro\/order","shopro\/order\/order","shopro\/order\/order\/index","shopro\/order\/order\/recyclebin","shopro\/order\/order\/add","shopro\/order\/order\/edit","shopro\/order\/order\/del","shopro\/order\/order\/destroy","shopro\/order\/order\/restore","shopro\/order\/order\/multi","shopro\/order\/order\/detail","shopro\/order\/order\/send","shopro\/order\/order\/aftersalefinish","shopro\/order\/order\/refund","shopro\/order\/order\/editmemo","shopro\/order\/order\/gettype","shopro\/order\/order\/refundrefuse","shopro\/order\/order\/export","shopro\/order\/order\/actions","shopro\/order\/order\/editconsignee","shopro\/order\/order_item","shopro\/order\/order_item\/index","shopro\/order\/order_item\/recyclebin","shopro\/order\/order_item\/add","shopro\/order\/order_item\/edit","shopro\/order\/order_item\/del","shopro\/order\/order_item\/destroy","shopro\/order\/order_item\/restore","shopro\/order\/order_item\/multi","shopro\/order\/aftersale","shopro\/order\/aftersale\/index","shopro\/order\/aftersale\/recyclebin","shopro\/order\/aftersale\/add","shopro\/order\/aftersale\/edit","shopro\/order\/aftersale\/del","shopro\/order\/aftersale\/destroy","shopro\/order\/aftersale\/restore","shopro\/order\/aftersale\/multi","shopro\/order\/aftersale\/detail","shopro\/order\/aftersale\/addlog","shopro\/feedback","shopro\/feedback\/index","shopro\/feedback\/recyclebin","shopro\/feedback\/add","shopro\/feedback\/edit","shopro\/feedback\/del","shopro\/feedback\/destroy","shopro\/feedback\/restore","shopro\/feedback\/multi","shopro\/feedback\/detail","shopro\/goods\/sku","shopro\/goods_sku\/index","shopro\/goods_sku\/add","shopro\/goods_sku\/edit","shopro\/goods_sku\/del","shopro\/goods_sku\/multi","shopro\/goods_sku_price","shopro\/goods_sku_price\/index","shopro\/goods_sku_price\/recyclebin","shopro\/goods_sku_price\/add","shopro\/goods_sku_price\/edit","shopro\/goods_sku_price\/del","shopro\/goods_sku_price\/destroy","shopro\/goods_sku_price\/restore","shopro\/goods_sku_price\/multi","shopro\/dashboard","shopro\/dashboard\/index","shopro\/dashboard\/add","shopro\/dashboard\/edit","shopro\/dashboard\/del","shopro\/dashboard\/multi","shopro\/wechat","shopro\/wechat\/fans\/index","shopro\/wechat\/fans\/user","shopro\/wechat\/fans\/syncfans","shopro\/wechat\/index","shopro\/wechat\/add","shopro\/wechat\/edit","shopro\/wechat\/del","shopro\/wechat\/multi","shopro\/wechat\/menu\/index","shopro\/wechat\/menu\/edit","shopro\/wechat\/menu\/add","shopro\/wechat\/menu\/del","shopro\/wechat\/menu\/publish","shopro\/wechat\/menu\/copy","shopro\/wechat\/auto_reply\/index","shopro\/wechat\/auto_reply\/add","shopro\/wechat\/auto_reply\/edit","shopro\/wechat\/auto_reply\/del","shopro\/wechat\/material\/index","shopro\/wechat\/material\/add","shopro\/wechat\/material\/edit","shopro\/wechat\/material\/detail","shopro\/wechat\/material\/del","shopro\/wechat\/material\/select","shopro\/notification","shopro\/notification\/index","shopro\/notification\/recyclebin","shopro\/notification\/add","shopro\/notification\/edit","shopro\/notification\/del","shopro\/notification\/destroy","shopro\/notification\/restore","shopro\/notification\/config","shopro\/notification\/set_template","shopro\/notification\/set_status","shopro\/select","shopro\/upload","shopro\/upload\/index","shopro\/upload\/recyclebin","shopro\/upload\/add","shopro\/upload\/edit","shopro\/upload\/del","shopro\/upload\/destroy","shopro\/upload\/restore","shopro\/upload\/multi","shopro\/store\/store","shopro\/store\/store\/index","shopro\/store\/store\/add","shopro\/store\/store\/edit","shopro\/store\/store\/del","shopro\/store\/store\/recyclebin","shopro\/store\/store\/setstatus","shopro\/store\/store\/select","shopro\/user\/user","shopro\/user\/user\/index","shopro\/user\/user\/select","shopro\/user\/user\/profile","shopro\/user\/user\/del","shopro\/user\/user\/order_log","shopro\/user\/user\/login_log","shopro\/user\/user\/money_log","shopro\/user\/user\/score_log","shopro\/user\/user\/share_log","shopro\/user\/user\/goods_favorite","shopro\/user\/user\/coupon_log","shopro\/user\/user\/goods_view","shopro\/user\/user\/recyclebin","shopro\/user\/user\/update","shopro\/user\/user\/money_recharge","shopro\/user\/user\/score_recharge","shopro\/user\/group","shopro\/user\/group\/index","shopro\/user\/group\/add","shopro\/user\/group\/edit","shopro\/user\/group\/del"],"files":["application\\admin\\controller\\shopro\\activity\\Activity.php","application\\admin\\controller\\shopro\\activity\\ActivitySkuPrice.php","application\\admin\\controller\\shopro\\activity\\Groupon.php","application\\admin\\controller\\shopro\\app\\Live.php","application\\admin\\controller\\shopro\\app\\ScoreShop.php","application\\admin\\controller\\shopro\\Area.php","application\\admin\\controller\\shopro\\Base.php","application\\admin\\controller\\shopro\\Category.php","application\\admin\\controller\\shopro\\Config.php","application\\admin\\controller\\shopro\\Coupons.php","application\\admin\\controller\\shopro\\Dashboard.php","application\\admin\\controller\\shopro\\Decorate.php","application\\admin\\controller\\shopro\\dispatch\\Autosend.php","application\\admin\\controller\\shopro\\dispatch\\Dispatch.php","application\\admin\\controller\\shopro\\dispatch\\Express.php","application\\admin\\controller\\shopro\\dispatch\\Selfetch.php","application\\admin\\controller\\shopro\\dispatch\\Store.php","application\\admin\\controller\\shopro\\Express.php","application\\admin\\controller\\shopro\\Faq.php","application\\admin\\controller\\shopro\\Feedback.php","application\\admin\\controller\\shopro\\goods\\Comment.php","application\\admin\\controller\\shopro\\goods\\Goods.php","application\\admin\\controller\\shopro\\goods\\Service.php","application\\admin\\controller\\shopro\\goods\\Sku.php","application\\admin\\controller\\shopro\\goods\\SkuPrice.php","application\\admin\\controller\\shopro\\Link.php","application\\admin\\controller\\shopro\\Notification.php","application\\admin\\controller\\shopro\\order\\Aftersale.php","application\\admin\\controller\\shopro\\order\\Order.php","application\\admin\\controller\\shopro\\order\\OrderItem.php","application\\admin\\controller\\shopro\\Richtext.php","application\\admin\\controller\\shopro\\store\\Store.php","application\\admin\\controller\\shopro\\Upload.php","application\\admin\\controller\\shopro\\user\\Group.php","application\\admin\\controller\\shopro\\user\\Rule.php","application\\admin\\controller\\shopro\\user\\User.php","application\\admin\\controller\\shopro\\UserFake.php","application\\admin\\controller\\shopro\\UserWalletApply.php","application\\admin\\controller\\shopro\\wechat\\AutoReply.php","application\\admin\\controller\\shopro\\wechat\\Fans.php","application\\admin\\controller\\shopro\\wechat\\Material.php","application\\admin\\controller\\shopro\\wechat\\Menu.php","application\\admin\\lang\\zh-cn\\shopro\\activity\\activity.php","application\\admin\\lang\\zh-cn\\shopro\\activity\\activity_sku_price.php","application\\admin\\lang\\zh-cn\\shopro\\activity\\groupon.php","application\\admin\\lang\\zh-cn\\shopro\\app\\live.php","application\\admin\\lang\\zh-cn\\shopro\\app\\score_shop.php","application\\admin\\lang\\zh-cn\\shopro\\area.php","application\\admin\\lang\\zh-cn\\shopro\\category.php","application\\admin\\lang\\zh-cn\\shopro\\config.php","application\\admin\\lang\\zh-cn\\shopro\\coupons.php","application\\admin\\lang\\zh-cn\\shopro\\decorate.php","application\\admin\\lang\\zh-cn\\shopro\\dispatch\\dispatch.php","application\\admin\\lang\\zh-cn\\shopro\\dispatch\\express.php","application\\admin\\lang\\zh-cn\\shopro\\dispatch\\expressname.php","application\\admin\\lang\\zh-cn\\shopro\\dispatch\\store.php","application\\admin\\lang\\zh-cn\\shopro\\faq.php","application\\admin\\lang\\zh-cn\\shopro\\feedback.php","application\\admin\\lang\\zh-cn\\shopro\\goods\\comment.php","application\\admin\\lang\\zh-cn\\shopro\\goods\\goods.php","application\\admin\\lang\\zh-cn\\shopro\\goods\\service.php","application\\admin\\lang\\zh-cn\\shopro\\goods\\sku.php","application\\admin\\lang\\zh-cn\\shopro\\goods\\sku_price.php","application\\admin\\lang\\zh-cn\\shopro\\link.php","application\\admin\\lang\\zh-cn\\shopro\\notification\\config.php","application\\admin\\lang\\zh-cn\\shopro\\notification.php","application\\admin\\lang\\zh-cn\\shopro\\order\\aftersale.php","application\\admin\\lang\\zh-cn\\shopro\\order\\order.php","application\\admin\\lang\\zh-cn\\shopro\\order\\order_item.php","application\\admin\\lang\\zh-cn\\shopro\\order\\refund_log.php","application\\admin\\lang\\zh-cn\\shopro\\richtext.php","application\\admin\\lang\\zh-cn\\shopro\\share.php","application\\admin\\lang\\zh-cn\\shopro\\upload.php","application\\admin\\lang\\zh-cn\\shopro\\user\\group.php","application\\admin\\lang\\zh-cn\\shopro\\user\\rule.php","application\\admin\\lang\\zh-cn\\shopro\\user\\user.php","application\\admin\\lang\\zh-cn\\shopro\\user_fake.php","application\\admin\\lang\\zh-cn\\shopro\\user_wallet_apply.php","application\\admin\\lang\\zh-cn\\shopro\\wechat\\fans.php","application\\admin\\lang\\zh-cn\\shopro\\wechat.php","application\\admin\\model\\shopro\\activity\\Activity.php","application\\admin\\model\\shopro\\activity\\ActivitySkuPrice.php","application\\admin\\model\\shopro\\activity\\Groupon.php","application\\admin\\model\\shopro\\activity\\GrouponLog.php","application\\admin\\model\\shopro\\app\\Live.php","application\\admin\\model\\shopro\\app\\ScoreSkuPrice.php","application\\admin\\model\\shopro\\Area.php","application\\admin\\model\\shopro\\Category.php","application\\admin\\model\\shopro\\Config.php","application\\admin\\model\\shopro\\Coupons.php","application\\admin\\model\\shopro\\Decorate.php","application\\admin\\model\\shopro\\DecorateContent.php","application\\admin\\model\\shopro\\DecoratePage.php","application\\admin\\model\\shopro\\dispatch\\Autosend.php","application\\admin\\model\\shopro\\dispatch\\Dispatch.php","application\\admin\\model\\shopro\\dispatch\\Express.php","application\\admin\\model\\shopro\\dispatch\\ExpressCompany.php","application\\admin\\model\\shopro\\dispatch\\Selfetch.php","application\\admin\\model\\shopro\\dispatch\\Store.php","application\\admin\\model\\shopro\\Express.php","application\\admin\\model\\shopro\\Faq.php","application\\admin\\model\\shopro\\Feedback.php","application\\admin\\model\\shopro\\goods\\Comment.php","application\\admin\\model\\shopro\\goods\\Goods.php","application\\admin\\model\\shopro\\goods\\Service.php","application\\admin\\model\\shopro\\goods\\Sku.php","application\\admin\\model\\shopro\\goods\\SkuPrice.php","application\\admin\\model\\shopro\\Link.php","application\\admin\\model\\shopro\\notification\\Config.php","application\\admin\\model\\shopro\\Notification.php","application\\admin\\model\\shopro\\order\\Aftersale.php","application\\admin\\model\\shopro\\order\\AftersaleLog.php","application\\admin\\model\\shopro\\order\\Order.php","application\\admin\\model\\shopro\\order\\OrderAction.php","application\\admin\\model\\shopro\\order\\OrderExpress.php","application\\admin\\model\\shopro\\order\\OrderExpressLog.php","application\\admin\\model\\shopro\\order\\OrderItem.php","application\\admin\\model\\shopro\\order\\RefundLog.php","application\\admin\\model\\shopro\\Richtext.php","application\\admin\\model\\shopro\\Share.php","application\\admin\\model\\shopro\\store\\Store.php","application\\admin\\model\\shopro\\Upload.php","application\\admin\\model\\shopro\\user\\Coupon.php","application\\admin\\model\\shopro\\user\\Favorite.php","application\\admin\\model\\shopro\\user\\Group.php","application\\admin\\model\\shopro\\user\\MoneyLog.php","application\\admin\\model\\shopro\\user\\Oauth.php","application\\admin\\model\\shopro\\user\\ScoreLog.php","application\\admin\\model\\shopro\\user\\User.php","application\\admin\\model\\shopro\\user\\View.php","application\\admin\\model\\shopro\\UserFake.php","application\\admin\\model\\shopro\\UserWalletApply.php","application\\admin\\model\\shopro\\wechat\\Fans.php","application\\admin\\model\\shopro\\wechat\\Wechat.php","application\\admin\\validate\\shopro\\activity\\Activity.php","application\\admin\\validate\\shopro\\activity\\ActivitySkuPrice.php","application\\admin\\validate\\shopro\\activity\\Groupon.php","application\\admin\\validate\\shopro\\app\\Live.php","application\\admin\\validate\\shopro\\Area.php","application\\admin\\validate\\shopro\\Category.php","application\\admin\\validate\\shopro\\Config.php","application\\admin\\validate\\shopro\\Coupons.php","application\\admin\\validate\\shopro\\Decorate.php","application\\admin\\validate\\shopro\\dispatch\\Dispatch.php","application\\admin\\validate\\shopro\\dispatch\\Express.php","application\\admin\\validate\\shopro\\dispatch\\Expressname.php","application\\admin\\validate\\shopro\\dispatch\\Store.php","application\\admin\\validate\\shopro\\Faq.php","application\\admin\\validate\\shopro\\Feedback.php","application\\admin\\validate\\shopro\\Goods.php","application\\admin\\validate\\shopro\\GoodsComment.php","application\\admin\\validate\\shopro\\GoodsService.php","application\\admin\\validate\\shopro\\GoodsSku.php","application\\admin\\validate\\shopro\\GoodsSkuPrice.php","application\\admin\\validate\\shopro\\Link.php","application\\admin\\validate\\shopro\\notification\\Config.php","application\\admin\\validate\\shopro\\Notification.php","application\\admin\\validate\\shopro\\Notification_config.php","application\\admin\\validate\\shopro\\order\\Aftersale.php","application\\admin\\validate\\shopro\\order\\Order.php","application\\admin\\validate\\shopro\\order\\OrderItem.php","application\\admin\\validate\\shopro\\Richtext.php","application\\admin\\validate\\shopro\\Upload.php","application\\admin\\validate\\shopro\\UserFake.php","application\\admin\\validate\\shopro\\UserWalletApply.php","application\\admin\\validate\\shopro\\wechat\\Fans.php","application\\admin\\validate\\shopro\\Wechat.php","application\\admin\\view\\shopro\\activity\\activity\\add.html","application\\admin\\view\\shopro\\activity\\activity\\edit.html","application\\admin\\view\\shopro\\activity\\activity\\index.html","application\\admin\\view\\shopro\\activity\\activity\\recyclebin.html","application\\admin\\view\\shopro\\activity\\activity\\select.html","application\\admin\\view\\shopro\\activity\\activity\\sku.html","application\\admin\\view\\shopro\\activity\\activity_sku_price\\add.html","application\\admin\\view\\shopro\\activity\\activity_sku_price\\edit.html","application\\admin\\view\\shopro\\activity\\activity_sku_price\\index.html","application\\admin\\view\\shopro\\activity\\activity_sku_price\\recyclebin.html","application\\admin\\view\\shopro\\activity\\groupon\\add.html","application\\admin\\view\\shopro\\activity\\groupon\\detail.html","application\\admin\\view\\shopro\\activity\\groupon\\edit.html","application\\admin\\view\\shopro\\activity\\groupon\\index.html","application\\admin\\view\\shopro\\app\\live\\add.html","application\\admin\\view\\shopro\\app\\live\\detail.html","application\\admin\\view\\shopro\\app\\live\\edit.html","application\\admin\\view\\shopro\\app\\live\\index.html","application\\admin\\view\\shopro\\app\\live\\recyclebin.html","application\\admin\\view\\shopro\\app\\live\\select.html","application\\admin\\view\\shopro\\app\\score_shop\\add.html","application\\admin\\view\\shopro\\app\\score_shop\\edit.html","application\\admin\\view\\shopro\\app\\score_shop\\index.html","application\\admin\\view\\shopro\\app\\score_shop\\recyclebin.html","application\\admin\\view\\shopro\\app\\score_shop\\select.html","application\\admin\\view\\shopro\\app\\score_shop\\sku.html","application\\admin\\view\\shopro\\area\\add.html","application\\admin\\view\\shopro\\area\\edit.html","application\\admin\\view\\shopro\\area\\index.html","application\\admin\\view\\shopro\\area\\select.html","application\\admin\\view\\shopro\\category\\add.html","application\\admin\\view\\shopro\\category\\edit.html","application\\admin\\view\\shopro\\category\\index.html","application\\admin\\view\\shopro\\category\\select.html","application\\admin\\view\\shopro\\config\\add.html","application\\admin\\view\\shopro\\config\\edit.html","application\\admin\\view\\shopro\\config\\index.html","application\\admin\\view\\shopro\\config\\platform.html","application\\admin\\view\\shopro\\coupons\\add.html","application\\admin\\view\\shopro\\coupons\\edit.html","application\\admin\\view\\shopro\\coupons\\index.html","application\\admin\\view\\shopro\\coupons\\recyclebin.html","application\\admin\\view\\shopro\\coupons\\select.html","application\\admin\\view\\shopro\\dashboard\\index.html","application\\admin\\view\\shopro\\decorate\\add.html","application\\admin\\view\\shopro\\decorate\\custom.html","application\\admin\\view\\shopro\\decorate\\designer.html","application\\admin\\view\\shopro\\decorate\\dodecorate.html","application\\admin\\view\\shopro\\decorate\\edit.html","application\\admin\\view\\shopro\\decorate\\index.html","application\\admin\\view\\shopro\\decorate\\lists.html","application\\admin\\view\\shopro\\decorate\\recyclebin.html","application\\admin\\view\\shopro\\decorate\\select.html","application\\admin\\view\\shopro\\dispatch\\autosend\\add.html","application\\admin\\view\\shopro\\dispatch\\autosend\\edit.html","application\\admin\\view\\shopro\\dispatch\\autosend\\index.html","application\\admin\\view\\shopro\\dispatch\\autosend\\recyclebin.html","application\\admin\\view\\shopro\\dispatch\\dispatch\\add.html","application\\admin\\view\\shopro\\dispatch\\dispatch\\edit.html","application\\admin\\view\\shopro\\dispatch\\dispatch\\index.html","application\\admin\\view\\shopro\\dispatch\\dispatch\\recyclebin.html","application\\admin\\view\\shopro\\dispatch\\express\\add.html","application\\admin\\view\\shopro\\dispatch\\express\\edit.html","application\\admin\\view\\shopro\\dispatch\\express\\index.html","application\\admin\\view\\shopro\\dispatch\\express\\recyclebin.html","application\\admin\\view\\shopro\\dispatch\\selfetch\\add.html","application\\admin\\view\\shopro\\dispatch\\selfetch\\edit.html","application\\admin\\view\\shopro\\dispatch\\selfetch\\index.html","application\\admin\\view\\shopro\\dispatch\\selfetch\\recyclebin.html","application\\admin\\view\\shopro\\dispatch\\store\\add.html","application\\admin\\view\\shopro\\dispatch\\store\\edit.html","application\\admin\\view\\shopro\\dispatch\\store\\index.html","application\\admin\\view\\shopro\\dispatch\\store\\recyclebin.html","application\\admin\\view\\shopro\\express\\add.html","application\\admin\\view\\shopro\\express\\edit.html","application\\admin\\view\\shopro\\express\\index.html","application\\admin\\view\\shopro\\faq\\add.html","application\\admin\\view\\shopro\\faq\\edit.html","application\\admin\\view\\shopro\\faq\\index.html","application\\admin\\view\\shopro\\faq\\recyclebin.html","application\\admin\\view\\shopro\\feedback\\add.html","application\\admin\\view\\shopro\\feedback\\edit.html","application\\admin\\view\\shopro\\feedback\\index.html","application\\admin\\view\\shopro\\feedback\\recyclebin.html","application\\admin\\view\\shopro\\goods\\comment\\add.html","application\\admin\\view\\shopro\\goods\\comment\\edit.html","application\\admin\\view\\shopro\\goods\\comment\\index.html","application\\admin\\view\\shopro\\goods\\comment\\recyclebin.html","application\\admin\\view\\shopro\\goods\\goods\\add.html","application\\admin\\view\\shopro\\goods\\goods\\edit.html","application\\admin\\view\\shopro\\goods\\goods\\index.html","application\\admin\\view\\shopro\\goods\\goods\\recyclebin.html","application\\admin\\view\\shopro\\goods\\goods\\select.html","application\\admin\\view\\shopro\\goods\\goods\\sku.html","application\\admin\\view\\shopro\\goods\\goods\\skuedit.html","application\\admin\\view\\shopro\\goods\\service\\add.html","application\\admin\\view\\shopro\\goods\\service\\edit.html","application\\admin\\view\\shopro\\goods\\service\\index.html","application\\admin\\view\\shopro\\goods\\service\\recyclebin.html","application\\admin\\view\\shopro\\goods\\sku\\add.html","application\\admin\\view\\shopro\\goods\\sku\\edit.html","application\\admin\\view\\shopro\\goods\\sku\\index.html","application\\admin\\view\\shopro\\goods\\sku_price\\add.html","application\\admin\\view\\shopro\\goods\\sku_price\\edit.html","application\\admin\\view\\shopro\\goods\\sku_price\\index.html","application\\admin\\view\\shopro\\goods\\sku_price\\recyclebin.html","application\\admin\\view\\shopro\\link\\add.html","application\\admin\\view\\shopro\\link\\edit.html","application\\admin\\view\\shopro\\link\\index.html","application\\admin\\view\\shopro\\link\\recyclebin.html","application\\admin\\view\\shopro\\link\\select.html","application\\admin\\view\\shopro\\notification\\config.html","application\\admin\\view\\shopro\\notification\\edit.html","application\\admin\\view\\shopro\\notification\\index.html","application\\admin\\view\\shopro\\notification\\recyclebin.html","application\\admin\\view\\shopro\\order\\aftersale\\add.html","application\\admin\\view\\shopro\\order\\aftersale\\detail.html","application\\admin\\view\\shopro\\order\\aftersale\\edit.html","application\\admin\\view\\shopro\\order\\aftersale\\index.html","application\\admin\\view\\shopro\\order\\aftersale\\recyclebin.html","application\\admin\\view\\shopro\\order\\order\\add.html","application\\admin\\view\\shopro\\order\\order\\detail.html","application\\admin\\view\\shopro\\order\\order\\edit.html","application\\admin\\view\\shopro\\order\\order\\index.html","application\\admin\\view\\shopro\\order\\order\\recyclebin.html","application\\admin\\view\\shopro\\order\\order_item\\add.html","application\\admin\\view\\shopro\\order\\order_item\\edit.html","application\\admin\\view\\shopro\\order\\order_item\\index.html","application\\admin\\view\\shopro\\order\\order_item\\recyclebin.html","application\\admin\\view\\shopro\\richtext\\add.html","application\\admin\\view\\shopro\\richtext\\edit.html","application\\admin\\view\\shopro\\richtext\\index.html","application\\admin\\view\\shopro\\richtext\\recyclebin.html","application\\admin\\view\\shopro\\richtext\\select.html","application\\admin\\view\\shopro\\store\\store\\add.html","application\\admin\\view\\shopro\\store\\store\\edit.html","application\\admin\\view\\shopro\\store\\store\\index.html","application\\admin\\view\\shopro\\store\\store\\recyclebin.html","application\\admin\\view\\shopro\\upload\\add.html","application\\admin\\view\\shopro\\upload\\edit.html","application\\admin\\view\\shopro\\upload\\index.html","application\\admin\\view\\shopro\\upload\\recyclebin.html","application\\admin\\view\\shopro\\upload\\select.html","application\\admin\\view\\shopro\\user\\group\\add.html","application\\admin\\view\\shopro\\user\\group\\edit.html","application\\admin\\view\\shopro\\user\\group\\index.html","application\\admin\\view\\shopro\\user\\rule\\add.html","application\\admin\\view\\shopro\\user\\rule\\edit.html","application\\admin\\view\\shopro\\user\\rule\\index.html","application\\admin\\view\\shopro\\user\\user\\index.html","application\\admin\\view\\shopro\\user\\user\\money_recharge.html","application\\admin\\view\\shopro\\user\\user\\profile.html","application\\admin\\view\\shopro\\user\\user\\score_recharge.html","application\\admin\\view\\shopro\\user_fake\\add.html","application\\admin\\view\\shopro\\user_fake\\edit.html","application\\admin\\view\\shopro\\user_fake\\index.html","application\\admin\\view\\shopro\\user_wallet_apply\\add.html","application\\admin\\view\\shopro\\user_wallet_apply\\edit.html","application\\admin\\view\\shopro\\user_wallet_apply\\index.html","application\\admin\\view\\shopro\\user_wallet_apply\\recyclebin.html","application\\admin\\view\\shopro\\wechat\\auto_reply\\add.html","application\\admin\\view\\shopro\\wechat\\auto_reply\\edit.html","application\\admin\\view\\shopro\\wechat\\auto_reply\\index.html","application\\admin\\view\\shopro\\wechat\\fans\\index.html","application\\admin\\view\\shopro\\wechat\\material\\add.html","application\\admin\\view\\shopro\\wechat\\material\\edit.html","application\\admin\\view\\shopro\\wechat\\material\\index.html","application\\admin\\view\\shopro\\wechat\\menu\\add.html","application\\admin\\view\\shopro\\wechat\\menu\\edit.html","application\\admin\\view\\shopro\\wechat\\menu\\index.html","public\\assets\\addons\\shopro\\img\\category\\edit.png","public\\assets\\addons\\shopro\\img\\category\\img-1.png","public\\assets\\addons\\shopro\\img\\category\\img-2.png","public\\assets\\addons\\shopro\\img\\category\\img-3.png","public\\assets\\addons\\shopro\\img\\category\\img-4.png","public\\assets\\addons\\shopro\\img\\category\\selected.png","public\\assets\\addons\\shopro\\img\\config\\alipay-icon.png","public\\assets\\addons\\shopro\\img\\config\\App-icon.png","public\\assets\\addons\\shopro\\img\\config\\apple-icon.png","public\\assets\\addons\\shopro\\img\\config\\h5-icon.png","public\\assets\\addons\\shopro\\img\\config\\order-icon.png","public\\assets\\addons\\shopro\\img\\config\\score-icon.png","public\\assets\\addons\\shopro\\img\\config\\services-icon.png","public\\assets\\addons\\shopro\\img\\config\\share-icon.png","public\\assets\\addons\\shopro\\img\\config\\shopro-icon.png","public\\assets\\addons\\shopro\\img\\config\\user-icon.png","public\\assets\\addons\\shopro\\img\\config\\wallet-icon.png","public\\assets\\addons\\shopro\\img\\config\\wechat-icon.png","public\\assets\\addons\\shopro\\img\\config\\withdraw-icon.png","public\\assets\\addons\\shopro\\img\\config\\wxMiniProgram-icon.png","public\\assets\\addons\\shopro\\img\\config\\wxOfficialAccount-icon.png","public\\assets\\addons\\shopro\\img\\dashboard\\1.png","public\\assets\\addons\\shopro\\img\\dashboard\\2.png","public\\assets\\addons\\shopro\\img\\dashboard\\3.png","public\\assets\\addons\\shopro\\img\\dashboard\\4.png","public\\assets\\addons\\shopro\\img\\dashboard\\5.png","public\\assets\\addons\\shopro\\img\\dashboard\\6.png","public\\assets\\addons\\shopro\\img\\dashboard\\icon-1.png","public\\assets\\addons\\shopro\\img\\dashboard\\icon-2.png","public\\assets\\addons\\shopro\\img\\dashboard\\icon-3.png","public\\assets\\addons\\shopro\\img\\dashboard\\icon-4.png","public\\assets\\addons\\shopro\\img\\dashboard\\icon-5.png","public\\assets\\addons\\shopro\\img\\dashboard\\icon-6.png","public\\assets\\addons\\shopro\\img\\decorate\\adv.png","public\\assets\\addons\\shopro\\img\\decorate\\adv_01.png","public\\assets\\addons\\shopro\\img\\decorate\\adv_02.png","public\\assets\\addons\\shopro\\img\\decorate\\adv_03.png","public\\assets\\addons\\shopro\\img\\decorate\\adv_04.png","public\\assets\\addons\\shopro\\img\\decorate\\adv_05.png","public\\assets\\addons\\shopro\\img\\decorate\\adv_06.png","public\\assets\\addons\\shopro\\img\\decorate\\adv_07.png","public\\assets\\addons\\shopro\\img\\decorate\\adv_bg.png","public\\assets\\addons\\shopro\\img\\decorate\\App.png","public\\assets\\addons\\shopro\\img\\decorate\\banner.png","public\\assets\\addons\\shopro\\img\\decorate\\banner_bg.png","public\\assets\\addons\\shopro\\img\\decorate\\code_1.png","public\\assets\\addons\\shopro\\img\\decorate\\copy-btn.png","public\\assets\\addons\\shopro\\img\\decorate\\coupon.png","public\\assets\\addons\\shopro\\img\\decorate\\coupons_bg.png","public\\assets\\addons\\shopro\\img\\decorate\\coupon_bg1.png","public\\assets\\addons\\shopro\\img\\decorate\\decorate-btn.png","public\\assets\\addons\\shopro\\img\\decorate\\delete-btn.png","public\\assets\\addons\\shopro\\img\\decorate\\down-btn.png","public\\assets\\addons\\shopro\\img\\decorate\\edit-btn.png","public\\assets\\addons\\shopro\\img\\decorate\\float-button.png","public\\assets\\addons\\shopro\\img\\decorate\\float-button_bg.png","public\\assets\\addons\\shopro\\img\\decorate\\goods-group.png","public\\assets\\addons\\shopro\\img\\decorate\\goods-group_bg.png","public\\assets\\addons\\shopro\\img\\decorate\\goods-list.png","public\\assets\\addons\\shopro\\img\\decorate\\goods-list_bg.png","public\\assets\\addons\\shopro\\img\\decorate\\goods_bg.png","public\\assets\\addons\\shopro\\img\\decorate\\grid-list.png","public\\assets\\addons\\shopro\\img\\decorate\\grid-list_bg.png","public\\assets\\addons\\shopro\\img\\decorate\\groupon.png","public\\assets\\addons\\shopro\\img\\decorate\\groupon_bg.png","public\\assets\\addons\\shopro\\img\\decorate\\H5.png","public\\assets\\addons\\shopro\\img\\decorate\\image-default.png","public\\assets\\addons\\shopro\\img\\decorate\\image-default2.png","public\\assets\\addons\\shopro\\img\\decorate\\image-default3.png","public\\assets\\addons\\shopro\\img\\decorate\\live.png","public\\assets\\addons\\shopro\\img\\decorate\\live_bg.png","public\\assets\\addons\\shopro\\img\\decorate\\menu.png","public\\assets\\addons\\shopro\\img\\decorate\\menu_bg.png","public\\assets\\addons\\shopro\\img\\decorate\\nav-list.png","public\\assets\\addons\\shopro\\img\\decorate\\nav-list_bg.png","public\\assets\\addons\\shopro\\img\\decorate\\order-card.png","public\\assets\\addons\\shopro\\img\\decorate\\order-card_bg.png","public\\assets\\addons\\shopro\\img\\decorate\\popover_bg.png","public\\assets\\addons\\shopro\\img\\decorate\\popup.png","public\\assets\\addons\\shopro\\img\\decorate\\preview-btn.png","public\\assets\\addons\\shopro\\img\\decorate\\preview_bg.png","public\\assets\\addons\\shopro\\img\\decorate\\recycle-btn.png","public\\assets\\addons\\shopro\\img\\decorate\\release-btn.png","public\\assets\\addons\\shopro\\img\\decorate\\rich-text.png","public\\assets\\addons\\shopro\\img\\decorate\\rich-text_bg.png","public\\assets\\addons\\shopro\\img\\decorate\\search.png","public\\assets\\addons\\shopro\\img\\decorate\\search_bg.png","public\\assets\\addons\\shopro\\img\\decorate\\secKill.png","public\\assets\\addons\\shopro\\img\\decorate\\secKill_bg.png","public\\assets\\addons\\shopro\\img\\decorate\\tabbar.png","public\\assets\\addons\\shopro\\img\\decorate\\tabs-header.png","public\\assets\\addons\\shopro\\img\\decorate\\title-block.png","public\\assets\\addons\\shopro\\img\\decorate\\title-block_bg.png","public\\assets\\addons\\shopro\\img\\decorate\\title1.png","public\\assets\\addons\\shopro\\img\\decorate\\title2.png","public\\assets\\addons\\shopro\\img\\decorate\\title3.png","public\\assets\\addons\\shopro\\img\\decorate\\title4.png","public\\assets\\addons\\shopro\\img\\decorate\\title5.png","public\\assets\\addons\\shopro\\img\\decorate\\user.png","public\\assets\\addons\\shopro\\img\\decorate\\user_bg.png","public\\assets\\addons\\shopro\\img\\decorate\\wallet-card.png","public\\assets\\addons\\shopro\\img\\decorate\\wallet-card_bg.png","public\\assets\\addons\\shopro\\img\\decorate\\wxMiniProgram.png","public\\assets\\addons\\shopro\\img\\decorate\\wxOfficialAccount.png","public\\assets\\addons\\shopro\\img\\decorate\\zujian.png","public\\assets\\addons\\shopro\\img\\default-avatar.png","public\\assets\\addons\\shopro\\img\\derocate_down.png","public\\assets\\addons\\shopro\\img\\derocate_up.png","public\\assets\\addons\\shopro\\img\\dispatch\\position-icon.png","public\\assets\\addons\\shopro\\img\\goods\\active.png","public\\assets\\addons\\shopro\\img\\goods\\batch.png","public\\assets\\addons\\shopro\\img\\goods\\close.png","public\\assets\\addons\\shopro\\img\\goods\\entity.png","public\\assets\\addons\\shopro\\img\\goods\\hover.png","public\\assets\\addons\\shopro\\img\\goods\\move.png","public\\assets\\addons\\shopro\\img\\goods\\selected.png","public\\assets\\addons\\shopro\\img\\goods\\virtual.png","public\\assets\\addons\\shopro\\img\\notification\\email.png","public\\assets\\addons\\shopro\\img\\notification\\note.png","public\\assets\\addons\\shopro\\img\\notification\\wxMiniProgram.png","public\\assets\\addons\\shopro\\img\\notification\\wxOfficialAccount.png","public\\assets\\addons\\shopro\\img\\order\\App.png","public\\assets\\addons\\shopro\\img\\order\\H5.png","public\\assets\\addons\\shopro\\img\\order\\wxMiniProgram.png","public\\assets\\addons\\shopro\\img\\order\\wxOfficialAccount.png","public\\assets\\addons\\shopro\\img\\sku_close.png","public\\assets\\addons\\shopro\\img\\wechat\\add-btn.png","public\\assets\\addons\\shopro\\img\\wechat\\avatar.jpg","public\\assets\\addons\\shopro\\img\\wechat\\code.png","public\\assets\\addons\\shopro\\img\\wechat\\female.png","public\\assets\\addons\\shopro\\img\\wechat\\male-female.png","public\\assets\\addons\\shopro\\img\\wechat\\male.png","public\\assets\\addons\\shopro\\img\\xinu.png","public\\assets\\addons\\shopro\\libs\\antv.js","public\\assets\\addons\\shopro\\libs\\clipboard.min.js","public\\assets\\addons\\shopro\\libs\\color-thief.js","public\\assets\\addons\\shopro\\libs\\common.css","public\\assets\\addons\\shopro\\libs\\element\\element.css","public\\assets\\addons\\shopro\\libs\\element\\element.js","public\\assets\\addons\\shopro\\libs\\element\\fonts\\element-icons.ttf","public\\assets\\addons\\shopro\\libs\\element\\fonts\\element-icons.woff","public\\assets\\addons\\shopro\\libs\\moment.js","public\\assets\\addons\\shopro\\libs\\Sortable.min.js","public\\assets\\addons\\shopro\\libs\\vue-dev.js","public\\assets\\addons\\shopro\\libs\\vue.js","public\\assets\\addons\\shopro\\libs\\vuedraggable.js","public\\assets\\js\\backend\\shopro\\activity\\activity.js","public\\assets\\js\\backend\\shopro\\activity\\activity_sku_price.js","public\\assets\\js\\backend\\shopro\\activity\\groupon.js","public\\assets\\js\\backend\\shopro\\app\\live.js","public\\assets\\js\\backend\\shopro\\app\\score_shop.js","public\\assets\\js\\backend\\shopro\\area.js","public\\assets\\js\\backend\\shopro\\category.js","public\\assets\\js\\backend\\shopro\\config.js","public\\assets\\js\\backend\\shopro\\coupons.js","public\\assets\\js\\backend\\shopro\\dashboard.js","public\\assets\\js\\backend\\shopro\\decorate.js","public\\assets\\js\\backend\\shopro\\dispatch\\autosend.js","public\\assets\\js\\backend\\shopro\\dispatch\\dispatch.js","public\\assets\\js\\backend\\shopro\\dispatch\\express.js","public\\assets\\js\\backend\\shopro\\dispatch\\selfetch.js","public\\assets\\js\\backend\\shopro\\dispatch\\store.js","public\\assets\\js\\backend\\shopro\\express.js","public\\assets\\js\\backend\\shopro\\faq.js","public\\assets\\js\\backend\\shopro\\feedback.js","public\\assets\\js\\backend\\shopro\\goods\\comment.js","public\\assets\\js\\backend\\shopro\\goods\\goods.js","public\\assets\\js\\backend\\shopro\\goods\\service.js","public\\assets\\js\\backend\\shopro\\goods\\sku.js","public\\assets\\js\\backend\\shopro\\goods\\sku_price.js","public\\assets\\js\\backend\\shopro\\link.js","public\\assets\\js\\backend\\shopro\\notification.js","public\\assets\\js\\backend\\shopro\\order\\aftersale.js","public\\assets\\js\\backend\\shopro\\order\\order.js","public\\assets\\js\\backend\\shopro\\order\\order_item.js","public\\assets\\js\\backend\\shopro\\richtext.js","public\\assets\\js\\backend\\shopro\\store\\store.js","public\\assets\\js\\backend\\shopro\\upload.js","public\\assets\\js\\backend\\shopro\\user\\group.js","public\\assets\\js\\backend\\shopro\\user\\user.js","public\\assets\\js\\backend\\shopro\\user_fake.js","public\\assets\\js\\backend\\shopro\\user_wallet_apply.js","public\\assets\\js\\backend\\shopro\\wechat\\auto_reply.js","public\\assets\\js\\backend\\shopro\\wechat\\fans.js","public\\assets\\js\\backend\\shopro\\wechat\\material.js","public\\assets\\js\\backend\\shopro\\wechat\\menu.js"]}
\ No newline at end of file
... ...
<?php
namespace addons\shopro;
use think\Addons;
use app\common\library\Menu;
use app\admin\model\AuthRule;
use addons\shopro\library\Hook;
use think\Exception;
use think\exception\PDOException;
/**
* Shopro插件 v1.0.7
*/
class Shopro extends Addons
{
/**
* 插件安装方法
* @return bool
*/
public function install()
{
$menu = self::getMenu();
Menu::create($menu['new']);
return true;
}
/**
* 插件卸载方法
* @return bool
*/
public function uninstall()
{
Menu::delete('shopro');
return true;
}
/**
* 插件启用方法
*/
public function enable()
{
Menu::enable('shopro');
return true;
}
/**
* 插件更新方法
*/
public function upgrade()
{
$menu = self::getMenu();
if(method_exists(Menu::class, 'upgrade')){
Menu::upgrade('shopro', $menu['new']);
}else {
//使用Shopro自带的更新操作
self::menuCreateOrUpdate($menu['new'], $menu['old']);
}
return true;
}
/**
* 插件禁用方法
*/
public function disable()
{
Menu::disable('shopro');
return true;
}
/**
* 应用初始化
*/
public function appInit()
{
//不使用官方epay插件,可以打开此处loader,Shopro已预制YansongdaPay的依赖
// \think\Loader::addNamespace('Yansongda\Pay', ADDON_PATH . 'shopro' . DS . 'library' . DS . 'Yansongda' . DS);
// \think\Loader::addNamespace('Yansongda\Supports', ADDON_PATH . 'shopro' . DS . 'library' . DS . 'Supports' . DS);
// 公共方法
require_once __DIR__ . '/helper.php';
// 全局注册行为事件
Hook::register();
}
private static function getMenu()
{
$newMenu = [];
$config_file = ADDON_PATH . "shopro" . DS . 'config' . DS . "menu.php";
if (is_file($config_file)) {
$newMenu = include $config_file;
}
$oldMenu = AuthRule::where('name','like',"shopro%")->select();
$oldMenu = array_column($oldMenu, null, 'name');
return ['new' => $newMenu, 'old' => $oldMenu];
}
private static function menuCreateOrUpdate($newMenu, $oldMenu, $parent = 0)
{
if (!is_numeric($parent)) {
$parentRule = AuthRule::getByName($parent);
$pid = $parentRule ? $parentRule['id'] : 0;
} else {
$pid = $parent;
}
$allow = array_flip(['file', 'name', 'title', 'icon', 'condition', 'remark', 'ismenu', 'weigh']);
foreach ($newMenu as $k => $v) {
$hasChild = isset($v['sublist']) && $v['sublist'] ? true : false;
$data = array_intersect_key($v, $allow);
$data['ismenu'] = isset($data['ismenu']) ? $data['ismenu'] : ($hasChild ? 1 : 0);
$data['icon'] = isset($data['icon']) ? $data['icon'] : ($hasChild ? 'fa fa-list' : 'fa fa-circle-o');
$data['pid'] = $pid;
$data['status'] = 'normal';
try {
if (!isset($oldMenu[$data['name']])) {
$menu = AuthRule::create($data);
}else{
$menu = $oldMenu[$data['name']];
}
if ($hasChild) {
self::menuCreateOrUpdate($v['sublist'], $oldMenu, $menu['id']);
}
} catch (PDOException $e) {
throw new Exception($e->getMessage());
}
}
}
}
\ No newline at end of file
... ...
<?php
return [
"table_name" => "",
"self_path" => "\r\npublic/assets/addons/shopro\r\napplication/admin/lang/zh-cn/shopro",
"update_data" => ""
];
\ No newline at end of file
... ...
此 diff 太大无法显示。
<?php
namespace addons\shopro\controller;
/**
* 拼团开的团
*
*/
class ActivityGroupon extends Base
{
protected $noNeedLogin = ['index'];
protected $noNeedRight = ['*'];
/**
* 根据商品 id 获取正在拼的团
*/
public function index() {
$params = $this->request->get();
$this->success('团列表', \addons\shopro\model\ActivityGroupon::getActivityGroupon($params));
}
public function detail () {
$id = $this->request->get('id');
$this->success('团详情', \addons\shopro\model\ActivityGroupon::getActivityGrouponDetail($id));
}
public function myGroupon () {
$type = $this->request->get('type', 'all');
$user = $this->auth->getUserInfo();
$logs = \addons\shopro\model\ActivityGrouponLog::with(['groupon', 'order.firstItem', 'goods' => function ($query) {
$query->removeOption('soft_delete'); // 商品查询包括被软删除的
}]);
if ($type != 'all') {
$type = $type == 'finish' ? ['finish', 'finish-fictitious'] : [$type];
$logs = $logs->whereExists(function ($query) use ($type) {
$log_name = (new \addons\shopro\model\ActivityGrouponLog())->getQuery()->getTable();
$groupon_name = (new \addons\shopro\model\ActivityGroupon())->getQuery()->getTable();
$query->table($groupon_name)->where('id=' . $log_name . '.groupon_id')
->where('status', 'in', $type);
});
}
$logs = $logs->where('user_id', $user['id'])
->order('id', 'desc')
->paginate(10);
// 将列表的显示价格,都查当时购买的价格,和当时对应的活动的 真实销量
if ($grouponLogs = $logs->items()) {
// 拿到所有活动 ids
$activity_ids = array_column($grouponLogs, 'activity_id');
// 一次获取所有活动,包括被软删除的活动,并关联规格
$activities = \addons\shopro\model\Activity::withTrashed()
->with('activityGoodsSkuPrice')
->where('id', 'in', $activity_ids)->select();
$activities = array_column($activities, null, 'id');
foreach ($grouponLogs as $key => $grouponLog) {
if (isset($grouponLog['goods']) && $grouponLog['goods'] && isset($activities[$grouponLog['activity_id']])) {
$activity = $activities[$grouponLog['activity_id']];
// 拿到当前商品对应的活动规格
$currentGoodsActivitySkuPrices = [];
foreach ($activity['activityGoodsSkuPrice'] as $k => $skuPrice) {
if ($skuPrice['status'] == 'up' && $skuPrice['goods_id'] == $grouponLog['goods_id']) {
$currentGoodsActivitySkuPrices[] = $skuPrice;
}
}
// 当时参加活动真实销量
if ($currentGoodsActivitySkuPrices) {
$grouponLogs[$key]['goods']['sales'] = array_sum(array_column($currentGoodsActivitySkuPrices, 'sales'));
}
// 这个是购买时候的活动单价
if (isset($grouponLog['order']['first_item'])) {
$grouponLogs[$key]['goods']['price'] = $grouponLog['order']['first_item']['goods_price'];
}
}
}
$logs->data = $grouponLogs;
}
$this->success('我的拼团', $logs);
}
}
... ...
<?php
namespace addons\shopro\controller;
use addons\shopro\exception\Exception;
use addons\shopro\model\UserAddress;
use addons\shopro\model\Area;
class Address extends Base
{
protected $noNeedLogin = ['area'];
protected $noNeedRight = ['*'];
public function index()
{
$this->success('收货地址', UserAddress::getUserAddress());
}
public function defaults()
{
$this->success('默认收货地址', UserAddress::getUserDefaultAddress());
}
public function area()
{
$data['provinceData'] = Area::where('level', 1)->order('id asc')->field('id as value, name as label, pid, level')->select();
foreach ($data['provinceData'] as $k => $p) {
$data['cityData'][$k] = Area::where(['level' => 2, 'pid' => $p->value])->order('id asc')->field('id as value, name as label, pid, level')->select();
foreach ($data['cityData'][$k] as $i => $c) {
$data['areaData'][$k][$i] = Area::where(['level' => 3, 'pid' => $c->value])->order('id asc')->field('id as value, name as label, pid, level')->select();
}
}
$this->success('省市区', $data);
}
public function edit()
{
$params = $this->request->post();
// 表单验证
$this->shoproValidate($params, get_class(), 'edit');
$this->success('编辑地址', UserAddress::edit($params));
}
public function info()
{
$params = $this->request->get();
$this->success('地址详情', UserAddress::info($params));
}
public function del()
{
$params = $this->request->post();
$this->success('地址详情', UserAddress::del($params));
}
}
\ No newline at end of file
... ...
<?php
namespace addons\shopro\controller;
use addons\shopro\exception\Exception;
use app\common\controller\Api;
use think\Lang;
class Base extends Api
{
public function _initialize()
{
parent::_initialize();
$controllername = strtolower($this->request->controller());
$this->loadlang($controllername);
}
protected function loadlang($name)
{
Lang::load(ADDON_PATH . 'shopro/lang/' . $this->request->langset() . '/' . str_replace('.', '/', $name) . '.php');
}
protected function shoproValidate($params, $class, $scene, $rules = []) {
$validate = validate(str_replace('controller', 'validate', $class));
if (!$validate->check($params, $rules, $scene)) {
throw new Exception($validate->getError());
}
}
}
... ...
<?php
namespace addons\shopro\controller;
use addons\shopro\model\Cart as CartModel;
class Cart extends Base
{
protected $noNeedLogin = [];
protected $noNeedRight = ['*'];
public function index()
{
$data = CartModel::info();
$this->success('我的购物车', $data);
}
public function add()
{
$params = $this->request->post();
// 表单验证
$this->shoproValidate($params, get_class(), 'add');
$goodsList = $params['goods_list'];
$this->success('已添加', CartModel::add($goodsList));
}
public function edit()
{
$params = $this->request->post();
// 表单验证
$this->shoproValidate($params, get_class(), 'edit');
$this->success('', CartModel::edit($params));
}
}
\ No newline at end of file
... ...
<?php
namespace addons\shopro\controller;
use addons\shopro\model\Category as CategoryModel;
use addons\shopro\model\Goods;
/**
* 分类管理
*
* @icon fa fa-list
* @remark 用于统一管理网站的所有分类,分类可进行无限级分类,分类类型请在常规管理->系统配置->字典配置中添加
*/
class Category extends Base
{
protected $noNeedLogin = ['*'];
protected $noNeedRight = ['*'];
public function index()
{
$id = $this->request->get('id');
$data = CategoryModel::getCategoryList($id);
$this->success('商城分类', $data);
}
public function goods() {
$params = $this->request->get();
$category_id = $params['category_id'];
$categories = CategoryModel::where('pid', $category_id)->where('status', 'normal')->select();
// 获取这个分类下面的所有商品
$goodsList = Goods::getGoodsList(array_merge($params, ['no_activity' => true]), false);
foreach($categories as $key => $category) {
$categoryIds = ',' . $category['id'] . ',';
$currentCategoryGoods = [];
foreach ($goodsList as $k => $goods) {
$goodsCategoryIds = ',' . $goods['category_ids'] . ',';
if (strpos($goodsCategoryIds, $categoryIds) !== false) {
$currentCategoryGoods[] = $goods;
}
}
$categories[$key]['goods'] = $currentCategoryGoods;
}
$this->success('商城分类商品', $categories);
}
}
... ...
<?php
namespace addons\shopro\controller;
class Coupons extends Base
{
protected $noNeedLogin = ['lists', 'detail', 'goods'];
protected $noNeedRight = ['*'];
// 领券中心,自己的优惠券
public function index()
{
$type = $this->request->get('type');
$this->success('优惠券中心', \addons\shopro\model\Coupons::getCouponsList($type));
}
public function lists()
{
$ids = $this->request->get('ids');
$this->success('优惠券列表', \addons\shopro\model\Coupons::getCouponsListByIds($ids));
}
public function get()
{
$id = $this->request->get('id');
$this->success('领取成功', \addons\shopro\model\Coupons::getCoupon($id));
}
public function detail()
{
$id = $this->request->get('id');
$user_coupons_id = $this->request->get('user_coupons_id', 0);
$detail = \addons\shopro\model\Coupons::getCouponsDetail($id, $user_coupons_id);
$this->success('优惠券详情', $detail);
}
public function goods()
{
$id = $this->request->get('id');
$detail = \addons\shopro\model\Coupons::getGoodsByCoupons($id);
$this->success('优惠券详情', $detail);
}
}
... ...
<?php
namespace addons\shopro\controller;
class Decorate extends Base
{
protected $noNeedLogin = ['saveImg'];
protected $noNeedRight = ['*'];
public function saveImg()
{
$params = $this->request->post();
// 表单验证
$this->shoproValidate($params, get_class(), 'saveImg');
$id = $params['id'];
$image = $params['image'];
$result = \addons\shopro\model\Decorate::where('id', $id)->update(['image' => $image]);
$this->success();
}
}
... ...
<?php
namespace addons\shopro\controller;
use addons\shopro\exception\Exception;
use addons\shopro\model\Order;
use addons\shopro\model\User;
use think\Db;
use think\Log;
class Express extends Base
{
protected $noNeedLogin = ['callback'];
protected $noNeedRight = ['*'];
/**
* 物流信息订阅回调接口
*/
public function callback()
{
$requestData = $this->request->post();
$expressLib = new \addons\shopro\library\Express();
// 信息记录日志
\think\Log::write('expresscallback:'. json_encode($requestData));
$data = json_decode(html_entity_decode($requestData['RequestData']), true);
$expressData = $data['Data'];
foreach ($expressData as $key => $express) {
// 查找包裹
$orderExpress = \addons\shopro\model\OrderExpress::with('order')->where('express_code', $express['ShipperCode'])
->where('express_no', $express['LogisticCode'])
->find();
if (!$orderExpress) {
// 包裹不存在,记录日志信息,然后继续下一个
\think\Log::write('orderExpressNotFound:' . json_encode($express));
continue;
}
if (!$express['Success']) {
// 失败了
if ($express['Reason'] == '三天无轨迹' || $express['Reason'] == '七天无轨迹') {
// 需要重新订阅
$expressLib->subscribe([
'express_code' => $express['ShipperCode'],
'express_no' => $express['LogisticCode']
], $orderExpress, $orderExpress->order);
}
continue;
}
$expressLib->checkAndAddTraces($orderExpress, $express);
}
return $expressLib->setPushResult(true);
}
}
... ...
<?php
namespace addons\shopro\controller;
class Faq extends Base
{
protected $noNeedLogin = ['*'];
protected $noNeedRight = ['*'];
// faq 列表
public function index()
{
$this->success('获取成功', \addons\shopro\model\Faq::order('id', 'DESC')->paginate(10));
}
public function detail () {
$id = $this->request->get('id');
$this->success('签到成功', \addons\shopro\model\Faq::where('id', $id)->find());
}
}
... ...
<?php
namespace addons\shopro\controller;
class Feedback extends Base
{
protected $noNeedLogin = ['type'];
protected $noNeedRight = ['*'];
public function type()
{
$this->success('反馈类型', array_values(\addons\shopro\model\Feedback::$typeAll));
}
public function add() {
$params = $this->request->post();
// 表单验证
$this->shoproValidate($params, get_class(), 'add');
$this->success('反馈成功', \addons\shopro\model\Feedback::add($params));
}
}
... ...
<?php
namespace addons\shopro\controller;
use addons\shopro\exception\Exception;
class Goods extends Base
{
protected $noNeedLogin = ['index', 'detail', 'lists', 'activity', 'seckillList', 'grouponList', 'store'];
protected $noNeedRight = ['*'];
public function index()
{
// 测试,下面代码可删除
// $redis = $this->getRedis();
// $redis->HSET('aaaaa', 'bbb', 'smallnews');
// // 获取活动集合
// $hashList = $redis->ZRANGE('aaaaa', 0, 999999999);
// var_dump($hashList);
// $user = \addons\shopro\model\User::where('id', 57)->find();
// $user->notify(
// new \addons\shopro\notifications\Order([
// // 'order' => \addons\shopro\model\Order::where('id', 359)->find(),
// // 'item' => \addons\shopro\model\OrderItem::where('id', 390)->find(),
// 'order' => \addons\shopro\model\Order::where('id', 349)->find(),
// 'item' => \addons\shopro\model\OrderItem::where('id', 380)->find(),
// 'event' => 'order_sended'
// ])
// );
// $user = \addons\shopro\model\User::where('id', 2)->find();
// $user->notify(
// new \addons\shopro\notifications\Aftersale([
// 'aftersale' => \addons\shopro\model\OrderAftersale::get(6),
// 'order' => \addons\shopro\model\Order::get(115),
// 'aftersaleLog' => \addons\shopro\model\OrderAftersaleLog::get(9),
// 'event' => 'aftersale_change'
// ])
// );
// $user = \addons\shopro\model\User::where('id', 2)->find();
// $user->notify(
// new \addons\shopro\notifications\Wallet([
// 'apply' => \addons\shopro\model\UserWalletApply::get(1),
// 'event' => 'wallet_apply'
// ])
// );
// $user = \addons\shopro\model\User::where('id', 2)->find();
// $user->notify(
// new \addons\shopro\notifications\Wallet([
// 'walletLog' => \addons\shopro\model\UserWalletLog::get(1),
// 'event' => 'wallet_change'
// ])
// );
// $user = \addons\shopro\model\User::where('id', 2)->find();
// $user->notify(
// new \addons\shopro\notifications\store\Order([
// 'store' => \addons\shopro\model\Store::get(1),
// 'order' => \addons\shopro\model\Order::get(83),
// 'event' => 'store_order_new'
// ])
// );
}
public function detail()
{
$id = $this->request->get('id');
$detail = \addons\shopro\model\Goods::getGoodsDetail($id);
// 记录足记
\addons\shopro\model\UserView::addView($detail);
$sku_price = $detail['sku_price']; // 处理过的规格
// tp bug json_encode 或者 toArray 的时候 sku_price 会重新查询数据库,导致被处理过的规格又还原回去了
$detail = json_decode(json_encode($detail), true);
$detail['sku_price'] = $sku_price;
$this->success('商品详情', $detail);
}
public function lists()
{
$params = $this->request->get();
$data = \addons\shopro\model\Goods::getGoodsList($params);
$this->success('商品列表', $data);
}
/**
* 获取商品支持的 自提点
*/
public function store()
{
$params = $this->request->get();
$data = \addons\shopro\model\Goods::getGoodsStore($params);
$this->success('自提列表', $data);
}
// 秒杀列表
public function seckillList() {
$params = $this->request->get();
$this->success('秒杀商品列表', \addons\shopro\model\Goods::getSeckillGoodsList($params));
}
// 拼团列表
public function grouponList() {
$params = $this->request->get();
$this->success('拼团商品列表', \addons\shopro\model\Goods::getGrouponGoodsList($params));
}
public function activity()
{
$activity_id = $this->request->get('activity_id');
$activity = \addons\shopro\model\Activity::get($activity_id);
if (!$activity) {
throw new Exception('活动不存在', -1);
}
$goods = \addons\shopro\model\Goods::getGoodsList(['goods_ids' => $activity->goods_ids]);
$activity->goods = $goods;
$this->success('活动列表', $activity);
}
public function favorite()
{
$params = $this->request->post();
$result = \addons\shopro\model\UserFavorite::edit($params);
$this->success($result ? '收藏成功' : '取消收藏', $result);
}
public function favoriteList()
{
$data = \addons\shopro\model\UserFavorite::getGoodsList();
$this->success('商品收藏列表', $data);
}
public function viewDelete()
{
$params = $this->request->post();
$result = \addons\shopro\model\UserView::del($params);
$this->success('删除成功', $result);
}
public function viewList()
{
$data = \addons\shopro\model\UserView::getGoodsList();
$this->success('商品浏览列表', $data);
}
}
... ...
<?php
namespace addons\shopro\controller;
class GoodsComment extends Base
{
protected $noNeedLogin = ['index', 'type'];
protected $noNeedRight = ['*'];
public function index()
{
$params = $this->request->get();
$goodsComments = \addons\shopro\model\GoodsComment::getList($params);
$this->success('评价详情', $goodsComments);
}
public function type() {
$goods_id = $this->request->get('goods_id', 0);
$type = array_values(\addons\shopro\model\GoodsComment::$typeAll);
foreach ($type as $key => $val) {
// 只查询 count 比查出来所有评论,在判断状态要快
$comment = \addons\shopro\model\GoodsComment::where('goods_id', $goods_id);
if ($val['code'] != 'all') {
$comment = $comment->{$val['code']}();
}
$comment = $comment->count();
$type[$key]['num'] = $comment;
}
$this->success('筛选类型', $type);
}
}
... ...
<?php
namespace addons\shopro\controller;
use addons\shopro\model\Config;
use think\Db;
use think\Config as FaConfig;
use fast\Random;
class Index extends Base
{
protected $noNeedLogin = ['*'];
protected $noNeedRight = ['*'];
public function index()
{
}
//初始化商城数据
public function init()
{
$params = $this->request->get();
$platform = $this->request->header('platform');
$config = new \addons\shopro\model\Config;
$platformConfig = json_decode($config->where(['name' => $platform])->value('value'), true);
$paymentConfig = $config->where('group', 'payment')->select();
$payment = [];
foreach ($paymentConfig as $key => $config) {
$val = json_decode($config->value, true);
if ($val && in_array($platform, $val['platform'])) {
$payment[] = $config->name;
}
}
$data['payment'] = $payment; // 平台支持的支付方式
$shopro = json_decode(Config::where(['name' => 'shopro'])->value('value'), true);
$data['info'] = $shopro;
$data['info']['logo'] = cdnurl($data['info']['logo'], true);
$autologin = false;
if (isset($platformConfig['auto_login']) && $platformConfig['auto_login'] == 1) {
$autologin = true;
}
$data['wechat'] = [
'appid' => isset($platformConfig['app_id']) ? $platformConfig['app_id'] : '',
'autologin' => $autologin,
];
$share = json_decode(Config::where(['name' => 'share'])->value('value'), true);
$data['share'] = [
'title' => $share['title'],
'image' => isset($share['image']) ? cdnurl($share['image'], true) : '',
'goods_poster_bg' => isset($share['goods_poster_bg']) ? cdnurl($share['goods_poster_bg'], true) : '',
'user_poster_bg' => isset($share['user_poster_bg']) ? cdnurl($share['user_poster_bg'], true) : '',
'groupon_poster_bg' => isset($share['groupon_poster_bg']) ? cdnurl($share['groupon_poster_bg'], true) : '',
];
$data['addons'] = array_keys(get_addon_list());
$this->success('初始化数据', $data);
}
//商城模板数据
public function template()
{
$get = $this->request->get();
$platform = $this->request->header('platform');
if (isset($get['shop_id'])) {
$template = \addons\shopro\model\Decorate::getCurrentPlatformDecorate('preview', $get['shop_id']);
} else {
$template = \addons\shopro\model\Decorate::getCurrentPlatformDecorate($platform);
}
$this->success('模板数据', $template);
}
//自定义页面
public function custom()
{
$get = $this->request->get();
$decorate = \addons\shopro\model\Decorate::get($get['id']);
if (!$decorate) {
$this->error('未找到自定义页面');
}
$decorate->template = \addons\shopro\model\Decorate::getCustomDecorate($get['id']);
$this->success('自定义模板数据', $decorate);
}
//富文本详情
public function richtext()
{
$id = $this->request->get('id');
$data = \addons\shopro\model\Richtext::get(['id' => $id]);
$this->success($data->title, $data);
}
//同步前端所有页面链接
public function asyncLink()
{
$post = $this->request->post();
$newLink = $post['data'];
$existLink = Db::name('shopro_link')->select();
$newLinkPath = array_column($newLink, 'path');
$existLinkPath = array_flip(array_column($existLink, 'path'));
$insertData = [];
$count = 1;
foreach ($newLinkPath as $key => $item) {
if (!isset($existLinkPath[$item]) && isset($newLink[$key]['meta']['async']) && $newLink[$key]['meta']['async']) {
$insertData[] = [
'name' => isset($newLink[$key]['meta']['title']) ? $newLink[$key]['meta']['title'] : '新链接' . $count,
'path' => $item,
'group' => isset($newLink[$key]['meta']['group']) ? $newLink[$key]['meta']['group'] : '其它',
'createtime' => time(),
'updatetime' => time()
];
$count++;
}
}
if ($insertData !== []) {
Db::name('shopro_link')->insertAll($insertData);
}
}
//前端获取轮播图平均色
//1.0.7以后此接口作废
public function asyncBannerBgColor()
{
$params = $this->request->post();
$platform = $this->request->header('platform');
$data['template'] = \addons\shopro\model\Decorate::asyncBannerBgColor($platform, $params);
}
//店铺装修 截图商城首页
public function asyncDecorateScreenShot()
{
$params = $this->request->post();
\addons\shopro\model\Decorate::asyncDecorateScreenShot($params);
}
/**
* 上传文件
* @ApiMethod (POST)
* @param File $file 文件流
*/
public function upload()
{
$file = $this->request->file('file');
if (empty($file)) {
$this->error(__('No file upload or server upload limit exceeded'));
}
//判断是否已经存在附件
$sha1 = $file->hash();
$upload = FaConfig::get('upload');
preg_match('/(\d+)(\w+)/', $upload['maxsize'], $matches);
$type = strtolower($matches[2]);
$typeDict = ['b' => 0, 'k' => 1, 'kb' => 1, 'm' => 2, 'mb' => 2, 'gb' => 3, 'g' => 3];
$size = (int)$upload['maxsize'] * pow(1024, isset($typeDict[$type]) ? $typeDict[$type] : 0);
$fileInfo = $file->getInfo();
$suffix = strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION));
$suffix = $suffix && preg_match("/^[a-zA-Z0-9]+$/", $suffix) ? $suffix : 'file';
$mimetypeArr = explode(',', strtolower($upload['mimetype']));
$typeArr = explode('/', $fileInfo['type']);
//禁止上传PHP和HTML文件
if (in_array($fileInfo['type'], ['text/x-php', 'text/html']) || in_array($suffix, ['php', 'html', 'htm'])) {
$this->error(__('Uploaded file format is limited'));
}
//验证文件后缀
if ($upload['mimetype'] !== '*' &&
(
!in_array($suffix, $mimetypeArr)
|| (stripos($typeArr[0] . '/', $upload['mimetype']) !== false && (!in_array($fileInfo['type'], $mimetypeArr) && !in_array($typeArr[0] . '/*', $mimetypeArr)))
)
) {
$this->error(__('Uploaded file format is limited'));
}
//验证是否为图片文件
$imagewidth = $imageheight = 0;
if (in_array($fileInfo['type'], ['image/gif', 'image/jpg', 'image/jpeg', 'image/bmp', 'image/png', 'image/webp']) || in_array($suffix, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'webp'])) {
$imgInfo = getimagesize($fileInfo['tmp_name']);
if (!$imgInfo || !isset($imgInfo[0]) || !isset($imgInfo[1])) {
$this->error(__('Uploaded file is not a valid image'));
}
$imagewidth = isset($imgInfo[0]) ? $imgInfo[0] : $imagewidth;
$imageheight = isset($imgInfo[1]) ? $imgInfo[1] : $imageheight;
}
$replaceArr = [
'{year}' => date("Y"),
'{mon}' => date("m"),
'{day}' => date("d"),
'{hour}' => date("H"),
'{min}' => date("i"),
'{sec}' => date("s"),
'{random}' => Random::alnum(16),
'{random32}' => Random::alnum(32),
'{filename}' => $suffix ? substr($fileInfo['name'], 0, strripos($fileInfo['name'], '.')) : $fileInfo['name'],
'{suffix}' => $suffix,
'{.suffix}' => $suffix ? '.' . $suffix : '',
'{filemd5}' => md5_file($fileInfo['tmp_name']),
];
$savekey = $upload['savekey'];
$savekey = str_replace(array_keys($replaceArr), array_values($replaceArr), $savekey);
$uploadDir = substr($savekey, 0, strripos($savekey, '/') + 1);
$fileName = substr($savekey, strripos($savekey, '/') + 1);
//
$splInfo = $file->validate(['size' => $size])->move(ROOT_PATH . '/public' . $uploadDir, $fileName);
if ($splInfo) {
$params = array(
'admin_id' => 0,
'user_id' => (int)$this->auth->id,
'filesize' => $fileInfo['size'],
'imagewidth' => $imagewidth,
'imageheight' => $imageheight,
'imagetype' => $suffix,
'imageframes' => 0,
'mimetype' => $fileInfo['type'],
'url' => $uploadDir . $splInfo->getSaveName(),
'uploadtime' => time(),
'storage' => 'local',
'sha1' => $sha1,
);
$attachment = new \app\common\model\Attachment;
$attachment->data(array_filter($params));
$attachment->save();
\think\Hook::listen("upload_after", $attachment);
$this->success(__('Upload successful'), [
'url' => $uploadDir . $splInfo->getSaveName(),
'full_url' => request()->domain() . $uploadDir . $splInfo->getSaveName()
]);
} else {
// 上传失败获取错误信息
$this->error($file->getError());
}
}
/**
* 上传 base64 图片
* @ApiMethod (POST)
* @param base64 内容
*/
public function uploadBase64()
{
$content = $this->request->post('content', '');
if (empty($content) || !preg_match('/^(data:\s*image\/(\w+);base64,)/', $content, $matches)) {
$this->error(__('No file upload or server upload limit exceeded'));
}
$upload = FaConfig::get('upload');
$suffix = $matches[2]; //图片后缀
$mimetypeArr = explode(',', strtolower($upload['mimetype']));
// 判断是否允许的后缀
if ($upload['mimetype'] !== '*' && !in_array($suffix, $mimetypeArr)) {
$this->error(__('Uploaded file format is limited'));
}
$replaceArr = [
'{year}' => date("Y"),
'{mon}' => date("m"),
'{day}' => date("d"),
'{hour}' => date("H"),
'{min}' => date("i"),
'{sec}' => date("s"),
'{random}' => Random::alnum(16),
'{random32}' => Random::alnum(32),
'{filename}' => "店铺装修截图",
'{suffix}' => $suffix,
'{.suffix}' => $suffix ? '.' . $suffix : '',
'{filemd5}' => md5($content),
];
$savekey = $upload['savekey'];
$savekey = str_replace(array_keys($replaceArr), array_values($replaceArr), $savekey);
$uploadDir = substr($savekey, 0, strripos($savekey, '/') + 1);
$fileName = substr($savekey, strripos($savekey, '/') + 1);
$fullDir = ROOT_PATH . '/public' . $uploadDir;
$uploadPath = $uploadDir . $fileName;
$fullPath = $fullDir . $fileName;
if (!is_dir($fullDir)) {
mkdir($fullDir, 0777, true);
}
$imageContent = base64_decode(str_replace($matches[1], '', $content));
if (file_put_contents($fullPath, $imageContent)) {
$imgInfo = getimagesize($fullPath);
$imagewidth = isset($imgInfo[0]) ? $imgInfo[0] : 0;
$imageheight = isset($imgInfo[1]) ? $imgInfo[1] : 0;
$params = array(
'admin_id' => 0,
'user_id' => (int) $this->auth->id,
'filesize' => strlen($content),
'imagewidth' => $imagewidth,
'imageheight' => $imageheight,
'imagetype' => $suffix,
'imageframes' => 0,
'mimetype' => isset($imgInfo['mime']) ? $imgInfo['mime'] : 'image/' . $suffix,
'url' => $uploadPath,
'uploadtime' => time(),
'storage' => 'local',
'sha1' => hash_file('sha1', $fullPath),
);
$attachment = new \app\common\model\Attachment;
$attachment->data(array_filter($params));
$attachment->save();
\think\Hook::listen("upload_after", $attachment);
$this->success(__('Upload successful'), [
'url' => $uploadPath,
'full_url' => request()->domain() . $uploadPath
]);
} else {
$this->error("文件上传失败");
}
}
public function debugLog()
{
$params = $this->request->post();
\think\Log::write($params, 'notice');
}
}
... ...
<?php
namespace addons\shopro\controller;
/**
* 客服接口
*/
class Kefu extends Base
{
protected $noNeedLogin = [];
protected $noNeedRight = ['*'];
/**
* 对接Fastadmin插件市场WorkerMan客服插件
*/
public function historyGoods()
{
$viewList = \addons\shopro\model\UserView::getGoodsList();
if(!empty($viewList)) {
foreach($viewList as $k => &$v) {
$v->id = $v->goods_id;
$v->logo = $v->goods->image;
$v->subject = $v->goods->title;
$v->note = $v->goods->subtitle;
$v->price = $v->goods->price;
unset($v['goods']);
unset($v['goods_id']);
unset($v['user_id']);
}
// halt($viewList);
}
$this->success('浏览历史', $viewList);
if(!empty($params['token'])) {
$auth = \app\common\library\Auth::instance();
$auth->init($params['token']);
halt($auth);
}
}
public function historyOrder()
{
$orderList = \addons\shopro\model\Order::getList(['type' => 'all']);
if(!empty($orderList)) {
foreach($orderList['data'] as $k => &$v) {
$order = [];
$order['id'] = $v['id'];
$order['subject'] = $v['item'][0]['goods_title'];
$order['logo'] = $v['item'][0]['goods_image'];
$order['note'] = "订单编号:{$v['order_sn']}";
$order['price'] = $v['total_amount'];
$order['number'] = 23;
$itemNumber = count($v['item']);
if($itemNumber == 1) {
$order['subject'] = "{$order['subject']}...{$itemNumber}个产品";
}
$v = $order;
}
// halt($viewList);
}
$this->success('order', $orderList);
}
}
\ No newline at end of file
... ...
<?php
namespace addons\shopro\controller;
use addons\shopro\library\Wechat;
use addons\shopro\exception\Exception;
use think\Cache;
class Live extends Base
{
protected $noNeedLogin = ['*'];
protected $noNeedRight = ['*'];
public function index()
{
$params = $this->request->get();
$type = $params['type'] ?? 'all';
$ids = array_filter(isset($params['ids']) ? explode(',', $params['ids']) : []);
if (!in_array($type, ['all', 'notice', 'living', 'lived'])) {
throw new Exception('参数错误');
}
// 同步直播
\addons\shopro\model\Live::autoSyncLive();
if ($type != 'all') {
$lives = \addons\shopro\model\Live::{$type}()
->with('goods')
->order('id', 'desc')
->paginate(10);
} else {
$lives = \addons\shopro\model\Live::order('live_status', 'asc')
->with('goods')
->order('id', 'desc');
if (isset($params['ids'])) {
// 首页根据 id 获取
$lives = $lives->where('id', 'in', $ids)->select();
} else {
// 直播列表
$lives = $lives->paginate(10);
}
}
$this->success('获取成功', $lives);
}
}
... ...
<?php
namespace addons\shopro\controller;
use addons\shopro\exception\Exception;
use addons\shopro\model\NotificationConfig;
use think\Cache;
class Notification extends Base
{
protected $noNeedLogin = ['*'];
protected $noNeedRight = ['*'];
public function template()
{
// 获取小程序模板消息所有配置
$notificationConfig = NotificationConfig::cache(300)->where('platform', 'wxMiniProgram')->select();
$templates = [];
foreach ($notificationConfig as $k => $config) {
if ($config['status'] && $config['content_arr'] && $config['content_arr']['template_id']) {
$templates[$config['event']] = $config['content_arr']['template_id'];
}
}
$this->success('获取成功', $templates);
}
}
... ...
<?php
namespace addons\shopro\controller;
class Order extends Base
{
protected $noNeedLogin = [];
protected $noNeedRight = ['*'];
public function index()
{
$params = $this->request->get();
$this->success('订单列表', \addons\shopro\model\Order::getList($params));
}
public function detail()
{
$params = $this->request->get();
$this->success('订单详情', \addons\shopro\model\Order::detail($params));
}
public function itemDetail()
{
$params = $this->request->get();
$this->success('订单商品', \addons\shopro\model\Order::itemDetail($params));
}
//
public function statusNum () {
$this->success('订单数量', \addons\shopro\model\Order::statusNum());
}
// 取消订单
public function cancel()
{
$params = $this->request->post();
// 表单验证
$this->shoproValidate($params, get_class(), 'cancel');
$this->success('取消成功', \addons\shopro\model\Order::operCancel($params));
}
// 删除订单
public function delete()
{
$params = $this->request->post();
// 表单验证
$this->shoproValidate($params, get_class(), 'delete');
$this->success('删除成功', \addons\shopro\model\Order::operDelete($params));
}
// 确认收货
public function confirm()
{
$params = $this->request->post();
// 表单验证
$this->shoproValidate($params, get_class(), 'confirm');
$this->success('收货成功', \addons\shopro\model\Order::operConfirm($params));
}
// 申请售后 (已废弃)
// public function aftersale()
// {
// $params = $this->request->post();
// // 表单验证
// $this->shoproValidate($params, get_class(), 'aftersale');
// $this->success('申请成功', \addons\shopro\model\Order::operAftersale($params));
// }
// 申请退款 (已废弃)
// public function refund()
// {
// $params = $this->request->post();
// // 表单验证
// $this->shoproValidate($params, get_class(), 'refund');
// $this->success('申请成功', \addons\shopro\model\Order::operRefund($params));
// }
public function comment ()
{
$params = $this->request->post();
// 表单验证
$this->shoproValidate($params, get_class(), 'comment');
$this->success('评价成功', \addons\shopro\model\Order::operComment($params));
}
public function pre()
{
$params = $this->request->post();
// 表单验证
$this->shoproValidate($params, get_class(), 'pre');
$result = \addons\shopro\model\Order::pre($params);
$this->success('计算成功', $result);
}
public function createOrder()
{
$params = $this->request->post();
// 表单验证
$this->shoproValidate($params, get_class(), 'createOrder');
$order = \addons\shopro\model\Order::createOrder($params);
$this->success('订单添加成功', $order);
}
// 获取可用优惠券列表
public function coupons () {
$params = $this->request->post();
// 表单验证
$this->shoproValidate($params, get_class(), 'coupons');
$coupons = \addons\shopro\model\Order::coupons($params);
$this->success('获取成功', $coupons);
}
}
... ...
<?php
namespace addons\shopro\controller;
class OrderAftersale extends Base
{
protected $noNeedLogin = [];
protected $noNeedRight = ['*'];
public function index()
{
$params = $this->request->get();
$this->success('售后列表', \addons\shopro\model\OrderAftersale::getList($params));
}
/**
* 详情
*/
public function detail()
{
$params = $this->request->get();
$this->shoproValidate($params, get_class(), 'detail');
$this->success('售后详情', \addons\shopro\model\OrderAftersale::detail($params));
}
// 申请售后
public function aftersale()
{
$params = $this->request->post();
// 表单验证
$this->shoproValidate($params, get_class(), 'aftersale');
$this->success('申请成功', \addons\shopro\model\OrderAftersale::aftersale($params));
}
// 取消售后单
public function cancel()
{
$params = $this->request->post();
// 表单验证
$this->shoproValidate($params, get_class(), 'cancel');
$this->success('取消成功', \addons\shopro\model\OrderAftersale::operCancel($params));
}
// 删除售后单
public function delete()
{
$params = $this->request->post();
// 表单验证
$this->shoproValidate($params, get_class(), 'delete');
$this->success('删除成功', \addons\shopro\model\OrderAftersale::operDelete($params));
}
}
... ...
<?php
namespace addons\shopro\controller;
class OrderExpress extends Base
{
protected $noNeedLogin = [];
protected $noNeedRight = ['*'];
public function index()
{
$params = $this->request->get();
$this->success('包裹列表', \addons\shopro\model\OrderExpress::getList($params));
}
public function detail()
{
$params = $this->request->get();
$this->success('包裹详情', \addons\shopro\model\OrderExpress::detail($params));
}
}
... ...
<?php
namespace addons\shopro\controller;
use addons\epay\library\Service;
use fast\Random;
use think\addons\Controller;
use addons\shopro\exception\Exception;
use addons\shopro\model\Order;
use addons\shopro\model\User;
use think\Db;
use think\Log;
class Pay extends Base
{
protected $noNeedLogin = ['prepay', 'notifyx', 'notifyr', 'alipay'];
protected $noNeedRight = ['*'];
/**
* 支付宝网页支付
*/
public function alipay()
{
$order_sn = $this->request->get('order_sn');
$order = Order::where('order_sn', $order_sn)->find();
try {
if (!$order) {
throw new \Exception("订单不存在");
}
if ($order->status > 0) {
throw new \Exception("订单已支付");
}
if ($order->status < 0) {
throw new \Exception("订单已失效");
}
$notify_url = $this->request->root(true) . '/addons/shopro/pay/notifyx/payment/alipay/platform/H5';
$pay = new \addons\shopro\library\PayService('alipay', 'url', $notify_url);
$order_data = [
'out_trade_no' => $order->order_sn,
'total_fee' => $order->total_fee,
'subject' => '商城订单支付',
];
$result = $pay->create($order_data);
$result = $result->getContent();
echo $result;
} catch (\Exception $e) {
echo $e->getMessage();
}
// $this->assign('result', $result);
// return $this->view->fetch();
}
/**
* 拉起支付
*/
public function prepay()
{
$order_sn = $this->request->post('order_sn');
$payment = $this->request->post('payment');
$openid = $this->request->post('openid', '');
$platform = request()->header('platform');
$order = Order::nopay()->where('order_sn', $order_sn)->find();
if (!$order) {
throw new Exception("订单不存在");
}
if (!$payment || !in_array($payment, ['wechat', 'alipay', 'wallet'])) {
throw new Exception("支付类型不能为空");
}
if ($payment == 'wallet') {
// 余额支付
$this->walletPay($order, $payment, $platform);
}
$order_data = [
'out_trade_no' => $order->order_sn,
'total_fee' => $order->total_fee,
];
// 微信公众号,小程序支付,必须有 openid
if ($payment == 'wechat') {
if (in_array($platform, ['wxOfficialAccount', 'wxMiniProgram'])) {
if (isset($openid) && $openid) {
// 如果传的有 openid
$order_data['openid'] = $openid;
} else {
// 没有 openid 默认拿下单人的 openid
$oauth = \addons\shopro\model\UserOauth::where([
'user_id' => $order->user_id,
'provider' => 'Wechat',
'platform' => $platform
])->find();
$order_data['openid'] = $oauth ? $oauth->openid : '';
}
if (empty($order_data['openid'])) {
// 缺少 openid
return $this->success('缺少 openid', 'no_openid');
}
}
$order_data['body'] = '商城订单支付';
} else {
$order_data['subject'] = '商城订单支付';
}
$notify_url = $this->request->root(true) . '/addons/shopro/pay/notifyx/payment/' . $payment . '/platform/' . $platform;
$pay = new \addons\shopro\library\PayService($payment, $platform, $notify_url);
$result = $pay->create($order_data);
if ($platform == 'App') {
$result = $result->getContent();
}
if ($platform == 'H5' && $payment == 'wechat') {
$result = $result->getContent();
}
return $this->success('获取预付款成功', [
'pay_data' => $result,
'pay_action' => $pay->method,
]);
}
// 余额支付
public function walletPay ($order, $type, $method) {
$order = Db::transaction(function () use ($order, $type, $method) {
$total_fee = $order->total_fee;
// 扣除余额
$user = User::info();
if (is_null($user)) {
// 没有登录,请登录
$this->error(__('Please login first'), null, 401);
}
User::moneyReduce($user->id, $total_fee, 'wallet_pay', $order->id, [
'order_id' => $order->id,
'order_sn' => $order->order_sn,
]);
// 支付后流程
$notify = [
'order_sn' => $order['order_sn'],
'transaction_id' => '',
'notify_time' => date('Y-m-d H:i:s'),
'buyer_email' => $user->id,
'pay_fee' => $order->total_fee,
'pay_type' => 'wallet' // 支付方式
];
$notify['payment_json'] = json_encode($notify);
$order->paymentProcess($order, $notify);
return $order;
});
$this->success('支付成功', $order);
}
/**
* 支付成功回调
*/
public function notifyx()
{
Log::write('notifyx-comein:');
$payment = $this->request->param('payment');
$platform = $this->request->param('platform');
$pay = new \addons\shopro\library\PayService($payment, $platform);
$result = $pay->notify(function ($data, $pay) use ($payment, $platform) {
Log::write('notifyx-result:'. json_encode($data));
// { // 微信回调参数
// "appid":"wx39cd0799d4567dd0",
// "bank_type":"OTHERS",
// "cash_fee":"1",
// "fee_type":"CNY",
// "is_subscribe":"N",
// "mch_id":"1481069012",
// "nonce_str":"dPpcZ6AzCDU8daNC",
// "openid":"oD9ko4x7QMDQPZEuN8V5jtZjie3g",
// "out_trade_no":"202010240834057843002700",
// "result_code":"SUCCESS",
// "return_code":"SUCCESS",
// "sign":"3103B6D06F13D2B3959C5B3F7F1FD61C",
// "time_end":"20200407102424",
// "total_fee":"1",
// "trade_type":"JSAPI",
// "transaction_id":"4200000479202004070804485027"
// }
// { // 支付宝支付成功回调参数
// "gmt_create":"2020-04-10 19:15:00",
// "charset":"utf-8",
// "seller_email":"xptech@qq.com",
// "subject":"\u5546\u57ce\u8ba2\u5355\u652f\u4ed8",
// "sign":"AOiYZ1a2mEMOuIbHFCi6V6A0LJ97UMiHsCWgNdSU9dlzKFl15Ts8b0mL\/tN+Hhskl+94S3OUiNTBD3dD0Kv923SqaTWxNdj533PCdo2GDKsZIZgKbavnOvaccSKUdmQRE9KtmePPq9V9lFzEQvdUkKq1M8KAWO5K9LTy2iT2y5CUynpiu\/04GVzsTL9PqY+LDwqj6K+w7MgceWm1BWaFWg27AXIRw7wvsFckr3k9GGajgE2fufhoCYGYtGFbhGOp6ExtqS5RXBuPODOyRhBLpD8mwpOX38Oy0X+R4YQIrOi02dhqwPpvw79YjnvgXY3qZEQ66EdUsrT7EBdcPHK0Gw==",
// "buyer_id":"2088902485164146",
// "invoice_amount":"0.01",
// "notify_id":"2020041000222191501064141414240102",
// "fund_bill_list":"[{\"amount\":\"0.01\",\"fundChannel\":\"PCREDIT\"}]",
// "notify_type":"trade_status_sync",
// "trade_status":"TRADE_SUCCESS",
// "receipt_amount":"0.01",
// "buyer_pay_amount":"0.01",
// "app_id":"2021001114666742",
// "sign_type":"RSA2",
// "seller_id":"2088721922277739",
// "gmt_payment":"2020-04-10 19:15:00",
// "notify_time":"2020-04-10 19:15:01",
// "version":"1.0",
// "out_trade_no":"202007144778322770017000",
// "total_amount":"0.01",
// "trade_no":"2020041022001464141443020240",
// "auth_app_id":"2021001114666742",
// "buyer_logon_id":"157***@163.com",
// "point_amount":"0.00"
// }
// { // 支付宝退款成功(交易关闭)回调参数
// "gmt_create": "2020-08-15 14:48:32",
// "charset": "utf-8",
// "seller_email": "xptech@qq.com",
// "gmt_payment": "2020-08-15 14:48:32",
// "notify_time": "2020-08-15 16:11:45",
// "subject": "商城订单支付",
// "gmt_refund": "2020-08-15 16:11:45.140",
// "sign": "b6ArkgzLIRteRL9FMGC6i\/jf6VwFYQbaGDGRx002W+pdmN5q9+O4edZ3ALF74fYaijSl9ksNr0dKdvanu3uYxBTcd\/GIS4N1CWzmCOv6pzgx5rO\/YvGoHLM3Yop0GKKuMxmnNsZ6jhYKEY7SYD3Y0L6PU9ZMdHV7yIiVj+zZmbKzUgK9MPDCEXs+nzpNAiSM8GTqYRSUvKobAK68hswG2k1QIcqr5z+ZmVYa\/nHHkoC9qXt5zwyGi4P+2eOsr6V2PjA3x8qqe7TN5aI1DeoZD5KqHPYYaYF17J2q6YPlgl3WUl1RhE7H86bivB1fIuYEv\/3+JR74WN\/o7krGw1RPHg==",
// "out_biz_no": "R202004114414846255015300",
// "buyer_id": "2088902485164146",
// "version": "1.0",
// "notify_id": "2020081500222161145064141453349793",
// "notify_type": "trade_status_sync",
// "out_trade_no": "202002460317545607015300",
// "total_amount": "0.01",
// "trade_status": "TRADE_CLOSED",
// "refund_fee": "0.01",
// "trade_no": "2020081522001464141438570535",
// "auth_app_id": "2021001114666742",
// "buyer_logon_id": "157***@163.com",
// "gmt_close": "2020-08-15 16:11:45",
// "app_id": "2021001114666742",
// "sign_type": "RSA2",
// "seller_id": "2088721922277739"
// }
try {
$out_trade_no = $data['out_trade_no'];
$out_refund_no = $data['out_biz_no'] ?? '';
// 判断是否是支付宝退款(支付宝退款成功会通知该接口)
if ($payment == 'alipay' // 支付宝支付
&& $data['notify_type'] == 'trade_status_sync' // 同步交易状态
&& $data['trade_status'] == 'TRADE_CLOSED' // 交易关闭
&& $out_refund_no // 退款单号
) {
// 退款回调
$this->refundFinish($out_trade_no, $out_refund_no);
return $pay->success()->send();
}
// 判断支付宝微信是否是支付成功状态,如果不是,直接返回响应
if ($payment == 'alipay' && $data['trade_status'] != 'TRADE_SUCCESS') {
// 不是交易成功的通知,直接返回成功
return $pay->success()->send();
}
if ($payment == 'wechat' && ($data['result_code'] != 'SUCCESS' || $data['return_code'] != 'SUCCESS')) {
// 微信交易未成功,返回 false,让微信再次通知
return false;
}
// 支付成功流程
$pay_fee = $payment == 'alipay' ? $data['total_amount'] : $data['total_fee'] / 100;
//你可以在此编写订单逻辑
$order = Order::where('order_sn', $out_trade_no)->find();
if (!$order || $order->status > 0) {
// 订单不存在,或者订单已支付
return $pay->success()->send();
}
Db::transaction(function () use ($order, $data, $payment, $platform, $pay_fee) {
$notify = [
'order_sn' => $data['out_trade_no'],
'transaction_id' => $payment == 'alipay' ? $data['trade_no'] : $data['transaction_id'],
'notify_time' => date('Y-m-d H:i:s', strtotime($data['time_end'])),
'buyer_email' => $payment == 'alipay' ? $data['buyer_logon_id'] : $data['openid'],
'payment_json' => json_encode($data->all()),
'pay_fee' => $pay_fee,
'pay_type' => $payment // 支付方式
];
$order->paymentProcess($order, $notify);
});
return $pay->success()->send();
} catch (\Exception $e) {
Log::write('notifyx-error:' . json_encode($e->getMessage()));
}
});
return $result;
}
/**
* 退款成功回调
*/
public function notifyr()
{
Log::write('notifyreturn-comein:');
$payment = $this->request->param('payment');
$platform = $this->request->param('platform');
$pay = new \addons\shopro\library\PayService($payment, $platform);
$result = $pay->notifyRefund(function ($data, $pay) use ($payment, $platform) {
Log::write('notifyr-result:' . json_encode($data));
try {
$out_refund_no = $data['out_refund_no'];
$out_trade_no = $data['out_trade_no'];
// 退款
$this->refundFinish($out_trade_no, $out_refund_no);
return $pay->success()->send();
} catch (\Exception $e) {
Log::write('notifyreturn-error:' . json_encode($e->getMessage()));
}
});
return $result;
}
private function refundFinish($out_trade_no, $out_refund_no) {
$order = Order::where('order_sn', $out_trade_no)->find();
$refundLog = \app\admin\model\shopro\order\RefundLog::where('refund_sn', $out_refund_no)->find();
if (!$order || !$refundLog || $refundLog->status != 0) {
// 订单不存在,或者订单已退款
return true;
}
$item = \app\admin\model\shopro\order\OrderItem::where('id', $refundLog->order_item_id)->find();
Db::transaction(function () use ($order, $item, $refundLog) {
\app\admin\model\shopro\order\Order::refundFinish($order, $item, $refundLog);
});
return true;
}
}
... ...
<?php
namespace addons\shopro\controller;
class ScoreGoodsSkuPrice extends Base
{
protected $noNeedLogin = ['*'];
protected $noNeedRight = ['*'];
public function index()
{
$params = $this->request->get();
$goods = \addons\shopro\model\ScoreGoodsSkuPrice::getGoodsList($params);
$this->success('积分商城列表', $goods);
}
public function detail()
{
$id = $this->request->get('id');
$detail = \addons\shopro\model\ScoreGoodsSkuPrice::getGoodsDetail($id);
$this->success('商品详情', $detail);
}
}
... ...
<?php
namespace addons\shopro\controller;
use addons\shopro\model\Share as ShareModel;
class Share extends Base
{
protected $noNeedLogin = [];
protected $noNeedRight = ['*'];
public function add()
{
$params = $this->request->post();
$params['platform'] = $this->request->header('platform');
$this->success('添加分享记录', ShareModel::add($params));
}
}
\ No newline at end of file
... ...
<?php
namespace app\api\controller;
namespace addons\shopro\controller;
use app\common\controller\Api;
use app\common\library\Ems as Emslib;
use app\common\model\User;
use app\common\library\Sms as Smslib;
use addons\shopro\model\User;
use think\Hook;
/**
* 邮箱验证码接口
* 手机短信接口
*/
class Ems extends Api
class Sms extends Base
{
protected $noNeedLogin = '*';
protected $noNeedRight = '*';
public function _initialize()
{
parent::_initialize();
\think\Hook::add('ems_send', function ($params) {
$obj = \app\common\library\Email::instance();
$result = $obj
->to($params->email)
->subject('验证码')
->message("你的验证码是:" . $params->code)
->send();
return $result;
});
}
/**
* 发送验证码
*
* @param string $email 邮箱
* @param string $mobile 手机号
* @param string $event 事件名称
*/
public function send()
{
$email = $this->request->request("email");
$event = $this->request->request("event");
$mobile = $this->request->post("mobile");
$event = $this->request->post("event");
$event = $event ? $event : 'register';
$last = Emslib::get($email, $event);
if (!$mobile || !\think\Validate::regex($mobile, "^1\d{10}$")) {
$this->error(__('手机号不正确'));
}
$last = Smslib::get($mobile, $event);
if ($last && time() - $last['createtime'] < 60) {
$this->error(__('发送频繁'));
}
$ipSendTotal = \app\common\model\Sms::where(['ip' => $this->request->ip()])->whereTime('createtime', '-1 hours')->count();
if ($ipSendTotal >= 5) {
$this->error(__('发送频繁'));
}
if ($event) {
$userinfo = User::getByEmail($email);
$userinfo = User::getByMobile($mobile);
if ($event == 'register' && $userinfo) {
//已被注册
$this->error(__('已被注册'));
} elseif (in_array($event, ['changeemail']) && $userinfo) {
} elseif (in_array($event, ['changemobile']) && $userinfo) {
//被占用
$this->error(__('已被占用'));
} elseif (in_array($event, ['changepwd', 'resetpwd']) && !$userinfo) {
} elseif (in_array($event, ['changepwd', 'resetpwd', 'mobilelogin']) && !$userinfo) {
//未注册
$this->error(__('未注册'));
}
}
$ret = Emslib::send($email, null, $event);
if (!Hook::get('sms_send')) {
$this->error(__('请在后台插件管理安装短信验证插件'));
}
$ret = Smslib::send($mobile, null, $event);
if ($ret) {
$this->success(__('发送成功'));
} else {
$this->error(__('发送失败'));
$this->error(__('发送失败,请检查短信配置是否正确'));
}
}
/**
* 检测验证码
*
* @param string $email 邮箱
* @param string $event 事件名称
* @param string $mobile 手机号
* @param string $event 事件名称
* @param string $captcha 验证码
*/
public function check()
{
$email = $this->request->request("email");
$event = $this->request->request("event");
$mobile = $this->request->post("mobile");
$event = $this->request->post("event");
$event = $event ? $event : 'register';
$captcha = $this->request->request("captcha");
$captcha = $this->request->post("captcha");
if (!$mobile || !\think\Validate::regex($mobile, "^1\d{10}$")) {
$this->error(__('手机号不正确'));
}
if ($event) {
$userinfo = User::getByEmail($email);
$userinfo = User::getByMobile($mobile);
if ($event == 'register' && $userinfo) {
//已被注册
$this->error(__('已被注册'));
} elseif (in_array($event, ['changeemail']) && $userinfo) {
} elseif (in_array($event, ['changemobile']) && $userinfo) {
//被占用
$this->error(__('已被占用'));
} elseif (in_array($event, ['changepwd', 'resetpwd']) && !$userinfo) {
... ... @@ -92,7 +91,7 @@ class Ems extends Api
$this->error(__('未注册'));
}
}
$ret = Emslib::check($email, $captcha, $event);
$ret = Smslib::check($mobile, $captcha, $event);
if ($ret) {
$this->success(__('成功'));
} else {
... ...
<?php
namespace addons\shopro\controller;
use addons\shopro\exception\Exception;
use addons\shopro\model\Store as ModelStore;
use addons\shopro\model\User;
use addons\shopro\model\UserStore;
class Store extends Base
{
protected $noNeedLogin = [];
protected $noNeedRight = ['*'];
public function index()
{
$user = User::info();
$userStore = UserStore::where('user_id', $user->id)->select();
$store_id_arr = array_column($userStore, 'store_id');
$stores = [];
if ($store_id_arr) {
$stores = ModelStore::where('id', 'in', $store_id_arr)->select();
}
$this->success('获取门店列表', $stores);
}
}
... ...
<?php
namespace addons\shopro\controller;
use app\common\library\Ems;
use app\common\library\Sms;
use fast\Random;
use think\Validate;
use addons\shopro\library\Wechat;
use think\Db;
use addons\shopro\model\UserOauth;
use addons\shopro\model\User as UserModel;
use addons\shopro\model\UserStore;
/**
* 会员接口
*/
class User extends Base
{
protected $noNeedLogin = ['login', 'mobilelogin', 'accountLogin', 'register', 'resetpwd', 'changeemail', 'changemobile', 'third', 'wxMiniProgramLogin', 'getWxMiniProgramSessionKey', 'wxOfficialAccountLogin', 'wxOfficialAccountBaseLogin', 'wxOpenPlatformLogin', 'getUserDefaultFields'];
protected $noNeedRight = '*';
public function _initialize()
{
return parent::_initialize();
}
/**
* 会员中心
*/
public function index()
{
$auth = \app\common\library\Auth::instance();
$auth->setAllowFields(['id', 'username', 'nickname', 'mobile', 'avatar', 'score', 'birthday', 'money', 'group', 'group_id']);
$data = $auth->getUserinfo();
if (!isset($data['group'])) {
$data['group'] = \addons\shopro\model\UserGroup::get($data['group_id']);
}
// 查询用户优惠券数量
$userCoupons = \addons\shopro\model\Coupons::getCouponsList(1);
$data['coupons_num'] = count($userCoupons);
// 查询用户是否是门店管理员
$userStores = UserStore::where('user_id', $data['id'])->select();
$data['is_store'] = $userStores ? 1 : 0;
$data['store_id'] = 0;
if (count($userStores) == 1) {
// 只有一个店铺 直接进入店铺
$data['store_id'] = $userStores[0]['store_id'];
}
$this->success('用户信息', $data);
}
/**
* 会员登录
*
* @param string $account 账号
* @param string $password 密码
*/
public function accountLogin()
{
$account = $this->request->post('account');
$password = $this->request->post('password');
if (!$account || !$password) {
$this->error(__('Invalid parameters'));
}
$ret = $this->auth->login($account, $password);
if ($ret) {
$data = ['userinfo' => $this->auth->getUserinfo()];
$this->success(__('Logged in successful'), $data);
} else {
$this->error($this->auth->getError());
}
}
/**
* 获取微信小程序session_key
*
* @param string $code 加密code
*/
public function getWxMiniProgramSessionKey()
{
$post = $this->request->post();
$wechat = new Wechat('wxMiniProgram');
$decryptSession = $wechat->code($post['code']);
$this->success('获取session_key', $decryptSession);
}
/**
* 微信小程序登录
*
* @param string $code 加密code
*/
public function wxMiniProgramLogin()
{
$post = $this->request->post();
$wechat = new Wechat('wxMiniProgram');
$decryptUserInfo = $wechat->decryptData($post['session_key'], $post['iv'], $post['encryptedData']);
// array(10) {
// ["openId"] => string(28) "oD9ko40ZEoru7bjzN2f0Wnm3uNmA"
// ["nickName"] => string(12) "Civilization"
// ["gender"] => int(1)
// ["language"] => string(5) "zh_CN"
// ["city"] => string(0) ""
// ["province"] => string(0) ""
// ["country"] => string(7) "Iceland"
// ["avatarUrl"] => string(124) "https://wx.qlogo.cn/mmopen/vi_32/bKchg38ErVBnuJBb4NfCOYkMsxgzZ3vZGu7y7V0BQG8clImsyvZge2HzGGYfxXKBNv8dbQOvyvmjKPEtRyrniaA/132"
// ["unionId"] => string(28) "odsYQ1MLsGSGL6Gp5f6y3at2j7Hg"
// ["watermark"] => array(2) {
// ["timestamp"] => int(1590344429)
// ["appid"] => string(18) "wx39cd0799d4567dd0"
// }
// }
//组装decryptData
$decryptData = array_change_key_case($decryptUserInfo, CASE_LOWER);
$decryptData['headimgurl'] = $decryptData['avatarurl'];
$decryptData['sex'] = $decryptData['gender'];
$decryptData['session_key'] = $post['session_key'];
if (empty($decryptData['openid'])) {
$this->error(__('code错误'), $decryptData);
}
$ret = $this->oauthLoginOrRegister($decryptData, 'wxMiniProgram', 'Wechat');
if ($ret) {
$data = $ret->getUserinfo();
if (!isset($data['group'])) {
$data['group'] = \addons\shopro\model\UserGroup::get($data['group_id']);
}
$this->success(__('Logged in successful'), $data);
}
$this->error($this->auth->getError());
}
/**
* 微信APP登录
*
* @param string $authResult id信息
* @param string $userInfo 用户信息
*/
public function wxOpenPlatformLogin()
{
$params = $this->request->post();
//App
// 'authResult' =>
// array (
// 'access_token' => '32_WlLV5jxPoZuHWi7fnnxNPhun8Dj_igJPWOOxkP_WyEkHHc6pLpBz-13F3uu8KvS2HI0ei0l64Js8TD_W7A16JSr7PA16gwcDeU7RWd35gzQ',
// 'expires_in' => 7200,
// 'refresh_token' => '32_uvVpEiwt9q4ZmzDZgyF7jv8e4XxXValLOsuux4-GG7PIgywjnVL8Ovzzw-H1sKUd__X9NJko2lB49ZMo1ubYL4DT0Hv0C33yKkZDq8K0J9Y',
// 'openid' => 'oO01HuKtCFucLFr-Q9vwCLMGHO08',
// 'scope' => 'snsapi_userinfo',
// 'unionid' => 'odsYQ1IOJtHfVIK9KqPdy1U0uMBo',
// ),
// 'userInfo' =>
// array (
// 'openId' => 'oO01HuKtCFucLFr-Q9vwCLMGHO08',
// 'nickName' => 'RogerD',
// 'gender' => 1,
// 'city' => '中山',
// 'province' => '广东',
// 'country' => '中国',
// 'avatarUrl' => 'http://thirdwx.qlogo.cn/mmopen/vi_32/PiajxSqBRaEK5uWViaPyje54F39j2FZYgvVicB0sQV1zLQ4ia41DYm7bqLlygCYu5sH8Y4MvfFWicNRUP4by7l1yhkg/132',
// 'unionId' => 'odsYQ1IOJtHfVIK9KqPdy1U0uMBo',
// ),
//组装decryptData
$userInfo = array_change_key_case($params['userInfo'], CASE_LOWER);
$userInfo['headimgurl'] = $userInfo['avatarurl'];
$userInfo['sex'] = $userInfo['gender'];
$decryptData = array_merge($params['authResult'], $userInfo);
$ret = $this->oauthLoginOrRegister($decryptData, 'App', 'Wechat');
if ($ret) {
$data = $ret->getUserinfo();
if (!isset($data['group'])) {
$data['group'] = \addons\shopro\model\UserGroup::get($data['group_id']);
}
$this->success(__('Logged in successful'), $data);
}
$this->error($this->auth->getError());
}
/**
* 微信公众号登录
*
* @param string $code 加密code
*/
public function wxOfficialAccountLogin()
{
$wechat = new Wechat('wxOfficialAccount');
$oauth = $wechat->oauth();
//解析来源页面
$oUrl = input('get.state');
$url = explode('/', $oUrl);
$procotol = $url[0] . '//';
$host = $url[2];
$decryptData = $oauth->user()->getOriginal();
// ["openid"] => string(28) "oUgIVxASHEWU0wHd_ypNhJAdH088"
// ["nickname"] => string(6) "東浩"
// ["sex"] => int(1)
// ["language"] => string(5) "zh_CN"
// ["city"] => string(6) "郑州"
// ["province"] => string(6) "河南"
// ["country"] => string(6) "中国"
// ["headimgurl"] => string(133) "http://thirdwx.qlogo.cn/mmopen/vi_32/PiajxSqBRaEI3EldP4TQicjoF7utibMMRP08vfC9AOWia3WYmUWAGyI9GjWVkzMiahVYo2ef4KTNvVwLfhvKA3W0iccQ/132"
// ["privilege"] => array(0) {
// }
// ["unionid"] => string(28) "odsYQ1CI3j4CK8_NmWdz0HuKsajY"
$ret = $this->oauthLoginOrRegister($decryptData, 'wxOfficialAccount', 'Wechat');
if ($ret) {
//登录页接参Token
header('Location:' . $procotol . $host . '/pages/public/login?token=' . $ret->getToken());
exit;
}
$this->error($ret->getError());
}
/**
* 微信公众号静默登录
*
* @param string $code 加密code
*/
public function wxOfficialAccountBaseLogin()
{
$wechat = new Wechat('wxOfficialAccount');
$oauth = $wechat->oauth();
$oUrl = input('get.state');
$url = explode('/', $oUrl);
$decryptData = $oauth->user()->getOriginal();
if ($decryptData) {
header('Location:' . $oUrl . '&openid=' . $decryptData['openid']);
} else {
$this->error('未获取到OPENID');
}
}
/**
* 第三方登录或自动注册
*
* @param string $decryptData 解密参数
* @param string $platform 平台名称
* @param string $provider 厂商名称
* @param string $keeptime 有效时长
*/
private function oauthLoginOrRegister($decryptData, $platform, $provider, $keeptime = 0)
{
extract($decryptData);
@$oauthData = compact('provider', 'unionid', 'platform', 'openid', 'nickname', 'sex', 'city', 'province', 'country', 'headimgurl', 'session_key', 'refresh_token', 'access_token');
$oauthData['logintime'] = time();
$oauthData['logincount'] = 1;
if ($platform === 'wxMiniProgram' || $platform === 'App') {
$oauthData['expire_in'] = 7200;
$oauthData['expiretime'] = time() + 7200;
}
$auth = \app\common\library\Auth::instance();
$auth->keeptime($keeptime);
$auth->setAllowFields(['id', 'username', 'nickname', 'mobile', 'avatar', 'score', 'money', 'group', 'group_id']);
$userOauth = UserOauth::get(['openid' => $openid]);
if (isset($decryptData['nickname'])) {
$fields['nickname'] = $decryptData['nickname'];
}
if (isset($decryptData['headimgurl'])) {
$fields['avatar'] = $decryptData['headimgurl'];
}
//开启事务
Db::startTrans();
try {
if ($userOauth) {
//找到对应已注册用户,更新oauthData数据和用户数据直接发起登录
$user_id = $userOauth->user_id;
$user = UserModel::get($user_id);
$oauthData['logincount'] = $userOauth->logincount + 1;
$userOauth->save($oauthData);
} else {
//添加新的oauthData数据
//默认创建新用户
$createNewUser = true;
// 判断是否有unionid 并且已存在oauth数据中
if (isset($unionid)) {
//存在同厂商信息,添加oauthData数据,合并用户
$user_id = UserOauth::where(['unionid' => $unionid])->value('user_id');
$user = UserModel::get($user_id);
if ($user) {
$createNewUser = false;
}
}
if ($createNewUser) {
// 创建空用户
$username = Random::alnum(20);
$password = '';
$domain = request()->host();
$extend = $this->getUserDefaultFields();
$result = $auth->register($username, $password, $username . '@' . $domain, '', $extend, $keeptime);
if (!$result) {
return false;
}
$user = $auth->getUser();
if (!isset($fields['nickname'])) {
//默认昵称
$fields['nickname'] = $extend['nickname'] . $user->id;
}
// 更新会员资料
$user = UserModel::get($user->id);
// 保存第三方信息
$user_id = $user->id;
}
$oauthData['user_id'] = $user_id;
UserOauth::create($oauthData);
}
if (isset($fields)) $user->save($fields);
Db::commit();
} catch (\Exception $e) {
Db::rollback();
$auth->logout();
$this->error($e->getMessage());
return false;
}
$auth->direct($user_id);
return $auth;
}
/**
* 手机验证码登录
*
* @param string $mobile 手机号
* @param string $code 验证码
*/
public function mobileLogin()
{
$mobile = $this->request->post('mobile');
$code = $this->request->post('code');
if (!$mobile || !$code) {
$this->error(__('Invalid parameters'));
}
if (!Validate::regex($mobile, "^1\d{10}$")) {
$this->error(__('Mobile is incorrect'));
}
if (!Sms::check($mobile, $code, 'mobilelogin')) {
$this->error(__('Captcha is incorrect'));
}
$user = \app\common\model\User::getByMobile($mobile);
if ($user) {
if ($user->status != 'normal') {
$this->error(__('Account is locked'));
}
//如果已经有账号则直接登录
$ret = $this->auth->direct($user->id);
}
if ($ret) {
Sms::flush($mobile, 'mobilelogin');
$data = ['userinfo' => $this->auth->getUserinfo()];
$this->success(__('Logged in successful'), $data);
} else {
$this->error($this->auth->getError());
}
}
/**
* 注册会员
*
* @param string $username 用户名
* @param string $password 密码
* @param string $email 邮箱
* @param string $mobile 手机号
* @param string $code 验证码
*/
public function register()
{
$username = $this->request->post('mobile');
$password = $this->request->post('password');
$email = $this->request->post('mobile') . '@' . request()->host();
$mobile = $this->request->post('mobile');
$code = $this->request->post('code');
if (!$password) {
$this->error(__('请填写密码')); //TODO:密码规则校验
}
if (strlen($password) < 6 || strlen($password) > 16) {
$this->error(__('密码长度 6-16 位')); //TODO:密码规则校验
}
if ($email && !Validate::is($email, "email")) {
$this->error(__('邮箱填写错误'));
}
if ($mobile && !Validate::regex($mobile, "^1\d{10}$")) {
$this->error(__('手机号填写错误'));
}
$ret = Sms::check($mobile, $code, 'register');
if (!$ret) {
$this->error(__('Captcha is incorrect'));
}
$extend = $this->getUserDefaultFields();
$ret = $this->auth->register($username, $password, $email, $mobile, $extend);
if ($ret) {
$user = $this->auth->getUser();
$user->nickname = $user->nickname . $user->id;
$user->save();
$data = ['userinfo' => $this->auth->getUserinfo()];
$this->success(__('注册成功'), $data);
} else {
$this->error($this->auth->getError());
}
}
/**
* 注销登录
*/
public function logout()
{
$this->auth->logout();
$this->success(__('Logout successful'));
}
/**
* 修改会员个人信息
*
* @param string $avatar 头像地址
* @param string $username 用户名
* @param string $nickname 昵称
* @param string $birthday 生日
* @param string $bio 个人简介
*/
public function profile()
{
$user = $this->auth->getUser();
$username = $this->request->post('username');
$nickname = $this->request->post('nickname');
$bio = $this->request->post('bio', '');
$birthday = $this->request->post('birthday');
$avatar = $this->request->post('avatar', '', 'trim,strip_tags,htmlspecialchars');
if ($username) {
$exists = \app\common\model\User::where('username', $username)->where('id', '<>', $this->auth->id)->find();
if ($exists) {
$this->error(__('Username already exists'));
}
$user->username = $username;
}
$user->nickname = $nickname;
$user->bio = $bio;
$user->birthday = $birthday;
$user->avatar = $avatar;
$user->save();
$this->success();
}
/**
* 修改邮箱
*
* @param string $email 邮箱
* @param string $captcha 验证码
*/
public function changeemail()
{
$user = $this->auth->getUser();
$email = $this->request->post('email');
$captcha = $this->request->request('captcha');
if (!$email || !$captcha) {
$this->error(__('Invalid parameters'));
}
if (!Validate::is($email, "email")) {
$this->error(__('Email is incorrect'));
}
if (\app\common\model\User::where('email', $email)->where('id', '<>', $user->id)->find()) {
$this->error(__('Email already exists'));
}
$result = Ems::check($email, $captcha, 'changeemail');
if (!$result) {
$this->error(__('Captcha is incorrect'));
}
$verification = $user->verification;
$verification->email = 1;
$user->verification = $verification;
$user->email = $email;
$user->save();
Ems::flush($email, 'changeemail');
$this->success();
}
/**
* 修改手机号
*
* @param string $mobile 手机号
* @param string $captcha 验证码
*/
public function changemobile()
{
$user = $this->auth->getUser();
$mobile = $this->request->post('mobile');
$captcha = $this->request->post('captcha');
if (!$mobile || !$captcha) {
$this->error(__('Invalid parameters'));
}
if (!Validate::regex($mobile, "^1\d{10}$")) {
$this->error(__('Mobile is incorrect'));
}
if (\app\common\model\User::where('mobile', $mobile)->where('id', '<>', $user->id)->find()) {
$this->error(__('Mobile already exists'));
}
$result = Sms::check($mobile, $captcha, 'changemobile');
if (!$result) {
$this->error(__('Captcha is incorrect'));
}
$verification = $user->verification;
$verification->mobile = 1;
$user->verification = $verification;
$user->mobile = $mobile;
$user->save();
Sms::flush($mobile, 'changemobile');
$this->success();
}
/**
* 重置密码
*
* @param string $mobile 手机号
* @param string $newpassword 新密码
* @param string $captcha 验证码
*/
public function resetpwd()
{
$type = $this->request->post("type", 'mobile');
$mobile = $this->request->post("mobile");
$email = $this->request->post("email");
$newpassword = $this->request->post("newpassword");
$captcha = $this->request->post("captcha");
if (!$newpassword || !$captcha) {
$this->error(__('Invalid parameters'));
}
if (strlen($newpassword) < 6 || strlen($newpassword) > 16) {
$this->error(__('密码长度 6-16 位')); //TODO:密码规则校验
}
if ($type == 'mobile') {
if (!Validate::regex($mobile, "^1\d{10}$")) {
$this->error(__('Mobile is incorrect'));
}
$user = \app\common\model\User::getByMobile($mobile);
if (!$user) {
$this->error(__('User not found'));
}
$ret = Sms::check($mobile, $captcha, 'resetpwd');
if (!$ret) {
$this->error(__('Captcha is incorrect'));
}
Sms::flush($mobile, 'resetpwd');
} else {
if (!Validate::is($email, "email")) {
$this->error(__('Email is incorrect'));
}
$user = \app\common\model\User::getByEmail($email);
if (!$user) {
$this->error(__('User not found'));
}
$ret = Ems::check($email, $captcha, 'resetpwd');
if (!$ret) {
$this->error(__('Captcha is incorrect'));
}
Ems::flush($email, 'resetpwd');
}
//模拟一次登录
$this->auth->direct($user->id);
$ret = $this->auth->changepwd($newpassword, '', true);
if ($ret) {
$this->success(__('Reset password successful'));
} else {
$this->error($this->auth->getError());
}
}
public function changepwd()
{
$user = $this->auth->getUser();
$oldpassword = $this->request->post("oldpassword");
$newpassword = $this->request->post("newpassword");
if (!$newpassword || !$oldpassword) {
$this->error(__('Invalid parameters'));
}
if (strlen($newpassword) < 6 || strlen($newpassword) > 16) {
$this->error(__('密码长度 6-16 位')); //TODO:密码规则校验
}
$ret = $this->auth->changepwd($newpassword, $oldpassword);
if ($ret) {
$this->auth->direct($user->id);
$data = ['userinfo' => $this->auth->getUserinfo()];
$this->success(__('Change password successful'), $data);
} else {
$this->error($this->auth->getError());
}
}
private function getUserDefaultFields()
{
$userConfig = json_decode(\addons\shopro\model\Config::get(['name' => 'user'])->value,true);
return $userConfig;
}
}
... ...
<?php
namespace addons\shopro\controller;
class UserBank extends Base
{
protected $noNeedLogin = [];
protected $noNeedRight = ['*'];
public function info()
{
$this->success('银行卡', \addons\shopro\model\UserBank::info());
}
public function edit () {
$params = $this->request->post();
// 表单验证
$this->shoproValidate($params, get_class(), 'edit');
$this->success('编辑成功', \addons\shopro\model\UserBank::edit($params));
}
}
... ...
<?php
namespace addons\shopro\controller;
class UserSign extends Base
{
protected $noNeedLogin = [];
protected $noNeedRight = ['*'];
// 按月份获取签到记录
public function index()
{
$params = $this->request->get();
$this->success('获取成功', \addons\shopro\model\UserSign::getList($params));
}
public function sign () {
$params = $this->request->post();
$this->success('签到成功', \addons\shopro\model\UserSign::sign($params));
}
}
... ...
<?php
namespace addons\shopro\controller;
class UserWalletApply extends Base
{
protected $noNeedLogin = ['rule'];
protected $noNeedRight = ['*'];
public function index()
{
$this->success('提现记录', \addons\shopro\model\UserWalletApply::getList());
}
public function apply () {
$params = $this->request->post();
$this->success('申请成功', \addons\shopro\model\UserWalletApply::apply($params));
}
public function rule () {
// 提现规则
$config = \addons\shopro\model\Config::where('name', 'withdraw')->find();
$config = json_decode($config['value'], true);
$min = round(floatval($config['min']), 2);
$max = round(floatval($config['max']), 2);
$service_fee = floatval($config['service_fee']) * 100;
$service_fee = round($service_fee, 1); // 1 位小数
$rule = '提现金额必须';
if ($max) {
$rule .= '在' . $min . '-' . $max . '元之间';
} else {
$rule .= '大于' . ($min >= 0 ? $min : 0);
}
if ($service_fee) {
$rule .= ',提现手续费为提现金额的 '. $service_fee . '%';
}
$this->success('获取成功', $rule);
}
}
... ...
<?php
namespace addons\shopro\controller;
use addons\shopro\exception\Exception;
class UserWalletLog extends Base
{
protected $noNeedLogin = ['*'];
protected $noNeedRight = ['*'];
public function index()
{
$params = $this->request->get();
$wallet_type = $params['wallet_type'] ?? 'money';
$status = $params['status'] ?? 'all';
if (!in_array($wallet_type, ['money', 'score'])) {
throw new Exception('参数错误');
}
$this->success(($wallet_type == 'money' ? '钱包记录' : '积分记录'), \addons\shopro\model\UserWalletLog::getList($wallet_type, $status));
}
}
... ...
<?php
namespace addons\shopro\controller;
use addons\shopro\library\Wechat as WechatLibrary;
use addons\shopro\model\Wechat as WechatModel;
use addons\shopro\model\Config;
/**
* 微信接口
*/
class Wechat extends Base
{
protected $noNeedLogin = ['*'];
protected $noNeedRight = ['*'];
protected $app = null;
protected $userOpenId = '';
/**
* 微信公众号服务端API对接、处理消息回复
*/
public function index()
{
$wechat = new WechatLibrary('wxOfficialAccount');
$this->app = $wechat->getApp();
$this->app->server->push(function ($message) {
//初始化信息
$this->userOpenId = $message['FromUserName'];
// return json_encode($message, JSON_UNESCAPED_UNICODE); //调试使用
switch ($message['MsgType']) {
case 'event': //收到事件消息
switch ($message['Event']) {
case 'subscribe': //订阅(关注)事件
//获取粉丝信息并保存
$subscribe = WechatModel::get(['type' => 'subscribe']);
if ($subscribe) {
return $this->response($subscribe);
}
break;
case 'unsubscribe': //取消订阅(关注)事件
//获取粉丝信息并保存
break;
case 'CLICK': //自定义菜单事件
return $this->response($message, 'CLICK');
break;
case 'SCAN': //扫码事件
return '';
break;
}
break;
case 'text': //收到文本消息
//检测关键字回复
$content = $message['Content'];
$auto_reply = WechatModel::where('type', 'auto_reply')->where('find_in_set(:keywords,rules)', ['keywords' => $content])->find();
if ($auto_reply) {
return $this->response($auto_reply);
}
case 'image': //收到图片消息
case 'voice': //收到语音消息
case 'video': //收到视频消息
case 'location': //收到坐标消息
case 'link': //收到链接消息
case 'file': //收到文件消息
default: // ... 默认回复消息
$default_reply = WechatModel::where('type', 'default_reply')->find();
if ($default_reply) {
return $this->response($default_reply);
}
}
});
$response = $this->app->server->serve();
// 将响应输出
$response->send();
}
public function jssdk()
{
$params = $this->request->post();
$apis = [
'checkJsApi',
'onMenuShareTimeline',
'onMenuShareAppMessage',
'getLocation', //获取位置
'openLocation', //打开位置
'scanQRCode', //扫一扫接口
'chooseWXPay', //微信支付
'chooseImage', //拍照或从手机相册中选图接口
'previewImage', //预览图片接口
'uploadImage', //上传图片
'openAddress', // 获取微信地址
];
$uri = urldecode($params['uri']);
$wechat = new WechatLibrary('wxOfficialAccount');
$res = $wechat->getApp()->jssdk->setUrl($uri)->buildConfig($apis, $debug = false, $beta = false, $json = false);
$this->success('sdk', $res);
}
/**
* 微信公众号服务端API对接
*/
public function wxacode()
{
$scene = $this->request->get('scene', '');
$path = $this->request->get('path', '');
if (empty($path)) {
$path = 'pages/index/index';
}
$wechat = new WechatLibrary('wxMiniProgram');
$content = $wechat->getApp()->app_code->getUnlimit($scene, [
'page' => $path,
'is_hyaline' => true,
]);
if ($content instanceof \EasyWeChat\Kernel\Http\StreamResponse) {
return response($content->getBody(), 200, ['Content-Length' => strlen($content)])->contentType('image/png');
} else {
// 小程序码获取失败
$msg = isset($content['errcode']) ? $content['errcode'] : '-';
$msg .= isset($content['errmsg']) ? $content['errmsg'] : '';
\think\Log::write('wxacode-error' . $msg);
$this->error('获取失败', $msg);
}
}
/**
* 回复消息
*/
private function response($replyInfo, $event = 'text')
{
switch ($event) {
case 'SCAN': //解析扫码事件EventKey
break;
case 'CLICK': //解析菜单点击事件EventKey
$key = explode('|', $replyInfo['EventKey']);
if ($key) {
$message['type'] = $key[0];
if ($key[0] === 'text') {
$message['content'] = json_decode(WechatModel::get($key[1])->content, true);
} elseif($key[0] === 'link') {
$link = WechatModel::get($key[1]);
$message = array_merge($message, json_decode($link->content, true));
$message['title'] = $link->name;
// return json_encode($message);
}else {
$message['media_id'] = $key[1];
}
}
break;
default:
$message = json_decode($replyInfo['content'], true);
break;
}
switch ($message['type']) {
case 'text': //回复文本
$content = new \EasyWeChat\Kernel\Messages\Text($message['content']);
break;
case 'image': //回复图片
$content = new \EasyWeChat\Kernel\Messages\Image($message['media_id']);
break;
case 'news': //回复图文
$message = new \EasyWeChat\Kernel\Messages\Media($message['media_id'], 'mpnews');
$this->app->customer_service->message($message)->to($this->userOpenId)->send(); //素材消息使用客服接口回复
break;
case 'voice': //回复语音
$content = new \EasyWeChat\Kernel\Messages\Voice($message['media_id']);
break;
case 'video': //回复视频
$content = new \EasyWeChat\Kernel\Messages\Video($message['media_id']);
break;
case 'link': //回复链接
$items = new \EasyWeChat\Kernel\Messages\NewsItem([
'title' => $message['title'],
'description' => $message['description'],
'url' => $message['url'],
'image' => cdnurl($message['image'], true),
// ...
]);
$content = new \EasyWeChat\Kernel\Messages\News([$items]);
break;
}
return $content;
}
}
... ...
<?php
namespace addons\shopro\controller\store;
use addons\shopro\exception\Exception;
use addons\shopro\controller\Base as AddonsBase;
use addons\shopro\model\Store;
use addons\shopro\model\User;
use addons\shopro\model\UserStore;
class Base extends AddonsBase
{
public function _initialize()
{
parent::_initialize();
// 验证登录用户是否可以访问门店接口
$this->checkUserStore();
}
/**
* 检测用户管理的是否有门店
*/
private function checkUserStore() {
// 获取当前用户的门店
$user = User::info();
$store_id = $this->request->param('store_id');
if (!$store_id) {
throw new Exception('请选择门店');
}
$userStore = UserStore::with('store')->where('user_id', $user->id)->where('store_id', $store_id)->find();
if (!$userStore || !$userStore->store) {
throw new Exception('权限不足');
}
$store = $userStore->store->toArray();
// 存 session 本次请求有效
session('current_oper_store', $store);
}
}
... ...
<?php
namespace addons\shopro\controller\store;
class Order extends Base
{
protected $noNeedLogin = [];
protected $noNeedRight = ['*'];
public function index()
{
$params = $this->request->get();
$this->success('订单列表', \addons\shopro\model\store\Order::getList($params));
}
public function detail()
{
$params = $this->request->get();
$this->success('订单详情', \addons\shopro\model\store\Order::detail($params));
}
public function send() {
$params = $this->request->post();
$this->success('发货成功', \addons\shopro\model\store\Order::operSend($params));
}
public function confirm()
{
$params = $this->request->post();
$this->success('核销成功', \addons\shopro\model\store\Order::operConfirm($params));
}
}
... ...
<?php
namespace addons\shopro\controller\store;
use addons\shopro\exception\Exception;
use addons\shopro\model\Store as ModelStore;
class Store extends Base
{
protected $noNeedLogin = [];
protected $noNeedRight = ['*'];
public function index()
{
$params = $this->request->get();
$store = ModelStore::info();
if (!$store) {
throw new Exception('门店不存在');
}
$this->success('获取成功', $store);
}
}
... ...
<?php
namespace addons\shopro\exception;
use think\Response;
class Exception
{
protected $msg = '错误消息';
protected $code = 0; //TOAST自动弹出消息
const NOT_LOGIN = 401; //未登录自动弹框提醒
const NOT_AUTHORIZE = 403;//
const IGNORE = -1;
public function __construct($msg, $code = 0, $status_code = 200)
{
$this->msg = $msg;
$this->code = $code;
$this->send($status_code);
}
protected function send($code = 200)
{
$data = [
'code' => $this->code,
'msg' => $this->msg,
'data' => null,
'time' => time()
];
Response::create($data, 'json', $code)->send();
die;
}
}
... ...
<?php
if (!function_exists('matchLatLng')) {
function matchLatLng($latlng) {
$match = "/^\d{1,3}\.\d{1,30}$/";
return preg_match($match, $latlng) ? $latlng : 0;
}
}
if (!function_exists('getDistanceBuilder')) {
function getDistanceBuilder($lat, $lng) {
return "ROUND(6378.138 * 2 * ASIN(SQRT(POW(SIN((". matchLatLng($lat) . " * PI() / 180 - latitude * PI() / 180) / 2), 2) + COS(". matchLatLng($lat). " * PI() / 180) * COS(latitude * PI() / 180) * POW(SIN((". matchLatLng($lng). " * PI() / 180 - longitude * PI() / 180) / 2), 2))) * 1000) AS distance";
}
}
\ No newline at end of file
... ...
<?php
return [
// 订单创建
'order_create_before' => [ // 订单创建前
'addons\\shopro\\listener\\order\\Create'
],
'order_create_after' => [ // 订单创建后
'addons\\shopro\\listener\\order\\Create'
],
'order_payed_after' => [ // 订单支付成功
'addons\\shopro\\listener\\order\\Payed'
],
// 订单关闭
'order_close_before' => [ // 订单关闭前
],
'order_close_after' => [ // 订单关闭后
'addons\\shopro\\listener\\order\\Invalid'
],
// 订单取消
'order_cancel_before' => [ // 订单取消前
],
'order_cancel_after' => [ // 订单取消后
'addons\\shopro\\listener\\order\\Invalid'
],
// 订单发货
'order_send_before' => [ // 订单发货前
],
'order_send_after' => [ // 订单发货后
'addons\\shopro\\listener\\order\\Send'
],
// 订单确认收货
'order_confirm_before' => [ // 订单确认收货前
],
'order_confirm_after' => [ // 订单确认收货后
'addons\\shopro\\listener\\order\\Confirm'
],
// 订单完成事件
'order_finish' => [
],
// 订单评价
'order_comment_before' => [ // 订单评价前
],
'order_comment_after' => [ // 订单评价后
'addons\\shopro\\listener\\order\\Comment'
],
// 订单退款
'order_refund_before' => [ // 订单退款前
'addons\\shopro\\listener\\order\\Refund'
],
'order_refund_after' => [ // 订单退款后
'addons\\shopro\\listener\\order\\Refund'
],
// 订单拒绝退款 (钩子废弃 2020-07-28)
// 'order_refund_refuse_before' => [ // 订单拒绝退款前
// 'addons\\shopro\\listener\\order\\Refund'
// ],
// 'order_refund_refuse_after' => [ // 订单拒绝退款后
// 'addons\\shopro\\listener\\order\\Refund'
// ],
// 售后完成
'aftersale_finish_before' => [ // 售后完成前
],
'aftersale_finish_after' => [ // 售后完成后
],
// 售后拒绝
'aftersale_refuse_before' => [ // 售后拒绝前
],
'aftersale_refuse_after' => [ // 售后拒绝后
],
// 售后变动,(包含完成,拒绝)
'aftersale_change' => [ // 售后变动
'addons\\shopro\\listener\\order\\Aftersale'
],
// 活动更新
'activity_update_after' => [ // 活动更新后
'addons\\shopro\\listener\\activity\\Update'
],
'activity_delete_after' => [ // 活动删除之后
'addons\\shopro\\listener\\activity\\Update'
],
// 拼团
'activity_groupon_finish' => [ // 拼团成功
'addons\\shopro\\listener\\activity\\Groupon'
],
'activity_groupon_fail' => [ // 拼团失败,超时,后台手动解散等
'addons\\shopro\\listener\\activity\\Groupon'
]
];
... ...
name = shopro
title = Shopro商城
intro = 多发货方式、到店核销、对接客服、antV数据中心、店铺装修、小程序直播、跨端通用分享、自定义营销活动、Canvas分享海报、消息通知、微信管理、积分商城、拼团、秒杀等多种功能
author = 星品科技
website = https://shopro.top
version = 1.1.2
state = 1
url = /addons/shopro
first_menu = shopro
license = extended
licenseto = 10789
... ...
此 diff 太大无法显示。
<?php
namespace addons\shopro\job;
use addons\shopro\library\traits\ActivityCache;
use addons\shopro\model\Activity;
use think\queue\Job;
/**
* 订单自动操作
*/
class ActivityAutoOper extends BaseJob
{
use ActivityCache;
/**
* 活动自动删除
*/
public function autoClose(Job $job, $data){
try {
$activity = $data['activity'];
$activity = Activity::get($activity['id']);
// 一个活动会存在多个队列,要排重
if ($activity) {
// 如果活动还没被删除
// 规则
$rules = $activity['rules'];
// 当前配置应该自动结束的时间
$laterTime = $activity['endtime'];
if (isset($rules['activity_auto_close']) && $rules['activity_auto_close'] > 0) {
$laterTime += ($rules['activity_auto_close'] * 60);
}
// 如果当前时间大于 laterTime,可以执行删除
if (time() >= $laterTime) {
// 删除活动 【软删】
$activity->delete();
// 删除活动缓存
$this->delActivity($activity);
}
}
// 删除 job
$job->delete();
} catch (\Exception $e) {
// 队列执行失败
\think\Log::write('queue-' . get_class() . '-autoClose' . ':执行失败,错误信息:' . $e->getMessage());
}
}
}
\ No newline at end of file
... ...
<?php
namespace addons\shopro\job;
use addons\shopro\library\traits\ActivityCache;
use addons\shopro\library\traits\Groupon;
use addons\shopro\model\Activity;
use addons\shopro\model\ActivityGroupon;
use think\queue\Job;
/**
* 订单自动操作
*/
class ActivityGrouponAutoOper extends BaseJob
{
use ActivityCache, Groupon;
/**
* 拼团判断,将团结束,
*/
public function expire(Job $job, $data){
try {
$activity = $data['activity'];
$activity_groupon_id = $data['activity_groupon_id'];
$activityGroupon = ActivityGroupon::where('id', $activity_groupon_id)->find();
// 活动正在进行中, 走这里的说明人数 都没满
if ($activityGroupon && $activityGroupon['status'] == 'ing') {
\think\Db::transaction(function () use ($activity, $activityGroupon) {
$rules = $activity['rules'];
// 是否虚拟成团
$is_fictitious = $rules['is_fictitious'] ?? 0;
// 最大虚拟人数 ,不填或者 "" 不限制人数,都允许虚拟成团, 0相当于不允许虚拟成团
$fictitious_num = (!isset($rules['fictitious_num']) || $rules['fictitious_num'] == '') ? 'no-limit' : $rules['fictitious_num'];
// 拼团剩余人数
$surplus_num = $activityGroupon['num'] - $activityGroupon['current_num'];
if ($is_fictitious && ($fictitious_num == 'no-limit' || $fictitious_num >= $surplus_num)) {
// 虚拟成团,如果虚拟用户不够,则自动解散
$this->finishFictitiousGroupon($activityGroupon);
} else {
// 解散退款
$this->invalidRefundGroupon($activityGroupon);
}
});
}
// 删除 job
$job->delete();
} catch (\Exception $e) {
// 队列执行失败
\think\Log::write('queue-' . get_class() . '-expire' . ':执行失败,错误信息:' . $e->getMessage());
}
}
}
\ No newline at end of file
... ...
<?php
namespace addons\shopro\job;
use addons\shopro\model\Order;
use addons\shopro\model\OrderAction;
use think\queue\Job;
/**
* BaseJob 基类
*/
class BaseJob
{
public function failed($data){
// 记录日志
\think\Db::name('shopro_failed_job')->insert([
'data' => json_encode($data),
'createtime' => time(),
'updatetime' => time()
]);
}
}
\ No newline at end of file
... ...
<?php
namespace addons\shopro\job;
use think\queue\Job;
/**
* 队列消息通知
*/
class Notification extends BaseJob
{
/**
* 发送通知
*/
public function send(Job $job, $data){
try {
// 这里获取到的 $notifiables 和 notification 两个都是数组,不是类,尴尬, 更可恨的 notification 只是 {"delay":0,"event":"changemobile"}
$notifiables = $data['notifiables'];
$notification = $data['notification'];
// 因为 notification 只有参数,需要把对应的类传过来,在这里重新初始化
$notification_name = $data['notification_name'];
// 重新实例化 notification 实例
$notification = new $notification_name($notification['data']);
// 发送消息
\addons\shopro\library\notify\Notify::sendNow($notifiables, $notification);
// 删除 job
$job->delete();
} catch (\Exception $e) {
// 队列执行失败
\think\Log::write('queue-' . get_class()
. (isset($notification->event) ? ('-' . $notification->event) : '')
. ':执行失败,错误信息:' . $e->getMessage());
}
}
}
\ No newline at end of file
... ...
<?php
namespace addons\shopro\job;
use addons\shopro\model\GoodsComment;
use addons\shopro\model\Order;
use addons\shopro\model\OrderAction;
use addons\shopro\model\OrderItem;
use addons\shopro\model\Config;
use think\queue\Job;
/**
* 订单自动操作
*/
class OrderAutoOper extends BaseJob
{
/**
* 订单自动关闭
*/
public function autoClose(Job $job, $data){
try {
$order = $data['order'];
$order = Order::get($order['id']);
if ($order['status'] == 0) {
\think\Db::transaction(function () use ($order, $data) {
// 订单关闭前
\think\Hook::listen('order_close_before', $data);
// 执行关闭
$order->status = Order::STATUS_INVALID;
$order->ext = json_encode($order->setExt($order, ['invalid_time' => time()])); // 取消时间
$order->save();
OrderAction::operAdd($order, null, null, 'system', '系统自动失效订单');
// 订单自动关闭之后 行为 返还用户优惠券,积分
$data = ['order' => $order];
\think\Hook::listen('order_close_after', $data);
});
}
// 删除 job
$job->delete();
} catch (\Exception $e) {
// 队列执行失败
\think\Log::write('queue-' . get_class() . '-autoClose' . ':执行失败,错误信息:' . $e->getMessage());
}
}
/**
* 订单自动确认
*/
public function autoConfirm(Job $job, $data) {
try {
$order = $data['order'];
$item = $data['item'];
// 只要没有退款成功,所有队列正常执行
$item = OrderItem::where('id', $item['id'])
->where('dispatch_status', OrderItem::DISPATCH_STATUS_SENDED)
->where('refund_status', 'not in', [OrderItem::REFUND_STATUS_OK, OrderItem::REFUND_STATUS_FINISH])
->find();
if ($item) {
\think\Db::transaction(function () use ($order, $item, $data) {
(new Order())->getedItem($order, $item, ['oper_type' => 'system']);
});
}
// 删除 job
$job->delete();
} catch (\Exception $e) {
// 队列执行失败
\think\Log::write('queue-' . get_class() . '-autoConfirm' . ':执行失败,错误信息:' . $e->getMessage());
}
}
public function autoComment(Job $job, $data) {
try {
$order = $data['order'];
$item = $data['item'];
// 只要没有退款成功,所有队列正常执行
$item = OrderItem::where('id', $item['id'])
->where('dispatch_status', OrderItem::DISPATCH_STATUS_GETED)
->where('comment_status', OrderItem::COMMENT_STATUS_NO)
->where('refund_status', 'not in', [OrderItem::REFUND_STATUS_OK, OrderItem::REFUND_STATUS_FINISH])
->find();
if ($item) {
\think\Db::transaction(function () use ($order, $item, $data) {
// 订单评价前
\think\Hook::listen('order_comment_before', $data);
// 获取自动好评内容
$config = Config::where('name', 'order')->cache(300)->find(); // 读取配置自动缓存 5 分钟
$config = isset($config) ? json_decode($config['value'], true) : [];
$comment_content = (isset($config['order_comment_content']) && $config['order_comment_content'])
? $config['order_comment_content'] : '用户默认好评'; // 单位天
GoodsComment::create([
'goods_id' => $item['goods_id'],
'order_id' => $order['id'],
'user_id' => $order['user_id'],
'level' => 5, // 自动好评
'content' => $comment_content,
'images' => '',
'status' => 'show'
]);
$item->comment_status = OrderItem::COMMENT_STATUS_OK; // 评价成功
$item->save();
OrderAction::operAdd($order, $item, null, 'system', '系统自动评价成功');
// 订单评价后
$data = ['order' => $order, 'item' => $item];
\think\Hook::listen('order_comment_after', $data);
});
}
// 删除 job
$job->delete();
} catch (\Exception $e) {
// 队列执行失败
\think\Log::write('queue-' . get_class() . '-autoComment' . $e->getMessage());
}
}
}
\ No newline at end of file
... ...
<?php
namespace addons\shopro\job;
use addons\shopro\library\traits\ActivityCache;
use addons\shopro\library\traits\Groupon;
use addons\shopro\library\traits\StockSale;
use addons\shopro\model\GoodsComment;
use addons\shopro\model\Order;
use addons\shopro\model\OrderAction;
use addons\shopro\model\OrderItem;
use think\queue\Job;
/**
* 订单支付完成
*/
class OrderPayed extends BaseJob
{
use StockSale, ActivityCache, Groupon;
/**
* 订单支付完成
*/
public function payed(Job $job, $data){
try {
$order = $data['order'];
$user = $data['user'];
$order = Order::with('item')->where('id', $order['id'])->find();
\think\Db::transaction(function () use ($order, $user, $data) {
// 订单减库存
$this->realForwardStockSale($order);
// 判断,如果是拼团 真实加入团
if (strpos($order['activity_type'], 'groupon') !== false) {
$this->joinGroupon($order, $user);
}
// 检测有没有自动发货的商品,有就自动发货
$order->checkDispatchAndSend($order, ['user' => $user]);
// 触发订单支付完成事件
$data = ['order' => $order];
\think\Hook::listen('order_payed_after', $data);
});
// 删除 job
$job->delete();
} catch (\Exception $e) {
// 队列执行失败
\think\Log::write('queue-' . get_class() . '-payed' . ':执行失败,错误信息:' . $e->getMessage());
}
}
}
\ No newline at end of file
... ...
<?php
namespace addons\shopro\job;
use think\queue\Job;
/**
* 微信任务
*/
class Wechat extends BaseJob
{
/**
* 异步分批创建新的队列任务
*/
public function createQueueByOpenIdsArray(Job $job, $openIdsArray)
{
try {
$count = count($openIdsArray);
if ($count > 0) {
$page = ceil($count / 100);
for ($i = 0; $i < $page; $i++) {
\think\Queue::push('\addons\shopro\job\Wechat@saveSubscribeUserInfo', array_slice($openIdsArray, $i * 100, 100), 'shopro');
}
}
// 删除 job
$job->delete();
} catch (\Exception $e) {
// 队列执行失败
\think\Log::write('queue-' . get_class() . '-createQueueByOpenIdsArray' . ':执行失败,错误信息:' . $e->getMessage());
}
}
/**
* 保存更新关注用户
*/
public function saveSubscribeUserInfo(Job $job, $openIdsArray)
{
try {
$wechat = new \addons\shopro\library\Wechat('wxOfficialAccount');
$result = $wechat->getSubscribeUserInfoByOpenId($openIdsArray);
if (isset($result['user_info_list'])) {
$userInfoList = $result['user_info_list'];
$insertData = [];
foreach ($userInfoList as $u) {
$wechatFans = \app\admin\model\shopro\wechat\Fans::get(['openid' => $u['openid']]);
if ($wechatFans) {
$wechatFans->save([
'nickname' => $u['nickname'],
'headimgurl' => $u['headimgurl'],
'sex' => $u['sex'],
'country' => $u['country'],
'province' => $u['province'],
'city' => $u['city'],
'subscribe' => 1,
'subscribe_time' => $u['subscribe_time']
]);
}else{
$insertData[] = $u;
}
}
if (count($insertData) > 0) {
$wechatFans = new \app\admin\model\shopro\wechat\Fans;
$wechatFans->allowField(true)->saveAll($insertData);
}
}
$job->delete();
} catch (\Exception $e) {
// 队列执行失败
\think\Log::write('queue-' . get_class() . '-saveSubscribeUserInfo' . ':执行失败,错误信息2:' . $e->getMessage());
}
}
}
\ No newline at end of file
... ...
<?php
namespace addons\shopro\library;
/**
*
*/
class Activity extends Model
{
public function __construct($platform)
{
$this->config = Config::getEasyWechatConfig($platform);
switch ($platform) {
case 'wxOfficialAccount':
$this->app = Factory::officialAccount($this->config);
break;
case 'wxMiniProgram':
$this->app = Factory::miniProgram($this->config);
break;
}
}
}
... ...
<?php
namespace addons\shopro\library;
use EasyWeChat\Factory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
/**
*
*/
class Export
{
public function __construct()
{
}
public function exportExcel($expTitle, $expCellName, $expTableData){
$fileName = $expTitle;
$cellNum = count($expCellName);
$dataNum = count($expTableData);
$spreadsheet = new Spreadsheet();
$cellName = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'AA', 'AB', 'AC', 'AD', 'AE', 'AF', 'AG', 'AH', 'AI', 'AJ', 'AK', 'AL', 'AM', 'AN', 'AO', 'AP', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AV', 'AW', 'AX', 'AY', 'AZ');
$sheet = $spreadsheet->getActiveSheet(0);
// for ($i = 0; $i < $cellNum; $i++) {
// $sheet->getColumnDimension($cellName[$i])->setWidth(30);
// }
$sheet->getStyle('A1:' . $cellName[$cellNum - 1] . '1')->getFont()->setBold(true);
$i = 0;
foreach ($expCellName as $key => $cell) {
$sheet->setCellValue($cellName[$i] . '1', $cell);
$i ++;
}
for ($i = 0; $i < $dataNum; $i++) {
if ($i == ($dataNum - 1)) {
$sheet->mergeCells('A' . ($i + 2) . ':' . $cellName[$cellNum - 1] . ($i + 2));
$sheet->setCellValue('A' . ($i + 2), $expTableData[$i][key($expCellName)]);
} else {
$j = 0;
foreach ($expCellName as $key => $cell) {
$sheet->setCellValue($cellName[$j] . ($i + 2), $expTableData[$i][$key]);
$j++;
}
}
}
header('pragma:public');
header('Content-type:application/vnd.ms-excel;charset=utf-8;name="' . $fileName . '.xls"');
header("Content-Disposition:attachment;filename=$fileName.xls"); //attachment新窗口打印inline本窗口打印
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx');
$writer->save('php://output');
}
}
... ...
<?php
namespace addons\shopro\library;
use fast\Http;
class Express
{
// 查询接口
const REQURL = "https://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx";
// 订阅接口
const SUBURL = "https://api.kdniao.com/api/dist";
protected $config = [];
/**
* 构造函数
*/
public function __construct()
{
$config = \addons\shopro\model\Config::get(['name' => 'services']);
$config = ($config && $config->value) ? json_decode($config->value, true) : [];
$expressConfig = $config['express'] ?? [];
if (!$expressConfig || !$expressConfig['ebusiness_id'] || !$expressConfig['appkey']) {
throw new \Exception('请配置快递接口');
}
$this->config = $expressConfig;
}
/**
* Json方式 物流信息订阅
*/
public function subscribe($data = [], $orderExpress = null, $order = null)
{
$requestData = $this->getRequestData($data, $orderExpress = null, $order = null);
$datas = [
'EBusinessID' => $this->config['ebusiness_id'],
'RequestType' => $this->config['type'] == 'free' ? '1008' : '8008',
'RequestData' => urlencode($requestData),
'DataType' => '2',
];
$datas['DataSign'] = $this->encrypt($requestData, $this->config['appkey']);
$result = Http::sendRequest(self::SUBURL, $datas, 'POST', []);
if ($result['ret'] == 1) {
$exResult = json_decode($result['msg'], true);
if (!$exResult['Success']) {
throw new \Exception($exResult['Reason']);
}
return $exResult;
} else {
throw new \Exception($result['msg']);
}
}
// 查询快递信息
public function search($data = [], $orderExpress = null, $order = null)
{
$requestData = $this->getRequestData($data, $orderExpress = null, $order = null);
$datas = [
'EBusinessID' => $this->config['ebusiness_id'],
'RequestType' => $this->config['type'] == 'free' ? '1002' : '8001',
'RequestData' => urlencode($requestData),
'DataType' => '2',
];
$datas['DataSign'] = $this->encrypt($requestData, $this->config['appkey']);
$result = Http::sendRequest(self::REQURL, $datas, 'POST', []);
if ($result['ret'] == 1) {
$exResult = json_decode($result['msg'], true);
if (!$exResult['Success']) {
throw new \Exception($exResult['Reason']);
}
return $exResult;
} else {
throw new \Exception($result['msg']);
}
}
// 组装请求数据
private function getRequestData($data = [], $orderExpress = null, $order = null) {
$requestData = [
'OrderCode' => $order ? $order->order_sn : '',
'ShipperCode' => $data['express_code'],
'LogisticCode' => $data['express_no'],
];
if ($data['express_code'] == 'JD') {
// 京东青龙配送单号
$requestData['CustomerName'] = $this->config['jd_code'];
} else if ($data['express_code'] == 'SF') {
// 收件人手机号后四位
$requestData['CustomerName'] = substr($order->phone, 7);
}
$requestData = json_encode($requestData);
return $requestData;
}
// 差异更新物流信息
public function checkAndAddTraces ($orderExpress, $express) {
$traces = $express['Traces'];
// 查询现有轨迹记录
$orderExpressLog = \addons\shopro\model\OrderExpressLog::where('order_express_id', $orderExpress->id)->select();
$log_count = count($orderExpressLog);
if ($log_count > 0) {
// 移除已经存在的记录
array_splice($traces, 0, $log_count);
}
// 增加包裹记录
foreach ($traces as $k => $trace) {
$orderExpressLog = new \addons\shopro\model\OrderExpressLog();
$orderExpressLog->user_id = $orderExpress['user_id'];
$orderExpressLog->order_id = $orderExpress['order_id'];
$orderExpressLog->order_express_id = $orderExpress['id'];
$orderExpressLog->status = $trace['Action'] ?? $express['State'];
$orderExpressLog->content = $trace['AcceptStation'];
$orderExpressLog->changedate = substr($trace['AcceptTime'], 0, 19); // 快递鸟测试数据 返回的是个 2020-08-03 16:58:272 格式
$orderExpressLog->location = $trace['Location'] ?? ($express['Location'] ?? null);
$orderExpressLog->save();
}
}
// 组装返回结果
public function setPushResult($success = false, $reason = '') {
$result = [
"EBusinessID" => $this->config['ebusiness_id'],
"UpdateTime" => date('Y-m-d H:i:s'),
"Success" => $success,
"Reason" => $reason
];
return json_encode($result);
}
// 加签
function encrypt($data, $appkey)
{
return urlencode(base64_encode(md5($data . $appkey)));
}
}
\ No newline at end of file
... ...
<?php
namespace addons\shopro\library;
use EasyWeChat\Factory;
use addons\shopro\model\Config;
use think\Model;
/**
*
*/
class Hook
{
public function __construct()
{
}
public static function register ($behaviors = []) {
$default = require ROOT_PATH . 'addons/shopro/hooks.php';
$behaviors = array_merge($default, $behaviors);
foreach ($behaviors as $tag => $behavior) {
// 数组反转保证 最上面的行为优先级最高
$behavior = array_reverse($behavior);
foreach ($behavior as $be) {
\think\Hook::add($tag, $be, true); // 所有行为都插入最前面
}
}
}
}
... ...
<?php
namespace addons\shopro\library;
use Yansongda\Pay\Pay;
use Yansongda\Pay\Log;
use addons\shopro\exception\Exception;
class PayService
{
protected $config;
protected $platform;
protected $payment;
protected $notify_url;
public $method;
public function __construct($payment, $platform = '', $notify_url = '')
{
$this->platform = $platform;
$this->payment = $payment;
$this->notify_url = $notify_url;
$this->setPaymentConfig();
}
private function setPaymentConfig()
{
$paymentConfig = json_decode(\addons\shopro\model\Config::get(['name' => $this->payment])->value, true);
if ($this->platform != 'url' && !in_array($this->platform, $paymentConfig['platform'])) {
throw new Exception('暂不支持该方式付款');
}
$this->config = $paymentConfig;
$this->config['notify_url'] = $this->notify_url;
if ($this->payment === 'wechat') {
switch ($this->platform) {
case 'wxOfficialAccount':
$platformConfig = json_decode(\addons\shopro\model\Config::get(['name' => $this->platform])->value, true);
$this->config['app_id'] = $platformConfig['app_id'];
break;
case 'wxMiniProgram':
$platformConfig = json_decode(\addons\shopro\model\Config::get(['name' => $this->platform])->value, true);
$this->config['miniapp_id'] = $platformConfig['app_id'];
break;
case 'H5':
$platformConfig = json_decode(\addons\shopro\model\Config::get(['name' => $this->platform])->value, true);
$this->config['app_id'] = $platformConfig['app_id'];
break;
case 'App':
$platformConfig = json_decode(\addons\shopro\model\Config::get(['name' => 'App'])->value, true);
$this->config['appid'] = $platformConfig['app_id']; // 微信 App 支付使用这个
$this->config['app_id'] = $platformConfig['app_id']; // 微信 App 支付退款使用的是这个
break;
}
}
// 处理证书路径
if ($this->payment == 'wechat') {
// 微信支付证书
$this->config['cert_client'] = ROOT_PATH . 'public' . $this->config['cert_client'];
$this->config['cert_key'] = ROOT_PATH . 'public' . $this->config['cert_key'];
} else {
// 支付宝证书路径
$end = substr($this->config['ali_public_key'], -4);
if ($end == '.crt') {
$this->config['ali_public_key'] = ROOT_PATH . 'public' . $this->config['ali_public_key'];
}
$this->config['app_cert_public_key'] = ROOT_PATH . 'public' . $this->config['app_cert_public_key'];
$this->config['alipay_root_cert'] = ROOT_PATH . 'public' . $this->config['alipay_root_cert'];
}
$this->setPaymentMethod();
}
private function setPaymentMethod()
{
$method = [
'wechat' => [
'wxOfficialAccount' => 'mp', //公众号支付 Collection
'wxMiniProgram' => 'miniapp', //小程序支付
'H5' => 'wap', //手机网站支付 Response
'App' => 'app' //APP 支付 JsonResponse
],
'alipay' => [
'wxOfficialAccount' => 'wap', //手机网站支付 Response
'wxMiniProgram' => 'wap', //小程序支付
'H5' => 'wap', //手机网站支付 Response
'url' => 'wap', //手机网站支付 Response
'App' => 'app' //APP 支付 JsonResponse
],
];
$this->method = $method[$this->payment][$this->platform];
}
public function create($order)
{
// $order = [
// 'out_trade_no' => time(),
// 'total_fee' => '1', // **单位:分**
// 'body' => 'test body - 测试',
// 'openid' => 'onkVf1FjWS5SBIixxxxxxx', //微信需要带openid过来
// ];
$method = $this->method;
switch ($this->payment) {
case 'wechat':
$order['total_fee'] = $order['total_fee'] * 100;
$pay = Pay::wechat($this->config)->$method($order);
break;
case 'alipay':
if (in_array($this->platform, ['wxOfficialAccount', 'wxMiniProgram', 'H5'])) {
// 返回支付宝支付链接
$pay = request()->domain() . '/addons/shopro/pay/alipay?order_sn=' . $order['out_trade_no'];
} else {
if ($this->method == 'wap') {
// 支付宝 wap 支付,增加 return_url
// 获取 h5 域名
$platformConfig = json_decode(\addons\shopro\model\Config::get(['name' => 'shopro'])->value, true);
// 如果域名存在,增加 return_url
if ($platformConfig && isset($platformConfig['domain'])) {
$start = substr($platformConfig['domain'], -1) == '/' ? "" : "/";
$this->config['return_url'] = $platformConfig['domain'] . $start . "pages/order/payment/result?orderSn=" . $order['out_trade_no'] . "&type=alipay&pay=1";
}
}
$pay = Pay::alipay($this->config)->$method($order);
}
break;
}
return $pay;
}
public function notify($callback)
{
$pay = $this->getPay();
try {
$data = $pay->verify(); // 是的,验签就这么简单!
$result = $callback($data, $pay);
// Log::debug('Wechat notify', $data->all());
} catch (\Exception $e) {
// $e->getMessage();
}
return $result;
}
public function refund($order_data) {
$pay = $this->getPay();
$order_data['type'] = $this->platform == 'wxMiniProgram' ? 'miniapp' : '';
$result = $pay->refund($order_data);
return $result;
}
public function notifyRefund($callback) {
$pay = $this->getPay();
try {
$data = $pay->verify(null, true); // 是的,验签就这么简单!
$result = $callback($data, $pay);
// Log::debug('Wechat notify', $data->all());
} catch (\Exception $e) {
// $e->getMessage();
}
return $result;
}
private function getPay () {
switch ($this->payment) {
case 'wechat':
$pay = Pay::wechat($this->config);
break;
case 'alipay':
$pay = Pay::alipay($this->config);
break;
default :
throw new Exception('支付方式不支持');
}
return $pay;
}
}
... ...
<?php
namespace addons\shopro\library;
use addons\shopro\exception\Exception;
class Redis
{
protected $handler = null;
protected $options = [
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'select' => 0,
'timeout' => 0,
'expire' => 0,
'persistent' => false,
'prefix' => '',
];
/**
* 构造函数
* @param array $options 缓存参数
* @access public
*/
public function __construct($options = [])
{
if (!extension_loaded('redis')) {
throw new \BadFunctionCallException('not support: redis');
}
// 获取 redis 配置
$config = \think\Config::get('redis');
if (empty($config) && empty($options)) {
throw new \Exception('redis connection fail: no redis config');
}
if (!empty($config)) {
$this->options = array_merge($this->options, $config);
}
if (!empty($options)) {
$this->options = array_merge($this->options, $options);
}
$this->handler = new \Redis();
if ($this->options['persistent']) {
$this->handler->pconnect($this->options['host'], $this->options['port'], $this->options['timeout'], 'persistent_id_' . $this->options['select']);
} else {
$this->handler->connect($this->options['host'], $this->options['port'], $this->options['timeout']);
}
if ('' != $this->options['password']) {
$this->handler->auth($this->options['password']);
}
if (0 != $this->options['select']) {
$this->handler->select($this->options['select']);
}
// 赋值全局,避免多次实例化
$GLOBALS['SPREDIS'] = $this->handler;
}
public function getRedis() {
return $this->handler;
}
}
\ No newline at end of file
... ...
<?php
namespace Yansongda\Supports;
use Closure;
/**
* Array helper from Illuminate\Support\Arr.
*/
class Arr
{
/**
* Add an element to an array using "dot" notation if it doesn't exist.
*
* @param array $array
* @param string $key
* @param mixed $value
*
* @return array
*/
public static function add($array, $key, $value)
{
if (is_null(static::get($array, $key))) {
static::set($array, $key, $value);
}
return $array;
}
/**
* Build a new array using a callback.
*
* @param array $array
*
* @return array
*/
public static function build($array, Closure $callback)
{
$results = [];
foreach ($array as $key => $value) {
list($innerKey, $innerValue) = call_user_func($callback, $key, $value);
$results[$innerKey] = $innerValue;
}
return $results;
}
/**
* Divide an array into two arrays. One with keys and the other with values.
*
* @param array $array
*
* @return array
*/
public static function divide($array)
{
return [
array_keys($array),
array_values($array),
];
}
/**
* Flatten a multi-dimensional associative array with dots.
*
* @param array $array
* @param string $prepend
*
* @return array
*/
public static function dot($array, $prepend = '')
{
$results = [];
foreach ($array as $key => $value) {
if (is_array($value)) {
$results = array_merge($results, static::dot($value, $prepend.$key.'.'));
} else {
$results[$prepend.$key] = $value;
}
}
return $results;
}
/**
* Get all of the given array except for a specified array of items.
*
* @param array $array
* @param array|string $keys
*
* @return array
*/
public static function except($array, $keys)
{
return array_diff_key($array, array_flip((array) $keys));
}
/**
* Fetch a flattened array of a nested array element.
*
* @param array $array
* @param string $key
*
* @return array
*/
public static function fetch($array, $key)
{
$results = [];
foreach (explode('.', $key) as $segment) {
$results = [];
foreach ($array as $value) {
$value = (array) $value;
$results[] = $value[$segment];
}
$array = array_values($results);
}
return array_values($results);
}
/**
* Return the first element in an array passing a given truth test.
*
* @param array $array
* @param Closure $callback
* @param mixed $default
*
* @return mixed
*/
public static function first($array, $callback, $default = null)
{
foreach ($array as $key => $value) {
if (call_user_func($callback, $key, $value)) {
return $value;
}
}
return $default;
}
/**
* Return the last element in an array passing a given truth test.
*
* @param array $array
* @param Closure $callback
* @param mixed $default
*
* @return mixed
*/
public static function last($array, $callback, $default = null)
{
return static::first(array_reverse($array), $callback, $default);
}
/**
* Flatten a multi-dimensional array into a single level.
*
* @param array $array
*
* @return array
*/
public static function flatten($array)
{
$return = [];
array_walk_recursive(
$array,
function ($x) use (&$return) {
$return[] = $x;
}
);
return $return;
}
/**
* Remove one or many array items from a given array using "dot" notation.
*
* @param array $array
* @param array|string $keys
*/
public static function forget(&$array, $keys)
{
$original = &$array;
foreach ((array) $keys as $key) {
$parts = explode('.', $key);
while (count($parts) > 1) {
$part = array_shift($parts);
if (isset($array[$part]) && is_array($array[$part])) {
$array = &$array[$part];
}
}
unset($array[array_shift($parts)]);
// clean up after each pass
$array = &$original;
}
}
/**
* Get an item from an array using "dot" notation.
*
* @param array $array
* @param string $key
* @param mixed $default
*
* @return mixed
*/
public static function get($array, $key, $default = null)
{
if (is_null($key)) {
return $array;
}
if (isset($array[$key])) {
return $array[$key];
}
foreach (explode('.', $key) as $segment) {
if (!is_array($array) || !array_key_exists($segment, $array)) {
return $default;
}
$array = $array[$segment];
}
return $array;
}
/**
* Get a subset of the items from the given array.
*
* @param array $array
* @param array|string $keys
*
* @return array
*/
public static function only($array, $keys)
{
return array_intersect_key($array, array_flip((array) $keys));
}
/**
* Pluck an array of values from an array.
*
* @param array $array
* @param string $value
* @param string $key
*
* @return array
*/
public static function pluck($array, $value, $key = null)
{
$results = [];
foreach ($array as $item) {
$itemValue = is_object($item) ? $item->{$value} : $item[$value];
// If the key is "null", we will just append the value to the array and keep
// looping. Otherwise we will key the array using the value of the key we
// received from the developer. Then we'll return the final array form.
if (is_null($key)) {
$results[] = $itemValue;
} else {
$itemKey = is_object($item) ? $item->{$key} : $item[$key];
$results[$itemKey] = $itemValue;
}
}
return $results;
}
/**
* Get a value from the array, and remove it.
*
* @param array $array
* @param string $key
* @param mixed $default
*
* @return mixed
*/
public static function pull(&$array, $key, $default = null)
{
$value = static::get($array, $key, $default);
static::forget($array, $key);
return $value;
}
/**
* Set an array item to a given value using "dot" notation.
*
* If no key is given to the method, the entire array will be replaced.
*
* @param array $array
* @param string $key
* @param mixed $value
*
* @return array
*/
public static function set(&$array, $key, $value)
{
if (is_null($key)) {
return $array = $value;
}
$keys = explode('.', $key);
while (count($keys) > 1) {
$key = array_shift($keys);
// If the key doesn't exist at this depth, we will just create an empty array
// to hold the next value, allowing us to create the arrays to hold final
// values at the correct depth. Then we'll keep digging into the array.
if (!isset($array[$key]) || !is_array($array[$key])) {
$array[$key] = [];
}
$array = &$array[$key];
}
$array[array_shift($keys)] = $value;
return $array;
}
/**
* Sort the array using the given Closure.
*
* @param array $array
*
* @return array
*/
public static function sort($array, Closure $callback)
{
$results = [];
foreach ($array as $key => $value) {
$results[$key] = $callback($value);
}
return $results;
}
/**
* Filter the array using the given Closure.
*
* @param array $array
*
* @return array
*/
public static function where($array, Closure $callback)
{
$filtered = [];
foreach ($array as $key => $value) {
if (call_user_func($callback, $key, $value)) {
$filtered[$key] = $value;
}
}
return $filtered;
}
/**
* Convert encoding.
*
* @author yansongda <me@yansongda.cn>
*
* @param array $array
* @param string $to_encoding
* @param string $from_encoding
*
* @return array
*/
public static function encoding($array, $to_encoding, $from_encoding = 'gb2312')
{
$encoded = [];
foreach ($array as $key => $value) {
$encoded[$key] = is_array($value) ? self::encoding($value, $to_encoding, $from_encoding) :
mb_convert_encoding($value, $to_encoding, $from_encoding);
}
return $encoded;
}
}
... ...