Browse Source

Merge branch 'master' of http://1.14.104.71:10880/root/ylrz_scrm_adminUI

caoliqin 1 month ago
parent
commit
3abd215fbf

+ 18 - 0
src/api/store/user.js

@@ -83,3 +83,21 @@ export function getAllUserListLimit(query) {
     params: query
   })
 }
+
+// 获取小黑屋用户列表
+export function darkRoomList(query) {
+  return request({
+    url: '/store/user/darkRoomList',
+    method: 'get',
+    params: query
+  })
+}
+
+// 批量解禁
+export function enabledUsers(data) {
+  return request({
+    url: '/store/user/enabledUsers',
+    method: 'post',
+    data: data
+  })
+}

+ 6 - 0
src/components/ImageUpload/index.vue

@@ -9,6 +9,7 @@
       :on-error="handleUploadError"
       :on-exceed="handleExceed"
       name="file"
+      :disabled="disabled"
       :on-remove="handleRemove"
       :show-file-list="true"
       :file-list="fileList"
@@ -56,6 +57,11 @@ export default {
        type: Number,
       default: 5,
     },
+    // 大小限制(MB)
+    disabled: {
+      type: Boolean,
+      default: false,
+    },
     // 文件类型, 例如['png', 'jpg', 'jpeg']
     fileType: {
       type: Array,

+ 6 - 5
src/views/components/course/userCourseCatalogDetails.vue

@@ -50,6 +50,7 @@
           type="primary"
           plain
           size="mini"
+          v-if="isPrivate === 1"
           @click="updateRedPageckeOpen"
         >修改红包</el-button>
       </el-col>
@@ -77,7 +78,7 @@
               {{ formatDuration(row.duration) }}
           </template>
       </el-table-column>
-      <el-table-column label="红包金额" align="center" prop="redPacketMoney" />
+      <el-table-column label="红包金额" align="center" prop="redPacketMoney" v-if="isPrivate === 1"/>
       <el-table-column label="排序" align="center" prop="courseSort" />
       <el-table-column label="上传时间" align="center" prop="createTime" />
       <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
@@ -119,7 +120,7 @@
         <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="timeRange">
+        <el-form-item label="看课时间" prop="timeRange" v-if="isPrivate === 1">
           <el-time-picker
             is-range
             v-model="form.timeRange"
@@ -130,7 +131,7 @@
             placeholder="选择时间范围">
           </el-time-picker>
         </el-form-item>
-        <el-form-item label="领取红包时间" prop="lastJoinTime">
+        <el-form-item label="领取红包时间" prop="lastJoinTime" v-if="isPrivate === 1">
           <el-time-picker
             v-model="form.lastJoinTime"
             :selectableRange="form.timeRange"
@@ -170,7 +171,7 @@
           append-to-body
         />
 
-        <el-form-item label="课题选择" prop="questionBankId">
+        <el-form-item label="课题选择" prop="questionBankId" v-if="isPrivate === 1">
           <el-button size="small" type="primary" @click="chooseQuestionBank">选取课题</el-button>
           <el-table border width="100%" style="margin-top:5px;"  :data="form.questionBankList">
 
@@ -201,7 +202,7 @@
             </el-table-column>
           </el-table>
         </el-form-item >
-        <el-form-item label="红包金额" prop="redPacketMoney">
+        <el-form-item label="红包金额" prop="redPacketMoney" v-if="isPrivate === 1">
           <el-input-number v-model="form.redPacketMoney" :min="0.1" :max="200" :step="0.1" ></el-input-number>
         </el-form-item>
       </el-form>

+ 11 - 211
src/views/course/userCourse/index.vue

@@ -31,7 +31,7 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="课堂类型" prop="isPrivate">
+      <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"
@@ -144,25 +144,10 @@
           </el-popover>
         </template>
       </el-table-column>
-      <el-table-column label="小封面" align="center" prop="secondImg" width="100">
-        <template slot-scope="scope">
-          <el-popover
-            placement="right"
-            title=""
-            trigger="hover"
-          >
-            <img slot="reference" :src="scope.row.secondImg" width="50">
-            <img :src="scope.row.secondImg" style="max-width: 100px;">
-          </el-popover>
-        </template>
-      </el-table-column>
       <el-table-column label="课堂名称" align="center" show-overflow-tooltip prop="courseName"/>
       <el-table-column label="排序" align="center" prop="sort"/>
       <el-table-column label="分类名称" align="center" prop="cateName"/>
       <el-table-column label="子分类名称" align="center" prop="subCateName"/>
-      <el-table-column label="原价" align="center" prop="price"/>
-      <el-table-column label="售价" align="center" prop="sellPrice"/>
-      <el-table-column label="单节积分" align="center" prop="integral"/>
       <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
         <template slot-scope="scope">
           <el-button
@@ -255,36 +240,6 @@
             </el-form-item>
           </el-col>
         </el-row>
-        <el-row>
-          <!-- <el-col :span="8">
-            <el-form-item label="课堂类型" prop="courseType">
-              <el-select v-model="form.courseType" 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-col> -->
-          <el-col :span="8">
-            <el-form-item label="关联达人" prop="talentId">
-              <el-select v-model="form.talentId" remote filterable clearable reserve-keyword
-                         placeholder="输入手机号搜索" :remote-method="talentMethod">
-                <el-option
-                  v-for="item in talentList"
-                  :key="item.talentId"
-                  :label="item.nickName +'#'+item.phone"
-                  :value="item.talentId">
-                  <span style="float: left">{{ item.talentId }}</span>
-                  <span style="margin-left: 30px ;">{{ item.nickName }}</span>
-                  <span style="margin-left: 30px">{{ item.phone }}</span>
-                </el-option>
-              </el-select>
-            </el-form-item>
-          </el-col>
-        </el-row>
         <el-row>
           <el-col :span="24">
             <el-form-item label="课堂简介" prop="description">
@@ -295,161 +250,6 @@
         <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="imgUrl">
-          <ImageUpload v-model="form.secondImg" type="image" :num="10" :width="150" :height="150"/>
-        </el-form-item>
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="标签" prop="tags">
-              <el-select v-model="tags" multiple placeholder="请选择标签" filterable clearable size="small">
-                <el-option
-                  v-for="dict in tagsOptions"
-                  :key="dict.dictValue"
-                  :label="dict.dictLabel"
-                  :value="dict.dictValue"
-                />
-              </el-select>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="8">
-            <el-form-item label="发课时间" prop="sendTime">
-              <el-time-picker
-                v-model="form.sendTime"
-                value-format="HH:mm"
-                format="HH:mm"
-                style="width: 100px"
-                :picker-options="{ selectableRange: startTimeRange }"
-              >
-              </el-time-picker>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="8">
-            <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-col :span="8">
-            <el-form-item label="播放量" prop="views">
-              <el-input-number v-model="form.views" :min="0" label="浏览量"></el-input-number>
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="点赞量" prop="likes">
-              <el-input-number v-model="form.likes" :min="0" label="点赞量"></el-input-number>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-
-          <el-col :span="8">
-            <el-form-item label="收藏数" prop="favoriteNum">
-              <el-input-number v-model="form.favoriteNum" :min="0" label="收藏数"></el-input-number>
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="分享数" prop="shares">
-              <el-input-number v-model="form.shares" :min="0" label="分享数"></el-input-number>
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="热度值" prop="hotNum">
-              <el-input-number v-model="form.hotNum" :min="0" label="热度值"></el-input-number>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="8">
-            <el-form-item label="状态" prop="isShow">
-              <el-radio-group v-model="form.isShow">
-                <el-radio :label="item.dictValue" v-for="item in specShowOptions">{{ item.dictLabel }}</el-radio>
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="是否推荐" prop="isTui">
-              <el-radio-group v-model="form.isTui">
-                <el-radio :label="item.dictValue" v-for="item in orOptions">{{ item.dictLabel }}</el-radio>
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="是否精选" prop="isBest">
-              <el-radio-group v-model="form.isBest">
-                <el-radio :label="item.dictValue" v-for="item in orOptions">{{ item.dictLabel }}</el-radio>
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="8">
-            <el-form-item label="是否自动播放" prop="isAutoPlay">
-              <el-radio-group v-model="form.isAutoPlay">
-                <el-radio :label="item.dictValue" v-for="item in orOptions">{{ item.dictLabel }}</el-radio>
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="是否允许快进" prop="isFast">
-              <el-radio-group v-model="form.isFast">
-                <el-radio :label="item.dictValue" v-for="item in orOptions">{{ item.dictLabel }}</el-radio>
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="是否积分兑换" prop="isIntegral">
-              <el-radio-group v-model="form.isIntegral">
-                <el-radio :label="item.dictValue" v-for="item in orOptions">{{ item.dictLabel }}</el-radio>
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="8">
-            <el-form-item label="是否逐级播放" prop="isNext">
-              <el-radio-group v-model="form.isNext">
-                <el-radio :label="item.dictValue" v-for="item in orOptions">{{ item.dictLabel }}</el-radio>
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="是否私域" prop="isPrivate">
-              <el-radio-group v-model="form.isPrivate">
-                <el-radio :label="item.dictValue" v-for="item in orOptions">{{ item.dictLabel }}</el-radio>
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="8">
-            <el-form-item label="课程原价" prop="price">
-              <el-input v-model="form.price" placeholder="请输入课程原价"/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="课程售价" prop="sellPrice">
-              <el-input v-model="form.sellPrice" placeholder="请输入课程售价"/>
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="单节所需积分" prop="integral" v-if="form.isIntegral==1">
-              <el-input v-model="form.integral" placeholder="请输入单节所需积分"/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <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>
@@ -558,7 +358,8 @@ export default {
         description: null,
         hotRanking: null,
         integral: null,
-        price: null
+        price: null,
+        isPrivate: 1
       },
       // 表单参数
       form: {},
@@ -799,9 +600,11 @@ export default {
       getUserCourse(courseId).then(response => {
         this.form = response.data;
         // this.form.cateId = response.data.cateId.toString();
-        getCateListByPid(this.form.cateId).then(response => {
-          this.subCategoryOptions = response.data;
-        });
+        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();
@@ -835,12 +638,9 @@ export default {
     submitForm() {
       this.$refs["form"].validate(valid => {
         if (valid) {
-          if (this.tags.length > 0) {
-            this.form.tags = this.tags.toString();
-          } else {
-            this.form.tags = null
-          }
-          this.form.companyIds = this.companyIds.toString()
+
+          // 私域课程
+          this.form.isPrivate = 1
           if (this.form.courseId != null) {
             updateUserCourse(this.form).then(response => {
               this.msgSuccess("修改成功");

+ 929 - 0
src/views/course/userCourse/public.vue

@@ -0,0 +1,929 @@
+<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="课堂名称" prop="courseName">
+        <el-input
+          v-model="queryParams.courseName"
+          placeholder="请输入课堂名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </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>
+      <el-col :span="1.5">
+        <el-button
+          v-if="queryParams.isShow==0"
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="multiple"
+          @click="putOn"
+          v-hasPermi="['course:userCourse:putOn']"
+        >上架
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          v-if="queryParams.isShow==1"
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="multiple"
+          @click="pullOff"
+          v-hasPermi="['course:userCourse:pullOff']"
+        >下架
+        </el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-tabs type="card" v-model="queryParams.isShow" @tab-click="handleClick">
+      <el-tab-pane label="已上架" name="1"></el-tab-pane>
+      <el-tab-pane label="待上架" name="0"></el-tab-pane>
+    </el-tabs>
+    <el-table height="600" border v-loading="loading" :data="userCourseList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+      <el-table-column label="课程ID" align="center" prop="courseId"/>
+      <el-table-column label="所属项目" align="center" prop="projectName"/>
+      <el-table-column label="封面图片" align="center" prop="imgUrl" width="120">
+        <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" prop="secondImg" width="100">
+        <template slot-scope="scope">
+          <el-popover
+            placement="right"
+            title=""
+            trigger="hover"
+          >
+            <img slot="reference" :src="scope.row.secondImg" width="50">
+            <img :src="scope.row.secondImg" style="max-width: 100px;">
+          </el-popover>
+        </template>
+      </el-table-column>
+      <el-table-column label="课堂名称" align="center" show-overflow-tooltip prop="courseName"/>
+      <el-table-column label="排序" align="center" prop="sort"/>
+      <el-table-column label="分类名称" align="center" prop="cateName"/>
+      <el-table-column label="子分类名称" align="center" prop="subCateName"/>
+      <el-table-column label="原价" align="center" prop="price"/>
+      <el-table-column label="售价" align="center" prop="sellPrice"/>
+      <el-table-column label="单节积分" align="center" prop="integral"/>
+      <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)"
+          >目录管理
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            :icon="scope.row.isShow === 1 ? 'el-icon-close' : 'el-icon-open'"
+            @click="handleShow(scope.row)"
+            v-hasPermi="['course:userCourse:editShow']"
+          >
+            {{ scope.row.isShow === 1 ? '下架' : '上架' }}
+          </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-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['course:userCourse: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="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="8">
+            <el-form-item label="课堂类型" prop="courseType">
+              <el-select v-model="form.courseType" 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-col> -->
+          <el-col :span="8">
+            <el-form-item label="关联达人" prop="talentId">
+              <el-select v-model="form.talentId" remote filterable clearable reserve-keyword
+                         placeholder="输入手机号搜索" :remote-method="talentMethod">
+                <el-option
+                  v-for="item in talentList"
+                  :key="item.talentId"
+                  :label="item.nickName +'#'+item.phone"
+                  :value="item.talentId">
+                  <span style="float: left">{{ item.talentId }}</span>
+                  <span style="margin-left: 30px ;">{{ item.nickName }}</span>
+                  <span style="margin-left: 30px">{{ item.phone }}</span>
+                </el-option>
+              </el-select>
+            </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="imgUrl">
+          <ImageUpload v-model="form.secondImg" type="image" :num="10" :width="150" :height="150"/>
+        </el-form-item>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="标签" prop="tags">
+              <el-select v-model="tags" multiple placeholder="请选择标签" filterable clearable size="small">
+                <el-option
+                  v-for="dict in tagsOptions"
+                  :key="dict.dictValue"
+                  :label="dict.dictLabel"
+                  :value="dict.dictValue"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="发课时间" prop="sendTime">
+              <el-time-picker
+                v-model="form.sendTime"
+                value-format="HH:mm"
+                format="HH:mm"
+                style="width: 100px"
+                :picker-options="{ selectableRange: startTimeRange }"
+              >
+              </el-time-picker>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="8">
+            <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-col :span="8">
+            <el-form-item label="播放量" prop="views">
+              <el-input-number v-model="form.views" :min="0" label="浏览量"></el-input-number>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="点赞量" prop="likes">
+              <el-input-number v-model="form.likes" :min="0" label="点赞量"></el-input-number>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+
+          <el-col :span="8">
+            <el-form-item label="收藏数" prop="favoriteNum">
+              <el-input-number v-model="form.favoriteNum" :min="0" label="收藏数"></el-input-number>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="分享数" prop="shares">
+              <el-input-number v-model="form.shares" :min="0" label="分享数"></el-input-number>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="热度值" prop="hotNum">
+              <el-input-number v-model="form.hotNum" :min="0" label="热度值"></el-input-number>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="状态" prop="isShow">
+              <el-radio-group v-model="form.isShow">
+                <el-radio :label="item.dictValue" v-for="item in specShowOptions">{{ item.dictLabel }}</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="是否推荐" prop="isTui">
+              <el-radio-group v-model="form.isTui">
+                <el-radio :label="item.dictValue" v-for="item in orOptions">{{ item.dictLabel }}</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="是否精选" prop="isBest">
+              <el-radio-group v-model="form.isBest">
+                <el-radio :label="item.dictValue" v-for="item in orOptions">{{ item.dictLabel }}</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="是否自动播放" prop="isAutoPlay">
+              <el-radio-group v-model="form.isAutoPlay">
+                <el-radio :label="item.dictValue" v-for="item in orOptions">{{ item.dictLabel }}</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="是否允许快进" prop="isFast">
+              <el-radio-group v-model="form.isFast">
+                <el-radio :label="item.dictValue" v-for="item in orOptions">{{ item.dictLabel }}</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="是否积分兑换" prop="isIntegral">
+              <el-radio-group v-model="form.isIntegral">
+                <el-radio :label="item.dictValue" v-for="item in orOptions">{{ item.dictLabel }}</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="是否逐级播放" prop="isNext">
+              <el-radio-group v-model="form.isNext">
+                <el-radio :label="item.dictValue" v-for="item in orOptions">{{ item.dictLabel }}</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8" style="display: none">
+            <el-form-item label="是否私域" prop="isPrivate">
+              <el-radio-group v-model="form.isPrivate">
+                <el-radio :label="item.dictValue" v-for="item in orOptions">{{ item.dictLabel }}</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="课程原价" prop="price">
+              <el-input v-model="form.price" placeholder="请输入课程原价"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="课程售价" prop="sellPrice">
+              <el-input v-model="form.sellPrice" placeholder="请输入课程售价"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="单节所需积分" prop="integral" v-if="form.isIntegral==1">
+              <el-input v-model="form.integral" placeholder="请输入单节所需积分"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <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-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,
+  putOn,
+  pullOff
+} 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/userCourseCatalogDetails.vue';
+import {getAllCourseCategoryList, getCatePidList, getCateListByPid} from "@/api/course/userCourseCategory";
+import {allList} from "@/api/company/company";
+
+export default {
+  name: "UserCoursePublic",
+  components: {
+    Treeselect,
+    Editor, ImageUpload, userCourseCatalogDetails
+  },
+  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,
+      // 查询参数
+      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,
+        isPrivate: 0
+      },
+      // 表单参数
+      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"}
+        ],
+      }
+    };
+  },
+  created() {
+    this.getList();
+    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);
+    },
+    handleClick(tab, event) {
+      this.queryParams.isShow = tab.name;
+      this.getList();
+    },
+    /** 转换课堂分类数据结构 */
+    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: "0",
+        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.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      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();
+        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 = "修改课程";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.tags.length > 0) {
+            this.form.tags = this.tags.toString();
+          } else {
+            this.form.tags = null
+          }
+          this.form.companyIds = this.companyIds.toString()
+          this.form.isPrivate = 0
+          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();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    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 () {
+      });
+    }
+  }
+};
+</script>

+ 1 - 1
src/views/fs/user/index.vue

@@ -119,7 +119,7 @@
             <el-option
               v-for="item in companyUserOptions"
               :key="item.userId"
-              :label="item.nickName"
+              :label="item.nickName + '_' + item.userName"
               :value="item.userId"
             />
           </el-select>

+ 8 - 0
src/views/qw/sop/ImageUpload.vue

@@ -9,6 +9,7 @@
       :on-error="handleUploadError"
       :on-exceed="handleExceed"
       name="file"
+      :disabled="disabled"
       :on-remove="handleRemove"
       :show-file-list="true"
       :file-list="fileList"
@@ -54,6 +55,11 @@ export default {
       type: Array,
       default: () => ["png", "jpg", "jpeg"],
     },
+    // 大小限制(MB)
+    disabled: {
+      type: Boolean,
+      default: false,
+    },
     // 是否显示提示
     isShowTip: {
       type: Boolean,
@@ -112,12 +118,14 @@ export default {
       if(findex > -1) {
         this.fileList.splice(findex, 1);
         this.$emit("input", this.listToString(this.fileList));
+        this.$emit("change", this.listToString(this.fileList));    // 新增change事件触发
       }
     },
     // 上传成功回调
     handleUploadSuccess(res,file) {
       this.fileList.push({ name: res.url, url: res.url });
       this.$emit("input", this.listToString(this.fileList));
+      this.$emit("change", this.listToString(this.fileList));    // 新增change事件触发
       this.loading.close();
     },
     // 上传前loading加载

+ 38 - 22
src/views/qw/sopTemp/index.vue

@@ -2,7 +2,7 @@
   <div class="app-container">
     <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
       <el-form-item label="销售公司" prop="companyId">
-        <el-select filterable  v-model="queryParams.companyId" clearable placeholder="请选择公司名" size="small">
+        <el-select filterable v-model="queryParams.companyId" clearable placeholder="请选择公司名" size="small">
           <el-option
             v-for="item in companys"
             :key="item.companyId"
@@ -122,7 +122,7 @@
       <el-table-column label="模板编号" align="center" prop="id"/>
       <el-table-column label="销售公司" align="center">
         <template slot-scope="scope">
-          <el-tag v-for="item in companys" v-if="scope.row.companyId == item.companyId">{{item.companyName}}</el-tag>
+          <el-tag v-for="item in companys" v-if="scope.row.companyId == item.companyId">{{ item.companyName }}</el-tag>
         </template>
       </el-table-column>
       <el-table-column label="模板标题" align="center" prop="name"/>
@@ -210,7 +210,7 @@
           <el-input v-model="form.name" placeholder="请输入模板标题"/>
         </el-form-item>
         <el-form-item label="销售公司" prop="companyId">
-          <el-select filterable  v-model="form.companyId" placeholder="请选择公司名" size="small">
+          <el-select filterable v-model="form.companyId" placeholder="请选择公司名" size="small">
             <el-option
               v-for="item in companys"
               :key="item.companyId"
@@ -240,7 +240,8 @@
           </el-select>
         </el-form-item>
         <el-form-item label="课程" prop="courseId" v-if="form.sendType == 5 && !form.id">
-          <el-select v-model="form.courseId"placeholder="请选择课程" style=" margin-right: 10px;" size="mini" filterable>
+          <el-select v-model="form.courseId" placeholder="请选择课程" style=" margin-right: 10px;" size="mini"
+                     filterable>
             <el-option
               v-for="dict in courseList"
               :key="dict.dictValue"
@@ -256,19 +257,19 @@
           <el-input-number v-model="form.sort" :min="0" label="排序"></el-input-number>
         </el-form-item>
         <el-form-item label="每天发送次数" prop="num" v-if="form.sendType == 5 && !form.id">
-          <el-input-number v-model="form.num" :min="1" label="每天发送次数"></el-input-number>
+          <el-input-number v-model="form.num" :min="1" label="每天发送次数" @change="sendNumChange"></el-input-number>
         </el-form-item>
         <el-form-item label="发送时间" v-if="form.sendType == 5 && !form.id">
-            <el-time-picker
-              class="custom-input"
-              v-for="index in form.num"
-              v-model="form.timeList[index]"
-              value-format="HH:mm"
-              format="HH:mm"
-              :picker-options="{ selectableRange: startTimeRange }"
-              placeholder="时间"
-              style="width: 100px;height: 20px;margin-left: 10px;margin-top: 10px">
-            </el-time-picker>
+          <el-time-picker
+            v-for="item in form.timeList"
+            class="custom-input"
+            v-model="item.value"
+            value-format="HH:mm"
+            format="HH:mm"
+            :picker-options="{ selectableRange: startTimeRange }"
+            placeholder="时间"
+            style="width: 100px;height: 20px;margin-left: 10px;margin-top: 10px">
+          </el-time-picker>
         </el-form-item>
       </el-form>
       <div slot="footer" class="dialog-footer" style="float: right;">
@@ -282,7 +283,8 @@
         <el-table-column label="小节" align="left" prop="videoName"/>
         <el-table-column label="金额" align="center">
           <template slot-scope="scope">
-            <el-input-number v-model="scope.row.redPacketMoney" :min="0.01" step="0.01" label="红包金额"></el-input-number>
+            <el-input-number v-model="scope.row.redPacketMoney" :min="0.01" step="0.01"
+                             label="红包金额"></el-input-number>
           </template>
         </el-table-column>
       </el-table>
@@ -307,7 +309,7 @@ import {
   updateRedPackage,
   updateTemp
 } from "@/api/qw/sopTemp";
-import { getCompanyList } from "@/api/company/company";
+import {getCompanyList} from "@/api/company/company";
 import {courseList} from "@/api/qw/sop";
 import fa from "element-ui/src/locale/lang/fa";
 
@@ -452,7 +454,7 @@ export default {
         sendType: this.sendType,
         sort: 0,
         num: 1,
-        timeList:[],
+        timeList: [{value: ""}],
         status: "1",
       };
       this.resetForm("form");
@@ -578,6 +580,10 @@ export default {
       delete this.form.rules
       this.$refs["form"].validate(valid => {
         if (valid) {
+          let f = JSON.parse(JSON.stringify(this.form));
+          if (f.timeList && f.timeList.length > 0) {
+            f.timeList = f.timeList.map(item => item.value);
+          }
           const loading = this.$loading({
             lock: true,
             text: 'Loading',
@@ -585,22 +591,22 @@ export default {
             background: 'rgba(0, 0, 0, 0.7)'
           });
           if (this.command == 2) {
-            copyTemplate(this.form).then(response => {
+            copyTemplate(f).then(response => {
               this.msgSuccess("复制成功");
               this.open = false;
               loading.close();
               this.getList();
             });
           } else {
-            if (this.form.id != null) {
-              updateTemp(this.form).then(response => {
+            if (f.id != null) {
+              updateTemp(f).then(response => {
                 this.msgSuccess("修改成功");
                 this.open = false;
                 loading.close();
                 this.getList();
               });
             } else {
-              addTemp(this.form).then(response => {
+              addTemp(f).then(response => {
                 this.msgSuccess("新增成功");
                 this.open = false;
                 loading.close();
@@ -658,6 +664,16 @@ export default {
         this.exportLoading = false;
       }).catch(() => {
       });
+    },
+    sendNumChange(val, old) {
+      if (val > old) {
+        for (let i = 0; i < val - old; i++) {
+          this.form.timeList.push({value: ""});
+        }
+      } else {
+        let len = old - val;
+        this.form.timeList.splice(Math.max(this.form.timeList.length - len, 0), len);
+      }
     }
   }
 };

+ 60 - 26
src/views/qw/sopTemp/updateSopTemp.vue

@@ -52,7 +52,7 @@
                                   placeholder="内容名称,仅内部可见"/>
                       </el-form-item>
                       <el-form-item label="课程" v-if="form.sendType == 5 && item.content && item.content.length > 0" required>
-                        <el-select :disabled="formType == 3 || form.sendType == 5" v-model="item.content[0].courseId"
+                        <el-select :disabled="(formType == 3 || form.sendType == 5) && item.id != null" v-model="item.content[0].courseId"
                                    placeholder="请选择课程" style=" margin-right: 10px;" size="mini" remote
                                    filterable
                                    @change="courseChangeUpdate(item.content[0], index, 0)">
@@ -63,7 +63,7 @@
                             :value="parseInt(dict.dictValue)"
                           />
                         </el-select>
-                        <el-select :disabled="formType == 3 || form.sendType == 5" v-model="item.content[0].videoId"
+                        <el-select :disabled="(formType == 3 || form.sendType == 5) && item.id != null" v-model="item.content[0].videoId"
                                    placeholder="请选择小节" size="mini" style=" margin-right: 10px;" remote
                                    filterable
                                    @change="videoIdChange(item.content[0],index,0)">
@@ -74,17 +74,6 @@
                             :value="parseInt(dict.dictValue)"
                           />
                         </el-select>
-                        <el-select :disabled="formType == 3" v-model="item.content[0].courseType"
-                                   placeholder="请选择消息类型" size="mini"
-                                   style=" margin-right: 10px;" v-if="item.content[0].type != 4 ">
-                          <el-option
-                            v-for="dict in sysFsSopWatchStatus"
-                            :key="dict.dictValue"
-                            :label="dict.dictLabel"
-                            :value="Number(dict.dictValue)"
-                          />
-                        </el-select>
-
                       </el-form-item>
                       <el-form-item label="规则">
                         <div v-for="(content, contentIndex) in item.content" :key="contentIndex"
@@ -128,6 +117,18 @@
                                     inactive-value="0">
                                   </el-switch>
                                 </el-form-item>
+                                <el-form-item label="消息类型" v-if="form.sendType != 4">
+                                  <el-select :disabled="formType == 3" v-model="content.courseType"
+                                             placeholder="请选择消息类型" size="mini"
+                                             style=" margin-right: 10px;" v-if="content.type != 4 ">
+                                    <el-option
+                                      v-for="dict in sysFsSopWatchStatus"
+                                      :key="dict.dictValue"
+                                      :label="dict.dictLabel"
+                                      :value="Number(dict.dictValue)"
+                                    />
+                                  </el-select>
+                                </el-form-item>
 
                                 <el-form-item label="消息类别" v-if="form.sendType != 4 && form.sendType != 5">
                                   <el-radio-group v-model="content.type"
@@ -135,7 +136,6 @@
                                                   @change="updateHtml(() => content.contentType = '1')">
                                     <el-radio :label="1">普通</el-radio>
                                     <el-radio :label="2">课程</el-radio>
-                                    <el-radio :label="3">订单</el-radio>
                                     <el-radio :label="4">AI触达</el-radio>
                                     <el-radio :label="5">打标签</el-radio>
                                   </el-radio-group>
@@ -260,10 +260,10 @@
                                               </el-radio>
                                             </el-radio-group>
                                           </div>
-                                          <div v-if="form.sendType == 2 || form.sendType == 5">
+                                          <div v-if="form.sendType == 2">
                                             <el-radio-group v-model="setList.contentType"
                                                             :disabled="formType == 3"
-                                                            @change="handleContentTypeChange(content,index,contentIndex,setIndex)">
+                                                            @change="handleContentTypeChange(content,index,contentIndex,setIndex, item, 'contentType', $event)">
                                               <el-radio
                                                 :key="item.dictValue"
                                                 :label="item.dictValue"
@@ -272,6 +272,18 @@
                                               </el-radio>
                                             </el-radio-group>
                                           </div>
+                                          <div v-if="form.sendType == 5">
+                                            <el-radio-group v-model="setList.contentType"
+                                                            :disabled="formType == 3 || (form.sendType == 5 && contentIndex != 0 && setIndex == 0)"
+                                                            @change="handleContentTypeChange(content,index,contentIndex,setIndex, item, 'contentType', $event)">
+                                              <el-radio
+                                                :key="item.dictValue"
+                                                :label="item.dictValue"
+                                                :disabled="(content.type!=2 && item.dictValue === '9') || (content.isOfficial==1 && ['5','6','7','8','9'].includes(item.dictValue))"
+                                                v-for="item in sysQwSopAiContentType" v-if="setIndex == 0 ? courseTypeList.includes(item.dictValue) : !courseTypeList.includes(item.dictValue)">{{ item.dictLabel }}
+                                              </el-radio>
+                                            </el-radio-group>
+                                          </div>
                                         </el-form-item>
                                         <el-form-item label="内容">
                                           <el-input :disabled="formType == 3" v-if="setList.contentType == 1 "
@@ -300,19 +312,22 @@
                                             v-if="setList.contentType == 3  || (setList.contentType == 9 && content.type==2 )">
                                             <el-card class="box-card">
                                               <el-form-item label="链接标题:" label-width="100px" required>
-                                                <el-input :disabled="formType == 3" v-model="setList.linkTitle"
+                                                <el-input :disabled="formType == 3 || (form.sendType == 5 && contentIndex != 0 && setIndex == 0)" v-model="setList.linkTitle"
+                                                          @change="updateAll(setIndex, item, 'linkTitle', $event)"
                                                           placeholder="请输入链接标题"
                                                           style="width: 90%;"/>
                                               </el-form-item>
                                               <el-form-item label="链接描述:" label-width="100px" required>
-                                                <el-input :disabled="formType == 3" type="textarea" :rows="3"
+                                                <el-input :disabled="formType == 3 || (form.sendType == 5 && contentIndex != 0 && setIndex == 0)" type="textarea" :rows="3"
                                                           v-model="setList.linkDescribe"
+                                                          @change="updateAll(setIndex, item, 'linkDescribe', $event)"
                                                           placeholder="请输入链接描述"
                                                           style="width: 90%;margin-top: 1%;"/>
                                               </el-form-item>
                                               <el-form-item label="链接封面:" label-width="100px" required>
-                                                <ImageUpload :disabled="formType == 3" v-model="setList.linkImageUrl"
+                                                <ImageUpload :disabled="formType == 3 || (form.sendType == 5 && contentIndex != 0 && setIndex == 0)" v-model="setList.linkImageUrl"
                                                              type="image" :num="1"
+                                                             @input="updateAll(setIndex, item, 'linkImageUrl', $event)"
                                                              :file-size="2" :width="150" :height="150"
                                                              style="margin-top: 1%;"/>
                                               </el-form-item>
@@ -337,12 +352,16 @@
                                             <el-card class="box-card">
                                               <el-form-item label="标题" prop="miniprogramTitle">
                                                 <el-input v-model="setList.miniprogramTitle"
+                                                          :disabled="formType == 3 || (form.sendType == 5 && contentIndex != 0 && setIndex == 0)"
+                                                          @change="updateAll(setIndex, item, 'miniprogramTitle', $event)"
                                                           placeholder="请输入小程序消息标题,最长为64字节" :rows="2"
                                                           maxlength="64" type="textarea"
                                                           @input="checkByteLength(content,setList.contentType,content.isOfficial)"/>
                                               </el-form-item>
                                               <el-form-item label="封面" prop="miniprogramPicUrl">
                                                 <ImageUpload v-if="content.isOfficial !== '1'"
+                                                             @change="updateAll(setIndex, item, 'miniprogramPicUrl', $event)"
+                                                             :disabled="formType == 3 || (form.sendType == 5 && contentIndex != 0 && setIndex == 0)"
                                                              v-model="setList.miniprogramPicUrl" type="image" :num="10"
                                                              :width="150" :height="150"/>
                                               </el-form-item>
@@ -479,7 +498,7 @@
                                         <el-form-item label="添加短链"
                                                       v-if="content.type == 2 && setList.contentType == 1  ">
                                           <el-tooltip content="请先根据课程选定课程小节之后再添加" effect="dark"
-                                                      :disabled="!!content.videoId">
+                                                      :disabled="!content.videoId">
                                             <el-switch
                                               @change="updateHtml"
                                               v-model="setList.isBindUrl"
@@ -500,6 +519,8 @@
                                                       v-if="content.type == 2 && setList.isBindUrl == '1' && setList.contentType != 2  && setList.contentType != 5  && setList.contentType != 6 && setList.contentType != 8 && setList.contentType != 9 && setList.contentType != 10  ">
                                           <el-row>
                                             <el-input type="number" v-model="setList.expiresDays"
+                                                      :disabled="formType == 3 || (form.sendType == 5 && contentIndex != 0 && setIndex == 0)"
+                                                      @change="updateAll(setIndex, item, 'expiresDays', $event)"
                                                       style="width: 200px">
                                               <template slot="append">天</template>
                                             </el-input>
@@ -545,7 +566,7 @@
                                     <el-col :span="1" :offset="1">
                                       <i class="el-icon-delete" @click="delSetList(index,contentIndex,setIndex)"
                                          style="margin-top: 20px;"
-                                         v-if="content.setting.length>1 && (formType != 3)"></i>
+                                         v-if="content.setting.length>1 && formType != 3 && !(form.sendType == 5 && setIndex == 0)"></i>
                                     </el-col>
                                   </el-row>
                                 </div>
@@ -707,6 +728,7 @@ export default {
       dayList: [],
       ruleList: [],
       ids: [],
+      courseTypeList: ['3', '4', '9'],
       sysFsSopWatchStatus: [],
       //消息内容类型 企微版
       sysQwSopContentType: [],
@@ -1412,7 +1434,7 @@ export default {
         });
       }
     },
-    handleContentTypeChange(content, index, countIndex) {
+    handleContentTypeChange(content, index, countIndex, setIndex, item, fieldName, val) {
       //如果是链接的才上
       if (content.courseId != null && content.type == 2) {
         const selectedCourse = this.courseList.find(course => parseInt(course.dictValue) === content.courseId);
@@ -1450,7 +1472,14 @@ export default {
           }
         }
       }
-
+      if(countIndex == 0 && setIndex == 0){
+        this.updateAll(setIndex, item, fieldName, val);
+        for (let index in item.content) {
+          if(index != 0){
+            this.handleContentTypeChange(item.content[index], 0, index, 0, item, fieldName, val);
+          }
+        }
+      }
     },
     videoIdChange(content, index, countIndex) {
 
@@ -1699,9 +1728,14 @@ export default {
       val || val();
 
     },
-    // updateChange(val) {
-    //   console.log(val)
-    // }
+    updateAll(setIndex, list, fieldName, newVal) {
+      if(this.form.sendType == 5 && setIndex == 0) {
+        console.info("更新数据", newVal)
+        for (let index in list.content) {
+          this.$set(list.content[index].setting[0], fieldName, newVal);
+        }
+      }
+    }
   }
 };
 </script>

+ 179 - 0
src/views/user/darkRoom/index.vue

@@ -0,0 +1,179 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px" @submit.native.prevent>
+      <el-form-item label="关键词" prop="keyword">
+        <el-input
+          style="width:220px"
+          v-model="queryParams.keyword"
+          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-row :gutter="10" class="mb8">
+      <el-button
+        size="mini"
+        type="primary"
+        style="margin-left: 5px"
+        :disabled="ids.length === 0"
+        @click="handleUpdateBatch"
+        v-hasPermi="['store:user:darkRoomList']"
+      >批量启用</el-button>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table  height="500" border v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="用户id" align="center" prop="userId" />
+      <el-table-column label="用户昵称" align="center" prop="nickname" />
+      <el-table-column label="用户头像" align="center" prop="avatar">
+        <template slot-scope="scope">
+          <el-popover trigger="hover" placement="top">
+            <el-image :src="scope.row.avatar" style="width: 200px;height: 200px"/>
+            <div slot="reference" class="name-wrapper">
+              <el-avatar shape="square" size="large" :src="scope.row.avatar"/>
+            </div>
+          </el-popover>
+        </template>
+      </el-table-column>
+      <el-table-column label="注册时间" align="center" prop="createTime" width="160px"/>
+      <el-table-column label="看课数量" align="center" prop="watchCourseCount" />
+      <el-table-column label="缺课数量" align="center" prop="missCourseCount" />
+      <el-table-column label="缺课状态" align="center" prop="missCourseStatus">
+        <template slot-scope="scope">
+          <el-tag effect="dark" type="danger"  v-if="scope.row.missCourseStatus === 1">已缺课</el-tag>
+          <el-tag effect="dark" type="success" v-else>未缺课</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="参与营期数量" align="center" prop="partCourseCount" width="100px"/>
+      <el-table-column label="最后一次看课时间" align="center" prop="lastWatchDate"  width="160px"/>
+      <el-table-column label="用户状态" align="center" prop="courseCountStatus">
+        <template slot-scope="scope">
+          <el-tag effect="dark" type="success" v-if="scope.row.courseCountStatus === 1">正常</el-tag>
+          <el-tag effect="dark" type="info"    v-else-if="scope.row.courseCountStatus === 2">停止</el-tag>
+          <el-tag effect="dark" type="danger"  v-else>未看</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="停课天数" align="center" prop="stopWatchDays" />
+      <el-table-column label="完播时间" align="center" prop="completeWatchDate" width="160px"/>
+      <el-table-column label="标签名称" align="center" prop="tag" />
+      <el-table-column label="所属销售名称" align="center" prop="companyUserNickName" width="120px"/>
+      <el-table-column label="备注" align="center" prop="remark" />
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['store:user:darkRoomList']"
+          >启用</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 { darkRoomList,enabledUsers } from "@/api/store/user";
+
+export default {
+  name: "darkRoom",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 用户列表数据
+      userList: [],
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        keyword: null,
+        isBlack: true
+      },
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 查询客户列表 */
+    getList() {
+      this.loading = true;
+      darkRoomList(this.queryParams).then(response => {
+        this.userList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.userId)
+      this.single = selection.length!==1
+      this.multiple = !selection.length
+    },
+    // 启用
+    handleUpdate(row) {
+      enabledUsers([row.userId]).then(response => {
+        if (response.code === 200) {
+          this.msgSuccess("取消禁用成功");
+          this.getList();
+        } else {
+          this.msgError(response.msg);
+        }
+      });
+    },
+    // 启用
+    handleUpdateBatch() {
+      enabledUsers(this.ids).then(response => {
+        if (response.code === 200) {
+          this.msgSuccess("取消禁用成功");
+          this.getList();
+        } else {
+          this.msgError(response.msg);
+        }
+      });
+    }
+  }
+};
+</script>
+<style scoped>
+.app-container {
+  height: 87.5vh;
+}
+</style>