Files
temu-plugin/src/view/shipping/ShippingDesk.vue
liushiwei 0808f42ce7 调整
2024-07-18 14:48:44 +08:00

640 lines
22 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div>
<ai-list class="list" v-loading="isLoading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading">
<ai-title
slot="title"
title="发货单管理"
tips="请先在当前浏览器登录“拼多多跨境卖家中心”,期间保持登录状态"
isShowBottomBorder>
</ai-title>
<template slot="content">
<ai-search-bar>
<template #left>
<el-dropdown @command="handleClick">
<el-button type="primary" :disabled="isBegin">添加备货单</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="byStore">按店铺添加</el-dropdown-item>
<el-dropdown-item command="loadAll">一键添加所有</el-dropdown-item>
</el-dropdown-menu>
<!--<el-button type="primary" :disabled="isBegin" @click="isShow = true">添加备货单</el-button>
<el-button type="primary" :disabled="isBegin" @click="loadAll">一键加载全部</el-button>-->
</el-dropdown>
<el-button v-if="!isBegin" type="button" :class="'el-button el-button--primary'" @click="beginCreateConfirm">开始创建</el-button>
<el-button v-else type="button" :icon="isBegin? 'el-icon-loading': ''" :class="isBegin ? 'el-button el-button--danger': 'el-button el-button--primary'" @click="beginCreate()">{{ `结束创建(${choosedList.length}/${createTotal})` }}</el-button>
</template>
</ai-search-bar>
<ai-table
:tableData="choosedList"
:col-configs="robColConfigs"
:total="total"
height="500"
:isShowPagination="false"
style="margin-top: 8px;">
<el-table-column slot="productName" width="480px" label="基本信息" align="center">
<template slot-scope="scope">
<div class="product">
<img :src="scope.row.subPurchaseOrderBasicVO.productSkcPicture">
<div class="right">
<div>备货母单号: {{ scope.row.subPurchaseOrderBasicVO.subPurchaseOrderSn }}</div>
<div>SKC: {{ scope.row.subPurchaseOrderBasicVO.productSkcId }}</div>
<div>货号: {{ scope.row.subPurchaseOrderBasicVO.skcExtCode }}</div>
</div>
</div>
</template>
</el-table-column>
<el-table-column slot="subWarehouseName" width="180px" label="收货仓库" align="center">
<template slot-scope="scope">
{{ scope.row.subPurchaseOrderBasicVO.subWarehouseName }}
</template>
</el-table-column>
<el-table-column slot="purchaseTime" width="180px" label="下单时间" align="center">
<template slot-scope="scope">
{{ formatTime(scope.row.subPurchaseOrderBasicVO.purchaseTime) }}
</template>
</el-table-column>
<el-table-column slot="className" label="SKU信息" width="440px" show-overflow-tooltip align="center">
<template slot-scope="scope">
<div class="order-manage_skuInfo__FW-Nd" v-for="(item, index) in scope.row.orderDetailVOList" :key="index">
<div>
<div data-testid="beast-core-box" class="outerWrapper-1-3-1 outerWrapper-d18-1-3-20 index-module__image-preview___2fiZX">
<div class="index-module__img___p3B1N" :style="getStyle(item.productSkuImgUrlList[0])"></div>
</div>
</div>
<div class="order-manage_contentInfo__1Cjd6">
<div>属性集{{ item.color + ' ' + item.size}}</div>
<div>待发货数/最大发货数(){{ item.productSkuPurchaseQuantity }} / {{ item.skuDeliveryQuantityMaxLimit }}</div>
<div>SKU ID {{ item.productSkuId }}</div>
</div>
</div>
</template>
</el-table-column>
<el-table-column slot="options" label="操作" width="80px" v-if="!isBegin" show-overflow-tooltip align="center" fixed="right">
<template slot-scope="{ row }">
<div class="table-options">
<el-button type="text" @click="remove(row.subPurchaseOrderBasicVO.subPurchaseOrderSn)">移除</el-button>
</div>
</template>
</el-table-column>
</ai-table>
<AiDialog
title="添加备货单"
:visible.sync="isShow"
:close-on-click-modal="false"
customFooter
@confirm="onConfirm"
width="1290px">
<label style="width:90px">店铺</label>
<el-select v-model="mallId" placeholder="请选择" @change="mallChange">
<el-option
v-for="item in mallList"
:key="item.mallId"
:label="item.mallName"
:value="item.mallId">
{{ item.mallName }}
</el-option>
</el-select>
<ai-table
:tableData="tableData"
:col-configs="colConfigs"
:total="total"
:isShowPagination="false"
style="margin-top: 8px;"
v-loading="isDlgLoading"
@selection-change="onChooseChange">
<el-table-column slot="productName" width="480px" label="基本信息" align="center">
<template slot-scope="scope">
<div class="product">
<img :src="scope.row.subPurchaseOrderBasicVO.productSkcPicture">
<div class="right">
<div>备货母单号: {{ scope.row.subPurchaseOrderBasicVO.subPurchaseOrderSn }}</div>
<div>SKC: {{ scope.row.subPurchaseOrderBasicVO.productSkcId }}</div>
<div>货号: {{ scope.row.subPurchaseOrderBasicVO.skcExtCode }}</div>
</div>
</div>
</template>
</el-table-column>
<el-table-column slot="subWarehouseName" width="180px" label="收货仓库" align="center">
<template slot-scope="scope">
{{ scope.row.subPurchaseOrderBasicVO.subWarehouseName }}
</template>
</el-table-column>
<el-table-column slot="purchaseTime" width="180px" label="下单时间" align="center">
<template slot-scope="scope">
{{ formatTime(scope.row.subPurchaseOrderBasicVO.purchaseTime) }}
</template>
</el-table-column>
<el-table-column slot="className" label="SKU信息" width="440px" show-overflow-tooltip align="center">
<template slot-scope="scope">
<div class="order-manage_skuInfo__FW-Nd" v-for="(item, index) in scope.row.orderDetailVOList" :key="index">
<div>
<div data-testid="beast-core-box" class="outerWrapper-1-3-1 outerWrapper-d18-1-3-20 index-module__image-preview___2fiZX">
<div class="index-module__img___p3B1N" :style="getStyle(item.productSkuImgUrlList[0])"></div>
</div>
</div>
<div class="order-manage_contentInfo__1Cjd6">
<div>属性集{{ item.color + ' ' + item.size}}</div>
<div>待发货数/最大发货数(){{ item.productSkuPurchaseQuantity }} / {{ item.skuDeliveryQuantityMaxLimit }}</div>
<div>SKU ID {{ item.productSkuId }}</div>
</div>
</div>
</template>
</el-table-column>
</ai-table>
<span slot="footer" class="dialog-footer">
<el-button @click="isShow = false"> </el-button>
<el-button type="primary" @click="onConfirm">添加</el-button>
</span>
</AiDialog>
<AiDialog
title="创建发货单设置"
:visible.sync="createDlgShow"
:close-on-click-modal="false"
customFooter
height="500px"
width="700px">
<el-form :model="robForm" ref="robForm" label-width="180px" class="form">
<el-form-item
prop="isModifyMaxNum"
label="是否修改为最大发货数:"
:rules="[{ required: true, message: '请选择是否修改为最大发货数', trigger: 'blur' }]">
<el-radio-group v-model="robForm.isModifyMaxNum" size="medium">
<el-radio :label="false"></el-radio>
<el-radio :label="true"></el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="createDlgShow = false"> </el-button>
<el-button type="primary" @click="beforeBegin"> </el-button>
</span>
</AiDialog>
</template>
</ai-list>
</div>
</template>
<script>
import { mapState } from 'vuex'
import {sendChromeAPIMessage} from '@/api/chromeApi'
import { Message } from 'element-ui'
import {timestampToTime} from '@/utils/date'
export default {
name: 'ShippingDesk',
data () {
return {
isShow: false,
colConfigs: [
{ type: "selection", width: '70px', align: 'left' },
{ slot: 'productName' },
{ slot: 'subWarehouseName'},
{ prop: 'mallName', label: '店铺来源', align: 'center' },
{ slot: 'className'},
{ slot: 'purchaseTime'}
],
robColConfigs: [
{ slot: 'productName' },
{ slot: 'subWarehouseName'},
{ prop: 'mallName', label: '店铺来源', align: 'center' },
{ slot: 'className'},
{ slot: 'purchaseTime'}
],
mallId: '',
mallName: '',
tableData: [],
total: 0,
isBegin: false,
choosedList: [],
choosedSnMallList: [],
arr: [],
createTotal: 0,
pageSize: 100,
currentPage: 1,
robForm: {
isModifyMaxNum: false
},
loadMallIndex: 0,
loadMode: 0, // 加载模式0表示单个店铺加载1表示一键加载
// 加载数据
isLoading: false,
isDlgLoading: false,
createDlgShow: false,
addressList: []
}
},
computed: {
...mapState(['mallList'])
},
created () {
this.toGetAddressInfo();
},
methods: {
onChooseChange (e) {
this.arr = e
},
mallChange() {
this.$userCheck(this.mallId).then(() => {
let mallInfo = this.mallList.filter(item => {
return item.mallId == this.mallId
})
this.mallName = mallInfo[0].mallName
// 下载数据
this.loadMode = 0
this.tableData = []
this.currentPage = 1
this.isDlgLoading = true
this.getList(this.tableData, this.mallId, this.mallName, 1)
}).catch((err) => {
this.mallId = ''
console.log(err)
})
},
toGetAddressInfo() {
this.addressList = []
this.getAddressInfo()
},
async getAddressInfo() {
if (!this.mallList) {
Message.error('获取默认发货地址失败,请刷新重试')
return
}
for (let index = 0; index < this.mallList.length; index++) {
let mallInfo = this.mallList[index]
while(true) {
let res = await sendChromeAPIMessage({
url: 'bgSongbird-api/supplier/address/queryDeliveryAddressInfo',
needMallId: true,
mallId: mallInfo.mallId,
data: {}})
if (res.errorCode == 1000000) {
let addressArr = res.result.deliveryAddressInfoList.filter(i => {
return i.isDefault
})
if (addressArr.length > 0) {
this.addressList.push({
mallId: mallInfo.mallId,
addressId: addressArr[0].id
})
} else {
Message.error("店铺【" + mallInfo.mallName + "】未设置默认发货地址,将无法自动创建发货单")
}
break
}
}
}
},
onConfirm () {
if (this.arr.length == 0) {
Message.error("请选择备货单")
return
}
console.log(this.arr)
this.arr.map(item => {
let temp = this.choosedList.filter(i => {
return i.subPurchaseOrderBasicVO?.subPurchaseOrderSn == item.subPurchaseOrderBasicVO.subPurchaseOrderSn
})
console.log(temp)
if (temp.length == 0) {
this.choosedList.push(item)
console.log(this.choosedList)
}
})
Message.success("添加成功,可继续添加")
},
loadAll() {
this.$userCheck().then(() => {
this.choosedList = []
this.currentPage = 1
this.isLoading = true
if (this.$store.state.userInfo.type == 3) {
this.loadMode = 0
this.getList(this.choosedList, this.$store.state.mallId, this.$store.state.mallName, 1)
} else {
this.loadMallIndex = 0
this.loadMode = 1
this.getList(this.choosedList, this.mallList[this.loadMallIndex].mallId, this.mallList[this.loadMallIndex].mallName, 1)
}
});
},
handleClick (e) {
if (e === 'byStore') {
this.isShow = true
} else if (e === 'loadAll') {
this.loadAll()
}
},
beginCreateConfirm() {
if (this.choosedList.length <= 0) {
Message.error('请先添加备货单');
return;
}
this.createDlgShow = true
},
beforeBegin() {
this.$refs.robForm.validate((valid) => {
if (valid) {
this.createDlgShow = false
this.beginCreate()
}
})
},
getList (data, mallId, mallName, currentPage) {
sendChromeAPIMessage({
url: 'bgSongbird-api/supplier/deliverGoods/platform/pageQuerySubPurchaseOrder',
needMallId: true,
anti: true,
mallId: mallId,
data: {
"pageNo": currentPage,
"pageSize": 100
}}).then((res) => {
if (res.errorCode == 1000000) {
res.result.list.map((item) => {
data.push({...item, mallId: mallId, mallName: mallName})
})
if (this.pageSize == length) {
currentPage ++
this.getList(data, mallId, mallName, currentPage)
} else {
if (this.loadMode == 1) {
this.loadMallIndex ++
if (this.loadMallIndex < this.mallList.length) {
this.getList(data, this.mallList[this.loadMallIndex].mallId, this.mallList[this.loadMallIndex].mallName, 1)
} else {
this.isLoading = false
this.isDlgLoading = false
Message.success("所有店铺备货单已加载完成")
}
} else {
this.isLoading = false
this.isDlgLoading = false
}
}
} else {
this.getList(data, mallId, mallName, currentPage)
}
})
},
remove(sn) {
for (let i = 0; i < this.choosedList.length; i++) {
if (this.choosedList[i].subPurchaseOrderBasicVO.subPurchaseOrderSn == sn) {
this.choosedList.splice(i, 1)
break
}
}
},
getStyle(url) {
return "background-image: url(" + url + "); width: 72px; height: 72px; cursor: pointer; border-radius: 6px; border: 1px solid rgba(0, 0, 0, 0.14);";
},
beginCreate() {
if (this.isBegin) {
this.isBegin = false;
return;
}
this.createTotal = this.choosedList.length
this.isBegin = true;
this.choosedList.map((data, index) => {
let deliverOrderDetailInfos = data.orderDetailVOList.map(item => {
if (this.robForm.isModifyMaxNum) {
return {
productSkuId: item.productSkuId,
deliverSkuNum: item.skuDeliveryQuantityMaxLimit
}
} else {
return {
productSkuId: item.productSkuId,
deliverSkuNum: item.productSkuPurchaseQuantity
}
}
})
let packageInfos = []
data.orderDetailVOList.map(item => {
let packageDetailSaveInfos = []
if (this.robForm.isModifyMaxNum) {
packageDetailSaveInfos.push({
productSkuId: item.productSkuId,
skuNum: item.skuDeliveryQuantityMaxLimit
})
} else {
packageDetailSaveInfos.push({
productSkuId: item.productSkuId,
skuNum: item.productSkuPurchaseQuantity
})
}
packageInfos.push({packageDetailSaveInfos: packageDetailSaveInfos})
})
let addressInfo = this.addressList.filter(k => {
return k.mallId == data.mallId
})
let deliveryOrderCreateInfos = []
deliveryOrderCreateInfos.push({
deliverOrderDetailInfos: deliverOrderDetailInfos,
subPurchaseOrderSn: data.subPurchaseOrderBasicVO.subPurchaseOrderSn,
deliveryAddressId: addressInfo[0].addressId,
packageInfos: packageInfos
})
let deliveryOrderCreateGroupList = []
deliveryOrderCreateGroupList.push({
deliveryOrderCreateInfos: deliveryOrderCreateInfos,
receiveAddressInfo: data.subPurchaseOrderBasicVO.receiveAddressInfo,
subWarehouseId: data.subPurchaseOrderBasicVO.subWarehouseId
})
setTimeout(() => {
this.createDeliveryOrder(data.mallId, data.subPurchaseOrderBasicVO.subPurchaseOrderSn, deliveryOrderCreateGroupList)
}, index * 100)
})
let _this = this;
let tt = setInterval(function() {
if (_this.choosedList.length == 0) {
_this.isBegin = false;
clearInterval(tt);
}
}, 1000)
},
createDeliveryOrder(mallId, sn, data) {
sendChromeAPIMessage({
url: 'bgSongbird-api/supplier/deliverGoods/platform/createDeliveryOrderGroupSimpleByAddress',
needMallId: true,
anti: true,
mallId: mallId,
data: {deliveryOrderCreateGroupList: data}}).then((res) => {
if (res.errorCode == 1000000) {
for (let j = 0; j < this.choosedList.length; j++) {
if (this.choosedList[j].subPurchaseOrderBasicVO.subPurchaseOrderSn == sn) {
this.choosedList.splice(j, 1);
break;
}
}
} else {
setTimeout(() => { this.createDeliveryOrder(mallId, sn, data)}, 1000)
}
})
},
formatTime(time) {
return timestampToTime(time)
}
}
}
</script>
<style scoped lang="scss">
.product {
display: flex;
align-items: center;
justify-content: center;
.right {
flex: 1;
text-align: left;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
img {
width: 60px;
margin-right: 10px;
}
}
.tips {
position: relative;
width: 40px;
height: 40px;
border-radius: 50%;
background: rgba(243, 8, 8, .4);
@keyframes warn {
0% {
transform: translate(-50%, -50%) scale(0);
opacity: 1;
}
100% {
transform: translate(-50%, -50%) scale(1.1);
opacity: 0;
}
}
div {
position: absolute;
left: 50%;
top: 50%;
z-index: 11;
width: 100px;
height: 100px;
border-radius: 50%;
animation: warn 0.9s ease-out;
animation-iteration-count: infinite;
box-shadow: 1px 1px 30px #EF2D02;
transform: translate(-50%, -50%) scale(0.2);
transition: all ease-in-out 0.6s;
background: rgba(243, 8, 8, .6);
}
}
.order-manage_productInfo__1pD83>img {
width: 60px;
margin-right: 10px;
}
.order-manage_productInfo__1pD83 {
min-height: 60px;
padding-left: 70px;
position: relative;
}
.order-manage_productInfo__1pD83>div:nth-child(2) {
color: rgba(0,0,0,.8);
}
.outerWrapper {
margin: 4px 4px 0px 0px;
}
.dot-module__dot___M-RuH .dot-module__circle___2l2UV {
flex-shrink: 0;
width: 8px;
height: 8px;
border-radius: 50%;
margin-right: 8px;
}
.dot-module__dot___M-RuH {
display: inline-flex;
align-items: center;
}
.index-module__image-preview___2fiZX .index-module__img___p3B1N {
width: 60px;
height: 60px;
margin-right: 10px;
background-repeat: no-repeat;
background-size: cover;
background-color: #f5f5f5;
font-size: 12px;
display: flex;
justify-content: center;
align-items: center;
color: var(--bc-Table-emptyTextColor);
position: relative;
}
.textoverflow {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
cursor: pointer;
}
.order-manage_skuInfo__FW-Nd {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 10px;
&:last-child {
margin-bottom: 0;
}
.order-manage_contentInfo__1Cjd6 {
display: flex;
flex-direction: column;
text-align: left;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 240px;
}
}
.order-manage_skuInfo__FW-Nd .order-manage_contentInfo__1Cjd6 .order-manage_title__1VTO5 {
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
color: rgba(0,0,0,.8);
}
</style>