<template>
|
<div>
|
<Card>
|
<!-- 搜索表单 -->
|
<Form
|
ref="searchForm"
|
@keydown.enter.native="handleSearch"
|
:model="searchForm"
|
inline
|
:label-width="80"
|
class="search-form"
|
>
|
<FormItem label="活动名称" prop="activityName">
|
<Input
|
type="text"
|
v-model="searchForm.activityName"
|
placeholder="请输入活动名称"
|
clearable
|
@on-clear="handleSearch"
|
style="width: 180px"
|
/>
|
</FormItem>
|
<FormItem label="报名开始时间" prop="beginTime">
|
<DatePicker
|
:value="searchForm.beginTime"
|
type="datetime"
|
placeholder="选择开始时间"
|
style="width: 180px"
|
value-format="YYYY-MM-DD HH:mm:ss"
|
@on-change="handleSearch('beginTime', $event)"
|
@on-clear="handleSearch"
|
></DatePicker>
|
</FormItem>
|
<FormItem label="报名结束时间" prop="endTime">
|
<DatePicker
|
value-format="YYYY-MM-DD HH:mm:ss"
|
:value="searchForm.endTime"
|
type="datetime"
|
placeholder="选择结束时间"
|
style="width: 180px"
|
@on-clear="handleSearch"
|
@on-change="handleSearch('endTime', $event)"
|
></DatePicker>
|
</FormItem>
|
<Button
|
@click="handleSearch"
|
type="primary"
|
icon="ios-search"
|
class="search-btn"
|
>搜索</Button>
|
<Button
|
@click="resetSearch"
|
icon="md-refresh"
|
style="margin-left: 8px"
|
>重置</Button>
|
</Form>
|
|
<!-- 操作按钮 -->
|
<Row class="operation">
|
<Button @click="openAdd" type="primary" icon="md-add">新增抽奖活动</Button>
|
</Row>
|
|
<!-- 活动表格 -->
|
<Table
|
:loading="loading"
|
border
|
:columns="columns"
|
:data="activityList"
|
ref="table"
|
class="activity-table"
|
>
|
<!-- 操作按钮插槽 -->
|
<template slot-scope="{ row }" slot="action">
|
<div class="action-btns">
|
<Button
|
type="primary"
|
size="small"
|
@click="publishPrizeActivity(row)"
|
:loading="row.statusLoading"
|
>
|
{{row.enableStatus === 'ON' ? '关闭' : '开启'}}
|
</Button>
|
<Button
|
type="info"
|
size="small"
|
@click="detail(row)"
|
>详情</Button>
|
<Button
|
type="info"
|
size="small"
|
:disabled="!row.canSet"
|
@click="setPrize(row)"
|
>奖品设置</Button>
|
<!-- <Button-->
|
<!-- type="info"-->
|
<!-- size="small"-->
|
<!-- @click="openEdit(row)"-->
|
<!-- >编辑</Button>-->
|
<!-- <Button-->
|
<!-- type="error"-->
|
<!-- size="small"-->
|
<!-- @click="delById(row)"-->
|
<!-- >删除</Button>-->
|
|
</div>
|
</template>
|
</Table>
|
|
<!-- 分页 -->
|
<Row type="flex" justify="end" class="page-footer">
|
<Page
|
:current="searchForm.pageNumber"
|
:total="total"
|
:page-size="searchForm.pageSize"
|
@on-change="changePage"
|
@on-page-size-change="changePageSize"
|
:page-size-opts="[10, 20, 50]"
|
size="small"
|
show-total
|
show-elevator
|
show-sizer
|
></Page>
|
</Row>
|
|
<!-- 活动编辑/新增模态框 -->
|
<Modal
|
v-model="modelShow"
|
:title="modelTitle"
|
@on-cancel="modelClose"
|
width="800"
|
:mask-closable="false"
|
>
|
<Form ref="form" :model="activityFrom" :label-width="100" :rules="rules" >
|
<Row :gutter="16">
|
<Col span="12">
|
<FormItem label="活动名称" prop="activityName">
|
<Input
|
v-model="activityFrom.activityName"
|
placeholder="请输入活动名称"
|
clearable
|
/>
|
</FormItem>
|
</Col>
|
<Col span="12">
|
<FormItem label="活动描述" prop="activityDes" :label-width="100">
|
<Input v-model="activityFrom.activityDes" type="textarea" :autosize="{minRows: 2,maxRows: 5}" placeholder="请输入"></Input>
|
</FormItem>
|
</Col>
|
<Col span="12">
|
<FormItem label="开始时间" prop="beginTime">
|
<DatePicker
|
v-model="activityFrom.beginTime"
|
type="datetime"
|
placeholder="选择开始时间"
|
style="width: 180px"
|
></DatePicker>
|
</FormItem>
|
</Col>
|
<Col span="12">
|
<FormItem label="结束时间" prop="endTime">
|
<DatePicker
|
v-model="activityFrom.endTime"
|
type="datetime"
|
placeholder="请选择结束时间"
|
style="width: 180px"
|
></DatePicker>
|
</FormItem>
|
</Col>
|
<Col span="12">
|
<FormItem label="每日最大抽奖上限" prop="maxPrize">
|
<InputNumber
|
v-model="activityFrom.maxPrize"
|
:min="1"
|
placeholder="请输入每日最大抽奖上限"
|
style="width: 180px"
|
/>
|
</FormItem>
|
</Col>
|
<Col span="12">
|
<FormItem label="初始化抽奖次数" prop="prizeNum" >
|
<InputNumber
|
:min="1"
|
v-model="activityFrom.prizeNum"
|
placeholder="请输入初始化抽奖次数"
|
style="width: 180px"
|
/>
|
</FormItem>
|
</Col>
|
<Col span="24">
|
<FormItem label="活动图片:" prop="activityImg">
|
<Upload
|
v-if="!imgTempUrl"
|
:before-upload="(file) => handleBeforeUpload(file, 'content')"
|
:format="['jpg','jpeg','png','gif']"
|
:max-size="20480"
|
action=""
|
accept="image/*"
|
>
|
<Button icon="ios-cloud-upload-outline">上传封面图片</Button>
|
</Upload>
|
<div v-else class="upload-file-info">
|
<img :src="imgTempUrl" alt="活动图片" class="preview-image-limit">
|
<Button type="text" @click="handleRemove('content')">删除</Button>
|
</div>
|
|
<!-- 基于elementUi的上传组件 el-upload end-->
|
</FormItem>
|
</Col>
|
<Col span="24">
|
<FormItem label="活动封面:" prop="activityCover">
|
<Upload
|
v-if="!coverTempUrl"
|
:before-upload="(file) => handleBeforeUpload(file, 'cover')"
|
:format="['jpg','jpeg','png','gif']"
|
:max-size="20480"
|
action=""
|
accept="image/*"
|
>
|
<Button icon="ios-cloud-upload-outline">上传封面图片</Button>
|
</Upload>
|
<div v-else class="upload-file-info">
|
<img :src="coverTempUrl" alt="活动图片" class="preview-image-limit">
|
<Button type="text" @click="handleRemove('cover')">删除</Button>
|
</div>
|
|
<!-- 基于elementUi的上传组件 el-upload end-->
|
</FormItem>
|
</Col>
|
</Row>
|
</Form>
|
|
<div slot="footer">
|
<Button @click="modelClose">取消</Button>
|
<Button type="primary" :loading="submitLoading" @click="saveOrUpdate">提交</Button>
|
</div>
|
</Modal>
|
<!-- 详情-->
|
<Modal
|
v-model="infoModalShow"
|
title="活动详情"
|
@on-cancel="infoModelClose"
|
width="800"
|
:mask-closable="false"
|
>
|
<div class="detail-container">
|
<Row :gutter="16">
|
<Col span="12">
|
<div class="detail-item">
|
<label>活动名称:</label>
|
<span>{{ detailData.activityName }}</span>
|
</div>
|
</Col>
|
<Col span="12">
|
<div class="detail-item">
|
<label>活动描述:</label>
|
<span>{{ detailData.activityDes}}</span>
|
</div>
|
</Col>
|
<Col span="12">
|
<div class="detail-item">
|
<label>开始时间:</label>
|
<span>{{ formatDate(detailData.beginTime) }}</span>
|
</div>
|
</Col>
|
<Col span="12">
|
<div class="detail-item">
|
<label>结束时间:</label>
|
<span>{{ formatDate(detailData.endTime) }}</span>
|
</div>
|
</Col>
|
<Col span="12">
|
<div class="detail-item">
|
<label>每日最大抽奖上限:</label>
|
<span>{{ detailData.maxPrize || '0' }}</span>
|
</div>
|
</Col>
|
<Col span="12">
|
<div class="detail-item">
|
<label>初始化抽奖次数:</label>
|
<span>{{ detailData.prizeNum || '0' }}</span>
|
</div>
|
</Col>
|
<Col span="24">
|
<div class="detail-item">
|
<label>活动状态:</label>
|
<Tag :color="detailData.enableStatus === 'ON' ? 'success' : 'default'">
|
{{ detailData.enableStatus === 'ON' ? '已启用' : '未启用' }}
|
</Tag>
|
</div>
|
</Col>
|
<Col span="24">
|
<div class="detail-item">
|
<label>活动图片:</label>
|
<div v-if="detailData.activityImgUrl" class="detail-image">
|
<img :src="detailData.activityImgUrl" alt="活动图片" class="preview-image-limit">
|
</div>
|
<span v-else>-</span>
|
</div>
|
</Col>
|
<Col span="24">
|
<div class="detail-item">
|
<label>活动封面:</label>
|
<div v-if="detailData.activityCoverUrl" class="detail-image">
|
<img
|
:src="detailData.activityCoverUrl" alt="活动封面"
|
class="preview-image-limit"
|
>
|
</div>
|
<span v-else>-</span>
|
</div>
|
</Col>
|
<Col span="24">
|
<div class="detail-item">
|
<label>奖品:</label>
|
<div style="width: 100%; overflow-y: auto; padding-bottom: 8px; box-sizing: border-box;height: 150px">
|
<div v-if="detailData.prizes && detailData.prizes.length > 0" class="prize-list">
|
<div v-for="(prize, index) in detailData.prizes" :key="index" class="prize-item">
|
<div class="prize-header">
|
<span class="prize-name">{{ prize.prizeName }}</span>
|
<Tag v-if="prize.prizeType">
|
{{ replaceText(prize.prizeType) }}
|
</Tag>
|
</div>
|
<div class="prize-content">
|
<p v-if="prize.prizeContent">{{ prize.prizeContent }}</p>
|
<Row :gutter="16" class="prize-info">
|
<Col span="12">
|
<span>总数: {{ prize.prizeNum}}</span>
|
</Col>
|
<Col span="12">
|
<span>剩余:
|
<span>
|
{{ prize.remainNum }}
|
</span>
|
</span>
|
</Col>
|
<Col span="12">
|
<span>概率: {{ prize.prizeProbability}}%</span>
|
</Col>
|
</Row>
|
</div>
|
</div>
|
</div>
|
<div v-else class="no-prize">
|
<span>暂无奖品信息</span>
|
</div>
|
</div>
|
|
|
</div>
|
</Col>
|
</Row>
|
</div>
|
|
</Modal>
|
|
<Modal
|
v-model="prizeSettingShow"
|
title="奖品设置"
|
@on-cancel="prizeSettingModelClose"
|
width="1200"
|
:mask-closable="false">
|
<!-- 奖品部分 -->
|
|
|
<Form ref="activityPrizeForm" :label-width="100" >
|
<Col span="24">
|
<FormItem label="奖品列表:">
|
<Table
|
:loading="prizeLoading"
|
border
|
:columns="prizeColumns"
|
:data="prizeList"
|
ref="table"
|
class="prize-table"
|
>
|
<template slot-scope="{ row }" slot="prizeCoverUrl">
|
<img
|
:src="row.prizeCoverUrl"
|
alt="奖品封面"
|
class="thumbnail"
|
>
|
</template>
|
<template slot-scope="{ row }" slot="action">
|
<Button
|
@click="choicePrize(row)"
|
:disabled="isPrizeChosen(row.id)"
|
type="primary"
|
icon="md-add"
|
>
|
{{ isPrizeChosen(row.id) ? '已添加' : '添加' }}
|
</Button>
|
</template>
|
</Table>
|
<Row type="flex" justify="end" class="page-footer">
|
<Page
|
:current="prizeSearchForm.pageNumber"
|
:total="prizeTotal"
|
:page-size="prizeSearchForm.pageSize"
|
@on-change="prizeChangePage"
|
@on-page-size-change="prizeChangePageSize"
|
:page-size-opts="[10, 20, 50]"
|
size="small"
|
show-total
|
show-elevator
|
show-sizer
|
></Page>
|
</Row>
|
</FormItem>
|
</Col>
|
<Col span="24">
|
<FormItem label="已选奖品:">
|
<!-- 遍历已选奖品,并可以设置数量等属性 -->
|
<Table
|
:data="choiceData"
|
:columns="choiceColumns"
|
border
|
style="margin-top: 10px;"
|
:loading="choiceLoading"
|
>
|
<!-- 奖品图片 slot -->
|
<template slot-scope="{ row }" slot="prizeCoverUrl">
|
<img :src="row.prizeCoverUrl" alt="奖品封面" style="width: 50px; height: 50px; object-fit: cover;">
|
</template>
|
<!-- 数量 slot -->
|
<template slot-scope="{ row, index }" slot="maxPreDay">
|
<InputNumber
|
v-model="row.maxPreDay"
|
:min="1"
|
:max="999999"
|
placeholder="请输入每日最大中奖数"
|
style="width: 100%"
|
@on-change="(val) => handleMaxPreDayChange(val, index)"
|
></InputNumber>
|
</template>
|
<template slot-scope="{ row, index }" slot="prizeNum">
|
<InputNumber
|
v-model="row.prizeNum"
|
:min="1"
|
:max="999999"
|
placeholder="数量"
|
style="width: 100%"
|
@on-change="(val) => handlePrizeNumChange(val, index)"
|
></InputNumber>
|
</template>
|
|
<!-- 概率 slot -->
|
<template slot-scope="{ row, index }" slot="prizeProbability">
|
<Input
|
v-model="row.prizeProbability"
|
placeholder="0.01"
|
style="width: 100%"
|
@on-blur="(e) => handleProbabilityInput(e, index)"
|
@on-enter="(e) => handleProbabilityInput(e, index)"
|
></Input>
|
</template>
|
|
<!-- 操作 slot -->
|
<template slot-scope="{ row, index }" slot="action">
|
<Button type="error" size="small" icon="md-close" @click="removePrize(index)">移除</Button>
|
</template>
|
</Table>
|
<!-- 如果没有选择任何奖品时的提示 -->
|
<div v-if="choiceData.length === 0" style="text-align: center; color: #999; padding: 20px;">
|
尚未选择任何奖品
|
</div>
|
|
</FormItem>
|
</Col>
|
</Form>
|
<div slot="footer">
|
<Button @click="prizeSettingModelClose">取消</Button>
|
<Button type="primary" :loading="choiceSubmitLoading" @click="choiceSubmit">提交</Button>
|
</div>
|
</Modal>
|
|
</Card>
|
</div>
|
</template>
|
|
<script>
|
import {
|
getPage as getPrizePage
|
} from '@/api/prize.js'
|
import {
|
getPage,
|
detail,
|
edit,
|
add,
|
del,
|
addActivityRefPrizeList,
|
getActivityRefPrizeByActivityId,
|
publishPrizeActivity
|
} from '@/api/activity-prize.js'
|
import {delByKey, uploadFileByLmk} from "../../api/common";
|
|
export default {
|
name: "activityPrize",
|
|
data() {
|
return {
|
//奖品设置弹窗
|
choiceLoading:false,
|
choiceSubmitLoading:false,
|
prizeTotal:0,
|
choiceData:[],
|
choiceColumns:[
|
{
|
title: '奖品图片',
|
slot: 'prizeCoverUrl',
|
width: 80,
|
align: 'center'
|
},
|
{
|
title: '奖品名称',
|
key: 'prizeName',
|
minWidth: 120
|
},
|
{
|
title: '奖品类型',
|
slot: 'prizeType',
|
width: 100,
|
render: (h, params) => {
|
if (params.row.prizeType === "coupon") {
|
return h("Tag", {props: {color: "red"}}, "优惠券");
|
} else {
|
return h("Tag", {props: {color: "purple"}}, "未知");
|
}
|
}
|
},
|
{
|
title: '每日最大中奖数',
|
slot: 'maxPreDay',
|
width: 120
|
},
|
{
|
title: '数量',
|
slot: 'prizeNum',
|
width: 120
|
},
|
{
|
title: '中将概率不能为空',
|
slot: 'prizeProbability',
|
width: 120
|
},
|
{
|
title: '操作',
|
slot: 'action',
|
width: 80,
|
align: 'center'
|
}
|
],
|
|
prizeLoading:false,
|
prizeList:[],
|
prizeSettingShow:false,
|
prizeColumns:[
|
{
|
title: '奖品封面',
|
key: 'prizeCoverUrl',
|
slot:'prizeCoverUrl',
|
align: 'center',
|
minWidth: 100,
|
},
|
{
|
title: '奖品名称',
|
key: 'prizeName',
|
minWidth: 100,
|
},
|
{
|
title: '奖品类型',
|
key: 'prizeType',
|
minWidth: 100,
|
render: (h, params) => {
|
if (params.row.prizeType === "coupon") {
|
return h("Tag", {props: {color: "red"}}, "优惠券");
|
} else {
|
return h("Tag", {props: {color: "purple"}}, "未知");
|
}
|
}
|
},
|
{
|
title: '奖品内容',
|
key: 'prizeContent',
|
minWidth: 100,
|
},
|
{
|
title: '奖品描述',
|
key: 'prizeDes',
|
minWidth: 100,
|
},
|
{
|
title:'操作',
|
slot: 'action',
|
width: 200,
|
align:'center',
|
fixed:'right'
|
}
|
],
|
activityPrizeId:null,
|
prizeSearchForm:{
|
prizeName:'',
|
prizeType:'',
|
pageSize:10,
|
pageNumber:1,
|
},
|
|
infoModalShow:false,
|
detailData: {},
|
modelShow:false,
|
modelTitle:'',
|
rules: {
|
activityDes:[
|
{ required: true, message: '请输入活动描述', trigger: 'blur' },
|
{ max: 100, message: '长度不能超过100个字符', trigger: 'blur' }
|
],
|
activityName: [
|
{ required: true, message: '请输入活动名称', trigger: 'blur' },
|
{ max: 50, message: '长度不能超过50个字符', trigger: 'blur' }
|
],
|
beginTime: [
|
{ type:'date',required: true, message: '请选择开始时间', trigger: 'change'},
|
{
|
trigger: ['change' ],
|
validator: this.validateBeginTime
|
}
|
],
|
endTime: [
|
{ type:'date',required: true, message: '请选择结束时间', trigger: 'change'},
|
|
{ trigger: ['change'] ,
|
validator: this.validateEndTime
|
}
|
],
|
maxPrize: [
|
{required: true, type: 'number', message: '请输入每日最大抽奖上限', trigger: 'blur'},
|
{type: 'number', min: 1, message: '必须大于0', trigger: 'blur'}
|
],
|
prizeNum: [
|
{required: true, type: 'number', message: '请输入初始化抽奖次数', trigger: 'blur'},
|
{type: 'number', min: 1, message: '必须大于0', trigger: 'blur'}
|
],
|
activityCover: [
|
{required: true, message: '请选择活动封面', trigger: 'blur'}
|
],
|
activityImg: [
|
{required: true, message: '请选择活动图片', trigger: 'blur'}
|
],
|
},
|
activityFrom:{
|
id:'',
|
activityName:'',
|
activityDes:'',
|
beginTime:'',
|
endTime:'',
|
maxPrize:0,
|
prizeNum:0,
|
activityImg:'',
|
activityCover:'',
|
enableStatus:''
|
},
|
loading:false,
|
columns:[
|
{
|
title: '活动名称',
|
key: 'activityName',
|
minWidth: 100,
|
},
|
{
|
title: '活动描述',
|
key: 'activityDes',
|
minWidth: 100,
|
},
|
{
|
title: '开始时间',
|
key: 'beginTime',
|
minWidth: 100,
|
render: (h, params) => {
|
return h('div', [
|
h('div', this.formatDate(params.row.beginTime)),
|
])
|
}
|
},
|
{
|
title: '结束时间',
|
key: 'endTime',
|
minWidth: 100,
|
render: (h, params) => {
|
return h('div', [
|
h('div', this.formatDate(params.row.endTime)),
|
])
|
}
|
},
|
{
|
title: '每日最大抽奖上限',
|
key: 'maxPrize',
|
minWidth: 100,
|
},
|
{
|
title: '初始化抽奖次数',
|
key: 'prizeNum',
|
minWidth: 100,
|
},
|
{
|
title: '是否开启活动',
|
key: 'enableStatus',
|
minWidth: 100,
|
render: (h, params) => {
|
return h('Tag', {
|
props: {
|
color: params.row.enableStatus === 'ON' ? 'green' : 'default'
|
}
|
}, params.row.enableStatus === 'ON' ? '开启' : '关闭')
|
}
|
},
|
{
|
title: '操作',
|
slot: 'action',
|
width: 280,
|
align: 'center',
|
fixed: 'right'
|
},
|
],
|
activityList:[],
|
total:0,
|
searchForm:{
|
pageSize:10,
|
pageNumber:1,
|
activityName:'',
|
endTime:'',
|
beginTime:'',
|
},
|
submitLoading:false,
|
activityCover:null,
|
activityImg:null,
|
|
coverTempUrl:null,
|
imgTempUrl:null,
|
|
}
|
},
|
// 在组件创建前注册
|
beforeCreate() {
|
|
},
|
mounted() {
|
this.init();
|
},
|
methods: {
|
handleProbabilityInput(event, index) {
|
const inputValue = event.target.value;
|
let numericValue = parseFloat(inputValue);
|
|
if (isNaN(numericValue)) {
|
this.choiceData[index].prizeProbabilityDisplay = '0.01';
|
this.choiceData[index].prizeProbability = 0.01;
|
this.$Message.warning('请输入有效的数字');
|
return;
|
}
|
|
// 限制范围
|
if (numericValue < 0.01) {
|
numericValue = 0.01;
|
this.$Message.warning('中奖概率不能小于0.01');
|
} else if (numericValue > 100) {
|
numericValue = 100;
|
this.$Message.warning('中奖概率不能大于100');
|
}
|
|
// 保持2位小数
|
const fixedValue = parseFloat(numericValue.toFixed(2));
|
this.choiceData[index].prizeProbabilityDisplay = fixedValue.toString();
|
this.choiceData[index].prizeProbability = fixedValue;
|
|
// 更新后端字段
|
this.choiceData[index].probability = (fixedValue / 100).toFixed(4);
|
},
|
choiceSubmit(){
|
addActivityRefPrizeList(this.activityPrizeId,this.choiceData).then(res =>{
|
if (res.code === 200){
|
this.$Message.success(res.msg)
|
this.prizeSettingModelClose()
|
}else{
|
this.$Message.error(res.msg)
|
}
|
})
|
},
|
|
// 格式化奖品类型
|
replaceText(type) {
|
if (type === "coupon") {
|
return "优惠券";
|
}
|
return type; // 如果不是目标词,返回原文本
|
},
|
|
// 数量变化处理
|
handlePrizeNumChange(value, index) {
|
if (value === null || value < 1) {
|
this.choiceData[index].prizeNum = 1;
|
this.$Message.warning('数量不能小于1');
|
} else {
|
this.choiceData[index].prizeNum = value;
|
}
|
},
|
// 数量变化处理
|
handleMaxPreDayChange(value, index) {
|
if (value === null || value < 1) {
|
this.choiceData[index].maxPreDay = 1;
|
this.$Message.warning('数量不能小于1');
|
} else {
|
this.choiceData[index].maxPreDay = value;
|
}
|
},
|
|
// 移除已选奖品
|
removePrize(index) {
|
this.choiceData.splice(index, 1);
|
this.$Message.info('已移除奖品');
|
},
|
// 检查奖品是否已被选择
|
isPrizeChosen(prizeId) {
|
return this.choiceData.some(item => item.prizeId === prizeId);
|
},
|
choicePrize(row){
|
//判断数组长度
|
if(this.choiceData.length >= 5){
|
this.$Message.warning("最多添加5个奖品")
|
return;
|
}
|
console.log(row.prizeId)
|
if (this.isPrizeChosen(row.id)){
|
|
this.$Message.warning("已添加")
|
return;
|
}
|
this.choiceLoading = true;
|
|
const prizeToAdd = {
|
prizeCoverUrl:row.prizeCoverUrl,
|
prizeType: row.prizeType,
|
prizeName: row.prizeName,
|
prizeNum: 1, // 默认数量为1
|
maxPreDay:1,
|
prizeProbability:0.01,
|
prizeId:row.id,
|
prizeContent:row.prizeContent
|
// 可以添加其他扩展属性,如:
|
// sort: this.choiceData.length + 1 // 排序
|
};
|
this.choiceData.push(prizeToAdd);
|
this.choiceLoading = false;
|
this.$Message.success('添加成功!');
|
|
},
|
getPrizeList(){
|
this.prizeLoading = true;
|
getPrizePage(this.prizeSearchForm).then(res =>{
|
this.prizeLoading = false;
|
if (res.code === 200){
|
this.prizeList = res.data;
|
this.prizeTotal = res.total
|
}else {
|
this.$Message.error(res.msg)
|
}
|
})
|
},
|
|
//规则
|
validateBeginTime(rule, value, callback) {
|
console.log("触发验证")
|
// 校验必填
|
if (!value) {
|
return callback(new Error('请选择开始时间')); // ✅ 正确提示
|
}
|
console.log("表单开始验证开始时间")
|
console.log(value)
|
console.log(this.activityFrom.beginTime)
|
// 校验开始时间不能晚于结束时间
|
if (new Date(this.activityFrom.beginTime) > new Date(this.activityFrom.endTime) ) {
|
return callback(new Error('开始时间不能晚于结束时间'));
|
}
|
callback(); // 验证通过
|
},
|
validateEndTime(rule, value, callback) {
|
// 校验必填
|
if (!value) {
|
return callback(new Error('请选择结束时间')); // ✅ 正确提示
|
}
|
// 校验结束时间不能早于开始时间
|
if (new Date(this.activityFrom.endTime) < new Date(this.activityFrom.beginTime)) {
|
return callback(new Error('结束时间不能早于开始时间'));
|
}
|
callback(); // 验证通过
|
},
|
|
//奖品设置
|
setPrize(row){
|
//判断是否启动,若启动则,无法编辑
|
if("ON" === row.enableStatus){
|
this.$Message.error("抽奖已开启,不能编辑!")
|
return
|
}
|
//判断是否已有奖品有的话不让设置
|
this.activityPrizeId = row.id;
|
this.getPrizeList();
|
this.prizeSettingShow = true;
|
|
this.choiceLoading = true;
|
getActivityRefPrizeByActivityId(row.id).then(res =>{
|
this.choiceLoading = false;
|
if (res.code === 200){
|
res.data.forEach(item =>{
|
item.id =null;
|
})
|
this.choiceData = res.data
|
}
|
|
})
|
|
},
|
prizeSettingModelClose(){
|
this.activityPrizeId = null;
|
this.prizeSettingShow = false;
|
this.choiceData = [];
|
},
|
//文本转换
|
formatDate(date, format = 'YYYY-MM-DD HH:mm:ss') {
|
if (!date) return '';
|
|
const d = new Date(date);
|
if (isNaN(d.getTime())) return '';
|
|
const padZero = (num) => String(num).padStart(2, '0'); // 更可靠的补零方法
|
|
const year = d.getFullYear();
|
const month = padZero(d.getMonth() + 1); // 月份 0-11 → +1
|
const day = padZero(d.getDate());
|
const hours = padZero(d.getHours());
|
const minutes = padZero(d.getMinutes());
|
const seconds = padZero(d.getSeconds());
|
return format
|
.replace('YYYY', year)
|
.replace('MM', month)
|
.replace('DD', day)
|
.replace('HH', hours)
|
.replace('mm', minutes)
|
.replace('ss', seconds);
|
},
|
resetSearch(){
|
this.$refs.searchForm.resetFields()
|
this.searchForm.pageNumber = 1
|
this.getPage()
|
},
|
handleBeforeUpload(file,type){
|
if("content" === type){
|
this.activityImg = file;
|
this.imgTempUrl = URL.createObjectURL(file);
|
return false;
|
}else if ("cover" === type){
|
this.activityCover = file;
|
this.coverTempUrl = URL.createObjectURL(file);
|
return false;
|
}
|
},
|
// 删除文件
|
handleRemove(type) {
|
if ('content' === type){
|
this.activityImg = null;
|
this.imgTempUrl = null;
|
|
}else if ('cover' === type){
|
this.activityCover = null;
|
this.coverTempUrl = null;
|
}
|
},
|
|
async uploadFileByLmk(){
|
if (this.activityImg){
|
this.submitLoading = true
|
const formData = new FormData()
|
formData.append('file', this.activityImg)
|
await uploadFileByLmk(formData).then(res => {
|
this.submitLoading = false
|
if (res.code === 200) {
|
this.activityFrom.activityImg = res.data.fileKey;
|
// this.$Message.success('上传成功')
|
}else{
|
// this.$Message.error(res.msg)
|
}
|
}).catch(() => {
|
this.submitLoading = false
|
})
|
}
|
if (this.activityCover){
|
this.submitLoading = true
|
const formData = new FormData()
|
formData.append('file', this.activityCover)
|
|
await uploadFileByLmk(formData).then(res => {
|
this.submitLoading = false
|
if (res.code === 200) {
|
this.activityFrom.activityCover = res.data.fileKey
|
// this.$Message.success('上传成功')
|
}else{
|
// this.$Message.error(res.msg)
|
}
|
}).catch(() => {
|
this.submitLoading = false
|
})
|
}
|
},
|
async saveOrUpdate(){
|
if (this.activityFrom.maxPrize < this.activityFrom.prizeNum){
|
this.$Message.error("初始化次数因小于或等于最大抽奖次数")
|
return
|
}
|
await this.uploadFileByLmk();
|
|
const submitData = {
|
...this.activityFrom,
|
beginTime: this.formatDate(this.activityFrom.beginTime, 'YYYY-MM-DD HH:mm:ss'),
|
endTime: this.formatDate(this.activityFrom.endTime, 'YYYY-MM-DD HH:mm:ss')
|
};
|
console.log(submitData)
|
this.$refs.form.validate(valid => {
|
if (valid) {
|
this.submitLoading = true
|
const api = this.activityFrom.id ? edit : add
|
api(submitData).then(res => {
|
this.submitLoading = false
|
if (res.code === 200) {
|
this.$Message.success(res.msg)
|
this.modelShow = false;
|
this.getPage()
|
}else{
|
this.$Message.error(res.msg)
|
}
|
}).catch(() => {
|
this.submitLoading = false
|
})
|
}
|
})
|
},
|
infoModelClose(){
|
this.infoModalShow = false;
|
},
|
modelClose(){
|
this.modelShow = false
|
this.submitLoading = false
|
this.$refs.form.resetFields()
|
},
|
getPage(){
|
this.loading = true;
|
getPage(this.searchForm).then(res =>{
|
this.loading = false;
|
if (res.code === 200){
|
this.activityList = res.data;
|
this.total = res.total;
|
}else {
|
this.$Message.error(res.msg)
|
}
|
})
|
},
|
detail(row){
|
this.infoModalShow = true;
|
this.detailData = {...row};
|
getActivityRefPrizeByActivityId(row.id).then(res=>{
|
if (res.code ===200){
|
this.$set(this.detailData,'prizes', res.data);
|
}
|
})
|
console.log(this.detailData)
|
|
},
|
// openEdit(row){
|
// if("ON" === row.enableStatus){
|
// this.$Message.error("抽奖已开启,不能编辑!")
|
// return
|
// }
|
// this.modelShow = true;
|
// this.modelTitle = "编辑活动";
|
// this.activityFrom= {
|
// id:row.id,
|
// activityName:row.activityName,
|
// activityDes:row.activityDes,
|
// beginTime:this.formatDate(row.beginTime, 'YYYY-MM-DD HH:mm:ss'),
|
// endTime: this.formatDate(row.endTime, 'YYYY-MM-DD HH:mm:ss'),
|
// maxPrize:row.maxPrize,
|
// prizeNum:row.prizeNum,
|
// activityImg:row.activityImg,
|
// activityCover:row.activityCover,
|
// enableStatus:row.enableStatus,
|
// }
|
// this.coverTempUrl = row.activityCoverUrl;
|
// this.imgTempUrl = row.activityImgUrl;
|
//
|
// },
|
|
handleSearch(type,value){
|
if (type === 'beginTime') {
|
this.searchForm.beginTime = value
|
} else if (type === 'endTime') {
|
this.searchForm.endTime = value
|
}
|
this.getPage()
|
},
|
openAdd(){
|
this.$refs.form.resetFields()
|
this.activityFrom.id = null;
|
this.modelShow = true;
|
this.modelTitle = "新增活动";
|
this.coverTempUrl = null;
|
this.prizeCover=null;
|
this.prizeImg = null;
|
this.imgTempUrl = null;
|
},
|
// delById(row){
|
// if("ON" === row.enableStatus){
|
// this.$Message.error("抽奖已开启,无法删除!")
|
// return
|
// }
|
// //若关联商品不让删
|
// del(row.id).then(res=>{
|
// if (res.code === 200){
|
// this.$Message.success(res.msg)
|
// }else {
|
// this.$Message.error(res.msg)
|
// }
|
// this.getPage()
|
// })
|
// },
|
// 获取富文本编辑器的内容
|
// 初始化数据
|
init() {
|
this.getPage()
|
},
|
changePage(){
|
this.searchForm.pageNumber = 1
|
this.searchForm.pageSize = pageSize
|
this.getPage()
|
},
|
changePageSize(){
|
this.searchForm.pageNumber = page
|
this.getPage()
|
},
|
prizeChangePage(){
|
this.prizeSearchForm.pageNumber = 1
|
this.prizeSearchForm.pageSize = pageSize
|
this.getPrizeList()
|
},
|
prizeChangePageSize(){
|
this.prizeSearchForm.pageNumber = page
|
this.getPrizeList()
|
},
|
async publishPrizeActivity(row){
|
await publishPrizeActivity(row.id).then(res =>{
|
if (res.code === 200){
|
this.$Message.success(res.msg)
|
}else{
|
this.$Message.error(res.msg)
|
}
|
})
|
await this.getPage()
|
},
|
|
},
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
.detail-container {
|
padding: 16px;
|
}
|
|
.detail-item {
|
margin-bottom: 16px;
|
line-height: 1.5;
|
}
|
|
.detail-item label {
|
display: inline-block;
|
width: 120px;
|
font-weight: bold;
|
color: #515a6e;
|
vertical-align: top;
|
}
|
|
.detail-item span {
|
display: inline-block;
|
max-width: calc(100% - 120px);
|
}
|
|
.detail-image {
|
display: inline-block;
|
margin-top: 8px;
|
border: 1px dashed #dcdee2;
|
padding: 4px;
|
border-radius: 4px;
|
background: #f8f8f9;
|
}
|
.search-form {
|
padding: 16px;
|
background: #f8f8f9;
|
border-radius: 4px;
|
margin-bottom: 16px;
|
|
.ivu-form-item {
|
margin-bottom: 16px;
|
margin-right: 16px;
|
}
|
|
.search-btn {
|
margin-left: 8px;
|
}
|
}
|
.operation {
|
margin-bottom: 16px;
|
|
.ivu-btn {
|
margin-right: 8px;
|
}
|
}
|
.activity-table {
|
.thumbnail {
|
max-width: 100%;
|
max-height: 100%;
|
object-fit: contain;
|
cursor: pointer;
|
transition: all 0.3s;
|
|
&:hover {
|
transform: scale(1.05);
|
box-shadow: 0 0 8px rgba(0, 0, 0, 0.2);
|
}
|
}
|
.action-btns {
|
display: flex;
|
flex-wrap: wrap;
|
justify-content: center;
|
|
.ivu-btn {
|
margin: 4px;
|
font-size: 12px;
|
padding: 2px 6px;
|
min-width: 60px;
|
}
|
}
|
}
|
.prize-table {
|
.thumbnail {
|
max-width: 100px;
|
max-height: 100px;
|
object-fit: contain;
|
cursor: pointer;
|
transition: all 0.3s;
|
|
&:hover {
|
transform: scale(1.05);
|
box-shadow: 0 0 8px rgba(0, 0, 0, 0.2);
|
}
|
}
|
|
.action-btns {
|
display: flex;
|
flex-wrap: wrap;
|
justify-content: center;
|
|
.ivu-btn {
|
margin: 4px;
|
font-size: 12px;
|
padding: 2px 6px;
|
min-width: 60px;
|
}
|
}
|
}
|
.preview-image-limit{
|
max-width: 100%;
|
max-height: 200px;
|
object-fit: contain;
|
border-radius: 4px;
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
display: block;
|
}
|
//详情商品样式
|
.prize-list {
|
margin-top: 10px;
|
max-height: 300px;
|
overflow-y: auto;
|
}
|
|
.prize-item {
|
padding: 12px;
|
border: 1px solid #e8eaec;
|
border-radius: 4px;
|
margin-bottom: 10px;
|
background: #f8f9fa;
|
}
|
.prize-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 8px;
|
}
|
|
.prize-name {
|
font-weight: bold;
|
color: #17233d;
|
}
|
|
.prize-content {
|
font-size: 13px;
|
}
|
|
.prize-info {
|
margin-top: 8px;
|
color: #808695;
|
}
|
|
</style>
|