仓库初始化
This commit is contained in:
commit
a5f9731177
|
@ -0,0 +1,11 @@
|
||||||
|
VITE_APP_NAME=超级后台
|
||||||
|
VITE_APP_ENV=development
|
||||||
|
VITE_APP_PORT=1000
|
||||||
|
VITE_DROP_CONSOLE=false
|
||||||
|
|
||||||
|
# axios
|
||||||
|
VITE_APP_BASE_API=/api
|
||||||
|
VITE_APP_PROXY_URL=http://localhost:8765
|
||||||
|
|
||||||
|
# rsa 公钥
|
||||||
|
VITE_APP_RSA_PUBLIC_KEY=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJps/EXxxSpEM1Ix4R0NWIOBciHCr7P7coDT8tNKfelgR7txcJOqHCO/MIWe7T04aHQTcpQxqx9hMca7dbqz8TZpz9jvLzE/6ZonVKxHsoFnNlHMp1/CPAJ9f6D9wYicum2KltJkmQ0g//D9W2zPCYoGOmSRFcZx/KEBa4EM53jQIDAQAB
|
|
@ -0,0 +1,8 @@
|
||||||
|
VITE_APP_NAME=超级后台
|
||||||
|
VITE_APP_ENV=production
|
||||||
|
VITE_APP_PORT=1001
|
||||||
|
VITE_DROP_CONSOLE=true
|
||||||
|
|
||||||
|
# axios
|
||||||
|
VITE_APP_BASE_API=/api
|
||||||
|
VITE_APP_PROXY_URL=https://172.10.10.238:8765
|
|
@ -0,0 +1,24 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"recommendations": ["Vue.volar"]
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
# Vue 3 + TypeScript + Vite
|
||||||
|
|
||||||
|
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
||||||
|
|
||||||
|
Learn more about the recommended Project Setup and IDE Support in the [Vue Docs TypeScript Guide](https://vuejs.org/guide/typescript/overview.html#project-setup).
|
|
@ -0,0 +1,15 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8"/>
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/vite.svg"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
<script type="module" src="/src/assets/iconfont/iconfont.js"></script>
|
||||||
|
|
||||||
|
<title>Vite + Vue + TS</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.ts"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
"name": "supermanagement",
|
||||||
|
"appName": "超级后台",
|
||||||
|
"private": true,
|
||||||
|
"version": "1.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vue-tsc -b && vite build",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ant-design-vue": "^4.2.3",
|
||||||
|
"axios": "^1.7.5",
|
||||||
|
"jsencrypt": "^3.3.2",
|
||||||
|
"pinia": "^2.2.2",
|
||||||
|
"pinia-plugin-persistedstate": "^3.2.0",
|
||||||
|
"sass": "^1.77.8",
|
||||||
|
"vue": "^3.4.37",
|
||||||
|
"vue-router": "4"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^22.5.1",
|
||||||
|
"@vitejs/plugin-vue": "^5.1.2",
|
||||||
|
"@vitejs/plugin-vue-jsx": "^4.0.1",
|
||||||
|
"typescript": "^5.5.3",
|
||||||
|
"unplugin-vue-components": "^0.27.4",
|
||||||
|
"vite": "^5.4.1",
|
||||||
|
"vue-tsc": "^2.0.29"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
After Width: | Height: | Size: 1.5 KiB |
|
@ -0,0 +1,22 @@
|
||||||
|
<template>
|
||||||
|
<a-config-provider :locale="zhCN">
|
||||||
|
<a-app>
|
||||||
|
<a-spin :spinning="false" style="z-index: 1001" :tip="''">
|
||||||
|
<router-view></router-view>
|
||||||
|
</a-spin>
|
||||||
|
</a-app>
|
||||||
|
</a-config-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import zhCN from 'ant-design-vue/es/locale/zh_CN';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import 'dayjs/locale/zh-cn';
|
||||||
|
import {App as AApp} from 'ant-design-vue'
|
||||||
|
|
||||||
|
dayjs.locale('zh-cn');
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
|
@ -0,0 +1,539 @@
|
||||||
|
/* Logo 字体 */
|
||||||
|
@font-face {
|
||||||
|
font-family: "iconfont logo";
|
||||||
|
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
|
||||||
|
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
|
||||||
|
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
|
||||||
|
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
|
||||||
|
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
font-family: "iconfont logo";
|
||||||
|
font-size: 160px;
|
||||||
|
font-style: normal;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tabs */
|
||||||
|
.nav-tabs {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tabs .nav-more {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
height: 42px;
|
||||||
|
line-height: 42px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tabs {
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tabs li {
|
||||||
|
cursor: pointer;
|
||||||
|
width: 100px;
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 16px;
|
||||||
|
border-bottom: 2px solid transparent;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
margin-bottom: -1px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#tabs .active {
|
||||||
|
border-bottom-color: #f00;
|
||||||
|
color: #222;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-container .content {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 页面布局 */
|
||||||
|
.main {
|
||||||
|
padding: 30px 100px;
|
||||||
|
width: 960px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main .logo {
|
||||||
|
color: #333;
|
||||||
|
text-align: left;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
line-height: 1;
|
||||||
|
height: 110px;
|
||||||
|
margin-top: -50px;
|
||||||
|
overflow: hidden;
|
||||||
|
*zoom: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main .logo a {
|
||||||
|
font-size: 160px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.helps {
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.helps pre {
|
||||||
|
padding: 20px;
|
||||||
|
margin: 10px 0;
|
||||||
|
border: solid 1px #e7e1cd;
|
||||||
|
background-color: #fffdef;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon_lists {
|
||||||
|
width: 100% !important;
|
||||||
|
overflow: hidden;
|
||||||
|
*zoom: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon_lists li {
|
||||||
|
width: 100px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
margin-right: 20px;
|
||||||
|
text-align: center;
|
||||||
|
list-style: none !important;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon_lists li .code-name {
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon_lists .icon {
|
||||||
|
display: block;
|
||||||
|
height: 100px;
|
||||||
|
line-height: 100px;
|
||||||
|
font-size: 42px;
|
||||||
|
margin: 10px auto;
|
||||||
|
color: #333;
|
||||||
|
-webkit-transition: font-size 0.25s linear, width 0.25s linear;
|
||||||
|
-moz-transition: font-size 0.25s linear, width 0.25s linear;
|
||||||
|
transition: font-size 0.25s linear, width 0.25s linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon_lists .icon:hover {
|
||||||
|
font-size: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon_lists .svg-icon {
|
||||||
|
/* 通过设置 font-size 来改变图标大小 */
|
||||||
|
width: 1em;
|
||||||
|
/* 图标和文字相邻时,垂直对齐 */
|
||||||
|
vertical-align: -0.15em;
|
||||||
|
/* 通过设置 color 来改变 SVG 的颜色/fill */
|
||||||
|
fill: currentColor;
|
||||||
|
/* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
|
||||||
|
normalize.css 中也包含这行 */
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon_lists li .name,
|
||||||
|
.icon_lists li .code-name {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* markdown 样式 */
|
||||||
|
.markdown {
|
||||||
|
color: #666;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.highlight {
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown img {
|
||||||
|
vertical-align: middle;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown h1 {
|
||||||
|
color: #404040;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 40px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown h2,
|
||||||
|
.markdown h3,
|
||||||
|
.markdown h4,
|
||||||
|
.markdown h5,
|
||||||
|
.markdown h6 {
|
||||||
|
color: #404040;
|
||||||
|
margin: 1.6em 0 0.6em 0;
|
||||||
|
font-weight: 500;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown h1 {
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown h2 {
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown h3 {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown h4 {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown h5 {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown h6 {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown hr {
|
||||||
|
height: 1px;
|
||||||
|
border: 0;
|
||||||
|
background: #e9e9e9;
|
||||||
|
margin: 16px 0;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown p {
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown>p,
|
||||||
|
.markdown>blockquote,
|
||||||
|
.markdown>.highlight,
|
||||||
|
.markdown>ol,
|
||||||
|
.markdown>ul {
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown ul>li {
|
||||||
|
list-style: circle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown>ul li,
|
||||||
|
.markdown blockquote ul>li {
|
||||||
|
margin-left: 20px;
|
||||||
|
padding-left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown>ul li p,
|
||||||
|
.markdown>ol li p {
|
||||||
|
margin: 0.6em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown ol>li {
|
||||||
|
list-style: decimal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown>ol li,
|
||||||
|
.markdown blockquote ol>li {
|
||||||
|
margin-left: 20px;
|
||||||
|
padding-left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown code {
|
||||||
|
margin: 0 3px;
|
||||||
|
padding: 0 5px;
|
||||||
|
background: #eee;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown strong,
|
||||||
|
.markdown b {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown>table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0px;
|
||||||
|
empty-cells: show;
|
||||||
|
border: 1px solid #e9e9e9;
|
||||||
|
width: 95%;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown>table th {
|
||||||
|
white-space: nowrap;
|
||||||
|
color: #333;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown>table th,
|
||||||
|
.markdown>table td {
|
||||||
|
border: 1px solid #e9e9e9;
|
||||||
|
padding: 8px 16px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown>table th {
|
||||||
|
background: #F7F7F7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown blockquote {
|
||||||
|
font-size: 90%;
|
||||||
|
color: #999;
|
||||||
|
border-left: 4px solid #e9e9e9;
|
||||||
|
padding-left: 0.8em;
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown blockquote p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown .anchor {
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s ease;
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown .waiting {
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown h1:hover .anchor,
|
||||||
|
.markdown h2:hover .anchor,
|
||||||
|
.markdown h3:hover .anchor,
|
||||||
|
.markdown h4:hover .anchor,
|
||||||
|
.markdown h5:hover .anchor,
|
||||||
|
.markdown h6:hover .anchor {
|
||||||
|
opacity: 1;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown>br,
|
||||||
|
.markdown>p>br {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.hljs {
|
||||||
|
display: block;
|
||||||
|
background: white;
|
||||||
|
padding: 0.5em;
|
||||||
|
color: #333333;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-comment,
|
||||||
|
.hljs-meta {
|
||||||
|
color: #969896;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-string,
|
||||||
|
.hljs-variable,
|
||||||
|
.hljs-template-variable,
|
||||||
|
.hljs-strong,
|
||||||
|
.hljs-emphasis,
|
||||||
|
.hljs-quote {
|
||||||
|
color: #df5000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-keyword,
|
||||||
|
.hljs-selector-tag,
|
||||||
|
.hljs-type {
|
||||||
|
color: #a71d5d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-literal,
|
||||||
|
.hljs-symbol,
|
||||||
|
.hljs-bullet,
|
||||||
|
.hljs-attribute {
|
||||||
|
color: #0086b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-section,
|
||||||
|
.hljs-name {
|
||||||
|
color: #63a35c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-tag {
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-title,
|
||||||
|
.hljs-attr,
|
||||||
|
.hljs-selector-id,
|
||||||
|
.hljs-selector-class,
|
||||||
|
.hljs-selector-attr,
|
||||||
|
.hljs-selector-pseudo {
|
||||||
|
color: #795da3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-addition {
|
||||||
|
color: #55a532;
|
||||||
|
background-color: #eaffea;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-deletion {
|
||||||
|
color: #bd2c00;
|
||||||
|
background-color: #ffecec;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-link {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 代码高亮 */
|
||||||
|
/* PrismJS 1.15.0
|
||||||
|
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
|
||||||
|
/**
|
||||||
|
* prism.js default theme for JavaScript, CSS and HTML
|
||||||
|
* Based on dabblet (http://dabblet.com)
|
||||||
|
* @author Lea Verou
|
||||||
|
*/
|
||||||
|
code[class*="language-"],
|
||||||
|
pre[class*="language-"] {
|
||||||
|
color: black;
|
||||||
|
background: none;
|
||||||
|
text-shadow: 0 1px white;
|
||||||
|
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||||
|
text-align: left;
|
||||||
|
white-space: pre;
|
||||||
|
word-spacing: normal;
|
||||||
|
word-break: normal;
|
||||||
|
word-wrap: normal;
|
||||||
|
line-height: 1.5;
|
||||||
|
|
||||||
|
-moz-tab-size: 4;
|
||||||
|
-o-tab-size: 4;
|
||||||
|
tab-size: 4;
|
||||||
|
|
||||||
|
-webkit-hyphens: none;
|
||||||
|
-moz-hyphens: none;
|
||||||
|
-ms-hyphens: none;
|
||||||
|
hyphens: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre[class*="language-"]::-moz-selection,
|
||||||
|
pre[class*="language-"] ::-moz-selection,
|
||||||
|
code[class*="language-"]::-moz-selection,
|
||||||
|
code[class*="language-"] ::-moz-selection {
|
||||||
|
text-shadow: none;
|
||||||
|
background: #b3d4fc;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre[class*="language-"]::selection,
|
||||||
|
pre[class*="language-"] ::selection,
|
||||||
|
code[class*="language-"]::selection,
|
||||||
|
code[class*="language-"] ::selection {
|
||||||
|
text-shadow: none;
|
||||||
|
background: #b3d4fc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
|
||||||
|
code[class*="language-"],
|
||||||
|
pre[class*="language-"] {
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Code blocks */
|
||||||
|
pre[class*="language-"] {
|
||||||
|
padding: 1em;
|
||||||
|
margin: .5em 0;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
:not(pre)>code[class*="language-"],
|
||||||
|
pre[class*="language-"] {
|
||||||
|
background: #f5f2f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inline code */
|
||||||
|
:not(pre)>code[class*="language-"] {
|
||||||
|
padding: .1em;
|
||||||
|
border-radius: .3em;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.comment,
|
||||||
|
.token.prolog,
|
||||||
|
.token.doctype,
|
||||||
|
.token.cdata {
|
||||||
|
color: slategray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.punctuation {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.namespace {
|
||||||
|
opacity: .7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.property,
|
||||||
|
.token.tag,
|
||||||
|
.token.boolean,
|
||||||
|
.token.number,
|
||||||
|
.token.constant,
|
||||||
|
.token.symbol,
|
||||||
|
.token.deleted {
|
||||||
|
color: #905;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.selector,
|
||||||
|
.token.attr-name,
|
||||||
|
.token.string,
|
||||||
|
.token.char,
|
||||||
|
.token.builtin,
|
||||||
|
.token.inserted {
|
||||||
|
color: #690;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.operator,
|
||||||
|
.token.entity,
|
||||||
|
.token.url,
|
||||||
|
.language-css .token.string,
|
||||||
|
.style .token.string {
|
||||||
|
color: #9a6e3a;
|
||||||
|
background: hsla(0, 0%, 100%, .5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.atrule,
|
||||||
|
.token.attr-value,
|
||||||
|
.token.keyword {
|
||||||
|
color: #07a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.function,
|
||||||
|
.token.class-name {
|
||||||
|
color: #DD4A68;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.regex,
|
||||||
|
.token.important,
|
||||||
|
.token.variable {
|
||||||
|
color: #e90;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.important,
|
||||||
|
.token.bold {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.italic {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.entity {
|
||||||
|
cursor: help;
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -0,0 +1,399 @@
|
||||||
|
@font-face {
|
||||||
|
font-family: "iconfont"; /* Project id 4036849 */
|
||||||
|
src: url('iconfont.woff2?t=1723194854588') format('woff2'),
|
||||||
|
url('iconfont.woff?t=1723194854588') format('woff'),
|
||||||
|
url('iconfont.ttf?t=1723194854588') format('truetype');
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconfont {
|
||||||
|
font-family: "iconfont" !important;
|
||||||
|
font-size: 16px;
|
||||||
|
font-style: normal;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-daxiaochilun:before {
|
||||||
|
content: "\e6d0";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-quanping:before {
|
||||||
|
content: "\e67d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-sousuo1:before {
|
||||||
|
content: "\e628";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-xiaoxitongzhi:before {
|
||||||
|
content: "\eaf8";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-tuichuquanping:before {
|
||||||
|
content: "\e6db";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-tianjia:before {
|
||||||
|
content: "\e695";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-bianji1:before {
|
||||||
|
content: "\10117";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-grid:before {
|
||||||
|
content: "\e8e4";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-ic_batch:before {
|
||||||
|
content: "\e739";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-shanchu:before {
|
||||||
|
content: "\fcb6";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-qita1:before {
|
||||||
|
content: "\e602";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-quanbu:before {
|
||||||
|
content: "\e745";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-yinpin:before {
|
||||||
|
content: "\e603";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-wendang:before {
|
||||||
|
content: "\e60e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-tupian:before {
|
||||||
|
content: "\e606";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-shipin:before {
|
||||||
|
content: "\fb3c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-a-041_wendang:before {
|
||||||
|
content: "\e6da";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-guanlianbaoan:before {
|
||||||
|
content: "\e600";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-baoanxiaofang:before {
|
||||||
|
content: "\e613";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-youjiantou:before {
|
||||||
|
content: "\e60c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-zuojiantou:before {
|
||||||
|
content: "\e60d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-lingdang:before {
|
||||||
|
content: "\e649";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-wenjianjia:before {
|
||||||
|
content: "\e662";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-caidan1:before {
|
||||||
|
content: "\e626";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-a-ziyuan4:before {
|
||||||
|
content: "\e669";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-zichanguanli:before {
|
||||||
|
content: "\e62e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-fix:before {
|
||||||
|
content: "\e9b9";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-wenzidaxiao2:before {
|
||||||
|
content: "\e854";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-zhuanyi03:before {
|
||||||
|
content: "\ea34";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-wxbpinpaibao:before {
|
||||||
|
content: "\e620";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-chanpinku:before {
|
||||||
|
content: "\e65f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-gongyingshangzhifu:before {
|
||||||
|
content: "\e618";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-kehu:before {
|
||||||
|
content: "\e6d2";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-jinxiaocun:before {
|
||||||
|
content: "\e61f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-xiangmuguanli-:before {
|
||||||
|
content: "\e609";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-exe:before {
|
||||||
|
content: "\e63a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-mp4:before {
|
||||||
|
content: "\e639";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-zhutushipin:before {
|
||||||
|
content: "\e612";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-weizhiwenjian:before {
|
||||||
|
content: "\e61a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-Jpg:before {
|
||||||
|
content: "\e731";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-Pdf:before {
|
||||||
|
content: "\e733";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-svgtubiao:before {
|
||||||
|
content: "\e650";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-doc:before {
|
||||||
|
content: "\e735";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-gif:before {
|
||||||
|
content: "\e6a4";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-JPEG:before {
|
||||||
|
content: "\e66d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-DOCX:before {
|
||||||
|
content: "\e672";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-XLS:before {
|
||||||
|
content: "\e673";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-XLSX:before {
|
||||||
|
content: "\e674";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-PNG:before {
|
||||||
|
content: "\e69f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-shangchuanwenjian:before {
|
||||||
|
content: "\e652";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-24gl-folderPlus:before {
|
||||||
|
content: "\eabe";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-019shanchuwenjian:before {
|
||||||
|
content: "\e7e5";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-xiazaiwenjian:before {
|
||||||
|
content: "\e615";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-3333:before {
|
||||||
|
content: "\e680";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-shijianchaxun-yimidida-:before {
|
||||||
|
content: "\e64d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-wenjian:before {
|
||||||
|
content: "\e62b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-xitong1:before {
|
||||||
|
content: "\e67c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-danwei:before {
|
||||||
|
content: "\e611";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-policeman-full:before {
|
||||||
|
content: "\e8f1";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-mysql:before {
|
||||||
|
content: "\e667";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-RabbitMQ:before {
|
||||||
|
content: "\e6a0";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-duanluqi:before {
|
||||||
|
content: "\e60a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-baimingdan:before {
|
||||||
|
content: "\e643";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-VPNwangguan:before {
|
||||||
|
content: "\e7da";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-kaifazhezhongxin:before {
|
||||||
|
content: "\e70f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-kongzhitai:before {
|
||||||
|
content: "\e651";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-baidu:before {
|
||||||
|
content: "\e8cb";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-waibulianjie:before {
|
||||||
|
content: "\e858";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-zidianguanli:before {
|
||||||
|
content: "\e625";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-shujukaifajiaobenkaifa:before {
|
||||||
|
content: "\e65c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-chanpin:before {
|
||||||
|
content: "\e64f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-xiaoshou:before {
|
||||||
|
content: "\e624";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-ceshi:before {
|
||||||
|
content: "\e853";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-zhuanshujingli:before {
|
||||||
|
content: "\e883";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-gongsi:before {
|
||||||
|
content: "\e679";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-xitongquanxian:before {
|
||||||
|
content: "\e61e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-rizhi:before {
|
||||||
|
content: "\e647";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-yonghuguanli_huaban:before {
|
||||||
|
content: "\e62d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-dingshirenwu:before {
|
||||||
|
content: "\e6a3";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-dashboard:before {
|
||||||
|
content: "\e78b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-caidan:before {
|
||||||
|
content: "\e65d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-bumenguanli:before {
|
||||||
|
content: "\e61d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-jiaoseguanli:before {
|
||||||
|
content: "\e621";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-xitong:before {
|
||||||
|
content: "\e601";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-shouye:before {
|
||||||
|
content: "\e8b9";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-guanyu:before {
|
||||||
|
content: "\e623";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-DVLINK_daping:before {
|
||||||
|
content: "\e627";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-weixin:before {
|
||||||
|
content: "\e656";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-QQ:before {
|
||||||
|
content: "\e882";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-contentright:before {
|
||||||
|
content: "\e67a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-zhuti:before {
|
||||||
|
content: "\e610";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-sousuo:before {
|
||||||
|
content: "\e68a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-xiaoxi:before {
|
||||||
|
content: "\e8be";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-zhongyingwen:before {
|
||||||
|
content: "\e605";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-fangda:before {
|
||||||
|
content: "\e622";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-suoxiao:before {
|
||||||
|
content: "\e62a";
|
||||||
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,681 @@
|
||||||
|
{
|
||||||
|
"id": "4036849",
|
||||||
|
"name": "luozhun",
|
||||||
|
"font_family": "iconfont",
|
||||||
|
"css_prefix_text": "icon-",
|
||||||
|
"description": "",
|
||||||
|
"glyphs": [
|
||||||
|
{
|
||||||
|
"icon_id": "8959587",
|
||||||
|
"name": "大小齿轮",
|
||||||
|
"font_class": "daxiaochilun",
|
||||||
|
"unicode": "e6d0",
|
||||||
|
"unicode_decimal": 59088
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "23875177",
|
||||||
|
"name": "全屏",
|
||||||
|
"font_class": "quanping",
|
||||||
|
"unicode": "e67d",
|
||||||
|
"unicode_decimal": 59005
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "25840027",
|
||||||
|
"name": "搜索",
|
||||||
|
"font_class": "sousuo1",
|
||||||
|
"unicode": "e628",
|
||||||
|
"unicode_decimal": 58920
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "29312195",
|
||||||
|
"name": "消息通知",
|
||||||
|
"font_class": "xiaoxitongzhi",
|
||||||
|
"unicode": "eaf8",
|
||||||
|
"unicode_decimal": 60152
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "37425403",
|
||||||
|
"name": "退出全屏",
|
||||||
|
"font_class": "tuichuquanping",
|
||||||
|
"unicode": "e6db",
|
||||||
|
"unicode_decimal": 59099
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "12188081",
|
||||||
|
"name": "添加",
|
||||||
|
"font_class": "tianjia",
|
||||||
|
"unicode": "e695",
|
||||||
|
"unicode_decimal": 59029
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "34882873",
|
||||||
|
"name": "编辑",
|
||||||
|
"font_class": "bianji1",
|
||||||
|
"unicode": "10117",
|
||||||
|
"unicode_decimal": 65815
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "924384",
|
||||||
|
"name": "grid",
|
||||||
|
"font_class": "grid",
|
||||||
|
"unicode": "e8e4",
|
||||||
|
"unicode_decimal": 59620
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "25944286",
|
||||||
|
"name": "ic_batch",
|
||||||
|
"font_class": "ic_batch",
|
||||||
|
"unicode": "e739",
|
||||||
|
"unicode_decimal": 59193
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "24473117",
|
||||||
|
"name": "删除",
|
||||||
|
"font_class": "shanchu",
|
||||||
|
"unicode": "fcb6",
|
||||||
|
"unicode_decimal": 64694
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7632835",
|
||||||
|
"name": "其他",
|
||||||
|
"font_class": "qita1",
|
||||||
|
"unicode": "e602",
|
||||||
|
"unicode_decimal": 58882
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "11412028",
|
||||||
|
"name": "全部",
|
||||||
|
"font_class": "quanbu",
|
||||||
|
"unicode": "e745",
|
||||||
|
"unicode_decimal": 59205
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "12085836",
|
||||||
|
"name": "音频",
|
||||||
|
"font_class": "yinpin",
|
||||||
|
"unicode": "e603",
|
||||||
|
"unicode_decimal": 58883
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "15173237",
|
||||||
|
"name": "文档",
|
||||||
|
"font_class": "wendang",
|
||||||
|
"unicode": "e60e",
|
||||||
|
"unicode_decimal": 58894
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "24110222",
|
||||||
|
"name": "图片",
|
||||||
|
"font_class": "tupian",
|
||||||
|
"unicode": "e606",
|
||||||
|
"unicode_decimal": 58886
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "24111668",
|
||||||
|
"name": "视频",
|
||||||
|
"font_class": "shipin",
|
||||||
|
"unicode": "fb3c",
|
||||||
|
"unicode_decimal": 64316
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "38945085",
|
||||||
|
"name": "041_文档",
|
||||||
|
"font_class": "a-041_wendang",
|
||||||
|
"unicode": "e6da",
|
||||||
|
"unicode_decimal": 59098
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "2667175",
|
||||||
|
"name": "关联保安",
|
||||||
|
"font_class": "guanlianbaoan",
|
||||||
|
"unicode": "e600",
|
||||||
|
"unicode_decimal": 58880
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "12156012",
|
||||||
|
"name": "保安消防",
|
||||||
|
"font_class": "baoanxiaofang",
|
||||||
|
"unicode": "e613",
|
||||||
|
"unicode_decimal": 58899
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7587762",
|
||||||
|
"name": "右箭头",
|
||||||
|
"font_class": "youjiantou",
|
||||||
|
"unicode": "e60c",
|
||||||
|
"unicode_decimal": 58892
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7587767",
|
||||||
|
"name": "左箭头",
|
||||||
|
"font_class": "zuojiantou",
|
||||||
|
"unicode": "e60d",
|
||||||
|
"unicode_decimal": 58893
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "2234525",
|
||||||
|
"name": "铃铛",
|
||||||
|
"font_class": "lingdang",
|
||||||
|
"unicode": "e649",
|
||||||
|
"unicode_decimal": 58953
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "1301378",
|
||||||
|
"name": "文件夹",
|
||||||
|
"font_class": "wenjianjia",
|
||||||
|
"unicode": "e662",
|
||||||
|
"unicode_decimal": 58978
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "10333707",
|
||||||
|
"name": "菜单",
|
||||||
|
"font_class": "caidan1",
|
||||||
|
"unicode": "e626",
|
||||||
|
"unicode_decimal": 58918
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "27157318",
|
||||||
|
"name": "按钮",
|
||||||
|
"font_class": "a-ziyuan4",
|
||||||
|
"unicode": "e669",
|
||||||
|
"unicode_decimal": 58985
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "6241686",
|
||||||
|
"name": "资产管理",
|
||||||
|
"font_class": "zichanguanli",
|
||||||
|
"unicode": "e62e",
|
||||||
|
"unicode_decimal": 58926
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "18170419",
|
||||||
|
"name": "解除固定,图钉",
|
||||||
|
"font_class": "fix",
|
||||||
|
"unicode": "e9b9",
|
||||||
|
"unicode_decimal": 59833
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "34198298",
|
||||||
|
"name": "文字大小2",
|
||||||
|
"font_class": "wenzidaxiao2",
|
||||||
|
"unicode": "e854",
|
||||||
|
"unicode_decimal": 59476
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "35102495",
|
||||||
|
"name": "转移03",
|
||||||
|
"font_class": "zhuanyi03",
|
||||||
|
"unicode": "ea34",
|
||||||
|
"unicode_decimal": 59956
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "591724",
|
||||||
|
"name": "wxb品牌宝",
|
||||||
|
"font_class": "wxbpinpaibao",
|
||||||
|
"unicode": "e620",
|
||||||
|
"unicode_decimal": 58912
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "1680680",
|
||||||
|
"name": "产品库",
|
||||||
|
"font_class": "chanpinku",
|
||||||
|
"unicode": "e65f",
|
||||||
|
"unicode_decimal": 58975
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "1964103",
|
||||||
|
"name": "供应商支付",
|
||||||
|
"font_class": "gongyingshangzhifu",
|
||||||
|
"unicode": "e618",
|
||||||
|
"unicode_decimal": 58904
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "9874502",
|
||||||
|
"name": "KHCFDC_客户",
|
||||||
|
"font_class": "kehu",
|
||||||
|
"unicode": "e6d2",
|
||||||
|
"unicode_decimal": 59090
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "31313005",
|
||||||
|
"name": "进销存",
|
||||||
|
"font_class": "jinxiaocun",
|
||||||
|
"unicode": "e61f",
|
||||||
|
"unicode_decimal": 58911
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "4657688",
|
||||||
|
"name": "项目管理",
|
||||||
|
"font_class": "xiangmuguanli-",
|
||||||
|
"unicode": "e609",
|
||||||
|
"unicode_decimal": 58889
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "31260962",
|
||||||
|
"name": "exe",
|
||||||
|
"font_class": "exe",
|
||||||
|
"unicode": "e63a",
|
||||||
|
"unicode_decimal": 58938
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "31260975",
|
||||||
|
"name": "mp4",
|
||||||
|
"font_class": "mp4",
|
||||||
|
"unicode": "e639",
|
||||||
|
"unicode_decimal": 58937
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "22325375",
|
||||||
|
"name": "主图视频",
|
||||||
|
"font_class": "zhutushipin",
|
||||||
|
"unicode": "e612",
|
||||||
|
"unicode_decimal": 58898
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "19145266",
|
||||||
|
"name": "未知文件",
|
||||||
|
"font_class": "weizhiwenjian",
|
||||||
|
"unicode": "e61a",
|
||||||
|
"unicode_decimal": 58906
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "6376407",
|
||||||
|
"name": "Jpg",
|
||||||
|
"font_class": "Jpg",
|
||||||
|
"unicode": "e731",
|
||||||
|
"unicode_decimal": 59185
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "6376410",
|
||||||
|
"name": "Pdf",
|
||||||
|
"font_class": "Pdf",
|
||||||
|
"unicode": "e733",
|
||||||
|
"unicode_decimal": 59187
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "6441713",
|
||||||
|
"name": "svg图标",
|
||||||
|
"font_class": "svgtubiao",
|
||||||
|
"unicode": "e650",
|
||||||
|
"unicode_decimal": 58960
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "6472244",
|
||||||
|
"name": "doc",
|
||||||
|
"font_class": "doc",
|
||||||
|
"unicode": "e735",
|
||||||
|
"unicode_decimal": 59189
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "17290933",
|
||||||
|
"name": "gif",
|
||||||
|
"font_class": "gif",
|
||||||
|
"unicode": "e6a4",
|
||||||
|
"unicode_decimal": 59044
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "22007985",
|
||||||
|
"name": "JPEG",
|
||||||
|
"font_class": "JPEG",
|
||||||
|
"unicode": "e66d",
|
||||||
|
"unicode_decimal": 58989
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "22008512",
|
||||||
|
"name": "DOCX",
|
||||||
|
"font_class": "DOCX",
|
||||||
|
"unicode": "e672",
|
||||||
|
"unicode_decimal": 58994
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "22008667",
|
||||||
|
"name": "XLS",
|
||||||
|
"font_class": "XLS",
|
||||||
|
"unicode": "e673",
|
||||||
|
"unicode_decimal": 58995
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "22008680",
|
||||||
|
"name": "XLSX",
|
||||||
|
"font_class": "XLSX",
|
||||||
|
"unicode": "e674",
|
||||||
|
"unicode_decimal": 58996
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "23182868",
|
||||||
|
"name": "PNG",
|
||||||
|
"font_class": "PNG",
|
||||||
|
"unicode": "e69f",
|
||||||
|
"unicode_decimal": 59039
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "567560",
|
||||||
|
"name": "上传文件",
|
||||||
|
"font_class": "shangchuanwenjian",
|
||||||
|
"unicode": "e652",
|
||||||
|
"unicode_decimal": 58962
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7594807",
|
||||||
|
"name": "24gl-folderPlus",
|
||||||
|
"font_class": "24gl-folderPlus",
|
||||||
|
"unicode": "eabe",
|
||||||
|
"unicode_decimal": 60094
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "15816428",
|
||||||
|
"name": "019删除文件",
|
||||||
|
"font_class": "019shanchuwenjian",
|
||||||
|
"unicode": "e7e5",
|
||||||
|
"unicode_decimal": 59365
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "27438098",
|
||||||
|
"name": "下载文件",
|
||||||
|
"font_class": "xiazaiwenjian",
|
||||||
|
"unicode": "e615",
|
||||||
|
"unicode_decimal": 58901
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "406256",
|
||||||
|
"name": "私人文件夹",
|
||||||
|
"font_class": "3333",
|
||||||
|
"unicode": "e680",
|
||||||
|
"unicode_decimal": 59008
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "11472722",
|
||||||
|
"name": "事件查询-壹米滴答-01",
|
||||||
|
"font_class": "shijianchaxun-yimidida-",
|
||||||
|
"unicode": "e64d",
|
||||||
|
"unicode_decimal": 58957
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "21193294",
|
||||||
|
"name": "文件",
|
||||||
|
"font_class": "wenjian",
|
||||||
|
"unicode": "e62b",
|
||||||
|
"unicode_decimal": 58923
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "1137788",
|
||||||
|
"name": "系统",
|
||||||
|
"font_class": "xitong1",
|
||||||
|
"unicode": "e67c",
|
||||||
|
"unicode_decimal": 59004
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "5650859",
|
||||||
|
"name": "单位",
|
||||||
|
"font_class": "danwei",
|
||||||
|
"unicode": "e611",
|
||||||
|
"unicode_decimal": 58897
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "18167099",
|
||||||
|
"name": "警察半身,公安",
|
||||||
|
"font_class": "policeman-full",
|
||||||
|
"unicode": "e8f1",
|
||||||
|
"unicode_decimal": 59633
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "3876471",
|
||||||
|
"name": "mysql",
|
||||||
|
"font_class": "mysql",
|
||||||
|
"unicode": "e667",
|
||||||
|
"unicode_decimal": 58983
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "3172487",
|
||||||
|
"name": "RabbitMQ",
|
||||||
|
"font_class": "RabbitMQ",
|
||||||
|
"unicode": "e6a0",
|
||||||
|
"unicode_decimal": 59040
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "18337193",
|
||||||
|
"name": "断路器",
|
||||||
|
"font_class": "duanluqi",
|
||||||
|
"unicode": "e60a",
|
||||||
|
"unicode_decimal": 58890
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "29328030",
|
||||||
|
"name": "白名单",
|
||||||
|
"font_class": "baimingdan",
|
||||||
|
"unicode": "e643",
|
||||||
|
"unicode_decimal": 58947
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "10055646",
|
||||||
|
"name": "VPN网关",
|
||||||
|
"font_class": "VPNwangguan",
|
||||||
|
"unicode": "e7da",
|
||||||
|
"unicode_decimal": 59354
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "1259944",
|
||||||
|
"name": "开发者中心",
|
||||||
|
"font_class": "kaifazhezhongxin",
|
||||||
|
"unicode": "e70f",
|
||||||
|
"unicode_decimal": 59151
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "12975229",
|
||||||
|
"name": "控制台",
|
||||||
|
"font_class": "kongzhitai",
|
||||||
|
"unicode": "e651",
|
||||||
|
"unicode_decimal": 58961
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "18166606",
|
||||||
|
"name": "百度",
|
||||||
|
"font_class": "baidu",
|
||||||
|
"unicode": "e8cb",
|
||||||
|
"unicode_decimal": 59595
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "34201231",
|
||||||
|
"name": "外部链接 ",
|
||||||
|
"font_class": "waibulianjie",
|
||||||
|
"unicode": "e858",
|
||||||
|
"unicode_decimal": 59480
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "5434087",
|
||||||
|
"name": "字典管理",
|
||||||
|
"font_class": "zidianguanli",
|
||||||
|
"unicode": "e625",
|
||||||
|
"unicode_decimal": 58917
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "4773266",
|
||||||
|
"name": "数据开发—脚本开发",
|
||||||
|
"font_class": "shujukaifajiaobenkaifa",
|
||||||
|
"unicode": "e65c",
|
||||||
|
"unicode_decimal": 58972
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "5121534",
|
||||||
|
"name": "产品",
|
||||||
|
"font_class": "chanpin",
|
||||||
|
"unicode": "e64f",
|
||||||
|
"unicode_decimal": 58959
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "11641886",
|
||||||
|
"name": "销售",
|
||||||
|
"font_class": "xiaoshou",
|
||||||
|
"unicode": "e624",
|
||||||
|
"unicode_decimal": 58916
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "16398952",
|
||||||
|
"name": "测试",
|
||||||
|
"font_class": "ceshi",
|
||||||
|
"unicode": "e853",
|
||||||
|
"unicode_decimal": 59475
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "34453374",
|
||||||
|
"name": "专属经理",
|
||||||
|
"font_class": "zhuanshujingli",
|
||||||
|
"unicode": "e883",
|
||||||
|
"unicode_decimal": 59523
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "9592764",
|
||||||
|
"name": "公司",
|
||||||
|
"font_class": "gongsi",
|
||||||
|
"unicode": "e679",
|
||||||
|
"unicode_decimal": 59001
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "8225386",
|
||||||
|
"name": "系统权限",
|
||||||
|
"font_class": "xitongquanxian",
|
||||||
|
"unicode": "e61e",
|
||||||
|
"unicode_decimal": 58910
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "6527123",
|
||||||
|
"name": "日志",
|
||||||
|
"font_class": "rizhi",
|
||||||
|
"unicode": "e647",
|
||||||
|
"unicode_decimal": 58951
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "12753449",
|
||||||
|
"name": "用户管理",
|
||||||
|
"font_class": "yonghuguanli_huaban",
|
||||||
|
"unicode": "e62d",
|
||||||
|
"unicode_decimal": 58925
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "20853327",
|
||||||
|
"name": "定时任务",
|
||||||
|
"font_class": "dingshirenwu",
|
||||||
|
"unicode": "e6a3",
|
||||||
|
"unicode_decimal": 59043
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "4765881",
|
||||||
|
"name": "dashboard",
|
||||||
|
"font_class": "dashboard",
|
||||||
|
"unicode": "e78b",
|
||||||
|
"unicode_decimal": 59275
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "5283349",
|
||||||
|
"name": "菜单",
|
||||||
|
"font_class": "caidan",
|
||||||
|
"unicode": "e65d",
|
||||||
|
"unicode_decimal": 58973
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "6627737",
|
||||||
|
"name": "部门管理",
|
||||||
|
"font_class": "bumenguanli",
|
||||||
|
"unicode": "e61d",
|
||||||
|
"unicode_decimal": 58909
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7274106",
|
||||||
|
"name": "角色管理",
|
||||||
|
"font_class": "jiaoseguanli",
|
||||||
|
"unicode": "e621",
|
||||||
|
"unicode_decimal": 58913
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "1119109",
|
||||||
|
"name": "系统",
|
||||||
|
"font_class": "xitong",
|
||||||
|
"unicode": "e601",
|
||||||
|
"unicode_decimal": 58881
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "1727423",
|
||||||
|
"name": "204首页",
|
||||||
|
"font_class": "shouye",
|
||||||
|
"unicode": "e8b9",
|
||||||
|
"unicode_decimal": 59577
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "11641882",
|
||||||
|
"name": "关于",
|
||||||
|
"font_class": "guanyu",
|
||||||
|
"unicode": "e623",
|
||||||
|
"unicode_decimal": 58915
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "12769434",
|
||||||
|
"name": "DVLINK_大屏",
|
||||||
|
"font_class": "DVLINK_daping",
|
||||||
|
"unicode": "e627",
|
||||||
|
"unicode_decimal": 58919
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "318438",
|
||||||
|
"name": "weixin",
|
||||||
|
"font_class": "weixin",
|
||||||
|
"unicode": "e656",
|
||||||
|
"unicode_decimal": 58966
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "4936984",
|
||||||
|
"name": "QQ",
|
||||||
|
"font_class": "QQ",
|
||||||
|
"unicode": "e882",
|
||||||
|
"unicode_decimal": 59522
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "128654",
|
||||||
|
"name": "content-right",
|
||||||
|
"font_class": "contentright",
|
||||||
|
"unicode": "e67a",
|
||||||
|
"unicode_decimal": 59002
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "4608986",
|
||||||
|
"name": "主题",
|
||||||
|
"font_class": "zhuti",
|
||||||
|
"unicode": "e610",
|
||||||
|
"unicode_decimal": 58896
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "10452247",
|
||||||
|
"name": "sousuo",
|
||||||
|
"font_class": "sousuo",
|
||||||
|
"unicode": "e68a",
|
||||||
|
"unicode_decimal": 59018
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "11372726",
|
||||||
|
"name": "消息中心",
|
||||||
|
"font_class": "xiaoxi",
|
||||||
|
"unicode": "e8be",
|
||||||
|
"unicode_decimal": 59582
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "7533292",
|
||||||
|
"name": "中英文",
|
||||||
|
"font_class": "zhongyingwen",
|
||||||
|
"unicode": "e605",
|
||||||
|
"unicode_decimal": 58885
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "3278362",
|
||||||
|
"name": "放大",
|
||||||
|
"font_class": "fangda",
|
||||||
|
"unicode": "e622",
|
||||||
|
"unicode_decimal": 58914
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "5698509",
|
||||||
|
"name": "全屏缩小",
|
||||||
|
"font_class": "suoxiao",
|
||||||
|
"unicode": "e62a",
|
||||||
|
"unicode_decimal": 58922
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 551 KiB |
|
@ -0,0 +1,493 @@
|
||||||
|
/* flex */
|
||||||
|
.flex-center {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-end {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-justify-between {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-align-center {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-column-center {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-f {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-f {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.f-r {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.f-l {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clearfix */
|
||||||
|
.clearfix::after {
|
||||||
|
display: block;
|
||||||
|
height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
clear: both;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 文字单行省略号 */
|
||||||
|
.sle {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 文字多行省略号 */
|
||||||
|
.mle {
|
||||||
|
display: -webkit-box;
|
||||||
|
overflow: hidden;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 文字多了自动換行 */
|
||||||
|
.break-word {
|
||||||
|
word-break: break-all;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fade-transform */
|
||||||
|
.fade-transform-leave-active,
|
||||||
|
.fade-transform-enter-active {
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-transform-enter-from {
|
||||||
|
opacity: 0;
|
||||||
|
transition: all 0.2s;
|
||||||
|
transform: translateX(-30px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-transform-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transition: all 0.2s;
|
||||||
|
transform: translateX(30px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* breadcrumb-transform */
|
||||||
|
.breadcrumb-enter-active {
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb-enter-from,
|
||||||
|
.breadcrumb-leave-active {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 外边距、内边距全局样式 */
|
||||||
|
@for $i from 0 through 40 {
|
||||||
|
.mt#{$i} {
|
||||||
|
margin-top: #{$i}px !important;
|
||||||
|
}
|
||||||
|
.mr#{$i} {
|
||||||
|
margin-right: #{$i}px !important;
|
||||||
|
}
|
||||||
|
.mb#{$i} {
|
||||||
|
margin-bottom: #{$i}px !important;
|
||||||
|
}
|
||||||
|
.ml#{$i} {
|
||||||
|
margin-left: #{$i}px !important;
|
||||||
|
}
|
||||||
|
.pt#{$i} {
|
||||||
|
padding-top: #{$i}px !important;
|
||||||
|
}
|
||||||
|
.pr#{$i} {
|
||||||
|
padding-right: #{$i}px !important;
|
||||||
|
}
|
||||||
|
.pb#{$i} {
|
||||||
|
padding-bottom: #{$i}px !important;
|
||||||
|
}
|
||||||
|
.pl#{$i} {
|
||||||
|
padding-left: #{$i}px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- 内外边距 -- */
|
||||||
|
|
||||||
|
.margin-0 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-xs {
|
||||||
|
margin: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-sm {
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin {
|
||||||
|
margin: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-lg {
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-xl {
|
||||||
|
margin: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-top-xs {
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-top-sm {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-top {
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-top-lg {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-top-xl {
|
||||||
|
margin-top: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-right-xs {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-right-sm {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-right {
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-right-lg {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-right-xl {
|
||||||
|
margin-right: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-bottom-xs {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-bottom-sm {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-bottom {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-bottom-lg {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-bottom-xl {
|
||||||
|
margin-bottom: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-left-xs {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-left-sm {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-left {
|
||||||
|
margin-left: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-left-lg {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-left-xl {
|
||||||
|
margin-left: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-lr-xs {
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-lr-sm {
|
||||||
|
margin-left: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-lr {
|
||||||
|
margin-left: 15px;
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-lr-lg {
|
||||||
|
margin-left: 20px;
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-lr-xl {
|
||||||
|
margin-left: 25px;
|
||||||
|
margin-right: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-tb-xs {
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-tb-sm {
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-tb {
|
||||||
|
margin-top: 15px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-tb-lg {
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-tb-xl {
|
||||||
|
margin-top: 25px;
|
||||||
|
margin-bottom: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-0 {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-xs {
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-sm {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding {
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-lg {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-xl {
|
||||||
|
padding: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-top-xs {
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-top-sm {
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-top {
|
||||||
|
padding-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-top-lg {
|
||||||
|
padding-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-top-xl {
|
||||||
|
padding-top: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-right-xs {
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-right-sm {
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-right {
|
||||||
|
padding-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-right-lg {
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-right-xl {
|
||||||
|
padding-right: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-bottom-xs {
|
||||||
|
padding-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-bottom-sm {
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-bottom {
|
||||||
|
padding-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-bottom-lg {
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-bottom-xl {
|
||||||
|
padding-bottom: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-left-xs {
|
||||||
|
padding-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-left-sm {
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-left {
|
||||||
|
padding-left: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-left-lg {
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-left-xl {
|
||||||
|
padding-left: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-lr-xs {
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-lr-sm {
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-lr {
|
||||||
|
padding-left: 15px;
|
||||||
|
padding-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-lr-lg {
|
||||||
|
padding-left: 20px;
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-lr-xl {
|
||||||
|
padding-left: 25px;
|
||||||
|
padding-right: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-tb-xs {
|
||||||
|
padding-top: 5px;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-tb-sm {
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-tb {
|
||||||
|
padding-top: 15px;
|
||||||
|
padding-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-tb-lg {
|
||||||
|
padding-top: 20px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-tb-xl {
|
||||||
|
padding-top: 25px;
|
||||||
|
padding-bottom: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*高德地图去水印*/
|
||||||
|
.amap-logo {
|
||||||
|
display: none !important;
|
||||||
|
visibility: hidden !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.amap-copyright {
|
||||||
|
display: none !important;
|
||||||
|
visibility: hidden !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*高德地图去水印 结束*/
|
||||||
|
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 8px;
|
||||||
|
height: 12px;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*浏览器滚动条样式*/
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
display: block;
|
||||||
|
min-height: 12px;
|
||||||
|
min-width: 8px;
|
||||||
|
border-radius: 6px;
|
||||||
|
background-color: rgb(217, 217, 217);
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
display: block;
|
||||||
|
min-height: 12px;
|
||||||
|
min-width: 8px;
|
||||||
|
border-radius: 6px;
|
||||||
|
background-color: rgb(159, 159, 159);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*浏览器滚动条样式 结束*/
|
||||||
|
|
||||||
|
/* 鼠标悬浮手指 */
|
||||||
|
.pointer {
|
||||||
|
cursor: pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-table {
|
||||||
|
thead, th, td {
|
||||||
|
border: 1px solid black;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
|
After Width: | Height: | Size: 496 B |
|
@ -0,0 +1,85 @@
|
||||||
|
import axios, {AxiosInstance, AxiosRequestConfig, InternalAxiosRequestConfig} from "axios";
|
||||||
|
import {message} from "ant-design-vue";
|
||||||
|
import {useUserStore} from "@/stores/modules/userStore.ts";
|
||||||
|
import router from "@/router";
|
||||||
|
|
||||||
|
export interface CustomAxiosRequestConfig extends AxiosRequestConfig {
|
||||||
|
//是否需要全屏禁用
|
||||||
|
loading?: boolean,
|
||||||
|
loadingMessage?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CustomInternalAxiosRequestConfig extends InternalAxiosRequestConfig {
|
||||||
|
//是否需要全屏禁用
|
||||||
|
loading?: boolean,
|
||||||
|
loadingMessage?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const axiosConfig: AxiosRequestConfig = {
|
||||||
|
baseURL: __APP_ENV.VITE_APP_BASE_API,
|
||||||
|
timeout: __APP_ENV.VITE_APP_ENV === 'production' ? 10 * 1000 : 60 * 1000,
|
||||||
|
timeoutErrorMessage: "请求超时......"
|
||||||
|
};
|
||||||
|
|
||||||
|
class RequestHttp {
|
||||||
|
|
||||||
|
service: AxiosInstance;
|
||||||
|
|
||||||
|
constructor(config: AxiosRequestConfig) {
|
||||||
|
this.service = axios.create(config);
|
||||||
|
|
||||||
|
this.service.interceptors.request.use((cfg: CustomInternalAxiosRequestConfig) => {
|
||||||
|
const userStore = useUserStore()
|
||||||
|
cfg.headers.set(userStore.getTokenInfo?.name as string, userStore.getTokenInfo?.value as string)
|
||||||
|
return cfg;
|
||||||
|
}, async (error) => {
|
||||||
|
message.error(error.message)
|
||||||
|
return Promise.reject(error);
|
||||||
|
})
|
||||||
|
|
||||||
|
this.service.interceptors.response.use(async (resp): Promise<any> => {
|
||||||
|
const jsonResult: JsonResult<unknown> = resp.data;
|
||||||
|
if (jsonResult && jsonResult.code != 200) {
|
||||||
|
//一些特定的错误需要重新登录
|
||||||
|
if ([-1].includes(jsonResult.code)) {
|
||||||
|
//清除登录信息
|
||||||
|
await useUserStore().resetUserInfo();
|
||||||
|
//跳转登录页
|
||||||
|
await router.push({
|
||||||
|
path: '/login'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
message.error(jsonResult.message)
|
||||||
|
return Promise.reject(jsonResult);
|
||||||
|
}
|
||||||
|
return Promise.resolve(jsonResult);
|
||||||
|
}, (error) => {
|
||||||
|
message.error(error.message)
|
||||||
|
return Promise.reject(error);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 常用请求方法封装
|
||||||
|
*/
|
||||||
|
get<T>(url: string, params?: object, _object: CustomAxiosRequestConfig = {}): Promise<JsonResult<T>> {
|
||||||
|
return this.service.get(url, {params, ..._object});
|
||||||
|
}
|
||||||
|
|
||||||
|
post<T>(url: string, params?: object | object[], _object: CustomAxiosRequestConfig = {}): Promise<JsonResult<T>> {
|
||||||
|
return this.service.post(url, params, _object);
|
||||||
|
}
|
||||||
|
|
||||||
|
put<T>(url: string, params?: object | object[], _object: CustomAxiosRequestConfig = {}): Promise<JsonResult<T>> {
|
||||||
|
return this.service.put(url, params, _object);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete<T>(url: string, params?: object, _object: CustomAxiosRequestConfig = {}): Promise<JsonResult<T>> {
|
||||||
|
return this.service.delete(url, {params, ..._object});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const api = new RequestHttp(axiosConfig);
|
||||||
|
|
||||||
|
export default api
|
|
@ -0,0 +1,41 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
defineProps<{ msg: string }>()
|
||||||
|
|
||||||
|
const count = ref(0)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<h1>{{ msg }}</h1>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<button type="button" @click="count++">count is {{ count }}</button>
|
||||||
|
<p>
|
||||||
|
Edit
|
||||||
|
<code>components/HelloWorld.vue</code> to test HMR
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Check out
|
||||||
|
<a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
|
||||||
|
>create-vue</a
|
||||||
|
>, the official Vue + Vite starter
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Learn more about IDE Support for Vue in the
|
||||||
|
<a
|
||||||
|
href="https://vuejs.org/guide/scaling-up/tooling.html#ide-support"
|
||||||
|
target="_blank"
|
||||||
|
>Vue Docs Scaling up Guide</a
|
||||||
|
>.
|
||||||
|
</p>
|
||||||
|
<p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.read-the-docs {
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,36 @@
|
||||||
|
<template>
|
||||||
|
<div class="flex-justify-between h-f">
|
||||||
|
<div class="flex-center">
|
||||||
|
<menu-unfold-outlined
|
||||||
|
v-if="collapsed"
|
||||||
|
class="trigger"
|
||||||
|
@click="() => (collapsed = !collapsed)"
|
||||||
|
/>
|
||||||
|
<menu-fold-outlined v-else class="trigger" @click="() => (collapsed = !collapsed)"/>
|
||||||
|
</div>
|
||||||
|
<div class="margin-right flex-center">
|
||||||
|
<a-avatar/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {MenuFoldOutlined, MenuUnfoldOutlined} from "@ant-design/icons-vue";
|
||||||
|
|
||||||
|
|
||||||
|
const collapsed = defineModel<boolean>('collapsed')
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.trigger {
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 64px;
|
||||||
|
padding: 0 24px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trigger:hover {
|
||||||
|
color: #1890ff;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,90 @@
|
||||||
|
<template>
|
||||||
|
<a-layout class="main-content">
|
||||||
|
<a-layout-sider
|
||||||
|
:collapsed="collapsed"
|
||||||
|
theme="light"
|
||||||
|
:trigger="null"
|
||||||
|
collapsible
|
||||||
|
>
|
||||||
|
<div v-if="!collapsed" class="title flex-center">
|
||||||
|
<div>超级后台</div>
|
||||||
|
</div>
|
||||||
|
<div v-else class="logo flex-center">
|
||||||
|
<img src="@/assets/vue.svg" title="超级后台" alt="xx">
|
||||||
|
</div>
|
||||||
|
</a-layout-sider>
|
||||||
|
<a-layout>
|
||||||
|
<a-layout-header
|
||||||
|
class="layout-header"
|
||||||
|
>
|
||||||
|
<layout-header v-model:collapsed="collapsed"/>
|
||||||
|
</a-layout-header>
|
||||||
|
<a-layout-content
|
||||||
|
class="layout-content"
|
||||||
|
>
|
||||||
|
<router-view v-slot="{ Component, route }">
|
||||||
|
<transition appear name="fade-transform" mode="out-in">
|
||||||
|
<keep-alive :include="keepAliveNames">
|
||||||
|
<component :is="Component" :key="route.fullPath"/>
|
||||||
|
</keep-alive>
|
||||||
|
</transition>
|
||||||
|
</router-view>
|
||||||
|
</a-layout-content>
|
||||||
|
</a-layout>
|
||||||
|
</a-layout>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {ref} from "vue";
|
||||||
|
import LayoutHeader from "@/components/layout/header/LayoutHeader.vue";
|
||||||
|
|
||||||
|
const collapsed = ref<boolean>(false);
|
||||||
|
|
||||||
|
const keepAliveNames = ref<string[]>([])
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.main-content {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
|
||||||
|
.layout-header {
|
||||||
|
background: #ffffff;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-content {
|
||||||
|
margin: 10px;
|
||||||
|
padding: 4px;
|
||||||
|
background: #f5f7fd;
|
||||||
|
min-height: 280px;
|
||||||
|
border-radius: 5px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
height: 32px;
|
||||||
|
width: 168px;
|
||||||
|
transition: width 2ms linear 2ms;
|
||||||
|
margin: 16px;
|
||||||
|
color: black;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 20px
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
margin: 16px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-layout .site-layout-background {
|
||||||
|
background: #ffffff;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,132 @@
|
||||||
|
<template>
|
||||||
|
<a-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="loginParams"
|
||||||
|
:rules="loginParamsRule"
|
||||||
|
@finish="login"
|
||||||
|
layout="vertical"
|
||||||
|
size="large"
|
||||||
|
class="login-form"
|
||||||
|
>
|
||||||
|
<a-form-item name="telephone">
|
||||||
|
<a-input
|
||||||
|
v-model:value="loginParams.telephone"
|
||||||
|
placeholder="请输入账号/手机号"
|
||||||
|
:max-length="64"
|
||||||
|
allow-clear
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item name="password">
|
||||||
|
<a-input-password
|
||||||
|
v-model:value="loginParams.password"
|
||||||
|
placeholder="请输入密码"
|
||||||
|
:max-length="32"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<div class="remember-me">
|
||||||
|
<a-checkbox disabled>
|
||||||
|
记住我
|
||||||
|
</a-checkbox>
|
||||||
|
</div>
|
||||||
|
<a-button
|
||||||
|
class="btn"
|
||||||
|
type="primary"
|
||||||
|
html-type="submit"
|
||||||
|
>立即登录
|
||||||
|
</a-button>
|
||||||
|
</a-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import {ref} from 'vue'
|
||||||
|
import {FormInstance, message, notification} from "ant-design-vue";
|
||||||
|
import {Rule} from "ant-design-vue/es/form";
|
||||||
|
import {LoginParams} from "@/types/views/login.ts";
|
||||||
|
import api from "@/axios";
|
||||||
|
import {CLIENT_TYPE} from "@/config";
|
||||||
|
import rsaUtil from "@/utils/rsaUtil.ts";
|
||||||
|
import {TokenInfo} from "@/types/stores/userStore.ts";
|
||||||
|
import {useUserStore} from "@/stores/modules/userStore.ts";
|
||||||
|
import {useRouter} from "vue-router";
|
||||||
|
|
||||||
|
const userStore = useUserStore()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
const formRef = ref<FormInstance>(null!)
|
||||||
|
const loginParamsRule: Record<keyof LoginParams, Rule[]> = {
|
||||||
|
telephone: [
|
||||||
|
{required: true, message: '请输入手机号', trigger: 'change'},
|
||||||
|
{len: 11, message: "长度不够", trigger: 'blur'},
|
||||||
|
],
|
||||||
|
password: [
|
||||||
|
{required: true, message: '请输入密码', trigger: 'change'},
|
||||||
|
{min: 6, max: 20, message: '密码长度最小为6最长为20', trigger: 'blur'},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
const loginParams = ref<LoginParams>({
|
||||||
|
telephone: __APP_ENV.VITE_APP_ENV === "development" ? '15576404472' : '',
|
||||||
|
password: __APP_ENV.VITE_APP_ENV === "development" ? '123456' : ''
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录
|
||||||
|
*/
|
||||||
|
const login = async () => {
|
||||||
|
//校验表单
|
||||||
|
await formRef.value.validate()
|
||||||
|
//执行登录逻辑
|
||||||
|
const resp = await api.post<TokenInfo>('/login', {
|
||||||
|
clientType: CLIENT_TYPE,
|
||||||
|
loginParams: {
|
||||||
|
telephone: loginParams.value.telephone,
|
||||||
|
password: rsaUtil.encryptStr(loginParams.value.password)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
//保存token
|
||||||
|
userStore.saveTokenInfo(resp.data as TokenInfo)
|
||||||
|
//跳转页面
|
||||||
|
router.push("/index").then(() => {
|
||||||
|
notification.success({
|
||||||
|
message: '登录成功',
|
||||||
|
duration: 2,
|
||||||
|
description: '欢迎来到本系统!',
|
||||||
|
placement: 'topRight'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.login-form {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0 5px;
|
||||||
|
margin-top: 16px;
|
||||||
|
|
||||||
|
:deep(.ant-input-group-addon) {
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-form-item {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remember-me {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 0 0 1px #05f,
|
||||||
|
0 2px 1px rgba(0, 0, 0, 0.15);
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
height: 40px;
|
||||||
|
line-height: 22px;
|
||||||
|
margin: 20px 0 12px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,2 @@
|
||||||
|
export const CLIENT_TYPE = "MANAGEMENT_SUPER";
|
||||||
|
export const ROUTER_WHITE_LIST: string[] = ['/login', '/test'];
|
|
@ -0,0 +1,10 @@
|
||||||
|
declare const __APP_ENV: ImportMetaEnv;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全局返回
|
||||||
|
*/
|
||||||
|
interface JsonResult<T> {
|
||||||
|
code: number;
|
||||||
|
message: string;
|
||||||
|
data?: T;
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
import {createApp} from 'vue'
|
||||||
|
import App from '@/App.vue'
|
||||||
|
import '@/reset.css'
|
||||||
|
|
||||||
|
// 公共样式
|
||||||
|
import '@/assets/scss/common.scss'
|
||||||
|
// iconfont css
|
||||||
|
import "@/assets/iconfont/iconfont.css";
|
||||||
|
// vue Router
|
||||||
|
import router from "@/router";
|
||||||
|
// pinia stores
|
||||||
|
import pinia from "@/stores";
|
||||||
|
|
||||||
|
const vueApp = createApp(App);
|
||||||
|
|
||||||
|
vueApp
|
||||||
|
.use(router)
|
||||||
|
.use(pinia)
|
||||||
|
.mount('#app')
|
|
@ -0,0 +1,57 @@
|
||||||
|
/* http://meyerweb.com/eric/tools/css/reset/ */
|
||||||
|
/* v1.0 | 20080212 */
|
||||||
|
|
||||||
|
html, body, div, span, applet, object, iframe,
|
||||||
|
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||||
|
a, abbr, acronym, address, big, cite, code,
|
||||||
|
del, dfn, em, font, img, ins, kbd, q, s, samp,
|
||||||
|
small, strike, strong, sub, sup, tt, var,
|
||||||
|
b, u, i, center,
|
||||||
|
dl, dt, dd, ol, ul, li,
|
||||||
|
fieldset, form, label, legend,
|
||||||
|
table, caption, tbody, tfoot, thead, tr, th, td {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
outline: 0;
|
||||||
|
font-size: 100%;
|
||||||
|
vertical-align: baseline;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol, ul {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote, q {
|
||||||
|
quotes: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote:before, blockquote:after,
|
||||||
|
q:before, q:after {
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remember to define focus styles! */
|
||||||
|
:focus {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remember to highlight inserts somehow! */
|
||||||
|
ins {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
del {
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tables still need 'cellspacing="0"' in the markup */
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0;
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
import {createRouter, createWebHistory} from "vue-router";
|
||||||
|
import {staticRouter} from "@/router/staticRouters.ts";
|
||||||
|
import {message, Modal} from "ant-design-vue";
|
||||||
|
import {useUserStore} from "@/stores/modules/userStore.ts";
|
||||||
|
import {ROUTER_WHITE_LIST} from "@/config";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* createWebHistory & createWebHashHistory
|
||||||
|
* createWebHistory: 路径不带#号,但需要后端进行配置(如nginx配置:try_files $uri $uri/ /index.html last;)
|
||||||
|
* createWebHashHistory: 路径带#号 这部分 URL 从未被发送到服务器,所以它不需要在服务器层面上进行任何特殊处理,影响SEO
|
||||||
|
*/
|
||||||
|
const router = createRouter({
|
||||||
|
history: createWebHistory(),
|
||||||
|
routes: [...staticRouter],
|
||||||
|
strict: false,
|
||||||
|
scrollBehavior: () => ({left: 0, top: 0})
|
||||||
|
});
|
||||||
|
|
||||||
|
router.beforeEach(async (to, from, next) => {
|
||||||
|
Modal.destroyAll();
|
||||||
|
//判断访问的是不是登录页
|
||||||
|
const userStore = useUserStore();
|
||||||
|
if (to.path.toLocaleLowerCase() === '/login' && userStore.getTokenInfo?.value) {
|
||||||
|
//如果已登录 且访问login页面 直接返回当前页面
|
||||||
|
await message.warn('当前已登录,请先退出账号');
|
||||||
|
return next(from.fullPath)
|
||||||
|
}
|
||||||
|
//判断访问路径是不是白名单d
|
||||||
|
if (ROUTER_WHITE_LIST.includes(to.path)) {
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
//不在白名单内需要查看是否携带token 没有token需要返回登录页进行登录
|
||||||
|
if (!userStore.getTokenInfo?.value) {
|
||||||
|
await message.warn('未找到token,请重新登陆!')
|
||||||
|
return next('/login');
|
||||||
|
}
|
||||||
|
//放行
|
||||||
|
return next();
|
||||||
|
})
|
||||||
|
|
||||||
|
router.onError(error => {
|
||||||
|
console.error("路由错误", error.message);
|
||||||
|
})
|
||||||
|
|
||||||
|
export default router
|
|
@ -0,0 +1,33 @@
|
||||||
|
import {RouteRecordRaw} from "vue-router";
|
||||||
|
|
||||||
|
export const staticRouter: RouteRecordRaw[] = [
|
||||||
|
{
|
||||||
|
path: '/login',
|
||||||
|
name: 'login',
|
||||||
|
meta: {
|
||||||
|
title: '登录',
|
||||||
|
},
|
||||||
|
component: () => import("@/views/login.vue"),
|
||||||
|
}, {
|
||||||
|
path: "/",
|
||||||
|
redirect: '/index',
|
||||||
|
}, {
|
||||||
|
path: '/layout',
|
||||||
|
name: 'layout',
|
||||||
|
redirect: '/index',
|
||||||
|
component: () => import("@/components/layout/layout.vue"),
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '/index',
|
||||||
|
name: 'index',
|
||||||
|
meta: {
|
||||||
|
title: '首页',
|
||||||
|
icon: 'icon-shouye',
|
||||||
|
fixed: true,
|
||||||
|
isKeepAlive: false
|
||||||
|
},
|
||||||
|
component: () => import('@/views/index.vue')
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
|
@ -0,0 +1,8 @@
|
||||||
|
import {createPinia} from "pinia";
|
||||||
|
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
||||||
|
|
||||||
|
//创建store实例 持久化插件
|
||||||
|
const pinia = createPinia();
|
||||||
|
pinia.use(piniaPluginPersistedstate);
|
||||||
|
|
||||||
|
export default pinia;
|
|
@ -0,0 +1,27 @@
|
||||||
|
import {defineStore} from "pinia";
|
||||||
|
import {TokenInfo, UserStore} from "@/types/stores/userStore.ts";
|
||||||
|
|
||||||
|
export const useUserStore = defineStore({
|
||||||
|
id: 'useUserStore',
|
||||||
|
state: (): UserStore => {
|
||||||
|
return {
|
||||||
|
tokenInfo: undefined
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
saveTokenInfo(tokenInfo: TokenInfo) {
|
||||||
|
this.tokenInfo = tokenInfo
|
||||||
|
},
|
||||||
|
async resetUserInfo() {
|
||||||
|
this.tokenInfo = undefined;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getters: {
|
||||||
|
getTokenInfo: (state): TokenInfo => state.tokenInfo as TokenInfo,
|
||||||
|
},
|
||||||
|
persist: {
|
||||||
|
key: "useUserStore",
|
||||||
|
storage: window.localStorage,
|
||||||
|
paths: ["tokenInfo"],
|
||||||
|
}
|
||||||
|
})
|
|
@ -0,0 +1,8 @@
|
||||||
|
export interface TokenInfo {
|
||||||
|
name: string;
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserStore {
|
||||||
|
tokenInfo?: TokenInfo;
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
export interface LoginParams {
|
||||||
|
telephone: string;
|
||||||
|
password: string;
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
import {JSEncrypt} from "jsencrypt";
|
||||||
|
|
||||||
|
const rsa = new JSEncrypt()
|
||||||
|
rsa.setPublicKey(__APP_ENV.VITE_APP_RSA_PUBLIC_KEY)
|
||||||
|
|
||||||
|
const encryptStr = (text: string): string => {
|
||||||
|
const r = rsa.encrypt(text);
|
||||||
|
if (!r) {
|
||||||
|
throw "加密失败";
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
encryptStr
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
<template>
|
||||||
|
index页面
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,236 @@
|
||||||
|
<template>
|
||||||
|
<div class="root">
|
||||||
|
<div class="header">
|
||||||
|
<img src="@/assets/vue.svg" alt="Logo" height="33" width="33"/>
|
||||||
|
<div class="logo-text">超级后台</div>
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
<div class="left-banner"></div>
|
||||||
|
<div class="login-card">
|
||||||
|
<div class="title">
|
||||||
|
欢迎来到超级后台
|
||||||
|
</div>
|
||||||
|
<a-tabs class="account-tab" v-model:active-key="activeKey">
|
||||||
|
<a-tab-pane :key="0" tab="账号登录">
|
||||||
|
<TelephoneLogin/>
|
||||||
|
</a-tab-pane>
|
||||||
|
</a-tabs>
|
||||||
|
<div class="oauth">
|
||||||
|
<a-divider class="text" orientation="center">其他登录方式</a-divider>
|
||||||
|
<div class="idps">
|
||||||
|
<a-button class="app" type="link" shape="circle" disabled>
|
||||||
|
<QqOutlined/>
|
||||||
|
</a-button>
|
||||||
|
<a-button class="app" type="link" shape="circle" disabled>
|
||||||
|
<WechatOutlined/>
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
<div class="beian">
|
||||||
|
<div class="below text" v-html="'...'"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import {QqOutlined, WechatOutlined} from '@ant-design/icons-vue'
|
||||||
|
import TelephoneLogin from '@/components/login/TelephoneLogin.vue';
|
||||||
|
import {ref} from "vue";
|
||||||
|
|
||||||
|
const activeKey = ref(0)
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.root {
|
||||||
|
background-image: url('@/assets/images/login/bg.jpg');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: cover;
|
||||||
|
min-height: 100vh;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #3370ff;
|
||||||
|
cursor: pointer !important;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
color: #6694ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
padding: 32px 40px 10px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-text {
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 4px;
|
||||||
|
margin-left: 4px;
|
||||||
|
color: rgba(29, 33, 41);
|
||||||
|
font-size: 24px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
align-items: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
height: calc(100vh - 100px);
|
||||||
|
justify-content: center;
|
||||||
|
margin: 0 auto;
|
||||||
|
max-width: 1200px;
|
||||||
|
min-height: 650px;
|
||||||
|
|
||||||
|
.left-banner {
|
||||||
|
flex: 1 1;
|
||||||
|
height: 100%;
|
||||||
|
max-height: 700px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 100%;
|
||||||
|
left: 0;
|
||||||
|
max-height: 350px;
|
||||||
|
max-width: 500px;
|
||||||
|
object-fit: contain;
|
||||||
|
position: absolute;
|
||||||
|
top: 4.5%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-card {
|
||||||
|
display: flex;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 20px;
|
||||||
|
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
|
||||||
|
box-sizing: border-box;
|
||||||
|
min-height: 500px;
|
||||||
|
position: relative;
|
||||||
|
width: 450px;
|
||||||
|
min-width: 434px;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-bottom: 53px;
|
||||||
|
padding: 48px 43px 32px;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
color: #020814;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 500;
|
||||||
|
letter-spacing: 0.003em;
|
||||||
|
line-height: 32px;
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-tab {
|
||||||
|
margin-top: 36px;
|
||||||
|
|
||||||
|
:deep(.ant-tabs-nav) {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.ant-tabs-content) {
|
||||||
|
padding-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.ant-tabs-nav::before) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.ant-tabs-tab-btn) {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 22px;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 1px 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.ant-tabs-tab-btn:before) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.ant-tabs-tab) {
|
||||||
|
margin: 0 30px 0 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.oauth {
|
||||||
|
margin-top: 20px;
|
||||||
|
padding: 0 5px;
|
||||||
|
|
||||||
|
:deep(.ant-divider-inner-text) {
|
||||||
|
color: #80838a;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.ant-divider) {
|
||||||
|
margin-bottom: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.idps {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.app {
|
||||||
|
margin-right: 12px;
|
||||||
|
align-items: center;
|
||||||
|
border: 1px solid #eaedf1;
|
||||||
|
border-radius: 32px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
height: 32px;
|
||||||
|
justify-content: center;
|
||||||
|
width: 32px;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
width: 21px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.app:hover {
|
||||||
|
background: #f3f7ff;
|
||||||
|
border: 1px solid #97bcff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
align-items: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.beian {
|
||||||
|
.text {
|
||||||
|
color: #41464f;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 400;
|
||||||
|
letter-spacing: 0.2px;
|
||||||
|
line-height: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.below {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,16 @@
|
||||||
|
/// <reference types="vite/client" />
|
||||||
|
interface ImportMetaEnv {
|
||||||
|
// 项目名称
|
||||||
|
readonly VITE_APP_NAME: string;
|
||||||
|
// 当前环境
|
||||||
|
readonly VITE_APP_ENV: 'development' | 'production';
|
||||||
|
// 启动端口
|
||||||
|
readonly VITE_APP_PORT: number;
|
||||||
|
|
||||||
|
// axios
|
||||||
|
readonly VITE_APP_BASE_API: string;
|
||||||
|
readonly VITE_APP_PROXY_URL: string;
|
||||||
|
|
||||||
|
// RSA公钥
|
||||||
|
readonly VITE_APP_RSA_PUBLIC_KEY: string;
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2020",
|
||||||
|
"useDefineForClassFields": true,
|
||||||
|
"module": "ESNext",
|
||||||
|
"lib": [
|
||||||
|
"ES2020",
|
||||||
|
"DOM",
|
||||||
|
"DOM.Iterable"
|
||||||
|
],
|
||||||
|
"skipLibCheck": true,
|
||||||
|
/* Bundler mode */
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"noEmit": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"jsxImportSource": "vue",
|
||||||
|
/* Linting */
|
||||||
|
"strict": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"baseUrl": "./",
|
||||||
|
/* 配置别名 */
|
||||||
|
"paths": {
|
||||||
|
"@/*": [
|
||||||
|
"src/*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"allowSyntheticDefaultImports": true
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*.ts",
|
||||||
|
"src/**/*.d.ts",
|
||||||
|
"src/**/*.tsx",
|
||||||
|
"src/**/*.vue"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"files": [],
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.app.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.node.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2022",
|
||||||
|
"lib": [
|
||||||
|
"ES2023"
|
||||||
|
],
|
||||||
|
"module": "ESNext",
|
||||||
|
"skipLibCheck": true,
|
||||||
|
/* Bundler mode */
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"noEmit": true,
|
||||||
|
/* Linting */
|
||||||
|
"strict": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"noFallthroughCasesInSwitch": true
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"vite.config.ts"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
import {defineConfig, loadEnv} from 'vite'
|
||||||
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
import Components from 'unplugin-vue-components/vite';
|
||||||
|
import {AntDesignVueResolver} from 'unplugin-vue-components/resolvers';
|
||||||
|
import * as path from "node:path";
|
||||||
|
import vueJsx from '@vitejs/plugin-vue-jsx'
|
||||||
|
|
||||||
|
const pathSrc = path.resolve(__dirname, 'src');
|
||||||
|
|
||||||
|
// https://vitejs.dev/config/
|
||||||
|
export default defineConfig(({mode}) => {
|
||||||
|
const env: Record<string, string> = loadEnv(mode, process.cwd(), '')
|
||||||
|
return {
|
||||||
|
define: {
|
||||||
|
__APP_ENV: JSON.stringify(env)
|
||||||
|
},
|
||||||
|
base: '/',
|
||||||
|
plugins: [
|
||||||
|
vue(),
|
||||||
|
vueJsx(),
|
||||||
|
Components({
|
||||||
|
resolvers: [
|
||||||
|
AntDesignVueResolver({importStyle: false})
|
||||||
|
]
|
||||||
|
})
|
||||||
|
],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': pathSrc,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
host: '0.0.0.0',
|
||||||
|
port: parseInt(env['VITE_APP_PORT']),
|
||||||
|
open: false,
|
||||||
|
proxy: {
|
||||||
|
[env["VITE_APP_BASE_API"]]: {
|
||||||
|
target: env["VITE_APP_PROXY_URL"],
|
||||||
|
changeOrigin: true,
|
||||||
|
secure: false,
|
||||||
|
rewrite: path => path.replace(RegExp(`^${env['VITE_APP_BASE_API']}`), '')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
outDir: 'dist',
|
||||||
|
target: 'modules',
|
||||||
|
chunkSizeWarningLimit: 1500,
|
||||||
|
minify: 'terser',
|
||||||
|
terserOptions: {
|
||||||
|
compress: {
|
||||||
|
//生产环境时移除console
|
||||||
|
drop_console: env['VITE_DROP_CONSOLE'] as unknown as boolean,
|
||||||
|
drop_debugger: env['VITE_DROP_CONSOLE'] as unknown as boolean,
|
||||||
|
},
|
||||||
|
format: {
|
||||||
|
//删除注释
|
||||||
|
comments: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rollupOptions: {
|
||||||
|
output: {
|
||||||
|
manualChunks(id) {
|
||||||
|
if (id.includes('node_modules')) {
|
||||||
|
return id
|
||||||
|
.toString()
|
||||||
|
.split('node_modules/')[1]
|
||||||
|
.split('/')[0]
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
chunkFileNames(chunkInfo) {
|
||||||
|
const facadeModuleId = chunkInfo.facadeModuleId ? chunkInfo.facadeModuleId.split('/') : [];
|
||||||
|
const fileName =
|
||||||
|
facadeModuleId[facadeModuleId.length - 2] || '[name]';
|
||||||
|
return `js/${fileName}/[name].[hash].js`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
|
@ -0,0 +1,5 @@
|
||||||
|
.idea
|
||||||
|
target
|
||||||
|
logs
|
||||||
|
temp
|
||||||
|
HELP.md
|
|
@ -0,0 +1,313 @@
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.changhu</groupId>
|
||||||
|
<artifactId>policeSecurityServer</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>policeSecurityServer</name>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>17</java.version>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
<spring.boot.version>3.2.2</spring.boot.version>
|
||||||
|
|
||||||
|
<hutool.version>5.8.27</hutool.version>
|
||||||
|
<knife4j.version>4.5.0</knife4j.version>
|
||||||
|
<zxing.version>3.3.3</zxing.version>
|
||||||
|
<pinyin4j.version>2.5.1</pinyin4j.version>
|
||||||
|
<fastjson2.version>2.0.50</fastjson2.version>
|
||||||
|
<easyexcel.version>3.3.4</easyexcel.version>
|
||||||
|
<mysql.driver.version>8.0.32</mysql.driver.version>
|
||||||
|
<mybatis.plus.version>3.5.7</mybatis.plus.version>
|
||||||
|
<druid.version>1.2.20</druid.version>
|
||||||
|
<minio.version>8.4.3</minio.version>
|
||||||
|
<okhttp.version>4.8.1</okhttp.version>
|
||||||
|
<sa.token.version>1.38.0</sa.token.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- spring boot web -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
<exclusions>
|
||||||
|
<!--过滤系统自带日志-->
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-logging</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<!-- 去掉Jackson依赖,用fastjson -->
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-json</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<!-- 监控、追踪、审计、控制 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- 自动注解配置 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<!-- log4j2日志 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-log4j2</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- 单元测试 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- spring boot websocket支持 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- spring boot aop支持 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-aop</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- redis缓存 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- 提供Redis连接池 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-pool2</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- 参数校验-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-validation</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- lombok工具 https://projectlombok.org/ -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案 https://github.com/xiaoymin/knife4j -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.xiaoymin</groupId>
|
||||||
|
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
|
||||||
|
<version>${knife4j.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- fastjson2 对 SpringFramework 扩展 https://alibaba.github.io/fastjson2/ -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.fastjson2</groupId>
|
||||||
|
<artifactId>fastjson2-extension-spring6</artifactId>
|
||||||
|
<version>${fastjson2.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- easyexcel https://easyexcel.opensource.alibaba.com/-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>easyexcel</artifactId>
|
||||||
|
<version>${easyexcel.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- hutool工具 https://doc.hutool.cn/pages/index/-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-all</artifactId>
|
||||||
|
<version>${hutool.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- hutool使用CaptchaUtil需要导入第三方包 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.zxing</groupId>
|
||||||
|
<artifactId>core</artifactId>
|
||||||
|
<version>${zxing.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- hutool使用PinyinUtil需要导入第三方包 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.belerweb</groupId>
|
||||||
|
<artifactId>pinyin4j</artifactId>
|
||||||
|
<version>${pinyin4j.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- Sa-Token 权限认证,在线文档:https://sa-token.cc -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-spring-boot3-starter</artifactId>
|
||||||
|
<version>${sa.token.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- Sa-Token 整合 Redis -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-redis</artifactId>
|
||||||
|
<version>${sa.token.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- mysql 驱动 注:最新版本的MySQL Connector/J已经迁移到了符合反转DNS规范的Maven坐标 因此,您需要按照新的坐标来引用该依赖。根据错误消息中提供的信息,将mysql:mysql-connector-java替换为com.mysql:mysql-connector-j,版本保持不变。-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-j</artifactId>
|
||||||
|
<version>${mysql.driver.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- druid数据库连接池 https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>druid-spring-boot-3-starter</artifactId>
|
||||||
|
<version>${druid.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- mybatis plus https://baomidou.com/pages/24112f/-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
|
||||||
|
<version>${mybatis.plus.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- minio对象存储 https://www.minio.org.cn/ -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.minio</groupId>
|
||||||
|
<artifactId>minio</artifactId>
|
||||||
|
<version>${minio.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.squareup.okhttp3</groupId>
|
||||||
|
<artifactId>okhttp</artifactId>
|
||||||
|
<version>${okhttp.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>osgeo</id>
|
||||||
|
<name>OSGeo Release Repository</name>
|
||||||
|
<url>https://repo.osgeo.org/repository/release/</url>
|
||||||
|
<snapshots>
|
||||||
|
<enabled>false</enabled>
|
||||||
|
</snapshots>
|
||||||
|
<releases>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</releases>
|
||||||
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>osgeo-snapshot</id>
|
||||||
|
<name>OSGeo Snapshot Repository</name>
|
||||||
|
<url>https://repo.osgeo.org/repository/snapshot/</url>
|
||||||
|
<snapshots>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</snapshots>
|
||||||
|
<releases>
|
||||||
|
<enabled>false</enabled>
|
||||||
|
</releases>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<!-- spring boot版本依赖管理-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-dependencies</artifactId>
|
||||||
|
<version>${spring.boot.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>${project.artifactId}</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.11.0</version>
|
||||||
|
<configuration>
|
||||||
|
<source>${maven.compiler.source}</source>
|
||||||
|
<target>${maven.compiler.target}</target>
|
||||||
|
<compilerArgs>
|
||||||
|
<arg>
|
||||||
|
-parameters
|
||||||
|
</arg>
|
||||||
|
</compilerArgs>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<version>${spring.boot.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
|
||||||
|
<!-- 定义资源目录 -->
|
||||||
|
<resources>
|
||||||
|
<!-- ${project.basedir}/src/main/resources/${profiles.environment} 下的文件输出到根目录下 -->
|
||||||
|
<resource>
|
||||||
|
<directory>${project.basedir}/src/main/resources/${profiles.environment}</directory>
|
||||||
|
</resource>
|
||||||
|
<!-- ${project.basedir}/src/main/resources/META-INF 下的文件输出到 META-INF 下 -->
|
||||||
|
<resource>
|
||||||
|
<directory>${project.basedir}/src/main/resources/META-INF</directory>
|
||||||
|
<targetPath>META-INF</targetPath>
|
||||||
|
</resource>
|
||||||
|
<!-- ${project.basedir}/src/main/resources/static 下的文件输出到 static 下 -->
|
||||||
|
<resource>
|
||||||
|
<directory>${project.basedir}/src/main/resources/static</directory>
|
||||||
|
<targetPath>static</targetPath>
|
||||||
|
</resource>
|
||||||
|
<!-- ${project.basedir}/src/main/resources/conf 下的文件输出到 conf 下 -->
|
||||||
|
<resource>
|
||||||
|
<directory>${project.basedir}/src/main/resources/conf</directory>
|
||||||
|
<targetPath>conf</targetPath>
|
||||||
|
</resource>
|
||||||
|
<!-- ${project.basedir}/src/main/resources/mapper 下的文件输出到 mapper 下 -->
|
||||||
|
<resource>
|
||||||
|
<directory>${project.basedir}/src/main/resources/mapper</directory>
|
||||||
|
<targetPath>mapper</targetPath>
|
||||||
|
</resource>
|
||||||
|
<resource>
|
||||||
|
<directory>${project.basedir}/src/main/resources/templates</directory>
|
||||||
|
<targetPath>templates</targetPath>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<!--开发环境-->
|
||||||
|
<profile>
|
||||||
|
<id>dev</id>
|
||||||
|
<properties>
|
||||||
|
<profiles.environment>env/dev</profiles.environment>
|
||||||
|
</properties>
|
||||||
|
<activation>
|
||||||
|
<!--默认激活本地环境-->
|
||||||
|
<activeByDefault>true</activeByDefault>
|
||||||
|
</activation>
|
||||||
|
</profile>
|
||||||
|
|
||||||
|
<!--本地环境-->
|
||||||
|
<profile>
|
||||||
|
<id>local</id>
|
||||||
|
<properties>
|
||||||
|
<profiles.environment>env/local</profiles.environment>
|
||||||
|
</properties>
|
||||||
|
</profile>
|
||||||
|
|
||||||
|
<!--线上环境-->
|
||||||
|
<profile>
|
||||||
|
<id>prod</id>
|
||||||
|
<properties>
|
||||||
|
<profiles.environment>env/prod</profiles.environment>
|
||||||
|
</properties>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
</project>
|
|
@ -0,0 +1,47 @@
|
||||||
|
package com.changhu;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.cache.annotation.EnableCaching;
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
|
import org.springframework.web.socket.config.annotation.EnableWebSocket;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hello world!
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableTransactionManagement
|
||||||
|
@EnableScheduling
|
||||||
|
@EnableCaching
|
||||||
|
@EnableWebSocket
|
||||||
|
public class PoliceSecurityServerApp {
|
||||||
|
@SneakyThrows
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication app = new SpringApplication(PoliceSecurityServerApp.class);
|
||||||
|
ConfigurableApplicationContext application = app.run(args);
|
||||||
|
Environment env = application.getEnvironment();
|
||||||
|
log.info(StrUtil.format("""
|
||||||
|
\n----------------------------------------------------------
|
||||||
|
\tApplication '{}' is running! Access URLs:
|
||||||
|
\tLocal: \t\thttp://localhost:{}
|
||||||
|
\tExternal: \thttp://{}:{}
|
||||||
|
\tDoc: \t\thttp://{}:{}/doc.html
|
||||||
|
""",
|
||||||
|
env.getProperty("spring.application.name"),
|
||||||
|
env.getProperty("server.port"),
|
||||||
|
InetAddress.getLocalHost().getHostAddress(),
|
||||||
|
env.getProperty("server.port"),
|
||||||
|
InetAddress.getLocalHost().getHostAddress(),
|
||||||
|
env.getProperty("server.port")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.changhu.common.annotation;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.DesensitizedUtil;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: 脱敏注解
|
||||||
|
* createTime: 2023/9/13 16:45
|
||||||
|
*/
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface Desensitized {
|
||||||
|
DesensitizedUtil.DesensitizedType value();
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.changhu.common.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: 是拓展属性
|
||||||
|
* createTime: 2023/11/1 17:25
|
||||||
|
*/
|
||||||
|
@Documented
|
||||||
|
@Retention(value = RetentionPolicy.RUNTIME)
|
||||||
|
@Target(value = {ElementType.FIELD})
|
||||||
|
public @interface IsExtData {
|
||||||
|
boolean value() default true;
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.changhu.common.annotation;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: JsonResult
|
||||||
|
* createTime: 2023/8/18 10:47
|
||||||
|
*/
|
||||||
|
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@RestController
|
||||||
|
public @interface JsonBody {
|
||||||
|
boolean value() default true;
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.changhu.common.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 20252
|
||||||
|
* @createTime 2024/6/26 上午9:41
|
||||||
|
* @desc RealDelete...
|
||||||
|
*/
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
public @interface RealDelete {
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package com.changhu.common.db;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Dict;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import com.baomidou.mybatisplus.annotation.IEnum;
|
||||||
|
import com.changhu.common.exception.MessageException;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: BaseEnum
|
||||||
|
* createTime: 2023/8/16 17:38
|
||||||
|
*/
|
||||||
|
public interface BaseEnum<V> {
|
||||||
|
/**
|
||||||
|
* 获取值
|
||||||
|
*
|
||||||
|
* @return V
|
||||||
|
*/
|
||||||
|
V getValue();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文本
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
String getLabel();
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
static <P, T extends BaseEnum<P>> T valueOf(Class<? extends BaseEnum<P>> enumType, P code) {
|
||||||
|
BaseEnum<P>[] enumConstants = enumType.getEnumConstants();
|
||||||
|
for (BaseEnum<P> pBaseEnum : enumConstants) {
|
||||||
|
if (ObjectUtil.equals(code, pBaseEnum.getValue())) {
|
||||||
|
return (T) pBaseEnum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new MessageException("不存在值为:{} 的【{}】对象!", code.toString(), enumType.componentType().getSimpleName());
|
||||||
|
}
|
||||||
|
|
||||||
|
default Object serializer() {
|
||||||
|
return Dict.of(
|
||||||
|
"value", this.getValue(),
|
||||||
|
"label", this.getLabel()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.changhu.common.db.enums;
|
||||||
|
|
||||||
|
import com.changhu.common.db.BaseEnum;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 20252
|
||||||
|
* @createTime 2024/8/28 下午3:51
|
||||||
|
* @desc CheckStatus...
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum CheckStatus implements BaseEnum<Integer> {
|
||||||
|
|
||||||
|
checked(0, "已审核"),
|
||||||
|
unChecked(1, "未审核"),
|
||||||
|
;
|
||||||
|
|
||||||
|
private final Integer value;
|
||||||
|
private final String label;
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.changhu.common.db.enums;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Dict;
|
||||||
|
import com.changhu.common.db.BaseEnum;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: DeleteFlag
|
||||||
|
* createTime: 2023/8/16 17:39
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum DeleteFlag implements BaseEnum<Integer> {
|
||||||
|
|
||||||
|
FALSE(0, "未删除"),
|
||||||
|
TRUE(1, "已删除"),
|
||||||
|
;
|
||||||
|
|
||||||
|
private final Integer value;
|
||||||
|
private final String label;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.changhu.common.db.enums;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IEnum;
|
||||||
|
import com.changhu.common.annotation.IsExtData;
|
||||||
|
import com.changhu.common.db.BaseEnum;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: IsEnable
|
||||||
|
* createTime: 2023/8/22 9:52
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum IsEnable implements BaseEnum<Integer>, IEnum<Integer> {
|
||||||
|
|
||||||
|
TRUE(0, "启用", "success"),
|
||||||
|
FALSE(1, "禁用", "error"),
|
||||||
|
;
|
||||||
|
|
||||||
|
private final Integer value;
|
||||||
|
private final String label;
|
||||||
|
@IsExtData
|
||||||
|
private final String color;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.changhu.common.db.enums;
|
||||||
|
|
||||||
|
import com.changhu.common.db.BaseEnum;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: IsOrNot
|
||||||
|
* createTime: 2023/9/21 16:42
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum IsOrNot implements BaseEnum<Integer> {
|
||||||
|
IS(0, "是"),
|
||||||
|
NOT(1, "否"),
|
||||||
|
;
|
||||||
|
|
||||||
|
private final Integer value;
|
||||||
|
private final String label;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.changhu.common.db.enums;
|
||||||
|
|
||||||
|
import com.changhu.common.db.BaseEnum;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fileName: Sex
|
||||||
|
* author: LuoZhun
|
||||||
|
* createTime: 2023/11/8 17:14
|
||||||
|
* description: 性别
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum Sex implements BaseEnum<Integer> {
|
||||||
|
MAN(0, "男"),
|
||||||
|
WOMAN(1, "女"),
|
||||||
|
UNKNOWN(2, "隐藏");
|
||||||
|
|
||||||
|
private final Integer value;
|
||||||
|
private final String label;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.changhu.common.enums;
|
||||||
|
|
||||||
|
import com.changhu.common.db.BaseEnum;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: CaptchaType
|
||||||
|
* createTime: 2023/9/19 19:15
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum CaptchaType implements BaseEnum<String> {
|
||||||
|
|
||||||
|
LOGIN("login", "登录验证码"),
|
||||||
|
;
|
||||||
|
|
||||||
|
private final String value;
|
||||||
|
private final String label;
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
package com.changhu.common.enums;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: ResultCode
|
||||||
|
* createTime: 2023/8/16 17:30
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum ResultCode {
|
||||||
|
/**
|
||||||
|
* 常见状态码
|
||||||
|
*/
|
||||||
|
SUCCESS(200, "操作成功!"),
|
||||||
|
ERROR(500, "操作失败!"),
|
||||||
|
WARN(555, "出现警告!"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 权限相关 -1错误需要重新返回登录页面 进行认证
|
||||||
|
*/
|
||||||
|
NOT_TOKEN(-1, "未能读取到有效 token"),
|
||||||
|
INVALID_TOKEN(-1, "token 无效"),
|
||||||
|
TOKEN_TIMEOUT(-1, "token 已过期"),
|
||||||
|
BE_REPLACED(-1, "token 已被顶下线"),
|
||||||
|
KICK_OUT(-1, "token 已被踢下线"),
|
||||||
|
TOKEN_FREEZE(-1, "token 已被冻结"),
|
||||||
|
NO_PREFIX(-1, "未按照指定前缀提交 token"),
|
||||||
|
OTHER_TOKEN_ERROR(-1, "当前会话未登录"),
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加密解密
|
||||||
|
*/
|
||||||
|
DECRYPT_ERROR(301, "解码失败"),
|
||||||
|
ENCIPHER_ERROR(302, "编码失败"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统相关
|
||||||
|
*/
|
||||||
|
USER_NOT_FOUND(402, "用户不存在"),
|
||||||
|
PASSWORD_ERROR(403, "密码错误"),
|
||||||
|
NOT_FOUND_404(404, "找不到资源"),
|
||||||
|
USER_IS_DISABLE(405, "用户已禁用"),
|
||||||
|
ROLE_IS_DISABLE(405, "角色已禁用"),
|
||||||
|
CODE_ERROR(406, "验证码错误"),
|
||||||
|
DATA_NOT_FOUND(407, "数据不存在"),
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 参数校验
|
||||||
|
*/
|
||||||
|
PARAM_ERROR(502, "参数错误"),
|
||||||
|
REQUIRED_PARAM_MISSING(503, "未找到必填参数"),
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
private final Integer code;
|
||||||
|
private final String message;
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package com.changhu.common.exception;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.changhu.common.enums.ResultCode;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: MessageException
|
||||||
|
* createTime: 2023/8/16 17:27
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class MessageException extends RuntimeException {
|
||||||
|
|
||||||
|
private Integer code = ResultCode.ERROR.getCode();
|
||||||
|
private String message = ResultCode.ERROR.getMessage();
|
||||||
|
private Object data;
|
||||||
|
|
||||||
|
public MessageException(String errorMessage) {
|
||||||
|
this.message = errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageException(Integer errorCode, String errorMessage) {
|
||||||
|
this.code = errorCode;
|
||||||
|
this.message = errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageException(Integer errorCode, String template, String... errorMessage) {
|
||||||
|
this.code = errorCode;
|
||||||
|
this.message = StrUtil.format(template, Arrays.stream(errorMessage).toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageException(String template, String... errorMessage) {
|
||||||
|
this.message = StrUtil.format(template, Arrays.stream(errorMessage).toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageException(ResultCode resultCode, String errorMessage) {
|
||||||
|
this.code = resultCode.getCode();
|
||||||
|
this.message = errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageException(ResultCode resultCode, Object data, String errorMessage) {
|
||||||
|
this.code = resultCode.getCode();
|
||||||
|
this.message = errorMessage;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageException(ResultCode resultCode, Object data) {
|
||||||
|
this.code = resultCode.getCode();
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageException(ResultCode resultCode) {
|
||||||
|
this.code = resultCode.getCode();
|
||||||
|
this.message = resultCode.getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return StrUtil.format("业务错误:错误代码:{},错误内容:{}", Objects.isNull(this.code) ? 500 : this.code, this.message);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
package com.changhu.common.pojo.model;
|
||||||
|
|
||||||
|
import com.changhu.common.enums.ResultCode;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: JsonResult
|
||||||
|
* createTime: 2023/8/16 17:29
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class JsonResult<T> implements java.io.Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 响应编码
|
||||||
|
*/
|
||||||
|
private Integer code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回消息
|
||||||
|
*/
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回数据
|
||||||
|
*/
|
||||||
|
private T data;
|
||||||
|
|
||||||
|
public JsonResult(Integer code, String message) {
|
||||||
|
this.code = code;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonResult(ResultCode resultCode, T data) {
|
||||||
|
this.code = resultCode.getCode();
|
||||||
|
this.message = resultCode.getMessage();
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 成功信息
|
||||||
|
*/
|
||||||
|
public static <O> JsonResult<O> success() {
|
||||||
|
return new JsonResult<>(ResultCode.SUCCESS, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <O> JsonResult<O> successMsg(String message) {
|
||||||
|
return new JsonResult<>(ResultCode.SUCCESS.getCode(), message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <O> JsonResult<O> success(O data) {
|
||||||
|
return new JsonResult<>(ResultCode.SUCCESS, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作失败
|
||||||
|
*/
|
||||||
|
public static <O> JsonResult<O> error() {
|
||||||
|
return new JsonResult<>(ResultCode.ERROR, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <O> JsonResult<O> errorMsg(String message) {
|
||||||
|
return new JsonResult<>(ResultCode.ERROR.getCode(), message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <O> JsonResult<O> error(O data) {
|
||||||
|
return new JsonResult<>(ResultCode.ERROR, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 警告信息
|
||||||
|
*/
|
||||||
|
public static <O> JsonResult<O> warn() {
|
||||||
|
return new JsonResult<>(ResultCode.WARN, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <O> JsonResult<O> warnMsg(String message) {
|
||||||
|
return new JsonResult<>(ResultCode.WARN.getCode(), message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <O> JsonResult<O> warn(O data) {
|
||||||
|
return new JsonResult<>(ResultCode.WARN, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义信息
|
||||||
|
*/
|
||||||
|
public static <O> JsonResult<O> custom(Integer code, String message, O data) {
|
||||||
|
return new JsonResult<>(code, message, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <O> JsonResult<O> custom(Integer code, String message) {
|
||||||
|
return new JsonResult<>(code, message, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <O> JsonResult<O> custom(ResultCode resultCode) {
|
||||||
|
return new JsonResult<>(resultCode, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <O> JsonResult<O> custom(ResultCode resultCode, O data) {
|
||||||
|
return new JsonResult<>(resultCode, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <O> JsonResult<O> custom(Boolean result) {
|
||||||
|
return new JsonResult<>(result ? ResultCode.SUCCESS : ResultCode.ERROR, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <O> JsonResult<O> custom(Integer count) {
|
||||||
|
return new JsonResult<>(count > 0 ? ResultCode.SUCCESS : ResultCode.ERROR, null);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.changhu.common.pojo.vo;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Dict;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: SelectNodeVo
|
||||||
|
* createTime: 2023/9/22 9:53
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class SelectGroupNodeVo<T> implements Serializable {
|
||||||
|
/**
|
||||||
|
* 选择的值
|
||||||
|
*/
|
||||||
|
private T value;
|
||||||
|
/**
|
||||||
|
* 显示文本
|
||||||
|
*/
|
||||||
|
private String label;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分组选项
|
||||||
|
*/
|
||||||
|
private List<SelectGroupNodeVo<T>> options;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拓展属性
|
||||||
|
*/
|
||||||
|
private Dict extData;
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.changhu.common.pojo.vo;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Dict;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: SelectNodeVo
|
||||||
|
* createTime: 2023/9/22 9:53
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class SelectNodeVo<T> implements Serializable {
|
||||||
|
/**
|
||||||
|
* 选择的值
|
||||||
|
*/
|
||||||
|
private T value;
|
||||||
|
/**
|
||||||
|
* 显示文本
|
||||||
|
*/
|
||||||
|
private String label;
|
||||||
|
/**
|
||||||
|
* 拓展属性
|
||||||
|
*/
|
||||||
|
private Dict extData;
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.changhu.common.pojo.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 20252
|
||||||
|
* @createTime 2024/8/29 下午2:55
|
||||||
|
* @desc TokenInfo...
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TokenInfo {
|
||||||
|
private String name;
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public TokenInfo(String name, String value) {
|
||||||
|
this.name = name;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,176 @@
|
||||||
|
package com.changhu.common.pojo.vo;
|
||||||
|
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.lang.Dict;
|
||||||
|
import cn.hutool.core.util.NumberUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.springframework.lang.NonNull;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: TreeNodeVo
|
||||||
|
* createTime: 2023/9/4 16:38
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@Schema(description = "json树形数据")
|
||||||
|
public class TreeNodeVo<T> implements Serializable {
|
||||||
|
/**
|
||||||
|
* 值
|
||||||
|
*/
|
||||||
|
@Schema(description = "节点的唯一value")
|
||||||
|
private T value;
|
||||||
|
/**
|
||||||
|
* 父节点的值
|
||||||
|
*/
|
||||||
|
@Schema(description = "父节点的value")
|
||||||
|
private T parentValue;
|
||||||
|
/**
|
||||||
|
* 显示文本
|
||||||
|
*/
|
||||||
|
@Schema(description = "节点名称")
|
||||||
|
private String label;
|
||||||
|
/**
|
||||||
|
* 排序
|
||||||
|
*/
|
||||||
|
@Builder.Default
|
||||||
|
@Schema(description = "排序")
|
||||||
|
private Integer orderIndex = 0;
|
||||||
|
/**
|
||||||
|
* 拓展属性
|
||||||
|
*/
|
||||||
|
@Schema(description = "拓展属性")
|
||||||
|
private Dict extData;
|
||||||
|
/**
|
||||||
|
* 子节点
|
||||||
|
*/
|
||||||
|
@Schema(description = "子节点")
|
||||||
|
private List<TreeNodeVo<T>> children;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 树构建
|
||||||
|
*/
|
||||||
|
public static <T> List<TreeNodeVo<T>> buildTree(List<TreeNodeVo<T>> data, @NonNull T rootKey) {
|
||||||
|
//数据为空 直接返回空
|
||||||
|
if (CollUtil.isEmpty(data)) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
//先将数据根据parentValue分组
|
||||||
|
Map<T, List<TreeNodeVo<T>>> groupData = data.stream().collect(Collectors.groupingBy(TreeNodeVo::getParentValue));
|
||||||
|
//组装树
|
||||||
|
return data.stream()
|
||||||
|
.filter(e -> ObjectUtil.equals(e.getParentValue(), rootKey))
|
||||||
|
.peek(d -> d.setChildren(children(groupData, d)))
|
||||||
|
.sorted((a, b) -> NumberUtil.compare(b.getOrderIndex(), a.getOrderIndex()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> List<TreeNodeVo<T>> children(Map<T, List<TreeNodeVo<T>>> groupData, TreeNodeVo<T> node) {
|
||||||
|
List<TreeNodeVo<T>> treeNodeVos = groupData.get(node.getValue());
|
||||||
|
if (CollUtil.isEmpty(treeNodeVos)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return treeNodeVos.stream()
|
||||||
|
.peek(p -> p.setChildren(children(groupData, p)))
|
||||||
|
.sorted((a, b) -> NumberUtil.compare(b.getOrderIndex(), a.getOrderIndex()))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义树构建
|
||||||
|
*/
|
||||||
|
public static <T> List<Map<String, Object>> buildTree(List<?> data, @NonNull String key, @NonNull String parentKey, @NonNull T rootKey) {
|
||||||
|
if (CollUtil.isEmpty(data)) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
//先将数据转 对象为map
|
||||||
|
List<Map<String, Object>> mapListData = data.stream().map(BeanUtil::beanToMap).toList();
|
||||||
|
//将map集合根据parentKey分组
|
||||||
|
Map<Object, List<Map<String, Object>>> collect = mapListData.stream().collect(Collectors.groupingBy(e -> e.get(parentKey)));
|
||||||
|
|
||||||
|
return mapListData.stream()
|
||||||
|
.filter(e -> ObjectUtil.equals(e.get(parentKey), rootKey))
|
||||||
|
.peek(e -> e.put("children", children(collect, e, key)))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<Map<String, Object>> children(Map<Object, List<Map<String, Object>>> groupData, Map<String, Object> node, String key) {
|
||||||
|
List<Map<String, Object>> treeNodeVos = groupData.get(node.get(key));
|
||||||
|
if (CollUtil.isEmpty(treeNodeVos)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return treeNodeVos.stream()
|
||||||
|
.peek(p -> p.put("children", children(groupData, p, key)))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成随机字符串
|
||||||
|
*
|
||||||
|
* @param len 长度
|
||||||
|
* @param fun 校验方法
|
||||||
|
*/
|
||||||
|
public static String generateCode(Integer len, Function<String, Boolean> fun) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
// 生成三位字符串
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
// 生成随机索引,范围是0到35(26个字母加10个数字)
|
||||||
|
int index = (int) (Math.random() * 36);
|
||||||
|
char ch;
|
||||||
|
if (index < 26) {
|
||||||
|
// 生成字母
|
||||||
|
ch = (char) ('a' + index); // 将索引转换为字母
|
||||||
|
} else {
|
||||||
|
// 生成数字
|
||||||
|
ch = (char) ('0' + (index - 26)); // 将索引转换为数字
|
||||||
|
}
|
||||||
|
sb.append(ch); // 将生成的字符添加到字符串中
|
||||||
|
}
|
||||||
|
String result = sb.toString();
|
||||||
|
boolean b = fun.apply(result);
|
||||||
|
if (b) {
|
||||||
|
result = generateCode(len, fun);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成随机字符串
|
||||||
|
*
|
||||||
|
* @param fun 校验方法
|
||||||
|
*/
|
||||||
|
public static String generateCode(Function<String, Boolean> fun) {
|
||||||
|
return generateCode(3, fun);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (o == null || getClass() != o.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
TreeNodeVo<?> that = (TreeNodeVo<?>) o;
|
||||||
|
return Objects.equals(value, that.value) && Objects.equals(label, that.label);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(value, label);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.changhu.common.properties;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: some...
|
||||||
|
* createTime: 2023/12/15 10:43
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Component
|
||||||
|
@ConfigurationProperties(prefix = "project.fastjson2")
|
||||||
|
public class Fastjson2Properties {
|
||||||
|
private String dateFormat;
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.changhu.common.properties;
|
||||||
|
|
||||||
|
import com.changhu.common.db.BaseEnum;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: some...
|
||||||
|
* createTime: 2023/11/29 15:34
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum ProjectEnv implements BaseEnum<String> {
|
||||||
|
|
||||||
|
DEV("开发环境", "dev"),
|
||||||
|
PROD("生产环境", "prod");
|
||||||
|
|
||||||
|
private final String label;
|
||||||
|
private final String value;
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.changhu.common.properties;
|
||||||
|
|
||||||
|
import com.changhu.common.exception.MessageException;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: some...
|
||||||
|
* createTime: 2023/11/29 15:42
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Data
|
||||||
|
@Component
|
||||||
|
@ConfigurationProperties(prefix = "project")
|
||||||
|
public class ProjectProperties {
|
||||||
|
/**
|
||||||
|
* 项目运行环境
|
||||||
|
*/
|
||||||
|
private ProjectEnv env;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ProjectEnv projectEnv() {
|
||||||
|
if (env == null) {
|
||||||
|
throw new MessageException("当前环境没有配置【projectEnv】请配置");
|
||||||
|
}
|
||||||
|
log.info("当前运行环境:【{} ({})】", env.getValue(), env.getLabel());
|
||||||
|
return env;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.changhu.common.properties;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: some...
|
||||||
|
* createTime: 2023/12/15 10:46
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Component
|
||||||
|
@ConfigurationProperties(prefix = "project.thread-pool")
|
||||||
|
public class ThreadProperties {
|
||||||
|
/**
|
||||||
|
* 线程名字前缀
|
||||||
|
*/
|
||||||
|
private String threadNamePrefix;
|
||||||
|
/**
|
||||||
|
* 核心线程数
|
||||||
|
*/
|
||||||
|
private Integer corePoolSize;
|
||||||
|
/**
|
||||||
|
* 最大线程数
|
||||||
|
*/
|
||||||
|
private Integer maxPoolSize;
|
||||||
|
/**
|
||||||
|
* 阻塞队列容量
|
||||||
|
*/
|
||||||
|
private Integer queueCapacity;
|
||||||
|
/**
|
||||||
|
* 空闲线程存活时间
|
||||||
|
*/
|
||||||
|
private Integer keepAliveSeconds;
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package com.changhu.common.utils;
|
||||||
|
|
||||||
|
import cn.hutool.crypto.Mode;
|
||||||
|
import cn.hutool.crypto.Padding;
|
||||||
|
import cn.hutool.crypto.symmetric.AES;
|
||||||
|
import cn.hutool.setting.Setting;
|
||||||
|
import cn.hutool.setting.SettingUtil;
|
||||||
|
import com.changhu.common.enums.ResultCode;
|
||||||
|
import com.changhu.common.exception.MessageException;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: 加密解密工具
|
||||||
|
* createTime: 2023/8/19 12:21
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class AesUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置文件
|
||||||
|
*/
|
||||||
|
private static final Setting setting = SettingUtil.get("aes");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AES实例
|
||||||
|
*/
|
||||||
|
private static final AES aes = new AES(
|
||||||
|
Mode.CBC,
|
||||||
|
Padding.PKCS5Padding,
|
||||||
|
setting.getStr("secretKey").getBytes(StandardCharsets.UTF_8),
|
||||||
|
setting.getStr("secretIv").getBytes(StandardCharsets.UTF_8)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加密 明文 -> 密文
|
||||||
|
*
|
||||||
|
* @param text 加密字符串
|
||||||
|
* @return 加密的结果
|
||||||
|
*/
|
||||||
|
public static String encrypt(String text) {
|
||||||
|
try {
|
||||||
|
return aes.encryptHex(text);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("加密失败: {}", e.getMessage());
|
||||||
|
throw new MessageException(ResultCode.ENCIPHER_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解密: 密文 -> 明文
|
||||||
|
*/
|
||||||
|
public static String decrypt(String cipherString) {
|
||||||
|
try {
|
||||||
|
return aes.decryptStr(cipherString);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("解密失败: {}", e.getMessage());
|
||||||
|
throw new MessageException(ResultCode.DECRYPT_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.changhu.common.utils;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: some...
|
||||||
|
* createTime: 2023/12/26 15:49
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class IpUtil {
|
||||||
|
|
||||||
|
public static String getIp(HttpServletRequest request) {
|
||||||
|
String ipAddress;
|
||||||
|
try {
|
||||||
|
ipAddress = request.getHeader("x-forwarded-for");
|
||||||
|
if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
|
||||||
|
ipAddress = request.getHeader("Proxy-Client-IP");
|
||||||
|
}
|
||||||
|
if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
|
||||||
|
ipAddress = request.getHeader("WL-Proxy-Client-IP");
|
||||||
|
}
|
||||||
|
if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
|
||||||
|
ipAddress = request.getRemoteAddr();
|
||||||
|
if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) {
|
||||||
|
try {
|
||||||
|
ipAddress = InetAddress.getLocalHost().getHostAddress();
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
log.error("未知的host:{}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
|
||||||
|
if (ipAddress != null) {
|
||||||
|
if (ipAddress.contains(",")) {
|
||||||
|
return ipAddress.split(",")[0];
|
||||||
|
} else {
|
||||||
|
return ipAddress;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("ip获取失败:{}", e.getMessage());
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
package com.changhu.common.utils;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 20252
|
||||||
|
* @createTime 2024/8/5 下午4:11
|
||||||
|
* @desc JavaClassToTsUtils...
|
||||||
|
*/
|
||||||
|
public class JavaClassToTsUtil {
|
||||||
|
|
||||||
|
public static <T> String parse(Class<T> tClass) {
|
||||||
|
//类名字
|
||||||
|
StringBuilder tsInterface = new StringBuilder("interface " + tClass.getSimpleName() + " {");
|
||||||
|
//获取class所有属性
|
||||||
|
Field[] fields = tClass.getDeclaredFields();
|
||||||
|
|
||||||
|
for (Field field : fields) {
|
||||||
|
tsInterface
|
||||||
|
.append("\n\t")
|
||||||
|
.append("/** ")
|
||||||
|
.append(field.getAnnotation(Schema.class) != null ? field.getAnnotation(Schema.class).description() : field.getName())
|
||||||
|
.append(" **/")
|
||||||
|
.append("\n\t")
|
||||||
|
.append(field.getName())
|
||||||
|
.append(isMust(field) ? "" : "?")
|
||||||
|
.append(":")
|
||||||
|
.append(convertJavaTypeToTS(field.getType()))
|
||||||
|
.append(";");
|
||||||
|
}
|
||||||
|
return tsInterface
|
||||||
|
.append("\n")
|
||||||
|
.append("}")
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将Java类型转化未ts类型
|
||||||
|
*
|
||||||
|
* @param type Java类型
|
||||||
|
* @return ts类型
|
||||||
|
*/
|
||||||
|
private static String convertJavaTypeToTS(Class<?> type) {
|
||||||
|
Set<Class<?>> stringList = Set.of(String.class);
|
||||||
|
Set<Class<?>> boolList = Set.of(Boolean.class, boolean.class);
|
||||||
|
Set<Class<?>> numberList = Set.of(
|
||||||
|
Integer.class, int.class,
|
||||||
|
Double.class, double.class,
|
||||||
|
Float.class, float.class,
|
||||||
|
Long.class, long.class,
|
||||||
|
Short.class, short.class,
|
||||||
|
BigDecimal.class,
|
||||||
|
Byte.class, byte.class
|
||||||
|
);
|
||||||
|
Set<Class<?>> dateList = Set.of(LocalDateTime.class, LocalDate.class, LocalTime.class);
|
||||||
|
if (stringList.contains(type)) {
|
||||||
|
return "string";
|
||||||
|
} else if (boolList.contains(type)) {
|
||||||
|
return "boolean";
|
||||||
|
} else if (numberList.contains(type)) {
|
||||||
|
return "number";
|
||||||
|
} else if (dateList.contains(type)) {
|
||||||
|
return "Dayjs";
|
||||||
|
} else {
|
||||||
|
return "unsupported";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查字段是否必须
|
||||||
|
*
|
||||||
|
* @param field 字段
|
||||||
|
* @return 是否必须
|
||||||
|
*/
|
||||||
|
private static boolean isMust(Field field) {
|
||||||
|
return Stream.of(
|
||||||
|
NotNull.class,
|
||||||
|
NotEmpty.class,
|
||||||
|
NotBlank.class
|
||||||
|
).anyMatch(field::isAnnotationPresent);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package com.changhu.common.utils;
|
||||||
|
|
||||||
|
import cn.hutool.crypto.asymmetric.KeyType;
|
||||||
|
import cn.hutool.crypto.asymmetric.RSA;
|
||||||
|
import cn.hutool.setting.Setting;
|
||||||
|
import cn.hutool.setting.SettingUtil;
|
||||||
|
import com.changhu.common.enums.ResultCode;
|
||||||
|
import com.changhu.common.exception.MessageException;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 20252
|
||||||
|
* @createTime 2024/8/20 下午4:57
|
||||||
|
* @desc rsa加密工具类
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class RsaUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rsa密钥配置文件
|
||||||
|
*/
|
||||||
|
private static final Setting setting = SettingUtil.get("rsa");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rsa实例
|
||||||
|
*/
|
||||||
|
private static final RSA rsa = new RSA(setting.getStr("privateKey"), setting.getStr("publicKey"));
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过公钥进行加密
|
||||||
|
*
|
||||||
|
* @param text 需要加密的密码
|
||||||
|
* @return 加密的结果
|
||||||
|
*/
|
||||||
|
public static String encipher(String text) {
|
||||||
|
try {
|
||||||
|
return rsa.encryptHex(text, KeyType.PublicKey);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("加密失败: {}", e.getMessage());
|
||||||
|
throw new MessageException(ResultCode.ENCIPHER_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过私钥解密
|
||||||
|
*
|
||||||
|
* @param encryptedString 加密后的字符串
|
||||||
|
* @return 解密后的结果
|
||||||
|
*/
|
||||||
|
public static String decrypt(String encryptedString) {
|
||||||
|
try {
|
||||||
|
return rsa.decryptStr(encryptedString, KeyType.PrivateKey);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("解码失败: {}", e.getMessage());
|
||||||
|
throw new MessageException(ResultCode.DECRYPT_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
RSA rs = new RSA();
|
||||||
|
System.out.println(rs.getPublicKeyBase64());
|
||||||
|
System.out.println(rs.getPrivateKeyBase64());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.changhu.common.utils;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Snowflake;
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: SnowFlakeIdUtil
|
||||||
|
* createTime: 2023/8/16 17:33
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class SnowFlakeIdUtil {
|
||||||
|
|
||||||
|
//todo 暂时先固定靶
|
||||||
|
private static final Snowflake snowflake = IdUtil.getSnowflake(1, 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统默认雪花id生成
|
||||||
|
*
|
||||||
|
* @return 雪花id
|
||||||
|
*/
|
||||||
|
public static synchronized long snowflakeId() {
|
||||||
|
return snowflake.nextId();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定生成雪花id
|
||||||
|
*
|
||||||
|
* @param workerId 机器id
|
||||||
|
* @param datacenterId 数据中心id
|
||||||
|
* @return 雪花id
|
||||||
|
*/
|
||||||
|
public static synchronized long snowflakeId(long workerId, long datacenterId) {
|
||||||
|
return IdUtil.getSnowflake(workerId, datacenterId).nextId();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,122 @@
|
||||||
|
package com.changhu.common.utils;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.stp.SaTokenInfo;
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.crypto.SecureUtil;
|
||||||
|
import com.changhu.common.enums.ResultCode;
|
||||||
|
import com.changhu.common.exception.MessageException;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: some...
|
||||||
|
* createTime: 2023/12/15 11:30
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class UserUtil {
|
||||||
|
|
||||||
|
public static final String DEFAULT_PASSWORD = "123456";
|
||||||
|
|
||||||
|
public static final Long ERROR_USER_ID = -1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户登录 保存信息
|
||||||
|
*
|
||||||
|
* @param userId 用户id
|
||||||
|
*/
|
||||||
|
public static void login(Long userId) {
|
||||||
|
StpUtil.login(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录并且返回SaTokenInfo
|
||||||
|
*
|
||||||
|
* @param userId 用户id
|
||||||
|
* @return SaTokenInfo
|
||||||
|
*/
|
||||||
|
public static SaTokenInfo loginAndTokenInfo(Long userId) {
|
||||||
|
login(userId);
|
||||||
|
return getTokenInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户登出
|
||||||
|
*/
|
||||||
|
public static void logout() {
|
||||||
|
StpUtil.logout();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户id
|
||||||
|
*/
|
||||||
|
public static Long getUserId() {
|
||||||
|
return StpUtil.getLoginIdAsLong();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前用户token
|
||||||
|
*
|
||||||
|
* @return token
|
||||||
|
*/
|
||||||
|
public static String getToken() {
|
||||||
|
return StpUtil.getTokenValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据token获取id
|
||||||
|
*
|
||||||
|
* @param token token
|
||||||
|
* @return id
|
||||||
|
*/
|
||||||
|
public static Long getUserIdByToken(String token) {
|
||||||
|
return Long.parseLong(Optional.ofNullable(StpUtil.getLoginIdByToken(token))
|
||||||
|
.map(Object::toString)
|
||||||
|
.orElseThrow(() -> new MessageException(ResultCode.NOT_TOKEN)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取token信息
|
||||||
|
*
|
||||||
|
* @return token信息
|
||||||
|
*/
|
||||||
|
public static SaTokenInfo getTokenInfo() {
|
||||||
|
return StpUtil.getTokenInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加密明文密码
|
||||||
|
*
|
||||||
|
* @param plainTextPassWord 明文密码
|
||||||
|
* @return 盐 + 加密后的密码
|
||||||
|
*/
|
||||||
|
public static String passWordEncrypt(String plainTextPassWord) {
|
||||||
|
//随机盐值
|
||||||
|
String salt = IdUtil.simpleUUID();
|
||||||
|
//生成密文密码
|
||||||
|
String ciphertextPassWord = SecureUtil.md5(salt + plainTextPassWord);
|
||||||
|
return salt + "$$" + ciphertextPassWord;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解密密码 校验密码是否正确
|
||||||
|
*
|
||||||
|
* @param plainTextPassWord 明文密码
|
||||||
|
* @param salt 盐
|
||||||
|
* @param ciphertextPassWord 密文密码
|
||||||
|
* @return 比对结果
|
||||||
|
*/
|
||||||
|
public static boolean verifyPassWord(String plainTextPassWord, String salt, String ciphertextPassWord) {
|
||||||
|
boolean result = false;
|
||||||
|
if (StrUtil.isAllNotEmpty(plainTextPassWord, salt, ciphertextPassWord)) {
|
||||||
|
// 使用同样的加密算法和随机盐值生成最终加密的密码
|
||||||
|
if (StrUtil.equals(SecureUtil.md5(salt + plainTextPassWord), ciphertextPassWord)) {
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.changhu.common.utils;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import com.changhu.common.exception.MessageException;
|
||||||
|
import jakarta.validation.ConstraintViolation;
|
||||||
|
import jakarta.validation.Validation;
|
||||||
|
import jakarta.validation.Validator;
|
||||||
|
import jakarta.validation.ValidatorFactory;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: ValidatorUtil
|
||||||
|
* createTime: 2023/8/22 9:39
|
||||||
|
*/
|
||||||
|
public class ValidatorUtil {
|
||||||
|
/**
|
||||||
|
* 手动校验
|
||||||
|
*/
|
||||||
|
public static <T> void manual(T params) {
|
||||||
|
try (ValidatorFactory vf = Validation.buildDefaultValidatorFactory()) {
|
||||||
|
Validator validator = vf.getValidator();
|
||||||
|
Set<ConstraintViolation<T>> validateResult = validator.validate(params);
|
||||||
|
if (CollUtil.isNotEmpty(validateResult)) {
|
||||||
|
String errMessage = validateResult.stream().map(ConstraintViolation::getMessage).collect(Collectors.joining(","));
|
||||||
|
throw new MessageException(errMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package com.changhu.common.validator;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Validator;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.changhu.common.validator.annotation.IdCard;
|
||||||
|
import jakarta.validation.ConstraintValidator;
|
||||||
|
import jakarta.validation.ConstraintValidatorContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 20252
|
||||||
|
* @createTime 2024/8/21 下午3:41
|
||||||
|
* @desc IdCardValidator...
|
||||||
|
*/
|
||||||
|
public class IdCardValidator implements ConstraintValidator<IdCard, String> {
|
||||||
|
|
||||||
|
private boolean required;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize(IdCard constraintAnnotation) {
|
||||||
|
required = constraintAnnotation.required();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValid(String value, ConstraintValidatorContext context) {
|
||||||
|
if (required) {
|
||||||
|
return Validator.isCitizenId(value);
|
||||||
|
} else {
|
||||||
|
if (StrUtil.isBlank(value)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return Validator.isCitizenId(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.changhu.common.validator;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Validator;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.changhu.common.utils.ValidatorUtil;
|
||||||
|
import com.changhu.common.validator.annotation.IsMobile;
|
||||||
|
import jakarta.validation.ConstraintValidator;
|
||||||
|
import jakarta.validation.ConstraintValidatorContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: IsMobileValidator
|
||||||
|
* createTime: 2023/8/22 9:38
|
||||||
|
*/
|
||||||
|
public class IsMobileValidator implements ConstraintValidator<IsMobile, String> {
|
||||||
|
private boolean required;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize(IsMobile constraintAnnotation) {
|
||||||
|
//初始化时先获取他是否为必填信息
|
||||||
|
required = constraintAnnotation.required();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
|
||||||
|
if (required) {
|
||||||
|
//必填则校验手机号
|
||||||
|
return Validator.isMobile(s);
|
||||||
|
} else {
|
||||||
|
//非必填直接返回ture
|
||||||
|
if (StrUtil.isBlank(s)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return Validator.isMobile(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
package com.changhu.common.validator;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.NumberUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.changhu.common.validator.annotation.OnlyInValue;
|
||||||
|
import jakarta.validation.ConstraintValidator;
|
||||||
|
import jakarta.validation.ConstraintValidatorContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: OnlyInValueValidator
|
||||||
|
* createTime: 2023/8/22 9:40
|
||||||
|
*/
|
||||||
|
public class OnlyInValueValidator implements ConstraintValidator<OnlyInValue, Object> {
|
||||||
|
private boolean required = false;
|
||||||
|
private String[] strValues;
|
||||||
|
private int[] intValues;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize(OnlyInValue constraintAnnotation) {
|
||||||
|
required = constraintAnnotation.required();
|
||||||
|
strValues = constraintAnnotation.strValues();
|
||||||
|
intValues = constraintAnnotation.intValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValid(Object value, ConstraintValidatorContext context) {
|
||||||
|
if (required) {
|
||||||
|
return valid(value);
|
||||||
|
} else {
|
||||||
|
if (ObjectUtil.isNull(value)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return valid(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean valid(Object value) {
|
||||||
|
if (value instanceof String) {
|
||||||
|
for (String str : strValues) {
|
||||||
|
if (StrUtil.equals(str, value + "")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (value instanceof Integer) {
|
||||||
|
for (int num : intValues) {
|
||||||
|
if (NumberUtil.equals(num, (int) value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.changhu.common.validator.annotation;
|
||||||
|
|
||||||
|
import com.changhu.common.validator.IdCardValidator;
|
||||||
|
import jakarta.validation.Constraint;
|
||||||
|
import jakarta.validation.Payload;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
|
||||||
|
import static java.lang.annotation.ElementType.CONSTRUCTOR;
|
||||||
|
import static java.lang.annotation.ElementType.FIELD;
|
||||||
|
import static java.lang.annotation.ElementType.METHOD;
|
||||||
|
import static java.lang.annotation.ElementType.PARAMETER;
|
||||||
|
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||||
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 20252
|
||||||
|
* @createTime 2024/8/21 下午3:34
|
||||||
|
* @desc IdCard...
|
||||||
|
*/
|
||||||
|
@Documented
|
||||||
|
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
|
||||||
|
@Retention(RUNTIME)
|
||||||
|
@Constraint(validatedBy = {IdCardValidator.class})
|
||||||
|
public @interface IdCard {
|
||||||
|
boolean required() default true;
|
||||||
|
|
||||||
|
String message() default "身份证格式错误!";
|
||||||
|
|
||||||
|
Class<?>[] groups() default {};
|
||||||
|
|
||||||
|
Class<? extends Payload>[] payload() default {};
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.changhu.common.validator.annotation;
|
||||||
|
|
||||||
|
import com.changhu.common.validator.IsMobileValidator;
|
||||||
|
import jakarta.validation.Constraint;
|
||||||
|
import jakarta.validation.Payload;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: IsMobile
|
||||||
|
* createTime: 2023/8/22 9:38
|
||||||
|
*/
|
||||||
|
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Constraint(validatedBy = {IsMobileValidator.class})
|
||||||
|
public @interface IsMobile {
|
||||||
|
boolean required() default true;
|
||||||
|
|
||||||
|
String message() default "手机号码格式错误!";
|
||||||
|
|
||||||
|
Class<?>[] groups() default {};
|
||||||
|
|
||||||
|
Class<? extends Payload>[] payload() default {};
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.changhu.common.validator.annotation;
|
||||||
|
|
||||||
|
import com.changhu.common.validator.OnlyInValueValidator;
|
||||||
|
import jakarta.validation.Constraint;
|
||||||
|
import jakarta.validation.Payload;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: 只能为定义的值 比如[1,0]
|
||||||
|
* createTime: 2023/8/22 9:41
|
||||||
|
*/
|
||||||
|
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Constraint(
|
||||||
|
validatedBy = {
|
||||||
|
OnlyInValueValidator.class
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public @interface OnlyInValue {
|
||||||
|
boolean required() default true;
|
||||||
|
|
||||||
|
String message() default "必须为指定值";
|
||||||
|
|
||||||
|
String[] strValues() default {};
|
||||||
|
|
||||||
|
int[] intValues() default {};
|
||||||
|
|
||||||
|
Class<?>[] groups() default {};
|
||||||
|
|
||||||
|
Class<? extends Payload>[] payload() default {};
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package com.changhu.config;
|
||||||
|
|
||||||
|
import com.changhu.common.properties.ThreadProperties;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.scheduling.annotation.EnableAsync;
|
||||||
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||||
|
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: 线程池配置
|
||||||
|
* createTime: 2023/8/23 18:12
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Configuration
|
||||||
|
@EnableAsync
|
||||||
|
public class ThreadPollConfig {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ThreadProperties threadProperties;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
|
||||||
|
|
||||||
|
log.info("已加载 【{}】 的配置 【{}】:", "线 程 池", threadProperties);
|
||||||
|
|
||||||
|
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
|
||||||
|
// 配置核心线程数
|
||||||
|
threadPoolTaskExecutor.setCorePoolSize(threadProperties.getCorePoolSize());
|
||||||
|
// 配置最大线程数
|
||||||
|
threadPoolTaskExecutor.setMaxPoolSize(threadProperties.getMaxPoolSize());
|
||||||
|
// 配置队列大小
|
||||||
|
threadPoolTaskExecutor.setQueueCapacity(threadProperties.getQueueCapacity());
|
||||||
|
// 配置存活时间
|
||||||
|
threadPoolTaskExecutor.setKeepAliveSeconds(threadProperties.getKeepAliveSeconds());
|
||||||
|
// 配置线程池中的线程的名称前缀
|
||||||
|
threadPoolTaskExecutor.setThreadNamePrefix(threadProperties.getThreadNamePrefix());
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rejection-policy:当pool已经达到max size的时候,如何处理新任务?
|
||||||
|
* 1.ThreadPoolExecutor.AbortPolicy 丢弃任务并抛出RejectedExecutionException异常(默认)。
|
||||||
|
* 2.ThreadPoolExecutor.DiscardPolicy 丢弃任务,但是不抛出异常。
|
||||||
|
* 3.ThreadPoolExecutor.DiscardOldestPolicy 丢弃队列最前面的任务,然后重新尝试执行任务
|
||||||
|
* 4.ThreadPoolExecutor.CallerRunsPolicy 由调用线程处理该任务
|
||||||
|
*/
|
||||||
|
threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
|
||||||
|
// 执行初始化
|
||||||
|
threadPoolTaskExecutor.initialize();
|
||||||
|
return threadPoolTaskExecutor;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package com.changhu.config;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.interceptor.SaInterceptor;
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import com.changhu.support.interceptor.JsonBodyInterceptor;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* author: luozhun
|
||||||
|
* desc: WebConfig
|
||||||
|
* createTime: 2023/8/18 10:56
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class WebConfig implements WebMvcConfigurer {
|
||||||
|
|
||||||
|
private final List<String> whiteList = new ArrayList<>();
|
||||||
|
|
||||||
|
public WebConfig() {
|
||||||
|
whiteList.add("/managementSuperUser/**");
|
||||||
|
whiteList.add("/common/**");
|
||||||
|
whiteList.add("/test/**");
|
||||||
|
whiteList.add("/login");
|
||||||
|
whiteList.add("/logout");
|
||||||
|
whiteList.add("/favicon.ico");
|
||||||
|
//druid console
|
||||||
|
whiteList.add("/druid/**");
|
||||||
|
//knife4j
|
||||||
|
whiteList.add("/doc.html/**");
|
||||||
|
whiteList.add("/static/**");
|
||||||
|
whiteList.add("/swagger-resources");
|
||||||
|
whiteList.add("/**webjars/**");
|
||||||
|
whiteList.add("/v3/**");
|
||||||
|
//平台信息
|
||||||
|
whiteList.add("/platformSetting/getPlatformInfo");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addInterceptors(@NotNull InterceptorRegistry registry) {
|
||||||
|
// 注册 Sa-Token 拦截器,校验规则为 StpUtil.checkLogin() 登录校验。
|
||||||
|
registry.addInterceptor(new SaInterceptor(handle -> StpUtil.checkLogin()))
|
||||||
|
.addPathPatterns("/**")
|
||||||
|
.excludePathPatterns(whiteList);
|
||||||
|
// 注册jsonBody 拦截器 用于标识是否需要JsonResult返回
|
||||||
|
registry.addInterceptor(new JsonBodyInterceptor());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||||
|
registry.addResourceHandler("doc.html")
|
||||||
|
.addResourceLocations("classpath:/META-INF/resources/");
|
||||||
|
registry.addResourceHandler("swagger-ui.html")
|
||||||
|
.addResourceLocations("classpath:/META-INF/resources/");
|
||||||
|
registry.addResourceHandler("/webjars/**")
|
||||||
|
.addResourceLocations("classpath:/META-INF/resources/webjars/");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.changhu.controller;
|
||||||
|
|
||||||
|
import com.changhu.common.annotation.JsonBody;
|
||||||
|
import com.changhu.common.pojo.vo.TokenInfo;
|
||||||
|
import com.changhu.pojo.params.LoginParams;
|
||||||
|
import com.changhu.service.LoginService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 20252
|
||||||
|
* @createTime 2024/8/28 下午5:12
|
||||||
|
* @desc LoginController...
|
||||||
|
*/
|
||||||
|
@JsonBody
|
||||||
|
public class LoginController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private LoginService loginService;
|
||||||
|
|
||||||
|
@PostMapping("/login")
|
||||||
|
public TokenInfo login(@RequestBody LoginParams loginParams) {
|
||||||
|
return loginService.login(loginParams);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.changhu.enums;
|
||||||
|
|
||||||
|
import com.changhu.enums.handler.AbstractLoginHandler;
|
||||||
|
import com.changhu.enums.handler.ManagementSuperLogin;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 20252
|
||||||
|
* @createTime 2024/8/28 下午5:19
|
||||||
|
* @desc ClientType...
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum ClientType {
|
||||||
|
MANAGEMENT_SUPER("management_super", "超级后台", ManagementSuperLogin.instance),
|
||||||
|
MANAGEMENT_POLICE("management_police", "公安后台", ManagementSuperLogin.instance),
|
||||||
|
MANAGEMENT_SECURITY("management_security", "保安后台", ManagementSuperLogin.instance),
|
||||||
|
MINI_PROGRAM("mini_program", "微信小程序", ManagementSuperLogin.instance),
|
||||||
|
;
|
||||||
|
|
||||||
|
private final String value;
|
||||||
|
private final String remark;
|
||||||
|
private final AbstractLoginHandler loginHandler;
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.changhu.enums.handler;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.changhu.common.pojo.vo.TokenInfo;
|
||||||
|
import org.apache.poi.ss.formula.functions.T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 20252
|
||||||
|
* @createTime 2024/8/28 下午5:24
|
||||||
|
* @desc AbstractLoginHandler...
|
||||||
|
*/
|
||||||
|
public abstract class AbstractLoginHandler {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统一登录方法
|
||||||
|
*
|
||||||
|
* @param jsonObject 登录参数
|
||||||
|
* @return token
|
||||||
|
*/
|
||||||
|
public abstract TokenInfo login(JSONObject jsonObject);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.changhu.enums.handler;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.stp.SaTokenInfo;
|
||||||
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.changhu.common.enums.ResultCode;
|
||||||
|
import com.changhu.common.exception.MessageException;
|
||||||
|
import com.changhu.common.pojo.vo.TokenInfo;
|
||||||
|
import com.changhu.common.utils.RsaUtil;
|
||||||
|
import com.changhu.common.utils.UserUtil;
|
||||||
|
import com.changhu.common.utils.ValidatorUtil;
|
||||||
|
import com.changhu.module.management.pojo.entity.ManagementSuperUser;
|
||||||
|
import com.changhu.module.management.service.ManagementSuperUserService;
|
||||||
|
import com.changhu.pojo.params.ManagementSuperLoginParams;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 20252
|
||||||
|
* @createTime 2024/8/28 下午5:25
|
||||||
|
* @desc ManagementSuperLogin...
|
||||||
|
*/
|
||||||
|
public class ManagementSuperLogin extends AbstractLoginHandler {
|
||||||
|
|
||||||
|
private static final ManagementSuperUserService managementSuperUserService = SpringUtil.getBean(ManagementSuperUserService.class);
|
||||||
|
|
||||||
|
public static final ManagementSuperLogin instance = new ManagementSuperLogin();
|
||||||
|
|
||||||
|
private ManagementSuperLogin() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TokenInfo login(JSONObject jsonObject) {
|
||||||
|
ManagementSuperLoginParams loginParams = jsonObject.to(ManagementSuperLoginParams.class);
|
||||||
|
ValidatorUtil.manual(loginParams);
|
||||||
|
String telephone = loginParams.getTelephone();
|
||||||
|
String password = RsaUtil.decrypt(loginParams.getPassword());
|
||||||
|
|
||||||
|
//用户是否存在
|
||||||
|
ManagementSuperUser user = managementSuperUserService.lambdaQuery()
|
||||||
|
.eq(ManagementSuperUser::getTelephone, telephone)
|
||||||
|
.oneOpt()
|
||||||
|
.orElseThrow(() -> new MessageException("用户不存在"));
|
||||||
|
|
||||||
|
//判断密码是否正确
|
||||||
|
if (!UserUtil.verifyPassWord(password, user.getSalt(), user.getPassword())) {
|
||||||
|
throw new MessageException(ResultCode.PASSWORD_ERROR);
|
||||||
|
}
|
||||||
|
//登录
|
||||||
|
SaTokenInfo saTokenInfo = UserUtil.loginAndTokenInfo(user.getSnowFlakeId());
|
||||||
|
//返回token
|
||||||
|
return new TokenInfo(saTokenInfo.getTokenName(), saTokenInfo.getTokenValue());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.changhu.module.management.controller;
|
||||||
|
|
||||||
|
import com.changhu.common.annotation.JsonBody;
|
||||||
|
import com.changhu.module.management.pojo.params.ManagementSuperUserSaveOrUpdateParams;
|
||||||
|
import com.changhu.module.management.service.ManagementSuperUserService;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 20252
|
||||||
|
* @createTime 2024/8/28 下午5:12
|
||||||
|
* @desc 超级后台用户控制器
|
||||||
|
*/
|
||||||
|
@Tag(name = "后台用户-超级后台")
|
||||||
|
@JsonBody
|
||||||
|
@RequestMapping("/managementSuperUser")
|
||||||
|
public class ManagementSuperUserController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ManagementSuperUserService managementSuperUserService;
|
||||||
|
|
||||||
|
@Operation(summary = "新增或保存")
|
||||||
|
@PostMapping("/saveOrUpdate")
|
||||||
|
public void saveOrUpdate(@RequestBody @Valid ManagementSuperUserSaveOrUpdateParams params) {
|
||||||
|
managementSuperUserService.saveOrUpdate(params);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
package com.changhu.module.management.controller;
|
||||||
|
|
||||||
|
import com.changhu.common.db.enums.IsOrNot;
|
||||||
|
import com.changhu.common.db.enums.DeleteFlag;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import com.changhu.common.db.enums.IsEnable;
|
||||||
|
import com.changhu.common.db.enums.Sex;
|
||||||
|
|
||||||
|
import com.changhu.common.annotation.JsonBody;
|
||||||
|
import com.changhu.module.management.pojo.entity.ManagementPoliceUnitUser;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 20252
|
||||||
|
* @createTime 2024/8/28 下午4:02
|
||||||
|
* @desc TestController...
|
||||||
|
*/
|
||||||
|
@JsonBody
|
||||||
|
@RequestMapping("/test")
|
||||||
|
public class TestController {
|
||||||
|
|
||||||
|
@GetMapping("/get")
|
||||||
|
public ManagementPoliceUnitUser get() {
|
||||||
|
ManagementPoliceUnitUser managementPoliceUnitUser = new ManagementPoliceUnitUser();
|
||||||
|
managementPoliceUnitUser.setPoliceUnitId(0L);
|
||||||
|
managementPoliceUnitUser.setName("");
|
||||||
|
managementPoliceUnitUser.setSex(Sex.MAN);
|
||||||
|
managementPoliceUnitUser.setTelephone("");
|
||||||
|
managementPoliceUnitUser.setSalt("");
|
||||||
|
managementPoliceUnitUser.setPassword("");
|
||||||
|
managementPoliceUnitUser.setIsEnable(IsEnable.TRUE);
|
||||||
|
managementPoliceUnitUser.setIsAdmin(IsOrNot.IS);
|
||||||
|
managementPoliceUnitUser.setSnowFlakeId(0L);
|
||||||
|
managementPoliceUnitUser.setCreateBy(0L);
|
||||||
|
managementPoliceUnitUser.setCreateTime(LocalDateTime.now());
|
||||||
|
managementPoliceUnitUser.setUpdateBy(0L);
|
||||||
|
managementPoliceUnitUser.setUpdateTime(LocalDateTime.now());
|
||||||
|
managementPoliceUnitUser.setDeleteFlag(0);
|
||||||
|
return managementPoliceUnitUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/de")
|
||||||
|
public void test(@RequestBody P p) {
|
||||||
|
System.out.println(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Data
|
||||||
|
class P {
|
||||||
|
private String name;
|
||||||
|
private DeleteFlag deleteFlag;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.changhu.module.management.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.changhu.module.management.pojo.entity.ManagementPoliceUnitUser;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* management_police_user (后台-公安单位用户表) 固化类
|
||||||
|
* author: luozhun
|
||||||
|
* desc 由groovy脚本自动生成
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface ManagementPoliceUserMapper extends BaseMapper<ManagementPoliceUnitUser> {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.changhu.module.management.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.changhu.module.management.pojo.entity.ManagementSecurityUnitUser;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* management_security_unit_user (后台-保安单位用户表) 固化类
|
||||||
|
* author: luozhun
|
||||||
|
* desc 由groovy脚本自动生成
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface ManagementSecurityUnitUserMapper extends BaseMapper<ManagementSecurityUnitUser> {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.changhu.module.management.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.changhu.module.management.pojo.entity.ManagementSuperUser;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* management_super_user (后台-超级后台) 固化类
|
||||||
|
* author: luozhun
|
||||||
|
* desc 由groovy脚本自动生成
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface ManagementSuperUserMapper extends BaseMapper<ManagementSuperUser> {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
package com.changhu.module.management.pojo.entity;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import com.changhu.common.db.enums.IsEnable;
|
||||||
|
import com.changhu.common.db.enums.IsOrNot;
|
||||||
|
import com.changhu.common.db.enums.Sex;
|
||||||
|
import com.changhu.support.mybatisplus.pojo.entity.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后台-公安单位用户表 实体类
|
||||||
|
* author: luozhun
|
||||||
|
* desc 由groovy脚本自动生成
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@SuperBuilder
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@TableName(autoResultMap = true)
|
||||||
|
public class ManagementPoliceUnitUser extends BaseEntity implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 所属公安机关id
|
||||||
|
*/
|
||||||
|
private Long policeUnitId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 性别
|
||||||
|
*/
|
||||||
|
private Sex sex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手机号
|
||||||
|
*/
|
||||||
|
private String telephone;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 盐值
|
||||||
|
*/
|
||||||
|
private String salt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 密码
|
||||||
|
*/
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用
|
||||||
|
*/
|
||||||
|
private IsEnable isEnable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否是超管
|
||||||
|
*/
|
||||||
|
private IsOrNot isAdmin;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
package com.changhu.module.management.pojo.entity;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import com.changhu.common.db.enums.IsEnable;
|
||||||
|
import com.changhu.common.db.enums.IsOrNot;
|
||||||
|
import com.changhu.common.db.enums.Sex;
|
||||||
|
import com.changhu.support.mybatisplus.pojo.entity.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后台-保安单位用户表 实体类
|
||||||
|
* author: luozhun
|
||||||
|
* desc 由groovy脚本自动生成
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@SuperBuilder
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@TableName(autoResultMap = true)
|
||||||
|
public class ManagementSecurityUnitUser extends BaseEntity implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 所属保安公司id
|
||||||
|
*/
|
||||||
|
private Long securityUnitId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 性别
|
||||||
|
*/
|
||||||
|
private Sex sex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手机号
|
||||||
|
*/
|
||||||
|
private String telephone;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 盐值
|
||||||
|
*/
|
||||||
|
private String salt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 密码
|
||||||
|
*/
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用
|
||||||
|
*/
|
||||||
|
private IsEnable isEnable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否是超管
|
||||||
|
*/
|
||||||
|
private IsOrNot isAdmin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package com.changhu.module.management.pojo.entity;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import com.changhu.common.db.enums.IsEnable;
|
||||||
|
import com.changhu.support.mybatisplus.pojo.entity.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后台-超级后台 实体类
|
||||||
|
* author: luozhun
|
||||||
|
* desc 由groovy脚本自动生成
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@SuperBuilder
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@TableName(autoResultMap = true)
|
||||||
|
public class ManagementSuperUser extends BaseEntity implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手机号
|
||||||
|
*/
|
||||||
|
private String telephone;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 盐值
|
||||||
|
*/
|
||||||
|
private String salt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 密码
|
||||||
|
*/
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用
|
||||||
|
*/
|
||||||
|
private IsEnable isEnable;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.changhu.module.management.pojo.params;
|
||||||
|
|
||||||
|
import com.changhu.common.validator.annotation.IsMobile;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 20252
|
||||||
|
* @createTime 2024/8/28 下午5:47
|
||||||
|
* @desc ManagementSuperUserSaveOrUpdateParams...
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ManagementSuperUserSaveOrUpdateParams {
|
||||||
|
|
||||||
|
@Schema(description = "id")
|
||||||
|
private Long snowFlakeId;
|
||||||
|
|
||||||
|
@Schema(description = "名称")
|
||||||
|
@NotNull(message = "用户名不能为空")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "手机号")
|
||||||
|
@IsMobile
|
||||||
|
private String telephone;
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.changhu.module.management.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.changhu.module.management.pojo.entity.ManagementPoliceUnitUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* management_police_user (后台-公安单位用户表) 服务类
|
||||||
|
* author: luozhun
|
||||||
|
* desc 由groovy脚本自动生成
|
||||||
|
*/
|
||||||
|
public interface ManagementPoliceUserService extends IService<ManagementPoliceUnitUser> {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.changhu.module.management.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.changhu.module.management.pojo.entity.ManagementSecurityUnitUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* management_security_unit_user (后台-保安单位用户表) 服务类
|
||||||
|
* author: luozhun
|
||||||
|
* desc 由groovy脚本自动生成
|
||||||
|
*/
|
||||||
|
public interface ManagementSecurityUnitUserService extends IService<ManagementSecurityUnitUser> {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.changhu.module.management.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.changhu.module.management.pojo.entity.ManagementSuperUser;
|
||||||
|
import com.changhu.module.management.pojo.params.ManagementSuperUserSaveOrUpdateParams;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* management_super_user (后台-超级后台) 服务类
|
||||||
|
* author: luozhun
|
||||||
|
* desc 由groovy脚本自动生成
|
||||||
|
*/
|
||||||
|
public interface ManagementSuperUserService extends IService<ManagementSuperUser> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增或保存
|
||||||
|
*
|
||||||
|
* @param params 参数
|
||||||
|
*/
|
||||||
|
void saveOrUpdate(ManagementSuperUserSaveOrUpdateParams params);
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue