吴树波 1 месяц назад
Родитель
Сommit
806cc8c32e

+ 347 - 206
src/views/course/courseFinishTemp/index.vue

@@ -53,7 +53,8 @@
           size="mini"
           @click="handleAdd"
           v-hasPermi="['courseFinishTemp:course:add']"
-        >新增</el-button>
+        >新增
+        </el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button
@@ -64,7 +65,8 @@
           :disabled="single"
           @click="handleUpdate"
           v-hasPermi="['courseFinishTemp:course:edit']"
-        >修改</el-button>
+        >修改
+        </el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button
@@ -75,7 +77,8 @@
           :disabled="multiple"
           @click="handleDelete"
           v-hasPermi="['courseFinishTemp:course:remove']"
-        >删除</el-button>
+        >删除
+        </el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button
@@ -86,24 +89,25 @@
           :loading="exportLoading"
           @click="handleExport"
           v-hasPermi="['courseFinishTemp:course:export']"
-        >导出</el-button>
+        >导出
+        </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="name" />
+      <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="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="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"/>
@@ -117,21 +121,24 @@
             icon="el-icon-edit"
             @click="handleUpdate(scope.row)"
             v-hasPermi="['courseFinishTemp:course:edit']"
-          >修改</el-button>
+          >修改
+          </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>
           <el-button
             size="mini"
             type="text"
             icon="el-icon-delete"
             @click="handleDelete(scope.row)"
             v-hasPermi="['courseFinishTemp:course:remove']"
-          >删除</el-button>
+          >删除
+          </el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -148,7 +155,7 @@
     <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-input v-model="form.name" placeholder="请输入模板名称"/>
         </el-form-item>
         <el-form-item label="类型">
           <el-radio-group v-model="form.type">
@@ -162,11 +169,13 @@
               v-for="dict in statusOptions"
               :key="dict.dictValue"
               :label="parseInt(dict.dictValue)"
-            >{{dict.dictLabel}}</el-radio>
+            >{{ 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-select v-model="form.courseId" placeholder="请选择课程" style=" margin-right: 10px;" size="mini"
+                     @change="courseChange()">
             <el-option
               v-for="dict in courseList"
               :key="dict.dictValue"
@@ -174,7 +183,7 @@
               :value="parseInt(dict.dictValue)"
             />
           </el-select>
-          <el-select  v-model="form.videoId" placeholder="请选择小节" size="mini" style=" margin-right: 10px;" >
+          <el-select v-model="form.videoId" placeholder="请选择小节" size="mini" style=" margin-right: 10px;">
             <el-option
               v-for="dict in videoList"
               :key="dict.dictValue"
@@ -183,96 +192,205 @@
             />
           </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-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="内容" 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>
-                      <el-form-item label="链接描述:"   label-width="100px" >
-                        <el-input type="textarea" :rows="3" v-model="item.linkDescribe" placeholder="请输入链接描述" style="width: 90%;margin-top: 1%;"/>
+
+                    </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>
-                      <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%;" />
+                    </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>
-                      <el-form-item label="链接地址:"  label-width="100px" >
-                        <el-input v-model="item.linkUrl" placeholder="请输入链接地址" style="width: 90%;"/>
+
+                    </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>
-                    </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 ">
+                    </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)" style="margin-top: 20px;" v-if="setting.length>1 && formType==1"></i>
-            </el-col>
-          </el-row>
+                    </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()' v-if="formType==1" >添加内容</el-link>
+          <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
@@ -286,7 +404,7 @@
           <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%;">
+          <el-select v-model="companyUserIds" remote multiple placeholder="请选择" filterable style="width: 100%;">
             <el-option
               v-for="dict in userList"
               :key="dict.userId"
@@ -305,8 +423,15 @@
 </template>
 
 <script>
-import { listCourseFinishTemp, getCourseFinishTemp, addCourseFinishTemp, updateCourseFinishTemp, delCourseFinishTemp, exportCourseFinishTemp } from "@/api/course/courseFinishTemp";
-import { getUserList } from '@/api/company/companyUser'
+import {
+  listCourseFinishTemp,
+  getCourseFinishTemp,
+  addCourseFinishTemp,
+  updateCourseFinishTemp,
+  delCourseFinishTemp,
+  exportCourseFinishTemp
+} from "@/api/course/courseFinishTemp";
+import {getUserList} from '@/api/company/companyUser'
 import {courseList, videoList} from '@/api/qw/sop'
 import ImageUpload from "@/views/qw/sop/ImageUpload.vue";
 
@@ -316,16 +441,16 @@ export default {
   data() {
     return {
       //上传语音的遮罩层
-      voiceLoading :false,
-      uploadUrl:process.env.VUE_APP_BASE_API+"/common/uploadOSS2",
-      uploadUrlByVoice:process.env.VUE_APP_BASE_API+"/common/uploadOSSByHOOKVoice",
-      companyUserIds:[],
-      userList:[],
+      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:[],
+      courseList: [],
+      videoList: [],
       // 遮罩层
       loading: true,
       // 导出遮罩层
@@ -338,13 +463,13 @@ export default {
       multiple: true,
       // 显示搜索条件
       showSearch: true,
-      formType:1,
+      formType: 1,
       // 总条数
       total: 0,
       // 完课模板表格数据
       courseFinishTempList: [],
       //插件版
-      sysQwSopAiContentType:[],
+      sysQwSopAiContentType: [],
 
       sysFsSopWatchStatus: [],
 
@@ -359,6 +484,7 @@ export default {
         name: null,
         status: null,
         setting: null,
+        chatSetting: null,
         companyId: null,
         courseId: null,
         videoId: null,
@@ -367,22 +493,23 @@ export default {
       },
       // 模板表格数据
       setting: [],
+      chatSetting: [],
       // 表单参数
       form: {
-        setting:null,
-        videoIdSet:null,
-        courseIdSet:null,
+        setting: null,
+        chatSetting: null,
+        videoIdSet: null,
+        courseIdSet: null,
       },
       // 表单校验
-      rules: {
-      }
+      rules: {}
     };
   },
   created() {
     this.getList();
     getUserList().then(response => {
-      this.userList =  response.data;
-      console.log("this.userList",this.userList)
+      this.userList = response.data;
+      console.log("this.userList", this.userList)
     });
     this.getDicts("sys_company_status").then(response => {
       this.statusOptions = response.data;
@@ -408,7 +535,7 @@ export default {
     courseChange() {
 
       videoList(this.form.courseId).then(response => {
-        this.videoList=response.list;
+        this.videoList = response.list;
       });
     },
     /** 查询完课模板列表 */
@@ -434,7 +561,7 @@ export default {
       }
     },
 
-    beforeAvatarUploadFile(file){
+    beforeAvatarUploadFile(file) {
       const isLt1M = file.size / 1024 / 1024 < 10;
       if (!isLt1M) {
         this.$message.error('上传大小不能超过 10MB!');
@@ -446,7 +573,7 @@ export default {
       // 直接返回文件 URL
       return materialUrl;
     },
-    handleInputVideoText(value,content){
+    handleInputVideoText(value, content) {
       // 允许的字符:中文、英文(大小写)、数字和指定标点符号(,。!?)
       const regex = /^[\u4e00-\u9fa5,。!?,!?]+$/;
 
@@ -457,16 +584,15 @@ export default {
 
     },
     handleAvatarSuccessVideo(res, file, item) {
-      if(res.code==200){
+      if (res.code == 200) {
         // 使用 $set 确保响应式更新
         this.$set(item, 'videoUrl', res.url);
-      }
-      else{
+      } else {
         this.msgError(res.msg);
       }
     },
 
-    beforeAvatarUploadVideo(file){
+    beforeAvatarUploadVideo(file) {
       const isLt30M = file.size / 1024 / 1024 < 10;
       const isMP4 = file.type === 'video/mp4';
 
@@ -483,8 +609,8 @@ export default {
       return true;
     },
 
-    handleAvatarSuccessVoice(res, file, item){
-      if(res.code==200){
+    handleAvatarSuccessVoice(res, file, item) {
+      if (res.code == 200) {
 
         // 创建 Audio 对象加载音频
         const audio = new Audio(res.mp3Url);
@@ -495,11 +621,17 @@ export default {
         // 使用 $set 确保响应式更新
         this.$set(item, 'voiceUrl', res.silkUrl);
         this.$set(item, 'mp3Url', res.mp3Url);
-      }
-      else{
+      } else {
         this.msgError(res.msg);
       }
-      this.voiceLoading=false;
+      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) => {
@@ -524,7 +656,7 @@ export default {
             // 获取时长并保存
             if (Math.ceil(audio.duration) > 30) {
               this.$message.error('音频时长不能超过30秒!');
-              this.voiceLoading=false;
+              this.voiceLoading = false;
               return reject(false); // 不允许继续上传
             }
             resolve(true); // 允许上传
@@ -535,22 +667,22 @@ export default {
           this.$message.error('无法读取音频文件!请上传正确的音频文件');
           reject(false); // 不允许继续上传
         };
-        this.voiceLoading=true;
+        this.voiceLoading = true;
         reader.readAsDataURL(file); // 开始读取文件
       });
     },
-    delSetList(index){
-      this.setting.splice(index,1)
-    },
 
-    addSetList(){
-        const newSetting = {
-          contentType:'1',
-          value: '',
-        };
-        // 将新设置项添加到 content.setting 数组中
+    addSetList(type) {
+      const newSetting = {
+        contentType: '1',
+        value: '',
+      };
+      // 将新设置项添加到 content.setting 数组中
+      if (type == 0) {
         this.setting.push(newSetting);
-
+      } else {
+        this.chatSetting.push(newSetting);
+      }
     },
     // 表单重置
     reset() {
@@ -560,6 +692,7 @@ export default {
         type: 1,
         status: 1,
         setting: [],
+        chatSetting: [],
         companyId: null,
         createBy: null,
         createTime: null,
@@ -568,10 +701,11 @@ export default {
         companyUserIds: null,
         updateTime: null,
         isDel: null,
-        isAllCompanyUser:null,
+        isAllCompanyUser: null,
       };
-      this.companyUserIds=[]
-      this.setting=[]
+      this.companyUserIds = []
+      this.setting = []
+      this.chatSetting = []
       this.resetForm("form");
     },
     /** 搜索按钮操作 */
@@ -587,7 +721,7 @@ export default {
     // 多选框选中数据
     handleSelectionChange(selection) {
       this.ids = selection.map(item => item.id)
-      this.single = selection.length!==1
+      this.single = selection.length !== 1
       this.multiple = !selection.length
     },
     /** 新增按钮操作 */
@@ -598,28 +732,29 @@ export default {
     },
 
     /**
-    * 查看完课模板
-    */
-    handleSelectDetails(row){
+     * 查看完课模板
+     */
+    handleSelectDetails(row) {
 
       this.reset();
       const id = row.id || this.ids
       getCourseFinishTemp(id).then(response => {
-        console.log("this.form222 ",response.data )
+        console.log("this.form222 ", response.data)
         this.form = response.data;
 
-        this.setting=JSON.parse(this.form.setting)
-        if (response.data.companyUserIds!=null){
+        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.videoList = response.list;
         });
 
         this.open = true;
         this.title = "查看完课模板";
-        this.formType=2;
+        this.formType = 2;
 
       });
     },
@@ -628,16 +763,17 @@ export default {
       this.reset();
       const id = row.id || this.ids
       getCourseFinishTemp(id).then(response => {
-        console.log("this.response.data",response.data)
+        console.log("this.response.data", response.data)
         this.form = response.data;
 
-        this.setting=JSON.parse(this.form.setting)
-        if (response.data.companyUserIds!=null){
+        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.videoList = response.list;
         });
 
 
@@ -651,43 +787,44 @@ export default {
       this.$refs["form"].validate(valid => {
         if (valid) {
 
-          if (this.form.isAllCompanyUser==null){
-            this.form.isAllCompanyUser=2;
+          if (this.form.isAllCompanyUser == null) {
+            this.form.isAllCompanyUser = 2;
           }
           this.form.companyUserIds = this.companyUserIds.toString()
 
-          this.form.setting=JSON.stringify(this.setting)
+          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.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("语音不能为空")
             }
           }
 
@@ -696,13 +833,15 @@ export default {
               this.msgSuccess("修改成功");
               this.open = false;
               this.getList();
-              this.setting=[];
+              this.setting = [];
+              this.chatSetting = [];
             });
           } else {
             addCourseFinishTemp(this.form).then(response => {
               this.msgSuccess("新增成功");
               this.open = false;
-              this.setting=[];
+              this.setting = [];
+              this.chatSetting = [];
               this.getList();
             });
           }
@@ -713,30 +852,32 @@ export default {
     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(() => {});
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(function () {
+        return delCourseFinishTemp(ids);
+      }).then(() => {
+        this.getList();
+        this.msgSuccess("删除成功");
+      }).catch(() => {
+      });
     },
     /** 导出按钮操作 */
     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(() => {});
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        this.exportLoading = true;
+        return exportCourseFinishTemp(queryParams);
+      }).then(response => {
+        this.download(response.msg);
+        this.exportLoading = false;
+      }).catch(() => {
+      });
     }
   }
 };

Разница между файлами не показана из-за своего большого размера
+ 243 - 201
src/views/qw/sop/addSop.vue


+ 13 - 16
src/views/qw/sop/sop.vue

@@ -194,11 +194,10 @@
       <!--          </div>-->
       <!--        </template>-->
       <!--      </el-table-column>-->
-      <el-table-column label="类别" align="center" prop="type">
+      <el-table-column label="类别" align="center" prop="type" width="100">
         <template slot-scope="scope">
           <el-tag type="success" v-if="scope.row.type==1">个微</el-tag>
-          <el-tag type="primary" v-else-if="scope.row.type==2">企微</el-tag>
-          <el-tag type="primary" v-else-if="scope.row.type==3">企微群聊</el-tag>
+          <el-tag type="primary" v-else-if="scope.row.type==2">企微<span v-if="scope.row.filterMode == 2">(群聊)</span></el-tag>
         </template>
       </el-table-column>
       <el-table-column label="发送方式" align="center" prop="sendType">
@@ -220,7 +219,7 @@
       <el-table-column label="成员" align="center" prop="qwUserIds" width="150">
         <template slot-scope="scope">
           <!-- 点击事件绑定到整个 div -->
-          <div @click="toggleRow(scope.row)" v-if="scope.row.type != 3">
+          <div @click="toggleRow(scope.row)" v-if="scope.row.filterMode == 1">
             <!-- 显示当前行的成员数量 -->
             <span v-if="!expandedRows[scope.row.id]">
             点击展开 ({{ scope.row.qwUserIds.split(',').length }} 人)
@@ -243,7 +242,7 @@
               </div>
             </div>
           </div>
-          <div @click="toggleRow(scope.row)" v-if="scope.row.type == 3">
+          <div @click="toggleRow(scope.row)" v-if="scope.row.filterMode == 2">
             <!-- 显示当前行的成员数量 -->
             <span v-if="!expandedRows[scope.row.id]">
             点击展开 ({{ scope.row.chatId.split(',').length }} 个)
@@ -271,7 +270,7 @@
       <el-table-column label="新客户自动创建sop" align="center" prop="isAutoSop" width="140">
         <template slot-scope="scope">
           <el-switch
-            v-if="scope.row.sendType==2 || scope.row.sendType==4"
+            v-if="(scope.row.sendType==2 || scope.row.sendType==4) && scope.row.filterMode == 1"
             v-model="scope.row.isAutoSop"
             active-color="#13ce66"
             inactive-color="#ff4949"
@@ -279,11 +278,11 @@
             :inactive-value="2"
             @change="switchAutoSopChange(scope.row.id,scope.row.isAutoSop)">
           </el-switch>
-          <span v-if="scope.row.sendType!=1 && scope.row.isAutoSop == '1'"
+          <span v-if="scope.row.sendType!=1 && scope.row.isAutoSop == '1' && scope.row.filterMode == 1"
                 style="margin-left: 10px;color: #13ce66">已开启</span>
-          <span v-if="scope.row.sendType!=1 && scope.row.isAutoSop == '2'"
+          <span v-if="scope.row.sendType!=1 && scope.row.isAutoSop == '2' && scope.row.filterMode == 1"
                 style="margin-left: 10px;color: #ff4949">已关闭</span>
-          <span v-if="scope.row.sendType==1" style="margin-left: 10px;color: rgb(250,114,3)">企微接口无法设置</span>
+          <span v-if="scope.row.sendType==1 && scope.row.filterMode == 1" style="margin-left: 10px;color: rgb(250,114,3)">企微接口无法设置</span>
         </template>
       </el-table-column>
       <el-table-column label="过期时间" align="center" prop="expiryTime">
@@ -1207,18 +1206,16 @@ export default {
      * 查看SOP任务内营期
      */
     selectSchedule(row) {
-      const data = {
+      const query = {
         id: row.id,
         name: row.name,
-        tempId: row.tempId
+        tempId: row.tempId,
+        filterMode: row.filterMode
       }
       // 使用 params 传递参数
       this.$router.push({
-        path: `/qw/sopUserLogs/sopUserLogsSchedule/${data.id}`,
-        query: {
-          name: data.name,
-          tempId: data.tempId,
-        } // 如果需要传递更多参数,可以使用 query
+        path: `/qw/sopUserLogs/sopUserLogsSchedule/${query.id}`,
+        query// 如果需要传递更多参数,可以使用 query
       });
     },
 

+ 15 - 0
src/views/qw/sopTemp/index.vue

@@ -205,6 +205,17 @@
             >{{dict.dictLabel}}</el-radio>
           </el-radio-group>
         </el-form-item>
+
+        <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-form-item label="间隔天数" prop="gap">
           <el-input-number v-model="form.gap"  :min="1" label="间隔天数"></el-input-number>
         </el-form-item>
@@ -319,6 +330,7 @@ export default {
       sopTempList: [],
       sysQwSopType:[],
       companyList:[],
+      projectOptions:[],
       // 弹出层标题
       title: "",
       // 是否显示弹出层
@@ -376,6 +388,9 @@ export default {
       this.statusOptions = response.data;
     });
 
+    this.getDicts("sys_course_project").then(response => {
+      this.projectOptions = response.data;
+    });
 
     this.getDicts("sys_qw_sop_type").then(response => {
       this.sysQwSopType = response.data;

+ 5 - 0
src/views/qw/sopUserLogs/sopUserLogsSchedule.vue

@@ -56,6 +56,7 @@
       <el-table-column label="营期编号" align="center" prop="id" />
 <!--      <el-table-column label="模板编号" align="center" prop="sopTempId" />-->
       <el-table-column label="企微员工账号" align="center" prop="qwUserId" />
+      <el-table-column label="群聊" align="center" prop="chatName" v-if="filterMode == 2" />
       <el-table-column label="营期时间" align="center" prop="startTime" width="180">
         <template slot-scope="scope">
           <span>{{ parseTime(scope.row.startTime, '{y}-{m}-{d}') }}</span>
@@ -171,6 +172,7 @@ export default {
       sopUserLogsDelStatus:[],
       // 弹出层标题
       title: "",
+      filterMode: 1,
       // 是否显示弹出层
       open: false,
       // 查询参数
@@ -213,6 +215,8 @@ export default {
       this.sysQwSopAiContentType = response.data;
     });
     this.queryParams.sopId = this.$route.params.id;
+    this.filterMode = this.$route.query.filterMode;
+    console.info(this.$route.query)
     this.sopName = this.$route.query.name;
     this.tempId = this.$route.query.tempId;
     this.getList()
@@ -278,6 +282,7 @@ export default {
     },
 
     handleSelect(val){
+      val.filterMode = this.filterMode;
       this.logsInfoDetailsOpen.title='企微账号:'+val.qwUserId+'  '+'营期时间:'+val.startTime+'  '+'天数:' + val.countDays;
       this.logsInfoDetailsOpen.open=true;
       const externalUserName = this.queryParams.externalUserName;

+ 32 - 2
src/views/qw/sopUserLogsInfo/sopUserLogsInfoDetails.vue

@@ -50,7 +50,7 @@
       </el-form-item>
     </el-form>
 
-    <el-row :gutter="10" class="mb8">
+    <el-row :gutter="10" class="mb8" v-if="queryParams.filterMode == 1">
       <el-col :span="1.5">
         <el-button
           type="warning"
@@ -85,7 +85,7 @@
 <!--      </el-col>-->
     </el-row>
 
-    <el-table border v-loading="loading" :data="sopUserLogsInfoList" @selection-change="handleSelectionChange">
+    <el-table border v-loading="loading" :data="sopUserLogsInfoList" @selection-change="handleSelectionChange" v-if="queryParams.filterMode == 1">
       <el-table-column type="selection" width="55" align="center" />
       <el-table-column label="编号" align="center" prop="id" width="100"/>
 <!--      <el-table-column label="企微员工账号" align="center" prop="qwUserId" width="100"/>-->
@@ -143,6 +143,34 @@
       </el-table-column>
     </el-table>
 
+    <el-table border v-loading="loading" :data="sopUserLogsInfoList" @selection-change="handleSelectionChange" v-if="queryParams.filterMode == 2">
+      <el-table-column label="编号" align="center" prop="id" width="100"/>
+      <el-table-column label="客户名称" align="center" prop="name" />
+      <el-table-column label="备注" align="center" prop="remark" />
+      <el-table-column label="客户标签" align="center" prop="tagIds" width="240">
+        <template slot-scope="scope">
+          <div v-if="scope.row.tagIds && scope.row.tagIds !== '无标签'">
+            <div v-for="i in JSON.parse(scope.row.tagIds)" :key="i" style="display: inline;">
+              <el-tag
+                type="success"
+                v-for="ii in tagList"
+                :key="ii.id"
+                style="margin: 3px;"
+                v-if="ii.tagId == i"
+              >
+                {{ ii.name }}
+              </el-tag>
+            </div>
+          </div>
+          <div v-else>
+            <span style="color: red;">无标签</span>
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column label="加群时间" align="center" prop="joinTime" width="180"/>
+      <el-table-column label="进线时间" align="center" prop="inComTime" width="180"/>
+    </el-table>
+
     <pagination-more
       v-show="total>0"
       :total="total"
@@ -467,7 +495,9 @@ export default {
 
       this.loading = true;
       this.queryParams.sopId=val.sopId;
+      this.queryParams.filterMode=val.filterMode;
       this.queryParams.userLogsId=val.id;
+      this.queryParams.chatId=val.chatId;
       if (externalUserName!=null){
         this.queryParams.externalUserName = externalUserName;
       }

Некоторые файлы не были показаны из-за большого количества измененных файлов