Compare commits
10 Commits
05cad57358
...
ec8bffa6f0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ec8bffa6f0 | ||
| 560581f1a4 | |||
| 17d2251a70 | |||
| dcd677bbab | |||
| 60f6fc4873 | |||
| 5e34aaf402 | |||
| c5fb3ea0b2 | |||
| 666e27246f | |||
| 91ee2dd7cb | |||
| 7df29e741c |
BIN
YOLO工具箱.zip
Normal file
121
package-lock.json
generated
@@ -23,12 +23,14 @@
|
||||
"@vue/cli-plugin-router": "~5.0.0",
|
||||
"@vue/cli-plugin-vuex": "~5.0.0",
|
||||
"@vue/cli-service": "~5.0.0",
|
||||
"file-loader": "^6.2.0",
|
||||
"less": "^4.2.2",
|
||||
"less-loader": "^12.2.0",
|
||||
"postcss-preset-env": "^10.1.5",
|
||||
"postcss-px-to-viewport": "^1.1.1",
|
||||
"postcss-px-viewport": "^0.0.4",
|
||||
"postcss-viewport-units": "^0.1.6"
|
||||
"postcss-viewport-units": "^0.1.6",
|
||||
"url-loader": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@achrinza/node-ipc": {
|
||||
@@ -7018,6 +7020,61 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/file-loader": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz",
|
||||
"integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"loader-utils": "^2.0.0",
|
||||
"schema-utils": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.13.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/webpack"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"webpack": "^4.0.0 || ^5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/file-loader/node_modules/loader-utils": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
|
||||
"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"big.js": "^5.2.2",
|
||||
"emojis-list": "^3.0.0",
|
||||
"json5": "^2.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/file-loader/node_modules/schema-utils": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
|
||||
"integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/json-schema": "^7.0.8",
|
||||
"ajv": "^6.12.5",
|
||||
"ajv-keywords": "^3.5.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.13.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/webpack"
|
||||
}
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
@@ -13209,6 +13266,68 @@
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/url-loader": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz",
|
||||
"integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"loader-utils": "^2.0.0",
|
||||
"mime-types": "^2.1.27",
|
||||
"schema-utils": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.13.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/webpack"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"file-loader": "*",
|
||||
"webpack": "^4.0.0 || ^5.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"file-loader": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/url-loader/node_modules/loader-utils": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
|
||||
"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"big.js": "^5.2.2",
|
||||
"emojis-list": "^3.0.0",
|
||||
"json5": "^2.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/url-loader/node_modules/schema-utils": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
|
||||
"integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/json-schema": "^7.0.8",
|
||||
"ajv": "^6.12.5",
|
||||
"ajv-keywords": "^3.5.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.13.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/webpack"
|
||||
}
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
|
||||
@@ -22,12 +22,14 @@
|
||||
"@vue/cli-plugin-router": "~5.0.0",
|
||||
"@vue/cli-plugin-vuex": "~5.0.0",
|
||||
"@vue/cli-service": "~5.0.0",
|
||||
"file-loader": "^6.2.0",
|
||||
"less": "^4.2.2",
|
||||
"less-loader": "^12.2.0",
|
||||
"postcss-preset-env": "^10.1.5",
|
||||
"postcss-px-to-viewport": "^1.1.1",
|
||||
"postcss-px-viewport": "^0.0.4",
|
||||
"postcss-viewport-units": "^0.1.6"
|
||||
"postcss-viewport-units": "^0.1.6",
|
||||
"url-loader": "^4.1.1"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
|
||||
@@ -24,4 +24,10 @@ window.ResizeObserver = class ResizeObserver extends _ResizeObserver {
|
||||
super(callback)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
||||
<!-- <style lang="less">
|
||||
/*每个页面公共css */
|
||||
|
||||
@import "@/static/css/app.less";
|
||||
</style> -->
|
||||
@@ -1,17 +1,71 @@
|
||||
import { getAxios, postAxios, downFile } from '@/utils/axios.js'
|
||||
|
||||
export function apiGetCart() {
|
||||
return getAxios({ url: '/cgi-bin/cart/latest' })
|
||||
}
|
||||
//登录
|
||||
export function login(data) {
|
||||
return postAxios({ url: 'api/account/login', data })
|
||||
return postAxios({ url: 'api/user/doLogin', data })
|
||||
}
|
||||
|
||||
//ai
|
||||
//获取所有话术列表
|
||||
export function getDialogList(data) {
|
||||
return postAxios({ url: 'ai/templateList', data })
|
||||
}
|
||||
//获取所有语言列表
|
||||
export function getLanguageList(data) {
|
||||
return postAxios({ url: 'ai/languageList', data })
|
||||
}
|
||||
//添加话术
|
||||
export function addDialog(data) {
|
||||
return postAxios({ url: 'ai/addTemplate', data })
|
||||
}
|
||||
//编辑话术
|
||||
export function editDialog(data) {
|
||||
return postAxios({ url: 'ai/editTemplate', data })
|
||||
}
|
||||
//删除话术
|
||||
export function deleteDialog(data) {
|
||||
return postAxios({ url: 'ai/deleteTemplate', data })
|
||||
}
|
||||
//删除语言
|
||||
export function deleteLanguage(data) {
|
||||
return postAxios({ url: 'ai/deleteLanguage', data })
|
||||
}
|
||||
//编辑语言
|
||||
export function editLanguage(data) {
|
||||
return postAxios({ url: 'ai/updateLanguage', data })
|
||||
}
|
||||
//添加语言
|
||||
export function addLanguage(data) {
|
||||
return postAxios({ url: 'ai/addLanguage', data })
|
||||
}
|
||||
|
||||
|
||||
//小程序
|
||||
//获取配置列表
|
||||
export function getWxConfigList(data) {
|
||||
return postAxios({ url: 'pk/configList', data })
|
||||
}
|
||||
//添加配置
|
||||
export function addWxConfig(data) {
|
||||
return postAxios({ url: 'pk/addNewConfig', data })
|
||||
}
|
||||
//编辑配置
|
||||
export function editWxConfig(data) {
|
||||
return postAxios({ url: 'pk/updateConfig', data })
|
||||
}
|
||||
//删除配置
|
||||
export function deleteWxConfig(data) {
|
||||
return postAxios({ url: 'pk/deleteConfig', data })
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export function cheekalive(data) {
|
||||
return postAxios({ url: 'api/account/cheekalive', data })
|
||||
}
|
||||
export function tkhostdata(data) {
|
||||
return postAxios({ url: 'api/tkinfo/tkhostdata', data })
|
||||
}
|
||||
|
||||
export function dicts(data) {
|
||||
return postAxios({ url: 'api/param/dicts', data })
|
||||
}
|
||||
@@ -25,10 +79,7 @@ export function exporthosts(data) {
|
||||
export function downList(url, data) {
|
||||
return downFile(url, data)
|
||||
}
|
||||
//查询tk账号查询次数
|
||||
export function tkaccountuseinfo(data) {
|
||||
return postAxios({ url: 'api/tkinfo/tkaccountuseinfo', data })
|
||||
}
|
||||
|
||||
//查询员工
|
||||
export function getStaffList(data) {
|
||||
return postAxios({ url: 'api/account/list', data })
|
||||
@@ -41,7 +92,9 @@ export function managerhosts(data) {
|
||||
export function upholdinfo(data) {
|
||||
return postAxios({ url: 'api/tkinfo/upholdinfo', data })
|
||||
}
|
||||
//获取
|
||||
export function getCountryinfo(data) {
|
||||
return postAxios({ url: 'api/tkinfo/countryinfo', data })
|
||||
|
||||
//查看名字
|
||||
export function accountName(str) {
|
||||
return postAxios({ url: 'api/account/accountName?accounts=' + str })
|
||||
}
|
||||
|
||||
|
||||
BIN
src/assets/MiniProgram.png
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
BIN
src/assets/ai.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
src/assets/icon.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 88 KiB |
BIN
src/assets/logo1.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 2.1 MiB After Width: | Height: | Size: 1.3 MiB |
BIN
src/assets/logoBg1.png
Normal file
|
After Width: | Height: | Size: 2.1 MiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 106 KiB |
BIN
src/assets/logotext1.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
src/assets/logotext12.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
BIN
src/assets/plus.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
src/assets/plus2.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 993 B |
@@ -38,6 +38,8 @@ export default {
|
||||
|
||||
this.inputTime = this.time
|
||||
this.getTkhostdetail();
|
||||
console.log(this.time)
|
||||
|
||||
console.log(this.getPrevious7Days(this.inputTime))
|
||||
|
||||
},
|
||||
@@ -93,16 +95,6 @@ export default {
|
||||
res[0][this.getPrevious7Days(this.inputTime)[6]] == null ? 0 : Number(res[0][this.getPrevious7Days(this.inputTime)[6]][this.dataType]),
|
||||
]
|
||||
|
||||
// this.seriesData = {
|
||||
// [this.getPrevious7Days(this.inputTime)[0]]: res[0][this.getPrevious7Days(this.inputTime)[0]] == null ? 0 : res[0][this.getPrevious7Days(this.inputTime)[0]][this.dataType],
|
||||
// [this.getPrevious7Days(this.inputTime)[1]]: res[0][this.getPrevious7Days(this.inputTime)[1]] == null ? 0 : res[0][this.getPrevious7Days(this.inputTime)[1]][this.dataType],
|
||||
// [this.getPrevious7Days(this.inputTime)[2]]: res[0][this.getPrevious7Days(this.inputTime)[2]] == null ? 0 : res[0][this.getPrevious7Days(this.inputTime)[2]][this.dataType],
|
||||
// [this.getPrevious7Days(this.inputTime)[3]]: res[0][this.getPrevious7Days(this.inputTime)[3]] == null ? 0 : res[0][this.getPrevious7Days(this.inputTime)[3]][this.dataType],
|
||||
// [this.getPrevious7Days(this.inputTime)[4]]: res[0][this.getPrevious7Days(this.inputTime)[4]] == null ? 0 : res[0][this.getPrevious7Days(this.inputTime)[4]][this.dataType],
|
||||
// [this.getPrevious7Days(this.inputTime)[5]]: res[0][this.getPrevious7Days(this.inputTime)[5]] == null ? 0 : res[0][this.getPrevious7Days(this.inputTime)[5]][this.dataType],
|
||||
// [this.getPrevious7Days(this.inputTime)[6]]: res[0][this.getPrevious7Days(this.inputTime)[6]] == null ? 0 : res[0][this.getPrevious7Days(this.inputTime)[6]][this.dataType],
|
||||
// }
|
||||
|
||||
this.initChart();
|
||||
this.num++
|
||||
console.log("返回数据", this.seriesData)
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
<template>
|
||||
<div class="sidebar">
|
||||
<div class="logo">
|
||||
<!-- <div class="logo">
|
||||
<img style="margin-right: 10px;" src="@/assets/logo.png">
|
||||
<img src="@/assets/logotext.png">
|
||||
</div>
|
||||
</div> -->
|
||||
<ul>
|
||||
<li @click="updateActiveIndex(1)" v-show="userInfo.userType == 3">
|
||||
<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>
|
||||
<img v-show="activeIndex == 1" src="@/assets/ai.png" style="margin-right: 10px;width: 24px;height: 24px;">
|
||||
<img v-show="activeIndex == 2" src="@/assets/ai.png" style="margin-right: 10px;width: 24px;height: 24px;">
|
||||
<div :style="activeIndex == 1 ? 'color: #000' : 'color: #fff'" class="center-justify">Ai后台管理</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -21,9 +21,9 @@
|
||||
<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>
|
||||
<img v-show="activeIndex == 2" src="@/assets/MiniProgram.png" style="margin-right: 10px;width: 30px;height: 30px;">
|
||||
<img v-show="activeIndex == 1" src="@/assets/MiniProgram.png" style="margin-right: 10px;width: 30px;height: 30px;">
|
||||
<div :style="activeIndex == 2 ? 'color: #000' : 'color: #fff'" class="center-justify">小程序后台管理</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -45,11 +45,13 @@ import { ref, reactive, onMounted } from 'vue';
|
||||
import { getUser } from '@/utils/storage'
|
||||
import { defineEmits } from 'vue';
|
||||
|
||||
|
||||
|
||||
const userInfo = ref(getUser())
|
||||
|
||||
let activeIndex = ref(userInfo.value.userType == 3 ? 1 : 2);
|
||||
let activeIndex = ref(1);
|
||||
|
||||
const emit = defineEmits(['update:activeIndex']);
|
||||
const emit = defineEmits(['activeIndex']);
|
||||
|
||||
|
||||
const updateActiveIndex = (index) => {
|
||||
@@ -58,23 +60,23 @@ const updateActiveIndex = (index) => {
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style scoped lang="less">
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 900px;
|
||||
width: 280px;
|
||||
background-color: #338F6A;
|
||||
background-color: @bg-color;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.logo {
|
||||
border-bottom: 1px solid #fff;
|
||||
padding-bottom: 29px;
|
||||
padding-top: 20px;
|
||||
|
||||
img:nth-of-type(1) {
|
||||
height: 40px;
|
||||
height: 66px;
|
||||
}
|
||||
|
||||
img:nth-of-type(2) {
|
||||
|
||||
@@ -5,11 +5,15 @@ import store from './store'
|
||||
import { createPinia } from 'pinia';
|
||||
import ElementPlus from 'element-plus'
|
||||
import 'element-plus/dist/index.css'
|
||||
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'; // 引入中文语言包
|
||||
|
||||
// createApp(App).use(store).use(router).mount('#app')
|
||||
|
||||
|
||||
const app = createApp(App);
|
||||
app.use(ElementPlus, {
|
||||
locale: zhCn, // 配置中文
|
||||
});
|
||||
app.use(ElementPlus) // 注册 ElementPlus
|
||||
app.use(createPinia()); // 注册 Pinia
|
||||
app.use(store); // 注册 store
|
||||
|
||||
@@ -11,19 +11,35 @@ const routes = [
|
||||
{
|
||||
path: '/nav',
|
||||
name: 'nav',
|
||||
// redirect: '/nav/hostsList', // 默认跳转
|
||||
redirect: '/nav/Home', // 默认跳转
|
||||
component: () => import(/* webpackChunkName: "hostsList" */ '../views/nav.vue'),
|
||||
children: [
|
||||
{
|
||||
path: 'hostsList',
|
||||
name: 'hostsList',
|
||||
component: () => import(/* webpackChunkName: "hostsList" */ '../views/hosts/hostsList.vue')
|
||||
path: 'Home',
|
||||
name: 'Home',
|
||||
component: () => import(/* webpackChunkName: "hostsList" */ '../views/hosts/Home.vue'),
|
||||
},
|
||||
{
|
||||
path: 'workBenches',
|
||||
name: 'workBenches',
|
||||
component: () => import(/* webpackChunkName: "hostsList" */ '../views/hosts/workbenches.vue')
|
||||
},]
|
||||
path: 'scriptManagement',
|
||||
name: 'scriptManagement',
|
||||
component: () => import(/* webpackChunkName: "hostsList" */ '../views/hosts/ai/scriptManagement.vue'),
|
||||
},
|
||||
{
|
||||
path: 'LanguageManagement',
|
||||
name: 'LanguageManagement',
|
||||
component: () => import(/* webpackChunkName: "hostsList" */ '../views/hosts/ai/LanguageManagement.vue'),
|
||||
},
|
||||
{
|
||||
path: 'miniAM',
|
||||
name: 'miniAM',
|
||||
component: () => import(/* webpackChunkName: "hostsList" */ '../views/hosts/mini/miniAM.vue'),
|
||||
},
|
||||
{
|
||||
path: 'miniIntegral',
|
||||
name: 'miniIntegral',
|
||||
component: () => import(/* webpackChunkName: "hostsList" */ '../views/hosts/mini/miniIntegral.vue'),
|
||||
},
|
||||
]
|
||||
}
|
||||
]
|
||||
const router = createRouter({
|
||||
|
||||
4
src/static/css/app.less
Normal file
@@ -0,0 +1,4 @@
|
||||
@bg-color: #022b4e; // 主色
|
||||
@bg-color-light: #022b4eaf; // 浅主色
|
||||
@bg-color-light-light: #022b4e1c; // 浅浅主色
|
||||
@btn-bg-color: #045dac; // 黄色按钮主色
|
||||
@@ -4,33 +4,43 @@
|
||||
*/
|
||||
import axios from 'axios'
|
||||
import { getToken, getUser } from '@/utils/storage'
|
||||
import { useRouter } from 'vue-router';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import router from '@/router'
|
||||
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { usePythonBridge, } from '@/utils/pythonBridge'
|
||||
|
||||
const { stopScript } = usePythonBridge();
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
// 请求地址前缀
|
||||
let baseURL = ''
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
// 生产环境
|
||||
baseURL = "http://120.26.251.180:8085/"
|
||||
// baseURL = "http://192.168.0.115:8085/"
|
||||
// baseURL = "https://api.tkpage.yolozs.com"
|
||||
baseURL = "http://49.235.115.212:12025/"
|
||||
// baseURL = "http://192.168.0.103:8085/"
|
||||
} else {
|
||||
// 测试环境
|
||||
// baseURL = "http://120.26.251.180:8085/"
|
||||
// 开发环境
|
||||
baseURL = "http://120.26.251.180:8085/"
|
||||
baseURL = "http://49.235.115.212:12025/"
|
||||
// baseURL = "http://api.tkpage.vvtiktok.cn"
|
||||
}
|
||||
|
||||
// 请求拦截器
|
||||
axios.interceptors.request.use((config) => {
|
||||
// if (getToken()) {
|
||||
// config.headers['token'] = getToken();
|
||||
console.log("config", config)
|
||||
const url = sliceUrl(config.url)
|
||||
console.log("url", url)
|
||||
// if (!(config.url == 'templateList' || config.url == 'languageList')) {
|
||||
// config.headers['vvtoken'] = getToken();
|
||||
// }
|
||||
|
||||
// 请求超时时间 - 毫秒
|
||||
config.timeout = 60000
|
||||
config.baseURL = baseURL
|
||||
// 自定义Content-type
|
||||
config.headers['Content-type'] = 'application/json'
|
||||
// config.headers['Content-type'] = 'application/json'
|
||||
return config;
|
||||
}, (error) => {
|
||||
return Promise.reject(error)
|
||||
@@ -38,7 +48,15 @@ axios.interceptors.request.use((config) => {
|
||||
|
||||
// 响应拦截器
|
||||
axios.interceptors.response.use((response) => {
|
||||
return response
|
||||
console.log("```````````````response```````````````````", response.data)
|
||||
if (response.data.code == '200') {
|
||||
console.log("response", response.data.data)
|
||||
return response.data.data
|
||||
} else {
|
||||
router.push('/')
|
||||
ElMessage.error(response.data.code + '' + response.data.message);
|
||||
}
|
||||
|
||||
}, (error) => {
|
||||
// 可添加请求失败后的处理逻辑
|
||||
return Promise.reject(error)
|
||||
@@ -54,10 +72,9 @@ export function getAxios({ url, params }) {
|
||||
params
|
||||
// 请求成功,将返回的数据传递给resolve函数
|
||||
}).then(res => {
|
||||
resolve(res.data)
|
||||
resolve(res)
|
||||
// 请求失败,将错误信息传递给reject函数
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
@@ -65,37 +82,17 @@ export function getAxios({ url, params }) {
|
||||
|
||||
// axios的post请求
|
||||
export function postAxios({ url, data }) {
|
||||
if (url != 'api/account/login') {
|
||||
|
||||
throttledCheekalive();
|
||||
|
||||
}
|
||||
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
console.log("```````````````data```````````````", data);
|
||||
console.log("````````````````url````````````````", url);
|
||||
|
||||
axios.post(
|
||||
url,
|
||||
data,
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
}
|
||||
).then(res => {
|
||||
resolve(res.data)
|
||||
resolve(res)
|
||||
}).catch(err => {
|
||||
if (err.message == "Network Error") {
|
||||
// alert("网络错误,请检查网络连接")
|
||||
ElMessage.error('网络连接错误');
|
||||
reject('网络连接错误')
|
||||
|
||||
} else {
|
||||
ElMessage.error(err.message);
|
||||
reject(err.message)
|
||||
|
||||
}
|
||||
// console.log(err)
|
||||
// reject(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -146,6 +143,7 @@ function cheekalive() {
|
||||
if (res.data) {
|
||||
|
||||
} else {
|
||||
stopScript();
|
||||
alert("账号在其他地方登录!")
|
||||
window.location.href = '/';
|
||||
}
|
||||
@@ -167,6 +165,18 @@ function throttle(func, limit) {
|
||||
}
|
||||
}
|
||||
|
||||
const throttledCheekalive = throttle(cheekalive, 5000);
|
||||
function sliceUrl(url) {
|
||||
const lastSlash = url.lastIndexOf('/');
|
||||
const questionMark = url.indexOf('?');
|
||||
if (questionMark == -1) {
|
||||
const result = url.slice(lastSlash + 1, url.length);
|
||||
return result;
|
||||
} else {
|
||||
const result = url.slice(lastSlash + 1, questionMark);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default axios
|
||||
@@ -99,8 +99,23 @@ export function usePythonBridge() {
|
||||
}
|
||||
|
||||
};
|
||||
const stopScript = () => {
|
||||
if (bridge.value) {
|
||||
bridge.value.stopScript();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//获取版本号
|
||||
const getVersion = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (bridge.value) {
|
||||
bridge.value.currentVersion(function (result) {
|
||||
resolve(result);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
// 在组件挂载时初始化桥接
|
||||
onMounted(initBridge);
|
||||
|
||||
@@ -112,6 +127,8 @@ export function usePythonBridge() {
|
||||
givePyAnchorId,
|
||||
backStageloginStatus,
|
||||
backStageloginStatusCopy,
|
||||
exportToExcel
|
||||
exportToExcel,
|
||||
stopScript,
|
||||
getVersion
|
||||
};
|
||||
}
|
||||
@@ -42,4 +42,13 @@ export function setTkUser(userdata) {
|
||||
// 用于获取tk账户密码
|
||||
export function getTkUser() {
|
||||
return JSON.parse(localStorage.getItem('tkuser'));
|
||||
}
|
||||
|
||||
// 用于列表筛选条件
|
||||
export function setSerch(data) {
|
||||
localStorage.setItem('Serch', JSON.stringify(data));
|
||||
}
|
||||
// 用于获取列表筛选条件
|
||||
export function getSerch() {
|
||||
return JSON.parse(localStorage.getItem('Serch'));
|
||||
}
|
||||
@@ -25,8 +25,8 @@
|
||||
<!-- logo -->
|
||||
<div class="logo">
|
||||
<div class="center-justify" style="height: 80px; width: 300px;">
|
||||
<img style="margin-right: 20px;" src="@/assets/logo.png">
|
||||
<img src="@/assets/logotext.png">
|
||||
<!-- <img style="margin-right: 20px;height: 100%;" src="@/assets/logo.png">
|
||||
<img style="height: 100%;" src="@/assets/logotext.png"> -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
|
||||
<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.userId" placeholder="账号" clearable
|
||||
@@ -53,12 +52,16 @@
|
||||
<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>
|
||||
@@ -66,18 +69,34 @@
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { login } from '@/api/account';
|
||||
import { login, getIdByName } from '@/api/account';
|
||||
import { getToken, setToken, setUser, setUserPass, getUserPass } from '@/utils/storage';
|
||||
import { ElLoading } from 'element-plus';
|
||||
import { usePythonBridge } from '@/utils/pythonBridge'
|
||||
|
||||
|
||||
// const { getVersion } = usePythonBridge();
|
||||
// let version = ref('0.0.0');
|
||||
// onMounted(() => {
|
||||
// setTimeout(() => {
|
||||
// getVersion().then((res) => {
|
||||
// version.value = res;
|
||||
// })
|
||||
// }, 500);
|
||||
|
||||
// })
|
||||
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const formData = ref({
|
||||
// tenantName: getUserPass() == null ? '' : getUserPass().tenantName,
|
||||
userId: getUserPass() == null ? '' : getUserPass().userId,
|
||||
password: getUserPass() == null ? '' : getUserPass().password,
|
||||
});
|
||||
|
||||
|
||||
|
||||
const onSubmit = () => {
|
||||
const loading = ElLoading.service({
|
||||
lock: true,
|
||||
@@ -85,28 +104,24 @@ const onSubmit = () => {
|
||||
background: 'rgba(0, 0, 0, 0.7)',
|
||||
});
|
||||
setUserPass(formData.value);
|
||||
login({
|
||||
userId: formData.value.userId,
|
||||
password: formData.value.password,
|
||||
}).then((res) => {
|
||||
loading.close();
|
||||
console.log(res)
|
||||
if (res) {
|
||||
if (res.activeYn == 'Y') {
|
||||
setToken(res.currcode);
|
||||
setUser(res);
|
||||
router.push('/nav');
|
||||
} else {
|
||||
alert('账号未启用');
|
||||
}
|
||||
getIdByName(formData.value.tenantName).then((tenantId) => {
|
||||
console.log(tenantId)
|
||||
login({
|
||||
// tenantId: Number(tenantId),
|
||||
username: formData.value.userId,
|
||||
password: formData.value.password,
|
||||
}).then((res) => {
|
||||
loading.close();
|
||||
console.log(res)
|
||||
setToken(res.tokenValue);
|
||||
setUser(res);
|
||||
router.push('/nav');
|
||||
}).catch((err) => {
|
||||
loading.close();
|
||||
});
|
||||
})
|
||||
|
||||
} else {
|
||||
alert('账号或密码错误');
|
||||
}
|
||||
|
||||
}).catch((err) => {
|
||||
loading.close();
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -141,6 +156,18 @@ const onSubmit = () => {
|
||||
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;
|
||||
@@ -175,8 +202,8 @@ const onSubmit = () => {
|
||||
|
||||
.from {
|
||||
width: 420px;
|
||||
height: 320px;
|
||||
color: #107A4E;
|
||||
// height: 320px;
|
||||
color: @bg-color;
|
||||
background-color: #ffffff44;
|
||||
border-radius: 20px;
|
||||
border: 1px solid #fff;
|
||||
@@ -187,7 +214,7 @@ const onSubmit = () => {
|
||||
font-family: Source Han Sans SC;
|
||||
font-weight: 500;
|
||||
font-size: 24px;
|
||||
color: #107A4E;
|
||||
color: @bg-color;
|
||||
line-height: 37px;
|
||||
|
||||
|
||||
@@ -207,7 +234,7 @@ const onSubmit = () => {
|
||||
padding: 8px 0;
|
||||
|
||||
.from-input-item-title {
|
||||
color: #107A4E;
|
||||
color: @bg-color;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
width: 80px;
|
||||
@@ -225,7 +252,7 @@ const onSubmit = () => {
|
||||
font-family: Source Han Sans SC;
|
||||
font-weight: 500;
|
||||
font-size: 18px;
|
||||
color: #107A4E;
|
||||
color: @bg-color;
|
||||
line-height: 37px;
|
||||
}
|
||||
}
|
||||
@@ -234,7 +261,7 @@ const onSubmit = () => {
|
||||
display: flex;
|
||||
width: 359px;
|
||||
height: 50px;
|
||||
background: rgba(147, 174, 158, 0.37);
|
||||
background: @bg-color-light-light;
|
||||
border-radius: 24px;
|
||||
border: 1px solid #FFFFFF;
|
||||
padding: 12px 25px 13px 25px;
|
||||
@@ -277,7 +304,7 @@ const onSubmit = () => {
|
||||
}
|
||||
</style>
|
||||
|
||||
<style scoped>
|
||||
<style scoped lang="less">
|
||||
::v-deep(.el-input__wrapper) {
|
||||
background-color: rgba(255, 0, 0, 0);
|
||||
box-shadow: none;
|
||||
@@ -285,11 +312,11 @@ const onSubmit = () => {
|
||||
}
|
||||
|
||||
::v-deep(.el-input__inner) {
|
||||
color: #107A4E;
|
||||
color: #fff;
|
||||
|
||||
}
|
||||
|
||||
::v-deep(.el-input__inner::placeholder) {
|
||||
color: #107A4E;
|
||||
color: @bg-color;
|
||||
}
|
||||
</style>
|
||||
38
src/views/hosts/Home.vue
Normal file
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<div class="home">
|
||||
|
||||
|
||||
</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>
|
||||
.home {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #ffffff;
|
||||
border-radius: 10px;
|
||||
}
|
||||
</style>
|
||||
279
src/views/hosts/ai/LanguageManagement.vue
Normal file
@@ -0,0 +1,279 @@
|
||||
<template>
|
||||
<div class="language-management">
|
||||
<div class="content">
|
||||
<div class="languagetitle">
|
||||
<div class="title">语言管理</div>
|
||||
|
||||
<div class="add" @click="dialogVisible = true">
|
||||
<img class="add-img" src="@/assets/plus2.png" alt="" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- 语言列表 -->
|
||||
<div class="languagelist">
|
||||
<el-table
|
||||
:data="tableData"
|
||||
stripe
|
||||
style="width: 100%; margin-top: 10px"
|
||||
max-height="700"
|
||||
>
|
||||
<el-table-column prop="language" label="语言名称" />
|
||||
<el-table-column prop="" label="" />
|
||||
<el-table-column prop="" label="" />
|
||||
<el-table-column prop="" label="" />
|
||||
<el-table-column label="操作">
|
||||
|
||||
<template #default="scope">
|
||||
<el-button size="small" @click="handleEdit(scope.$index, scope.row)">
|
||||
修改
|
||||
</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
type="danger"
|
||||
@click="handleDelete(scope.$index, scope.row)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 编辑弹窗 -->
|
||||
<el-drawer v-model="dialogVisible" :with-header="false" @close="dialogVisible = false, languageNamedeta = {}">
|
||||
<div class="dialog-content">
|
||||
<div class="dialog-title">语言{{languageNamedeta.id? '编辑' : '新增'}}</div>
|
||||
<el-input
|
||||
v-model="languageNamedeta.language"
|
||||
style="width: 100%; margin-top: 20px"
|
||||
:rows="3"
|
||||
type="textarea"
|
||||
placeholder="请输入语言内容"
|
||||
/>
|
||||
<div class="dialog-btn">
|
||||
<div class="dialogSave" @click="languageSave">保存</div>
|
||||
<div class="dialogCancel" @click="dialogVisible = false">取消</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { getLanguageList,deleteLanguage,editLanguage,addLanguage} from "@/api/account";
|
||||
import {
|
||||
ref, // 响应式基础
|
||||
watch, // 侦听器
|
||||
onMounted, // 组件挂载完成后执行
|
||||
onUpdated, // 组件更新后执行
|
||||
onUnmounted, // 组件销毁前执行
|
||||
} from "vue";
|
||||
const refname = ref("");
|
||||
const tableData = ref([]);
|
||||
const dialogVisible = ref(false);
|
||||
let languageNamedeta = ref({});// 编辑添加弹窗数据
|
||||
// 编辑弹窗
|
||||
function handleEdit(index, row) {
|
||||
dialogVisible.value = true;
|
||||
languageNamedeta.value = row;
|
||||
}
|
||||
// 保存语言
|
||||
function languageSave() {
|
||||
if (languageNamedeta.value.language == null) {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "请输入语言内容",
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (languageNamedeta.value.id) {
|
||||
// 修改语言
|
||||
editLanguage(languageNamedeta.value)
|
||||
.then(() => {
|
||||
ElMessage({
|
||||
type: "success",
|
||||
message: "修改成功",
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "修改失败",
|
||||
});
|
||||
});
|
||||
dialogVisible.value = false;
|
||||
}else{
|
||||
// 新增语言
|
||||
addLanguage(languageNamedeta.value)
|
||||
.then(() => {
|
||||
ElMessage({
|
||||
type: "success",
|
||||
message: "添加成功",
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "添加失败",
|
||||
});
|
||||
});
|
||||
dialogVisible.value = false;
|
||||
}
|
||||
}
|
||||
// 删除语言
|
||||
function handleDelete(index, row) {
|
||||
ElMessageBox.confirm("您确认要删除这个语言吗?")
|
||||
.then(() => {
|
||||
deleteLanguage({ id: row.id })
|
||||
.then(() => {
|
||||
ElMessage({
|
||||
type: "success",
|
||||
message: "删除成功",
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "删除失败",
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
watch(refname, async (newQuestion, oldQuestion) => {
|
||||
// 变化后执行
|
||||
});
|
||||
onMounted(() => {
|
||||
// // 组件挂载完成后执行
|
||||
// // 获取语言列表
|
||||
// getLanguageList()
|
||||
// .then((res) => {
|
||||
// tableData.value = res.data;
|
||||
// }).catch(() => {
|
||||
// ElMessage({
|
||||
// type: "error",
|
||||
// message: "获取语言列表失败",
|
||||
// });
|
||||
// });
|
||||
});
|
||||
onUpdated(() => {
|
||||
// 组件更新后执行
|
||||
});
|
||||
onUnmounted(() => {
|
||||
// 组件销毁前执行
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.language-management {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #ffffff;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.content {
|
||||
width: 95%;
|
||||
height: 95%;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
box-shadow: 2px 4px 8px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
.languagetitle {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 50px;
|
||||
background-color: #e2e2e2;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.title {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
color: #999999;
|
||||
margin-left: 40px;
|
||||
}
|
||||
.add {
|
||||
width: 150px;
|
||||
height: 50px;
|
||||
background-color: #cccccc;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.add:hover {
|
||||
background-color: #999999;
|
||||
}
|
||||
.add-img {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
.languagelist {
|
||||
width: 97%;
|
||||
height: 85%;
|
||||
background-color: #ffffff;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 10px;
|
||||
overflow: auto;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
.dialog-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.dialog-title {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
font-size: 25px;
|
||||
color: #b4b4b4;
|
||||
font-weight: bold;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
.dialog-btn {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.dialogSave {
|
||||
width: 45%;
|
||||
height: 50px;
|
||||
background-color: #d6d6d6;
|
||||
line-height: 50px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
border-radius: 5px;
|
||||
font-size: 16px;
|
||||
color: #ffffff;
|
||||
}
|
||||
.dialogSave:hover {
|
||||
background-color: #b4b4b4;
|
||||
}
|
||||
.dialogCancel {
|
||||
width: 45%;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
border-radius: 5px;
|
||||
font-size: 16px;
|
||||
color: #d6d6d6;
|
||||
border: 1px solid #d6d6d6;
|
||||
}
|
||||
.dialogCancel:hover {
|
||||
background-color: #e7e6e6;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
399
src/views/hosts/ai/scriptManagement.vue
Normal file
@@ -0,0 +1,399 @@
|
||||
<template>
|
||||
<div class="scriptManagement">
|
||||
<div class="wordslist">
|
||||
<!-- 话术列表 -->
|
||||
<div class="wordscontent" ref="containerRef">
|
||||
<div
|
||||
class="words"
|
||||
v-for="(item, index) in LanguageData"
|
||||
:key="index"
|
||||
:id="item.language"
|
||||
>
|
||||
<div class="wordsname">{{ item.language }}</div>
|
||||
<div class="wordscontents">
|
||||
<div
|
||||
class="wordscontentstext"
|
||||
v-for="(items, indexs) in item.content"
|
||||
:key="index"
|
||||
>
|
||||
<div>{{ indexs + 1 + ". " + items.content }}</div>
|
||||
<div class="wordscontentstextbtn">
|
||||
<div style="margin-right: 10px" @click="handleEditor(items.id)">编辑</div>
|
||||
<div @click="handleDelete(items.id)">删除</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="Languagelist">
|
||||
<div class="Languagecontent">
|
||||
<!-- 话术添加 -->
|
||||
<div class="addwords" @click="wordsAddStatus = true">
|
||||
<img class="addwordsimg" src="@/assets/plus.png" />
|
||||
</div>
|
||||
<!-- 语言选择 -->
|
||||
<el-anchor
|
||||
class="Languageanchor"
|
||||
:container="containerRef"
|
||||
direction="vertical"
|
||||
type="default"
|
||||
:offset="30"
|
||||
@click="handleClick"
|
||||
>
|
||||
<el-anchor-link
|
||||
class="anchorLink"
|
||||
v-for="(item, index) in getLanguageListData"
|
||||
:href="'#' + item.language"
|
||||
:title="item.language"
|
||||
:key="index"
|
||||
/>
|
||||
</el-anchor>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 话术编辑 -->
|
||||
<el-drawer v-model="dialogVisible" :with-header="false">
|
||||
<div class="dialog-content">
|
||||
<div class="dialog-title">话术编辑</div>
|
||||
<el-input
|
||||
v-model="handletextareadeta.content"
|
||||
style="width: 100%; margin-top: 20px"
|
||||
:rows="25"
|
||||
type="textarea"
|
||||
placeholder="请输入话术内容"
|
||||
/>
|
||||
<div class="dialog-btn">
|
||||
<div class="dialogSave" @click="handleSave">保存</div>
|
||||
<div class="dialogCancel" @click="dialogVisible = false">取消</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
<!-- 话术添加 -->
|
||||
<el-drawer v-model="wordsAddStatus" :with-header="false">
|
||||
<div class="dialog-content">
|
||||
<div class="dialog-title">话术编辑</div>
|
||||
<el-select v-model="wordsAddData.language" placeholder="请选择语言"></el-select>
|
||||
<el-input
|
||||
v-model="wordsAddData.content"
|
||||
style="width: 100%; margin-top: 20px"
|
||||
:rows="25"
|
||||
type="textarea"
|
||||
placeholder="请输入话术内容"
|
||||
/>
|
||||
<div class="dialog-btn">
|
||||
<div class="dialogSave" @click="handleSaveWordsAdd">保存</div>
|
||||
<div class="dialogCancel" @click="wordsAddStatus = false">取消</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getDialogList, getLanguageList, editDialog, deleteDialog,addDialog} from "@/api/account";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import {
|
||||
ref, // 响应式基础
|
||||
watch, // 侦听器
|
||||
onMounted, // 组件挂载完成后执行
|
||||
onUpdated, // 组件更新后执行
|
||||
onUnmounted, // 组件销毁前执行
|
||||
} from "vue";
|
||||
const refname = ref("");
|
||||
const containerRef = ref(null);
|
||||
const getDialogListData = ref([]);
|
||||
const getLanguageListData = ref([]);
|
||||
const LanguageData = ref([]);
|
||||
const wordsAddStatus = ref(false);
|
||||
const wordsAddData = ref({
|
||||
language: "",
|
||||
content: "",
|
||||
});
|
||||
|
||||
const handleClick = (e) => {
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
//数据处理
|
||||
function groupContentByLanguage(arr1, arr2) {
|
||||
return arr2.map((item) => {
|
||||
// 过滤出对应语言的内容
|
||||
const contents = arr1
|
||||
.filter(({ language }) => language === item.language)
|
||||
// 按 id 排序
|
||||
.sort((a, b) => a.id - b.id)
|
||||
// 转换为所需格式
|
||||
.map(({ id, content }) => ({ id, content }));
|
||||
|
||||
return {
|
||||
id: item.id,
|
||||
language: item.language,
|
||||
content: contents,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const handletextareadeta = ref({});
|
||||
//添加话术
|
||||
function handleSaveWordsAdd() {
|
||||
if (wordsAddData.value.language === "" || wordsAddData.value.content === "") {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "请填写完整信息",
|
||||
});
|
||||
return;
|
||||
}
|
||||
addDialog(wordsAddData.value)
|
||||
.then(() => {
|
||||
ElMessage({
|
||||
type: "success",
|
||||
message: "添加成功",
|
||||
});
|
||||
wordsAddStatus.value = false;
|
||||
getDialogListData.value = getDialogList();
|
||||
LanguageData.value = groupContentByLanguage(
|
||||
getDialogListData.value,
|
||||
getLanguageListData.value
|
||||
);
|
||||
}).catch(() => {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "添加失败",
|
||||
});
|
||||
});
|
||||
}
|
||||
// 编辑
|
||||
function handleEditor(id) {
|
||||
dialogVisible.value = true;
|
||||
handletextareadeta.value = getDialogListData.value.find((item) => item.id === id);
|
||||
}
|
||||
|
||||
// 保存
|
||||
function handleSave() {
|
||||
editDialog({
|
||||
id: handletextareadeta.value.id,
|
||||
content: handletextareadeta.value.content,
|
||||
})
|
||||
.then(() => {
|
||||
ElMessage({
|
||||
type: "success",
|
||||
message: "保存成功",
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "保存失败",
|
||||
});
|
||||
});
|
||||
dialogVisible.value = false;
|
||||
getDialogListData.value = getDialogList();
|
||||
}
|
||||
// 删除
|
||||
function handleDelete(id) {
|
||||
ElMessageBox.confirm("您确认要删除这条话术吗?")
|
||||
.then(() => {
|
||||
deleteDialog({ id })
|
||||
.then(() => {
|
||||
ElMessage({
|
||||
type: "success",
|
||||
message: "删除成功",
|
||||
});
|
||||
getDialogListData.value = getDialogList();
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "删除失败",
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
watch(refname, async (newQuestion, oldQuestion) => {
|
||||
// 变化后执行
|
||||
});
|
||||
onMounted(() => {
|
||||
// getDialogListData.value = getDialogList();
|
||||
// console.log(getDialogListData.value);
|
||||
// getLanguageListData.value = getLanguageList();
|
||||
LanguageData.value = groupContentByLanguage(
|
||||
getDialogListData.value,
|
||||
getLanguageListData.value
|
||||
);
|
||||
});
|
||||
onUpdated(() => {
|
||||
// 组件更新后执行
|
||||
});
|
||||
onUnmounted(() => {
|
||||
// 组件销毁前执行
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.scriptManagement {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #ffffff;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
}
|
||||
.wordslist {
|
||||
width: 87%;
|
||||
height: 97%;
|
||||
padding: 1% 1%;
|
||||
/* background-color: #00ff40; */
|
||||
}
|
||||
.Languagelist {
|
||||
height: 97%;
|
||||
width: 10%;
|
||||
padding: 1% 1% 1% 0%;
|
||||
/* background-color: #8d0000; */
|
||||
}
|
||||
.wordscontent {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
border-radius: 10px;
|
||||
background-color: rgb(243, 243, 243);
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
.Languagecontent {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
border-radius: 10px;
|
||||
background-color: rgb(243, 243, 243);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: none; /* 隐藏滚动条 */
|
||||
}
|
||||
.addwords {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
background-color: rgb(226, 226, 226);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.addwords:hover{
|
||||
background-color: rgb(214, 214, 214);
|
||||
}
|
||||
.addwordsimg {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
.Language {
|
||||
height: 50px;
|
||||
width: 100%;
|
||||
background-color: rgb(226, 226, 226);
|
||||
margin-top: 20px;
|
||||
}
|
||||
.words {
|
||||
width: 95%;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.Languageanchor {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
background-color: rgb(243, 243, 243);
|
||||
}
|
||||
.anchorLink {
|
||||
width: 100px;
|
||||
height: 30px;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
line-height: 30px;
|
||||
border-radius: 5px;
|
||||
margin-left: -0.875vw;
|
||||
}
|
||||
.wordsname {
|
||||
font-size: 18px;
|
||||
color: #c9c9c9;
|
||||
font-weight: bold;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.wordscontents {
|
||||
width: 95%;
|
||||
/* min-height: 200px; */
|
||||
/* background-color: #ffffff; */
|
||||
border-radius: 10px;
|
||||
margin-left: 30px;
|
||||
}
|
||||
.wordscontentstext {
|
||||
font-size: 16px;
|
||||
color: #7a7a7a;
|
||||
line-height: 24px;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
text-align: left;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.wordscontentstextbtn {
|
||||
display: flex;
|
||||
}
|
||||
.dialog-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.dialog-title {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
font-size: 25px;
|
||||
color: #b4b4b4;
|
||||
font-weight: bold;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
.dialog-btn {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.dialogSave {
|
||||
width: 45%;
|
||||
height: 50px;
|
||||
background-color: #d6d6d6;
|
||||
line-height: 50px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
border-radius: 5px;
|
||||
font-size: 16px;
|
||||
color: #ffffff;
|
||||
}
|
||||
.dialogSave:hover {
|
||||
background-color: #b4b4b4;
|
||||
}
|
||||
.dialogCancel {
|
||||
width: 45%;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
border-radius: 5px;
|
||||
font-size: 16px;
|
||||
color: #d6d6d6;
|
||||
border: 1px solid #d6d6d6;
|
||||
}
|
||||
.dialogCancel:hover {
|
||||
background-color: #e7e6e6;
|
||||
color: #ffffff;
|
||||
}
|
||||
/* 样式定义 */
|
||||
</style>
|
||||
@@ -1,576 +0,0 @@
|
||||
<template>
|
||||
<div class="hostList">
|
||||
<div>
|
||||
<div style="display: flex;">
|
||||
<el-select v-model="searchForm.country" filterable placeholder="选择国家" size="large" style="width: 240px">
|
||||
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
<div></div>
|
||||
<el-date-picker v-model="searchForm.time" type="date" value-format="YYYYMMDD" placeholder="选择查询时间" size="large"
|
||||
style="margin-left: 50px;" />
|
||||
|
||||
<el-button class="serch-button" style="margin-left: 50px;" type="primary" @click="serch">查询</el-button>
|
||||
<el-button class="put-button" :disabled="tableData.length == 0" type="primary"
|
||||
@click="exportList">导出Excel数据</el-button>
|
||||
<el-button v-if="userInfo.userType == 3" class="put-button" type="primary"
|
||||
@click="dialogFormVisible = true">分配给指定员工</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" height="500"
|
||||
@selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="35" />
|
||||
<el-table-column fixed prop="hostId" label="主播id" width="160">
|
||||
<template #default="scope">
|
||||
<div class="hostIdText" @click="openHTML(scope.row.hostId)"> {{ scope.row.hostId }}</div>
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="hostName" label="主播名字" min-width="160">
|
||||
<template #default="scope">
|
||||
{{ scope.row.hostName }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="hostlevel" label="等级" width="120">
|
||||
<template #default="scope">
|
||||
{{ scope.row.hostlevel }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-for="label in labelList" :key="label.paramCode" :prop="label.paramCode"
|
||||
:label="label.paramCodeMeaning" width="120">
|
||||
<template v-if="label.paramCode != 'createDt'" #default="scope">
|
||||
<el-popover v-if="!(label.paramCode == 'hostcoins' || label.paramCode == 'ysthostcoins')"
|
||||
placement="bottom" :width="600" trigger="hover">
|
||||
<div style="height: 300px;">
|
||||
<component :is="EChartsComponent" v-if="isPopoverVisible[`${scope.row.hostId}-${label.paramCode}`]"
|
||||
:title="label.paramCodeMeaning" :id="scope.row.hostId" :dataType="label.paramCode"
|
||||
:time="searchForm.time"></component>
|
||||
</div>
|
||||
<template #reference>
|
||||
<span @mouseover="openPopover(scope.row.hostId, label.paramCode)"
|
||||
@mouseout="closePopover(scope.row.hostId, label.paramCode)">
|
||||
{{ scope.row[label.paramCode] }}
|
||||
</span>
|
||||
</template>
|
||||
</el-popover>
|
||||
|
||||
<el-popover v-else placement="bottom" :width="500" trigger="hover">
|
||||
<div style="height: 300px;">
|
||||
<component :is="EChartsComponent" v-if="isPopoverVisible[`${scope.row.hostId}-${label.paramCode}`]"
|
||||
:title="label.paramCodeMeaning" :id="scope.row.hostId" :dataType="label.paramCode"
|
||||
:time="searchForm.time">
|
||||
</component>
|
||||
</div>
|
||||
<template #reference>
|
||||
<!-- 鼠标移入时开启 -->
|
||||
|
||||
<span @mouseover="openPopover(scope.row.hostId, label.paramCode)"
|
||||
@mouseout="closePopover(scope.row.hostId, label.paramCode)">
|
||||
{{ scope.row[label.paramCode] }}
|
||||
</span>
|
||||
</template>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column fixed="right" label="操作" width="120">
|
||||
<template #default="scope">
|
||||
|
||||
<el-popover placement="top-start" :width="200" trigger="hover" :content="scope.row.comment">
|
||||
<template #reference>
|
||||
<el-button @click="openComment(scope.row)" link type="primary" size="small">维护情况</el-button>
|
||||
</template>
|
||||
</el-popover>
|
||||
|
||||
|
||||
<select @change="handleSelectChange($event, scope.row)" v-model="scope.row.useable" class="m-2"
|
||||
placeholder="Select" size="small" style="width: 70px">
|
||||
<option label="未转化" value="N" />
|
||||
<option label="已转化" value="Y" />
|
||||
</select>
|
||||
|
||||
<el-dialog :modal="false" v-model="commentVisible" title="维护情况" align-center>
|
||||
<el-input maxlength="80" v-model="commentInfo" placeholder="请输入维护情况" clearable show-word-limit />
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="commentVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="uphostcomment()">
|
||||
提交
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column label="操作">
|
||||
<template #default="scope">
|
||||
<div style="display: flex; align-items: center">
|
||||
<el-button type="primary" @click="getTkhostdetail(scope.row.hostId)">查看</el-button>
|
||||
</div>
|
||||
</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]"
|
||||
@size-change="handleSizeChange" @current-change="handleCurrentChange" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<el-dialog v-model="dialogFormVisible" title="分配主播" align-center>
|
||||
<el-select v-model="staffValue" filterable placeholder="Select" style="width: 240px">
|
||||
<el-option v-for="item in staffOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="dialogFormVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="allocation">
|
||||
分配
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
|
||||
<el-dialog v-model="filterdialogVisible" width="800px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<label>选择筛选条件</label>
|
||||
<el-select v-model="searchForm.dataType" filterable placeholder="筛选条件" style="width: 240px">
|
||||
<el-option v-for="item in filterOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div v-if="!(searchForm.dataType == 'InvitationType')"><label>最小值</label></div>
|
||||
<div v-else><label>普票/金票</label></div>
|
||||
|
||||
<el-input v-show="!(searchForm.dataType == 'InvitationType')" type="number" v-model="searchForm.dataStart"
|
||||
placeholder="请输入最小值" />
|
||||
<el-select v-show="(searchForm.dataType == 'InvitationType')" v-model="searchForm.dataStart" filterable
|
||||
placeholder="请选择" style="width: 240px">
|
||||
<el-option v-for="item in [{ label: '普票', value: '1' }, { label: '金票', value: '2' }]" :key="item.value"
|
||||
:label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<div v-show="!(searchForm.dataType == 'InvitationType')"><label>最大值</label></div>
|
||||
|
||||
<el-input v-show="!(searchForm.dataType == 'InvitationType')" type="number" v-model="searchForm.dataEnd"
|
||||
placeholder="请输入最大值" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<!-- <el-button @click="filterdialogVisible = false">取消</el-button> -->
|
||||
<el-button type="primary" @click="filterdialogVisible = false">
|
||||
确认
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// import { getToken, setToken, removeToken } from '@/utils/storage'
|
||||
import { tkhostdata, dicts, tkhostdetail, downList, getStaffList, managerhosts, upholdinfo, getCountryinfo } from '@/api/account';
|
||||
import { usePythonBridge, } from '@/utils/pythonBridge'
|
||||
import { getUser } from '@/utils/storage'
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import EChartsComponent from '@/components/EChartsComponent.vue';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
|
||||
const loading = ref(false)
|
||||
//py方法
|
||||
const { givePyAnchorId, exportToExcel } = usePythonBridge();
|
||||
|
||||
let num = ref(0)
|
||||
//账号信息
|
||||
const userInfo = ref(getUser())
|
||||
//主播列表DOM
|
||||
const multipleTableRef = ref(null)
|
||||
|
||||
let labelList = ref([])
|
||||
const tableData = ref([])
|
||||
//选择国家
|
||||
const searchForm = ref({
|
||||
country: '',
|
||||
time: new Date().toISOString().split('T')[0].replace(/-/g, ''),
|
||||
dataType: '',
|
||||
dataStart: '',
|
||||
dataEnd: '',
|
||||
})
|
||||
|
||||
//员工选择列表
|
||||
let staffOptions = ref([])
|
||||
//筛选条件选择列表
|
||||
let filterOptions = ref([])
|
||||
//选择的员工
|
||||
let staffValue = ref('')
|
||||
//选择的主播列表
|
||||
let selectHostList = ref([])
|
||||
//分配弹窗是否弹出
|
||||
let dialogFormVisible = ref(false)
|
||||
//备注弹窗是否弹出
|
||||
let commentVisible = ref(false)
|
||||
//筛选弹窗是否弹出
|
||||
let filterdialogVisible = ref(false)
|
||||
|
||||
//备注信息
|
||||
let commentInfo = ref('')
|
||||
//备注信息主播
|
||||
let commentHost = ref('')
|
||||
//分页
|
||||
let pageSize = ref(10)
|
||||
let page = ref(1)
|
||||
let total = ref(0)
|
||||
//是否渲染
|
||||
const isPopoverVisible = reactive({})
|
||||
|
||||
|
||||
let options = ref([])
|
||||
|
||||
onMounted(() => {
|
||||
//获取字典
|
||||
getdictionary()
|
||||
//获取下级员工
|
||||
getStaff();
|
||||
//获取国家
|
||||
getCountry();
|
||||
})
|
||||
|
||||
function serch() {
|
||||
|
||||
getlist();
|
||||
}
|
||||
|
||||
function exportList() {
|
||||
if (searchForm.value.dataType == 'InvitationType') {
|
||||
searchForm.value.dataEnd = searchForm.value.dataStart
|
||||
}
|
||||
exportToExcel({
|
||||
searchTime: searchForm.value.time,
|
||||
region: searchForm.value.country,
|
||||
dataType: searchForm.value.dataType == '' ? null : searchForm.value.dataType,
|
||||
dataStart: searchForm.value.dataStart == '' ? null : searchForm.value.dataStart,
|
||||
dataEnd: searchForm.value.dataEnd == '' ? null : searchForm.value.dataEnd,
|
||||
pageSize: pageSize.value,
|
||||
page: page.value,
|
||||
userId: userInfo.value.userId,
|
||||
userType: userInfo.value.userType
|
||||
})
|
||||
|
||||
|
||||
// //浏览器导出方法
|
||||
// downList('export/hostsinfo',
|
||||
// {
|
||||
// searchTime: searchForm.value.time,
|
||||
// region: searchForm.value.country,
|
||||
// pageSize: pageSize.value,
|
||||
// page: page.value,
|
||||
// userId: userInfo.value.userId,
|
||||
// userType: userInfo.value.userType
|
||||
// }
|
||||
// );
|
||||
|
||||
}
|
||||
//分页每页条数
|
||||
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)
|
||||
data.forEach(item => {
|
||||
selectHostList.value.push(item.hostId)
|
||||
})
|
||||
// multipleTableRef.value = data
|
||||
// console.log(multipleTableRef.value)
|
||||
|
||||
}
|
||||
//获取主播列表
|
||||
const getlist = () => {
|
||||
if (searchForm.value.dataType == 'InvitationType') {
|
||||
searchForm.value.dataEnd = searchForm.value.dataStart
|
||||
}
|
||||
|
||||
|
||||
|
||||
loading.value = true
|
||||
console.log(searchForm.value)
|
||||
tkhostdata({
|
||||
searchTime: searchForm.value.time,
|
||||
region: searchForm.value.country,
|
||||
dataType: searchForm.value.dataType == '' ? null : searchForm.value.dataType,
|
||||
dataStart: searchForm.value.dataStart == '' ? null : searchForm.value.dataStart,
|
||||
dataEnd: searchForm.value.dataEnd == '' ? null : searchForm.value.dataEnd,
|
||||
pageSize: pageSize.value,
|
||||
page: page.value,
|
||||
userId: userInfo.value.userId,
|
||||
userType: userInfo.value.userType
|
||||
}).then(res => {
|
||||
loading.value = false
|
||||
total.value = res.total
|
||||
tableData.value = []
|
||||
res.records.forEach(item => {
|
||||
if (item.infoMap.InvitationType == '1') {
|
||||
item.infoMap.InvitationType = '普票'
|
||||
} else if (item.infoMap.InvitationType == '2') {
|
||||
item.infoMap.InvitationType = '金票'
|
||||
|
||||
}
|
||||
console.log(item.infoMap)
|
||||
item = { ...item, ...item.infoMap }
|
||||
tableData.value.push(item)
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
function openComment(data) {
|
||||
console.log(data)
|
||||
commentInfo.value = data.comment
|
||||
commentHost.value = data.hostId
|
||||
commentVisible.value = true
|
||||
}
|
||||
|
||||
//修改主播维护状态
|
||||
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
|
||||
})
|
||||
}
|
||||
//获取字典
|
||||
const getdictionary = () => {
|
||||
dicts({
|
||||
paramType: "hostsdata",
|
||||
// page: 1,
|
||||
offset: 1,
|
||||
pageSize: 100
|
||||
}).then(res => {
|
||||
// labelList.value = res.records
|
||||
labelList.value = res
|
||||
console.log(labelList.value)
|
||||
labelList.value.forEach(item => {
|
||||
filterOptions.value.push({
|
||||
value: item.paramCode,
|
||||
label: item.paramCodeMeaning
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
//获取国家
|
||||
function getCountry() {
|
||||
getCountryinfo({}).then(res => {
|
||||
console.log(res)
|
||||
res.forEach(item => {
|
||||
options.value.push({ value: item.countryGroupName, label: item.countryGroupName })
|
||||
})
|
||||
console.log(options.value)
|
||||
})
|
||||
}
|
||||
|
||||
//获取下级员工
|
||||
const getStaff = () => {
|
||||
getStaffList({
|
||||
userId: userInfo.value.userId,
|
||||
userType: userInfo.value.userType,
|
||||
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) {
|
||||
givePyAnchorId(id)
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.hostList {
|
||||
box-sizing: border-box;
|
||||
// height: 100vh;
|
||||
width: 100%;
|
||||
padding: 40px;
|
||||
|
||||
/* 页面无法选中 */
|
||||
// -webkit-user-select: none;
|
||||
// -moz-user-select: none;
|
||||
// -ms-user-select: none;
|
||||
// user-select: none;
|
||||
|
||||
.hostTable {
|
||||
width: 100%;
|
||||
padding: 40px 0;
|
||||
|
||||
.hostIdText {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
color: #0f0092;
|
||||
}
|
||||
}
|
||||
|
||||
.serch-button {
|
||||
width: 80px;
|
||||
height: 47px;
|
||||
background: #E7CA92;
|
||||
border-radius: 10px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.put-button {
|
||||
width: 132px;
|
||||
height: 47px;
|
||||
background: #E7CA92;
|
||||
border-radius: 10px;
|
||||
border: none;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.el-dialog {
|
||||
|
||||
--el-dialog-font-line-height: 50px;
|
||||
--el-dialog-width: 600px;
|
||||
--el-dialog-border-radius: 8px;
|
||||
}
|
||||
|
||||
.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>
|
||||
::v-deep(.el-input__wrapper) {
|
||||
background-color: #F2FAF9;
|
||||
border: 1px solid #B7CEC5;
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
::v-deep(.el-select__wrapper) {
|
||||
background-color: #F2FAF9;
|
||||
border: 1px solid #B7CEC5;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
::v-deep(.el-pagination.is-background .el-pager li.is-active) {
|
||||
background-color: #338F6A;
|
||||
}
|
||||
</style>
|
||||
38
src/views/hosts/mini/miniAM.vue
Normal file
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<div class="miniAM">
|
||||
小程序账号管理
|
||||
</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>
|
||||
.miniAM {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #ffffff;
|
||||
border-radius: 10px;
|
||||
}
|
||||
/* 样式定义 */
|
||||
</style>
|
||||
311
src/views/hosts/mini/miniIntegral.vue
Normal file
@@ -0,0 +1,311 @@
|
||||
<template>
|
||||
<div class="mini-integral">
|
||||
<div class="content">
|
||||
<!-- 积分配置列表 -->
|
||||
<div class="integral-list">
|
||||
<el-table
|
||||
:data="tableData"
|
||||
stripe
|
||||
style="width: 100%; margin-top: 10px"
|
||||
max-height="700"
|
||||
>
|
||||
<el-table-column prop="functionName" label="事件" />
|
||||
<el-table-column prop="" label="" />
|
||||
<el-table-column prop="functionValue" label="积分" />
|
||||
<el-table-column prop="" label="" />
|
||||
<el-table-column label="操作">
|
||||
<template #default="scope">
|
||||
<el-button size="small" @click="miniIntegralEdit(scope.$index, scope.row)">
|
||||
修改
|
||||
</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
type="danger"
|
||||
@click="miniIntegralDelete(scope.$index, scope.row)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<!-- 积分配置 -->
|
||||
<div class="integral-title">
|
||||
<div class="add" @click="dialogVisible = true">
|
||||
<img class="add-img" src="@/assets/plus2.png" alt="">
|
||||
</div>
|
||||
<div class="integral-text">
|
||||
<div class="h1">小</div>
|
||||
<div class="h1">程</div>
|
||||
<div class="h1">序</div>
|
||||
<div class="h1">积</div>
|
||||
<div class="h1">分</div>
|
||||
<div class="h1">配</div>
|
||||
<div class="h1">置</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 新增修改积分配置弹窗 -->
|
||||
<el-drawer v-model="dialogVisible" :with-header="false" @close="dialogVisible = false, miniIntegraldeta = {}">
|
||||
<div class="dialog-content">
|
||||
<div class="dialog-title">事件{{miniIntegraldeta.id? '编辑' : '新增'}}</div>
|
||||
<el-input
|
||||
v-if="!miniIntegraldeta.id"
|
||||
v-model="miniIntegraldeta.functionName"
|
||||
style="width: 100%; margin-top: 20px"
|
||||
:rows="3"
|
||||
type="textarea"
|
||||
placeholder="请输入事件名称"
|
||||
/>
|
||||
<el-input
|
||||
v-model="miniIntegraldeta.functionValue"
|
||||
style="width: 100%;height: 50px; margin-top: 20px"
|
||||
type="number"
|
||||
placeholder="请输入积分值"
|
||||
/>
|
||||
<div class="dialog-btn">
|
||||
<div class="dialogSave" @click="miniIntegralAddSave">保存</div>
|
||||
<div class="dialogCancel" @click="dialogVisible = false">取消</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import {
|
||||
getWxConfigList,
|
||||
addWxConfig,
|
||||
editWxConfig,
|
||||
deleteWxConfig,
|
||||
} from "@/api/account";
|
||||
import {
|
||||
ref, // 响应式基础
|
||||
watch, // 侦听器
|
||||
onMounted, // 组件挂载完成后执行
|
||||
onUpdated, // 组件更新后执行
|
||||
onUnmounted, // 组件销毁前执行
|
||||
} from "vue";
|
||||
const refname = ref("");
|
||||
const tableData = ref([
|
||||
{
|
||||
id: 1,
|
||||
functionName: "登录",
|
||||
functionValue: 10,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
functionName: "分享",
|
||||
functionValue: 20,
|
||||
},
|
||||
]);
|
||||
const dialogVisible = ref(false);
|
||||
const miniIntegraldeta = ref({});
|
||||
//保存积分配置
|
||||
function miniIntegralAddSave() {
|
||||
if (!miniIntegraldeta.value.functionName) {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "事件名称不能为空",
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!miniIntegraldeta.value.functionValue) {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "积分值不能为空",
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (miniIntegraldeta.value.id) {
|
||||
// 修改积分配置
|
||||
editWxConfig(miniIntegraldeta.value)
|
||||
.then(() => {
|
||||
ElMessage({
|
||||
type: "success",
|
||||
message: "修改成功",
|
||||
});
|
||||
dialogVisible.value = false;
|
||||
miniIntegraldeta.value = {};
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "修改失败",
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// 新增积分配置
|
||||
addWxConfig(miniIntegraldeta.value)
|
||||
.then(() => {
|
||||
ElMessage({
|
||||
type: "success",
|
||||
message: "新增成功",
|
||||
});
|
||||
dialogVisible.value = false;
|
||||
miniIntegraldeta.value = {};
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "新增失败",
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
// 新增积分配置弹窗
|
||||
function miniIntegralEdit(index, row) {
|
||||
dialogVisible.value = true;
|
||||
miniIntegraldeta.value = row;
|
||||
console.log(index, row);
|
||||
}
|
||||
//删除积分配置
|
||||
function miniIntegralDelete(index, row) {
|
||||
ElMessageBox.confirm("您确认要删除这个积分配置吗?")
|
||||
.then(() => {
|
||||
deleteWxConfig({ id: row.id })
|
||||
.then(() => {
|
||||
ElMessage({
|
||||
type: "success",
|
||||
message: "删除成功",
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "删除失败",
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
watch(refname, async (newQuestion, oldQuestion) => {
|
||||
// 变化后执行
|
||||
});
|
||||
onMounted(() => {
|
||||
// 组件挂载完成后执行
|
||||
});
|
||||
onUpdated(() => {
|
||||
// 组件更新后执行
|
||||
});
|
||||
onUnmounted(() => {
|
||||
// 组件销毁前执行
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.mini-integral {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #ffffff;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.content {
|
||||
width: 80%;
|
||||
height: 80%;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
box-shadow: 2px 4px 8px rgba(0, 0, 0, 0.3);
|
||||
padding: 40px;
|
||||
}
|
||||
.integral-list{
|
||||
width: 87%;
|
||||
height: 100%;
|
||||
background-color: #ffffff;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.integral-title{
|
||||
width: 10%;
|
||||
height: 100%;
|
||||
background-color: #ffffff;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.add{
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #c4c4c4;
|
||||
border-radius: 10px 10px 0 0;
|
||||
}
|
||||
.add:hover{
|
||||
background-color: #a9a9a9;
|
||||
}
|
||||
.add-img{
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
.integral-text{
|
||||
width: 100%;
|
||||
height: 520px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 20px;
|
||||
color: #c4c4c4;
|
||||
font-size: 25px;
|
||||
font-family: "SimSun", "Microsoft YaHei", sans-serif;
|
||||
}
|
||||
.h1{
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.dialog-title {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
font-size: 25px;
|
||||
color: #b4b4b4;
|
||||
font-weight: bold;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
.dialog-btn {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.dialogSave {
|
||||
width: 45%;
|
||||
height: 50px;
|
||||
background-color: #d6d6d6;
|
||||
line-height: 50px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
border-radius: 5px;
|
||||
font-size: 16px;
|
||||
color: #ffffff;
|
||||
}
|
||||
.dialogSave:hover {
|
||||
background-color: #b4b4b4;
|
||||
}
|
||||
.dialogCancel {
|
||||
width: 45%;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
border-radius: 5px;
|
||||
font-size: 16px;
|
||||
color: #d6d6d6;
|
||||
border: 1px solid #d6d6d6;
|
||||
}
|
||||
.dialogCancel:hover {
|
||||
background-color: #e7e6e6;
|
||||
color: #ffffff;
|
||||
}
|
||||
/* 样式定义 */
|
||||
</style>
|
||||
@@ -1,589 +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>
|
||||
<div class="center-line" style="padding-top: 15vh;">
|
||||
<el-button class="open-login" type="primary" @click="openTK">开启tk</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="!(isTk && tkData[index].code == 0)" 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="!(isTk && tkData[index].code == 0)" v-model="tkData[index].password"
|
||||
type="password" placeholder="请输入登录密码" show-password />
|
||||
</div>
|
||||
|
||||
<el-button class="open-login" style="margin-left: 60px;"
|
||||
:disabled="!(isTk && tkData[index].code == 0)" type="primary"
|
||||
@click="loginTK(index)">登录tk</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" :min="0"
|
||||
:max="pyData.frequency.day - 1" placeholder="次/小时" style="width: 100%"
|
||||
:disabled="!pyData.isStart">
|
||||
<template #append>次/小时</template>
|
||||
</el-input>
|
||||
<el-input type='number' v-model="pyData.frequency.day" :min="pyData.frequency.hour + 1"
|
||||
:max="100" 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 } 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 statusTimer = ref(null);
|
||||
let statusTimerCopy = ref(null);
|
||||
|
||||
|
||||
//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(false);
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
//提交数据到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;
|
||||
}
|
||||
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) => {
|
||||
|
||||
getHostTimer.value = setInterval(() => {
|
||||
fetchDataCount().then((res) => {
|
||||
hostData.value = JSON.parse(res);
|
||||
tkaccountuse(tkData.value[0].account, 0)
|
||||
tkaccountuse(tkData.value[1].account, 1)
|
||||
})
|
||||
}, 1000);
|
||||
|
||||
|
||||
}).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) => {
|
||||
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) {
|
||||
statusTimer = setInterval(() => {
|
||||
getloginStatus();
|
||||
}, 2000)
|
||||
} else if (index == 1) {
|
||||
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;
|
||||
}
|
||||
})
|
||||
}
|
||||
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;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function tkaccountuse(id, index) {
|
||||
let num = 0;
|
||||
tkaccountuseinfo({ userId: id }).then((res) => {
|
||||
num = res
|
||||
tkData.value[index].num = num
|
||||
console.log('账号使用次数', tkData.value[index].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: #E7CA92;
|
||||
border-radius: 10px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.reset-button {
|
||||
width: 132px;
|
||||
height: 47px;
|
||||
background: #E7CA92;
|
||||
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: #338F6A;
|
||||
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>
|
||||
::v-deep(.el-input-group__prepend) {
|
||||
background: #84CEB2;
|
||||
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: #84CEB2;
|
||||
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,89 +1,205 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<Sidebar class="noneText" @activeIndex="activeIndexFn" />
|
||||
<div class="content ">
|
||||
<div v-show="activeIndex == 1">
|
||||
<workbenches v-if="openWerk" />
|
||||
</div>
|
||||
<div v-show="activeIndex == 2">
|
||||
<hostsList v-if="openList" />
|
||||
</div>
|
||||
<div class="common-layout">
|
||||
<el-container class="container">
|
||||
<el-aside :width="asideWidth" class="aside">
|
||||
<!-- logo -->
|
||||
<div class="logo" :style="{ width: isCollapse ? '4vw' : '10vw' }">
|
||||
<img
|
||||
class="logoimg"
|
||||
:style="{
|
||||
width: isCollapse ? '3vw' : '6vw',
|
||||
height: isCollapse ? '3vw' : '6vw',
|
||||
}"
|
||||
src="../assets//icon.png"
|
||||
alt="图标"
|
||||
/>
|
||||
</div>
|
||||
<!-- 收缩按钮 -->
|
||||
<div
|
||||
class="collapse-btn"
|
||||
:style="{ width: isCollapse ? '4vw' : '10vw' }"
|
||||
@click="toggleCollapse"
|
||||
>
|
||||
<el-icon v-if="isCollapse"><ArrowRightBold /></el-icon
|
||||
><el-icon v-else><ArrowLeftBold /></el-icon>
|
||||
</div>
|
||||
<!-- 菜单 -->
|
||||
<el-row class="row">
|
||||
<el-col :span="12">
|
||||
<el-menu
|
||||
default-active="/nav"
|
||||
background-color="#545c64"
|
||||
router
|
||||
text-color="#fff"
|
||||
@open="handleOpen"
|
||||
@close="handleClose"
|
||||
@select="handleSelect"
|
||||
:collapse="isCollapse"
|
||||
popper-offset="-115"
|
||||
class="menu"
|
||||
>
|
||||
<el-sub-menu index="1" class="sub-menu">
|
||||
<template #title>
|
||||
<el-icon><Tickets /></el-icon>
|
||||
<span>Ai管理</span>
|
||||
</template>
|
||||
<el-menu-item-group>
|
||||
<template #title><span>Ai</span></template>
|
||||
<el-menu-item index="/nav/scriptManagement">话术管理</el-menu-item>
|
||||
<el-menu-item index="/nav/LanguageManagement">语言管理</el-menu-item>
|
||||
</el-menu-item-group>
|
||||
</el-sub-menu>
|
||||
|
||||
<el-sub-menu index="2" class="sub-menu">
|
||||
<template #title>
|
||||
<el-icon><Collection /></el-icon>
|
||||
<span>小程序管理</span>
|
||||
</template>
|
||||
<el-menu-item-group>
|
||||
<template #title><span>小程序</span></template>
|
||||
<el-menu-item index="/nav/miniAM">账号管理</el-menu-item>
|
||||
<el-menu-item index="/nav/miniIntegral">积分配置</el-menu-item>
|
||||
</el-menu-item-group>
|
||||
</el-sub-menu>
|
||||
</el-menu>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-aside>
|
||||
|
||||
</div>
|
||||
<el-container>
|
||||
<!-- 顶部 -->
|
||||
<el-header class="header">
|
||||
<el-breadcrumb :separator-icon="ArrowRight">
|
||||
<el-breadcrumb-item :to="{ path: '/nav/Home' }">首页</el-breadcrumb-item>
|
||||
<el-breadcrumb-item
|
||||
v-for="(item, index) in breadcrumbList"
|
||||
:key="index"
|
||||
replace="true"
|
||||
:to="{ path: handleurl(item.path) }"
|
||||
>
|
||||
{{ item.name }}
|
||||
</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</el-header>
|
||||
<!-- 内容 -->
|
||||
<el-main class="main">
|
||||
<router-view>
|
||||
</router-view>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Sidebar from '../components/Sidebar.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 { ref } from "vue";
|
||||
import {
|
||||
Menu as IconMenu,
|
||||
Message,
|
||||
Setting,
|
||||
Tickets,
|
||||
Collection,
|
||||
ArrowRightBold,
|
||||
ArrowLeftBold,
|
||||
} from "@element-plus/icons-vue";
|
||||
import { ArrowRight } from "@element-plus/icons-vue";
|
||||
import { RouterLink, RouterView } from "vue-router";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
|
||||
let userType = ref(getUser().userType)
|
||||
let activeIndex = ref(userType.value == 3 ? 1 : 2)
|
||||
let openWerk = ref(userType.value == 3 ? true : false)
|
||||
let openList = ref(userType.value == 3 ? false : true)
|
||||
console.log("用户等级", getUser().userType)
|
||||
|
||||
|
||||
|
||||
function activeIndexFn(data) {
|
||||
activeIndex.value = data
|
||||
openWerk.value = true
|
||||
openList.value = true
|
||||
console.log(data)
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
const isCollapse = ref(false);
|
||||
const asideWidth = ref("10vw");
|
||||
const breadcrumbList = ref([]);
|
||||
//路由映射
|
||||
function convertPathsToMenuItems(paths) {
|
||||
const pathMap = {
|
||||
1: "ai管理",
|
||||
2: "小程序管理",
|
||||
"/nav/scriptManagement": "话术管理",
|
||||
"/nav/miniAM": "小程序账号管理",
|
||||
"/nav/miniIntegral": "积分配置",
|
||||
"/nav/LanguageManagement": "语言管理",
|
||||
};
|
||||
return paths.map((path) => {
|
||||
const name = pathMap[path];
|
||||
if (!name) throw new Error(`未找到路径 ${path} 对应的名称`);
|
||||
return { name, path };
|
||||
});
|
||||
}
|
||||
//面包屑
|
||||
function handleSelect(index, indexPath) {
|
||||
console.log("select", convertPathsToMenuItems(indexPath));
|
||||
breadcrumbList.value = convertPathsToMenuItems(indexPath);
|
||||
}
|
||||
//面包屑地址判断
|
||||
function handleurl(indexPath) {
|
||||
if (indexPath === "1" || indexPath === "2") {
|
||||
return "";
|
||||
} else {
|
||||
return indexPath;
|
||||
}
|
||||
}
|
||||
//菜单展开
|
||||
function toggleCollapse() {
|
||||
asideWidth.value = isCollapse.value ? "10vw" : "4vw";
|
||||
isCollapse.value = isCollapse.value ? false : true;
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
body,
|
||||
html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
<style scoped>
|
||||
.common-layout {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.app-container {
|
||||
.aside {
|
||||
height: 100vh;
|
||||
background-color: rgb(87, 87, 87);
|
||||
transition: width 0.3s ease; /* 添加过渡效果 */
|
||||
}
|
||||
.header {
|
||||
width: 85vw;
|
||||
height: 4vh;
|
||||
background-color: rgb(255, 255, 255);
|
||||
display: flex;
|
||||
width: 1600px;
|
||||
height: 900px;
|
||||
background-color: #338F6A;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.noneText {
|
||||
/* 页面无法选中 */
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 200px;
|
||||
background-color: #338F6A;
|
||||
padding: 20px;
|
||||
/* box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1); */
|
||||
}
|
||||
|
||||
.content {
|
||||
margin-left: 280px;
|
||||
width: 1304px;
|
||||
height: 868px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 36px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.center-justify {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
.main {
|
||||
width: 100%;
|
||||
height: 90vh;
|
||||
background-color: rgb(199, 199, 199);
|
||||
}
|
||||
.logo {
|
||||
margin-top: 10px;
|
||||
font-size: 20px;
|
||||
color: white;
|
||||
text-align: center;
|
||||
line-height: 10vh;
|
||||
width: 10vw;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.logoimg {
|
||||
transition: width 0.3s ease; /* 添加过渡效果 */
|
||||
transition: height 0.3s ease; /* 添加过渡效果 */
|
||||
border-radius: 20%;
|
||||
}
|
||||
.row {
|
||||
width: 10vw;
|
||||
height: 80vh;
|
||||
}
|
||||
.menu {
|
||||
width: 10vw;
|
||||
font-size: 30px;
|
||||
}
|
||||
.collapse-btn {
|
||||
height: 40px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
transition: width 0.3s ease; /* 添加过渡效果 */
|
||||
background-color: #3b4046;
|
||||
}
|
||||
</style>
|
||||
|
||||
BIN
tk-page.rar
@@ -18,7 +18,11 @@ module.exports = defineConfig({
|
||||
})
|
||||
]
|
||||
}
|
||||
},
|
||||
less: {
|
||||
additionalData: `@import "@/static/css/app.less";` // 注入全局变量文件
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
||||