feat(shop): 新增线下付款支持及优化Dashboard数据统计
- 新增线下付款(payType=9)支付方式,支持订单中标识和确认收款操作 - 实现商家确认线下付款后订单进入待发货状态功能 - 更新支付方式组件和订单列表及详情页的支付状态显示 - 优化shop/dashboard快捷操作按钮为商城常用功能,修正快速入口路由路径 - 修复Dashboard待发货订单数统计时未过滤商城订单导致数据不准的问题 - 修复Dashboard运行天数为0的异常,将租户信息请求独立处理,避免某些请求失败影响 - 修复statisticsStore中couponUsedCount与getter同名冲突,改名为safeCouponUsedCount并同步更新引用
This commit is contained in:
@@ -6,3 +6,27 @@
|
|||||||
- 在 `src/views/shop/dashboard/index.vue` 的欢迎横幅右侧添加新订单提醒开关栏(开关 + 测试按钮),检测到新订单后自动调用 loadData() 刷新 Dashboard 数据。
|
- 在 `src/views/shop/dashboard/index.vue` 的欢迎横幅右侧添加新订单提醒开关栏(开关 + 测试按钮),检测到新订单后自动调用 loadData() 刷新 Dashboard 数据。
|
||||||
- 在 `src/views/cms/dashboard/index.vue` 的概况卡片标题栏添加新订单提醒控件,同样检测到新订单后刷新数据。
|
- 在 `src/views/cms/dashboard/index.vue` 的概况卡片标题栏添加新订单提醒控件,同样检测到新订单后刷新数据。
|
||||||
- 提取了 CMS Dashboard 的 loadData 函数使其可复用。
|
- 提取了 CMS Dashboard 的 loadData 函数使其可复用。
|
||||||
|
|
||||||
|
## 更新 shop/dashboard 快捷操作按钮为商城常用功能
|
||||||
|
|
||||||
|
- 快捷操作按钮从原来的通用功能(参数配置/用户管理/站点管理/登录日志)改为商城系统常用功能:订单管理、商品管理、商品分类、优惠券管理、会员管理、商城设置、清除缓存。
|
||||||
|
- 路由路径统一使用 `/shop/shopXxx` 格式(与 `/shop/shopOrder` 等已确认路径一致),修复了快速入口中 `/shopGoods` → `/shop/shopGoods` 的路径不一致问题。
|
||||||
|
- 快速入口九宫格也同步改为商城相关入口。
|
||||||
|
- 图标导入更新:移除 UngroupOutlined/CalendarOutlined/UserOutlined/FileTextOutlined,新增 ShoppingCartOutlined/AppstoreOutlined/GiftOutlined/TeamOutlined/SettingOutlined。
|
||||||
|
|
||||||
|
## 修复 shop/dashboard 待发货订单数量统计不准确
|
||||||
|
|
||||||
|
- 根因:订单列表页 datasource 中 `where.type = 0`(只查商城订单),但 Dashboard 统计未传 `type: 0`,导致把预定订单/外卖(type=1)和会员卡订单(type=2)也计入。
|
||||||
|
- 修复:为 pendingShipmentCount 和 pendingRefundCount 查询都加上 `type: 0`。
|
||||||
|
|
||||||
|
## 修复 Dashboard 运行天数为 0 的问题
|
||||||
|
|
||||||
|
- 根因:`getTenantInfo()` 被放在 `await Promise.all([...])` 之后,如果 `statisticsStore.fetchStatistics()` 抛异常(`couponUsedCount` 错误),`Promise.all` reject 后直接跳到 `catch`,`getTenantInfo` 根本不会执行,`tenantCreateTime` 永远是空值。
|
||||||
|
- 修复:在 `shop/dashboard/index.vue` 和 `cms/dashboard/index.vue` 的 `loadData` 中,把 `getTenantInfo()` 放到 `Promise.all` 外面,用 `.then` 独立执行,不受其他请求失败影响。
|
||||||
|
- 运行天数计算基于 `getTenantInfo()` 返回的 `Company.createTime`(租户创建时间)。
|
||||||
|
|
||||||
|
## 修复 statisticsStore couponUsedCount 冲突
|
||||||
|
|
||||||
|
- 根因:`couponUsedCount` 同时被定义成 state 属性和 getter,Pinia 中同名冲突导致 action 里 `this.couponUsedCount = ...` 报错:`'set' on proxy: trap returned falsish`。
|
||||||
|
- 修复:将 getter 改名为 `safeCouponUsedCount`,`shop/dashboard/index.vue` 中同步更新引用(该引用当前被注释,但保持一致性)。
|
||||||
|
|
||||||
|
|||||||
@@ -150,3 +150,19 @@ export async function refundShopOrder(data: ShopOrder) {
|
|||||||
}
|
}
|
||||||
return Promise.reject(new Error(res.data.message));
|
return Promise.reject(new Error(res.data.message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确认线下付款收款
|
||||||
|
* 商家确认已收到线下转账(微信转账/银行汇款等),确认后订单进入待发货状态
|
||||||
|
*/
|
||||||
|
export async function confirmOfflinePayment(id: number, remarks?: string) {
|
||||||
|
const res = await request.put<ApiResult<unknown>>(
|
||||||
|
MODULES_API_URL + '/shop/shop-order/confirm-offline-payment/' + id,
|
||||||
|
null,
|
||||||
|
{ params: { remarks } }
|
||||||
|
);
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
return res.data.message;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.data.message));
|
||||||
|
}
|
||||||
|
|||||||
@@ -85,9 +85,9 @@ export interface ShopOrder {
|
|||||||
coachId?: number;
|
coachId?: number;
|
||||||
// 支付的用户id
|
// 支付的用户id
|
||||||
payUserId?: number;
|
payUserId?: number;
|
||||||
// 0余额支付, 1微信支付, 2支付宝, 3银联支付, 4现金支付, 5POS机支付, 6免费, 7积分支付, 8货到付款, 9~18 已废弃
|
// 0余额支付, 1微信支付, 2支付宝, 3银联支付, 4现金支付, 5POS机支付, 6免费, 7积分支付, 8货到付款, 9线下付款, 10~18 已废弃
|
||||||
payType?: number;
|
payType?: number;
|
||||||
// 代付支付方式, 0余额支付, 1微信支付, 2支付宝, 3银联支付, 4现金支付, 5POS机支付, 6免费, 7积分支付, 8货到付款, 9~18 已废弃
|
// 代付支付方式, 0余额支付, 1微信支付, 2支付宝, 3银联支付, 4现金支付, 5POS机支付, 6免费, 7积分支付, 8货到付款, 9线下付款, 10~18 已废弃
|
||||||
friendPayType?: number;
|
friendPayType?: number;
|
||||||
// 0未付款,1已付款
|
// 0未付款,1已付款
|
||||||
payStatus?: number;
|
payStatus?: number;
|
||||||
|
|||||||
@@ -84,6 +84,12 @@
|
|||||||
label: '货到付款',
|
label: '货到付款',
|
||||||
key: 'codPay',
|
key: 'codPay',
|
||||||
icon: 'IdcardOutlined'
|
icon: 'IdcardOutlined'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 9,
|
||||||
|
label: '线下付款',
|
||||||
|
key: 'offlinePay',
|
||||||
|
icon: 'IdcardOutlined'
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@@ -90,9 +90,9 @@ export const useStatisticsStore = defineStore('statistics', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取今日使用优惠券数量
|
* 获取今日使用优惠券数量(安全取值)
|
||||||
*/
|
*/
|
||||||
couponUsedCount: (state): number => {
|
safeCouponUsedCount: (state): number => {
|
||||||
return safeNumber(state.couponUsedCount);
|
return safeNumber(state.couponUsedCount);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,10 @@ export function getPayType(index?: number): any {
|
|||||||
{
|
{
|
||||||
value: 8,
|
value: 8,
|
||||||
label: '货到付款'
|
label: '货到付款'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 9,
|
||||||
|
label: '线下付款'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
if (index != null) {
|
if (index != null) {
|
||||||
|
|||||||
@@ -213,11 +213,14 @@
|
|||||||
import { openNew } from '@/utils/common';
|
import { openNew } from '@/utils/common';
|
||||||
import { useSiteStore } from '@/store/modules/site';
|
import { useSiteStore } from '@/store/modules/site';
|
||||||
import { useStatisticsStore } from '@/store/modules/statistics';
|
import { useStatisticsStore } from '@/store/modules/statistics';
|
||||||
|
import { useUserStore } from '@/store/modules/user';
|
||||||
|
import { getTenantInfo } from '@/api/layout';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
|
|
||||||
// 使用状态管理
|
// 使用状态管理
|
||||||
const siteStore = useSiteStore();
|
const siteStore = useSiteStore();
|
||||||
const statisticsStore = useStatisticsStore();
|
const statisticsStore = useStatisticsStore();
|
||||||
|
const userStore = useUserStore();
|
||||||
|
|
||||||
// 从 store 中获取响应式数据
|
// 从 store 中获取响应式数据
|
||||||
const { siteInfo, loading: siteLoading } = storeToRefs(siteStore);
|
const { siteInfo, loading: siteLoading } = storeToRefs(siteStore);
|
||||||
@@ -238,7 +241,13 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 计算属性
|
// 计算属性
|
||||||
const runDays = computed(() => siteStore.runDays);
|
const now = ref(Date.now());
|
||||||
|
const tenantCreateTime = ref<string>('');
|
||||||
|
let runDaysTimer: ReturnType<typeof setInterval>;
|
||||||
|
const runDays = computed(() => {
|
||||||
|
if (!tenantCreateTime.value) return 0;
|
||||||
|
return Math.floor((now.value - new Date(tenantCreateTime.value).getTime()) / (24 * 60 * 60 * 1000));
|
||||||
|
});
|
||||||
const userCount = computed(() => statisticsStore.userCount);
|
const userCount = computed(() => statisticsStore.userCount);
|
||||||
const orderCount = computed(() => statisticsStore.orderCount);
|
const orderCount = computed(() => statisticsStore.orderCount);
|
||||||
const totalSales = computed(() => statisticsStore.totalSales);
|
const totalSales = computed(() => statisticsStore.totalSales);
|
||||||
@@ -248,6 +257,15 @@
|
|||||||
|
|
||||||
// 加载数据
|
// 加载数据
|
||||||
const loadData = async () => {
|
const loadData = async () => {
|
||||||
|
// 独立请求租户信息,不受其他请求失败影响
|
||||||
|
getTenantInfo()
|
||||||
|
.then((res) => {
|
||||||
|
tenantCreateTime.value = res?.createTime || '';
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
console.warn('获取租户信息失败:', e);
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
siteStore.fetchSiteInfo(),
|
siteStore.fetchSiteInfo(),
|
||||||
@@ -267,11 +285,14 @@
|
|||||||
await loadData();
|
await loadData();
|
||||||
// 开始自动刷新统计数据(每5分钟)
|
// 开始自动刷新统计数据(每5分钟)
|
||||||
statisticsStore.startAutoRefresh();
|
statisticsStore.startAutoRefresh();
|
||||||
|
// 运行天数每小时检查一次(跨天自动更新)
|
||||||
|
runDaysTimer = setInterval(() => { now.value = Date.now(); }, 60 * 60 * 1000);
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
// 组件卸载时停止自动刷新
|
// 组件卸载时停止自动刷新
|
||||||
statisticsStore.stopAutoRefresh();
|
statisticsStore.stopAutoRefresh();
|
||||||
|
clearInterval(runDaysTimer);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -180,27 +180,30 @@
|
|||||||
<a-button
|
<a-button
|
||||||
type="primary"
|
type="primary"
|
||||||
block
|
block
|
||||||
@click="navigateTo('/website/field')"
|
@click="navigateTo('/shop/shopOrder')"
|
||||||
:loading="loading"
|
|
||||||
>
|
>
|
||||||
<UngroupOutlined />
|
<ShoppingCartOutlined />
|
||||||
参数配置
|
|
||||||
</a-button>
|
|
||||||
<a-button block @click="navigateTo('/shop/shopOrder')">
|
|
||||||
<CalendarOutlined />
|
|
||||||
订单管理
|
订单管理
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button block @click="navigateTo('/system/user')">
|
<a-button block @click="navigateTo('/shop/shopGoods')">
|
||||||
<UserOutlined />
|
|
||||||
用户管理
|
|
||||||
</a-button>
|
|
||||||
<a-button block @click="navigateTo('/website/index')">
|
|
||||||
<ShopOutlined />
|
<ShopOutlined />
|
||||||
站点管理
|
商品管理
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button block @click="navigateTo('/system/login-record')">
|
<a-button block @click="navigateTo('/shop/shopGoodsCategory')">
|
||||||
<FileTextOutlined />
|
<AppstoreOutlined />
|
||||||
登录日志
|
商品分类
|
||||||
|
</a-button>
|
||||||
|
<a-button block @click="navigateTo('/shop/shopCoupon')">
|
||||||
|
<GiftOutlined />
|
||||||
|
优惠券管理
|
||||||
|
</a-button>
|
||||||
|
<a-button block @click="navigateTo('/shop/shopUser')">
|
||||||
|
<TeamOutlined />
|
||||||
|
会员管理
|
||||||
|
</a-button>
|
||||||
|
<a-button block @click="navigateTo('/shop/shopSetting')">
|
||||||
|
<SettingOutlined />
|
||||||
|
商城设置
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button block @click="handleClearCache">
|
<a-button block @click="handleClearCache">
|
||||||
<ClearOutlined />
|
<ClearOutlined />
|
||||||
@@ -221,11 +224,12 @@ import { useOrderNotify } from '@/views/shop/shopOrder/useOrderNotify';
|
|||||||
import {
|
import {
|
||||||
ReloadOutlined,
|
ReloadOutlined,
|
||||||
RightOutlined,
|
RightOutlined,
|
||||||
UngroupOutlined,
|
ShoppingCartOutlined,
|
||||||
CalendarOutlined,
|
|
||||||
UserOutlined,
|
|
||||||
ShopOutlined,
|
ShopOutlined,
|
||||||
FileTextOutlined,
|
AppstoreOutlined,
|
||||||
|
GiftOutlined,
|
||||||
|
TeamOutlined,
|
||||||
|
SettingOutlined,
|
||||||
ClearOutlined,
|
ClearOutlined,
|
||||||
InfoCircleOutlined
|
InfoCircleOutlined
|
||||||
} from '@ant-design/icons-vue';
|
} from '@ant-design/icons-vue';
|
||||||
@@ -234,6 +238,7 @@ import { useSiteStore } from '@/store/modules/site';
|
|||||||
import { useStatisticsStore } from '@/store/modules/statistics';
|
import { useStatisticsStore } from '@/store/modules/statistics';
|
||||||
import { useUserStore } from '@/store/modules/user';
|
import { useUserStore } from '@/store/modules/user';
|
||||||
import { pageShopOrder } from '@/api/shop/shopOrder';
|
import { pageShopOrder } from '@/api/shop/shopOrder';
|
||||||
|
import { getTenantInfo } from '@/api/layout';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { removeSiteInfoCache } from '@/api/cms/cmsWebsite';
|
import { removeSiteInfoCache } from '@/api/cms/cmsWebsite';
|
||||||
|
|
||||||
@@ -257,7 +262,13 @@ const systemInfo = reactive({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 计算属性
|
// 计算属性
|
||||||
const runDays = computed(() => siteStore.runDays);
|
const now = ref(Date.now());
|
||||||
|
const tenantCreateTime = ref<string>('');
|
||||||
|
let runDaysTimer: ReturnType<typeof setInterval>;
|
||||||
|
const runDays = computed(() => {
|
||||||
|
if (!tenantCreateTime.value) return 0;
|
||||||
|
return Math.floor((now.value - new Date(tenantCreateTime.value).getTime()) / (24 * 60 * 60 * 1000));
|
||||||
|
});
|
||||||
const userCount = computed(() => statisticsStore.userCount);
|
const userCount = computed(() => statisticsStore.userCount);
|
||||||
const orderCount = computed(() => statisticsStore.orderCount);
|
const orderCount = computed(() => statisticsStore.orderCount);
|
||||||
const totalSales = computed(() => statisticsStore.totalSales);
|
const totalSales = computed(() => statisticsStore.totalSales);
|
||||||
@@ -279,7 +290,7 @@ const coreStats = computed(() => [
|
|||||||
// 待处理事项数据
|
// 待处理事项数据
|
||||||
const pendingShipmentCount = ref(0);
|
const pendingShipmentCount = ref(0);
|
||||||
const pendingRefundCount = ref(0);
|
const pendingRefundCount = ref(0);
|
||||||
const couponUsedCount = computed(() => statisticsStore.couponUsedCount);
|
const couponUsedCount = computed(() => statisticsStore.safeCouponUsedCount);
|
||||||
|
|
||||||
// 待处理事项(使用computed确保响应式更新)
|
// 待处理事项(使用computed确保响应式更新)
|
||||||
const todoItems = computed(() => [
|
const todoItems = computed(() => [
|
||||||
@@ -298,12 +309,12 @@ const todayStats = computed(() => ({
|
|||||||
|
|
||||||
// 快速入口
|
// 快速入口
|
||||||
const quickLinks = [
|
const quickLinks = [
|
||||||
{ to: '/website/field', icon: '⚙️', label: '参数配置', bg: '#eff6ff' },
|
|
||||||
{ to: '/shop/shopOrder', icon: '📦', label: '订单管理', bg: '#f0fdf4' },
|
{ to: '/shop/shopOrder', icon: '📦', label: '订单管理', bg: '#f0fdf4' },
|
||||||
{ to: '/system/user', icon: '👥', label: '用户管理', bg: '#fff7ed' },
|
{ to: '/shop/shopGoods', icon: '🏸', label: '商品管理', bg: '#ecfdf5' },
|
||||||
{ to: '/website/index', icon: '🏪', label: '站点管理', bg: '#faf5ff' },
|
{ to: '/shop/shopGoodsCategory', icon: '🗂️', label: '商品分类', bg: '#eff6ff' },
|
||||||
{ to: '/shopGoods', icon: '🏸', label: '商品管理', bg: '#ecfdf5' },
|
{ to: '/shop/shopCoupon', icon: '🎁', label: '优惠券', bg: '#fff7ed' },
|
||||||
{ to: '/cmsArticle', icon: '📝', label: '文章管理', bg: '#fefce8' },
|
{ to: '/shop/shopUser', icon: '👥', label: '会员管理', bg: '#faf5ff' },
|
||||||
|
{ to: '/shop/shopSetting', icon: '⚙️', label: '商城设置', bg: '#fefce8' },
|
||||||
];
|
];
|
||||||
|
|
||||||
// 导航跳转
|
// 导航跳转
|
||||||
@@ -348,6 +359,15 @@ const refreshStatistics = async () => {
|
|||||||
|
|
||||||
// 加载数据
|
// 加载数据
|
||||||
const loadData = async () => {
|
const loadData = async () => {
|
||||||
|
// 独立请求租户信息,不受其他请求失败影响
|
||||||
|
getTenantInfo()
|
||||||
|
.then((res) => {
|
||||||
|
tenantCreateTime.value = res?.createTime || '';
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
console.warn('获取租户信息失败:', e);
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
siteStore.fetchSiteInfo(),
|
siteStore.fetchSiteInfo(),
|
||||||
@@ -356,8 +376,9 @@ const loadData = async () => {
|
|||||||
|
|
||||||
// 获取待处理事项数据
|
// 获取待处理事项数据
|
||||||
try {
|
try {
|
||||||
// 获取待发货订单数(使用 statusFilter=1 对应待发货)
|
// 获取待发货订单数(type=0商城订单, statusFilter=1待发货)
|
||||||
const shipmentResult = await pageShopOrder({
|
const shipmentResult = await pageShopOrder({
|
||||||
|
type: 0,
|
||||||
statusFilter: 1,
|
statusFilter: 1,
|
||||||
page: 1,
|
page: 1,
|
||||||
limit: 1
|
limit: 1
|
||||||
@@ -369,8 +390,9 @@ const loadData = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 获取退款/售后订单数(使用 statusFilter=6 对应退款/售后)
|
// 获取退款/售后订单数(type=0商城订单, statusFilter=6退款/售后)
|
||||||
const refundResult = await pageShopOrder({
|
const refundResult = await pageShopOrder({
|
||||||
|
type: 0,
|
||||||
statusFilter: 6,
|
statusFilter: 6,
|
||||||
page: 1,
|
page: 1,
|
||||||
limit: 1
|
limit: 1
|
||||||
@@ -391,11 +413,15 @@ onMounted(async () => {
|
|||||||
|
|
||||||
// 开始自动刷新统计数据(每5分钟)
|
// 开始自动刷新统计数据(每5分钟)
|
||||||
statisticsStore.startAutoRefresh();
|
statisticsStore.startAutoRefresh();
|
||||||
|
|
||||||
|
// 运行天数每小时检查一次(跨天自动更新)
|
||||||
|
runDaysTimer = setInterval(() => { now.value = Date.now(); }, 60 * 60 * 1000);
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
// 组件卸载时停止自动刷新
|
// 组件卸载时停止自动刷新
|
||||||
statisticsStore.stopAutoRefresh();
|
statisticsStore.stopAutoRefresh();
|
||||||
|
clearInterval(runDaysTimer);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -71,9 +71,11 @@
|
|||||||
label="支付状态"
|
label="支付状态"
|
||||||
:labelStyle="{ width: '90px', color: '#808080' }"
|
:labelStyle="{ width: '90px', color: '#808080' }"
|
||||||
>
|
>
|
||||||
<a-tag v-if="form.payStatus == 1 && form.payType !== 8" color="green">已付款</a-tag>
|
<a-tag v-if="form.payStatus == 1 && form.payType !== 8 && form.payType !== 9" color="green">已付款</a-tag>
|
||||||
<a-tag v-if="form.payStatus == 1 && form.payType === 8" color="blue">待收货付款</a-tag>
|
<a-tag v-if="form.payStatus == 1 && form.payType === 8" color="blue">待收货付款</a-tag>
|
||||||
<a-tag v-if="form.payStatus == 0">未付款</a-tag>
|
<a-tag v-if="form.payStatus == 1 && form.payType === 9" color="green">已确认收款</a-tag>
|
||||||
|
<a-tag v-if="form.payStatus == 0 && form.payType === 9" color="orange">待确认收款</a-tag>
|
||||||
|
<a-tag v-if="form.payStatus == 0 && form.payType !== 9">未付款</a-tag>
|
||||||
<a-tag v-if="form.payStatus == 3">未付款,占场中</a-tag>
|
<a-tag v-if="form.payStatus == 3">未付款,占场中</a-tag>
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
<!-- 第四排-->
|
<!-- 第四排-->
|
||||||
@@ -147,7 +149,7 @@
|
|||||||
</a-tag>
|
</a-tag>
|
||||||
<a-tag v-if="form.payType == 9">
|
<a-tag v-if="form.payType == 9">
|
||||||
<IdcardOutlined class="tag-icon" />
|
<IdcardOutlined class="tag-icon" />
|
||||||
IC月卡
|
线下付款
|
||||||
</a-tag>
|
</a-tag>
|
||||||
<a-tag v-if="form.payType == 10">
|
<a-tag v-if="form.payType == 10">
|
||||||
<IdcardOutlined class="tag-icon" />
|
<IdcardOutlined class="tag-icon" />
|
||||||
@@ -187,7 +189,16 @@
|
|||||||
</a-tag>
|
</a-tag>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<span class="text-gray-400">未支付</span>
|
<!-- 线下付款未确认时也显示支付方式 -->
|
||||||
|
<a-tag v-if="form.payType == 9">
|
||||||
|
<IdcardOutlined class="tag-icon" />
|
||||||
|
线下付款
|
||||||
|
</a-tag>
|
||||||
|
<a-tag v-if="form.payType == 8">
|
||||||
|
<IdcardOutlined class="tag-icon" />
|
||||||
|
货到付款
|
||||||
|
</a-tag>
|
||||||
|
<span v-if="form.payType !== 9 && form.payType !== 8" class="text-gray-400">未支付</span>
|
||||||
</template>
|
</template>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
|
|||||||
@@ -93,10 +93,15 @@
|
|||||||
v-if="record.payType === 8"
|
v-if="record.payType === 8"
|
||||||
color="blue"
|
color="blue"
|
||||||
>货到付款</a-tag>
|
>货到付款</a-tag>
|
||||||
|
<!-- 线下付款标识 -->
|
||||||
|
<a-tag
|
||||||
|
v-if="record.payType === 9"
|
||||||
|
color="orange"
|
||||||
|
>线下付款</a-tag>
|
||||||
|
|
||||||
<!-- 支付状态 -->
|
<!-- 支付状态 -->
|
||||||
<a-tag
|
<a-tag
|
||||||
v-if="record.payStatus == 1 && record.payType !== 8"
|
v-if="record.payStatus == 1 && record.payType !== 8 && record.payType !== 9"
|
||||||
color="green"
|
color="green"
|
||||||
@click.stop="updatePayStatus(record)"
|
@click.stop="updatePayStatus(record)"
|
||||||
class="cursor-pointer"
|
class="cursor-pointer"
|
||||||
@@ -109,6 +114,20 @@
|
|||||||
class="cursor-pointer"
|
class="cursor-pointer"
|
||||||
>待收货付款</a-tag
|
>待收货付款</a-tag
|
||||||
>
|
>
|
||||||
|
<a-tag
|
||||||
|
v-else-if="record.payStatus == 1 && record.payType === 9"
|
||||||
|
color="green"
|
||||||
|
@click.stop="updatePayStatus(record)"
|
||||||
|
class="cursor-pointer"
|
||||||
|
>已确认收款</a-tag
|
||||||
|
>
|
||||||
|
<a-tag
|
||||||
|
v-else-if="record.payStatus == 0 && record.payType === 9"
|
||||||
|
color="orange"
|
||||||
|
@click.stop="updatePayStatus(record)"
|
||||||
|
class="cursor-pointer"
|
||||||
|
>待确认收款</a-tag
|
||||||
|
>
|
||||||
<a-tag
|
<a-tag
|
||||||
v-else-if="record.payStatus == 0 || record.payStatus == null"
|
v-else-if="record.payStatus == 0 || record.payStatus == null"
|
||||||
@click.stop="updatePayStatus(record)"
|
@click.stop="updatePayStatus(record)"
|
||||||
@@ -185,6 +204,10 @@
|
|||||||
<template v-if="record.payType === 8">
|
<template v-if="record.payType === 8">
|
||||||
<a-tag color="blue">货到付款</a-tag>
|
<a-tag color="blue">货到付款</a-tag>
|
||||||
</template>
|
</template>
|
||||||
|
<!-- 线下付款特殊标识 -->
|
||||||
|
<template v-else-if="record.payType === 9">
|
||||||
|
<a-tag color="orange">线下付款</a-tag>
|
||||||
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<template v-for="item in getPayType()">
|
<template v-for="item in getPayType()">
|
||||||
<template v-if="record.payStatus == 1">
|
<template v-if="record.payStatus == 1">
|
||||||
@@ -230,8 +253,8 @@
|
|||||||
<!-- 查看详情 - 所有状态都可以查看 -->
|
<!-- 查看详情 - 所有状态都可以查看 -->
|
||||||
<a @click.stop="openEdit(record)"> <EyeOutlined /> 详情 </a>
|
<a @click.stop="openEdit(record)"> <EyeOutlined /> 详情 </a>
|
||||||
|
|
||||||
<!-- 未付款状态的操作 -->
|
<!-- 未付款状态的操作(排除线下付款) -->
|
||||||
<template v-if="!record.payStatus && record.orderStatus === 0">
|
<template v-if="!record.payStatus && record.orderStatus === 0 && record.payType !== 9">
|
||||||
<a @click.stop="handleEditOrder(record)">
|
<a @click.stop="handleEditOrder(record)">
|
||||||
<EditOutlined /> 修改
|
<EditOutlined /> 修改
|
||||||
</a>
|
</a>
|
||||||
@@ -240,6 +263,16 @@
|
|||||||
</a>
|
</a>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<!-- 线下付款·待确认收款状态的操作 -->
|
||||||
|
<template v-if="!record.payStatus && record.orderStatus === 0 && record.payType === 9">
|
||||||
|
<a @click.stop="handleConfirmOfflinePayment(record)" class="ele-text-success">
|
||||||
|
<CheckCircleOutlined /> 确认收款
|
||||||
|
</a>
|
||||||
|
<a @click.stop="handleCancelOrder(record)">
|
||||||
|
<span class="ele-text-warning"> <CloseOutlined /> 关闭 </span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
|
||||||
<!-- 已付款未发货状态的操作 -->
|
<!-- 已付款未发货状态的操作 -->
|
||||||
<template
|
<template
|
||||||
v-if="
|
v-if="
|
||||||
@@ -371,7 +404,8 @@
|
|||||||
repairOrder,
|
repairOrder,
|
||||||
removeShopOrder,
|
removeShopOrder,
|
||||||
removeBatchShopOrder,
|
removeBatchShopOrder,
|
||||||
updateShopOrder, refundShopOrder
|
updateShopOrder, refundShopOrder,
|
||||||
|
confirmOfflinePayment
|
||||||
} from '@/api/shop/shopOrder';
|
} from '@/api/shop/shopOrder';
|
||||||
import { updateUser } from '@/api/system/user';
|
import { updateUser } from '@/api/system/user';
|
||||||
import { getPayType } from '@/utils/shop';
|
import { getPayType } from '@/utils/shop';
|
||||||
@@ -627,6 +661,35 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 确认线下付款收款
|
||||||
|
const handleConfirmOfflinePayment = (record: ShopOrder) => {
|
||||||
|
let remarksValue = '';
|
||||||
|
Modal.confirm({
|
||||||
|
title: '确认线下收款',
|
||||||
|
content: createVNode('div', null, [
|
||||||
|
createVNode('p', { style: 'margin-bottom: 8px' }, '确认已收到该订单的线下付款(微信转账/银行汇款等)?'),
|
||||||
|
createVNode('p', { style: 'margin-bottom: 8px; color: #999; font-size: 12px' }, `订单号:${record.orderNo}`),
|
||||||
|
createVNode('input', {
|
||||||
|
id: 'offline-remarks-input',
|
||||||
|
placeholder: '可填写备注(如:微信转账已收到)',
|
||||||
|
style: 'width: 100%; padding: 4px 8px; border: 1px solid #d9d9d9; border-radius: 4px;',
|
||||||
|
onInput: (e: any) => { remarksValue = e.target.value; }
|
||||||
|
})
|
||||||
|
]),
|
||||||
|
okText: '确认收款',
|
||||||
|
okType: 'success',
|
||||||
|
onOk: async () => {
|
||||||
|
try {
|
||||||
|
await confirmOfflinePayment(record.orderId!, remarksValue || undefined);
|
||||||
|
message.success('确认收款成功,订单已进入待发货状态');
|
||||||
|
reload();
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message || '确认收款失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// 发货处理
|
// 发货处理
|
||||||
const handleDelivery = (record: ShopOrder) => {
|
const handleDelivery = (record: ShopOrder) => {
|
||||||
current.value = record;
|
current.value = record;
|
||||||
|
|||||||
@@ -17,9 +17,9 @@
|
|||||||
<a-tab-pane tab="分销设置" key="dealer">
|
<a-tab-pane tab="分销设置" key="dealer">
|
||||||
<Dealer />
|
<Dealer />
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane tab="支付设置" key="payment">
|
<!-- <a-tab-pane tab="支付设置" key="payment">-->
|
||||||
<Payment />
|
<!-- <Payment />-->
|
||||||
</a-tab-pane>
|
<!-- </a-tab-pane>-->
|
||||||
<a-tab-pane tab="通知设置" key="notify">
|
<a-tab-pane tab="通知设置" key="notify">
|
||||||
<Notify />
|
<Notify />
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
@@ -43,7 +43,7 @@ import Basic from './components/basic.vue';
|
|||||||
import Order from './components/order.vue';
|
import Order from './components/order.vue';
|
||||||
import Points from './components/points.vue';
|
import Points from './components/points.vue';
|
||||||
import Dealer from './components/dealer.vue';
|
import Dealer from './components/dealer.vue';
|
||||||
import Payment from './components/payment.vue';
|
// import Payment from './components/payment.vue';
|
||||||
import Notify from './components/notify.vue';
|
import Notify from './components/notify.vue';
|
||||||
import Upload from './components/upload.vue';
|
import Upload from './components/upload.vue';
|
||||||
import Sms from './components/sms.vue';
|
import Sms from './components/sms.vue';
|
||||||
|
|||||||
Reference in New Issue
Block a user