Commit 2c62a85dc41d3433279a9b611ba9038fd410d417

Authored by 岑健浩
1 parent 6228a7a5

前端代码分支

.gitignore
... ... @@ -29,4 +29,22 @@ build/
29 29 .vscode/
30 30  
31 31 ### Mac OS ###
32   -.DS_Store
33 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 0 \ No newline at end of file
public/config.js 0 → 100644
  1 +const BaseUrl = {
  2 + URL: "http://127.0.0.1:8080/"
  3 +}
  4 +export default BaseUrl;
... ...
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
  1 +<template>
  2 + <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor">
  3 + <path
  4 + d="M10 3.22l-.61-.6a5.5 5.5 0 0 0-7.666.105 5.5 5.5 0 0 0-.114 7.665L10 18.78l8.39-8.4a5.5 5.5 0 0 0-.114-7.665 5.5 5.5 0 0 0-7.666-.105l-.61.61z"
  5 + />
  6 + </svg>
  7 +</template>
... ...
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
1   -package com.ectrip.demo.exception;
2   -
3   -public class SNRepetitiveException extends Exception{
4   -
5   - public SNRepetitiveException() {}
6   -
7   - public SNRepetitiveException(String message) {
8   - super(message);
9   - }
10   -
11   -}
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 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 0 \ No newline at end of file
src/main/resources/sn/SN.txt deleted
1   -sn6##项目2##2024-03-20 19:22:17
2   -sn7##项目2##2024-03-20 19:22:17
3   -sn8##项目2##2024-03-20 19:22:17
src/main/resources/sn/SNTemp.txt deleted
1   -sn6##项目2##2024-03-20 19:22:17
2   -sn7##项目2##2024-03-20 19:22:17
3   -sn8##项目2##2024-03-20 19:22:17
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 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 +})
... ...