Ver código fonte

Merge remote-tracking branch 'origin/红德堂' into 红德堂-test

# Conflicts:
#	.env.prod-hdt
wangxy 3 dias atrás
pai
commit
4b3520aa9f

+ 1 - 1
.env.prod-hdt

@@ -31,7 +31,7 @@ VUE_APP_VIDEO_URL = https://bdhdtvolcengine.ylrztop.com
 #火山云视频点播空间名
 VUE_APP_HSY_SPACE = bdhdt-2114522511
 #直播解码路径
-LIVE_PATH = /live
+VUE_APP_LIVE_PATH = /live
 
 # 开发环境配置
 ENV = 'development'

+ 2 - 1
src/api/his/user.js

@@ -75,7 +75,8 @@ export function exportUser(query) {
 export function exportOpenId() {
   return request({
     url: '/his/user/exportOpenId',
-    method: 'get'
+    method: 'post',
+    responseType: 'blob'
   })
 }
 

+ 2 - 2
src/api/live/liveData.js

@@ -28,9 +28,9 @@ export function getLiveDataDetailBySql(liveId) {
   })
 }
 
-export function getLiveUserDetailListBySql(liveId) {
+export function getLiveUserDetailListBySql(liveId, pageNum, pageSize) {
   return request({
-    url: '/liveData/liveData/getLiveUserDetailListBySql?liveId=' + liveId,
+    url: '/liveData/liveData/getLiveUserDetailListBySql?liveId=' + liveId + '&pageNum=' + (pageNum || 1) + '&pageSize=' + (pageSize || 100),
     method: 'get'
   })
 }

+ 1 - 1
src/components/LiveVideoUpload/index.vue

@@ -209,7 +209,7 @@ export default {
     async uploadVideoToTxPcdn() {
       try {
         const file = this.fileList[0].raw;
-        const data = await uploadObject(file, this.updateTxProgress, this.type);
+        const data = await uploadObject(file, this.updateTxProgress, 3);
         console.log("腾讯COS返回========>", data);
         console.log("isPrivate=======>", this.isPrivate)
         let line_1 = '';

+ 41 - 7
src/views/his/user/index.vue

@@ -104,7 +104,7 @@
           plain
           icon="el-icon-download"
           size="mini"
-          :loading="exportLoading"
+          :loading="exportOpenIdLoading"
           @click="handleExportOpenId"
           v-hasPermi="['his:user:exportOpenId']"
         >服务号用户OPENID导出</el-button>
@@ -286,7 +286,9 @@
 </template>
 
 <script>
+import axios from 'axios'
 import { listUser, getUser, delUser, addUser, updateUser, exportUser, addPoint,exportOpenId } from "@/api/his/user";
+import { getToken } from '@/utils/auth';
 import { getCompanyUserList, changeCompanyUser, getCompanyList } from '@/api/company/companyUser';
 import userDetails from '../../components/his/userDetails.vue';
 import userDetailsByNew from './userDetails.vue';
@@ -312,6 +314,7 @@ export default {
       loading: true,
       // 导出遮罩层
       exportLoading: false,
+      exportOpenIdLoading: false,
       // 选中数组
       ids: [],
       orOptions:[],
@@ -600,13 +603,44 @@ export default {
         cancelButtonText: "取消",
         type: "warning"
       }).then(() => {
-        this.exportLoading = true;
-        return exportOpenId();
+        this.exportOpenIdLoading = true;
+
+        // 直接使用axios发起请求,绕过响应拦截器
+        return axios({
+          url: process.env.VUE_APP_BASE_API + '/his/user/exportOpenId',
+          method: 'post',
+          responseType: 'blob', // 重要:设置响应类型为blob
+          headers: {
+            'Authorization': 'Bearer ' + getToken(),
+            'X-Frontend-Type': 'admin'
+          }
+        });
       }).then(response => {
-        this.download(response.msg);
-        this.exportLoading = false;
-      }).catch(() => {
-        this.exportLoading = false;
+        // 处理文件流下载
+        const blob = new Blob([response.data], { type: 'application/vnd.ms-excel' });
+
+        // 直接使用默认文件名,因为后端没有返回
+        const fileName = '用户openId数据.xlsx';
+
+        // 创建下载链接
+        const url = window.URL.createObjectURL(blob);
+        const link = document.createElement('a');
+        link.href = url;
+        link.setAttribute('download', fileName);
+
+        // 触发下载
+        document.body.appendChild(link);
+        link.click();
+
+        // 清理
+        document.body.removeChild(link);
+        window.URL.revokeObjectURL(url);
+
+        this.exportOpenIdLoading = false;
+      }).catch(error => {
+        this.exportOpenIdLoading = false;
+        console.error('导出失败:', error);
+        this.$message.error('导出失败,请稍后重试');
       });
     }
   }

+ 3 - 3
src/views/his/user/indexProject.vue

@@ -707,13 +707,13 @@ export default {
     },
     /** 删除按钮操作 */
     handleDelete(row) {
-      const companyUserId = row.companyUserId;
-      this.$confirm('是否确认删除用户编号为"' + companyUserId + '"的数据项?', "警告", {
+      const userCompanyUserId = row.userCompanyUserId;
+      this.$confirm('是否确认删除用户编号为"' + userCompanyUserId + '"的数据项?', "警告", {
         confirmButtonText: "确定",
         cancelButtonText: "取消",
         type: "warning"
       }).then(function() {
-        return delUserCompanyUser(companyUserId);
+        return delUserCompanyUser(userCompanyUserId);
       }).then(() => {
         this.getList();
         this.msgSuccess("删除成功");

+ 31 - 10
src/views/live/liveData/index.vue

@@ -363,25 +363,25 @@
             </el-col>
             <el-col :span="12">
               <div class="detail-item">
-                <span class="detail-label">>20分钟人数(直播):</span>
+                <span class="detail-label">>=20分钟人数(直播):</span>
                 <span class="detail-value">{{ detailData.liveOver20Minutes || 0 }}</span>
               </div>
             </el-col>
             <el-col :span="12">
               <div class="detail-item">
-                <span class="detail-label">>30分钟人数(直播):</span>
+                <span class="detail-label">>=30分钟人数(直播):</span>
                 <span class="detail-value">{{ detailData.liveOver30Minutes || 0 }}</span>
               </div>
             </el-col>
             <el-col :span="12">
               <div class="detail-item">
-                <span class="detail-label">到课完课率直播(>20分钟):</span>
+                <span class="detail-label">到课完课率直播(>=20分钟):</span>
                 <span class="detail-value">{{ formatPercent(detailData.liveCompletionRate20) }}</span>
               </div>
             </el-col>
             <el-col :span="12">
               <div class="detail-item">
-                <span class="detail-label">到课完课率直播(>30分钟):</span>
+                <span class="detail-label">到课完课率直播(>=30分钟):</span>
                 <span class="detail-value">{{ formatPercent(detailData.liveCompletionRate30) }}</span>
               </div>
             </el-col>
@@ -399,25 +399,25 @@
             </el-col>
             <el-col :span="12">
               <div class="detail-item">
-                <span class="detail-label">>20分钟人数(回放):</span>
+                <span class="detail-label">>=20分钟人数(回放):</span>
                 <span class="detail-value">{{ detailData.playbackOver20Minutes || 0 }}</span>
               </div>
             </el-col>
             <el-col :span="12">
               <div class="detail-item">
-                <span class="detail-label">>30分钟人数(回放):</span>
+                <span class="detail-label">>=30分钟人数(回放):</span>
                 <span class="detail-value">{{ detailData.playbackOver30Minutes || 0 }}</span>
               </div>
             </el-col>
             <el-col :span="12">
               <div class="detail-item">
-                <span class="detail-label">到课完课率回放(>20分钟):</span>
+                <span class="detail-label">到课完课率回放(>=20分钟):</span>
                 <span class="detail-value">{{ formatPercent(detailData.playbackCompletionRate20) }}</span>
               </div>
             </el-col>
             <el-col :span="12">
               <div class="detail-item">
-                <span class="detail-label">到课完课率回放(>30分钟):</span>
+                <span class="detail-label">到课完课率回放(>=30分钟):</span>
                 <span class="detail-value">{{ formatPercent(detailData.playbackCompletionRate30) }}</span>
               </div>
             </el-col>
@@ -555,6 +555,16 @@
           <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>
+        <!-- 用户详情分页组件 -->
+        <pagination
+          v-show="userDetailTotal > 0"
+          :total="userDetailTotal"
+          :page.sync="userDetailQueryParams.pageNum"
+          :limit.sync="userDetailQueryParams.pageSize"
+          :page-sizes="[10, 100, 1000]"
+          @pagination="handleViewUserDetail"
+          style="margin-top: 20px;"
+        />
       </div>
     </el-drawer>
   </div>
@@ -633,7 +643,12 @@ export default {
       userDetailList: [],
       userDetailLoading: false,
       showUserDetail: false,
-      userDetailExportLoading: false
+      userDetailExportLoading: false,
+      userDetailTotal: 0,
+      userDetailQueryParams: {
+        pageNum: 1,
+        pageSize: 10
+      }
     };
   },
   created() {
@@ -882,9 +897,10 @@ export default {
       if (!this.currentLiveId) return;
       this.showUserDetail = true;
       this.userDetailLoading = true;
-      getLiveUserDetailListBySql(this.currentLiveId).then(response => {
+      getLiveUserDetailListBySql(this.currentLiveId, this.userDetailQueryParams.pageNum, this.userDetailQueryParams.pageSize).then(response => {
         if (response.code === 200) {
           this.userDetailList = response.data || [];
+          this.userDetailTotal = response.total || 0;
         }
         this.userDetailLoading = false;
       }).catch(() => {
@@ -898,6 +914,11 @@ export default {
       this.detailData = {};
       this.userDetailList = [];
       this.currentLiveId = null;
+      this.userDetailTotal = 0;
+      this.userDetailQueryParams = {
+        pageNum: 1,
+        pageSize: 100
+      };
     },
     /** 格式化百分比 */
     formatPercent(value) {

+ 83 - 41
src/views/live/order/index.vue

@@ -161,37 +161,37 @@
 <!--        </el-select>-->
 <!--      </el-form-item>-->
 
-      <el-form-item label="结算状态" prop="deliveryPayStatus">
-        <el-select v-model="queryParams.deliveryPayStatus" placeholder="请选择物流结算状态" clearable size="small">
-          <el-option
-            v-for="item in deliveryPayStatusOptions"
-            :key="item.dictValue"
-            :label="item.dictLabel"
-            :value="item.dictValue"
-          />
-        </el-select>
-      </el-form-item>
+<!--      <el-form-item label="结算状态" prop="deliveryPayStatus">-->
+<!--        <el-select v-model="queryParams.deliveryPayStatus" placeholder="请选择物流结算状态" clearable size="small">-->
+<!--          <el-option-->
+<!--            v-for="item in deliveryPayStatusOptions"-->
+<!--            :key="item.dictValue"-->
+<!--            :label="item.dictLabel"-->
+<!--            :value="item.dictValue"-->
+<!--          />-->
+<!--        </el-select>-->
+<!--      </el-form-item>-->
 
-      <el-form-item label="小程序" prop="appId">
-        <el-select v-model="queryParams.appId" placeholder="请选择所属小程序" clearable size="small">
-          <el-option
-            v-for="dict in appMallOptions"
-            :key="dict.appid"
-            :label="dict.name + '(' + dict.appid + ')'"
-            :value="dict.appid"
-          />
-        </el-select>
-      </el-form-item>
+<!--      <el-form-item label="小程序" prop="appId">-->
+<!--        <el-select v-model="queryParams.appId" placeholder="请选择所属小程序" clearable size="small">-->
+<!--          <el-option-->
+<!--            v-for="dict in appMallOptions"-->
+<!--            :key="dict.appid"-->
+<!--            :label="dict.name + '(' + dict.appid + ')'"-->
+<!--            :value="dict.appid"-->
+<!--          />-->
+<!--        </el-select>-->
+<!--      </el-form-item>-->
 
-      <el-form-item label="商品规格" prop="productSpec">
-        <el-input
-          v-model="queryParams.productSpec"
-          placeholder="请输入商品规格"
-          clearable
-          size="small"
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
+<!--      <el-form-item label="商品规格" prop="productSpec">-->
+<!--        <el-input-->
+<!--          v-model="queryParams.productSpec"-->
+<!--          placeholder="请输入商品规格"-->
+<!--          clearable-->
+<!--          size="small"-->
+<!--          @keyup.enter.native="handleQuery"-->
+<!--        />-->
+<!--      </el-form-item>-->
 
 <!--      <el-form-item label="商品数量" prop="totalNum">-->
 <!--        <el-input-->
@@ -232,6 +232,15 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
+      <el-form-item label="汇付商户订单号" prop="hfshh">
+        <el-input
+          v-model="queryParams.hfshh"
+          placeholder="请输入汇付商户订单号"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
 
 <!--      <el-form-item label="成本价格" prop="cost">-->
 <!--        <el-input-->
@@ -253,16 +262,16 @@
 <!--        />-->
 <!--      </el-form-item>-->
 
-      <el-form-item label="档期归属" prop="scheduleId">
-        <el-select filterable style="width: 215px" v-model="queryParams.scheduleId" placeholder="请选择档期" clearable size="small">
-          <el-option
-            v-for="item in scheduleOptions"
-            :key="item.id"
-            :label="item.name"
-            :value="item.id"
-          />
-        </el-select>
-      </el-form-item>
+<!--      <el-form-item label="档期归属" prop="scheduleId">-->
+<!--        <el-select filterable style="width: 215px" v-model="queryParams.scheduleId" placeholder="请选择档期" clearable size="small">-->
+<!--          <el-option-->
+<!--            v-for="item in scheduleOptions"-->
+<!--            :key="item.id"-->
+<!--            :label="item.name"-->
+<!--            :value="item.id"-->
+<!--          />-->
+<!--        </el-select>-->
+<!--      </el-form-item>-->
 
       <el-form-item label="代服账户" prop="erpAccount" v-if="SFDFopen">
         <el-select v-model="queryParams.erpAccount" style="width: 215px" placeholder="ERP账户" clearable size="small">
@@ -293,6 +302,7 @@
           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="结束日期"
@@ -308,8 +318,10 @@
           v-model="payTimeRange"
           type="datetimerange"
           value-format="yyyy-MM-dd HH:mm:ss"
+          format="yyyy-MM-dd HH:mm:ss"
           start-placeholder="开始日期"
           end-placeholder="结束日期"
+          @change="handlePayTimeChange"
         />
       </el-form-item>
 
@@ -447,6 +459,7 @@
       <el-table-column label="手机号" align="center" prop="userPhone" width="120px" />
       <el-table-column label="商品规格" align="center" prop="productSpec" width="120px" />
       <el-table-column label="商品数量" align="center" prop="totalNum" width="100px" />
+      <el-table-column label="汇付商户订单号" align="center" prop="hfshh" width="100px" />
       <el-table-column label="订单金额" align="center" prop="totalPrice" width="100px">
         <template slot-scope="scope">
           <span v-if="scope.row.totalPrice != null">{{ scope.row.totalPrice.toFixed(2) }}</span>
@@ -717,6 +730,7 @@ export default {
         pageSize: 10,
         companyId: null,
         deptId: null,
+        hfshh: null,
         orderTypeFilter: null,
         salesName: null,
         orderCodes: [],
@@ -916,13 +930,41 @@ export default {
     },
     handleOrderTimeChange(value) {
       if (value && value.length === 2) {
-        this.queryParams.createTimeStart = value[0]
-        this.queryParams.createTimeEnd = value[1]
+        // 如果结束时间不是当天的23:59:59,则自动设置为当天的23:59:59
+        const endDate = new Date(value[1])
+        const endDateStr = value[1]
+        const datePart = endDateStr.split(' ')[0] // 获取日期部分
+        const timePart = endDateStr.split(' ')[1] // 获取时间部分
+        
+        // 如果时间部分不是23:59:59,则设置为23:59:59
+        if (timePart !== '23:59:59') {
+          const newEndTime = datePart + ' 23:59:59'
+          this.createTimeRange = [value[0], newEndTime]
+          this.queryParams.createTimeStart = value[0]
+          this.queryParams.createTimeEnd = newEndTime
+        } else {
+          this.queryParams.createTimeStart = value[0]
+          this.queryParams.createTimeEnd = value[1]
+        }
       } else {
         this.queryParams.createTimeStart = null
         this.queryParams.createTimeEnd = null
       }
     },
+    handlePayTimeChange(value) {
+      if (value && value.length === 2) {
+        // 如果结束时间不是当天的23:59:59,则自动设置为当天的23:59:59
+        const endDateStr = value[1]
+        const datePart = endDateStr.split(' ')[0] // 获取日期部分
+        const timePart = endDateStr.split(' ')[1] // 获取时间部分
+        
+        // 如果时间部分不是23:59:59,则设置为23:59:59
+        if (timePart !== '23:59:59') {
+          const newEndTime = datePart + ' 23:59:59'
+          this.payTimeRange = [value[0], newEndTime]
+        }
+      }
+    },
     /** 导出订单 */
     handleExport() {
       this.prepareExportParams()