594 lines
14 KiB
Vue
594 lines
14 KiB
Vue
<template>
|
|
<div class="mainBox">
|
|
<div class="leftBox">
|
|
<div class="section">
|
|
<div class="bigTitle">快捷导航</div>
|
|
<ul class="recUl">
|
|
<li v-for="(item,index) in navList" :key="index" @click="goBaidu(item)">
|
|
<img :src="getNavIcon(index)" class="nav-icon" alt="icon" />
|
|
{{ item.name }}
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="section">
|
|
<div class="bigTitle">资源概览</div>
|
|
<ul class="recUl overView">
|
|
<li v-for="(item, index) in viewList" :key="index">
|
|
<div class="overview-item">
|
|
<span class="title">{{ item.name }}</span>
|
|
<span class="number">{{ item.count }}</span>
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="section">
|
|
<div class="bigTitle">到期预警</div>
|
|
<div class="table-container">
|
|
<el-table
|
|
height="250px"
|
|
border
|
|
:data="tableData"
|
|
style="width: 100%"
|
|
header-cell-class-name="table-header"
|
|
cell-class-name="table-cell">
|
|
<el-table-column prop="name" label="名称" min-width="120"></el-table-column>
|
|
<el-table-column prop="instanceid" label="资源id" min-width="120"></el-table-column>
|
|
<el-table-column prop="status" label="状态" min-width="80">
|
|
<template slot-scope="scope">
|
|
<el-tag :type="scope.row.status === '即将到期' ? 'warning' : 'danger'">
|
|
{{ scope.row.status }}
|
|
</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="days" label="剩余天数" min-width="80">
|
|
<template slot-scope="scope">
|
|
<span :class="scope.row.days < 3 ? 'critical' : ''">{{ scope.row.days }}天</span>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 右侧部分保持不变 -->
|
|
<div class="rightBox">
|
|
<div class="user card">
|
|
<div class="userImg">
|
|
<div class="imgUser">{{ userInfo.username.charAt(0) }}</div>
|
|
</div>
|
|
<div class="userBox">
|
|
<h3>{{ userInfo.username }}</h3>
|
|
<div class="user-info">
|
|
<p><i class="el-icon-user"></i> ID: {{ userInfo.id }}</p>
|
|
<p><i class="el-icon-phone"></i> 手机号: {{ userInfo.mobile }}</p>
|
|
<p><i class="el-icon-message"></i> 邮箱: {{ userInfo.email }}</p>
|
|
</div>
|
|
</div>· </div>
|
|
|
|
<div class="price card">
|
|
<div class="title">账户余额</div>
|
|
<div class="content">
|
|
<span class="balance">¥{{ mybalance }}</span>
|
|
<el-button size="mini" type="primary" @click="$router.push('/kbossCharge')">
|
|
立即充值
|
|
</el-button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="todos card">
|
|
<div class="title">待办事项</div>
|
|
<ul class="todo-list">
|
|
<li
|
|
v-for="(item, index) in todoList"
|
|
:key="index"
|
|
class="todo-item"
|
|
@click="handleTodoClick(item.name)"
|
|
>
|
|
<span class="todo-name">{{ item.name }}</span>
|
|
<span class="todo-count">{{ item.count }}</span>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<MessageCenter
|
|
ref="messageCenter"
|
|
:visible.sync="messageCenterVisible"
|
|
@unread-count-update="handleUnreadCountUpdate"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import Vue from 'vue'
|
|
import { mapState } from "vuex";
|
|
import { reqNewHomeResource, reqNewHomeResourceWarning, reqQuickNav, todoCount } from "@/api/newHome";
|
|
import { editReachargelogAPI } from "@/api/finance/customerRechargeManagement";
|
|
import { getUnreadmsgAPI } from "@/api/login";
|
|
import MessageCenter from '@/components/MessageCenter/MessageCenter.vue';
|
|
import icon1 from '@/assets/image/icon1.png';
|
|
import icon2 from '@/assets/image/icon2.png';
|
|
import icon3 from '@/assets/image/icon3.png';
|
|
import icon4 from '@/assets/image/icon4.png';
|
|
|
|
export default Vue.extend({
|
|
name: "mainPage",
|
|
components: {
|
|
MessageCenter
|
|
},
|
|
data() {
|
|
return {
|
|
tableData: [],
|
|
userInfo: {
|
|
id: "",
|
|
username: "",
|
|
mobile: "",
|
|
email: ""
|
|
},
|
|
viewList: [],
|
|
navList: [],
|
|
// 移除 data 中的 mybalance 定义
|
|
mybalance: 0,
|
|
todoList: [
|
|
{ name: '待支付', count: 0 },
|
|
{ name: '待续费', count: 0 },
|
|
{ name: '处理中', count: 0 },
|
|
{ name: '站内信', count: 0 }
|
|
],
|
|
messageCenterVisible: false,
|
|
// 添加图标路径数组
|
|
navIcons: [icon1, icon2, icon3, icon4]
|
|
}
|
|
},
|
|
created() {
|
|
// 移除 initMybalance 调用,因为现在使用 computed 的 mybalance
|
|
this.initMybalance(); // ❌ 删除这一行
|
|
this.getUnreadMsgCount();
|
|
this.fetchTodoCount();
|
|
},
|
|
mounted() {
|
|
reqQuickNav().then(res => {
|
|
this.navList = res.data
|
|
})
|
|
this.userInfo = JSON.parse(localStorage.getItem("user_info") || "{}");
|
|
reqNewHomeResource().then(res => {
|
|
if (res.status) {
|
|
this.viewList = res.data || [];
|
|
} else {
|
|
this.$message.error(res.msg);
|
|
}
|
|
})
|
|
reqNewHomeResourceWarning().then(res => {
|
|
if (res.status) {
|
|
this.tableData = res.data || [];
|
|
} else {
|
|
this.$message.error(res.msg);
|
|
}
|
|
})
|
|
},
|
|
methods: {
|
|
goBaidu(item) {
|
|
this.$store.commit('setRedirectUrl', item.url)
|
|
localStorage.setItem('redirectUrl', item.url)
|
|
localStorage.setItem('userRescourseUrl', item.listUrl)
|
|
this.$router.push({
|
|
name: 'baiduProductShow',
|
|
params: {
|
|
listUrl: item.listUrl,
|
|
url: item.url
|
|
}
|
|
})
|
|
},
|
|
// 添加获取导航图标的方法
|
|
getNavIcon(index) {
|
|
// 如果导航项数量超过图标数量,循环使用图标
|
|
const iconIndex = index % this.navIcons.length;
|
|
return this.navIcons[iconIndex];
|
|
},
|
|
// 移除 initMybalance 方法,因为现在使用 computed 的 mybalance
|
|
async initMybalance() { // ❌ 删除这个方法
|
|
const res = await editReachargelogAPI()
|
|
if (res.status) {
|
|
this.mybalance = res.data
|
|
}
|
|
},
|
|
async getUnreadMsgCount() {
|
|
try {
|
|
const res = await getUnreadmsgAPI();
|
|
if (res.status) {
|
|
const messageItem = this.todoList.find(item => item.name === '站内信');
|
|
if (messageItem) {
|
|
messageItem.count = res.data || 0;
|
|
}
|
|
} else {
|
|
this.$message.error(res.msg || '获取未读消息失败');
|
|
}
|
|
} catch (error) {
|
|
console.error('获取未读消息失败:', error);
|
|
this.$message.error('获取未读消息失败');
|
|
}
|
|
},
|
|
// 获取待办事项数量
|
|
async fetchTodoCount() {
|
|
try {
|
|
const res = await todoCount();
|
|
if (res.status && res.data) {
|
|
// 更新待办事项数量
|
|
this.todoList = this.todoList.map(item => {
|
|
switch(item.name) {
|
|
case '待支付':
|
|
return { ...item, count: res.data.pending_payment_orders || 0 };
|
|
case '待续费':
|
|
return { ...item, count: res.data.pending_renew_orders || 0 };
|
|
case '处理中':
|
|
return { ...item, count: res.data.processing_orders || 0 };
|
|
default:
|
|
return item;
|
|
}
|
|
});
|
|
} else {
|
|
this.$message.error(res.msg || '获取待办事项数量失败');
|
|
}
|
|
} catch (error) {
|
|
console.error('获取待办事项数量失败:', error);
|
|
this.$message.error('获取待办事项数量失败');
|
|
}
|
|
},
|
|
handleTodoClick(todoName) {
|
|
if (todoName === '站内信') {
|
|
this.openMessageCenter();
|
|
} else {
|
|
let query = {};
|
|
|
|
switch(todoName) {
|
|
case '待支付':
|
|
query = {
|
|
filterType: 'processing'
|
|
};
|
|
break;
|
|
case '待续费':
|
|
query = {
|
|
filterType: 'pendingPayment'
|
|
};
|
|
break;
|
|
case '处理中':
|
|
query = {
|
|
filterType: 'processing'
|
|
};
|
|
break;
|
|
}
|
|
|
|
console.log(`跳转到资源概览,筛选类型: ${todoName}`, query);
|
|
|
|
this.$router.push({
|
|
path: '/orderManagement/orderManagement',
|
|
query: query
|
|
});
|
|
}
|
|
},
|
|
openMessageCenter() {
|
|
this.messageCenterVisible = true;
|
|
},
|
|
handleUnreadCountUpdate(count) {
|
|
const messageItem = this.todoList.find(item => item.name === '站内信');
|
|
if (messageItem) {
|
|
messageItem.count = count || 0;
|
|
}
|
|
}
|
|
},
|
|
computed: {
|
|
...mapState({
|
|
mybalance: state => state.user.mybalance,
|
|
})
|
|
},
|
|
})
|
|
</script>
|
|
|
|
<style lang="less" scoped>
|
|
::v-deep .table-header {
|
|
background: #409eff !important;
|
|
color: #ffffff !important;
|
|
font-weight: bold;
|
|
text-align: center;
|
|
}
|
|
|
|
.mainBox {
|
|
background: #f5f7fa;
|
|
width: 100%;
|
|
height: calc(100vh - 100px);
|
|
display: flex;
|
|
padding: 10px;
|
|
padding-bottom: 20px;
|
|
box-sizing: border-box;
|
|
gap: 20px;
|
|
overflow-y: auto;
|
|
overflow-x: hidden;
|
|
}
|
|
|
|
.leftBox {
|
|
width: 65%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 20px;
|
|
min-width: 0;
|
|
|
|
.section {
|
|
background: white;
|
|
border-radius: 10px;
|
|
padding: 20px;
|
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
|
}
|
|
}
|
|
|
|
.rightBox {
|
|
width: 35%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 20px;
|
|
min-width: 0;
|
|
|
|
.card {
|
|
background: white;
|
|
border-radius: 10px;
|
|
padding: 20px;
|
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
|
}
|
|
}
|
|
|
|
.table-container {
|
|
width: 100%;
|
|
overflow-x: auto;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.table-container ::v-deep .el-table {
|
|
width: 100% !important;
|
|
}
|
|
|
|
.recUl {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
|
|
gap: 15px;
|
|
list-style: none;
|
|
padding: 0;
|
|
margin: 0;
|
|
|
|
li {
|
|
padding: 15px;
|
|
cursor: pointer;
|
|
transition: all 0.3s ease;
|
|
border: 1px solid #ebeef5;
|
|
border-radius: 8px;
|
|
text-align: center;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
min-width: 0;
|
|
|
|
// 修改这里:为图片添加样式
|
|
.nav-icon {
|
|
width: 24px;
|
|
height: 24px;
|
|
margin-bottom: 10px;
|
|
object-fit: contain;
|
|
}
|
|
|
|
// 移除原来的图标样式
|
|
// i {
|
|
// font-size: 24px;
|
|
// margin-bottom: 10px;
|
|
// color: #409eff;
|
|
// }
|
|
|
|
&:hover {
|
|
transform: translateY(-3px);
|
|
box-shadow: 0 4px 12px rgba(64, 158, 255, 0.2);
|
|
border-color: #409eff;
|
|
}
|
|
}
|
|
}
|
|
|
|
.overView {
|
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
|
|
li {
|
|
cursor: default;
|
|
&:hover {
|
|
transform: none;
|
|
box-shadow: none;
|
|
border-color: #ebeef5;
|
|
}
|
|
}
|
|
|
|
.overview-item {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
width: 100%;
|
|
min-width: 0;
|
|
|
|
.title {
|
|
font-size: 16px;
|
|
color: #606266;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
.number {
|
|
font-size: 20px;
|
|
font-weight: bold;
|
|
color: #303133;
|
|
white-space: nowrap;
|
|
}
|
|
}
|
|
}
|
|
|
|
.bigTitle {
|
|
color: #303133;
|
|
margin-bottom: 20px;
|
|
font-size: 18px;
|
|
font-weight: bold;
|
|
padding-bottom: 10px;
|
|
border-bottom: 2px solid #409eff;
|
|
display: inline-block;
|
|
}
|
|
|
|
.user {
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
.userImg {
|
|
margin-right: 20px;
|
|
flex-shrink: 0;
|
|
|
|
.imgUser {
|
|
width: 80px;
|
|
height: 80px;
|
|
border-radius: 50%;
|
|
background: linear-gradient(135deg, #409eff, #64b5f6);
|
|
font-size: 36px;
|
|
color: white;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-weight: bold;
|
|
}
|
|
}
|
|
|
|
.userBox {
|
|
flex: 1;
|
|
min-width: 0;
|
|
|
|
h3 {
|
|
margin-top: 0;
|
|
margin-bottom: 15px;
|
|
color: #303133;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
.user-info {
|
|
p {
|
|
margin: 8px 0;
|
|
color: #606266;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
|
|
i {
|
|
margin-right: 8px;
|
|
color: #409eff;
|
|
flex-shrink: 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.price {
|
|
.content {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
|
|
.balance {
|
|
font-size: 28px;
|
|
font-weight: bold;
|
|
color: #e6a23c;
|
|
}
|
|
}
|
|
}
|
|
|
|
.todos {
|
|
.title {
|
|
margin-bottom: 15px;
|
|
}
|
|
.todo-list {
|
|
list-style: none;
|
|
padding: 0;
|
|
margin: 0;
|
|
display: grid;
|
|
grid-template-columns: repeat(2, 1fr);
|
|
gap: 15px;
|
|
|
|
.todo-item {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 15px;
|
|
border: 1px solid #ebeef5;
|
|
border-radius: 8px;
|
|
text-align: center;
|
|
transition: all 0.3s ease;
|
|
cursor: pointer;
|
|
|
|
&:hover {
|
|
transform: translateY(-3px);
|
|
box-shadow: 0 4px 12px rgba(64, 158, 255, 0.2);
|
|
border-color: #409eff;
|
|
}
|
|
|
|
.todo-name {
|
|
font-size: 14px;
|
|
color: #606266;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.todo-count {
|
|
font-size: 24px;
|
|
font-weight: bold;
|
|
color: #409eff;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.critical {
|
|
color: #f56c6c;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.table-header {
|
|
background-color: #f5f7fa !important;
|
|
color: #606266;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.table-cell {
|
|
padding: 8px 0 !important;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.mainBox {
|
|
flex-direction: column;
|
|
height: auto;
|
|
overflow-x: hidden;
|
|
}
|
|
|
|
.leftBox, .rightBox {
|
|
width: 100%;
|
|
flex: none;
|
|
}
|
|
|
|
.recUl {
|
|
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
|
|
}
|
|
|
|
.overView {
|
|
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
|
}
|
|
|
|
.todo-list {
|
|
grid-template-columns: repeat(2, 1fr);
|
|
}
|
|
}
|
|
</style>
|