|
|
@@ -11,23 +11,20 @@ import {
|
|
|
pauseActivity,
|
|
|
resumeActivity
|
|
|
} from "@/api/activity";
|
|
|
-import { getActivityDetail, getActivityCoupons } from "@/api/marketing";
|
|
|
-import type { PaginationProps } from "@pureadmin/table";
|
|
|
+import type { PaginationProps, TableColumnList } from "@pureadmin/table";
|
|
|
import { deviceDetection } from "@pureadmin/utils";
|
|
|
import { onMounted, reactive, ref, toRaw } from "vue";
|
|
|
import {
|
|
|
ElForm,
|
|
|
ElInput,
|
|
|
ElFormItem,
|
|
|
- ElSelect,
|
|
|
- ElOption,
|
|
|
ElDatePicker,
|
|
|
+ ElInputNumber,
|
|
|
ElDescriptions,
|
|
|
ElDescriptionsItem,
|
|
|
- ElTabs,
|
|
|
- ElTabPane,
|
|
|
- ElTable,
|
|
|
- ElTableColumn
|
|
|
+ ElTag,
|
|
|
+ ElRadioGroup,
|
|
|
+ ElRadioButton
|
|
|
} from "element-plus";
|
|
|
import {
|
|
|
initPagination,
|
|
|
@@ -36,6 +33,10 @@ import {
|
|
|
resetPagination,
|
|
|
updatePaginationData
|
|
|
} from "@/utils/paginationHelper";
|
|
|
+import ShopSelector from "../../components/ShopSelector.vue";
|
|
|
+import DeviceSelector from "../../components/DeviceSelector.vue";
|
|
|
+import ProductSelector from "../../components/ProductSelector.vue";
|
|
|
+import type { FormItemProps } from "./types";
|
|
|
|
|
|
interface SearchFormProps {
|
|
|
name: string;
|
|
|
@@ -53,18 +54,33 @@ export function useActivity() {
|
|
|
const dataList = ref([]);
|
|
|
const pagination = reactive<PaginationProps>(initPagination());
|
|
|
|
|
|
- const typeMap = {
|
|
|
- 1: "折扣活动",
|
|
|
- 2: "满减活动",
|
|
|
- 3: "赠品活动",
|
|
|
- 4: "秒杀活动"
|
|
|
+ const typeMap: Record<number, { text: string; type: string; color: string }> = {
|
|
|
+ 1: { text: "首单立减", type: "primary", color: "#409EFF" },
|
|
|
+ 2: { text: "优惠折扣", type: "success", color: "#67C23A" },
|
|
|
+ 3: { text: "商品满减", type: "warning", color: "#E6A23C" }
|
|
|
};
|
|
|
|
|
|
- const statusMap = {
|
|
|
+ const statusMap: Record<number, { text: string; type: string }> = {
|
|
|
0: { text: "草稿", type: "info" },
|
|
|
- 1: { text: "进行中", type: "success" },
|
|
|
- 2: { text: "已暂停", type: "warning" },
|
|
|
- 3: { text: "已结束", type: "info" }
|
|
|
+ 1: { text: "已发布", type: "primary" },
|
|
|
+ 2: { text: "进行中", type: "success" },
|
|
|
+ 3: { text: "已暂停", type: "warning" },
|
|
|
+ 4: { text: "已结束", type: "info" }
|
|
|
+ };
|
|
|
+
|
|
|
+ const applyScopeMap: Record<number, { text: string; type: string }> = {
|
|
|
+ 1: { text: "全部门店", type: "primary" },
|
|
|
+ 2: { text: "指定门店", type: "warning" }
|
|
|
+ };
|
|
|
+
|
|
|
+ const deviceScopeMap: Record<number, { text: string; type: string }> = {
|
|
|
+ 1: { text: "全部设备", type: "primary" },
|
|
|
+ 2: { text: "指定设备", type: "warning" }
|
|
|
+ };
|
|
|
+
|
|
|
+ const productScopeMap: Record<number, { text: string; type: string }> = {
|
|
|
+ 1: { text: "全部商品", type: "primary" },
|
|
|
+ 2: { text: "指定商品", type: "warning" }
|
|
|
};
|
|
|
|
|
|
const columns: TableColumnList = [
|
|
|
@@ -75,14 +91,32 @@ export function useActivity() {
|
|
|
},
|
|
|
{
|
|
|
label: "活动名称",
|
|
|
- prop: "name",
|
|
|
+ prop: "activityName",
|
|
|
minWidth: 150
|
|
|
},
|
|
|
{
|
|
|
label: "活动类型",
|
|
|
- prop: "type",
|
|
|
+ prop: "activityType",
|
|
|
minWidth: 100,
|
|
|
- formatter: ({ type }) => typeMap[type] || "未知"
|
|
|
+ cellRenderer: ({ row }) => {
|
|
|
+ const item = typeMap[row.activityType] || { text: "未知", type: "info" };
|
|
|
+ return <ElTag type={item.type}>{item.text}</ElTag>;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: "优惠规则",
|
|
|
+ prop: "discountValue",
|
|
|
+ minWidth: 120,
|
|
|
+ formatter: ({ activityType, discountValue, minAmount }) => {
|
|
|
+ if (activityType === 1) {
|
|
|
+ return `首单立减 ¥${discountValue || 0}`;
|
|
|
+ } else if (activityType === 2) {
|
|
|
+ return `${((discountValue || 0) * 10).toFixed(1)}折优惠`;
|
|
|
+ } else if (activityType === 3) {
|
|
|
+ return `满${minAmount || 0}减${discountValue || 0}`;
|
|
|
+ }
|
|
|
+ return "-";
|
|
|
+ }
|
|
|
},
|
|
|
{
|
|
|
label: "开始时间",
|
|
|
@@ -104,7 +138,7 @@ export function useActivity() {
|
|
|
minWidth: 100,
|
|
|
cellRenderer: ({ row }) => {
|
|
|
const item = statusMap[row.status] || { text: "未知", type: "info" };
|
|
|
- return <el-tag type={item.type}>{item.text}</el-tag>;
|
|
|
+ return <ElTag type={item.type}>{item.text}</ElTag>;
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
@@ -130,9 +164,8 @@ export function useActivity() {
|
|
|
pageSize: pagination.pageSize
|
|
|
};
|
|
|
|
|
|
- // 只添加非空的搜索条件
|
|
|
- if (form.name) searchParams.name = form.name;
|
|
|
- if (form.type !== undefined) searchParams.type = form.type;
|
|
|
+ if (form.name) searchParams.activityName = form.name;
|
|
|
+ if (form.type !== undefined) searchParams.activityType = form.type;
|
|
|
if (form.status !== undefined) searchParams.status = form.status;
|
|
|
|
|
|
const { data } = await getActivityList(searchParams);
|
|
|
@@ -192,116 +225,313 @@ export function useActivity() {
|
|
|
contentRenderer: () => (
|
|
|
<div>
|
|
|
<ElDescriptions column={2} border>
|
|
|
- <ElDescriptionsItem label="活动名称">{row.name}</ElDescriptionsItem>
|
|
|
- <ElDescriptionsItem label="活动类型">{typeMap[row.type]}</ElDescriptionsItem>
|
|
|
+ <ElDescriptionsItem label="活动名称">{row.activityName}</ElDescriptionsItem>
|
|
|
+ <ElDescriptionsItem label="活动类型">
|
|
|
+ <ElTag type={typeMap[row.activityType]?.type}>{typeMap[row.activityType]?.text}</ElTag>
|
|
|
+ </ElDescriptionsItem>
|
|
|
+ <ElDescriptionsItem label="优惠规则">
|
|
|
+ {row.activityType === 1 && `首单立减 ¥${row.discountValue}`}
|
|
|
+ {row.activityType === 2 && `${(row.discountValue * 10).toFixed(1)}折优惠`}
|
|
|
+ {row.activityType === 3 && `满${row.minAmount}减${row.discountValue}`}
|
|
|
+ </ElDescriptionsItem>
|
|
|
+ <ElDescriptionsItem label="最大优惠">
|
|
|
+ {row.maxDiscount ? `¥${row.maxDiscount}` : "不限制"}
|
|
|
+ </ElDescriptionsItem>
|
|
|
<ElDescriptionsItem label="开始时间">{dayjs(row.startTime).format("YYYY-MM-DD HH:mm:ss")}</ElDescriptionsItem>
|
|
|
<ElDescriptionsItem label="结束时间">{dayjs(row.endTime).format("YYYY-MM-DD HH:mm:ss")}</ElDescriptionsItem>
|
|
|
<ElDescriptionsItem label="状态">
|
|
|
- <el-tag type={statusMap[row.status]?.type}>{statusMap[row.status]?.text}</el-tag>
|
|
|
+ <ElTag type={statusMap[row.status]?.type}>{statusMap[row.status]?.text}</ElTag>
|
|
|
+ </ElDescriptionsItem>
|
|
|
+ <ElDescriptionsItem label="活动预算">
|
|
|
+ {row.totalBudget ? `¥${row.totalBudget}` : "不限制"}
|
|
|
+ </ElDescriptionsItem>
|
|
|
+ <ElDescriptionsItem label="适用范围">
|
|
|
+ <ElTag type={applyScopeMap[row.applyScope]?.type}>{applyScopeMap[row.applyScope]?.text}</ElTag>
|
|
|
+ </ElDescriptionsItem>
|
|
|
+ <ElDescriptionsItem label="设备范围">
|
|
|
+ <ElTag type={deviceScopeMap[row.deviceScope]?.type}>{deviceScopeMap[row.deviceScope]?.text}</ElTag>
|
|
|
+ </ElDescriptionsItem>
|
|
|
+ <ElDescriptionsItem label="商品范围">
|
|
|
+ <ElTag type={productScopeMap[row.productScope]?.type}>{productScopeMap[row.productScope]?.text}</ElTag>
|
|
|
</ElDescriptionsItem>
|
|
|
<ElDescriptionsItem label="创建时间">{dayjs(row.createTime).format("YYYY-MM-DD HH:mm:ss")}</ElDescriptionsItem>
|
|
|
- <ElDescriptionsItem label="活动说明" span={2}>{row.description || "暂无说明"}</ElDescriptionsItem>
|
|
|
+ <ElDescriptionsItem label="活动说明" span={2}>{row.activityDesc || "暂无说明"}</ElDescriptionsItem>
|
|
|
</ElDescriptions>
|
|
|
|
|
|
<div class="mt-4">
|
|
|
- <h4>统计数据</h4>
|
|
|
+ <h4 class="mb-2">统计数据</h4>
|
|
|
<ElDescriptions column={3}>
|
|
|
- <ElDescriptionsItem label="参与人数">1,234人</ElDescriptionsItem>
|
|
|
- <ElDescriptionsItem label="订单数">567单</ElDescriptionsItem>
|
|
|
- <ElDescriptionsItem label="总营收">¥89,456</ElDescriptionsItem>
|
|
|
+ <ElDescriptionsItem label="参与人数">{row.participantCount || 0}人</ElDescriptionsItem>
|
|
|
+ <ElDescriptionsItem label="订单数">{row.orderCount || 0}单</ElDescriptionsItem>
|
|
|
+ <ElDescriptionsItem label="总营收">¥{row.totalRevenue || 0}</ElDescriptionsItem>
|
|
|
</ElDescriptions>
|
|
|
</div>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ const formStyles = `
|
|
|
+ .activity-form { padding: 0; }
|
|
|
+ .form-section { margin-bottom: 16px; }
|
|
|
+ .section-title {
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #303133;
|
|
|
+ margin-bottom: 12px;
|
|
|
+ padding-bottom: 8px;
|
|
|
+ border-bottom: 1px solid #ebeef5;
|
|
|
+ }
|
|
|
+ .type-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-bottom: 16px; }
|
|
|
+ .type-card {
|
|
|
+ padding: 16px;
|
|
|
+ border: 2px solid #e4e7ed;
|
|
|
+ border-radius: 8px;
|
|
|
+ cursor: pointer;
|
|
|
+ transition: all 0.2s;
|
|
|
+ background: #fff;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+ .type-card:hover { border-color: var(--card-color); background: var(--card-bg); }
|
|
|
+ .type-card.active { border-color: var(--card-color); background: var(--card-bg); }
|
|
|
+ .type-card .title { font-size: 15px; font-weight: 600; color: #303133; margin-bottom: 4px; }
|
|
|
+ .type-card .desc { font-size: 12px; color: #909399; }
|
|
|
+ .scope-row { display: flex; gap: 24px; flex-wrap: wrap; }
|
|
|
+ .scope-item { display: flex; align-items: center; gap: 8px; }
|
|
|
+ .scope-item .label { font-size: 13px; color: #606266; min-width: 60px; }
|
|
|
+ .discount-preview {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ padding: 12px;
|
|
|
+ background: #f5f7fa;
|
|
|
+ border-radius: 6px;
|
|
|
+ font-size: 15px;
|
|
|
+ font-weight: 600;
|
|
|
+ margin-top: 12px;
|
|
|
+ }
|
|
|
+ .form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
|
|
|
+ @media (max-width: 768px) {
|
|
|
+ .type-cards { grid-template-columns: 1fr; }
|
|
|
+ .form-row { grid-template-columns: 1fr; }
|
|
|
+ .scope-row { flex-direction: column; }
|
|
|
+ }
|
|
|
+ `;
|
|
|
+
|
|
|
+ function renderForm(formData: FormItemProps) {
|
|
|
+ return (
|
|
|
+ <div class="activity-form">
|
|
|
+ <style>{formStyles}</style>
|
|
|
+
|
|
|
+ <div class="form-section">
|
|
|
+ <div class="section-title">选择活动类型</div>
|
|
|
+ <div class="type-cards">
|
|
|
+ {[1, 2, 3].map(type => {
|
|
|
+ const info = typeMap[type];
|
|
|
+ const bgColors = { 1: "#f0f9ff", 2: "#f0f9eb", 3: "#fdf6ec" };
|
|
|
+ return (
|
|
|
+ <div
|
|
|
+ class={`type-card ${formData.activityType === type ? 'active' : ''}`}
|
|
|
+ style={`--card-color: ${info.color}; --card-bg: ${bgColors[type]};`}
|
|
|
+ onClick={() => { formData.activityType = type; }}
|
|
|
+ >
|
|
|
+ <div class="title">{info.text}</div>
|
|
|
+ <div class="desc">
|
|
|
+ {type === 1 && "新用户首单优惠"}
|
|
|
+ {type === 2 && "全场折扣优惠"}
|
|
|
+ {type === 3 && "满额减免优惠"}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ })}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="form-section">
|
|
|
+ <div class="section-title">基本信息</div>
|
|
|
+ <ElForm label-width="80px" size="small">
|
|
|
+ <div class="form-row">
|
|
|
+ <ElFormItem label="活动名称" required>
|
|
|
+ <ElInput v-model={formData.activityName} placeholder="请输入活动名称" clearable maxlength={50} showWordLimit />
|
|
|
+ </ElFormItem>
|
|
|
+ <ElFormItem label="活动预算">
|
|
|
+ <ElInputNumber v-model={formData.totalBudget} min={0} precision={2} class="w-full" placeholder="可选" />
|
|
|
+ </ElFormItem>
|
|
|
+ </div>
|
|
|
+ <ElFormItem label="活动时间" required>
|
|
|
+ <div class="flex gap-2 w-full">
|
|
|
+ <ElDatePicker v-model={formData.startTime} type="datetime" placeholder="开始时间" class="flex-1" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" />
|
|
|
+ <span class="leading-8 text-gray-400">至</span>
|
|
|
+ <ElDatePicker v-model={formData.endTime} type="datetime" placeholder="结束时间" class="flex-1" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" />
|
|
|
+ </div>
|
|
|
+ </ElFormItem>
|
|
|
+ </ElForm>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="form-section">
|
|
|
+ <div class="section-title">优惠规则</div>
|
|
|
+ {!formData.activityType && <div style="text-align: center; color: #909399; padding: 20px;">请先选择活动类型</div>}
|
|
|
|
|
|
- <div class="mt-4">
|
|
|
- <h4>关联优惠券</h4>
|
|
|
- <div class="mb-2">
|
|
|
- <el-button type="primary" size="small">新建优惠券</el-button>
|
|
|
- <el-button type="success" size="small" class="ml-2">关联现有优惠券</el-button>
|
|
|
+ {formData.activityType === 1 && (
|
|
|
+ <div>
|
|
|
+ <ElForm label-width="80px" size="small">
|
|
|
+ <ElFormItem label="立减金额" required>
|
|
|
+ <ElInputNumber v-model={formData.discountValue} min={0.01} precision={2} class="w-full" placeholder="首单立减金额" prefix="¥" />
|
|
|
+ </ElFormItem>
|
|
|
+ </ElForm>
|
|
|
+ <div class="discount-preview" style="color: #409EFF;">新用户首单立减 ¥{formData.discountValue || '0.00'}</div>
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+
|
|
|
+ {formData.activityType === 2 && (
|
|
|
+ <div>
|
|
|
+ <ElForm label-width="80px" size="small">
|
|
|
+ <div class="form-row">
|
|
|
+ <ElFormItem label="折扣比例" required>
|
|
|
+ <ElInputNumber v-model={formData.discountValue} min={0.1} max={1} step={0.1} precision={1} class="w-full" placeholder="如 0.8 表示 8 折" />
|
|
|
+ </ElFormItem>
|
|
|
+ <ElFormItem label="最大优惠">
|
|
|
+ <ElInputNumber v-model={formData.maxDiscount} min={0} precision={2} class="w-full" placeholder="可选" prefix="¥" />
|
|
|
+ </ElFormItem>
|
|
|
+ </div>
|
|
|
+ </ElForm>
|
|
|
+ <div class="discount-preview" style="color: #67C23A;">
|
|
|
+ 全场 {formData.discountValue ? (formData.discountValue * 10).toFixed(1) : '0'} 折优惠
|
|
|
+ {formData.maxDiscount && ` (最高减¥${formData.maxDiscount})`}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+
|
|
|
+ {formData.activityType === 3 && (
|
|
|
+ <div>
|
|
|
+ <ElForm label-width="80px" size="small">
|
|
|
+ <div class="form-row">
|
|
|
+ <ElFormItem label="满减门槛" required>
|
|
|
+ <ElInputNumber v-model={formData.minAmount} min={0} precision={2} class="w-full" placeholder="订单满多少" prefix="¥" />
|
|
|
+ </ElFormItem>
|
|
|
+ <ElFormItem label="减免金额" required>
|
|
|
+ <ElInputNumber v-model={formData.discountValue} min={0.01} precision={2} class="w-full" placeholder="减免金额" prefix="¥" />
|
|
|
+ </ElFormItem>
|
|
|
+ </div>
|
|
|
+ </ElForm>
|
|
|
+ <div class="discount-preview" style="color: #E6A23C;">满 ¥{formData.minAmount || '0'} 减 ¥{formData.discountValue || '0'}</div>
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="form-section">
|
|
|
+ <div class="section-title">适用范围</div>
|
|
|
+ <div class="scope-row">
|
|
|
+ <div class="scope-item">
|
|
|
+ <span class="label">门店范围</span>
|
|
|
+ <ElRadioGroup v-model={formData.applyScope} size="small">
|
|
|
+ <ElRadioButton value={1}>全部</ElRadioButton>
|
|
|
+ <ElRadioButton value={2}>指定</ElRadioButton>
|
|
|
+ </ElRadioGroup>
|
|
|
+ {formData.applyScope === 2 && <ShopSelector v-model={formData.shopIds} />}
|
|
|
+ </div>
|
|
|
+ <div class="scope-item">
|
|
|
+ <span class="label">设备范围</span>
|
|
|
+ <ElRadioGroup v-model={formData.deviceScope} size="small">
|
|
|
+ <ElRadioButton value={1}>全部</ElRadioButton>
|
|
|
+ <ElRadioButton value={2}>指定</ElRadioButton>
|
|
|
+ </ElRadioGroup>
|
|
|
+ {formData.deviceScope === 2 && <DeviceSelector v-model={formData.deviceIds} />}
|
|
|
+ </div>
|
|
|
+ <div class="scope-item">
|
|
|
+ <span class="label">商品范围</span>
|
|
|
+ <ElRadioGroup v-model={formData.productScope} size="small">
|
|
|
+ <ElRadioButton value={1}>全部</ElRadioButton>
|
|
|
+ <ElRadioButton value={2}>指定</ElRadioButton>
|
|
|
+ </ElRadioGroup>
|
|
|
+ {formData.productScope === 2 && <ProductSelector v-model={formData.productIds} />}
|
|
|
</div>
|
|
|
- <ElTable data={[]} style="width: 100%" empty-text="暂无关联优惠券">
|
|
|
- <ElTableColumn prop="name" label="优惠券名称" width="150" />
|
|
|
- <ElTableColumn prop="type" label="类型" width="100" />
|
|
|
- <ElTableColumn prop="status" label="状态" width="100" />
|
|
|
- <ElTableColumn label="操作" width="150" v-slots={{
|
|
|
- default: ({ row }) => (
|
|
|
- <>
|
|
|
- <el-button link type="primary" size="small">查看详情</el-button>
|
|
|
- <el-button link type="danger" size="small" class="ml-2">解除关联</el-button>
|
|
|
- </>
|
|
|
- )
|
|
|
- }} />
|
|
|
- </ElTable>
|
|
|
</div>
|
|
|
</div>
|
|
|
- )
|
|
|
- });
|
|
|
+
|
|
|
+ <div class="form-section">
|
|
|
+ <div class="section-title">活动说明</div>
|
|
|
+ <ElForm size="small">
|
|
|
+ <ElFormItem label="">
|
|
|
+ <ElInput v-model={formData.activityDesc} type="textarea" rows={2} placeholder="请输入活动说明(可选)" maxlength={500} showWordLimit />
|
|
|
+ </ElFormItem>
|
|
|
+ </ElForm>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ function validateForm(formData: FormItemProps): boolean {
|
|
|
+ if (!formData.activityName) {
|
|
|
+ message("请输入活动名称", { type: "warning" });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!formData.activityType) {
|
|
|
+ message("请选择活动类型", { type: "warning" });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!formData.startTime) {
|
|
|
+ message("请选择开始时间", { type: "warning" });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!formData.endTime) {
|
|
|
+ message("请选择结束时间", { type: "warning" });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!formData.discountValue || formData.discountValue <= 0) {
|
|
|
+ message("请输入有效的优惠值", { type: "warning" });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (formData.activityType === 3 && (!formData.minAmount || formData.minAmount <= 0)) {
|
|
|
+ message("请输入有效的满减门槛", { type: "warning" });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (formData.applyScope === 2 && (!formData.shopIds || formData.shopIds.length === 0)) {
|
|
|
+ message("请选择至少一个门店", { type: "warning" });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (formData.deviceScope === 2 && (!formData.deviceIds || formData.deviceIds.length === 0)) {
|
|
|
+ message("请选择至少一个设备", { type: "warning" });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (formData.productScope === 2 && (!formData.productIds || formData.productIds.length === 0)) {
|
|
|
+ message("请选择至少一个商品", { type: "warning" });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
function handleEdit(row) {
|
|
|
- const formData = reactive({
|
|
|
+ const formData = reactive<FormItemProps>({
|
|
|
id: row.id,
|
|
|
- name: row.name,
|
|
|
- type: row.type,
|
|
|
+ activityName: row.activityName,
|
|
|
+ activityType: row.activityType,
|
|
|
+ activityDesc: row.activityDesc || "",
|
|
|
startTime: row.startTime,
|
|
|
endTime: row.endTime,
|
|
|
- description: row.description
|
|
|
+ status: row.status,
|
|
|
+ discountValue: row.discountValue,
|
|
|
+ minAmount: row.minAmount,
|
|
|
+ maxDiscount: row.maxDiscount,
|
|
|
+ applyScope: row.applyScope || 1,
|
|
|
+ deviceScope: row.deviceScope || 1,
|
|
|
+ productScope: row.productScope || 1,
|
|
|
+ totalBudget: row.totalBudget,
|
|
|
+ shopIds: row.shopIds || [],
|
|
|
+ deviceIds: row.deviceIds || [],
|
|
|
+ productIds: row.productIds || []
|
|
|
});
|
|
|
|
|
|
addDialog({
|
|
|
title: "编辑活动",
|
|
|
- width: "600px",
|
|
|
+ width: "800px",
|
|
|
draggable: true,
|
|
|
fullscreen: deviceDetection(),
|
|
|
- contentRenderer: () => (
|
|
|
- <ElForm label-width="100px">
|
|
|
- <ElFormItem label="活动名称" required>
|
|
|
- <ElInput v-model={formData.name} placeholder="请输入活动名称" clearable />
|
|
|
- </ElFormItem>
|
|
|
- <ElFormItem label="活动类型" required>
|
|
|
- <ElSelect v-model={formData.type} placeholder="请选择活动类型" class="w-full" clearable>
|
|
|
- <ElOption label="折扣活动" value={1} />
|
|
|
- <ElOption label="满减活动" value={2} />
|
|
|
- <ElOption label="赠品活动" value={3} />
|
|
|
- <ElOption label="秒杀活动" value={4} />
|
|
|
- </ElSelect>
|
|
|
- </ElFormItem>
|
|
|
- <ElFormItem label="开始时间" required>
|
|
|
- <ElDatePicker
|
|
|
- v-model={formData.startTime}
|
|
|
- type="datetime"
|
|
|
- placeholder="请选择开始时间"
|
|
|
- class="w-full"
|
|
|
- format="YYYY-MM-DD HH:mm:ss"
|
|
|
- value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
- />
|
|
|
- </ElFormItem>
|
|
|
- <ElFormItem label="结束时间" required>
|
|
|
- <ElDatePicker
|
|
|
- v-model={formData.endTime}
|
|
|
- type="datetime"
|
|
|
- placeholder="请选择结束时间"
|
|
|
- class="w-full"
|
|
|
- format="YYYY-MM-DD HH:mm:ss"
|
|
|
- value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
- />
|
|
|
- </ElFormItem>
|
|
|
- <ElFormItem label="活动说明">
|
|
|
- <ElInput
|
|
|
- v-model={formData.description}
|
|
|
- type="textarea"
|
|
|
- rows={4}
|
|
|
- placeholder="请输入活动说明"
|
|
|
- />
|
|
|
- </ElFormItem>
|
|
|
- </ElForm>
|
|
|
- ),
|
|
|
+ contentRenderer: () => renderForm(formData),
|
|
|
beforeSure: async (done) => {
|
|
|
- if (!formData.name) {
|
|
|
- message("请输入活动名称", { type: "warning" });
|
|
|
- return;
|
|
|
- }
|
|
|
+ if (!validateForm(formData)) return;
|
|
|
try {
|
|
|
- const { code } = await updateActivity(formData.id, toRaw(formData));
|
|
|
+ const { code } = await updateActivity(formData.id!, toRaw(formData));
|
|
|
if (code === 200) {
|
|
|
message("编辑成功", { type: "success" });
|
|
|
done();
|
|
|
@@ -315,79 +545,33 @@ export function useActivity() {
|
|
|
}
|
|
|
|
|
|
function handleAdd() {
|
|
|
- const formData = reactive({
|
|
|
- name: "",
|
|
|
- type: undefined,
|
|
|
+ const formData = reactive<FormItemProps>({
|
|
|
+ activityName: "",
|
|
|
+ activityType: undefined,
|
|
|
+ activityDesc: "",
|
|
|
startTime: "",
|
|
|
endTime: "",
|
|
|
- description: ""
|
|
|
+ status: 0,
|
|
|
+ discountValue: null,
|
|
|
+ minAmount: null,
|
|
|
+ maxDiscount: null,
|
|
|
+ applyScope: 1,
|
|
|
+ deviceScope: 1,
|
|
|
+ productScope: 1,
|
|
|
+ totalBudget: null,
|
|
|
+ shopIds: [],
|
|
|
+ deviceIds: [],
|
|
|
+ productIds: []
|
|
|
});
|
|
|
|
|
|
addDialog({
|
|
|
title: "新增活动",
|
|
|
- width: "600px",
|
|
|
+ width: "800px",
|
|
|
draggable: true,
|
|
|
fullscreen: deviceDetection(),
|
|
|
- contentRenderer: () => (
|
|
|
- <ElForm label-width="100px">
|
|
|
- <ElFormItem label="活动名称" required>
|
|
|
- <ElInput v-model={formData.name} placeholder="请输入活动名称" clearable />
|
|
|
- </ElFormItem>
|
|
|
- <ElFormItem label="活动类型" required>
|
|
|
- <ElSelect v-model={formData.type} placeholder="请选择活动类型" class="w-full" clearable>
|
|
|
- <ElOption label="折扣活动" value={1} />
|
|
|
- <ElOption label="满减活动" value={2} />
|
|
|
- <ElOption label="赠品活动" value={3} />
|
|
|
- <ElOption label="秒杀活动" value={4} />
|
|
|
- </ElSelect>
|
|
|
- </ElFormItem>
|
|
|
- <ElFormItem label="开始时间" required>
|
|
|
- <ElDatePicker
|
|
|
- v-model={formData.startTime}
|
|
|
- type="datetime"
|
|
|
- placeholder="请选择开始时间"
|
|
|
- class="w-full"
|
|
|
- format="YYYY-MM-DD HH:mm:ss"
|
|
|
- value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
- />
|
|
|
- </ElFormItem>
|
|
|
- <ElFormItem label="结束时间" required>
|
|
|
- <ElDatePicker
|
|
|
- v-model={formData.endTime}
|
|
|
- type="datetime"
|
|
|
- placeholder="请选择结束时间"
|
|
|
- class="w-full"
|
|
|
- format="YYYY-MM-DD HH:mm:ss"
|
|
|
- value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
- />
|
|
|
- </ElFormItem>
|
|
|
- <ElFormItem label="活动说明">
|
|
|
- <ElInput
|
|
|
- v-model={formData.description}
|
|
|
- type="textarea"
|
|
|
- rows={4}
|
|
|
- placeholder="请输入活动说明"
|
|
|
- />
|
|
|
- </ElFormItem>
|
|
|
- </ElForm>
|
|
|
- ),
|
|
|
+ contentRenderer: () => renderForm(formData),
|
|
|
beforeSure: async (done) => {
|
|
|
- if (!formData.name) {
|
|
|
- message("请输入活动名称", { type: "warning" });
|
|
|
- return;
|
|
|
- }
|
|
|
- if (!formData.type) {
|
|
|
- message("请选择活动类型", { type: "warning" });
|
|
|
- return;
|
|
|
- }
|
|
|
- if (!formData.startTime) {
|
|
|
- message("请选择开始时间", { type: "warning" });
|
|
|
- return;
|
|
|
- }
|
|
|
- if (!formData.endTime) {
|
|
|
- message("请选择结束时间", { type: "warning" });
|
|
|
- return;
|
|
|
- }
|
|
|
+ if (!validateForm(formData)) return;
|
|
|
try {
|
|
|
const { code } = await createActivity(toRaw(formData));
|
|
|
if (code === 200) {
|
|
|
@@ -422,6 +606,9 @@ export function useActivity() {
|
|
|
pagination,
|
|
|
typeMap,
|
|
|
statusMap,
|
|
|
+ applyScopeMap,
|
|
|
+ deviceScopeMap,
|
|
|
+ productScopeMap,
|
|
|
onSearch,
|
|
|
resetForm,
|
|
|
handleAdd,
|
|
|
@@ -434,4 +621,4 @@ export function useActivity() {
|
|
|
handleSizeChange,
|
|
|
handleCurrentChange
|
|
|
};
|
|
|
-}
|
|
|
+}
|