<template>
|
<div class="wrapper">
|
<Card class="user-action-card">
|
<Row @keydown.enter.native="handleSearch">
|
<Form ref="searchForm" :model="searchForm" inline :label-width="80" style="width: 100%" class="search-form">
|
<Form-item label="用户昵称" prop="userName">
|
<Input type="text" v-model="searchForm.userName" placeholder="请输入用户昵称" clearable style="width: 200px" />
|
</Form-item>
|
<Form-item label="页面类型" prop="pageCode">
|
<Select
|
v-model="searchForm.pageCode"
|
clearable
|
filterable
|
style="width: 200px"
|
placeholder="请选择页面类型">
|
<Option
|
v-for="item in pageTypeOptions"
|
:key="item.value"
|
:value="item.value"
|
:label="item.label">
|
{{ item.label }}
|
</Option>
|
</Select>
|
</Form-item>
|
<Form-item label="开始时间" prop="beginDate">
|
<DatePicker
|
v-model="searchForm.beginDate"
|
type="datetime"
|
placeholder="请选择开始时间"
|
style="width: 200px">
|
</DatePicker>
|
</Form-item>
|
<Form-item label="结束时间" prop="endDate">
|
<DatePicker
|
v-model="searchForm.endDate"
|
type="datetime"
|
placeholder="请选择结束时间"
|
style="width: 200px">
|
</DatePicker>
|
</Form-item>
|
<Button @click="handleSearch" type="primary" icon="ios-search" class="search-btn">搜索</Button>
|
<Button @click="handleReset" type="default" class="search-btn">重置</Button>
|
</Form>
|
</Row>
|
<div class="table-container">
|
<Table
|
:loading="loading"
|
border
|
:columns="columns"
|
:data="data"
|
ref="table">
|
</Table>
|
</div>
|
<Row type="flex" justify="end" class="mt_10">
|
<Page
|
:current="searchForm.pageNumber"
|
:total="total"
|
:page-size="searchForm.pageSize"
|
@on-change="changePage"
|
@on-page-size-change="changePageSize"
|
:page-size-opts="[10, 20, 50]"
|
size="small"
|
show-total
|
show-elevator
|
show-sizer>
|
</Page>
|
</Row>
|
</Card>
|
|
<!-- 视频详情弹窗 -->
|
<Modal
|
v-model="videoDetailShow"
|
:title="videoDetailTitle"
|
width="800"
|
:mask-closable="false"
|
@on-cancel="closeVideoDetail">
|
<div class="video-info" v-if="currentVideoDetail && !videoLoading">
|
<div class="video-basic-info">
|
<h3>{{ currentVideoDetail.title }}</h3>
|
</div>
|
<div style="margin: 15px 0; height: 1px; background-color: #e8eaec;"></div>
|
</div>
|
<div class="video-wrapper">
|
<video
|
v-if="videoDetailUrl"
|
:src="videoDetailUrl"
|
autoplay
|
controls
|
style="width: 100%; height: 450px"
|
/>
|
<div v-else style="text-align: center; padding: 50px 0;">
|
<Spin v-if="videoLoading" fix />
|
<div v-else>暂无视频内容</div>
|
</div>
|
</div>
|
<div slot="footer">
|
<Button type="text" @click="closeVideoDetail">关闭</Button>
|
</div>
|
</Modal>
|
</div>
|
</template>
|
|
<script>
|
import { userShareList } from "@/api/userAction";
|
import { formatDate } from "@/utils/filters";
|
import { getVideoById } from "@/api/video";
|
import { getFilePreview } from "@/api/file";
|
|
export default {
|
name: "userShareAction",
|
data() {
|
// 设置默认时间改为最近7天
|
const now = new Date();
|
const endTime = new Date(now);
|
endTime.setHours(23, 59, 59, 999);
|
|
// 开始时间为7天前(包含今天,总共7天)
|
const startTime = new Date(now);
|
startTime.setDate(startTime.getDate() - 6);
|
startTime.setHours(0, 0, 0, 0);
|
|
return {
|
loading: false, // 默认不加载
|
searchForm: {
|
pageNumber: 1,
|
pageSize: 10,
|
userName: "",
|
pageCode: "",
|
beginDate: startTime,
|
endDate: endTime
|
},
|
// 页面类型选项(用于下拉框)
|
pageTypeOptions: [
|
{ value: "RECOMMEND_VIDEO", label: "首页推荐视频" },
|
{ value: "SHOPPING_SQUARE", label: "商品广场" },
|
{ value: "GOODS_DETAILS", label: "商品详情页面" }
|
],
|
// 视频详情弹窗相关数据
|
videoDetailShow: false,
|
videoDetailTitle: '',
|
videoDetailUrl: '',
|
videoLoading: false,
|
currentVideoDetail: null, // 当前视频详情数据
|
columns: [
|
{
|
title: "用户昵称",
|
key: "nickName",
|
minWidth: 120
|
},
|
{
|
title: "页面类型",
|
key: "pageCode",
|
minWidth: 150,
|
render: (h, params) => {
|
const pageCodes = {
|
"RECOMMEND_VIDEO": "首页推荐视频",
|
"HEALTH_VIDEO": "大健康视频",
|
"KITCHEN_VIDEO": "神厨视频",
|
"RECOMMEND_VIDEO_GOODS": "视频推荐商品页面",
|
"RECOMMEND_VIDEO_LEFT_GOODS": "左滑推荐商品",
|
"RECOMMEND_VIDEO_RIGHT_VIDEO": "右滑视频页面",
|
"FILL_ORDER": "填写订单",
|
"PAY_ORDER": "支付订单",
|
"PAY_SUCCESS": "支付成功",
|
"ORDER_LIST": "订单列表",
|
"ORDER_DETAIL": "订单详情",
|
"PRIZE_DETAIL": "抽奖活动",
|
"CART_LIST": "购物车",
|
"TBA_BAR_MY": "我的页面",
|
"SHOPPING_SQUARE": "商品广场",
|
"ACTIVITY_LIST": "活动列表",
|
"ACTIVITY_DETAIL": "活动详情",
|
"PUBLISH_VIDEO": "视频发布",
|
"SWIPER_GOODS": "滑动商品",
|
"COUPON_CENTER": "领卷中心",
|
"MY_COUPON": "我的优惠卷",
|
"AFTER_SALE": "售后列表",
|
"APPLY_SALE": "申请售后",
|
"REFUND_ORDER": "退款/退货",
|
"GOODS_DETAILS": "商品详情页面"
|
};
|
return h('span', pageCodes[params.row.pageCode] || params.row.pageCode);
|
}
|
},
|
{
|
title: "分享时间",
|
key: "createTime",
|
minWidth: 160
|
},
|
{
|
title: "操作",
|
key: "action",
|
width: 150,
|
align: "center",
|
render: (h, params) => {
|
// 只有当页面类型是商品详情页面时才显示跳转按钮
|
if (params.row.pageCode === "GOODS_DETAILS") {
|
return h('div', [
|
h('Button', {
|
props: {
|
type: 'primary',
|
size: 'small'
|
},
|
on: {
|
click: () => {
|
this.goToGoodsDetail(params.row.shareOption);
|
}
|
}
|
}, '查看商品详情')
|
]);
|
}
|
// 当页面类型是推荐视频页面时显示跳转按钮
|
if (params.row.pageCode === "RECOMMEND_VIDEO") {
|
// 检查参数是否完整,如果完整才显示查看按钮
|
if (this.canViewVideoDetail(params.row.shareOption)) {
|
return h('div', [
|
h('Button', {
|
props: {
|
type: 'primary',
|
size: 'small'
|
},
|
on: {
|
click: () => {
|
// 查看视频详情
|
this.viewVideoDetail(params.row);
|
}
|
}
|
}, '查看视频详情')
|
]);
|
}
|
}
|
return h('span', '-');
|
}
|
}
|
],
|
data: [],
|
total: 0
|
};
|
},
|
methods: {
|
// 初始化数据
|
init() {
|
this.$nextTick(() => {
|
this.getDataListWithoutValidation();
|
});
|
},
|
// 获取最近7天的开始时间(包含今天,总共7天)
|
getDefaultBeginDate() {
|
const now = new Date();
|
const startTime = new Date(now);
|
startTime.setDate(startTime.getDate() - 6); // 7天前,包含今天
|
startTime.setHours(0, 0, 0, 0);
|
return startTime;
|
},
|
// 获取当天结束时间
|
getDefaultEndDate() {
|
const now = new Date();
|
now.setHours(23, 59, 59, 999);
|
return now;
|
},
|
// 不进行表单验证的数据获取
|
getDataListWithoutValidation() {
|
this.loading = true;
|
|
// 处理时间格式
|
const params = { ...this.searchForm };
|
if (params.beginDate) {
|
params.beginDate = this.formatDate(params.beginDate);
|
} else {
|
this.loading = false;
|
this.$Message.error("开始时间不能为空");
|
return;
|
}
|
if (params.endDate) {
|
params.endDate = this.formatDate(params.endDate);
|
} else {
|
this.loading = false;
|
this.$Message.error("结束时间不能为空");
|
return;
|
}
|
|
userShareList(params).then(res => {
|
if (res.code === 200) {
|
this.data = res.data.records || [];
|
this.total = res.data.total || 0;
|
} else {
|
this.$Message.error(res.msg || "获取数据失败");
|
}
|
}).catch(err => {
|
console.error("请求失败:", err);
|
this.$Message.error("请求异常: " + (err.message || "未知错误"));
|
}).finally(() => {
|
this.loading = false;
|
});
|
},
|
// 带表单验证的数据获取
|
getDataList() {
|
this.$refs.searchForm.validate((valid) => {
|
if (valid) {
|
this.getDataListWithoutValidation();
|
} else {
|
this.loading = false;
|
this.$Message.error("请检查表单输入是否正确");
|
}
|
});
|
},
|
// 格式化日期时间
|
formatDate(date) {
|
if (!date) {
|
return "";
|
}
|
try {
|
const formattedDate = formatDate(new Date(date), 'yyyy-MM-dd hh:mm:ss');
|
return formattedDate;
|
} catch (error) {
|
// 如果格式化出错,尝试使用另一种方式
|
try {
|
const d = new Date(date);
|
const year = d.getFullYear();
|
const month = ('0' + (d.getMonth() + 1)).slice(-2);
|
const day = ('0' + d.getDate()).slice(-2);
|
const hours = ('0' + d.getHours()).slice(-2);
|
const minutes = ('0' + d.getMinutes()).slice(-2);
|
const seconds = ('0' + d.getSeconds()).slice(-2);
|
const formatted = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
return formatted;
|
} catch (backupError) {
|
return "";
|
}
|
}
|
},
|
// 改变页数
|
changePage(page) {
|
this.searchForm.pageNumber = page;
|
this.getDataListWithoutValidation();
|
},
|
// 改变页码
|
changePageSize(pageSize) {
|
this.searchForm.pageNumber = 1;
|
this.searchForm.pageSize = pageSize;
|
this.getDataListWithoutValidation();
|
},
|
// 搜索
|
handleSearch() {
|
this.searchForm.pageNumber = 1;
|
// 检查时间参数是否为空
|
if (!this.searchForm.beginDate || !this.searchForm.endDate) {
|
this.$Message.error("开始时间和结束时间不能为空");
|
return;
|
}
|
this.getDataListWithoutValidation();
|
},
|
// 重置
|
handleReset() {
|
this.searchForm.pageNumber = 1;
|
this.searchForm.pageSize = 10;
|
this.searchForm.userName = "";
|
this.searchForm.pageCode = "";
|
this.searchForm.beginDate = this.getDefaultBeginDate();
|
this.searchForm.endDate = this.getDefaultEndDate();
|
this.$nextTick(() => {
|
this.getDataListWithoutValidation();
|
});
|
},
|
|
// 检查是否可以查看视频详情
|
canViewVideoDetail(shareOption) {
|
try {
|
const params = JSON.parse(shareOption);
|
return params && params.videoId;
|
} catch (error) {
|
console.error("解析视频参数出错:", error);
|
return false;
|
}
|
},
|
|
// 查看视频详情
|
viewVideoDetail(row) {
|
try {
|
// 解析shareOption获取视频ID
|
const params = JSON.parse(row.shareOption);
|
const videoId = params.videoId;
|
|
if (!videoId) {
|
this.$Message.error("视频参数不完整");
|
return;
|
}
|
|
// 显示弹窗并设置加载状态
|
this.videoDetailShow = true;
|
this.videoDetailTitle = "视频详情";
|
this.videoLoading = true;
|
this.videoDetailUrl = '';
|
this.currentVideoDetail = null;
|
|
// 获取视频详情
|
getVideoById(videoId).then(res => {
|
if (res.code === 200 && res.data) {
|
const videoData = res.data;
|
// 保存视频详情数据
|
this.currentVideoDetail = videoData;
|
|
// 获取视频预览地址
|
if (videoData.videoFileKey) {
|
getFilePreview(videoData.videoFileKey).then(previewRes => {
|
if (previewRes.code === 200) {
|
this.videoDetailUrl = previewRes.data;
|
} else {
|
this.$Message.error("获取视频地址失败");
|
}
|
}).catch(err => {
|
console.error("获取视频预览地址失败:", err);
|
this.$Message.error("获取视频地址失败");
|
}).finally(() => {
|
this.videoLoading = false;
|
});
|
} else {
|
this.videoLoading = false;
|
this.$Message.info("该视频暂无内容");
|
}
|
} else {
|
this.videoLoading = false;
|
this.$Message.error("获取视频详情失败");
|
}
|
}).catch(err => {
|
console.error("获取视频详情失败:", err);
|
this.videoLoading = false;
|
this.$Message.error("获取视频详情失败");
|
});
|
} catch (error) {
|
console.error("解析视频参数出错:", error);
|
this.videoLoading = false;
|
this.$Message.error("视频参数解析失败");
|
}
|
},
|
|
// 格式化视频时长
|
formatVideoDuration(seconds) {
|
if (isNaN(seconds) || seconds < 0) return '0秒';
|
|
const mins = Math.floor(seconds / 60);
|
const secs = seconds % 60;
|
|
if (mins === 0) return `${secs}秒`;
|
if (secs === 0) return `${mins}分`;
|
|
return `${mins}分${secs}秒`;
|
},
|
|
// 关闭视频详情弹窗
|
closeVideoDetail() {
|
this.videoDetailShow = false;
|
this.videoDetailTitle = '';
|
this.videoDetailUrl = '';
|
this.videoLoading = false;
|
this.currentVideoDetail = null;
|
},
|
|
// 跳转到商品详情页面
|
goToGoodsDetail(shareOption) {
|
try {
|
// 解析shareOption JSON字符串
|
const params = JSON.parse(shareOption);
|
|
// 检查必要参数
|
if (!params.goodsId) {
|
this.$Message.error("商品参数不完整");
|
return;
|
}
|
|
// 跳转到商品详情页面,传递参数
|
this.$router.push({
|
name: "goods-detail",
|
query: {
|
id: params.goodsId
|
}
|
});
|
} catch (error) {
|
console.error("解析shareOption出错:", error);
|
this.$Message.error("参数解析失败");
|
}
|
}
|
},
|
mounted() {
|
this.$nextTick(() => {
|
this.init();
|
});
|
}
|
};
|
</script>
|
|
<style scoped>
|
.search-btn {
|
margin-right: 10px;
|
}
|
.mt_10 {
|
margin-top: 10px;
|
}
|
|
/* 用户行为卡片样式 */
|
.user-action-card {
|
height: calc(100vh - 100px);
|
display: flex;
|
flex-direction: column;
|
}
|
|
/* 表格容器样式 */
|
.table-container {
|
flex: 1;
|
overflow: hidden;
|
display: flex;
|
flex-direction: column;
|
}
|
|
/* 表格样式 */
|
.table-container /deep/ .ivu-table-wrapper {
|
flex: 1;
|
overflow-y: auto;
|
height: 100%;
|
}
|
|
/* 搜索表单样式 */
|
.search-form {
|
padding: 16px 0;
|
}
|
|
/* 分页样式 */
|
.mt_10 {
|
padding: 10px 0;
|
}
|
|
/* 视频容器样式 */
|
.video-wrapper {
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
min-height: 450px;
|
}
|
|
/* 视频信息样式 */
|
.video-info {
|
padding: 10px 0;
|
}
|
|
.video-basic-info h3 {
|
margin-bottom: 15px;
|
color: #333;
|
}
|
|
.info-item {
|
margin-bottom: 8px;
|
display: flex;
|
align-items: center;
|
}
|
|
.label {
|
font-weight: bold;
|
color: #666;
|
min-width: 60px;
|
}
|
|
.value {
|
color: #333;
|
}
|
|
.ivu-tag {
|
margin-right: 5px;
|
}
|
</style>
|