优化
This commit is contained in:
@@ -8,18 +8,18 @@ VITE_APP_BASE_API=/dev-api
|
|||||||
|
|
||||||
# VITE_APP_API_URL=https://tapi.cashier.sxczgkj.cn/ # 测试
|
# VITE_APP_API_URL=https://tapi.cashier.sxczgkj.cn/ # 测试
|
||||||
# VITE_APP_API_URL=https://cashier.sxczgkj.com/ # 正式
|
# VITE_APP_API_URL=https://cashier.sxczgkj.com/ # 正式
|
||||||
# VITE_APP_API_URL=http://192.168.1.42/ # 本地
|
VITE_APP_API_URL=http://192.168.1.43/ # 本地
|
||||||
VITE_APP_API_URL=https://frp.sxczgkj.com # 本地映射地址
|
# VITE_APP_API_URL=https://frp.sxczgkj.com # 本地映射地址
|
||||||
VITE_APP_API_PHP_URL=http://192.168.1.42:8000 #php抖音美团测试环境
|
VITE_APP_API_PHP_URL=http://192.168.1.43:8000 #php抖音美团测试环境
|
||||||
VITE_APP_API_PHP_IMPORT_URL=http://192.168.1.42:8789 #本地php批量导入
|
VITE_APP_API_PHP_IMPORT_URL=http://192.168.1.43:8789 #本地php批量导入
|
||||||
# VITE_APP_API_PHP_IMPORT_URL=https://diftcs.sxczgkj.com #本地线上php批量导入
|
# VITE_APP_API_PHP_IMPORT_URL=https://diftcs.sxczgkj.com #本地线上php批量导入
|
||||||
|
|
||||||
|
|
||||||
# WebSocket 端点(不配置则关闭),线上 ws://api.youlai.tech/ws ,本地 ws://localhost:8989/ws
|
# WebSocket 端点(不配置则关闭),线上 ws://api.youlai.tech/ws ,本地 ws://localhost:8989/ws
|
||||||
# VITE_APP_WS_ENDPOINT=wss://sockets.sxczgkj.com/wss
|
# VITE_APP_WS_ENDPOINT=wss://sockets.sxczgkj.com/wss
|
||||||
# VITE_APP_WS_ENDPOINT=wss://czgeatws.sxczgkj.com/wss # 正式
|
# VITE_APP_WS_ENDPOINT=wss://czgeatws.sxczgkj.com/wss # 正式
|
||||||
# VITE_APP_WS_ENDPOINT=ws://192.168.1.42:2348 # 本地
|
VITE_APP_WS_ENDPOINT=ws://192.168.1.43:2348 # 本地
|
||||||
VITE_APP_WS_ENDPOINT=ws://frp.sxczgkj.com/wss # 本地
|
# VITE_APP_WS_ENDPOINT=ws://frp.sxczgkj.com/wss # 本地
|
||||||
# VITE_APP_API_PHP_URL=https://newblockwlx.sxczgkj.cn #php抖音美团正式环境
|
# VITE_APP_API_PHP_URL=https://newblockwlx.sxczgkj.cn #php抖音美团正式环境
|
||||||
|
|
||||||
# 启用 Mock 服务
|
# 启用 Mock 服务
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ VITE_APP_PORT=3000
|
|||||||
|
|
||||||
# VITE_APP_API_URL=https://tapi.cashier.sxczgkj.cn/ # 测试
|
# VITE_APP_API_URL=https://tapi.cashier.sxczgkj.cn/ # 测试
|
||||||
# VITE_APP_API_URL=https://cashier.sxczgkj.com/ # 正式
|
# VITE_APP_API_URL=https://cashier.sxczgkj.com/ # 正式
|
||||||
VITE_APP_API_URL=http://192.168.1.42/ # 本地
|
VITE_APP_API_URL=http://192.168.1.43/ # 本地
|
||||||
|
|
||||||
|
|
||||||
# WebSocket 端点(不配置则关闭),线上 ws://api.youlai.tech/ws ,本地 ws://localhost:8989/ws
|
# WebSocket 端点(不配置则关闭),线上 ws://api.youlai.tech/ws ,本地 ws://localhost:8989/ws
|
||||||
# VITE_APP_WS_ENDPOINT=wss://sockets.sxczgkj.com/wss
|
# VITE_APP_WS_ENDPOINT=wss://sockets.sxczgkj.com/wss
|
||||||
# VITE_APP_WS_ENDPOINT=wss://czgeatws.sxczgkj.com/wss # 正式
|
# VITE_APP_WS_ENDPOINT=wss://czgeatws.sxczgkj.com/wss # 正式
|
||||||
VITE_APP_WS_ENDPOINT=ws://192.168.1.42:2348 # 本地
|
VITE_APP_WS_ENDPOINT=ws://192.168.1.43:2348 # 本地
|
||||||
VITE_APP_API_PHP_URL=http://192.168.1.42:8000 #php抖音美团测试环境
|
VITE_APP_API_PHP_URL=http://192.168.1.43:8000 #php抖音美团测试环境
|
||||||
|
|
||||||
|
|
||||||
# 启用 Mock 服务
|
# 启用 Mock 服务
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ VITE_APP_NAME=production
|
|||||||
#VITE_APP_WS_ENDPOINT=wss://api.youlai.tech/ws
|
#VITE_APP_WS_ENDPOINT=wss://api.youlai.tech/ws
|
||||||
|
|
||||||
# 接口地址
|
# 接口地址
|
||||||
VITE_APP_BASE_API = https://cashier.sxczgkj.com/
|
# VITE_APP_BASE_API = https://cashier.sxczgkj.com/
|
||||||
# VITE_APP_BASE_API = https://frp.sxczgkj.com/
|
VITE_APP_BASE_API = https://frp.sxczgkj.com/
|
||||||
|
|
||||||
VITE_APP_API_PHP_URL=https://newblockwlx.sxczgkj.cn #php抖音美团正式环境
|
VITE_APP_API_PHP_URL=https://newblockwlx.sxczgkj.cn #php抖音美团正式环境
|
||||||
|
|
||||||
@@ -19,9 +19,9 @@ VITE_APP_API_PHP_URL=https://newblockwlx.sxczgkj.cn #php抖音美团正式环
|
|||||||
|
|
||||||
|
|
||||||
# WebSocket 端点(不配置则关闭),线上 ws://api.youlai.tech/ws ,本地 ws://localhost:8989/ws
|
# WebSocket 端点(不配置则关闭),线上 ws://api.youlai.tech/ws ,本地 ws://localhost:8989/ws
|
||||||
VITE_APP_WS_ENDPOINT=wss://czgeatws.sxczgkj.com/wss
|
# VITE_APP_WS_ENDPOINT=wss://czgeatws.sxczgkj.com/wss
|
||||||
|
|
||||||
# VITE_APP_WS_ENDPOINT=wss://frp.sxczgkj.com/wss
|
VITE_APP_WS_ENDPOINT=wss://frp.sxczgkj.com/wss
|
||||||
|
|
||||||
# 启用 Mock 服务
|
# 启用 Mock 服务
|
||||||
VITE_MOCK_DEV_SERVER=false
|
VITE_MOCK_DEV_SERVER=false
|
||||||
|
|||||||
@@ -44,6 +44,14 @@ const API = {
|
|||||||
params
|
params
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
// 修改会员信息
|
||||||
|
editMemberInfo(data: any) {
|
||||||
|
return request({
|
||||||
|
url: `/account/admin/shopUser/editVip`,
|
||||||
|
method: "put",
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
},
|
||||||
}
|
}
|
||||||
export default API;
|
export default API;
|
||||||
|
|
||||||
|
|||||||
@@ -81,4 +81,26 @@ export default {
|
|||||||
label: "退单",
|
label: "退单",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
platformType: [
|
||||||
|
{
|
||||||
|
key: "PC",
|
||||||
|
label: "收银机客户端",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "wechat",
|
||||||
|
label: "微信小程序",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "alipay",
|
||||||
|
label: "支付宝小程序",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "admin-pc",
|
||||||
|
label: "PC管理端",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "admin-app",
|
||||||
|
label: "APP管理端",
|
||||||
|
},
|
||||||
|
]
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import OrderApi from "@/api/order/order";
|
|||||||
import type { editRequest } from "@/api/system/version";
|
import type { editRequest } from "@/api/system/version";
|
||||||
import type { IContentConfig } from "@/components/CURD/types";
|
import type { IContentConfig } from "@/components/CURD/types";
|
||||||
import { returnOptionsLabel } from "./config";
|
import { returnOptionsLabel } from "./config";
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
const contentConfig: IContentConfig = {
|
const contentConfig: IContentConfig = {
|
||||||
pageName: "sys:user",
|
pageName: "sys:user",
|
||||||
table: {
|
table: {
|
||||||
@@ -22,7 +23,9 @@ const contentConfig: IContentConfig = {
|
|||||||
delete params.createAt;
|
delete params.createAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await OrderApi.getList(params)
|
const route = useRoute()
|
||||||
|
|
||||||
|
const res = await OrderApi.getList({ ...params, userId: route.query.userId })
|
||||||
console.log('OrderApi.getList', res);
|
console.log('OrderApi.getList', res);
|
||||||
|
|
||||||
res.records.map(item => {
|
res.records.map(item => {
|
||||||
|
|||||||
744
src/views/order/index/detail.vue
Normal file
744
src/views/order/index/detail.vue
Normal file
@@ -0,0 +1,744 @@
|
|||||||
|
<template>
|
||||||
|
<div style="padding: 20px 0;width: 100%;flex: 1;">
|
||||||
|
<div class="header">
|
||||||
|
<div class="title">
|
||||||
|
<div class="back">
|
||||||
|
<el-icon :size="20" @click="router.back()">
|
||||||
|
<Back />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
订单详情
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="order_detail_container">
|
||||||
|
<div class="order_top">
|
||||||
|
<!-- <div class="info_content">
|
||||||
|
<div class="item">
|
||||||
|
<div class="label">会员信息</div>
|
||||||
|
<div class="row">
|
||||||
|
<div>会员昵称:-{{ user.nickName || "" }}</div>
|
||||||
|
<div>联系电话:-{{ user.phone || "" }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
<div class="table">
|
||||||
|
<div class="item div1">
|
||||||
|
<el-text type="info">台桌信息:</el-text>
|
||||||
|
<el-text size="large">{{ detail.tableName || '无台桌' }}</el-text>
|
||||||
|
<el-tag :type="detail.status == 'closed' ? 'success' : 'primary'" disable-transitions size="large"
|
||||||
|
style="margin-left: 14px;">
|
||||||
|
{{ statusFilter(detail.status) }}
|
||||||
|
</el-tag>
|
||||||
|
</div>
|
||||||
|
<div class="item div2">
|
||||||
|
<el-text type="info">订单类型:</el-text>
|
||||||
|
<el-text>{{ sendTypeFilter(detail.dineMode) }}</el-text>
|
||||||
|
</div>
|
||||||
|
<div class="item div3">
|
||||||
|
<el-text type="info">下单方式:</el-text>
|
||||||
|
<el-text>{{ platformTypeFilter(detail.platformType) }}</el-text>
|
||||||
|
</div>
|
||||||
|
<div class="item div4">
|
||||||
|
<el-text type="info">订单编号:</el-text>
|
||||||
|
<el-text>{{ detail.orderNo }}</el-text>
|
||||||
|
</div>
|
||||||
|
<div class="item div5">
|
||||||
|
<el-text type="info">支付时间:</el-text>
|
||||||
|
<el-text>{{ timeFilter(detail.paidTime) }}</el-text>
|
||||||
|
</div>
|
||||||
|
<div class="item div6">
|
||||||
|
<el-text type="info">下单时间:</el-text>
|
||||||
|
<el-text>{{ timeFilter(detail.createTime) }}</el-text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="table">
|
||||||
|
<div class="item">
|
||||||
|
<div class="t">订单编号</div>
|
||||||
|
<div class="b">
|
||||||
|
{{ detail.orderNo }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="t">下单时间</div>
|
||||||
|
<div class="b">{{ timeFilter(detail.createTime) }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="t">支付时间</div>
|
||||||
|
<div class="b">
|
||||||
|
{{ timeFilter(detail.paidTime) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
<div class="info_content">
|
||||||
|
<div class="item">
|
||||||
|
<div class="title">订单金额</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="row_col">
|
||||||
|
<el-text type="info">实收金额:</el-text>
|
||||||
|
<el-text size="large">¥{{ detail.payAmount }}</el-text>
|
||||||
|
<el-button v-if="detail.status != 'unpaid' && detail.refundAmount < detail.payAmount" size="small"
|
||||||
|
type="danger" class="u-m-l-10" @click="tuikuan()">
|
||||||
|
<span>退款</span>
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="row_col">
|
||||||
|
<el-text type="info">支付方式:</el-text>
|
||||||
|
<el-text>{{ returnPayType(detail.payType) || '-' }}</el-text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="row_col">
|
||||||
|
<el-text type="info">订单原价:</el-text>
|
||||||
|
<el-text>¥{{ detail.originAmount }}</el-text>
|
||||||
|
</div>
|
||||||
|
<div class="row_col">
|
||||||
|
<el-text type="info">打包费:</el-text>
|
||||||
|
<el-text>¥{{ detail.packFee || "-" }}</el-text>
|
||||||
|
</div>
|
||||||
|
<div class="row_col">
|
||||||
|
<el-text type="info">餐位费:</el-text>
|
||||||
|
<el-text>¥{{ detail.seatAmount || "-" }}</el-text>
|
||||||
|
</div>
|
||||||
|
<div class="row_col">
|
||||||
|
<el-text type="info">商品券抵扣:</el-text>
|
||||||
|
<el-text>¥{{ detail.productCouponDiscountAmount || '-' }}</el-text>
|
||||||
|
</div>
|
||||||
|
<div class="row_col">
|
||||||
|
<el-text type="info">优惠券抵扣:</el-text>
|
||||||
|
<el-text>¥{{ detail.otherCouponDiscountAmount || '-' }}</el-text>
|
||||||
|
</div>
|
||||||
|
<div class="row_col"></div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="row_col">
|
||||||
|
<el-text type="info">满减活动:</el-text>
|
||||||
|
<el-text>¥{{ detail.discountActAmount || "-" }}</el-text>
|
||||||
|
</div>
|
||||||
|
<div class="row_col">
|
||||||
|
<el-text type="info">新客立减:</el-text>
|
||||||
|
<el-text>¥{{ detail.newCustomerDiscountAmount || "-" }}</el-text>
|
||||||
|
</div>
|
||||||
|
<div class="row_col">
|
||||||
|
<el-text type="info">退单金额:</el-text>
|
||||||
|
<el-text>¥{{ detail.refundAmount || "-" }}</el-text>
|
||||||
|
</div>
|
||||||
|
<div class="row_col">
|
||||||
|
<el-text type="info">整单改价:</el-text>
|
||||||
|
<el-text>¥{{ detail.discountAmount || '-' }}</el-text>
|
||||||
|
</div>
|
||||||
|
<div class="row_col">
|
||||||
|
<el-text type="info">积分抵扣:</el-text>
|
||||||
|
<el-text>¥{{ detail.pointsDiscountAmount || '-' }}</el-text>
|
||||||
|
</div>
|
||||||
|
<div class="row_col">
|
||||||
|
<el-text type="info">抹零:</el-text>
|
||||||
|
<el-text>¥{{ detail.roundAmount || '-' }}</el-text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="row">
|
||||||
|
<div>满减活动:¥{{ detail.discountActAmount || "-" }}</div>
|
||||||
|
<div>新客立减:¥{{ detail.newCustomerDiscountAmount || "-" }}</div>
|
||||||
|
<div>会员折扣:¥{{ detail.vipDiscountAmount || "-" }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div>退单金额:¥{{ detail.refundAmount }}</div>
|
||||||
|
<div>整单改价:¥{{ detail.discountAmount }}</div>
|
||||||
|
<div>积分抵扣:¥{{ detail.pointsDiscountAmount }}</div>
|
||||||
|
<div>抹零:¥{{ detail.roundAmount }}</div>
|
||||||
|
<div>
|
||||||
|
实收金额:
|
||||||
|
<span style="color: red">¥{{ detail.payAmount }}</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
<!-- <div class="row">
|
||||||
|
<div>支付方式:{{ returnPayType(detail.payType) }}</div>
|
||||||
|
<div>
|
||||||
|
退款金额:¥{{ detail.refundAmount }}
|
||||||
|
</div>
|
||||||
|
<div class="color-red">
|
||||||
|
<span v-if="detail.refundType">
|
||||||
|
退款方式:{{ detail.refundType === "cash" ? "现金退款" : "原路退回" }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
<div class="item" v-if="detail.refundType">
|
||||||
|
<div class="title">退款详情</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="row_col">
|
||||||
|
<el-text type="info">退款金额:</el-text>
|
||||||
|
<el-text type="danger">¥{{ detail.refundAmount }}</el-text>
|
||||||
|
</div>
|
||||||
|
<div class="row_col">
|
||||||
|
<el-text type="info">退款方式:</el-text>
|
||||||
|
<el-text type="danger">{{ detail.refundType === "cash" ? "现金退款" : "原路退回" }}</el-text>
|
||||||
|
</div>
|
||||||
|
<div class="row_col">
|
||||||
|
<el-text type="info">退款原因:</el-text>
|
||||||
|
<el-text type="danger">{{ detail.refundRemark }}</el-text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="info_content" v-if="user.id">
|
||||||
|
<div class="title">用户信息</div>
|
||||||
|
<div class="user_info_wrap">
|
||||||
|
<div class="user_info_wrap_item" style="width: 60px;flex: none;">
|
||||||
|
<el-avatar :size="40" :src="user.headImg">{{ user.nickName || '-' }}</el-avatar>
|
||||||
|
</div>
|
||||||
|
<div class="user_info_wrap_item">
|
||||||
|
<el-text type="info">用户名称</el-text>
|
||||||
|
<el-text>{{ user.nickName || '-' }}</el-text>
|
||||||
|
</div>
|
||||||
|
<div class="user_info_wrap_item">
|
||||||
|
<el-text type="info">ID</el-text>
|
||||||
|
<el-text>{{ user.id || '-' }}</el-text>
|
||||||
|
</div>
|
||||||
|
<div class="user_info_wrap_item">
|
||||||
|
<el-text type="info">当前余额</el-text>
|
||||||
|
<el-text>{{ user.amount || '-' }}</el-text>
|
||||||
|
</div>
|
||||||
|
<div class="user_info_wrap_item">
|
||||||
|
<el-text type="info">会员</el-text>
|
||||||
|
<el-text>{{ user.isVip ? user.memberLevelName : '暂未成为会员' }}</el-text>
|
||||||
|
</div>
|
||||||
|
<div class="user_info_wrap_item">
|
||||||
|
<el-text type="info">消费累计</el-text>
|
||||||
|
<el-text>{{ user.consumeAmount || '-' }}</el-text>
|
||||||
|
</div>
|
||||||
|
<div class="user_info_wrap_item">
|
||||||
|
<el-text type="info">注册时间</el-text>
|
||||||
|
<el-text>{{ user.createTime || '-' }}</el-text>
|
||||||
|
</div>
|
||||||
|
<div class="user_info_wrap_item" style="padding-left: 24px;">
|
||||||
|
<el-button type="primary"
|
||||||
|
@click="router.push({ path: '/order/index', query: { userId: user.userId } })">查看所有订单</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="shop_info_wrap">
|
||||||
|
<div style="margin-bottom: 16px; font-size: 16px">商品详情</div>
|
||||||
|
<template v-for="(item, index) in detail.detailMap" :key="index">
|
||||||
|
<h4>第{{ index }}次下单</h4>
|
||||||
|
<el-table :data="item" :ref="el => { if (el) tableRefs[`refTable${index}`] = el }"
|
||||||
|
@select-all="tableSelectAll($event, index)">
|
||||||
|
<el-table-column label="数量" type="selection">
|
||||||
|
<template #default="scope">
|
||||||
|
<div v-if="detail.status == 'unpaid'">
|
||||||
|
<el-checkbox v-if="scope.row.num - scope.row.returnNum > 0" v-model="scope.row.checked" />
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<el-checkbox v-if="scope.row.num - scope.row.refundNum > 0" v-model="scope.row.checked" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="商品" width="150">
|
||||||
|
<template #default="scope">
|
||||||
|
<div class="shop_info">
|
||||||
|
<el-image :src="scope.row.productImg" style="width: 40px; height: 40px"></el-image>
|
||||||
|
<div class="info">
|
||||||
|
<span :class="[scope.row.isVip == 1 ? 'colorStyle' : '']">
|
||||||
|
{{ scope.row.productName }}
|
||||||
|
</span>
|
||||||
|
<span style="color: #999">{{ scope.row.productSkuName }}</span>
|
||||||
|
<div>
|
||||||
|
<el-tag v-if="scope.row.isTimeDiscount" type="danger" disable-transitions>
|
||||||
|
限时折扣
|
||||||
|
</el-tag>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="下单数量">
|
||||||
|
<template #default="scope">x{{ scope.row.num }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="退菜数量">
|
||||||
|
<template #default="scope">x{{ scope.row.returnNum }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="单价">
|
||||||
|
<template #default="scope">¥{{ scope.row.unitPrice }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="备注" prop="remark"></el-table-column>
|
||||||
|
<el-table-column label="出菜时间" prop="dishOutTime" width="180"></el-table-column>
|
||||||
|
<el-table-column label="上菜时间" prop="foodServeTime" width="180"></el-table-column>
|
||||||
|
<el-table-column label="小计">
|
||||||
|
<template #default="scope">¥{{ scope.row.payAmount }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="实付">
|
||||||
|
<template #default="scope">¥{{ scope.row.payAmount }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column v-if="detail.status == 'unpaid'" label="可退菜数量" align="center" width="130px">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-input-number v-if="scope.row.checked" :min="0" style="width: 100px" v-model="scope.row.selNumber"
|
||||||
|
:max="scope.row.num - scope.row.returnNum"></el-input-number>
|
||||||
|
<span v-else>{{ scope.row.num - scope.row.returnNum }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column v-else label="可退款数量" align="center" width="130px">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-input-number v-if="scope.row.checked" :min="0" style="width: 100px" v-model="scope.row.selNumber"
|
||||||
|
:max="scope.row.num - scope.row.refundNum - scope.row.returnNum"></el-input-number>
|
||||||
|
<span v-else>
|
||||||
|
{{ scope.row.num - scope.row.refundNum - scope.row.returnNum }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="已退款数量" width="100" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<span v-if="detail.status == 'unpaid'">{{ scope.row.returnNum }}</span>
|
||||||
|
<span v-else>{{ scope.row.refundNum }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" fixed="right">
|
||||||
|
<template #default="scope">
|
||||||
|
<template v-if="detail.status != 'unpaid'">
|
||||||
|
<el-button v-if="canTuikuan(scope.row)" link size="small" @click="tuikuan(scope.row)">
|
||||||
|
<span>退款</span>
|
||||||
|
</el-button>
|
||||||
|
<span class="color-999" v-if="scope.row.status == 'refund'">已退款</span>
|
||||||
|
</template>
|
||||||
|
<template v-if="detail.status == 'unpaid'">
|
||||||
|
<el-button v-if="canTuicai(scope.row)" link size="small" @click="tuicai(scope.row)">
|
||||||
|
<span>退菜</span>
|
||||||
|
</el-button>
|
||||||
|
<span class="color-999" v-else>已退菜</span>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</template>
|
||||||
|
<div class="u-p-20 u-flex u-row-right"
|
||||||
|
v-if="detail.status !== 'refund' && detail.status !== 'unpaid' && detail.status !== 'cancelled'">
|
||||||
|
<el-checkbox v-model="allSelected" @change="allSelectedChange" label="全选"></el-checkbox>
|
||||||
|
<el-button type="danger" class="u-m-l-20" @click.stop="tuikuan('all')">退款</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="u-p-20 u-flex u-row-right" v-if="detail.status == 'unpaid'">
|
||||||
|
<el-checkbox v-model="allSelected" @change="allSelectedChange" label="全选"></el-checkbox>
|
||||||
|
<el-button type="danger" class="u-m-l-20" @click.stop="tuicai('all')">退菜</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<return-money :modal="false" ref="refReturnMoney" :max="selGoods.num" :goods="selGoods"
|
||||||
|
@confirm="refReturnMoneyConfirm"></return-money>
|
||||||
|
<order-return-cart ref="refReturnCart" @confirm="refReturnCartConfirm"></order-return-cart>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, computed, watch, defineEmits, onMounted } from 'vue'
|
||||||
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
import returnMoney from "./components/return-money.vue";
|
||||||
|
import orderReturnCart from "./components/order-return-cart.vue";
|
||||||
|
import { ElMessage } from "element-plus";
|
||||||
|
import { returnOptionsLabel } from "./config/config";
|
||||||
|
import * as $util from "./order_goods_util.js";
|
||||||
|
import orderApi from "@/api/order/order";
|
||||||
|
import shopUserApi from "@/api/account/shopUser";
|
||||||
|
import orderEnum from "./components/orderEnum";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import { use } from 'echarts';
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
const emit = defineEmits(['close'])
|
||||||
|
|
||||||
|
// 基础变量
|
||||||
|
const allSelected = ref(false)
|
||||||
|
const user = ref("")
|
||||||
|
const drawer = ref(false)
|
||||||
|
const type = ref("1")
|
||||||
|
const detail = ref("")
|
||||||
|
const loading = ref(false)
|
||||||
|
const refoundList = ref([])
|
||||||
|
const selGoods = ref({ num: 1 })
|
||||||
|
const tableRefs = ref({})
|
||||||
|
|
||||||
|
// 子组件ref
|
||||||
|
const refReturnMoney = ref(null)
|
||||||
|
const refReturnCart = ref(null)
|
||||||
|
|
||||||
|
// 计算属性
|
||||||
|
const returnOriginAmount = computed(() => {
|
||||||
|
let amount = 0;
|
||||||
|
if (detail.value && detail.value.originAmount) {
|
||||||
|
return detail.value.originAmount;
|
||||||
|
}
|
||||||
|
if (!detail.value) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for (const i in detail.value.detailMap) {
|
||||||
|
amount += detail.value.detailMap[i].reduce((pre, cur) => pre + cur.payAmount, 0);
|
||||||
|
}
|
||||||
|
return amount.toFixed(2);
|
||||||
|
})
|
||||||
|
|
||||||
|
// 监听关闭抽屉
|
||||||
|
watch(drawer, (newval) => {
|
||||||
|
if (!newval) {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 方法
|
||||||
|
const tableSelectAll = (e, index) => {
|
||||||
|
const arr = detail.value.detailMap[index];
|
||||||
|
for (const i in arr) {
|
||||||
|
arr[i].checked = e.length ? true : false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const allSelectedChange = (newval) => {
|
||||||
|
for (const i in detail.value.detailMap) {
|
||||||
|
for (const key in detail.value.detailMap[i]) {
|
||||||
|
detail.value.detailMap[i][key].checked = newval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const reset = () => {
|
||||||
|
user.value = "";
|
||||||
|
allSelected.value = false;
|
||||||
|
emit("close");
|
||||||
|
}
|
||||||
|
|
||||||
|
const returnPayType = (payType) => {
|
||||||
|
if (!payType) return "";
|
||||||
|
return returnOptionsLabel("payType", payType);
|
||||||
|
}
|
||||||
|
|
||||||
|
const sendTypeFilter = (t) => {
|
||||||
|
if (!t) return t;
|
||||||
|
const item = orderEnum.sendType.find(item => item.key == t);
|
||||||
|
return item ? item.label : "-";
|
||||||
|
}
|
||||||
|
|
||||||
|
const platformTypeFilter = (t) => {
|
||||||
|
if (!t) return t;
|
||||||
|
const item = orderEnum.platformType.find(item => item.key == t);
|
||||||
|
return item ? item.label : "-";
|
||||||
|
}
|
||||||
|
|
||||||
|
const statusFilter = (t) => {
|
||||||
|
return returnOptionsLabel("status", t);
|
||||||
|
}
|
||||||
|
|
||||||
|
const timeFilter = (t) => {
|
||||||
|
return t ? dayjs(t).format("YYYY-MM-DD HH:mm:ss") : "-";
|
||||||
|
}
|
||||||
|
|
||||||
|
const canTuikuan = (item) => $util.canTuiKuan(detail.value, item)
|
||||||
|
const canTuicai = (item) => $util.canTuicai(detail.value, item)
|
||||||
|
|
||||||
|
const refReturnMoneyConfirm = async (e) => {
|
||||||
|
await orderApi.refundOrder({ ...e, orderId: detail.value.id });
|
||||||
|
ElMessage.success("退款成功");
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
const update = () => {
|
||||||
|
tbOrderInfoDetail(detail.value.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
const refReturnCartConfirm = async (e) => {
|
||||||
|
await orderApi.refundOrder({ ...e, orderId: detail.value.id });
|
||||||
|
ElMessage.success("退菜成功");
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
const tuikuan = (item) => {
|
||||||
|
if (!item) {
|
||||||
|
refReturnMoney.value.open([], detail.value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const arr = [];
|
||||||
|
if (item === "all") {
|
||||||
|
for (const i in detail.value.detailMap) {
|
||||||
|
detail.value.detailMap[i].forEach(v => {
|
||||||
|
if (v.checked && v.selNumber) arr.push(v);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
arr.push(item);
|
||||||
|
}
|
||||||
|
if (arr.length === 0) {
|
||||||
|
return ElMessage.error("请选择要退款的商品和数量");
|
||||||
|
}
|
||||||
|
refReturnMoney.value.open(arr, detail.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
const tuicai = (item) => {
|
||||||
|
const arr = [];
|
||||||
|
if (item === "all") {
|
||||||
|
for (const i in detail.value.detailMap) {
|
||||||
|
detail.value.detailMap[i].forEach(v => {
|
||||||
|
if (v.checked && v.selNumber) arr.push(v);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
arr.push(item);
|
||||||
|
}
|
||||||
|
if (arr.length === 0) {
|
||||||
|
return ElMessage.error("请选择要退菜的商品和数量");
|
||||||
|
}
|
||||||
|
refReturnCart.value.open(arr, detail.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拉取订单详情
|
||||||
|
const tbOrderInfoDetail = async (id) => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
const res = await orderApi.get({ orderId: id });
|
||||||
|
if (res.userId) {
|
||||||
|
shopUserApi.get({ userId: res.userId }).then(res1 => {
|
||||||
|
user.value = res1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
for (const i in res.detailMap) {
|
||||||
|
res.detailMap[i] = res.detailMap[i].map(v => {
|
||||||
|
return {
|
||||||
|
...v,
|
||||||
|
checked: false,
|
||||||
|
selNumber: v.num - (res.status == "unpaid" ? v.returnNum : v.refundNum),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
detail.value = res;
|
||||||
|
loading.value = false;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const show = (obj) => {
|
||||||
|
drawer.value = true;
|
||||||
|
type.value = "1";
|
||||||
|
detail.value = "";
|
||||||
|
tbOrderInfoDetail(obj.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保留废弃方法防止外部调用报错
|
||||||
|
const tableSelect = () => { }
|
||||||
|
const tableSelectionChange = () => { }
|
||||||
|
const rowClick = () => { }
|
||||||
|
const isShowGoodsVipPrice = (item) => $util.isShowGoodsVipPrice(item)
|
||||||
|
const isUseCalcPrice = (item) => $util.isUseCalcPrice(detail.value, item)
|
||||||
|
const close = () => emit("close")
|
||||||
|
const isTui = (item) => $util.isTui(item)
|
||||||
|
const to2 = (n) => Number(n).toFixed(2)
|
||||||
|
const orderTypeFilter = (t) => {
|
||||||
|
if (!t) return t;
|
||||||
|
const row = orderEnum.orderType.find(item => item.key == t);
|
||||||
|
return row?.label;
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (route.query.orderId) {
|
||||||
|
tbOrderInfoDetail(route.query.orderId);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.packeFee {
|
||||||
|
width: 40px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 40px;
|
||||||
|
background: #3f9eff;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 12px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shop_info {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.info {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding-left: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
padding: 0 20px 0;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
|
.back {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-th {
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order_detail_container {
|
||||||
|
width: 100%;
|
||||||
|
--gap: 20px;
|
||||||
|
padding: 0 var(--gap);
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
.order_top {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 14px;
|
||||||
|
|
||||||
|
.table {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
grid-template-rows: repeat(3, 1fr);
|
||||||
|
grid-column-gap: 0px;
|
||||||
|
grid-row-gap: 10px;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.div1 {
|
||||||
|
grid-area: 1 / 1 / 2 / 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.div2 {
|
||||||
|
grid-area: 2 / 1 / 3 / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.div3 {
|
||||||
|
grid-area: 2 / 2 / 3 / 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.div4 {
|
||||||
|
grid-area: 3 / 1 / 4 / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.div5 {
|
||||||
|
grid-area: 3 / 2 / 4 / 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.div6 {
|
||||||
|
grid-area: 3 / 3 / 4 / 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.info_content {
|
||||||
|
padding: var(--gap);
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-top: var(--gap);
|
||||||
|
|
||||||
|
.item {
|
||||||
|
// border-bottom: 1px dashed #ececec;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
|
||||||
|
&:not(:first-child) {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
display: flex;
|
||||||
|
color: #555;
|
||||||
|
padding-top: 20px;
|
||||||
|
|
||||||
|
.row_col {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
div {
|
||||||
|
width: 25%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.user_info_wrap {
|
||||||
|
display: flex;
|
||||||
|
margin-top: var(--gap);
|
||||||
|
|
||||||
|
.user_info_wrap_item {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.shop_info_wrap {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: var(--gap);
|
||||||
|
margin-top: var(--gap);
|
||||||
|
}
|
||||||
|
|
||||||
|
.refund_wrap {
|
||||||
|
.row {
|
||||||
|
border-bottom: 1px dashed #ececec;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
|
||||||
|
&:not(:first-child) {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list {
|
||||||
|
.list_row {
|
||||||
|
display: flex;
|
||||||
|
padding-top: 10px;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
color: #555;
|
||||||
|
|
||||||
|
.name {
|
||||||
|
margin-left: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.foot {
|
||||||
|
color: #333;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.colorStyle {
|
||||||
|
color: #ffc315;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -238,7 +238,8 @@ function toPayOrder(order: getListResponse) {
|
|||||||
//详情
|
//详情
|
||||||
const refDetail = ref();
|
const refDetail = ref();
|
||||||
function showdetail(row: OrderInfoVo) {
|
function showdetail(row: OrderInfoVo) {
|
||||||
refDetail.value.show(row);
|
// refDetail.value.show(row);
|
||||||
|
router.push({ name: 'order_detail', query: { orderId: row.id } })
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
277
src/views/user/list/components/setUserVipDialog.vue
Normal file
277
src/views/user/list/components/setUserVipDialog.vue
Normal file
@@ -0,0 +1,277 @@
|
|||||||
|
<!-- 设置会员等级 -->
|
||||||
|
<template>
|
||||||
|
<el-dialog title="设置会员等级" width="600px" v-model="visible" @close="resetHandle">
|
||||||
|
<div class="container">
|
||||||
|
<div class="title">当前会员详情</div>
|
||||||
|
<div class="row">
|
||||||
|
<el-avatar :size="50" :src="userInfo.headImg" shape="square"></el-avatar>
|
||||||
|
<div class="info">
|
||||||
|
<div class="name">昵称:{{ userInfo.nickName }}</div>
|
||||||
|
<div class="id">id:{{ userInfo.id }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="vip-info">
|
||||||
|
<div class="item">
|
||||||
|
<div class="label">会员等级:</div>
|
||||||
|
<div class="value">{{ userInfo.isVip == 1 ? userInfo.memberLevelName : '非会员' }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="label">开通时间:</div>
|
||||||
|
<div class="value">{{ userInfo.startTime || '-' }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="label">到期时间:</div>
|
||||||
|
<div class="value">
|
||||||
|
<template v-if="userInfo.isVip">
|
||||||
|
<el-text type="danger">
|
||||||
|
{{ userInfo.endTime == permanentTime ? '永久有效' : userInfo.endTime }}
|
||||||
|
</el-text>
|
||||||
|
</template>
|
||||||
|
<template v-else>-</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="label">成长值:</div>
|
||||||
|
<div class="value">{{ userInfo.experience || 0 }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="title">设置会员等级</div>
|
||||||
|
<el-form ref="formRef" :model="form" :rules="rules">
|
||||||
|
<el-form-item label="到期时间" prop="timeType">
|
||||||
|
<el-radio-group v-model="form.timeType" @change="timeTypeChange">
|
||||||
|
<el-radio :value="1" label="永久有效"></el-radio>
|
||||||
|
<el-radio :value="2" label="手动设置"></el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="form.timeType === 2" label="设置时间" prop="endTime">
|
||||||
|
<el-date-picker v-model="form.endTime" type="date" placeholder="请选择时间"
|
||||||
|
:disabled-date="disabledDate"></el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="会员等级" prop="memberLevelId">
|
||||||
|
<el-radio-group v-model="form.memberLevelId">
|
||||||
|
<el-radio :value="item.id" :label="item.name" v-for="item in levelList" :key="item.id"></el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="visible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="handleOk" :loading="confirmLoading">确 定</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import { ref, onMounted, watch } from "vue";
|
||||||
|
import memberApi from '@/api/market/member'
|
||||||
|
|
||||||
|
const emits = defineEmits(['success'])
|
||||||
|
|
||||||
|
const userInfo = ref({});
|
||||||
|
|
||||||
|
const form = ref({
|
||||||
|
timeType: '',
|
||||||
|
endTime: '',
|
||||||
|
memberLevelId: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
// 页面初始化仅计算一次今日零点
|
||||||
|
const dateKey = ref(0)
|
||||||
|
const today = dayjs().startOf('day').valueOf()
|
||||||
|
|
||||||
|
const disabledDate = (time) => {
|
||||||
|
return time.getTime() < today
|
||||||
|
}
|
||||||
|
|
||||||
|
const visible = ref(false);
|
||||||
|
const formRef = ref(null);
|
||||||
|
const permanentTime = ref('9999-12-31 23:59:59')
|
||||||
|
const rules = {
|
||||||
|
timeType: [{ required: true, message: '请选择到期时间', trigger: 'blur' }],
|
||||||
|
endTime: [{ required: true, message: '请输入到期时间', trigger: 'blur' }],
|
||||||
|
memberLevelId: [{ required: true, message: '请选择会员等级', trigger: 'blur' }]
|
||||||
|
};
|
||||||
|
const confirmLoading = ref(false);
|
||||||
|
function handleOk() {
|
||||||
|
formRef.value.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
confirmLoading.value = true;
|
||||||
|
const data = {
|
||||||
|
id: userInfo.value.id,
|
||||||
|
isVip: 1,
|
||||||
|
memberLevelId: form.value.memberLevelId,
|
||||||
|
endTime: dayjs(form.value.endTime).format('YYYY-MM-DD 23:59:59')
|
||||||
|
}
|
||||||
|
memberApi.editMemberInfo(data).then(res => {
|
||||||
|
confirmLoading.value = false;
|
||||||
|
ElNotification({
|
||||||
|
title: '成功',
|
||||||
|
message: '设置会员等级成功',
|
||||||
|
type: 'success',
|
||||||
|
});
|
||||||
|
visible.value = false;
|
||||||
|
emits('success')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetHandle() {
|
||||||
|
form.value = {
|
||||||
|
timeType: '',
|
||||||
|
endTime: [],
|
||||||
|
memberLevelId: ''
|
||||||
|
};
|
||||||
|
confirmLoading.value = false;
|
||||||
|
formRef.value.clearValidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
function open(row) {
|
||||||
|
console.log(row);
|
||||||
|
userInfo.value = { ...row };
|
||||||
|
visible.value = true;
|
||||||
|
|
||||||
|
if (userInfo.value.isVip) {
|
||||||
|
form.value.endTime = userInfo.value.endTime
|
||||||
|
form.value.memberLevelId = userInfo.value.memberLevelId
|
||||||
|
|
||||||
|
if (userInfo.value.endTime == permanentTime.value) {
|
||||||
|
form.value.timeType = 1
|
||||||
|
} else {
|
||||||
|
form.value.timeType = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消会员
|
||||||
|
async function cancelVip(row) {
|
||||||
|
try {
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
ElMessageBox.confirm('确定取消会员吗?', '提示', {
|
||||||
|
beforeClose: async (action, instance, done) => {
|
||||||
|
if (action === 'confirm') {
|
||||||
|
instance.confirmButtonLoading = true
|
||||||
|
try {
|
||||||
|
const data = {
|
||||||
|
id: row.id,
|
||||||
|
isVip: 0
|
||||||
|
}
|
||||||
|
// 仅接口成功才 resolve,执行关闭
|
||||||
|
await memberApi.editMemberInfo(data)
|
||||||
|
ElMessage.success('操作成功')
|
||||||
|
emits('success')
|
||||||
|
resolve()
|
||||||
|
// 请求成功再关闭弹窗
|
||||||
|
done()
|
||||||
|
} catch (e) {
|
||||||
|
// 请求失败:不关闭弹窗,只取消loading,向外抛出错误
|
||||||
|
instance.confirmButtonLoading = false
|
||||||
|
reject(e)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 点击取消,直接关闭
|
||||||
|
done()
|
||||||
|
reject(new Error('cancel'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).catch(() => reject(new Error('cancel')))
|
||||||
|
})
|
||||||
|
} catch (err) {
|
||||||
|
// 区分是手动取消还是接口报错
|
||||||
|
if (err.message !== 'cancel') {
|
||||||
|
ElMessage.error(err.message || '操作失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open,
|
||||||
|
cancelVip
|
||||||
|
});
|
||||||
|
|
||||||
|
// 到期时间类型切换
|
||||||
|
function timeTypeChange(value) {
|
||||||
|
if (value === 1) {
|
||||||
|
form.value.endTime = permanentTime.value;
|
||||||
|
} else {
|
||||||
|
form.value.endTime = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取会员等级列表
|
||||||
|
const levelList = ref([]);
|
||||||
|
async function getlevelList() {
|
||||||
|
try {
|
||||||
|
const res = await memberApi.levelList();
|
||||||
|
levelList.value = res;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getlevelList()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
background-color: #efefef;
|
||||||
|
border-radius: 2px;
|
||||||
|
padding: 14px 18px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.info {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
padding-left: 14px;
|
||||||
|
|
||||||
|
.name {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.id {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.vip-info {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
gap: 10px;
|
||||||
|
padding: 10px 0;
|
||||||
|
margin-bottom: 14px;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -94,7 +94,8 @@ const contentConfig: IContentConfig<any> = {
|
|||||||
align: "center",
|
align: "center",
|
||||||
fixed: "right",
|
fixed: "right",
|
||||||
width: 180,
|
width: 180,
|
||||||
templet: "tool",
|
templet: "custom",
|
||||||
|
slotName: "operat",
|
||||||
operat: [
|
operat: [
|
||||||
{
|
{
|
||||||
name: "edit",
|
name: "edit",
|
||||||
@@ -109,6 +110,7 @@ const contentConfig: IContentConfig<any> = {
|
|||||||
{ label: '充值记录', command: 'charge-list' },
|
{ label: '充值记录', command: 'charge-list' },
|
||||||
{ label: '赠送券', command: 'give-coupon' },
|
{ label: '赠送券', command: 'give-coupon' },
|
||||||
{ label: '账号禁用/开启', command: 'user-disabld' },
|
{ label: '账号禁用/开启', command: 'user-disabld' },
|
||||||
|
{ label: '设置会员等级', command: 'user-vip' },
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -44,27 +44,27 @@ const modalConfig: IModalConfig<editRequest> = {
|
|||||||
sm: 12,
|
sm: 12,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// {
|
{
|
||||||
// type: "input",
|
type: "input",
|
||||||
// label: "手机号码",
|
label: "手机号码",
|
||||||
// prop: "phone",
|
prop: "phone",
|
||||||
// rules: [
|
rules: [
|
||||||
// {
|
{
|
||||||
// required: true,
|
required: true,
|
||||||
// pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
|
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
|
||||||
// message: "请输入正确的手机号码",
|
message: "请输入正确的手机号码",
|
||||||
// trigger: "blur",
|
trigger: "blur",
|
||||||
// },
|
},
|
||||||
// ],
|
],
|
||||||
// attrs: {
|
attrs: {
|
||||||
// placeholder: "请输入手机号码",
|
placeholder: "请输入手机号码",
|
||||||
// maxlength: 11,
|
maxlength: 11,
|
||||||
// },
|
},
|
||||||
// col: {
|
col: {
|
||||||
// xs: 24,
|
xs: 24,
|
||||||
// sm: 12,
|
sm: 12,
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
{
|
{
|
||||||
label: "会员生日",
|
label: "会员生日",
|
||||||
prop: "birthDay",
|
prop: "birthDay",
|
||||||
@@ -72,6 +72,10 @@ const modalConfig: IModalConfig<editRequest> = {
|
|||||||
type: "date-picker",
|
type: "date-picker",
|
||||||
attrs: {
|
attrs: {
|
||||||
placeholder: "请选择会员生日",
|
placeholder: "请选择会员生日",
|
||||||
|
// 禁止选择今天之后的日期
|
||||||
|
'disabled-date': (time: any) => {
|
||||||
|
return dayjs(time).isAfter(dayjs(), 'day')
|
||||||
|
}
|
||||||
},
|
},
|
||||||
col: {
|
col: {
|
||||||
xs: 24,
|
xs: 24,
|
||||||
|
|||||||
@@ -89,7 +89,30 @@
|
|||||||
</el-link>
|
</el-link>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<template #operat="scope">
|
||||||
|
<el-button type="primary" link @click="handleEditClick(scope.row)">编辑</el-button>
|
||||||
|
<el-dropdown placement="bottom-end" @command="dropdownCommand($event, scope.row)">
|
||||||
|
<el-button type="primary" link>
|
||||||
|
更多
|
||||||
|
<el-icon class="el-icon--right">
|
||||||
|
<arrow-down />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item command="change-money">增减余额</el-dropdown-item>
|
||||||
|
<el-dropdown-item command="charge-list">充值记录</el-dropdown-item>
|
||||||
|
<el-dropdown-item command="give-coupon">赠送券</el-dropdown-item>
|
||||||
|
<el-dropdown-item command="user-disabld">账号禁用/开启</el-dropdown-item>
|
||||||
|
<el-dropdown-item command="user-vip">设置会员等级</el-dropdown-item>
|
||||||
|
<el-dropdown-item command="user-vip-cancel" v-if="scope.row.isVip == 1">取消会员</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</template>
|
||||||
</page-content>
|
</page-content>
|
||||||
|
<!-- 设置会员等级 -->
|
||||||
|
<setUserVipDialog ref="setUserVipDialogRef" @success="searchQueryClick"></setUserVipDialog>
|
||||||
|
|
||||||
<!-- 新增 -->
|
<!-- 新增 -->
|
||||||
<page-modal ref="addModalRef" :modal-config="addModalConfig" @submit-click="handleSubmitClick"></page-modal>
|
<page-modal ref="addModalRef" :modal-config="addModalConfig" @submit-click="handleSubmitClick"></page-modal>
|
||||||
@@ -163,7 +186,9 @@ import shopUserApi from "@/api/account/shopUser";
|
|||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { ElNotification } from 'element-plus'
|
import { ElNotification } from 'element-plus'
|
||||||
import { downloadFile } from "@/utils/index";
|
import { downloadFile } from "@/utils/index";
|
||||||
|
import setUserVipDialog from "./components/setUserVipDialog.vue";
|
||||||
|
|
||||||
|
const setUserVipDialogRef = ref(null);
|
||||||
const editMoneyModalRef = ref(null);
|
const editMoneyModalRef = ref(null);
|
||||||
const userCouponDialogRef = ref(null);
|
const userCouponDialogRef = ref(null);
|
||||||
const GiveCouponRef = ref(null);
|
const GiveCouponRef = ref(null);
|
||||||
@@ -317,6 +342,11 @@ async function getUserVipInfo() {
|
|||||||
|
|
||||||
// 赠送券
|
// 赠送券
|
||||||
function toGiveCoupon() { }
|
function toGiveCoupon() { }
|
||||||
|
|
||||||
|
function dropdownCommand(command, row) {
|
||||||
|
handleOperatClick({ name: "more", command, row });
|
||||||
|
}
|
||||||
|
|
||||||
// 其他操作列
|
// 其他操作列
|
||||||
async function handleOperatClick(data) {
|
async function handleOperatClick(data) {
|
||||||
const row = data.row;
|
const row = data.row;
|
||||||
@@ -343,6 +373,14 @@ async function handleOperatClick(data) {
|
|||||||
visible.value = true
|
visible.value = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (data.command === 'user-vip') {
|
||||||
|
setUserVipDialogRef.value.open(row)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (data.command === 'user-vip-cancel') {
|
||||||
|
setUserVipDialogRef.value.cancelVip(row)
|
||||||
|
return
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user