This commit is contained in:
赵世界 2023-08-22 15:26:34 +08:00
parent c342859b37
commit c221f8f9ae
17 changed files with 197 additions and 91 deletions

View File

@ -7,7 +7,6 @@ use App\Http\Resources\ShopsResource;
use App\Models\Shop;
use App\Models\ShopSender;
use App\Models\ShopShip;
use App\Services\Business\KuaiTuanTuan\FaceSheet;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
@ -15,25 +14,18 @@ class ShipController extends Controller
{
public function index(Request $request)
{
$shops = Shop::query()
->select(['id', 'name', 'plat_id'])
->with('ship')
->where('plat_id', 1)
$shopShips = ShopShip::query()
->select(['id', 'type', 'shop_id', 'expires_at', 'owner_id', 'owner_name'])
->with('shop:id,name')
->get();
$time = date('Y-m-d H:i:s');
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]);
}
foreach ($shopShips as $shopShip) {
if ($shopShip->expires_at && $time >= $shopShip->expires_at) {
ShopShip::query()->where('shop_id', $shopShip->shop_id)->update(['status' => Shop::$STATUS_UNAUTHORIZED]);
}
}
return ShopsResource::collection($shops);
return ShopsResource::collection($shopShips);
}
public function getSenders(Request $request)

View File

@ -8,7 +8,6 @@ use App\Models\GoodsSku;
use App\Models\Shop;
use App\Http\Resources\ShopsResource;
use App\Models\ShopSender;
use App\Models\ShopShip;
use App\Services\Business\KuaiTuanTuan\FaceSheet;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
@ -227,18 +226,11 @@ class ShopsController extends Controller
public function pddPrintAuth(Request $request)
{
[$shopId, $platId] = explode('_', $request->get('state'));
[$shopId, $type] = explode('_', $request->get('state'));
$faceSheet = new FaceSheet();
$faceSheet->setCode($request->get('code'));
$faceSheet->setShopWithId($shopId);
$faceSheet->auth('ship');
$shopShip = ShopShip::query()
->where('shop_id', $shopId)
->first();
if (empty($shopShip)) {
exit();
}
$faceSheet->setShop($shopShip);
$shopShip = $faceSheet->auth('ship', $type);
$resp = $faceSheet->searchWayBill();
if (!isset($resp['pdd_waybill_search_response']['waybill_apply_subscription_cols'])) {
exit();

View File

@ -8,7 +8,7 @@ class ShopShip extends Model
{
protected $guarded = [];
protected function shop()
public function shop()
{
return $this->belongsTo(Shop::class, 'shop_id', 'id');
}
@ -32,6 +32,16 @@ class ShopShip extends Model
return $value ? date('Y-m-d H:i:s', $value) : '';
}
public function getTypeAttribute($value)
{
$map = [
'normal' => '电商标快',
'air' => '空运',
];
return $map[$value];
}
public function senders()
{
return $this->hasMany(ShopSender::class, 'shop_ship_id');

View File

@ -31,7 +31,7 @@ class KuaiTuanTuan extends BusinessClient
'sign' => ''
];
public function auth($type = 'ktt')
public function auth($type = 'ktt', $shipType = 'normal')
{
$accessToken = $this->getAccessTokenWithCode();
$accessToken['scope'] = json_encode($accessToken['scope'], 256);
@ -42,8 +42,8 @@ class KuaiTuanTuan extends BusinessClient
}
if ('ship' === $type) {
unset($accessToken['r1_expires_at'], $accessToken['r1_expires_in'], $accessToken['r2_expires_at'], $accessToken['r2_expires_in'], $accessToken['w1_expires_at'], $accessToken['w1_expires_in'], $accessToken['w2_expires_at'], $accessToken['w2_expires_in'], $accessToken['request_id']);
ShopShip::query()->updateOrCreate(
['shop_id' => $this->shop->id],
$this->shop = ShopShip::query()->updateOrCreate(
['shop_id' => $this->shop->id, 'type' => $shipType],
$accessToken
);
}

View File

@ -29,12 +29,15 @@ class WayBillService
$contents = [];
foreach ($this->orders as $shopId => $order) {
// 订单取消的情况暂不处理
$shop = $this->getShop($shopId);
$faceSheet = new FaceSheet();
$faceSheet->setShop($shop);
foreach ($order as $item) {
[$sender, $orderInfo, $wpCode] = $this->prepareRequest($item, $shop);
$waybill = $this->saveWayBill($item, $shop);
$packageInfoItems = $this->getPackageInfoItems($item);
$this->getTimedDelivery($item);
$faceSheet = new FaceSheet();
$shopShip = $this->getShopShip($shopId);
$faceSheet->setShop($shopShip);
[$sender, $orderInfo, $wpCode] = $this->prepareRequest($item, $shopShip, $packageInfoItems);
$waybill = $this->saveWayBill($item, $shopShip);
if (empty($waybill->id)) {
$resp = $faceSheet->getWayBill($sender, $orderInfo, $wpCode);
@ -146,11 +149,12 @@ class WayBillService
$waybill->participate_no = $order['participate_no'];
$waybill->note = $order['note'];
$waybill->items = json_encode($order['items'], 256);
$waybill->code = $this->timedDeliveryCode;
return $waybill;
}
private function timedDelivery($order)
private function getTimedDelivery($orderItem)
{
$this->timedDeliveryCode = Waybill::$BUSINESS_EXPRESS_CODE;
$address = [
@ -166,34 +170,18 @@ class WayBillService
'西宁市', '海东市', '海北藏族自治州', '黄南藏族自治州', '海南藏族自治州', '玉树藏族自治州'
],
];
if (isset($address[$order['recipient_province']])) {
if (empty($address[$order['recipient_province']])) {
if (isset($address[$orderItem['recipient_province']])) {
if (empty($address[$orderItem['recipient_province']])) {
$this->timedDeliveryCode = Waybill::$AIR_FREIGHT_CODE;
}
if ($address[$order['recipient_province']] && in_array($order['recipient_city'], $address[$order['recipient_province']], true)) {
if ($address[$orderItem['recipient_province']] && in_array($orderItem['recipient_city'], $address[$orderItem['recipient_province']], true)) {
$this->timedDeliveryCode = Waybill::$AIR_FREIGHT_CODE;
}
}
}
private function prepareRequest($order, $shop)
private function getPackageInfoItems($order)
{
$this->timedDelivery($order);
$senderConfig = $shop->senders[0];
$sender = [
'address' => [
'city' => $senderConfig['city'],
'country' => $senderConfig['country'],
'detail' => $senderConfig['detail'],
'district' => $senderConfig['district'],
'province' => $senderConfig['province'],
],
'name' => $senderConfig['name'],
'mobile' => $senderConfig['mobile'],
];
$this->setObjectId();
$items = [];
foreach ($order['items'] as $item) {
if ($item['should_print']) {
@ -209,6 +197,26 @@ class WayBillService
}
}
return $items;
}
private function prepareRequest($order, $shopShip, $packageInfoItems)
{
$senderConfig = $shopShip->senders[0];
$sender = [
'address' => [
'city' => $senderConfig['city'],
'country' => $senderConfig['country'],
'detail' => $senderConfig['detail'],
'district' => $senderConfig['district'],
'province' => $senderConfig['province'],
],
'name' => $senderConfig['name'],
'mobile' => $senderConfig['mobile'],
];
$this->setObjectId();
$orderInfo = [
'logistics_services' => [
'TIMED-DELIVERY' => [
@ -221,7 +229,7 @@ class WayBillService
'trade_order_list' => [$order['order_sn']],
],
'package_info' => [
'items' => $items,
'items' => $packageInfoItems,
],
'recipient' => [
'address' => [
@ -234,7 +242,7 @@ class WayBillService
'mobile' => $order['recipient_mobile'],
],
'template_url' => $this->sfOne,
'user_id' => $shop->owner_id,
'user_id' => $shopShip->owner_id,
];
return [$sender, $orderInfo, $senderConfig['wp_code']];
@ -329,11 +337,14 @@ class WayBillService
return $this;
}
private function getShop($shopId)
private function getShopShip($shopId)
{
$type = $this->timedDeliveryCode === Waybill::$AIR_FREIGHT_CODE ? 'air' : 'normal';
return ShopShip::query()
->select(['id', 'shop_id', 'access_token', 'owner_id'])
->where('shop_id', $shopId)
->where('type', $type)
->with([
'senders' => function ($query) {
$query->orderBy('sort')->first();

View File

@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddTypeToShopShipsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
if (Schema::hasColumns('shop_ships', ['type'])) {
return;
}
Schema::table('shop_ships', function (Blueprint $table) {
$table->string('type')->default('normal')->comment('账户类型normal-普通,air-空运');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('shop_ships', function (Blueprint $table) {
$table->dropColumn(['type']);
});
}
}

View File

@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddCodeToWaybillsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
if (Schema::hasColumns('waybills', ['code'])) {
return;
}
Schema::table('waybills', function (Blueprint $table) {
$table->integer('code')->default(247)->comment('247-电商标快,266-空运');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('waybills', function (Blueprint $table) {
$table->dropColumn(['code']);
});
}
}

View File

@ -1 +1 @@
#nprogress{pointer-events:none}#nprogress .bar{background:#29d;position:fixed;z-index:1031;top:0;left:0;width:100%;height:2px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px #29d,0 0 5px #29d;opacity:1;transform:rotate(3deg) translateY(-4px)}#nprogress .spinner{display:block;position:fixed;z-index:1031;top:15px;right:15px}#nprogress .spinner-icon{width:18px;height:18px;box-sizing:border-box;border:2px solid transparent;border-top-color:#29d;border-left-color:#29d;border-radius:50%;animation:nprogress-spinner .4s linear infinite}.nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent #nprogress .bar,.nprogress-custom-parent #nprogress .spinner{position:absolute}@keyframes nprogress-spinner{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}a[data-v-5959e012]{text-decoration:none;color:#fff}.block[data-v-5959e012]{margin-top:20px}
#nprogress{pointer-events:none}#nprogress .bar{background:#29d;position:fixed;z-index:1031;top:0;left:0;width:100%;height:2px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px #29d,0 0 5px #29d;opacity:1;transform:rotate(3deg) translateY(-4px)}#nprogress .spinner{display:block;position:fixed;z-index:1031;top:15px;right:15px}#nprogress .spinner-icon{width:18px;height:18px;box-sizing:border-box;border:2px solid transparent;border-top-color:#29d;border-left-color:#29d;border-radius:50%;animation:nprogress-spinner .4s linear infinite}.nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent #nprogress .bar,.nprogress-custom-parent #nprogress .spinner{position:absolute}@keyframes nprogress-spinner{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}a[data-v-e84f6478]{text-decoration:none;color:#fff}.block[data-v-e84f6478]{margin-top:20px}

View File

@ -1 +1 @@
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>erp</title><script defer="defer" src="js/chunk-vendors.9dd0c7db.js"></script><script defer="defer" src="js/app.d75564d8.js"></script><link href="css/chunk-vendors.4e2d36cb.css" rel="stylesheet"><link href="css/app.487f8f5a.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but erp doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>erp</title><script defer="defer" src="js/chunk-vendors.9dd0c7db.js"></script><script defer="defer" src="js/app.65f96f26.js"></script><link href="css/chunk-vendors.4e2d36cb.css" rel="stylesheet"><link href="css/app.487f8f5a.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but erp doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>

4
public/dist/js/107.4ae2ec64.js vendored Normal file

File diff suppressed because one or more lines are too long

1
public/dist/js/107.4ae2ec64.js.map vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
public/dist/js/app.65f96f26.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,33 +1,44 @@
<template>
<div class="conent">
<div>
<el-button type="primary" @click="addAuthVisible = true">新增授权</el-button>
</div>
<div class="table" style="margin-top: 10px">
<el-table v-loading="loading" :data="tableData" style="width: 100%">
<el-table-column prop="name" label="店铺名称"></el-table-column>
<el-table-column prop="ship.expires_at" label="授权过期时间点"></el-table-column>
<el-table-column prop="ship.owner_id" label="商家店铺id"></el-table-column>
<el-table-column prop="ship.owner_name" label="商家账号名称"></el-table-column>
<el-table-column prop="shop.name" label="店铺名称"></el-table-column>
<el-table-column prop="type" label="账户类型"></el-table-column>
<el-table-column prop="expires_at" label="授权过期时间点"></el-table-column>
<el-table-column prop="owner_id" label="商家店铺id"></el-table-column>
<el-table-column prop="owner_name" label="商家账号名称"></el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button type="danger" v-if="scope.row.status === '未授权'" size="small">
<a :href="scope.row.authUrl" target="_blank" rel="noopener noreferrer">授权</a>
</el-button>
<template v-if="scope.row.status === '已授权'">
<el-button type="success" :disabled="true" size="small">{{ scope.row.status }}</el-button>
</template>
<template v-if="scope.row.status === '重新授权'">
<el-button type="danger" target="_blank" size="small">
<a :href="scope.row.authUrl" rel="noopener noreferrer">重新授权</a>
</el-button>
</template>
<el-button v-if="scope.row.ship" type="info" @click="getSenders(scope.row)"
size="small">发货信息</el-button>
<el-button type="info" @click="getSenders(scope.row)" size="small">发货信息</el-button>
</template>
</el-table-column>
</el-table>
</div>
<!-- 新增授权 -->
<el-dialog title="新增授权" :visible.sync="addAuthVisible" :close-on-click-modal="false" width="20%">
<el-form :model="authForm" label-width="80px">
<el-form-item label="店铺">
<el-select v-model="authForm.shop_id" placeholder="请选择店铺">
<el-option v-for="item in shops" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="账户类型">
<el-radio-group v-model="authForm.type">
<el-radio label="normal">电商标快</el-radio>
<el-radio label="air">空运</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="authBtn()">授权</el-button>
</el-form-item>
</el-form>
</el-dialog>
<!-- 发货信息 -->
<el-dialog title="发货信息" :visible.sync="dialogVisible" :close-on-click-modal="false">
@ -62,7 +73,7 @@
</template>
<el-form-item>
<el-button type="primary" @click="saveSenders">保存</el-button>
<el-button type="primary" @click="saveSenders()">保存</el-button>
<el-button @click="dialogVisible = false">取消</el-button>
</el-form-item>
</el-form>
@ -71,7 +82,7 @@
</template>
<script>
import { shipList, ShopSenderList, saveSenders } from "../../api/shop";
import { shipList, ShopSenderList, saveSenders, storeList } from "../../api/shop";
export default {
data() {
return {
@ -79,13 +90,20 @@ export default {
loading: true,
tableData: [],
dialogVisible: false,
addAuthVisible: false,
sendersForm: {
senderList: []
},
shops: [],
authForm: {
shop_id: '',
type: 'normal'
}
};
},
mounted() {
this.getShipList();
this.getShopsList();
},
methods: {
getShipList() {
@ -95,7 +113,7 @@ export default {
this.loading = false
},
getSenders(row) {
ShopSenderList(row.id, row.ship.id).then((res) => {
ShopSenderList(row.shop_id, row.id).then((res) => {
this.sendersForm.senderList = res.data.data;
this.dialogVisible = true;
})
@ -108,6 +126,19 @@ export default {
this.$message.error(res.data.message);
}
})
},
getShopsList() {
let page = {
page: 0,
per_page: 999,
plat_id: 1,
};
storeList(page).then((res) => {
this.shops = res.data.data;
});
},
authBtn() {
location.href = "https://wb.pinduoduo.com/logistics/auth?client_id=24f25877aca447c5830a6aa896301d5e&redirect_uri=http://erp.chutang66.com/pdd/ship&state=" + this.authForm.shop_id + '_' + this.authForm.type;
}
},
};