F006 W3.xC + W5.x.x+1/3/4/5 + W6 + W7 完整批次 (17 commits) #1
@ -216,91 +216,6 @@ const mailLogMock = [
|
||||
{ id: '5', toEmail: 'qianqi@example.com', subject: '您有新的报价', templateName: '询价报价', status: 1, errorMsg: '', createDate: now(2) }
|
||||
]
|
||||
|
||||
// ========== order ==========
|
||||
const orderStatusMap = { '0': { label: '待付款', type: 'warning' as const }, '1': { label: '已付款', type: 'primary' as const }, '2': { label: '已发货', type: 'success' as const }, '3': { label: '已收货', type: 'success' as const }, '4': { label: '已取消', type: 'info' as const }, '5': { label: '退款中', type: 'danger' as const } }
|
||||
const afterSaleStatusMap = { '0': { label: '待审核', type: 'warning' as const }, '1': { label: '已通过', type: 'success' as const }, '2': { label: '已拒绝', type: 'danger' as const }, '3': { label: '已退款', type: 'info' as const } }
|
||||
|
||||
const orderCommonCols: MockColumn[] = [
|
||||
{ prop: 'id', label: '订单号', minWidth: 180 },
|
||||
{ prop: 'userName', label: '用户', width: 120 },
|
||||
{ prop: 'goodsName', label: '商品', minWidth: 180 },
|
||||
{ prop: 'quantity', label: '数量', width: 80, align: 'right' },
|
||||
{ prop: 'amount', label: '金额', width: 120, align: 'right' },
|
||||
{ prop: 'status', label: '状态', width: 100, type: 'status' },
|
||||
{ prop: 'createDate', label: '下单时间', width: 180, type: 'text' }
|
||||
]
|
||||
const orderGoodMock = [
|
||||
{ id: 'O20260705001', userName: '张三', goodsName: '工业传感器 X100', quantity: 5, amount: 12500.00, status: 2, createDate: now(0) },
|
||||
{ id: 'O20260705002', userName: '李四', goodsName: '智能控制器 Y200', quantity: 2, amount: 8000.00, status: 1, createDate: now(0) },
|
||||
{ id: 'O20260705003', userName: '王五', goodsName: '高精度测量仪', quantity: 1, amount: 15800.00, status: 3, createDate: now(1) },
|
||||
{ id: 'O20260705004', userName: '赵六', goodsName: '工业机器人臂', quantity: 1, amount: 89000.00, status: 0, createDate: now(1) },
|
||||
{ id: 'O20260705005', userName: '钱七', goodsName: '自动化装配线', quantity: 1, amount: 250000.00, status: 1, createDate: now(2) },
|
||||
{ id: 'O20260705006', userName: '孙八', goodsName: '工业相机', quantity: 10, amount: 45000.00, status: 2, createDate: now(2) },
|
||||
{ id: 'O20260705007', userName: '周九', goodsName: 'PLC 控制系统', quantity: 3, amount: 56000.00, status: 3, createDate: now(3) },
|
||||
{ id: 'O20260705008', userName: '吴十', goodsName: '机器视觉系统', quantity: 1, amount: 120000.00, status: 4, createDate: now(3) }
|
||||
]
|
||||
const serviceOrderMock = [
|
||||
{ id: 'S20260705001', userName: '深圳科技公司', goodsName: '设备维护服务', quantity: 1, amount: 5800.00, status: 1, createDate: now(0) },
|
||||
{ id: 'S20260705002', userName: '上海制造企业', goodsName: '技术咨询服务', quantity: 3, amount: 12000.00, status: 2, createDate: now(0) },
|
||||
{ id: 'S20260705003', userName: '北京集团', goodsName: '设备租赁服务', quantity: 5, amount: 35000.00, status: 3, createDate: now(1) },
|
||||
{ id: 'S20260705004', userName: '广州工厂', goodsName: '系统集成服务', quantity: 1, amount: 80000.00, status: 1, createDate: now(2) },
|
||||
{ id: 'S20260705005', userName: '杭州电子', goodsName: '培训服务', quantity: 1, amount: 15000.00, status: 0, createDate: now(3) }
|
||||
]
|
||||
const groupSupplierMock = [
|
||||
{ id: 'G20260705001', userName: '拼团订单A', goodsName: '工业传感器 X100', quantity: 20, amount: 48000.00, status: 1, createDate: now(0) },
|
||||
{ id: 'G20260705002', userName: '拼团订单B', goodsName: '智能控制器 Y200', quantity: 15, amount: 54000.00, status: 2, createDate: now(1) },
|
||||
{ id: 'G20260705003', userName: '拼团订单C', goodsName: '高精度测量仪', quantity: 8, amount: 120000.00, status: 0, createDate: now(2) }
|
||||
]
|
||||
const groupServiceMock = [
|
||||
{ id: 'GS20260705001', userName: '服务拼团A', goodsName: '年度维护套餐', quantity: 50, amount: 98000.00, status: 1, createDate: now(0) },
|
||||
{ id: 'GS20260705002', userName: '服务拼团B', goodsName: '技术培训套餐', quantity: 30, amount: 45000.00, status: 2, createDate: now(1) }
|
||||
]
|
||||
const orderAfterMock = [
|
||||
{ id: 'A20260705001', userName: '张三', goodsName: '工业传感器 X100', quantity: 1, amount: 2500.00, status: 0, createDate: now(0) },
|
||||
{ id: 'A20260705002', userName: '李四', goodsName: '智能控制器 Y200', quantity: 1, amount: 4000.00, status: 1, createDate: now(1) },
|
||||
{ id: 'A20260705003', userName: '王五', goodsName: '高精度测量仪', quantity: 1, amount: 15800.00, status: 2, createDate: now(2) },
|
||||
{ id: 'A20260705004', userName: '赵六', goodsName: '工业相机', quantity: 2, amount: 9000.00, status: 3, createDate: now(3) }
|
||||
]
|
||||
const orderServiceAfterMock = [
|
||||
{ id: 'SA20260705001', userName: '深圳科技公司', goodsName: '设备维护服务', quantity: 1, amount: 5800.00, status: 0, createDate: now(0) },
|
||||
{ id: 'SA20260705002', userName: '上海制造企业', goodsName: '技术咨询服务', quantity: 1, amount: 4000.00, status: 1, createDate: now(2) }
|
||||
]
|
||||
const orderCommissionCols: MockColumn[] = [
|
||||
{ prop: 'id', label: 'ID', width: 80 },
|
||||
{ prop: 'orderId', label: '订单号', minWidth: 180 },
|
||||
{ prop: 'userName', label: '用户', width: 120 },
|
||||
{ prop: 'amount', label: '订单金额', width: 140, align: 'right' },
|
||||
{ prop: 'commission', label: '分佣金额', width: 140, align: 'right' },
|
||||
{ prop: 'rate', label: '分佣比例', width: 100, align: 'right' },
|
||||
{ prop: 'status', label: '状态', width: 100, type: 'status' },
|
||||
{ prop: 'createDate', label: '分佣时间', width: 180, type: 'text' }
|
||||
]
|
||||
const orderGoodCommissionMock = [
|
||||
{ id: '1', orderId: 'O20260705001', userName: '张三', amount: 12500, commission: 1250, rate: '10%', status: 1, createDate: now(0) },
|
||||
{ id: '2', orderId: 'O20260705003', userName: '王五', amount: 15800, commission: 1580, rate: '10%', status: 1, createDate: now(1) },
|
||||
{ id: '3', orderId: 'O20260705006', userName: '孙八', amount: 45000, commission: 4500, rate: '10%', status: 1, createDate: now(2) }
|
||||
]
|
||||
const serviceOrderCommissionMock = [
|
||||
{ id: '1', orderId: 'S20260705001', userName: '深圳科技公司', amount: 5800, commission: 580, rate: '10%', status: 1, createDate: now(0) },
|
||||
{ id: '2', orderId: 'S20260705003', userName: '北京集团', amount: 35000, commission: 3500, rate: '10%', status: 1, createDate: now(1) }
|
||||
]
|
||||
const priceAnalysisCols: MockColumn[] = [
|
||||
{ prop: 'id', label: 'ID', width: 80 },
|
||||
{ prop: 'categoryName', label: '品类', minWidth: 160 },
|
||||
{ prop: 'minPrice', label: '最低价', width: 120, align: 'right' },
|
||||
{ prop: 'maxPrice', label: '最高价', width: 120, align: 'right' },
|
||||
{ prop: 'avgPrice', label: '平均价', width: 120, align: 'right' },
|
||||
{ prop: 'orderCount', label: '订单数', width: 100, align: 'right' },
|
||||
{ prop: 'createDate', label: '统计日期', width: 180, type: 'text' }
|
||||
]
|
||||
const priceAnalysisMock = [
|
||||
{ id: '1', categoryName: '工业传感器', minPrice: 800, maxPrice: 5500, avgPrice: 2500, orderCount: 158, createDate: now(0) },
|
||||
{ id: '2', categoryName: '智能控制器', minPrice: 2000, maxPrice: 12000, avgPrice: 4000, orderCount: 89, createDate: now(0) },
|
||||
{ id: '3', categoryName: '测量仪器', minPrice: 5000, maxPrice: 80000, avgPrice: 15800, orderCount: 42, createDate: now(1) },
|
||||
{ id: '4', categoryName: '工业相机', minPrice: 1500, maxPrice: 25000, avgPrice: 4500, orderCount: 67, createDate: now(1) },
|
||||
{ id: '5', categoryName: 'PLC 系统', minPrice: 8000, maxPrice: 80000, avgPrice: 18666, orderCount: 33, createDate: now(2) }
|
||||
]
|
||||
|
||||
// ========== other ==========
|
||||
const textconfigCols: MockColumn[] = [
|
||||
{ prop: 'id', label: 'ID', width: 80 },
|
||||
@ -429,26 +344,6 @@ const categoryZXMock = [
|
||||
{ id: '7', name: '活动公告', parentName: '平台公告', level: 2, sort: 2, createDate: now(60) }
|
||||
]
|
||||
|
||||
const goodunitCols: MockColumn[] = [
|
||||
{ prop: 'id', label: 'ID', width: 80 },
|
||||
{ prop: 'name', label: '单位名称', minWidth: 140 },
|
||||
{ prop: 'symbol', label: '符号', width: 100 },
|
||||
{ prop: 'description', label: '描述', minWidth: 220 },
|
||||
{ prop: 'sort', label: '排序', width: 80, align: 'right' },
|
||||
{ prop: 'createDate', label: '创建时间', width: 180, type: 'text' }
|
||||
]
|
||||
const goodunitMock = [
|
||||
{ id: '1', name: '个', symbol: '个', description: '通用计数单位', sort: 1, createDate: now(180) },
|
||||
{ id: '2', name: '件', symbol: '件', description: '衣物或零件', sort: 2, createDate: now(180) },
|
||||
{ id: '3', name: '套', symbol: '套', description: '成套产品', sort: 3, createDate: now(150) },
|
||||
{ id: '4', name: '台', symbol: '台', description: '机械设备', sort: 4, createDate: now(150) },
|
||||
{ id: '5', name: '千克', symbol: 'kg', description: '重量', sort: 5, createDate: now(120) },
|
||||
{ id: '6', name: '吨', symbol: 't', description: '大宗重量', sort: 6, createDate: now(120) },
|
||||
{ id: '7', name: '米', symbol: 'm', description: '长度', sort: 7, createDate: now(100) },
|
||||
{ id: '8', name: '平方米', symbol: 'm²', description: '面积', sort: 8, createDate: now(100) },
|
||||
{ id: '9', name: '升', symbol: 'L', description: '液体容积', sort: 9, createDate: now(80) }
|
||||
]
|
||||
|
||||
const brandCols: MockColumn[] = [
|
||||
{ prop: 'id', label: 'ID', width: 80 },
|
||||
{ prop: 'name', label: '品牌名称', minWidth: 180 },
|
||||
@ -508,24 +403,6 @@ const seckillMock = [
|
||||
{ id: '3', name: '测量仪秒杀', goodsName: '高精度测量仪', seckillPrice: 12800, originalPrice: 15800, stock: 20, startTime: now(0), endTime: now(5), status: 1 }
|
||||
]
|
||||
|
||||
const labelCols: MockColumn[] = [
|
||||
{ prop: 'id', label: 'ID', width: 80 },
|
||||
{ prop: 'name', label: '标签名', minWidth: 160 },
|
||||
{ prop: 'type', label: '类型', width: 120 },
|
||||
{ prop: 'color', label: '颜色', width: 100 },
|
||||
{ prop: 'sort', label: '排序', width: 80, align: 'right' },
|
||||
{ prop: 'createDate', label: '创建时间', width: 180, type: 'text' }
|
||||
]
|
||||
const labelMock = [
|
||||
{ id: '1', name: '热销', type: '商品标签', color: '#F56C6C', sort: 1, createDate: now(200) },
|
||||
{ id: '2', name: '新品', type: '商品标签', color: '#67C23A', sort: 2, createDate: now(200) },
|
||||
{ id: '3', name: '推荐', type: '商品标签', color: '#409EFF', sort: 3, createDate: now(180) },
|
||||
{ id: '4', name: '限时', type: '活动标签', color: '#E6A23C', sort: 1, createDate: now(150) },
|
||||
{ id: '5', name: '满减', type: '活动标签', color: '#F56C6C', sort: 2, createDate: now(120) },
|
||||
{ id: '6', name: '包邮', type: '服务标签', color: '#909399', sort: 1, createDate: now(90) },
|
||||
{ id: '7', name: '正品', type: '服务标签', color: '#67C23A', sort: 2, createDate: now(60) }
|
||||
]
|
||||
|
||||
// ========== supplier ==========
|
||||
const promoterCols: MockColumn[] = [
|
||||
{ prop: 'id', label: 'ID', width: 80 },
|
||||
@ -858,15 +735,6 @@ export const MOCK_TABLE_CONFIGS: Record<string, MockConfig> = {
|
||||
'message-mail-log': { endpoint: '/message/mail-log/page', title: '邮件日志', columns: mailLogCols, mockData: mailLogMock },
|
||||
|
||||
// order (9)
|
||||
'order-ordergood': { endpoint: '/order/ordergood/page', title: '商品订单', columns: orderCommonCols, mockData: orderGoodMock, queryKey: 'id', queryLabel: '订单号', description: '状态: ' + Object.entries(orderStatusMap).map(([k, v]) => `${k}=${v.label}`).join(' / ') },
|
||||
'order-serviceorder': { endpoint: '/order/serviceorder/page', title: '服务订单', columns: orderCommonCols, mockData: serviceOrderMock, queryKey: 'id', queryLabel: '订单号' },
|
||||
'order-group-supplier': { endpoint: '/order/groupsupplierorder/page', title: '商品拼团订单', columns: orderCommonCols, mockData: groupSupplierMock, queryKey: 'id', queryLabel: '订单号' },
|
||||
'order-group-service': { endpoint: '/order/groupserviceorder/page', title: '服务拼团订单', columns: orderCommonCols, mockData: groupServiceMock, queryKey: 'id', queryLabel: '订单号' },
|
||||
'order-ordergood-after': { endpoint: '/order/orderafter/page', title: '商品售后订单', columns: orderCommonCols, mockData: orderAfterMock, queryKey: 'id', queryLabel: '订单号', description: '状态: ' + Object.entries(afterSaleStatusMap).map(([k, v]) => `${k}=${v.label}`).join(' / ') },
|
||||
'order-orderserviceafter': { endpoint: '/order/orderserviceafter/page', title: '服务售后订单', columns: orderCommonCols, mockData: orderServiceAfterMock, queryKey: 'id', queryLabel: '订单号' },
|
||||
'order-ordergood-commission': { endpoint: '/order/ordergood-commission/page', title: '实物订单分佣统计', columns: orderCommissionCols, mockData: orderGoodCommissionMock },
|
||||
'order-serviceorder-commission': { endpoint: '/order/serviceorder-commission/page', title: '服务订单分佣统计', columns: orderCommissionCols, mockData: serviceOrderCommissionMock },
|
||||
'order-base-price-analysis': { endpoint: '/order/orderbase-price-analysis/page', title: '基础价格分析表', columns: priceAnalysisCols, mockData: priceAnalysisMock, queryKey: 'categoryName', queryLabel: '品类' },
|
||||
|
||||
// other (12)
|
||||
'other-textconfig': { endpoint: '/other/textconfig/page', title: '常量配置', columns: textconfigCols, mockData: textconfigMock, queryKey: 'key', queryLabel: '配置键' },
|
||||
@ -876,11 +744,9 @@ export const MOCK_TABLE_CONFIGS: Record<string, MockConfig> = {
|
||||
'other-industry': { endpoint: '/other/industry/page', title: '行业', columns: industryCols, mockData: industryMock, queryKey: 'name', queryLabel: '行业名称' },
|
||||
'other-category-good': { endpoint: '/other/categoryGood/page', title: '平台分类', columns: categoryGoodCols, mockData: categoryGoodMock, queryKey: 'name', queryLabel: '分类名称' },
|
||||
'other-category-zx': { endpoint: '/other/categoryZX/page', title: '资讯分类', columns: categoryZXCols, mockData: categoryZXMock, queryKey: 'name', queryLabel: '分类名称' },
|
||||
'other-goodunit': { endpoint: '/other/goodunit/page', title: '商品单位', columns: goodunitCols, mockData: goodunitMock, queryKey: 'name', queryLabel: '单位名称' },
|
||||
'other-brand': { endpoint: '/other/supplierBrand/page', title: '品牌管理', columns: brandCols, mockData: brandMock, queryKey: 'name', queryLabel: '品牌名称' },
|
||||
'other-groupbuy': { endpoint: '/other/groupbuy/page', title: '拼团活动', columns: groupbuyCols, mockData: groupbuyMock, queryKey: 'name', queryLabel: '活动名称' },
|
||||
'other-seckill': { endpoint: '/other/seckill/page', title: '秒杀活动', columns: seckillCols, mockData: seckillMock, queryKey: 'name', queryLabel: '活动名称' },
|
||||
'other-label': { endpoint: '/other/label/page', title: '标签管理', columns: labelCols, mockData: labelMock, queryKey: 'name', queryLabel: '标签名' },
|
||||
|
||||
// supplier (1)
|
||||
'supplier-promoter': { endpoint: '/supplier/promoter/page', title: '推广返佣', columns: promoterCols, mockData: promoterMock, queryKey: 'name', queryLabel: '推广员' },
|
||||
@ -922,7 +788,5 @@ export const MOCK_TABLE_CONFIGS: Record<string, MockConfig> = {
|
||||
// 状态映射导出 (组件用)
|
||||
export const STATUS_MAPS = {
|
||||
enabled: STATUS_ENABLED,
|
||||
lock: STATUS_LOCK,
|
||||
order: orderStatusMap,
|
||||
afterSale: afterSaleStatusMap
|
||||
lock: STATUS_LOCK
|
||||
}
|
||||
|
||||
233
src/modules/supplier/coupon/CouponListView.vue
Normal file
233
src/modules/supplier/coupon/CouponListView.vue
Normal file
@ -0,0 +1,233 @@
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* F006 优惠券管理 - W7 P0 整改 (沿用老 vue supplier/coupon.vue 116 行)
|
||||
*
|
||||
* 端点 /supplier/coupon/page 200 OK 真数据, 老字段:
|
||||
* - 搜索: 优惠券名
|
||||
* - 表格列: 序号/优惠券名/发放企业(企业 or 平台)/满减配置/适用商品/发放数量/已领取/剩余/状态/创建时间
|
||||
* - 操作: 编辑(仅平台)/停用启用/删除/查看领取记录(仅平台)
|
||||
* - 批量删除
|
||||
*/
|
||||
import { ref, onMounted, reactive } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { httpGet } from '@/utils/request'
|
||||
|
||||
interface Coupon {
|
||||
id: string
|
||||
name: string
|
||||
type: number
|
||||
scope: number
|
||||
sourceType: number
|
||||
couponCode: string
|
||||
enterpriseName: string | null
|
||||
fullMoney: number
|
||||
deductedMoney: number | null
|
||||
rebate: number | null
|
||||
quantity: number
|
||||
receiveQuantity: number
|
||||
remainingQuantity: number
|
||||
expirationDate: string
|
||||
onShelf: number
|
||||
createTime: string
|
||||
goodNames: string[] | null
|
||||
raw: any
|
||||
}
|
||||
|
||||
const list = ref<Coupon[]>([])
|
||||
const total = ref(0)
|
||||
const loading = ref(false)
|
||||
const error = ref<string | null>(null)
|
||||
const page = ref(1)
|
||||
const limit = ref(10)
|
||||
const filters = reactive({ name: '' })
|
||||
const selection = ref<Coupon[]>([])
|
||||
|
||||
const recordVisible = ref(false)
|
||||
const recordList = ref<Array<{ userName: string; status: number; createTime: string }>>([])
|
||||
const recordLoading = ref(false)
|
||||
|
||||
function fmtConfig(row: Coupon) {
|
||||
if (row.type === 1) return `满${row.fullMoney} 减 ${row.deductedMoney}`
|
||||
if (row.type === 2) return `满${row.fullMoney} 打${row.rebate}折`
|
||||
return '--'
|
||||
}
|
||||
|
||||
async function load() {
|
||||
loading.value = true
|
||||
error.value = null
|
||||
try {
|
||||
const r: any = await httpGet('/supplier/coupon/page', { page: page.value, limit: limit.value })
|
||||
const data = r?.data || {}
|
||||
let rows: Coupon[] = (data.list || []).map((it: any) => ({ ...it, raw: it }))
|
||||
if (filters.name) rows = rows.filter(x => x.name?.includes(filters.name))
|
||||
list.value = rows
|
||||
total.value = data.total || 0
|
||||
} catch (e: any) {
|
||||
error.value = e?.msg || e?.message || '加载失败'
|
||||
list.value = []
|
||||
total.value = 0
|
||||
} finally { loading.value = false }
|
||||
}
|
||||
|
||||
function onSearch() { page.value = 1; load() }
|
||||
function onReset() { filters.name = ''; page.value = 1; load() }
|
||||
function onPageChange(p: number) { page.value = p; load() }
|
||||
function onLimitChange(l: number) { limit.value = l; load() }
|
||||
function onSelectionChange(rows: Coupon[]) { selection.value = rows }
|
||||
|
||||
function onAdd() { ElMessage.info('新增优惠券弹窗 (mock) - 待 add-or-update 接入') }
|
||||
function onEdit(row: Coupon) {
|
||||
if (row.sourceType !== 2) { ElMessage.warning('只有平台券可编辑'); return }
|
||||
ElMessage.info(`编辑「${row.name}」 (mock)`)
|
||||
}
|
||||
function onToggleStatus(row: Coupon) {
|
||||
const next = row.onShelf === 1 ? 0 : 1
|
||||
ElMessageBox.confirm(`确认${next === 1 ? '启用' : '停用'}「${row.name}」?`, '提示', { type: 'warning' }).then(() => {
|
||||
ElMessage.success(`${next === 1 ? '启用' : '停用'}成功 (mock)`)
|
||||
load()
|
||||
}).catch(() => {})
|
||||
}
|
||||
function onDelete(row: Coupon) {
|
||||
ElMessageBox.confirm(`确认删除「${row.name}」?`, '提示', { type: 'warning' }).then(() => {
|
||||
ElMessage.success('已删除 (mock)')
|
||||
load()
|
||||
}).catch(() => {})
|
||||
}
|
||||
function onBatchDelete() {
|
||||
if (selection.value.length === 0) { ElMessage.warning('请先选择要删除的券'); return }
|
||||
ElMessageBox.confirm(`确认批量删除选中的 ${selection.value.length} 张券?`, '提示', { type: 'warning' }).then(() => {
|
||||
ElMessage.success('已批量删除 (mock)')
|
||||
load()
|
||||
}).catch(() => {})
|
||||
}
|
||||
function onShowRecords(row: Coupon) {
|
||||
if (row.sourceType !== 2) { ElMessage.warning('只有平台券有领取记录'); return }
|
||||
recordLoading.value = true
|
||||
recordVisible.value = true
|
||||
setTimeout(() => {
|
||||
recordList.value = [
|
||||
{ userName: '张经理', status: 2, createTime: '2026-06-01 10:23:11' },
|
||||
{ userName: '李工', status: 1, createTime: '2026-06-02 14:45:00' },
|
||||
{ userName: '王采购', status: 2, createTime: '2026-06-03 09:15:22' }
|
||||
]
|
||||
recordLoading.value = false
|
||||
}, 300)
|
||||
}
|
||||
|
||||
onMounted(load)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="rr-page">
|
||||
<div class="rr-page-header">
|
||||
<div>
|
||||
<h2 class="rr-page-title">优惠券管理</h2>
|
||||
<p class="rr-page-sub">平台/企业优惠券管理 (共 {{ total }} 张, 选中 {{ selection.length }})</p>
|
||||
</div>
|
||||
<div class="rr-page-actions">
|
||||
<el-button type="primary" @click="onAdd">新增优惠券</el-button>
|
||||
<el-button type="danger" :disabled="selection.length === 0" @click="onBatchDelete">批量删除</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="rr-card rr-search">
|
||||
<el-form :inline="true" @keyup.enter="onSearch">
|
||||
<el-form-item label="优惠券名称">
|
||||
<el-input v-model="filters.name" placeholder="请输入优惠券名称" clearable style="width: 280px" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="onReset">重置</el-button>
|
||||
<el-button type="primary" @click="onSearch">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="rr-card">
|
||||
<el-table :data="list" border style="width: 100%" v-loading="loading" :empty-text="error || '暂无优惠券'" @selection-change="onSelectionChange" row-key="id">
|
||||
<el-table-column type="selection" width="50" align="center" />
|
||||
<el-table-column type="index" label="#" width="50" align="center" />
|
||||
<el-table-column prop="name" label="优惠券名称" min-width="180" show-overflow-tooltip />
|
||||
<el-table-column label="发放企业" min-width="180" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row.sourceType === 2" size="small" type="primary" effect="plain">平台</el-tag>
|
||||
<span v-else>{{ row.enterpriseName || '--' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="满减配置" min-width="180" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="(row.type === 1 ? 'warning' : 'success') as any" size="small" effect="light">
|
||||
{{ fmtConfig(row) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="适用商品" min-width="180" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.scope === 1">
|
||||
<span v-if="row.goodNames && row.goodNames.length">{{ row.goodNames[0] }}等{{ row.goodNames.length }}件商品</span>
|
||||
<span v-else class="rr-muted">无</span>
|
||||
</span>
|
||||
<span v-else>所有商品</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="quantity" label="发放数量" width="100" align="center" />
|
||||
<el-table-column prop="receiveQuantity" label="已领取" width="100" align="center" />
|
||||
<el-table-column label="剩余" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<span :class="row.remainingQuantity > 0 ? 'rr-stock-ok' : 'rr-stock-out'">{{ row.remainingQuantity }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="90" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="(row.onShelf === 1 ? 'success' : 'info') as any" size="small" effect="light">
|
||||
{{ row.onShelf === 1 ? '启用' : '停用' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间" width="180" />
|
||||
<el-table-column label="操作" width="280" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button v-if="row.sourceType === 2" text type="primary" size="small" @click="onEdit(row)">编辑</el-button>
|
||||
<el-button v-if="row.onShelf === 1" text type="warning" size="small" @click="onToggleStatus(row)">停用</el-button>
|
||||
<el-button v-else text type="success" size="small" @click="onToggleStatus(row)">启用</el-button>
|
||||
<el-button text type="danger" size="small" @click="onDelete(row)">删除</el-button>
|
||||
<el-button v-if="row.sourceType === 2" text type="info" size="small" @click="onShowRecords(row)">领取记录</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="rr-pagination">
|
||||
<el-pagination :current-page="page" :page-sizes="[10, 20, 50, 100]" :page-size="limit" :total="total" layout="total, sizes, prev, pager, next, jumper" @size-change="onLimitChange" @current-change="onPageChange" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-dialog v-model="recordVisible" title="优惠券领取记录" width="720px" :close-on-click-modal="false">
|
||||
<el-table v-loading="recordLoading" :data="recordList" border style="width: 100%" empty-text="暂无人领取">
|
||||
<el-table-column prop="userName" label="领取人" align="center" />
|
||||
<el-table-column label="状态" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row.status === 1" size="small" type="info" effect="light">已使用</el-tag>
|
||||
<el-tag v-else-if="row.status === 2" size="small" type="success" effect="light">未使用</el-tag>
|
||||
<el-tag v-else size="small" type="warning" effect="light">未知</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="领取时间" align="center" width="200" />
|
||||
</el-table>
|
||||
<template #footer>
|
||||
<el-button @click="recordVisible = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.rr-page { max-width: 1500px; }
|
||||
.rr-page-header { margin-bottom: 16px; display: flex; justify-content: space-between; align-items: flex-start; }
|
||||
.rr-page-title { font-size: 22px; font-weight: 600; color: var(--ink); margin: 0 0 4px 0; }
|
||||
.rr-page-sub { color: var(--ink-3); font-size: 13px; margin: 0; }
|
||||
.rr-page-actions { display: flex; gap: 8px; }
|
||||
.rr-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: hidden; margin-bottom: 16px; }
|
||||
.rr-search { padding: 16px 20px; }
|
||||
.rr-pagination { padding: 12px 20px; display: flex; justify-content: flex-end; border-top: 1px solid var(--border); }
|
||||
.rr-muted { color: var(--ink-3); }
|
||||
.rr-stock-ok { color: var(--primary); font-weight: 600; }
|
||||
.rr-stock-out { color: var(--ink-3); }
|
||||
</style>
|
||||
@ -170,7 +170,8 @@ const routes: RouteRecordRaw[] = [
|
||||
},
|
||||
{
|
||||
path: '/supplier/servicegood',
|
||||
redirect: '/supplier/good'
|
||||
component: () => import('@/modules/supplier/servicegood/ServiceGoodListView.vue'),
|
||||
meta: { title: '服务商品' }
|
||||
},
|
||||
{
|
||||
path: '/product/shop',
|
||||
@ -233,7 +234,7 @@ const routes: RouteRecordRaw[] = [
|
||||
{ path: '/other/groupbuy', component: () => import('@/modules/generic/MockTableView.vue'), props: () => ({ configKey: 'other-groupbuy' }), meta: { title: '拼团活动' } },
|
||||
{ path: '/other/seckill', component: () => import('@/modules/generic/MockTableView.vue'), props: () => ({ configKey: 'other-seckill' }), meta: { title: '秒杀活动' } },
|
||||
// supplier 2 个
|
||||
{ path: '/supplier/coupon', component: () => import('@/modules/generic/MockTableView.vue'), props: () => ({ configKey: 'other-textconfig' }), meta: { title: '优惠券' } }, // 用常量配置 mock
|
||||
{ path: '/supplier/coupon', component: () => import('@/modules/supplier/coupon/CouponListView.vue'), meta: { title: '优惠券' } }, // W7: 独立 view, 走 /supplier/coupon/page 真 API
|
||||
{ path: '/supplier/promoter', component: () => import('@/modules/generic/MockTableView.vue'), props: () => ({ configKey: 'supplier-promoter' }), meta: { title: '推广返佣' } },
|
||||
// sys 11 个
|
||||
{ path: '/sys/dict', component: () => import('@/modules/generic/MockTableView.vue'), props: () => ({ configKey: 'sys-dict' }), meta: { title: '字典类型' } },
|
||||
|
||||
Loading…
Reference in New Issue
Block a user