소스 검색

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

ct 2 주 전
부모
커밋
471fa8d01d

+ 10 - 8
.env.development

@@ -1,13 +1,15 @@
 # 页面标题
-VUE_APP_TITLE =互联网医院管理系统
+VUE_APP_TITLE =木易华康互联网医院管理系统
+# 首页菜单标题
+VUE_APP_TITLE_INDEX =木易华康互联网医院
 # 公司名称
-VUE_APP_COMPANY_NAME =重庆云联融智科技有限公司
+VUE_APP_COMPANY_NAME =福州市木易华康医药有限公司
 # ICP备案号
-VUE_APP_ICP_RECORD =蜀ICP备2023036719号
+VUE_APP_ICP_RECORD =闽ICP备2020016609号-3
 # ICP网站访问地址
 VUE_APP_ICP_URL =https://beian.miit.gov.cn
 # 网站LOG
-VUE_APP_LOG_URL =@/assets/logo/logo.png
+VUE_APP_LOG_URL =@/assets/logo/myhk.png
 # 存储桶配置
 VUE_APP_OBS_ACCESS_KEY_ID = K2UTJGIN7UTZJR2XMXYG
 # 存储桶配置
@@ -15,15 +17,15 @@ VUE_APP_OBS_SECRET_ACCESS_KEY = sbyeNJLbcYmH6copxeFP9pAoksM4NIT9Zw4x0SRX
 # 存储桶配置
 VUE_APP_OBS_SERVER = https://obs.cn-north-4.myhuaweicloud.com
 # 存储桶配置
-VUE_APP_OBS_BUCKET = zkzh-hw079058881
+VUE_APP_OBS_BUCKET = myhk-hw079058881
 # 存储桶配置
-VUE_APP_COS_BUCKET = zkzh-1323137866
+VUE_APP_COS_BUCKET = myhk-1323137866
 # 存储桶配置
 VUE_APP_COS_REGION = ap-chongqing
 # 线路一地址
-VUE_APP_VIDEO_LINE_1 = https://zkzhtcpv.ylrzcloud.com
+VUE_APP_VIDEO_LINE_1 = https://myhktcpv.ylrzcloud.com
 # 线路二地址
-VUE_APP_VIDEO_LINE_2 = https://zkzhobs.ylrztop.com
+VUE_APP_VIDEO_LINE_2 = https://myhkobs.ylrztop.com
 
 # 开发环境配置
 ENV = 'development'

+ 2 - 0
.env.prod-hcl

@@ -1,5 +1,7 @@
 # 页面标题
 VUE_APP_TITLE =恒春来管理系统
+# 首页菜单标题
+VUE_APP_TITLE_INDEX =恒春来
 # 公司名称
 VUE_APP_COMPANY_NAME =黑龙江珠斯网络科技有限公司
 # ICP备案号

+ 2 - 0
.env.prod-hdt

@@ -1,5 +1,7 @@
 # 页面标题
 VUE_APP_TITLE =弘德互联网医院管理系统
+# 首页菜单标题
+VUE_APP_TITLE_INDEX =弘德互联网医院
 # 公司名称
 VUE_APP_COMPANY_NAME =河北红德堂医药连锁有限公司保定第五十七分公司
 # ICP备案号

+ 2 - 0
.env.prod-hzyy

@@ -1,5 +1,7 @@
 # 页面标题
 VUE_APP_TITLE =弘珍医药管理系统
+# 首页菜单标题
+VUE_APP_TITLE_INDEX =弘珍医药
 # 公司名称
 VUE_APP_COMPANY_NAME =南宁良庆区宝和堂金悦澜湾大药房
 # ICP备案号

+ 2 - 0
.env.prod-jnmy

@@ -1,5 +1,7 @@
 # 页面标题
 VUE_APP_TITLE =金牛明医互联网医院管理系统
+# 首页菜单标题
+VUE_APP_TITLE_INDEX =金牛明医
 # 公司名称
 VUE_APP_COMPANY_NAME =成都金牛明医云联互联网医院有限公司
 # ICP备案号

+ 2 - 0
.env.prod-jzzx

@@ -1,5 +1,7 @@
 # 页面标题
 VUE_APP_TITLE =九州在线管理系统
+# 首页菜单标题
+VUE_APP_TITLE_INDEX =九州在线
 # 公司名称
 VUE_APP_COMPANY_NAME =成都双流九州在线互联网医院有限公司
 # ICP备案号

+ 6 - 4
.env.prod-myhk

@@ -1,9 +1,11 @@
 # 页面标题
-VUE_APP_TITLE =木易华康医药管理系统
+VUE_APP_TITLE =木易华康互联网医院管理系统
+# 首页菜单标题
+VUE_APP_TITLE_INDEX =木易华康
 # 公司名称
-VUE_APP_COMPANY_NAME =木易华康医药管理系统
+VUE_APP_COMPANY_NAME =福州市木易华康医药有限公司
 # ICP备案号
-VUE_APP_ICP_RECORD =桂ICP备2025059156号-1
+VUE_APP_ICP_RECORD =闽ICP备2020016609号-3
 # ICP网站访问地址
 VUE_APP_ICP_URL =https://beian.miit.gov.cn
 # 网站LOG
@@ -26,7 +28,7 @@ VUE_APP_VIDEO_LINE_1 = https://myhktcpv.ylrzcloud.com
 VUE_APP_VIDEO_LINE_2 = https://myhkobs.ylrztop.com
 
 # 开发环境配置
-ENV = 'development'
+ENV = 'production'
 
 # FS管理系统/开发环境
 VUE_APP_BASE_API = '/prod-api'

+ 2 - 0
.env.prod-sxjz

@@ -1,5 +1,7 @@
 # 页面标题
 VUE_APP_TITLE =互联网医院管理系统
+# 首页菜单标题
+VUE_APP_TITLE_INDEX =陕西今正
 # 公司名称
 VUE_APP_COMPANY_NAME =银川鑫泰互联网医院有限公司
 # ICP备案号

+ 2 - 0
.env.prod-yzt

@@ -1,5 +1,7 @@
 # 页面标题
 VUE_APP_TITLE =易诊通互联网医院管理系统
+# 首页菜单标题
+VUE_APP_TITLE_INDEX =易诊通
 # 公司名称
 VUE_APP_COMPANY_NAME =广州易诊通医院有限公司
 # ICP备案号

+ 7 - 1
src/api/company/companyUser.js

@@ -15,6 +15,12 @@ export function getAllUserlist(query) {
     params: query
   })
 }
+export function getUserList(companyId){
+  return request({
+    url: '/company/companyUser/getUserList?companyId='+companyId,
+    method: 'get'
+  })
+}
 
 export function getUserListByDeptId(query) {
   return request({
@@ -66,4 +72,4 @@ export function exportCompanyUser(query) {
     method: 'get',
     params: query
   })
-}
+}

+ 53 - 0
src/api/course/courseFinishTemp.js

@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询完课模板列表
+export function listCourseFinishTemp(query) {
+  return request({
+    url: '/course/courseFinishTemp/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询完课模板详细
+export function getCourseFinishTemp(id) {
+  return request({
+    url: '/course/courseFinishTemp/' + id,
+    method: 'get'
+  })
+}
+
+// 新增完课模板
+export function addCourseFinishTemp(data) {
+  return request({
+    url: '/course/courseFinishTemp',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改完课模板
+export function updateCourseFinishTemp(data) {
+  return request({
+    url: '/course/courseFinishTemp',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除完课模板
+export function delCourseFinishTemp(id) {
+  return request({
+    url: '/course/courseFinishTemp/' + id,
+    method: 'delete'
+  })
+}
+
+// 导出完课模板
+export function exportCourseFinishTemp(query) {
+  return request({
+    url: '/course/courseFinishTemp/export',
+    method: 'get',
+    params: query
+  })
+}

+ 53 - 0
src/api/course/courseFinishTempParent.js

@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询完课模板列表
+export function listCourseFinishTempParent(query) {
+  return request({
+    url: '/course/courseFinishTempParent/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询完课模板详细
+export function getCourseFinishTempParent(id) {
+  return request({
+    url: '/course/courseFinishTempParent/' + id,
+    method: 'get'
+  })
+}
+
+// 新增完课模板
+export function addCourseFinishTempParent(data) {
+  return request({
+    url: '/course/courseFinishTempParent',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改完课模板
+export function updateCourseFinishTempParent(data) {
+  return request({
+    url: '/course/courseFinishTempParent',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除完课模板
+export function delCourseFinishTempParent(id) {
+  return request({
+    url: '/course/courseFinishTempParent/' + id,
+    method: 'delete'
+  })
+}
+
+// 导出完课模板
+export function exportCourseFinishTempParent(query) {
+  return request({
+    url: '/course/courseFinishTempParent/export',
+    method: 'get',
+    params: query
+  })
+}

+ 82 - 0
src/api/course/userCoursePublic.js

@@ -0,0 +1,82 @@
+import request from '@/utils/request'
+
+// 查询课程列表
+export function listUserCourse(query) {
+  return request({
+    url: '/course/userCourse/publicList',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询课程详细
+export function getUserCourse(courseId) {
+  return request({
+    url: '/course/userCourse/public/' + courseId,
+    method: 'get'
+  })
+}
+
+// 新增课程
+export function addUserCourse(data) {
+  return request({
+    url: '/course/userCourse/public',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改课程
+export function updateUserCourse(data) {
+  return request({
+    url: '/course/userCourse/public',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除课程
+export function delUserCourse(courseId) {
+  return request({
+    url: '/course/userCourse/public/' + courseId,
+    method: 'delete'
+  })
+}
+
+// 导出课程
+export function exportUserCourse(query) {
+  return request({
+    url: '/course/userCourse/publicExport',
+    method: 'get',
+    params: query
+  })
+}
+
+export function getAllCourse() {
+  return request({
+    url: '/course/userCourse/getAllList',
+    method: 'get'
+  })
+}
+
+
+export function updateIsShow(data) {
+  return request({
+    url: '/course/userCourse/publicUpdateIsShow',
+    method: 'post',
+    data: data
+  })
+}
+
+export function putOn(courseIds) {
+  return request({
+    url: '/course/userCourse/publicPutOn/' + courseIds,
+    method: 'post'
+  })
+}
+export function pullOff(courseIds) {
+  return request({
+    url: '/course/userCourse/publicPutOff/' + courseIds,
+    method: 'post'
+  })
+}

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

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

BIN
src/assets/logo/myhk.png


+ 1 - 1
src/layout/components/Sidebar/Logo.vue

@@ -34,7 +34,7 @@ export default {
   },
   data() {
     return {
-      title: process.env.VUE_APP_TITLE,
+      title: process.env.VUE_APP_TITLE_INDEX || "互联网医院SCRM",
     }
   }
 }

+ 13 - 0
src/router/index.js

@@ -202,6 +202,19 @@ export const constantRoutes = [
       }
     ]
   },
+  {
+    path: '/course',
+    component: Layout,
+    hidden: true,
+    children: [
+      {
+        path: 'courseFinishTemp/:parentId',
+        component: (resolve) => require(['@/views/course/courseFinishTemp/index'], resolve),
+        name: 'courseFinishTemp',
+        meta: { title: '模板详情', activeMenu: '/course'}
+      }
+    ]
+  },
   {
     path: '/qw/sopUserLogs',
     component: Layout,

+ 9 - 2
src/views/components/course/userCourseCatalogDetails.vue

@@ -26,6 +26,7 @@
           icon="el-icon-plus"
           size="mini"
           @click="handleAdd"
+          v-hasPermi="['course:userCourseVideo:add']"
         >新增目录</el-button>
       </el-col>
       <el-col :span="1.5">
@@ -35,6 +36,7 @@
           :disabled="!ids || ids.length <= 0"
           size="mini"
           @click="openUpdates"
+          v-hasPermi="['course:userCourseVideo:updateTime']"
         >修改时间</el-button>
       </el-col>
       <el-col :span="1.5">
@@ -43,6 +45,7 @@
           plain
           size="mini"
           @click="openAdds"
+          v-hasPermi="['course:userCourseVideo:batchAdd']"
         >批量添加</el-button>
       </el-col>
       <el-col :span="1.5">
@@ -52,6 +55,7 @@
           size="mini"
           v-if="isPrivate === 1"
           @click="updateRedPageckeOpen"
+          v-hasPermi="['course:userCourseVideo:updateRed']"
         >修改红包</el-button>
       </el-col>
       <el-col :span="1.5">
@@ -62,6 +66,7 @@
           size="mini"
           :disabled="multiple"
           @click="handleDelete"
+          v-hasPermi="['course:userCourseVideo:remove']"
         >删除</el-button>
       </el-col>
       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -69,7 +74,7 @@
     <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" prop="round" />
+<!--      <el-table-column label="轮次" align="center" prop="round" />-->
       <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>
@@ -106,12 +111,14 @@
             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-delete"
             @click="handleDelete(scope.row)"
+            v-hasPermi="['course:userCourseVideo:remove']"
           >删除</el-button>
         </template>
       </el-table-column>
@@ -257,7 +264,7 @@
         <el-button @click="updateBatchData.open = false">取 消</el-button>
       </div>
     </el-dialog>
-    <el-dialog :title="questionBank.title" :visible.sync="questionBank.open" width="800px" append-to-body >
+    <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="视频库选择" :visible.sync="addBatchData.open" width="900px" append-to-body>

+ 916 - 0
src/views/course/courseFinishTemp/index.vue

@@ -0,0 +1,916 @@
+<template>
+  <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-option
+            v-for="item in companys"
+            :key="item.companyId"
+            :label="item.companyName"
+            :value="item.companyId"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="模板名称" prop="name">
+        <el-input
+          v-model="queryParams.name"
+          placeholder="请输入模板名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="请选择状态" clearable size="small">
+          <el-option
+            v-for="dict in statusOptions"
+            :key="dict.dictValue"
+            :label="dict.dictLabel"
+            :value="dict.dictValue"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="课程" 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="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="['courseFinishTemp:course: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="['courseFinishTemp:course: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="['courseFinishTemp:course: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="['courseFinishTemp:course:export']"
+        >导出
+        </el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table border v-loading="loading" :data="courseFinishTempList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+      <el-table-column label="模板ID" align="center" prop="id"/>
+      <el-table-column label="销售公司" align="center" prop="status">
+        <template slot-scope="scope">
+          <el-tag v-for="item in companys" v-if="item.companyId == scope.row.companyId" >{{item.companyName}}</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="模板名称" align="center" prop="name"/>
+      <el-table-column label="状态" align="center" prop="status">
+        <template slot-scope="scope">
+          <dict-tag :options="statusOptions" :value="scope.row.status"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="课程名称" align="center" prop="courseName"/>
+      <el-table-column label="小节名称" align="center" prop="videoName"/>
+      <el-table-column label="创建时间" align="center" prop="createTime"/>
+      <el-table-column label="修改时间" align="center" prop="updateTime"/>
+      <el-table-column label="全选销售" align="center" prop="isAllCompanyUser">
+        <template slot-scope="scope">
+          <dict-tag :options="allowSelect" :value="scope.row.isAllCompanyUser"/>
+        </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="['courseFinishTemp:course:edit']"
+          >修改
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-s-promotion"
+            @click="handleSelectDetails(scope.row)"
+            v-hasPermi="['courseFinishTemp:course:query']"
+          >详情
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['courseFinishTemp:course: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="80px">
+        <el-form-item label="模板名称" prop="name">
+          <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" @change="initCompanyUserList">
+            <el-option
+              v-for="item in companys"
+              :key="item.companyId"
+              :label="item.companyName"
+              :value="item.companyId"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="类型">
+          <el-radio-group v-model="form.type">
+            <el-radio :label="1">个人消息</el-radio>
+            <el-radio :label="2">群发消息</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="状态">
+          <el-radio-group v-model="form.status">
+            <el-radio
+              v-for="dict in statusOptions"
+              :key="dict.dictValue"
+              :label="parseInt(dict.dictValue)"
+            >{{ dict.dictLabel }}
+            </el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="选择课程">
+          <el-select v-model="form.courseId" placeholder="请选择课程" style=" margin-right: 10px;" size="mini"
+                     @change="courseChange()">
+            <el-option
+              v-for="dict in courseList"
+              :key="dict.dictValue"
+              :label="dict.dictLabel"
+              :value="parseInt(dict.dictValue)"
+            />
+          </el-select>
+          <el-select v-model="form.videoId" placeholder="请选择小节" size="mini" style=" margin-right: 10px;">
+            <el-option
+              v-for="dict in videoList"
+              :key="dict.dictValue"
+              :label="dict.dictLabel"
+              :value="parseInt(dict.dictValue)"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="规则" prop="setting">
+          <div v-for="(item, index) in setting" :key="index"
+               style="background-color: #fdfdfd; border: 1px solid #e6e6e6; margin-bottom: 20px;">
+            <el-row>
+              <el-col :span="22">
+                <el-form :model="item" label-width="70px">
+                  <el-form-item label="内容类别" style="margin: 2%">
+                    <el-radio-group v-model="item.contentType">
+                      <el-radio :label="item.dictValue" v-for="item in sysQwSopAiContentType">{{ item.dictLabel }}
+                      </el-radio>
+                    </el-radio-group>
+                  </el-form-item>
+                  <el-form-item label="内容" style="margin-bottom: 2%">
+                    <el-input v-if="item.contentType == 1 " v-model="item.value" type="textarea" :rows="3"
+                              placeholder="内容" style="width: 90%;margin-top: 10px;"/>
+
+                    <ImageUpload v-if="item.contentType == 2 " v-model="item.imgUrl" type="image" :num="1" :width="150"
+                                 :height="150"/>
+
+                    <div v-if="item.contentType == 3 ">
+                      <el-card class="box-card">
+                        <el-form-item label="链接标题:" label-width="100px">
+                          <el-input v-model="item.linkTitle" placeholder="请输入链接标题" style="width: 90%;"/>
+                        </el-form-item>
+                        <el-form-item label="链接描述:" label-width="100px">
+                          <el-input type="textarea" :rows="3" v-model="item.linkDescribe" placeholder="请输入链接描述"
+                                    style="width: 90%;margin-top: 1%;"/>
+                        </el-form-item>
+                        <el-form-item label="链接封面:" label-width="100px">
+                          <ImageUpload v-model="item.linkImageUrl" type="image" :num="1" :file-size="2" :width="150"
+                                       :height="150" style="margin-top: 1%;"/>
+                        </el-form-item>
+                        <el-form-item label="链接地址:" label-width="100px">
+                          <el-input v-model="item.linkUrl" placeholder="请输入链接地址" style="width: 90%;"/>
+                        </el-form-item>
+                      </el-card>
+                    </div>
+                    <div v-if="item.contentType == 4">
+
+                    </div>
+                    <div v-if="item.contentType == 5 ">
+
+                      <el-form-item label="上传文件:" prop="fileUrl" label-width="100px">
+                        <el-upload
+                          v-model="item.fileUrl"
+                          class="avatar-uploader"
+                          :action="uploadUrl"
+                          :show-file-list="false"
+                          :on-success="(res, file) => handleAvatarSuccessFile(res, file, item)"
+                          :before-upload="beforeAvatarUploadFile">
+                          <i class="el-icon-plus avatar-uploader-icon"></i>
+                        </el-upload>
+                        <el-link v-if="item.fileUrl" type="primary" :href="downloadUrl(item.fileUrl)" download>
+                          {{ item.fileUrl }}
+                        </el-link>
+                      </el-form-item>
+
+                    </div>
+
+                    <div v-if="item.contentType == 6 ">
+                      <el-form-item label="上传视频:" prop="videoUrl" label-width="100px">
+                        <el-upload
+                          v-model="item.videoUrl"
+                          class="avatar-uploader"
+                          :action="uploadUrl"
+                          :show-file-list="false"
+                          :on-success="(res, file) => handleAvatarSuccessVideo(res, file, item)"
+                          :before-upload="beforeAvatarUploadVideo">
+                          <i class="el-icon-plus avatar-uploader-icon"></i>
+                        </el-upload>
+                        <video v-if="item.videoUrl"
+                               :src="item.videoUrl"
+                               controls style="width: 200px;height: 100px">
+                        </video>
+                      </el-form-item>
+                    </div>
+                    <div v-if="item.contentType == 7 ">
+                      <el-input
+                        v-model="item.value"
+                        type="textarea" :rows="3" maxlength="66" show-word-limit
+                        placeholder="输入要转为语音的内容" style="width: 90%;margin-top: 10px;"
+                        @input="handleInputVideoText(item.value,item)"/>
+                    </div>
+                    <div v-if="item.contentType == 8">
+
+                    </div>
+
+                  </el-form-item>
+                </el-form>
+              </el-col>
+              <el-col :span="1" :offset="1">
+                <i class="el-icon-delete" @click="delSetList(index, 0)" style="margin-top: 20px;"
+                   v-if="setting.length>1 && formType==1"></i>
+              </el-col>
+            </el-row>
+          </div>
+          <el-link type="primary" class="el-icon-plus" :underline="false" @click='addSetList(0)' v-if="formType==1">
+            添加内容
+          </el-link>
+        </el-form-item>
+        <el-form-item label="群聊恭喜规则" prop="setting">
+          <div v-for="(item, index) in chatSetting" :key="index"
+               style="background-color: #fdfdfd; border: 1px solid #e6e6e6; margin-bottom: 20px;">
+            <el-row>
+              <el-col :span="22">
+                <el-form :model="item" label-width="70px">
+                  <el-form-item label="内容类别" style="margin: 2%">
+                    <el-radio-group v-model="item.contentType">
+                      <el-radio :label="item.dictValue" v-for="item in sysQwSopAiContentType">{{ item.dictLabel }}
+                      </el-radio>
+                    </el-radio-group>
+                  </el-form-item>
+                  <el-form-item label="内容" style="margin-bottom: 2%">
+                    <el-input v-if="item.contentType == 1 " v-model="item.value" type="textarea" :rows="3"
+                              placeholder="内容" style="width: 90%;margin-top: 10px;"/>
+
+                    <ImageUpload v-if="item.contentType == 2 " v-model="item.imgUrl" type="image" :num="1" :width="150"
+                                 :height="150"/>
+
+                    <div v-if="item.contentType == 3 ">
+                      <el-card class="box-card">
+                        <el-form-item label="链接标题:" label-width="100px">
+                          <el-input v-model="item.linkTitle" placeholder="请输入链接标题" style="width: 90%;"/>
+                        </el-form-item>
+                        <el-form-item label="链接描述:" label-width="100px">
+                          <el-input type="textarea" :rows="3" v-model="item.linkDescribe" placeholder="请输入链接描述"
+                                    style="width: 90%;margin-top: 1%;"/>
+                        </el-form-item>
+                        <el-form-item label="链接封面:" label-width="100px">
+                          <ImageUpload v-model="item.linkImageUrl" type="image" :num="1" :file-size="2" :width="150"
+                                       :height="150" style="margin-top: 1%;"/>
+                        </el-form-item>
+                        <el-form-item label="链接地址:" label-width="100px">
+                          <el-input v-model="item.linkUrl" placeholder="请输入链接地址" style="width: 90%;"/>
+                        </el-form-item>
+                      </el-card>
+                    </div>
+                    <div v-if="item.contentType == 4">
+
+                    </div>
+                    <div v-if="item.contentType == 5 ">
+
+                      <el-form-item label="上传文件:" prop="fileUrl" label-width="100px">
+                        <el-upload
+                          v-model="item.fileUrl"
+                          class="avatar-uploader"
+                          :action="uploadUrl"
+                          :show-file-list="false"
+                          :on-success="(res, file) => handleAvatarSuccessFile(res, file, item)"
+                          :before-upload="beforeAvatarUploadFile">
+                          <i class="el-icon-plus avatar-uploader-icon"></i>
+                        </el-upload>
+                        <el-link v-if="item.fileUrl" type="primary" :href="downloadUrl(item.fileUrl)" download>
+                          {{ item.fileUrl }}
+                        </el-link>
+                      </el-form-item>
+
+                    </div>
+
+                    <div v-if="item.contentType == 6 ">
+                      <el-form-item label="上传视频:" prop="videoUrl" label-width="100px">
+                        <el-upload
+                          v-model="item.videoUrl"
+                          class="avatar-uploader"
+                          :action="uploadUrl"
+                          :show-file-list="false"
+                          :on-success="(res, file) => handleAvatarSuccessVideo(res, file, item)"
+                          :before-upload="beforeAvatarUploadVideo">
+                          <i class="el-icon-plus avatar-uploader-icon"></i>
+                        </el-upload>
+                        <video v-if="item.videoUrl"
+                               :src="item.videoUrl"
+                               controls style="width: 200px;height: 100px">
+                        </video>
+                      </el-form-item>
+                    </div>
+                    <div v-if="item.contentType == 7 ">
+                      <el-input
+                        v-model="item.value"
+                        type="textarea" :rows="3" maxlength="66" show-word-limit
+                        placeholder="输入要转为语音的内容" style="width: 90%;margin-top: 10px;"
+                        @input="handleInputVideoText(item.value,item)"/>
+                    </div>
+                    <div v-if="item.contentType == 8">
+
+                    </div>
+
+                  </el-form-item>
+                </el-form>
+              </el-col>
+              <el-col :span="1" :offset="1">
+                <i class="el-icon-delete" @click="delSetList(index,1)" style="margin-top: 20px;"
+                   v-if="setting.length>1 && formType==1"></i>
+              </el-col>
+            </el-row>
+          </div>
+          <el-link type="primary" class="el-icon-plus" :underline="false" @click='addSetList(1)' v-if="formType==1">
+            添加内容
+          </el-link>
+        </el-form-item>
+        <el-form-item label="全选销售" prop="isAllCompanyUser">
+          <el-switch
+            v-model="form.isAllCompanyUser"
+            active-color="#13ce66"
+            inactive-color="#ff4949"
+            :active-value="1"
+            :inactive-value="2">
+          </el-switch>
+          <span v-if="form.isAllCompanyUser == '1'" style="margin-left: 10px;color: #13ce66">是</span>
+          <span v-else style="margin-left: 10px;color: #ff4949">否</span>
+        </el-form-item>
+        <el-form-item label="所属销售" prop="companyUserIds">
+          <el-select v-model="companyUserIds" remote multiple placeholder="请选择" filterable style="width: 100%;" v-loading="userLoading">
+            <el-option
+              v-for="dict in userList"
+              :key="dict.userId"
+              :label="dict.nickName"
+              :value="dict.userId.toString()">
+            </el-option>
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer" v-if="formType==1">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  listCourseFinishTemp,
+  getCourseFinishTemp,
+  addCourseFinishTemp,
+  updateCourseFinishTemp,
+  delCourseFinishTemp,
+  exportCourseFinishTemp
+} from "@/api/course/courseFinishTemp";
+import {getAllUserlist} from '@/api/company/companyUser'
+import {courseList, videoList} from '@/api/qw/sop'
+import ImageUpload from "@/views/qw/sop/ImageUpload.vue";
+import { getCompanyList } from "@/api/company/company";
+
+export default {
+  name: "CourseFinishTemp",
+  components: {ImageUpload},
+  data() {
+    return {
+      //上传语音的遮罩层
+      voiceLoading: false,
+      uploadUrl: process.env.VUE_APP_BASE_API + "/common/uploadOSS2",
+      uploadUrlByVoice: process.env.VUE_APP_BASE_API + "/common/uploadOSSByHOOKVoice",
+      companyUserIds: [],
+      userList: [],
+      // 状态字典
+      statusOptions: [],
+      allowSelect: [],
+      courseList: [],
+      videoList: [],
+      // 遮罩层
+      loading: true,
+      userLoading: false,
+      // 导出遮罩层
+      exportLoading: false,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      companys: [],
+      formType: 1,
+      // 总条数
+      total: 0,
+      // 完课模板表格数据
+      courseFinishTempList: [],
+      //插件版
+      sysQwSopAiContentType: [],
+
+      sysFsSopWatchStatus: [],
+
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        name: null,
+        status: null,
+        setting: null,
+        chatSetting: null,
+        companyId: null,
+        courseId: null,
+        videoId: null,
+        companyUserIds: null,
+        isDel: null
+      },
+      // 模板表格数据
+      setting: [],
+      chatSetting: [],
+      // 表单参数
+      form: {
+        setting: null,
+        chatSetting: null,
+        videoIdSet: null,
+        courseIdSet: null,
+      },
+      // 表单校验
+      rules: {}
+    };
+  },
+  created() {
+    this.getList();
+
+    getCompanyList().then(response => {
+      this.companys = response.data;
+    });
+    this.getDicts("sys_company_status").then(response => {
+      this.statusOptions = response.data;
+    });
+
+    //复用一下
+    this.getDicts("sys_qw_allow_select").then(response => {
+      this.allowSelect = response.data;
+    });
+
+    this.getDicts("sys_fs_sop_watch_status").then(response => {
+      this.sysFsSopWatchStatus = response.data;
+    });
+
+    this.getDicts("sys_qwSopAi_contentType").then(response => {
+      this.sysQwSopAiContentType = response.data;
+    });
+    courseList().then(response => {
+      this.courseList = response.list;
+    });
+  },
+  methods: {
+    courseChange() {
+
+      videoList(this.form.courseId).then(response => {
+        this.videoList = response.list;
+      });
+    },
+    /** 查询完课模板列表 */
+    getList() {
+      this.loading = true;
+      listCourseFinishTemp(this.queryParams).then(response => {
+        this.courseFinishTempList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    handleAvatarSuccessFile(res, file, item) {
+      if (res.code === 200) {
+        // 使用 $set 确保响应式更新
+        this.$set(item, 'fileUrl', res.url);
+      } else {
+        this.msgError(res.msg);
+      }
+    },
+
+    beforeAvatarUploadFile(file) {
+      const isLt1M = file.size / 1024 / 1024 < 10;
+      if (!isLt1M) {
+        this.$message.error('上传大小不能超过 10MB!');
+      }
+      return isLt1M;
+    },
+    //下载文件
+    downloadUrl(materialUrl) {
+      // 直接返回文件 URL
+      return materialUrl;
+    },
+    handleInputVideoText(value, content) {
+      // 允许的字符:中文、英文(大小写)、数字和指定标点符号(,。!?)
+      const regex = /^[\u4e00-\u9fa5,。!?,!?]+$/;
+
+      // 删除不符合条件的字符
+      const filteredValue = value.split('').filter(char => regex.test(char)).join('');
+
+      this.$set(content, 'value', filteredValue);
+
+    },
+    handleAvatarSuccessVideo(res, file, item) {
+      if (res.code == 200) {
+        // 使用 $set 确保响应式更新
+        this.$set(item, 'videoUrl', res.url);
+      } else {
+        this.msgError(res.msg);
+      }
+    },
+
+    beforeAvatarUploadVideo(file) {
+      const isLt30M = file.size / 1024 / 1024 < 10;
+      const isMP4 = file.type === 'video/mp4';
+
+      if (!isMP4) {
+        this.$message.error('仅支持上传 MP4 格式的视频文件!');
+        return false;
+      }
+
+      if (!isLt30M) {
+        this.$message.error('上传大小不能超过 10MB!');
+        return false;
+      }
+
+      return true;
+    },
+
+    handleAvatarSuccessVoice(res, file, item) {
+      if (res.code == 200) {
+
+        // 创建 Audio 对象加载音频
+        const audio = new Audio(res.mp3Url);
+        audio.addEventListener('loadedmetadata', () => {
+          // 获取音频时长
+          this.$set(item, 'voiceDuration', Math.ceil(audio.duration));
+        });
+        // 使用 $set 确保响应式更新
+        this.$set(item, 'voiceUrl', res.silkUrl);
+        this.$set(item, 'mp3Url', res.mp3Url);
+      } else {
+        this.msgError(res.msg);
+      }
+      this.voiceLoading = false;
+    },
+    delSetList(index, type) {
+      if (type == 0) {
+        this.setting.splice(index, 1)
+      } else {
+        this.chatSetting.splice(index, 1)
+      }
+    },
+    beforeAvatarUploadVoice(file) {
+      return new Promise((resolve, reject) => {
+        const isLt10M = file.size / 1024 / 1024 < 10; // 假设语音文件大小限制为10MB
+        const isVoiceType = ['audio/mp3', 'audio/mpeg', 'audio/wav', 'audio/x-wav'].includes(file.type);
+
+        if (!isVoiceType) {
+          this.$message.error('仅支持上传 MP3, WAV, X-WAV 格式的语音文件!');
+          return reject(false); // 不允许继续上传
+        }
+
+        if (!isLt10M) {
+          this.$message.error('上传大小不能超过 10MB!');
+          return reject(false); // 不允许继续上传
+        }
+
+        // 使用 FileReader 读取文件
+        const reader = new FileReader();
+        reader.onload = (event) => {
+          const audio = new Audio(event.target.result);
+          audio.addEventListener('loadedmetadata', () => {
+            // 获取时长并保存
+            if (Math.ceil(audio.duration) > 30) {
+              this.$message.error('音频时长不能超过30秒!');
+              this.voiceLoading = false;
+              return reject(false); // 不允许继续上传
+            }
+            resolve(true); // 允许上传
+          });
+        };
+
+        reader.onerror = () => {
+          this.$message.error('无法读取音频文件!请上传正确的音频文件');
+          reject(false); // 不允许继续上传
+        };
+        this.voiceLoading = true;
+        reader.readAsDataURL(file); // 开始读取文件
+      });
+    },
+
+    addSetList(type) {
+      const newSetting = {
+        contentType: '1',
+        value: '',
+      };
+      // 将新设置项添加到 content.setting 数组中
+      if (type == 0) {
+        this.setting.push(newSetting);
+      } else {
+        this.chatSetting.push(newSetting);
+      }
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        name: null,
+        type: 1,
+        status: 1,
+        setting: [],
+        chatSetting: [],
+        companyId: null,
+        createBy: null,
+        createTime: null,
+        courseId: null,
+        videoId: null,
+        companyUserIds: null,
+        updateTime: null,
+        isDel: null,
+        isAllCompanyUser: null,
+      };
+      this.companyUserIds = []
+      this.setting = []
+      this.chatSetting = []
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加完课模板";
+    },
+
+    /**
+     * 查看完课模板
+     */
+    handleSelectDetails(row) {
+
+      this.reset();
+      const id = row.id || this.ids
+      getCourseFinishTemp(id).then(response => {
+        this.form = JSON.parse(JSON.stringify(response.data));
+        this.initCompanyUserList();
+
+        this.setting = JSON.parse(this.form.setting)
+        this.chatSetting = JSON.parse(this.form.chatSetting)
+        if (response.data.companyUserIds != null) {
+          this.companyUserIds = response.data.companyUserIds.split(",");
+        }
+
+        videoList(this.form.courseId).then(response => {
+          this.videoList = response.list;
+        });
+
+        this.open = true;
+        this.title = "查看完课模板";
+        this.formType = 2;
+
+      });
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getCourseFinishTemp(id).then(response => {
+        this.form = response.data;
+        this.setting = JSON.parse(this.form.setting)
+        this.chatSetting = JSON.parse(this.form.chatSetting)
+        if (response.data.companyUserIds != null) {
+          this.companyUserIds = this.form.companyUserIds.split(",");
+        }
+        videoList(this.form.courseId).then(response => {
+
+          this.videoList = response.list;
+        });
+        this.open = true;
+        this.title = "修改完课模板";
+        this.initCompanyUserList();
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+
+          if (this.form.isAllCompanyUser == null) {
+            this.form.isAllCompanyUser = 2;
+          }
+          this.form.companyUserIds = this.companyUserIds.toString()
+
+          this.form.setting = JSON.stringify(this.setting)
+          this.form.chatSetting = JSON.stringify(this.chatSetting)
+
+          if (this.setting.length <= 0) {
+            return this.$message("请添加规则")
+          }
+          for (let i = 0; i < this.setting.length; i++) {
+            if (this.setting[i].contentType == 1 && (this.setting[i].value == null || this.setting[i].value == "")) {
+              return this.$message.error("内容不能为空")
+            }
+            if (this.setting[i].contentType == 2 && (this.setting[i].imgUrl == null || this.setting[i].imgUrl == "")) {
+              return this.$message.error("图片不能为空")
+            }
+            if (this.setting[i].contentType == 3 && (this.setting[i].linkTitle == null || this.setting[i].linkTitle == "")) {
+              return this.$message.error("链接标题不能为空")
+            }
+            if (this.setting[i].contentType == 3 && (this.setting[i].linkDescribe == null || this.setting[i].linkDescribe == "")) {
+              return this.$message.error("链接描述不能为空")
+            }
+            if (this.setting[i].contentType == 3 && (this.setting[i].linkImageUrl == null || this.setting[i].linkImageUrl == "")) {
+              return this.$message.error("链接图片不能为空")
+            }
+            if (this.setting[i].contentType == 3 && this.setting[i].type == 1 && (this.setting[i].linkUrl == null || this.setting[i].linkUrl == "")) {
+              return this.$message.error("链接地址不能为空")
+            }
+            if (this.setting[i].contentType == 5 && (this.setting[i].fileUrl == null || this.setting[i].fileUrl == "")) {
+              return this.$message.error("文件不能为空")
+            }
+            if (this.setting[i].contentType == 6 && (this.setting[i].videoUrl == null || this.setting[i].videoUrl == "")) {
+              return this.$message.error("视频不能为空")
+            }
+            if (this.setting[i].contentType == 7 && (this.setting[i].value == null || this.setting[i].value == "")) {
+              return this.$message.error("语音不能为空")
+            }
+          }
+
+          if (this.form.id != null) {
+            updateCourseFinishTemp(this.form).then(response => {
+              this.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+              this.setting = [];
+              this.chatSetting = [];
+            });
+          } else {
+            addCourseFinishTemp(this.form).then(response => {
+              this.msgSuccess("新增成功");
+              this.open = false;
+              this.setting = [];
+              this.chatSetting = [];
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$confirm('是否确认删除完课模板编号为"' + ids + '"的数据项?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(function () {
+        return delCourseFinishTemp(ids);
+      }).then(() => {
+        this.getList();
+        this.msgSuccess("删除成功");
+      }).catch(() => {
+      });
+    },
+    initCompanyUserList(){
+      this.form.companyUserIds = [];
+      this.userLoading = true;
+      getAllUserlist({companyId: this.form.companyId}).then(response => {
+        this.userLoading = false;
+        this.userList = response.data;
+      });
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm('是否确认导出所有完课模板数据项?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        this.exportLoading = true;
+        return exportCourseFinishTemp(queryParams);
+      }).then(response => {
+        this.download(response.msg);
+        this.exportLoading = false;
+      }).catch(() => {
+      });
+    }
+  }
+};
+</script>

+ 717 - 0
src/views/course/courseFinishTempParent/index.vue

@@ -0,0 +1,717 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="名称" prop="name">
+        <el-input
+          v-model="queryParams.name"
+          placeholder="请输入名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="课程" prop="courseId">
+        <el-select v-model="queryParams.courseId" clearable placeholder="请选择课程" style=" margin-right: 10px;" size="mini">
+          <el-option
+            v-for="dict in courseList"
+            :key="dict.dictValue"
+            :label="dict.dictLabel"
+            :value="parseInt(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:courseFinishTempParent: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:courseFinishTempParent: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:courseFinishTempParent: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:courseFinishTempParent:export']"
+        >导出</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table border v-loading="loading" :data="courseFinishTempParentList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="名称" align="center" prop="name" />
+      <el-table-column label="课程" align="center" prop="courseId">
+        <template slot-scope="scope">
+          <el-tag v-for="dict in courseList" v-if="dict.dictValue == scope.row.courseId">{{dict.dictLabel}}</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:courseFinishTempParent:edit']"
+          >修改</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            @click="jump(scope.row.id)"
+          >模板列表</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['course:courseFinishTempParent: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="80px">
+        <el-form-item label="名称" prop="name">
+          <el-input v-model="form.name" placeholder="请输入名称" />
+        </el-form-item>
+        <el-form-item label="状态" v-if="!form.id">
+          <el-radio-group v-model="form.status">
+            <el-radio
+              v-for="dict in statusOptions"
+              :key="dict.dictValue"
+              :label="parseInt(dict.dictValue)"
+            >{{ dict.dictLabel }}
+            </el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="销售公司" prop="companyId">
+          <el-select filterable v-model="form.companyId" placeholder="请选择公司名" size="small" @change="loadUser">
+            <el-option
+              v-for="item in companyList"
+              :key="item.companyId"
+              :label="item.companyName"
+              :value="item.companyId"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="课程ID" prop="courseId">
+          <el-select v-model="form.courseId" :disabled="form.id != null" placeholder="请选择课程" style=" margin-right: 10px;" size="mini">
+            <el-option
+              v-for="dict in courseList"
+              :key="dict.dictValue"
+              :label="dict.dictLabel"
+              :value="parseInt(dict.dictValue)"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="规则" prop="setting" v-if="!form.id">
+          <div v-for="(item, index) in setting" :key="index"
+               style="background-color: #fdfdfd; border: 1px solid #e6e6e6; margin-bottom: 20px;">
+            <el-row>
+              <el-col :span="22">
+                <el-form :model="item" label-width="70px">
+                  <el-form-item label="内容类别" style="margin: 2%">
+                    <el-radio-group v-model="item.contentType">
+                      <el-radio :label="item.dictValue" v-for="item in sysQwSopAiContentType">{{ item.dictLabel }}
+                      </el-radio>
+                    </el-radio-group>
+                  </el-form-item>
+                  <el-form-item label="内容" style="margin-bottom: 2%">
+                    <el-input v-if="item.contentType == 1 " v-model="item.value" type="textarea" :rows="3"
+                              placeholder="内容" style="width: 90%;margin-top: 10px;"/>
+
+                    <ImageUpload v-if="item.contentType == 2 " v-model="item.imgUrl" type="image" :num="1" :width="150"
+                                 :height="150"/>
+
+                    <div v-if="item.contentType == 3 ">
+                      <el-card class="box-card">
+                        <el-form-item label="链接标题:" label-width="100px">
+                          <el-input v-model="item.linkTitle" placeholder="请输入链接标题" style="width: 90%;"/>
+                        </el-form-item>
+                        <el-form-item label="链接描述:" label-width="100px">
+                          <el-input type="textarea" :rows="3" v-model="item.linkDescribe" placeholder="请输入链接描述"
+                                    style="width: 90%;margin-top: 1%;"/>
+                        </el-form-item>
+                        <el-form-item label="链接封面:" label-width="100px">
+                          <ImageUpload v-model="item.linkImageUrl" type="image" :num="1" :file-size="2" :width="150"
+                                       :height="150" style="margin-top: 1%;"/>
+                        </el-form-item>
+                        <el-form-item label="链接地址:" label-width="100px">
+                          <el-input v-model="item.linkUrl" placeholder="请输入链接地址" style="width: 90%;"/>
+                        </el-form-item>
+                      </el-card>
+                    </div>
+                    <div v-if="item.contentType == 4">
+
+                    </div>
+                    <div v-if="item.contentType == 5 ">
+
+                      <el-form-item label="上传文件:" prop="fileUrl" label-width="100px">
+                        <el-upload
+                          v-model="item.fileUrl"
+                          class="avatar-uploader"
+                          :action="uploadUrl"
+                          :show-file-list="false"
+                          :on-success="(res, file) => handleAvatarSuccessFile(res, file, item)"
+                          :before-upload="beforeAvatarUploadFile">
+                          <i class="el-icon-plus avatar-uploader-icon"></i>
+                        </el-upload>
+                        <el-link v-if="item.fileUrl" type="primary" :href="downloadUrl(item.fileUrl)" download>
+                          {{ item.fileUrl }}
+                        </el-link>
+                      </el-form-item>
+
+                    </div>
+
+                    <div v-if="item.contentType == 6 ">
+                      <el-form-item label="上传视频:" prop="videoUrl" label-width="100px">
+                        <el-upload
+                          v-model="item.videoUrl"
+                          class="avatar-uploader"
+                          :action="uploadUrl"
+                          :show-file-list="false"
+                          :on-success="(res, file) => handleAvatarSuccessVideo(res, file, item)"
+                          :before-upload="beforeAvatarUploadVideo">
+                          <i class="el-icon-plus avatar-uploader-icon"></i>
+                        </el-upload>
+                        <video v-if="item.videoUrl"
+                               :src="item.videoUrl"
+                               controls style="width: 200px;height: 100px">
+                        </video>
+                      </el-form-item>
+                    </div>
+                    <div v-if="item.contentType == 7 ">
+                      <el-input
+                        v-model="item.value"
+                        type="textarea" :rows="3" maxlength="66" show-word-limit
+                        placeholder="输入要转为语音的内容" style="width: 90%;margin-top: 10px;"
+                        @input="handleInputVideoText(item.value,item)"/>
+                    </div>
+                    <div v-if="item.contentType == 8">
+
+                    </div>
+
+                  </el-form-item>
+                </el-form>
+              </el-col>
+              <el-col :span="1" :offset="1">
+                <i class="el-icon-delete" @click="delSetList(index, 0)" style="margin-top: 20px;"
+                   v-if="setting.length>1"></i>
+              </el-col>
+            </el-row>
+          </div>
+          <el-link type="primary" class="el-icon-plus" :underline="false" @click='addSetList(0)'>
+            添加内容
+          </el-link>
+        </el-form-item>
+        <el-form-item label="群聊恭喜规则" prop="setting" v-if="!form.id">
+          <div v-for="(item, index) in chatSetting" :key="index"
+               style="background-color: #fdfdfd; border: 1px solid #e6e6e6; margin-bottom: 20px;">
+            <el-row>
+              <el-col :span="22">
+                <el-form :model="item" label-width="70px">
+                  <el-form-item label="内容类别" style="margin: 2%">
+                    <el-radio-group v-model="item.contentType">
+                      <el-radio :label="item.dictValue" v-for="item in sysQwSopAiContentType">{{ item.dictLabel }}
+                      </el-radio>
+                    </el-radio-group>
+                  </el-form-item>
+                  <el-form-item label="内容" style="margin-bottom: 2%">
+                    <el-input v-if="item.contentType == 1 " v-model="item.value" type="textarea" :rows="3"
+                              placeholder="内容" style="width: 90%;margin-top: 10px;"/>
+
+                    <ImageUpload v-if="item.contentType == 2 " v-model="item.imgUrl" type="image" :num="1" :width="150"
+                                 :height="150"/>
+
+                    <div v-if="item.contentType == 3 ">
+                      <el-card class="box-card">
+                        <el-form-item label="链接标题:" label-width="100px">
+                          <el-input v-model="item.linkTitle" placeholder="请输入链接标题" style="width: 90%;"/>
+                        </el-form-item>
+                        <el-form-item label="链接描述:" label-width="100px">
+                          <el-input type="textarea" :rows="3" v-model="item.linkDescribe" placeholder="请输入链接描述"
+                                    style="width: 90%;margin-top: 1%;"/>
+                        </el-form-item>
+                        <el-form-item label="链接封面:" label-width="100px">
+                          <ImageUpload v-model="item.linkImageUrl" type="image" :num="1" :file-size="2" :width="150"
+                                       :height="150" style="margin-top: 1%;"/>
+                        </el-form-item>
+                        <el-form-item label="链接地址:" label-width="100px">
+                          <el-input v-model="item.linkUrl" placeholder="请输入链接地址" style="width: 90%;"/>
+                        </el-form-item>
+                      </el-card>
+                    </div>
+                    <div v-if="item.contentType == 4">
+
+                    </div>
+                    <div v-if="item.contentType == 5 ">
+
+                      <el-form-item label="上传文件:" prop="fileUrl" label-width="100px">
+                        <el-upload
+                          v-model="item.fileUrl"
+                          class="avatar-uploader"
+                          :action="uploadUrl"
+                          :show-file-list="false"
+                          :on-success="(res, file) => handleAvatarSuccessFile(res, file, item)"
+                          :before-upload="beforeAvatarUploadFile">
+                          <i class="el-icon-plus avatar-uploader-icon"></i>
+                        </el-upload>
+                        <el-link v-if="item.fileUrl" type="primary" :href="downloadUrl(item.fileUrl)" download>
+                          {{ item.fileUrl }}
+                        </el-link>
+                      </el-form-item>
+
+                    </div>
+
+                    <div v-if="item.contentType == 6 ">
+                      <el-form-item label="上传视频:" prop="videoUrl" label-width="100px">
+                        <el-upload
+                          v-model="item.videoUrl"
+                          class="avatar-uploader"
+                          :action="uploadUrl"
+                          :show-file-list="false"
+                          :on-success="(res, file) => handleAvatarSuccessVideo(res, file, item)"
+                          :before-upload="beforeAvatarUploadVideo">
+                          <i class="el-icon-plus avatar-uploader-icon"></i>
+                        </el-upload>
+                        <video v-if="item.videoUrl"
+                               :src="item.videoUrl"
+                               controls style="width: 200px;height: 100px">
+                        </video>
+                      </el-form-item>
+                    </div>
+                    <div v-if="item.contentType == 7 ">
+                      <el-input
+                        v-model="item.value"
+                        type="textarea" :rows="3" maxlength="66" show-word-limit
+                        placeholder="输入要转为语音的内容" style="width: 90%;margin-top: 10px;"
+                        @input="handleInputVideoText(item.value,item)"/>
+                    </div>
+                    <div v-if="item.contentType == 8">
+
+                    </div>
+
+                  </el-form-item>
+                </el-form>
+              </el-col>
+              <el-col :span="1" :offset="1">
+                <i class="el-icon-delete" @click="delSetList(index,1)" style="margin-top: 20px;"
+                   v-if="setting.length>1"></i>
+              </el-col>
+            </el-row>
+          </div>
+          <el-link type="primary" class="el-icon-plus" :underline="false" @click='addSetList(1)'>
+            添加内容
+          </el-link>
+        </el-form-item>
+        <el-form-item label="全选销售" prop="isAllCompanyUser" v-if="!form.id">
+          <el-switch
+            v-model="form.isAllCompanyUser"
+            active-color="#13ce66"
+            inactive-color="#ff4949"
+            :active-value="1"
+            :inactive-value="2">
+          </el-switch>
+          <span v-if="form.isAllCompanyUser == '1'" style="margin-left: 10px;color: #13ce66">是</span>
+          <span v-else style="margin-left: 10px;color: #ff4949">否</span>
+        </el-form-item>
+        <el-form-item label="所属销售" prop="companyUserIds" v-if="!form.id">
+          <el-select v-model="companyUserIds" remote multiple placeholder="请选择" filterable style="width: 100%;">
+            <el-option
+              v-for="dict in userList"
+              :key="dict.userId"
+              :label="dict.nickName"
+              :value="dict.userId.toString()">
+            </el-option>
+          </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>
+  </div>
+</template>
+
+<script>
+import {getCompanyList} from "@/api/company/company";
+import { listCourseFinishTempParent, getCourseFinishTempParent, delCourseFinishTempParent, addCourseFinishTempParent, updateCourseFinishTempParent, exportCourseFinishTempParent } from "@/api/course/courseFinishTempParent";
+import {courseList} from '@/api/qw/sop'
+import ImageUpload from '@/views/qw/sop/ImageUpload.vue'
+import { getUserList } from '@/api/company/companyUser'
+
+
+export default {
+  name: "CourseFinishTempParent",
+  components: { ImageUpload },
+  data() {
+    return {
+      voiceLoading: false,
+      uploadUrl: process.env.VUE_APP_BASE_API + "/common/uploadOSS2",
+      uploadUrlByVoice: process.env.VUE_APP_BASE_API + "/common/uploadOSSByHOOKVoice",
+      // 遮罩层
+      loading: true,
+      // 导出遮罩层
+      exportLoading: false,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 完课模板表格数据
+      courseFinishTempParentList: [],
+      companyUserIds: [],
+      courseList: [],
+      userList: [],
+      // 状态字典
+      statusOptions: [],
+      allowSelect: [],
+      sysFsSopWatchStatus: [],
+      sysQwSopAiContentType: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 模板表格数据
+      setting: [],
+      companyList: [],
+      chatSetting: [],
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        name: null,
+        courseId: null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        name:[
+          { required: true, message: "名称不能为空", trigger: "blur" }
+        ],
+        courseId:[
+          { required: true, message: "课程不能为空", trigger: "blur" }
+        ],
+      }
+    };
+  },
+  created() {
+    this.getDicts("sys_company_status").then(response => {
+      this.statusOptions = response.data;
+    });//复用一下
+    this.getDicts("sys_qw_allow_select").then(response => {
+      this.allowSelect = response.data;
+    });
+
+    this.getDicts("sys_fs_sop_watch_status").then(response => {
+      this.sysFsSopWatchStatus = response.data;
+    });
+
+    this.getDicts("sys_qwSopAi_contentType").then(response => {
+      this.sysQwSopAiContentType = response.data;
+    });
+    courseList().then(response => {
+      this.courseList = response.list;
+    });
+    getCompanyList().then(response => {
+      this.companyList = response.data;
+    });
+    this.getList();
+  },
+  methods: {
+    /** 查询完课模板列表 */
+    getList() {
+      this.loading = true;
+      listCourseFinishTempParent(this.queryParams).then(response => {
+        this.courseFinishTempParentList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    loadUser(){
+      getUserList(this.form.companyId).then(response => {
+        this.userList = response.data;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        status: 1,
+        companyId: 1,
+        name: null,
+        setting: [],
+        chatSetting: [],
+        courseId: null,
+        createTime: null,
+        createBy: null,
+        updateBy: null,
+        updateTime: null,
+        companyUserIds: null,
+        remark: null
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length!==1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加完课模板";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id || this.ids
+      getCourseFinishTempParent(id).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改完课模板";
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            updateCourseFinishTempParent(this.form).then(response => {
+              this.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            if (this.form.isAllCompanyUser == null) {
+              this.form.isAllCompanyUser = 2;
+            }
+            this.form.companyUserIds = this.companyUserIds.toString()
+
+            this.form.setting = JSON.stringify(this.setting)
+            this.form.chatSetting = JSON.stringify(this.chatSetting)
+
+            if (this.setting.length <= 0) {
+              return this.$message("请添加规则")
+            }
+            for (let i = 0; i < this.setting.length; i++) {
+              if (this.setting[i].contentType == 1 && (this.setting[i].value == null || this.setting[i].value == "")) {
+                return this.$message.error("内容不能为空")
+              }
+              if (this.setting[i].contentType == 2 && (this.setting[i].imgUrl == null || this.setting[i].imgUrl == "")) {
+                return this.$message.error("图片不能为空")
+              }
+              if (this.setting[i].contentType == 3 && (this.setting[i].linkTitle == null || this.setting[i].linkTitle == "")) {
+                return this.$message.error("链接标题不能为空")
+              }
+              if (this.setting[i].contentType == 3 && (this.setting[i].linkDescribe == null || this.setting[i].linkDescribe == "")) {
+                return this.$message.error("链接描述不能为空")
+              }
+              if (this.setting[i].contentType == 3 && (this.setting[i].linkImageUrl == null || this.setting[i].linkImageUrl == "")) {
+                return this.$message.error("链接图片不能为空")
+              }
+              if (this.setting[i].contentType == 3 && this.setting[i].type == 1 && (this.setting[i].linkUrl == null || this.setting[i].linkUrl == "")) {
+                return this.$message.error("链接地址不能为空")
+              }
+              if (this.setting[i].contentType == 5 && (this.setting[i].fileUrl == null || this.setting[i].fileUrl == "")) {
+                return this.$message.error("文件不能为空")
+              }
+              if (this.setting[i].contentType == 6 && (this.setting[i].videoUrl == null || this.setting[i].videoUrl == "")) {
+                return this.$message.error("视频不能为空")
+              }
+              if (this.setting[i].contentType == 7 && (this.setting[i].value == null || this.setting[i].value == "")) {
+                return this.$message.error("语音不能为空")
+              }
+            }
+            addCourseFinishTempParent(this.form).then(response => {
+              this.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$confirm('是否确认删除完课模板编号为"' + ids + '"的数据项?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(function() {
+        return delCourseFinishTempParent(ids);
+      }).then(() => {
+        this.getList();
+        this.msgSuccess("删除成功");
+      }).catch(() => {});
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm('是否确认导出所有完课模板数据项?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        this.exportLoading = true;
+        return exportCourseFinishTempParent(queryParams);
+      }).then(response => {
+        this.download(response.msg);
+        this.exportLoading = false;
+      }).catch(() => {});
+    },
+
+
+    handleAvatarSuccessFile(res, file, item) {
+      if (res.code === 200) {
+        // 使用 $set 确保响应式更新
+        this.$set(item, 'fileUrl', res.url);
+      } else {
+        this.msgError(res.msg);
+      }
+    },
+
+    beforeAvatarUploadFile(file) {
+      const isLt1M = file.size / 1024 / 1024 < 10;
+      if (!isLt1M) {
+        this.$message.error('上传大小不能超过 10MB!');
+      }
+      return isLt1M;
+    },
+    //下载文件
+    downloadUrl(materialUrl) {
+      // 直接返回文件 URL
+      return materialUrl;
+    },
+    handleInputVideoText(value, content) {
+      // 允许的字符:中文、英文(大小写)、数字和指定标点符号(,。!?)
+      const regex = /^[\u4e00-\u9fa5,。!?,!?]+$/;
+
+      // 删除不符合条件的字符
+      const filteredValue = value.split('').filter(char => regex.test(char)).join('');
+
+      this.$set(content, 'value', filteredValue);
+
+    },
+    handleAvatarSuccessVideo(res, file, item) {
+      if (res.code == 200) {
+        // 使用 $set 确保响应式更新
+        this.$set(item, 'videoUrl', res.url);
+      } else {
+        this.msgError(res.msg);
+      }
+    },
+
+    beforeAvatarUploadVideo(file) {
+      const isLt30M = file.size / 1024 / 1024 < 10;
+      const isMP4 = file.type === 'video/mp4';
+
+      if (!isMP4) {
+        this.$message.error('仅支持上传 MP4 格式的视频文件!');
+        return false;
+      }
+
+      if (!isLt30M) {
+        this.$message.error('上传大小不能超过 10MB!');
+        return false;
+      }
+
+      return true;
+    },
+
+    delSetList(index, type) {
+      if (type == 0) {
+        this.setting.splice(index, 1)
+      } else {
+        this.chatSetting.splice(index, 1)
+      }
+    },
+    addSetList(type) {
+      const newSetting = {
+        contentType: '1',
+        value: '',
+      };
+      // 将新设置项添加到 content.setting 数组中
+      if (type == 0) {
+        this.setting.push(newSetting);
+      } else {
+        this.chatSetting.push(newSetting);
+      }
+    },
+    jump(id){
+      this.$router.push('/course/courseFinishTemp/' + id)
+    },
+  },
+};
+</script>

+ 3 - 3
src/views/course/courseQuestionBank/QuestionBank.vue

@@ -44,8 +44,8 @@
         <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
       </el-form-item>
     </el-form>
-    <el-table border v-loading="loading" ref="table"   :data="courseQuestionBankList" @selection-change="handleSelectionChange">
-      <el-table-column type="selection" width="55" align="center"/>
+    <el-table border v-loading="loading" ref="table"   :data="courseQuestionBankList" >
+<!--      <el-table-column type="selection" width="55" align="center"/>-->
       <el-table-column label="标题" align="center" prop="title" >
         <template slot-scope="scope">
           <el-tooltip class="item" effect="dark" :content="scope.row.title" placement="top">
@@ -270,7 +270,7 @@ export default {
 	this.getDicts("sys_course_question_type").then(response => {
 	  this.questionTypeOptions = response.data;
 	});
-	
+
   },
   methods: {
     getOptionLabel(index) {

+ 243 - 425
src/views/course/userCourse/index.vue

@@ -2,23 +2,24 @@
   <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-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"
-            />
+            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"
-            />
+            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">
@@ -30,14 +31,14 @@
           @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"
-              :key="dict.dictValue"
-              :label="dict.dictLabel"
-              :value="dict.dictValue"
-            />
+            v-for="dict in courseTypeOptions"
+            :key="dict.dictValue"
+            :label="dict.dictLabel"
+            :value="dict.dictValue"
+          />
         </el-select>
       </el-form-item>
       <el-form-item>
@@ -55,7 +56,8 @@
           size="mini"
           @click="handleAdd"
           v-hasPermi="['course:userCourse:add']"
-        >新增</el-button>
+        >新增
+        </el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button
@@ -66,7 +68,8 @@
           :disabled="single"
           @click="handleUpdate"
           v-hasPermi="['course:userCourse:edit']"
-        >修改</el-button>
+        >修改
+        </el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button
@@ -77,7 +80,8 @@
           :disabled="multiple"
           @click="handleDelete"
           v-hasPermi="['course:userCourse:remove']"
-        >删除</el-button>
+        >删除
+        </el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button
@@ -88,42 +92,16 @@
           :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-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 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
@@ -131,45 +109,23 @@
             title=""
             trigger="hover"
           >
-            <img slot="reference" :src="scope.row.imgUrl" width="100" >
+            <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" 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" 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 ? '下架' : '上架' }}
+            v-hasPermi="['course:userCourse:cateMange']"
+          >目录管理
           </el-button>
           <el-button
             size="mini"
@@ -177,14 +133,16 @@
             icon="el-icon-edit"
             @click="handleUpdate(scope.row)"
             v-hasPermi="['course:userCourse:edit']"
-          >修改</el-button>
+          >修改
+          </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>
         </template>
       </el-table-column>
     </el-table>
@@ -200,85 +158,30 @@
     <!-- 添加或修改课程对话框 -->
     <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-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-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-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 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="project">
-              <el-select v-model="form.project" placeholder="请选择项目" filterable clearable size="small">
-                <el-option
-                  v-for="dict in projectOptions"
+                  v-for="dict in categoryOptions"
                   :key="dict.dictValue"
                   :label="dict.dictLabel"
                   :value="dict.dictValue"
@@ -286,11 +189,11 @@
               </el-select>
             </el-form-item>
           </el-col>
-          <el-col :span="12">
-            <el-form-item label="标签" prop="tags">
-              <el-select v-model="tags" multiple placeholder="请选择标签" filterable clearable size="small">
+          <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 tagsOptions"
+                  v-for="dict in subCategoryOptions"
                   :key="dict.dictValue"
                   :label="dict.dictLabel"
                   :value="dict.dictValue"
@@ -300,129 +203,25 @@
           </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-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="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-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>
@@ -430,53 +229,67 @@
       </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>
+      :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 {
+  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 {listBySearch} from "@/api/course/userTalent";
 import userCourseCatalogDetails from '../../components/course/userCourseCatalogDetails.vue';
-import { getAllCourseCategoryList,getCatePidList ,getCateListByPid} from "@/api/course/userCourseCategory";
+import {getAllCourseCategoryList, getCatePidList, getCateListByPid} from "@/api/course/userCourseCategory";
 import {allList} from "@/api/company/company";
+
 export default {
   name: "UserCourse",
   components: {
     Treeselect,
-    Editor,ImageUpload,userCourseCatalogDetails
+    Editor, ImageUpload, userCourseCatalogDetails
   },
   data() {
     return {
-      talentParam:{
-        phone:null,
-        talentId:null
+      talentParam: {
+        phone: null,
+        talentId: null
       },
-      talentList:[],
-      show:{
-        title:"目录管理",
-        open:false
+      talentList: [],
+      startTimeRange: [],
+      show: {
+        title: "目录管理",
+        open: false
       },
-      activeName:"1",
-      projectOptions:[],
-      tagsOptions:[],
-      tags:[],
-	  companyIds:[],
-      courseTypeOptions:[],
+      activeName: "1",
+      projectOptions: [],
+      tagsOptions: [],
+      tags: [],
+      companyIds: [],
+      courseTypeOptions: [],
       orOptions: [],
       specShowOptions: [],
       specTypeOptions: [],
-      categoryOptions:[],
-      subCategoryOptions:[],
-      querySubCateOptions:[],
+      categoryOptions: [],
+      subCategoryOptions: [],
+      querySubCateOptions: [],
       // 遮罩层
       loading: true,
       // 导出遮罩层
@@ -493,7 +306,7 @@ export default {
       total: 0,
       // 课程表格数据
       userCourseList: [],
-	  companyOptions:[],
+      companyOptions: [],
       // 弹出层标题
       title: "",
       // 是否显示弹出层
@@ -503,7 +316,7 @@ export default {
         pageNum: 1,
         pageSize: 10,
         cateId: null,
-        subCateId:null,
+        subCateId: null,
         title: null,
         imgUrl: null,
         userId: null,
@@ -517,56 +330,57 @@ export default {
         description: null,
         hotRanking: null,
         integral: null,
-        price: null
+        price: null,
+        isPrivate: 1
       },
       // 表单参数
       form: {},
       // 表单校验
       rules: {
         courseName: [
-          { required: true, message: "课堂名称不能为空", trigger: "blur" }
+          {required: true, message: "课堂名称不能为空", trigger: "blur"}
         ],
         imgUrl: [
-          { required: true, message: "封面图片不能为空", trigger: "blur" }
+          {required: true, message: "封面图片不能为空", trigger: "blur"}
         ],
         isTui: [
-          { required: true, message: "是否推荐不能为空", trigger: "blur" }
+          {required: true, message: "是否推荐不能为空", trigger: "blur"}
         ],
         isBest: [
-          { required: true, message: "是否精选不能为空", trigger: "blur" }
+          {required: true, message: "是否精选不能为空", trigger: "blur"}
         ],
         isFast: [
-          { required: true, message: "是否允许快进不能为空", trigger: "blur" }
+          {required: true, message: "是否允许快进不能为空", trigger: "blur"}
         ],
         isAutoPlay: [
-          { required: true, message: "是否自动播放不能为空", trigger: "blur" }
+          {required: true, message: "是否自动播放不能为空", trigger: "blur"}
         ],
         sort: [
-          { required: true, message: "排序不能为空", trigger: "blur" }
+          {required: true, message: "排序不能为空", trigger: "blur"}
         ],
         views: [
-          { required: true, message: "播放量不能为空", trigger: "blur" }
+          {required: true, message: "播放量不能为空", trigger: "blur"}
         ],
         likes: [
-          { required: true, message: "点赞数不能为空", trigger: "blur" }
+          {required: true, message: "点赞数不能为空", trigger: "blur"}
         ],
         favoriteNum: [
-          { required: true, message: "收藏数不能为空", trigger: "blur" }
+          {required: true, message: "收藏数不能为空", trigger: "blur"}
         ],
         shares: [
-          { required: true, message: "分享数不能为空", trigger: "blur" }
+          {required: true, message: "分享数不能为空", trigger: "blur"}
         ],
         isIntegral: [
-          { required: true, message: "是否允许积分兑换不能为空", trigger: "blur" }
+          {required: true, message: "是否允许积分兑换不能为空", trigger: "blur"}
         ],
         isShow: [
-          { required: true, message: "上架状态不能为空", trigger: "blur" }
+          {required: true, message: "上架状态不能为空", trigger: "blur"}
         ],
         isPrivate: [
-          { required: true, message: "公私域不能为空", trigger: "blur" }
+          {required: true, message: "公私域不能为空", trigger: "blur"}
         ],
         integral: [
-          { required: true, message: "小节兑换积分不能为空", trigger: "blur" }
+          {required: true, message: "小节兑换积分不能为空", trigger: "blur"}
         ],
       }
     };
@@ -574,9 +388,13 @@ export default {
   created() {
     this.getList();
     getCatePidList().then(response => {
-        this.categoryOptions = response.data;
+      this.categoryOptions = response.data;
     });
 
+
+    getSelectableRange().then(e => {
+      this.startTimeRange = e.data;
+    })
     // this.getTreeselect();
     this.getDicts("sys_spec_show").then(response => {
       this.specShowOptions = response.data;
@@ -596,15 +414,15 @@ export default {
     this.getDicts("sys_company_or").then(response => {
       this.orOptions = response.data;
     });
-	allList().then(response => {
-	    this.companyOptions = response.rows;
-	});
+    allList().then(response => {
+      this.companyOptions = response.rows;
+    });
   },
   methods: {
-    selectTalent(){
+    selectTalent() {
 
     },
-    talentMethod(query){
+    talentMethod(query) {
       if (query !== '') {
         this.talentParam.phone = query;
         listBySearch(this.talentParam).then(response => {
@@ -612,45 +430,41 @@ export default {
         });
       }
     },
-    getSubCateList(pid){
-      this.form.subCateId=null;
-      if(pid == ''){
-        this.subCategoryOptions=[];
+    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=[];
+    getQuerySubCateList(pid) {
+      this.queryParams.subCateId = null;
+      if (pid == '') {
+        this.querySubCateOptions = [];
         return
       }
-      this.queryParams.subCateId=null;
+      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 };
+      var course = {courseId: row.courseId, isShow: isShowValue};
       updateIsShow(course).then(response => {
         this.msgSuccess("修改成功");
         this.getList();
       });
     },
-    handleCatalog(row){
+    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();
+      this.show.open = true;
+      setTimeout(() => {
+        this.$refs.userCourseCatalogDetails.getDetails(courseId, row.courseName, row.isPrivate);
+      }, 200);
     },
     /** 转换课堂分类数据结构 */
     normalizer(node) {
@@ -667,7 +481,7 @@ export default {
       getAllCourseCategoryList().then(response => {
         this.categoryOptions = [];
         const data = this.handleTree(response.data, "cateId", "pid");
-        this.categoryOptions=data;
+        this.categoryOptions = data;
       });
     },
     /** 查询课程列表 */
@@ -689,10 +503,10 @@ export default {
       this.form = {
         courseId: null,
         cateId: null,
-        subCateId:null,
+        subCateId: null,
         title: null,
         imgUrl: null,
-        // secondImg:null,
+        secondImg: null,
         userId: null,
         sort: null,
         createTime: null,
@@ -700,26 +514,27 @@ export default {
         status: 0,
         isVip: null,
         isAutoPlay: "1",
-        isIntegral:"0",
+        isIntegral: "0",
         isShow: "1",
-        isFast:"1",
-        isTui:"1",
-        isBest:"1",
-        isNext:"1",
-        isPrivate:"0",
+        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
+        likes: 100000,
+        shares: 100000,
+        favoriteNum: 100000,
+        hotNum: 100000,
       };
-      this.tags=[];
-      this.subCategoryOptions=[]
+      this.tags = [];
+      this.subCategoryOptions = []
+      this.companyIds = []
       this.resetForm("form");
     },
     /** 搜索按钮操作 */
@@ -730,38 +545,40 @@ export default {
     /** 重置按钮操作 */
     resetQuery() {
       this.resetForm("queryForm");
-      this.queryParams.isShow=this.activeName
+      this.queryParams.isShow = this.activeName
       this.handleQuery();
     },
     // 多选框选中数据
     handleSelectionChange(selection) {
       this.ids = selection.map(item => item.courseId)
-      this.single = selection.length!==1
+      this.single = selection.length !== 1
       this.multiple = !selection.length
     },
     /** 新增按钮操作 */
     handleAdd() {
       this.reset();
-      this.talentList=[];
+      this.talentList = [];
       this.open = true;
       this.title = "添加课程";
     },
     /** 修改按钮操作 */
     handleUpdate(row) {
       this.reset();
-      this.talentList=[];
+      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;
-        });
+        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){
+        if (response.data.project != null) {
           this.form.project = response.data.project.toString();
         }
-        if(response.data.tags!=null){
+        if (response.data.tags != null) {
           this.tags = response.data.tags.split(",")
         }
         this.form.isAutoPlay = response.data.isAutoPlay.toString();
@@ -773,11 +590,11 @@ export default {
         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=[]
-		}
+        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;
@@ -790,13 +607,10 @@ 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.companyIds = this.companyIds.toString()
+          // 私域课程
+          this.form.isPrivate = 1
           if (this.form.courseId != null) {
             updateUserCourse(this.form).then(response => {
               this.msgSuccess("修改成功");
@@ -817,62 +631,66 @@ export default {
     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(() => {});
+        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(() => {});
+        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("未选择课程");
+      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() {});
+        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("未选择课程");
+      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() {});
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(function () {
+        return pullOff(courseIds);
+      }).then(() => {
+        this.getList();
+        this.msgSuccess("下架成功");
+      }).catch(function () {
+      });
     }
   }
 };

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

@@ -0,0 +1,905 @@
+<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:publicAdd']"
+        >新增
+        </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:publicEdit']"
+        >修改
+        </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:publicRemove']"
+        >删除
+        </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:publicExport']"
+        >导出
+        </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:publicPutOn']"
+        >上架
+        </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:publicPutOff']"
+        >下架
+        </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)"
+            v-hasPermi="['course:userCourse:publicCateManage']"
+          >目录管理
+          </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:publicUpdateIsShow']"
+          >
+            {{ scope.row.isShow === 1 ? '下架' : '上架' }}
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['course:userCourse:publicEdit']"
+          >修改
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['course:userCourse:publicRemove']"
+          >删除
+          </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="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>
+      <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/userCoursePublic";
+
+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.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/course/userCoursePeriod/index.vue

@@ -1664,7 +1664,7 @@ export default {
 
 /* 添加训练营表单样式 */
 .drawer-footer {
-  position: absolute;
+  //position: absolute;
   bottom: 0;
   left: 0;
   right: 0;

+ 1 - 1
src/views/course/videoResource/index.vue

@@ -63,7 +63,7 @@
           size="mini"
           @click="handleBatchAdd"
           :disabled="hasMinimizableDialog"
-          v-hasPermi="['course:videoResource:add']"
+          v-hasPermi="['course:videoResource:batchAdd']"
         >批量新增</el-button>
       </el-col>
       <el-col :span="1.5">

+ 7 - 9
src/views/index.vue

@@ -90,15 +90,13 @@ export default {
     }
   },
   methods: {
-    getIndex() {
-      this.loading = true;
-      getIndex().then(response => {
-        this.data = response.data;
-
-      });
-    },
-  },
-  methods: {
+    // getIndex() {
+    //   this.loading = true;
+    //   getIndex().then(response => {
+    //     this.data = response.data;
+    //
+    //   });
+    // },
     getDocT(row){
       setTimeout(() => {
            this.$refs.getDoc.getDoc(row);

+ 1 - 1
src/views/login.vue

@@ -70,7 +70,7 @@ export default {
     return {
       codeUrl: "",
       vueAppTitle: process.env.VUE_APP_TITLE,
-      companyName: process.env.VUE_APP_VUE_APP_COMPANY_NAME,
+      companyName: process.env.VUE_APP_COMPANY_NAME,
       icpRecord: process.env.VUE_APP_ICP_RECORD,
       icpUrl: process.env.VUE_APP_ICP_URL,
       cookiePassword: "",

+ 1 - 1
src/views/qw/sopTemp/addAiChatTemp.vue

@@ -155,7 +155,7 @@
                              @click='addSetting()'>添加天数</el-link> -->
         </el-form-item>
       </el-form>
-      <div slot="footer" class="dialog-footer" style="float: right;">
+      <div slot="footer" class="dialog-footer" style="display: flex;justify-content: flex-end;">
         <el-button type="primary" @click="submitForm">确 定</el-button>
         <el-button @click="cancel">取 消</el-button>
       </div>

+ 1 - 1
src/views/qw/sopTemp/addSopTemp.vue

@@ -335,7 +335,7 @@
         </el-form-item>
 
       </el-form>
-      <div slot="footer" class="dialog-footer" style="float: right;">
+      <div slot="footer" class="dialog-footer" style="display: flex;justify-content: flex-end;">
         <el-button type="primary" @click="submitForm">确 定</el-button>
         <el-button @click="cancel">取 消</el-button>
       </div>

+ 1 - 1
src/views/qw/sopTemp/addSopTempOld.vue

@@ -268,7 +268,7 @@
         </el-form-item>
 
       </el-form>
-      <div slot="footer" class="dialog-footer" style="float: right;">
+      <div slot="footer" class="dialog-footer" style="display: flex;justify-content: flex-end;">
         <el-button type="primary" @click="submitForm">确 定</el-button>
         <el-button @click="cancel">取 消</el-button>
       </div>

+ 1 - 1
src/views/qw/sopTemp/addTemp.vue

@@ -26,7 +26,7 @@
           <el-input-number v-model="form.sort"  :min="0" label="排序"></el-input-number>
         </el-form-item>
       </el-form>
-      <div slot="footer" class="dialog-footer" style="float: right;">
+      <div slot="footer" class="dialog-footer" style="display: flex;justify-content: flex-end;">
         <el-button type="primary" @click="submitForm">确 定</el-button>
         <el-button @click="cancel">取 消</el-button>
       </div>

+ 2 - 2
src/views/qw/sopTemp/index.vue

@@ -272,7 +272,7 @@
           </el-time-picker>
         </el-form-item>
       </el-form>
-      <div slot="footer" class="dialog-footer" style="float: right;">
+      <div slot="footer" class="dialog-footer" style="display: flex;justify-content: flex-end;">
         <el-button type="primary" @click="submitForm">确 定</el-button>
         <el-button @click="cancel">取 消</el-button>
       </div>
@@ -288,7 +288,7 @@
           </template>
         </el-table-column>
       </el-table>
-      <div slot="footer" class="dialog-footer" style="float: right;">
+      <div slot="footer" class="dialog-footer" style="display: flex;justify-content: flex-end;">
         <el-button type="primary" @click="updateRedData" :disabled="redData.loading">保 存</el-button>
       </div>
     </el-dialog>

+ 1 - 1
src/views/qw/sopTemp/updateSopTempOld.vue

@@ -258,7 +258,7 @@
         </el-form-item>
 
       </el-form>
-      <div slot="footer" class="dialog-footer" style="float: right;">
+      <div slot="footer" class="dialog-footer" style="display: flex;justify-content: flex-end;">
         <el-button type="primary" @click="submitForm">确 定</el-button>
         <el-button @click="cancel">取 消</el-button>
       </div>

+ 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="['his:user:enabledUsers']"
+      >批量启用</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="['his: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/his/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>

+ 1 - 1
vue.config.js

@@ -5,7 +5,7 @@ function resolve(dir) {
   return path.join(__dirname, dir)
 }
 
-const name = process.env.VUE_APP_TITLE || '弘珍医药互联网医院管理系统' // 网页标题
+const name = process.env.VUE_APP_TITLE || '互联网医院管理系统' // 网页标题
 
 const port = process.env.port || process.env.npm_config_port || 80 // 端口