├── .github
├── FUNDING.yml
└── workflows
│ ├── built-and-release.yml
│ ├── gh-pages.yml
│ └── npm-release.yml
├── .gitignore
├── LICENSE
├── README.md
├── README_ch.md
├── admin
├── .env.development
├── .env.production
├── .eslintrc.cjs
├── .gitignore
├── .vscode
│ └── extensions.json
├── README.md
├── directoryList.md
├── index.html
├── jsconfig.json
├── package.json
├── pnpm-lock.yaml
├── public
│ └── favicon.ico
├── qodana.yaml
├── src
│ ├── App.vue
│ ├── api
│ │ ├── admin.js
│ │ ├── comment.js
│ │ ├── student.js
│ │ └── topic.js
│ ├── assets
│ │ ├── carousel
│ │ │ ├── image1.jpg
│ │ │ ├── image2.jpg
│ │ │ ├── image3.jpg
│ │ │ ├── image4.jpg
│ │ │ ├── image5.jpg
│ │ │ └── image6.jpg
│ │ ├── logo
│ │ │ ├── default.png
│ │ │ ├── icon_logo.png
│ │ │ ├── login_bg.png
│ │ │ ├── logo.png
│ │ │ └── mini-logo.png
│ │ └── main.scss
│ ├── main.js
│ ├── router
│ │ └── index.js
│ ├── store
│ │ ├── admin.js
│ │ └── token.js
│ ├── style.css
│ ├── utils
│ │ ├── request.js
│ │ └── requestOptimize.js
│ └── views
│ │ ├── Dashboard.vue
│ │ ├── Login.vue
│ │ ├── admin
│ │ ├── Admin.vue
│ │ ├── addAdmin.vue
│ │ └── changePassword.vue
│ │ ├── notice
│ │ └── Notice.vue
│ │ ├── student
│ │ └── Student.vue
│ │ └── topic
│ │ └── Topic.vue
└── vite.config.js
├── backend
├── .gitignore
├── README.md
├── directoryList.md
├── package-lock.json
├── pom.xml
├── wall-common
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── cn
│ │ └── yiming1234
│ │ └── NottinghamWall
│ │ ├── constant
│ │ ├── AutoFillConstant.java
│ │ ├── JwtClaimsConstant.java
│ │ ├── MessageConstant.java
│ │ ├── PasswordConstant.java
│ │ └── StatusConstant.java
│ │ ├── context
│ │ └── BaseContext.java
│ │ ├── enumeration
│ │ └── OperationType.java
│ │ ├── exception
│ │ ├── AccountLockedException.java
│ │ ├── AccountNotFoundException.java
│ │ ├── BaseException.java
│ │ ├── DeletionNotAllowedException.java
│ │ ├── LoginFailedException.java
│ │ ├── MaxUploadSizeException.java
│ │ ├── PasswordEditFailedException.java
│ │ ├── PasswordErrorException.java
│ │ ├── TeapotException.java
│ │ └── UserNotLoginException.java
│ │ ├── json
│ │ └── JacksonObjectMapper.java
│ │ ├── properties
│ │ ├── AliOssProperties.java
│ │ ├── JwtProperties.java
│ │ └── WeChatProperties.java
│ │ ├── result
│ │ ├── PageResult.java
│ │ └── Result.java
│ │ └── utils
│ │ ├── AliOssUtil.java
│ │ ├── ContentCheckUtil.java
│ │ ├── HttpClientUtil.java
│ │ ├── ImageCheckUtil.java
│ │ └── JwtUtil.java
├── wall-pojo
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── cn
│ │ └── yiming1234
│ │ └── NottinghamWall
│ │ ├── dto
│ │ ├── AdminDTO.java
│ │ ├── AdminLoginDTO.java
│ │ ├── CommentDTO.java
│ │ ├── PageQueryDTO.java
│ │ ├── ReportDTO.java
│ │ ├── StudentDTO.java
│ │ ├── StudentLoginDTO.java
│ │ ├── TopicDTO.java
│ │ └── UpdatePasswordDTO.java
│ │ ├── entity
│ │ ├── Admin.java
│ │ ├── Comment.java
│ │ ├── Report.java
│ │ ├── Student.java
│ │ └── Topic.java
│ │ ├── typehandler
│ │ └── JsonTypeHandler.java
│ │ └── vo
│ │ ├── AdminLoginVO.java
│ │ └── StudentLoginVO.java
└── wall-server
│ ├── pom.xml
│ └── src
│ └── main
│ ├── java
│ └── cn
│ │ └── yiming1234
│ │ └── NottinghamWall
│ │ ├── WallApplication.java
│ │ ├── annotation
│ │ └── AutoFill.java
│ │ ├── aspect
│ │ └── AutoFillAspect.java
│ │ ├── config
│ │ ├── OssConfiguration.java
│ │ ├── RedisConfiguration.java
│ │ └── WebMvcConfiguration.java
│ │ ├── controller
│ │ ├── admin
│ │ │ ├── AdminCommonController.java
│ │ │ ├── AdminController.java
│ │ │ ├── ReportController.java
│ │ │ ├── StudentController.java
│ │ │ ├── TopicController.java
│ │ │ └── UniappController.java
│ │ └── student
│ │ │ ├── CommentController.java
│ │ │ ├── ReportController.java
│ │ │ ├── StudentCommonController.java
│ │ │ ├── StudentController.java
│ │ │ ├── TopicController.java
│ │ │ └── UniappController.java
│ │ ├── handler
│ │ └── GlobalExceptionHandler.java
│ │ ├── interceptor
│ │ ├── JwtTokenAdminInterceptor.java
│ │ └── JwtTokenStudentInterceptor.java
│ │ ├── mapper
│ │ ├── AdminMapper.java
│ │ ├── CommentMapper.java
│ │ ├── ReportMapper.java
│ │ ├── StudentMapper.java
│ │ └── TopicMapper.java
│ │ └── service
│ │ ├── AdminService.java
│ │ ├── CommentService.java
│ │ ├── ReportService.java
│ │ ├── StudentService.java
│ │ ├── TopicService.java
│ │ └── impl
│ │ ├── AdminServiceImpl.java
│ │ ├── CommentServiceImpl.java
│ │ ├── ReportServiceImpl.java
│ │ ├── StudentServiceImpl.java
│ │ └── TopicServiceImpl.java
│ └── resources
│ ├── application-template.yml
│ └── mapper
│ ├── AdminMapper.xml
│ ├── CommentMapper.xml
│ ├── ReportMapper.xml
│ ├── StudentMapper.xml
│ └── TopicMapper.xml
├── docs
├── .idea
│ ├── .gitignore
│ ├── .name
│ ├── UniappTool.xml
│ ├── docs.iml
│ ├── modules.xml
│ └── vcs.xml
├── .vitepress
│ ├── config.js
│ ├── config
│ │ ├── env.js
│ │ └── sidebar.js
│ └── theme
│ │ ├── index.js
│ │ └── layout.vue
├── CNAME
├── about.md
├── guide
│ ├── admin
│ │ ├── deployment.md
│ │ ├── index.md
│ │ └── project-structure.md
│ ├── backend
│ │ ├── api-design.md
│ │ ├── database-setup.md
│ │ ├── deployment.md
│ │ ├── index.md
│ │ └── project-structure.md
│ ├── getting-started.md
│ ├── index.md
│ ├── overview.md
│ └── uniapp
│ │ ├── deployment.md
│ │ ├── index.md
│ │ └── project-structure.md
└── index.md
├── nottinghamwall.sql
├── package-lock.json
├── package.json
├── pnpm-lock.yaml
└── uniapp
├── .gitignore
├── .hbuilderx
└── launch.json
├── directoryList.md
├── index.html
├── jsconfig.json
├── package.json
├── pnpm-lock.yaml
├── shims-uni.d.ts
├── src
├── App.vue
├── api
│ ├── collect.js
│ ├── comment.js
│ ├── getPhone.js
│ ├── like.js
│ ├── login.js
│ ├── topic.js
│ └── user.js
├── main.js
├── manifest.json
├── pages.json
├── pages
│ ├── favorites
│ │ ├── components
│ │ │ └── topic.vue
│ │ ├── index.vue
│ │ └── post.vue
│ ├── index
│ │ ├── about.vue
│ │ ├── components
│ │ │ ├── fab.vue
│ │ │ ├── swipper.vue
│ │ │ └── topic.vue
│ │ └── index.vue
│ ├── message
│ │ └── index.vue
│ ├── order
│ │ ├── address.vue
│ │ ├── location.vue
│ │ └── order.vue
│ ├── person
│ │ ├── authentication.vue
│ │ ├── editInfo.vue
│ │ ├── getPhone.vue
│ │ ├── person.vue
│ │ └── universe.vue
│ ├── topic
│ │ ├── create.vue
│ │ ├── report.vue
│ │ └── view.vue
│ └── transition
│ │ └── agreement.vue
├── shime-uni.d.ts
├── static
│ ├── carousel
│ │ ├── image1.jpg
│ │ ├── image2.jpg
│ │ ├── image3.jpg
│ │ ├── image4.jpg
│ │ ├── image5.jpg
│ │ └── image6.jpg
│ ├── default_avatar.jpg
│ ├── icon
│ │ ├── home-active.png
│ │ ├── home.png
│ │ ├── message-active.png
│ │ ├── message.png
│ │ ├── order-active.png
│ │ ├── order.png
│ │ ├── person-active.png
│ │ ├── person.png
│ │ ├── star-active.png
│ │ ├── star.png
│ │ ├── topic-active.png
│ │ └── topic.png
│ ├── logo.png
│ └── logo
│ │ ├── default.png
│ │ ├── icon_logo.png
│ │ ├── login_bg.png
│ │ ├── logo.png
│ │ └── mini-logo.png
├── uni.scss
└── utils
│ └── request.js
└── vite.config.js
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | custom: ['https://blog.yiming1234.cn']
2 |
--------------------------------------------------------------------------------
/.github/workflows/built-and-release.yml:
--------------------------------------------------------------------------------
1 | name: SpringBoot Built and Release
2 |
3 | on:
4 | workflow_dispatch:
5 | push:
6 | branches:
7 | - main
8 | paths:
9 | - 'backend/**'
10 |
11 | jobs:
12 | build:
13 |
14 | permissions: write-all
15 | runs-on: ubuntu-latest
16 | steps:
17 |
18 | - uses: actions/checkout@v3
19 | - name: Setup Java JDK
20 | uses: actions/setup-java@v4.2.1
21 | with:
22 | java-version: '17'
23 | distribution: 'temurin'
24 | cache: maven
25 | - name: maven-settings-xml-action
26 | uses: whelk-io/maven-settings-xml-action@v20
27 | with:
28 | repositories: ''
29 | servers: ''
30 | - name: Build with Maven
31 | run: mvn package -B -DskipTests --file backend/pom.xml
32 | - name: GH Release
33 | uses: softprops/action-gh-release@v2.0.6
34 | with:
35 | files: backend/wall-server/target/wall-server-*.jar
36 | name: Updated at 25/02/10
37 | tag_name: NottinghamWall-backend-v1.0
38 | - name: upload to server
39 | uses: appleboy/scp-action@master
40 | with:
41 | host: ${{secrets.SERVER_HOST}}
42 | username: ${{secrets.SERVER_USER}}
43 | password: ${{secrets.SERVER_PASSWORD}}
44 | port: 22
45 | source: "backend/wall-server/target/"
46 | target: ${{secrets.SERVER_PATH}}
47 |
--------------------------------------------------------------------------------
/.github/workflows/gh-pages.yml:
--------------------------------------------------------------------------------
1 | name: Deploy VitePress site to Pages
2 |
3 | on:
4 | workflow_dispatch:
5 | push:
6 | branches: [main]
7 |
8 | permissions:
9 | contents: read
10 | pages: write
11 | id-token: write
12 |
13 | concurrency:
14 | group: pages
15 | cancel-in-progress: false
16 |
17 | jobs:
18 | build:
19 | if: github.event.repository.fork == false
20 | runs-on: ubuntu-latest
21 | steps:
22 | - name: Checkout
23 | uses: actions/checkout@v4
24 | with:
25 | fetch-depth: 0
26 |
27 | - name: Setup Node
28 | uses: actions/setup-node@v4
29 | with:
30 | node-version: 20
31 | cache: npm
32 |
33 | - name: Setup Pages
34 | uses: actions/configure-pages@v4
35 |
36 | - name: Install dependencies
37 | run: npm ci
38 |
39 | - name: Build with VitePress
40 | run: npm run docs:build
41 |
42 | - name: Copy CNAME to dist
43 | run: cp docs/CNAME docs/.vitepress/dist/
44 |
45 | - name: Upload artifact
46 | uses: actions/upload-pages-artifact@v3
47 | with:
48 | path: docs/.vitepress/dist
49 |
50 | deploy:
51 | environment:
52 | name: github-pages
53 | url: ${{ steps.deployment.outputs.page_url }}
54 | needs: build
55 | runs-on: ubuntu-latest
56 | steps:
57 | - name: Deploy to GitHub Pages
58 | id: deployment
59 | uses: actions/deploy-pages@v4
60 |
--------------------------------------------------------------------------------
/.github/workflows/npm-release.yml:
--------------------------------------------------------------------------------
1 | name: Node.js Package Release
2 |
3 | on:
4 | workflow_dispatch:
5 | push:
6 | branches:
7 | - main
8 | paths:
9 | - 'admin/package.json'
10 |
11 | jobs:
12 |
13 | build:
14 | runs-on: ubuntu-latest
15 | steps:
16 | - uses: actions/checkout@v4
17 | - name: Setup Node.js environment
18 | uses: actions/setup-node@v4.0.3
19 | with:
20 | node-version: 20
21 | - name: Install dependencies
22 | run: npm install
23 | working-directory: ./admin
24 |
25 | publish:
26 | needs: build
27 | runs-on: ubuntu-latest
28 | steps:
29 | - uses: actions/checkout@v4
30 | - name: Setup Node.js environment
31 | uses: actions/setup-node@v4.0.3
32 | with:
33 | node-version: 20
34 | - name: Configure npm for npm registry
35 | run: |
36 | echo "@pleasure1234:registry=https://registry.npmjs.org/" > .npmrc
37 | echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" >> .npmrc
38 | working-directory: ./admin
39 | - name: Publish to npm
40 | run: npm publish
41 | working-directory: ./admin
42 | env:
43 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
44 | - name: Configure npm for GitHub Packages
45 | run: |
46 | echo "@NottinghamWall:registry=https://npm.pkg.github.com/" > .npmrc
47 | echo "//npm.pkg.github.com/:_authToken=${{ secrets.GH_TOKEN }}" >> .npmrc
48 | working-directory: ./admin
49 | - name: Publish to GitHub Packages
50 | run: npm publish --registry=https://npm.pkg.github.com/
51 | working-directory: ./admin
52 | env:
53 | NODE_AUTH_TOKEN: ${{ secrets.GH_TOKEN }}
54 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | backend/wall-server/src/main/resources/application.yml
2 | backend/wall-server/src/main/resources/application-dev.yml
3 | backend/wall-server/src/main/resources/application-prod.yml
4 | backend/wall-server/target/classes/application.yml
5 | backend/wall-server/target/classes/application-dev.yml
6 | backend/wall-server/target/classes/application-prod.yml
7 |
8 | uniapp/src/utils/env.js
9 | uniapp/dist/mp-weixin/utils/env.js
10 |
11 | node_modules/
12 | docs/.vitepress/dist
13 | docs/.vitepress/cache
14 |
15 | .idea/
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Computer Psycho Union
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # University of Nottingham Ningbo Campus Wall
2 | 🌏 English | [中文](/README_ch.md)
3 |
4 | ## Project Overview
5 |
6 | Initiated and developed by Pleasurecruise, a the Computer Science (2+2) program student of Class of 2027, and established on June 15, 2024.
7 |
8 | This project primarily consists of three parts: the server side, the mini-program side, and the management side.
9 |
10 | If you encounter any issues during deployment or have any suggestions, feel free to commit above.
11 |
12 | **Under Development**
13 |
14 | ## Notes
15 |
16 | Since features such as order placement and user information retrieval involve value-added business reviews and require corresponding business licenses, some testing is conducted on the WeChat Mini-Program test account.
17 |
18 | Version 1.0 of the mini-program is now live! Search for `CPU Wall` on WeChat or scan the mini-program code below to experience it.
19 |
20 |
21 |
22 | ## Snapshots
23 |
24 | | Mini-Program Homepage | Mini-Program Order Placement |
25 | |-------|-------|
26 | |  |  |
27 | | Management Platform Login Page | Admin Management Interface |
28 | |  |  |
29 |
30 | [Backend project in progress......]
31 |
32 | ## Relevant Information
33 |
34 | API Interface Address: (https://nottinghamwall.apifox.cn)
35 |
36 | Server-Side Project Address: (https://github.com/CompPsyUnion/NottinghamWall/tree/main/backend)
37 | (in ``backend`` folder of this project)
38 |
39 | Mini-Program Project Address: (https://github.com/CompPsyUnion/NottinghamWall/tree/main/uniapp)
40 | (in ``uniapp`` folder of this project)
41 |
42 | Management-Side Project Address: (https://github.com/CompPsyUnion/NottinghamWall/tree/main/admin)
43 | (in ``admin`` folder of this project)
44 |
45 |
46 | ## Star History
47 |
48 | [](https://star-history.com/#CompPsyUnion/NottinghamWall&Date)
49 |
--------------------------------------------------------------------------------
/README_ch.md:
--------------------------------------------------------------------------------
1 | # 宁波诺丁汉大学校园墙
2 | 🌏 [English](/README.md) | 中文
3 |
4 | ## 项目简介
5 |
6 | 由23级 CSAI(2+2) 的 Pleasurecruise 发起和编写,于2024年6月15日建立
7 |
8 | 该项目主要由 服务器端 小程序端 管理端 三部分组成
9 |
10 | 如果在部署时有什么问题,或者有什么好的建议都可以在上方commit
11 |
12 | **占坑开发中**
13 |
14 | ## 特别说明
15 |
16 | 由于接单,用户信息获取等功能涉及到增值业务审核,需要有相应的营业执照,所以部分测试是在微信小程序测试号上进行。
17 |
18 | 小程序1.0版本现已上线!微信搜索`CPU Wall`或者扫描下方的小程序码进行体验。
19 |
20 |
21 |
22 | ## 效果展示
23 |
24 | | 小程序端首页 | 小程序端发布订单 |
25 | |-------|-------|
26 | |  |  |
27 | | 管理平台登录页面 | 管理员管理界面 |
28 | |  |  |
29 |
30 | [后端项目编写中......]
31 |
32 | ## 相关信息
33 |
34 | API接口地址:(https://nottinghamwall.apifox.cn)
35 |
36 | 服务器端项目地址:(https://github.com/CompPsyUnion/NottinghamWall/tree/main/backend)
37 |
38 | 小程序端项目地址:(https://github.com/CompPsyUnion/NottinghamWall/tree/main/uniapp)
39 |
40 | 管理端项目地址:(https://github.com/CompPsyUnion/NottinghamWall/tree/main/admin)
41 |
42 | ## Star History
43 |
44 | [](https://star-history.com/#CompPsyUnion/NottinghamWall&Date)
45 |
--------------------------------------------------------------------------------
/admin/.env.development:
--------------------------------------------------------------------------------
1 | # This file is used to define environment variables for development environment
2 | NODE_ENV = 'development'
3 | VITE_API_URL=http://localhost:8080
4 | VITE_API_SOCKET_URL = 'ws://localhost:8080/ws/'
5 |
--------------------------------------------------------------------------------
/admin/.env.production:
--------------------------------------------------------------------------------
1 | # This file is used to set environment variables for production builds.
2 | NODE_ENV = 'production'
3 | VITE_API_URL='https://nottinghamwall.yiming1234.cn'
4 | VITE_API_SOCKET_URL = 'ws://localhost:8080/ws/'
5 |
--------------------------------------------------------------------------------
/admin/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | parserOptions: {
4 | ecmaVersion: 2021, // 适用于 ES9 以及更新版本
5 | sourceType: 'module'
6 | },
7 | env: {
8 | browser: true,
9 | node: true,
10 | es2021: true
11 | },
12 | extends: [
13 | 'eslint:recommended',
14 | 'plugin:vue/recommended', // 如果使用 Vue.js
15 | '@vue/standard', // 如果使用 Vue.js Standard 风格
16 | ],
17 | rules: {
18 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', // 在生产环境中禁止使用 console,开发环境中允许
19 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', // 在生产环境中禁止使用 debugger,开发环境中允许
20 | 'space-before-function-paren': 0, // 函数括号前不需要空格
21 | 'vue/array-bracket-spacing': 0, // 数组括号内不需要空格
22 | 'vue/arrow-spacing': 0, // 箭头函数的箭头前后不需要空格
23 | 'vue/block-spacing': 0, // 代码块内不需要空格
24 | 'vue/brace-style': 'error', // 大括号风格错误
25 | 'vue/camelcase': 'error', // 驼峰命名错误
26 | 'vue/comma-dangle': 'error', // 逗号悬挂错误
27 | 'vue/component-name-in-template-casing': 'error', // 模板中的组件名称大小写错误
28 | 'vue/eqeqeq': 'error', // 必须使用全等
29 | 'vue/key-spacing': 0, // 键值对之间不需要空格
30 | 'vue/match-component-file-name': 'error', // 组件名称与文件名不匹配错误
31 | 'vue/object-curly-spacing': 0, // 对象大括号内不需要空格
32 | 'vue/max-attributes-per-line': 0, // 每行最大属性数不限制
33 | 'padded-blocks': 0, // 代码块内不需要填充空行
34 | 'semi': 0, // 不需要分号
35 | 'indent': 0, // 不需要缩进
36 | 'space-infix-ops': 0, // 操作符周围不需要空格
37 | 'space-before-blocks': 0, // 代码块前不需要空格
38 | 'eqeqeq': 0, // 不强制使用全等
39 | 'object-curly-spacing': 0, // 对象大括号内不需要空格
40 | 'keyword-spacing': 0, // 关键字周围不需要空格
41 | 'spaced-comment': 0, // 注释前不需要空格
42 | 'key-spacing': 0, // 键值对之间不需要空格
43 | 'comma-spacing': 0, // 逗号前后不需要空格
44 | 'comma-dangle': 0, // 不需要逗号悬挂
45 | 'space-in-parens': 0, // 括号内不需要空格
46 | 'standard/object-curly-even-spacing': 0, // 对象大括号内不需要空格
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/admin/.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 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | .vscode
18 | !.vscode/extensions.json
19 | .idea
20 | .env.production
21 | .DS_Store
22 | *.suo
23 | *.ntvs*
24 | *.njsproj
25 | *.sln
26 | *.sw?
27 |
--------------------------------------------------------------------------------
/admin/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["Vue.volar"]
3 | }
4 |
--------------------------------------------------------------------------------
/admin/README.md:
--------------------------------------------------------------------------------
1 | # 宁波诺丁汉大学校园墙管理端
2 |
3 | ## 项目简介
4 |
5 | 由23级计算机科学与技术专业(2+2)的 Pleasurecruise 独立开发,于2024年6月15日建立
6 |
7 | 有意者也欢迎commit加入我
8 |
9 | **占坑开发中**
10 |
11 | ## 特别说明
12 |
13 | 由于初始准备是想能够上线在校内推广该小程序,但由于接单功能涉及到增值业务审核需要有相应的营业执照。
14 |
15 | 如果你想Git后更换相应元素作为你的毕业设计......
16 |
17 | 感谢大家的支持
18 |
19 | ## 效果展示
20 |
21 | 
22 |
23 | 
24 |
25 | [后端项目编写中......]
26 |
27 | ## 相关信息
28 |
29 | API接口地址:(https://nottinghamwall.apifox.cn)
30 |
31 | 小程序端项目地址:(https://github.com/CompPsyUnion/NottinghamWall/tree/uniapp)
32 |
33 | 服务端项目地址:(https://github.com/CompPsyUnion/NottinghamWall/tree/backend)
34 |
--------------------------------------------------------------------------------
/admin/directoryList.md:
--------------------------------------------------------------------------------
1 | |-- undefined
2 | |-- .env.development
3 | |-- .env.production
4 | |-- .eslintrc.cjs
5 | |-- .gitignore
6 | |-- index.html
7 | |-- jsconfig.json
8 | |-- package.json
9 | |-- pnpm-lock.yaml
10 | |-- qodana.yaml
11 | |-- README.md
12 | |-- vite.config.js
13 | |-- .idea
14 | | |-- .gitignore
15 | | |-- admin.iml
16 | | |-- modules.xml
17 | | |-- UniappTool.xml
18 | | |-- vcs.xml
19 | | |-- workspace.xml
20 | | |-- inspectionProfiles
21 | | |-- Project_Default.xml
22 | |-- .vscode
23 | | |-- extensions.json
24 | |-- public
25 | | |-- favicon.ico
26 | |-- src
27 | |-- App.vue
28 | |-- main.js
29 | |-- style.css
30 | |-- api
31 | | |-- admin.js
32 | | |-- comment.js
33 | | |-- student.js
34 | |-- assets
35 | | |-- main.scss
36 | | |-- carousel
37 | | | |-- image1.jpg
38 | | | |-- image2.jpg
39 | | | |-- image3.jpg
40 | | | |-- image4.jpg
41 | | | |-- image5.jpg
42 | | | |-- image6.jpg
43 | | |-- logo
44 | | |-- default.png
45 | | |-- icon_logo.png
46 | | |-- login_bg.png
47 | | |-- logo.png
48 | | |-- mini-logo.png
49 | |-- components
50 | | |-- HelloWorld.vue
51 | |-- router
52 | | |-- index.js
53 | |-- store
54 | | |-- admin.js
55 | | |-- token.js
56 | |-- utils
57 | | |-- request.js
58 | | |-- requestOptimize.js
59 | |-- views
60 | |-- Dashboard.vue
61 | |-- Login.vue
62 | |-- admin
63 | | |-- addAdmin.vue
64 | | |-- Admin.vue
65 | |-- notice
66 | | |-- Notice.vue
67 | |-- student
68 | | |-- Student.vue
69 | |-- topic
70 | |-- Topic.vue
71 |
--------------------------------------------------------------------------------
/admin/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 宁波诺丁汉大学校园墙管理员操作面板
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/admin/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": ".",
4 | "paths": {
5 | "@/*": ["src/*"]
6 | }
7 | },
8 | "include": [
9 | "src/**/*.vue",
10 | "src/**/*.js",
11 | "src/**/*"
12 | ],
13 | "exclude": [
14 | "node_modules",
15 | "dist",
16 | "test"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/admin/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@pleasurecruise/nottinghamwall",
3 | "author": "Pleasurecruise <3196812536@qq.com>",
4 | "description": "宁波诺丁汉大学校园墙",
5 | "license": "Apache-2.0",
6 | "private": false,
7 | "version": "1.0.9",
8 | "repository": {
9 | "type": "git",
10 | "url": "https://github.com/NottinghamWall/NottinghamWall"
11 | },
12 | "publishConfig": {
13 | "access": "public",
14 | "registry": "https://registry.npmjs.org/"
15 | },
16 | "scripts": {
17 | "dev": "vite",
18 | "build": "vite build",
19 | "preview": "vite preview"
20 | },
21 | "dependencies": {
22 | "axios": "1.7.4",
23 | "element-plus": "^2.8.0",
24 | "md5": "^2.3.0",
25 | "pinia": "^2.2.1",
26 | "pinia-persistedstate-plugin": "^0.1.0",
27 | "vue": "^3.4.37",
28 | "vue-router": "^4.4.3"
29 | },
30 | "devDependencies": {
31 | "@element-plus/icons-vue": "^2.3.1",
32 | "@eslint/js": "^9.8.0",
33 | "@vitejs/plugin-vue": "^5.1.2",
34 | "@vue/eslint-config-standard": "^8.0.1",
35 | "eslint": "^8.0.1",
36 | "eslint-plugin-vue": "^9.27.0",
37 | "sass": "^1.77.8",
38 | "vite": "5.4.6"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/admin/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/admin/public/favicon.ico
--------------------------------------------------------------------------------
/admin/qodana.yaml:
--------------------------------------------------------------------------------
1 | #-------------------------------------------------------------------------------#
2 | # Qodana analysis is configured by qodana.yaml file #
3 | # https://www.jetbrains.com/help/qodana/qodana-yaml.html #
4 | #-------------------------------------------------------------------------------#
5 | version: "1.0"
6 |
7 | #Specify inspection profile for code analysis
8 | profile:
9 | name: qodana.starter
10 |
11 | #Enable inspections
12 | #include:
13 | # - name:
14 |
15 | #Disable inspections
16 | #exclude:
17 | # - name:
18 | # paths:
19 | # -
20 |
21 | #Execute shell command before Qodana execution (Applied in CI/CD pipeline)
22 | #bootstrap: sh ./prepare-qodana.sh
23 |
24 | #Install IDE plugins before Qodana execution (Applied in CI/CD pipeline)
25 | #plugins:
26 | # - id: #(plugin id can be found at https://plugins.jetbrains.com)
27 |
28 | #Specify Qodana linter for analysis (Applied in CI/CD pipeline)
29 | linter: jetbrains/qodana-js:latest
30 |
--------------------------------------------------------------------------------
/admin/src/App.vue:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
11 |
--------------------------------------------------------------------------------
/admin/src/api/comment.js:
--------------------------------------------------------------------------------
1 | import request from '@/utils/request';
2 |
3 | /**
4 | * 根据话题获取评论列表
5 | */
6 | export function getCommentListByTopicId(topicId) {
7 | console.log('Fetching comment');
8 | return request({
9 | url: `/admin/topic/getcomment/${topicId}`,
10 | method: 'get'
11 | }).catch(error => {
12 | console.error('Fetching comment failed', error);
13 | throw error;
14 | }
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/admin/src/api/student.js:
--------------------------------------------------------------------------------
1 | import request from '@/utils/request';
2 | // import {useAdminStore} from '@/store/admin';
3 | // import {useTokenStore} from '@/store/token';
4 | /**
5 | * 提供调用获取学生列表接口的函数
6 | */
7 | export const getStudentList = (params) => {
8 | console.log('Fetching student list');
9 | return request.get('/admin/student/page', {params}).then(response => {
10 | console.log('Student list response received', response);
11 | return response;
12 | }).catch(error => {
13 | console.error('Fetching student list failed', error);
14 | throw error;
15 | });
16 | };
17 |
18 | /**
19 | * 根据id获取学生信息
20 | */
21 | export const getStudentById = (id) => {
22 | console.log('Fetching student info');
23 | return request.get(`/admin/student/${id}`).then(response => {
24 | console.log('Student info response received', response);
25 | return response;
26 | }).catch(error => {
27 | console.error('Fetching student info failed', error);
28 | throw error;
29 | });
30 | }
31 |
--------------------------------------------------------------------------------
/admin/src/api/topic.js:
--------------------------------------------------------------------------------
1 | import request from '@/utils/request';
2 |
3 | /**
4 | * 提供调用获取话题列表接口的函数
5 | */
6 | export const getTopicList = (params) => {
7 | console.log('Fetching topic list');
8 | return request.get('/admin/topic/page', {params}).then(response => {
9 | console.log('Topic list response received', response);
10 | return response;
11 | }).catch(error => {
12 | console.error('Fetching topic list failed', error);
13 | throw error;
14 | });
15 | };
16 |
17 | /**
18 | * 提供删除特定话题的函数
19 | */
20 | export const deleteTopic = (id) => {
21 | console.log('Deleting topic', id);
22 | return request.delete(`/admin/topic/delete/${id}`).then(response => {
23 | console.log('Topic deleted', response);
24 | return response;
25 | }).catch(error => {
26 | console.error('Deleting topic failed', error);
27 | throw error;
28 | });
29 | }
30 |
--------------------------------------------------------------------------------
/admin/src/assets/carousel/image1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/admin/src/assets/carousel/image1.jpg
--------------------------------------------------------------------------------
/admin/src/assets/carousel/image2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/admin/src/assets/carousel/image2.jpg
--------------------------------------------------------------------------------
/admin/src/assets/carousel/image3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/admin/src/assets/carousel/image3.jpg
--------------------------------------------------------------------------------
/admin/src/assets/carousel/image4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/admin/src/assets/carousel/image4.jpg
--------------------------------------------------------------------------------
/admin/src/assets/carousel/image5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/admin/src/assets/carousel/image5.jpg
--------------------------------------------------------------------------------
/admin/src/assets/carousel/image6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/admin/src/assets/carousel/image6.jpg
--------------------------------------------------------------------------------
/admin/src/assets/logo/default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/admin/src/assets/logo/default.png
--------------------------------------------------------------------------------
/admin/src/assets/logo/icon_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/admin/src/assets/logo/icon_logo.png
--------------------------------------------------------------------------------
/admin/src/assets/logo/login_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/admin/src/assets/logo/login_bg.png
--------------------------------------------------------------------------------
/admin/src/assets/logo/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/admin/src/assets/logo/logo.png
--------------------------------------------------------------------------------
/admin/src/assets/logo/mini-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/admin/src/assets/logo/mini-logo.png
--------------------------------------------------------------------------------
/admin/src/assets/main.scss:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | background-color: #ffffff;
4 | }
5 |
6 | /* fade-slide */
7 | .fade-slide-leave-active,
8 | .fade-slide-enter-active {
9 | transition: all 0.3s;
10 | }
11 |
12 | .fade-slide-enter-from {
13 | transform: translateX(-30px);
14 | opacity: 0;
15 | }
16 |
17 | .fade-slide-leave-to {
18 | transform: translateX(30px);
19 | opacity: 0;
20 | }
--------------------------------------------------------------------------------
/admin/src/main.js:
--------------------------------------------------------------------------------
1 | import './assets/main.scss'
2 | import { createApp } from 'vue'
3 | import ElementPlus from 'element-plus'
4 | import 'element-plus/dist/index.css'
5 | import { createPinia } from 'pinia'
6 | import { createPersistedState } from 'pinia-persistedstate-plugin'
7 | import router from '@/router/index'
8 | import App from '@/App.vue'
9 | import zhCn from 'element-plus/es/locale/lang/zh-cn';
10 |
11 | const app = createApp(App);
12 | const pinia = createPinia();
13 | const persist = createPersistedState();
14 | pinia.use(persist);
15 | app.use(pinia);
16 | app.use(router);
17 | app.use(ElementPlus, { locale: zhCn });
18 | app.mount('#app')
19 |
--------------------------------------------------------------------------------
/admin/src/router/index.js:
--------------------------------------------------------------------------------
1 | import {createRouter, createWebHistory} from 'vue-router'
2 | import { useTokenStore } from '@/store/token'
3 |
4 | //导入组件
5 | import LoginVue from '@/views/Login.vue'
6 | import DashboardVue from '@/views/Dashboard.vue'
7 | import NoticeVue from '@/views/notice/Notice.vue'
8 | import AdminVue from '@/views/admin/Admin.vue'
9 | import StudentVue from '@/views/student/Student.vue'
10 | import addAdminVue from '@/views/admin/addAdmin.vue'
11 | import TopicVue from '@/views/topic/Topic.vue'
12 | import ChangePasswordVue from '@/views/admin/changePassword.vue';
13 |
14 | //定义路由关系
15 | const routes = [
16 | {path: '/login', component: LoginVue},
17 | {
18 | path: '/',
19 | component: DashboardVue,
20 | children: [
21 | {
22 | path: '/',
23 | component: NoticeVue,
24 | },
25 | {
26 | path: 'manage/admin',
27 | component: AdminVue,
28 | },
29 | {
30 | path: 'manage/student',
31 | component: StudentVue,
32 | },
33 | {
34 | path: 'manage/add',
35 | component: addAdminVue
36 | },
37 | {
38 | path:'manage/topic',
39 | component: TopicVue
40 | },
41 | {
42 | path: 'manage/password',
43 | component: ChangePasswordVue
44 | }
45 | ]
46 | }
47 | ]
48 |
49 | //创建路由器
50 | const router = createRouter({
51 | history: createWebHistory(process.env.VITE_API_URL),
52 | routes
53 | })
54 |
55 | //添加全局路由守卫
56 | router.beforeEach((to, from, next) => {
57 | const tokenStore = useTokenStore();
58 | const token = tokenStore.token;
59 | if (!token) {
60 | if (to.path !== '/login') {
61 | console.log('No valid token found, redirecting to /login'); // 添加日志输出
62 | next('/login');
63 | } else {
64 | next();
65 | }
66 | } else {
67 | next();
68 | }
69 | })
70 |
71 | //导出路由
72 | export default router;
73 |
--------------------------------------------------------------------------------
/admin/src/store/admin.js:
--------------------------------------------------------------------------------
1 | // store/userStore.js
2 | import { defineStore } from 'pinia';
3 |
4 | export const useAdminStore = defineStore( {
5 | id: 'admin',
6 | state: () => ({
7 | admin: localStorage.getItem('admin') || ''
8 | }),
9 | actions: {
10 | setAdmin(userName) {
11 | this.admin = userName;
12 | localStorage.setItem('admin', userName);
13 | },
14 | clearAdmin() {
15 | this.admin = '';
16 | localStorage.removeItem('admin');
17 | }
18 | },
19 | persist: true // 启用持久化
20 | });
21 |
--------------------------------------------------------------------------------
/admin/src/store/token.js:
--------------------------------------------------------------------------------
1 | import { defineStore } from 'pinia';
2 |
3 | export const useTokenStore = defineStore({
4 | id: 'token',
5 | state: () => ({
6 | token: localStorage.getItem('token') || ''
7 | }),
8 | actions: {
9 | setToken(token) {
10 | this.token = token;
11 | localStorage.setItem('token', token);
12 | },
13 | removeToken() {
14 | this.token = '';
15 | localStorage.removeItem('token');
16 | }
17 | },
18 | persist: true
19 | });
20 |
--------------------------------------------------------------------------------
/admin/src/style.css:
--------------------------------------------------------------------------------
1 | :root {
2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
3 | line-height: 1.5;
4 | font-weight: 400;
5 |
6 | color-scheme: light dark;
7 | color: rgba(255, 255, 255, 0.87);
8 | background-color: #242424;
9 |
10 | font-synthesis: none;
11 | text-rendering: optimizeLegibility;
12 | -webkit-font-smoothing: antialiased;
13 | -moz-osx-font-smoothing: grayscale;
14 | }
15 |
16 | a {
17 | font-weight: 500;
18 | color: #646cff;
19 | text-decoration: inherit;
20 | }
21 | a:hover {
22 | color: #535bf2;
23 | }
24 |
25 | body {
26 | margin: 0;
27 | display: flex;
28 | place-items: center;
29 | min-width: 320px;
30 | min-height: 100vh;
31 | }
32 |
33 | h1 {
34 | font-size: 3.2em;
35 | line-height: 1.1;
36 | }
37 |
38 | button {
39 | border-radius: 8px;
40 | border: 1px solid transparent;
41 | padding: 0.6em 1.2em;
42 | font-size: 1em;
43 | font-weight: 500;
44 | font-family: inherit;
45 | background-color: #1a1a1a;
46 | cursor: pointer;
47 | transition: border-color 0.25s;
48 | }
49 | button:hover {
50 | border-color: #646cff;
51 | }
52 | button:focus,
53 | button:focus-visible {
54 | outline: 4px auto -webkit-focus-ring-color;
55 | }
56 |
57 | .card {
58 | padding: 2em;
59 | }
60 |
61 | #app {
62 | max-width: 1280px;
63 | margin: 0 auto;
64 | padding: 2rem;
65 | text-align: center;
66 | }
67 |
68 | @media (prefers-color-scheme: light) {
69 | :root {
70 | color: #213547;
71 | background-color: #ffffff;
72 | }
73 | a:hover {
74 | color: #747bff;
75 | }
76 | button {
77 | background-color: #f9f9f9;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/admin/src/utils/request.js:
--------------------------------------------------------------------------------
1 | //定制请求的实例
2 | import axios from 'axios';
3 | import { ElMessage } from 'element-plus'
4 | import { useTokenStore } from '@/store/token'
5 | import router from '@/router/index'
6 |
7 | const instance = axios.create({
8 | baseURL: '/api',
9 | timeout: 600000
10 | })
11 |
12 | // 添加请求拦截器
13 | instance.interceptors.request.use(
14 | (config) => {
15 | console.log('Sending request:', config); // 添加日志
16 | const tokenStore = useTokenStore()
17 | if (tokenStore.token) {
18 | config.headers.token = tokenStore.token
19 | } else if (!tokenStore.token && config.url !== '/admin/manage/login') {
20 | window.location.href = '/login'
21 | return Promise.reject(new Error('No token'))
22 | }
23 | return config
24 | },
25 | (error) => {
26 | return Promise.reject(error)
27 | }
28 | )
29 |
30 | // 添加响应拦截器
31 | instance.interceptors.response.use(
32 | result => {
33 | console.log('Received response:', result); // 添加日志
34 | //判断业务状态码
35 | if (result.data.code === 1) {
36 | return result.data;
37 | }
38 | //操作失败
39 | //alert(result.data.msg?result.data.msg:'服务异常')
40 | ElMessage.error(result.data.msg ? result.data.msg : '服务异常')
41 | //异步操作的状态转换为失败
42 | return Promise.reject(result.data)
43 |
44 | },
45 | err => {
46 | //判断响应状态码,如果为401,则证明未登录,提示请登录,并跳转到登录页面
47 | if (err.response.status === 401) {
48 | ElMessage.error('请先登录')
49 | router.push('/login')
50 | } else {
51 | ElMessage.error('服务异常')
52 | }
53 |
54 | return Promise.reject(err);//异步的状态转化成失败的状态
55 | }
56 | )
57 |
58 | export default instance;
59 |
--------------------------------------------------------------------------------
/admin/src/utils/requestOptimize.js:
--------------------------------------------------------------------------------
1 | import md5 from 'md5';
2 |
3 | // 根据请求的地址,方式,参数,统一计算出当前请求的md5值作为key
4 | const getRequestKey = (config) => {
5 | if (!config) {
6 | // 如果没有获取到请求的相关配置信息,根据时间戳生成
7 | return md5(+new Date());
8 | }
9 |
10 | const data = typeof config.data === 'string' ? config.data : JSON.stringify(config.data);
11 | // console.log(config, pending, config.url, md5(config.url + '&' + config.method + '&' + data), 'config')
12 | return md5(config.url + '&' + config.method + '&' + data);
13 | }
14 |
15 | // 存储key值
16 | const pending = {};
17 |
18 | // 检查key值
19 | const checkPending = (key) => !!pending[key];
20 |
21 | // 删除key值
22 | const removePending = (key) => {
23 | // console.log(key, 'key')
24 | delete pending[key];
25 | };
26 |
27 | export {
28 | getRequestKey,
29 | pending,
30 | checkPending,
31 | removePending
32 | }
33 |
--------------------------------------------------------------------------------
/admin/src/views/admin/changePassword.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | 保存
18 |
19 |
20 | 重置
21 |
22 | $router.push('/manage/admin')">
23 | 返回
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
103 |
104 |
137 |
--------------------------------------------------------------------------------
/admin/src/views/notice/Notice.vue:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
37 |
--------------------------------------------------------------------------------
/admin/src/views/student/Student.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | 查询
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | {{ Number(scope.row.sex) ===1 ? '男':'女' }}
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
46 |
47 |
48 |
49 |
50 |
51 |
101 |
102 |
121 |
--------------------------------------------------------------------------------
/admin/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite';
2 | import vue from '@vitejs/plugin-vue';
3 | import path from 'path';
4 |
5 | export default defineConfig(({ mode }) => {
6 | return {
7 | plugins: [vue()],
8 | logLevel: 'info',
9 | define: {
10 | 'process.env.NODE_ENV': JSON.stringify('production')
11 | },
12 | base: mode === 'production' ? './' : '/', // 类似于 Vue CLI 的 publicPath
13 | resolve: {
14 | alias: {
15 | '@': path.resolve(__dirname, 'src')
16 | }
17 | },
18 | server: {
19 | port: 8888,
20 | open: true,
21 | proxy: {
22 | '/api': {
23 | target: process.env.VITE_API_URL || 'http://localhost:8080', // 使用环境变量配置 API 地址
24 | changeOrigin: true,
25 | rewrite: (path) => {
26 | const newPath = path.replace(/^\/api/, ''); // 去掉 /api 前缀
27 | console.log(`Original path: ${path}, Rewritten path: ${newPath}`); // 输出重写前后的路径
28 | return newPath;
29 | },
30 | },
31 | },
32 | },
33 | build: {
34 | minify: mode === 'production' ? 'esbuild' : false,
35 | assetsDir: 'assets'
36 | },
37 | };
38 | });
39 |
--------------------------------------------------------------------------------
/backend/.gitignore:
--------------------------------------------------------------------------------
1 | **/target/
2 | .idea
3 | *.iml
4 | *.class
5 | *Test.java
6 | **/test/
--------------------------------------------------------------------------------
/backend/README.md:
--------------------------------------------------------------------------------
1 | # 宁波诺丁汉大学校园墙服务器端
2 |
3 | ## 项目简介
4 |
5 | 由23级计算机科学与技术专业(2+2)的 Pleasurecruise 独立开发,于2024年6月15日建立
6 |
7 | 该主项目为由SpringBoot编写的接口地址
8 |
9 | 欢迎后来者调用接口,编写自己喜欢的前端页面
10 |
11 | 有意者也欢迎commit加入我
12 |
13 | **占坑开发中**
14 |
15 | ## 特别说明
16 |
17 | 由于初始准备是想能够上线在校内推广该小程序,但由于接单功能涉及到增值业务审核需要有相应的营业执照。
18 |
19 | 感谢大家的支持
20 |
21 | ## 效果展示
22 |
23 | 
24 |
25 | 
26 |
27 | [后端项目编写中......]
28 |
29 | ## 相关信息
30 |
31 | API接口地址:(https://nottinghamwall.apifox.cn)
32 |
33 | 小程序端项目地址:(https://github.com/CompPsyUnion/NottinghamWall/tree/uniapp)
34 |
35 | 管理端项目地址:(https://github.com/CompPsyUnion/NottinghamWall/tree/admin)
36 |
--------------------------------------------------------------------------------
/backend/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "lockfileVersion": 1
3 | }
4 |
--------------------------------------------------------------------------------
/backend/wall-common/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | wall-common
8 | 1.0-SNAPSHOT
9 |
10 |
11 | cn.yiming1234.NottinghamWall
12 | NottinghamWall
13 | 1.0-SNAPSHOT
14 | ../pom.xml
15 |
16 |
17 |
18 |
19 | org.projectlombok
20 | lombok
21 |
22 |
23 | com.alibaba
24 | fastjson
25 | 1.2.83
26 |
27 |
28 | commons-lang
29 | commons-lang
30 |
31 |
32 | org.springframework.boot
33 | spring-boot-starter-json
34 |
35 |
36 | io.jsonwebtoken
37 | jjwt
38 |
39 |
40 |
41 | org.springframework.boot
42 | spring-boot-configuration-processor
43 | true
44 |
45 |
46 | com.aliyun.oss
47 | aliyun-sdk-oss
48 | 3.17.4
49 |
50 |
51 | com.aliyun
52 | green20220302
53 | 2.2.15
54 |
55 |
56 | javax.xml.bind
57 | jaxb-api
58 |
59 |
60 | com.aliyun.oss
61 | aliyun-sdk-oss
62 | 3.17.4
63 |
64 |
65 | org.springframework.boot
66 | spring-boot-test
67 | test
68 |
69 |
70 | junit
71 | junit
72 | test
73 |
74 |
75 | org.springframework
76 | spring-test
77 | test
78 |
79 |
80 | com.aliyun.oss
81 | aliyun-sdk-oss
82 | 3.17.4
83 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/backend/wall-common/src/main/java/cn/yiming1234/NottinghamWall/constant/AutoFillConstant.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.constant;
2 |
3 | /**
4 | * 公共字段自动填充相关常量
5 | */
6 | public class AutoFillConstant {
7 | /**
8 | * 实体类中的方法名称
9 | */
10 | public static final String SET_CREATE_TIME = "setCreateTime";
11 | public static final String SET_UPDATE_TIME = "setUpdateTime";
12 | public static final String SET_CREATE_USER = "setCreateUser";
13 | public static final String SET_UPDATE_USER = "setUpdateUser";
14 | }
15 |
--------------------------------------------------------------------------------
/backend/wall-common/src/main/java/cn/yiming1234/NottinghamWall/constant/JwtClaimsConstant.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.constant;
2 |
3 | public class JwtClaimsConstant {
4 |
5 | public static final String EMP_ID = "empId";
6 | public static final String USER_ID = "userId";
7 | public static final String PHONE = "phone";
8 | public static final String USERNAME = "username";
9 | public static final String NAME = "name";
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/backend/wall-common/src/main/java/cn/yiming1234/NottinghamWall/constant/MessageConstant.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.constant;
2 |
3 | /**
4 | * 信息提示常量类
5 | */
6 | public class MessageConstant {
7 |
8 | public static final String PASSWORD_ERROR = "密码错误";
9 | public static final String PASSWORD_MISMATCH = "密码不一致";
10 | public static final String ACCOUNT_NOT_FOUND = "账号不存在";
11 | public static final String ACCOUNT_LOCKED = "账号被锁定";
12 | public static final String ACCOUNT_EXIST = "账号已存在";
13 | public static final String UNKNOWN_ERROR = "未知错误";
14 | public static final String USER_NOT_LOGIN = "用户未登录";
15 | public static final String SHOPPING_CART_IS_NULL = "购物车数据为空,不能下单";
16 | public static final String ADDRESS_BOOK_IS_NULL = "用户地址为空,不能下单";
17 | public static final String LOGIN_FAILED = "登录失败";
18 | public static final String UPLOAD_FAILED = "文件上传失败";
19 | public static final String ORDER_STATUS_ERROR = "订单状态错误";
20 | public static final String ORDER_NOT_FOUND = "订单不存在";
21 | public static final String CONTENT_UNSECURED = "内容含违规信息";
22 | }
23 |
--------------------------------------------------------------------------------
/backend/wall-common/src/main/java/cn/yiming1234/NottinghamWall/constant/PasswordConstant.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.constant;
2 |
3 | /**
4 | * 密码常量
5 | */
6 | public class PasswordConstant {
7 |
8 | public static final String DEFAULT_PASSWORD = "123456";
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/backend/wall-common/src/main/java/cn/yiming1234/NottinghamWall/constant/StatusConstant.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.constant;
2 |
3 | /**
4 | * 状态常量,启用或者禁用
5 | */
6 | public class StatusConstant {
7 |
8 | //启用
9 | public static final Integer ENABLE = 1;
10 |
11 | //禁用
12 | public static final Integer DISABLE = 0;
13 | }
14 |
--------------------------------------------------------------------------------
/backend/wall-common/src/main/java/cn/yiming1234/NottinghamWall/context/BaseContext.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.context;
2 |
3 | public class BaseContext {
4 |
5 | public static ThreadLocal threadLocal = new ThreadLocal<>();
6 |
7 | public static void setCurrentId(Integer id) {
8 | threadLocal.set(id);
9 | }
10 |
11 | public static Integer getCurrentId() {
12 | return Math.toIntExact(threadLocal.get());
13 | }
14 |
15 | public static void removeCurrentId() {
16 | threadLocal.remove();
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/backend/wall-common/src/main/java/cn/yiming1234/NottinghamWall/enumeration/OperationType.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.enumeration;
2 |
3 | /**
4 | * 数据库操作类型
5 | */
6 | public enum OperationType {
7 |
8 | /**
9 | * 更新操作
10 | */
11 | UPDATE,
12 |
13 | /**
14 | * 插入操作
15 | */
16 | INSERT
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/backend/wall-common/src/main/java/cn/yiming1234/NottinghamWall/exception/AccountLockedException.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.exception;
2 |
3 | /**
4 | * 账号被锁定异常
5 | */
6 | public class AccountLockedException extends BaseException {
7 |
8 | public AccountLockedException(String msg) {
9 | super(msg);
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/backend/wall-common/src/main/java/cn/yiming1234/NottinghamWall/exception/AccountNotFoundException.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.exception;
2 |
3 | /**
4 | * 账号不存在异常
5 | */
6 | public class AccountNotFoundException extends BaseException {
7 |
8 | public AccountNotFoundException(String msg) {
9 | super(msg);
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/backend/wall-common/src/main/java/cn/yiming1234/NottinghamWall/exception/BaseException.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.exception;
2 |
3 | /**
4 | * 业务异常
5 | */
6 | public class BaseException extends RuntimeException {
7 |
8 | public BaseException() {
9 | }
10 |
11 | public BaseException(String msg) {
12 | super(msg);
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/backend/wall-common/src/main/java/cn/yiming1234/NottinghamWall/exception/DeletionNotAllowedException.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.exception;
2 |
3 | public class DeletionNotAllowedException extends BaseException {
4 |
5 | public DeletionNotAllowedException(String msg) {
6 | super(msg);
7 | }
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/backend/wall-common/src/main/java/cn/yiming1234/NottinghamWall/exception/LoginFailedException.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.exception;
2 |
3 | /**
4 | * 登录失败
5 | */
6 | public class LoginFailedException extends BaseException{
7 | public LoginFailedException(String msg){
8 | super(msg);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/backend/wall-common/src/main/java/cn/yiming1234/NottinghamWall/exception/MaxUploadSizeException.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.exception;
2 |
3 | /**
4 | * 文件上传过大异常
5 | */
6 | public class MaxUploadSizeException extends BaseException{
7 | public MaxUploadSizeException(String msg){
8 | super(msg);
9 | // TODO
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/backend/wall-common/src/main/java/cn/yiming1234/NottinghamWall/exception/PasswordEditFailedException.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.exception;
2 |
3 | /**
4 | * 密码修改失败异常
5 | */
6 | public class PasswordEditFailedException extends BaseException{
7 |
8 | public PasswordEditFailedException(String msg){
9 | super(msg);
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/backend/wall-common/src/main/java/cn/yiming1234/NottinghamWall/exception/PasswordErrorException.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.exception;
2 |
3 | /**
4 | * 密码错误异常
5 | */
6 | public class PasswordErrorException extends BaseException {
7 |
8 | public PasswordErrorException() {
9 | }
10 |
11 | public PasswordErrorException(String msg) {
12 | super(msg);
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/backend/wall-common/src/main/java/cn/yiming1234/NottinghamWall/exception/TeapotException.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.exception;
2 |
3 | public class TeapotException extends BaseException {
4 | public TeapotException(String message) {
5 | super(message);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/backend/wall-common/src/main/java/cn/yiming1234/NottinghamWall/exception/UserNotLoginException.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.exception;
2 |
3 | public class UserNotLoginException extends BaseException {
4 |
5 | public UserNotLoginException() {
6 | }
7 |
8 | public UserNotLoginException(String msg) {
9 | super(msg);
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/backend/wall-common/src/main/java/cn/yiming1234/NottinghamWall/json/JacksonObjectMapper.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.json;
2 |
3 | import com.fasterxml.jackson.databind.DeserializationFeature;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 | import com.fasterxml.jackson.databind.module.SimpleModule;
6 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
7 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
8 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
9 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
10 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
11 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
12 |
13 | import java.time.LocalDate;
14 | import java.time.LocalDateTime;
15 | import java.time.LocalTime;
16 | import java.time.format.DateTimeFormatter;
17 |
18 | import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;
19 |
20 | /**
21 | * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
22 | * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
23 | * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
24 | */
25 | public class JacksonObjectMapper extends ObjectMapper {
26 |
27 | public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
28 | //public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
29 | public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";
30 | public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
31 |
32 | public JacksonObjectMapper() {
33 | super();
34 | //收到未知属性时不报异常
35 | this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);
36 |
37 | //反序列化时,属性不存在的兼容处理
38 | this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
39 |
40 | SimpleModule simpleModule = new SimpleModule()
41 | .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
42 | .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
43 | .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
44 | .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
45 | .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
46 | .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
47 |
48 | //注册功能模块 例如,可以添加自定义序列化器和反序列化器
49 | this.registerModule(simpleModule);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/backend/wall-common/src/main/java/cn/yiming1234/NottinghamWall/properties/AliOssProperties.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.properties;
2 |
3 | import lombok.Data;
4 | import org.springframework.boot.context.properties.ConfigurationProperties;
5 | import org.springframework.stereotype.Component;
6 |
7 | @Component
8 | @ConfigurationProperties(prefix = "yiming1234.alioss")
9 | @Data
10 | public class AliOssProperties {
11 | private String endpoint;
12 | private String accessKeyId;
13 | private String accessKeySecret;
14 | private String bucketName;
15 | }
--------------------------------------------------------------------------------
/backend/wall-common/src/main/java/cn/yiming1234/NottinghamWall/properties/JwtProperties.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.properties;
2 |
3 | import lombok.Data;
4 | import org.springframework.boot.context.properties.ConfigurationProperties;
5 | import org.springframework.stereotype.Component;
6 |
7 | @Component
8 | @ConfigurationProperties(prefix = "yiming1234.jwt")
9 | @Data
10 | public class JwtProperties {
11 |
12 | /**
13 | * 管理端员工生成jwt令牌相关配置
14 | */
15 | private String adminSecretKey;
16 | private long adminTtl;
17 | private String adminTokenName;
18 |
19 | /**
20 | * 用户端微信用户生成jwt令牌相关配置
21 | */
22 | private String userSecretKey;
23 | private long userTtl;
24 | private String userTokenName;
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/backend/wall-common/src/main/java/cn/yiming1234/NottinghamWall/properties/WeChatProperties.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.properties;
2 |
3 | import lombok.Data;
4 | import org.springframework.boot.context.properties.ConfigurationProperties;
5 | import org.springframework.stereotype.Component;
6 |
7 | @Component
8 | @ConfigurationProperties(prefix = "yiming1234.wechat")
9 | @Data
10 | public class WeChatProperties {
11 |
12 | private String appid; //小程序的appid
13 | private String secret; //小程序的秘钥
14 | private String mchid; //商户号
15 | private String mchSerialNo; //商户API证书的证书序列号
16 | private String privateKeyFilePath; //商户私钥文件
17 | private String apiV3Key; //证书解密的密钥
18 | private String weChatPayCertFilePath; //平台证书
19 | private String notifyUrl; //支付成功的回调地址
20 | private String refundNotifyUrl; //退款成功的回调地址
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/backend/wall-common/src/main/java/cn/yiming1234/NottinghamWall/result/PageResult.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.result;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * 封装分页查询结果
11 | */
12 | @Data
13 | @AllArgsConstructor
14 | @NoArgsConstructor
15 | public class PageResult {
16 |
17 | private long total;
18 | private List records;
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/backend/wall-common/src/main/java/cn/yiming1234/NottinghamWall/result/Result.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.result;
2 |
3 | import lombok.Data;
4 |
5 | import java.io.Serializable;
6 |
7 | /**
8 | * 后端统一返回结果
9 | * @param
10 | */
11 | @Data
12 | public class Result implements Serializable {
13 |
14 | private Integer code;
15 | private String msg;
16 | private T data;
17 |
18 | public static Result success() {
19 | Result result = new Result();
20 | result.code = 1;
21 | return result;
22 | }
23 |
24 | public static Result success(T object) {
25 | Result result = new Result();
26 | result.data = object;
27 | result.code = 1;
28 | return result;
29 | }
30 |
31 | public static Result error(String msg) {
32 | Result result = new Result<>();
33 | result.msg = msg;
34 | result.code = 0;
35 | return result;
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/backend/wall-common/src/main/java/cn/yiming1234/NottinghamWall/utils/ImageCheckUtil.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.utils;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.aliyun.green20220302.Client;
5 | import com.aliyun.green20220302.models.ImageModerationRequest;
6 | import com.aliyun.green20220302.models.ImageModerationResponse;
7 | import com.aliyun.teaopenapi.models.Config;
8 | import com.aliyun.teautil.models.RuntimeOptions;
9 | import lombok.extern.slf4j.Slf4j;
10 |
11 | import java.util.HashMap;
12 | import java.util.Map;
13 | import java.util.UUID;
14 |
15 | /**
16 | * 阿里云图片内容审核工具类
17 | */
18 | @Slf4j
19 | public class ImageCheckUtil {
20 |
21 | public static Client createClient(String accessKeyId, String accessKeySecret, String endpoint, String ossObjectName) throws Exception {
22 | Config config = new Config();
23 | config.setAccessKeyId(accessKeyId);
24 | config.setAccessKeySecret(accessKeySecret);
25 | config.setEndpoint(endpoint);
26 | return new Client(config);
27 | }
28 |
29 | public static ImageModerationResponse invokeFunction(String accessKeyId, String accessKeySecret, String endpoint, String ossObjectName) throws Exception {
30 | Client client = createClient(accessKeyId, accessKeySecret, endpoint, ossObjectName);
31 | RuntimeOptions runtime = new RuntimeOptions();
32 |
33 | Map serviceParameters = new HashMap<>();
34 | serviceParameters.put("dataId", UUID.randomUUID().toString());
35 | serviceParameters.put("ossRegionId", "cn-beijing");
36 | serviceParameters.put("ossBucketName", "yiming1234");
37 | serviceParameters.put("ossObjectName", ossObjectName);
38 |
39 | ImageModerationRequest request = new ImageModerationRequest();
40 | request.setService("baselineCheck");
41 | request.setServiceParameters(JSON.toJSONString(serviceParameters));
42 |
43 | ImageModerationResponse response = null;
44 | try {
45 | response = client.imageModerationWithOptions(request, runtime);
46 | log.info("response:{}", response.toString());
47 | } catch (Exception e) {
48 | log.error("invoke function error:{}", e.getMessage());
49 | }
50 | return response;
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/backend/wall-common/src/main/java/cn/yiming1234/NottinghamWall/utils/JwtUtil.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.utils;
2 |
3 | import io.jsonwebtoken.Claims;
4 | import io.jsonwebtoken.JwtBuilder;
5 | import io.jsonwebtoken.Jwts;
6 | import io.jsonwebtoken.SignatureAlgorithm;
7 | import org.springframework.stereotype.Component;
8 |
9 | import java.nio.charset.StandardCharsets;
10 | import java.util.Date;
11 | import java.util.Map;
12 |
13 | @Component
14 | public class JwtUtil {
15 | /**
16 | * 生成jwt
17 | * 使用Hs256算法, 私匙使用固定秘钥
18 | *
19 | * @param secretKey jwt秘钥
20 | * @param ttlMillis jwt过期时间(毫秒)
21 | * @param claims 设置的信息
22 | */
23 | public static String createJWT(String secretKey, long ttlMillis, Map claims) {
24 | // 指定签名的时候使用的签名算法,也就是header那部分
25 | SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
26 |
27 | // 生成JWT的时间
28 | long expMillis = System.currentTimeMillis() + ttlMillis;
29 | Date exp = new Date(expMillis);
30 |
31 | // 设置jwt的body
32 | JwtBuilder builder = Jwts.builder()
33 | // 如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的
34 | .setClaims(claims)
35 | // 设置签名使用的签名算法和签名使用的秘钥
36 | .signWith(signatureAlgorithm, secretKey.getBytes(StandardCharsets.UTF_8))
37 | // 设置过期时间
38 | .setExpiration(exp);
39 |
40 | return builder.compact();
41 | }
42 |
43 | /**
44 | * Token解密
45 | *
46 | * @param secretKey jwt秘钥 此秘钥一定要保留好在服务端, 不能暴露出去, 否则sign就可以被伪造, 如果对接多个客户端建议改造成多个
47 | * @param token 加密后的token
48 | */
49 | public static Claims parseJWT(String secretKey, String token) {
50 | // 得到DefaultJwtParser
51 | // 设置签名的秘钥
52 | // 设置需要解析的jwt
53 | return Jwts.parser()
54 | // 设置签名的秘钥
55 | .setSigningKey(secretKey.getBytes(StandardCharsets.UTF_8))
56 | // 设置需要解析的jwt
57 | .parseClaimsJws(token).getBody();
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/backend/wall-pojo/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | wall-pojo
8 | 1.0-SNAPSHOT
9 |
10 |
11 | cn.yiming1234.NottinghamWall
12 | NottinghamWall
13 | 1.0-SNAPSHOT
14 | ../pom.xml
15 |
16 |
17 |
18 |
19 | org.projectlombok
20 | lombok
21 |
22 |
23 | com.fasterxml.jackson.core
24 | jackson-databind
25 | 2.13.4.1
26 |
27 |
28 | com.github.xiaoymin
29 | knife4j-spring-boot-starter
30 |
31 |
32 | org.mybatis
33 | mybatis
34 | 3.5.14
35 | compile
36 |
37 |
38 | org.mybatis
39 | mybatis
40 | 3.5.14
41 | compile
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/backend/wall-pojo/src/main/java/cn/yiming1234/NottinghamWall/dto/AdminDTO.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.dto;
2 |
3 | import lombok.Data;
4 |
5 | import java.io.Serializable;
6 |
7 | @Data
8 | public class AdminDTO implements Serializable {
9 |
10 | private Integer id;
11 | private String username;
12 | private String name;
13 | private String phone;
14 | private String sex;
15 | private String idNumber;
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/backend/wall-pojo/src/main/java/cn/yiming1234/NottinghamWall/dto/AdminLoginDTO.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.dto;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import io.swagger.annotations.ApiModelProperty;
5 | import lombok.Data;
6 |
7 | import java.io.Serializable;
8 |
9 | @Data
10 | @ApiModel(description = "管理员登录时传递的数据模型")
11 | public class AdminLoginDTO implements Serializable {
12 |
13 | @ApiModelProperty("用户名")
14 | private String username;
15 |
16 | @ApiModelProperty("密码")
17 | private String password;
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/backend/wall-pojo/src/main/java/cn/yiming1234/NottinghamWall/dto/CommentDTO.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.dto;
2 |
3 | import lombok.Data;
4 |
5 | import java.time.LocalDateTime;
6 | import java.util.List;
7 |
8 | @Data
9 | public class CommentDTO {
10 |
11 | private Integer id;
12 | private Integer topicId;
13 | private Integer userId;
14 | private String username;
15 | private String avatar;
16 | private String content;
17 | private Integer parentId;
18 | private Boolean isLiked;
19 | private Integer likeCount;
20 | private LocalDateTime createdAt;
21 | private LocalDateTime updatedAt;
22 | private StudentDTO user;
23 | private List replies;
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/backend/wall-pojo/src/main/java/cn/yiming1234/NottinghamWall/dto/PageQueryDTO.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.dto;
2 |
3 | import lombok.Data;
4 |
5 | import java.io.Serializable;
6 |
7 | @Data
8 | public class PageQueryDTO implements Serializable {
9 |
10 | private String name;
11 | private String tags;
12 | private String username;
13 | private Integer page;
14 | private Integer pageSize;
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/backend/wall-pojo/src/main/java/cn/yiming1234/NottinghamWall/dto/ReportDTO.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.dto;
2 |
3 | import lombok.Data;
4 |
5 | @Data
6 | public class ReportDTO {
7 |
8 | private Integer id;
9 | private Integer topicId;
10 | private Integer commentId;
11 | private Integer authorId;
12 | private Integer userId;
13 | private String tags;
14 | private String detailedDescription;
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/backend/wall-pojo/src/main/java/cn/yiming1234/NottinghamWall/dto/StudentDTO.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.dto;
2 |
3 | import com.fasterxml.jackson.annotation.JsonInclude;
4 | import lombok.Data;
5 | import lombok.ToString;
6 |
7 | import java.io.Serializable;
8 |
9 | @Data
10 | @JsonInclude(JsonInclude.Include.NON_NULL)
11 |
12 | public class StudentDTO implements Serializable {
13 |
14 | private Integer id;
15 | private Integer studentid;
16 | private String username;
17 | private String name;
18 | private String avatar;
19 | private String email;
20 | private String phone;
21 | private String sex;
22 | private String idNumber;
23 |
24 | /**
25 | * 重写toString方法
26 | * @return
27 | */
28 | @Override
29 | @ToString.Include
30 | public String toString() {
31 | StringBuilder sb = new StringBuilder("StudentDTO{");
32 | sb.append("id=").append(id);
33 | if (studentid != null) sb.append(", studentid='").append(studentid).append('\'');
34 | if (username != null) sb.append(", username='").append(username).append('\'');
35 | if (name != null) sb.append(", name='").append(name).append('\'');
36 | if (avatar != null) sb.append(", avatar='").append(avatar).append('\'');
37 | if (email != null) sb.append(", email='").append(email).append('\'');
38 | if (phone != null) sb.append(", phone='").append(phone).append('\'');
39 | if (sex != null) sb.append(", sex='").append(sex).append('\'');
40 | if (idNumber != null) sb.append(", idNumber='").append(idNumber).append('\'');
41 | sb.append('}');
42 | return sb.toString();
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/backend/wall-pojo/src/main/java/cn/yiming1234/NottinghamWall/dto/StudentLoginDTO.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.dto;
2 |
3 | import lombok.Data;
4 | import lombok.Getter;
5 | import lombok.Setter;
6 |
7 | import java.io.Serializable;
8 |
9 | /**
10 | * 学生登录DTO
11 | */
12 | @Setter
13 | @Getter
14 | @Data
15 | public class StudentLoginDTO implements Serializable {
16 |
17 | private String code;
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/backend/wall-pojo/src/main/java/cn/yiming1234/NottinghamWall/dto/TopicDTO.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.dto;
2 |
3 | import lombok.Data;
4 |
5 | import java.io.Serializable;
6 | import java.time.LocalDateTime;
7 | import java.util.List;
8 |
9 | @Data
10 | public class TopicDTO implements Serializable {
11 |
12 | private Integer id;
13 | private String content;
14 | private List imgURLs;
15 | private Integer authorID;
16 | private LocalDateTime createdAt;
17 | private LocalDateTime updatedAt;
18 | private Boolean isDraft;
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/backend/wall-pojo/src/main/java/cn/yiming1234/NottinghamWall/dto/UpdatePasswordDTO.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.dto;
2 |
3 | import lombok.Data;
4 |
5 | @Data
6 | public class UpdatePasswordDTO {
7 | private String oldPassword;
8 | private String newPassword;
9 | private String confirmPassword;
10 | }
--------------------------------------------------------------------------------
/backend/wall-pojo/src/main/java/cn/yiming1234/NottinghamWall/entity/Admin.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.entity;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.io.Serializable;
9 | import java.time.LocalDateTime;
10 |
11 | @Data
12 | @Builder
13 | @NoArgsConstructor
14 | @AllArgsConstructor
15 | public class Admin implements Serializable {
16 |
17 | private static final long serialVersionUID = 1L;
18 | private Integer id;
19 | private String username;
20 | private String name;
21 | private String password;
22 | private String phone;
23 | private String sex;
24 | private String idNumber;
25 | private Integer status;
26 |
27 | //@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
28 | private LocalDateTime createTime;
29 | //@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
30 | private LocalDateTime updateTime;
31 | private Integer createUser;
32 | private Integer updateUser;
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/backend/wall-pojo/src/main/java/cn/yiming1234/NottinghamWall/entity/Comment.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.entity;
2 |
3 | import lombok.Data;
4 |
5 | import java.time.LocalDateTime;
6 |
7 | @Data
8 | public class Comment {
9 |
10 | private Integer id;
11 | private Integer topicId;
12 | private Integer userId;
13 | private String username;
14 | private String avatar;
15 | private String content;
16 | private boolean isLiked;
17 | private Integer likeCount;
18 | private LocalDateTime createdAt;
19 | private LocalDateTime updatedAt;
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/backend/wall-pojo/src/main/java/cn/yiming1234/NottinghamWall/entity/Report.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.entity;
2 |
3 | import lombok.Data;
4 |
5 | import java.time.LocalDateTime;
6 |
7 | @Data
8 | public class Report {
9 |
10 | private Integer id;
11 | private Integer topicId;
12 | private Integer commentId;
13 | private Integer authorId;
14 | private Integer userId;
15 | private LocalDateTime reportTime;
16 | private String tags;
17 | private String detailedDescription;
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/backend/wall-pojo/src/main/java/cn/yiming1234/NottinghamWall/entity/Student.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.entity;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.io.Serializable;
9 | import java.time.LocalDateTime;
10 |
11 | @Data
12 | @Builder
13 | @NoArgsConstructor
14 | @AllArgsConstructor
15 | public class Student implements Serializable {
16 |
17 | private static final long serialVersionUID = 1L;
18 | private Integer id;
19 | private String openid;
20 | private Integer studentid;
21 | private String username;
22 | private String email;
23 | private String phone;
24 | private String sex;
25 | private String idNumber;
26 | private String avatar;
27 | private LocalDateTime createTime;
28 | private LocalDateTime updateTime;
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/backend/wall-pojo/src/main/java/cn/yiming1234/NottinghamWall/entity/Topic.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.entity;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.io.Serializable;
9 | import java.time.LocalDateTime;
10 | import java.util.List;
11 |
12 | @Data
13 | @Builder
14 | @NoArgsConstructor
15 | @AllArgsConstructor
16 | public class Topic implements Serializable {
17 |
18 | private static final long serialVersionUID = 1L;
19 | private Integer id;
20 | private String content;
21 | private Integer authorID;
22 | private String username;
23 | private String avatar;
24 | private List imgURLs;
25 | private LocalDateTime createdAt;
26 | private LocalDateTime updatedAt;
27 | private Boolean isDraft;
28 | private Integer likeCount;
29 | private Integer commentCount;
30 | private Integer collectCount;
31 | private Boolean isLiked;
32 | private Boolean isCollected;
33 | }
--------------------------------------------------------------------------------
/backend/wall-pojo/src/main/java/cn/yiming1234/NottinghamWall/typehandler/JsonTypeHandler.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.typehandler;
2 |
3 | import com.fasterxml.jackson.core.JsonProcessingException;
4 | import com.fasterxml.jackson.core.type.TypeReference;
5 | import com.fasterxml.jackson.databind.ObjectMapper;
6 | import org.apache.ibatis.type.BaseTypeHandler;
7 | import org.apache.ibatis.type.JdbcType;
8 |
9 | import java.sql.*;
10 | import java.util.List;
11 |
12 | public class JsonTypeHandler extends BaseTypeHandler> {
13 |
14 | private static final ObjectMapper objectMapper = new ObjectMapper();
15 |
16 | @Override
17 | public void setNonNullParameter(PreparedStatement ps, int i, List parameter, JdbcType jdbcType) throws SQLException {
18 | try {
19 | ps.setString(i, objectMapper.writeValueAsString(parameter));
20 | } catch (JsonProcessingException e) {
21 | throw new RuntimeException(e);
22 | }
23 | }
24 |
25 | @Override
26 | public List getNullableResult(ResultSet rs, String columnName) throws SQLException {
27 | return toList(rs.getString(columnName));
28 | }
29 |
30 | @Override
31 | public List getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
32 | return toList(rs.getString(columnIndex));
33 | }
34 |
35 | @Override
36 | public List getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
37 | return toList(cs.getString(columnIndex));
38 | }
39 |
40 | private List toList(String json) throws SQLException {
41 | if (json == null) {
42 | return null;
43 | }
44 | try {
45 | return objectMapper.readValue(json, new TypeReference>() {});
46 | } catch (Exception e) {
47 | throw new SQLException("Failed to convert JSON to List", e);
48 | }
49 | }
50 | }
--------------------------------------------------------------------------------
/backend/wall-pojo/src/main/java/cn/yiming1234/NottinghamWall/vo/AdminLoginVO.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.vo;
2 |
3 | import io.swagger.annotations.ApiModel;
4 | import io.swagger.annotations.ApiModelProperty;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 |
10 | import java.io.Serializable;
11 |
12 | @Data
13 | @Builder
14 | @NoArgsConstructor
15 | @AllArgsConstructor
16 | @ApiModel(description = "管理员登录返回的数据格式")
17 | public class AdminLoginVO implements Serializable {
18 |
19 | @ApiModelProperty("主键值")
20 | private Integer id;
21 |
22 | @ApiModelProperty("用户名")
23 | private String userName;
24 |
25 | @ApiModelProperty("姓名")
26 | private String name;
27 |
28 | @ApiModelProperty("jwt令牌")
29 | private String token;
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/backend/wall-pojo/src/main/java/cn/yiming1234/NottinghamWall/vo/StudentLoginVO.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.vo;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.io.Serializable;
9 |
10 | /**
11 | * 学生登录VO
12 | */
13 | @Data
14 | @Builder
15 | @NoArgsConstructor
16 | @AllArgsConstructor
17 | public class StudentLoginVO implements Serializable {
18 |
19 | private Integer id;
20 | private String openid;
21 | private String token;
22 | }
23 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/java/cn/yiming1234/NottinghamWall/WallApplication.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.mybatis.spring.annotation.MapperScan;
5 | import org.springframework.boot.SpringApplication;
6 | import org.springframework.boot.autoconfigure.SpringBootApplication;
7 | import org.springframework.context.annotation.EnableAspectJAutoProxy;
8 | import org.springframework.transaction.annotation.EnableTransactionManagement;
9 |
10 | @SpringBootApplication
11 | @EnableAspectJAutoProxy
12 | @EnableTransactionManagement
13 | @MapperScan("cn.yiming1234.NottinghamWall.mapper")
14 | @Slf4j
15 | public class WallApplication {
16 | public static void main(String[] args) {
17 | SpringApplication.run(WallApplication.class, args);
18 | log.info("server started");
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/java/cn/yiming1234/NottinghamWall/annotation/AutoFill.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.annotation;
2 |
3 | import cn.yiming1234.NottinghamWall.enumeration.OperationType;
4 | import java.lang.annotation.ElementType;
5 | import java.lang.annotation.Retention;
6 | import java.lang.annotation.RetentionPolicy;
7 | import java.lang.annotation.Target;
8 |
9 | /**
10 | * 自动填充注解
11 | */
12 | @Target(ElementType.METHOD)
13 | @Retention(RetentionPolicy.RUNTIME)
14 | public @interface AutoFill{
15 | OperationType value();
16 | }
--------------------------------------------------------------------------------
/backend/wall-server/src/main/java/cn/yiming1234/NottinghamWall/aspect/AutoFillAspect.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.aspect;
2 |
3 | import cn.yiming1234.NottinghamWall.annotation.AutoFill;
4 | import cn.yiming1234.NottinghamWall.constant.AutoFillConstant;
5 | import cn.yiming1234.NottinghamWall.context.BaseContext;
6 | import cn.yiming1234.NottinghamWall.enumeration.OperationType;
7 | import lombok.extern.slf4j.Slf4j;
8 | import org.aspectj.lang.JoinPoint;
9 | import org.aspectj.lang.annotation.Aspect;
10 | import org.aspectj.lang.annotation.Before;
11 | import org.aspectj.lang.annotation.Pointcut;
12 | import org.aspectj.lang.reflect.MethodSignature;
13 | import org.springframework.stereotype.Component;
14 |
15 | import java.lang.reflect.Method;
16 | import java.time.LocalDateTime;
17 |
18 | /**
19 | * 自动填充切面
20 | */
21 | @Component
22 | @Aspect
23 | @Slf4j
24 | public class AutoFillAspect {
25 |
26 | /**
27 | * 自动填充切入点
28 | */
29 | @Pointcut("execution(* cn.yiming1234.NottinghamWall.mapper.*.*(..)) && @annotation(cn.yiming1234.NottinghamWall.annotation.AutoFill)")
30 | public void autoFillPointCut() {
31 | }
32 |
33 | /**
34 | * 自动填充
35 | */
36 | @Before("autoFillPointCut()")
37 | public void autoFill(JoinPoint joinPoint) {
38 | MethodSignature signature = (MethodSignature) joinPoint.getSignature();
39 | AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);
40 | OperationType operationType = autoFill.value();
41 |
42 | Object[] args = joinPoint.getArgs();
43 | if(args == null || args.length == 0) {
44 | return;
45 | }
46 | Object entity = args[0];
47 | LocalDateTime now = LocalDateTime.now();
48 | Integer currentId = BaseContext.getCurrentId();
49 | log.info("Auto-fill operation start");
50 | if(operationType == OperationType.INSERT) {
51 | try {
52 | Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME,LocalDateTime.class);
53 | Method setCreateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER,Integer.class);
54 | Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME,LocalDateTime.class);
55 | Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER,Integer.class);
56 |
57 | setCreateTime.invoke(entity, now);
58 | setCreateUser.invoke(entity, currentId);
59 | setUpdateTime.invoke(entity, now);
60 | setUpdateUser.invoke(entity, currentId);
61 | log.info("Auto-fill operation success");
62 | } catch (Exception e) {
63 | log.error("Error during auto-fill operation", e);
64 | }
65 | }else if(operationType == OperationType.UPDATE){
66 | try {
67 | Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME,LocalDateTime.class);
68 | Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER,Integer.class);
69 |
70 | setUpdateTime.invoke(entity, now);
71 | setUpdateUser.invoke(entity, currentId);
72 | } catch (Exception e) {
73 | log.error("Error during auto-fill operation", e);
74 | }
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/java/cn/yiming1234/NottinghamWall/config/OssConfiguration.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.config;
2 |
3 | import cn.yiming1234.NottinghamWall.properties.AliOssProperties;
4 | import cn.yiming1234.NottinghamWall.utils.AliOssUtil;
5 | import lombok.extern.slf4j.Slf4j;
6 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.context.annotation.Configuration;
9 |
10 | @Configuration
11 | @Slf4j
12 | public class OssConfiguration {
13 | @Bean
14 | @ConditionalOnMissingBean
15 | public AliOssUtil aliOssUtil(AliOssProperties aliOssProperties) {
16 | log.info("开始创建阿里云文件上传工具类: {}", aliOssProperties);
17 | return new AliOssUtil(
18 | aliOssProperties.getEndpoint(),
19 | aliOssProperties.getAccessKeyId(),
20 | aliOssProperties.getAccessKeySecret(),
21 | aliOssProperties.getBucketName());
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/java/cn/yiming1234/NottinghamWall/config/RedisConfiguration.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.config;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.springframework.context.annotation.Bean;
5 | import org.springframework.context.annotation.Configuration;
6 | import org.springframework.data.redis.connection.RedisConnectionFactory;
7 | import org.springframework.data.redis.core.RedisTemplate;
8 | import org.springframework.data.redis.serializer.StringRedisSerializer;
9 |
10 | @Configuration
11 | @Slf4j
12 | public class RedisConfiguration {
13 |
14 | @Bean
15 | public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
16 | log.info("初始化RedisTemplate");
17 | RedisTemplate redisTemplate = new RedisTemplate();
18 | redisTemplate.setConnectionFactory(redisConnectionFactory);
19 | //设置序列化方式
20 | redisTemplate.setKeySerializer(new StringRedisSerializer());
21 | return redisTemplate;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/java/cn/yiming1234/NottinghamWall/controller/admin/AdminCommonController.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.controller.admin;
2 |
3 | import cn.yiming1234.NottinghamWall.result.Result;
4 | import cn.yiming1234.NottinghamWall.utils.AliOssUtil;
5 | import io.swagger.annotations.Api;
6 | import io.swagger.annotations.ApiOperation;
7 | import lombok.extern.slf4j.Slf4j;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.web.bind.annotation.PostMapping;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.bind.annotation.RestController;
12 | import org.springframework.web.multipart.MultipartFile;
13 |
14 | import java.io.IOException;
15 | import java.util.UUID;
16 |
17 | /**
18 | * 公共控制器
19 | */
20 | @RestController
21 | @RequestMapping("admin/common")
22 | @Api(tags = "管理端公共接口")
23 | @Slf4j
24 | public class AdminCommonController {
25 |
26 | @Autowired
27 | private AliOssUtil aliOssUtil;
28 |
29 | /**
30 | * 管理员上传文件
31 | */
32 | @PostMapping("/upload")
33 | @ApiOperation(value = "管理员上传文件")
34 | public Result upload(MultipartFile file) {
35 | log.info("上传成功:{}",file);
36 |
37 | try {
38 | String originalFilename = file.getOriginalFilename();
39 | String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
40 | String objectName = UUID.randomUUID() + extension;
41 | String filePath = aliOssUtil.upload(file.getBytes(), objectName);
42 | return Result.success(filePath);
43 | } catch (IOException e) {
44 | log.error("上传文件失败", e);
45 | } catch (Exception e) {
46 | throw new RuntimeException(e);
47 | }
48 |
49 | return null;
50 | }
51 | /**
52 | * 管理员删除文件
53 | */
54 | @PostMapping("/delete")
55 | @ApiOperation(value = "管理员删除文件")
56 | public Result delete(String file) {
57 | log.info("删除文件:{}",file);
58 | aliOssUtil.delete(file);
59 | return Result.success();
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/java/cn/yiming1234/NottinghamWall/controller/admin/ReportController.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.controller.admin;
2 |
3 | import cn.yiming1234.NottinghamWall.dto.PageQueryDTO;
4 | import cn.yiming1234.NottinghamWall.result.PageResult;
5 | import cn.yiming1234.NottinghamWall.result.Result;
6 | import cn.yiming1234.NottinghamWall.service.ReportService;
7 | import io.swagger.annotations.ApiOperation;
8 | import lombok.extern.slf4j.Slf4j;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.web.bind.annotation.GetMapping;
11 | import org.springframework.web.bind.annotation.RequestMapping;
12 | import org.springframework.web.bind.annotation.RestController;
13 |
14 | @RestController("adminReportController")
15 | @RequestMapping("/admin")
16 | @ApiOperation("管理端举报接口")
17 | @Slf4j
18 | public class ReportController {
19 |
20 | @Autowired
21 | private ReportService reportService;
22 |
23 | /**
24 | * 举报分页查询
25 | */
26 | @GetMapping("/page")
27 | @ApiOperation("分页查询举报")
28 | public Result page(PageQueryDTO pageQueryDTO) {
29 | log.info("举报分页查询:{}", pageQueryDTO);
30 | PageResult pageResult = reportService.pageQuery(pageQueryDTO);
31 | return Result.success(pageResult);
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/java/cn/yiming1234/NottinghamWall/controller/admin/StudentController.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.controller.admin;
2 |
3 | import cn.yiming1234.NottinghamWall.dto.PageQueryDTO;
4 | import cn.yiming1234.NottinghamWall.entity.Student;
5 | import cn.yiming1234.NottinghamWall.result.PageResult;
6 | import cn.yiming1234.NottinghamWall.result.Result;
7 | import cn.yiming1234.NottinghamWall.service.StudentService;
8 | import com.aliyuncs.exceptions.ClientException;
9 | import io.swagger.annotations.Api;
10 | import io.swagger.annotations.ApiOperation;
11 | import lombok.extern.slf4j.Slf4j;
12 | import org.springframework.beans.factory.annotation.Autowired;
13 | import org.springframework.web.bind.annotation.GetMapping;
14 | import org.springframework.web.bind.annotation.PathVariable;
15 | import org.springframework.web.bind.annotation.RequestMapping;
16 | import org.springframework.web.bind.annotation.RestController;
17 |
18 | @RestController("adminStudentController")
19 | @RequestMapping("/admin/student")
20 | @Slf4j
21 | @Api(tags = "管理端学生接口")
22 | public class StudentController {
23 |
24 | @Autowired
25 | private StudentService studentService;
26 |
27 | /**
28 | * 学生分页查询
29 | */
30 | @GetMapping("/page")
31 | @ApiOperation("分页查询学生")
32 | public Result> page(PageQueryDTO pageQueryDTO){
33 | log.info("学生分页查询:{}", pageQueryDTO);
34 | PageResult pageResult = studentService.pageQuery(pageQueryDTO);
35 | return Result.success(pageResult);
36 | }
37 | /**
38 | * 根据id查询学生
39 | */
40 | @GetMapping("/{id}")
41 | @ApiOperation("根据id查询学生")
42 | public Result getById(@PathVariable Integer id) throws ClientException {
43 | Student student = studentService.getById(id);
44 | return Result.success(student);
45 | }
46 |
47 | /**
48 | * 根据学号查询学生
49 | */
50 | @GetMapping("/getByStudentId/{studentId}")
51 | @ApiOperation("根据学号查询学生")
52 | public Result getByStudentId(@PathVariable Integer studentId){
53 | Student student = studentService.getByStudentId(studentId);
54 | return Result.success(student);
55 | }
56 |
57 | /**
58 | * 根据邮箱查询学生
59 | */
60 | @GetMapping("/getByEmail/{email}")
61 | @ApiOperation("根据邮箱查询学生")
62 | public Result getByEmail(@PathVariable String email){
63 | Student student = studentService.getByEmail(email);
64 | return Result.success(student);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/java/cn/yiming1234/NottinghamWall/controller/admin/TopicController.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.controller.admin;
2 |
3 | import cn.yiming1234.NottinghamWall.dto.CommentDTO;
4 | import cn.yiming1234.NottinghamWall.dto.PageQueryDTO;
5 | import cn.yiming1234.NottinghamWall.entity.Topic;
6 | import cn.yiming1234.NottinghamWall.result.PageResult;
7 | import cn.yiming1234.NottinghamWall.result.Result;
8 | import cn.yiming1234.NottinghamWall.service.CommentService;
9 | import cn.yiming1234.NottinghamWall.service.TopicService;
10 | import cn.yiming1234.NottinghamWall.utils.AliOssUtil;
11 | import com.github.pagehelper.PageInfo;
12 | import io.swagger.annotations.ApiOperation;
13 | import lombok.extern.slf4j.Slf4j;
14 | import org.springframework.beans.factory.annotation.Autowired;
15 | import org.springframework.web.bind.annotation.*;
16 |
17 | import java.util.List;
18 |
19 | @RestController("adminTopicController")
20 | @RequestMapping("/admin/topic")
21 | @ApiOperation("管理端话题接口")
22 | @Slf4j
23 | public class TopicController {
24 |
25 | private final TopicService topicService;
26 | private final CommentService commentService;
27 | private final AliOssUtil aliOssUtil;
28 |
29 | @Autowired
30 | public TopicController(TopicService topicService, CommentService commentService, AliOssUtil aliOssUtil) {
31 | this.topicService = topicService;
32 | this.commentService = commentService;
33 | this.aliOssUtil = aliOssUtil;
34 | }
35 |
36 | /**
37 | * 话题分页查询
38 | */
39 | @GetMapping("/page")
40 | @ApiOperation("分页查询话题")
41 | public Result> page(PageQueryDTO pageQueryDTO) {
42 | PageResult pageResult = topicService.pageQuery(pageQueryDTO);
43 | log.info("管理端话题分页查询结果:{}", pageResult);
44 | return Result.success(pageResult);
45 | }
46 |
47 | /**
48 | * 根据话题id获取所有评论
49 | */
50 | @GetMapping("/getcomment/{id}")
51 | @ApiOperation("根据话题id获取评论")
52 | public Result> getComment(@PathVariable Integer id) {
53 | PageInfo comments = commentService.getComments(id, 1, 10);
54 | log.info("根据话题id获取评论:{}", comments);
55 | return Result.success(comments);
56 | }
57 |
58 | /**
59 | * 根据话题id删除话题
60 | */
61 | @DeleteMapping("/delete/{id}")
62 | @ApiOperation("根据话题id删除话题")
63 | public Result deleteTopic(@PathVariable Integer id) {
64 | log.info("删除话题:{}", id);
65 | Topic topic = topicService.getTopicById(id);
66 | List imgURLs = topic.getImgURLs();
67 | for (String imgURL : imgURLs) {
68 | String objectName = imgURL.substring(imgURL.lastIndexOf("/") + 1);
69 | aliOssUtil.delete(objectName);
70 | }
71 | log.info("删除图片成功");
72 | topicService.deleteTopic(id);
73 | return Result.success(null);
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/java/cn/yiming1234/NottinghamWall/controller/admin/UniappController.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.controller.admin;
2 |
3 | import cn.yiming1234.NottinghamWall.result.Result;
4 | import io.swagger.annotations.Api;
5 | import io.swagger.annotations.ApiOperation;
6 | import lombok.extern.slf4j.Slf4j;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.data.redis.core.RedisTemplate;
9 | import org.springframework.web.bind.annotation.*;
10 |
11 | @RestController("adminUniappController")
12 | @RequestMapping("/admin/uniapp")
13 | @Api(tags = "uniapp管理接口")
14 | @Slf4j
15 | public class UniappController {
16 |
17 | public static final String KEY = "uniapp_status";
18 |
19 | @Autowired
20 | private RedisTemplate redisTemplate;
21 | /**
22 | * 设置状态
23 | */
24 | @PutMapping("/{status}")
25 | @ApiOperation(value = "设置状态")
26 | public Result setStatus(@PathVariable Integer status) {
27 | log.info("设置状态:{}", status == 1 ? "开启" : "关闭");
28 | redisTemplate.opsForValue().set(KEY, status);
29 | return Result.success();
30 | }
31 |
32 | /**
33 | * 管理端获取状态
34 | */
35 | @GetMapping("/status")
36 | @ApiOperation(value = "获取状态")
37 | public Result getStatus() {
38 | Integer status = (Integer) redisTemplate.opsForValue().get(KEY);
39 | log.info("获取状态:{}", status == 1 ? "运行中" : "维护中");
40 | return Result.success(status);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/java/cn/yiming1234/NottinghamWall/controller/student/ReportController.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.controller.student;
2 |
3 | import cn.yiming1234.NottinghamWall.dto.ReportDTO;
4 | import cn.yiming1234.NottinghamWall.service.ReportService;
5 | import io.swagger.annotations.Api;
6 | import io.swagger.annotations.ApiOperation;
7 | import lombok.extern.slf4j.Slf4j;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.http.HttpStatus;
10 | import org.springframework.http.ResponseEntity;
11 | import org.springframework.web.bind.annotation.PostMapping;
12 | import org.springframework.web.bind.annotation.RequestBody;
13 | import org.springframework.web.bind.annotation.RequestMapping;
14 | import org.springframework.web.bind.annotation.RestController;
15 |
16 | @RestController
17 | @RequestMapping("/student")
18 | @Api(tags = "用户端举报接口")
19 | @Slf4j
20 | public class ReportController {
21 |
22 | @Autowired
23 | private ReportService reportService;
24 |
25 | @PostMapping("/report/insert")
26 | @ApiOperation(value = "举报")
27 | public ResponseEntity insertReport(@RequestBody ReportDTO reportDTO) {
28 | try {
29 | reportService.insertReport(reportDTO);
30 | log.info("举报成功:{}", reportDTO);
31 | return ResponseEntity.ok("举报成功");
32 | } catch (IllegalArgumentException e) {
33 | log.warn("举报失败: {}", e.getMessage());
34 | return ResponseEntity.status(HttpStatus.CONFLICT).body("举报失败: " + e.getMessage());
35 | }
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/java/cn/yiming1234/NottinghamWall/controller/student/UniappController.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.controller.student;
2 |
3 | import cn.yiming1234.NottinghamWall.result.Result;
4 | import io.swagger.annotations.Api;
5 | import io.swagger.annotations.ApiOperation;
6 | import lombok.extern.slf4j.Slf4j;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.data.redis.core.RedisTemplate;
9 | import org.springframework.web.bind.annotation.*;
10 |
11 | @RestController("studentUniappController")
12 | @RequestMapping("/student/uniapp")
13 | @Api(tags = "uniapp管理接口")
14 | @Slf4j
15 | public class UniappController {
16 |
17 | public static final String KEY = "uniapp_status";
18 |
19 | @Autowired
20 | private RedisTemplate redisTemplate;
21 |
22 | /**
23 | * 学生端获取状态
24 | */
25 | @GetMapping("/status")
26 | @ApiOperation(value = "获取状态")
27 | public Result getStatus() {
28 | Integer status = (Integer) redisTemplate.opsForValue().get(KEY);
29 | log.info("获取状态:{}", status == 1 ? "运行中" : "维护中");
30 | return Result.success(status);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/java/cn/yiming1234/NottinghamWall/handler/GlobalExceptionHandler.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.handler;
2 |
3 | import cn.yiming1234.NottinghamWall.exception.BaseException;
4 | import cn.yiming1234.NottinghamWall.exception.TeapotException;
5 | import cn.yiming1234.NottinghamWall.result.Result;
6 | import lombok.extern.slf4j.Slf4j;
7 | import org.springframework.web.bind.annotation.ExceptionHandler;
8 | import org.springframework.web.bind.annotation.RestControllerAdvice;
9 |
10 | /**
11 | * 全局异常处理器,处理项目中抛出的业务异常
12 | */
13 | @RestControllerAdvice
14 | @Slf4j
15 | public class GlobalExceptionHandler {
16 |
17 | /**
18 | * 捕获业务异常
19 | */
20 | @ExceptionHandler
21 | public Result exceptionHandler(BaseException ex){
22 | log.error("异常信息:{}", ex.getMessage());
23 | return Result.error(ex.getMessage());
24 | }
25 |
26 | /**
27 | * 捕获TeapotException异常
28 | */
29 | @ExceptionHandler(TeapotException.class)
30 | public Result teapotExceptionHandler(TeapotException ex){
31 | log.error("异常信息:{}", ex.getMessage());
32 | return Result.error(ex.getMessage());
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/java/cn/yiming1234/NottinghamWall/interceptor/JwtTokenAdminInterceptor.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.interceptor;
2 |
3 | import cn.yiming1234.NottinghamWall.constant.JwtClaimsConstant;
4 | import cn.yiming1234.NottinghamWall.context.BaseContext;
5 | import cn.yiming1234.NottinghamWall.properties.JwtProperties;
6 | import cn.yiming1234.NottinghamWall.utils.JwtUtil;
7 | import io.jsonwebtoken.Claims;
8 | import lombok.extern.slf4j.Slf4j;
9 | import org.jetbrains.annotations.NotNull;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.stereotype.Component;
12 | import org.springframework.web.method.HandlerMethod;
13 | import org.springframework.web.servlet.HandlerInterceptor;
14 |
15 | import javax.servlet.http.HttpServletRequest;
16 | import javax.servlet.http.HttpServletResponse;
17 |
18 | /**
19 | * jwt令牌校验的拦截器
20 | */
21 | @Component
22 | @Slf4j
23 | public class JwtTokenAdminInterceptor implements HandlerInterceptor {
24 |
25 | @Autowired
26 | private JwtProperties jwtProperties;
27 |
28 | /**
29 | * 校验jwt
30 | */
31 | public boolean preHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) {
32 | if (!(handler instanceof HandlerMethod)) {
33 | return true;
34 |
35 | }
36 | String token = request.getHeader(jwtProperties.getAdminTokenName());
37 | try {
38 | log.info("jwt校验:{}", token);
39 | Claims claims = JwtUtil.parseJWT(jwtProperties.getAdminSecretKey(), token);
40 | Integer empId = (Integer) claims.get(JwtClaimsConstant.EMP_ID);
41 | log.info("当前员工id:{}", empId);
42 | BaseContext.setCurrentId(empId);
43 | return true;
44 | } catch (Exception ex) {
45 | response.setStatus(401);
46 | return false;
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/java/cn/yiming1234/NottinghamWall/interceptor/JwtTokenStudentInterceptor.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.interceptor;
2 |
3 | import cn.yiming1234.NottinghamWall.constant.JwtClaimsConstant;
4 | import cn.yiming1234.NottinghamWall.context.BaseContext;
5 | import cn.yiming1234.NottinghamWall.properties.JwtProperties;
6 | import cn.yiming1234.NottinghamWall.utils.JwtUtil;
7 | import io.jsonwebtoken.Claims;
8 | import lombok.extern.slf4j.Slf4j;
9 | import org.jetbrains.annotations.NotNull;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.stereotype.Component;
12 | import org.springframework.web.method.HandlerMethod;
13 | import org.springframework.web.servlet.HandlerInterceptor;
14 |
15 | import javax.servlet.http.HttpServletRequest;
16 | import javax.servlet.http.HttpServletResponse;
17 |
18 | /**
19 | * jwt令牌校验的拦截器
20 | */
21 | @Component
22 | @Slf4j
23 | public class JwtTokenStudentInterceptor implements HandlerInterceptor {
24 |
25 | @Autowired
26 | private JwtProperties jwtProperties;
27 |
28 | /**
29 | * 校验jwt
30 | */
31 | public boolean preHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) {
32 | if (!(handler instanceof HandlerMethod)) {
33 | return true;
34 | }
35 | String token = request.getHeader(jwtProperties.getUserTokenName());
36 | try {
37 | log.info("jwt校验:{}", token);
38 | Claims claims = JwtUtil.parseJWT(jwtProperties.getUserSecretKey(), token);
39 | Integer userId = (Integer) claims.get(JwtClaimsConstant.USER_ID);
40 | log.info("userId:{}", userId);
41 | BaseContext.setCurrentId(userId);
42 | return true;
43 | } catch (Exception ex) {
44 | response.setStatus(401);
45 | return false;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/java/cn/yiming1234/NottinghamWall/mapper/AdminMapper.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.mapper;
2 |
3 | import cn.yiming1234.NottinghamWall.dto.PageQueryDTO;
4 | import com.github.pagehelper.Page;
5 | import cn.yiming1234.NottinghamWall.annotation.AutoFill;
6 | import cn.yiming1234.NottinghamWall.entity.Admin;
7 | import cn.yiming1234.NottinghamWall.enumeration.OperationType;
8 | import org.apache.ibatis.annotations.Mapper;
9 |
10 | @Mapper
11 | public interface AdminMapper {
12 | /**
13 | * 根据用户名查询管理员
14 | */
15 | Admin getByUsername(String username);
16 |
17 | /**
18 | * 根据id查询管理员
19 | */
20 | Admin getById(Integer id);
21 |
22 | /**
23 | * 分页查询管理员
24 | */
25 | Page pageQuery(PageQueryDTO pageQueryDTO);
26 |
27 | /**
28 | * 新增管理员
29 | */
30 | @AutoFill(value = OperationType.INSERT)
31 | void insert(Admin admin);
32 |
33 | /**
34 | * 修改管理员
35 | */
36 | @AutoFill(value = OperationType.UPDATE)
37 | void update(Admin admin);
38 | }
39 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/java/cn/yiming1234/NottinghamWall/mapper/CommentMapper.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.mapper;
2 |
3 | import cn.yiming1234.NottinghamWall.dto.CommentDTO;
4 | import cn.yiming1234.NottinghamWall.entity.Topic;
5 | import org.apache.ibatis.annotations.Mapper;
6 | import org.apache.ibatis.annotations.Param;
7 |
8 | import java.util.List;
9 |
10 | @Mapper
11 | public interface CommentMapper {
12 |
13 | /**
14 | * 评论话题
15 | */
16 | void commentTopic(CommentDTO commentDTO);
17 |
18 | /**
19 | * 回复评论
20 | */
21 | void replyComment(CommentDTO commentDTO);
22 |
23 | /**
24 | * 删除评论
25 | */
26 | void deleteComment(@Param("commentId") Integer commentId, @Param("userId") Integer userId);
27 |
28 | /**
29 | * 点赞评论
30 | */
31 | void likeComment(@Param("commentId") Integer commentId, @Param("userId") Integer userId);
32 |
33 | /**
34 | * 取消点赞评论
35 | */
36 | void unlikeComment(@Param("commentId") Integer commentId, @Param("userId") Integer userId);
37 |
38 | /**
39 | * 判断是否点赞评论
40 | */
41 | Boolean isLikeComment(@Param("commentId") Integer commentId, @Param("userId") Integer userId);
42 |
43 | /**
44 | * 获取点赞评论计数
45 | */
46 | int getLikeCommentCount(Integer id);
47 |
48 | /**
49 | * 获取评论列表
50 | */
51 | List getComments(@Param("topicId") Integer topicId);
52 |
53 | /**
54 | * 获取评论计数
55 | */
56 | int getCommentCount(@Param("topicId") Integer topicId);
57 |
58 | /**
59 | * 获取评论详情
60 | */
61 | CommentDTO getCommentById(@Param("commentId") Integer commentId);
62 |
63 | /**
64 | * 查询用户评论的帖子
65 | */
66 | List getCommentedPosts(@Param("userId") Integer userId);
67 | }
68 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/java/cn/yiming1234/NottinghamWall/mapper/ReportMapper.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.mapper;
2 |
3 | import cn.yiming1234.NottinghamWall.dto.PageQueryDTO;
4 | import cn.yiming1234.NottinghamWall.entity.Report;
5 | import com.github.pagehelper.Page;
6 | import org.apache.ibatis.annotations.Mapper;
7 | import org.apache.ibatis.annotations.Param;
8 |
9 | @Mapper
10 | public interface ReportMapper {
11 |
12 | /**
13 | * 插入举报信息
14 | */
15 | void insertReport(Report report);
16 |
17 | /**
18 | * 查询已经举报过的次数
19 | */
20 | int countExistingReports(@Param("authorId")Integer authorId, @Param("userId") Integer userId, @Param("topicId") Integer topicId, @Param("commentId") Integer commentId);
21 |
22 | /**
23 | * 分页查询举报
24 | */
25 | Page pageQuery(PageQueryDTO pageQueryDTO);
26 | }
27 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/java/cn/yiming1234/NottinghamWall/mapper/StudentMapper.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.mapper;
2 |
3 | import cn.yiming1234.NottinghamWall.dto.PageQueryDTO;
4 | import cn.yiming1234.NottinghamWall.entity.Student;
5 | import com.github.pagehelper.Page;
6 | import org.apache.ibatis.annotations.Mapper;
7 |
8 | @Mapper
9 | public interface StudentMapper {
10 |
11 | /**
12 | * 插入学生信息
13 | * @param student 学生信息
14 | */
15 | void insert(Student student);
16 |
17 | /**
18 | * 根据用户名查询管学生
19 | * @param username 用户名
20 | */
21 | Student getByUsername(String username);
22 |
23 | /**
24 | * 根据id查询学生
25 | * @param id 学生id
26 | */
27 | Student getById(Integer id);
28 |
29 | /**
30 | * 根据id查询openid
31 | * @param id 学生id
32 | */
33 | String getOpenidById(Integer id);
34 |
35 | /**
36 | * 根据openid查询学生
37 | * @param openid openid
38 | */
39 | Student findByOpenid(String openid);
40 |
41 | /**
42 | * 根据学号查询学生
43 | * @param studentid 学号
44 | */
45 | Student getByStudentId(Integer studentid);
46 |
47 | /**
48 | * 分页查询学生
49 | * @param pageQueryDTO 分页查询条件
50 | */
51 | Page pageQuery(PageQueryDTO pageQueryDTO);
52 |
53 | /**
54 | * 根据邮箱查询学生
55 | * @param email 邮箱
56 | */
57 | Student getByEmail(String email);
58 |
59 | /**
60 | * 更新学生信息
61 | * @param student 学生信息
62 | */
63 | void updateById(Student student);
64 |
65 | }
--------------------------------------------------------------------------------
/backend/wall-server/src/main/java/cn/yiming1234/NottinghamWall/mapper/TopicMapper.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.mapper;
2 |
3 | import cn.yiming1234.NottinghamWall.dto.PageQueryDTO;
4 | import cn.yiming1234.NottinghamWall.entity.Topic;
5 | import com.github.pagehelper.Page;
6 | import org.apache.ibatis.annotations.Mapper;
7 | import org.apache.ibatis.annotations.Param;
8 |
9 | import java.util.List;
10 |
11 | @Mapper
12 | public interface TopicMapper {
13 |
14 | /**
15 | * 新增话题/草稿
16 | */
17 | void insert(Topic topic);
18 |
19 | /**
20 | * 更新草稿
21 | */
22 | void update(Topic topic);
23 |
24 | /**
25 | * 获取草稿
26 | */
27 | Topic getDraft(Integer userId);
28 |
29 | /**
30 | * 删除草稿
31 | */
32 | void deleteDraft(Integer id);
33 |
34 | /**
35 | * 检查是否存在草稿
36 | */
37 | Boolean isExistDraft(Integer authorID);
38 |
39 | /**
40 | * 分页查询话题
41 | */
42 | Page pageQuery(PageQueryDTO pageQueryDTO);
43 |
44 | /**
45 | * 根据id获取话题
46 | */
47 | Topic getTopicById(Integer id);
48 |
49 | /**
50 | * 根据ids获取话题列表
51 | */
52 | List getTopicsByIds(List collectedTopicIds);
53 |
54 | /**
55 | * 点赞话题
56 | */
57 | void likeTopic(@Param("topicId") Integer topicId, @Param("userId") Integer userId);
58 |
59 | /**
60 | * 取消点赞话题
61 | */
62 | void unlikeTopic(@Param("topicId") Integer topicId, @Param("userId") Integer userId);
63 |
64 | /**
65 | * 判断是否点赞话题
66 | */
67 | Boolean isLikeTopic(@Param("topicId") Integer topicId, @Param("userId") Integer userId);
68 |
69 | /**
70 | * 获取点赞计数
71 | */
72 | int getLikeCount(@Param("topicId") Integer topicId);
73 |
74 | /**
75 | * 收藏话题
76 | */
77 | void collectTopic(@Param("topicId") Integer topicId, @Param("userId") Integer userId);
78 |
79 | /**
80 | * 取消收藏话题
81 | */
82 | void uncollectTopic(@Param("topicId") Integer topicId, @Param("userId") Integer userId);
83 |
84 | /**
85 | * 判断是否收藏话题
86 | */
87 | Boolean isCollectTopic(@Param("topicId") Integer topicId, @Param("userId") Integer userId);
88 |
89 | /**
90 | * 获取收藏计数
91 | */
92 | int getCollectCount(@Param("topicId") Integer topicId);
93 |
94 | /**
95 | * 删除话题及其相关信息
96 | */
97 | void deleteTopic(Integer topicId);
98 |
99 | /**
100 | * 删除话题点赞信息
101 | */
102 | void deleteTopicLikes(Integer topicId);
103 |
104 | /**
105 | * 删除话题收藏信息
106 | */
107 | void deleteTopicCollections(Integer topicId);
108 |
109 | /**
110 | * 删除话题评论信息
111 | */
112 | void deleteTopicComments(Integer topicId);
113 |
114 | /**
115 | * 查询用户发布的帖子ids
116 | */
117 | List getPublishedTopicIds(@Param("authorId") Integer authorId);
118 |
119 | /**
120 | * 查询用户收藏的帖子ids
121 | */
122 | List getCollectedTopicIds(@Param("id") Integer id);
123 | }
124 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/java/cn/yiming1234/NottinghamWall/service/AdminService.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.service;
2 |
3 | import cn.yiming1234.NottinghamWall.dto.AdminDTO;
4 | import cn.yiming1234.NottinghamWall.dto.AdminLoginDTO;
5 | import cn.yiming1234.NottinghamWall.dto.PageQueryDTO;
6 | import cn.yiming1234.NottinghamWall.entity.Admin;
7 | import cn.yiming1234.NottinghamWall.result.PageResult;
8 |
9 | public interface AdminService {
10 |
11 | /**
12 | * 管理员登录
13 | */
14 | Admin login(AdminLoginDTO adminLoginDTO);
15 |
16 | /**
17 | * 新增管理员
18 | */
19 | void save(AdminDTO adminDTO);
20 |
21 | /**
22 | * 启用禁用管理员
23 | */
24 | void startOrStop(Integer status, Integer id);
25 |
26 | /**
27 | * 分页查询管理员
28 | */
29 | PageResult pageQuery(PageQueryDTO PageQueryDTO);
30 |
31 | /**
32 | * 根据id查询管理员
33 | */
34 | Admin getById(Integer id);
35 |
36 | /**
37 | * 修改管理员
38 | */
39 | void update(AdminDTO adminDTO);
40 |
41 | /**
42 | * 修改密码
43 | */
44 | void updatePassword(Integer adminId, String oldPassword, String newPassword, String confirmPassword);
45 | }
46 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/java/cn/yiming1234/NottinghamWall/service/CommentService.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.service;
2 |
3 | import cn.yiming1234.NottinghamWall.dto.CommentDTO;
4 | import com.github.pagehelper.PageInfo;
5 |
6 | public interface CommentService {
7 | /**
8 | * 评论话题
9 | */
10 | void commentTopic(CommentDTO commentDTO);
11 |
12 | /**
13 | * 回复评论
14 | */
15 | void replyComment(CommentDTO commentDTO);
16 |
17 | /**
18 | * 删除评论
19 |
20 | */
21 | void deleteComment(Integer commentId, Integer userId);
22 |
23 | /**
24 | * 点赞评论
25 | */
26 | void likeComment(Integer commentId, Integer userId);
27 |
28 | /**
29 | * 取消点赞评论
30 | */
31 | void unlikeComment(Integer commentId, Integer userId);
32 |
33 | /**
34 | * 管理端获取评论列表
35 | */
36 | PageInfo getComments(Integer topicId, int page, int pageSize);
37 |
38 | /**
39 | * 用户端获取评论列表
40 | */
41 | PageInfo getComments(Integer userId, Integer topicId, int page, int pageSize);
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/java/cn/yiming1234/NottinghamWall/service/ReportService.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.service;
2 |
3 | import cn.yiming1234.NottinghamWall.dto.ReportDTO;
4 | import cn.yiming1234.NottinghamWall.dto.PageQueryDTO;
5 | import cn.yiming1234.NottinghamWall.result.PageResult;
6 |
7 | public interface ReportService {
8 |
9 | /**
10 | * 创建举报
11 | */
12 | void insertReport(ReportDTO reportDTO);
13 |
14 | /**
15 | * 分页查询举报
16 | */
17 | PageResult pageQuery(PageQueryDTO pageQueryDTO);
18 | }
19 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/java/cn/yiming1234/NottinghamWall/service/StudentService.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.service;
2 |
3 | import cn.yiming1234.NottinghamWall.dto.StudentDTO;
4 | import cn.yiming1234.NottinghamWall.dto.StudentLoginDTO;
5 | import cn.yiming1234.NottinghamWall.dto.PageQueryDTO;
6 | import cn.yiming1234.NottinghamWall.entity.Student;
7 | import cn.yiming1234.NottinghamWall.entity.Topic;
8 | import cn.yiming1234.NottinghamWall.result.PageResult;
9 | import com.aliyuncs.exceptions.ClientException;
10 |
11 | import java.io.IOException;
12 |
13 | public interface StudentService {
14 |
15 | /**
16 | * 微信登录
17 | * @param studentLoginDTO 学生登录信息
18 | */
19 | Student wxLogin(StudentLoginDTO studentLoginDTO);
20 |
21 | /**
22 | * 微信获取手机号
23 | * @param code 微信登录凭证
24 | */
25 | String getPhoneNumber(String code, Integer id) throws IOException;
26 |
27 | /**
28 | * 分页查询学生
29 | * @param pageQueryDTO 分页查询条件
30 | */
31 | PageResult pageQuery(PageQueryDTO pageQueryDTO);
32 |
33 | /**
34 | * 更新学生信息
35 | * @param studentDTO 学生信息
36 | */
37 | Student update(StudentDTO studentDTO) throws Exception;
38 |
39 | /**
40 | * 更新学生手机号
41 | * @param id 学生id
42 | */
43 | void updatePhoneNumber(Integer id, String phoneNumber);
44 |
45 | /**
46 | * 根据id查询学生
47 | * @param id 学生id
48 | */
49 | Student getById(Integer id) throws ClientException;
50 |
51 | /**
52 | * 根据用户名查询学生
53 | * @param username 用户名
54 | */
55 | Student getByUsername(String username);
56 |
57 | /**
58 | * 根据学号查询学生
59 | * @param studentId 学号
60 | */
61 | Student getByStudentId(Integer studentId);
62 |
63 | /**
64 | * 根据邮箱查询学生
65 | * @param email 邮箱
66 | */
67 | Student getByEmail(String email);
68 |
69 | /**
70 | * 查询发布的帖子(分页)
71 | * @param id 学生id
72 | * @param page 页码
73 | * @param pageSize 每页大小
74 | */
75 | PageResult getPublishedPosts(Integer id, int page, int pageSize);
76 |
77 | /**
78 | * 查询评论的帖子(分页)
79 | * @param id 学生id
80 | * @param page 页码
81 | * @param pageSize 每页大小
82 | */
83 | PageResult getCommentedPosts(Integer id, int page, int pageSize);
84 |
85 | /**
86 | * 查询收藏的帖子(分页)
87 | * @param id 学生id
88 | * @param page 页码
89 | * @param pageSize 每页大小
90 | */
91 | PageResult getCollectedPosts(Integer id, int page, int pageSize);
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/java/cn/yiming1234/NottinghamWall/service/TopicService.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.service;
2 |
3 | import cn.yiming1234.NottinghamWall.dto.TopicDTO;
4 | import cn.yiming1234.NottinghamWall.dto.PageQueryDTO;
5 | import cn.yiming1234.NottinghamWall.entity.Topic;
6 | import cn.yiming1234.NottinghamWall.result.PageResult;
7 |
8 | public interface TopicService {
9 |
10 | /**
11 | * 添加话题
12 | * @param topicDTO 话题DTO
13 | */
14 | void addTopic(TopicDTO topicDTO) throws Exception;
15 |
16 | /**
17 | * 删除话题
18 | * @param id 话题id
19 | */
20 | void deleteTopic(Integer id);
21 |
22 | /**
23 | * 新建草稿
24 | * @param topicDTO 话题DTO
25 | */
26 | void saveDraft(TopicDTO topicDTO);
27 |
28 | /**
29 | * 获取草稿
30 | * @param userId 用户id
31 | */
32 | Topic getDraft(Integer userId);
33 |
34 | /**
35 | * 删除草稿
36 | * @param id 话题id
37 | */
38 | void deleteDraft(Integer id);
39 |
40 | /**
41 | * 检查是否存在草稿
42 | * @param authorID 作者id
43 | */
44 | Boolean isExistDraft(Integer authorID);
45 |
46 | /**
47 | * 管理端分页查询话题
48 | */
49 | PageResult pageQuery(PageQueryDTO pageQueryDTO);
50 |
51 | /**
52 | * 用户端分页查询话题
53 | * @param pageQueryDTO 分页查询DTO
54 | */
55 | PageResult pageQuery(PageQueryDTO pageQueryDTO, Integer userId);
56 |
57 | /**
58 | * 根据id获取话题
59 | * @param id 话题id
60 | */
61 | Topic getTopicById(Integer id);
62 |
63 | /**
64 | * 根据id获取话题
65 | * @param id 话题id
66 | */
67 | Topic getTopicById(Integer id, Integer userId);
68 |
69 | /**
70 | * 点赞话题
71 | * @param id 话题id
72 | * @param userId 用户id
73 | */
74 | void likeTopic(Integer id, Integer userId);
75 |
76 | /**
77 | * 取消点赞话题
78 | * @param id 话题id
79 | * @param userId 用户id
80 | */
81 | void unlikeTopic(Integer id, Integer userId);
82 |
83 | /**
84 | * 收藏话题
85 | * @param id 话题id
86 | * @param userId 用户id
87 | */
88 | void collectTopic(Integer id, Integer userId);
89 |
90 | /**
91 | * 取消收藏话题
92 | * @param id 话题id
93 | * @param userId 用户id
94 | */
95 | void uncollectTopic(Integer id, Integer userId);
96 |
97 | // TODO 邮箱功能(获赞评论提醒)
98 | }
99 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/java/cn/yiming1234/NottinghamWall/service/impl/ReportServiceImpl.java:
--------------------------------------------------------------------------------
1 | package cn.yiming1234.NottinghamWall.service.impl;
2 |
3 | import cn.yiming1234.NottinghamWall.dto.ReportDTO;
4 | import cn.yiming1234.NottinghamWall.dto.PageQueryDTO;
5 | import cn.yiming1234.NottinghamWall.entity.Report;
6 | import cn.yiming1234.NottinghamWall.mapper.ReportMapper;
7 | import cn.yiming1234.NottinghamWall.mapper.TopicMapper;
8 | import cn.yiming1234.NottinghamWall.result.PageResult;
9 | import cn.yiming1234.NottinghamWall.service.ReportService;
10 | import com.github.pagehelper.Page;
11 | import com.github.pagehelper.PageHelper;
12 | import org.springframework.beans.factory.annotation.Autowired;
13 | import org.springframework.stereotype.Service;
14 |
15 | import java.time.LocalDateTime;
16 | import java.util.List;
17 |
18 | @Service
19 | public class ReportServiceImpl implements ReportService {
20 |
21 | private final ReportMapper reportMapper;
22 | private final TopicMapper topicMapper;
23 |
24 | @Autowired
25 | public ReportServiceImpl(ReportMapper reportMapper, TopicMapper topicMapper) {
26 | this.reportMapper = reportMapper;
27 | this.topicMapper = topicMapper;
28 | }
29 |
30 | /**
31 | * 举报
32 | * @param reportDTO 举报DTO
33 | */
34 | @Override
35 | public void insertReport(ReportDTO reportDTO) {
36 |
37 | int count = reportMapper.countExistingReports(reportDTO.getAuthorId(), reportDTO.getUserId(), reportDTO.getTopicId(), reportDTO.getCommentId());
38 | if (count > 0) {
39 | throw new IllegalArgumentException("已经举报过该内容");
40 | }
41 |
42 | Report report = new Report();
43 | report.setId(reportDTO.getId());
44 | report.setTopicId(reportDTO.getTopicId());
45 | report.setCommentId(reportDTO.getCommentId());
46 | Integer authorId = topicMapper.getTopicById(reportDTO.getTopicId()).getAuthorID();
47 | report.setAuthorId(authorId);
48 | report.setUserId(reportDTO.getUserId());
49 | report.setTags(reportDTO.getTags());
50 | report.setDetailedDescription(reportDTO.getDetailedDescription());
51 | report.setReportTime(LocalDateTime.now());
52 | reportMapper.insertReport(report);
53 |
54 | }
55 |
56 | /**
57 | * 分页查询举报
58 | * @param pageQueryDTO 分页查询DTO
59 | */
60 | @Override
61 | public PageResult pageQuery(PageQueryDTO pageQueryDTO) {
62 | PageHelper.startPage(pageQueryDTO.getPage(), pageQueryDTO.getPageSize());
63 | Page page = reportMapper.pageQuery(pageQueryDTO);
64 |
65 | long total = page.getTotal();
66 | List records = page.getResult();
67 | return new PageResult<>(total, records);
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/resources/application-template.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 8080
3 |
4 | spring:
5 | profiles:
6 | active: dev
7 | main:
8 | allow-circular-references: true
9 | mvc:
10 | pathmatch:
11 | matching-strategy: ant_path_matcher
12 | servlet:
13 | multipart:
14 | max-file-size: 10MB
15 | max-request-size: 10MB
16 | datasource:
17 | druid:
18 | driver-class-name: ${yiming1234.datasource.driver-class-name}
19 | url: jdbc:mysql://${yiming1234.datasource.host}:${yiming1234.datasource.port}/${yiming1234.datasource.database}?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
20 | username: ${yiming1234.datasource.username}
21 | password: ${yiming1234.datasource.password}
22 |
23 | mybatis:
24 | mapper-locations: classpath:mapper/*.xml
25 | type-aliases-package: cn.yiming1234.NottinghamWall.entity, cn.yiming1234.NottinghamWall.dto
26 | configuration:
27 | map-underscore-to-camel-case: true
28 |
29 | pagehelper:
30 | helper-dialect: mysql
31 | reasonable: true
32 | support-methods-arguments: true
33 | params: count=countSql
34 |
35 | redis:
36 | host: ${yiming1234.redis.host}
37 | port: ${yiming1234.redis.port}
38 | password: ${yiming1234.redis.password}
39 |
40 | logging:
41 | level:
42 | cn:
43 | yiming1234:
44 | mapper: debug
45 | service: info
46 | controller: info
47 |
48 | yiming1234:
49 | jwt:
50 | admin-secret-key: itcast
51 | admin-ttl: 7200000
52 | admin-token-name: token
53 | user-secret-key: yiming1234
54 | user-ttl: 7200000
55 | user-token-name: token
56 | alioss:
57 | endpoint: ${yiming1234.alioss.endpoint}
58 | access-key-id: ${yiming1234.alioss.access-key-id}
59 | access-key-secret: ${yiming1234.alioss.access-key-secret}
60 | bucket-name: ${yiming1234.alioss.bucket-name}
61 | wechat:
62 | appid: ${yiming1234.wechat.appid}
63 | secret: ${yiming1234.wechat.secret}
--------------------------------------------------------------------------------
/backend/wall-server/src/main/resources/mapper/AdminMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 | INSERT INTO admin (name, username, password, phone, sex, id_number, create_time, update_time, create_user, update_user)
8 | VALUES (#{name}, #{username}, #{password}, #{phone}, #{sex}, #{idNumber}, #{createTime}, #{updateTime}, #{createUser}, #{updateUser})
9 |
10 |
11 |
14 |
15 |
18 |
19 |
28 |
29 |
30 | update admin
31 |
32 | name = #{name},
33 | username = #{username},
34 | password = #{password},
35 | phone = #{phone},
36 | sex = #{sex},
37 | id_Number = #{idNumber},
38 | update_Time = #{updateTime},
39 | update_User = #{updateUser},
40 | status = #{status},
41 |
42 | where id = #{id}
43 |
44 |
45 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/resources/mapper/ReportMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 | INSERT INTO report (id, topic_id, comment_id, author_id, user_id, tags, detailed_description)
10 | VALUES (#{id}, #{topicId}, #{commentId}, #{authorId}, #{userId}, #{tags}, #{detailedDescription})
11 |
12 |
13 |
18 |
19 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/backend/wall-server/src/main/resources/mapper/StudentMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 | insert into student (openid, studentid, username, email, phone, sex, id_number, avatar, create_time, update_time)
7 | values (#{openid},#{studentid}, #{username}, #{email}, #{phone}, #{sex}, #{idNumber}, #{avatar}, #{createTime}, #{updateTime})
8 |
9 |
10 |
13 |
14 |
17 |
18 |
21 |
22 |
25 |
26 |
29 |
30 |
39 |
40 |
43 |
44 |
45 | UPDATE student
46 | SET
47 | username = #{username},
48 | avatar = #{avatar},
49 | sex = #{sex},
50 | phone = #{phone},
51 | studentid = #{studentid},
52 | update_time = #{updateTime}
53 | WHERE id = #{id}
54 |
55 |
56 |
--------------------------------------------------------------------------------
/docs/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/docs/.idea/.name:
--------------------------------------------------------------------------------
1 | index.md
--------------------------------------------------------------------------------
/docs/.idea/UniappTool.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/docs/.idea/docs.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/docs/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/docs/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/docs/.vitepress/config.js:
--------------------------------------------------------------------------------
1 | import sidebar from "./config/sidebar.js";
2 |
3 | export default {
4 | title: 'CPU Wall Wiki',
5 | description: 'Documentation for NottinghamWall',
6 | base: "/",
7 | themeConfig: {
8 | logo: "https://avatars.githubusercontent.com/u/178354211?s=200&v=4",
9 | nav: [
10 | { text: 'Home', link: '/' },
11 | { text: 'Guide', link: '/guide/' }
12 | ],
13 | sidebar: sidebar,
14 | search: {
15 | provider: 'local'
16 | },
17 | socialLinks: [
18 | { icon: 'github', link: 'https://github.com/CompPsyUnion/' }
19 | ],
20 | footer: {
21 | message: "MIT Licensed",
22 | copyright: "Copyright © 2024-present CompPsyUnion",
23 | },
24 | docFooter: {
25 | prev: "上一页",
26 | next: "下一页",
27 | },
28 | editLink: {
29 | text: "在 GitHub 上编辑此页",
30 | pattern:
31 | "https://github.com/CompPsyUnion/NottinghamWall/edit/main/docs/:path",
32 | },
33 | lastUpdated: {
34 | text: "最后更新于",
35 | formatOptions: {
36 | dateStyle: "short",
37 | timeStyle: "medium",
38 | },
39 | },
40 | }
41 | }
42 |
43 |
--------------------------------------------------------------------------------
/docs/.vitepress/config/env.js:
--------------------------------------------------------------------------------
1 | export default {
2 | repo: "CompPsyUnion/NottinghamWall",
3 | repoId: "R_kgDOMJfYsg",
4 | category: "General",
5 | categoryId: "DIC_kwDOMJfYss4Chgfj",
6 | };
--------------------------------------------------------------------------------
/docs/.vitepress/config/sidebar.js:
--------------------------------------------------------------------------------
1 | export default [
2 | {
3 | text: 'Guide',
4 | items: [
5 | { text: "Introduction", link: "/guide/" },
6 | { text: "Guide Overview", link: "/guide/overview" },
7 | { text: "Getting Started", link: "/guide/getting-started" },
8 | ],
9 | },
10 | {
11 | text: 'Backend',
12 | collapsible: true,
13 | collapsed: true,
14 | items: [
15 | { text: "项目概述", link: "/guide/backend/" },
16 | { text: "项目结构", link: "/guide/backend/project-structure" },
17 | { text: "API 设计", link: "/guide/backend/api-design" },
18 | { text: "数据库配置", link: "/guide/backend/database-setup" },
19 | { text: "项目部署", link: "/guide/backend/deployment" },
20 | ],
21 | },
22 | {
23 | text: 'Admin',
24 | collapsible: true,
25 | collapsed: true,
26 | items: [
27 | { text: "项目概述", link: "/guide/admin/" },
28 | { text: "项目结构", link: "/guide/admin/project-structure" },
29 | { text: "项目部署", link: "/guide/admin/deployment" },
30 | ],
31 | },
32 | {
33 | text: 'UniApp',
34 | collapsible: true,
35 | collapsed: true,
36 | items: [
37 | { text: "项目概述", link: "/guide/uniapp/" },
38 | { text: "项目结构", link: "/guide/uniapp/project-structure" },
39 | { text: "项目部署", link: "/guide/uniapp/deployment" },
40 | ],
41 | },
42 | ];
43 |
--------------------------------------------------------------------------------
/docs/.vitepress/theme/index.js:
--------------------------------------------------------------------------------
1 | import DefaultTheme from 'vitepress/theme'
2 | import Layout from "./layout.vue";
3 |
4 | export default {
5 | ...DefaultTheme,
6 | Layout,
7 | async enhanceApp(ctx) {
8 | // extend default theme custom behaviour.
9 | DefaultTheme.enhanceApp(ctx);
10 | // register your custom global components
11 | },
12 | }
--------------------------------------------------------------------------------
/docs/.vitepress/theme/layout.vue:
--------------------------------------------------------------------------------
1 |
34 |
35 |
36 |
37 |
38 |
39 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/docs/CNAME:
--------------------------------------------------------------------------------
1 | wallwiki.yiming1234.cn
--------------------------------------------------------------------------------
/docs/about.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: doc
3 | sidebar: false
4 | ---
5 |
6 | # About Us / 关于我们
7 |
8 | 👋 你好,我们是宁波诺丁汉大学计算机爱好者协会!
9 | 👋 Hi, we are Computer Psychologist Union of UNNC!
10 |
11 | ## GitHub Organization / GitHub 组织
12 |
13 | 我们在 GitHub 上的组织信息:
14 | Below are some statistics about our GitHub organization:
15 |
16 |
21 |
22 | ## On-site Activities / 校内活动
23 |
24 | - 技术分享交流会 Tech Sharing Seminar
25 | Open to all CS Students, [CLICK HERE](https://forms.office.com/r/iU3z5BhiBf) to subcribe the information(UNNC Account required).
26 | ⚠️Tips: Seminars will be given in Chinese.
27 | 面向所有计算机系学生开放,[点击此处](https://forms.office.com/r/iU3z5BhiBf)订阅我们的邮件通知。
28 |
29 | - CS学生大讲堂 CS Student Public Lecture
30 | For Year 1 Gaokao Student, there will be 2 blue SPDPO credit. 对于大一年级学生将会有2蓝色SPDPO学分。
31 |
32 | - 趣味编程大赛(程序设计比赛) Programming Competition
33 | For Year 1 Gaokao Student, there will be SPDPO credits. 对于大一年级学生将会有SPDPO学分。
34 |
35 | - 趣味CTF网安竞赛 CTF Competition
36 | For Year 1 Gaokao Student, there will be SPDPO credits. 对于大一年级学生将会有SPDPO学分。
37 |
38 | - LEGO EV3 机器人活动 LEGO EV3 robotics activities
39 | For Year 1 Gaokao Student, there will be SPDPO credits. 对于大一年级学生将会有SPDPO学分。
40 |
41 | ## Join us / 加入我们
42 |
43 | If you’re a student in UNNC, welcome to join us!
44 | 如果你是一个宁诺学生,对我们的内容感兴趣,欢迎加入我们!
45 |
46 | **How to apply? 如何申请加入?**
47 |
48 | -- 在我们在每学年开始会提供统一的网申通道和面试机会。平常日期,请发送您的资料到我们的邮箱computerpsychounion@nottingham.edu.cn,我们会酌情考虑你是否适合加入我们!
49 |
50 | -- We provide a online application form and interview opportunities at the beginning of each academic year (Chance for AY2425 is ending). On normal dates, please send your information to our email address computerpsychounion@nottingham.edu.cn and we will consider whether you are suitable to join us!
51 |
52 | ## Contact Us / 联系我们
53 |
54 | - 📮 Email: computerpsychounion@nottingham.edu.cn
55 | - 📱 WeChat Official Account: 宁诺CPU
56 | - 💬 Official Website: [CPU](https://comppsyunion.github.io/.github/)
57 | - 📌 CPU_Tech_Forum: [CPU_Tech_Forum](https://comppsyunion.github.io/CPU_Tech_Forum/)
58 |
--------------------------------------------------------------------------------
/docs/guide/admin/deployment.md:
--------------------------------------------------------------------------------
1 | # 项目部署
2 |
3 | ## 部署方案
4 |
5 | 1. **构建生产包**
6 | - 运行以下命令生成生产环境文件:
7 | ```bash
8 | pnpm run build
9 | ```
10 | - 打包文件输出至 `dist/` 目录。
11 |
12 | 2. **部署到服务器**
13 | - 使用 Nginx 部署:
14 | - 将 `dist/` 内容上传至服务器。
15 | - 配置 Nginx:
16 | ```nginx
17 | server {
18 | listen 80;
19 | server_name yourdomain.com;
20 |
21 | location / {
22 | root /path/to/dist;
23 | index index.html;
24 | try_files $uri $uri/ /index.html;
25 | }
26 | }
27 | ```
28 | - 验证部署成功后,通过浏览器访问域名。
29 |
30 | 3. **注意事项**
31 | - 配置 `.env.production` 确保环境变量正确。
32 | - 检查生产环境 API 接口和跨域配置。
--------------------------------------------------------------------------------
/docs/guide/admin/index.md:
--------------------------------------------------------------------------------
1 | # Admin Overview
2 |
3 | ## 项目概述
4 |
5 | 本项目是基于 **Vue 3** 框架开发的后端管理面板,采用模块化设计思想,具备良好的扩展性和维护性。
6 |
7 | 该系统包含用户管理、学生管理、公告管理、话题管理等核心功能,通过简洁清晰的界面和高效的 API 调用,帮助管理员实现快速高效的后台操作。
8 |
9 | ## 开发环境配置
10 |
11 | 1. **必备工具**
12 | - Node.js:`>=16.0.0`
13 | - 包管理工具:pnpm
14 | - IDE:WebStorm 或 VSCode(推荐安装 `Vetur`、`Prettier` 插件)。
15 |
16 | 2. **环境变量**
17 | - `.env.development`:开发环境变量配置。
18 | - `.env.production`:生产环境变量配置。
19 |
20 | 3. **安装依赖**
21 | ```bash
22 | pnpm install
23 | ```
24 |
25 | 4. **开发启动**
26 | ```bash
27 | pnpm run dev
28 | ```
29 |
30 | 5. **构建生产包**
31 | ```bash
32 | pnpm run build
33 | ```
34 |
35 | 6. **代码规范**
36 | - 配置文件:`.eslintrc.cjs`
37 | - Lint 检查:
38 | ```bash
39 | pnpm run lint
40 | ```
41 |
42 | ## 技术栈
43 |
44 | 1. **前端框架**
45 | - Vue 3:现代化渐进式 JavaScript 框架,用于构建用户界面。
46 | - Vite:快速构建工具,提供高效的开发体验和优化的生产构建。
47 |
48 | 2. **状态管理**
49 | - Pinia(可扩展为 Vuex):集中式状态管理,处理全局状态,如用户 token 和权限。
50 |
51 | 3. **路由管理**
52 | - Vue Router:负责页面的动态导航和权限管理。
53 |
54 | 4. **请求工具**
55 | - Axios:用于封装 HTTP 请求,结合 `request.js` 和 `requestOptimize.js` 提供统一的请求和响应拦截。
56 |
57 | 5. **样式与 UI**
58 | - CSS + SCSS:灵活的样式支持,主样式入口为 `assets/main.scss`。
59 | - Icon:内置的 `logo` 图标集,满足各种场景需求。
--------------------------------------------------------------------------------
/docs/guide/admin/project-structure.md:
--------------------------------------------------------------------------------
1 | # 项目结构
2 |
3 | ## 目录结构分析
4 |
5 | 1. **根目录**
6 | - `vite.config.js`:配置开发工具,包含路径别名、代理服务等。
7 | - `package.json`:项目依赖和脚本配置。
8 | - `index.html`:项目入口文件。
9 | - `.env.*`:存放环境变量配置。
10 |
11 | 2. **`src` 目录**
12 | - **核心文件**
13 | - `App.vue`:应用根组件,负责布局和全局配置。
14 | - `main.js`:应用入口,挂载全局组件和插件。
15 | - **页面文件**
16 | - `views/`:功能模块页面,包括 `Dashboard.vue`(首页概览)、`Login.vue`(登录页)、`admin`(管理员管理)、`student`(学生管理)、`topic`(主题管理)等。
17 | - **组件**
18 | - `components/`: 存放可复用组件,如 `HelloWorld.vue`。
19 | - **路由**
20 | - `router/index.js`:定义路由规则,支持路由懒加载和权限控制。
21 | - **状态管理**
22 | - `store/`: 使用 Pinia/Vuex 管理全局状态,如用户登录状态和权限。
23 | - **工具类**
24 | - `utils/request.js`:封装 API 请求,统一处理异常与响应数据。
25 | - `utils/requestOptimize.js`:对请求进行进一步优化。
26 | - **静态资源**
27 | - `assets/`: 样式和图片资源,按功能模块分类存放。
28 |
29 | 3. **`public` 目录**
30 | - `favicon.ico`:应用图标。
31 | - 可存放公共资源,生产环境会直接复制到根目录。
32 |
33 | ## 功能模块说明
34 |
35 | 1. **登录与认证**
36 | - 用户通过登录页面输入账号密码,验证成功后跳转至管理面板。
37 | - 使用 token 实现会话管理,状态存储于 Pinia。
38 |
39 | 2. **仪表盘**
40 | - 在 `Dashboard.vue` 展示系统概览、统计数据和快速入口。
41 |
42 | 3. **模块管理**
43 | - 管理员模块:添加、编辑、删除管理员。
44 | - 学生模块:查看、搜索、管理学生信息。
45 | - 公告模块:发布、管理公告。
46 | - 主题模块:创建、编辑、查看主题内容。
47 |
48 | 4. **权限控制**
49 | - 路由守卫根据用户权限动态加载功能模块。
--------------------------------------------------------------------------------
/docs/guide/backend/deployment.md:
--------------------------------------------------------------------------------
1 | # 项目部署
2 |
3 | ## 环境配置
4 |
5 | 1. 安装 JDK:确保已安装 JDK 1.8 或以上版本,并配置好 JAVA_HOME 环境变量。
6 |
7 | 2. 安装 Maven:下载并安装 Maven,配置 MAVEN_HOME 环境变量。
8 |
9 | 3. 安装 MySQL:安装 MySQL 数据库,并创建项目所需的数据库。
10 |
11 | - 数据库所需文件在仓库根目录下的 `nottinghamwall.sql` 中
12 |
13 | 4. 安装 Redis:安装并启动 Redis 服务。
14 |
15 | 5. 配置阿里云 OSS:在阿里云控制台获取访问密钥,并创建存储空间。
16 |
17 | 6. 配置文件修改
18 |
19 | - 进入 `wall-server/src/main/resources` 目录,根据环境修改以下配置文件:
20 |
21 | **数据库配置**(`application.yml`):
22 |
23 | ```yaml
24 | spring:
25 | datasource:
26 | url: jdbc:mysql://localhost:3306/your_database_name?useSSL=false&useUnicode=true&characterEncoding=UTF-8
27 | username: your_username
28 | password: your_password
29 | ```
30 |
31 | **Redis 配置**:
32 |
33 | ```yaml
34 | spring:
35 | redis:
36 | host: localhost
37 | port: 6379
38 | ```
39 |
40 | **阿里云 OSS 配置**(`application.yml` 或自定义配置文件):
41 |
42 | ```yaml
43 | oss:
44 | endpoint: your_oss_endpoint
45 | accessKeyId: your_access_key_id
46 | accessKeySecret: your_access_key_secret
47 | bucketName: your_bucket_name
48 | ```
49 |
50 | **JWT 配置**:
51 |
52 | ```yaml
53 | jwt:
54 | secret: your_jwt_secret
55 | expiration: token_expiration_time_in_seconds
56 | ```
57 |
58 | ## 构建与运行
59 |
60 | 1. **使用 Maven 构建项目**:
61 |
62 | 在项目根目录下执行下面的命令来安装该部分所需的依赖,
63 |
64 | 或者点击IDEA右侧栏中`maven`生命周期中的install选项
65 |
66 | ```bash
67 | mvn clean install
68 | ```
69 |
70 | 2. **运行项目**:
71 |
72 | - **方法一**:使用 IDE(如 IntelliJ IDEA)运行 `WallApplication` 的 `main` 方法。
73 | - **方法二**:在终端中运行打包后的 JAR 文件:
74 |
75 | ```bash
76 | cd wall-server/target
77 | java -jar wall-server-1.0-SNAPSHOT.jar
78 | ```
--------------------------------------------------------------------------------
/docs/guide/backend/index.md:
--------------------------------------------------------------------------------
1 | # Backend Overview
2 |
3 | ## 项目概述
4 |
5 | 本项目是一个基于 Java 的 Web 应用程序,旨在构建一个 NottinghamWall 平台,为用户提供交流和互动的空间。
6 |
7 | 该部分采用多模块的 Maven 项目结构,包括 wall-common、wall-pojo 和 wall-server 三个主要模块。
8 |
9 | ## 开发环境(本人使用)
10 |
11 | * 操作系统:Windows、macOS 或 Linux。
12 | * JDK:17 或以上版本。
13 | * 数据库:MySQL 8.0 或以上版本。
14 | * 缓存:Redis 5.0 或以上版本。
15 | * 构建工具:Maven 3.6 或以上版本。
16 |
17 | ## 技术栈
18 |
19 | ### 后端技术:
20 |
21 | * Spring Boot:用于构建独立运行的 Spring 应用程序。
22 | * MyBatis:持久层框架,简化数据库操作。
23 | * Redis:用于缓存和会话管理。
24 | * 阿里云 OSS:用于文件存储和管理,以及**图片内容安全**的识别。
25 | * JWT(JSON Web Token):用于实现安全的用户身份认证。
26 | * Lombok:简化实体类的编写。
27 |
28 | ### 数据库:
29 |
30 | * MySQL:关系型数据库,用于存储核心业务数据。
31 |
32 | ### 其他:
33 |
34 | * Maven:项目管理和构建工具。
35 | * Git:版本控制系统。
--------------------------------------------------------------------------------
/docs/guide/backend/project-structure.md:
--------------------------------------------------------------------------------
1 | # 项目结构
2 |
3 | ```
4 | 项目根目录
5 | ├── pom.xml // 父项目的 Maven 配置文件
6 | ├── README.md // 项目说明文件
7 | ├── wall-common // 公共模块
8 | │ ├── pom.xml
9 | │ └── src
10 | │ └── main/java/cn/yiming1234/NottinghamWall
11 | │ ├── constant // 常量类
12 | │ ├── context // 上下文处理
13 | │ ├── enumeration // 枚举类型
14 | │ ├── exception // 自定义异常
15 | │ ├── json // JSON 处理
16 | │ ├── properties // 配置属性类
17 | │ ├── result // 统一返回结果封装
18 | │ └── utils // 工具类
19 | ├── wall-pojo // 实体类模块
20 | │ ├── pom.xml
21 | │ └── src
22 | │ └── main/java/cn/yiming1234/NottinghamWall
23 | │ ├── dto // 数据传输对象
24 | │ ├── entity // 实体类
25 | │ ├── typehandler // 类型处理器
26 | │ └── vo // 视图对象
27 | └── wall-server // 服务模块
28 | ├── pom.xml
29 | └── src
30 | ├── main/java/cn/yiming1234/NottinghamWall
31 | │ ├── WallApplication.java // 启动类
32 | │ ├── annotation // 自定义注解
33 | │ ├── aspect // 切面编程
34 | │ ├── config // 配置类
35 | │ ├── controller // 控制层
36 | │ │ ├── admin // 管理员相关接口
37 | │ │ └── student // 学生相关接口
38 | │ ├── handler // 全局异常处理
39 | │ ├── interceptor // 拦截器
40 | │ ├── mapper // 数据访问层
41 | │ └── service // 业务逻辑层
42 | └── main/resources
43 | ├── application.yml // 主配置文件
44 | ├── application-dev.yml // 开发环境配置文件
45 | ├── application-prod.yml // 生产环境配置文件
46 | └── mapper // MyBatis 映射文件
47 |
48 | ```
--------------------------------------------------------------------------------
/docs/guide/getting-started.md:
--------------------------------------------------------------------------------
1 | # 相关链接
2 |
3 | * [项目小程序端](https://github.com/NottinghamWall/NottinghamWall/tree/main/uniapp)
4 |
5 | * [项目后台管理端](https://github.com/NottinghamWall/NottinghamWall/tree/main/admin)
6 |
7 | * [项目服务器端](https://github.com/NottinghamWall/NottinghamWall/tree/main/backend)
8 |
9 | * [项目接口文档](https://apifox.com/apidoc/shared-4f188e54-2808-4958-9fd1-8acbb4c4072c)
10 |
11 |
12 | 特别说明:接口文档中Header参数部分使用的token为每次登录时生成的JWT令牌,无默认有效值。
13 |
14 | 管理端默认用户名:Pleasure1234 密码:123456
15 |
16 | 由于写入数据库时进行了md5编码,导入sql文件时应在admin数据表中添加 Pleasure1234 e10adc3949ba59abbe56e057f20f883e 1
17 |
18 | 开发者需自行在数据库中进行添加编辑
19 |
20 | # 相关功能及技术栈
21 |
22 | ## 简单介绍
23 |
24 | * NottinghamWall-backend主要使用SpringBoot进行编写,同时运用MySQL,MyBatis等工具。
25 |
26 | * NottinghamWall-Admin主要使用Vue3进行编写,搭配Element-plus组件库来实现页面效果,同时运用Vite项目管理器以及pnpm包管理工具。
27 |
28 | * NottinghamWall-uniapp主要用uniapp进行编写,搭配uni-ui组件库来实现页面效果。
29 |
30 | P.S. 特别说明
31 |
32 | 1. 简介中提到的工具,如果是在开发环境中,需要自行提前安装,暂未尝试针对其他构建工具的适配。由于笔者能力有限,一些关于自动化测试部分的内容创建但没有书写。采用的是最朴素的日志,接口工具以及前后端联调等方式进行的测试。
33 |
34 | 2. 小程序端由于资质认证备案以及上线比较困难,所以部分功能的测试是在**小程序测试号**中进行。
35 |
36 | 3. 微信官方为了防止相关接口的滥用,需要在小程序测试号中配置合法的服务器域名,如果不想将NottinghamWall-backend上传至服务器,可以选择将本地启动的服务器端进行内网穿透,填写在合法域名栏中,推荐CPOLAR。
37 |
38 | ## 技术栈相关知识
39 |
40 | 如果你对相关的技术还不熟悉,可以前往我的博客看看整理的相关文章。就不在这里过多赘述占据篇幅了。
41 |
42 | 
43 |
44 | * [前置知识专栏](https://blog.csdn.net/2302_79791164/category_12589142.html)
45 |
46 | * [前后端的比较](https://yiming1234.blog.csdn.net/article/details/136700267)
47 |
48 | * [Vue前置知识](https://yiming1234.blog.csdn.net/article/details/136977577)
49 |
50 | * [前端专有名词介绍](https://yiming1234.blog.csdn.net/article/details/140828434)
51 |
52 | * [SpringBoot中一些常见的技术](https://yiming1234.blog.csdn.net/article/details/138284767)
53 |
54 | * [SpringBoot常见目录的作用](https://yiming1234.blog.csdn.net/article/details/138380736)
--------------------------------------------------------------------------------
/docs/guide/index.md:
--------------------------------------------------------------------------------
1 | # CPU Wall
2 |
3 | Welcome to the CPU Wall wiki!
4 |
5 | You can visit the website to see it.
6 |
7 | There is no English version at present.
8 |
--------------------------------------------------------------------------------
/docs/guide/overview.md:
--------------------------------------------------------------------------------
1 | # 项目介绍
2 |
3 | 由23届 `CSAI`(2+2)的Pleasure1234开发,`xuanzhi33`提供技术指导,于2024年6月15日建立
4 |
5 | V1.0版本现已上线微信小程序,搜索`CPU Wall`即可访问使用
6 |
7 | V1.0版本仅包含作为一个社交论坛小程序最基本的功能
8 |
9 | 此项目属于**个人项目**,目前仍在对版本功能进行不断更新,Wiki以及ReadeMe仍在完善中
10 |
11 | 如果您想加入我,可以在Discussion中告诉我。
12 |
13 | # 效果展示
14 |
15 | ## 小程序端
16 |
17 | 
18 |
19 | 
20 |
21 | ## 管理端
22 |
23 | 
24 |
25 | 
--------------------------------------------------------------------------------
/docs/guide/uniapp/deployment.md:
--------------------------------------------------------------------------------
1 | # 项目部署
2 |
3 | ## 执行步骤
4 |
5 | 1. **启动开发环境**
6 | - 微信小程序开发:
7 | ```bash
8 | pnpm run dev:mp-weixin
9 | ```
10 |
11 | 2. **生产构建**
12 | - 在`mianfest.json`中,绑定对应的 AppID
13 | - 微信小程序生产环境编译构建:
14 | ```bash
15 | pnpm run build:mp-weixin
16 | ```
17 | 3. **微信小程序部署**
18 | - 构建输出到 `dist/dev/mp-weixin` 文件夹。
19 | - 导入微信开发者工具并上传代码。
--------------------------------------------------------------------------------
/docs/guide/uniapp/index.md:
--------------------------------------------------------------------------------
1 | # Uniapp Overview
2 |
3 | ## 项目概述
4 |
5 | 本项目采用 **Uniapp** 框架进行开发,主要编译成微信小程序,具有模块化结构、清晰的代码组织及高扩展性。
6 | 目录结构包含必要的配置文件、页面组件、静态资源以及工具类文件,支持多端高效开发和维护。
7 |
8 | ## 开发环境
9 |
10 | 1. **必备工具**
11 | - IDE: HBuilderX(推荐)、WebStorm 或 VSCode。
12 | - Node.js 版本:`>=16.0.0`
13 | - 包管理工具:pnpm
14 |
15 | 2. **安装依赖**
16 | ```bash
17 | pnpm install
18 | ```
19 |
20 | 3. **启动开发环境**
21 | - 微信小程序开发:
22 | ```bash
23 | pnpm run dev:mp-weixin
24 | ```
25 |
26 | 4. **生产构建**
27 | - 微信小程序生产环境构建:
28 | ```bash
29 | pnpm run build:mp-weixin
30 | ```
31 |
32 | ## 技术栈
33 |
34 | 1. **框架与语言**
35 | - 开发框架:Uniapp
36 | - 核心语言:JavaScript (ES6+) / TypeScript (可选)
37 |
38 | 2. **构建工具**
39 | - Vite:提供快速、轻量的构建环境。
40 | - pnpm:高效的依赖管理工具。
41 |
42 | 3. **UI 组件**
43 | - 使用 `@dcloudio/uni-ui` 提供的组件(如 `uni-card`、`uni-icons` 等),实现一致的 UI 体验。
44 |
45 | 4. **后端接口**
46 |
47 | - 见`backend`部分
48 |
49 | 5. **多端兼容**
50 | - 主要兼容微信小程序,通过配置 `manifest.json` 和 `pages.json` 定义应用入口与页面结构。
51 |
52 |
--------------------------------------------------------------------------------
/docs/guide/uniapp/project-structure.md:
--------------------------------------------------------------------------------
1 | # 项目结构
2 |
3 | 1. **核心文件**
4 | - `index.html`:H5 项目的主入口。
5 | - `vite.config.js`:Vite 的配置文件。
6 | - `manifest.json`:项目多端打包配置文件。
7 | - `pages.json`:应用页面及路由配置。
8 | - `App.vue`:全局页面布局。
9 |
10 | 2. **业务模块**
11 | - `src/pages`:存放应用的业务逻辑页面,按功能划分子文件夹(如 `favorites`、`order`)。
12 | - `src/api`:封装所有接口请求逻辑,模块化处理。
13 |
14 | 3. **UI 组件**
15 | - `src/pages/index/components`:存放业务相关的自定义组件(如 `fab.vue`、`swipper.vue`)。
16 |
17 | 4. **静态资源**
18 | - `src/static`:存放图片、图标等静态资源。
19 | - 按功能划分文件夹(如 `carousel`、`icon`、`logo`)。
20 |
21 | 5. **工具类**
22 | - `src/utils/env.js`:存放环境变量配置。
23 | - `src/utils/request.js`:封装 Axios 网络请求。
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: home
3 | title: 主页
4 | hero:
5 | name: "CPU Wall Wiki Docs"
6 | text: "CPU Wall 项目文档"
7 | tagline: 一个由宁诺计算机爱好者协会维护的项目
8 | actions:
9 | - theme: brand
10 | text: 指南
11 | link: /guide/
12 | - theme: alt
13 | text: 关于我们
14 | link: /about
15 |
16 | features:
17 | - title: 对于CPU成员
18 | details: A opportunity for communication what you know and show yourself to others.
19 | - title: 对于零基础的CS学生
20 | details: Learn more CS major knowledge in our event. Improve your Computer Science Studying.
21 | - title: 线上和线下
22 | details: Bi-weekly on-site events in UNNC Campus, and live & recording meetings available on MSTeams.
23 | ---
24 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nottinghamwall_docs",
3 | "version": "1.0.0",
4 | "description": "Docs of NottinghamWall",
5 | "main": "index.js",
6 | "directories": {
7 | "doc": "docs"
8 | },
9 | "scripts": {
10 | "docs:dev": "vitepress dev docs",
11 | "docs:build": "vitepress build docs",
12 | "docs:serve": "vitepress serve docs"
13 | },
14 | "repository": {
15 | "type": "git",
16 | "url": "git+https://github.com/CompPsyUnion/NottinghamWall.git"
17 | },
18 | "author": "Computer Psycho Union",
19 | "license": "MIT",
20 | "bugs": {
21 | "url": "https://github.com/CompPsyUnion/NottinghamWall/issues"
22 | },
23 | "homepage": "https://github.com/CompPsyUnion/NottinghamWall#readme",
24 | "dependencies": {
25 | "@giscus/vue": "^3.0.0",
26 | "radix-vue": "^1.9.8",
27 | "vitepress": "^1.5.0",
28 | "vue": "^3.5.12"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/uniapp/.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 | *.local
14 |
15 | # Editor directories and files
16 | .idea
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | *.sw?
22 |
--------------------------------------------------------------------------------
/uniapp/.hbuilderx/launch.json:
--------------------------------------------------------------------------------
1 | { // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
2 | // launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数
3 | "version": "0.0",
4 | "configurations": [{
5 | "default" :
6 | {
7 | "launchtype" : "local"
8 | },
9 | "mp-weixin" :
10 | {
11 | "launchtype" : "local"
12 | },
13 | "type" : "uniCloud"
14 | }
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/uniapp/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/uniapp/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": ".",
4 | "paths": {
5 | "@/*": ["src/*"]
6 | }
7 | },
8 | "include": [
9 | "src/**/*.vue",
10 | "src/**/*.js",
11 | "src/**/*"
12 | ],
13 | "exclude": [
14 | "node_modules",
15 | "dist",
16 | "test"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/uniapp/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "uni-preset-vue",
3 | "version": "0.0.0",
4 | "scripts": {
5 | "dev:mp-weixin": "uni -p mp-weixin",
6 | "build:mp-weixin": "uni build -p mp-weixin",
7 | "serve:mp-weixin": "uni serve -p mp-weixin"
8 | },
9 | "dependencies": {
10 | "@dcloudio/uni-app": "3.0.0-4040520250104002",
11 | "@dcloudio/uni-app-harmony": "3.0.0-4040520250104002",
12 | "@dcloudio/uni-app-plus": "3.0.0-4040520250104002",
13 | "@dcloudio/uni-components": "3.0.0-4040520250104002",
14 | "@dcloudio/uni-h5": "3.0.0-4040520250104002",
15 | "@dcloudio/uni-mp-alipay": "3.0.0-4040520250104002",
16 | "@dcloudio/uni-mp-baidu": "3.0.0-4040520250104002",
17 | "@dcloudio/uni-mp-jd": "3.0.0-4040520250104002",
18 | "@dcloudio/uni-mp-kuaishou": "3.0.0-4040520250104002",
19 | "@dcloudio/uni-mp-lark": "3.0.0-4040520250104002",
20 | "@dcloudio/uni-mp-qq": "3.0.0-4040520250104002",
21 | "@dcloudio/uni-mp-toutiao": "3.0.0-4040520250104002",
22 | "@dcloudio/uni-mp-weixin": "3.0.0-4040520250104002",
23 | "@dcloudio/uni-mp-xhs": "3.0.0-4040520250104002",
24 | "@dcloudio/uni-quickapp-webview": "3.0.0-4040520250104002",
25 | "@dcloudio/uni-ui": "^1.5.7",
26 | "axios": "1.7.4",
27 | "element-plus": "^2.8.7",
28 | "pinia": "^2.2.1",
29 | "pinia-persistedstate-plugin": "^0.1.0",
30 | "vue": "^3.4.37",
31 | "vue-i18n": "^9.13.1"
32 | },
33 | "devDependencies": {
34 | "@dcloudio/types": "^3.4.12",
35 | "@dcloudio/uni-automator": "3.0.0-4040520250104002",
36 | "@dcloudio/uni-cli-shared": "3.0.0-4040520250104002",
37 | "@dcloudio/uni-stacktracey": "3.0.0-4040520250104002",
38 | "@dcloudio/vite-plugin-uni": "3.0.0-4040520250104002",
39 | "@vue/runtime-core": "^3.4.37",
40 | "sass": "^1.77.8",
41 | "sass-loader": "10.1.1",
42 | "vite": "5.2.8"
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/uniapp/shims-uni.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | import 'vue'
3 |
4 | declare module '@vue/runtime-core' {
5 | type Hooks = App.AppInstance & Page.PageInstance;
6 |
7 | interface ComponentCustomOptions extends Hooks {
8 |
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/uniapp/src/App.vue:
--------------------------------------------------------------------------------
1 |
15 |
16 |
19 |
--------------------------------------------------------------------------------
/uniapp/src/api/collect.js:
--------------------------------------------------------------------------------
1 | import { baseUrl } from "@/utils/env";
2 |
3 | /**
4 | * 获取用户收藏的话题
5 | */
6 | export const fetchCollectedTopics = (page = 1, pageSize = 5) => {
7 | return new Promise((resolve, reject) => {
8 | uni.request({
9 | url: `${baseUrl}/student/get/collect?page=${page}&pageSize=${pageSize}`,
10 | method: 'GET',
11 | header: {
12 | 'Content-Type': 'application/json',
13 | 'token': uni.getStorageSync('token')
14 | },
15 | success: (res) => {
16 | if (res.data.code === 1) {
17 | resolve(res.data.data);
18 | console.log('获取收藏话题成功', res.data.data);
19 | } else {
20 | reject(new Error('获取收藏话题失败'));
21 | }
22 | },
23 | fail: (err) => reject(err)
24 | });
25 | });
26 | };
27 |
28 | /**
29 | * 收藏话题
30 | */
31 | export const collectTopic = (topicId) => {
32 | return new Promise((resolve, reject) => {
33 | uni.request({
34 | url: `${baseUrl}/student/collect/topic/${topicId}`,
35 | method: 'POST',
36 | header: {
37 | 'Content-Type': 'application/json',
38 | 'token': uni.getStorageSync('token'),
39 | },
40 | success: (res) => {
41 | if (res.data.code === 1) {
42 | resolve(res.data.msg);
43 | } else {
44 | reject(res.data.msg || '收藏失败');
45 | }
46 | },
47 | fail: (err) => reject(err),
48 | });
49 | });
50 | };
51 |
52 | /**
53 | * 取消收藏话题
54 | */
55 | export const uncollectTopic = (topicId) => {
56 | return new Promise((resolve, reject) => {
57 | uni.request({
58 | url: `${baseUrl}/student/uncollect/topic/${topicId}`,
59 | method: 'POST',
60 | header: {
61 | 'Content-Type': 'application/json',
62 | 'token': uni.getStorageSync('token'),
63 | },
64 | success: (res) => {
65 | if (res.data.code === 1) {
66 | resolve(res.data.msg);
67 | } else {
68 | reject(res.data.msg || '取消收藏失败');
69 | }
70 | },
71 | fail: (err) => reject(err),
72 | });
73 | });
74 | };
75 |
--------------------------------------------------------------------------------
/uniapp/src/api/getPhone.js:
--------------------------------------------------------------------------------
1 | import {baseUrl} from "@/utils/env";
2 |
3 | /**
4 | * 获取用户手机号
5 | */
6 | export const userGetPhoneService = (code) => {
7 | console.log('Request initiated');
8 | console.log(code);
9 | return new Promise(() => {
10 | uni.request({
11 | url: `${baseUrl}/student/login/getPhoneNumber?code=${code.code}`,
12 | method: 'POST',
13 | header: {
14 | 'Content-Type': 'application/json',
15 | 'token': uni.getStorageSync('token')
16 | },
17 | success: function (res) {
18 | if (res.statusCode === 200) {
19 | console.log('请求成功:', res.data);
20 | return res.data.phone;
21 | } else {
22 | console.error('请求失败,状态码:', res.statusCode);
23 | }
24 | },
25 | });
26 | })
27 | }
28 |
--------------------------------------------------------------------------------
/uniapp/src/api/like.js:
--------------------------------------------------------------------------------
1 | import { baseUrl } from "@/utils/env";
2 |
3 | /**
4 | * 点赞话题
5 | */
6 | export const likeTopic = (topicId) => {
7 | return new Promise((resolve, reject) => {
8 | uni.request({
9 | url: `${baseUrl}/student/like/topic/${topicId}`,
10 | method: 'POST',
11 | header: {
12 | 'Content-Type': 'application/json',
13 | 'token': uni.getStorageSync('token'),
14 | },
15 | success: (res) => {
16 | if (res.data.code === 1) {
17 | resolve(res.data.msg);
18 | } else {
19 | reject(res.data.msg || '点赞失败');
20 | }
21 | },
22 | fail: (err) => reject(err),
23 | });
24 | });
25 | };
26 |
27 | /**
28 | * 取消点赞话题
29 | */
30 | export const unlikeTopic = (topicId) => {
31 | return new Promise((resolve, reject) => {
32 | uni.request({
33 | url: `${baseUrl}/student/unlike/topic/${topicId}`,
34 | method: 'POST',
35 | header: {
36 | 'Content-Type': 'application/json',
37 | 'token': uni.getStorageSync('token'),
38 | },
39 | success: (res) => {
40 | if (res.data.code === 1) {
41 | resolve(res.data.msg);
42 | } else {
43 | reject(res.data.msg || '取消点赞失败');
44 | }
45 | },
46 | fail: (err) => reject(err),
47 | });
48 | });
49 | };
50 |
--------------------------------------------------------------------------------
/uniapp/src/api/login.js:
--------------------------------------------------------------------------------
1 | import {baseUrl} from "@/utils/env";
2 |
3 | /**
4 | * token校验与续签
5 | */
6 | // TODO 当前token失效采用每次登录清除上次token的方式,后续可考虑使用refreshToken
7 | export const checkTokenService = () => {
8 | return new Promise(() => {
9 | uni.request({
10 | url: baseUrl + '/student/login/checkToken',
11 | method: 'POST',
12 | header: {
13 | 'Content-Type': 'application/json',
14 | 'token': uni.getStorageSync('token')
15 | },
16 | success: function (res) {
17 | if (res.statusCode === 200) {
18 | console.log('token is valid', res.data);
19 | console.log('-=-=-=-=checkTokenRes-=-=-=');
20 | } else if (res.data.newToken) {
21 | console.log('token已续签:', res.data.newToken);
22 | uni.setStorageSync('token', res.data.newToken);
23 | }
24 | },
25 | fail: function (error) {
26 | console.error('请求失败:', error);
27 | }
28 | });
29 |
30 | })
31 | }
32 |
33 | /**
34 | * 用户登录
35 | */
36 | export const userLoginService = (LoginData) => {
37 | return new Promise(() => {
38 | uni.request({
39 | url: baseUrl + '/student/login/login',
40 | method: 'POST',
41 | header: {
42 | 'Content-Type': 'application/json'
43 | },
44 | data: JSON.stringify(LoginData),
45 | success: function (res) {
46 | if (res.statusCode === 200) {
47 | console.log('请求成功:', res.data);
48 | uni.setStorageSync('token', res.data.data.token);
49 | // store.setSessionId(store.sessionId);
50 | // store.init();
51 | console.log(uni.getStorageSync('token'));
52 | console.log('-=-=-=-=loginRes-=-=-=');
53 | } else {
54 | console.error('请求失败,状态码:', res.statusCode);
55 | }
56 | },
57 | fail: function (error) {
58 | console.error('请求失败:', error);
59 | }
60 | });
61 |
62 | })
63 | }
64 |
--------------------------------------------------------------------------------
/uniapp/src/api/user.js:
--------------------------------------------------------------------------------
1 | import { baseUrl } from "@/utils/env";
2 |
3 | /**
4 | * 获取当前用户信息
5 | */
6 | export const getCurrentUserInfo = () => {
7 | return new Promise((resolve, reject) => {
8 | uni.request({
9 | url: `${baseUrl}/student/get/currentUserInfo`,
10 | method: 'GET',
11 | header: {
12 | 'Content-Type': 'application/json',
13 | 'token': uni.getStorageSync('token'),
14 | },
15 | success: (res) => {
16 | if (res.data.code === 1) {
17 | resolve(res.data.data);
18 | } else {
19 | reject(res.data.msg);
20 | }
21 | },
22 | fail: (err) => reject(err),
23 | });
24 | });
25 | };
26 |
--------------------------------------------------------------------------------
/uniapp/src/main.js:
--------------------------------------------------------------------------------
1 | import { createSSRApp } from "vue";
2 | import App from "./App.vue";
3 | import { createPinia } from 'pinia';
4 | import { createPersistedState } from 'pinia-persistedstate-plugin';
5 |
6 | export function createApp() {
7 | const app = createSSRApp(App);
8 | const pinia = createPinia();
9 | const persist = createPersistedState();
10 |
11 | pinia.use(persist);
12 | app.use(pinia);
13 |
14 | return {
15 | app,
16 | pinia
17 | };
18 | }
19 |
--------------------------------------------------------------------------------
/uniapp/src/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name" : "wall-uniapp",
3 | "appid" : "__UNI__3388B50",
4 | "description" : "",
5 | "versionName" : "1.0.0",
6 | "versionCode" : "100",
7 | "transformPx" : false,
8 | /* 5+App特有相关 */
9 | "app-plus" : {
10 | "usingComponents" : true,
11 | "nvueStyleCompiler" : "uni-app",
12 | "compilerVersion" : 3,
13 | "splashscreen" : {
14 | "alwaysShowBeforeRender" : true,
15 | "waiting" : true,
16 | "autoclose" : true,
17 | "delay" : 0
18 | },
19 | /* 模块配置 */
20 | "modules" : {},
21 | /* 应用发布信息 */
22 | "distribute" : {
23 | /* android打包配置 */
24 | "android" : {
25 | "permissions" : [
26 | "",
27 | "",
28 | "",
29 | "",
30 | "",
31 | "",
32 | "",
33 | "",
34 | "",
35 | "",
36 | "",
37 | "",
38 | "",
39 | "",
40 | ""
41 | ]
42 | },
43 | /* ios打包配置 */
44 | "ios" : {},
45 | /* SDK配置 */
46 | "sdkConfigs" : {
47 | "share" : {
48 | "weixin" : {
49 | "appid" : "wx39ff21ee255f85dd",
50 | "UniversalLinks" : ""
51 | }
52 | }
53 | }
54 | }
55 | },
56 | /* 快应用特有相关 */
57 | "quickapp" : {},
58 | /* 小程序特有相关 */
59 | "mp-weixin" : {
60 | "appid" : "wxbd9c9c99d9116c2a",
61 | "setting" : {
62 | "urlCheck" : false,
63 | "minified" : true,
64 | "ignoreDevUnusedFiles" : false,
65 | "ignoreUploadUnusedFiles" : false,
66 | "postcss" : true
67 | },
68 | "usingComponents" : true,
69 | "permission" : {
70 | "scope.userLocation" : {
71 | "desc" : "订单功能需要获取用户位置信息"
72 | }
73 | },
74 | "requiredPrivateInfos" : [ "getLocation", "chooseLocation" ]
75 | },
76 | "mp-alipay" : {
77 | "usingComponents" : true
78 | },
79 | "mp-baidu" : {
80 | "usingComponents" : true
81 | },
82 | "mp-toutiao" : {
83 | "usingComponents" : true
84 | },
85 | "uniStatistics" : {
86 | "enable" : false
87 | },
88 | "vueVersion" : "3",
89 | "locale" : "zh-Hans",
90 | "h5" : {
91 | "sdkConfigs" : {
92 | "maps" : {
93 | "qqmap" : {
94 | "key" : "RSNBZ-3ABW4-MF3UK-FMCJP-JC4YT-RUFTR"
95 | }
96 | }
97 | }
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/uniapp/src/pages.json:
--------------------------------------------------------------------------------
1 | {
2 | "easycom": {
3 | "autoscan": true,
4 | "custom": {
5 | "^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
6 | }
7 | },
8 | "pages": [
9 | {
10 | "path": "pages/index/index",
11 | "style": {
12 | "navigationBarTitleText": "CPU Wall"
13 | }
14 | },
15 | {
16 | "path": "pages/person/getPhone",
17 | "style": {
18 | "navigationBarTitleText": "获取手机号"
19 | }
20 | },
21 | {
22 | "path": "pages/transition/agreement",
23 | "style": {
24 | "navigationBarTitleText": "用户协议"
25 | }
26 | },
27 | {
28 | "path": "pages/person/person",
29 | "style": {
30 | "navigationBarTitleText": "个人中心"
31 | }
32 | },
33 | {
34 | "path": "pages/person/editInfo",
35 | "style": {
36 | "navigationBarTitleText": "个人信息编辑"
37 | }
38 | },
39 | {
40 | "path": "pages/person/authentication",
41 | "style": {
42 | "navigationBarTitleText": "个人信息认证"
43 | }
44 | },
45 | {
46 | "path": "pages/person/universe",
47 | "style": {
48 | "navigationBarTitleText": "通用管理"
49 | }
50 | },
51 | {
52 | "path": "pages/topic/create",
53 | "style": {
54 | "navigationBarTitleText": "创建帖子"
55 | }
56 | },
57 | {
58 | "path": "pages/topic/view",
59 | "style": {
60 | "navigationBarTitleText": "发表评论"
61 | }
62 | },
63 | {
64 | "path": "pages/topic/report",
65 | "style": {
66 | "navigationBarTitleText": "举报"
67 | }
68 | },
69 | {
70 | "path": "pages/order/order",
71 | "style": {
72 | "navigationBarTitleText": "发布订单"
73 | }
74 | },
75 | {
76 | "path": "pages/order/location",
77 | "style": {
78 | "navigationBarTitleText": "地图选点"
79 | }
80 | },
81 | {
82 | "path": "pages/order/address",
83 | "style": {
84 | "navigationBarTitleText": "地址管理"
85 | }
86 | },
87 | {
88 | "path": "pages/message/index",
89 | "style": {
90 | "navigationBarTitleText": "我的消息"
91 | }
92 | },
93 | {
94 | "path": "pages/favorites/post",
95 | "style": {
96 | "navigationBarTitleText": "我的发布"
97 | }
98 | },
99 | {
100 | "path": "pages/favorites/index",
101 | "style": {
102 | "navigationBarTitleText": "我的收藏"
103 | }
104 | },
105 | {
106 | "path": "pages/index/about",
107 | "style": {
108 | "navigationBarTitleText": "关于我们"
109 | }
110 | }
111 | ],
112 | "tabBar": {
113 | "color": "#000000",
114 | "selectedColor": "#000000",
115 | "backgroundColor": "#ffffff",
116 | "borderStyle": "black",
117 | "list": [
118 | {
119 | "pagePath": "pages/index/index",
120 | "text": "首页",
121 | "iconPath": "static/icon/home.png",
122 | "selectedIconPath": "static/icon/home-active.png"
123 | },
124 | // {
125 | // "pagePath": "pages/order/order",
126 | // "text": "订单",
127 | // "iconPath": "static/icon/order.png",
128 | // "selectedIconPath": "static/icon/order-active.png"
129 | // },
130 | {
131 | "pagePath": "pages/message/index",
132 | "text": "消息",
133 | "iconPath": "static/icon/message.png",
134 | "selectedIconPath": "static/icon/message-active.png"
135 | },
136 | {
137 | "pagePath": "pages/person/person",
138 | "text": "我的",
139 | "iconPath": "static/icon/person.png",
140 | "selectedIconPath": "static/icon/person-active.png"
141 | }
142 | ]
143 | },
144 | "globalStyle": {
145 | "navigationBarTextStyle": "black",
146 | "navigationBarTitleText": "uni-app",
147 | "navigationBarBackgroundColor": "#F8F8F8",
148 | "backgroundColor": "#F8F8F8"
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/uniapp/src/pages/index/about.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 👋 你好,我们是宁波诺丁汉大学计算机爱好者协会!
5 | 欢迎来到我们的应用!我们致力于提供最好的服务和体验。
6 | 这个小程序由Pleasure1234独立开发,xuanzhi33提供技术支持
7 |
8 |
9 |
10 |
11 |
34 |
--------------------------------------------------------------------------------
/uniapp/src/pages/index/components/fab.vue:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
67 |
68 |
77 |
--------------------------------------------------------------------------------
/uniapp/src/pages/index/components/swipper.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
50 |
51 |
70 |
--------------------------------------------------------------------------------
/uniapp/src/pages/message/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ❤️
7 | 获赞和收藏
8 |
9 |
10 |
11 | 评论
12 |
13 |
14 |
15 |
16 |
17 |
21 |
22 |
23 | 暂无内容
24 |
25 |
26 |
27 |
28 |
29 |
37 |
38 |
123 |
--------------------------------------------------------------------------------
/uniapp/src/pages/order/address.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 打开地图选点
6 |
7 |
8 | {{address.province}}
9 |
10 |
11 | {{address.city}}
12 |
13 |
14 | {{address.district}}
15 |
16 |
17 | {{address.name}}
18 |
19 |
20 | {{address.address}}
21 |
22 |
23 | {{address.location}}
24 |
25 |
26 | 省编码:{{address.pcode}}
27 |
28 |
29 | 城市编码{{address.citycode}}
30 |
31 |
32 | 区编码{{address.adcode}}
33 |
34 |
35 |
36 |
37 |
66 |
67 |
91 |
--------------------------------------------------------------------------------
/uniapp/src/pages/order/location.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
45 |
46 |
52 |
--------------------------------------------------------------------------------
/uniapp/src/pages/person/authentication.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
10 |
11 |
手机号
12 |
13 |
151****4032
14 |
15 |
16 |
17 |
24 |
25 |
学校邮箱认证
26 |
27 |
scyyw24@nottingham.edu.cn
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
46 |
47 |
105 |
--------------------------------------------------------------------------------
/uniapp/src/pages/person/getPhone.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | 请您阅读并同意
18 | 《用户协议》
19 | 《隐私协议》
20 |
21 |
22 |
23 |
24 |
25 |
26 |
51 |
52 |
130 |
--------------------------------------------------------------------------------
/uniapp/src/pages/person/universe.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
17 |
18 |
19 |
22 |
40 |
41 |
42 |
43 |
51 |
52 |
107 |
--------------------------------------------------------------------------------
/uniapp/src/pages/transition/agreement.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 隐私权政策提示
5 |
6 |
7 | 请您在使用CPU Wall服务前点击
8 | 《服务使用协议》
9 | 《隐私与个人信息保护政策》与
10 | 并仔细阅读。如您同意以上全部内容,请点击同意并开始使用我们的服务。如果您不同意,您将无法使用我们的小程序。
11 |
12 |
13 |
14 |
15 | 本人已年满14岁,可自行授权个人信息处理
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
45 |
46 |
121 |
--------------------------------------------------------------------------------
/uniapp/src/shime-uni.d.ts:
--------------------------------------------------------------------------------
1 | export {};
2 |
3 | declare module "vue" {
4 | type Hooks = App.AppInstance & Page.PageInstance;
5 | interface ComponentCustomOptions extends Hooks {}
6 | }
--------------------------------------------------------------------------------
/uniapp/src/static/carousel/image1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/uniapp/src/static/carousel/image1.jpg
--------------------------------------------------------------------------------
/uniapp/src/static/carousel/image2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/uniapp/src/static/carousel/image2.jpg
--------------------------------------------------------------------------------
/uniapp/src/static/carousel/image3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/uniapp/src/static/carousel/image3.jpg
--------------------------------------------------------------------------------
/uniapp/src/static/carousel/image4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/uniapp/src/static/carousel/image4.jpg
--------------------------------------------------------------------------------
/uniapp/src/static/carousel/image5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/uniapp/src/static/carousel/image5.jpg
--------------------------------------------------------------------------------
/uniapp/src/static/carousel/image6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/uniapp/src/static/carousel/image6.jpg
--------------------------------------------------------------------------------
/uniapp/src/static/default_avatar.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/uniapp/src/static/default_avatar.jpg
--------------------------------------------------------------------------------
/uniapp/src/static/icon/home-active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/uniapp/src/static/icon/home-active.png
--------------------------------------------------------------------------------
/uniapp/src/static/icon/home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/uniapp/src/static/icon/home.png
--------------------------------------------------------------------------------
/uniapp/src/static/icon/message-active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/uniapp/src/static/icon/message-active.png
--------------------------------------------------------------------------------
/uniapp/src/static/icon/message.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/uniapp/src/static/icon/message.png
--------------------------------------------------------------------------------
/uniapp/src/static/icon/order-active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/uniapp/src/static/icon/order-active.png
--------------------------------------------------------------------------------
/uniapp/src/static/icon/order.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/uniapp/src/static/icon/order.png
--------------------------------------------------------------------------------
/uniapp/src/static/icon/person-active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/uniapp/src/static/icon/person-active.png
--------------------------------------------------------------------------------
/uniapp/src/static/icon/person.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/uniapp/src/static/icon/person.png
--------------------------------------------------------------------------------
/uniapp/src/static/icon/star-active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/uniapp/src/static/icon/star-active.png
--------------------------------------------------------------------------------
/uniapp/src/static/icon/star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/uniapp/src/static/icon/star.png
--------------------------------------------------------------------------------
/uniapp/src/static/icon/topic-active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/uniapp/src/static/icon/topic-active.png
--------------------------------------------------------------------------------
/uniapp/src/static/icon/topic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/uniapp/src/static/icon/topic.png
--------------------------------------------------------------------------------
/uniapp/src/static/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/uniapp/src/static/logo.png
--------------------------------------------------------------------------------
/uniapp/src/static/logo/default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/uniapp/src/static/logo/default.png
--------------------------------------------------------------------------------
/uniapp/src/static/logo/icon_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/uniapp/src/static/logo/icon_logo.png
--------------------------------------------------------------------------------
/uniapp/src/static/logo/login_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/uniapp/src/static/logo/login_bg.png
--------------------------------------------------------------------------------
/uniapp/src/static/logo/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/uniapp/src/static/logo/logo.png
--------------------------------------------------------------------------------
/uniapp/src/static/logo/mini-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CompPsyUnion/NottinghamWall/6073d2743903ff003da9eb9197a52bce4438ff6e/uniapp/src/static/logo/mini-logo.png
--------------------------------------------------------------------------------
/uniapp/src/uni.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * 这里是uni-app内置的常用样式变量
3 | *
4 | * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
5 | * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
6 | *
7 | */
8 |
9 | /**
10 | * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
11 | *
12 | * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
13 | */
14 |
15 | /* 颜色变量 */
16 |
17 | /* 行为相关颜色 */
18 | $uni-color-primary: #007aff;
19 | $uni-color-success: #4cd964;
20 | $uni-color-warning: #f0ad4e;
21 | $uni-color-error: #dd524d;
22 |
23 | /* 文字基本颜色 */
24 | $uni-text-color: #333; // 基本色
25 | $uni-text-color-inverse: #fff; // 反色
26 | $uni-text-color-grey: #999; // 辅助灰色,如加载更多的提示信息
27 | $uni-text-color-placeholder: #808080;
28 | $uni-text-color-disable: #c0c0c0;
29 |
30 | /* 背景颜色 */
31 | $uni-bg-color: #fff;
32 | $uni-bg-color-grey: #f8f8f8;
33 | $uni-bg-color-hover: #f1f1f1; // 点击状态颜色
34 | $uni-bg-color-mask: rgba(0, 0, 0, 0.4); // 遮罩颜色
35 |
36 | /* 边框颜色 */
37 | $uni-border-color: #c8c7cc;
38 |
39 | /* 尺寸变量 */
40 |
41 | /* 文字尺寸 */
42 | $uni-font-size-sm: 12px;
43 | $uni-font-size-base: 14px;
44 | $uni-font-size-lg: 16;
45 |
46 | /* 图片尺寸 */
47 | $uni-img-size-sm: 20px;
48 | $uni-img-size-base: 26px;
49 | $uni-img-size-lg: 40px;
50 |
51 | /* Border Radius */
52 | $uni-border-radius-sm: 2px;
53 | $uni-border-radius-base: 3px;
54 | $uni-border-radius-lg: 6px;
55 | $uni-border-radius-circle: 50%;
56 |
57 | /* 水平间距 */
58 | $uni-spacing-row-sm: 5px;
59 | $uni-spacing-row-base: 10px;
60 | $uni-spacing-row-lg: 15px;
61 |
62 | /* 垂直间距 */
63 | $uni-spacing-col-sm: 4px;
64 | $uni-spacing-col-base: 8px;
65 | $uni-spacing-col-lg: 12px;
66 |
67 | /* 透明度 */
68 | $uni-opacity-disabled: 0.3; // 组件禁用态的透明度
69 |
70 | /* 文章场景相关 */
71 | $uni-color-title: #2c405a; // 文章标题颜色
72 | $uni-font-size-title: 20px;
73 | $uni-color-subtitle: #555; // 二级标题颜色
74 | $uni-font-size-subtitle: 18px;
75 | $uni-color-paragraph: #3f536e; // 文章段落颜色
76 | $uni-font-size-paragraph: 15px;
--------------------------------------------------------------------------------
/uniapp/src/utils/request.js:
--------------------------------------------------------------------------------
1 | import {baseUrl} from '@/utils/env'
2 |
3 | export function request({url='', params={}, method='GET'}) {
4 |
5 | let header = {
6 | 'Accept': 'application/json',
7 | 'Content-Type': 'application/json',
8 | token: uni.getStorageSync('token')
9 | }
10 |
11 | return new Promise((resolve, reject) => {
12 | uni.request({
13 | url: baseUrl + url,
14 | data: params,
15 | header: header,
16 | method: method,
17 | success: (res) => {
18 | const {data} = res
19 | if (data.code === 200 || data.code === 1) {
20 | // store.commit('setLoading', false)
21 | console.log('Request Success:', res)
22 | resolve(res.data)
23 | } else {
24 | // store.commit('setLoading', true)
25 | console.error('Request Failed:', res.data)
26 | reject(res.data)
27 | }
28 | },
29 | fail: (err) => {
30 | console.error('Request Failed:', err);
31 | const error = {data: {msg: err.data}}
32 | // store.commit('setLoading', true)
33 | reject(error)
34 | }
35 | });
36 | })
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/uniapp/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import uni from '@dcloudio/vite-plugin-uni'
3 | import path from "path";
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [
7 | uni(),
8 | ],
9 | resolve: {
10 | alias: {
11 | '@': path.resolve(__dirname, 'src')
12 | }
13 | },
14 | })
15 |
--------------------------------------------------------------------------------