xw 1 Minggu lalu
induk
melakukan
fef7ea25da
2 mengubah file dengan 150 tambahan dan 37 penghapusan
  1. 76 24
      src/views/qw/sop/sop.vue
  2. 74 13
      src/views/qw/sopUserLogsInfo/sendMsgSopOpenTool.vue

+ 76 - 24
src/views/qw/sop/sop.vue

@@ -809,8 +809,13 @@
               <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"  @change="handleContentTypeChange()">{{item.dictLabel}}</el-radio>
+                    <el-radio-group v-model="item.contentType">
+                      <el-radio
+                        v-for="typeDict in sysQwSopAiContentType"
+                        :key="typeDict.dictValue"
+                        :label="typeDict.dictValue"
+                        @change="handleContentTypeChange()"
+                      >{{ typeDict.dictLabel }}</el-radio>
                     </el-radio-group>
                   </el-form-item>
                   <el-form-item label="内容" style="margin-bottom: 2%" >
@@ -850,7 +855,7 @@
 
                     <ImageUpload v-if="item.contentType == 2 " v-model="item.imgUrl" type="image" :num="1"  :width="150" :height="150" />
 
-                    <div v-if="item.contentType == 3 ">
+                    <div v-if="isLinkH5ContentType(item.contentType)">
                       <el-card class="box-card">
                         <el-form-item label="链接标题:"  label-width="100px">
                           <el-input v-model="item.linkTitle" placeholder="请输入链接标题" style="width: 90%;"/>
@@ -866,6 +871,26 @@
                         </el-form-item>
                       </el-card>
                     </div>
+                    <div v-if="isAppContentType(item.contentType)">
+                      <el-card class="box-card">
+                        <el-form-item label="消息标题" label-width="100px">
+                          <el-input v-model="item.linkTitle" placeholder="APP 消息标题(短链/推送展示)" 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-tag type="info">可点击链接由服务端根据所选课程、课节生成,无需填写短链</el-tag>
+                        </el-form-item>
+                        <el-form-item label="链接有效天数" label-width="100px">
+                          <el-input-number v-model="item.expiresDays" :min="0" :max="365" :precision="0" placeholder="可选"/>
+                          <span class="tip" style="margin-left: 8px;">不填或 0 表示使用课程/系统默认过期时间</span>
+                        </el-form-item>
+                      </el-card>
+                    </div>
                     <div v-if="item.contentType == 4">
                       <el-card class="box-card">
                         <el-form-item label="标题" prop="miniprogramTitle">
@@ -1814,6 +1839,32 @@ export default {
       this.setting.push(newSetting);
 
     },
+    isAppContentType(ct) {
+      if (ct === undefined || ct === null || ct === '') {
+        return false;
+      }
+      return String(ct).trim() === '9';
+    },
+    isLinkH5ContentType(ct) {
+      if (ct === undefined || ct === null || ct === '') {
+        return false;
+      }
+      return String(ct).trim() === '3';
+    },
+    buildMsgSettingPayload() {
+      return this.setting.map(row => {
+        const o = { ...row };
+        o.contentType = o.contentType !== undefined && o.contentType !== null ? String(o.contentType) : o.contentType;
+        if (this.isAppContentType(row.contentType)) {
+          o.contentType = '9';
+          const d = o.expiresDays;
+          if (d === undefined || d === null || d === '' || Number(d) === 0) {
+            delete o.expiresDays;
+          }
+        }
+        return o;
+      });
+    },
 
     handleContentTypeChange() {
 
@@ -1825,7 +1876,7 @@ export default {
             this.$set(this.setting[i], 'voiceInputMode', 'dropdown');
           }
           //响应式直接给链接的标题/封面上值
-          if (selectedCourse && this.setting[i].contentType == 3 && this.msgForm.courseId != null) {
+          if (selectedCourse && (this.setting[i].contentType == 3 || this.setting[i].contentType == 9) && this.msgForm.courseId != null) {
             this.$set(this.setting[i], 'linkTitle', selectedCourse.dictLabel);
             this.$set(this.setting[i], 'linkImageUrl', selectedCourse.dictImgUrl);
           }
@@ -2246,7 +2297,6 @@ export default {
     submitMsgForm(){
       this.$refs["msgForm"].validate(valid => {
         if (valid) {
-          this.msgForm.setting=JSON.stringify(this.setting)
           this.msgForm.sopId=this.sendMsgOpen.row.id;
           this.msgForm.corpId=this.sendMsgOpen.row.corpId;
           this.msgForm.filterMode=this.sendMsgOpen.row.filterMode;
@@ -2254,17 +2304,15 @@ export default {
           if (this.setting.length <= 0) {
             return this.$message.error("请添加规则")
           }
-          console.log(this.msgForm.setting)
-          let jsonSetting = JSON.parse(this.msgForm.setting);
           let hasLiveSetting = false;
-          console.log(jsonSetting)
-          for(let index=0;index < jsonSetting.length;index++){
-           if(!!jsonSetting[index] && jsonSetting[index].contentType == "12") {
-            if(!!hasLiveSetting){
-               return this.$message.error("发送直播间只能一次只能发送一条");
+          for (let index = 0; index < this.setting.length; index++) {
+            const row = this.setting[index];
+            if (row && String(row.contentType).trim() === '12') {
+              if (hasLiveSetting) {
+                return this.$message.error("发送直播间只能一次只能发送一条");
+              }
+              hasLiveSetting = true;
             }
-            hasLiveSetting = true;
-           }
           }
           if(!!hasLiveSetting && (this.msgForm.courseId!=null && this.msgForm.courseId!='')){
               return this.$message.error("直播间不能选取课程");
@@ -2272,8 +2320,6 @@ export default {
           if(!!hasLiveSetting && (this.msgForm.videoId!=null && this.msgForm.videoId!='')){
               return this.$message.error("直播间不能选取课节");
           }
-          console.log(hasLiveSetting);
-          // debugger;
           if ((this.msgForm.courseId===null || this.msgForm.courseId==='') && !hasLiveSetting){
             return this.$message.error("课程不能为空")
           }
@@ -2286,6 +2332,10 @@ export default {
             return this.$message.error("消息类型不能为空")
           }
 
+          const hasAppBlock = this.setting.some(s => this.isAppContentType(s.contentType));
+          if (hasAppBlock && (this.msgForm.corpId === null || this.msgForm.corpId === undefined || this.msgForm.corpId === '')) {
+            return this.$message.error("企业编号不能为空")
+          }
 
           for (let i = 0; i < this.setting.length; i++) {
             if (this.setting[i].contentType == 1 && (this.setting[i].value == null || this.setting[i].value == "")) {
@@ -2294,16 +2344,16 @@ export default {
             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.isLinkH5ContentType(this.setting[i].contentType) || this.isAppContentType(this.setting[i].contentType)) && (this.setting[i].linkTitle == null || this.setting[i].linkTitle == "")) {
+              return this.$message.error(this.isAppContentType(this.setting[i].contentType) ? "APP 消息标题不能为空" : "链接标题不能为空")
             }
-            if (this.setting[i].contentType == 3 && (this.setting[i].linkDescribe == null || this.setting[i].linkDescribe == "")) {
-              return this.$message.error("链接描述不能为空")
+            if ((this.isLinkH5ContentType(this.setting[i].contentType) || this.isAppContentType(this.setting[i].contentType)) && (this.setting[i].linkDescribe == null || this.setting[i].linkDescribe == "")) {
+              return this.$message.error(this.isAppContentType(this.setting[i].contentType) ? "APP 描述不能为空" : "链接描述不能为空")
             }
-            if (this.setting[i].contentType == 3 && (this.setting[i].linkImageUrl == null || this.setting[i].linkImageUrl == "")) {
-              return this.$message.error("链接图片不能为空")
+            if ((this.isLinkH5ContentType(this.setting[i].contentType) || this.isAppContentType(this.setting[i].contentType)) && (this.setting[i].linkImageUrl == null || this.setting[i].linkImageUrl == "")) {
+              return this.$message.error(this.isAppContentType(this.setting[i].contentType) ? "APP 封面不能为空" : "链接图片不能为空")
             }
-            if (this.setting[i].contentType == 3 && this.setting[i].type == 1 && (this.setting[i].linkUrl == null || this.setting[i].linkUrl == "")) {
+            if (this.isLinkH5ContentType(this.setting[i].contentType) && 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 == "")) {
@@ -2329,6 +2379,8 @@ export default {
             }
           }
 
+          this.msgForm.setting = JSON.stringify(this.buildMsgSettingPayload())
+
           this.sendMsgOpen.open = false;
 
           const loading = this.$loading({
@@ -2365,7 +2417,7 @@ export default {
         const selectedCourse = this.courseList.find(course => parseInt(course.dictValue) === this.msgForm.courseId);
         for (let i = 0; i < this.setting.length; i++) {
           //响应式直接给链接的标题/封面上值
-          if (selectedCourse && this.setting[i].contentType == 3 && this.msgForm.courseId != null) {
+          if (selectedCourse && (this.setting[i].contentType == 3 || this.setting[i].contentType == 9) && this.msgForm.courseId != null) {
             this.$set(this.setting[i], 'linkTitle', selectedCourse.dictLabel);
             this.$set(this.setting[i], 'linkImageUrl', selectedCourse.dictImgUrl);
           }

+ 74 - 13
src/views/qw/sopUserLogsInfo/sendMsgSopOpenTool.vue

@@ -52,8 +52,13 @@
               <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"  @change="handleContentTypeChange()">{{item.dictLabel}}</el-radio>
+                    <el-radio-group v-model="item.contentType">
+                      <el-radio
+                        v-for="typeDict in sysQwSopAiContentType"
+                        :key="typeDict.dictValue"
+                        :label="typeDict.dictValue"
+                        @change="handleContentTypeChange()"
+                      >{{ typeDict.dictLabel }}</el-radio>
                     </el-radio-group>
                   </el-form-item>
                   <el-form-item label="内容" style="margin-bottom: 2%" >
@@ -88,7 +93,7 @@
 
                     <ImageUpload v-if="item.contentType == 2 " v-model="item.imgUrl" type="image" :num="1"  :width="150" :height="150" />
 
-                    <div v-if="item.contentType == 3 || item.contentType ==9 ">
+                    <div v-if="isLinkH5ContentType(item.contentType)">
                       <el-card class="box-card">
                         <el-form-item label="链接标题:"  label-width="100px">
                           <el-input v-model="item.linkTitle" placeholder="请输入链接标题" style="width: 90%;"/>
@@ -104,6 +109,26 @@
                         </el-form-item>
                       </el-card>
                     </div>
+                    <div v-if="isAppContentType(item.contentType)">
+                      <el-card class="box-card">
+                        <el-form-item label="消息标题" label-width="100px">
+                          <el-input v-model="item.linkTitle" placeholder="APP 消息标题(短链/推送展示)" 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-tag type="info">可点击链接由服务端根据上方所选课程、课节生成,无需填写短链</el-tag>
+                        </el-form-item>
+                        <el-form-item label="链接有效天数" label-width="100px">
+                          <el-input-number v-model="item.expiresDays" :min="0" :max="365" :precision="0" placeholder="可选"/>
+                          <span class="tip" style="margin-left: 8px;">不填或 0 表示使用课程/系统默认过期时间</span>
+                        </el-form-item>
+                      </el-card>
+                    </div>
                     <div v-if="item.contentType == 4 || item.contentType == 10 ">
                       <el-card class="box-card">
                         <el-form-item label="标题" prop="miniprogramTitle">
@@ -340,7 +365,8 @@
                                                           && item.contentType != 2
                                                           && item.contentType != 5
                                                           && item.contentType != 6
-                                                          && item.contentType != 8"
+                                                          && item.contentType != 8
+                                                          && !isAppContentType(item.contentType)"
                                 style="margin-top: 1%" label-width="100px">
                     <el-row>
                       <el-input-number  v-model="item.expiresDays"  :min="1" :max="100" ></el-input-number>
@@ -595,6 +621,36 @@ export default {
       this.msgForm.isMine = isMine;
       this.msgForm.qwUserIds = qwUserIds;
     },
+    /** 内容类别 APP,与后端 contentType 字符串 "9" 对齐(兼容字典 number / string) */
+    isAppContentType(ct) {
+      if (ct === undefined || ct === null || ct === '') {
+        return false;
+      }
+      return String(ct).trim() === '9';
+    },
+    isLinkH5ContentType(ct) {
+      if (ct === undefined || ct === null || ct === '') {
+        return false;
+      }
+      return String(ct).trim() === '3';
+    },
+    /**
+     * 提交前规范化 setting:contentType 统一为字符串;APP 项固定为 "9",空/0 的 expiresDays 不传
+     */
+    buildSettingPayload() {
+      return this.setting.map(row => {
+        const o = { ...row };
+        o.contentType = o.contentType !== undefined && o.contentType !== null ? String(o.contentType) : o.contentType;
+        if (this.isAppContentType(row.contentType)) {
+          o.contentType = '9';
+          const d = o.expiresDays;
+          if (d === undefined || d === null || d === '' || Number(d) === 0) {
+            delete o.expiresDays;
+          }
+        }
+        return o;
+      });
+    },
     courseChange() {
       if (this.msgForm.courseId != null ) {
         const selectedCourse = this.courseList.find(course => parseInt(course.dictValue) === this.msgForm.courseId);
@@ -932,8 +988,6 @@ export default {
 
           if (this.msgForm.draftStrategy==1){
 
-            this.msgForm.setting=JSON.stringify(this.setting)
-
             if (this.setting.length <= 0) {
               return this.$message.error("请添加规则")
             }
@@ -949,6 +1003,11 @@ export default {
               return this.$message.error("消息类型不能为空")
             }
 
+            const hasAppBlock = this.setting.some(s => this.isAppContentType(s.contentType));
+            if (hasAppBlock && (this.msgForm.corpId === null || this.msgForm.corpId === undefined || this.msgForm.corpId === '')) {
+              return this.$message.error("企业编号不能为空")
+            }
+
             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("内容不能为空")
@@ -956,16 +1015,16 @@ export default {
               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].contentType == 9  ) && (this.setting[i].linkTitle == null || this.setting[i].linkTitle == "")) {
-                return this.$message.error("链接标题不能为空")
+              if ((this.isLinkH5ContentType(this.setting[i].contentType) || this.isAppContentType(this.setting[i].contentType)) && (this.setting[i].linkTitle == null || this.setting[i].linkTitle == "")) {
+                return this.$message.error(this.isAppContentType(this.setting[i].contentType) ? "APP 消息标题不能为空" : "链接标题不能为空")
               }
-              if ((this.setting[i].contentType == 3 || this.setting[i].contentType == 9 ) && (this.setting[i].linkDescribe == null || this.setting[i].linkDescribe == "")) {
-                return this.$message.error("链接描述不能为空")
+              if ((this.isLinkH5ContentType(this.setting[i].contentType) || this.isAppContentType(this.setting[i].contentType)) && (this.setting[i].linkDescribe == null || this.setting[i].linkDescribe == "")) {
+                return this.$message.error(this.isAppContentType(this.setting[i].contentType) ? "APP 描述不能为空" : "链接描述不能为空")
               }
-              if ((this.setting[i].contentType == 3 || this.setting[i].contentType == 9 ) && (this.setting[i].linkImageUrl == null || this.setting[i].linkImageUrl == "")) {
-                return this.$message.error("链接图片不能为空")
+              if ((this.isLinkH5ContentType(this.setting[i].contentType) || this.isAppContentType(this.setting[i].contentType)) && (this.setting[i].linkImageUrl == null || this.setting[i].linkImageUrl == "")) {
+                return this.$message.error(this.isAppContentType(this.setting[i].contentType) ? "APP 封面不能为空" : "链接图片不能为空")
               }
-              if ((this.setting[i].contentType == 3 || this.setting[i].contentType == 9 )&& this.setting[i].type == 1 && (this.setting[i].linkUrl == null || this.setting[i].linkUrl == "")) {
+              if (this.isLinkH5ContentType(this.setting[i].contentType) && this.setting[i].type == 1 && (this.setting[i].linkUrl == null || this.setting[i].linkUrl == "")) {
                 return this.$message.error("链接地址不能为空")
               }
 
@@ -999,6 +1058,8 @@ export default {
                 return this.$message.error("订阅号文章链接不能为空")
               }
             }
+
+            this.msgForm.setting = JSON.stringify(this.buildSettingPayload())
           }