瀏覽代碼

Merge remote-tracking branch 'origin/master'

ct 1 周之前
父節點
當前提交
87cbf01cf6

+ 1524 - 0
src/views/components/course/userCourseCatalogDetailsZM.vue

@@ -0,0 +1,1524 @@
+<template>
+  <div class="app-container">
+    <div style="padding-bottom: 20px">
+      <span v-if="courseName != null">{{ courseName }}</span>
+    </div>
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="小节名称" prop="title">
+        <el-input v-model="queryParams.title" placeholder="请输入小节名称" clearable size="small"
+                  @keyup.enter.native="handleQuery"/>
+      </el-form-item>
+      <el-form-item label="小节id" prop="videoId">
+        <el-input v-model="queryParams.videoId" placeholder="请输入小节id" clearable size="small"
+                  @keyup.enter.native="handleQuery"/>
+      </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 type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
+                   v-hasPermi="['course:userCourseVideo:add']">新增目录
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="primary" plain :disabled="!ids || ids.length <= 0" size="mini" @click="openUpdates"
+                   v-hasPermi="['course:userCourseVideo:updateTime']">修改时间
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="primary" plain size="mini" @click="openAdds"
+                   v-hasPermi="['course:userCourseVideo:batchAdd']">批量添加
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="primary" plain size="mini" @click="updateRedPageckeOpen"
+                   v-hasPermi="['course:userCourseVideo:updateRed']">修改红包
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete"
+                   v-hasPermi="['course:userCourseVideo:remove']">删除
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="warning" plain icon="el-icon-edit" size="mini" @click="handleCourseSort"
+                   v-hasPermi="['course:userCourseVideo:sort']">修改课节排序
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="primary" plain icon="el-icon-delete" size="mini" @click="handleSync"
+                   v-hasPermi="['course:userCourseVideo:sync']">同步模板数据
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="primary" plain icon="el-icon-edit" size="mini" :disabled="multiple" @click="handleDown"
+                   v-hasPermi="['course:userCourseVideo:batchDown']">批量下架
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="primary" plain icon="el-icon-edit" size="mini" :disabled="multiple" @click="handleUp"
+                   v-hasPermi="['course:userCourseVideo:batchUp']">批量上架</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="primary" plain icon="el-icon-edit" size="mini" :disabled="multiple" @click="handleEditCover"
+                   v-hasPermi="['course:userCourseVideo:batchEditCover']">批量修改封面图
+        </el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+    <el-table border v-loading="loading" :data="userCourseVideoList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+      <el-table-column label="视频ID" align="center" prop="videoId"/>
+      <el-table-column label="小节名称" align="center" show-overflow-tooltip prop="title"/>
+      <el-table-column label="视频文件名称" align="center" show-overflow-tooltip prop="fileName">
+      </el-table-column>
+      <el-table-column label="视频时长" align="center" prop="duration">
+        <template slot-scope="{ row }">
+          {{ formatDuration(row.duration) }}
+        </template>
+      </el-table-column>
+      <el-table-column label="看课开始时间" align="center" prop="duration">
+        <template slot-scope="{ row }">
+          <el-tag v-if="row.viewStartTime">{{ row.viewStartTime }}</el-tag>
+          <el-tag type="danger" v-if="!row.viewStartTime">无</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="看课结束时间" align="center" prop="duration">
+        <template slot-scope="{ row }">
+          <el-tag v-if="row.viewEndTime">{{ row.viewEndTime }}</el-tag>
+          <el-tag type="danger" v-if="!row.viewEndTime">无</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="领取红包时间" align="center" prop="duration">
+        <template slot-scope="{ row }">
+          <el-tag v-if="row.lastJoinTime">{{ row.lastJoinTime }}</el-tag>
+          <el-tag type="danger" v-if="!row.lastJoinTime">无</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="红包金额" align="center" prop="redPacketMoney"/>
+      <el-table-column label="排序" align="center" prop="courseSort"/>
+      <el-table-column label="上传时间" align="center" prop="createTime"/>
+      <el-table-column label="是否上架" align="center" prop="isOnPut">
+        <template slot-scope="{ row }">
+          <el-tag v-if="row.isOnPut == 0">是</el-tag>
+          <el-tag type="danger" v-if="row.isOnPut == 1">否</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
+                     v-hasPermi="['course:userCourseVideo:edit']">修改
+          </el-button>
+          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleComment(scope.row)"
+                     v-hasPermi="['course:courseWatchComment:list']">查看评论
+          </el-button>
+          <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
+                     v-hasPermi="['course:userCourseVideo: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="1000px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="110px" v-loading="uploadLoading">
+        <el-form-item label="视频标题" prop="title">
+          <el-input v-model="form.title" placeholder="请输入内容"/>
+        </el-form-item>
+        <el-form-item label="视频描述" prop="description">
+          <el-input v-model="form.description" type="textarea" :rows="2" placeholder="请输入内容"/>
+        </el-form-item>
+        <el-form-item label="课程排序" prop="courseSort">
+          <el-input-number v-model="form.courseSort" :min="1"></el-input-number>
+        </el-form-item>
+
+        <el-form-item label="视频缩略图" prop="thumbnail">
+          <el-upload v-model="form.thumbnail" class="avatar-uploader" :action="uploadUrl" :show-file-list="false"
+                     :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
+            <img v-if="form.thumbnail" :src="form.thumbnail" class="avatar" width="300px">
+            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+          </el-upload>
+        </el-form-item>
+        <video-upload :type="1" :isPrivate="isPrivate" :fileKey.sync="form.fileKey" :fileSize.sync="form.fileSize"
+                      :videoUrl.sync="videoUrl" :fileName.sync="form.fileName" :line_1.sync="form.lineOne"
+                      :line_2.sync="form.lineTwo" :line_3.sync="form.lineThree" :thumbnail.sync="form.thumbnail"
+                      :uploadType.sync="form.uploadType" :isTranscode.sync="form.isTranscode"
+                      :transcodeFileKey.sync="form.transcodeFileKey" @video-duration="handleVideoDuration"
+                      @change="handleVideoChange" @selectProjects="handleSelectProjects" ref="videoUpload"
+                      append-to-body/>
+
+        <el-form-item label="关联疗法" >
+          <el-button size="small" type="primary" @click="choosePackage">选取疗法</el-button>
+          <el-table border width="100%" style="margin-top:5px;"  :data="packageList">
+            <el-table-column label="疗法名称" align="center" prop="packageName"/>
+            <el-table-column label="疗法图片" align="center" prop="imgUrl">
+              <template slot-scope="scope">
+                <img :src="scope.row.imgUrl" style="height: 80px;">
+              </template>
+            </el-table-column>
+            <el-table-column label="疗法别名" align="center" prop="secondName"/>
+            <el-table-column label="总金额" align="center" prop="totalPrice"/>
+            <!-- 根据课程类型控制是否显示弹出时间列:0是公域(显示),1是私域(不显示) -->
+            <el-table-column label="弹出时间" align="center" width="250px" v-if="isPrivate == 0">
+              <template slot-scope="scope">
+                <div>
+                  <el-time-select
+                    v-model="scope.row.duration"
+                    size="mini"
+                    placeholder="选择时间"
+                    :picker-options="getPickerOptions()"
+                    @change="handleTimeChange(scope.$index, scope.row)"
+                  ></el-time-select>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column label="操作" align="center" width="100px" fixed="right">
+              <template slot-scope="scope">
+                <el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-delete"
+                  @click="handlePackageDelete(scope.row)"
+                >删除</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-form-item >
+
+        <el-form-item label="课题选择" prop="questionBankId">
+          <el-button size="small" type="primary" @click="chooseQuestionBank">选取课题</el-button>
+          <el-table border width="100%" style="margin-top:5px;" :data="form.questionBankList">
+            <el-table-column label="问题" align="center" prop="title">
+              <template slot-scope="scope">
+                <el-tooltip class="item" effect="dark" :content="scope.row.title" placement="top">
+                  <div
+                    style="display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; text-overflow: ellipsis;">
+                    <span>{{ scope.row.title }}</span>
+                  </div>
+                </el-tooltip>
+              </template>
+            </el-table-column>
+            <el-table-column label="类别" align="center" prop="type">
+              <template slot-scope="scope">
+                <dict-tag :options="typeOptions" :value="scope.row.type"/>
+              </template>
+            </el-table-column>
+            <el-table-column label="答案" align="center" prop="answer"/>
+            <el-table-column label="操作" align="center" width="100px" fixed="right">
+              <template slot-scope="scope">
+                <el-button size="mini" type="text" icon="el-icon-delete"
+                           @click="handleQuestionBankDelete(scope.row)">删除
+                </el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-form-item>
+        <el-form-item label="红包金额" prop="redPacketMoney">
+          <el-input-number v-model="form.redPacketMoney" :min="0.1" :max="200" :step="0.1"></el-input-number>
+        </el-form-item>
+        <!-- v-if="!!form.randomRedPacketRulesArr" -->
+        <el-form-item v-if="!!enableRandomRedPacket" label="随机红包金额"  >
+          <template >
+            <div v-for="(rule, index) in form.randomRedPacketRulesArr" :key="index" class="form-row">
+              <el-form-item
+                label="随机红包金额区间"
+                :prop="`randomRedPacketRulesArr.${index}.minAmount`"
+                :rules="[
+              { required: true, message: '请输入最小金额', trigger: 'blur' },
+              { validator: validateMinAmount, trigger: 'blur', index: index }
+            ]"
+                class="form-item-amount"
+              >
+                <el-input
+                  v-model.number="rule.minAmount"
+                  type="number"
+                  :min="0.01"
+                  :precision="2"
+                  :step="0.01"
+                  placeholder="最小金额"
+                  size="small"
+                  class="amount-input"
+                  @input="handleAmountInput(rule, 'minAmount')"
+                ></el-input>
+                <span class="separator">-</span>
+                <el-input
+                  v-model.number="rule.maxAmount"
+                  type="number"
+                  :min="rule.minAmount || 0.01"
+                  :precision="2"
+                  :step="0.01"
+                  placeholder="最大金额"
+                  size="small"
+                  class="amount-input"
+                  @input="handleAmountInput(rule, 'maxAmount')"
+                ></el-input>
+                <span class="suffix">元</span>
+              </el-form-item>
+              <el-form-item
+                label="随机权重"
+                :prop="`randomRedPacketRulesArr.${index}.weight`"
+                :rules="[
+                  { required: true, message: '请输入权重', trigger: 'blur' },
+                  { type: 'integer', message: '权重必须为整数', trigger: 'blur' },
+                ]"
+                class="form-item-weight"
+              >
+                <el-input
+                  v-model.number="rule.weight"
+                  type="number"
+                  :min="1"
+                  placeholder="权重"
+                  size="small"
+                ></el-input>
+              </el-form-item>
+              <el-tooltip class="item" effect="dark" content="权重越高,被随机到的概率越大" placement="top">
+                <i class="el-icon-question"></i>
+              </el-tooltip>
+              <div class="action-buttons">
+                <el-button
+                  icon="el-icon-plus"
+                  size="mini"
+                  type="text"
+                  @click="addRule(index)"
+                  class="add-btn"
+                >
+                  新增
+                </el-button>
+                <el-button
+                  icon="el-icon-delete"
+                  size="mini"
+                  type="text"
+                  @click="deleteRule(index)"
+                  :disabled="form.randomRedPacketRulesArr.length <= 1"
+                  class="delete-btn"
+                >
+                  删除
+                </el-button>
+              </div>
+            </div>
+          </template>
+
+        </el-form-item>
+        <el-form-item label="是否关联商品">
+          <el-radio v-model="form.isProduct" :label=0>否</el-radio>
+          <el-radio v-model="form.isProduct" :label=1>是</el-radio>
+        </el-form-item>
+        <el-form-item label="是否先导课" prop="isFirst">
+          <el-radio-group v-model="form.isFirst">
+            <el-radio :label="1">是</el-radio>
+            <el-radio :label="0">否</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="是否启用倍速" prop="isSpeed">
+          <el-radio-group v-model="form.isSpeed">
+            <el-radio :label="1">是</el-radio>
+            <el-radio :label="0">否</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="是否上架" prop="isOnPut">
+          <el-radio-group v-model="form.isOnPut">
+            <el-radio :label="0">上架</el-radio>
+            <el-radio :label="1">下架</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="商品选择" v-if="form.isProduct === 1">
+          <el-button size="small" type="primary" @click="chooseCourseProduct">选取商品</el-button>
+          <el-table border width="100%" style="margin-top:5px;" :data="form.courseProducts">
+            <el-table-column label="商品名称" align="center" prop="productName"/>
+            <el-table-column label="产品条码" align="center" prop="barCode"/>
+            <el-table-column label="商品价格" align="center" prop="price"/>
+            <el-table-column label="库存" align="center" prop="stock"/>
+            <el-table-column label="操作" align="center" width="100px" fixed="right">
+              <template slot-scope="scope">
+                <el-button size="mini" type="text" icon="el-icon-delete"
+                           @click="handleCourseProductDelete(scope.row)">删除
+                </el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-form-item>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item v-if="form.isProduct === 1" label="商品售卖时间" prop="listingStartTime">
+              <el-input-number v-model="form.listingStartTime" :min="0" label="商品售卖时间"></el-input-number>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item v-if="form.isProduct === 1" label="结束售卖时间" prop="listingStartTime">
+              <el-input-number v-model="form.listingEndTime" :min="0" label="结束售卖时间"></el-input-number>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </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>
+    <el-dialog :title="title" :visible.sync="updateBatchData.open" width="1000px" append-to-body>
+      <el-form ref="form" :model="updateBatchData.form" label-width="110px">
+        <el-form-item label="看课时间" prop="timeRange">
+          <el-time-picker is-range v-model="updateBatchData.form.timeRange" range-separator="至"
+                          start-placeholder="开始时间"
+                          value-format="HH:mm:ss" end-placeholder="结束时间" placeholder="选择时间范围">
+          </el-time-picker>
+        </el-form-item>
+        <el-form-item label="领取红包时间" prop="lastJoinTime">
+          <el-time-picker v-model="updateBatchData.form.lastJoinTime" :selectableRange="updateBatchData.form.timeRange"
+                          value-format="HH:mm:ss" placeholder="选择时间范围">
+          </el-time-picker>
+          <p style="color: red;margin: 0;font-size: 12px">超过领取红包时间,只允许看课,不允许领取红包</p>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="updateBatch">确 定</el-button>
+        <el-button @click="updateBatchData.open = false">取 消</el-button>
+      </div>
+    </el-dialog>
+    <el-dialog :title="questionBank.title" :visible.sync="questionBank.open" width="1000px" append-to-body>
+      <question-bank ref="questionBank" @questionBankResult="questionBankResult"></question-bank>
+    </el-dialog>
+    <el-dialog :title="courseProduct.title" :visible.sync="courseProduct.open" width="1000px" append-to-body>
+      <course-product ref="courseProduct" @courseProductResult="courseProductResult"></course-product>
+    </el-dialog>
+    <el-dialog title="视频库选择" :visible.sync="addBatchData.open" width="900px" append-to-body>
+      <!-- 搜索条件 -->
+      <el-form :inline="true" :model="addBatchData.queryParams" class="library-search">
+        <el-form-item label="素材名称">
+          <el-input v-model="addBatchData.queryParams.resourceName" placeholder="请输入素材名称" clearable size="small"
+                    @keyup.enter.native="resourceList"/>
+        </el-form-item>
+        <el-form-item label="类型">
+          <el-select v-model="addBatchData.queryParams.typeId" @change="changeCateType" placeholder="请选择素材类型"
+                     clearable
+                     size="small">
+            <el-option v-for="item in addBatchData.typeOptions" :key="item.dictValue" :label="item.dictLabel"
+                       :value="item.dictValue"/>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="子类型">
+          <el-select v-model="addBatchData.queryParams.typeSubId" placeholder="请选择素材子类型" clearable size="small">
+            <el-option v-for="item in addBatchData.typeSubOptions" :key="item.dictValue" :label="item.dictLabel"
+                       :value="item.dictValue"/>
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" icon="el-icon-search" size="mini" @click="resourceList">搜索</el-button>
+        </el-form-item>
+      </el-form>
+
+      <!-- 视频列表 -->
+      <el-table v-loading="addBatchData.loading" :data="addBatchData.list"
+                @selection-change="handVideoleSelectionChange" height="400px">
+        <el-table-column type="selection" width="55" align="center"/>
+        <el-table-column label="素材名称" align="center" prop="resourceName"/>
+        <el-table-column label="文件名称" align="center" prop="fileName"/>
+        <el-table-column label="排序" align="center" prop="sort"/>
+        <el-table-column label="缩略图" align="center">
+          <template slot-scope="scope">
+            <el-popover placement="right" title="" trigger="hover">
+              <img alt="" slot="reference" :src="scope.row.thumbnail" style="width: 80px; height: 50px"/>
+              <img alt="" :src="scope.row.thumbnail" style="max-width: 150px;"/>
+            </el-popover>
+          </template>
+        </el-table-column>
+        <el-table-column label="视频时长" align="center">
+          <template slot-scope="scope">
+            <span>{{ formatDuration(scope.row.duration) }}</span>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 分页 -->
+      <pagination v-show="addBatchData.total > 0" :total="addBatchData.total"
+                  :page.sync="addBatchData.queryParams.pageNum" :limit.sync="addBatchData.queryParams.pageSize"
+                  @pagination="resourceList"/>
+
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="batchVideoSave">确 定</el-button>
+      </div>
+    </el-dialog>
+    <el-dialog title="章节红包" :visible.sync="redData.open" width="900px" append-to-body>
+      <el-table border v-loading="redData.loading" :data="redData.list" height="600px">
+        <el-table-column label="小节名称" align="center" show-overflow-tooltip prop="title"/>
+        <el-table-column label="视频文件名称" align="center" show-overflow-tooltip prop="fileName">
+        </el-table-column>
+        <el-table-column label="视频时长" align="center" prop="duration">
+          <template slot-scope="{ row }">
+            {{ formatDuration(row.duration) }}
+          </template>
+        </el-table-column>
+        <el-table-column label="红包金额" align="center" prop="redPacketMoney">
+          <template slot-scope="scope">
+            <el-input class="el-input" v-model="scope.row.redPacketMoney"/>
+          </template>
+        </el-table-column>
+        <el-table-column label="排序" align="center" prop="courseSort"/>
+        <el-table-column label="上传时间" align="center" prop="createTime"/>
+      </el-table>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="batchRedSave">确 定</el-button>
+      </div>
+    </el-dialog>
+    <el-dialog :title="commentDialog.title" :visible.sync="commentDialog.open" width="1000px" append-to-body
+               :close-on-click-modal="false">
+      <course-watch-comment ref="courseWatchComment" :courseId="commentDialog.courseId" :videoId="commentDialog.videoId"
+                            v-if="commentDialog.open">
+      </course-watch-comment>
+    </el-dialog>
+
+
+    <el-dialog title="修改课节排序" :visible.sync="openVideoSort" style="width: 1600px;" append-to-body>
+      <draggable v-model="userCourseVideoSortList" @end="onDragEndDay" style="padding: 10px">
+        <el-button style="margin: 8px 4px;" v-for="(item, index) in userCourseVideoSortList"
+                   :class="item.newCourseSort != item.courseSort ? 'red':''">第{{
+            item.newCourseSort
+          }}序(原排序第{{ item.courseSort }})
+        </el-button>
+      </draggable>
+      <div style="float: right;margin-top: -20px">
+        <el-button type="primary" @click="saveSorts">保存</el-button>
+      </div>
+    </el-dialog>
+
+    <!-- 批量修改封面 -->
+    <el-dialog :title="batchEditCoverDialog.title" :visible.sync="batchEditCoverDialog.visible" width="500px" append-to-body>
+      <el-form ref="batchEditCoverDialogForm"
+               :model="batchEditCoverDialog.form"
+               :rules="batchEditCoverDialog.rules"
+               v-loading="batchEditCoverDialog.uploadLoading">
+        <el-form-item label="视频封面" prop="thumbnail">
+          <el-upload v-model="batchEditCoverDialog.form.thumbnail"
+                     class="avatar-uploader"
+                     :action="uploadUrl"
+                     :show-file-list="false"
+                     :on-success="handleCoverSuccess"
+                     :before-upload="beforeAvatarUpload">
+            <img v-if="batchEditCoverDialog.form.thumbnail" :src="batchEditCoverDialog.form.thumbnail" class="avatar" width="300px">
+            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+          </el-upload>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitEditCoverForm">确 定</el-button>
+        <el-button @click="cancelEditCoverForm">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  addUserCourseVideo,
+  batchSaveVideo,
+  batchUpdateRed,
+  delUserCourseVideo,
+  getSort,
+  getUserCourseVideo,
+  getVideoListByCourseId,
+  getVideoListByCourseIdAll,
+  sortCourseVideo,
+  updates,
+  updateUserCourseVideo,
+  syncTemplate, batchDownUserCourseVideo, batchEditCover, batchUpUserCourseVideo
+} from '@/api/course/userCourseVideo'
+// import {syncTemplate} from '@/api/course/userCourse'
+import QuestionBank from "@/views/course/courseQuestionBank/QuestionBank.vue";
+import CourseProduct from "@/views/course/fsCourseProduct/CourseProductZM.vue";
+import VideoUpload from "@/components/VideoUpload/index.vue";
+import {listVideoResource} from '@/api/course/videoResource';
+import {getByIds} from '@/api/course/courseQuestionBank'
+import CourseWatchComment from "./courseWatchComment.vue";
+import {getCateListByPid, getCatePidList} from '@/api/course/userCourseCategory'
+import draggable from 'vuedraggable'
+import { getConfigByKey } from '@/api/system/config'
+
+export default {
+  name: "userCourseCatalog",
+  components: {VideoUpload, QuestionBank, CourseWatchComment, CourseProduct, draggable},
+  watch:{
+    // 深度监听 rules 数组的变化,以更新总权重
+    "form.randomRedPacketRulesArr": {
+      handler(val) {
+        // this.calculateTotalWeight();
+        this.validateRules();
+      },
+      deep: true,
+    },
+  },
+  data() {
+    return {
+      duration: null,
+      packageList: [],
+      //课题
+      package: {
+        title: '',
+        open: false,
+      },
+      //课题
+      questionBank: {
+        title: '',
+        open: false,
+      },
+      //拍商品
+      courseProduct: {
+        title: '',
+        open: false,
+      },
+      isPrivate: null,
+      videoUrl: "",
+      uploadTypeOptions: [
+        {dictLabel: "线路一", dictValue: 2},
+        {dictLabel: "线路二", dictValue: 3},
+      ],
+      uploadLoading: false,
+      courseId: null,
+      videoName: '',
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      uploadUrl: process.env.VUE_APP_BASE_API + "/common/uploadOSS",
+      baseUrl: process.env.VUE_APP_BASE_API,
+      typeOptions: [],
+      files: [],
+      fileList: [],
+      // 上传成功后的地址
+      videoURL: '',
+      // 进度条百分比
+      progress: 0,
+      // 上传视频获取成功后拿到的fileID【备用】
+      fileId: '',
+      courseName: null,
+      userCourseVideoList: [],
+      userCourseVideoSortList: [],
+      total: 0,
+      redData: {
+        queryParams: {
+          pageNum: 1,
+          pageSize: 99999,
+          courseId: null,
+        },
+        list: [],
+        open: false,
+        loading: true,
+        form: {}
+      },
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        courseId: null,
+        videoId: null,
+        title: null
+      },
+      addBatchData: {
+        open: false,
+        loading: true,
+        form: {},
+        select: [], // 按用户选择顺序存储视频ID
+        total: 0,
+        queryParams: {
+          pageNum: 1,
+          pageSize: 10,
+          resourceName: null,
+          typeId: null,
+          typeSubId: null
+        },
+        typeOptions: [],
+        typeSubOptions: []
+      },
+      // 显示搜索条件
+      showSearch: true,
+      // 遮罩层
+      loading: true,
+      // 导出遮罩层
+      exportLoading: false,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      loading3: false,
+      openVideoSort: false,
+      // 表单参数
+      form: {
+        isOnPut: 0,
+        courseProducts: [],
+        randomRedPacketRules:null,
+        randomRedPacketRulesArr:[
+          {
+            minAmount: 0.01,
+            maxAmount: 0.01,
+            weight: 100,
+          }
+        ]
+      },
+      updateBatchData: {
+        open: false,
+        form: {}
+      },
+      // 表单校验
+      rules: {
+        title: [
+          {required: true, message: "小节名称不能为空", trigger: "change"}
+        ],
+        courseSort: [
+          {required: true, message: "排序不能为空", trigger: "change"}
+        ],
+
+      },
+      // 评论弹窗数据
+      commentDialog: {
+        open: false,
+        courseId: null,
+        videoId: null,
+        title: ""
+      },
+      enableRandomRedPacket:false,
+      // 批量修改封面
+      batchEditCoverDialog: {
+        title: '修改视频封面',
+        visible: false,
+        uploadLoading: false,
+        form: {
+          thumbnail: null,
+        },
+        rules: {
+          thumbnail: [
+            {required: true, message: "视频封面不能为空", trigger: "change"}
+          ],
+        }
+      }
+    }
+  },
+  created() {
+    this.getDicts("sys_course_temp_type").then(response => {
+      this.typeOptions = response.data;
+    });
+    getConfigByKey('randomRedpacket:config').then(res=>{
+      let configData = res.data;
+      if(!!configData && !!configData.configValue){
+        let configValue = JSON.parse(configData.configValue);
+        if(!!configValue.enableRandomRedpacket){
+          this.enableRandomRedPacket = configValue.enableRandomRedpacket;
+          console.log("this.enableRandomRedPacket ::" + this.enableRandomRedPacket)
+        }
+      }
+    }).catch(res=>{
+
+    })
+  },
+  methods: {
+    getPickerOptions() {
+      const durationInMinutes = Math.floor(this.form.duration / 60); // 将秒转换为分钟
+      const endHour = Math.floor(durationInMinutes / 60); // 起始小时
+      const endMinute = durationInMinutes % 60; // 起始分钟
+      return {
+        start: "00:00", // 固定开始时间
+        step: "00:01", // 时间间隔
+        end: `${endHour.toString().padStart(2, "0")}:${endMinute
+          .toString()
+          .padStart(2, "0")}`, // 动态结束时间
+      };
+    },
+
+    // 处理时间选择框值变化
+    handleTimeChange(index, row) {
+      // 确保 packageList 中的数据被正确更新
+      this.$set(this.packageList, index, row);
+      // 同步更新 form.packageJson 字段
+      this.$nextTick(() => {
+        // 确保每个疗法包都有 duration 字段
+        this.packageList.forEach(item => {
+          if (item.duration === undefined || item.duration === null) {
+            item.duration = ''; // 空值应初始化为空字符串而不是null,避免显示"null"
+          }
+        });
+        this.form.packageJson = JSON.stringify(this.packageList);
+      });
+    },
+    handlePackageDelete(row) {
+      this.packageList.splice(this.packageList.findIndex(item => item.packageId === row.packageId), 1)
+    },
+    choosePackage() {
+      this.package.open = true;
+      this.package.title = '疗法选择';
+    },
+    /**
+     * 选择课题
+     */
+    chooseQuestionBank() {
+      this.questionBank.open = true;
+      this.questionBank.title = '课题选择';
+    },
+
+    /**
+     * 选择拍商品
+     */
+    chooseCourseProduct() {
+      this.courseProduct.open = true;
+      this.courseProduct.title = '拍商品选择';
+    },
+
+
+    //选择疗法
+    selectPackage(row) {
+      const drug = {};
+      for (var i = 0; i < this.packageList.length; i++) {
+        if (this.packageList[i].packageId == row.packageId) {
+          this.$message.warning("疗法已存在!")
+          return;
+        }
+      }
+      drug.packageId = row.packageId;
+      drug.packageName = row.packageName;
+      drug.secondName = row.secondName;
+      drug.totalPrice = row.totalPrice;
+      drug.imgUrl = row.imgUrl;
+      this.packageList.push(drug);
+      this.$message({
+        message: '添加成功',
+        type: 'success'
+      });
+
+    },
+
+    courseProductResult(val) {
+      this.form.courseProducts = this.form.courseProducts || [];
+
+      // 检查商品是否已存在
+      const exists = this.form.courseProducts.some(item => item.productId === val.productId);
+      if (exists) {
+        this.$message.error("当前商品已选择");
+        return;
+      }
+
+      // 添加商品到列表
+      this.form.courseProducts.push(val);
+      this.$message.success("添加成功");
+    },
+
+    //选择结果
+    questionBankResult(val) {
+
+      // 确保 questionBankList 是数组
+      this.form.questionBankList = this.form.questionBankList || [];
+
+      for (var i = 0; i < this.form.questionBankList.length; i++) {
+        if (this.form.questionBankList[i].id == val.id) {
+          return this.$message.error("当前课题已选择")
+        }
+      }
+
+      this.form.questionBankList.push(val);
+      this.$message({
+        message: '添加成功',
+        type: 'success'
+      });
+    },
+
+    //删除课题
+    handleQuestionBankDelete(row) {
+      this.form.questionBankList.splice(this.form.questionBankList.findIndex(item => item.id === row.id), 1)
+    },
+
+    //删除商品
+    handleCourseProductDelete(row) {
+      const index = this.form.courseProducts.findIndex(item => item.id === row.id);
+      if (index > -1) {
+        this.form.courseProducts.splice(index, 1);
+      }
+    },
+    handleVideoChange() {
+      if (this.form.uploadType == 1) {
+        this.videoUrl = this.form.lineOne;
+      } else if (this.form.uploadType == 2) {
+        this.videoUrl = this.form.lineTwo;
+      } else if (this.form.uploadType == 3) {
+        this.videoUrl = this.form.lineThree;
+      }
+    },
+    // 视频库课题
+    handleSelectProjects(projectIds) {
+      this.form.questionBankList = []
+      if (!projectIds || projectIds.length === 0 || this.isPrivate === 0) {
+        return
+      }
+
+      const params = {ids: projectIds}
+      getByIds(params).then(response => {
+        if (response.code === 200) {
+          response.data.forEach(item => {
+            let isExist = this.form.questionBankList.some(q => q.id === item.id)
+            if (!isExist) {
+              this.form.questionBankList.push(item)
+            }
+          });
+        }
+      })
+    },
+    handleVideoDuration(duration) {
+      this.form.duration = duration;
+    },
+    formatDuration(seconds) {
+      if (seconds === null || seconds === undefined) {
+        return '未上传视频';
+      }
+      const hours = Math.floor(seconds / 3600);
+      const minutes = Math.floor((seconds % 3600) / 60);
+      const remainingSeconds = seconds % 60;
+
+      const formattedHours = hours > 0 ? hours.toString() + ':' : '';
+      const formattedMinutes = minutes.toString().padStart(2, '0');
+      const formattedSeconds = remainingSeconds.toString().padStart(2, '0');
+
+      return `${formattedHours}${formattedMinutes}:${formattedSeconds}`;
+    },
+
+    handleAvatarSuccess(res, file) {
+      if (res.code == 200) {
+        this.form.thumbnail = res.url;
+        this.$forceUpdate()
+      } else {
+        this.msgError(res.msg);
+      }
+    },
+    beforeAvatarUpload(file) {
+      const isLt1M = file.size / 1024 / 1024 < 5;
+      if (!isLt1M) {
+        this.$message.error('上传图片大小不能超过 5MB!');
+      }
+      return isLt1M;
+    },
+    getDetails(courseId, courseName, isPrivate) {
+      this.isPrivate = isPrivate
+      this.courseName = courseName
+      this.courseId = courseId;
+      this.queryParams.courseId = courseId;
+      this.getList();
+    },
+    getList() {
+      this.loading = true;
+      getVideoListByCourseId(this.queryParams).then(response => {
+        this.userCourseVideoList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        videoId: null,
+        title: null,
+        description: null,
+        url: null,
+        thumbnail: null,
+        duration: null,
+        createTime: null,
+        uploadType: null,
+        lineOne: null,
+        lineTwo: null,
+        lineThree: null,
+        fileName: null,
+        userId: null,
+        cateId: null,
+        courseId: null,
+        likes: null,
+        views: null,
+        comments: null,
+        status: 0,
+        courseSort: 1,
+        isHot: null,
+        isShow: null,
+        isAudit: null,
+        auditBy: null,
+        auditTime: null,
+        updateTime: null,
+        source: null,
+        isDel: null,
+        shares: null,
+        tags: null,
+        productId: null,
+        id: null,
+        packageJson: null,
+        questionBankId: null,
+        questionBankList: [],
+        redPacketMoney: 0,
+        isTranscode: 0,
+        transcodeFileKey: null,
+        isProduct: 0,
+        isFirst: 0,
+        isSpeed: 0,
+        isOnPut: 0,
+        listingStartTime: null,
+        listingEndTime: null,
+        showProduct: 1, // 默认无商品
+        randomRedPacketRules:null,
+        randomRedPacketRulesArr:[
+          {
+            minAmount: 0.01,
+            maxAmount: 0.01,
+            weight: 100,
+          }
+        ]
+      };
+      this.videoURL = '';
+      this.progress = 0;
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.videoId)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    // 视频库多选框选中数据(按用户点击顺序记录)
+    handVideoleSelectionChange(selection) {
+      // 提取当前选中的所有ID
+      const selectedIds = selection.map(item => item.id);
+      // 处理新增选中项:保留用户点击顺序
+      selectedIds.forEach(id => {
+        if (!this.addBatchData.select.includes(id)) {
+          this.addBatchData.select.push(id);
+        }
+      });
+      // 处理取消选中项:移除已取消的ID
+      this.addBatchData.select = this.addBatchData.select.filter(id => selectedIds.includes(id));
+    },
+    handleAdd() {
+      this.reset();
+      this.form.courseId = this.courseId;
+      this.open = true;
+      this.title = "添加课堂视频";
+      this.videoUrl = '';
+      this.packageList = [];
+      getSort(this.courseId).then(response => {
+        this.form.courseSort = Number(response.data);
+      })
+      setTimeout(() => {
+        this.$refs.videoUpload.resetUpload();
+      }, 500);
+
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      this.form.isOnPut = row.isOnPut;
+      this.packageList = [];
+      const videoId = row.videoId || this.ids;
+      getUserCourseVideo(videoId).then(response => {
+        console.log(response);
+        this.form = response.data;
+        this.$set(this.form, 'isOnPut', response.data.isOnPut !== undefined ? response.data.isOnPut : 0);
+
+        if (this.form.randomRedPacketRules) {
+          this.$set(this.form, 'randomRedPacketRulesArr', JSON.parse(this.form.randomRedPacketRules));
+        } else {
+          // 处理初始值
+          this.form.randomRedPacketRulesArr = [{
+            minAmount: 0.01,
+            maxAmount: 0.01,
+            weight: 100,
+          }];
+        }
+
+        if (response.data.videoUrl != null && response.data.videoUrl !== '') {
+          this.videoUrl = response.data.videoUrl;
+        }
+
+        if (this.form.packageJson != null) {
+          try {
+            // 检查 packageJson 是否包含商品数据,如果是则解析为 courseProducts
+            const parsedData = JSON.parse(this.form.packageJson);
+            if (Array.isArray(parsedData) && parsedData.length > 0 && parsedData[0].hasOwnProperty('productName')) {
+              // 如果是商品数据格式,则设置到 courseProducts
+              this.form.courseProducts = parsedData;
+            } else {
+              // 否则按照原有逻辑设置到 packageList
+              this.packageList = parsedData;
+            }
+          } catch (e) {
+            // 如果解析失败,按原来的处理方式
+            this.packageList = JSON.parse(this.form.packageJson);
+          }
+        }
+
+        if (response.data.viewStartTime != null && response.data.viewEndTime != null) {
+          this.form.timeRange = [response.data.viewStartTime, response.data.viewEndTime];
+        }
+        // 根据商品数量设置是否关联商品状态
+        if (this.form.courseProducts && this.form.courseProducts.length > 0) {
+          this.form.isProduct = 1; // 有关联商品时设为1(是)
+        } else {
+          this.form.isProduct = 0; // 无关联商品时设为0(否)
+        }
+        // 设置商品选择状态
+        if (this.form.id) {
+          this.form.showProduct = 0; // 有商品时设为0
+        } else {
+          this.form.showProduct = 1; // 无商品时设为1
+        }
+
+        setTimeout(() => {
+          this.$refs.videoUpload.resetUpload();
+        }, 500);
+        this.open = true;
+        this.title = "修改课堂视频";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          this.form.videoUrl = this.videoUrl;
+          if (this.form.videoUrl == null || this.form.videoUrl === '') {
+            this.$message({
+              message: '请上传视频!',
+              type: 'warning'
+            });
+            return
+          }
+
+          if (this.form.timeRange && this.form.timeRange.length === 2) {
+            this.form.viewStartTime = this.form.timeRange[0];
+            this.form.viewEndTime = this.form.timeRange[1];
+          }
+
+          if (this.form.duration == null) {
+            this.$message({
+              message: '未识别到视频时长请稍等。。。',
+              type: 'warning'
+            });
+            return
+          }
+          if (this.form.isProduct != null && this.form.isProduct == 1 && (this.form.courseProducts == null || this.form.courseProducts.length < 1)) {
+            this.$message({
+              message: '请选择关联商品',
+              type: 'warning'
+            });
+            return
+          }
+
+          if (this.form.questionBankList !== null) {
+            this.form.questionBankId = this.form.questionBankList.map(item => item.id).join(',');
+          }
+
+          // 处理商品选择逻辑
+          if (this.form.courseProducts && this.form.courseProducts.length > 0) {
+            this.form.id = this.form.courseProducts.map(item => item.id).join(',');
+            this.form.showProduct = 0; // 有商品选择时设为0
+
+            // 将商品数据序列化为JSON字符串传递给packageJson
+            this.form.packageJson = JSON.stringify(this.form.courseProducts);
+          } else {
+            this.form.id = null;
+            this.form.showProduct = 1; // 无商品选择时设为1
+            this.form.packageJson = "[]"; // 无商品时传递空数组
+          }
+
+          if (this.form.randomRedPacketRulesArr) {
+            let rulesJson = JSON.stringify(this.form.randomRedPacketRulesArr);
+            this.form.randomRedPacketRules = rulesJson;
+          }
+
+          if (this.form.videoId != null) {
+            updateUserCourseVideo(this.form).then(response => {
+              this.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addUserCourseVideo(this.form).then(response => {
+              this.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    openUpdates() {
+      this.updateBatchData.form = {};
+      this.updateBatchData.open = true;
+    },
+    /** 提交按钮 */
+    updateBatch() {
+      this.updateBatchData.form.ids = this.ids;
+      if (this.updateBatchData.form.timeRange != null && this.updateBatchData.form.timeRange.length === 2) {
+        this.updateBatchData.form.viewStartTime = this.updateBatchData.form.timeRange[0];
+        this.updateBatchData.form.viewEndTime = this.updateBatchData.form.timeRange[1];
+      }
+      updates(this.updateBatchData.form).then(response => {
+        this.msgSuccess("修改成功");
+        this.updateBatchData.open = false;
+        this.getList();
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const videoIds = row.videoId || this.ids;
+      this.$confirm('是否确认删除视频编号为"' + videoIds + '"的数据项?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(function () {
+        return delUserCourseVideo(videoIds);
+      }).then(() => {
+        this.getList();
+        this.msgSuccess("删除成功");
+      }).catch(() => {
+      });
+    },
+    /** 同步模板数据*/
+    handleSync() {
+      const courseId = this.courseId;
+      this.$confirm('是否同步课程数据至模板', "确认", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(function () {
+        return syncTemplate(courseId);
+      }).then(() => {
+        this.getList();
+        this.msgSuccess("正在同步模板中!!请稍后!");
+      }).catch(() => {
+      });
+    },
+
+    handleCourseSort() {
+
+      getVideoListByCourseIdAll(this.queryParams.courseId).then(response => {
+
+        response.rows.forEach((item) => item.newCourseSort = item.courseSort);
+        this.userCourseVideoSortList = response.rows.sort((a, b) => a.courseSort - b.courseSort);
+        if (this.userCourseVideoSortList == null || this.userCourseVideoSortList.length == 0) {
+          this.$message.error("暂无课节天数")
+        } else {
+          this.openVideoSort = true;
+        }
+      })
+
+
+    },
+
+    onDragEndDay() {
+      this.userCourseVideoSortList.forEach((item, index) => {
+        item.newCourseSort = index + 1;
+      })
+      this.$forceUpdate()
+    },
+
+    saveSorts() {
+      let list = this.userCourseVideoSortList.filter(e => e.courseSort != e.newCourseSort).map(e => {
+        return {courseSort: e.newCourseSort, videoId: e.videoId}
+      })
+      this.loading3 = true;
+      sortCourseVideo(list).then(e => {
+        this.getList();
+      }).finally(() => {
+        this.userCourseVideoSortList = [];
+        this.openVideoSort = false;
+      })
+    },
+
+    openAdds() {
+      this.addBatchData.open = true;
+      this.getRootTypeList();
+      this.addBatchData.form = {
+        courseId: this.courseId,
+      };
+      // 重置选择顺序数组
+      this.addBatchData.select = [];
+      this.resourceList();
+    },
+    getRootTypeList() {
+      getCatePidList().then(response => {
+        this.addBatchData.typeOptions = response.data
+      });
+    },
+    async changeCateType(val) {
+      this.addBatchData.queryParams.typeSubId = null
+      this.addBatchData.typeSubOptions = []
+      if (!val) {
+        return
+      }
+      await getCateListByPid(val).then(response => {
+        this.addBatchData.typeSubOptions = response.data
+      })
+    },
+    resourceList() {
+      this.addBatchData.loading = true;
+      listVideoResource(this.addBatchData.queryParams).then(response => {
+        this.addBatchData.loading = false;
+        this.addBatchData.list = response.rows;
+        this.addBatchData.total = response.total;
+      });
+    },
+    batchVideoSave() {
+      if (this.addBatchData.select.length === 0) {
+        this.$message({
+          message: '请选择视频!!',
+          type: 'warning'
+        });
+        return
+      }
+      this.addBatchData.form.ids = this.addBatchData.select; // 按用户选择顺序提交
+      batchSaveVideo(this.addBatchData.form).then(response => {
+        this.addBatchData.open = false;
+        this.getList();
+      })
+    },
+    updateRedPageckeOpen() {
+      this.redData.open = true;
+      this.redData.loading = true;
+      this.redData.queryParams.courseId = this.courseId;
+      getVideoListByCourseId(this.redData.queryParams).then(response => {
+        if(!!response.rows && response.rows.length >0){
+          for(let i = 0; i < response.rows.length; i++){
+            if(!!response.rows[i].randomRedPacketRules){
+              this.$set(response.rows[i], 'randomRedPacketRulesArr', JSON.parse(response.rows[i].randomRedPacketRules)) ;
+            }
+          }
+        }
+        this.redData.list = response.rows;
+        console.log(this.redData.list);
+        this.redData.loading = false;
+      });
+    },
+    batchRedSave() {
+      batchUpdateRed(this.redData.list).then(response => {
+        this.redData.open = false;
+        this.getList();
+      })
+    },
+    /** 查看评论按钮操作 */
+    handleComment(row) {
+      this.commentDialog.courseId = row.courseId || this.courseId;
+      this.commentDialog.videoId = row.videoId;
+      this.commentDialog.title = `查看评论 - ${row.title}`;
+      this.commentDialog.open = true;
+    },
+    // 实时过滤金额输入,只允许两位小数
+    handleAmountInput(rule, field) {
+      let value = rule[field];
+      if (value === null || value === undefined) return;
+
+      // 转换为字符串处理
+      let str = value.toString();
+
+      // 移除除数字和小数点外的所有字符
+      str = str.replace(/[^0-9.]/g, '');
+
+      // 只保留一个小数点
+      const dotIndex = str.indexOf('.');
+      if (dotIndex !== -1) {
+        str = str.substring(0, dotIndex + 1) + str.substring(dotIndex + 1).replace(/\./g, '');
+      }
+
+      // 限制小数点后最多两位
+      if (dotIndex !== -1 && str.length > dotIndex + 3) {
+        str = str.substring(0, dotIndex + 3);
+      }
+
+      // 转换回数字并更新
+      rule[field] = parseFloat(str) || 0;
+    },
+    deleteRule(index) {
+      this.$confirm("确定要删除这个区间吗?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      }).then(() => {
+        this.form.randomRedPacketRulesArr.splice(index, 1);
+        this.$message({
+          type: "success",
+          message: "删除成功!",
+        });
+      });
+    },
+    addRule(index) {
+      // 在当前行的后面插入一个新行
+      this.form.randomRedPacketRulesArr.splice(index + 1, 0, {
+        minAmount: 0.01,
+        maxAmount: 0.01,
+        weight: 100,
+      });
+    },
+    // 自定义校验规则:确保最大金额大于最小金额
+    validateMinAmount(rule, value, callback) {
+      // debugger;
+      // const maxAmount = this.form29.rules[].maxAmount
+
+      const index = rule.index;
+      const maxAmount = this.form.randomRedPacketRulesArr[index].maxAmount;
+
+      if (value > maxAmount) {
+        callback(new Error("最小金额不能大于最大金额"));
+      } else {
+        callback();
+      }
+    },
+    validateRules() {
+      this.form.randomRedPacketRulesArr.forEach((rule) => {
+        if (rule.minAmount === undefined || rule.minAmount < 0.01) {
+          rule.minAmount = 0.01;
+        }
+        if (rule.maxAmount === undefined || rule.maxAmount < rule.minAmount) {
+          rule.maxAmount = rule.minAmount;
+        }
+        if (rule.weight === undefined || rule.weight < 1) {
+          rule.weight = 1;
+        }
+      });
+    },
+    /** 下架 **/
+    handleDown() {
+      const videoIds = this.ids;
+      this.$confirm('是否确认下架视频编号为"' + videoIds + '"的数据项?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(function () {
+        return batchDownUserCourseVideo(videoIds);
+      }).then(() => {
+        this.getList();
+        this.msgSuccess("下架成功");
+      }).catch(() => {
+      });
+    },
+    /** 上架按钮操作 */
+    handleUp() {
+      const videoIds = this.ids;
+      this.$confirm('是否确认上架视频编号为"' + videoIds + '"的数据项?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(function () {
+        return batchUpUserCourseVideo(videoIds);
+      }).then(() => {
+        this.getList();
+        this.msgSuccess("上架成功");
+      }).catch(function () {
+      });
+    },
+    /** 修改封面 **/
+    handleEditCover() {
+      this.batchEditCoverDialog.form = {
+        thumbnail: null
+      }
+      this.batchEditCoverDialog.visible = true
+    },
+    handleCoverSuccess(res, file) {
+      if (res.code === 200) {
+        this.batchEditCoverDialog.form.thumbnail = res.url;
+        this.$forceUpdate()
+      } else {
+        this.msgError(res.msg);
+      }
+    },
+    submitEditCoverForm() {
+      this.$refs["batchEditCoverDialogForm"].validate(valid => {
+        if (!valid) {
+          return;
+        }
+
+        const thumbnail = this.batchEditCoverDialog.form.thumbnail
+        const videoIds = this.ids
+
+        if (!thumbnail || thumbnail === '') {
+          this.$message({
+            message: '请上传封面!',
+            type: 'warning'
+          });
+          return
+        }
+
+        if (!videoIds || videoIds.length === 0) {
+          this.$message({
+            message: '请选择小节!',
+            type: 'warning'
+          });
+          return
+        }
+
+        const params = {
+          thumbnail: thumbnail,
+          videoIds: videoIds
+        }
+
+        batchEditCover(params).then(response => {
+          this.msgSuccess("修改成功")
+          this.batchEditCoverDialog.visible = false
+          this.getList();
+        });
+      });
+    },
+    cancelEditCoverForm() {
+      this.batchEditCoverDialog.visible = false
+      this.batchEditCoverDialog.form = {
+        thumbnail: null,
+      }
+    },
+
+  }
+}
+</script>
+<style scoped>
+.avatar-uploader-icon {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+</style>
+<style>
+.avatar-uploader .el-upload {
+  border: 1px dashed #d9d9d9;
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+}
+
+.avatar-uploader .el-upload:hover {
+  border-color: #409EFF;
+}
+
+.avatar-uploader-icon {
+  font-size: 28px;
+  color: #8c939d;
+  width: 150px;
+  height: 150px;
+  line-height: 150px;
+  text-align: center;
+}
+
+
+.red:hover {
+  color: #dbdbdb !important;
+}
+
+.red {
+  background-color: #F56C6C !important;
+  color: #fff !important;
+}
+
+</style>

+ 1 - 1
src/views/components/index/statisticsDashboard.vue

@@ -251,7 +251,7 @@
             <el-radio-button label="本周"></el-radio-button>
             <el-radio-button label="本月"></el-radio-button>
             <el-radio-button label="上月"></el-radio-button>
-            <el-radio-button label="指定日期" v-if="!showCompanyField"></el-radio-button>
+            <el-radio-button label="指定日期" v-if="showCompanyField"></el-radio-button>
           </el-radio-group>
           <el-date-picker
       v-if="queryTime === '指定日期'"

+ 29 - 0
src/views/course/courseUserStatistics/qw/index.vue

@@ -24,6 +24,18 @@
           />
         </el-select>
       </el-form-item>
+      <el-form-item label="添加方式" prop="addWays" v-if="showCompanyField">
+        <el-select v-model="addWays" placeholder="请选择添加方式" size="small" multiple
+    collapse-tags
+    style="width: 100%;" clearable>
+          <el-option
+            v-for="dict in myAddWayList"
+            :key="dict.dictValue"
+            :label="dict.dictLabel"
+            :value="dict.dictValue"
+          />
+        </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>
@@ -201,6 +213,7 @@ export default {
         eTime:null,
         scheduleStartTime: null,
         scheduleEndTime: null,
+        addWays:[],
       },
       // 表单参数
       form: {},
@@ -208,8 +221,16 @@ export default {
       rules: {
       },
       scheduleTime: null,
+      myAddWayList:[],
+      addWays:[],
     };
   },
+  computed: {
+    // 计算属性判断是否显示
+    showCompanyField() {
+      return process.env.VUE_APP_TITLE_INDEX === '恒春来';
+    },
+  },
   created() {
     getCompanyList().then(response => {
       this.companys = response.data;
@@ -223,6 +244,9 @@ export default {
     this.getDicts("sys_course_watch_log_type").then(response => {
       this.logTypeOptions = response.data;
     });
+    this.getDicts("sys_qw_externalContact_addWay").then((response) => {
+      this.myAddWayList = response.data;
+    });
   },
   methods: {
     courseChange(row){
@@ -288,6 +312,9 @@ export default {
     /** 搜索按钮操作 */
     handleQuery() {
       this.queryParams.pageNum = 1;
+      if( this.addWays.length>0){
+        this.queryParams.addWays = this.addWays.join(',');
+      }
       this.getList();
     },
     /** 重置按钮操作 */
@@ -299,6 +326,8 @@ export default {
       this.queryParams.eTime = null;
       this.queryParams.scheduleStartTime = null;
       this.queryParams.scheduleEndTime = null;
+      this.queryParams.addWays = [];
+      this.addWays = [];
       this.handleQuery();
     },
     // 多选框选中数据

+ 166 - 0
src/views/course/fsCourseProduct/CourseProductZM.vue

@@ -0,0 +1,166 @@
+<template>
+    <div class="app-container">
+        <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+            <el-form-item label="商品名称" prop="productName">
+                <el-input v-model="queryParams.productName" placeholder="请输入商品名称" clearable size="small"
+                    @keyup.enter.native="handleQuery" />
+            </el-form-item>
+
+            <el-form-item label="产品条码" prop="barCode">
+                <el-input v-model="queryParams.barCode" placeholder="请输入产品条码" clearable size="small"
+                    @keyup.enter.native="handleQuery" />
+            </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-table border v-loading="loading" :data="fsCourseProductList">
+            <el-table-column label="商品名称" align="center" prop="productName" />
+            <el-table-column label="商品图片" align="center" prop="image" width="120">
+                <template slot-scope="scope">
+                    <el-popover placement="right" title="" trigger="hover">
+                        <img slot="reference" :src="scope.row.image" width="100">
+                        <img :src="scope.row.image" style="max-width: 150px;">
+                    </el-popover>
+                </template>
+            </el-table-column>
+            <el-table-column label="产品条码" align="center" prop="barCode" />
+            <el-table-column label="商品价格" align="center" prop="price" />
+            <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+                <template slot-scope="scope">
+                    <el-button size="mini" type="text" icon="el-icon-edit"
+                        @click="chooseCourseProduct(scope.row)">选择此商品</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" />
+
+
+    </div>
+</template>
+
+<script>
+import { listFsCourseProduct, } from "@/api/course/fsCourseProduct";
+import Material from '@/components/Material'
+import singleImg from '@/components/Material/single'
+import { listStoreProduct } from '@/api/hisStore/storeProduct'
+export default {
+    name: "CourseProduct",
+    components: { Material, singleImg, },
+    watch: {
+        imageArr: function (val) {
+            this.form.imgUrl = val.join(',')
+        },
+        photoArr: function (val) {
+            this.form.images = val.join(',')
+        }
+    },
+    data() {
+        return {
+            photoArr: [],
+            imageArr: [],
+            // 遮罩层
+            loading: true,
+            // 导出遮罩层
+            exportLoading: false,
+            // 选中数组
+            ids: [],
+            // 非单个禁用
+            single: true,
+            // 非多个禁用
+            multiple: true,
+            // 显示搜索条件
+            showSearch: true,
+            // 总条数
+            total: 0,
+            // 拍单商品表格数据
+            fsCourseProductList: [],
+            // 弹出层标题
+            title: "",
+            // 是否显示弹出层
+            open: false,
+            // 查询参数
+            queryParams: {
+                pageNum: 1,
+                pageSize: 10,
+                imgUrl: null,
+                images: null,
+                barCode: null,
+                sort: null,
+                stock: null,
+                productContent: null,
+                productPrice: null,
+                productName: null,
+            },
+            // 表单参数
+            form: {},
+            // 表单校验
+
+        };
+    },
+    created() {
+        this.getList();
+    },
+    methods: {
+        chooseCourseProduct(val) {
+            this.$emit('courseProductResult', val)
+        },
+        /** 查询拍单商品列表 */
+        getList() {
+            this.loading = true;
+          listStoreProduct(this.queryParams).then(response => {
+                this.fsCourseProductList = response.rows;
+                this.total = response.total;
+                this.loading = false;
+            });
+        },
+        // 取消按钮
+        cancel() {
+            this.open = false;
+            this.reset();
+        },
+        // 表单重置
+        reset() {
+            this.form = {
+                id: null,
+                imgUrl: null,
+                images: null,
+                barCode: null,
+                sort: null,
+                stock: null,
+                productContent: null,
+                productPrice: null,
+                productName: null,
+                createTime: null,
+                updateTime: null
+            };
+            this.resetForm("form");
+            this.photoArr = [];
+            this.imageArr = [];
+        },
+        /** 搜索按钮操作 */
+        handleQuery() {
+            this.queryParams.pageNum = 1;
+            this.getList();
+        },
+        /** 重置按钮操作 */
+        resetQuery() {
+            this.resetForm("queryForm");
+            this.handleQuery();
+        },
+
+
+
+
+
+
+    }
+};
+</script>

+ 1195 - 0
src/views/course/userCourse/indexZM.vue

@@ -0,0 +1,1195 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px">
+      <el-form-item label="课堂分类" prop="cateId">
+        <el-select v-model="queryParams.cateId" placeholder="请选择" clearable size="small"
+                   @change="getQuerySubCateList(queryParams.cateId)">
+          <el-option
+            v-for="dict in categoryOptions"
+            :key="dict.dictValue"
+            :label="dict.dictLabel"
+            :value="dict.dictValue"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="课堂子分类" prop="subCateId">
+        <el-select v-model="queryParams.subCateId" placeholder="请选择" clearable size="small">
+          <el-option
+            v-for="dict in querySubCateOptions"
+            :key="dict.dictValue"
+            :label="dict.dictLabel"
+            :value="dict.dictValue"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="课堂id" prop="courseId">
+        <el-input
+          v-model="queryParams.courseId"
+          placeholder="请输入课堂id"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="课堂名称" prop="courseName">
+        <el-input
+          v-model="queryParams.courseName"
+          placeholder="请输入课堂名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="关联的公司" prop="companyIds">
+        <el-select v-model="queryParams.companyIdsList" multiple placeholder="请选择公司" filterable clearable style="width: 90%;">
+          <el-option
+            v-for="dict in companyOptions"
+            :key="dict.dictValue"
+            :label="dict.dictLabel"
+            :value="dict.dictValue"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="课堂类型" prop="isPrivate" style="display: none">
+        <el-select v-model="queryParams.isPrivate" placeholder="请选择" clearable size="small">
+          <el-option
+            v-for="dict in courseTypeOptions"
+            :key="dict.dictValue"
+            :label="dict.dictLabel"
+            :value="dict.dictValue"
+          />
+        </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
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['course:userCourse:add']"
+        >新增
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['course:userCourse:edit']"
+        >修改
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['course:userCourse:remove']"
+        >删除
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          :loading="exportLoading"
+          @click="handleExport"
+          v-hasPermi="['course:userCourse:export']"
+        >导出
+        </el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+<!--    <el-table height="600" border v-loading="loading" :data="userCourseList" @selection-change="handleSelectionChange" style="width: 100%" :fit="true">-->
+    <el-table max-height="600" border v-loading="loading" :data="userCourseList" @selection-change="handleSelectionChange" style="width: 100%" :fit="true">
+      <el-table-column type="selection" width="55" align="center"/>
+      <el-table-column label="课程ID" align="center" prop="courseId" width="55"/>
+      <el-table-column label="所属项目" align="center" prop="projectName" width="120"/>
+      <el-table-column label="封面图片" align="center" prop="imgUrl" width="170">
+        <template slot-scope="scope">
+          <el-popover
+            placement="right"
+            title=""
+            trigger="hover"
+          >
+            <img slot="reference" :src="scope.row.imgUrl" width="100">
+            <img :src="scope.row.imgUrl" style="max-width: 300px;">
+          </el-popover>
+        </template>
+      </el-table-column>
+      <el-table-column label="课堂名称" align="center" show-overflow-tooltip prop="courseName" min-width="100"/>
+      <el-table-column label="排序" align="center" prop="sort" width="80"/>
+      <el-table-column label="分类名称" align="center" prop="cateName" width="120"/>
+      <el-table-column label="子分类名称" align="center" prop="subCateName" width="120"/>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            @click="handleCatalog(scope.row)"
+            v-hasPermi="['course:userCourse:cateMange']"
+          >目录管理
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['course:userCourse:edit']"
+          >修改
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdateRedPage(scope.row)"
+            v-hasPermi="['course:userCourse:editRedPage']"
+          >统一修改红包金额
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleCopy(scope.row)"
+            v-hasPermi="['course:userCourse:copy']"
+          >复制
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['course:userCourse:remove']"
+          >删除
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            v-if="scope.row.isPrivate === 1"
+            v-has-permi="['course:userCourse:editConfig']"
+            @click="configCourse(scope.row)"
+          >过程页配置
+          </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="1200px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="110px">
+        <el-row>
+          <el-form-item label="所属项目" prop="project">
+            <el-select v-model="form.project" placeholder="请选择项目" filterable clearable size="small">
+              <el-option
+                v-for="dict in projectOptions"
+                :key="dict.dictValue"
+                :label="dict.dictLabel"
+                :value="dict.dictValue"
+              />
+            </el-select>
+          </el-form-item>
+        </el-row>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="课堂名称" prop="courseName">
+              <el-input v-model="form.courseName" placeholder="请输入课堂名称"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="课堂分类" prop="cateId">
+              <el-select v-model="form.cateId" placeholder="请选择" clearable size="small"
+                         @change="getSubCateList(form.cateId)">
+                <el-option
+                  v-for="dict in categoryOptions"
+                  :key="dict.dictValue"
+                  :label="dict.dictLabel"
+                  :value="dict.dictValue"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="课堂子分类" prop="subCateId">
+              <el-select v-model="form.subCateId" placeholder="请选择" clearable size="small">
+                <el-option
+                  v-for="dict in subCategoryOptions"
+                  :key="dict.dictValue"
+                  :label="dict.dictLabel"
+                  :value="dict.dictValue"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="排序" prop="sort">
+                          <el-input-number v-model="form.sort"  :min="0"  label="排序"></el-input-number>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="课堂简介" prop="description">
+              <el-input v-model="form.description" type="textarea" :rows="2" placeholder="请输入课堂简介"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="课程封面" prop="imgUrl">
+          <ImageUpload v-model="form.imgUrl" type="image" :num="10" :width="150" :height="150"/>
+        </el-form-item>
+        <el-form-item label="关联公司" prop="tags">
+          <el-select v-model="companyIds" multiple placeholder="请选择公司" filterable clearable style="width: 90%;">
+            <el-option
+              v-for="dict in companyOptions"
+              :key="dict.dictValue"
+              :label="dict.dictLabel"
+              :value="dict.dictValue"
+            />
+          </el-select>
+        </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>
+
+
+    <el-dialog title="修改课程红包金额" :visible.sync="openRedPage.open" width="1000px" append-to-body>
+      <el-form ref="openRedPage" :model="openRedPage" :rules="rulesRedPage" label-width="110px">
+        <el-form-item label="红包金额" prop="redPacketMoney">
+          <el-input-number v-model="openRedPage.redPacketMoney" :min="0.1" :max="200" :step="0.1"></el-input-number>
+        </el-form-item>
+        <div v-if="!!enableRandomRedPacket" style=" display: flex;
+                  flex-direction: column;">
+             <div v-for="(rule, index) in openRedPage.rules" :key="index" class="form-row">
+           <el-form-item
+            label="随机红包金额区间"
+            :prop="`rules.${index}.minAmount`"
+            :rules="[
+              { required: true, message: '请输入最小金额', trigger: 'blur' },
+              { validator: validateMinAmount, trigger: 'blur', index: index }
+            ]"
+            class="form-item-amount"
+          >
+            <el-input
+              v-model.number="rule.minAmount"
+              type="number"
+              :min="0.01"
+              :precision="2"
+              :step="0.01"
+              placeholder="最小金额"
+              size="small"
+              class="amount-input"
+              @input="handleAmountInput(rule, 'minAmount')"
+            ></el-input>
+            <span class="separator">-</span>
+            <el-input
+              v-model.number="rule.maxAmount"
+              type="number"
+              :min="rule.minAmount || 0.01"
+              :precision="2"
+              :step="0.01"
+              placeholder="最大金额"
+              size="small"
+              class="amount-input"
+              @input="handleAmountInput(rule, 'maxAmount')"
+            ></el-input>
+            <span class="suffix">元</span>
+          </el-form-item>
+              <el-form-item
+                label="随机权重"
+                :prop="`rules.${index}.weight`"
+                :rules="[
+                  { required: true, message: '请输入权重', trigger: 'blur' },
+                  { type: 'integer', message: '权重必须为整数', trigger: 'blur' },
+                ]"
+                class="form-item-weight"
+              >
+                <el-input
+                  v-model.number="rule.weight"
+                  type="number"
+                  :min="1"
+                  placeholder="权重"
+                  size="small"
+                ></el-input>
+              </el-form-item>
+              <el-tooltip class="item" effect="dark" content="权重越高,被随机到的概率越大" placement="top">
+                <i class="el-icon-question"></i>
+              </el-tooltip>
+              <div class="action-buttons">
+                <el-button
+                  icon="el-icon-plus"
+                  size="mini"
+                  type="text"
+                  @click="addRule(index)"
+                  class="add-btn"
+                >
+                  新增
+                </el-button>
+                <el-button
+                  icon="el-icon-delete"
+                  size="mini"
+                  type="text"
+                  @click="deleteRule(index)"
+                  :disabled="openRedPage.rules.length <= 1"
+                  class="delete-btn"
+                >
+                  删除
+                </el-button>
+              </div>
+            </div>
+        </div>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitFormRedPage">确 定</el-button>
+        <el-button @click="cancelRedPage">取 消</el-button>
+      </div>
+    </el-dialog>
+
+    <!-- 过程页配置 -->
+    <el-dialog
+      :visible.sync="configDialog.dialogVisible"
+      title="过程页配置"
+      append-to-body
+      width="1200px"
+    >
+      <el-form :model="configDialog.form" :rules="configDialog.rules" ref="configForm" label-width="110px">
+        <el-form-item label="过程页图片" prop="coverImg">
+          <ImageUpload v-model="configDialog.form.coverImg" :height="150" :limit="1" :width="150" type="image"/>
+          <i class="el-icon-warning"/>
+          <span style="color: rgb(153, 169, 191)"> 不配置将使用课程默认图片</span>
+        </el-form-item>
+        <el-form-item label="首播电视台" prop="tvEnable">
+          <el-switch v-model="configDialog.form.tvEnable" active-color="#13ce66"/>
+        </el-form-item>
+        <el-form-item prop="tv" v-if="configDialog.form.tvEnable">
+          <el-input v-model="configDialog.form.tv" clearable></el-input>
+          <i class="el-icon-warning"/>
+          <span style="color: rgb(153, 169, 191)"> 多个首播电视台,请用英文逗号隔开</span>
+        </el-form-item>
+        <el-form-item label="网络播放平台" prop="networkEnable">
+          <el-switch v-model="configDialog.form.networkEnable" active-color="#13ce66"/>
+        </el-form-item>
+        <el-form-item prop="network" v-if="configDialog.form.networkEnable">
+          <el-input v-model="configDialog.form.network" clearable></el-input>
+          <i class="el-icon-warning"/>
+          <span style="color: rgb(153, 169, 191)"> 多个网络播放平台,请用英文逗号隔开</span>
+        </el-form-item>
+        <el-form-item label="制作单位" prop="unitEnable">
+          <el-switch v-model="configDialog.form.unitEnable" active-color="#13ce66"/>
+        </el-form-item>
+        <el-form-item prop="unit" v-if="configDialog.form.unitEnable">
+          <el-input v-model="configDialog.form.unit" clearable></el-input>
+          <i class="el-icon-warning"/>
+          <span style="color: rgb(153, 169, 191)"> 多个制作单位,请用英文逗号隔开</span>
+        </el-form-item>
+        <el-form-item label="专家顾问团队" prop="teamEnable">
+          <el-switch v-model="configDialog.form.teamEnable" active-color="#13ce66"/>
+        </el-form-item>
+        <el-form-item prop="team" v-if="configDialog.form.teamEnable">
+          <el-input v-model="configDialog.form.team" clearable></el-input>
+          <i class="el-icon-warning"/>
+          <span style="color: rgb(153, 169, 191)"> 多个专家顾问,请用英文逗号隔开</span>
+        </el-form-item>
+        <el-form-item label="支持单位" prop="supportEnable">
+          <el-switch v-model="configDialog.form.supportEnable" active-color="#13ce66"/>
+        </el-form-item>
+        <el-form-item prop="support" v-if="configDialog.form.supportEnable">
+          <el-input v-model="configDialog.form.support" clearable></el-input>
+          <i class="el-icon-warning"/>
+          <span style="color: rgb(153, 169, 191)"> 多个支持单位,请用英文逗号隔开</span>
+        </el-form-item>
+        <el-form-item label="监督投诉电话" prop="complaintPhone">
+          <el-input v-model="configDialog.form.complaintPhone" placeholder="请输入监督投诉电话" clearable/>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary"
+                   :loading="configDialog.updating"
+                   :disabled="configDialog.updating"
+                   @click="submitConfigForm">确 定</el-button>
+        <el-button @click="cancelConfig">取 消</el-button>
+      </div>
+    </el-dialog>
+
+    <el-drawer
+      :with-header="false"
+      size="75%"
+      :title="show.title" :visible.sync="show.open" append-to-body>
+      <userCourseCatalogDetails ref="userCourseCatalogDetails"/>
+    </el-drawer>
+  </div>
+</template>
+
+<script>
+import {
+  listUserCourse,
+  getUserCourse,
+  delUserCourse,
+  addUserCourse,
+  updateUserCourse,
+  exportUserCourse,
+  updateIsShow,
+  copyUserCourse,
+  putOn,
+  pullOff, updateUserCourseRedPage,
+  editConfig
+} from '@/api/course/userCourse'
+
+import {getSelectableRange} from "@/api/qw/sopTemp";
+import Treeselect from "@riophae/vue-treeselect";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+import Editor from '@/components/Editor/wang';
+import ImageUpload from '@/components/ImageUpload/index';
+import {listBySearch} from "@/api/course/userTalent";
+import userCourseCatalogDetails from '../../components/course/userCourseCatalogDetailsZM.vue';
+import {getAllCourseCategoryList, getCatePidList, getCateListByPid} from "@/api/course/userCourseCategory";
+import {allList} from "@/api/company/company";
+import VideoUpload from '@/components/VideoUpload/index.vue'
+import { getConfigByKey } from '@/api/system/config'
+export default {
+  name: "UserCourse",
+  components: {
+    VideoUpload,
+    Treeselect,
+    Editor, ImageUpload, userCourseCatalogDetails
+  },
+  watch:{
+  // 深度监听 rules 数组的变化,以更新总权重
+    "openRedPage.rules": {
+      handler(val) {
+        // this.calculateTotalWeight();
+        this.validateRules();
+      },
+      deep: true,
+    },
+  },
+  data() {
+    return {
+      talentParam: {
+        phone: null,
+        talentId: null
+      },
+      talentList: [],
+      startTimeRange: [],
+      show: {
+        title: "目录管理",
+        open: false
+      },
+      activeName: "1",
+      projectOptions: [],
+      tagsOptions: [],
+      tags: [],
+      companyIds: [],
+      courseTypeOptions: [],
+      orOptions: [],
+      specShowOptions: [],
+      specTypeOptions: [],
+      categoryOptions: [],
+      subCategoryOptions: [],
+      querySubCateOptions: [],
+      // 遮罩层
+      loading: true,
+      // 导出遮罩层
+      exportLoading: false,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 课程表格数据
+      userCourseList: [],
+      companyOptions: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      openRedPage:{
+        open:false,
+        courseId:null,
+        courseName:null,
+        redPacketMoney:0.1,
+        //随机红包配置
+        rules:[
+           {
+            minAmount: 0.01,
+            maxAmount: 0.01,
+            weight: 100,
+          }
+        ]
+      },
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        cateId: null,
+        subCateId: null,
+        title: null,
+        imgUrl: null,
+        userId: null,
+        sort: null,
+        status: null,
+        isVip: null,
+        isHot: null,
+        isShow: "1",
+        views: null,
+        duration: null,
+        description: null,
+        hotRanking: null,
+        integral: null,
+        price: null,
+        courseId: null,
+        isPrivate: 1,
+        companyIdsList:[],
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        courseName: [
+          {required: true, message: "课堂名称不能为空", trigger: "blur"}
+        ],
+        imgUrl: [
+          {required: true, message: "封面图片不能为空", trigger: "blur"}
+        ],
+        isTui: [
+          {required: true, message: "是否推荐不能为空", trigger: "blur"}
+        ],
+        isBest: [
+          {required: true, message: "是否精选不能为空", trigger: "blur"}
+        ],
+        isFast: [
+          {required: true, message: "是否允许快进不能为空", trigger: "blur"}
+        ],
+        isAutoPlay: [
+          {required: true, message: "是否自动播放不能为空", trigger: "blur"}
+        ],
+        sort: [
+          {required: true, message: "排序不能为空", trigger: "blur"}
+        ],
+        views: [
+          {required: true, message: "播放量不能为空", trigger: "blur"}
+        ],
+        likes: [
+          {required: true, message: "点赞数不能为空", trigger: "blur"}
+        ],
+        favoriteNum: [
+          {required: true, message: "收藏数不能为空", trigger: "blur"}
+        ],
+        shares: [
+          {required: true, message: "分享数不能为空", trigger: "blur"}
+        ],
+        isIntegral: [
+          {required: true, message: "是否允许积分兑换不能为空", trigger: "blur"}
+        ],
+        isShow: [
+          {required: true, message: "上架状态不能为空", trigger: "blur"}
+        ],
+        isPrivate: [
+          {required: true, message: "公私域不能为空", trigger: "blur"}
+        ],
+        integral: [
+          {required: true, message: "小节兑换积分不能为空", trigger: "blur"}
+        ],
+      },
+
+      rulesRedPage:{
+        redPacketMoney: [
+          {required: true, message: "红包金额不能为空", trigger: "blur"}
+        ],
+      },
+      configDialog: {
+        dialogVisible: false,
+        updating: false,
+        form: {
+          id: null,
+          coverImg: null,
+          tvEnable: 0,
+          tv: null,
+          networkEnable: 0,
+          network: null,
+          unitEnable: 0,
+          unit: null,
+          teamEnable: 0,
+          team: null,
+          supportEnable: 0,
+          support: null,
+          //监督投诉电话
+          complaintPhone: null,
+        },
+        rules: {
+          tv: [
+            { required: true, message: '首播电视台不能为空', trigger: 'blur' }
+          ],
+          network: [
+            { required: true, message: '网络播放平台不能为空', trigger: 'blur' }
+          ],
+          unit: [
+            { required: true, message: '制作单位不能为空', trigger: 'blur' }
+          ],
+          team: [
+            { required: true, message: '专家顾问团队不能为空', trigger: 'blur' }
+          ],
+          support: [
+            { required: true, message: '支持单位不能为空', trigger: 'blur' }
+          ],
+        }
+      },
+      enableRandomRedPacket:false
+    };
+  },
+  created() {
+    this.getList();
+    getConfigByKey('randomRedpacket:config').then(res=>{
+        console.log("res::")
+        console.log(res);
+        let configData = res.data;
+        if(!!configData && !!configData.configValue){
+           let configValue = JSON.parse(configData.configValue);
+           console.log(configValue);
+           if(!!configValue.enableRandomRedpacket){
+            this.enableRandomRedPacket = configValue.enableRandomRedpacket;
+           }
+        }
+    }).catch(res=>{
+
+    })
+    getCatePidList().then(response => {
+      this.categoryOptions = response.data;
+    });
+
+
+    getSelectableRange().then(e => {
+      this.startTimeRange = e.data;
+    })
+    // this.getTreeselect();
+    this.getDicts("sys_spec_show").then(response => {
+      this.specShowOptions = response.data;
+    });
+    this.getDicts("sys_spec_type").then(response => {
+      this.specTypeOptions = response.data;
+    });
+    this.getDicts("sys_course_type").then(response => {
+      this.courseTypeOptions = response.data;
+    });
+    this.getDicts("sys_course_project").then(response => {
+      this.projectOptions = response.data;
+    });
+    this.getDicts("sys_course_tags").then(response => {
+      this.tagsOptions = response.data;
+    });
+    this.getDicts("sys_company_or").then(response => {
+      this.orOptions = response.data;
+    });
+    allList().then(response => {
+      this.companyOptions = response.rows;
+    });
+  },
+  methods: {
+    selectTalent() {
+
+    },
+    talentMethod(query) {
+      if (query !== '') {
+        this.talentParam.phone = query;
+        listBySearch(this.talentParam).then(response => {
+          this.talentList = response.data;
+        });
+      }
+    },
+    getSubCateList(pid) {
+      this.form.subCateId = null;
+      if (pid == '') {
+        this.subCategoryOptions = [];
+        return
+      }
+      getCateListByPid(pid).then(response => {
+        this.subCategoryOptions = response.data;
+      });
+    },
+    getQuerySubCateList(pid) {
+      this.queryParams.subCateId = null;
+      if (pid == '') {
+        this.querySubCateOptions = [];
+        return
+      }
+      this.queryParams.subCateId = null;
+      getCateListByPid(pid).then(response => {
+        this.querySubCateOptions = response.data;
+      });
+    },
+    handleShow(row) {
+      var isShowValue = row.isShow === 0 ? 1 : 0;
+      var course = {courseId: row.courseId, isShow: isShowValue};
+      updateIsShow(course).then(response => {
+        this.msgSuccess("修改成功");
+        this.getList();
+      });
+    },
+    handleCatalog(row) {
+      const courseId = row.courseId;
+      this.show.open = true;
+      setTimeout(() => {
+        this.$refs.userCourseCatalogDetails.getDetails(courseId, row.courseName, row.isPrivate);
+      }, 200);
+    },
+    /** 转换课堂分类数据结构 */
+    normalizer(node) {
+      if (node.children && !node.children.length) {
+        delete node.children;
+      }
+      return {
+        id: node.cateId,
+        label: node.cateName,
+        children: node.children
+      };
+    },
+    getTreeselect() {
+      getAllCourseCategoryList().then(response => {
+        this.categoryOptions = [];
+        const data = this.handleTree(response.data, "cateId", "pid");
+        this.categoryOptions = data;
+      });
+    },
+    /** 查询课程列表 */
+    getList() {
+      this.loading = true;
+      listUserCourse(this.queryParams).then(response => {
+        this.userCourseList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        courseId: null,
+        cateId: null,
+        subCateId: null,
+        title: null,
+        imgUrl: null,
+        secondImg: null,
+        userId: null,
+        sort: null,
+        createTime: null,
+        updateTime: null,
+        status: 0,
+        isVip: null,
+        isAutoPlay: "1",
+        isIntegral: "0",
+        isShow: "1",
+        isFast: "1",
+        isTui: "1",
+        isBest: "1",
+        isNext: "1",
+        isPrivate: "1",
+        views: 100000,
+        duration: null,
+        description: null,
+        hotRanking: null,
+        integral: null,
+        price: null,
+        likes: 100000,
+        shares: 100000,
+        favoriteNum: 100000,
+        hotNum: 100000,
+      };
+      this.tags = [];
+      this.subCategoryOptions = []
+      this.companyIds = []
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.queryParams.companyIdsList = [];
+      this.queryParams.isShow = this.activeName
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.courseId)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.talentList = [];
+      this.open = true;
+      this.title = "添加课程";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      this.talentList = [];
+      const courseId = row.courseId || this.ids
+      getUserCourse(courseId).then(response => {
+        this.form = response.data;
+        // this.form.cateId = response.data.cateId.toString();
+        if (this.form.cateId) {
+          getCateListByPid(this.form.cateId).then(response => {
+            this.subCategoryOptions = response.data;
+          });
+        }
+        // this.form.courseType = response.data.courseType.toString();
+        if (response.data.project != null) {
+          this.form.project = response.data.project.toString();
+        }
+        if (response.data.tags != null) {
+          this.tags = response.data.tags.split(",")
+        }
+        this.form.isAutoPlay = response.data.isAutoPlay.toString();
+        this.form.isShow = response.data.isShow.toString();
+        this.form.isBest = response.data.isBest.toString();
+        this.form.isFast = response.data.isFast.toString();
+        this.form.isIntegral = response.data.isIntegral.toString();
+        this.form.isTui = response.data.isTui.toString();
+        this.form.isNext = response.data.isNext.toString();
+        this.form.isPrivate = response.data.isPrivate.toString();
+        this.talentParam.talentId = response.data.talentId;
+        if (this.form.companyIds != null) {
+          this.companyIds = ((this.form.companyIds).split(",").map(Number))
+        } else {
+          this.companyIds = []
+        }
+
+        listBySearch(this.talentParam).then(response => {
+          this.talentList = response.data;
+        });
+        this.open = true;
+        this.title = "修改课程";
+      });
+    },
+
+    handleUpdateRedPage(row){
+      this.openRedPage.open=true;
+      this.openRedPage.courseId=row.courseId;
+      this.openRedPage.courseName=row.courseName;
+
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+
+          this.form.companyIds = this.companyIds.toString()
+          // 私域课程
+          this.form.isPrivate = 1
+          if (this.form.courseId != null) {
+            updateUserCourse(this.form).then(response => {
+              this.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addUserCourse(this.form).then(response => {
+              this.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+
+    submitFormRedPage(){
+
+      const courseId = this.openRedPage.courseId;
+      const redPacketMoney = this.openRedPage.redPacketMoney;
+      let randomRedPacketRules = JSON.stringify( this.openRedPage.rules);
+      console.log(randomRedPacketRules)
+      this.$confirm('是否确认将课程id 为"' + courseId + '"的红包批量修改为:【'+redPacketMoney+'】?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(function () {
+        return updateUserCourseRedPage({courseId:courseId,redPacketMoney:redPacketMoney,randomRedPacketRules:randomRedPacketRules});
+      }).then(() => {
+        this.getList();
+        this.msgSuccess("修改成功");
+        this.openRedPage.open=false;
+      }).finally(() => {
+        this.getList();
+        this.openRedPage.open=false;
+      });
+
+    },
+    cancelRedPage(){
+      this.openRedPage.open=false;
+    },
+
+    /** 复制按钮操作 */
+    handleCopy(row) {
+      const courseId = row.courseId;
+      this.$confirm('是否确认复制课程编号为"' + courseId + '"的数据项?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(function () {
+        return copyUserCourse(courseId);
+      }).then(() => {
+        this.getList();
+        this.msgSuccess("复制成功");
+      }).catch(() => {
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const courseIds = row.courseId || this.ids;
+      this.$confirm('是否确认删除课程编号为"' + courseIds + '"的数据项?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(function () {
+        return delUserCourse(courseIds);
+      }).then(() => {
+        this.getList();
+        this.msgSuccess("删除成功");
+      }).catch(() => {
+      });
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm('是否确认导出所有课程数据项?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        this.exportLoading = true;
+        return exportUserCourse(queryParams);
+      }).then(response => {
+        this.download(response.msg);
+        this.exportLoading = false;
+      }).catch(() => {
+      });
+    },
+    putOn() {
+      const courseIds = this.ids;
+      if (courseIds == null || courseIds == "") {
+        return this.$message("未选择课程");
+      }
+      this.$confirm('是否确认批量上架课程?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(function () {
+        return putOn(courseIds);
+      }).then(() => {
+        this.getList();
+        this.msgSuccess("上架成功");
+      }).catch(function () {
+      });
+    },
+    pullOff() {
+      const courseIds = this.ids;
+      if (courseIds == null || courseIds == "") {
+        return this.$message("未选择课程");
+      }
+      this.$confirm('是否确认批量下架课程?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(function () {
+        return pullOff(courseIds);
+      }).then(() => {
+        this.getList();
+        this.msgSuccess("下架成功");
+      }).catch(function () {
+      });
+    },
+    configCourse(row) {
+      if (row.configJson) {
+        this.configDialog.form = {
+          tvEnable: 0,
+          networkEnable: 0,
+          unitEnable: 0,
+          teamEnable: 0,
+          supportEnable: 0,
+          ...JSON.parse(row.configJson)
+        }
+      }
+      this.configDialog.form.id = row.courseId
+      this.configDialog.dialogVisible = true;
+      this.configDialog.updating = false
+    },
+    submitConfigForm() {
+      this.$refs['configForm'].validate(valid => {
+        if (!valid) {
+          this.msgError('请完善配置内容')
+          return
+        }
+
+        if (this.configDialog.updating) {
+          return
+        }
+        this.configDialog.updating = true
+
+        const content = {
+          coverImg: this.configDialog.form.coverImg,
+          tvEnable: this.configDialog.form.tvEnable,
+          tv: this.configDialog.form.tv?.replace(",",","),
+          networkEnable: this.configDialog.form.networkEnable,
+          network: this.configDialog.form.network?.replace(",",","),
+          unitEnable: this.configDialog.form.unitEnable,
+          unit: this.configDialog.form.unit?.replace(",",","),
+          teamEnable: this.configDialog.form.teamEnable,
+          team: this.configDialog.form.team?.replace(",",","),
+          supportEnable: this.configDialog.form.supportEnable,
+          support: this.configDialog.form.support?.replace(",",","),
+        }
+
+        const params = {
+          id: this.configDialog.form.id,
+          configJson: JSON.stringify(content)
+        }
+
+        editConfig(params).then(() => {
+          this.msgSuccess('修改成功')
+          this.configDialog.dialogVisible = false;
+          this.getList()
+        }).finally(() => {
+          setTimeout(() => {
+            this.configDialog.updating = false
+          }, 500)
+        })
+      })
+    },
+    cancelConfig() {
+      this.configDialog.form = {
+        id: null,
+        coverImg: null,
+        tvEnable: 0,
+        tv: null,
+        networkEnable: 0,
+        network: null,
+        unitEnable: 0,
+        unit: null,
+        teamEnable: 0,
+        team: null,
+        supportEnable: 0,
+        support: null
+      }
+      this.resetForm('configForm')
+      this.configDialog.dialogVisible = false;
+    },
+    // 实时过滤金额输入,只允许两位小数
+    handleAmountInput(rule, field) {
+      let value = rule[field];
+      if (value === null || value === undefined) return;
+
+      // 转换为字符串处理
+      let str = value.toString();
+
+      // 移除除数字和小数点外的所有字符
+      str = str.replace(/[^0-9.]/g, '');
+
+      // 只保留一个小数点
+      const dotIndex = str.indexOf('.');
+      if (dotIndex !== -1) {
+        str = str.substring(0, dotIndex + 1) + str.substring(dotIndex + 1).replace(/\./g, '');
+      }
+
+      // 限制小数点后最多两位
+      if (dotIndex !== -1 && str.length > dotIndex + 3) {
+        str = str.substring(0, dotIndex + 3);
+      }
+
+      // 转换回数字并更新
+      rule[field] = parseFloat(str) || 0;
+    },
+      deleteRule(index) {
+      this.$confirm("确定要删除这个区间吗?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      }).then(() => {
+        this.openRedPage.rules.splice(index, 1);
+        this.$message({
+          type: "success",
+          message: "删除成功!",
+        });
+      });
+    },
+      addRule(index) {
+      // 在当前行的后面插入一个新行
+      this.openRedPage.rules.splice(index + 1, 0, {
+        minAmount: 0.01,
+        maxAmount: 0.01,
+        weight: 100,
+      });
+    },
+       // 自定义校验规则:确保最大金额大于最小金额
+    validateMinAmount(rule, value, callback) {
+      // debugger;
+      // const maxAmount = this.form29.rules[].maxAmount
+
+      const index = rule.index;
+      const maxAmount = this.openRedPage.rules[index].maxAmount;
+
+      if (value > maxAmount) {
+        callback(new Error("最小金额不能大于最大金额"));
+      } else {
+        callback();
+      }
+    },
+      validateRules() {
+      this.openRedPage.rules.forEach((rule) => {
+        if (rule.minAmount === undefined || rule.minAmount < 0.01) {
+          rule.minAmount = 0.01;
+        }
+        if (rule.maxAmount === undefined || rule.maxAmount < rule.minAmount) {
+          rule.maxAmount = rule.minAmount;
+        }
+        if (rule.weight === undefined || rule.weight < 1) {
+          rule.weight = 1;
+        }
+      });
+    },
+
+  }
+};
+</script>