Bläddra i källkod

1、直播调整迁移
2、太乙堂配置

yys 2 dagar sedan
förälder
incheckning
36b1d9bb7a

+ 49 - 0
.env.prod-tyt

@@ -0,0 +1,49 @@
+# 页面标题
+VUE_APP_TITLE = 重庆太乙堂互联网医院管理系统
+# 首页菜单标题
+VUE_APP_TITLE_INDEX = 重庆太乙堂
+# 公司名称
+VUE_APP_COMPANY_NAME = 重庆太乙堂云联互联网医院有限公司
+# ICP备案号
+VUE_APP_ICP_RECORD = 渝ICP备2023010906号-8
+# ICP网站访问地址
+VUE_APP_ICP_URL =https://beian.miit.gov.cn
+# 网站LOG
+VUE_APP_LOG_URL =@/assets/logo/tyt.png
+# 存储桶配置
+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 = tyt-hw079058881
+# 存储桶配置
+VUE_APP_COS_BUCKET = tyt-1323137866
+# 存储桶配置
+VUE_APP_COS_REGION = ap-chongqing
+# 线路一地址
+VUE_APP_VIDEO_LINE_1 = https://tyttcpv.ylrzcloud.com
+# 线路二地址
+VUE_APP_VIDEO_LINE_2 = https://tytobs.ylrztop.com
+#火山云视频地址域名
+VUE_APP_VIDEO_URL = https://tytvolcengine.ylrztop.com
+#火山云视频点播空间名
+VUE_APP_HSY_SPACE = tyt-2114522511
+
+# 生产环境配置
+ENV = 'production'
+
+#FS管理系统/生产环境
+VUE_APP_BASE_API = '/prod-api'
+
+#默认 1、会员 2、企微
+VUE_APP_COURSE_DEFAULT = 1
+
+# 路由懒加载
+VUE_CLI_BABEL_TRANSPILE_MODULES = true
+
+#直播解码路径
+VUE_APP_LIVE_PATH = /live
+
+VUE_APP_LIVE_WS_URL = wss://liveapp.cqtyt.com/ws

+ 2 - 0
package.json

@@ -40,6 +40,7 @@
     "build:prod-bjczwh": "vue-cli-service build --mode prod-bjczwh",
     "build:prod-jnlzjk": "vue-cli-service build --mode prod-jnlzjk",
     "build:prod-fby": "vue-cli-service build --mode prod-fby",
+    "build:prod-tyt": "vue-cli-service build --mode prod-tyt",
     "build:prod-zkzh": "vue-cli-service build --mode prod-zkzh",
     "build:prod-syysy": "vue-cli-service build --mode prod-syysy",
     "build:prod-hyt": "vue-cli-service build --mode prod-hyt",
@@ -113,6 +114,7 @@
     "vue-cropper": "0.5.5",
     "vue-jsonp": "^2.0.0",
     "vue-meta": "^2.4.0",
+    "vue-mobile-calendar": "^3.3.0",
     "vue-router": "3.4.9",
     "vuedraggable": "^2.24.3",
     "vuex": "3.6.0",

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

@@ -55,4 +55,12 @@ export function exportLiveUserDetail(liveId) {
     url: '/liveData/liveData/exportLiveUserDetail?liveId=' + liveId,
     method: 'get'
   })
-}
+}
+
+export function exportLiveData(query) {
+  return request({
+    url: '/liveData/liveData/export',
+    method: 'get',
+    params: query
+  })
+}

+ 9 - 0
src/api/live/liveMsg.js

@@ -59,3 +59,12 @@ export function exportLiveMsg(query) {
     params: query
   })
 }
+
+// 导出直播评论
+export function exportLiveMsgComments(liveId) {
+  return request({
+    url: '/live/liveMsg/exportComments/' + liveId,
+    method: 'get',
+    responseType: 'blob'
+  })
+}

+ 27 - 0
src/api/live/liveSignRecord.js

@@ -0,0 +1,27 @@
+import request from '@/utils/request'
+
+// 查询直播签到记录列表
+export function listLiveSignRecord(query) {
+  return request({
+    url: '/his/liveSignRecord/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询直播签到记录详细
+export function getLiveSignRecord(id) {
+  return request({
+    url: '/his/liveSignRecord/' + id,
+    method: 'get'
+  })
+}
+
+// 导出直播签到记录
+export function exportLiveSignRecord(query) {
+  return request({
+    url: '/his/liveSignRecord/export',
+    method: 'post',
+    params: query
+  })
+}

+ 7 - 0
src/api/live/words.js

@@ -51,3 +51,10 @@ export function exportWords(query) {
     params: query
   })
 }
+// 下载用户导入模板
+export function importTemplate() {
+  return request({
+    url: '/live/words/importTemplate',
+    method: 'get'
+  })
+}

+ 16 - 0
src/api/live/wxExpressTask.js

@@ -0,0 +1,16 @@
+import request from '@/utils/request'
+
+export function list(query) {
+  return request({
+    url: '/live/wxExpressTask/list',
+    method: 'get',
+    params: query
+  })
+}
+
+export function getFailedCount() {
+  return request({
+    url: '/live/wxExpressTask/getFailedCount',
+    method: 'get'
+  })
+}

BIN
src/assets/logo/tyt.png


+ 28 - 7
src/views/live/components/productAfterSalesOrder.vue

@@ -39,13 +39,20 @@
                 </span>
           </el-descriptions-item>
           <el-descriptions-item label="退款金额"  >
-                <span v-if="afterSales!=null">
-                  {{afterSales.refundAmount}}
+                <span>
+<!--                  {{order.totalPrice}}-->
+                  ¥{{(order.totalPrice-order.discountMoney).toFixed(2)}}
+<!--                  ¥{{(order.totalPrice-order.payPostage+order.discountMoney).toFixed(2)}}-->
+                </span>
+          </el-descriptions-item>
+          <el-descriptions-item label="优惠券"  >
+                <span>
+                  ¥{{order.discountMoney}}
                 </span>
           </el-descriptions-item>
           <el-descriptions-item label="运费"  >
                 <span v-if="order!=null">
-                  {{order.payDelivery}}
+                  ¥{{order.payPostage}}
                 </span>
           </el-descriptions-item>
           <el-descriptions-item label="申请类型"  >
@@ -133,6 +140,16 @@
 
             </template>
           </el-table-column>
+          <el-table-column label="优惠券" width="300" align="center">
+            <template slot-scope="scope">
+              <p>¥{{order.discountMoney}}</p>
+            </template>
+          </el-table-column>
+          <el-table-column label="运费" width="300" align="center">
+            <template slot-scope="scope">
+              <p>¥{{order.payPostage}}</p>
+            </template>
+          </el-table-column>
           <el-table-column label="属性" width="240" align="center">
             <template slot-scope="scope">
               {{JSON.parse(scope.row.jsonInfo).sku}}
@@ -145,13 +162,16 @@
           </el-table-column>
           <el-table-column label="小计"  align="center">
             <template slot-scope="scope">
-              ¥{{JSON.parse(scope.row.jsonInfo).num*JSON.parse(scope.row.jsonInfo).price}}
+              ¥ {{(order.totalPrice-order.discountMoney).toFixed(2)}}
+<!--              ¥{{(order.totalPrice-order.payPostage+order.discountMoney).toFixed(2)}}--><!--{{JSON.parse(scope.row.jsonInfo).num*JSON.parse(scope.row.jsonInfo).price}}-->
             </template>
           </el-table-column>
         </el-table>
         <div style="margin-top: 12px; text-align: right;" v-if="order">
-          <div>订单金额:¥{{ goodsTotal.toFixed(2) }}</div>
-          <div>运费金额:¥{{ (order.payDelivery || 0).toFixed(2) }}</div>
+          <div>商品金额:¥{{ goodsTotal.toFixed(2) }}</div>
+          <div>运费金额:¥{{ (order.payPostage || 0).toFixed(2) }}</div>
+          <div>优惠券金额:¥{{ order.discountMoney }}</div>
+          <div>小计:¥{{(order.totalPrice-order.discountMoney).toFixed(2)}}</div>
         </div>
         <div style="margin-top: 20px">
           <span class="font-small">操作信息</span>
@@ -345,7 +365,8 @@ export default {
     handleRefund(){
       this.audit.open=true;
       this.form.salesId=this.afterSales.id;
-      this.form.refundAmount=this.afterSales.refundAmount;
+      //this.form.refundAmount=this.afterSales.refundAmount;
+      this.form.refundAmount=this.order.payMoney; //实付金额
     },
     handleImmediatelyRefund(){
       let _this = this;

+ 144 - 1
src/views/live/live/index.vue

@@ -349,6 +349,18 @@
               <el-dropdown-item @click.native="handleAudit(scope.row)">
                 <i class="el-icon-service"></i> 审核
               </el-dropdown-item>
+              <el-dropdown-item
+                v-if="scope.row.status != 2"
+                @click.native="handleRoomPassword(scope.row)">
+                <i class="el-icon-service"></i> 房间密码
+              </el-dropdown-item>
+<!--              <el-dropdown-item -->
+<!--                @click.native="handleExportComments(scope.row)"-->
+<!--                :disabled="exportingComments[scope.row.liveId]"-->
+<!--                v-hasPermi="['live:liveMsg:export']"-->
+<!--              >-->
+<!--                <i class="el-icon-download"></i> 导出评论-->
+<!--              </el-dropdown-item>-->
             </el-dropdown-menu>
           </el-dropdown>
           <!--          <el-button-->
@@ -581,9 +593,10 @@
                       plain
                       size="mini"
                       @click="addUserTag(scope.row,scope.$index)"
-                      v-hasPermi="['qw:externalContact:addTag']"
+
                   >选择标签</el-button>
                </template>
+<!--              v-hasPermi="['qw:externalContact:addTag']"-->
             </el-table-column>
             <el-table-column label="操作" width="100">
               <template slot-scope="scope">
@@ -663,6 +676,38 @@
         <el-button @click="addTagCancel">取 消</el-button>
       </div>
     </el-dialog>
+
+    <!-- 设置房间密码对话框 -->
+    <el-dialog
+      title="设置房间密码"
+      :visible.sync="roomPasswordDialog.open"
+      width="500px"
+      append-to-body
+      class="simple-dialog"
+    >
+      <el-form ref="roomPasswordForm" :model="roomPasswordForm" :rules="roomPasswordRules" label-width="100px">
+        <el-form-item label="直播ID">
+          <el-input v-model="roomPasswordForm.liveId" disabled />
+        </el-form-item>
+        <el-form-item label="直播名称">
+          <el-input v-model="roomPasswordForm.liveName" disabled />
+        </el-form-item>
+        <el-form-item label="房间密码" prop="roomPassword">
+          <el-input
+            v-model="roomPasswordForm.roomPassword"
+            placeholder="请输入房间密码(留空表示无密码)"
+            clearable
+            maxlength="20"
+            show-word-limit
+          />
+          <div class="form-tip">提示:设置密码后,用户进入直播间需要输入密码</div>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitRoomPassword">确 定</el-button>
+        <el-button @click="roomPasswordDialog.open = false">取 消</el-button>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
@@ -686,6 +731,7 @@ import {
   getTagsListByCorpId,
   clearLiveCache,
 } from "@/api/live/live";
+import { exportLiveMsgComments } from "@/api/live/liveMsg";
 import Editor from "@/components/Editor/wang";
 import user from "@/store/modules/user";
 import VideoUpload from "@/components/LiveVideoUpload/single.vue";
@@ -811,6 +857,24 @@ export default {
         name:null,
         corpId:null,
       },
+      // 导出评论状态:key为liveId,value为是否正在导出
+      exportingComments: {},
+      // 房间密码弹窗
+      roomPasswordDialog: {
+        open: false
+      },
+      // 房间密码表单
+      roomPasswordForm: {
+        liveId: null,
+        liveName: null,
+        roomPassword: null
+      },
+      // 房间密码表单校验
+      roomPasswordRules: {
+        roomPassword: [
+          { max: 20, message: '密码长度不能超过20个字符', trigger: 'blur' }
+        ]
+      }
     };
   },
   created() {
@@ -1241,6 +1305,39 @@ export default {
     handleImgError(e) {
       e.target.src = this.defaultImg;
     },
+    // 设置房间密码
+    handleRoomPassword(row){
+      this.roomPasswordForm.liveId = row.liveId
+      this.roomPasswordForm.liveName = row.liveName
+      this.roomPasswordForm.roomPassword = row.roomPassword || ''
+      this.roomPasswordForm.startTime = row.startTime || ''
+      this.roomPasswordDialog.open = true
+    },
+    // 提交房间密码
+    submitRoomPassword() {
+      this.$refs['roomPasswordForm'].validate(valid => {
+        if (valid) {
+          const params = {
+            liveId: this.roomPasswordForm.liveId,
+            roomPassword: this.roomPasswordForm.roomPassword || '',
+            startTime: this.roomPasswordForm.startTime || '',
+          }
+
+          updateLive(params).then(response => {
+            if (response.code === 200) {
+              this.$message.success('房间密码设置成功')
+              this.roomPasswordDialog.open = false
+              this.getList()
+            } else {
+              this.$message.error(response.msg || '设置失败')
+            }
+          }).catch(error => {
+            console.error('设置房间密码失败:', error)
+            this.$message.error('设置失败,请稍后重试')
+          })
+        }
+      })
+    },
     handleAudit(row) {
       this.$alert("是否审核通过?", "审核", {
         confirmButtonText: "同意",
@@ -1434,6 +1531,52 @@ export default {
       this.lastCheckTagRow = null;
       this.currentCheck = null;
       this.currentCheckTagIndex = null;
+    },
+    /** 导出评论按钮操作 */
+    handleExportComments(row) {
+      const liveId = row.liveId;
+      // 检查是否正在导出
+      if (this.exportingComments[liveId]) {
+        this.$message.warning("正在导出中,请勿重复操作");
+        return;
+      }
+
+      // 检查是否有其他直播间正在导出
+      const hasExporting = Object.values(this.exportingComments).some(status => status === true);
+      if (hasExporting) {
+        this.$message.warning("当前已有导出任务进行中,请等待完成后再试");
+        return;
+      }
+
+      this.$confirm('是否确认导出该直播间的评论数据?', "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "info"
+      }).then(() => {
+        // 设置导出状态
+        this.$set(this.exportingComments, liveId, true);
+
+        exportLiveMsgComments(liveId).then(response => {
+          // 创建blob对象
+          const blob = new Blob([response], { type: 'application/vnd.ms-excel' });
+          // 创建下载链接
+          const url = window.URL.createObjectURL(blob);
+          const link = document.createElement('a');
+          link.href = url;
+          link.setAttribute('download', `直播评论_${row.liveName || liveId}_${new Date().getTime()}.xlsx`);
+          document.body.appendChild(link);
+          link.click();
+          document.body.removeChild(link);
+          window.URL.revokeObjectURL(url);
+
+          this.$message.success("导出成功");
+        }).catch(error => {
+          this.$message.error(error.msg || "导出失败");
+        }).finally(() => {
+          // 清除导出状态
+          this.$set(this.exportingComments, liveId, false);
+        });
+      }).catch(() => {});
     }
 
   },

+ 33 - 5
src/views/live/liveAfteraSales/index.vue

@@ -125,6 +125,15 @@
             @keyup.enter.native="handleQuery"/>
        </el-form-item>
 
+      <el-form-item label="银行交易流水" prop="bankTransactionId" label-width="100">
+          <el-input
+            v-model="queryParams.bankTransactionId"
+            placeholder="请输入银行交易流水"
+            clearable
+            size="small"
+            @keyup.enter.native="handleQuery"/>
+       </el-form-item>
+
       <el-form-item label="提交时间" prop="createTime">
         <el-date-picker
           style="width:205.4px"
@@ -166,7 +175,8 @@
       <el-table-column label="支付单号" align="center" prop="payCode" />
       <el-table-column label="会员手机号" align="center" prop="userPhone" />
       <el-table-column label="产品名称" align="center" prop="productName" :show-overflow-tooltip="true" />
-      <el-table-column label="退款金额" align="center" prop="refundAmount" />
+<!--      <el-table-column label="退款金额" align="center" prop="refundAmount" />-->
+      <el-table-column label="退款金额" align="center" prop="payMoney" />
       <el-table-column label="退款类型" align="center" prop="refundType" >
         <template slot-scope="scope">
           <dict-tag :options="serviceTypeOptions" :value="scope.row.refundType"/>
@@ -280,6 +290,7 @@ export default {
         deliverySn: null,
         deliveryName: null,
         hfOrderCode:null,
+        bankTransactionId: null,
         status: null,
         Status: null,
         isDel: null,
@@ -331,7 +342,7 @@ export default {
     this.getDicts("store_order_delivery_status").then((response) => {
       this.deliveryStatusOptions = response.data;
     });
-    this.getDicts("live_order_status").then((response) => {
+    this.getDicts("sys_live_order_status").then((response) => {
       this.orderStatusOptions = response.data;
     });
 
@@ -353,6 +364,11 @@ export default {
         let ss = params.hfOrderCode.split("-");
         params.hfOrderCode = ss[1];
       }
+      // 处理日期范围
+      if (this.dateRange && this.dateRange.length === 2) {
+        params.createTimeBegin = this.dateRange[0];
+        params.createTimeEnd = this.dateRange[1];
+      }
       listLiveAfterSales(params).then(response => {
         this.liveAfterSalesList = response.rows;
         this.total = response.total;
@@ -403,6 +419,7 @@ export default {
     },
     /** 重置按钮操作 */
     resetQuery() {
+      this.dateRange = [];
       this.resetForm("queryForm");
       this.handleQuery();
     },
@@ -464,18 +481,29 @@ export default {
     },
     /** 导出按钮操作 */
     handleExport() {
-      const queryParams = this.queryParams;
+      const params = { ...this.queryParams, deliverySn: this.queryParams.returnDeliverySn || this.queryParams.deliverySn };
+      if(!!params.hfOrderCode && params.hfOrderCode.indexOf("-") > -1){
+        let ss = params.hfOrderCode.split("-");
+        params.hfOrderCode = ss[1];
+      }
+      // 处理日期范围
+      if (this.dateRange && this.dateRange.length === 2) {
+        params.createTimeBegin = this.dateRange[0];
+        params.createTimeEnd = this.dateRange[1];
+      }
       this.$confirm('是否确认导出所有售后记录数据项?', "警告", {
           confirmButtonText: "确定",
           cancelButtonText: "取消",
           type: "warning"
         }).then(() => {
           this.exportLoading = true;
-          return exportLiveAfterSales(queryParams);
+          return exportLiveAfterSales(params);
         }).then(response => {
           this.download(response.msg);
           this.exportLoading = false;
-        }).catch(() => {});
+        }).catch(() => {
+          this.exportLoading = false;
+        });
     },
     getTreeselect() {
       var param={companyId:this.companyId}

+ 1 - 1
src/views/live/liveAnchor/index.vue

@@ -356,7 +356,7 @@ export default {
   }
 };
 </script>
-<style >
+<style scoped>
 .el-form-item__label {
   width: 120px !important;
 }

+ 1 - 1
src/views/live/liveConfig/index.vue

@@ -80,7 +80,7 @@
         <!-- 右边信息 -->
         <div class="right-info">
           <!-- 动态组件 -->
-          <component :is="currentComponent" ></component>
+          <component :is="currentComponent" :live-type="liveInfo.liveType"></component>
         </div>
       </div>
 <!--      <el-tabs tab-position="left" style="height: 200px;">-->

+ 7 - 4
src/views/live/liveConfig/liveRedConf.vue

@@ -95,7 +95,7 @@
       <el-table-column label="有效时间 单位:分" align="center" prop="duration" />
       <el-table-column label="红包类型" align="center" prop="redType" :formatter="redTypeFormatter"/>
       <el-table-column label="直播间ID" align="center" prop="liveId" />
-      <el-table-column label="芳华币数量" align="center" prop="redNum" />
+      <el-table-column label="币数量" align="center" prop="redNum" />
       <el-table-column label="可中奖份量" align="center" prop="totalLots" />
       <el-table-column label="实际发放奖励份量" align="center" prop="totalSend" />
       <el-table-column label="红包标题" align="center" prop="desc" />
@@ -177,8 +177,8 @@
         <el-form-item label="直播间ID" prop="liveId">
           <el-input v-model="form.liveId" placeholder="请输入直播间ID" :disabled="canLiveId"/>
         </el-form-item>
-        <el-form-item label="芳华币数" prop="redNum">
-          <el-input v-model="form.redNum" placeholder="请输入芳华币数量" />
+        <el-form-item label="币数" prop="redNum">
+          <el-input v-model="form.redNum" placeholder="请输入币数量" />
         </el-form-item>
         <el-form-item label="中奖份量" prop="totalLots">
           <el-input v-model="form.totalLots" placeholder="请输入可中奖份量" />
@@ -253,7 +253,7 @@ export default {
           { required: true, message: "直播间ID不能为空", trigger: "blur" }
         ],
         redNum: [
-          { required: true, message: "芳华币数量不能为空", trigger: "blur" }
+          { required: true, message: "币数量不能为空", trigger: "blur" }
         ],
         totalLots: [
           { required: true, message: "可中奖份量不能为空", trigger: "blur" }
@@ -340,6 +340,9 @@ export default {
         redId: row.redId,
         redStatus: status,
         totalLots: row.totalLots,
+        totalSend: row.totalSend,
+        redType: row.redType,
+        redNum: row.redNum,
         liveId: this.liveId,
         duration: row.duration,
         status: status

+ 20 - 0
src/views/live/liveConfig/task.vue

@@ -229,6 +229,9 @@
             <el-option v-for="i in goodsStatusOptions" :key="i.value" :label="i.label" :value="i.value"></el-option>
           </el-select>
         </el-form-item>
+<!--        <el-form-item label="序号" prop="signNo" v-if="form.taskType == 7">-->
+<!--          <el-input v-model.number="form.signNo" placeholder="请输入签到序号" oninput="value=value.replace(/[^\d]/g,'')" />-->
+<!--        </el-form-item>-->
         <el-form-item label="触发时间" prop="content">
           <el-time-picker
             default-value="2025-01-01 00:00:00"
@@ -297,6 +300,9 @@ export default {
         {
           value: 6,
           label: "定时商品上下架"
+        },{
+          value: 7,
+          label: "签到"
         }
       ],
       statusOptions:[{
@@ -668,6 +674,7 @@ export default {
         content: null,
         goodsId: null,
         goodsStatus: null,
+        // signNo:null,
         status: 1,
         createdTime: null,
         updatedTime: null
@@ -731,6 +738,8 @@ export default {
         }else if(this.form.taskType == 6){
           this.form.goodsId = content.goodsId;
           this.form.goodsStatus = content.status;
+        }else if(this.form.taskType == 7){
+          // this.form.signNo = content.signNo;
         }
         this.open = true;
         this.title = "修改直播间自动化任务配置";
@@ -754,6 +763,17 @@ export default {
         })
 
       }
+      if(this.form.taskType == 7){
+        // if(this.form.signNo == null) {
+        //   this.msgError("必须填写签到序号");
+        //   return;
+        // }
+        // 序号后端自己生成,
+        this.form.content = JSON.stringify({
+          signNo: 1
+        })
+      }
+
       this.$refs["form"].validate(valid => {
         if (valid) {
           if (this.form.id != null) {

+ 35 - 19
src/views/live/liveConfig/watchReward.vue

@@ -1,7 +1,7 @@
 <template >
   <div v-loading.fullscreen.lock="loading">
     <!-- 提示信息 -->
-    <div class="tip-message" >
+    <div class="tip-message">
       设置观看奖励,用户达到直播观看时长后可领取奖励
     </div>
 
@@ -26,7 +26,7 @@
         <el-form-item label="参与条件" prop="participateCondition">
           <el-radio-group v-model="watchRewardForm.participateCondition">
             <el-radio label="1">达到指定观看时长</el-radio>
-            <el-radio label="2">启用完课积分</el-radio>
+            <el-radio label="2" v-if="liveType == 2">启用完课积分</el-radio>
           </el-radio-group>
         </el-form-item>
 
@@ -39,10 +39,10 @@
 
         <!-- 完课率要求 -->
         <el-form-item label="完课率要求" prop="completionRate" v-if="watchRewardForm.participateCondition === '2'">
-          <el-input-number 
-            v-model="watchRewardForm.completionRate" 
-            :min="1" 
-            :max="100" 
+          <el-input-number
+            v-model="watchRewardForm.completionRate"
+            :min="1"
+            :max="100"
             :precision="0"
             placeholder="请输入完课率"
             style="width: 200px;"
@@ -55,9 +55,9 @@
           <div style="display: flex; flex-direction: column; gap: 10px;">
             <div v-for="(point, index) in watchRewardForm.pointsConfig" :key="index" style="display: flex; align-items: center;">
               <span style="width: 80px;">第{{ index + 1 }}天:</span>
-              <el-input-number 
-                v-model="watchRewardForm.pointsConfig[index]" 
-                :min="0" 
+              <el-input-number
+                v-model="watchRewardForm.pointsConfig[index]"
+                :min="0"
                 :precision="0"
                 placeholder="请输入积分值"
                 style="width: 200px;"
@@ -200,6 +200,12 @@
 import {addConfig, getConfig, updateConfig} from "@/api/live/liveQuestionLive";
 
 export default {
+  props: {
+    liveType: {
+      type: Number,
+      default: 1
+    }
+  },
   data() {
     return {
       loading: true,
@@ -248,7 +254,7 @@ export default {
           { required: true, message: '请选择参与条件', trigger: 'change'}
         ],
         watchDuration:[
-          { 
+          {
             validator: (rule, value, callback) => {
               if (this.watchRewardForm.participateCondition === '1') {
                 if (!value) {
@@ -259,12 +265,12 @@ export default {
               } else {
                 callback();
               }
-            }, 
+            },
             trigger: 'blur'
           }
         ],
         completionRate:[
-          { 
+          {
             validator: (rule, value, callback) => {
               if (this.watchRewardForm.participateCondition === '2') {
                 if (!value && value !== 0) {
@@ -277,12 +283,12 @@ export default {
               } else {
                 callback();
               }
-            }, 
+            },
             trigger: 'blur'
           }
         ],
         action:[
-          { 
+          {
             validator: (rule, value, callback) => {
               if (this.watchRewardForm.participateCondition === '1') {
                 if (!value) {
@@ -293,7 +299,7 @@ export default {
               } else {
                 callback();
               }
-            }, 
+            },
             trigger: 'change'
           }
         ],
@@ -318,10 +324,10 @@ export default {
       },
       // 添加实施动作选项
       actionOptions: [
-        // {
-        //   label: '现金红包',
-        //   value: '1'
-        // },
+        {
+          label: '现金红包',
+          value: '1'
+        },
         {
           label: '积分红包',
           value: '2'
@@ -352,6 +358,16 @@ export default {
           this.autoSaveEnabled();
         }
       }
+    },
+    // 监听直播类型变化,直播时不支持完课积分
+    liveType: {
+      handler(newValue) {
+        // 如果是直播(liveType == 1)且当前选择了完课积分,则切换到观看时长
+        if (newValue == 1 && this.watchRewardForm.participateCondition === '2') {
+          this.watchRewardForm.participateCondition = '1';
+        }
+      },
+      immediate: true
     }
   },
   created() {

+ 5 - 0
src/views/live/liveCouponIssue/index.vue

@@ -197,6 +197,10 @@ export default {
     /** 查询优惠券领取列表 */
     getList() {
       this.loading = true;
+      if (this.dateRange!=null && this.dateRange.length>0){
+        this.dateRange[0]=this.dateRange[0]+" 00:00:00"
+        this.dateRange[1]=this.dateRange[1]+" 23:59:59"
+      }
       listStoreCouponIssue(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
         this.storeCouponIssueList = response.rows;
         this.total = response.total;
@@ -235,6 +239,7 @@ export default {
     /** 重置按钮操作 */
     resetQuery() {
       this.resetForm("queryForm");
+      this.dateRange = []; // 清空日期范围选择器的值
       this.handleQuery();
     },
     // 多选框选中数据

+ 13 - 11
src/views/live/liveData/index.vue

@@ -531,29 +531,31 @@
         <el-table
           :data="userDetailList"
           v-loading="userDetailLoading"
-          border
-          style="width: 100%"
+          border          style="width: 100%"
         >
-          <el-table-column type="index" label="序号" width="60" align="center"></el-table-column>
-          <el-table-column prop="userName" label="用户名称" min-width="120"></el-table-column>
-          <el-table-column prop="liveWatchDuration" label="直播观看时长" width="140" align="center">
+          <el-table-column type="index" label="序号" width="60" align="center" fixed></el-table-column>
+          <el-table-column prop="userName" label="用户名称" min-width="120" show-overflow-tooltip></el-table-column>
+          <el-table-column prop="signFirst" label="打卡1" width="80" align="center" show-overflow-tooltip></el-table-column>
+          <el-table-column prop="signSecond" label="打卡2" width="80" align="center" show-overflow-tooltip></el-table-column>
+          <el-table-column prop="signThird" label="打卡3" width="80" align="center" show-overflow-tooltip></el-table-column>
+          <el-table-column prop="liveWatchDuration" label="直播观看时长" width="130" align="center">
             <template slot-scope="scope">
               {{ formatDuration(scope.row.liveWatchDuration || 0) }}
             </template>
           </el-table-column>
-          <el-table-column prop="playbackWatchDuration" label="回放观看时长" width="140" align="center">
+          <el-table-column prop="playbackWatchDuration" label="回放观看时长" width="130" align="center">
             <template slot-scope="scope">
               {{ formatDuration(scope.row.playbackWatchDuration || 0) }}
             </template>
           </el-table-column>
-          <el-table-column prop="orderCount" label="订单数" width="100" align="center"></el-table-column>
-          <el-table-column prop="orderAmount" label="订单金额" width="120" align="center">
+          <el-table-column prop="orderCount" label="订单数" width="80" align="center"></el-table-column>
+          <el-table-column prop="orderAmount" label="订单金额" width="110" align="center">
             <template slot-scope="scope">
               {{ formatMoney(scope.row.orderAmount) }}
             </template>
           </el-table-column>
-          <el-table-column prop="companyName" label="分公司" min-width="150"></el-table-column>
-          <el-table-column prop="salesName" label="销售" min-width="120"></el-table-column>
+          <el-table-column prop="salesName" label="邀请销售" min-width="100" show-overflow-tooltip></el-table-column>
+          <el-table-column prop="companyName" label="销售公司" min-width="120" show-overflow-tooltip></el-table-column>
         </el-table>
         <!-- 用户详情分页组件 -->
         <pagination
@@ -571,7 +573,7 @@
 </template>
 
 <script>
-import { listLiveData, exportLiveData, autoTagAndRemark, dashboardData, getLiveDataDetailBySql, getLiveUserDetailListBySql, exportLiveUserDetail } from "@/api/live/liveData";
+import { listLiveData, exportLiveData,  dashboardData, getLiveDataDetailBySql, getLiveUserDetailListBySql, exportLiveUserDetail } from "@/api/live/liveData";
 import { batchUpdateExternalContactNotes } from "@/api/qw/externalContact";
 import { addTag } from "@/api/qw/externalContact";
 

+ 2 - 2
src/views/live/liveOrder/index.vue

@@ -599,8 +599,8 @@ export default {
       // 同时清空范围选择器的值
       this.orderTimeRange = [];
       // 清空时间范围参数
-      this.queryParams.orderStartTime = null;
-      this.queryParams.orderEndTime = null;
+      this.queryParams.createTimeStart = null;
+      this.queryParams.createTimeEnd = null;
       this.handleQuery();
     },
 

+ 1 - 1
src/views/live/liveOrder/liveOrderDetails.vue

@@ -43,7 +43,7 @@
           <div class="operate-button-container" v-if="item.extendOrderId!=null"  >
             <el-button size="mini" @click="showErpOrder()" >ERP订单信息</el-button>
           </div>
-          <div class="operate-button-container" v-if="item.status>1">
+          <div class="operate-button-container" v-if="item.status>0">
             <el-button size="mini" @click="refund()" v-hasPermi="['his:liveOrder:refundOrderMoney']">退款</el-button>
           </div>
         </div>

+ 173 - 0
src/views/live/liveSignRecord/index.vue

@@ -0,0 +1,173 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px">
+      <el-form-item label="直播间ID" prop="liveId">
+        <el-input
+          v-model="queryParams.liveId"
+          placeholder="请输入直播间ID"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="用户名称" prop="userName">
+        <el-input
+          v-model="queryParams.userName"
+          placeholder="请输入用户名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="用户ID" prop="userId">
+        <el-input
+          v-model="queryParams.userId"
+          placeholder="请输入用户ID"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="签到序号" prop="signNo">
+        <el-input
+          v-model="queryParams.signNo"
+          placeholder="请输入签到序号"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          :loading="exportLoading"
+          @click="handleExport"
+          v-hasPermi="['his:liveSignRecord:export']"
+        >导出</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table border v-loading="loading" :data="signRecordList">
+      <el-table-column label="序号" align="center" type="index" width="60" />
+      <el-table-column label="直播ID" align="center" prop="liveId" width="120" />
+      <el-table-column label="用户ID" align="center" prop="userId" width="120" />
+      <el-table-column label="用户名称" align="center" prop="userName" width="150" show-overflow-tooltip />
+      <el-table-column label="签到序号" align="center" prop="signNo" width="120">
+        <template slot-scope="scope">
+          <el-tag type="success">
+            第{{ scope.row.signNo }}次
+          </el-tag>
+        </template>
+      </el-table-column>
+      <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>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+  </div>
+</template>
+
+<script>
+import { listLiveSignRecord, exportLiveSignRecord } from '@/api/live/liveSignRecord'
+
+export default {
+  name: 'LiveSignRecord',
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 导出遮罩层
+      exportLoading: false,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 直播签到记录表格数据
+      signRecordList: [],
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        liveId: null,
+        userId: null,
+        userName: null,
+        signNo: null
+      }
+    }
+  },
+  created() {
+    this.getList()
+  },
+  methods: {
+    /** 查询直播签到记录列表 */
+    getList() {
+      this.loading = true
+      listLiveSignRecord(this.queryParams).then(response => {
+        this.signRecordList = response.rows
+        this.total = response.total
+        this.loading = false
+      }).catch(error => {
+        console.error('获取签到记录失败:', error)
+        this.loading = false
+      })
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1
+      this.getList()
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm('queryForm')
+      this.handleQuery()
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      // 验证必须填写直播间ID
+      if (!this.queryParams.liveId) {
+        this.$message.warning('请先输入直播间ID再进行导出')
+        return
+      }
+      this.$confirm('是否确认导出所有签到记录数据项?', '警告', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.exportLoading = true
+        return exportLiveSignRecord(this.queryParams)
+      }).then(response => {
+        this.download(response.msg)
+        this.exportLoading = false
+      }).catch(() => {
+        this.exportLoading = false
+      })
+    }
+  }
+}
+</script>
+
+<style scoped>
+.app-container {
+  padding: 20px;
+}
+</style>

+ 1 - 1
src/views/live/liveUserRedRecord/index.vue

@@ -86,7 +86,7 @@
       <el-table-column label="抽奖ID" align="center" prop="redId" />
       <el-table-column label="直播间ID" align="center" prop="liveId" />
       <el-table-column label="中奖用户ID" align="center" prop="userId" />
-      <el-table-column label="芳华币数量" align="center" prop="integral" />
+      <el-table-column label="币数量" align="center" prop="integral" />
       <el-table-column label="创建日期" align="center" prop="createTime" width="180">
         <template slot-scope="scope">
           <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>

+ 16 - 1
src/views/live/liveVideo/index.vue

@@ -1,6 +1,20 @@
 <template>
   <div class="app-container">
-
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="视频名称" prop="remark">
+        <el-input
+          v-model="queryParams.remark"
+          placeholder="请输入视频名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
     <el-row :gutter="10" class="mb8">
       <el-col :span="1.5">
         <el-button
@@ -124,6 +138,7 @@ export default {
       queryParams: {
         pageNum: 1,
         pageSize: 10,
+        remark: null,
         liveId: -1,
         videoUrl: null,
         videoType: -1,

+ 10 - 8
src/views/live/order/index.vue

@@ -302,9 +302,11 @@
           v-model="createTimeRange"
           type="datetimerange"
           value-format="yyyy-MM-dd HH:mm:ss"
+          format="yyyy-MM-dd HH:mm:ss"
           range-separator="至"
           start-placeholder="开始日期"
           end-placeholder="结束日期"
+          :default-time="['00:00:00', '23:59:59']"
           @change="handleOrderTimeChange"
         />
       </el-form-item>
@@ -317,8 +319,11 @@
           v-model="payTimeRange"
           type="datetimerange"
           value-format="yyyy-MM-dd HH:mm:ss"
+          format="yyyy-MM-dd HH:mm:ss"
           start-placeholder="开始日期"
           end-placeholder="结束日期"
+          :default-time="['00:00:00', '23:59:59']"
+          @change="handlePayTimeChange"
         />
       </el-form-item>
 
@@ -728,7 +733,7 @@ export default {
         companyId: null,
         deptId: null,
         hfshh: null,
-        orderTypeFilter: null,
+        orderTypeFilter: 1,
         salesName: null,
         orderCodes: [],
         orderCode: null,
@@ -926,13 +931,10 @@ export default {
       this.getList()
     },
     handleOrderTimeChange(value) {
-      if (value && value.length === 2) {
-        this.queryParams.createTimeStart = value[0]
-        this.queryParams.createTimeEnd = value[1]
-      } else {
-        this.queryParams.createTimeStart = null
-        this.queryParams.createTimeEnd = null
-      }
+
+    },
+    handlePayTimeChange(value) {
+
     },
     /** 导出订单 */
     handleExport() {

+ 14 - 13
src/views/live/order/liveDetail.vue

@@ -73,6 +73,10 @@
           <el-descriptions-item label=" 公众号/渠道" ><span v-if="item!=null">{{item.channel}}</span></el-descriptions-item>
           <el-descriptions-item label=" 渠道" ><span v-if="item!=null"><dict-tag :options="channelOptions" :value="item.orderChannel"/></span></el-descriptions-item>
           <el-descriptions-item label=" 企微主体" ><span v-if="item!=null"><dict-tag :options="qwSubjectOptions" :value="item.qwSubject"/></span></el-descriptions-item>
+          <el-descriptions-item label="物流公司编码" ><span v-if="item!=null">{{item.deliveryCode}}</span></el-descriptions-item>
+          <el-descriptions-item label="物流公司名称" ><span v-if="item!=null">{{item.deliveryName}}</span></el-descriptions-item>
+          <el-descriptions-item label="物流单号" ><span v-if="item!=null">{{item.deliveryId}}</span></el-descriptions-item>
+          <el-descriptions-item label="发货时间" ><span v-if="item!=null">{{item.deliverySendTime}}</span></el-descriptions-item>
         </el-descriptions>
       </el-card>
     </div>
@@ -178,9 +182,10 @@
         <el-button size="mini" circle icon="el-icon-search" @click="showListD()" />
       </el-tooltip>
       <el-descriptions :column="3" border  >
-        <el-descriptions-item label="商品合计"  ><span v-if="item!=null">{{item.totalPrice}}</span></el-descriptions-item>
-        <el-descriptions-item label="应付金额"><span v-if="item.totalPrice!=null">{{item.totalPrice}}</span></el-descriptions-item>
-        <el-descriptions-item label="运费"><span v-if="item.payDelivery!=null">{{item.payDelivery}}</span></el-descriptions-item>
+        <el-descriptions-item label="商品合计"  ><span v-if="item!=null">{{(item.totalPrice-item.payPostage).toFixed(2)}}</span></el-descriptions-item>
+        <el-descriptions-item label="应付金额"><span v-if="item.totalPrice!=null">{{(item.totalPrice-item.payPostage).toFixed(2)}}</span></el-descriptions-item>
+<!--        <el-descriptions-item label="运费"><span v-if="item.payDelivery!=null">{{item.payDelivery}}</span></el-descriptions-item>-->
+        <el-descriptions-item label="运费"><span v-if="item.payDelivery!=null">{{item.payPostage}}</span></el-descriptions-item>
         <el-descriptions-item label="优惠券"  ><span v-if="item.discountMoney!=null"/>{{item.discountMoney}}</el-descriptions-item>
         <el-descriptions-item label="积分抵扣" >  <span v-if="item!=null">{{item.payIntegral}}</span>  </el-descriptions-item>
         <el-descriptions-item label="实付金额" >  <span v-if="item!=null">{{item.payMoney}}</span>  </el-descriptions-item>
@@ -188,7 +193,7 @@
         <el-descriptions-item label="服务费" >  <span v-if="item!=null">{{0.00}}</span>  </el-descriptions-item>
       </el-descriptions>
       <div style="float: right;margin: 20px" v-if="item.totalPrice!=null">
-        合计:<span class="color-danger">¥{{item.totalPrice.toFixed(2)}}</span>
+        合计:<span class="color-danger">¥{{item.payMoney.toFixed(2)}}</span>
       </div>
     </div>
 
@@ -710,17 +715,15 @@ export default {
 
     //修改订单状态
     submitEditForm(){
+      var that = this;
       this.$refs["editForm"].validate(valid => {
         if (valid) {
           updateLiveOrder(this.editForm).then(response => {
             if (response.code === 200) {
               this.msgSuccess("操作成功");
               this.edit.open = false;
-              getLiveOrder(this.item.orderId).then(response => {
-                this.item=response.data
-                that.getlogList(this.item.orderId);
-                that.$parent.$parent.getList();
-              });
+              // 刷新当前页面数据
+              this.getDetails(this.item.orderId, this.nickName, this.storeName);
             }
           });
         }
@@ -982,10 +985,8 @@ export default {
             if (response.code === 200) {
               this.msgSuccess("操作成功");
               this.editDy.open = false;
-              getLiveOrder(this.item.orderId).then(response => {
-                this.item = response.data;
-                this.$parent.$parent.getList();
-              });
+              // 刷新当前页面数据
+              this.getDetails(this.item.orderId, this.nickName, this.storeName);
             }
           })
         }

+ 7 - 2
src/views/live/order/storeDetail.vue

@@ -81,9 +81,9 @@
 <!--            <el-descriptions-item label="订单类型"  >
               <el-tag prop="orderType" v-for="(item, index) in orderTypeOptions"    v-if="order!=null&&order.orderType==item.dictValue">{{item.dictLabel}}</el-tag>
             </el-descriptions-item>-->
-            <el-descriptions-item label="物流公司编"  >
+            <el-descriptions-item label="物流公司编"  >
                 <span v-if="order!=null">
-                  {{order.deliverySn}}
+                  {{order.deliveryCode || order.deliverySn}}
                 </span>
             </el-descriptions-item>
             <el-descriptions-item label="物流公司名称"  >
@@ -96,6 +96,11 @@
                   {{order.deliveryId}}
                 </span>
             </el-descriptions-item>
+            <el-descriptions-item label="发货时间"  >
+                <span v-if="order!=null">
+                  {{order.deliverySendTime}}
+                </span>
+            </el-descriptions-item>
             <el-descriptions-item label="物流状态"  >
                 <span v-if="order!=null">
                   <el-tag prop="deliveryId" v-for="(item, index) in deliveryStatusOptions"    v-if="order!=null&&order.deliveryStatus==item.dictValue">{{item.dictLabel}}</el-tag>

+ 7 - 2
src/views/live/order/userDetail.vue

@@ -81,9 +81,9 @@
 <!--            <el-descriptions-item label="订单类型"  >
               <el-tag prop="orderType" v-for="(item, index) in orderTypeOptions"    v-if="order!=null&&order.orderType==item.dictValue">{{item.dictLabel}}</el-tag>
             </el-descriptions-item>-->
-            <el-descriptions-item label="物流公司编"  >
+            <el-descriptions-item label="物流公司编"  >
                 <span v-if="order!=null">
-                  {{order.deliverySn}}
+                  {{order.deliveryCode || order.deliverySn}}
                 </span>
             </el-descriptions-item>
             <el-descriptions-item label="物流公司名称"  >
@@ -96,6 +96,11 @@
                   {{order.deliveryId}}
                 </span>
             </el-descriptions-item>
+            <el-descriptions-item label="发货时间"  >
+                <span v-if="order!=null">
+                  {{order.deliverySendTime}}
+                </span>
+            </el-descriptions-item>
             <el-descriptions-item label="物流状态"  >
                 <span v-if="order!=null">
                   <el-tag prop="deliveryId" v-for="(item, index) in deliveryStatusOptions"    v-if="order!=null&&order.deliveryStatus==item.dictValue">{{item.dictLabel}}</el-tag>

+ 148 - 0
src/views/live/upload2WX/index.vue

@@ -0,0 +1,148 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px">
+      <el-form-item label="小程序" prop="appid">
+        <el-select 
+          v-model="queryParams.appid" 
+          placeholder="请选择小程序" 
+          clearable 
+          filterable
+          size="small"
+          style="width: 200px"
+        >
+          <el-option
+            v-for="item in appOptions"
+            :key="item.appid"
+            :label="item.name"
+            :value="item.appid"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="上传状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="请选择上传状态" clearable size="small">
+          <el-option label="待执行" value="0" />
+          <el-option label="执行中" value="1" />
+          <el-option label="执行成功" value="2" />
+          <el-option label="执行失败" value="3" />
+          <el-option label="已取消" value="4" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="订单号" prop="orderCode">
+        <el-input
+          v-model="queryParams.orderCode"
+          placeholder="请输入订单号"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-table v-loading="loading" :data="wxExpressTaskList">
+      <el-table-column label="ID" align="center" prop="id" width="80" />
+      <el-table-column label="订单号" align="center" prop="orderCode" width="180" />
+      <el-table-column label="用户ID" align="center" prop="userId" width="100" />
+      <el-table-column label="数据" align="center" prop="data" width="200" show-overflow-tooltip />
+      <el-table-column label="任务状态" align="center" prop="status" width="120">
+        <template slot-scope="scope">
+          <el-tag v-if="scope.row.status === 0" type="info">待执行</el-tag>
+          <el-tag v-else-if="scope.row.status === 1" type="warning">执行中</el-tag>
+          <el-tag v-else-if="scope.row.status === 2" type="success">执行成功</el-tag>
+          <el-tag v-else-if="scope.row.status === 3" type="danger">执行失败</el-tag>
+          <el-tag v-else-if="scope.row.status === 4" type="info">已取消</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="重试次数" align="center" prop="retryCount" width="100" />
+      <el-table-column label="请求体" align="center" prop="requestBody" width="200" show-overflow-tooltip />
+      <el-table-column label="响应体" align="center" prop="responseBody" width="200" show-overflow-tooltip />
+      <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>
+        </template>
+      </el-table-column>
+      <el-table-column label="快递公司" align="center" prop="expressCompany" width="120" />
+      <el-table-column label="快递单号" align="center" prop="expressNo" width="150" />
+      <el-table-column label="订单类型" align="center" prop="type" width="120">
+        <template slot-scope="scope">
+          <span v-if="scope.row.type === 0">商城订单</span>
+          <span v-else-if="scope.row.type === 1">直播订单</span>
+          <span v-else>-</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="小程序ID" align="center" prop="appid" width="180" />
+    </el-table>
+
+    <pagination
+      v-show="total > 0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+  </div>
+</template>
+
+<script>
+import { list } from "@/api/live/wxExpressTask";
+import { list as listAppConfig } from "@/api/course/coursePlaySourceConfig";
+
+export default {
+  name: "WxExpressTask",
+  data() {
+    return {
+      loading: true,
+      showSearch: true,
+      wxExpressTaskList: [],
+      total: 0,
+      appOptions: [],
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        appid: null,
+        status: null,
+        orderCode: null
+      }
+    };
+  },
+  created() {
+    this.getList();
+    this.getAppList();
+  },
+  methods: {
+    /** 查询微信快递任务列表 */
+    getList() {
+      this.loading = true;
+      list(this.queryParams).then(response => {
+        this.wxExpressTaskList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    /** 获取小程序列表 */
+    getAppList() {
+      listAppConfig({ pageNum: 1, pageSize: 100 }).then(response => {
+        if (response.rows) {
+          this.appOptions = response.rows;
+        }
+      });
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    }
+  }
+};
+</script>
+
+<style scoped>
+</style>

+ 66 - 2
src/views/live/words/index.vue

@@ -57,6 +57,14 @@
           v-hasPermi="['live:words:remove']"
         >删除</el-button>
       </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          icon="el-icon-upload2"
+          size="mini"
+          @click="handleImport"
+        >导入</el-button>
+      </el-col>
       <el-col :span="1.5">
         <el-button
           type="warning"
@@ -120,11 +128,29 @@
         <el-button @click="cancel">取 消</el-button>
       </div>
     </el-dialog>
+    <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
+      <el-upload ref="upload" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag>
+        <i class="el-icon-upload"></i>
+        <div class="el-upload__text">
+          将文件拖到此处,或
+          <em>点击上传</em>
+        </div>
+        <div class="el-upload__tip" slot="tip">
+          <el-link type="info" style="font-size:12px" @click="importTemplate">下载模板</el-link>
+        </div>
+        <div class="el-upload__tip" style="color:red" slot="tip">提示:仅允许导入“xls”或“xlsx”格式文件!</div>
+      </el-upload>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitFileForm">确 定</el-button>
+        <el-button @click="upload.open = false">取 消</el-button>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
 <script>
-import {listWords, getWords, delWords, addWords, updateWords, exportWords} from "@/api/live/words";
+import {listWords, getWords, delWords, addWords, updateWords, exportWords,importTemplate} from "@/api/live/words";
+import {getToken} from "@/utils/auth";
 
 export default {
   name: "Words",
@@ -144,6 +170,18 @@ export default {
       showSearch: true,
       // 总条数
       total: 0,
+      upload: {
+        // 是否显示弹出层(用户导入)
+        open: false,
+        // 弹出层标题(用户导入)
+        title: "",
+        // 是否禁用上传
+        isUploading: false,
+        // 设置上传的请求头部
+        headers: { Authorization: "Bearer " + getToken() },
+        // 上传的地址
+        url: process.env.VUE_APP_BASE_API + "/live/words/importData",
+      },
       // 直播间敏感词过滤表格数据
       wordsList: [],
       // 弹出层标题
@@ -171,6 +209,21 @@ export default {
     this.getList();
   },
   methods: {
+    submitFileForm() {
+      this.$refs.upload.submit();
+    },
+    // 文件上传中处理
+    handleFileUploadProgress(event, file, fileList) {
+      this.upload.isUploading = true;
+    },
+    // 文件上传成功处理
+    handleFileSuccess(response, file, fileList) {
+      this.upload.open = false;
+      this.upload.isUploading = false;
+      this.$refs.upload.clearFiles();
+      this.$alert(response.msg, "导入结果", { dangerouslyUseHTMLString: true });
+      this.getList();
+    },
     /** 查询直播间敏感词过滤列表 */
     getList() {
       this.loading = true;
@@ -194,6 +247,12 @@ export default {
       };
       this.resetForm("form");
     },
+    /** 下载模板操作 */
+    importTemplate() {
+      importTemplate().then((response) => {
+        this.download(response.msg);
+      });
+    },
     /** 搜索按钮操作 */
     handleQuery() {
       this.queryParams.pageNum = 1;
@@ -274,7 +333,12 @@ export default {
           this.download(response.msg);
           this.exportLoading = false;
         }).catch(() => {});
-    }
+    },
+    /** 导入按钮操作 */
+    handleImport() {
+      this.upload.title = "导入";
+      this.upload.open = true;
+    },
   }
 };
 </script>

+ 38 - 2
src/views/system/config/config.vue

@@ -2987,6 +2987,25 @@
           </div>
         </el-form>
       </el-tab-pane>
+      <el-tab-pane label="直播配置" name="living.config">
+        <el-form ref="formzb" :model="formzb" label-width="150px">
+          <el-form-item label="类型" prop="app">
+            <el-radio-group v-model="formzb.app">
+              <el-radio label="live">直播</el-radio>
+            </el-radio-group>
+          </el-form-item>
+          <el-form-item label="直播流链接" prop="domain">
+            <el-input v-model="formzb.domain" placeholder="请输入直播流链接"></el-input>
+          </el-form-item>
+          <el-form-item label="推流链接" prop="http">
+            <el-input v-model="formzb.http" placeholder="请输入推流链接"></el-input>
+          </el-form-item>
+          <br>
+          <div class="footer">
+            <el-button type="primary" @click="submitFormzb">提 交</el-button>
+          </div>
+        </el-form>
+      </el-tab-pane>
 
       <!--   福袋配置    -->
       <el-tab-pane label="福袋配置" name="luckyBag.config">
@@ -3207,7 +3226,6 @@
 
         </el-form>
       </el-tab-pane>
-
     </el-tabs>
 
 
@@ -3293,6 +3311,7 @@ export default {
       form9: {},
       form10: [],
       form12: [],
+      formzb: [],
       form13: {
         dfAccounts: [] // 初始化代付管家账户数组
       },
@@ -4006,7 +4025,15 @@ export default {
           console.log("----------"+response.data)
           this.configId = response.data.configId
           this.configKey = response.data.configKey
-          this.form34 =JSON.parse(response.data.configValue);
+          this.formim =JSON.parse(response.data.configValue);
+        }
+        if(key == 'living.config'){
+          if(!!response.data){
+            this.configId = response.data.configId
+            this.configKey = response.data.configKey
+            this.formzb = {...this.formzb, ...JSON.parse(response.data.configValue)}
+            console.log(this.formzb );
+          }
         }
         if(key=="app.pageConfig"){
           const defaultForm = this.form35
@@ -4368,6 +4395,15 @@ export default {
       console.log(this.form27.pass_columns)
 
     },
+    submitFormzb(){
+      const param = { configId: this.configId, configName : "直播源配置", configKey: this.configKey, configValue: JSON.stringify(this.formzb) }
+      console.log(param)
+      updateConfigByKey(param).then(response => {
+        if (response.code === 200) {
+          this.msgSuccess('修改成功')
+        }
+      })
+    },
     submitForm24() {
       this.$refs['form24'].validate(valid => {
         if (valid) {

+ 6 - 0
vue.config.js

@@ -25,6 +25,12 @@ module.exports = {
   lintOnSave: process.env.NODE_ENV === 'development',
   // 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。
   productionSourceMap: false,
+  // 需要Babel转译的依赖包(这些包使用了ES2020+语法如??、?.、数字分隔符等)
+  transpileDependencies: [
+    '@aws-sdk',
+    '@smithy',
+    '@huaweicloud'
+  ],
   // webpack-dev-server 相关配置
   devServer: {
     host: '0.0.0.0',