Prechádzať zdrojové kódy

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

caoliqin 1 mesiac pred
rodič
commit
dd53390cb4

+ 4 - 0
.env.prod-cfryt

@@ -26,6 +26,10 @@ VUE_APP_COS_REGION = ap-chongqing
 VUE_APP_VIDEO_LINE_1 = https://ryttcpv.ylrzcloud.com
 # 线路二地址
 VUE_APP_VIDEO_LINE_2 = https://cfrytobs.ylrztop.com
+#火山云视频地址域名
+VUE_APP_VIDEO_URL = https://rytvolcengine.ylrztop.com
+#火山云视频点播空间名
+VUE_APP_HSY_SPACE = ryt-2114522511
 
 # 开发环境配置
 ENV = 'production'

+ 4 - 0
.env.prod-hat

@@ -26,6 +26,10 @@ VUE_APP_COS_REGION = ap-chongqing
 VUE_APP_VIDEO_LINE_1 = https://hattcpv.ylrzcloud.com
 # 线路二地址
 VUE_APP_VIDEO_LINE_2 = https://hatobs.ylrztop.com
+#火山云视频地址域名
+VUE_APP_VIDEO_URL = https://hatvolcengine.ylrztop.com
+#火山云视频点播空间名
+VUE_APP_HSY_SPACE = hat-2114522511
 
 # 开发环境配置
 ENV = 'development'

+ 3 - 0
.env.prod-heyantang

@@ -38,3 +38,6 @@ VUE_APP_COURSE_DEFAULT = 2
 
 # 路由懒加载
 VUE_CLI_BABEL_TRANSPILE_MODULES = true
+
+
+VUE_APP_LIVE_WS_URL = wss://liveapp.yytcdta.com/ws

+ 4 - 0
.env.prod-hsyy

@@ -26,6 +26,10 @@ VUE_APP_COS_REGION = ap-chongqing
 VUE_APP_VIDEO_LINE_1 = https://heshanyytcpv.ylrzcloud.com
 # 线路二地址
 VUE_APP_VIDEO_LINE_2 = https://hsyyobs.ylrztop.com
+#火山云视频地址域名
+VUE_APP_VIDEO_URL = https://heshanyyvolcengine.ylrztop.com
+#火山云视频点播空间名
+VUE_APP_HSY_SPACE = heshanyy-2114522511
 
 # 开发环境配置
 ENV = 'production'

+ 4 - 0
.env.prod-jnlzjk

@@ -26,6 +26,10 @@ VUE_APP_COS_REGION = ap-chongqing
 VUE_APP_VIDEO_LINE_1 = https://jnlzjktcpv.ylrzcloud.com
 # 线路二地址
 VUE_APP_VIDEO_LINE_2 = https://jnlzjkobs.ylrztop.com
+#火山云
+VUE_APP_VIDEO_URL = https://jnlzjkvolcengine.ylrztop.com
+#火山云
+VUE_APP_HSY_SPACE = lzjk-2114522511
 
 # 开发环境配置
 ENV = 'production'

+ 5 - 0
.env.prod-jnmy

@@ -27,6 +27,11 @@ VUE_APP_VIDEO_LINE_1 = https://jnmytcpv.ylrzcloud.com
 # 线路二地址
 VUE_APP_VIDEO_LINE_2 = https://jnmyobs.ylrztop.com
 
+#火山云视频地址域名
+VUE_APP_VIDE0_URL = https://cdjnmyvolcengine.ylrztop.com
+#火山云视频点播空间名
+VUE_APP_HSY_SPACE = cdjnmy-2114522511
+
 # 开发环境配置
 ENV = 'development'
 

+ 4 - 0
.env.prod-myhk

@@ -26,6 +26,10 @@ VUE_APP_COS_REGION = ap-chongqing
 VUE_APP_VIDEO_LINE_1 = https://myhktcpv.ylrzcloud.com
 # 线路二地址
 VUE_APP_VIDEO_LINE_2 = https://myhkobs.ylrztop.com
+#火山云视频地址域名
+VUE_APP_VIDEO_URL = https://myhkvolcengine.ylrztop.com
+#火山云视频点播空间名
+VUE_APP_HSY_SPACE = myhk-2114522511
 
 # 开发环境配置
 ENV = 'production'

+ 4 - 1
.env.prod-qdtst

@@ -26,7 +26,10 @@ VUE_APP_COS_REGION = ap-chongqing
 VUE_APP_VIDEO_LINE_1 = https://qdtsttcpv.ylrzcloud.com
 # 线路二地址
 VUE_APP_VIDEO_LINE_2 = https://qdtstobs.ylrztop.com
-
+#火山云视频地址域名
+VUE_APP_VIDEO_URL = https://qdtstvolcengine.ylrztop.com
+#火山云视频点播空间名
+VUE_APP_HSY_SPACE = qdtst-2114522511
 # 开发环境配置
 ENV = 'development'
 

+ 40 - 0
.env.prod-shdn

@@ -0,0 +1,40 @@
+# 页面标题
+VUE_APP_TITLE =互联网医院管理系统
+# 首页菜单标题
+VUE_APP_TITLE_INDEX =宽益堂管理系统
+# 公司名称
+VUE_APP_COMPANY_NAME =重庆云联融智科技有限公司
+# ICP备案号
+VUE_APP_ICP_RECORD =渝ICP备2024031984号-1
+# ICP网站访问地址
+VUE_APP_ICP_URL =https://beian.miit.gov.cn
+# 网站LOG
+VUE_APP_LOG_URL =@/assets/logo/kyt.jpg
+# 存储桶配置
+VUE_APP_OBS_ACCESS_KEY_ID = K2UTJGIN7UTZJR2XMXYG
+# 存储桶配置
+VUE_APP_OBS_SECRET_ACCESS_KEY = sbyeNJLbcYmH6copxeFP9pAoksM4NIT9Zw4x0SRX
+# 存储桶配置
+VUE_APP_OBS_SERVER = https://obs.cn-north-4.myhuaweicloud.com
+# 存储桶配置
+VUE_APP_OBS_BUCKET = kyt-hw079058881
+# 存储桶配置
+VUE_APP_COS_BUCKET = kyt-1323137866
+# 存储桶配置
+VUE_APP_COS_REGION = ap-chongqing
+# 线路一地址
+VUE_APP_VIDEO_LINE_1 = https://kyttcpv.ylrzcloud.com
+# 线路二地址
+VUE_APP_VIDEO_LINE_2 = https://kytobs.ylrztop.com
+
+# 开发环境配置
+ENV = 'development'
+
+# FS管理系统/开发环境
+VUE_APP_BASE_API = '/prod-api'
+
+#默认 1、会员 2、企微
+VUE_APP_COURSE_DEFAULT = 2
+
+# 路由懒加载
+VUE_CLI_BABEL_TRANSPILE_MODULES = true

+ 4 - 0
.env.prod-sxjz

@@ -26,6 +26,10 @@ VUE_APP_COS_REGION = ap-chongqing
 VUE_APP_VIDEO_LINE_1 = https://sxjztcpv.ylrzcloud.com
 # 线路二地址
 VUE_APP_VIDEO_LINE_2 = https://sxjzobs.ylrztop.com
+#火山云视频地址域名
+VUE_APP_VIDEO_URL = https://sxjzvolcengine.ylrztop.com
+#火山云视频点播空间名
+VUE_APP_HSY_SPACE = sxjz-2114522511
 
 # 开发环境配置
 ENV = 'development'

+ 4 - 0
.env.prod-syysy

@@ -26,6 +26,10 @@ VUE_APP_COS_REGION = ap-chongqing
 VUE_APP_VIDEO_LINE_1 = https://syysytcpv.ylrzcloud.com
 # 线路二地址
 VUE_APP_VIDEO_LINE_2 = https://syysyobs.ylrztop.com
+#火山云视频地址域名
+VUE_APP_VIDEO_URL = https://syysyvolcengine.ylrztop.com
+#火山云视频点播空间名
+VUE_APP_HSY_SPACE = syysy-2114522511
 
 # 开发环境配置
 ENV = 'development'

+ 4 - 1
.env.prod-yxj

@@ -26,7 +26,10 @@ VUE_APP_COS_REGION = ap-chongqing
 VUE_APP_VIDEO_LINE_1 = https://yxjtcpv.ylrzcloud.com
 # 线路二地址
 VUE_APP_VIDEO_LINE_2 = https://whyxjobs.ylrztop.com
-
+#火山云视频地址域名
+VUE_APP_VIDEO_URL = https://whyxjvolcengine.ylrztop.com
+#火山云视频点播空间名
+VUE_APP_HSY_SPACE = whyxj-2114522511
 # 开发环境配置
 ENV = 'development'
 

+ 2 - 0
package.json

@@ -54,6 +54,7 @@
     "build:prod-cfryt": "vue-cli-service build --mode prod-cfryt",
     "build:prod-hsyy": "vue-cli-service build --mode prod-hsyy",
     "build:prod-jnsyj": "vue-cli-service build --mode prod-jnsyj",
+    "build:prod-shdn": "vue-cli-service build --mode prod-shdn",
     "preview": "node build/index.js --preview",
     "lint": "eslint --ext .js,.vue src"
   },
@@ -104,6 +105,7 @@
     "quill": "1.3.7",
     "screenfull": "5.0.2",
     "sortablejs": "1.10.2",
+    "tt-uploader": "^1.5.5",
     "vod-js-sdk-v6": "^1.7.0",
     "vue": "2.6.12",
     "vue-baidu-map": "^0.21.22",

+ 9 - 1
src/api/live/live.js

@@ -157,4 +157,12 @@ export function getTagsListByCorpId(qwTagGroup) {
     method: 'get',
     params:qwTagGroup
   })
-}
+}
+
+// 清除直播间缓存
+export function clearLiveCache(liveId) {
+  return request({
+    url: '/live/live/clearCache/' + liveId,
+    method: 'post'
+  })
+}

+ 8 - 0
src/api/qw/friendWelcome.js

@@ -8,3 +8,11 @@ export function listFriendWelcome(query) {
     params: query
   })
 }
+
+// 查询好友欢迎语详细
+export function getFriendWelcome(id) {
+  return request({
+    url: '/qw/friendWelcome/' + id,
+    method: 'get'
+  })
+}

+ 3 - 0
src/views/course/courseRedPacketLog/index.vue

@@ -148,6 +148,7 @@
       <el-table-column type="selection" width="55" align="center" />
 <!--      <el-table-column label="记录编号" align="center" prop="logId" />-->
       <el-table-column label="批次单号" align="center" prop="outBatchNo" />
+      <el-table-column label="营期名称" align="center" prop="periodName" />
       <el-table-column label="课程名称" align="center" prop="courseId" >
         <template slot-scope="scope">
           <span prop="status" v-for="(item, index) in courseLists"    v-if="scope.row.courseId==item.dictValue">{{item.dictLabel}}</span>
@@ -215,6 +216,8 @@
 <script>
 import { courseList,videoList,getCourseRedPacketLog, delCourseRedPacketLog, addCourseRedPacketLog, updateCourseRedPacketLog, exportCourseRedPacketLog,listCourseRedPacketLogPage } from "@/api/course/courseRedPacketLog";
 import { getCompanyList } from "@/api/company/company";
+import { periodList } from "@/api/course/userCoursePeriod";
+import {treeselect} from "../../../api/company/companyDept";
 import SelectTree from '@/components/TreeSelect/index.vue'
 import { getDeptData } from '@/api/system/employeeStats'
 

+ 4 - 4
src/views/course/fsCourseProductOrder/index.vue

@@ -490,14 +490,14 @@ export default {
     handleDecodeExport() {
       if (this.payDateRange && this.payDateRange.length === 2) {
         this.queryParams.payStartTime = this.payDateRange[0];
-        this.queryParams.payEndTime = this.payDateRange[1];
+        this.queryParams.payEndTime = this.payDateRange[1].substring(0,10)+" 23:59:59";
       } else {
         this.queryParams.payStartTime = null;
         this.queryParams.payEndTime = null;
       }
       if (this.refundDateRange && this.refundDateRange.length === 2) {
         this.queryParams.refundStartTime = this.refundDateRange[0];
-        this.queryParams.refundEndTime = this.refundDateRange[1];
+        this.queryParams.refundEndTime = this.refundDateRange[1].substring(0,10)+" 23:59:59";
       } else {
         this.queryParams.refundStartTime = null;
         this.queryParams.refundEndTime = null;
@@ -519,14 +519,14 @@ export default {
     handleExport() {
       if (this.payDateRange && this.payDateRange.length === 2) {
         this.queryParams.payStartTime = this.payDateRange[0];
-        this.queryParams.payEndTime = this.payDateRange[1];
+        this.queryParams.payEndTime = this.payDateRange[1].substring(0,10)+" 23:59:59";
       } else {
         this.queryParams.payStartTime = null;
         this.queryParams.payEndTime = null;
       }
       if (this.refundDateRange && this.refundDateRange.length === 2) {
         this.queryParams.refundStartTime = this.refundDateRange[0];
-        this.queryParams.refundEndTime = this.refundDateRange[1];
+        this.queryParams.refundEndTime = this.refundDateRange[1].substring(0,10)+" 23:59:59";
       } else {
         this.queryParams.refundStartTime = null;
         this.queryParams.refundEndTime = null;

+ 24 - 3
src/views/course/videoResource/index.vue

@@ -550,7 +550,7 @@
           </el-form-item>
 
           <el-form-item label="子分类" prop="typeSubId" :rules="[{ required: true, message: '请选择子分类', trigger: 'blur' }]">
-            <el-select v-model="batchUploadForm.typeSubId" clearable placeholder="请选择子分类" style="width: 100%">
+            <el-select v-model="batchUploadForm.typeSubId" clearable placeholder="请选择子分类" style="width: 100%" @change="changeSubType">
               <el-option
                 v-for="item in subTypeList"
                 :key="item.dictValue"
@@ -560,7 +560,7 @@
             </el-select>
           </el-form-item>
 
-          <el-form-item label="关联题目" prop="projectIds" style="display: none">
+          <el-form-item label="关联题目" prop="projectIds" v-show="currentProject === 'myhk'">
             <el-select
               ref="customSelect"
               class="custom-select-class"
@@ -1168,6 +1168,9 @@ export default {
       }
       if (type === 3) {
         this.batchUploadForm.typeSubId = null
+        if (this.currentProject === 'myhk') {
+          this.batchUploadForm.projectIds = []
+        }
       }
       this.subTypeList = []
       if (!val) {
@@ -1177,6 +1180,25 @@ export default {
         this.subTypeList = response.data
       })
     },
+    changeSubType(val) {
+      if (this.currentProject !== 'myhk') {
+        return
+      }
+      this.projectShowList = []
+      this.batchUploadForm.projectIds = []
+      listCourseQuestionBank({questionSubType: val}).then(async response => {
+        const projectIds = response.rows.map(item => item.id)
+
+        // 如果存在关联项目,获取项目详情用于回显
+        if (projectIds && projectIds.length > 0) {
+          // 加载项目列表信息用于回显
+          await getByIds({ids: projectIds.join(',')}).then(reponse => {
+            this.projectShowList = reponse.data
+            this.batchUploadForm.projectIds = projectIds
+          });
+        }
+      })
+    },
     /** 预览视频 */
     handleVideoPreview(url) {
       this.videoPreviewVisible = true;
@@ -1732,7 +1754,6 @@ export default {
       if (this.currentProject === 'myhk') {
         this.batchUploadForm = {
           ...this.batchUploadForm,
-          projectIds: [],
           files: []
         };
       } else {

+ 19 - 0
src/views/his/company/index.vue

@@ -140,6 +140,13 @@
           </el-tag>
         </template>
       </el-table-column>
+      <!--  看课休息    -->
+      <el-table-column label="看课休息开关" align="center" prop="isOpenRestReminder">
+        <template slot-scope="scope">
+          <el-tag v-if="scope.row.isOpenRestReminder==1" type="success">开启</el-tag>
+          <el-tag v-if="scope.row.isOpenRestReminder==0" type="success">关闭</el-tag>
+        </template>
+      </el-table-column>
       <el-table-column label="备注" align="center" prop="remark"/>
       <el-table-column label="开始时间" align="center" prop="startTime" width="180"/>
       <el-table-column label="到期时间" align="center" prop="limitTime" width="180"/>
@@ -456,6 +463,17 @@
             />
           </el-select>
         </el-form-item>
+        <el-form-item label="看课休息开关" >
+          <el-radio-group v-model="form.isOpenRestReminder">
+            <el-radio :label="1" >开</el-radio>
+            <el-radio :label="0">关</el-radio>
+          </el-radio-group>
+          <span>(默认为空,走系统配置)</span>
+        </el-form-item>
+
+
+
+
         <el-form-item label="备注" prop="remark">
           <el-input v-model="form.remark" type="textarea" :rows="2" placeholder="请输入备注"/>
         </el-form-item>
@@ -1140,6 +1158,7 @@ export default {
         groupName: null,
         userId: null,
         remark: null,
+        isOpenRestReminder: null,
         linkName: null,
         limitUserCount: null,
         maxPadNum: -1,

+ 2 - 0
src/views/hisStore/integralGoods/index.vue

@@ -417,6 +417,8 @@ export default {
         descs: null,
         createTime: null
       };
+      this.imageArr = [];
+      this.photoArr = [];
       this.resetForm("form");
     },
     /** 搜索按钮操作 */

+ 2 - 2
src/views/hisStore/storeOrder/index.vue

@@ -129,10 +129,10 @@
           @keyup.enter.native="handleQuery"/>
       </el-form-item>
 
-      <el-form-item label="员工姓名" prop="companyUserNickName">
+      <el-form-item label="销售名称" prop="companyUserNickName">
         <el-input
           v-model="queryParams.companyUserNickName"
-          placeholder="请输入员工姓名"
+          placeholder="请输入销售名称"
           clearable
           size="small"
           @keyup.enter.native="handleQuery"

+ 47 - 4
src/views/live/live/index.vue

@@ -200,6 +200,12 @@
       @selection-change="handleSelectionChange"
     >
       <el-table-column type="selection" width="55"></el-table-column>
+      <el-table-column
+        label="直播ID"
+        align="center"
+        prop="liveId"
+        width="100"
+      />
       <el-table-column
         label="直播封面"
         align="center"
@@ -303,6 +309,14 @@
             v-hasPermi="['live:console:list']"
             >进入直播间</el-button
           >
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleClearCache(scope.row)"
+            v-hasPermi="['live:live:edit']"
+            >清理缓存</el-button
+          >
           <el-dropdown trigger="hover">
             <el-button size="mini" type="text" icon="el-icon-more">
               更多
@@ -388,8 +402,13 @@
         </el-form-item>
         <el-form-item label="直播类型" prop="liveType">
           <el-radio-group v-model="form.liveType">
-            <!--            <el-radio :label="1">直播</el-radio>-->
-            <el-radio :label="2">录播</el-radio>
+            <el-radio
+              v-for="item in liveTypeDictList"
+              :key="item.dictValue"
+              :label="parseInt(item.dictValue)"
+            >
+              {{ item.dictLabel }}
+            </el-radio>
           </el-radio-group>
         </el-form-item>
         <!--        <el-form-item label="直播达人" prop="talentId">-->
@@ -665,6 +684,7 @@ import {
   getCompanyDropList,
   getQwCorpList,
   getTagsListByCorpId,
+  clearLiveCache,
 } from "@/api/live/live";
 import Editor from "@/components/Editor/wang";
 import user from "@/store/modules/user";
@@ -675,6 +695,7 @@ export default {
   components: { Editor, VideoUpload },
   data() {
     return {
+      liveTypeDictList: [],
       currentCheck:null,
       currentCheckTagIndex:null,
       lastCheckTagRow:null,
@@ -798,6 +819,10 @@ export default {
     this.getDicts("live_mark_type").then((response) => {
       this.markTypeDropList = response.data;
     });
+    // 新增:获取直播类型字典
+    this.getDicts("live_type").then((response) => {
+      this.liveTypeDictList = response.data;
+    });
   },
   watch: {
     "form.startTime": {
@@ -1127,8 +1152,8 @@ export default {
         }else{
           for(let index =0 ;index<this.form.liveTagList.length;index ++){
             this.form.liveTagList[index].markType = this.form.liveTagList[index].markType +"";
-            this.selectCompanyChange(this.form.liveTagList[index],index); 
-          }           
+            this.selectCompanyChange(this.form.liveTagList[index],index);
+          }
         }
         setTimeout(() => {
           if (this.form.liveDesc == null) {
@@ -1289,6 +1314,24 @@ export default {
         })
         .catch(() => {});
     },
+    /** 清理缓存按钮操作 */
+    handleClearCache(row) {
+      this.$confirm("是否确认清理该直播间的缓存?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          clearLiveCache(row.liveId).then((response) => {
+            if (response.code === 200) {
+              this.msgSuccess("缓存清理成功");
+            } else {
+              this.msgError(response.msg || "缓存清理失败");
+            }
+          });
+        })
+        .catch(() => {});
+    },
     /** 导出按钮操作 */
     handleExport() {
       const queryParams = this.queryParams;

+ 15 - 15
src/views/live/liveConsole/LiveConsole.vue

@@ -149,11 +149,11 @@
           <div style="height: 20px;"></div>
           </el-scrollbar>
           <!-- 加载最新消息按钮 -->
-          <el-button 
-            v-if="showLoadLatestBtn" 
-            class="load-latest-btn" 
-            type="primary" 
-            size="small" 
+          <el-button
+            v-if="showLoadLatestBtn"
+            class="load-latest-btn"
+            type="primary"
+            size="small"
             @click.stop="loadLatestMessages"
             :disabled="isLoadingLatest"
             :loading="isLoadingLatest"
@@ -474,7 +474,7 @@ export default {
           const clientHeight = wrap.clientHeight;
           const currentScrollTop = wrap.scrollTop;
           const maxScrollTop = scrollHeight - clientHeight;
-          
+
           if (currentScrollTop < maxScrollTop - 50) {
             this.showLoadLatestBtn = true;
           }
@@ -487,17 +487,17 @@ export default {
       if (!this.isAutoScrollEnabled && !forceScroll) {
         return;
       }
-      
+
       if (this.$refs.manageRightRef && this.$refs.manageRightRef.wrap) {
         this.$nextTick(() => {
           const wrap = this.$refs.manageRightRef.wrap;
           if (!wrap) return;
-          
+
           const scrollHeight = wrap.scrollHeight;
           const clientHeight = wrap.clientHeight;
           const currentScrollTop = wrap.scrollTop;
           const maxScrollTop = scrollHeight - clientHeight;
-          
+
           // 强制滚动或启用自动滚动时,直接滚动到底部并隐藏按钮
           if (forceScroll || this.isAutoScrollEnabled) {
             this.showLoadLatestBtn = false;
@@ -811,7 +811,7 @@ export default {
             }
             if (res.data.liveType == 1) {
               this.videoParam.livingUrl = res.data.flvHlsUrl
-              this.videoParam.livingUrl = this.livingUrl.replace("flv","m3u8")
+              this.videoParam.livingUrl = this.videoParam.livingUrl.replace("flv","m3u8")
               // this.$nextTick(() => {
               //   this.initPlayer()
               // })
@@ -1191,7 +1191,7 @@ export default {
             setTimeout(() => {
               // 重置加载状态
               this.isLoadingLatest = false;
-              
+
               if (this.isAutoScrollEnabled) {
                 // 如果启用自动滚动,强制滚动到底部并隐藏按钮
                 this.scrollToBottom(true);
@@ -1203,7 +1203,7 @@ export default {
                   const clientHeight = wrap.clientHeight;
                   const currentScrollTop = wrap.scrollTop;
                   const maxScrollTop = scrollHeight - clientHeight;
-                  
+
                   if (currentScrollTop < maxScrollTop - 50) {
                     this.showLoadLatestBtn = true;
                   } else {
@@ -1229,11 +1229,11 @@ export default {
       if (this.scrollDebounceTimer) {
         clearTimeout(this.scrollDebounceTimer);
       }
-      
+
       // 设置防抖,300ms内只执行一次
       this.scrollDebounceTimer = setTimeout(() => {
         this.saveChatScrollPosition();
-        
+
         // 检查是否滚动到底部
         if (this.$refs.manageRightRef && this.$refs.manageRightRef.wrap) {
           const wrap = this.$refs.manageRightRef.wrap;
@@ -1241,7 +1241,7 @@ export default {
           const clientHeight = wrap.clientHeight;
           const currentScrollTop = wrap.scrollTop;
           const maxScrollTop = scrollHeight - clientHeight;
-          
+
           // 如果滚动到底部(距离底部小于50px),隐藏按钮并恢复自动滚动
           if (currentScrollTop >= maxScrollTop - 50) {
             this.showLoadLatestBtn = false;

+ 170 - 57
src/views/live/liveConsole/LivePlayer.vue

@@ -1,7 +1,22 @@
 <template>
   <div class="live-player">
-    <video ref="videoPlayer" loop autoplay class="player">
-      <source :src="videoParam.videoUrl" type="application/x-mpegURL">
+    <!-- 修改:所有录播和回放都使用同一个video元素,MP4和HLS都支持 -->
+    <video
+      v-if="videoParam.liveType == 2 || videoParam.liveType == 3"
+      ref="videoPlayer"
+      :loop="videoParam.liveType == 2"
+      autoplay
+      class="player"
+    >
+      <!-- 去掉type,让浏览器自动检测 -->
+    </video>
+
+    <video
+      v-if="videoParam.liveType == 1"
+      ref="livePlayer"
+      autoplay
+      class="player"
+    >
     </video>
   </div>
 </template>
@@ -25,23 +40,33 @@ export default {
   },
   data() {
     return {
-      videoDuration: 0, // 视频总时长(秒)
-      startTime: 0, // 开播时间戳(毫秒)
-      hls: null, // HLS 实例
+      videoDuration: 0,
+      startTime: 0,
+      hls: null,
+      liveHls: null // 分开管理直播和录播的HLS实例
     };
   },
   mounted() {
-
-    // 这里可以添加播放器初始化逻辑
+    this.initPlayer();
   },
   methods: {
     videoPlay(url) {
-      if (Hls.isSupported()) {
-        const videoElement = this.$refs.videoPlayer
-        if (!videoElement) {
-          console.error('找不到 video 元素')
-          return
-        }
+      const videoElement = this.$refs.videoPlayer;
+      if (!videoElement) {
+        console.error('找不到 video 元素');
+        return;
+      }
+
+      // 判断是否是MP4格式
+      const isMp4 = url.toLowerCase().endsWith('.mp4') ||
+        url.toLowerCase().includes('.mp4?');
+
+      // 判断是否是HLS格式(m3u8)
+      const isHls = url.toLowerCase().endsWith('.m3u8') ||
+        url.toLowerCase().includes('.m3u8?');
+
+      if (isHls && Hls.isSupported()) {
+        // HLS格式使用hls.js播放
         this.hls = new Hls();
         this.hls.attachMedia(videoElement);
         this.hls.on(Hls.Events.MEDIA_ATTACHED, () => {
@@ -53,80 +78,165 @@ export default {
         this.hls.on(Hls.Events.ERROR, (event, data) => {
           console.error('HLS 错误:', data);
         });
-        // 1. 初始化开播时间
-        this.startTime = new Date(this.videoParam.startTime).getTime();
+
+        // 录播的时间位置计算
         if (this.videoParam.liveType === 2) {
-          // 2. 监听视频元数据加载完成(获取视频时长)
           videoElement.addEventListener('loadedmetadata', () => {
-            this.videoDuration = videoElement.duration; // 获取视频时长(秒)
-
-            // 初始化视频播放位置
+            this.videoDuration = videoElement.duration;
             this.updateVideoPosition(videoElement);
+          });
+        }
 
+      } else if (isMp4 || !isHls) {
+        // MP4格式或非HLS格式直接使用video元素播放
+        videoElement.src = url;
+
+        // 录播的时间位置计算
+        if (this.videoParam.liveType === 2) {
+          videoElement.addEventListener('loadedmetadata', () => {
+            this.videoDuration = videoElement.duration;
+            this.updateVideoPosition(videoElement);
           });
         }
+
+        // 触发播放
+        videoElement.load();
+        videoElement.play().catch(e => {
+          console.warn('自动播放失败:', e);
+        });
+
       } else {
-        console.error('浏览器不支持 HLS')
+        // 不支持HLS的浏览器,尝试直接播放
+        console.warn('浏览器不支持HLS,尝试直接播放');
+        videoElement.src = url;
+        videoElement.load();
+        videoElement.play().catch(e => {
+          console.warn('播放失败:', e);
+        });
       }
     },
-    updateVideoPosition(video){
-      const currentTime = new Date().getTime(); // 当前时间戳(毫秒)
-      const elapsedTime = currentTime - this.startTime; // 已流逝时间(毫秒)
+
+    updateVideoPosition(video) {
+      const currentTime = new Date().getTime();
+      this.startTime = new Date(this.videoParam.startTime).getTime();
+      const elapsedTime = currentTime - this.startTime;
+
       if (elapsedTime < 0) {
-        // 未开播:视频停在初始位置
         video.currentTime = 0;
         return;
       }
 
-      // 已开播:计算视频循环后的位置(流逝时间 % 视频时长)
-      const elapsedSeconds = elapsedTime / 1000; // 转换为秒
-      // 视频内的播放位置(秒)
-      // 设置视频播放位置
-      video.currentTime = elapsedSeconds % this.videoDuration;
+      const elapsedSeconds = elapsedTime / 1000;
+      if (this.videoDuration > 0) {
+        video.currentTime = elapsedSeconds % this.videoDuration;
+      }
+    },
+
+    livePlay(url) {
+      if (Hls.isSupported()) {
+        const videoElement = this.$refs.livePlayer;
+        if (!videoElement) {
+          console.error('找不到 video 元素');
+          return;
+        }
+
+        this.liveHls = new Hls();
+        this.liveHls.attachMedia(videoElement);
+        this.liveHls.on(Hls.Events.MEDIA_ATTACHED, () => {
+          this.liveHls.loadSource(url);
+          this.liveHls.on(Hls.Events.STREAM_LOADED, (event, data) => {
+            videoElement.play();
+          });
+        });
+        this.liveHls.on(Hls.Events.ERROR, (event, data) => {
+          console.error('HLS 错误:', data);
+        });
+
+      } else {
+        // 浏览器原生支持HLS(如Safari)
+        const videoElement = this.$refs.livePlayer;
+        if (videoElement.canPlayType('application/vnd.apple.mpegurl')) {
+          videoElement.src = url;
+          videoElement.play().catch(e => {
+            console.warn('自动播放失败:', e);
+          });
+        } else {
+          console.error('浏览器不支持 HLS');
+        }
+      }
     },
+
     initPlayer() {
+      // 清理之前的实例
+      if (this.hls) {
+        this.hls.destroy();
+        this.hls = null;
+      }
+      if (this.liveHls) {
+        this.liveHls.destroy();
+        this.liveHls = null;
+      }
 
       if (this.videoParam.liveType === 1) {
         // 直播
         const isUrl = this.videoParam.livingUrl === null || this.videoParam.livingUrl.trim() === '';
         if (isUrl) {
-          console.error('直播地址为空,无法初始化播放器')
-          return
+          console.error('直播地址为空,无法初始化播放器');
+          return;
         }
-        this.videoPlay(this.videoParam.livingUrl);
+        this.$nextTick(() => {
+          this.livePlay(this.videoParam.livingUrl);
+        });
         return;
       }
-      const viUrl = this.videoParam.videoUrl === null || this.videoParam.videoUrl.trim() === ''
+
+      const viUrl = this.videoParam.videoUrl === null || this.videoParam.videoUrl.trim() === '';
       if (viUrl) {
-        console.error('播放地址为空,无法初始化播放器')
-        return
+        console.error('播放地址为空,无法初始化播放器');
+        return;
       }
-      if(this.videoParam.liveType === 2){
-        // 录播
-        this.videoPlay(this.videoParam.videoUrl);
-      } else if(this.videoParam.liveType === 3){
-        // 直播回放
-        this.videoPlay(this.videoParam.videoUrl);
-      }else {
-        console.error('直播类型错误,无法初始化播放器')
+
+      if (this.videoParam.liveType === 2 || this.videoParam.liveType === 3) {
+        // 录播或直播回放
+        this.$nextTick(() => {
+          this.videoPlay(this.videoParam.videoUrl);
+        });
+      } else {
+        console.error('直播类型错误,无法初始化播放器');
       }
-      // 创建播放器实例
-      const videoPlayer = this.$refs.videoPlayer;
-      // 添加播放器事件监听器
-      videoPlayer.addEventListener('play', () => {
-        console.log('播放器已开始播放');
-      });
-      videoPlayer.addEventListener('pause', () => {
-        console.log('播放器已暂停');
-      });
-      videoPlayer.addEventListener('ended', () => {
-        console.log('播放器已结束');
-      });
     }
   },
+
+  watch: {
+    // 监听videoParam变化,重新初始化播放器
+    videoParam: {
+      handler() {
+        this.$nextTick(() => {
+          this.initPlayer();
+        });
+      },
+      deep: true
+    }
+  },
+
   beforeDestroy() {
-    this.hls?.destroy()
-    // 销毁播放器实例
+    // 销毁HLS实例
+    this.hls?.destroy();
+    this.liveHls?.destroy();
+
+    // 清理video元素
+    const videoElements = [
+      this.$refs.videoPlayer,
+      this.$refs.livePlayer
+    ];
+
+    videoElements.forEach(video => {
+      if (video) {
+        video.pause();
+        video.src = '';
+        video.load();
+      }
+    });
   }
 };
 </script>
@@ -140,5 +250,8 @@ export default {
   width: 100%;
   height: auto;
   border-radius: 8px;
+  max-height: 300px; /* 设置最大高度,避免过大 */
+  object-fit: contain; /* 保持比例,不拉伸 */
+  background-color: #000; /* 黑色背景,避免视频加载时显示白色 */
 }
 </style>

+ 39 - 29
src/views/live/liveOrder/index.vue

@@ -25,6 +25,15 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
+      <el-form-item label="销售名称" prop="companyUserName">
+        <el-input
+          v-model="queryParams.companyUserName"
+          placeholder="请输入销售名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
       <el-form-item label="订单号" prop="orderCode">
         <el-input
           v-model="queryParams.orderCode"
@@ -74,25 +83,25 @@
         />
       </el-form-item>
 
-      <el-form-item label="商品数量" prop="totalNum">
-        <el-input
-          v-model="queryParams.totalNum"
-          placeholder="请输入商品数量"
-          clearable
-          size="small"
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-
-      <el-form-item label="销售价格" prop="price">
-        <el-input
-          v-model="queryParams.price"
-          placeholder="请输入销售价格"
-          clearable
-          size="small"
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
+<!--      <el-form-item label="商品数量" prop="totalNum">-->
+<!--        <el-input-->
+<!--          v-model="queryParams.totalNum"-->
+<!--          placeholder="请输入商品数量"-->
+<!--          clearable-->
+<!--          size="small"-->
+<!--          @keyup.enter.native="handleQuery"-->
+<!--        />-->
+<!--      </el-form-item>-->
+
+<!--      <el-form-item label="销售价格" prop="price">-->
+<!--        <el-input-->
+<!--          v-model="queryParams.price"-->
+<!--          placeholder="请输入销售价格"-->
+<!--          clearable-->
+<!--          size="small"-->
+<!--          @keyup.enter.native="handleQuery"-->
+<!--        />-->
+<!--      </el-form-item>-->
 
       <el-form-item label="收货地址" prop="userAddress">
         <el-input
@@ -124,15 +133,15 @@
         />
       </el-form-item>
 
-      <el-form-item label="供应商" prop="supplierName">
-        <el-input
-          v-model="queryParams.supplierName"
-          placeholder="请输入供应商名称"
-          clearable
-          size="small"
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
+<!--      <el-form-item label="供应商" prop="supplierName">-->
+<!--        <el-input-->
+<!--          v-model="queryParams.supplierName"-->
+<!--          placeholder="请输入供应商名称"-->
+<!--          clearable-->
+<!--          size="small"-->
+<!--          @keyup.enter.native="handleQuery"-->
+<!--        />-->
+<!--      </el-form-item>-->
 
       <!-- 下单时间范围选择 -->
       <el-form-item label="下单时间" prop="orderTimeRange">
@@ -244,7 +253,7 @@
       <el-table-column label="商品分类" align="center" prop="cateName" v-if="showFinanceTableField"/>
       <el-table-column label="成交价" align="center" prop="payMoney"/>
       <el-table-column label="收货地址" align="center" prop="userAddress" width="200" />
-      <el-table-column label="对应供应商" align="center" prop="supplierName" width="120" />
+<!--      <el-table-column label="对应供应商" align="center" prop="supplierName" width="120" />-->
       <el-table-column label="下单时间" align="center" prop="createTime" width="180">
         <template slot-scope="scope">
           <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
@@ -411,6 +420,7 @@ export default {
         liveId: null,
         pageSize: 10,
         companyId: null,
+        companyUserName: null,
         deptId: null,
         productName: null,
         productSpec: null,

+ 55 - 53
src/views/live/order/index.vue

@@ -193,25 +193,25 @@
         />
       </el-form-item>
 
-      <el-form-item label="商品数量" prop="totalNum">
-        <el-input
-          v-model="queryParams.totalNum"
-          placeholder="请输入商品数量"
-          clearable
-          size="small"
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
+<!--      <el-form-item label="商品数量" prop="totalNum">-->
+<!--        <el-input-->
+<!--          v-model="queryParams.totalNum"-->
+<!--          placeholder="请输入商品数量"-->
+<!--          clearable-->
+<!--          size="small"-->
+<!--          @keyup.enter.native="handleQuery"-->
+<!--        />-->
+<!--      </el-form-item>-->
 
-      <el-form-item label="销售价格" prop="price">
-        <el-input
-          v-model="queryParams.price"
-          placeholder="请输入销售价格"
-          clearable
-          size="small"
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
+<!--      <el-form-item label="销售价格" prop="price">-->
+<!--        <el-input-->
+<!--          v-model="queryParams.price"-->
+<!--          placeholder="请输入销售价格"-->
+<!--          clearable-->
+<!--          size="small"-->
+<!--          @keyup.enter.native="handleQuery"-->
+<!--        />-->
+<!--      </el-form-item>-->
 
       <el-form-item label="收货地址" prop="userAddress">
         <el-input
@@ -243,15 +243,15 @@
 <!--        />-->
 <!--      </el-form-item>-->
 
-      <el-form-item label="供应商" prop="supplierName">
-        <el-input
-          v-model="queryParams.supplierName"
-          placeholder="请输入供应商名称"
-          clearable
-          size="small"
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
+<!--      <el-form-item label="供应商" prop="supplierName">-->
+<!--        <el-input-->
+<!--          v-model="queryParams.supplierName"-->
+<!--          placeholder="请输入供应商名称"-->
+<!--          clearable-->
+<!--          size="small"-->
+<!--          @keyup.enter.native="handleQuery"-->
+<!--        />-->
+<!--      </el-form-item>-->
 
       <el-form-item label="档期归属" prop="scheduleId">
         <el-select filterable style="width: 215px" v-model="queryParams.scheduleId" placeholder="请选择档期" clearable size="small">
@@ -306,38 +306,38 @@
           clearable
           size="small"
           v-model="payTimeRange"
-          type="daterange"
-          value-format="yyyy-MM-dd"
+          type="datetimerange"
+          value-format="yyyy-MM-dd HH:mm:ss"
           start-placeholder="开始日期"
           end-placeholder="结束日期"
         />
       </el-form-item>
 
-      <el-form-item label="发货时间" prop="deliverySendTimeRange">
-        <el-date-picker
-          style="width:215px"
-          clearable
-          size="small"
-          v-model="deliverySendTimeRange"
-          type="daterange"
-          value-format="yyyy-MM-dd"
-          start-placeholder="开始日期"
-          end-placeholder="结束日期"
-        />
-      </el-form-item>
+<!--      <el-form-item label="发货时间" prop="deliverySendTimeRange">-->
+<!--        <el-date-picker-->
+<!--          style="width:215px"-->
+<!--          clearable-->
+<!--          size="small"-->
+<!--          v-model="deliverySendTimeRange"-->
+<!--          type="daterange"-->
+<!--          value-format="yyyy-MM-dd"-->
+<!--          start-placeholder="开始日期"-->
+<!--          end-placeholder="结束日期"-->
+<!--        />-->
+<!--      </el-form-item>-->
 
-      <el-form-item label="回单时间" prop="deliveryImportTimeRange">
-        <el-date-picker
-          style="width:215px"
-          clearable
-          size="small"
-          v-model="deliveryImportTimeRange"
-          type="daterange"
-          value-format="yyyy-MM-dd"
-          start-placeholder="开始日期"
-          end-placeholder="结束日期"
-        />
-      </el-form-item>
+<!--      <el-form-item label="回单时间" prop="deliveryImportTimeRange">-->
+<!--        <el-date-picker-->
+<!--          style="width:215px"-->
+<!--          clearable-->
+<!--          size="small"-->
+<!--          v-model="deliveryImportTimeRange"-->
+<!--          type="daterange"-->
+<!--          value-format="yyyy-MM-dd"-->
+<!--          start-placeholder="开始日期"-->
+<!--          end-placeholder="结束日期"-->
+<!--        />-->
+<!--      </el-form-item>-->
 
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
@@ -360,6 +360,7 @@
           type="warning"
           icon="el-icon-download"
           size="mini"
+          v-hasPermi="['live:order:export']"
           :loading="exportLoading"
           @click="handleExport"
         >导出订单</el-button>
@@ -385,6 +386,7 @@
           type="warning"
           icon="el-icon-download"
           size="mini"
+          v-hasPermi="['live:order:exportAll']"
           @click="handleExportDetails"
         >导出订单(明文)</el-button>
       </el-col>

+ 248 - 11
src/views/qw/friendWelcome/index.vue

@@ -2,7 +2,7 @@
   <div class="app-container">
     <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="120px">
       <el-form-item label="销售公司" prop="companyId">
-        <el-select v-model="queryParams.companyId" clearable placeholder="销售公司" @change="changeCorpOrCompany()" size="small">
+        <el-select v-model="queryParams.companyId" placeholder="销售公司" @change="changeCorpOrCompany()" size="small">
           <el-option
             v-for="dict in companyList"
             :key="dict.dictValue"
@@ -12,7 +12,7 @@
         </el-select>
       </el-form-item>
       <el-form-item label="企微主体" prop="corpId">
-        <el-select v-model="queryParams.corpId" clearable placeholder="企微主体" @change="changeCorpOrCompany()" size="small">
+        <el-select v-model="queryParams.corpId" placeholder="企微主体" @change="changeCorpOrCompany()" size="small">
           <el-option
             v-for="dict in myQwCompanyList"
             :key="dict.dictValue"
@@ -101,6 +101,15 @@
       </el-table-column>
       <el-table-column label="创建时间" align="center" prop="createTime" width="180"/>
       <el-table-column label="更新时间" align="center" prop="updateTime" width="180"/>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="120px">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            @click="handleDetail(scope.row)"
+          >详情</el-button>
+        </template>
+      </el-table-column>
     </el-table>
 
     <pagination
@@ -110,11 +119,175 @@
       :limit.sync="queryParams.pageSize"
       @pagination="getList"
     />
+
+    <!-- 添加或修改好友欢迎语对话框 -->
+    <el-dialog :title="friendWelcomeDialog.title" :visible.sync="friendWelcomeDialog.visible" v-loading="friendWelcomeDialog.loading" width="1200px" append-to-body>
+      <div style="width: 1130px" class="app-container">
+        <div>
+          <span style="font-size: 15px">基础信息</span>
+          <el-divider></el-divider>
+        </div>
+        <el-form ref="form" :model="friendWelcomeDialog.friendWelcomeInfo" :disabled="true" label-width="120px">
+          <el-form-item label="使用成员:" style="margin-top: 2%">
+            <div>
+              <el-tag
+                style="margin-left: 5px"
+                size="medium"
+                :key="list.id"
+                v-for="list in userSelectList"
+                closable
+                :disable-transitions="false">
+                {{list.qwUserName}}({{list.nickName}})
+              </el-tag>
+            </div>
+          </el-form-item>
+          <!-- 新增整体标题 -->
+          <el-form-item label="标题:" prop="welcomeTitle">
+            <el-input v-model="friendWelcomeDialog.friendWelcomeInfo.welcomeTitle" placeholder="请输入欢迎语标题"/>
+            <el-alert style="margin-top: 8px;height: 30px"
+                      title="此标题仅用于欢迎语的用途区分"
+                      type="info"
+                      :closable="false"
+                      show-icon>
+            </el-alert>
+          </el-form-item>
+          <el-form-item label="是否发送欢迎语">
+            <el-switch
+              v-model="friendWelcomeDialog.friendWelcomeInfo.isSendMsg"
+              active-color="#13ce66"
+              inactive-color="#ff4949"
+              active-value="1"
+              inactive-value="2">
+            </el-switch>
+            <span v-if="friendWelcomeDialog.friendWelcomeInfo.isSendMsg == '1'" style="margin-left: 10px;color: #13ce66">允许</span>
+            <span v-if="friendWelcomeDialog.friendWelcomeInfo.isSendMsg == '2'" style="margin-left: 10px;color: #ff4949">不允许</span>
+
+          </el-form-item>
+          <div>
+            <span style="font-size: 15px">发送欢迎语</span>
+            <el-divider></el-divider>
+          </div>
+          <el-form-item label="默认欢迎语:" prop="welcomeText">
+            <el-input v-model="friendWelcomeDialog.friendWelcomeInfo.welcomeText" type="textarea"  :rows="12" maxlength="1300" show-word-limit placeholder="请输入消息内容"/>
+            <!-- 附件和链接列表 -->
+            <el-row>
+              <el-col>
+                <div v-for="(item, index) in friendWelcomeDialog.friendWelcomeInfo.attachments" :key="index" style="background-color: #f5f7fa;padding: 5px;border: 1px solid  #d9d9d9;">
+                  <div slot="header" style="display: flex;justify-content: space-between;align-items: center; ">
+                    <div style="flex: 1;">
+                      <span v-if="item.msgtype === 'image'">【图片】: {{ item.image.pic_url }}</span>
+                      <span v-if="item.msgtype === 'video'">【视频】: {{ item.video.url }}</span>
+                      <span v-if="item.msgtype === 'link'">【链接】: {{ item.link.title }}-{{item.link.desc}}</span>
+                      <span v-if="item.msgtype === 'miniprogram'">【小程序】: {{ item.miniprogram.title }}</span>
+                    </div>
+                  </div>
+                </div>
+              </el-col>
+            </el-row>
+          </el-form-item>
+
+          <el-form-item label="分时段欢迎语">
+            <el-switch
+              v-model="friendWelcomeDialog.friendWelcomeInfo.isDayparting"
+              active-color="#13ce66"
+              inactive-color="#ff4949"
+              active-value="1"
+              inactive-value="2">
+            </el-switch>
+            <span v-if="friendWelcomeDialog.friendWelcomeInfo.isDayparting == '1'" style="margin-left: 10px;color: #13ce66">已启用</span>
+            <span v-if="friendWelcomeDialog.friendWelcomeInfo.isDayparting == '2'" style="margin-left: 10px;color: #ff4949">已禁用</span>
+          </el-form-item>
+
+          <el-form-item v-if="friendWelcomeDialog.friendWelcomeInfo.isDayparting == '1'" >
+            <div style="background-color:#ecf8fe;width: 100%;border: 1px solid #dcdfe6">
+              <span style="margin-left:20px;font-size: 15px;display: block" >注意:1、员工上下班不同时间段可设置不同欢迎语;</span>
+              <span style="margin-left:65px;font-size: 15px;display: block" >2、分时段之外的时间将发送已允许的默认欢迎语。</span>
+              <span style="margin-left:65px;font-size: 15px;display: block" >3、不设置分时段欢迎语则使用已允许的默认欢迎语</span>
+              <span style="margin-left:65px;font-size: 15px;display: block" >4、若员工没有设置过欢迎语则不会发送</span>
+            </div>
+          </el-form-item>
+          <el-form-item v-if="friendWelcomeDialog.friendWelcomeInfo.isDayparting == '2'">
+            <div style="background-color:#ecf8fe;width: 100%;border: 1px solid #dcdfe6">
+              <span style="margin-left:20px;font-size: 15px;display: block" >注意:1、新建欢迎语最多可发送1条文字消息和9个附件;</span>
+              <span style="margin-left:65px;font-size: 15px;display: block" >2、文字消息和附件不能同时为空,当两者均填写时用户会收到多条消息;</span>
+              <span style="margin-left:65px;font-size: 15px;display: block" >3、欢迎语将在客户加为好友后20秒内下发,因网络延迟可能造成发送不成功</span>
+            </div>
+          </el-form-item>
+          <div  v-if="friendWelcomeDialog.friendWelcomeInfo.isDayparting == '1'"  v-for="(item, index) in friendWelcomeDialog.friendWelcomeInfo.daypartingItemlist"    :key="index" >
+            <el-form-item :label="`时段 ${index + 1}:`">
+              <el-row>
+                <el-col style="width: 965px">
+                  <div style="background-color: #fbfbfb;padding: 10px;  border: 1px solid #e6e6e6; margin-bottom: 20px;">
+                    <el-form ref="friendWelcomeItemForm" :disabled="true" :model="item">
+                      <div style="display: flex; gap: 10px;">
+                        <el-form-item label="发起时间:" prop="week" style="flex: 8;">
+                          <el-select v-model="item.week" remote multiple placeholder="请选择" filterable style="width: 580px">
+                            <el-option
+                              v-for="dict in weekOptions"
+                              :key="dict.value"
+                              :label="dict.label"
+                              :value="dict.value">
+                            </el-option>
+                          </el-select>
+                        </el-form-item>
+                        <el-form-item prop="startTime" style="flex: 1;">
+                          <el-time-select style="width: 120px;"
+                                          placeholder="起始时间"
+                                          v-model="item.startTime"
+                                          :picker-options="{
+                                            start: '00:00',
+                                            step: '00:15',
+                                            end: '24:00'
+                                          }">
+                          </el-time-select>
+                        </el-form-item>
+                        <el-form-item prop="endTime" style="flex: 1;">
+                          <el-time-select style="width: 120px;"
+                                          placeholder="结束时间"
+                                          v-model="item.endTime"
+                                          :picker-options="{
+                                            start: '00:00',
+                                            step: '00:15',
+                                            end: '24:00',
+                                            minTime: item.startTime
+                                          }">
+                          </el-time-select>
+                        </el-form-item>
+                      </div>
+
+                      <el-form-item style="margin-top: 20px" prop="welcomeText">
+                        <el-input v-model="item.welcomeText" type="textarea" :rows="12" maxlength="1300" show-word-limit placeholder="请输入消息内容"/>
+                        <!-- 附件和链接列表 -->
+                        <el-row>
+                          <el-col>
+                            <div v-for="(attachment, attachIndex) in item.attachments" :key="attachIndex" style="background-color: #f5f7fa;padding: 5px;border: 1px solid  #d9d9d9;">
+                              <div slot="header" style="  display: flex;justify-content: space-between;align-items: center; ">
+                                <div style="flex: 1;">
+                                  <span v-if="attachment.msgtype === 'image'">【图片】: {{ attachment.image.pic_url }}</span>
+                                  <span v-if="attachment.msgtype === 'video'">【视频】: {{ attachment.video.url }}</span>
+                                  <span v-if="attachment.msgtype === 'link'">【链接】: {{ attachment.link.title }}-{{attachment.link.desc}}</span>
+                                  <span v-if="attachment.msgtype === 'miniprogram'">【小程序】: {{ attachment.miniprogram.title }}</span>
+                                </div>
+                              </div>
+                            </div>
+                          </el-col>
+                        </el-row>
+                      </el-form-item>
+                    </el-form>
+                  </div>
+                </el-col>
+              </el-row>
+            </el-form-item>
+          </div>
+
+        </el-form>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
 <script>
-import { listFriendWelcome } from '@/api/qw/friendWelcome'
+import { getFriendWelcome, listFriendWelcome } from '@/api/qw/friendWelcome'
 import { allList } from '@/api/company/company'
 import { getMyQwCompanyList, getQwAllUserList } from '@/api/qw/user'
 
@@ -145,18 +318,40 @@ export default {
         updateTime: null,
         isSendMsg: null,
       },
+      userSelectList: [],
+      friendWelcomeDialog: {
+        visible: false,
+        loading: false,
+        title: "详情",
+        friendWelcomeInfo: {},
+      },
+      weekOptions: [
+        { value: 1, label: '星期一' },
+        { value: 2, label: '星期二' },
+        { value: 3, label: '星期三' },
+        { value: 4, label: '星期四' },
+        { value: 5, label: '星期五' },
+        { value: 6, label: '星期六' },
+        { value: 7, label: '星期天' }
+      ],
     }
   },
-  created() {
+  async created() {
     this.getDicts("sys_qw_allow_select").then(response => {
       this.allowSelectOptions = response.data;
     });
-    allList().then(response => {
-      this.companyList = response.rows;
-    });
-    getMyQwCompanyList().then(response => {
-      this.myQwCompanyList = response.data;
-    });
+    const [allRes, myRes] = await Promise.all([
+      allList(),
+      getMyQwCompanyList()
+    ]);
+
+    this.companyList = allRes.rows;
+    this.myQwCompanyList = myRes.data;
+
+    this.queryParams.companyId = this.companyList[0].dictValue
+    this.queryParams.corpId = this.myQwCompanyList[0].dictValue
+
+    this.changeCorpOrCompany()
     this.getList();
   },
   methods: {
@@ -167,6 +362,10 @@ export default {
     resetQuery() {
       this.resetForm("queryForm");
       this.companyUserList = []
+
+      this.queryParams.companyId = this.companyList[0].dictValue
+      this.queryParams.corpId = this.myQwCompanyList[0].dictValue
+      this.changeCorpOrCompany()
       this.handleQuery();
     },
     getList() {
@@ -187,7 +386,45 @@ export default {
           this.companyUserList = response.data;
         });
       }
-    }
+    },
+    handleDetail(row) {
+      getFriendWelcome(row.id).then(response => {
+        let data = response.row
+
+        const params = {
+          companyId: data.companyId,
+          corpId: data.corpId
+        }
+        getQwAllUserList(params).then(res => {
+          this.userSelectList = res.data.filter(item => {
+            return data.qwUserIds.includes(item.id)
+          })
+        })
+
+        // 转换 attachments
+        if (typeof data.attachments === 'string') {
+          data.attachments = JSON.parse(data.attachments);
+        }
+
+        // 转换 daypartingItemlist
+        if (typeof data.daypartingItemlist === 'string') {
+          data.daypartingItemlist = JSON.parse(data.daypartingItemlist);
+        }
+
+        // 转换 daypartingItemlist 中的每个项目的 attachments 和 week
+        if (Array.isArray(data.daypartingItemlist)) {
+          data.daypartingItemlist = data.daypartingItemlist.map(item => {
+            return {
+              ...item,
+              attachments: typeof item.attachments === 'string' ? JSON.parse(item.attachments) : item.attachments,
+              week: typeof item.week === 'string' ? JSON.parse(item.week) : item.week
+            };
+          });
+        }
+        this.friendWelcomeDialog.friendWelcomeInfo = data
+        this.friendWelcomeDialog.visible = true
+      })
+    },
   },
 }
 </script>