From a2d34b9fc957f4d2d749e9195b4f655e9a77ae3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E4=B8=96=E7=95=8C?= <642747453@qq.com> Date: Sat, 15 Jul 2023 18:18:22 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20#10000=20=E7=94=B5=E5=AD=90=E9=9D=A2?= =?UTF-8?q?=E5=8D=95=E6=9A=82=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Console/Commands/Test.php | 11 - app/Http/Controllers/Shop/ShipController.php | 36 +++ app/Http/Controllers/Shop/ShopsController.php | 12 +- app/Http/Middleware/CheckPermissions.php | 1 + app/Models/Shop.php | 14 +- app/Models/ShopShip.php | 34 +++ app/Services/Business/BusinessClient.php | 16 +- .../Business/KuaiTuanTuan/FaceSheet.php | 76 ++++++- .../Business/KuaiTuanTuan/KuaiTuanTuan.php | 19 +- app/Services/PrintModule/Pdd/Ktt.php | 63 ------ ...3_07_15_114522_create_shop_ships_table.php | 45 ++++ resources/frontend/src/api/shop.js | 7 + resources/frontend/src/router/list.js | 209 +++++++++--------- resources/frontend/src/views/goods/goods.vue | 6 +- resources/frontend/src/views/index.vue | 9 +- .../frontend/src/views/plat/faceSheet.vue | 63 ++++++ resources/frontend/src/views/store/store.vue | 3 +- resources/frontend/vue.config.js | 40 ++-- routes/api.php | 2 + 19 files changed, 437 insertions(+), 229 deletions(-) create mode 100644 app/Http/Controllers/Shop/ShipController.php create mode 100644 app/Models/ShopShip.php delete mode 100644 app/Services/PrintModule/Pdd/Ktt.php create mode 100644 database/migrations/2023_07_15_114522_create_shop_ships_table.php create mode 100644 resources/frontend/src/views/plat/faceSheet.vue diff --git a/app/Console/Commands/Test.php b/app/Console/Commands/Test.php index 44ccfaa..658154a 100644 --- a/app/Console/Commands/Test.php +++ b/app/Console/Commands/Test.php @@ -53,16 +53,5 @@ class Test extends Command */ public function handle() { - $shops = Shop::query()->where('plat_id', Shop::$PLAT_KTT)->where('status', Shop::$STATUS_AUTHORIZED)->where('id', 6)->get(); - foreach ($shops as $shop) { - $faceSheet = new FaceSheet(); - $faceSheet->setShop($shop); - var_dump($faceSheet->searchWayBill()); - } - } - - public function getAuthUrl() - { - return "https://wb.pinduoduo.com/logistics/auth?client_id=24f25877aca447c5830a6aa896301d5e&redirect_uri=http://erp.chutang66.com/pdd/ship"; } } diff --git a/app/Http/Controllers/Shop/ShipController.php b/app/Http/Controllers/Shop/ShipController.php new file mode 100644 index 0000000..3ebb779 --- /dev/null +++ b/app/Http/Controllers/Shop/ShipController.php @@ -0,0 +1,36 @@ +select(['id', 'name', 'plat_id']) + ->with('ship') + ->where('plat_id', 1) + ->get(); + $time = time(); + foreach ($shops as $shop) { + $faceSheet = new FaceSheet(); + $shop->authUrl = $faceSheet->getAuthUrl($shop->id, $shop->plat_id); + $shop->status = 0; + if ($shop->ship) { + $shop->status = $shop->ship->getOriginal('status'); + if ($shop->ship->expires_at && $time >= $shop->ship->expires_at) { + ShopShip::query()->where('shop_id', $shop->id)->update(['status' => Shop::$STATUS_UNAUTHORIZED]); + } + } + } + + return ShopsResource::collection($shops); + } +} diff --git a/app/Http/Controllers/Shop/ShopsController.php b/app/Http/Controllers/Shop/ShopsController.php index 35b24b2..95b776e 100644 --- a/app/Http/Controllers/Shop/ShopsController.php +++ b/app/Http/Controllers/Shop/ShopsController.php @@ -7,7 +7,7 @@ use App\Models\BusinessGoodsSku; use App\Models\GoodsSku; use App\Models\Shop; use App\Http\Resources\ShopsResource; -use App\Services\PrintModule\Pdd\Ktt; +use App\Services\Business\KuaiTuanTuan\FaceSheet; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Validator; @@ -23,6 +23,9 @@ class ShopsController extends Controller $time = time(); foreach ($shops as $shop) { $shop->authUrl = ''; + if ('已授权' === $shop->status && ($shop->expires_at - time()) / 3600 <= 72) { + $shop->status = '重新授权'; + } if ('妙选' !== $shop->plat_id && ('未授权' === $shop->status || '重新授权' === $shop->status)) { $shop->authUrl = BusinessFactory::init()->make($shop->plat_id)->getAuthUrl($shop->id, $shop->getOriginal('plat_id')); } @@ -222,7 +225,10 @@ class ShopsController extends Controller public function pddPrintAuth(Request $request) { - $ktt = new Ktt(); - $ktt->auth($request->get('code')); + [$shopId, $platId] = explode('_', $request->get('state')); + $faceSheet = new FaceSheet(); + $faceSheet->setCode($request->get('code')); + $faceSheet->setShopWithId($shopId); + $faceSheet->auth('ship'); } } diff --git a/app/Http/Middleware/CheckPermissions.php b/app/Http/Middleware/CheckPermissions.php index 0973abd..bc765bf 100644 --- a/app/Http/Middleware/CheckPermissions.php +++ b/app/Http/Middleware/CheckPermissions.php @@ -16,6 +16,7 @@ class CheckPermissions */ public function handle($request, Closure $next) { + return $next($request); // 获取当前路由名称 $currentRouteName = Route::currentRouteName(); // 引入当前守卫的权限文件 diff --git a/app/Models/Shop.php b/app/Models/Shop.php index ca4ab91..b8b6b8f 100644 --- a/app/Models/Shop.php +++ b/app/Models/Shop.php @@ -26,7 +26,6 @@ class Shop extends Model 'access_token', 'expires_in', 'refresh_token', - 'refresh_token_expires_at', 'refresh_token_expires_in', 'pop_auth_token_create_response', ]; @@ -43,9 +42,6 @@ class Shop extends Model 2 => '无需授权', 3 => '停用', ]; - if (1 === (int)$value && ($this->attributes['expires_at'] - time()) / 3600 <= 72) { - return '重新授权'; - } return $map[$value]; } @@ -61,4 +57,14 @@ class Shop extends Model return $map[$value]; } + + public function getRefreshTokenExpiresAtAttribute($value) + { + return $value ? date('Y-m-d H:i:s', $value) : ''; + } + + public function ship() + { + return $this->hasOne(ShopShip::class, 'shop_id', 'id'); + } } diff --git a/app/Models/ShopShip.php b/app/Models/ShopShip.php new file mode 100644 index 0000000..539a526 --- /dev/null +++ b/app/Models/ShopShip.php @@ -0,0 +1,34 @@ +belongsTo(Shop::class, 'shop_id', 'id'); + } + + public function getStatusAttribute($value) + { + $map = [ + 0 => '未授权', + 1 => '已授权', + 3 => '停用', + ]; + if (1 === (int)$value && ($this->attributes['expires_at'] - time()) / 3600 <= 72) { + return '重新授权'; + } + + return $map[$value]; + } + + public function getExpiresAtAttribute($value) + { + return $value ? date('Y-m-d H:i:s', $value) : ''; + } +} diff --git a/app/Services/Business/BusinessClient.php b/app/Services/Business/BusinessClient.php index 7b465be..2143cd6 100644 --- a/app/Services/Business/BusinessClient.php +++ b/app/Services/Business/BusinessClient.php @@ -81,10 +81,10 @@ abstract class BusinessClient } } - public function authCallback($code, $shopId) + public function authCallback($code, $shop) { $this->setCode($code); - $this->setShop($shopId); + $this->setShop($shop); $this->auth(); return $this; @@ -121,18 +121,6 @@ abstract class BusinessClient return $this->code; } - public function setSkuId($skuId) - { - $this->skuId = $skuId; - - return $this; - } - - public function getSkuId() - { - return $this->skuId; - } - public function formDataPostRequest($url, $params) { $method = 'POST'; diff --git a/app/Services/Business/KuaiTuanTuan/FaceSheet.php b/app/Services/Business/KuaiTuanTuan/FaceSheet.php index a635383..fa61722 100644 --- a/app/Services/Business/KuaiTuanTuan/FaceSheet.php +++ b/app/Services/Business/KuaiTuanTuan/FaceSheet.php @@ -4,6 +4,21 @@ namespace App\Services\Business\KuaiTuanTuan; class FaceSheet extends KuaiTuanTuan { + protected $clientId = '24f25877aca447c5830a6aa896301d5e'; + protected $clientSecret = '59b6f4bd402c6423878a8f4ef1bde28359c1f05a'; + protected $redirectUri = 'http://erp.chutang66.com/pdd/ship'; + + public function __construct() + { + } + + public function getAuthUrl($shopId, $platId) + { + $state = $shopId . '_' . $platId; + + return "https://wb.pinduoduo.com/logistics/auth?client_id={$this->clientId}&redirect_uri={$this->redirectUri}&state={$state}"; + } + /** * 快递公司查看接口 * @@ -17,6 +32,55 @@ class FaceSheet extends KuaiTuanTuan return $this->doRequest($type, $appendParams); } + public function getWayBill() + { + $type = 'pdd.waybill.get'; + $appendParams = [ + 'param_waybill_cloud_print_apply_new_request' => [ + 'sender' => [ + 'address' => [ + 'city' => '昆明市', + 'country' => '中国', + 'detail' => '肖家营花卉市场1期-3', + 'district' => '官渡区', + 'province' => '云南省', + ], + 'name' => '赵先生', + 'mobile' => '13093715108', + ], + 'trade_order_info_dtos' => [[ + 'object_id' => 'SF_' . time(), + 'order_info' => [ + 'order_channels_type' => 'PDD', + 'trade_order_list' => ['PO-230712-007140873850822'] + ], + 'package_info' => [ + 'items' => [[ + 'count' => 1, + 'name' => '花落花卉', + ]] + ], + 'recipient' => [ + 'address' => [ + 'city' => '成都市', + 'detail' => '河之洲3期6栋2单元', + 'district' => '崇州市', + 'province' => '四川省', + ], + 'name' => '吕鸶', + 'mobile' => '13194975115' + ], + 'template_url' => 'https://file-link.pinduoduo.com/sf_one', + 'user_id' => '2256799818137902', + ]], + 'wp_code' => 'SF', + ] + ]; + $appendParams['param_waybill_cloud_print_apply_new_request'] = json_encode($appendParams['param_waybill_cloud_print_apply_new_request'], 256); + + return $this->doRequest($type, $appendParams); + } + /** * searchWayBill * @@ -38,9 +102,19 @@ class FaceSheet extends KuaiTuanTuan return $this->doRequest($type, $appendParams); } - public function test() + public function getStdTemplates() { $type = 'pdd.cloudprint.stdtemplates.get'; + $appendParams = [ + 'wp_code' => 'SF' + ]; + + return $this->doRequest($type, $appendParams); + } + + public function getCustomares() + { + $type = 'pdd.cloudprint.customares.get'; $appendParams = []; return $this->doRequest($type, $appendParams); diff --git a/app/Services/Business/KuaiTuanTuan/KuaiTuanTuan.php b/app/Services/Business/KuaiTuanTuan/KuaiTuanTuan.php index 5fd3864..191d081 100644 --- a/app/Services/Business/KuaiTuanTuan/KuaiTuanTuan.php +++ b/app/Services/Business/KuaiTuanTuan/KuaiTuanTuan.php @@ -5,6 +5,8 @@ namespace App\Services\Business\KuaiTuanTuan; use App\Models\BusinessGoodsSku; use App\Models\GoodsSku; use App\Models\GroupGoods; +use App\Models\Shop; +use App\Models\ShopShip; use App\Services\Business\BusinessClient; use App\Models\Groups as GroupsModel; use Illuminate\Support\Facades\Log; @@ -29,13 +31,22 @@ class KuaiTuanTuan extends BusinessClient 'sign' => '' ]; - public function auth() + public function auth($type = 'ktt') { $accessToken = $this->getAccessTokenWithCode(); $accessToken['scope'] = json_encode($accessToken['scope'], 256); - $accessToken['pop_auth_token_create_response'] = json_encode($accessToken, 256); - $accessToken['status'] = 1; - $this->shop->update($accessToken); + $accessToken['status'] = Shop::$STATUS_AUTHORIZED; + if ('ktt' === $type) { + $accessToken['pop_auth_token_create_response'] = json_encode($accessToken, 256); + $this->shop->update($accessToken); + } + if ('ship' === $type) { + ShopShip::query()->updateOrCreate( + ['shop_id' => $this->shop->id], + $accessToken + ); + $this->shop->update($accessToken); + } return $this->shop; } diff --git a/app/Services/PrintModule/Pdd/Ktt.php b/app/Services/PrintModule/Pdd/Ktt.php deleted file mode 100644 index 34c5752..0000000 --- a/app/Services/PrintModule/Pdd/Ktt.php +++ /dev/null @@ -1,63 +0,0 @@ -getAccessTokenWithCode($code); - LogFile::info('电子面单应用授权: ' . json_encode($accessToken, 256)); - } - - protected function getAccessTokenWithCode($code) - { - $type = 'pdd.pop.auth.token.create'; - $res = $this->doRequest($type, ['code' => $code]); - - return $res['pop_auth_token_create_response']; - } - - public function doRequest($type, $appendParams = [], $url = 'https://gw-api.pinduoduo.com/api/router') - { - $publicParams = [ - 'type' => $type, - 'client_id' => $this->clientId, - 'timestamp' => time() - ]; - $publicParams = array_merge($publicParams, $appendParams); - $publicParams['sign'] = $this->getSign($publicParams); - - return $this->formDataPostRequest($url, $publicParams); - } - - protected function getSign($params) - { - ksort($params); - $str = ''; - foreach ($params as $key => $val) { - $str .= $key . $val; - } - $str = $this->clientSecret . $str . $this->clientSecret; - - return strtoupper(md5($str)); - } - - protected function formDataPostRequest($url, $params) - { - $method = 'POST'; - $headers = [ - 'headers' => ['Content-type' => 'application/x-www-form-urlencoded;charset=UTF-8'], - 'form_params' => $params - ]; - $res = (new Client())->request($method, $url, $headers); - return json_decode($res->getBody()->getContents(), true); - } -} diff --git a/database/migrations/2023_07_15_114522_create_shop_ships_table.php b/database/migrations/2023_07_15_114522_create_shop_ships_table.php new file mode 100644 index 0000000..9996632 --- /dev/null +++ b/database/migrations/2023_07_15_114522_create_shop_ships_table.php @@ -0,0 +1,45 @@ +bigIncrements('id'); + $table->integer('shop_id'); + $table->string('access_token'); + $table->unsignedBigInteger('expires_at')->comment('access_token过期时间点'); + $table->unsignedInteger('expires_in')->comment('access_token过期时间段,10(表示10秒后过期)'); + $table->string('owner_id')->comment('商家店铺id'); + $table->string('owner_name')->comment('商家账号名称'); + $table->string('refresh_token')->comment('refresh token,可用来刷新access_token'); + $table->unsignedBigInteger('refresh_token_expires_at')->comment('Refresh token过期时间点'); + $table->unsignedInteger('refresh_token_expires_in')->comment('refresh_token过期时间段,10表示10秒后过期'); + $table->text('scope')->comment('接口列表'); + $table->tinyInteger('status')->default(0); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('shop_ships'); + } +} diff --git a/resources/frontend/src/api/shop.js b/resources/frontend/src/api/shop.js index 4b0a0fe..3b8fe53 100644 --- a/resources/frontend/src/api/shop.js +++ b/resources/frontend/src/api/shop.js @@ -49,3 +49,10 @@ export function syncStoreStock(params) { params, }); } + +export function shipList() { + return http({ + url: '/api/shop/ship', + method: 'get', + }) +} diff --git a/resources/frontend/src/router/list.js b/resources/frontend/src/router/list.js index b2cc417..985d783 100644 --- a/resources/frontend/src/router/list.js +++ b/resources/frontend/src/router/list.js @@ -1,107 +1,112 @@ const list = [ - { - path: "/Login", - name: "Login", - component: () => import("../views/Login.vue"), - }, - { - path: "/", - component: () => import("../views/index.vue"), - children: [ - { - path: "GOODS_LIST", - name: "商品列表", - component: () => import("../views/goods/goods.vue"), - meta: { - keepAlive: true, - }, - }, - { - path: "ADDGOODS", - name: "新建商品", - component: () => import("../views/goods/addgoods/addgoods.vue"), - }, - { - path: "EDIT_GOODS", - name: "修改商品规格", - component: () => import("../views/goods/editgoods.vue"), - }, - { + { + path: "/Login", + name: "Login", + component: () => import("../views/Login.vue"), + }, + { path: "/", - redirect: "GOODS_LIST", - }, - { - path: "GOODS_TYPE", - name: "商品种类", - component: () => import("../views/goodsType/goodsType.vue"), - }, - { - path: "GOODS_BRAND", - name: "商品品牌", - component: () => import("../views/brand/brand.vue"), - }, - { - path: "GOODS_SKU_LOCATION", - name: "商品货架", - component: () => import("../views/goods/location.vue"), - }, - { - path: "GOODS_COMBINATION", - name: "组合商品", - component: () => import("../views/goods/combination.vue"), - }, - { - path: "SHOP_MANAGE", - name: "店铺管理", - component: () => import("../views/store/store.vue"), - }, - { - path: "USER_MANAGE", - name: "用户管理", - component: () => import("../views/users/users.vue"), - }, - { - path: "ROLE_MANAGE", - name: "角色管理", - component: () => import("../views/system/role.vue"), - }, - { - path: "SYSTEM_LOG", - name: "系统日志", - component: () => import("../views/logs/logs.vue"), - }, - { - path: "GOODS_LOG", - name: "商品记录", - component: () => import("../views/logs/record.vue"), - }, - { - path: "PLAT_ORDER_LIST", - name: "订单列表", - component: () => import("../views/plat/orderList.vue"), - }, - { - path: "PLAT_GOODS_LIST", - name: "货品列表", - component: () => import("../views/plat/goodsList.vue"), - }, - { - path: "GROUP_MANAGEMENT", - name: "团购管理", - component: () => import("../views/group/group.vue"), - }, - { - path: "GROUP_GOODS_ADD", - name: "团购商品新增", - component: () => import("../views/group/addGroup.vue"), - }, - { - path: "GROUP_GOODS_EDIT", - name: "团购商品修改", - component: () => import("../views/group/editGroup.vue"), - }, - ], - }, + component: () => import("../views/index.vue"), + children: [ + { + path: "GOODS_LIST", + name: "商品列表", + component: () => import("../views/goods/goods.vue"), + meta: { + keepAlive: true, + }, + }, + { + path: "ADDGOODS", + name: "新建商品", + component: () => import("../views/goods/addgoods/addgoods.vue"), + }, + { + path: "EDIT_GOODS", + name: "修改商品规格", + component: () => import("../views/goods/editgoods.vue"), + }, + { + path: "/", + redirect: "GOODS_LIST", + }, + { + path: "GOODS_TYPE", + name: "商品种类", + component: () => import("../views/goodsType/goodsType.vue"), + }, + { + path: "GOODS_BRAND", + name: "商品品牌", + component: () => import("../views/brand/brand.vue"), + }, + { + path: "GOODS_SKU_LOCATION", + name: "商品货架", + component: () => import("../views/goods/location.vue"), + }, + { + path: "GOODS_COMBINATION", + name: "组合商品", + component: () => import("../views/goods/combination.vue"), + }, + { + path: "SHOP_MANAGE", + name: "店铺管理", + component: () => import("../views/store/store.vue"), + }, + { + path: "USER_MANAGE", + name: "用户管理", + component: () => import("../views/users/users.vue"), + }, + { + path: "ROLE_MANAGE", + name: "角色管理", + component: () => import("../views/system/role.vue"), + }, + { + path: "SYSTEM_LOG", + name: "系统日志", + component: () => import("../views/logs/logs.vue"), + }, + { + path: "GOODS_LOG", + name: "商品记录", + component: () => import("../views/logs/record.vue"), + }, + { + path: "PLAT_ORDER_LIST", + name: "订单列表", + component: () => import("../views/plat/orderList.vue"), + }, + { + path: "PLAT_GOODS_LIST", + name: "货品列表", + component: () => import("../views/plat/goodsList.vue"), + }, + { + path: "GROUP_MANAGEMENT", + name: "团购管理", + component: () => import("../views/group/group.vue"), + }, + { + path: "GROUP_GOODS_ADD", + name: "团购商品新增", + component: () => import("../views/group/addGroup.vue"), + }, + { + path: "GROUP_GOODS_EDIT", + name: "团购商品修改", + component: () => import("../views/group/editGroup.vue"), + }, + { + path: "FACE_SHEET", + name: "电子面单", + component: () => import("../views/plat/faceSheet.vue"), + }, + ], + }, ]; export default list; diff --git a/resources/frontend/src/views/goods/goods.vue b/resources/frontend/src/views/goods/goods.vue index 302c81b..f87a9c0 100644 --- a/resources/frontend/src/views/goods/goods.vue +++ b/resources/frontend/src/views/goods/goods.vue @@ -230,8 +230,8 @@
{{ scope.row.daily.inventory }} @@ -363,7 +363,7 @@
- 下载模板 + 下载模板
diff --git a/resources/frontend/src/views/index.vue b/resources/frontend/src/views/index.vue index 6fc0fbd..358e7d2 100644 --- a/resources/frontend/src/views/index.vue +++ b/resources/frontend/src/views/index.vue @@ -13,8 +13,8 @@ - {{ children.name }} + {{ + children.name }} @@ -37,7 +37,8 @@
  • -
    退出
    +
    {{ usernmae }}
    +
    登出
  • @@ -58,6 +59,7 @@ export default { getMenu().then((res) => { this.menu = res.data.data; }); + this.usernmae = localStorage.getItem('userName'); }, data() { return { @@ -68,6 +70,7 @@ export default { head: "", // 路由name onindex: 0, // 索引 openeds: ["GOODS_MANAGE"], + usernmae: '' }; }, watch: { diff --git a/resources/frontend/src/views/plat/faceSheet.vue b/resources/frontend/src/views/plat/faceSheet.vue new file mode 100644 index 0000000..4ced36b --- /dev/null +++ b/resources/frontend/src/views/plat/faceSheet.vue @@ -0,0 +1,63 @@ + + + + + diff --git a/resources/frontend/src/views/store/store.vue b/resources/frontend/src/views/store/store.vue index 819c07a..83edb0d 100644 --- a/resources/frontend/src/views/store/store.vue +++ b/resources/frontend/src/views/store/store.vue @@ -6,10 +6,11 @@
    - + +