优化代码
BIN
YOLO工具箱.zip
9
package-lock.json
generated
@@ -8,10 +8,11 @@
|
|||||||
"name": "tk-page",
|
"name": "tk-page",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@element-plus/icons-vue": "^2.3.1",
|
||||||
"axios": "^1.8.4",
|
"axios": "^1.8.4",
|
||||||
"core-js": "^3.8.3",
|
"core-js": "^3.8.3",
|
||||||
"echarts": "^5.6.0",
|
"echarts": "^5.6.0",
|
||||||
"element-plus": "^2.9.7",
|
"element-plus": "^2.10.4",
|
||||||
"pinia": "^3.0.3",
|
"pinia": "^3.0.3",
|
||||||
"qwebchannel": "^6.2.0",
|
"qwebchannel": "^6.2.0",
|
||||||
"vue": "^3.2.13",
|
"vue": "^3.2.13",
|
||||||
@@ -6538,9 +6539,9 @@
|
|||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/element-plus": {
|
"node_modules/element-plus": {
|
||||||
"version": "2.9.7",
|
"version": "2.10.4",
|
||||||
"resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.9.7.tgz",
|
"resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.10.4.tgz",
|
||||||
"integrity": "sha512-6vjZh5SXBncLhUwJGTVKS5oDljfgGMh6J4zVTeAZK3YdMUN76FgpvHkwwFXocpJpMbii6rDYU3sgie64FyPerQ==",
|
"integrity": "sha512-UD4elWHrCnp1xlPhbXmVcaKFLCRaRAY6WWRwemGfGW3ceIjXm9fSYc9RNH3AiOEA6Ds1p9ZvhCs76CR9J8Vd+A==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ctrl/tinycolor": "^3.4.1",
|
"@ctrl/tinycolor": "^3.4.1",
|
||||||
|
|||||||
@@ -7,10 +7,11 @@
|
|||||||
"build": "vue-cli-service build"
|
"build": "vue-cli-service build"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@element-plus/icons-vue": "^2.3.1",
|
||||||
"axios": "^1.8.4",
|
"axios": "^1.8.4",
|
||||||
"core-js": "^3.8.3",
|
"core-js": "^3.8.3",
|
||||||
"echarts": "^5.6.0",
|
"echarts": "^5.6.0",
|
||||||
"element-plus": "^2.9.7",
|
"element-plus": "^2.10.4",
|
||||||
"pinia": "^3.0.3",
|
"pinia": "^3.0.3",
|
||||||
"qwebchannel": "^6.2.0",
|
"qwebchannel": "^6.2.0",
|
||||||
"vue": "^3.2.13",
|
"vue": "^3.2.13",
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 4.2 KiB |
@@ -9,7 +9,6 @@
|
|||||||
<title>
|
<title>
|
||||||
<%= webpackConfig.name %>
|
<%= webpackConfig.name %>
|
||||||
</title>
|
</title>
|
||||||
<script src="qrc:///qtwebchannel/qwebchannel.js"></script>
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -26,8 +26,6 @@ window.ResizeObserver = class ResizeObserver extends _ResizeObserver {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- <style lang="less">
|
<style lang="less">
|
||||||
/*每个页面公共css */
|
|
||||||
|
|
||||||
@import "@/static/css/app.less";
|
@import "@/static/css/app.less";
|
||||||
</style> -->
|
</style>
|
||||||
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 2.1 MiB |
|
Before Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 806 B |
BIN
src/assets/push.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 945 B |
|
Before Width: | Height: | Size: 993 B |
|
Before Width: | Height: | Size: 993 B |
|
Before Width: | Height: | Size: 1.2 KiB |
173
src/components/Appaside.vue
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
<template>
|
||||||
|
<div class="app-aside">
|
||||||
|
<div class="logo">
|
||||||
|
<img class="logo-img" src="@/assets/logo.png" alt="logo"></img>
|
||||||
|
</div>
|
||||||
|
<div class="Navigation">
|
||||||
|
|
||||||
|
<div class="Navigation-card" v-for="(item, index) in NavigationModule" :key="index" @click="handleClick(item.path, item.id)" :style="{backgroundColor: item.id === activeId|| item.id === 5? '#ffffff' : '' ,boxShadow: item.id === activeId|| item.id === 5? '5px 5px 15px rgba(0, 0, 0, 0.3)' : ''}">
|
||||||
|
<img class="Navigation-card-icon-img" :src="item.icon" alt="">
|
||||||
|
<div class="Navigation-card-name">{{ item.name }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="Avatar">
|
||||||
|
<img class="Avatar-img" src="@/assets/logo.png" alt="logo"></img>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import { setStorage , getStorage } from '@/utils/storage.js';
|
||||||
|
const router = useRouter();
|
||||||
|
import {
|
||||||
|
ref, // 响应式基础
|
||||||
|
watch, // 侦听器
|
||||||
|
onMounted, // 组件挂载完成后执行
|
||||||
|
onBeforeMount, // 组件挂载前执行
|
||||||
|
onUpdated, // 组件更新后执行
|
||||||
|
onUnmounted, // 组件销毁前执行
|
||||||
|
} from "vue";
|
||||||
|
|
||||||
|
const NavigationModule = [
|
||||||
|
{
|
||||||
|
name: 'PK',
|
||||||
|
id: 1,
|
||||||
|
path: '/nav/PK',
|
||||||
|
icon: 'https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/Pk.png'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '站内信',
|
||||||
|
id: 2,
|
||||||
|
path: '/nav/Forum',
|
||||||
|
icon: 'https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/Forum.png'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '消息',
|
||||||
|
id: 3,
|
||||||
|
path: '/nav/Message',
|
||||||
|
icon: 'https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/Message.png'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '我的',
|
||||||
|
id: 4,
|
||||||
|
path: '/nav/Mine',
|
||||||
|
icon: 'https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/Mine.png'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
icon: 'https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/push.png'
|
||||||
|
}
|
||||||
|
|
||||||
|
]
|
||||||
|
const activeId = ref(1);
|
||||||
|
function handleClick(path, id) {
|
||||||
|
|
||||||
|
if (id === 5) {
|
||||||
|
|
||||||
|
}else{
|
||||||
|
activeId.value = id;
|
||||||
|
router.push(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const refname = ref('');
|
||||||
|
|
||||||
|
watch(refname, async (newQuestion, oldQuestion) => {
|
||||||
|
// 变化后执行
|
||||||
|
});
|
||||||
|
onMounted(() => {
|
||||||
|
// 组件挂载完成后执行
|
||||||
|
try{
|
||||||
|
activeId.value = getStorage('activeId');
|
||||||
|
0 }catch(e){
|
||||||
|
activeId.value = 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
onBeforeMount(()=>{
|
||||||
|
// 组件挂载前执行
|
||||||
|
});
|
||||||
|
onUpdated(() => {
|
||||||
|
// 组件更新后执行
|
||||||
|
});
|
||||||
|
onUnmounted(() => {
|
||||||
|
// 组件销毁前执行
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style scoped lang="less">
|
||||||
|
.app-aside{
|
||||||
|
width: 100%;
|
||||||
|
height: 95%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content:space-between;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
.logo{
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
margin-top: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
.logo-img{
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
.Avatar{
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
border-radius: 50px;
|
||||||
|
}
|
||||||
|
.Avatar-img{
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
border-radius: 50px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
.Avatar-img:hover{
|
||||||
|
box-shadow: 5px 5px 15px rgba(0, 0, 0, 0.3);
|
||||||
|
transform: scale(1.1);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
.Navigation{
|
||||||
|
width: 100%;
|
||||||
|
height: 75%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.Navigation-card{
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
border-radius: 10px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 30px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
.Navigation-card-icon{
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
.Navigation-card-icon-img{
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
.Navigation-card-name{
|
||||||
|
font-size: 12px;
|
||||||
|
color:@Prompt-text-color;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
.Navigation-card:hover{
|
||||||
|
transform: scale(1.1);
|
||||||
|
opacity: 0.8;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,160 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div ref="chart" style="width: 500px; height: 300px;"></div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import * as echarts from 'echarts';
|
|
||||||
import { tkhostdata, dicts, tkhostdetail } from '@/api/account';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'EChartsComponent',
|
|
||||||
props: {
|
|
||||||
title: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
id: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
dataType: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
time: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
seriesData: [],
|
|
||||||
num: 0,
|
|
||||||
inputTime: '',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
|
|
||||||
this.inputTime = this.time
|
|
||||||
this.getTkhostdetail();
|
|
||||||
console.log(this.time)
|
|
||||||
|
|
||||||
console.log(this.getPrevious7Days(this.inputTime))
|
|
||||||
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
initChart() {
|
|
||||||
if (!this.$refs.chart) {
|
|
||||||
console.error('DOM element not found');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const myChart = echarts.init(this.$refs.chart);
|
|
||||||
const option = {
|
|
||||||
title: {
|
|
||||||
text: this.title
|
|
||||||
},
|
|
||||||
tooltip: {},
|
|
||||||
legend: {
|
|
||||||
data: [this.title]
|
|
||||||
},
|
|
||||||
xAxis: {
|
|
||||||
data: [this.getPrevious7Days(this.inputTime)[0].slice(4), this.getPrevious7Days(this.inputTime)[1].slice(4), this.getPrevious7Days(this.inputTime)[2].slice(4), this.getPrevious7Days(this.inputTime)[3].slice(4), this.getPrevious7Days(this.inputTime)[4].slice(4), this.getPrevious7Days(this.inputTime)[5].slice(4), this.getPrevious7Days(this.inputTime)[6].slice(4)]
|
|
||||||
},
|
|
||||||
yAxis: {},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: this.title,
|
|
||||||
type: 'line',
|
|
||||||
data: [this.seriesData[0], this.seriesData[1], this.seriesData[2], this.seriesData[3], this.seriesData[4], this.seriesData[5], this.seriesData[6]],
|
|
||||||
smooth: true
|
|
||||||
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
myChart.setOption(option);
|
|
||||||
console.log(this.dataTime)
|
|
||||||
|
|
||||||
},
|
|
||||||
getTkhostdetail() {
|
|
||||||
tkhostdetail({
|
|
||||||
hostId: this.id,
|
|
||||||
dataType: this.dataType,
|
|
||||||
searchTimeStart: this.getPrevious7Days(this.inputTime)[0],
|
|
||||||
searchTimeEnd: this.getPrevious7Days(this.inputTime)[6]
|
|
||||||
}).then(res => {
|
|
||||||
// console.log("返回数据", res[0][this.getPrevious7Days(this.inputTime)[2]])
|
|
||||||
//echarts 数据初始化
|
|
||||||
this.seriesData = [
|
|
||||||
res[0][this.getPrevious7Days(this.inputTime)[0]] == null ? 0 : Number(res[0][this.getPrevious7Days(this.inputTime)[0]][this.dataType]),
|
|
||||||
res[0][this.getPrevious7Days(this.inputTime)[1]] == null ? 0 : Number(res[0][this.getPrevious7Days(this.inputTime)[1]][this.dataType]),
|
|
||||||
res[0][this.getPrevious7Days(this.inputTime)[2]] == null ? 0 : Number(res[0][this.getPrevious7Days(this.inputTime)[2]][this.dataType]),
|
|
||||||
res[0][this.getPrevious7Days(this.inputTime)[3]] == null ? 0 : Number(res[0][this.getPrevious7Days(this.inputTime)[3]][this.dataType]),
|
|
||||||
res[0][this.getPrevious7Days(this.inputTime)[4]] == null ? 0 : Number(res[0][this.getPrevious7Days(this.inputTime)[4]][this.dataType]),
|
|
||||||
res[0][this.getPrevious7Days(this.inputTime)[5]] == null ? 0 : Number(res[0][this.getPrevious7Days(this.inputTime)[5]][this.dataType]),
|
|
||||||
res[0][this.getPrevious7Days(this.inputTime)[6]] == null ? 0 : Number(res[0][this.getPrevious7Days(this.inputTime)[6]][this.dataType]),
|
|
||||||
]
|
|
||||||
|
|
||||||
this.initChart();
|
|
||||||
this.num++
|
|
||||||
console.log("返回数据", this.seriesData)
|
|
||||||
console.log("返回数据", this.num)
|
|
||||||
|
|
||||||
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// getCurrentDate() {
|
|
||||||
// const dates = [];
|
|
||||||
// const today = new Date();
|
|
||||||
|
|
||||||
// for (let i = 6; i >= 0; i--) {
|
|
||||||
// const date = new Date(today);
|
|
||||||
// date.setDate(today.getDate() - i);
|
|
||||||
|
|
||||||
// const year = date.getFullYear();
|
|
||||||
// const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
||||||
// const day = String(date.getDate()).padStart(2, '0');
|
|
||||||
|
|
||||||
// dates.push(`${year}${month}${day}`);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return dates;
|
|
||||||
// },
|
|
||||||
getPrevious7Days(dateStr) {
|
|
||||||
// 验证输入格式是否正确
|
|
||||||
if (!/^\d{8}$/.test(dateStr)) {
|
|
||||||
console.error('输入的格式不是YYYYMMDD.');
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
// 解析输入的日期字符串
|
|
||||||
const year = parseInt(dateStr.substring(0, 4));
|
|
||||||
const month = parseInt(dateStr.substring(4, 6)) - 1; // 月份从 0 开始
|
|
||||||
const day = parseInt(dateStr.substring(6, 8));
|
|
||||||
|
|
||||||
// 创建日期对象
|
|
||||||
const date = new Date(year, month, day);
|
|
||||||
|
|
||||||
// 存储结果的数组
|
|
||||||
const result = [];
|
|
||||||
|
|
||||||
// 计算前 7 天的日期
|
|
||||||
for (let i = 0; i <= 6; i++) {
|
|
||||||
const currentDate = new Date(date);
|
|
||||||
currentDate.setDate(date.getDate() - i); // 减去 i 天
|
|
||||||
|
|
||||||
// 格式化为 YYYYMMDD
|
|
||||||
const formattedDate = `${currentDate.getFullYear()}${(currentDate.getMonth() + 1).toString().padStart(2, '0')}${currentDate.getDate().toString().padStart(2, '0')}`;
|
|
||||||
result.push(formattedDate);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 按时间顺序排序(从最早到最晚)
|
|
||||||
result.sort((a, b) => a.localeCompare(b));
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@@ -1,142 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="sidebar">
|
|
||||||
<div class="logo">
|
|
||||||
<!-- <img style="margin-right: 10px;" src="@/assets/logo.png"> -->
|
|
||||||
<img src="@/assets/logotext.png">
|
|
||||||
</div>
|
|
||||||
<ul>
|
|
||||||
<li @click="updateActiveIndex(1)">
|
|
||||||
<div>
|
|
||||||
<img v-show="activeIndex == 1" src="@/assets/navAction.png" autoplay loop muted class="background-img">
|
|
||||||
<div style="display: flex;">
|
|
||||||
<img v-show="activeIndex == 1" src="@/assets/workAction.png" style="margin-right: 10px;">
|
|
||||||
<img v-show="activeIndex == 2" src="@/assets/workAction.png" style="margin-right: 10px;">
|
|
||||||
<div :style="activeIndex == 1 ? 'color: #000' : 'color: #fff'" class="center-justify">工作台</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li @click="updateActiveIndex(2)">
|
|
||||||
<div>
|
|
||||||
<img v-show="activeIndex == 2" src="@/assets/navAction.png" autoplay loop muted class="background-img">
|
|
||||||
|
|
||||||
<div style="display: flex;">
|
|
||||||
<img v-show="activeIndex == 2" src="@/assets/listAction.png" style="margin-right: 10px;">
|
|
||||||
<img v-show="activeIndex == 1" src="@/assets/listAction.png" style="margin-right: 10px;">
|
|
||||||
<div :style="activeIndex == 2 ? 'color: #000' : 'color: #fff'" class="center-justify">主播列表</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<a @click="$router.push('/')" href="javascript:void(0);"
|
|
||||||
style="position: absolute; bottom: 30px; color: aliceblue; font-size: 20px; font-weight: 500;">
|
|
||||||
退出登录
|
|
||||||
</a>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, reactive, onMounted } from 'vue';
|
|
||||||
import { getUser } from '@/utils/storage'
|
|
||||||
import { defineEmits } from 'vue';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const userInfo = ref(getUser())
|
|
||||||
|
|
||||||
let activeIndex = ref(1);
|
|
||||||
|
|
||||||
const emit = defineEmits(['activeIndex']);
|
|
||||||
|
|
||||||
|
|
||||||
const updateActiveIndex = (index) => {
|
|
||||||
activeIndex.value = index;
|
|
||||||
emit('activeIndex', index);
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="less">
|
|
||||||
.sidebar {
|
|
||||||
position: fixed;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
height: 900px;
|
|
||||||
width: 280px;
|
|
||||||
background-color: @bg-color;
|
|
||||||
padding: 20px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
border-bottom: 1px solid #fff;
|
|
||||||
padding-top: 20px;
|
|
||||||
|
|
||||||
img:nth-of-type(1) {
|
|
||||||
height: 66px;
|
|
||||||
}
|
|
||||||
|
|
||||||
img:nth-of-type(2) {
|
|
||||||
height: 29px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar ul {
|
|
||||||
list-style: none;
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar li {
|
|
||||||
margin-top: 50px;
|
|
||||||
padding-top: 30px;
|
|
||||||
padding-left: 30px;
|
|
||||||
margin-bottom: 50px;
|
|
||||||
height: 64px;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar a {
|
|
||||||
text-decoration: none;
|
|
||||||
color: #000000;
|
|
||||||
display: block;
|
|
||||||
padding: 8px;
|
|
||||||
border-radius: 4px;
|
|
||||||
|
|
||||||
font-family: Source Han Sans SC;
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 22px;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* .sidebar a:hover {
|
|
||||||
background-color: #e0e0e0;
|
|
||||||
} */
|
|
||||||
|
|
||||||
|
|
||||||
.background-img {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 13px;
|
|
||||||
width: 247px;
|
|
||||||
height: 126px;
|
|
||||||
object-fit: cover;
|
|
||||||
z-index: -1;
|
|
||||||
/* 确保视频在内容之下 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.center-justify {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-around;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
298
src/components/mineSubComponent/AnchorLibrary.vue
Normal file
@@ -0,0 +1,298 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 主播库 -->
|
||||||
|
<div class="anchor-library">
|
||||||
|
<el-splitter>
|
||||||
|
<el-splitter-panel size="70%">
|
||||||
|
<!-- 主播列表 -->
|
||||||
|
<div class="demo-panel">
|
||||||
|
<div
|
||||||
|
class="anchor-library-list"
|
||||||
|
style="overflow: auto"
|
||||||
|
v-infinite-scroll="load"
|
||||||
|
>
|
||||||
|
<div class="anchor-library-card" v-for="(item, index) in list" :key="index">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="card-avatar"></div>
|
||||||
|
<div class="personalInformation">
|
||||||
|
<div class="name">来自世界上最长名的国家的某个人</div>
|
||||||
|
<div class="GenderAndCountry">
|
||||||
|
<div class="Gender">女</div>
|
||||||
|
<div class="Country">来自世界上最长名的国家的名称很长很长哦</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-Operation">
|
||||||
|
<div class="modify">
|
||||||
|
<img
|
||||||
|
class="modify-icon"
|
||||||
|
src="https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/recompose.png"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="delete">
|
||||||
|
<img
|
||||||
|
class="delete-icon"
|
||||||
|
src="https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/expurgate.png"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-splitter-panel>
|
||||||
|
<el-splitter-panel size="25%" :collapsible="true" :resizable="false">
|
||||||
|
<!-- 添加或修改主播 -->
|
||||||
|
<div class="demo-panel">
|
||||||
|
<div class="add-anchor-library">
|
||||||
|
<div class="title">添加我的主播</div>
|
||||||
|
<!-- <div class="title">
|
||||||
|
修改主播信息
|
||||||
|
</div> -->
|
||||||
|
<div class="add-anchor-library-content">
|
||||||
|
<div class="input-name">
|
||||||
|
<!-- 主播名称 -->
|
||||||
|
<el-input v-model="refname" size="large" placeholder="请输入主播名称" />
|
||||||
|
</div>
|
||||||
|
<div class="country">
|
||||||
|
<!-- 国家 -->
|
||||||
|
<el-select-v2
|
||||||
|
v-model="countryvalue"
|
||||||
|
filterable
|
||||||
|
:options="country"
|
||||||
|
placeholder="请选择国家"
|
||||||
|
size="large"
|
||||||
|
style="vertical-align: middle"
|
||||||
|
class="select"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="gender">
|
||||||
|
<!-- 性别 -->
|
||||||
|
<el-select-v2
|
||||||
|
v-model="gendervalue"
|
||||||
|
filterable
|
||||||
|
:options="genderOptions"
|
||||||
|
size="large"
|
||||||
|
placeholder="请选择性别"
|
||||||
|
style="vertical-align: middle"
|
||||||
|
class="select"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="Confirm">确认</div>
|
||||||
|
<div class="Reset">重置</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-splitter-panel>
|
||||||
|
</el-splitter>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
ref, // 响应式基础
|
||||||
|
watch, // 侦听器
|
||||||
|
onMounted, // 组件挂载完成后执行
|
||||||
|
onUpdated, // 组件更新后执行
|
||||||
|
onUnmounted, // 组件销毁前执行
|
||||||
|
} from "vue";
|
||||||
|
import { getCountryNamesArray } from "../../utils/countryUtil";
|
||||||
|
const refname = ref("");
|
||||||
|
const country = ref([]);
|
||||||
|
country.value = getCountryNamesArray(); //国家条目
|
||||||
|
const genderOptions = [
|
||||||
|
{ value: 1, label: "男" },
|
||||||
|
{ value: 2, label: "女" },
|
||||||
|
]; // 性别选项
|
||||||
|
const list = ref([{}, {}, {}, {}, {}, {}]);
|
||||||
|
|
||||||
|
function load() {}
|
||||||
|
watch(refname, async (newQuestion, oldQuestion) => {
|
||||||
|
// 变化后执行
|
||||||
|
});
|
||||||
|
onMounted(() => {
|
||||||
|
// 组件挂载完成后执行
|
||||||
|
});
|
||||||
|
onUpdated(() => {
|
||||||
|
// 组件更新后执行
|
||||||
|
});
|
||||||
|
onUnmounted(() => {
|
||||||
|
// 组件销毁前执行
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
.anchor-library {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.anchor-library-list {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.anchor-library-card {
|
||||||
|
width: 100%;
|
||||||
|
height: 150px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
margin-top: 15px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.card-content {
|
||||||
|
width: 90%;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 20px;
|
||||||
|
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.3);
|
||||||
|
background-image: linear-gradient(45deg, @bg-Sidebar-color-bottom, @bg-color);
|
||||||
|
transition: all 0.4s ease;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.card-content:hover {
|
||||||
|
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.8);
|
||||||
|
transform: scale(1.1);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
.card-avatar {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #ffffff;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
.personalInformation {
|
||||||
|
width: calc(100% - 340px);
|
||||||
|
height: 100px;
|
||||||
|
margin-left: 20px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
.GenderAndCountry {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.Gender {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #666666;
|
||||||
|
border-radius: 50px;
|
||||||
|
background-color: #ffffff;
|
||||||
|
padding: 2px 20px 2px 20px;
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
.Country {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #666666;
|
||||||
|
border-radius: 50px;
|
||||||
|
background-color: #ffffff;
|
||||||
|
padding: 2px 20px 2px 20px;
|
||||||
|
}
|
||||||
|
.card-Operation {
|
||||||
|
width: 200px;
|
||||||
|
height: 100px;
|
||||||
|
margin-left: 20px;
|
||||||
|
margin-right: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
.modify-icon {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
.delete-icon {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
.demo-panel {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.add-anchor-library {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.title {
|
||||||
|
width: 100%;
|
||||||
|
height: 70px;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333333;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 70px;
|
||||||
|
}
|
||||||
|
.add-anchor-library-content {
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100% - 70px);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.input-name {
|
||||||
|
width: 80%;
|
||||||
|
height: 50px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.country {
|
||||||
|
width: 80%;
|
||||||
|
height: 50px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.gender {
|
||||||
|
width: 80%;
|
||||||
|
height: 80px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.select {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.Confirm {
|
||||||
|
width: 80%;
|
||||||
|
height: 50px;
|
||||||
|
margin-top: 200px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 50px;
|
||||||
|
background-color: #ffffff;
|
||||||
|
color: @Prompt-text-color;
|
||||||
|
font-size: 20px;
|
||||||
|
transition: all 0.4s ease;
|
||||||
|
border-radius: 20px;
|
||||||
|
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
.Confirm:hover {
|
||||||
|
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.8);
|
||||||
|
transform: scale(1.1);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
.Reset {
|
||||||
|
width: 80%;
|
||||||
|
height: 50px;
|
||||||
|
margin-top: 30px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 50px;
|
||||||
|
background-color: #ffffff;
|
||||||
|
color: @Prompt-text-color;
|
||||||
|
font-size: 20px;
|
||||||
|
transition: all 0.4s ease;
|
||||||
|
border-radius: 20px;
|
||||||
|
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
.Reset:hover {
|
||||||
|
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.8);
|
||||||
|
transform: scale(1.1);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
31
src/components/mineSubComponent/PKRecord.vue
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 我的PK记录 -->
|
||||||
|
<div>我的PK记录</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
ref, // 响应式基础
|
||||||
|
watch, // 侦听器
|
||||||
|
onMounted, // 组件挂载完成后执行
|
||||||
|
onUpdated, // 组件更新后执行
|
||||||
|
onUnmounted, // 组件销毁前执行
|
||||||
|
} from "vue";
|
||||||
|
const refname = ref('');
|
||||||
|
watch(refname, async (newQuestion, oldQuestion) => {
|
||||||
|
// 变化后执行
|
||||||
|
});
|
||||||
|
onMounted(() => {
|
||||||
|
// 组件挂载完成后执行
|
||||||
|
});
|
||||||
|
onUpdated(() => {
|
||||||
|
// 组件更新后执行
|
||||||
|
});
|
||||||
|
onUnmounted(() => {
|
||||||
|
// 组件销毁前执行
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 样式定义 */
|
||||||
|
</style>
|
||||||
31
src/components/mineSubComponent/PKmessage.vue
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<template>
|
||||||
|
<!-- PK信息 -->
|
||||||
|
<div>PK信息</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
ref, // 响应式基础
|
||||||
|
watch, // 侦听器
|
||||||
|
onMounted, // 组件挂载完成后执行
|
||||||
|
onUpdated, // 组件更新后执行
|
||||||
|
onUnmounted, // 组件销毁前执行
|
||||||
|
} from "vue";
|
||||||
|
const refname = ref('');
|
||||||
|
watch(refname, async (newQuestion, oldQuestion) => {
|
||||||
|
// 变化后执行
|
||||||
|
});
|
||||||
|
onMounted(() => {
|
||||||
|
// 组件挂载完成后执行
|
||||||
|
});
|
||||||
|
onUpdated(() => {
|
||||||
|
// 组件更新后执行
|
||||||
|
});
|
||||||
|
onUnmounted(() => {
|
||||||
|
// 组件销毁前执行
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 样式定义 */
|
||||||
|
</style>
|
||||||
31
src/components/mineSubComponent/PointsList.vue
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 积分列表 -->
|
||||||
|
<div>积分列表</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
ref, // 响应式基础
|
||||||
|
watch, // 侦听器
|
||||||
|
onMounted, // 组件挂载完成后执行
|
||||||
|
onUpdated, // 组件更新后执行
|
||||||
|
onUnmounted, // 组件销毁前执行
|
||||||
|
} from "vue";
|
||||||
|
const refname = ref('');
|
||||||
|
watch(refname, async (newQuestion, oldQuestion) => {
|
||||||
|
// 变化后执行
|
||||||
|
});
|
||||||
|
onMounted(() => {
|
||||||
|
// 组件挂载完成后执行
|
||||||
|
});
|
||||||
|
onUpdated(() => {
|
||||||
|
// 组件更新后执行
|
||||||
|
});
|
||||||
|
onUnmounted(() => {
|
||||||
|
// 组件销毁前执行
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 样式定义 */
|
||||||
|
</style>
|
||||||
@@ -6,12 +6,15 @@ import { createPinia } from 'pinia';
|
|||||||
import ElementPlus from 'element-plus'
|
import ElementPlus from 'element-plus'
|
||||||
import 'element-plus/dist/index.css'
|
import 'element-plus/dist/index.css'
|
||||||
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'; // 引入中文语言包
|
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'; // 引入中文语言包
|
||||||
|
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
|
||||||
|
|
||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
app.use(ElementPlus, {
|
app.use(ElementPlus, {
|
||||||
locale: zhCn, // 配置中文
|
locale: zhCn, // 配置中文
|
||||||
});
|
});
|
||||||
|
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
||||||
|
app.component(key, component)
|
||||||
|
}
|
||||||
app.use(ElementPlus) // 注册 ElementPlus
|
app.use(ElementPlus) // 注册 ElementPlus
|
||||||
app.use(createPinia()); // 注册 Pinia
|
app.use(createPinia()); // 注册 Pinia
|
||||||
app.use(store); // 注册 store
|
app.use(store); // 注册 store
|
||||||
|
|||||||
@@ -11,19 +11,29 @@ const routes = [
|
|||||||
{
|
{
|
||||||
path: '/nav',
|
path: '/nav',
|
||||||
name: 'nav',
|
name: 'nav',
|
||||||
// redirect: '/nav/hostsList', // 默认跳转
|
redirect: '/nav/PK', // 默认跳转
|
||||||
component: () => import(/* webpackChunkName: "hostsList" */ '../views/nav.vue'),
|
component: () => import('../views/nav.vue'),
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'hostsList',
|
path: 'PK',
|
||||||
name: 'hostsList',
|
name: 'pk',
|
||||||
component: () => import(/* webpackChunkName: "hostsList" */ '../views/hosts/hostsList.vue')
|
component: () => import('../views/hosts/pk.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'Forum',
|
||||||
|
name: 'Forum',
|
||||||
|
component: () => import('../views/hosts/Forum.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'Message',
|
||||||
|
name: 'Message',
|
||||||
|
component: () => import('../views/hosts/Message.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'Mine',
|
||||||
|
name: 'Mine',
|
||||||
|
component: () => import('../views/hosts/Mine.vue')
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// path: 'workBenches',
|
|
||||||
// name: 'workBenches',
|
|
||||||
// component: () => import(/* webpackChunkName: "hostsList" */ '../views/hosts/workbenches.vue')
|
|
||||||
// },
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,4 +1,12 @@
|
|||||||
@bg-color: #022b4e; // 主色
|
@bg-color: #F8F9FA;// 主色
|
||||||
@bg-color-light: #022b4eaf; // 浅主色
|
@font-color: #212529; // 字体色
|
||||||
@bg-color-light-light: #022b4e1c; // 浅浅主色
|
@border-color: #E9ECEF; // 边框色
|
||||||
@btn-bg-color: #045dac; // 黄色按钮主色
|
@bg-Sidebar-color-top:#F8F9FA; // 侧边栏背景色
|
||||||
|
@bg-Sidebar-color-bottom: #E9ECEF; // 侧边栏底色
|
||||||
|
@Supplementary-text-color: #495057; // 补充文字色
|
||||||
|
@Prompt-text-color: #6c757d; // 提示文字色
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@bg-night-color: #1A1A1A; // 夜间模式色
|
||||||
|
@font-color-night: #E9ECEF; // 夜间模式字体色
|
||||||
|
|||||||
@@ -255,7 +255,6 @@ export const CountryCode = {
|
|||||||
ZM: "赞比亚",
|
ZM: "赞比亚",
|
||||||
ZW: "津巴布韦"
|
ZW: "津巴布韦"
|
||||||
};
|
};
|
||||||
|
export function getCountryNamesArray() {
|
||||||
export function getCountryName(code) {
|
return Object.entries(CountryCode).map(([code, nickname]) => ({ value: nickname, label: nickname }));
|
||||||
return CountryCode[code] || null;
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,198 +0,0 @@
|
|||||||
// pythonBridge.js
|
|
||||||
import { ref, onMounted } from 'vue';
|
|
||||||
import { ElMessage } from 'element-plus';
|
|
||||||
const pyBridge = ref(null);
|
|
||||||
// 初始化 QWebChannel
|
|
||||||
const initBridge = () => {
|
|
||||||
if (/localhost/.test(window.location.href)) return
|
|
||||||
new QWebChannel(qt.webChannelTransport, (channel) => {
|
|
||||||
pyBridge.value = channel.objects.bridge;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
export function usePythonBridge() {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// // 调用 Python 方法
|
|
||||||
// const fetchDataConfig = (data) => {
|
|
||||||
// return new Promise((resolve, reject) => {
|
|
||||||
// if (bridge.value) {
|
|
||||||
// bridge.value.fetchDataConfig(data, function (result) {
|
|
||||||
// resolve(result);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// });
|
|
||||||
// };
|
|
||||||
|
|
||||||
// // 查询获取主播的数据
|
|
||||||
// const fetchDataCount = () => {
|
|
||||||
// return new Promise((resolve, reject) => {
|
|
||||||
// if (bridge.value) {
|
|
||||||
// bridge.value.fetchDataCount(function (result) {
|
|
||||||
// resolve(result);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// };
|
|
||||||
|
|
||||||
//删除前端储存数据
|
|
||||||
const deleteStorageData = (data) => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
if (pyBridge.value) {
|
|
||||||
pyBridge.value.deleteAccountInfo(JSON.stringify(data),function (result) {
|
|
||||||
resolve(result);
|
|
||||||
});
|
|
||||||
}else{
|
|
||||||
console.log("pyBridge is null未连接上")
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
//获取前端储存数据
|
|
||||||
const getStorageData = (data) => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
if (pyBridge.value) {
|
|
||||||
pyBridge.value.readAccountInfo(JSON.stringify(data),function (result) {
|
|
||||||
resolve(result);
|
|
||||||
});
|
|
||||||
}else{
|
|
||||||
console.log("pyBridge is null未连接上")
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
//设置前端储存数据
|
|
||||||
const setStorageData = (data) => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
if (pyBridge.value) {
|
|
||||||
pyBridge.value.storageAccountInfo(JSON.stringify(data),function (result) {
|
|
||||||
resolve(result);
|
|
||||||
});
|
|
||||||
}else{
|
|
||||||
console.log("pyBridge is null未连接上")
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 查询获取大哥的数据
|
|
||||||
const controlTask = (data) => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
if (pyBridge.value) {
|
|
||||||
pyBridge.value.control_task(data,function (result) {
|
|
||||||
resolve(result);
|
|
||||||
});
|
|
||||||
}else{
|
|
||||||
console.log("pyBridge is null未连接上")
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
//总数有效数
|
|
||||||
const getBrotherInfo = () => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
if (pyBridge.value) {
|
|
||||||
pyBridge.value.getBrotherInfo(function (result) {
|
|
||||||
resolve(JSON.parse(result));
|
|
||||||
});
|
|
||||||
}else{
|
|
||||||
console.log("pyBridge is null未连接上")
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 打开tk后台
|
|
||||||
const loginTikTok = () => {
|
|
||||||
if (pyBridge.value) {
|
|
||||||
pyBridge.value.loginTikTok(function (result) {
|
|
||||||
});
|
|
||||||
}else{
|
|
||||||
console.log("pyBridge is null未连接上")
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// // 登录tk后台
|
|
||||||
// const loginBackStage = (data) => {
|
|
||||||
// if (bridge.value) {
|
|
||||||
// if (data.index == 0) {
|
|
||||||
// bridge.value.loginBackStage(JSON.stringify(data));
|
|
||||||
// } else if (data.index == 1) {
|
|
||||||
// bridge.value.loginBackStageCopy(JSON.stringify(data));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
//跳转到主播页面
|
|
||||||
const givePyAnchorId = (id) => {
|
|
||||||
console.log("id",id);
|
|
||||||
if (pyBridge.value) {
|
|
||||||
pyBridge.value.givePyAnchorId(id, function (result) {
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// //查询登录状态
|
|
||||||
// const backStageloginStatus = () => {
|
|
||||||
// return new Promise((resolve, reject) => {
|
|
||||||
// if (bridge.value) {
|
|
||||||
// bridge.value.backStageloginStatus(function (result) {
|
|
||||||
// resolve(result);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
// };
|
|
||||||
// //查询登录状态
|
|
||||||
// const backStageloginStatusCopy = () => {
|
|
||||||
// return new Promise((resolve, reject) => {
|
|
||||||
// if (bridge.value) {
|
|
||||||
// bridge.value.backStageloginStatusCopy(function (result) {
|
|
||||||
// resolve(result);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
// };
|
|
||||||
|
|
||||||
//导出表格
|
|
||||||
const exportToExcel = (data) => {
|
|
||||||
if (pyBridge .value) {
|
|
||||||
pyBridge .value.exportToExcel(JSON.stringify(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
const stopScript = () => {
|
|
||||||
if (pyBridge .value) {
|
|
||||||
pyBridge .value.stopScript();
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
//获取版本号
|
|
||||||
const getVersion = () => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
if (pyBridge.value) {
|
|
||||||
pyBridge.value.currentVersion(function (result) {
|
|
||||||
resolve(result);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 在组件挂载时初始化桥接
|
|
||||||
onMounted(initBridge);
|
|
||||||
|
|
||||||
return {
|
|
||||||
loginTikTok,
|
|
||||||
exportToExcel,
|
|
||||||
stopScript,
|
|
||||||
controlTask,
|
|
||||||
getBrotherInfo,
|
|
||||||
getVersion,
|
|
||||||
givePyAnchorId,
|
|
||||||
getStorageData,
|
|
||||||
setStorageData,
|
|
||||||
deleteStorageData,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,70 +1,13 @@
|
|||||||
|
|
||||||
import { usePythonBridge} from "@/utils/pythonBridge";
|
//存储localStorage
|
||||||
|
export function setStorage(key, value) {
|
||||||
const { getStorageData, setStorageData,deleteStorageData} = usePythonBridge();
|
window.localStorage.setItem(key, value);
|
||||||
import { ElMessage } from 'element-plus';
|
|
||||||
|
|
||||||
export async function setToken(token) {
|
|
||||||
const res = await setStorageData({key: 'token',data: token}).then(res => {
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
//获取localStorage
|
||||||
export async function getToken() {
|
export function getStorage(key) {
|
||||||
const res = await getStorageData({ key: 'token' });
|
return window.localStorage.getItem(key);
|
||||||
return JSON.parse(res);
|
|
||||||
}
|
}
|
||||||
|
//清除localStorage
|
||||||
export async function removeToken() {
|
export function clearStorage() {
|
||||||
const res = deleteStorageData({key: 'token'});
|
window.localStorage.clear();
|
||||||
}
|
|
||||||
|
|
||||||
export async function setUser(user) {
|
|
||||||
const res = await setStorageData({key: 'user',data: user}).then(res => {
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getUser() {
|
|
||||||
const res = await getStorageData({ key: 'user' });
|
|
||||||
return JSON.parse(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function setNumData(numData) {
|
|
||||||
const res = await setStorageData({key: 'num',data: numData})
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getNumData() {
|
|
||||||
const res = await getStorageData({ key: 'num' });
|
|
||||||
return JSON.parse(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 导出一个函数,用于设置用户密码
|
|
||||||
export async function setUserPass(userdata) {
|
|
||||||
const res = await setStorageData({key: 'userPass',data:userdata})
|
|
||||||
}
|
|
||||||
// 导出一个函数,用于获取用户密码
|
|
||||||
export async function getUserPass() {
|
|
||||||
const res = await getStorageData({ key: 'userPass' });
|
|
||||||
return JSON.parse(res);
|
|
||||||
}
|
|
||||||
// 用于设置tk账户密码
|
|
||||||
export async function setTkUser(userdata) {
|
|
||||||
const res = await setStorageData({key: 'tkuser',data: userdata})
|
|
||||||
}
|
|
||||||
// 用于获取tk账户密码
|
|
||||||
|
|
||||||
export async function getTkUser() {
|
|
||||||
const res = await getStorageData({ key: 'tkuser' });
|
|
||||||
return JSON.parse(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 用于列表筛选条件
|
|
||||||
export async function setSerch(data) {
|
|
||||||
const res = await setStorageData({key: 'Serch',data: data})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 用于获取列表筛选条件
|
|
||||||
export async function getSerch() {
|
|
||||||
const res = await getStorageData({ key: 'Serch' });
|
|
||||||
return JSON.parse(res);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,351 +1,30 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="main">
|
<div></div>
|
||||||
<div class="container">
|
|
||||||
<div class="right">
|
|
||||||
<img src="../assets/logoBg.png" class="background-video" alt="" />
|
|
||||||
<!-- 设置 -->
|
|
||||||
<div class="center-align">
|
|
||||||
<div></div>
|
|
||||||
<div class="setup">
|
|
||||||
<div class="setup-item center-justify">
|
|
||||||
<div></div>
|
|
||||||
<span> 网络设置 </span>
|
|
||||||
</div>
|
|
||||||
<div class="setup-item center-justify">
|
|
||||||
<div></div>
|
|
||||||
<span> 简体中文 </span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="center-line" style="margin-top: 40px">
|
|
||||||
<!-- logo -->
|
|
||||||
<div class="logo">
|
|
||||||
<!-- <div class="center-justify" style="height: 80px; width: 300px;">
|
|
||||||
<img style="height: 100%;" src="@/assets/logotext.png">
|
|
||||||
</div> -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- From -->
|
|
||||||
<div class="from">
|
|
||||||
<div class="from-title center-justify">
|
|
||||||
<div>账号登陆</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="from-input">
|
|
||||||
<el-form label-position="left" label-width="100px" :model="formData">
|
|
||||||
<div class="from-input-item1">
|
|
||||||
<img src="@/assets/username.png" alt="" />
|
|
||||||
<el-input
|
|
||||||
style="height: 25px"
|
|
||||||
v-model="formData.tenantName"
|
|
||||||
placeholder="租户名称"
|
|
||||||
clearable
|
|
||||||
@keyup.enter="onSubmit"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="from-input-item1">
|
|
||||||
<img src="@/assets/username.png" alt="" />
|
|
||||||
<el-input
|
|
||||||
style="height: 25px"
|
|
||||||
v-model="formData.userId"
|
|
||||||
placeholder="账号"
|
|
||||||
clearable
|
|
||||||
@keyup.enter="onSubmit"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="from-input-item1">
|
|
||||||
<img src="@/assets/password.png" alt="" />
|
|
||||||
<el-input
|
|
||||||
style="height: 25px"
|
|
||||||
v-model="formData.password"
|
|
||||||
type="password"
|
|
||||||
placeholder="密码"
|
|
||||||
show-password
|
|
||||||
@keyup.enter="onSubmit"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="from-input-item">
|
|
||||||
<el-button
|
|
||||||
class="loginButton"
|
|
||||||
color="#8f7ee7"
|
|
||||||
type="primary"
|
|
||||||
@click="onSubmit"
|
|
||||||
>登录</el-button
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</el-form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="version center-justify">版本号:{{ version }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, onMounted } from "vue";
|
import {
|
||||||
import { useRouter } from "vue-router";
|
ref, // 响应式基础
|
||||||
import { login, rentgetloginID } from "@/api/account";
|
watch, // 侦听器
|
||||||
import { getToken, setToken, setUser, setUserPass, getUserPass } from "@/utils/storage";
|
onMounted, // 组件挂载完成后执行
|
||||||
import { ElLoading } from "element-plus";
|
onUpdated, // 组件更新后执行
|
||||||
import { usePythonBridge } from "@/utils/pythonBridge";
|
onUnmounted, // 组件销毁前执行
|
||||||
import { ElMessage } from 'element-plus';
|
} from "vue";
|
||||||
import { tokenStore,UserStore } from '@/stores/notice'
|
const refname = ref('');
|
||||||
|
watch(refname, async (newQuestion, oldQuestion) => {
|
||||||
const tokenCache = tokenStore()
|
// 变化后执行
|
||||||
const userCache = UserStore()
|
});
|
||||||
const { getVersion } = usePythonBridge();
|
onMounted(() => {
|
||||||
let version = ref("0.0.0");
|
// 组件挂载完成后执行
|
||||||
|
});
|
||||||
onMounted(() => {
|
onUpdated(() => {
|
||||||
setTimeout(() => {
|
// 组件更新后执行
|
||||||
getVersion().then((res) => {
|
});
|
||||||
version.value = res;
|
onUnmounted(() => {
|
||||||
});
|
// 组件销毁前执行
|
||||||
getpassword();
|
|
||||||
}, 500);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
async function getpassword(){
|
|
||||||
const res = await getUserPass();
|
|
||||||
formData.value = {
|
|
||||||
tenantName: res == null ? "" : res.tenantName,
|
|
||||||
userId: res == null ? "" : res.userId,
|
|
||||||
password: res == null ? "" : res.password,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
const formData = ref({});
|
|
||||||
|
|
||||||
const onSubmit = () => {
|
|
||||||
const loading = ElLoading.service({
|
|
||||||
lock: true,
|
|
||||||
text: "Loading",
|
|
||||||
background: "rgba(0, 0, 0, 0.7)",
|
|
||||||
});
|
|
||||||
rentgetloginID({
|
|
||||||
name: formData.value.tenantName,
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
console.log(res);
|
|
||||||
|
|
||||||
login({
|
|
||||||
username: formData.value.userId,
|
|
||||||
tenantId: res,
|
|
||||||
password: formData.value.password,
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
loading.close();
|
|
||||||
console.log(res);
|
|
||||||
setToken(res.tokenValue);
|
|
||||||
tokenCache.setToken(res.tokenValue)
|
|
||||||
userCache.setUser(res)
|
|
||||||
setUser(res);
|
|
||||||
setUserPass(formData.value);
|
|
||||||
router.push("/nav");
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
loading.close();
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
loading.close();
|
|
||||||
console.log(err);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less">
|
<style scoped>
|
||||||
.main {
|
/* 样式定义 */
|
||||||
width: 1600px;
|
</style>
|
||||||
height: 900px;
|
|
||||||
overflow: hidden;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
/* 页面无法选中 */
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-ms-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
|
|
||||||
.container {
|
|
||||||
display: flex;
|
|
||||||
box-sizing: border-box;
|
|
||||||
width: 1600px;
|
|
||||||
height: 900px;
|
|
||||||
|
|
||||||
.right {
|
|
||||||
box-sizing: border-box;
|
|
||||||
position: relative;
|
|
||||||
width: 1600px;
|
|
||||||
height: 900px;
|
|
||||||
padding: 20px 40px 20px 50px;
|
|
||||||
border-left: 3px solid #23516e;
|
|
||||||
position: relative;
|
|
||||||
/* 添加 position: relative */
|
|
||||||
overflow: hidden;
|
|
||||||
/* 防止内容溢出 */
|
|
||||||
|
|
||||||
.version {
|
|
||||||
color: #fff;
|
|
||||||
position: absolute;
|
|
||||||
font-size: 20px;
|
|
||||||
bottom: 20px;
|
|
||||||
left: calc(50% - 50px);
|
|
||||||
// box-sizing: border-box;
|
|
||||||
// width: 1600px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.background-video {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
z-index: -1;
|
|
||||||
/* 确保视频在内容之下 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.setup {
|
|
||||||
display: flex;
|
|
||||||
color: #fff;
|
|
||||||
|
|
||||||
.setup-item {
|
|
||||||
padding: 10px 6px;
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
div {
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background-color: rgb(255, 255, 255);
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
padding: 20px 0;
|
|
||||||
height: 80px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.from {
|
|
||||||
width: 420px;
|
|
||||||
// height: 320px;
|
|
||||||
color: @bg-color;
|
|
||||||
background-color: #ffffff44;
|
|
||||||
border-radius: 20px;
|
|
||||||
border: 1px solid #fff;
|
|
||||||
padding: 32px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
.from-title {
|
|
||||||
font-family: Source Han Sans SC;
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 24px;
|
|
||||||
color: @bg-color;
|
|
||||||
line-height: 37px;
|
|
||||||
|
|
||||||
div {
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: 600;
|
|
||||||
// border-bottom: 4px solid #1db97d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.from-input {
|
|
||||||
width: 100%;
|
|
||||||
padding: 15px 0;
|
|
||||||
|
|
||||||
.from-input-item {
|
|
||||||
display: flex;
|
|
||||||
padding: 8px 0;
|
|
||||||
|
|
||||||
.from-input-item-title {
|
|
||||||
color: @bg-color;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 500;
|
|
||||||
width: 80px;
|
|
||||||
height: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loginButton {
|
|
||||||
width: 359px;
|
|
||||||
height: 50px;
|
|
||||||
background: #ffffff;
|
|
||||||
border-radius: 24px;
|
|
||||||
border: 1px solid #ffffff;
|
|
||||||
|
|
||||||
font-family: Source Han Sans SC;
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 18px;
|
|
||||||
color: @bg-color;
|
|
||||||
line-height: 37px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.from-input-item1 {
|
|
||||||
display: flex;
|
|
||||||
width: 359px;
|
|
||||||
height: 50px;
|
|
||||||
background: @bg-color-light-light;
|
|
||||||
border-radius: 24px;
|
|
||||||
border: 1px solid #ffffff;
|
|
||||||
padding: 12px 25px 13px 25px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.center-line {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.center-justify {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-around;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.center-align {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.center-flex {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-input__wrapper {
|
|
||||||
--el-input-focus-border-color: rgba(255, 255, 0, 0);
|
|
||||||
--el-menu-hover-bg-color: rgba(255, 255, 0, 0);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style scoped lang="less">
|
|
||||||
::v-deep(.el-input__wrapper) {
|
|
||||||
background-color: rgba(255, 0, 0, 0);
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep(.el-input__inner) {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep(.el-input__inner::placeholder) {
|
|
||||||
color: @bg-color;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
77
src/views/hosts/Forum.vue
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
<template>
|
||||||
|
<div class="forum">
|
||||||
|
<div v-infinite-scroll="load" class="infinite-list" style="overflow: auto">
|
||||||
|
|
||||||
|
<el-card style="width: 90%">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span>Card name</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<p v-for="o in 2" :key="o" class="text item">{{ "List item " + o }}</p>
|
||||||
|
<template #footer>
|
||||||
|
<div class="card-footer">
|
||||||
|
<span>Card footer</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
ref, // 响应式基础
|
||||||
|
watch, // 侦听器
|
||||||
|
onMounted, // 组件挂载完成后执行
|
||||||
|
onUpdated, // 组件更新后执行
|
||||||
|
onUnmounted, // 组件销毁前执行
|
||||||
|
} from "vue";
|
||||||
|
const refname = ref("");
|
||||||
|
function load() {
|
||||||
|
// 加载更多数据
|
||||||
|
}
|
||||||
|
watch(refname, async (newQuestion, oldQuestion) => {
|
||||||
|
// 变化后执行
|
||||||
|
});
|
||||||
|
onMounted(() => {
|
||||||
|
// 组件挂载完成后执行
|
||||||
|
});
|
||||||
|
onUpdated(() => {
|
||||||
|
// 组件更新后执行
|
||||||
|
});
|
||||||
|
onUnmounted(() => {
|
||||||
|
// 组件销毁前执行
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
.forum {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.infinite-list {
|
||||||
|
width: 90%;
|
||||||
|
height: 90%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.card-header{
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.card-footer{
|
||||||
|
font-size: 14px;
|
||||||
|
display: flex;
|
||||||
|
justify-content:flex-end;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
218
src/views/hosts/Message.vue
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
<template>
|
||||||
|
<div class="message">
|
||||||
|
<div style="height: 100%">
|
||||||
|
<el-splitter>
|
||||||
|
<el-splitter-panel size="17%" min="17%" max="25%">
|
||||||
|
<!-- 会话列表 -->
|
||||||
|
<div class="demo-panel">
|
||||||
|
<div
|
||||||
|
v-infinite-scroll="load"
|
||||||
|
infinite-scroll-distance="100px"
|
||||||
|
class="chatList"
|
||||||
|
style="overflow: auto"
|
||||||
|
>
|
||||||
|
<div class="chatItem" v-for="(item, index) in chatList" :key="index">
|
||||||
|
<div class="Avatar"></div>
|
||||||
|
<div class="chatContent">
|
||||||
|
<div class="PersonalInfo">
|
||||||
|
<div class="name">名称</div>
|
||||||
|
<div class="time">07-29 14:00</div>
|
||||||
|
</div>
|
||||||
|
<div class="chatText">最后一条消息</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-splitter-panel>
|
||||||
|
<el-splitter-panel>
|
||||||
|
<el-splitter layout="vertical">
|
||||||
|
<el-splitter-panel>
|
||||||
|
<!-- 消息列表 -->
|
||||||
|
<div class="demo-panel"></div>
|
||||||
|
</el-splitter-panel>
|
||||||
|
<el-splitter-panel size="20%" min="20%" max="40%">
|
||||||
|
<!-- 输入框 -->
|
||||||
|
<div class="demo-panel">
|
||||||
|
<div class="inputBox">
|
||||||
|
<div class="Console">
|
||||||
|
<div class="Console-content">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input">
|
||||||
|
<textarea
|
||||||
|
v-model="textarea"
|
||||||
|
class="textarea"
|
||||||
|
style="width: 100%; height: 100%"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-splitter-panel>
|
||||||
|
</el-splitter>
|
||||||
|
</el-splitter-panel>
|
||||||
|
</el-splitter>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
ref, // 响应式基础
|
||||||
|
watch, // 侦听器
|
||||||
|
onMounted, // 组件挂载完成后执行
|
||||||
|
onUpdated, // 组件更新后执行
|
||||||
|
onUnmounted, // 组件销毁前执行
|
||||||
|
} from "vue";
|
||||||
|
const refname = ref("");
|
||||||
|
const textarea = ref(""); // 输入框内容
|
||||||
|
const chatList = ref([
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
]);
|
||||||
|
|
||||||
|
function load() {
|
||||||
|
console.log("加载更多",textarea.value);
|
||||||
|
|
||||||
|
} // 加载更多
|
||||||
|
|
||||||
|
watch(refname, async (newQuestion, oldQuestion) => {
|
||||||
|
// 变化后执行
|
||||||
|
});
|
||||||
|
onMounted(() => {
|
||||||
|
// 组件挂载完成后执行
|
||||||
|
});
|
||||||
|
onUpdated(() => {
|
||||||
|
// 组件更新后执行
|
||||||
|
});
|
||||||
|
onUnmounted(() => {
|
||||||
|
// 组件销毁前执行
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
.message {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.demo-panel {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.chatList {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #ffffff;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
.chatItem {
|
||||||
|
width: 100%;
|
||||||
|
height: 70px;
|
||||||
|
background-color: #ffffff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.chatItem:hover {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
.Avatar {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-left: 10px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
.chatContent {
|
||||||
|
margin-left: 10px;
|
||||||
|
width: calc(100% - 80px);
|
||||||
|
height: 60%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.PersonalInfo {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.name {
|
||||||
|
width: 50%;
|
||||||
|
font-size: 14px;
|
||||||
|
color: @font-color;
|
||||||
|
font-weight: bold;
|
||||||
|
white-space: nowrap; /* 单行显示 */
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis; /* 显示省略号 */
|
||||||
|
}
|
||||||
|
.time {
|
||||||
|
font-size: 12px;
|
||||||
|
color: @Prompt-text-color;
|
||||||
|
}
|
||||||
|
.chatText {
|
||||||
|
font-size: 10px;
|
||||||
|
color: @font-color;
|
||||||
|
width: 100%;
|
||||||
|
white-space: nowrap; /* 单行显示 */
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis; /* 显示省略号 */
|
||||||
|
}
|
||||||
|
.inputBox {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.Console {
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.Console-content{
|
||||||
|
width: 98%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.input {
|
||||||
|
width: 98%;
|
||||||
|
height: calc(100% - 70px);
|
||||||
|
}
|
||||||
|
.textarea{
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color:#ffffff00;
|
||||||
|
resize:none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
105
src/views/hosts/Mine.vue
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
<template>
|
||||||
|
<div class="mine">
|
||||||
|
<div class="custom-style">
|
||||||
|
<el-segmented v-model="segmentedvalue" :options="options" block>
|
||||||
|
<template #default="scope">
|
||||||
|
<div class="flex flex-col items-center gap-2 p-2">
|
||||||
|
<el-icon size="1.5vw">
|
||||||
|
<component :is="scope.item.icon" />
|
||||||
|
</el-icon>
|
||||||
|
<div>{{ scope.item.label }}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-segmented>
|
||||||
|
</div>
|
||||||
|
<div class="mine-content">
|
||||||
|
<PointsList v-if="segmentedvalue === 4" />
|
||||||
|
<PKRecord v-if="segmentedvalue === 3" />
|
||||||
|
<PKmessage v-if="segmentedvalue === 2" />
|
||||||
|
<AnchorLibrary v-if="segmentedvalue === 1" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
ref, // 响应式基础
|
||||||
|
watch, // 侦听器
|
||||||
|
onMounted, // 组件挂载完成后执行
|
||||||
|
onUpdated, // 组件更新后执行
|
||||||
|
onUnmounted, // 组件销毁前执行
|
||||||
|
} from "vue";
|
||||||
|
const refname = ref('');
|
||||||
|
import {
|
||||||
|
Document,
|
||||||
|
Mic,
|
||||||
|
Coin,
|
||||||
|
List
|
||||||
|
} from '@element-plus/icons-vue';
|
||||||
|
import PointsList from "@/components/mineSubComponent/PointsList";
|
||||||
|
import PKRecord from "@/components/mineSubComponent/PKRecord";
|
||||||
|
import PKmessage from "@/components/mineSubComponent/PKmessage";
|
||||||
|
import AnchorLibrary from "@/components/mineSubComponent/AnchorLibrary";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const options = [
|
||||||
|
{
|
||||||
|
label: '主播库',
|
||||||
|
value: 1,
|
||||||
|
icon: Coin,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'PK信息',
|
||||||
|
value: 2,
|
||||||
|
icon: Mic,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '我的PK记录',
|
||||||
|
value: 3,
|
||||||
|
icon: List,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '积分列表',
|
||||||
|
value: 4,
|
||||||
|
icon: Document,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const segmentedvalue = ref(1);
|
||||||
|
watch(refname, async (newQuestion, oldQuestion) => {
|
||||||
|
// 变化后执行
|
||||||
|
});
|
||||||
|
onMounted(() => {
|
||||||
|
// 组件挂载完成后执行
|
||||||
|
});
|
||||||
|
onUpdated(() => {
|
||||||
|
// 组件更新后执行
|
||||||
|
});
|
||||||
|
onUnmounted(() => {
|
||||||
|
// 组件销毁前执行
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
.mine{
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.custom-style .el-segmented {
|
||||||
|
height: 70px;
|
||||||
|
--el-segmented-item-selected-color: var(--el-text-color-primary);
|
||||||
|
--el-segmented-item-selected-bg-color: @border-color;
|
||||||
|
--el-border-radius-base: 20px;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
.mine-content{
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100% - 70px);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,834 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="hostList">
|
|
||||||
<div>
|
|
||||||
<!-- -->
|
|
||||||
<div style="display: flex">
|
|
||||||
<div></div>
|
|
||||||
<el-input
|
|
||||||
v-model="queryFormData.coinMin"
|
|
||||||
placeholder="最小金币"
|
|
||||||
size="large"
|
|
||||||
style="width: 180px"
|
|
||||||
type="number"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<el-input
|
|
||||||
v-model="queryFormData.coinMax"
|
|
||||||
placeholder="最大金币"
|
|
||||||
size="large"
|
|
||||||
style="width: 180px;"
|
|
||||||
class="right-input"
|
|
||||||
type="number"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<el-input
|
|
||||||
v-model="queryFormData.levelMin"
|
|
||||||
placeholder="最小等级"
|
|
||||||
size="large"
|
|
||||||
style="width: 180px;"
|
|
||||||
class="right-input"
|
|
||||||
type="number"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<el-input
|
|
||||||
v-model="queryFormData.levelMax"
|
|
||||||
placeholder="最大等级"
|
|
||||||
size="large"
|
|
||||||
style="width: 180px;"
|
|
||||||
class="right-input"
|
|
||||||
type="number"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div class="right-input right-text" style="width: 250px; height: 50px; line-height: 50px">
|
|
||||||
当前网络:{{ countryData }}
|
|
||||||
</div>
|
|
||||||
<div class="right-input right-text" style="width: 160px; height: 50px; line-height: 50px">
|
|
||||||
总数:{{ getBrotherInfodata.total }}
|
|
||||||
</div>
|
|
||||||
<div class="right-input right-text" style="width: 160px;height: 50px; line-height: 50px">
|
|
||||||
有效数:{{ getBrotherInfodata.valid }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-button
|
|
||||||
class="serch-button right-input"
|
|
||||||
type="primary"
|
|
||||||
@click="Resetss"
|
|
||||||
>重置</el-button
|
|
||||||
>
|
|
||||||
|
|
||||||
<el-button
|
|
||||||
class="serch-button right-input"
|
|
||||||
style="width: 150px"
|
|
||||||
type="primary"
|
|
||||||
@click="openTikTok"
|
|
||||||
>打开 TikTok 登录</el-button
|
|
||||||
>
|
|
||||||
<el-button
|
|
||||||
v-show="queryFormData.isRunning"
|
|
||||||
class="serch-button right-input"
|
|
||||||
type="primary"
|
|
||||||
@click="getBigBrother"
|
|
||||||
>开始</el-button
|
|
||||||
>
|
|
||||||
<el-button
|
|
||||||
v-show="!queryFormData.isRunning"
|
|
||||||
class="serch-button right-input"
|
|
||||||
type="primary"
|
|
||||||
@click="BigBrotherstop"
|
|
||||||
>结束</el-button
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<!-- `````````````````````````````````````````````````````````````````````````````````````````````````` -->
|
|
||||||
<div style="width: 100%; border-bottom: 1px solid #e9e9e9; margin-top: 30px"></div>
|
|
||||||
<!-- ···································································································· -->
|
|
||||||
<div style="display: flex; margin-top: 30px; flex-wrap: wrap">
|
|
||||||
<el-select
|
|
||||||
v-model="searchForm.region"
|
|
||||||
filterable
|
|
||||||
placeholder="选择国家"
|
|
||||||
size="large"
|
|
||||||
style="width: 160px"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in options"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
|
|
||||||
<el-input
|
|
||||||
v-model="searchForm.displayId"
|
|
||||||
placeholder="大哥id"
|
|
||||||
size="large"
|
|
||||||
style="width: 160px;"
|
|
||||||
class="right-input"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
|
|
||||||
<el-button
|
|
||||||
class="serch-button right-input"
|
|
||||||
type="primary"
|
|
||||||
@click="serch"
|
|
||||||
>查询</el-button
|
|
||||||
>
|
|
||||||
|
|
||||||
<el-button class="serch-button" type="primary" @click="reset"> 重置 </el-button>
|
|
||||||
|
|
||||||
<el-button
|
|
||||||
class="put-button"
|
|
||||||
:disabled="tableData.length == 0"
|
|
||||||
type="primary"
|
|
||||||
@click="exportList"
|
|
||||||
>导出Excel数据</el-button
|
|
||||||
>
|
|
||||||
<el-button
|
|
||||||
@click="filterdialogVisible = true"
|
|
||||||
class="put-button buttoMore-filters"
|
|
||||||
type="primary"
|
|
||||||
><img class="filters-img" src="@/assets/filter.png"
|
|
||||||
/><div style="margin-left: 10px">
|
|
||||||
更多筛选
|
|
||||||
</div></el-button>
|
|
||||||
<!-- <el-button @click="filterdialogVisible = true" style="width: 50px;" class="put-button" type="primary"><img
|
|
||||||
style="height: 30px;" src="@/assets/filter.png"></el-button> -->
|
|
||||||
</div>
|
|
||||||
<!-- ····················································································································· -->
|
|
||||||
<div class="hostTable center-justify">
|
|
||||||
<el-table
|
|
||||||
ref="multipleTableRef"
|
|
||||||
:data="tableData"
|
|
||||||
stripe
|
|
||||||
v-loading="loading"
|
|
||||||
max-height="500"
|
|
||||||
@selection-change="handleSelectionChange"
|
|
||||||
>
|
|
||||||
<!-- <el-table-column type="selection" width="35" /> -->
|
|
||||||
|
|
||||||
<el-table-column fixed prop="displayId" label="Id" :width="screenWidth">
|
|
||||||
<template #default="scope">
|
|
||||||
<div class="hostIdText" @click="openHTML(scope.row.displayId)">
|
|
||||||
{{ scope.row.displayId }}
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
<el-table-column
|
|
||||||
v-for="label in labelList"
|
|
||||||
:key="label.paramCode"
|
|
||||||
:prop="label.paramCode"
|
|
||||||
:label="label.paramCodeMeaning"
|
|
||||||
:width="screenWidth"
|
|
||||||
>
|
|
||||||
<template v-if="label.paramCode != 'createDt'" #default="scope"> </template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
<!-- ······································································································································ -->
|
|
||||||
<!-- 分页 -->
|
|
||||||
<div class="center-justify" style="margin-top: 30px">
|
|
||||||
<el-pagination
|
|
||||||
v-model:current-page="page"
|
|
||||||
v-model:page-size="pageSize"
|
|
||||||
background
|
|
||||||
layout="sizes, prev, pager, next"
|
|
||||||
:total="total"
|
|
||||||
:page-sizes="[10, 20, 50, 100, 500, 1000]"
|
|
||||||
@size-change="handleSizeChange"
|
|
||||||
@current-change="handleCurrentChange"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- ·······································································弹窗······································································· -->
|
|
||||||
<el-dialog v-model="filterdialogVisible" width="800px" :before-close="handleClose">
|
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col :span="4">
|
|
||||||
<!-- <label>选择筛选条件</label> -->
|
|
||||||
<div style="height: 100%; padding-top: 10px" class="center-justify">时间</div>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="10">
|
|
||||||
<div><label>开始时间/结束时间</label></div>
|
|
||||||
|
|
||||||
<el-date-picker
|
|
||||||
v-model="createTimes"
|
|
||||||
type="datetimerange"
|
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
|
||||||
placeholder="选择查询时间"
|
|
||||||
size="large"
|
|
||||||
style="width: 600px; margin-top: 10px"
|
|
||||||
/>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-row
|
|
||||||
v-for="(field, index) in fields"
|
|
||||||
:key="index"
|
|
||||||
:gutter="20"
|
|
||||||
style="margin-bottom: 10px"
|
|
||||||
>
|
|
||||||
<el-col :span="4">
|
|
||||||
<div style="height: 100%" class="center-justify">
|
|
||||||
{{ field.label }}
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="10">
|
|
||||||
<div><label>最小值</label></div>
|
|
||||||
<el-input
|
|
||||||
type="number"
|
|
||||||
:oninput="'if(value.length>9)value=value.slice(0,9)'"
|
|
||||||
v-model.number="searchForm[field.minModel]"
|
|
||||||
placeholder="请输入最小值"
|
|
||||||
/>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="10">
|
|
||||||
<div><label>最大值</label></div>
|
|
||||||
<el-input
|
|
||||||
type="number"
|
|
||||||
:oninput="'if(value.length>9)value=value.slice(0,9)'"
|
|
||||||
v-model.number="searchForm[field.maxModel]"
|
|
||||||
placeholder="请输入最大值"
|
|
||||||
/>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col :span="4">
|
|
||||||
<!-- <label>选择筛选条件</label> -->
|
|
||||||
<div style="height: 100%; padding-top: 10px" class="center-justify">排序</div>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="10">
|
|
||||||
<div><label>排序类型</label></div>
|
|
||||||
|
|
||||||
<el-select
|
|
||||||
v-model="sortData.sortName"
|
|
||||||
filterable
|
|
||||||
placeholder="请选择"
|
|
||||||
style="width: 240px"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in sortNameOptions"
|
|
||||||
:key="item.type"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.type"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="10">
|
|
||||||
<div><label>升序/降序</label></div>
|
|
||||||
|
|
||||||
<el-select
|
|
||||||
v-model="sortData.sort"
|
|
||||||
filterable
|
|
||||||
placeholder="请选择"
|
|
||||||
style="width: 240px"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in [
|
|
||||||
{ label: '升序', value: 'asc' },
|
|
||||||
{ label: '降序', value: 'desc' },
|
|
||||||
]"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<template #footer>
|
|
||||||
<span class="dialog-footer">
|
|
||||||
<el-button type="primary" @click="reset"> 重置 </el-button>
|
|
||||||
<!-- <el-button @click="filterdialogVisible = false">取消</el-button> -->
|
|
||||||
<el-button type="primary" @click="handelClick"> 确认 </el-button>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
// import { getToken, setToken, removeToken } from '@/utils/storage'
|
|
||||||
import {
|
|
||||||
tkhostdata,
|
|
||||||
dicts,
|
|
||||||
tkhostdetail,
|
|
||||||
downList,
|
|
||||||
getStaffList,
|
|
||||||
managerhosts,
|
|
||||||
upholdinfo,
|
|
||||||
getCountryinfo,
|
|
||||||
accountName,
|
|
||||||
} from "@/api/account";
|
|
||||||
import { usePythonBridge } from "@/utils/pythonBridge";
|
|
||||||
import { getUser, setSerch, getSerch } from "@/utils/storage";
|
|
||||||
import { ref, reactive, onMounted,onBeforeUnmount } from "vue";
|
|
||||||
import EChartsComponent from "@/components/EChartsComponent.vue";
|
|
||||||
import { ElMessage, ElMessageBox } from "element-plus";
|
|
||||||
import { color } from "echarts";
|
|
||||||
import { getCountryName } from "@/utils/countryUtil";
|
|
||||||
import { ElLoading } from "element-plus";
|
|
||||||
//ip国家
|
|
||||||
let countryData = ref("");
|
|
||||||
//获取屏幕宽度
|
|
||||||
const screenWidth = ref(window.innerWidth/10);
|
|
||||||
//获取国家
|
|
||||||
const getIpInfo = async () => {
|
|
||||||
try {
|
|
||||||
const response = await fetch("https://ipapi.co/json/");
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("请求失败");
|
|
||||||
}
|
|
||||||
const data = await response.json();
|
|
||||||
console.log("IP信息:", data.country);
|
|
||||||
|
|
||||||
countryData.value = getCountryName(data.country);
|
|
||||||
} catch (error) {
|
|
||||||
console.error("请求出错:", error);
|
|
||||||
ElMessageBox.prompt("请输入将要获取国家的中文名", "获取国家失败", {
|
|
||||||
confirmButtonText: "确认",
|
|
||||||
cancelButtonText: "取消",
|
|
||||||
showClose: false,
|
|
||||||
closeOnClickModal: false,
|
|
||||||
showCancelButton: false,
|
|
||||||
}).then(({ value }) => {
|
|
||||||
countryData.value = value;
|
|
||||||
});
|
|
||||||
// .catch(() => {
|
|
||||||
// ElMessage({
|
|
||||||
// type: 'info',
|
|
||||||
// message: 'Input canceled',
|
|
||||||
// })
|
|
||||||
// })
|
|
||||||
}
|
|
||||||
};
|
|
||||||
//打开TikTok登录
|
|
||||||
function openTikTok() {
|
|
||||||
loginTikTok();
|
|
||||||
}
|
|
||||||
//重置
|
|
||||||
function Resetss() {
|
|
||||||
queryFormData.value = {};
|
|
||||||
}
|
|
||||||
//大哥climb
|
|
||||||
const queryFormData = ref({
|
|
||||||
coinMin: "",
|
|
||||||
coinMax: "",
|
|
||||||
levelMin: "",
|
|
||||||
levelMax: "",
|
|
||||||
isRunning: true,
|
|
||||||
});
|
|
||||||
//时间
|
|
||||||
const timerId = ref(null);
|
|
||||||
const getBrotherInfodata = ref({
|
|
||||||
total: 0,
|
|
||||||
valid: 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
function BigBrotherstop() {
|
|
||||||
queryFormData.value.tenantId = userInfo.value.tenantId;
|
|
||||||
queryFormData.value.region = countryData.value;
|
|
||||||
controlTask(JSON.stringify(queryFormData.value)).then((res) => {
|
|
||||||
queryFormData.value.isRunning = true;
|
|
||||||
clearInterval(timerId.value);
|
|
||||||
timerId.value = null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function getBigBrother() {
|
|
||||||
const loading = ElLoading.service({
|
|
||||||
lock: true,
|
|
||||||
text: "正在启动...",
|
|
||||||
background: "rgba(0, 0, 0, 0.7)",
|
|
||||||
});
|
|
||||||
queryFormData.value.tenantId = userInfo.value.tenantId;
|
|
||||||
queryFormData.value.region = countryData.value;
|
|
||||||
controlTask(JSON.stringify(queryFormData.value)).then((res) => {
|
|
||||||
queryFormData.value.isRunning = false;
|
|
||||||
timerId.value = setInterval(() => {
|
|
||||||
getBrotherInfo().then((res) => {
|
|
||||||
loading.close();
|
|
||||||
getBrotherInfodata.value = res;
|
|
||||||
});
|
|
||||||
}, 1000);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const loading = ref(false);
|
|
||||||
//py方法
|
|
||||||
const {
|
|
||||||
givePyAnchorId,
|
|
||||||
exportToExcel,
|
|
||||||
loginTikTok,
|
|
||||||
controlTask,
|
|
||||||
getBrotherInfo,
|
|
||||||
} = usePythonBridge();
|
|
||||||
|
|
||||||
let num = ref(0);
|
|
||||||
//账号信息
|
|
||||||
const userInfo = ref({});
|
|
||||||
//主播列表DOM
|
|
||||||
const multipleTableRef = ref(null);
|
|
||||||
let labelList = ref([
|
|
||||||
{ paramCode: "userIdStr", paramCodeMeaning: "用户id" },
|
|
||||||
{ paramCode: "level", paramCodeMeaning: "等级" },
|
|
||||||
{ paramCode: "hostcoins", paramCodeMeaning: "打赏的金币" },
|
|
||||||
{ paramCode: "hostDisplayId", paramCodeMeaning: "所在直播间主播id" },
|
|
||||||
{ paramCode: "region", paramCodeMeaning: "地区" },
|
|
||||||
{ paramCode: "followerCount", paramCodeMeaning: "粉丝数" },
|
|
||||||
{ paramCode: "followingCount", paramCodeMeaning: "关注数" },
|
|
||||||
{ paramCode: "createTime", paramCodeMeaning: "创建时间" },
|
|
||||||
]);
|
|
||||||
|
|
||||||
const tableData = ref([]);
|
|
||||||
//主播列表传参
|
|
||||||
const searchForm = ref({});
|
|
||||||
const createTimes = ref([]);
|
|
||||||
//分页
|
|
||||||
const page = ref(1);
|
|
||||||
const pageSize = ref(10);
|
|
||||||
const fields = [
|
|
||||||
// { label: "打赏的金币", minModel: "hostcoinsMin", maxModel: "hostcoinsMax" },
|
|
||||||
{ label: "等级", minModel: "levelMin", maxModel: "levelMax" },
|
|
||||||
];
|
|
||||||
//排序
|
|
||||||
let sortData = ref({ sortName: "createTime", sort: "desc" });
|
|
||||||
|
|
||||||
//排序类型
|
|
||||||
let sortNameOptions = ref([
|
|
||||||
{ label: "创建时间", type: "createTime" },
|
|
||||||
{ label: "打赏的金币", type: "hostsCoins" },
|
|
||||||
{ label: "等级", type: "level" },
|
|
||||||
]);
|
|
||||||
//员工选择列表
|
|
||||||
let staffOptions = ref([]);
|
|
||||||
//筛选条件选择列表
|
|
||||||
|
|
||||||
//选择的员工
|
|
||||||
let staffValue = ref("");
|
|
||||||
//选择的主播列表
|
|
||||||
let selectHostList = ref([]);
|
|
||||||
//分配弹窗是否弹出
|
|
||||||
let dialogFormVisible = ref(false);
|
|
||||||
//分配情况弹窗是否弹出
|
|
||||||
let hostNameVisible = ref(false);
|
|
||||||
|
|
||||||
//备注弹窗是否弹出
|
|
||||||
let commentVisible = ref(false);
|
|
||||||
//筛选弹窗是否弹出
|
|
||||||
let filterdialogVisible = ref(false);
|
|
||||||
//分配的员工
|
|
||||||
let staffId = ref({});
|
|
||||||
//备注信息
|
|
||||||
let commentInfo = ref("");
|
|
||||||
//备注信息主播
|
|
||||||
let commentHost = ref("");
|
|
||||||
//分页
|
|
||||||
let total = ref(0);
|
|
||||||
//是否渲染
|
|
||||||
const isPopoverVisible = reactive({});
|
|
||||||
|
|
||||||
let options = ref([]);
|
|
||||||
|
|
||||||
let version = ref("0.0.0");
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
window.addEventListener('resize', handleResize)
|
|
||||||
setTimeout(() => {
|
|
||||||
getUserdata();
|
|
||||||
}, 500);
|
|
||||||
});
|
|
||||||
|
|
||||||
function handleResize() {
|
|
||||||
screenWidth.value = window.innerWidth/10;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getUserdata() {
|
|
||||||
const User = await getUser();
|
|
||||||
userInfo.value = User;
|
|
||||||
getCountry(); //获取国家
|
|
||||||
getlist(); //获取主播列表
|
|
||||||
getIpInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
function serch() {
|
|
||||||
page.value = 1;
|
|
||||||
getlist();
|
|
||||||
}
|
|
||||||
|
|
||||||
function exportList() {
|
|
||||||
// if (searchForm.value.dataType == "InvitationType") {
|
|
||||||
// searchForm.value.dataEnd = searchForm.value.dataStart;
|
|
||||||
// }
|
|
||||||
exportToExcel(requestParams.value);
|
|
||||||
|
|
||||||
// //浏览器导出方法
|
|
||||||
// downList('export/hostsinfo',
|
|
||||||
// {
|
|
||||||
// searchTime: searchForm.value.time,
|
|
||||||
// region: searchForm.value.country,
|
|
||||||
// pageSize: pageSize.value,
|
|
||||||
// page: page.value,
|
|
||||||
// userId: userInfo.value.userId,
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
}
|
|
||||||
//分页每页条数
|
|
||||||
function handleSizeChange(val) {
|
|
||||||
console.log(`${val} items per page`);
|
|
||||||
getlist();
|
|
||||||
}
|
|
||||||
//分页页数
|
|
||||||
function handleCurrentChange(val) {
|
|
||||||
console.log(`current page: ${val}`);
|
|
||||||
getlist();
|
|
||||||
}
|
|
||||||
//选择行
|
|
||||||
function handleSelectionChange(data) {
|
|
||||||
console.log(data);
|
|
||||||
selectHostList.value = [];
|
|
||||||
data.forEach((item) => {
|
|
||||||
selectHostList.value.push(item.hostId);
|
|
||||||
});
|
|
||||||
// multipleTableRef.value = data
|
|
||||||
// console.log(multipleTableRef.value)
|
|
||||||
}
|
|
||||||
//时间格式化
|
|
||||||
function formatDate(date) {
|
|
||||||
const year = date.getFullYear();
|
|
||||||
const month = String(date.getMonth() + 1).padStart(2, "0"); // 月份从 0开始,需要+1
|
|
||||||
const day = String(date.getDate()).padStart(2, "0");
|
|
||||||
const hours = String(date.getHours()).padStart(2, "0");
|
|
||||||
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
||||||
const seconds = String(date.getSeconds()).padStart(2, "0");
|
|
||||||
|
|
||||||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
|
||||||
}
|
|
||||||
//获取主播列表
|
|
||||||
//记录请求参数
|
|
||||||
let requestParams = ref({});
|
|
||||||
const getlist = () => {
|
|
||||||
loading.value = true;
|
|
||||||
tkhostdata({
|
|
||||||
tenantId: Number(userInfo.value.tenantId),
|
|
||||||
sort: sortData.value.sort, //正序倒序
|
|
||||||
sortName: sortData.value.sortName, //排序类型
|
|
||||||
current: page.value,
|
|
||||||
pageSize: pageSize.value,
|
|
||||||
createTimeStart: createTimes.value[0],
|
|
||||||
createTimeEnd: createTimes.value[1],
|
|
||||||
...searchForm.value, //筛选条件
|
|
||||||
}).then((res) => {
|
|
||||||
loading.value = false;
|
|
||||||
console.log(res);
|
|
||||||
if (res) {
|
|
||||||
requestParams.value = res.records;
|
|
||||||
console.log(res.records);
|
|
||||||
total.value = Number(res.total);
|
|
||||||
tableData.value = res.records.map((item) => ({
|
|
||||||
level: item.level, // 等级
|
|
||||||
createTime: formatDate(new Date(item.createTime)), // 创建时间
|
|
||||||
followerCount: item.followerCount, // 粉丝数
|
|
||||||
followingCount: item.followingCount, // 关注数
|
|
||||||
hostDisplayId: item.hostDisplayId, // 所在直播间主播id
|
|
||||||
hostcoins: item.hostcoins, // 打赏的金币
|
|
||||||
region: item.region, // 地区
|
|
||||||
totalGiftCoins: item.totalGiftCoins, // 打赏金币总和
|
|
||||||
userIdStr: item.userIdStr, // 用户id
|
|
||||||
displayId: item.displayId,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
function handelClick() {
|
|
||||||
filterdialogVisible.value = false;
|
|
||||||
}
|
|
||||||
function reset() {
|
|
||||||
searchForm.value = {};
|
|
||||||
sortData.value = { sortName: "createTime", sort: "desc" };
|
|
||||||
createTimes.value = [];
|
|
||||||
}
|
|
||||||
function handleClose(done) {
|
|
||||||
console.log("关闭");
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
|
|
||||||
//修改主播维护状态
|
|
||||||
// function handleSelectChange(event, data) {
|
|
||||||
|
|
||||||
// upholdinfo({
|
|
||||||
// "hostId": data.hostId,
|
|
||||||
// "userId": userInfo.value.userId,
|
|
||||||
// "tenantId": userInfo.value.tenantId,
|
|
||||||
// // "comment": "我已经尽力维护,但是失败了",
|
|
||||||
// "useable": event.target.value
|
|
||||||
// }).then(res => {
|
|
||||||
// console.log(res)
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
|
|
||||||
//更改主播维护备注
|
|
||||||
|
|
||||||
// function uphostcomment() {
|
|
||||||
// upholdinfo({
|
|
||||||
// "hostId": commentHost.value,
|
|
||||||
// "userId": userInfo.value.userId,
|
|
||||||
// "tenantId": userInfo.value.tenantId,
|
|
||||||
// "comment": commentInfo.value,
|
|
||||||
// }).then(res => {
|
|
||||||
// console.log(res)
|
|
||||||
// serch()
|
|
||||||
// commentVisible.value = false
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
|
|
||||||
function filterTag(value, row) {
|
|
||||||
console.log(row.useable, value);
|
|
||||||
return row.useable === value;
|
|
||||||
}
|
|
||||||
|
|
||||||
//获取国家
|
|
||||||
function getCountry() {
|
|
||||||
getCountryinfo({})
|
|
||||||
.then((res) => {
|
|
||||||
console.log("````````国家`````````", res);
|
|
||||||
res.forEach((item) => {
|
|
||||||
if (item.countryGroupName) {
|
|
||||||
options.value.push({
|
|
||||||
value: item.countryGroupName,
|
|
||||||
label: item.countryGroupName,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
console.log("````````国家2`````````", options.value);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.log("getCountry", err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//获取下级员工
|
|
||||||
// const getStaff = () => {
|
|
||||||
// getStaffList({
|
|
||||||
// userId: userInfo.value.userId,
|
|
||||||
// activeYn: userInfo.value.activeYn,
|
|
||||||
// tenantId: userInfo.value.tenantId,
|
|
||||||
// }).then(res => {
|
|
||||||
// console.log(res)
|
|
||||||
// res.forEach(item => {
|
|
||||||
// staffOptions.value.push({
|
|
||||||
// value: item.userId,
|
|
||||||
// label: item.userName
|
|
||||||
// })
|
|
||||||
// })
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //分配主播给员工
|
|
||||||
// function allocation() {
|
|
||||||
// managerhosts({
|
|
||||||
// "manaId": userInfo.value.userId,
|
|
||||||
// "userId": staffValue.value,
|
|
||||||
// "tenantId": userInfo.value.tenantId,
|
|
||||||
// "hostIds": selectHostList.value
|
|
||||||
// }).then(res => {
|
|
||||||
// if (res) {
|
|
||||||
// dialogFormVisible.value = false
|
|
||||||
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
|
|
||||||
//获取主播信息
|
|
||||||
// const getTkhostdetail = (id) => {
|
|
||||||
// tkhostdetail({
|
|
||||||
// hostId: id,
|
|
||||||
// // page: 1,
|
|
||||||
// searchTimeStart: '20250401',
|
|
||||||
// searchTimeEnd: '20250403'
|
|
||||||
// }).then(res => {
|
|
||||||
|
|
||||||
// console.log(labelList.value)
|
|
||||||
|
|
||||||
// })
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
function openPopover(hostId, paramCode) {
|
|
||||||
isPopoverVisible[`${hostId}-${paramCode}`] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function closePopover(hostId, paramCode) {
|
|
||||||
// isPopoverVisible[`${hostId}-${paramCode}`] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function openHTML(id) {
|
|
||||||
console.log(id);
|
|
||||||
|
|
||||||
givePyAnchorId(id);
|
|
||||||
|
|
||||||
// upholdinfo({
|
|
||||||
// "hostId": id,
|
|
||||||
// "userId": userInfo.value.userId,
|
|
||||||
// "tenantId": userInfo.value.tenantId,
|
|
||||||
// // "comment": "我已经尽力维护,但是失败了",
|
|
||||||
// "useable": "Y"
|
|
||||||
// }).then(res => {
|
|
||||||
|
|
||||||
// getlist();
|
|
||||||
// })
|
|
||||||
}
|
|
||||||
|
|
||||||
// function openAccountName(idStr) {
|
|
||||||
// if (idStr) {
|
|
||||||
// hostNameVisible.value = true
|
|
||||||
// accountName(idStr).then(res => {
|
|
||||||
// staffId.value = JSON.stringify(res).replace(/[{}"]/g, '') // 移除所有 {} 和 "
|
|
||||||
// .split(',') // 按逗号分割成数组
|
|
||||||
|
|
||||||
// console.log(res)
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="less">
|
|
||||||
.hostList {
|
|
||||||
box-sizing: border-box;
|
|
||||||
// height: 100vh;
|
|
||||||
padding: 40px;
|
|
||||||
|
|
||||||
/* 页面无法选中 */
|
|
||||||
// -webkit-user-select: none;
|
|
||||||
// -moz-user-select: none;
|
|
||||||
// -ms-user-select: none;
|
|
||||||
// user-select: none;
|
|
||||||
|
|
||||||
.hostTable {
|
|
||||||
width: 100%;
|
|
||||||
padding: 30px 0;
|
|
||||||
|
|
||||||
.hostIdText {
|
|
||||||
text-decoration: underline;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.serch-button {
|
|
||||||
width: 80px;
|
|
||||||
height: 47px;
|
|
||||||
background: @btn-bg-color;
|
|
||||||
border-radius: 10px;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.put-button {
|
|
||||||
width: 132px;
|
|
||||||
height: 47px;
|
|
||||||
background: @btn-bg-color;
|
|
||||||
border-radius: 10px;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.buttoMore-filters{
|
|
||||||
width: 150px;
|
|
||||||
}
|
|
||||||
.filters-img{
|
|
||||||
width: 30px;
|
|
||||||
}
|
|
||||||
.el-dialog {
|
|
||||||
--el-dialog-font-line-height: 50px;
|
|
||||||
--el-dialog-width: 600px;
|
|
||||||
--el-dialog-border-radius: 8px;
|
|
||||||
|
|
||||||
// border: 10px solid @bg-color-light;
|
|
||||||
}
|
|
||||||
|
|
||||||
.center-line {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
// justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.center-justify {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-around;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.center-align {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.center-flex {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style scoped lang="less">
|
|
||||||
::v-deep(.el-input__wrapper) {
|
|
||||||
background-color: #f2faf9;
|
|
||||||
border: 1px solid @bg-color;
|
|
||||||
height: 44px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep(.el-select__wrapper) {
|
|
||||||
background-color: #f2faf9;
|
|
||||||
border: 1px solid @bg-color;
|
|
||||||
height: 48px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep(.el-pagination.is-background .el-pager li.is-active) {
|
|
||||||
background-color: @bg-color;
|
|
||||||
}
|
|
||||||
.right-input {
|
|
||||||
margin-left: 20px;
|
|
||||||
}
|
|
||||||
.right-text{
|
|
||||||
color: #666;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
538
src/views/hosts/pk.vue
Normal file
@@ -0,0 +1,538 @@
|
|||||||
|
<template>
|
||||||
|
<div class="pk">
|
||||||
|
<!-- -->
|
||||||
|
<div class="el-scrollbar__wrap">
|
||||||
|
<el-splitter>
|
||||||
|
<el-splitter-panel collapsible>
|
||||||
|
<el-splitter layout="vertical">
|
||||||
|
<el-splitter-panel collapsible size="15 %" :resizable="false">
|
||||||
|
<!-- 顶部面板 -->
|
||||||
|
<div class="demo-panel">
|
||||||
|
<div class="controlPanel">
|
||||||
|
<div
|
||||||
|
class="today"
|
||||||
|
@click="PKistodayorhall = true"
|
||||||
|
:style="{
|
||||||
|
boxShadow: PKistodayorhall
|
||||||
|
? '0px 0px 10px rgba(0, 0, 0, 0.4)'
|
||||||
|
: 'none',
|
||||||
|
color: PKistodayorhall ? '#6c757d' : '',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
PK大厅
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="hall"
|
||||||
|
@click="PKistodayorhall = false"
|
||||||
|
:style="{
|
||||||
|
boxShadow: PKistodayorhall
|
||||||
|
? 'none'
|
||||||
|
: '0px 0px 10px rgba(0, 0, 0, 0.4)',
|
||||||
|
color: PKistodayorhall ? '' : '#6c757d',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
今日PK
|
||||||
|
</div>
|
||||||
|
<div class="selectbox" :style="{flexDirection: PKistodayorhall? 'column' : 'row'}">
|
||||||
|
<!-- 国家 -->
|
||||||
|
<el-select-v2
|
||||||
|
v-model="countryvalue"
|
||||||
|
filterable
|
||||||
|
:options="country"
|
||||||
|
placeholder="请选择国家"
|
||||||
|
style="vertical-align: middle"
|
||||||
|
class="select"
|
||||||
|
/>
|
||||||
|
<!-- 性别 -->
|
||||||
|
<el-select-v2
|
||||||
|
v-model="gendervalue"
|
||||||
|
filterable
|
||||||
|
:options="genderOptions"
|
||||||
|
placeholder="请选择性别"
|
||||||
|
style="vertical-align: middle"
|
||||||
|
class="select"
|
||||||
|
:style="{marginLeft: PKistodayorhall? '0px' : '30px'}"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<!-- 最大最小金币 -->
|
||||||
|
<div class="Goldcoinbox">
|
||||||
|
<div class="Goldcoinbox-left">
|
||||||
|
<div class="Goldcoinbox-text">最小金币数(单位为K)</div>
|
||||||
|
<el-input-number
|
||||||
|
v-model="minnum"
|
||||||
|
controls-position="right"
|
||||||
|
@change="handleChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="Goldcoinbox-middle"></div>
|
||||||
|
<div class="Goldcoinbox-right">
|
||||||
|
<div class="Goldcoinbox-text">最大金币数(单位为K)</div>
|
||||||
|
<el-input-number
|
||||||
|
v-model="maxnum"
|
||||||
|
controls-position="right"
|
||||||
|
@change="handleChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 时间 -->
|
||||||
|
<div class="timebox" v-if="PKistodayorhall">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="timevalue"
|
||||||
|
type="datetimerange"
|
||||||
|
range-separator="至"
|
||||||
|
start-placeholder="最小PK时间"
|
||||||
|
end-placeholder="最大PK时间"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="btnbox" :style="{flexDirection: PKistodayorhall? 'column' : 'row',width: PKistodayorhall? '80px' : '190px'}">
|
||||||
|
<div
|
||||||
|
class="primary search"
|
||||||
|
@click="search"
|
||||||
|
:style="{
|
||||||
|
backgroundColor: searchStatus ? '#5a6268' : '',
|
||||||
|
color: searchStatus ? '#ffffff' : '',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
搜索
|
||||||
|
</div>
|
||||||
|
<div class="primary" @click="reset" :style="{marginLeft: PKistodayorhall? '0px' : '30px'}">重置</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-splitter-panel>
|
||||||
|
<el-splitter-panel collapsible>
|
||||||
|
<el-splitter>
|
||||||
|
<el-splitter-panel collapsible :resizable="false">
|
||||||
|
<!-- 列表面板 -->
|
||||||
|
<div class="demo-panel">
|
||||||
|
<div
|
||||||
|
v-infinite-scroll="load"
|
||||||
|
infinite-scroll-distance="100px"
|
||||||
|
class="infinite-list"
|
||||||
|
style="overflow: auto"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="infinite-list-item"
|
||||||
|
v-for="(item, index) in list"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<div class="infinite-card">
|
||||||
|
<!-- 头像 -->
|
||||||
|
<div class="Avatar"></div>
|
||||||
|
<div class="Information">
|
||||||
|
<!-- 个人信息 -->
|
||||||
|
<div class="Information-Personal">
|
||||||
|
<div class="Information-name">
|
||||||
|
来自世界上最长名的国家的某个人
|
||||||
|
</div>
|
||||||
|
<div class="Information-gender">女</div>
|
||||||
|
<div class="Information-Country">
|
||||||
|
来自世界上最长名的国家的某个人
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 时间 -->
|
||||||
|
<div class="time">PK时间(北京时间):2025-08-09 01:00</div>
|
||||||
|
<!--PK信息 -->
|
||||||
|
<div class="Information-PK">
|
||||||
|
<img
|
||||||
|
class="goldimg"
|
||||||
|
src="https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/gold.png"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
<div class="gold">金币:9999k</div>
|
||||||
|
<img
|
||||||
|
class="sessionimg"
|
||||||
|
src="https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/session.png"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
<div class="Session">场次:100场</div>
|
||||||
|
</div>
|
||||||
|
<!-- 备注信息 -->
|
||||||
|
<div class="Information-Remarks">
|
||||||
|
这是一条备注信息他很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-splitter-panel>
|
||||||
|
<el-splitter-panel collapsible size="27%" :resizable="false">
|
||||||
|
<!-- 聊天面板 -->
|
||||||
|
<div class="demo-panel">
|
||||||
|
<div class="chat">
|
||||||
|
<div class="chat-name">来自世界上最长名的国家的某个人</div>
|
||||||
|
<div class="chat-content"></div>
|
||||||
|
<div class="chat-input">
|
||||||
|
<div class="chat-input-Controls"></div>
|
||||||
|
<div class="chat-input-Textarea">
|
||||||
|
<el-input
|
||||||
|
v-model="textarea"
|
||||||
|
style="width:100%"
|
||||||
|
:rows="4"
|
||||||
|
type="textarea"
|
||||||
|
placeholder="请输入内容"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-splitter-panel>
|
||||||
|
</el-splitter>
|
||||||
|
</el-splitter-panel>
|
||||||
|
</el-splitter>
|
||||||
|
</el-splitter-panel>
|
||||||
|
</el-splitter>
|
||||||
|
</div>
|
||||||
|
<!-- -->
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
ref, // 响应式基础
|
||||||
|
watch, // 侦听器
|
||||||
|
onMounted, // 组件挂载完成后执行
|
||||||
|
onUpdated, // 组件更新后执行
|
||||||
|
onUnmounted, // 组件销毁前执行
|
||||||
|
} from "vue";
|
||||||
|
import { getCountryNamesArray } from "../../utils/countryUtil";
|
||||||
|
import { time } from "echarts";
|
||||||
|
const country = ref([]);
|
||||||
|
country.value = getCountryNamesArray(); //国家条目
|
||||||
|
const PKistodayorhall = ref(true); // 选择今日PK还是PK大厅/false 今日PK/true PK大厅
|
||||||
|
const genderOptions = [
|
||||||
|
{ value: 1, label: "男" },
|
||||||
|
{ value: 2, label: "女" },
|
||||||
|
]; // 性别选项
|
||||||
|
const searchStatus = ref(false); // 搜索状态
|
||||||
|
|
||||||
|
const countryvalue = ref(null); //选中的国家
|
||||||
|
const gendervalue = ref(null); // 选中的性别
|
||||||
|
const minnum = ref(null); // 最小金币
|
||||||
|
const maxnum = ref(null); // 最大金币
|
||||||
|
const timevalue = ref(null); // 时间
|
||||||
|
const textarea = ref(""); // 聊天输入框
|
||||||
|
|
||||||
|
const list = ref([{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}]); // 列表数据
|
||||||
|
|
||||||
|
//搜索按钮
|
||||||
|
function search() {
|
||||||
|
searchStatus.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//重置按钮
|
||||||
|
function reset() {
|
||||||
|
searchStatus.value = false;
|
||||||
|
countryvalue.value = null;
|
||||||
|
gendervalue.value = null;
|
||||||
|
minnum.value = null;
|
||||||
|
maxnum.value = null;
|
||||||
|
timevalue.value = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function load() {} // 加载更多
|
||||||
|
|
||||||
|
const refname = ref(""); //
|
||||||
|
watch(refname, async (newQuestion, oldQuestion) => {
|
||||||
|
// 变化后执行
|
||||||
|
});
|
||||||
|
onMounted(() => {
|
||||||
|
// 组件挂载完成后执行
|
||||||
|
});
|
||||||
|
onUpdated(() => {
|
||||||
|
// 组件更新后执行
|
||||||
|
});
|
||||||
|
onUnmounted(() => {
|
||||||
|
// 组件销毁前执行
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
.pk {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
// background-color: #ffffff;
|
||||||
|
}
|
||||||
|
.demo-panel {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.el-scrollbar__wrap {
|
||||||
|
height: 100%;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
.controlPanel {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-image: linear-gradient(
|
||||||
|
30deg,
|
||||||
|
@bg-Sidebar-color-bottom,
|
||||||
|
@bg-Sidebar-color-top
|
||||||
|
);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
.today {
|
||||||
|
width: 150px;
|
||||||
|
height: 50px;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 50px;
|
||||||
|
transition: all 0.4s ease;
|
||||||
|
color: #e9e8e8;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 50px;
|
||||||
|
letter-spacing: 3px;
|
||||||
|
}
|
||||||
|
.today:hover {
|
||||||
|
box-shadow: 5px 5px 15px rgba(0, 0, 0, 0.3);
|
||||||
|
transform: scale(1.1);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
.today:active {
|
||||||
|
transform: scale(1.1) rotate(10deg);
|
||||||
|
}
|
||||||
|
.hall {
|
||||||
|
width: 150px;
|
||||||
|
height: 50px;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 50px;
|
||||||
|
transition: all 0.4s ease;
|
||||||
|
color: #e9e8e8;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 50px;
|
||||||
|
letter-spacing: 3px;
|
||||||
|
}
|
||||||
|
.hall:hover {
|
||||||
|
box-shadow: 5px 5px 15px rgba(0, 0, 0, 0.3);
|
||||||
|
transform: scale(1.1);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
.hall:active {
|
||||||
|
transform: scale(1.1) rotate(10deg);
|
||||||
|
}
|
||||||
|
.selectbox {
|
||||||
|
display: flex;
|
||||||
|
// flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.select {
|
||||||
|
width: 150px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.Goldcoinbox {
|
||||||
|
width: 330px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.Goldcoinbox-left {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.Goldcoinbox-right {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.Goldcoinbox-text {
|
||||||
|
font-size: 10px;
|
||||||
|
color: @Prompt-text-color;
|
||||||
|
}
|
||||||
|
.Goldcoinbox-middle {
|
||||||
|
border-bottom: 2px solid #b9b9b9;
|
||||||
|
width: 5px;
|
||||||
|
height: 15px;
|
||||||
|
}
|
||||||
|
.timebox {
|
||||||
|
width: 410px;
|
||||||
|
}
|
||||||
|
.btnbox {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.primary {
|
||||||
|
width: 80px;
|
||||||
|
height: 30px;
|
||||||
|
background-color: #e9e7e7;
|
||||||
|
border-radius: 10px;
|
||||||
|
color: @Supplementary-text-color;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 30px;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
transition: all 0.4s ease;
|
||||||
|
}
|
||||||
|
.search {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.primary:hover {
|
||||||
|
background-color: #5a6268;
|
||||||
|
color: #ffffff;
|
||||||
|
transform: scale(1.1);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
.infinite-list {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
.infinite-list-item {
|
||||||
|
width: 100%;
|
||||||
|
height: 170px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
margin-top: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.infinite-card {
|
||||||
|
width: 90%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
background-image: linear-gradient(0deg, @bg-Sidebar-color-top, @bg-color);
|
||||||
|
border-radius: 20px;
|
||||||
|
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.3);
|
||||||
|
transition: all 0.4s ease;
|
||||||
|
}
|
||||||
|
.infinite-card:hover {
|
||||||
|
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.8);
|
||||||
|
transform: scale(1.1);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
.Avatar {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #ececec;
|
||||||
|
margin-left: 30px;
|
||||||
|
}
|
||||||
|
.Information {
|
||||||
|
width: calc(100% - 160px);
|
||||||
|
height: 90%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.Information-Personal {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.Information-name {
|
||||||
|
width: auto;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: @font-color;
|
||||||
|
}
|
||||||
|
.Information-gender {
|
||||||
|
width: 50px;
|
||||||
|
height: 20px;
|
||||||
|
background-color: #e9e7e7;
|
||||||
|
border-radius: 10px;
|
||||||
|
color: @Prompt-text-color;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 20px;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
.Information-Country {
|
||||||
|
width: auto;
|
||||||
|
height: 20px;
|
||||||
|
background-color: #e9e7e7;
|
||||||
|
border-radius: 10px;
|
||||||
|
color: @Prompt-text-color;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 20px;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
.time {
|
||||||
|
font-size: 16px;
|
||||||
|
color: @Prompt-text-color;
|
||||||
|
}
|
||||||
|
.Information-PK {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.goldimg {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
.gold {
|
||||||
|
font-size: 16px;
|
||||||
|
color: @font-color;
|
||||||
|
}
|
||||||
|
.sessionimg {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
margin-left: 50px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
.Session {
|
||||||
|
font-size: 16px;
|
||||||
|
color: @font-color;
|
||||||
|
}
|
||||||
|
.Information-Remarks {
|
||||||
|
font-size: 14px;
|
||||||
|
color: @Prompt-text-color;
|
||||||
|
}
|
||||||
|
.chat {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.chat-name {
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
background-color: #ffffff;
|
||||||
|
// border-bottom: 3px solid #b9b9b9;
|
||||||
|
color: @Prompt-text-color;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 50px;
|
||||||
|
letter-spacing: 3px;
|
||||||
|
white-space: nowrap; /* 单行显示 */
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis; /* 显示省略号 */
|
||||||
|
}
|
||||||
|
.chat-content {
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100% - 200px);
|
||||||
|
}
|
||||||
|
.chat-input {
|
||||||
|
width: 100%;
|
||||||
|
height: 150px;
|
||||||
|
// border-top: 3px solid #b9b9b9;
|
||||||
|
}
|
||||||
|
.chat-input-Controls {
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
background-color: @border-color;
|
||||||
|
}
|
||||||
|
.chat-input-Textarea {
|
||||||
|
width: 100%;
|
||||||
|
height: 80px;
|
||||||
|
// background-color: #ffffff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,742 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="center-line workbenches">
|
|
||||||
<div class="center-align" style="width: 100%; margin: 0 20px;">
|
|
||||||
<div class="box-card-num1 center-line">
|
|
||||||
<div>总数量: <span>{{ hostData.totalCount }}</span></div>
|
|
||||||
<div>新建主播: <span>{{ hostData.validAnchorsCount }}</span></div>
|
|
||||||
<div> 已查询: <span>{{ hostData.checkedDataCount }}</span></div>
|
|
||||||
<div>可邀请: <span>{{ hostData.canInvitationCount }}</span></div>
|
|
||||||
<div>运行时间: <span>{{ formattedTime }}</span></div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="center-line" style="padding-top: 15vh;">
|
|
||||||
<el-button class="open-login" type="primary" @click="openTK">开启tk</el-button>
|
|
||||||
<!-- <el-button class="open-login" type="primary" @click="startTimer">计时开始</el-button> -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
|
|
||||||
<el-card class="box-card-num" v-for="(item, index) in 2" :key="index">
|
|
||||||
<div class="center-justify">
|
|
||||||
<div class="from-input-item">
|
|
||||||
<div class="from-input-item-title center-justify">
|
|
||||||
公会账号:
|
|
||||||
</div>
|
|
||||||
<el-input :disabled="!(tkData[index].code == 0 && !isLogin[index])"
|
|
||||||
v-model="tkData[index].account" placeholder="请输入登录账号" clearable />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="from-input-item">
|
|
||||||
<div class="from-input-item-title center-justify">
|
|
||||||
公会密码:
|
|
||||||
</div>
|
|
||||||
<el-input :disabled="!(tkData[index].code == 0 && !isLogin[index])"
|
|
||||||
v-model="tkData[index].password" type="password" placeholder="请输入登录密码" show-password />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-button class="open-login" style="margin-left: 60px;"
|
|
||||||
:disabled="!(tkData[index].code == 0 && !isLogin[index])" type="primary"
|
|
||||||
@click="loginTK(index)">登录后台</el-button>
|
|
||||||
<div v-if="tkData[index].code == 0" class="loginState"></div>
|
|
||||||
<div v-if="tkData[index].code == 1" class="loginState" style="background-color: green;"></div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="todayCount">今日已查询次数:{{ tkData[index].num }}</div>
|
|
||||||
</el-card>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="container ">
|
|
||||||
|
|
||||||
<el-card class="box-card">
|
|
||||||
<template #header>
|
|
||||||
<div class="card-header">
|
|
||||||
<span class="center-justify"><img src="@/assets/worklogo.png">工作台 </span>
|
|
||||||
<div style="margin-right: 120px;">当前网络:{{ countryData }}
|
|
||||||
<!-- <el-button class="reset-button" @click="reset">重置数据</el-button> -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col :span="8">
|
|
||||||
<div class="input-group">
|
|
||||||
<label>设置金币数量</label>
|
|
||||||
<el-input type='number' v-model="pyData.gold.min" :min="0" :max="pyData.gold.max - 1"
|
|
||||||
placeholder="最小值" style="width: 100%" :disabled="!pyData.isStart">
|
|
||||||
<template #prepend>最小金币数</template>
|
|
||||||
</el-input>
|
|
||||||
<el-input type='number' v-model="pyData.gold.max" :min="pyData.gold.min + 1" :max="100"
|
|
||||||
placeholder="最大值" style="width: 100%; margin-top: 10px" :disabled="!pyData.isStart">
|
|
||||||
<template #prepend>最大金币数</template>
|
|
||||||
</el-input>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
<div class="input-group">
|
|
||||||
<label>设置粉丝数量</label>
|
|
||||||
<el-input type='number' v-model="pyData.fans.min" :min="0" :max="pyData.fans.max - 1"
|
|
||||||
placeholder="最小值" style="width: 100%" :disabled="!pyData.isStart">
|
|
||||||
<template #prepend>最小粉丝数</template>
|
|
||||||
</el-input>
|
|
||||||
<el-input type='number' v-model="pyData.fans.max" :min="pyData.fans.min + 1" :max="100"
|
|
||||||
placeholder="最大值" style="width: 100%; margin-top: 10px" :disabled="!pyData.isStart">
|
|
||||||
<template #prepend>最大粉丝数</template>
|
|
||||||
</el-input>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
<div class="input-group">
|
|
||||||
<label>后台查询频率</label>
|
|
||||||
<!-- <el-input type='number' v-model="pyData.frequency.hour" @input="handleInputHour" -->
|
|
||||||
<el-input type='number' v-model="pyData.frequency.hour" placeholder="次/小时"
|
|
||||||
style="width: 100%" :disabled="!pyData.isStart">
|
|
||||||
<template #append>次/小时</template>
|
|
||||||
</el-input>
|
|
||||||
<!-- <el-input type='number' v-model="pyData.frequency.day" @input="handleInputDay" -->
|
|
||||||
<el-input type='number' v-model="pyData.frequency.day" placeholder="次/24小时"
|
|
||||||
style="width: 100%; margin-top: 10px" :disabled="!pyData.isStart">
|
|
||||||
<template #append>次/24小时</template>
|
|
||||||
</el-input>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<div style="margin-top: 20px; text-align: center">
|
|
||||||
|
|
||||||
<el-button class="submit-button" :disabled="submitting" v-show="pyData.isStart" type="primary"
|
|
||||||
@click="submit">开始获取数据</el-button>
|
|
||||||
<el-button v-show="!pyData.isStart" type="danger" @click="unsubmit">停止获取</el-button>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, onMounted, computed } from 'vue';
|
|
||||||
import { usePythonBridge, } from '@/utils/pythonBridge'
|
|
||||||
import { setNumData, getNumData, getUser, setTkUser, getTkUser } from '@/utils/storage'
|
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
||||||
import { getCountryName } from '@/utils/countryUtil'
|
|
||||||
import { tkaccountuseinfo } from '@/api/account'
|
|
||||||
|
|
||||||
//导入python交互方法
|
|
||||||
const { fetchDataConfig, fetchDataCount, loginBackStage, loginTikTok, backStageloginStatus, backStageloginStatusCopy } = usePythonBridge();
|
|
||||||
|
|
||||||
//ip国家
|
|
||||||
let countryData = ref('');
|
|
||||||
//获取主播数量的定时器
|
|
||||||
let getHostTimer = ref(null);
|
|
||||||
//获取的主播信息
|
|
||||||
let hostData = ref({
|
|
||||||
totalCount: 0,
|
|
||||||
validAnchorsCount: 0,
|
|
||||||
canInvitationCount: 0,
|
|
||||||
checkedDataCount: 0,
|
|
||||||
});
|
|
||||||
//是否开启tk
|
|
||||||
// let isTk = ref(true);
|
|
||||||
|
|
||||||
//账号是否登陆中
|
|
||||||
let isLogin = ref([false, false]);
|
|
||||||
//设置状态轮询定时器
|
|
||||||
let statusTimer = ref(null);
|
|
||||||
let statusTimerCopy = ref(null);
|
|
||||||
|
|
||||||
//设置次数最大值
|
|
||||||
let maxCount = ref([
|
|
||||||
{
|
|
||||||
hourMax: 50,
|
|
||||||
dayMax: 300,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
hourMax: 100,
|
|
||||||
dayMax: 600,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
//tk账号信息
|
|
||||||
let tkData = ref([
|
|
||||||
{
|
|
||||||
account: '',
|
|
||||||
password: '',
|
|
||||||
index: 1,
|
|
||||||
code: 0,
|
|
||||||
num: 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
account: '',
|
|
||||||
password: '',
|
|
||||||
index: 2,
|
|
||||||
code: 0,
|
|
||||||
num: 0
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
//python需要的数据
|
|
||||||
let pyData = ref({
|
|
||||||
gold: { min: 0, max: 0 },
|
|
||||||
fans: { min: 0, max: 0 },
|
|
||||||
frequency: { hour: 0, day: 0 },
|
|
||||||
isStart: true,
|
|
||||||
country: countryData.value,
|
|
||||||
test: '123',
|
|
||||||
test1: { test: 123, test12: 123 },
|
|
||||||
tenantId: getUser().tenantId,
|
|
||||||
userId: getUser().userId,
|
|
||||||
});
|
|
||||||
|
|
||||||
//按钮提交状态
|
|
||||||
let submitting = ref(true);
|
|
||||||
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
//从缓存获取数据
|
|
||||||
if (getNumData()) {
|
|
||||||
pyData.value = getNumData();
|
|
||||||
}
|
|
||||||
if (getTkUser()) {
|
|
||||||
tkData.value = getTkUser();
|
|
||||||
tkData.value[0].code = 0;
|
|
||||||
tkData.value[1].code = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
tkaccountuse(tkData.value[0].account, 0)
|
|
||||||
tkaccountuse(tkData.value[1].account, 1)
|
|
||||||
|
|
||||||
getIpInfo()
|
|
||||||
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
const getIpInfo = async () => {
|
|
||||||
try {
|
|
||||||
const response = await fetch('https://ipapi.co/json/');
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error('请求失败');
|
|
||||||
}
|
|
||||||
const data = await response.json();
|
|
||||||
console.log('IP信息:', data.country);
|
|
||||||
|
|
||||||
countryData.value = getCountryName(data.country);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('请求出错:', error);
|
|
||||||
ElMessageBox.prompt('请输入将要获取国家的中文名', '获取国家失败', {
|
|
||||||
confirmButtonText: '确认',
|
|
||||||
cancelButtonText: '取消',
|
|
||||||
showClose: false,
|
|
||||||
closeOnClickModal: false,
|
|
||||||
showCancelButton: false,
|
|
||||||
})
|
|
||||||
.then(({ value }) => {
|
|
||||||
countryData.value = value
|
|
||||||
})
|
|
||||||
// .catch(() => {
|
|
||||||
// ElMessage({
|
|
||||||
// type: 'info',
|
|
||||||
// message: 'Input canceled',
|
|
||||||
// })
|
|
||||||
// })
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//提交数据到py
|
|
||||||
const submit = () => {
|
|
||||||
pyData.value.country = countryData.value;
|
|
||||||
console.log('提交的区间值:', pyData.value);
|
|
||||||
// if (tkData.value[0].account == '' && tkData.value[1].account == '') {
|
|
||||||
// ElMessage.error('请输入账号密码');
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// if (tkData.value[0].password == '' && tkData.value[1].password == '') {
|
|
||||||
// ElMessage.error('请输入账号密码');
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
if (((Number(pyData.value.gold.min) > Number(pyData.value.gold.max)) || (Number(pyData.value.fans.min) > Number(pyData.value.fans.max)))) {
|
|
||||||
ElMessage.error('请输入正确的区间值');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ((Number(pyData.value.gold.max) <= 0 || Number(pyData.value.fans.max <= 0)) || pyData.value.gold.max == '' || pyData.value.fans.max == '') {
|
|
||||||
ElMessage.error('请输入正确的区间值');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (Number(pyData.value.frequency.hour) <= 0 || Number(pyData.value.frequency.day) <= 0 || pyData.value.frequency.hour == '' || pyData.value.frequency.day == '') {
|
|
||||||
ElMessage.error('请输入正确的频率区间值');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ElMessageBox.confirm(
|
|
||||||
'确认开始爬取数据?',
|
|
||||||
'开始',
|
|
||||||
{
|
|
||||||
confirmButtonText: '开始',
|
|
||||||
cancelButtonText: '取消',
|
|
||||||
type: 'success',
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.then(() => {
|
|
||||||
// console.log('提交的区间值:', pyData.value.gold, pyData.value.fans, pyData.value.frequency);
|
|
||||||
//开始按钮的状态 改为禁用
|
|
||||||
submitting.value = true;
|
|
||||||
setNumData(pyData.value);
|
|
||||||
console.error('提交的区间值:', JSON.stringify(pyData.value));
|
|
||||||
|
|
||||||
fetchDataConfig(JSON.stringify({
|
|
||||||
gold: pyData.value.gold,
|
|
||||||
fans: pyData.value.fans,
|
|
||||||
frequency: pyData.value.frequency,
|
|
||||||
isStart: true,
|
|
||||||
country: countryData.value,
|
|
||||||
tenantId: getUser().tenantId,
|
|
||||||
userId: getUser().userId,
|
|
||||||
})).then((res) => {
|
|
||||||
//开始计时器
|
|
||||||
startTimer();
|
|
||||||
//开启查询次数
|
|
||||||
getHostTimer.value = setInterval(() => {
|
|
||||||
fetchDataCount().then((res) => {
|
|
||||||
hostData.value = JSON.parse(res);
|
|
||||||
tkaccountuse(tkData.value[0].account, 0)
|
|
||||||
tkaccountuse(tkData.value[1].account, 1)
|
|
||||||
})
|
|
||||||
}, 5000);
|
|
||||||
|
|
||||||
|
|
||||||
}).finally(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
pyData.value.isStart = false;
|
|
||||||
submitting.value = false;
|
|
||||||
}, 2000)
|
|
||||||
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
//停止
|
|
||||||
const unsubmit = () => {
|
|
||||||
fetchDataConfig(JSON.stringify({
|
|
||||||
gold: pyData.value.gold,
|
|
||||||
fans: pyData.value.fans,
|
|
||||||
frequency: pyData.value.frequency,
|
|
||||||
isStart: false,
|
|
||||||
country: countryData.value,
|
|
||||||
tenantId: getUser().tenantId,
|
|
||||||
userId: getUser().userId,
|
|
||||||
})).then((res) => {
|
|
||||||
pauseTimer();
|
|
||||||
pyData.value.isStart = true;
|
|
||||||
clearInterval(getHostTimer.value);
|
|
||||||
getHostTimer.value = null;
|
|
||||||
// ElMessage.sussec('已停止')
|
|
||||||
}).catch((err) => {
|
|
||||||
// ElMessage.error('停止失败')
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
//重置
|
|
||||||
const reset = () => {
|
|
||||||
pyData.value.gold = { min: 0, max: 0 };
|
|
||||||
pyData.value.fans = { min: 0, max: 0 };
|
|
||||||
pyData.value.frequency = { hour: 0, day: 0 };
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const loginTK = (index) => {
|
|
||||||
setTkUser(tkData.value)
|
|
||||||
loginBackStage({
|
|
||||||
account: tkData.value[index].account,
|
|
||||||
password: tkData.value[index].password,
|
|
||||||
index: index
|
|
||||||
})
|
|
||||||
if (index == 0) {
|
|
||||||
isLogin.value[1] = true;
|
|
||||||
statusTimer = setInterval(() => {
|
|
||||||
getloginStatus();
|
|
||||||
}, 2000)
|
|
||||||
} else if (index == 1) {
|
|
||||||
isLogin.value[0] = true;
|
|
||||||
statusTimerCopy = setInterval(() => {
|
|
||||||
getloginStatusCopy();
|
|
||||||
}, 2000)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const openTK = () => {
|
|
||||||
// isTk.value = true;
|
|
||||||
// console.log(isTk.value)
|
|
||||||
loginTikTok();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function getloginStatus() {
|
|
||||||
backStageloginStatus().then((res) => {
|
|
||||||
const data = JSON.parse(res);
|
|
||||||
tkData.value[data.index].code = data.code
|
|
||||||
|
|
||||||
if (data.code == 1) {
|
|
||||||
clearInterval(statusTimer);
|
|
||||||
statusTimer = null;
|
|
||||||
submitting.value = false
|
|
||||||
isLogin.value[1] = false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
function getloginStatusCopy() {
|
|
||||||
backStageloginStatusCopy().then((res) => {
|
|
||||||
const data = JSON.parse(res);
|
|
||||||
tkData.value[data.index].code = data.code
|
|
||||||
|
|
||||||
if (data.code == 1) {
|
|
||||||
clearInterval(statusTimer);
|
|
||||||
statusTimer = null;
|
|
||||||
submitting.value = false
|
|
||||||
isLogin.value[0] = false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function tkaccountuse(id, index) {
|
|
||||||
let num = 0;
|
|
||||||
tkaccountuseinfo(id).then((res) => {
|
|
||||||
if (res) {
|
|
||||||
num = res
|
|
||||||
tkData.value[index].num = num
|
|
||||||
console.log('账号使用次数', tkData.value[index].num)
|
|
||||||
}
|
|
||||||
}).catch((err) => {
|
|
||||||
console.log('账号使用次数', err)
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const isRunning = ref(false);
|
|
||||||
const totalSeconds = ref(0);
|
|
||||||
//定时器
|
|
||||||
let timerCrawl = null;
|
|
||||||
|
|
||||||
const startTimedata = ref(null);
|
|
||||||
//清空时间 并开始运行
|
|
||||||
const startTimer = () => {
|
|
||||||
resetTimer();
|
|
||||||
if (isRunning.value) return;
|
|
||||||
isRunning.value = true;
|
|
||||||
startTimedata.value = Date.now();
|
|
||||||
timerCrawl = setInterval(() => {
|
|
||||||
totalSeconds.value = Math.floor((Date.now() - startTimedata.value) / 1000);
|
|
||||||
}, 1000);
|
|
||||||
};
|
|
||||||
|
|
||||||
//结束运行 暂停
|
|
||||||
const pauseTimer = () => {
|
|
||||||
isRunning.value = false;
|
|
||||||
clearInterval(timerCrawl);
|
|
||||||
};
|
|
||||||
//清空时间
|
|
||||||
const resetTimer = () => {
|
|
||||||
isRunning.value = false;
|
|
||||||
clearInterval(timerCrawl);
|
|
||||||
totalSeconds.value = 0;
|
|
||||||
};
|
|
||||||
// 格式化时间为 HH:MM:SS
|
|
||||||
const formattedTime = computed(() => {
|
|
||||||
const hours = Math.floor(totalSeconds.value / 3600);
|
|
||||||
const minutes = Math.floor((totalSeconds.value % 3600) / 60);
|
|
||||||
const seconds = totalSeconds.value % 60;
|
|
||||||
|
|
||||||
return [
|
|
||||||
hours.toString().padStart(2, '0'),
|
|
||||||
minutes.toString().padStart(2, '0'),
|
|
||||||
seconds.toString().padStart(2, '0')
|
|
||||||
].join(':');
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
function handleInputHour(value) {
|
|
||||||
console.log(value)
|
|
||||||
// 替换非数字字符为空字符串
|
|
||||||
let num = value.replace(/[^\d]/g, '');
|
|
||||||
// 如果值小于等于0,则设置为0
|
|
||||||
if (Number(num) <= 0) {
|
|
||||||
num = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((tkData.value[0].code == 1) && (tkData.value[1].code == 1)) {
|
|
||||||
if (Number(num) > maxCount.value[1].hourMax) {
|
|
||||||
num = maxCount.value[1].hourMax;
|
|
||||||
}
|
|
||||||
} else if ((tkData.value[0].code == 1) || (tkData.value[1].code == 1)) {
|
|
||||||
// 如果值大于最大值,则设置为最大值
|
|
||||||
if (Number(num) > maxCount.value[0].hourMax) {
|
|
||||||
num = maxCount.value[0].hourMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
ElMessage.error('请先登录tk后台');
|
|
||||||
num = 0;
|
|
||||||
}
|
|
||||||
// 更新模型
|
|
||||||
pyData.value.frequency.hour = num;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleInputDay(value) {
|
|
||||||
console.log(value)
|
|
||||||
// 替换非数字字符为空字符串
|
|
||||||
let num = value.replace(/[^\d]/g, '');
|
|
||||||
// 如果值小于等于0,则设置为0
|
|
||||||
if (Number(num) <= 0) {
|
|
||||||
num = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((tkData.value[0].code == 1) && (tkData.value[1].code == 1)) {
|
|
||||||
if (Number(num) > maxCount.value[1].dayMax) {
|
|
||||||
num = maxCount.value[1].dayMax;
|
|
||||||
}
|
|
||||||
} else if ((tkData.value[0].code == 1) || (tkData.value[1].code == 1)) {
|
|
||||||
// 如果值大于最大值,则设置为最大值
|
|
||||||
if (Number(num) > maxCount.value[0].dayMax) {
|
|
||||||
num = maxCount.value[0].dayMax;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ElMessage.error('请先登录tk后台');
|
|
||||||
num = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 更新模型
|
|
||||||
pyData.value.frequency.day = num;
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="less">
|
|
||||||
.container {
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workbenches {
|
|
||||||
padding: 45px 29px 22px 27px;
|
|
||||||
|
|
||||||
/* 页面无法选中 */
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-ms-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.box-card {
|
|
||||||
// width: 1240px;
|
|
||||||
height: 436px;
|
|
||||||
background: #FFFFFF;
|
|
||||||
box-shadow: 0px 0px 21px 0px rgba(183, 183, 183, 0.33);
|
|
||||||
border-radius: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.box-card-num1 {
|
|
||||||
|
|
||||||
width: 197px;
|
|
||||||
height: 321px;
|
|
||||||
background: #FFFFFF;
|
|
||||||
box-shadow: 0px 0px 21px 0px rgba(183, 183, 183, 0.33);
|
|
||||||
border-radius: 24px;
|
|
||||||
// padding-top: 60px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
div {
|
|
||||||
height: 20%;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-around;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
color: #8D8E8E;
|
|
||||||
|
|
||||||
span {
|
|
||||||
color: #000;
|
|
||||||
padding-left: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.box-card-num {
|
|
||||||
width: 897px;
|
|
||||||
height: 145px;
|
|
||||||
background: #FFFFFF;
|
|
||||||
box-shadow: 0px 0px 21px 0px rgba(183, 183, 183, 0.33);
|
|
||||||
border-radius: 24px;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
|
|
||||||
padding-top: 18px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
.todayCount {
|
|
||||||
padding: 15px 21px;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.from-input-item {
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
.from-input-item-title {
|
|
||||||
color: #000000;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 500;
|
|
||||||
width: 100px;
|
|
||||||
height: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loginButton {
|
|
||||||
width: 100%;
|
|
||||||
height: 40px;
|
|
||||||
color: #ffffff;
|
|
||||||
font-size: 16px;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.loginState {
|
|
||||||
width: 15px;
|
|
||||||
height: 15px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background-color: #b90000;
|
|
||||||
margin-left: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
span {
|
|
||||||
font-family: Source Han Sans SC;
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 20px;
|
|
||||||
color: #2D2727;
|
|
||||||
line-height: 37px;
|
|
||||||
|
|
||||||
img {
|
|
||||||
margin-right: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-group {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
|
|
||||||
.el-input {
|
|
||||||
margin: 22px 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #606266;
|
|
||||||
}
|
|
||||||
|
|
||||||
.open-login {
|
|
||||||
width: 100px;
|
|
||||||
height: 47px;
|
|
||||||
background: @btn-bg-color;
|
|
||||||
border-radius: 10px;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.reset-button {
|
|
||||||
width: 132px;
|
|
||||||
height: 47px;
|
|
||||||
background: @btn-bg-color;
|
|
||||||
border-radius: 10px;
|
|
||||||
|
|
||||||
font-family: Source Han Sans SC;
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 18px;
|
|
||||||
color: #FFFFFF;
|
|
||||||
|
|
||||||
margin-left: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.submit-button {
|
|
||||||
width: 160px;
|
|
||||||
height: 47px;
|
|
||||||
background: @bg-color;
|
|
||||||
border-radius: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.center-line {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
// justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.center-justify {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-around;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.center-align {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.center-flex {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
||||||
<style scoped lang="less">
|
|
||||||
::v-deep(.el-input-group__prepend) {
|
|
||||||
background: @bg-color-light;
|
|
||||||
border-radius: 10px 0px 0px 10px;
|
|
||||||
border: 1px solid #B7CEC5;
|
|
||||||
font-family: Source Han Sans SC;
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 18px;
|
|
||||||
color: #FFFFFF;
|
|
||||||
line-height: 37px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep(.el-input-group__append) {
|
|
||||||
background: @bg-color-light;
|
|
||||||
border-radius: 0px 10px 10px 0px;
|
|
||||||
border: 1px solid #B7CEC5;
|
|
||||||
font-family: Source Han Sans SC;
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 18px;
|
|
||||||
color: #FFFFFF;
|
|
||||||
line-height: 37px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep(.el-input__wrapper) {
|
|
||||||
width: 218px;
|
|
||||||
height: 44px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-input {
|
|
||||||
width: 200px;
|
|
||||||
height: 48px;
|
|
||||||
background: #FFFFFF;
|
|
||||||
border-radius: 10px;
|
|
||||||
border: 1px solid #B7CEC5;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,40 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="common-layout">
|
||||||
<!-- <Sidebar class="noneText" @activeIndex="activeIndexFn" /> -->
|
<el-container>
|
||||||
<div class="content ">
|
<!-- 左侧导航栏 -->
|
||||||
<!-- <div v-show="activeIndexA == 1">
|
<el-aside class="nav-aside">
|
||||||
<workbenches />
|
<Appaside></Appaside>
|
||||||
</div> -->
|
</el-aside>
|
||||||
<div>
|
<!-- 右侧主体内容 -->
|
||||||
<hostsList />
|
<el-main class="nav-main">
|
||||||
</div>
|
<router-view />
|
||||||
<!-- <div style="position: absolute; bottom: 0; right: 0;">{{ version }}</div> -->
|
</el-main>
|
||||||
|
</el-container>
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
// import Sidebar from '../components/Sidebar.vue';
|
import Appaside from "/src/components/Appaside.vue";
|
||||||
import { RouterLink, RouterView } from 'vue-router'
|
|
||||||
import hostsList from '@/views/hosts/hostsList.vue'
|
|
||||||
// import workbenches from '@/views/hosts/workbenches.vue'
|
|
||||||
import { ref } from 'vue'
|
|
||||||
import { getUser } from '@/utils/storage'
|
|
||||||
// import { usePythonBridge } from '@/utils/pythonBridge'
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// let activeIndexA = ref(1)
|
|
||||||
|
|
||||||
// function activeIndexFn(data) {
|
|
||||||
// activeIndexA.value = data
|
|
||||||
// console.log(data)
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@@ -44,48 +24,22 @@ body,
|
|||||||
html {
|
html {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
height: 100%;
|
height: 100vh;
|
||||||
|
width: 100vw;
|
||||||
}
|
}
|
||||||
|
.common-layout {
|
||||||
.app-container {
|
width: 100vw;
|
||||||
display: flex;
|
height: 100vh;
|
||||||
width: 1600px;
|
|
||||||
height: 900px;
|
|
||||||
background-color: @bg-color;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
.nav-main {
|
||||||
.noneText {
|
width: 95vw;
|
||||||
/* 页面无法选中 */
|
height: 100vh;
|
||||||
-webkit-user-select: none;
|
background-color:@bg-color;
|
||||||
-moz-user-select: none;
|
|
||||||
-ms-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
}
|
}
|
||||||
|
.nav-aside {
|
||||||
.sidebar {
|
width: 5vw;
|
||||||
width: 200px;
|
height: 100vh;
|
||||||
background-color: @bg-color;
|
background-image: linear-gradient(0deg, @bg-Sidebar-color-top, @bg-color);
|
||||||
padding: 20px;
|
border: 2px solid @border-color;
|
||||||
/* box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1); */
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
// margin-left: 280px;
|
|
||||||
margin-left: 25px;
|
|
||||||
margin-right: 25px;
|
|
||||||
width: 1540px;
|
|
||||||
height: 868px;
|
|
||||||
background: #FFFFFF;
|
|
||||||
border-radius: 36px;
|
|
||||||
margin-top: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.center-justify {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-around;
|
|
||||||
align-items: center;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||