All checks were successful
continuous-integration/drone/push Build is passing
271 lines
8.0 KiB
Vue
271 lines
8.0 KiB
Vue
<template>
|
|
<div class="coupon-manage">
|
|
<!-- 顶部操作栏 -->
|
|
<div class="toolbar">
|
|
<el-button type="primary" @click="handleAdd">新增优惠券</el-button>
|
|
</div>
|
|
|
|
<!-- 优惠券列表表格 -->
|
|
<el-table :data="couponList" border style="width: 100%">
|
|
<el-table-column label="名称(简中)" prop="nameZhCn" min-width="120" show-overflow-tooltip />
|
|
<el-table-column label="名称(繁中)" prop="nameZhTw" min-width="120" show-overflow-tooltip />
|
|
<el-table-column label="名称(英文)" prop="nameEn" min-width="120" show-overflow-tooltip />
|
|
|
|
<el-table-column label="类型" width="100" align="center">
|
|
<template #default="{ row }">
|
|
<el-tag v-if="row.type === 'ThresholdDiscount'" type="warning">满减券</el-tag>
|
|
<el-tag v-else type="success">抵扣券</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
|
|
<el-table-column label="满减门槛" width="100" align="center">
|
|
<template #default="{ row }">
|
|
{{ row.thresholdAmount != null ? `¥${row.thresholdAmount}` : '-' }}
|
|
</template>
|
|
</el-table-column>
|
|
|
|
<el-table-column label="折扣金额" width="100" align="center">
|
|
<template #default="{ row }">¥{{ row.discountAmount }}</template>
|
|
</el-table-column>
|
|
|
|
<el-table-column label="所需积分" prop="pointsCost" width="100" align="center" />
|
|
|
|
<el-table-column label="到期时间" width="170" align="center">
|
|
<template #default="{ row }">
|
|
{{ formatDate(row.expireAt) }}
|
|
</template>
|
|
</el-table-column>
|
|
|
|
<el-table-column label="创建时间" width="170" align="center">
|
|
<template #default="{ row }">
|
|
{{ formatDate(row.createdAt) }}
|
|
</template>
|
|
</el-table-column>
|
|
|
|
<el-table-column label="状态" width="80" align="center">
|
|
<template #default="{ row }">
|
|
<el-tag :type="row.isActive ? 'success' : 'info'">
|
|
{{ row.isActive ? '上架' : '下架' }}
|
|
</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
|
|
<el-table-column label="操作" width="200" align="center" fixed="right">
|
|
<template #default="{ row }">
|
|
<el-button size="small" @click="handleEdit(row)">编辑</el-button>
|
|
<el-button
|
|
size="small"
|
|
:type="row.isActive ? 'warning' : 'success'"
|
|
@click="handleToggle(row.id)"
|
|
>
|
|
{{ row.isActive ? '下架' : '上架' }}
|
|
</el-button>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
|
|
<!-- 分页 -->
|
|
<div class="pagination">
|
|
<el-pagination
|
|
v-model:current-page="currentPage"
|
|
:page-size="pageSize"
|
|
:total="total"
|
|
layout="total, prev, pager, next"
|
|
@current-change="loadCoupons"
|
|
/>
|
|
</div>
|
|
|
|
<!-- 新增/编辑弹窗 -->
|
|
<el-dialog
|
|
v-model="dialogVisible"
|
|
:title="isEdit ? '编辑优惠券' : '新增优惠券'"
|
|
width="620px"
|
|
destroy-on-close
|
|
>
|
|
<el-form :model="form" label-width="120px">
|
|
<el-form-item label="名称(简中)" required>
|
|
<el-input v-model="form.nameZhCn" placeholder="请输入简体中文名称" />
|
|
</el-form-item>
|
|
<el-form-item label="名称(繁中)" required>
|
|
<el-input v-model="form.nameZhTw" placeholder="请输入繁体中文名称" />
|
|
</el-form-item>
|
|
<el-form-item label="名称(英文)" required>
|
|
<el-input v-model="form.nameEn" placeholder="请输入英文名称" />
|
|
</el-form-item>
|
|
<el-form-item label="优惠券类型" required>
|
|
<el-select v-model="form.type" style="width: 100%">
|
|
<el-option label="满减券" value="ThresholdDiscount" />
|
|
<el-option label="抵扣券" value="DirectDiscount" />
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item v-if="form.type === 'ThresholdDiscount'" label="满减门槛">
|
|
<el-input-number v-model="form.thresholdAmount" :min="0" :precision="2" style="width: 100%" />
|
|
</el-form-item>
|
|
<el-form-item label="折扣金额" required>
|
|
<el-input-number v-model="form.discountAmount" :min="0.01" :precision="2" style="width: 100%" />
|
|
</el-form-item>
|
|
<el-form-item label="所需积分" required>
|
|
<el-input-number v-model="form.pointsCost" :min="0" style="width: 100%" />
|
|
</el-form-item>
|
|
<el-form-item label="到期时间" required>
|
|
<el-date-picker
|
|
v-model="form.expireAt"
|
|
type="datetime"
|
|
placeholder="选择到期时间"
|
|
style="width: 100%"
|
|
/>
|
|
</el-form-item>
|
|
</el-form>
|
|
<template #footer>
|
|
<el-button @click="dialogVisible = false">取消</el-button>
|
|
<el-button type="primary" :loading="submitting" @click="handleSubmit">确定</el-button>
|
|
</template>
|
|
</el-dialog>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, onMounted } from 'vue'
|
|
import { ElMessage } from 'element-plus'
|
|
import { getCoupons, createCoupon, updateCoupon, toggleCouponActive } from '@/api/coupon'
|
|
|
|
// 优惠券数据类型
|
|
interface CouponItem {
|
|
id: string
|
|
nameZhCn: string
|
|
nameZhTw: string
|
|
nameEn: string
|
|
type: string
|
|
thresholdAmount: number | null
|
|
discountAmount: number
|
|
pointsCost: number
|
|
expireAt: string
|
|
isActive: boolean
|
|
isStamp: boolean
|
|
}
|
|
|
|
const couponList = ref<CouponItem[]>([])
|
|
const currentPage = ref(1)
|
|
const pageSize = 20
|
|
const total = ref(0)
|
|
const dialogVisible = ref(false)
|
|
const isEdit = ref(false)
|
|
const submitting = ref(false)
|
|
const editingId = ref('')
|
|
|
|
const defaultForm = () => ({
|
|
nameZhCn: '',
|
|
nameZhTw: '',
|
|
nameEn: '',
|
|
type: 'DirectDiscount' as string,
|
|
thresholdAmount: 0 as number | null,
|
|
discountAmount: 0,
|
|
pointsCost: 0,
|
|
expireAt: '' as string | Date,
|
|
})
|
|
const form = ref(defaultForm())
|
|
|
|
// 格式化日期
|
|
function formatDate(dateStr: string) {
|
|
if (!dateStr) return '-'
|
|
return new Date(dateStr).toLocaleString('zh-CN')
|
|
}
|
|
|
|
// 加载优惠券列表
|
|
async function loadCoupons() {
|
|
try {
|
|
const res: any = await getCoupons(currentPage.value, pageSize)
|
|
couponList.value = res.data?.items || res.data || []
|
|
total.value = res.data?.total || couponList.value.length
|
|
} catch {
|
|
// 错误已由拦截器处理
|
|
}
|
|
}
|
|
|
|
// 新增
|
|
function handleAdd() {
|
|
isEdit.value = false
|
|
editingId.value = ''
|
|
form.value = defaultForm()
|
|
dialogVisible.value = true
|
|
}
|
|
|
|
// 编辑
|
|
function handleEdit(row: CouponItem) {
|
|
isEdit.value = true
|
|
editingId.value = row.id
|
|
form.value = {
|
|
nameZhCn: row.nameZhCn,
|
|
nameZhTw: row.nameZhTw,
|
|
nameEn: row.nameEn,
|
|
type: row.type,
|
|
thresholdAmount: row.thresholdAmount,
|
|
discountAmount: row.discountAmount,
|
|
pointsCost: row.pointsCost,
|
|
expireAt: row.expireAt,
|
|
}
|
|
dialogVisible.value = true
|
|
}
|
|
|
|
// 上下架切换
|
|
async function handleToggle(id: string) {
|
|
try {
|
|
await toggleCouponActive(id)
|
|
ElMessage.success('操作成功')
|
|
await loadCoupons()
|
|
} catch {
|
|
// 错误已由拦截器处理
|
|
}
|
|
}
|
|
|
|
// 提交表单
|
|
async function handleSubmit() {
|
|
if (!form.value.nameZhCn || !form.value.nameZhTw || !form.value.nameEn) {
|
|
ElMessage.warning('请填写所有语言的名称')
|
|
return
|
|
}
|
|
if (!form.value.expireAt) {
|
|
ElMessage.warning('请选择到期时间')
|
|
return
|
|
}
|
|
submitting.value = true
|
|
try {
|
|
const payload = {
|
|
...form.value,
|
|
thresholdAmount: form.value.type === 'ThresholdDiscount' ? form.value.thresholdAmount : null,
|
|
}
|
|
if (isEdit.value) {
|
|
await updateCoupon(editingId.value, payload)
|
|
ElMessage.success('更新成功')
|
|
} else {
|
|
await createCoupon(payload)
|
|
ElMessage.success('创建成功')
|
|
}
|
|
dialogVisible.value = false
|
|
await loadCoupons()
|
|
} catch {
|
|
// 错误已由拦截器处理
|
|
} finally {
|
|
submitting.value = false
|
|
}
|
|
}
|
|
|
|
onMounted(() => {
|
|
loadCoupons()
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.coupon-manage {
|
|
padding: 20px;
|
|
}
|
|
.toolbar {
|
|
margin-bottom: 16px;
|
|
}
|
|
.pagination {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
margin-top: 16px;
|
|
}
|
|
</style>
|