北斗启航科技教育平台管理系统
30
.gitignore
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
dist-ssr
|
||||
coverage
|
||||
*.local
|
||||
|
||||
/cypress/videos/
|
||||
/cypress/screenshots/
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
*.tsbuildinfo
|
||||
29
README.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# account-manager
|
||||
|
||||
This template should help get you started developing with Vue 3 in Vite.
|
||||
|
||||
## Recommended IDE Setup
|
||||
|
||||
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
|
||||
|
||||
## Customize configuration
|
||||
|
||||
See [Vite Configuration Reference](https://vitejs.dev/config/).
|
||||
|
||||
## Project Setup
|
||||
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
|
||||
### Compile and Hot-Reload for Development
|
||||
|
||||
```sh
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Compile and Minify for Production
|
||||
|
||||
```sh
|
||||
npm run build
|
||||
```
|
||||
49
index.html
Normal file
@@ -0,0 +1,49 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="w-h-full">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>北斗启航科技教育平台管理系统</title>
|
||||
<style>
|
||||
/* 当屏幕宽度大于或等于3000px时 */
|
||||
@media (min-width: 3000px) {
|
||||
html {
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 当屏幕宽度在1920px到2999px之间时 */
|
||||
@media (min-width: 1920px) and (max-width: 2999px) {
|
||||
html {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 当屏幕宽度在750px到1919px之间时 */
|
||||
@media (min-width: 750px) and (max-width: 1919px) {
|
||||
html {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 当屏幕宽度在600px到749px之间时 */
|
||||
@media (min-width: 600px) and (max-width: 749px) {
|
||||
html {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 当屏幕宽度小于600px时 */
|
||||
@media (max-width: 599px) {
|
||||
html {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="w-h-full">
|
||||
<div id="app" class="w-h-full text-white"></div>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
8
jsconfig.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
47
package.json
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"name": "account-manager",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --port=7012",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview --port=7012"
|
||||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
"axios": "^1.7.7",
|
||||
"core-js": "^3.39.0",
|
||||
"crypto-js": "^4.2.0",
|
||||
"echarts": "^5.5.1",
|
||||
"element-plus": "^2.8.8",
|
||||
"file-saver": "^2.0.5",
|
||||
"fingerprintjs2": "^2.1.4",
|
||||
"jsencrypt": "^3.3.2",
|
||||
"moment": "^2.30.1",
|
||||
"node-xlsx": "^0.24.0",
|
||||
"pinia": "^2.2.6",
|
||||
"pinia-plugin-persist": "^1.0.0",
|
||||
"terser": "^5.36.0",
|
||||
"vue": "^3.5.13",
|
||||
"vue-echarts": "^7.0.3",
|
||||
"vue-quill-editor": "^3.0.6",
|
||||
"vue-router": "^4.5.0",
|
||||
"vue-vercode": "^1.0.6",
|
||||
"vue3-slide-verify": "^1.1.5",
|
||||
"watermark-dom": "^2.3.0",
|
||||
"xlsx": "^0.18.5",
|
||||
"zipson": "^0.2.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-legacy": "^5.4.3",
|
||||
"@vitejs/plugin-vue": "^5.2.0",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"postcss": "^8.4.49",
|
||||
"tailwindcss": "^3.4.15",
|
||||
"unplugin-auto-import": "^0.18.5",
|
||||
"unplugin-vue-components": "^0.27.4",
|
||||
"vite": "^5.4.11",
|
||||
"vite-plugin-components": "^0.13.3"
|
||||
}
|
||||
}
|
||||
6
postcss.config.js
Normal file
@@ -0,0 +1,6 @@
|
||||
export default {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {}
|
||||
}
|
||||
}
|
||||
BIN
public/favicon.ico
Normal file
|
After Width: | Height: | Size: 72 KiB |
9
src/App.vue
Normal file
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<RouterView />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { RouterView } from "vue-router";
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
130
src/api/index.js
Normal file
@@ -0,0 +1,130 @@
|
||||
import axios from "axios";
|
||||
import $url from "./url";
|
||||
import router from "../router";
|
||||
import { encrypt } from "../utils/aes";
|
||||
|
||||
// 添加请求拦截器
|
||||
axios.interceptors.request.use(function (config) {
|
||||
// 在发送请求之前做些什么
|
||||
if (localStorage.access_token && localStorage.access_token !== "" && localStorage.access_token !== null && localStorage.access_token !== undefined && localStorage.access_token !== NaN) {
|
||||
if (config.headers) {
|
||||
config.headers.authorization = localStorage.access_token;
|
||||
}
|
||||
}
|
||||
return config;
|
||||
}, function (error) {
|
||||
// 对请求错误做些什么
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
// 转到登录页面
|
||||
const toLogin = () => {
|
||||
// localStorage.clear();
|
||||
router.push({ path: '/mlogin' });
|
||||
};
|
||||
|
||||
// 添加响应拦截器
|
||||
let result = true;
|
||||
axios.interceptors.response.use(function (response) {
|
||||
// 2xx 范围内的状态码都会触发该函数。
|
||||
// 对响应数据做点什么
|
||||
if (response.data.code === 200) {
|
||||
if ("access_token" in response.data) {
|
||||
localStorage.setItem("access_token", response.data.access_token);
|
||||
}
|
||||
if ("refresh_token" in response.data) {
|
||||
localStorage.setItem("refresh_token", response.data.refresh_token);
|
||||
}
|
||||
if ("data" in response.data) {
|
||||
localStorage.setItem("data", response.data.data);
|
||||
}
|
||||
}
|
||||
// if (response.data.code === 404) {
|
||||
// localStorage.clear();
|
||||
// //转到404页面
|
||||
// router.push({ path: '/404page' });
|
||||
// }
|
||||
// if (response.data.code === 402) {
|
||||
// toLogin();
|
||||
// }
|
||||
if (response.data.code === 401 && result) {
|
||||
result = false;
|
||||
setTimeout(() => {
|
||||
result = true;
|
||||
}, 1000);
|
||||
let getCode = window.location.href.indexOf('?');
|
||||
if (getCode != '-1') {
|
||||
let code = window.location.href.substring(getCode + 1);
|
||||
const data = {
|
||||
code: code,
|
||||
type: encrypt('code')
|
||||
};
|
||||
axios.post($url.getToken, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
localStorage.setItem("data", res.data.data);
|
||||
localStorage.setItem("access_token", res.data.access_token);
|
||||
localStorage.setItem("refresh_token", res.data.refresh_token);
|
||||
window.location.href = res.data.redirect;
|
||||
} else {
|
||||
toLogin();
|
||||
}
|
||||
});
|
||||
} else if(localStorage.loginCode && localStorage.loginCode !== "" && localStorage.loginCode !== null && localStorage.loginCode !== undefined && localStorage.loginCode !== NaN) {
|
||||
const data = {
|
||||
code: localStorage.loginCode,
|
||||
type: encrypt('code')
|
||||
};
|
||||
axios.post($url.getToken, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
localStorage.setItem("data", res.data.data);
|
||||
localStorage.setItem("access_token", res.data.access_token);
|
||||
localStorage.setItem("refresh_token", res.data.refresh_token);
|
||||
localStorage.removeItem('loginCode');
|
||||
window.location.href = res.data.redirect;
|
||||
} else {
|
||||
toLogin();
|
||||
}
|
||||
});
|
||||
} else if (localStorage.refresh_token && localStorage.refresh_token !== "" && localStorage.refresh_token !== null && localStorage.refresh_token !== undefined && localStorage.refresh_token !== NaN) {
|
||||
const data = {
|
||||
code: localStorage.refresh_token,
|
||||
type: localStorage.data
|
||||
};
|
||||
axios.post($url.getToken, data).then((res) => {
|
||||
console.log(res);
|
||||
if (res.data.code === 200) {
|
||||
localStorage.setItem("data", res.data.data);
|
||||
localStorage.setItem("access_token", res.data.access_token);
|
||||
localStorage.setItem("refresh_token", res.data.refresh_token);
|
||||
window.location.reload();
|
||||
} else {
|
||||
toLogin();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
toLogin();
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}, function (error) {
|
||||
// 超出 2xx 范围的状态码都会触发该函数。
|
||||
// 对响应错误做点什么
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
export default {
|
||||
get(url, query = {}) {
|
||||
return axios.get(url, {
|
||||
params: query
|
||||
});
|
||||
},
|
||||
post(url, body) {
|
||||
return axios.post(url, body);
|
||||
},
|
||||
put(url, body) {
|
||||
return axios.put(url, body);
|
||||
},
|
||||
del(url) {
|
||||
return axios.delete(url);
|
||||
},
|
||||
}
|
||||
163
src/api/url.js
Normal file
@@ -0,0 +1,163 @@
|
||||
export default {
|
||||
// 退出登录
|
||||
unLogin: "/authentication/unLogin",
|
||||
// 获取登录状态
|
||||
loginStatus: "/authentication/loginStatus",
|
||||
// 登录请求接口
|
||||
mlogin: "/authentication/mlogin",
|
||||
// 用于获取token
|
||||
getToken: "/authentication/getToken",
|
||||
// 用于验证token
|
||||
verify: "/authentication/verify",
|
||||
// 获取用户基本信息
|
||||
getUser: "/authentication/getUser",
|
||||
// 修改用户基本信息
|
||||
editUser: "/authentication/editUser",
|
||||
// 修改密码
|
||||
changePassword: "/authentication/changePassword",
|
||||
|
||||
// 获取资源
|
||||
main: "/accountManager/main",
|
||||
home: "/accountManager/main/home",
|
||||
bside: "/accountManager/main/bside",
|
||||
cside: "/accountManager/main/cside",
|
||||
contest: "/accountManager/main/contest",
|
||||
manager: "/accountManager/main/manager",
|
||||
system: "/accountManager/main/system",
|
||||
|
||||
// 注册北斗卡
|
||||
addBdCard: "/accountManager/addBdCard",
|
||||
// 查看北斗卡
|
||||
showBdCard: "/accountManager/showBdCard",
|
||||
// 编辑北斗卡
|
||||
editBdCard: "/accountManager/editBdCard",
|
||||
// 删除北斗卡
|
||||
deleteBdCard: "/accountManager/deleteBdCard",
|
||||
|
||||
// 查看绑定记录
|
||||
showBindRecord: "/accountManager/showBindRecord",
|
||||
// 删除绑定记录
|
||||
deleteBindRecord: "/accountManager/deleteBindRecord",
|
||||
|
||||
// 注册公司业务
|
||||
addBusiness: "/accountManager/addBusiness",
|
||||
// 查看公司业务
|
||||
showBusiness: "/accountManager/showBusiness",
|
||||
// 远程搜索公司业务
|
||||
SearchBusiness: "/accountManager/SearchBusiness",
|
||||
// 编辑公司业务
|
||||
editBusiness: "/accountManager/editBusiness",
|
||||
// 删除公司业务
|
||||
deleteBusiness: "/accountManager/deleteBusiness",
|
||||
|
||||
// 注册B端用户
|
||||
addBSide: "/accountManager/addBSide",
|
||||
// 查看B端用户
|
||||
showBSide: "/accountManager/showBSide",
|
||||
// 编辑B端用户
|
||||
editBSide: "/accountManager/editBSide",
|
||||
// 删除B端用户
|
||||
deleteBSide: "/accountManager/deleteBSide",
|
||||
|
||||
// 查看C端用户
|
||||
showCSide: "/accountManager/showCSide",
|
||||
// 编辑C端用户
|
||||
editCSide: "/accountManager/editCSide",
|
||||
// 删除C端用户
|
||||
deleteCSide: "/accountManager/deleteCSide",
|
||||
|
||||
// 注册管理系统用户
|
||||
addInsiders: "/accountManager/addInsiders",
|
||||
// 查看管理系统用户
|
||||
showInsiders: "/accountManager/showInsiders",
|
||||
// 编辑管理系统用户
|
||||
editInsiders: "/accountManager/editInsiders",
|
||||
// 删除管理系统用户
|
||||
deleteInsiders: "/accountManager/deleteInsiders",
|
||||
|
||||
// 注册B端用户单位
|
||||
addOrganization: "/accountManager/addOrganization",
|
||||
// 查看B端用户单位
|
||||
showOrganization: "/accountManager/showOrganization",
|
||||
// 远程搜索B端用户单位
|
||||
SearchOrganization: "/accountManager/SearchOrganization",
|
||||
// 编辑B端用户单位
|
||||
editOrganization: "/accountManager/editOrganization",
|
||||
// 删除B端用户单位
|
||||
deleteOrganization: "/accountManager/deleteOrganization",
|
||||
|
||||
// 查看监控记录
|
||||
showMonitoring: "/accountManager/showMonitoring",
|
||||
// 删除监控记录
|
||||
deleteMonitoring: "/accountManager/deleteMonitoring",
|
||||
|
||||
// 管理系统检索竞赛 uid
|
||||
searchContestUid: "/accountManager/searchContestUid",
|
||||
// 管理系统创建竞赛信息
|
||||
addContest: "/accountManager/addContest",
|
||||
// 管理系统查看竞赛信息
|
||||
showContest: "/accountManager/showContest",
|
||||
// 管理系统编辑竞赛信息
|
||||
editContest: "/accountManager/editContest",
|
||||
// 管理系统删除竞赛信息
|
||||
delContest: "/accountManager/delContest",
|
||||
|
||||
// 管理系统导入选择题
|
||||
importChoiceTopic: "/accountManager/importChoiceTopic",
|
||||
// 管理系统创建选择题
|
||||
addChoiceTopic: "/accountManager/addChoiceTopic",
|
||||
// 管理系统查看选择题
|
||||
showChoiceTopic: "/accountManager/showChoiceTopic",
|
||||
// 管理系统编辑选择题
|
||||
editChoiceTopic: "/accountManager/editChoiceTopic",
|
||||
// 管理系统删除选择题
|
||||
delChoiceTopic: "/accountManager/delChoiceTopic",
|
||||
|
||||
// 管理系统导入竞赛账号信息
|
||||
importAccount: "/accountManager/importAccount",
|
||||
// 管理系统创建竞赛账号信息
|
||||
addAccount: "/accountManager/addAccount",
|
||||
// 管理系统查看竞赛账号信息
|
||||
showAccount: "/accountManager/showAccount",
|
||||
// 管理系统编辑竞赛账号信息
|
||||
editAccount: "/accountManager/editAccount",
|
||||
// 管理系统删除竞赛账号信息
|
||||
delAccount: "/accountManager/delAccount",
|
||||
|
||||
// 管理系统重置竞赛账号密码
|
||||
resetAccount: "/accountManager/resetAccount",
|
||||
|
||||
// 管理系统查看账号成绩排名
|
||||
showExamination: "/accountManager/showExamination",
|
||||
// 管理系统编辑账号成绩排名
|
||||
editExamination: "/accountManager/editExamination",
|
||||
// 管理系统删除账号成绩排名
|
||||
delExamination: "/accountManager/delExamination",
|
||||
// 管理系统导出账号成绩排名
|
||||
downloadExamination: "/accountManager/downloadExamination",
|
||||
|
||||
// 注册SN号
|
||||
addSN: "/accountManager/addSN",
|
||||
// 查看SN号
|
||||
showSN: "/accountManager/showSN",
|
||||
// 编辑SN号
|
||||
editSN: "/accountManager/editSN",
|
||||
// 删除SN号
|
||||
deleteSN: "/accountManager/deleteSN",
|
||||
|
||||
// 查看SN号绑定记录
|
||||
showBindSNRecord: "/accountManager/showBindSNRecord",
|
||||
// 删除SN号绑定记录
|
||||
deleteBindSNRecord: "/accountManager/deleteBindSNRecord",
|
||||
|
||||
// 搜索可分配的SN号
|
||||
searchAllocationSN: "/accountManager/searchAllocationSN",
|
||||
// 搜索可分配的单位用户
|
||||
searchAllocationUser: "/accountManager/searchAllocationUser",
|
||||
// B端分配SN号
|
||||
allocationSN: "/accountManager/allocationSN",
|
||||
// 查看B端SN号分配记录
|
||||
showAllocationSNRecord: "/accountManager/showAllocationSNRecord",
|
||||
// 删除B端SN号分配记录
|
||||
deleteAllocationSNRecord: "/accountManager/deleteAllocationSNRecord",
|
||||
}
|
||||
BIN
src/assets/favicon.ico
Normal file
|
After Width: | Height: | Size: 72 KiB |
BIN
src/assets/img/BDThemeLesson.jpg
Normal file
|
After Width: | Height: | Size: 58 KiB |
BIN
src/assets/img/comprehensivePracticalActivities.jpg
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
src/assets/img/correctExample.png
Normal file
|
After Width: | Height: | Size: 843 B |
BIN
src/assets/img/ephemeris_search.jpg
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
src/assets/img/errorsExample.png
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
src/assets/img/interferenceSimulation.png
Normal file
|
After Width: | Height: | Size: 4.7 MiB |
BIN
src/assets/img/mapTheCampus.jpg
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
src/assets/img/nmea0183-thumbnail.jpg
Normal file
|
After Width: | Height: | Size: 45 KiB |
BIN
src/assets/img/tdt-thumbnail.jpg
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
src/assets/img/trajectory.jpg
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
BIN
src/assets/logo.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
1
src/assets/logo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg>
|
||||
|
After Width: | Height: | Size: 276 B |
9
src/assets/main.css
Normal file
@@ -0,0 +1,9 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer components {
|
||||
.w-h-full {
|
||||
@apply w-full h-full m-0 p-0 overflow-hidden;
|
||||
}
|
||||
}
|
||||
BIN
src/assets/qrcode.jpg
Normal file
|
After Width: | Height: | Size: 39 KiB |
155
src/components/addNewData/SNForm/SNForm.vue
Normal file
@@ -0,0 +1,155 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="resetCheckForm"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ title }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<FormTools @showTools="showTools" :dialogObj="SNActive" />
|
||||
<SingleAdd ref="singleAddRef" v-if="dialogSingleVisible" @addSN="addSN" />
|
||||
<MultipleAdd
|
||||
ref="multipleAddRef"
|
||||
v-if="dialogMultipleVisible"
|
||||
:checkNeed="false"
|
||||
@addSN="addSN"
|
||||
/>
|
||||
<ExcleAdd ref="excleAddRef" v-if="dialogExcleVisible" @addSN="addSN" />
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm"> 取消 </el-button>
|
||||
<el-button style="font-weight: bold" type="primary" @click="confirm">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import FormTools from "../../operate/formTools.vue";
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
import MultipleAdd from "./multipleAdd.vue";
|
||||
import ExcleAdd from "./excleAdd.vue";
|
||||
|
||||
import SNActiveStore from "../../../stores/SN";
|
||||
|
||||
import $http from "../../../api/index";
|
||||
import $url from "../../../api/url";
|
||||
|
||||
import { encrypt } from "../../../utils/aes";
|
||||
|
||||
const SNActive = SNActiveStore();
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const singleAddRef = ref(null);
|
||||
const multipleAddRef = ref(null);
|
||||
const excleAddRef = ref(null);
|
||||
const dialogSingleVisible = ref(true);
|
||||
const dialogMultipleVisible = ref(false);
|
||||
const dialogExcleVisible = ref(false);
|
||||
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["reloadData"]);
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "single":
|
||||
dialogSingleVisible.value = true;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = false;
|
||||
SNActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
SNActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
SNActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "multiple":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = true;
|
||||
dialogExcleVisible.value = false;
|
||||
SNActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
SNActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
SNActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "excle":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = true;
|
||||
SNActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
SNActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
SNActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.resetCheckForm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.resetCheckForm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.resetCheckForm();
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.confirm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.confirm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.confirm();
|
||||
}
|
||||
};
|
||||
|
||||
const addSN = (requestMsg) => {
|
||||
requestMsg.forEach((element) => {
|
||||
element.sn_number = encrypt(String(element.sn_number));
|
||||
});
|
||||
const data = { requestMsg };
|
||||
$http.post($url.addSN, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
resetCheckForm();
|
||||
ElMessage({
|
||||
message: "新增SN号成功!",
|
||||
type: "success",
|
||||
});
|
||||
emit("reloadData");
|
||||
} else {
|
||||
ElMessage.error("新增SN号失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ dialogVisible });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
82
src/components/addNewData/SNForm/excleAdd.vue
Normal file
@@ -0,0 +1,82 @@
|
||||
<template>
|
||||
<UploadFile
|
||||
ref="uploadFileRef"
|
||||
:options="options"
|
||||
:relatedRules="relatedRules"
|
||||
:relatedOptions="relatedOptions"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import UploadFile from "../../operate/uploadFile.vue";
|
||||
|
||||
const uploadFileRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const options = {
|
||||
limit: 1,
|
||||
accept: ".xlsx",
|
||||
action: "",
|
||||
multiple: false,
|
||||
listType: "text",
|
||||
autoUpload: false,
|
||||
};
|
||||
|
||||
const relatedRules = {
|
||||
sn_number: {
|
||||
value: "",
|
||||
label: "SN号",
|
||||
}
|
||||
};
|
||||
|
||||
const relatedOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "SN号",
|
||||
disabled: false,
|
||||
}
|
||||
];
|
||||
|
||||
const emit = defineEmits(["addSN"]);
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!uploadFileRef) return;
|
||||
uploadFileRef.value.handleExceed();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!uploadFileRef) return;
|
||||
formClone.value = [];
|
||||
const length = uploadFileRef.value.loadData.length;
|
||||
if (length == 0) return ElMessage.error("请先上传文件!");
|
||||
const flag = await uploadFileRef.value.confirm();
|
||||
if (!flag) return ElMessage.error("请先选择表格关联项!");
|
||||
ElMessage({
|
||||
message: `正在上传数据中,请稍等...`,
|
||||
type: "success",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uploadFileRef.value.loadData.forEach((ExcleForm) => {
|
||||
ExcleForm.forEach((worksheet) => {
|
||||
let context = [...worksheet];
|
||||
context.shift();
|
||||
context.forEach((item) => {
|
||||
if (item.length != 0) {
|
||||
formClone.value.push({
|
||||
sn_number: item[relatedRules.sn_number.value]
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
emit("addSN", formClone.value);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
113
src/components/addNewData/SNForm/multipleAdd.vue
Normal file
@@ -0,0 +1,113 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="flex flex-warp justify-center items-center font-bold"
|
||||
>
|
||||
<div style="font-size: 1rem">请输入要导入的数据数量:</div>
|
||||
<el-input-number v-model="singleFormNum" :min="1" :max="10" @change="createForm" />
|
||||
<div v-if="checkNeed"> </div>
|
||||
<el-checkbox
|
||||
v-if="checkNeed"
|
||||
v-model="checked"
|
||||
label="为所有表单进行相同操作"
|
||||
size="large"
|
||||
/>
|
||||
</div>
|
||||
<el-scrollbar max-height="40rem">
|
||||
<div class="mt-2 border-2 border-gray-300" v-for="item in input">
|
||||
<div style="font-size: 1.2rem" class="w-full text-center font-bold">
|
||||
{{ item.label }}
|
||||
</div>
|
||||
<SingleAdd ref="singleAddRef" />
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
|
||||
const singleFormNum = ref(1);
|
||||
const checked = ref(true);
|
||||
const input = ref([{ label: "SN号1" }]);
|
||||
const singleAddRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const props = defineProps({
|
||||
checkNeed: Boolean,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addSN"]);
|
||||
|
||||
const initData = () => {
|
||||
setTimeout(() => {
|
||||
singleAddRef.value.forEach((item) => {});
|
||||
}, 0);
|
||||
};
|
||||
|
||||
const createForm = () => {
|
||||
let difference = Math.abs(singleFormNum.value - input.value.length);
|
||||
for (let i = 0; i < difference; i++) {
|
||||
if (singleFormNum.value > input.value.length) {
|
||||
input.value.push({ label: `卡${input.value.length + 1}` });
|
||||
} else if (singleFormNum.value < input.value.length) {
|
||||
input.value.pop();
|
||||
}
|
||||
}
|
||||
if (checked.value) {
|
||||
initData();
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!singleAddRef) return;
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.resetCheckForm();
|
||||
});
|
||||
singleFormNum.value = 1;
|
||||
createForm();
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (!singleAddRef) return;
|
||||
let valid = true;
|
||||
formClone.value = [];
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.validate().then((result) => {
|
||||
if (result) {
|
||||
formClone.value.push({ ...element.ruleForm });
|
||||
} else {
|
||||
valid = result;
|
||||
}
|
||||
});
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (valid) {
|
||||
emit("addSN", formClone.value);
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.resetCheckForm();
|
||||
});
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
}, 0);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
|
||||
watch(checked, (value) => {
|
||||
if (value) {
|
||||
initData();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
96
src/components/addNewData/SNForm/singleAdd.vue
Normal file
@@ -0,0 +1,96 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="SN号" prop="sn_number">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入卡号"
|
||||
minlength="8"
|
||||
maxlength="8"
|
||||
v-model="ruleForm.sn_number"
|
||||
@input="filter(ruleForm.sn_number, 'sn_number')"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
const ruleFormRef = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
sn_number: ""
|
||||
});
|
||||
|
||||
const formClone = ref({});
|
||||
|
||||
const checkLength = (length) => {
|
||||
return (rule, value) => {
|
||||
if (!value) return new Error(`请输入${length}位数字`);
|
||||
else if (value.length !== length) return new Error(`请输入${length}位数字`);
|
||||
else return true;
|
||||
};
|
||||
};
|
||||
|
||||
const rules = reactive({
|
||||
sn_number: [
|
||||
{ required: true, message: "请输入卡号", trigger: "blur" },
|
||||
{ validator: checkLength(8), trigger: "blur" },
|
||||
]
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addSN"]);
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!ruleFormRef) return;
|
||||
ruleFormRef.value.resetFields();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!ruleFormRef) return;
|
||||
await ruleFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
formClone.value = { ...ruleForm };
|
||||
emit("addSN", [formClone.value]);
|
||||
ruleFormRef.value.resetFields();
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const validate = () => {
|
||||
if (!ruleFormRef) return Promise.resolve(false);
|
||||
return new Promise((resolve) => {
|
||||
ruleFormRef.value.validate((valid) => {
|
||||
resolve(valid);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, validate, ruleForm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
156
src/components/addNewData/bdCardForm/bdCardForm.vue
Normal file
@@ -0,0 +1,156 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="resetCheckForm"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ title }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<FormTools @showTools="showTools" :dialogObj="bdCardMsgActive" />
|
||||
<SingleAdd ref="singleAddRef" v-if="dialogSingleVisible" @addBdCard="addBdCard" />
|
||||
<MultipleAdd
|
||||
ref="multipleAddRef"
|
||||
v-if="dialogMultipleVisible"
|
||||
:checkNeed="false"
|
||||
@addBdCard="addBdCard"
|
||||
/>
|
||||
<ExcleAdd ref="excleAddRef" v-if="dialogExcleVisible" @addBdCard="addBdCard" />
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm"> 取消 </el-button>
|
||||
<el-button style="font-weight: bold" type="primary" @click="confirm">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import FormTools from "../../operate/formTools.vue";
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
import MultipleAdd from "./multipleAdd.vue";
|
||||
import ExcleAdd from "./excleAdd.vue";
|
||||
|
||||
import bdCardActiveStore from "../../../stores/bdCard";
|
||||
|
||||
import $http from "../../../api/index";
|
||||
import $url from "../../../api/url";
|
||||
|
||||
import { encrypt } from "../../../utils/aes";
|
||||
|
||||
const bdCardMsgActive = bdCardActiveStore();
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const singleAddRef = ref(null);
|
||||
const multipleAddRef = ref(null);
|
||||
const excleAddRef = ref(null);
|
||||
const dialogSingleVisible = ref(true);
|
||||
const dialogMultipleVisible = ref(false);
|
||||
const dialogExcleVisible = ref(false);
|
||||
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["reloadData"]);
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "single":
|
||||
dialogSingleVisible.value = true;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = false;
|
||||
bdCardMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
bdCardMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
bdCardMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "multiple":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = true;
|
||||
dialogExcleVisible.value = false;
|
||||
bdCardMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
bdCardMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
bdCardMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "excle":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = true;
|
||||
bdCardMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
bdCardMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
bdCardMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.resetCheckForm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.resetCheckForm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.resetCheckForm();
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.confirm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.confirm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.confirm();
|
||||
}
|
||||
};
|
||||
|
||||
const addBdCard = (requestMsg) => {
|
||||
requestMsg.forEach((element) => {
|
||||
element.card_id = encrypt(String(element.card_id));
|
||||
element.card_imsi = encrypt(String(element.card_imsi));
|
||||
});
|
||||
const data = { requestMsg };
|
||||
$http.post($url.addBdCard, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
resetCheckForm();
|
||||
ElMessage({
|
||||
message: "新增北斗卡成功!",
|
||||
type: "success",
|
||||
});
|
||||
emit("reloadData");
|
||||
} else {
|
||||
ElMessage.error("新增北斗卡失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ dialogVisible });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
92
src/components/addNewData/bdCardForm/excleAdd.vue
Normal file
@@ -0,0 +1,92 @@
|
||||
<template>
|
||||
<UploadFile
|
||||
ref="uploadFileRef"
|
||||
:options="options"
|
||||
:relatedRules="relatedRules"
|
||||
:relatedOptions="relatedOptions"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import UploadFile from "../../operate/uploadFile.vue";
|
||||
|
||||
const uploadFileRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const options = {
|
||||
limit: 1,
|
||||
accept: ".xlsx",
|
||||
action: "",
|
||||
multiple: false,
|
||||
listType: "text",
|
||||
autoUpload: false,
|
||||
};
|
||||
|
||||
const relatedRules = {
|
||||
card_id: {
|
||||
value: "",
|
||||
label: "卡号",
|
||||
},
|
||||
card_imsi: {
|
||||
value: "",
|
||||
label: "IMSI号",
|
||||
},
|
||||
};
|
||||
|
||||
const relatedOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "卡号",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "IMSI号",
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
|
||||
const emit = defineEmits(["addBdCard"]);
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!uploadFileRef) return;
|
||||
uploadFileRef.value.handleExceed();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!uploadFileRef) return;
|
||||
formClone.value = [];
|
||||
const length = uploadFileRef.value.loadData.length;
|
||||
if (length == 0) return ElMessage.error("请先上传文件!");
|
||||
const flag = await uploadFileRef.value.confirm();
|
||||
if (!flag) return ElMessage.error("请先选择表格关联项!");
|
||||
ElMessage({
|
||||
message: `正在上传数据中,请稍等...`,
|
||||
type: "success",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uploadFileRef.value.loadData.forEach((ExcleForm) => {
|
||||
ExcleForm.forEach((worksheet) => {
|
||||
let context = [...worksheet];
|
||||
context.shift();
|
||||
context.forEach((item) => {
|
||||
if (item.length != 0) {
|
||||
formClone.value.push({
|
||||
card_id: item[relatedRules.card_id.value],
|
||||
card_imsi: item[relatedRules.card_imsi.value],
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
emit("addBdCard", formClone.value);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
113
src/components/addNewData/bdCardForm/multipleAdd.vue
Normal file
@@ -0,0 +1,113 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="flex flex-warp justify-center items-center font-bold"
|
||||
>
|
||||
<div style="font-size: 1rem">请输入要导入的数据数量:</div>
|
||||
<el-input-number v-model="singleFormNum" :min="1" :max="10" @change="createForm" />
|
||||
<div v-if="checkNeed"> </div>
|
||||
<el-checkbox
|
||||
v-if="checkNeed"
|
||||
v-model="checked"
|
||||
label="为所有表单进行相同操作"
|
||||
size="large"
|
||||
/>
|
||||
</div>
|
||||
<el-scrollbar max-height="40rem">
|
||||
<div class="mt-2 border-2 border-gray-300" v-for="item in input">
|
||||
<div style="font-size: 1.2rem" class="w-full text-center font-bold">
|
||||
{{ item.label }}
|
||||
</div>
|
||||
<SingleAdd ref="singleAddRef" />
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
|
||||
const singleFormNum = ref(1);
|
||||
const checked = ref(true);
|
||||
const input = ref([{ label: "卡1" }]);
|
||||
const singleAddRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const props = defineProps({
|
||||
checkNeed: Boolean,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addBdCard"]);
|
||||
|
||||
const initData = () => {
|
||||
setTimeout(() => {
|
||||
singleAddRef.value.forEach((item) => {});
|
||||
}, 0);
|
||||
};
|
||||
|
||||
const createForm = () => {
|
||||
let difference = Math.abs(singleFormNum.value - input.value.length);
|
||||
for (let i = 0; i < difference; i++) {
|
||||
if (singleFormNum.value > input.value.length) {
|
||||
input.value.push({ label: `卡${input.value.length + 1}` });
|
||||
} else if (singleFormNum.value < input.value.length) {
|
||||
input.value.pop();
|
||||
}
|
||||
}
|
||||
if (checked.value) {
|
||||
initData();
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!singleAddRef) return;
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.resetCheckForm();
|
||||
});
|
||||
singleFormNum.value = 1;
|
||||
createForm();
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (!singleAddRef) return;
|
||||
let valid = true;
|
||||
formClone.value = [];
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.validate().then((result) => {
|
||||
if (result) {
|
||||
formClone.value.push({ ...element.ruleForm });
|
||||
} else {
|
||||
valid = result;
|
||||
}
|
||||
});
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (valid) {
|
||||
emit("addBdCard", formClone.value);
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.resetCheckForm();
|
||||
});
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
}, 0);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
|
||||
watch(checked, (value) => {
|
||||
if (value) {
|
||||
initData();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
111
src/components/addNewData/bdCardForm/singleAdd.vue
Normal file
@@ -0,0 +1,111 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="卡号" prop="card_id">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入卡号"
|
||||
minlength="8"
|
||||
maxlength="8"
|
||||
v-model="ruleForm.card_id"
|
||||
@input="filter(ruleForm.card_id, 'card_id')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="IMSI号" prop="card_imsi">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入IMSI号"
|
||||
minlength="18"
|
||||
maxlength="18"
|
||||
v-model="ruleForm.card_imsi"
|
||||
@input="filter(ruleForm.card_imsi, 'card_imsi')"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
const ruleFormRef = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
card_id: "",
|
||||
card_imsi: "",
|
||||
});
|
||||
|
||||
const formClone = ref({});
|
||||
|
||||
const checkLength = (length) => {
|
||||
return (rule, value) => {
|
||||
if (!value) return new Error(`请输入${length}位数字`);
|
||||
else if (value.length !== length) return new Error(`请输入${length}位数字`);
|
||||
else return true;
|
||||
};
|
||||
};
|
||||
|
||||
const rules = reactive({
|
||||
card_id: [
|
||||
{ required: true, message: "请输入卡号", trigger: "blur" },
|
||||
{ validator: checkLength(8), trigger: "blur" },
|
||||
],
|
||||
card_imsi: [
|
||||
{ required: true, message: "请输入IMSI号", trigger: "blur" },
|
||||
{ validator: checkLength(18), trigger: "blur" },
|
||||
],
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addBdCard"]);
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!ruleFormRef) return;
|
||||
ruleFormRef.value.resetFields();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!ruleFormRef) return;
|
||||
await ruleFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
formClone.value = { ...ruleForm };
|
||||
emit("addBdCard", [formClone.value]);
|
||||
ruleFormRef.value.resetFields();
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const validate = () => {
|
||||
if (!ruleFormRef) return Promise.resolve(false);
|
||||
return new Promise((resolve) => {
|
||||
ruleFormRef.value.validate((valid) => {
|
||||
resolve(valid);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, validate, ruleForm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
177
src/components/addNewData/bsideForm/bsideForm.vue
Normal file
@@ -0,0 +1,177 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="resetCheckForm"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ title }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<FormTools @showTools="showTools" :dialogObj="bsideMsgActive" />
|
||||
<SingleAdd
|
||||
ref="singleAddRef"
|
||||
v-if="dialogSingleVisible"
|
||||
:addData="addData"
|
||||
:createdAt="createdAt"
|
||||
@addBside="addBside"
|
||||
@remoteSearch="remoteSearch"
|
||||
/>
|
||||
<MultipleAdd
|
||||
ref="multipleAddRef"
|
||||
v-if="dialogMultipleVisible"
|
||||
:addData="addData"
|
||||
:checkNeed="true"
|
||||
:createdAt="createdAt"
|
||||
@addBside="addBside"
|
||||
@remoteSearch="remoteSearch"
|
||||
/>
|
||||
<ExcleAdd ref="excleAddRef" v-if="dialogExcleVisible" @addBside="addBside" />
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm"> 取消 </el-button>
|
||||
<el-button style="font-weight: bold" type="primary" @click="confirm">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import FormTools from "../../operate/formTools.vue";
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
import MultipleAdd from "./multipleAdd.vue";
|
||||
import ExcleAdd from "./excleAdd.vue";
|
||||
|
||||
import bsideActiveStore from "../../../stores/bside";
|
||||
|
||||
import $http from "../../../api/index";
|
||||
import $url from "../../../api/url";
|
||||
|
||||
import { encrypt } from "../../../utils/aes";
|
||||
|
||||
const bsideMsgActive = bsideActiveStore();
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const singleAddRef = ref(null);
|
||||
const multipleAddRef = ref(null);
|
||||
const excleAddRef = ref(null);
|
||||
const dialogSingleVisible = ref(true);
|
||||
const dialogMultipleVisible = ref(false);
|
||||
const dialogExcleVisible = ref(false);
|
||||
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
addData: Object,
|
||||
createdAt: String,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["reloadData", "remoteSearch"]);
|
||||
|
||||
const remoteSearch = (data, searchKey, timeBefor, operateType) => {
|
||||
emit("remoteSearch", data, searchKey, timeBefor, "add", operateType);
|
||||
};
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "single":
|
||||
dialogSingleVisible.value = true;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = false;
|
||||
bsideMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
bsideMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
bsideMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "multiple":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = true;
|
||||
dialogExcleVisible.value = false;
|
||||
bsideMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
bsideMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
bsideMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "excle":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = true;
|
||||
bsideMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
bsideMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
bsideMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.resetCheckForm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.resetCheckForm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.resetCheckForm();
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.confirm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.confirm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.confirm();
|
||||
}
|
||||
};
|
||||
|
||||
const addBside = (requestMsg) => {
|
||||
requestMsg.forEach((element) => {
|
||||
element.role = encrypt(String(element.role));
|
||||
element.account_name = encrypt(String(element.account_name));
|
||||
element.organization =
|
||||
element.organization == "" ? "" : encrypt(String(element.organization));
|
||||
element.user_name = element.user_name == "" ? "" : encrypt(String(element.user_name));
|
||||
element.phone = element.phone == "" ? "" : encrypt(String(element.phone));
|
||||
element.msg = element.msg == "" ? "" : encrypt(String(element.msg));
|
||||
});
|
||||
const data = { requestMsg };
|
||||
$http.post($url.addBSide, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
resetCheckForm();
|
||||
ElMessage({
|
||||
message: "新增B端用户成功!",
|
||||
type: "success",
|
||||
});
|
||||
emit("reloadData");
|
||||
} else {
|
||||
ElMessage.error("新增B端用户失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ dialogVisible, singleAddRef, multipleAddRef });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
132
src/components/addNewData/bsideForm/excleAdd.vue
Normal file
@@ -0,0 +1,132 @@
|
||||
<template>
|
||||
<UploadFile
|
||||
ref="uploadFileRef"
|
||||
:options="options"
|
||||
:relatedRules="relatedRules"
|
||||
:relatedOptions="relatedOptions"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import UploadFile from "../../operate/uploadFile.vue";
|
||||
|
||||
const uploadFileRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const options = {
|
||||
limit: 1,
|
||||
accept: ".xlsx",
|
||||
action: "",
|
||||
multiple: false,
|
||||
listType: "text",
|
||||
autoUpload: false,
|
||||
};
|
||||
|
||||
const relatedRules = {
|
||||
role: {
|
||||
value: "",
|
||||
label: "账号角色",
|
||||
},
|
||||
account_name: {
|
||||
value: "",
|
||||
label: "账号名称",
|
||||
},
|
||||
organization: {
|
||||
value: "",
|
||||
label: "单位uid",
|
||||
},
|
||||
user_name: {
|
||||
value: "",
|
||||
label: "用户姓名",
|
||||
},
|
||||
phone: {
|
||||
value: "",
|
||||
label: "用户手机号码",
|
||||
},
|
||||
msg: {
|
||||
value: "",
|
||||
label: "用户基本信息",
|
||||
},
|
||||
};
|
||||
|
||||
const relatedOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "账号角色",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "账号名称",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "单位uid",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "3",
|
||||
label: "用户姓名",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "4",
|
||||
label: "用户手机号码",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "5",
|
||||
label: "用户基本信息",
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
|
||||
const emit = defineEmits(["addBside"]);
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!uploadFileRef) return;
|
||||
uploadFileRef.value.handleExceed();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!uploadFileRef) return;
|
||||
formClone.value = [];
|
||||
const length = uploadFileRef.value.loadData.length;
|
||||
if (length == 0) return ElMessage.error("请先上传文件!");
|
||||
const flag = await uploadFileRef.value.confirm();
|
||||
if (!flag) return ElMessage.error("请先选择表格关联项!");
|
||||
ElMessage({
|
||||
message: `正在上传数据中,请稍等...`,
|
||||
type: "success",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uploadFileRef.value.loadData.forEach((ExcleForm) => {
|
||||
ExcleForm.forEach((worksheet) => {
|
||||
let context = [...worksheet];
|
||||
context.shift();
|
||||
context.forEach((item) => {
|
||||
if (item.length != 0) {
|
||||
formClone.value.push({
|
||||
role: item[relatedRules.role.value],
|
||||
account_name: item[relatedRules.account_name.value],
|
||||
organization: item[relatedRules.organization.value],
|
||||
user_name: item[relatedRules.user_name.value],
|
||||
phone: item[relatedRules.phone.value],
|
||||
msg: item[relatedRules.msg.value],
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
emit("addBside", formClone.value);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
121
src/components/addNewData/bsideForm/multipleAdd.vue
Normal file
@@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="flex flex-warp justify-center items-center font-bold"
|
||||
>
|
||||
<div style="font-size: 1rem">请输入要导入的数据数量:</div>
|
||||
<el-input-number v-model="singleFormNum" :min="1" :max="10" @change="createForm" />
|
||||
<div v-if="checkNeed"> </div>
|
||||
<el-checkbox v-model="checked" label="为所有表单进行相同操作" size="large" />
|
||||
</div>
|
||||
<el-scrollbar max-height="40rem">
|
||||
<div class="mt-2 border-2 border-gray-300" v-for="item in input">
|
||||
<div style="font-size: 1.2rem" class="w-full text-center font-bold">
|
||||
{{ item.label }}
|
||||
</div>
|
||||
<SingleAdd
|
||||
ref="singleAddRef"
|
||||
:addData="addData"
|
||||
:createdAt="createdAt"
|
||||
@remoteSearch="remoteSearch"
|
||||
/>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
|
||||
const singleFormNum = ref(1);
|
||||
const checked = ref(true);
|
||||
const input = ref([{ label: "卡1" }]);
|
||||
const singleAddRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const props = defineProps({
|
||||
addData: Object,
|
||||
checkNeed: Boolean,
|
||||
createdAt: String,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addBside", "remoteSearch"]);
|
||||
|
||||
const remoteSearch = (data, searchKey, timeBefor) => {
|
||||
emit("remoteSearch", data, searchKey, timeBefor, "multiple");
|
||||
};
|
||||
|
||||
const initData = () => {
|
||||
setTimeout(() => {
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.ruleForm.role = singleAddRef.value[0].ruleForm.role;
|
||||
});
|
||||
}, 0);
|
||||
};
|
||||
|
||||
const createForm = () => {
|
||||
let difference = Math.abs(singleFormNum.value - input.value.length);
|
||||
for (let i = 0; i < difference; i++) {
|
||||
if (singleFormNum.value > input.value.length) {
|
||||
input.value.push({ label: `卡${input.value.length + 1}` });
|
||||
} else if (singleFormNum.value < input.value.length) {
|
||||
input.value.pop();
|
||||
}
|
||||
}
|
||||
if (checked.value) {
|
||||
initData();
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!singleAddRef) return;
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.resetCheckForm();
|
||||
});
|
||||
singleFormNum.value = 1;
|
||||
createForm();
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (!singleAddRef) return;
|
||||
let valid = true;
|
||||
formClone.value = [];
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.validate().then((result) => {
|
||||
if (result) {
|
||||
formClone.value.push({ ...element.ruleForm });
|
||||
} else {
|
||||
valid = result;
|
||||
}
|
||||
});
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (valid) {
|
||||
emit("addBside", formClone.value);
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.resetCheckForm();
|
||||
});
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
}, 0);
|
||||
};
|
||||
|
||||
defineExpose({ singleAddRef, resetCheckForm, confirm, formClone });
|
||||
|
||||
watch(checked, (value) => {
|
||||
if (value) {
|
||||
initData();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
165
src/components/addNewData/bsideForm/singleAdd.vue
Normal file
@@ -0,0 +1,165 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="账号角色" prop="role">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择账号角色"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.role"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in addData.roleOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="账号名称" prop="account_name">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入账号名称"
|
||||
minlength="8"
|
||||
maxlength="12"
|
||||
v-model="ruleForm.account_name"
|
||||
@input="filter(ruleForm.account_name, 'account_name')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="用户单位" prop="organization">
|
||||
<RemoteSearch
|
||||
ref="remoteSearchRef"
|
||||
@searchResult="searchResult"
|
||||
:disabled="false"
|
||||
searchKey="organization_name"
|
||||
:timeBefor="createdAt"
|
||||
@handleSelect="handleSelect"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="用户姓名" prop="user_name">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入用户姓名"
|
||||
maxlength="10"
|
||||
v-model="ruleForm.user_name"
|
||||
@input="filter(ruleForm.user_name, 'user_name')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="用户手机号码" prop="phone">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入用户手机号码"
|
||||
maxlength="11"
|
||||
v-model="ruleForm.phone"
|
||||
@input="filter(ruleForm.phone, 'phone')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="用户基本信息" prop="msg">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入用户基本信息"
|
||||
maxlength="200"
|
||||
v-model="ruleForm.msg"
|
||||
@input="filter(ruleForm.msg, 'msg')"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import RemoteSearch from "../../search/remoteSearch.vue";
|
||||
|
||||
const ruleFormRef = ref(null);
|
||||
const remoteSearchRef = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
role: "",
|
||||
account_name: "",
|
||||
organization: "",
|
||||
user_name: "",
|
||||
phone: "",
|
||||
msg: "",
|
||||
});
|
||||
|
||||
const props = defineProps({
|
||||
addData: Object,
|
||||
createdAt: String,
|
||||
});
|
||||
|
||||
const formClone = ref({});
|
||||
|
||||
const rules = reactive({
|
||||
role: [{ required: true, message: "请选择账号角色", trigger: "blur" }],
|
||||
account_name: [{ required: true, message: "请输入账号名称", trigger: "blur" }],
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addBside", "remoteSearch"]);
|
||||
|
||||
const searchResult = (data, searchKey, timeBefor) => {
|
||||
emit("remoteSearch", data, searchKey, timeBefor, "single");
|
||||
};
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!ruleFormRef) return;
|
||||
ruleFormRef.value.resetFields();
|
||||
remoteSearchRef.value.clearValue();
|
||||
};
|
||||
|
||||
const handleSelect = () => {
|
||||
ruleForm.organization = remoteSearchRef.value.keyValue;
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!ruleFormRef) return;
|
||||
await ruleFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
formClone.value = { ...ruleForm };
|
||||
emit("addBside", [formClone.value]);
|
||||
ruleFormRef.value.resetFields();
|
||||
remoteSearchRef.value.clearValue();
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const validate = () => {
|
||||
if (!ruleFormRef) return Promise.resolve(false);
|
||||
return new Promise((resolve) => {
|
||||
ruleFormRef.value.validate((valid) => {
|
||||
resolve(valid);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ remoteSearchRef, resetCheckForm, confirm, validate, ruleForm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
179
src/components/addNewData/businessForm/businessForm.vue
Normal file
@@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="resetCheckForm"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ title }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<FormTools @showTools="showTools" :dialogObj="businessMsgActive" />
|
||||
<SingleAdd
|
||||
ref="singleAddRef"
|
||||
v-if="dialogSingleVisible"
|
||||
:addData="addData"
|
||||
:createdAt="createdAt"
|
||||
@addBusiness="addBusiness"
|
||||
@remoteSearch="remoteSearch"
|
||||
/>
|
||||
<MultipleAdd
|
||||
ref="multipleAddRef"
|
||||
v-if="dialogMultipleVisible"
|
||||
:addData="addData"
|
||||
:checkNeed="true"
|
||||
:createdAt="createdAt"
|
||||
@addBusiness="addBusiness"
|
||||
@remoteSearch="remoteSearch"
|
||||
/>
|
||||
<ExcleAdd ref="excleAddRef" v-if="dialogExcleVisible" @addBusiness="addBusiness" />
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm"> 取消 </el-button>
|
||||
<el-button style="font-weight: bold" type="primary" @click="confirm">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import FormTools from "../../operate/formTools.vue";
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
import MultipleAdd from "./multipleAdd.vue";
|
||||
import ExcleAdd from "./excleAdd.vue";
|
||||
|
||||
import businessActiveStore from "../../../stores/business";
|
||||
|
||||
import $http from "../../../api/index";
|
||||
import $url from "../../../api/url";
|
||||
|
||||
import { encrypt } from "../../../utils/aes";
|
||||
|
||||
const businessMsgActive = businessActiveStore();
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const singleAddRef = ref(null);
|
||||
const multipleAddRef = ref(null);
|
||||
const excleAddRef = ref(null);
|
||||
const dialogSingleVisible = ref(true);
|
||||
const dialogMultipleVisible = ref(false);
|
||||
const dialogExcleVisible = ref(false);
|
||||
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
addData: Object,
|
||||
createdAt: String,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["reloadData", "remoteSearch"]);
|
||||
|
||||
const remoteSearch = (data, searchKey, timeBefor, operateType) => {
|
||||
emit("remoteSearch", data, searchKey, timeBefor, "add", operateType);
|
||||
};
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "single":
|
||||
dialogSingleVisible.value = true;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = false;
|
||||
businessMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
businessMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
businessMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "multiple":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = true;
|
||||
dialogExcleVisible.value = false;
|
||||
businessMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
businessMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
businessMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "excle":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = true;
|
||||
businessMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
businessMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
businessMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.resetCheckForm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.resetCheckForm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.resetCheckForm();
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.confirm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.confirm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.confirm();
|
||||
}
|
||||
};
|
||||
|
||||
const addBusiness = (requestMsg) => {
|
||||
requestMsg.forEach((element) => {
|
||||
element.login_url = encrypt(String(element.login_url));
|
||||
element.client_url = encrypt(String(element.client_url));
|
||||
element.temporary_id = encrypt(
|
||||
element.temporary_id === true ? "true" : String(element.temporary_id)
|
||||
);
|
||||
element.name = encrypt(String(element.name));
|
||||
element.type = encrypt(String(element.type));
|
||||
element.level = encrypt(String(element.level));
|
||||
element.status = encrypt(String(element.status));
|
||||
});
|
||||
const data = { requestMsg };
|
||||
$http.post($url.addBusiness, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
resetCheckForm();
|
||||
ElMessage({
|
||||
message: "新增公司业务成功!",
|
||||
type: "success",
|
||||
});
|
||||
emit("reloadData");
|
||||
} else {
|
||||
ElMessage.error("新增公司业务失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ dialogVisible, singleAddRef, multipleAddRef });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
132
src/components/addNewData/businessForm/excleAdd.vue
Normal file
@@ -0,0 +1,132 @@
|
||||
<template>
|
||||
<UploadFile
|
||||
ref="uploadFileRef"
|
||||
:options="options"
|
||||
:relatedRules="relatedRules"
|
||||
:relatedOptions="relatedOptions"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import UploadFile from "../../operate/uploadFile.vue";
|
||||
|
||||
const uploadFileRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const options = {
|
||||
limit: 1,
|
||||
accept: ".xlsx",
|
||||
action: "",
|
||||
multiple: false,
|
||||
listType: "text",
|
||||
autoUpload: false,
|
||||
};
|
||||
|
||||
const relatedRules = {
|
||||
login_url: {
|
||||
value: "",
|
||||
label: "业务登录网址",
|
||||
},
|
||||
client_url: {
|
||||
value: "",
|
||||
label: "业务网址",
|
||||
},
|
||||
name: {
|
||||
value: "",
|
||||
label: "业务名称",
|
||||
},
|
||||
type: {
|
||||
value: "",
|
||||
label: "业务类型",
|
||||
},
|
||||
level: {
|
||||
value: "",
|
||||
label: "业务等级",
|
||||
},
|
||||
status: {
|
||||
value: "",
|
||||
label: "业务状态",
|
||||
},
|
||||
};
|
||||
|
||||
const relatedOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "业务登录网址",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "业务网址",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "业务名称",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "3",
|
||||
label: "业务类型",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "4",
|
||||
label: "业务等级",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "5",
|
||||
label: "业务状态",
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
|
||||
const emit = defineEmits(["addBusiness"]);
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!uploadFileRef) return;
|
||||
uploadFileRef.value.handleExceed();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!uploadFileRef) return;
|
||||
formClone.value = [];
|
||||
const length = uploadFileRef.value.loadData.length;
|
||||
if (length == 0) return ElMessage.error("请先上传文件!");
|
||||
const flag = await uploadFileRef.value.confirm();
|
||||
if (!flag) return ElMessage.error("请先选择表格关联项!");
|
||||
ElMessage({
|
||||
message: `正在上传数据中,请稍等...`,
|
||||
type: "success",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uploadFileRef.value.loadData.forEach((ExcleForm) => {
|
||||
ExcleForm.forEach((worksheet) => {
|
||||
let context = [...worksheet];
|
||||
context.shift();
|
||||
context.forEach((item) => {
|
||||
if (item.length != 0) {
|
||||
formClone.value.push({
|
||||
login_url: item[relatedRules.login_url.value],
|
||||
client_url: item[relatedRules.client_url.value],
|
||||
name: item[relatedRules.name.value],
|
||||
type: item[relatedRules.type.value],
|
||||
level: item[relatedRules.level.value],
|
||||
status: item[relatedRules.status.value],
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
emit("addBusiness", formClone.value);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
137
src/components/addNewData/businessForm/multipleAdd.vue
Normal file
@@ -0,0 +1,137 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="flex flex-warp justify-center items-center font-bold"
|
||||
>
|
||||
<div style="font-size: 1rem">请输入要导入的数据数量:</div>
|
||||
<el-input-number v-model="singleFormNum" :min="1" :max="10" @change="createForm" />
|
||||
<div v-if="checkNeed"> </div>
|
||||
<el-checkbox
|
||||
v-if="checkNeed"
|
||||
v-model="checked"
|
||||
label="为所有表单进行相同操作"
|
||||
size="large"
|
||||
/>
|
||||
</div>
|
||||
<el-scrollbar max-height="40rem">
|
||||
<div class="mt-2 border-2 border-gray-300" v-for="item in input">
|
||||
<div style="font-size: 1.2rem" class="w-full text-center font-bold">
|
||||
{{ item.label }}
|
||||
</div>
|
||||
<SingleAdd
|
||||
ref="singleAddRef"
|
||||
:addData="addData"
|
||||
:createdAt="createdAt"
|
||||
@remoteSearch="remoteSearch"
|
||||
/>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
|
||||
const singleFormNum = ref(1);
|
||||
const checked = ref(true);
|
||||
const input = ref([{ label: "卡1" }]);
|
||||
const singleAddRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const props = defineProps({
|
||||
addData: Object,
|
||||
checkNeed: Boolean,
|
||||
createdAt: String,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addBusiness", "remoteSearch"]);
|
||||
|
||||
const remoteSearch = (data, searchKey, timeBefor) => {
|
||||
emit("remoteSearch", data, searchKey, timeBefor, "multiple");
|
||||
};
|
||||
|
||||
const initData = () => {
|
||||
setTimeout(() => {
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.ruleForm.type = singleAddRef.value[0].ruleForm.type;
|
||||
item.ruleForm.level = singleAddRef.value[0].ruleForm.level;
|
||||
item.ruleForm.status = singleAddRef.value[0].ruleForm.status;
|
||||
});
|
||||
}, 0);
|
||||
};
|
||||
|
||||
const createForm = () => {
|
||||
let difference = Math.abs(singleFormNum.value - input.value.length);
|
||||
for (let i = 0; i < difference; i++) {
|
||||
if (singleFormNum.value > input.value.length) {
|
||||
input.value.push({ label: `卡${input.value.length + 1}` });
|
||||
} else if (singleFormNum.value < input.value.length) {
|
||||
input.value.pop();
|
||||
}
|
||||
}
|
||||
if (checked.value) {
|
||||
initData();
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!singleAddRef) return;
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.resetCheckForm();
|
||||
});
|
||||
singleFormNum.value = 1;
|
||||
createForm();
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (!singleAddRef) return;
|
||||
let valid = true;
|
||||
formClone.value = [];
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.validate().then((result) => {
|
||||
if (!element.switchChecked) {
|
||||
if (
|
||||
element.ruleForm.temporary_id == true ||
|
||||
element.ruleForm.temporary_id == undefined
|
||||
) {
|
||||
result = false;
|
||||
element.checkedText = true;
|
||||
}
|
||||
}
|
||||
if (result) {
|
||||
formClone.value.push({ ...element.ruleForm });
|
||||
} else {
|
||||
valid = result;
|
||||
}
|
||||
});
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (valid) {
|
||||
emit("addBusiness", formClone.value);
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.resetCheckForm();
|
||||
});
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
}, 0);
|
||||
};
|
||||
|
||||
defineExpose({ singleAddRef, resetCheckForm, confirm, formClone });
|
||||
|
||||
watch(checked, (value) => {
|
||||
if (value) {
|
||||
initData();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
254
src/components/addNewData/businessForm/singleAdd.vue
Normal file
@@ -0,0 +1,254 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="业务登录网址" prop="login_url">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入业务登录网址"
|
||||
v-model="ruleForm.login_url"
|
||||
@input="filter(ruleForm.login_url, 'login_url')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="业务网址" prop="client_url">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入业务网址"
|
||||
v-model="ruleForm.client_url"
|
||||
@input="filter(ruleForm.client_url, 'client_url')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="业务临时标识" prop="temporary_id">
|
||||
<el-switch
|
||||
v-model="switchChecked"
|
||||
class="ml-2"
|
||||
inline-prompt
|
||||
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
|
||||
active-text="随机生成业务临时标识"
|
||||
inactive-text="使用已有业务临时标识"
|
||||
/>
|
||||
<div v-if="checkedText"> </div>
|
||||
<div v-if="checkedText" class="text-red-500 font-black">
|
||||
请搜索并使用业务临时标识
|
||||
</div>
|
||||
<RemoteSearch
|
||||
ref="remoteSearchRef"
|
||||
@searchResult="searchResult"
|
||||
:disabled="switchChecked"
|
||||
searchKey="name"
|
||||
:timeBefor="createdAt"
|
||||
@handleSelect="handleSelect"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="业务名称" prop="name">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入业务名称"
|
||||
v-model="ruleForm.name"
|
||||
@input="filter(ruleForm.name, 'name')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="业务类型" prop="type">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择业务类型"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.type"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in addData.typeOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="业务等级" prop="level">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择业务等级"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.level"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in addData.levelOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="业务状态" prop="status">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择业务状态"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.status"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in addData.statusOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import RemoteSearch from "../../search/remoteSearch.vue";
|
||||
|
||||
const ruleFormRef = ref(null);
|
||||
const switchChecked = ref(true);
|
||||
const checkedText = ref(false);
|
||||
const remoteSearchRef = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
login_url: "",
|
||||
client_url: "",
|
||||
temporary_id: true,
|
||||
name: "",
|
||||
type: "",
|
||||
level: "",
|
||||
status: "",
|
||||
});
|
||||
|
||||
const props = defineProps({
|
||||
addData: Object,
|
||||
createdAt: String,
|
||||
});
|
||||
|
||||
const formClone = ref({});
|
||||
|
||||
const rules = reactive({
|
||||
login_url: [{ required: true, message: "请输入业务登录网址", trigger: "blur" }],
|
||||
client_url: [{ required: true, message: "请输入业务网址", trigger: "blur" }],
|
||||
name: [{ required: true, message: "请输入业务名称", trigger: "blur" }],
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addBusiness", "remoteSearch"]);
|
||||
|
||||
const searchResult = (data, searchKey, timeBefor) => {
|
||||
emit("remoteSearch", data, searchKey, timeBefor, "single");
|
||||
};
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelect = () => {
|
||||
ruleForm.temporary_id = remoteSearchRef.value.keyValue;
|
||||
checkedText.value = false;
|
||||
remoteSearchRef.value.selectStyle = "";
|
||||
remoteSearchRef.value.statusHolder = false;
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!ruleFormRef) return;
|
||||
ruleFormRef.value.resetFields();
|
||||
remoteSearchRef.value.clearValue();
|
||||
switchChecked.value = true;
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!ruleFormRef) return;
|
||||
await ruleFormRef.value.validate((valid) => {
|
||||
if (!switchChecked.value) {
|
||||
if (ruleForm.temporary_id == true || ruleForm.temporary_id == undefined) {
|
||||
valid = false;
|
||||
checkedText.value = true;
|
||||
remoteSearchRef.value.selectStyle = "border-width: 2px; border-color: rgb(239 68 68);";
|
||||
remoteSearchRef.value.statusHolder = true;
|
||||
}
|
||||
}
|
||||
if (valid) {
|
||||
formClone.value = { ...ruleForm };
|
||||
emit("addBusiness", [formClone.value]);
|
||||
ruleFormRef.value.resetFields();
|
||||
remoteSearchRef.value.clearValue();
|
||||
switchChecked.value = true;
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const validate = () => {
|
||||
if (!ruleFormRef) return Promise.resolve(false);
|
||||
return new Promise((resolve) => {
|
||||
ruleFormRef.value.validate((valid) => {
|
||||
resolve(valid);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
remoteSearchRef,
|
||||
resetCheckForm,
|
||||
confirm,
|
||||
validate,
|
||||
ruleForm,
|
||||
formClone,
|
||||
switchChecked,
|
||||
checkedText,
|
||||
});
|
||||
|
||||
watch(switchChecked, (value) => {
|
||||
if (value) {
|
||||
checkedText.value = false;
|
||||
remoteSearchRef.value.selectStyle = "";
|
||||
ruleForm.temporary_id = true;
|
||||
remoteSearchRef.value.clearValue();
|
||||
} else {
|
||||
if (remoteSearchRef.value.statusHolder) {
|
||||
checkedText.value = true;
|
||||
remoteSearchRef.value.selectStyle = "border-width: 2px; border-color: rgb(239 68 68);";
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
watch(ruleForm, (value) => {
|
||||
if (!switchChecked.value) {
|
||||
checkedText.value = true;
|
||||
remoteSearchRef.value.selectStyle = "border-width: 2px; border-color: rgb(239 68 68);";
|
||||
remoteSearchRef.value.statusHolder = true;
|
||||
}
|
||||
if (value.temporary_id !== true && value.temporary_id !== undefined) {
|
||||
checkedText.value = false;
|
||||
remoteSearchRef.value.selectStyle = "";
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
156
src/components/addNewData/contest/accountForm/accountForm.vue
Normal file
@@ -0,0 +1,156 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="resetCheckForm"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ title }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<FormTools @showTools="showTools" :dialogObj="accountMsgActive" />
|
||||
<SingleAdd ref="singleAddRef" v-if="dialogSingleVisible" @addAccount="addAccount" />
|
||||
<MultipleAdd
|
||||
ref="multipleAddRef"
|
||||
v-if="dialogMultipleVisible"
|
||||
:checkNeed="false"
|
||||
@addAccount="addAccount"
|
||||
/>
|
||||
<ExcleAdd ref="excleAddRef" v-if="dialogExcleVisible" @addAccount="addAccount" />
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm"> 取消 </el-button>
|
||||
<el-button style="font-weight: bold" type="primary" @click="confirm">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import FormTools from "../../../operate/formTools.vue";
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
import MultipleAdd from "./multipleAdd.vue";
|
||||
import ExcleAdd from "./excleAdd.vue";
|
||||
|
||||
import accountActiveStore from "../../../../stores/contest/account";
|
||||
|
||||
import $http from "../../../../api/index";
|
||||
import $url from "../../../../api/url";
|
||||
|
||||
import { encrypt } from "../../../../utils/aes";
|
||||
|
||||
const accountMsgActive = accountActiveStore();
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const singleAddRef = ref(null);
|
||||
const multipleAddRef = ref(null);
|
||||
const excleAddRef = ref(null);
|
||||
const dialogSingleVisible = ref(true);
|
||||
const dialogMultipleVisible = ref(false);
|
||||
const dialogExcleVisible = ref(false);
|
||||
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["reloadData"]);
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "single":
|
||||
dialogSingleVisible.value = true;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = false;
|
||||
accountMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
accountMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
accountMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "multiple":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = true;
|
||||
dialogExcleVisible.value = false;
|
||||
accountMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
accountMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
accountMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "excle":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = true;
|
||||
accountMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
accountMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
accountMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.resetCheckForm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.resetCheckForm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.resetCheckForm();
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.confirm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.confirm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.confirm();
|
||||
}
|
||||
};
|
||||
|
||||
const addAccount = (requestMsg) => {
|
||||
requestMsg.forEach((element) => {
|
||||
element.contest_uid = encrypt(String(element.contest_uid));
|
||||
element.account_name = encrypt(String(element.account_name));
|
||||
});
|
||||
const data = { requestMsg };
|
||||
$http.post($url.addAccount, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
resetCheckForm();
|
||||
ElMessage({
|
||||
message: "新增竞赛账号成功!",
|
||||
type: "success",
|
||||
});
|
||||
emit("reloadData");
|
||||
} else {
|
||||
ElMessage.error("新增竞赛账号失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ dialogVisible });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
82
src/components/addNewData/contest/accountForm/excleAdd.vue
Normal file
@@ -0,0 +1,82 @@
|
||||
<template>
|
||||
<UploadFile
|
||||
ref="uploadFileRef"
|
||||
:options="options"
|
||||
:relatedRules="relatedRules"
|
||||
:relatedOptions="relatedOptions"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import UploadFile from "../../../operate/uploadFile.vue";
|
||||
|
||||
const uploadFileRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const options = {
|
||||
limit: 1,
|
||||
accept: ".xlsx",
|
||||
action: "",
|
||||
multiple: false,
|
||||
listType: "text",
|
||||
autoUpload: false,
|
||||
};
|
||||
|
||||
const relatedRules = {
|
||||
account_name: {
|
||||
value: "",
|
||||
label: "账号名称",
|
||||
},
|
||||
};
|
||||
|
||||
const relatedOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "账号名称",
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
|
||||
const emit = defineEmits(["addAccount"]);
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!uploadFileRef) return;
|
||||
uploadFileRef.value.handleExceed();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!uploadFileRef) return;
|
||||
formClone.value = [];
|
||||
const length = uploadFileRef.value.loadData.length;
|
||||
if (length == 0) return ElMessage.error("请先上传文件!");
|
||||
const flag = await uploadFileRef.value.confirm();
|
||||
if (!flag) return ElMessage.error("请先选择表格关联项!");
|
||||
ElMessage({
|
||||
message: `正在上传数据中,请稍等...`,
|
||||
type: "success",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uploadFileRef.value.loadData.forEach((ExcleForm) => {
|
||||
ExcleForm.forEach((worksheet) => {
|
||||
let context = [...worksheet];
|
||||
context.shift();
|
||||
context.forEach((item) => {
|
||||
if (item.length != 0) {
|
||||
formClone.value.push({
|
||||
account_name: item[relatedRules.account_name.value],
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
emit("addAccount", formClone.value);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
113
src/components/addNewData/contest/accountForm/multipleAdd.vue
Normal file
@@ -0,0 +1,113 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="flex flex-warp justify-center items-center font-bold"
|
||||
>
|
||||
<div style="font-size: 1rem">请输入要导入的数据数量:</div>
|
||||
<el-input-number v-model="singleFormNum" :min="1" :max="10" @change="createForm" />
|
||||
<div v-if="checkNeed"> </div>
|
||||
<el-checkbox
|
||||
v-if="checkNeed"
|
||||
v-model="checked"
|
||||
label="为所有表单进行相同操作"
|
||||
size="large"
|
||||
/>
|
||||
</div>
|
||||
<el-scrollbar max-height="40rem">
|
||||
<div class="mt-2 border-2 border-gray-300" v-for="item in input">
|
||||
<div style="font-size: 1.2rem" class="w-full text-center font-bold">
|
||||
{{ item.label }}
|
||||
</div>
|
||||
<SingleAdd ref="singleAddRef" />
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
|
||||
const singleFormNum = ref(1);
|
||||
const checked = ref(true);
|
||||
const input = ref([{ label: "卡1" }]);
|
||||
const singleAddRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const props = defineProps({
|
||||
checkNeed: Boolean,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addAccount"]);
|
||||
|
||||
const initData = () => {
|
||||
setTimeout(() => {
|
||||
singleAddRef.value.forEach((item) => {});
|
||||
}, 0);
|
||||
};
|
||||
|
||||
const createForm = () => {
|
||||
let difference = Math.abs(singleFormNum.value - input.value.length);
|
||||
for (let i = 0; i < difference; i++) {
|
||||
if (singleFormNum.value > input.value.length) {
|
||||
input.value.push({ label: `卡${input.value.length + 1}` });
|
||||
} else if (singleFormNum.value < input.value.length) {
|
||||
input.value.pop();
|
||||
}
|
||||
}
|
||||
if (checked.value) {
|
||||
initData();
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!singleAddRef) return;
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.resetCheckForm();
|
||||
});
|
||||
singleFormNum.value = 1;
|
||||
createForm();
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (!singleAddRef) return;
|
||||
let valid = true;
|
||||
formClone.value = [];
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.validate().then((result) => {
|
||||
if (result) {
|
||||
formClone.value.push({ ...element.ruleForm });
|
||||
} else {
|
||||
valid = result;
|
||||
}
|
||||
});
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (valid) {
|
||||
emit("addAccount", formClone.value);
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.resetCheckForm();
|
||||
});
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
}, 0);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
|
||||
watch(checked, (value) => {
|
||||
if (value) {
|
||||
initData();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
111
src/components/addNewData/contest/accountForm/singleAdd.vue
Normal file
@@ -0,0 +1,111 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="竞赛uid" prop="contest_uid">
|
||||
<el-autocomplete
|
||||
:fetch-suggestions="searchContestUid"
|
||||
clearable
|
||||
placeholder="请输入竞赛uid"
|
||||
v-model="ruleForm.contest_uid"
|
||||
@input="filter(ruleForm.contest_uid, 'contest_uid')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="账号名称" prop="account_name">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入账号名称"
|
||||
maxlength="20"
|
||||
v-model="ruleForm.account_name"
|
||||
@input="filter(ruleForm.account_name, 'account_name')"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import $http from "../../../../api/index";
|
||||
import $url from "../../../../api/url";
|
||||
|
||||
const ruleFormRef = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
contest_uid: "",
|
||||
account_name: "",
|
||||
});
|
||||
|
||||
const formClone = ref({});
|
||||
|
||||
const searchContestUid = (value, cb) => {
|
||||
const data = {
|
||||
contest_uid: value,
|
||||
};
|
||||
$http.post($url.searchContestUid, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
cb(res.data.data);
|
||||
} else {
|
||||
cb([]);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const rules = reactive({
|
||||
contest_uid: [{ required: true, message: "请输入竞赛uid", trigger: "blur" }],
|
||||
account_name: [{ required: true, message: "请输入账号名称", trigger: "blur" }],
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addAccount"]);
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!ruleFormRef) return;
|
||||
ruleFormRef.value.resetFields();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!ruleFormRef) return;
|
||||
await ruleFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
formClone.value = { ...ruleForm };
|
||||
emit("addAccount", [formClone.value]);
|
||||
ruleFormRef.value.resetFields();
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const validate = () => {
|
||||
if (!ruleFormRef) return Promise.resolve(false);
|
||||
return new Promise((resolve) => {
|
||||
ruleFormRef.value.validate((valid) => {
|
||||
resolve(valid);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, validate, ruleForm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,168 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="resetCheckForm"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ title }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<FormTools @showTools="showTools" :dialogObj="choiceTopicMsgActive" />
|
||||
<SingleAdd
|
||||
ref="singleAddRef"
|
||||
v-if="dialogSingleVisible"
|
||||
@addChoiceTopic="addChoiceTopic"
|
||||
/>
|
||||
<MultipleAdd
|
||||
ref="multipleAddRef"
|
||||
v-if="dialogMultipleVisible"
|
||||
:checkNeed="false"
|
||||
@addChoiceTopic="addChoiceTopic"
|
||||
/>
|
||||
<ExcleAdd
|
||||
ref="excleAddRef"
|
||||
v-if="dialogExcleVisible"
|
||||
@addChoiceTopic="addChoiceTopic"
|
||||
/>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm"> 取消 </el-button>
|
||||
<el-button style="font-weight: bold" type="primary" @click="confirm">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import FormTools from "../../../operate/formTools.vue";
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
import MultipleAdd from "./multipleAdd.vue";
|
||||
import ExcleAdd from "./excleAdd.vue";
|
||||
|
||||
import choiceTopicActiveStore from "../../../../stores/contest/choiceTopic";
|
||||
|
||||
import $http from "../../../../api/index";
|
||||
import $url from "../../../../api/url";
|
||||
|
||||
import { encrypt } from "../../../../utils/aes";
|
||||
|
||||
const choiceTopicMsgActive = choiceTopicActiveStore();
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const singleAddRef = ref(null);
|
||||
const multipleAddRef = ref(null);
|
||||
const excleAddRef = ref(null);
|
||||
const dialogSingleVisible = ref(true);
|
||||
const dialogMultipleVisible = ref(false);
|
||||
const dialogExcleVisible = ref(false);
|
||||
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["reloadData"]);
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "single":
|
||||
dialogSingleVisible.value = true;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = false;
|
||||
choiceTopicMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
choiceTopicMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
choiceTopicMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "multiple":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = true;
|
||||
dialogExcleVisible.value = false;
|
||||
choiceTopicMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
choiceTopicMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
choiceTopicMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "excle":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = true;
|
||||
choiceTopicMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
choiceTopicMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
choiceTopicMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.resetCheckForm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.resetCheckForm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.resetCheckForm();
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.confirm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.confirm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.confirm();
|
||||
}
|
||||
};
|
||||
|
||||
const addChoiceTopic = (requestMsg) => {
|
||||
requestMsg.forEach((element) => {
|
||||
element.topic = encrypt(String(element.topic));
|
||||
element.options_a = encrypt(String(element.options_a));
|
||||
element.options_b = encrypt(String(element.options_b));
|
||||
element.options_c = encrypt(String(element.options_c));
|
||||
element.options_d = encrypt(String(element.options_d));
|
||||
element.answer = encrypt(String(element.answer));
|
||||
});
|
||||
const data = { requestMsg };
|
||||
$http.post($url.addChoiceTopic, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
resetCheckForm();
|
||||
ElMessage({
|
||||
message: "新增单选题成功!",
|
||||
type: "success",
|
||||
});
|
||||
emit("reloadData");
|
||||
} else {
|
||||
ElMessage.error("新增单选题失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ dialogVisible });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
132
src/components/addNewData/contest/choiceTopicForm/excleAdd.vue
Normal file
@@ -0,0 +1,132 @@
|
||||
<template>
|
||||
<UploadFile
|
||||
ref="uploadFileRef"
|
||||
:options="options"
|
||||
:relatedRules="relatedRules"
|
||||
:relatedOptions="relatedOptions"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import UploadFile from "../../../operate/uploadFile.vue";
|
||||
|
||||
const uploadFileRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const options = {
|
||||
limit: 1,
|
||||
accept: ".xlsx",
|
||||
action: "",
|
||||
multiple: false,
|
||||
listType: "text",
|
||||
autoUpload: false,
|
||||
};
|
||||
|
||||
const relatedRules = {
|
||||
topic: {
|
||||
value: "",
|
||||
label: "题目",
|
||||
},
|
||||
options_a: {
|
||||
value: "",
|
||||
label: "选项A",
|
||||
},
|
||||
options_b: {
|
||||
value: "",
|
||||
label: "选项B",
|
||||
},
|
||||
options_c: {
|
||||
value: "",
|
||||
label: "选项C",
|
||||
},
|
||||
options_d: {
|
||||
value: "",
|
||||
label: "选项D",
|
||||
},
|
||||
answer: {
|
||||
value: "",
|
||||
label: "答案",
|
||||
},
|
||||
};
|
||||
|
||||
const relatedOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "题目",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "选项A",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "选项B",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "选项C",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "选项D",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "答案",
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
|
||||
const emit = defineEmits(["addChoiceTopic"]);
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!uploadFileRef) return;
|
||||
uploadFileRef.value.handleExceed();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!uploadFileRef) return;
|
||||
formClone.value = [];
|
||||
const length = uploadFileRef.value.loadData.length;
|
||||
if (length == 0) return ElMessage.error("请先上传文件!");
|
||||
const flag = await uploadFileRef.value.confirm();
|
||||
if (!flag) return ElMessage.error("请先选择表格关联项!");
|
||||
ElMessage({
|
||||
message: `正在上传数据中,请稍等...`,
|
||||
type: "success",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uploadFileRef.value.loadData.forEach((ExcleForm) => {
|
||||
ExcleForm.forEach((worksheet) => {
|
||||
let context = [...worksheet];
|
||||
context.shift();
|
||||
context.forEach((item) => {
|
||||
if (item.length != 0) {
|
||||
formClone.value.push({
|
||||
topic: item[relatedRules.topic.value],
|
||||
options_a: item[relatedRules.options_a.value],
|
||||
options_b: item[relatedRules.options_b.value],
|
||||
options_c: item[relatedRules.options_c.value],
|
||||
options_d: item[relatedRules.options_d.value],
|
||||
answer: item[relatedRules.answer.value],
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
emit("addChoiceTopic", formClone.value);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,113 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="flex flex-warp justify-center items-center font-bold"
|
||||
>
|
||||
<div style="font-size: 1rem">请输入要导入的数据数量:</div>
|
||||
<el-input-number v-model="singleFormNum" :min="1" :max="10" @change="createForm" />
|
||||
<div v-if="checkNeed"> </div>
|
||||
<el-checkbox
|
||||
v-if="checkNeed"
|
||||
v-model="checked"
|
||||
label="为所有表单进行相同操作"
|
||||
size="large"
|
||||
/>
|
||||
</div>
|
||||
<el-scrollbar max-height="40rem">
|
||||
<div class="mt-2 border-2 border-gray-300" v-for="item in input">
|
||||
<div style="font-size: 1.2rem" class="w-full text-center font-bold">
|
||||
{{ item.label }}
|
||||
</div>
|
||||
<SingleAdd ref="singleAddRef" />
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
|
||||
const singleFormNum = ref(1);
|
||||
const checked = ref(true);
|
||||
const input = ref([{ label: "卡1" }]);
|
||||
const singleAddRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const props = defineProps({
|
||||
checkNeed: Boolean,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addChoiceTopic"]);
|
||||
|
||||
const initData = () => {
|
||||
setTimeout(() => {
|
||||
singleAddRef.value.forEach((item) => {});
|
||||
}, 0);
|
||||
};
|
||||
|
||||
const createForm = () => {
|
||||
let difference = Math.abs(singleFormNum.value - input.value.length);
|
||||
for (let i = 0; i < difference; i++) {
|
||||
if (singleFormNum.value > input.value.length) {
|
||||
input.value.push({ label: `卡${input.value.length + 1}` });
|
||||
} else if (singleFormNum.value < input.value.length) {
|
||||
input.value.pop();
|
||||
}
|
||||
}
|
||||
if (checked.value) {
|
||||
initData();
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!singleAddRef) return;
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.resetCheckForm();
|
||||
});
|
||||
singleFormNum.value = 1;
|
||||
createForm();
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (!singleAddRef) return;
|
||||
let valid = true;
|
||||
formClone.value = [];
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.validate().then((result) => {
|
||||
if (result) {
|
||||
formClone.value.push({ ...element.ruleForm });
|
||||
} else {
|
||||
valid = result;
|
||||
}
|
||||
});
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (valid) {
|
||||
emit("addChoiceTopic", formClone.value);
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.resetCheckForm();
|
||||
});
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
}, 0);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
|
||||
watch(checked, (value) => {
|
||||
if (value) {
|
||||
initData();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
133
src/components/addNewData/contest/choiceTopicForm/singleAdd.vue
Normal file
@@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="题目" prop="topic">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入题目"
|
||||
v-model="ruleForm.topic"
|
||||
@input="filter(ruleForm.topic, 'topic')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="选项A" prop="options_a">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入选项A"
|
||||
v-model="ruleForm.options_a"
|
||||
@input="filter(ruleForm.options_a, 'options_a')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="选项B" prop="options_b">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入选项B"
|
||||
v-model="ruleForm.options_b"
|
||||
@input="filter(ruleForm.options_b, 'options_b')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="选项C" prop="options_c">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入选项C"
|
||||
v-model="ruleForm.options_c"
|
||||
@input="filter(ruleForm.options_c, 'options_c')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="选项D" prop="options_d">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入选项D"
|
||||
v-model="ruleForm.options_d"
|
||||
@input="filter(ruleForm.options_d, 'options_d')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="答案" prop="answer">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入答案"
|
||||
v-model="ruleForm.answer"
|
||||
@input="filter(ruleForm.answer, 'answer')"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
const ruleFormRef = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
topic: "",
|
||||
options_a: "",
|
||||
options_b: "",
|
||||
options_c: "",
|
||||
options_d: "",
|
||||
answer: "",
|
||||
});
|
||||
|
||||
const formClone = ref({});
|
||||
|
||||
const rules = reactive({
|
||||
topic: [{ required: true, message: "请输入题目", trigger: "blur" }],
|
||||
options_a: [{ required: true, message: "请输入选项A", trigger: "blur" }],
|
||||
options_b: [{ required: true, message: "请输入选项B", trigger: "blur" }],
|
||||
options_c: [{ required: true, message: "请输入选项C", trigger: "blur" }],
|
||||
options_d: [{ required: true, message: "请输入选项D", trigger: "blur" }],
|
||||
answer: [{ required: true, message: "请输入答案", trigger: "blur" }],
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addChoiceTopic"]);
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!ruleFormRef) return;
|
||||
ruleFormRef.value.resetFields();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!ruleFormRef) return;
|
||||
await ruleFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
formClone.value = { ...ruleForm };
|
||||
emit("addChoiceTopic", [formClone.value]);
|
||||
ruleFormRef.value.resetFields();
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const validate = () => {
|
||||
if (!ruleFormRef) return Promise.resolve(false);
|
||||
return new Promise((resolve) => {
|
||||
ruleFormRef.value.validate((valid) => {
|
||||
resolve(valid);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, validate, ruleForm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
164
src/components/addNewData/contest/contestForm/contestForm.vue
Normal file
@@ -0,0 +1,164 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="resetCheckForm"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ title }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<FormTools @showTools="showTools" :dialogObj="contestMsgActive" />
|
||||
<SingleAdd
|
||||
ref="singleAddRef"
|
||||
v-if="dialogSingleVisible"
|
||||
:addData="addData"
|
||||
@addContest="addContest"
|
||||
/>
|
||||
<MultipleAdd
|
||||
ref="multipleAddRef"
|
||||
v-if="dialogMultipleVisible"
|
||||
:checkNeed="false"
|
||||
:addData="addData"
|
||||
@addContest="addContest"
|
||||
/>
|
||||
<ExcleAdd ref="excleAddRef" v-if="dialogExcleVisible" @addContest="addContest" />
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm"> 取消 </el-button>
|
||||
<el-button style="font-weight: bold" type="primary" @click="confirm">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import FormTools from "../../../operate/formTools.vue";
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
import MultipleAdd from "./multipleAdd.vue";
|
||||
import ExcleAdd from "./excleAdd.vue";
|
||||
|
||||
import contestActiveStore from "../../../../stores/contest/contest";
|
||||
|
||||
import $http from "../../../../api/index";
|
||||
import $url from "../../../../api/url";
|
||||
|
||||
import { encrypt } from "../../../../utils/aes";
|
||||
|
||||
const contestMsgActive = contestActiveStore();
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const singleAddRef = ref(null);
|
||||
const multipleAddRef = ref(null);
|
||||
const excleAddRef = ref(null);
|
||||
const dialogSingleVisible = ref(true);
|
||||
const dialogMultipleVisible = ref(false);
|
||||
const dialogExcleVisible = ref(false);
|
||||
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["reloadData"]);
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "single":
|
||||
dialogSingleVisible.value = true;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = false;
|
||||
contestMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
contestMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
contestMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "multiple":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = true;
|
||||
dialogExcleVisible.value = false;
|
||||
contestMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
contestMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
contestMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "excle":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = true;
|
||||
contestMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
contestMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
contestMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.resetCheckForm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.resetCheckForm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.resetCheckForm();
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.confirm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.confirm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.confirm();
|
||||
}
|
||||
};
|
||||
|
||||
const addContest = (requestMsg) => {
|
||||
requestMsg.forEach((element) => {
|
||||
element.contest_name = encrypt(String(element.contest_name));
|
||||
element.contest_organizers = encrypt(String(element.contest_organizers));
|
||||
element.contest_term = encrypt(String(element.contest_term));
|
||||
});
|
||||
const data = { requestMsg };
|
||||
$http.post($url.addContest, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
resetCheckForm();
|
||||
ElMessage({
|
||||
message: "新增竞赛成功!",
|
||||
type: "success",
|
||||
});
|
||||
emit("reloadData");
|
||||
} else {
|
||||
ElMessage.error("新增竞赛失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ dialogVisible });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
172
src/components/addNewData/contest/contestForm/excleAdd.vue
Normal file
@@ -0,0 +1,172 @@
|
||||
<template>
|
||||
<UploadFile
|
||||
ref="uploadFileRef"
|
||||
:options="options"
|
||||
:relatedRules="relatedRules"
|
||||
:relatedOptions="relatedOptions"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import UploadFile from "../../../operate/uploadFile.vue";
|
||||
|
||||
const uploadFileRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const options = {
|
||||
limit: 1,
|
||||
accept: ".xlsx",
|
||||
action: "",
|
||||
multiple: false,
|
||||
listType: "text",
|
||||
autoUpload: false,
|
||||
};
|
||||
|
||||
const relatedRules = {
|
||||
contest_name: {
|
||||
value: "",
|
||||
label: "竞赛名称",
|
||||
},
|
||||
contest_organizers: {
|
||||
value: "",
|
||||
label: "竞赛主办方",
|
||||
},
|
||||
contest_term: {
|
||||
value: "",
|
||||
label: "竞赛届数",
|
||||
},
|
||||
type: {
|
||||
value: "",
|
||||
label: "竞赛类型",
|
||||
},
|
||||
online_start: {
|
||||
value: "",
|
||||
label: "线上赛开始时间",
|
||||
},
|
||||
online_end: {
|
||||
value: "",
|
||||
label: "线上赛结束时间",
|
||||
},
|
||||
offline_start: {
|
||||
value: "",
|
||||
label: "线下赛开始时间",
|
||||
},
|
||||
offline_end: {
|
||||
value: "",
|
||||
label: "线下赛结束时间",
|
||||
},
|
||||
contest_start: {
|
||||
value: "",
|
||||
label: "竞赛开始时间",
|
||||
},
|
||||
contest_end: {
|
||||
value: "",
|
||||
label: "竞赛结束时间",
|
||||
},
|
||||
};
|
||||
|
||||
const relatedOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "竞赛名称",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "竞赛主办方",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "竞赛届数",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "3",
|
||||
label: "竞赛类型",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "4",
|
||||
label: "线上赛开始时间",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "5",
|
||||
label: "线上赛结束时间",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "6",
|
||||
label: "线下赛开始时间",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "7",
|
||||
label: "线下赛结束时间",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "8",
|
||||
label: "竞赛开始时间",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "9",
|
||||
label: "竞赛结束时间",
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
|
||||
const emit = defineEmits(["addContest"]);
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!uploadFileRef) return;
|
||||
uploadFileRef.value.handleExceed();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!uploadFileRef) return;
|
||||
formClone.value = [];
|
||||
const length = uploadFileRef.value.loadData.length;
|
||||
if (length == 0) return ElMessage.error("请先上传文件!");
|
||||
const flag = await uploadFileRef.value.confirm();
|
||||
if (!flag) return ElMessage.error("请先选择表格关联项!");
|
||||
ElMessage({
|
||||
message: `正在上传数据中,请稍等...`,
|
||||
type: "success",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uploadFileRef.value.loadData.forEach((ExcleForm) => {
|
||||
ExcleForm.forEach((worksheet) => {
|
||||
let context = [...worksheet];
|
||||
context.shift();
|
||||
context.forEach((item) => {
|
||||
if (item.length != 0) {
|
||||
formClone.value.push({
|
||||
contest_name: item[relatedRules.contest_name.value],
|
||||
contest_organizers: item[relatedRules.contest_organizers.value],
|
||||
contest_term: item[relatedRules.contest_term.value],
|
||||
type: item[relatedRules.type.value],
|
||||
online_start: item[relatedRules.online_start.value],
|
||||
online_end: item[relatedRules.online_end.value],
|
||||
offline_start: item[relatedRules.offline_start.value],
|
||||
offline_end: item[relatedRules.offline_end.value],
|
||||
contest_start: item[relatedRules.contest_start.value],
|
||||
contest_end: item[relatedRules.contest_end.value],
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
emit("addContest", formClone.value);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
114
src/components/addNewData/contest/contestForm/multipleAdd.vue
Normal file
@@ -0,0 +1,114 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="flex flex-warp justify-center items-center font-bold"
|
||||
>
|
||||
<div style="font-size: 1rem">请输入要导入的数据数量:</div>
|
||||
<el-input-number v-model="singleFormNum" :min="1" :max="10" @change="createForm" />
|
||||
<div v-if="checkNeed"> </div>
|
||||
<el-checkbox
|
||||
v-if="checkNeed"
|
||||
v-model="checked"
|
||||
label="为所有表单进行相同操作"
|
||||
size="large"
|
||||
/>
|
||||
</div>
|
||||
<el-scrollbar max-height="40rem">
|
||||
<div class="mt-2 border-2 border-gray-300" v-for="item in input">
|
||||
<div style="font-size: 1.2rem" class="w-full text-center font-bold">
|
||||
{{ item.label }}
|
||||
</div>
|
||||
<SingleAdd ref="singleAddRef" :addData="addData" />
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
|
||||
const singleFormNum = ref(1);
|
||||
const checked = ref(true);
|
||||
const input = ref([{ label: "卡1" }]);
|
||||
const singleAddRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const props = defineProps({
|
||||
checkNeed: Boolean,
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addContest"]);
|
||||
|
||||
const initData = () => {
|
||||
setTimeout(() => {
|
||||
singleAddRef.value.forEach((item) => {});
|
||||
}, 0);
|
||||
};
|
||||
|
||||
const createForm = () => {
|
||||
let difference = Math.abs(singleFormNum.value - input.value.length);
|
||||
for (let i = 0; i < difference; i++) {
|
||||
if (singleFormNum.value > input.value.length) {
|
||||
input.value.push({ label: `卡${input.value.length + 1}` });
|
||||
} else if (singleFormNum.value < input.value.length) {
|
||||
input.value.pop();
|
||||
}
|
||||
}
|
||||
if (checked.value) {
|
||||
initData();
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!singleAddRef) return;
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.resetCheckForm();
|
||||
});
|
||||
singleFormNum.value = 1;
|
||||
createForm();
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (!singleAddRef) return;
|
||||
let valid = true;
|
||||
formClone.value = [];
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.validate().then((result) => {
|
||||
if (result) {
|
||||
formClone.value.push({ ...element.ruleForm });
|
||||
} else {
|
||||
valid = result;
|
||||
}
|
||||
});
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (valid) {
|
||||
emit("addContest", formClone.value);
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.resetCheckForm();
|
||||
});
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
}, 0);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
|
||||
watch(checked, (value) => {
|
||||
if (value) {
|
||||
initData();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
227
src/components/addNewData/contest/contestForm/singleAdd.vue
Normal file
@@ -0,0 +1,227 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="竞赛名称" prop="contest_name">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入竞赛名称"
|
||||
v-model="ruleForm.contest_name"
|
||||
@input="filter(ruleForm.contest_name, 'contest_name')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="竞赛主办方" prop="contest_organizers">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入竞赛主办方"
|
||||
v-model="ruleForm.contest_organizers"
|
||||
@input="filter(ruleForm.contest_organizers, 'contest_organizers')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="竞赛届数" prop="contest_term">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入竞赛届数"
|
||||
v-model="ruleForm.contest_term"
|
||||
@input="filter(ruleForm.contest_term, 'contest_term')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="竞赛类型" prop="type">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择竞赛类型"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.type"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in addData.typeOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="线上赛起止时间">
|
||||
<el-col :span="11">
|
||||
<el-form-item prop="online_start">
|
||||
<el-date-picker
|
||||
v-model="ruleForm.online_start"
|
||||
type="datetime"
|
||||
placeholder="请选择线上赛开始时间"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="2" class="text-center">
|
||||
<span class="text-gray-500">-</span>
|
||||
</el-col>
|
||||
<el-col :span="11">
|
||||
<el-form-item prop="online_end">
|
||||
<el-date-picker
|
||||
v-model="ruleForm.online_end"
|
||||
type="datetime"
|
||||
placeholder="请选择线上赛结束时间"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="线下赛起止时间">
|
||||
<el-col :span="11">
|
||||
<el-form-item prop="offline_start">
|
||||
<el-date-picker
|
||||
v-model="ruleForm.offline_start"
|
||||
type="datetime"
|
||||
placeholder="请选择线下赛开始时间"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="2" class="text-center">
|
||||
<span class="text-gray-500">-</span>
|
||||
</el-col>
|
||||
<el-col :span="11">
|
||||
<el-form-item prop="offline_end">
|
||||
<el-date-picker
|
||||
v-model="ruleForm.offline_end"
|
||||
type="datetime"
|
||||
placeholder="请选择线下赛结束时间"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="竞赛起止时间">
|
||||
<el-col :span="11">
|
||||
<el-form-item prop="contest_start">
|
||||
<el-date-picker
|
||||
v-model="ruleForm.contest_start"
|
||||
type="datetime"
|
||||
placeholder="请选择竞赛开始时间"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="2" class="text-center">
|
||||
<span class="text-gray-500">-</span>
|
||||
</el-col>
|
||||
<el-col :span="11">
|
||||
<el-form-item prop="contest_end">
|
||||
<el-date-picker
|
||||
v-model="ruleForm.contest_end"
|
||||
type="datetime"
|
||||
placeholder="请选择竞赛结束时间"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
const props = defineProps({
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const ruleFormRef = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
contest_name: "",
|
||||
contest_organizers: "",
|
||||
contest_term: "",
|
||||
type: "",
|
||||
online_start: "",
|
||||
online_end: "",
|
||||
offline_start: "",
|
||||
offline_end: "",
|
||||
contest_start: "",
|
||||
contest_end: "",
|
||||
});
|
||||
|
||||
const formClone = ref({});
|
||||
|
||||
const rules = reactive({
|
||||
contest_name: [{ required: true, message: "请输入竞赛名称", trigger: "blur" }],
|
||||
contest_organizers: [{ required: true, message: "请输入竞赛主办方", trigger: "blur" }],
|
||||
contest_term: [{ required: true, message: "请输入竞赛届数", trigger: "blur" }],
|
||||
type: [{ required: true, message: "请选择竞赛类型", trigger: "change" }],
|
||||
online_start: [
|
||||
{ type: "date", required: true, message: "线上赛开始时间", trigger: "change" },
|
||||
],
|
||||
online_end: [
|
||||
{ type: "date", required: true, message: "线上赛结束时间", trigger: "change" },
|
||||
],
|
||||
offline_start: [
|
||||
{ type: "date", required: true, message: "线下赛开始时间", trigger: "change" },
|
||||
],
|
||||
offline_end: [
|
||||
{ type: "date", required: true, message: "线下赛结束时间", trigger: "change" },
|
||||
],
|
||||
contest_start: [
|
||||
{ type: "date", required: true, message: "竞赛开始时间", trigger: "change" },
|
||||
],
|
||||
contest_end: [
|
||||
{ type: "date", required: true, message: "竞赛结束时间", trigger: "change" },
|
||||
],
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addContest"]);
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!ruleFormRef) return;
|
||||
ruleFormRef.value.resetFields();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!ruleFormRef) return;
|
||||
await ruleFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
formClone.value = { ...ruleForm };
|
||||
emit("addContest", [formClone.value]);
|
||||
ruleFormRef.value.resetFields();
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const validate = () => {
|
||||
if (!ruleFormRef) return Promise.resolve(false);
|
||||
return new Promise((resolve) => {
|
||||
ruleFormRef.value.validate((valid) => {
|
||||
resolve(valid);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, validate, ruleForm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
112
src/components/addNewData/insidersForm/excleAdd.vue
Normal file
@@ -0,0 +1,112 @@
|
||||
<template>
|
||||
<UploadFile
|
||||
ref="uploadFileRef"
|
||||
:options="options"
|
||||
:relatedRules="relatedRules"
|
||||
:relatedOptions="relatedOptions"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import UploadFile from "../../operate/uploadFile.vue";
|
||||
|
||||
const uploadFileRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const options = {
|
||||
limit: 1,
|
||||
accept: ".xlsx",
|
||||
action: "",
|
||||
multiple: false,
|
||||
listType: "text",
|
||||
autoUpload: false,
|
||||
};
|
||||
|
||||
const relatedRules = {
|
||||
role: {
|
||||
value: "",
|
||||
label: "账号角色",
|
||||
},
|
||||
name: {
|
||||
value: "",
|
||||
label: "员工姓名",
|
||||
},
|
||||
department: {
|
||||
value: "",
|
||||
label: "所属部门",
|
||||
},
|
||||
change: {
|
||||
value: "",
|
||||
label: "账号信息变更描述",
|
||||
},
|
||||
};
|
||||
|
||||
const relatedOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "账号角色",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "员工姓名",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "所属部门",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "3",
|
||||
label: "账号信息变更描述",
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
|
||||
const emit = defineEmits(["addInsiders"]);
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!uploadFileRef) return;
|
||||
uploadFileRef.value.handleExceed();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!uploadFileRef) return;
|
||||
formClone.value = [];
|
||||
const length = uploadFileRef.value.loadData.length;
|
||||
if (length == 0) return ElMessage.error("请先上传文件!");
|
||||
const flag = await uploadFileRef.value.confirm();
|
||||
if (!flag) return ElMessage.error("请先选择表格关联项!");
|
||||
ElMessage({
|
||||
message: `正在上传数据中,请稍等...`,
|
||||
type: "success",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uploadFileRef.value.loadData.forEach((ExcleForm) => {
|
||||
ExcleForm.forEach((worksheet) => {
|
||||
let context = [...worksheet];
|
||||
context.shift();
|
||||
context.forEach((item) => {
|
||||
if (item.length != 0) {
|
||||
formClone.value.push({
|
||||
role: item[relatedRules.role.value],
|
||||
name: item[relatedRules.name.value],
|
||||
department: item[relatedRules.department.value],
|
||||
change: item[relatedRules.change.value],
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
emit("addInsiders", formClone.value);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
166
src/components/addNewData/insidersForm/insidersForm.vue
Normal file
@@ -0,0 +1,166 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="resetCheckForm"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ title }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<FormTools @showTools="showTools" :dialogObj="insidersMsgActive" />
|
||||
<SingleAdd
|
||||
ref="singleAddRef"
|
||||
v-if="dialogSingleVisible"
|
||||
:addData="addData"
|
||||
@addInsiders="addInsiders"
|
||||
/>
|
||||
<MultipleAdd
|
||||
ref="multipleAddRef"
|
||||
v-if="dialogMultipleVisible"
|
||||
:addData="addData"
|
||||
:checkNeed="true"
|
||||
@addInsiders="addInsiders"
|
||||
/>
|
||||
<ExcleAdd ref="excleAddRef" v-if="dialogExcleVisible" @addInsiders="addInsiders" />
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm"> 取消 </el-button>
|
||||
<el-button style="font-weight: bold" type="primary" @click="confirm">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import FormTools from "../../operate/formTools.vue";
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
import MultipleAdd from "./multipleAdd.vue";
|
||||
import ExcleAdd from "./excleAdd.vue";
|
||||
|
||||
import insidersActiveStore from "../../../stores/insiders";
|
||||
|
||||
import $http from "../../../api/index";
|
||||
import $url from "../../../api/url";
|
||||
|
||||
import { encrypt } from "../../../utils/aes";
|
||||
|
||||
const insidersMsgActive = insidersActiveStore();
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const singleAddRef = ref(null);
|
||||
const multipleAddRef = ref(null);
|
||||
const excleAddRef = ref(null);
|
||||
const dialogSingleVisible = ref(true);
|
||||
const dialogMultipleVisible = ref(false);
|
||||
const dialogExcleVisible = ref(false);
|
||||
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["reloadData"]);
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "single":
|
||||
dialogSingleVisible.value = true;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = false;
|
||||
insidersMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
insidersMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
insidersMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "multiple":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = true;
|
||||
dialogExcleVisible.value = false;
|
||||
insidersMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
insidersMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
insidersMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "excle":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = true;
|
||||
insidersMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
insidersMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
insidersMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.resetCheckForm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.resetCheckForm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.resetCheckForm();
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.confirm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.confirm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.confirm();
|
||||
}
|
||||
};
|
||||
|
||||
const addInsiders = (requestMsg) => {
|
||||
requestMsg.forEach((element) => {
|
||||
element.role = encrypt(String(element.role));
|
||||
element.name = encrypt(String(element.name));
|
||||
element.department =
|
||||
element.department == "" ? "" : encrypt(String(element.department));
|
||||
element.change = encrypt(String(element.change));
|
||||
});
|
||||
const data = { requestMsg };
|
||||
$http.post($url.addInsiders, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
resetCheckForm();
|
||||
ElMessage({
|
||||
message: "新增公司员工成功!",
|
||||
type: "success",
|
||||
});
|
||||
emit("reloadData");
|
||||
} else {
|
||||
ElMessage.error("新增公司员工失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ dialogVisible });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
116
src/components/addNewData/insidersForm/multipleAdd.vue
Normal file
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="flex flex-warp justify-center items-center font-bold"
|
||||
>
|
||||
<div style="font-size: 1rem">请输入要导入的数据数量:</div>
|
||||
<el-input-number v-model="singleFormNum" :min="1" :max="10" @change="createForm" />
|
||||
<div v-if="checkNeed"> </div>
|
||||
<el-checkbox
|
||||
v-if="checkNeed"
|
||||
v-model="checked"
|
||||
label="为所有表单进行相同操作"
|
||||
size="large"
|
||||
/>
|
||||
</div>
|
||||
<el-scrollbar max-height="40rem">
|
||||
<div class="mt-2 border-2 border-gray-300" v-for="item in input">
|
||||
<div style="font-size: 1.2rem" class="w-full text-center font-bold">
|
||||
{{ item.label }}
|
||||
</div>
|
||||
<SingleAdd ref="singleAddRef" :addData="addData" />
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
|
||||
const singleFormNum = ref(1);
|
||||
const checked = ref(true);
|
||||
const input = ref([{ label: "卡1" }]);
|
||||
const singleAddRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const props = defineProps({
|
||||
addData: Object,
|
||||
checkNeed: Boolean,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addInsiders"]);
|
||||
|
||||
const initData = () => {
|
||||
setTimeout(() => {
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.ruleForm.role = singleAddRef.value[0].ruleForm.role;
|
||||
});
|
||||
}, 0);
|
||||
};
|
||||
|
||||
const createForm = () => {
|
||||
let difference = Math.abs(singleFormNum.value - input.value.length);
|
||||
for (let i = 0; i < difference; i++) {
|
||||
if (singleFormNum.value > input.value.length) {
|
||||
input.value.push({ label: `卡${input.value.length + 1}` });
|
||||
} else if (singleFormNum.value < input.value.length) {
|
||||
input.value.pop();
|
||||
}
|
||||
}
|
||||
if (checked.value) {
|
||||
initData();
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!singleAddRef) return;
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.resetCheckForm();
|
||||
});
|
||||
singleFormNum.value = 1;
|
||||
createForm();
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (!singleAddRef) return;
|
||||
let valid = true;
|
||||
formClone.value = [];
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.validate().then((result) => {
|
||||
if (result) {
|
||||
formClone.value.push({ ...element.ruleForm });
|
||||
} else {
|
||||
valid = result;
|
||||
}
|
||||
});
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (valid) {
|
||||
emit("addInsiders", formClone.value);
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.resetCheckForm();
|
||||
});
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
}, 0);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
|
||||
watch(checked, (value) => {
|
||||
if (value) {
|
||||
initData();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
127
src/components/addNewData/insidersForm/singleAdd.vue
Normal file
@@ -0,0 +1,127 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="账号角色" prop="role">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择账号角色"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.role"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in addData.roleOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="员工姓名" prop="name">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入员工姓名"
|
||||
v-model="ruleForm.name"
|
||||
@input="filter(ruleForm.name, 'name')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="员工所属部门" prop="department">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入员工所属部门"
|
||||
v-model="ruleForm.department"
|
||||
@input="filter(ruleForm.department, 'department')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="账号信息变更描述" prop="change">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入账号信息变更描述"
|
||||
v-model="ruleForm.change"
|
||||
@input="filter(ruleForm.change, 'change')"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
const ruleFormRef = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
role: "",
|
||||
name: "",
|
||||
department: "",
|
||||
change: "",
|
||||
});
|
||||
|
||||
const props = defineProps({
|
||||
addData: Object,
|
||||
});
|
||||
|
||||
const formClone = ref({});
|
||||
|
||||
const rules = reactive({
|
||||
role: [{ required: true, message: "请选择账号角色", trigger: "blur" }],
|
||||
name: [{ required: true, message: "请输入员工姓名", trigger: "blur" }],
|
||||
change: [{ required: true, message: "请输入账号信息变更描述", trigger: "blur" }],
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addInsiders"]);
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!ruleFormRef) return;
|
||||
ruleFormRef.value.resetFields();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!ruleFormRef) return;
|
||||
await ruleFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
formClone.value = { ...ruleForm };
|
||||
emit("addInsiders", [formClone.value]);
|
||||
ruleFormRef.value.resetFields();
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const validate = () => {
|
||||
if (!ruleFormRef) return Promise.resolve(false);
|
||||
return new Promise((resolve) => {
|
||||
ruleFormRef.value.validate((valid) => {
|
||||
resolve(valid);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, validate, ruleForm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
142
src/components/addNewData/organizationForm/excleAdd.vue
Normal file
@@ -0,0 +1,142 @@
|
||||
<template>
|
||||
<UploadFile
|
||||
ref="uploadFileRef"
|
||||
:options="options"
|
||||
:relatedRules="relatedRules"
|
||||
:relatedOptions="relatedOptions"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import UploadFile from "../../operate/uploadFile.vue";
|
||||
|
||||
const uploadFileRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const options = {
|
||||
limit: 1,
|
||||
accept: ".xlsx",
|
||||
action: "",
|
||||
multiple: false,
|
||||
listType: "text",
|
||||
autoUpload: false,
|
||||
};
|
||||
|
||||
const relatedRules = {
|
||||
organization_name: {
|
||||
value: "",
|
||||
label: "单位名称",
|
||||
},
|
||||
address: {
|
||||
value: "",
|
||||
label: "通信地址",
|
||||
},
|
||||
liaison_name: {
|
||||
value: "",
|
||||
label: "单位联系人姓名",
|
||||
},
|
||||
phone: {
|
||||
value: "",
|
||||
label: "联系人手机号码",
|
||||
},
|
||||
email: {
|
||||
value: "",
|
||||
label: "单位电子邮箱地址",
|
||||
},
|
||||
other_information: {
|
||||
value: "",
|
||||
label: "其他信息",
|
||||
},
|
||||
post_code: {
|
||||
value: "",
|
||||
label: "邮政编码",
|
||||
},
|
||||
};
|
||||
|
||||
const relatedOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "单位名称",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "通信地址",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "单位联系人姓名",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "3",
|
||||
label: "联系人手机号码",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "4",
|
||||
label: "单位电子邮箱地址",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "5",
|
||||
label: "其他信息",
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
value: "6",
|
||||
label: "邮政编码",
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
|
||||
const emit = defineEmits(["addOrganization"]);
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!uploadFileRef) return;
|
||||
uploadFileRef.value.handleExceed();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!uploadFileRef) return;
|
||||
formClone.value = [];
|
||||
const length = uploadFileRef.value.loadData.length;
|
||||
if (length == 0) return ElMessage.error("请先上传文件!");
|
||||
const flag = await uploadFileRef.value.confirm();
|
||||
if (!flag) return ElMessage.error("请先选择表格关联项!");
|
||||
ElMessage({
|
||||
message: `正在上传数据中,请稍等...`,
|
||||
type: "success",
|
||||
});
|
||||
setTimeout(() => {
|
||||
uploadFileRef.value.loadData.forEach((ExcleForm) => {
|
||||
ExcleForm.forEach((worksheet) => {
|
||||
let context = [...worksheet];
|
||||
context.shift();
|
||||
context.forEach((item) => {
|
||||
if (item.length != 0) {
|
||||
formClone.value.push({
|
||||
organization_name: item[relatedRules.organization_name.value],
|
||||
address: item[relatedRules.address.value],
|
||||
liaison_name: item[relatedRules.liaison_name.value],
|
||||
phone: item[relatedRules.phone.value],
|
||||
email: item[relatedRules.email.value],
|
||||
other_information: item[relatedRules.other_information.value],
|
||||
post_code: item[relatedRules.post_code.value],
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
emit("addOrganization", formClone.value);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
111
src/components/addNewData/organizationForm/multipleAdd.vue
Normal file
@@ -0,0 +1,111 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="flex flex-warp justify-center items-center font-bold"
|
||||
>
|
||||
<div style="font-size: 1rem">请输入要导入的数据数量:</div>
|
||||
<el-input-number v-model="singleFormNum" :min="1" :max="10" @change="createForm" />
|
||||
<div v-if="checkNeed"> </div>
|
||||
<el-checkbox v-if="checkNeed" v-model="checked" label="为所有表单进行相同操作" size="large" />
|
||||
</div>
|
||||
<el-scrollbar max-height="40rem">
|
||||
<div class="mt-2 border-2 border-gray-300" v-for="item in input">
|
||||
<div style="font-size: 1.2rem" class="w-full text-center font-bold">
|
||||
{{ item.label }}
|
||||
</div>
|
||||
<SingleAdd
|
||||
ref="singleAddRef"
|
||||
/>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
|
||||
const singleFormNum = ref(1);
|
||||
const checked = ref(true);
|
||||
const input = ref([{ label: "卡1" }]);
|
||||
const singleAddRef = ref(null);
|
||||
const formClone = ref([]);
|
||||
|
||||
const props = defineProps({
|
||||
checkNeed: Boolean
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addOrganization"]);
|
||||
|
||||
const initData = () => {
|
||||
setTimeout(() => {
|
||||
singleAddRef.value.forEach((item) => {
|
||||
});
|
||||
}, 0);
|
||||
};
|
||||
|
||||
const createForm = () => {
|
||||
let difference = Math.abs(singleFormNum.value - input.value.length);
|
||||
for (let i = 0; i < difference; i++) {
|
||||
if (singleFormNum.value > input.value.length) {
|
||||
input.value.push({ label: `卡${input.value.length + 1}` });
|
||||
} else if (singleFormNum.value < input.value.length) {
|
||||
input.value.pop();
|
||||
}
|
||||
}
|
||||
if(checked.value) {
|
||||
initData();
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!singleAddRef) return;
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.resetCheckForm();
|
||||
});
|
||||
singleFormNum.value = 1;
|
||||
createForm();
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (!singleAddRef) return;
|
||||
let valid = true;
|
||||
formClone.value = [];
|
||||
singleAddRef.value.forEach((element) => {
|
||||
element.validate().then((result) => {
|
||||
if (result) {
|
||||
formClone.value.push({ ...element.ruleForm });
|
||||
} else {
|
||||
valid = result;
|
||||
}
|
||||
});
|
||||
});
|
||||
setTimeout(() => {
|
||||
if (valid) {
|
||||
emit("addOrganization", formClone.value);
|
||||
singleAddRef.value.forEach((item) => {
|
||||
item.resetCheckForm();
|
||||
});
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
}, 0);
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, formClone });
|
||||
|
||||
watch(checked, (value) => {
|
||||
if(value) {
|
||||
initData();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
171
src/components/addNewData/organizationForm/organizationForm.vue
Normal file
@@ -0,0 +1,171 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="resetCheckForm"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ title }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<FormTools @showTools="showTools" :dialogObj="organizationMsgActive" />
|
||||
<SingleAdd
|
||||
ref="singleAddRef"
|
||||
v-if="dialogSingleVisible"
|
||||
@addOrganization="addOrganization"
|
||||
/>
|
||||
<MultipleAdd
|
||||
ref="multipleAddRef"
|
||||
v-if="dialogMultipleVisible"
|
||||
:checkNeed="false"
|
||||
@addOrganization="addOrganization"
|
||||
/>
|
||||
<ExcleAdd
|
||||
ref="excleAddRef"
|
||||
v-if="dialogExcleVisible"
|
||||
@addOrganization="addOrganization"
|
||||
/>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm"> 取消 </el-button>
|
||||
<el-button style="font-weight: bold" type="primary" @click="confirm">
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import FormTools from "../../operate/formTools.vue";
|
||||
import SingleAdd from "./singleAdd.vue";
|
||||
import MultipleAdd from "./multipleAdd.vue";
|
||||
import ExcleAdd from "./excleAdd.vue";
|
||||
|
||||
import organizationActiveStore from "../../../stores/organization";
|
||||
|
||||
import $http from "../../../api/index";
|
||||
import $url from "../../../api/url";
|
||||
|
||||
import { encrypt } from "../../../utils/aes";
|
||||
|
||||
const organizationMsgActive = organizationActiveStore();
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const singleAddRef = ref(null);
|
||||
const multipleAddRef = ref(null);
|
||||
const excleAddRef = ref(null);
|
||||
const dialogSingleVisible = ref(true);
|
||||
const dialogMultipleVisible = ref(false);
|
||||
const dialogExcleVisible = ref(false);
|
||||
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["reloadData"]);
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "single":
|
||||
dialogSingleVisible.value = true;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = false;
|
||||
organizationMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
organizationMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
organizationMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "multiple":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = true;
|
||||
dialogExcleVisible.value = false;
|
||||
organizationMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
organizationMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
organizationMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
case "excle":
|
||||
dialogSingleVisible.value = false;
|
||||
dialogMultipleVisible.value = false;
|
||||
dialogExcleVisible.value = true;
|
||||
organizationMsgActive.dialogSingleVisible = dialogSingleVisible.value;
|
||||
organizationMsgActive.dialogMultipleVisible = dialogMultipleVisible.value;
|
||||
organizationMsgActive.dialogExcleVisible = dialogExcleVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.resetCheckForm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.resetCheckForm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.resetCheckForm();
|
||||
}
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (dialogSingleVisible.value) {
|
||||
singleAddRef.value.confirm();
|
||||
} else if (dialogMultipleVisible.value) {
|
||||
multipleAddRef.value.confirm();
|
||||
} else if (dialogExcleVisible.value) {
|
||||
excleAddRef.value.confirm();
|
||||
}
|
||||
};
|
||||
|
||||
const addOrganization = (requestMsg) => {
|
||||
requestMsg.forEach((element) => {
|
||||
element.organization_name = encrypt(String(element.organization_name));
|
||||
element.address = element.address == "" ? "" : encrypt(String(element.address));
|
||||
element.liaison_name =
|
||||
element.liaison_name == "" ? "" : encrypt(String(element.liaison_name));
|
||||
element.phone = element.phone == "" ? "" : encrypt(String(element.phone));
|
||||
element.email = element.email == "" ? "" : encrypt(String(element.email));
|
||||
element.other_information =
|
||||
element.other_information == "" ? "" : encrypt(String(element.other_information));
|
||||
element.post_code = element.post_code == "" ? "" : encrypt(String(element.post_code));
|
||||
});
|
||||
const data = { requestMsg };
|
||||
$http.post($url.addOrganization, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
resetCheckForm();
|
||||
ElMessage({
|
||||
message: "新增B端单位成功!",
|
||||
type: "success",
|
||||
});
|
||||
emit("reloadData");
|
||||
} else {
|
||||
ElMessage.error("新增B端单位失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ dialogVisible });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
137
src/components/addNewData/organizationForm/singleAdd.vue
Normal file
@@ -0,0 +1,137 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="单位名称" prop="organization_name">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入单位名称"
|
||||
v-model="ruleForm.organization_name"
|
||||
@input="filter(ruleForm.organization_name, 'organization_name')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="通信地址" prop="address">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入通信地址"
|
||||
v-model="ruleForm.address"
|
||||
@input="filter(ruleForm.address, 'address')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="单位联系人姓名" prop="liaison_name">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入单位联系人姓名"
|
||||
v-model="ruleForm.liaison_name"
|
||||
@input="filter(ruleForm.liaison_name, 'liaison_name')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="联系人电话号码" prop="phone">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入联系人电话号码"
|
||||
v-model="ruleForm.phone"
|
||||
@input="filter(ruleForm.phone, 'phone')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="单位电子邮箱" prop="email">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入单位电子邮箱"
|
||||
v-model="ruleForm.email"
|
||||
@input="filter(ruleForm.email, 'email')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="其他信息" prop="other_information">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入其他信息"
|
||||
v-model="ruleForm.other_information"
|
||||
@input="filter(ruleForm.other_information, 'other_information')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="邮政编码" prop="post_code">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入邮政编码"
|
||||
v-model="ruleForm.post_code"
|
||||
@input="filter(ruleForm.post_code, 'post_code')"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
const ruleFormRef = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
organization_name: "",
|
||||
address: "",
|
||||
liaison_name: "",
|
||||
phone: "",
|
||||
email: "",
|
||||
other_information: "",
|
||||
post_code: "",
|
||||
});
|
||||
|
||||
const formClone = ref({});
|
||||
|
||||
const rules = reactive({
|
||||
organization_name: [{ required: true, message: "请输入单位名称", trigger: "blur" }],
|
||||
});
|
||||
|
||||
const emit = defineEmits(["addOrganization"]);
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
if (!ruleFormRef) return;
|
||||
ruleFormRef.value.resetFields();
|
||||
};
|
||||
|
||||
const confirm = async () => {
|
||||
if (!ruleFormRef) return;
|
||||
await ruleFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
formClone.value = { ...ruleForm };
|
||||
emit("addOrganization", [formClone.value]);
|
||||
ruleFormRef.value.resetFields();
|
||||
ElMessage({
|
||||
message: `提交成功!`,
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const validate = () => {
|
||||
if (!ruleFormRef) return Promise.resolve(false);
|
||||
return new Promise((resolve) => {
|
||||
ruleFormRef.value.validate((valid) => {
|
||||
resolve(valid);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ resetCheckForm, confirm, validate, ruleForm, formClone });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
60
src/components/aside/Menu.vue
Normal file
@@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<el-menu
|
||||
:default-active="activeIndex"
|
||||
style="background-color: rgb(250 240 210)"
|
||||
class="el-menu-vertical-demo"
|
||||
@open="handleOpen"
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-menu-item
|
||||
v-for="(options, index) in menu"
|
||||
:key="options.path"
|
||||
@click="goToPage(options.path, options.id)"
|
||||
:index="index"
|
||||
:style="
|
||||
activeIndex == options.id
|
||||
? 'background-color: rgb(20 200 200);color: #fff;border-width: 2px;border-bottom-color: rgb(192 38 211);'
|
||||
: ''
|
||||
"
|
||||
>
|
||||
<el-icon><icon-menu /></el-icon>
|
||||
<span>{{ options.label }}</span>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, defineProps, onMounted } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
import activeIndexActiveStore from "../../stores/activeIndex";
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const activeIndexActive = activeIndexActiveStore();
|
||||
|
||||
const { menu } = defineProps(["menu"]);
|
||||
|
||||
const activeIndex = ref(0);
|
||||
|
||||
const handleOpen = (key, keyPath) => {
|
||||
console.log(key, keyPath);
|
||||
};
|
||||
const handleClose = (key, keyPath) => {
|
||||
console.log(key, keyPath);
|
||||
};
|
||||
|
||||
const goToPage = (page, id) => {
|
||||
activeIndex.value = id;
|
||||
activeIndexActive.asideActive = id;
|
||||
router.push({ name: page });
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
if (activeIndexActive.asideActive >= menu.length)
|
||||
activeIndexActive.asideActive = menu.length - 1;
|
||||
goToPage(menu[activeIndexActive.asideActive].path, activeIndexActive.asideActive);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
147
src/components/editData/SNForm.vue
Normal file
@@ -0,0 +1,147 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog
|
||||
v-model="operateDialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ operateLabel }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm(ruleFormRef)"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="绑定状态" prop="status">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择绑定状态"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.status"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in editData.statusOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm(ruleFormRef)">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button
|
||||
style="font-weight: bold"
|
||||
type="primary"
|
||||
@click="confirm(ruleFormRef)"
|
||||
>
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<PasswordOauth
|
||||
ref="editPasswordOauthRef"
|
||||
:operateLabel="operateLabel"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import PasswordOauth from "../operate/passwordOauth.vue";
|
||||
|
||||
const operateDialogVisible = ref(false);
|
||||
const model = ref("single");
|
||||
const ruleFormRef = ref(null);
|
||||
const editPasswordOauthRef = ref(null);
|
||||
const formElClone = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
status: "",
|
||||
});
|
||||
|
||||
const password = ref("");
|
||||
|
||||
const rules = reactive({
|
||||
status: [{ required: true, message: "请选择绑定状态", trigger: "blur" }],
|
||||
});
|
||||
|
||||
const props = defineProps({
|
||||
operateLabel: String,
|
||||
editData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["requestOperate"]);
|
||||
|
||||
const handleClose = () => {
|
||||
operateDialogVisible.value = false;
|
||||
if (!ruleFormRef) return;
|
||||
formElClone.value = ruleFormRef.value;
|
||||
formElClone.value.resetFields();
|
||||
};
|
||||
|
||||
const resetCheckForm = (formEl) => {
|
||||
operateDialogVisible.value = false;
|
||||
if (!formEl) return;
|
||||
formEl.resetFields();
|
||||
};
|
||||
|
||||
const requestOperate = () => {
|
||||
password.value = editPasswordOauthRef.value.ruleForm.password;
|
||||
emit("requestOperate");
|
||||
operateDialogVisible.value = false;
|
||||
formElClone.value.resetFields();
|
||||
};
|
||||
|
||||
const confirm = async (formEl) => {
|
||||
if (!formEl) return;
|
||||
await formEl.validate((valid) => {
|
||||
if (valid) {
|
||||
editPasswordOauthRef.value.operateDialogVisible = true;
|
||||
formElClone.value = formEl;
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ operateDialogVisible, model, ruleForm, password });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
147
src/components/editData/bdCardForm.vue
Normal file
@@ -0,0 +1,147 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog
|
||||
v-model="operateDialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ operateLabel }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm(ruleFormRef)"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="白名单类型" prop="type">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择白名单类型"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.type"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in editData.typeOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm(ruleFormRef)">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button
|
||||
style="font-weight: bold"
|
||||
type="primary"
|
||||
@click="confirm(ruleFormRef)"
|
||||
>
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<PasswordOauth
|
||||
ref="editPasswordOauthRef"
|
||||
:operateLabel="operateLabel"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import PasswordOauth from "../operate/passwordOauth.vue";
|
||||
|
||||
const operateDialogVisible = ref(false);
|
||||
const model = ref("single");
|
||||
const ruleFormRef = ref(null);
|
||||
const editPasswordOauthRef = ref(null);
|
||||
const formElClone = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
type: "",
|
||||
});
|
||||
|
||||
const password = ref("");
|
||||
|
||||
const rules = reactive({
|
||||
type: [{ required: true, message: "请选择白名单类型", trigger: "blur" }],
|
||||
});
|
||||
|
||||
const props = defineProps({
|
||||
operateLabel: String,
|
||||
editData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["requestOperate"]);
|
||||
|
||||
const handleClose = () => {
|
||||
operateDialogVisible.value = false;
|
||||
if (!ruleFormRef) return;
|
||||
formElClone.value = ruleFormRef.value;
|
||||
formElClone.value.resetFields();
|
||||
};
|
||||
|
||||
const resetCheckForm = (formEl) => {
|
||||
operateDialogVisible.value = false;
|
||||
if (!formEl) return;
|
||||
formEl.resetFields();
|
||||
};
|
||||
|
||||
const requestOperate = () => {
|
||||
password.value = editPasswordOauthRef.value.ruleForm.password;
|
||||
emit("requestOperate");
|
||||
operateDialogVisible.value = false;
|
||||
formElClone.value.resetFields();
|
||||
};
|
||||
|
||||
const confirm = async (formEl) => {
|
||||
if (!formEl) return;
|
||||
await formEl.validate((valid) => {
|
||||
if (valid) {
|
||||
editPasswordOauthRef.value.operateDialogVisible = true;
|
||||
formElClone.value = formEl;
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ operateDialogVisible, model, ruleForm, password });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
204
src/components/editData/bsideForm.vue
Normal file
@@ -0,0 +1,204 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog
|
||||
v-model="operateDialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ operateLabel }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm(ruleFormRef)"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="账号状态" prop="status">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择账号状态"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.status"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in editData.statusOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="账号角色" prop="role">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择账号角色"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.role"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in editData.roleOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="用户单位" prop="organization">
|
||||
<RemoteSearch
|
||||
ref="remoteSearchRef"
|
||||
@searchResult="searchResult"
|
||||
:disabled="false"
|
||||
searchKey="organization_name"
|
||||
:timeBefor="createdAt"
|
||||
@handleSelect="handleSelect"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm(ruleFormRef)">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button
|
||||
style="font-weight: bold"
|
||||
type="primary"
|
||||
@click="confirm(ruleFormRef)"
|
||||
>
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- <PasswordOauth
|
||||
ref="editPasswordOauthRef"
|
||||
:operateLabel="operateLabel"
|
||||
@requestOperate="requestOperate"
|
||||
/> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
// import PasswordOauth from "../operate/passwordOauth.vue";
|
||||
import RemoteSearch from "../search/remoteSearch.vue";
|
||||
|
||||
const operateDialogVisible = ref(false);
|
||||
const model = ref("single");
|
||||
const ruleFormRef = ref(null);
|
||||
// const editPasswordOauthRef = ref(null);
|
||||
const remoteSearchRef = ref(null);
|
||||
const formElClone = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
status: "",
|
||||
role: "",
|
||||
organization: "",
|
||||
});
|
||||
|
||||
const password = ref("");
|
||||
|
||||
const rules = reactive({});
|
||||
|
||||
const props = defineProps({
|
||||
operateLabel: String,
|
||||
editData: Object,
|
||||
createdAt: String,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["requestOperate", "remoteSearch"]);
|
||||
|
||||
const searchResult = (data, searchKey, timeBefor) => {
|
||||
emit("remoteSearch", data, searchKey, timeBefor, "edit");
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
operateDialogVisible.value = false;
|
||||
if (!ruleFormRef) return;
|
||||
formElClone.value = ruleFormRef.value;
|
||||
formElClone.value.resetFields();
|
||||
remoteSearchRef.value.clearValue();
|
||||
};
|
||||
|
||||
const resetCheckForm = (formEl) => {
|
||||
operateDialogVisible.value = false;
|
||||
if (!formEl) return;
|
||||
formEl.resetFields();
|
||||
remoteSearchRef.value.clearValue();
|
||||
};
|
||||
|
||||
// const requestOperate = () => {
|
||||
// password.value = editPasswordOauthRef.value.ruleForm.password;
|
||||
// emit("requestOperate");
|
||||
// operateDialogVisible.value = false;
|
||||
// formElClone.value.resetFields();
|
||||
// remoteSearchRef.value.clearValue();
|
||||
// };
|
||||
|
||||
const handleSelect = () => {
|
||||
ruleForm.organization = remoteSearchRef.value.keyValue;
|
||||
};
|
||||
|
||||
const confirm = async (formEl) => {
|
||||
if (!formEl) return;
|
||||
await formEl.validate((valid) => {
|
||||
let FormNull = false;
|
||||
for (const element in ruleForm) {
|
||||
if (ruleForm[element] !== "" && ruleForm[element] !== undefined) {
|
||||
FormNull = true;
|
||||
}
|
||||
}
|
||||
if (valid && FormNull) {
|
||||
// editPasswordOauthRef.value.operateDialogVisible = true;
|
||||
formElClone.value = formEl;
|
||||
emit("requestOperate");
|
||||
operateDialogVisible.value = false;
|
||||
formElClone.value.resetFields();
|
||||
remoteSearchRef.value.clearValue();
|
||||
} else {
|
||||
if (!FormNull) {
|
||||
ElMessage.error("请先编辑数据!");
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ remoteSearchRef, model, operateDialogVisible, ruleForm, password });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
407
src/components/editData/businessForm.vue
Normal file
@@ -0,0 +1,407 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog
|
||||
v-model="operateDialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ operateLabel }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm(ruleFormRef)"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item
|
||||
v-if="model == 'single' ? true : false"
|
||||
class="mx-1 font-bold"
|
||||
label="业务随机盐"
|
||||
prop="salt"
|
||||
>
|
||||
<el-switch
|
||||
v-model="ruleForm.salt"
|
||||
class="ml-2"
|
||||
inline-prompt
|
||||
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
|
||||
active-text="更改当前业务随机盐"
|
||||
inactive-text="保持当前业务随机盐"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="model == 'single' ? true : false"
|
||||
class="mx-1 font-bold"
|
||||
label="业务登录网址"
|
||||
prop="login_url"
|
||||
>
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入业务登录网址"
|
||||
v-model="ruleForm.login_url"
|
||||
@input="filter(ruleForm.login_url, 'login_url')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="model == 'single' ? true : false"
|
||||
class="mx-1 font-bold"
|
||||
label="业务网址"
|
||||
prop="client_url"
|
||||
>
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入业务网址"
|
||||
v-model="ruleForm.client_url"
|
||||
@input="filter(ruleForm.client_url, 'client_url')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="model == 'single' ? true : false"
|
||||
class="mx-1 font-bold"
|
||||
label="业务临时标识"
|
||||
prop="temporary_id"
|
||||
>
|
||||
<el-switch
|
||||
v-model="switched"
|
||||
class="ml-2"
|
||||
inline-prompt
|
||||
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
|
||||
active-text="更改当前业务临时标识"
|
||||
inactive-text="保持当前业务临时标识"
|
||||
@change="switchChange"
|
||||
/>
|
||||
<div> </div>
|
||||
<el-checkbox
|
||||
:disabled="!switched"
|
||||
v-model="checked"
|
||||
label="随机生成业务临时标识"
|
||||
size="large"
|
||||
@change="checkedChange"
|
||||
/>
|
||||
<div v-if="checkedText"> </div>
|
||||
<div v-if="checkedText" class="text-red-500 font-black">
|
||||
请搜索并使用业务临时标识
|
||||
</div>
|
||||
<RemoteSearch
|
||||
ref="remoteSearchRef"
|
||||
@searchResult="searchResult"
|
||||
:disabled="!switched ? true : checked"
|
||||
searchKey="name"
|
||||
:timeBefor="ruleForm.created_at"
|
||||
@handleSelect="handleSelect"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="model == 'single' ? true : false"
|
||||
class="mx-1 font-bold"
|
||||
label="业务ID"
|
||||
prop="client_id"
|
||||
>
|
||||
<el-switch
|
||||
v-model="ruleForm.client_id"
|
||||
class="ml-2"
|
||||
inline-prompt
|
||||
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
|
||||
active-text="更改当前业务ID"
|
||||
inactive-text="保持当前业务ID"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="model == 'single' ? true : false"
|
||||
class="mx-1 font-bold"
|
||||
label="业务密钥"
|
||||
prop="client_secret"
|
||||
>
|
||||
<el-switch
|
||||
v-model="ruleForm.client_secret"
|
||||
class="ml-2"
|
||||
inline-prompt
|
||||
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
|
||||
active-text="更改当前业务密钥"
|
||||
inactive-text="保持当前业务密钥"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="model == 'single' ? true : false"
|
||||
class="mx-1 font-bold"
|
||||
label="业务名称"
|
||||
prop="name"
|
||||
>
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入业务名称"
|
||||
v-model="ruleForm.name"
|
||||
@input="filter(ruleForm.name, 'name')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="业务类型" prop="type">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择业务类型"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.type"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in editData.typeOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="业务等级" prop="level">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择业务等级"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.level"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in editData.levelOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="业务状态" prop="status">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择业务状态"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.status"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in editData.statusOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm(ruleFormRef)">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button
|
||||
style="font-weight: bold"
|
||||
type="primary"
|
||||
@click="confirm(ruleFormRef)"
|
||||
>
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<PasswordOauth
|
||||
ref="editPasswordOauthRef"
|
||||
:operateLabel="operateLabel"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import PasswordOauth from "../operate/passwordOauth.vue";
|
||||
import RemoteSearch from "../search/remoteSearch.vue";
|
||||
|
||||
const operateDialogVisible = ref(false);
|
||||
const model = ref("single");
|
||||
const ruleFormRef = ref(null);
|
||||
const editPasswordOauthRef = ref(null);
|
||||
const switched = ref(false);
|
||||
const checked = ref(false);
|
||||
const checkedText = ref(false);
|
||||
const remoteSearchRef = ref(null);
|
||||
const formElClone = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
salt: false,
|
||||
login_url: "",
|
||||
client_url: "",
|
||||
temporary_id: false,
|
||||
client_id: false,
|
||||
client_secret: false,
|
||||
name: "",
|
||||
type: "",
|
||||
level: "",
|
||||
status: "",
|
||||
created_at: "",
|
||||
});
|
||||
|
||||
const password = ref("");
|
||||
|
||||
const rules = reactive({});
|
||||
|
||||
const props = defineProps({
|
||||
operateLabel: String,
|
||||
editData: Object,
|
||||
createdAt: String,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["requestOperate", "remoteSearch"]);
|
||||
|
||||
const searchResult = (data, searchKey, timeBefor) => {
|
||||
emit("remoteSearch", data, searchKey, timeBefor, "edit");
|
||||
};
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const switchChange = (value) => {
|
||||
if (!value) {
|
||||
ruleForm.temporary_id = false;
|
||||
remoteSearchRef.value.clearValue();
|
||||
checkedText.value = false;
|
||||
remoteSearchRef.value.selectStyle = "";
|
||||
} else {
|
||||
if (remoteSearchRef.value.statusHolder) {
|
||||
checkedText.value = true;
|
||||
remoteSearchRef.value.selectStyle = "border-width: 2px; border-color: rgb(239 68 68);";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const checkedChange = (value) => {
|
||||
if (value) {
|
||||
ruleForm.temporary_id = true;
|
||||
remoteSearchRef.value.clearValue();
|
||||
checkedText.value = false;
|
||||
remoteSearchRef.value.selectStyle = "";
|
||||
} else {
|
||||
if (remoteSearchRef.value.statusHolder) {
|
||||
checkedText.value = true;
|
||||
remoteSearchRef.value.selectStyle = "border-width: 2px; border-color: rgb(239 68 68);";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const handleSelect = () => {
|
||||
ruleForm.temporary_id = remoteSearchRef.value.keyValue;
|
||||
checkedText.value = false;
|
||||
remoteSearchRef.value.selectStyle = "";
|
||||
remoteSearchRef.value.statusHolder = false;
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
operateDialogVisible.value = false;
|
||||
if (!ruleFormRef) return;
|
||||
formElClone.value = ruleFormRef.value;
|
||||
formElClone.value.resetFields();
|
||||
remoteSearchRef.value.clearValue();
|
||||
};
|
||||
|
||||
const resetCheckForm = (formEl) => {
|
||||
operateDialogVisible.value = false;
|
||||
if (!formEl) return;
|
||||
formEl.resetFields();
|
||||
remoteSearchRef.value.clearValue();
|
||||
};
|
||||
|
||||
const confirm = async (formEl) => {
|
||||
if (!formEl) return;
|
||||
await formEl.validate((valid) => {
|
||||
if (switched.value ? !checked.value : false) {
|
||||
if (ruleForm.temporary_id == undefined || ruleForm.temporary_id == false || ruleForm.temporary_id == true ) {
|
||||
valid = false;
|
||||
checkedText.value = true;
|
||||
remoteSearchRef.value.selectStyle = "border-width: 2px; border-color: rgb(239 68 68);";
|
||||
remoteSearchRef.value.statusHolder = true;
|
||||
}
|
||||
}
|
||||
if (valid) {
|
||||
checkedText.value = false;
|
||||
remoteSearchRef.value.selectStyle = "";
|
||||
editPasswordOauthRef.value.operateDialogVisible = true;
|
||||
formElClone.value = formEl;
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const originForm = (editData, options) => {
|
||||
ruleForm.login_url = editData.login_url;
|
||||
ruleForm.client_url = editData.client_url;
|
||||
ruleForm.name = editData.name;
|
||||
ruleForm.type = options.typeOptions[editData.type].value;
|
||||
ruleForm.level = options.levelOptions[editData.level].value;
|
||||
ruleForm.status = options.statusOptions[editData.status].value;
|
||||
ruleForm.created_at = editData.origin_createdAt;
|
||||
};
|
||||
|
||||
const requestOperate = () => {
|
||||
if (switched.value && checked.value) {
|
||||
ruleForm.temporary_id = "true";
|
||||
} else if (switched.value && !checked.value) {
|
||||
ruleForm.temporary_id = remoteSearchRef.value.keyValue;
|
||||
}
|
||||
password.value = editPasswordOauthRef.value.ruleForm.password;
|
||||
emit("requestOperate");
|
||||
operateDialogVisible.value = false;
|
||||
formElClone.value.resetFields();
|
||||
remoteSearchRef.value.clearValue();
|
||||
};
|
||||
|
||||
defineExpose({ remoteSearchRef, operateDialogVisible, model, ruleForm, originForm, password });
|
||||
|
||||
watch(ruleForm, (value) => {
|
||||
if (remoteSearchRef.value) {
|
||||
if (switched.value && !checked.value) {
|
||||
checkedText.value = true;
|
||||
remoteSearchRef.value.selectStyle = "border-width: 2px; border-color: rgb(239 68 68);";
|
||||
}
|
||||
if (value.temporary_id !== true && value.temporary_id !== undefined) {
|
||||
checkedText.value = false;
|
||||
remoteSearchRef.value.selectStyle = "";
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
202
src/components/editData/contest/accountForm.vue
Normal file
@@ -0,0 +1,202 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog
|
||||
v-model="operateDialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ operateLabel }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm(ruleFormRef)"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="竞赛uid" prop="contest_uid">
|
||||
<el-autocomplete
|
||||
:fetch-suggestions="searchContestUid"
|
||||
clearable
|
||||
placeholder="请输入竞赛uid"
|
||||
v-model="ruleForm.contest_uid"
|
||||
@input="filter(ruleForm.contest_uid, 'contest_uid')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="账号名称" prop="account_name">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入账号名称"
|
||||
maxlength="20"
|
||||
v-model="ruleForm.account_name"
|
||||
@input="filter(ruleForm.account_name, 'account_name')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="账号状态" prop="status">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择账号状态"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.status"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in editData.statusOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm(ruleFormRef)">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button
|
||||
style="font-weight: bold"
|
||||
type="primary"
|
||||
@click="confirm(ruleFormRef)"
|
||||
>
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- <PasswordOauth
|
||||
ref="editPasswordOauthRef"
|
||||
:operateLabel="operateLabel"
|
||||
@requestOperate="requestOperate"
|
||||
/> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import $http from "../../../api/index";
|
||||
import $url from "../../../api/url";
|
||||
|
||||
// import PasswordOauth from "../../operate/passwordOauth.vue";
|
||||
|
||||
const operateDialogVisible = ref(false);
|
||||
const model = ref("single");
|
||||
const ruleFormRef = ref(null);
|
||||
// const editPasswordOauthRef = ref(null);
|
||||
const formElClone = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
contest_uid: "",
|
||||
account_name: "",
|
||||
status: "",
|
||||
});
|
||||
|
||||
const password = ref("");
|
||||
|
||||
const searchContestUid = (value, cb) => {
|
||||
const data = {
|
||||
contest_uid: value,
|
||||
};
|
||||
$http.post($url.searchContestUid, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
cb(res.data.data);
|
||||
} else {
|
||||
cb([]);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const rules = reactive({
|
||||
contest_uid: [{ required: true, message: "请输入竞赛uid", trigger: "blur" }],
|
||||
account_name: [{ required: true, message: "请输入账号名称", trigger: "blur" }],
|
||||
status: [{ required: true, message: "请选择账号状态", trigger: "change" }],
|
||||
});
|
||||
|
||||
const props = defineProps({
|
||||
operateLabel: String,
|
||||
editData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["requestOperate"]);
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
operateDialogVisible.value = false;
|
||||
if (!ruleFormRef) return;
|
||||
formElClone.value = ruleFormRef.value;
|
||||
formElClone.value.resetFields();
|
||||
};
|
||||
|
||||
const resetCheckForm = (formEl) => {
|
||||
operateDialogVisible.value = false;
|
||||
if (!formEl) return;
|
||||
formEl.resetFields();
|
||||
};
|
||||
|
||||
// const requestOperate = () => {
|
||||
// password.value = editPasswordOauthRef.value.ruleForm.password;
|
||||
// emit("requestOperate");
|
||||
// operateDialogVisible.value = false;
|
||||
// formElClone.value.resetFields();
|
||||
// };
|
||||
|
||||
const confirm = async (formEl) => {
|
||||
if (!formEl) return;
|
||||
await formEl.validate((valid) => {
|
||||
if (valid) {
|
||||
// editPasswordOauthRef.value.operateDialogVisible = true;
|
||||
formElClone.value = formEl;
|
||||
emit("requestOperate");
|
||||
operateDialogVisible.value = false;
|
||||
formElClone.value.resetFields();
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const accountForm = (editData) => {
|
||||
ruleForm.contest_uid = editData.contest_uid;
|
||||
ruleForm.account_name = editData.account_name;
|
||||
ruleForm.status = props.editData.statusOptions[editData.status];
|
||||
};
|
||||
|
||||
defineExpose({ operateDialogVisible, model, ruleForm, accountForm, password });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
206
src/components/editData/contest/choiceTopicForm.vue
Normal file
@@ -0,0 +1,206 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog
|
||||
v-model="operateDialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ operateLabel }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm(ruleFormRef)"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="题目" prop="topic">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入题目"
|
||||
v-model="ruleForm.topic"
|
||||
@input="filter(ruleForm.topic, 'topic')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="选项A" prop="options_a">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入选项A"
|
||||
v-model="ruleForm.options_a"
|
||||
@input="filter(ruleForm.options_a, 'options_a')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="选项B" prop="options_b">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入选项B"
|
||||
v-model="ruleForm.options_b"
|
||||
@input="filter(ruleForm.options_b, 'options_b')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="选项C" prop="options_c">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入选项C"
|
||||
v-model="ruleForm.options_c"
|
||||
@input="filter(ruleForm.options_c, 'options_c')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="选项D" prop="options_d">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入选项D"
|
||||
v-model="ruleForm.options_d"
|
||||
@input="filter(ruleForm.options_d, 'options_d')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="答案" prop="answer">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入答案"
|
||||
v-model="ruleForm.answer"
|
||||
@input="filter(ruleForm.answer, 'answer')"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm(ruleFormRef)">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button
|
||||
style="font-weight: bold"
|
||||
type="primary"
|
||||
@click="confirm(ruleFormRef)"
|
||||
>
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- <PasswordOauth
|
||||
ref="editPasswordOauthRef"
|
||||
:operateLabel="operateLabel"
|
||||
@requestOperate="requestOperate"
|
||||
/> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
// import PasswordOauth from "../../operate/passwordOauth.vue";
|
||||
|
||||
const operateDialogVisible = ref(false);
|
||||
const model = ref("single");
|
||||
const ruleFormRef = ref(null);
|
||||
// const editPasswordOauthRef = ref(null);
|
||||
const formElClone = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
topic: "",
|
||||
options_a: "",
|
||||
options_b: "",
|
||||
options_c: "",
|
||||
options_d: "",
|
||||
answer: "",
|
||||
});
|
||||
|
||||
const password = ref("");
|
||||
|
||||
const rules = reactive({
|
||||
topic: [{ required: true, message: "请输入题目", trigger: "blur" }],
|
||||
options_a: [{ required: true, message: "请输入选项A", trigger: "blur" }],
|
||||
options_b: [{ required: true, message: "请输入选项B", trigger: "blur" }],
|
||||
options_c: [{ required: true, message: "请输入选项C", trigger: "blur" }],
|
||||
options_d: [{ required: true, message: "请输入选项D", trigger: "blur" }],
|
||||
answer: [{ required: true, message: "请输入答案", trigger: "blur" }],
|
||||
});
|
||||
|
||||
const props = defineProps({
|
||||
operateLabel: String,
|
||||
editData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["requestOperate"]);
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
operateDialogVisible.value = false;
|
||||
if (!ruleFormRef) return;
|
||||
formElClone.value = ruleFormRef.value;
|
||||
formElClone.value.resetFields();
|
||||
};
|
||||
|
||||
const resetCheckForm = (formEl) => {
|
||||
operateDialogVisible.value = false;
|
||||
if (!formEl) return;
|
||||
formEl.resetFields();
|
||||
};
|
||||
|
||||
// const requestOperate = () => {
|
||||
// password.value = editPasswordOauthRef.value.ruleForm.password;
|
||||
// emit("requestOperate");
|
||||
// operateDialogVisible.value = false;
|
||||
// formElClone.value.resetFields();
|
||||
// };
|
||||
|
||||
const confirm = async (formEl) => {
|
||||
if (!formEl) return;
|
||||
await formEl.validate((valid) => {
|
||||
if (valid) {
|
||||
// editPasswordOauthRef.value.operateDialogVisible = true;
|
||||
formElClone.value = formEl;
|
||||
emit("requestOperate");
|
||||
operateDialogVisible.value = false;
|
||||
formElClone.value.resetFields();
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const choiceTopicForm = (editData) => {
|
||||
ruleForm.topic = editData.topic;
|
||||
ruleForm.options_a = editData.options_a;
|
||||
ruleForm.options_b = editData.options_b;
|
||||
ruleForm.options_c = editData.options_c;
|
||||
ruleForm.options_d = editData.options_d;
|
||||
ruleForm.answer = editData.answer;
|
||||
};
|
||||
|
||||
defineExpose({ operateDialogVisible, model, ruleForm, choiceTopicForm, password });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
322
src/components/editData/contest/contestForm.vue
Normal file
@@ -0,0 +1,322 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog
|
||||
v-model="operateDialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ operateLabel }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm(ruleFormRef)"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="竞赛名称" prop="contest_name">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入竞赛名称"
|
||||
v-model="ruleForm.contest_name"
|
||||
@input="filter(ruleForm.contest_name, 'contest_name')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="竞赛主办方" prop="contest_organizers">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入竞赛主办方"
|
||||
v-model="ruleForm.contest_organizers"
|
||||
@input="filter(ruleForm.contest_organizers, 'contest_organizers')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="竞赛届数" prop="contest_term">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入竞赛届数"
|
||||
v-model="ruleForm.contest_term"
|
||||
@input="filter(ruleForm.contest_term, 'contest_term')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="竞赛类型" prop="type">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择竞赛类型"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.type"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in editData.typeOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="举办状态" prop="status">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择举办状态"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.status"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in editData.statusOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="线上赛起止时间">
|
||||
<el-col :span="11">
|
||||
<el-form-item prop="online_start">
|
||||
<el-date-picker
|
||||
v-model="ruleForm.online_start"
|
||||
type="datetime"
|
||||
placeholder="请选择线上赛开始时间"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="2" class="text-center">
|
||||
<span class="text-gray-500">-</span>
|
||||
</el-col>
|
||||
<el-col :span="11">
|
||||
<el-form-item prop="online_end">
|
||||
<el-date-picker
|
||||
v-model="ruleForm.online_end"
|
||||
type="datetime"
|
||||
placeholder="请选择线上赛结束时间"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="线下赛起止时间">
|
||||
<el-col :span="11">
|
||||
<el-form-item prop="offline_start">
|
||||
<el-date-picker
|
||||
v-model="ruleForm.offline_start"
|
||||
type="datetime"
|
||||
placeholder="请选择线下赛开始时间"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="2" class="text-center">
|
||||
<span class="text-gray-500">-</span>
|
||||
</el-col>
|
||||
<el-col :span="11">
|
||||
<el-form-item prop="offline_end">
|
||||
<el-date-picker
|
||||
v-model="ruleForm.offline_end"
|
||||
type="datetime"
|
||||
placeholder="请选择线下赛结束时间"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item label="竞赛起止时间">
|
||||
<el-col :span="11">
|
||||
<el-form-item prop="contest_start">
|
||||
<el-date-picker
|
||||
v-model="ruleForm.contest_start"
|
||||
type="datetime"
|
||||
placeholder="请选择竞赛开始时间"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="2" class="text-center">
|
||||
<span class="text-gray-500">-</span>
|
||||
</el-col>
|
||||
<el-col :span="11">
|
||||
<el-form-item prop="contest_end">
|
||||
<el-date-picker
|
||||
v-model="ruleForm.contest_end"
|
||||
type="datetime"
|
||||
placeholder="请选择竞赛结束时间"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm(ruleFormRef)">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button
|
||||
style="font-weight: bold"
|
||||
type="primary"
|
||||
@click="confirm(ruleFormRef)"
|
||||
>
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- <PasswordOauth
|
||||
ref="editPasswordOauthRef"
|
||||
:operateLabel="operateLabel"
|
||||
@requestOperate="requestOperate"
|
||||
/> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
// import PasswordOauth from "../../operate/passwordOauth.vue";
|
||||
|
||||
const operateDialogVisible = ref(false);
|
||||
const model = ref("single");
|
||||
const ruleFormRef = ref(null);
|
||||
// const editPasswordOauthRef = ref(null);
|
||||
const formElClone = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
contest_name: "",
|
||||
contest_organizers: "",
|
||||
contest_term: "",
|
||||
type: "",
|
||||
status: "",
|
||||
online_start: "",
|
||||
online_end: "",
|
||||
offline_start: "",
|
||||
offline_end: "",
|
||||
contest_start: "",
|
||||
contest_end: "",
|
||||
});
|
||||
|
||||
const password = ref("");
|
||||
|
||||
const rules = reactive({
|
||||
contest_name: [{ required: true, message: "请输入竞赛名称", trigger: "blur" }],
|
||||
contest_organizers: [{ required: true, message: "请输入竞赛主办方", trigger: "blur" }],
|
||||
contest_term: [{ required: true, message: "请输入竞赛届数", trigger: "blur" }],
|
||||
type: [{ required: true, message: "请选择竞赛类型", trigger: "change" }],
|
||||
status: [{ required: true, message: "请选择举办状态", trigger: "change" }],
|
||||
online_start: [
|
||||
{ type: "date", required: true, message: "线上赛开始时间", trigger: "change" },
|
||||
],
|
||||
online_end: [
|
||||
{ type: "date", required: true, message: "线上赛结束时间", trigger: "change" },
|
||||
],
|
||||
offline_start: [
|
||||
{ type: "date", required: true, message: "线下赛开始时间", trigger: "change" },
|
||||
],
|
||||
offline_end: [
|
||||
{ type: "date", required: true, message: "线下赛结束时间", trigger: "change" },
|
||||
],
|
||||
contest_start: [
|
||||
{ type: "date", required: true, message: "竞赛开始时间", trigger: "change" },
|
||||
],
|
||||
contest_end: [
|
||||
{ type: "date", required: true, message: "竞赛结束时间", trigger: "change" },
|
||||
],
|
||||
});
|
||||
|
||||
const props = defineProps({
|
||||
operateLabel: String,
|
||||
editData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["requestOperate"]);
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
operateDialogVisible.value = false;
|
||||
if (!ruleFormRef) return;
|
||||
formElClone.value = ruleFormRef.value;
|
||||
formElClone.value.resetFields();
|
||||
};
|
||||
|
||||
const resetCheckForm = (formEl) => {
|
||||
operateDialogVisible.value = false;
|
||||
if (!formEl) return;
|
||||
formEl.resetFields();
|
||||
};
|
||||
|
||||
// const requestOperate = () => {
|
||||
// password.value = editPasswordOauthRef.value.ruleForm.password;
|
||||
// emit("requestOperate");
|
||||
// operateDialogVisible.value = false;
|
||||
// formElClone.value.resetFields();
|
||||
// };
|
||||
|
||||
const confirm = async (formEl) => {
|
||||
if (!formEl) return;
|
||||
await formEl.validate((valid) => {
|
||||
if (valid) {
|
||||
// editPasswordOauthRef.value.operateDialogVisible = true;
|
||||
formElClone.value = formEl;
|
||||
emit("requestOperate");
|
||||
operateDialogVisible.value = false;
|
||||
formElClone.value.resetFields();
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const contestForm = (editData) => {
|
||||
ruleForm.contest_name = editData.contest_name;
|
||||
ruleForm.contest_organizers = editData.contest_organizers;
|
||||
ruleForm.contest_term = editData.contest_term;
|
||||
ruleForm.type = props.editData.typeOptions[editData.type];
|
||||
ruleForm.status = props.editData.statusOptions[editData.status];
|
||||
ruleForm.online_start = editData.origin_onlineStart;
|
||||
ruleForm.online_end = editData.origin_onlineEnd;
|
||||
ruleForm.offline_start = editData.origin_offlineStart;
|
||||
ruleForm.offline_end = editData.origin_offlineEnd;
|
||||
ruleForm.contest_start = editData.origin_contestStart;
|
||||
ruleForm.contest_end = editData.origin_contestEnd;
|
||||
};
|
||||
|
||||
defineExpose({ operateDialogVisible, model, ruleForm, contestForm, password });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
151
src/components/editData/contest/examinationForm.vue
Normal file
@@ -0,0 +1,151 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog
|
||||
v-model="operateDialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ operateLabel }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm(ruleFormRef)"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="得分" prop="score">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入得分"
|
||||
v-model="ruleForm.score"
|
||||
@input="filter(ruleForm.score, 'score')"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm(ruleFormRef)">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button
|
||||
style="font-weight: bold"
|
||||
type="primary"
|
||||
@click="confirm(ruleFormRef)"
|
||||
>
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- <PasswordOauth
|
||||
ref="editPasswordOauthRef"
|
||||
:operateLabel="operateLabel"
|
||||
@requestOperate="requestOperate"
|
||||
/> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
// import PasswordOauth from "../../operate/passwordOauth.vue";
|
||||
|
||||
const operateDialogVisible = ref(false);
|
||||
const model = ref("single");
|
||||
const ruleFormRef = ref(null);
|
||||
// const editPasswordOauthRef = ref(null);
|
||||
const formElClone = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
score: "",
|
||||
});
|
||||
|
||||
const password = ref("");
|
||||
|
||||
const rules = reactive({
|
||||
score: [{ required: true, message: "请输入得分", trigger: "blur" }],
|
||||
});
|
||||
|
||||
const props = defineProps({
|
||||
operateLabel: String,
|
||||
editData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["requestOperate"]);
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
operateDialogVisible.value = false;
|
||||
if (!ruleFormRef) return;
|
||||
formElClone.value = ruleFormRef.value;
|
||||
formElClone.value.resetFields();
|
||||
};
|
||||
|
||||
const resetCheckForm = (formEl) => {
|
||||
operateDialogVisible.value = false;
|
||||
if (!formEl) return;
|
||||
formEl.resetFields();
|
||||
};
|
||||
|
||||
// const requestOperate = () => {
|
||||
// password.value = editPasswordOauthRef.value.ruleForm.password;
|
||||
// emit("requestOperate");
|
||||
// operateDialogVisible.value = false;
|
||||
// formElClone.value.resetFields();
|
||||
// };
|
||||
|
||||
const confirm = async (formEl) => {
|
||||
if (!formEl) return;
|
||||
await formEl.validate((valid) => {
|
||||
if (valid) {
|
||||
// editPasswordOauthRef.value.operateDialogVisible = true;
|
||||
formElClone.value = formEl;
|
||||
emit("requestOperate");
|
||||
operateDialogVisible.value = false;
|
||||
formElClone.value.resetFields();
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const examinationForm = (editData) => {
|
||||
ruleForm.score = editData.score;
|
||||
};
|
||||
|
||||
defineExpose({ operateDialogVisible, model, ruleForm, examinationForm, password });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
178
src/components/editData/csideForm.vue
Normal file
@@ -0,0 +1,178 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog
|
||||
v-model="operateDialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ operateLabel }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm(ruleFormRef)"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="账号状态" prop="status">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择账号状态"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.status"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in editData.statusOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="账号角色" prop="role">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择账号角色"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.role"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in editData.roleOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm(ruleFormRef)">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button
|
||||
style="font-weight: bold"
|
||||
type="primary"
|
||||
@click="confirm(ruleFormRef)"
|
||||
>
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- <PasswordOauth
|
||||
ref="editPasswordOauthRef"
|
||||
:operateLabel="operateLabel"
|
||||
@requestOperate="requestOperate"
|
||||
/> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
// import PasswordOauth from "../operate/passwordOauth.vue";
|
||||
|
||||
const operateDialogVisible = ref(false);
|
||||
const model = ref("single");
|
||||
const ruleFormRef = ref(null);
|
||||
// const editPasswordOauthRef = ref(null);
|
||||
const formElClone = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
status: "",
|
||||
role: "",
|
||||
});
|
||||
|
||||
const password = ref("");
|
||||
|
||||
const rules = reactive({});
|
||||
|
||||
const props = defineProps({
|
||||
operateLabel: String,
|
||||
editData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["requestOperate"]);
|
||||
|
||||
const handleClose = () => {
|
||||
operateDialogVisible.value = false;
|
||||
if (!ruleFormRef) return;
|
||||
formElClone.value = ruleFormRef.value;
|
||||
formElClone.value.resetFields();
|
||||
};
|
||||
|
||||
const resetCheckForm = (formEl) => {
|
||||
operateDialogVisible.value = false;
|
||||
if (!formEl) return;
|
||||
formEl.resetFields();
|
||||
};
|
||||
|
||||
// const requestOperate = () => {
|
||||
// password.value = editPasswordOauthRef.value.ruleForm.password;
|
||||
// emit("requestOperate");
|
||||
// operateDialogVisible.value = false;
|
||||
// formElClone.value.resetFields();
|
||||
// };
|
||||
|
||||
const confirm = async (formEl) => {
|
||||
if (!formEl) return;
|
||||
await formEl.validate((valid) => {
|
||||
let FormNull = false;
|
||||
for (const element in ruleForm) {
|
||||
if (ruleForm[element] !== "" && ruleForm[element] !== undefined) {
|
||||
FormNull = true;
|
||||
}
|
||||
}
|
||||
if (valid && FormNull) {
|
||||
// editPasswordOauthRef.value.operateDialogVisible = true;
|
||||
formElClone.value = formEl;
|
||||
emit("requestOperate");
|
||||
operateDialogVisible.value = false;
|
||||
formElClone.value.resetFields();
|
||||
} else {
|
||||
if (!FormNull) {
|
||||
ElMessage.error("请先编辑数据!");
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ operateDialogVisible, model, ruleForm, password });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
178
src/components/editData/insidersForm.vue
Normal file
@@ -0,0 +1,178 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog
|
||||
v-model="operateDialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ operateLabel }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm(ruleFormRef)"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="账号状态" prop="status">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择账号状态"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.status"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in editData.statusOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="账号角色" prop="role">
|
||||
<el-select
|
||||
clearable
|
||||
size="small"
|
||||
placeholder="请选择账号角色"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.role"
|
||||
style="width: 100%; font-size: 1rem"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in editData.roleOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
class="text-center"
|
||||
:style="item.style"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm(ruleFormRef)">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button
|
||||
style="font-weight: bold"
|
||||
type="primary"
|
||||
@click="confirm(ruleFormRef)"
|
||||
>
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- <PasswordOauth
|
||||
ref="editPasswordOauthRef"
|
||||
:operateLabel="operateLabel"
|
||||
@requestOperate="requestOperate"
|
||||
/> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
// import PasswordOauth from "../operate/passwordOauth.vue";
|
||||
|
||||
const operateDialogVisible = ref(false);
|
||||
const model = ref("single");
|
||||
const ruleFormRef = ref(null);
|
||||
// const editPasswordOauthRef = ref(null);
|
||||
const formElClone = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
status: "",
|
||||
role: "",
|
||||
});
|
||||
|
||||
const password = ref("");
|
||||
|
||||
const rules = reactive({});
|
||||
|
||||
const props = defineProps({
|
||||
operateLabel: String,
|
||||
editData: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["requestOperate"]);
|
||||
|
||||
const handleClose = () => {
|
||||
operateDialogVisible.value = false;
|
||||
if (!ruleFormRef) return;
|
||||
formElClone.value = ruleFormRef.value;
|
||||
formElClone.value.resetFields();
|
||||
};
|
||||
|
||||
const resetCheckForm = (formEl) => {
|
||||
operateDialogVisible.value = false;
|
||||
if (!formEl) return;
|
||||
formEl.resetFields();
|
||||
};
|
||||
|
||||
// const requestOperate = () => {
|
||||
// password.value = editPasswordOauthRef.value.ruleForm.password;
|
||||
// emit("requestOperate");
|
||||
// operateDialogVisible.value = false;
|
||||
// formElClone.value.resetFields();
|
||||
// };
|
||||
|
||||
const confirm = async (formEl) => {
|
||||
if (!formEl) return;
|
||||
await formEl.validate((valid) => {
|
||||
let FormNull = false;
|
||||
for (const element in ruleForm) {
|
||||
if (ruleForm[element] !== "" && ruleForm[element] !== undefined) {
|
||||
FormNull = true;
|
||||
}
|
||||
}
|
||||
if (valid && FormNull) {
|
||||
// editPasswordOauthRef.value.operateDialogVisible = true;
|
||||
formElClone.value = formEl;
|
||||
emit("requestOperate");
|
||||
operateDialogVisible.value = false;
|
||||
formElClone.value.resetFields();
|
||||
} else {
|
||||
if (!FormNull) {
|
||||
ElMessage.error("请先编辑数据!");
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ operateDialogVisible, model, ruleForm, password });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
210
src/components/editData/organizationForm.vue
Normal file
@@ -0,0 +1,210 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog
|
||||
v-model="operateDialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<template #header="{ titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
{{ operateLabel }}
|
||||
</div>
|
||||
<div
|
||||
@click="resetCheckForm(ruleFormRef)"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="单位名称" prop="organization_name">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入单位名称"
|
||||
v-model="ruleForm.organization_name"
|
||||
@input="filter(ruleForm.organization_name, 'organization_name')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="通信地址" prop="address">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入通信地址"
|
||||
v-model="ruleForm.address"
|
||||
@input="filter(ruleForm.address, 'address')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="单位联系人姓名" prop="liaison_name">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入单位联系人姓名"
|
||||
v-model="ruleForm.liaison_name"
|
||||
@input="filter(ruleForm.liaison_name, 'liaison_name')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="联系人手机号码" prop="phone">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入联系人手机号码"
|
||||
v-model="ruleForm.phone"
|
||||
@input="filter(ruleForm.phone, 'phone')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="单位电子邮箱" prop="email">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入单位电子邮箱"
|
||||
v-model="ruleForm.email"
|
||||
@input="filter(ruleForm.email, 'email')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="其他信息" prop="other_information">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入其他信息"
|
||||
v-model="ruleForm.other_information"
|
||||
@input="filter(ruleForm.other_information, 'other_information')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="邮政编码" prop="post_code">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入邮政编码"
|
||||
v-model="ruleForm.post_code"
|
||||
@input="filter(ruleForm.post_code, 'post_code')"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetCheckForm(ruleFormRef)">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button
|
||||
style="font-weight: bold"
|
||||
type="primary"
|
||||
@click="confirm(ruleFormRef)"
|
||||
>
|
||||
确定
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- <PasswordOauth
|
||||
ref="editPasswordOauthRef"
|
||||
:operateLabel="operateLabel"
|
||||
@requestOperate="requestOperate"
|
||||
/> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
// import PasswordOauth from "../operate/passwordOauth.vue";
|
||||
|
||||
const operateDialogVisible = ref(false);
|
||||
const model = ref("single");
|
||||
const ruleFormRef = ref(null);
|
||||
// const editPasswordOauthRef = ref(null);
|
||||
const formElClone = ref(null);
|
||||
|
||||
const ruleForm = reactive({
|
||||
organization_name: "",
|
||||
address: "",
|
||||
liaison_name: "",
|
||||
phone: "",
|
||||
email: "",
|
||||
other_information: "",
|
||||
post_code: "",
|
||||
});
|
||||
|
||||
const password = ref("");
|
||||
|
||||
const rules = reactive({
|
||||
organization_name: [{ required: true, message: "请输入单位名称", trigger: "blur" }],
|
||||
});
|
||||
|
||||
const props = defineProps({
|
||||
operateLabel: String,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["requestOperate"]);
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
operateDialogVisible.value = false;
|
||||
if (!ruleFormRef) return;
|
||||
formElClone.value = ruleFormRef.value;
|
||||
formElClone.value.resetFields();
|
||||
};
|
||||
|
||||
const resetCheckForm = (formEl) => {
|
||||
operateDialogVisible.value = false;
|
||||
if (!formEl) return;
|
||||
formEl.resetFields();
|
||||
};
|
||||
|
||||
// const requestOperate = () => {
|
||||
// password.value = editPasswordOauthRef.value.ruleForm.password;
|
||||
// emit("requestOperate");
|
||||
// operateDialogVisible.value = false;
|
||||
// formElClone.value.resetFields();
|
||||
// };
|
||||
|
||||
const confirm = async (formEl) => {
|
||||
if (!formEl) return;
|
||||
await formEl.validate((valid) => {
|
||||
if (valid) {
|
||||
// editPasswordOauthRef.value.operateDialogVisible = true;
|
||||
formElClone.value = formEl;
|
||||
emit("requestOperate");
|
||||
operateDialogVisible.value = false;
|
||||
formElClone.value.resetFields();
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const originForm = (editData) => {
|
||||
ruleForm.organization_name = editData.organization_name;
|
||||
ruleForm.address = editData.address;
|
||||
ruleForm.liaison_name = editData.liaison_name;
|
||||
ruleForm.phone = editData.phone;
|
||||
ruleForm.email = editData.email;
|
||||
ruleForm.other_information = editData.other_information;
|
||||
ruleForm.post_code = editData.post_code;
|
||||
};
|
||||
|
||||
defineExpose({ operateDialogVisible, model, ruleForm, originForm, password });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
146
src/components/header/Exit.vue
Normal file
@@ -0,0 +1,146 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="bg-fuchsia-200">
|
||||
<el-dropdown class="flex flex-auto justify-end items-center">
|
||||
<el-button style="font-weight: bold" type="success" size="small">
|
||||
账户名: {{ userMsg.name }}
|
||||
<el-icon class="el-icon--right">
|
||||
<arrow-down />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item
|
||||
style="background-color: rgba(56, 188, 248, 0.1)"
|
||||
@click="editUser"
|
||||
>
|
||||
<el-link style="font-weight: bold" :underline="false" type="primary">
|
||||
账户管理
|
||||
</el-link>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
style="background-color: rgba(56, 188, 248, 0.1)"
|
||||
@click="changePassword"
|
||||
>
|
||||
<el-link style="font-weight: bold" :underline="false" type="primary">
|
||||
密码管理
|
||||
</el-link>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
style="background-color: rgba(240, 70, 70, 0.1)"
|
||||
@click="unLogin"
|
||||
>
|
||||
<el-link style="font-weight: bold" :underline="false" type="danger">
|
||||
退出登录
|
||||
</el-link>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
<UserManager @resetData="resetData" ref="userManagerRef" :msg="userMsg" />
|
||||
<PasswordManager ref="passwordManagerRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch, onMounted } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { ArrowDown } from "@element-plus/icons-vue";
|
||||
|
||||
import $http from "../../api/index";
|
||||
import $url from "../../api/url";
|
||||
|
||||
import UserManager from "../manager/userManager.vue";
|
||||
import PasswordManager from "../manager/changePassword.vue";
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const systemManager = ref(false);
|
||||
const manager = ref(false);
|
||||
const userManagerRef = ref(null);
|
||||
const userMsg = ref({});
|
||||
const passwordManagerRef = ref(null);
|
||||
|
||||
const editUser = () => {
|
||||
if (userManagerRef.value) {
|
||||
userManagerRef.value.dialogVisible = true;
|
||||
userManagerRef.value.reset();
|
||||
}
|
||||
};
|
||||
|
||||
const changePassword = () => {
|
||||
if (passwordManagerRef.value) {
|
||||
passwordManagerRef.value.dialogVisible = true;
|
||||
}
|
||||
};
|
||||
|
||||
const unLogin = () => {
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
access_token: localStorage.access_token,
|
||||
refresh_token: localStorage.refresh_token,
|
||||
};
|
||||
$http.post($url.unLogin, data).then((res) => {
|
||||
localStorage.clear();
|
||||
if (localStorage.length == 0) {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const resetData = () => {
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
};
|
||||
$http.post($url.getUser, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
ElMessage({
|
||||
message: "获取用户信息成功!",
|
||||
type: "success",
|
||||
});
|
||||
userMsg.value = res.data.userData;
|
||||
if (res.data.userData.role == 9) {
|
||||
systemManager.value = true;
|
||||
}
|
||||
if (res.data.userData.role == 6 || res.data.userData.role == 9) {
|
||||
manager.value = true;
|
||||
}
|
||||
if (res.data.userData.status == 0) {
|
||||
ElMessage({
|
||||
showClose: true,
|
||||
message: "您的账号正在使用默认密码,请尽快进行更改!",
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
if (res.data.userData.status == 2) {
|
||||
ElMessage({
|
||||
showClose: true,
|
||||
message: "您的账号已被封禁,请联系管理员进行申诉!",
|
||||
type: "error",
|
||||
});
|
||||
}
|
||||
} else {
|
||||
ElMessage.error("获取用户信息失败!");
|
||||
if (localStorage.length == 0) {
|
||||
// window.location.reload();
|
||||
router.push({ path: '/mlogin' });
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
watch(manager, (value) => {
|
||||
if (value) {
|
||||
}
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
resetData();
|
||||
}, 200);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
17
src/components/header/Logo.vue
Normal file
@@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<div>
|
||||
<img class="cursor-pointer" src="../../assets/logo.png" alt="" @click="goToHome">
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const goToHome = () => {
|
||||
router.push({ name: "home" });
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
59
src/components/header/Navigation.vue
Normal file
@@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<div class="w-2/3 h-full flex justify-between items-center bg-teal-400">
|
||||
<template v-for="options in nav" :key="options.page">
|
||||
<div
|
||||
:style="
|
||||
activeIndex == options.id
|
||||
? 'background-color: rgb(14 165 233);border-width: 2px;border-bottom-color: rgb(192 38 211);line-height: 5.7rem'
|
||||
: 'line-height: 5.7rem'
|
||||
"
|
||||
class="h-full flex-1 cursor-pointer text-center hover:bg-sky-500"
|
||||
@click="goToPage(options.page, options.id)"
|
||||
>
|
||||
{{ options.label }}
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
import activeIndexActiveStore from "../../stores/activeIndex";
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const activeIndexActive = activeIndexActiveStore();
|
||||
|
||||
const activeIndex = ref(0);
|
||||
|
||||
const nav = [
|
||||
{ label: "首页", page: "home", id: 0 },
|
||||
{ label: "工作区", page: "workspace", id: 1 },
|
||||
{ label: "B端管理", page: "bside", id: 2 },
|
||||
{ label: "C端管理", page: "cside", id: 3 },
|
||||
{ label: "竞赛管理", page: "contest", id: 4 },
|
||||
{ label: "内部管理", page: "insiders", id: 5 },
|
||||
{ label: "系统设置", page: "system", id: 6 },
|
||||
];
|
||||
|
||||
const handleOpen = (key, keyPath) => {
|
||||
console.log(key, keyPath);
|
||||
};
|
||||
const handleClose = (key, keyPath) => {
|
||||
console.log(key, keyPath);
|
||||
};
|
||||
|
||||
const goToPage = (page, id) => {
|
||||
activeIndex.value = id;
|
||||
activeIndexActive.headerActive = id;
|
||||
router.push({ name: page });
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
goToPage(nav[activeIndexActive.headerActive].page, activeIndexActive.headerActive);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
8
src/components/main/Charts.vue
Normal file
@@ -0,0 +1,8 @@
|
||||
<template>
|
||||
<el-text class="mx-1"> Charts </el-text>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
8
src/components/main/Form.vue
Normal file
@@ -0,0 +1,8 @@
|
||||
<template>
|
||||
<el-text class="mx-1"> Form </el-text>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
8
src/components/main/Table.vue
Normal file
@@ -0,0 +1,8 @@
|
||||
<template>
|
||||
<el-text class="mx-1"> Table </el-text>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
584
src/components/mainPage/SN.vue
Normal file
@@ -0,0 +1,584 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 表格 -->
|
||||
<el-card>
|
||||
<div class="flex justify-center flex-wrap">
|
||||
<TabelTools @showTools="showTools" :dialogObj="SNActive" />
|
||||
<AddNewData newDataLabel="新增SN号" @showAddForm="showAddForm" />
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="tableData"
|
||||
style="width: 100%"
|
||||
max-height="50rem"
|
||||
table-layout="auto"
|
||||
scrollbar-always-on
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column
|
||||
v-if="dialogOperationVisible"
|
||||
fixed="left"
|
||||
type="selection"
|
||||
width="40"
|
||||
column-key="selection"
|
||||
/>
|
||||
<TabelSelect
|
||||
v-if="dialogOperationVisible"
|
||||
ref="EditSelectRef"
|
||||
:holderText="editSelectHold"
|
||||
singleColor="primary"
|
||||
multipleColor="warning"
|
||||
allColor="danger"
|
||||
singleSize="small"
|
||||
multipleSize="small"
|
||||
allSize="small"
|
||||
:singlePlain="true"
|
||||
:multiplePlain="false"
|
||||
:allPlain="false"
|
||||
operateType="edit"
|
||||
@showComfirmDialog="showComfirmDialog"
|
||||
/>
|
||||
<TabelSelect
|
||||
v-if="dialogOperationVisible"
|
||||
ref="DelSelectRef"
|
||||
:holderText="delSelectHold"
|
||||
singleColor="danger"
|
||||
multipleColor="warning"
|
||||
allColor="danger"
|
||||
singleSize="small"
|
||||
multipleSize="small"
|
||||
allSize="small"
|
||||
:singlePlain="true"
|
||||
:multiplePlain="false"
|
||||
:allPlain="false"
|
||||
operateType="del"
|
||||
@showComfirmDialog="showComfirmDialog"
|
||||
/>
|
||||
<el-table-column min-width="100" column-key="sn_number">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchSNKeyRef"
|
||||
holderText="输入SN号以搜索相关数据"
|
||||
@search="SNMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> SN号 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="SortSNRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="SNMsg"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(statusOptions, scope.row.status)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ scope.row.sn_number }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="80" column-key="status">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectStatusSearchRef"
|
||||
holderText="选择绑定状态以搜索相关数据"
|
||||
:options="statusOptions"
|
||||
@search="SNMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 绑定状态 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(statusOptions, scope.row.status)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(statusOptions, scope.row.status) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="120" column-key="account_name">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchAccountNameKeyRef"
|
||||
holderText="输入绑定用户以搜索相关数据"
|
||||
@search="SNMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 绑定用户 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(statusOptions, scope.row.status)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ scope.row.account_name }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="created_at">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="createdDateTimePickerRef"
|
||||
DateTimePicker="createdDateTimePicker"
|
||||
@search="SNMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 注册时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="createdSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="SNMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(statusOptions, scope.row.status)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ scope.row.created_at }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="updated_at">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="updatedDateTimePickerRef"
|
||||
DateTimePicker="updatedMsgDateTimePicker"
|
||||
@search="SNMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 绑定状态变更时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="updatedSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="SNMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(statusOptions, scope.row.status)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ scope.row.updated_at }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<Pagination
|
||||
ref="PaginationRef"
|
||||
:active="SNActive"
|
||||
@sizeChangeBack="changePage"
|
||||
@search="SNMsg"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
<AddSNForm ref="addSNFormRef" title="新增SN号" @reloadData="SNMsg" />
|
||||
<EditSNForm
|
||||
ref="editSNFormRef"
|
||||
operateLabel="编辑SN号"
|
||||
:editData="editData"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
<PasswordOauth
|
||||
ref="delPasswordOauthRef"
|
||||
operateLabel="删除SN号"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch, onMounted, nextTick } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import TabelTools from "../operate/tabelTools.vue";
|
||||
import AddNewData from "../operate/addNewData.vue";
|
||||
import TabelSelect from "../operate/tabelSelect.vue";
|
||||
import SearchKey from "../search/searchKey.vue";
|
||||
import SortSearch from "../search/sortSearch.vue";
|
||||
import SelectSearch from "../search/selectSearch.vue";
|
||||
import DateTimePicker from "../search/dateTimePicker.vue";
|
||||
import Pagination from "../search/pagination.vue";
|
||||
import AddSNForm from "../addNewData/SNForm/SNForm.vue";
|
||||
import EditSNForm from "../editData/SNForm.vue";
|
||||
import PasswordOauth from "../operate/passwordOauth.vue";
|
||||
|
||||
import SNActiveStore from "../../stores/SN";
|
||||
|
||||
import moment from "moment";
|
||||
|
||||
import $http from "../../api/index";
|
||||
import $url from "../../api/url";
|
||||
|
||||
import { encrypt } from "../../utils/aes";
|
||||
import { judgment } from "../../utils/judgment.js";
|
||||
import { hasNullOrEmptyPropertyWithTypeof } from "../../utils/hasNullOrEmptyPropertyWithTypeof.js";
|
||||
|
||||
const SNActive = SNActiveStore();
|
||||
|
||||
const editSelectHold = {
|
||||
single: "编辑",
|
||||
multiple: "编辑选中",
|
||||
all: "编辑所有",
|
||||
label: "编辑SN号",
|
||||
};
|
||||
|
||||
const delSelectHold = {
|
||||
single: "删除",
|
||||
multiple: "删除选中",
|
||||
all: "删除所有",
|
||||
label: "删除SN号",
|
||||
};
|
||||
const EditSelectRef = ref(null);
|
||||
const DelSelectRef = ref(null);
|
||||
const SearchSNKeyRef = ref(null);
|
||||
const SelectStatusSearchRef = ref(null);
|
||||
const createdDateTimePickerRef = ref(null);
|
||||
const updatedDateTimePickerRef = ref(null);
|
||||
const SortSNRef = ref(null);
|
||||
const createdSortDateTimeRef = ref(null);
|
||||
const updatedSortDateTimeRef = ref(null);
|
||||
const PaginationRef = ref(null);
|
||||
const addSNFormRef = ref(null);
|
||||
const editSNFormRef = ref(null);
|
||||
const delPasswordOauthRef = ref(null);
|
||||
const dialogSearchVisible = ref(false);
|
||||
const dialogSortVisible = ref(false);
|
||||
const dialogOperationVisible = ref(false);
|
||||
const tableRef = ref();
|
||||
const offsetOff = ref(true);
|
||||
const pageCount = ref(0);
|
||||
const operate = ref("edit");
|
||||
const searchOptions = reactive({
|
||||
sn_number: "",
|
||||
status: "",
|
||||
created_at: "",
|
||||
updated_at: "",
|
||||
});
|
||||
const sortOptions = reactive({
|
||||
sn_number: false,
|
||||
created_at: false,
|
||||
updated_at: false,
|
||||
});
|
||||
const tableData = ref([]);
|
||||
const statusOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "未绑定",
|
||||
style: "color: rgb(20, 200, 200);background-color: rgba(20, 200, 200, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "B端绑定",
|
||||
style: "color: rgb(255, 100, 180);background-color: rgba(255, 100, 180, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "C端绑定",
|
||||
style: "color: rgb(255, 120, 20);background-color: rgba(255, 120, 20, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "3",
|
||||
label: "竞赛绑定",
|
||||
style: "color: rgb(255, 200, 0);background-color: rgba(255, 200, 0, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "4",
|
||||
label: "B端预绑定",
|
||||
style: "color: rgb(240, 70, 70);background-color: rgba(240, 70, 70, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
let singleData = reactive({});
|
||||
let operateData = reactive({});
|
||||
let operateDataClone = reactive({});
|
||||
const editData = reactive({
|
||||
statusOptions,
|
||||
});
|
||||
|
||||
const showAddForm = () => {
|
||||
addSNFormRef.value.dialogVisible = true;
|
||||
};
|
||||
|
||||
const styleShunt = (options, data) => {
|
||||
let nowStyle;
|
||||
options.forEach((item) => {
|
||||
if (data == item.value) {
|
||||
nowStyle = item.style;
|
||||
}
|
||||
});
|
||||
return nowStyle;
|
||||
};
|
||||
|
||||
const labelShunt = (options, data) => {
|
||||
let nowLabel;
|
||||
options.forEach((item) => {
|
||||
if (data == item.value) {
|
||||
nowLabel = item.label;
|
||||
}
|
||||
});
|
||||
return nowLabel;
|
||||
};
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "search":
|
||||
dialogSearchVisible.value = !dialogSearchVisible.value;
|
||||
SNActive.dialogSearchVisible = dialogSearchVisible.value;
|
||||
break;
|
||||
case "sort":
|
||||
dialogSortVisible.value = !dialogSortVisible.value;
|
||||
SNActive.dialogSortVisible = dialogSortVisible.value;
|
||||
break;
|
||||
case "operation":
|
||||
dialogOperationVisible.value = !dialogOperationVisible.value;
|
||||
SNActive.dialogOperationVisible = dialogOperationVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetOffset = () => {
|
||||
if (hasNullOrEmptyPropertyWithTypeof(searchOptions)) {
|
||||
if (PaginationRef.value.offset !== 1 && offsetOff.value) {
|
||||
PaginationRef.value.handleCurrentChange(1);
|
||||
offsetOff.value = false;
|
||||
}
|
||||
} else {
|
||||
offsetOff.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
const SNMsg = () => {
|
||||
judgment(searchOptions, "sn_number", SearchSNKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "status", SelectStatusSearchRef.value, "searchMsg");
|
||||
judgment(searchOptions, "created_at", createdDateTimePickerRef.value, "searchMsg");
|
||||
judgment(searchOptions, "updated_at", updatedDateTimePickerRef.value, "searchMsg");
|
||||
judgment(sortOptions, "sn_number", SortSNRef.value, "searchMsg");
|
||||
judgment(sortOptions, "created_at", createdSortDateTimeRef.value, "searchMsg");
|
||||
judgment(sortOptions, "updated_at", updatedSortDateTimeRef.value, "searchMsg");
|
||||
resetOffset();
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
offset: PaginationRef.value == null ? 1 : PaginationRef.value.offset,
|
||||
limit: PaginationRef.value == null ? 10 : PaginationRef.value.limit,
|
||||
searchOptions: searchOptions,
|
||||
sortOptions: sortOptions,
|
||||
};
|
||||
$http.post($url.showSN, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableData.value = res.data.SNMsg;
|
||||
tableData.value.forEach((item) => {
|
||||
item.origin_createdAt = item.created_at;
|
||||
item.created_at = moment
|
||||
.utc(item.created_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
item.origin_updatedAt = item.updated_at;
|
||||
item.updated_at = moment
|
||||
.utc(item.updated_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
});
|
||||
PaginationRef.value.dataCount = res.data.count;
|
||||
SNActive.dataCount = PaginationRef.value.dataCount;
|
||||
pageCount.value = Math.ceil(
|
||||
PaginationRef.value.dataCount / PaginationRef.value.limit
|
||||
);
|
||||
SNActive.pageCount = pageCount.value;
|
||||
if (!operateData[PaginationRef.value.offset]) return;
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
tableData.value.forEach((item) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
nextTick(() => {
|
||||
tableRef.value.toggleRowSelection(item, true);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
tableData.value = [];
|
||||
ElMessage.error("未查找到相关数据!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const changePage = (val) => {
|
||||
pageCount.value = Math.ceil(PaginationRef.value.dataCount / val);
|
||||
operateData = {};
|
||||
for (let i = 0; i < pageCount.value; i++) {
|
||||
operateData[i + 1] = [];
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((element) => {
|
||||
// 判断数据在第几页
|
||||
if (Math.ceil(element.location / PaginationRef.value.limit) == i + 1) {
|
||||
operateData[i + 1].push(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelectionChange = (val) => {
|
||||
operateData[PaginationRef.value.offset] = val;
|
||||
tableData.value.forEach((item, index) => {
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
// 数据在表格中的位置
|
||||
element.location =
|
||||
(PaginationRef.value.offset - 1) * PaginationRef.value.limit + (index + 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
operateDataClone = JSON.parse(JSON.stringify(operateData));
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((item) => {
|
||||
if (item.origin_createdAt) {
|
||||
item.created_at = item.origin_createdAt;
|
||||
}
|
||||
if (item.origin_updatedAt) {
|
||||
item.created_at = item.origin_updatedAt;
|
||||
}
|
||||
delete item.origin_createdAt;
|
||||
delete item.origin_updatedAt;
|
||||
delete item.location;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const showComfirmDialog = (singleMsg) => {
|
||||
singleData = { ...singleMsg.data };
|
||||
singleData.created_at = singleData.origin_createdAt;
|
||||
singleData.updated_at = singleData.origin_updatedAt;
|
||||
delete singleData.origin_createdAt;
|
||||
delete singleData.origin_updatedAt;
|
||||
operate.value = singleMsg.operateType;
|
||||
if (singleMsg.operateType == "edit") {
|
||||
editSNFormRef.value.operateDialogVisible = true;
|
||||
editSNFormRef.value.model = EditSelectRef.value.model;
|
||||
}
|
||||
if (singleMsg.operateType == "del") {
|
||||
delPasswordOauthRef.value.operateDialogVisible = true;
|
||||
}
|
||||
};
|
||||
|
||||
const requestOperate = () => {
|
||||
let operateType, url, model, password;
|
||||
if (operate.value == "edit") {
|
||||
operateType = "编辑";
|
||||
url = $url.editSN;
|
||||
model = EditSelectRef.value.model;
|
||||
password = editSNFormRef.value.password;
|
||||
} else if (operate.value == "del") {
|
||||
operateType = "删除";
|
||||
url = $url.deleteSN;
|
||||
model = DelSelectRef.value.model;
|
||||
password = delPasswordOauthRef.value.ruleForm.password;
|
||||
}
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
model: encrypt(model),
|
||||
password: encrypt(password),
|
||||
requestMsg:
|
||||
model == "single" ? singleData : model == "multiple" ? operateDataClone : "",
|
||||
};
|
||||
if (operate.value == "edit") {
|
||||
data.updateMsg = { ...editSNFormRef.value.ruleForm };
|
||||
}
|
||||
$http.post(url, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableRef.value.clearSelection();
|
||||
operateData = {};
|
||||
operateDataClone = {};
|
||||
ElMessage({
|
||||
message: `${operateType}成功!`,
|
||||
type: "success",
|
||||
});
|
||||
SNMsg();
|
||||
} else {
|
||||
ElMessage.error(`${operateType}失败!`);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ SNMsg });
|
||||
|
||||
watch(searchOptions, (value) => {
|
||||
SNActive.searchOptions = value;
|
||||
});
|
||||
|
||||
watch(sortOptions, (value) => {
|
||||
SNActive.sortOptions = value;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
pageCount.value = SNActive.pageCount;
|
||||
dialogSearchVisible.value = SNActive.dialogSearchVisible;
|
||||
dialogSortVisible.value = SNActive.dialogSortVisible;
|
||||
dialogOperationVisible.value = SNActive.dialogOperationVisible;
|
||||
|
||||
if (dialogSearchVisible.value) {
|
||||
searchOptions.sn_number = SNActive.searchOptions.sn_number;
|
||||
searchOptions.status = SNActive.searchOptions.status;
|
||||
searchOptions.created_at = SNActive.searchOptions.created_at;
|
||||
searchOptions.updated_at = SNActive.searchOptions.updated_at;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
sortOptions.sn_number = SNActive.sortOptions.sn_number;
|
||||
sortOptions.created_at = SNActive.sortOptions.created_at;
|
||||
sortOptions.updated_at = SNActive.sortOptions.updated_at;
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
SNMsg();
|
||||
}, 200);
|
||||
|
||||
setTimeout(() => {
|
||||
if (dialogSearchVisible.value) {
|
||||
SearchSNKeyRef.value.searchMsg = SNActive.searchOptions.sn_number;
|
||||
SelectStatusSearchRef.value.searchMsg = SNActive.searchOptions.status;
|
||||
createdDateTimePickerRef.value.created_at =
|
||||
SNActive.searchOptions.created_at;
|
||||
updatedDateTimePickerRef.value.updated_at =
|
||||
SNActive.searchOptions.updated_at;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
SortSNRef.value.searchMsg = SNActive.sortOptions.sn_number;
|
||||
createdSortDateTimeRef.value.searchMsg = SNActive.sortOptions.created_at;
|
||||
updatedSortDateTimeRef.value.searchMsg = SNActive.sortOptions.updated_at;
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
329
src/components/mainPage/SNAdmin.vue
Normal file
@@ -0,0 +1,329 @@
|
||||
<template>
|
||||
<div class="card-container">
|
||||
<div class="top-block">
|
||||
<div class="info-block">
|
||||
<el-card class="box-card">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>用户ID</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="unbind-users" :style="{ height: contentBlockHeight + 'px' }">
|
||||
<el-tag v-show="selectedUser !== ''" type="info" class="sn-tag" effect="dark">
|
||||
{{ selectedUser }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card class="box-card">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>SN号</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="unbind-sn" :style="{ height: contentBlockHeight + 'px' }">
|
||||
<el-tag
|
||||
v-for="sn in selectedSNs"
|
||||
:key="sn"
|
||||
type="info"
|
||||
class="sn-tag"
|
||||
effect="dark"
|
||||
>
|
||||
{{ sn }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
<div
|
||||
class="action-block"
|
||||
:style="{
|
||||
height: contentBlockHeight + 'px',
|
||||
lineHeight: contentBlockHeight / 2 + 'px',
|
||||
}"
|
||||
>
|
||||
<div class="sn-count-label">
|
||||
用户可管理的SN号数量
|
||||
<div>
|
||||
<el-input
|
||||
v-model.number="snCount"
|
||||
type="number"
|
||||
placeholder="输入可绑定的SN数量"
|
||||
class="sn-count-input"
|
||||
:min="0"
|
||||
@change="validateSNCount"
|
||||
/>
|
||||
</div>
|
||||
<el-button class="bind-button" type="primary" @click="allocationSN"
|
||||
>确认绑定</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-block" ref="contentBlockRef">
|
||||
<el-card class="box-card">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>未绑定的用户</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="unbind-users">
|
||||
<el-tag
|
||||
v-for="user in unbindUsers"
|
||||
:key="user"
|
||||
type="info"
|
||||
class="user-tag"
|
||||
:effect="user === selectedUser ? 'dark' : 'plain'"
|
||||
@click="selectUser(user)"
|
||||
>
|
||||
{{ user }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card class="box-card">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>未绑定的SN号</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="unbind-sn">
|
||||
<el-tag
|
||||
v-for="sn in unbindSN"
|
||||
:key="sn"
|
||||
type="info"
|
||||
class="sn-tag"
|
||||
:effect="selectedSNs.includes(sn) ? 'dark' : 'plain'"
|
||||
@click="toggleSelectSN(sn)"
|
||||
>
|
||||
{{ sn }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, nextTick } from "vue";
|
||||
import { ElCard, ElButton, ElTag, ElMessage, ElInput } from "element-plus";
|
||||
|
||||
import SNAdminActiveStore from "../../stores/SNAdmin";
|
||||
|
||||
import $http from "../../api/index";
|
||||
import $url from "../../api/url";
|
||||
|
||||
const SNAdminActive = SNAdminActiveStore();
|
||||
|
||||
const selectedUser = ref("");
|
||||
const selectedSNs = ref([]);
|
||||
const snCount = ref(0);
|
||||
const unbindUsers = ref([]);
|
||||
const userObj = ref({});
|
||||
const unbindSN = ref([]);
|
||||
const contentBlockRef = ref(null);
|
||||
const contentBlockHeight = ref(0);
|
||||
|
||||
const selectUser = (user) => {
|
||||
selectedUser.value = user;
|
||||
SNAdminActive.selectedUser = user;
|
||||
};
|
||||
|
||||
const toggleSelectSN = (sn) => {
|
||||
if (selectedSNs.value.includes(sn)) {
|
||||
selectedSNs.value = selectedSNs.value.filter((s) => s !== sn);
|
||||
SNAdminActive.selectedSNs = selectedSNs.value.filter((s) => s !== sn);
|
||||
} else {
|
||||
if (selectedSNs.value.length < snCount.value) {
|
||||
selectedSNs.value.push(sn);
|
||||
} else {
|
||||
ElMessage.warning("已达到可绑定的SN号数量上限!");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const validateSNCount = () => {
|
||||
if (snCount.value < 0) {
|
||||
snCount.value = 0;
|
||||
ElMessage.warning("SN号数量不能为负数!");
|
||||
} else {
|
||||
if (selectedSNs.value.length > snCount.value) {
|
||||
snCount.value = selectedSNs.value.length;
|
||||
ElMessage.warning("已达到可绑定的SN号数量上限!");
|
||||
}
|
||||
}
|
||||
SNAdminActive.snCount = snCount.value;
|
||||
};
|
||||
|
||||
const resetCheckForm = () => {
|
||||
selectedUser.value = "";
|
||||
SNAdminActive.selectedUser = "";
|
||||
selectedSNs.value = [];
|
||||
SNAdminActive.selectedSNs = [];
|
||||
snCount.value = 0;
|
||||
SNAdminActive.snCount = 0;
|
||||
};
|
||||
|
||||
const searchAllocationUser = () => {
|
||||
$http.get($url.searchAllocationUser).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
res.data.userArr.forEach(element => {
|
||||
unbindUsers.value.push(element.account_name);
|
||||
userObj.value[element.account_name] = element.uid;
|
||||
});
|
||||
} else {
|
||||
unbindUsers.value = [];
|
||||
resetCheckForm();
|
||||
// ElMessage.error("未查找到相关数据!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const searchAllocationSN = () => {
|
||||
$http.get($url.searchAllocationSN).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
res.data.snArr.forEach(element => {
|
||||
unbindSN.value.push(element.sn_number);
|
||||
});
|
||||
} else {
|
||||
unbindSN.value = [];
|
||||
resetCheckForm();
|
||||
// ElMessage.error("未查找到相关数据!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const allocationSN = () => {
|
||||
if (selectedUser.value === "" || selectedSNs.value.length === 0) {
|
||||
ElMessage.warning("请选择用户和SN号!");
|
||||
return;
|
||||
}
|
||||
const data = {
|
||||
user_uid: userObj.value[selectedUser.value],
|
||||
length: snCount.value,
|
||||
sn_set: selectedSNs.value.join(","),
|
||||
};
|
||||
$http.post($url.allocationSN, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
resetCheckForm();
|
||||
unbindUsers.value = [];
|
||||
unbindSN.value = [];
|
||||
searchAllocationUser();
|
||||
searchAllocationSN();
|
||||
ElMessage({
|
||||
message: "绑定成功!",
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("绑定失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const setContentBlockHeight = async () => {
|
||||
await nextTick();
|
||||
if (contentBlockRef.value) {
|
||||
contentBlockHeight.value = contentBlockRef.value.offsetHeight;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
selectedUser.value = SNAdminActive.selectedUser;
|
||||
selectedSNs.value = SNAdminActive.selectedSNs;
|
||||
snCount.value = SNAdminActive.snCount;
|
||||
setTimeout(() => {
|
||||
searchAllocationUser();
|
||||
searchAllocationSN();
|
||||
setContentBlockHeight();
|
||||
}, 200);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.card-container {
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.top-block {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.info-block {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.box-card {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.unbind-users,
|
||||
.unbind-sn {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
height: 100%;
|
||||
align-items: flex-start;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.unbind-users .sn-tag,
|
||||
.unbind-sn .sn-tag {
|
||||
margin-bottom: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.user-tag.effect-dark,
|
||||
.sn-tag.effect-dark {
|
||||
background-color: #409eff;
|
||||
color: #fff;
|
||||
border-color: #409eff;
|
||||
}
|
||||
|
||||
.user-tag.effect-plain:hover,
|
||||
.sn-tag.effect-plain:hover {
|
||||
background-color: #ecf5ff;
|
||||
color: #409eff;
|
||||
border-color: #d9ecff;
|
||||
}
|
||||
|
||||
.action-block {
|
||||
color: #000;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.sn-count-label {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.sn-count-input,
|
||||
.bind-button {
|
||||
width: 100%;
|
||||
max-width: 200px; /* 设置最大宽度,确保文字长度合适 */
|
||||
}
|
||||
|
||||
.content-block {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 20px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.unbound-users .el-tag,
|
||||
.unbound-sn .el-tag {
|
||||
color: #000; /* 确保文字为黑色 */
|
||||
}
|
||||
</style>
|
||||
384
src/components/mainPage/allocationSNRecord.vue
Normal file
@@ -0,0 +1,384 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 表格 -->
|
||||
<el-card>
|
||||
<div class="flex justify-center flex-wrap">
|
||||
<TabelTools @showTools="showTools" :dialogObj="allocationSNRecordActive" />
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="tableData"
|
||||
style="width: 100%"
|
||||
max-height="50rem"
|
||||
table-layout="auto"
|
||||
scrollbar-always-on
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column
|
||||
v-if="dialogOperationVisible"
|
||||
fixed="left"
|
||||
type="selection"
|
||||
width="40"
|
||||
column-key="selection"
|
||||
/>
|
||||
<TabelSelect
|
||||
v-if="dialogOperationVisible"
|
||||
ref="DelSelectRef"
|
||||
:holderText="delSelectHold"
|
||||
singleColor="danger"
|
||||
multipleColor="warning"
|
||||
allColor="danger"
|
||||
singleSize="small"
|
||||
multipleSize="small"
|
||||
allSize="small"
|
||||
:singlePlain="true"
|
||||
:multiplePlain="false"
|
||||
:allPlain="false"
|
||||
operateType="del"
|
||||
@showComfirmDialog="showComfirmDialog"
|
||||
/>
|
||||
<el-table-column min-width="140" column-key="account_name">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchAccountNameKeyRef"
|
||||
holderText="输入账户名以搜索相关数据"
|
||||
@search="bindSNRecordMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 账户名 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.account_name }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="140" column-key="user_uid">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchUserUidKeyRef"
|
||||
holderText="输入账户uid以搜索相关数据"
|
||||
@search="bindSNRecordMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 账户uid </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.user_uid }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="140" column-key="length">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchLengthKeyRef"
|
||||
holderText="输入可管理的SN号数量以搜索相关数据"
|
||||
@search="bindSNRecordMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 可管理的SN号数量 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.length }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="140" column-key="sn_set">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchSNKeyRef"
|
||||
holderText="输入SN号以搜索相关数据"
|
||||
@search="bindSNRecordMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> SN号 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.sn_set }}
|
||||
</div>
|
||||
<el-button
|
||||
style="font-size: 1rem; font-weight: bold"
|
||||
size="small"
|
||||
type="primary"
|
||||
plain
|
||||
@click="showAll(scope.row.sn_set)"
|
||||
>
|
||||
查看全部
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<Pagination
|
||||
ref="PaginationRef"
|
||||
:active="allocationSNRecordActive"
|
||||
@sizeChangeBack="changePage"
|
||||
@search="bindSNRecordMsg"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
<DataShow ref="DataShowRef" />
|
||||
<PasswordOauth
|
||||
ref="delPasswordOauthRef"
|
||||
operateLabel="删除SN号分配记录"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch, onMounted } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import TabelTools from "../operate/tabelTools.vue";
|
||||
import TabelSelect from "../operate/tabelSelect.vue";
|
||||
import SearchKey from "../search/searchKey.vue";
|
||||
import Pagination from "../search/pagination.vue";
|
||||
import DataShow from "../operate/dataShow.vue";
|
||||
import PasswordOauth from "../operate/passwordOauth.vue";
|
||||
|
||||
import allocationSNRecordActiveStore from "../../stores/allocationSNRecord";
|
||||
|
||||
import $http from "../../api/index";
|
||||
import $url from "../../api/url";
|
||||
|
||||
import { encrypt } from "../../utils/aes";
|
||||
import { judgment } from "../../utils/judgment.js";
|
||||
import { hasNullOrEmptyPropertyWithTypeof } from "../../utils/hasNullOrEmptyPropertyWithTypeof.js";
|
||||
|
||||
const allocationSNRecordActive = allocationSNRecordActiveStore();
|
||||
|
||||
const delSelectHold = {
|
||||
single: "删除",
|
||||
multiple: "删除选中",
|
||||
all: "删除所有",
|
||||
label: "删除SN号分配记录",
|
||||
};
|
||||
const DelSelectRef = ref(null);
|
||||
const SearchAccountNameKeyRef = ref(null);
|
||||
const SearchUserUidKeyRef = ref(null);
|
||||
const SearchLengthKeyRef = ref(null);
|
||||
const SearchSNKeyRef = ref(null);
|
||||
const PaginationRef = ref(null);
|
||||
const DataShowRef = ref(null);
|
||||
const delPasswordOauthRef = ref(null);
|
||||
const dialogSearchVisible = ref(false);
|
||||
const dialogSortVisible = ref(false);
|
||||
const dialogOperationVisible = ref(false);
|
||||
const tableRef = ref();
|
||||
const offsetOff = ref(true);
|
||||
const pageCount = ref(0);
|
||||
const operate = ref("del");
|
||||
const searchOptions = reactive({
|
||||
account_name: "",
|
||||
user_uid: "",
|
||||
length: "",
|
||||
sn_set: "",
|
||||
});
|
||||
const sortOptions = reactive({});
|
||||
const tableData = ref([]);
|
||||
let singleData = reactive({});
|
||||
let operateData = reactive({});
|
||||
let operateDataClone = reactive({});
|
||||
|
||||
const showAll = (msg) => {
|
||||
DataShowRef.value.dialogMsg = msg;
|
||||
DataShowRef.value.dialogVisible = true;
|
||||
};
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "search":
|
||||
dialogSearchVisible.value = !dialogSearchVisible.value;
|
||||
allocationSNRecordActive.dialogSearchVisible = dialogSearchVisible.value;
|
||||
break;
|
||||
case "sort":
|
||||
dialogSortVisible.value = !dialogSortVisible.value;
|
||||
allocationSNRecordActive.dialogSortVisible = dialogSortVisible.value;
|
||||
break;
|
||||
case "operation":
|
||||
dialogOperationVisible.value = !dialogOperationVisible.value;
|
||||
allocationSNRecordActive.dialogOperationVisible = dialogOperationVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetOffset = () => {
|
||||
if (hasNullOrEmptyPropertyWithTypeof(searchOptions)) {
|
||||
if (PaginationRef.value.offset !== 1 && offsetOff.value) {
|
||||
PaginationRef.value.handleCurrentChange(1);
|
||||
offsetOff.value = false;
|
||||
}
|
||||
} else {
|
||||
offsetOff.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
const bindSNRecordMsg = () => {
|
||||
judgment(searchOptions, "account_name", SearchAccountNameKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "user_uid", SearchUserUidKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "length", SearchLengthKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "sn_set", SearchSNKeyRef.value, "searchMsg");
|
||||
resetOffset();
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
offset: PaginationRef.value == null ? 1 : PaginationRef.value.offset,
|
||||
limit: PaginationRef.value == null ? 10 : PaginationRef.value.limit,
|
||||
searchOptions: searchOptions,
|
||||
sortOptions: sortOptions,
|
||||
};
|
||||
$http.post($url.showAllocationSNRecord, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableData.value = res.data.SNAdminMsg;
|
||||
PaginationRef.value.dataCount = res.data.count;
|
||||
allocationSNRecordActive.dataCount = PaginationRef.value.dataCount;
|
||||
pageCount.value = Math.ceil(
|
||||
PaginationRef.value.dataCount / PaginationRef.value.limit
|
||||
);
|
||||
allocationSNRecordActive.pageCount = pageCount.value;
|
||||
if (!operateData[PaginationRef.value.offset]) return;
|
||||
} else {
|
||||
tableData.value = [];
|
||||
ElMessage.error("未查找到相关数据!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const changePage = (val) => {
|
||||
pageCount.value = Math.ceil(PaginationRef.value.dataCount / val);
|
||||
operateData = {};
|
||||
for (let i = 0; i < pageCount.value; i++) {
|
||||
operateData[i + 1] = [];
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((element) => {
|
||||
// 判断数据在第几页
|
||||
if (Math.ceil(element.location / PaginationRef.value.limit) == i + 1) {
|
||||
operateData[i + 1].push(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelectionChange = (val) => {
|
||||
operateData[PaginationRef.value.offset] = val;
|
||||
operateDataClone = JSON.parse(JSON.stringify(operateData));
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((item) => {
|
||||
delete item.origin_createdAt;
|
||||
delete item.location;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const showComfirmDialog = (singleMsg) => {
|
||||
singleData = { ...singleMsg.data };
|
||||
delete singleData.origin_createdAt;
|
||||
operate.value = singleMsg.operateType;
|
||||
if (singleMsg.operateType == "del") {
|
||||
delPasswordOauthRef.value.operateDialogVisible = true;
|
||||
}
|
||||
};
|
||||
|
||||
const requestOperate = () => {
|
||||
let operateType, url, model, password;
|
||||
if (operate.value == "del") {
|
||||
operateType = "删除";
|
||||
url = $url.deleteAllocationSNRecord;
|
||||
model = DelSelectRef.value.model;
|
||||
password = delPasswordOauthRef.value.ruleForm.password;
|
||||
}
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
model: encrypt(model),
|
||||
password: encrypt(password),
|
||||
requestMsg:
|
||||
model == "single" ? singleData : model == "multiple" ? operateDataClone : "",
|
||||
};
|
||||
$http.post(url, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableRef.value.clearSelection();
|
||||
operateData = {};
|
||||
operateDataClone = {};
|
||||
ElMessage({
|
||||
message: `${operateType}成功!`,
|
||||
type: "success",
|
||||
});
|
||||
bindSNRecordMsg();
|
||||
} else {
|
||||
ElMessage.error(`${operateType}失败!`);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ bindSNRecordMsg });
|
||||
|
||||
watch(searchOptions, (value) => {
|
||||
allocationSNRecordActive.searchOptions = value;
|
||||
});
|
||||
|
||||
watch(sortOptions, (value) => {
|
||||
allocationSNRecordActive.sortOptions = value;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
pageCount.value = allocationSNRecordActive.pageCount;
|
||||
dialogSearchVisible.value = allocationSNRecordActive.dialogSearchVisible;
|
||||
dialogSortVisible.value = allocationSNRecordActive.dialogSortVisible;
|
||||
dialogOperationVisible.value = allocationSNRecordActive.dialogOperationVisible;
|
||||
|
||||
if (dialogSearchVisible.value) {
|
||||
searchOptions.account_name = allocationSNRecordActive.searchOptions.account_name;
|
||||
searchOptions.user_uid = allocationSNRecordActive.searchOptions.user_uid;
|
||||
searchOptions.length = allocationSNRecordActive.searchOptions.length;
|
||||
searchOptions.sn_set = allocationSNRecordActive.searchOptions.sn_set;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
bindSNRecordMsg();
|
||||
}, 200);
|
||||
|
||||
setTimeout(() => {
|
||||
if (dialogSearchVisible.value) {
|
||||
SearchAccountNameKeyRef.value.searchMsg = allocationSNRecordActive.searchOptions.account_name;
|
||||
SearchUserUidKeyRef.value.searchMsg = allocationSNRecordActive.searchOptions.user_uid;
|
||||
SearchLengthKeyRef.value.searchMsg = allocationSNRecordActive.searchOptions.length;
|
||||
SearchSNKeyRef.value.searchMsg = allocationSNRecordActive.searchOptions.sn_set;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
658
src/components/mainPage/bdCard.vue
Normal file
@@ -0,0 +1,658 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 表格 -->
|
||||
<el-card>
|
||||
<div class="flex justify-center flex-wrap">
|
||||
<TabelTools @showTools="showTools" :dialogObj="bdCardMsgActive" />
|
||||
<AddNewData newDataLabel="新增北斗卡" @showAddForm="showAddForm" />
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="tableData"
|
||||
style="width: 100%"
|
||||
max-height="50rem"
|
||||
table-layout="auto"
|
||||
scrollbar-always-on
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column
|
||||
v-if="dialogOperationVisible"
|
||||
fixed="left"
|
||||
type="selection"
|
||||
width="40"
|
||||
column-key="selection"
|
||||
/>
|
||||
<TabelSelect
|
||||
v-if="dialogOperationVisible"
|
||||
ref="EditSelectRef"
|
||||
:holderText="editSelectHold"
|
||||
singleColor="primary"
|
||||
multipleColor="warning"
|
||||
allColor="danger"
|
||||
singleSize="small"
|
||||
multipleSize="small"
|
||||
allSize="small"
|
||||
:singlePlain="true"
|
||||
:multiplePlain="false"
|
||||
:allPlain="false"
|
||||
operateType="edit"
|
||||
@showComfirmDialog="showComfirmDialog"
|
||||
/>
|
||||
<TabelSelect
|
||||
v-if="dialogOperationVisible"
|
||||
ref="DelSelectRef"
|
||||
:holderText="delSelectHold"
|
||||
singleColor="danger"
|
||||
multipleColor="warning"
|
||||
allColor="danger"
|
||||
singleSize="small"
|
||||
multipleSize="small"
|
||||
allSize="small"
|
||||
:singlePlain="true"
|
||||
:multiplePlain="false"
|
||||
:allPlain="false"
|
||||
operateType="del"
|
||||
@showComfirmDialog="showComfirmDialog"
|
||||
/>
|
||||
<el-table-column min-width="100" column-key="card_id">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchCardIdKeyRef"
|
||||
holderText="输入卡号以搜索相关数据"
|
||||
@search="bdCardMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 卡号 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="SortCardIdRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="bdCardMsg"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.card_id }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="160" column-key="card_imsi">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchCardImsiKeyRef"
|
||||
holderText="输入IMSI号以搜索相关数据"
|
||||
@search="bdCardMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> IMSI号 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="SortCardImsiRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="bdCardMsg"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.card_imsi }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100" column-key="type">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectTypeSearchRef"
|
||||
holderText="选择白名单类型以搜索相关数据"
|
||||
:options="typeOptions"
|
||||
@search="bdCardMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 白名单类型 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(typeOptions, scope.row.type)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(typeOptions, scope.row.type) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="80" column-key="status">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectStatusSearchRef"
|
||||
holderText="选择绑定状态以搜索相关数据"
|
||||
:options="statusOptions"
|
||||
@search="bdCardMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 绑定状态 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(statusOptions, scope.row.status)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(statusOptions, scope.row.status) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="120" column-key="account_name">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchAccountNameKeyRef"
|
||||
holderText="输入绑定用户以搜索相关数据"
|
||||
@search="bdCardMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 绑定用户 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.account_name }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="created_at">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="createdDateTimePickerRef"
|
||||
DateTimePicker="createdDateTimePicker"
|
||||
@search="bdCardMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 注册时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="createdSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="bdCardMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.created_at }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="updated_at">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="updatedDateTimePickerRef"
|
||||
DateTimePicker="updatedMsgDateTimePicker"
|
||||
@search="bdCardMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 绑定状态变更时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="updatedSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="bdCardMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.updated_at }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<Pagination
|
||||
ref="PaginationRef"
|
||||
:active="bdCardMsgActive"
|
||||
@sizeChangeBack="changePage"
|
||||
@search="bdCardMsg"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
<AddBdCardForm ref="addBdCardFormRef" title="新增北斗卡" @reloadData="bdCardMsg" />
|
||||
<EditBdCardForm
|
||||
ref="editBdCardFormRef"
|
||||
operateLabel="编辑北斗卡"
|
||||
:editData="editData"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
<PasswordOauth
|
||||
ref="delPasswordOauthRef"
|
||||
operateLabel="删除北斗卡"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch, onMounted, nextTick } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import TabelTools from "../operate/tabelTools.vue";
|
||||
import AddNewData from "../operate/addNewData.vue";
|
||||
import TabelSelect from "../operate/tabelSelect.vue";
|
||||
import SearchKey from "../search/searchKey.vue";
|
||||
import SortSearch from "../search/sortSearch.vue";
|
||||
import SelectSearch from "../search/selectSearch.vue";
|
||||
import DateTimePicker from "../search/dateTimePicker.vue";
|
||||
import Pagination from "../search/pagination.vue";
|
||||
import AddBdCardForm from "../addNewData/bdCardForm/bdCardForm.vue";
|
||||
import EditBdCardForm from "../editData/bdCardForm.vue";
|
||||
import PasswordOauth from "../operate/passwordOauth.vue";
|
||||
|
||||
import bdCardActiveStore from "../../stores/bdCard";
|
||||
|
||||
import moment from "moment";
|
||||
|
||||
import $http from "../../api/index";
|
||||
import $url from "../../api/url";
|
||||
|
||||
import { encrypt } from "../../utils/aes";
|
||||
import { judgment } from "../../utils/judgment.js";
|
||||
import { hasNullOrEmptyPropertyWithTypeof } from "../../utils/hasNullOrEmptyPropertyWithTypeof.js";
|
||||
|
||||
const bdCardMsgActive = bdCardActiveStore();
|
||||
|
||||
const editSelectHold = {
|
||||
single: "编辑",
|
||||
multiple: "编辑选中",
|
||||
all: "编辑所有",
|
||||
label: "编辑北斗卡",
|
||||
};
|
||||
|
||||
const delSelectHold = {
|
||||
single: "删除",
|
||||
multiple: "删除选中",
|
||||
all: "删除所有",
|
||||
label: "删除北斗卡",
|
||||
};
|
||||
const EditSelectRef = ref(null);
|
||||
const DelSelectRef = ref(null);
|
||||
const SearchCardIdKeyRef = ref(null);
|
||||
const SearchCardImsiKeyRef = ref(null);
|
||||
const SelectTypeSearchRef = ref(null);
|
||||
const SelectStatusSearchRef = ref(null);
|
||||
const SearchAccountNameKeyRef = ref(null);
|
||||
const createdDateTimePickerRef = ref(null);
|
||||
const updatedDateTimePickerRef = ref(null);
|
||||
const SortCardIdRef = ref(null);
|
||||
const SortCardImsiRef = ref(null);
|
||||
const createdSortDateTimeRef = ref(null);
|
||||
const updatedSortDateTimeRef = ref(null);
|
||||
const PaginationRef = ref(null);
|
||||
const addBdCardFormRef = ref(null);
|
||||
const editBdCardFormRef = ref(null);
|
||||
const delPasswordOauthRef = ref(null);
|
||||
const dialogSearchVisible = ref(false);
|
||||
const dialogSortVisible = ref(false);
|
||||
const dialogOperationVisible = ref(false);
|
||||
const tableRef = ref();
|
||||
const offsetOff = ref(true);
|
||||
const pageCount = ref(0);
|
||||
const operate = ref("edit");
|
||||
const searchOptions = reactive({
|
||||
card_id: "",
|
||||
card_imsi: "",
|
||||
type: "",
|
||||
status: "",
|
||||
account_name: "",
|
||||
created_at: "",
|
||||
updated_at: "",
|
||||
});
|
||||
const sortOptions = reactive({
|
||||
card_id: false,
|
||||
card_imsi: false,
|
||||
created_at: false,
|
||||
updated_at: false,
|
||||
});
|
||||
const tableData = ref([]);
|
||||
const typeOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "白名单",
|
||||
style:
|
||||
"color: rgb(16, 184, 130);background-color: rgba(16, 184, 130, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "审核中",
|
||||
style:
|
||||
"color: rgb(56, 188, 248);background-color: rgba(56, 188, 248, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "黑名单",
|
||||
style: "color: rgb(240, 70, 70);background-color: rgba(240, 70, 70, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
const statusOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "未绑定",
|
||||
style: "color: rgb(255, 200, 0);background-color: rgba(255, 200, 0, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "B端绑定",
|
||||
style:
|
||||
"color: rgb(255, 100, 180);background-color: rgba(255, 100, 180, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "C端绑定",
|
||||
style:
|
||||
"color: rgb(255, 120, 20);background-color: rgba(255, 120, 20, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "3",
|
||||
label: "竞赛绑定",
|
||||
style:
|
||||
"color: rgb(20, 200, 200);background-color: rgba(20, 200, 200, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
let singleData = reactive({});
|
||||
let operateData = reactive({});
|
||||
let operateDataClone = reactive({});
|
||||
const editData = reactive({
|
||||
typeOptions,
|
||||
});
|
||||
|
||||
const showAddForm = () => {
|
||||
addBdCardFormRef.value.dialogVisible = true;
|
||||
};
|
||||
|
||||
const styleShunt = (options, data) => {
|
||||
let nowStyle;
|
||||
options.forEach((item) => {
|
||||
if (data == item.value) {
|
||||
nowStyle = item.style;
|
||||
}
|
||||
});
|
||||
return nowStyle;
|
||||
};
|
||||
|
||||
const labelShunt = (options, data) => {
|
||||
let nowLabel;
|
||||
options.forEach((item) => {
|
||||
if (data == item.value) {
|
||||
nowLabel = item.label;
|
||||
}
|
||||
});
|
||||
return nowLabel;
|
||||
};
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "search":
|
||||
dialogSearchVisible.value = !dialogSearchVisible.value;
|
||||
bdCardMsgActive.dialogSearchVisible = dialogSearchVisible.value;
|
||||
break;
|
||||
case "sort":
|
||||
dialogSortVisible.value = !dialogSortVisible.value;
|
||||
bdCardMsgActive.dialogSortVisible = dialogSortVisible.value;
|
||||
break;
|
||||
case "operation":
|
||||
dialogOperationVisible.value = !dialogOperationVisible.value;
|
||||
bdCardMsgActive.dialogOperationVisible = dialogOperationVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetOffset = () => {
|
||||
if (hasNullOrEmptyPropertyWithTypeof(searchOptions)) {
|
||||
if (PaginationRef.value.offset !== 1 && offsetOff.value) {
|
||||
PaginationRef.value.handleCurrentChange(1);
|
||||
offsetOff.value = false;
|
||||
}
|
||||
} else {
|
||||
offsetOff.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
const bdCardMsg = () => {
|
||||
judgment(searchOptions, "card_id", SearchCardIdKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "card_imsi", SearchCardImsiKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "type", SelectTypeSearchRef.value, "searchMsg");
|
||||
judgment(searchOptions, "status", SelectStatusSearchRef.value, "searchMsg");
|
||||
judgment(searchOptions, "account_name", SearchAccountNameKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "created_at", createdDateTimePickerRef.value, "searchMsg");
|
||||
judgment(searchOptions, "updated_at", updatedDateTimePickerRef.value, "searchMsg");
|
||||
judgment(sortOptions, "card_id", SortCardIdRef.value, "searchMsg");
|
||||
judgment(sortOptions, "card_imsi", SortCardImsiRef.value, "searchMsg");
|
||||
judgment(sortOptions, "created_at", createdSortDateTimeRef.value, "searchMsg");
|
||||
judgment(sortOptions, "updated_at", updatedSortDateTimeRef.value, "searchMsg");
|
||||
resetOffset();
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
offset: PaginationRef.value == null ? 1 : PaginationRef.value.offset,
|
||||
limit: PaginationRef.value == null ? 10 : PaginationRef.value.limit,
|
||||
searchOptions: searchOptions,
|
||||
sortOptions: sortOptions,
|
||||
};
|
||||
$http.post($url.showBdCard, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableData.value = res.data.bdCardMsg;
|
||||
tableData.value.forEach((item) => {
|
||||
item.origin_createdAt = item.created_at;
|
||||
item.created_at = moment
|
||||
.utc(item.created_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
item.origin_updatedAt = item.updated_at;
|
||||
item.updated_at = moment
|
||||
.utc(item.updated_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
});
|
||||
PaginationRef.value.dataCount = res.data.count;
|
||||
bdCardMsgActive.dataCount = PaginationRef.value.dataCount;
|
||||
pageCount.value = Math.ceil(
|
||||
PaginationRef.value.dataCount / PaginationRef.value.limit
|
||||
);
|
||||
bdCardMsgActive.pageCount = pageCount.value;
|
||||
if (!operateData[PaginationRef.value.offset]) return;
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
tableData.value.forEach((item) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
nextTick(() => {
|
||||
tableRef.value.toggleRowSelection(item, true);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
tableData.value = [];
|
||||
ElMessage.error("未查找到相关数据!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const changePage = (val) => {
|
||||
pageCount.value = Math.ceil(PaginationRef.value.dataCount / val);
|
||||
operateData = {};
|
||||
for (let i = 0; i < pageCount.value; i++) {
|
||||
operateData[i + 1] = [];
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((element) => {
|
||||
// 判断数据在第几页
|
||||
if (Math.ceil(element.location / PaginationRef.value.limit) == i + 1) {
|
||||
operateData[i + 1].push(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelectionChange = (val) => {
|
||||
operateData[PaginationRef.value.offset] = val;
|
||||
tableData.value.forEach((item, index) => {
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
// 数据在表格中的位置
|
||||
element.location =
|
||||
(PaginationRef.value.offset - 1) * PaginationRef.value.limit + (index + 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
operateDataClone = JSON.parse(JSON.stringify(operateData));
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((item) => {
|
||||
if (item.origin_createdAt) {
|
||||
item.created_at = item.origin_createdAt;
|
||||
}
|
||||
if (item.origin_updatedAt) {
|
||||
item.created_at = item.origin_updatedAt;
|
||||
}
|
||||
delete item.origin_createdAt;
|
||||
delete item.origin_updatedAt;
|
||||
delete item.location;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const showComfirmDialog = (singleMsg) => {
|
||||
singleData = { ...singleMsg.data };
|
||||
singleData.created_at = singleData.origin_createdAt;
|
||||
singleData.updated_at = singleData.origin_updatedAt;
|
||||
delete singleData.origin_createdAt;
|
||||
delete singleData.origin_updatedAt;
|
||||
operate.value = singleMsg.operateType;
|
||||
if (singleMsg.operateType == "edit") {
|
||||
editBdCardFormRef.value.operateDialogVisible = true;
|
||||
editBdCardFormRef.value.model = EditSelectRef.value.model;
|
||||
}
|
||||
if (singleMsg.operateType == "del") {
|
||||
delPasswordOauthRef.value.operateDialogVisible = true;
|
||||
}
|
||||
};
|
||||
|
||||
const requestOperate = () => {
|
||||
let operateType, url, model, password;
|
||||
if (operate.value == "edit") {
|
||||
operateType = "编辑";
|
||||
url = $url.editBdCard;
|
||||
model = EditSelectRef.value.model;
|
||||
password = editBdCardFormRef.value.password;
|
||||
} else if (operate.value == "del") {
|
||||
operateType = "删除";
|
||||
url = $url.deleteBdCard;
|
||||
model = DelSelectRef.value.model;
|
||||
password = delPasswordOauthRef.value.ruleForm.password;
|
||||
}
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
model: encrypt(model),
|
||||
password: encrypt(password),
|
||||
requestMsg: model == "single" ? singleData : model == "multiple" ? operateDataClone : "",
|
||||
};
|
||||
if (operate.value == "edit") {
|
||||
data.updateMsg = { ...editBdCardFormRef.value.ruleForm };
|
||||
}
|
||||
$http.post(url, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableRef.value.clearSelection();
|
||||
operateData = {};
|
||||
operateDataClone = {};
|
||||
ElMessage({
|
||||
message: `${operateType}成功!`,
|
||||
type: "success",
|
||||
});
|
||||
bdCardMsg();
|
||||
} else {
|
||||
ElMessage.error(`${operateType}失败!`);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ bdCardMsg });
|
||||
|
||||
watch(searchOptions, (value) => {
|
||||
bdCardMsgActive.searchOptions = value;
|
||||
});
|
||||
|
||||
watch(sortOptions, (value) => {
|
||||
bdCardMsgActive.sortOptions = value;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
pageCount.value = bdCardMsgActive.pageCount;
|
||||
dialogSearchVisible.value = bdCardMsgActive.dialogSearchVisible;
|
||||
dialogSortVisible.value = bdCardMsgActive.dialogSortVisible;
|
||||
dialogOperationVisible.value = bdCardMsgActive.dialogOperationVisible;
|
||||
|
||||
if (dialogSearchVisible.value) {
|
||||
searchOptions.card_id = bdCardMsgActive.searchOptions.card_id;
|
||||
searchOptions.card_imsi = bdCardMsgActive.searchOptions.card_imsi;
|
||||
searchOptions.type = bdCardMsgActive.searchOptions.type;
|
||||
searchOptions.status = bdCardMsgActive.searchOptions.status;
|
||||
searchOptions.account_name = bdCardMsgActive.searchOptions.account_name;
|
||||
searchOptions.created_at = bdCardMsgActive.searchOptions.created_at;
|
||||
searchOptions.updated_at = bdCardMsgActive.searchOptions.updated_at;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
sortOptions.card_id = bdCardMsgActive.sortOptions.card_id;
|
||||
sortOptions.card_imsi = bdCardMsgActive.sortOptions.card_imsi;
|
||||
sortOptions.created_at = bdCardMsgActive.sortOptions.created_at;
|
||||
sortOptions.updated_at = bdCardMsgActive.sortOptions.updated_at;
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
bdCardMsg();
|
||||
}, 200);
|
||||
|
||||
setTimeout(() => {
|
||||
if (dialogSearchVisible.value) {
|
||||
SearchCardIdKeyRef.value.searchMsg = bdCardMsgActive.searchOptions.card_id;
|
||||
SearchCardImsiKeyRef.value.searchMsg = bdCardMsgActive.searchOptions.card_imsi;
|
||||
SelectTypeSearchRef.value.searchMsg = bdCardMsgActive.searchOptions.type;
|
||||
SelectStatusSearchRef.value.searchMsg = bdCardMsgActive.searchOptions.status;
|
||||
SearchAccountNameKeyRef.value.searchMsg =
|
||||
bdCardMsgActive.searchOptions.account_name;
|
||||
createdDateTimePickerRef.value.created_at =
|
||||
bdCardMsgActive.searchOptions.created_at;
|
||||
updatedDateTimePickerRef.value.updated_at =
|
||||
bdCardMsgActive.searchOptions.updated_at;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
SortCardIdRef.value.searchMsg = bdCardMsgActive.sortOptions.card_id;
|
||||
SortCardImsiRef.value.searchMsg = bdCardMsgActive.sortOptions.card_imsi;
|
||||
createdSortDateTimeRef.value.searchMsg = bdCardMsgActive.sortOptions.created_at;
|
||||
updatedSortDateTimeRef.value.searchMsg = bdCardMsgActive.sortOptions.updated_at;
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
510
src/components/mainPage/bindRecord.vue
Normal file
@@ -0,0 +1,510 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 表格 -->
|
||||
<el-card>
|
||||
<div class="flex justify-center flex-wrap">
|
||||
<TabelTools @showTools="showTools" :dialogObj="bindRecordMsgActive" />
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="tableData"
|
||||
style="width: 100%"
|
||||
max-height="50rem"
|
||||
table-layout="auto"
|
||||
scrollbar-always-on
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column
|
||||
v-if="dialogOperationVisible"
|
||||
fixed="left"
|
||||
type="selection"
|
||||
width="40"
|
||||
column-key="selection"
|
||||
/>
|
||||
<TabelSelect
|
||||
v-if="dialogOperationVisible"
|
||||
ref="DelSelectRef"
|
||||
:holderText="delSelectHold"
|
||||
singleColor="danger"
|
||||
multipleColor="warning"
|
||||
allColor="danger"
|
||||
singleSize="small"
|
||||
multipleSize="small"
|
||||
allSize="small"
|
||||
:singlePlain="true"
|
||||
:multiplePlain="false"
|
||||
:allPlain="false"
|
||||
operateType="del"
|
||||
@showComfirmDialog="showComfirmDialog"
|
||||
/>
|
||||
<el-table-column min-width="140" column-key="account_name">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchAccountNameKeyRef"
|
||||
holderText="输入账户名以搜索相关数据"
|
||||
@search="bindRecordMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 账户名 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.account_name }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100" column-key="side">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectSideSearchRef"
|
||||
holderText="选择用户类型以搜索相关数据"
|
||||
:options="sideOptions"
|
||||
@search="bindRecordMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 用户类型 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(sideOptions, scope.row.side)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(sideOptions, scope.row.side) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="140" column-key="user_uid">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchUserUidKeyRef"
|
||||
holderText="输入账户uid以搜索相关数据"
|
||||
@search="bindRecordMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 账户uid </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.user_uid }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="140" column-key="card_id">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchCardIdKeyRef"
|
||||
holderText="输入卡号以搜索相关数据"
|
||||
@search="bindRecordMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 卡号 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.card_id }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100" column-key="type">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectTypeSearchRef"
|
||||
holderText="选择操作类型以搜索相关数据"
|
||||
:options="typeOptions"
|
||||
@search="bindRecordMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 操作类型 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(typeOptions, scope.row.type)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(typeOptions, scope.row.type) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="created_at">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="createdDateTimePickerRef"
|
||||
DateTimePicker="createdDateTimePicker"
|
||||
@search="bindRecordMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 记录时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="createdSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="bindRecordMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.created_at }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<Pagination
|
||||
ref="PaginationRef"
|
||||
:active="bindRecordMsgActive"
|
||||
@sizeChangeBack="changePage"
|
||||
@search="bindRecordMsg"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
<PasswordOauth
|
||||
ref="delPasswordOauthRef"
|
||||
operateLabel="删除北斗卡绑定记录"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch, onMounted, nextTick } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import TabelTools from "../operate/tabelTools.vue";
|
||||
import TabelSelect from "../operate/tabelSelect.vue";
|
||||
import SearchKey from "../search/searchKey.vue";
|
||||
import SortSearch from "../search/sortSearch.vue";
|
||||
import SelectSearch from "../search/selectSearch.vue";
|
||||
import DateTimePicker from "../search/dateTimePicker.vue";
|
||||
import Pagination from "../search/pagination.vue";
|
||||
import PasswordOauth from "../operate/passwordOauth.vue";
|
||||
|
||||
import bindRecordActiveStore from "../../stores/bindRecord";
|
||||
|
||||
import moment from "moment";
|
||||
|
||||
import $http from "../../api/index";
|
||||
import $url from "../../api/url";
|
||||
|
||||
import { encrypt } from "../../utils/aes";
|
||||
import { judgment } from "../../utils/judgment.js";
|
||||
import { hasNullOrEmptyPropertyWithTypeof } from "../../utils/hasNullOrEmptyPropertyWithTypeof.js";
|
||||
|
||||
const bindRecordMsgActive = bindRecordActiveStore();
|
||||
|
||||
const delSelectHold = {
|
||||
single: "删除",
|
||||
multiple: "删除选中",
|
||||
all: "删除所有",
|
||||
label: "删除北斗卡绑定记录",
|
||||
};
|
||||
const DelSelectRef = ref(null);
|
||||
const SearchAccountNameKeyRef = ref(null);
|
||||
const SelectSideSearchRef = ref(null);
|
||||
const SearchUserUidKeyRef = ref(null);
|
||||
const SearchCardIdKeyRef = ref(null);
|
||||
const SelectTypeSearchRef = ref(null);
|
||||
const createdDateTimePickerRef = ref(null);
|
||||
const createdSortDateTimeRef = ref(null);
|
||||
const PaginationRef = ref(null);
|
||||
const delPasswordOauthRef = ref(null);
|
||||
const dialogSearchVisible = ref(false);
|
||||
const dialogSortVisible = ref(false);
|
||||
const dialogOperationVisible = ref(false);
|
||||
const tableRef = ref();
|
||||
const offsetOff = ref(true);
|
||||
const pageCount = ref(0);
|
||||
const operate = ref("del");
|
||||
const searchOptions = reactive({
|
||||
account_name: "",
|
||||
side: "",
|
||||
user_uid: "",
|
||||
card_id: "",
|
||||
type: "",
|
||||
created_at: "",
|
||||
});
|
||||
const sortOptions = reactive({
|
||||
created_at: false,
|
||||
});
|
||||
const tableData = ref([]);
|
||||
const sideOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "B端用户",
|
||||
style: "color: rgb(255, 100, 180);background-color: rgba(255, 100, 180, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "C端用户",
|
||||
style: "color: rgb(255, 120, 20);background-color: rgba(255, 120, 20, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
const typeOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "绑定",
|
||||
style: "color: rgb(16, 184, 130);background-color: rgba(16, 184, 130, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "解绑",
|
||||
style: "color: rgb(240, 70, 70);background-color: rgba(240, 70, 70, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
let singleData = reactive({});
|
||||
let operateData = reactive({});
|
||||
let operateDataClone = reactive({});
|
||||
|
||||
const styleShunt = (options, data) => {
|
||||
let nowStyle;
|
||||
options.forEach((item) => {
|
||||
if (data == item.value) {
|
||||
nowStyle = item.style;
|
||||
}
|
||||
});
|
||||
return nowStyle;
|
||||
};
|
||||
|
||||
const labelShunt = (options, data) => {
|
||||
let nowLabel;
|
||||
options.forEach((item) => {
|
||||
if (data == item.value) {
|
||||
nowLabel = item.label;
|
||||
}
|
||||
});
|
||||
return nowLabel;
|
||||
};
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "search":
|
||||
dialogSearchVisible.value = !dialogSearchVisible.value;
|
||||
bindRecordMsgActive.dialogSearchVisible = dialogSearchVisible.value;
|
||||
break;
|
||||
case "sort":
|
||||
dialogSortVisible.value = !dialogSortVisible.value;
|
||||
bindRecordMsgActive.dialogSortVisible = dialogSortVisible.value;
|
||||
break;
|
||||
case "operation":
|
||||
dialogOperationVisible.value = !dialogOperationVisible.value;
|
||||
bindRecordMsgActive.dialogOperationVisible = dialogOperationVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetOffset = () => {
|
||||
if (hasNullOrEmptyPropertyWithTypeof(searchOptions)) {
|
||||
if (PaginationRef.value.offset !== 1 && offsetOff.value) {
|
||||
PaginationRef.value.handleCurrentChange(1);
|
||||
offsetOff.value = false;
|
||||
}
|
||||
} else {
|
||||
offsetOff.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
const bindRecordMsg = () => {
|
||||
judgment(searchOptions, "account_name", SearchAccountNameKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "side", SelectSideSearchRef.value, "searchMsg");
|
||||
judgment(searchOptions, "user_uid", SearchUserUidKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "card_id", SearchCardIdKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "type", SelectTypeSearchRef.value, "searchMsg");
|
||||
judgment(searchOptions, "created_at", createdDateTimePickerRef.value, "searchMsg");
|
||||
judgment(sortOptions, "created_at", createdSortDateTimeRef.value, "searchMsg");
|
||||
resetOffset();
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
offset: PaginationRef.value == null ? 1 : PaginationRef.value.offset,
|
||||
limit: PaginationRef.value == null ? 10 : PaginationRef.value.limit,
|
||||
searchOptions: searchOptions,
|
||||
sortOptions: sortOptions,
|
||||
};
|
||||
$http.post($url.showBindRecord, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableData.value = res.data.BindRecordMsg;
|
||||
tableData.value.forEach((item) => {
|
||||
item.origin_createdAt = item.created_at;
|
||||
item.created_at = moment
|
||||
.utc(item.created_at)
|
||||
.add(0, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
});
|
||||
PaginationRef.value.dataCount = res.data.count;
|
||||
bindRecordMsgActive.dataCount = PaginationRef.value.dataCount;
|
||||
pageCount.value = Math.ceil(
|
||||
PaginationRef.value.dataCount / PaginationRef.value.limit
|
||||
);
|
||||
bindRecordMsgActive.pageCount = pageCount.value;
|
||||
if (!operateData[PaginationRef.value.offset]) return;
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
tableData.value.forEach((item) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
nextTick(() => {
|
||||
tableRef.value.toggleRowSelection(item, true);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
tableData.value = [];
|
||||
ElMessage.error("未查找到相关数据!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const changePage = (val) => {
|
||||
pageCount.value = Math.ceil(PaginationRef.value.dataCount / val);
|
||||
operateData = {};
|
||||
for (let i = 0; i < pageCount.value; i++) {
|
||||
operateData[i + 1] = [];
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((element) => {
|
||||
// 判断数据在第几页
|
||||
if (Math.ceil(element.location / PaginationRef.value.limit) == i + 1) {
|
||||
operateData[i + 1].push(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelectionChange = (val) => {
|
||||
operateData[PaginationRef.value.offset] = val;
|
||||
tableData.value.forEach((item, index) => {
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
// 数据在表格中的位置
|
||||
element.location =
|
||||
(PaginationRef.value.offset - 1) * PaginationRef.value.limit + (index + 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
operateDataClone = JSON.parse(JSON.stringify(operateData));
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((item) => {
|
||||
if (item.origin_createdAt) {
|
||||
item.created_at = item.origin_createdAt;
|
||||
}
|
||||
delete item.origin_createdAt;
|
||||
delete item.location;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const showComfirmDialog = (singleMsg) => {
|
||||
singleData = { ...singleMsg.data };
|
||||
singleData.created_at = singleData.origin_createdAt;
|
||||
delete singleData.origin_createdAt;
|
||||
operate.value = singleMsg.operateType;
|
||||
if (singleMsg.operateType == "del") {
|
||||
delPasswordOauthRef.value.operateDialogVisible = true;
|
||||
}
|
||||
};
|
||||
|
||||
const requestOperate = () => {
|
||||
let operateType, url, model, password;
|
||||
if (operate.value == "del") {
|
||||
operateType = "删除";
|
||||
url = $url.deleteBindRecord;
|
||||
model = DelSelectRef.value.model;
|
||||
password = delPasswordOauthRef.value.ruleForm.password;
|
||||
}
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
model: encrypt(model),
|
||||
password: encrypt(password),
|
||||
requestMsg:
|
||||
model == "single" ? singleData : model == "multiple" ? operateDataClone : "",
|
||||
};
|
||||
$http.post(url, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableRef.value.clearSelection();
|
||||
operateData = {};
|
||||
operateDataClone = {};
|
||||
ElMessage({
|
||||
message: `${operateType}成功!`,
|
||||
type: "success",
|
||||
});
|
||||
bindRecordMsg();
|
||||
} else {
|
||||
ElMessage.error(`${operateType}失败!`);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ bindRecordMsg });
|
||||
|
||||
watch(searchOptions, (value) => {
|
||||
bindRecordMsgActive.searchOptions = value;
|
||||
});
|
||||
|
||||
watch(sortOptions, (value) => {
|
||||
bindRecordMsgActive.sortOptions = value;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
pageCount.value = bindRecordMsgActive.pageCount;
|
||||
dialogSearchVisible.value = bindRecordMsgActive.dialogSearchVisible;
|
||||
dialogSortVisible.value = bindRecordMsgActive.dialogSortVisible;
|
||||
dialogOperationVisible.value = bindRecordMsgActive.dialogOperationVisible;
|
||||
|
||||
if (dialogSearchVisible.value) {
|
||||
searchOptions.account_name = bindRecordMsgActive.searchOptions.account_name;
|
||||
searchOptions.side = bindRecordMsgActive.searchOptions.side;
|
||||
searchOptions.user_uid = bindRecordMsgActive.searchOptions.user_uid;
|
||||
searchOptions.card_id = bindRecordMsgActive.searchOptions.card_id;
|
||||
searchOptions.type = bindRecordMsgActive.searchOptions.type;
|
||||
searchOptions.created_at = bindRecordMsgActive.searchOptions.created_at;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
sortOptions.created_at = bindRecordMsgActive.sortOptions.created_at;
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
bindRecordMsg();
|
||||
}, 200);
|
||||
|
||||
setTimeout(() => {
|
||||
if (dialogSearchVisible.value) {
|
||||
SearchAccountNameKeyRef.value.searchMsg = bindRecordMsgActive.searchOptions.account_name;
|
||||
SelectSideSearchRef.value.searchMsg = bindRecordMsgActive.searchOptions.side;
|
||||
SearchUserUidKeyRef.value.searchMsg = bindRecordMsgActive.searchOptions.user_uid;
|
||||
SearchCardIdKeyRef.value.searchMsg = bindRecordMsgActive.searchOptions.card_id;
|
||||
SelectTypeSearchRef.value.searchMsg = bindRecordMsgActive.searchOptions.type;
|
||||
createdDateTimePickerRef.value.created_at = bindRecordMsgActive.searchOptions.created_at;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
createdSortDateTimeRef.value.searchMsg = bindRecordMsgActive.sortOptions.created_at;
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
515
src/components/mainPage/bindSNRecord.vue
Normal file
@@ -0,0 +1,515 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 表格 -->
|
||||
<el-card>
|
||||
<div class="flex justify-center flex-wrap">
|
||||
<TabelTools @showTools="showTools" :dialogObj="bindSNRecordMsgActive" />
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="tableData"
|
||||
style="width: 100%"
|
||||
max-height="50rem"
|
||||
table-layout="auto"
|
||||
scrollbar-always-on
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column
|
||||
v-if="dialogOperationVisible"
|
||||
fixed="left"
|
||||
type="selection"
|
||||
width="40"
|
||||
column-key="selection"
|
||||
/>
|
||||
<TabelSelect
|
||||
v-if="dialogOperationVisible"
|
||||
ref="DelSelectRef"
|
||||
:holderText="delSelectHold"
|
||||
singleColor="danger"
|
||||
multipleColor="warning"
|
||||
allColor="danger"
|
||||
singleSize="small"
|
||||
multipleSize="small"
|
||||
allSize="small"
|
||||
:singlePlain="true"
|
||||
:multiplePlain="false"
|
||||
:allPlain="false"
|
||||
operateType="del"
|
||||
@showComfirmDialog="showComfirmDialog"
|
||||
/>
|
||||
<el-table-column min-width="140" column-key="account_name">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchAccountNameKeyRef"
|
||||
holderText="输入账户名以搜索相关数据"
|
||||
@search="bindSNRecordMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 账户名 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.account_name }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100" column-key="side">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectSideSearchRef"
|
||||
holderText="选择用户类型以搜索相关数据"
|
||||
:options="sideOptions"
|
||||
@search="bindSNRecordMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 用户类型 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(sideOptions, scope.row.side)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(sideOptions, scope.row.side) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="140" column-key="user_uid">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchUserUidKeyRef"
|
||||
holderText="输入账户uid以搜索相关数据"
|
||||
@search="bindSNRecordMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 账户uid </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.user_uid }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="140" column-key="sn_number">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchSNKeyRef"
|
||||
holderText="输入SN号以搜索相关数据"
|
||||
@search="bindSNRecordMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> SN号 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.sn_number }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100" column-key="type">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectTypeSearchRef"
|
||||
holderText="选择操作类型以搜索相关数据"
|
||||
:options="typeOptions"
|
||||
@search="bindSNRecordMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 操作类型 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(typeOptions, scope.row.type)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(typeOptions, scope.row.type) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="created_at">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="createdDateTimePickerRef"
|
||||
DateTimePicker="createdDateTimePicker"
|
||||
@search="bindSNRecordMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 记录时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="createdSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="bindSNRecordMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.created_at }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<Pagination
|
||||
ref="PaginationRef"
|
||||
:active="bindSNRecordMsgActive"
|
||||
@sizeChangeBack="changePage"
|
||||
@search="bindSNRecordMsg"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
<PasswordOauth
|
||||
ref="delPasswordOauthRef"
|
||||
operateLabel="删除SN号绑定记录"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch, onMounted, nextTick } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import TabelTools from "../operate/tabelTools.vue";
|
||||
import TabelSelect from "../operate/tabelSelect.vue";
|
||||
import SearchKey from "../search/searchKey.vue";
|
||||
import SortSearch from "../search/sortSearch.vue";
|
||||
import SelectSearch from "../search/selectSearch.vue";
|
||||
import DateTimePicker from "../search/dateTimePicker.vue";
|
||||
import Pagination from "../search/pagination.vue";
|
||||
import PasswordOauth from "../operate/passwordOauth.vue";
|
||||
|
||||
import bindSNRecordActiveStore from "../../stores/bindSNRecord";
|
||||
|
||||
import moment from "moment";
|
||||
|
||||
import $http from "../../api/index";
|
||||
import $url from "../../api/url";
|
||||
|
||||
import { encrypt } from "../../utils/aes";
|
||||
import { judgment } from "../../utils/judgment.js";
|
||||
import { hasNullOrEmptyPropertyWithTypeof } from "../../utils/hasNullOrEmptyPropertyWithTypeof.js";
|
||||
|
||||
const bindSNRecordMsgActive = bindSNRecordActiveStore();
|
||||
|
||||
const delSelectHold = {
|
||||
single: "删除",
|
||||
multiple: "删除选中",
|
||||
all: "删除所有",
|
||||
label: "删除SN号绑定记录",
|
||||
};
|
||||
const DelSelectRef = ref(null);
|
||||
const SearchAccountNameKeyRef = ref(null);
|
||||
const SelectSideSearchRef = ref(null);
|
||||
const SearchUserUidKeyRef = ref(null);
|
||||
const SearchSNKeyRef = ref(null);
|
||||
const SelectTypeSearchRef = ref(null);
|
||||
const createdDateTimePickerRef = ref(null);
|
||||
const createdSortDateTimeRef = ref(null);
|
||||
const PaginationRef = ref(null);
|
||||
const delPasswordOauthRef = ref(null);
|
||||
const dialogSearchVisible = ref(false);
|
||||
const dialogSortVisible = ref(false);
|
||||
const dialogOperationVisible = ref(false);
|
||||
const tableRef = ref();
|
||||
const offsetOff = ref(true);
|
||||
const pageCount = ref(0);
|
||||
const operate = ref("del");
|
||||
const searchOptions = reactive({
|
||||
account_name: "",
|
||||
side: "",
|
||||
user_uid: "",
|
||||
sn_number: "",
|
||||
type: "",
|
||||
created_at: "",
|
||||
});
|
||||
const sortOptions = reactive({
|
||||
created_at: false,
|
||||
});
|
||||
const tableData = ref([]);
|
||||
const sideOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "B端用户",
|
||||
style:
|
||||
"color: rgb(255, 100, 180);background-color: rgba(255, 100, 180, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "C端用户",
|
||||
style:
|
||||
"color: rgb(255, 120, 20);background-color: rgba(255, 120, 20, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
const typeOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "绑定",
|
||||
style:
|
||||
"color: rgb(16, 184, 130);background-color: rgba(16, 184, 130, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "解绑",
|
||||
style: "color: rgb(240, 70, 70);background-color: rgba(240, 70, 70, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
let singleData = reactive({});
|
||||
let operateData = reactive({});
|
||||
let operateDataClone = reactive({});
|
||||
|
||||
const styleShunt = (options, data) => {
|
||||
let nowStyle;
|
||||
options.forEach((item) => {
|
||||
if (data == item.value) {
|
||||
nowStyle = item.style;
|
||||
}
|
||||
});
|
||||
return nowStyle;
|
||||
};
|
||||
|
||||
const labelShunt = (options, data) => {
|
||||
let nowLabel;
|
||||
options.forEach((item) => {
|
||||
if (data == item.value) {
|
||||
nowLabel = item.label;
|
||||
}
|
||||
});
|
||||
return nowLabel;
|
||||
};
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "search":
|
||||
dialogSearchVisible.value = !dialogSearchVisible.value;
|
||||
bindSNRecordMsgActive.dialogSearchVisible = dialogSearchVisible.value;
|
||||
break;
|
||||
case "sort":
|
||||
dialogSortVisible.value = !dialogSortVisible.value;
|
||||
bindSNRecordMsgActive.dialogSortVisible = dialogSortVisible.value;
|
||||
break;
|
||||
case "operation":
|
||||
dialogOperationVisible.value = !dialogOperationVisible.value;
|
||||
bindSNRecordMsgActive.dialogOperationVisible = dialogOperationVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetOffset = () => {
|
||||
if (hasNullOrEmptyPropertyWithTypeof(searchOptions)) {
|
||||
if (PaginationRef.value.offset !== 1 && offsetOff.value) {
|
||||
PaginationRef.value.handleCurrentChange(1);
|
||||
offsetOff.value = false;
|
||||
}
|
||||
} else {
|
||||
offsetOff.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
const bindSNRecordMsg = () => {
|
||||
judgment(searchOptions, "account_name", SearchAccountNameKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "side", SelectSideSearchRef.value, "searchMsg");
|
||||
judgment(searchOptions, "user_uid", SearchUserUidKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "sn_number", SearchSNKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "type", SelectTypeSearchRef.value, "searchMsg");
|
||||
judgment(searchOptions, "created_at", createdDateTimePickerRef.value, "searchMsg");
|
||||
judgment(sortOptions, "created_at", createdSortDateTimeRef.value, "searchMsg");
|
||||
resetOffset();
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
offset: PaginationRef.value == null ? 1 : PaginationRef.value.offset,
|
||||
limit: PaginationRef.value == null ? 10 : PaginationRef.value.limit,
|
||||
searchOptions: searchOptions,
|
||||
sortOptions: sortOptions,
|
||||
};
|
||||
$http.post($url.showBindSNRecord, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableData.value = res.data.BindSNRecordMsg;
|
||||
tableData.value.forEach((item) => {
|
||||
item.origin_createdAt = item.created_at;
|
||||
item.created_at = moment
|
||||
.utc(item.created_at)
|
||||
.add(0, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
});
|
||||
PaginationRef.value.dataCount = res.data.count;
|
||||
bindSNRecordMsgActive.dataCount = PaginationRef.value.dataCount;
|
||||
pageCount.value = Math.ceil(
|
||||
PaginationRef.value.dataCount / PaginationRef.value.limit
|
||||
);
|
||||
bindSNRecordMsgActive.pageCount = pageCount.value;
|
||||
if (!operateData[PaginationRef.value.offset]) return;
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
tableData.value.forEach((item) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
nextTick(() => {
|
||||
tableRef.value.toggleRowSelection(item, true);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
tableData.value = [];
|
||||
ElMessage.error("未查找到相关数据!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const changePage = (val) => {
|
||||
pageCount.value = Math.ceil(PaginationRef.value.dataCount / val);
|
||||
operateData = {};
|
||||
for (let i = 0; i < pageCount.value; i++) {
|
||||
operateData[i + 1] = [];
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((element) => {
|
||||
// 判断数据在第几页
|
||||
if (Math.ceil(element.location / PaginationRef.value.limit) == i + 1) {
|
||||
operateData[i + 1].push(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelectionChange = (val) => {
|
||||
operateData[PaginationRef.value.offset] = val;
|
||||
tableData.value.forEach((item, index) => {
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
// 数据在表格中的位置
|
||||
element.location =
|
||||
(PaginationRef.value.offset - 1) * PaginationRef.value.limit + (index + 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
operateDataClone = JSON.parse(JSON.stringify(operateData));
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((item) => {
|
||||
if (item.origin_createdAt) {
|
||||
item.created_at = item.origin_createdAt;
|
||||
}
|
||||
delete item.origin_createdAt;
|
||||
delete item.location;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const showComfirmDialog = (singleMsg) => {
|
||||
singleData = { ...singleMsg.data };
|
||||
singleData.created_at = singleData.origin_createdAt;
|
||||
delete singleData.origin_createdAt;
|
||||
operate.value = singleMsg.operateType;
|
||||
if (singleMsg.operateType == "del") {
|
||||
delPasswordOauthRef.value.operateDialogVisible = true;
|
||||
}
|
||||
};
|
||||
|
||||
const requestOperate = () => {
|
||||
let operateType, url, model, password;
|
||||
if (operate.value == "del") {
|
||||
operateType = "删除";
|
||||
url = $url.deleteBindSNRecord;
|
||||
model = DelSelectRef.value.model;
|
||||
password = delPasswordOauthRef.value.ruleForm.password;
|
||||
}
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
model: encrypt(model),
|
||||
password: encrypt(password),
|
||||
requestMsg:
|
||||
model == "single" ? singleData : model == "multiple" ? operateDataClone : "",
|
||||
};
|
||||
$http.post(url, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableRef.value.clearSelection();
|
||||
operateData = {};
|
||||
operateDataClone = {};
|
||||
ElMessage({
|
||||
message: `${operateType}成功!`,
|
||||
type: "success",
|
||||
});
|
||||
bindSNRecordMsg();
|
||||
} else {
|
||||
ElMessage.error(`${operateType}失败!`);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ bindSNRecordMsg });
|
||||
|
||||
watch(searchOptions, (value) => {
|
||||
bindSNRecordMsgActive.searchOptions = value;
|
||||
});
|
||||
|
||||
watch(sortOptions, (value) => {
|
||||
bindSNRecordMsgActive.sortOptions = value;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
pageCount.value = bindSNRecordMsgActive.pageCount;
|
||||
dialogSearchVisible.value = bindSNRecordMsgActive.dialogSearchVisible;
|
||||
dialogSortVisible.value = bindSNRecordMsgActive.dialogSortVisible;
|
||||
dialogOperationVisible.value = bindSNRecordMsgActive.dialogOperationVisible;
|
||||
|
||||
if (dialogSearchVisible.value) {
|
||||
searchOptions.account_name = bindSNRecordMsgActive.searchOptions.account_name;
|
||||
searchOptions.side = bindSNRecordMsgActive.searchOptions.side;
|
||||
searchOptions.user_uid = bindSNRecordMsgActive.searchOptions.user_uid;
|
||||
searchOptions.sn_number = bindSNRecordMsgActive.searchOptions.sn_number;
|
||||
searchOptions.type = bindSNRecordMsgActive.searchOptions.type;
|
||||
searchOptions.created_at = bindSNRecordMsgActive.searchOptions.created_at;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
sortOptions.created_at = bindSNRecordMsgActive.sortOptions.created_at;
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
bindSNRecordMsg();
|
||||
}, 200);
|
||||
|
||||
setTimeout(() => {
|
||||
if (dialogSearchVisible.value) {
|
||||
SearchAccountNameKeyRef.value.searchMsg =
|
||||
bindSNRecordMsgActive.searchOptions.account_name;
|
||||
SelectSideSearchRef.value.searchMsg = bindSNRecordMsgActive.searchOptions.side;
|
||||
SearchUserUidKeyRef.value.searchMsg = bindSNRecordMsgActive.searchOptions.user_uid;
|
||||
SearchSNKeyRef.value.searchMsg = bindSNRecordMsgActive.searchOptions.sn_number;
|
||||
SelectTypeSearchRef.value.searchMsg = bindSNRecordMsgActive.searchOptions.type;
|
||||
createdDateTimePickerRef.value.created_at =
|
||||
bindSNRecordMsgActive.searchOptions.created_at;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
createdSortDateTimeRef.value.searchMsg = bindSNRecordMsgActive.sortOptions.created_at;
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
817
src/components/mainPage/bside.vue
Normal file
@@ -0,0 +1,817 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 表格 -->
|
||||
<el-card>
|
||||
<div class="flex justify-center flex-wrap">
|
||||
<TabelTools @showTools="showTools" :dialogObj="bsideMsgActive" />
|
||||
<AddNewData newDataLabel="新增B端用户" @showAddForm="showAddForm" />
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="tableData"
|
||||
style="width: 100%"
|
||||
max-height="50rem"
|
||||
table-layout="auto"
|
||||
scrollbar-always-on
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column
|
||||
v-if="dialogOperationVisible"
|
||||
fixed="left"
|
||||
type="selection"
|
||||
width="40"
|
||||
column-key="selection"
|
||||
/>
|
||||
<TabelSelect
|
||||
v-if="dialogOperationVisible"
|
||||
ref="EditSelectRef"
|
||||
:holderText="editSelectHold"
|
||||
singleColor="primary"
|
||||
multipleColor="warning"
|
||||
allColor="danger"
|
||||
singleSize="small"
|
||||
multipleSize="small"
|
||||
allSize="small"
|
||||
:singlePlain="true"
|
||||
:multiplePlain="false"
|
||||
:allPlain="false"
|
||||
operateType="edit"
|
||||
@showComfirmDialog="showComfirmDialog"
|
||||
/>
|
||||
<TabelSelect
|
||||
v-if="dialogOperationVisible"
|
||||
ref="DelSelectRef"
|
||||
:holderText="delSelectHold"
|
||||
singleColor="danger"
|
||||
multipleColor="warning"
|
||||
allColor="danger"
|
||||
singleSize="small"
|
||||
multipleSize="small"
|
||||
allSize="small"
|
||||
:singlePlain="true"
|
||||
:multiplePlain="false"
|
||||
:allPlain="false"
|
||||
operateType="del"
|
||||
@showComfirmDialog="showComfirmDialog"
|
||||
/>
|
||||
<el-table-column min-width="100" column-key="status">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectStatusSearchRef"
|
||||
holderText="选择账号状态以搜索相关数据"
|
||||
:options="statusOptions"
|
||||
@search="bsideMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 账号状态 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(statusOptions, scope.row.status)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(statusOptions, scope.row.status) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100" column-key="role">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectRoleSearchRef"
|
||||
holderText="选择账号角色以搜索相关数据"
|
||||
:options="roleOptions"
|
||||
@search="bsideMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 账号角色 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(roleOptions, scope.row.role)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(roleOptions, scope.row.role) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="120" column-key="account_name">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchAccountNameKeyRef"
|
||||
holderText="输入账号名称以搜索相关数据"
|
||||
@search="bsideMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 账号名称 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.account_name }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="organization">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchOrganizationKeyRef"
|
||||
holderText="输入单位名称以搜索相关数据"
|
||||
@search="bsideMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 单位名称 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.organization }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100" column-key="user_name">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchUserNameKeyRef"
|
||||
holderText="输入用户姓名以搜索相关数据"
|
||||
@search="bsideMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 用户姓名 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.user_name }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="120" column-key="phone">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchPhoneKeyRef"
|
||||
holderText="输入手机号码以搜索相关数据"
|
||||
@search="bsideMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 手机号码 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.phone }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="msg">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchMsgKeyRef"
|
||||
holderText="输入基本信息以搜索相关数据"
|
||||
@search="bsideMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 基本信息 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.msg }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="created_at">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="createdDateTimePickerRef"
|
||||
DateTimePicker="createdDateTimePicker"
|
||||
@search="bsideMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 注册时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="createdSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="bsideMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.created_at }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="updated_at">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="updatedDateTimePickerRef"
|
||||
DateTimePicker="updatedMsgDateTimePicker"
|
||||
@search="bsideMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 账号状态变更时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="updatedSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="bsideMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.updated_at }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="login_at">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="loginDateTimePickerRef"
|
||||
DateTimePicker="loginMsgDateTimePicker"
|
||||
@search="bsideMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 上次登录时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="loginSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="bsideMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.login_at }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100" column-key="login_status">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectLoginStatusSearchRef"
|
||||
holderText="选择登录状态以搜索相关数据"
|
||||
:options="loginStatusOptions"
|
||||
@search="bsideMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 登录状态 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(loginStatusOptions, scope.row.login_status)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(loginStatusOptions, scope.row.login_status) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<Pagination
|
||||
ref="PaginationRef"
|
||||
:active="bsideMsgActive"
|
||||
@sizeChangeBack="changePage"
|
||||
@search="bsideMsg"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
<AddBsideForm
|
||||
ref="addBsideFormRef"
|
||||
title="新增B端用户"
|
||||
:addData="addData"
|
||||
:createdAt="null"
|
||||
@reloadData="bsideMsg"
|
||||
@remoteSearch="remoteSearch"
|
||||
/>
|
||||
<EditBsideForm
|
||||
ref="editBsideFormRef"
|
||||
operateLabel="编辑B端用户"
|
||||
:editData="editData"
|
||||
:createdAt="null"
|
||||
@requestOperate="requestOperate"
|
||||
@remoteSearch="remoteSearch"
|
||||
/>
|
||||
<PasswordOauth
|
||||
ref="delPasswordOauthRef"
|
||||
operateLabel="删除B端用户"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch, onMounted, nextTick } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import TabelTools from "../operate/tabelTools.vue";
|
||||
import AddNewData from "../operate/addNewData.vue";
|
||||
import TabelSelect from "../operate/tabelSelect.vue";
|
||||
import SearchKey from "../search/searchKey.vue";
|
||||
import SortSearch from "../search/sortSearch.vue";
|
||||
import SelectSearch from "../search/selectSearch.vue";
|
||||
import DateTimePicker from "../search/dateTimePicker.vue";
|
||||
import Pagination from "../search/pagination.vue";
|
||||
import AddBsideForm from "../addNewData/bsideForm/bsideForm.vue";
|
||||
import EditBsideForm from "../editData/bsideForm.vue";
|
||||
import PasswordOauth from "../operate/passwordOauth.vue";
|
||||
|
||||
import bsideActiveStore from "../../stores/bside";
|
||||
|
||||
import moment from "moment";
|
||||
|
||||
import $http from "../../api/index";
|
||||
import $url from "../../api/url";
|
||||
|
||||
import { encrypt } from "../../utils/aes";
|
||||
import { judgment } from "../../utils/judgment.js";
|
||||
import { hasNullOrEmptyPropertyWithTypeof } from "../../utils/hasNullOrEmptyPropertyWithTypeof.js";
|
||||
|
||||
const bsideMsgActive = bsideActiveStore();
|
||||
|
||||
const editSelectHold = {
|
||||
single: "编辑",
|
||||
multiple: "编辑选中",
|
||||
all: "编辑所有",
|
||||
label: "编辑B端用户",
|
||||
};
|
||||
|
||||
const delSelectHold = {
|
||||
single: "删除",
|
||||
multiple: "删除选中",
|
||||
all: "删除所有",
|
||||
label: "删除B端用户",
|
||||
};
|
||||
const EditSelectRef = ref(null);
|
||||
const DelSelectRef = ref(null);
|
||||
const SelectStatusSearchRef = ref(null);
|
||||
const SelectRoleSearchRef = ref(null);
|
||||
const SearchAccountNameKeyRef = ref(null);
|
||||
const SearchOrganizationKeyRef = ref(null);
|
||||
const SearchUserNameKeyRef = ref(null);
|
||||
const SearchPhoneKeyRef = ref(null);
|
||||
const SearchMsgKeyRef = ref(null);
|
||||
const createdDateTimePickerRef = ref(null);
|
||||
const updatedDateTimePickerRef = ref(null);
|
||||
const loginDateTimePickerRef = ref(null);
|
||||
const SelectLoginStatusSearchRef = ref(null);
|
||||
const createdSortDateTimeRef = ref(null);
|
||||
const updatedSortDateTimeRef = ref(null);
|
||||
const loginSortDateTimeRef = ref(null);
|
||||
const PaginationRef = ref(null);
|
||||
const addBsideFormRef = ref(null);
|
||||
const editBsideFormRef = ref(null);
|
||||
const delPasswordOauthRef = ref(null);
|
||||
const dialogSearchVisible = ref(false);
|
||||
const dialogSortVisible = ref(false);
|
||||
const dialogOperationVisible = ref(false);
|
||||
const tableRef = ref();
|
||||
const offsetOff = ref(true);
|
||||
const pageCount = ref(0);
|
||||
const operate = ref("edit");
|
||||
const searchOptions = reactive({
|
||||
status: "",
|
||||
role: "",
|
||||
account_name: "",
|
||||
organization: "",
|
||||
user_name: "",
|
||||
phone: "",
|
||||
msg: "",
|
||||
created_at: "",
|
||||
updated_at: "",
|
||||
login_at: "",
|
||||
login_status: "",
|
||||
});
|
||||
const sortOptions = reactive({
|
||||
created_at: false,
|
||||
updated_at: false,
|
||||
login_at: false,
|
||||
});
|
||||
const tableData = ref([]);
|
||||
const statusOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "默认",
|
||||
style: "color: rgb(56, 188, 248);background-color: rgba(56, 188, 248, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "正在使用",
|
||||
style: "color: rgb(16, 184, 130);background-color: rgba(16, 184, 130, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "封禁",
|
||||
style: "color: rgb(240, 70, 70);background-color: rgba(240, 70, 70, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
const roleOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "普通用户",
|
||||
style: "color: rgb(56, 188, 248);background-color: rgba(56, 188, 248, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "单位管理员",
|
||||
style: "color: rgb(255, 200, 0);background-color: rgba(255, 200, 0, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
const loginStatusOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "未登录",
|
||||
style: "color: rgb(56, 188, 248);background-color: rgba(56, 188, 248, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "已登录",
|
||||
style: "color: rgb(16, 184, 130);background-color: rgba(16, 184, 130, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
let singleData = reactive({});
|
||||
let operateData = reactive({});
|
||||
let operateDataClone = reactive({});
|
||||
const addData = reactive({
|
||||
roleOptions,
|
||||
});
|
||||
const editData = reactive({
|
||||
statusOptions,
|
||||
roleOptions,
|
||||
});
|
||||
|
||||
const showAddForm = () => {
|
||||
addBsideFormRef.value.dialogVisible = true;
|
||||
};
|
||||
|
||||
const styleShunt = (options, data) => {
|
||||
let nowStyle;
|
||||
options.forEach((item) => {
|
||||
if (data == item.value) {
|
||||
nowStyle = item.style;
|
||||
}
|
||||
});
|
||||
return nowStyle;
|
||||
};
|
||||
|
||||
const labelShunt = (options, data) => {
|
||||
let nowLabel;
|
||||
options.forEach((item) => {
|
||||
if (data == item.value) {
|
||||
nowLabel = item.label;
|
||||
}
|
||||
});
|
||||
return nowLabel;
|
||||
};
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "search":
|
||||
dialogSearchVisible.value = !dialogSearchVisible.value;
|
||||
bsideMsgActive.dialogSearchVisible = dialogSearchVisible.value;
|
||||
break;
|
||||
case "sort":
|
||||
dialogSortVisible.value = !dialogSortVisible.value;
|
||||
bsideMsgActive.dialogSortVisible = dialogSortVisible.value;
|
||||
break;
|
||||
case "operation":
|
||||
dialogOperationVisible.value = !dialogOperationVisible.value;
|
||||
bsideMsgActive.dialogOperationVisible = dialogOperationVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const remoteSearch = (query, key, timeBefor, model, operateType) => {
|
||||
const data = {
|
||||
query: query,
|
||||
key: key,
|
||||
};
|
||||
$http.post($url.SearchOrganization, data).then((res) => {
|
||||
if (res.data.code == 200) {
|
||||
if (model == "edit") {
|
||||
res.data.organization.forEach((element) => {
|
||||
let created_at = moment
|
||||
.utc(element.created_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
editBsideFormRef.value.remoteSearchRef.options.push({
|
||||
value: element.uid,
|
||||
label: element.organization_name + "------" + created_at,
|
||||
});
|
||||
});
|
||||
} else if (model == "add") {
|
||||
res.data.organization.forEach((element) => {
|
||||
let created_at = moment
|
||||
.utc(element.created_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
if (operateType == "single") {
|
||||
addBsideFormRef.value.singleAddRef.remoteSearchRef.options.push({
|
||||
value: element.uid,
|
||||
label: element.organization_name + "------" + created_at,
|
||||
});
|
||||
} else if (operateType == "multiple") {
|
||||
addBsideFormRef.value.multipleAddRef.singleAddRef.forEach((item) => {
|
||||
item.remoteSearchRef.options.push({
|
||||
value: element.uid,
|
||||
label: element.organization_name + "------" + created_at,
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
ElMessage.error("无相关数据");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const resetOffset = () => {
|
||||
if (hasNullOrEmptyPropertyWithTypeof(searchOptions)) {
|
||||
if (PaginationRef.value.offset !== 1 && offsetOff.value) {
|
||||
PaginationRef.value.handleCurrentChange(1);
|
||||
offsetOff.value = false;
|
||||
}
|
||||
} else {
|
||||
offsetOff.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
const bsideMsg = () => {
|
||||
judgment(searchOptions, "status", SelectStatusSearchRef.value, "searchMsg");
|
||||
judgment(searchOptions, "role", SelectRoleSearchRef.value, "searchMsg");
|
||||
judgment(searchOptions, "account_name", SearchAccountNameKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "organization", SearchOrganizationKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "user_name", SearchUserNameKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "phone", SearchPhoneKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "msg", SearchMsgKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "created_at", createdDateTimePickerRef.value, "searchMsg");
|
||||
judgment(searchOptions, "updated_at", updatedDateTimePickerRef.value, "searchMsg");
|
||||
judgment(searchOptions, "login_at", loginDateTimePickerRef.value, "searchMsg");
|
||||
judgment(searchOptions, "login_status", SelectLoginStatusSearchRef.value, "searchMsg");
|
||||
judgment(sortOptions, "created_at", createdSortDateTimeRef.value, "searchMsg");
|
||||
judgment(sortOptions, "updated_at", updatedSortDateTimeRef.value, "searchMsg");
|
||||
judgment(sortOptions, "login_at", loginSortDateTimeRef.value, "searchMsg");
|
||||
resetOffset();
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
offset: PaginationRef.value == null ? 1 : PaginationRef.value.offset,
|
||||
limit: PaginationRef.value == null ? 10 : PaginationRef.value.limit,
|
||||
searchOptions: searchOptions,
|
||||
sortOptions: sortOptions,
|
||||
};
|
||||
$http.post($url.showBSide, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableData.value = res.data.BSideMsg;
|
||||
tableData.value.forEach((item) => {
|
||||
item.origin_createdAt = item.created_at;
|
||||
item.created_at = moment
|
||||
.utc(item.created_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
item.origin_updatedAt = item.updated_at;
|
||||
item.updated_at = moment
|
||||
.utc(item.updated_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
item.origin_loginAt = item.login_at;
|
||||
item.login_at = moment
|
||||
.utc(item.login_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
});
|
||||
PaginationRef.value.dataCount = res.data.count;
|
||||
bsideMsgActive.dataCount = PaginationRef.value.dataCount;
|
||||
pageCount.value = Math.ceil(
|
||||
PaginationRef.value.dataCount / PaginationRef.value.limit
|
||||
);
|
||||
bsideMsgActive.pageCount = pageCount.value;
|
||||
if (!operateData[PaginationRef.value.offset]) return;
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
tableData.value.forEach((item) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
nextTick(() => {
|
||||
tableRef.value.toggleRowSelection(item, true);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
tableData.value = [];
|
||||
ElMessage.error("未查找到相关数据!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const changePage = (val) => {
|
||||
pageCount.value = Math.ceil(PaginationRef.value.dataCount / val);
|
||||
operateData = {};
|
||||
for (let i = 0; i < pageCount.value; i++) {
|
||||
operateData[i + 1] = [];
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((element) => {
|
||||
// 判断数据在第几页
|
||||
if (Math.ceil(element.location / PaginationRef.value.limit) == i + 1) {
|
||||
operateData[i + 1].push(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelectionChange = (val) => {
|
||||
operateData[PaginationRef.value.offset] = val;
|
||||
tableData.value.forEach((item, index) => {
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
// 数据在表格中的位置
|
||||
element.location =
|
||||
(PaginationRef.value.offset - 1) * PaginationRef.value.limit + (index + 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
operateDataClone = JSON.parse(JSON.stringify(operateData));
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((item) => {
|
||||
if (item.origin_createdAt) {
|
||||
item.created_at = item.origin_createdAt;
|
||||
}
|
||||
if (item.origin_updatedAt) {
|
||||
item.created_at = item.origin_updatedAt;
|
||||
}
|
||||
if (item.origin_loginAt) {
|
||||
item.created_at = item.origin_loginAt;
|
||||
}
|
||||
delete item.origin_createdAt;
|
||||
delete item.origin_updatedAt;
|
||||
delete item.origin_loginAt;
|
||||
delete item.location;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const showComfirmDialog = (singleMsg) => {
|
||||
singleData = { ...singleMsg.data };
|
||||
singleData.created_at = singleData.origin_createdAt;
|
||||
singleData.updated_at = singleData.origin_updatedAt;
|
||||
singleData.login_at = singleData.origin_loginAt;
|
||||
delete singleData.origin_createdAt;
|
||||
delete singleData.origin_updatedAt;
|
||||
delete singleData.origin_loginAt;
|
||||
operate.value = singleMsg.operateType;
|
||||
if (singleMsg.operateType == "edit") {
|
||||
editBsideFormRef.value.operateDialogVisible = true;
|
||||
editBsideFormRef.value.model = EditSelectRef.value.model;
|
||||
}
|
||||
if (singleMsg.operateType == "del") {
|
||||
delPasswordOauthRef.value.operateDialogVisible = true;
|
||||
}
|
||||
};
|
||||
|
||||
const requestOperate = () => {
|
||||
let operateType, url, model, password;
|
||||
if (operate.value == "edit") {
|
||||
operateType = "编辑";
|
||||
url = $url.editBSide;
|
||||
model = EditSelectRef.value.model;
|
||||
password = editBsideFormRef.value.password;
|
||||
} else if (operate.value == "del") {
|
||||
operateType = "删除";
|
||||
url = $url.deleteBSide;
|
||||
model = DelSelectRef.value.model;
|
||||
password = delPasswordOauthRef.value.ruleForm.password;
|
||||
}
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
model: encrypt(model),
|
||||
password: encrypt(password),
|
||||
requestMsg:
|
||||
model == "single" ? singleData : model == "multiple" ? operateDataClone : "",
|
||||
};
|
||||
if (operate.value == "edit") {
|
||||
data.updateMsg = { ...editBsideFormRef.value.ruleForm };
|
||||
for (const element in data.updateMsg) {
|
||||
if (data.updateMsg[element] == "") {
|
||||
delete data.updateMsg[element];
|
||||
}
|
||||
}
|
||||
}
|
||||
$http.post(url, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableRef.value.clearSelection();
|
||||
operateData = {};
|
||||
operateDataClone = {};
|
||||
ElMessage({
|
||||
message: `${operateType}成功!`,
|
||||
type: "success",
|
||||
});
|
||||
bsideMsg();
|
||||
} else {
|
||||
ElMessage.error(`${operateType}失败!`);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ bsideMsg });
|
||||
|
||||
watch(searchOptions, (value) => {
|
||||
bsideMsgActive.searchOptions = value;
|
||||
});
|
||||
|
||||
watch(sortOptions, (value) => {
|
||||
bsideMsgActive.sortOptions = value;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
pageCount.value = bsideMsgActive.pageCount;
|
||||
dialogSearchVisible.value = bsideMsgActive.dialogSearchVisible;
|
||||
dialogSortVisible.value = bsideMsgActive.dialogSortVisible;
|
||||
dialogOperationVisible.value = bsideMsgActive.dialogOperationVisible;
|
||||
|
||||
if (dialogSearchVisible.value) {
|
||||
searchOptions.status = bsideMsgActive.searchOptions.status;
|
||||
searchOptions.role = bsideMsgActive.searchOptions.role;
|
||||
searchOptions.account_name = bsideMsgActive.searchOptions.account_name;
|
||||
searchOptions.organization = bsideMsgActive.searchOptions.organization;
|
||||
searchOptions.user_name = bsideMsgActive.searchOptions.user_name;
|
||||
searchOptions.phone = bsideMsgActive.searchOptions.phone;
|
||||
searchOptions.msg = bsideMsgActive.searchOptions.msg;
|
||||
searchOptions.created_at = bsideMsgActive.searchOptions.created_at;
|
||||
searchOptions.updated_at = bsideMsgActive.searchOptions.updated_at;
|
||||
searchOptions.login_at = bsideMsgActive.searchOptions.login_at;
|
||||
searchOptions.login_status = bsideMsgActive.searchOptions.login_status;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
sortOptions.created_at = bsideMsgActive.sortOptions.created_at;
|
||||
sortOptions.updated_at = bsideMsgActive.sortOptions.updated_at;
|
||||
sortOptions.login_at = bsideMsgActive.sortOptions.login_at;
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
bsideMsg();
|
||||
}, 200);
|
||||
|
||||
setTimeout(() => {
|
||||
if (dialogSearchVisible.value) {
|
||||
SelectStatusSearchRef.value.searchMsg = bsideMsgActive.searchOptions.status;
|
||||
SelectRoleSearchRef.value.searchMsg = bsideMsgActive.searchOptions.role;
|
||||
SearchAccountNameKeyRef.value.searchMsg = bsideMsgActive.searchOptions.account_name;
|
||||
SearchOrganizationKeyRef.value.searchMsg =
|
||||
bsideMsgActive.searchOptions.organization;
|
||||
SearchUserNameKeyRef.value.searchMsg = bsideMsgActive.searchOptions.user_name;
|
||||
SearchPhoneKeyRef.value.searchMsg = bsideMsgActive.searchOptions.phone;
|
||||
SearchMsgKeyRef.value.searchMsg = bsideMsgActive.searchOptions.msg;
|
||||
createdDateTimePickerRef.value.created_at = bsideMsgActive.searchOptions.created_at;
|
||||
updatedDateTimePickerRef.value.updated_at = bsideMsgActive.searchOptions.updated_at;
|
||||
loginDateTimePickerRef.value.login_at = bsideMsgActive.searchOptions.login_at;
|
||||
SelectLoginStatusSearchRef.value.searchMsg =
|
||||
bsideMsgActive.searchOptions.login_status;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
createdSortDateTimeRef.value.searchMsg = bsideMsgActive.sortOptions.created_at;
|
||||
updatedSortDateTimeRef.value.searchMsg = bsideMsgActive.sortOptions.updated_at;
|
||||
loginSortDateTimeRef.value.searchMsg = bsideMsgActive.sortOptions.login_at;
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
824
src/components/mainPage/business.vue
Normal file
@@ -0,0 +1,824 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 表格 -->
|
||||
<el-card>
|
||||
<div class="flex justify-center flex-wrap">
|
||||
<TabelTools @showTools="showTools" :dialogObj="businessMsgActive" />
|
||||
<AddNewData newDataLabel="新增公司业务" @showAddForm="showAddForm" />
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="tableData"
|
||||
style="width: 100%"
|
||||
max-height="50rem"
|
||||
table-layout="auto"
|
||||
scrollbar-always-on
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column
|
||||
v-if="dialogOperationVisible"
|
||||
fixed="left"
|
||||
type="selection"
|
||||
width="40"
|
||||
column-key="selection"
|
||||
/>
|
||||
<TabelSelect
|
||||
v-if="dialogOperationVisible"
|
||||
ref="EditSelectRef"
|
||||
:holderText="editSelectHold"
|
||||
singleColor="primary"
|
||||
multipleColor="warning"
|
||||
allColor="danger"
|
||||
singleSize="small"
|
||||
multipleSize="small"
|
||||
allSize="small"
|
||||
:singlePlain="true"
|
||||
:multiplePlain="false"
|
||||
:allPlain="false"
|
||||
operateType="edit"
|
||||
singleType="single"
|
||||
@showComfirmDialog="showComfirmDialog"
|
||||
/>
|
||||
<TabelSelect
|
||||
v-if="dialogOperationVisible"
|
||||
ref="DelSelectRef"
|
||||
:holderText="delSelectHold"
|
||||
singleColor="danger"
|
||||
multipleColor="warning"
|
||||
allColor="danger"
|
||||
singleSize="small"
|
||||
multipleSize="small"
|
||||
allSize="small"
|
||||
:singlePlain="true"
|
||||
:multiplePlain="false"
|
||||
:allPlain="false"
|
||||
operateType="del"
|
||||
@showComfirmDialog="showComfirmDialog"
|
||||
/>
|
||||
<el-table-column min-width="300" column-key="salt">
|
||||
<template #header>
|
||||
<div>
|
||||
<div>
|
||||
<el-text class="mx-1"> 随机盐值 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.salt }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="300" column-key="login_url">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchLoginUrlKeyRef"
|
||||
holderText="输入业务登录网址以搜索相关数据"
|
||||
@search="businessMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 业务登录网址 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.login_url }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="300" column-key="client_url">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchClientUrlKeyRef"
|
||||
holderText="输入业务网址以搜索相关数据"
|
||||
@search="businessMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 业务网址 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.client_url }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="600" column-key="temporary_id">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchTemporaryIdKeyRef"
|
||||
holderText="输入业务临时标识以搜索相关数据"
|
||||
@search="businessMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 业务临时标识 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.temporary_id }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="client_id">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchClientIdKeyRef"
|
||||
holderText="输入业务ID以搜索相关数据"
|
||||
@search="businessMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 业务ID </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.client_id }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="client_secret">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchClientSecretKeyRef"
|
||||
holderText="输入业务密钥以搜索相关数据"
|
||||
@search="businessMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 业务密钥 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.client_secret }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="name">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchNameKeyRef"
|
||||
holderText="输入业务名称以搜索相关数据"
|
||||
@search="businessMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 业务名称 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.name }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100" column-key="type">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectTypeSearchRef"
|
||||
holderText="选择业务类型以搜索相关数据"
|
||||
:options="typeOptions"
|
||||
@search="businessMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 业务类型 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(typeOptions, scope.row.type)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(typeOptions, scope.row.type) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100" column-key="level">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectLevelSearchRef"
|
||||
holderText="选择业务等级以搜索相关数据"
|
||||
:options="levelOptions"
|
||||
@search="businessMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 业务等级 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(levelOptions, scope.row.level)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(levelOptions, scope.row.level) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100" column-key="status">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectStatusSearchRef"
|
||||
holderText="选择业务状态以搜索相关数据"
|
||||
:options="statusOptions"
|
||||
@search="businessMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 业务状态 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(statusOptions, scope.row.status)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(statusOptions, scope.row.status) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="created_at">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="createdDateTimePickerRef"
|
||||
DateTimePicker="createdDateTimePicker"
|
||||
@search="businessMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 业务开通时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="createdSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="businessMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.created_at }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="updated_at">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="updatedDateTimePickerRef"
|
||||
DateTimePicker="updatedMsgDateTimePicker"
|
||||
@search="businessMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 业务变更时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="updatedSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="businessMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.updated_at }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<Pagination
|
||||
ref="PaginationRef"
|
||||
:active="businessMsgActive"
|
||||
@sizeChangeBack="changePage"
|
||||
@search="businessMsg"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
<AddBusinessForm
|
||||
ref="addBusinessFormRef"
|
||||
title="新增公司业务"
|
||||
:addData="addData"
|
||||
:createdAt="new Date()"
|
||||
@reloadData="businessMsg"
|
||||
@remoteSearch="remoteSearch"
|
||||
/>
|
||||
<EditBusinessForm
|
||||
ref="editBusinessFormRef"
|
||||
operateLabel="编辑公司业务"
|
||||
:editData="editData"
|
||||
:createdAt="tableData.origin_createdAt"
|
||||
@requestOperate="requestOperate"
|
||||
@remoteSearch="remoteSearch"
|
||||
/>
|
||||
<PasswordOauth
|
||||
ref="delPasswordOauthRef"
|
||||
operateLabel="删除公司业务"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch, onMounted, nextTick } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import TabelTools from "../operate/tabelTools.vue";
|
||||
import AddNewData from "../operate/addNewData.vue";
|
||||
import TabelSelect from "../operate/tabelSelect.vue";
|
||||
import SearchKey from "../search/searchKey.vue";
|
||||
import SortSearch from "../search/sortSearch.vue";
|
||||
import SelectSearch from "../search/selectSearch.vue";
|
||||
import DateTimePicker from "../search/dateTimePicker.vue";
|
||||
import Pagination from "../search/pagination.vue";
|
||||
import AddBusinessForm from "../addNewData/businessForm/businessForm.vue";
|
||||
import EditBusinessForm from "../editData/businessForm.vue";
|
||||
import PasswordOauth from "../operate/passwordOauth.vue";
|
||||
|
||||
import businessActiveStore from "../../stores/business";
|
||||
|
||||
import moment from "moment";
|
||||
|
||||
import $http from "../../api/index";
|
||||
import $url from "../../api/url";
|
||||
|
||||
import { encrypt } from "../../utils/aes";
|
||||
import { judgment } from "../../utils/judgment.js";
|
||||
import { hasNullOrEmptyPropertyWithTypeof } from "../../utils/hasNullOrEmptyPropertyWithTypeof.js";
|
||||
|
||||
const businessMsgActive = businessActiveStore();
|
||||
|
||||
const editSelectHold = {
|
||||
single: "编辑",
|
||||
multiple: "编辑选中",
|
||||
all: "编辑所有",
|
||||
label: "编辑公司业务",
|
||||
};
|
||||
|
||||
const delSelectHold = {
|
||||
single: "删除",
|
||||
multiple: "删除选中",
|
||||
all: "删除所有",
|
||||
label: "删除公司业务",
|
||||
};
|
||||
const EditSelectRef = ref(null);
|
||||
const DelSelectRef = ref(null);
|
||||
const SearchLoginUrlKeyRef = ref(null);
|
||||
const SearchClientUrlKeyRef = ref(null);
|
||||
const SearchTemporaryIdKeyRef = ref(null);
|
||||
const SearchClientIdKeyRef = ref(null);
|
||||
const SearchClientSecretKeyRef = ref(null);
|
||||
const SearchNameKeyRef = ref(null);
|
||||
const SelectTypeSearchRef = ref(null);
|
||||
const SelectLevelSearchRef = ref(null);
|
||||
const SelectStatusSearchRef = ref(null);
|
||||
const createdDateTimePickerRef = ref(null);
|
||||
const updatedDateTimePickerRef = ref(null);
|
||||
const createdSortDateTimeRef = ref(null);
|
||||
const updatedSortDateTimeRef = ref(null);
|
||||
const PaginationRef = ref(null);
|
||||
const addBusinessFormRef = ref(null);
|
||||
const editBusinessFormRef = ref(null);
|
||||
const delPasswordOauthRef = ref(null);
|
||||
const dialogSearchVisible = ref(false);
|
||||
const dialogSortVisible = ref(false);
|
||||
const dialogOperationVisible = ref(false);
|
||||
const tableRef = ref();
|
||||
const offsetOff = ref(true);
|
||||
const pageCount = ref(0);
|
||||
const operate = ref("edit");
|
||||
const searchOptions = reactive({
|
||||
salt: "",
|
||||
login_url: "",
|
||||
client_url: "",
|
||||
temporary_id: "",
|
||||
client_id: "",
|
||||
client_secret: "",
|
||||
name: "",
|
||||
type: "",
|
||||
level: "",
|
||||
status: "",
|
||||
created_at: "",
|
||||
updated_at: "",
|
||||
});
|
||||
const sortOptions = reactive({
|
||||
created_at: false,
|
||||
updated_at: false,
|
||||
});
|
||||
const tableData = ref([]);
|
||||
const typeOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "B端业务",
|
||||
style: "color: rgb(255, 100, 180);background-color: rgba(255, 100, 180, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "C端业务",
|
||||
style: "color: rgb(255, 120, 20);background-color: rgba(255, 120, 20, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "通用业务",
|
||||
style: "color: rgb(255, 200, 0);background-color: rgba(255, 200, 0, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
const levelOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "一般",
|
||||
style: "color: rgb(56, 188, 248);background-color: rgba(56, 188, 248, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "重要",
|
||||
style: "color: rgb(255, 200, 0);background-color: rgba(255, 200, 0, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "紧要",
|
||||
style: "color: rgb(240, 70, 70);background-color: rgba(240, 70, 70, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
const statusOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "未启动",
|
||||
style: "color: rgb(56, 188, 248);background-color: rgba(56, 188, 248, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "已启动",
|
||||
style: "color: rgb(16, 184, 130);background-color: rgba(16, 184, 130, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "已关闭",
|
||||
style: "color: rgb(240, 70, 70);background-color: rgba(240, 70, 70, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
let singleData = reactive({});
|
||||
let operateData = reactive({});
|
||||
let operateDataClone = reactive({});
|
||||
const addData = reactive({
|
||||
typeOptions,
|
||||
levelOptions,
|
||||
statusOptions,
|
||||
});
|
||||
const editData = reactive({
|
||||
typeOptions,
|
||||
levelOptions,
|
||||
statusOptions,
|
||||
});
|
||||
|
||||
const showAddForm = () => {
|
||||
addBusinessFormRef.value.dialogVisible = true;
|
||||
};
|
||||
|
||||
const styleShunt = (options, data) => {
|
||||
let nowStyle;
|
||||
options.forEach((item) => {
|
||||
if (data == item.value) {
|
||||
nowStyle = item.style;
|
||||
}
|
||||
});
|
||||
return nowStyle;
|
||||
};
|
||||
|
||||
const labelShunt = (options, data) => {
|
||||
let nowLabel;
|
||||
options.forEach((item) => {
|
||||
if (data == item.value) {
|
||||
nowLabel = item.label;
|
||||
}
|
||||
});
|
||||
return nowLabel;
|
||||
};
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "search":
|
||||
dialogSearchVisible.value = !dialogSearchVisible.value;
|
||||
businessMsgActive.dialogSearchVisible = dialogSearchVisible.value;
|
||||
break;
|
||||
case "sort":
|
||||
dialogSortVisible.value = !dialogSortVisible.value;
|
||||
businessMsgActive.dialogSortVisible = dialogSortVisible.value;
|
||||
break;
|
||||
case "operation":
|
||||
dialogOperationVisible.value = !dialogOperationVisible.value;
|
||||
businessMsgActive.dialogOperationVisible = dialogOperationVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const remoteSearch = (query, key, timeBefor, model, operateType) => {
|
||||
const data = {
|
||||
query: query,
|
||||
key: key,
|
||||
timeBefor: timeBefor,
|
||||
};
|
||||
$http.post($url.SearchBusiness, data).then((res) => {
|
||||
if (res.data.code == 200) {
|
||||
if (model == "edit") {
|
||||
res.data.business.forEach((element) => {
|
||||
let created_at = moment
|
||||
.utc(element.created_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
editBusinessFormRef.value.remoteSearchRef.options.push({
|
||||
value: element.temporary_id,
|
||||
label: element.name + "------" + created_at,
|
||||
});
|
||||
});
|
||||
} else if (model == "add") {
|
||||
res.data.business.forEach((element) => {
|
||||
let created_at = moment
|
||||
.utc(element.created_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
if (operateType == "single") {
|
||||
addBusinessFormRef.value.singleAddRef.remoteSearchRef.options.push({
|
||||
value: element.temporary_id,
|
||||
label: element.name + "------" + created_at,
|
||||
});
|
||||
} else if (operateType == "multiple") {
|
||||
addBusinessFormRef.value.multipleAddRef.singleAddRef.forEach((item) => {
|
||||
item.remoteSearchRef.options.push({
|
||||
value: element.temporary_id,
|
||||
label: element.name + "------" + created_at,
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
ElMessage.error("无相关数据");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const resetOffset = () => {
|
||||
if (hasNullOrEmptyPropertyWithTypeof(searchOptions)) {
|
||||
if (PaginationRef.value.offset !== 1 && offsetOff.value) {
|
||||
PaginationRef.value.handleCurrentChange(1);
|
||||
offsetOff.value = false;
|
||||
}
|
||||
} else {
|
||||
offsetOff.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
const businessMsg = () => {
|
||||
judgment(searchOptions, "login_url", SearchLoginUrlKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "client_url", SearchClientUrlKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "temporary_id", SearchTemporaryIdKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "client_id", SearchClientIdKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "client_secret", SearchClientSecretKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "name", SearchNameKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "type", SelectTypeSearchRef.value, "searchMsg");
|
||||
judgment(searchOptions, "level", SelectLevelSearchRef.value, "searchMsg");
|
||||
judgment(searchOptions, "status", SelectStatusSearchRef.value, "searchMsg");
|
||||
judgment(searchOptions, "created_at", createdDateTimePickerRef.value, "searchMsg");
|
||||
judgment(searchOptions, "updated_at", updatedDateTimePickerRef.value, "searchMsg");
|
||||
judgment(sortOptions, "created_at", createdSortDateTimeRef.value, "searchMsg");
|
||||
judgment(sortOptions, "updated_at", updatedSortDateTimeRef.value, "searchMsg");
|
||||
resetOffset();
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
offset: PaginationRef.value == null ? 1 : PaginationRef.value.offset,
|
||||
limit: PaginationRef.value == null ? 10 : PaginationRef.value.limit,
|
||||
searchOptions: searchOptions,
|
||||
sortOptions: sortOptions,
|
||||
};
|
||||
$http.post($url.showBusiness, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableData.value = res.data.BusinessMsg;
|
||||
tableData.value.forEach((item) => {
|
||||
item.origin_createdAt = item.created_at;
|
||||
item.created_at = moment
|
||||
.utc(item.created_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
item.origin_updatedAt = item.updated_at;
|
||||
item.updated_at = moment
|
||||
.utc(item.updated_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
});
|
||||
PaginationRef.value.dataCount = res.data.count;
|
||||
businessMsgActive.dataCount = PaginationRef.value.dataCount;
|
||||
pageCount.value = Math.ceil(
|
||||
PaginationRef.value.dataCount / PaginationRef.value.limit
|
||||
);
|
||||
businessMsgActive.pageCount = pageCount.value;
|
||||
if (!operateData[PaginationRef.value.offset]) return;
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
tableData.value.forEach((item) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
nextTick(() => {
|
||||
tableRef.value.toggleRowSelection(item, true);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
tableData.value = [];
|
||||
ElMessage.error("未查找到相关数据!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const changePage = (val) => {
|
||||
pageCount.value = Math.ceil(PaginationRef.value.dataCount / val);
|
||||
operateData = {};
|
||||
for (let i = 0; i < pageCount.value; i++) {
|
||||
operateData[i + 1] = [];
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((element) => {
|
||||
// 判断数据在第几页
|
||||
if (Math.ceil(element.location / PaginationRef.value.limit) == i + 1) {
|
||||
operateData[i + 1].push(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelectionChange = (val) => {
|
||||
operateData[PaginationRef.value.offset] = val;
|
||||
tableData.value.forEach((item, index) => {
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
// 数据在表格中的位置
|
||||
element.location =
|
||||
(PaginationRef.value.offset - 1) * PaginationRef.value.limit + (index + 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
operateDataClone = JSON.parse(JSON.stringify(operateData));
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((item) => {
|
||||
if (item.origin_createdAt) {
|
||||
item.created_at = item.origin_createdAt;
|
||||
}
|
||||
if (item.origin_updatedAt) {
|
||||
item.created_at = item.origin_updatedAt;
|
||||
}
|
||||
delete item.origin_createdAt;
|
||||
delete item.origin_updatedAt;
|
||||
delete item.location;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const showComfirmDialog = (singleMsg) => {
|
||||
singleData = { ...singleMsg.data };
|
||||
singleData.created_at = singleData.origin_createdAt;
|
||||
singleData.updated_at = singleData.origin_updatedAt;
|
||||
delete singleData.origin_createdAt;
|
||||
delete singleData.origin_updatedAt;
|
||||
operate.value = singleMsg.operateType;
|
||||
if (singleMsg.operateType == "edit") {
|
||||
editBusinessFormRef.value.originForm({ ...singleMsg.data }, { ...editData });
|
||||
editBusinessFormRef.value.operateDialogVisible = true;
|
||||
editBusinessFormRef.value.model = EditSelectRef.value.model;
|
||||
}
|
||||
if (singleMsg.operateType == "del") {
|
||||
delPasswordOauthRef.value.operateDialogVisible = true;
|
||||
}
|
||||
};
|
||||
|
||||
const requestOperate = () => {
|
||||
let operateType, url, model, password;
|
||||
if (operate.value == "edit") {
|
||||
operateType = "编辑";
|
||||
url = $url.editBusiness;
|
||||
model = EditSelectRef.value.model;
|
||||
password = editBusinessFormRef.value.password;
|
||||
} else if (operate.value == "del") {
|
||||
operateType = "删除";
|
||||
url = $url.deleteBusiness;
|
||||
model = DelSelectRef.value.model;
|
||||
password = delPasswordOauthRef.value.ruleForm.password;
|
||||
}
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
model: encrypt(model),
|
||||
password: encrypt(password),
|
||||
requestMsg:
|
||||
model == "single" ? singleData : model == "multiple" ? operateDataClone : "",
|
||||
};
|
||||
if (operate.value == "edit") {
|
||||
data.updateMsg = { ...editBusinessFormRef.value.ruleForm };
|
||||
}
|
||||
$http.post(url, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableRef.value.clearSelection();
|
||||
operateData = {};
|
||||
operateDataClone = {};
|
||||
ElMessage({
|
||||
message: `${operateType}成功!`,
|
||||
type: "success",
|
||||
});
|
||||
businessMsg();
|
||||
} else {
|
||||
ElMessage.error(`${operateType}失败!`);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ businessMsg });
|
||||
|
||||
watch(searchOptions, (value) => {
|
||||
businessMsgActive.searchOptions = value;
|
||||
});
|
||||
|
||||
watch(sortOptions, (value) => {
|
||||
businessMsgActive.sortOptions = value;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
pageCount.value = businessMsgActive.pageCount;
|
||||
dialogSearchVisible.value = businessMsgActive.dialogSearchVisible;
|
||||
dialogSortVisible.value = businessMsgActive.dialogSortVisible;
|
||||
dialogOperationVisible.value = businessMsgActive.dialogOperationVisible;
|
||||
|
||||
if (dialogSearchVisible.value) {
|
||||
searchOptions.login_url = businessMsgActive.searchOptions.login_url;
|
||||
searchOptions.client_url = businessMsgActive.searchOptions.client_url;
|
||||
searchOptions.temporary_id = businessMsgActive.searchOptions.temporary_id;
|
||||
searchOptions.client_id = businessMsgActive.searchOptions.client_id;
|
||||
searchOptions.client_secret = businessMsgActive.searchOptions.client_secret;
|
||||
searchOptions.name = businessMsgActive.searchOptions.name;
|
||||
searchOptions.type = businessMsgActive.searchOptions.type;
|
||||
searchOptions.level = businessMsgActive.searchOptions.level;
|
||||
searchOptions.status = businessMsgActive.searchOptions.status;
|
||||
searchOptions.created_at = businessMsgActive.searchOptions.created_at;
|
||||
searchOptions.updated_at = businessMsgActive.searchOptions.updated_at;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
sortOptions.created_at = businessMsgActive.sortOptions.created_at;
|
||||
sortOptions.updated_at = businessMsgActive.sortOptions.updated_at;
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
businessMsg();
|
||||
}, 200);
|
||||
|
||||
setTimeout(() => {
|
||||
if (dialogSearchVisible.value) {
|
||||
SearchLoginUrlKeyRef.value.searchMsg = businessMsgActive.searchOptions.login_url;
|
||||
SearchClientUrlKeyRef.value.searchMsg = businessMsgActive.searchOptions.client_url;
|
||||
SearchTemporaryIdKeyRef.value.searchMsg =
|
||||
businessMsgActive.searchOptions.temporary_id;
|
||||
SearchClientIdKeyRef.value.searchMsg = businessMsgActive.searchOptions.client_id;
|
||||
SearchClientSecretKeyRef.value.searchMsg =
|
||||
businessMsgActive.searchOptions.client_secret;
|
||||
SearchNameKeyRef.value.searchMsg = businessMsgActive.searchOptions.name;
|
||||
SelectTypeSearchRef.value.searchMsg = businessMsgActive.searchOptions.type;
|
||||
SelectLevelSearchRef.value.searchMsg = businessMsgActive.searchOptions.level;
|
||||
SelectStatusSearchRef.value.searchMsg = businessMsgActive.searchOptions.status;
|
||||
createdDateTimePickerRef.value.created_at =
|
||||
businessMsgActive.searchOptions.created_at;
|
||||
updatedDateTimePickerRef.value.updated_at =
|
||||
businessMsgActive.searchOptions.updated_at;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
createdSortDateTimeRef.value.searchMsg = businessMsgActive.sortOptions.created_at;
|
||||
updatedSortDateTimeRef.value.searchMsg = businessMsgActive.sortOptions.updated_at;
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
648
src/components/mainPage/contest/account.vue
Normal file
@@ -0,0 +1,648 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 表格 -->
|
||||
<el-card>
|
||||
<div class="flex justify-center flex-wrap">
|
||||
<TabelTools @showTools="showTools" :dialogObj="accountMsgActive" />
|
||||
<AddNewData newDataLabel="新增比赛账号" @showAddForm="showAddForm" />
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="tableData"
|
||||
style="width: 100%"
|
||||
max-height="50rem"
|
||||
table-layout="auto"
|
||||
scrollbar-always-on
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column
|
||||
v-if="dialogOperationVisible"
|
||||
fixed="left"
|
||||
type="selection"
|
||||
width="40"
|
||||
column-key="selection"
|
||||
/>
|
||||
<TabelSelect
|
||||
v-if="dialogOperationVisible"
|
||||
ref="EditSelectRef"
|
||||
:holderText="editSelectHold"
|
||||
singleColor="primary"
|
||||
multipleColor="warning"
|
||||
allColor="danger"
|
||||
singleSize="small"
|
||||
multipleSize="small"
|
||||
allSize="small"
|
||||
:singlePlain="true"
|
||||
:multiplePlain="false"
|
||||
:allPlain="false"
|
||||
operateType="edit"
|
||||
@showComfirmDialog="showComfirmDialog"
|
||||
/>
|
||||
<TabelSelect
|
||||
v-if="dialogOperationVisible"
|
||||
ref="DelSelectRef"
|
||||
:holderText="delSelectHold"
|
||||
singleColor="danger"
|
||||
multipleColor="warning"
|
||||
allColor="danger"
|
||||
singleSize="small"
|
||||
multipleSize="small"
|
||||
allSize="small"
|
||||
:singlePlain="true"
|
||||
:multiplePlain="false"
|
||||
:allPlain="false"
|
||||
operateType="del"
|
||||
@showComfirmDialog="showComfirmDialog"
|
||||
/>
|
||||
<el-table-column min-width="120" :column-key="重置密码">
|
||||
<template #header>
|
||||
<div>
|
||||
<el-text class="mx-1"> 重置密码 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
style="font-weight: bold"
|
||||
type="warning"
|
||||
size="small"
|
||||
plain="true"
|
||||
@click="showResetDialog(scope.row.uid)"
|
||||
>
|
||||
重置密码
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="140" column-key="uid">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchUidKeyRef"
|
||||
holderText="输入账号uid以搜索相关数据"
|
||||
@search="accountMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 账号uid </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.uid }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="140" column-key="contest_uid">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchContestUidKeyRef"
|
||||
holderText="输入竞赛uid以搜索相关数据"
|
||||
@search="accountMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 竞赛uid </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.contest_uid }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="account_name">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchAccountNameKeyRef"
|
||||
holderText="输入账号名称以搜索相关数据"
|
||||
@search="accountMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 账号名称 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.account_name }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="80" column-key="status">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectStatusSearchRef"
|
||||
holderText="选择账号状态以搜索相关数据"
|
||||
:options="statusOptions"
|
||||
@search="accountMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 账号状态 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(statusOptions, scope.row.status)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(statusOptions, scope.row.status) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="created_at">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="createdDateTimePickerRef"
|
||||
DateTimePicker="createdDateTimePicker"
|
||||
@search="accountMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 注册时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="createdSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="accountMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.created_at }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="80" column-key="login_status">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectLoginStatusSearchRef"
|
||||
holderText="选择登录状态以搜索相关数据"
|
||||
:options="loginStatusOptions"
|
||||
@search="accountMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 登录状态 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(loginStatusOptions, scope.row.login_status)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(loginStatusOptions, scope.row.login_status) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<Pagination
|
||||
ref="PaginationRef"
|
||||
:active="accountMsgActive"
|
||||
@sizeChangeBack="changePage"
|
||||
@search="accountMsg"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
<AddAccountForm
|
||||
ref="addAccountFormRef"
|
||||
title="新增账号信息"
|
||||
@reloadData="accountMsg"
|
||||
/>
|
||||
<EditAccountForm
|
||||
ref="editAccountFormRef"
|
||||
operateLabel="编辑账号信息"
|
||||
:editData="editData"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
<PasswordOauth
|
||||
ref="delPasswordOauthRef"
|
||||
operateLabel="删除账号信息"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
<PasswordOauth
|
||||
ref="resetPasswordOauthRef"
|
||||
operateLabel="重置账号密码"
|
||||
@requestOperate="resetAccount"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch, onMounted, nextTick } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import TabelTools from "../../operate/tabelTools.vue";
|
||||
import AddNewData from "../../operate/addNewData.vue";
|
||||
import TabelSelect from "../../operate/tabelSelect.vue";
|
||||
import SearchKey from "../../search/searchKey.vue";
|
||||
import SortSearch from "../../search/sortSearch.vue";
|
||||
import SelectSearch from "../../search/selectSearch.vue";
|
||||
import DateTimePicker from "../../search/dateTimePicker.vue";
|
||||
import Pagination from "../../search/pagination.vue";
|
||||
import AddAccountForm from "../../addNewData/contest/accountForm/accountForm.vue";
|
||||
import EditAccountForm from "../../editData/contest/accountForm.vue";
|
||||
import PasswordOauth from "../../operate/passwordOauth.vue";
|
||||
|
||||
import accountActiveStore from "../../../stores/contest/account";
|
||||
|
||||
import moment from "moment";
|
||||
|
||||
import $http from "../../../api/index";
|
||||
import $url from "../../../api/url";
|
||||
|
||||
import { encrypt } from "../../../utils/aes";
|
||||
import { judgment } from "../../../utils/judgment.js";
|
||||
import { hasNullOrEmptyPropertyWithTypeof } from "../../../utils/hasNullOrEmptyPropertyWithTypeof.js";
|
||||
|
||||
const accountMsgActive = accountActiveStore();
|
||||
|
||||
const editSelectHold = {
|
||||
single: "编辑",
|
||||
multiple: "编辑选中",
|
||||
all: "编辑所有",
|
||||
label: "编辑账号信息",
|
||||
};
|
||||
|
||||
const delSelectHold = {
|
||||
single: "删除",
|
||||
multiple: "删除选中",
|
||||
all: "删除所有",
|
||||
label: "删除账号信息",
|
||||
};
|
||||
const EditSelectRef = ref(null);
|
||||
const DelSelectRef = ref(null);
|
||||
const SearchUidKeyRef = ref(null);
|
||||
const SearchContestUidKeyRef = ref(null);
|
||||
const SearchAccountNameKeyRef = ref(null);
|
||||
const SelectStatusSearchRef = ref(null);
|
||||
const createdDateTimePickerRef = ref(null);
|
||||
const SelectLoginStatusSearchRef = ref(null);
|
||||
const createdSortDateTimeRef = ref(null);
|
||||
const PaginationRef = ref(null);
|
||||
const addAccountFormRef = ref(null);
|
||||
const editAccountFormRef = ref(null);
|
||||
const delPasswordOauthRef = ref(null);
|
||||
const resetPasswordOauthRef = ref(null);
|
||||
const resetAccountUid = ref("");
|
||||
const dialogSearchVisible = ref(false);
|
||||
const dialogSortVisible = ref(false);
|
||||
const dialogOperationVisible = ref(false);
|
||||
const tableRef = ref();
|
||||
const offsetOff = ref(true);
|
||||
const pageCount = ref(0);
|
||||
const operate = ref("edit");
|
||||
const searchOptions = reactive({
|
||||
uid: "",
|
||||
contest_uid: "",
|
||||
account_name: "",
|
||||
status: "",
|
||||
created_at: "",
|
||||
login_status: "",
|
||||
});
|
||||
const sortOptions = reactive({
|
||||
created_at: false,
|
||||
});
|
||||
const tableData = ref([]);
|
||||
const statusOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "准备参赛",
|
||||
style:
|
||||
"color: rgb(56, 188, 248);background-color: rgba(56, 188, 248, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "正在参赛",
|
||||
style:
|
||||
"color: rgb(16, 184, 130);background-color: rgba(16, 184, 130, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "已经结赛",
|
||||
style:
|
||||
"color: rgb(255, 100, 180);background-color: rgba(255, 100, 180, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "3",
|
||||
label: "已被封禁",
|
||||
style: "color: rgb(240, 70, 70);background-color: rgba(240, 70, 70, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
const loginStatusOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "未登录",
|
||||
style:
|
||||
"color: rgb(56, 188, 248);background-color: rgba(56, 188, 248, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "已登录",
|
||||
style:
|
||||
"color: rgb(16, 184, 130);background-color: rgba(16, 184, 130, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
let singleData = reactive({});
|
||||
let operateData = reactive({});
|
||||
let operateDataClone = reactive({});
|
||||
const editData = reactive({
|
||||
statusOptions,
|
||||
});
|
||||
|
||||
const showAddForm = () => {
|
||||
addAccountFormRef.value.dialogVisible = true;
|
||||
};
|
||||
|
||||
const styleShunt = (options, data) => {
|
||||
let nowStyle;
|
||||
options.forEach((item) => {
|
||||
if (data == item.value) {
|
||||
nowStyle = item.style;
|
||||
}
|
||||
});
|
||||
return nowStyle;
|
||||
};
|
||||
|
||||
const labelShunt = (options, data) => {
|
||||
let nowLabel;
|
||||
options.forEach((item) => {
|
||||
if (data == item.value) {
|
||||
nowLabel = item.label;
|
||||
}
|
||||
});
|
||||
return nowLabel;
|
||||
};
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "search":
|
||||
dialogSearchVisible.value = !dialogSearchVisible.value;
|
||||
accountMsgActive.dialogSearchVisible = dialogSearchVisible.value;
|
||||
break;
|
||||
case "sort":
|
||||
dialogSortVisible.value = !dialogSortVisible.value;
|
||||
accountMsgActive.dialogSortVisible = dialogSortVisible.value;
|
||||
break;
|
||||
case "operation":
|
||||
dialogOperationVisible.value = !dialogOperationVisible.value;
|
||||
accountMsgActive.dialogOperationVisible = dialogOperationVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetOffset = () => {
|
||||
if (hasNullOrEmptyPropertyWithTypeof(searchOptions)) {
|
||||
if (PaginationRef.value.offset !== 1 && offsetOff.value) {
|
||||
PaginationRef.value.handleCurrentChange(1);
|
||||
offsetOff.value = false;
|
||||
}
|
||||
} else {
|
||||
offsetOff.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
const accountMsg = () => {
|
||||
judgment(searchOptions, "uid", SearchUidKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "contest_uid", SearchContestUidKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "account_name", SearchAccountNameKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "status", SelectStatusSearchRef.value, "searchMsg");
|
||||
judgment(searchOptions, "created_at", createdDateTimePickerRef.value, "searchMsg");
|
||||
judgment(searchOptions, "login_status", SelectLoginStatusSearchRef.value, "searchMsg");
|
||||
judgment(sortOptions, "created_at", createdSortDateTimeRef.value, "searchMsg");
|
||||
resetOffset();
|
||||
const data = {
|
||||
offset: PaginationRef.value == null ? 1 : PaginationRef.value.offset,
|
||||
limit: PaginationRef.value == null ? 10 : PaginationRef.value.limit,
|
||||
searchOptions: searchOptions,
|
||||
sortOptions: sortOptions,
|
||||
};
|
||||
$http.post($url.showAccount, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableData.value = res.data.accountMsg;
|
||||
tableData.value.forEach((item) => {
|
||||
item.origin_createdAt = item.created_at;
|
||||
item.created_at = moment
|
||||
.utc(item.created_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
item.origin_updatedAt = item.updated_at;
|
||||
item.updated_at = moment
|
||||
.utc(item.updated_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
});
|
||||
PaginationRef.value.dataCount = res.data.count;
|
||||
accountMsgActive.dataCount = PaginationRef.value.dataCount;
|
||||
pageCount.value = Math.ceil(
|
||||
PaginationRef.value.dataCount / PaginationRef.value.limit
|
||||
);
|
||||
accountMsgActive.pageCount = pageCount.value;
|
||||
if (!operateData[PaginationRef.value.offset]) return;
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
tableData.value.forEach((item) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
nextTick(() => {
|
||||
tableRef.value.toggleRowSelection(item, true);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
tableData.value = [];
|
||||
ElMessage.error("未查找到相关数据!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const changePage = (val) => {
|
||||
pageCount.value = Math.ceil(PaginationRef.value.dataCount / val);
|
||||
operateData = {};
|
||||
for (let i = 0; i < pageCount.value; i++) {
|
||||
operateData[i + 1] = [];
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((element) => {
|
||||
// 判断数据在第几页
|
||||
if (Math.ceil(element.location / PaginationRef.value.limit) == i + 1) {
|
||||
operateData[i + 1].push(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelectionChange = (val) => {
|
||||
operateData[PaginationRef.value.offset] = val;
|
||||
tableData.value.forEach((item, index) => {
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
// 数据在表格中的位置
|
||||
element.location =
|
||||
(PaginationRef.value.offset - 1) * PaginationRef.value.limit + (index + 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
operateDataClone = JSON.parse(JSON.stringify(operateData));
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((item) => {
|
||||
if (item.origin_createdAt) {
|
||||
item.created_at = item.origin_createdAt;
|
||||
}
|
||||
if (item.origin_updatedAt) {
|
||||
item.created_at = item.origin_updatedAt;
|
||||
}
|
||||
delete item.origin_createdAt;
|
||||
delete item.origin_updatedAt;
|
||||
delete item.location;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const showComfirmDialog = (singleMsg) => {
|
||||
singleData = { ...singleMsg.data };
|
||||
singleData.created_at = singleData.origin_createdAt;
|
||||
singleData.updated_at = singleData.origin_updatedAt;
|
||||
delete singleData.origin_createdAt;
|
||||
delete singleData.origin_updatedAt;
|
||||
operate.value = singleMsg.operateType;
|
||||
if (singleMsg.operateType == "edit") {
|
||||
editAccountFormRef.value.accountForm({ ...singleMsg.data });
|
||||
editAccountFormRef.value.operateDialogVisible = true;
|
||||
editAccountFormRef.value.model = EditSelectRef.value.model;
|
||||
}
|
||||
if (singleMsg.operateType == "del") {
|
||||
delPasswordOauthRef.value.operateDialogVisible = true;
|
||||
}
|
||||
};
|
||||
|
||||
const showResetDialog = (uid) => {
|
||||
resetAccountUid.value = uid;
|
||||
resetPasswordOauthRef.value.operateDialogVisible = true;
|
||||
};
|
||||
|
||||
const resetAccount = () => {
|
||||
const data = {
|
||||
account_uid: encrypt(resetAccountUid.value),
|
||||
password: encrypt(resetPasswordOauthRef.value.ruleForm.password),
|
||||
};
|
||||
$http.post($url.resetAccount, data).then((res) => {
|
||||
resetAccountUid.value = "";
|
||||
if (res.data.code === 200) {
|
||||
ElMessage({
|
||||
message: "重置账号密码成功!",
|
||||
type: "success",
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("重置账号密码失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const requestOperate = () => {
|
||||
let operateType, url, model, password;
|
||||
if (operate.value == "edit") {
|
||||
operateType = "编辑";
|
||||
url = $url.editAccount;
|
||||
model = EditSelectRef.value.model;
|
||||
password = editAccountFormRef.value.password;
|
||||
} else if (operate.value == "del") {
|
||||
operateType = "删除";
|
||||
url = $url.delAccount;
|
||||
model = DelSelectRef.value.model;
|
||||
password = delPasswordOauthRef.value.ruleForm.password;
|
||||
}
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
model: encrypt(model),
|
||||
password: encrypt(password),
|
||||
requestMsg:
|
||||
model == "single" ? singleData : model == "multiple" ? operateDataClone : "",
|
||||
};
|
||||
if (operate.value == "edit") {
|
||||
data.updateMsg = { ...editAccountFormRef.value.ruleForm };
|
||||
data.updateMsg.status = Number(data.updateMsg.status.value);
|
||||
}
|
||||
$http.post(url, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableRef.value.clearSelection();
|
||||
operateData = {};
|
||||
operateDataClone = {};
|
||||
ElMessage({
|
||||
message: `${operateType}成功!`,
|
||||
type: "success",
|
||||
});
|
||||
accountMsg();
|
||||
} else {
|
||||
ElMessage.error(`${operateType}失败!`);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ accountMsg });
|
||||
|
||||
watch(searchOptions, (value) => {
|
||||
accountMsgActive.searchOptions = value;
|
||||
});
|
||||
|
||||
watch(sortOptions, (value) => {
|
||||
accountMsgActive.sortOptions = value;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
pageCount.value = accountMsgActive.pageCount;
|
||||
dialogSearchVisible.value = accountMsgActive.dialogSearchVisible;
|
||||
dialogSortVisible.value = accountMsgActive.dialogSortVisible;
|
||||
dialogOperationVisible.value = accountMsgActive.dialogOperationVisible;
|
||||
|
||||
if (dialogSearchVisible.value) {
|
||||
searchOptions.uid = accountMsgActive.searchOptions.uid;
|
||||
searchOptions.contest_uid = accountMsgActive.searchOptions.contest_uid;
|
||||
searchOptions.account_name = accountMsgActive.searchOptions.account_name;
|
||||
searchOptions.status = accountMsgActive.searchOptions.status;
|
||||
searchOptions.created_at = accountMsgActive.searchOptions.created_at;
|
||||
searchOptions.login_status = accountMsgActive.searchOptions.login_status;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
sortOptions.created_at = accountMsgActive.sortOptions.created_at;
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
accountMsg();
|
||||
}, 200);
|
||||
|
||||
setTimeout(() => {
|
||||
if (dialogSearchVisible.value) {
|
||||
SearchUidKeyRef.value.searchMsg = accountMsgActive.searchOptions.uid;
|
||||
SearchContestUidKeyRef.value.searchMsg = accountMsgActive.searchOptions.contest_uid;
|
||||
SearchAccountNameKeyRef.value.searchMsg =
|
||||
accountMsgActive.searchOptions.account_name;
|
||||
SelectStatusSearchRef.value.searchMsg = accountMsgActive.searchOptions.status;
|
||||
createdDateTimePickerRef.value.created_at =
|
||||
accountMsgActive.searchOptions.created_at;
|
||||
SelectLoginStatusSearchRef.value.searchMsg =
|
||||
accountMsgActive.searchOptions.login_status;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
createdSortDateTimeRef.value.searchMsg = accountMsgActive.sortOptions.created_at;
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
538
src/components/mainPage/contest/choiceTopic.vue
Normal file
@@ -0,0 +1,538 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 表格 -->
|
||||
<el-card>
|
||||
<div class="flex justify-center flex-wrap">
|
||||
<TabelTools @showTools="showTools" :dialogObj="choiceTopicMsgActive" />
|
||||
<AddNewData newDataLabel="新增单选题" @showAddForm="showAddForm" />
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="tableData"
|
||||
style="width: 100%"
|
||||
max-height="50rem"
|
||||
table-layout="auto"
|
||||
scrollbar-always-on
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column
|
||||
v-if="dialogOperationVisible"
|
||||
fixed="left"
|
||||
type="selection"
|
||||
width="40"
|
||||
column-key="selection"
|
||||
/>
|
||||
<TabelSelect
|
||||
v-if="dialogOperationVisible"
|
||||
ref="EditSelectRef"
|
||||
:holderText="editSelectHold"
|
||||
singleColor="primary"
|
||||
multipleColor="warning"
|
||||
allColor="danger"
|
||||
singleSize="small"
|
||||
multipleSize="small"
|
||||
allSize="small"
|
||||
:singlePlain="true"
|
||||
:multiplePlain="false"
|
||||
:allPlain="false"
|
||||
operateType="edit"
|
||||
singleType="single"
|
||||
@showComfirmDialog="showComfirmDialog"
|
||||
/>
|
||||
<TabelSelect
|
||||
v-if="dialogOperationVisible"
|
||||
ref="DelSelectRef"
|
||||
:holderText="delSelectHold"
|
||||
singleColor="danger"
|
||||
multipleColor="warning"
|
||||
allColor="danger"
|
||||
singleSize="small"
|
||||
multipleSize="small"
|
||||
allSize="small"
|
||||
:singlePlain="true"
|
||||
:multiplePlain="false"
|
||||
:allPlain="false"
|
||||
operateType="del"
|
||||
@showComfirmDialog="showComfirmDialog"
|
||||
/>
|
||||
<el-table-column min-width="200" column-key="topic">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchTopicKeyRef"
|
||||
holderText="输入题目以搜索相关数据"
|
||||
@search="choiceTopicMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 题目 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.topic }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="options_a">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchOptionsAKeyRef"
|
||||
holderText="输入选项A以搜索相关数据"
|
||||
@search="choiceTopicMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 选项A </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.options_a }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="options_b">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchOptionsBKeyRef"
|
||||
holderText="输入选项B以搜索相关数据"
|
||||
@search="choiceTopicMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 选项B </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.options_b }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="options_c">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchOptionsCKeyRef"
|
||||
holderText="输入选项C以搜索相关数据"
|
||||
@search="choiceTopicMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 选项C </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.options_c }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="options_d">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchOptionsDKeyRef"
|
||||
holderText="输入选项D以搜索相关数据"
|
||||
@search="choiceTopicMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 选项D </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.options_d }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100" column-key="answer">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchAnswerKeyRef"
|
||||
holderText="输入答案以搜索相关数据"
|
||||
@search="choiceTopicMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 答案 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.answer }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<Pagination
|
||||
ref="PaginationRef"
|
||||
:active="choiceTopicMsgActive"
|
||||
@sizeChangeBack="changePage"
|
||||
@search="choiceTopicMsg"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
<AddChoiceTopicForm
|
||||
ref="addChoiceTopicFormRef"
|
||||
title="新增单选题"
|
||||
@reloadData="choiceTopicMsg"
|
||||
/>
|
||||
<EditChoiceTopicForm
|
||||
ref="editChoiceTopicFormRef"
|
||||
operateLabel="编辑单选题"
|
||||
:editData="editData"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
<PasswordOauth
|
||||
ref="delPasswordOauthRef"
|
||||
operateLabel="删除单选题"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch, onMounted, nextTick } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import TabelTools from "../../operate/tabelTools.vue";
|
||||
import AddNewData from "../../operate/addNewData.vue";
|
||||
import TabelSelect from "../../operate/tabelSelect.vue";
|
||||
import SearchKey from "../../search/searchKey.vue";
|
||||
import Pagination from "../../search/pagination.vue";
|
||||
import AddChoiceTopicForm from "../../addNewData/contest/choiceTopicForm/choiceTopicForm.vue";
|
||||
import EditChoiceTopicForm from "../../editData/contest/choiceTopicForm.vue";
|
||||
import PasswordOauth from "../../operate/passwordOauth.vue";
|
||||
|
||||
import choiceTopicActiveStore from "../../../stores/contest/choiceTopic";
|
||||
|
||||
import moment from "moment";
|
||||
|
||||
import $http from "../../../api/index";
|
||||
import $url from "../../../api/url";
|
||||
|
||||
import { encrypt } from "../../../utils/aes";
|
||||
import { judgment } from "../../../utils/judgment.js";
|
||||
import { hasNullOrEmptyPropertyWithTypeof } from "../../../utils/hasNullOrEmptyPropertyWithTypeof.js";
|
||||
|
||||
const choiceTopicMsgActive = choiceTopicActiveStore();
|
||||
|
||||
const editSelectHold = {
|
||||
single: "编辑",
|
||||
multiple: "编辑选中",
|
||||
all: "编辑所有",
|
||||
label: "编辑单选题",
|
||||
};
|
||||
|
||||
const delSelectHold = {
|
||||
single: "删除",
|
||||
multiple: "删除选中",
|
||||
all: "删除所有",
|
||||
label: "删除单选题",
|
||||
};
|
||||
const EditSelectRef = ref(null);
|
||||
const DelSelectRef = ref(null);
|
||||
const SearchTopicKeyRef = ref(null);
|
||||
const SearchOptionsAKeyRef = ref(null);
|
||||
const SearchOptionsBKeyRef = ref(null);
|
||||
const SearchOptionsCKeyRef = ref(null);
|
||||
const SearchOptionsDKeyRef = ref(null);
|
||||
const SearchAnswerKeyRef = ref(null);
|
||||
const PaginationRef = ref(null);
|
||||
const addChoiceTopicFormRef = ref(null);
|
||||
const editChoiceTopicFormRef = ref(null);
|
||||
const delPasswordOauthRef = ref(null);
|
||||
const dialogSearchVisible = ref(false);
|
||||
const dialogSortVisible = ref(false);
|
||||
const dialogOperationVisible = ref(false);
|
||||
const tableRef = ref();
|
||||
const offsetOff = ref(true);
|
||||
const pageCount = ref(0);
|
||||
const operate = ref("edit");
|
||||
const searchOptions = reactive({
|
||||
topic: "",
|
||||
options_a: "",
|
||||
options_b: "",
|
||||
options_c: "",
|
||||
options_d: "",
|
||||
answer: "",
|
||||
});
|
||||
const sortOptions = reactive({});
|
||||
const tableData = ref([]);
|
||||
let singleData = reactive({});
|
||||
let operateData = reactive({});
|
||||
let operateDataClone = reactive({});
|
||||
const editData = reactive({});
|
||||
|
||||
const showAddForm = () => {
|
||||
addChoiceTopicFormRef.value.dialogVisible = true;
|
||||
};
|
||||
|
||||
const styleShunt = (options, data) => {
|
||||
let nowStyle;
|
||||
options.forEach((item) => {
|
||||
if (data == item.value) {
|
||||
nowStyle = item.style;
|
||||
}
|
||||
});
|
||||
return nowStyle;
|
||||
};
|
||||
|
||||
const labelShunt = (options, data) => {
|
||||
let nowLabel;
|
||||
options.forEach((item) => {
|
||||
if (data == item.value) {
|
||||
nowLabel = item.label;
|
||||
}
|
||||
});
|
||||
return nowLabel;
|
||||
};
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "search":
|
||||
dialogSearchVisible.value = !dialogSearchVisible.value;
|
||||
choiceTopicMsgActive.dialogSearchVisible = dialogSearchVisible.value;
|
||||
break;
|
||||
case "sort":
|
||||
dialogSortVisible.value = !dialogSortVisible.value;
|
||||
choiceTopicMsgActive.dialogSortVisible = dialogSortVisible.value;
|
||||
break;
|
||||
case "operation":
|
||||
dialogOperationVisible.value = !dialogOperationVisible.value;
|
||||
choiceTopicMsgActive.dialogOperationVisible = dialogOperationVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetOffset = () => {
|
||||
if (hasNullOrEmptyPropertyWithTypeof(searchOptions)) {
|
||||
if (PaginationRef.value.offset !== 1 && offsetOff.value) {
|
||||
PaginationRef.value.handleCurrentChange(1);
|
||||
offsetOff.value = false;
|
||||
}
|
||||
} else {
|
||||
offsetOff.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
const choiceTopicMsg = () => {
|
||||
judgment(searchOptions, "topic", SearchTopicKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "options_a", SearchOptionsAKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "options_b", SearchOptionsBKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "options_c", SearchOptionsCKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "options_d", SearchOptionsDKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "answer", SearchAnswerKeyRef.value, "searchMsg");
|
||||
resetOffset();
|
||||
const data = {
|
||||
offset: PaginationRef.value == null ? 1 : PaginationRef.value.offset,
|
||||
limit: PaginationRef.value == null ? 10 : PaginationRef.value.limit,
|
||||
searchOptions: searchOptions,
|
||||
sortOptions: sortOptions,
|
||||
};
|
||||
$http.post($url.showChoiceTopic, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableData.value = res.data.choiceTopicMsg;
|
||||
tableData.value.forEach((item) => {
|
||||
item.origin_createdAt = item.created_at;
|
||||
item.created_at = moment
|
||||
.utc(item.created_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
item.origin_updatedAt = item.updated_at;
|
||||
item.updated_at = moment
|
||||
.utc(item.updated_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
});
|
||||
PaginationRef.value.dataCount = res.data.count;
|
||||
choiceTopicMsgActive.dataCount = PaginationRef.value.dataCount;
|
||||
pageCount.value = Math.ceil(
|
||||
PaginationRef.value.dataCount / PaginationRef.value.limit
|
||||
);
|
||||
choiceTopicMsgActive.pageCount = pageCount.value;
|
||||
if (!operateData[PaginationRef.value.offset]) return;
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
tableData.value.forEach((item) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
nextTick(() => {
|
||||
tableRef.value.toggleRowSelection(item, true);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
tableData.value = [];
|
||||
ElMessage.error("未查找到相关数据!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const changePage = (val) => {
|
||||
pageCount.value = Math.ceil(PaginationRef.value.dataCount / val);
|
||||
operateData = {};
|
||||
for (let i = 0; i < pageCount.value; i++) {
|
||||
operateData[i + 1] = [];
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((element) => {
|
||||
// 判断数据在第几页
|
||||
if (Math.ceil(element.location / PaginationRef.value.limit) == i + 1) {
|
||||
operateData[i + 1].push(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelectionChange = (val) => {
|
||||
operateData[PaginationRef.value.offset] = val;
|
||||
tableData.value.forEach((item, index) => {
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
// 数据在表格中的位置
|
||||
element.location =
|
||||
(PaginationRef.value.offset - 1) * PaginationRef.value.limit + (index + 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
operateDataClone = JSON.parse(JSON.stringify(operateData));
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((item) => {
|
||||
if (item.origin_createdAt) {
|
||||
item.created_at = item.origin_createdAt;
|
||||
}
|
||||
if (item.origin_updatedAt) {
|
||||
item.created_at = item.origin_updatedAt;
|
||||
}
|
||||
delete item.origin_createdAt;
|
||||
delete item.origin_updatedAt;
|
||||
delete item.location;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const showComfirmDialog = (singleMsg) => {
|
||||
singleData = { ...singleMsg.data };
|
||||
singleData.created_at = singleData.origin_createdAt;
|
||||
singleData.updated_at = singleData.origin_updatedAt;
|
||||
delete singleData.origin_createdAt;
|
||||
delete singleData.origin_updatedAt;
|
||||
operate.value = singleMsg.operateType;
|
||||
if (singleMsg.operateType == "edit") {
|
||||
editChoiceTopicFormRef.value.choiceTopicForm({ ...singleMsg.data });
|
||||
editChoiceTopicFormRef.value.operateDialogVisible = true;
|
||||
editChoiceTopicFormRef.value.model = EditSelectRef.value.model;
|
||||
}
|
||||
if (singleMsg.operateType == "del") {
|
||||
delPasswordOauthRef.value.operateDialogVisible = true;
|
||||
}
|
||||
};
|
||||
|
||||
const requestOperate = () => {
|
||||
let operateType, url, model, password;
|
||||
if (operate.value == "edit") {
|
||||
operateType = "编辑";
|
||||
url = $url.editChoiceTopic;
|
||||
model = EditSelectRef.value.model;
|
||||
password = editChoiceTopicFormRef.value.password;
|
||||
} else if (operate.value == "del") {
|
||||
operateType = "删除";
|
||||
url = $url.delChoiceTopic;
|
||||
model = DelSelectRef.value.model;
|
||||
password = delPasswordOauthRef.value.ruleForm.password;
|
||||
}
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
model: encrypt(model),
|
||||
password: encrypt(password),
|
||||
requestMsg:
|
||||
model == "single" ? singleData : model == "multiple" ? operateDataClone : "",
|
||||
};
|
||||
if (operate.value == "edit") {
|
||||
data.updateMsg = { ...editChoiceTopicFormRef.value.ruleForm };
|
||||
}
|
||||
$http.post(url, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableRef.value.clearSelection();
|
||||
operateData = {};
|
||||
operateDataClone = {};
|
||||
ElMessage({
|
||||
message: `${operateType}成功!`,
|
||||
type: "success",
|
||||
});
|
||||
choiceTopicMsg();
|
||||
} else {
|
||||
ElMessage.error(`${operateType}失败!`);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ choiceTopicMsg });
|
||||
|
||||
watch(searchOptions, (value) => {
|
||||
choiceTopicMsgActive.searchOptions = value;
|
||||
});
|
||||
|
||||
watch(sortOptions, (value) => {
|
||||
choiceTopicMsgActive.sortOptions = value;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
pageCount.value = choiceTopicMsgActive.pageCount;
|
||||
dialogSearchVisible.value = choiceTopicMsgActive.dialogSearchVisible;
|
||||
dialogSortVisible.value = choiceTopicMsgActive.dialogSortVisible;
|
||||
dialogOperationVisible.value = choiceTopicMsgActive.dialogOperationVisible;
|
||||
|
||||
if (dialogSearchVisible.value) {
|
||||
searchOptions.topic = choiceTopicMsgActive.searchOptions.topic;
|
||||
searchOptions.options_a = choiceTopicMsgActive.searchOptions.options_a;
|
||||
searchOptions.options_b = choiceTopicMsgActive.searchOptions.options_b;
|
||||
searchOptions.options_c = choiceTopicMsgActive.searchOptions.options_c;
|
||||
searchOptions.options_d = choiceTopicMsgActive.searchOptions.options_d;
|
||||
searchOptions.answer = choiceTopicMsgActive.searchOptions.answer;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
choiceTopicMsg();
|
||||
}, 200);
|
||||
|
||||
setTimeout(() => {
|
||||
if (dialogSearchVisible.value) {
|
||||
SearchTopicKeyRef.value.searchMsg = choiceTopicMsgActive.searchOptions.topic;
|
||||
SearchOptionsAKeyRef.value.searchMsg = choiceTopicMsgActive.searchOptions.options_a;
|
||||
SearchOptionsBKeyRef.value.searchMsg = choiceTopicMsgActive.searchOptions.options_b;
|
||||
SearchOptionsCKeyRef.value.searchMsg = choiceTopicMsgActive.searchOptions.options_c;
|
||||
SearchOptionsDKeyRef.value.searchMsg = choiceTopicMsgActive.searchOptions.options_d;
|
||||
SearchAnswerKeyRef.value.searchMsg = choiceTopicMsgActive.searchOptions.answer;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
928
src/components/mainPage/contest/contest.vue
Normal file
@@ -0,0 +1,928 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 表格 -->
|
||||
<el-card>
|
||||
<div class="flex justify-center flex-wrap">
|
||||
<TabelTools @showTools="showTools" :dialogObj="contestMsgActive" />
|
||||
<AddNewData newDataLabel="新增竞赛" @showAddForm="showAddForm" />
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="tableData"
|
||||
style="width: 100%"
|
||||
max-height="50rem"
|
||||
table-layout="auto"
|
||||
scrollbar-always-on
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column
|
||||
v-if="dialogOperationVisible"
|
||||
fixed="left"
|
||||
type="selection"
|
||||
width="40"
|
||||
column-key="selection"
|
||||
/>
|
||||
<TabelSelect
|
||||
v-if="dialogOperationVisible"
|
||||
ref="EditSelectRef"
|
||||
:holderText="editSelectHold"
|
||||
singleColor="primary"
|
||||
multipleColor="warning"
|
||||
allColor="danger"
|
||||
singleSize="small"
|
||||
multipleSize="small"
|
||||
allSize="small"
|
||||
:singlePlain="true"
|
||||
:multiplePlain="false"
|
||||
:allPlain="false"
|
||||
operateType="edit"
|
||||
singleType="single"
|
||||
@showComfirmDialog="showComfirmDialog"
|
||||
/>
|
||||
<TabelSelect
|
||||
v-if="dialogOperationVisible"
|
||||
ref="DelSelectRef"
|
||||
:holderText="delSelectHold"
|
||||
singleColor="danger"
|
||||
multipleColor="warning"
|
||||
allColor="danger"
|
||||
singleSize="small"
|
||||
multipleSize="small"
|
||||
allSize="small"
|
||||
:singlePlain="true"
|
||||
:multiplePlain="false"
|
||||
:allPlain="false"
|
||||
operateType="del"
|
||||
@showComfirmDialog="showComfirmDialog"
|
||||
/>
|
||||
<el-table-column min-width="140" column-key="uid">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchUidKeyRef"
|
||||
holderText="输入竞赛uid以搜索相关数据"
|
||||
@search="contestMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 竞赛uid </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.uid }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="contest_name">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchContestNameKeyRef"
|
||||
holderText="输入竞赛名称以搜索相关数据"
|
||||
@search="contestMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 竞赛名称 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.contest_name }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="contest_organizers">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearcContestOrganizersKeyRef"
|
||||
holderText="输入竞赛主办方以搜索相关数据"
|
||||
@search="contestMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 竞赛主办方 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.contest_organizers }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="120" column-key="contest_term">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchContestTermKeyRef"
|
||||
holderText="输入竞赛届数以搜索相关数据"
|
||||
@search="contestMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 竞赛届数 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.contest_term }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="120" column-key="type">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectTypeSearchRef"
|
||||
holderText="选择竞赛类型以搜索相关数据"
|
||||
:options="typeOptions"
|
||||
@search="contestMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 竞赛类型 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(typeOptions, scope.row.type)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(typeOptions, scope.row.type) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="120" column-key="status">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectStatusSearchRef"
|
||||
holderText="选择举办状态以搜索相关数据"
|
||||
:options="statusOptions"
|
||||
@search="contestMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 举办状态 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(statusOptions, scope.row.status)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(statusOptions, scope.row.status) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="online_start">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="onlineStartDateTimePickerRef"
|
||||
DateTimePicker="onlineStartMsgDateTimePicker"
|
||||
@search="contestMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 线上赛开始时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="onlineStartSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="contestMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.online_start }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="online_end">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="onlineEndDateTimePickerRef"
|
||||
DateTimePicker="onlineEndMsgDateTimePicker"
|
||||
@search="contestMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 线上赛结束时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="onlineEndSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="contestMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.online_end }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="offline_start">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="offlineStartDateTimePickerRef"
|
||||
DateTimePicker="offlineStartMsgDateTimePicker"
|
||||
@search="contestMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 线下赛开始时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="offlineStartSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="contestMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.offline_start }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="offline_end">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="offlineEndDateTimePickerRef"
|
||||
DateTimePicker="offlineEndMsgDateTimePicker"
|
||||
@search="contestMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 线下赛结束时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="offlineEndSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="contestMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.offline_end }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="contest_start">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="contestStartDateTimePickerRef"
|
||||
DateTimePicker="contestStartMsgDateTimePicker"
|
||||
@search="contestMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 竞赛开始时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="contestStartSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="contestMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.contest_start }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="contest_end">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="contestEndDateTimePickerRef"
|
||||
DateTimePicker="contestEndMsgDateTimePicker"
|
||||
@search="contestMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 竞赛结束时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="contestEndSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="contestMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.contest_end }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="created_at">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="createdDateTimePickerRef"
|
||||
DateTimePicker="createdDateTimePicker"
|
||||
@search="contestMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 创建时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="createdSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="contestMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.created_at }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<Pagination
|
||||
ref="PaginationRef"
|
||||
:active="contestMsgActive"
|
||||
@sizeChangeBack="changePage"
|
||||
@search="contestMsg"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
<AddContestForm
|
||||
ref="addContestFormRef"
|
||||
title="新增竞赛"
|
||||
:addData="addData"
|
||||
@reloadData="contestMsg"
|
||||
/>
|
||||
<EditContestForm
|
||||
ref="editContestFormRef"
|
||||
operateLabel="编辑竞赛"
|
||||
:editData="editData"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
<PasswordOauth
|
||||
ref="delPasswordOauthRef"
|
||||
operateLabel="删除竞赛"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch, onMounted, nextTick } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import TabelTools from "../../operate/tabelTools.vue";
|
||||
import AddNewData from "../../operate/addNewData.vue";
|
||||
import TabelSelect from "../../operate/tabelSelect.vue";
|
||||
import SearchKey from "../../search/searchKey.vue";
|
||||
import SortSearch from "../../search/sortSearch.vue";
|
||||
import SelectSearch from "../../search/selectSearch.vue";
|
||||
import DateTimePicker from "../../search/dateTimePicker.vue";
|
||||
import Pagination from "../../search/pagination.vue";
|
||||
import AddContestForm from "../../addNewData/contest/contestForm/contestForm.vue";
|
||||
import EditContestForm from "../../editData/contest/contestForm.vue";
|
||||
import PasswordOauth from "../../operate/passwordOauth.vue";
|
||||
|
||||
import contestActiveStore from "../../../stores/contest/contest";
|
||||
|
||||
import moment from "moment";
|
||||
|
||||
import $http from "../../../api/index";
|
||||
import $url from "../../../api/url";
|
||||
|
||||
import { encrypt } from "../../../utils/aes";
|
||||
import { judgment } from "../../../utils/judgment.js";
|
||||
import { hasNullOrEmptyPropertyWithTypeof } from "../../../utils/hasNullOrEmptyPropertyWithTypeof.js";
|
||||
|
||||
const contestMsgActive = contestActiveStore();
|
||||
|
||||
const editSelectHold = {
|
||||
single: "编辑",
|
||||
multiple: "编辑选中",
|
||||
all: "编辑所有",
|
||||
label: "编辑竞赛",
|
||||
};
|
||||
|
||||
const delSelectHold = {
|
||||
single: "删除",
|
||||
multiple: "删除选中",
|
||||
all: "删除所有",
|
||||
label: "删除竞赛",
|
||||
};
|
||||
const EditSelectRef = ref(null);
|
||||
const DelSelectRef = ref(null);
|
||||
const SearchUidKeyRef = ref(null);
|
||||
const SearchContestNameKeyRef = ref(null);
|
||||
const SearchContestOrganizersKeyRef = ref(null);
|
||||
const SearchContestTermKeyRef = ref(null);
|
||||
const SelectTypeSearchRef = ref(null);
|
||||
const SelectStatusSearchRef = ref(null);
|
||||
const onlineStartDateTimePickerRef = ref(null);
|
||||
const onlineEndDateTimePickerRef = ref(null);
|
||||
const offlineStartDateTimePickerRef = ref(null);
|
||||
const offlineEndDateTimePickerRef = ref(null);
|
||||
const contestStartDateTimePickerRef = ref(null);
|
||||
const contestEndDateTimePickerRef = ref(null);
|
||||
const createdDateTimePickerRef = ref(null);
|
||||
const onlineStartSortDateTimeRef = ref(null);
|
||||
const onlineEndSortDateTimeRef = ref(null);
|
||||
const offlineStartSortDateTimeRef = ref(null);
|
||||
const offlineEndSortDateTimeRef = ref(null);
|
||||
const contestStartSortDateTimeRef = ref(null);
|
||||
const contestEndSortDateTimeRef = ref(null);
|
||||
const createdSortDateTimeRef = ref(null);
|
||||
const PaginationRef = ref(null);
|
||||
const addContestFormRef = ref(null);
|
||||
const editContestFormRef = ref(null);
|
||||
const delPasswordOauthRef = ref(null);
|
||||
const dialogSearchVisible = ref(false);
|
||||
const dialogSortVisible = ref(false);
|
||||
const dialogOperationVisible = ref(false);
|
||||
const tableRef = ref();
|
||||
const offsetOff = ref(true);
|
||||
const pageCount = ref(0);
|
||||
const operate = ref("edit");
|
||||
const searchOptions = reactive({
|
||||
uid: "",
|
||||
contest_name: "",
|
||||
contest_organizers: "",
|
||||
contest_term: "",
|
||||
type: "",
|
||||
status: "",
|
||||
online_start: "",
|
||||
online_end: "",
|
||||
offline_start: "",
|
||||
offline_end: "",
|
||||
contest_start: "",
|
||||
contest_end: "",
|
||||
created_at: "",
|
||||
});
|
||||
const sortOptions = reactive({
|
||||
online_start: false,
|
||||
online_end: false,
|
||||
offline_start: false,
|
||||
offline_end: false,
|
||||
contest_start: false,
|
||||
contest_end: false,
|
||||
created_at: false,
|
||||
});
|
||||
const tableData = ref([]);
|
||||
const typeOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "线上赛",
|
||||
style:
|
||||
"color: rgb(56, 188, 248);background-color: rgba(56, 188, 248, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "线下赛",
|
||||
style:
|
||||
"color: rgb(16, 184, 130);background-color: rgba(16, 184, 130, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
const statusOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "准备开赛",
|
||||
style:
|
||||
"color: rgb(56, 188, 248);background-color: rgba(56, 188, 248, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "正在进行",
|
||||
style:
|
||||
"color: rgb(16, 184, 130);background-color: rgba(16, 184, 130, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "已经结赛",
|
||||
style:
|
||||
"color: rgb(255, 100, 180);background-color: rgba(255, 100, 180, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "3",
|
||||
label: "停止举办",
|
||||
style: "color: rgb(240, 70, 70);background-color: rgba(240, 70, 70, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
let singleData = reactive({});
|
||||
let operateData = reactive({});
|
||||
let operateDataClone = reactive({});
|
||||
const addData = reactive({
|
||||
typeOptions,
|
||||
});
|
||||
const editData = reactive({
|
||||
typeOptions,
|
||||
statusOptions,
|
||||
});
|
||||
|
||||
const showAddForm = () => {
|
||||
addContestFormRef.value.dialogVisible = true;
|
||||
};
|
||||
|
||||
const styleShunt = (options, data) => {
|
||||
let nowStyle;
|
||||
options.forEach((item) => {
|
||||
if (data == item.value) {
|
||||
nowStyle = item.style;
|
||||
}
|
||||
});
|
||||
return nowStyle;
|
||||
};
|
||||
|
||||
const labelShunt = (options, data) => {
|
||||
let nowLabel;
|
||||
options.forEach((item) => {
|
||||
if (data == item.value) {
|
||||
nowLabel = item.label;
|
||||
}
|
||||
});
|
||||
return nowLabel;
|
||||
};
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "search":
|
||||
dialogSearchVisible.value = !dialogSearchVisible.value;
|
||||
contestMsgActive.dialogSearchVisible = dialogSearchVisible.value;
|
||||
break;
|
||||
case "sort":
|
||||
dialogSortVisible.value = !dialogSortVisible.value;
|
||||
contestMsgActive.dialogSortVisible = dialogSortVisible.value;
|
||||
break;
|
||||
case "operation":
|
||||
dialogOperationVisible.value = !dialogOperationVisible.value;
|
||||
contestMsgActive.dialogOperationVisible = dialogOperationVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetOffset = () => {
|
||||
if (hasNullOrEmptyPropertyWithTypeof(searchOptions)) {
|
||||
if (PaginationRef.value.offset !== 1 && offsetOff.value) {
|
||||
PaginationRef.value.handleCurrentChange(1);
|
||||
offsetOff.value = false;
|
||||
}
|
||||
} else {
|
||||
offsetOff.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
const contestMsg = () => {
|
||||
judgment(searchOptions, "uid", SearchUidKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "contest_name", SearchContestNameKeyRef.value, "searchMsg");
|
||||
judgment(
|
||||
searchOptions,
|
||||
"contest_organizers",
|
||||
SearchContestOrganizersKeyRef.value,
|
||||
"searchMsg"
|
||||
);
|
||||
judgment(searchOptions, "contest_term", SearchContestTermKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "type", SelectTypeSearchRef.value, "searchMsg");
|
||||
judgment(searchOptions, "status", SelectStatusSearchRef.value, "searchMsg");
|
||||
judgment(
|
||||
searchOptions,
|
||||
"online_start",
|
||||
onlineStartDateTimePickerRef.value,
|
||||
"searchMsg"
|
||||
);
|
||||
judgment(searchOptions, "online_end", onlineEndDateTimePickerRef.value, "searchMsg");
|
||||
judgment(
|
||||
searchOptions,
|
||||
"offline_start",
|
||||
offlineStartDateTimePickerRef.value,
|
||||
"searchMsg"
|
||||
);
|
||||
judgment(searchOptions, "offline_end", offlineEndDateTimePickerRef.value, "searchMsg");
|
||||
judgment(
|
||||
searchOptions,
|
||||
"contest_start",
|
||||
contestStartDateTimePickerRef.value,
|
||||
"searchMsg"
|
||||
);
|
||||
judgment(searchOptions, "contest_end", contestEndDateTimePickerRef.value, "searchMsg");
|
||||
judgment(searchOptions, "created_at", createdDateTimePickerRef.value, "searchMsg");
|
||||
judgment(sortOptions, "online_start", onlineStartSortDateTimeRef.value, "searchMsg");
|
||||
judgment(sortOptions, "online_end", onlineEndSortDateTimeRef.value, "searchMsg");
|
||||
judgment(sortOptions, "offline_start", offlineStartSortDateTimeRef.value, "searchMsg");
|
||||
judgment(sortOptions, "offline_end", offlineEndSortDateTimeRef.value, "searchMsg");
|
||||
judgment(sortOptions, "contest_start", contestStartSortDateTimeRef.value, "searchMsg");
|
||||
judgment(sortOptions, "contest_end", contestEndSortDateTimeRef.value, "searchMsg");
|
||||
judgment(sortOptions, "created_at", createdSortDateTimeRef.value, "searchMsg");
|
||||
resetOffset();
|
||||
const data = {
|
||||
offset: PaginationRef.value == null ? 1 : PaginationRef.value.offset,
|
||||
limit: PaginationRef.value == null ? 10 : PaginationRef.value.limit,
|
||||
searchOptions: searchOptions,
|
||||
sortOptions: sortOptions,
|
||||
};
|
||||
$http.post($url.showContest, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableData.value = res.data.contestMsg;
|
||||
tableData.value.forEach((item) => {
|
||||
item.origin_onlineStart = item.online_start;
|
||||
item.online_start = moment
|
||||
.utc(item.online_start)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
item.origin_onlineEnd = item.online_end;
|
||||
item.online_end = moment
|
||||
.utc(item.online_end)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
item.origin_offlineStart = item.offline_start;
|
||||
item.offline_start = moment
|
||||
.utc(item.offline_start)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
item.origin_offlineEnd = item.offline_end;
|
||||
item.offline_end = moment
|
||||
.utc(item.offline_end)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
item.origin_contestStart = item.contest_start;
|
||||
item.contest_start = moment
|
||||
.utc(item.contest_start)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
item.origin_contestEnd = item.contest_end;
|
||||
item.contest_end = moment
|
||||
.utc(item.contest_end)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
item.origin_createdAt = item.created_at;
|
||||
item.created_at = moment
|
||||
.utc(item.created_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
});
|
||||
PaginationRef.value.dataCount = res.data.count;
|
||||
contestMsgActive.dataCount = PaginationRef.value.dataCount;
|
||||
pageCount.value = Math.ceil(
|
||||
PaginationRef.value.dataCount / PaginationRef.value.limit
|
||||
);
|
||||
contestMsgActive.pageCount = pageCount.value;
|
||||
if (!operateData[PaginationRef.value.offset]) return;
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
tableData.value.forEach((item) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
nextTick(() => {
|
||||
tableRef.value.toggleRowSelection(item, true);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
tableData.value = [];
|
||||
ElMessage.error("未查找到相关数据!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const changePage = (val) => {
|
||||
pageCount.value = Math.ceil(PaginationRef.value.dataCount / val);
|
||||
operateData = {};
|
||||
for (let i = 0; i < pageCount.value; i++) {
|
||||
operateData[i + 1] = [];
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((element) => {
|
||||
// 判断数据在第几页
|
||||
if (Math.ceil(element.location / PaginationRef.value.limit) == i + 1) {
|
||||
operateData[i + 1].push(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelectionChange = (val) => {
|
||||
operateData[PaginationRef.value.offset] = val;
|
||||
tableData.value.forEach((item, index) => {
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
// 数据在表格中的位置
|
||||
element.location =
|
||||
(PaginationRef.value.offset - 1) * PaginationRef.value.limit + (index + 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
operateDataClone = JSON.parse(JSON.stringify(operateData));
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((item) => {
|
||||
if (item.origin_onlineStart) {
|
||||
item.online_start = item.origin_onlineStart;
|
||||
}
|
||||
if (item.origin_onlineEnd) {
|
||||
item.online_end = item.origin_onlineEnd;
|
||||
}
|
||||
if (item.origin_offlineStart) {
|
||||
item.offline_start = item.origin_offlineStart;
|
||||
}
|
||||
if (item.origin_offlineEnd) {
|
||||
item.offline_end = item.origin_offlineEnd;
|
||||
}
|
||||
if (item.origin_contestStart) {
|
||||
item.contest_start = item.origin_contestStart;
|
||||
}
|
||||
if (item.origin_contestEnd) {
|
||||
item.contest_end = item.origin_contestEnd;
|
||||
}
|
||||
if (item.origin_createdAt) {
|
||||
item.created_at = item.origin_createdAt;
|
||||
}
|
||||
delete item.origin_onlineStart;
|
||||
delete item.origin_onlineEnd;
|
||||
delete item.origin_offlineStart;
|
||||
delete item.origin_offlineEnd;
|
||||
delete item.origin_contestStart;
|
||||
delete item.origin_contestEnd;
|
||||
delete item.origin_createdAt;
|
||||
delete item.location;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const showComfirmDialog = (singleMsg) => {
|
||||
singleData = { ...singleMsg.data };
|
||||
singleData.online_start = singleData.origin_onlineStart;
|
||||
singleData.online_end = singleData.origin_onlineEnd;
|
||||
singleData.offline_start = singleData.origin_offlineStart;
|
||||
singleData.offline_end = singleData.origin_offlineEnd;
|
||||
singleData.contest_start = singleData.origin_contestStart;
|
||||
singleData.contest_end = singleData.origin_contestEnd;
|
||||
singleData.created_at = singleData.origin_createdAt;
|
||||
if (singleMsg.operateType == "edit") {
|
||||
editContestFormRef.value.contestForm({ ...singleMsg.data });
|
||||
editContestFormRef.value.operateDialogVisible = true;
|
||||
editContestFormRef.value.model = EditSelectRef.value.model;
|
||||
}
|
||||
delete singleData.origin_onlineStart;
|
||||
delete singleData.origin_onlineEnd;
|
||||
delete singleData.origin_offlineStart;
|
||||
delete singleData.origin_offlineEnd;
|
||||
delete singleData.origin_contestStart;
|
||||
delete singleData.origin_contestEnd;
|
||||
delete singleData.origin_createdAt;
|
||||
operate.value = singleMsg.operateType;
|
||||
if (singleMsg.operateType == "del") {
|
||||
delPasswordOauthRef.value.operateDialogVisible = true;
|
||||
}
|
||||
};
|
||||
|
||||
const requestOperate = () => {
|
||||
let operateType, url, model, password;
|
||||
if (operate.value == "edit") {
|
||||
operateType = "编辑";
|
||||
url = $url.editContest;
|
||||
model = EditSelectRef.value.model;
|
||||
password = editContestFormRef.value.password;
|
||||
} else if (operate.value == "del") {
|
||||
operateType = "删除";
|
||||
url = $url.delContest;
|
||||
model = DelSelectRef.value.model;
|
||||
password = delPasswordOauthRef.value.ruleForm.password;
|
||||
}
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
model: encrypt(model),
|
||||
password: encrypt(password),
|
||||
requestMsg:
|
||||
model == "single" ? singleData : model == "multiple" ? operateDataClone : "",
|
||||
};
|
||||
if (operate.value == "edit") {
|
||||
data.updateMsg = { ...editContestFormRef.value.ruleForm };
|
||||
data.updateMsg.type = Number(data.updateMsg.type.value);
|
||||
data.updateMsg.status = Number(data.updateMsg.status.value);
|
||||
}
|
||||
$http.post(url, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableRef.value.clearSelection();
|
||||
operateData = {};
|
||||
operateDataClone = {};
|
||||
ElMessage({
|
||||
message: `${operateType}成功!`,
|
||||
type: "success",
|
||||
});
|
||||
contestMsg();
|
||||
} else {
|
||||
ElMessage.error(`${operateType}失败!`);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ contestMsg });
|
||||
|
||||
watch(searchOptions, (value) => {
|
||||
contestMsgActive.searchOptions = value;
|
||||
});
|
||||
|
||||
watch(sortOptions, (value) => {
|
||||
contestMsgActive.sortOptions = value;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
pageCount.value = contestMsgActive.pageCount;
|
||||
dialogSearchVisible.value = contestMsgActive.dialogSearchVisible;
|
||||
dialogSortVisible.value = contestMsgActive.dialogSortVisible;
|
||||
dialogOperationVisible.value = contestMsgActive.dialogOperationVisible;
|
||||
|
||||
if (dialogSearchVisible.value) {
|
||||
searchOptions.uid = contestMsgActive.searchOptions.uid;
|
||||
searchOptions.contest_name = contestMsgActive.searchOptions.contest_name;
|
||||
searchOptions.contest_organizers = contestMsgActive.searchOptions.contest_organizers;
|
||||
searchOptions.contest_term = contestMsgActive.searchOptions.contest_term;
|
||||
searchOptions.type = contestMsgActive.searchOptions.type;
|
||||
searchOptions.status = contestMsgActive.searchOptions.status;
|
||||
searchOptions.online_start = contestMsgActive.searchOptions.online_start;
|
||||
searchOptions.online_end = contestMsgActive.searchOptions.online_end;
|
||||
searchOptions.offline_start = contestMsgActive.searchOptions.offline_start;
|
||||
searchOptions.offline_end = contestMsgActive.searchOptions.offline_end;
|
||||
searchOptions.contest_start = contestMsgActive.searchOptions.contest_start;
|
||||
searchOptions.contest_end = contestMsgActive.searchOptions.contest_end;
|
||||
searchOptions.created_at = contestMsgActive.searchOptions.created_at;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
sortOptions.online_start = contestMsgActive.sortOptions.online_start;
|
||||
sortOptions.online_end = contestMsgActive.sortOptions.online_end;
|
||||
sortOptions.offline_start = contestMsgActive.sortOptions.offline_start;
|
||||
sortOptions.offline_end = contestMsgActive.sortOptions.offline_end;
|
||||
sortOptions.contest_start = contestMsgActive.sortOptions.contest_start;
|
||||
sortOptions.contest_end = contestMsgActive.sortOptions.contest_end;
|
||||
sortOptions.created_at = contestMsgActive.sortOptions.created_at;
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
contestMsg();
|
||||
}, 200);
|
||||
|
||||
setTimeout(() => {
|
||||
if (dialogSearchVisible.value) {
|
||||
SearchUidKeyRef.value.searchMsg = contestMsgActive.searchOptions.uid;
|
||||
SearchContestNameKeyRef.value.searchMsg =
|
||||
contestMsgActive.searchOptions.contest_name;
|
||||
SearchContestOrganizersKeyRef.value.searchMsg =
|
||||
contestMsgActive.searchOptions.contest_organizers;
|
||||
SearchContestTermKeyRef.value.searchMsg =
|
||||
contestMsgActive.searchOptions.contest_term;
|
||||
SelectTypeSearchRef.value.searchMsg = contestMsgActive.searchOptions.type;
|
||||
SelectStatusSearchRef.value.searchMsg = contestMsgActive.searchOptions.status;
|
||||
onlineStartDateTimePickerRef.value.online_start =
|
||||
contestMsgActive.searchOptions.online_start;
|
||||
onlineEndDateTimePickerRef.value.online_end =
|
||||
contestMsgActive.searchOptions.online_end;
|
||||
offlineStartDateTimePickerRef.value.offline_start =
|
||||
contestMsgActive.searchOptions.offline_start;
|
||||
offlineEndDateTimePickerRef.value.offline_end =
|
||||
contestMsgActive.searchOptions.offline_end;
|
||||
contestStartDateTimePickerRef.value.contest_start =
|
||||
contestMsgActive.searchOptions.contest_start;
|
||||
contestEndDateTimePickerRef.value.contest_end =
|
||||
contestMsgActive.searchOptions.contest_end;
|
||||
createdDateTimePickerRef.value.created_at =
|
||||
contestMsgActive.searchOptions.created_at;
|
||||
}
|
||||
if (dialogSortVisible.value) {
|
||||
onlineStartSortDateTimeRef.value.searchMsg =
|
||||
contestMsgActive.sortOptions.online_start;
|
||||
onlineEndSortDateTimeRef.value.searchMsg = contestMsgActive.sortOptions.online_end;
|
||||
offlineStartSortDateTimeRef.value.searchMsg =
|
||||
contestMsgActive.sortOptions.offline_start;
|
||||
offlineEndSortDateTimeRef.value.searchMsg =
|
||||
contestMsgActive.sortOptions.offline_end;
|
||||
contestStartSortDateTimeRef.value.searchMsg =
|
||||
contestMsgActive.sortOptions.contest_start;
|
||||
contestEndSortDateTimeRef.value.searchMsg =
|
||||
contestMsgActive.sortOptions.contest_end;
|
||||
createdSortDateTimeRef.value.searchMsg = contestMsgActive.sortOptions.created_at;
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
643
src/components/mainPage/contest/examination.vue
Normal file
@@ -0,0 +1,643 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 表格 -->
|
||||
<el-card>
|
||||
<div class="flex justify-center flex-wrap">
|
||||
<TabelTools @showTools="showTools" :dialogObj="examinationMsgActive" />
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="tableData"
|
||||
style="width: 100%"
|
||||
max-height="50rem"
|
||||
table-layout="auto"
|
||||
scrollbar-always-on
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column
|
||||
v-if="dialogOperationVisible"
|
||||
fixed="left"
|
||||
type="selection"
|
||||
width="40"
|
||||
column-key="selection"
|
||||
/>
|
||||
<TabelSelect
|
||||
v-if="dialogOperationVisible"
|
||||
ref="EditSelectRef"
|
||||
:holderText="editSelectHold"
|
||||
singleColor="primary"
|
||||
multipleColor="warning"
|
||||
allColor="danger"
|
||||
singleSize="small"
|
||||
multipleSize="small"
|
||||
allSize="small"
|
||||
:singlePlain="true"
|
||||
:multiplePlain="false"
|
||||
:allPlain="false"
|
||||
operateType="edit"
|
||||
@showComfirmDialog="showComfirmDialog"
|
||||
/>
|
||||
<TabelSelect
|
||||
v-if="dialogOperationVisible"
|
||||
ref="DelSelectRef"
|
||||
:holderText="delSelectHold"
|
||||
singleColor="danger"
|
||||
multipleColor="warning"
|
||||
allColor="danger"
|
||||
singleSize="small"
|
||||
multipleSize="small"
|
||||
allSize="small"
|
||||
:singlePlain="true"
|
||||
:multiplePlain="false"
|
||||
:allPlain="false"
|
||||
operateType="del"
|
||||
@showComfirmDialog="showComfirmDialog"
|
||||
/>
|
||||
<el-table-column min-width="140" column-key="user_uid">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchUserUidKeyRef"
|
||||
holderText="输入账号uid以搜索相关数据"
|
||||
@search="examinationMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 账号uid </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.user_uid }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="140" column-key="contest_uid">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchContestUidKeyRef"
|
||||
holderText="输入竞赛uid以搜索相关数据"
|
||||
@search="examinationMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 竞赛uid </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.contest_uid }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100" column-key="exam_type">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectExamTypeSearchRef"
|
||||
holderText="选择竞赛类型以搜索相关数据"
|
||||
:options="examTypeOptions"
|
||||
@search="examinationMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 竞赛类型 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(examTypeOptions, scope.row.exam_type)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(examTypeOptions, scope.row.exam_type) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="80" column-key="topic_type">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectTopicTypeSearchRef"
|
||||
holderText="选择题目类型以搜索相关数据"
|
||||
:options="topicTypeOptions"
|
||||
@search="examinationMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 题目类型 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(topicTypeOptions, scope.row.topic_type)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(topicTypeOptions, scope.row.topic_type) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100" column-key="score">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchScoreKeyRef"
|
||||
holderText="输入得分以搜索相关数据"
|
||||
@search="examinationMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 得分 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="SortScoreRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="examinationMsg"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.score }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="created_at">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="createdDateTimePickerRef"
|
||||
DateTimePicker="createdDateTimePicker"
|
||||
@search="examinationMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 开始答题时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="createdSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="examinationMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.created_at }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="updated_at">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="updatedDateTimePickerRef"
|
||||
DateTimePicker="updatedMsgDateTimePicker"
|
||||
@search="examinationMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 结束答题时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="updatedSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="examinationMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.updated_at }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<Pagination
|
||||
ref="PaginationRef"
|
||||
:active="examinationMsgActive"
|
||||
@sizeChangeBack="changePage"
|
||||
@search="examinationMsg"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
<EditExaminationForm
|
||||
ref="editExaminationFormRef"
|
||||
operateLabel="编辑答题信息"
|
||||
:editData="editData"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
<PasswordOauth
|
||||
ref="delPasswordOauthRef"
|
||||
operateLabel="删除答题信息"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch, onMounted, nextTick } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import TabelTools from "../../operate/tabelTools.vue";
|
||||
import AddNewData from "../../operate/addNewData.vue";
|
||||
import TabelSelect from "../../operate/tabelSelect.vue";
|
||||
import SearchKey from "../../search/searchKey.vue";
|
||||
import SortSearch from "../../search/sortSearch.vue";
|
||||
import SelectSearch from "../../search/selectSearch.vue";
|
||||
import DateTimePicker from "../../search/dateTimePicker.vue";
|
||||
import Pagination from "../../search/pagination.vue";
|
||||
import EditExaminationForm from "../../editData/contest/examinationForm.vue";
|
||||
import PasswordOauth from "../../operate/passwordOauth.vue";
|
||||
|
||||
import examinationActiveStore from "../../../stores/contest/examination";
|
||||
|
||||
import moment from "moment";
|
||||
|
||||
import $http from "../../../api/index";
|
||||
import $url from "../../../api/url";
|
||||
|
||||
import { encrypt } from "../../../utils/aes";
|
||||
import { judgment } from "../../../utils/judgment.js";
|
||||
import { hasNullOrEmptyPropertyWithTypeof } from "../../../utils/hasNullOrEmptyPropertyWithTypeof.js";
|
||||
|
||||
const examinationMsgActive = examinationActiveStore();
|
||||
|
||||
const editSelectHold = {
|
||||
single: "编辑",
|
||||
multiple: "编辑选中",
|
||||
all: "编辑所有",
|
||||
label: "编辑答题信息",
|
||||
};
|
||||
|
||||
const delSelectHold = {
|
||||
single: "删除",
|
||||
multiple: "删除选中",
|
||||
all: "删除所有",
|
||||
label: "删除答题信息",
|
||||
};
|
||||
const EditSelectRef = ref(null);
|
||||
const DelSelectRef = ref(null);
|
||||
const SearchUserUidKeyRef = ref(null);
|
||||
const SearchContestUidKeyRef = ref(null);
|
||||
const SelectExamTypeSearchRef = ref(null);
|
||||
const SelectTopicTypeSearchRef = ref(null);
|
||||
const SearchScoreKeyRef = ref(null);
|
||||
const createdDateTimePickerRef = ref(null);
|
||||
const updatedDateTimePickerRef = ref(null);
|
||||
const SortScoreRef = ref(null);
|
||||
const createdSortDateTimeRef = ref(null);
|
||||
const updatedSortDateTimeRef = ref(null);
|
||||
const PaginationRef = ref(null);
|
||||
const editExaminationFormRef = ref(null);
|
||||
const delPasswordOauthRef = ref(null);
|
||||
const dialogSearchVisible = ref(false);
|
||||
const dialogSortVisible = ref(false);
|
||||
const dialogOperationVisible = ref(false);
|
||||
const tableRef = ref();
|
||||
const offsetOff = ref(true);
|
||||
const pageCount = ref(0);
|
||||
const operate = ref("edit");
|
||||
const searchOptions = reactive({
|
||||
user_uid: "",
|
||||
contest_uid: "",
|
||||
exam_type: "",
|
||||
topic_type: "",
|
||||
score: "",
|
||||
created_at: "",
|
||||
updated_at: "",
|
||||
});
|
||||
const sortOptions = reactive({
|
||||
score: false,
|
||||
created_at: false,
|
||||
updated_at: false,
|
||||
});
|
||||
const tableData = ref([]);
|
||||
const examTypeOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "线上赛",
|
||||
style:
|
||||
"color: rgb(56, 188, 248);background-color: rgba(56, 188, 248, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "线下赛",
|
||||
style:
|
||||
"color: rgb(16, 184, 130);background-color: rgba(16, 184, 130, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
const topicTypeOptions = [
|
||||
{
|
||||
value: "1",
|
||||
label: "题目一",
|
||||
style:
|
||||
"color: rgb(16, 184, 130);background-color: rgba(16, 184, 130, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "题目二",
|
||||
style:
|
||||
"color: rgb(56, 188, 248);background-color: rgba(56, 188, 248, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "3",
|
||||
label: "题目三",
|
||||
style: "color: rgb(240, 70, 70);background-color: rgba(240, 70, 70, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "4",
|
||||
label: "题目四",
|
||||
style: "color: rgb(255, 200, 0);background-color: rgba(255, 200, 0, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "5",
|
||||
label: "题目五",
|
||||
style:
|
||||
"color: rgb(255, 100, 180);background-color: rgba(255, 100, 180, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
let singleData = reactive({});
|
||||
let operateData = reactive({});
|
||||
let operateDataClone = reactive({});
|
||||
const editData = reactive({
|
||||
examTypeOptions,
|
||||
topicTypeOptions,
|
||||
});
|
||||
|
||||
const styleShunt = (options, data) => {
|
||||
let nowStyle;
|
||||
options.forEach((item) => {
|
||||
if (data == item.value) {
|
||||
nowStyle = item.style;
|
||||
}
|
||||
});
|
||||
return nowStyle;
|
||||
};
|
||||
|
||||
const labelShunt = (options, data) => {
|
||||
let nowLabel;
|
||||
options.forEach((item) => {
|
||||
if (data == item.value) {
|
||||
nowLabel = item.label;
|
||||
}
|
||||
});
|
||||
return nowLabel;
|
||||
};
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "search":
|
||||
dialogSearchVisible.value = !dialogSearchVisible.value;
|
||||
examinationMsgActive.dialogSearchVisible = dialogSearchVisible.value;
|
||||
break;
|
||||
case "sort":
|
||||
dialogSortVisible.value = !dialogSortVisible.value;
|
||||
examinationMsgActive.dialogSortVisible = dialogSortVisible.value;
|
||||
break;
|
||||
case "operation":
|
||||
dialogOperationVisible.value = !dialogOperationVisible.value;
|
||||
examinationMsgActive.dialogOperationVisible = dialogOperationVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetOffset = () => {
|
||||
if (hasNullOrEmptyPropertyWithTypeof(searchOptions)) {
|
||||
if (PaginationRef.value.offset !== 1 && offsetOff.value) {
|
||||
PaginationRef.value.handleCurrentChange(1);
|
||||
offsetOff.value = false;
|
||||
}
|
||||
} else {
|
||||
offsetOff.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
const examinationMsg = () => {
|
||||
judgment(searchOptions, "user_uid", SearchUserUidKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "contest_uid", SearchContestUidKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "exam_type", SelectExamTypeSearchRef.value, "searchMsg");
|
||||
judgment(searchOptions, "topic_type", SelectTopicTypeSearchRef.value, "searchMsg");
|
||||
judgment(searchOptions, "score", SearchScoreKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "created_at", createdDateTimePickerRef.value, "searchMsg");
|
||||
judgment(searchOptions, "updated_at", updatedDateTimePickerRef.value, "searchMsg");
|
||||
judgment(sortOptions, "score", SortScoreRef.value, "searchMsg");
|
||||
judgment(sortOptions, "created_at", createdSortDateTimeRef.value, "searchMsg");
|
||||
judgment(sortOptions, "updated_at", updatedSortDateTimeRef.value, "searchMsg");
|
||||
resetOffset();
|
||||
const data = {
|
||||
offset: PaginationRef.value == null ? 1 : PaginationRef.value.offset,
|
||||
limit: PaginationRef.value == null ? 10 : PaginationRef.value.limit,
|
||||
searchOptions: searchOptions,
|
||||
sortOptions: sortOptions,
|
||||
};
|
||||
$http.post($url.showExamination, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableData.value = res.data.examinationMsg;
|
||||
tableData.value.forEach((item) => {
|
||||
item.origin_createdAt = item.created_at;
|
||||
item.created_at = moment
|
||||
.utc(item.created_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
item.origin_updatedAt = item.updated_at;
|
||||
item.updated_at = moment
|
||||
.utc(item.updated_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
});
|
||||
PaginationRef.value.dataCount = res.data.count;
|
||||
examinationMsgActive.dataCount = PaginationRef.value.dataCount;
|
||||
pageCount.value = Math.ceil(
|
||||
PaginationRef.value.dataCount / PaginationRef.value.limit
|
||||
);
|
||||
examinationMsgActive.pageCount = pageCount.value;
|
||||
if (!operateData[PaginationRef.value.offset]) return;
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
tableData.value.forEach((item) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
nextTick(() => {
|
||||
tableRef.value.toggleRowSelection(item, true);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
tableData.value = [];
|
||||
ElMessage.error("未查找到相关数据!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const changePage = (val) => {
|
||||
pageCount.value = Math.ceil(PaginationRef.value.dataCount / val);
|
||||
operateData = {};
|
||||
for (let i = 0; i < pageCount.value; i++) {
|
||||
operateData[i + 1] = [];
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((element) => {
|
||||
// 判断数据在第几页
|
||||
if (Math.ceil(element.location / PaginationRef.value.limit) == i + 1) {
|
||||
operateData[i + 1].push(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelectionChange = (val) => {
|
||||
operateData[PaginationRef.value.offset] = val;
|
||||
tableData.value.forEach((item, index) => {
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
// 数据在表格中的位置
|
||||
element.location =
|
||||
(PaginationRef.value.offset - 1) * PaginationRef.value.limit + (index + 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
operateDataClone = JSON.parse(JSON.stringify(operateData));
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((item) => {
|
||||
if (item.origin_createdAt) {
|
||||
item.created_at = item.origin_createdAt;
|
||||
}
|
||||
if (item.origin_updatedAt) {
|
||||
item.created_at = item.origin_updatedAt;
|
||||
}
|
||||
delete item.origin_createdAt;
|
||||
delete item.origin_updatedAt;
|
||||
delete item.location;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const showComfirmDialog = (singleMsg) => {
|
||||
singleData = { ...singleMsg.data };
|
||||
singleData.created_at = singleData.origin_createdAt;
|
||||
singleData.updated_at = singleData.origin_updatedAt;
|
||||
delete singleData.origin_createdAt;
|
||||
delete singleData.origin_updatedAt;
|
||||
operate.value = singleMsg.operateType;
|
||||
if (singleMsg.operateType == "edit") {
|
||||
editExaminationFormRef.value.examinationForm({ ...singleMsg.data });
|
||||
editExaminationFormRef.value.operateDialogVisible = true;
|
||||
editExaminationFormRef.value.model = EditSelectRef.value.model;
|
||||
}
|
||||
if (singleMsg.operateType == "del") {
|
||||
delPasswordOauthRef.value.operateDialogVisible = true;
|
||||
}
|
||||
};
|
||||
|
||||
const requestOperate = () => {
|
||||
let operateType, url, model, password;
|
||||
if (operate.value == "edit") {
|
||||
operateType = "编辑";
|
||||
url = $url.editExamination;
|
||||
model = EditSelectRef.value.model;
|
||||
password = editExaminationFormRef.value.password;
|
||||
} else if (operate.value == "del") {
|
||||
operateType = "删除";
|
||||
url = $url.delExamination;
|
||||
model = DelSelectRef.value.model;
|
||||
password = delPasswordOauthRef.value.ruleForm.password;
|
||||
}
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
model: encrypt(model),
|
||||
password: encrypt(password),
|
||||
requestMsg:
|
||||
model == "single" ? singleData : model == "multiple" ? operateDataClone : "",
|
||||
};
|
||||
if (operate.value == "edit") {
|
||||
data.updateMsg = { ...editExaminationFormRef.value.ruleForm };
|
||||
}
|
||||
$http.post(url, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableRef.value.clearSelection();
|
||||
operateData = {};
|
||||
operateDataClone = {};
|
||||
ElMessage({
|
||||
message: `${operateType}成功!`,
|
||||
type: "success",
|
||||
});
|
||||
examinationMsg();
|
||||
} else {
|
||||
ElMessage.error(`${operateType}失败!`);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ examinationMsg });
|
||||
|
||||
watch(searchOptions, (value) => {
|
||||
examinationMsgActive.searchOptions = value;
|
||||
});
|
||||
|
||||
watch(sortOptions, (value) => {
|
||||
examinationMsgActive.sortOptions = value;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
pageCount.value = examinationMsgActive.pageCount;
|
||||
dialogSearchVisible.value = examinationMsgActive.dialogSearchVisible;
|
||||
dialogSortVisible.value = examinationMsgActive.dialogSortVisible;
|
||||
dialogOperationVisible.value = examinationMsgActive.dialogOperationVisible;
|
||||
|
||||
if (dialogSearchVisible.value) {
|
||||
searchOptions.user_uid = examinationMsgActive.searchOptions.user_uid;
|
||||
searchOptions.contest_uid = examinationMsgActive.searchOptions.contest_uid;
|
||||
searchOptions.exam_type = examinationMsgActive.searchOptions.exam_type;
|
||||
searchOptions.topic_type = examinationMsgActive.searchOptions.topic_type;
|
||||
searchOptions.score = examinationMsgActive.searchOptions.score;
|
||||
searchOptions.created_at = examinationMsgActive.searchOptions.created_at;
|
||||
searchOptions.updated_at = examinationMsgActive.searchOptions.updated_at;
|
||||
}
|
||||
if (dialogSortVisible.value) {
|
||||
sortOptions.score = examinationMsgActive.sortOptions.score;
|
||||
sortOptions.created_at = examinationMsgActive.sortOptions.created_at;
|
||||
sortOptions.updated_at = examinationMsgActive.sortOptions.updated_at;
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
examinationMsg();
|
||||
}, 200);
|
||||
|
||||
setTimeout(() => {
|
||||
if (dialogSearchVisible.value) {
|
||||
SearchUserUidKeyRef.value.searchMsg = examinationMsgActive.searchOptions.user_uid;
|
||||
SearchContestUidKeyRef.value.searchMsg =
|
||||
examinationMsgActive.searchOptions.contest_uid;
|
||||
SelectExamTypeSearchRef.value.searchMsg =
|
||||
examinationMsgActive.searchOptions.exam_type;
|
||||
SelectTopicTypeSearchRef.value.searchMsg =
|
||||
examinationMsgActive.searchOptions.topic_type;
|
||||
SearchScoreKeyRef.value.searchMsg = examinationMsgActive.searchOptions.score;
|
||||
createdDateTimePickerRef.value.created_at =
|
||||
examinationMsgActive.searchOptions.created_at;
|
||||
updatedDateTimePickerRef.value.updated_at =
|
||||
examinationMsgActive.searchOptions.updated_at;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
SortScoreRef.value.searchMsg = examinationMsgActive.sortOptions.score;
|
||||
createdSortDateTimeRef.value.searchMsg =
|
||||
examinationMsgActive.sortOptions.created_at;
|
||||
updatedSortDateTimeRef.value.searchMsg =
|
||||
examinationMsgActive.sortOptions.updated_at;
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
850
src/components/mainPage/cside.vue
Normal file
@@ -0,0 +1,850 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 表格 -->
|
||||
<el-card>
|
||||
<div class="flex justify-center flex-wrap">
|
||||
<TabelTools @showTools="showTools" :dialogObj="csideMsgActive" />
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="tableData"
|
||||
style="width: 100%"
|
||||
max-height="50rem"
|
||||
table-layout="auto"
|
||||
scrollbar-always-on
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column
|
||||
v-if="dialogOperationVisible"
|
||||
fixed="left"
|
||||
type="selection"
|
||||
width="40"
|
||||
column-key="selection"
|
||||
/>
|
||||
<TabelSelect
|
||||
v-if="dialogOperationVisible"
|
||||
ref="EditSelectRef"
|
||||
:holderText="editSelectHold"
|
||||
singleColor="primary"
|
||||
multipleColor="warning"
|
||||
allColor="danger"
|
||||
singleSize="small"
|
||||
multipleSize="small"
|
||||
allSize="small"
|
||||
:singlePlain="true"
|
||||
:multiplePlain="false"
|
||||
:allPlain="false"
|
||||
operateType="edit"
|
||||
@showComfirmDialog="showComfirmDialog"
|
||||
/>
|
||||
<TabelSelect
|
||||
v-if="dialogOperationVisible"
|
||||
ref="DelSelectRef"
|
||||
:holderText="delSelectHold"
|
||||
singleColor="danger"
|
||||
multipleColor="warning"
|
||||
allColor="danger"
|
||||
singleSize="small"
|
||||
multipleSize="small"
|
||||
allSize="small"
|
||||
:singlePlain="true"
|
||||
:multiplePlain="false"
|
||||
:allPlain="false"
|
||||
operateType="del"
|
||||
@showComfirmDialog="showComfirmDialog"
|
||||
/>
|
||||
<el-table-column min-width="100" column-key="status">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectStatusSearchRef"
|
||||
holderText="选择账号状态以搜索相关数据"
|
||||
:options="statusOptions"
|
||||
@search="csideMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 账号状态 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(statusOptions, scope.row.status)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(statusOptions, scope.row.status) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100" column-key="role">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectRoleSearchRef"
|
||||
holderText="选择账号角色以搜索相关数据"
|
||||
:options="roleOptions"
|
||||
@search="csideMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 账号角色 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(roleOptions, scope.row.role)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(roleOptions, scope.row.role) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="120" column-key="account_name">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchAccountNameKeyRef"
|
||||
holderText="输入账号名称以搜索相关数据"
|
||||
@search="csideMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 账号名称 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.account_name }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100" column-key="user_name">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchUserNameKeyRef"
|
||||
holderText="输入用户姓名以搜索相关数据"
|
||||
@search="csideMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 用户姓名 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.user_name }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="120" column-key="phone">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchPhoneKeyRef"
|
||||
holderText="输入手机号码以搜索相关数据"
|
||||
@search="csideMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 手机号码 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.phone }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="60" column-key="gender">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectGenderSearchRef"
|
||||
holderText="选择性别以搜索相关数据"
|
||||
:options="genderOptions"
|
||||
@search="csideMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 性别 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(genderOptions, scope.row.gender)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(genderOptions, scope.row.gender) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="60" column-key="age">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchAgeKeyRef"
|
||||
holderText="输入年龄以搜索相关数据"
|
||||
@search="csideMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 年龄 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="SortAgeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="csideMsg"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.age }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="email">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchEmailKeyRef"
|
||||
holderText="输入电子邮箱以搜索相关数据"
|
||||
@search="csideMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 电子邮箱 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.email }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="address">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchAddressKeyRef"
|
||||
holderText="输入通信地址以搜索相关数据"
|
||||
@search="csideMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 通信地址 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.address }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100" column-key="post_code">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchPostCodeKeyRef"
|
||||
holderText="输入邮政编码以搜索相关数据"
|
||||
@search="csideMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 邮政编码 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.post_code }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="created_at">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="createdDateTimePickerRef"
|
||||
DateTimePicker="createdDateTimePicker"
|
||||
@search="csideMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 注册时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="createdSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="csideMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.created_at }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="updated_at">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="updatedDateTimePickerRef"
|
||||
DateTimePicker="updatedMsgDateTimePicker"
|
||||
@search="csideMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 账号信息变更时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="updatedSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="csideMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.updated_at }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="login_at">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="loginDateTimePickerRef"
|
||||
DateTimePicker="loginMsgDateTimePicker"
|
||||
@search="csideMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 上次登录时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="loginSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="csideMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.login_at }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100" column-key="login_status">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectLoginStatusSearchRef"
|
||||
holderText="选择登录状态以搜索相关数据"
|
||||
:options="loginStatusOptions"
|
||||
@search="csideMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 登录状态 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(loginStatusOptions, scope.row.login_status)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(loginStatusOptions, scope.row.login_status) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<Pagination
|
||||
ref="PaginationRef"
|
||||
:active="csideMsgActive"
|
||||
@sizeChangeBack="changePage"
|
||||
@search="csideMsg"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
<EditCsideForm
|
||||
ref="editCsideFormRef"
|
||||
operateLabel="编辑C端用户"
|
||||
:editData="editData"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
<PasswordOauth
|
||||
ref="delPasswordOauthRef"
|
||||
operateLabel="删除C端用户"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch, onMounted, nextTick } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import TabelTools from "../operate/tabelTools.vue";
|
||||
import TabelSelect from "../operate/tabelSelect.vue";
|
||||
import SearchKey from "../search/searchKey.vue";
|
||||
import SortSearch from "../search/sortSearch.vue";
|
||||
import SelectSearch from "../search/selectSearch.vue";
|
||||
import DateTimePicker from "../search/dateTimePicker.vue";
|
||||
import Pagination from "../search/pagination.vue";
|
||||
import EditCsideForm from "../editData/csideForm.vue";
|
||||
import PasswordOauth from "../operate/passwordOauth.vue";
|
||||
|
||||
import csideActiveStore from "../../stores/cside";
|
||||
|
||||
import moment from "moment";
|
||||
|
||||
import $http from "../../api/index";
|
||||
import $url from "../../api/url";
|
||||
|
||||
import { encrypt } from "../../utils/aes";
|
||||
import { judgment } from "../../utils/judgment.js";
|
||||
import { hasNullOrEmptyPropertyWithTypeof } from "../../utils/hasNullOrEmptyPropertyWithTypeof.js";
|
||||
|
||||
const csideMsgActive = csideActiveStore();
|
||||
|
||||
const editSelectHold = {
|
||||
single: "编辑",
|
||||
multiple: "编辑选中",
|
||||
all: "编辑所有",
|
||||
label: "编辑C端用户",
|
||||
};
|
||||
|
||||
const delSelectHold = {
|
||||
single: "删除",
|
||||
multiple: "删除选中",
|
||||
all: "删除所有",
|
||||
label: "删除C端用户",
|
||||
};
|
||||
const EditSelectRef = ref(null);
|
||||
const DelSelectRef = ref(null);
|
||||
const SelectStatusSearchRef = ref(null);
|
||||
const SelectRoleSearchRef = ref(null);
|
||||
const SearchAccountNameKeyRef = ref(null);
|
||||
const SearchUserNameKeyRef = ref(null);
|
||||
const SearchPhoneKeyRef = ref(null);
|
||||
const SelectGenderSearchRef = ref(null);
|
||||
const SearchAgeKeyRef = ref(null);
|
||||
const SearchEmailKeyRef = ref(null);
|
||||
const SearchAddressKeyRef = ref(null);
|
||||
const SearchPostCodeKeyRef = ref(null);
|
||||
const createdDateTimePickerRef = ref(null);
|
||||
const updatedDateTimePickerRef = ref(null);
|
||||
const loginDateTimePickerRef = ref(null);
|
||||
const SelectLoginStatusSearchRef = ref(null);
|
||||
const SortAgeRef = ref(null);
|
||||
const createdSortDateTimeRef = ref(null);
|
||||
const updatedSortDateTimeRef = ref(null);
|
||||
const loginSortDateTimeRef = ref(null);
|
||||
const PaginationRef = ref(null);
|
||||
const editCsideFormRef = ref(null);
|
||||
const delPasswordOauthRef = ref(null);
|
||||
const dialogSearchVisible = ref(false);
|
||||
const dialogSortVisible = ref(false);
|
||||
const dialogOperationVisible = ref(false);
|
||||
const tableRef = ref();
|
||||
const offsetOff = ref(true);
|
||||
const pageCount = ref(0);
|
||||
const operate = ref("edit");
|
||||
const searchOptions = reactive({
|
||||
status: "",
|
||||
role: "",
|
||||
account_name: "",
|
||||
user_name: "",
|
||||
phone: "",
|
||||
gender: "",
|
||||
age: "",
|
||||
email: "",
|
||||
address: "",
|
||||
post_code: "",
|
||||
created_at: "",
|
||||
updated_at: "",
|
||||
login_at: "",
|
||||
login_status: "",
|
||||
});
|
||||
const sortOptions = reactive({
|
||||
age: false,
|
||||
created_at: false,
|
||||
updated_at: false,
|
||||
login_at: false,
|
||||
});
|
||||
const tableData = ref([]);
|
||||
const statusOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "默认",
|
||||
style: "color: rgb(56, 188, 248);background-color: rgba(56, 188, 248, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "正在使用",
|
||||
style: "color: rgb(16, 184, 130);background-color: rgba(16, 184, 130, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "封禁",
|
||||
style: "color: rgb(240, 70, 70);background-color: rgba(240, 70, 70, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
const roleOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "普通用户",
|
||||
style: "color: rgb(56, 188, 248);background-color: rgba(56, 188, 248, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "特殊用户",
|
||||
style: "color: rgb(255, 200, 0);background-color: rgba(255, 200, 0, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
const genderOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "女",
|
||||
style: "color: rgb(255, 100, 180);background-color: rgba(255, 100, 180, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "男",
|
||||
style: "color: rgb(56, 188, 248);background-color: rgba(56, 188, 248, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
const loginStatusOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "未登录",
|
||||
style: "color: rgb(56, 188, 248);background-color: rgba(56, 188, 248, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "已登录",
|
||||
style: "color: rgb(16, 184, 130);background-color: rgba(16, 184, 130, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
let singleData = reactive({});
|
||||
let operateData = reactive({});
|
||||
let operateDataClone = reactive({});
|
||||
const editData = reactive({
|
||||
statusOptions,
|
||||
roleOptions,
|
||||
});
|
||||
|
||||
const styleShunt = (options, data) => {
|
||||
let nowStyle;
|
||||
options.forEach((item) => {
|
||||
if (data == item.value) {
|
||||
nowStyle = item.style;
|
||||
}
|
||||
});
|
||||
return nowStyle;
|
||||
};
|
||||
|
||||
const labelShunt = (options, data) => {
|
||||
let nowLabel;
|
||||
options.forEach((item) => {
|
||||
if (data == item.value) {
|
||||
nowLabel = item.label;
|
||||
}
|
||||
});
|
||||
return nowLabel;
|
||||
};
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "search":
|
||||
dialogSearchVisible.value = !dialogSearchVisible.value;
|
||||
csideMsgActive.dialogSearchVisible = dialogSearchVisible.value;
|
||||
break;
|
||||
case "sort":
|
||||
dialogSortVisible.value = !dialogSortVisible.value;
|
||||
csideMsgActive.dialogSortVisible = dialogSortVisible.value;
|
||||
break;
|
||||
case "operation":
|
||||
dialogOperationVisible.value = !dialogOperationVisible.value;
|
||||
csideMsgActive.dialogOperationVisible = dialogOperationVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetOffset = () => {
|
||||
if (hasNullOrEmptyPropertyWithTypeof(searchOptions)) {
|
||||
if (PaginationRef.value.offset !== 1 && offsetOff.value) {
|
||||
PaginationRef.value.handleCurrentChange(1);
|
||||
offsetOff.value = false;
|
||||
}
|
||||
} else {
|
||||
offsetOff.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
const csideMsg = () => {
|
||||
judgment(searchOptions, "status", SelectStatusSearchRef.value, "searchMsg");
|
||||
judgment(searchOptions, "role", SelectRoleSearchRef.value, "searchMsg");
|
||||
judgment(searchOptions, "account_name", SearchAccountNameKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "user_name", SearchUserNameKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "phone", SearchPhoneKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "gender", SelectGenderSearchRef.value, "searchMsg");
|
||||
judgment(searchOptions, "age", SearchAgeKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "email", SearchEmailKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "address", SearchAddressKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "post_code", SearchPostCodeKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "created_at", createdDateTimePickerRef.value, "searchMsg");
|
||||
judgment(searchOptions, "updated_at", updatedDateTimePickerRef.value, "searchMsg");
|
||||
judgment(searchOptions, "login_at", loginDateTimePickerRef.value, "searchMsg");
|
||||
judgment(searchOptions, "login_status", SelectLoginStatusSearchRef.value, "searchMsg");
|
||||
judgment(sortOptions, "age", SortAgeRef.value, "searchMsg");
|
||||
judgment(sortOptions, "created_at", createdSortDateTimeRef.value, "searchMsg");
|
||||
judgment(sortOptions, "updated_at", updatedSortDateTimeRef.value, "searchMsg");
|
||||
judgment(sortOptions, "login_at", loginSortDateTimeRef.value, "searchMsg");
|
||||
resetOffset();
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
offset: PaginationRef.value == null ? 1 : PaginationRef.value.offset,
|
||||
limit: PaginationRef.value == null ? 10 : PaginationRef.value.limit,
|
||||
searchOptions: searchOptions,
|
||||
sortOptions: sortOptions,
|
||||
};
|
||||
$http.post($url.showCSide, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableData.value = res.data.CSideMsg;
|
||||
tableData.value.forEach((item) => {
|
||||
item.origin_createdAt = item.created_at;
|
||||
item.created_at = moment
|
||||
.utc(item.created_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
item.origin_updatedAt = item.updated_at;
|
||||
item.updated_at = moment
|
||||
.utc(item.updated_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
item.origin_loginAt = item.login_at;
|
||||
item.login_at = moment
|
||||
.utc(item.login_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
});
|
||||
PaginationRef.value.dataCount = res.data.count;
|
||||
csideMsgActive.dataCount = PaginationRef.value.dataCount;
|
||||
pageCount.value = Math.ceil(
|
||||
PaginationRef.value.dataCount / PaginationRef.value.limit
|
||||
);
|
||||
csideMsgActive.pageCount = pageCount.value;
|
||||
if (!operateData[PaginationRef.value.offset]) return;
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
tableData.value.forEach((item) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
nextTick(() => {
|
||||
tableRef.value.toggleRowSelection(item, true);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
tableData.value = [];
|
||||
ElMessage.error("未查找到相关数据!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const changePage = (val) => {
|
||||
pageCount.value = Math.ceil(PaginationRef.value.dataCount / val);
|
||||
operateData = {};
|
||||
for (let i = 0; i < pageCount.value; i++) {
|
||||
operateData[i + 1] = [];
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((element) => {
|
||||
// 判断数据在第几页
|
||||
if (Math.ceil(element.location / PaginationRef.value.limit) == i + 1) {
|
||||
operateData[i + 1].push(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelectionChange = (val) => {
|
||||
operateData[PaginationRef.value.offset] = val;
|
||||
tableData.value.forEach((item, index) => {
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
// 数据在表格中的位置
|
||||
element.location =
|
||||
(PaginationRef.value.offset - 1) * PaginationRef.value.limit + (index + 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
operateDataClone = JSON.parse(JSON.stringify(operateData));
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((item) => {
|
||||
if (item.origin_createdAt) {
|
||||
item.created_at = item.origin_createdAt;
|
||||
}
|
||||
if (item.origin_updatedAt) {
|
||||
item.created_at = item.origin_updatedAt;
|
||||
}
|
||||
if (item.origin_loginAt) {
|
||||
item.created_at = item.origin_loginAt;
|
||||
}
|
||||
delete item.origin_createdAt;
|
||||
delete item.origin_updatedAt;
|
||||
delete item.origin_loginAt;
|
||||
delete item.location;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const showComfirmDialog = (singleMsg) => {
|
||||
singleData = { ...singleMsg.data };
|
||||
singleData.created_at = singleData.origin_createdAt;
|
||||
singleData.updated_at = singleData.origin_updatedAt;
|
||||
singleData.login_at = singleData.origin_loginAt;
|
||||
delete singleData.origin_createdAt;
|
||||
delete singleData.origin_updatedAt;
|
||||
delete singleData.origin_loginAt;
|
||||
operate.value = singleMsg.operateType;
|
||||
if (singleMsg.operateType == "edit") {
|
||||
editCsideFormRef.value.operateDialogVisible = true;
|
||||
editCsideFormRef.value.model = EditSelectRef.value.model;
|
||||
}
|
||||
if (singleMsg.operateType == "del") {
|
||||
delPasswordOauthRef.value.operateDialogVisible = true;
|
||||
}
|
||||
};
|
||||
|
||||
const requestOperate = () => {
|
||||
let operateType, url, model, password;
|
||||
if (operate.value == "edit") {
|
||||
operateType = "编辑";
|
||||
url = $url.editCSide;
|
||||
model = EditSelectRef.value.model;
|
||||
password = editCsideFormRef.value.password;
|
||||
} else if (operate.value == "del") {
|
||||
operateType = "删除";
|
||||
url = $url.deleteCSide;
|
||||
model = DelSelectRef.value.model;
|
||||
password = delPasswordOauthRef.value.ruleForm.password;
|
||||
}
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
model: encrypt(model),
|
||||
password: encrypt(password),
|
||||
requestMsg:
|
||||
model == "single" ? singleData : model == "multiple" ? operateDataClone : "",
|
||||
};
|
||||
if (operate.value == "edit") {
|
||||
data.updateMsg = { ...editCsideFormRef.value.ruleForm };
|
||||
for (const element in data.updateMsg) {
|
||||
if (data.updateMsg[element] == "") {
|
||||
delete data.updateMsg[element];
|
||||
}
|
||||
}
|
||||
}
|
||||
$http.post(url, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableRef.value.clearSelection();
|
||||
operateData = {};
|
||||
operateDataClone = {};
|
||||
ElMessage({
|
||||
message: `${operateType}成功!`,
|
||||
type: "success",
|
||||
});
|
||||
csideMsg();
|
||||
} else {
|
||||
ElMessage.error(`${operateType}失败!`);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ csideMsg });
|
||||
|
||||
watch(searchOptions, (value) => {
|
||||
csideMsgActive.searchOptions = value;
|
||||
});
|
||||
|
||||
watch(sortOptions, (value) => {
|
||||
csideMsgActive.sortOptions = value;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
pageCount.value = csideMsgActive.pageCount;
|
||||
dialogSearchVisible.value = csideMsgActive.dialogSearchVisible;
|
||||
dialogSortVisible.value = csideMsgActive.dialogSortVisible;
|
||||
dialogOperationVisible.value = csideMsgActive.dialogOperationVisible;
|
||||
|
||||
if (dialogSearchVisible.value) {
|
||||
searchOptions.status = csideMsgActive.searchOptions.status;
|
||||
searchOptions.role = csideMsgActive.searchOptions.role;
|
||||
searchOptions.account_name = csideMsgActive.searchOptions.account_name;
|
||||
searchOptions.user_name = csideMsgActive.searchOptions.user_name;
|
||||
searchOptions.phone = csideMsgActive.searchOptions.phone;
|
||||
searchOptions.gender = csideMsgActive.searchOptions.gender;
|
||||
searchOptions.age = csideMsgActive.searchOptions.age;
|
||||
searchOptions.email = csideMsgActive.searchOptions.email;
|
||||
searchOptions.address = csideMsgActive.searchOptions.address;
|
||||
searchOptions.post_code = csideMsgActive.searchOptions.post_code;
|
||||
searchOptions.created_at = csideMsgActive.searchOptions.created_at;
|
||||
searchOptions.updated_at = csideMsgActive.searchOptions.updated_at;
|
||||
searchOptions.login_at = csideMsgActive.searchOptions.login_at;
|
||||
searchOptions.login_status = csideMsgActive.searchOptions.login_status;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
sortOptions.age = csideMsgActive.sortOptions.age;
|
||||
sortOptions.created_at = csideMsgActive.sortOptions.created_at;
|
||||
sortOptions.updated_at = csideMsgActive.sortOptions.updated_at;
|
||||
sortOptions.login_at = csideMsgActive.sortOptions.login_at;
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
csideMsg();
|
||||
}, 200);
|
||||
|
||||
setTimeout(() => {
|
||||
if (dialogSearchVisible.value) {
|
||||
SelectStatusSearchRef.value.searchMsg = csideMsgActive.searchOptions.status;
|
||||
SelectStatusSearchRef.value.searchMsg = csideMsgActive.searchOptions.role;
|
||||
SearchAccountNameKeyRef.value.searchMsg = csideMsgActive.searchOptions.account_name;
|
||||
SearchUserNameKeyRef.value.searchMsg = csideMsgActive.searchOptions.user_name;
|
||||
SearchPhoneKeyRef.value.searchMsg = csideMsgActive.searchOptions.phone;
|
||||
SelectStatusSearchRef.value.searchMsg = csideMsgActive.searchOptions.gender;
|
||||
SearchAgeKeyRef.value.searchMsg = csideMsgActive.searchOptions.age;
|
||||
SearchEmailKeyRef.value.searchMsg = csideMsgActive.searchOptions.email;
|
||||
SearchAddressKeyRef.value.searchMsg = csideMsgActive.searchOptions.address;
|
||||
SearchPostCodeKeyRef.value.searchMsg = csideMsgActive.searchOptions.post_code;
|
||||
createdDateTimePickerRef.value.created_at = csideMsgActive.searchOptions.created_at;
|
||||
updatedDateTimePickerRef.value.updated_at = csideMsgActive.searchOptions.updated_at;
|
||||
loginDateTimePickerRef.value.login_at = csideMsgActive.searchOptions.login_at;
|
||||
SelectStatusSearchRef.value.searchMsg = csideMsgActive.searchOptions.login_status;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
SortAgeRef.value.searchMsg = csideMsgActive.sortOptions.age;
|
||||
createdSortDateTimeRef.value.searchMsg = csideMsgActive.sortOptions.created_at;
|
||||
updatedSortDateTimeRef.value.searchMsg = csideMsgActive.sortOptions.updated_at;
|
||||
loginSortDateTimeRef.value.searchMsg = csideMsgActive.sortOptions.login_at;
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
750
src/components/mainPage/insiders.vue
Normal file
@@ -0,0 +1,750 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 表格 -->
|
||||
<el-card>
|
||||
<div class="flex justify-center flex-wrap">
|
||||
<TabelTools @showTools="showTools" :dialogObj="insidersMsgActive" />
|
||||
<AddNewData newDataLabel="新增公司员工" @showAddForm="showAddForm" />
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="tableData"
|
||||
style="width: 100%"
|
||||
max-height="50rem"
|
||||
table-layout="auto"
|
||||
scrollbar-always-on
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column
|
||||
v-if="dialogOperationVisible"
|
||||
fixed="left"
|
||||
type="selection"
|
||||
width="40"
|
||||
column-key="selection"
|
||||
/>
|
||||
<TabelSelect
|
||||
v-if="dialogOperationVisible"
|
||||
ref="EditSelectRef"
|
||||
:holderText="editSelectHold"
|
||||
singleColor="primary"
|
||||
multipleColor="warning"
|
||||
allColor="danger"
|
||||
singleSize="small"
|
||||
multipleSize="small"
|
||||
allSize="small"
|
||||
:singlePlain="true"
|
||||
:multiplePlain="false"
|
||||
:allPlain="false"
|
||||
operateType="edit"
|
||||
@showComfirmDialog="showComfirmDialog"
|
||||
/>
|
||||
<TabelSelect
|
||||
v-if="dialogOperationVisible"
|
||||
ref="DelSelectRef"
|
||||
:holderText="delSelectHold"
|
||||
singleColor="danger"
|
||||
multipleColor="warning"
|
||||
allColor="danger"
|
||||
singleSize="small"
|
||||
multipleSize="small"
|
||||
allSize="small"
|
||||
:singlePlain="true"
|
||||
:multiplePlain="false"
|
||||
:allPlain="false"
|
||||
operateType="del"
|
||||
@showComfirmDialog="showComfirmDialog"
|
||||
/>
|
||||
<el-table-column min-width="140" column-key="uid">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchUidKeyRef"
|
||||
holderText="输入员工uid以搜索相关数据"
|
||||
@search="insidersMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 员工uid </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.uid }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100" column-key="status">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectStatusSearchRef"
|
||||
holderText="选择账号状态以搜索相关数据"
|
||||
:options="statusOptions"
|
||||
@search="insidersMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 账号状态 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(statusOptions, scope.row.status)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(statusOptions, scope.row.status) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100" column-key="role">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectRoleSearchRef"
|
||||
holderText="选择账号角色以搜索相关数据"
|
||||
:options="roleOptions"
|
||||
@search="insidersMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 账号角色 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(roleOptions, scope.row.role)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(roleOptions, scope.row.role) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100" column-key="name">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchNameKeyRef"
|
||||
holderText="输入员工姓名以搜索相关数据"
|
||||
@search="insidersMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 员工姓名 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.name }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="120" column-key="department">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchDepartmentKeyRef"
|
||||
holderText="输入所属部门以搜索相关数据"
|
||||
@search="insidersMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 所属部门 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.department }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="change">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchChangeKeyRef"
|
||||
holderText="输入信息变更描述以搜索相关数据"
|
||||
@search="insidersMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 信息变更描述 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.change }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="created_at">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="createdDateTimePickerRef"
|
||||
DateTimePicker="createdDateTimePicker"
|
||||
@search="insidersMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 注册时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="createdSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="insidersMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.created_at }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="updated_at">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="updatedDateTimePickerRef"
|
||||
DateTimePicker="updatedMsgDateTimePicker"
|
||||
@search="insidersMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 信息变更时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="updatedSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="insidersMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.updated_at }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="login_at">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="loginDateTimePickerRef"
|
||||
DateTimePicker="loginMsgDateTimePicker"
|
||||
@search="insidersMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 上次登录时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="loginSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="insidersMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.login_at }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100" column-key="login_status">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectLoginStatusSearchRef"
|
||||
holderText="选择登录状态以搜索相关数据"
|
||||
:options="loginStatusOptions"
|
||||
@search="insidersMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 登录状态 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(loginStatusOptions, scope.row.login_status)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(loginStatusOptions, scope.row.login_status) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<Pagination
|
||||
ref="PaginationRef"
|
||||
:active="insidersMsgActive"
|
||||
@sizeChangeBack="changePage"
|
||||
@search="insidersMsg"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
<AddInsidersForm
|
||||
ref="addInsidersFormRef"
|
||||
title="新增公司员工"
|
||||
:addData="addData"
|
||||
@reloadData="insidersMsg"
|
||||
/>
|
||||
<EditInsidersForm
|
||||
ref="editInsidersFormRef"
|
||||
operateLabel="编辑公司员工"
|
||||
:editData="editData"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
<PasswordOauth
|
||||
ref="delPasswordOauthRef"
|
||||
operateLabel="删除公司员工"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch, onMounted, nextTick } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import TabelTools from "../operate/tabelTools.vue";
|
||||
import AddNewData from "../operate/addNewData.vue";
|
||||
import TabelSelect from "../operate/tabelSelect.vue";
|
||||
import SearchKey from "../search/searchKey.vue";
|
||||
import SortSearch from "../search/sortSearch.vue";
|
||||
import SelectSearch from "../search/selectSearch.vue";
|
||||
import DateTimePicker from "../search/dateTimePicker.vue";
|
||||
import Pagination from "../search/pagination.vue";
|
||||
import AddInsidersForm from "../addNewData/insidersForm/insidersForm.vue";
|
||||
import EditInsidersForm from "../editData/insidersForm.vue";
|
||||
import PasswordOauth from "../operate/passwordOauth.vue";
|
||||
|
||||
import insidersActiveStore from "../../stores/insiders";
|
||||
|
||||
import moment from "moment";
|
||||
|
||||
import $http from "../../api/index";
|
||||
import $url from "../../api/url";
|
||||
|
||||
import { encrypt } from "../../utils/aes";
|
||||
import { judgment } from "../../utils/judgment.js";
|
||||
import { hasNullOrEmptyPropertyWithTypeof } from "../../utils/hasNullOrEmptyPropertyWithTypeof.js";
|
||||
|
||||
const insidersMsgActive = insidersActiveStore();
|
||||
|
||||
const editSelectHold = {
|
||||
single: "编辑",
|
||||
multiple: "编辑选中",
|
||||
all: "编辑所有",
|
||||
label: "编辑公司员工",
|
||||
};
|
||||
|
||||
const delSelectHold = {
|
||||
single: "删除",
|
||||
multiple: "删除选中",
|
||||
all: "删除所有",
|
||||
label: "删除公司员工",
|
||||
};
|
||||
const EditSelectRef = ref(null);
|
||||
const DelSelectRef = ref(null);
|
||||
const SearchUidKeyRef = ref(null);
|
||||
const SelectStatusSearchRef = ref(null);
|
||||
const SelectRoleSearchRef = ref(null);
|
||||
const SearchNameKeyRef = ref(null);
|
||||
const SearchDepartmentKeyRef = ref(null);
|
||||
const SearchChangeKeyRef = ref(null);
|
||||
const createdDateTimePickerRef = ref(null);
|
||||
const updatedDateTimePickerRef = ref(null);
|
||||
const loginDateTimePickerRef = ref(null);
|
||||
const SelectLoginStatusSearchRef = ref(null);
|
||||
const createdSortDateTimeRef = ref(null);
|
||||
const updatedSortDateTimeRef = ref(null);
|
||||
const loginSortDateTimeRef = ref(null);
|
||||
const PaginationRef = ref(null);
|
||||
const addInsidersFormRef = ref(null);
|
||||
const editInsidersFormRef = ref(null);
|
||||
const delPasswordOauthRef = ref(null);
|
||||
const dialogSearchVisible = ref(false);
|
||||
const dialogSortVisible = ref(false);
|
||||
const dialogOperationVisible = ref(false);
|
||||
const tableRef = ref();
|
||||
const offsetOff = ref(true);
|
||||
const pageCount = ref(0);
|
||||
const operate = ref("edit");
|
||||
const searchOptions = reactive({
|
||||
uid: "",
|
||||
status: "",
|
||||
role: "",
|
||||
name: "",
|
||||
department: "",
|
||||
change: "",
|
||||
created_at: "",
|
||||
updated_at: "",
|
||||
login_at: "",
|
||||
login_status: "",
|
||||
});
|
||||
const sortOptions = reactive({
|
||||
created_at: false,
|
||||
updated_at: false,
|
||||
login_at: false,
|
||||
});
|
||||
const tableData = ref([]);
|
||||
const statusOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "默认",
|
||||
style: "color: rgb(56, 188, 248);background-color: rgba(56, 188, 248, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "正在使用",
|
||||
style: "color: rgb(16, 184, 130);background-color: rgba(16, 184, 130, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "已弃用",
|
||||
style: "color: rgb(240, 70, 70);background-color: rgba(240, 70, 70, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
const roleOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "临时员工",
|
||||
style: "color: rgb(255, 100, 180);background-color: rgba(255, 100, 180, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "3",
|
||||
label: "普通员工",
|
||||
style: "color: rgb(255, 120, 20);background-color: rgba(255, 120, 20, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "6",
|
||||
label: "普通管理员",
|
||||
style: "color: rgb(255, 200, 0);background-color: rgba(255, 200, 0, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "9",
|
||||
label: "高级管理员",
|
||||
style: "color: rgb(240, 70, 70);background-color: rgba(240, 70, 70, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
const loginStatusOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "未登录",
|
||||
style: "color: rgb(56, 188, 248);background-color: rgba(56, 188, 248, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "已登录",
|
||||
style: "color: rgb(16, 184, 130);background-color: rgba(16, 184, 130, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
let singleData = reactive({});
|
||||
let operateData = reactive({});
|
||||
let operateDataClone = reactive({});
|
||||
const addData = reactive({
|
||||
roleOptions,
|
||||
});
|
||||
const editData = reactive({
|
||||
statusOptions,
|
||||
roleOptions,
|
||||
});
|
||||
|
||||
const showAddForm = () => {
|
||||
addInsidersFormRef.value.dialogVisible = true;
|
||||
};
|
||||
|
||||
const styleShunt = (options, data) => {
|
||||
let nowStyle;
|
||||
options.forEach((item) => {
|
||||
if (data == item.value) {
|
||||
nowStyle = item.style;
|
||||
}
|
||||
});
|
||||
return nowStyle;
|
||||
};
|
||||
|
||||
const labelShunt = (options, data) => {
|
||||
let nowLabel;
|
||||
options.forEach((item) => {
|
||||
if (data == item.value) {
|
||||
nowLabel = item.label;
|
||||
}
|
||||
});
|
||||
return nowLabel;
|
||||
};
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "search":
|
||||
dialogSearchVisible.value = !dialogSearchVisible.value;
|
||||
insidersMsgActive.dialogSearchVisible = dialogSearchVisible.value;
|
||||
break;
|
||||
case "sort":
|
||||
dialogSortVisible.value = !dialogSortVisible.value;
|
||||
insidersMsgActive.dialogSortVisible = dialogSortVisible.value;
|
||||
break;
|
||||
case "operation":
|
||||
dialogOperationVisible.value = !dialogOperationVisible.value;
|
||||
insidersMsgActive.dialogOperationVisible = dialogOperationVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetOffset = () => {
|
||||
if (hasNullOrEmptyPropertyWithTypeof(searchOptions)) {
|
||||
if (PaginationRef.value.offset !== 1 && offsetOff.value) {
|
||||
PaginationRef.value.handleCurrentChange(1);
|
||||
offsetOff.value = false;
|
||||
}
|
||||
} else {
|
||||
offsetOff.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
const insidersMsg = () => {
|
||||
judgment(searchOptions, "uid", SearchUidKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "status", SelectStatusSearchRef.value, "searchMsg");
|
||||
judgment(searchOptions, "role", SelectRoleSearchRef.value, "searchMsg");
|
||||
judgment(searchOptions, "name", SearchNameKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "department", SearchDepartmentKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "change", SearchChangeKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "created_at", createdDateTimePickerRef.value, "searchMsg");
|
||||
judgment(searchOptions, "updated_at", updatedDateTimePickerRef.value, "searchMsg");
|
||||
judgment(searchOptions, "login_at", loginDateTimePickerRef.value, "searchMsg");
|
||||
judgment(sortOptions, "created_at", createdSortDateTimeRef.value, "searchMsg");
|
||||
judgment(sortOptions, "updated_at", updatedSortDateTimeRef.value, "searchMsg");
|
||||
judgment(sortOptions, "login_at", loginSortDateTimeRef.value, "searchMsg");
|
||||
resetOffset();
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
offset: PaginationRef.value == null ? 1 : PaginationRef.value.offset,
|
||||
limit: PaginationRef.value == null ? 10 : PaginationRef.value.limit,
|
||||
searchOptions: searchOptions,
|
||||
sortOptions: sortOptions,
|
||||
};
|
||||
$http.post($url.showInsiders, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableData.value = res.data.InsidersMsg;
|
||||
tableData.value.forEach((item) => {
|
||||
item.origin_createdAt = item.created_at;
|
||||
item.created_at = moment
|
||||
.utc(item.created_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
item.origin_updatedAt = item.updated_at;
|
||||
item.updated_at = moment
|
||||
.utc(item.updated_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
item.origin_loginAt = item.login_at;
|
||||
item.login_at = moment
|
||||
.utc(item.login_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
});
|
||||
PaginationRef.value.dataCount = res.data.count;
|
||||
insidersMsgActive.dataCount = PaginationRef.value.dataCount;
|
||||
pageCount.value = Math.ceil(
|
||||
PaginationRef.value.dataCount / PaginationRef.value.limit
|
||||
);
|
||||
insidersMsgActive.pageCount = pageCount.value;
|
||||
if (!operateData[PaginationRef.value.offset]) return;
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
tableData.value.forEach((item) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
nextTick(() => {
|
||||
tableRef.value.toggleRowSelection(item, true);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
tableData.value = [];
|
||||
ElMessage.error("未查找到相关数据!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const changePage = (val) => {
|
||||
pageCount.value = Math.ceil(PaginationRef.value.dataCount / val);
|
||||
operateData = {};
|
||||
for (let i = 0; i < pageCount.value; i++) {
|
||||
operateData[i + 1] = [];
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((element) => {
|
||||
// 判断数据在第几页
|
||||
if (Math.ceil(element.location / PaginationRef.value.limit) == i + 1) {
|
||||
operateData[i + 1].push(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelectionChange = (val) => {
|
||||
operateData[PaginationRef.value.offset] = val;
|
||||
tableData.value.forEach((item, index) => {
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
// 数据在表格中的位置
|
||||
element.location =
|
||||
(PaginationRef.value.offset - 1) * PaginationRef.value.limit + (index + 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
operateDataClone = JSON.parse(JSON.stringify(operateData));
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((item) => {
|
||||
if (item.origin_createdAt) {
|
||||
item.created_at = item.origin_createdAt;
|
||||
}
|
||||
if (item.origin_updatedAt) {
|
||||
item.created_at = item.origin_updatedAt;
|
||||
}
|
||||
if (item.origin_loginAt) {
|
||||
item.created_at = item.origin_loginAt;
|
||||
}
|
||||
delete item.origin_createdAt;
|
||||
delete item.origin_updatedAt;
|
||||
delete item.origin_loginAt;
|
||||
delete item.location;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const showComfirmDialog = (singleMsg) => {
|
||||
singleData = { ...singleMsg.data };
|
||||
singleData.created_at = singleData.origin_createdAt;
|
||||
singleData.updated_at = singleData.origin_updatedAt;
|
||||
singleData.login_at = singleData.origin_loginAt;
|
||||
delete singleData.origin_createdAt;
|
||||
delete singleData.origin_updatedAt;
|
||||
delete singleData.origin_loginAt;
|
||||
operate.value = singleMsg.operateType;
|
||||
if (singleMsg.operateType == "edit") {
|
||||
editInsidersFormRef.value.operateDialogVisible = true;
|
||||
editInsidersFormRef.value.model = EditSelectRef.value.model;
|
||||
}
|
||||
if (singleMsg.operateType == "del") {
|
||||
delPasswordOauthRef.value.operateDialogVisible = true;
|
||||
}
|
||||
};
|
||||
|
||||
const requestOperate = () => {
|
||||
let operateType, url, model, password;
|
||||
if (operate.value == "edit") {
|
||||
operateType = "编辑";
|
||||
url = $url.editInsiders;
|
||||
model = EditSelectRef.value.model;
|
||||
password = editInsidersFormRef.value.password;
|
||||
} else if (operate.value == "del") {
|
||||
operateType = "删除";
|
||||
url = $url.deleteInsiders;
|
||||
model = DelSelectRef.value.model;
|
||||
password = delPasswordOauthRef.value.ruleForm.password;
|
||||
}
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
model: encrypt(model),
|
||||
password: encrypt(password),
|
||||
requestMsg:
|
||||
model == "single" ? singleData : model == "multiple" ? operateDataClone : "",
|
||||
};
|
||||
if (operate.value == "edit") {
|
||||
data.updateMsg = { ...editInsidersFormRef.value.ruleForm };
|
||||
for (const element in data.updateMsg) {
|
||||
if (data.updateMsg[element] == "") {
|
||||
delete data.updateMsg[element];
|
||||
}
|
||||
}
|
||||
}
|
||||
$http.post(url, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableRef.value.clearSelection();
|
||||
operateData = {};
|
||||
operateDataClone = {};
|
||||
ElMessage({
|
||||
message: `${operateType}成功!`,
|
||||
type: "success",
|
||||
});
|
||||
insidersMsg();
|
||||
} else {
|
||||
ElMessage.error(`${operateType}失败!`);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ insidersMsg });
|
||||
|
||||
watch(searchOptions, (value) => {
|
||||
insidersMsgActive.searchOptions = value;
|
||||
});
|
||||
|
||||
watch(sortOptions, (value) => {
|
||||
insidersMsgActive.sortOptions = value;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
pageCount.value = insidersMsgActive.pageCount;
|
||||
dialogSearchVisible.value = insidersMsgActive.dialogSearchVisible;
|
||||
dialogSortVisible.value = insidersMsgActive.dialogSortVisible;
|
||||
dialogOperationVisible.value = insidersMsgActive.dialogOperationVisible;
|
||||
|
||||
if (dialogSearchVisible.value) {
|
||||
searchOptions.uid = insidersMsgActive.searchOptions.uid;
|
||||
searchOptions.status = insidersMsgActive.searchOptions.status;
|
||||
searchOptions.role = insidersMsgActive.searchOptions.role;
|
||||
searchOptions.name = insidersMsgActive.searchOptions.name;
|
||||
searchOptions.department = insidersMsgActive.searchOptions.department;
|
||||
searchOptions.change = insidersMsgActive.searchOptions.change;
|
||||
searchOptions.created_at = insidersMsgActive.searchOptions.created_at;
|
||||
searchOptions.updated_at = insidersMsgActive.searchOptions.updated_at;
|
||||
searchOptions.login_at = insidersMsgActive.searchOptions.login_at;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
sortOptions.created_at = insidersMsgActive.sortOptions.created_at;
|
||||
sortOptions.updated_at = insidersMsgActive.sortOptions.updated_at;
|
||||
sortOptions.login_at = insidersMsgActive.sortOptions.login_at;
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
insidersMsg();
|
||||
}, 200);
|
||||
|
||||
setTimeout(() => {
|
||||
if (dialogSearchVisible.value) {
|
||||
SearchUidKeyRef.value.searchMsg = insidersMsgActive.searchOptions.uid;
|
||||
SelectStatusSearchRef.value.searchMsg = insidersMsgActive.searchOptions.status;
|
||||
SelectRoleSearchRef.value.searchMsg = insidersMsgActive.searchOptions.role;
|
||||
SearchNameKeyRef.value.searchMsg = insidersMsgActive.searchOptions.name;
|
||||
SearchDepartmentKeyRef.value.searchMsg = insidersMsgActive.searchOptions.department;
|
||||
SearchChangeKeyRef.value.searchMsg = insidersMsgActive.searchOptions.change;
|
||||
createdDateTimePickerRef.value.created_at =
|
||||
insidersMsgActive.searchOptions.created_at;
|
||||
updatedDateTimePickerRef.value.updated_at =
|
||||
insidersMsgActive.searchOptions.updated_at;
|
||||
loginDateTimePickerRef.value.login_at = insidersMsgActive.searchOptions.login_at;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
createdSortDateTimeRef.value.searchMsg = insidersMsgActive.sortOptions.created_at;
|
||||
updatedSortDateTimeRef.value.searchMsg = insidersMsgActive.sortOptions.updated_at;
|
||||
loginSortDateTimeRef.value.searchMsg = insidersMsgActive.sortOptions.login_at;
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
594
src/components/mainPage/monitoring.vue
Normal file
@@ -0,0 +1,594 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 表格 -->
|
||||
<el-card>
|
||||
<div class="flex justify-center flex-wrap">
|
||||
<TabelTools @showTools="showTools" :dialogObj="monitoringMsgActive" />
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="tableData"
|
||||
style="width: 100%"
|
||||
max-height="50rem"
|
||||
table-layout="auto"
|
||||
scrollbar-always-on
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column
|
||||
v-if="dialogOperationVisible"
|
||||
fixed="left"
|
||||
type="selection"
|
||||
width="40"
|
||||
column-key="selection"
|
||||
/>
|
||||
<TabelSelect
|
||||
v-if="dialogOperationVisible"
|
||||
ref="DelSelectRef"
|
||||
:holderText="delSelectHold"
|
||||
singleColor="danger"
|
||||
multipleColor="warning"
|
||||
allColor="danger"
|
||||
singleSize="small"
|
||||
multipleSize="small"
|
||||
allSize="small"
|
||||
:singlePlain="true"
|
||||
:multiplePlain="false"
|
||||
:allPlain="false"
|
||||
operateType="del"
|
||||
@showComfirmDialog="showComfirmDialog"
|
||||
/>
|
||||
<el-table-column min-width="100" column-key="operate">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectOperateSearchRef"
|
||||
holderText="选择操作名称以搜索相关数据"
|
||||
:options="operateOptions"
|
||||
@search="monitoringMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 操作名称 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(operateOptions, scope.row.operate)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(operateOptions, scope.row.operate) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100" column-key="operate_msg">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchOperateMsgKeyRef"
|
||||
holderText="输入操作描述以搜索相关数据"
|
||||
@search="monitoringMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 操作描述 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.operate_msg }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100" column-key="type">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectTypeSearchRef"
|
||||
holderText="选择危险等级以搜索相关数据"
|
||||
:options="typeOptions"
|
||||
@search="monitoringMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 危险等级 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(typeOptions, scope.row.type)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(typeOptions, scope.row.type) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="150" column-key="status">
|
||||
<template #header>
|
||||
<SelectSearch
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SelectStatusSearchRef"
|
||||
holderText="选择执行状态以搜索相关数据"
|
||||
:options="statusOptions"
|
||||
@search="monitoringMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 执行状态 </el-text>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div
|
||||
:style="styleShunt(statusOptions, scope.row.status)"
|
||||
class="flex justify-start items-center text-base"
|
||||
>
|
||||
{{ labelShunt(statusOptions, scope.row.status) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="80" column-key="affect_entries">
|
||||
<template #header>
|
||||
<div>
|
||||
<div>
|
||||
<el-text class="mx-1"> 影响到的数据数目 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.affect_entries }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="140" column-key="user">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchUserKeyRef"
|
||||
holderText="输入操作者uid以搜索相关数据"
|
||||
@search="monitoringMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 操作者uid </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.user }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="140" column-key="name">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchNameKeyRef"
|
||||
holderText="输入操作者姓名以搜索相关数据"
|
||||
@search="monitoringMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 操作者姓名 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.name }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="created_at">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="createdDateTimePickerRef"
|
||||
DateTimePicker="createdDateTimePicker"
|
||||
@search="monitoringMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 行为记录时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="createdSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="monitoringMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.created_at }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<Pagination
|
||||
ref="PaginationRef"
|
||||
:active="monitoringMsgActive"
|
||||
@sizeChangeBack="changePage"
|
||||
@search="monitoringMsg"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
<PasswordOauth
|
||||
ref="delPasswordOauthRef"
|
||||
operateLabel="删除系统记录"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch, onMounted, nextTick } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import TabelTools from "../operate/tabelTools.vue";
|
||||
import TabelSelect from "../operate/tabelSelect.vue";
|
||||
import SearchKey from "../search/searchKey.vue";
|
||||
import SortSearch from "../search/sortSearch.vue";
|
||||
import SelectSearch from "../search/selectSearch.vue";
|
||||
import DateTimePicker from "../search/dateTimePicker.vue";
|
||||
import Pagination from "../search/pagination.vue";
|
||||
import PasswordOauth from "../operate/passwordOauth.vue";
|
||||
|
||||
import monitoringActiveStore from "../../stores/monitoring";
|
||||
|
||||
import moment from "moment";
|
||||
|
||||
import $http from "../../api/index";
|
||||
import $url from "../../api/url";
|
||||
|
||||
import { encrypt } from "../../utils/aes";
|
||||
import { judgment } from "../../utils/judgment.js";
|
||||
import { hasNullOrEmptyPropertyWithTypeof } from "../../utils/hasNullOrEmptyPropertyWithTypeof.js";
|
||||
|
||||
const monitoringMsgActive = monitoringActiveStore();
|
||||
|
||||
const delSelectHold = {
|
||||
single: "删除",
|
||||
multiple: "删除选中",
|
||||
all: "删除所有",
|
||||
label: "删除系统记录",
|
||||
};
|
||||
const DelSelectRef = ref(null);
|
||||
const SelectOperateSearchRef = ref(null);
|
||||
const SearchOperateMsgKeyRef = ref(null);
|
||||
const SelectTypeSearchRef = ref(null);
|
||||
const SelectStatusSearchRef = ref(null);
|
||||
const SearchUserKeyRef = ref(null);
|
||||
const SearchNameKeyRef = ref(null);
|
||||
const createdDateTimePickerRef = ref(null);
|
||||
const createdSortDateTimeRef = ref(null);
|
||||
const PaginationRef = ref(null);
|
||||
const delPasswordOauthRef = ref(null);
|
||||
const dialogSearchVisible = ref(false);
|
||||
const dialogSortVisible = ref(false);
|
||||
const dialogOperationVisible = ref(false);
|
||||
const tableRef = ref();
|
||||
const offsetOff = ref(true);
|
||||
const pageCount = ref(0);
|
||||
const operate = ref("del");
|
||||
const searchOptions = reactive({
|
||||
operate: "",
|
||||
operate_msg: "",
|
||||
type: "",
|
||||
status: "",
|
||||
affect_entries: "",
|
||||
user: "",
|
||||
created_at: "",
|
||||
});
|
||||
const sortOptions = reactive({
|
||||
created_at: false,
|
||||
});
|
||||
const tableData = ref([]);
|
||||
const operateOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "新增数据",
|
||||
style: "color: rgb(16, 184, 130);background-color: rgba(16, 184, 130, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "编辑数据",
|
||||
style: "color: rgb(255, 200, 0);background-color: rgba(255, 200, 0, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "删除数据",
|
||||
style: "color: rgb(240, 70, 70);background-color: rgba(240, 70, 70, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
const typeOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "普通",
|
||||
style: "color: rgb(16, 184, 130);background-color: rgba(16, 184, 130, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "重要",
|
||||
style: "color: rgb(255, 200, 0);background-color: rgba(255, 200, 0, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "危险",
|
||||
style: "color: rgb(240, 70, 70);background-color: rgba(240, 70, 70, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
const statusOptions = [
|
||||
{
|
||||
value: "0",
|
||||
label: "操作执行失败,原因:无用户身份",
|
||||
style: "color: rgb(120, 140, 180);background-color: rgba(120, 140, 180, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "1",
|
||||
label: "操作执行失败,原因:密码错误",
|
||||
style: "color: rgb(255, 100, 180);background-color: rgba(255, 100, 180, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "2",
|
||||
label: "操作执行失败,原因:权限不足",
|
||||
style: "color: rgb(56, 188, 248);background-color: rgba(56, 188, 248, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "3",
|
||||
label: "操作执行失败,原因:查询条件错误",
|
||||
style: "color: rgb(255, 200, 0);background-color: rgba(255, 200, 0, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "4",
|
||||
label: "操作执行成功",
|
||||
style: "color: rgb(16, 184, 130);background-color: rgba(16, 184, 130, 0.1);padding: 0;",
|
||||
},
|
||||
{
|
||||
value: "5",
|
||||
label: "操作执行失败,原因:程序错误",
|
||||
style: "color: rgb(240, 70, 70);background-color: rgba(240, 70, 70, 0.1);padding: 0;",
|
||||
},
|
||||
];
|
||||
let singleData = reactive({});
|
||||
let operateData = reactive({});
|
||||
let operateDataClone = reactive({});
|
||||
|
||||
const styleShunt = (options, data) => {
|
||||
let nowStyle;
|
||||
options.forEach((item) => {
|
||||
if (data == item.value) {
|
||||
nowStyle = item.style;
|
||||
}
|
||||
});
|
||||
return nowStyle;
|
||||
};
|
||||
|
||||
const labelShunt = (options, data) => {
|
||||
let nowLabel;
|
||||
options.forEach((item) => {
|
||||
if (data == item.value) {
|
||||
nowLabel = item.label;
|
||||
}
|
||||
});
|
||||
return nowLabel;
|
||||
};
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "search":
|
||||
dialogSearchVisible.value = !dialogSearchVisible.value;
|
||||
monitoringMsgActive.dialogSearchVisible = dialogSearchVisible.value;
|
||||
break;
|
||||
case "sort":
|
||||
dialogSortVisible.value = !dialogSortVisible.value;
|
||||
monitoringMsgActive.dialogSortVisible = dialogSortVisible.value;
|
||||
break;
|
||||
case "operation":
|
||||
dialogOperationVisible.value = !dialogOperationVisible.value;
|
||||
monitoringMsgActive.dialogOperationVisible = dialogOperationVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetOffset = () => {
|
||||
if (hasNullOrEmptyPropertyWithTypeof(searchOptions)) {
|
||||
if (PaginationRef.value.offset !== 1 && offsetOff.value) {
|
||||
PaginationRef.value.handleCurrentChange(1);
|
||||
offsetOff.value = false;
|
||||
}
|
||||
} else {
|
||||
offsetOff.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
const monitoringMsg = () => {
|
||||
judgment(searchOptions, "operate", SelectOperateSearchRef.value, "searchMsg");
|
||||
judgment(searchOptions, "operate_msg", SearchOperateMsgKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "type", SelectTypeSearchRef.value, "searchMsg");
|
||||
judgment(searchOptions, "status", SelectStatusSearchRef.value, "searchMsg");
|
||||
judgment(searchOptions, "created_at", createdDateTimePickerRef.value, "searchMsg");
|
||||
judgment(searchOptions, "user", SearchUserKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "name", SearchNameKeyRef.value, "searchMsg");
|
||||
judgment(sortOptions, "created_at", createdSortDateTimeRef.value, "searchMsg");
|
||||
resetOffset();
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
offset: PaginationRef.value == null ? 1 : PaginationRef.value.offset,
|
||||
limit: PaginationRef.value == null ? 10 : PaginationRef.value.limit,
|
||||
searchOptions: searchOptions,
|
||||
sortOptions: sortOptions,
|
||||
};
|
||||
$http.post($url.showMonitoring, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableData.value = res.data.MonitoringMsg;
|
||||
tableData.value.forEach((item) => {
|
||||
item.origin_createdAt = item.created_at;
|
||||
item.created_at = moment
|
||||
.utc(item.created_at)
|
||||
.add(0, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
});
|
||||
PaginationRef.value.dataCount = res.data.count;
|
||||
monitoringMsgActive.dataCount = PaginationRef.value.dataCount;
|
||||
pageCount.value = Math.ceil(
|
||||
PaginationRef.value.dataCount / PaginationRef.value.limit
|
||||
);
|
||||
monitoringMsgActive.pageCount = pageCount.value;
|
||||
if (!operateData[PaginationRef.value.offset]) return;
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
tableData.value.forEach((item) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
nextTick(() => {
|
||||
tableRef.value.toggleRowSelection(item, true);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
tableData.value = [];
|
||||
ElMessage.error("未查找到相关数据!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const changePage = (val) => {
|
||||
pageCount.value = Math.ceil(PaginationRef.value.dataCount / val);
|
||||
operateData = {};
|
||||
for (let i = 0; i < pageCount.value; i++) {
|
||||
operateData[i + 1] = [];
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((element) => {
|
||||
// 判断数据在第几页
|
||||
if (Math.ceil(element.location / PaginationRef.value.limit) == i + 1) {
|
||||
operateData[i + 1].push(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelectionChange = (val) => {
|
||||
operateData[PaginationRef.value.offset] = val;
|
||||
tableData.value.forEach((item, index) => {
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
// 数据在表格中的位置
|
||||
element.location =
|
||||
(PaginationRef.value.offset - 1) * PaginationRef.value.limit + (index + 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
operateDataClone = JSON.parse(JSON.stringify(operateData));
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((item) => {
|
||||
if (item.origin_createdAt) {
|
||||
item.created_at = item.origin_createdAt;
|
||||
}
|
||||
delete item.origin_createdAt;
|
||||
delete item.location;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const showComfirmDialog = (singleMsg) => {
|
||||
singleData = { ...singleMsg.data };
|
||||
singleData.created_at = singleData.origin_createdAt;
|
||||
delete singleData.origin_createdAt;
|
||||
operate.value = singleMsg.operateType;
|
||||
if (singleMsg.operateType == "del") {
|
||||
delPasswordOauthRef.value.operateDialogVisible = true;
|
||||
}
|
||||
};
|
||||
|
||||
const requestOperate = () => {
|
||||
let operateType, url, model, password;
|
||||
if (operate.value == "del") {
|
||||
operateType = "删除";
|
||||
url = $url.deleteMonitoring;
|
||||
model = DelSelectRef.value.model;
|
||||
password = delPasswordOauthRef.value.ruleForm.password;
|
||||
}
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
model: encrypt(model),
|
||||
password: encrypt(password),
|
||||
requestMsg:
|
||||
model == "single" ? singleData : model == "multiple" ? operateDataClone : "",
|
||||
};
|
||||
$http.post(url, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableRef.value.clearSelection();
|
||||
operateData = {};
|
||||
operateDataClone = {};
|
||||
ElMessage({
|
||||
message: `${operateType}成功!`,
|
||||
type: "success",
|
||||
});
|
||||
monitoringMsg();
|
||||
} else {
|
||||
ElMessage.error(`${operateType}失败!`);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ monitoringMsg });
|
||||
|
||||
watch(searchOptions, (value) => {
|
||||
monitoringMsgActive.searchOptions = value;
|
||||
});
|
||||
|
||||
watch(sortOptions, (value) => {
|
||||
monitoringMsgActive.sortOptions = value;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
pageCount.value = monitoringMsgActive.pageCount;
|
||||
dialogSearchVisible.value = monitoringMsgActive.dialogSearchVisible;
|
||||
dialogSortVisible.value = monitoringMsgActive.dialogSortVisible;
|
||||
dialogOperationVisible.value = monitoringMsgActive.dialogOperationVisible;
|
||||
|
||||
if (dialogSearchVisible.value) {
|
||||
searchOptions.operate = monitoringMsgActive.searchOptions.operate;
|
||||
searchOptions.operate_msg = monitoringMsgActive.searchOptions.operate_msg;
|
||||
searchOptions.type = monitoringMsgActive.searchOptions.type;
|
||||
searchOptions.status = monitoringMsgActive.searchOptions.status;
|
||||
searchOptions.created_at = monitoringMsgActive.searchOptions.created_at;
|
||||
searchOptions.user = monitoringMsgActive.searchOptions.user;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
sortOptions.created_at = monitoringMsgActive.sortOptions.created_at;
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
monitoringMsg();
|
||||
}, 200);
|
||||
|
||||
setTimeout(() => {
|
||||
if (dialogSearchVisible.value) {
|
||||
SelectOperateSearchRef.value.searchMsg = monitoringMsgActive.searchOptions.operate;
|
||||
SearchOperateMsgKeyRef.value.searchMsg =
|
||||
monitoringMsgActive.searchOptions.operate_msg;
|
||||
SelectTypeSearchRef.value.searchMsg = monitoringMsgActive.searchOptions.type;
|
||||
SelectStatusSearchRef.value.searchMsg = monitoringMsgActive.searchOptions.status;
|
||||
createdDateTimePickerRef.value.created_at =
|
||||
monitoringMsgActive.searchOptions.created_at;
|
||||
SearchUserKeyRef.value.searchMsg = monitoringMsgActive.searchOptions.user;
|
||||
SearchNameKeyRef.value.searchMsg = monitoringMsgActive.searchOptions.name;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
createdSortDateTimeRef.value.searchMsg = monitoringMsgActive.sortOptions.created_at;
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
655
src/components/mainPage/organization.vue
Normal file
@@ -0,0 +1,655 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 表格 -->
|
||||
<el-card>
|
||||
<div class="flex justify-center flex-wrap">
|
||||
<TabelTools @showTools="showTools" :dialogObj="organizationMsgActive" />
|
||||
<AddNewData newDataLabel="新增用户单位" @showAddForm="showAddForm" />
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="tableData"
|
||||
style="width: 100%"
|
||||
max-height="50rem"
|
||||
table-layout="auto"
|
||||
scrollbar-always-on
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<TabelSelect
|
||||
v-if="dialogOperationVisible"
|
||||
ref="EditSelectRef"
|
||||
:holderText="editSelectHold"
|
||||
singleColor="primary"
|
||||
multipleColor="warning"
|
||||
allColor="danger"
|
||||
singleSize="small"
|
||||
multipleSize="small"
|
||||
allSize="small"
|
||||
:singlePlain="true"
|
||||
:multiplePlain="false"
|
||||
:allPlain="false"
|
||||
operateType="edit"
|
||||
singleType="single"
|
||||
@showComfirmDialog="showComfirmDialog"
|
||||
/>
|
||||
<TabelSelect
|
||||
v-if="dialogOperationVisible"
|
||||
ref="DelSelectRef"
|
||||
:holderText="delSelectHold"
|
||||
singleColor="danger"
|
||||
multipleColor="warning"
|
||||
allColor="danger"
|
||||
singleSize="small"
|
||||
multipleSize="small"
|
||||
allSize="small"
|
||||
:singlePlain="true"
|
||||
:multiplePlain="false"
|
||||
:allPlain="false"
|
||||
operateType="del"
|
||||
@showComfirmDialog="showComfirmDialog"
|
||||
/>
|
||||
<el-table-column min-width="150" column-key="uid">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchUidKeyRef"
|
||||
holderText="输入单位uid以搜索相关数据"
|
||||
@search="organizationMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 单位uid </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.uid }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="organization_name">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchOrganizationNameKeyRef"
|
||||
holderText="输入单位名称以搜索相关数据"
|
||||
@search="organizationMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 单位名称 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.organization_name }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="address">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchAddressKeyRef"
|
||||
holderText="输入通信地址以搜索相关数据"
|
||||
@search="organizationMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 通信地址 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.address }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100" column-key="liaison_name">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchLiaisonNameKeyRef"
|
||||
holderText="输入联系人姓名以搜索相关数据"
|
||||
@search="organizationMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 联系人姓名 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.liaison_name }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="120" column-key="phone">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchPhoneKeyRef"
|
||||
holderText="输入联系人电话以搜索相关数据"
|
||||
@search="organizationMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 联系人电话 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.phone }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="email">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchEmailKeyRef"
|
||||
holderText="输入单位邮箱以搜索相关数据"
|
||||
@search="organizationMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 单位邮箱 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.email }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="other_information">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchOtherInformationKeyRef"
|
||||
holderText="输入信息关键字以搜索相关数据"
|
||||
@search="organizationMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 其他信息 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.other_information }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="100" column-key="post_code">
|
||||
<template #header>
|
||||
<div>
|
||||
<SearchKey
|
||||
v-if="dialogSearchVisible"
|
||||
ref="SearchPostCodeKeyRef"
|
||||
holderText="输入邮政编码以搜索相关数据"
|
||||
@search="organizationMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 邮政编码 </el-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.post_code }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="created_at">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="createdDateTimePickerRef"
|
||||
DateTimePicker="createdDateTimePicker"
|
||||
@search="organizationMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 添加时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="createdSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="organizationMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.created_at }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column min-width="200" column-key="updated_at">
|
||||
<template #header>
|
||||
<DateTimePicker
|
||||
v-if="dialogSearchVisible"
|
||||
ref="updatedDateTimePickerRef"
|
||||
DateTimePicker="updatedMsgDateTimePicker"
|
||||
@search="organizationMsg"
|
||||
/>
|
||||
<div>
|
||||
<el-text class="mx-1"> 上次信息变更时间 </el-text>
|
||||
<SortSearch
|
||||
v-if="dialogSortVisible"
|
||||
ref="updatedSortDateTimeRef"
|
||||
activeText="顺序"
|
||||
inactiveText="倒序"
|
||||
@search="organizationMsg"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div class="flex justify-start items-center text-base">
|
||||
{{ scope.row.updated_at }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<Pagination
|
||||
ref="PaginationRef"
|
||||
:active="organizationMsgActive"
|
||||
@sizeChangeBack="changePage"
|
||||
@search="organizationMsg"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
<AddOrganizationForm
|
||||
ref="addOrganizationFormRef"
|
||||
title="新增用户单位"
|
||||
@reloadData="organizationMsg"
|
||||
/>
|
||||
<EditOrganizationForm
|
||||
ref="editOrganizationFormRef"
|
||||
operateLabel="编辑用户单位"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
<PasswordOauth
|
||||
ref="delPasswordOauthRef"
|
||||
operateLabel="删除用户单位"
|
||||
@requestOperate="requestOperate"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch, onMounted, nextTick } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import TabelTools from "../operate/tabelTools.vue";
|
||||
import AddNewData from "../operate/addNewData.vue";
|
||||
import TabelSelect from "../operate/tabelSelect.vue";
|
||||
import SearchKey from "../search/searchKey.vue";
|
||||
import SortSearch from "../search/sortSearch.vue";
|
||||
import DateTimePicker from "../search/dateTimePicker.vue";
|
||||
import Pagination from "../search/pagination.vue";
|
||||
import AddOrganizationForm from "../addNewData/organizationForm/organizationForm.vue";
|
||||
import EditOrganizationForm from "../editData/organizationForm.vue";
|
||||
import PasswordOauth from "../operate/passwordOauth.vue";
|
||||
|
||||
import organizationActiveStore from "../../stores/organization";
|
||||
|
||||
import moment from "moment";
|
||||
|
||||
import $http from "../../api/index";
|
||||
import $url from "../../api/url";
|
||||
|
||||
import { encrypt } from "../../utils/aes";
|
||||
import { judgment } from "../../utils/judgment.js";
|
||||
import { hasNullOrEmptyPropertyWithTypeof } from "../../utils/hasNullOrEmptyPropertyWithTypeof.js";
|
||||
|
||||
const organizationMsgActive = organizationActiveStore();
|
||||
|
||||
const editSelectHold = {
|
||||
single: "编辑",
|
||||
multiple: "编辑选中",
|
||||
all: "编辑所有",
|
||||
label: "编辑用户单位",
|
||||
};
|
||||
|
||||
const delSelectHold = {
|
||||
single: "删除",
|
||||
multiple: "删除选中",
|
||||
all: "删除所有",
|
||||
label: "删除用户单位",
|
||||
};
|
||||
const EditSelectRef = ref(null);
|
||||
const DelSelectRef = ref(null);
|
||||
const SearchUidKeyRef = ref(null);
|
||||
const SearchOrganizationNameKeyRef = ref(null);
|
||||
const SearchAddressKeyRef = ref(null);
|
||||
const SearchLiaisonNameKeyRef = ref(null);
|
||||
const SearchPhoneKeyRef = ref(null);
|
||||
const SearchEmailKeyRef = ref(null);
|
||||
const SearchOtherInformationKeyRef = ref(null);
|
||||
const SearchPostCodeKeyRef = ref(null);
|
||||
const createdDateTimePickerRef = ref(null);
|
||||
const updatedDateTimePickerRef = ref(null);
|
||||
const createdSortDateTimeRef = ref(null);
|
||||
const updatedSortDateTimeRef = ref(null);
|
||||
const PaginationRef = ref(null);
|
||||
const addOrganizationFormRef = ref(null);
|
||||
const editOrganizationFormRef = ref(null);
|
||||
const delPasswordOauthRef = ref(null);
|
||||
const dialogSearchVisible = ref(false);
|
||||
const dialogSortVisible = ref(false);
|
||||
const dialogOperationVisible = ref(false);
|
||||
const tableRef = ref();
|
||||
const offsetOff = ref(true);
|
||||
const pageCount = ref(0);
|
||||
const operate = ref("edit");
|
||||
const searchOptions = reactive({
|
||||
uid: "",
|
||||
organization_name: "",
|
||||
address: "",
|
||||
liaison_name: "",
|
||||
phone: "",
|
||||
email: "",
|
||||
other_information: "",
|
||||
post_code: "",
|
||||
created_at: "",
|
||||
updated_at: "",
|
||||
});
|
||||
const sortOptions = reactive({
|
||||
created_at: false,
|
||||
updated_at: false,
|
||||
});
|
||||
const tableData = ref([]);
|
||||
let singleData = reactive({});
|
||||
let operateData = reactive({});
|
||||
let operateDataClone = reactive({});
|
||||
|
||||
const showAddForm = () => {
|
||||
addOrganizationFormRef.value.dialogVisible = true;
|
||||
};
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "search":
|
||||
dialogSearchVisible.value = !dialogSearchVisible.value;
|
||||
organizationMsgActive.dialogSearchVisible = dialogSearchVisible.value;
|
||||
break;
|
||||
case "sort":
|
||||
dialogSortVisible.value = !dialogSortVisible.value;
|
||||
organizationMsgActive.dialogSortVisible = dialogSortVisible.value;
|
||||
break;
|
||||
case "operation":
|
||||
dialogOperationVisible.value = !dialogOperationVisible.value;
|
||||
organizationMsgActive.dialogOperationVisible = dialogOperationVisible.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const resetOffset = () => {
|
||||
if (hasNullOrEmptyPropertyWithTypeof(searchOptions)) {
|
||||
if (PaginationRef.value.offset !== 1 && offsetOff.value) {
|
||||
PaginationRef.value.handleCurrentChange(1);
|
||||
offsetOff.value = false;
|
||||
}
|
||||
} else {
|
||||
offsetOff.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
const organizationMsg = () => {
|
||||
judgment(searchOptions, "uid", SearchUidKeyRef.value, "searchMsg");
|
||||
judgment(
|
||||
searchOptions,
|
||||
"organization_name",
|
||||
SearchOrganizationNameKeyRef.value,
|
||||
"searchMsg"
|
||||
);
|
||||
judgment(searchOptions, "address", SearchAddressKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "liaison_name", SearchLiaisonNameKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "phone", SearchPhoneKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "email", SearchEmailKeyRef.value, "searchMsg");
|
||||
judgment(
|
||||
searchOptions,
|
||||
"other_information",
|
||||
SearchOtherInformationKeyRef.value,
|
||||
"searchMsg"
|
||||
);
|
||||
judgment(searchOptions, "post_code", SearchPostCodeKeyRef.value, "searchMsg");
|
||||
judgment(searchOptions, "created_at", createdDateTimePickerRef.value, "searchMsg");
|
||||
judgment(searchOptions, "updated_at", updatedDateTimePickerRef.value, "searchMsg");
|
||||
judgment(sortOptions, "created_at", createdSortDateTimeRef.value, "searchMsg");
|
||||
judgment(sortOptions, "updated_at", updatedSortDateTimeRef.value, "searchMsg");
|
||||
resetOffset();
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
offset: PaginationRef.value == null ? 1 : PaginationRef.value.offset,
|
||||
limit: PaginationRef.value == null ? 10 : PaginationRef.value.limit,
|
||||
searchOptions: searchOptions,
|
||||
sortOptions: sortOptions,
|
||||
};
|
||||
$http.post($url.showOrganization, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableData.value = res.data.OrganizationMsg;
|
||||
tableData.value.forEach((item) => {
|
||||
item.origin_createdAt = item.created_at;
|
||||
item.created_at = moment
|
||||
.utc(item.created_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
item.origin_updatedAt = item.updated_at;
|
||||
item.updated_at = moment
|
||||
.utc(item.updated_at)
|
||||
.add(8, "hours")
|
||||
.format("YYYY-MM-DD-HH:mm:ss");
|
||||
});
|
||||
PaginationRef.value.dataCount = res.data.count;
|
||||
organizationMsgActive.dataCount = PaginationRef.value.dataCount;
|
||||
pageCount.value = Math.ceil(
|
||||
PaginationRef.value.dataCount / PaginationRef.value.limit
|
||||
);
|
||||
organizationMsgActive.pageCount = pageCount.value;
|
||||
if (!operateData[PaginationRef.value.offset]) return;
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
tableData.value.forEach((item) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
nextTick(() => {
|
||||
tableRef.value.toggleRowSelection(item, true);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
tableData.value = [];
|
||||
ElMessage.error("未查找到相关数据!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const changePage = (val) => {
|
||||
pageCount.value = Math.ceil(PaginationRef.value.dataCount / val);
|
||||
operateData = {};
|
||||
for (let i = 0; i < pageCount.value; i++) {
|
||||
operateData[i + 1] = [];
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((element) => {
|
||||
// 判断数据在第几页
|
||||
if (Math.ceil(element.location / PaginationRef.value.limit) == i + 1) {
|
||||
operateData[i + 1].push(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelectionChange = (val) => {
|
||||
operateData[PaginationRef.value.offset] = val;
|
||||
tableData.value.forEach((item, index) => {
|
||||
operateData[PaginationRef.value.offset].forEach((element) => {
|
||||
if (item.created_at == element.created_at) {
|
||||
// 数据在表格中的位置
|
||||
element.location =
|
||||
(PaginationRef.value.offset - 1) * PaginationRef.value.limit + (index + 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
operateDataClone = JSON.parse(JSON.stringify(operateData));
|
||||
for (const key in operateDataClone) {
|
||||
operateDataClone[key].forEach((item) => {
|
||||
if (item.origin_createdAt) {
|
||||
item.created_at = item.origin_createdAt;
|
||||
}
|
||||
if (item.origin_updatedAt) {
|
||||
item.created_at = item.origin_updatedAt;
|
||||
}
|
||||
delete item.origin_createdAt;
|
||||
delete item.origin_updatedAt;
|
||||
delete item.location;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const showComfirmDialog = (singleMsg) => {
|
||||
singleData = { ...singleMsg.data };
|
||||
singleData.created_at = singleData.origin_createdAt;
|
||||
singleData.updated_at = singleData.origin_updatedAt;
|
||||
delete singleData.origin_createdAt;
|
||||
delete singleData.origin_updatedAt;
|
||||
operate.value = singleMsg.operateType;
|
||||
if (singleMsg.operateType == "edit") {
|
||||
editOrganizationFormRef.value.originForm({ ...singleMsg.data });
|
||||
editOrganizationFormRef.value.operateDialogVisible = true;
|
||||
editOrganizationFormRef.value.model = EditSelectRef.value.model;
|
||||
}
|
||||
if (singleMsg.operateType == "del") {
|
||||
delPasswordOauthRef.value.operateDialogVisible = true;
|
||||
}
|
||||
};
|
||||
|
||||
const requestOperate = () => {
|
||||
let operateType, url, model, password;
|
||||
if (operate.value == "edit") {
|
||||
operateType = "编辑";
|
||||
url = $url.editOrganization;
|
||||
model = EditSelectRef.value.model;
|
||||
password = editOrganizationFormRef.value.password;
|
||||
} else if (operate.value == "del") {
|
||||
operateType = "删除";
|
||||
url = $url.deleteOrganization;
|
||||
model = DelSelectRef.value.model;
|
||||
password = delPasswordOauthRef.value.ruleForm.password;
|
||||
}
|
||||
const data = {
|
||||
uid: localStorage.data,
|
||||
model: encrypt(model),
|
||||
password: encrypt(password),
|
||||
requestMsg:
|
||||
model == "single" ? singleData : model == "multiple" ? operateDataClone : "",
|
||||
};
|
||||
if (operate.value == "edit") {
|
||||
data.updateMsg = { ...editOrganizationFormRef.value.ruleForm };
|
||||
}
|
||||
$http.post(url, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
tableRef.value.clearSelection();
|
||||
operateData = {};
|
||||
operateDataClone = {};
|
||||
ElMessage({
|
||||
message: `${operateType}成功!`,
|
||||
type: "success",
|
||||
});
|
||||
organizationMsg();
|
||||
} else {
|
||||
ElMessage.error(`${operateType}失败!`);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ organizationMsg });
|
||||
|
||||
watch(searchOptions, (value) => {
|
||||
organizationMsgActive.searchOptions = value;
|
||||
});
|
||||
|
||||
watch(sortOptions, (value) => {
|
||||
organizationMsgActive.sortOptions = value;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
pageCount.value = organizationMsgActive.pageCount;
|
||||
dialogSearchVisible.value = organizationMsgActive.dialogSearchVisible;
|
||||
dialogSortVisible.value = organizationMsgActive.dialogSortVisible;
|
||||
dialogOperationVisible.value = organizationMsgActive.dialogOperationVisible;
|
||||
|
||||
if (dialogSearchVisible.value) {
|
||||
searchOptions.uid = organizationMsgActive.searchOptions.uid;
|
||||
searchOptions.organization_name =
|
||||
organizationMsgActive.searchOptions.organization_name;
|
||||
searchOptions.address = organizationMsgActive.searchOptions.address;
|
||||
searchOptions.liaison_name = organizationMsgActive.searchOptions.liaison_name;
|
||||
searchOptions.phone = organizationMsgActive.searchOptions.phone;
|
||||
searchOptions.email = organizationMsgActive.searchOptions.email;
|
||||
searchOptions.other_information =
|
||||
organizationMsgActive.searchOptions.other_information;
|
||||
searchOptions.post_code = organizationMsgActive.searchOptions.post_code;
|
||||
searchOptions.type = organizationMsgActive.searchOptions.type;
|
||||
searchOptions.status = organizationMsgActive.searchOptions.status;
|
||||
searchOptions.created_at = organizationMsgActive.searchOptions.created_at;
|
||||
searchOptions.updated_at = organizationMsgActive.searchOptions.updated_at;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
sortOptions.created_at = organizationMsgActive.sortOptions.created_at;
|
||||
sortOptions.updated_at = organizationMsgActive.sortOptions.updated_at;
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
organizationMsg();
|
||||
}, 200);
|
||||
|
||||
setTimeout(() => {
|
||||
if (dialogSearchVisible.value) {
|
||||
SearchUidKeyRef.value.searchMsg = organizationMsgActive.searchOptions.uid;
|
||||
SearchOrganizationNameKeyRef.value.searchMsg =
|
||||
organizationMsgActive.searchOptions.organization_name;
|
||||
SearchAddressKeyRef.value.searchMsg = organizationMsgActive.searchOptions.address;
|
||||
SearchLiaisonNameKeyRef.value.searchMsg =
|
||||
organizationMsgActive.searchOptions.liaison_name;
|
||||
SearchPhoneKeyRef.value.searchMsg = organizationMsgActive.searchOptions.phone;
|
||||
SearchEmailKeyRef.value.searchMsg = organizationMsgActive.searchOptions.email;
|
||||
SearchOtherInformationKeyRef.value.searchMsg =
|
||||
organizationMsgActive.searchOptions.other_information;
|
||||
SearchPostCodeKeyRef.value.searchMsg =
|
||||
organizationMsgActive.searchOptions.post_code;
|
||||
createdDateTimePickerRef.value.created_at =
|
||||
organizationMsgActive.searchOptions.created_at;
|
||||
updatedDateTimePickerRef.value.updated_at =
|
||||
organizationMsgActive.searchOptions.updated_at;
|
||||
}
|
||||
|
||||
if (dialogSortVisible.value) {
|
||||
createdSortDateTimeRef.value.searchMsg =
|
||||
organizationMsgActive.sortOptions.created_at;
|
||||
updatedSortDateTimeRef.value.searchMsg =
|
||||
organizationMsgActive.sortOptions.updated_at;
|
||||
}
|
||||
|
||||
if (dialogOperationVisible.value) {
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
220
src/components/manager/changePassword.vue
Normal file
@@ -0,0 +1,220 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<template #header="{ close, titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
密码管理
|
||||
</div>
|
||||
<div
|
||||
@click="close"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer"
|
||||
>
|
||||
<el-icon class="el-icon--left">
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="原密码" prop="oldPassword">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入原密码"
|
||||
type="password"
|
||||
show-password
|
||||
maxlength="16"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.oldPassword"
|
||||
@input="filter(ruleForm.oldPassword, 'oldPassword')"
|
||||
oncut="return false"
|
||||
onpaste="return false"
|
||||
oncopy="return false"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="新密码" prop="newPassword">
|
||||
<el-text
|
||||
style="color: rgb(240 70 70)"
|
||||
class="mx-1 font-bold"
|
||||
size="small"
|
||||
type="info"
|
||||
>
|
||||
密码必须包含数字、大小写字母以及特殊字符(!@#$%^&*),且长度在8-16位之间
|
||||
</el-text>
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请输入新密码"
|
||||
type="password"
|
||||
show-password
|
||||
maxlength="16"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.newPassword"
|
||||
@input="filter(ruleForm.newPassword, 'newPassword')"
|
||||
oncut="return false"
|
||||
onpaste="return false"
|
||||
oncopy="return false"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="确认新密码" prop="checkPass">
|
||||
<el-input
|
||||
clearable
|
||||
placeholder="请再次输入新密码"
|
||||
type="checkPass"
|
||||
show-password
|
||||
maxlength="16"
|
||||
autocomplete="off"
|
||||
v-model="ruleForm.checkPass"
|
||||
@input="filter(ruleForm.checkPass, 'checkPass')"
|
||||
oncut="return false"
|
||||
onpaste="return false"
|
||||
oncopy="return false"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetForm(ruleFormRef)">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button
|
||||
style="font-weight: bold"
|
||||
type="primary"
|
||||
@click="changePassword(ruleFormRef)"
|
||||
>
|
||||
提交修改
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import { encrypt } from "../../utils/aes";
|
||||
|
||||
import $http from "../../api/index";
|
||||
import $url from "../../api/url";
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const ruleFormRef = ref(null);
|
||||
const formElClone = ref(null);
|
||||
const ruleForm = reactive({
|
||||
oldPassword: "",
|
||||
newPassword: "",
|
||||
checkPass: "",
|
||||
});
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const passwordRegex = /^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*]).{8,16}$/;
|
||||
|
||||
const validatePass = (rule, value, callback) => {
|
||||
if (value === "") {
|
||||
callback(new Error("请输入密码"));
|
||||
} else if (!passwordRegex.test(value)) {
|
||||
callback(
|
||||
new Error(
|
||||
"密码必须包含数字、大小写字母以及特殊字符(!@#$%^&*),且长度在8-16位之间"
|
||||
)
|
||||
);
|
||||
} else {
|
||||
if (ruleForm.checkPass !== "") {
|
||||
if (!ruleFormRef.value) return;
|
||||
ruleFormRef.value.validateField("checkPass");
|
||||
}
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
const validateCheck = (rule, value, callback) => {
|
||||
if (value === "") {
|
||||
callback(new Error("请再次输入密码"));
|
||||
} else if (value !== ruleForm.newPassword) {
|
||||
callback(new Error("两次输入的密码不一致"));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
const rules = reactive({
|
||||
oldPassword: [{ required: true, message: "请输入原密码", trigger: "blur" }],
|
||||
newPassword: [{ required: true, validator: validatePass, trigger: "blur" }],
|
||||
checkPass: [{ required: true, validator: validateCheck, trigger: "blur" }],
|
||||
});
|
||||
|
||||
const handleClose = () => {
|
||||
dialogVisible.value = false;
|
||||
if (!ruleFormRef) return;
|
||||
formElClone.value = ruleFormRef.value;
|
||||
formElClone.value.resetFields();
|
||||
};
|
||||
|
||||
const resetForm = (formEl) => {
|
||||
dialogVisible.value = false;
|
||||
if (!formEl) return;
|
||||
formEl.resetFields();
|
||||
};
|
||||
|
||||
const changePassword = async (formEl) => {
|
||||
if (!formEl) return;
|
||||
await formEl.validate((valid) => {
|
||||
if (valid) {
|
||||
dialogVisible.value = false;
|
||||
let encryptForm = {
|
||||
oldPassword: encrypt(ruleForm.oldPassword),
|
||||
newPassword: encrypt(ruleForm.newPassword),
|
||||
};
|
||||
formEl.resetFields();
|
||||
const data = {
|
||||
passwordForm: encryptForm,
|
||||
uid: localStorage.data,
|
||||
};
|
||||
$http.post($url.changePassword, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
ElMessage({
|
||||
message: "密码修改成功!",
|
||||
type: "success",
|
||||
});
|
||||
localStorage.clear();
|
||||
window.location.reload();
|
||||
} else {
|
||||
ElMessage.error("密码修改失败!");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ dialogVisible });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
190
src/components/manager/userManager.vue
Normal file
@@ -0,0 +1,190 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<template #header="{ close, titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
账户管理
|
||||
</div>
|
||||
<div
|
||||
@click="close"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer"
|
||||
>
|
||||
<el-icon class="el-icon--left">
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
style="max-width: 600px"
|
||||
:model="ruleForm"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
size="default"
|
||||
status-icon
|
||||
class="mx-auto"
|
||||
>
|
||||
<el-form-item class="mx-1 font-bold" label="姓名" prop="name">
|
||||
<el-input
|
||||
:disabled="acabled"
|
||||
minlength="1"
|
||||
maxlength="20"
|
||||
clearable
|
||||
placeholder="请输入姓名"
|
||||
v-model="ruleForm.name"
|
||||
@input="filter(ruleForm.name, 'name')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="mx-1 font-bold" label="所属部门" prop="department">
|
||||
<el-input
|
||||
maxlength="20"
|
||||
clearable
|
||||
placeholder="请输入所属部门"
|
||||
v-model="ruleForm.department"
|
||||
@input="filter(ruleForm.department, 'department')"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" @click="resetForm(ruleFormRef)">
|
||||
取消
|
||||
</el-button>
|
||||
<el-button
|
||||
style="font-weight: bold"
|
||||
type="primary"
|
||||
@click="editUser(ruleFormRef)"
|
||||
>
|
||||
提交修改
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch, onMounted } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
import userManagerActiveStore from "../../stores/userManager";
|
||||
|
||||
import { encrypt, decrypt } from "../../utils/aes";
|
||||
|
||||
import $http from "../../api/index";
|
||||
import $url from "../../api/url";
|
||||
|
||||
const userManagerActive = userManagerActiveStore();
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const acabled = ref(true);
|
||||
const ruleFormRef = ref(null);
|
||||
const formElClone = ref(null);
|
||||
const ruleForm = reactive({
|
||||
name: "",
|
||||
department: "",
|
||||
});
|
||||
|
||||
const props = defineProps({
|
||||
msg: Object,
|
||||
});
|
||||
|
||||
const filter = (value, label) => {
|
||||
if (/[=\s"'+-]/.test(value)) {
|
||||
if (ruleForm[label]) {
|
||||
ruleForm[label] = value.replace(/[=\s"'+-]/g, "");
|
||||
}
|
||||
} else {
|
||||
ruleForm[label] = value;
|
||||
}
|
||||
};
|
||||
|
||||
const rules = reactive({
|
||||
name: [{ required: false, message: "请输入姓名", trigger: "blur" }],
|
||||
department: [],
|
||||
});
|
||||
|
||||
const handleClose = () => {
|
||||
dialogVisible.value = false;
|
||||
if (!ruleFormRef) return;
|
||||
formElClone.value = ruleFormRef.value;
|
||||
formElClone.value.resetFields();
|
||||
};
|
||||
|
||||
const resetForm = (formEl) => {
|
||||
dialogVisible.value = false;
|
||||
if (!formEl) return;
|
||||
formEl.resetFields();
|
||||
};
|
||||
|
||||
const emit = defineEmits(["resetData"]);
|
||||
|
||||
const reset = () => {
|
||||
ruleForm.name = props.msg.name;
|
||||
ruleForm.department = props.msg.department;
|
||||
};
|
||||
|
||||
const editUser = async (formEl) => {
|
||||
if (!formEl) return;
|
||||
await formEl.validate((valid) => {
|
||||
if (valid) {
|
||||
dialogVisible.value = false;
|
||||
const data = {
|
||||
userMsg: ruleForm,
|
||||
uid: localStorage.data,
|
||||
};
|
||||
$http.post($url.editUser, data).then((res) => {
|
||||
if (res.data.code === 200) {
|
||||
ElMessage({
|
||||
message: "用户信息修改成功!",
|
||||
type: "success",
|
||||
});
|
||||
emit("resetData");
|
||||
} else {
|
||||
ElMessage.error("用户信息修改失败!");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ElMessage.error("提交失败!");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ dialogVisible, reset });
|
||||
|
||||
watch(ruleForm, (value) => {
|
||||
if (dialogVisible.value) {
|
||||
userManagerActive.dialogVisible = dialogVisible.value;
|
||||
userManagerActive.ruleForm.name = encrypt(value.name);
|
||||
userManagerActive.ruleForm.department = encrypt(value.department);
|
||||
}
|
||||
});
|
||||
|
||||
watch(dialogVisible, (value) => {
|
||||
if (!value) {
|
||||
userManagerActive.dialogVisible = value;
|
||||
userManagerActive.ruleForm = {};
|
||||
}
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
dialogVisible.value = userManagerActive.dialogVisible;
|
||||
if (userManagerActive.dialogVisible) {
|
||||
ruleForm.name = decrypt(userManagerActive.ruleForm.name);
|
||||
ruleForm.department = decrypt(userManagerActive.ruleForm.department);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
29
src/components/operate/addNewData.vue
Normal file
@@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<div class="relative top-0 right-0">
|
||||
<div class="absolute top-0 right-0" style="font-size: 1rem">
|
||||
<el-button
|
||||
style="font-weight: bold"
|
||||
type="primary"
|
||||
size="small"
|
||||
plain
|
||||
@click="showAddForm"
|
||||
>
|
||||
{{ newDataLabel }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
newDataLabel: String
|
||||
});
|
||||
|
||||
const emit = defineEmits(["showAddForm"]);
|
||||
|
||||
const showAddForm = () => {
|
||||
emit("showAddForm");
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
62
src/components/operate/dataShow.vue
Normal file
@@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:show-close="false"
|
||||
style="width: 80%"
|
||||
center
|
||||
align-center
|
||||
>
|
||||
<template #header="{ close, titleId, titleClass }">
|
||||
<div
|
||||
style="font-size: 2rem"
|
||||
class="w-full font-bold"
|
||||
:id="titleId"
|
||||
:class="titleClass"
|
||||
>
|
||||
数据展示
|
||||
</div>
|
||||
<div
|
||||
@click="close"
|
||||
class="bg-gray-400 hover:bg-red-600 text-3xl absolute top-0 right-0 cursor-pointer flex justify-center items-center"
|
||||
>
|
||||
<el-icon>
|
||||
<CloseBold />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<div class="text-center">
|
||||
<el-tag
|
||||
v-for="sn in dialogMsg.split(',')"
|
||||
:key="sn"
|
||||
type="info"
|
||||
class="m-2"
|
||||
effect="dark"
|
||||
>
|
||||
{{ sn }}
|
||||
</el-tag>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button style="font-weight: bold" type="primary" @click="resetForm">
|
||||
返回
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { CloseBold } from "@element-plus/icons-vue";
|
||||
|
||||
const dialogMsg = ref();
|
||||
const dialogVisible = ref(false);
|
||||
|
||||
const resetForm = () => {
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
|
||||
defineExpose({ dialogMsg, dialogVisible });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
119
src/components/operate/formTools.vue
Normal file
@@ -0,0 +1,119 @@
|
||||
<template>
|
||||
<div
|
||||
class="w-full h-8 flex flex-col justify-center items-center relative top-0 right-0"
|
||||
>
|
||||
<div class="absolute top-0 left-0" style="font-size: 1rem">
|
||||
<el-dropdown>
|
||||
<el-button style="font-weight: bold" type="warning" size="small" plain>
|
||||
表单工具
|
||||
<el-icon class="el-icon--right">
|
||||
<arrow-down />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item :style="singleBgColor" @click="showTools('single')">
|
||||
<el-link style="font-weight: bold" :underline="false" type="success">
|
||||
单独导入
|
||||
<el-icon v-show="showSingle" class="el-icon--right">
|
||||
<View />
|
||||
</el-icon>
|
||||
</el-link>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item :style="multipleBgColor" @click="showTools('multiple')">
|
||||
<el-link style="font-weight: bold" :underline="false" type="success">
|
||||
批量导入
|
||||
<el-icon v-show="showMultiple" class="el-icon--right">
|
||||
<View />
|
||||
</el-icon>
|
||||
</el-link>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item :style="excleBgColor" @click="showTools('excle')">
|
||||
<el-link style="font-weight: bold" :underline="false" type="success">
|
||||
excel表格导入
|
||||
<el-icon v-show="showExcle" class="el-icon--right">
|
||||
<View />
|
||||
</el-icon>
|
||||
</el-link>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch, onMounted } from "vue";
|
||||
import { ArrowDown, View } from "@element-plus/icons-vue";
|
||||
|
||||
const showSingle = ref(false);
|
||||
const singleBgColor = ref("background-color: rgba(16, 184, 130, 0.1);");
|
||||
const showMultiple = ref(false);
|
||||
const multipleBgColor = ref("background-color: rgba(16, 184, 130, 0.1);");
|
||||
const showExcle = ref(false);
|
||||
const excleBgColor = ref("background-color: rgba(16, 184, 130, 0.1);");
|
||||
|
||||
const props = defineProps({
|
||||
dialogObj: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["showTools"]);
|
||||
|
||||
const showTools = (operateType) => {
|
||||
switch (operateType) {
|
||||
case "single":
|
||||
emit("showTools", "single");
|
||||
showSingle.value = true;
|
||||
showMultiple.value = false;
|
||||
showExcle.value = false;
|
||||
break;
|
||||
case "multiple":
|
||||
emit("showTools", "multiple");
|
||||
showSingle.value = false;
|
||||
showMultiple.value = true;
|
||||
showExcle.value = false;
|
||||
break;
|
||||
case "excle":
|
||||
emit("showTools", "excle");
|
||||
showSingle.value = false;
|
||||
showMultiple.value = false;
|
||||
showExcle.value = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
watch(showSingle, (value) => {
|
||||
if (value) {
|
||||
singleBgColor.value = "background-color: rgba(16, 184, 130, 0.2);";
|
||||
} else {
|
||||
singleBgColor.value = "background-color: rgba(16, 184, 130, 0.1);";
|
||||
}
|
||||
});
|
||||
|
||||
watch(showMultiple, (value) => {
|
||||
if (value) {
|
||||
multipleBgColor.value = "background-color: rgba(16, 184, 130, 0.2);";
|
||||
} else {
|
||||
multipleBgColor.value = "background-color: rgba(16, 184, 130, 0.1);";
|
||||
}
|
||||
});
|
||||
|
||||
watch(showExcle, (value) => {
|
||||
if (value) {
|
||||
excleBgColor.value = "background-color: rgba(16, 184, 130, 0.2);";
|
||||
} else {
|
||||
excleBgColor.value = "background-color: rgba(16, 184, 130, 0.1);";
|
||||
}
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
showSingle.value = props.dialogObj.dialogSingleVisible;
|
||||
showMultiple.value = props.dialogObj.dialogMultipleVisible;
|
||||
showExcle.value = props.dialogObj.dialogExcleVisible;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||