Commit 2c62a85dc41d3433279a9b611ba9038fd410d417
1 parent
6228a7a5
前端代码分支
Showing
34 changed files
with
676 additions
and
760 deletions
.gitignore
@@ -29,4 +29,22 @@ build/ | @@ -29,4 +29,22 @@ build/ | ||
29 | .vscode/ | 29 | .vscode/ |
30 | 30 | ||
31 | ### Mac OS ### | 31 | ### Mac OS ### |
32 | -.DS_Store | ||
33 | \ No newline at end of file | 32 | \ No newline at end of file |
33 | +.DS_Store | ||
34 | + | ||
35 | +node_modules/ | ||
36 | +package-lock.json | ||
37 | +npm-debug.log* | ||
38 | +yarn-debug.log* | ||
39 | +yarn-error.log* | ||
40 | +tests/**/coverage/ | ||
41 | +./unpackage/dist/* | ||
42 | +.unpackage/dist/dev* | ||
43 | +unpackage/ | ||
44 | +.gitignore | ||
45 | +.hbuilderx | ||
46 | +*.sui | ||
47 | +*.ntvs* | ||
48 | +*.njsproj | ||
49 | +*.sln | ||
50 | +.tea | ||
51 | +helper.json |
README.md
1 | -**配置SN文件路径:** | ||
2 | -在resources下设置**application.properties**文件中的**SN.file.path**属性(该属性是存储SN的文件的路径,文件格式是txt,例:D:/temp/SN.txt) | ||
3 | -以及设置**SN.file.temp.path**属性(该属性是SN备份文件的路径,文件格式是txt,例:D:/temp/SNTemp.txt) | 1 | +# y |
4 | 2 | ||
5 | -**配置日志文件路径:** | ||
6 | -在resources下设置**log4j2.xml**文件中"Property name="baseDir" value="./log"/"标签内的value值(该值为存储日志文件的文件夹路径,例:D:/temp/log) | 3 | +This template should help get you started developing with Vue 3 in Vite. |
4 | + | ||
5 | +## Recommended IDE Setup | ||
6 | + | ||
7 | +[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin). | ||
8 | + | ||
9 | +## Customize configuration | ||
10 | + | ||
11 | +See [Vite Configuration Reference](https://vitejs.dev/config/). | ||
12 | + | ||
13 | +## Project Setup | ||
14 | + | ||
15 | +```sh | ||
16 | +npm install | ||
17 | +``` | ||
18 | + | ||
19 | +### Compile and Hot-Reload for Development | ||
20 | + | ||
21 | +```sh | ||
22 | +npm run dev | ||
23 | +``` | ||
24 | + | ||
25 | +### Compile and Minify for Production | ||
26 | + | ||
27 | +```sh | ||
28 | +npm run build | ||
29 | +``` |
index.html
0 → 100644
1 | +<!DOCTYPE html> | ||
2 | +<html lang="en"> | ||
3 | + <head> | ||
4 | + <meta charset="UTF-8"> | ||
5 | + <link rel="icon" href="/favicon.ico"> | ||
6 | + <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
7 | + <title>Vite App</title> | ||
8 | + </head> | ||
9 | + <body> | ||
10 | + <div id="app"></div> | ||
11 | + <script type="module" src="/src/main.js"></script> | ||
12 | + </body> | ||
13 | +</html> |
package.json
0 → 100644
1 | +{ | ||
2 | + "name": "y", | ||
3 | + "version": "0.0.0", | ||
4 | + "private": true, | ||
5 | + "scripts": { | ||
6 | + "dev": "vite", | ||
7 | + "build": "vite build", | ||
8 | + "preview": "vite preview" | ||
9 | + }, | ||
10 | + "dependencies": { | ||
11 | + "@element-plus/icons-vue": "^2.3.1", | ||
12 | + "axios": "^1.4.0", | ||
13 | + "element-plus": "^2.3.8", | ||
14 | + "js-cookie": "^3.0.5", | ||
15 | + "spark-md5": "^3.0.2", | ||
16 | + "vue": "^3.3.4", | ||
17 | + "vue-router": "^4.2.4" | ||
18 | + }, | ||
19 | + "devDependencies": { | ||
20 | + "@vitejs/plugin-vue": "^4.2.3", | ||
21 | + "vite": "^4.4.6" | ||
22 | + } | ||
23 | +} |
pom.xml deleted
1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
2 | -<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
3 | - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
4 | - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
5 | - <modelVersion>4.0.0</modelVersion> | ||
6 | - | ||
7 | - <groupId>com.ectrip</groupId> | ||
8 | - <artifactId>SNManage</artifactId> | ||
9 | - <version>1.0</version> | ||
10 | - | ||
11 | - <properties> | ||
12 | - | ||
13 | - </properties> | ||
14 | - | ||
15 | - | ||
16 | - <parent> | ||
17 | - <groupId>org.springframework.boot</groupId> | ||
18 | - <artifactId>spring-boot-starter-parent</artifactId> | ||
19 | - <version>2.3.1.RELEASE</version> | ||
20 | - <relativePath/> | ||
21 | - </parent> | ||
22 | - | ||
23 | - <dependencies> | ||
24 | - <!--springboot启动类依赖导入--> | ||
25 | - <dependency> | ||
26 | - <groupId>org.springframework.boot</groupId> | ||
27 | - <artifactId>spring-boot-starter-web</artifactId> | ||
28 | - </dependency> | ||
29 | - <!--junit5--> | ||
30 | - <dependency> | ||
31 | - <groupId>org.springframework.boot</groupId> | ||
32 | - <artifactId>spring-boot-starter-test</artifactId> | ||
33 | - <scope>test</scope> | ||
34 | - </dependency> | ||
35 | - <dependency> | ||
36 | - <groupId>io.springfox</groupId> | ||
37 | - <artifactId>springfox-swagger2</artifactId> | ||
38 | - <version>2.7.0</version> | ||
39 | - </dependency> | ||
40 | - <dependency> | ||
41 | - <groupId>io.springfox</groupId> | ||
42 | - <artifactId>springfox-swagger-ui</artifactId> | ||
43 | - <version>2.7.0</version> | ||
44 | - </dependency> | ||
45 | - <!--hutool工具类--> | ||
46 | - <dependency> | ||
47 | - <groupId>cn.hutool</groupId> | ||
48 | - <artifactId>hutool-http</artifactId> | ||
49 | - <version>4.1.14</version> | ||
50 | - </dependency> | ||
51 | - <!--validation--> | ||
52 | - <dependency> | ||
53 | - <groupId>org.springframework.boot</groupId> | ||
54 | - <artifactId>spring-boot-starter-validation</artifactId> | ||
55 | - </dependency> | ||
56 | - <dependency> | ||
57 | - <groupId>org.projectlombok</groupId> | ||
58 | - <artifactId>lombok</artifactId> | ||
59 | - <version>1.16.10</version> | ||
60 | - </dependency> | ||
61 | - <!--排除springboot自带的日志依赖--> | ||
62 | - <dependency> | ||
63 | - <groupId>org.springframework.boot</groupId> | ||
64 | - <artifactId>spring-boot-starter</artifactId> | ||
65 | - <exclusions> | ||
66 | - <exclusion> | ||
67 | - <groupId>org.springframework.boot</groupId> | ||
68 | - <artifactId>spring-boot-starter-logging</artifactId> | ||
69 | - </exclusion> | ||
70 | - </exclusions> | ||
71 | - </dependency> | ||
72 | - <!--导入log4j2日志依赖--> | ||
73 | - <dependency> | ||
74 | - <groupId>org.springframework.boot</groupId> | ||
75 | - <artifactId>spring-boot-starter-log4j2</artifactId> | ||
76 | - </dependency> | ||
77 | - | ||
78 | - | ||
79 | - </dependencies> | ||
80 | - | ||
81 | - <build> | ||
82 | - | ||
83 | - <resources> | ||
84 | - <resource> | ||
85 | - <directory>src/main/java</directory> | ||
86 | - <includes> | ||
87 | - <include>**/*.xml</include> | ||
88 | - </includes> | ||
89 | - </resource> | ||
90 | - <resource> | ||
91 | - <directory>src/main/resources</directory> | ||
92 | - <includes> | ||
93 | - <include>**/*.*</include> | ||
94 | - </includes> | ||
95 | - </resource> | ||
96 | - </resources> | ||
97 | - <plugins> | ||
98 | - <plugin> | ||
99 | - <groupId>org.springframework.boot</groupId> | ||
100 | - <artifactId>spring-boot-maven-plugin</artifactId> | ||
101 | - <executions> | ||
102 | - <execution> | ||
103 | - <goals> | ||
104 | - <goal>repackage</goal> | ||
105 | - </goals> | ||
106 | - </execution> | ||
107 | - </executions> | ||
108 | - </plugin> | ||
109 | - </plugins> | ||
110 | - </build> | ||
111 | - | ||
112 | -</project> | ||
113 | \ No newline at end of file | 0 | \ No newline at end of file |
public/config.js
0 → 100644
public/favicon.ico
0 → 100644
No preview for this file type
src/App.vue
0 → 100644
1 | +<script setup> | ||
2 | +import { RouterLink, RouterView } from 'vue-router' | ||
3 | + | ||
4 | +</script> | ||
5 | + | ||
6 | +<template> | ||
7 | + <!-- <HomeView></HomeView> --> | ||
8 | + | ||
9 | + <!-- <header> | ||
10 | + <img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125" /> | ||
11 | + | ||
12 | + <div class="wrapper"> | ||
13 | + <HelloWorld msg="You did it!" /> | ||
14 | + | ||
15 | + <nav> | ||
16 | + <RouterLink to="/">Home</RouterLink> | ||
17 | + <RouterLink to="/about">About</RouterLink> | ||
18 | + </nav> | ||
19 | + </div> | ||
20 | + </header> --> | ||
21 | + | ||
22 | + <el-menu | ||
23 | + default-active="1" | ||
24 | + class="el-menu-demo" | ||
25 | + mode="horizontal" | ||
26 | + background-color="#545c64" | ||
27 | + text-color="#fff" | ||
28 | + active-text-color="#ffd04b" | ||
29 | + | ||
30 | + > | ||
31 | + <!-- <el-menu-item index="1"> | ||
32 | + <RouterLink to="/">主页</RouterLink> | ||
33 | + </el-menu-item> --> | ||
34 | + <!-- <el-menu-item index="2"> | ||
35 | + <RouterLink to="/login.html">登录</RouterLink> | ||
36 | + </el-menu-item> --> | ||
37 | + | ||
38 | + | ||
39 | + </el-menu> | ||
40 | + | ||
41 | + | ||
42 | + <RouterView /> | ||
43 | +</template> | ||
44 | + | ||
45 | +<style scoped> | ||
46 | + | ||
47 | +</style> |
src/api/api.js
0 → 100644
1 | + | ||
2 | +const baseUrl = '/api'; | ||
3 | + | ||
4 | +export const addSNsApi = { | ||
5 | + method: 'post', | ||
6 | + url: baseUrl + '/sn/add_sn' | ||
7 | +} | ||
8 | + | ||
9 | +export const getSNsApi = { | ||
10 | + method: 'get', | ||
11 | + url: baseUrl + '/sn/get_sn' | ||
12 | +} | ||
13 | + | ||
14 | +export const deleteSNsApi = { | ||
15 | + method: 'post', | ||
16 | + url: baseUrl + '/sn/delete_sn' | ||
17 | +} | ||
18 | + |
src/assets/base.css
0 → 100644
1 | +/* color palette from <https://github.com/vuejs/theme> */ | ||
2 | +:root { | ||
3 | + --vt-c-white: #ffffff; | ||
4 | + --vt-c-white-soft: #f8f8f8; | ||
5 | + --vt-c-white-mute: #f2f2f2; | ||
6 | + | ||
7 | + --vt-c-black: #181818; | ||
8 | + --vt-c-black-soft: #222222; | ||
9 | + --vt-c-black-mute: #282828; | ||
10 | + | ||
11 | + --vt-c-indigo: #2c3e50; | ||
12 | + | ||
13 | + --vt-c-divider-light-1: rgba(60, 60, 60, 0.29); | ||
14 | + --vt-c-divider-light-2: rgba(60, 60, 60, 0.12); | ||
15 | + --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65); | ||
16 | + --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48); | ||
17 | + | ||
18 | + --vt-c-text-light-1: var(--vt-c-indigo); | ||
19 | + --vt-c-text-light-2: rgba(60, 60, 60, 0.66); | ||
20 | + --vt-c-text-dark-1: var(--vt-c-white); | ||
21 | + --vt-c-text-dark-2: rgba(235, 235, 235, 0.64); | ||
22 | +} | ||
23 | + | ||
24 | +/* semantic color variables for this project */ | ||
25 | +:root { | ||
26 | + --color-background: var(--vt-c-white); | ||
27 | + --color-background-soft: var(--vt-c-white-soft); | ||
28 | + --color-background-mute: var(--vt-c-white-mute); | ||
29 | + | ||
30 | + --color-border: var(--vt-c-divider-light-2); | ||
31 | + --color-border-hover: var(--vt-c-divider-light-1); | ||
32 | + | ||
33 | + --color-heading: var(--vt-c-text-light-1); | ||
34 | + --color-text: var(--vt-c-text-light-1); | ||
35 | + | ||
36 | + --section-gap: 160px; | ||
37 | +} | ||
38 | + | ||
39 | +@media (prefers-color-scheme: dark) { | ||
40 | + :root { | ||
41 | + --color-background: var(--vt-c-black); | ||
42 | + --color-background-soft: var(--vt-c-black-soft); | ||
43 | + --color-background-mute: var(--vt-c-black-mute); | ||
44 | + | ||
45 | + --color-border: var(--vt-c-divider-dark-2); | ||
46 | + --color-border-hover: var(--vt-c-divider-dark-1); | ||
47 | + | ||
48 | + --color-heading: var(--vt-c-text-dark-1); | ||
49 | + --color-text: var(--vt-c-text-dark-2); | ||
50 | + } | ||
51 | +} | ||
52 | + | ||
53 | +*, | ||
54 | +*::before, | ||
55 | +*::after { | ||
56 | + box-sizing: border-box; | ||
57 | + margin: 0; | ||
58 | + font-weight: normal; | ||
59 | +} | ||
60 | + | ||
61 | +body { | ||
62 | + min-height: 100vh; | ||
63 | + color: var(--color-text); | ||
64 | + background: var(--color-background); | ||
65 | + transition: color 0.5s, background-color 0.5s; | ||
66 | + line-height: 1.6; | ||
67 | + font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, | ||
68 | + Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; | ||
69 | + font-size: 15px; | ||
70 | + text-rendering: optimizeLegibility; | ||
71 | + -webkit-font-smoothing: antialiased; | ||
72 | + -moz-osx-font-smoothing: grayscale; | ||
73 | +} |
src/assets/logo.svg
0 → 100644
1 | +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg> |
src/assets/main.css
0 → 100644
1 | +@import './base.css'; | ||
2 | + | ||
3 | +#app { | ||
4 | + max-width: 1280px; | ||
5 | + margin: 0 auto; | ||
6 | + padding: 2rem; | ||
7 | + | ||
8 | + font-weight: normal; | ||
9 | +} | ||
10 | + | ||
11 | +a, | ||
12 | +.green { | ||
13 | + text-decoration: none; | ||
14 | + color: hsla(160, 100%, 37%, 1); | ||
15 | + transition: 0.4s; | ||
16 | +} | ||
17 | + | ||
18 | +@media (hover: hover) { | ||
19 | + a:hover { | ||
20 | + background-color: hsla(160, 100%, 37%, 0.2); | ||
21 | + } | ||
22 | +} | ||
23 | + | ||
24 | +@media (min-width: 1024px) { | ||
25 | + body { | ||
26 | + display: flex; | ||
27 | + place-items: center; | ||
28 | + } | ||
29 | + | ||
30 | + #app { | ||
31 | + display: grid; | ||
32 | + grid-template-columns: 1fr 1fr; | ||
33 | + padding: 0 2rem; | ||
34 | + } | ||
35 | +} |
src/components/icons/IconCommunity.vue
0 → 100644
1 | +<template> | ||
2 | + <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor"> | ||
3 | + <path | ||
4 | + d="M15 4a1 1 0 1 0 0 2V4zm0 11v-1a1 1 0 0 0-1 1h1zm0 4l-.707.707A1 1 0 0 0 16 19h-1zm-4-4l.707-.707A1 1 0 0 0 11 14v1zm-4.707-1.293a1 1 0 0 0-1.414 1.414l1.414-1.414zm-.707.707l-.707-.707.707.707zM9 11v-1a1 1 0 0 0-.707.293L9 11zm-4 0h1a1 1 0 0 0-1-1v1zm0 4H4a1 1 0 0 0 1.707.707L5 15zm10-9h2V4h-2v2zm2 0a1 1 0 0 1 1 1h2a3 3 0 0 0-3-3v2zm1 1v6h2V7h-2zm0 6a1 1 0 0 1-1 1v2a3 3 0 0 0 3-3h-2zm-1 1h-2v2h2v-2zm-3 1v4h2v-4h-2zm1.707 3.293l-4-4-1.414 1.414 4 4 1.414-1.414zM11 14H7v2h4v-2zm-4 0c-.276 0-.525-.111-.707-.293l-1.414 1.414C5.42 15.663 6.172 16 7 16v-2zm-.707 1.121l3.414-3.414-1.414-1.414-3.414 3.414 1.414 1.414zM9 12h4v-2H9v2zm4 0a3 3 0 0 0 3-3h-2a1 1 0 0 1-1 1v2zm3-3V3h-2v6h2zm0-6a3 3 0 0 0-3-3v2a1 1 0 0 1 1 1h2zm-3-3H3v2h10V0zM3 0a3 3 0 0 0-3 3h2a1 1 0 0 1 1-1V0zM0 3v6h2V3H0zm0 6a3 3 0 0 0 3 3v-2a1 1 0 0 1-1-1H0zm3 3h2v-2H3v2zm1-1v4h2v-4H4zm1.707 4.707l.586-.586-1.414-1.414-.586.586 1.414 1.414z" | ||
5 | + /> | ||
6 | + </svg> | ||
7 | +</template> |
src/components/icons/IconDocumentation.vue
0 → 100644
1 | +<template> | ||
2 | + <svg xmlns="http://www.w3.org/2000/svg" width="20" height="17" fill="currentColor"> | ||
3 | + <path | ||
4 | + d="M11 2.253a1 1 0 1 0-2 0h2zm-2 13a1 1 0 1 0 2 0H9zm.447-12.167a1 1 0 1 0 1.107-1.666L9.447 3.086zM1 2.253L.447 1.42A1 1 0 0 0 0 2.253h1zm0 13H0a1 1 0 0 0 1.553.833L1 15.253zm8.447.833a1 1 0 1 0 1.107-1.666l-1.107 1.666zm0-14.666a1 1 0 1 0 1.107 1.666L9.447 1.42zM19 2.253h1a1 1 0 0 0-.447-.833L19 2.253zm0 13l-.553.833A1 1 0 0 0 20 15.253h-1zm-9.553-.833a1 1 0 1 0 1.107 1.666L9.447 14.42zM9 2.253v13h2v-13H9zm1.553-.833C9.203.523 7.42 0 5.5 0v2c1.572 0 2.961.431 3.947 1.086l1.107-1.666zM5.5 0C3.58 0 1.797.523.447 1.42l1.107 1.666C2.539 2.431 3.928 2 5.5 2V0zM0 2.253v13h2v-13H0zm1.553 13.833C2.539 15.431 3.928 15 5.5 15v-2c-1.92 0-3.703.523-5.053 1.42l1.107 1.666zM5.5 15c1.572 0 2.961.431 3.947 1.086l1.107-1.666C9.203 13.523 7.42 13 5.5 13v2zm5.053-11.914C11.539 2.431 12.928 2 14.5 2V0c-1.92 0-3.703.523-5.053 1.42l1.107 1.666zM14.5 2c1.573 0 2.961.431 3.947 1.086l1.107-1.666C18.203.523 16.421 0 14.5 0v2zm3.5.253v13h2v-13h-2zm1.553 12.167C18.203 13.523 16.421 13 14.5 13v2c1.573 0 2.961.431 3.947 1.086l1.107-1.666zM14.5 13c-1.92 0-3.703.523-5.053 1.42l1.107 1.666C11.539 15.431 12.928 15 14.5 15v-2z" | ||
5 | + /> | ||
6 | + </svg> | ||
7 | +</template> |
src/components/icons/IconEcosystem.vue
0 → 100644
1 | +<template> | ||
2 | + <svg xmlns="http://www.w3.org/2000/svg" width="18" height="20" fill="currentColor"> | ||
3 | + <path | ||
4 | + d="M11.447 8.894a1 1 0 1 0-.894-1.789l.894 1.789zm-2.894-.789a1 1 0 1 0 .894 1.789l-.894-1.789zm0 1.789a1 1 0 1 0 .894-1.789l-.894 1.789zM7.447 7.106a1 1 0 1 0-.894 1.789l.894-1.789zM10 9a1 1 0 1 0-2 0h2zm-2 2.5a1 1 0 1 0 2 0H8zm9.447-5.606a1 1 0 1 0-.894-1.789l.894 1.789zm-2.894-.789a1 1 0 1 0 .894 1.789l-.894-1.789zm2 .789a1 1 0 1 0 .894-1.789l-.894 1.789zm-1.106-2.789a1 1 0 1 0-.894 1.789l.894-1.789zM18 5a1 1 0 1 0-2 0h2zm-2 2.5a1 1 0 1 0 2 0h-2zm-5.447-4.606a1 1 0 1 0 .894-1.789l-.894 1.789zM9 1l.447-.894a1 1 0 0 0-.894 0L9 1zm-2.447.106a1 1 0 1 0 .894 1.789l-.894-1.789zm-6 3a1 1 0 1 0 .894 1.789L.553 4.106zm2.894.789a1 1 0 1 0-.894-1.789l.894 1.789zm-2-.789a1 1 0 1 0-.894 1.789l.894-1.789zm1.106 2.789a1 1 0 1 0 .894-1.789l-.894 1.789zM2 5a1 1 0 1 0-2 0h2zM0 7.5a1 1 0 1 0 2 0H0zm8.553 12.394a1 1 0 1 0 .894-1.789l-.894 1.789zm-1.106-2.789a1 1 0 1 0-.894 1.789l.894-1.789zm1.106 1a1 1 0 1 0 .894 1.789l-.894-1.789zm2.894.789a1 1 0 1 0-.894-1.789l.894 1.789zM8 19a1 1 0 1 0 2 0H8zm2-2.5a1 1 0 1 0-2 0h2zm-7.447.394a1 1 0 1 0 .894-1.789l-.894 1.789zM1 15H0a1 1 0 0 0 .553.894L1 15zm1-2.5a1 1 0 1 0-2 0h2zm12.553 2.606a1 1 0 1 0 .894 1.789l-.894-1.789zM17 15l.447.894A1 1 0 0 0 18 15h-1zm1-2.5a1 1 0 1 0-2 0h2zm-7.447-5.394l-2 1 .894 1.789 2-1-.894-1.789zm-1.106 1l-2-1-.894 1.789 2 1 .894-1.789zM8 9v2.5h2V9H8zm8.553-4.894l-2 1 .894 1.789 2-1-.894-1.789zm.894 0l-2-1-.894 1.789 2 1 .894-1.789zM16 5v2.5h2V5h-2zm-4.553-3.894l-2-1-.894 1.789 2 1 .894-1.789zm-2.894-1l-2 1 .894 1.789 2-1L8.553.106zM1.447 5.894l2-1-.894-1.789-2 1 .894 1.789zm-.894 0l2 1 .894-1.789-2-1-.894 1.789zM0 5v2.5h2V5H0zm9.447 13.106l-2-1-.894 1.789 2 1 .894-1.789zm0 1.789l2-1-.894-1.789-2 1 .894 1.789zM10 19v-2.5H8V19h2zm-6.553-3.894l-2-1-.894 1.789 2 1 .894-1.789zM2 15v-2.5H0V15h2zm13.447 1.894l2-1-.894-1.789-2 1 .894 1.789zM18 15v-2.5h-2V15h2z" | ||
5 | + /> | ||
6 | + </svg> | ||
7 | +</template> |
src/components/icons/IconSupport.vue
0 → 100644
src/components/icons/IconTooling.vue
0 → 100644
1 | +<!-- This icon is from <https://github.com/Templarian/MaterialDesign>, distributed under Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0) license--> | ||
2 | +<template> | ||
3 | + <svg | ||
4 | + xmlns="http://www.w3.org/2000/svg" | ||
5 | + xmlns:xlink="http://www.w3.org/1999/xlink" | ||
6 | + aria-hidden="true" | ||
7 | + role="img" | ||
8 | + class="iconify iconify--mdi" | ||
9 | + width="24" | ||
10 | + height="24" | ||
11 | + preserveAspectRatio="xMidYMid meet" | ||
12 | + viewBox="0 0 24 24" | ||
13 | + > | ||
14 | + <path | ||
15 | + d="M20 18v-4h-3v1h-2v-1H9v1H7v-1H4v4h16M6.33 8l-1.74 4H7v-1h2v1h6v-1h2v1h2.41l-1.74-4H6.33M9 5v1h6V5H9m12.84 7.61c.1.22.16.48.16.8V18c0 .53-.21 1-.6 1.41c-.4.4-.85.59-1.4.59H4c-.55 0-1-.19-1.4-.59C2.21 19 2 18.53 2 18v-4.59c0-.32.06-.58.16-.8L4.5 7.22C4.84 6.41 5.45 6 6.33 6H7V5c0-.55.18-1 .57-1.41C7.96 3.2 8.44 3 9 3h6c.56 0 1.04.2 1.43.59c.39.41.57.86.57 1.41v1h.67c.88 0 1.49.41 1.83 1.22l2.34 5.39z" | ||
16 | + fill="currentColor" | ||
17 | + ></path> | ||
18 | + </svg> | ||
19 | +</template> |
src/main.js
0 → 100644
1 | +// import './assets/main.css' | ||
2 | + | ||
3 | +import { createApp } from 'vue' | ||
4 | +import App from './App.vue' | ||
5 | +import router from './router' | ||
6 | +import ElementPlus from 'element-plus' | ||
7 | +import 'element-plus/dist/index.css' | ||
8 | +import * as ElementPlusIconsVue from '@element-plus/icons-vue' | ||
9 | + | ||
10 | +const app = createApp(App) | ||
11 | + | ||
12 | +app.use(router) | ||
13 | + .use(ElementPlus) | ||
14 | + | ||
15 | + | ||
16 | +app.mount('#app') | ||
17 | + | ||
18 | +for (const [key, component] of Object.entries(ElementPlusIconsVue)) { | ||
19 | + app.component(key, component) | ||
20 | +} |
src/main/java/com/ectrip/demo/SNManageApplication.java deleted
1 | -package com.ectrip.demo; | ||
2 | - | ||
3 | -import org.springframework.boot.SpringApplication; | ||
4 | -import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
5 | -import springfox.documentation.swagger2.annotations.EnableSwagger2; | ||
6 | - | ||
7 | - | ||
8 | -@SpringBootApplication | ||
9 | -@EnableSwagger2 | ||
10 | -public class SNManageApplication { | ||
11 | - | ||
12 | - public static void main(String[] args) { | ||
13 | - SpringApplication.run(SNManageApplication.class, args); | ||
14 | - } | ||
15 | - | ||
16 | -} |
src/main/java/com/ectrip/demo/controller/SNController.java deleted
1 | -package com.ectrip.demo.controller; | ||
2 | - | ||
3 | -import com.ectrip.demo.util.HttpResult; | ||
4 | -import com.ectrip.demo.dto.AddSNsDTO; | ||
5 | -import com.ectrip.demo.dto.DeleteSNsDTO; | ||
6 | -import com.ectrip.demo.exception.SNRepetitiveException; | ||
7 | -import com.ectrip.demo.service.SNService; | ||
8 | -import io.swagger.annotations.Api; | ||
9 | -import io.swagger.annotations.ApiOperation; | ||
10 | -import org.apache.logging.log4j.LogManager; | ||
11 | -import org.apache.logging.log4j.Logger; | ||
12 | -import org.springframework.beans.factory.annotation.Autowired; | ||
13 | -import org.springframework.web.bind.annotation.*; | ||
14 | - | ||
15 | -import javax.validation.Valid; | ||
16 | - | ||
17 | -@Api(tags = "SN操作") | ||
18 | -@RestController | ||
19 | -@RequestMapping("/sn") | ||
20 | -public class SNController { | ||
21 | - static Logger logger = LogManager.getLogger(SNController.class); | ||
22 | - | ||
23 | - @Autowired | ||
24 | - SNService snService; | ||
25 | - | ||
26 | -// @ApiOperation("首页") | ||
27 | -// @GetMapping("/index.html") | ||
28 | -// public String index() { | ||
29 | -// return "Index"; | ||
30 | -// } | ||
31 | - | ||
32 | - @ApiOperation("添加SN") | ||
33 | - @PostMapping("/add_sn") | ||
34 | - @ResponseBody | ||
35 | - public HttpResult addSN(@RequestBody @Valid AddSNsDTO addSNsDTO) { | ||
36 | - | ||
37 | - try { | ||
38 | - snService.addSN(addSNsDTO); | ||
39 | - return HttpResult.success("添加成功"); | ||
40 | - } catch (SNRepetitiveException e) { | ||
41 | - return HttpResult.fail(e.getMessage()); | ||
42 | - } catch (Exception e) { | ||
43 | - logger.error(e.getMessage()); | ||
44 | - return HttpResult.fail(); | ||
45 | - } | ||
46 | - | ||
47 | - } | ||
48 | - | ||
49 | - | ||
50 | -// @ApiOperation("获取全部SN") | ||
51 | -// @GetMapping("/get_SNs") | ||
52 | -// @ResponseBody | ||
53 | -// public void getSNs(HttpServletRequest request, HttpServletResponse response) { | ||
54 | -// try { | ||
55 | -// snService.downloadSNFile(request, response); | ||
56 | -// } catch (Exception e) { | ||
57 | -// response.setStatus(500); | ||
58 | -// } | ||
59 | -// | ||
60 | -// } | ||
61 | - | ||
62 | - @ApiOperation("获取全部base64加密后的SN") | ||
63 | - @GetMapping("/get_sn") | ||
64 | - @ResponseBody | ||
65 | - public HttpResult<String> getBase64SNs() { | ||
66 | - try { | ||
67 | - return HttpResult.success("",snService.getEncryptSNs()); | ||
68 | - } catch (Exception e) { | ||
69 | - logger.error(e.getMessage()); | ||
70 | - return HttpResult.fail("服务器异常"); | ||
71 | - } | ||
72 | - | ||
73 | - } | ||
74 | - | ||
75 | - @ApiOperation("删除指定SN") | ||
76 | - @PostMapping("/delete_sn") | ||
77 | - @ResponseBody | ||
78 | - public HttpResult deleteSN(@RequestBody @Valid DeleteSNsDTO deleteSNsDTO) { | ||
79 | - try { | ||
80 | - snService.deleteSN(deleteSNsDTO); | ||
81 | - return HttpResult.success("删除成功!"); | ||
82 | - } | ||
83 | - catch (Exception e) { | ||
84 | - logger.error(e.getMessage()); | ||
85 | - return HttpResult.fail("服务器异常!"); | ||
86 | - } | ||
87 | - } | ||
88 | - | ||
89 | - | ||
90 | -} |
src/main/java/com/ectrip/demo/dto/AddSNsDTO.java deleted
1 | -package com.ectrip.demo.dto; | ||
2 | - | ||
3 | - | ||
4 | -import io.swagger.annotations.ApiModel; | ||
5 | -import io.swagger.annotations.ApiModelProperty; | ||
6 | -import lombok.Data; | ||
7 | - | ||
8 | -import javax.validation.constraints.NotBlank; | ||
9 | -import javax.validation.constraints.NotNull; | ||
10 | -import java.util.ArrayList; | ||
11 | -import java.util.List; | ||
12 | - | ||
13 | -@Data | ||
14 | -@ApiModel(description = "删除SNs入参") | ||
15 | -public class AddSNsDTO { | ||
16 | - | ||
17 | - @ApiModelProperty(value = "项目名称") | ||
18 | - @NotBlank(message = "项目名称不能为空!") | ||
19 | - private String projectName; | ||
20 | - | ||
21 | - @ApiModelProperty(value = "设备码") | ||
22 | - @NotNull(message = "设备码不能为空!") | ||
23 | - private ArrayList<String> sns; | ||
24 | -} |
src/main/java/com/ectrip/demo/dto/DeleteSNsDTO.java deleted
1 | -package com.ectrip.demo.dto; | ||
2 | - | ||
3 | -import io.swagger.annotations.ApiModel; | ||
4 | -import io.swagger.annotations.ApiModelProperty; | ||
5 | -import lombok.Data; | ||
6 | - | ||
7 | -import javax.validation.constraints.NotNull; | ||
8 | -import java.util.ArrayList; | ||
9 | -import java.util.List; | ||
10 | - | ||
11 | -@Data | ||
12 | -@ApiModel(description = "删除SNs入参") | ||
13 | -public class DeleteSNsDTO { | ||
14 | - @ApiModelProperty(value = "设备码") | ||
15 | - @NotNull(message = "设备码不能为空!") | ||
16 | - private ArrayList<String> sns; | ||
17 | -} |
src/main/java/com/ectrip/demo/exception/SNRepetitiveException.java deleted
src/main/java/com/ectrip/demo/service/SNService.java deleted
1 | -package com.ectrip.demo.service; | ||
2 | - | ||
3 | -import com.ectrip.demo.dto.AddSNsDTO; | ||
4 | -import com.ectrip.demo.dto.DeleteSNsDTO; | ||
5 | -import com.ectrip.demo.exception.SNRepetitiveException; | ||
6 | - | ||
7 | -import javax.servlet.http.HttpServletRequest; | ||
8 | -import javax.servlet.http.HttpServletResponse; | ||
9 | -import java.io.IOException; | ||
10 | - | ||
11 | -public interface SNService { | ||
12 | - /** | ||
13 | - * 新增SN号 | ||
14 | - * @param addSNsDTO SN号 | ||
15 | - */ | ||
16 | - void addSN(AddSNsDTO addSNsDTO) throws SNRepetitiveException, IOException; | ||
17 | - | ||
18 | - /** | ||
19 | - * 下载所有SN号 | ||
20 | - */ | ||
21 | - void downloadSNFile(HttpServletRequest request, HttpServletResponse response) throws IOException; | ||
22 | - | ||
23 | - /** | ||
24 | - * 获取所有加密后的SN字符串 | ||
25 | - * @return - | ||
26 | - */ | ||
27 | - String getEncryptSNs() throws IOException; | ||
28 | - | ||
29 | - /** | ||
30 | - * 删除指定SN记录 | ||
31 | - * @param deleteSNsDTO SN号 | ||
32 | - */ | ||
33 | - void deleteSN(DeleteSNsDTO deleteSNsDTO) throws Exception; | ||
34 | - | ||
35 | -} |
src/main/java/com/ectrip/demo/service/impl/SNServiceImpl.java deleted
1 | -package com.ectrip.demo.service.impl; | ||
2 | - | ||
3 | -import cn.hutool.core.codec.Base64; | ||
4 | -import com.ectrip.demo.dto.DeleteSNsDTO; | ||
5 | -import com.ectrip.demo.service.SNService; | ||
6 | -import com.ectrip.demo.dto.AddSNsDTO; | ||
7 | -import com.ectrip.demo.exception.SNRepetitiveException; | ||
8 | -import org.apache.logging.log4j.LogManager; | ||
9 | -import org.apache.logging.log4j.Logger; | ||
10 | -import org.springframework.beans.factory.annotation.Value; | ||
11 | -import org.springframework.stereotype.Service; | ||
12 | - | ||
13 | -import javax.servlet.http.HttpServletRequest; | ||
14 | -import javax.servlet.http.HttpServletResponse; | ||
15 | -import java.io.*; | ||
16 | -import java.nio.charset.StandardCharsets; | ||
17 | -import java.nio.file.Files; | ||
18 | -import java.nio.file.Paths; | ||
19 | -import java.text.SimpleDateFormat; | ||
20 | -import java.util.Date; | ||
21 | -import java.util.HashSet; | ||
22 | -import java.util.Set; | ||
23 | -import java.util.concurrent.locks.Lock; | ||
24 | -import java.util.concurrent.locks.ReentrantLock; | ||
25 | - | ||
26 | -@Service | ||
27 | -public class SNServiceImpl implements SNService { | ||
28 | - /** | ||
29 | - * 多线程改写文件存在并发问题,需加锁操作 | ||
30 | - */ | ||
31 | - private static final Lock lock = new ReentrantLock(); | ||
32 | - | ||
33 | - static Logger logger = LogManager.getLogger(SNServiceImpl.class); | ||
34 | - | ||
35 | - @Value("${SN.file.path}") | ||
36 | - String SNFilePath; | ||
37 | - | ||
38 | - @Value("${SN.file.temp.path}") | ||
39 | - String SNTempFilePath; | ||
40 | - | ||
41 | - @Override | ||
42 | - public void addSN(AddSNsDTO addSNsDTO) throws SNRepetitiveException, IOException { | ||
43 | - | ||
44 | - //加try,catch只为释放锁 | ||
45 | - try { | ||
46 | - //加锁 | ||
47 | - lock.lock(); | ||
48 | - logger.info("-----------------------------开始添加SNs-----------------------------"); | ||
49 | - StringBuilder SNs = new StringBuilder(); | ||
50 | - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | ||
51 | - String currTime = sdf.format(new Date()); | ||
52 | - //读取文件,判断SN是否重复 | ||
53 | - Set<String> set = new HashSet<>(); | ||
54 | - Reader reader = new InputStreamReader(Files.newInputStream(Paths.get(SNFilePath)),StandardCharsets.UTF_8); | ||
55 | - BufferedReader bufferedReader = new BufferedReader(reader); | ||
56 | - String br; | ||
57 | - while ((br=bufferedReader.readLine()) != null) { | ||
58 | - //截取SN | ||
59 | - int index = br.indexOf("##"); | ||
60 | - String SN = br.substring(0,index == -1? 0 : index); | ||
61 | - set.add(SN); | ||
62 | - } | ||
63 | - for (String SN : addSNsDTO.getSns()) { | ||
64 | - if (set.contains(SN)) { | ||
65 | - throw new SNRepetitiveException("SN:" + SN + " 已存在,请勿重复添加"); | ||
66 | - } | ||
67 | - SNs.append(SN).append("##").append(addSNsDTO.getProjectName()).append("##").append(currTime); | ||
68 | - SNs.append(System.lineSeparator()); | ||
69 | - } | ||
70 | - | ||
71 | - | ||
72 | - //写入 | ||
73 | - FileOutputStream fileOutputStream = new FileOutputStream(SNFilePath,true); | ||
74 | - fileOutputStream.write(SNs.toString().getBytes(StandardCharsets.UTF_8)); | ||
75 | - fileOutputStream.flush(); | ||
76 | - fileOutputStream.close(); | ||
77 | - logger.info("成功写入SNs:{}",SNs); | ||
78 | - } finally { //释放锁 | ||
79 | - lock.unlock(); | ||
80 | - } | ||
81 | - } | ||
82 | - | ||
83 | - @Override | ||
84 | - public String getEncryptSNs() throws IOException { | ||
85 | - //读取文件 | ||
86 | - Reader reader = new InputStreamReader(Files.newInputStream(Paths.get(SNFilePath)),StandardCharsets.UTF_8); | ||
87 | - char[] chars = new char[1000]; | ||
88 | - StringBuilder builder = new StringBuilder(); | ||
89 | - int len = reader.read(chars); | ||
90 | - while (len != -1) { | ||
91 | - builder.append(chars,0,len); | ||
92 | - len = reader.read(chars); | ||
93 | - } | ||
94 | - | ||
95 | - //加密 | ||
96 | - return Base64.encode(builder.toString()); | ||
97 | - } | ||
98 | - | ||
99 | - @Override | ||
100 | - public void deleteSN(DeleteSNsDTO deleteSNsDTO) throws Exception{ | ||
101 | - try { | ||
102 | - lock.lock(); | ||
103 | - logger.info("-----------------------------开始删除SNs-----------------------------"); | ||
104 | - | ||
105 | - HashSet<String> deleteSNsSet = new HashSet<>(deleteSNsDTO.getSns()); | ||
106 | - | ||
107 | - //读取文件,记录不用删除的数据 | ||
108 | - Reader reader = new InputStreamReader(Files.newInputStream(new File(SNFilePath).toPath()), StandardCharsets.UTF_8); | ||
109 | - BufferedReader bufferedReader = new BufferedReader(reader); | ||
110 | - String br; | ||
111 | - StringBuilder stringBuilder = new StringBuilder(); | ||
112 | - StringBuilder existSNs = new StringBuilder(); | ||
113 | - //所要删除的SN是否存在 | ||
114 | - boolean SNExist = false; | ||
115 | - while ((br=bufferedReader.readLine()) != null) { | ||
116 | - //截取SN | ||
117 | - int index = br.indexOf("##"); | ||
118 | - String str = br.substring(0,index == -1? 0 : index); | ||
119 | - if (!deleteSNsSet.contains(str)) { | ||
120 | - stringBuilder.append(br); | ||
121 | - stringBuilder.append(System.lineSeparator()); | ||
122 | - } else { | ||
123 | - existSNs.append(br).append(System.lineSeparator()); | ||
124 | - SNExist = true; | ||
125 | - } | ||
126 | - } | ||
127 | - bufferedReader.close(); | ||
128 | - | ||
129 | - //如果存在要删除的SN,先将数据备份,再将留存数据覆盖掉原SN文件。 | ||
130 | - if (SNExist) { | ||
131 | - //备份数据 | ||
132 | - FileOutputStream tempFileOutputStream = new FileOutputStream(SNTempFilePath); | ||
133 | - tempFileOutputStream.write(stringBuilder.toString().getBytes(StandardCharsets.UTF_8)); | ||
134 | - tempFileOutputStream.flush(); | ||
135 | - tempFileOutputStream.close(); | ||
136 | - //覆盖掉原来的数据到SN文件中 | ||
137 | - FileOutputStream fileOutputStream = new FileOutputStream(SNFilePath); | ||
138 | - fileOutputStream.write(stringBuilder.toString().getBytes(StandardCharsets.UTF_8)); | ||
139 | - fileOutputStream.flush(); | ||
140 | - fileOutputStream.close(); | ||
141 | - logger.warn("成功删除SNs:{}",existSNs); | ||
142 | - } | ||
143 | - | ||
144 | - logger.info("-----------------------------结束删除SNs-----------------------------"); | ||
145 | - | ||
146 | - | ||
147 | - } finally { | ||
148 | - lock.unlock(); | ||
149 | - } | ||
150 | - } | ||
151 | - | ||
152 | - @Override | ||
153 | - public void downloadSNFile(HttpServletRequest request, HttpServletResponse response) throws IOException { | ||
154 | - File file = new File(SNFilePath); | ||
155 | - | ||
156 | - response.setCharacterEncoding("UTF-8"); | ||
157 | - response.setHeader("Content-type","application/octet-stream;charset=UTF-8"); | ||
158 | - response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(file.getName().trim(), "UTF-8")); | ||
159 | - response.addHeader("Pargam", "no-cache"); | ||
160 | - response.addHeader("Cache-Control", "no-cache"); | ||
161 | - | ||
162 | - //读取文件 | ||
163 | - byte[] SNsByteArr = new byte[(int) file.length()]; | ||
164 | - FileInputStream fileInputStream = new FileInputStream(file); | ||
165 | - fileInputStream.read(SNsByteArr); | ||
166 | - //加密 | ||
167 | - String encodeSNs = Base64.encode(SNsByteArr); | ||
168 | - | ||
169 | - //写入到输出流 | ||
170 | - response.addHeader("Content-Length",String.valueOf(encodeSNs.getBytes().length)); | ||
171 | - OutputStream outputStream = response.getOutputStream(); | ||
172 | - outputStream.write(encodeSNs.getBytes()); | ||
173 | - outputStream.flush(); | ||
174 | - outputStream.close(); | ||
175 | - | ||
176 | - } | ||
177 | - | ||
178 | -} |
src/main/java/com/ectrip/demo/util/HttpResult.java deleted
1 | -package com.ectrip.demo.util; | ||
2 | - | ||
3 | -import lombok.AllArgsConstructor; | ||
4 | -import lombok.Data; | ||
5 | -import lombok.NoArgsConstructor; | ||
6 | - | ||
7 | -import java.io.Serializable; | ||
8 | - | ||
9 | -@Data | ||
10 | -@AllArgsConstructor | ||
11 | -@NoArgsConstructor | ||
12 | -public class HttpResult<T> implements Serializable { | ||
13 | - public static final int CODE_SUCCESS = 200; | ||
14 | - public static final int CODE_FAILED = 500; | ||
15 | - | ||
16 | - private Integer code; | ||
17 | - | ||
18 | - private String message; | ||
19 | - | ||
20 | - private T data; | ||
21 | - | ||
22 | - public static <T> HttpResult<T> success() { | ||
23 | - return new HttpResult<>(200,"success",null); | ||
24 | - } | ||
25 | - | ||
26 | - public static <T> HttpResult<T> success(String message) { | ||
27 | - return new HttpResult<>(200,message,null); | ||
28 | - } | ||
29 | - | ||
30 | - public static <T> HttpResult<T> success(String message, T data) { | ||
31 | - return new HttpResult<>(200,message,data); | ||
32 | - } | ||
33 | - | ||
34 | - public static <T> HttpResult<T> fail() { | ||
35 | - return new HttpResult<>(500,"fail",null); | ||
36 | - } | ||
37 | - public static <T> HttpResult<T> fail(String message) { | ||
38 | - return new HttpResult<>(500,message,null); | ||
39 | - } | ||
40 | -} |
src/main/resources/application.properties deleted
1 | - server.port=8080 | ||
2 | - | ||
3 | - | ||
4 | -spring.web.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/ | ||
5 | - | ||
6 | - | ||
7 | -logging.config=classpath:log4j2.xml | ||
8 | - | ||
9 | -#swagger.basic.enable = true | ||
10 | -#swagger.basic.username = test | ||
11 | -#swagger.basic.password = 123 | ||
12 | - | ||
13 | -#spring.thymeleaf.cache=false | ||
14 | -#spring.thymeleaf.prefix=classpath:/templates/ | ||
15 | -#spring.thymeleaf.suffix=.html | ||
16 | - | ||
17 | - | ||
18 | -SN.file.path=src/main/resources/sn/SN.txt | ||
19 | -SN.file.temp.path=src/main/resources/sn/SNTemp.txt | ||
20 | - | ||
21 | -#SN.file.path= | ||
22 | -#SN.file.temp.path= | ||
23 | \ No newline at end of file | 0 | \ No newline at end of file |
src/main/resources/log4j2.xml deleted
1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
2 | -<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL --> | ||
3 | -<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出--> | ||
4 | -<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数--> | ||
5 | -<configuration status="WARN" monitorInterval="30"> | ||
6 | - <Properties> | ||
7 | - <Property name="baseDir" value="./log"/> | ||
8 | - </Properties> | ||
9 | - <!--先定义所有的appender--> | ||
10 | - <appenders> | ||
11 | - <!--这个输出控制台的配置--> | ||
12 | - <console name="Console" target="SYSTEM_OUT"> | ||
13 | - <!--输出日志的格式--> | ||
14 | - <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> | ||
15 | - </console> | ||
16 | - <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,个这也挺有用的,适合临时测试用--> | ||
17 | -<!-- <File name="log" fileName="${baseDir}/all.log" append="false">--> | ||
18 | -<!-- <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>--> | ||
19 | -<!-- </File>--> | ||
20 | - <!--这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档--> | ||
21 | - <RollingFile name="RollingFileInfo" fileName="${baseDir}/info.log" | ||
22 | - filePattern="${baseDir}/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log"> | ||
23 | - <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)--> | ||
24 | - <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/> | ||
25 | - <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> | ||
26 | - <Policies> | ||
27 | - <TimeBasedTriggeringPolicy/> | ||
28 | - <SizeBasedTriggeringPolicy size="100 MB"/> | ||
29 | - </Policies> | ||
30 | - </RollingFile> | ||
31 | - <RollingFile name="RollingFileWarn" fileName="${baseDir}/warn.log" | ||
32 | - filePattern="${baseDir}/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log"> | ||
33 | - <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/> | ||
34 | - <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> | ||
35 | - <Policies> | ||
36 | - <TimeBasedTriggeringPolicy/> | ||
37 | - <SizeBasedTriggeringPolicy size="100 MB"/> | ||
38 | - </Policies> | ||
39 | - <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 --> | ||
40 | - <DefaultRolloverStrategy max="20"/> | ||
41 | - </RollingFile> | ||
42 | - <RollingFile name="RollingFileError" fileName="${baseDir}/error.log" | ||
43 | - filePattern="${baseDir}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log"> | ||
44 | - <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/> | ||
45 | - <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> | ||
46 | - <Policies> | ||
47 | - <TimeBasedTriggeringPolicy/> | ||
48 | - <SizeBasedTriggeringPolicy size="100 MB"/> | ||
49 | - </Policies> | ||
50 | - </RollingFile> | ||
51 | - </appenders> | ||
52 | - <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效--> | ||
53 | - <loggers> | ||
54 | - <!--过滤掉spring和mybatis的一些无用的DEBUG信息--> | ||
55 | - <logger name="org.springframework" level="INFO"></logger> | ||
56 | - <logger name="org.mybatis" level="INFO"></logger> | ||
57 | - <root level="all"> | ||
58 | - <appender-ref ref="Console"/> | ||
59 | - <appender-ref ref="RollingFileInfo"/> | ||
60 | - <appender-ref ref="RollingFileWarn"/> | ||
61 | - <appender-ref ref="RollingFileError"/> | ||
62 | - </root> | ||
63 | - </loggers> | ||
64 | -</configuration> | ||
65 | \ No newline at end of file | 0 | \ No newline at end of file |
src/main/resources/sn/SN.txt deleted
src/main/resources/sn/SNTemp.txt deleted
src/main/resources/templates/Index.html deleted
1 | -<!DOCTYPE html> | ||
2 | -<html lang="en"> | ||
3 | -<meta charset="UTF-8"> | ||
4 | - | ||
5 | -<body> | ||
6 | - <div> | ||
7 | - <div> | ||
8 | - <input type="text" placeholder="请输入SN号" id="SNContent"/> | ||
9 | - <input type="text" placeholder="请输入项目名称" id="projectName"/> | ||
10 | - </div> | ||
11 | - <button id="add">添加</button> | ||
12 | - </div> | ||
13 | - <br/> | ||
14 | - | ||
15 | - <div> | ||
16 | - <div> | ||
17 | - <input type="text" placeholder="请输入SN号" id="SNContentDelete"/> | ||
18 | - </div> | ||
19 | - <button id="delete">删除</button> | ||
20 | - </div> | ||
21 | - <br/> | ||
22 | - | ||
23 | - <div> | ||
24 | - <button id="show">获取所有</button> | ||
25 | - | ||
26 | - </div> | ||
27 | - <span id="SNShow" style="display: inline-block; | ||
28 | - width: 500px; | ||
29 | - word-break: break-all; | ||
30 | - white-space: normal;"></span> | ||
31 | - | ||
32 | - <script> | ||
33 | - //添加 | ||
34 | - var addButton = document.getElementById("add"); | ||
35 | - addButton.onclick = function () { | ||
36 | - let SNcontent = document.getElementById("SNContent").value.trim(); | ||
37 | - let projectName = document.getElementById("projectName").value.trim(); | ||
38 | - let dateTime = formattedDate().trim(); | ||
39 | - | ||
40 | - //数据判空 | ||
41 | - if (typeof SNcontent === 'undefined' || SNcontent == null || SNcontent === '') { | ||
42 | - alert("请输入SN号") | ||
43 | - return; | ||
44 | - } | ||
45 | - if (typeof projectName === 'undefined' || projectName == null || projectName === '') { | ||
46 | - alert("请输入projectName") | ||
47 | - return; | ||
48 | - } | ||
49 | - | ||
50 | - let SNDto = SNcontent + "##" + projectName + "##" +dateTime; | ||
51 | - //ajax请求提交数据 | ||
52 | - var xhr = new XMLHttpRequest(); | ||
53 | - xhr.open('POST','/add_SN'); | ||
54 | - xhr.setRequestHeader('Content-Type','application/json') | ||
55 | - xhr.send(SNDto); | ||
56 | - xhr.onreadystatechange = function () { | ||
57 | - if (xhr.readyState === XMLHttpRequest.DONE) { | ||
58 | - let responseObject = JSON.parse(xhr.responseText); | ||
59 | - alert(responseObject.message); | ||
60 | - } | ||
61 | - } | ||
62 | - } | ||
63 | - | ||
64 | - //查询 | ||
65 | - var showButton = document.getElementById("show"); | ||
66 | - showButton.onclick = function () { | ||
67 | - //ajax请求获取数据 | ||
68 | - var xhr = new XMLHttpRequest(); | ||
69 | - xhr.open('GET','/get_SNs',true); | ||
70 | - xhr.send(); | ||
71 | - xhr.onreadystatechange = function () { | ||
72 | - | ||
73 | - // if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) { | ||
74 | - // var blob = new Blob([this.response], {type: 'application/octet-stream'}); | ||
75 | - // var url = URL.createObjectURL(blob); | ||
76 | - // var a = document.createElement('a'); | ||
77 | - // a.href = url; | ||
78 | - // a.download = 'SNs.txt'; | ||
79 | - // a.target = '_blank'; | ||
80 | - // a.click(); | ||
81 | - // } | ||
82 | - if (xhr.readyState === XMLHttpRequest.DONE) { | ||
83 | - if (xhr.status === 200) { | ||
84 | - let responseObject = JSON.parse(xhr.responseText); | ||
85 | - let SNs = responseObject.data; | ||
86 | - document.getElementById("SNShow").innerText = SNs; | ||
87 | - } else { | ||
88 | - document.getElementById("SNShow").innerText = "出错了!"; | ||
89 | - } | ||
90 | - } | ||
91 | - } | ||
92 | - | ||
93 | - } | ||
94 | - | ||
95 | - //删除 | ||
96 | - var deleteButton = document.getElementById("delete"); | ||
97 | - deleteButton.onclick = function () { | ||
98 | - let SNContentDelete = document.getElementById("SNContentDelete").value.trim(); | ||
99 | - if (typeof SNContentDelete === 'undefined' || SNContentDelete == null || SNContentDelete === '') { | ||
100 | - alert("请输入SN号") | ||
101 | - return; | ||
102 | - } | ||
103 | - | ||
104 | - //ajax请求获取数据 | ||
105 | - var xhr = new XMLHttpRequest(); | ||
106 | - xhr.open('POST','/delete_SN',true); | ||
107 | - xhr.send(SNContentDelete); | ||
108 | - xhr.onreadystatechange = function () { | ||
109 | - if (xhr.readyState === XMLHttpRequest.DONE) { | ||
110 | - let responseObject = JSON.parse(xhr.responseText); | ||
111 | - alert(responseObject.message); | ||
112 | - } | ||
113 | - } | ||
114 | - | ||
115 | - } | ||
116 | - | ||
117 | - | ||
118 | - | ||
119 | - function formattedDate() { | ||
120 | - const date = new Date(); | ||
121 | - const year = date.getFullYear(); | ||
122 | - const month = (date.getMonth() + 1).toString().padStart(2, '0'); | ||
123 | - const day = date.getDate().toString().padStart(2, '0'); | ||
124 | - const hour = date.getHours().toString().padStart(2, '0'); | ||
125 | - const minute = date.getMinutes().toString().padStart(2, '0'); | ||
126 | - const second = date.getSeconds().toString().padStart(2, '0'); | ||
127 | - const formattedDate = `${year}-${month}-${day} ${hour}:${minute}:${second}`; | ||
128 | - return formattedDate; | ||
129 | - } | ||
130 | - | ||
131 | - | ||
132 | - | ||
133 | - | ||
134 | - </script> | ||
135 | - | ||
136 | -</body> | ||
137 | - | ||
138 | - | ||
139 | -</html> | ||
140 | \ No newline at end of file | 0 | \ No newline at end of file |
src/router/index.js
0 → 100644
1 | +import { createRouter, createWebHistory } from 'vue-router' | ||
2 | +import HomeView from '../views/HomeView.vue' | ||
3 | + | ||
4 | +const router = createRouter({ | ||
5 | + history: createWebHistory(import.meta.env.BASE_URL), | ||
6 | + routes: [ | ||
7 | + { | ||
8 | + path: '/', | ||
9 | + name: 'home', | ||
10 | + component: HomeView, | ||
11 | + meta: { | ||
12 | + title: 'SN管理' | ||
13 | + } | ||
14 | + } | ||
15 | + ] | ||
16 | +}) | ||
17 | + | ||
18 | +router.beforeEach((to,from,next)=>{//beforeEach是router的钩子函数,在进入路由前执行 | ||
19 | + if(to.meta.title){//判断是否有标题 | ||
20 | + document.title = to.meta.title | ||
21 | + } | ||
22 | + next() //执行进入路由,如果不写就不会进入目标页 | ||
23 | +}) | ||
24 | + | ||
25 | +export default router |
src/views/HomeView.vue
0 → 100644
1 | +<script setup> | ||
2 | + import { reactive, ref } from 'vue' | ||
3 | + // import { FormInstance } from 'element-plus' | ||
4 | + import axios from 'axios'; | ||
5 | + import { ElMessage } from 'element-plus' | ||
6 | + import { addSNsApi, getSNsApi, deleteSNsApi } from '../api/api'; | ||
7 | + | ||
8 | + const addFormRef = ref() | ||
9 | + const deleteFormRef = ref() | ||
10 | + | ||
11 | + //获取的SN内容 | ||
12 | + const SNsContent = ref('...') | ||
13 | + | ||
14 | + //当前显示的表单 1-添加SN 2-获取SN 3-删除SN | ||
15 | + const currForm = ref('1'); | ||
16 | + const changeForm = (tab, event) => { | ||
17 | + currForm.value = tab.props.name; | ||
18 | + //把SN数据查出来 | ||
19 | + if (currForm.value == 3) { | ||
20 | + axios({ | ||
21 | + method: getSNsApi.method, | ||
22 | + url: getSNsApi.url | ||
23 | + }).then(response => { | ||
24 | + if (response.data.code == 200) { | ||
25 | + SNsContent.value = response.data.data; | ||
26 | + | ||
27 | + } else { | ||
28 | + ElMessage({ | ||
29 | + message: response.data.message, | ||
30 | + type: 'error', | ||
31 | + }) | ||
32 | + } | ||
33 | + | ||
34 | + }).catch(err => { | ||
35 | + ElMessage.error(err) | ||
36 | + }) | ||
37 | + } | ||
38 | + | ||
39 | + } | ||
40 | + | ||
41 | + | ||
42 | + //添加SN的表单 | ||
43 | + const dynamicValidateAddForm = reactive({ | ||
44 | + SNs: [ | ||
45 | + { | ||
46 | + key: 1, | ||
47 | + value: '', | ||
48 | + }, | ||
49 | + ], | ||
50 | + projectName: '', | ||
51 | + }) | ||
52 | + | ||
53 | + //删除SN的表单 | ||
54 | + const dynamicValidateDeleteForm = reactive({ | ||
55 | + SNs: [ | ||
56 | + { | ||
57 | + key: 1, | ||
58 | + value: '', | ||
59 | + }, | ||
60 | + ] | ||
61 | + }) | ||
62 | + | ||
63 | + | ||
64 | + | ||
65 | + const removeAddFormDomain = (domainItem) => { | ||
66 | + const index = dynamicValidateAddForm.SNs.indexOf(domainItem) | ||
67 | + if (index > 0) { | ||
68 | + dynamicValidateAddForm.SNs.splice(index, 1) | ||
69 | + } | ||
70 | + } | ||
71 | + const removeDeleteFormDomain = (domainItem) => { | ||
72 | + const index = dynamicValidateDeleteForm.SNs.indexOf(domainItem) | ||
73 | + if (index > 0) { | ||
74 | + dynamicValidateDeleteForm.SNs.splice(index, 1) | ||
75 | + } | ||
76 | + } | ||
77 | + | ||
78 | + const addSNAddDomain = () => { | ||
79 | + dynamicValidateAddForm.SNs.push({ | ||
80 | + key: Date.now(), | ||
81 | + value: '', | ||
82 | + }) | ||
83 | + } | ||
84 | + | ||
85 | + const addSNDeleteDomain = () => { | ||
86 | + dynamicValidateDeleteForm.SNs.push({ | ||
87 | + key: Date.now(), | ||
88 | + value: '', | ||
89 | + }) | ||
90 | + } | ||
91 | + | ||
92 | + //提交添加SN | ||
93 | + const submitAddSNForm = (formInstance) => { | ||
94 | + if (!formInstance) return | ||
95 | + formInstance.validate((valid) => { | ||
96 | + if (valid) { | ||
97 | + let addSNs = []; | ||
98 | + for (let SNItem of dynamicValidateAddForm.SNs) { | ||
99 | + addSNs.push(SNItem.value.trim()) | ||
100 | + } | ||
101 | + | ||
102 | + //调用后端接口添加SNs | ||
103 | + axios({ | ||
104 | + method: addSNsApi.method, | ||
105 | + url: addSNsApi.url, | ||
106 | + data: { | ||
107 | + projectName: dynamicValidateAddForm.projectName, | ||
108 | + sns: addSNs | ||
109 | + } | ||
110 | + }).then(response => { | ||
111 | + if (response.data.code == 200) { | ||
112 | + ElMessage({ | ||
113 | + //showClose: true, | ||
114 | + duration: 3000, | ||
115 | + message: response.data.message, | ||
116 | + type: 'success', | ||
117 | + }) | ||
118 | + | ||
119 | + } else { | ||
120 | + ElMessage({ | ||
121 | + //showClose: true, | ||
122 | + duration: 3000, | ||
123 | + message: response.data.message, | ||
124 | + type: 'error', | ||
125 | + }) | ||
126 | + } | ||
127 | + | ||
128 | + }).catch(err => { | ||
129 | + ElMessage.error(err) | ||
130 | + }) | ||
131 | + console.log(dynamicValidateAddForm.projectName) | ||
132 | + } else { | ||
133 | + console.log('error submit!') | ||
134 | + return false | ||
135 | + } | ||
136 | + }) | ||
137 | + } | ||
138 | + | ||
139 | + //提交删除SN | ||
140 | + const submitDeleteSNForm = (formInstance) => { | ||
141 | + if (!formInstance) return | ||
142 | + formInstance.validate((valid) => { | ||
143 | + if (valid) { | ||
144 | + let deleteSNs = []; | ||
145 | + for (let SNItem of dynamicValidateDeleteForm.SNs) { | ||
146 | + deleteSNs.push(SNItem.value.trim()) | ||
147 | + } | ||
148 | + | ||
149 | + //调用后端接口删除SNs | ||
150 | + axios({ | ||
151 | + method: deleteSNsApi.method, | ||
152 | + url: deleteSNsApi.url, | ||
153 | + data: { | ||
154 | + sns: deleteSNs | ||
155 | + } | ||
156 | + }).then(response => { | ||
157 | + if (response.data.code == 200) { | ||
158 | + ElMessage({ | ||
159 | + //showClose: true, | ||
160 | + duration: 3000, | ||
161 | + message: response.data.message, | ||
162 | + type: 'success', | ||
163 | + }) | ||
164 | + } else { | ||
165 | + ElMessage({ | ||
166 | + //showClose: true, | ||
167 | + duration: 3000, | ||
168 | + message: response.data.message, | ||
169 | + type: 'error', | ||
170 | + }) | ||
171 | + } | ||
172 | + | ||
173 | + }).catch(err => { | ||
174 | + ElMessage.error(err) | ||
175 | + }) | ||
176 | + | ||
177 | + } else { | ||
178 | + console.log('error submit!') | ||
179 | + return false | ||
180 | + } | ||
181 | + }) | ||
182 | + } | ||
183 | + | ||
184 | + const resetForm = (formInstance) => { | ||
185 | + if (!formInstance) return | ||
186 | + formInstance.resetFields() | ||
187 | + } | ||
188 | + | ||
189 | + | ||
190 | +</script> | ||
191 | + | ||
192 | +<template> | ||
193 | + <div class="home"> | ||
194 | + | ||
195 | + <el-tabs type="border-card" v-model="currForm" @tab-click="changeForm"> | ||
196 | + <el-tab-pane label="添加SN" name="1"></el-tab-pane> | ||
197 | + <el-tab-pane label="删除SN" name="2"></el-tab-pane> | ||
198 | + <el-tab-pane label="获取SN" name="3"></el-tab-pane> | ||
199 | + | ||
200 | + <el-form | ||
201 | + ref="addFormRef" | ||
202 | + style="max-width: 600px" | ||
203 | + :model="dynamicValidateAddForm" | ||
204 | + label-width="auto" | ||
205 | + class="demo-dynamic" | ||
206 | + v-show="currForm == 1? true : false" | ||
207 | + > | ||
208 | + <el-form-item | ||
209 | + prop="projectName" | ||
210 | + label="项目名称" | ||
211 | + :rules="[ | ||
212 | + { | ||
213 | + required: true, | ||
214 | + message: '请输入项目名称', | ||
215 | + trigger: 'blur', | ||
216 | + } | ||
217 | + ]" | ||
218 | + > | ||
219 | + <el-input v-model="dynamicValidateAddForm.projectName" /> | ||
220 | + </el-form-item> | ||
221 | + <el-form-item | ||
222 | + v-for="(SN, index) in dynamicValidateAddForm.SNs" | ||
223 | + :key="SN.key" | ||
224 | + :label="'SN' + (index+1)" | ||
225 | + :prop="'SNs.' + index + '.value'" | ||
226 | + :rules="{ | ||
227 | + required: true, | ||
228 | + message: 'SN不能为空', | ||
229 | + trigger: 'blur', | ||
230 | + }" | ||
231 | + > | ||
232 | + <el-input v-model="SN.value" /> | ||
233 | + <el-button class="mt-2" @click.prevent="removeAddFormDomain(SN)" | ||
234 | + >移除</el-button | ||
235 | + > | ||
236 | + </el-form-item> | ||
237 | + <el-form-item> | ||
238 | + <el-button type="primary" @click="submitAddSNForm(addFormRef)">提交</el-button> | ||
239 | + <el-button @click="addSNAddDomain">添加选项</el-button> | ||
240 | + <el-button @click="resetForm(addFormRef)">重置</el-button> | ||
241 | + </el-form-item> | ||
242 | + </el-form> | ||
243 | + | ||
244 | + <el-form | ||
245 | + ref="deleteFormRef" | ||
246 | + style="max-width: 600px" | ||
247 | + :model="dynamicValidateDeleteForm" | ||
248 | + label-width="auto" | ||
249 | + class="demo-dynamic" | ||
250 | + v-show="currForm == 2? true : false" | ||
251 | + > | ||
252 | + <el-form-item | ||
253 | + v-for="(SN, index) in dynamicValidateDeleteForm.SNs" | ||
254 | + :key="SN.key" | ||
255 | + :label="'SN' + (index+1)" | ||
256 | + :prop="'SNs.' + index + '.value'" | ||
257 | + :rules="{ | ||
258 | + required: true, | ||
259 | + message: 'SN不能为空', | ||
260 | + trigger: 'blur', | ||
261 | + }" | ||
262 | + > | ||
263 | + <el-input v-model="SN.value" /> | ||
264 | + <el-button class="mt-2" @click.prevent="removeDeleteFormDomain(SN)" | ||
265 | + >移除</el-button | ||
266 | + > | ||
267 | + </el-form-item> | ||
268 | + <el-form-item> | ||
269 | + <el-button type="primary" @click="submitDeleteSNForm(deleteFormRef)">提交</el-button> | ||
270 | + <el-button @click="addSNDeleteDomain">添加选项</el-button> | ||
271 | + <el-button @click="resetForm(deleteFormRef)">重置</el-button> | ||
272 | + </el-form-item> | ||
273 | + </el-form> | ||
274 | + | ||
275 | + <el-text class="mx-1" v-show="currForm == 3? true : false"> | ||
276 | + {{ SNsContent }} | ||
277 | + </el-text> | ||
278 | + | ||
279 | + | ||
280 | + </el-tabs> | ||
281 | + | ||
282 | + | ||
283 | + | ||
284 | + </div> | ||
285 | + | ||
286 | +</template> | ||
287 | + | ||
288 | +<style> | ||
289 | + .home { | ||
290 | + width: 50%; | ||
291 | + margin: 0px auto; | ||
292 | + } | ||
293 | + | ||
294 | +</style> | ||
295 | + | ||
296 | + |
vite.config.js
0 → 100644
1 | +import { fileURLToPath, URL } from 'node:url' | ||
2 | +import BaseUrl from './public/config' | ||
3 | +import { defineConfig } from 'vite' | ||
4 | +import vue from '@vitejs/plugin-vue' | ||
5 | + | ||
6 | +// https://vitejs.dev/config/ | ||
7 | +export default defineConfig({ | ||
8 | + plugins: [ | ||
9 | + vue(), | ||
10 | + ], | ||
11 | + resolve: { | ||
12 | + alias: { | ||
13 | + '@': fileURLToPath(new URL('./src', import.meta.url)) | ||
14 | + } | ||
15 | + }, | ||
16 | + //设置代理请求 | ||
17 | + server: { | ||
18 | + proxy: { | ||
19 | + '/api': { | ||
20 | + // 后台地址 | ||
21 | + target: BaseUrl.URL, | ||
22 | + changeOrigin: true, | ||
23 | + rewrite: path => path.replace(/^\/api/, '') | ||
24 | + } | ||
25 | + } | ||
26 | + } | ||
27 | +}) |