| @@ -5,6 +5,8 @@ NODE_ENV='development' | |||||
| VITE_APP_TITLE = 'Metavatar-PC' | VITE_APP_TITLE = 'Metavatar-PC' | ||||
| VITE_APP_PORT = 3000 | VITE_APP_PORT = 3000 | ||||
| ## VITE_APP_BASE_API = 'https://photo.metavatar.cc/C' | |||||
| VITE_APP_BASE_API = 'https://test.metavatar.cc/C' | |||||
| ## VITE_APP_BASE_API = 'https://photo.metavatar.cc/C' alitest 123456 | |||||
| VITE_APP_BASE_API = 'https://mtest.metavatar.cc/A' | |||||
| @@ -1,4 +1,4 @@ | |||||
| <!-- 照片说话 慧影 --> | |||||
| <!-- 邃芒A端--> | |||||
| git commit -m "feat: " | git commit -m "feat: " | ||||
| git commit --no-verify -m "提交时的注释" 跳过检验 | git commit --no-verify -m "提交时的注释" 跳过检验 | ||||
| git merge origin/dev_ | git merge origin/dev_ | ||||
| @@ -5,7 +5,7 @@ | |||||
| <meta charset="UTF-8" /> | <meta charset="UTF-8" /> | ||||
| <link rel="icon" href="/favicon.ico" /> | <link rel="icon" href="/favicon.ico" /> | ||||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||||
| <title>Metavatar-慧影</title> | |||||
| <title>Metavatar-邃芒管理端</title> | |||||
| </head> | </head> | ||||
| <body> | <body> | ||||
| @@ -24,6 +24,7 @@ | |||||
| "echarts": "^5.2.2", | "echarts": "^5.2.2", | ||||
| "element-plus": "^2.3.1", | "element-plus": "^2.3.1", | ||||
| "js-audio-recorder": "^1.0.7", | "js-audio-recorder": "^1.0.7", | ||||
| "js-cookie": "^3.0.5", | |||||
| "nprogress": "^0.2.0", | "nprogress": "^0.2.0", | ||||
| "path-browserify": "^1.0.1", | "path-browserify": "^1.0.1", | ||||
| "path-to-regexp": "^6.2.0", | "path-to-regexp": "^6.2.0", | ||||
| @@ -0,0 +1,52 @@ | |||||
| import request from "@/utils/request.js"; | |||||
| /** | |||||
| * @description 获取合作商列表 | |||||
| * @param {*} (pageNum,pageSize) | |||||
| * @returns data | |||||
| */ | |||||
| export function businessListApi(pageNum, pageSize) { | |||||
| return request({ | |||||
| url: `/serviceInfo/page?pageNum=${pageNum}&pageSize=${pageSize}`, | |||||
| method: 'get' | |||||
| }) | |||||
| } | |||||
| /** | |||||
| * @description 通过id获取合作商 | |||||
| * @param {*} id | |||||
| * @returns data | |||||
| */ | |||||
| export function getBusinessByIdApi(id) { | |||||
| return request({ | |||||
| url: `/serviceInfo/get?id=${id}`, | |||||
| method: 'get' | |||||
| }) | |||||
| } | |||||
| /** | |||||
| * @description 新增合作商 | |||||
| * @param {*} data | |||||
| * @returns data | |||||
| */ | |||||
| export function addBusinessApi(data) { | |||||
| return request({ | |||||
| url: `/serviceInfo/save`, | |||||
| method: 'post', | |||||
| data | |||||
| }) | |||||
| } | |||||
| /** | |||||
| * @description 修改合作商 | |||||
| * @param {*} data | |||||
| * @returns data | |||||
| */ | |||||
| export function updateBusinessApi(data) { | |||||
| return request({ | |||||
| url: `/serviceInfo/update`, | |||||
| method: 'post', | |||||
| data | |||||
| }) | |||||
| } | |||||
| @@ -0,0 +1,39 @@ | |||||
| import request from "@/utils/request.js"; | |||||
| /** | |||||
| * @description 获取密钥列表 | |||||
| * @param {*} (pageNum,pageSize) | |||||
| * @returns data | |||||
| */ | |||||
| export function keyListApi(pageNum, pageSize) { | |||||
| return request({ | |||||
| url: `/thirdPartyApi/page?pageNum=${pageNum}&pageSize=${pageSize}`, | |||||
| method: 'get' | |||||
| }) | |||||
| } | |||||
| /** | |||||
| * @description 根据id获取密钥详情 | |||||
| * @param {*} (id) | |||||
| * @returns data | |||||
| */ | |||||
| export function getKeyByIdApi(id) { | |||||
| return request({ | |||||
| url: `/thirdPartyApi/get?id=${id}`, | |||||
| method: 'get' | |||||
| }) | |||||
| } | |||||
| /** | |||||
| * @description 更改密钥状态 | |||||
| * @param {*} (id,status) | |||||
| * @returns data | |||||
| */ | |||||
| export function updateKeyStatusApi(id, status) { | |||||
| return request({ | |||||
| url: `/thirdPartyApi/updateStatus`, | |||||
| method: 'post', | |||||
| data: { id, status } | |||||
| }) | |||||
| } | |||||
| @@ -0,0 +1,13 @@ | |||||
| import request from "@/utils/request.js"; | |||||
| /** | |||||
| * @description:全查询导航菜单 | |||||
| * @param | |||||
| * @return: | |||||
| */ | |||||
| export function getMenuNavApi() { | |||||
| return request({ | |||||
| url: `/menu/nav`, | |||||
| method: 'get', | |||||
| }) | |||||
| } | |||||
| @@ -2,29 +2,16 @@ import request from "@/utils/request.js"; | |||||
| const baseURL = import.meta.env.VITE_APP_BASE_API | const baseURL = import.meta.env.VITE_APP_BASE_API | ||||
| /** | |||||
| * @description 注册 | |||||
| * @params email,password | |||||
| * @returns data | |||||
| */ | |||||
| export function register(data) { | |||||
| return request({ | |||||
| // url: `/api/user/doRegisterByEmail`, | |||||
| url: `/api/user/doRegisterByPhone`, | |||||
| method: 'post', | |||||
| data | |||||
| }) | |||||
| } | |||||
| /** | /** | ||||
| * @description 登录 | * @description 登录 | ||||
| * @params email,password,code | * @params email,password,code | ||||
| * @returns data | * @returns data | ||||
| */ | */ | ||||
| export function login(data) { | |||||
| export function loginApi(data) { | |||||
| return request({ | return request({ | ||||
| // url: `/api/user/loginByEmail`, | // url: `/api/user/loginByEmail`, | ||||
| url: `/api/user/login`, | |||||
| url: `/doLogin`, | |||||
| method: 'post', | method: 'post', | ||||
| data | data | ||||
| }) | }) | ||||
| @@ -175,5 +162,5 @@ export function resetPwdFormApi(data) { | |||||
| * @description:获取图形验证码 | * @description:获取图形验证码 | ||||
| * @return: 验证码地址 | * @return: 验证码地址 | ||||
| */ | */ | ||||
| export const getCodeImgUrl = baseURL + '/api/user/captcha.jpg' | |||||
| export const getCodeImgUrl = baseURL + '/captcha.jpg' | |||||
| @@ -70,7 +70,7 @@ export function updUserInfoApi(data) { | |||||
| */ | */ | ||||
| export function getUserInfoApi() { | export function getUserInfoApi() { | ||||
| return request({ | return request({ | ||||
| url: `api/user/getUserInfo`, | |||||
| url: `getUserInfo`, | |||||
| method: 'get', | method: 'get', | ||||
| }) | }) | ||||
| } | } | ||||
| @@ -0,0 +1,13 @@ | |||||
| import request from "@/utils/request.js"; | |||||
| /** | |||||
| * @description 获取用户列表 | |||||
| * @param sex ,pageNum,pageSize | |||||
| * @returns data | |||||
| */ | |||||
| export function modeListApi(sex, pageNum, pageSize, videoType) { | |||||
| return request({ | |||||
| url: `/api/personPatch/list?sex=${sex}&pageNum=${pageNum}&pageSize=${pageSize}&videoType=${videoType}`, | |||||
| method: 'get' | |||||
| }) | |||||
| } | |||||
| @@ -15,7 +15,7 @@ export default { | |||||
| // 登录页面国际化 | // 登录页面国际化 | ||||
| login: { | login: { | ||||
| // title: "Metavatar-MetaTalker", | // title: "Metavatar-MetaTalker", | ||||
| title: "MetaTalker", | |||||
| title: "MetaTalker-Admin", | |||||
| username: "Username", | username: "Username", | ||||
| email: "Phone", | email: "Phone", | ||||
| password: "Password", | password: "Password", | ||||
| @@ -24,7 +24,7 @@ export default { | |||||
| register: "Sign up", | register: "Sign up", | ||||
| loginBtn: "Sign in", | loginBtn: "Sign in", | ||||
| registerBtn: "Sign up", | registerBtn: "Sign up", | ||||
| verifyCode: "Verify code", | |||||
| captcha: "Verify code", | |||||
| signIn: "Already got an account? Sign in here", | signIn: "Already got an account? Sign in here", | ||||
| signUp: "Don't have an account? Sign up here", | signUp: "Don't have an account? Sign up here", | ||||
| forgetPwd: "I forgot my password", | forgetPwd: "I forgot my password", | ||||
| @@ -203,10 +203,6 @@ export default { | |||||
| comingSoon: "Coming Soon", | comingSoon: "Coming Soon", | ||||
| }, | }, | ||||
| apiMangage: { | |||||
| title: "API Mangage", | |||||
| }, | |||||
| signSucceed: { | signSucceed: { | ||||
| title: "Confirm your email", | title: "Confirm your email", | ||||
| succeed: "Sign Succeed !", | succeed: "Sign Succeed !", | ||||
| @@ -221,6 +217,44 @@ export default { | |||||
| }, | }, | ||||
| modelMangage: { | modelMangage: { | ||||
| title: "Model Set", | |||||
| title: "Model", | |||||
| }, | |||||
| businessMangage: { | |||||
| title: "Business", | |||||
| name: "Owner", | |||||
| address: "Address", | |||||
| status: "Status", | |||||
| code: "Code", | |||||
| addNew: "Add new business", | |||||
| createTime: "CreateTime", | |||||
| cancel: "Cancel", | |||||
| confirm: "Confirm", | |||||
| nameInputText: "Please type owner", | |||||
| addressInputText: "Please type address", | |||||
| codeInputText: "Please type code and make sure it's only", | |||||
| accessMethod: "Access Method", | |||||
| typeInputText: "Please select your access method", | |||||
| }, | |||||
| keyMangage: { | |||||
| title: "Key", | |||||
| list: "Key List", | |||||
| name: "Owner", | |||||
| status: "Status", | |||||
| operations: "Operations", | |||||
| check: "Check", | |||||
| }, | |||||
| priceMangage: { | |||||
| title: "Price", | |||||
| }, | |||||
| dataCount: { | |||||
| title: "DataBoard", | |||||
| }, | |||||
| apiMangage: { | |||||
| title: "API", | |||||
| }, | }, | ||||
| }; | }; | ||||
| @@ -14,7 +14,7 @@ export default { | |||||
| }, | }, | ||||
| // 登录页面国际化 | // 登录页面国际化 | ||||
| login: { | login: { | ||||
| title: "慧影", | |||||
| title: "邃芒管理端", | |||||
| username: "用户名", | username: "用户名", | ||||
| email: "手机号", | email: "手机号", | ||||
| password: "密码", | password: "密码", | ||||
| @@ -23,7 +23,7 @@ export default { | |||||
| register: "注册", | register: "注册", | ||||
| loginBtn: "登 录", | loginBtn: "登 录", | ||||
| registerBtn: "注 册", | registerBtn: "注 册", | ||||
| verifyCode: "验证码", | |||||
| captcha: "验证码", | |||||
| // signIn: "已有账号?现在登录!", | // signIn: "已有账号?现在登录!", | ||||
| // signUp: "没有账号?现在加入!", | // signUp: "没有账号?现在加入!", | ||||
| signIn: "立即登录", | signIn: "立即登录", | ||||
| @@ -203,10 +203,6 @@ export default { | |||||
| comingSoon: "敬请期待", | comingSoon: "敬请期待", | ||||
| }, | }, | ||||
| apiMangage: { | |||||
| title: "API 管理", | |||||
| }, | |||||
| signSucceed: { | signSucceed: { | ||||
| title: "确认邮箱", | title: "确认邮箱", | ||||
| succeed: "注册成功", | succeed: "注册成功", | ||||
| @@ -222,4 +218,42 @@ export default { | |||||
| modelMangage: { | modelMangage: { | ||||
| title: "模板管理", | title: "模板管理", | ||||
| }, | }, | ||||
| businessMangage: { | |||||
| title: "商务管理", | |||||
| name: "所属人", | |||||
| address: "地址", | |||||
| status: "状态", | |||||
| code: "凭证", | |||||
| addNew: "新增合作商", | |||||
| createTime: "创建时间", | |||||
| cancel: "取消", | |||||
| confirm: "确认", | |||||
| nameInputText: "请输入所属人名称", | |||||
| addressInputText: "请输入地址", | |||||
| codeInputText: "请输入凭证并确保此字段是唯一值", | |||||
| accessMethod: "接入方式", | |||||
| typeInputText: "请选择接入方式", | |||||
| }, | |||||
| keyMangage: { | |||||
| title: "密钥管理", | |||||
| list: "密钥列表", | |||||
| name: "所属人", | |||||
| status: "密钥状态", | |||||
| operations: "操作", | |||||
| check: "查看", | |||||
| }, | |||||
| priceMangage: { | |||||
| title: "价格管理", | |||||
| }, | |||||
| dataCount: { | |||||
| title: "数据统计", | |||||
| }, | |||||
| apiMangage: { | |||||
| title: "API 管理", | |||||
| }, | |||||
| }; | }; | ||||
| @@ -1,119 +0,0 @@ | |||||
| <template> | |||||
| <div> | |||||
| <!-- 侧边栏 --> | |||||
| <div><Sidebar class="sidebar-container" /></div> | |||||
| <!-- 页面主体 --> | |||||
| <div> | |||||
| <!-- nav --> | |||||
| <div><navbar /></div> | |||||
| <!-- 页面主体 --> | |||||
| <div><app-main /></div> | |||||
| </div> | |||||
| </div> | |||||
| </template> | |||||
| <script setup lang="ts"> | |||||
| import { computed, watchEffect } from "vue"; | |||||
| import { useWindowSize } from "@vueuse/core"; | |||||
| import { AppMain, Navbar } from "./components/index"; | |||||
| import SignSucceed from "../views/signSucceed/index.vue"; | |||||
| import Sidebar from "./components/Sidebar/index.vue"; | |||||
| import { useAppStore } from "@/store/modules/app"; | |||||
| import { useSettingsStore } from "@/store/modules/settings"; | |||||
| import { useRoute, useRouter } from "vue-router"; | |||||
| const route = useRoute(); | |||||
| const { params } = route; | |||||
| const { width } = useWindowSize(); | |||||
| /** | |||||
| * 响应式布局容器固定宽度 | |||||
| * | |||||
| * 大屏(>=1200px) | |||||
| * 中屏(>=992px) | |||||
| * 小屏(>=768px) | |||||
| */ | |||||
| const WIDTH = 992; | |||||
| const appStore = useAppStore(); | |||||
| const settingsStore = useSettingsStore(); | |||||
| const fixedHeader = computed(() => settingsStore.fixedHeader); | |||||
| const showTagsView = computed(() => settingsStore.tagsView); | |||||
| const showSettings = computed(() => settingsStore.showSettings); | |||||
| const classObj = computed(() => ({ | |||||
| hideSidebar: !appStore.sidebar.opened, | |||||
| openSidebar: appStore.sidebar.opened, | |||||
| withoutAnimation: appStore.sidebar.withoutAnimation, | |||||
| mobile: appStore.device === "mobile", | |||||
| })); | |||||
| watchEffect(() => { | |||||
| if (width.value < WIDTH) { | |||||
| appStore.toggleDevice("mobile"); | |||||
| appStore.closeSideBar(true); | |||||
| } else { | |||||
| appStore.toggleDevice("desktop"); | |||||
| if (width.value >= 1200) { | |||||
| //大屏 | |||||
| appStore.openSideBar(true); | |||||
| } else { | |||||
| appStore.closeSideBar(true); | |||||
| } | |||||
| } | |||||
| }); | |||||
| function handleOutsideClick() { | |||||
| appStore.closeSideBar(false); | |||||
| } | |||||
| onMounted(() => {}); | |||||
| </script> | |||||
| <style lang="scss" scoped> | |||||
| .app-wrapper { | |||||
| &::after { | |||||
| display: table; | |||||
| clear: both; | |||||
| content: ""; | |||||
| } | |||||
| position: relative; | |||||
| width: 100%; | |||||
| height: 100%; | |||||
| e &.mobile.openSidebar { | |||||
| position: fixed; | |||||
| top: 0; | |||||
| } | |||||
| } | |||||
| .fixed-header { | |||||
| position: fixed; | |||||
| top: 0; | |||||
| right: 0; | |||||
| z-index: 9; | |||||
| width: calc(100% - #{$sideBarWidth}); | |||||
| transition: width 0.28s; | |||||
| } | |||||
| .hideSidebar .fixed-header { | |||||
| width: calc(100% - 54px); | |||||
| } | |||||
| .mobile .fixed-header { | |||||
| width: 100%; | |||||
| } | |||||
| .drawer-bg { | |||||
| position: absolute; | |||||
| top: 0; | |||||
| z-index: 999; | |||||
| width: 100%; | |||||
| height: 100%; | |||||
| // background: #1b213a; | |||||
| background: #000; | |||||
| opacity: 0.3; | |||||
| } | |||||
| </style> | |||||
| @@ -1,131 +0,0 @@ | |||||
| <template> | |||||
| <div :class="classObj" class="app-wrapper"> | |||||
| <!-- 手机设备侧边栏打开遮罩层 --> | |||||
| <div | |||||
| v-if="classObj.mobile && classObj.openSidebar" | |||||
| class="drawer-bg" | |||||
| @click="handleOutsideClick" | |||||
| ></div> | |||||
| <Sidebar class="sidebar-container" /> | |||||
| <div :class="{ hasTagsView: showTagsView }" class="main-container"> | |||||
| <div | |||||
| :class="{ 'fixed-header': fixedHeader }" | |||||
| style="box-shadow: rgba(0, 0, 0, 0.05) 0px 4px 4px; height: 80px" | |||||
| > | |||||
| <navbar /> | |||||
| <tags-view v-if="showTagsView" /> | |||||
| </div> | |||||
| <!-- 主页面 --> | |||||
| <app-main /> | |||||
| </div> | |||||
| </div> | |||||
| </template> | |||||
| <script setup lang="ts"> | |||||
| import { computed, watchEffect } from "vue"; | |||||
| import { useWindowSize } from "@vueuse/core"; | |||||
| import { AppMain, Navbar } from "./components/index"; | |||||
| import SignSucceed from "../views/signSucceed/index.vue"; | |||||
| import Sidebar from "./components/Sidebar/index.vue"; | |||||
| import { useAppStore } from "@/store/modules/app"; | |||||
| import { useSettingsStore } from "@/store/modules/settings"; | |||||
| import { useRoute, useRouter } from "vue-router"; | |||||
| const route = useRoute(); | |||||
| const { params } = route; | |||||
| const { width } = useWindowSize(); | |||||
| /** | |||||
| * 响应式布局容器固定宽度 | |||||
| * | |||||
| * 大屏(>=1200px) | |||||
| * 中屏(>=992px) | |||||
| * 小屏(>=768px) | |||||
| */ | |||||
| const WIDTH = 992; | |||||
| const appStore = useAppStore(); | |||||
| const settingsStore = useSettingsStore(); | |||||
| const fixedHeader = computed(() => settingsStore.fixedHeader); | |||||
| const showTagsView = computed(() => settingsStore.tagsView); | |||||
| const showSettings = computed(() => settingsStore.showSettings); | |||||
| const classObj = computed(() => ({ | |||||
| hideSidebar: !appStore.sidebar.opened, | |||||
| openSidebar: appStore.sidebar.opened, | |||||
| withoutAnimation: appStore.sidebar.withoutAnimation, | |||||
| mobile: appStore.device === "mobile", | |||||
| })); | |||||
| watchEffect(() => { | |||||
| if (width.value < WIDTH) { | |||||
| appStore.toggleDevice("mobile"); | |||||
| appStore.closeSideBar(true); | |||||
| } else { | |||||
| appStore.toggleDevice("desktop"); | |||||
| if (width.value >= 1200) { | |||||
| //大屏 | |||||
| appStore.openSideBar(true); | |||||
| } else { | |||||
| appStore.closeSideBar(true); | |||||
| } | |||||
| } | |||||
| }); | |||||
| function handleOutsideClick() { | |||||
| appStore.closeSideBar(false); | |||||
| } | |||||
| onMounted(() => {}); | |||||
| </script> | |||||
| <style lang="scss" scoped> | |||||
| .app-wrapper { | |||||
| &::after { | |||||
| display: table; | |||||
| clear: both; | |||||
| content: ""; | |||||
| } | |||||
| position: relative; | |||||
| width: 100%; | |||||
| height: 100%; | |||||
| e &.mobile.openSidebar { | |||||
| position: fixed; | |||||
| top: 0; | |||||
| } | |||||
| } | |||||
| .fixed-header { | |||||
| position: fixed; | |||||
| top: 0; | |||||
| right: 0; | |||||
| z-index: 9; | |||||
| width: calc(100% - #{$sideBarWidth}); | |||||
| transition: width 0.28s; | |||||
| } | |||||
| .hideSidebar .fixed-header { | |||||
| width: calc(100% - 54px); | |||||
| } | |||||
| .mobile .fixed-header { | |||||
| width: 100%; | |||||
| } | |||||
| .drawer-bg { | |||||
| position: absolute; | |||||
| top: 0; | |||||
| z-index: 999; | |||||
| width: 100%; | |||||
| height: 100%; | |||||
| // background: #1b213a; | |||||
| background: #000; | |||||
| opacity: 0.3; | |||||
| } | |||||
| </style> | |||||
| @@ -11,19 +11,69 @@ | |||||
| </div> | </div> | ||||
| <!-- 侧边路由列表 --> | <!-- 侧边路由列表 --> | ||||
| <div class="myRouter"> | <div class="myRouter"> | ||||
| <div class="myRouter-item" @click="router.push('/createVideo')"> | |||||
| <!-- 动态路由 --> | |||||
| <div | |||||
| v-for="item in MenuList" | |||||
| :key="item.id" | |||||
| class="myRouter-item" | |||||
| @click="showChildrenRouter = item.name" | |||||
| > | |||||
| <div class="icon"> | |||||
| <el-icon><i-ep-edit /></el-icon> | |||||
| <span>{{ item.name }}</span> | |||||
| </div> | |||||
| <div | |||||
| v-show="showChildrenRouter == item.name" | |||||
| v-for="childrens in item.children" | |||||
| :key="childrens.id" | |||||
| class="childrenRouter" | |||||
| @click="router.push(`/${childrens.url}`)" | |||||
| > | |||||
| {{ childrens.name }} | |||||
| </div> | |||||
| </div> | |||||
| <!-- 固定路由 --> | |||||
| <div class="myRouter-item" @click="router.push('/model')"> | |||||
| <div class="icon"> | |||||
| <el-icon><i-ep-edit /></el-icon> | |||||
| {{ $t("modelMangage.title") }} | |||||
| </div> | |||||
| </div> | |||||
| <div class="myRouter-item" @click="router.push('/businessList')"> | |||||
| <div class="icon"> | |||||
| <el-icon><i-ep-edit /></el-icon> | |||||
| {{ $t("businessMangage.title") }} | |||||
| </div> | |||||
| </div> | |||||
| <div class="myRouter-item" @click="router.push('/keyList')"> | |||||
| <div class="icon"> | |||||
| <el-icon><i-ep-edit /></el-icon> | |||||
| {{ $t("keyMangage.title") }} | |||||
| </div> | |||||
| </div> | |||||
| <div class="myRouter-item" @click="router.push('/model')"> | |||||
| <div class="icon"> | <div class="icon"> | ||||
| <el-icon><i-ep-edit /></el-icon> | <el-icon><i-ep-edit /></el-icon> | ||||
| {{ $t("priceMangage.title") }} | |||||
| </div> | |||||
| </div> | |||||
| <div class="myRouter-item" @click="router.push('/model')"> | |||||
| <div class="icon"> | |||||
| <el-icon><i-ep-edit /></el-icon> | |||||
| {{ $t("dataCount.title") }} | |||||
| </div> | </div> | ||||
| {{ $t("modelMangage.title") }} | |||||
| </div> | </div> | ||||
| <div class="bottomBtx"> | <div class="bottomBtx"> | ||||
| <div class="myRouter-item" @click="router.push('/myAPI')"> | |||||
| <div class="myRouter-item" @click="router.push('/model')"> | |||||
| <div class="icon"> | <div class="icon"> | ||||
| <el-icon><i-ep-DocumentAdd /></el-icon> | <el-icon><i-ep-DocumentAdd /></el-icon> | ||||
| {{ $t("apiMangage.title") }} | |||||
| </div> | </div> | ||||
| {{ $t("apiMangage.title") }} | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -77,7 +127,7 @@ import { useAppStore } from "@/store/modules/app"; | |||||
| // import { useSettingsStore } from "@/store/modules/settings"; | // import { useSettingsStore } from "@/store/modules/settings"; | ||||
| import { useRoute, useRouter } from "vue-router"; | import { useRoute, useRouter } from "vue-router"; | ||||
| import { useI18n } from "vue-i18n"; | import { useI18n } from "vue-i18n"; | ||||
| import { getMenuNavApi } from "@/apis/Permission.js"; | |||||
| import { userInfoModules } from "@/store/modules/userInfo"; | import { userInfoModules } from "@/store/modules/userInfo"; | ||||
| const userInfoPinia = userInfoModules(); | const userInfoPinia = userInfoModules(); | ||||
| @@ -138,12 +188,31 @@ function handleOutsideClick() { | |||||
| appStore.closeSideBar(false); | appStore.closeSideBar(false); | ||||
| } | } | ||||
| onMounted(() => {}); | |||||
| onMounted(() => { | |||||
| getMenuNavFunc(); | |||||
| }); | |||||
| //#region 联系我们弹窗 | //#region 联系我们弹窗 | ||||
| const showTalkUsDialog = ref(false); | const showTalkUsDialog = ref(false); | ||||
| const updateShowTalkUsDialog = (newValue: any) => { | const updateShowTalkUsDialog = (newValue: any) => { | ||||
| showTalkUsDialog.value = newValue; | showTalkUsDialog.value = newValue; | ||||
| }; | }; | ||||
| //#endregion ------------------------------------ | |||||
| //#region 获取路由列表 | |||||
| const MenuList = ref([{ id: "", name: "" }]); | |||||
| async function getMenuNavFunc() { | |||||
| try { | |||||
| const res = await getMenuNavApi(); | |||||
| MenuList.value = res.data.menuList; | |||||
| } catch (error) { | |||||
| console.log(error); | |||||
| } | |||||
| } | |||||
| //#endregion ------------------------------------ | |||||
| //#region 路由及子路由 | |||||
| const showChildrenRouter = ref(""); | |||||
| //#endregion ------------------------------------ | //#endregion ------------------------------------ | ||||
| </script> | </script> | ||||
| @@ -179,10 +248,10 @@ const updateShowTalkUsDialog = (newValue: any) => { | |||||
| bottom: 30px; | bottom: 30px; | ||||
| } | } | ||||
| &-item { | &-item { | ||||
| display: flex; | |||||
| // display: flex; | |||||
| width: 100%; | width: 100%; | ||||
| height: 50px; | |||||
| padding-left: 10px; | |||||
| // height: 50px; | |||||
| // padding-left: 10px; | |||||
| font-size: 20px; | font-size: 20px; | ||||
| font-weight: 500; | font-weight: 500; | ||||
| line-height: 50px; | line-height: 50px; | ||||
| @@ -193,14 +262,20 @@ const updateShowTalkUsDialog = (newValue: any) => { | |||||
| border-radius: 5px; | border-radius: 5px; | ||||
| margin-bottom: 20px; | margin-bottom: 20px; | ||||
| margin-right: 20px; | margin-right: 20px; | ||||
| overflow: hidden; | |||||
| .icon { | .icon { | ||||
| width: 40px; | |||||
| height: 40px; | |||||
| display: flex; | |||||
| color: #fff; | color: #fff; | ||||
| border-radius: 50%; | border-radius: 50%; | ||||
| margin-right: 10px; | |||||
| width: 100%; | |||||
| height: 50px; | |||||
| line-height: 50px; | |||||
| .el-icon { | .el-icon { | ||||
| margin-left: 10px; | |||||
| margin-top: 12px; | |||||
| margin-right: 10px; | |||||
| width: 25px; | width: 25px; | ||||
| height: 25px; | height: 25px; | ||||
| font-size: 25px; | font-size: 25px; | ||||
| @@ -210,11 +285,22 @@ const updateShowTalkUsDialog = (newValue: any) => { | |||||
| vertical-align: sub; | vertical-align: sub; | ||||
| } | } | ||||
| } | } | ||||
| .childrenRouter { | |||||
| cursor: pointer; | |||||
| transition: all 0.3s; | |||||
| } | |||||
| .childrenRouter:hover { | |||||
| color: #ffffff; | |||||
| background-color: #000000; | |||||
| } | |||||
| &:hover { | &:hover { | ||||
| // background: rgba(255, 255, 255, 0.2); | // background: rgba(255, 255, 255, 0.2); | ||||
| color: #000; | color: #000; | ||||
| background: #fff; | background: #fff; | ||||
| .icon { | |||||
| color: #000; | |||||
| } | |||||
| .el-icon { | .el-icon { | ||||
| // color: #d4d0ff; | // color: #d4d0ff; | ||||
| color: #000; | color: #000; | ||||
| @@ -9,35 +9,36 @@ NProgress.configure({ showSpinner: false }); // 进度条 | |||||
| const permissionStore = usePermissionStoreHook(); | const permissionStore = usePermissionStoreHook(); | ||||
| // 白名单路由 | // 白名单路由 | ||||
| const whiteList = ["/login", "/signSucceed",'/createVideo','/moveImg']; | |||||
| const whiteList = ["/login", "/signSucceed", "/createVideo", "/moveImg"]; | |||||
| router.beforeEach(async (to, from, next) => { | router.beforeEach(async (to, from, next) => { | ||||
| NProgress.start(); | NProgress.start(); | ||||
| const AccessToken = localStorage.getItem("AccessToken"); | const AccessToken = localStorage.getItem("AccessToken"); | ||||
| next(); | |||||
| // 已登录 | // 已登录 | ||||
| if (AccessToken) { | |||||
| // 重置密码时可以去往login页面 | |||||
| if ((to.params.type as string) == "4") { | |||||
| next(); | |||||
| } | |||||
| if (to.query.resetPwd) { | |||||
| next(); | |||||
| } | |||||
| if (to.path === "/login") { | |||||
| next({ path: "/createVideo" }); | |||||
| } else { | |||||
| next(); | |||||
| } | |||||
| // 未登录 | |||||
| } else { | |||||
| // 未登录可以访问白名单页面 | |||||
| if (whiteList.indexOf(to.path) !== -1) { | |||||
| next(); | |||||
| } else { | |||||
| // 不在白名单内,跳转登录页 | |||||
| next({ path: "/login" }); | |||||
| } | |||||
| } | |||||
| // if (AccessToken) { | |||||
| // // 重置密码时可以去往login页面 | |||||
| // if ((to.params.type as string) == "4") { | |||||
| // next(); | |||||
| // } | |||||
| // if (to.query.resetPwd) { | |||||
| // next(); | |||||
| // } | |||||
| // if (to.path === "/login") { | |||||
| // next({ path: "/createVideo" }); | |||||
| // } else { | |||||
| // next(); | |||||
| // } | |||||
| // // 未登录 | |||||
| // } else { | |||||
| // // 未登录可以访问白名单页面 | |||||
| // if (whiteList.indexOf(to.path) !== -1) { | |||||
| // next(); | |||||
| // } else { | |||||
| // // 不在白名单内,跳转登录页 | |||||
| // next({ path: "/login" }); | |||||
| // } | |||||
| // } | |||||
| }); | }); | ||||
| router.afterEach(() => { | router.afterEach(() => { | ||||
| @@ -5,87 +5,89 @@ export const Layout = () => import("@/layout/index.vue"); | |||||
| // 静态路由 | // 静态路由 | ||||
| export const constantRoutes: RouteRecordRaw[] = [ | export const constantRoutes: RouteRecordRaw[] = [ | ||||
| // 登录 | // 登录 | ||||
| { | { | ||||
| path: "/login", | path: "/login", | ||||
| component: () => import("@/views/login/index.vue"), | component: () => import("@/views/login/index.vue"), | ||||
| meta: { hidden: true }, | meta: { hidden: true }, | ||||
| name:'login' | |||||
| name: "login", | |||||
| }, | }, | ||||
| { | { | ||||
| path: "/signSucceed", | path: "/signSucceed", | ||||
| component: () => import("@/views/signSucceed/index.vue"), | component: () => import("@/views/signSucceed/index.vue"), | ||||
| meta: { hidden: true }, | meta: { hidden: true }, | ||||
| }, | }, | ||||
| // 创建视频 | |||||
| { | { | ||||
| path: "/", | path: "/", | ||||
| component: Layout, | component: Layout, | ||||
| redirect: "/createVideo", | |||||
| redirect: "/model", | |||||
| children: [ | children: [ | ||||
| { | { | ||||
| path: "createVideo", | |||||
| component: () => import("@/views/createVideo/index.vue"), | |||||
| name: "createVideo", | |||||
| path: "model", | |||||
| component: () => import("@/views/mangage/model.vue"), | |||||
| name: "model", | |||||
| meta: { | meta: { | ||||
| title: "createVideo", | |||||
| title: "model", | |||||
| icon: "homepage", | icon: "homepage", | ||||
| affix: true, | affix: true, | ||||
| name: "createVideo.title", | |||||
| name: "modelMangage.title", | |||||
| }, | }, | ||||
| }, | }, | ||||
| ], | ], | ||||
| }, | }, | ||||
| // 视频列表 | |||||
| { | { | ||||
| path: "/", | path: "/", | ||||
| component: Layout, | component: Layout, | ||||
| redirect: "/myCreating", | |||||
| redirect: "/keyList", | |||||
| children: [ | children: [ | ||||
| { | { | ||||
| path: "myCreating", | |||||
| component: () => import("@/views/myCreating/index.vue"), | |||||
| name: "myCreating", | |||||
| path: "keyList", | |||||
| component: () => import("@/views/keys/keyList.vue"), | |||||
| name: "keyList", | |||||
| meta: { | meta: { | ||||
| title: "myCreating", | |||||
| title: "keyList", | |||||
| icon: "homepage", | icon: "homepage", | ||||
| affix: true, | affix: true, | ||||
| name: "myCreating.title", | |||||
| name: "keyMangage.list", | |||||
| }, | }, | ||||
| }, | }, | ||||
| ], | ], | ||||
| }, { | |||||
| }, | |||||
| { | |||||
| path: "/", | path: "/", | ||||
| component: Layout, | component: Layout, | ||||
| redirect: "/myStore", | |||||
| redirect: "/keyCheck", | |||||
| children: [ | children: [ | ||||
| { | { | ||||
| path: "myStore", | |||||
| component: () => import("@/views/myStore/index.vue"), | |||||
| name: "myStore", | |||||
| path: "keyCheck", | |||||
| component: () => import("@/views/keys/keyCheck.vue"), | |||||
| name: "keyCheck", | |||||
| meta: { | meta: { | ||||
| title: "myStore", | |||||
| title: "keyCheck", | |||||
| icon: "homepage", | icon: "homepage", | ||||
| affix: true, | affix: true, | ||||
| name: "myStore.title", | |||||
| name: "keyMangage.title", | |||||
| }, | }, | ||||
| }, | }, | ||||
| ], | ], | ||||
| }, { | |||||
| }, | |||||
| { | |||||
| path: "/", | path: "/", | ||||
| component: Layout, | component: Layout, | ||||
| redirect: "/myAPI", | |||||
| redirect: "/businessList", | |||||
| children: [ | children: [ | ||||
| { | { | ||||
| path: "myAPI", | |||||
| component: () => import("@/views/myAPI/index.vue"), | |||||
| name: "myAPI", | |||||
| path: "businessList", | |||||
| component: () => import("@/views/business/businessList.vue"), | |||||
| name: "businessList", | |||||
| meta: { | meta: { | ||||
| title: "myAPI", | |||||
| title: "businessList", | |||||
| icon: "homepage", | icon: "homepage", | ||||
| affix: true, | affix: true, | ||||
| name: "API.title", | |||||
| name: "keyMangage.list", | |||||
| }, | }, | ||||
| }, | }, | ||||
| ], | ], | ||||
| @@ -93,22 +95,58 @@ export const constantRoutes: RouteRecordRaw[] = [ | |||||
| { | { | ||||
| path: "/", | path: "/", | ||||
| component: Layout, | component: Layout, | ||||
| redirect: "/moveImg", | |||||
| redirect: "/businessCheck", | |||||
| children: [ | children: [ | ||||
| { | { | ||||
| path: "moveImg", | |||||
| component: () => import("@/views/moveImg/index.vue"), | |||||
| name: "moveImg", | |||||
| path: "businessCheck", | |||||
| component: () => import("@/views/business/businessCheck.vue"), | |||||
| name: "businessCheck", | |||||
| meta: { | meta: { | ||||
| title: "moveImg", | |||||
| title: "businessCheck", | |||||
| icon: "homepage", | icon: "homepage", | ||||
| affix: true, | affix: true, | ||||
| name: "moveImg.title", | |||||
| name: "keyMangage.title", | |||||
| }, | |||||
| }, | |||||
| ], | |||||
| }, | |||||
| // 系统设置路由 | |||||
| { | |||||
| path: "/", | |||||
| component: Layout, | |||||
| redirect: "/userList", | |||||
| children: [ | |||||
| { | |||||
| path: "userList", | |||||
| component: () => import("@/views/dict/index.vue"), | |||||
| name: "userList", | |||||
| meta: { | |||||
| title: "userList", | |||||
| icon: "homepage", | |||||
| affix: true, | |||||
| name: "userListMangage.title", | |||||
| }, | |||||
| }, | |||||
| ], | |||||
| }, | |||||
| { | |||||
| path: "/", | |||||
| component: Layout, | |||||
| redirect: "/ruleList", | |||||
| children: [ | |||||
| { | |||||
| path: "ruleList", | |||||
| component: () => import("@/views/mangage/ruleList.vue"), | |||||
| name: "ruleList", | |||||
| meta: { | |||||
| title: "ruleList", | |||||
| icon: "homepage", | |||||
| affix: true, | |||||
| name: "ruleListMangage.title", | |||||
| }, | }, | ||||
| }, | }, | ||||
| ], | ], | ||||
| }, | }, | ||||
| ]; | ]; | ||||
| /** | /** | ||||
| @@ -2,9 +2,6 @@ | |||||
| export {} | export {} | ||||
| declare global { | declare global { | ||||
| const EffectScope: typeof import('vue')['EffectScope'] | const EffectScope: typeof import('vue')['EffectScope'] | ||||
| const ElForm: typeof import('element-plus/es')['ElForm'] | |||||
| const ElMessage: typeof import('element-plus/es')['ElMessage'] | |||||
| const ElMessageBox: typeof import('element-plus/es')['ElMessageBox'] | |||||
| const asyncComputed: typeof import('@vueuse/core')['asyncComputed'] | const asyncComputed: typeof import('@vueuse/core')['asyncComputed'] | ||||
| const autoResetRef: typeof import('@vueuse/core')['autoResetRef'] | const autoResetRef: typeof import('@vueuse/core')['autoResetRef'] | ||||
| const computed: typeof import('vue')['computed'] | const computed: typeof import('vue')['computed'] | ||||
| @@ -271,9 +268,6 @@ import { UnwrapRef } from 'vue' | |||||
| declare module 'vue' { | declare module 'vue' { | ||||
| interface ComponentCustomProperties { | interface ComponentCustomProperties { | ||||
| readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']> | readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']> | ||||
| readonly ElForm: UnwrapRef<typeof import('element-plus/es')['ElForm']> | |||||
| readonly ElMessage: UnwrapRef<typeof import('element-plus/es')['ElMessage']> | |||||
| readonly ElMessageBox: UnwrapRef<typeof import('element-plus/es')['ElMessageBox']> | |||||
| readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']> | readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']> | ||||
| readonly autoResetRef: UnwrapRef<typeof import('@vueuse/core')['autoResetRef']> | readonly autoResetRef: UnwrapRef<typeof import('@vueuse/core')['autoResetRef']> | ||||
| readonly computed: UnwrapRef<typeof import('vue')['computed']> | readonly computed: UnwrapRef<typeof import('vue')['computed']> | ||||
| @@ -13,38 +13,10 @@ declare module '@vue/runtime-core' { | |||||
| CutImg1: typeof import('./../components/cutImg1.vue')['default'] | CutImg1: typeof import('./../components/cutImg1.vue')['default'] | ||||
| EditPosition: typeof import('./../components/EditPosition.vue')['default'] | EditPosition: typeof import('./../components/EditPosition.vue')['default'] | ||||
| 'EditPosition copy': typeof import('./../components/EditPosition copy.vue')['default'] | 'EditPosition copy': typeof import('./../components/EditPosition copy.vue')['default'] | ||||
| ElButton: typeof import('element-plus/es')['ElButton'] | |||||
| ElDialog: typeof import('element-plus/es')['ElDialog'] | |||||
| ElDropdown: typeof import('element-plus/es')['ElDropdown'] | |||||
| ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem'] | |||||
| ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu'] | |||||
| ElForm: typeof import('element-plus/es')['ElForm'] | |||||
| ElFormItem: typeof import('element-plus/es')['ElFormItem'] | |||||
| ElIcon: typeof import('element-plus/es')['ElIcon'] | ElIcon: typeof import('element-plus/es')['ElIcon'] | ||||
| ElInput: typeof import('element-plus/es')['ElInput'] | |||||
| ElInputNumber: typeof import('element-plus/es')['ElInputNumber'] | |||||
| ElOption: typeof import('element-plus/es')['ElOption'] | |||||
| ElPagination: typeof import('element-plus/es')['ElPagination'] | |||||
| ElSelect: typeof import('element-plus/es')['ElSelect'] | |||||
| ElSwitch: typeof import('element-plus/es')['ElSwitch'] | |||||
| ElTooltip: typeof import('element-plus/es')['ElTooltip'] | |||||
| ElUpload: typeof import('element-plus/es')['ElUpload'] | |||||
| GithubCorner: typeof import('./../components/GithubCorner/index.vue')['default'] | GithubCorner: typeof import('./../components/GithubCorner/index.vue')['default'] | ||||
| Hamburger: typeof import('./../components/Hamburger/index.vue')['default'] | Hamburger: typeof import('./../components/Hamburger/index.vue')['default'] | ||||
| IconSelect: typeof import('./../components/IconSelect/index.vue')['default'] | IconSelect: typeof import('./../components/IconSelect/index.vue')['default'] | ||||
| IEpCloseBold: typeof import('~icons/ep/close-bold')['default'] | |||||
| IEpDelete: typeof import('~icons/ep/delete')['default'] | |||||
| IEpDocumentAdd: typeof import('~icons/ep/document-add')['default'] | |||||
| IEpDownload: typeof import('~icons/ep/download')['default'] | |||||
| IEpEdit: typeof import('~icons/ep/edit')['default'] | |||||
| IEpGoods: typeof import('~icons/ep/goods')['default'] | |||||
| IEpLoading: typeof import('~icons/ep/loading')['default'] | |||||
| IEpLock: typeof import('~icons/ep/lock')['default'] | |||||
| IEpMenu: typeof import('~icons/ep/menu')['default'] | |||||
| IEpPhone: typeof import('~icons/ep/phone')['default'] | |||||
| IEpSearch: typeof import('~icons/ep/search')['default'] | |||||
| IEpUser: typeof import('~icons/ep/user')['default'] | |||||
| IEpVideoPlay: typeof import('~icons/ep/video-play')['default'] | |||||
| LangSelect: typeof import('./../components/LangSelect/index.vue')['default'] | LangSelect: typeof import('./../components/LangSelect/index.vue')['default'] | ||||
| MultiUpload: typeof import('./../components/Upload/MultiUpload.vue')['default'] | MultiUpload: typeof import('./../components/Upload/MultiUpload.vue')['default'] | ||||
| MyLoading: typeof import('./../components/myLoading.vue')['default'] | MyLoading: typeof import('./../components/myLoading.vue')['default'] | ||||
| @@ -58,7 +30,4 @@ declare module '@vue/runtime-core' { | |||||
| TalkUs: typeof import('./../components/talkUs.vue')['default'] | TalkUs: typeof import('./../components/talkUs.vue')['default'] | ||||
| WangEditor: typeof import('./../components/WangEditor/index.vue')['default'] | WangEditor: typeof import('./../components/WangEditor/index.vue')['default'] | ||||
| } | } | ||||
| export interface ComponentCustomProperties { | |||||
| vInfiniteScroll: typeof import('element-plus/es')['ElInfiniteScroll'] | |||||
| } | |||||
| } | } | ||||
| @@ -1,67 +0,0 @@ | |||||
| import axios from 'axios' | |||||
| import router from '@/router/index' | |||||
| import { ElMessage } from 'element-plus' | |||||
| // ElMessage | |||||
| import { userInfoModules } from "@/store/modules/userInfo"; | |||||
| // import stores from '@/store/index' | |||||
| import { store } from '@/store/index'; // 因为不是在setup环境而是js中,必须重新初始化加载store | |||||
| const userInfoPinia = userInfoModules(store); //pinia | |||||
| // 开发环境需以 "/api" 拼接,其他环境需以 "/C" 拼接 | |||||
| const env = process.env.NODE_ENV == 'development' ? "/api" : "/C" | |||||
| // console.log(process.env.NODE_ENV, 'env') | |||||
| /** | |||||
| * @description:发送Axios请求 | |||||
| */ | |||||
| const request = axios.create({ | |||||
| baseURL: env, | |||||
| timeout: 15000 | |||||
| }) | |||||
| // 请求拦截器 | |||||
| request.interceptors.request.use( | |||||
| function (config) { | |||||
| // 给所有授权的请求提供token | |||||
| const AccessToken = localStorage.getItem("AccessToken") | |||||
| if (AccessToken) { | |||||
| config.headers.token = AccessToken | |||||
| } | |||||
| return config | |||||
| }, | |||||
| function (error) { | |||||
| // 操作 | |||||
| return Promise.reject(error) | |||||
| } | |||||
| ) | |||||
| // 响应拦截器 | |||||
| request.interceptors.response.use( | |||||
| function (response) { | |||||
| let code = response.data.code | |||||
| // 当token无效(过期或损坏)时 1053为未登录 | |||||
| if (code == 1052 || code == 1053) { | |||||
| localStorage.removeItem("AccessToken"); | |||||
| router.push("/login"); | |||||
| ElMessage.error("登录过期,请重新登录!"); | |||||
| return | |||||
| // 弹出错误 | |||||
| } else if (code != 200) { | |||||
| if (code == 500) { | |||||
| ElMessage.error("系统异常,请稍后再试"); | |||||
| // 其他错误 | |||||
| } else { | |||||
| return Promise.reject(response.data) | |||||
| } | |||||
| } else { | |||||
| // 正常返回 | |||||
| return response.data | |||||
| } | |||||
| }, | |||||
| function (error) { | |||||
| } | |||||
| ) | |||||
| export default request | |||||
| @@ -11,8 +11,8 @@ const appStore = useAppStore(store); //pinia | |||||
| const userInfoPinia = userInfoModules(store); //pinia | const userInfoPinia = userInfoModules(store); //pinia | ||||
| // const userInfoPinia = userInfoModules(store); //pinia | // const userInfoPinia = userInfoModules(store); //pinia | ||||
| // 开发环境需以 "/api" 拼接,其他环境需以 "/C" 拼接 | // 开发环境需以 "/api" 拼接,其他环境需以 "/C" 拼接 | ||||
| const env = process.env.NODE_ENV == 'development' ? "/api" : "/C" | |||||
| // const env = process.env.NODE_ENV == 'development' ? "" : "" | |||||
| // const env = process.env.NODE_ENV == 'development' ? "/api" : "/C" | |||||
| const env = process.env.NODE_ENV == 'development' ? "/A" : "/A" | |||||
| console.log(env) | console.log(env) | ||||
| /** | /** | ||||
| @@ -60,7 +60,7 @@ request.interceptors.response.use( | |||||
| let code = response.data.code | let code = response.data.code | ||||
| // 当token无效(过期或损坏)时 1053为未登录 | // 当token无效(过期或损坏)时 1053为未登录 | ||||
| if (code == 1052 || code == 1053) { | if (code == 1052 || code == 1053) { | ||||
| localStorage.removeItem("AccessToken"); | |||||
| // localStorage.removeItem("AccessToken"); | |||||
| router.push("/login"); | router.push("/login"); | ||||
| // ElMessage.error("登录过期,请重新登录!"); | // ElMessage.error("登录过期,请重新登录!"); | ||||
| // ElMessage.error($t('tips.tokenExpired')); | // ElMessage.error($t('tips.tokenExpired')); | ||||
| @@ -0,0 +1,301 @@ | |||||
| <template> | |||||
| <div class="page flex justify-around"> | |||||
| <div class="card"> | |||||
| <div class="title">密钥详情</div> | |||||
| <div class="key"> | |||||
| <span class="text">{{ $t("keyMangage.name") }}:{{ name }}</span> | |||||
| </div> | |||||
| <!-- appId --> | |||||
| <div class="key"> | |||||
| <span class="text">appId:{{ showCode }}</span> | |||||
| <span class="showOrHide" @click="showHideCode">{{ showText }}</span> | |||||
| <span v-if="showText == '隐藏'" class="copy" @click="copyKey(showCode)" | |||||
| >复制</span | |||||
| > | |||||
| </div> | |||||
| <!-- appKey --> | |||||
| <div class="key"> | |||||
| <span class="text">appKey:{{ showCodeII }}</span> | |||||
| <span class="showOrHide" @click="showHideCodeII">{{ showTextII }}</span> | |||||
| <span | |||||
| v-if="showTextII == '隐藏'" | |||||
| class="copy" | |||||
| @click="copyKey(showCodeII)" | |||||
| >复制</span | |||||
| > | |||||
| </div> | |||||
| <!-- signKey --> | |||||
| <div class="key"> | |||||
| <span class="text">signKey:{{ showCodeIII }}</span> | |||||
| <span class="showOrHide" @click="showHideCodeIII(showCodeIII)">{{ | |||||
| showTextIII | |||||
| }}</span> | |||||
| <span v-if="showTextIII == '隐藏'" class="copy" @click="copyKey" | |||||
| >复制</span | |||||
| > | |||||
| </div> | |||||
| <div class="keyStatus"> | |||||
| <span class="text" | |||||
| >密钥状态: | |||||
| <span v-if="!keyStatus" style="color: #36db43">正常</span> | |||||
| <span v-else style="color: #ff0000">失效</span> | |||||
| </span> | |||||
| <span v-if="keyStatus" class="fail" @click="changeStatus(0)">恢复</span> | |||||
| <span v-if="!keyStatus" class="success" @click="changeStatus(1)" | |||||
| >作废</span | |||||
| > | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </template> | |||||
| <!-- videoType==1为竖,==2为横 --> | |||||
| <script setup> | |||||
| //#region 导入 | |||||
| import { linkEmits } from "element-plus"; | |||||
| import { getCurrentInstance } from "vue"; | |||||
| import { useI18n } from "vue-i18n"; | |||||
| import { useRoute, useRouter } from "vue-router"; | |||||
| import { getKeyByIdApi, updateKeyStatusApi } from "@/api_mangage/key"; | |||||
| const route = useRoute(); | |||||
| const router = useRouter(); | |||||
| const { locale } = useI18n(); | |||||
| const lanChange = ref(locale); | |||||
| const AccessToken = localStorage.getItem("AccessToken"); // 判断有没有登录 | |||||
| const keyId = ref(""); | |||||
| const name = ref(""); | |||||
| const appId = ref(""); | |||||
| const hideCode = ref(""); | |||||
| const showCode = ref(""); | |||||
| const showText = ref("查看"); | |||||
| const showHideCode = () => { | |||||
| if (showText.value == "查看") { | |||||
| showText.value = "隐藏"; | |||||
| showCode.value = appId.value; | |||||
| } else { | |||||
| showText.value = "查看"; | |||||
| showCode.value = hideCode.value; | |||||
| } | |||||
| }; | |||||
| const appKey = ref(""); | |||||
| const hideCodeII = ref(""); | |||||
| const showCodeII = ref(""); | |||||
| const showTextII = ref("查看"); | |||||
| const showHideCodeII = () => { | |||||
| if (showTextII.value == "查看") { | |||||
| showTextII.value = "隐藏"; | |||||
| showCodeII.value = appKey.value; | |||||
| } else { | |||||
| showTextII.value = "查看"; | |||||
| showCodeII.value = hideCodeII.value; | |||||
| } | |||||
| }; | |||||
| const signKey = ref(""); | |||||
| const hideCodeIII = ref(""); | |||||
| const showCodeIII = ref(""); | |||||
| const showTextIII = ref("查看"); | |||||
| const showHideCodeIII = () => { | |||||
| if (showTextIII.value == "查看") { | |||||
| showTextIII.value = "隐藏"; | |||||
| showCodeIII.value = signKey.value; | |||||
| } else { | |||||
| showTextIII.value = "查看"; | |||||
| showCodeIII.value = hideCodeIII.value; | |||||
| } | |||||
| }; | |||||
| const getKeyFunc = async () => { | |||||
| const id = keyId.value; | |||||
| try { | |||||
| const res = await getKeyByIdApi(id); | |||||
| console.log(res, "res"); | |||||
| appId.value = res.data.appId; | |||||
| appKey.value = res.data.appKey; | |||||
| signKey.value = res.data.signKey; | |||||
| keyStatus.value = res.data.status; | |||||
| name.value = res.data.name; | |||||
| const len = appId.value.length; | |||||
| const lenII = appKey.value.length; | |||||
| const lenIII = signKey.value.length; | |||||
| let code = ""; | |||||
| let codeII = ""; | |||||
| let codeIII = ""; | |||||
| for (let index = 0; index < len; index++) { | |||||
| code += "*"; | |||||
| } | |||||
| for (let index = 0; index < lenII; index++) { | |||||
| codeII += "*"; | |||||
| } | |||||
| for (let index = 0; index < lenIII; index++) { | |||||
| codeIII += "*"; | |||||
| } | |||||
| hideCode.value = code; | |||||
| showCode.value = code; | |||||
| hideCodeII.value = codeII; | |||||
| showCodeII.value = codeII; | |||||
| hideCodeIII.value = codeIII; | |||||
| showCodeIII.value = codeIII; | |||||
| } catch (error) { | |||||
| console.log(error, "err"); | |||||
| } | |||||
| }; | |||||
| const copyKey = (text) => { | |||||
| navigator.clipboard | |||||
| .writeText(text) | |||||
| .then(() => { | |||||
| ElMessage.success("复制成功!"); | |||||
| }) | |||||
| .catch(() => { | |||||
| ElMessage.error("复制失败!"); | |||||
| }); | |||||
| }; | |||||
| const keyStatus = ref(""); | |||||
| const changeStatus = async (status) => { | |||||
| const id = keyId.value; | |||||
| if (status) { | |||||
| ElMessageBox.confirm("此操作将作废密钥,确定?", "Warning", { | |||||
| confirmButtonText: "确定", | |||||
| cancelButtonText: "取消", | |||||
| type: "warning", | |||||
| }) | |||||
| .then(async () => { | |||||
| try { | |||||
| const res = await updateKeyStatusApi(id, status); | |||||
| if (res.code == 200) { | |||||
| ElMessage({ | |||||
| type: "success", | |||||
| message: "作废成功!", | |||||
| }); | |||||
| getKeyFunc(); | |||||
| } | |||||
| } catch (error) { | |||||
| console.log(error, "err"); | |||||
| } | |||||
| }) | |||||
| .catch(() => {}); | |||||
| } else { | |||||
| try { | |||||
| const res = await updateKeyStatusApi(id, status); | |||||
| if (res.code == 200) { | |||||
| ElMessage({ | |||||
| type: "success", | |||||
| message: "恢复成功!", | |||||
| }); | |||||
| getKeyFunc(); | |||||
| } | |||||
| } catch (error) { | |||||
| console.log(error, "err"); | |||||
| } | |||||
| } | |||||
| }; | |||||
| onMounted(() => { | |||||
| keyId.value = route.query.id; | |||||
| getKeyFunc(); | |||||
| }); | |||||
| </script> | |||||
| <style lang="scss" scoped> | |||||
| .page { | |||||
| height: calc(100vh - 80px); | |||||
| // height: calc(100vh - 80px); | |||||
| background-color: #ffffff; | |||||
| border-radius: 30px 0 0 0; | |||||
| overflow: hidden; | |||||
| .card { | |||||
| width: 80%; | |||||
| height: 70%; | |||||
| background-color: #fafafa; | |||||
| margin-top: 10vh; | |||||
| border-radius: 5vh; | |||||
| box-shadow: #0000002e 1px 1px 1px 1px; | |||||
| .title { | |||||
| text-align: center; | |||||
| font-size: 3vh; | |||||
| padding: 4vh; | |||||
| } | |||||
| .key { | |||||
| text-align: center; | |||||
| font-size: 2.5vh; | |||||
| padding: 5vh; | |||||
| padding-bottom: 0.5vh; | |||||
| text-align: left; | |||||
| .copy { | |||||
| color: #ffffff; | |||||
| margin-left: 2vh; | |||||
| cursor: pointer; | |||||
| transition: all 0.3s; | |||||
| background-color: #3a57b6; | |||||
| padding: 0.7vh; | |||||
| border-radius: 15px; | |||||
| &:hover { | |||||
| background-color: #1ceedc; | |||||
| } | |||||
| } | |||||
| .showOrHide { | |||||
| color: #20b4a8; | |||||
| margin-left: 2vh; | |||||
| cursor: pointer; | |||||
| transition: all 0.3s; | |||||
| &:hover { | |||||
| color: #476ad9; | |||||
| } | |||||
| } | |||||
| } | |||||
| .keyStatus { | |||||
| text-align: center; | |||||
| font-size: 2.9vh; | |||||
| padding: 4vh; | |||||
| margin-top: 1vh; | |||||
| .success { | |||||
| color: #ffffff; | |||||
| background-color: #ff0000; | |||||
| margin-left: 2vh; | |||||
| padding: 0.7vh; | |||||
| border-radius: 15px; | |||||
| cursor: pointer; | |||||
| transition: all 0.3s; | |||||
| &:hover { | |||||
| background-color: #36db43; | |||||
| } | |||||
| } | |||||
| .fail { | |||||
| color: #ffffff; | |||||
| background-color: #36db43; | |||||
| margin-left: 2vh; | |||||
| padding: 0.7vh; | |||||
| border-radius: 15px; | |||||
| cursor: pointer; | |||||
| transition: all 0.3s; | |||||
| &:hover { | |||||
| background-color: #ff0000; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| </style> | |||||
| @@ -0,0 +1,351 @@ | |||||
| <template> | |||||
| <div class="page justify-around"> | |||||
| <div class="addbtn"> | |||||
| <el-button type="primary" @click="dialogVisible = true">新增</el-button> | |||||
| </div> | |||||
| <el-table | |||||
| :data="tableData" | |||||
| style="width: 100%; height: 90%" | |||||
| size="large" | |||||
| align="center" | |||||
| > | |||||
| <el-table-column | |||||
| prop="name" | |||||
| :label="$t('businessMangage.name')" | |||||
| width="200" | |||||
| align="center" | |||||
| /> | |||||
| <el-table-column | |||||
| prop="address" | |||||
| :label="$t('businessMangage.address')" | |||||
| width="200" | |||||
| align="center" | |||||
| /> | |||||
| <el-table-column | |||||
| prop="status" | |||||
| :label="$t('businessMangage.status')" | |||||
| width="200" | |||||
| align="center" | |||||
| > | |||||
| <template #default="scope"> | |||||
| <span | |||||
| :style="1 * scope.row.status ? 'color: #ff0000' : 'color: #36db43'" | |||||
| >{{ getStatus(scope.row.status) }}</span | |||||
| > | |||||
| </template> | |||||
| </el-table-column> | |||||
| <el-table-column | |||||
| prop="code" | |||||
| :label="$t('businessMangage.code')" | |||||
| width="200" | |||||
| align="center" | |||||
| /> | |||||
| <el-table-column | |||||
| prop="createTime" | |||||
| :label="$t('businessMangage.createTime')" | |||||
| width="200" | |||||
| align="center" | |||||
| > | |||||
| <template #default="scope"> | |||||
| {{ getDate(scope.row.createTime) }} | |||||
| </template> | |||||
| </el-table-column> | |||||
| <el-table-column | |||||
| fixed="right" | |||||
| :label="$t('keyMangage.operations')" | |||||
| width="200" | |||||
| align="center" | |||||
| > | |||||
| <template #default="scope"> | |||||
| <el-button | |||||
| link | |||||
| type="primary" | |||||
| size="small" | |||||
| @click="showDetail(scope.row.id)" | |||||
| >{{ $t("keyMangage.check") }}</el-button | |||||
| > | |||||
| </template> | |||||
| </el-table-column> | |||||
| </el-table> | |||||
| <el-dialog | |||||
| v-model="dialogVisible" | |||||
| :title="$t('businessMangage.addNew')" | |||||
| width="35%" | |||||
| :before-close="handleClose" | |||||
| > | |||||
| <div class="formData"> | |||||
| <el-form | |||||
| ref="ruleForm" | |||||
| label-position="left" | |||||
| label-width="120px" | |||||
| :model="formData" | |||||
| :rules="rules" | |||||
| > | |||||
| <el-form-item :label="$t('businessMangage.name') + ':'" prop="name"> | |||||
| <el-input | |||||
| v-model="formData.name" | |||||
| :placeholder="$t('businessMangage.nameInputText')" | |||||
| /> | |||||
| </el-form-item> | |||||
| <el-form-item | |||||
| :label="$t('businessMangage.address') + ':'" | |||||
| prop="address" | |||||
| > | |||||
| <el-input | |||||
| v-model="formData.address" | |||||
| :placeholder="$t('businessMangage.addressInputText')" | |||||
| /> | |||||
| </el-form-item> | |||||
| <el-form-item :label="$t('businessMangage.code') + ':'" prop="code"> | |||||
| <el-input | |||||
| v-model="formData.code" | |||||
| :placeholder="$t('businessMangage.codeInputText')" | |||||
| /> | |||||
| </el-form-item> | |||||
| <el-form-item | |||||
| :label="$t('businessMangage.accessMethod') + ':'" | |||||
| prop="type" | |||||
| > | |||||
| <el-select | |||||
| v-model="formData.type" | |||||
| :placeholder="$t('businessMangage.typeInputText')" | |||||
| clearable | |||||
| > | |||||
| <el-option | |||||
| v-for="(item, index) in accessMethods" | |||||
| :key="index" | |||||
| :label="item.label" | |||||
| :value="item.value" | |||||
| /> | |||||
| </el-select> | |||||
| </el-form-item> | |||||
| </el-form> | |||||
| </div> | |||||
| <template #footer> | |||||
| <span class="dialog-footer"> | |||||
| <el-button @click="dialogVisible = false">{{ | |||||
| $t("businessMangage.cancel") | |||||
| }}</el-button> | |||||
| <el-button type="primary" @click="addNew(ruleForm)"> | |||||
| {{ $t("businessMangage.confirm") }} | |||||
| </el-button> | |||||
| </span> | |||||
| </template> | |||||
| </el-dialog> | |||||
| <div class="pagination"> | |||||
| <el-pagination | |||||
| v-model:current-page="pageNum" | |||||
| v-model:page-size="pageSize" | |||||
| :page-sizes="[10, 50, 100]" | |||||
| :small="false" | |||||
| :disabled="false" | |||||
| :background="true" | |||||
| layout="total, sizes, prev, pager, next, jumper" | |||||
| :total="total" | |||||
| @size-change="handleSizeChange" | |||||
| @current-change="handleCurrentChange" | |||||
| /> | |||||
| </div> | |||||
| </div> | |||||
| </template> | |||||
| <!-- videoType==1为竖,==2为横 --> | |||||
| <script setup> | |||||
| //#region 导入 | |||||
| import { linkEmits } from "element-plus"; | |||||
| import { getCurrentInstance } from "vue"; | |||||
| import { businessListApi, addBusinessApi } from "@/api_mangage/business.js"; | |||||
| import { useI18n } from "vue-i18n"; | |||||
| import dayjs from "dayjs"; | |||||
| import { useRoute, useRouter } from "vue-router"; | |||||
| const route = useRoute(); | |||||
| const router = useRouter(); | |||||
| const { locale } = useI18n(); | |||||
| const lanChange = ref(locale); | |||||
| const tableData = ref([]); | |||||
| const dialogVisible = ref(false); | |||||
| const showDetail = (id) => { | |||||
| router.push({ | |||||
| path: "/businessCheck", | |||||
| query: { | |||||
| id, | |||||
| }, | |||||
| }); | |||||
| }; | |||||
| const pageNum = ref(1); | |||||
| const pageSize = ref(10); | |||||
| const total = ref(0); | |||||
| const getStatus = (val) => { | |||||
| return val * 1 ? "锁定" : "正常"; | |||||
| }; | |||||
| const getDate = (val) => { | |||||
| return dayjs(val).format("YYYY-MM-DD"); | |||||
| }; | |||||
| const handleSizeChange = (val) => { | |||||
| pageSize.value = val; | |||||
| getBusinessListFunc(pageNum.value, pageSize.value); | |||||
| }; | |||||
| const handleCurrentChange = (val) => { | |||||
| pageNum.value = val; | |||||
| getBusinessListFunc(pageNum.value, pageSize.value); | |||||
| }; | |||||
| const getBusinessListFunc = async (PageNum, PageSize) => { | |||||
| try { | |||||
| const res = await businessListApi(PageNum, PageSize); | |||||
| console.log(res, "res"); | |||||
| tableData.value = res.data.list; | |||||
| total.value = res.data.total * 1; | |||||
| } catch (error) { | |||||
| console.log(error, "err"); | |||||
| } | |||||
| }; | |||||
| const formData = ref({ | |||||
| name: "", | |||||
| address: "", | |||||
| code: "", | |||||
| type: "", | |||||
| }); | |||||
| const rules = { | |||||
| name: [ | |||||
| { | |||||
| required: true, | |||||
| message: "Please input name", | |||||
| trigger: "blur", | |||||
| }, | |||||
| ], | |||||
| address: [ | |||||
| { | |||||
| required: true, | |||||
| message: "Please input address", | |||||
| trigger: "blur", | |||||
| }, | |||||
| ], | |||||
| code: [ | |||||
| { | |||||
| required: true, | |||||
| message: "Please input code", | |||||
| trigger: "blur", | |||||
| }, | |||||
| ], | |||||
| type: [ | |||||
| { | |||||
| required: true, | |||||
| message: "Please select access methods", | |||||
| trigger: "blur", | |||||
| }, | |||||
| ], | |||||
| }; | |||||
| const accessMethods = ref([ | |||||
| { | |||||
| label: "api接入", | |||||
| value: 1, | |||||
| }, | |||||
| { | |||||
| label: "私有化接入", | |||||
| value: 2, | |||||
| }, | |||||
| ]); | |||||
| const handleClose = () => { | |||||
| dialogVisible.value = false; | |||||
| setTimeout(() => { | |||||
| formData.value = { | |||||
| name: "", | |||||
| address: "", | |||||
| code: "", | |||||
| type: "", | |||||
| }; | |||||
| }, 500); | |||||
| }; | |||||
| const ruleForm = ref(); | |||||
| const addNew = async (refForm) => { | |||||
| if (!refForm) return; | |||||
| await refForm.validate(async (valid, fields) => { | |||||
| if (valid) { | |||||
| const data = formData.value; | |||||
| try { | |||||
| const res = await addBusinessApi(data); | |||||
| console.log(res, "res"); | |||||
| if (res.code == 200) { | |||||
| ElMessage.success("添加成功!"); | |||||
| dialogVisible.value = false; | |||||
| } | |||||
| getBusinessListFunc(1, 10); | |||||
| pageNum.value = 1; | |||||
| pageSize.value = 10; | |||||
| } catch (error) { | |||||
| console.log(error, "err"); | |||||
| ElMessage.error(error.message); | |||||
| } | |||||
| } else { | |||||
| ElMessage.error("请完善信息!"); | |||||
| } | |||||
| }); | |||||
| }; | |||||
| onMounted(() => { | |||||
| getBusinessListFunc(1, 10); | |||||
| }); | |||||
| </script> | |||||
| <style lang="scss" scoped> | |||||
| .page { | |||||
| height: calc(100vh - 80px); | |||||
| // height: calc(100vh - 80px); | |||||
| background-color: #ffffff; | |||||
| border-radius: 30px 0 0 0; | |||||
| overflow: hidden; | |||||
| padding: 10vh; | |||||
| .addbtn { | |||||
| margin-bottom: 2vh; | |||||
| } | |||||
| .formData { | |||||
| padding: 5vh 3vh; | |||||
| } | |||||
| .pagination { | |||||
| position: fixed; | |||||
| left: 55%; | |||||
| bottom: 8vh; | |||||
| transform: translateX(-50%); | |||||
| border-radius: 5px; | |||||
| padding: 10px 20px; | |||||
| z-index: 99; | |||||
| transition: all 0.3s; | |||||
| cursor: pointer; | |||||
| &:hover { | |||||
| background-color: #b8b8b873; | |||||
| } | |||||
| } | |||||
| } | |||||
| </style> | |||||
| @@ -757,8 +757,8 @@ const soundStyle = ref(""); //选择的风格 | |||||
| // 语言下拉框内容 | // 语言下拉框内容 | ||||
| const languageOptions = ref([]); | const languageOptions = ref([]); | ||||
| async function voiceTotal() { | async function voiceTotal() { | ||||
| const res = await voiceTotalApi(); | |||||
| languageOptions.value = res.data; | |||||
| // const res = await voiceTotalApi(); | |||||
| // languageOptions.value = res.data; | |||||
| } | } | ||||
| // 声音下拉框内容 | // 声音下拉框内容 | ||||
| const soundOptions = ref([]); | const soundOptions = ref([]); | ||||
| @@ -0,0 +1,325 @@ | |||||
| <!-- 字典数据 --> | |||||
| <script setup lang="ts"> | |||||
| import { | |||||
| getDictPage, | |||||
| getDictFormData, | |||||
| addDict, | |||||
| updateDict, | |||||
| deleteDict, | |||||
| } from "@/api/dict"; | |||||
| import { DictPageVO, DictForm, DictQuery } from "@/api/dict/types"; | |||||
| defineOptions({ | |||||
| name: "DictData", | |||||
| inheritAttrs: false, | |||||
| }); | |||||
| const props = defineProps({ | |||||
| typeCode: { | |||||
| type: String, | |||||
| default: () => { | |||||
| return ""; | |||||
| }, | |||||
| }, | |||||
| typeName: { | |||||
| type: String, | |||||
| default: () => { | |||||
| return ""; | |||||
| }, | |||||
| }, | |||||
| }); | |||||
| watch( | |||||
| () => props.typeCode, | |||||
| (newVal: string) => { | |||||
| queryParams.typeCode = newVal; | |||||
| formData.typeCode = newVal; | |||||
| resetQuery(); | |||||
| } | |||||
| ); | |||||
| const queryFormRef = ref(ElForm); | |||||
| const dataFormRef = ref(ElForm); | |||||
| const loading = ref(false); | |||||
| const ids = ref<number[]>([]); | |||||
| const total = ref(0); | |||||
| const queryParams = reactive<DictQuery>({ | |||||
| pageNum: 1, | |||||
| pageSize: 10, | |||||
| typeCode: props.typeCode, | |||||
| }); | |||||
| const dictList = ref<DictPageVO[]>(); | |||||
| const dialog = reactive<DialogOption>({ | |||||
| visible: false, | |||||
| }); | |||||
| const formData = reactive<DictForm>({ | |||||
| status: 1, | |||||
| typeCode: props.typeCode, | |||||
| sort: 1, | |||||
| }); | |||||
| const rules = reactive({ | |||||
| name: [{ required: true, message: "请输入字典名称", trigger: "blur" }], | |||||
| value: [{ required: true, message: "请输入字典值", trigger: "blur" }], | |||||
| }); | |||||
| /** | |||||
| * 查询 | |||||
| */ | |||||
| function handleQuery() { | |||||
| if (queryParams.typeCode) { | |||||
| loading.value = true; | |||||
| getDictPage(queryParams) | |||||
| .then(({ data }) => { | |||||
| dictList.value = data.list; | |||||
| total.value = data.total; | |||||
| }) | |||||
| .finally(() => (loading.value = false)); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * 重置查询 | |||||
| */ | |||||
| function resetQuery() { | |||||
| queryFormRef.value.resetFields(); | |||||
| queryParams.pageNum = 1; | |||||
| handleQuery(); | |||||
| } | |||||
| /** | |||||
| * 行checkbox change事件 | |||||
| * | |||||
| * @param selection | |||||
| */ | |||||
| function handleSelectionChange(selection: any) { | |||||
| ids.value = selection.map((item: any) => item.id); | |||||
| } | |||||
| /** | |||||
| * 打开字典表单弹窗 | |||||
| * | |||||
| * @param dictId 字典ID | |||||
| */ | |||||
| function openDialog(dictId?: number) { | |||||
| dialog.visible = true; | |||||
| if (dictId) { | |||||
| dialog.title = "修改字典"; | |||||
| getDictFormData(dictId).then(({ data }) => { | |||||
| Object.assign(formData, data); | |||||
| }); | |||||
| } else { | |||||
| dialog.title = "新增字典"; | |||||
| } | |||||
| } | |||||
| /** | |||||
| * 字典表单提交 | |||||
| */ | |||||
| function handleSubmit() { | |||||
| dataFormRef.value.validate((isValid: boolean) => { | |||||
| if (isValid) { | |||||
| loading.value = false; | |||||
| const dictId = formData.id; | |||||
| if (dictId) { | |||||
| updateDict(dictId, formData) | |||||
| .then(() => { | |||||
| ElMessage.success("修改成功"); | |||||
| closeDialog(); | |||||
| resetQuery(); | |||||
| }) | |||||
| .finally(() => (loading.value = false)); | |||||
| } else { | |||||
| addDict(formData) | |||||
| .then(() => { | |||||
| ElMessage.success("新增成功"); | |||||
| closeDialog(); | |||||
| resetQuery(); | |||||
| }) | |||||
| .finally(() => (loading.value = false)); | |||||
| } | |||||
| } | |||||
| }); | |||||
| } | |||||
| /** | |||||
| * 关闭弹窗 | |||||
| */ | |||||
| function closeDialog() { | |||||
| dialog.visible = false; | |||||
| resetForm(); | |||||
| } | |||||
| /** | |||||
| * 重置表单 | |||||
| */ | |||||
| function resetForm() { | |||||
| dataFormRef.value.resetFields(); | |||||
| dataFormRef.value.clearValidate(); | |||||
| formData.id = undefined; | |||||
| formData.status = 1; | |||||
| formData.sort = 1; | |||||
| formData.typeCode = props.typeCode; | |||||
| } | |||||
| /** | |||||
| * 删除字典 | |||||
| */ | |||||
| function handleDelete(dictId?: number) { | |||||
| const dictIds = [dictId || ids.value].join(","); | |||||
| if (!dictIds) { | |||||
| ElMessage.warning("请勾选删除项"); | |||||
| return; | |||||
| } | |||||
| ElMessageBox.confirm("确认删除已选中的数据项?", "警告", { | |||||
| confirmButtonText: "确定", | |||||
| cancelButtonText: "取消", | |||||
| type: "warning", | |||||
| }).then(() => { | |||||
| deleteDict(dictIds).then(() => { | |||||
| ElMessage.success("删除成功"); | |||||
| resetQuery(); | |||||
| }); | |||||
| }); | |||||
| } | |||||
| onMounted(() => { | |||||
| handleQuery(); | |||||
| }); | |||||
| </script> | |||||
| <template> | |||||
| <div class="app-container"> | |||||
| <div class="search-container"> | |||||
| <!-- 搜索表单 --> | |||||
| <el-form ref="queryFormRef" :model="queryParams" :inline="true"> | |||||
| <el-form-item label="关键字" prop="name"> | |||||
| <el-input | |||||
| v-model="queryParams.name" | |||||
| placeholder="字典名称" | |||||
| clearable | |||||
| /> | |||||
| </el-form-item> | |||||
| <el-form-item> | |||||
| <el-button type="primary" @click="handleQuery" | |||||
| ><i-ep-search />搜索</el-button | |||||
| > | |||||
| <el-button @click="resetQuery"> <i-ep-refresh />重置</el-button> | |||||
| </el-form-item> | |||||
| </el-form> | |||||
| </div> | |||||
| <el-card shadow="never"> | |||||
| <template #header> | |||||
| <el-button | |||||
| v-hasPerm="['sys:dict:add']" | |||||
| type="success" | |||||
| @click="openDialog()" | |||||
| ><i-ep-plus />新增</el-button | |||||
| > | |||||
| <el-button | |||||
| v-hasPerm="['sys:dict:delete']" | |||||
| type="danger" | |||||
| :disabled="ids.length === 0" | |||||
| @click="handleDelete()" | |||||
| ><i-ep-delete />删除</el-button | |||||
| > | |||||
| </template> | |||||
| <!-- 数据表格 --> | |||||
| <el-table | |||||
| v-loading="loading" | |||||
| :data="dictList" | |||||
| border | |||||
| @selection-change="handleSelectionChange" | |||||
| > | |||||
| <el-table-column type="selection" width="50" /> | |||||
| <el-table-column label="字典名称" prop="name" /> | |||||
| <el-table-column label="字典值" prop="value" /> | |||||
| <el-table-column label="状态" align="center"> | |||||
| <template #default="scope"> | |||||
| <el-tag v-if="scope.row.status === 1" type="success">启用</el-tag> | |||||
| <el-tag v-else type="info">禁用</el-tag> | |||||
| </template> | |||||
| </el-table-column> | |||||
| <el-table-column fixed="right" label="操作" align="center"> | |||||
| <template #default="scope"> | |||||
| <el-button | |||||
| v-hasPerm="['sys:dict:edit']" | |||||
| type="primary" | |||||
| link | |||||
| @click="openDialog(scope.row.id)" | |||||
| ><i-ep-edit />编辑</el-button | |||||
| > | |||||
| <el-button | |||||
| v-hasPerm="['sys:dict:delete']" | |||||
| type="primary" | |||||
| link | |||||
| @click.stop="handleDelete(scope.row.id)" | |||||
| ><i-ep-delete />删除</el-button | |||||
| > | |||||
| </template> | |||||
| </el-table-column> | |||||
| </el-table> | |||||
| <pagination | |||||
| v-if="total > 0" | |||||
| v-model:total="total" | |||||
| v-model:page="queryParams.pageNum" | |||||
| v-model:limit="queryParams.pageSize" | |||||
| @pagination="handleQuery" | |||||
| /> | |||||
| </el-card> | |||||
| <!-- 表单弹窗 --> | |||||
| <el-dialog | |||||
| v-model="dialog.visible" | |||||
| :title="dialog.title" | |||||
| width="500px" | |||||
| @close="closeDialog" | |||||
| > | |||||
| <el-form | |||||
| ref="dataFormRef" | |||||
| :model="formData" | |||||
| :rules="rules" | |||||
| label-width="100px" | |||||
| > | |||||
| <el-form-item label="字典名称">{{ typeName }}</el-form-item> | |||||
| <el-form-item label="字典名称" prop="name"> | |||||
| <el-input v-model="formData.name" placeholder="请输入字典名称" /> | |||||
| </el-form-item> | |||||
| <el-form-item label="字典值" prop="value"> | |||||
| <el-input v-model="formData.value" placeholder="字典值" /> | |||||
| </el-form-item> | |||||
| <el-form-item label="排序" prop="sort"> | |||||
| <el-input-number | |||||
| v-model="formData.sort" | |||||
| controls-position="right" | |||||
| :min="0" | |||||
| /> | |||||
| </el-form-item> | |||||
| <el-form-item label="状态" prop="status"> | |||||
| <el-radio-group v-model="formData.status"> | |||||
| <el-radio :label="1">正常</el-radio> | |||||
| <el-radio :label="0">停用</el-radio> | |||||
| </el-radio-group> | |||||
| </el-form-item> | |||||
| <el-form-item label="备注" prop="remark"> | |||||
| <el-input v-model="formData.remark" type="textarea" /> | |||||
| </el-form-item> | |||||
| </el-form> | |||||
| <template #footer> | |||||
| <div class="dialog-footer"> | |||||
| <el-button type="primary" @click="handleSubmit">确 定</el-button> | |||||
| <el-button @click="closeDialog">取 消</el-button> | |||||
| </div> | |||||
| </template> | |||||
| </el-dialog> | |||||
| </div> | |||||
| </template> | |||||
| @@ -0,0 +1,322 @@ | |||||
| <template> | |||||
| <div class="app-container"> | |||||
| <div class="search-container"> | |||||
| <el-form ref="queryFormRef" :model="queryParams" :inline="true"> | |||||
| <el-form-item label="关键字" prop="name"> | |||||
| <el-input | |||||
| v-model="queryParams.keywords" | |||||
| placeholder="字典类型名称/编码" | |||||
| clearable | |||||
| @keyup.enter="handleQuery" | |||||
| /> | |||||
| </el-form-item> | |||||
| <el-form-item> | |||||
| <el-button type="primary" @click="handleQuery()" | |||||
| ><i-ep-search />搜索</el-button | |||||
| > | |||||
| <el-button @click="resetQuery()"><i-ep-refresh />重置</el-button> | |||||
| </el-form-item> | |||||
| </el-form> | |||||
| </div> | |||||
| <el-card shadow="never" class="table-container"> | |||||
| <template #header> | |||||
| <el-button | |||||
| v-hasPerm="['sys:dict_type:add']" | |||||
| type="success" | |||||
| @click="openDialog()" | |||||
| ><i-ep-plus />新增</el-button | |||||
| > | |||||
| <el-button | |||||
| type="danger" | |||||
| :disabled="ids.length === 0" | |||||
| @click="handleDelete()" | |||||
| ><i-ep-delete />删除</el-button | |||||
| > | |||||
| </template> | |||||
| <el-table | |||||
| v-loading="loading" | |||||
| highlight-current-row | |||||
| :data="dictTypeList" | |||||
| border | |||||
| @selection-change="handleSelectionChange" | |||||
| > | |||||
| <el-table-column type="selection" width="55" align="center" /> | |||||
| <el-table-column label="字典类型名称" prop="name" width="200" /> | |||||
| <el-table-column label="字典类型编码" prop="code" width="200" /> | |||||
| <el-table-column label="状态" align="center" width="100"> | |||||
| <template #default="scope"> | |||||
| <el-tag v-if="scope.row.status === 1" type="success">启用</el-tag> | |||||
| <el-tag v-else type="info">禁用</el-tag> | |||||
| </template> | |||||
| </el-table-column> | |||||
| <el-table-column label="备注" prop="remark" align="center" /> | |||||
| <el-table-column fixed="right" label="操作" align="center" width="220"> | |||||
| <template #default="scope"> | |||||
| <el-button | |||||
| type="primary" | |||||
| link | |||||
| size="small" | |||||
| @click.stop="openDictDialog(scope.row)" | |||||
| ><i-ep-Collection />字典数据</el-button | |||||
| > | |||||
| <el-button | |||||
| v-hasPerm="['sys:dict_type:edit']" | |||||
| type="primary" | |||||
| link | |||||
| size="small" | |||||
| @click.stop="openDialog(scope.row.id)" | |||||
| ><i-ep-edit />编辑</el-button | |||||
| > | |||||
| <el-button | |||||
| v-hasPerm="['sys:dict_type:delete']" | |||||
| type="primary" | |||||
| link | |||||
| size="small" | |||||
| @click.stop="handleDelete(scope.row.id)" | |||||
| ><i-ep-delete />删除</el-button | |||||
| > | |||||
| </template> | |||||
| </el-table-column> | |||||
| </el-table> | |||||
| <pagination | |||||
| v-if="total > 0" | |||||
| v-model:total="total" | |||||
| v-model:page="queryParams.pageNum" | |||||
| v-model:limit="queryParams.pageSize" | |||||
| @pagination="handleQuery" | |||||
| /> | |||||
| </el-card> | |||||
| <el-dialog | |||||
| v-model="dialog.visible" | |||||
| :title="dialog.title" | |||||
| width="500px" | |||||
| @close="closeDialog" | |||||
| > | |||||
| <el-form | |||||
| ref="dataFormRef" | |||||
| :model="formData" | |||||
| :rules="rules" | |||||
| label-width="80px" | |||||
| > | |||||
| <el-form-item label="字典名称" prop="name"> | |||||
| <el-input v-model="formData.name" placeholder="请输入字典名称" /> | |||||
| </el-form-item> | |||||
| <el-form-item label="字典编码" prop="code"> | |||||
| <el-input v-model="formData.code" placeholder="请输入字典编码" /> | |||||
| </el-form-item> | |||||
| <el-form-item label="状态" prop="status"> | |||||
| <el-radio-group v-model="formData.status"> | |||||
| <el-radio :label="1">正常</el-radio> | |||||
| <el-radio :label="0">停用</el-radio> | |||||
| </el-radio-group> | |||||
| </el-form-item> | |||||
| <el-form-item label="备注" prop="remark"> | |||||
| <el-input | |||||
| v-model="formData.remark" | |||||
| type="textarea" | |||||
| placeholder="字典类型备注" | |||||
| :autosize="{ minRows: 2, maxRows: 4 }" | |||||
| /> | |||||
| </el-form-item> | |||||
| </el-form> | |||||
| <template #footer> | |||||
| <div class="dialog-footer"> | |||||
| <el-button type="primary" @click="handleSubmit">确 定</el-button> | |||||
| <el-button @click="closeDialog">取 消</el-button> | |||||
| </div> | |||||
| </template> | |||||
| </el-dialog> | |||||
| <!--字典数据弹窗--> | |||||
| <el-dialog | |||||
| v-model="dictDataDialog.visible" | |||||
| :title="dictDataDialog.title" | |||||
| width="1000px" | |||||
| @close="closeDictDialog" | |||||
| > | |||||
| <dict-item | |||||
| v-model:typeCode="selectedDictType.typeCode" | |||||
| v-model:typeName="selectedDictType.typeName" | |||||
| /> | |||||
| </el-dialog> | |||||
| </div> | |||||
| </template> | |||||
| <script setup> | |||||
| import { | |||||
| getDictTypePage, | |||||
| getDictTypeForm, | |||||
| addDictType, | |||||
| updateDictType, | |||||
| deleteDictTypes, | |||||
| } from "@/api/dict"; | |||||
| // import { DictTypePageVO, DictTypeQuery, DictTypeForm } from "@/api/dict/types"; | |||||
| defineOptions({ | |||||
| name: "DictType", | |||||
| inheritAttrs: false, | |||||
| }); | |||||
| const queryFormRef = ref(""); | |||||
| const dataFormRef = ref(""); | |||||
| const loading = ref(false); | |||||
| const ids = ref([]); | |||||
| const total = ref(0); | |||||
| const queryParams = reactive({ | |||||
| pageNum: 1, | |||||
| pageSize: 10, | |||||
| }); | |||||
| const dictTypeList = ref(); | |||||
| const dialog = reactive({ | |||||
| visible: false, | |||||
| }); | |||||
| const formData = reactive({ | |||||
| status: 1, | |||||
| }); | |||||
| const rules = reactive({ | |||||
| name: [{ required: true, message: "请输入字典类型名称", trigger: "blur" }], | |||||
| code: [{ required: true, message: "请输入字典类型编码", trigger: "blur" }], | |||||
| }); | |||||
| /** 查询 */ | |||||
| function handleQuery() { | |||||
| loading.value = true; | |||||
| getDictTypePage(queryParams) | |||||
| .then(({ data }) => { | |||||
| dictTypeList.value = data.list; | |||||
| total.value = data.total; | |||||
| }) | |||||
| .finally(() => { | |||||
| loading.value = false; | |||||
| }); | |||||
| } | |||||
| /** | |||||
| * 重置查询 | |||||
| */ | |||||
| function resetQuery() { | |||||
| queryFormRef.value.resetFields(); | |||||
| queryParams.pageNum = 1; | |||||
| handleQuery(); | |||||
| } | |||||
| /** 行复选框选中 */ | |||||
| function handleSelectionChange(selection) { | |||||
| ids.value = selection.map((item) => item.id); | |||||
| } | |||||
| /** | |||||
| * 打开字典类型表单弹窗 | |||||
| * | |||||
| * @param dicTypeId 字典类型ID | |||||
| */ | |||||
| function openDialog(dicTypeId) { | |||||
| dialog.visible = true; | |||||
| if (dicTypeId) { | |||||
| dialog.title = "修改字典类型"; | |||||
| getDictTypeForm(dicTypeId).then(({ data }) => { | |||||
| Object.assign(formData, data); | |||||
| }); | |||||
| } else { | |||||
| dialog.title = "新增字典类型"; | |||||
| } | |||||
| } | |||||
| /** 字典类型表单提交 */ | |||||
| function handleSubmit() { | |||||
| dataFormRef.value.validate((isValid) => { | |||||
| if (isValid) { | |||||
| loading.value = false; | |||||
| const dictTypeId = formData.id; | |||||
| if (dictTypeId) { | |||||
| updateDictType(dictTypeId, formData) | |||||
| .then(() => { | |||||
| ElMessage.success("修改成功"); | |||||
| closeDialog(); | |||||
| handleQuery(); | |||||
| }) | |||||
| .finally(() => (loading.value = false)); | |||||
| } else { | |||||
| addDictType(formData) | |||||
| .then(() => { | |||||
| ElMessage.success("新增成功"); | |||||
| closeDialog(); | |||||
| handleQuery(); | |||||
| }) | |||||
| .finally(() => (loading.value = false)); | |||||
| } | |||||
| } | |||||
| }); | |||||
| } | |||||
| /** 关闭字典类型弹窗 */ | |||||
| function closeDialog() { | |||||
| dialog.visible = false; | |||||
| resetForm(); | |||||
| } | |||||
| /** 重置字典类型表单 */ | |||||
| function resetForm() { | |||||
| dataFormRef.value.resetFields(); | |||||
| dataFormRef.value.clearValidate(); | |||||
| formData.id = undefined; | |||||
| formData.status = 1; | |||||
| } | |||||
| /** 删除字典类型 */ | |||||
| function handleDelete(dictTypeId) { | |||||
| const dictTypeIds = [dictTypeId || ids.value].join(","); | |||||
| if (!dictTypeIds) { | |||||
| ElMessage.warning("请勾选删除项"); | |||||
| return; | |||||
| } | |||||
| ElMessageBox.confirm("确认删除已选中的数据项?", "警告", { | |||||
| confirmButtonText: "确定", | |||||
| cancelButtonText: "取消", | |||||
| type: "warning", | |||||
| }).then(() => { | |||||
| deleteDictTypes(dictTypeIds).then(() => { | |||||
| ElMessage.success("删除成功"); | |||||
| resetQuery(); | |||||
| }); | |||||
| }); | |||||
| } | |||||
| const dictDataDialog = reactive({ | |||||
| visible: false, | |||||
| }); | |||||
| const selectedDictType = reactive({ typeCode: "", typeName: "" }); // 当前选中的字典类型 | |||||
| /** 打开字典数据弹窗 */ | |||||
| function openDictDialog(row) { | |||||
| dictDataDialog.visible = true; | |||||
| dictDataDialog.title = "【" + row.name + "】字典数据"; | |||||
| selectedDictType.typeCode = row.code; | |||||
| selectedDictType.typeName = row.name; | |||||
| } | |||||
| /** 关闭字典数据弹窗 */ | |||||
| function closeDictDialog() { | |||||
| dictDataDialog.visible = false; | |||||
| } | |||||
| onMounted(() => { | |||||
| handleQuery(); | |||||
| }); | |||||
| </script> | |||||
| <style lang="scss" scoped></style> | |||||
| @@ -0,0 +1,301 @@ | |||||
| <template> | |||||
| <div class="page flex justify-around"> | |||||
| <div class="card"> | |||||
| <div class="title">密钥详情</div> | |||||
| <div class="key"> | |||||
| <span class="text">{{ $t("keyMangage.name") }}:{{ name }}</span> | |||||
| </div> | |||||
| <!-- appId --> | |||||
| <div class="key"> | |||||
| <span class="text">appId:{{ showCode }}</span> | |||||
| <span class="showOrHide" @click="showHideCode">{{ showText }}</span> | |||||
| <span v-if="showText == '隐藏'" class="copy" @click="copyKey(showCode)" | |||||
| >复制</span | |||||
| > | |||||
| </div> | |||||
| <!-- appKey --> | |||||
| <div class="key"> | |||||
| <span class="text">appKey:{{ showCodeII }}</span> | |||||
| <span class="showOrHide" @click="showHideCodeII">{{ showTextII }}</span> | |||||
| <span | |||||
| v-if="showTextII == '隐藏'" | |||||
| class="copy" | |||||
| @click="copyKey(showCodeII)" | |||||
| >复制</span | |||||
| > | |||||
| </div> | |||||
| <!-- signKey --> | |||||
| <div class="key"> | |||||
| <span class="text">signKey:{{ showCodeIII }}</span> | |||||
| <span class="showOrHide" @click="showHideCodeIII(showCodeIII)">{{ | |||||
| showTextIII | |||||
| }}</span> | |||||
| <span v-if="showTextIII == '隐藏'" class="copy" @click="copyKey" | |||||
| >复制</span | |||||
| > | |||||
| </div> | |||||
| <div class="keyStatus"> | |||||
| <span class="text" | |||||
| >密钥状态: | |||||
| <span v-if="!keyStatus" style="color: #36db43">正常</span> | |||||
| <span v-else style="color: #ff0000">失效</span> | |||||
| </span> | |||||
| <span v-if="keyStatus" class="fail" @click="changeStatus(0)">恢复</span> | |||||
| <span v-if="!keyStatus" class="success" @click="changeStatus(1)" | |||||
| >作废</span | |||||
| > | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </template> | |||||
| <!-- videoType==1为竖,==2为横 --> | |||||
| <script setup> | |||||
| //#region 导入 | |||||
| import { linkEmits } from "element-plus"; | |||||
| import { getCurrentInstance } from "vue"; | |||||
| import { useI18n } from "vue-i18n"; | |||||
| import { useRoute, useRouter } from "vue-router"; | |||||
| import { getKeyByIdApi, updateKeyStatusApi } from "@/api_mangage/key"; | |||||
| const route = useRoute(); | |||||
| const router = useRouter(); | |||||
| const { locale } = useI18n(); | |||||
| const lanChange = ref(locale); | |||||
| const AccessToken = localStorage.getItem("AccessToken"); // 判断有没有登录 | |||||
| const keyId = ref(""); | |||||
| const name = ref(""); | |||||
| const appId = ref(""); | |||||
| const hideCode = ref(""); | |||||
| const showCode = ref(""); | |||||
| const showText = ref("查看"); | |||||
| const showHideCode = () => { | |||||
| if (showText.value == "查看") { | |||||
| showText.value = "隐藏"; | |||||
| showCode.value = appId.value; | |||||
| } else { | |||||
| showText.value = "查看"; | |||||
| showCode.value = hideCode.value; | |||||
| } | |||||
| }; | |||||
| const appKey = ref(""); | |||||
| const hideCodeII = ref(""); | |||||
| const showCodeII = ref(""); | |||||
| const showTextII = ref("查看"); | |||||
| const showHideCodeII = () => { | |||||
| if (showTextII.value == "查看") { | |||||
| showTextII.value = "隐藏"; | |||||
| showCodeII.value = appKey.value; | |||||
| } else { | |||||
| showTextII.value = "查看"; | |||||
| showCodeII.value = hideCodeII.value; | |||||
| } | |||||
| }; | |||||
| const signKey = ref(""); | |||||
| const hideCodeIII = ref(""); | |||||
| const showCodeIII = ref(""); | |||||
| const showTextIII = ref("查看"); | |||||
| const showHideCodeIII = () => { | |||||
| if (showTextIII.value == "查看") { | |||||
| showTextIII.value = "隐藏"; | |||||
| showCodeIII.value = signKey.value; | |||||
| } else { | |||||
| showTextIII.value = "查看"; | |||||
| showCodeIII.value = hideCodeIII.value; | |||||
| } | |||||
| }; | |||||
| const getKeyFunc = async () => { | |||||
| const id = keyId.value; | |||||
| try { | |||||
| const res = await getKeyByIdApi(id); | |||||
| console.log(res, "res"); | |||||
| appId.value = res.data.appId; | |||||
| appKey.value = res.data.appKey; | |||||
| signKey.value = res.data.signKey; | |||||
| keyStatus.value = res.data.status; | |||||
| name.value = res.data.name; | |||||
| const len = appId.value.length; | |||||
| const lenII = appKey.value.length; | |||||
| const lenIII = signKey.value.length; | |||||
| let code = ""; | |||||
| let codeII = ""; | |||||
| let codeIII = ""; | |||||
| for (let index = 0; index < len; index++) { | |||||
| code += "*"; | |||||
| } | |||||
| for (let index = 0; index < lenII; index++) { | |||||
| codeII += "*"; | |||||
| } | |||||
| for (let index = 0; index < lenIII; index++) { | |||||
| codeIII += "*"; | |||||
| } | |||||
| hideCode.value = code; | |||||
| showCode.value = code; | |||||
| hideCodeII.value = codeII; | |||||
| showCodeII.value = codeII; | |||||
| hideCodeIII.value = codeIII; | |||||
| showCodeIII.value = codeIII; | |||||
| } catch (error) { | |||||
| console.log(error, "err"); | |||||
| } | |||||
| }; | |||||
| const copyKey = (text) => { | |||||
| navigator.clipboard | |||||
| .writeText(text) | |||||
| .then(() => { | |||||
| ElMessage.success("复制成功!"); | |||||
| }) | |||||
| .catch(() => { | |||||
| ElMessage.error("复制失败!"); | |||||
| }); | |||||
| }; | |||||
| const keyStatus = ref(""); | |||||
| const changeStatus = async (status) => { | |||||
| const id = keyId.value; | |||||
| if (status) { | |||||
| ElMessageBox.confirm("此操作将作废密钥,确定?", "Warning", { | |||||
| confirmButtonText: "确定", | |||||
| cancelButtonText: "取消", | |||||
| type: "warning", | |||||
| }) | |||||
| .then(async () => { | |||||
| try { | |||||
| const res = await updateKeyStatusApi(id, status); | |||||
| if (res.code == 200) { | |||||
| ElMessage({ | |||||
| type: "success", | |||||
| message: "作废成功!", | |||||
| }); | |||||
| getKeyFunc(); | |||||
| } | |||||
| } catch (error) { | |||||
| console.log(error, "err"); | |||||
| } | |||||
| }) | |||||
| .catch(() => {}); | |||||
| } else { | |||||
| try { | |||||
| const res = await updateKeyStatusApi(id, status); | |||||
| if (res.code == 200) { | |||||
| ElMessage({ | |||||
| type: "success", | |||||
| message: "恢复成功!", | |||||
| }); | |||||
| getKeyFunc(); | |||||
| } | |||||
| } catch (error) { | |||||
| console.log(error, "err"); | |||||
| } | |||||
| } | |||||
| }; | |||||
| onMounted(() => { | |||||
| keyId.value = route.query.id; | |||||
| getKeyFunc(); | |||||
| }); | |||||
| </script> | |||||
| <style lang="scss" scoped> | |||||
| .page { | |||||
| height: calc(100vh - 80px); | |||||
| // height: calc(100vh - 80px); | |||||
| background-color: #ffffff; | |||||
| border-radius: 30px 0 0 0; | |||||
| overflow: hidden; | |||||
| .card { | |||||
| width: 80%; | |||||
| height: 70%; | |||||
| background-color: #fafafa; | |||||
| margin-top: 10vh; | |||||
| border-radius: 5vh; | |||||
| box-shadow: #0000002e 1px 1px 1px 1px; | |||||
| .title { | |||||
| text-align: center; | |||||
| font-size: 3vh; | |||||
| padding: 4vh; | |||||
| } | |||||
| .key { | |||||
| text-align: center; | |||||
| font-size: 2.5vh; | |||||
| padding: 5vh; | |||||
| padding-bottom: 0.5vh; | |||||
| text-align: left; | |||||
| .copy { | |||||
| color: #ffffff; | |||||
| margin-left: 2vh; | |||||
| cursor: pointer; | |||||
| transition: all 0.3s; | |||||
| background-color: #3a57b6; | |||||
| padding: 0.7vh; | |||||
| border-radius: 15px; | |||||
| &:hover { | |||||
| background-color: #1ceedc; | |||||
| } | |||||
| } | |||||
| .showOrHide { | |||||
| color: #20b4a8; | |||||
| margin-left: 2vh; | |||||
| cursor: pointer; | |||||
| transition: all 0.3s; | |||||
| &:hover { | |||||
| color: #476ad9; | |||||
| } | |||||
| } | |||||
| } | |||||
| .keyStatus { | |||||
| text-align: center; | |||||
| font-size: 2.9vh; | |||||
| padding: 4vh; | |||||
| margin-top: 1vh; | |||||
| .success { | |||||
| color: #ffffff; | |||||
| background-color: #ff0000; | |||||
| margin-left: 2vh; | |||||
| padding: 0.7vh; | |||||
| border-radius: 15px; | |||||
| cursor: pointer; | |||||
| transition: all 0.3s; | |||||
| &:hover { | |||||
| background-color: #36db43; | |||||
| } | |||||
| } | |||||
| .fail { | |||||
| color: #ffffff; | |||||
| background-color: #36db43; | |||||
| margin-left: 2vh; | |||||
| padding: 0.7vh; | |||||
| border-radius: 15px; | |||||
| cursor: pointer; | |||||
| transition: all 0.3s; | |||||
| &:hover { | |||||
| background-color: #ff0000; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| </style> | |||||
| @@ -0,0 +1,149 @@ | |||||
| <template> | |||||
| <div class="page flex justify-around"> | |||||
| <el-table | |||||
| :data="tableData" | |||||
| style="width: 100%; height: 90%" | |||||
| size="large" | |||||
| align="center" | |||||
| > | |||||
| <el-table-column | |||||
| prop="name" | |||||
| :label="$t('keyMangage.name')" | |||||
| width="220" | |||||
| align="center" | |||||
| /> | |||||
| <el-table-column | |||||
| prop="status" | |||||
| :label="$t('keyMangage.status')" | |||||
| width="220" | |||||
| align="center" | |||||
| > | |||||
| <template #default="scope"> | |||||
| <span | |||||
| :style="1 * scope.row.status ? 'color: #ff0000' : 'color: #36db43'" | |||||
| >{{ getStatus(scope.row.status) }}</span | |||||
| > | |||||
| </template> | |||||
| </el-table-column> | |||||
| <el-table-column | |||||
| fixed="right" | |||||
| :label="$t('keyMangage.operations')" | |||||
| width="220" | |||||
| align="center" | |||||
| > | |||||
| <template #default="scope"> | |||||
| <el-button | |||||
| link | |||||
| type="primary" | |||||
| size="small" | |||||
| @click="showDetail(scope.row.id)" | |||||
| >{{ $t("keyMangage.check") }}</el-button | |||||
| > | |||||
| </template> | |||||
| </el-table-column> | |||||
| </el-table> | |||||
| <div class="pagination"> | |||||
| <el-pagination | |||||
| v-model:current-page="pageNum" | |||||
| v-model:page-size="pageSize" | |||||
| :page-sizes="[10, 50, 100]" | |||||
| :small="false" | |||||
| :disabled="false" | |||||
| :background="true" | |||||
| layout="total, sizes, prev, pager, next, jumper" | |||||
| :total="total" | |||||
| @size-change="handleSizeChange" | |||||
| @current-change="handleCurrentChange" | |||||
| /> | |||||
| </div> | |||||
| </div> | |||||
| </template> | |||||
| <!-- videoType==1为竖,==2为横 --> | |||||
| <script setup> | |||||
| //#region 导入 | |||||
| import { linkEmits } from "element-plus"; | |||||
| import { getCurrentInstance } from "vue"; | |||||
| import { keyListApi } from "@/api_mangage/key"; | |||||
| import { useI18n } from "vue-i18n"; | |||||
| import { useRoute, useRouter } from "vue-router"; | |||||
| const route = useRoute(); | |||||
| const router = useRouter(); | |||||
| const { locale } = useI18n(); | |||||
| const lanChange = ref(locale); | |||||
| const tableData = ref([]); | |||||
| const showDetail = (id) => { | |||||
| router.push({ | |||||
| path: "/keyCheck", | |||||
| query: { | |||||
| id, | |||||
| }, | |||||
| }); | |||||
| }; | |||||
| const pageNum = ref(1); | |||||
| const pageSize = ref(10); | |||||
| const total = ref(0); | |||||
| const getStatus = (val) => { | |||||
| return val * 1 ? "失效" : "正常"; | |||||
| }; | |||||
| const handleSizeChange = (val) => { | |||||
| pageSize.value = val; | |||||
| getKeyListFunc(pageNum.value, pageSize.value); | |||||
| }; | |||||
| const handleCurrentChange = (val) => { | |||||
| pageNum.value = val; | |||||
| getKeyListFunc(pageNum.value, pageSize.value); | |||||
| }; | |||||
| const getKeyListFunc = async (PageNum, PageSize) => { | |||||
| try { | |||||
| const res = await keyListApi(PageNum, PageSize); | |||||
| console.log(res, "res"); | |||||
| tableData.value = res.data.list; | |||||
| total.value = res.data.total * 1; | |||||
| } catch (error) { | |||||
| console.log(error, "err"); | |||||
| } | |||||
| }; | |||||
| onMounted(() => { | |||||
| getKeyListFunc(1, 10); | |||||
| }); | |||||
| </script> | |||||
| <style lang="scss" scoped> | |||||
| .page { | |||||
| height: calc(100vh - 80px); | |||||
| // height: calc(100vh - 80px); | |||||
| background-color: #ffffff; | |||||
| border-radius: 30px 0 0 0; | |||||
| overflow: hidden; | |||||
| padding: 10vh; | |||||
| .pagination { | |||||
| position: fixed; | |||||
| left: 55%; | |||||
| bottom: 8vh; | |||||
| transform: translateX(-50%); | |||||
| border-radius: 5px; | |||||
| padding: 10px 20px; | |||||
| z-index: 99; | |||||
| transition: all 0.3s; | |||||
| cursor: pointer; | |||||
| &:hover { | |||||
| background-color: #b8b8b873; | |||||
| } | |||||
| } | |||||
| } | |||||
| </style> | |||||
| @@ -31,7 +31,7 @@ | |||||
| </el-tooltip> | </el-tooltip> | ||||
| </div> | </div> | ||||
| <el-form-item prop="email"> | |||||
| <el-form-item prop="username"> | |||||
| <div class="text-white"> | <div class="text-white"> | ||||
| <svg-icon icon-class="user" /> | <svg-icon icon-class="user" /> | ||||
| </div> | </div> | ||||
| @@ -39,8 +39,8 @@ | |||||
| class="flex-1" | class="flex-1" | ||||
| ref="email" | ref="email" | ||||
| size="large" | size="large" | ||||
| v-model="loginData.email" | |||||
| :placeholder="$t('login.email')" | |||||
| v-model="loginData.username" | |||||
| :placeholder="$t('login.username')" | |||||
| name="email" | name="email" | ||||
| /> | /> | ||||
| </el-form-item> | </el-form-item> | ||||
| @@ -67,14 +67,14 @@ | |||||
| </el-form-item> | </el-form-item> | ||||
| <!-- 验证码 --> | <!-- 验证码 --> | ||||
| <el-form-item prop="verifyCode"> | |||||
| <el-form-item prop="captcha"> | |||||
| <span class="text-white"> | <span class="text-white"> | ||||
| <svg-icon icon-class="verify_code" /> | <svg-icon icon-class="verify_code" /> | ||||
| </span> | </span> | ||||
| <el-input | <el-input | ||||
| v-model="loginData.verifyCode" | |||||
| v-model="loginData.captcha" | |||||
| auto-complete="off" | auto-complete="off" | ||||
| :placeholder="$t('login.verifyCode')" | |||||
| :placeholder="$t('login.captcha')" | |||||
| class="flex-1" | class="flex-1" | ||||
| @keyup.enter="handleLogin" | @keyup.enter="handleLogin" | ||||
| /> | /> | ||||
| @@ -111,9 +111,6 @@ | |||||
| </el-button> | </el-button> | ||||
| <div :class="currentLan == 'zh-cn' ? 'bottomBtnCN' : 'bottomBtnEN'"> | <div :class="currentLan == 'zh-cn' ? 'bottomBtnCN' : 'bottomBtnEN'"> | ||||
| <div style="margin-bottom: 5px" @click="loginFlag(2)"> | |||||
| <span class="join">{{ $t("login.signUp") }}</span> | |||||
| </div> | |||||
| <div style="margin-bottom: 5px"> | <div style="margin-bottom: 5px"> | ||||
| <span class="join" @click="loginFlag(7)">{{ | <span class="join" @click="loginFlag(7)">{{ | ||||
| $t("login.SMSLogin") | $t("login.SMSLogin") | ||||
| @@ -126,188 +123,8 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </el-form> | </el-form> | ||||
| <!-- 注册账户 isLogin == 2--> | |||||
| <el-form | |||||
| v-if="isLogin == 2" | |||||
| ref="loginFormRef" | |||||
| :model="loginData2" | |||||
| :rules="loginRules" | |||||
| class="login-form" | |||||
| > | |||||
| <div class="flex text-white items-center"> | |||||
| <span class="flex-1 text-center">{{ | |||||
| $t("login.title") + " " + $t("login.register") | |||||
| }}</span> | |||||
| <el-tooltip | |||||
| class="box-item" | |||||
| effect="dark" | |||||
| :content="$t('navbar.LanguageChange')" | |||||
| placement="top-start" | |||||
| > | |||||
| <lang-select class="navItem" style="color: #ffffff" /> | |||||
| </el-tooltip> | |||||
| </div> | |||||
| <el-form-item prop="email"> | |||||
| <div class="text-white"> | |||||
| <svg-icon icon-class="user" /> | |||||
| </div> | |||||
| <el-input | |||||
| class="flex-1" | |||||
| ref="email" | |||||
| size="large" | |||||
| v-model="loginData2.email" | |||||
| :placeholder="$t('login.email')" | |||||
| name="email" | |||||
| /> | |||||
| </el-form-item> | |||||
| <el-form-item prop="password"> | |||||
| <span class="text-white"> | |||||
| <svg-icon icon-class="password" /> | |||||
| </span> | |||||
| <el-input | |||||
| class="flex-1" | |||||
| v-model="loginData2.password" | |||||
| :placeholder="$t('login.password')" | |||||
| :type="passwordVisible === false ? 'password' : 'input'" | |||||
| size="large" | |||||
| name="password" | |||||
| /> | |||||
| <span class="mr-2" @click="passwordVisible = !passwordVisible"> | |||||
| <svg-icon | |||||
| :icon-class="passwordVisible === false ? 'eye' : 'eye-open'" | |||||
| class="text-white cursor-pointer" | |||||
| /> | |||||
| </span> | |||||
| </el-form-item> | |||||
| <el-form-item prop="confirmPassword"> | |||||
| <span class="text-white"> | |||||
| <svg-icon icon-class="password" /> | |||||
| </span> | |||||
| <el-input | |||||
| class="flex-1" | |||||
| v-model="loginData2.confirmPassword" | |||||
| :placeholder="$t('login.confirmPassword')" | |||||
| :type="passwordVisible === false ? 'password' : 'input'" | |||||
| size="large" | |||||
| name="confirmPassword" | |||||
| @keyup.enter="handleRegister" | |||||
| /> | |||||
| <span class="mr-2" @click="passwordVisible = !passwordVisible"> | |||||
| <svg-icon | |||||
| :icon-class="passwordVisible === false ? 'eye' : 'eye-open'" | |||||
| class="text-white cursor-pointer" | |||||
| /> | |||||
| </span> | |||||
| </el-form-item> | |||||
| <el-button | |||||
| size="default" | |||||
| :loading="loading" | |||||
| type="primary" | |||||
| class="loginBtn" | |||||
| @click.prevent="handleRegister" | |||||
| > | |||||
| <el-icon | |||||
| v-if="isRegistering" | |||||
| style="margin-right: 10px" | |||||
| class="is-loading" | |||||
| > | |||||
| <svg | |||||
| viewBox="0 0 1024 1024" | |||||
| xmlns="http://www.w3.org/2000/svg" | |||||
| data-v-ea893728="" | |||||
| > | |||||
| <path | |||||
| fill="currentColor" | |||||
| d="M512 64a32 32 0 0 1 32 32v192a32 32 0 0 1-64 0V96a32 32 0 0 1 32-32zm0 640a32 32 0 0 1 32 32v192a32 32 0 1 1-64 0V736a32 32 0 0 1 32-32zm448-192a32 32 0 0 1-32 32H736a32 32 0 1 1 0-64h192a32 32 0 0 1 32 32zm-640 0a32 32 0 0 1-32 32H96a32 32 0 0 1 0-64h192a32 32 0 0 1 32 32zM195.2 195.2a32 32 0 0 1 45.248 0L376.32 331.008a32 32 0 0 1-45.248 45.248L195.2 240.448a32 32 0 0 1 0-45.248zm452.544 452.544a32 32 0 0 1 45.248 0L828.8 783.552a32 32 0 0 1-45.248 45.248L647.744 692.992a32 32 0 0 1 0-45.248zM828.8 195.264a32 32 0 0 1 0 45.184L692.992 376.32a32 32 0 0 1-45.248-45.248l135.808-135.808a32 32 0 0 1 45.248 0zm-452.544 452.48a32 32 0 0 1 0 45.248L240.448 828.8a32 32 0 0 1-45.248-45.248l135.808-135.808a32 32 0 0 1 45.248 0z" | |||||
| ></path> | |||||
| </svg> | |||||
| </el-icon> | |||||
| {{ $t("login.registerBtn") }} | |||||
| </el-button> | |||||
| <div :class="currentLan == 'zh-cn' ? 'bottomBtnCN' : 'bottomBtnEN'"> | |||||
| <div style="margin-bottom: 5px" @click="loginFlag(1)"> | |||||
| <span class="join">{{ $t("login.signIn") }}</span> | |||||
| </div> | |||||
| <div> | |||||
| <span class="join" @click="loginFlag(3)">{{ | |||||
| $t("login.forgetPwd") | |||||
| }}</span> | |||||
| </div> | |||||
| </div> | |||||
| </el-form> | |||||
| <!-- 注册账户之后输入短信验证码 isLogin == 6--> | <!-- 注册账户之后输入短信验证码 isLogin == 6--> | ||||
| <el-form | |||||
| v-if="isLogin == 6" | |||||
| ref="loginFormRef" | |||||
| :model="loginData6" | |||||
| :rules="loginRules" | |||||
| class="login-form" | |||||
| > | |||||
| <div class="flex text-white items-center"> | |||||
| <span class="flex-1 text-center">{{ | |||||
| $t("login.title") + " " + $t("login.register") | |||||
| }}</span> | |||||
| <el-tooltip | |||||
| class="box-item" | |||||
| effect="dark" | |||||
| :content="$t('navbar.LanguageChange')" | |||||
| placement="top-start" | |||||
| > | |||||
| <lang-select class="navItem" style="color: #ffffff" /> | |||||
| </el-tooltip> | |||||
| </div> | |||||
| <el-form-item prop="SMSCode"> | |||||
| <div class="text-white"> | |||||
| <svg-icon icon-class="user" /> | |||||
| </div> | |||||
| <el-input | |||||
| class="flex-1" | |||||
| ref="email" | |||||
| size="large" | |||||
| v-model="loginData6.SMSCode" | |||||
| :placeholder="$t('login.SMSCode')" | |||||
| name="email" | |||||
| /> | |||||
| </el-form-item> | |||||
| <el-button | |||||
| size="default" | |||||
| :loading="loading" | |||||
| type="primary" | |||||
| class="loginBtn" | |||||
| @click.prevent="handleRegister" | |||||
| > | |||||
| <el-icon | |||||
| v-if="isRegistering" | |||||
| style="margin-right: 10px" | |||||
| class="is-loading" | |||||
| > | |||||
| <svg | |||||
| viewBox="0 0 1024 1024" | |||||
| xmlns="http://www.w3.org/2000/svg" | |||||
| data-v-ea893728="" | |||||
| > | |||||
| <path | |||||
| fill="currentColor" | |||||
| d="M512 64a32 32 0 0 1 32 32v192a32 32 0 0 1-64 0V96a32 32 0 0 1 32-32zm0 640a32 32 0 0 1 32 32v192a32 32 0 1 1-64 0V736a32 32 0 0 1 32-32zm448-192a32 32 0 0 1-32 32H736a32 32 0 1 1 0-64h192a32 32 0 0 1 32 32zm-640 0a32 32 0 0 1-32 32H96a32 32 0 0 1 0-64h192a32 32 0 0 1 32 32zM195.2 195.2a32 32 0 0 1 45.248 0L376.32 331.008a32 32 0 0 1-45.248 45.248L195.2 240.448a32 32 0 0 1 0-45.248zm452.544 452.544a32 32 0 0 1 45.248 0L828.8 783.552a32 32 0 0 1-45.248 45.248L647.744 692.992a32 32 0 0 1 0-45.248zM828.8 195.264a32 32 0 0 1 0 45.184L692.992 376.32a32 32 0 0 1-45.248-45.248l135.808-135.808a32 32 0 0 1 45.248 0zm-452.544 452.48a32 32 0 0 1 0 45.248L240.448 828.8a32 32 0 0 1-45.248-45.248l135.808-135.808a32 32 0 0 1 45.248 0z" | |||||
| ></path> | |||||
| </svg> | |||||
| </el-icon> | |||||
| {{ $t("login.registerBtn") }} | |||||
| </el-button> | |||||
| <div :class="currentLan == 'zh-cn' ? 'bottomBtnCN' : 'bottomBtnEN'"> | |||||
| <div style="margin-bottom: 5px" @click="loginFlag(1)"> | |||||
| <span class="join">{{ $t("login.signIn") }}</span> | |||||
| </div> | |||||
| </div> | |||||
| </el-form> | |||||
| <!-- 忘记密码 isLogin == 3--> | <!-- 忘记密码 isLogin == 3--> | ||||
| <el-form | <el-form | ||||
| v-if="isLogin == 3" | v-if="isLogin == 3" | ||||
| @@ -691,9 +508,6 @@ | |||||
| </el-button> | </el-button> | ||||
| <div :class="currentLan == 'zh-cn' ? 'bottomBtnCN' : 'bottomBtnEN'"> | <div :class="currentLan == 'zh-cn' ? 'bottomBtnCN' : 'bottomBtnEN'"> | ||||
| <div style="margin-bottom: 5px" @click="loginFlag(2)"> | |||||
| <span class="join">{{ $t("login.signUp") }}</span> | |||||
| </div> | |||||
| <div style="margin-bottom: 5px"> | <div style="margin-bottom: 5px"> | ||||
| <span class="join" @click="loginFlag(1)">{{ | <span class="join" @click="loginFlag(1)">{{ | ||||
| $t("login.pwsLogin") | $t("login.pwsLogin") | ||||
| @@ -786,8 +600,7 @@ | |||||
| import LangSelect from "@/components/LangSelect/index.vue"; | import LangSelect from "@/components/LangSelect/index.vue"; | ||||
| import SvgIcon from "@/components/SvgIcon/index.vue"; | import SvgIcon from "@/components/SvgIcon/index.vue"; | ||||
| import { | import { | ||||
| register, | |||||
| login, | |||||
| loginApi, | |||||
| sendRegisterEmail, | sendRegisterEmail, | ||||
| getCodeImgUrl, | getCodeImgUrl, | ||||
| sendUpdPwdEmailApi, | sendUpdPwdEmailApi, | ||||
| @@ -799,6 +612,7 @@ import { | |||||
| doFindInviteCode, | doFindInviteCode, | ||||
| doUpdateInviteCode, | doUpdateInviteCode, | ||||
| } from "@/apis/login"; | } from "@/apis/login"; | ||||
| import { getMenuNavApi } from "@/apis/Permission.js"; | |||||
| import axios from "axios"; | import axios from "axios"; | ||||
| // 状态管理依赖 | // 状态管理依赖 | ||||
| @@ -848,9 +662,9 @@ const isLogining = ref(false); | |||||
| const isRegistering = ref(false); | const isRegistering = ref(false); | ||||
| const loginData = ref({ | const loginData = ref({ | ||||
| email: "", | |||||
| username: "", | |||||
| password: "", | password: "", | ||||
| verifyCode: "", | |||||
| captcha: "", | |||||
| }); | }); | ||||
| const loginData2 = ref({ | const loginData2 = ref({ | ||||
| @@ -882,6 +696,13 @@ const loginData8 = ref({ | |||||
| invitatioCode: "", | invitatioCode: "", | ||||
| }); | }); | ||||
| const loginRules = ref({ | const loginRules = ref({ | ||||
| username: [ | |||||
| { | |||||
| required: true, | |||||
| trigger: "blur", | |||||
| validator: passwordValidator, | |||||
| }, | |||||
| ], | |||||
| email: [ | email: [ | ||||
| { | { | ||||
| required: true, | required: true, | ||||
| @@ -894,13 +715,13 @@ const loginRules = ref({ | |||||
| confirmPassword: [ | confirmPassword: [ | ||||
| { required: true, trigger: "blur", validator: confirmPasswordValidator }, | { required: true, trigger: "blur", validator: confirmPasswordValidator }, | ||||
| ], | ], | ||||
| verifyCode: [ | |||||
| captcha: [ | |||||
| { | { | ||||
| required: true, | required: true, | ||||
| trigger: "blur", | trigger: "blur", | ||||
| message: | message: | ||||
| currentLan.value == "zh-cn" | currentLan.value == "zh-cn" | ||||
| ? "请输入验证码" | |||||
| ? "请输入验证码2" | |||||
| : "Please input verifyCode", | : "Please input verifyCode", | ||||
| }, | }, | ||||
| ], | ], | ||||
| @@ -928,8 +749,8 @@ const loginRules = ref({ | |||||
| watch(currentLan, (newValue, oldValue) => { | watch(currentLan, (newValue, oldValue) => { | ||||
| const loginRule = loginRules.value; | const loginRule = loginRules.value; | ||||
| loginRule.verifyCode[0].message = | |||||
| newValue == "zh-cn" ? "请输入验证码" : "Please input verifyCode"; | |||||
| loginRule.captcha[0].message = | |||||
| newValue == "zh-cn" ? "请输入验证码1" : "Please input verifyCode"; | |||||
| setTimeout(() => { | setTimeout(() => { | ||||
| loginFormRef.value.resetFields(); | loginFormRef.value.resetFields(); | ||||
| getInfo(); | getInfo(); | ||||
| @@ -973,7 +794,7 @@ function getInfo() { | |||||
| const deCodeUserInfo = decodeURI(data as any); | const deCodeUserInfo = decodeURI(data as any); | ||||
| const userInfo = JSON.parse(deCodeUserInfo); | const userInfo = JSON.parse(deCodeUserInfo); | ||||
| if (userInfo) { | if (userInfo) { | ||||
| loginData.value.email = userInfo.email ? userInfo.email : ""; | |||||
| loginData.value.username = userInfo.email ? userInfo.email : ""; | |||||
| loginData.value.password = userInfo.password ? userInfo.password : ""; | loginData.value.password = userInfo.password ? userInfo.password : ""; | ||||
| } | } | ||||
| } | } | ||||
| @@ -1091,48 +912,7 @@ function confirmPasswordValidator5(rule: any, value: any, callback: any) { | |||||
| } | } | ||||
| //#endregion ---------------------------- | //#endregion ---------------------------- | ||||
| // 登录行为 | |||||
| function handleLogin() { | |||||
| loginFormRef.value.validate((val: any) => { | |||||
| if (val) { | |||||
| const data = { | |||||
| phone: loginData.value.email, | |||||
| password: loginData.value.password, | |||||
| code: loginData.value.verifyCode, | |||||
| }; | |||||
| isLogining.value = true; | |||||
| doLogin(data); | |||||
| } else { | |||||
| const msg = | |||||
| currentLan.value == "zh-cn" | |||||
| ? "请检查信息格式!" | |||||
| : "Please check the format !"; | |||||
| ElMessage.error(msg); | |||||
| return; | |||||
| } | |||||
| }); | |||||
| } | |||||
| // 注册行为 | // 注册行为 | ||||
| function handleRegister() { | |||||
| loginFormRef.value.validate((val: any) => { | |||||
| if (val) { | |||||
| const data = { | |||||
| phone: loginData2.value.email, | |||||
| password: loginData2.value.password, | |||||
| }; | |||||
| isRegistering.value = true; | |||||
| doRegister(data); | |||||
| } else { | |||||
| const msg = | |||||
| currentLan.value == "zh-cn" | |||||
| ? "请检查信息格式!" | |||||
| : "Please check the format !"; | |||||
| ElMessage.error(msg); | |||||
| return; | |||||
| } | |||||
| }); | |||||
| } | |||||
| //#region 忘记密码 表单3 | //#region 忘记密码 表单3 | ||||
| function sendEmailforgetPwd() { | function sendEmailforgetPwd() { | ||||
| @@ -1329,7 +1109,7 @@ async function checkInviteCode() { | |||||
| isLogin.value = 8; | isLogin.value = 8; | ||||
| // 有邀请码直接前往我的页面 | // 有邀请码直接前往我的页面 | ||||
| } else if (status == 1) { | } else if (status == 1) { | ||||
| userInfoPinia.getUserInfo(); //保存邮箱到pinia | |||||
| // userInfoPinia.getUserInfo(); //保存邮箱到pinia | |||||
| ElMessage.success( | ElMessage.success( | ||||
| 'currentLan.value == "zh-cn" ? "登录成功!" : "Welcome to Metavatar!"' | 'currentLan.value == "zh-cn" ? "登录成功!" : "Welcome to Metavatar!"' | ||||
| ); | ); | ||||
| @@ -1351,7 +1131,7 @@ async function handleInvitatioCode() { | |||||
| }; | }; | ||||
| try { | try { | ||||
| const res = await doUpdateInviteCode(data); | const res = await doUpdateInviteCode(data); | ||||
| userInfoPinia.getUserInfo(); //保存邮箱到pinia | |||||
| // userInfoPinia.getUserInfo(); //保存邮箱到pinia | |||||
| ElMessage.success( | ElMessage.success( | ||||
| 'currentLan.value == "zh-cn" ? "登录成功!" : "Welcome to Metavatar!"' | 'currentLan.value == "zh-cn" ? "登录成功!" : "Welcome to Metavatar!"' | ||||
| ); | ); | ||||
| @@ -1370,58 +1150,75 @@ function getCode() { | |||||
| axios({ | axios({ | ||||
| url: getCodeImgUrl, | url: getCodeImgUrl, | ||||
| method: "get", | method: "get", | ||||
| }).then(() => { | |||||
| }).then((res) => { | |||||
| verifyCodeUrl.value = getCodeImgUrl; | verifyCodeUrl.value = getCodeImgUrl; | ||||
| showCodeImg.value = true; | showCodeImg.value = true; | ||||
| }); | }); | ||||
| } | } | ||||
| /** | /** | ||||
| * @description:注册 | |||||
| * @description:登录 | |||||
| * @param {Object} data | * @param {Object} data | ||||
| * @return: data | * @return: data | ||||
| */ | */ | ||||
| async function doRegister(data: object) { | |||||
| /** | |||||
| * @description:重新发送邮件 | |||||
| * @param {string} email | |||||
| * @return: data | |||||
| */ | |||||
| async function reSendEmail(email: string) { | |||||
| const msg = | const msg = | ||||
| currentLan.value == "zh-cn" ? "注册成功!" : "Registered successfully"; | |||||
| await register(data) | |||||
| currentLan.value == "zh-cn" | |||||
| ? "确认信息已发送至您的邮箱,请注意查收!" | |||||
| : "An email has been send to you, Please pay attention to confirm !"; | |||||
| await sendRegisterEmail(email) | |||||
| .then((res) => { | .then((res) => { | ||||
| console.log(res, "res"); | console.log(res, "res"); | ||||
| isRegistering.value = false; | |||||
| ElMessage.success(msg); | ElMessage.success(msg); | ||||
| isLogin.value = 1; | |||||
| // 注册成功将账号密码保存到本地 | |||||
| saveInfo(data); | |||||
| router.go(0); | |||||
| }) | }) | ||||
| .catch((err) => { | .catch((err) => { | ||||
| // 注册失败刷新验证码 | |||||
| getCode(); | |||||
| isRegistering.value = false; | |||||
| console.log(err, "err"); | console.log(err, "err"); | ||||
| ElMessage.error(err.message); | ElMessage.error(err.message); | ||||
| }); | }); | ||||
| } | } | ||||
| /** | |||||
| * @description:登录 | |||||
| * @param {Object} data | |||||
| * @return: data | |||||
| */ | |||||
| //#region 新登录 | |||||
| // 登录行为 | |||||
| function handleLogin() { | |||||
| loginFormRef.value.validate((val: any) => { | |||||
| if (val) { | |||||
| const data = { | |||||
| username: loginData.value.username, | |||||
| password: loginData.value.password, | |||||
| captcha: loginData.value.captcha, | |||||
| }; | |||||
| isLogining.value = true; | |||||
| doLogin(data); | |||||
| } else { | |||||
| const msg = | |||||
| currentLan.value == "zh-cn" | |||||
| ? "请检查信息格式!" | |||||
| : "Please check the format !"; | |||||
| ElMessage.error(msg); | |||||
| return; | |||||
| } | |||||
| }); | |||||
| } | |||||
| async function doLogin(data: any) { | async function doLogin(data: any) { | ||||
| const msg = | const msg = | ||||
| currentLan.value == "zh-cn" ? "登录成功!" : "Welcome to Metavatar!"; | currentLan.value == "zh-cn" ? "登录成功!" : "Welcome to Metavatar!"; | ||||
| await login(data) | |||||
| await loginApi(data) | |||||
| .then(async (res) => { | .then(async (res) => { | ||||
| console.log(res, "res"); | console.log(res, "res"); | ||||
| localStorage.setItem("AccessToken", res.data.token); | |||||
| // localStorage.setItem("AccessToken", res.data.token); | |||||
| // 注册成功将账号密码保存到本地 | // 注册成功将账号密码保存到本地 | ||||
| saveInfo(data); | saveInfo(data); | ||||
| await getMenuNavFunc(); | |||||
| isLogining.value = false; | isLogining.value = false; | ||||
| // await checkInviteCode(); | // await checkInviteCode(); | ||||
| userInfoPinia.getUserInfo(); //保存邮箱到pinia | |||||
| // userInfoPinia.getUserInfo(); //保存邮箱到pinia | |||||
| ElMessage.success(msg); | ElMessage.success(msg); | ||||
| router.push("/createVideo"); | |||||
| router.push("/model"); | |||||
| }) | }) | ||||
| .catch((err) => { | .catch((err) => { | ||||
| console.log(err, "err"); | console.log(err, "err"); | ||||
| @@ -1434,28 +1231,17 @@ async function doLogin(data: any) { | |||||
| } | } | ||||
| }); | }); | ||||
| } | } | ||||
| //#endregion | |||||
| /** | |||||
| * @description:重新发送邮件 | |||||
| * @param {string} email | |||||
| * @return: data | |||||
| */ | |||||
| async function reSendEmail(email: string) { | |||||
| const msg = | |||||
| currentLan.value == "zh-cn" | |||||
| ? "确认信息已发送至您的邮箱,请注意查收!" | |||||
| : "An email has been send to you, Please pay attention to confirm !"; | |||||
| await sendRegisterEmail(email) | |||||
| .then((res) => { | |||||
| console.log(res, "res"); | |||||
| ElMessage.success(msg); | |||||
| }) | |||||
| .catch((err) => { | |||||
| console.log(err, "err"); | |||||
| ElMessage.error(err.message); | |||||
| }); | |||||
| //#region 获取菜单导航路由 | |||||
| async function getMenuNavFunc() { | |||||
| try { | |||||
| const res = await getMenuNavApi(); | |||||
| } catch (error) { | |||||
| console.log(error); | |||||
| } | |||||
| } | } | ||||
| //#endregion -------------------------------- | |||||
| onMounted(() => { | onMounted(() => { | ||||
| getCode(); | getCode(); | ||||
| getInfo(); | getInfo(); | ||||
| @@ -0,0 +1,16 @@ | |||||
| <template> | |||||
| <div class="page flex justify-around"></div> | |||||
| </template> | |||||
| <!-- videoType==1为竖,==2为横 --> | |||||
| <script setup></script> | |||||
| <style lang="scss" scoped> | |||||
| .page { | |||||
| height: calc(100vh - 80px); | |||||
| // height: calc(100vh - 80px); | |||||
| background-color: #fff; | |||||
| border-radius: 30px 0 0 0; | |||||
| overflow: hidden; | |||||
| } | |||||
| </style> | |||||
| @@ -0,0 +1,16 @@ | |||||
| <template> | |||||
| <div class="page flex justify-around"></div> | |||||
| </template> | |||||
| <!-- videoType==1为竖,==2为横 --> | |||||
| <script setup></script> | |||||
| <style lang="scss" scoped> | |||||
| .page { | |||||
| height: calc(100vh - 80px); | |||||
| // height: calc(100vh - 80px); | |||||
| background-color: #fff; | |||||
| border-radius: 30px 0 0 0; | |||||
| overflow: hidden; | |||||
| } | |||||
| </style> | |||||
| @@ -0,0 +1,16 @@ | |||||
| <template> | |||||
| <div class="page flex justify-around"></div> | |||||
| </template> | |||||
| <!-- videoType==1为竖,==2为横 --> | |||||
| <script setup></script> | |||||
| <style lang="scss" scoped> | |||||
| .page { | |||||
| height: calc(100vh - 80px); | |||||
| // height: calc(100vh - 80px); | |||||
| background-color: #fff; | |||||
| border-radius: 30px 0 0 0; | |||||
| overflow: hidden; | |||||
| } | |||||
| </style> | |||||
| @@ -1,698 +0,0 @@ | |||||
| <template> | |||||
| <div class="page"> | |||||
| <!-- 搜索框 --> | |||||
| <div class="top"> | |||||
| <div class="flex justify-between" style="width: 300px"> | |||||
| <el-input | |||||
| v-model="title" | |||||
| :placeholder="$t('myCreating.search')" | |||||
| @keyup.enter="searchVideoList" | |||||
| /> | |||||
| <el-icon class="icon-edit" @click="searchVideoList" | |||||
| ><i-ep-search | |||||
| /></el-icon> | |||||
| </div> | |||||
| </div> | |||||
| <!-- 作品列表 --> | |||||
| <div v-if="!isLoading"> | |||||
| <div v-if="videoList.length > 0" class="workList flex"> | |||||
| <div class="workItem" v-for="item in videoList" :key="item.id"> | |||||
| <div class="workImg"> | |||||
| <img | |||||
| v-if="item.coverImg" | |||||
| class="coverImg inmiddle" | |||||
| :src="item.coverImg" | |||||
| alt="" | |||||
| /> | |||||
| <img | |||||
| v-else | |||||
| class="takePlace inmiddle" | |||||
| src="@/assets/img/left-top-logo.png" | |||||
| alt="" | |||||
| /> | |||||
| </div> | |||||
| <div :class="'statusName ' + item.statusName"> | |||||
| {{ $t("myCreating." + item.statusName) }} | |||||
| </div> | |||||
| <div class="workInfo flex"> | |||||
| <span>{{ item.title }}</span> | |||||
| <span>{{ dayjs(item.createDate).format("YYYY-MM-DD") }}</span> | |||||
| </div> | |||||
| <!-- 更多遮罩层 --> | |||||
| <div | |||||
| class="more" | |||||
| @mouseleave="mouseleave" | |||||
| @click="clickVideoItem(item)" | |||||
| > | |||||
| <el-icon | |||||
| v-if="[0].includes(item.videoStatus)" | |||||
| class="icon-videoPlay" | |||||
| ><i-ep-edit | |||||
| /></el-icon> | |||||
| <el-icon | |||||
| v-if="[1, 2, 4, 6].includes(item.videoStatus)" | |||||
| class="icon-videoPlay" | |||||
| ><i-ep-loading | |||||
| /></el-icon> | |||||
| <el-icon | |||||
| v-if="[3].includes(item.videoStatus)" | |||||
| class="icon-videoPlay" | |||||
| ><i-ep-closeBold | |||||
| /></el-icon> | |||||
| <el-icon | |||||
| v-if="[5].includes(item.videoStatus)" | |||||
| class="icon-videoPlay" | |||||
| ><i-ep-videoPlay | |||||
| /></el-icon> | |||||
| <div class="showBtn" @click.stop="mouseenter(item)">...</div> | |||||
| <div class="btns" v-show="showPopup"> | |||||
| <!-- 下载按钮 --> | |||||
| <div | |||||
| class="btns-item" | |||||
| @click.stop="handleDownload(item.videoPlayUrl)" | |||||
| > | |||||
| <div class="btns-item-icon"> | |||||
| <el-icon class="icon-delete"><i-ep-download /></el-icon> | |||||
| </div> | |||||
| <div class="text">{{ $t("myCreating.download") }}</div> | |||||
| </div> | |||||
| <!-- 删除按钮 --> | |||||
| <div | |||||
| class="btns-item" | |||||
| @click.stop="handelDelete(item.id, item.title)" | |||||
| > | |||||
| <div class="btns-item-icon"> | |||||
| <el-icon class="icon-delete"><i-ep-delete /></el-icon> | |||||
| </div> | |||||
| <div class="text">{{ $t("myCreating.delete") }}</div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div v-if="videoList.length == 0" class="noList"> | |||||
| <div class="title"> | |||||
| {{ $t("myCreating.noList") }} | |||||
| </div> | |||||
| <div class="goCreate" @click="goCreate"> | |||||
| {{ $t("myCreating.goCreate") }} | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div v-if="isLoading" class="loadingIcon"> | |||||
| <el-icon class="is-loading"> | |||||
| <svg | |||||
| viewBox="0 0 1024 1024" | |||||
| xmlns="http://www.w3.org/2000/svg" | |||||
| data-v-ea893728="" | |||||
| > | |||||
| <path | |||||
| fill="currentColor" | |||||
| d="M512 64a32 32 0 0 1 32 32v192a32 32 0 0 1-64 0V96a32 32 0 0 1 32-32zm0 640a32 32 0 0 1 32 32v192a32 32 0 1 1-64 0V736a32 32 0 0 1 32-32zm448-192a32 32 0 0 1-32 32H736a32 32 0 1 1 0-64h192a32 32 0 0 1 32 32zm-640 0a32 32 0 0 1-32 32H96a32 32 0 0 1 0-64h192a32 32 0 0 1 32 32zM195.2 195.2a32 32 0 0 1 45.248 0L376.32 331.008a32 32 0 0 1-45.248 45.248L195.2 240.448a32 32 0 0 1 0-45.248zm452.544 452.544a32 32 0 0 1 45.248 0L828.8 783.552a32 32 0 0 1-45.248 45.248L647.744 692.992a32 32 0 0 1 0-45.248zM828.8 195.264a32 32 0 0 1 0 45.184L692.992 376.32a32 32 0 0 1-45.248-45.248l135.808-135.808a32 32 0 0 1 45.248 0zm-452.544 452.48a32 32 0 0 1 0 45.248L240.448 828.8a32 32 0 0 1-45.248-45.248l135.808-135.808a32 32 0 0 1 45.248 0z" | |||||
| ></path> | |||||
| </svg> | |||||
| </el-icon> | |||||
| <span class="loadingText">{{ $t("myCreating.loading") }}</span> | |||||
| </div> | |||||
| <!-- 弹出框预览作品 --> | |||||
| <el-dialog | |||||
| destroy-on-close | |||||
| class="elDialog" | |||||
| v-model="showDialog" | |||||
| :title="presentItem.title" | |||||
| width="40%" | |||||
| center | |||||
| > | |||||
| <div class="videoBox"> | |||||
| <video | |||||
| v-if="presentItem.videoPlayUrl" | |||||
| controls="true" | |||||
| class="" | |||||
| :src="presentItem.videoPlayUrl" | |||||
| ></video> | |||||
| <div v-else class="insteadVideo"> | |||||
| {{ $t("myCreating." + presentItem.statusName + "Text") }} | |||||
| <span v-if="presentItem.videoStatus == 3">{{ | |||||
| presentItem.videoMsg | |||||
| }}</span> | |||||
| </div> | |||||
| <!-- 有视频路径的页脚 --> | |||||
| <div class="footer" v-if="presentItem.videoPlayUrl"> | |||||
| <span class="dialog-footer"> | |||||
| <!-- dialog下载按钮 --> | |||||
| <button | |||||
| class="elBtn" | |||||
| type="primary" | |||||
| @click.stop="handleDownload(presentItem.videoPlayUrl)" | |||||
| > | |||||
| <el-icon class="icon-delete"><i-ep-download /></el-icon | |||||
| >{{ $t("myCreating.download") }} | |||||
| </button> | |||||
| <!-- dialog删除按钮 --> | |||||
| <button | |||||
| class="elBtn" | |||||
| @click.stop="handelDelete(presentItem.id, presentItem.title)" | |||||
| > | |||||
| <el-icon class="icon-delete"><i-ep-delete /></el-icon | |||||
| >{{ $t("myCreating.delete") }} | |||||
| </button> | |||||
| </span> | |||||
| </div> | |||||
| <!-- 无视频路径的页脚 --> | |||||
| <div class="footer" v-if="!presentItem.videoPlayUrl"> | |||||
| <span class="dialog-footer"> | |||||
| <!-- dialog编辑按钮 --> | |||||
| <button | |||||
| class="elBtn" | |||||
| type="primary" | |||||
| @click.stop=" | |||||
| router.push({ | |||||
| path: '/createVideo', | |||||
| query: { id: presentItem.id }, | |||||
| }) | |||||
| " | |||||
| v-if="[0, 3].includes(presentItem.videoStatus)" | |||||
| > | |||||
| {{ $t("myCreating.edit") }} | |||||
| </button> | |||||
| </span> | |||||
| </div> | |||||
| </div> | |||||
| </el-dialog> | |||||
| <!-- 分页 --> | |||||
| <div v-if="!isLoading" class="pagination"> | |||||
| <el-pagination | |||||
| v-model:current-page="pageNum" | |||||
| v-model:page-size="pageSize" | |||||
| :page-sizes="[10, 20, 50, 100, 200]" | |||||
| :small="false" | |||||
| :disabled="false" | |||||
| :background="true" | |||||
| layout="total, sizes, prev, pager, next, jumper" | |||||
| :total="total" | |||||
| @size-change="handleSizeChange" | |||||
| @current-change="handleCurrentChange" | |||||
| /> | |||||
| </div> | |||||
| </div> | |||||
| </template> | |||||
| <script setup> | |||||
| import { | |||||
| userPhotoVideoListApi, | |||||
| delUserPhotoVideoByIDApi, | |||||
| } from "@/apis/myCreating"; | |||||
| import { timestampToTime } from "@/utils/tools"; | |||||
| import { useI18n } from "vue-i18n"; | |||||
| import { getStatus } from "./videoStatus"; | |||||
| import { useRouter } from "vue-router"; | |||||
| import dayjs from "dayjs"; | |||||
| const router = useRouter(); | |||||
| // 当前语言状态与国际化组件 | |||||
| const { locale } = useI18n(); | |||||
| const lanChange = ref(locale); | |||||
| const title = ref(""); | |||||
| const pageNum = ref(1); | |||||
| const pageSize = ref(10); | |||||
| const total = ref(0); | |||||
| // 弹窗显示隐藏 | |||||
| const showDialog = ref(false); | |||||
| const isLoading = ref(true); | |||||
| // 当前作品 | |||||
| const presentItem = ref(""); | |||||
| // 作品列表 | |||||
| const videoList = ref([]); | |||||
| const handleSizeChange = (val) => { | |||||
| pageSize.value = val; | |||||
| getPhotoVideoList(pageNum.value, pageSize.value, title.value); | |||||
| }; | |||||
| const handleCurrentChange = (val) => { | |||||
| pageNum.value = val; | |||||
| getPhotoVideoList(pageNum.value, pageSize.value, title.value); | |||||
| }; | |||||
| // 点击作品 | |||||
| function clickVideoItem(item) { | |||||
| showDialog.value = true; | |||||
| presentItem.value = item; | |||||
| } | |||||
| // 删除框是否显示 | |||||
| let showPopup = ref(false); | |||||
| function mouseleave() { | |||||
| showPopup.value = false; | |||||
| } | |||||
| function mouseenter(item) { | |||||
| presentItem.value = item; | |||||
| showPopup.value = !showPopup.value; | |||||
| } | |||||
| // 下载 | |||||
| function handleDownload(itemVideoPlayUrl) { | |||||
| if (itemVideoPlayUrl) { | |||||
| const link = document.createElement("a"); | |||||
| link.href = itemVideoPlayUrl; | |||||
| document.body.appendChild(link); | |||||
| link.click(); | |||||
| document.body.removeChild(link); | |||||
| } else { | |||||
| ElMessage.error( | |||||
| lanChange.value == "zh-cn" ? `无法下载` : `Unable to download` | |||||
| ); | |||||
| } | |||||
| } | |||||
| function goCreate() { | |||||
| router.push("/createVideo"); | |||||
| } | |||||
| function searchVideoList() { | |||||
| getPhotoVideoList(pageNum.value, pageSize.value, title.value, true); | |||||
| } | |||||
| function handelDelete(id, title) { | |||||
| const msg = | |||||
| lanChange.value == "zh-cn" | |||||
| ? `确定要删除这个作品吗? 作品标题:${title}` | |||||
| : `Are you sure to delete this video ? Title:${title};`; | |||||
| const notice = lanChange.value == "zh-cn" ? "提示" : "Notice"; | |||||
| const confirm = lanChange.value == "zh-cn" ? "确定" : "Confirm"; | |||||
| const cancel = lanChange.value == "zh-cn" ? "取消" : "Cancel"; | |||||
| ElMessageBox.confirm(msg, notice, { | |||||
| confirmButtonText: confirm, | |||||
| cancelButtonText: cancel, | |||||
| }).then(() => { | |||||
| delPhotoVideo(id); | |||||
| }); | |||||
| } | |||||
| /** | |||||
| * @description:获取我的视频作品 | |||||
| * @return: data | |||||
| */ | |||||
| function getPhotoVideoList(pageNum, pageSize, title, searchFlag) { | |||||
| userPhotoVideoList(pageNum, pageSize, title) | |||||
| .then((res) => { | |||||
| console.log(res, "res"); | |||||
| res.data.list.forEach((item) => { | |||||
| // item.createDate = timestampToTime(item.createDate) || ""; | |||||
| // item.updateDate = timestampToTime(item.updateDate) || ""; | |||||
| // item.createVideoDate = timestampToTime(item.createVideoDate) || ""; | |||||
| item.statusName = getStatus(item.videoStatus); | |||||
| }); | |||||
| videoList.value = res.data.list; | |||||
| total.value = res.data.total * 1; | |||||
| if (searchFlag) { | |||||
| const total = res.data.total; | |||||
| const msg1 = | |||||
| lanChange.value == "zh-cn" | |||||
| ? `查询成功!找到${total}条符合条件的视频` | |||||
| : `Found! Match ${total} videos`; | |||||
| const msg2 = | |||||
| lanChange.value == "zh-cn" | |||||
| ? `查询成功!没有符合条件的视频` | |||||
| : `Found! No match videos`; | |||||
| const msg3 = | |||||
| lanChange.value == "zh-cn" | |||||
| ? `查询成功!已加载全部视频` | |||||
| : `Found! Present all videos`; | |||||
| return title | |||||
| ? ElMessage.success(total > 0 ? msg1 : msg2) | |||||
| : ElMessage.success(msg3); | |||||
| } | |||||
| isLoading.value = false; | |||||
| }) | |||||
| .catch((err) => { | |||||
| console.log(err, "err"); | |||||
| }); | |||||
| } | |||||
| /** | |||||
| * @description:删除视频作品 | |||||
| * @param: videoID | |||||
| * @return: data | |||||
| */ | |||||
| function delPhotoVideo(videoID) { | |||||
| delUserPhotoVideoByID(videoID) | |||||
| .then((res) => { | |||||
| console.log(res, "res"); | |||||
| const msg = lanChange.value == "zh-cn" ? `删除成功!` : `Success !`; | |||||
| ElMessage.success(msg); | |||||
| showDialog.value = false; | |||||
| getPhotoVideoList(pageNum.value, pageSize.value, title.value); | |||||
| }) | |||||
| .catch((err) => { | |||||
| console.log(err, "err"); | |||||
| ElMessage.error(err.message); | |||||
| }); | |||||
| } | |||||
| onMounted(() => { | |||||
| isLoading.value = true; | |||||
| getPhotoVideoList(pageNum.value, pageSize.value, title.value); | |||||
| }); | |||||
| </script> | |||||
| <style lang="scss" scoped> | |||||
| .page { | |||||
| min-height: calc(100vh - 80px); | |||||
| padding: 15px 130px; | |||||
| background-color: #fff; | |||||
| border-radius: 25px 0 0; | |||||
| .top { | |||||
| margin-bottom: 35px; | |||||
| } | |||||
| .loadingIcon { | |||||
| height: 100px; | |||||
| line-height: 100px; | |||||
| text-align: center; | |||||
| transform: scale(2); | |||||
| .loadingText { | |||||
| position: relative; | |||||
| top: -2px; | |||||
| left: 4px; | |||||
| } | |||||
| } | |||||
| .workList { | |||||
| flex-wrap: wrap; | |||||
| justify-content: flex-start; | |||||
| width: 100%; | |||||
| // height: 200px; | |||||
| margin-top: 5px; | |||||
| padding-bottom: 50px; | |||||
| cursor: pointer; | |||||
| .workItem { | |||||
| position: relative; | |||||
| width: 300px; | |||||
| // height: 200px; | |||||
| margin: 0 20px 20px 0; | |||||
| border: 2px solid #c2c2c2; | |||||
| border-radius: 15px; | |||||
| cursor: pointer; | |||||
| overflow: hidden; | |||||
| .workImg { | |||||
| position: relative; | |||||
| width: 100%; | |||||
| height: 170px; | |||||
| cursor: pointer; | |||||
| padding: 10px; | |||||
| overflow: hidden; | |||||
| .coverImg { | |||||
| max-width: 90%; | |||||
| max-height: 170px; | |||||
| cursor: pointer; | |||||
| } | |||||
| .takePlace { | |||||
| position: absolute; | |||||
| top: 40%; | |||||
| width: 80%; | |||||
| } | |||||
| } | |||||
| .more { | |||||
| position: absolute; | |||||
| top: 0; | |||||
| left: 0; | |||||
| width: 100%; | |||||
| height: 170px; | |||||
| background-color: rgb(0 0 0 / 30%); | |||||
| cursor: pointer; | |||||
| opacity: 0; | |||||
| transition: all 0.2s; | |||||
| .icon-videoPlay { | |||||
| position: absolute; | |||||
| top: 50%; | |||||
| left: 50%; | |||||
| width: 50px; | |||||
| height: 50px; | |||||
| font-size: 50px; | |||||
| color: #fff; | |||||
| text-align: center; | |||||
| transform: translate(-50%, -50%); | |||||
| cursor: pointer; | |||||
| } | |||||
| .showBtn { | |||||
| position: absolute; | |||||
| top: 10px; | |||||
| right: 10px; | |||||
| width: 20px; | |||||
| height: 20px; | |||||
| font-size: 20px; | |||||
| line-height: 10px; | |||||
| color: #fff; | |||||
| text-align: center; | |||||
| transition: all 0.3s; | |||||
| cursor: pointer; | |||||
| border-radius: 2px; | |||||
| &:hover { | |||||
| background-color: #00000056; | |||||
| } | |||||
| } | |||||
| .btns { | |||||
| position: absolute; | |||||
| top: 45px; | |||||
| right: 10px; | |||||
| // width: 70px; | |||||
| // height: 60px; | |||||
| overflow: hidden; | |||||
| border-radius: 10px; | |||||
| cursor: pointer; | |||||
| &-item { | |||||
| // width: 70px; | |||||
| // height: 30px; | |||||
| text-align: center; | |||||
| background-color: #fff; | |||||
| padding: 0 10px; | |||||
| transition: all 0.3s; | |||||
| cursor: pointer; | |||||
| &-icon { | |||||
| position: relative; | |||||
| display: inline-block; | |||||
| width: 20px; | |||||
| height: 20px; | |||||
| cursor: pointer; | |||||
| .icon-delete { | |||||
| position: absolute; | |||||
| top: 4px; | |||||
| left: 0; | |||||
| width: 20px; | |||||
| height: 20px; | |||||
| font-size: 16px; | |||||
| color: #000; | |||||
| text-align: center; | |||||
| cursor: pointer; | |||||
| } | |||||
| } | |||||
| .text { | |||||
| display: inline-block; | |||||
| height: 30px; | |||||
| padding-left: 5px; | |||||
| margin-top: -5px; | |||||
| line-height: 20px; | |||||
| cursor: pointer; | |||||
| } | |||||
| &:hover { | |||||
| color: #ffffff; | |||||
| background-color: #0000001a; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| .workInfo { | |||||
| justify-content: space-between; | |||||
| height: 40px; | |||||
| padding: 0 10px; | |||||
| line-height: 40px; | |||||
| border-top: 1px solid #afafaf; | |||||
| white-space: nowrap; | |||||
| overflow: hidden; | |||||
| text-overflow: ellipsis; | |||||
| font-size: 13px; | |||||
| } | |||||
| .statusName { | |||||
| position: absolute; | |||||
| top: 10%; | |||||
| left: -10%; | |||||
| width: 120px; | |||||
| text-align: center; | |||||
| color: #ffffff; | |||||
| font-size: 14px; | |||||
| transform: rotate(-45deg); | |||||
| &.manuscript { | |||||
| /* 草稿 */ | |||||
| background: linear-gradient(to right, #d7d2cc 0%, #304352 100%); | |||||
| } | |||||
| &.generating { | |||||
| /* 生成中 */ | |||||
| background: linear-gradient(270deg, #4b61dc, #15d1b8); | |||||
| } | |||||
| &.generationFailed { | |||||
| /* 生成失败 */ | |||||
| background: linear-gradient(120deg, #f093fb 0%, #f5576c 100%); | |||||
| } | |||||
| &.generationSucceed { | |||||
| /* 生成成功 */ | |||||
| background: linear-gradient(120deg, #84fab0 0%, #8fd3f4 100%); | |||||
| } | |||||
| } | |||||
| &:hover { | |||||
| .more { | |||||
| opacity: 1; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| .noList { | |||||
| .title { | |||||
| font-size: 30px; | |||||
| text-align: center; | |||||
| margin-top: 100px; | |||||
| background-image: -webkit-linear-gradient( | |||||
| left, | |||||
| #4b61dc, | |||||
| #15d1b8 25%, | |||||
| #4b61dc 50%, | |||||
| #15d1b8 75%, | |||||
| #4b61dc | |||||
| ) !important; | |||||
| -webkit-text-fill-color: transparent !important; | |||||
| -webkit-background-clip: text !important; | |||||
| background-clip: text !important; | |||||
| -webkit-background-size: 200% 100% !important; | |||||
| background-size: 200% 100% !important; | |||||
| } | |||||
| .goCreate { | |||||
| width: 200px; | |||||
| height: 40px; | |||||
| line-height: 40px; | |||||
| text-align: center; | |||||
| color: #ffffff; | |||||
| border-radius: 6px; | |||||
| background: linear-gradient(270deg, #4b61dc, #15d1b8); | |||||
| margin: 30px auto; | |||||
| cursor: pointer; | |||||
| transition: all 0.3s; | |||||
| &:hover { | |||||
| transform: scale(1.1); | |||||
| } | |||||
| } | |||||
| } | |||||
| .pagination { | |||||
| position: fixed; | |||||
| bottom: 20px; | |||||
| left: 50%; | |||||
| transform: translateX(-50%); | |||||
| background-color: #ffffff; | |||||
| padding: 10px 20px; | |||||
| border-radius: 8px; | |||||
| transition: all 0.3s; | |||||
| cursor: pointer; | |||||
| &:hover { | |||||
| background-color: #b8b8b873; | |||||
| } | |||||
| } | |||||
| } | |||||
| :deep(.el-input__wrapper) { | |||||
| border: none; | |||||
| border-bottom: 2px solid #000; | |||||
| border-radius: 0; | |||||
| box-shadow: none; | |||||
| } | |||||
| .el-icon.icon-edit { | |||||
| width: 30px; | |||||
| height: 30px; | |||||
| font-size: 30px; | |||||
| color: #8c939d; | |||||
| text-align: center; | |||||
| cursor: pointer; | |||||
| transition: all 0.3s; | |||||
| &:hover { | |||||
| color: #292929; | |||||
| } | |||||
| } | |||||
| .elDialog { | |||||
| .videoBox { | |||||
| // display: flex; | |||||
| // justify-content: space-between; | |||||
| width: 100%; | |||||
| padding: 20px; | |||||
| video { | |||||
| width: 100%; | |||||
| max-height: 600px; | |||||
| margin: auto; | |||||
| } | |||||
| .insteadVideo { | |||||
| font-size: 20px; | |||||
| font-weight: 600; | |||||
| margin: 20px auto; | |||||
| text-align: center; | |||||
| } | |||||
| } | |||||
| .dialog-footer { | |||||
| display: flex; | |||||
| justify-content: space-between; | |||||
| .elBtn { | |||||
| color: #fff; | |||||
| border-radius: 10px; | |||||
| padding: 5px 10px; | |||||
| cursor: pointer; | |||||
| background-color: #000; | |||||
| transition: all 0.3s; | |||||
| &:hover { | |||||
| background-color: #15d1b8; | |||||
| } | |||||
| } | |||||
| :deep(.el-icon) { | |||||
| margin-right: 5px; | |||||
| font-weight: 700; | |||||
| } | |||||
| } | |||||
| } | |||||
| :deep(.el-dialog) { | |||||
| overflow: hidden; | |||||
| border-radius: 25px; | |||||
| } | |||||
| // :deep(.el-dialog__header) { | |||||
| // } | |||||
| :deep(.el-dialog__title) { | |||||
| background-image: -webkit-linear-gradient( | |||||
| left, | |||||
| #4b61dc, | |||||
| #15d1b8 25%, | |||||
| #4b61dc 50%, | |||||
| #15d1b8 75%, | |||||
| #4b61dc | |||||
| ) !important; | |||||
| -webkit-text-fill-color: transparent !important; | |||||
| -webkit-background-clip: text !important; | |||||
| background-clip: text !important; | |||||
| -webkit-background-size: 200% 100% !important; | |||||
| background-size: 200% 100% !important; | |||||
| } | |||||
| :deep(.el-dialog__body) { | |||||
| padding: 0; | |||||
| } | |||||
| :deep(.dialog__footer) { | |||||
| padding: 0; | |||||
| } | |||||
| </style> | |||||
| @@ -49,12 +49,17 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => { | |||||
| host: "0.0.0.0", | host: "0.0.0.0", | ||||
| port: Number(env.VITE_APP_PORT), | port: Number(env.VITE_APP_PORT), | ||||
| open: true, // 运行是否自动打开浏览器 | open: true, // 运行是否自动打开浏览器 | ||||
| // "/api": { | |||||
| // target: env.VITE_APP_BASE_API, // 线上接口地址 | |||||
| // changeOrigin: true, | |||||
| // rewrite: (path) => path.replace(/^\/api/, ""), | |||||
| // }, | |||||
| proxy: { | proxy: { | ||||
| // 反向代理解决跨域 | // 反向代理解决跨域 | ||||
| "/api": { | |||||
| "/A": { | |||||
| target: env.VITE_APP_BASE_API, // 线上接口地址 | target: env.VITE_APP_BASE_API, // 线上接口地址 | ||||
| changeOrigin: true, | changeOrigin: true, | ||||
| rewrite: (path) => path.replace(/^\/api/, ""), | |||||
| rewrite: (path) => path.replace(/^\/A/, ""), | |||||
| }, | }, | ||||
| }, | }, | ||||
| }, | }, | ||||