@@ -5,6 +5,8 @@ NODE_ENV='development' | |||
VITE_APP_TITLE = 'Metavatar-PC' | |||
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' | |||
@@ -5,4 +5,4 @@ NODE_ENV='production' | |||
VITE_APP_TITLE = 'Metavatar-PC' | |||
VITE_APP_PORT = 3000 | |||
VITE_APP_BASE_API = 'https://neuver.metavatar.cc/C' | |||
VITE_APP_BASE_API = 'https://neuver.metavatar.cc/A' |
@@ -6,4 +6,4 @@ NODE_ENV='test' | |||
VITE_APP_TITLE = 'Metavatar-PC' | |||
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://mtest.metavatar.cc/A' |
@@ -1,4 +1,4 @@ | |||
<!-- 照片说话 慧影 --> | |||
<!-- 邃芒A端--> | |||
git commit -m "feat: " | |||
git commit --no-verify -m "提交时的注释" 跳过检验 | |||
git merge origin/dev_ |
@@ -5,7 +5,7 @@ | |||
<meta charset="UTF-8" /> | |||
<link rel="icon" href="/favicon.ico" /> | |||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |||
<title>Metavatar-慧影</title> | |||
<title>Metavatar-邃芒管理端</title> | |||
</head> | |||
<body> | |||
@@ -24,6 +24,7 @@ | |||
"echarts": "^5.2.2", | |||
"element-plus": "^2.3.1", | |||
"js-audio-recorder": "^1.0.7", | |||
"js-cookie": "^3.0.5", | |||
"nprogress": "^0.2.0", | |||
"path-browserify": "^1.0.1", | |||
"path-to-regexp": "^6.2.0", | |||
@@ -67,7 +68,6 @@ | |||
"stylelint-config-recommended-vue": "^1.4.0", | |||
"stylelint-config-standard": "^32.0.0", | |||
"stylelint-config-standard-scss": "^8.0.0", | |||
"typescript": "^4.9.3", | |||
"unocss": "^0.50.1", | |||
"unplugin-auto-import": "^0.13.0", | |||
"unplugin-icons": "^0.15.1", | |||
@@ -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/getByServiceId?serviceId=${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', | |||
}) | |||
} |
@@ -0,0 +1,113 @@ | |||
import request from "@/utils/request.js"; | |||
/** | |||
* @description 获取合作商列表 | |||
* @param {*} (pageNum,pageSize) | |||
* @returns data | |||
*/ | |||
export function businessListApi(pageNum, pageSize, type, id) { | |||
return request({ | |||
url: `/serviceInfo/page?pageNum=${pageNum}&pageSize=${pageSize}&type=${type}&id=${id || ''}`, | |||
method: 'get' | |||
}) | |||
} | |||
/** | |||
* @description 新增合作商 | |||
* @param {*} data | |||
* @returns data | |||
*/ | |||
export function addBusinessApi(data) { | |||
return request({ | |||
url: `/serviceInfo/save`, | |||
method: 'post', | |||
data | |||
}) | |||
} | |||
/** | |||
* @description 获取api接入管理列表 | |||
* @param {*} (pageNum,pageSize) | |||
* @returns data | |||
*/ | |||
export function apiManageListApi(pageNum, pageSize) { | |||
return request({ | |||
url: `/serviceInfo/page?type=1pageNum=${pageNum}&pageSize=${pageSize}`, | |||
method: 'get' | |||
}) | |||
} | |||
/** | |||
* @description 设置登录账号 | |||
* @param {*} data | |||
* @returns data | |||
*/ | |||
export function saveMallUserInfo(data) { | |||
return request({ | |||
url: `/serviceInfo/saveMallUserInfo`, | |||
method: 'post', | |||
data | |||
}) | |||
} | |||
/** | |||
* @description 修改登录账号 详情 | |||
* @param {*} data | |||
* @returns data | |||
*/ | |||
export function getMallUserInfo(id) { | |||
return request({ | |||
url: `/serviceInfo/getMallUserInfo?serviceId=${id}`, | |||
method: 'get' | |||
}) | |||
} | |||
/** | |||
* @description 设置时长 | |||
* @param {*} data | |||
* @returns data | |||
*/ | |||
export function setRemainingTimes(data) { | |||
return request({ | |||
url: `/serviceInfo/setRemainingTimes`, | |||
method: 'post', | |||
data | |||
}) | |||
} | |||
/** | |||
* @description 所有模版 | |||
* @param {*} (pageNum,pageSize) | |||
* @returns data | |||
*/ | |||
export function modelAllList(pageNum, pageSize) { | |||
return request({ | |||
url: `/personMould/alList?pageNum=${pageNum}&pageSize=${pageSize}`, | |||
method: 'get' | |||
}) | |||
} | |||
/** | |||
* @description 已关联模版 | |||
* @param {*} | |||
* @returns data | |||
*/ | |||
export function personMouldIdList(id) { | |||
return request({ | |||
url: `/serviceInfo/personMouldIdList?serviceId=${id || ''}`, | |||
method: 'get' | |||
}) | |||
} | |||
/** | |||
* @description 保存关联模版 | |||
* @param {*} | |||
* @returns data | |||
*/ | |||
export function associatedMould(data) { | |||
return request({ | |||
url: `/serviceInfo/associatedMould`, | |||
method: 'post', | |||
data | |||
}) | |||
} |
@@ -0,0 +1,14 @@ | |||
import request from "@/utils/request.js"; | |||
/** | |||
* @description 修改密码 | |||
* @params userName, pwd | |||
* @returns data | |||
*/ | |||
export function updatepwd(data) { | |||
return request({ | |||
url: `/user/updatepwd`, | |||
method: 'post', | |||
data | |||
}) | |||
} |
@@ -0,0 +1,83 @@ | |||
/* | |||
* @Autor: Chutingting | |||
* @Date: 2023-11-11 19:15:01 | |||
* @LastEditors: Chutingting | |||
* @LastEditTime: 2023-11-13 10:28:20 | |||
* @Description: | |||
*/ | |||
import request from "@/utils/request.js"; | |||
/** | |||
* @description:用户角色 | |||
* @param | |||
* @return: | |||
*/ | |||
export function getUser() { | |||
return request({ | |||
url: `/user/getUser`, | |||
method: 'get', | |||
}) | |||
} | |||
/** | |||
* @description:用户角色 | |||
* @param | |||
* @return: | |||
*/ | |||
export function localDeployApi() { | |||
return request({ | |||
url: `/localDeploy`, | |||
method: 'get', | |||
}) | |||
} | |||
/** | |||
* @description: api 剩余时长 | |||
* @param | |||
* @return: | |||
*/ | |||
export function current() { | |||
return request({ | |||
url: `/serviceInfo/current`, | |||
method: 'get', | |||
}) | |||
} | |||
/** | |||
* @description: 私有化 剩余时长 | |||
* @param | |||
* @return: | |||
*/ | |||
export function privateDeployAdminCurrent() { | |||
return request({ | |||
url: `/serviceInfo/privateDeployAdminCurrent`, | |||
method: 'get', | |||
}) | |||
} | |||
/** | |||
* @description: 视频制作统计 | |||
* @param | |||
* @return: | |||
*/ | |||
export function videoListApi(pageNum, pageSize) { | |||
let api = localStorage.getItem("isAdmin") === '0' ? '/serviceInfo/currentVideoRecords' : '/serviceInfo/privateDeployAdminCurrentVideoRecords' | |||
return request({ | |||
url: `${api}?pageNum=${pageNum}&pageSize=${pageSize}`, | |||
method: 'get', | |||
}) | |||
} | |||
/** | |||
* @description: 已消耗总时长 | |||
* @param | |||
* @return: | |||
*/ | |||
export function currentVideoToalApi(pageNum) { | |||
let api = localStorage.getItem("isAdmin") === '0' ? '/serviceInfo/currentVideoToal' : '/serviceInfo/privateDeployAdminCurrentVideoTotal' | |||
return request({ | |||
url: `${api}`, | |||
method: 'get', | |||
}) | |||
} | |||
@@ -2,31 +2,31 @@ import request from "@/utils/request.js"; | |||
const baseURL = import.meta.env.VITE_APP_BASE_API | |||
/** | |||
* @description 注册 | |||
* @params email,password | |||
* @description 登录 | |||
* @params email,password,code | |||
* @returns data | |||
*/ | |||
export function register(data) { | |||
export function loginApi(data) { | |||
return request({ | |||
// url: `/api/user/doRegisterByEmail`, | |||
url: `/api/user/doRegisterByPhone`, | |||
// url: `/api/user/loginByEmail`, | |||
url: `/doLogin`, | |||
method: 'post', | |||
data | |||
}) | |||
} | |||
/** | |||
* @description 登录 | |||
* @description 退出登录 | |||
* @params email,password,code | |||
* @returns data | |||
*/ | |||
export function login(data) { | |||
export function logoutApi(data) { | |||
return request({ | |||
// url: `/api/user/loginByEmail`, | |||
url: `/api/user/login`, | |||
method: 'post', | |||
data | |||
url: `/logout`, | |||
method: 'get' | |||
}) | |||
} | |||
@@ -175,5 +175,5 @@ export function resetPwdFormApi(data) { | |||
* @description:获取图形验证码 | |||
* @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() { | |||
return request({ | |||
url: `api/user/getUserInfo`, | |||
url: `getUserInfo`, | |||
method: 'get', | |||
}) | |||
} |
@@ -0,0 +1,13 @@ | |||
import request from "@/utils/request.js"; | |||
/** | |||
* @description: 密钥查看 | |||
* @param | |||
* @return: | |||
*/ | |||
export function secretKeyApi() { | |||
return request({ | |||
url: `/thirdPartyApi/current`, | |||
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' | |||
}) | |||
} |
@@ -0,0 +1,14 @@ | |||
import request from "@/utils/request.js"; | |||
/** | |||
* @description 获取合作商列表 | |||
* @param {*} (pageNum,pageSize) | |||
* @returns data | |||
*/ | |||
export function templateListApi(pageNum, pageSize) { | |||
let api = localStorage.getItem("isAdmin") === '1' && localStorage.getItem("localDeploy") === 'true' ? '/personMould/alList' : '/personMould/serviceMouldList' | |||
return request({ | |||
url: `${api}?pageNum=${pageNum}&pageSize=${pageSize}`, | |||
method: 'get' | |||
}) | |||
} |
@@ -0,0 +1,159 @@ | |||
import request from "@/utils/request.js"; | |||
/** | |||
* @description 用户列表 | |||
* @param {*} (pageNum,pageSize) | |||
* @returns data | |||
*/ | |||
export function userListApi(params) { | |||
return request({ | |||
url: `/wxCUserBasicInfo/list`, | |||
method: 'get', | |||
params | |||
}) | |||
} | |||
/** | |||
* @description 用户列表-状态 | |||
* @param {*} | |||
* @returns | |||
*/ | |||
export function updateStatusApi(data) { | |||
return request({ | |||
url: `/wxCUserBasicInfo/updateStatus`, | |||
method: 'post', | |||
data | |||
}) | |||
} | |||
// 绑定定制模板 | |||
export function personMouldListApi(pageNum, pageSize) { | |||
return request({ | |||
url: `/personMould/alList?onlyCustomizedQuery=1&pageNum=${pageNum}&pageSize=${pageSize}`, | |||
method: 'get' | |||
}) | |||
} | |||
// 绑定定制模板-已关联模版 | |||
export function userPersonMouldIdListApi(cUserId) { | |||
return request({ | |||
url: `/personMould/userPersonMouldIdList?cUserId=${cUserId}`, | |||
method: 'get' | |||
}) | |||
} | |||
// 绑定定制模板-关联模版 | |||
export function associatedUserMouldsApi(data) { | |||
return request({ | |||
url: `/personMould/associatedUserMoulds`, | |||
method: 'post', | |||
data | |||
}) | |||
} | |||
// 绑定定制声纹 | |||
export function voiceMouldListApi(pageNum, pageSize) { | |||
return request({ | |||
url: `/voiceMould/alList?onlyCustomizedQuery=1&pageNum=${pageNum}&pageSize=${pageSize}`, | |||
method: 'get' | |||
}) | |||
} | |||
// 绑定定制声纹-已关联模版 | |||
export function userVoiceIdListApi(cUserId) { | |||
return request({ | |||
url: `/voiceMould/userVoiceIdList?cUserId=${cUserId}`, | |||
method: 'get' | |||
}) | |||
} | |||
// 绑定定制声纹-关联模版 | |||
export function associatedUserVoicesApi(data) { | |||
return request({ | |||
url: `/voiceMould/associatedUserVoices`, | |||
method: 'post', | |||
data | |||
}) | |||
} | |||
/** | |||
* @description 用户列表查看 | |||
* @param {*} | |||
* @returns | |||
*/ | |||
export function userListFindByIdApi(id) { | |||
return request({ | |||
url: `/wxCUserBasicInfo/findById?id=${id}`, | |||
method: 'get' | |||
}) | |||
} | |||
/** | |||
* @description 私人定制模板列表 | |||
* @param {*} (pageNum,pageSize) | |||
* @returns data | |||
*/ | |||
export function userMouldListApi(params) { | |||
return request({ | |||
url: `/personMould/userMouldList`, | |||
method: 'get', | |||
params | |||
}) | |||
} | |||
/** | |||
* @description 私人定制声纹列表 | |||
* @param {*} (pageNum,pageSize) | |||
* @returns data | |||
*/ | |||
export function userVoiceListAPi(params) { | |||
return request({ | |||
url: `/voiceMould/userVoiceList`, | |||
method: 'get', | |||
params | |||
}) | |||
} | |||
/** | |||
* @description 充值列表 | |||
* @param {*} (pageNum,pageSize) | |||
* @returns data | |||
*/ | |||
export function rechargeListApi(params) { | |||
return request({ | |||
url: `/productOrder/paiedOrders`, | |||
method: 'get', | |||
params | |||
}) | |||
} | |||
/** | |||
* @description 视频列表 | |||
* @param {*} (pageNum,pageSize) | |||
* @returns data | |||
*/ | |||
export function videoListApi(params) { | |||
return request({ | |||
url: `/userVideo/list`, | |||
method: 'get', | |||
params | |||
}) | |||
} | |||
/** | |||
* @description 视频列表-查看 | |||
* @param {*} | |||
* @returns | |||
*/ | |||
export function videoListFindByIdApi(id) { | |||
return request({ | |||
url: `/userVideo/findById?id=${id}`, | |||
method: 'get' | |||
}) | |||
} | |||
/** | |||
* @description 视频列表-删除 | |||
* @param {*} | |||
* @returns | |||
*/ | |||
export function videoListDelApi(id) { | |||
return request({ | |||
url: `/userVideo/del?id=${id}`, | |||
method: 'get' | |||
}) | |||
} |
@@ -15,7 +15,7 @@ export default { | |||
// 登录页面国际化 | |||
login: { | |||
// title: "Metavatar-MetaTalker", | |||
title: "MetaTalker", | |||
title: "MetaTalker-Admin", | |||
username: "Username", | |||
email: "Phone", | |||
password: "Password", | |||
@@ -24,7 +24,7 @@ export default { | |||
register: "Sign up", | |||
loginBtn: "Sign in", | |||
registerBtn: "Sign up", | |||
verifyCode: "Verify code", | |||
captcha: "Verify code", | |||
signIn: "Already got an account? Sign in here", | |||
signUp: "Don't have an account? Sign up here", | |||
forgetPwd: "I forgot my password", | |||
@@ -51,6 +51,18 @@ export default { | |||
logout: "Logout", | |||
goLogin: "Go and log in", | |||
LanguageChange: "Language switching", | |||
home: 'Home', | |||
apiManage: 'API Access Party Management', | |||
privatization: 'Privatized customer management', | |||
template: 'Template management', | |||
secretKey: 'Key View', | |||
video: 'Video production statistics', | |||
userMange: 'User Management', | |||
userList: 'User List', | |||
userMouldList: 'Private Custom Template List', | |||
userVoiceList: 'Private customized voiceprint list', | |||
rechargeList: 'Recharge List', | |||
videoList: 'Video List' | |||
}, | |||
// 创作视频 | |||
@@ -203,10 +215,6 @@ export default { | |||
comingSoon: "Coming Soon", | |||
}, | |||
apiMangage: { | |||
title: "API Mangage", | |||
}, | |||
signSucceed: { | |||
title: "Confirm your email", | |||
succeed: "Sign Succeed !", | |||
@@ -221,6 +229,189 @@ export default { | |||
}, | |||
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", | |||
}, | |||
home: { | |||
info: 'Personal Information', | |||
welcome: 'Welcome', | |||
loginAccount: 'Login account', | |||
userName: 'User nickname', | |||
phone: 'Phone', | |||
time: 'Current account duration', | |||
setting: 'security setting', | |||
editPwd: 'Change password', | |||
key: 'secret key', | |||
view: 'View', | |||
}, | |||
template: { | |||
img: 'picture' | |||
}, | |||
video: { | |||
time: 'Total time consumed', | |||
code: 'Access Party Code', | |||
videoTime: 'Video duration(S)', | |||
videoUrl: 'Video link', | |||
createTime: 'CreateTime', | |||
detail: 'View video details', | |||
}, | |||
userList: { | |||
phone: 'phone', | |||
phonePlaceholder: 'Please enter your phone number', | |||
search: 'search', | |||
id: 'user id', | |||
poins: 'Current currency value', | |||
createDate: 'CreateTime', | |||
view: 'View', | |||
rechargeDetail: 'View recharge records', | |||
videoDetail: 'View video list', | |||
personMould: 'Bind custom templates', | |||
personVoice: 'Bind custom voiceprints', | |||
viewDetail: 'Detail', | |||
close: 'Close' | |||
}, | |||
personMould: { | |||
cancel: 'Cancel', | |||
confirm: 'Confirm association' | |||
}, | |||
personVoice: { | |||
lang: 'language', | |||
country: 'country', | |||
enName: 'English name', | |||
chineseName: 'Chinese name', | |||
cancel: 'Cancel', | |||
confirm: 'Confirm association' | |||
}, | |||
rechargeList: { | |||
phone: 'phone', | |||
phonePlaceholder: 'Please enter your phone number', | |||
search: 'search', | |||
productName: 'product name', | |||
productNamePlaceholder: 'Please enter the product name', | |||
time: 'Recharge time period', | |||
orderNumber: 'Order No', | |||
payVendor: 'Payment method', | |||
orderPriceStr: 'Payment amount', | |||
createDate: 'CreateTime' | |||
}, | |||
userMouldList: { | |||
phone: 'phone', | |||
phonePlaceholder: 'Please enter your phone number', | |||
search: 'search', | |||
coverImg: 'Cover Image', | |||
mouldSmId: 'Template number', | |||
mouldSmIdPlaceholder: 'Please enter the template number', | |||
bindPhone: 'Bind phone number', | |||
createDate: 'CreateTime' | |||
}, | |||
userVoiceList: { | |||
phone: 'phone', | |||
phonePlaceholder: 'Please enter your phone number', | |||
mouldSmId: 'Template number', | |||
mouldSmIdPlaceholder: 'Please enter the template number', | |||
search: 'search', | |||
lang: 'language', | |||
country: 'country', | |||
enName: 'English name', | |||
chineseName: 'Chinese name', | |||
bindPhone: 'Bind phone number', | |||
createDate: 'CreateTime' | |||
}, | |||
videoList: { | |||
phone: 'phone', | |||
phonePlaceholder: 'Please enter your phone number', | |||
text: 'text', | |||
textPlaceholder: 'Please enter text', | |||
type: 'type', | |||
typePlaceholder: 'Please select a type', | |||
portrait: 'Portrait', | |||
transversePlate: 'horizontal version', | |||
status: 'status', | |||
statusPlaceholder: 'Please select a status', | |||
notDeleted: 'Not deleted', | |||
deleted: 'Deleted', | |||
time: 'Create time period', | |||
search: 'search', | |||
title: 'Video Title', | |||
coverImg: 'Cover Image', | |||
videoPlayUrl: 'Video address', | |||
videoTime: 'Video duration(S)', | |||
videoSize: 'Video size', | |||
videoMsg: 'Video Generation Information', | |||
costPoints: 'Consumption coins', | |||
costPointsDetail: 'Consumption Gold Coin Details', | |||
createDate: 'CreateTime', | |||
view: 'view', | |||
del: 'delete', | |||
videoDetail: 'Video Details', | |||
name: 'name', | |||
videType: 'Video type', | |||
close: 'Close', | |||
all: 'All' | |||
}, | |||
businessCheck: { | |||
detail: 'Key details', | |||
copy: 'copy', | |||
status: 'Key Status', | |||
normal: 'normal', | |||
loseEfficacy: 'lose efficacy', | |||
restore: 'restore', | |||
cancel: 'cancel' | |||
}, | |||
editPass: { | |||
username: 'user name', | |||
pass: 'password', | |||
checkPass: 'Confirm Password' | |||
}, | |||
apiManage: { | |||
add: 'add', | |||
time: 'Duration (s)', | |||
viewKey: 'View Key', | |||
editAccount: 'Modify login account', | |||
eddAccount: 'Add login account', | |||
setTime: 'Set duration', | |||
associationTemp: 'Association template', | |||
loginAccount: 'Login account', | |||
username: 'user name', | |||
name: 'name', | |||
pass: 'password', | |||
phone: 'phone', | |||
} | |||
}; |
@@ -14,7 +14,7 @@ export default { | |||
}, | |||
// 登录页面国际化 | |||
login: { | |||
title: "慧影", | |||
title: "邃芒管理端", | |||
username: "用户名", | |||
email: "手机号", | |||
password: "密码", | |||
@@ -23,7 +23,7 @@ export default { | |||
register: "注册", | |||
loginBtn: "登 录", | |||
registerBtn: "注 册", | |||
verifyCode: "验证码", | |||
captcha: "验证码", | |||
// signIn: "已有账号?现在登录!", | |||
// signUp: "没有账号?现在加入!", | |||
signIn: "立即登录", | |||
@@ -52,6 +52,18 @@ export default { | |||
logout: "注销", | |||
goLogin: "登录", | |||
LanguageChange: "语言切换", | |||
home: '首页', | |||
apiManage: 'API接入方管理', | |||
privatization: '私有化客户管理', | |||
template: '模版管理', | |||
secretKey: '密钥查看', | |||
video: '视频制作统计', | |||
userMange: '用户管理', | |||
userList: '用户列表', | |||
userMouldList: '私人定制模板列表', | |||
userVoiceList: '私人定制声纹列表', | |||
rechargeList: '充值列表', | |||
videoList: '视频列表' | |||
}, | |||
// 创作视频 | |||
@@ -203,10 +215,6 @@ export default { | |||
comingSoon: "敬请期待", | |||
}, | |||
apiMangage: { | |||
title: "API 管理", | |||
}, | |||
signSucceed: { | |||
title: "确认邮箱", | |||
succeed: "注册成功", | |||
@@ -222,4 +230,187 @@ export default { | |||
modelMangage: { | |||
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 管理", | |||
}, | |||
home: { | |||
info: '个人信息', | |||
welcome: '欢迎您', | |||
loginAccount: '登录账号', | |||
userName: '用户昵称', | |||
phone: '手机号', | |||
time: '当前账户时长', | |||
setting: '安全设置', | |||
editPwd: '修改密码', | |||
key: '密钥', | |||
view: '查看', | |||
}, | |||
template: { | |||
img: '图片' | |||
}, | |||
video: { | |||
time: '已消耗总时长', | |||
code: '接入方编码', | |||
videoTime: '视频时长(秒)', | |||
videoUrl: '视频链接', | |||
createTime: '创建时间', | |||
detail: '查看视频详情', | |||
}, | |||
userList: { | |||
phone: '手机号', | |||
phonePlaceholder: '请输入手机号', | |||
search: '查询', | |||
id: '用户ID', | |||
poins: '当前币值', | |||
createDate: '创建时间', | |||
view: '查看', | |||
rechargeDetail: '查看充值记录', | |||
videoDetail: '查看视频列表', | |||
personMould: '绑定定制模版', | |||
personVoice: '绑定定制声纹', | |||
viewDetail: '查看详情', | |||
close: '关闭' | |||
}, | |||
personMould: { | |||
cancel: '取消', | |||
confirm: '确认关联' | |||
}, | |||
personVoice: { | |||
lang: '语言', | |||
country: '国家', | |||
enName: '英文名称', | |||
chineseName: '中文名称', | |||
cancel: '取消', | |||
confirm: '确认关联' | |||
}, | |||
rechargeList: { | |||
phone: '手机号', | |||
phonePlaceholder: '请输入手机号', | |||
search: '查询', | |||
productName: '商品名称', | |||
productNamePlaceholder: '请输入商品名', | |||
time: '充值时间段', | |||
orderNumber: '订单号', | |||
payVendor: '支付方式', | |||
orderPriceStr: '支付金额', | |||
createDate: '创建时间' | |||
}, | |||
userMouldList: { | |||
phone: '手机号', | |||
phonePlaceholder: '请输入手机号', | |||
search: '查询', | |||
coverImg: '封面图', | |||
mouldSmId: '模版号', | |||
mouldSmIdPlaceholder: '请输入模版号', | |||
bindPhone: '绑定手机号', | |||
createDate: '创建时间' | |||
}, | |||
userVoiceList: { | |||
phone: '手机号', | |||
phonePlaceholder: '请输入手机号', | |||
mouldSmId: '模版号', | |||
mouldSmIdPlaceholder: '请输入模版号', | |||
search: '查询', | |||
lang: '语言', | |||
country: '国家', | |||
enName: '英文名称', | |||
chineseName: '中文名称', | |||
bindPhone: '绑定手机号', | |||
createDate: '创建时间' | |||
}, | |||
videoList: { | |||
phone: '手机号', | |||
phonePlaceholder: '请输入手机号', | |||
text: '文本', | |||
textPlaceholder: '请输入文本', | |||
type: '类型', | |||
typePlaceholder: '请选择类型', | |||
portrait: '竖版', | |||
transversePlate: '横版', | |||
status: '状态', | |||
statusPlaceholder: '请选择状态', | |||
notDeleted: '未删除', | |||
deleted: '已删除', | |||
time: '创建时间段', | |||
search: '查询', | |||
title: '视频标题', | |||
coverImg: '封面图', | |||
videoPlayUrl: '视频地址', | |||
videoTime: '视频时长(秒)', | |||
videoSize: '视频大小', | |||
videoMsg: '视频生成信息', | |||
costPoints: '消耗金币', | |||
costPointsDetail: '消耗金币明细', | |||
createDate: '创建时间', | |||
view: '查看', | |||
del: '删除', | |||
videoDetail: '视频详情', | |||
name: '名称', | |||
videType: '视频类型', | |||
close: '关闭', | |||
all: '全部' | |||
}, | |||
businessCheck: { | |||
detail: '密钥详情', | |||
copy: '复制', | |||
status: '密钥状态', | |||
normal: '正常', | |||
loseEfficacy: '失效', | |||
restore: '恢复', | |||
cancel: '作废' | |||
}, | |||
editPass: { | |||
username: '用户名', | |||
pass: '密码', | |||
checkPass: '确认密码' | |||
}, | |||
apiManage: { | |||
add: '新增', | |||
time: '时长(秒)', | |||
viewKey: '查看密钥', | |||
editAccount: '修改登录账号', | |||
eddAccount: '新增登录账号', | |||
setTime: '设置时长', | |||
associationTemp: '关联模版', | |||
loginAccount: '登录账号', | |||
username: '用户名', | |||
name: '名称', | |||
pass: '密码', | |||
phone: '手机号', | |||
} | |||
}; |
@@ -1,3 +1,10 @@ | |||
<!-- | |||
* @Autor: Chutingting | |||
* @Date: 2023-11-02 11:32:51 | |||
* @LastEditors: Chutingting | |||
* @LastEditTime: 2023-11-08 16:06:12 | |||
* @Description: | |||
--> | |||
<script setup lang="ts"> | |||
import { useTagsViewStore } from "@/store/modules/tagsView"; | |||
@@ -23,6 +30,7 @@ const tagsViewStore = useTagsViewStore(); | |||
width: 100%; | |||
/* 50= navbar 50 */ | |||
min-height: calc(100vh - 80px); | |||
background: #fff; | |||
// overflow: hidden; | |||
// background-color: var(--el-bg-color-page); | |||
// background-color: #000; | |||
@@ -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,21 +11,55 @@ | |||
</div> | |||
<!-- 侧边路由列表 --> | |||
<div class="myRouter"> | |||
<div class="myRouter-item" @click="router.push('/createVideo')"> | |||
<div class="icon"> | |||
<el-icon><i-ep-edit /></el-icon> | |||
</div> | |||
{{ $t("modelMangage.title") }} | |||
</div> | |||
<div class="bottomBtx"> | |||
<div class="myRouter-item" @click="router.push('/myAPI')"> | |||
<div class="icon"> | |||
<el-icon><i-ep-DocumentAdd /></el-icon> | |||
</div> | |||
{{ $t("apiMangage.title") }} | |||
</div> | |||
</div> | |||
<el-menu | |||
default-active="1" | |||
active-text-color="#ffd04b" | |||
background-color="#000" | |||
text-color="#fff" | |||
class="el-menu-vertical-demo"> | |||
<el-menu-item index="1" @click="router.push('/home')"> | |||
<el-icon><i-ep-House /></el-icon> | |||
<span>{{ $t('navbar.home') }}</span> | |||
</el-menu-item> | |||
<!-- 邃芒后台 --> | |||
<el-menu-item v-if="isAdmin === '1' && localDeploy !== 'true' " index="2" @click="router.push('/apiManage')"> | |||
<el-icon><i-ep-link /></el-icon> | |||
<span>{{ $t('navbar.apiManage') }}</span> | |||
</el-menu-item> | |||
<el-menu-item v-if="isAdmin === '1' && localDeploy !== 'true'" index="3" @click="router.push('/privatization')"> | |||
<el-icon><i-ep-edit /></el-icon> | |||
<span>{{ $t('navbar.privatization') }}</span> | |||
</el-menu-item> | |||
<!-- 私有化客户管理 API v-if="(isAdmin === '1' && localDeploy === 'true') || isAdmin === '0'" --> | |||
<template v-else> | |||
<el-menu-item index="4" @click="router.push('/template')"> | |||
<el-icon><i-ep-edit /></el-icon> | |||
<span>{{ $t('navbar.template') }}</span> | |||
</el-menu-item> | |||
<el-menu-item index="5" @click="router.push('/secretKey')"> | |||
<el-icon><i-ep-edit /></el-icon> | |||
<span>{{ $t('navbar.secretKey') }}</span> | |||
</el-menu-item> | |||
<el-menu-item index="6" @click="router.push('/video')"> | |||
<el-icon><i-ep-edit /></el-icon> | |||
<span>{{ $t('navbar.video') }}</span> | |||
</el-menu-item> | |||
</template> | |||
<!-- v-if="isAdmin === '1'" --> | |||
<el-sub-menu index="7" v-if="isAdmin == '1'" > | |||
<template #title> | |||
<el-icon><i-ep-edit /></el-icon> | |||
<span>{{ $t('navbar.userMange') }}</span> | |||
</template> | |||
<el-menu-item-group> | |||
<el-menu-item index="7-1" @click="router.push('/userManage')">{{ $t('navbar.userList') }}</el-menu-item> | |||
<el-menu-item index="7-2" @click="router.push('/userMouldList')">{{ $t('navbar.userMouldList') }}</el-menu-item> | |||
<el-menu-item index="7-3" @click="router.push('/userVoiceList')">{{ $t('navbar.userVoiceList') }}</el-menu-item> | |||
<el-menu-item index="7-4" @click="router.push('/rechargeList')">{{ $t('navbar.rechargeList') }}</el-menu-item> | |||
<el-menu-item index="7-5" @click="router.push('/videoList')">{{ $t('navbar.videoList') }}</el-menu-item> | |||
</el-menu-item-group> | |||
</el-sub-menu> | |||
</el-menu> | |||
</div> | |||
</div> | |||
<!-- 右边显示部分 --> | |||
@@ -43,13 +77,13 @@ | |||
<lang-select class="navItem" /> | |||
</el-tooltip> | |||
<!-- 登录 --> | |||
<div class="navItem" v-if="!AccessToken" @click="router.push('login')"> | |||
<div class="navItem" v-if="!isLogin" @click="router.push('login')"> | |||
{{ $t("navbar.goLogin") }} | |||
</div> | |||
<!-- 注销 --> | |||
<div | |||
v-if="isLogin" | |||
class="navItem" | |||
v-if="AccessToken" | |||
@click="logout" | |||
style="margin-left: 10px" | |||
> | |||
@@ -77,8 +111,9 @@ import { useAppStore } from "@/store/modules/app"; | |||
// import { useSettingsStore } from "@/store/modules/settings"; | |||
import { useRoute, useRouter } from "vue-router"; | |||
import { useI18n } from "vue-i18n"; | |||
import { getMenuNavApi } from "@/apis/Permission.js"; | |||
import { userInfoModules } from "@/store/modules/userInfo"; | |||
import { logoutApi } from '@/apis/login.js' | |||
const userInfoPinia = userInfoModules(); | |||
const route = useRoute(); | |||
@@ -89,6 +124,10 @@ const AccessToken = localStorage.getItem("AccessToken"); | |||
// 当前语言状态与国际化组件 | |||
const { locale } = useI18n(); | |||
const lanChange = ref(locale); | |||
const isLogin = ref(false); | |||
const isAdmin = ref('') | |||
const localDeploy = ref('') | |||
function logout() { | |||
const msg = | |||
(lanChange.value as string) == "zh-cn" | |||
@@ -101,8 +140,11 @@ function logout() { | |||
confirmButtonText: confirm, | |||
cancelButtonText: cancel, | |||
}).then(() => { | |||
userInfoPinia.loginOut(); | |||
router.push(`/login`); | |||
logoutApi().then(res => { | |||
userInfoPinia.loginOut(); | |||
localStorage.clear() | |||
router.push(`/login`); | |||
}) | |||
localStorage.removeItem("AccessToken"); | |||
}); | |||
} | |||
@@ -138,19 +180,48 @@ function handleOutsideClick() { | |||
appStore.closeSideBar(false); | |||
} | |||
onMounted(() => {}); | |||
onMounted(() => { | |||
setTimeout(() => { | |||
isAdmin.value = localStorage.getItem("isAdmin") || '' | |||
localDeploy.value = localStorage.getItem("localDeploy") || '' | |||
}, 500) | |||
getMenuNavFunc(); | |||
}); | |||
//#region 联系我们弹窗 | |||
const showTalkUsDialog = ref(false); | |||
const updateShowTalkUsDialog = (newValue: any) => { | |||
showTalkUsDialog.value = newValue; | |||
}; | |||
//#endregion ------------------------------------ | |||
//#region 获取路由列表 | |||
const MenuList = ref([{ id: "", name: "" }]); | |||
async function getMenuNavFunc() { | |||
try { | |||
const res = await getMenuNavApi(); | |||
MenuList.value = res.data.menuList; | |||
if (res.code === 200) { | |||
isLogin.value = true | |||
} | |||
} catch (error) { | |||
console.log(error); | |||
} | |||
} | |||
//#endregion ------------------------------------ | |||
//#region 路由及子路由 | |||
const showChildrenRouter = ref(""); | |||
//#endregion ------------------------------------ | |||
</script> | |||
<!-- 新样式 --> | |||
<style lang="scss" scoped> | |||
.app-wrapper { | |||
width: 1920px; | |||
// width: 1920px; | |||
display: flex; | |||
} | |||
.Sidebar { | |||
@@ -170,8 +241,9 @@ const updateShowTalkUsDialog = (newValue: any) => { | |||
.myRouter { | |||
position: relative; | |||
height: calc(100% - 80px); | |||
padding: 130px 20px 0; | |||
padding: 50px 20px 0; | |||
color: #fff; | |||
width: 230px; | |||
// color: #868593; | |||
.bottomBtx { | |||
@@ -179,10 +251,10 @@ const updateShowTalkUsDialog = (newValue: any) => { | |||
bottom: 30px; | |||
} | |||
&-item { | |||
display: flex; | |||
// display: flex; | |||
width: 100%; | |||
height: 50px; | |||
padding-left: 10px; | |||
// height: 50px; | |||
// padding-left: 10px; | |||
font-size: 20px; | |||
font-weight: 500; | |||
line-height: 50px; | |||
@@ -193,14 +265,20 @@ const updateShowTalkUsDialog = (newValue: any) => { | |||
border-radius: 5px; | |||
margin-bottom: 20px; | |||
margin-right: 20px; | |||
overflow: hidden; | |||
.icon { | |||
width: 40px; | |||
height: 40px; | |||
display: flex; | |||
color: #fff; | |||
border-radius: 50%; | |||
margin-right: 10px; | |||
width: 100%; | |||
height: 50px; | |||
line-height: 50px; | |||
.el-icon { | |||
margin-left: 10px; | |||
margin-top: 12px; | |||
margin-right: 10px; | |||
width: 25px; | |||
height: 25px; | |||
font-size: 25px; | |||
@@ -210,11 +288,22 @@ const updateShowTalkUsDialog = (newValue: any) => { | |||
vertical-align: sub; | |||
} | |||
} | |||
.childrenRouter { | |||
cursor: pointer; | |||
transition: all 0.3s; | |||
} | |||
.childrenRouter:hover { | |||
color: #ffffff; | |||
background-color: #000000; | |||
} | |||
&:hover { | |||
// background: rgba(255, 255, 255, 0.2); | |||
color: #000; | |||
background: #fff; | |||
.icon { | |||
color: #000; | |||
} | |||
.el-icon { | |||
// color: #d4d0ff; | |||
color: #000; | |||
@@ -256,4 +345,11 @@ const updateShowTalkUsDialog = (newValue: any) => { | |||
} | |||
} | |||
} | |||
.el-menu{ | |||
border: none; | |||
:deep .el-sub-menu__title, :deep .el-menu-item{ | |||
font-size: 16px; | |||
} | |||
} | |||
</style> |
@@ -17,7 +17,7 @@ import "element-plus/theme-chalk/dark/css-vars.css"; | |||
import "@/styles/index.scss"; | |||
import "uno.css"; | |||
import "@/styles/my.scss"; // 引入自己定义的样式 | |||
import 'amfe-flexible'; | |||
// import 'amfe-flexible'; | |||
import ElementPlus from "element-plus"; | |||
// 引入组件 | |||
import myLoading from "@/components/myLoading.vue"; | |||
@@ -9,35 +9,36 @@ NProgress.configure({ showSpinner: false }); // 进度条 | |||
const permissionStore = usePermissionStoreHook(); | |||
// 白名单路由 | |||
const whiteList = ["/login", "/signSucceed",'/createVideo','/moveImg']; | |||
const whiteList = ["/login", "/signSucceed", "/createVideo", "/moveImg"]; | |||
router.beforeEach(async (to, from, next) => { | |||
NProgress.start(); | |||
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(() => { | |||
@@ -5,87 +5,93 @@ export const Layout = () => import("@/layout/index.vue"); | |||
// 静态路由 | |||
export const constantRoutes: RouteRecordRaw[] = [ | |||
{ | |||
path: "/", | |||
redirect: "/login", | |||
}, | |||
// 登录 | |||
{ | |||
path: "/login", | |||
component: () => import("@/views/login/index.vue"), | |||
meta: { hidden: true }, | |||
name:'login' | |||
name: "login", | |||
}, | |||
{ | |||
path: "/signSucceed", | |||
component: () => import("@/views/signSucceed/index.vue"), | |||
meta: { hidden: true }, | |||
}, | |||
// 创建视频 | |||
{ | |||
path: "/", | |||
component: Layout, | |||
redirect: "/createVideo", | |||
redirect: "/model", | |||
children: [ | |||
{ | |||
path: "createVideo", | |||
component: () => import("@/views/createVideo/index.vue"), | |||
name: "createVideo", | |||
path: "model", | |||
component: () => import("@/views/mangage/model.vue"), | |||
name: "model", | |||
meta: { | |||
title: "createVideo", | |||
title: "model", | |||
icon: "homepage", | |||
affix: true, | |||
name: "createVideo.title", | |||
name: "modelMangage.title", | |||
}, | |||
}, | |||
], | |||
}, | |||
// 视频列表 | |||
{ | |||
path: "/", | |||
component: Layout, | |||
redirect: "/myCreating", | |||
redirect: "/keyList", | |||
children: [ | |||
{ | |||
path: "myCreating", | |||
component: () => import("@/views/myCreating/index.vue"), | |||
name: "myCreating", | |||
path: "keyList", | |||
component: () => import("@/views/keys/keyList.vue"), | |||
name: "keyList", | |||
meta: { | |||
title: "myCreating", | |||
title: "keyList", | |||
icon: "homepage", | |||
affix: true, | |||
name: "myCreating.title", | |||
name: "keyMangage.list", | |||
}, | |||
}, | |||
], | |||
}, { | |||
}, | |||
{ | |||
path: "/", | |||
component: Layout, | |||
redirect: "/myStore", | |||
redirect: "/keyCheck", | |||
children: [ | |||
{ | |||
path: "myStore", | |||
component: () => import("@/views/myStore/index.vue"), | |||
name: "myStore", | |||
path: "keyCheck", | |||
component: () => import("@/views/keys/keyCheck.vue"), | |||
name: "keyCheck", | |||
meta: { | |||
title: "myStore", | |||
title: "keyCheck", | |||
icon: "homepage", | |||
affix: true, | |||
name: "myStore.title", | |||
name: "keyMangage.title", | |||
}, | |||
}, | |||
], | |||
}, { | |||
}, | |||
{ | |||
path: "/", | |||
component: Layout, | |||
redirect: "/myAPI", | |||
redirect: "/businessList", | |||
children: [ | |||
{ | |||
path: "myAPI", | |||
component: () => import("@/views/myAPI/index.vue"), | |||
name: "myAPI", | |||
path: "businessList", | |||
component: () => import("@/views/business/businessList.vue"), | |||
name: "businessList", | |||
meta: { | |||
title: "myAPI", | |||
title: "businessList", | |||
icon: "homepage", | |||
affix: true, | |||
name: "API.title", | |||
name: "keyMangage.list", | |||
}, | |||
}, | |||
], | |||
@@ -93,22 +99,187 @@ export const constantRoutes: RouteRecordRaw[] = [ | |||
{ | |||
path: "/", | |||
component: Layout, | |||
redirect: "/moveImg", | |||
redirect: "/businessCheck", | |||
children: [ | |||
{ | |||
path: "moveImg", | |||
component: () => import("@/views/moveImg/index.vue"), | |||
name: "moveImg", | |||
path: "businessCheck", | |||
component: () => import("@/views/apiManage/businessCheck.vue"), | |||
name: "businessCheck", | |||
meta: { | |||
title: "moveImg", | |||
title: "businessCheck", | |||
icon: "homepage", | |||
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", | |||
}, | |||
}, | |||
], | |||
}, | |||
{ | |||
path: "/", | |||
component: Layout, | |||
redirect: "/home", | |||
children: [ | |||
{ | |||
path: "/home", | |||
component: () => import("@/views/home/index.vue"), | |||
name: "home", | |||
meta: { | |||
title: "home", | |||
icon: "home", | |||
affix: true, | |||
name: "ruleListMangage.title", | |||
}, | |||
}, | |||
{ | |||
path: "/apiManage", | |||
component: () => import("@/views/apiManage/index.vue"), | |||
name: "apiManage", | |||
meta: { | |||
title: "apiManage", | |||
icon: "homepage", | |||
affix: true, | |||
name: "ruleListMangage.title", | |||
}, | |||
}, | |||
{ | |||
path: "/privatization", | |||
component: () => import("@/views/privatization/index.vue"), | |||
name: "privatization", | |||
meta: { | |||
title: "privatization", | |||
icon: "homepage", | |||
affix: true, | |||
name: "ruleListMangage.title", | |||
}, | |||
}, | |||
{ | |||
path: "/template", | |||
component: () => import("@/views/template/index.vue"), | |||
name: "template", | |||
meta: { | |||
title: "template", | |||
icon: "homepage", | |||
affix: true, | |||
name: "ruleListMangage.title", | |||
}, | |||
}, | |||
{ | |||
path: "/secretKey", | |||
component: () => import("@/views/secretKey/index.vue"), | |||
name: "secretKey", | |||
meta: { | |||
title: "secretKey", | |||
icon: "homepage", | |||
affix: true, | |||
name: "ruleListMangage.title", | |||
}, | |||
}, | |||
{ | |||
path: "/video", | |||
component: () => import("@/views/video/index.vue"), | |||
name: "video", | |||
meta: { | |||
title: "video", | |||
icon: "homepage", | |||
affix: true, | |||
name: "ruleListMangage.title", | |||
}, | |||
}, | |||
{ | |||
path: "/userManage", | |||
component: () => import("@/views/userManage/userList.vue"), | |||
name: "userManage", | |||
meta: { | |||
title: "userManage", | |||
icon: "homepage", | |||
affix: true, | |||
name: "ruleListMangage.title", | |||
}, | |||
}, | |||
{ | |||
path: "/userMouldList", | |||
component: () => import("@/views/userManage/userMouldList.vue"), | |||
name: "userMouldList", | |||
meta: { | |||
title: "userMouldList", | |||
icon: "homepage", | |||
affix: true, | |||
name: "ruleListMangage.title", | |||
}, | |||
}, | |||
{ | |||
path: "/userVoiceList", | |||
component: () => import("@/views/userManage/userVoiceList.vue"), | |||
name: "userVoiceList", | |||
meta: { | |||
title: "userVoiceList", | |||
icon: "homepage", | |||
affix: true, | |||
name: "ruleListMangage.title", | |||
}, | |||
}, | |||
{ | |||
path: "/rechargeList", | |||
component: () => import("@/views/userManage/rechargeList.vue"), | |||
name: "rechargeList", | |||
meta: { | |||
title: "rechargeList", | |||
icon: "homepage", | |||
affix: true, | |||
name: "ruleListMangage.title", | |||
}, | |||
}, | |||
{ | |||
path: "/videoList", | |||
component: () => import("@/views/userManage/videoList.vue"), | |||
name: "videoList", | |||
meta: { | |||
title: "videoList", | |||
icon: "homepage", | |||
affix: true, | |||
name: "ruleListMangage.title", | |||
}, | |||
}, | |||
], | |||
} | |||
]; | |||
/** | |||
@@ -1,3 +1,10 @@ | |||
/* | |||
* @Autor: Chutingting | |||
* @Date: 2023-11-02 11:32:51 | |||
* @LastEditors: Chutingting | |||
* @LastEditTime: 2023-11-08 10:26:54 | |||
* @Description: | |||
*/ | |||
import { defineStore } from "pinia"; | |||
import { store } from "@/store"; | |||
import { | |||
@@ -13,7 +13,12 @@ declare module '@vue/runtime-core' { | |||
CutImg1: typeof import('./../components/cutImg1.vue')['default'] | |||
EditPosition: typeof import('./../components/EditPosition.vue')['default'] | |||
'EditPosition copy': typeof import('./../components/EditPosition copy.vue')['default'] | |||
ElAlert: typeof import('element-plus/es')['ElAlert'] | |||
ElButton: typeof import('element-plus/es')['ElButton'] | |||
ElCard: typeof import('element-plus/es')['ElCard'] | |||
ElCheckbox: typeof import('element-plus/es')['ElCheckbox'] | |||
ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup'] | |||
ElDatePicker: typeof import('element-plus/es')['ElDatePicker'] | |||
ElDialog: typeof import('element-plus/es')['ElDialog'] | |||
ElDropdown: typeof import('element-plus/es')['ElDropdown'] | |||
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem'] | |||
@@ -23,27 +28,40 @@ declare module '@vue/runtime-core' { | |||
ElIcon: typeof import('element-plus/es')['ElIcon'] | |||
ElInput: typeof import('element-plus/es')['ElInput'] | |||
ElInputNumber: typeof import('element-plus/es')['ElInputNumber'] | |||
ElMenu: typeof import('element-plus/es')['ElMenu'] | |||
ElMenuItem: typeof import('element-plus/es')['ElMenuItem'] | |||
ElMenuItemGroup: typeof import('element-plus/es')['ElMenuItemGroup'] | |||
ElOption: typeof import('element-plus/es')['ElOption'] | |||
ElPagination: typeof import('element-plus/es')['ElPagination'] | |||
ElRadio: typeof import('element-plus/es')['ElRadio'] | |||
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup'] | |||
ElSelect: typeof import('element-plus/es')['ElSelect'] | |||
ElSubMenu: typeof import('element-plus/es')['ElSubMenu'] | |||
ElSwitch: typeof import('element-plus/es')['ElSwitch'] | |||
ElTable: typeof import('element-plus/es')['ElTable'] | |||
ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] | |||
ElTag: typeof import('element-plus/es')['ElTag'] | |||
ElTooltip: typeof import('element-plus/es')['ElTooltip'] | |||
ElUpload: typeof import('element-plus/es')['ElUpload'] | |||
GithubCorner: typeof import('./../components/GithubCorner/index.vue')['default'] | |||
Hamburger: typeof import('./../components/Hamburger/index.vue')['default'] | |||
IconSelect: typeof import('./../components/IconSelect/index.vue')['default'] | |||
IEpAvatar: typeof import('~icons/ep/avatar')['default'] | |||
IEpCloseBold: typeof import('~icons/ep/close-bold')['default'] | |||
IEpCollection: typeof import('~icons/ep/collection')['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'] | |||
IEpHouse: typeof import('~icons/ep/house')['default'] | |||
IEpLink: typeof import('~icons/ep/link')['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'] | |||
IEpPlus: typeof import('~icons/ep/plus')['default'] | |||
IEpPointer: typeof import('~icons/ep/pointer')['default'] | |||
IEpRefresh: typeof import('~icons/ep/refresh')['default'] | |||
IEpSearch: typeof import('~icons/ep/search')['default'] | |||
IEpUser: typeof import('~icons/ep/user')['default'] | |||
IEpUserFilled: typeof import('~icons/ep/user-filled')['default'] | |||
IEpVideoPlay: typeof import('~icons/ep/video-play')['default'] | |||
LangSelect: typeof import('./../components/LangSelect/index.vue')['default'] | |||
MultiUpload: typeof import('./../components/Upload/MultiUpload.vue')['default'] | |||
@@ -60,5 +78,6 @@ declare module '@vue/runtime-core' { | |||
} | |||
export interface ComponentCustomProperties { | |||
vInfiniteScroll: typeof import('element-plus/es')['ElInfiniteScroll'] | |||
vLoading: typeof import('element-plus/es')['ElLoadingDirective'] | |||
} | |||
} |
@@ -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 | |||
// 开发环境需以 "/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) | |||
/** | |||
@@ -27,7 +27,7 @@ const request = axios.create({ | |||
request.interceptors.request.use( | |||
function (config) { | |||
// 给所有授权的请求提供token | |||
// // 给所有授权的请求提供token | |||
const AccessToken = localStorage.getItem("AccessToken") | |||
if (AccessToken) { | |||
config.headers.token = AccessToken | |||
@@ -59,8 +59,8 @@ request.interceptors.response.use( | |||
} | |||
let code = response.data.code | |||
// 当token无效(过期或损坏)时 1053为未登录 | |||
if (code == 1052 || code == 1053) { | |||
localStorage.removeItem("AccessToken"); | |||
if (code == 1052 || code == 1053 || code === 701) { | |||
// localStorage.removeItem("AccessToken"); | |||
router.push("/login"); | |||
// ElMessage.error("登录过期,请重新登录!"); | |||
// ElMessage.error($t('tips.tokenExpired')); | |||
@@ -78,7 +78,7 @@ request.interceptors.response.use( | |||
); | |||
// 其他错误 | |||
} else { | |||
return Promise.reject(response.data) | |||
return Promise.reject(response.data.message) | |||
} | |||
} else { | |||
// 正常返回 | |||
@@ -21,7 +21,11 @@ service.interceptors.request.use( | |||
return Promise.reject(error); | |||
} | |||
); | |||
declare module 'axios' { | |||
interface AxiosInstance { | |||
(config: AxiosRequestConfig): Promise<any> | |||
} | |||
} | |||
// 响应拦截器 | |||
service.interceptors.response.use( | |||
(response: AxiosResponse) => { | |||
@@ -0,0 +1,304 @@ | |||
<template> | |||
<div class="page flex justify-around"> | |||
<div class="card"> | |||
<div class="title">{{ $t("businessCheck.detail") }}</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)" | |||
>{{ $t("businessCheck.copy") }}</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)" | |||
>{{ $t("businessCheck.copy") }}</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" | |||
>{{ $t("businessCheck.copy") }}</span | |||
> | |||
</div> | |||
<div class="keyStatus"> | |||
<span class="text" | |||
>{{ $t("businessCheck.status") }}: | |||
<span v-if="!keyStatus" style="color: #36db43">{{ $t("businessCheck.normal") }}</span> | |||
<span v-else style="color: #ff0000">{{ $t("businessCheck.loseEfficacy") }}</span> | |||
</span> | |||
<span v-if="keyStatus" class="fail" @click="changeStatus(0)">{{ $t("businessCheck.restore") }}</span> | |||
<span v-if="!keyStatus" class="success" @click="changeStatus(1)" | |||
>{{ $t("businessCheck.cancel") }}</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 detailId = 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"); | |||
detailId.value = res.data.id | |||
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 = detailId.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,519 @@ | |||
<template> | |||
<div class="page justify-around"> | |||
<div class="addbtn"> | |||
<el-button type="primary" @click="dialogVisible = true"><el-icon><i-ep-plus /></el-icon> {{$t('apiManage.add')}}</el-button> | |||
</div> | |||
<el-table | |||
:data="tableData" | |||
style="width: 100%; height: 90%" | |||
size="large" | |||
align="center" | |||
border | |||
> | |||
<el-table-column | |||
prop="name" | |||
:label="$t('businessMangage.name')" | |||
align="center" | |||
/> | |||
<el-table-column | |||
prop="address" | |||
:label="$t('businessMangage.address')" | |||
align="center" | |||
/> | |||
<el-table-column | |||
prop="status" | |||
:label="$t('businessMangage.status')" | |||
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')" | |||
align="center" | |||
/> | |||
<el-table-column | |||
prop="createTime" | |||
:label="$t('businessMangage.createTime')" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
{{ getDate(scope.row.createTime) }} | |||
</template> | |||
</el-table-column> | |||
<el-table-column | |||
prop="createTime" | |||
:label="$t('apiManage.time')" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
{{ scope.row.remainingTimes }} | |||
</template> | |||
</el-table-column> | |||
<el-table-column | |||
fixed="right" | |||
:label="$t('keyMangage.operations')" | |||
width="400" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
<el-button | |||
link | |||
type="primary" | |||
size="small" | |||
@click="showDetail(scope.row.id)" | |||
>{{$t('apiManage.viewKey')}}</el-button> | |||
<el-button link type="primary" size="small" @click="loginAccount(scope.row)">{{ scope.row.mallUserInfo ? $t('apiManage.editAccount') : $t('apiManage.eddAccount')}}</el-button> | |||
<el-button link type="primary" size="small" @click="setTime(scope.row.id)">{{$t('apiManage.setTime')}}</el-button> | |||
<el-button link type="primary" size="small" @click="associationTemp(scope.row.id)">{{$t('apiManage.associationTemp')}}</el-button> | |||
</template> | |||
</el-table-column> | |||
</el-table> | |||
<el-dialog | |||
v-model="dialogVisible" | |||
v-if="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 | |||
disabled | |||
> | |||
<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> | |||
<!-- 登录账号 --> | |||
<el-dialog v-model="accountDialogVisible" v-if="accountDialogVisible" :title="$t('apiManage.loginAccount')" width="35%" :before-close="handleClose" > | |||
<el-form ref="ruleForm2" label-position="left" label-width="120px" :model="formData2" :rules="rules2"> | |||
<el-form-item :label="$t('apiManage.username')" prop="username"> | |||
<el-input :disabled="mallUserInfoFlag" v-model="formData2.username" :placeholder="$t('businessMangage.nameInputText')" /> | |||
</el-form-item> | |||
<el-form-item :label="$t('apiManage.name')" prop="name" > | |||
<el-input v-model="formData2.name" :placeholder="$t('businessMangage.addressInputText')" /> | |||
</el-form-item> | |||
<el-form-item :label="$t('apiManage.pass')" prop="password"> | |||
<el-input v-model="formData2.password" :placeholder="$t('businessMangage.codeInputText')" /> | |||
</el-form-item> | |||
<el-form-item :label="$t('apiManage.phone')" prop="phone"> | |||
<el-input v-model="formData2.phone" :placeholder="$t('businessMangage.codeInputText')" /> | |||
</el-form-item> | |||
</el-form> | |||
<template #footer> | |||
<span class="dialog-footer"> | |||
<el-button @click="accountDialogVisible = false">{{ | |||
$t("businessMangage.cancel") | |||
}}</el-button> | |||
<el-button type="primary" @click="addAccount(ruleForm2)"> | |||
{{ $t("businessMangage.confirm") }} | |||
</el-button> | |||
</span> | |||
</template> | |||
</el-dialog> | |||
<el-dialog v-model="modelDialogVisible" v-if="modelDialogVisible" :title="$t('apiManage.associationTemp')" width="60%" :before-close="handleClose" > | |||
<model :serviceId="serviceId" @close="handleClose"></model> | |||
</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, setRemainingTimes, saveMallUserInfo, getMallUserInfo } from '@/apis/apiManage.js' | |||
import { useI18n } from "vue-i18n"; | |||
import dayjs from "dayjs"; | |||
import { useRoute, useRouter } from "vue-router"; | |||
import model from './model.vue' | |||
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; | |||
getListData(pageNum.value, pageSize.value); | |||
}; | |||
const handleCurrentChange = (val) => { | |||
pageNum.value = val; | |||
getListData(pageNum.value, pageSize.value); | |||
}; | |||
const getListData = async (PageNum, PageSize) => { | |||
try { | |||
const res = await businessListApi(PageNum, PageSize, 1, route.query.id || ''); | |||
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: 1, | |||
}); | |||
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; | |||
accountDialogVisible.value = false; | |||
modelDialogVisible.value = false; | |||
setTimeout(() => { | |||
formData.value = { | |||
name: "", | |||
address: "", | |||
code: "", | |||
type: 1, | |||
}; | |||
}, 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; | |||
} | |||
getListData(1, 10); | |||
pageNum.value = 1; | |||
pageSize.value = 10; | |||
} catch (error) { | |||
console.log(error, "err"); | |||
ElMessage.error(error.message); | |||
} | |||
} else { | |||
ElMessage.error("请完善信息!"); | |||
} | |||
}); | |||
}; | |||
// 设置时长 | |||
const setTime = (id) => { | |||
ElMessageBox.prompt('请输入时长(秒)', '设置时长', { | |||
confirmButtonText: 'OK', | |||
cancelButtonText: 'Cancel', | |||
inputPattern: /^[0-9]*$/, | |||
inputErrorMessage: '请输入数字', | |||
beforeClose: async (action, instance, done) => { | |||
if (action == "confirm") {//点击确认请求接口 | |||
let res = await setRemainingTimes({ id: id, times: instance.inputValue }) | |||
if (res.code === 200) { | |||
// 通过监测关闭 | |||
ElMessage.success('设置成功') | |||
done(); | |||
} else { | |||
ElMessage.error(res.message) | |||
} | |||
} else { | |||
//点击取消关闭 | |||
done(); | |||
} | |||
} | |||
}) | |||
} | |||
// 登录账号 | |||
const accountDialogVisible = ref(false); | |||
const mallUserInfoFlag = ref(false); | |||
const loginAccount = (item) => { | |||
if (item.mallUserInfo) { | |||
getMallUserInfo(item.id).then(res => { | |||
if (res.code === 200) { | |||
formData2.value = { | |||
serviceId: item.id, | |||
username: res.data.username, | |||
name: res.data.name, | |||
password: '', | |||
phone: res.data.phone | |||
}; | |||
} | |||
}) | |||
} else { | |||
formData2.value.serviceId = item.id | |||
} | |||
mallUserInfoFlag.value = item.mallUserInfo ? true : false | |||
accountDialogVisible.value = true | |||
} | |||
// 登录账号 | |||
const formData2 = ref({ | |||
serviceId: "", | |||
username: "", | |||
name: "", | |||
password: "", | |||
phone: "", | |||
}); | |||
const rules2 = { | |||
name: [ | |||
{ | |||
required: true, | |||
message: "Please input name", | |||
trigger: "blur", | |||
}, | |||
], | |||
username: [ | |||
{ | |||
required: true, | |||
message: "Please input username", | |||
trigger: "blur", | |||
}, | |||
], | |||
password: [ | |||
{ | |||
required: true, | |||
message: "Please input password", | |||
trigger: "blur", | |||
}, | |||
], | |||
phone: [ | |||
{ | |||
required: true, | |||
message: "Please input phone", | |||
trigger: "blur", | |||
}, | |||
], | |||
}; | |||
const ruleForm2 = ref(); | |||
const addAccount = async (refForm) => { | |||
if (!refForm) return; | |||
await refForm.validate(async (valid, fields) => { | |||
if (valid) { | |||
const data = formData2.value; | |||
try { | |||
const res = await saveMallUserInfo(data); | |||
if (res.code == 200) { | |||
ElMessage.success("添加成功!"); | |||
accountDialogVisible.value = false; | |||
} | |||
getListData(1, 10); | |||
pageNum.value = 1; | |||
pageSize.value = 10; | |||
} catch (error) { | |||
console.log(error, "err"); | |||
ElMessage.error(error); | |||
} | |||
} else { | |||
ElMessage.error("请完善信息!"); | |||
} | |||
}); | |||
}; | |||
// 关联模版 | |||
const modelDialogVisible = ref(false); | |||
const serviceId = ref('') | |||
function associationTemp(id) { | |||
modelDialogVisible.value = true | |||
serviceId.value = id | |||
} | |||
onMounted(() => { | |||
getListData(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> |
@@ -0,0 +1,88 @@ | |||
<template> | |||
<div> | |||
<el-checkbox-group v-model="checkboxGroup" size="small" class="checkbox"> | |||
<el-checkbox v-for="(item, index) in tableData" :key="index" :label="item.id" border> | |||
<img :src="item.coverImg" width="50" /> | |||
<p>{{ item.title }}</p> | |||
</el-checkbox> | |||
</el-checkbox-group> | |||
<div style="margin-top: 20px"> | |||
<el-button @click="handleClose" | |||
>{{ $t('personMould.cancel') }}</el-button | |||
> | |||
<el-button type="primary" @click="addModel()">{{ $t('personMould.confirm') }}</el-button> | |||
</div> | |||
</div> | |||
</template> | |||
<script setup> | |||
import { ref } from 'vue' | |||
import { ElTable } from 'element-plus' | |||
import { modelAllList, personMouldIdList, associatedMould } from '@/apis/apiManage.js' | |||
import dayjs from "dayjs"; | |||
const emit = defineEmits(["close"]); | |||
const props = defineProps({ | |||
serviceId: { | |||
required: true, | |||
} | |||
}); | |||
const getDate = (val) => { | |||
return dayjs(val).format("YYYY-MM-DD"); | |||
}; | |||
const checkboxGroup = ref([]) | |||
const total = ref(0); | |||
const tableData = ref([]); | |||
const modelAllListFunc = async () => { | |||
try { | |||
const res = await modelAllList(1, 10000); | |||
const modelIds = await personMouldIdList(props.serviceId); | |||
tableData.value = res.data.list; | |||
total.value = res.data.total * 1; | |||
setTimeout(()=> { | |||
if(modelIds.data && modelIds.data.length > 0) { | |||
modelIds.data.forEach((item) => { | |||
checkboxGroup.value.push(item) | |||
}) | |||
} | |||
}, 500) | |||
} catch (error) { | |||
console.log(error, "err"); | |||
} | |||
}; | |||
const addModel = async () => { | |||
const data = { | |||
mouldIds: checkboxGroup.value, | |||
serviceId: props.serviceId | |||
} | |||
const res = await associatedMould(data); | |||
if(res.code === 200) { | |||
ElMessage.success("关联成功!"); | |||
handleClose() | |||
} | |||
}; | |||
function handleClose() { | |||
emit("close"); | |||
} | |||
onMounted(() => { | |||
modelAllListFunc(1, 10); | |||
}); | |||
</script> | |||
<style lang="scss" scoped> | |||
.checkbox { | |||
max-height: 500px; | |||
overflow: auto; | |||
:deep .el-checkbox.el-checkbox--small { | |||
width: 110px; | |||
height:110px; | |||
margin-bottom: 10px; | |||
} | |||
} | |||
</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,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([]); | |||
async function voiceTotal() { | |||
const res = await voiceTotalApi(); | |||
languageOptions.value = res.data; | |||
// const res = await voiceTotalApi(); | |||
// languageOptions.value = res.data; | |||
} | |||
// 声音下拉框内容 | |||
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,116 @@ | |||
<template> | |||
<div class="page"> | |||
<el-form | |||
ref="ruleFormRef" | |||
:model="ruleForm" | |||
status-icon | |||
:rules="rules" | |||
label-width="120px" | |||
class="editPass" | |||
> | |||
<el-form-item :label="$t('editPass.username')" prop="pass"> | |||
<el-input v-model="ruleForm.userName" disabled autocomplete="off" /> | |||
</el-form-item> | |||
<el-form-item :label="$t('editPass.pass')" prop="pass"> | |||
<el-input v-model="ruleForm.pass" type="password" autocomplete="off" /> | |||
</el-form-item> | |||
<el-form-item :label="$t('editPass.checkPass')" prop="checkPass"> | |||
<el-input | |||
v-model="ruleForm.checkPass" | |||
type="password" | |||
autocomplete="off" | |||
/> | |||
</el-form-item> | |||
<el-form-item> | |||
<el-button @click="handleClose(ruleFormRef)">Close</el-button> | |||
<el-button type="primary" @click="submitForm(ruleFormRef)">Submit</el-button> | |||
</el-form-item> | |||
</el-form> | |||
</div> | |||
</template> | |||
<script lang="ts" setup> | |||
import { reactive, ref } from 'vue' | |||
import type { FormInstance, FormRules } from 'element-plus' | |||
import { updatepwd } from "@/apis/editPass.js"; | |||
import { logoutApi } from '@/apis/login.js' | |||
import { userInfoModules } from "@/store/modules/userInfo"; | |||
import { useRoute, useRouter } from "vue-router"; | |||
import { useI18n } from "vue-i18n"; | |||
const { locale } = useI18n(); | |||
const lanChange = ref(locale); | |||
const userInfoPinia = userInfoModules(); | |||
const router = useRouter(); | |||
const emit = defineEmits(["close"]); | |||
const ruleFormRef = ref<FormInstance>() | |||
const validatePass = (rule: any, value: any, callback: any) => { | |||
if (value === '') { | |||
callback(new Error(lanChange.value == "zh-cn" ? '请输入密码' : 'Please enter the password')) | |||
} else { | |||
if (ruleForm.checkPass !== '') { | |||
if (!ruleFormRef.value) return | |||
ruleFormRef.value.validateField('checkPass', () => null) | |||
} | |||
callback() | |||
} | |||
} | |||
const validatePass2 = (rule: any, value: any, callback: any) => { | |||
if (value === '') { | |||
callback(new Error(lanChange.value == "zh-cn" ? '请重新输入密码' : 'Please re-enter the password')) | |||
} else if (value !== ruleForm.pass) { | |||
callback(new Error(lanChange.value == "zh-cn" ? "两次密码不一致" : 'The two passwords do not match')) | |||
} else { | |||
callback() | |||
} | |||
} | |||
const ruleForm = reactive({ | |||
userName: localStorage.getItem("username"), | |||
pass: '', | |||
checkPass: '' | |||
}) | |||
const rules = reactive({ | |||
pass: [{ validator: validatePass, trigger: 'blur' }], | |||
checkPass: [{ validator: validatePass2, trigger: 'blur' }] | |||
}) | |||
const submitForm = (formEl: FormInstance | undefined) => { | |||
if (!formEl) return | |||
formEl.validate(async (valid) => { | |||
if (valid) { | |||
const data = { | |||
userName: ruleForm.userName, | |||
pwd: ruleForm.checkPass | |||
}; | |||
try { | |||
const res = await updatepwd(data); | |||
if (res.code == 200) { | |||
ElMessage.success( lanChange.value == "zh-cn" ? "修改成功!" : 'Modified successfully!'); | |||
logoutApi().then(d => { | |||
userInfoPinia.loginOut(); | |||
router.push(`/login`); | |||
}) | |||
localStorage.removeItem("AccessToken"); | |||
handleClose(ruleFormRef.value) | |||
} | |||
} catch (error) { | |||
console.log(error, "err"); | |||
// ElMessage.error(error.message); | |||
} | |||
} else { | |||
console.log('error submit!') | |||
return false | |||
} | |||
}) | |||
} | |||
const handleClose = (formEl: FormInstance | undefined) => { | |||
if (!formEl) return | |||
formEl.resetFields() | |||
emit("close"); | |||
} | |||
</script> |
@@ -0,0 +1,104 @@ | |||
<template> | |||
<div class="page"> | |||
<el-card class="box-card"> | |||
<div slot="header" class="clearfix"> | |||
<span>{{ $t('home.info') }}</span> | |||
</div> | |||
<div> | |||
<div style="text-align: center"> | |||
<div class="el-upload"> | |||
<img :src="Avatar" class="avatar"> | |||
<p>{{ userData.username }},{{ $t('home.welcome') }}</p> | |||
</div> | |||
</div> | |||
<ul class="user-info"> | |||
<li><div style="height: 100%"><el-icon><i-ep-UserFilled /></el-icon> {{ $t('home.loginAccount') }}<div class="user-right">{{ userData.username }}</div></div></li> | |||
<li><el-icon><i-ep-Avatar /></el-icon> {{ $t('home.userName') }} <div class="user-right">{{ userData.name }}</div></li> | |||
<li><el-icon><i-ep-User /></el-icon> {{ $t('home.phone') }} <div class="user-right"> {{ userData.phone }}</div></li> | |||
<li v-if="(userData.isAdmin === 1 && localDeploy) || userData.isAdmin === 0"><el-icon><i-ep-User /></el-icon> {{ $t('home.time') }} <div class="user-right"> {{ userData.remainingTimes }} (秒)</div></li> | |||
<li> | |||
<el-icon><i-ep-edit /></el-icon> {{ $t('home.setting') }} | |||
<div class="user-right"> | |||
<a @click="editDialogVisible = true">{{ $t('home.editPwd') }}</a> | |||
</div> | |||
</li> | |||
<!-- <li v-if="userData.isAdmin === '1' && userData.localDeploy"> | |||
<el-icon><i-ep-Pointer /></el-icon> 视频制作统计 | |||
<div class="user-right"> | |||
<a @click="videoDialogVisible = true">查看</a> | |||
</div> | |||
</li> --> | |||
<li v-if="userData.isAdmin === 0"> | |||
<el-icon><i-ep-Pointer /></el-icon>{{ $t('home.key') }} | |||
<div class="user-right"> | |||
<a @click="router.push('/secretKey')">{{ $t('home.view') }} </a> | |||
</div> | |||
</li> | |||
</ul> | |||
</div> | |||
</el-card> | |||
<el-dialog v-model="editDialogVisible" :title="$t('home.editPwd')" width="40%" :before-close="handleClose" > | |||
<edit-pass @close="handleClose"></edit-pass> | |||
</el-dialog> | |||
</div> | |||
</template> | |||
<script setup> | |||
import editPass from '../editPass/index.vue' | |||
import { useRoute, useRouter } from "vue-router"; | |||
import { getUser, privateDeployAdminCurrent, current, localDeployApi } from "@/apis/home.js"; | |||
const route = useRoute(); | |||
const router = useRouter(); | |||
const Avatar = ref('https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png') | |||
const editDialogVisible = ref(false) | |||
const handleClose = () => { | |||
editDialogVisible.value = false; | |||
}; | |||
const userData = ref({ | |||
username: '', | |||
name: '', | |||
remainingTimes: '', | |||
phone: '', | |||
isAdmin: '', | |||
localDeploy: '' | |||
}); | |||
const localDeploy = ref('') | |||
const getData = async () => { | |||
let userRes = await getUser() | |||
let localDeployRes = await localDeployApi() | |||
userData.value = userRes.data | |||
localStorage.setItem("username", userRes.data.username); | |||
localStorage.setItem("isAdmin", userRes.data.isAdmin); // isAdmin=1,为管理人员(邃芒后台) , isAdmin=0,为API接入方登录后台 isAmin=1&&localDeploy=true,就是私有化部署的管理后台 | |||
userData.value.localDeploy = localDeployRes.data | |||
localDeploy.value = localDeployRes.data | |||
localStorage.setItem("localDeploy", localDeployRes.data); | |||
// 当前账户时长 | |||
let res = userData.isAdmin === 1 && localDeploy ? await privateDeployAdminCurrent() : await current() | |||
userData.value.remainingTimes = res.data.remainingTimes | |||
} | |||
onMounted(async () => { | |||
getData() | |||
}); | |||
</script> | |||
<style lang="scss" scoped> | |||
.page{ | |||
padding: 30px | |||
} | |||
.user-info { | |||
padding-left: 0; | |||
list-style: none; | |||
li{ | |||
border-bottom: 1px solid #F0F3F4; | |||
padding: 11px 0; | |||
font-size: 13px; | |||
} | |||
.user-right { | |||
float: right; | |||
a{ | |||
color: #317EF3; | |||
} | |||
} | |||
} | |||
</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> | |||
</div> | |||
<el-form-item prop="email"> | |||
<el-form-item prop="username"> | |||
<div class="text-white"> | |||
<svg-icon icon-class="user" /> | |||
</div> | |||
@@ -39,8 +39,8 @@ | |||
class="flex-1" | |||
ref="email" | |||
size="large" | |||
v-model="loginData.email" | |||
:placeholder="$t('login.email')" | |||
v-model="loginData.username" | |||
:placeholder="$t('login.username')" | |||
name="email" | |||
/> | |||
</el-form-item> | |||
@@ -67,14 +67,14 @@ | |||
</el-form-item> | |||
<!-- 验证码 --> | |||
<el-form-item prop="verifyCode"> | |||
<el-form-item prop="captcha"> | |||
<span class="text-white"> | |||
<svg-icon icon-class="verify_code" /> | |||
</span> | |||
<el-input | |||
v-model="loginData.verifyCode" | |||
v-model="loginData.captcha" | |||
auto-complete="off" | |||
:placeholder="$t('login.verifyCode')" | |||
:placeholder="$t('login.captcha')" | |||
class="flex-1" | |||
@keyup.enter="handleLogin" | |||
/> | |||
@@ -111,9 +111,6 @@ | |||
</el-button> | |||
<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"> | |||
<span class="join" @click="loginFlag(7)">{{ | |||
$t("login.SMSLogin") | |||
@@ -126,188 +123,8 @@ | |||
</div> | |||
</div> | |||
</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--> | |||
<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--> | |||
<el-form | |||
v-if="isLogin == 3" | |||
@@ -691,9 +508,6 @@ | |||
</el-button> | |||
<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"> | |||
<span class="join" @click="loginFlag(1)">{{ | |||
$t("login.pwsLogin") | |||
@@ -786,8 +600,7 @@ | |||
import LangSelect from "@/components/LangSelect/index.vue"; | |||
import SvgIcon from "@/components/SvgIcon/index.vue"; | |||
import { | |||
register, | |||
login, | |||
loginApi, | |||
sendRegisterEmail, | |||
getCodeImgUrl, | |||
sendUpdPwdEmailApi, | |||
@@ -799,6 +612,7 @@ import { | |||
doFindInviteCode, | |||
doUpdateInviteCode, | |||
} from "@/apis/login"; | |||
import { getMenuNavApi } from "@/apis/Permission.js"; | |||
import axios from "axios"; | |||
// 状态管理依赖 | |||
@@ -848,9 +662,9 @@ const isLogining = ref(false); | |||
const isRegistering = ref(false); | |||
const loginData = ref({ | |||
email: "", | |||
username: "", | |||
password: "", | |||
verifyCode: "", | |||
captcha: "", | |||
}); | |||
const loginData2 = ref({ | |||
@@ -882,6 +696,13 @@ const loginData8 = ref({ | |||
invitatioCode: "", | |||
}); | |||
const loginRules = ref({ | |||
username: [ | |||
{ | |||
required: true, | |||
trigger: "blur", | |||
validator: passwordValidator, | |||
}, | |||
], | |||
email: [ | |||
{ | |||
required: true, | |||
@@ -894,13 +715,13 @@ const loginRules = ref({ | |||
confirmPassword: [ | |||
{ required: true, trigger: "blur", validator: confirmPasswordValidator }, | |||
], | |||
verifyCode: [ | |||
captcha: [ | |||
{ | |||
required: true, | |||
trigger: "blur", | |||
message: | |||
currentLan.value == "zh-cn" | |||
? "请输入验证码" | |||
? "请输入验证码2" | |||
: "Please input verifyCode", | |||
}, | |||
], | |||
@@ -928,8 +749,8 @@ const loginRules = ref({ | |||
watch(currentLan, (newValue, oldValue) => { | |||
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(() => { | |||
loginFormRef.value.resetFields(); | |||
getInfo(); | |||
@@ -973,7 +794,7 @@ function getInfo() { | |||
const deCodeUserInfo = decodeURI(data as any); | |||
const userInfo = JSON.parse(deCodeUserInfo); | |||
if (userInfo) { | |||
loginData.value.email = userInfo.email ? userInfo.email : ""; | |||
loginData.value.username = userInfo.email ? userInfo.email : ""; | |||
loginData.value.password = userInfo.password ? userInfo.password : ""; | |||
} | |||
} | |||
@@ -1091,48 +912,7 @@ function confirmPasswordValidator5(rule: any, value: any, callback: any) { | |||
} | |||
//#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 | |||
function sendEmailforgetPwd() { | |||
@@ -1178,7 +958,7 @@ function resetPwdEmail() { | |||
ticket: route.query.ticket, | |||
}); | |||
localStorage.removeItem("AccessToken"); | |||
loginData.value.email = route.query.email + ""; | |||
// loginData.value.email = route.query.email + ""; | |||
loginData.value.password = ""; | |||
isLogin.value = 1; | |||
router.push({ path: "login", query: {} }); | |||
@@ -1329,7 +1109,7 @@ async function checkInviteCode() { | |||
isLogin.value = 8; | |||
// 有邀请码直接前往我的页面 | |||
} else if (status == 1) { | |||
userInfoPinia.getUserInfo(); //保存邮箱到pinia | |||
// userInfoPinia.getUserInfo(); //保存邮箱到pinia | |||
ElMessage.success( | |||
'currentLan.value == "zh-cn" ? "登录成功!" : "Welcome to Metavatar!"' | |||
); | |||
@@ -1351,7 +1131,7 @@ async function handleInvitatioCode() { | |||
}; | |||
try { | |||
const res = await doUpdateInviteCode(data); | |||
userInfoPinia.getUserInfo(); //保存邮箱到pinia | |||
// userInfoPinia.getUserInfo(); //保存邮箱到pinia | |||
ElMessage.success( | |||
'currentLan.value == "zh-cn" ? "登录成功!" : "Welcome to Metavatar!"' | |||
); | |||
@@ -1370,92 +1150,98 @@ function getCode() { | |||
axios({ | |||
url: getCodeImgUrl, | |||
method: "get", | |||
}).then(() => { | |||
}).then((res) => { | |||
verifyCodeUrl.value = getCodeImgUrl; | |||
showCodeImg.value = true; | |||
}); | |||
} | |||
/** | |||
* @description:注册 | |||
* @description:登录 | |||
* @param {Object} data | |||
* @return: data | |||
*/ | |||
async function doRegister(data: object) { | |||
/** | |||
* @description:重新发送邮件 | |||
* @param {string} email | |||
* @return: data | |||
*/ | |||
async function reSendEmail(email: string) { | |||
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) => { | |||
console.log(res, "res"); | |||
isRegistering.value = false; | |||
ElMessage.success(msg); | |||
isLogin.value = 1; | |||
// 注册成功将账号密码保存到本地 | |||
saveInfo(data); | |||
router.go(0); | |||
}) | |||
.catch((err) => { | |||
// 注册失败刷新验证码 | |||
getCode(); | |||
isRegistering.value = false; | |||
console.log(err, "err"); | |||
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) { | |||
const msg = | |||
currentLan.value == "zh-cn" ? "登录成功!" : "Welcome to Metavatar!"; | |||
await login(data) | |||
await loginApi(data) | |||
.then(async (res) => { | |||
console.log(res, "res"); | |||
localStorage.setItem("AccessToken", res.data.token); | |||
// localStorage.setItem("AccessToken", res.data.token); | |||
// 注册成功将账号密码保存到本地 | |||
saveInfo(data); | |||
await getMenuNavFunc(); | |||
isLogining.value = false; | |||
// await checkInviteCode(); | |||
userInfoPinia.getUserInfo(); //保存邮箱到pinia | |||
// userInfoPinia.getUserInfo(); //保存邮箱到pinia | |||
ElMessage.success(msg); | |||
router.push("/createVideo"); | |||
router.push("/home"); | |||
}) | |||
.catch((err) => { | |||
console.log(err, "err"); | |||
// 登录失败刷新验证码 | |||
getCode(); | |||
ElMessage.error(err.message); | |||
ElMessage.error(err); | |||
isLogining.value = false; | |||
if (err.code == 2112) { | |||
reSendEmail(data.email); | |||
} | |||
}); | |||
} | |||
//#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(() => { | |||
getCode(); | |||
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> |
@@ -0,0 +1,378 @@ | |||
<template> | |||
<div class="page justify-around"> | |||
<div class="addbtn"> | |||
<el-button type="primary" @click="dialogVisible = true"><el-icon><i-ep-plus /></el-icon> 新增</el-button> | |||
</div> | |||
<el-table | |||
:data="tableData" | |||
style="width: 100%; height: 90%" | |||
size="large" | |||
align="center" | |||
border | |||
> | |||
<el-table-column | |||
prop="name" | |||
:label="$t('businessMangage.name')" | |||
align="center" | |||
/> | |||
<el-table-column | |||
prop="address" | |||
:label="$t('businessMangage.address')" | |||
align="center" | |||
/> | |||
<el-table-column | |||
prop="status" | |||
:label="$t('businessMangage.status')" | |||
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')" | |||
align="center" | |||
/> | |||
<el-table-column | |||
prop="createTime" | |||
:label="$t('businessMangage.createTime')" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
{{ getDate(scope.row.createTime) }} | |||
</template> | |||
</el-table-column> | |||
<el-table-column | |||
prop="createTime" | |||
label="时长(秒)" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
{{ scope.row.remainingTimes }} | |||
</template> | |||
</el-table-column> | |||
<el-table-column | |||
fixed="right" | |||
:label="$t('keyMangage.operations')" | |||
width="400" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
<el-button | |||
link | |||
type="primary" | |||
size="small" | |||
@click="showDetail(scope.row.id)" | |||
>查看密钥</el-button> | |||
<el-button link type="primary" size="small" @click="setTime(scope.row.id)">设置时长</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 | |||
disabled | |||
> | |||
<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 { businessListApi, addBusinessApi, setRemainingTimes, saveMallUserInfo } from '@/apis/apiManage.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 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; | |||
getListData(pageNum.value, pageSize.value); | |||
}; | |||
const handleCurrentChange = (val) => { | |||
pageNum.value = val; | |||
getListData(pageNum.value, pageSize.value); | |||
}; | |||
const getListData = async (PageNum, PageSize) => { | |||
try { | |||
const res = await businessListApi(PageNum, PageSize, 2); | |||
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: 2, | |||
}); | |||
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: 1, | |||
}; | |||
}, 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; | |||
} | |||
getListData(1, 10); | |||
pageNum.value = 1; | |||
pageSize.value = 10; | |||
} catch (error) { | |||
console.log(error, "err"); | |||
ElMessage.error(error.message); | |||
} | |||
} else { | |||
ElMessage.error("请完善信息!"); | |||
} | |||
}); | |||
}; | |||
// 查看时长 | |||
const showDetail = (id) => { | |||
router.push({ | |||
path: "/businessCheck", | |||
query: { | |||
id, | |||
}, | |||
}); | |||
} | |||
// 设置时长 | |||
const setTime = (id) => { | |||
ElMessageBox.prompt('请输入时长(秒)', '设置时长', { | |||
confirmButtonText: 'OK', | |||
cancelButtonText: 'Cancel', | |||
inputPattern: /^[0-9]*$/, | |||
inputErrorMessage: '请输入数字', | |||
beforeClose: async (action, instance, done) => { | |||
if (action == "confirm") {//点击确认请求接口 | |||
let res = await setRemainingTimes({ id: id, times: instance.inputValue }) | |||
if (res.code === 200) { | |||
// 通过监测关闭 | |||
ElMessage.success('设置成功') | |||
done(); | |||
} else { | |||
ElMessage.error(res.message) | |||
} | |||
} else { | |||
//点击取消关闭 | |||
done(); | |||
} | |||
} | |||
}) | |||
} | |||
onMounted(() => { | |||
getListData(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> |
@@ -0,0 +1,43 @@ | |||
<template> | |||
<el-form :model="form" label-width="120px" class="page"> | |||
<el-form-item label="name"> | |||
<el-input v-model="form.name" /> | |||
</el-form-item> | |||
<el-form-item label="appId"> | |||
<el-input v-model="form.appId" /> | |||
</el-form-item> | |||
<el-form-item label="appKey"> | |||
<el-input v-model="form.appKey" /> | |||
</el-form-item> | |||
<el-form-item label="signKey"> | |||
<el-input v-model="form.signKey" /> | |||
</el-form-item> | |||
</el-form> | |||
</template> | |||
<script lang="ts" setup> | |||
import { reactive } from 'vue' | |||
import { secretKeyApi } from '@/apis/secretKey.js' | |||
const form = ref({ | |||
name: '', | |||
appId: '', | |||
appKey: '', | |||
signKey: '' | |||
}) | |||
function getSecretKey() { | |||
secretKeyApi().then(res => { | |||
form.value = res.data | |||
}) | |||
} | |||
onMounted(() => { | |||
getSecretKey(); | |||
}); | |||
</script> | |||
<style lang="scss" scoped> | |||
.page{ | |||
height: calc(100vh - 80px); | |||
background-color: #ffffff; | |||
border-radius: 30px 0 0 0; | |||
overflow: hidden; | |||
padding: 10vh; | |||
} | |||
</style> |
@@ -0,0 +1,124 @@ | |||
<template> | |||
<div class="page justify-around"> | |||
<el-table | |||
:data="tableData" | |||
style="width: 100%; height: 90%" | |||
size="large" | |||
align="center" | |||
border | |||
> | |||
<el-table-column :label="$t('template.img')" align="center"> | |||
<template #default="scope"> | |||
<img :src="scope.row.coverImg" width="50" /> | |||
</template> | |||
</el-table-column> | |||
<el-table-column | |||
prop="createTime" | |||
label="创建时间" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
{{ getDate(scope.row.createTime) }} | |||
</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 { templateListApi } from '@/apis/template.js' | |||
import { useI18n } from "vue-i18n"; | |||
import dayjs from "dayjs"; | |||
import { useRoute, useRouter } from "vue-router"; | |||
const route = useRoute(); | |||
const router = useRouter(); | |||
const tableData = ref([]); | |||
const pageNum = ref(1); | |||
const pageSize = ref(10); | |||
const total = ref(0); | |||
const getDate = (val) => { | |||
return dayjs(val).format("YYYY-MM-DD"); | |||
}; | |||
const handleSizeChange = (val) => { | |||
pageSize.value = val; | |||
getListData(pageNum.value, pageSize.value); | |||
}; | |||
const handleCurrentChange = (val) => { | |||
pageNum.value = val; | |||
getListData(pageNum.value, pageSize.value); | |||
}; | |||
const getListData = async (PageNum, PageSize) => { | |||
try { | |||
const res = await templateListApi(PageNum, PageSize); | |||
console.log(res, "res"); | |||
tableData.value = res.data.list; | |||
total.value = res.data.total * 1; | |||
} catch (error) { | |||
console.log(error, "err"); | |||
} | |||
}; | |||
onMounted(() => { | |||
getListData(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> |
@@ -0,0 +1,91 @@ | |||
<template> | |||
<div> | |||
<el-checkbox-group v-model="checkboxGroup" size="small" class="checkbox"> | |||
<el-checkbox v-for="(item, index) in tableData" :key="index" :label="item.id" border> | |||
<img :src="item.coverImg" width="50" /> | |||
<p>{{ item.title }}</p> | |||
</el-checkbox> | |||
</el-checkbox-group> | |||
<div style="margin-top: 20px"> | |||
<el-button @click="handleClose" | |||
>{{$t('personMould.cancel')}}</el-button | |||
> | |||
<el-button type="primary" @click="addModel()">{{$t('personMould.confirm')}}</el-button> | |||
</div> | |||
</div> | |||
</template> | |||
<script setup> | |||
import { ref } from 'vue' | |||
import { personMouldListApi, userPersonMouldIdListApi, associatedUserMouldsApi } from '@/apis/userManage.js' | |||
import dayjs from "dayjs"; | |||
import { useI18n } from "vue-i18n"; | |||
const { locale } = useI18n(); | |||
const lanChange = ref(locale); | |||
const emit = defineEmits(["close"]); | |||
const props = defineProps({ | |||
cUserId: { | |||
required: true, | |||
} | |||
}); | |||
const getDate = (val) => { | |||
return dayjs(val).format("YYYY-MM-DD"); | |||
}; | |||
const checkboxGroup = ref([]) | |||
const total = ref(0); | |||
const tableData = ref([]); | |||
const modelAllListFunc = async () => { | |||
try { | |||
const res = await personMouldListApi(1, 10000); | |||
const modelIds = await userPersonMouldIdListApi(props.cUserId); | |||
tableData.value = res.data.list; | |||
total.value = res.data.total * 1; | |||
setTimeout(()=> { | |||
if(modelIds.data && modelIds.data.length > 0) { | |||
modelIds.data.forEach((item) => { | |||
checkboxGroup.value.push(item) | |||
let set = new Set(checkboxGroup.value) | |||
checkboxGroup.value = Array.from(set) | |||
}) | |||
} | |||
}, 500) | |||
} catch (error) { | |||
console.log(error, "err"); | |||
} | |||
}; | |||
const addModel = async () => { | |||
const data = { | |||
mouldIds: checkboxGroup.value, | |||
userId: props.cUserId | |||
} | |||
const res = await associatedUserMouldsApi(data); | |||
if(res.code === 200) { | |||
ElMessage.success((lanChange.value) == "zh-cn" ? "关联成功!" : 'Successfully associated!'); | |||
handleClose() | |||
} | |||
}; | |||
function handleClose() { | |||
emit("close"); | |||
} | |||
onMounted(() => { | |||
modelAllListFunc(1, 10); | |||
}); | |||
</script> | |||
<style lang="scss" scoped> | |||
.checkbox { | |||
max-height: 500px; | |||
overflow: auto; | |||
:deep .el-checkbox.el-checkbox--small { | |||
width: 110px; | |||
height:110px; | |||
margin-bottom: 10px; | |||
} | |||
} | |||
</style> |
@@ -0,0 +1,146 @@ | |||
<template> | |||
<el-table | |||
ref="multipleTableRef" | |||
:data="tableData" | |||
style="width: 100%" | |||
border | |||
@selection-change="handleSelectionChange" | |||
> | |||
<el-table-column type="selection" width="55" align="center"/> | |||
<el-table-column property="language" :label="$t('personVoice.lang')" align="center"/> | |||
<el-table-column property="country" :label="$t('personVoice.country')" align="center"/> | |||
<el-table-column property="name" :label="$t('personVoice.enName')" align="center"/> | |||
<el-table-column property="chineseName" :label="$t('personVoice.chineseName')" align="center"/> | |||
<el-table-column | |||
prop="createTime" | |||
:label="$t('businessMangage.createTime')" | |||
align="center"> | |||
<template #default="scope"> | |||
{{ getDate(scope.row.createDate) }} | |||
</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" | |||
:total="total" | |||
@size-change="handleSizeChange" | |||
@current-change="handleCurrentChange" | |||
/> | |||
</div> | |||
<div style="margin-top: 20px"> | |||
<el-button @click="handleClose" | |||
>取消</el-button | |||
> | |||
<el-button type="primary" @click="addModel()">确认关联</el-button> | |||
</div> | |||
</template> | |||
<script setup> | |||
import { voiceMouldListApi, userVoiceIdListApi, associatedUserVoicesApi } from '@/apis/userManage.js' | |||
import dayjs from "dayjs"; | |||
import { useI18n } from "vue-i18n"; | |||
const { locale } = useI18n(); | |||
const lanChange = ref(locale); | |||
const emit = defineEmits(["close"]); | |||
const props = defineProps({ | |||
cUserId: { | |||
required: true, | |||
} | |||
}); | |||
const getDate = (val) => { | |||
return dayjs(val).format("YYYY-MM-DD"); | |||
}; | |||
const multipleTableRef = ref() | |||
const multipleSelection = ref([]) | |||
const toggleSelection = (rows) => { | |||
if (rows) { | |||
rows.forEach((row) => { | |||
// TODO: improvement typing when refactor table | |||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | |||
// @ts-expect-error | |||
multipleTableRef.value.toggleRowSelection(row, undefined) | |||
}) | |||
} else { | |||
multipleTableRef.value.clearSelection() | |||
} | |||
} | |||
const handleSelectionChange = (val) => { | |||
multipleSelection.value = val | |||
} | |||
const pageNum = ref(1); | |||
const pageSize = ref(10); | |||
const total = ref(0); | |||
const tableData = ref([]); | |||
const handleSizeChange = (val) => { | |||
pageSize.value = val; | |||
modelAllListFunc(pageNum.value, pageSize.value); | |||
}; | |||
const handleCurrentChange = (val) => { | |||
pageNum.value = val; | |||
modelAllListFunc(pageNum.value, pageSize.value); | |||
}; | |||
const modelAllListFunc = async (PageNum, PageSize) => { | |||
try { | |||
const res = await voiceMouldListApi(PageNum, 10000); | |||
const modelIds = await userVoiceIdListApi(props.cUserId); | |||
let idIndx = [] | |||
if(modelIds.data && modelIds.data.length > 0) { | |||
res.data.list.forEach((ele, idx) => { | |||
modelIds.data.forEach((item) => { | |||
if (ele.id === item) { | |||
idIndx.push(idx) | |||
} | |||
}) | |||
}) | |||
} | |||
tableData.value = res.data.list; | |||
total.value = res.data.total * 1; | |||
// 选中关联模版 | |||
if(idIndx.length) { | |||
setTimeout(()=> { | |||
let list = [] | |||
idIndx.forEach(d => { | |||
list.push(tableData.value[d]) | |||
}) | |||
toggleSelection(list) | |||
}, 500) | |||
} | |||
} catch (error) { | |||
console.log(error, "err"); | |||
} | |||
}; | |||
const addModel = async () => { | |||
console.log(multipleSelection.value) | |||
let mouldIds = [] | |||
multipleSelection.value.forEach(res => { | |||
mouldIds.push(res.id) | |||
}) | |||
const data = { | |||
voiceLanguageIdList: mouldIds, | |||
userId: props.cUserId | |||
} | |||
const res = await associatedUserVoicesApi(data); | |||
if(res.code === 200) { | |||
ElMessage.success((lanChange.value) == "zh-cn" ? "关联成功!" : 'Successfully associated!'); | |||
handleClose() | |||
} | |||
}; | |||
function handleClose() { | |||
emit("close"); | |||
} | |||
onMounted(() => { | |||
modelAllListFunc(1, 10); | |||
}); | |||
</script> |
@@ -0,0 +1,207 @@ | |||
<template> | |||
<div class="page justify-around"> | |||
<div class="addbtn"> | |||
<el-form :inline="true" :model="formInline" class="demo-form-inline"> | |||
<el-form-item :label="$t('rechargeList.phone')"> | |||
<el-input v-model="formInline.phone" :placeholder="$t('rechargeList.phonePlaceholder')" clearable /> | |||
</el-form-item> | |||
<el-form-item :label="$t('rechargeList.productName')"> | |||
<el-input v-model="formInline.productTitle" :placeholder="$t('rechargeList.productNamePlaceholder')" clearable /> | |||
</el-form-item> | |||
<el-form-item :label="$t('rechargeList.time')"> | |||
<el-date-picker | |||
v-model="formInline.time" | |||
type="datetimerange" | |||
start-placeholder="Start Date" | |||
end-placeholder="End Date" | |||
value-format="YYYY-MM-DD HH:mm:ss" | |||
:default-time="defaultTime" | |||
/> | |||
</el-form-item> | |||
<el-form-item> | |||
<el-button type="primary" @click="getListData()">{{ $t('rechargeList.search') }}</el-button> | |||
</el-form-item> | |||
</el-form> | |||
</div> | |||
<el-table | |||
:data="tableData" | |||
style="width: 100%; height: 90%" | |||
size="large" | |||
align="center" | |||
border | |||
> | |||
<el-table-column | |||
prop="orderNumber" | |||
:label="$t('rechargeList.orderNumber')" | |||
align="center" | |||
/> | |||
<el-table-column | |||
prop="productTitle" | |||
:label="$t('rechargeList.productName')" | |||
align="center" | |||
/> | |||
<el-table-column | |||
prop="payVendor" | |||
:label="$t('rechargeList.payVendor')" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
{{ getPayVendor(scope.row.payVendor) }} | |||
</template> | |||
</el-table-column> | |||
<el-table-column | |||
prop="orderPriceStr" | |||
:label="$t('rechargeList.orderPriceStr')" | |||
align="center" | |||
/> | |||
<el-table-column | |||
prop="phone" | |||
:label="$t('rechargeList.phone')" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
{{ scope.row.cuserInfo ? scope.row.cuserInfo.phone : '' }} | |||
</template> | |||
</el-table-column> | |||
<el-table-column | |||
prop="createDate" | |||
:label="$t('rechargeList.createDate')" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
{{ getDate(scope.row.createDate) }} | |||
</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 { rechargeListApi } from '@/apis/userManage.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 pageNum = ref(1); | |||
const pageSize = ref(10); | |||
const total = ref(0); | |||
const defaultTime = [ | |||
new Date(2000, 1, 1, 0, 0, 0), | |||
new Date(2000, 2, 1, 23, 59, 59), | |||
] // '12:00:00', '08:00:00' | |||
const getPayVendor = (val) => { | |||
return val === 2 ? "微信" : "支付宝"; | |||
}; | |||
const getDate = (val) => { | |||
return dayjs(val).format("YYYY-MM-DD HH:mm:ss"); | |||
}; | |||
const handleSizeChange = (val) => { | |||
pageSize.value = val; | |||
getListData(pageNum.value, pageSize.value); | |||
}; | |||
const handleCurrentChange = (val) => { | |||
pageNum.value = val; | |||
getListData(pageNum.value, pageSize.value); | |||
}; | |||
const formInline = ref({ | |||
phone: route.query.phone || '', | |||
productTitle: '', | |||
time: '' | |||
}) | |||
const getListData = async (PageNum, PageSize) => { | |||
try { | |||
let data = { | |||
PageNum: PageNum || 1, | |||
PageSize: PageSize || 10, | |||
phone: formInline.value.phone, | |||
projectType: 2, | |||
productTitle: formInline.value.productTitle, | |||
startDate: formInline.value.time ? formInline.value.time[0] : '', | |||
endDate: formInline.value.time ? formInline.value.time[1] : '', | |||
} | |||
const res = await rechargeListApi(data); | |||
tableData.value = res.data.list; | |||
total.value = res.data.total * 1; | |||
} catch (error) { | |||
console.log(error, "err"); | |||
} | |||
}; | |||
onMounted(() => { | |||
getListData(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> | |||
@@ -0,0 +1,264 @@ | |||
<template> | |||
<div class="page justify-around"> | |||
<div class="addbtn"> | |||
<el-form :inline="true" :model="formInline" class="demo-form-inline"> | |||
<el-form-item :label="$t('userList.phone')"> | |||
<el-input v-model="formInline.phone" :placeholder="$t('userList.phonePlaceholder')" clearable /> | |||
</el-form-item> | |||
<el-form-item> | |||
<el-button type="primary" @click="getListData()">{{ $t('userList.search') }}</el-button> | |||
</el-form-item> | |||
</el-form> | |||
</div> | |||
<el-table | |||
:data="tableData" | |||
style="width: 100%; height: 90%" | |||
size="large" | |||
align="center" | |||
border | |||
> | |||
<el-table-column | |||
prop="id" | |||
:label="$t('userList.id')" | |||
align="center" | |||
/> | |||
<el-table-column | |||
prop="phone" | |||
:label="$t('userList.phone')" | |||
align="center" | |||
/> | |||
<el-table-column | |||
prop="poins" | |||
:label="$t('userList.poins')" | |||
align="center" | |||
/> | |||
<el-table-column | |||
prop="createDate" | |||
:label="$t('userList.createDate')" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
{{ getDate(scope.row.createDate) }} | |||
</template> | |||
</el-table-column> | |||
<el-table-column | |||
fixed="right" | |||
:label="$t('keyMangage.operations')" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
<el-button link type="primary" size="small" @click="setStatus(scope.row)">{{ scope.row.status === 0 ? '封禁' : '恢复' }}</el-button> | |||
<el-button link type="primary" size="small" @click="showDetail(scope.row.id)">{{$t('userList.view')}}</el-button> | |||
<el-button link type="primary" size="small" @click="rechargeDetail(scope.row)">{{$t('userList.rechargeDetail')}}</el-button> | |||
<el-button link type="primary" size="small" @click="videoDetail(scope.row)"> {{$t('userList.videoDetail')}}</el-button> | |||
<el-button link type="primary" size="small" @click="personMould(scope.row.id)">{{$t('userList.personMould')}}</el-button> | |||
<el-button link type="primary" size="small" @click="personVoice(scope.row.id)">{{$t('userList.personVoice')}}</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> | |||
<el-dialog v-model="detailDialogVisible" v-if="detailDialogVisible" :title="$t('userList.viewDetail')" width="60%" :before-close="handleClose" > | |||
<el-form :model="form" label-width="120px"> | |||
<el-form-item :label="$t('userList.phone')"> | |||
<el-input v-model="form.phone" /> | |||
</el-form-item> | |||
<el-form-item label="Level"> | |||
<el-input v-model="form.level" /> | |||
</el-form-item> | |||
<el-form-item :label="$t('userList.poins')"> | |||
<el-input v-model="form.poins" /> | |||
</el-form-item> | |||
<el-form-item :label="$t('userList.createDate')"> | |||
<el-input v-model="form.createDate" /> | |||
</el-form-item> | |||
<!-- <el-form-item> | |||
<el-button>{{$t('userList.close')}}</el-button> | |||
</el-form-item> --> | |||
</el-form> | |||
</el-dialog> | |||
<el-dialog v-model="modelDialogVisible" v-if="modelDialogVisible" :title="$t('userList.personMould')" width="60%" :before-close="handleClose" > | |||
<model :cUserId="cUserId" @close="handleClose"></model> | |||
</el-dialog> | |||
<el-dialog v-model="voiceDialogVisible" v-if="voiceDialogVisible" :title="$t('userList.personVoice')" width="60%" :before-close="handleClose" > | |||
<voice :cUserId="cUserId" @close="handleClose"></voice> | |||
</el-dialog> | |||
</div> | |||
</template> | |||
<!-- videoType==1为竖,==2为横 --> | |||
<script setup> | |||
//#region 导入 | |||
import { userListApi, userListFindByIdApi, updateStatusApi } from '@/apis/userManage.js' | |||
import { useI18n } from "vue-i18n"; | |||
import dayjs from "dayjs"; | |||
import { useRoute, useRouter } from "vue-router"; | |||
import model from './personMould.vue' | |||
import voice from './personVoice.vue' | |||
const route = useRoute(); | |||
const router = useRouter(); | |||
const { locale } = useI18n(); | |||
const lanChange = ref(locale); | |||
const tableData = ref([]); | |||
const dialogVisible = ref(false); | |||
const rechargeDetail = (item) => { | |||
router.push({ | |||
path: "/rechargeList", | |||
query: { | |||
phone: item.phone | |||
}, | |||
}); | |||
}; | |||
const videoDetail = (item) => { | |||
router.push({ | |||
path: "/videoList", | |||
query: { | |||
phone: item.phone | |||
}, | |||
}); | |||
}; | |||
const pageNum = ref(1); | |||
const pageSize = ref(10); | |||
const total = ref(0); | |||
const getDate = (val) => { | |||
return dayjs(val).format("YYYY-MM-DD HH:mm:ss"); | |||
}; | |||
const handleSizeChange = (val) => { | |||
pageSize.value = val; | |||
getListData(pageNum.value, pageSize.value); | |||
}; | |||
const handleCurrentChange = (val) => { | |||
pageNum.value = val; | |||
getListData(pageNum.value, pageSize.value); | |||
}; | |||
const formInline = ref({ | |||
phone: '' | |||
}) | |||
const getListData = async (PageNum, PageSize) => { | |||
try { | |||
let data = { | |||
PageNum: PageNum || 1, | |||
PageSize: PageSize || 10, | |||
phone: formInline.value.phone | |||
} | |||
const res = await userListApi(data); | |||
console.log(res, "res"); | |||
tableData.value = res.data.list; | |||
total.value = res.data.total * 1; | |||
} catch (error) { | |||
console.log(error, "err"); | |||
} | |||
}; | |||
const form = ref({ | |||
name: '', | |||
phone: '' | |||
}) | |||
const detailDialogVisible = ref(false) | |||
function showDetail(id) { | |||
userListFindByIdApi(id).then(res => { | |||
detailDialogVisible.value = true | |||
res.data.createDate = getDate(res.data.createDate) | |||
form.value = res.data | |||
}) | |||
} | |||
function handleClose() { | |||
detailDialogVisible.value = false | |||
modelDialogVisible.value = false | |||
voiceDialogVisible.value = false | |||
} | |||
const modelDialogVisible = ref(false) | |||
const cUserId = ref('') | |||
function personMould(id) { | |||
modelDialogVisible.value = true | |||
cUserId.value = id | |||
} | |||
const voiceDialogVisible = ref(false) | |||
function personVoice(id) { | |||
voiceDialogVisible.value = true | |||
cUserId.value = id | |||
} | |||
// 状态 | |||
function setStatus(item) { | |||
updateStatusApi({id: item.id, status: item.status === 0 ? 1 : 0}).then(res => { | |||
if (res.code === 200) { | |||
ElMessage.success((lanChange.value) == "zh-cn" ? "操作成功!" : 'Operation successful!'); | |||
getListData(1, 10); | |||
} | |||
}) | |||
} | |||
onMounted(() => { | |||
getListData(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> | |||
@@ -0,0 +1,180 @@ | |||
<template> | |||
<div class="page justify-around"> | |||
<div class="addbtn"> | |||
<el-form :inline="true" :model="formInline" class="demo-form-inline"> | |||
<el-form-item :label="$t('userMouldList.phone')"> | |||
<el-input v-model="formInline.phone" :placeholder="$t('userMouldList.phonePlaceholder')" clearable /> | |||
</el-form-item> | |||
<el-form-item :label="$t('userMouldList.mouldSmId')"> | |||
<el-input v-model="formInline.mouldSmIdLike" :placeholder="$t('userMouldList.mouldSmIdPlaceholder')" clearable /> | |||
</el-form-item> | |||
<el-form-item> | |||
<el-button type="primary" @click="getListData()">{{$t('userMouldList.search')}}</el-button> | |||
</el-form-item> | |||
</el-form> | |||
</div> | |||
<el-table | |||
:data="tableData" | |||
style="width: 100%; height: 90%" | |||
size="large" | |||
align="center" | |||
border | |||
> | |||
<el-table-column | |||
prop="coverImg" | |||
:label="$t('userMouldList.coverImg')" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
<img :src="scope.row.coverImg" width="50" height="50" alt="" /> | |||
</template> | |||
</el-table-column> | |||
<el-table-column | |||
prop="mouldSmId" | |||
:label="$t('userMouldList.mouldSmId')" | |||
align="center" | |||
/> | |||
<el-table-column | |||
prop="wxCUserBasicInfoList" | |||
:label="$t('userMouldList.bindPhone')" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
{{ getListPhone(scope.row.wxCUserBasicInfoList) }} | |||
</template> | |||
</el-table-column> | |||
<el-table-column | |||
prop="createDate" | |||
:label="$t('userMouldList.createDate')" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
{{ getDate(scope.row.createDate) }} | |||
</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 { userMouldListApi } from '@/apis/userManage.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 pageNum = ref(1); | |||
const pageSize = ref(10); | |||
const total = ref(0); | |||
const getDate = (val) => { | |||
return dayjs(val).format("YYYY-MM-DD"); | |||
}; | |||
const getListPhone = (list) => { | |||
let phone = [] | |||
list && list.forEach(ele => { | |||
phone.push(ele.phone) | |||
}); | |||
return phone.join(',') | |||
} | |||
const handleSizeChange = (val) => { | |||
pageSize.value = val; | |||
getListData(pageNum.value, pageSize.value); | |||
}; | |||
const handleCurrentChange = (val) => { | |||
pageNum.value = val; | |||
getListData(pageNum.value, pageSize.value); | |||
}; | |||
const formInline = ref({ | |||
phone: '', | |||
mouldSmIdLike: '' | |||
}) | |||
const getListData = async (PageNum, PageSize) => { | |||
try { | |||
let data = { | |||
PageNum: PageNum || 1, | |||
PageSize: PageSize || 10, | |||
phone: formInline.value.phone, | |||
mouldSmIdLike: formInline.value.mouldSmIdLike | |||
} | |||
const res = await userMouldListApi(data); | |||
console.log(res, "res"); | |||
tableData.value = res.data.list; | |||
total.value = res.data.total * 1; | |||
} catch (error) { | |||
console.log(error, "err"); | |||
} | |||
}; | |||
onMounted(() => { | |||
getListData(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> | |||
@@ -0,0 +1,188 @@ | |||
<template> | |||
<div class="page justify-around"> | |||
<div class="addbtn"> | |||
<el-form :inline="true" :model="formInline" class="demo-form-inline"> | |||
<el-form-item :label="$t('userVoiceList.phone')"> | |||
<el-input v-model="formInline.phone" :placeholder="$t('userVoiceList.phonePlaceholder')" clearable /> | |||
</el-form-item> | |||
<el-form-item :label="$t('userVoiceList.mouldSmId')"> | |||
<el-input v-model="formInline.mouldSmIdLike" :placeholder="$t('userVoiceList.mouldSmIdPlaceholder')" clearable /> | |||
</el-form-item> | |||
<el-form-item> | |||
<el-button type="primary" @click="getListData()"> {{ $t('userVoiceList.search') }}</el-button> | |||
</el-form-item> | |||
</el-form> | |||
</div> | |||
<el-table | |||
:data="tableData" | |||
style="width: 100%; height: 90%" | |||
size="large" | |||
align="center" | |||
border | |||
> | |||
<el-table-column | |||
prop="name" | |||
:label="$t('userVoiceList.enName')" | |||
align="center" | |||
/> | |||
<el-table-column | |||
prop="chineseName" | |||
:label="$t('userVoiceList.chineseName')" | |||
align="center" | |||
/> | |||
<el-table-column | |||
prop="country" | |||
:label="$t('userVoiceList.country')" | |||
align="center" | |||
/> | |||
<el-table-column | |||
prop="language" | |||
:label="$t('userVoiceList.lang')" | |||
align="center" | |||
/> | |||
<el-table-column | |||
prop="wxCUserBasicInfoList" | |||
:label="$t('userVoiceList.bindPhone')" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
{{ getListPhone(scope.row.wxCUserBasicInfoList) }} | |||
</template> | |||
</el-table-column> | |||
<el-table-column | |||
prop="createDate" | |||
:label="$t('userVoiceList.createDate')" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
{{ getDate(scope.row.createDate) }} | |||
</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 { userVoiceListAPi } from '@/apis/userManage.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 pageNum = ref(1); | |||
const pageSize = ref(10); | |||
const total = ref(0); | |||
const getDate = (val) => { | |||
return dayjs(val).format("YYYY-MM-DD"); | |||
}; | |||
const getListPhone = (list) => { | |||
let phone = [] | |||
list && list.forEach(ele => { | |||
phone.push(ele.phone) | |||
}); | |||
return phone.join(',') | |||
} | |||
const handleSizeChange = (val) => { | |||
pageSize.value = val; | |||
getListData(pageNum.value, pageSize.value); | |||
}; | |||
const handleCurrentChange = (val) => { | |||
pageNum.value = val; | |||
getListData(pageNum.value, pageSize.value); | |||
}; | |||
const formInline = ref({ | |||
phone: '', | |||
mouldSmIdLike: '' | |||
}) | |||
const getListData = async (PageNum, PageSize) => { | |||
try { | |||
let data = { | |||
PageNum: PageNum || 1, | |||
PageSize: PageSize || 10, | |||
phone: formInline.value.phone, | |||
mouldSmIdLike: formInline.value.mouldSmIdLike | |||
} | |||
const res = await userVoiceListAPi(data); | |||
console.log(res, "res"); | |||
tableData.value = res.data.list; | |||
total.value = res.data.total * 1; | |||
} catch (error) { | |||
console.log(error, "err"); | |||
} | |||
}; | |||
onMounted(() => { | |||
getListData(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> |
@@ -0,0 +1,342 @@ | |||
<template> | |||
<div class="page justify-around"> | |||
<div class="addbtn"> | |||
<el-form :inline="true" :model="formInline" class="demo-form-inline"> | |||
<el-form-item :label="$t('videoList.phone')"> | |||
<el-input v-model="formInline.phone" :placeholder="$t('videoList.phonePlaceholder')" clearable /> | |||
</el-form-item> | |||
<el-form-item :label="$t('videoList.text')"> | |||
<el-input v-model="formInline.paperwork" :placeholder="$t('videoList.textPlaceholder')" clearable /> | |||
</el-form-item> | |||
<el-form-item :label="$t('videoList.type')"> | |||
<el-select | |||
v-model="formInline.videoType" | |||
:placeholder="$t('videoList.typePlaceholder')" | |||
clearable | |||
> | |||
<el-option :label="$t('videoList.all')" value="" /> | |||
<el-option :label="$t('videoList.portrait')" value="1" /> | |||
<el-option :label="$t('videoList.transversePlate')" value="2" /> | |||
</el-select> | |||
</el-form-item> | |||
<el-form-item :label="$t('videoList.status')"> | |||
<el-select | |||
v-model="formInline.isDel" | |||
:placeholder="$t('videoList.statusPlaceholder')" | |||
clearable | |||
> | |||
<el-option :label="$t('videoList.all')" value="" /> | |||
<el-option :label="$t('videoList.notDeleted')" value="0" /> | |||
<el-option :label="$t('videoList.deleted')" value="1" /> | |||
</el-select> | |||
</el-form-item> | |||
<el-form-item :label="$t('videoList.time')"> | |||
<el-date-picker | |||
v-model="formInline.time" | |||
type="datetimerange" | |||
start-placeholder="Start Date" | |||
end-placeholder="End Date" | |||
value-format="YYYY-MM-DD HH:mm:ss" | |||
:default-time="defaultTime" | |||
/> | |||
</el-form-item> | |||
<el-form-item> | |||
<el-button type="primary" @click="getListData()">{{ $t('videoList.search') }}</el-button> | |||
</el-form-item> | |||
</el-form> | |||
</div> | |||
<el-table | |||
:data="tableData" | |||
style="width: 100%; height: 90%" | |||
size="large" | |||
align="center" | |||
border | |||
> | |||
<el-table-column | |||
prop="videoType" | |||
:label="$t('videoList.type')" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
{{ getVideoType(scope.row.videoType) }} | |||
</template> | |||
</el-table-column> | |||
<el-table-column | |||
prop="paperwork" | |||
:label="$t('videoList.text')" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
{{ scope.row.paperwork.substring(0, 10) + '...' }} | |||
</template> | |||
</el-table-column> | |||
<el-table-column | |||
prop="isDel" | |||
:label="$t('videoList.status')" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
{{ getIsDel(scope.row.isDel) }} | |||
</template> | |||
</el-table-column> | |||
<el-table-column | |||
prop="title" | |||
:label="$t('videoList.title')" | |||
align="center" | |||
/> | |||
<el-table-column | |||
prop="coverImg" | |||
:label="$t('videoList.coverImg')" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
<img :src="scope.row.coverImg" width="50" height="50" alt="" /> | |||
</template> | |||
</el-table-column> | |||
<el-table-column | |||
prop="videoPlayUrl" | |||
:label="$t('videoList.videoPlayUrl')" | |||
align="center" | |||
/> | |||
<el-table-column | |||
prop="videoTime" | |||
:label="$t('videoList.videoTime')" | |||
align="center" | |||
> | |||
</el-table-column> | |||
<el-table-column | |||
prop="videoSize" | |||
:label="$t('videoList.videoSize')" | |||
align="center" | |||
/> | |||
<el-table-column | |||
prop="videoMsg" | |||
:label="$t('videoList.videoMsg')" | |||
align="center" | |||
/> | |||
<el-table-column | |||
prop="costPoints" | |||
:label="$t('videoList.costPoints')" | |||
align="center" | |||
/> | |||
<el-table-column | |||
prop="costPointsDetail" | |||
:label="$t('videoList.costPointsDetail')" | |||
align="center" | |||
/> | |||
<el-table-column | |||
prop="createDate" | |||
:label="$t('videoList.createDate')" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
{{ getDate(scope.row.createDate) }} | |||
</template> | |||
</el-table-column> | |||
<el-table-column | |||
fixed="right" | |||
:label="$t('keyMangage.operations')" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
<el-button link type="primary" size="small" @click="showDetail(scope.row.id)">{{$t('videoList.view')}}</el-button> | |||
<el-button v-if="scope.row.isDel === 0" link type="primary" size="small" @click="confirmDel(scope.row.id)">{{$t('videoList.del')}}</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> | |||
<el-dialog v-model="dialogVisible" v-if="dialogVisible" :title="`${$t('videoList.videoDetail')}:`" width="40%"> | |||
<el-form :model="form" label-width="120px"> | |||
<el-form-item :label="$t('videoList.name')"> | |||
<el-input v-model="form.title" /> | |||
</el-form-item> | |||
<el-form-item :label="$t('videoList.videType')"> | |||
<el-radio-group v-model="form.videoType"> | |||
<el-radio :label="1">{{$t('videoList.portrait')}}</el-radio> | |||
<el-radio :label="2">{{$t('videoList.transversePlate')}}</el-radio> | |||
</el-radio-group> | |||
</el-form-item> | |||
<el-form-item :label="$t('videoList.text')"> | |||
<el-input v-model="form.paperwork" type="textarea" /> | |||
</el-form-item> | |||
<el-form-item :label="$t('videoList.coverImg')"> | |||
<img :src="form.coverImg" alt="" :style="{ width: form.videoType === 1 ? '50%' : '100%'}"> | |||
</el-form-item> | |||
<el-form-item :label="$t('videoList.videoPlayUrl')"> | |||
<el-input v-model="form.videoPlayUrl" /> | |||
<video :src="form.videoPlayUrl" controls :style="{ width: form.videoType === 1 ? '50%' : '100%'}"></video> | |||
</el-form-item> | |||
<el-form-item :label="$t('videoList.videoTime')"> | |||
<el-input v-model="form.videoTime" /> | |||
</el-form-item> | |||
<el-form-item :label="$t('videoList.createDate')"> | |||
<el-input v-model="form.createDate" /> | |||
</el-form-item> | |||
<el-form-item :label="$t('videoList.costPoints')"> | |||
<el-input v-model="form.costPoints" /> | |||
</el-form-item> | |||
<el-form-item :label="$t('videoList.costPointsDetail')"> | |||
<el-input v-model="form.costPointsDetail" /> | |||
</el-form-item> | |||
<el-form-item> | |||
<el-button @click="dialogVisible = false">{{ $t('videoList.close') }}</el-button> | |||
</el-form-item> | |||
</el-form> | |||
</el-dialog> | |||
</div> | |||
</template> | |||
<script setup> | |||
//#region 导入 | |||
import { videoListApi, videoListFindByIdApi, videoListDelApi } from '@/apis/userManage.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 pageNum = ref(1); | |||
const pageSize = ref(10); | |||
const total = ref(0); | |||
const defaultTime = [ | |||
new Date(2000, 1, 1, 0, 0, 0), | |||
new Date(2000, 2, 1, 23, 59, 59), | |||
] // '12:00:00', '08:00:00' | |||
const getVideoType = (val) => { | |||
return val === 1 ? "竖版" : "横版"; | |||
}; | |||
const getIsDel = (val) => { | |||
return val === 1 ? "已删除" : "未删除"; | |||
}; | |||
const getDate = (val) => { | |||
return dayjs(val).format("YYYY-MM-DD HH:mm:ss"); | |||
}; | |||
const handleSizeChange = (val) => { | |||
pageSize.value = val; | |||
getListData(pageNum.value, pageSize.value); | |||
}; | |||
const handleCurrentChange = (val) => { | |||
pageNum.value = val; | |||
getListData(pageNum.value, pageSize.value); | |||
}; | |||
const formInline = ref({ | |||
phone: route.query.phone || '', | |||
productTitle: '', | |||
time: '' | |||
}) | |||
const getListData = async (PageNum, PageSize) => { | |||
try { | |||
let data = { | |||
PageNum: PageNum || 1, | |||
PageSize: PageSize || 10, | |||
phone: formInline.value.phone, | |||
projectType: 2, | |||
productTitle: formInline.value.productTitle, | |||
startDate: formInline.value.time ? formInline.value.time[0] : '', | |||
endDate: formInline.value.time ? formInline.value.time[1] : '', | |||
id: route.query.id || '', | |||
isDel: formInline.value.isDel, | |||
videoType: formInline.value.videoType, | |||
paperwork: formInline.value.paperwork | |||
} | |||
const res = await videoListApi(data); | |||
tableData.value = res.data.list; | |||
total.value = res.data.total * 1; | |||
} catch (error) { | |||
console.log(error, "err"); | |||
} | |||
}; | |||
// 查看详情 | |||
const dialogVisible = ref(false) | |||
const form = ref({}) | |||
function showDetail(id) { | |||
videoListFindByIdApi(id).then(res => { | |||
if(res.code === 200){ | |||
dialogVisible.value = true | |||
form.value = res.data | |||
} | |||
}) | |||
} | |||
function confirmDel(id) { | |||
ElMessageBox.confirm('你确定要删除吗?').then(() => { | |||
videoListDelApi(id).then(res => { | |||
if (res.code == 200) { | |||
ElMessage.success("删除成功!"); | |||
getListData(1, 10) | |||
} | |||
}) | |||
done() | |||
}).catch(() => { | |||
// catch error | |||
}) | |||
} | |||
onMounted(() => { | |||
getListData(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> | |||
@@ -0,0 +1,87 @@ | |||
<template> | |||
<div> | |||
<el-checkbox-group v-model="checkboxGroup" size="small" class="checkbox"> | |||
<el-checkbox v-for="(item, index) in tableData" :key="index" :label="item.id" border> | |||
<img :src="item.coverImg" width="50" /> | |||
<p>{{ item.title }}</p> | |||
</el-checkbox> | |||
</el-checkbox-group> | |||
<div style="margin-top: 20px"> | |||
<el-button @click="handleClose" | |||
>{{ $t('personMould.cancel') }}</el-button | |||
> | |||
<el-button type="primary" @click="addModel()">{{ $t('personMould.confirm') }}</el-button> | |||
</div> | |||
</div> | |||
</template> | |||
<script setup> | |||
import { ref } from 'vue' | |||
import { voiceMouldListApi, userVoiceIdListApi, associatedUserVoicesApi } from '@/apis/userManage.js' | |||
import dayjs from "dayjs"; | |||
const emit = defineEmits(["close"]); | |||
const props = defineProps({ | |||
serviceId: { | |||
required: true, | |||
} | |||
}); | |||
const getDate = (val) => { | |||
return dayjs(val).format("YYYY-MM-DD"); | |||
}; | |||
const checkboxGroup = ref([]) | |||
const total = ref(0); | |||
const tableData = ref([]); | |||
const modelAllListFunc = async () => { | |||
try { | |||
const res = await voiceMouldListApi(1, 10000); | |||
const modelIds = await userVoiceIdListApi(props.serviceId); | |||
tableData.value = res.data.list; | |||
total.value = res.data.total * 1; | |||
setTimeout(()=> { | |||
if(modelIds.data && modelIds.data.length > 0) { | |||
modelIds.data.forEach((item) => { | |||
checkboxGroup.value.push(item) | |||
}) | |||
} | |||
}, 500) | |||
} catch (error) { | |||
console.log(error, "err"); | |||
} | |||
}; | |||
const addModel = async () => { | |||
const data = { | |||
mouldIds: checkboxGroup.value, | |||
cUserId: props.serviceId | |||
} | |||
const res = await associatedUserVoicesApi(data); | |||
if(res.code === 200) { | |||
ElMessage.success("关联成功!"); | |||
handleClose() | |||
} | |||
}; | |||
function handleClose() { | |||
emit("close"); | |||
} | |||
onMounted(() => { | |||
modelAllListFunc(1, 10); | |||
}); | |||
</script> | |||
<style lang="scss" scoped> | |||
.checkbox { | |||
max-height: 500px; | |||
overflow: auto; | |||
:deep .el-checkbox.el-checkbox--small { | |||
width: 110px; | |||
height:110px; | |||
margin-bottom: 10px; | |||
} | |||
} | |||
</style> |
@@ -0,0 +1,175 @@ | |||
<template> | |||
<div class="page justify-around"> | |||
<el-alert :title="`${$t('video.time')}:${crrentVideoToal} 秒`" type="success" :closable="false" /> | |||
<el-table | |||
:data="tableData" | |||
style="width: 100%; height: 90%" | |||
size="large" | |||
align="center" | |||
border | |||
> | |||
<el-table-column | |||
prop="serviceId" | |||
:label="$t('video.code')" | |||
align="center"> | |||
<template #default="scope"> | |||
<el-button type="primary" text @click="getDetail(scope.row.serviceId)">{{ scope.row.serviceId }}</el-button> | |||
</template> | |||
</el-table-column> | |||
<el-table-column | |||
prop="videoTime" | |||
:label="$t('video.videoTime')" | |||
align="center" | |||
/> | |||
<el-table-column | |||
prop="videoUrl" | |||
:label="$t('video.videoUrl')" | |||
align="center" | |||
/> | |||
<el-table-column | |||
prop="createTime" | |||
:label="$t('video.createTime')" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
{{ getDate(scope.row.createTime) }} | |||
</template> | |||
</el-table-column> | |||
<el-table-column | |||
fixed="right" | |||
:label="$t('keyMangage.operations')" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
<el-button link type="primary" size="small" @click="showDetail(scope.row.userMouldVideoId)">{{ $t('keyMangage.detail') }}</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 { videoListApi,currentVideoToalApi } from '@/apis/home.js' | |||
import { useI18n } from "vue-i18n"; | |||
import dayjs from "dayjs"; | |||
import { useRoute, useRouter } from "vue-router"; | |||
const route = useRoute(); | |||
const router = useRouter(); | |||
const tableData = ref([]); | |||
const pageNum = ref(1); | |||
const pageSize = ref(10); | |||
const total = ref(0); | |||
const getDate = (val) => { | |||
return dayjs(Number(val)).format("YYYY-MM-DD HH:mm:ss"); | |||
}; | |||
// 跳转视频列表 | |||
const showDetail = (id) => { | |||
router.push({ | |||
path: "/videoList", | |||
query: { | |||
id, | |||
}, | |||
}); | |||
}; | |||
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 videoListApi(PageNum, PageSize); | |||
console.log(res, "res"); | |||
tableData.value = res.data.list; | |||
total.value = res.data.total * 1; | |||
} catch (error) { | |||
console.log(error, "err"); | |||
} | |||
}; | |||
//查看详情 | |||
function getDetail(id) { | |||
router.push({ | |||
path: "/apiManage", | |||
query: { | |||
id, | |||
}, | |||
}); | |||
} | |||
const crrentVideoToal = ref('') | |||
function getCrrentVideoToal() { | |||
currentVideoToalApi().then(res => { | |||
crrentVideoToal.value = res.data | |||
}) | |||
} | |||
onMounted(() => { | |||
getCrrentVideoToal() | |||
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> | |||
@@ -35,26 +35,31 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => { | |||
`, | |||
}, | |||
}, | |||
postcss: { | |||
plugins: [ | |||
postCssPxToRem({ | |||
rootValue: 192, // 1rem 的大小 | |||
propList: ['*'], // 需要转换的属性,*(全部转换) | |||
unitPrecision: 6 // 转换精度,保留的小数位数 | |||
}) | |||
] | |||
} | |||
// postcss: { | |||
// plugins: [ | |||
// postCssPxToRem({ | |||
// rootValue: 192, // 1rem 的大小 | |||
// propList: ['*'], // 需要转换的属性,*(全部转换) | |||
// unitPrecision: 6 // 转换精度,保留的小数位数 | |||
// }) | |||
// ] | |||
// } | |||
}, | |||
server: { | |||
host: "0.0.0.0", | |||
port: Number(env.VITE_APP_PORT), | |||
open: true, // 运行是否自动打开浏览器 | |||
// "/api": { | |||
// target: env.VITE_APP_BASE_API, // 线上接口地址 | |||
// changeOrigin: true, | |||
// rewrite: (path) => path.replace(/^\/api/, ""), | |||
// }, | |||
proxy: { | |||
// 反向代理解决跨域 | |||
"/api": { | |||
"/A": { | |||
target: env.VITE_APP_BASE_API, // 线上接口地址 | |||
changeOrigin: true, | |||
rewrite: (path) => path.replace(/^\/api/, ""), | |||
rewrite: (path) => path.replace(/^\/A/, ""), | |||
}, | |||
}, | |||
}, | |||