Browse Source

看课记录批量修改备注

xw 2 days ago
parent
commit
51ed16fa15

+ 9 - 0
src/api/qw/externalContact.js

@@ -306,6 +306,15 @@ export function batchUpdateExternalContactNotes(data) {
   })
 }
 
+export function batchUpdateExternalContactNotesByWatchLog(data) {
+  return request({
+    url: '/qw/externalContact/batchUpdateExternalContactNotesByWatchLog',
+    method: 'post',
+    data: data
+  })
+}
+
+
 // 查询企业微信客户流失删除统计列表
 export function delLossStatistics(query) {
   return request({

+ 147 - 1
src/views/course/courseWatchLog/index.vue

@@ -326,6 +326,28 @@
           >批量移除标签</el-button>
         </el-col>
       </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          @click="handleBatchUpdateNotes"
+          v-hasPermi="['qw:externalContact:edit']"
+        >批量修改备注
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          @click="handleBatchUpdateNotesFilter"
+          v-hasPermi="['qw:externalContact:edit']"
+        >批量修改备注(筛选条件)
+        </el-button>
+      </el-col>
       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
     </el-row>
 
@@ -608,6 +630,54 @@
       </span>
     </el-dialog>
 
+    <el-dialog title="批量添加客户备注" :visible.sync="notesOpen.open" width="800px" append-to-body>
+      <el-card>
+        <el-row>
+          <el-col>
+            <el-radio-group v-model="notesOpen.nameType" style="margin-bottom: 2%">
+              <el-radio :label="1">
+                客户名称添加在【新备注】【前】
+              </el-radio>
+              <el-radio :label="2">
+                客户名称添加在【新备注】【后】
+              </el-radio>
+              <el-radio :label="3">
+                不添加客户名称
+              </el-radio>
+            </el-radio-group>
+          </el-col>
+          <el-col>
+            <el-radio-group v-model="notesOpen.type">
+              <el-radio
+                :label="1"
+              >添加【新备注】在最【前】面
+              </el-radio>
+              <el-radio
+                :label="2"
+              >添加【新备注】在最【后】面
+              </el-radio>
+              <el-radio
+                :label="3"
+              >替换所有备注
+              </el-radio>
+            </el-radio-group>
+          </el-col>
+          <el-col>
+            <el-input v-model="notesOpen.notes" placeholder="请输入客户备注(最多20个字,含已有的)" clearable size="small"
+                      maxlength="20" show-word-limit style="width: 500px;margin-top: 3%"/>
+            <div style="color: #999;font-size: 14px;display: flex;align-items: center;">
+              <i class="el-icon-info"></i>
+              由于企业微信官方限制,备注最多20个字,且自动会去除末尾超出的字
+            </div>
+          </el-col>
+        </el-row>
+      </el-card>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="notesSubmitForm()">确 定</el-button>
+        <el-button @click="notesCancel()">取消</el-button>
+      </div>
+    </el-dialog>
+
   </div>
 </template>
 
@@ -617,7 +687,7 @@ import {courseList, listCourseRedPacketLog, videoList, periodList} from '@/api/c
 import {listLogs} from "@/api/course/courseAnswerlogs";
 import {allListTagGroup} from "../../../api/qw/tagGroup";
 import {searchTags} from "../../../api/qw/tag";
-import {addTagByWatch, delTagByWatch} from "../../../api/qw/externalContact";
+import {addTagByWatch, delTagByWatch, batchUpdateExternalContactNotes, batchUpdateExternalContactNotesByWatchLog} from "../../../api/qw/externalContact";
 import Vue from 'vue'
 import Calendar from 'vue-mobile-calendar'
 import {infoSop} from "@/api/qw/sop";
@@ -764,6 +834,7 @@ export default {
       // SOP搜索相关
       sopSearchText: '', // SOP搜索框显示的文本
       selectedSopId: null, // 选中的SOP ID
+      sysCompanyOr: [],
       // 查询参数
       queryParams: {
         pageNum: 1,
@@ -821,6 +892,14 @@ export default {
         pageSize: 10
       },
       qwUserOptionsLoading: false,
+      notesOpen: {
+        type: 1,
+        nameType: 3,
+        addType: 0,
+        filter: false,
+        open: false,
+        notes: null,
+      },
     };
   },
   created() {
@@ -834,6 +913,9 @@ export default {
     this.getDicts("sys_course_project").then(response => {
       this.projectOptions = response.data;
     });
+    this.getDicts("sys_company_or").then(response => {
+      this.sysCompanyOr = response.data;
+    });
     this.getCompanyUserListLikeName(true);
   },
   methods: {
@@ -1646,6 +1728,70 @@ export default {
       this.sopSearchText = '';
     },
 
+    handleBatchUpdateNotesFilter() {
+      this.notesOpen.open = true;
+      this.notesOpen.filter = true;
+    },
+    handleBatchUpdateNotes() {
+
+      if (this.ids == null || this.ids == "") {
+        return this.$message('请选择需要添加备注的客户');
+      }
+
+      this.notesOpen.open = true;
+      this.notesOpen.filter = false;
+
+    },
+    notesCancel(){
+      this.notesOpen={
+        open: false,
+        notes: null,
+        type: 1,
+        nameType:3,
+      }
+    },
+    notesSubmitForm() {
+
+      if (this.notesOpen.notes == null || this.notesOpen.notes == "") {
+        return this.$message.error("请输入备注内容");
+      }
+
+      // let loadingRock = this.$loading({
+      //   lock: true,
+      //   text: '正在执行中请稍后~~请不要刷新页面!!',
+      //   spinner: 'el-icon-loading',
+      //   background: 'rgba(0, 0, 0, 0.7)'
+      // });
+
+      let obj = JSON.parse(JSON.stringify(this.queryParams))
+      console.log(obj);
+      if(obj.tagIds !== null && obj.tagIds !== undefined && obj.tagIds !== ''){
+        obj.tagIds = obj.tagIds.split(",");
+      }
+      batchUpdateExternalContactNotesByWatchLog({
+        // addType: 0,
+        watchLogIds: this.ids,
+        notes: this.notesOpen.notes,
+        type: this.notesOpen.type,
+        nameType: this.notesOpen.nameType,
+        filter: this.notesOpen.filter,
+        watchLogParam: obj,
+        fromMyList:0
+      }).then(res => {
+
+        this.resultMessage = res.msg;
+        this.$message.success("正在执行中...");
+        // this.resultDialogVisible = true; // 显示弹窗
+        // this.resultTitle = '批量修改备注结果';
+
+      }).finally(res => {
+        this.getList();
+        // loadingRock.close();
+        this.notesCancel();
+      })
+
+    },
+
   }
 };
 </script>

+ 212 - 88
src/views/course/courseWatchLog/watchLog.vue

@@ -70,7 +70,7 @@
       </el-form-item>
       <el-form-item label="课程" prop="courseId">
         <el-select filterable v-model="queryParams.courseId" placeholder="请选择课程" clearable size="small"
-                   @change="handleCourseChange">
+                   @change="courseChange(queryParams.courseId)">
           <el-option
             v-for="dict in courseLists"
             :key="dict.dictValue"
@@ -79,20 +79,8 @@
           />
         </el-select>
       </el-form-item>
-      <el-form-item label="营期" prop="periodId">
-        <el-select filterable v-model="queryParams.periodId" placeholder="请选择营期" clearable size="small"
-                   @change="handlePeriodChange" :disabled="!queryParams.courseId">
-          <el-option
-            v-for="dict in periodList"
-            :key="dict.dictValue"
-            :label="dict.dictLabel"
-            :value="dict.dictValue"
-          />
-        </el-select>
-      </el-form-item>
       <el-form-item label="小节" prop="videoId">
-        <el-select filterable v-model="queryParams.videoId" placeholder="请选择小节" clearable size="small"
-                   :disabled="!queryParams.periodId">
+        <el-select filterable v-model="queryParams.videoId" placeholder="请选择小节" clearable size="small">
           <el-option
             v-for="dict in videoList"
             :key="dict.dictValue"
@@ -303,6 +291,28 @@
           >批量移除标签</el-button>
         </el-col>
       </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          @click="handleBatchUpdateNotes"
+          v-hasPermi="['qw:externalContact:edit']"
+        >批量修改备注
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="el-icon-edit"
+          size="mini"
+          @click="handleBatchUpdateNotesFilter"
+          v-hasPermi="['qw:externalContact:edit']"
+        >批量修改备注(筛选条件)
+        </el-button>
+      </el-col>
       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
     </el-row>
 
@@ -335,6 +345,20 @@
 <!--         </el-popover>-->
 <!--       </template>-->
 <!--     </el-table-column>-->
+      <el-table-column label="头像" align="center">
+        <template slot-scope="scope">
+          <img
+            v-if="queryParams.sendType == 1"
+            :src="scope.row.fsAvatar"
+            style="width:50px;height:50px"
+          />
+          <img
+            v-else-if="queryParams.sendType == 2"
+            :src="scope.row.externalUserAvatar"
+            style="width:50px;height:50px"
+          />
+        </template>
+      </el-table-column>
       <el-table-column label="用户昵称" align="center" v-if="queryParams.sendType == 1">
         <template slot-scope="scope">
           {{ queryParams.sendType=='1' ? scope.row.fsNickName : scope.row.externalUserName }}
@@ -470,7 +494,7 @@
 <!--        <el-table-column label="会员电话" align="center" prop="phone" />-->
 <!--        <el-table-column label="所属销售" align="center" prop="companyUserName" />-->
 <!--        <el-table-column label="所属公司" align="center" prop="companyName" />-->
-        <el-table-column label="转金额" align="center" prop="amount" />
+        <el-table-column label="转金额" align="center" prop="amount" />
         <el-table-column label="状态" align="center" prop="status" >
           <template slot-scope="scope">
             <el-tag>
@@ -585,7 +609,53 @@
         <el-button @click="resultDialogVisible = false">关闭</el-button>
       </span>
     </el-dialog>
-
+     <el-dialog title="批量添加客户备注" :visible.sync="notesOpen.open" width="800px" append-to-body>
+      <el-card>
+        <el-row>
+          <el-col>
+            <el-radio-group v-model="notesOpen.nameType" style="margin-bottom: 2%">
+              <el-radio :label="1">
+                客户名称添加在【新备注】【前】
+              </el-radio>
+              <el-radio :label="2">
+                客户名称添加在【新备注】【后】
+              </el-radio>
+              <el-radio :label="3">
+                不添加客户名称
+              </el-radio>
+            </el-radio-group>
+          </el-col>
+          <el-col>
+            <el-radio-group v-model="notesOpen.type">
+              <el-radio
+                :label="1"
+              >添加【新备注】在最【前】面
+              </el-radio>
+              <el-radio
+                :label="2"
+              >添加【新备注】在最【后】面
+              </el-radio>
+              <el-radio
+                :label="3"
+              >替换所有备注
+              </el-radio>
+            </el-radio-group>
+          </el-col>
+          <el-col>
+            <el-input v-model="notesOpen.notes" placeholder="请输入客户备注(最多20个字,含已有的)" clearable size="small"
+                      maxlength="20" show-word-limit style="width: 500px;margin-top: 3%"/>
+            <div style="color: #999;font-size: 14px;display: flex;align-items: center;">
+              <i class="el-icon-info"></i>
+              由于企业微信官方限制,备注最多20个字,且自动会去除末尾超出的字
+            </div>
+          </el-col>
+        </el-row>
+      </el-card>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="notesSubmitForm()">确 定</el-button>
+        <el-button @click="notesCancel()">取消</el-button>
+      </div>
+    </el-dialog>
 
   </div>
 </template>
@@ -599,11 +669,11 @@ import {
   myListCourseWatchLog,
   updateCourseWatchLog
 } from "@/api/course/courseWatchLog";
-import {courseList, myListCourseRedPacketLog, videoList, periodList} from '@/api/course/courseRedPacketLog'
+import {courseList, myListCourseRedPacketLog, videoList} from '@/api/course/courseRedPacketLog'
 import {myListLogs} from "@/api/course/courseAnswerlogs";
 import {getMyQwUserList} from "@/api/qw/user";
 import {searchTags} from "../../../api/qw/tag";
-import {addTagByWatch, delTagByWatch} from "../../../api/qw/externalContact";
+import {addTagByWatch, delTagByWatch,batchUpdateExternalContactNotes,batchUpdateExternalContactNotesByWatchLog} from "../../../api/qw/externalContact";
 import {allListTagGroup} from "../../../api/qw/tagGroup";
 import Vue from 'vue'
 import Calendar from 'vue-mobile-calendar'
@@ -661,7 +731,6 @@ export default {
         }
       },
       courseLists: [],
-      periodList: [], // 营期列表
       videoList: [],
       myQwUserList: [],
       logTypeOptions: [],
@@ -763,7 +832,6 @@ export default {
         companyUserId: null,
         companyId: null,
         courseId: null,
-        periodId: null, // 营期ID
         sTime: null,
         eTime: null,
         upSTime:null,
@@ -781,14 +849,22 @@ export default {
       // 表单参数
       form: {},
       // 表单校验
-      rules: {}
+      rules: {},
+      notesOpen: {
+        type: 1,
+        nameType: 3,
+        addType: 0,
+        filter: false,
+        open: false,
+        notes: null,
+      },
     };
   },
   created() {
     courseList().then(response => {
       this.courseLists = response.list;
     });
-    this.getList();
+
     this.getDicts("sys_course_watch_log_type_new").then(response => {
       this.logTypeOptions = response.data;
     });
@@ -796,14 +872,30 @@ export default {
     this.getDicts("sys_company_or").then(response => {
       this.sysCompanyOr = response.data;
     });
-    getMyQwUserList().then(response => {
-      this.myQwUserList = response.data;
-    });
     this.getDicts("sys_course_project").then(response => {
       this.projectOptions = response.data;
     });
+    // 设置默认当天时间 xgb 防止频繁查询大量数据
+    this.setToday();
+
+    this.getList();
+    getMyQwUserList().then(response => {
+      this.myQwUserList = response.data;
+    });
+
   },
   methods: {
+    setToday(){
+      const today = new Date();
+      const todayStart = new Date(today);
+      todayStart.setHours(0, 0, 0, 0);
+      const todayEnd = new Date(today);
+      todayEnd.setHours(23, 59, 59, 999);
+
+      this.createTimeText = [this.formatDate(todayStart), this.formatDate(todayEnd)];
+      this.queryParams.sTime = this.formatDate(todayStart);
+      this.queryParams.eTime = this.formatDate(todayEnd);
+    },
 
     handleSendTypeChange() {
       // 重置相关参数
@@ -855,63 +947,14 @@ export default {
       if (!dates || dates.length < 2) return '';
       return dates.map(date => date.format('YYYY-MM-DD')).join(' ~ ');
     },
-    /**
-     * 课程变更处理
-     * 当课程改变时,清空营期和小节的选择和列表
-     */
-    handleCourseChange(courseId) {
-      // 清空下级选择和列表
-      this.queryParams.periodId = null;
-      this.queryParams.videoId = null;
-      this.periodList = [];
-      this.videoList = [];
-
-      // 如果选择了课程,加载营期列表
-      if (courseId) {
-        this.loadPeriodList(courseId);
-      }
-    },
-
-    /**
-     * 营期变更处理
-     * 当营期改变时,清空小节的选择和列表
-     */
-    handlePeriodChange(periodId) {
-      // 清空下级选择和列表
+    courseChange(row) {
       this.queryParams.videoId = null;
-      this.videoList = [];
-
-      // 如果选择了营期,加载视频列表
-      if (periodId) {
-        this.loadVideoList(periodId);
-      }
-    },
-
-    /**
-     * 加载营期列表
-     * @param {Number} courseId - 课程ID
-     */
-    loadPeriodList(courseId) {
-      periodList({ courseId: courseId }).then(response => {
-        this.periodList = response.data || [];
-      }).catch(error => {
-        console.error('加载营期列表失败:', error);
-        this.$message.error('加载营期列表失败');
-        this.periodList = [];
-      });
-    },
-
-    /**
-     * 加载视频列表
-     * @param {Number} periodId - 营期ID
-     */
-    loadVideoList(periodId) {
-      videoList(periodId).then(response => {
-        this.videoList = response.list || [];
-      }).catch(error => {
-        console.error('加载视频列表失败:', error);
-        this.$message.error('加载视频列表失败');
+      if (row === '') {
         this.videoList = [];
+        return
+      }
+      videoList(row).then(response => {
+        this.videoList = response.list
       });
     },
     updateQwuser() {
@@ -951,6 +994,20 @@ export default {
     // 创建时间
     createChange(createTime) {
       if (createTime && createTime.length >= 2) {
+        const startDate = new Date(createTime[0]);
+        const endDate = new Date(createTime[1]);
+        const timeDiff = Math.abs(endDate.getTime() - startDate.getTime());
+        const diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24));
+
+        // 限制时间区间为一个月
+        if (diffDays > 31) {
+          this.$message.warning('创建时间区间不能超过一个月');
+          this.createTimeText = null;
+          this.queryParams.sTime = null;
+          this.queryParams.eTime = null;
+          return;
+        }
+
         // this.createTimeText = this.formatDateRange(createTime);
         this.queryParams.sTime = this.formatDate(createTime[0]) || null;
         this.queryParams.eTime = this.formatDate(createTime[1]) || null;
@@ -1076,6 +1133,11 @@ export default {
 
     /** 查询短链课程看课记录列表 */
     getList() {
+      // xgb 看课数据量太大必须限制时间
+      if (!this.createTimeText) {
+        this.$message.warning('请选择创建时间');
+        return;
+      }
       this.loading = true;
       let param = JSON.parse(JSON.stringify(this.queryParams));
       if (param.logType == "10") {
@@ -1144,19 +1206,13 @@ export default {
       this.queryParams.isVip = null; // 重置 isVip 状态
       this.queryParams.qwUserId = null; // 重置 qwUserId
       this.queryParams.externalUserName=null;
-
-      // 重置三级联动相关数据
-      this.queryParams.courseId = null;
-      this.queryParams.periodId = null;
-      this.queryParams.videoId = null;
-      this.periodList = [];
-      this.videoList = [];
-
       // 重置SOP搜索
       this.handleSopClear();
       // 统一重置日历组件
       this.resetCalendars();
 
+      this.setToday();
+
       this.handleQuery();
     },
     // 多选框选中数据
@@ -1218,6 +1274,10 @@ export default {
     },
     /** 导出按钮操作 */
     handleExport() {
+      if (!this.createTimeText) {
+        this.$message.warning('请选择创建时间');
+        return;
+      }
       const queryParams = this.queryParams;
       this.$confirm('是否确认导出所有短链课程看课记录数据项?', "警告", {
         confirmButtonText: "确定",
@@ -1325,6 +1385,7 @@ export default {
 
       searchTags(this.queryTagParams).then(response => {
         this.tagGroupList = response.rows;
+        this.tagTotal = response.total;
       });
 
       // searchTags({name:name,corpId:this.queryParams.corpId}).then(response => {
@@ -1501,6 +1562,69 @@ export default {
       this.queryParams.sopId = null;
       this.sopSearchText = '';
     },
+    handleBatchUpdateNotesFilter() {
+      this.notesOpen.open = true;
+      this.notesOpen.filter = true;
+    },
+    handleBatchUpdateNotes() {
+
+      if (this.ids == null || this.ids == "") {
+        return this.$message('请选择需要添加备注的客户');
+      }
+
+      this.notesOpen.open = true;
+      this.notesOpen.filter = false;
+
+    },
+    notesCancel(){
+      this.notesOpen={
+        open: false,
+        notes: null,
+        type: 1,
+        nameType:3,
+      }
+    },
+    notesSubmitForm() {
+
+      if (this.notesOpen.notes == null || this.notesOpen.notes == "") {
+        return this.$message.error("请输入备注内容");
+      }
+
+      // let loadingRock = this.$loading({
+      //   lock: true,
+      //   text: '正在执行中请稍后~~请不要刷新页面!!',
+      //   spinner: 'el-icon-loading',
+      //   background: 'rgba(0, 0, 0, 0.7)'
+      // });
+
+      let obj = JSON.parse(JSON.stringify(this.queryParams))
+      console.log(obj);
+      if(obj.tagIds !== null && obj.tagIds !== undefined && obj.tagIds !== ''){
+        obj.tagIds = obj.tagIds.split(",");
+      }
+      batchUpdateExternalContactNotesByWatchLog({
+        // addType: 0,
+        watchLogIds: this.ids,
+        notes: this.notesOpen.notes,
+        type: this.notesOpen.type,
+        nameType: this.notesOpen.nameType,
+        filter: this.notesOpen.filter,
+        watchLogParam: obj,
+        fromMyList:1
+      }).then(res => {
+
+        this.resultMessage = res.msg;
+        this.$message.success("正在执行中...");
+        // this.resultDialogVisible = true; // 显示弹窗
+        // this.resultTitle = '批量修改备注结果';
+
+      }).finally(res => {
+        this.getList();
+        // loadingRock.close();
+        this.notesCancel();
+      })
+
+    },
   }
 };
 </script>