Procházet zdrojové kódy

Merge remote-tracking branch 'origin/master'

yfh před 1 týdnem
rodič
revize
95eea30a0f

+ 9 - 0
src/api/course/userCourse.js

@@ -98,3 +98,12 @@ export function pullOff(courseIds) {
     method: 'post'
   })
 }
+
+// 修改课堂配置
+export function editConfig(data) {
+  return request({
+    url: '/course/userCourse/editConfig',
+    method: 'post',
+    data: data
+  })
+}

+ 4 - 4
src/api/qw/user.js

@@ -67,9 +67,9 @@ export function getQwUserByIds(ids) {
   })
 }
 
-export function addQwUserName(id,companyId) {
+export function addQwUserName(id) {
   return request({
-    url: '/qw/user/syncName/' + id+"/"+companyId,
+    url: '/qw/user/syncName/' + id,
     method: 'post',
   })
 }
@@ -82,9 +82,9 @@ export function addUser(data) {
     data: data
   })
 }
-export function addQwUser(id,companyId) {
+export function addQwUser(id) {
   return request({
-    url: '/qw/user/sync/' + id+"/"+companyId,
+    url: '/qw/user/sync/' + id,
     method: 'post',
   })
 }

+ 59 - 34
src/views/company/companyUser/indexAll.vue

@@ -46,9 +46,6 @@
           <el-col :span="1.5">
             <el-button  plain type="success" icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate" v-hasPermi="['company:user:edit']">修改</el-button>
           </el-col>
-          <el-col :span="1.5">
-            <el-button  plain type="success" icon="el-icon-edit" size="mini" :disabled="multiple" @click="batchEditRole"v-hasPermi="['company:user:edit']">批量修改角色</el-button>
-          </el-col>
           <el-col :span="1.5">
             <el-button  plain type="danger" icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete" v-hasPermi="['company:user:remove']">删除</el-button>
           </el-col>
@@ -490,21 +487,38 @@
         </el-row>
         <el-row>
           <el-col :span="12">
-            <el-form-item label="归属部门" prop="deptId">
-              <treeselect v-model="formBindCompany.deptId" :options="deptOptions" :show-count="true" placeholder="请选择归属部门" />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="角色" prop="roleIds">
-              <el-select v-model="formBindCompany.roleIds" multiple placeholder="请选择">
-                <el-option v-for="item in roleOptions" :key="item.roleId" :label="item.roleName" :value="item.roleId "></el-option>
+            <el-form-item label="销售公司" prop="companyId">
+              <el-select filterable  v-model="formBindCompany.companyId" placeholder="请选择销售公司"  clearable size="small" @change="formBindCompanyChange">
+                <el-option
+                  v-for="item in companys"
+                  :key="item.companyId"
+                  :label="item.companyName"
+                  :value="item.companyId"
+                />
               </el-select>
             </el-form-item>
           </el-col>
         </el-row>
+
+        <div v-if="formBindCompany.companyId!=null">
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="归属部门" prop="deptId">
+                <treeselect v-model="formBindCompany.deptId" :options="deptOptionsByCompanyId" :show-count="true" placeholder="请选择归属部门" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="角色" prop="roleIds">
+                <el-select v-model="formBindCompany.roleIds" multiple placeholder="请选择">
+                  <el-option v-for="item in roleBindOptions" :key="item.roleId" :label="item.roleName" :value="item.roleId "></el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </div>
+
         <el-row>
           <el-col :span="12">
             <el-form-item label="销售区域" prop="addressId">
@@ -742,6 +756,7 @@ export default {
       postOptions: [],
       // 角色选项
       roleOptions: [],
+      roleBindOptions: [],
       userTypeOptions:[
         { "dictLabel": "临时管理员","dictValue": "02"},
         { "dictLabel": "普通用户","dictValue": "01"}
@@ -849,6 +864,9 @@ export default {
       },
       // 表单校验
       bindCompanyRules: {
+        companyId: [
+          { required: true, message: "销售公司不能为空", trigger: "blur" },
+        ],
         deptId: [
           { required: true, message: "归属部门不能为空", trigger: "blur" },
         ],
@@ -984,20 +1002,6 @@ export default {
       });
     },
 
-    // 在 methods 中添加批量修改角色的方法
-    batchEditRole() {
-      if (this.ids.length === 0) {
-        this.$message.warning("请至少选择一个用户");
-        return;
-      }
-      // 获取角色列表数据
-      getUser().then((response) => {
-        this.roleOptions = response.roles;
-        this.batchRoleDialogVisible = true;
-        this.selectedRoleIds = []; // 清空之前的选择
-      });
-    },
-
     // 添加批量角色更新提交方法
     submitBatchRoles() {
       // 验证选择的角色
@@ -1146,6 +1150,7 @@ export default {
         deptId: null,
         addressId: null,
         roleIds: [],
+        companyId: null,
       };
       this.resetForm("formBindCompany");
     },
@@ -1201,12 +1206,10 @@ export default {
     handleBindCompanyUserCode() {
       this.reset();
       this.getTreeselect();
-      getUser().then((response) => {
-        this.postOptions = response.posts;
-        this.roleOptions = response.roles;
-        this.bindCompanyOpen = true;
-        this.title = "创建 新增/绑定销售 的二维码";
-      });
+
+      this.bindCompanyOpen = true;
+      this.title = "创建 新增/绑定销售 的二维码";
+
     },
 
     /** 修改按钮操作 */
@@ -1298,6 +1301,28 @@ export default {
       document.body.removeChild(link);
     },
 
+    formBindCompanyChange(){
+
+
+        if (this.formBindCompany.companyId == null) {
+          return this.$message.warning("请选择公司");
+        }
+
+        this.getTreeselectByCompanyId(this.formBindCompany.companyId);
+
+        addInfo(this.formBindCompany.companyId).then((response) => {
+
+          this.formBindCompany.deptId= null;
+          this.formBindCompany.roleIds=[];
+
+          this.postOptions = response.posts;
+          this.roleBindOptions = response.roles;
+
+
+        });
+
+    },
+
     submitBingCompanyForm: function() {
 
       this.$refs["formBindCompany"].validate((valid) => {

+ 118 - 40
src/views/course/courseWatchLog/index.vue

@@ -44,11 +44,23 @@
           @change="handleScheduleTimeChange">
         </el-date-picker>
       </el-form-item>
+<!--      <el-form-item label="创建时间" prop="createTime">-->
+<!--        <el-date-picker v-model="createTime" size="small" style="width: 220px" value-format="yyyy-MM-dd"-->
+<!--                        type="daterange"-->
+<!--                        :required="true"-->
+<!--                        range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" @change="createChange"></el-date-picker>-->
+<!--      </el-form-item>-->
       <el-form-item label="创建时间" prop="createTime">
-        <el-date-picker v-model="createTime" size="small" style="width: 220px" value-format="yyyy-MM-dd"
-                        type="daterange"
-                        :required="true"
-                        range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" @change="createChange"></el-date-picker>
+        <el-date-picker
+          v-model="createTime"
+          type="datetimerange"
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          value-format="yyyy-MM-dd HH:mm:ss"
+          @change="createChange"
+          :default-time="['00:00:00', '23:59:59']"
+        />
       </el-form-item>
       <el-form-item label="最新更新时间" prop="updateTime">
         <el-date-picker v-model="updateTime" size="small" style="width: 220px" value-format="yyyy-MM-dd" type="daterange"
@@ -262,16 +274,38 @@ export default {
 
     setToday(){
       const today = new Date();
-      const todayStr = this.formatDate(today);
-      this.createTime = [todayStr, todayStr];
-      this.queryParams.sTime = todayStr;
-      this.queryParams.eTime = todayStr;
+      const todayStart = new Date(today);
+      todayStart.setHours(0, 0, 0, 0);
+      const todayEnd = new Date(today);
+      todayEnd.setHours(23, 59, 59, 999);
+
+      this.createTime = [this.formatDate(todayStart), this.formatDate(todayEnd)];
+      this.queryParams.sTime = this.formatDate(todayStart);
+      this.queryParams.eTime = this.formatDate(todayEnd);
     },
     formatDate(date) {
-      const year = date.getFullYear();
-      const month = String(date.getMonth() + 1).padStart(2, '0');
-      const day = String(date.getDate()).padStart(2, '0');
-      return `${year}-${month}-${day}`;
+      if (!date) return ''
+
+      // 确保 date 是 Date 对象
+      let dateObj = date
+      if (typeof date === 'string') {
+        dateObj = new Date(date)
+      }
+
+      // 如果转换失败,返回空字符串
+      if (!(dateObj instanceof Date) || isNaN(dateObj.getTime())) {
+        return ''
+      }
+
+      // 使用更安全的格式化方法
+      const year = dateObj.getFullYear()
+      const month = String(dateObj.getMonth() + 1).padStart(2, '0')
+      const day = String(dateObj.getDate()).padStart(2, '0')
+      const hours = String(dateObj.getHours()).padStart(2, '0')
+      const minutes = String(dateObj.getMinutes()).padStart(2, '0')
+      const seconds = String(dateObj.getSeconds()).padStart(2, '0')
+
+      return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
     },
     handleClear(){
       this.queryUserLoading = false;
@@ -311,35 +345,58 @@ export default {
         this.videoList=response.list
       });
     },
-    createChange() {
-      if (this.createTime != null) {
-        const startDate = new Date(this.createTime[0]);
-        const endDate = new Date(this.createTime[1]);
-        const timeDiff = Math.abs(endDate.getTime() - startDate.getTime());
-        const diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24));
-
-        // 限制时间区间为一个月
-        if (diffDays >= 31) {
-          this.$message.warning('创建时间区间不能超过一个月');
+    checkDateRangeLimit(dateRange) {
+      if (dateRange && dateRange.length >= 2) {
+        const startDate = new Date(dateRange[0]);
+        const endDate = new Date(dateRange[1]);
+
+        // 设置时间为当天开始,避免时间部分影响计算
+        startDate.setHours(0, 0, 0, 0);
+        endDate.setHours(0, 0, 0, 0);
+
+        const timeDiff = Math.abs(endDate - startDate);
+        const diffDays = Math.ceil(timeDiff / (1000 * 60 * 60 * 24));
+
+        if (diffDays > 31) { // maxDays-1 因为包含起始日
+          this.$message.warning('时间区间不能超过一个月');
+          return false;
+        }
+      }
+      return true;
+    },
+    createChange(createTime) {
+      if (createTime && createTime.length >= 2) {
+        if(!this.checkDateRangeLimit(createTime)){
           this.createTime = null;
-          this.queryParams.sTime = null;
-          this.queryParams.eTime = null;
+          this.queryParams.sTime=null;
+          this.queryParams.eTime=null;
           return;
         }
 
-        this.queryParams.sTime = this.createTime[0];
-        this.queryParams.eTime = this.createTime[1];
+        // this.createTimeText = this.formatDateRange(createTime);
+        this.queryParams.sTime = this.formatDate(createTime[0]) || null;
+        this.queryParams.eTime = this.formatDate(createTime[1]) || null;
       } else {
+        this.createTimeText = '';
         this.queryParams.sTime = null;
         this.queryParams.eTime = null;
       }
     },
 
-    updateChange(){
-      if (this.updateTime != null) {
-        this.queryParams.upSTime = this.updateTime[0];
-        this.queryParams.upETime = this.updateTime[1];
+    updateChange(updateTime){
+      if (updateTime && updateTime.length >= 2) {
+        if(!this.checkDateRangeLimit(updateTime)){
+          this.updateTime = null;
+          this.queryParams.upSTime=null;
+          this.queryParams.upETime=null;
+          return;
+        }
+
+        // this.updateTime = this.formatDateRange(updateTime);
+        this.queryParams.upSTime = updateTime[0] || null;
+        this.queryParams.upETime = updateTime[1] || null;
       } else {
+        this.updateTime = [];
         this.queryParams.upSTime = null;
         this.queryParams.upETime = null;
       }
@@ -356,9 +413,11 @@ export default {
     /** 查询短链课程看课记录列表 */
     getList() {
 
-      // xgb 看课数据量太大必须限制时间
-      if (!this.createTime) {
-        this.$message.warning('请选择创建时间');
+      // xgb 看课数据量太大必须限制时间if (this.isEmptyArray(this.createTime) &&
+      if (this.isEmptyArray(this.createTime) &&
+        this.isEmptyArray(this.updateTime) &&
+        this.isEmptyArray(this.scheduleTime)) {
+        this.$message.warning('请选择创建时间或营期时间或最新更新时间');
         return;
       }
       this.loading = true;
@@ -370,7 +429,10 @@ export default {
         this.courseWatchLogList = response.rows;
         this.total = response.total;
         this.loading = false;
-      });
+      }).catch(() => {
+          this.loading = false;
+        }
+      );
     },
     // 取消按钮
     cancel() {
@@ -479,10 +541,17 @@ export default {
           this.msgSuccess("删除成功");
         }).catch(() => {});
     },
+    // 添加辅助方法
+    isEmptyArray(arr) {
+      return !arr || arr.length === 0;
+    },
     /** 导出按钮操作 */
     handleExport() {
-      if (!this.createTime) {
-        this.$message.warning('请选择创建时间');
+      // xgb 看课数据量太大必须限制时间
+      if (this.isEmptyArray(this.createTime) &&
+        this.isEmptyArray(this.updateTime) &&
+        this.isEmptyArray(this.scheduleTime)) {
+        this.$message.warning('请选择创建时间或营期时间或最新更新时间');
         return;
       }
       const queryParams = this.queryParams;
@@ -498,11 +567,20 @@ export default {
           this.exportLoading = false;
         }).catch(() => {});
     },
-    handleScheduleTimeChange(val) {
-      if (val) {
-        this.queryParams.scheduleStartTime = val[0];
-        this.queryParams.scheduleEndTime = val[1];
+    handleScheduleTimeChange(scheduleTime) {
+      if (scheduleTime && scheduleTime.length >= 2) {
+        if(!this.checkDateRangeLimit(scheduleTime)){
+          this.scheduleTime = null;
+          this.queryParams.scheduleStartTime=null;
+          this.queryParams.scheduleStartTime=null;
+          return;
+        }
+
+        // this.scheduleTime = this.formatDateRange(scheduleTime);
+        this.queryParams.scheduleStartTime = scheduleTime[0] || null;
+        this.queryParams.scheduleEndTime = scheduleTime[1] || null;
       } else {
+        this.scheduleTime = [];
         this.queryParams.scheduleStartTime = null;
         this.queryParams.scheduleEndTime = null;
       }

+ 184 - 2
src/views/course/userCourse/index.vue

@@ -169,6 +169,14 @@
             v-hasPermi="['course:userCourse:remove']"
           >删除
           </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            v-if="scope.row.isPrivate === 1"
+            v-has-permi="['course:userCourse:editConfig']"
+            @click="configCourse(scope.row)"
+          >过程页配置
+          </el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -275,6 +283,69 @@
       </div>
     </el-dialog>
 
+    <!-- 过程页配置 -->
+    <el-dialog
+      :visible.sync="configDialog.dialogVisible"
+      title="过程页配置"
+      append-to-body
+      width="1200px"
+    >
+      <el-form :model="configDialog.form" :rules="configDialog.rules" ref="configForm" label-width="110px">
+        <el-form-item label="过程页图片" prop="coverImg">
+          <ImageUpload v-model="configDialog.form.coverImg" :height="150" :limit="1" :width="150" type="image"/>
+          <i class="el-icon-warning"/>
+          <span style="color: rgb(153, 169, 191)"> 不配置将使用课程默认图片</span>
+        </el-form-item>
+        <el-form-item label="首播电视台" prop="tvEnable">
+          <el-switch v-model="configDialog.form.tvEnable" active-color="#13ce66"/>
+        </el-form-item>
+        <el-form-item prop="tv" v-if="configDialog.form.tvEnable">
+          <el-input v-model="configDialog.form.tv" clearable></el-input>
+          <i class="el-icon-warning"/>
+          <span style="color: rgb(153, 169, 191)"> 多个首播电视台,请用英文逗号隔开</span>
+        </el-form-item>
+        <el-form-item label="网络播放平台" prop="networkEnable">
+          <el-switch v-model="configDialog.form.networkEnable" active-color="#13ce66"/>
+        </el-form-item>
+        <el-form-item prop="network" v-if="configDialog.form.networkEnable">
+          <el-input v-model="configDialog.form.network" clearable></el-input>
+          <i class="el-icon-warning"/>
+          <span style="color: rgb(153, 169, 191)"> 多个网络播放平台,请用英文逗号隔开</span>
+        </el-form-item>
+        <el-form-item label="制作单位" prop="unitEnable">
+          <el-switch v-model="configDialog.form.unitEnable" active-color="#13ce66"/>
+        </el-form-item>
+        <el-form-item prop="unit" v-if="configDialog.form.unitEnable">
+          <el-input v-model="configDialog.form.unit" clearable></el-input>
+          <i class="el-icon-warning"/>
+          <span style="color: rgb(153, 169, 191)"> 多个制作单位,请用英文逗号隔开</span>
+        </el-form-item>
+        <el-form-item label="专家顾问团队" prop="teamEnable">
+          <el-switch v-model="configDialog.form.teamEnable" active-color="#13ce66"/>
+        </el-form-item>
+        <el-form-item prop="team" v-if="configDialog.form.teamEnable">
+          <el-input v-model="configDialog.form.team" clearable></el-input>
+          <i class="el-icon-warning"/>
+          <span style="color: rgb(153, 169, 191)"> 多个专家顾问,请用英文逗号隔开</span>
+        </el-form-item>
+        <el-form-item label="支持单位" prop="supportEnable">
+          <el-switch v-model="configDialog.form.supportEnable" active-color="#13ce66"/>
+        </el-form-item>
+        <el-form-item prop="support" v-if="configDialog.form.supportEnable">
+          <el-input v-model="configDialog.form.support" clearable></el-input>
+          <i class="el-icon-warning"/>
+          <span style="color: rgb(153, 169, 191)"> 多个支持单位,请用英文逗号隔开</span>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary"
+                   :loading="configDialog.updating"
+                   :disabled="configDialog.updating"
+                   @click="submitConfigForm">确 定</el-button>
+        <el-button @click="cancelConfig">取 消</el-button>
+      </div>
+    </el-dialog>
+
     <el-drawer
       :with-header="false"
       size="75%"
@@ -295,7 +366,8 @@ import {
   updateIsShow,
   copyUserCourse,
   putOn,
-  pullOff, updateUserCourseRedPage
+  pullOff, updateUserCourseRedPage,
+  editConfig
 } from '@/api/course/userCourse'
 
 import {getSelectableRange} from "@/api/qw/sopTemp";
@@ -445,6 +517,41 @@ export default {
         redPacketMoney: [
           {required: true, message: "红包金额不能为空", trigger: "blur"}
         ],
+      },
+      configDialog: {
+        dialogVisible: false,
+        updating: false,
+        form: {
+          id: null,
+          coverImg: null,
+          tvEnable: 0,
+          tv: null,
+          networkEnable: 0,
+          network: null,
+          unitEnable: 0,
+          unit: null,
+          teamEnable: 0,
+          team: null,
+          supportEnable: 0,
+          support: null
+        },
+        rules: {
+          tv: [
+            { required: true, message: '首播电视台不能为空', trigger: 'blur' }
+          ],
+          network: [
+            { required: true, message: '网络播放平台不能为空', trigger: 'blur' }
+          ],
+          unit: [
+            { required: true, message: '制作单位不能为空', trigger: 'blur' }
+          ],
+          team: [
+            { required: true, message: '专家顾问团队不能为空', trigger: 'blur' }
+          ],
+          support: [
+            { required: true, message: '支持单位不能为空', trigger: 'blur' }
+          ],
+        }
       }
     };
   },
@@ -802,7 +909,82 @@ export default {
         this.msgSuccess("下架成功");
       }).catch(function () {
       });
-    }
+    },
+    configCourse(row) {
+      if (row.configJson) {
+        this.configDialog.form = {
+          tvEnable: 0,
+          networkEnable: 0,
+          unitEnable: 0,
+          teamEnable: 0,
+          supportEnable: 0,
+          ...JSON.parse(row.configJson)
+        }
+      }
+      this.configDialog.form.id = row.courseId
+      this.configDialog.dialogVisible = true;
+      this.configDialog.updating = false
+    },
+    submitConfigForm() {
+      this.$refs['configForm'].validate(valid => {
+        if (!valid) {
+          this.msgError('请完善配置内容')
+          return
+        }
+
+        if (this.configDialog.updating) {
+          return
+        }
+        this.configDialog.updating = true
+
+        const content = {
+          coverImg: this.configDialog.form.coverImg,
+          tvEnable: this.configDialog.form.tvEnable,
+          tv: this.configDialog.form.tv?.replace(",",","),
+          networkEnable: this.configDialog.form.networkEnable,
+          network: this.configDialog.form.network?.replace(",",","),
+          unitEnable: this.configDialog.form.unitEnable,
+          unit: this.configDialog.form.unit?.replace(",",","),
+          teamEnable: this.configDialog.form.teamEnable,
+          team: this.configDialog.form.team?.replace(",",","),
+          supportEnable: this.configDialog.form.supportEnable,
+          support: this.configDialog.form.support?.replace(",",","),
+        }
+
+        const params = {
+          id: this.configDialog.form.id,
+          configJson: JSON.stringify(content)
+        }
+
+        editConfig(params).then(() => {
+          this.msgSuccess('修改成功')
+          this.configDialog.dialogVisible = false;
+          this.getList()
+        }).finally(() => {
+          setTimeout(() => {
+            this.configDialog.updating = false
+          }, 500)
+        })
+      })
+    },
+    cancelConfig() {
+      this.configDialog.form = {
+        id: null,
+        coverImg: null,
+        tvEnable: 0,
+        tv: null,
+        networkEnable: 0,
+        network: null,
+        unitEnable: 0,
+        unit: null,
+        teamEnable: 0,
+        team: null,
+        supportEnable: 0,
+        support: null
+      }
+      this.resetForm('configForm')
+      this.configDialog.dialogVisible = false;
+    },
   }
 };
 </script>