<template>
<div class="activity-edit-class" v-loading="loading">
<el-form :model="activityForm" ref="activityForm" :rules="rules">
<div class="pannel basic-info">
<div class="title">基础信息</div>
<div class="body">
<el-row :gutter="20" v-if="!isAdd">
<el-col :span="24">
<el-form-item label="活动编号:" label-width="130px" ref="activityId">
{{activityForm.activityId}}
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="活动名称:" label-width="130px" prop="activityName" ref="activityName">
<el-input v-model.trim="activityForm.activityName" maxlength="30" placeholder="请输入活动名称(30个字符)"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="活动时间:" label-width="130px" prop="activityTime" ref="activityTime">
<el-date-picker
v-model="activityForm.activityTime"
:disabled="editable('activityTime')"
type="datetimerange"
range-separator="~"
:picker-options="{disabledDate(time) {
return time.getTime() < (new Date().getTime() - 24*60*60*1000)
}}"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="活动分享主标题:" label-width="130px" prop="shareTitle" ref="shareTitle" >
<el-input type="textarea" v-model.trim="activityForm.shareTitle" :disabled="editable('shareTitle')" :autosize="{minRows: 3}" maxlength="100" show-word-limit placeholder="请输入活动主标题(100个字符)"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="活动分享副标题:" label-width="130px" prop="shareSubtitle" ref="shareSubtitle">
<el-input type="textarea" v-model.trim="activityForm.shareSubtitle" :disabled="editable('shareSubtitle')" :autosize="{minRows: 3}" maxlength="100" show-word-limit placeholder="请输入活动副标题(100个字符)"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="活动分享图标:" label-width="130px" prop="shareIconUrl" ref="shareIconUrl" class="shareUpload fileUpload">
<file-upload
listType="picture-card"
accept=".jpg,.png"
:disabled="editable('shareIconUrl')"
:size="40"
:fileList="activityForm.shareIconUrl"
description="支持jpg和png格式,图标尺寸为300px*300px,大小不超过40K"
target='shareIconUrl'
:onExceed="handleExceedLimit"
:beforeUpload="handleBeforeUpload"
:onProgress="handleProgress"
:onPreview="handlePreview"
:onRemove="handleRemove"></file-upload>
</el-form-item>
</el-col>
</el-row>
</div>
</div>
<div class="pannel">
<div class="title">活动图片配置</div>
<div class="body">
<el-row>
<el-col :span="24">
<el-form-item label="活动底图颜色:" label-width="150px" prop="color" ref="color">
<el-color-picker
v-model="activityForm.color"
show-alpha
:predefine="predefineColors">
</el-color-picker>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="活动banner图:" label-width="150px" prop="coverUrl" class="fileUpload" ref="coverUrl">
<file-upload
listType="picture-card"
accept=".jpg,.png"
:disabled="editable('coverUrl')"
:size="500"
:fileList="activityForm.coverUrl"
description="支持jpg和png格式,建议按钮尺寸宽度为750px,高度240-320px,大小不超过500K"
target='coverUrl'
:onExceed="handleExceedLimit"
:beforeUpload="handleBeforeUpload"
:onProgress="handleProgress"
:onPreview="handlePreview"
:onRemove="handleRemove"></file-upload>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="邀请按钮图片:" label-width="150px" prop="inviteButtonUrl" ref="inviteButtonUrl" class="buttonUrl fileUpload">
<file-upload
listType="picture-card"
accept=".jpg,.png"
:size="50"
:fileList="activityForm.inviteButtonUrl"
description="支持jpg和png格式,建议按钮尺寸宽度为300-400px,高度60-80px,大小不超过50K"
target='inviteButtonUrl'
:onExceed="handleExceedLimit"
:beforeUpload="handleBeforeUpload"
:onProgress="handleProgress"
:onPreview="handlePreview"
:onRemove="handleRemove"></file-upload>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="获奖滚动显示字色:" label-width="150px" prop="scrollColor" ref="scrollColor" class="scrollColor">
<span :class="activityForm.scrollColor === 'black' ? 'active' : ''" @click="selectScrollColor('black')"></span>
<span :class="activityForm.scrollColor === 'white' ? 'active' : ''" @click="selectScrollColor('white')"></span>
</el-form-item>
</el-col>
</el-row>
<div>
<el-form-item label="中间区域图:" label-width="150px" prop="imageUrls" ref="imageUrls" class="infoUrl fileUpload">
<el-row v-for="(img, index) in activityForm.imageUrls" :key="index" class="withUrlUpload">
<el-col :span="7">
<file-upload
listType="picture-card"
accept=".jpg,.png"
:limit="1"
:size="200"
:fileList="img.url ? [img] : []"
:target="{name: 'imageUrls', index}"
:onExceed="handleExceedLimit"
:beforeUpload="handleBeforeUpload"
:onProgress="handleProgress"
:onPreview="handlePreview"
:onRemove="handleRemove"></file-upload>
</el-col>
<el-col :span="16">
<el-row :gutter="20">
<el-col :span="17">
<el-form-item label="跳转URL:" label-width="80px" :ref="'imageUrls.' + index + '.href'" :prop="'imageUrls.' + index + '.href'" :rules="[
{ min: 0, max: 200, message: '长度最多 200 个字符', trigger: 'change' }
]">
<el-input v-model.trim="img.href" placeholder="请输入链接"></el-input>
</el-form-item>
</el-col>
<el-col :span="7" class="handleButton">
<el-button type="danger" icon="el-icon-delete" v-if="activityForm.imageUrls.length > 1" @click="removeUploadItem('imageUrls', index)"></el-button>
<el-button type="warning" icon="el-icon-plus" v-if="(index + 1) === activityForm.imageUrls.length && activityForm.imageUrls.length < imageUrlsLimit" @click="addUploadItem('imageUrls')"></el-button>
</el-col>
</el-row>
</el-col>
</el-row>
<div class="hint">支持jpg和png格式,建议按钮尺寸宽度为750px,高度200-280px,大小不超过200K</div>
</el-form-item>
</div>
<el-row>
<el-form-item label="立即下单按钮图片:" label-width="150px" prop="orderButtonUrl" ref="orderButtonUrl" class="buttonUrl fileUpload">
<el-row class="withUrlUpload">
<el-col :span="7">
<file-upload
listType="picture-card"
accept=".jpg,.png"
:size="50"
:fileList="activityForm.orderButtonUrl"
target='orderButtonUrl'
:onExceed="handleExceedLimit"
:beforeUpload="handleBeforeUpload"
:onProgress="handleProgress"
:onPreview="handlePreview"
:onRemove="handleRemove"></file-upload>
</el-col>
<el-col :span="16">
<el-row :gutter="20">
<el-col :span="17">
<el-form-item label="跳转URL:" label-width="80px" prop="orderButtonHref" ref="orderButtonHref">
<el-input v-model.trim="activityForm.orderButtonHref" placeholder="请输入链接"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-col>
</el-row>
<div class="hint">支持jpg和png格式,建议按钮尺寸宽度为300-400px,高度60-80px,大小不超过50K</div>
</el-form-item>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="奖励类型:" label-width="150px" prop="ruleType" ref="ruleType">
<el-radio-group v-model="activityForm.ruleType" @change="ruleTypeChange">
<el-radio :disabled="editable('ruleType')" label="01">不限奖励</el-radio>
<el-radio :disabled="editable('ruleType')" label="02">阶梯奖励</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="邀请人奖励背景图:" label-width="150px" prop="ruleTypeUrl" ref="ruleTypeUrl" class="ruleTypeUrl fileUpload" :rules="[
{ required: true, message: '请选择一个奖励背景图', trigger: 'change' }
]">
<file-upload
listType="picture-card"
accept=".jpg,.png"
:limit="activityForm.ruleType === '01' ? 1 : 5"
:disabled="editable('ruleTypeUrl')"
:size="200"
:fileList="activityForm.ruleTypeUrl"
:description="`支持jpg和png格式,建议图片尺寸宽度为${activityForm.ruleType === '01' ? 690 : 510}px,高度200px,大小不超过200K`"
target='ruleTypeUrl'
:onExceed="handleExceedLimit"
:beforeUpload="handleBeforeUpload"
:onProgress="handleProgress"
:onPreview="handlePreview"
:onRemove="handleRemove"></file-upload>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="被邀请人奖励背景图:" label-width="150px" prop="beinvitedUrls" ref="beinvitedUrls" class="ruleTypeUrl fileUpload" :rules="[
{ required: true, message: '请选择一个奖励背景图', trigger: 'change' }
]">
<file-upload
listType="picture-card"
accept=".jpg,.png"
:limit="5"
:disabled="editable('beinvitedUrls')"
:size="200"
:fileList="activityForm.beinvitedUrls"
:description="`支持jpg和png格式,建议图片尺寸宽度为690px,高度200px,大小不超过200K`"
target='beinvitedUrls'
:onExceed="handleExceedLimit"
:beforeUpload="handleBeforeUpload"
:onProgress="handleProgress"
:onPreview="handlePreview"
:onRemove="handleRemove"></file-upload>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="活动规则:" label-width="150px" prop="activityRuleDes" ref="activityRuleDes" class="activityRuleDes extraRuleDes">
<tinymce :height="300" v-model="activityForm.activityRuleDes" id='tinymce' :readonly="!isAdd && activityForm.activityStatus === '02'" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-form-item label="底部活动图:" label-width="150px" prop="bottomUrls" ref="bottomUrls" class="buttonUrl fileUpload">
<el-row v-for="(img, index) in activityForm.bottomUrls" :key="index" class="withUrlUpload">
<el-col :span="7">
<file-upload
listType="picture-card"
accept=".jpg,.png"
:size="200"
:fileList="img.url ? [img] : []"
:target="{name: 'bottomUrls', index}"
:onExceed="handleExceedLimit"
:beforeUpload="handleBeforeUpload"
:onProgress="handleProgress"
:onPreview="handlePreview"
:onRemove="handleRemove"></file-upload>
</el-col>
<el-col :span="16">
<el-row :gutter="20">
<el-col :span="17">
<el-form-item label="跳转URL:" label-width="80px" :ref="'bottomUrls.' + index + '.href'" :prop="'bottomUrls.' + index + '.href'" :rules="[
{ min: 0, max: 200, message: '长度最多 200 个字符', trigger: 'change' }
]">
<el-input v-model.trim="img.href" placeholder="请输入链接"></el-input>
</el-form-item>
</el-col>
<el-col :span="7" class="handleButton">
<el-button type="danger" icon="el-icon-delete" v-if="activityForm.bottomUrls.length > 1" @click="removeUploadItem('bottomUrls', index)"></el-button>
<el-button type="warning" icon="el-icon-plus" v-if="(index + 1) === activityForm.bottomUrls.length && activityForm.bottomUrls.length < bottomUrlsLimit" @click="addUploadItem('bottomUrls')"></el-button>
</el-col>
</el-row>
</el-col>
</el-row>
<div class="hint">支持jpg和png格式,建议按钮尺寸宽度为750px,高度200-280px,大小不超过200K</div>
</el-form-item>
</el-row>
</div>
</div>
<div class="pannel rule-setting">
<div class="title">活动规则配置</div>
<div class="body">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="活动类型:" label-width="80px" prop="activityType" ref="activityType">
<el-select v-model="activityForm.activityType" :disabled="editable('activityType')" placeholder="请选择活动类型" @change="getTypeOptionList">
<el-option
v-for="item in activityTypeList"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<template v-for="(rule, ruleIndex) in activityForm.rules" ref="activityFormRules">
<div class="objects" :key="rule.userTarget">
<div class="object">用户对象:<span>{{rule.userTarget === '01' ? '邀请人' : '被邀请人'}}</span></div>
<div class="rules">
<el-row class="header" :gutter="20">
<el-col :span="6">
<el-row :gutter="20">
<el-col :span="12"><span class="requireSign">*</span>有效行为</el-col>
<el-col :span="12"><span class="requireSign" v-if="(rule.effectiveBehavior !== '07' && rule.effectiveBehavior !== '01')">*</span>订单类型</el-col>
</el-row>
</el-col>
<el-col :span="18">
<el-row :gutter="20">
<el-col :span="3" v-if="activityForm.ruleType === '02' && rule.userTarget === '01'"><span class="requireSign">*</span>人数</el-col>
<el-col :span="5"><span class="requireSign">*</span>批次号</el-col>
<el-col :span="5"><span class="requireSign">*</span>获得奖励</el-col>
<el-col :span="3" v-if="activityForm.ruleType === '01' || rule.userTarget === '02'"><span class="requireSign">*</span>中奖概率(%)</el-col>
<el-col :span="2">当前剩余</el-col>
<el-col :span="4"><span class="requireSign">*</span>奖品数量</el-col>
<el-col :span="2">库存</el-col>
<el-col :span="2">操作</el-col>
</el-row>
</el-col>
</el-row>
<el-row class="items" :gutter="20">
<el-col class="left" :span="6">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item :prop="'rules.' + ruleIndex + '.effectiveBehavior'" :rules="[
{ required: true, message: '请选择有效行为', trigger: 'change' }
]">
<el-select v-model="rule.effectiveBehavior" :disabled="editable('effectiveBehavior')">
<el-option
v-for="item in behaviorTypeList"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :prop="'rules.' + ruleIndex + '.businessType'" :rules="[
{ required: (rule.effectiveBehavior !== '07' && rule.effectiveBehavior !== '01') , message: '请选择订单类型', trigger: 'change' }
]">
<el-select v-model="rule.businessType" :disabled="editable('businessType')">
<el-option
v-for="item in orderTypeList"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item :prop="'rules.' + ruleIndex + '.travelTime'" v-if="rule.effectiveBehavior === '03'" :rules="[
{ required: true, message: '请选择出行时间', trigger: 'change' }
]">
<el-date-picker
v-model="rule.travelTime"
:disabled="editable('travelTime')"
type="datetimerange"
range-separator="~"
:picker-options="{disabledDate(time) {
if(activityForm.activityTime.length) {
return time.getTime() < new Date(activityForm.activityTime[0]).getTime()
}
return false
}}"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
</el-col>
<el-col class="right" :span="18">
<el-form :model="activityForm.rules[ruleIndex]" ref="activityForm1">
<template v-for="(reward, rewardIndex) in rule.rewards">
<el-row :gutter="20" :key="rewardIndex" v-if="reward.flag !== '03'">
<el-col :span="3" v-if="activityForm.ruleType === '02' && rule.userTarget === '01'">
<el-form-item :prop="'rewards.' + rewardIndex + '.peopleNumber'" :ref="'rewards.' + rewardIndex + '.peopleNumber'" :rules="[
{ required: true, message: '请输入人数', trigger: 'change' },
{ type: 'number', message: '人数必须为数字值', trigger: 'change'},
{ validator: (rule, value, callback) => {
if (value <= 0) {
return callback('人数必须大于0')
}
callback()
}, trigger: 'change' }
]">
<el-input v-model.number="reward.peopleNumber" min='1' :disabled="editable('peopleNumber')" placeholder="请输入人数"></el-input>
</el-form-item>
</el-col>
<el-col :span="5">
<el-row :gutter="20">
<el-col :span="24">
<el-form-item :prop="'rewards.' + rewardIndex + '.rewardType'" :ref="'rewards.' + rewardIndex + '.rewardType'" :rules="[
{ required: true, message: '请选择批次号', trigger: 'change' }
]">
<el-select v-model="reward.value" value-key='businessId' :disabled="editable('rewardType')" @change="changeBusinessIdType($event,ruleIndex, rewardIndex)">
<el-option
v-for="item in businessIdList"
:key="item.businessId"
:label="item.value"
:value="item">
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-col>
<el-col :span="5">
<el-row :gutter="20">
<el-col :span="8">
<el-form-item :prop="'rewards.' + rewardIndex + '.rewardType'" :ref="'rewards.' + rewardIndex + '.rewardType'" :rules="[
{ required: true, message: '请选择奖励类型', trigger: 'change' }
]">
<el-input v-model="reward.rewardType" disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="16">
<el-form-item :prop="'rewards.' + rewardIndex + '.businessId'" :ref="'rewards.' + rewardIndex + '.businessId'" :rules="[
{ required: true, message: '请选择优惠券', trigger: 'change' }
]">
<el-input v-model="reward.rewardName" disabled></el-input>
</el-form-item>
</el-col>
</el-row>
</el-col>
<el-col :span="3" v-if="activityForm.ruleType === '01' || rule.userTarget === '02'">
<el-form-item :prop="'rewards.' + rewardIndex + '.probability'" :ref="'rewards.' + rewardIndex + '.probability'" :rules="[
{ required: true, message: '请输入中奖概率', trigger: 'change' },
{ type: 'number', message: '中奖概率必须为数字值', trigger: 'change'},
{ validator: (rule, value, callback) => {
if (value <= 0) {
return callback('中奖概率需大于0')
}
callback()
}, trigger: 'change' }
]">
<el-input v-model.number="reward.probability" :disabled="editable('probability')" placeholder="请输入中奖概率"></el-input>
</el-form-item>
</el-col>
<el-col :span="2">
<el-form-item :prop="'rewards.' + rewardIndex + '.lave'">
<el-input v-model.number="reward.lave" disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item :prop="'rewards.' + rewardIndex + '.amount'" :ref="'rewards.' + rewardIndex + '.amount'" :rules="[
{ required: true, message: '请输入奖品数量', trigger: 'change' },
{ type: 'number', message: '奖品数量必须为数字值', trigger: 'change'},
{ validator: (rule, value, callback) => {
if (value <= 0) {
return callback('奖品数量需大于0')
}
callback()
}, trigger: 'change' }
]">
<el-input v-model.number="reward.amount" v-on:keyup.native="changeRewardAmout($event,ruleIndex, rewardIndex)" min=1 placeholder="请输入奖品数量"></el-input>
</el-form-item>
</el-col>
<el-col :span="2">
<el-form-item >
<el-input v-model.trim="reward.stock" disabled placeholder="库存"></el-input>
</el-form-item>
</el-col>
<el-col :span="2">
<el-link type="danger" :underline="false" :disabled="editable('ruleDel')" v-if="rule.rewards.length > 1 && getValidRewards(rule.rewards) > 1" @click="removeReward(ruleIndex, rewardIndex)">删除</el-link>
<el-link type="primary" :underline="false" :disabled="editable('ruleAdd')" v-if="rewardIndex === lastValidReward(rule.rewards) && rewardIndex < 4" @click="addReward(ruleIndex)">添加</el-link>
</el-col>
</el-row>
</template>
</el-form>
</el-col>
</el-row>
</div>
</div>
</template>
<el-row>
<el-col :span="24">
<el-form-item label="活动结束条件:" prop="dismounting">
<el-checkbox-group v-model="activityForm.dismounting" :disabled="editable('dismounting')">
<el-checkbox label="1" name="dismounting" disabled>活动时间</el-checkbox>
<el-checkbox label="2" name="dismounting">奖品数量发放完毕</el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-col>
</el-row>
</div>
</div>
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>
<div class="button-bottom">
<el-button @click="returnList">取消</el-button>
<el-button type="warning" @click="showPreview(true)">预览</el-button>
<el-button type="primary" @click="save">提交</el-button>
</div>
</el-form>
<div class="preview" v-if="previewShow">
<span @click="showPreview(false)">X</span>
<div class="mobile">
<HomeModule :activityInfo="previewActivityInfo" :cookie="cookie" />
</div>
</div>
</div>
</template>
<script>
import _ from 'lodash'
import moment from 'moment'
import {
addActivity,
editActivity,
activityDetail,
typeOptionList,
rewardOptionList
} from '@/api/activity'
import FileUpload from '@/components/FileUpload'
import HomeModule from '@/module/home/index'
import Tinymce from '@/components/Tinymce'
const cookie = require('@/utils/auth')
export default {
name: 'activityEdit',
components: {
FileUpload,
HomeModule,
Tinymce
},
data() {
return {
loading: false,
isAdd: false,
cookie: cookie,
dialogVisible: false,
previewShow: false,
dialogImageUrl: '',
predefineColors: [
'#FEF2D8',
'#ECF3FF',
'#FFEAEA',
'#EAF8FF',
'#E1F8E2',
'#F1EAFE'
],
activityTypeList: [],
orderTypeList: [],
behaviorTypeList: [],
rewardList: [],
businessIdList: [],
imageUrlsLimit: 10,
bottomUrlsLimit: 10,
previewActivityInfo: {
from: 'offline'
},
activityForm: {
activityName: '',
activityTime: [],
startTime: '',
endTime: '',
activityType: '',
shareTitle: '',
shareSubtitle: '',
shareIconUrl: [],
color: '',
coverUrl: [],
inviteButtonUrl: [],
scrollColor: 'black',
imageUrls: [{}],
orderButtonUrl: [],
orderButtonHref: '',
ruleType: '01',
ruleTypeUrl: [],
beinvitedUrls: [],
activityRuleDes: '',
bottomUrls: [{}],
rules: [{
userTarget: '01',
effectiveBehavior: '',
travelTime: [],
startTime: '',
endTime: '',
businessType: '',
rewards: [{
rewardInfoList: [],
value: '',
peopleNumber: '',
rewardType: '',
businessId: '',
rewardName: '',
probability: '',
lave: '',
pareAmount: 0,
pareLave: 0,
amount: '',
stock: ''
}]
}, {
userTarget: '02',
effectiveBehavior: '',
travelTime: [],
startTime: '',
endTime: '',
businessType: '',
rewards: [{
rewardInfoList: [],
value: '',
peopleNumber: '',
rewardType: '',
businessId: '',
rewardName: '',
probability: '',
lave: '',
pareAmount: 0,
pareLave: 0,
amount: '',
stock: ''
}]
}],
dismounting: ['1'],
dismountingTime: false,
dismountingPrize: false
},
pareAddActivityForm: {},
pareEditActivityForm: {},
rules: {
activityName: [
{ required: true, message: '请输入活动名称', trigger: 'change' },
{ min: 1, max: 30, message: '长度在 1 到 30 个字符', trigger: 'change' }
],
activityTime: [
{ required: true, message: '请选择活动时间', trigger: 'change' }
],
activityType: [
{ required: true, message: '请选择活动类型', trigger: 'change' }
],
shareTitle: [
{ required: true, message: '请输入活动主标题', trigger: 'change' },
{ min: 1, max: 100, message: '长度在 1 到 100 个字符', trigger: 'change' }
],
shareSubtitle: [
{ required: true, message: '请输入活动副标题', trigger: 'change' },
{ min: 1, max: 100, message: '长度在 1 到 100 个字符', trigger: 'change' }
],
shareIconUrl: [
{ required: true, message: '请选择一个活动分享图标', trigger: 'change' }
],
color: [
{ required: true, message: '请选择活动底图颜色', trigger: 'change' }
],
coverUrl: [
{ required: true, message: '请选择一个活动配图', trigger: 'change' }
],
inviteButtonUrl: [
{ required: true, message: '请选择一个邀请按钮图', trigger: 'change' }
],
scrollColor: [
{ required: true, message: '请选择一个获奖滚动显示字色', trigger: 'change' }
],
orderButtonUrl: [
{ required: true, message: '请选择一个立即下单按钮图', trigger: 'change' }
],
orderButtonHref: [
{ required: true, message: '请输入跳转链接', trigger: 'change' },
{ min: 1, max: 200, message: '长度在 1 到 200 个字符', trigger: 'change' }
],
ruleType: [
{ required: true, message: '请选择奖励类型', trigger: 'change' }
],
activityRuleDes: [
{ required: true, message: '请填写活动规则', trigger: 'change' },
{ min: 1, max: 2000, message: '长度在 1 到 2000 个字符', trigger: 'change' }
],
dismounting: [
{ type: 'array', required: true, message: '请至少选择一个活动结束条件', trigger: 'change' }
]
}
}
},
mounted() {
if (this.$router.history.current.path === '/activityManage/add') {
this.isAdd = true
this.pareAddActivityForm = _.cloneDeep(this.activityForm)
} else {
this.isAdd = false
}
this.getActivityTypeList()
this.getRewardOrderList().then(() => {
const { query } = this.$router.history.current
if (!this.isAdd) {
const { id } = query
this.getActivityInfo(id)
}
})
},
methods: {
getActivityInfo(id) {
this.loading = true
activityDetail({
activityId: id
}).then(response => {
this.loading = false
const { data } = response
this.getTypeOptionList(data.activityType)
data.activityTime = [moment(data.startTime).format(), moment(data.endTime).format()]
data.coverUrl = [{ url: data.coverUrl }]
data.shareIconUrl = [{ url: data.shareIconUrl }]
data.inviteButtonUrl = [{ url: data.inviteButtonUrl }]
data.orderButtonUrl = [{ url: data.orderButtonUrl }]
if (data.ruleTypeUrl) {
const urls = data.ruleTypeUrl.split(',')
data.ruleTypeUrl = []
urls.map(url => {
data.ruleTypeUrl.push({ url })
})
} else {
data.ruleTypeUrl = []
}
if (data.beinvitedUrls) {
const urls = data.beinvitedUrls.split(',')
data.beinvitedUrls = []
urls.map(url => {
data.beinvitedUrls.push({ url })
})
} else {
data.beinvitedUrls = []
}
if (!data.bottomUrls || !data.bottomUrls.length) {
data.bottomUrls = [{}]
}
if (!data.imageUrls || !data.imageUrls.length) {
data.imageUrls = [{}]
}
const indexArr = ['01', '02']
const orderedRules = []
data.rules.map((rule, ruleIndex) => {
const { startTime, endTime, rewards } = rule
rule.flag = '02'
if (startTime && endTime) {
rule.travelTime = [moment(startTime).format(), moment(endTime).format()]
}
rewards.map((reward, rewardIndex) => {
reward.flag = '02'
const rewardItem = data.rules[ruleIndex].rewards[rewardIndex]
reward.value = `${rewardItem.businessId}-${rewardItem.rewardType}-${rewardItem.rewardName}`
reward.pareAmount = rewardItem.amount
reward.pareLave = rewardItem.lave
reward.stock = rewardItem.stock
})
})
indexArr.map(index => {
data.rules.map(rule => {
if (rule.userTarget === index) {
orderedRules.push(rule)
}
return
})
return
})
data.rules = orderedRules
data.dismounting = []
data.dismountingTime ? data.dismounting.push('1') : ''
data.dismountingPrize ? data.dismounting.push('2') : ''
this.activityForm = data
this.pareEditActivityForm = Object.assign({}, data)
}).catch(() => {
this.loading = false
})
},
getActivityTypeList() {
this.loading = true
typeOptionList({ pullDownType: '01' }).then(response => {
this.activityTypeList = response.data
this.loading = false
}).catch(() => {
this.loading = false
})
},
getRewardOrderList() {
this.loading = true
return rewardOptionList({}).then(response => {
this.businessIdList = response.data.map(item => {
return { value: `${item.businessId}-${item.rewardType}-${item.rewardName}`, ...item }
})
this.rewardList = response.data
this.loading = false
return response
}).catch(() => {
this.loading = false
})
},
getTypeOptionList(activityType) {
if (!activityType) {
this.orderTypeList = []
this.behaviorTypeList = []
const { rules } = this.activityForm
rules.map(rule => {
rule.effectiveBehavior = ''
rule.businessType = ''
rule.travelTime = []
})
return
}
this.loading = true
typeOptionList({ activityType, pullDownType: '02' }).then(response => {
this.orderTypeList = response.data
this.loading = false
}).catch(() => {
this.loading = false
})
typeOptionList({ pullDownType: '03' }).then(response => {
this.behaviorTypeList = response.data
this.loading = false
}).catch(() => {
this.loading = false
})
},
selectScrollColor(color) {
this.activityForm.scrollColor = color
},
ruleTypeChange(value) {
const { rules } = this.activityForm
rules.map(rule => {
const { userTarget, rewards } = rule
if (userTarget === '01') {
rewards.map(reward => {
value === '02' ? reward.probability = '' : reward.peopleNumber = ''
})
}
})
},
editable(item) {
const { activityStatus } = this.activityForm
if (this.isAdd) {
return false
}
if (activityStatus === '03') {
return true
} else if (activityStatus === '02') {
return true
} else {
if (item === 'activityType') {
return true
}
return false
}
},
changeBusinessIdType(val, ruleIndex, rewardIndex) {
const reward = this.activityForm.rules[ruleIndex].rewards[rewardIndex]
reward.rewardType = val.rewardType
reward.businessId = val.businessId
reward.rewardName = val.rewardName
reward.stock = val.rewardAmount
},
changeRewardAmout(e, ruleIndex, rewardIndex) {
const val = e.target.value
const reward = this.activityForm.rules[ruleIndex].rewards[rewardIndex]
if (this.isAdd) {
reward.lave = val
this.$set(this.activityForm.rules[ruleIndex], rewardIndex, reward)
} else {
const diffVal = val - reward.pareAmount
reward.lave = reward.pareLave + diffVal
this.$set(this.activityForm.rules[ruleIndex], rewardIndex, reward)
}
},
returnList() {
const editflag = _.isEqual(this.activityForm, this.pareEditActivityForm)
const addflag = _.isEqual(this.activityForm, this.pareAddActivityForm)
if (!editflag && !this.isAdd) {
this.$confirm(`当前活动尚未保存,确定退出${this.isAdd ? '新增' : '编辑'}活动?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$router.push({
path: '/activityManage/index'
})
sessionStorage.setItem('returnActivityIndexFlag', 'true')
})
} else if (!addflag && this.isAdd) {
this.$confirm(`当前活动尚未填写完成,确定退出${this.isAdd ? '新增' : '编辑'}活动?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$router.push({
path: '/activityManage/index'
})
sessionStorage.setItem('returnActivityIndexFlag', 'true')
})
} else {
this.$router.push({
path: '/activityManage/index'
})
sessionStorage.setItem('returnActivityIndexFlag', 'true')
}
},
showPreview(show) {
const params = { ...this.activityForm, from: 'offline', activityId: 'HD0000000', participatePeople: 'xxx' }
const { activityTime, coverUrl, shareIconUrl, inviteButtonUrl, orderButtonUrl, ruleTypeUrl, beinvitedUrls, bottomUrls, imageUrls, dismounting } = params
params.startTime = activityTime.length ? activityTime[0] : ''
params.endTime = activityTime.length ? activityTime[1] : ''
params.coverUrl = coverUrl.length ? coverUrl[0].url : ''
params.shareIconUrl = shareIconUrl.length ? shareIconUrl[0].url : ''
params.inviteButtonUrl = inviteButtonUrl.length ? inviteButtonUrl[0].url : ''
params.orderButtonUrl = orderButtonUrl.length ? orderButtonUrl[0].url : ''
params.ruleTypeUrl = ruleTypeUrl.length ? ruleTypeUrl.map(ruleType => ruleType.url).join(',') : ''
params.beinvitedUrls = beinvitedUrls.length ? beinvitedUrls.map(ruleType => ruleType.url).join(',') : ''
params.bottomUrls = [...bottomUrls]
if (params.bottomUrls.length) {
const lastIndex = params.bottomUrls.length - 1
const lastBottomUrl = params.bottomUrls[lastIndex]
if (!lastBottomUrl.url && !lastBottomUrl.href) {
params.bottomUrls.splice(lastIndex, 1)
}
}
params.imageUrls = [...imageUrls]
if (params.imageUrls.length) {
const lastIndex = params.imageUrls.length - 1
const lastImageUrl = params.imageUrls[lastIndex]
if (!lastImageUrl.url && !lastImageUrl.href) {
params.imageUrls.splice(lastIndex, 1)
}
}
params.dismountingTime = false
params.dismountingPrize = false
dismounting.map(dismount => {
dismount === '1' ? params.dismountingTime = true : ''
dismount === '2' ? params.dismountingPrize = true : ''
})
this.previewActivityInfo = params
this.previewShow = show
document.querySelector('.activity-edit-class').scrollIntoView()
},
save() {
const latestRewards = this.getRewardOrderList().then(result => result.data)
const validRules = this.$refs.activityForm1.map(form => {
return new Promise((resolve, reject) => {
form.validate((valid, object) => {
if (valid) {
resolve()
} else {
let dom = this.$refs.activityForm1
if (Object.prototype.toString.call(dom) !== '[object Object]') {
dom = dom[0]
}
dom.$el.scrollIntoView({
block: 'center',
behavior: 'smooth'
})
}
})
})
})
var main = new Promise((resolve, reject) => {
this.$refs.activityForm.validate((valid, object) => {
if (valid) {
resolve()
} else {
const keyArr = Object.keys(object)
let dom = this.$refs[keyArr[0]]
if (Object.prototype.toString.call(dom) !== '[object Object]') {
dom = dom[0]
}
dom.$el.scrollIntoView({
block: 'center',
behavior: 'smooth'
})
}
})
})
Promise.all([latestRewards, main, ...validRules]).then(data => {
const rewardsResult = data[0]
const params = { ...this.activityForm }
const { activityTime, coverUrl, shareIconUrl, inviteButtonUrl, orderButtonUrl, ruleTypeUrl, beinvitedUrls, bottomUrls, imageUrls, dismounting, ruleType, rules } = params
let valided = true
for (const rule of rules) {
const { rewards, userTarget, travelTime } = rule
if (ruleType === '02' && userTarget === '01') {
if (ruleTypeUrl.length !== this.getValidRewards(rewards)) {
this.$message({
message: '邀请人奖励背景图张数需与规则数保持一致',
type: 'error',
duration: 2000,
offset: 330
})
valided = false
break
}
}
let probabilityTotal = 0
for (const reward of rewards) {
const { rewardType, businessId, probability, amount, flag, value } = reward
let latestStock = ''
for (const latestReward of rewardsResult) {
if (latestReward.rewardType === rewardType) {
if (latestReward.businessId === businessId) {
latestStock = latestReward.rewardAmount
break
}
}
}
if (!latestStock) {
this.$message({
message: `${value} 已失效`,
type: 'error',
duration: 2000,
offset: 330
})
valided = false
break
}
if (parseInt(amount) > latestStock) {
this.$message({
message: '奖品数量不能大于库存量',
type: 'error',
duration: 2000,
offset: 330
})
valided = false
break
}
probabilityTotal += (flag === '03' ? 0 : probability)
}
if (!valided) break
if (((ruleType === '02' && userTarget === '02') || ruleType === '01') && probabilityTotal !== 100) {
this.$message({
message: `${userTarget === '01' ? '邀请人' : '被邀请人'}中奖概率之和必须为100`,
type: 'error',
duration: 2000,
offset: 330
})
valided = false
break
}
if (travelTime && travelTime.length) {
rule.startTime = travelTime[0]
rule.endTime = travelTime[1]
}
}
if (!valided) return
params.startTime = activityTime.length ? activityTime[0] : ''
params.endTime = activityTime.length ? activityTime[1] : ''
params.coverUrl = coverUrl.length ? coverUrl[0].url : ''
params.shareIconUrl = shareIconUrl.length ? shareIconUrl[0].url : ''
params.inviteButtonUrl = inviteButtonUrl.length ? inviteButtonUrl[0].url : ''
params.orderButtonUrl = orderButtonUrl.length ? orderButtonUrl[0].url : ''
params.ruleTypeUrl = ruleTypeUrl.length ? ruleTypeUrl.map(ruleType => ruleType.url).join(',') : ''
params.beinvitedUrls = beinvitedUrls.length ? beinvitedUrls.map(ruleType => ruleType.url).join(',') : ''
params.bottomUrls = [...bottomUrls]
if (params.bottomUrls.length) {
const lastIndex = params.bottomUrls.length - 1
const lastBottomUrl = params.bottomUrls[lastIndex]
if (!lastBottomUrl.url && !lastBottomUrl.href) {
params.bottomUrls.splice(lastIndex, 1)
}
}
params.imageUrls = [...imageUrls]
if (params.imageUrls.length) {
const lastIndex = params.imageUrls.length - 1
const lastImageUrl = params.imageUrls[lastIndex]
if (!lastImageUrl.url && !lastImageUrl.href) {
params.imageUrls.splice(lastIndex, 1)
}
}
params.dismountingTime = false
params.dismountingPrize = false
dismounting.map(dismount => {
dismount === '1' ? params.dismountingTime = true : ''
dismount === '2' ? params.dismountingPrize = true : ''
})
if (this.isAdd) {
addActivity(params).then(response => {
this.$message({
message: '提交成功,等待审核',
type: 'success',
duration: 2000,
offset: 330
})
this.$router.push({
path: '/activityManage/index'
})
}).catch(() => {
})
} else {
editActivity(params).then(response => {
if (params.activityStatus === '01') {
this.$message({
message: '提交成功,等待审核',
type: 'success',
duration: 2000,
offset: 330
})
} else if (params.activityStatus === '02') {
this.$message({
message: '提交成功',
type: 'success',
duration: 2000,
offset: 330
})
}
this.$router.push({
path: '/activityManage/index'
})
sessionStorage.setItem('returnActivityIndexFlag', 'true')
}).catch(() => {
})
}
})
},
addUploadItem(target) {
this.activityForm[target].push({})
},
removeUploadItem(target, index) {
this.activityForm[target].splice(index, 1)
},
addReward(ruleIndex) {
this.activityForm.rules[ruleIndex].rewards.push(Object.assign({
peopleNumber: '',
rewardType: '',
businessId: '',
rewardName: '',
probability: '',
amount: '',
lave: '',
pareAmount: 0,
pareLave: 0,
stock: ''
}, this.isAdd ? {} : { new: true, flag: '01' }))
},
removeReward(ruleIndex, rewardIndex) {
(this.isAdd || this.activityForm.rules[ruleIndex].rewards[rewardIndex].new) ? this.activityForm.rules[ruleIndex].rewards.splice(rewardIndex, 1) : this.activityForm.rules[ruleIndex].rewards[rewardIndex].flag = '03'
},
getValidRewards(rewards) {
let length = 0
rewards.map(reward => {
if (reward.flag !== '03') {
length++
}
})
return length
},
lastValidReward(rewards) {
const length = rewards.length - 1
let index = length
let i = length
for (i; i >= 0; i--) {
if (rewards[i].flag !== '03') {
index = i
break
}
}
return index
},
handleExceedLimit(files, fileList) {
},
handleBeforeUpload(fileInfo, target, multiple) {
if (multiple) {
if (typeof target === 'object') {
const { name, index } = target
const item = this.activityForm[name][index]
item.url = fileInfo.url
this.$set(this.activityForm[name], index, item)
} else {
this.activityForm[target].push(fileInfo)
}
} else {
if (typeof target === 'object') {
const { name, index } = target
const item = this.activityForm[name][index]
item.url = fileInfo.url
this.$set(this.activityForm[name], index, item)
} else {
this.activityForm[target].push(fileInfo)
}
}
},
handleProgress(event, file, fileList) {
},
handlePreview(url) {
this.dialogVisible = true
this.dialogImageUrl = url
},
handleRemove(index, target) {
if (typeof target === 'object') {
const { name, index } = target
const item = this.activityForm[name][index]
item.url = ''
this.$set(this.activityForm[name], index, item)
} else {
this.activityForm[target].splice(index, 1)
}
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
/deep/.activity-edit-class {
position: relative;
.el-dialog .el-dialog__header {
border: none;
.el-dialog__headerbtn {
font-size: 20px;
}
}
.pannel {
border-radius: 10px;
background-color: rgba(255, 255, 255, 1);
margin-bottom: 15px;
.title {
padding: 16px 32px;
border-bottom: solid 1px rgba(238, 238, 238, 1);
color: rgba(51, 51, 51, 1);
font-size: 16px;
}
.body {
padding: 24px 32px;
.scrollColor {
span {
width: 30px;
height: 30px;
border-radius: 4px;
display: inline-block;
cursor: pointer;
border: 1px solid rgba(255, 255, 255, 1);
box-shadow: 0px 1px 6px 0px rgba(0, 0, 0, 0.14);
background-color: rgba(255, 255, 255, 1);
&:first-child {
border: 1px solid rgba(0, 0, 0, 1);
box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.2);
background-color: rgba(0, 0, 0, 1);
margin-right: 20px;
}
&.active {
border: 3px solid rgba(48, 126, 255, 1);
}
}
}
.withUrlUpload {
margin-bottom: 8px;
display: flex;
align-items: center;
.handleButton {
display: flex;
align-items: center;
height: 41px;
.el-button {
width: 48px;
height: 28px;
}
}
}
.hint {
color: rgba(153, 153, 153, 1);
font-size: 12px;
}
.remark {
color: rgba(255, 80, 79, 1);
font-size: 14px;
}
}
&.basic-info {
.el-row {
margin-bottom: 24px;
&:last-child {
margin-bottom: 0;
}
.el-form-item {
margin-bottom: 0;
.el-form-item__label {
padding-right: 5px;
}
}
}
}
&.rule-setting {
margin-bottom: 72px;
}
}
.button-bottom {
position: fixed;
bottom: 0;
right: 0;
left: 0;
height: 72px;
line-height: 72px;
text-align: right;
background-color: rgba(255, 255, 255, 1);
box-shadow: 0px 0px 12px 0px rgba(0, 0, 0, 0.04);
padding-right: 24px;
z-index: 100;
}
.el-select, .el-date-editor--datetimerange {
width: 100%;
}
.el-upload-list--picture-card .el-upload-list__item {
width: 225px;
height: 96px;
}
.el-upload--picture-card, .el-upload--picture {
width: 225px!important;
height: 96px!important;
line-height: 96px;
img {
width: 100%;
height: 100%;
}
}
.fileUpload {
.el-form-item__content {
line-height: inherit;
}
}
.avatar-uploader-icon {
height: 96px!important;
width: 225px!important;
line-height: 96px!important;
}
.shareUpload {
.el-upload-list--picture-card .el-upload-list__item {
width: 100px;
height: 100px;
}
.el-upload--picture-card, .el-upload--picture {
width: 100px!important;
height: 100px!important;
line-height: 100px;
}
.avatar-uploader-icon {
height: 100px!important;
width: 100px!important;
line-height: 100px!important;
}
}
.buttonUrl {
.el-upload-list--picture-card .el-upload-list__item {
width: 200px;
height: 40px;
}
.el-upload--picture-card, .el-upload--picture {
width: 200px!important;
height: 40px!important;
line-height: 40px;
}
.avatar-uploader-icon {
height: 200px!important;
width: 40px!important;
line-height: 40px!important;
}
}
.infoUrl {
.el-upload-list--picture-card .el-upload-list__item {
width: 200px;
height: 80px;
}
.el-upload--picture-card, .el-upload--picture {
width: 200px!important;
height: 80px!important;
line-height: 80px;
}
.avatar-uploader-icon {
height: 200px!important;
width: 80px!important;
line-height: 80px!important;
}
}
.ruleTypeUrl {
.el-upload-list--picture-card .el-upload-list__item {
width: 255px;
height: 100px;
}
.el-upload--picture-card, .el-upload--picture {
width: 255px!important;
height: 100px!important;
line-height: 100px;
}
.avatar-uploader-icon {
height: 255px!important;
width: 100px!important;
line-height: 100px!important;
}
}
.objects {
font-size: 14px;
margin-bottom: 30px;
.object {
color: rgba(85, 85, 85, 1);
margin-bottom: 16px;
span {
color: rgba(51, 51, 51, 1);
}
}
.rules {
border: 1px solid rgba(232, 232, 232, 1);
border-bottom: none;
.header {
height: 54px;
line-height: 54px;
background-color: rgba(244, 244, 244, 1);
color: rgba(51, 51, 51, 1);
margin: 0!important;
white-space: nowrap;
.requireSign {
color: rgba(255, 80, 79, 1);
}
}
.items {
display: flex;
align-items: center;
margin: 0!important;
border-bottom: 1px solid #e8e8e8;
>.el-col {
>.el-form-item {
margin: 0;
}
}
.left {
padding-top: 12px;
.el-form-item {
margin-bottom: 12px;
}
}
.right {
border-left: solid 1px rgba(232, 232, 232, 1);
.el-row {
display: flex;
align-items: center;
border-bottom: solid 1px rgba(232, 232, 232, 1);
&:last-child {
border: none;
}
.el-form-item {
margin: 16px 0;
}
}
}
}
}
}
.preview {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: 10;
background-color: rgba(0, 0, 0, 0.65);
span {
width: 44px;
height: 44px;
line-height: 44px;
position: absolute;
right: 30px;
top: 30px;
color: white;
font-size: 20px;
text-align: center;
cursor: pointer;
}
.mobile {
// width: 375px;
// height: 667px;
width: 750px;
height: 1334px;
margin: 40px auto;
transform: scale(0.5, 0.5) translateY(-50%);
.participateNum{
font-size: 28px;
}
.checkRewards {
font-size: 28px;
}
.rule {
font-size: 30px;
}
.ladder dd{
font-size: 28px;
}
}
}
.el-loading-mask {
.el-loading-spinner {
position: fixed;
width: auto;
left: 60%;
}
}
// .extraRuleDes{
// display: flex;
// flex-direction: column;
// .el-form-item__label{
// text-align: left;
// }
// }
}
</style>