'!'
This commit is contained in:
305
src/pages/goods-manager/childPages/right-main/right-main.scss
Normal file
305
src/pages/goods-manager/childPages/right-main/right-main.scss
Normal file
@@ -0,0 +1,305 @@
|
||||
.skuName-cell {
|
||||
box-sizing: border-box;
|
||||
background: white;
|
||||
padding: 19rpx;
|
||||
border-radius: 10rpx;
|
||||
margin: 15rpx 15rpx;
|
||||
box-shadow: 0rpx 2rpx 10rpx rgb(207, 207, 207);
|
||||
|
||||
|
||||
.skuName {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
position: relative;
|
||||
|
||||
.skuName-img {
|
||||
position: relative;
|
||||
|
||||
view {
|
||||
position: absolute;
|
||||
z-index: 9;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 182rpx;
|
||||
height: 182rpx;
|
||||
border-radius: 10rpx;
|
||||
background: rgba(0, 0, 0, .4);
|
||||
text-align: center;
|
||||
line-height: 182rpx;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.imglabel {
|
||||
width: 180rpx;
|
||||
height: 180rpx;
|
||||
border-radius: 10rpx;
|
||||
border: 1rpx solid rgb(218, 218, 218);
|
||||
}
|
||||
}
|
||||
|
||||
.skuName-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
margin-left: 17rpx;
|
||||
width: 100%;
|
||||
height: 180rpx;
|
||||
|
||||
.input-price {
|
||||
position: absolute;
|
||||
border: 1rpx solid rgba(0, 0, 0, 0.1);
|
||||
background: white;
|
||||
border-radius: 8rpx;
|
||||
padding: 20rpx;
|
||||
top: 60rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.skuName-name {
|
||||
color: #333;
|
||||
font-size: 32rpx;
|
||||
line-height: 1;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.skuName-monthsale {
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
line-height: 1;
|
||||
margin-top: 7rpx;
|
||||
}
|
||||
|
||||
.skuName-failsync {
|
||||
font-size: 28rpx;
|
||||
color: #F60D58;
|
||||
line-height: 1;
|
||||
margin-top: 7rpx;
|
||||
margin-bottom: -30rpx;
|
||||
}
|
||||
|
||||
.skuName-price {
|
||||
display: flex;
|
||||
color: #F60D58;
|
||||
line-height: 1;
|
||||
|
||||
.icon-modify {
|
||||
margin-left: 15rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.skuName-tips {
|
||||
font-size: 28rpx;
|
||||
line-height: 1;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.red {
|
||||
color: #F60D58;
|
||||
}
|
||||
|
||||
.green {
|
||||
color: $jx-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sku
|
||||
.skus {
|
||||
border-top: 1rpx dashed #ccc;
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
// justify-content: flex-end;
|
||||
// padding-top: 16rpx;
|
||||
// overflow: hidden;
|
||||
margin-top: 10rpx;
|
||||
align-items: flex-start;
|
||||
|
||||
.sku-cell:nth-of-type(even) {
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 价格审核中样式
|
||||
.check-display {
|
||||
color: #f44;
|
||||
font-size: 24rpx;
|
||||
font-weight: bold;
|
||||
animation: rubberBand 1s infinite alternate;
|
||||
}
|
||||
}
|
||||
|
||||
.skus-wrapper-new {
|
||||
border-top: 1rpx solid rgb(219, 219, 219);
|
||||
|
||||
.error {
|
||||
text-align: center;
|
||||
font-size: 24rpx;
|
||||
font-weight: bold;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.mt {
|
||||
color: #f29a40;
|
||||
}
|
||||
|
||||
.eb {
|
||||
color: #51a7fc;
|
||||
}
|
||||
|
||||
.sku-cell2 {
|
||||
padding: 10rpx 0 0 0;
|
||||
border-bottom: 1rpx solid rgb(219, 219, 219);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.isSale2 {}
|
||||
|
||||
.cell-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.price {
|
||||
color: #333;
|
||||
width: 23%;
|
||||
flex-shrink: 0;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-flow: column;
|
||||
|
||||
.sku-spec {
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.sku-price {
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.promotion-price {
|
||||
color: #F60D58;
|
||||
}
|
||||
|
||||
.btn-group {
|
||||
width: 78%;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
|
||||
.btn {
|
||||
box-sizing: border-box;
|
||||
flex: 1;
|
||||
height: 80rpx;
|
||||
text-align: center;
|
||||
font-size: 24rpx;
|
||||
border-radius: 10rpx;
|
||||
color: $jx-primary;
|
||||
border: 2rpx solid $jx-primary;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
.tmpSaleNo {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: 28rpx;
|
||||
line-height: 1.02;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.onActive {
|
||||
background: $jx-primary;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cell-bottom {
|
||||
font-size: 28rpx;
|
||||
text-align: center;
|
||||
color: #666;
|
||||
padding: 5rpx 0;
|
||||
}
|
||||
|
||||
.sku-autoSaleAt {
|
||||
font-size: 26rpx;
|
||||
text-align: center;
|
||||
color: #F25340;
|
||||
padding: 5rpx 0;
|
||||
|
||||
text {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.checkBoxWrap {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: flex-end;
|
||||
padding-top: 15rpx;
|
||||
}
|
||||
|
||||
.aduit-type {
|
||||
font-size: 28rpx;
|
||||
text-align: center;
|
||||
color: $jx-primary;
|
||||
}
|
||||
|
||||
.aduit-btn-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-top: 20rpx;
|
||||
|
||||
.btn {
|
||||
font-size: 28rpx;
|
||||
padding: 20rpx 40rpx;
|
||||
background: $jx-primary;
|
||||
border-radius: 10rpx;
|
||||
color: white;
|
||||
margin: 0 20rpx;
|
||||
}
|
||||
|
||||
.refuse {
|
||||
background: #f44;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes rubberBand {
|
||||
from {
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
|
||||
30% {
|
||||
transform: scale3d(1.01, 0.75, 1);
|
||||
}
|
||||
|
||||
40% {
|
||||
transform: scale3d(0.95, 1.25, 1);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: scale3d(1.02, 0.85, 1);
|
||||
}
|
||||
|
||||
65% {
|
||||
transform: scale3d(0.98, 1.05, 1);
|
||||
}
|
||||
|
||||
75% {
|
||||
transform: scale3d(1.01, 0.95, 1);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
}
|
||||
177
src/pages/goods-manager/childPages/right-main/right-main.ts
Normal file
177
src/pages/goods-manager/childPages/right-main/right-main.ts
Normal file
@@ -0,0 +1,177 @@
|
||||
import shopping from "@/api/https/shopping"
|
||||
import { store } from "@/store"
|
||||
import { getStorage } from "@/utils/storage"
|
||||
import toast from "@/utils/toast"
|
||||
import { jx_throttles, timeFormatD } from "@/utils/tools"
|
||||
import { computed } from "@vue/reactivity"
|
||||
import configCms from "@/utils/configCms"
|
||||
|
||||
interface propType {
|
||||
skuName: AnyObject
|
||||
isAudit: boolean
|
||||
isHot: boolean
|
||||
showMountTab: boolean
|
||||
}
|
||||
/*************************************************
|
||||
* 商品列表
|
||||
*/
|
||||
function goodsListFn(props: Readonly<propType>) {
|
||||
|
||||
/*************************************************
|
||||
* 列表判断条件
|
||||
*/
|
||||
const isNewPriceDisplay: any = computed(() => {
|
||||
store.getters['storeInfo/isNewPriceDisplay']
|
||||
})
|
||||
|
||||
/*************************************************
|
||||
* 获取userType
|
||||
*/
|
||||
const userType = computed(() => {
|
||||
return +getStorage('userType')
|
||||
})
|
||||
|
||||
/*************************************************
|
||||
* 修改商品售卖状态
|
||||
*/
|
||||
function updateSaleStatus(sku: AnyObject, skuName: AnyObject, status: number) {
|
||||
if (+sku.storeSkuStatus === +status && !sku.autoSaleAt) return false
|
||||
let data = {
|
||||
sku,
|
||||
skuName,
|
||||
status
|
||||
}
|
||||
updateSaleStatusThrottles(data)
|
||||
}
|
||||
const updateSaleStatusThrottles = jx_throttles({
|
||||
time: 500,
|
||||
success: async (e: AnyObject) => {
|
||||
let data = {
|
||||
storeIDs: JSON.stringify([getStorage('storeID')]),
|
||||
payload: JSON.stringify([
|
||||
{
|
||||
nameID: e.skuName.id,
|
||||
skus: [
|
||||
{
|
||||
skuID: e.sku.id,
|
||||
isSale: +e.status === 0 ? -1 : +e.status,
|
||||
},
|
||||
],
|
||||
},
|
||||
]),
|
||||
}
|
||||
let res = await shopping.update_stores_skus(data)
|
||||
if (res.code == 0) {
|
||||
changeSaleStatus(e.sku, e.skuName, e.status)
|
||||
if (e.sku.autoSaleAt) e.sku.autoSaleAt = 0
|
||||
} else {
|
||||
toast('修改失败', 2)
|
||||
}
|
||||
},
|
||||
fail: (t: number) => {
|
||||
toast(`操作太快`)
|
||||
}
|
||||
})
|
||||
|
||||
/*************************************************
|
||||
* 修改商品临时不可售
|
||||
*/
|
||||
function tmpSaleNo(sku: AnyObject, skuName: AnyObject) {
|
||||
if (sku.storeSkuStatus === 0 && sku.autoSaleAt) return false
|
||||
let data = {
|
||||
sku,
|
||||
skuName,
|
||||
}
|
||||
tmpSaleNoThrottles(data)
|
||||
}
|
||||
const tmpSaleNoThrottles = jx_throttles({
|
||||
time: 500,
|
||||
success: async (e: AnyObject) => {
|
||||
let autoSaleAt = computedAutoSaleAt()
|
||||
let data = {
|
||||
storeIDs: JSON.stringify([getStorage('storeID')]),
|
||||
payload: JSON.stringify([{
|
||||
skuID: e.sku.id,
|
||||
isSale: -1,
|
||||
isAsync: false,
|
||||
}]),
|
||||
autoSaleAt: autoSaleAt
|
||||
}
|
||||
let res = await shopping.update_stores_skus_sale(data)
|
||||
|
||||
// let res:AnyObject = {
|
||||
// code: "-105",
|
||||
// desc: "本地数据修改成功,但同步失败,请根据错误提示处理!,同步错误信息:[{\"商品ID\":0,\"分类名\":\"\",\"门店ID\":804947,\"平台名\":\"抖店平台\",\"平台商品ID\":\"\",\"商品nameID\":0,\"平台价\":0,\"同步类型\":\"异常同步错误\",\"错误信息\":\"门店:804947,修改没有创建的商品:22807\"},{\"商品ID\":22807,\"分类名\":\"\",\"门店ID\":804947,\"平台名\":\"京东到家\",\"平台商品ID\":\"2792687352\",\"商品nameID\":8643,\"平台价\":0,\"同步类型\":\"更新商品状态\",\"错误信息\":\"未查询到到家商品编码\"}]",
|
||||
// data: ""
|
||||
// }
|
||||
|
||||
// if (res.code === '0') {
|
||||
// changeSaleStatus(e.sku, e.skuName, 0)
|
||||
// e.sku.autoSaleAt = autoSaleAt
|
||||
// } else {
|
||||
// if(res.code === '-105' && res.desc.includes('本地数据修改成功,但同步失败,请根据错误提示处理')) toast(res.desc)
|
||||
// else toast('修改失败', 2)
|
||||
// }
|
||||
|
||||
if (res.code == 0) {
|
||||
changeSaleStatus(e.sku, e.skuName, 0)
|
||||
e.sku.autoSaleAt = autoSaleAt
|
||||
} else {
|
||||
let findIndex = res.desc.indexOf('[')
|
||||
let str = ''
|
||||
if(findIndex !== -1){
|
||||
JSON.parse(res.desc.substring(findIndex)).forEach((element:AnyObject) => {
|
||||
str = str.length >0 ? str + ';\n' + element['平台名'] + ':【' + element['错误信息'] + '】': str + element['平台名'] +':【' + element['错误信息']+'】'
|
||||
});
|
||||
}
|
||||
if(res.code === '-105' && res.desc.includes('本地数据修改成功,但同步失败,请根据错误提示处理')) toast(`${str}`)
|
||||
else toast('修改失败', 2)
|
||||
}
|
||||
},
|
||||
fail: (t: number) => {
|
||||
toast(`操作太快`)
|
||||
}
|
||||
})
|
||||
|
||||
/*************************************************
|
||||
* 计算自动可售时间
|
||||
*/
|
||||
function computedAutoSaleAt() {
|
||||
let now = +new Date()
|
||||
let autoTime = +new Date(`${timeFormatD(+new Date())} ${autoSaleAt.value}`)
|
||||
if (now < autoTime) {
|
||||
return `${timeFormatD(+new Date())} ${autoSaleAt.value}`
|
||||
} else {
|
||||
return `${timeFormatD(+new Date() + 24 * 3600 * 1000)} ${autoSaleAt.value}`
|
||||
}
|
||||
}
|
||||
|
||||
// 自动可售时间
|
||||
const autoSaleAt = computed(() => {
|
||||
let { autoSaleAt = '' } = configCms.serveInfo
|
||||
return autoSaleAt
|
||||
})
|
||||
|
||||
/*************************************************
|
||||
* 修改商品可售状态
|
||||
*/
|
||||
async function changeSaleStatus(sku: AnyObject, skuName: AnyObject, status: number) {
|
||||
if (props.isAudit) return false
|
||||
sku.storeSkuStatus = +status
|
||||
// 计算可售不可售图标
|
||||
if (skuName.skus.some((item: AnyObject) => item.storeSkuStatus)) {
|
||||
skuName.skuAllnoSale = false
|
||||
} else {
|
||||
skuName.skuAllnoSale = true
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
isNewPriceDisplay, // 列表判断条件
|
||||
userType, // 获取userType
|
||||
updateSaleStatus, // 修改商品售卖状态
|
||||
tmpSaleNo, // 临时不可售
|
||||
}
|
||||
}
|
||||
|
||||
export default goodsListFn
|
||||
264
src/pages/goods-manager/childPages/right-main/right-main.vue
Normal file
264
src/pages/goods-manager/childPages/right-main/right-main.vue
Normal file
@@ -0,0 +1,264 @@
|
||||
<template>
|
||||
<view class="skuName-cell">
|
||||
<!-- skuName -->
|
||||
<view class="skuName">
|
||||
<!-- 图片 -->
|
||||
<view class="skuName-img" @tap="previewImg(skuName)">
|
||||
<view v-show="skuName.skuAllnoSale">不可售</view>
|
||||
<image
|
||||
class="imglabel"
|
||||
mode="scaleToFill"
|
||||
lazy-load
|
||||
:src="skuName.img"
|
||||
/>
|
||||
</view>
|
||||
<!-- 图片 -->
|
||||
<!-- 其他信息 -->
|
||||
<view class="skuName-info">
|
||||
<!-- 名称 -->
|
||||
<view class="skuName-name">
|
||||
{{ skuName.prefix ? '[' + skuName.prefix + ']' : ''
|
||||
}}{{ skuName.name }}
|
||||
</view>
|
||||
<!-- skuNameID -->
|
||||
<view @tap.stop="copyInfo(''+ skuName.id, '复制nameID成功')" style="color:#818181;">
|
||||
<text>{{ skuName.id }}</text>
|
||||
<jx-icon icon="fuzhi" color="#818181" style="margin-left: 10rpx;"></jx-icon>
|
||||
</view>
|
||||
<!-- 价格 改价 -->
|
||||
<view class="skuName-price" @tap="openPriceDialog(skuName)">
|
||||
<jx-price
|
||||
:price="skuName.unitPrice"
|
||||
color="#F60D58"
|
||||
sizeM="22rpx"
|
||||
sizeN="38rpx"
|
||||
/>
|
||||
|
||||
<view class="icon-modify" v-if="!isAudit">
|
||||
<jx-icon icon="shuxie" color="#999" :size="38" />
|
||||
</view>
|
||||
</view>
|
||||
<!-- 提示信息 -->
|
||||
<view>
|
||||
<view class="skuName-tips" v-if="skuName.unit === '份'">
|
||||
该价格为每斤价格
|
||||
</view>
|
||||
<view class="skuName-tips green" v-if="skuName.unit !== '份'">
|
||||
该价格为每{{ skuName.unit }}价格
|
||||
</view>
|
||||
<!-- 审核状态 -->
|
||||
<view class="check-display" v-show="skuName.auditUnitPrice">
|
||||
审核中价格:<jx-price
|
||||
:price="skuName.auditUnitPrice"
|
||||
color="#f44"
|
||||
size="24rpx"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 其他信息 -->
|
||||
</view>
|
||||
<!-- skuName -->
|
||||
<!-- sku2 -->
|
||||
<view class="skus-wrapper-new" v-if="!isAudit">
|
||||
<view v-for="(sku, j) in skuName.skus" :key="j" class="sku-cell2">
|
||||
<!-- 异常商品 -->
|
||||
<view
|
||||
class="error mt"
|
||||
v-if="
|
||||
sku.mtwmID !== '' &&
|
||||
(sku.mtwmSyncStatus & 16) === 16 &&
|
||||
(sku.mtwmSyncStatus & 2) !== 2 &&
|
||||
(sku.mtwmSyncStatus & 4) !== 4
|
||||
"
|
||||
>美团:该商品无法修改价格,请联系运营修改</view
|
||||
>
|
||||
<view
|
||||
class="error eb"
|
||||
v-if="
|
||||
sku.ebaiID !== '' &&
|
||||
(sku.ebaiSyncStatus & 16) === 16 &&
|
||||
(sku.ebaiSyncStatus & 2) !== 2 &&
|
||||
(sku.ebaiSyncStatus & 4) !== 4
|
||||
"
|
||||
>饿佰:该商品无法修改价格,请联系运营修改</view
|
||||
>
|
||||
<view class="cell-top">
|
||||
<view class="price">
|
||||
<view class="sku-spec">
|
||||
{{ sku.specQuality }}{{ sku.specUnit }}
|
||||
</view>
|
||||
<view
|
||||
class="sku-price"
|
||||
:class="{ 'promotion-price': !isNewPriceDisplay && sku.actPrice }"
|
||||
>
|
||||
<jx-price
|
||||
:price="sku.comparePrice"
|
||||
sizeM="22rpx"
|
||||
sizeN="28rpx"
|
||||
color="#000"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn-group">
|
||||
<view
|
||||
class="btn"
|
||||
:class="{ onActive: sku.storeSkuStatus }"
|
||||
@tap="updateSaleStatus(sku, skuName, 1)"
|
||||
>
|
||||
可售
|
||||
</view>
|
||||
<view
|
||||
class="btn"
|
||||
:class="{ onActive: !sku.storeSkuStatus && !sku.autoSaleAt }"
|
||||
@tap="updateSaleStatus(sku, skuName, 0)"
|
||||
>
|
||||
不可售
|
||||
</view>
|
||||
<view
|
||||
v-if="!isHot"
|
||||
class="btn tmpSaleNo"
|
||||
:class="{ onActive: !sku.storeSkuStatus && sku.autoSaleAt }"
|
||||
@tap="tmpSaleNo(sku, skuName)"
|
||||
>
|
||||
<text>临时</text>
|
||||
<text>不可售</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 库存以及位置码 -->
|
||||
<view style="display: flex;color:#666;margin-top:20rpx;justify-content: center">
|
||||
<view @tap="openDialog(skuName,sku,'stock')">
|
||||
库存:{{sku.stock}}
|
||||
<jx-icon icon="shuxie" color="#999" :size="24" />
|
||||
</view>
|
||||
<view style="margin-left: 20rpx;" @tap="openDialog(skuName,sku,'locationCode')">
|
||||
货架码:{{sku.locationCode && sku.locationCode !== 'EMPTY_VALUE' ? sku.locationCode : ''}}
|
||||
<jx-icon icon="shuxie" color="#999" :size="24" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="cell-bottom">{{ sku.comment ? sku.comment : '' }}</view>
|
||||
<view class="sku-autoSaleAt" v-if="sku.autoSaleAt">
|
||||
该规格将在 <text>{{ sku.autoSaleAt }}</text> 可售
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="showMountTab" class="checkBoxWrap">
|
||||
<label @tap="handleSale(skuName)">
|
||||
<checkbox color="#4eb331" style="transform: scale(0.8)" />选中商品
|
||||
</label>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 待审核商品操作面板 -->
|
||||
<view class="aduit-wall" v-else>
|
||||
<view class="aduit-type">{{
|
||||
skuName.type === 1 ? '【价格】正在审核中' : '【新建】正在审核中'
|
||||
}}</view>
|
||||
<!-- ((userType & 4) === 4) 运营 -->
|
||||
<view class="aduit-btn-group" v-if="(+getStorage('userType') & 4) === 4">
|
||||
<view class="btn refuse" @tap="toExamine(skuName, -1)">拒绝</view>
|
||||
<view class="btn" @tap="toExamine(skuName, 1)">批准</view>
|
||||
</view>
|
||||
<view class="aduit-btn-group" v-else>
|
||||
<view class="btn" @tap="phoneCall(storeInfo.marketManName)"
|
||||
>联系运营加快审核</view
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup >
|
||||
import useGlobalFunc from '@/composables/useGlobalFunc'
|
||||
import { store } from '@/store'
|
||||
import { getStorage } from '@/utils/storage'
|
||||
import { computed } from 'vue'
|
||||
import goodsListFn from './right-main'
|
||||
import useOrderInfo from '@/composables/useOrderInfo'
|
||||
const { copyInfo } = useOrderInfo()
|
||||
const { phoneCall } = useGlobalFunc()
|
||||
|
||||
/*************************************************
|
||||
* 接收数据
|
||||
*/
|
||||
interface propType {
|
||||
skuName: AnyObject
|
||||
isAudit: boolean
|
||||
isHot: boolean
|
||||
showMountTab: boolean
|
||||
}
|
||||
|
||||
const prop = defineProps<propType>()
|
||||
|
||||
const {
|
||||
isNewPriceDisplay, // 列表判断条件
|
||||
updateSaleStatus, // 修改商品售卖状态
|
||||
tmpSaleNo, // 临时不可售
|
||||
} = goodsListFn(prop)
|
||||
const {
|
||||
previewImage, // 预览图片
|
||||
} = useGlobalFunc()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'handleSale', data: AnyObject): void
|
||||
(e: 'openPriceDialog', data: AnyObject): void
|
||||
(e: 'openDialog', data: AnyObject): void
|
||||
(e: 'toExamine', data: AnyObject): void
|
||||
}>()
|
||||
function handleSale(skuName: AnyObject) {
|
||||
emit('handleSale', skuName)
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 预览图片
|
||||
*/
|
||||
function previewImg(skuName:AnyObject) {
|
||||
let arr = [skuName.img,skuName.img2,skuName.img3,skuName.img4,skuName.img5].filter(item => { return item && item.length > 0 })
|
||||
previewImage(arr)
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 修改操作
|
||||
*/
|
||||
function openPriceDialog(skuName: AnyObject) {
|
||||
if (prop.isAudit) return
|
||||
emit('openPriceDialog', skuName)
|
||||
}
|
||||
|
||||
function openDialog(skuName: AnyObject,sku:AnyObject,type:String) {
|
||||
let payload = {
|
||||
nameID:skuName.id,
|
||||
Skus:[{
|
||||
skuID:sku.id,
|
||||
stock:sku.stock,
|
||||
locationCode:sku.locationCode && sku.locationCode !== 'EMPTY_VALUE' ? sku.locationCode : ''
|
||||
}]
|
||||
}
|
||||
emit('openDialog', {payload,type,name:skuName.name})
|
||||
}
|
||||
|
||||
|
||||
/*************************************************
|
||||
* 拒绝改价
|
||||
*/
|
||||
function toExamine(skuName: AnyObject, type: any) {
|
||||
let data = {
|
||||
status: type,
|
||||
nameID: skuName.nameID,
|
||||
storeID: getStorage('storeID'),
|
||||
auditPrice: skuName.auditUnitPrice,
|
||||
}
|
||||
emit('toExamine', data)
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
* 获取门店信息
|
||||
*/
|
||||
const storeInfo = computed(() => {
|
||||
return store.state.storeInfo.allStoreInfo
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './right-main.scss';
|
||||
</style>
|
||||
@@ -0,0 +1,218 @@
|
||||
<template>
|
||||
<view class="filter-root"
|
||||
:class="{'filter-fill':isCheckoutFilter}">
|
||||
<template v-if="isCheckoutFilter">
|
||||
<view
|
||||
class="item item-fill"
|
||||
:class="{ active: filteActive2 == item.lable }"
|
||||
v-for="(item, index) in filterData2"
|
||||
:key="index"
|
||||
@tap="fliterFn2(item.lable, item.status)"
|
||||
>{{ item.title }}</view
|
||||
>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view
|
||||
class="item item-filter"
|
||||
:class="{ active: filteActive == item.lable }"
|
||||
v-for="(item, index) in filterData"
|
||||
:key="index"
|
||||
@tap="fliterFn(item, item.status)"
|
||||
>{{ item.title }}</view
|
||||
>
|
||||
</template>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup >
|
||||
import toast from '@/utils/toast'
|
||||
import { jx_throttles } from '@/utils/tools'
|
||||
import { ref, watch } from 'vue'
|
||||
|
||||
interface propsType {
|
||||
isCheckoutFilter: boolean
|
||||
updateStateOk: boolean
|
||||
}
|
||||
const props = defineProps<propsType>()
|
||||
|
||||
/*************************************************
|
||||
* 参数1
|
||||
*/
|
||||
const filterData = ref<Array<AnyObject>>([
|
||||
{
|
||||
title: '全部',
|
||||
name:'all',
|
||||
lable: 2,
|
||||
status: -1,
|
||||
},
|
||||
{
|
||||
title: '可售',
|
||||
name:'status',
|
||||
lable: 1,
|
||||
status: 1,
|
||||
},
|
||||
{
|
||||
title: '不可售',
|
||||
name:'status',
|
||||
lable: 0,
|
||||
status: 0,
|
||||
},
|
||||
{
|
||||
title: '有库存', //库存 1 全查~ 2 有~ 3 无~
|
||||
name:'stock',
|
||||
lable:4,
|
||||
status: 2,
|
||||
},
|
||||
{
|
||||
title: '无库存',
|
||||
name:'stock',
|
||||
lable:5,
|
||||
status: 3,
|
||||
},
|
||||
// {
|
||||
// title: '有货架码',
|
||||
// name:'locationCode',
|
||||
// lable:6,
|
||||
// status:false // 实际上是全部查,感觉没用
|
||||
// },
|
||||
{
|
||||
title: '无货架码',
|
||||
name:'locationCode',
|
||||
lable:7,
|
||||
status:true
|
||||
},
|
||||
{
|
||||
title: '批量',
|
||||
name:'',
|
||||
lable: 3,
|
||||
status: -1,
|
||||
},
|
||||
])
|
||||
|
||||
/*************************************************
|
||||
* 参数2
|
||||
*/
|
||||
const filterData2 = ref<Array<AnyObject>>([
|
||||
{
|
||||
title: '全部',
|
||||
lable: 2,
|
||||
status: -1,
|
||||
},
|
||||
{
|
||||
title: '批量',
|
||||
lable: 3,
|
||||
status: -1,
|
||||
},
|
||||
])
|
||||
|
||||
/*************************************************
|
||||
* emit
|
||||
*/
|
||||
const emit = defineEmits<{
|
||||
(e: 'updateIsSale', data: AnyObject): void
|
||||
(e: 'updateTowFilter', data: AnyObject): void
|
||||
}>()
|
||||
|
||||
/*************************************************
|
||||
* 筛选1
|
||||
*/
|
||||
const filteActive = ref<number>(2)
|
||||
function fliterFn(item: AnyObject, status: number | boolean) {
|
||||
if (filteActive.value == item.lable) return
|
||||
fliterFn_throttles(item, status)
|
||||
}
|
||||
|
||||
const fliterFn_throttles = jx_throttles({
|
||||
time: 2000,
|
||||
success: (item: AnyObject, status: number | boolean) => {
|
||||
filteActive.value = item.lable
|
||||
filteActive2.value = item.lable
|
||||
let data = {
|
||||
status: status,
|
||||
lable: item.lable,
|
||||
name:item.name
|
||||
}
|
||||
emit('updateIsSale', data)
|
||||
},
|
||||
fail: () => {
|
||||
toast('老板要点慢点哦')
|
||||
},
|
||||
})
|
||||
|
||||
/*************************************************
|
||||
* 筛选2
|
||||
*/
|
||||
const filteActive2 = ref<number>(2)
|
||||
function fliterFn2(lable: number, status: number) {
|
||||
if (filteActive2.value == lable) return
|
||||
filteActive2.value = lable
|
||||
filteActive.value = lable
|
||||
let data = {
|
||||
status: status,
|
||||
lable: lable,
|
||||
}
|
||||
emit('updateTowFilter', data)
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.updateStateOk,
|
||||
(val) => {
|
||||
if (val) {
|
||||
filteActive2.value = 2
|
||||
filteActive.value = 2
|
||||
}
|
||||
}
|
||||
)
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.filter-root {
|
||||
display: flex;
|
||||
overflow-x: auto; /* 允许水平方向滚动 */
|
||||
white-space: nowrap; /* 防止子元素换行 */
|
||||
align-items: center;
|
||||
// justify-content: space-around;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
border-left: 1rpx solid rgb(223, 223, 223);
|
||||
height: 90rpx;
|
||||
background-color: #fff;
|
||||
box-shadow: 10rpx 0rpx 10rpx rgb(207, 207, 207);
|
||||
border-bottom: 1rpx solid rgb(224, 224, 224);
|
||||
padding: 0 10rpx;
|
||||
|
||||
.filter-fill{
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.item {
|
||||
flex: 1;
|
||||
height: 60rpx;
|
||||
border-radius: 10rpx;
|
||||
border: 2rpx solid $jx-primary;
|
||||
color: $jx-primary;
|
||||
padding: 0 10rpx;
|
||||
line-height: 60rpx;
|
||||
text-align: center;
|
||||
transition: all 0.2s;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
|
||||
.item-filter{
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.item-fill{
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.item:nth-child(1) {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.active {
|
||||
background-color: $jx-primary;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,128 @@
|
||||
<template>
|
||||
<view class="search-root">
|
||||
<view class="add-shopping" @tap="createGoods">
|
||||
<jx-icon icon="jiahao" color="#4eb331"></jx-icon>
|
||||
<text>新建</text>
|
||||
</view>
|
||||
|
||||
<uni-search-bar
|
||||
cancelButton="none"
|
||||
clearButton="auto"
|
||||
placeholder="请输入关键字 例如:土豆"
|
||||
@confirm="confirm"
|
||||
@input="input"
|
||||
@clear="clear"
|
||||
v-model="text"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup >
|
||||
import toast from '@/utils/toast'
|
||||
import { jx_trembling } from '@/utils/tools'
|
||||
import { ref, watch } from 'vue'
|
||||
|
||||
/*************************************************
|
||||
* props
|
||||
*/
|
||||
interface propsType {
|
||||
isFilter: string | number
|
||||
}
|
||||
const props = defineProps<propsType>()
|
||||
|
||||
const text = ref<string>('')
|
||||
let isInput = false
|
||||
watch(
|
||||
() => props.isFilter,
|
||||
(val) => {
|
||||
if (val == 'hot' || val == 'audit') {
|
||||
isInput = true
|
||||
} else {
|
||||
isInput = false
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
/*************************************************
|
||||
* emit
|
||||
*/
|
||||
const emit = defineEmits<{
|
||||
(e: 'serachShopping', data: string): void
|
||||
(e: 'clearInpu', data: string): void
|
||||
(e: 'createGoods'): void
|
||||
}>()
|
||||
|
||||
/*************************************************
|
||||
* 确定搜索
|
||||
*/
|
||||
let watchTimer: any = null
|
||||
function confirm(e: AnyObject) {
|
||||
if (isInput) {
|
||||
let watchTimer = setTimeout(() => {
|
||||
text.value = ''
|
||||
clearTimeout(watchTimer)
|
||||
}, 500)
|
||||
return toast('该分类暂不支持搜索')
|
||||
}
|
||||
emit('serachShopping', e.value)
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 输入框加载
|
||||
*/
|
||||
function input(e: string) {
|
||||
if (isInput) {
|
||||
let watchTimer = setTimeout(() => {
|
||||
text.value = ''
|
||||
clearTimeout(watchTimer)
|
||||
}, 500)
|
||||
return toast('该分类暂不支持搜索')
|
||||
}
|
||||
trembling(e)
|
||||
}
|
||||
const trembling = jx_trembling((e: string) => {
|
||||
emit('serachShopping', e)
|
||||
}, 1000)
|
||||
|
||||
/*************************************************
|
||||
* 清空输入框
|
||||
*/
|
||||
function clear(e: AnyObject) {
|
||||
if (isInput) return
|
||||
emit('clearInpu', e.value)
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 新建商品
|
||||
*/
|
||||
function createGoods() {
|
||||
emit('createGoods')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.search-root {
|
||||
box-sizing: border-box;
|
||||
background-color: $jx-primary;
|
||||
padding: 0 20rpx 2rpx 20rpx;
|
||||
height: 92rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.add-shopping {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
background-color: #fff;
|
||||
font-size: 20rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
border-radius: 50%;
|
||||
color: $jx-primary;
|
||||
line-height: 1;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
45
src/pages/goods-manager/component/left-bar/left-bar.scss
Normal file
45
src/pages/goods-manager/component/left-bar/left-bar.scss
Normal file
@@ -0,0 +1,45 @@
|
||||
// 一级
|
||||
.one-item {
|
||||
background-color: #fff;
|
||||
height: 90rpx;
|
||||
overflow: hidden;
|
||||
transition: all 0.4s;
|
||||
border-bottom: 1rpx solid #f1f1f1;
|
||||
|
||||
// 二级名字
|
||||
.one-item-name {
|
||||
display: flex;
|
||||
height: 90rpx;
|
||||
line-height: 90rpx;
|
||||
|
||||
.iconfont {
|
||||
display: inline-block;
|
||||
transform: rotate(0deg);
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.noe-seat {
|
||||
display: inline-block;
|
||||
width: 30rpx;
|
||||
height: 90rpx;
|
||||
border-left: 7rpx solid transparent;
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
// 二级内容
|
||||
.tow-item {
|
||||
display: flex;
|
||||
height: 90rpx;
|
||||
line-height: 90rpx;
|
||||
transition: none;
|
||||
|
||||
// 二级左侧竖杠
|
||||
.tow-seat {
|
||||
display: inline-block;
|
||||
width: 30rpx;
|
||||
height: 90rpx;
|
||||
border-left: 7rpx solid transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
83
src/pages/goods-manager/component/left-bar/left-bar.ts
Normal file
83
src/pages/goods-manager/component/left-bar/left-bar.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import shopping from "@/api/https/shopping"
|
||||
import { getStorage } from "@/utils/storage"
|
||||
import { onLoad } from "@dcloudio/uni-app"
|
||||
import { ref } from "vue"
|
||||
|
||||
/*************************************************
|
||||
* 商品分类栏目
|
||||
*/
|
||||
function leftBarFn(props: AnyObject) {
|
||||
|
||||
onLoad(async () => {
|
||||
await GetStoreCategoryMap()
|
||||
})
|
||||
|
||||
/*************************************************
|
||||
* @info 左侧tab数据
|
||||
* 获取列表数据
|
||||
*/
|
||||
const cat = ref<Array<AnyObject>>([])
|
||||
async function GetStoreCategoryMap() {
|
||||
let data = {
|
||||
storeID: getStorage('storeID'),
|
||||
parentID: -1,
|
||||
}
|
||||
let res = await shopping.getStore_category_map(data)
|
||||
if (res.code == 0) {
|
||||
handledata(res.data, true)
|
||||
} else {
|
||||
cat.value = []
|
||||
handleOriginData()
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 处理列表数据
|
||||
*/
|
||||
const _isMap = ref<boolean>(false)
|
||||
function handledata(curdeData: Array<AnyObject>, isMap: boolean) {
|
||||
let data = curdeData
|
||||
let catData: Array<AnyObject> = []
|
||||
data.forEach((item: AnyObject) => {
|
||||
if (item.name !== '3件9.9') {
|
||||
item.name = item.name.slice(0, 4)
|
||||
}
|
||||
catData.push(item)
|
||||
})
|
||||
|
||||
//把sku分类过滤掉
|
||||
if (!isMap) catData = catData.filter((item) => item.type === 0)
|
||||
let catLevel1 = catData.filter((item) => item.level === 1)
|
||||
let catLevel2 = catData.filter((item) => item.level === 2)
|
||||
|
||||
// 组合分类
|
||||
let catData2: Array<AnyObject> = []
|
||||
let catData3: AnyObject
|
||||
catLevel1.forEach((level1: AnyObject) => {
|
||||
isMap
|
||||
? (catData3 = catLevel2.filter(
|
||||
(level2) => level2.parentID === level1.categoryID
|
||||
))
|
||||
: (catData3 = catLevel2.filter((level2) => level2.parentID === level1.id))
|
||||
level1.children = catData3
|
||||
_isMap.value = isMap
|
||||
catData2.push(level1)
|
||||
})
|
||||
let lastData = props.dafauleData.concat(catData2)
|
||||
cat.value = lastData
|
||||
}
|
||||
|
||||
async function handleOriginData() {
|
||||
let res = await shopping.get_categories()
|
||||
if (res.code == 0) {
|
||||
handledata(res.data, false)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
cat, // 右侧菜单数据
|
||||
GetStoreCategoryMap, // 获取数据
|
||||
}
|
||||
}
|
||||
|
||||
export default leftBarFn
|
||||
139
src/pages/goods-manager/component/left-bar/left-bar.vue
Normal file
139
src/pages/goods-manager/component/left-bar/left-bar.vue
Normal file
@@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<view
|
||||
v-for="(item, index) in cat"
|
||||
:key="index"
|
||||
class="one-item"
|
||||
:class="{
|
||||
'one-item-active':
|
||||
index == oneActive && item.children.length != 0 && isOpen,
|
||||
'item-name': oneActive == index && item.children.length == 0,
|
||||
}"
|
||||
>
|
||||
<!-- 第一层 -->
|
||||
<view
|
||||
:class="{
|
||||
'never-pen-active': index == oneActive && item.children.length != 0,
|
||||
}"
|
||||
class="one-item-name"
|
||||
@tap="oneItemFn(item, index)"
|
||||
>
|
||||
<text class="iconfont icon-jiantou1" v-if="item.children.length != 0" />
|
||||
<text class="noe-seat noe-seat-active" v-else></text>
|
||||
<text>{{ item.name }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 第二层 -->
|
||||
<view
|
||||
class="tow-item"
|
||||
:class="{ 'tow-item-active': towActive == childIndex }"
|
||||
v-for="(childItem, childIndex) in item.children"
|
||||
:key="childIndex"
|
||||
@tap="towItemFn(childItem, childIndex)"
|
||||
>
|
||||
<text class="tow-seat tow-seat-active"></text>{{ childItem.name }}</view
|
||||
>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup >
|
||||
import { Ref, ref } from 'vue'
|
||||
import leftBarFn from './left-bar'
|
||||
|
||||
/*************************************************
|
||||
* 接收数据
|
||||
*/
|
||||
interface propsType {
|
||||
dafauleData: Array<AnyObject>
|
||||
}
|
||||
const props = defineProps<propsType>()
|
||||
|
||||
const {
|
||||
cat, // 右侧菜单数据
|
||||
GetStoreCategoryMap, // 获取数据
|
||||
} = leftBarFn(props)
|
||||
|
||||
/*************************************************
|
||||
* emit
|
||||
*/
|
||||
const eimt = defineEmits<{
|
||||
(e: 'oneMenuClick', data: string | number): void
|
||||
}>()
|
||||
|
||||
/*************************************************
|
||||
* 一级菜单点击
|
||||
*/
|
||||
const isOpen = ref<boolean>(false)
|
||||
const oneActive = ref<number>(0) // 高亮
|
||||
const oneHeight: Ref<string> = ref('0px') // 高度
|
||||
function oneItemFn(item: AnyObject, index: number) {
|
||||
if (oneActive.value == index) {
|
||||
isOpen.value = !isOpen.value
|
||||
} else {
|
||||
isOpen.value = true
|
||||
}
|
||||
oneActive.value = index // 一级菜单
|
||||
oneHeight.value = `${(item.length + 1) * 90}rpx` // 动态高度
|
||||
towActive.value = -1 // 默认二级菜单
|
||||
if (!isOpen.value) return
|
||||
eimt('oneMenuClick', item.categoryID)
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 二级菜单点击
|
||||
*/
|
||||
const towActive = ref<number>(-1) // 高亮
|
||||
function towItemFn(childItem: AnyObject, index: number) {
|
||||
if (towActive.value == index) return
|
||||
towActive.value = index
|
||||
eimt('oneMenuClick', childItem.categoryID)
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 导出子组件方法
|
||||
*/
|
||||
defineExpose({
|
||||
GetStoreCategoryMap,
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './left-bar.scss';
|
||||
|
||||
// 一级展开动画
|
||||
.one-item-active {
|
||||
height: v-bind(oneHeight) !important;
|
||||
background-color: rgb(236, 252, 233);
|
||||
|
||||
// 三角图标动画
|
||||
.icon-jiantou1 {
|
||||
display: inline-block;
|
||||
transform: rotate(90deg) !important;
|
||||
}
|
||||
}
|
||||
|
||||
// 一级选中高亮
|
||||
.never-pen-active {
|
||||
background-color: $jx-primary;
|
||||
color: #fff;
|
||||
border-bottom: 1rpx solid #fff;
|
||||
}
|
||||
|
||||
// 一级展开背景
|
||||
.item-name {
|
||||
color: $jx-primary;
|
||||
.noe-seat-active {
|
||||
border-left: 7rpx solid $jx-primary !important;
|
||||
}
|
||||
}
|
||||
|
||||
// 二级高亮
|
||||
.tow-item-active {
|
||||
color: $jx-primary;
|
||||
background-color: #fff;
|
||||
|
||||
// 二级选中高亮
|
||||
.tow-seat-active {
|
||||
border-left: 7rpx solid $jx-primary !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
124
src/pages/goods-manager/main.scss
Normal file
124
src/pages/goods-manager/main.scss
Normal file
@@ -0,0 +1,124 @@
|
||||
.MountWrap {
|
||||
display: flex;
|
||||
z-index: 99;
|
||||
box-sizing: border-box;
|
||||
justify-content: space-between;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background-color: $jx-primary;
|
||||
padding: 20rpx 25rpx;
|
||||
|
||||
.onActive {
|
||||
width: 44%;
|
||||
background-color: #fff;
|
||||
color: $jx-primary;
|
||||
text-align: center;
|
||||
border-radius: 10rpx;
|
||||
padding: 10rpx 0;
|
||||
}
|
||||
}
|
||||
|
||||
.createGoods {
|
||||
padding: 10rpx 80rpx;
|
||||
border-radius: 10rpx;
|
||||
background-color: $jx-primary;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.jx-popup-update {
|
||||
box-sizing: border-box;
|
||||
padding: 20rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 0 0 15rpx 15rpx;
|
||||
|
||||
.text {
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin-bottom: 25rpx;
|
||||
padding-bottom: 10rpx;
|
||||
border-bottom: 2rpx solid rgb(209, 209, 209);
|
||||
}
|
||||
|
||||
.tip-new{
|
||||
padding: 2rpx 0;
|
||||
height: 66rpx;
|
||||
line-height: 66rpx;
|
||||
text-align: left;
|
||||
border-bottom:1px dashed #999;
|
||||
|
||||
.money {
|
||||
color: $jx-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.ipt-box{
|
||||
margin: 10rpx 0;
|
||||
// height: 86rpx;
|
||||
// line-height: normal;
|
||||
}
|
||||
|
||||
.tip {
|
||||
padding: 10rpx 0;
|
||||
|
||||
.money {
|
||||
color: $jx-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.ipt {
|
||||
border: 2rpx solid rgb(209, 209, 209);
|
||||
text-align: center;
|
||||
border-radius: 5rpx;
|
||||
height: 86rpx;
|
||||
line-height: normal;
|
||||
// -webkit-appearance: none;
|
||||
// border-radius: 0
|
||||
}
|
||||
|
||||
.title {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.btn-root {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: 40rpx 0 0rpx 0;
|
||||
|
||||
.btn-esc,
|
||||
.btn-ok {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
padding: 15rpx 0;
|
||||
border-radius: 10rpx;
|
||||
border: 2rpx solid $jx-primary;
|
||||
color: $jx-primary;
|
||||
}
|
||||
|
||||
.btn-ok {
|
||||
background-color: $jx-primary;
|
||||
color: #fff;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
|
||||
.btn-esc {
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.delete {
|
||||
margin-top: 50rpx;
|
||||
margin-bottom: 20rpx;
|
||||
background-color: $jx-warring;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
padding: 20rpx;
|
||||
border-radius: 15rpx;
|
||||
}
|
||||
}
|
||||
710
src/pages/goods-manager/main.ts
Normal file
710
src/pages/goods-manager/main.ts
Normal file
@@ -0,0 +1,710 @@
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app'
|
||||
import { getStorage } from '@/utils/storage'
|
||||
import { computed, onBeforeUnmount, ref } from 'vue'
|
||||
import { store } from '@/store'
|
||||
import { timeFormatD, timeFormatHMS } from '@/utils/tools'
|
||||
import toast from '@/utils/toast'
|
||||
import shopping from '@/api/https/shopping'
|
||||
import merchant from '@/api/https/merchant'
|
||||
/*************************************************
|
||||
* 商品管理
|
||||
*/
|
||||
function shoppingMangerFn() {
|
||||
/*************************************************
|
||||
* 数据归位,元神显现
|
||||
*/
|
||||
function dataHoming() {
|
||||
skuNames.value = []
|
||||
page.value = 1
|
||||
totalCount.value = 0
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 下拉刷新数据重现
|
||||
*/
|
||||
const leftBarRef = ref<any>(null)
|
||||
let onPullDownRefreshTimer: any = ''
|
||||
const triggered = ref<boolean>(false)
|
||||
function refresherrefresh() {
|
||||
triggered.value = true
|
||||
clearTimeout(onPullDownRefreshTimer)
|
||||
onPullDownRefreshTimer = setTimeout(() => {
|
||||
triggered.value = false
|
||||
dataHoming()
|
||||
oneMenuClick(isFilter.value)
|
||||
if (isFilter.value == 'hot') return
|
||||
leftBarRef.value.GetStoreCategoryMap()
|
||||
}, 500)
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 获取数据
|
||||
*/
|
||||
let oldStoreID: any = 0
|
||||
onShow(() => {
|
||||
if (oldStoreID != getStorage('storeID') && oldStoreID != 0) {
|
||||
triggered.value = true
|
||||
}
|
||||
oldStoreID = getStorage('storeID')
|
||||
})
|
||||
|
||||
/*************************************************
|
||||
* 默认数据
|
||||
*/
|
||||
const dafauleData: Array<AnyObject> = [
|
||||
{
|
||||
categoryID: 'all',
|
||||
children: [],
|
||||
level: 1,
|
||||
name: '所有分类',
|
||||
},
|
||||
{
|
||||
categoryID: 'act',
|
||||
children: [],
|
||||
level: 1,
|
||||
name: '活动商品',
|
||||
},
|
||||
{
|
||||
categoryID: 'hot',
|
||||
children: [],
|
||||
level: 1,
|
||||
name: '畅销推荐',
|
||||
},
|
||||
{
|
||||
categoryID: 'audit',
|
||||
children: [],
|
||||
level: 1,
|
||||
name: '待审商品',
|
||||
},
|
||||
]
|
||||
|
||||
/*************************************************
|
||||
* @info 右侧主体数据
|
||||
* 获取商品数据
|
||||
*/
|
||||
onLoad(async () => {
|
||||
if (!getStorage('token')) return
|
||||
store.commit('storeInfo/jxLoadingFn', true)
|
||||
await getSkuNames()
|
||||
store.commit('storeInfo/jxLoadingFn', false)
|
||||
})
|
||||
const keyword = ref<string>('')
|
||||
const categoryID = ref<string>('') // 分类id
|
||||
const isAct = ref<boolean>(false) // 是否是活动商品
|
||||
const totalCount = ref<number>(0) // 总条数
|
||||
const skuNames = ref<Array<AnyObject>>([]) // 商品数据
|
||||
const isAudit = ref<boolean>(false) // 商品列表判断条件
|
||||
const isHot = ref<boolean>(false) // 商品列表判断条件
|
||||
async function getSkuNames() {
|
||||
isLoad.value = true
|
||||
let data:AnyObject = {
|
||||
categoryID: categoryID.value,
|
||||
isFocus: true,
|
||||
keyword: keyword.value,
|
||||
offset: pageSize.value * (page.value - 1),
|
||||
pageSize: pageSize.value,
|
||||
isAct: isAct.value,
|
||||
status: -1,
|
||||
storeID: getStorage('storeID')
|
||||
}
|
||||
|
||||
if(allSaleStatus.value && allSaleStatus.value.name !== 'all') data[allSaleStatus.value.name] = allSaleStatus.value.status
|
||||
|
||||
keyFilter(data)
|
||||
|
||||
let res = await shopping.get_stores_skus_for_store(data)
|
||||
|
||||
if (res.code == 0) {
|
||||
totalCount.value = res.data.totalCount
|
||||
let filterData = mapskuName(res.data.skuNames || [])
|
||||
skuNames.value = skuNames.value.concat(filterData)
|
||||
if (filterData.length == 0) return toast('该分类未找到商品')
|
||||
} else {
|
||||
dataHoming()
|
||||
toast('分类查询错误')
|
||||
}
|
||||
isLoad.value = false
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 过滤对象空字段
|
||||
*/
|
||||
function keyFilter(obj: AnyObject) {
|
||||
for (let key in obj) {
|
||||
if ('' + obj[key] == "" || '' + obj[key] == undefined) {
|
||||
delete obj[key]
|
||||
}
|
||||
}
|
||||
return obj
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 列表判断条件
|
||||
*/
|
||||
const isNewPriceDisplay = ref<boolean>(
|
||||
store.getters['storeInfo/isNewPriceDisplay']
|
||||
)
|
||||
|
||||
/*************************************************
|
||||
* 格式化数据
|
||||
*/
|
||||
function mapskuName(skuNames: Array<AnyObject>) {
|
||||
let arr = skuNames.map((skuName) => {
|
||||
skuName.auditUnitPrice = skuName.auditUnitPrice
|
||||
// 是否全部不可售
|
||||
if (skuName.skus.some((item: AnyObject) => item.storeSkuStatus)) {
|
||||
skuName.skuAllnoSale = false
|
||||
} else {
|
||||
skuName.skuAllnoSale = true
|
||||
}
|
||||
// skus
|
||||
skuName.skus = skuName.skus.map((sku: AnyObject) => {
|
||||
// 价格异常请参考老版本或者在git进行查看
|
||||
sku.comparePrice = sku.price
|
||||
sku.autoSaleAt =
|
||||
+new Date(sku.autoSaleAt) > 0 ? timeFormatHMS(sku.autoSaleAt) : 0
|
||||
return sku
|
||||
})
|
||||
return skuName
|
||||
})
|
||||
return arr
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 页面触底,加载更多数据
|
||||
*/
|
||||
const page = ref<number>(1) // 第几页
|
||||
const pageSize = ref<number>(20) // 每页条数
|
||||
const isLoad = ref<boolean>(false) // 加载图
|
||||
function scrolltolower() {
|
||||
page.value++
|
||||
if (pageSize.value * (page.value - 1) > totalCount.value || totalCount.value < pageSize.value) {
|
||||
isLoad.value = false
|
||||
} else {
|
||||
if (isLoad.value) return
|
||||
if (isFilter.value == 'hot') return
|
||||
if (isFilter.value == 'audit') return GetStoreSkuAudit()
|
||||
getSkuNames()
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 点击菜单获取数据
|
||||
*/
|
||||
const isCheckoutFilter = ref<boolean>(false)
|
||||
const isFilter = ref<string | number>('')
|
||||
function oneMenuClick(catID: string | number) {
|
||||
isAct.value = false
|
||||
isHot.value = false
|
||||
isCheckoutFilter.value = false
|
||||
categoryID.value = ''
|
||||
keyword.value = ''
|
||||
isFilter.value = catID
|
||||
isAudit.value = false
|
||||
dataHoming()
|
||||
if (catID == 'all') { // 全部商品
|
||||
isAct.value = false
|
||||
getSkuNames()
|
||||
} else if (catID == 'act') { // 活动商品
|
||||
isAct.value = true
|
||||
getSkuNames()
|
||||
} else if (catID == 'hot') { // 畅销商品
|
||||
isHot.value = true
|
||||
isCheckoutFilter.value = true
|
||||
getTopSkus()
|
||||
} else if (catID == 'audit') { // 待审核商品
|
||||
isCheckoutFilter.value = true
|
||||
isAudit.value = true
|
||||
GetStoreSkuAudit()
|
||||
} else {
|
||||
categoryID.value = catID as string
|
||||
getSkuNames()
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 畅销推荐
|
||||
*/
|
||||
async function getTopSkus() {
|
||||
isLoad.value = true
|
||||
let data = {
|
||||
storeID: getStorage('storeID')
|
||||
}
|
||||
let res = await shopping.get_top_skus_by_city_code(data)
|
||||
if (res.code == 0) {
|
||||
let data = res.data || []
|
||||
if (data.length > 0) {
|
||||
totalCount.value = data.length
|
||||
skuNames.value = mapskuName(data)
|
||||
} else {
|
||||
dataHoming()
|
||||
toast('暂无畅销商品')
|
||||
}
|
||||
|
||||
} else {
|
||||
toast('分类查询错误')
|
||||
dataHoming()
|
||||
}
|
||||
isLoad.value = false
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 待审核商品
|
||||
*/
|
||||
async function GetStoreSkuAudit() {
|
||||
isLoad.value = true
|
||||
let data = {
|
||||
storeIDs: JSON.stringify([getStorage('storeID')]),
|
||||
applyTimeStart: timeFormatD(+new Date() - 1000 * 60 * 60 * 24 * 30) + ' 00:00:00',
|
||||
applyTimeEnd: timeFormatD(+new Date()) + ' 23:59:59',
|
||||
statuss: JSON.stringify([0]),
|
||||
types: JSON.stringify([1, 2]),
|
||||
offset: pageSize.value * (page.value - 1),
|
||||
pageSize: pageSize.value,
|
||||
}
|
||||
let res = await shopping.get_store_sku_audit(data)
|
||||
if (res.code == 0) {
|
||||
totalCount.value = res.data.totalCount
|
||||
let newData = res.data.data || []
|
||||
let filterSkuName = mapAuditSkuName(newData)
|
||||
skuNames.value = skuNames.value.concat(filterSkuName)
|
||||
if (newData.length == 0) return toast('暂无待审核商品')
|
||||
} else {
|
||||
toast('分类查询错误')
|
||||
dataHoming()
|
||||
}
|
||||
isLoad.value = false
|
||||
}
|
||||
|
||||
|
||||
/*************************************************
|
||||
* 过滤待审核商品
|
||||
*/
|
||||
function mapAuditSkuName(data: AnyObject) {
|
||||
let arr = data.map((item: any) => ({
|
||||
auditUnitPrice: item.unitPrice,
|
||||
unitPrice: item.originPrice,
|
||||
skuAllnoSale: false,
|
||||
nameID: item.nameID,
|
||||
img: item.img,
|
||||
unit: item.unit,
|
||||
type: item.type,
|
||||
prefix: item.prefix,
|
||||
name: item.skuName,
|
||||
}))
|
||||
return arr
|
||||
}
|
||||
|
||||
|
||||
/*************************************************
|
||||
* @info 过滤类数据
|
||||
*/
|
||||
const showMountTab = ref<boolean>(false)
|
||||
|
||||
|
||||
/*************************************************
|
||||
* 头部数据过滤
|
||||
*/
|
||||
const allSaleStatus = ref<AnyObject>()
|
||||
async function updateIsSale(data: AnyObject) {
|
||||
allSaleStatus.value = data
|
||||
data.lable == 3
|
||||
? (showMountTab.value = true)
|
||||
: (showMountTab.value = false)
|
||||
if (data.lable == 3) return
|
||||
dataHoming()
|
||||
await getSkuNames()
|
||||
}
|
||||
async function updateTowFilter(data: AnyObject) {
|
||||
if (data.lable == 3) {
|
||||
return showMountTab.value = true
|
||||
} else {
|
||||
showMountTab.value = false
|
||||
}
|
||||
if (isFilter.value == 'hot') {
|
||||
oneMenuClick(isFilter.value)
|
||||
}
|
||||
|
||||
if (isFilter.value == 'audit') {
|
||||
oneMenuClick(isFilter.value)
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* @info 搜索框操作
|
||||
*/
|
||||
async function serachShopping(text: string) {
|
||||
dataHoming()
|
||||
keyword.value = text
|
||||
await getSkuNames()
|
||||
}
|
||||
async function clearInpu() {
|
||||
dataHoming()
|
||||
keyword.value = ''
|
||||
await getSkuNames()
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 批量操作
|
||||
*/
|
||||
let picked: Array<AnyObject> = []
|
||||
function handleSale(skuName: AnyObject) {
|
||||
if (picked && picked.some((item) => item.nameID == skuName.id)) {
|
||||
picked = picked.filter((item) => {
|
||||
return item.nameID != skuName.id
|
||||
})
|
||||
} else {
|
||||
picked.push({ nameID: Number(skuName.id) })
|
||||
picked = distinct(picked, 'nameID')
|
||||
}
|
||||
}
|
||||
function distinct(arr: any, key: string) {
|
||||
let set = new Set()
|
||||
return arr.reduce(
|
||||
(p: any, c: any) => (set.has(c[key]) ? p : (set.add(c[key]), [...p, c])),
|
||||
[]
|
||||
)
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 批量可售与不可售
|
||||
*/
|
||||
let handleChangeSaleTimer: any = null
|
||||
const updateStateOk = ref<boolean>(false)
|
||||
async function handleChangeSale(type: number) {
|
||||
if (picked.length == 0) return toast('未选择商品')
|
||||
picked.forEach((item: AnyObject) => {
|
||||
item['isSale'] = type
|
||||
})
|
||||
let data = {
|
||||
storeIDs: JSON.stringify([getStorage('storeID')]),
|
||||
payload: JSON.stringify(picked),
|
||||
}
|
||||
let res = await shopping.update_stores_skus(data)
|
||||
if (res.code == 0) {
|
||||
toast('修改成功')
|
||||
let data = {
|
||||
status: -1,
|
||||
lable: 2,
|
||||
}
|
||||
updateStateOk.value = true
|
||||
handleChangeSaleTimer = setTimeout(() => {
|
||||
updateIsSale(data)
|
||||
clearTimeout(handleChangeSaleTimer)
|
||||
}, 1000)
|
||||
} else {
|
||||
toast('修改失败', 2)
|
||||
updateStateOk.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 去创建商品
|
||||
*/
|
||||
function createGoods() {
|
||||
uni.navigateTo({ url: '/subPages/shoppingChild/createGoods/createGoods' })
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 改价还是折扣(从vuex 里面读取)
|
||||
*/
|
||||
const isPointStore = computed(() => {
|
||||
return store.getters['storeInfo/isPointStore']
|
||||
})
|
||||
// skuName
|
||||
const skuName = ref<AnyObject>({
|
||||
unit: '',
|
||||
auditUnitPrice: ''
|
||||
})
|
||||
function openPriceDialog(skuNames: AnyObject) {
|
||||
skuName.value = skuNames
|
||||
popup.value.open()
|
||||
}
|
||||
// 当前修改价格
|
||||
const currentValue = ref<string>('')
|
||||
// 审核价格
|
||||
const auditUnitPrice = computed(() => {
|
||||
let price = skuName.value.auditUnitPrice
|
||||
if (price) {
|
||||
return +((price * 1) / 100).toFixed(2)
|
||||
} else {
|
||||
return +'0.00'
|
||||
}
|
||||
})
|
||||
// 弹窗实例
|
||||
const popup = ref<any>(null)
|
||||
// 确定修改价格
|
||||
function handleConfirm() {
|
||||
if (isNaN(+currentValue.value)) return toast('请输入格式正确的价格')
|
||||
if (+currentValue.value < 0.01) return toast('请输入大于等于1分钱的价格')
|
||||
if (
|
||||
currentValue.value.toString().indexOf('.') > -1 &&
|
||||
currentValue.value.toString().split('.')[1].length > 2
|
||||
) {
|
||||
return toast('最多只能有两位小数')
|
||||
}
|
||||
let updatePrice = Math.round(+currentValue.value * 100)
|
||||
if (updatePrice == skuName.value.unitPrice) {
|
||||
return toast('没有修改价格')
|
||||
}
|
||||
if (updatePrice > skuName.value.unitPrice * 1.3 ||
|
||||
updatePrice < skuName.value.unitPrice * 0.7) {
|
||||
uni.jxConfirm({
|
||||
title: '提示',
|
||||
content: `修改幅度超过30%,新价格为¥${(updatePrice / 100).toFixed(2)},是否确定修改?`,
|
||||
success: () => {
|
||||
updatePriceFn(updatePrice, skuName.value.id, skuName.value.unitPrice)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
updatePriceFn(updatePrice, skuName.value.id, skuName.value.unitPrice)
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 验证通过开始修改价格
|
||||
*/
|
||||
let updatePriceFnTimer: any = null
|
||||
async function updatePriceFn(price: string | number, id: number, originalUnitPrice: number) {
|
||||
let data = {
|
||||
storeIDs: JSON.stringify([+getStorage('storeID')]),
|
||||
payload: JSON.stringify([
|
||||
{
|
||||
nameID: skuName.value.id,
|
||||
unitPrice: price,
|
||||
},
|
||||
]),
|
||||
}
|
||||
popup.value.close() // 关闭 popup
|
||||
// 修改价格
|
||||
let updatePrice = await shopping.update_stores_skus(data)
|
||||
|
||||
if (updatePrice.code == 0) {
|
||||
// 获取单个门店serverSkuName
|
||||
let storeData = {
|
||||
storeIDs: JSON.stringify([+getStorage('storeID')]),
|
||||
isFocus: true,
|
||||
nameIDs: JSON.stringify([id]),
|
||||
fromStatus: 0,
|
||||
toStatus: 1,
|
||||
}
|
||||
const serverSkuName = await merchant.get_stores_skus(storeData)
|
||||
if (serverSkuName.code == 0) {
|
||||
let skuNameData = serverSkuName.data.skuNames || []
|
||||
if (skuNameData.length > 0) {
|
||||
let index = skuNames.value.findIndex((item: any) => item.id == id)
|
||||
if (index !== -1) skuNames.value[index] = mapskuName(skuNameData)[0]
|
||||
}
|
||||
}
|
||||
// 判断提示
|
||||
if (isPointStore.value || store.state.storeInfo.allStoreInfo.storeLevel == 'E') {
|
||||
toast('修改成功')
|
||||
currentValue.value = ''
|
||||
} else {
|
||||
currentValue.value = ''
|
||||
toast(
|
||||
+price < originalUnitPrice ? '修改成功' : '提交成功, 请等待审核'
|
||||
)
|
||||
}
|
||||
} else {
|
||||
toast('修改失败', 2)
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 修该库存或货架码
|
||||
*/
|
||||
const popupDialog = ref<any>(null)
|
||||
const skuNameItem = ref<AnyObject>({
|
||||
payload:{
|
||||
nameID:0,
|
||||
Skus:[],
|
||||
},
|
||||
name:'',
|
||||
type:'price'
|
||||
})
|
||||
const stockOrCode = ref('')
|
||||
|
||||
// 打开dialog 修改库存以及货架码
|
||||
function openDialog(payload: AnyObject) {
|
||||
skuNameItem.value = payload
|
||||
const sku = payload.payload.Skus[0]
|
||||
if(payload.type === 'stock') stockOrCode.value = sku.stock + ''
|
||||
if(payload.type === 'locationCode') stockOrCode.value = sku.locationCode
|
||||
popupDialog.value.open()
|
||||
}
|
||||
async function sureStockOrCode() {
|
||||
const nameID = skuNameItem.value.payload.nameID
|
||||
const skuID = skuNameItem.value.payload.Skus[0].skuID
|
||||
let data:AnyObject = {
|
||||
storeIDs: JSON.stringify([+getStorage('storeID')])
|
||||
}
|
||||
if(skuNameItem.value.type === 'stock') {
|
||||
data.payload = JSON.stringify([{
|
||||
nameID: nameID,
|
||||
Skus:[
|
||||
{
|
||||
skuID: skuID,
|
||||
stock: +stockOrCode.value
|
||||
}
|
||||
]
|
||||
}])
|
||||
}else{
|
||||
data.payload = JSON.stringify([{
|
||||
nameID: nameID,
|
||||
Skus:[
|
||||
{
|
||||
skuID:skuID,
|
||||
locationCode: ''+ stockOrCode.value ? '' + stockOrCode.value : 'EMPTY_VALUE'
|
||||
}
|
||||
]
|
||||
}])
|
||||
}
|
||||
popupDialog.value.close() // 关闭 popupDialog
|
||||
let res = await shopping.update_stores_skus(data)
|
||||
if (res.code == 0) {
|
||||
let storeData = {
|
||||
storeIDs: JSON.stringify([+getStorage('storeID')]),
|
||||
isFocus: true,
|
||||
nameIDs: JSON.stringify([skuNameItem.value.payload.nameID]),
|
||||
fromStatus: 0,
|
||||
toStatus: 1,
|
||||
}
|
||||
const serverSkuName = await merchant.get_stores_skus(storeData)
|
||||
if (serverSkuName.code == 0) {
|
||||
let skuNameData = serverSkuName.data.skuNames || []
|
||||
if (skuNameData.length > 0) {
|
||||
let index = skuNames.value.findIndex((item: any) => item.id == skuNameItem.value.payload.nameID)
|
||||
if (index !== -1) {
|
||||
skuNames.value[index] = mapskuName(skuNameData)[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
toast('修改成功')
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 删除商品
|
||||
*/
|
||||
function handleDelete() {
|
||||
uni.jxConfirm({
|
||||
title: '提示',
|
||||
content: `确认删除《${skuName.value.name}》吗?`,
|
||||
confirmText: '确认',
|
||||
success: async () => {
|
||||
popup.value.close() // 关闭 popup
|
||||
let data = {
|
||||
storeIDs: JSON.stringify([getStorage('storeID')]),
|
||||
payload: JSON.stringify([{ nameID: skuName.value.id, isFocus: -1 }]),
|
||||
}
|
||||
let res = await shopping.update_stores_skus(data)
|
||||
if (res.code == 0) {
|
||||
toast('删除成功')
|
||||
skuNames.value = skuNames.value.filter((item) => item.id != skuName.value.id)
|
||||
if (skuNames.value.length == 0) return dataHoming()
|
||||
} else {
|
||||
toast('删除失败', 2)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
const toExamineData = ref<AnyObject>({}) // 审核商品数据
|
||||
const toExaminePopup = ref<any>(null) // 审核弹窗实例
|
||||
const toExamineValue = ref<string | number>('') // 审核输入框
|
||||
/*************************************************
|
||||
* 审核商品
|
||||
*/
|
||||
function toExamine(res: AnyObject) {
|
||||
toExamineData.value = res
|
||||
if (res.status == 1) {
|
||||
toExamineValue.value = res.auditPrice / 100
|
||||
} else {
|
||||
toExamineValue.value = ''
|
||||
}
|
||||
toExaminePopup.value.open()
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 改价审核操作
|
||||
*/
|
||||
async function toExamineConfirm() {
|
||||
toExaminePopup.value.close()
|
||||
let data = {
|
||||
status: toExamineData.value.status,
|
||||
isAsync: false,
|
||||
isContinueWhenError: true,
|
||||
payload: JSON.stringify([{
|
||||
storeID: toExamineData.value.storeID,
|
||||
nameID: toExamineData.value.nameID,
|
||||
...(toExamineData.value.status == 1
|
||||
? { auditPrice: Math.floor(+toExamineValue.value * 100) }
|
||||
: { remark: toExamineValue.value })
|
||||
}])
|
||||
}
|
||||
let res = await shopping.store_sku_price_audit(data)
|
||||
if (res.code == 0) {
|
||||
toast('操作成功')
|
||||
skuNames.value = skuNames.value.filter((item) => item.nameID != toExamineData.value.nameID)
|
||||
if (skuNames.value.length == 0) return dataHoming()
|
||||
} else {
|
||||
toast(res.desc || res.data)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************************
|
||||
* 善后工作
|
||||
*/
|
||||
onBeforeUnmount(() => {
|
||||
clearTimeout(handleChangeSaleTimer)
|
||||
clearTimeout(updatePriceFnTimer)
|
||||
clearTimeout(onPullDownRefreshTimer)
|
||||
})
|
||||
|
||||
return {
|
||||
dafauleData, // 左侧tablist 数据
|
||||
totalCount, // 商品总条数
|
||||
skuNames, // 商品列表数据
|
||||
skuNameItem, // 商品数据2
|
||||
isAudit, // 商品列表判断条件
|
||||
isHot, // 商品列表判断条件
|
||||
showMountTab, // 批量操作判断
|
||||
scrolltolower, // 页面触底
|
||||
isLoad, // 加载动画
|
||||
updateIsSale, // 过滤筛选
|
||||
updateTowFilter, // 过滤筛选
|
||||
serachShopping, // 搜索框确定
|
||||
clearInpu, // 清空搜索框
|
||||
oneMenuClick, // 一级菜单点击事件
|
||||
isCheckoutFilter, // 切换过滤选项
|
||||
isFilter, // 判断条件
|
||||
handleSale, // 批量可售与不可售
|
||||
handleChangeSale, // 批量可售与不可售
|
||||
updateStateOk, // 批量操作成功
|
||||
createGoods, // 去创建商品
|
||||
isPointStore, // 判断扣点还是折扣
|
||||
skuName, // 当前修改的价格
|
||||
auditUnitPrice, // 正在审核的价格
|
||||
currentValue, // 当前修改价格
|
||||
popup, // 弹窗实例
|
||||
stockOrCode, // stock locationCode
|
||||
popupDialog, // 弹窗 stock locationCode
|
||||
handleConfirm, // 确定修改价格
|
||||
openPriceDialog, // 获取修改数据
|
||||
openDialog, // 获取修改数据2
|
||||
sureStockOrCode, // 确认框 stock locationCode
|
||||
handleDelete, // 删除商品
|
||||
refresherrefresh, // 下拉刷新
|
||||
triggered, // 下拉刷新标识
|
||||
leftBarRef, // 右侧导航栏实例
|
||||
toExamine, // 审核商品
|
||||
toExamineData, // 审核商品数据
|
||||
toExaminePopup, // 改价审核实例
|
||||
toExamineConfirm, // 确定操作审核
|
||||
toExamineValue, // 审核输入内容
|
||||
}
|
||||
}
|
||||
|
||||
export default shoppingMangerFn
|
||||
244
src/pages/goods-manager/main.vue
Normal file
244
src/pages/goods-manager/main.vue
Normal file
@@ -0,0 +1,244 @@
|
||||
<template>
|
||||
<view>
|
||||
<shopping-search
|
||||
class="shopping-cel"
|
||||
:isFilter="isFilter"
|
||||
@serachShopping="serachShopping"
|
||||
@clearInpu="clearInpu"
|
||||
@createGoods="createGoods"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view class="main-center-root">
|
||||
<view class="left-bar-root">
|
||||
<scroll-view scroll-y style="height: calc(100vh - 92rpx)">
|
||||
<left-bar
|
||||
ref="leftBarRef"
|
||||
:dafauleData="dafauleData"
|
||||
@oneMenuClick="oneMenuClick"
|
||||
/>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view class="right-center">
|
||||
<shopping-filter
|
||||
@updateIsSale="updateIsSale"
|
||||
@updateTowFilter="updateTowFilter"
|
||||
:isCheckoutFilter="isCheckoutFilter"
|
||||
:updateStateOk="updateStateOk"
|
||||
/>
|
||||
|
||||
<scroll-view
|
||||
scroll-y
|
||||
style="height: calc(100vh - 182rpx)"
|
||||
refresher-enabled
|
||||
:refresher-triggered="triggered"
|
||||
@scrolltolower="scrolltolower"
|
||||
@refresherrefresh="refresherrefresh"
|
||||
>
|
||||
<right-main
|
||||
v-for="item in skuNames"
|
||||
:key="item.id"
|
||||
:skuName="item"
|
||||
:isAudit="isAudit"
|
||||
:isHot="isHot"
|
||||
:showMountTab="showMountTab"
|
||||
@handleSale="handleSale"
|
||||
@openPriceDialog="openPriceDialog"
|
||||
@openDialog="openDialog"
|
||||
@toExamine="toExamine"
|
||||
/>
|
||||
<jx-load-more
|
||||
v-show="totalCount >= 4"
|
||||
:isLoad="isLoad"
|
||||
tip="没有更多商品了"
|
||||
/>
|
||||
<jx-empty
|
||||
class="jx-empty"
|
||||
v-show="totalCount == 0"
|
||||
title="该分类暂无商品"
|
||||
>
|
||||
<view class="createGoods" @tap="createGoods">去创建商品</view>
|
||||
</jx-empty>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="showMountTab" class="MountWrap">
|
||||
<view class="btn onActive" @tap="handleChangeSale(1)">可售</view>
|
||||
<view class="btn onActive" @tap="handleChangeSale(-1)">不可售</view>
|
||||
</view>
|
||||
|
||||
<!-- 修改价格 -->
|
||||
<uni-popup ref="popup" type="top">
|
||||
<view class="jx-popup-update">
|
||||
<text class="text">{{ isPointStore ? '改价' : '提交改价审核' }}</text>
|
||||
<view class="tip">
|
||||
当前价格每<text style="color: #f60d58">{{
|
||||
skuName.unit === '份' ? '斤' : skuName.unit
|
||||
}}</text
|
||||
>:
|
||||
<jx-price :price="skuName.unitPrice" color="#4eb331" />
|
||||
</view>
|
||||
<view class="tip audit" v-if="auditUnitPrice > 0">
|
||||
正在审核:¥<text>{{ auditUnitPrice }}</text>
|
||||
</view>
|
||||
<input
|
||||
class="ipt"
|
||||
type="digit"
|
||||
v-model="currentValue"
|
||||
placeholder="请输入修改价格"
|
||||
/>
|
||||
|
||||
<view class="btn-root">
|
||||
<view class="btn-esc" @tap="popup.close()">取消</view>
|
||||
<view class="btn-ok" @tap="handleConfirm">确定修改</view>
|
||||
</view>
|
||||
|
||||
<view class="delete">
|
||||
<view class="delete-text" @tap="handleDelete"
|
||||
>删除《{{ skuName.name }}》</view
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
|
||||
<!-- 审核商品 -->
|
||||
<uni-popup ref="toExaminePopup" type="top">
|
||||
<view class="jx-popup-update">
|
||||
<text class="text">{{
|
||||
toExamineData.status == 1 ? '同意申请' : '拒绝申请'
|
||||
}}</text>
|
||||
<view class="tip audit"
|
||||
>商户申请价格:¥{{ toExamineData.auditPrice / 100 }}</view
|
||||
>
|
||||
<input
|
||||
class="ipt"
|
||||
type="digit"
|
||||
v-model="toExamineValue"
|
||||
:placeholder="
|
||||
toExamineData.status == 1 ? '请输入审核价格' : '请输入拒绝原因'
|
||||
"
|
||||
/>
|
||||
<view class="btn-root">
|
||||
<view class="btn-esc" @tap="toExaminePopup.close()">取消</view>
|
||||
<view class="btn-ok" @tap="toExamineConfirm">确定</view>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
|
||||
<!-- 修改库存以及商品 -->
|
||||
<uni-popup ref="popupDialog" type="top">
|
||||
<view class="jx-popup-update" >
|
||||
<view class="text">
|
||||
{{ skuNameItem.type === 'stock' ? '修改库存' : '修改货架码' }}
|
||||
</view>
|
||||
<view class="tip-new">{{ skuNameItem.name }}</view>
|
||||
<view class="ipt-box">
|
||||
<input
|
||||
class="ipt"
|
||||
:type="skuNameItem.type === 'stock' ? 'number' : 'text'"
|
||||
v-model="stockOrCode"
|
||||
:placeholder="
|
||||
skuNameItem.type === 'stock' ? '请输入商品库存' : '请输入商品货架码'
|
||||
"
|
||||
/>
|
||||
</view>
|
||||
<view class="btn-root">
|
||||
<view class="btn-esc" @tap="popupDialog.close()">取消</view>
|
||||
<view class="btn-ok" @tap="sureStockOrCode">确定</view>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
|
||||
<!-- 公共组件 -->
|
||||
<jx-loading />
|
||||
<jx-login-empty title="马上登录,管理商品" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import shoppingSearch from './childPages/shopping-search/shopping-search.vue'
|
||||
import leftBar from './component/left-bar/left-bar.vue'
|
||||
import rightMain from './childPages/right-main/right-main.vue'
|
||||
import shoppingFilter from './childPages/shopping-filter/shopping-filter.vue'
|
||||
import shoppingMangerFn from './main'
|
||||
const {
|
||||
dafauleData, // 左侧tablit数据
|
||||
totalCount, // 商品总条数
|
||||
skuNames, // 商品列表数据
|
||||
skuNameItem, // 商品数据2
|
||||
isAudit, // 商品列表判断条件
|
||||
isHot, // 商品列表判断条件
|
||||
showMountTab, // 批量操作判断
|
||||
scrolltolower, // 页面触底
|
||||
isLoad, // 加载动画
|
||||
updateIsSale, // 过滤筛选
|
||||
updateTowFilter, // 过滤筛选
|
||||
serachShopping, // 搜索框确定
|
||||
clearInpu, // 清空搜索框
|
||||
oneMenuClick, // 一级菜单点击事件
|
||||
isCheckoutFilter, // 切换过滤选项
|
||||
isFilter, // 判断条件
|
||||
handleSale, // 批量可售与不可售
|
||||
handleChangeSale, // 批量可售与不可售
|
||||
updateStateOk, // 批量操作成功
|
||||
createGoods, // 去创建商品
|
||||
isPointStore, // 判断扣点还是折扣
|
||||
skuName, // 当前修改的价格
|
||||
auditUnitPrice, // 正在审核的价格
|
||||
currentValue, // 当前修改价格
|
||||
popup, // 弹窗实例
|
||||
stockOrCode, // stock locationCode
|
||||
popupDialog, // 弹窗 stock locationCode
|
||||
handleConfirm, // 确定修改价格
|
||||
openPriceDialog, // 获取修改数据
|
||||
openDialog, // 获取修改数据2
|
||||
sureStockOrCode, // 确认框 stock locationCode
|
||||
handleDelete, // 删除商品
|
||||
refresherrefresh, // 下拉刷新
|
||||
triggered, // 下拉刷新标识
|
||||
leftBarRef, // 右侧导航栏实例
|
||||
toExamine, // 审核商品
|
||||
toExamineData, // 审核商品数据
|
||||
toExaminePopup, // 改价审核实例
|
||||
toExamineConfirm, // 确定操作审核
|
||||
toExamineValue, // 审核输入内容
|
||||
} = shoppingMangerFn()
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #fff;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './main.scss';
|
||||
|
||||
.shopping-cel {
|
||||
:deep(.uni-searchbar) {
|
||||
padding: 0 !important;
|
||||
width: 610rpx !important;
|
||||
height: 70rpx;
|
||||
|
||||
.uni-searchbar__box {
|
||||
border-radius: 7rpx !important;
|
||||
height: auto !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.main-center-root {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.left-bar-root {
|
||||
width: 200rpx;
|
||||
box-shadow: 0rpx 10rpx 10rpx rgb(207, 207, 207);
|
||||
}
|
||||
|
||||
.right-center {
|
||||
width: calc(100vw - 200rpx);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
189
src/pages/merchant/index.ts
Normal file
189
src/pages/merchant/index.ts
Normal file
@@ -0,0 +1,189 @@
|
||||
|
||||
import { computed, onBeforeUnmount, ref } from 'vue'
|
||||
import { timeFormatD } from '@/utils/tools'
|
||||
import { getStorage, setStorage } from '@/utils/storage'
|
||||
import { onLoad, onPullDownRefresh } from '@dcloudio/uni-app'
|
||||
import merchant from '@/api/https/merchant'
|
||||
import { store } from '@/store'
|
||||
import useGlobalFunc from '@/composables/useGlobalFunc'
|
||||
import log from '@/utils/log'
|
||||
|
||||
/*************************************************
|
||||
* 商家中心
|
||||
*/
|
||||
const merchantFn = function () {
|
||||
const { getMtStoreIMStatus } = useGlobalFunc()
|
||||
/*************************************************
|
||||
* 下拉刷新
|
||||
*/
|
||||
let onPullDownRefreshTimer: any = null
|
||||
onPullDownRefresh(() => {
|
||||
clearTimeout(onPullDownRefreshTimer)
|
||||
onPullDownRefreshTimer = setTimeout(async () => {
|
||||
if (!getStorage('token')) return
|
||||
store.commit('storeInfo/jxLoadingFn', true)
|
||||
await getSaleInfo()
|
||||
await getStoreVendorMaps(-1)
|
||||
await getMtStoreIMStatus() // 获取美团门店的IM状态
|
||||
uni.stopPullDownRefresh()
|
||||
clearTimeout(onPullDownRefreshTimer)
|
||||
store.commit('storeInfo/jxLoadingFn', false)
|
||||
}, 500)
|
||||
})
|
||||
|
||||
|
||||
/*************************************************
|
||||
* 页面加载获取数据
|
||||
*/
|
||||
const popup = ref<any>(null)
|
||||
onLoad(async (params) => {
|
||||
// 订单管理-新订单通知
|
||||
let logData = {
|
||||
'日志记录时间': Date(),
|
||||
'启动类型': '订单管理',
|
||||
'启动参数': params,
|
||||
'用户TOKEN': getStorage('token') ? getStorage('token') : '未获取到用户TOKEN',
|
||||
'用户手机号': getStorage('mobile') ? getStorage('mobile') : '未获取到用户手机号',
|
||||
'店铺ID': getStorage('storeID') ? getStorage('storeID') : '未获取到店铺ID',
|
||||
'店铺名字': getStorage('storeName') ? getStorage('storeName') : '未获取到店铺名字',
|
||||
}
|
||||
log.info(JSON.stringify(logData))
|
||||
|
||||
if (!getStorage('token')) return
|
||||
store.commit('storeInfo/jxLoadingFn', true)
|
||||
await getStoreVendorMaps(-1)
|
||||
await getSaleInfo()
|
||||
store.commit('storeInfo/jxLoadingFn', false)
|
||||
if (getStorage('isDownApp') != 'true') {
|
||||
setTimeout(() => {
|
||||
popup.value.open()
|
||||
}, 800)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const saleInfo = ref({
|
||||
earningPrice: 0,
|
||||
count: 0,
|
||||
})
|
||||
|
||||
/*************************************************
|
||||
* 获取今日营业数据
|
||||
*/
|
||||
async function getSaleInfo() {
|
||||
let fromTime = `${timeFormatD()} 00:00:00`
|
||||
let toTime = `${timeFormatD()} 23:59:59`
|
||||
let data = {
|
||||
storeIDs: `[${parseInt(getStorage('storeID'))}]`,
|
||||
fromTime,
|
||||
toTime,
|
||||
statuss:JSON.stringify([110]) // 只统计已完成的订单,不包含取消单
|
||||
}
|
||||
await merchant.get_store_order_sale_info(data).then((res) => {
|
||||
let json = {
|
||||
earningPrice: 0,
|
||||
shopPrice: 0,
|
||||
realEarningPrice: 0,
|
||||
count: 0,
|
||||
actualPayPrice: 0,
|
||||
actualFee: 0
|
||||
}
|
||||
if (res.code == 0) {
|
||||
let data = res.data || []
|
||||
|
||||
data.forEach((item: AnyObject) => {
|
||||
if (item.status === 110) {
|
||||
json.actualPayPrice += item.actualPayPrice
|
||||
json.realEarningPrice += item.realEarningPrice
|
||||
json.earningPrice += item.earningPrice
|
||||
json.shopPrice += item.shopPrice
|
||||
json.count += item.count
|
||||
json.actualFee += item.actualFee
|
||||
}
|
||||
})
|
||||
json.actualFee = +(json.actualFee / 100).toFixed(2)
|
||||
saleInfo.value = json
|
||||
} else {
|
||||
saleInfo.value = json
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/*************************************************
|
||||
* 获取门店信息数据
|
||||
*/
|
||||
const _vendorPayPercentage = ref<number>(0)
|
||||
const isNotQuote = ref<boolean>(true)
|
||||
const isZero = ref<boolean>(true)
|
||||
const isUpperfif = ref<boolean>(false)
|
||||
const isShowShop = ref<boolean>(false)
|
||||
async function getStoreVendorMaps(vendorID: number) {
|
||||
let data = {
|
||||
storeID: getStorage('storeID'),
|
||||
vendorID: vendorID
|
||||
}
|
||||
let res = await merchant.get_store_vendor_maps(data)
|
||||
if (res.code == 0) {
|
||||
let data = res.data
|
||||
_vendorPayPercentage.value = data[0].vendorPayPercentage
|
||||
isNotQuote.value = true
|
||||
isNotQuote.value = data.some((item: AnyObject) => {
|
||||
return item.vendorPayPercentage != 0 && item.vendorPayPercentage <= 50
|
||||
})
|
||||
isZero.value = data.every((item: AnyObject) => {
|
||||
return item.vendorPayPercentage == 0
|
||||
})
|
||||
isUpperfif.value = data.every((item: AnyObject) => {
|
||||
return item.vendorPayPercentage > 50
|
||||
})
|
||||
if (isNotQuote.value) {
|
||||
isShowShop.value = data.every((v: AnyObject) => {
|
||||
return v.vendorPayPercentage > 50
|
||||
})
|
||||
}
|
||||
} else {
|
||||
_vendorPayPercentage.value = 0
|
||||
}
|
||||
}
|
||||
|
||||
function getMsg() {
|
||||
uni.removeTabBarBadge({ index: 3 })
|
||||
store.commit('storeInfo/setIsNewMessage', false)
|
||||
uni.navigateTo({
|
||||
url: '/subPages/merchantChild/message/message',
|
||||
})
|
||||
}
|
||||
|
||||
const isMsg = computed(() => {
|
||||
return store.state.storeInfo.isNewMessage
|
||||
})
|
||||
|
||||
function closeDownApp() {
|
||||
setStorage('isDownApp', 'true')
|
||||
popup.value.close()
|
||||
}
|
||||
|
||||
|
||||
/*************************************************
|
||||
* 做收尾工作
|
||||
*/
|
||||
onBeforeUnmount(() => {
|
||||
clearTimeout(onPullDownRefreshTimer)
|
||||
})
|
||||
|
||||
return {
|
||||
saleInfo, // 今日订单数据
|
||||
_vendorPayPercentage, // 供应商百分比
|
||||
isShowShop, // 是否为出售金额
|
||||
isNotQuote,
|
||||
isZero,
|
||||
isUpperfif,
|
||||
getMsg,
|
||||
isMsg,
|
||||
popup,
|
||||
closeDownApp,
|
||||
}
|
||||
}
|
||||
|
||||
export default merchantFn
|
||||
156
src/pages/merchant/index.vue
Normal file
156
src/pages/merchant/index.vue
Normal file
@@ -0,0 +1,156 @@
|
||||
<template>
|
||||
<!-- 用户信息 -->
|
||||
<user-info />
|
||||
|
||||
<!-- 实时订单数据 -->
|
||||
<order-data
|
||||
:showMore="true"
|
||||
:saleInfo="saleInfo"
|
||||
:_vendorPayPercentage="_vendorPayPercentage"
|
||||
:isShowShop="isShowShop"
|
||||
:isNotQuote="isNotQuote"
|
||||
:isZero="isZero"
|
||||
:isUpperfif="isUpperfif"
|
||||
:isOut="true"
|
||||
/>
|
||||
|
||||
<!-- 选项内容 -->
|
||||
<options />
|
||||
|
||||
<!-- 新信息 -->
|
||||
<view class="new-msg" v-if="isMsg" @tap="getMsg">
|
||||
<image
|
||||
class="img"
|
||||
src="https://image.jxc4.com/image/e17593d0abe4daa160a9d67f46732f7b.png"
|
||||
mode="scaleToFill"
|
||||
/>
|
||||
<view class="msg">
|
||||
<view class="title">新系统消息</view>
|
||||
<view>请查收您的系统信息</view>
|
||||
</view>
|
||||
<view class="btn">立即查看</view>
|
||||
</view>
|
||||
|
||||
<!-- 下载App -->
|
||||
<uni-popup ref="popup" type="center">
|
||||
<view class="down-app-root">
|
||||
<uni-title type="h2" title="菜市商家App上线" align="center" />
|
||||
<view class="info"
|
||||
>京西菜市商家版App全新上架,系统更加稳定,功能更加齐全,订单通知更加及时,请往手机自带应用商店搜索【京西菜市】进行安装使用!</view
|
||||
>
|
||||
<uni-title type="h3" title="苹果搜索【京西菜市】" />
|
||||
<image
|
||||
class="img"
|
||||
src="https://image.jxc4.com/image/a9879811d0bebfa8fd9d25240fccbcde.tem.jpg"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<uni-title type="h3" title="安卓搜索【京西菜市】" />
|
||||
<image
|
||||
class="img"
|
||||
src="https://image.jxc4.com/image/b77cc513274b89da69a9119fef43c24e.tem.jpg"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<view class="btn" @tap="closeDownApp">我知道了</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
|
||||
<!-- 公共组件 -->
|
||||
<jx-loading />
|
||||
|
||||
<!-- 未登录无网络 -->
|
||||
<jx-login-empty title="马上登录,开始使用" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import userInfo from './userInfo/userInfo.vue'
|
||||
import orderData from './orderData/orderData.vue'
|
||||
import options from './options/options.vue'
|
||||
import merchantFn from './index'
|
||||
const {
|
||||
saleInfo, //今日订单数据
|
||||
_vendorPayPercentage, // 供应商百分比
|
||||
isShowShop, // 是否为出售金额
|
||||
isNotQuote,
|
||||
isZero,
|
||||
isUpperfif,
|
||||
getMsg,
|
||||
popup,
|
||||
isMsg,
|
||||
closeDownApp,
|
||||
} = merchantFn()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.new-msg {
|
||||
position: fixed;
|
||||
bottom: 20rpx;
|
||||
left: 20rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10rpx 20rpx;
|
||||
width: 710rpx;
|
||||
overflow: hidden;
|
||||
background-color: rgba($color: #000000, $alpha: 0.65);
|
||||
color: #fff;
|
||||
border-radius: 15rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.img {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
}
|
||||
|
||||
.msg {
|
||||
.title {
|
||||
font-weight: bold;
|
||||
font-size: 35rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 7rpx 22rpx;
|
||||
border-radius: 50rpx;
|
||||
background-image: linear-gradient(135deg, #f72a6c, #f16692);
|
||||
animation: btnANimation 1s ease-in-out infinite alternate;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes btnANimation {
|
||||
0% {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
}
|
||||
|
||||
.down-app-root {
|
||||
background-color: #fff;
|
||||
width: 600rpx;
|
||||
box-sizing: border-box;
|
||||
padding: 25rpx 35rpx;
|
||||
border-radius: 20rpx;
|
||||
|
||||
.info {
|
||||
font-size: 28rpx;
|
||||
color: rgb(146, 146, 146);
|
||||
}
|
||||
|
||||
.img {
|
||||
width: 100%;
|
||||
margin-bottom: 25rpx;
|
||||
border-radius: 5rpx;
|
||||
box-shadow: 0 0 5rpx rgb(199, 199, 199);
|
||||
}
|
||||
|
||||
.btn {
|
||||
background: linear-gradient(0, #7ecf68, #51b535);
|
||||
color: #fff;
|
||||
padding: 15rpx 0;
|
||||
border-radius: 100rpx;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
106
src/pages/merchant/options/options.scss
Normal file
106
src/pages/merchant/options/options.scss
Normal file
@@ -0,0 +1,106 @@
|
||||
.options-root {
|
||||
background-color: #fff;
|
||||
margin-top: 20rpx;
|
||||
box-sizing: border-box;
|
||||
padding: 20rpx;
|
||||
|
||||
:deep(.popupAnimation) {
|
||||
z-index: 1000000;
|
||||
}
|
||||
|
||||
.grid-item-box {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.image {
|
||||
width: 75rpx;
|
||||
height: 75rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
|
||||
// ************* 角标内容 ************
|
||||
// 我的账单
|
||||
.bill-new {
|
||||
position: absolute;
|
||||
top: 15rpx;
|
||||
right: 15rpx;
|
||||
background-color: $jx-warring;
|
||||
color: #fff;
|
||||
font-size: 24rpx;
|
||||
padding: 0 15rpx 5rpx 15rpx;
|
||||
border-radius: 20rpx;
|
||||
animation: bill-new-animation 0.5s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
// 消息通知
|
||||
.msg-count {
|
||||
position: absolute;
|
||||
top: 20rpx;
|
||||
right: 35rpx;
|
||||
color: #fff;
|
||||
background-color: $jx-warring;
|
||||
font-size: 24rpx;
|
||||
min-width: 18rpx;
|
||||
min-height: 20rpx;
|
||||
line-height: 20rpx;
|
||||
text-align: center;
|
||||
line-height: 1;
|
||||
padding: 4rpx 8rpx 5rpx 8rpx;
|
||||
border-radius: 100rpx;
|
||||
}
|
||||
|
||||
// 差评管理
|
||||
.evaluate-number {
|
||||
position: absolute;
|
||||
top: 20rpx;
|
||||
right: 30rpx;
|
||||
color: #fff;
|
||||
background-color: $jx-warring;
|
||||
font-size: 24rpx;
|
||||
line-height: 1;
|
||||
padding: 4rpx 8rpx 5rpx 8rpx;
|
||||
border-radius: 100rpx;
|
||||
min-width: 30rpx;
|
||||
text-align: center;
|
||||
max-height: 35rpx;
|
||||
}
|
||||
|
||||
// 发现新版本
|
||||
.newVarsion {
|
||||
position: absolute;
|
||||
top: 15rpx;
|
||||
right: 30rpx;
|
||||
display: inline-block;
|
||||
background-color: $jx-warring;
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
border-radius: 50%;
|
||||
font-size: 24rpx;
|
||||
line-height: 30rpx;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
padding: 5rpx;
|
||||
animation: bill-new-animation 0.5s ease-in-out infinite alternate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@keyframes bill-new-animation {
|
||||
0% {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
}
|
||||
316
src/pages/merchant/options/options.ts
Normal file
316
src/pages/merchant/options/options.ts
Normal file
@@ -0,0 +1,316 @@
|
||||
/**
|
||||
* options 选项
|
||||
*/
|
||||
import toast from "@/utils/toast"
|
||||
import { store } from '@/store'
|
||||
import { timeFormatD } from "@/utils/tools"
|
||||
import { getStorage } from "@/utils/storage"
|
||||
import { onLoad, onPullDownRefresh } from "@dcloudio/uni-app"
|
||||
import { Ref, ref, onBeforeUnmount,watch } from "vue"
|
||||
import merchant from '@/api/https/merchant'
|
||||
import order from "@/api/https/order"
|
||||
|
||||
function options() {
|
||||
/**
|
||||
* 进入群聊
|
||||
*/
|
||||
function getGroupChat() {
|
||||
uni.navigateTo({
|
||||
url: '/subPages/merchantChild/enterGroupChat/enterGroupChat',
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 注册时间
|
||||
*/
|
||||
async function getSelfInfo() {
|
||||
let infoRes = await merchant.get_self_info()
|
||||
if (infoRes.code == 0) {
|
||||
let time1 = Math.floor((+new Date() - +new Date(infoRes.data.createdAt)) / 1000 / 24 / 3600)
|
||||
let time2 = Math.floor((+new Date() - +new Date(store.state.storeInfo.createStoreTimer)) / 1000 / 24 / 3600)
|
||||
uni.jxAlert({
|
||||
title: '回首过往',
|
||||
content: `门店ID:${getStorage('storeID')}\r\n\r\n您注册于${timeFormatD(infoRes.data.createdAt)}\r\n来到京西${time1}天\r\n\r\n门店创建于${timeFormatD(store.state.storeInfo.createStoreTimer)}\r\n在平台经营${time2}天`
|
||||
})
|
||||
} else toast('注册数据异常', 2)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 物料申请
|
||||
*/
|
||||
function moveToWM() {
|
||||
if (store.state.storeInfo.allStoreInfo.packageSwitch === 1) {
|
||||
let tel = store.state.storeInfo.allStoreInfo.marketManPhone ? store.state.storeInfo.allStoreInfo.marketManPhone : "18048531223"
|
||||
uni.jxAlert({
|
||||
title: '物料申请',
|
||||
content: `非常抱歉,无法进入物料商城,请联系运营${tel}`
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (store.state.storeInfo.storeStatus === -2) {
|
||||
uni.jxAlert({
|
||||
title: '物料申请',
|
||||
content: '门店已被禁用,请联系运营'
|
||||
})
|
||||
}
|
||||
|
||||
uni.navigateToMiniProgram({
|
||||
appId: 'wx4b5930c13f8b1170',
|
||||
path: `pages/index/index?storeID=666666&fromStoreID=${getStorage('storeID')}&storeType=c4`,
|
||||
success: (res) => {
|
||||
toast('即将进入京西菜市')
|
||||
},
|
||||
fail: (err) => {
|
||||
toast('取消申请')
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询是否有新账单
|
||||
*/
|
||||
onLoad(async () => {
|
||||
await handleMsg()
|
||||
await tmpGetJxBadCommentsNo()
|
||||
await getMessageData()
|
||||
})
|
||||
// 处理新账单
|
||||
const billUrl: Ref<string | undefined | object[]> = ref('')
|
||||
const newBillShow: Ref<boolean> = ref(false) // 是否有新帐单
|
||||
function handleMsg() {
|
||||
getStoreBills((url: Array<object> | string) => {
|
||||
if (typeof (url) == 'string') {
|
||||
billUrl.value = url
|
||||
// 保存新账单url地址 (存vuex)
|
||||
store.commit('serveInfo/setOrderUrl', url)
|
||||
|
||||
// 查询本地账单地址
|
||||
if (getStorage('newBillUrl') !== billUrl.value) {
|
||||
// 有新账单
|
||||
newBillShow.value = true
|
||||
} else {
|
||||
// 没有新帐单
|
||||
newBillShow.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
// 查询新订单
|
||||
interface BillListType {
|
||||
billName: string
|
||||
billTitle: string
|
||||
date: string
|
||||
id: number
|
||||
shopName: string
|
||||
storeId: string
|
||||
url: string
|
||||
}
|
||||
const billList = ref<Array<BillListType>>([])
|
||||
async function getStoreBills(fn: Function) {
|
||||
let data = {
|
||||
storeID: getStorage('storeID')
|
||||
}
|
||||
let newOrderRes = await merchant.get_store_bills(data)
|
||||
if (newOrderRes.code == 0) {
|
||||
let newMsg: Array<object> | string = []
|
||||
if (newOrderRes.data != null) {
|
||||
billList.value = newOrderRes.data.slice(0, 5)
|
||||
billList.value = billList.value.map((bill) => {
|
||||
let time = bill.date
|
||||
bill.date = timeFormatD(time)
|
||||
return bill
|
||||
})
|
||||
newMsg = newOrderRes.data[0].url.trim()
|
||||
fn && fn(newMsg)
|
||||
} else {
|
||||
billList.value = []
|
||||
fn && fn(newMsg)
|
||||
}
|
||||
} else {
|
||||
toast('账单数据异常', 2)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 是否有新信息
|
||||
*/
|
||||
const msgCount = ref<number>(0)
|
||||
async function getMessageData() {
|
||||
let data = {
|
||||
storeIDs: JSON.stringify([+getStorage('storeID')]),
|
||||
fromReadCount: 0,
|
||||
toReadCount: 0,
|
||||
offset: 0,
|
||||
pageSize: -1,
|
||||
fromTime:
|
||||
timeFormatD(+new Date() - 7 * 24 * 60 * 60 * 1000) + ' 00:00:00',
|
||||
toTime: timeFormatD(+new Date()) + ' 23:59:59',
|
||||
}
|
||||
let msgRes = await merchant.Get_store_message_statuses(data)
|
||||
if (msgRes.code == 0) {
|
||||
msgCount.value = msgRes.data.totalCount
|
||||
} else {
|
||||
toast('消息数据异常')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取差评数量
|
||||
*/
|
||||
let badCommentCount: Ref<number | string> = ref(0)
|
||||
async function tmpGetJxBadCommentsNo() {
|
||||
let data = {
|
||||
jxStoreId: getStorage('storeID')
|
||||
}
|
||||
let evaluateMRes = await merchant.tmp_get_jx_bad_comments_no(data)
|
||||
if (evaluateMRes.code == 0) {
|
||||
badCommentCount.value = evaluateMRes.data ? evaluateMRes.data : 0
|
||||
} else toast('差评数据异常', 2)
|
||||
}
|
||||
|
||||
watch(() => store.getters['storeInfo/imMtStatus'],
|
||||
(val) => {
|
||||
if(val && val.length>0) getInvoiceInfo('mt')
|
||||
})
|
||||
|
||||
/**
|
||||
* 发票数量 美团
|
||||
*/
|
||||
const invoiceCount:Ref<number | string> = ref(0)
|
||||
async function getInvoiceInfo(type:string,ebStore?:any) {
|
||||
if(type === 'mt'){
|
||||
// 美团们门店
|
||||
if(store.getters['storeInfo/imMtStatus'] && store.getters['storeInfo/imMtStatus'].length>0) {
|
||||
let data:AnyObject = {
|
||||
storeId: getStorage('storeID'),
|
||||
startTime: `${timeFormatD(+new Date() - 7 * 24 * 60 * 60 * 1000)}` + ' 00:00:00',
|
||||
endTime:`${timeFormatD()}` + ' 23:59:59',
|
||||
pageSize: -1,
|
||||
offset: 0
|
||||
}
|
||||
let res = await order.query_mt_invoice(data)
|
||||
if(res.code === '0') invoiceCount.value = res.data.totalCount
|
||||
}
|
||||
}else if(type === 'eb'){
|
||||
// console.log('get_invoice_info',ebStore)
|
||||
// let res = await order.get_invoice_info({
|
||||
// vendorId:'3',
|
||||
// vendorStoreID:'' + ebStore.vendorStoreID,
|
||||
// storeID:+ebStore.storeID
|
||||
// })
|
||||
// console.log('饿百数据列表信息',res.data)
|
||||
// if(res.code === '0') invoiceCount.value = Number(invoiceCount.value) + res.total_count
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 打开 app or 小程序
|
||||
*/
|
||||
function openAppOrApplet() {
|
||||
uni.jxAlert({
|
||||
title: '提示',
|
||||
content: '下载链接复制成功,请到浏览器进行下载,或者到手机应用商店搜索【京西菜市】进行下载!',
|
||||
success: () => {
|
||||
uni.setClipboardData({
|
||||
data: 'https://www.jxc4.com/managerApp/downApp.html'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/*************************************************
|
||||
* 下拉刷新
|
||||
*/
|
||||
let onPullDownRefreshTimer: any = null
|
||||
onPullDownRefresh(() => {
|
||||
clearTimeout(onPullDownRefreshTimer)
|
||||
onPullDownRefreshTimer = setTimeout(async () => {
|
||||
await tmpGetJxBadCommentsNo()
|
||||
await getMessageData()
|
||||
await handleMsg()
|
||||
await getInvoiceInfo('mt')
|
||||
// await getInvoiceInfo('eb')
|
||||
uni.stopPullDownRefresh()
|
||||
}, 1000)
|
||||
})
|
||||
|
||||
|
||||
/**
|
||||
* 版本更新
|
||||
*/
|
||||
const isVarsion = ref<boolean>(false)
|
||||
onBeforeUnmount(() => {
|
||||
clearTimeout(onPullDownRefreshTimer)
|
||||
})
|
||||
|
||||
|
||||
/*************************************************
|
||||
* 微信小程序版本更新
|
||||
*/
|
||||
function autoUpdate() {
|
||||
// 获取小程序更新机制兼容
|
||||
if (uni.canIUse('getUpdateManager')) {
|
||||
const updateManager = uni.getUpdateManager()
|
||||
// 检查是否有新版本发布
|
||||
updateManager.onCheckForUpdate(function (res) {
|
||||
if (res.hasUpdate) {
|
||||
isVarsion.value = true
|
||||
//小程序有新版本,则静默下载新版本,做好更新准备
|
||||
updateManager.onUpdateReady(function () {
|
||||
uni.jxAlert({
|
||||
title: '更新提示',
|
||||
content: '应用已经升级到新版本了请及时更新',
|
||||
success: () => {
|
||||
updateManager.applyUpdate()
|
||||
}
|
||||
})
|
||||
})
|
||||
// 新的版本下载失败
|
||||
updateManager.onUpdateFailed(function () {
|
||||
uni.showModal({
|
||||
title: '温馨提示',
|
||||
content: '新版本已经上线,请您删除当前小程序,重新搜索打开',
|
||||
})
|
||||
})
|
||||
} else {
|
||||
isVarsion.value = false
|
||||
toast('已经是最新版')
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// 提示用户在最新版本的客户端上体验
|
||||
uni.showModal({
|
||||
title: '温馨提示',
|
||||
content: '当前微信版本过低,可能无法使用该功能,请升级到最新版本后重试。'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return {
|
||||
getGroupChat, // 跳转加入群聊
|
||||
getSelfInfo, // 获取门店来京西的时间
|
||||
moveToWM, // 物料申请
|
||||
newBillShow, // 是否有新订单
|
||||
billList, // 账单列表
|
||||
msgCount, // 是否有信息
|
||||
badCommentCount, // 获取差评数量
|
||||
invoiceCount, // 发票数量
|
||||
openAppOrApplet, // app or 小程序
|
||||
isVarsion, // 是否现实新版本
|
||||
autoUpdate, // 检查微信更新
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default options
|
||||
280
src/pages/merchant/options/options.vue
Normal file
280
src/pages/merchant/options/options.vue
Normal file
@@ -0,0 +1,280 @@
|
||||
<template>
|
||||
<view class="options-root">
|
||||
<uni-grid :column="4" :highlight="true" :showBorder="false">
|
||||
<!-- grid -->
|
||||
<uni-grid-item
|
||||
v-for="(item, i) in newGrindListData"
|
||||
:key="i"
|
||||
@tap="grindData(item.id)"
|
||||
>
|
||||
<view class="grid-item-box">
|
||||
<image :src="item.icon" mode="scaleToFill" class="image" />
|
||||
<text class="text">{{ item.title }}</text>
|
||||
|
||||
<!-- ***** 角标内容 ****** -->
|
||||
<!-- 我的账单 -->
|
||||
<text class="bill-new" v-if="item.id == 4 && newBillShow">new</text>
|
||||
<!-- 信息通知 -->
|
||||
<text class="msg-count" v-if="item.id == 6 && msgCount > 0">{{ msgCount }}</text>
|
||||
<!-- 差评管理 -->
|
||||
<text
|
||||
class="evaluate-number"
|
||||
v-if="item.id == 5 && +badCommentCount > 0"
|
||||
>
|
||||
{{ +badCommentCount < 99 ? badCommentCount : '99+' }}
|
||||
</text>
|
||||
<!-- 发票数量 -->
|
||||
<text
|
||||
class="evaluate-number"
|
||||
v-if="item.id == 22 && +invoiceCount > 0"
|
||||
>
|
||||
{{ +invoiceCount < 99 ? invoiceCount : '99+' }}
|
||||
</text>
|
||||
<!-- 发现新版本 -->
|
||||
<text v-if="item.id == 17 && isVarsion" class="newVarsion">新</text>
|
||||
</view>
|
||||
</uni-grid-item>
|
||||
</uni-grid>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import options from './options'
|
||||
import { computed, ref } from 'vue'
|
||||
const {
|
||||
getGroupChat, // 跳转加入群聊
|
||||
getSelfInfo, // 获取门店来京西的时间
|
||||
moveToWM, // 物料申请
|
||||
newBillShow, // 是否有新订单
|
||||
msgCount, // 是否有信息
|
||||
billList, // 账单列表
|
||||
badCommentCount, // 差评数量
|
||||
invoiceCount, // 发票数量数量
|
||||
openAppOrApplet, // app or 小程序
|
||||
isVarsion, // 是否现实新版本
|
||||
autoUpdate, // 检查微信更新
|
||||
} = options()
|
||||
|
||||
// 不用展示信息的图标
|
||||
// 未下载微信不展示
|
||||
const grindListData = ref([
|
||||
{
|
||||
id: 1,
|
||||
icon: '/static/merchant-icon/1.png',
|
||||
title: '加入群聊',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
icon: '/static/merchant-icon/2.png',
|
||||
title: '营业资质',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
icon: '/static/merchant-icon/3.png',
|
||||
title: '平台管理',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
icon: '/static/merchant-icon/4.png',
|
||||
title: '我的账单',
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
icon: '/static/merchant-icon/5.png',
|
||||
title: '差评管理',
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
icon: '/static/merchant-icon/6.png',
|
||||
title: '消息通知',
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
icon: '/static/merchant-icon/7.png',
|
||||
title: '物料申请',
|
||||
},
|
||||
{
|
||||
id: 16,
|
||||
icon: '/static/merchant-icon/8.png',
|
||||
title: '扫码进店',
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
icon: '/static/merchant-icon/9.png',
|
||||
title: '待配商品',
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
icon: '/static/merchant-icon/10.png',
|
||||
title: '门店评分',
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
icon: '/static/merchant-icon/11.png',
|
||||
title: '帮助中心',
|
||||
},
|
||||
{
|
||||
id: 11,
|
||||
icon: '/static/merchant-icon/12.png',
|
||||
title: '官方客服',
|
||||
},
|
||||
{
|
||||
id: 12,
|
||||
icon: '/static/merchant-icon/13.png',
|
||||
title: '设置',
|
||||
},
|
||||
{
|
||||
id: 13,
|
||||
icon: '/static/merchant-icon/14.png',
|
||||
title: '活动信息',
|
||||
},
|
||||
{
|
||||
id: 14,
|
||||
icon: '/static/merchant-icon/15.png',
|
||||
title: '注册时间',
|
||||
},
|
||||
{
|
||||
id: 15,
|
||||
icon: '/static/merchant-icon/16.png',
|
||||
title: '下载App',
|
||||
},
|
||||
{
|
||||
id: 18,
|
||||
icon: '/static/merchant-icon/19.png',
|
||||
title: '个人信息',
|
||||
},
|
||||
{
|
||||
id: 20,
|
||||
icon: '/static/merchant-icon/21.png',
|
||||
title: '收款信息',
|
||||
},
|
||||
{
|
||||
id: 22,
|
||||
icon: '/static/merchant-icon/22.png',
|
||||
title: '发票管理',
|
||||
},
|
||||
{
|
||||
id: 19,
|
||||
icon: '/static/merchant-icon/20.png',
|
||||
title: '配送余额',
|
||||
},
|
||||
{
|
||||
id: 17,
|
||||
icon: '/static/merchant-icon/18.png',
|
||||
title: '检查更新',
|
||||
},
|
||||
])
|
||||
|
||||
/*************************************************
|
||||
* 格式化数据,没有下载微信有些数据不展示
|
||||
*/
|
||||
const newGrindListData = computed(() => {
|
||||
return grindListData.value
|
||||
})
|
||||
|
||||
function grindData(title: number) {
|
||||
switch (title) {
|
||||
case 1:
|
||||
getGroupChat() // 加入群聊
|
||||
break
|
||||
case 2:
|
||||
uni.navigateTo({
|
||||
url: '/subPages/merchantChild/businessLicense/businessLicense',
|
||||
}) // 营业资质
|
||||
break
|
||||
case 3:
|
||||
uni.navigateTo({
|
||||
url: '/subPages/merchantChild/platformM/platformM'
|
||||
}) // 平台管理
|
||||
break
|
||||
case 4:
|
||||
uni.navigateTo({
|
||||
url: `/subPages/merchantChild/bill/bill?billList=${JSON.stringify(
|
||||
billList.value
|
||||
)}`,
|
||||
}) // 我的账单
|
||||
break
|
||||
case 5:
|
||||
uni.navigateTo({
|
||||
url: `/subPages/merchantChild/evaluateM/evaluateM?number=${badCommentCount.value}`,
|
||||
}) // 差评管理
|
||||
break
|
||||
case 6:
|
||||
uni.navigateTo({
|
||||
url: '/subPages/merchantChild/message/message',
|
||||
}) // 消息通知
|
||||
break
|
||||
case 7:
|
||||
moveToWM()
|
||||
break
|
||||
case 8:
|
||||
uni.navigateTo({
|
||||
url: '/subPages/merchantChild/waitGoods/waitGoods',
|
||||
}) // 待配商品
|
||||
break
|
||||
case 9:
|
||||
uni.navigateTo({
|
||||
url: '/subPages/merchantChild/storeScore/storeScore',
|
||||
}) // 门店评分
|
||||
break
|
||||
case 10:
|
||||
uni.navigateTo({
|
||||
url: '/subPages/merchantChild/helpCenter/helpCenter'
|
||||
}) // 帮助中心
|
||||
break
|
||||
case 11:
|
||||
uni.navigateTo({
|
||||
url: '/subPages/orderChild/getPhone/getPhone'
|
||||
}) // 联系客服
|
||||
break
|
||||
case 12:
|
||||
uni.navigateTo({
|
||||
url: '/subPages/merchantChild/setUp/setUp'
|
||||
}) // 设置
|
||||
break
|
||||
case 13:
|
||||
uni.navigateTo({
|
||||
url: '/subPages/merchantChild/activity/activity'
|
||||
}) // 活动信息
|
||||
break
|
||||
case 14:
|
||||
getSelfInfo() // 注册时间
|
||||
break
|
||||
case 15:
|
||||
openAppOrApplet() // 打开 app or 小程序
|
||||
break
|
||||
case 16:
|
||||
uni.navigateTo({
|
||||
url: '/subPages/merchantChild/shareStore/shareStore'
|
||||
}) // 扫码进店
|
||||
break
|
||||
case 17:
|
||||
autoUpdate()
|
||||
break
|
||||
case 18:
|
||||
uni.navigateTo({
|
||||
url: '/subPages/merchantChild/useInfo/useInfo'
|
||||
}) // 个人信息
|
||||
break
|
||||
case 19:
|
||||
uni.navigateTo({
|
||||
url: '/subPages/merchantChild/accountBalance/accountBalance',
|
||||
}) // 配送余额
|
||||
break
|
||||
case 20:
|
||||
uni.navigateTo({
|
||||
url: '/subPages/merchantChild/payeeInfo/payeeInfo'
|
||||
}) // 收款信息
|
||||
break
|
||||
case 22:
|
||||
uni.navigateTo({
|
||||
url: '/subPages/merchantChild/invoice/invoice'
|
||||
}) // 发票信息
|
||||
break
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './options.scss';
|
||||
</style>
|
||||
49
src/pages/merchant/orderData/orderData.scss
Normal file
49
src/pages/merchant/orderData/orderData.scss
Normal file
@@ -0,0 +1,49 @@
|
||||
.order-data-root {
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.title-root {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 10rpx;
|
||||
|
||||
.see-more {
|
||||
color: #cfcccc;
|
||||
}
|
||||
|
||||
.text {
|
||||
margin-right: 15rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.order-money {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.money,
|
||||
.order {
|
||||
border-right: 1rpx solid #e0e0e0;
|
||||
}
|
||||
|
||||
.money,
|
||||
.order,
|
||||
.order1 {
|
||||
width: 354rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.number {
|
||||
font-weight: bold;
|
||||
font-size: 40rpx;
|
||||
padding: 30rpx 0;
|
||||
}
|
||||
}
|
||||
|
||||
.afterNumber::before{
|
||||
content: '-';
|
||||
}
|
||||
}
|
||||
151
src/pages/merchant/orderData/orderData.vue
Normal file
151
src/pages/merchant/orderData/orderData.vue
Normal file
@@ -0,0 +1,151 @@
|
||||
<template>
|
||||
<view class="order-data-root" @tap="getOrderRealTime">
|
||||
<view class="title-root">
|
||||
<view>
|
||||
<text class="text">今日完成实时数据</text>
|
||||
<jx-icon
|
||||
icon="wenhaoxiao"
|
||||
color="#cfcccc"
|
||||
@tap.stop="explain"
|
||||
></jx-icon>
|
||||
</view>
|
||||
|
||||
<view class="see-more" v-if="showMore">
|
||||
<text>更多</text>
|
||||
<jx-icon icon="gengduo" color="#cfcccc"></jx-icon>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="order-money">
|
||||
<view class="money">
|
||||
<text class="number">{{ price }}</text>
|
||||
<text>{{ vendorTitle }}</text>
|
||||
</view>
|
||||
<view class="order">
|
||||
<text class="number">{{ count }}</text>
|
||||
<text>有效订单量</text>
|
||||
</view>
|
||||
<view class="order1">
|
||||
<text class="number" :class="{'afterNumber': +actualFee > 0}">{{ actualFee }}</text>
|
||||
<text>运费</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import jxIcon from '@/components/jx-icon/jx-icon.vue'
|
||||
import { computed, Ref } from 'vue'
|
||||
import useGlobalFunc from '@/composables/useGlobalFunc'
|
||||
import { store } from '@/store'
|
||||
const { wholeCalcPrice, singleCalcPrice } = useGlobalFunc()
|
||||
|
||||
interface propsType {
|
||||
saleInfo: AnyObject
|
||||
showMore?: boolean
|
||||
_vendorPayPercentage: number | string
|
||||
isNotQuote: boolean
|
||||
isShowShop?: boolean
|
||||
isZero: boolean
|
||||
isUpperfif: boolean
|
||||
isOut?: boolean
|
||||
isAllplatfrom?: boolean
|
||||
}
|
||||
const props = defineProps<propsType>()
|
||||
|
||||
/*************************************************
|
||||
* 判断门店是否为折扣
|
||||
*/
|
||||
const isPointStore = computed(() => {
|
||||
return store.getters['storeInfo/isPointStore']
|
||||
})
|
||||
|
||||
/*************************************************
|
||||
* 收入说明
|
||||
*/
|
||||
const vendorTitle = computed(() => {
|
||||
if (isPointStore.value) {
|
||||
return '实际支付'
|
||||
} else {
|
||||
if (props._vendorPayPercentage != 0 && +props._vendorPayPercentage < 50) {
|
||||
//扣点
|
||||
return '实际支付'
|
||||
} else {
|
||||
//报价
|
||||
return '实际收入'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
/*************************************************
|
||||
* 订单数量
|
||||
*/
|
||||
const count: Ref<number | string> = computed(() => {
|
||||
return props.saleInfo.count || '0'
|
||||
})
|
||||
|
||||
/*************************************************
|
||||
* 扣除运费
|
||||
*/
|
||||
const actualFee: Ref<number | string> = computed(() => {
|
||||
return props.saleInfo.actualFee || '0'
|
||||
})
|
||||
|
||||
/*************************************************
|
||||
* 门店收益
|
||||
*/
|
||||
const price = computed(() => {
|
||||
if (count.value) {
|
||||
if (props.isAllplatfrom || props.isOut) {
|
||||
//全平台
|
||||
let calcData = {
|
||||
vendorPayPercentage: props._vendorPayPercentage,
|
||||
actualPayPrice: props.saleInfo.actualPayPrice,
|
||||
shopPrice: props.saleInfo.shopPrice,
|
||||
isPointStore: isPointStore.value,
|
||||
isUpperfif: props.isUpperfif,
|
||||
isZero: props.isZero,
|
||||
isNotQuote: props.isNotQuote,
|
||||
earningPrice: props.saleInfo.earningPrice,
|
||||
}
|
||||
return wholeCalcPrice(calcData)
|
||||
} else {
|
||||
//单平台
|
||||
let calcData = {
|
||||
vendorPayPercentage: props._vendorPayPercentage,
|
||||
actualPayPrice: props.saleInfo.actualPayPrice,
|
||||
shopPrice: props.saleInfo.shopPrice,
|
||||
isPointStore: isPointStore.value,
|
||||
earningPrice: props.saleInfo.earningPrice,
|
||||
}
|
||||
return singleCalcPrice(calcData)
|
||||
}
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 打开说明窗口
|
||||
*/
|
||||
function explain() {
|
||||
uni.jxAlert({
|
||||
title: '说明',
|
||||
content: `实际收入: 从当日0时到当前时间的实际获得,不再扣点,已扣除售后退款\r\n有效订单: 统计时间内,已支付订单中未被取消的订单数量`,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到营业数据
|
||||
*/
|
||||
function getOrderRealTime() {
|
||||
if (props.showMore != true) return
|
||||
uni.navigateTo({
|
||||
url: `/subPages/merchantChild/orderRealTime/orderRealTime?_vendorPayPercentage=${props._vendorPayPercentage}&isShowShop=${props.isShowShop}&isNotQuote=${props.isNotQuote}&isZero=${props.isZero}&isUpperfif=${props.isUpperfif}`,
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './orderData.scss';
|
||||
</style>
|
||||
127
src/pages/merchant/userInfo/userInfo.scss
Normal file
127
src/pages/merchant/userInfo/userInfo.scss
Normal file
@@ -0,0 +1,127 @@
|
||||
.merchant-root {
|
||||
box-sizing: border-box;
|
||||
background-color: #4eb331;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
|
||||
.store-timer {
|
||||
text-align: center;
|
||||
color: #fcff06;
|
||||
height: 0rpx;
|
||||
line-height: 50rpx;
|
||||
overflow: hidden;
|
||||
transition: all 0.5s;
|
||||
|
||||
.text {
|
||||
margin-left: -60rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.store-active {
|
||||
height: 50rpx;
|
||||
}
|
||||
|
||||
.info-root {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0rpx 20rpx 20rpx 20rpx;
|
||||
|
||||
.user-infor-root {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
image {
|
||||
width: 140rpx;
|
||||
height: 140rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #fff;
|
||||
border: 4rpx solid #fff;
|
||||
}
|
||||
|
||||
.isHeight {
|
||||
height: 190rpx;
|
||||
}
|
||||
|
||||
.storeName-style-timer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
color: #fff;
|
||||
width: 380rpx;
|
||||
margin-left: 25rpx;
|
||||
|
||||
.timer-root {
|
||||
margin-top: 5rpx;
|
||||
line-height: 1;
|
||||
padding: 10rpx 10rpx;
|
||||
background-color: rgba(0, 0, 0, 0.15);
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.name,
|
||||
.state,
|
||||
.timer-root {
|
||||
display: inline-block;
|
||||
max-width: 380rpx;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.state,
|
||||
.timer {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.state {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.tip{
|
||||
display: flex;
|
||||
line-height: 46rpx;
|
||||
.title{
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.do-business-root {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #3e8f27;
|
||||
border-radius: 80rpx;
|
||||
color: #cccccc;
|
||||
margin-right: 10rpx;
|
||||
transition: all 0.4s;
|
||||
|
||||
.text {
|
||||
padding: 0 15rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.business-active {
|
||||
background-color: #ffad49;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.esc-switchSoter {
|
||||
width: 152rpx;
|
||||
|
||||
button {
|
||||
font-size: 24rpx;
|
||||
color: #4eb331;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.swithcStore-btn {
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
229
src/pages/merchant/userInfo/userInfo.ts
Normal file
229
src/pages/merchant/userInfo/userInfo.ts
Normal file
@@ -0,0 +1,229 @@
|
||||
/**
|
||||
* 用户信息类
|
||||
*/
|
||||
import { getStorage, setStorage } from "@/utils/storage";
|
||||
import { onPullDownRefresh, onShow, onLoad } from "@dcloudio/uni-app";
|
||||
import { computed, onBeforeUnmount, ref } from "vue";
|
||||
import { timeFormatD } from "@/utils/tools";
|
||||
import useGlobalFunc from "@/composables/useGlobalFunc";
|
||||
import { listenOrder } from '@/utils/bluetoothPrinter/printerOrder'
|
||||
import { store } from "@/store";
|
||||
|
||||
|
||||
function userInfo() {
|
||||
const { newMessage, logOutFn, isTxd, getMtStoreIMStatus } = useGlobalFunc()
|
||||
|
||||
|
||||
/**
|
||||
* 门店自动营业时间
|
||||
*/
|
||||
const newAutoEnableAt = ref<string>('')
|
||||
const switchOpenTime = computed(() => {
|
||||
if (newAutoEnableAt.value) {
|
||||
let now = +new Date(timeFormatD(+new Date()));
|
||||
let time = +new Date(timeFormatD(newAutoEnableAt.value));
|
||||
let num = time - now;
|
||||
if (num < 0) {
|
||||
return "营业时间错误请联系运营";
|
||||
} else {
|
||||
let day = num / 1000 / 3600 / 24;
|
||||
if (day < 1) return "门店将在今天自动营业";
|
||||
else if (day >= 1 && day < 2) return "门店将在明天自动营业";
|
||||
else if (day >= 2 && day < 3) return "门店将在后天自动营业";
|
||||
else return `将在 ${timeFormatD(newAutoEnableAt.value)} 自动营业`;
|
||||
}
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 下拉刷新
|
||||
*/
|
||||
let onPullDownRefreshTimer: any = null
|
||||
onPullDownRefresh(async () => {
|
||||
await getStores()
|
||||
clearTimeout(onPullDownRefreshTimer)
|
||||
onPullDownRefreshTimer = setTimeout(() => {
|
||||
uni.stopPullDownRefresh()
|
||||
}, 1000)
|
||||
})
|
||||
|
||||
/**
|
||||
* 用户头像、门店名字
|
||||
*/
|
||||
interface StoreInfoType {
|
||||
avatar: string;
|
||||
storeName: string;
|
||||
}
|
||||
const storeInfo = ref<StoreInfoType>({
|
||||
avatar: "https://image.jxc4.com/image/70143fcf48aefe74537533f35a0a8153.jpg",
|
||||
storeName: "",
|
||||
});
|
||||
let oldStoreID: any = 0
|
||||
onShow(async () => {
|
||||
getStores()
|
||||
await listenOrder()
|
||||
storeInfo.value.storeName = getStorage("storeName")
|
||||
if (oldStoreID != getStorage('storeID') && oldStoreID != 0) {
|
||||
uni.startPullDownRefresh({})
|
||||
}
|
||||
oldStoreID = getStorage('storeID')
|
||||
});
|
||||
onLoad(async () => {
|
||||
await getStores()
|
||||
await newMessage() // 商家中心有新信息了
|
||||
})
|
||||
|
||||
const businessHours = ref<AnyObject>({})
|
||||
async function getStores() {
|
||||
await store.dispatch('storeInfo/getOneStore',getStorage("storeID"))
|
||||
businessHours.value = store.getters['storeInfo/businessHours'] // 营业时间
|
||||
newAutoEnableAt.value = store.getters['storeInfo/newAutoEnableAt'] // 手机门店休息时间
|
||||
|
||||
await getMtStoreIMStatus() // 获取门店的IM单聊开关状态
|
||||
|
||||
await newMessage() // 商家中心有新信息了
|
||||
await listenOrder() // 小程序监听新订单
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 去修改营业时间
|
||||
*/
|
||||
function setTime() {
|
||||
uni.navigateTo({ url: `/subPages/merchantChild/setBusinessTime/setBusinessTime` })
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出登录
|
||||
*/
|
||||
let goLoginTime: any = null
|
||||
function goLogin() {
|
||||
uni.vibrateShort({})
|
||||
uni.showActionSheet({
|
||||
title: '退出后不会删除任何数据',
|
||||
itemColor: '#e70808',
|
||||
itemList: ['退出登录'],
|
||||
popover: {
|
||||
width: 5000,
|
||||
},
|
||||
success: function (res) {
|
||||
logOutFn()
|
||||
// uni.navigateTo({ url: '/subPages/login/wxLogin/wxLogin' })
|
||||
uni.reLaunch({ url: '/subPages/login/wxLogin/wxLogin' })
|
||||
},
|
||||
fail: () => {
|
||||
console.log('ZSW-取消退出');
|
||||
},
|
||||
complete: () => {
|
||||
uni.vibrateShort({})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function downApp() {
|
||||
uni.jxAlert({
|
||||
title: '提示',
|
||||
content: '下载链接复制成功,请到浏览器进行下载,或者到手机应用商店搜索【京西菜市】进行下载!',
|
||||
success: () => {
|
||||
uni.setClipboardData({
|
||||
data: 'https://www.jxc4.com/managerApp/downApp.html'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换门店
|
||||
*/
|
||||
function switchStore() {
|
||||
uni.navigateTo({ url: "/subPages/switchStore/switchStore" });
|
||||
|
||||
// 图片转pdf https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&tn=88093251_52_hao_pg&wd=uniapp%E5%B0%8F%E7%A8%8B%E5%BA%8F%20%E5%A6%82%E4%BD%95%E5%B0%86%E5%9B%BE%E7%89%87%E7%9A%84%E4%B8%B4%E6%97%B6%E6%96%87%E4%BB%B6%E8%BD%AC%E6%88%90pdf%E6%A0%BC%E5%BC%8F&oq=%25E9%2587%258D%25E6%25B8%25A9%25E6%2580%25BB%25E4%25B9%25A6%25E8%25AE%25B0%25E5%25AF%25B9%25E6%25B5%25B7%25E5%258D%2597%25E5%25AF%2584%25E4%25BA%2588%25E7%259A%2584%25E5%258E%259A%25E6%259C%259B&rsv_pq=cd144c82001083ca&rsv_t=4715G1mkyqJr%2FhraQB%2FDsJO62gnA57BCAmiAx1S%2Be4x%2FRVjoViQTJa15XVpww3QSg2jkH32EJe6s&rqlang=cn&rsv_enter=1&rsv_dl=tb&rsv_sug3=25&rsv_n=2&rsv_sug1=18&rsv_sug7=100&rsv_btype=t&inputT=14749&rsv_sug4=14838
|
||||
// import jsPDF from 'jspdf';
|
||||
// const ctx = uni.createCanvasContext('myCanvas', this);
|
||||
// // 假设你有一个图片的临时路径,例如从uni.chooseImage获取
|
||||
// const imagePath = '/path/to/your/image.jpg';
|
||||
// ctx.drawImage(imagePath, 0, 0, 300, 300); // 绘制图片到Canvas上
|
||||
// ctx.draw(false, () => {
|
||||
// // 获取Canvas内容并转换为PDF
|
||||
// const contentWidth = 300; // Canvas宽度
|
||||
// const contentHeight = 300; // Canvas高度
|
||||
// const pdf = new jsPDF('p', 'pt', [contentWidth, contentHeight]); // A4 size page format
|
||||
// pdf.addImage(imagePath, 'JPEG', 0, 0, contentWidth, contentHeight); // 这里需要确保图片路径正确,或者在绘制后使用ctx.toTempFilePath获取图片路径
|
||||
// pdf.save('converted-image.pdf'); // 保存PDF文件
|
||||
// });
|
||||
// ctx.toTempFilePath({
|
||||
// success: (res) => {
|
||||
// console.log('图片路径:', res.tempFilePath);
|
||||
// },
|
||||
// fail: (err) => {
|
||||
// console.error('导出失败:', err);
|
||||
// }
|
||||
// });
|
||||
// uni.chooseImage({
|
||||
// count: 1, // 默认9,设置图片的最大数量为1张
|
||||
// sizeType: ['original'], // 可以指定是原图还是压缩图,默认二者都有
|
||||
// sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
|
||||
// success: function(res) {
|
||||
// // 获取到图片的本地文件路径列表
|
||||
// const tempFilePaths = res.tempFilePaths;
|
||||
// // 获取文件管理器
|
||||
// console.log('获取临时文件路径',res)
|
||||
// const fs = uni.getFileSystemManager();
|
||||
// // 读取文件内容并转换为Base64
|
||||
// fs.readFile({
|
||||
// filePath: tempFilePaths[0], // 选择图片返回的本地文件路径列表的第一个路径
|
||||
// encoding: 'base64', // 指定编码格式为base64
|
||||
// success: function(res) {
|
||||
// const base64Data = res.data; // 读取到的Base64数据
|
||||
// console.log(base64Data,'二进制文件base64格式'); // 输出或使用base64Data
|
||||
// },
|
||||
// fail: function(err) {
|
||||
// console.error('读取文件失败', err);
|
||||
// }
|
||||
// });
|
||||
// // fs.readFile({
|
||||
// // filePath: tempFilePaths[0], // 第一个图片的路径
|
||||
// // encoding: 'binary', // 以二进制形式读取
|
||||
// // success: function(res) {
|
||||
// // console.log(res,'图片的二进制数据:', res.data); // 这里的res.data就是图片的二进制数据
|
||||
// // }
|
||||
// // })
|
||||
// }
|
||||
// })
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到设置营业状态页面
|
||||
*/
|
||||
function jumpBusinessStatus() {
|
||||
uni.navigateTo({
|
||||
url: '/subPages/merchantChild/setBusinessStatus/setBusinessStatus'
|
||||
})
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 做收尾工作
|
||||
*/
|
||||
onBeforeUnmount(() => {
|
||||
clearTimeout(onPullDownRefreshTimer)
|
||||
clearTimeout(goLoginTime)
|
||||
})
|
||||
|
||||
|
||||
return {
|
||||
storeInfo, // 用户信息
|
||||
businessHours, // 营业时间段
|
||||
goLogin, // 退出登录
|
||||
switchStore, // 切换门店
|
||||
switchOpenTime, // 门店休息到那天
|
||||
setTime, // 去修改营业时间
|
||||
jumpBusinessStatus, // 跳转到营业状态页面
|
||||
downApp,
|
||||
store
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default userInfo
|
||||
97
src/pages/merchant/userInfo/userInfo.vue
Normal file
97
src/pages/merchant/userInfo/userInfo.vue
Normal file
@@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<view class="merchant-root">
|
||||
<view class="store-timer" :class="{ 'store-active': switchOpenTime != '' }">
|
||||
<text class="text">{{ switchOpenTime }}</text>
|
||||
</view>
|
||||
<view class="info-root">
|
||||
<view class="user-infor-root">
|
||||
<image
|
||||
@longtap=""
|
||||
:src="storeInfo.avatar"
|
||||
mode="scaleToFill"
|
||||
@tap="previewImage(storeInfo.avatar)"
|
||||
/>
|
||||
<view class="storeName-style-timer">
|
||||
<view class="name">{{ storeInfo.storeName }}</view>
|
||||
|
||||
<view class="state">
|
||||
<view class="tip" @tap="jumpBusinessStatus">
|
||||
<view class="title">营业状态:</view>
|
||||
<view
|
||||
class="do-business-root business-active"
|
||||
>
|
||||
<text class="text">{{store.getters['storeInfo/storeStatus'] === 1?'营业中':store.getters['storeInfo/storeStatus'] === 0?'临时休息':store.getters['storeInfo/storeStatus'] === -1?'休息':store.getters['storeInfo/storeStatus'] === -2?'禁用':'未知'}}</text>
|
||||
<jx-icon icon="shuxie" color="#fff"/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 营业时间段 -->
|
||||
<view
|
||||
class="timer-root"
|
||||
v-if="
|
||||
businessHours.timer1 != '00:00' && businessHours.timer2 != '00:00'
|
||||
"
|
||||
@tap="setTime"
|
||||
>
|
||||
<view class="timer">
|
||||
营业时间段{{ businessHours.timer1 }}至{{ businessHours.timer2 }}
|
||||
<jx-icon icon="shuxie" color="#fff" />
|
||||
</view>
|
||||
|
||||
<view
|
||||
class="timer"
|
||||
v-if="
|
||||
businessHours.timer3 != '00:00' &&
|
||||
businessHours.timer4 != '00:00'
|
||||
"
|
||||
>
|
||||
营业时间段{{ businessHours.timer3 }}至{{ businessHours.timer4 }}
|
||||
<jx-icon icon="shuxie" color="#fff" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 退出登录 -->
|
||||
<view class="esc-switchSoter">
|
||||
<button class="esc-btn" @tap="goLogin">退出登录</button>
|
||||
<button class="swithcStore-btn" @tap="switchStore">切换门店</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- app下载通告栏 -->
|
||||
<uni-notice-bar
|
||||
:speed="50"
|
||||
show-icon
|
||||
scrollable
|
||||
background-color="#fcefee"
|
||||
color="#e70808"
|
||||
moreColor="#e70808"
|
||||
showGetMore
|
||||
@click="downApp"
|
||||
text="京西菜市商家版App全新上架,系统更加稳定,功能更加齐全,订单通知更加及时,请往手机自带应用商店搜索【京西菜市】进行安装使用!"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import userInfo from './userInfo'
|
||||
import useGlobalFunc from '@/composables/useGlobalFunc'
|
||||
const { previewImage } = useGlobalFunc()
|
||||
const {
|
||||
storeInfo, // 用户信息
|
||||
businessHours, // 营业时间段
|
||||
goLogin, // 退出登录
|
||||
switchStore, // 切换门店
|
||||
switchOpenTime, // 门店休息到哪天
|
||||
setTime, // 去修改营业时间
|
||||
jumpBusinessStatus, // 跳转到营业状态页面
|
||||
downApp,
|
||||
store
|
||||
} = userInfo()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './userInfo.scss';
|
||||
</style>
|
||||
209
src/pages/message/index.ts
Normal file
209
src/pages/message/index.ts
Normal file
@@ -0,0 +1,209 @@
|
||||
import toast from '@/utils/toast'
|
||||
import { onPullDownRefresh, onShow } from '@dcloudio/uni-app'
|
||||
import { computed, ref } from 'vue'
|
||||
import { store } from "@/store"
|
||||
import { Decrypt, timeFormatDHM } from '@/utils/tools'
|
||||
import message from '@/api/https/message'
|
||||
import order from '@/api/https/order'
|
||||
import useGlobalFunc from "@/composables/useGlobalFunc"
|
||||
// import { msgInfo } from '@/api/mockData/index'
|
||||
/*************************************************
|
||||
* IM消息
|
||||
*/
|
||||
const messageFn = function () {
|
||||
// vuex
|
||||
const { getMtStoreIMStatus } = useGlobalFunc()
|
||||
|
||||
// 用户列表
|
||||
const userListData = ref<Array<AnyObject>>([])
|
||||
|
||||
/*************************************************
|
||||
* 获取用户列表
|
||||
*/
|
||||
onShow(() => {
|
||||
if (isFirstLogin.value) return
|
||||
userListData.value = []
|
||||
getMTUserList()
|
||||
})
|
||||
const isFirstLogin = computed(() => {
|
||||
// 是否没有登陆的状态
|
||||
return store.state.serveInfo.isFirstLogin
|
||||
})
|
||||
|
||||
/**
|
||||
* 整理参数信息,避免请求出错
|
||||
*/
|
||||
async function dataParams() {
|
||||
let arr:any = []
|
||||
let brr = store.getters['storeInfo/platformInfo']
|
||||
if(brr && brr.length>0){
|
||||
let mtVendorIDInfo = brr.find((item:AnyObject) => item.vendorID === 1)
|
||||
let ebVendorIDInfo = brr.find((item:AnyObject) => item.vendorID === 3)
|
||||
if(mtVendorIDInfo){
|
||||
arr.push({
|
||||
vendorStoreID: mtVendorIDInfo.vendorStoreID,
|
||||
vendorID: "1",
|
||||
appID: mtVendorIDInfo.vendorOrgCode
|
||||
})
|
||||
}
|
||||
|
||||
if(ebVendorIDInfo){
|
||||
arr.push({
|
||||
vendorStoreID: ebVendorIDInfo.vendorStoreID,
|
||||
vendorID: "3",
|
||||
appID: ebVendorIDInfo.vendorOrgCode
|
||||
})
|
||||
}
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// 获取美团IM
|
||||
async function getMTUserList(time?:number) {
|
||||
let arr = await dataParams()
|
||||
if(!(arr && arr.length>0)) return
|
||||
let data = {
|
||||
payLoad:JSON.stringify(arr)
|
||||
}
|
||||
let venderIDInfo = arr.find((item:AnyObject) => item.vendorID === '1')
|
||||
let ebStore = arr.find((item:AnyObject) => item.vendorID === '3')
|
||||
|
||||
let res = await message.get_IM_user_list(data)
|
||||
// res = msgInfo.userList // 模拟数据
|
||||
// console.log('获取用户列表', res)
|
||||
if (res.code == 0) {
|
||||
if (JSON.stringify(res.data) === '{}') return
|
||||
let platformID = venderIDInfo.appID // 美团账号
|
||||
let newArr: any = []
|
||||
// let fmtUserList = res.data[`${venderIDInfo.appID}:${venderIDInfo.vendorStoreID}:1`] || [] // 美团
|
||||
let fmtUserList = venderIDInfo ? res.data[`${venderIDInfo.appID}:${venderIDInfo.vendorStoreID}:1`] || [] : [] // 美团
|
||||
let febUserList = ebStore && JSON.stringify(ebStore) !== '{}' ? res.data[`${ebStore.appID}:${ebStore.vendorStoreID}:3`] || [] : [] // 饿百
|
||||
|
||||
let reverseList = fmtUserList && fmtUserList.length > 0 ? fmtUserList.reverse() : []
|
||||
let reverseListEb = febUserList && febUserList.length > 0 ? febUserList.reverse() : []
|
||||
reverseList.map((element: any) => {
|
||||
let resData = JSON.parse(element)
|
||||
|
||||
// 判断是否需要显示列表
|
||||
if (Decrypt(resData.latestMsg, platformID).indexOf('[自动回复]') == -1) {
|
||||
let latestMsgHandler = ''
|
||||
try {
|
||||
JSON.parse(Decrypt(resData.latestMsg, platformID))
|
||||
latestMsgHandler = typeof JSON.parse(Decrypt(resData.latestMsg, platformID)) === 'number' ? Decrypt(resData.latestMsg, platformID) : '【订单】'
|
||||
} catch (error) {
|
||||
let msg = Decrypt(resData.latestMsg, platformID)
|
||||
if (msg == '') latestMsgHandler = '【商品】'
|
||||
else {
|
||||
if (!(msg.includes('https') || msg.includes('http'))) latestMsgHandler = msg
|
||||
else latestMsgHandler = msg.indexOf('.amr') == -1 ? '【图片】' : '【语音】'
|
||||
}
|
||||
}
|
||||
|
||||
// if (resData.userID != 0) {
|
||||
// 只展示6个小时以内的消息
|
||||
let userList = {
|
||||
...resData,
|
||||
latestMsg: latestMsgHandler,
|
||||
latestTime: timeFormatDHM(+new Date(resData.latestTime * 1000)),
|
||||
orderInfo: {},
|
||||
orderDesc: ''
|
||||
}
|
||||
newArr.push(userList)
|
||||
|
||||
// 获取订单信息
|
||||
// if (userList.orderID) getOrderInfo(userList.orderID, index)
|
||||
if (userList.orderID) getOrderInfo(userList.orderID, newArr.length - 1)
|
||||
|
||||
// }
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
// 饿百
|
||||
reverseListEb.map((element: any, index: number) => {
|
||||
let resData = JSON.parse(element)
|
||||
let latestMsgHandler = JSON.parse(resData.latestMsg).text ? JSON.parse(resData.latestMsg).text : JSON.parse(resData.latestMsg).duration ? '【语音】' : '【图片】'
|
||||
// let isAddUserLiset = JSON.parse(resData.latestMsg).data && JSON.parse(JSON.parse(resData.latestMsg).data).title.includes('本次服务已经完成,会话暂停') ? false : true
|
||||
if (JSON.parse(resData.latestMsg).elements && JSON.parse(resData.latestMsg).elements.length > 0) {
|
||||
let findItem = JSON.parse(resData.latestMsg).elements.filter((item: { elementType: number }) => item.elementType === 1)
|
||||
latestMsgHandler = findItem && findItem.length > 0 ? JSON.parse(findItem[0].elementContent).text.replace('@商家', '') : latestMsgHandler
|
||||
}
|
||||
// 饿百参考文档:https://open-retail.ele.me/#/apidoc/me.ele.retail:im.message.send-3?aopApiCategory=IM_all&type=api_menu resData.userID != 0 && isAddUserLiset
|
||||
if ((new Date().getTime() - resData.latestTime * 1000) <= (3600 * 1000 * 12 * 1) ) {
|
||||
let userList = {
|
||||
...resData,
|
||||
latestMsg: latestMsgHandler,
|
||||
latestTime: timeFormatDHM(+new Date(resData.latestTime * 1000)),
|
||||
orderInfo: {},
|
||||
orderDesc: ''
|
||||
}
|
||||
newArr.push(userList)
|
||||
|
||||
// 获取订单信息
|
||||
// if (userList.orderID) getOrderInfo(userList.orderID, index)
|
||||
if (userList.orderID) getOrderInfo(userList.orderID, newArr.length - 1 )
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
userListData.value = newArr
|
||||
} else {
|
||||
toast('获取信息异常')
|
||||
userListData.value.length == 0
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单信息
|
||||
*/
|
||||
async function getOrderInfo(orderId: string, index: number) {
|
||||
let res = await order.get_orders({ vendorOrderID: orderId })
|
||||
if (res.code === '0') {
|
||||
userListData.value[index].orderInfo = res.data.data[0]
|
||||
userListData.value[index].orderDesc = ` #${res.data.data[0].orderSeq}`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 下拉刷新
|
||||
*/
|
||||
let onPullDownRefreshTimer: any = null
|
||||
onPullDownRefresh(() => {
|
||||
clearTimeout(onPullDownRefreshTimer)
|
||||
onPullDownRefreshTimer = setTimeout(async () => {
|
||||
getMtStoreIMStatus() // 刷新美团门店IM单聊状态
|
||||
// 获取用户列表
|
||||
getMTUserList()
|
||||
clearTimeout(onPullDownRefreshTimer)
|
||||
}, 500)
|
||||
})
|
||||
|
||||
|
||||
/*************************************************
|
||||
* 进入聊天页面
|
||||
*/
|
||||
function charItem(item: AnyObject) {
|
||||
item.latestMsg = ""
|
||||
uni.navigateTo({
|
||||
url: `/subPages/messageChild/msgChat/msgChat?data=${JSON.stringify(item)}`,
|
||||
})
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 进入设置页面
|
||||
*/
|
||||
function jumpToSetUp() {
|
||||
uni.navigateTo({
|
||||
url: `/subPages/merchantChild/setUp/setUp`,
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
charItem, // 进入聊天页面
|
||||
userListData, // 用户列表
|
||||
jumpToSetUp, // 跳到设置页面
|
||||
store
|
||||
}
|
||||
}
|
||||
|
||||
export default messageFn
|
||||
76
src/pages/message/index.vue
Normal file
76
src/pages/message/index.vue
Normal file
@@ -0,0 +1,76 @@
|
||||
<template>
|
||||
<!-- 美团授权已过期 -->
|
||||
<!-- <jx-empty v-if="imOnlineStatus === -1" title="美团授权已过期" /> -->
|
||||
|
||||
<!-- IM状态 -->
|
||||
<view v-if="store.getters['storeInfo/imStatus']" style="position:absolute;bottom:0;width:100%">
|
||||
<view class="notice" @tap="jumpToSetUp">
|
||||
<text>{{store.getters['storeInfo/imStatus']}}IM单聊状态未设置</text>
|
||||
<jx-icon icon="gengduo" color="red"></jx-icon>
|
||||
</view>
|
||||
</view>
|
||||
<!-- v-else -->
|
||||
<!-- <template > -->
|
||||
<!-- 用户列表 -->
|
||||
<template v-if="userListData.length > 0">
|
||||
<uni-list :border="false">
|
||||
<view class="chat-border" v-for="item in userListData" :key="item.userID">
|
||||
<uni-list-chat
|
||||
:clickable="true"
|
||||
@click="charItem(item)"
|
||||
:avatar-circle="true"
|
||||
:title="
|
||||
item.vendorID == 1
|
||||
? `【美团${item.orderDesc}】${item.userID === '0' ? '群发消息' : item.userID}`
|
||||
: `【饿了么】${item.userID}`
|
||||
"
|
||||
:avatar="
|
||||
item.vendorID == 1
|
||||
? 'https://image.jxc4.com/image/75654ab606494a0efdb0cf7d7ad060d9.png'
|
||||
: 'https://image.jxc4.com/image/6c2f1dfd95890df8ef5e27bde15c4e7f.png'
|
||||
"
|
||||
:note="item.latestMsg"
|
||||
:time="item.latestTime"
|
||||
badge-positon="left"
|
||||
:badge-text="item.NewMessageNum"
|
||||
/>
|
||||
</view>
|
||||
</uni-list>
|
||||
</template>
|
||||
|
||||
<jx-empty v-else title="暂无消息" />
|
||||
<!-- </template> -->
|
||||
|
||||
<!-- 公共组件 -->
|
||||
<jx-login-empty title="马上登录,查看消息" />
|
||||
<jx-loading />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup >
|
||||
import messageFn from './index'
|
||||
const {
|
||||
charItem, // 聊天详情
|
||||
userListData, // 用户列表
|
||||
jumpToSetUp, // 跳到设置页面
|
||||
store
|
||||
} = messageFn()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.chat-border:nth-child(1) {
|
||||
border-top: 2rpx solid rgb(230, 230, 230);
|
||||
}
|
||||
.chat-border {
|
||||
border-bottom: 2rpx solid rgb(230, 230, 230);
|
||||
}
|
||||
.notice {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
padding: 20rpx;
|
||||
background-color: #fef5f6;
|
||||
color: #e91d37;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,76 @@
|
||||
.position-relative {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.abnormal-order {
|
||||
background-color: #fff;
|
||||
padding-bottom: 1rpx;
|
||||
|
||||
.address {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 15rpx;
|
||||
font-size: 32rpx;
|
||||
border-bottom: 2rpx dashed #e7e7e7;
|
||||
color: #999999;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.abnormal-op {
|
||||
height: 90rpx;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 32rpx;
|
||||
padding: 0 20rpx;
|
||||
background: linear-gradient(to right, #e8edd8, white);
|
||||
|
||||
.title {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.op {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.btn-cancel,
|
||||
.btn-confirm {
|
||||
color: #fff;
|
||||
background-color: $jx-primary;
|
||||
padding: 7rpx 30rpx;
|
||||
border-radius: 7rpx;
|
||||
}
|
||||
|
||||
.btn-cancel {
|
||||
margin-right: 40rpx;
|
||||
background-color: #F60D58;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.abnormal-dealed {
|
||||
height: 90rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 32rpx;
|
||||
background: white;
|
||||
color: #333;
|
||||
|
||||
text {
|
||||
font-weight: bold;
|
||||
display: inline-block;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
|
||||
.agree {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.refuse {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<view
|
||||
class="abnormal-order position-relative"
|
||||
@tap="orderDetail(item.vendorOrderID, item.vendorID)"
|
||||
>
|
||||
<order-list-top :item="item" />
|
||||
<order-money :item="item" />
|
||||
|
||||
<!-- 地址 -->
|
||||
<view class="address">地址:{{ item.consigneeAddress }}</view>
|
||||
|
||||
<view v-if="item.lockStatus === -5">
|
||||
<view class="abnormal-op" @tap.stop v-if="(item.flag & 6) === 0">
|
||||
<view class="title">用户申请取消订单</view>
|
||||
<view class="op">
|
||||
<view class="btn-cancel" @tap.stop="fnCancelOrder(0)">拒绝</view>
|
||||
<view class="btn-confirm" @tap.stop="fnCancelOrder(1)">同意</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="abnormal-dealed" v-if="(item.flag & 6) !== 0">
|
||||
用户申请取消订单
|
||||
<text class="agree" v-if="(item.flag & 6) === 2">[已同意]</text>
|
||||
<text class="refuse" v-if="(item.flag & 6) === 6">[已拒绝]</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<template v-if="item.status === 17 && item.lockStatus === 0">
|
||||
<bottom-component
|
||||
title="骑手申请取消配送"
|
||||
@handleCancel="fnCancelDeliver(0)"
|
||||
@handleConfirm="fnCancelDeliver(1)"
|
||||
confirmText="同意"
|
||||
:order="item"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template v-if="item.status === 18 && item.lockStatus === 0">
|
||||
<bottom-component
|
||||
title="骑手取货失败"
|
||||
@handleConfirm="fnCallNew"
|
||||
confirmText="重新召唤骑手"
|
||||
:order="item"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template v-if="item.status === 22 && item.lockStatus === 0">
|
||||
<bottom-component
|
||||
title="用户拒收"
|
||||
@handleConfirm="fnGoodsReturn()"
|
||||
confirmText="确认退回"
|
||||
:order="item"
|
||||
/>
|
||||
</template>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup >
|
||||
import orderListTop from '../component/orderListTop.vue'
|
||||
import orderMoney from '../component/orderMoney.vue'
|
||||
import bottomComponent from './bottom-component.vue'
|
||||
import abonmrmalFn from './abonmrmal-order'
|
||||
import useOrderInfo from '@/composables/useOrderInfo'
|
||||
interface PropsType {
|
||||
item: AnyObject
|
||||
}
|
||||
const props = defineProps<PropsType>()
|
||||
const {
|
||||
fnCancelOrder, // 是否统一用户取消订单
|
||||
fnCancelDeliver, // 骑手申请取消
|
||||
fnCallNew, // 重新召唤骑手
|
||||
fnGoodsReturn, // 是否退回商品
|
||||
} = abonmrmalFn(props)
|
||||
const {
|
||||
orderDetail, // 订单详情
|
||||
} = useOrderInfo()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './abnormal-order.scss';
|
||||
</style>
|
||||
@@ -0,0 +1,158 @@
|
||||
import { store } from "@/store"
|
||||
import toast from "@/utils/toast"
|
||||
import order from '@/api/https/order'
|
||||
/*************************************************
|
||||
* 异常订单处理
|
||||
*/
|
||||
function abonmrmalFn(props: { item: AnyObject }) {
|
||||
|
||||
// 是否拒绝用户退款
|
||||
function fnCancelOrder(num: number) {
|
||||
let data = {
|
||||
vendorOrderID: props.item.vendorOrderID,
|
||||
vendorID: props.item.vendorID,
|
||||
acceptIt: Boolean(num),
|
||||
reason: '理由暂无'
|
||||
}
|
||||
// let data = {
|
||||
// afsOrderID: props.item.afsOrderID,
|
||||
// vendorID: props.item.vendorID,
|
||||
// approveType: num,
|
||||
// reason: '理由暂无'
|
||||
// }
|
||||
// 拒绝退款
|
||||
if (num == 0) {
|
||||
uni.jxConfirm({
|
||||
title: '提示',
|
||||
content: '是否拒绝用户取消该订单',
|
||||
success: async () => {
|
||||
let res = await order.agree_or_refuse_cancel(data)
|
||||
// let res = await order.agree_orRefuse_refund(data)
|
||||
if (res.code == 0) {
|
||||
toast('拒绝成功', 1)
|
||||
store.commit('serveInfo/setUpdateOrder', Date.now())
|
||||
} else {
|
||||
toast('决绝失败', 2)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 同意退款
|
||||
if (num == 1) {
|
||||
uni.jxConfirm({
|
||||
title: '提示',
|
||||
content: '是否同意用户取消该订单',
|
||||
success: async () => {
|
||||
let res = await order.agree_or_refuse_cancel(data)
|
||||
// let res = await order.agree_orRefuse_refund(data)
|
||||
if (res.code == 0) {
|
||||
toast('同意成功', 1)
|
||||
store.commit('serveInfo/setUpdateOrder', Date.now())
|
||||
} else {
|
||||
toast('同意失败', 2)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************************
|
||||
* 骑手申请取消
|
||||
*/
|
||||
function fnCancelDeliver(num: number) {
|
||||
let data = {
|
||||
vendorOrderID: props.item.vendorOrderID,
|
||||
vendorID: props.item.vendorID,
|
||||
acceptIt: Boolean(num),
|
||||
reason: '理由暂无'
|
||||
}
|
||||
//
|
||||
if (num == 0) {
|
||||
uni.jxConfirm({
|
||||
title: '提示',
|
||||
content: '拒绝后只能由该配送员完成本订单',
|
||||
success: async () => {
|
||||
let res = await order.accept_or_refuse_failed_get_order(data)
|
||||
if (res.code == 0) {
|
||||
store.commit('serveInfo/setUpdateOrder', Date.now())
|
||||
fnCallNew()
|
||||
} else {
|
||||
toast('操作失败', 2)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (num == 1) {
|
||||
uni.jxConfirm({
|
||||
title: '提示',
|
||||
content: '是否同意取消该订单配送',
|
||||
success: async () => {
|
||||
let res = await order.accept_or_refuse_failed_get_order(data)
|
||||
if (res.code == 0) {
|
||||
store.commit('serveInfo/setUpdateOrder', Date.now())
|
||||
fnCallNew()
|
||||
} else {
|
||||
toast('操作失败', 2)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
// 重新召唤骑手
|
||||
async function fnCallNew() {
|
||||
let data = {
|
||||
vendorOrderID: props.item.vendorOrderID,
|
||||
vendorID: props.item.vendorID
|
||||
}
|
||||
uni.jxConfirm({
|
||||
title: '提示',
|
||||
content: '是否重新召唤骑手进行配送',
|
||||
success: async () => {
|
||||
let res = await order.callP_m_courier(data)
|
||||
if (res.code == 0) {
|
||||
toast('操作成功')
|
||||
store.commit('serveInfo/setUpdateOrder', Date.now())
|
||||
} else {
|
||||
toast('操作失败')
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/*************************************************
|
||||
* 是否收到退货
|
||||
*/
|
||||
function fnGoodsReturn() {
|
||||
let data = {
|
||||
vendorOrderID: props.item.vendorOrderID,
|
||||
vendorID: props.item.vendorID,
|
||||
}
|
||||
uni.jxConfirm({
|
||||
title: '提示',
|
||||
content: '确认已经收到退回的货物',
|
||||
success: async () => {
|
||||
let res = await order.confirm_receive_goods(data)
|
||||
if (res.code == 0) {
|
||||
toast('操作成功')
|
||||
store.commit('serveInfo/setUpdateOrder', Date.now())
|
||||
} else {
|
||||
toast('操作失败')
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
fnCancelOrder, // 是否统一用户取消订单
|
||||
fnCancelDeliver, // 骑手申请取消
|
||||
fnCallNew, // 重新召唤骑手
|
||||
fnGoodsReturn, // 是否退回商品
|
||||
}
|
||||
}
|
||||
|
||||
export default abonmrmalFn
|
||||
@@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<view>
|
||||
<view
|
||||
class="abnormal-op"
|
||||
v-if="
|
||||
(order.status === 17 && (order.flag & 24) === 0) ||
|
||||
(order.status === 22 && (order.flag & 32) === 0) ||
|
||||
(order.status === 18 && (order.flag & 64) === 0)
|
||||
"
|
||||
>
|
||||
<view class="title">{{ title }}</view>
|
||||
<view class="op">
|
||||
<view class="btn-confirm" @click.stop="handleConfirm">{{
|
||||
confirmText
|
||||
}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
class="abnormal-dealed"
|
||||
v-if="
|
||||
(order.status === 17 && (order.flag & 24) !== 0) ||
|
||||
(order.status === 22 && (order.flag & 32) !== 0) ||
|
||||
(order.status === 18 && (order.flag & 64) !== 0)
|
||||
"
|
||||
>
|
||||
{{ title }}
|
||||
<text class="agree" v-if="(order.flag & 24) === 8">[已同意]</text>
|
||||
<text class="refuse" v-if="(order.flag & 24) === 24"
|
||||
>[已拒绝]请联系:18048531223</text
|
||||
>
|
||||
<text
|
||||
class="agree"
|
||||
v-if="(order.flag & 32) === 32 || (order.flag & 64) === 64"
|
||||
>[已发单]</text
|
||||
>
|
||||
<text><slot></slot></text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
interface propsType {
|
||||
title: string
|
||||
confirmText: string
|
||||
order: AnyObject
|
||||
}
|
||||
defineProps<propsType>()
|
||||
|
||||
const emits = defineEmits<{
|
||||
(e: 'handleCancel'): void
|
||||
(e: 'handleConfirm'): void
|
||||
}>()
|
||||
|
||||
// 点击取消
|
||||
function handleCancel() {
|
||||
emits('handleCancel')
|
||||
}
|
||||
|
||||
// 点击确定
|
||||
function handleConfirm() {
|
||||
emits('handleConfirm')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.abnormal-op {
|
||||
height: 90rpx;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 32rpx;
|
||||
padding: 0 20rpx;
|
||||
background: linear-gradient(to right, #e8edd8, white);
|
||||
|
||||
.title {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.op {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.btn-cancel,
|
||||
.btn-confirm {
|
||||
color: #fff;
|
||||
background-color: $jx-primary;
|
||||
padding: 7rpx 30rpx;
|
||||
border-radius: 7rpx;
|
||||
}
|
||||
|
||||
.btn-cancel {
|
||||
margin-right: 40rpx;
|
||||
background-color: #f60d58;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.abnormal-dealed {
|
||||
height: 90rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 32rpx;
|
||||
background: white;
|
||||
color: #333;
|
||||
|
||||
text {
|
||||
font-weight: bold;
|
||||
display: inline-block;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
|
||||
.agree {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.refuse {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
%globalStyle {
|
||||
border-bottom: 2rpx dashed #e7e7e7;
|
||||
padding: 15rpx;
|
||||
}
|
||||
|
||||
.position-relative {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.after-sales-root {
|
||||
background-color: #fff;
|
||||
|
||||
.top-title {
|
||||
@extend %globalStyle;
|
||||
border-bottom: 6rpx dashed #e7e7e7;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 30rpx;
|
||||
padding: 25rpx 15rpx;
|
||||
|
||||
.order {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.success {
|
||||
color: $jx-primary;
|
||||
}
|
||||
|
||||
.warring {
|
||||
color: $jx-warring;
|
||||
}
|
||||
}
|
||||
|
||||
.platform {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@extend %globalStyle;
|
||||
|
||||
.brand {
|
||||
display: inline-block;
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
flex-shrink: 0;
|
||||
background-size: 100%;
|
||||
background-repeat: no-repeat;
|
||||
border-radius: 15rpx;
|
||||
}
|
||||
|
||||
.orderSeq{
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.num {
|
||||
font-size: 30rpx;
|
||||
color: #999;
|
||||
margin-left: 15rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.detaile-text {
|
||||
@extend %globalStyle;
|
||||
color: $jx-warring;
|
||||
background-image: linear-gradient(90deg, #fffefd, #fceceb);
|
||||
}
|
||||
|
||||
.after-text {
|
||||
@extend %globalStyle;
|
||||
font-size: 34rpx;
|
||||
color: #666;
|
||||
|
||||
.mode {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.created-time {
|
||||
@extend %globalStyle;
|
||||
font-size: 32rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.shopping-count {
|
||||
@extend %globalStyle;
|
||||
font-size: 32rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.detail-btn {
|
||||
box-sizing: border-box;
|
||||
padding: 20rpx;
|
||||
margin: 15rpx;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
background-image: linear-gradient(135deg, #4eb331, #85c972);
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.tips-text {
|
||||
text-align: center;
|
||||
color: #f72a6c;
|
||||
|
||||
text {
|
||||
display: inline-block;
|
||||
padding: 15rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.operation-btn {
|
||||
@extend %globalStyle;
|
||||
|
||||
.text {
|
||||
color: #f72a6c;
|
||||
font-size: 24rpx;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.btn-root {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
|
||||
.reject,
|
||||
.resolve {
|
||||
width: 100%;
|
||||
padding: 20rpx;
|
||||
text-align: center;
|
||||
border-radius: 10rpx;
|
||||
margin-top: 15rpx;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.reject {
|
||||
margin-right: 15rpx;
|
||||
background-image: linear-gradient(135deg, #85c972, $jx-primary);
|
||||
}
|
||||
|
||||
.resolve {
|
||||
margin-left: 15rpx;
|
||||
background-image: linear-gradient(135deg, #ff6a20, #ec903f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.confirm-goods {
|
||||
@extend %globalStyle;
|
||||
|
||||
.text {
|
||||
padding: 20rpx;
|
||||
text-align: center;
|
||||
background-image: linear-gradient(135deg, #f72a6c, #f16692);
|
||||
border-radius: 10rpx;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.reson-root {
|
||||
padding: 15rpx;
|
||||
background-color: #fff;
|
||||
width: 600rpx;
|
||||
border-radius: 10rpx;
|
||||
|
||||
.title {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.textarea {
|
||||
box-sizing: border-box;
|
||||
margin: 15rpx 0;
|
||||
width: 100%;
|
||||
max-height: 200rpx;
|
||||
background-color: rgb(243, 243, 243);
|
||||
padding: 10rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.btn-root {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
border-top: 1rpx solid rgb(223, 223, 223);
|
||||
|
||||
.cancal,
|
||||
.confirm {
|
||||
width: 100%;
|
||||
padding: 20rpx 0 10rpx 0;
|
||||
text-align: center;
|
||||
|
||||
}
|
||||
|
||||
.cancal {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.confirm {
|
||||
border-left: 1rpx solid rgb(223, 223, 223);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,285 @@
|
||||
<template>
|
||||
<view
|
||||
class="after-sales-root position-relative"
|
||||
@tap="afterSalesDetaile(item.afsOrderID)"
|
||||
>
|
||||
<!-- 订单号 -->
|
||||
<view class="top-title">
|
||||
<view
|
||||
class="order"
|
||||
@tap.stop="copyInfo(item.afsOrderID, '售后单号复制成功')"
|
||||
>
|
||||
<text>售后单号:{{ item.afsOrderID }}</text>
|
||||
</view>
|
||||
<text :class="item.status == 180 ? 'success' : 'warring'">{{
|
||||
status
|
||||
}}</text>
|
||||
</view>
|
||||
|
||||
<!-- 订单平台 -->
|
||||
<view
|
||||
class="platform"
|
||||
@tap.stop="copyInfo(item.vendorOrderID, '订单号复制成功')"
|
||||
>
|
||||
<text class="brand" :class="`icon-${item.vendorID}`"></text>
|
||||
<text class="orderSeq">#{{ item.orderSeq }}</text>
|
||||
<text class="num">订单号:{{ item.vendorOrderID }}</text>
|
||||
<jx-icon icon="fuzhi" color="#818181"></jx-icon>
|
||||
</view>
|
||||
|
||||
<!-- 原因描述 -->
|
||||
<view class="detaile-text">{{ item.reasonDesc || '用户未评价' }}</view>
|
||||
|
||||
<!-- 售后方式 -->
|
||||
<view class="after-text">
|
||||
<text>售后方式:</text>
|
||||
<text class="mode">{{ afsAppealTypeName }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 申请时间 -->
|
||||
<view class="created-time"
|
||||
>申请时间:{{ timeFormatHMS(item.afsCreatedAt) || '无' }}</view
|
||||
>
|
||||
|
||||
<!-- 商品数量 -->
|
||||
<view class="shopping-count" v-if="item.skus != null"
|
||||
>共{{ item.skus.length || 0 }}份 {{ count }}件商品</view
|
||||
>
|
||||
|
||||
<!-- 驳回理由 -->
|
||||
<view class="shopping-count" v-if="item.refuseReason">
|
||||
<text>驳回理由: {{ item.refuseReason }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<view
|
||||
class="operation-btn"
|
||||
v-if="item.status === 155 && (item.flag & 3) === 0"
|
||||
>
|
||||
<text class="text"
|
||||
>若退款造成的损失较大,建议联系顾客,自行上门取回退货。</text
|
||||
>
|
||||
<view class="btn-root">
|
||||
<view class="reject" @tap.stop="popup.open()">驳回</view>
|
||||
<view class="resolve" @tap.stop="handleAgree">同意</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商家确认收到货 -->
|
||||
<view
|
||||
class="confirm-goods"
|
||||
v-if="item.status === 165 && (item.flag & 4) === 0"
|
||||
>
|
||||
<view class="text" @tap.stop="confirmGoods">商家确认收货</view>
|
||||
</view>
|
||||
|
||||
<!-- 查看详情 -->
|
||||
<view class="detail-btn">查看详情</view>
|
||||
|
||||
<!-- 提示内容 -->
|
||||
<view class="tips-text">
|
||||
<!-- 已进行审核操作 -->
|
||||
<template v-if="item.status === 155 && (item.flag & 3) !== 0">
|
||||
<text v-if="(item.flag & 3) === 1">已【同意】售后</text>
|
||||
<text v-if="(item.flag & 3) === 3">已【驳回】售后</text>
|
||||
</template>
|
||||
|
||||
<!-- 确认收货 -->
|
||||
<template v-if="item.status === 165 && (item.flag & 4) !== 0">
|
||||
<text>已确认收货</text>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<uni-popup ref="popup" type="center">
|
||||
<view class="reson-root">
|
||||
<view class="title">驳回原因</view>
|
||||
<textarea
|
||||
class="textarea"
|
||||
v-model.trim="reason"
|
||||
placeholder="请输入驳回原因"
|
||||
></textarea>
|
||||
<view class="btn-root">
|
||||
<view class="cancal" @tap="cancel">取消</view>
|
||||
<view class="confirm" @tap="handleRefuse">确定</view>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import useOrderInfo from '@/composables/useOrderInfo'
|
||||
import toast from '@/utils/toast'
|
||||
import { timeFormatHMS } from '@/utils/tools'
|
||||
import { computed, ref } from 'vue'
|
||||
import { store } from '@/store'
|
||||
import order from '@/api/https/order'
|
||||
const {
|
||||
copyInfo, // 复制内容
|
||||
afterSalesDetaile, // 售后详情
|
||||
} = useOrderInfo()
|
||||
|
||||
interface PropsType {
|
||||
item: any
|
||||
}
|
||||
const props = defineProps<PropsType>()
|
||||
|
||||
/**
|
||||
* 售后状态
|
||||
*/
|
||||
const status = computed(() => {
|
||||
switch (props.item.status) {
|
||||
case 155:
|
||||
return '待审核'
|
||||
case 160:
|
||||
return '已审核'
|
||||
case 165:
|
||||
return '退货待确认'
|
||||
case 167:
|
||||
return '退货已收到'
|
||||
case 180:
|
||||
return '售后成功'
|
||||
case 190:
|
||||
return '售后失败'
|
||||
default:
|
||||
return '未知'
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 售后方式
|
||||
*/
|
||||
const afsAppealTypeName = computed(() => {
|
||||
switch (props.item.appealType) {
|
||||
case 1:
|
||||
return '仅退款'
|
||||
case 2:
|
||||
return '退货退款'
|
||||
case 3:
|
||||
return '重发商品'
|
||||
default:
|
||||
return '未知'
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 商品数量
|
||||
*/
|
||||
const count = computed(() => {
|
||||
let num = 0
|
||||
props.item.skus.forEach((item: any) => {
|
||||
num += item.count
|
||||
})
|
||||
return num
|
||||
})
|
||||
|
||||
/**
|
||||
* 驳回售后
|
||||
*/
|
||||
const popup = ref<any>(null)
|
||||
const reason = ref<string>('')
|
||||
async function agreeOrRefuse(type: number) {
|
||||
// if (props.item.vendorID == 3) {
|
||||
// // 饿百订单
|
||||
// if (type === 1) {
|
||||
// // 同意
|
||||
// let data = {
|
||||
// vendorOrderID: props.item.vendorOrderID,
|
||||
// vendorID: props.item.vendorID,
|
||||
// acceptIt: Boolean(1), // 拒绝为0,同意为1
|
||||
// reason: type === 1 ? '同意退款' : reason.value,
|
||||
// }
|
||||
// let res = await order.agree_or_refuse_cancel(data)
|
||||
// judge(res)
|
||||
// } else {
|
||||
// // type ===3 驳回
|
||||
// let data = {
|
||||
// vendorOrderID: props.item.vendorOrderID,
|
||||
// vendorID: props.item.vendorID,
|
||||
// acceptIt: Boolean(1), // 拒绝为0,同意为1
|
||||
// reason: type === 1 ? '同意退款' : reason.value,
|
||||
// }
|
||||
// let res = await order.agree_or_refuse_cancel(data)
|
||||
// judge(res)
|
||||
// }
|
||||
// } else {
|
||||
// // 非饿百订单
|
||||
// 退货退款
|
||||
let data = {
|
||||
afsOrderID: props.item.afsOrderID,
|
||||
vendorID: props.item.vendorID,
|
||||
approveType: type,
|
||||
reason: type === 1 ? '同意退款' : reason.value,
|
||||
}
|
||||
let res = await order.agree_orRefuse_refund(data)
|
||||
judge(res)
|
||||
// }
|
||||
}
|
||||
async function handleRefuse() {
|
||||
if (reason.value) {
|
||||
agreeOrRefuse(3)
|
||||
} else {
|
||||
toast('请输入驳回原因')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断驳回信息
|
||||
*/
|
||||
function judge(res: AnyObject) {
|
||||
if (res.code == 0) {
|
||||
toast('操作成功', 1)
|
||||
cancel()
|
||||
// 刷新订单
|
||||
store.commit('serveInfo/setUpdateOrder', Date.now())
|
||||
} else {
|
||||
uni.jxAlert({
|
||||
title: '错误',
|
||||
content: res.desc,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭驳回弹窗
|
||||
*/
|
||||
function cancel() {
|
||||
reason.value = ''
|
||||
popup.value.close()
|
||||
}
|
||||
|
||||
/**
|
||||
* 同意售后
|
||||
*/
|
||||
function handleAgree() {
|
||||
uni.jxConfirm({
|
||||
title: '提示',
|
||||
content: '是否同意处理该售后单',
|
||||
success: () => {
|
||||
agreeOrRefuse(1)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 商家确认收货
|
||||
*/
|
||||
function confirmGoods() {
|
||||
uni.jxConfirm({
|
||||
title: '提示',
|
||||
content: '是否已经收到货',
|
||||
success: async () => {
|
||||
let data = {
|
||||
afsOrderID: props.item.afsOrderID,
|
||||
vendorID: props.item.vendorID,
|
||||
}
|
||||
let res = await order.confirm_received_return_goods(data)
|
||||
judge(res)
|
||||
},
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './after-sales-order.scss';
|
||||
</style>
|
||||
120
src/pages/order-manager/childPages/completed/completed.vue
Normal file
120
src/pages/order-manager/childPages/completed/completed.vue
Normal file
@@ -0,0 +1,120 @@
|
||||
<template>
|
||||
<view
|
||||
class="compelet-root position-relative"
|
||||
@tap="orderDetail(item.vendorOrderID, item.vendorID)"
|
||||
>
|
||||
<order-list-top :item="item" />
|
||||
<order-money :item="item" />
|
||||
|
||||
<!-- 地址 -->
|
||||
<view class="address">地址:{{ item.buyerComment.includes('支付方式') ? store.getters['storeInfo/storeAddress'] : item.consigneeAddress }}</view>
|
||||
|
||||
<!-- 配送信息 -->
|
||||
<view class="distribution-msg" v-if="!item.buyerComment.includes('支付方式')">
|
||||
<text class="vender-name">{{ wbVendor }}</text>
|
||||
<text class="distribution-name">{{ item.courierName }}</text>
|
||||
<text
|
||||
v-if="item.courierMobile.split(',')[1]"
|
||||
class="distribution-mobile"
|
||||
@tap.stop="phoneCall(item.courierMobile)"
|
||||
>{{
|
||||
item.courierMobile.split(',')[0] +
|
||||
'转' +
|
||||
item.courierMobile.split(',')[1]
|
||||
}}</text
|
||||
>
|
||||
<text
|
||||
v-else
|
||||
class="distribution-mobile"
|
||||
@tap.stop="phoneCall(item.courierMobile)"
|
||||
>{{ item.courierMobile }}</text
|
||||
>
|
||||
<jx-icon
|
||||
v-show="item.courierMobile != ''"
|
||||
icon="24gf-telephone"
|
||||
color="#999999"
|
||||
@tap.stop="phoneCall(item.courierMobile)"
|
||||
:size="38"
|
||||
style="margin-left: 10rpx"
|
||||
/>
|
||||
</view>
|
||||
<!-- 查看详情 -->
|
||||
<view class="detail-btn">查看详情</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import useOrderInfo from '@/composables/useOrderInfo'
|
||||
import { computed } from 'vue'
|
||||
import orderListTop from '../component/orderListTop.vue'
|
||||
import orderMoney from '../component/orderMoney.vue'
|
||||
import { store } from '@/store'
|
||||
|
||||
const {
|
||||
orderDetail, // 订单详情
|
||||
phoneCall, // 复制手机号
|
||||
waybillVendor, // 转换厂商
|
||||
} = useOrderInfo()
|
||||
|
||||
interface PropsType {
|
||||
item: any
|
||||
}
|
||||
const props = defineProps<PropsType>()
|
||||
|
||||
/**
|
||||
* 转换快递厂商
|
||||
*/
|
||||
const wbVendor = computed(() => {
|
||||
return waybillVendor(
|
||||
props.item.waybillVendorID,
|
||||
props.item.status,
|
||||
props.item.waybillStatus
|
||||
)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.position-relative {
|
||||
position: relative;
|
||||
}
|
||||
.compelet-root {
|
||||
background-color: #fff;
|
||||
padding-bottom: 1rpx;
|
||||
|
||||
.address {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 15rpx;
|
||||
font-size: 32rpx;
|
||||
color: #000000;
|
||||
background-color: rgba($color: #908f96, $alpha: 0.15);
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.detail-btn {
|
||||
background-color: #fff;
|
||||
padding: 20rpx;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
background-image: linear-gradient(135deg, #4eb331, #85c972);
|
||||
margin: 15rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.distribution-msg {
|
||||
padding: 15rpx;
|
||||
border-bottom: 2rpx dashed #e7e7e7;
|
||||
|
||||
.vender-name {
|
||||
color: #999999;
|
||||
margin-right: 25rpx;
|
||||
}
|
||||
.distribution-name {
|
||||
margin-right: 25rpx;
|
||||
}
|
||||
.distribution-mobile {
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
514
src/pages/order-manager/childPages/component/orderListTop.vue
Normal file
514
src/pages/order-manager/childPages/component/orderListTop.vue
Normal file
@@ -0,0 +1,514 @@
|
||||
<template>
|
||||
<!-- 订单信息 -->
|
||||
<view class="order-info">
|
||||
<view class="order">
|
||||
<view class="h-number index-color">
|
||||
<text class="brand" :class="`icon-${item.vendorID}`"></text>
|
||||
<text class="num-root">
|
||||
<text>#</text>
|
||||
<text class="num">{{ item.orderSeq }}</text>
|
||||
</text>
|
||||
</view>
|
||||
<view class="timer" v-if="!item.buyerComment.includes('支付方式')">预计{{ expectedDeliveredTime }}前送达</view>
|
||||
</view>
|
||||
<view v-if="isSrestPickTime" v-html="restPickTime"></view>
|
||||
|
||||
<view v-if="isCancelTime">
|
||||
<view v-if="item.lockStatus === -5 && (item.flag & 6) === 0">
|
||||
<text class="rest-time canceltime"
|
||||
>{{ cancelTime
|
||||
}}<text v-if="cancelTime !== '已超时'">分钟</text></text
|
||||
>
|
||||
</view>
|
||||
<text class="order-delivered">{{ abnormalStatus }}</text>
|
||||
</view>
|
||||
<!-- 状态展示 -->
|
||||
<text class="compelet" v-if="item.status === 110">已完成</text>
|
||||
<text class="cancel" v-else-if="item.status === 115">已取消</text>
|
||||
<text class="fail" v-else-if="item.status === 120">已失败</text>
|
||||
</view>
|
||||
|
||||
<!-- 用户名字 -->
|
||||
<view class="order-title" v-if="!item.buyerComment.includes('支付方式')">
|
||||
<!-- <view class="title-left" > -->
|
||||
<view >
|
||||
<text class="name">{{ item.consigneeName.slice(0, 1) }}...</text>
|
||||
<!-- <text class="name">{{ item.consigneeName }}</text> -->
|
||||
<!-- <img src="https://image.jxc4.com/jxapp/z_send_normal.png" alt="" class="connectUser" @tap.stop="connectUser(item)"> -->
|
||||
</view>
|
||||
|
||||
<!-- class="connectUser" -->
|
||||
<!-- <view style="width: 38rpx;height: 38rpx;"><img src="https://image.jxc4.com/jxapp/callPhone.png" alt="" style="width: 38rpx;height: 38rpx;" @tap.stop="connectUser(item)"></view> -->
|
||||
<view class="see-map" @tap.stop="callPhone(item)">拨打电话</view>
|
||||
|
||||
<!-- <view style="width: 38rpx;height: 38rpx;"><img src="https://image.jxc4.com/jxapp/sendMessage.png" alt="" style="width: 38rpx;height: 38rpx;" @tap.stop="connectUser(item)"></view> -->
|
||||
<view class="see-map" @tap.stop="connectUser(item)">发消息</view>
|
||||
|
||||
<!-- <view class="phone">
|
||||
<view>
|
||||
<text v-if="item.consigneeMobile">临1:</text>
|
||||
<text
|
||||
class="phone-number"
|
||||
@tap.stop="phoneCall(item.consigneeMobile)"
|
||||
v-if="item.consigneeMobile.split(',')[1]"
|
||||
>{{
|
||||
item.consigneeMobile.split(',')[0] +
|
||||
'转' +
|
||||
item.consigneeMobile.split(',')[1]
|
||||
}}</text
|
||||
>
|
||||
<text
|
||||
v-else
|
||||
class="phone-number"
|
||||
@tap.stop="phoneCall(item.consigneeMobile)"
|
||||
>{{ item.consigneeMobile }}</text
|
||||
>
|
||||
<br />
|
||||
真实号
|
||||
<text v-if="item.consigneeMobile2">临2:</text>
|
||||
<text
|
||||
class="phone-number"
|
||||
@tap.stop="phoneCall(item.consigneeMobile2)"
|
||||
v-if="item.consigneeMobile2.split(',')[1]"
|
||||
>{{
|
||||
item.consigneeMobile2.split(',')[0] +
|
||||
'转' +
|
||||
item.consigneeMobile2.split(',')[1]
|
||||
}}</text
|
||||
>
|
||||
<text
|
||||
v-else
|
||||
:class="item.consigneeMobile2 ? 'phone-number' : ''"
|
||||
@tap.stop="phoneCall(item.consigneeMobile2)"
|
||||
>{{ item.consigneeMobile2 }}</text
|
||||
>
|
||||
</view> -->
|
||||
<!-- </view> -->
|
||||
<!-- </view> -->
|
||||
<!-- style="height:25px;line-height:25px;margin:auto 10px;" -->
|
||||
<view class="see-map" @tap.stop="seeMap">查看地图</view>
|
||||
</view>
|
||||
|
||||
<!-- 订单号 -->
|
||||
<view class="order-number" @tap.stop="copyInfo(orderNum, '复制订单号成功')">
|
||||
<text class="number">订单号:{{ orderNum }}</text>
|
||||
<text class="copy">复制</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import useOrderInfo from '@/composables/useOrderInfo'
|
||||
import { store } from '@/store'
|
||||
import { isNullDate } from '@/utils/tools'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { computed, ref } from 'vue'
|
||||
import { setStorage } from "@/utils/storage";
|
||||
import toast from "@/utils/toast";
|
||||
const {
|
||||
copyInfo, // 复制内容
|
||||
phoneCall, // 拨号
|
||||
} = useOrderInfo()
|
||||
|
||||
interface PropsType {
|
||||
item: any
|
||||
}
|
||||
let props = defineProps<PropsType>()
|
||||
|
||||
|
||||
/**
|
||||
* 拨打电话
|
||||
*/
|
||||
function callPhone(item:AnyObject) {
|
||||
// let itemList = [item.consigneeMobile,item.consigneeMobile2]
|
||||
let itemList:string[] = []
|
||||
if(item.consigneeMobile) itemList.push('临1:' + item.consigneeMobile.split(',')[0] +'转' + item.consigneeMobile.split(',')[1])
|
||||
if(item.consigneeMobile2) itemList.push('临2:' + item.consigneeMobile2.split(',')[0] +'转' + item.consigneeMobile2.split(',')[1])
|
||||
if(itemList.length === 0) return toast('该订单暂无联系方式', 2)
|
||||
uni.showActionSheet({
|
||||
// title: '退出后不会删除任何数据',
|
||||
itemColor: '#4eb331',
|
||||
itemList,
|
||||
popover: {
|
||||
width: 5000,
|
||||
},
|
||||
success: function (res) {
|
||||
if(res.tapIndex === 0) phoneCall(item.consigneeMobile)
|
||||
if(res.tapIndex === 1) phoneCall(item.consigneeMobile2)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/*************************************************
|
||||
* 联系用户
|
||||
*/
|
||||
function connectUser(item:AnyObject) {
|
||||
|
||||
if(item.vendorID === 1){
|
||||
if(store.getters['storeInfo/imMtStatus'][0].imStatus !== 1) return toast('美团IM状态已关闭', 1)
|
||||
setStorage('vendorUserInfo',{
|
||||
venderOrderID:item.vendorOrderID,
|
||||
orderSeq:item.orderSeq,
|
||||
vendorOrgCode:item.vendorOrgCode,
|
||||
vendorStoreID:item.vendorStoreID,
|
||||
userID:item.vendorUserID,
|
||||
vendorID:item.vendorID
|
||||
})
|
||||
uni.navigateTo({ url: '/subPages/messageChild/msgChat/msgChat' })
|
||||
}else{
|
||||
// 饿百
|
||||
toast('暂不支持聊天', 2)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************************
|
||||
* 查看地图
|
||||
*/
|
||||
function seeMap() {
|
||||
uni.navigateTo({
|
||||
url: `/subPages/orderChild/seeMap/seeMap?vendorOrderID=${props.item.vendorOrderID}&vendorID=${props.item.vendorID}`,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否显示已超时
|
||||
*/
|
||||
const isCancelTime = computed(() => {
|
||||
return (
|
||||
(props.item.status === 17 ||
|
||||
props.item.status === 18 ||
|
||||
props.item.status === 22) &&
|
||||
props.item.lockStatus !== -5
|
||||
)
|
||||
})
|
||||
|
||||
/**
|
||||
* 是否显示预计送达时间
|
||||
*/
|
||||
const isSrestPickTime = computed(() => {
|
||||
return (
|
||||
(props.item.status === 10 ||
|
||||
props.item.status === 15 ||
|
||||
props.item.status === 20) &&
|
||||
props.item.lockStatus === 0
|
||||
)
|
||||
})
|
||||
|
||||
/**
|
||||
* 订单号转换
|
||||
*/
|
||||
const orderNum = computed(() => {
|
||||
return props.item.vendorID === 3
|
||||
? props.item.vendorOrderID2
|
||||
: props.item.vendorOrderID
|
||||
})
|
||||
|
||||
/**
|
||||
* 异常订单转换
|
||||
*/
|
||||
const abnormalStatus = computed(() => {
|
||||
let order = props.item
|
||||
if (order.lockStatus === -5) {
|
||||
return '申请取消'
|
||||
} else if (order.status === 17) {
|
||||
return '待审核'
|
||||
} else if (order.status === 18) {
|
||||
return '取货失败'
|
||||
} else if (order.status === 22) {
|
||||
return '投递失败'
|
||||
} else {
|
||||
return '未知'
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 待接单预计超时时间
|
||||
*/
|
||||
const cancelTime = ref<any>()
|
||||
const timer = ref<any>()
|
||||
onShow(() => {
|
||||
if (props.item.lockStatus === -5) {
|
||||
let { purchaseVendorInfo } = store.state.serveInfo.sysInfo as any
|
||||
let { userApplyCancelWaitMinute } = purchaseVendorInfo[props.item.vendorID]
|
||||
let cancelTime1 =
|
||||
new Date(props.item.lockStatusTime).getTime() +
|
||||
userApplyCancelWaitMinute * 60 * 1000 -
|
||||
new Date().getTime()
|
||||
cancelTime.value =
|
||||
cancelTime1 > 0 ? `${new Date(cancelTime1).getMinutes()}` : '已超时'
|
||||
timer.value = setInterval(() => {
|
||||
cancelTime1 =
|
||||
new Date(props.item.lockStatusTime).getTime() +
|
||||
userApplyCancelWaitMinute * 60 * 1000 -
|
||||
new Date().getTime()
|
||||
cancelTime.value =
|
||||
cancelTime1 > 0 ? `${new Date(cancelTime1).getMinutes()}` : '已超时'
|
||||
}, 1000)
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 预计送达时间
|
||||
*/
|
||||
const expectedDeliveredTime = computed(() => {
|
||||
let timer: any = ''
|
||||
if (isNullDate(props.item.expectedDeliveredTime)) {
|
||||
// 预计送达时间无的情况
|
||||
timer = new Date(
|
||||
new Date(props.item.orderCreatedAt).getTime() + 60 * 60 * 1000
|
||||
)
|
||||
} else {
|
||||
timer = new Date(props.item.expectedDeliveredTime)
|
||||
}
|
||||
return `${
|
||||
timer.getHours() < 10 ? '0' + timer.getHours() : timer.getHours()
|
||||
}:${timer.getMinutes() < 10 ? '0' + timer.getMinutes() : timer.getMinutes()}`
|
||||
})
|
||||
|
||||
/**
|
||||
* 剩余拣货时间 || 剩余用户自己取消订单时间
|
||||
*/
|
||||
const restPickTime = computed(() => {
|
||||
// 拣货结束时间time1 = 预计送达时间 - 30分钟
|
||||
let time1: any = ''
|
||||
if (isNullDate(props.item.pickDeadline)) {
|
||||
// 没有拣货时间
|
||||
if (isNullDate(props.item.expectedDeliveredTime)) {
|
||||
// 预计送达时间为空
|
||||
time1 = new Date(props.item.orderCreatedAt).getTime() + 30 * 60 * 1000
|
||||
} else {
|
||||
// 预计送达时间有
|
||||
time1 =
|
||||
new Date(props.item.expectedDeliveredTime).getTime() - 30 * 60 * 1000
|
||||
}
|
||||
} else {
|
||||
// 有拣货时间
|
||||
time1 = new Date(props.item.pickDeadline).getTime()
|
||||
}
|
||||
let restTime = (time1 - new Date().getTime()) / 1000 / 60 // 分钟
|
||||
restTime = Math.floor(restTime)
|
||||
// 送达时间
|
||||
let time2: any = ''
|
||||
if (isNullDate(props.item.expectedDeliveredTime)) {
|
||||
// 时间是空
|
||||
time2 =
|
||||
new Date(props.item.orderCreatedAt).getTime() +
|
||||
60 * 60 * 1000 -
|
||||
new Date().getTime()
|
||||
} else {
|
||||
time2 =
|
||||
new Date(props.item.expectedDeliveredTime).getTime() -
|
||||
new Date().getTime()
|
||||
}
|
||||
let arrivedTime = Math.floor(time2 / 1000 / 60)
|
||||
switch (props.item.status) {
|
||||
case 10:
|
||||
if (props.item.lockStatus === 0) {
|
||||
if (restTime < 0) {
|
||||
// 超时
|
||||
return `<span class="order-bg-cs"> </span>`
|
||||
} else if (restTime < 5) {
|
||||
// 小于5分钟
|
||||
return `<span class="rest-time picktime3">${restTime}分钟</span>`
|
||||
} else if (restTime < 10) {
|
||||
// 小于10分钟
|
||||
return `<span class="rest-time picktime2">${restTime}分钟</span>`
|
||||
} else if (restTime > 60 && props.item.businessType === 2) {
|
||||
// 预订单
|
||||
return `<span class="order-bg-dsd"> </span>`
|
||||
} else {
|
||||
// 通常
|
||||
return `<span class="rest-time picktime1">${restTime}分钟</span>`
|
||||
}
|
||||
} else {
|
||||
return `<span class="order-delivered">已锁定</span>`
|
||||
}
|
||||
case 15:
|
||||
return sendTime(arrivedTime)
|
||||
case 20:
|
||||
return sendTime(arrivedTime)
|
||||
case 105:
|
||||
return `<span class="order-delivered">已送达</span>`
|
||||
case 110:
|
||||
return `<span class="order-delivered">已送达</span>`
|
||||
case 115:
|
||||
return `<span class="order-delivered">已取消</span>`
|
||||
case 120:
|
||||
return `<span class="order-delivered">已失败</span>`
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
})
|
||||
function sendTime(time: any) {
|
||||
if (time < 0) {
|
||||
// 超时
|
||||
return `<span class="order-bg-cs"> </span>`
|
||||
} else if (time < 5) {
|
||||
// 小于5分钟
|
||||
return `<span class="rest-time arrived3">${time}分钟</span>`
|
||||
} else if (time < 20) {
|
||||
// 小于20分钟
|
||||
return `<span class="rest-time arrived2">${time}分钟</span>`
|
||||
} else if (time > 60 && props.item.businessType === 2) {
|
||||
// 预订单
|
||||
return `<span class="order-bg-dsd"> </span>`
|
||||
} else {
|
||||
// 通常
|
||||
return `<span class="rest-time arrived1">${time}分钟</span>`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否显示已完成,预计送达文字
|
||||
*/
|
||||
const isShow = computed(() => {
|
||||
if (
|
||||
props.item.status == 110 ||
|
||||
props.item.status == 115 ||
|
||||
props.item.status == 120
|
||||
) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 表哦提
|
||||
.order-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 20rpx 15rpx;
|
||||
background-color: #fff;
|
||||
border-bottom: 6rpx dashed #e7e7e7;
|
||||
|
||||
.order {
|
||||
.timer {
|
||||
margin-top: 6rpx;
|
||||
color: rgb(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.index-color {
|
||||
color: rgb(0, 0, 0);
|
||||
}
|
||||
|
||||
.h-number {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.brand {
|
||||
display: inline-block;
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
flex-shrink: 0;
|
||||
background-size: 100%;
|
||||
background-repeat: no-repeat;
|
||||
border-radius: 15rpx;
|
||||
}
|
||||
|
||||
.num-root {
|
||||
margin-left: 5rpx;
|
||||
}
|
||||
|
||||
.num {
|
||||
font-size: 50rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.compelet {
|
||||
color: #000;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.cancel {
|
||||
color: #f60d58;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.fail {
|
||||
color: $jx-warring;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
// 顶部标题
|
||||
.order-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
background-color: #ffffff;
|
||||
// padding: 15rpx;
|
||||
padding: 10rpx;
|
||||
border-bottom: 2rpx dashed #e7e7e7;
|
||||
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
|
||||
.name {
|
||||
color: #999999;
|
||||
// margin-right: 20rpx;
|
||||
}
|
||||
|
||||
// .title-left {
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
// justify-content: space-between;
|
||||
// width: calc(100% - 90px);
|
||||
// padding: 10rpx;
|
||||
// box-sizing: border-box;
|
||||
|
||||
|
||||
// .name {
|
||||
// color: #999999;
|
||||
// margin-right: 20rpx;
|
||||
// }
|
||||
|
||||
// .connectUser{
|
||||
// width: 38rpx;
|
||||
// height: 38rpx;
|
||||
// }
|
||||
|
||||
// // .phone {
|
||||
// // color: #999999;
|
||||
// // display: flex;
|
||||
// // align-items: center;
|
||||
// // margin-left: 10rpx;
|
||||
|
||||
// // .phone-number {
|
||||
// // margin-right: 10rpx;
|
||||
// // }
|
||||
// // }
|
||||
// }
|
||||
}
|
||||
|
||||
.order-number {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
white-space: nowrap;
|
||||
padding: 15rpx;
|
||||
border-bottom: 2rpx dashed #e7e7e7;
|
||||
color: #999999;
|
||||
|
||||
.copy {
|
||||
font-size: 26rpx;
|
||||
padding: 4rpx 12rpx;
|
||||
border-radius: 5rpx;
|
||||
border: 2rpx solid #999999;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
.see-map {
|
||||
font-size: 28rpx;
|
||||
padding: 7rpx 12rpx;
|
||||
border-radius: 5rpx;
|
||||
background-color: rgba($color: $jx-primary, $alpha: 0.15);
|
||||
color: $jx-primary;
|
||||
|
||||
height:25px;
|
||||
line-height:25px;
|
||||
margin:auto 10px;
|
||||
}
|
||||
</style>
|
||||
79
src/pages/order-manager/childPages/component/orderMoney.vue
Normal file
79
src/pages/order-manager/childPages/component/orderMoney.vue
Normal file
@@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<view class="order-totalCount">
|
||||
<text class="totalCount"
|
||||
>共{{ item.skuCount }}种{{ item.goodsCount }}件商品</text
|
||||
>
|
||||
<view>
|
||||
{{
|
||||
item.vendorPayPercentage != 0
|
||||
? item.vendorPayPercentage < 50
|
||||
? '实际支付:'
|
||||
: '实际收入:'
|
||||
: isPointStore
|
||||
? '实际支付:'
|
||||
: '实际收入:'
|
||||
}}<jx-real-income :orderData="item" color="#585858" />
|
||||
</view>
|
||||
|
||||
<!-- 预定单 -->
|
||||
<view class="preIcon" v-if="item.businessType === 2">预订单</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { store } from '@/store'
|
||||
import { computed } from 'vue'
|
||||
|
||||
interface PropsType {
|
||||
item: any
|
||||
}
|
||||
defineProps<PropsType>()
|
||||
|
||||
const isPointStore = computed(() => {
|
||||
return store.getters['storeInfo/isPointStore']
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 商品数量
|
||||
.order-totalCount {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 15rpx;
|
||||
border-bottom: 2rpx dashed #e7e7e7;
|
||||
color: #585858;
|
||||
|
||||
.play-money {
|
||||
margin-left: 30rpx;
|
||||
}
|
||||
|
||||
.totalCount {
|
||||
margin-right: 25rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.preIcon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: 4rpx 20rpx 6rpx 20rpx;
|
||||
font-size: 26rpx;
|
||||
color: #fff;
|
||||
border-radius: 0 0 0 10rpx;
|
||||
background-color: #ff702c;
|
||||
}
|
||||
|
||||
@keyframes enlarge {
|
||||
0% {
|
||||
transform: scale(0.9);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(0.9);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
45
src/pages/order-manager/childPages/jx-tab/jx-tab.scss
Normal file
45
src/pages/order-manager/childPages/jx-tab/jx-tab.scss
Normal file
@@ -0,0 +1,45 @@
|
||||
.jx-tabs {
|
||||
border-top: 1rpx solid #f8f8f8;
|
||||
background-color: #fff;
|
||||
border-bottom: 1rpx solid rgb(214, 214, 214);
|
||||
}
|
||||
|
||||
.tab-scroll {
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
height: 95rpx;
|
||||
line-height: 94rpx;
|
||||
}
|
||||
|
||||
|
||||
.scroll-item {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 150rpx;
|
||||
text-align: center;
|
||||
text-align: center;
|
||||
font-size: 33rpx;
|
||||
transition: all 0.2s;
|
||||
|
||||
.badge {
|
||||
position: absolute;
|
||||
right: -5rpx;
|
||||
top: 4rpx;
|
||||
border-radius: 100rpx 100rpx 100rpx 0;
|
||||
font-size: 28rpx;
|
||||
min-width: 40rpx;
|
||||
min-height: 40rpx;
|
||||
padding: 3rpx;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
line-height: 40rpx;
|
||||
color: #fff;
|
||||
background-color: #f60d58;
|
||||
}
|
||||
}
|
||||
|
||||
.jxTabsActive {
|
||||
color: #4eb331;
|
||||
font-weight: bold;
|
||||
font-size: 37rpx;
|
||||
}
|
||||
161
src/pages/order-manager/childPages/jx-tab/jx-tab.ts
Normal file
161
src/pages/order-manager/childPages/jx-tab/jx-tab.ts
Normal file
@@ -0,0 +1,161 @@
|
||||
/**
|
||||
* 订单木块方法
|
||||
*/
|
||||
import { Ref, ref } from "vue";
|
||||
import { getStorage } from '@/utils/storage'
|
||||
import { onShow } from "@dcloudio/uni-app";
|
||||
import order from '@/api/https/order'
|
||||
|
||||
function tabFn() {
|
||||
onShow(async () => {
|
||||
await getOrderCount()
|
||||
})
|
||||
|
||||
|
||||
/**
|
||||
* tab 菜单栏数据
|
||||
*/
|
||||
const currentStatus: Ref<number> = ref(2);
|
||||
interface OrderStatusType {
|
||||
id: number;
|
||||
status: number | Array<number>;
|
||||
name: string;
|
||||
count: number;
|
||||
}
|
||||
const orderStatus = ref<OrderStatusType[]>([
|
||||
{
|
||||
id: 1,
|
||||
status: [3],
|
||||
name: "待接单",
|
||||
count: 0,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
status: [10],
|
||||
name: "待拣货",
|
||||
count: 0,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
status: [15],
|
||||
name: "待配送",
|
||||
count: 0,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
status: [20],
|
||||
name: "配送中",
|
||||
count: 0,
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
status: [5, 10, 15, 20, 17, 18, 22],
|
||||
name: "异常单",
|
||||
count: 0,
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
status: [155, 160, 165, 167, 180, 190],
|
||||
name: "售后单",
|
||||
count: 0,
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
status: [110, 115, 120],
|
||||
name: "已完成",
|
||||
count: 0,
|
||||
},
|
||||
]);
|
||||
|
||||
|
||||
/**
|
||||
* tab 点击事件
|
||||
*/
|
||||
const scrollLeft: Ref<number> = ref(0); // 滚动到左边距离
|
||||
const record: Ref<number> = ref(1); // 记录值
|
||||
function clickTab(id: number, recordID: number, e: AnyObject) {
|
||||
currentStatus.value = id;
|
||||
// 判断左右滑动
|
||||
let { offsetLeft } = e.target;
|
||||
if (id > recordID) {
|
||||
scrollLeft.value = offsetLeft - 75;
|
||||
} else {
|
||||
scrollLeft.value = offsetLeft - 75 * 3;
|
||||
}
|
||||
record.value = id; // 赋值记录纸
|
||||
// 更新条数
|
||||
getOrderCount()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 请求订单数量信息
|
||||
*/
|
||||
async function getOrderCount() {
|
||||
let orderData = {
|
||||
storeID: getStorage('storeID'),
|
||||
lastHours: new Date().getHours() * 1 + 48
|
||||
}
|
||||
// 订单数量
|
||||
let orderCount = await order.Get_store_rder_count_info(orderData)
|
||||
// 售后单量
|
||||
let afsCount = await order.Get_store_afs_order_countinfo(orderData)
|
||||
if (orderCount.code == 0 && afsCount.code == 0) {
|
||||
// 没有数据默认一个空数组
|
||||
let data = orderCount.data || []
|
||||
let data2 = afsCount.data || []
|
||||
|
||||
// 判断显示条数
|
||||
if (data.length > 0) {
|
||||
// 3 待接单
|
||||
orderStatus.value[0].count = data.filter((item: any) => item.status === 3 && item.lockStatus === 0).length > 0 ? data.filter((item: any) => item.status === 3 && item.lockStatus === 0)[0].count : 0
|
||||
orderStatus.value[0].count += data.filter((item: any) => item.status === 3 && item.lockStatus === -20).length > 0 ? data.filter((item: any) => item.status === 3 && item.lockStatus === 0)[0].count : 0
|
||||
// 10 待拣货
|
||||
orderStatus.value[1].count = data.filter((item: any) => item.status === 10 && item.lockStatus === 0).length > 0 ? data.filter((item: any) => item.status === 10 && item.lockStatus === 0)[0].count : 0
|
||||
orderStatus.value[1].count += data.filter((item: any) => item.status === 10 && item.lockStatus === -20).length > 0 ? data.filter((item: any) => item.status === 10 && item.lockStatus === 0)[0].count : 0
|
||||
// 15 待配送
|
||||
orderStatus.value[2].count = data.filter((item: any) => item.status === 15 && item.lockStatus === 0).length > 0 ? data.filter((item: any) => item.status === 15 && item.lockStatus === 0)[0].count : 0
|
||||
orderStatus.value[2].count += data.filter((item: any) => item.status === 15 && item.lockStatus === -20).length > 0 ? data.filter((item: any) => item.status === 15 && item.lockStatus === -20)[0].count : 0
|
||||
// 20 配送中
|
||||
orderStatus.value[3].count = data.filter((item: any) => item.status === 20 && item.lockStatus === 0).length > 0 ? data.filter((item: any) => item.status === 20 && item.lockStatus === 0)[0].count : 0
|
||||
orderStatus.value[3].count += data.filter((item: any) => item.status === 20 && item.lockStatus === -20).length > 0 ? data.filter((item: any) => item.status === 20 && item.lockStatus === -20)[0].count : 0
|
||||
// 17 异常单
|
||||
orderStatus.value[4].count = data.filter((item: any) => item.status === 17 && item.lockStatus === 0).length > 0 ? data.filter((item: any) => item.status === 17 && item.lockStatus === 0)[0].count : 0
|
||||
// 18 已完成
|
||||
orderStatus.value[4].count += data.filter((item: any) => item.status === 18 && item.lockStatus === 0).length > 0 ? data.filter((item: any) => item.status === 18 && item.lockStatus === 0)[0].count : 0
|
||||
// 22 已完成
|
||||
orderStatus.value[4].count += data.filter((item: any) => item.status === 22 && item.lockStatus === 0).length > 0 ? data.filter((item: any) => item.status === 22 && item.lockStatus === 0)[0].count : 0
|
||||
orderStatus.value[4].count += data.filter((item: any) => item.lockStatus === -5 && item.status < 100).length > 0 ? data.filter((item: any) => item.lockStatus === -5 && item.status < 100)[0].count : 0
|
||||
} else {
|
||||
orderStatus.value[0].count = 0
|
||||
orderStatus.value[1].count = 0
|
||||
orderStatus.value[2].count = 0
|
||||
orderStatus.value[3].count = 0
|
||||
orderStatus.value[4].count = 0
|
||||
}
|
||||
// 售后单
|
||||
if (data2.length > 0) {
|
||||
orderStatus.value[5].count = data2.find((item: any) => item.status === 155) ? data2.find((item: any) => item.status === 155).count : 0
|
||||
orderStatus.value[5].count += data2.find((item: any) => item.status === 165) ? data2.find((item: any) => item.status === 155).count : 0
|
||||
} else {
|
||||
orderStatus.value[5].count = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 导出数据
|
||||
*/
|
||||
return {
|
||||
currentStatus, // 高亮初始值
|
||||
orderStatus, // tab 菜单栏数据
|
||||
scrollLeft, // 滚动到左边距离
|
||||
record, // 记录值
|
||||
clickTab, // tab 点击事件
|
||||
getOrderCount, // 获取数据
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default tabFn
|
||||
51
src/pages/order-manager/childPages/jx-tab/jx-tab.vue
Normal file
51
src/pages/order-manager/childPages/jx-tab/jx-tab.vue
Normal file
@@ -0,0 +1,51 @@
|
||||
<template>
|
||||
<view class="jx-tabs">
|
||||
<scroll-view
|
||||
class="tab-scroll"
|
||||
scroll-x="true"
|
||||
scroll-with-animation
|
||||
:scroll-left="scrollLeft"
|
||||
>
|
||||
<view
|
||||
v-for="item in orderStatus"
|
||||
:key="item.id"
|
||||
class="scroll-item"
|
||||
:class="{ jxTabsActive: currentStatus == item.id }"
|
||||
@tap="tabEmit(item.id, item, record, $event)"
|
||||
>{{ item.name }}
|
||||
<text class="badge" v-if="item.count != 0">{{ item.count }}</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import tabFn from './jx-tab'
|
||||
const {
|
||||
currentStatus, // 高亮初始值
|
||||
orderStatus, // tab 菜单栏数据
|
||||
scrollLeft, // 滚动到左边距离
|
||||
record, // 记录值
|
||||
clickTab, // tab 点击事件
|
||||
getOrderCount, // 获取数据
|
||||
} = tabFn()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'jxTab', target: AnyObject): void
|
||||
}>()
|
||||
let recordNum: number = 2
|
||||
function tabEmit(id: number, item: AnyObject, recordID: number, e: AnyObject) {
|
||||
if (recordNum == id) return false
|
||||
recordNum = id
|
||||
emit('jxTab', item)
|
||||
clickTab(id, recordID, e)
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
getOrderCount,
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './jx-tab.scss';
|
||||
</style>
|
||||
@@ -0,0 +1,56 @@
|
||||
.switch-filter {
|
||||
background-color: #fff;
|
||||
|
||||
.condition {
|
||||
text-align: center;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
box-sizing: border-box;
|
||||
border-radius: 10rpx;
|
||||
padding: 20rpx 40rpx 10rpx 40rpx;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
margin-top: 35rpx;
|
||||
|
||||
.root {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
text {
|
||||
padding: 0 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.value {
|
||||
padding: 5rpx 15rpx;
|
||||
border: 1rpx solid #bebebe;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.btnRoot {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 30rpx;
|
||||
border-top: 1rpx solid #999999;
|
||||
|
||||
.cancel,
|
||||
.confirm {
|
||||
color: #696969;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.confirm {
|
||||
color: #000;
|
||||
border-left: 1rpx solid #999999;
|
||||
}
|
||||
}
|
||||
}
|
||||
273
src/pages/order-manager/childPages/order-filter/order-filter.vue
Normal file
273
src/pages/order-manager/childPages/order-filter/order-filter.vue
Normal file
@@ -0,0 +1,273 @@
|
||||
<template>
|
||||
<uni-popup ref="popup" type="top">
|
||||
<view class="switch-filter">
|
||||
<view class="condition">查询条件</view>
|
||||
|
||||
<view class="item" v-if="orderState == 7">
|
||||
<text class="title">时间类型:</text>
|
||||
<picker
|
||||
class="value"
|
||||
mode="selector"
|
||||
:value="isDateFinishSearch"
|
||||
:range="dateFinish"
|
||||
range-key="name"
|
||||
@change="pickerChange1"
|
||||
>{{ dateFinish[isDateFinishSearch].name }}</picker
|
||||
>
|
||||
</view>
|
||||
<view class="item">
|
||||
<text class="title">查询时间:</text>
|
||||
<view class="root">
|
||||
<picker
|
||||
class="value"
|
||||
mode="date"
|
||||
:value="date1"
|
||||
start="2010-01-01"
|
||||
:end="endDate"
|
||||
@change="dateChange1"
|
||||
>{{ date1 }}</picker
|
||||
>
|
||||
<text>至</text>
|
||||
<picker
|
||||
class="value"
|
||||
mode="date"
|
||||
:value="date2"
|
||||
start="2010-01-01"
|
||||
:end="endDate"
|
||||
@change="dateChange2"
|
||||
>{{ date2 }}</picker
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<text class="title">外卖平台:</text>
|
||||
<picker
|
||||
class="value"
|
||||
mode="selector"
|
||||
:value="vendor"
|
||||
:range="vendorArr"
|
||||
range-key="name"
|
||||
@change="dateChange3"
|
||||
>{{ vendorArr[vendor].name }}</picker
|
||||
>
|
||||
</view>
|
||||
<view class="item" v-if="orderState == 7">
|
||||
<text class="title">配送方式:</text>
|
||||
<picker
|
||||
class="value"
|
||||
mode="selector"
|
||||
:value="waybillVendor"
|
||||
:range="waybillVendorArr"
|
||||
range-key="name"
|
||||
@change="dateChange4"
|
||||
>{{ waybillVendorArr[waybillVendor].name }}</picker
|
||||
>
|
||||
</view>
|
||||
<view class="item" v-if="orderState == 6">
|
||||
<text class="title">售后方式:</text>
|
||||
<picker
|
||||
class="value"
|
||||
mode="selector"
|
||||
:value="appealTypes1"
|
||||
:range="appealTypesArr"
|
||||
range-key="name"
|
||||
@change="dateChange5"
|
||||
>{{ appealTypesArr[appealTypes1].name }}</picker
|
||||
>
|
||||
</view>
|
||||
<view class="item" v-if="orderState == 6">
|
||||
<text class="title">售后状态:</text>
|
||||
<picker
|
||||
class="value"
|
||||
mode="selector"
|
||||
:value="afsStatus1"
|
||||
:range="afsStatusArr"
|
||||
range-key="name"
|
||||
@change="dateChange6"
|
||||
>{{ afsStatusArr[afsStatus1].name }}</picker
|
||||
>
|
||||
</view>
|
||||
<view class="btnRoot">
|
||||
<text class="cancel" @tap="popup.close()">取消</text>
|
||||
<text class="confirm" @tap="confirm">确定</text>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { timeFormatD } from '@/utils/tools'
|
||||
import { ref,watch } from 'vue'
|
||||
|
||||
/**
|
||||
* 筛选条件实例
|
||||
*/
|
||||
const popup = ref<any>(null)
|
||||
|
||||
interface propsType {
|
||||
orderState: number,
|
||||
orderStateInfo:AnyObject
|
||||
}
|
||||
const props = defineProps<propsType>()
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
const isDateFinishSearch = ref<number>(0)
|
||||
type dateFinishType = {
|
||||
key: number
|
||||
name: string
|
||||
}
|
||||
const dateFinish = ref<Array<dateFinishType>>([
|
||||
{ key: 0, name: '创建时间' },
|
||||
{ key: 1, name: '完成时间' },
|
||||
])
|
||||
function pickerChange1(e: AnyObject) {
|
||||
isDateFinishSearch.value = +e.detail.value
|
||||
}
|
||||
|
||||
/**
|
||||
* 起始时间,结束时间
|
||||
*/
|
||||
const date1 = ref<string>(
|
||||
timeFormatD(+new Date(new Date().getTime() - 1000 * 60 * 60 * 24 * 7))
|
||||
// timeFormatD(+new Date(new Date().getTime() - 1000 * 60 * 60 * 24 * 2))
|
||||
)
|
||||
watch(
|
||||
() => props.orderStateInfo,
|
||||
(val) => {
|
||||
if (val && val.id === 6 && val.count) {
|
||||
afsStatus1.value = 1
|
||||
date1.value = timeFormatD(+new Date(new Date().getTime() - 1000 * 60 * 60 * 24 * 2))
|
||||
}else {
|
||||
afsStatus1.value = 0
|
||||
date1.value = timeFormatD(+new Date(new Date().getTime() - 1000 * 60 * 60 * 24 * 7))
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const date2 = ref<string>(timeFormatD(+new Date()))
|
||||
const endDate = ref<string>('')
|
||||
function dateChange1(e: AnyObject) {
|
||||
date1.value = e.detail.value
|
||||
}
|
||||
function dateChange2(e: AnyObject) {
|
||||
date2.value = e.detail.value
|
||||
}
|
||||
|
||||
/**
|
||||
* 外卖平台
|
||||
*/
|
||||
const vendor = ref<number>(0)
|
||||
type vendorArrType = {
|
||||
id: number
|
||||
name: string
|
||||
}
|
||||
const vendorArr = ref<Array<vendorArrType>>([
|
||||
{ id: -1, name: '所有平台' },
|
||||
{ id: 0, name: '京东到家' },
|
||||
{ id: 1, name: '美团外卖' },
|
||||
{ id: 3, name: '饿百新零售' },
|
||||
{ id: 5, name: '京东商城' },
|
||||
{ id: 9, name: '京西商城' },
|
||||
])
|
||||
function dateChange3(e: AnyObject) {
|
||||
vendor.value = e.detail.value
|
||||
}
|
||||
|
||||
/**
|
||||
* 配送方式
|
||||
*/
|
||||
const waybillVendor = ref<number>(0)
|
||||
const waybillVendorArr = ref<Array<vendorArrType>>([
|
||||
{ id: -1, name: '所有配送' },
|
||||
{ id: 0, name: '京东到家专送' },
|
||||
{ id: 1, name: '美团专送' },
|
||||
{ id: 3, name: '饿百专送' },
|
||||
{ id: 101, name: '达达众包' },
|
||||
{ id: 102, name: '美团配送' },
|
||||
{ id: 103, name: '蜂鸟配送' },
|
||||
{ id: 105, name: 'UU跑腿' },
|
||||
{ id: 106, name: '顺丰同城' },
|
||||
])
|
||||
function dateChange4(e: AnyObject) {
|
||||
waybillVendor.value = e.detail.value
|
||||
}
|
||||
|
||||
/**
|
||||
* 售后方式
|
||||
*/
|
||||
const appealTypes1 = ref<number>(0)
|
||||
const appealTypesArr = ref<Array<vendorArrType>>([
|
||||
{ id: -1, name: '全部方式' },
|
||||
{ id: 1, name: '仅退款' },
|
||||
{ id: 2, name: '退货退款' },
|
||||
{ id: 3, name: '重发商品' },
|
||||
])
|
||||
function dateChange5(e: AnyObject) {
|
||||
appealTypes1.value = e.detail.value
|
||||
}
|
||||
|
||||
/**
|
||||
* 售后状态
|
||||
*/
|
||||
const afsStatus1 = ref<number>(0)
|
||||
const afsStatusArr = ref<Array<vendorArrType>>([
|
||||
{ id: -1, name: '全部状态' },
|
||||
{ id: 155, name: '待审核' },
|
||||
{ id: 160, name: '已审核' },
|
||||
{ id: 165, name: '退货待确认' },
|
||||
{ id: 167, name: '退货已收到' },
|
||||
{ id: 180, name: '售后成功' },
|
||||
{ id: 190, name: '售后失败' },
|
||||
])
|
||||
function dateChange6(e: AnyObject) {
|
||||
afsStatus1.value = e.detail.value
|
||||
}
|
||||
|
||||
/**
|
||||
* 确定筛选条件
|
||||
*/
|
||||
type emitType = {
|
||||
fromTime: string
|
||||
toTime: string
|
||||
vendorID: number | string
|
||||
waybillVendorID?: number | string
|
||||
isDateFinish?: boolean
|
||||
appealTypes?: number | string
|
||||
afsStatus?: number | string
|
||||
}
|
||||
const emit = defineEmits<{
|
||||
(e: 'filterData', data: emitType): void
|
||||
}>()
|
||||
function confirm() {
|
||||
let data = {
|
||||
fromTime: date1.value,
|
||||
toTime: date2.value,
|
||||
vendorID: vendorArr.value[vendor.value].id,
|
||||
waybillVendorID: waybillVendorArr.value[waybillVendor.value].id,
|
||||
isDateFinish: Boolean(isDateFinishSearch.value),
|
||||
appealTypes: appealTypesArr.value[appealTypes1.value].id,
|
||||
afsStatus: afsStatusArr.value[afsStatus1.value].id,
|
||||
}
|
||||
emit('filterData', data)
|
||||
popup.value.close()
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开弹窗
|
||||
*/
|
||||
function openRef() {
|
||||
popup.value.open()
|
||||
}
|
||||
/**
|
||||
* 导出外部访问函数
|
||||
*/
|
||||
defineExpose({
|
||||
openRef,
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './order-filter.scss';
|
||||
</style>
|
||||
@@ -0,0 +1,325 @@
|
||||
<template>
|
||||
<view
|
||||
class="distribution-root position-relative"
|
||||
@tap="orderDetail(item.vendorOrderID, item.vendorID)"
|
||||
>
|
||||
<order-list-top :item="item" />
|
||||
<order-money :item="item" />
|
||||
<view class="address">地址:{{ item.consigneeAddress }}</view>
|
||||
<view class="distribution-msg" v-if="item.courierName">
|
||||
<text class="vender-name">{{ wbVendor }}</text>
|
||||
<text class="distribution-name">{{ item.courierName }}</text>
|
||||
<text
|
||||
v-if="item.courierMobile.split(',')[1]"
|
||||
class="distribution-mobile"
|
||||
@tap.stop="phoneCall(item.courierMobile)"
|
||||
>{{
|
||||
item.courierMobile.split(',')[0] +
|
||||
'转' +
|
||||
item.courierMobile.split(',')[1]
|
||||
}}</text
|
||||
>
|
||||
<text
|
||||
v-else
|
||||
class="distribution-mobile"
|
||||
@tap.stop="phoneCall(item.courierMobile)"
|
||||
>{{ item.courierMobile }}</text
|
||||
>
|
||||
<jx-icon
|
||||
icon="24gf-telephone"
|
||||
color="#999999"
|
||||
@tap.stop="phoneCall(item.courierMobile)"
|
||||
:size="38"
|
||||
style="margin-left: 10rpx"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 自提订单 -->
|
||||
<view class="self-order self" v-if="item.deliveryType === 'self'"
|
||||
>[自提订单]</view
|
||||
>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<view class="operation">
|
||||
<view class="printerBtn" @tap.stop="deliverManager(item.vendorOrderID)"
|
||||
>配送管理</view
|
||||
>
|
||||
<view class="pickingBtn">查看详情</view>
|
||||
</view>
|
||||
|
||||
<!-- 确定自提 -->
|
||||
<template v-if="isSelfBtn">
|
||||
<view
|
||||
class="btn-picked"
|
||||
v-if="item.vendorID != 9"
|
||||
@tap.stop="inputTakeCode"
|
||||
>输入自提码</view
|
||||
>
|
||||
<view class="btn-picked" v-else @tap.stop="jxSelfTake('jx')"
|
||||
>完成自提</view
|
||||
>
|
||||
</template>
|
||||
|
||||
<!-- 商家自送送达按钮 status 20 -->
|
||||
<template v-if="isConfrim">
|
||||
<div class="btn-picked" @tap.stop="handleSelfDelivered">
|
||||
确认送达
|
||||
<text v-if="(item.flag & 128) === 128">[已操作]</text>
|
||||
</div>
|
||||
</template>
|
||||
</view>
|
||||
|
||||
<!-- 自提码弹窗 -->
|
||||
<uni-popup ref="popup" type="top">
|
||||
<view class="takeCode-root">
|
||||
<view class="title">自提订单</view>
|
||||
<input
|
||||
class="ipt"
|
||||
type="text"
|
||||
placeholder="请输入自提码"
|
||||
v-model="takeCode"
|
||||
/>
|
||||
<view class="btn-root">
|
||||
<view class="cancel" @tap.stop="popup.close()">取消</view>
|
||||
<view class="confirm" @tap.stop="jxSelfTake('noJx')">确定</view>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import useOrderInfo from '@/composables/useOrderInfo'
|
||||
import toast from '@/utils/toast'
|
||||
import { computed, ref } from 'vue'
|
||||
import orderListTop from '../component/orderListTop.vue'
|
||||
import orderMoney from '../component/orderMoney.vue'
|
||||
import { store } from '@/store'
|
||||
import order from '@/api/https/order'
|
||||
const {
|
||||
orderDetail, // 订单详情
|
||||
deliverManager, // 配送管理
|
||||
phoneCall, // 拨打电话
|
||||
waybillVendor, // 厂商转换
|
||||
} = useOrderInfo()
|
||||
|
||||
interface PropsType {
|
||||
item: any
|
||||
type: number
|
||||
}
|
||||
const props = defineProps<PropsType>()
|
||||
|
||||
/**
|
||||
* 转换快递厂商
|
||||
*/
|
||||
const wbVendor = computed(() => {
|
||||
return waybillVendor(
|
||||
props.item.waybillVendorID,
|
||||
props.item.status,
|
||||
props.item.waybillStatus
|
||||
)
|
||||
})
|
||||
|
||||
/**
|
||||
* 计算属性展示确认送达按钮
|
||||
*/
|
||||
const isConfrim = computed(() => {
|
||||
return (
|
||||
(props.item.deliveryFlag & 3) === 3 &&
|
||||
props.item.lockStatus === 0 &&
|
||||
props.item.deliveryType !== 'self' &&
|
||||
!props.item.vendorWaybillID
|
||||
)
|
||||
})
|
||||
|
||||
/**
|
||||
* 计算属性计算出是否显示自提订单按钮
|
||||
*/
|
||||
const isSelfBtn = computed(() => {
|
||||
return (
|
||||
props.item.status === 15 &&
|
||||
props.item.waybillVendorID === -1 &&
|
||||
props.item.lockStatus === 0 &&
|
||||
props.item.deliveryType === 'self'
|
||||
)
|
||||
})
|
||||
|
||||
/**
|
||||
* 除开京西自提订单
|
||||
*/
|
||||
const popup = ref<any>(null)
|
||||
function inputTakeCode() {
|
||||
takeCode.value = ''
|
||||
popup.value.open()
|
||||
}
|
||||
|
||||
/**
|
||||
* 自提订单 默认京西自提订单
|
||||
*/
|
||||
const takeCode = ref<any>() // 自提码
|
||||
function jxSelfTake(type: string) {
|
||||
if (type != 'jx' && takeCode.value == '') return toast('请输入自提码')
|
||||
uni.jxConfirm({
|
||||
title: '自提订单',
|
||||
content: '是否完成自提(请确保用户已出示正确订单,以免引起不必要的损失)',
|
||||
success: async () => {
|
||||
let data = {
|
||||
vendorOrderID: props.item.vendorOrderID,
|
||||
vendorID: props.item.vendorID,
|
||||
selfTakeCode: type === 'jx' ? '135246' : takeCode.value,
|
||||
}
|
||||
let res = await order.confirm_self_take(data)
|
||||
if (res.code == 0) {
|
||||
toast('自提成功', 1)
|
||||
popup.value.close()
|
||||
// 刷新订单
|
||||
store.commit('serveInfo/setUpdateOrder', Date.now())
|
||||
} else {
|
||||
toast('自提发生异常', 2)
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认送达
|
||||
*/
|
||||
function handleSelfDelivered() {
|
||||
// if ((props.item.flag & 128) === 128) return false
|
||||
uni.jxConfirm({
|
||||
title: '提示',
|
||||
content: '是否确认送达商品',
|
||||
success: async () => {
|
||||
let data = {
|
||||
vendorOrderID: props.item.vendorOrderID,
|
||||
vendorID: props.item.vendorID,
|
||||
}
|
||||
let res = await order.self_delivered(data)
|
||||
if (res.code == 0) {
|
||||
toast('送达成功', 1)
|
||||
// 刷新订单
|
||||
store.commit('serveInfo/setUpdateOrder', Date.now())
|
||||
} else {
|
||||
toast('送达异常'+ res.desc, 2)
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.order-totalCount) {
|
||||
border: none !important;
|
||||
}
|
||||
.position-relative {
|
||||
position: relative;
|
||||
}
|
||||
.distribution-root {
|
||||
position: relative;
|
||||
background-color: #fff;
|
||||
padding-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.self {
|
||||
padding: 15rpx;
|
||||
border-bottom: 2rpx dashed #e7e7e7;
|
||||
}
|
||||
|
||||
.address {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 15rpx;
|
||||
font-size: 32rpx;
|
||||
color: #000000;
|
||||
background-color: rgba($color: #908f96, $alpha: 0.15);
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
// 操作按钮
|
||||
.operation {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
padding: 15rpx 20rpx 0 20rpx;
|
||||
|
||||
.printerBtn,
|
||||
.pickingBtn {
|
||||
width: 100%;
|
||||
padding: 20rpx;
|
||||
text-align: center;
|
||||
border-radius: 10rpx;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.printerBtn {
|
||||
margin-right: 15rpx;
|
||||
background-image: linear-gradient(135deg, #ec903f, #ff6a20);
|
||||
}
|
||||
|
||||
.pickingBtn {
|
||||
margin-left: 15rpx;
|
||||
background-image: linear-gradient(135deg, $jx-primary, #85c972);
|
||||
}
|
||||
}
|
||||
|
||||
// 自提
|
||||
.takeCode-root {
|
||||
box-sizing: border-box;
|
||||
background-color: rgb(255, 255, 255);
|
||||
border-radius: 0 0 15rpx 15rpx;
|
||||
padding: 25rpx;
|
||||
|
||||
.title {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ipt {
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
border: 1rpx solid #cecece;
|
||||
border-radius: 10rpx;
|
||||
margin: 20rpx 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn-root {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.cancel,
|
||||
.confirm {
|
||||
width: 100%;
|
||||
padding: 15rpx 0;
|
||||
text-align: center;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
.cancel {
|
||||
color: $jx-primary;
|
||||
border: 1rpx solid $jx-primary;
|
||||
margin-right: 15rpx;
|
||||
}
|
||||
|
||||
.confirm {
|
||||
background-color: $jx-primary;
|
||||
margin-left: 15rpx;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.distribution-msg {
|
||||
padding: 15rpx;
|
||||
border-bottom: 2rpx dashed #e7e7e7;
|
||||
.distribution-name {
|
||||
margin-right: 25rpx;
|
||||
}
|
||||
.distribution-mobile {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.vender-name {
|
||||
color: #999999;
|
||||
margin-right: 25rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<view
|
||||
class="pending-order-root position-relative"
|
||||
@tap="orderDetail(item.vendorOrderID, item.vendorID)"
|
||||
>
|
||||
<order-list-top :item="item" />
|
||||
|
||||
<!-- 商品统计 -->
|
||||
<orderMoney :item="item" />
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<view class="operation-btn">
|
||||
<view
|
||||
class="refuse"
|
||||
@tap.stop="
|
||||
AcceptOrRefuseOrder(item.vendorOrderID, item.vendorID, false)
|
||||
"
|
||||
>拒绝接单</view
|
||||
>
|
||||
<view
|
||||
class="need"
|
||||
@tap.stop="AcceptOrRefuseOrder(item.vendorOrderID, item.vendorID, true)"
|
||||
>立即接单</view
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import useOrderInfo from '@/composables/useOrderInfo'
|
||||
import orderListTop from '../component/orderListTop.vue'
|
||||
import orderMoney from '../component/orderMoney.vue'
|
||||
import toast from '@/utils/toast'
|
||||
import { store } from '@/store'
|
||||
import order from '@/api/https/order'
|
||||
const {
|
||||
orderDetail, // 订单详情
|
||||
} = useOrderInfo()
|
||||
|
||||
interface PropsType {
|
||||
item: any
|
||||
}
|
||||
defineProps<PropsType>()
|
||||
|
||||
/**
|
||||
* 确定接单
|
||||
*/
|
||||
async function AcceptOrRefuseOrder(
|
||||
vendorOrderID: string,
|
||||
vendorID: string,
|
||||
isAccept: boolean
|
||||
) {
|
||||
let data = {
|
||||
vendorOrderID,
|
||||
vendorID,
|
||||
isAccept,
|
||||
}
|
||||
let res = await order.accept_or_refuse_order(data)
|
||||
if (res.code == 0) {
|
||||
if (isAccept) {
|
||||
toast('接单成功', 1)
|
||||
} else {
|
||||
toast('拒绝订单成功', 1)
|
||||
}
|
||||
// 刷新订单
|
||||
store.commit('serveInfo/setUpdateOrder', Date.now())
|
||||
} else {
|
||||
toast('订单数据异常')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.position-relative {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.pending-order-root {
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
|
||||
// 操作按钮
|
||||
.operation-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20rpx;
|
||||
justify-content: space-evenly;
|
||||
border-bottom: 2rpx dashed #e7e7e7;
|
||||
|
||||
.refuse,
|
||||
.need {
|
||||
padding: 8rpx 35rpx;
|
||||
border-radius: 7rpx;
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.refuse {
|
||||
background-color: #f60d58;
|
||||
}
|
||||
|
||||
.need {
|
||||
background-color: $jx-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,119 @@
|
||||
<template>
|
||||
<view
|
||||
class="pending-picking-root position-relative"
|
||||
@tap="orderDetail(item.vendorOrderID, item.vendorID)"
|
||||
>
|
||||
<order-list-top :item="item" />
|
||||
<view class="remarks"
|
||||
>备注:{{ item.buyerComment || '该订单用户未进行备注' }}</view
|
||||
>
|
||||
<order-money :item="item" />
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<view class="operation" v-if="item.status === 10 && item.lockStatus === 0">
|
||||
<view
|
||||
class="printerBtn"
|
||||
@tap.stop="printerOrder(item.vendorOrderID, item.vendorID)"
|
||||
>打印订单</view
|
||||
>
|
||||
<view
|
||||
class="pickingBtn"
|
||||
@tap.stop="pickingComplete(item.vendorOrderID, item.vendorID)"
|
||||
>拣货完成</view
|
||||
>
|
||||
</view>
|
||||
|
||||
<view class="self-order" v-if="item.deliveryType === 'self'"
|
||||
>[自提订单]</view
|
||||
>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import orderListTop from '../component/orderListTop.vue'
|
||||
import orderMoney from '../component/orderMoney.vue'
|
||||
import useOrderInfo from '@/composables/useOrderInfo'
|
||||
import toast from '@/utils/toast'
|
||||
import { store } from '@/store'
|
||||
import order from '@/api/https/order'
|
||||
const {
|
||||
orderDetail, // 订单详情
|
||||
printerOrder, // 打印订单
|
||||
} = useOrderInfo()
|
||||
interface PropsType {
|
||||
item: any
|
||||
}
|
||||
defineProps<PropsType>()
|
||||
|
||||
/**
|
||||
* 拣货完成
|
||||
*/
|
||||
async function pickingComplete(vendorOrderID: string, vendorID: string) {
|
||||
let data = {
|
||||
vendorOrderID,
|
||||
vendorID,
|
||||
}
|
||||
let res = await order.finished_pickup(data)
|
||||
if (res.code == 0) {
|
||||
toast('拣货成功', 1)
|
||||
// 刷新订单
|
||||
store.commit('serveInfo/setUpdateOrder', Date.now())
|
||||
} else {
|
||||
toast('拣货异常', 2)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.order-number) {
|
||||
border: none !important;
|
||||
}
|
||||
.position-relative {
|
||||
position: relative;
|
||||
}
|
||||
.pending-picking-root {
|
||||
background-color: #fff;
|
||||
|
||||
.remarks {
|
||||
padding: 15rpx;
|
||||
color: #999999;
|
||||
background-color: rgba($color: #908f96, $alpha: 0.15);
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.divider {
|
||||
width: 100%;
|
||||
height: 7rpx;
|
||||
background: white url('../../../../static/image/global/order-divider.png') 0
|
||||
0 no-repeat;
|
||||
background-size: 100%;
|
||||
}
|
||||
|
||||
// 操作按钮
|
||||
.operation {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
padding: 15rpx 20rpx;
|
||||
|
||||
.printerBtn,
|
||||
.pickingBtn {
|
||||
width: 100%;
|
||||
padding: 20rpx;
|
||||
text-align: center;
|
||||
border-radius: 10rpx;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.printerBtn {
|
||||
margin-right: 15rpx;
|
||||
background-image: linear-gradient(135deg, #85c972, $jx-primary);
|
||||
}
|
||||
|
||||
.pickingBtn {
|
||||
margin-left: 15rpx;
|
||||
background-image: linear-gradient(135deg, #ff6a20, #ec903f);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
407
src/pages/order-manager/main.ts
Normal file
407
src/pages/order-manager/main.ts
Normal file
@@ -0,0 +1,407 @@
|
||||
import useGlobalFunc from '@/composables/useGlobalFunc'
|
||||
import { store } from '@/store'
|
||||
import { getStorage } from '@/utils/storage'
|
||||
import toast from '@/utils/toast'
|
||||
import { timeFormatD, jx_trembling } from '@/utils/tools'
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app'
|
||||
import { watch, ref, onBeforeUnmount } from 'vue'
|
||||
import order from '@/api/https/order'
|
||||
// import merchant from '@/api/https/merchant'
|
||||
/**
|
||||
* 订单管理方法
|
||||
* @author zhangshuwie <2966211270@qq.com>
|
||||
* @param *
|
||||
* @return 模板使用数据与方法,详情内容请查看return
|
||||
*/
|
||||
function orderInfoFn() {
|
||||
const { isTrades } = useGlobalFunc()
|
||||
/**
|
||||
* 公共复位函数
|
||||
*/
|
||||
function reset() {
|
||||
orderDataList.value = []
|
||||
page.value = 1
|
||||
totalCount.value = 0
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* tab单击事件
|
||||
* @param target 点击对应tab获取到的信息
|
||||
*/
|
||||
const status = ref<Array<number>>([10]) // 默认显示待拣货
|
||||
const orderState = ref<number>(2) // 默认显示待拣货
|
||||
const orderStateInfo = ref()
|
||||
async function jxTabClick(target: AnyObject) {
|
||||
orderStateInfo.value = target
|
||||
reset()
|
||||
uni.removeTabBarBadge({ index: 0 })
|
||||
keyword.value = ''
|
||||
// 列表展示判断条件
|
||||
orderState.value = target.id
|
||||
// 请求数据订单状态
|
||||
status.value = target.status
|
||||
// 请求数据
|
||||
if (target.id == 6) {
|
||||
// 获取售后单
|
||||
if (orderStateInfo.value.count) {
|
||||
allData.value.fromTime = timeFormatD(+new Date(new Date().getTime() - 1000 * 60 * 60 * 24 * 2))
|
||||
allData.value.afsStatus = '155'
|
||||
}
|
||||
await getAfsOrders()
|
||||
} else {
|
||||
await getOrderAllInfo()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 下拉刷新
|
||||
*/
|
||||
let refresherrefreshTimer: any = null
|
||||
const triggered = ref<boolean>(false)
|
||||
function refresherrefresh() {
|
||||
uni.removeTabBarBadge({ index: 0 })
|
||||
triggered.value = true
|
||||
clearTimeout(refresherrefreshTimer)
|
||||
refresherrefreshTimer = setTimeout(async () => {
|
||||
store.commit('storeInfo/jxLoadingFn', true)
|
||||
reset()
|
||||
refreshTab()
|
||||
if (orderState.value == 5) {
|
||||
totalCount.value = 0
|
||||
}
|
||||
if (orderState.value == 6) {
|
||||
await getAfsOrders()
|
||||
} else {
|
||||
await getOrderAllInfo()
|
||||
}
|
||||
triggered.value = false
|
||||
store.commit('storeInfo/jxLoadingFn', false)
|
||||
}, 500)
|
||||
}
|
||||
|
||||
/**
|
||||
* 页面触底
|
||||
*/
|
||||
const isLoad = ref<boolean>(false)
|
||||
async function scrolltolower() {
|
||||
uni.removeTabBarBadge({ index: 0 })
|
||||
page.value++
|
||||
if (pageSize.value * (page.value - 1) > totalCount.value || totalCount.value < pageSize.value) {
|
||||
isLoad.value = false
|
||||
} else {
|
||||
if (isLoad.value) return
|
||||
if (orderState.value == 7) {
|
||||
await getOrderAllInfo()
|
||||
} else {
|
||||
await getAfsOrders()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取订单详情数据
|
||||
*/
|
||||
type emitType = {
|
||||
fromTime: string
|
||||
toTime: string
|
||||
vendorID: number | string
|
||||
waybillVendorID?: number | string
|
||||
isDateFinish?: boolean
|
||||
appealTypes?: number | string
|
||||
afsStatus?: number | string
|
||||
}
|
||||
let oldStoreID: any = 0
|
||||
|
||||
|
||||
/*************************************************
|
||||
* 门店休息情况
|
||||
*/
|
||||
const isRest = ref<boolean>(true)
|
||||
const isStatu = ref<boolean>(false)
|
||||
onShow(async () => {
|
||||
if (!store.state.storeInfo.allStoreInfo.id) {
|
||||
// console.log('ZSW-没有门店信息开始获取门店信息');
|
||||
await store.dispatch('storeInfo/getOneStore',getStorage("storeID"))
|
||||
}
|
||||
if (oldStoreID != getStorage('storeID') && oldStoreID != 0) {
|
||||
reset()
|
||||
triggered.value = true
|
||||
}
|
||||
oldStoreID = getStorage('storeID')
|
||||
isRest.value = isTrades(new Date()) // 门店是否接受预订单
|
||||
let storeInfo = store.state.storeInfo.allStoreInfo
|
||||
isStatu.value = storeInfo.status == 1 ? true : false
|
||||
uni.removeTabBarBadge({ index: 0 })
|
||||
})
|
||||
|
||||
onLoad(async (params) => {
|
||||
store.commit('storeInfo/jxLoadingFn', true)
|
||||
// 请求数据
|
||||
reset()
|
||||
await getOrderAllInfo()
|
||||
store.commit('storeInfo/jxLoadingFn', false)
|
||||
})
|
||||
const pageSize = ref<number>(33) // 每一页条数
|
||||
const page = ref<number>(1) // 第多少条
|
||||
const orderDataList = ref<any>([]) // 订单数据
|
||||
const totalCount = ref<number>(0) // 订单条数
|
||||
const allData = ref<emitType>({
|
||||
fromTime: timeFormatD(+new Date(new Date().getTime() - 1000 * 60 * 60 * 24 * 7)),
|
||||
toTime: timeFormatD(+new Date()),
|
||||
vendorID: '',
|
||||
waybillVendorID: '',
|
||||
isDateFinish: false,
|
||||
appealTypes: '',
|
||||
afsStatus: ''
|
||||
}) // 已完成数据筛选
|
||||
async function getOrderAllInfo() {
|
||||
isLoad.value = true
|
||||
let time1 = timeFormatD(+new Date(new Date().getTime() - 1000 * 60 * 60 * 24 * 7))
|
||||
let time2 = timeFormatD(+new Date())
|
||||
// 待接单、待检货、待配送、配送中、异常单、已完成
|
||||
let data: any = {
|
||||
fromDate: time1,
|
||||
toDate: time2,
|
||||
storeIDs: JSON.stringify([getStorage('storeID')]),
|
||||
statuss: JSON.stringify(status.value),
|
||||
offset: pageSize.value * (page.value - 1),
|
||||
pageSize: pageSize.value,
|
||||
isJxFirst: true
|
||||
}
|
||||
if (orderState.value == 7) {
|
||||
data = {
|
||||
fromDate: allData.value.fromTime ? allData.value.fromTime : time1,
|
||||
toDate: allData.value.toTime ? allData.value.toTime : time2,
|
||||
storeIDs: JSON.stringify([getStorage('storeID')]),
|
||||
statuss: JSON.stringify(status.value),
|
||||
offset: pageSize.value * (page.value - 1),
|
||||
pageSize: pageSize.value,
|
||||
isDateFinish: allData.value.isDateFinish,
|
||||
vendorIDs: `[${allData.value.vendorID}]`,
|
||||
waybillVendorIDs: `[${allData.value.waybillVendorID}]`,
|
||||
isJxFirst: true,
|
||||
keyword: keyword.value
|
||||
}
|
||||
}
|
||||
|
||||
let res = await order.get_orders(keyFilter(data))
|
||||
if (res.code == 0) {
|
||||
if (page.value <= 1) {
|
||||
reset()
|
||||
}
|
||||
let data: Array<any> = res.data.data || []
|
||||
if (data.length == 0) toast('暂无该类型订单')
|
||||
orderDataList.value = orderDataList.value.concat(data)
|
||||
totalCount.value = res.data.totalCount
|
||||
} else {
|
||||
reset()
|
||||
totalCount.value = 0
|
||||
|
||||
}
|
||||
isLoad.value = false
|
||||
}
|
||||
|
||||
|
||||
/*************************************************
|
||||
* 过滤对象空字段
|
||||
*/
|
||||
function keyFilter(obj: AnyObject) {
|
||||
for (let key in obj) {
|
||||
// if ((obj[key] == "" || obj[key] == [""] || obj[key] == '[-1]')) {
|
||||
if ((obj[key] == "" || obj[key] == '[-1]')) {
|
||||
delete obj[key]
|
||||
}
|
||||
}
|
||||
return obj
|
||||
}
|
||||
|
||||
|
||||
/*************************************************
|
||||
* 获取异常单
|
||||
*/
|
||||
async function getAfsOrders() {
|
||||
isLoad.value = true
|
||||
// 待接单、待捡货、待配送、配送中、异常单、已完成
|
||||
let data = {
|
||||
storeIDs: JSON.stringify([getStorage('storeID')]),
|
||||
fromTime: `${allData.value.fromTime} 00:00:00`,
|
||||
toTime: `${allData.value.toTime} 23:59:59`,
|
||||
pageSize: pageSize.value,
|
||||
offset: pageSize.value * (page.value - 1),
|
||||
vendorIDs: `[${allData.value.vendorID}]`,
|
||||
appealTypes: `[${allData.value.appealTypes}]`,
|
||||
statuss: `[${allData.value.afsStatus}]`,
|
||||
isDetail: true,
|
||||
keyword: keyword.value
|
||||
}
|
||||
let res = await order.get_afs_orders(keyFilter(data))
|
||||
if (res.code == 0) {
|
||||
if (page.value <= 1) {
|
||||
reset()
|
||||
}
|
||||
let data: Array<any> = res.data.data || []
|
||||
if (data.length == 0) toast("暂无售后订单")
|
||||
orderDataList.value = orderDataList.value.concat(res.data.data)
|
||||
totalCount.value = res.data.totalCount
|
||||
} else {
|
||||
reset()
|
||||
totalCount.value = 0
|
||||
}
|
||||
isLoad.value = false
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 刷新导航栏
|
||||
*/
|
||||
const tabInfo = ref<any>(null)
|
||||
function refreshTab() {
|
||||
tabInfo.value.getOrderCount()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 输入确认按钮
|
||||
*/
|
||||
const keyword = ref<string>('')
|
||||
async function searchStore(keywords: string) {
|
||||
keyword.value = keywords
|
||||
reset()
|
||||
if (orderState.value == 7) {
|
||||
await getOrderAllInfo()
|
||||
} else {
|
||||
await getAfsOrders()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 输入框输入值变化
|
||||
*/
|
||||
let trembling = jx_trembling(getOrderAllInfo, 800)
|
||||
let trembling2 = jx_trembling(getAfsOrders, 800)
|
||||
async function changeIpt(keywords: string) {
|
||||
keyword.value = keywords
|
||||
reset()
|
||||
if (orderState.value == 7) {
|
||||
trembling()
|
||||
} else {
|
||||
trembling2()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 清空输入框
|
||||
*/
|
||||
async function clearIpt() {
|
||||
keyword.value = ''
|
||||
reset()
|
||||
if (orderState.value == 7) {
|
||||
await getOrderAllInfo()
|
||||
} else {
|
||||
await getAfsOrders()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 已完成和售后单筛选
|
||||
*/
|
||||
const active = ref<number>(0)
|
||||
async function filterData(data: emitType) {
|
||||
let ruler = (+new Date() - +new Date(data.fromTime)) / 1000 / 60 / 60 / 24
|
||||
if (orderState.value != 7 && ruler > 59) {
|
||||
return toast('售后查询不能超过60天')
|
||||
}
|
||||
if (orderState.value == 7 && ruler > 180) {
|
||||
return toast('最大查询天数为180天')
|
||||
}
|
||||
allData.value = data
|
||||
reset()
|
||||
if (orderState.value == 7) {
|
||||
await getOrderAllInfo()
|
||||
} else {
|
||||
await getAfsOrders()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 筛选条件实例对象
|
||||
*/
|
||||
const orderFilterRef = ref<any>(null)
|
||||
|
||||
/**
|
||||
* 监听新订单刷新页面
|
||||
*/
|
||||
watch(() => store.state.serveInfo.updateOrder, async () => {
|
||||
reset()
|
||||
refreshTab()
|
||||
if (orderState.value == 6) {
|
||||
await getAfsOrders()
|
||||
} else {
|
||||
trembling()
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 动态计算scorll-view 高度
|
||||
*/
|
||||
const scorllHeight = ref<string>('94rpx')
|
||||
watch(() => orderState.value, (nweVal) => {
|
||||
let arr: Array<number> = [1, 2, 4, 5]
|
||||
if (arr.includes(nweVal)) {
|
||||
scorllHeight.value = '100rpx'
|
||||
} else {
|
||||
scorllHeight.value = '190rpx'
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
/*************************************************
|
||||
* 配送状态筛选
|
||||
*/
|
||||
function distributionStatu(type: number) {
|
||||
active.value = type
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 收尾工作
|
||||
*/
|
||||
onBeforeUnmount(() => {
|
||||
clearTimeout(refresherrefreshTimer)
|
||||
})
|
||||
|
||||
|
||||
return {
|
||||
jxTabClick, // 导航栏按钮
|
||||
orderDataList, // 订单数据
|
||||
totalCount, // 订单条数
|
||||
orderState, // 订单列表判断条件
|
||||
orderStateInfo, // 订单列表信息
|
||||
tabInfo, // 导航栏实例
|
||||
searchStore, // 输入库条件筛选
|
||||
keyword, // 输入库内容
|
||||
changeIpt, // 输入款输入变化
|
||||
clearIpt, // 清空输入框
|
||||
scorllHeight, // 动态计算scorll-view高度
|
||||
active, // 待配送筛选高亮
|
||||
orderFilterRef, // 筛选条件实例对象
|
||||
filterData, // 筛选条件数据
|
||||
refresherrefresh, // 下拉刷新
|
||||
triggered, // 下拉加载
|
||||
scrolltolower, // 页面触底
|
||||
isLoad, // 触底加载
|
||||
distributionStatu, // 配送筛选
|
||||
isRest, // 是否显示休息状态
|
||||
isStatu, // 门店是否在营业
|
||||
}
|
||||
}
|
||||
|
||||
export default orderInfoFn
|
||||
439
src/pages/order-manager/main.vue
Normal file
439
src/pages/order-manager/main.vue
Normal file
@@ -0,0 +1,439 @@
|
||||
<template>
|
||||
<!-- 联系运营 -->
|
||||
<image
|
||||
class="icon-phone"
|
||||
src="https://image.jxc4.com/image/dd78fd0b128be86e681f376e794f8309.png"
|
||||
mode="scaleToFill"
|
||||
@tap="getPhone"
|
||||
@touchmove.stop.prevent="touchM($event, 1)"
|
||||
@touchstart="touchS()"
|
||||
@touchend="touchE($event, 1)"
|
||||
/>
|
||||
|
||||
<!-- 当前门店是否休息 -->
|
||||
<view
|
||||
v-if="!isStatu"
|
||||
class="open-status-msg"
|
||||
@touchmove.prevent="touchM($event, 2)"
|
||||
@touchstart.prevent="touchS()"
|
||||
@touchend.prevent="touchE($event, 2)"
|
||||
><text>本店</text><text>已休息</text></view
|
||||
>
|
||||
<view
|
||||
v-else-if="!isRest"
|
||||
class="open-status-msg open-to-booking"
|
||||
@touchmove.prevent="touchM($event, 2)"
|
||||
@touchstart.prevent="touchS()"
|
||||
@touchend.prevent="touchE($event, 2)"
|
||||
><text>接受</text><text>预订单</text></view
|
||||
>
|
||||
|
||||
<!-- tab -->
|
||||
<view class="jx-tabs-root">
|
||||
<jx-tab ref="tabInfo" @jxTab="jxTabClick"></jx-tab>
|
||||
|
||||
<!-- 售后单,已完成 -->
|
||||
<template v-if="orderState == 6 || orderState == 7">
|
||||
<view class="filter-root">
|
||||
<text class="btn" @tap="orderFilterRef.openRef()">更多条件</text>
|
||||
<uni-search-bar
|
||||
v-model="keyword"
|
||||
@confirm="searchStore(keyword)"
|
||||
@clear="clearIpt"
|
||||
cancelButton="none"
|
||||
clearButton="auto"
|
||||
@input="changeIpt(keyword)"
|
||||
:placeholder="
|
||||
orderState == 6 ? '搜索售后单号、订单号、电话' : '搜索订单、电话等'
|
||||
"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<!-- 待配送筛选 -->
|
||||
<template v-if="orderState == 3">
|
||||
<view class="filter-order">
|
||||
<view :class="{ active: active == 0 }" @tap="distributionStatu(0)"
|
||||
>全 部</view
|
||||
>
|
||||
<view :class="{ active: active == 1 }" @tap="distributionStatu(1)"
|
||||
>未抢单</view
|
||||
>
|
||||
<view :class="{ active: active == 2 }" @tap="distributionStatu(2)"
|
||||
>已抢单</view
|
||||
>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
|
||||
<!-- 列表内容 -->
|
||||
<scroll-view
|
||||
class="order-item-main"
|
||||
scroll-y
|
||||
:style="{ height: `calc(100vh - ${scorllHeight})` }"
|
||||
refresher-enabled
|
||||
:refresher-triggered="triggered"
|
||||
@refresherrefresh="refresherrefresh"
|
||||
refresher-background="#efefef"
|
||||
@scrolltolower="scrolltolower"
|
||||
>
|
||||
<!-- 待接单 -->
|
||||
<template v-if="orderState == 1 && totalCount != 0">
|
||||
<pending-order
|
||||
v-for="item in orderDataList"
|
||||
:key="item.id"
|
||||
:item="item"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<!-- 待拣货 -->
|
||||
<template v-if="orderState == 2 && totalCount != 0">
|
||||
<pending-picking
|
||||
v-for="item in orderDataList"
|
||||
:key="item.id"
|
||||
:item="item"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<!-- 待配送 -->
|
||||
<template v-if="orderState == 3 && totalCount != 0">
|
||||
<view v-for="item in orderDataList" :key="item.id">
|
||||
<pending-distribution
|
||||
v-if="
|
||||
active === 0 ||
|
||||
(active === 1 && item.waybillStatus < 10) ||
|
||||
(active === 2 && item.waybillStatus >= 10 && item.lockStatus !== -5)
|
||||
"
|
||||
:item="item"
|
||||
:type="1"
|
||||
/>
|
||||
</view>
|
||||
<jx-load-more
|
||||
v-show="totalCount >= 2 && active === 0"
|
||||
:isLoad="isLoad"
|
||||
marginTop="25rpx"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<!-- 配送中 -->
|
||||
<template v-if="orderState == 4 && totalCount != 0">
|
||||
<pending-distribution
|
||||
v-for="item in orderDataList"
|
||||
:key="item.id"
|
||||
:item="item"
|
||||
:type="0"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<!-- 异常单 -->
|
||||
<template v-if="orderState == 5 && totalCount != 0">
|
||||
<view v-for="item in orderDataList" :key="item.id">
|
||||
<abnormal-order
|
||||
v-if="
|
||||
item.lockStatus === -5 ||
|
||||
((item.status === 17 || item.status === 18) &&
|
||||
item.lockStatus !== -5) ||
|
||||
(item.status === 22 && item.lockStatus !== -5)
|
||||
"
|
||||
:item="item"
|
||||
/>
|
||||
<jx-empty title="暂无异常订单" v-else />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<!-- 售后单 -->
|
||||
<template v-if="orderState == 6 && totalCount != 0">
|
||||
<after-sales-order
|
||||
v-for="item in orderDataList"
|
||||
:key="item.id"
|
||||
:item="item"
|
||||
></after-sales-order>
|
||||
</template>
|
||||
|
||||
<!-- 已完成 -->
|
||||
<template v-if="orderState == 7 && totalCount != 0">
|
||||
<completed
|
||||
v-for="item in orderDataList"
|
||||
:key="item.id"
|
||||
:item="item"
|
||||
></completed>
|
||||
</template>
|
||||
|
||||
<!-- 加载更多 -->
|
||||
<jx-load-more
|
||||
v-show="totalCount >= 2 && orderState != 3 && orderState != 5"
|
||||
:isLoad="isLoad"
|
||||
marginTop="25rpx"
|
||||
/>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<jx-empty title="暂无订单信息" v-show="totalCount == 0" />
|
||||
</scroll-view>
|
||||
|
||||
<!-- 切换筛选条件 -->
|
||||
<order-filter
|
||||
@filter-data="filterData"
|
||||
ref="orderFilterRef"
|
||||
:orderState="orderState"
|
||||
:orderStateInfo="orderStateInfo"
|
||||
/>
|
||||
|
||||
<!-- 公共组件 -->
|
||||
<jx-login-empty title="马上登录,查看订单" />
|
||||
<jx-loading />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import jxTab from './childPages/jx-tab/jx-tab.vue' // 待拣货
|
||||
import pendingOrder from './childPages/pending-order/pending-order.vue' // 待拣货
|
||||
import pendingPicking from './childPages/pending-picking/pending-picking.vue' // 待配送
|
||||
import pendingDistribution from './childPages/pending-distribution/pending-distribution.vue' // 配送中
|
||||
import afterSalesOrder from './childPages/after-sales-order/after-sales-order.vue' // 售后单
|
||||
import completed from './childPages/completed/completed.vue'
|
||||
import orderFilter from './childPages/order-filter/order-filter.vue'
|
||||
import abnormalOrder from './childPages/abnormal-order/abnormal-order.vue'
|
||||
import orderInfoFn from './main'
|
||||
import { ref } from 'vue'
|
||||
import { jx_throttles } from '@/utils/tools'
|
||||
const {
|
||||
jxTabClick, // 导航栏单击事件
|
||||
orderDataList, // 订单数据
|
||||
totalCount, // 订单条数
|
||||
orderState, // 订单列表判断条件
|
||||
orderStateInfo, // 订单列表信息
|
||||
tabInfo, // 导航栏实例
|
||||
searchStore, // 输入库条件筛选
|
||||
keyword, // 输入库内容
|
||||
changeIpt, // 输入款输入变化
|
||||
clearIpt, // 清空输入框
|
||||
scorllHeight, // 动态计算scorll-view高度
|
||||
active, // 待配送筛选高亮
|
||||
orderFilterRef, // 筛选条件实例对象
|
||||
filterData, // 筛选条件数据
|
||||
refresherrefresh, // 下拉刷新
|
||||
triggered, // 刷新状态
|
||||
scrolltolower, // 页面触底
|
||||
isLoad, // 触底加载
|
||||
distributionStatu, // 配送筛选
|
||||
isRest, // 是否显示休息状态
|
||||
isStatu, // 门店营业状态
|
||||
} = orderInfoFn()
|
||||
/**
|
||||
* 联系运营页面跳转
|
||||
*/
|
||||
function getPhone() {
|
||||
uni.navigateTo({ url: '/subPages/orderChild/getPhone/getPhone' })
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 开始触摸运营
|
||||
*/
|
||||
const isAnmarion = ref<string>('0s')
|
||||
let windowW = 0
|
||||
let windowH = 0
|
||||
function touchS() {
|
||||
isAnmarion.value = '0s'
|
||||
windowW = 0
|
||||
windowH = 0
|
||||
let sysTem = uni.getSystemInfoSync()
|
||||
windowW = sysTem.windowWidth
|
||||
windowH = sysTem.windowHeight
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* 移动联系运营
|
||||
*/
|
||||
const pageX1 = ref<string>('20rpx')
|
||||
const pageY1 = ref<string>('450rpx')
|
||||
const pageX2 = ref<string>('20rpx')
|
||||
const pageY2 = ref<string>('300rpx')
|
||||
function touchM(e: AnyObject, type: number) {
|
||||
touchMThrottles(e, type)
|
||||
}
|
||||
const touchMThrottles = jx_throttles({
|
||||
time: 5,
|
||||
success(e: AnyObject, type: number) {
|
||||
let sysTem = e.changedTouches[0]
|
||||
if (type == 1) {
|
||||
pageX1.value = sysTem.clientX - 25 + 'px'
|
||||
pageY1.value = sysTem.clientY - 25 + 'px'
|
||||
}
|
||||
|
||||
if (type == 2) {
|
||||
pageX2.value = sysTem.clientX - 25 + 'px'
|
||||
pageY2.value = sysTem.clientY - 25 + 'px'
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
/*************************************************
|
||||
* 触摸运营结束
|
||||
*/
|
||||
function touchE(e: AnyObject, type: number) {
|
||||
isAnmarion.value = '0.5s'
|
||||
let sysTem = e.target
|
||||
if (type == 1) {
|
||||
if (sysTem.offsetLeft <= 0 || sysTem.offsetLeft <= windowW / 2 - 25) {
|
||||
pageX1.value = '10px'
|
||||
}
|
||||
if (sysTem.offsetLeft >= windowW || sysTem.offsetLeft >= windowW / 2 - 25) {
|
||||
pageX1.value = windowW - 60 + 'px'
|
||||
}
|
||||
if (sysTem.offsetTop <= 50) {
|
||||
pageY1.value = '50px'
|
||||
}
|
||||
if (sysTem.offsetTop >= windowH - 100) {
|
||||
pageY1.value = windowH - 60 + 'px'
|
||||
}
|
||||
}
|
||||
|
||||
if (type == 2) {
|
||||
let pageX = parseInt(pageX2.value)
|
||||
let pageY = parseInt(pageY2.value)
|
||||
if (pageX <= 0 || pageX <= windowW / 2 - 25) {
|
||||
pageX2.value = '10px'
|
||||
}
|
||||
if (pageX >= windowW || pageX >= windowW / 2 - 25) {
|
||||
pageX2.value = windowW - 60 + 'px'
|
||||
}
|
||||
if (pageY <= 50) {
|
||||
pageY2.value = '50px'
|
||||
}
|
||||
if (pageY >= windowH - 100) {
|
||||
pageY2.value = windowH - 60 + 'px'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.open-status-msg {
|
||||
position: absolute;
|
||||
z-index: 99999999999;
|
||||
left: v-bind(pageX2);
|
||||
top: v-bind(pageY2);
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
font-size: 10px;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
border-radius: 50%;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
background: rgba(116, 116, 116, 0.75);
|
||||
text-shadow: 1rpx 1rpx 2rpx #eb6100;
|
||||
transition: all v-bind(isAnmarion);
|
||||
|
||||
text {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.open-to-booking {
|
||||
text-shadow: 2rpx 2rpx 2rpx $jx-warring;
|
||||
}
|
||||
|
||||
.icon-phone {
|
||||
position: absolute;
|
||||
z-index: 99999999999;
|
||||
left: v-bind(pageX1);
|
||||
top: v-bind(pageY1);
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
transition: all v-bind(isAnmarion);
|
||||
}
|
||||
.filter-root {
|
||||
box-sizing: border-box;
|
||||
height: 90rpx;
|
||||
padding: 15rpx;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.btn {
|
||||
padding: 8rpx 0;
|
||||
width: 160rpx;
|
||||
text-align: center;
|
||||
background-color: $jx-primary;
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
border-radius: 100rpx;
|
||||
margin-right: 15rpx;
|
||||
}
|
||||
|
||||
:deep(.uni-searchbar) {
|
||||
padding: 0 !important;
|
||||
width: 545rpx !important;
|
||||
|
||||
.uni-searchbar__box {
|
||||
border-radius: 100rpx !important;
|
||||
height: auto !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="scss">
|
||||
page {
|
||||
position: relative;
|
||||
background-color: #efefef;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.self-order {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
color: #ff0000;
|
||||
font-weight: bold;
|
||||
padding-bottom: 20rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.btn-picked {
|
||||
background: $jx-primary;
|
||||
color: white;
|
||||
border-radius: 10rpx;
|
||||
font-size: 36rpx;
|
||||
font-weight: 400;
|
||||
height: 94rpx;
|
||||
line-height: 94rpx;
|
||||
text-align: center;
|
||||
margin: 0rpx 20rpx;
|
||||
margin-top: 15rpx;
|
||||
}
|
||||
|
||||
.jx-tabs-root {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
box-shadow: 0 5rpx 7rpx #ececec;
|
||||
}
|
||||
|
||||
.filter-order {
|
||||
height: 90rpx;
|
||||
box-sizing: border-box;
|
||||
padding: 15rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
background-color: #fff;
|
||||
|
||||
view {
|
||||
box-sizing: border-box;
|
||||
width: 230rpx;
|
||||
padding: 10rpx 20rpx;
|
||||
border: 1rpx solid #999999;
|
||||
color: #999999;
|
||||
border-radius: 10rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.active {
|
||||
background-color: #82c86f;
|
||||
border: 1rpx solid #82c86f;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
.order-item-main {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user