├── public
└── favicon.ico
├── src
├── App.vue
├── methods
│ ├── logout.js
│ ├── admin.js
│ ├── register.js
│ ├── login.js
│ ├── reader.js
│ ├── book.js
│ └── borrow.js
├── assets
│ ├── logo.svg
│ ├── main.css
│ └── base.css
├── stores
│ ├── token.js
│ ├── admin.js
│ └── reader.js
├── main.js
├── css
│ └── main.css
├── router
│ └── index.js
├── util
│ └── request.js
├── components
│ ├── SideView.vue
│ └── HeaderView.vue
└── views
│ ├── UserView.vue
│ ├── RegisterView.vue
│ ├── LoginView.vue
│ ├── BorrowView.vue
│ ├── admin
│ ├── ReaderView.vue
│ └── AdminBookView.vue
│ └── BookView.vue
├── jsconfig.json
├── .eslintrc.cjs
├── vue3-vite.iml
├── index.html
├── .gitignore
├── package.json
├── LICENSE
├── vite.config.js
└── README.md
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/caolib/vue3-vite/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "paths": {
4 | "@/*": ["./src/*"]
5 | }
6 | },
7 | "exclude": ["node_modules", "dist"]
8 | }
9 |
--------------------------------------------------------------------------------
/src/methods/logout.js:
--------------------------------------------------------------------------------
1 | import request from "@/util/request.js";
2 | // 用户退出登录
3 | const logoutService = function () {
4 | // 调用后端接口清除redis中的令牌
5 | return request.delete('/logout');
6 | }
7 |
8 | export {logoutService}
9 |
10 |
--------------------------------------------------------------------------------
/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | /* eslint-env node */
2 | module.exports = {
3 | root: true,
4 | 'extends': [
5 | 'plugin:vue/vue3-essential',
6 | 'eslint:recommended'
7 | ],
8 | parserOptions: {
9 | ecmaVersion: 'latest'
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/methods/admin.js:
--------------------------------------------------------------------------------
1 | import request from "@/util/request";
2 |
3 |
4 | /**
5 | * 更新管理员信息
6 | */
7 | const updateAdminService = function (admin) {
8 | return request.put('/admin/update',admin);
9 | };
10 |
11 | export {updateAdminService};
--------------------------------------------------------------------------------
/src/assets/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/methods/register.js:
--------------------------------------------------------------------------------
1 | import request from "@/util/request";
2 | // 读者注册
3 | const registerService = function (reader) {
4 | return request.post('/reader/register',reader);
5 | };
6 |
7 | // 管理员注册
8 | const adminRegisterService = (admin)=>{
9 | return request.post('/admin/register',admin)
10 | }
11 |
12 | export {registerService,adminRegisterService};
--------------------------------------------------------------------------------
/src/methods/login.js:
--------------------------------------------------------------------------------
1 | import request from "@/util/request";
2 |
3 | // 读者登录
4 | const loginService = function (reader) {
5 | return request.post('/reader/login', reader);
6 | };
7 |
8 | // 管理员登录
9 | const adminLoginService = function (admin) {
10 | return request.post('/admin/login', admin);
11 | }
12 |
13 |
14 | export {loginService, adminLoginService};
--------------------------------------------------------------------------------
/vue3-vite.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | 图书借阅管理系统
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | .DS_Store
12 | dist
13 | dist-ssr
14 | coverage
15 | *.local
16 |
17 | /cypress/videos/
18 | /cypress/screenshots/
19 |
20 | # Editor directories and files
21 | .vscode/*
22 | !.vscode/extensions.json
23 | .idea
24 | *.suo
25 | *.ntvs*
26 | *.njsproj
27 | *.sln
28 | *.sw?
29 |
30 | *.tsbuildinfo
31 |
--------------------------------------------------------------------------------
/src/methods/reader.js:
--------------------------------------------------------------------------------
1 | import request from "@/util/request";
2 |
3 | // 修改用户信息
4 | const updateReaderService = function (reader) {
5 | return request.post('/reader/update', reader);
6 | };
7 |
8 | // 查询所有用户信息
9 | const getAllReaderService = (condition) => {
10 | return request.post('/reader', condition);
11 | }
12 |
13 |
14 | // 根据id删除读者信息
15 | const deleteReaderService = (id) => {
16 | return request.delete('/reader/' + id);
17 | }
18 | export {
19 | updateReaderService,
20 | getAllReaderService,
21 | deleteReaderService
22 | };
--------------------------------------------------------------------------------
/src/methods/book.js:
--------------------------------------------------------------------------------
1 | import request from "@/util/request";
2 | // 条件分页查询
3 | const getAllBookService = function (condition) {
4 | return request.post("/book", condition);
5 | };
6 |
7 | // 添加书籍
8 | const addBookService = (book)=>{
9 | return request.post("/book/add", book);
10 | }
11 |
12 | // 删除书籍
13 | const deleteBookService = (isbn)=>{
14 | return request.delete("/book/"+isbn);
15 | }
16 |
17 | // 更新书籍信息
18 | const updateBookService = (book)=>{
19 | return request.put("/book",book)
20 | }
21 |
22 | export {getAllBookService,addBookService,deleteBookService,updateBookService};
23 |
--------------------------------------------------------------------------------
/src/stores/token.js:
--------------------------------------------------------------------------------
1 | import {defineStore} from "pinia";
2 | import {ref} from 'vue';
3 |
4 | export const useTokenStore = defineStore('token', () => {
5 | //1.定义描述token
6 | const token = ref('')
7 | //2.定义修改token的方法
8 | const setToken = (newToken) => {
9 | token.value = newToken
10 | }
11 | //3.定义移除token的方法
12 | const removeToken = () => {
13 | token.value = ''
14 | }
15 | return {
16 | token, setToken, removeToken
17 | }
18 | },
19 | {
20 | //使用persis插件持久化
21 | persis: true
22 | }
23 | )
--------------------------------------------------------------------------------
/src/assets/main.css:
--------------------------------------------------------------------------------
1 | @import './base.css';
2 |
3 | #app {
4 | max-width: 1280px;
5 | margin: 0 auto;
6 | padding: 2rem;
7 | font-weight: normal;
8 | }
9 |
10 | a,
11 | .green {
12 | text-decoration: none;
13 | color: hsla(160, 100%, 37%, 1);
14 | transition: 0.4s;
15 | padding: 3px;
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 | }
36 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
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 "element-plus/theme-chalk/dark/css-vars.css";
9 | import "@/css/main.css";
10 |
11 | import { createPinia } from "pinia";
12 | import { createPersistedState } from "pinia-persistedstate-plugin";
13 |
14 | // 导入element-plus中文语言
15 | import zhCn from "element-plus/dist/locale/zh-cn.mjs";
16 |
17 | const app = createApp(App);
18 |
19 | // 使用pinia和persist保存状态并持久化
20 | const pinia = createPinia();
21 | const persist = createPersistedState();
22 | pinia.use(persist);
23 |
24 | app.use(ElementPlus, { locale: zhCn });
25 | app.use(router);
26 | app.use(pinia);
27 |
28 | app.mount("#app");
29 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-project",
3 | "version": "0.0.0",
4 | "private": true,
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "preview": "vite preview",
10 | "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore"
11 | },
12 | "dependencies": {
13 | "@element-plus/icons-vue": "^2.3.1",
14 | "@vueuse/core": "^10.7.1",
15 | "axios": "^1.6.5",
16 | "element-plus": "^2.4.4",
17 | "pinia": "^2.1.7",
18 | "pinia-persistedstate-plugin": "^0.1.0",
19 | "vue": "^3.3.11",
20 | "vue-router": "^4.2.5",
21 | "vuex": "^4.0.2"
22 | },
23 | "devDependencies": {
24 | "@vitejs/plugin-vue": "^4.5.2",
25 | "eslint": "^8.49.0",
26 | "eslint-plugin-vue": "^9.17.0",
27 | "unplugin-auto-import": "^0.17.3",
28 | "unplugin-vue-components": "^0.26.0",
29 | "vite": "^5.1.2"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/stores/admin.js:
--------------------------------------------------------------------------------
1 | import {defineStore} from "pinia";
2 | import {ref} from 'vue';
3 |
4 | /**
5 | * 保存登录时的管理员信息
6 | */
7 | export const useAdminStore = defineStore('admin', () => {
8 | const admin = ref({
9 | id: '',
10 | username: '',
11 | nickname: '',
12 | token:''
13 | });
14 | // 是否为管理员
15 | let isAdmin = ref();
16 | const setIsAdmin = (flag)=>{
17 | isAdmin.value = flag;
18 | }
19 | const setAdmin = (data) => {
20 | admin.value = data;
21 | }
22 | //清除信息
23 | const clearAdmin = ()=>{
24 | admin.value.id = '';
25 | admin.value.username = '';
26 | admin.value.nickname = '';
27 | admin.value.token = '';
28 | }
29 |
30 | return {
31 | admin, setAdmin,isAdmin,setIsAdmin,clearAdmin
32 | }
33 | },
34 | // 持久化,pinia保存在内存中,刷新即丢失
35 | {
36 | persis: true
37 | }
38 | )
39 |
--------------------------------------------------------------------------------
/src/stores/reader.js:
--------------------------------------------------------------------------------
1 | import {defineStore} from "pinia";
2 | import {ref} from 'vue';
3 |
4 | /**
5 | * 保存登录时用户的信息
6 | */
7 | export const useReaderStore = defineStore('reader', () => {
8 | const reader = ref({
9 | id: '',
10 | username: '',
11 | nickname: '',
12 | gender: '',
13 | age: '',
14 | tel: '',
15 | token: ''
16 | });
17 | const setReader = (data) => {
18 | reader.value = data;
19 | }
20 | //清除信息
21 | const clearReader = () => {
22 | reader.value.id = '';
23 | reader.value.username = '';
24 | reader.value.nickname = '';
25 | reader.value.gender = '';
26 | reader.value.age = '';
27 | reader.value.tel = '';
28 | reader.value.token = '';
29 | }
30 | return {
31 | reader, setReader, clearReader
32 | }
33 | },
34 | {
35 | persis: true
36 | }
37 | )
38 |
--------------------------------------------------------------------------------
/src/css/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | /*背景图片*/
3 | background-image: url("https://dogefs.s3.ladydaily.com/~/source/wallhaven/full/jx/wallhaven-jxl3qp.jpg?w=2560&h=1440&fmt=webp");
4 | background-repeat: no-repeat;
5 | background-size: cover;
6 | }
7 |
8 | body::after {
9 | content: "";
10 | position: absolute;
11 | top: 0;
12 | right: 0;
13 | bottom: 0;
14 | left: 0;
15 | background: rgba(0, 0, 0, 0.2); /* 这里的0.5是遮罩的透明度*/
16 | z-index: -1;
17 | }
18 |
19 | #checkTheme {
20 | background-color: rgba(0, 0, 0, 0);
21 | }
22 |
23 | /* 表格添加圆角 */
24 | .el-table {
25 | opacity: 0.75;
26 | border-radius: 10px; /* 圆角半径 */
27 | overflow: hidden; /* 隐藏超出边界的内容 */
28 | box-shadow: 10px 10px 10px rgba(0, 0, 0, 0.5);
29 | }
30 |
31 | .el-header {
32 | height: 550px;
33 | border-top-left-radius: 10px;
34 | border-top-right-radius: 10px;
35 | overflow: hidden;
36 | }
37 |
38 | .el-aside {
39 | border-bottom-left-radius: 10px;
40 | overflow: hidden;
41 | height: 550px;
42 | }
43 |
44 | .el-dialog {
45 | border-radius: 20px;
46 | }
47 |
--------------------------------------------------------------------------------
/src/methods/borrow.js:
--------------------------------------------------------------------------------
1 | import request from "@/util/request";
2 |
3 | // 查询个人的借书记录
4 | const getBorrowByReaderIdService = function () {
5 | return request.get('/borrow');
6 | };
7 |
8 | //借书
9 | const borrowService = function (isbn, dueDate) {
10 | return request.get('/borrow/borrowBook', {
11 | params: {
12 | isbn: isbn,
13 | dueDate: dueDate
14 | }
15 | });
16 | };
17 | // 还书
18 | const returnBookService = function (id, isbn) {
19 | console.log(id);
20 | return request.get('/borrow/returnBook', {
21 | params: {
22 | id: id,
23 | isbn: isbn
24 | }
25 | });
26 | };
27 |
28 | // 删除借书记录
29 | const deleteByIdService = function (id) {
30 | return request.delete('/borrow', {
31 | params: {id: id},
32 | });
33 | };
34 |
35 | //批量删除借阅记录
36 | const deleteBorrowBatchService = function (ids) {
37 | return request.post('/borrow/batch', ids);
38 | };
39 |
40 | export {
41 | getBorrowByReaderIdService,
42 | borrowService,
43 | returnBookService,
44 | deleteByIdService,
45 | deleteBorrowBatchService
46 | };
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 LiBin Cao
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import { fileURLToPath, URL } from "node:url";
2 |
3 | import { defineConfig } from "vite";
4 | import vue from "@vitejs/plugin-vue";
5 | import AutoImport from "unplugin-auto-import/vite";
6 | import Components from "unplugin-vue-components/vite";
7 | import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
8 |
9 | // https://vitejs.dev/config/
10 | export default defineConfig({
11 | plugins: [
12 | vue(),
13 | AutoImport({
14 | resolvers: [ElementPlusResolver()],
15 | }),
16 | Components({
17 | resolvers: [ElementPlusResolver()],
18 | }),
19 | ],
20 | resolve: {
21 | alias: {
22 | "@": fileURLToPath(new URL("./src", import.meta.url)),
23 | },
24 | },
25 | //代理http请求,解决跨域问题
26 | server: {
27 | // host: '192.168.0.66',
28 | // 前端地址
29 | host: "localhost",
30 | port: 5173,
31 | proxy: {
32 | "/api": {
33 | //匹配请求路径中含有 /api 的请求
34 | // target: 'http://47.115.226.138:8080', //后端服务地址
35 | target: "http://laptop:10086", //后端服务地址
36 | changeOrigin: true,
37 | rewrite: (path) => path.replace(/^\/api/, ""), //去除路径中的/api,还原请求路径
38 | },
39 | },
40 | },
41 | });
42 |
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | import {createRouter, createWebHistory} from "vue-router";
2 |
3 | const router = createRouter({
4 | history: createWebHistory(import.meta.env.BASE_URL),
5 | routes: [
6 | {
7 | path: "/",
8 | name: "home",
9 | component: () => import("../views/LoginView.vue"),
10 | },
11 | {
12 | path: "/book",
13 | name: "book",
14 | component: () => import("../views/BookView.vue"),
15 | },
16 | {
17 | path: "/admin/book",
18 | name: "adminBorrow",
19 | component: () => import("../views/admin/AdminBookView.vue"),
20 | },
21 | {
22 | path: "/login",
23 | name: "login",
24 | component: () => import("../views/LoginView.vue"),
25 | },
26 | {
27 | path: "/register",
28 | name: "register",
29 | component: () => import("../views/RegisterView.vue"),
30 | },
31 | {
32 | path: "/user",
33 | name: "user",
34 | component: () => import("../views/UserView.vue"),
35 | },
36 | {
37 | path: "/borrow",
38 | name: "borrow",
39 | component: () => import("../views/BorrowView.vue"),
40 | },
41 | {
42 | path: "/reader",
43 | name: "reader",
44 | component: () => import("../views/admin/ReaderView.vue"),
45 | },
46 | ],
47 | });
48 |
49 | export default router;
50 |
--------------------------------------------------------------------------------
/src/util/request.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 | import {ElMessage} from "element-plus";
3 | import router from "@/router";
4 | import {useTokenStore} from "@/stores/token.js";
5 |
6 | const baseURL = "/api";
7 | const instance = axios.create({baseURL});
8 | const tokenStore = useTokenStore();
9 |
10 |
11 | //响应拦截器,状态码为2xx时执行成功回调,否则执行失败回调
12 | instance.interceptors.response.use(
13 | //成功回调
14 | (result) => {
15 | // 如果状态码为0,后端发生异常
16 | if (result.data.code === 0) {
17 | ElMessage.error(result.data.msg);
18 | return Promise.reject(result);
19 | }
20 | return result.data;
21 | },
22 | //失败回调
23 | (error) => {
24 | const code = error.response.status;
25 | switch (code) {
26 | case 401:
27 | ElMessage({message: '请先登录!', type: "error",});
28 | break;
29 | case 419:
30 | ElMessage.error("身份已过期,请重新登录!");
31 | break;
32 | default:
33 | ElMessage.error("服务器异常!" + code);
34 | break;
35 | }
36 | router.push('/login');
37 | window.local.reload();
38 |
39 |
40 | // 将异步的状态设置为失败状态
41 | return Promise.reject(error);
42 | }
43 | );
44 |
45 | // 请求拦截器
46 | instance.interceptors.request.use(
47 | (config) => {
48 | //登录请求不需要token
49 | if (config.url.endsWith('/login') || config.url.endsWith('/register')) {
50 | return config;
51 | }
52 | //如果有token,将token放入请求头中
53 | const token = tokenStore.token;
54 | if (token != null) {
55 | config.headers['token'] = token;
56 | } else {
57 | router.push('/login');
58 | ElMessage({message: '请先登录!', type: "error",});
59 | return Promise.reject('token不存在!');
60 | }
61 | return config;
62 | },
63 | (err) => {
64 | //请求错误的回调
65 | return Promise.reject(err);
66 | }
67 | );
68 |
69 | export default instance;
70 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://git.io/typing-svg)
2 |
3 |
4 |

5 |

6 |

7 |

8 |

9 |

10 |

11 |
12 |
13 | > [!important]
14 | >
15 | > 简介:图书借阅管理系统前端,使用vue3框架
16 | >
17 | > **这是对应的 [后端项目地址](https://github.com/caolib/java_design)**
18 |
19 | ## 快速使用
20 |
21 | ### 1.进入项目根目录,使用npm命令下载项目所需的依赖模块
22 |
23 | > [!caution]
24 | >
25 | > :boom:**注意:要先安装nodejs,最好以管理员身份执行命令!!!**:boom:
26 |
27 | ```cmd
28 | npm install
29 | ```
30 |
31 | ### 2.修改配置文件
32 |
33 | 打开`vite.config.js`文件,可以自行修改前端地址,也可以修改向后端请求的地址,但是要相应地修改后端项目的启动路径
34 |
35 | ```js
36 | //代理http请求,解决跨域问题
37 | server: {
38 | // 前端项目启动路径,localhost:5173
39 | host: 'localhost',
40 | port: 5173,
41 | proxy: {
42 | '/api': { //匹配请求路径中含有 /api 的请求
43 | target: 'http://localhost:8080', //后端服务地址
44 | changeOrigin: true,
45 | rewrite: (path) => path.replace(/^\/api/, '') //去除路径中的/api,还原请求路径
46 | }
47 | }
48 | },
49 | ```
50 |
51 | ### 3.执行命令,启动项目
52 |
53 | ```cmd
54 | npm run dev
55 | ```
56 |
57 | ## 项目目录结构
58 |
59 | - `components`:公共组件,包括顶部导航和侧栏
60 | - `css`:全局样式
61 | - `methods`:前端所有向后端发送的请求api
62 | - `router`:界面路由
63 | - `stores`:pinia存储
64 | - `util`:工具方法
65 | - `views`:页面
66 | - `main.js`:入口文件,app的初始化
67 | - `package.json`:项目的各种依赖,执行脚本等
68 | - `vite.config.js`:项目配置文件
69 |
70 | 
71 |
--------------------------------------------------------------------------------
/src/assets/base.css:
--------------------------------------------------------------------------------
1 | /* color palette from */
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:
66 | color 0.5s,
67 | background-color 0.5s;
68 | line-height: 1.6;
69 | font-family:
70 | Inter,
71 | -apple-system,
72 | BlinkMacSystemFont,
73 | 'Segoe UI',
74 | Roboto,
75 | Oxygen,
76 | Ubuntu,
77 | Cantarell,
78 | 'Fira Sans',
79 | 'Droid Sans',
80 | 'Helvetica Neue',
81 | sans-serif;
82 | font-size: 15px;
83 | text-rendering: optimizeLegibility;
84 | -webkit-font-smoothing: antialiased;
85 | -moz-osx-font-smoothing: grayscale;
86 | }
87 |
--------------------------------------------------------------------------------
/src/components/SideView.vue:
--------------------------------------------------------------------------------
1 |
2 |
46 |
47 |
48 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/src/components/HeaderView.vue:
--------------------------------------------------------------------------------
1 |
53 |
54 |
55 |
117 |
118 |
--------------------------------------------------------------------------------
/src/views/UserView.vue:
--------------------------------------------------------------------------------
1 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
58 |
59 | 个人信息
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
94 |
95 |
96 |
97 |
98 | 保存
99 | 取消
102 |
103 |
104 |
105 |
106 |
107 |
115 |
116 | 个人信息
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 | 保存
128 | 取消
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
--------------------------------------------------------------------------------
/src/views/RegisterView.vue:
--------------------------------------------------------------------------------
1 |
67 |
68 |
69 |
70 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
90 |
91 |
92 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
122 |
123 |
132 |
133 |
134 |
135 |
136 | 注册
137 | 返回
140 |
141 |
142 |
143 |
144 |
145 |
166 |
--------------------------------------------------------------------------------
/src/views/LoginView.vue:
--------------------------------------------------------------------------------
1 |
113 |
114 |
115 |
116 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
136 |
137 |
138 |
139 | 登录
141 |
143 | 注册
145 |
147 |
148 |
149 |
158 |
159 |
160 |
161 |
162 |
184 |
--------------------------------------------------------------------------------
/src/views/BorrowView.vue:
--------------------------------------------------------------------------------
1 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 | 全部
104 | 已归还
105 | 未归还
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 | 未归还
127 | 已归还
128 |
129 |
130 |
131 |
132 |
133 |
136 | 归还
137 |
138 |
140 | 删除记录
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
172 |
--------------------------------------------------------------------------------
/src/views/admin/ReaderView.vue:
--------------------------------------------------------------------------------
1 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
102 |
103 |
104 |
105 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 | 修改
127 |
128 |
129 | 删除
130 |
131 |
132 |
133 |
134 |
135 |
136 |
138 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 | 保存
175 | 取消
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
--------------------------------------------------------------------------------
/src/views/BookView.vue:
--------------------------------------------------------------------------------
1 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
129 |
130 |
131 |
138 |
139 |
140 |
141 |
148 |
149 |
150 |
151 |
158 |
159 |
160 |
161 |
162 |
163 |
170 |
171 |
172 |
173 |
179 |
180 |
181 |
182 | 详细信息
188 |
189 | 借阅
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 | 借阅
205 |
206 |
211 | 选择归还日期
212 |
213 |
214 |
223 |
224 |
225 |
226 | 取消
227 | 提交
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
246 |
247 |
248 |
249 |
262 |
263 |
264 |
269 |
277 | 《{{ book.title }}》
278 |
279 |
280 |
281 | {{ book.author }}
282 |
283 |
284 | {{ book.number }}
285 |
286 |
287 | {{ book.isbn }}
288 |
289 |
290 |
291 |
292 |
293 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
--------------------------------------------------------------------------------
/src/views/admin/AdminBookView.vue:
--------------------------------------------------------------------------------
1 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 | 详细信息
190 |
191 |
197 |
198 | 删除
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
217 |
218 |
219 |
220 |
222 |
223 |
224 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 | {{book.isbn}}
243 |
244 |
245 |
248 |
249 |
250 |
251 |
252 |
253 |
254 | 保存
255 | 取消
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 | 添加
286 | 取消
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
--------------------------------------------------------------------------------