新后台
This commit is contained in:
parent
7eb2635fd0
commit
b61e5ebafe
@ -1,39 +1,89 @@
|
|||||||
//响应拦截器
|
//响应拦截器
|
||||||
|
import axios from 'axios'; // 引入axios用于创建新请求
|
||||||
|
|
||||||
export function setupResponseInterceptors(instance) {
|
export function setupResponseInterceptors(instance) {
|
||||||
|
// 用于存储正在刷新token的Promise
|
||||||
|
let isRefreshing = false;
|
||||||
|
// 存储等待token刷新的请求队列
|
||||||
|
let requests = [];
|
||||||
|
|
||||||
instance.interceptors.response.use(
|
instance.interceptors.response.use(
|
||||||
response => {
|
response => {
|
||||||
// 解析 response
|
const { data } = response;
|
||||||
const { data, config } = response;
|
if (data.code != 200) {
|
||||||
|
|
||||||
if(response.data.code != 200){
|
|
||||||
// 创建可追踪的业务逻辑错误
|
|
||||||
const error = new Error(data.message || '业务逻辑错误');
|
const error = new Error(data.message || '业务逻辑错误');
|
||||||
error.name = 'BusinessError'; // 自定义错误类型标识
|
error.name = 'BusinessError';
|
||||||
error.config = config; // 保留请求配置
|
error.data = data;
|
||||||
error.data = data; // 保留响应数据
|
error.code = data.code;
|
||||||
error.code = data.code; // 业务错误码
|
|
||||||
|
|
||||||
//必须 return Promise.reject 才能触发 catch
|
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
// 处理响应数据格式
|
return data;
|
||||||
return data
|
|
||||||
},
|
},
|
||||||
error => {
|
async error => {
|
||||||
// 统一错误处理
|
// 获取原始请求配置
|
||||||
if (error.response) {
|
const originalRequest = error.config;
|
||||||
switch (error.response.status) {
|
|
||||||
case 401:
|
// 判断是否401错误(token过期)且没有在刷新中
|
||||||
// 处理未授权
|
if (error.response?.status === 401 && !originalRequest._retry) {
|
||||||
break
|
// 标记该请求已尝试过重试
|
||||||
case 403:
|
originalRequest._retry = true;
|
||||||
// 处理禁止访问
|
|
||||||
break
|
// 如果当前没有在刷新token
|
||||||
default:
|
if (!isRefreshing) {
|
||||||
console.error('响应错误:', error)
|
isRefreshing = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 从localStorage获取refreshToken
|
||||||
|
const refreshToken = localStorage.getItem('refreshToken');
|
||||||
|
|
||||||
|
if (!refreshToken) {
|
||||||
|
// 无refreshToken,跳转到登录页
|
||||||
|
window.location.href = '/login';
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用刷新token接口
|
||||||
|
const response = await axios.post('/admin/getAccessToken', { refreshToken });
|
||||||
|
|
||||||
|
// 获取新的token
|
||||||
|
const { accessToken, refreshToken: newRefreshToken } = response.data.data;
|
||||||
|
|
||||||
|
// 更新本地存储
|
||||||
|
localStorage.setItem('accessToken', accessToken);
|
||||||
|
if (newRefreshToken) {
|
||||||
|
localStorage.setItem('refreshToken', newRefreshToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新当前请求的Authorization头
|
||||||
|
originalRequest.headers.Authorization = accessToken;
|
||||||
|
|
||||||
|
// 执行队列中的所有请求
|
||||||
|
requests.forEach(cb => cb(accessToken));
|
||||||
|
requests = [];
|
||||||
|
|
||||||
|
// 重新发送之前失败的请求
|
||||||
|
return instance(originalRequest);
|
||||||
|
} catch (refreshError) {
|
||||||
|
// 刷新token失败,清除token并跳转到登录页
|
||||||
|
localStorage.removeItem('accessToken');
|
||||||
|
localStorage.removeItem('refreshToken');
|
||||||
|
window.location.href = '/login';
|
||||||
|
return Promise.reject(refreshError);
|
||||||
|
} finally {
|
||||||
|
isRefreshing = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 如果已经在刷新中,将请求加入队列
|
||||||
|
return new Promise(resolve => {
|
||||||
|
requests.push(token => {
|
||||||
|
originalRequest.headers.Authorization = token;
|
||||||
|
resolve(instance(originalRequest));
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Promise.reject(error)
|
|
||||||
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
44
src/api/modules/order.js
Normal file
44
src/api/modules/order.js
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import request from '@/utils/axios'
|
||||||
|
|
||||||
|
// 获取订单列表
|
||||||
|
export function getOrderList(params) {
|
||||||
|
return request({
|
||||||
|
url: '/wechatOrder/list',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取订单详情
|
||||||
|
export function getOrderDetail(id) {
|
||||||
|
return request({
|
||||||
|
url: `/wechatOrder/${id}`,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增订单
|
||||||
|
export function addOrder(data) {
|
||||||
|
return request({
|
||||||
|
url: '/wechatOrder',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新订单
|
||||||
|
export function updateOrder(data) {
|
||||||
|
return request({
|
||||||
|
url: '/wechatOrder',
|
||||||
|
method: 'put',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除订单
|
||||||
|
export function deleteOrder(id) {
|
||||||
|
return request({
|
||||||
|
url: `/wechatOrder/${id}`,
|
||||||
|
method: 'delete'
|
||||||
|
})
|
||||||
|
}
|
||||||
77
src/api/modules/shop.d.ts
vendored
Normal file
77
src/api/modules/shop.d.ts
vendored
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
// Shop API类型定义
|
||||||
|
export interface ShopParams {
|
||||||
|
pageNum?: number;
|
||||||
|
pageSize?: number;
|
||||||
|
shopType?: string;
|
||||||
|
shopGroup?: string;
|
||||||
|
shopName?: string;
|
||||||
|
shopAliasName?: string;
|
||||||
|
shopAuthorize?: string;
|
||||||
|
status?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ShopData {
|
||||||
|
id: number;
|
||||||
|
mallId?: string;
|
||||||
|
shopNike?: string;
|
||||||
|
shopType: string;
|
||||||
|
shopGroup?: string;
|
||||||
|
shopName: string;
|
||||||
|
shopAliasName: string;
|
||||||
|
shopAuthorize: string;
|
||||||
|
status: string;
|
||||||
|
account?: string;
|
||||||
|
password?: string;
|
||||||
|
isSynOrder: number;
|
||||||
|
addTime?: string;
|
||||||
|
expirationTime?: string;
|
||||||
|
createdBy?: number;
|
||||||
|
createdTime?: number;
|
||||||
|
updatedBy?: number;
|
||||||
|
updatedTime?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ApiResponse<T> {
|
||||||
|
code: number;
|
||||||
|
message: string;
|
||||||
|
data: T;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PageResponse<T> {
|
||||||
|
endRow: number;
|
||||||
|
hasNextPage: boolean;
|
||||||
|
hasPreviousPage: boolean;
|
||||||
|
isFirstPage: boolean;
|
||||||
|
isLastPage: boolean;
|
||||||
|
list: T[];
|
||||||
|
navigateFirstPage: number;
|
||||||
|
navigateLastPage: number;
|
||||||
|
navigatePages: number;
|
||||||
|
navigatepageNums: number[];
|
||||||
|
nextPage: number;
|
||||||
|
pageNum: number;
|
||||||
|
pageSize: number;
|
||||||
|
pages: number;
|
||||||
|
prePage: number;
|
||||||
|
size: number;
|
||||||
|
startRow: number;
|
||||||
|
total: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare function getShopList(params: ShopParams): Promise<{data: ApiResponse<PageResponse<ShopData>>}>;
|
||||||
|
declare function getShopDetail(id: number): Promise<{data: ApiResponse<ShopData>}>;
|
||||||
|
declare function addShop(data: ShopData): Promise<{data: ApiResponse<any>}>;
|
||||||
|
declare function updateShop(data: ShopData): Promise<{data: ApiResponse<any>}>;
|
||||||
|
declare function deleteShop(id: number): Promise<{data: ApiResponse<any>}>;
|
||||||
|
declare function batchDeleteShop(ids: string): Promise<{data: ApiResponse<any>}>;
|
||||||
|
declare function updateSyncOrderStatus(id: number, isSynOrder: number): Promise<{data: ApiResponse<any>}>;
|
||||||
|
|
||||||
|
export {
|
||||||
|
getShopList,
|
||||||
|
getShopDetail,
|
||||||
|
addShop,
|
||||||
|
updateShop,
|
||||||
|
deleteShop,
|
||||||
|
batchDeleteShop,
|
||||||
|
updateSyncOrderStatus
|
||||||
|
};
|
||||||
66
src/api/modules/shop.js
Normal file
66
src/api/modules/shop.js
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import instance from '../../utils/axios.js'
|
||||||
|
|
||||||
|
// 获取店铺列表
|
||||||
|
export const getShopList = async (params = {}) => {
|
||||||
|
// 构造查询参数
|
||||||
|
const queryParams = new URLSearchParams();
|
||||||
|
|
||||||
|
// 添加分页参数
|
||||||
|
if (params.pageNum) queryParams.append('pageNum', params.pageNum);
|
||||||
|
if (params.pageSize) queryParams.append('pageSize', params.pageSize);
|
||||||
|
|
||||||
|
// 添加搜索参数
|
||||||
|
if (params.shopType) queryParams.append('shopType', params.shopType);
|
||||||
|
if (params.shopGroup) queryParams.append('shopGroup', params.shopGroup);
|
||||||
|
if (params.shopName) queryParams.append('shopName', params.shopName);
|
||||||
|
if (params.shopAliasName) queryParams.append('shopAliasName', params.shopAliasName);
|
||||||
|
if (params.shopAuthorize) queryParams.append('shopAuthorize', params.shopAuthorize);
|
||||||
|
if (params.status) queryParams.append('status', params.status);
|
||||||
|
|
||||||
|
const url = `/shop/list?${queryParams.toString()}`;
|
||||||
|
return instance.get(url);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取店铺详情
|
||||||
|
export const getShopDetail = (id) => {
|
||||||
|
return instance.get(`/shop/${id}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 新增店铺
|
||||||
|
export const addShop = (data) => {
|
||||||
|
return instance.post('/shop', data);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 修改店铺
|
||||||
|
export const updateShop = (data) => {
|
||||||
|
return instance.put('/shop', data);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除店铺
|
||||||
|
export const deleteShop = (id) => {
|
||||||
|
return instance.delete(`/shop/${id}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 批量删除店铺
|
||||||
|
export const batchDeleteShop = (ids) => {
|
||||||
|
return instance.delete(`/shop/batch/${ids}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 更新同步订单状态
|
||||||
|
export const updateSyncOrderStatus = (id, isSynOrder) => {
|
||||||
|
return instance.put('/shop/syncOrder', {
|
||||||
|
id,
|
||||||
|
isSynOrder
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 为了向后兼容,也导出整个对象
|
||||||
|
export const shopApi = {
|
||||||
|
getShopList,
|
||||||
|
getShopDetail,
|
||||||
|
addShop,
|
||||||
|
updateShop,
|
||||||
|
deleteShop,
|
||||||
|
batchDeleteShop,
|
||||||
|
updateSyncOrderStatus
|
||||||
|
};
|
||||||
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { shallowRef } from 'vue'
|
import { shallowRef } from 'vue'
|
||||||
import {Document as DocIcon,Setting,User,Message,ShoppingCart } from '@element-plus/icons-vue'
|
import {Document as DocIcon,Setting,User,Message,ShoppingCart,Shop,Connection } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
const menuData = shallowRef([{
|
const menuData = shallowRef([{
|
||||||
title: '系统管理',
|
title: '系统管理',
|
||||||
@ -80,6 +80,19 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '店铺管理',
|
||||||
|
path: '/shop',
|
||||||
|
icon: Shop,
|
||||||
|
children: [{
|
||||||
|
title: '店铺列表',
|
||||||
|
path: '/shop/list',
|
||||||
|
children: [{
|
||||||
|
title: '店铺列表',
|
||||||
|
path: '/shop/list'
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '工具管理',
|
title: '工具管理',
|
||||||
path: '/tools',
|
path: '/tools',
|
||||||
@ -128,20 +141,7 @@
|
|||||||
path: '/useModule/vas/list'
|
path: '/useModule/vas/list'
|
||||||
}]
|
}]
|
||||||
}]
|
}]
|
||||||
},
|
}
|
||||||
{
|
|
||||||
title: '订单管理',
|
|
||||||
path: '/order',
|
|
||||||
icon: ShoppingCart,
|
|
||||||
children: [{
|
|
||||||
title: '微信订单',
|
|
||||||
path: '/order/wechat',
|
|
||||||
children: [{
|
|
||||||
title: '订单列表',
|
|
||||||
path: '/order/wechat/list'
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
// 更多菜单...
|
// 更多菜单...
|
||||||
])
|
])
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -33,6 +33,11 @@ const routes = [{
|
|||||||
component: () => import('@/views/User/Edit.vue'),
|
component: () => import('@/views/User/Edit.vue'),
|
||||||
meta: { title: '新增用户' }
|
meta: { title: '新增用户' }
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/shop/list',
|
||||||
|
component: () => import('@/views/Shop/index.vue'),
|
||||||
|
meta: { title: '店铺列表' }
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/tools/cards/list',
|
path: '/tools/cards/list',
|
||||||
component: () => import('@/views/Tools/Cards/List.vue'),
|
component: () => import('@/views/Tools/Cards/List.vue'),
|
||||||
@ -62,6 +67,11 @@ const routes = [{
|
|||||||
path: '/order/wechat/list',
|
path: '/order/wechat/list',
|
||||||
component: () => import('@/views/order/wechat/list.vue'),
|
component: () => import('@/views/order/wechat/list.vue'),
|
||||||
meta: { title: '订单列表' }
|
meta: { title: '订单列表' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/websocket/demo',
|
||||||
|
component: () => import('@/views/websocket/index.vue'),
|
||||||
|
meta: { title: 'WebSocket演示' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
|
|||||||
57
src/utils/request.js
Normal file
57
src/utils/request.js
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
* 外部API请求工具
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 检查字符串是否为URL
|
||||||
|
const isValidUrl = (string) => {
|
||||||
|
try {
|
||||||
|
new URL(string);
|
||||||
|
return true;
|
||||||
|
} catch (_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 发送GET请求到外部API
|
||||||
|
export const fetchExternalApi = async (url) => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(url, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Accept': '*/*',
|
||||||
|
},
|
||||||
|
// 禁用缓存
|
||||||
|
cache: 'no-cache',
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP error! Status: ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 先尝试获取文本响应
|
||||||
|
const text = await response.text();
|
||||||
|
|
||||||
|
// 如果文本是URL,直接返回
|
||||||
|
if (isValidUrl(text)) {
|
||||||
|
console.log('直接返回URL:', text);
|
||||||
|
return { url: text.trim() };
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尝试解析为JSON
|
||||||
|
try {
|
||||||
|
const jsonData = JSON.parse(text);
|
||||||
|
return jsonData;
|
||||||
|
} catch (jsonError) {
|
||||||
|
// 如果不是JSON,则作为文本返回
|
||||||
|
return { text };
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('外部API请求失败:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
fetchExternalApi,
|
||||||
|
isValidUrl
|
||||||
|
};
|
||||||
@ -592,39 +592,66 @@
|
|||||||
<el-table-column type="selection" align="center" width="55" />
|
<el-table-column type="selection" align="center" width="55" />
|
||||||
<el-table-column prop="title" align="center" label="标题" width="120" />
|
<el-table-column prop="title" align="center" label="标题" width="120" />
|
||||||
<el-table-column prop="settled_cost_key" align="center" label="入驻标识" width="180" />
|
<el-table-column prop="settled_cost_key" align="center" label="入驻标识" width="180" />
|
||||||
<el-table-column prop="kickback_type" align="center" label="佣金类型" width="100">
|
<!-- 小程序收费佣金 -->
|
||||||
<template #default="{ row }">{{ formatKickbackType(row.kickback_type) }}</template>
|
<el-table-column align="center" label="小程序佣金" width="180">
|
||||||
</el-table-column>
|
|
||||||
<el-table-column align="center" label="佣金值" width="180">
|
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
|
<div v-if="parseConstraint(row.constraint_json) && parseConstraint(row.constraint_json).miniapp">
|
||||||
<div>
|
<div>
|
||||||
<div v-if="[1, 3].includes(row.kickback_type)">
|
类型: {{ formatKickbackType(parseConstraint(row.constraint_json).miniapp.kickback_type || 0) }}
|
||||||
提点: {{ parseKickbackValue(row.kickback_value, 'point') }}%
|
|
||||||
</div>
|
</div>
|
||||||
<div v-if="[2, 3].includes(row.kickback_type)">
|
<div v-if="[1, 3].includes(parseConstraint(row.constraint_json).miniapp.kickback_type || 0)">
|
||||||
固定费用: {{ parseKickbackValue(row.kickback_value, 'fixed') }}元
|
提点: {{ parseKickbackValueJson(parseConstraint(row.constraint_json).miniapp.kickback_value || '{}', 'point') }}%
|
||||||
</div>
|
</div>
|
||||||
<div v-if="![1, 2, 3].includes(row.kickback_type)">
|
<div v-if="[2, 3].includes(parseConstraint(row.constraint_json).miniapp.kickback_type || 0)">
|
||||||
{{ row.kickback_value }}
|
固费: {{ parseKickbackValueJson(parseConstraint(row.constraint_json).miniapp.kickback_value || '{}', 'fixed') }}元
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<span v-else>-</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="resource_cost_type" align="center" label="资源费类型" width="120">
|
|
||||||
|
<el-table-column label="操作" align="center" fixed="right">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
{{ formatResourceCostType(row.resource_cost_type) }}
|
<el-button-group>
|
||||||
|
<el-button type="primary" size="small" @click="handleEdit(row)">编辑</el-button>
|
||||||
|
<el-button type="danger" size="small" @click="handleDelete(row)" :disabled="row.is_del === 1">
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</el-button-group>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column align="center" label="资源费值/服务费率" width="180">
|
<!-- 孔夫子店铺佣金 -->
|
||||||
|
<el-table-column align="center" label="孔夫子佣金" width="180">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
|
<div v-if="parseConstraint(row.constraint_json) && parseConstraint(row.constraint_json).kongfz">
|
||||||
<div>
|
<div>
|
||||||
<div v-if="[1, 3].includes(row.resource_cost_type)">
|
类型: {{ formatKickbackType(parseConstraint(row.constraint_json).kongfz.kickback_type || 0) }}
|
||||||
服务费率: {{ row.service_rate }}%
|
|
||||||
</div>
|
</div>
|
||||||
<div v-if="[2, 3].includes(row.resource_cost_type)">
|
<div v-if="[1, 3].includes(parseConstraint(row.constraint_json).kongfz.kickback_type || 0)">
|
||||||
资源费值: {{ row.resource_cost_value }}元
|
提点: {{ parseKickbackValueJson(parseConstraint(row.constraint_json).kongfz.kickback_value || '{}', 'point') }}%
|
||||||
|
</div>
|
||||||
|
<div v-if="[2, 3].includes(parseConstraint(row.constraint_json).kongfz.kickback_type || 0)">
|
||||||
|
固费: {{ parseKickbackValueJson(parseConstraint(row.constraint_json).kongfz.kickback_value || '{}', 'fixed') }}元
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<span v-else>-</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<!-- 资源费分级佣金 -->
|
||||||
|
<el-table-column align="center" label="资源费佣金" width="180">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<div v-if="parseConstraint(row.constraint_json) && parseConstraint(row.constraint_json).resource_tier">
|
||||||
|
<div>
|
||||||
|
类型: {{ formatKickbackType(parseConstraint(row.constraint_json).resource_tier.kickback_type || 0) }}
|
||||||
|
</div>
|
||||||
|
<div v-if="[1, 3].includes(parseConstraint(row.constraint_json).resource_tier.kickback_type || 0)">
|
||||||
|
提点: {{ parseKickbackValueJson(parseConstraint(row.constraint_json).resource_tier.kickback_value || '{}', 'point') }}%
|
||||||
|
</div>
|
||||||
|
<div v-if="[2, 3].includes(parseConstraint(row.constraint_json).resource_tier.kickback_type || 0)">
|
||||||
|
固费: {{ parseKickbackValueJson(parseConstraint(row.constraint_json).resource_tier.kickback_value || '{}', 'fixed') }}元
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span v-else>-</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="price" align="center" label="价格(元)" width="120" />
|
<el-table-column prop="price" align="center" label="价格(元)" width="120" />
|
||||||
@ -639,16 +666,6 @@
|
|||||||
{{ row.is_del === 0 ? '正常' : '已删除' }}
|
{{ row.is_del === 0 ? '正常' : '已删除' }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" align="center" fixed="right">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<el-button-group>
|
|
||||||
<el-button type="primary" size="small" @click="handleEdit(row)">编辑</el-button>
|
|
||||||
<el-button type="danger" size="small" @click="handleDelete(row)" :disabled="row.is_del === 1">
|
|
||||||
删除
|
|
||||||
</el-button>
|
|
||||||
</el-button-group>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
@ -679,6 +696,11 @@
|
|||||||
<el-form-item label="入驻标识" prop="settled_cost_key">
|
<el-form-item label="入驻标识" prop="settled_cost_key">
|
||||||
<el-input v-model="formData.settled_cost_key" placeholder="请输入入驻标识" :disabled="dialogType === 'edit'" />
|
<el-input v-model="formData.settled_cost_key" placeholder="请输入入驻标识" :disabled="dialogType === 'edit'" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="会员类型" prop="member_type">
|
||||||
|
<el-select v-model="formData.member_type" placeholder="请选择会员类型" clearable>
|
||||||
|
<el-option label="小程序" :value="1" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="最小本数" prop="books_count_min">
|
<el-form-item label="最小本数" prop="books_count_min">
|
||||||
<el-input-number v-model="formData.books_count_min" :min="0" :precision="0" placeholder="请输入最小本数" />
|
<el-input-number v-model="formData.books_count_min" :min="0" :precision="0" placeholder="请输入最小本数" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -1660,6 +1682,7 @@ const formData = reactive({
|
|||||||
constraint_json: '',
|
constraint_json: '',
|
||||||
books_count_min: 0,
|
books_count_min: 0,
|
||||||
books_count_max: 0,
|
books_count_max: 0,
|
||||||
|
member_type: 1, // 添加会员类型,默认为1(小程序)
|
||||||
kickback_type: 0,
|
kickback_type: 0,
|
||||||
kickback_value: '',
|
kickback_value: '',
|
||||||
kickback_point: 0,
|
kickback_point: 0,
|
||||||
@ -1887,6 +1910,7 @@ const resetFormData = () => {
|
|||||||
constraint_json: '',
|
constraint_json: '',
|
||||||
books_count_min: 0,
|
books_count_min: 0,
|
||||||
books_count_max: 0,
|
books_count_max: 0,
|
||||||
|
member_type: 1, // 添加会员类型,默认为1(小程序)
|
||||||
kickback_type: 0,
|
kickback_type: 0,
|
||||||
kickback_value: '',
|
kickback_value: '',
|
||||||
kickback_point: 0,
|
kickback_point: 0,
|
||||||
@ -2202,6 +2226,7 @@ const handleEdit = (row: TableItem) => {
|
|||||||
id: row.id,
|
id: row.id,
|
||||||
title: row.title,
|
title: row.title,
|
||||||
settled_cost_key: row.settled_cost_key,
|
settled_cost_key: row.settled_cost_key,
|
||||||
|
member_type: constraintData.member_type || 1, // 设置会员类型,默认为1(小程序)
|
||||||
constraint_json: constraintData,
|
constraint_json: constraintData,
|
||||||
books_count_min: min,
|
books_count_min: min,
|
||||||
books_count_max: max,
|
books_count_max: max,
|
||||||
@ -2235,6 +2260,7 @@ const handleSubmit = async () => {
|
|||||||
const constraintObj = {
|
const constraintObj = {
|
||||||
books_count_min: formData.books_count_min,
|
books_count_min: formData.books_count_min,
|
||||||
books_count_max: formData.books_count_max,
|
books_count_max: formData.books_count_max,
|
||||||
|
member_type: formData.member_type, // 添加会员类型
|
||||||
|
|
||||||
// 小程序收费
|
// 小程序收费
|
||||||
miniapp: {
|
miniapp: {
|
||||||
|
|||||||
608
src/views/Shop/index.vue
Normal file
608
src/views/Shop/index.vue
Normal file
@ -0,0 +1,608 @@
|
|||||||
|
<template>
|
||||||
|
<div class="list-container">
|
||||||
|
<div class="search-area">
|
||||||
|
<el-form :model="queryParams" inline>
|
||||||
|
<el-form-item label="店铺类型">
|
||||||
|
<el-select v-model="queryParams.shopType" placeholder="请选择店铺类型" clearable>
|
||||||
|
<el-option label="拼多多" value="1" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="分组">
|
||||||
|
<el-input v-model="queryParams.shopGroup" placeholder="请输入分组" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="店铺名称">
|
||||||
|
<el-input v-model="queryParams.shopName" placeholder="请输入店铺名称" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="三方名称">
|
||||||
|
<el-input v-model="queryParams.shopAliasName" placeholder="请输入三方名称" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="是否授权">
|
||||||
|
<el-select v-model="queryParams.shopAuthorize" placeholder="请选择是否授权" clearable>
|
||||||
|
<el-option label="已授权" value="1" />
|
||||||
|
<el-option label="未授权" value="0" />
|
||||||
|
<el-option label="已过期" value="2" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="店铺状态">
|
||||||
|
<el-select v-model="queryParams.status" placeholder="请选择店铺状态" clearable>
|
||||||
|
<el-option label="正常" value="0" />
|
||||||
|
<el-option label="停用" value="1" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="handleSearch">搜索</el-button>
|
||||||
|
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="action-bar">
|
||||||
|
<div class="action-left">
|
||||||
|
<el-button type="primary" @click="handleAdd">新增</el-button>
|
||||||
|
<el-button type="primary" @click="handleEdit">编辑</el-button>
|
||||||
|
<el-button type="danger" @click="handleDelete">删除</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="action-right">
|
||||||
|
<RefreshButton @refresh="getShopListData" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-table
|
||||||
|
v-loading="loading"
|
||||||
|
:data="shopList"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
border
|
||||||
|
stripe
|
||||||
|
style="width: 100%"
|
||||||
|
row-key="id"
|
||||||
|
>
|
||||||
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
|
<el-table-column label="店铺编码" prop="id" align="center" />
|
||||||
|
<el-table-column label="店铺类型" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.shopType === '1' ? '拼多多' : '-' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="分组" prop="shopGroup" align="center" />
|
||||||
|
<el-table-column label="店铺名称" prop="shopName" align="center" />
|
||||||
|
<el-table-column label="三方名称" prop="shopAliasName" align="center" />
|
||||||
|
<el-table-column label="是否授权" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag :type="getAuthorizeTagType(scope.row.shopAuthorize)" v-if="scope.row.shopAuthorize === '1'">
|
||||||
|
{{ getAuthorizeText(scope.row.shopAuthorize) }}
|
||||||
|
</el-tag>
|
||||||
|
<el-button
|
||||||
|
v-else
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
@click="handleAuthorize(scope.row)"
|
||||||
|
>
|
||||||
|
授权
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="到期时间" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.expirationTime }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="添加时间" prop="addTime" align="center" />
|
||||||
|
<el-table-column label="店铺状态" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag :type="scope.row.status === '0' ? 'success' : 'danger'">
|
||||||
|
{{ scope.row.status === '0' ? '正常' : '停用' }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="同步订单" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-switch
|
||||||
|
v-model="scope.row.isSynOrder"
|
||||||
|
:active-value="1"
|
||||||
|
:inactive-value="0"
|
||||||
|
class="ml-2"
|
||||||
|
inline-prompt
|
||||||
|
active-text="开"
|
||||||
|
inactive-text="关"
|
||||||
|
@change="handleSyncOrderChange(scope.row)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="设置" align="center" width="60">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button type="primary" icon="Setting" circle plain size="small" @click="handleSetting(scope.row)" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" width="220" fixed="right">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button size="small" type="primary" @click="handleEdit(scope.row)">编辑</el-button>
|
||||||
|
<el-button size="small" type="danger" @click="handleDelete(scope.row)">删除</el-button>
|
||||||
|
<el-button
|
||||||
|
v-if="scope.row.status === '0'"
|
||||||
|
size="small"
|
||||||
|
type="warning"
|
||||||
|
@click="handleChangeStatus(scope.row, '1')"
|
||||||
|
>停用</el-button>
|
||||||
|
<el-button
|
||||||
|
v-if="scope.row.status === '1'"
|
||||||
|
size="small"
|
||||||
|
type="success"
|
||||||
|
@click="handleChangeStatus(scope.row, '0')"
|
||||||
|
>启用</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<div class="pagination-container">
|
||||||
|
<el-pagination
|
||||||
|
v-model:current-page="queryParams.pageNum"
|
||||||
|
v-model:page-size="queryParams.pageSize"
|
||||||
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="total"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 添加/编辑对话框 -->
|
||||||
|
<el-dialog
|
||||||
|
:title="dialog.title"
|
||||||
|
v-model="dialog.visible"
|
||||||
|
width="600px"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
append-to-body
|
||||||
|
>
|
||||||
|
<el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
|
||||||
|
<el-form-item label="店铺类型" prop="shopType">
|
||||||
|
<el-select v-model="form.shopType" placeholder="请选择店铺类型" style="width: 100%">
|
||||||
|
<el-option label="拼多多" value="1" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="分组" prop="shopGroup">
|
||||||
|
<el-input v-model="form.shopGroup" placeholder="请输入分组" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="店铺名称" prop="shopName">
|
||||||
|
<el-input v-model="form.shopName" placeholder="请输入店铺名称" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="三方名称" prop="shopAliasName">
|
||||||
|
<el-input v-model="form.shopAliasName" placeholder="请输入三方名称" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="店铺ID" prop="mallId">
|
||||||
|
<el-input v-model="form.mallId" placeholder="请输入三方店铺ID" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="万里牛ID" prop="shopNike">
|
||||||
|
<el-input v-model="form.shopNike" placeholder="请输入万里牛系统ID" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="第三方账号" prop="account">
|
||||||
|
<el-input v-model="form.account" placeholder="请输入第三方平台账号" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="第三方密码" prop="password">
|
||||||
|
<el-input v-model="form.password" type="password" placeholder="请输入第三方平台密码" show-password />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="同步订单" prop="isSynOrder">
|
||||||
|
<el-switch
|
||||||
|
v-model="form.isSynOrder"
|
||||||
|
:active-value="1"
|
||||||
|
:inactive-value="0"
|
||||||
|
inline-prompt
|
||||||
|
active-text="开"
|
||||||
|
inactive-text="关"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="店铺状态" prop="status">
|
||||||
|
<el-radio-group v-model="form.status">
|
||||||
|
<el-radio label="0">正常</el-radio>
|
||||||
|
<el-radio label="1">停用</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="dialog.visible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="submitForm">确定</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
// import { shopApi } from '@/api'
|
||||||
|
import {
|
||||||
|
getShopList,
|
||||||
|
getShopDetail,
|
||||||
|
addShop,
|
||||||
|
updateShop,
|
||||||
|
deleteShop,
|
||||||
|
batchDeleteShop,
|
||||||
|
updateSyncOrderStatus
|
||||||
|
} from '@/api/modules/shop'
|
||||||
|
import { fetchExternalApi } from '@/utils/request'
|
||||||
|
import RefreshButton from '@/components/RefreshButton.vue'
|
||||||
|
|
||||||
|
// 查询参数
|
||||||
|
const queryParams = reactive({
|
||||||
|
shopType: '',
|
||||||
|
shopGroup: '',
|
||||||
|
shopName: '',
|
||||||
|
shopAliasName: '',
|
||||||
|
shopAuthorize: '',
|
||||||
|
status: '',
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 20
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表格数据
|
||||||
|
const loading = ref(false)
|
||||||
|
const shopList = ref([])
|
||||||
|
const total = ref(0)
|
||||||
|
const selectedRows = ref<any[]>([])
|
||||||
|
|
||||||
|
// 对话框相关
|
||||||
|
const dialog = reactive({
|
||||||
|
visible: false,
|
||||||
|
title: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表单对象
|
||||||
|
const formRef = ref()
|
||||||
|
const form = reactive({
|
||||||
|
id: undefined,
|
||||||
|
mallId: '',
|
||||||
|
shopNike: '',
|
||||||
|
shopType: '1',
|
||||||
|
shopGroup: '',
|
||||||
|
shopName: '',
|
||||||
|
shopAliasName: '',
|
||||||
|
shopAuthorize: '0',
|
||||||
|
status: '0',
|
||||||
|
account: '',
|
||||||
|
password: '',
|
||||||
|
isSynOrder: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表单验证规则
|
||||||
|
const rules = {
|
||||||
|
shopType: [{ required: true, message: '请选择店铺类型', trigger: 'change' }],
|
||||||
|
shopName: [{ required: true, message: '请输入店铺名称', trigger: 'blur' }],
|
||||||
|
shopAliasName: [{ required: true, message: '请输入三方名称', trigger: 'blur' }]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化方法
|
||||||
|
onMounted(() => {
|
||||||
|
getShopListData()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取授权状态标签类型
|
||||||
|
const getAuthorizeTagType = (authorize: string) => {
|
||||||
|
switch (authorize) {
|
||||||
|
case '1': return 'success'
|
||||||
|
case '0': return 'info'
|
||||||
|
case '2': return 'warning'
|
||||||
|
default: return 'info'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取授权状态文本
|
||||||
|
const getAuthorizeText = (authorize: string) => {
|
||||||
|
switch (authorize) {
|
||||||
|
case '1': return '已授权'
|
||||||
|
case '0': return '未授权'
|
||||||
|
case '2': return '已过期'
|
||||||
|
default: return '未知'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取店铺列表
|
||||||
|
const getShopListData = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const res = await getShopList(queryParams)
|
||||||
|
console.log("res", res)
|
||||||
|
if (res.code === 200) {
|
||||||
|
shopList.value = res.data.list
|
||||||
|
total.value = res.data.total
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res.message || '获取数据失败')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('获取店铺列表失败')
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 搜索按钮操作
|
||||||
|
const handleSearch = () => {
|
||||||
|
queryParams.pageNum = 1
|
||||||
|
getShopListData()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置按钮操作
|
||||||
|
const handleReset = () => {
|
||||||
|
queryParams.shopType = ''
|
||||||
|
queryParams.shopGroup = ''
|
||||||
|
queryParams.shopName = ''
|
||||||
|
queryParams.shopAliasName = ''
|
||||||
|
queryParams.shopAuthorize = ''
|
||||||
|
queryParams.status = ''
|
||||||
|
queryParams.pageNum = 1
|
||||||
|
getShopListData()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页相关操作
|
||||||
|
const handleSizeChange = (val: number) => {
|
||||||
|
queryParams.pageSize = val
|
||||||
|
getShopListData()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCurrentChange = (val: number) => {
|
||||||
|
queryParams.pageNum = val
|
||||||
|
getShopListData()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选择行事件
|
||||||
|
const handleSelectionChange = (selection) => {
|
||||||
|
selectedRows.value = selection
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开添加对话框
|
||||||
|
const handleAdd = () => {
|
||||||
|
dialog.title = '添加店铺'
|
||||||
|
dialog.visible = true
|
||||||
|
form.id = undefined
|
||||||
|
form.mallId = ''
|
||||||
|
form.shopNike = ''
|
||||||
|
form.shopType = '1'
|
||||||
|
form.shopGroup = ''
|
||||||
|
form.shopName = ''
|
||||||
|
form.shopAliasName = ''
|
||||||
|
form.shopAuthorize = '0'
|
||||||
|
form.status = '0'
|
||||||
|
form.account = ''
|
||||||
|
form.password = ''
|
||||||
|
form.isSynOrder = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改按钮操作
|
||||||
|
const handleEdit = (row) => {
|
||||||
|
dialog.title = '编辑店铺'
|
||||||
|
dialog.visible = true
|
||||||
|
|
||||||
|
if (row) {
|
||||||
|
// 如果传递了行数据,则编辑该行
|
||||||
|
const shopId = row.id
|
||||||
|
if (shopId) {
|
||||||
|
getShopDetail(shopId).then(res => {
|
||||||
|
if (res.data.code === 200) {
|
||||||
|
Object.assign(form, res.data.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 否则检查是否有选中行
|
||||||
|
if (selectedRows.value.length !== 1) {
|
||||||
|
ElMessage.warning('请选择一条记录进行修改')
|
||||||
|
dialog.visible = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const shopId = selectedRows.value[0].id
|
||||||
|
if (shopId) {
|
||||||
|
getShopDetail(shopId).then(res => {
|
||||||
|
if (res.data.code === 200) {
|
||||||
|
Object.assign(form, res.data.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除按钮操作
|
||||||
|
const handleDelete = (row) => {
|
||||||
|
if (row) {
|
||||||
|
// 删除单条记录
|
||||||
|
ElMessageBox.confirm('确认删除该店铺记录吗?', '警告', {
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
if (row.id) {
|
||||||
|
deleteShop(row.id).then(res => {
|
||||||
|
if (res.data.code === 200) {
|
||||||
|
ElMessage.success('删除成功')
|
||||||
|
getShopListData()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}).catch(() => {})
|
||||||
|
} else {
|
||||||
|
// 批量删除
|
||||||
|
if (selectedRows.value.length === 0) {
|
||||||
|
ElMessage.warning('请至少选择一条记录')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ElMessageBox.confirm(`确认删除选中的${selectedRows.value.length}条店铺记录吗?`, '警告', {
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
const ids = selectedRows.value.map(item => item.id).filter(id => id !== undefined)
|
||||||
|
if (ids.length > 0) {
|
||||||
|
batchDeleteShop(ids.join(',')).then(res => {
|
||||||
|
if (res.data.code === 200) {
|
||||||
|
ElMessage.success('批量删除成功')
|
||||||
|
getShopListData()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}).catch(() => {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置按钮操作
|
||||||
|
const handleSetting = (row) => {
|
||||||
|
ElMessage.info(`设置店铺: ${row.shopName}`)
|
||||||
|
// 实现店铺设置功能
|
||||||
|
}
|
||||||
|
|
||||||
|
// 同步订单状态变更
|
||||||
|
const handleSyncOrderChange = (row) => {
|
||||||
|
const status = row.isSynOrder === 1 ? '开启' : '关闭'
|
||||||
|
if (row.id) {
|
||||||
|
updateSyncOrderStatus(row.id, row.isSynOrder).then(res => {
|
||||||
|
if (res.data.code === 200) {
|
||||||
|
ElMessage.success(`${status}同步订单成功`)
|
||||||
|
} else {
|
||||||
|
ElMessage.error(`${status}同步订单失败`)
|
||||||
|
// 恢复原状态
|
||||||
|
row.isSynOrder = row.isSynOrder === 1 ? 0 : 1
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
// 恢复原状态
|
||||||
|
row.isSynOrder = row.isSynOrder === 1 ? 0 : 1
|
||||||
|
ElMessage.error(`${status}同步订单失败`)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理授权操作
|
||||||
|
const handleAuthorize = async (row) => {
|
||||||
|
try {
|
||||||
|
// 显示加载提示
|
||||||
|
ElMessage.info('正在获取授权链接,请稍候...');
|
||||||
|
|
||||||
|
// 调用API获取授权链接
|
||||||
|
const apiUrl = `https://api.buzhiyushu.cn/huidiao/pdd/toPddGetCode?id=${row.id}&type=4`;
|
||||||
|
const result = await fetchExternalApi(apiUrl);
|
||||||
|
|
||||||
|
// 处理不同类型的响应
|
||||||
|
let authUrl = null;
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
if (result.url) {
|
||||||
|
// 如果响应中直接包含url字段
|
||||||
|
authUrl = result.url;
|
||||||
|
} else if (typeof result === 'string' && result.includes('http')) {
|
||||||
|
// 如果响应直接是URL字符串
|
||||||
|
authUrl = result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (authUrl) {
|
||||||
|
console.log('授权URL:', authUrl);
|
||||||
|
|
||||||
|
// 打开新窗口进行授权
|
||||||
|
const newTab = window.open(authUrl, '_blank');
|
||||||
|
|
||||||
|
// 如果无法打开新窗口,则尝试直接跳转
|
||||||
|
if (!newTab || newTab.closed || typeof newTab.closed === 'undefined') {
|
||||||
|
window.location.href = authUrl;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('无法解析授权链接:', result);
|
||||||
|
ElMessage.error('获取授权链接失败');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('授权请求失败:', error);
|
||||||
|
ElMessage.error('授权请求失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理状态变更
|
||||||
|
const handleChangeStatus = async (row, newStatus) => {
|
||||||
|
const statusText = newStatus === '0' ? '启用' : '停用';
|
||||||
|
|
||||||
|
ElMessageBox.confirm(`确认要${statusText}该店铺吗?`, '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(async () => {
|
||||||
|
try {
|
||||||
|
// 更新状态的API调用
|
||||||
|
const updatedData = { ...row, status: newStatus };
|
||||||
|
await updateShop(updatedData);
|
||||||
|
ElMessage.success(`${statusText}成功`);
|
||||||
|
getShopListData(); // 刷新数据
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`${statusText}失败:`, error);
|
||||||
|
ElMessage.error(`${statusText}失败`);
|
||||||
|
}
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交表单
|
||||||
|
const submitForm = () => {
|
||||||
|
formRef.value.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
if (form.id) {
|
||||||
|
// 编辑
|
||||||
|
updateShop(form).then(res => {
|
||||||
|
if (res.data.code === 200) {
|
||||||
|
ElMessage.success('修改成功')
|
||||||
|
dialog.visible = false
|
||||||
|
getShopListData()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 新增
|
||||||
|
addShop(form).then(res => {
|
||||||
|
if (res.data.code === 200) {
|
||||||
|
ElMessage.success('新增成功')
|
||||||
|
dialog.visible = false
|
||||||
|
getShopListData()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.list-container {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-area {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding: 18px;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-area :deep(.el-form-item) {
|
||||||
|
margin-right: 18px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-bar {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-left {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-right {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-container {
|
||||||
|
margin-top: 20px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -46,7 +46,7 @@ export default defineConfig({
|
|||||||
proxy: {
|
proxy: {
|
||||||
'/api': {
|
'/api': {
|
||||||
target: 'http://127.0.0.1:8089',
|
target: 'http://127.0.0.1:8089',
|
||||||
// target: 'http://146.56.227.42',
|
// target: 'http://146.56.227.42:8089',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: (path) => path.replace(/^\/api/,''),
|
rewrite: (path) => path.replace(/^\/api/,''),
|
||||||
// 如需处理WebSocket
|
// 如需处理WebSocket
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user