1
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
<!-- 搜索表单 -->
|
||||
<template>
|
||||
<a-space :size="10" style="flex-wrap: wrap">
|
||||
<a-button type="primary" class="ele-btn-icon" @click="add">
|
||||
<template #icon>
|
||||
<PlusOutlined />
|
||||
</template>
|
||||
<span>添加</span>
|
||||
</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { PlusOutlined } from '@ant-design/icons-vue';
|
||||
import type { GradeParam } from '@/api/user/grade/model';
|
||||
import { watch } from 'vue';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
// 选中的角色
|
||||
selection?: [];
|
||||
}>(),
|
||||
{}
|
||||
);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'search', where?: GradeParam): void;
|
||||
(e: 'add'): void;
|
||||
(e: 'remove'): void;
|
||||
(e: 'batchMove'): void;
|
||||
}>();
|
||||
|
||||
// 新增
|
||||
const add = () => {
|
||||
emit('add');
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.selection,
|
||||
() => {}
|
||||
);
|
||||
</script>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,803 @@
|
||||
<template>
|
||||
<a-page-header :title="getPageTitle()" @back="() => $router.go(-1)">
|
||||
<template #extra>
|
||||
<a-space>
|
||||
<a-button type="primary" @click="openEdit()">
|
||||
<template #icon>
|
||||
<PlusOutlined />
|
||||
</template>
|
||||
新增优惠券
|
||||
</a-button>
|
||||
<a-button @click="reload()">
|
||||
<template #icon>
|
||||
<ReloadOutlined />
|
||||
</template>
|
||||
刷新
|
||||
</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
|
||||
<a-card :bordered="false" :body-style="{ padding: '16px' }">
|
||||
<!-- 搜索区域 -->
|
||||
<div class="search-container">
|
||||
<a-form layout="inline" :model="searchForm" class="search-form">
|
||||
<a-form-item label="优惠券名称">
|
||||
<a-input
|
||||
v-model:value="searchForm.name"
|
||||
placeholder="请输入优惠券名称"
|
||||
allow-clear
|
||||
style="width: 200px"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="优惠券类型">
|
||||
<a-select
|
||||
v-model:value="searchForm.type"
|
||||
placeholder="请选择类型"
|
||||
allow-clear
|
||||
style="width: 150px"
|
||||
>
|
||||
<a-select-option :value="10">满减券</a-select-option>
|
||||
<a-select-option :value="20">折扣券</a-select-option>
|
||||
<a-select-option :value="30">免费券</a-select-option>
|
||||
<a-select-option :value="40">无门槛券</a-select-option>
|
||||
<a-select-option :value="50">场地使用券</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="到期类型">
|
||||
<a-select
|
||||
v-model:value="searchForm.expireType"
|
||||
placeholder="请选择到期类型"
|
||||
allow-clear
|
||||
style="width: 150px"
|
||||
>
|
||||
<a-select-option :value="10">领取后生效</a-select-option>
|
||||
<a-select-option :value="20">固定时间</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="是否过期">
|
||||
<a-select
|
||||
v-model:value="searchForm.isExpire"
|
||||
placeholder="请选择状态"
|
||||
allow-clear
|
||||
style="width: 120px"
|
||||
>
|
||||
<a-select-option :value="0">未过期</a-select-option>
|
||||
<a-select-option :value="1">已过期</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-space>
|
||||
<a-button type="primary" @click="handleSearch">
|
||||
<template #icon>
|
||||
<SearchOutlined />
|
||||
</template>
|
||||
搜索
|
||||
</a-button>
|
||||
<a-button @click="handleReset">
|
||||
<template #icon>
|
||||
<ClearOutlined />
|
||||
</template>
|
||||
重置
|
||||
</a-button>
|
||||
</a-space>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
|
||||
<!-- 批量操作区域 -->
|
||||
<div v-if="selection.length > 0" class="batch-actions">
|
||||
<a-alert
|
||||
:message="`已选择 ${selection.length} 项`"
|
||||
type="info"
|
||||
show-icon
|
||||
style="margin-bottom: 16px"
|
||||
>
|
||||
<template #action>
|
||||
<a-space>
|
||||
<a-button size="small" @click="clearSelection">取消选择</a-button>
|
||||
<a-popconfirm
|
||||
title="确定要删除选中的优惠券吗?"
|
||||
@confirm="removeBatch"
|
||||
>
|
||||
<a-button size="small" danger>批量删除</a-button>
|
||||
</a-popconfirm>
|
||||
</a-space>
|
||||
</template>
|
||||
</a-alert>
|
||||
</div>
|
||||
|
||||
<!-- 表格 -->
|
||||
<ele-pro-table
|
||||
ref="tableRef"
|
||||
row-key="id"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
:customRow="customRow"
|
||||
:row-selection="rowSelection"
|
||||
:scroll="{ x: 1800 }"
|
||||
tool-class="ele-toolbar-form"
|
||||
class="coupon-table"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'name'">
|
||||
<div class="coupon-name">
|
||||
<a-typography-text strong>{{ record.name }}</a-typography-text>
|
||||
<div class="coupon-description">{{
|
||||
record.description || '暂无描述'
|
||||
}}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'type'">
|
||||
<a-tag :color="getCouponTypeColor(record.type)">
|
||||
{{ getCouponTypeText(record.type) }}
|
||||
</a-tag>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'value'">
|
||||
<div class="coupon-value">
|
||||
<template v-if="record.type === 10">
|
||||
<span class="value-amount"
|
||||
>¥{{ Number(record.reducePrice).toFixed(2) || '0.00' }}</span
|
||||
>
|
||||
<div class="value-condition"
|
||||
>满¥{{
|
||||
Number(record.minPrice).toFixed(2) || '0.00'
|
||||
}}可用</div
|
||||
>
|
||||
</template>
|
||||
<template v-else-if="record.type === 20">
|
||||
<span class="value-discount">{{ record.discount }}折</span>
|
||||
<div class="value-condition"
|
||||
>满¥{{
|
||||
Number(record.minPrice)?.toFixed(2) || '0.00'
|
||||
}}可用</div
|
||||
>
|
||||
</template>
|
||||
<template v-else-if="record.type === 30">
|
||||
<span class="value-free">免费券</span>
|
||||
<div class="value-condition"
|
||||
>满¥{{
|
||||
Number(record.minPrice)?.toFixed(2) || '0.00'
|
||||
}}可用</div
|
||||
>
|
||||
</template>
|
||||
<template v-else-if="record.type === 40">
|
||||
<span class="value-amount" style="color: #1890ff"
|
||||
>¥{{ Number(record.reducePrice).toFixed(2) || '0.00' }}</span
|
||||
>
|
||||
<div class="value-condition">无门槛</div>
|
||||
</template>
|
||||
<template v-else-if="record.type === 50">
|
||||
<span class="value-free" style="color: #13c2c2">场地券</span>
|
||||
<div class="value-condition">
|
||||
{{ record.useCount === -1 ? '无限次' : record.useCount + '次' }}
|
||||
<template v-if="record.useDuration"
|
||||
>/{{ record.useDuration }}分钟</template
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'expireInfo'">
|
||||
<div class="expire-info">
|
||||
<a-tag :color="record.expireType === 10 ? 'blue' : 'green'">
|
||||
{{ record.expireType === 10 ? '领取后生效' : '固定时间' }}
|
||||
</a-tag>
|
||||
<div class="expire-detail">
|
||||
<template v-if="record.expireType === 10">
|
||||
{{ record.expireDay }}天有效
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ formatDate(record.startTime) }} 至
|
||||
{{ formatDate(record.endTime) }}
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'applyRange'">
|
||||
<a-tag :color="getApplyRangeColor(record.applyRange)">
|
||||
{{ getApplyRangeText(record.applyRange) }}
|
||||
</a-tag>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'receiveTarget'">
|
||||
<a-tag :color="getReceiveTargetColor(record.receiveTarget || 0)">
|
||||
{{ getReceiveTargetText(record.receiveTarget || 0) }}
|
||||
</a-tag>
|
||||
<template v-if="record.receiveTarget === 3 && record.receiveUserIds">
|
||||
<div style="color: #999; font-size: 12px">
|
||||
已指定 {{ JSON.parse(record.receiveUserIds).length }} 人
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'usage'">
|
||||
<div class="usage-info">
|
||||
<a-progress
|
||||
:percent="getUsagePercent(record)"
|
||||
:stroke-color="getUsageColor(record)"
|
||||
size="small"
|
||||
/>
|
||||
<div class="usage-text">
|
||||
已发放: {{ record.issuedCount || 0 }}
|
||||
<template v-if="record.totalCount !== -1">
|
||||
/ {{ record.totalCount }}
|
||||
</template>
|
||||
<template v-else> (无限制) </template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'isExpire'">
|
||||
<a-tag :color="record.isExpire === 0 ? 'success' : 'error'">
|
||||
{{ record.isExpire === 0 ? '未过期' : '已过期' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a-tooltip title="编辑">
|
||||
<a-button type="link" size="small" @click="openEdit(record)">
|
||||
<template #icon>
|
||||
<EditOutlined />
|
||||
</template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
<a-tooltip title="复制">
|
||||
<a-button type="link" size="small" @click="copyRecord(record)">
|
||||
<template #icon>
|
||||
<CopyOutlined />
|
||||
</template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
<a-popconfirm
|
||||
title="确定要删除此优惠券吗?"
|
||||
@confirm="remove(record)"
|
||||
>
|
||||
<a-tooltip title="删除">
|
||||
<a-button type="link" size="small" danger>
|
||||
<template #icon>
|
||||
<DeleteOutlined />
|
||||
</template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
</a-popconfirm>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</a-card>
|
||||
|
||||
<!-- 编辑弹窗 -->
|
||||
<ShopCouponEdit v-model:visible="showEdit" :data="current" @done="reload" />
|
||||
</a-page-header>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { createVNode, ref, reactive, computed } from 'vue';
|
||||
import { message, Modal } from 'ant-design-vue';
|
||||
import {
|
||||
ExclamationCircleOutlined,
|
||||
PlusOutlined,
|
||||
ReloadOutlined,
|
||||
SearchOutlined,
|
||||
ClearOutlined,
|
||||
EditOutlined,
|
||||
DeleteOutlined,
|
||||
CopyOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import type { EleProTable } from 'ele-admin-pro';
|
||||
import { toDateString } from 'ele-admin-pro';
|
||||
import type {
|
||||
DatasourceFunction,
|
||||
ColumnItem
|
||||
} from 'ele-admin-pro/es/ele-pro-table/types';
|
||||
import { getPageTitle } from '@/utils/common';
|
||||
import ShopCouponEdit from './components/shopCouponEdit.vue';
|
||||
import {
|
||||
pageShopCoupon,
|
||||
removeShopCoupon,
|
||||
removeBatchShopCoupon
|
||||
} from '@/api/shop/shopCoupon';
|
||||
import type {
|
||||
ShopCoupon,
|
||||
ShopCouponParam
|
||||
} from '@/api/shop/shopCoupon/model';
|
||||
|
||||
// 表格实例
|
||||
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||
|
||||
// 表格选中数据
|
||||
const selection = ref<ShopCoupon[]>([]);
|
||||
// 当前编辑数据
|
||||
const current = ref<ShopCoupon | null>(null);
|
||||
// 是否显示编辑弹窗
|
||||
const showEdit = ref(false);
|
||||
// 加载状态
|
||||
const loading = ref(false);
|
||||
|
||||
// 搜索表单
|
||||
const searchForm = reactive<ShopCouponParam>({
|
||||
keywords: '',
|
||||
name: undefined,
|
||||
type: undefined
|
||||
});
|
||||
|
||||
// 表格数据源
|
||||
const datasource: DatasourceFunction = ({
|
||||
page,
|
||||
limit,
|
||||
where,
|
||||
orders,
|
||||
filters
|
||||
}) => {
|
||||
const params = {
|
||||
...where,
|
||||
...searchForm,
|
||||
...orders,
|
||||
page,
|
||||
limit
|
||||
};
|
||||
|
||||
if (filters) {
|
||||
Object.assign(params, filters);
|
||||
}
|
||||
|
||||
return pageShopCoupon(params);
|
||||
};
|
||||
|
||||
// 行选择配置
|
||||
const rowSelection = computed(() => ({
|
||||
selectedRowKeys: selection.value.map((item) => item.id),
|
||||
onChange: (
|
||||
selectedRowKeys: (string | number)[],
|
||||
selectedRows: ShopCoupon[]
|
||||
) => {
|
||||
selection.value = selectedRows;
|
||||
},
|
||||
onSelect: (record: ShopCoupon, selected: boolean) => {
|
||||
if (selected) {
|
||||
selection.value.push(record);
|
||||
} else {
|
||||
const index = selection.value.findIndex(
|
||||
(item) => item.id === record.id
|
||||
);
|
||||
if (index > -1) {
|
||||
selection.value.splice(index, 1);
|
||||
}
|
||||
}
|
||||
},
|
||||
onSelectAll: (
|
||||
selected: boolean,
|
||||
selectedRows: ShopCoupon[],
|
||||
changeRows: ShopCoupon[]
|
||||
) => {
|
||||
if (selected) {
|
||||
changeRows.forEach((row) => {
|
||||
if (!selection.value.find((item) => item.id === row.id)) {
|
||||
selection.value.push(row);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
changeRows.forEach((row) => {
|
||||
const index = selection.value.findIndex((item) => item.id === row.id);
|
||||
if (index > -1) {
|
||||
selection.value.splice(index, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
// 表格列配置
|
||||
const columns = ref<ColumnItem[]>([
|
||||
{
|
||||
title: 'ID',
|
||||
dataIndex: 'id',
|
||||
key: 'id',
|
||||
align: 'center',
|
||||
width: 80,
|
||||
fixed: 'left'
|
||||
},
|
||||
{
|
||||
title: '优惠券信息',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
align: 'left',
|
||||
width: 250,
|
||||
fixed: 'left',
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
title: '类型',
|
||||
dataIndex: 'type',
|
||||
key: 'type',
|
||||
align: 'center',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: '优惠价值',
|
||||
dataIndex: 'value',
|
||||
key: 'value',
|
||||
align: 'center',
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
title: '有效期信息',
|
||||
dataIndex: 'expireInfo',
|
||||
key: 'expireInfo',
|
||||
align: 'center',
|
||||
width: 180
|
||||
},
|
||||
{
|
||||
title: '适用范围',
|
||||
dataIndex: 'applyRange',
|
||||
key: 'applyRange',
|
||||
align: 'center',
|
||||
width: 120
|
||||
},
|
||||
{
|
||||
title: '发放对象',
|
||||
dataIndex: 'receiveTarget',
|
||||
key: 'receiveTarget',
|
||||
align: 'center',
|
||||
width: 120
|
||||
},
|
||||
{
|
||||
title: '使用情况',
|
||||
dataIndex: 'usage',
|
||||
key: 'usage',
|
||||
align: 'center',
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
title: '每人限领',
|
||||
dataIndex: 'limitPerUser',
|
||||
key: 'limitPerUser',
|
||||
align: 'center',
|
||||
width: 100,
|
||||
customRender: ({ text }) => (text === -1 ? '无限制' : text)
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'isExpire',
|
||||
key: 'isExpire',
|
||||
align: 'center',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'createTime',
|
||||
key: 'createTime',
|
||||
align: 'center',
|
||||
width: 120,
|
||||
sorter: true,
|
||||
ellipsis: true,
|
||||
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd')
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 150,
|
||||
fixed: 'right',
|
||||
align: 'center',
|
||||
hideInSetting: true
|
||||
}
|
||||
]);
|
||||
|
||||
// 工具方法
|
||||
const getCouponTypeText = (type: number) => {
|
||||
const typeMap: Record<number, string> = {
|
||||
10: '满减券',
|
||||
20: '折扣券',
|
||||
30: '免费券',
|
||||
40: '无门槛券',
|
||||
50: '场地使用券'
|
||||
};
|
||||
return typeMap[type] || '未知';
|
||||
};
|
||||
|
||||
const getCouponTypeColor = (type: number) => {
|
||||
const colorMap: Record<number, string> = {
|
||||
10: 'red',
|
||||
20: 'orange',
|
||||
30: 'green',
|
||||
40: 'blue',
|
||||
50: 'cyan'
|
||||
};
|
||||
return colorMap[type] || 'default';
|
||||
};
|
||||
|
||||
const getReceiveTargetText = (target: number) => {
|
||||
const targetMap: Record<number, string> = {
|
||||
0: '全部用户',
|
||||
1: '仅会员',
|
||||
2: '仅非会员',
|
||||
3: '指定用户'
|
||||
};
|
||||
return targetMap[target] || '全部';
|
||||
};
|
||||
|
||||
const getReceiveTargetColor = (target: number) => {
|
||||
const colorMap: Record<number, string> = {
|
||||
0: 'default',
|
||||
1: 'gold',
|
||||
2: 'geekblue',
|
||||
3: 'magenta'
|
||||
};
|
||||
return colorMap[target] || 'default';
|
||||
};
|
||||
|
||||
const getApplyRangeText = (range: number) => {
|
||||
const rangeMap = {
|
||||
10: '全部商品',
|
||||
20: '指定商品',
|
||||
30: '指定分类'
|
||||
};
|
||||
return rangeMap[range as keyof typeof rangeMap] || '未知';
|
||||
};
|
||||
|
||||
const getApplyRangeColor = (range: number) => {
|
||||
const colorMap = {
|
||||
10: 'blue',
|
||||
20: 'purple',
|
||||
30: 'cyan'
|
||||
};
|
||||
return colorMap[range as keyof typeof colorMap] || 'default';
|
||||
};
|
||||
|
||||
const formatDate = (dateStr: string) => {
|
||||
return dateStr ? toDateString(dateStr, 'yyyy-MM-dd') : '-';
|
||||
};
|
||||
|
||||
const getUsagePercent = (record: ShopCoupon) => {
|
||||
if (record.totalCount === -1) return 0;
|
||||
return Math.round(
|
||||
((record.issuedCount || 0) / Number(record.totalCount)) * 100
|
||||
);
|
||||
};
|
||||
|
||||
const getUsageColor = (record: ShopCoupon) => {
|
||||
const percent = getUsagePercent(record);
|
||||
if (percent >= 90) return '#ff4d4f';
|
||||
if (percent >= 70) return '#faad14';
|
||||
return '#52c41a';
|
||||
};
|
||||
|
||||
/* 搜索 */
|
||||
const reload = (where?: ShopCouponParam) => {
|
||||
selection.value = [];
|
||||
tableRef?.value?.reload({ where: where });
|
||||
};
|
||||
|
||||
/* 处理搜索 */
|
||||
const handleSearch = () => {
|
||||
reload();
|
||||
};
|
||||
|
||||
/* 重置搜索 */
|
||||
const handleReset = () => {
|
||||
Object.assign(searchForm, {
|
||||
name: '',
|
||||
type: undefined,
|
||||
expireType: undefined,
|
||||
isExpire: undefined
|
||||
});
|
||||
reload();
|
||||
};
|
||||
|
||||
/* 清除选择 */
|
||||
const clearSelection = () => {
|
||||
selection.value = [];
|
||||
};
|
||||
|
||||
/* 打开编辑弹窗 */
|
||||
const openEdit = (row?: ShopCoupon) => {
|
||||
current.value = row ?? null;
|
||||
showEdit.value = true;
|
||||
};
|
||||
|
||||
/* 复制记录 */
|
||||
const copyRecord = (record: ShopCoupon) => {
|
||||
const copyData = {
|
||||
...record,
|
||||
id: undefined,
|
||||
name: `${record.name}_副本`,
|
||||
createTime: undefined,
|
||||
updateTime: undefined,
|
||||
issuedCount: 0
|
||||
};
|
||||
current.value = copyData;
|
||||
showEdit.value = true;
|
||||
message.success('已复制优惠券信息,请修改后保存');
|
||||
};
|
||||
|
||||
/* 删除单个 */
|
||||
const remove = (row: ShopCoupon) => {
|
||||
if (row.issuedCount && row.issuedCount > 0) {
|
||||
message.warning('该优惠券已有用户领取,无法删除');
|
||||
return;
|
||||
}
|
||||
|
||||
const hide = message.loading('删除中...', 0);
|
||||
removeShopCoupon(row.id)
|
||||
.then((msg) => {
|
||||
hide();
|
||||
message.success(msg);
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
};
|
||||
|
||||
/* 批量删除 */
|
||||
const removeBatch = () => {
|
||||
if (!selection.value.length) {
|
||||
message.error('请至少选择一条数据');
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否有已发放的优惠券
|
||||
const issuedCoupons = selection.value.filter(
|
||||
(item) => item.issuedCount && item.issuedCount > 0
|
||||
);
|
||||
if (issuedCoupons.length > 0) {
|
||||
message.warning(
|
||||
`选中的优惠券中有 ${issuedCoupons.length} 个已被用户领取,无法删除`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
Modal.confirm({
|
||||
title: '批量删除确认',
|
||||
content: `确定要删除选中的 ${selection.value.length} 个优惠券吗?此操作不可恢复。`,
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
maskClosable: true,
|
||||
okText: '确定删除',
|
||||
okType: 'danger',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
const hide = message.loading('批量删除中...', 0);
|
||||
removeBatchShopCoupon(selection.value.map((d) => d.id))
|
||||
.then((msg) => {
|
||||
hide();
|
||||
message.success(msg);
|
||||
selection.value = [];
|
||||
reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
hide();
|
||||
message.error(e.message);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/* 自定义行属性 */
|
||||
const customRow = (record: ShopCoupon) => {
|
||||
return {
|
||||
// 行点击事件
|
||||
onClick: () => {
|
||||
// console.log(record);
|
||||
},
|
||||
// 行双击事件
|
||||
onDblclick: () => {
|
||||
openEdit(record);
|
||||
},
|
||||
// 行样式
|
||||
class: record.isExpire === 1 ? 'expired-row' : ''
|
||||
};
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'ShopCoupon'
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.shop-coupon-container {
|
||||
.search-container {
|
||||
background: #fafafa;
|
||||
padding: 16px;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 16px;
|
||||
|
||||
.search-form {
|
||||
.ant-form-item {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.batch-actions {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.coupon-table {
|
||||
.coupon-name {
|
||||
text-align: left;
|
||||
|
||||
.coupon-description {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
margin-top: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.coupon-value {
|
||||
.value-amount {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #f5222d;
|
||||
}
|
||||
|
||||
.value-discount {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #fa8c16;
|
||||
}
|
||||
|
||||
.value-free {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
.value-condition {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.expire-info {
|
||||
.expire-detail {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
margin-top: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.usage-info {
|
||||
.usage-text {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
margin-top: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.expired-row {
|
||||
background-color: #fff2f0;
|
||||
|
||||
td {
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-table) {
|
||||
.ant-table-tbody > tr:hover > td {
|
||||
background-color: #e6f7ff;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-progress) {
|
||||
.ant-progress-text {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-alert) {
|
||||
.ant-alert-message {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user