xw пре 1 дан
родитељ
комит
2ad224b062

+ 13 - 0
src/api/live/liveRedConf.js

@@ -62,3 +62,16 @@ export function listLiveRedConfOn(query) {
   })
 }
 
+// 设置自动化红包(前端自动计算结束时间 = 开始时间 + 持续时间)
+export function setAutoRed(redId, autoStartTime, autoSettlementTime) {
+  return request({
+    url: '/live/liveRedConf/setAutoRed',
+    method: 'post',
+    params: {
+      redId,
+      autoStartTime,
+      autoSettlementTime
+    }
+  })
+}
+

+ 1 - 1
src/views/live/liveConfig/index.vue

@@ -139,7 +139,7 @@ export default {
       menuList:[
         { name: '观看奖励', label: '观看奖励', index: 'watchReward'},
         { name: '直播预告', label: '直播预告', index: 'preview'},
-        { name: '红包配置', label: '红包配置', index: 'liveRedConf'},
+        { name: '积分配置', label: '积分配置', index: 'liveRedConf'},
         { name: '抽奖配置', label: '抽奖配置', index: 'liveLotteryConf'},
         { name: '优惠券配置', label: '优惠券配置', index: 'liveCoupon'},
         // { name: '答题', label: '答题', index: 'answer'},

+ 236 - 38
src/views/live/liveConfig/liveRedConf.vue

@@ -1,13 +1,13 @@
 <template>
   <div class="app-container">
     <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
-      <el-form-item label="红包状态" prop="redStatus">
-        <el-select v-model="queryParams.redStatus" placeholder="请选择红包状态" clearable size="small">
+      <el-form-item label="积分状态" prop="redStatus">
+        <el-select v-model="queryParams.redStatus" placeholder="请选择积分状态" clearable size="small">
           <el-option v-for="(item,index) in redStatusOptions" :key="item.dictValue+index" :label="item.dictLabel" :value="item.dictValue" />
         </el-select>
       </el-form-item>
-      <el-form-item label="红包类型" prop="redType">
-        <el-select v-model="queryParams.redType" placeholder="请选择红包类型" clearable size="small">
+      <el-form-item label="积分类型" prop="redType">
+        <el-select v-model="queryParams.redType" placeholder="请选择积分类型" clearable size="small">
           <el-option v-for="(item,index) in redTypeOptions" :key="item.dictValue+index" :label="item.dictLabel" :value="item.dictValue" />
         </el-select>
       </el-form-item>
@@ -21,7 +21,7 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="红包标题" prop="desc">
+      <el-form-item label="积分描述" prop="desc">
         <el-input
           v-model="queryParams.desc"
           placeholder="请输入描述"
@@ -90,15 +90,15 @@
 
     <el-table border v-loading="loading" :data="liveRedConfList" @selection-change="handleSelectionChange">
       <el-table-column type="selection" width="55" align="center" />
-      <el-table-column label="红包ID" align="center" prop="redId" />
-      <el-table-column label="红包状态" align="center" prop="redStatus" :formatter="redStatusFormatter"/>
+      <el-table-column label="积分ID" align="center" prop="redId" />
+      <el-table-column label="积分状态" align="center" prop="redStatus" :formatter="redStatusFormatter"/>
       <el-table-column label="有效时间 单位:分" align="center" prop="duration" />
-      <el-table-column label="红包类型" align="center" prop="redType" :formatter="redTypeFormatter"/>
+      <el-table-column label="积分类型" align="center" prop="redType" :formatter="redTypeFormatter"/>
       <el-table-column label="直播间ID" align="center" prop="liveId" />
       <el-table-column label="积分数量" align="center" prop="redNum" />
       <el-table-column label="可中奖份量" align="center" prop="totalLots" />
       <el-table-column label="实际发放奖励份量" align="center" prop="totalSend" />
-      <el-table-column label="红包标题" align="center" prop="desc" />
+      <el-table-column label="积分标题" align="center" prop="desc" />
       <el-table-column label="创建日期" align="center" prop="createTime" width="120">
         <template slot-scope="scope">
           <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
@@ -151,6 +151,15 @@
             @click="handleDelete(scope.row)"
             v-hasPermi="['live:liveRedConf:edit']"
           >删除</el-button>
+          <!-- 自动化红包按钮 -->
+          <el-button
+            v-if="scope.row.redStatus+'' === '0'"
+            size="mini"
+            type="text"
+            icon="el-icon-time"
+            @click="handleAutoRed(scope.row)"
+            style="margin-left: 10px"
+          >自动化红包</el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -163,17 +172,33 @@
       @pagination="getList"
     />
 
-    <!-- 添加或修改直播红包记录配置对话框 -->
+    <!-- 添加或修改直播积分记录配置对话框 -->
     <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
-      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
-        <el-form-item label="持续时间" prop="duration">
-          <el-input v-model="form.duration" placeholder="请输入红包有效时间 单位:分" />
-        </el-form-item>
-<!--        <el-form-item label="红包类型" prop="redType">
-          <el-select v-model="form.redType" placeholder="请选择红包类型">
-            <el-option v-for="(item,index) in redTypeOptions" :key="item.dictValue+index" :label="item.dictLabel" :value="item.dictValue" />
+      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
+        <el-form-item label="参与方式" prop="require">
+          <el-select v-model="form.require" placeholder="请选择参与红包方式">
+            <el-option v-for="(item,index) in requireOptions" :key="item.dictValue+index" :label="item.dictLabel" :value="item.dictValue" />
           </el-select>
-        </el-form-item>-->
+        </el-form-item>
+        <!-- 评论关键词配置(仅当选择评论参与时显示) -->
+        <el-form-item 
+          v-if="form.require+'' === '4'" 
+          label="评论关键词" 
+          prop="requireConf"
+          style="margin-top: 20px;"
+        >
+          <el-input 
+            v-model="form.requireConf" 
+            placeholder="请输入评论关键词,例如:666、红包、我要红包" 
+            clearable
+          />
+          <span style="display: block; margin-top: 5px; font-size: 12px; color: #909399;">
+            💡 提示:用户发送包含该关键词的评论即可参与红包
+          </span>
+        </el-form-item>
+        <el-form-item label="持续时间" prop="duration" :style="form.require+'' === '4' ? '' : 'margin-top: 50px;'">
+          <el-input v-model="form.duration" placeholder="请输入积分有效时间 单位:分" />
+        </el-form-item>
         <el-form-item label="直播间ID" prop="liveId">
           <el-input v-model="form.liveId" placeholder="请输入直播间ID" :disabled="canLiveId"/>
         </el-form-item>
@@ -183,8 +208,8 @@
         <el-form-item label="中奖份量" prop="totalLots">
           <el-input v-model="form.totalLots" placeholder="请输入可中奖份量" />
         </el-form-item>
-        <el-form-item label="红包标题" prop="desc">
-          <el-input v-model="form.desc" placeholder="请输入红包描述" />
+        <el-form-item label="积分标题" prop="desc">
+          <el-input v-model="form.desc" placeholder="请输入积分描述" />
         </el-form-item>
       </el-form>
       <div slot="footer" class="dialog-footer">
@@ -192,19 +217,79 @@
         <el-button @click="cancel">取 消</el-button>
       </div>
     </el-dialog>
+
+    <!-- 自动化红包设置对话框 -->
+    <el-dialog 
+      title="设置自动化红包" 
+      :visible.sync="autoRedDialogVisible" 
+      width="500px" 
+      append-to-body
+    >
+      <el-form ref="autoRedForm" :model="autoRedForm" :rules="autoRedRules" label-width="130px">
+        <el-form-item label="红包ID" prop="redId">
+          <el-input v-model="autoRedForm.redId" disabled />
+        </el-form-item>
+        <el-form-item label="持续时间" prop="duration">
+          <el-input v-model="autoRedForm.duration" disabled>
+            <template slot="append">分钟</template>
+          </el-input>
+          <span style="display: block; margin-top: 5px; font-size: 12px; color: #909399;">
+            💡 提示:红包将持续 {{ autoRedForm.duration }} 分钟后自动结算
+          </span>
+        </el-form-item>
+        <el-form-item label="自动开始时间" prop="autoStartTime">
+          <el-date-picker
+            v-model="autoRedForm.autoStartTime"
+            type="datetime"
+            placeholder="请选择红包自动开始时间"
+            value-format="yyyy-MM-dd HH:mm:ss"
+            style="width: 100%"
+            :picker-options="redStartTimePickerOptions"
+          />
+          <span v-if="calculatedRedEndTime" style="display: block; margin-top: 5px; font-size: 12px; color: #67C23A;">
+            ⏰ 预计结束时间:{{ calculatedRedEndTime }}
+          </span>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="autoRedDialogVisible = false">取 消</el-button>
+        <el-button type="primary" @click="submitAutoRed" :loading="autoRedSubmitting">确 定</el-button>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
 <script>
-import { listLiveRedConf, getLiveRedConf, delLiveRedConf, addLiveRedConf, updateLiveRedConf, exportLiveRedConf } from "@/api/live/liveRedConf";
+import { listLiveRedConf, getLiveRedConf, delLiveRedConf, addLiveRedConf, updateLiveRedConf, exportLiveRedConf, setAutoRed } from "@/api/live/liveRedConf";
 
 export default {
   name: "LiveRedConf",
+  computed: {
+    // 计算预计结束时间
+    calculatedRedEndTime() {
+      if (this.autoRedForm.autoStartTime && this.autoRedForm.duration) {
+        const startTime = new Date(this.autoRedForm.autoStartTime);
+        const durationMinutes = parseInt(this.autoRedForm.duration);
+        const endTime = new Date(startTime.getTime() + durationMinutes * 60 * 1000);
+        
+        const year = endTime.getFullYear();
+        const month = String(endTime.getMonth() + 1).padStart(2, '0');
+        const day = String(endTime.getDate()).padStart(2, '0');
+        const hours = String(endTime.getHours()).padStart(2, '0');
+        const minutes = String(endTime.getMinutes()).padStart(2, '0');
+        const seconds = String(endTime.getSeconds()).padStart(2, '0');
+        
+        return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+      }
+      return '';
+    }
+  },
   data() {
     return {
       //字典
       redStatusOptions: [],
       redTypeOptions: [],
+      requireOptions: [],
       canLiveId:false,
       //parentLiveId
       parentLiveId : null,
@@ -222,12 +307,31 @@ export default {
       showSearch: true,
       // 总条数
       total: 0,
-      // 直播红包记录配置表格数据
+      // 直播积分记录配置表格数据
       liveRedConfList: [],
       // 弹出层标题
       title: "",
       // 是否显示弹出层
       open: false,
+      // 自动化红包对话框
+      autoRedDialogVisible: false,
+      autoRedSubmitting: false,
+      autoRedForm: {
+        redId: '',
+        duration: 0,
+        autoStartTime: ''
+      },
+      autoRedRules: {
+        autoStartTime: [
+          { required: true, message: '请选择自动开始时间', trigger: 'change' },
+          { validator: this.validateRedStartTime, trigger: 'change' }
+        ]
+      },
+      redStartTimePickerOptions: {
+        disabledDate: (time) => {
+          return time.getTime() < Date.now() - 8.64e7; // 禁止选择今天之前的日期
+        }
+      },
       // 查询参数
       queryParams: {
         pageNum: 1,
@@ -243,12 +347,15 @@ export default {
       form: {},
       // 表单校验
       rules: {
+        require: [
+          { required: true, message: "参与红包方式", trigger: "blur" }
+        ],
+        requireConf: [
+          { validator: this.validRequireConf, message: "当参与方式选择为“送礼参与”或“下单参与”或“评论参与”时,对应的配置不能为空", trigger: "blur" }
+        ],
         duration: [
           { required: true, message: "有效时间 单位:分不能为空", trigger: "blur" }
         ],
-        /* redType: [
-          { required: true, message: "红包类型不能为空", trigger: "change" }
-        ], */
         liveId: [
           { required: true, message: "直播间ID不能为空", trigger: "blur" }
         ],
@@ -297,10 +404,35 @@ export default {
     this.getDicts("sys_live_red_type").then(response => {
       this.redTypeOptions = response.data;
     });
+    // 1在线观众  2下单 3送礼 4评论
+    this.getDicts("sys_live_lottery_require").then(response => {
+      this.requireOptions = response.data;
+    });
   },
-  computed: {
+  mounted() {
+    this.$watch(
+      () => this.form.require,
+      (newVal) => {
+        this.$refs.form.validateField('requireConf');
+      }
+    );
   },
   methods: {
+    validRequireConf(rule, value, callback) {
+      // 当参与方式为"送礼参与"(2)、"下单参与"(3)或"评论参与"(4)时,requireConf不能为空
+      if(this.form.require+"" === "2" || this.form.require+"" === "3" || this.form.require+"" === "4"){
+        if(!value || value.trim() === ""){
+          if(this.form.require+"" === "4") {
+            callback(new Error('请输入评论关键词'));
+          } else {
+            callback(new Error('当参与方式选择为送礼参与或下单参与时,对应的配置不能为空'));
+          }
+          return false;
+        }
+      }
+      callback();
+      return true;
+    },
     handleStatusChange(row, status) {
       if (this.$store.state.liveWs[this.liveId] == null) {
         this.msgError("请从直播间进行操作!");
@@ -308,28 +440,28 @@ export default {
       }
       //结束的抽奖不能进行操作
       if(row.redStatus+"" === "2"){
-        this.msgError("已结束的红包不能进行操作");
+        this.msgError("已结束的积分不能进行操作");
         return;
       }
       switch (status+"") {
         case "1":
           //只能对未开启的抽奖进行操作
           if(row.redStatus+"" !== "0" && row.redStatus+"" !== "3"){
-            this.msgError("只能对未开启或暂停的红包进行开始操作");
+            this.msgError("只能对未开启或暂停的积分进行开始操作");
             return;
           }
           break;
         case "2":
-          //只能对进行中或暂停的红包进行结算
+          //只能对进行中或暂停的积分进行结算
           if(row.redStatus+"" !== "1" && row.redStatus+"" !== "3"){
-            this.msgError("只能对进行中或暂停的红包进行结算");
+            this.msgError("只能对进行中或暂停的积分进行结算");
             return;
           }
           break;
         case "3":
           //只能对进行中的抽奖执行暂停操作
           if(row.redStatus+"" !== "1"){
-            this.msgError("只能对进行中的红包执行暂停操作");
+            this.msgError("只能对进行中的积分执行暂停操作");
             return;
           }
           break;
@@ -369,7 +501,7 @@ export default {
     redTypeFormatter(row, column) {
       return this.selectDictLabel(this.redTypeOptions, row.redType);
     },
-    /** 查询直播红包记录配置列表 */
+    /** 查询直播积分记录配置列表 */
     getList() {
       this.loading = true;
       listLiveRedConf(this.queryParams).then(response => {
@@ -431,13 +563,13 @@ export default {
     handleAdd() {
       this.reset();
       this.open = true;
-      this.title = "添加直播红包记录配置";
+      this.title = "添加直播积分记录配置";
     },
     /** 修改按钮操作 */
     handleUpdate(row) {
       //只能对未开始或暂停的抽奖进行修改
       if(row.redStatus+"" !== "0" && row.redStatus+"" !== "3"){
-        this.msgError("只能对未开始或暂停的红包进行修改");
+        this.msgError("只能对未开始或暂停的积分进行修改");
         return;
       }
       this.reset();
@@ -445,7 +577,7 @@ export default {
       getLiveRedConf(redId).then(response => {
         this.form = response.data;
         this.open = true;
-        this.title = "修改直播红包记录配置";
+        this.title = "修改直播积分记录配置";
       });
     },
     /** 提交按钮 */
@@ -473,11 +605,11 @@ export default {
     handleDelete(row) {
       //如果状态不为0,则不能删除
       if (row.redStatus+"" !== "0") {
-        this.msgError("只能删除未发放的红包");
+        this.msgError("只能删除未发放的积分");
         return;
       }
       const redIds = row.redId || this.ids;
-      this.$confirm('是否确认删除直播红包记录配置编号为"' + redIds + '"的数据项?', "警告", {
+      this.$confirm('是否确认删除直播积分记录配置编号为"' + redIds + '"的数据项?', "警告", {
           confirmButtonText: "确定",
           cancelButtonText: "取消",
           type: "warning"
@@ -501,7 +633,7 @@ export default {
     /** 导出按钮操作 */
     handleExport() {
       const queryParams = this.queryParams;
-      this.$confirm('是否确认导出所有直播红包记录配置数据项?', "警告", {
+      this.$confirm('是否确认导出所有直播积分记录配置数据项?', "警告", {
           confirmButtonText: "确定",
           cancelButtonText: "取消",
           type: "warning"
@@ -512,6 +644,72 @@ export default {
           this.download(response.msg);
           this.exportLoading = false;
         }).catch(() => {});
+    },
+    /** 自动化红包按钮操作 */
+    handleAutoRed(row) {
+      // 重置表单
+      this.autoRedForm = {
+        redId: row.redId,
+        duration: row.duration || 0,
+        autoStartTime: ''
+      };
+      // 清空验证
+      this.$nextTick(() => {
+        if (this.$refs.autoRedForm) {
+          this.$refs.autoRedForm.clearValidate();
+        }
+      });
+      this.autoRedDialogVisible = true;
+    },
+    /** 验证自动开始时间 */
+    validateRedStartTime(rule, value, callback) {
+      if (!value) {
+        callback(new Error('请选择自动开始时间'));
+        return;
+      }
+      const startTime = new Date(value).getTime();
+      const now = Date.now();
+      if (startTime < now) {
+        callback(new Error('自动开始时间不能早于当前时间'));
+        return;
+      }
+      callback();
+    },
+    /** 提交自动化红包设置 */
+    submitAutoRed() {
+      this.$refs.autoRedForm.validate(valid => {
+        if (valid) {
+          this.autoRedSubmitting = true;
+          
+          const { redId, autoStartTime } = this.autoRedForm;
+          
+          // 前端计算结束时间 = 开始时间 + 持续时间(分钟)
+          const autoSettlementTime = this.calculatedRedEndTime;
+          
+          console.log('自动化红包设置请求参数:', { redId, autoStartTime, autoSettlementTime });
+          
+          // 调用接口
+          setAutoRed(redId, autoStartTime, autoSettlementTime)
+            .then(response => {
+              console.log('自动化红包设置返回数据:', response);
+              
+              if (response.code === 200) {
+                this.$message.success('自动化红包设置成功');
+                this.autoRedDialogVisible = false;
+                this.getList(); // 刷新列表
+              } else {
+                this.$message.error(response.msg || '设置失败');
+              }
+            })
+            .catch(error => {
+              console.error('自动化红包设置失败:', error);
+              this.$message.error('设置失败,请稍后重试');
+            })
+            .finally(() => {
+              this.autoRedSubmitting = false;
+            });
+        }
+      });
     }
   }
 };

+ 1 - 1
src/views/live/liveConsole/index-backup.vue

@@ -134,7 +134,7 @@
       <div style="display: flex; justify-content: space-around; padding: 15px 0; background: #fff; border-top: 1px solid #f0f0f0;">
         <div style="display: flex; flex-direction: column; align-items: center; cursor: pointer;" @click="handleClickRed">
           <i class="el-icon-money" style="font-size: 20px;"></i>
-          <span style="font-size: 12px; margin-top: 4px;">红包配置</span>
+          <span style="font-size: 12px; margin-top: 4px;">积分配置</span>
         </div>
         <div style="display: flex; flex-direction: column; align-items: center; cursor: pointer;" @click="handleClickLottery">
           <i class="el-icon-present" style="font-size: 20px;"></i>