| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081 |
- <template>
- <div class="app-container">
- <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
- <el-form-item label="直播间ID" prop="liveId">
- <el-input
- v-model="queryParams.liveId"
- placeholder="请输入直播间ID"
- clearable
- :disabled="liveAbled"
- size="small"
- @keyup.enter.native="handleQuery"
- />
- </el-form-item>
- <el-form-item label="任务名称" prop="taskName">
- <el-input
- v-model="queryParams.taskName"
- placeholder="请输入任务名称"
- clearable
- size="small"
- @keyup.enter.native="handleQuery"
- />
- </el-form-item>
- <el-form-item label="任务类型" prop="taskType">
- <el-select v-model="queryParams.taskType" placeholder="请选择任务类型" clearable size="small">
- <el-option v-for="i in taskTypeOptions" :key="i.value" :label="i.label" :value="i.value"></el-option>
- </el-select>
- </el-form-item>
- <!-- <el-form-item label="触发类型" prop="triggerType">-->
- <!-- <el-select v-model="queryParams.triggerType" placeholder="请选择触发类型" clearable size="small">-->
- <!-- <el-option v-for="i in triggerTypeOptions" :key="i.value" :label="i.label" :value="i.value"></el-option>-->
- <!-- </el-select>-->
- <!-- </el-form-item>-->
- <el-form-item label="状态" prop="status">
- <el-select v-model="queryParams.status" placeholder="请选择状态" clearable size="small">
- <el-option v-for="i in statusOptions" :key="i.value" :label="i.label" :value="i.value"></el-option>
- </el-select>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
- <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
- </el-form-item>
- </el-form>
- <el-row :gutter="10" class="mb8">
- <el-col :span="1.5">
- <el-button
- :disabled="isViewOnly"
- type="primary"
- plain
- icon="el-icon-plus"
- size="mini"
- @click="handleAdd"
- v-hasPermi="['live:task:add']"
- >新增</el-button>
- </el-col>
- <el-col :span="1.5">
- <el-button
- type="success"
- plain
- icon="el-icon-edit"
- size="mini"
- :disabled="single || isViewOnly"
- @click="handleUpdate"
- v-hasPermi="['live:task:edit']"
- >修改</el-button>
- </el-col>
- <el-col :span="1.5">
- <el-button
- type="danger"
- plain
- icon="el-icon-delete"
- size="mini"
- :disabled="multiple || isViewOnly"
- @click="handleDelete"
- v-hasPermi="['live:task:remove']"
- >删除</el-button>
- </el-col>
- <el-col :span="1.5">
- <el-button
- :disabled="isViewOnly"
- type="warning"
- plain
- icon="el-icon-download"
- size="mini"
- :loading="exportLoading"
- @click="handleExport"
- v-hasPermi="['live:task:export']"
- >导出</el-button>
- </el-col>
- <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
- </el-row>
- <el-table border v-loading="loading" :data="taskList" @selection-change="handleSelectionChange">
- <el-table-column type="selection" width="55" align="center" />
- <el-table-column label="编号" align="center" prop="id" />
- <el-table-column label="任务名称" align="center" prop="taskName" />
- <el-table-column label="任务类型" align="center" prop="taskType" :formatter="taskTypeFormatter" />
- <el-table-column label="触发类型" align="center" prop="triggerType" :formatter="triggerTypeFormatter" />
- <el-table-column label="触发时间" align="center" prop="triggerValue" :formatter="triggerValueFormatter" />
- <el-table-column label="关联内容" align="center" prop="productName" :formatter="productNameFormatter" />
- <el-table-column label="状态" align="center" prop="status" :formatter="statusFormatter" />
- <!-- <el-table-column label="完成状态" align="center" prop="finishStatus" :formatter="finishStatusFormatter" />-->
- <el-table-column label="更新时间" align="center" prop="updatedTime" width="180">
- <template slot-scope="scope">
- <span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d}') }}</span>
- </template>
- </el-table-column>
- <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
- <template slot-scope="scope">
- <el-button
- :disabled="isViewOnly"
- size="mini"
- type="text"
- icon="el-icon-edit"
- @click="handleUpdate(scope.row)"
- v-hasPermi="['live:task:edit']"
- >修改</el-button>
- <el-button
- :disabled="isViewOnly"
- size="mini"
- type="text"
- icon="el-icon-delete"
- @click="handleDelete(scope.row)"
- v-hasPermi="['live:task:remove']"
- >删除</el-button>
- </template>
- </el-table-column>
- </el-table>
- <pagination
- v-show="total>0"
- :total="total"
- :page.sync="queryParams.pageNum"
- :limit.sync="queryParams.pageSize"
- @pagination="getList"
- />
- <!-- 添加或修改直播间自动化任务配置对话框 -->
- <el-dialog :title="title" :visible.sync="open" width="620px" append-to-body>
- <el-form ref="form" :model="form" :rules="rules" label-width="90px">
- <el-form-item label="直播间ID" prop="liveId">
- <el-input :disabled="liveAbled" v-model="form.liveId" placeholder="请输入直播间ID" />
- </el-form-item>
- <el-form-item label="任务名称" prop="taskName">
- <el-input v-model="form.taskName" placeholder="请输入任务名称" />
- </el-form-item>
- <el-form-item label="任务类型" prop="taskType">
- <el-select v-model="form.taskType" placeholder="请选择任务类型" @change="updateTaskType()" >
- <el-option v-for="i in taskTypeOptions" :key="i.value" :label="i.label" :value="i.value"></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="商品选择" prop="content" v-if="form.taskType == 1">
- <el-select v-model="form.content" placeholder="请选择商品" ref="selectRef" >
- <el-option v-for="i in productOptions" :key="i.value" :label="i.label" :value="i.value"></el-option>
- <!-- 加载载中状态 -->
- <div v-if="isLoading" class="loading-indicator">
- <i class="el-icon-loading"></i>
- <span>加载中...</span>
- </div>
- <!-- 没有更多数据 -->
- <div v-if="!hasMore && !isLoading" class="no-more">
- 没有更多数据了
- </div>
- </el-select>
- </el-form-item>
- <el-form-item label="红包选择" prop="content" v-if="form.taskType == 2">
- <el-select v-model="form.content" placeholder="请选择红包" ref="selectRef" >
- <el-option v-for="i in redOptions" :key="i.value" :label="i.label" :value="i.value"></el-option>
- <!-- 加载载中状态 -->
- <div v-if="isLoading" class="loading-indicator">
- <i class="el-icon-loading"></i>
- <span>加载中...</span>
- </div>
- <!-- 没有更多数据 -->
- <div v-if="!hasMore && !isLoading" class="no-more">
- 没有更多数据了
- </div>
- </el-select>
- </el-form-item>
- <el-form-item label="抽奖选择" prop="content" v-if="form.taskType == 4">
- <el-select v-model="form.content" placeholder="请选择抽奖" ref="selectRef" >
- <el-option v-for="i in lotteryOptions" :key="i.value" :label="i.label" :value="i.value"></el-option>
- <!-- 加载载中状态 -->
- <div v-if="isLoading" class="loading-indicator">
- <i class="el-icon-loading"></i>
- <span>加载中...</span>
- </div>
- <!-- 没有更多数据 -->
- <div v-if="!hasMore && !isLoading" class="no-more">
- 没有更多数据了
- </div>
- </el-select>
- </el-form-item>
- <el-form-item label="优惠券" prop="content" v-if="form.taskType == 5">
- <el-select v-model="form.content" placeholder="请选择优惠券" ref="selectCoupon" >
- <el-option v-for="i in couponOptions" :key="i.value" :label="i.label" :value="i.value"></el-option>
- <!-- 加载载中状态 -->
- <div v-if="isLoading" class="loading-indicator">
- <i class="el-icon-loading"></i>
- <span>加载中...</span>
- </div>
- <!-- 没有更多数据 -->
- <div v-if="!hasMore && !isLoading" class="no-more">
- 没有更多数据了
- </div>
- </el-select>
- </el-form-item>
- <el-form-item label="商品选择" prop="goodsId" v-if="form.taskType == 6">
- <el-select v-model="form.goodsId" placeholder="请选择商品" ref="selectGoods" >
- <el-option v-for="i in productOptions" :key="i.value" :label="i.label" :value="i.value"></el-option>
- <!-- 加载载中状态 -->
- <div v-if="isLoading" class="loading-indicator">
- <i class="el-icon-loading"></i>
- <span>加载中...</span>
- </div>
- <!-- 没有更多数据 -->
- <div v-if="!hasMore && !isLoading" class="no-more">
- 没有更多数据了
- </div>
- </el-select>
- </el-form-item>
- <el-form-item label="上下架状态" prop="goodsStatus" v-if="form.taskType == 6">
- <el-select v-model="form.goodsStatus" placeholder="请选择上下架状态">
- <el-option v-for="i in goodsStatusOptions" :key="i.value" :label="i.label" :value="i.value"></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="签到奖励" v-if="form.taskType == 7">
- <div class="sign-reward-list">
- <div class="sign-reward-item" v-for="(item, index) in form.rewards" :key="index">
- <el-select v-model="item.rewardType" placeholder="奖励类型" style="width: 120px; margin-right: 8px;" @change="onSignRewardTypeChange(item, index)">
- <el-option v-for="i in rewardTypeOptions" :key="i.value" :label="i.label" :value="i.value"></el-option>
- </el-select>
- <el-select v-if="item.rewardType == 2" v-model="item.rewardId" placeholder="请选择积分红包" style="width: 180px; margin-right: 8px;">
- <el-option v-for="i in redOptions" :key="i.value" :label="i.label" :value="i.value"></el-option>
- </el-select>
- <template v-else-if="item.rewardType == 5">
- <el-select v-model="item.rewardId" placeholder="请选择优惠券" style="width: 160px; margin-right: 8px;">
- <el-option v-for="i in couponOptions" :key="i.value" :label="i.label" :value="i.value"></el-option>
- </el-select>
- <el-input-number v-model="item.couponCount" :min="1" :max="99" controls-position="right" placeholder="数量" style="width: 110px; margin-right: 8px;"></el-input-number>
- <span style="margin-right: 8px; color: #909399;">张</span>
- </template>
- <el-input v-else-if="item.rewardType == 6" v-model="item.amount" placeholder="金额精确到0.1元" style="width: 180px; margin-right: 8px;" @input="onCashAmountInput(item)"></el-input>
- <el-button type="text" icon="el-icon-delete" @click="removeSignReward(index)" v-if="form.rewards.length > 1">删除</el-button>
- </div>
- <el-button type="text" icon="el-icon-plus" @click="addSignReward">添加奖励</el-button>
- </div>
- </el-form-item>
- <el-form-item label="触发时间" prop="content">
- <el-time-picker
- default-value="2025-01-01 00:00:00"
- v-model="form.triggerValue"
- :picker-options="{
- selectableRange: '00:00:00 - 23:59:59'
- }"
- placeholder="任意时间点">
- </el-time-picker>
- </el-form-item>
- <!-- <el-form-item label="触发类型" prop="triggerType">-->
- <!-- <el-select v-model="form.triggerType" placeholder="请选择触发类型">-->
- <!-- <el-option label="请选择字典生成" value="" />-->
- <!-- </el-select>-->
- <!-- </el-form-item>-->
- <!-- <el-form-item label="触发值" prop="triggerValue">-->
- <!-- <el-input v-model="form.triggerValue" placeholder="请输入触发值" />-->
- <!-- </el-form-item>-->
- <!-- <el-form-item label="任务内容">-->
- <!-- <editor v-model="form.content" :min-height="192"/>-->
- <!-- </el-form-item>-->
- <el-form-item label="状态">
- <el-radio-group v-model="form.status">
- <el-radio :label="1">启用</el-radio>
- <el-radio :label="0">禁用</el-radio>
- </el-radio-group>
- </el-form-item>
- </el-form>
- <div slot="footer" class="dialog-footer">
- <el-button type="primary" @click="submitForm">确 定</el-button>
- <el-button @click="cancel">取 消</el-button>
- </div>
- </el-dialog>
- </div>
- </template>
- <script>
- import { listTask, getTask, delTask, addTask, updateTask, exportTask } from "@/api/live/task";
- import {listLiveGoods} from "@/api/live/liveGoods";
- import {listLiveRedConfOn} from "@/api/live/liveRedConf";
- import {listLiveLotteryConfOn} from "@/api/live/liveLotteryConf";
- import {listLiveCouponOn} from "@/api/live/liveCoupon";
- export default {
- props:{
- isViewOnly: {
- type: Boolean,
- default: false,
- }
- },
- name: "Task",
- data() {
- return {
- taskTypeOptions:[
- {
- value: 1,
- label: "定时卡片推荐商品"
- },
- {
- value: 2,
- label: "定时红包发送"
- },
- {
- value: 4,
- label: "定时抽奖"
- },
- {
- value: 5,
- label: "定时优惠券"
- },
- {
- value: 6,
- label: "定时商品上下架"
- },
- {
- value: 7,
- label: "签到任务"
- }
- ],
- rewardTypeOptions: [
- { value: 2, label: "积分红包" },
- { value: 5, label: "优惠券" },
- { value: 6, label: "金额红包" }
- ],
- statusOptions:[{
- value: "0",
- label: "禁用"
- },
- {
- value: "1",
- label: "启用"
- }
- ],
- goodsStatusOptions:[{
- value: 0,
- label: "下架"
- },
- {
- value: 1,
- label: "上架"
- }
- ],
- productOptions:[],
- haveData:{
- goods:false,
- red:false,
- lottery:false,
- coupon:false
- },
- redOptions:[],
- lotteryOptions:[],
- couponOptions:[],
- // 遮罩层
- loading: true,
- // 导出遮罩层
- exportLoading: false,
- // 选中数组
- ids: [],
- // 非单个禁用
- single: true,
- // 非多个禁用
- multiple: true,
- // 显示搜索条件
- showSearch: true,
- // 总条数
- total: 0,
- liveAbled: false,
- // 直播间自动化任务配置表格数据
- taskList: [],
- // 弹出层标题
- title: "",
- // 是否显示弹出层
- open: false,
- // 查询参数
- queryParams: {
- pageNum: 1,
- pageSize: 10,
- liveId: null,
- taskName: null,
- taskType: null,
- triggerType: null,
- triggerValue: null,
- content: null,
- status: null,
- createdTime: null,
- updatedTime: null
- },
- // 表单参数
- form: {},
- // 表单校验
- rules: {
- liveId: [
- { required: true, message: "直播间ID不能为空", trigger: "blur" }
- ],
- taskName: [
- { required: true, message: "任务名称不能为空", trigger: "blur" }
- ],
- taskType: [
- { required: true, message: "任务类型:1-定时推送卡片商品 2-定时发送红包 ", trigger: "change" }
- ],
- triggerType: [
- { required: true, message: "触发类型:相对直播开始时间不能为空", trigger: "change" }
- ],
- triggerValue: [
- { required: true, message: "触发值:绝对时间用yyyy-MM-dd HH:mm:ss,相对时间用分钟数不能为空", trigger: "blur" }
- ],
- status: [
- { required: true, message: "状态:0-禁用 1-启用不能为空", trigger: "blur" }
- ],
- createdTime: [
- { required: true, message: "创建时间不能为空", trigger: "blur" }
- ],
- updatedTime: [
- { required: true, message: "更新时间不能为空", trigger: "blur" }
- ]
- },
- liveId: null,
- listParams: {
- pageNum: 1,
- pageSize: 10,
- liveId: null
- },
- socket: null,
- isLoading: false, // 是否正在加载
- hasMore: true, // 是否还有更多数据
- };
- },
- watch: {
- // 监听路由的 query 参数变化
- '$route.query': {
- handler(newQuery) {
- if (this.$route.params.liveId) {
- this.liveId = this.$route.params.liveId;
- }else {
- this.liveId = this.$route.query.liveId;
- }
- if(this.liveId == null) {
- return;
- }
- this.liveAbled = true
- this.queryParams.liveId = this.liveId;
- this.getList();
- },
- // 初始化时立即执行一次
- immediate: true
- }
- },
- created() {
- this.socket = this.$store.state.liveWs[this.liveId]
- },
- methods: {
- statusFormatter(row, column, value){
- if (!value) return '--'; // 空值处理
- switch ( value){
- case 0:
- return "禁用";
- case 1:
- return "启用";
- default:
- return "--";
- }
- },
- finishStatusFormatter(row, column, value){
- if (!value) return '--'; // 空值处理
- switch ( value){
- case 0:
- return "未执行";
- case 1:
- return "已执行";
- default:
- return "--";
- }
- },
- taskTypeFormatter(row, column, value){
- if (!value) return '--'; // 空值处理
- switch (value) {
- case 1:
- return "定时推送卡片商品";
- case 2:
- return "定时发送红包";
- case 4:
- return "定时抽奖";
- case 5:
- return "定时优惠券";
- case 6:
- return "定时商品上下架";
- case 7:
- return "签到任务";
- default:
- return "--";
- }
- },
- triggerTypeFormatter(row, column, value){
- if (!value) return '--'; // 空值处理
- switch (value) {
- case 1:
- return "相对直播开始时间";
- case 2:
- return "相对时间";
- default:
- return "--";
- }
- },
- productNameFormatter(row, column, value){
- let content = JSON.parse(row.content)
- if(content.productName) {
- return content.productName
- }
- if (row.taskType == 7) {
- const rewards = Array.isArray(content.rewards) ? content.rewards : null;
- if (rewards && rewards.length) {
- return rewards.map(r => {
- if (!r) return '';
- if (r.rewardType == 2) return (r.reward && r.reward.desc) || '积分红包';
- if (r.rewardType == 5) {
- const title = (r.reward && r.reward.title) || '优惠券';
- const count = r.couponCount > 0 ? r.couponCount : 1;
- return title + '×' + count;
- }
- if (r.rewardType == 6) return '金额红包¥' + (r.amount != null ? r.amount : '--');
- return '';
- }).filter(Boolean).join('、') || '--';
- }
- if (content.reward) {
- if (content.rewardType == 2) return content.reward.desc || '--';
- if (content.rewardType == 5) return content.reward.title || '--';
- }
- }
- if (row.taskType == 2 && content.desc) return content.desc;
- if (row.taskType == 4 && content.desc) return content.desc;
- if (row.taskType == 5 && content.title) return content.title;
- return "--";
- },
- triggerValueFormatter(row, column, value) {
- if (!value) return '--'; // 空值处理
- // 创建日期对象(兼容时间戳和字符串)
- let date;
- if (typeof value === 'number') {
- // 处理时间戳(注意:如果是10位时间戳需要乘以1000)
- date = new Date(value.toString().length === 10 ? value * 1000 : value);
- } else if (typeof value === 'string') {
- // 处理字符串格式(尝试直接转换)
- date = new Date(value);
- } else {
- return '格式错误';
- }
- // 检查日期是否有效
- if (isNaN(date.getTime())) {
- return '无效时间';
- }
- // 格式化日期为 "yyyy-MM-dd HH:mm:ss"
- const hours = String(date.getHours()).padStart(2, '0');
- const minutes = String(date.getMinutes()).padStart(2, '0');
- const seconds = String(date.getSeconds()).padStart(2, '0');
- return `${hours}:${minutes}:${seconds}`;
- },
- async updateTaskType(){
- this.hasMore = true;
- this.listParams = {
- pageNum: 1,
- pageSize: 10,
- liveId: null
- }
- this.form.content = null;
- this.form.goodsId = null;
- this.form.goodsStatus = null;
- this.form.rewardType = null;
- this.form.rewardId = null;
- this.form.rewards = this.form.taskType == 7 ? [{ rewardType: null, rewardId: null, couponCount: 1, amount: null }] : [];
- if (this.isLoading || !this.hasMore) return;
- this.isLoading = true;
- this.listParams.liveId = this.liveId;
- if(this.listParams.liveId == null) {
- this.$message.error("页面错误,请联系管理员");
- return;
- }
- try{
- if (this.form.taskType == 1) {
- await this.addGoodsList();
- }else if (this.form.taskType == 2) {
- await this.addRedList();
- }else if (this.form.taskType == 4) {
- await this.addLotteryList();
- }else if(this.form.taskType == 5){
- await this.addCouponList();
- }else if(this.form.taskType == 6){
- await this.addGoodsList();
- }else if(this.form.taskType == 7){
- await this.preloadAllSignRewardOptions();
- }
- }catch ( err){
- console.error('加载数据失败:', err);
- }finally {
- this.isLoading = false;
- }
- },
- async preloadAllSignRewardOptions() {
- await this.addRedList();
- this.listParams.pageNum = 1;
- this.hasMore = true;
- await this.addCouponList();
- },
- async onSignRewardTypeChange(item) {
- item.rewardId = null;
- item.couponCount = 1;
- item.amount = null;
- if (!item.rewardType) return;
- const others = (this.form.rewards || []).filter(r => r !== item);
- if (item.rewardType == 2 && others.some(r => r.rewardType == 2)) {
- this.msgError("积分红包只能配置一个");
- item.rewardType = null;
- return;
- }
- if (item.rewardType == 6 && others.some(r => r.rewardType == 6)) {
- this.msgError("金额红包只能配置一个");
- item.rewardType = null;
- return;
- }
- this.listParams = { pageNum: 1, pageSize: 10, liveId: this.liveId };
- this.hasMore = true;
- if (item.rewardType == 2) await this.addRedList();
- else if (item.rewardType == 5) await this.addCouponList();
- },
- onCashAmountInput(item) {
- if (item.amount == null || item.amount === '') return;
- let val = String(item.amount).replace(/[^\d.]/g, '');
- const parts = val.split('.');
- if (parts.length > 2) {
- val = parts[0] + '.' + parts.slice(1).join('');
- }
- // 金额红包精确到 0.1 元(一位小数)
- if (parts.length === 2) {
- val = parts[0] + '.' + parts[1].slice(0, 1);
- }
- item.amount = val;
- },
- addSignReward() {
- if (!this.form.rewards) this.form.rewards = [];
- this.form.rewards.push({ rewardType: null, rewardId: null, couponCount: 1, amount: null });
- },
- removeSignReward(index) {
- this.form.rewards.splice(index, 1);
- },
- async loadSignRewardOptions(rewardType) {
- this.hasMore = true;
- this.listParams = {
- pageNum: 1,
- pageSize: 10,
- liveId: this.liveId
- }
- if (rewardType == 2) {
- await this.addRedList();
- } else if (rewardType == 5) {
- await this.addCouponList();
- }
- },
- addGoodsList() {
- if(this.haveData.goods) return
- listLiveGoods(this.listParams).then(res => {
- if(res.rows.length > 0) {
- res.rows.forEach(item => {
- // 根据productName和goodsId组装成为label和value
- this.productOptions.push({
- value: item.goodsId,
- label: item.productName
- })
- })
- this.listParams.pageNum++;
- // 判断是否还有更多数据
- this.hasMore = this.productOptions.length < res.total;
- if (this.hasMore) {
- this.addGoodsList();
- } else {
- this.haveData.goods = true;
- }
- } else {
- this.hasMore = false;
- this.haveData.goods = true;
- }
- });
- },
- addRedList() {
- if(this.haveData.red) return
- listLiveRedConfOn(this.listParams).then(res => {
- if(res.rows.length > 0) {
- res.rows.forEach(item => {
- // 根据productName和goodsId组装成为label和value
- this.redOptions.push({
- value: item.redId,
- label: item.desc
- })
- })
- this.listParams.pageNum++;
- // 判断是否还有更多数据
- this.hasMore = this.redOptions.length < res.total;
- if (this.hasMore) {
- this.addRedList();
- } else {
- this.haveData.red = true
- }
- } else {
- this.haveData.red = true
- this.hasMore = false;
- }
- });
- },
- addLotteryList() {
- if(this.haveData.lottery) return
- listLiveLotteryConfOn(this.listParams).then(res => {
- if(res.rows.length > 0) {
- res.rows.forEach(item => {
- // 根据productName和goodsId组装成为label和value
- this.lotteryOptions.push({
- value: item.lotteryId,
- label: item.desc
- })
- })
- this.listParams.pageNum++;
- // 判断是否还有更多数据
- this.hasMore = this.lotteryOptions.length < res.total;
- if (this.hasMore) {
- this.addLotteryList();
- } else {
- this.haveData.lottery = true
- }
- } else {
- this.haveData.lottery = true
- this.hasMore = false;
- }
- });
- },
- addCouponList() {
- if(this.haveData.coupon) return
- listLiveCouponOn(this.listParams).then(res => {
- if(res.rows.length > 0) {
- res.rows.forEach(item => {
- // 根据productName和goodsId组装成为label和value
- this.couponOptions.push({
- value: item.couponId,
- label: item.title
- })
- })
- this.listParams.pageNum++;
- // 判断是否还有更多数据
- this.hasMore = this.couponOptions.length < res.total;
- if (this.hasMore) {
- this.addCouponList();
- } else {
- this.haveData.coupon = true
- }
- } else {
- this.haveData.coupon = true
- this.hasMore = false;
- }
- });
- },
- /** 查询直播间自动化任务配置列表 */
- getList() {
- if(this.liveId == null) {
- this.$message.error("页面错误,请联系管理员");
- return;
- }
- this.loading = true;
- listTask(this.queryParams).then(res => {
- this.taskList = res.rows;
- this.total = res.total;
- this.loading = false;
- });
- },
- // 取消按钮
- cancel() {
- this.open = false;
- this.reset();
- },
- // 表单重置
- reset() {
- this.form = {
- id: null,
- liveId: this.liveId,
- taskName: null,
- taskType: null,
- triggerType: null,
- triggerValue: null,
- content: null,
- goodsId: null,
- goodsStatus: null,
- rewardType: null,
- rewardId: null,
- rewards: [],
- status: 1,
- createdTime: null,
- updatedTime: null
- };
- this.listParams={
- pageNum: 1,
- pageSize: 10,
- liveId: this.liveId
- }
- this.hasMore = true;
- this.resetForm("form");
- },
- /** 搜索按钮操作 */
- handleQuery() {
- this.queryParams.pageNum = 1;
- this.getList();
- },
- /** 重置按钮操作 */
- resetQuery() {
- this.resetForm("queryForm");
- this.handleQuery();
- },
- // 多选框选中数据
- handleSelectionChange(selection) {
- this.ids = selection.map(item => item.id)
- this.single = selection.length!==1
- this.multiple = !selection.length
- },
- /** 新增按钮操作 */
- handleAdd() {
- this.reset();
- this.open = true;
- this.title = "添加直播间自动化任务配置";
- },
- /** 修改按钮操作 */
- async handleUpdate(row) {
- this.reset();
- if(row.taskType == 1){
- await this.addGoodsList();
- }else if(row.taskType == 2){
- await this.addRedList();
- }else if(row.taskType == 4){
- await this.addLotteryList();
- }else if(row.taskType == 5) {
- await this.addCouponList();
- }else if(row.taskType == 6) {
- await this.addGoodsList();
- }
- const id = row.id || this.ids
- getTask(id).then(async response => {
- this.form = response.data;
- let content = JSON.parse( response.data.content)
- if (this.form.taskType == 1) {
- this.form.content = content.goodsId;
- }else if (this.form.taskType == 2) {
- this.form.content = content.redId;
- }else if (this.form.taskType == 4) {
- this.form.content = content.lotteryId;
- }else if(this.form.taskType == 5){
- this.form.content = content.couponId;
- }else if(this.form.taskType == 6){
- this.form.goodsId = content.goodsId;
- this.form.goodsStatus = content.status;
- }else if(this.form.taskType == 7){
- await this.preloadAllSignRewardOptions();
- const rewards = [];
- if (Array.isArray(content.rewards) && content.rewards.length) {
- content.rewards.forEach(r => {
- let rewardId = r.rewardId;
- if (rewardId == null && r.reward) {
- if (r.rewardType == 2) rewardId = r.reward.redId;
- else if (r.rewardType == 5) rewardId = r.reward.couponId;
- }
- rewards.push({
- rewardType: r.rewardType != null ? Number(r.rewardType) : null,
- rewardId: rewardId,
- couponCount: r.couponCount > 0 ? Number(r.couponCount) : 1,
- amount: r.amount != null ? r.amount : null
- });
- });
- } else if (content.rewardType != null) {
- // 兼容旧单奖励结构
- let rewardId = content.rewardId;
- if (rewardId == null && content.reward) {
- if (content.rewardType == 2) rewardId = content.reward.redId;
- else if (content.rewardType == 5) rewardId = content.reward.couponId;
- }
- rewards.push({
- rewardType: Number(content.rewardType),
- rewardId: rewardId,
- couponCount: content.couponCount > 0 ? Number(content.couponCount) : 1,
- amount: content.amount != null ? content.amount : null
- });
- }
- this.form.rewards = rewards.length ? rewards : [{ rewardType: null, rewardId: null, couponCount: 1, amount: null }];
- }
- this.open = true;
- this.title = "修改直播间自动化任务配置";
- });
- },
- /** 提交按钮 */
- submitForm() {
- this.form.liveId = this.liveId;
- if(this.liveId == null) {
- this.msgError("请选择直播间");
- return;
- }
- if(this.form.taskType == 6){
- if(this.form.goodsId == null) {
- this.msgError("请选择商品");
- return;
- }
- this.form.content = JSON.stringify({
- goodsId: this.form.goodsId,
- status: this.form.goodsStatus
- })
- }
- if(this.form.taskType == 7){
- const rewards = [];
- let hasPointRed = false;
- let hasCashRed = false;
- for (const r of (this.form.rewards || [])) {
- if (!r || r.rewardType == null) continue;
- if (r.rewardType == 2) {
- if (r.rewardId == null) {
- this.msgError("请选择积分红包");
- return;
- }
- if (hasPointRed) {
- this.msgError("积分红包只能配置一个");
- return;
- }
- hasPointRed = true;
- rewards.push({ rewardType: 2, rewardId: r.rewardId });
- } else if (r.rewardType == 5) {
- if (r.rewardId == null) {
- this.msgError("请选择优惠券");
- return;
- }
- const couponCount = r.couponCount > 0 ? Number(r.couponCount) : 1;
- rewards.push({ rewardType: 5, rewardId: r.rewardId, couponCount });
- } else if (r.rewardType == 6) {
- if (hasCashRed) {
- this.msgError("金额红包只能配置一个");
- return;
- }
- const amount = Number(r.amount);
- if (!amount || amount <= 0) {
- this.msgError("请输入正确的金额红包金额");
- return;
- }
- // 精确到 0.1 元
- const normalized = Math.round(amount * 10) / 10;
- if (Math.abs(amount - normalized) > 1e-8) {
- this.msgError("金额红包需精确到0.1元");
- return;
- }
- hasCashRed = true;
- rewards.push({ rewardType: 6, amount: normalized.toFixed(1) });
- }
- }
- if (!rewards.length) {
- this.msgError("请至少配置一个签到奖励");
- return;
- }
- this.form.content = JSON.stringify({ rewards })
- }
- this.$refs["form"].validate(valid => {
- if (valid) {
- if (this.form.id != null) {
- updateTask(this.form).then(response => {
- this.msgSuccess("修改成功");
- this.open = false;
- this.getList();
- });
- } else {
- addTask(this.form).then(response => {
- this.msgSuccess("新增成功");
- this.open = false;
- this.getList();
- });
- }
- }
- });
- },
- /** 删除按钮操作 */
- handleDelete(row) {
- if(this.socket == null) {
- this.$message.error("请进入直播间后,在进行操作!")
- return;
- }
- const ids = row.id || this.ids;
- this.$confirm('是否确认删除直播间自动化任务配置编号为"' + ids + '"的数据项?', "警告", {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- type: "warning"
- }).then(function() {
- return delTask(ids);
- }).then(() => {
- this.getList();
- this.msgSuccess("删除成功");
- const msg={
- cmd:'delAutoTask',
- data:row.absValue,
- liveId:this.liveId,
- userType:1
- }
- this.socket.send(JSON.stringify( msg))
- }).catch(() => {});
- },
- /** 导出按钮操作 */
- handleExport() {
- const queryParams = this.queryParams;
- this.$confirm('是否确认导出所有直播间自动化任务配置数据项?', "警告", {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- type: "warning"
- }).then(() => {
- this.exportLoading = true;
- return exportTask(queryParams);
- }).then(response => {
- this.download(response.msg);
- this.exportLoading = false;
- }).catch(() => {});
- },
- }
- };
- </script>
- <style scoped>
- .loading-indicator {
- padding: 10px;
- text-align: center;
- color: #606266;
- font-size: 12px;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .loading-indicator .el-icon-loading {
- margin-right: 5px;
- animation: rotate 1s linear infinite;
- }
- .no-more {
- padding: 10px;
- text-align: center;
- color: #909399;
- font-size: 12px;
- }
- @keyframes rotate {
- from { transform: rotate(0deg); }
- to { transform: rotate(360deg); }
- }
- .sign-reward-list {
- width: 100%;
- }
- .sign-reward-item {
- display: flex;
- align-items: center;
- margin-bottom: 8px;
- flex-wrap: wrap;
- }
- </style>
|