├── wall-vue
├── public
│ ├── favicon.ico
│ └── index.html
├── src
│ ├── assets
│ │ ├── img.png
│ │ ├── logo.png
│ │ ├── video.png
│ │ ├── pointer.cur
│ │ └── background.svg
│ ├── App.vue
│ ├── utils
│ │ ├── pub.js
│ │ ├── cache.js
│ │ └── request.js
│ ├── views
│ │ ├── other
│ │ │ └── 404.vue
│ │ ├── auth
│ │ │ └── login.vue
│ │ └── admin
│ │ │ ├── setting.vue
│ │ │ ├── tag.vue
│ │ │ ├── index.vue
│ │ │ ├── list.vue
│ │ │ └── upload.vue
│ ├── components
│ │ ├── footer-index.vue
│ │ ├── justifiedGallery.min.css
│ │ └── jquery.justifiedGallery.min.js
│ ├── main.js
│ └── router
│ │ └── index.js
├── babel.config.js
├── jsconfig.json
├── README.md
├── vue.config.js
├── package-copy.json
└── package.json
├── wall-service
├── src
│ └── main
│ │ ├── resources
│ │ ├── mapper
│ │ │ ├── TTagMapper.xml
│ │ │ ├── TOptionMapper.xml
│ │ │ ├── TResourceMapper.xml
│ │ │ └── TUserMapper.xml
│ │ ├── banner.txt
│ │ └── application.yml
│ │ └── java
│ │ └── cn
│ │ └── ityao
│ │ └── wall
│ │ ├── mapper
│ │ ├── TTagMapper.java
│ │ ├── TOptionMapper.java
│ │ ├── TResourceMapper.java
│ │ └── TUserMapper.java
│ │ ├── service
│ │ ├── ITTagService.java
│ │ ├── ITOptionService.java
│ │ ├── ITUserService.java
│ │ ├── impl
│ │ │ ├── TTagServiceImpl.java
│ │ │ ├── TUserServiceImpl.java
│ │ │ ├── TOptionServiceImpl.java
│ │ │ └── TResourceServiceImpl.java
│ │ └── ITResourceService.java
│ │ ├── vo
│ │ ├── RepassVo.java
│ │ └── TOptionVo.java
│ │ ├── common
│ │ └── SuperController.java
│ │ ├── exception
│ │ ├── Unauthorizedxception.java
│ │ ├── CustomException.java
│ │ ├── CustomErrorController.java
│ │ └── ExceptionHandleController.java
│ │ ├── config
│ │ ├── MybatisPlusConfig.java
│ │ ├── ErrorConfig.java
│ │ ├── ImageConfig.java
│ │ ├── JwtConfig.java
│ │ └── JwtInterceptor.java
│ │ ├── WallApplication.java
│ │ ├── util
│ │ ├── StringUtils.java
│ │ ├── encryption
│ │ │ ├── MD5Util.java
│ │ │ └── DesUtil.java
│ │ ├── TokenUtil.java
│ │ ├── picture
│ │ │ └── CompressUtils.java
│ │ ├── CoverExtractor.java
│ │ ├── DataResult.java
│ │ └── FileUtils.java
│ │ ├── controller
│ │ ├── VideoHttpRequestHandler.java
│ │ ├── AuthController.java
│ │ ├── TUserController.java
│ │ ├── TOptionController.java
│ │ ├── TTagController.java
│ │ └── TResourceController.java
│ │ └── entity
│ │ ├── TOption.java
│ │ ├── TTag.java
│ │ ├── TUser.java
│ │ └── TResource.java
├── README.md
├── wall.sql
└── pom.xml
├── 免责声明.md
└── README.md
/wall-vue/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/super-tongyao/wall/HEAD/wall-vue/public/favicon.ico
--------------------------------------------------------------------------------
/wall-vue/src/assets/img.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/super-tongyao/wall/HEAD/wall-vue/src/assets/img.png
--------------------------------------------------------------------------------
/wall-vue/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/super-tongyao/wall/HEAD/wall-vue/src/assets/logo.png
--------------------------------------------------------------------------------
/wall-vue/src/assets/video.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/super-tongyao/wall/HEAD/wall-vue/src/assets/video.png
--------------------------------------------------------------------------------
/wall-vue/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/wall-vue/src/assets/pointer.cur:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/super-tongyao/wall/HEAD/wall-vue/src/assets/pointer.cur
--------------------------------------------------------------------------------
/wall-service/src/main/resources/mapper/TTagMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/wall-service/src/main/resources/mapper/TOptionMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/wall-service/src/main/resources/mapper/TResourceMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/wall-vue/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
16 |
17 |
18 |
20 |
--------------------------------------------------------------------------------
/wall-vue/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "esnext",
5 | "baseUrl": "./",
6 | "moduleResolution": "node",
7 | "paths": {
8 | "@/*": [
9 | "src/*"
10 | ]
11 | },
12 | "lib": [
13 | "esnext",
14 | "dom",
15 | "dom.iterable",
16 | "scripthost"
17 | ]
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/mapper/TTagMapper.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.mapper;
2 |
3 | import cn.ityao.wall.entity.TTag;
4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
5 |
6 | /**
7 | *
8 | * 标签表 Mapper 接口
9 | *
10 | *
11 | * @author tongyao
12 | * @since 2023-02-14
13 | */
14 | public interface TTagMapper extends BaseMapper {
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/service/ITTagService.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.service;
2 |
3 | import cn.ityao.wall.entity.TTag;
4 | import com.baomidou.mybatisplus.extension.service.IService;
5 |
6 | /**
7 | *
8 | * 标签表 服务类
9 | *
10 | *
11 | * @author tongyao
12 | * @since 2023-02-14
13 | */
14 | public interface ITTagService extends IService {
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/vo/RepassVo.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.vo;
2 |
3 | import lombok.Data;
4 |
5 | /**
6 | * wall-service >>> 【cn.ityao.wall.vo】
7 | * 修改密码vo
8 | *
9 | * @author: tongyao
10 | * @since: 2023-02-14
11 | */
12 | @Data
13 | public class RepassVo {
14 | private String oldPass;
15 | private String newPass;
16 | private String reNewPass;
17 | }
18 |
--------------------------------------------------------------------------------
/wall-service/README.md:
--------------------------------------------------------------------------------
1 | # wall-service
2 |
3 | ## 修改配置
4 |
5 | 修改```src/main/resources/application.yml```配置文件,及修改你的数据库地址及端口。
6 | ```
7 | # project prot
8 | server:
9 | port: 9999
10 |
11 | # database config
12 | mysql:
13 | database: wall
14 | port: 3306
15 | ip: localhost
16 | username: root
17 | password: root
18 | ```
19 | ## 启动项目
20 |
21 | 打开```WallApplication.java```类,右键Run运行此项目。
22 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/mapper/TOptionMapper.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.mapper;
2 |
3 | import cn.ityao.wall.entity.TOption;
4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
5 |
6 | /**
7 | *
8 | * 配置表 Mapper 接口
9 | *
10 | *
11 | * @author tongyao
12 | * @since 2023-02-14
13 | */
14 | public interface TOptionMapper extends BaseMapper {
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/mapper/TResourceMapper.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.mapper;
2 |
3 | import cn.ityao.wall.entity.TResource;
4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
5 |
6 | /**
7 | *
8 | * 资源表 Mapper 接口
9 | *
10 | *
11 | * @author tongyao
12 | * @since 2023-02-14
13 | */
14 | public interface TResourceMapper extends BaseMapper {
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/wall-service/src/main/resources/mapper/TUserMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/wall-vue/src/utils/pub.js:
--------------------------------------------------------------------------------
1 | import {message} from "ant-design-vue";
2 | import {getLocal} from "@/utils/cache";
3 |
4 | export function copyText(text,msg){
5 | let save = function (e){
6 | e.clipboardData.setData('text/plain',text);
7 | e.preventDefault();
8 | }
9 | document.addEventListener('copy',save);
10 | document.execCommand("copy");
11 | message.success(msg);
12 | }
13 |
--------------------------------------------------------------------------------
/wall-service/src/main/resources/banner.txt:
--------------------------------------------------------------------------------
1 | ____ __ ____ ___ __ __
2 | \ \ / \ / / / \ | | | |
3 | \ \/ \/ / / ^ \ | | | |
4 | \ / / /_\ \ | | | |
5 | \ /\ / / _____ \ | `----.| `----.
6 | \__/ \__/ /__/ \__\ |_______||_______| v${project-info.version}
7 |
8 | GitHub开源地址: https://github.com/super-tongyao/wall
9 |
10 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/service/ITOptionService.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.service;
2 |
3 | import cn.ityao.wall.entity.TOption;
4 | import com.baomidou.mybatisplus.extension.service.IService;
5 |
6 | /**
7 | *
8 | * 配置表 服务类
9 | *
10 | *
11 | * @author tongyao
12 | * @since 2023-02-14
13 | */
14 | public interface ITOptionService extends IService {
15 |
16 | public String getOption(String optionKey);
17 | }
18 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/service/ITUserService.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.service;
2 |
3 | import cn.ityao.wall.entity.TUser;
4 | import com.baomidou.mybatisplus.extension.service.IService;
5 |
6 | /**
7 | *
8 | * 服务类
9 | *
10 | *
11 | * @author tongyao
12 | * @since 2023-02-14
13 | */
14 | public interface ITUserService extends IService {
15 |
16 | public TUser loadUserByUsername(String userName);
17 | }
18 |
--------------------------------------------------------------------------------
/wall-vue/src/views/other/404.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 返回主页
6 |
7 |
8 |
9 |
10 |
11 |
16 |
17 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/common/SuperController.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.common;
2 |
3 | import cn.ityao.wall.service.ITOptionService;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 |
6 | /**
7 | * wall-service >>> 【cn.ityao.wall.common】
8 | * 通用Controller类
9 | *
10 | * @author: tongyao
11 | * @since: 2023-02-14
12 | */
13 | public class SuperController {
14 |
15 | @Autowired
16 | public ITOptionService itOptionService;
17 | }
18 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/mapper/TUserMapper.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.mapper;
2 |
3 | import cn.ityao.wall.entity.TUser;
4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
5 | import org.apache.ibatis.annotations.Param;
6 |
7 | /**
8 | *
9 | * Mapper 接口
10 | *
11 | *
12 | * @author tongyao
13 | * @since 2023-02-14
14 | */
15 | public interface TUserMapper extends BaseMapper {
16 |
17 | public TUser loadUserByUsername(@Param("userName") String userName);
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/exception/Unauthorizedxception.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.exception;
2 |
3 | import lombok.Data;
4 |
5 | /**
6 | * byte-cabinet >>> 【com.cabinet.common.exception】
7 | * 自定义权限异常
8 | *
9 | * @author: tongyao
10 | * @since: 2023-02-14
11 | */
12 | @Data
13 | public class Unauthorizedxception extends RuntimeException {
14 | Integer code;
15 | public Unauthorizedxception(Integer code, String message) {
16 | super(message);
17 | this.code = code;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/wall-vue/src/utils/cache.js:
--------------------------------------------------------------------------------
1 | export function setLocal (key, value) {
2 | window.localStorage.setItem(key, JSON.stringify(value))
3 | }
4 | export function getLocal (key) {
5 | const value = window.localStorage.getItem(key)
6 | try {
7 | return JSON.parse(window.localStorage.getItem(key))
8 | } catch (error) {
9 | return value
10 | }
11 | }
12 | export function removeLocal (key) {
13 | window.localStorage.removeItem(key)
14 | }
15 | export function clearLocalAll () {
16 | window.localStorage.clear();
17 | }
--------------------------------------------------------------------------------
/wall-vue/README.md:
--------------------------------------------------------------------------------
1 | # wall-vue
2 |
3 | ## 安装
4 | ```
5 | npm install
6 | ```
7 | ## 修改地址
8 |
9 | 编辑根目录```vue.config.js```文件,修改你的后端请求地址和端口。
10 | ```
11 | devServer: {
12 | proxy: {
13 | '/api': {
14 | target: 'http://localhost:9999/',
15 | ws: true,
16 | changeOrigin: true,
17 | pathRewrite: {
18 | '^/api': ''
19 | }
20 | }
21 | }
22 | }
23 | ```
24 |
25 | ## 运行项目
26 | ```
27 | npm run serve
28 | ```
29 |
30 | ## 编译项目
31 | ```
32 | npm run build
33 | ```
34 | ## 更多配置
35 | 请看 [Configuration Reference](https://cli.vuejs.org/config/).
36 |
--------------------------------------------------------------------------------
/wall-vue/vue.config.js:
--------------------------------------------------------------------------------
1 | const { defineConfig } = require('@vue/cli-service')
2 | module.exports = defineConfig({
3 | transpileDependencies: true,
4 |
5 | // 关闭语法检查
6 | lintOnSave:false,
7 |
8 | devServer: {
9 | proxy: {
10 | '/api': {
11 | target: 'http://localhost:9999',
12 | ws: true,
13 | changeOrigin: true,
14 | pathRewrite: {
15 | '^/api': ''
16 | }
17 | }
18 | }
19 | },
20 | pages: {
21 | index: {
22 | entry: 'src/main.js', // 入口文件
23 | title: '站点正在加载中...'
24 | }
25 | }
26 | })
27 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/exception/CustomException.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.exception;
2 |
3 | import lombok.Data;
4 |
5 | /**
6 | * byte-cabinet >>> 【com.cabinet.common.exception】
7 | * 自定义异常
8 | *
9 | * @author: tongyao
10 | * @since: 2023-02-14
11 | */
12 | @Data
13 | public class CustomException extends RuntimeException {
14 | Integer httpCode;
15 | Integer JsonCode;
16 | public CustomException(Integer httpCode, Integer JsonCode, String message) {
17 | super(message);
18 | this.httpCode = httpCode;
19 | this.JsonCode = JsonCode;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/service/impl/TTagServiceImpl.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.service.impl;
2 |
3 | import cn.ityao.wall.entity.TTag;
4 | import cn.ityao.wall.mapper.TTagMapper;
5 | import cn.ityao.wall.service.ITTagService;
6 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
7 | import org.springframework.stereotype.Service;
8 |
9 | /**
10 | *
11 | * 标签表 服务实现类
12 | *
13 | *
14 | * @author tongyao
15 | * @since 2023-02-14
16 | */
17 | @Service
18 | public class TTagServiceImpl extends ServiceImpl implements ITTagService {
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/service/ITResourceService.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.service;
2 |
3 | import cn.ityao.wall.entity.TResource;
4 | import com.baomidou.mybatisplus.extension.service.IService;
5 | import org.springframework.web.multipart.MultipartFile;
6 |
7 | import javax.servlet.http.HttpServletRequest;
8 |
9 | /**
10 | *
11 | * 资源表 服务类
12 | *
13 | *
14 | * @author tongyao
15 | * @since 2023-02-14
16 | */
17 | public interface ITResourceService extends IService {
18 |
19 | public void uploadFileAndSave(TResource tResource, MultipartFile[] resource, HttpServletRequest request);
20 | }
21 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/config/MybatisPlusConfig.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.config;
2 |
3 | import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
4 | import org.springframework.context.annotation.Bean;
5 | import org.springframework.context.annotation.Configuration;
6 |
7 | /**
8 | * wall-service >>> 【cn.ityao.wall.config】
9 | * MyBatisPlus分页配置
10 | *
11 | * @author: tongyao
12 | * @since: 2023-02-14
13 | */
14 | @Configuration
15 | public class MybatisPlusConfig {
16 |
17 | @Bean
18 | public PaginationInterceptor paginationInterceptor() {
19 | PaginationInterceptor page = new PaginationInterceptor();
20 | return page;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/免责声明.md:
--------------------------------------------------------------------------------
1 | ## 免责声明
2 |
3 | “主程序作者”字样包含主程序开发者GitHub账号ID:super-tongyao。“Wall团队”字样包含源主程序作者、所有Wall团队贡献者。全文均为双引号里的简称。
4 |
5 | (一)、Wall提供免费开源程序及代码,不提供网站相关的内容服务,该程序著作权归主程序作者所有。
6 |
7 | (二)、用户可自由选择是否使用我们的程序,Wall与用户使用我们的程序所建立的网站无任何关联,Wall对用户及其网站不承担任何责任(包括相关影像版权侵权等)。
8 |
9 | (三)、用户下载、安装、使用本程序,即表明用户信任Wall,Wall对任何原因在使用本程序时可能对用户自己或他人造成的任何形式的损失和伤害不承担责任。
10 |
11 | (四)、任何单位或个人认为使用本程序建立的网站可能涉嫌侵犯其合法权益的,应该及时向该网站的所有人反映、交涉、或诉诸法律手段。
12 |
13 | (五)、使用本程序的用户因为违反本声明的规定而触犯中华人民共和国法律的,一切后果自己负责,Wall和Wall团队不承担任何责任。
14 |
15 | (六)、本声明未涉及的问题参见国家有关法律法规,当本声明与国家法律法规冲突时,以国家法律法规为准。
16 |
17 |
18 | ## 最后声明
19 |
20 | 本程序为开源项目,主要用于代码技术分享及技术业务讨论,请勿使用本程序上传违法国家法律等相关影音资源文件,如:成人黄色图片、成人黄色影音视频、血腥暴力、恐吓恐怖、等一切违法国家法律的和切勿用作商业用途。如不听劝阻,发生意外等相关事宜,与Wall团队、Wall开源项目无关。
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/WallApplication.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall;
2 |
3 | import org.mybatis.spring.annotation.MapperScan;
4 | import org.springframework.boot.SpringApplication;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
7 |
8 | /**
9 | * Wall启动类
10 | *
11 | * @author tongyao
12 | * @since 2023-02-14
13 | */
14 | @SpringBootApplication
15 | @MapperScan(basePackages = {
16 | "cn.ityao.wall.mapper"
17 | })
18 | public class WallApplication extends SpringBootServletInitializer {
19 |
20 | public static void main(String[] args){
21 | SpringApplication.run(WallApplication.class, args);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/vo/TOptionVo.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.vo;
2 |
3 | import com.fasterxml.jackson.annotation.JsonProperty;
4 | import lombok.Data;
5 |
6 | import javax.validation.constraints.NotBlank;
7 |
8 | /**
9 | * wall-service >>> 【cn.ityao.wall.vo】
10 | * 配置项vo
11 | *
12 | * @author: tongyao
13 | * @since: 2023-02-21
14 | */
15 | @Data
16 | public class TOptionVo {
17 | @NotBlank(message = "文件保存位置不能为空!")
18 | private String saveFilePath;
19 | private String beian;
20 |
21 | @NotBlank(message = "令牌过期时间不能为空!")
22 | private String expireDate;
23 |
24 | @NotBlank(message = "令牌密钥不能为空!")
25 | private String secret;
26 |
27 | @NotBlank(message = "首页标题不能为空!")
28 | private String homeTitle;
29 | private String initTagId;
30 | }
31 |
--------------------------------------------------------------------------------
/wall-vue/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <%= htmlWebpackPlugin.options.title %>
9 |
10 |
11 | 当前程序使用Wall搭建,Github开源地址:https://github.com/super-tongyao/wall,尊重开源、保留注释,Wall团队鸣谢!
12 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/config/ErrorConfig.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.config;
2 |
3 | /**
4 | * wall-service >>> 【cn.ityao.wall.config】
5 | *
6 | * @author: tongyao
7 | * @since: 2023-08-15 15:15
8 | */
9 | /*import org.springframework.boot.web.server.ErrorPageRegistrar;
10 | import org.springframework.boot.web.server.ErrorPage;
11 | import org.springframework.boot.web.server.ErrorPageRegistry;
12 | import org.springframework.http.HttpStatus;
13 | import org.springframework.stereotype.Component;
14 |
15 | @Component
16 | public class ErrorConfig implements ErrorPageRegistrar {
17 |
18 | @Override
19 | public void registerErrorPages(ErrorPageRegistry registry) {
20 | ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/index.html");
21 | registry.addErrorPages(error404Page);
22 | }
23 | }*/
24 |
25 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/service/impl/TUserServiceImpl.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.service.impl;
2 |
3 | import cn.ityao.wall.entity.TUser;
4 | import cn.ityao.wall.mapper.TUserMapper;
5 | import cn.ityao.wall.service.ITUserService;
6 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.stereotype.Service;
9 |
10 | /**
11 | *
12 | * 服务实现类
13 | *
14 | *
15 | * @author tongyao
16 | * @since 2023-02-14
17 | */
18 | @Service
19 | public class TUserServiceImpl extends ServiceImpl implements ITUserService {
20 |
21 | @Autowired
22 | private TUserMapper tUserMapper;
23 |
24 | @Override
25 | public TUser loadUserByUsername(String userName) {
26 | return tUserMapper.loadUserByUsername(userName);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/util/StringUtils.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.util;
2 |
3 | import java.util.UUID;
4 |
5 | /**
6 | * wall-service >>> 【cn.ityao.wall.util】
7 | * String工具类
8 | *
9 | * @author: tongyao
10 | * @since: 2023-02-14
11 | */
12 | public class StringUtils {
13 |
14 | public static boolean isBlank(String str){
15 | return str == null || "".equals(str.trim()) ?true:false;
16 | }
17 |
18 | public static boolean isNotBlank(String str){
19 | return str!=null&&!"".equals(str.trim())&&!"null".equals(str)?true:false;
20 | }
21 |
22 | public static boolean isNull(Object str){
23 | return str == null?true:false;
24 | }
25 |
26 | public static boolean isNotNull(Object str){
27 | return str != null?true:false;
28 | }
29 |
30 | public static String getUUID(){
31 | return UUID.randomUUID()+"".replaceAll("-","");
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/wall-vue/package-copy.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wall",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build"
8 | },
9 | "dependencies": {
10 | "ant-design-vue": "^3.2.10",
11 | "axios": "^1.3.2",
12 | "core-js": "^3.8.3",
13 | "js-md5": "^0.7.3",
14 | "nprogress": "^0.2.0",
15 | "photoswipe": "^5.3.5",
16 | "vue": "^3.2.13",
17 | "vue-axios": "^3.4.1",
18 | "vue-masonry": "^0.16.0",
19 | "vue-router": "^4.1.3"
20 | },
21 | "devDependencies": {
22 | "@babel/core": "^7.12.16",
23 | "@babel/eslint-parser": "^7.12.16",
24 | "@vue/cli-plugin-babel": "~5.0.0",
25 | "@vue/cli-plugin-eslint": "~5.0.0",
26 | "@vue/cli-service": "~5.0.0",
27 | "crypto-js": "^4.1.1"
28 | },
29 | "browserslist": [
30 | "> 1%",
31 | "last 2 versions",
32 | "not dead",
33 | "not ie 11"
34 | ]
35 | }
36 |
--------------------------------------------------------------------------------
/wall-vue/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wall",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build"
8 | },
9 | "dependencies": {
10 | "ant-design-vue": "^3.2.10",
11 | "axios": "^1.3.2",
12 | "core-js": "^3.8.3",
13 | "jquery": "^3.7.1",
14 | "js-md5": "^0.7.3",
15 | "lightgallery": "^2.7.1",
16 | "nprogress": "^0.2.0",
17 | "photoswipe": "^5.3.5",
18 | "vue": "^3.2.13",
19 | "vue-axios": "^3.4.1",
20 | "vue-masonry": "^0.16.0",
21 | "vue-router": "^4.1.3"
22 | },
23 | "devDependencies": {
24 | "@babel/core": "^7.12.16",
25 | "@babel/eslint-parser": "^7.12.16",
26 | "@vue/cli-plugin-babel": "~5.0.0",
27 | "@vue/cli-plugin-eslint": "~5.0.0",
28 | "@vue/cli-service": "~5.0.0",
29 | "crypto-js": "^4.1.1"
30 | },
31 | "browserslist": [
32 | "> 1%",
33 | "last 2 versions",
34 | "not dead",
35 | "not ie 11"
36 | ]
37 | }
38 |
--------------------------------------------------------------------------------
/wall-service/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | # project prot
2 | server:
3 | port: 9999
4 | mvc:
5 | throw-exception-if-no-handler-found: true # 告诉 SpringBoot 当出现 404 错误时, 直接抛出异常
6 | resources:
7 | add-mappings: false # 告诉 SpringBoot 不要为我们工程中的资源文件建立映射
8 |
9 | # database config
10 | mysql:
11 | database: wall
12 | port: 3306
13 | ip: 82.157.190.245
14 | username: root
15 | password: Zty197368
16 |
17 | # spring config
18 | spring:
19 | datasource:
20 | driver-class-name: com.mysql.cj.jdbc.Driver
21 | url: jdbc:mysql://${mysql.ip}:${mysql.port}/${mysql.database}?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2b8
22 | username: ${mysql.username}
23 | password: ${mysql.password}
24 |
25 | # file upload size
26 | servlet:
27 | multipart:
28 | max-file-size: 1024MB
29 | max-request-size: 1024MB
30 |
31 | # MyBatis conf
32 | mybatis-plus:
33 | mapper-locations: classpath:mapper/**/*.xml
34 | type-aliases-package: cn.ityao.wall.entity
35 |
36 | project-info:
37 | version: @version@
38 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/controller/VideoHttpRequestHandler.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.controller;
2 |
3 | /**
4 | * wall-service >>> 【cn.ityao.wall.controller】
5 | *
6 | * @author: tongyao
7 | * @since: 2023-03-06 17:16
8 | */
9 | import org.springframework.core.io.FileSystemResource;
10 | import org.springframework.core.io.Resource;
11 | import org.springframework.stereotype.Component;
12 | import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
13 | import javax.servlet.http.HttpServletRequest;
14 | import java.nio.file.Path;
15 |
16 | /**
17 | * @description: 视频流和音频流加载设置
18 | * @return:
19 | * @author: Ming
20 | * @time: 2022/6/24
21 | */
22 | @Component
23 | public class VideoHttpRequestHandler extends ResourceHttpRequestHandler {
24 | public final static String ATTR_FILE = "NON-STATIC-FILE";
25 |
26 | @Override
27 | protected Resource getResource(HttpServletRequest request) {
28 | final Path filePath = (Path) request.getAttribute(ATTR_FILE);
29 | return new FileSystemResource(filePath);
30 | }
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/wall-vue/src/components/footer-index.vue:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
29 |
30 |
41 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/config/ImageConfig.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.config;
2 |
3 | import cn.ityao.wall.service.ITOptionService;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
6 | import org.springframework.context.annotation.Configuration;
7 | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
8 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
9 |
10 | import java.io.File;
11 |
12 | /**
13 | * wall-service >>> 【cn.ityao.wall.config】
14 | * 本地图片资源映射
15 | *
16 | * @author: tongyao
17 | * @since: 2023-03-06
18 | */
19 | @Configuration
20 | public class ImageConfig implements WebMvcConfigurer {
21 |
22 | @Autowired
23 | public ITOptionService itOptionService;
24 |
25 | @Override
26 | public void addResourceHandlers(ResourceHandlerRegistry registry) {
27 | String rootPath = itOptionService.getOption("saveFilePath");
28 |
29 | // 判断目录是否存在,不在就创建
30 | File file = new File(rootPath);
31 | if(!file.exists()){
32 | file.mkdirs();
33 | }
34 | registry.addResourceHandler("/static/**").addResourceLocations("file:"+rootPath);
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/entity/TOption.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.entity;
2 |
3 | import com.baomidou.mybatisplus.annotation.TableId;
4 | import com.fasterxml.jackson.annotation.JsonFormat;
5 | import com.fasterxml.jackson.annotation.JsonProperty;
6 | import lombok.Data;
7 | import lombok.EqualsAndHashCode;
8 | import lombok.experimental.Accessors;
9 |
10 | import java.io.Serializable;
11 | import java.util.Date;
12 |
13 | /**
14 | *
15 | * 配置表
16 | *
17 | *
18 | * @author tongyao
19 | * @since 2023-02-14
20 | */
21 | @Data
22 | @EqualsAndHashCode(callSuper = false)
23 | @Accessors(chain = true)
24 | public class TOption implements Serializable {
25 |
26 | private static final long serialVersionUID = 1L;
27 |
28 | /**
29 | * 配置键
30 | */
31 | @TableId(value ="option_key")
32 | private String optionKey;
33 |
34 | /**
35 | * 配置内容
36 | */
37 | private String optionValue;
38 |
39 | /**
40 | * 创建者
41 | */
42 | @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
43 | private String createBy;
44 |
45 | /**
46 | * 创建时间
47 | */
48 | @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
49 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
50 | private Date createTime;
51 |
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/service/impl/TOptionServiceImpl.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.service.impl;
2 |
3 | import cn.ityao.wall.entity.TOption;
4 | import cn.ityao.wall.mapper.TOptionMapper;
5 | import cn.ityao.wall.service.ITOptionService;
6 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.stereotype.Service;
9 |
10 | import javax.annotation.Resource;
11 | import java.util.HashMap;
12 | import java.util.List;
13 | import java.util.Map;
14 |
15 | /**
16 | *
17 | * 配置表 服务实现类
18 | *
19 | *
20 | * @author tongyao
21 | * @since 2023-02-14
22 | */
23 | @Service
24 | public class TOptionServiceImpl extends ServiceImpl implements ITOptionService {
25 |
26 | @Resource
27 | private TOptionMapper tOptionMapper;
28 |
29 | @Override
30 | public String getOption(String optionKey) {
31 | Map map = new HashMap();
32 | map.put("option_key",optionKey);
33 | List tOptionList = tOptionMapper.selectByMap(map);
34 | if (tOptionList.size()==0){
35 | throw new RuntimeException("配置项:"+optionKey+",不存在数据库中!");
36 | }
37 | return tOptionList.get(0).getOptionValue();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/exception/CustomErrorController.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.exception;
2 |
3 | import cn.ityao.wall.util.DataResult;
4 | import org.springframework.boot.web.servlet.error.ErrorController;
5 | import org.springframework.http.ResponseEntity;
6 | import org.springframework.web.bind.annotation.RequestMapping;
7 | import org.springframework.web.bind.annotation.RestController;
8 |
9 | import javax.servlet.http.HttpServletRequest;
10 |
11 | /**
12 | * byte-cabinet >>> 【com.cabinet.auth.exception】
13 | * 由于@ControllerAdvice捕获不到404,用于只配置404错误,重写error页面
14 | *
15 | * @author: tongyao
16 | * @since: 2023-02-14
17 | */
18 | @RestController
19 | public class CustomErrorController implements ErrorController {
20 |
21 | @RequestMapping(value = "/error")
22 | public ResponseEntity error(HttpServletRequest request) {
23 | Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
24 | if(statusCode == 404){
25 | return ResponseEntity.status(statusCode)
26 | .body(DataResult.setResult(statusCode,"接口没有找到"));
27 | }
28 | return ResponseEntity.status(500)
29 | .body(DataResult.setResult(500,"error pages 500"));
30 | }
31 |
32 | @Override
33 | public String getErrorPath() {
34 | return "/error";
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/config/JwtConfig.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.config;
2 |
3 | import org.springframework.context.annotation.Bean;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
6 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
7 | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
8 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
9 |
10 | /**
11 | * wall-service >>> 【cn.ityao.wall.config】
12 | * JWT 配置文件
13 | *
14 | * @author: tongyao
15 | * @since: 2023-02-21
16 | */
17 | @Configuration
18 | public class JwtConfig implements WebMvcConfigurer{
19 |
20 | @Override
21 | public void addInterceptors(InterceptorRegistry registry) {
22 | //注册TestInterceptor拦截器
23 | InterceptorRegistration registration = registry.addInterceptor(jwtInterceptor());
24 |
25 | registration.excludePathPatterns(
26 | "/favicon.ico",
27 | "/login",
28 | "/t-tag/query",
29 | "/t-resource/query",
30 | "/t-option/target",
31 | "/static/**");
32 | registration.addPathPatterns("/**");
33 | }
34 |
35 | @Bean
36 | public JwtInterceptor jwtInterceptor() {
37 | return new JwtInterceptor();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/util/encryption/MD5Util.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.util.encryption;
2 |
3 | import java.security.MessageDigest;
4 |
5 | /**
6 | * wall-service >>> 【cn.ityao.wall.util.encryption】
7 | * md5加密
8 | *
9 | * @author: tongyao
10 | * @since: 2023-02-27
11 | */
12 | public class MD5Util {
13 |
14 | /***
15 | * MD5加码 生成32位md5码
16 | */
17 | public static String string2MD5(String inStr){
18 | MessageDigest md5 = null;
19 | try{
20 | md5 = MessageDigest.getInstance("MD5");
21 | }catch (Exception e){
22 | System.out.println(e.toString());
23 | e.printStackTrace();
24 | return "";
25 | }
26 | char[] charArray = inStr.toCharArray();
27 | byte[] byteArray = new byte[charArray.length];
28 |
29 | for (int i = 0; i < charArray.length; i++)
30 | byteArray[i] = (byte) charArray[i];
31 | byte[] md5Bytes = md5.digest(byteArray);
32 | StringBuffer hexValue = new StringBuffer();
33 | for (int i = 0; i < md5Bytes.length; i++){
34 | int val = ((int) md5Bytes[i]) & 0xff;
35 | if (val < 16)
36 | hexValue.append("0");
37 | hexValue.append(Integer.toHexString(val));
38 | }
39 | return hexValue.toString();
40 |
41 | }
42 |
43 | // 测试主函数
44 | public static void main(String args[]) {
45 | String s = new String("123456");
46 | System.out.println("原始:" + s);
47 | System.out.println("MD5后:" + string2MD5(s));
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/util/TokenUtil.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.util;
2 |
3 | import cn.ityao.wall.service.ITOptionService;
4 | import com.auth0.jwt.JWT;
5 | import com.auth0.jwt.algorithms.Algorithm;
6 | import com.auth0.jwt.interfaces.Claim;
7 | import com.auth0.jwt.interfaces.DecodedJWT;
8 | import com.auth0.jwt.interfaces.JWTVerifier;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.stereotype.Component;
11 |
12 | import java.util.Date;
13 | import java.util.HashMap;
14 | import java.util.Map;
15 |
16 | /**
17 | * wall-service >>> 【cn.ityao.wall.util】
18 | * token工具
19 | *
20 | * @author: tongyao
21 | * @since: 2023-02-16
22 | */
23 | @Component
24 | public class TokenUtil {
25 |
26 | public static String createToken(String userId, String userName, int expireTime, String secret) {
27 | long EXPIRE_TIME = expireTime * 60 * 1000;
28 | Date expireDate = new Date(System.currentTimeMillis() + EXPIRE_TIME);
29 |
30 | Map map = new HashMap<>();
31 | map.put("alg", "HS256");
32 | map.put("typ", "JWT");
33 | String token = JWT.create()
34 | .withHeader(map)
35 |
36 | .withClaim("userId", userId)
37 | .withClaim("userName", userName)
38 | .withExpiresAt(expireDate)
39 | .withIssuedAt(new Date())
40 | .sign(Algorithm.HMAC256(secret));
41 | return token;
42 | }
43 |
44 | public static Map parsingToken(String token,String secret) {
45 | JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secret)).build();
46 | DecodedJWT jwt = verifier.verify(token);
47 | return jwt.getClaims();
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/entity/TTag.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.entity;
2 |
3 | import com.baomidou.mybatisplus.annotation.IdType;
4 | import com.baomidou.mybatisplus.annotation.TableId;
5 | import com.fasterxml.jackson.annotation.JsonFormat;
6 | import com.fasterxml.jackson.annotation.JsonProperty;
7 | import lombok.Data;
8 | import lombok.EqualsAndHashCode;
9 | import lombok.experimental.Accessors;
10 |
11 | import javax.validation.constraints.NotBlank;
12 | import java.io.Serializable;
13 | import java.util.Date;
14 |
15 | /**
16 | *
17 | * 标签表
18 | *
19 | *
20 | * @author tongyao
21 | * @since 2023-02-14
22 | */
23 | @Data
24 | @EqualsAndHashCode(callSuper = false)
25 | @Accessors(chain = true)
26 | public class TTag implements Serializable {
27 |
28 | private static final long serialVersionUID = 1L;
29 |
30 | /**
31 | * 标签编号
32 | */
33 | @TableId(value ="tag_id", type = IdType.UUID)
34 | private String tagId;
35 |
36 | /**
37 | * 标签名称
38 | */
39 | @NotBlank(message = "标签名称不能为空!")
40 | private String tagName;
41 |
42 | /**
43 | * 排序
44 | */
45 | private Integer sort;
46 |
47 | /**
48 | * 创建者
49 | */
50 | @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
51 | private String createBy;
52 |
53 | /**
54 | * 创建时间
55 | */
56 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
57 | private Date createTime;
58 |
59 | /**
60 | * 修改者
61 | */
62 | @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
63 | private String modifyBy;
64 |
65 | /**
66 | * 修改时间
67 | */
68 | @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
69 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
70 | private Date modifyTime;
71 |
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/controller/AuthController.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.controller;
2 |
3 | import cn.ityao.wall.entity.TUser;
4 | import cn.ityao.wall.service.ITOptionService;
5 | import cn.ityao.wall.service.ITUserService;
6 | import cn.ityao.wall.util.DataResult;
7 | import cn.ityao.wall.util.TokenUtil;
8 | import cn.ityao.wall.util.encryption.DesUtil;
9 | import lombok.extern.log4j.Log4j2;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.web.bind.annotation.RequestMapping;
12 | import org.springframework.web.bind.annotation.RestController;
13 |
14 | import java.util.Date;
15 |
16 | /**
17 | *
18 | * 前端登录
19 | *
20 | *
21 | * @author tongyao
22 | * @since 2023-02-14
23 | */
24 | @RestController
25 | @Log4j2
26 | public class AuthController {
27 |
28 | @Autowired
29 | private ITUserService itUserService;
30 |
31 | @Autowired
32 | private ITOptionService itOptionService;
33 |
34 | @RequestMapping("/login")
35 | public DataResult login(String username,String password){
36 | TUser tUser = itUserService.loadUserByUsername(username);
37 | String pass = DesUtil.encryption(password);
38 | if(tUser == null){
39 | throw new RuntimeException("当前用户不存在");
40 | }else if(!tUser.getPassWord().equals(pass)){
41 | throw new RuntimeException("账号或密码错误!");
42 | }
43 |
44 | Integer expireDate = Integer.parseInt(itOptionService.getOption("expireDate"));
45 | String secret = itOptionService.getOption("secret");
46 |
47 | // 创建token
48 | String accessToken = TokenUtil.createToken(tUser.getUserId(), tUser.getUserName(), expireDate, secret);
49 |
50 | tUser.setAccess_token(accessToken);
51 | tUser.setLastTime(new Date());
52 | itUserService.updateById(tUser);
53 | return DataResult.setResult(tUser);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/wall-vue/src/utils/request.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import {message} from "ant-design-vue";
3 | import { clearLocalAll, getLocal, removeLocal, setLocal } from "@/utils/cache";
4 | import NProgress from "nprogress";
5 |
6 | const instance = axios.create({
7 | baseURL: "/api",
8 | })
9 |
10 | //请求前拦截器
11 | instance.interceptors.request.use(
12 | function(config) {
13 | config.headers.access_token = getLocal("access_token");
14 | return config;
15 | },
16 | function(err) {
17 | return Promise.reject(err);
18 | }
19 | );
20 |
21 | const tishi = 0;
22 | var that = this;
23 | //全局请求后拦截器,没有做http状态码和返回状态码统一。
24 | instance.interceptors.response.use(
25 | function(response) {
26 | // 200
27 | // console.log("response:",response.data)
28 | return response;
29 | },
30 | function(err) {
31 | if(err.response.data.code >= 500 || err.response.data.code == 404){
32 | message.warning(err.response.data.message);
33 | }else if(err.response.data.code == 401){
34 | if((getLocal("user") != null && getLocal("user") != "")){
35 | removeLocal("user")
36 | removeLocal("access_token")
37 | message.warning("登录已过期,1秒后自动刷新页面。");
38 | setTimeout(function () {
39 | location.reload();
40 | },1000)
41 | }else{
42 | message.warning(err.response.data.message);
43 | }
44 | }
45 | NProgress.done()
46 | return Promise.reject(err);
47 | }
48 | );
49 |
50 | export function get(url) {
51 | return instance.get(url).then((res)=>{
52 | return res.data;
53 | });
54 | }
55 | export function post(url,data) {
56 | return instance.post(url, data).then((res)=>{
57 | return res.data;
58 | });
59 | }
60 | export function remove(url,data) {
61 | return instance.delete(url, data).then((res)=>{
62 | return res.data;
63 | });
64 | }
65 |
--------------------------------------------------------------------------------
/wall-vue/src/main.js:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue'
2 | import App from './App.vue'
3 | import router from '@/router'
4 | import Antd from 'ant-design-vue';
5 | import 'ant-design-vue/dist/antd.css'
6 | import {VueMasonryPlugin} from "vue-masonry";
7 | import NProgress from 'nprogress'
8 | import 'nprogress/nprogress.css'
9 | NProgress.configure({
10 | showSpinner: false,
11 | })
12 |
13 | const app = createApp(App)
14 | app.use(router).use(Antd).use(VueMasonryPlugin).use(NProgress).mount('#app')
15 |
16 | app.config.globalProperties.NProgress = NProgress;
17 |
18 | import * as Icons from "@ant-design/icons-vue";
19 | const icons = Icons;
20 | for(const i in icons){
21 | app.component(i,icons[i]);
22 | }
23 |
24 | import * as pub from "@/utils/pub.js";
25 | app.config.globalProperties.$pub = pub;
26 |
27 | var deviceName = navigator.userAgent.toLowerCase();
28 | if (/android|iphone|webos|ipod|blackberry/.test(deviceName)) {
29 | app.config.globalProperties.maxTagCount = 2;
30 | app.config.globalProperties.waterfallWidth = 175;
31 | app.config.globalProperties.waterfallStyle = {
32 | overflow:'hidden',margin: '0px auto',width: '376px'
33 | };
34 | app.config.globalProperties.width = {
35 | width: '100%'
36 | };
37 | app.config.globalProperties.videoWidthHeighut = {
38 | width: '300px',
39 | height:'200px'
40 | }
41 | }else{
42 | app.config.globalProperties.maxTagCount = 5;
43 | app.config.globalProperties.waterfallWidth = 372;
44 | app.config.globalProperties.waterfallStyle = {
45 | overflow:'hidden',margin: '0px auto',width: '1537px'
46 | };
47 | app.config.globalProperties.width = {};
48 | app.config.globalProperties.videoWidthHeighut = {
49 | width: '880px',
50 | height:'500px'
51 | }
52 | }
53 |
54 |
55 | if (window.console && window.console.log) {
56 | const e = (...e) => setTimeout(console.log.bind(console, ...e));
57 | e("\n %c Wall %c https://github.com/super-tongyao/wall \n", "color:#FFFFFB;background:#ffa628;padding:5px 0;border-radius:.5rem 0 0 .5rem;", "background: #efefef;padding:5px 0 5px;border-radius:0 .5rem .5rem 0;")
58 | e(` 当前程序使用Wall搭建,作者:https://ityao.cn`);
59 | e(`\n\n\n\n\n`);
60 | }
61 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/exception/ExceptionHandleController.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.exception;
2 |
3 | import cn.hutool.core.exceptions.ExceptionUtil;
4 | import cn.ityao.wall.util.DataResult;
5 | import lombok.extern.log4j.Log4j2;
6 | import lombok.extern.slf4j.Slf4j;
7 | import org.springframework.http.ResponseEntity;
8 | import org.springframework.validation.BindingResult;
9 | import org.springframework.validation.FieldError;
10 | import org.springframework.web.bind.MethodArgumentNotValidException;
11 | import org.springframework.web.bind.annotation.ControllerAdvice;
12 | import org.springframework.web.bind.annotation.ExceptionHandler;
13 | import org.springframework.web.bind.annotation.RestController;
14 |
15 | /**
16 | * 统一异常处理类
17 | * 捕获程序所有异常,针对不同异常,采取不同的处理方式
18 | *
19 | * @version 2.0
20 | * @author tongyao
21 | * @since 2023-02-14
22 | */
23 | @ControllerAdvice
24 | @RestController
25 | @Log4j2
26 | public class ExceptionHandleController {
27 |
28 | @ExceptionHandler(value = Exception.class)
29 | public ResponseEntity handle(Exception e) {
30 | if(e instanceof CustomException){
31 | CustomException customException = (CustomException) e;
32 | return ResponseEntity.status(customException.getHttpCode())
33 | .body(DataResult.setResult(customException.getJsonCode(),customException.getMessage()));
34 | }else if(e instanceof MethodArgumentNotValidException){
35 | //500 字段为空异常
36 | BindingResult bindingResult = ((MethodArgumentNotValidException) e).getBindingResult();
37 | FieldError fieldError = bindingResult.getFieldError();
38 | return ResponseEntity.status(500)
39 | .body(DataResult.setResult(500,fieldError.getDefaultMessage()));
40 | }else if(e instanceof Unauthorizedxception){
41 | Unauthorizedxception unauthorizedxception = (Unauthorizedxception) e;
42 | return ResponseEntity.status(unauthorizedxception.getCode())
43 | .body(DataResult.setResult(unauthorizedxception.getCode(),unauthorizedxception.getMessage()));
44 | }
45 | log.error(ExceptionUtil.stacktraceToString(e));
46 | return ResponseEntity.status(500)
47 | .body(DataResult.setResult(500,e.getMessage()));
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/config/JwtInterceptor.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.config;
2 |
3 | import cn.ityao.wall.exception.Unauthorizedxception;
4 | import cn.ityao.wall.service.ITOptionService;
5 | import cn.ityao.wall.util.TokenUtil;
6 | import com.auth0.jwt.interfaces.Claim;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.web.servlet.HandlerInterceptor;
9 | import org.springframework.web.servlet.ModelAndView;
10 |
11 | import javax.servlet.http.HttpServletRequest;
12 | import javax.servlet.http.HttpServletResponse;
13 | import java.util.Map;
14 |
15 | /**
16 | * wall-service >>> 【cn.ityao.wall.config】
17 | * JWT 拦截器
18 | *
19 | * @author: tongyao
20 | * @since: 2023-02-21
21 | */
22 | public class JwtInterceptor implements HandlerInterceptor{
23 |
24 | @Autowired
25 | private ITOptionService itOptionService;
26 |
27 | @Override
28 | public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception {
29 | // 从 http 请求头中取出 token
30 | String token = httpServletRequest.getHeader("access_token");
31 |
32 | //tonken验证
33 | if (token == null || "null".equals(token)) {
34 | throw new Unauthorizedxception(401,"请先登录!");
35 | }
36 |
37 | String secret = itOptionService.getOption("secret");
38 | // 验证令牌正确性
39 | Map userData = null;
40 | try {
41 | userData = TokenUtil.parsingToken(token,secret);
42 | } catch (Exception e) {
43 | throw new Unauthorizedxception(401,"Token令牌不正确,请先登录。");
44 | }
45 | String userId = userData.get("userId").asString();
46 | String userName = userData.get("userName").asString();
47 |
48 | httpServletRequest.setAttribute("userId",userId);
49 | httpServletRequest.setAttribute("userName",userName);
50 | return true;
51 | }
52 |
53 | @Override
54 | public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
55 |
56 | }
57 | @Override
58 | public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
59 |
60 | }
61 |
62 |
63 |
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/util/picture/CompressUtils.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.util.picture;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.springframework.web.multipart.MultipartFile;
5 |
6 | import javax.imageio.ImageIO;
7 | import java.awt.*;
8 | import java.awt.image.BufferedImage;
9 | import java.io.IOException;
10 |
11 | /**
12 | * wall-service >>> 【cn.ityao.wall.util】
13 | * 图片压缩
14 | *
15 | * @author: tongyao
16 | * @since: 2023-02-16
17 | */
18 | @Slf4j
19 | public class CompressUtils {
20 |
21 | public BufferedImage commpressPicture(MultipartFile multipartFile){
22 | try {
23 | BufferedImage templateImage = ImageIO.read(multipartFile.getInputStream());
24 |
25 | //原始图片的长度和宽度
26 | int height = templateImage.getHeight();
27 | int width = templateImage.getWidth();
28 |
29 | //通过比例压缩
30 | float scale = 0.5f;
31 |
32 | //通过固定长度压缩
33 | /*int doWithHeight = 100;
34 | int dowithWidth = 300;*/
35 |
36 | //压缩之后的长度和宽度
37 | int doWithHeight = (int) (scale * height);
38 | int dowithWidth = (int) (scale * width);
39 |
40 | BufferedImage finalImage = new BufferedImage(dowithWidth, doWithHeight, BufferedImage.TYPE_INT_RGB);
41 | finalImage.getGraphics()
42 | .drawImage(
43 | templateImage.getScaledInstance(dowithWidth, doWithHeight, java.awt.Image.SCALE_SMOOTH)
44 | , 0, 0, null);
45 |
46 | return finalImage;
47 | } catch (IOException e) {
48 | log.error("图片压缩异常:"+e.getMessage());
49 | }
50 | return null;
51 | }
52 |
53 |
54 | public BufferedImage commpressPicture(BufferedImage templateImage){
55 | //原始图片的长度和宽度
56 | int height = templateImage.getHeight();
57 | int width = templateImage.getWidth();
58 |
59 | //通过比例压缩
60 | float scale = 1f;
61 |
62 | //通过固定长度压缩
63 | /*int doWithHeight = 100;
64 | int dowithWidth = 300;*/
65 |
66 | //压缩之后的长度和宽度
67 | int doWithHeight = (int) (scale * height);
68 | int dowithWidth = (int) (scale * width);
69 |
70 | BufferedImage finalImage = new BufferedImage(dowithWidth, doWithHeight, BufferedImage.TYPE_INT_RGB);
71 | finalImage.getGraphics().drawImage(templateImage.getScaledInstance(dowithWidth, doWithHeight, java.awt.Image.SCALE_SMOOTH), 0, 0, null);
72 |
73 | return finalImage;
74 | }
75 |
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/entity/TUser.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.entity;
2 |
3 | import com.baomidou.mybatisplus.annotation.IdType;
4 | import com.baomidou.mybatisplus.annotation.TableField;
5 | import com.baomidou.mybatisplus.annotation.TableId;
6 | import com.fasterxml.jackson.annotation.JsonFormat;
7 | import com.fasterxml.jackson.annotation.JsonProperty;
8 | import lombok.Data;
9 | import lombok.EqualsAndHashCode;
10 | import lombok.experimental.Accessors;
11 |
12 | import java.io.Serializable;
13 | import java.util.Date;
14 |
15 | /**
16 | *
17 | * 用户表
18 | *
19 | *
20 | * @author tongyao
21 | * @since 2023-02-14
22 | */
23 | @Data
24 | @EqualsAndHashCode(callSuper = false)
25 | @Accessors(chain = true)
26 | public class TUser implements Serializable {
27 |
28 | private static final long serialVersionUID = 1L;
29 |
30 | /**
31 | * 用户编号
32 | */
33 | @TableId(value ="user_id", type = IdType.UUID)
34 | private String userId;
35 |
36 | /**
37 | * 用户账号
38 | */
39 | private String userName;
40 |
41 | /**
42 | * 用户密码
43 | */
44 | private String passWord;
45 |
46 | /**
47 | * 性别(1为男,2为女)
48 | */
49 | private Integer sex;
50 |
51 | /**
52 | * 电话手机
53 | */
54 | private String phone;
55 |
56 | /**
57 | * 邮箱地址
58 | */
59 | private String email;
60 |
61 | /**
62 | * 最后登录的时间
63 | */
64 | @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
65 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
66 | private Date lastTime;
67 |
68 | /**
69 | * 排序
70 | */
71 | private Integer sort;
72 |
73 | /**
74 | * 创建者
75 | */
76 | @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
77 | private String createBy;
78 |
79 | /**
80 | * 创建时间
81 | */
82 | @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
83 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
84 | private Date createTime;
85 |
86 | /**
87 | * 修改者
88 | */
89 | @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
90 | private String modifyBy;
91 |
92 | /**
93 | * 修改时间
94 | */
95 | @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
96 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
97 | private Date modifyTime;
98 |
99 | /**
100 | * access_token
101 | */
102 | @TableField(exist = false)
103 | private String access_token;
104 | }
105 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/entity/TResource.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.entity;
2 |
3 | import com.baomidou.mybatisplus.annotation.IdType;
4 | import com.baomidou.mybatisplus.annotation.TableField;
5 | import com.baomidou.mybatisplus.annotation.TableId;
6 | import com.fasterxml.jackson.annotation.JsonFormat;
7 | import com.fasterxml.jackson.annotation.JsonProperty;
8 | import lombok.Data;
9 | import lombok.EqualsAndHashCode;
10 | import lombok.experimental.Accessors;
11 | import org.hibernate.validator.constraints.Length;
12 | import org.springframework.web.multipart.MultipartFile;
13 |
14 | import java.io.Serializable;
15 | import java.util.Date;
16 |
17 | /**
18 | *
19 | * 资源表
20 | *
21 | *
22 | * @author tongyao
23 | * @since 2023-02-14
24 | */
25 | @Data
26 | @EqualsAndHashCode(callSuper = false)
27 | @Accessors(chain = true)
28 | public class TResource implements Serializable {
29 |
30 | private static final long serialVersionUID = 1L;
31 |
32 | /**
33 | * 资源编号
34 | */
35 | @TableId(value ="resource_id", type = IdType.UUID)
36 | private String resourceId;
37 |
38 | /**
39 | * 标题标题描述
40 | */
41 | @Length(min = 0, max = 300, message = "标题长度不能超过500个字符!")
42 | private String title;
43 |
44 | /**
45 | * 封面路径
46 | */
47 | private String coverPath;
48 |
49 | /**
50 | * 资源物理存储路径
51 | */
52 | private String resourcePath;
53 |
54 | /**
55 | * 资源类型(1、图片 2、视频)
56 | */
57 | private String resourceType;
58 |
59 | /**
60 | * 标签编号(可多个,以英文逗号隔开)
61 | */
62 | private String tagId;
63 |
64 | /**
65 | * 资源来源
66 | */
67 | private String sourceType;
68 |
69 | /**
70 | * 资源格式
71 | */
72 | private String resourceFormat;
73 |
74 | /**
75 | * 可见状态(1、为可见 0、为不可见)
76 | */
77 | private boolean visibleFlag;
78 |
79 | /**
80 | * 创建者
81 | */
82 | @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
83 | private String createBy;
84 |
85 | /**
86 | * 创建时间
87 | */
88 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
89 | private Date createTime;
90 |
91 | /**
92 | * 修改者
93 | */
94 | @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
95 | private String modifyBy;
96 |
97 | /**
98 | * 修改时间
99 | */
100 | @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
101 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
102 | private Date modifyTime;
103 |
104 | @TableField(exist = false)
105 | private String bedUrl;
106 | }
107 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/util/CoverExtractor.java:
--------------------------------------------------------------------------------
1 | /*
2 | package cn.ityao.wall.util;
3 |
4 | */
5 | /**
6 | * wall-service >>> 【cn.ityao.wall.util】
7 | *
8 | * @author: tongyao
9 | * @since: 2023-08-22 14:13
10 | *//*
11 |
12 | import net.coobird.thumbnailator.Thumbnails;
13 |
14 | import javax.imageio.ImageIO;
15 | import java.awt.*;
16 | import java.awt.image.BufferedImage;
17 | import java.io.*;
18 |
19 | public class CoverExtractor {
20 | public static InputStream extractCover(InputStream inputStream, String outputPath) throws IOException {
21 | // 将输入流保存为临时文件
22 | File tempFile = File.createTempFile("temp", null);
23 | FileOutputStream fileOutputStream = new FileOutputStream(tempFile);
24 | byte[] buffer = new byte[1024];
25 | int bytesRead;
26 | while ((bytesRead = inputStream.read(buffer)) != -1) {
27 | fileOutputStream.write(buffer, 0, bytesRead);
28 | }
29 | fileOutputStream.close();
30 |
31 | // 提取封面
32 | Image coverImage;
33 | if (outputPath.toLowerCase().endsWith(".mp4") || outputPath.toLowerCase().endsWith(".mov") ||
34 | outputPath.toLowerCase().endsWith(".avi")) {
35 | coverImage = getVideoCover(tempFile.getAbsolutePath());
36 | } else {
37 | coverImage = getImageCover(tempFile.getAbsolutePath());
38 | }
39 |
40 | // 压缩封面图片
41 | BufferedImage resizedImage = Thumbnails.of(coverImage)
42 | .size(200, 200) // 设置封面图片的宽高
43 | .asBufferedImage();
44 |
45 | // 将压缩后的图片保存到输出路径
46 | ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
47 | ImageIO.write(resizedImage, "jpeg", outputStream);
48 |
49 | // 删除临时文件
50 | tempFile.delete();
51 |
52 | // 返回压缩后的图片作为InputStream流
53 | return new ByteArrayInputStream(outputStream.toByteArray());
54 | }
55 |
56 | private static Image getVideoCover(String videoPath) {
57 | // 使用你喜欢的方法获取视频封面,这里使用的是某个假设的方法
58 | // 这里需要调用第三方库或自定义代码来提取视频封面
59 | // 可以参考FFmpeg、OpenCV等库来实现
60 | // 返回一个Image对象作为视频的封面图像
61 | return null;
62 | }
63 |
64 | private static Image getImageCover(String imagePath) throws IOException {
65 | // 从给定的路径读取图像文件
66 | BufferedImage image = ImageIO.read(new File(imagePath));
67 |
68 | // 返回BufferedImage作为图片的封面
69 | return image;
70 | }
71 |
72 | public static void main(String[] args) {
73 | try {
74 | // 示例:从输入流中提取图片或视频封面并进行压缩
75 | InputStream inputStream = new FileInputStream("C:\\wall-test233\\70ba43d1-3b8c-4648-bcc4-9230d3c2586b.wmv");
76 | InputStream coverInputStream = extractCover(inputStream, "D:\\");
77 |
78 | // 在这里可以使用你的专门保存inputStream流的方法来保存coverInputStream
79 |
80 | // 关闭输入流
81 | inputStream.close();
82 | coverInputStream.close();
83 | } catch (IOException e) {
84 | e.printStackTrace();
85 | }
86 | }
87 | }
88 |
89 | */
90 |
--------------------------------------------------------------------------------
/wall-vue/src/router/index.js:
--------------------------------------------------------------------------------
1 | import {createRouter, createWebHashHistory, createWebHistory} from 'vue-router'
2 | import {getLocal, removeLocal} from "@/utils/cache";
3 |
4 | const routes = [
5 | {
6 | path: '/',
7 | name: 'index',
8 | meta:{
9 | title: '首页'
10 | },
11 | component: () => import('@/views/index')
12 | },
13 | {
14 | path: '/:tagId',
15 | name: 'index-type',
16 | meta:{
17 | title: '首页'
18 | },
19 | component: () => import('@/views/index')
20 | },
21 | {
22 | path: '/admin',
23 | name: 'admin',
24 | meta:{
25 | title: '加载后台'
26 | },
27 | component: () => import('@/views/admin/index'),
28 | children:[
29 | {
30 | path: '/admin/upload',
31 | name: 'upload',
32 | meta:{
33 | title: '上传资源'
34 | },
35 | component: () => import('@/views/admin/upload'),
36 | },
37 | {
38 | path: '/admin/list',
39 | name: 'list',
40 | meta:{
41 | title: '资源列表'
42 | },
43 | component: () => import('@/views/admin/list'),
44 | },
45 | {
46 | path: '/admin/tag',
47 | name: 'tag',
48 | meta:{
49 | title: '标签管理'
50 | },
51 | component: () => import('@/views/admin/tag'),
52 | },
53 | {
54 | path: '/admin/setting',
55 | name: 'setting',
56 | meta:{
57 | title: '其他设置'
58 | },
59 | component: () => import('@/views/admin/setting'),
60 | }
61 | ]
62 | },
63 | {
64 | path: '/login',
65 | name: 'login',
66 | meta:{
67 | title: '登录'
68 | },
69 | component: () => import('@/views/auth/login')
70 | },
71 | {
72 | path: '/:catchAll(.*)',
73 | meta:{
74 | title: '404'
75 | },
76 | component: () => import('@/views/other/404')
77 | }
78 | ]
79 |
80 |
81 | const router = createRouter({
82 | history: createWebHistory(), //hash
83 | routes
84 | })
85 |
86 | router.beforeEach(function (to,from,next){
87 | if(to.meta.title == null){
88 | document.title = to.params.key + ' - Wall';
89 | }else{
90 | document.title = to.meta.title + ' - Wall';
91 | }
92 |
93 | // 先看访问是不是需要登陆页面
94 | if(to.path.indexOf("admin") != -1){
95 | if(getLocal("user") != null && getLocal("user") != "") {
96 | // 判断默认是不是通过浏览器直接输入/admin,如果是自动重定向到上传资源页面
97 | if(to.path == '/admin'){
98 | next(to.path+"/upload")
99 | }
100 | }else{
101 | next("/");
102 | }
103 | }
104 | next()
105 |
106 | })
107 |
108 | router.afterEach(function() {})
109 |
110 | export default router
111 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/util/DataResult.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.util;
2 |
3 | import lombok.Data;
4 |
5 | /**
6 | * 数据结果返回类
7 | *
8 | * @version 2.0
9 | * @author tongyao
10 | * @since 2021-08-01
11 | */
12 | @Data
13 | public class DataResult {
14 |
15 | private int code = 200;
16 | private String message = "success";
17 | private Object data = null;
18 |
19 | public DataResult() {
20 |
21 | }
22 |
23 | public DataResult(int code, String message) {
24 | this.code = code;
25 | this.message = message;
26 | }
27 |
28 | public DataResult(int code, String message, Object data) {
29 | this.code = code;
30 | this.message = message;
31 | this.data = data;
32 | }
33 |
34 | /**
35 | * 设置状态为200的返回结果数据
36 | * @param data
37 | * @return
38 | */
39 | public static DataResult setResult(Object data) {
40 | DataResult dataResult = new DataResult();
41 | dataResult.setData(data);
42 | return dataResult;
43 | }
44 |
45 | /**
46 | * 设置自定义状态的返回结果数据
47 | * @param data
48 | * @return
49 | */
50 | public static DataResult setResult(int code, Object data) {
51 | DataResult dataResult = new DataResult();
52 | dataResult.setCode(code);
53 | dataResult.setData(data);
54 | return dataResult;
55 | }
56 |
57 | /**
58 | * 设置自定义状态和返回信息返回结果数据
59 | * @param data
60 | * @return
61 | */
62 | public static DataResult setResult(int code, String message, Object data) {
63 | DataResult dataResult = new DataResult();
64 | dataResult.setCode(code);
65 | dataResult.setMessage(message);
66 | dataResult.setData(data);
67 | return dataResult;
68 | }
69 |
70 | /**
71 | * 设置自定义状态和返回信息内容,但无结果数据
72 | * @param code
73 | * @param message
74 | * @return
75 | */
76 | public static DataResult setResult(int code, String message) {
77 | DataResult dataResult = new DataResult();
78 | dataResult.setCode(code);
79 | dataResult.setMessage(message);
80 | return dataResult;
81 | }
82 |
83 | /**
84 | * 设置默认200状态,自定义返回信息和结果数据
85 | * @param data
86 | * @return
87 | */
88 | public static DataResult setResult(String message, Object data) {
89 | DataResult dataResult = new DataResult();
90 | dataResult.setMessage(message);
91 | dataResult.setData(data);
92 | return dataResult;
93 | }
94 |
95 | /**
96 | * 默认返回错误方法,自定义返回错误信息
97 | * @param message
98 | * @return
99 | */
100 | public static DataResult setError(String message) {
101 | DataResult dataResult = new DataResult();
102 | dataResult.setCode(500);
103 | dataResult.setMessage(message);
104 | return dataResult;
105 | }
106 |
107 | /**
108 | * 默认返回成功方法,自定义返回结果数据
109 | * @param data
110 | * @return
111 | */
112 | public static DataResult setSuccess(Object data) {
113 | DataResult dataResult = new DataResult();
114 | dataResult.setData(data);
115 | return dataResult;
116 | }
117 |
118 | }
119 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/controller/TUserController.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.controller;
2 |
3 |
4 | import cn.ityao.wall.entity.TUser;
5 | import cn.ityao.wall.service.ITUserService;
6 | import cn.ityao.wall.util.DataResult;
7 | import cn.ityao.wall.util.encryption.DesUtil;
8 | import cn.ityao.wall.util.encryption.MD5Util;
9 | import cn.ityao.wall.vo.RepassVo;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.http.MediaType;
12 | import org.springframework.web.bind.annotation.PostMapping;
13 | import org.springframework.web.bind.annotation.RequestBody;
14 | import org.springframework.web.bind.annotation.RequestMapping;
15 |
16 | import org.springframework.web.bind.annotation.RestController;
17 |
18 | import javax.servlet.http.HttpServletRequest;
19 | import java.util.HashMap;
20 | import java.util.List;
21 | import java.util.Map;
22 | import java.util.regex.Pattern;
23 |
24 | /**
25 | *
26 | * 前端控制器
27 | *
28 | *
29 | * @author tongyao
30 | * @since 2023-02-14
31 | */
32 | @RestController
33 | @RequestMapping("/t-user")
34 | public class TUserController {
35 |
36 | @Autowired
37 | private ITUserService itUserService;
38 |
39 | @RequestMapping("/query")
40 | public DataResult query(){
41 | return DataResult.setSuccess(itUserService.list());
42 | }
43 |
44 | @PostMapping(value = "/pass" , produces = {MediaType.APPLICATION_JSON_VALUE})
45 | public DataResult pass(@RequestBody RepassVo repassVo, HttpServletRequest request){
46 | if(repassVo.getNewPass() == null || "".equals(repassVo.getNewPass())){
47 | throw new RuntimeException("请输入新密码");
48 | }else if(repassVo.getReNewPass() == null || "".equals(repassVo.getReNewPass())){
49 | throw new RuntimeException("请再次输入新密码");
50 | }else if(!(repassVo.getNewPass().length() >= 8 && repassVo.getNewPass().length() <= 16)){
51 | throw new RuntimeException("密码长度要大于等于8位或小于等于16位");
52 | }else if(!Pattern.matches("^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).*", repassVo.getNewPass())){
53 | throw new RuntimeException("密码必须包含大小写字符和数字");
54 | }else if(!repassVo.getNewPass().equals(repassVo.getReNewPass())){
55 | throw new RuntimeException("两次密码输入不一致");
56 | }
57 | String userName = (String) request.getAttribute("userName");
58 |
59 | try {
60 | Map tempMap = new HashMap<>();
61 | tempMap.put("user_name",userName);
62 | TUser tUser = null;
63 | try {
64 | List list = (List) itUserService.listByMap(tempMap);
65 | tUser = list.get(0);
66 |
67 | } catch (Exception e) {
68 | throw new RuntimeException("修改失败,账户不存在");
69 | }
70 | String oldPass = DesUtil.encryption(MD5Util.string2MD5(repassVo.getOldPass()));
71 | if(!tUser.getPassWord().equals(oldPass)){
72 | throw new RuntimeException("旧密码与原密码不一致");
73 | }
74 | tUser.setPassWord(DesUtil.encryption(MD5Util.string2MD5(repassVo.getNewPass())));
75 | itUserService.updateById(tUser);
76 | } catch (Exception e) {
77 | throw new RuntimeException(e.getMessage());
78 | }
79 | return DataResult.setResult(null);
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/wall-vue/src/components/justifiedGallery.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * justifiedGallery - v3.8.0
3 | * http://miromannino.github.io/Justified-Gallery/
4 | * Copyright (c) 2020 Miro Mannino
5 | * Licensed under the MIT license.
6 | */
7 | .justified-gallery {
8 | width: 100%;
9 | position: relative;
10 | overflow: hidden;
11 | }
12 | .justified-gallery > a,
13 | .justified-gallery > div,
14 | .justified-gallery > figure {
15 | position: absolute;
16 | display: inline-block;
17 | overflow: hidden;
18 | /* background: #888888; To have gray placeholders while the gallery is loading with waitThumbnailsLoad = false */
19 | filter: "alpha(opacity=10)";
20 | opacity: 0.1;
21 | margin: 0;
22 | padding: 0;
23 | }
24 | .justified-gallery > a > img,
25 | .justified-gallery > div > img,
26 | .justified-gallery > figure > img,
27 | .justified-gallery > a > a > img,
28 | .justified-gallery > div > a > img,
29 | .justified-gallery > figure > a > img,
30 | .justified-gallery > a > svg,
31 | .justified-gallery > div > svg,
32 | .justified-gallery > figure > svg,
33 | .justified-gallery > a > a > svg,
34 | .justified-gallery > div > a > svg,
35 | .justified-gallery > figure > a > svg {
36 | position: absolute;
37 | top: 50%;
38 | left: 50%;
39 | margin: 0;
40 | padding: 0;
41 | border: none;
42 | filter: "alpha(opacity=0)";
43 | opacity: 0;
44 | }
45 | .justified-gallery > a > .jg-caption,
46 | .justified-gallery > div > .jg-caption,
47 | .justified-gallery > figure > .jg-caption {
48 | display: none;
49 | position: absolute;
50 | bottom: 0;
51 | padding: 5px;
52 | background-color: #000000;
53 | left: 0;
54 | right: 0;
55 | margin: 0;
56 | color: white;
57 | font-size: 12px;
58 | font-weight: 300;
59 | font-family: sans-serif;
60 | }
61 | .justified-gallery > a > .jg-caption.jg-caption-visible,
62 | .justified-gallery > div > .jg-caption.jg-caption-visible,
63 | .justified-gallery > figure > .jg-caption.jg-caption-visible {
64 | display: initial;
65 | filter: "alpha(opacity=70)";
66 | opacity: 0.7;
67 | -webkit-transition: opacity 500ms ease-in;
68 | -moz-transition: opacity 500ms ease-in;
69 | -o-transition: opacity 500ms ease-in;
70 | transition: opacity 500ms ease-in;
71 | }
72 | .justified-gallery > .jg-entry-visible {
73 | filter: "alpha(opacity=100)";
74 | opacity: 1;
75 | background: none;
76 | }
77 | .justified-gallery > .jg-entry-visible > img,
78 | .justified-gallery > .jg-entry-visible > a > img,
79 | .justified-gallery > .jg-entry-visible > svg,
80 | .justified-gallery > .jg-entry-visible > a > svg {
81 | filter: "alpha(opacity=100)";
82 | opacity: 1;
83 | -webkit-transition: opacity 500ms ease-in;
84 | -moz-transition: opacity 500ms ease-in;
85 | -o-transition: opacity 500ms ease-in;
86 | transition: opacity 500ms ease-in;
87 | }
88 | .justified-gallery > .jg-filtered {
89 | display: none;
90 | }
91 | .justified-gallery > .jg-spinner {
92 | position: absolute;
93 | bottom: 0;
94 | margin-left: -24px;
95 | padding: 10px 0 10px 0;
96 | left: 50%;
97 | filter: "alpha(opacity=100)";
98 | opacity: 1;
99 | overflow: initial;
100 | }
101 | .justified-gallery > .jg-spinner > span {
102 | display: inline-block;
103 | filter: "alpha(opacity=0)";
104 | opacity: 0;
105 | width: 8px;
106 | height: 8px;
107 | margin: 0 4px 0 4px;
108 | background-color: #000;
109 | border-radius: 6px;
110 | }
111 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/util/encryption/DesUtil.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.util.encryption;
2 |
3 | import sun.misc.BASE64Decoder;
4 | import sun.misc.BASE64Encoder;
5 |
6 | import javax.crypto.*;
7 | import javax.crypto.spec.SecretKeySpec;
8 | import java.io.IOException;
9 | import java.io.UnsupportedEncodingException;
10 | import java.security.InvalidKeyException;
11 | import java.security.NoSuchAlgorithmException;
12 | import java.security.SecureRandom;
13 | import java.util.Scanner;
14 |
15 | /**
16 | * wall-service >>> 【cn.ityao.wall.util.encryption】
17 | * Des对称加密
18 | *
19 | * @author: tongyao
20 | * @since: 2023-02-27
21 | */
22 | public class DesUtil {
23 | public static String salt = "09ec4bc7-b685-11ed-93d8-525400d73e0b";
24 |
25 | /**
26 | * 加密
27 | * @param content
28 | * @return
29 | */
30 | public static String encryption(String content) {
31 | try {
32 | KeyGenerator keygen = KeyGenerator.getInstance("AES");
33 | SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
34 | secureRandom.setSeed(salt.getBytes("UTF-8"));
35 | keygen.init(secureRandom);
36 | SecretKey original_key = keygen.generateKey();
37 | byte[] raw = original_key.getEncoded();
38 | SecretKey key = new SecretKeySpec(raw, "AES");
39 | Cipher cipher = Cipher.getInstance("AES");
40 | cipher.init(Cipher.ENCRYPT_MODE, key);
41 | byte[] byte_encode = content.getBytes("utf-8");
42 | byte[] byte_AES = cipher.doFinal(byte_encode);
43 | String AES_encode = new String(new BASE64Encoder().encode(byte_AES));
44 | return AES_encode;
45 | } catch (NoSuchAlgorithmException e) {
46 | e.printStackTrace();
47 | } catch (NoSuchPaddingException e) {
48 | e.printStackTrace();
49 | } catch (InvalidKeyException e) {
50 | e.printStackTrace();
51 | } catch (IllegalBlockSizeException e) {
52 | e.printStackTrace();
53 | } catch (BadPaddingException e) {
54 | e.printStackTrace();
55 | } catch (UnsupportedEncodingException e) {
56 | e.printStackTrace();
57 | }
58 | return null;
59 | }
60 |
61 | /**
62 | * 解密
63 | * @param content
64 | * @return
65 | */
66 | public static String decryption(String content) {
67 | try {
68 | KeyGenerator keygen = KeyGenerator.getInstance("AES");
69 | keygen.init(128, new SecureRandom(salt.getBytes()));
70 | SecretKey original_key = keygen.generateKey();
71 | byte[] raw = original_key.getEncoded();
72 | SecretKey key = new SecretKeySpec(raw, "AES");
73 | Cipher cipher = Cipher.getInstance("AES");
74 | cipher.init(Cipher.DECRYPT_MODE, key);
75 | byte[] byte_content = new BASE64Decoder().decodeBuffer(content);
76 | byte[] byte_decode = cipher.doFinal(byte_content);
77 | String AES_decode = new String(byte_decode, "utf-8");
78 | return AES_decode;
79 | } catch (NoSuchAlgorithmException e) {
80 | e.printStackTrace();
81 | } catch (NoSuchPaddingException e) {
82 | e.printStackTrace();
83 | } catch (InvalidKeyException e) {
84 | e.printStackTrace();
85 | } catch (IOException e) {
86 | e.printStackTrace();
87 | } catch (IllegalBlockSizeException e) {
88 | e.printStackTrace();
89 | } catch (BadPaddingException e) {
90 | e.printStackTrace();
91 | }
92 | return null;
93 | }
94 |
95 | public static void main(String[] args) {
96 | DesUtil se = new DesUtil();
97 | Scanner scanner = new Scanner(System.in);
98 |
99 | /*
100 | * 加密
101 | */
102 | System.out.println("请输入要加密的内容:");
103 | String content = scanner.next();
104 | System.out.println("根据输入的规则" + salt + "加密后的密文是:" + se.encryption(content));
105 |
106 | /*
107 | * 解密
108 | */
109 | System.out.println("请输入要解密的内容(密文):");
110 | content = scanner.next();
111 | System.out.println("根据输入的规则" + salt + "解密后的明文是:" + se.decryption(content));
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/controller/TOptionController.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.controller;
2 |
3 |
4 | import cn.ityao.wall.entity.TOption;
5 | import cn.ityao.wall.entity.TResource;
6 | import cn.ityao.wall.service.ITOptionService;
7 | import cn.ityao.wall.util.DataResult;
8 | import cn.ityao.wall.util.StringUtils;
9 | import cn.ityao.wall.vo.TOptionVo;
10 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
11 | import org.springframework.beans.factory.annotation.Autowired;
12 | import org.springframework.web.bind.annotation.*;
13 |
14 | import javax.validation.Valid;
15 | import java.io.File;
16 | import java.util.ArrayList;
17 | import java.util.List;
18 |
19 | /**
20 | *
21 | * 配置表 前端控制器
22 | *
23 | *
24 | * @author tongyao
25 | * @since 2023-02-14
26 | */
27 | @RestController
28 | @RequestMapping("/t-option")
29 | public class TOptionController {
30 |
31 | @Autowired
32 | private ITOptionService itOptionService;
33 |
34 | @PostMapping("/save")
35 | public DataResult save(@Valid @RequestBody TOptionVo tOptionVo){
36 | List tOptionList = new ArrayList<>();
37 |
38 |
39 | String path = tOptionVo.getSaveFilePath();
40 | if (!path.substring(path.length()-1).equals("\\") && !path.substring(path.length()-1).equals("/")){
41 | path = tOptionVo.getSaveFilePath()+ File.separator;
42 | }
43 | TOption saveFilePath = new TOption();
44 | saveFilePath.setOptionKey("saveFilePath");
45 | saveFilePath.setOptionValue(path);
46 | tOptionList.add(saveFilePath);
47 |
48 | TOption beian = new TOption();
49 | beian.setOptionKey("beian");
50 | beian.setOptionValue(tOptionVo.getBeian());
51 | tOptionList.add(beian);
52 |
53 | TOption expireDate = new TOption();
54 | expireDate.setOptionKey("expireDate");
55 | expireDate.setOptionValue(tOptionVo.getExpireDate());
56 | tOptionList.add(expireDate);
57 |
58 | TOption secret = new TOption();
59 | secret.setOptionKey("secret");
60 | secret.setOptionValue(tOptionVo.getSecret());
61 | tOptionList.add(secret);
62 |
63 | TOption homeTitle = new TOption();
64 | homeTitle.setOptionKey("homeTitle");
65 | homeTitle.setOptionValue(tOptionVo.getHomeTitle());
66 | tOptionList.add(homeTitle);
67 |
68 | TOption initTagId = new TOption();
69 | initTagId.setOptionKey("initTagId");
70 | initTagId.setOptionValue(tOptionVo.getInitTagId());
71 | tOptionList.add(initTagId);
72 |
73 | itOptionService.updateBatchById(tOptionList);
74 | return DataResult.setSuccess(null);
75 | }
76 |
77 | @GetMapping("/query")
78 | public DataResult query(){
79 | TOptionVo tOptionVo = new TOptionVo();
80 | List tOptionList = itOptionService.list();
81 | for (TOption tOption : tOptionList){
82 | if(tOption.getOptionKey().equals("saveFilePath")){
83 | tOptionVo.setSaveFilePath(tOption.getOptionValue());
84 | }else if(tOption.getOptionKey().equals("beian")){
85 | tOptionVo.setBeian(tOption.getOptionValue());
86 | }else if(tOption.getOptionKey().equals("expireDate")){
87 | tOptionVo.setExpireDate(tOption.getOptionValue());
88 | }else if(tOption.getOptionKey().equals("secret")){
89 | tOptionVo.setSecret(tOption.getOptionValue());
90 | }else if(tOption.getOptionKey().equals("homeTitle")){
91 | tOptionVo.setHomeTitle(tOption.getOptionValue());
92 | }else if(tOption.getOptionKey().equals("initTagId")){
93 | tOptionVo.setInitTagId(tOption.getOptionValue());
94 | }
95 | }
96 | return DataResult.setSuccess(tOptionVo);
97 | }
98 |
99 | @GetMapping("/target")
100 | public DataResult target(){
101 | TOptionVo tOptionVo = new TOptionVo();
102 | List tOptionList = itOptionService.list();
103 | for (TOption tOption : tOptionList){
104 | if(tOption.getOptionKey().equals("beian")){
105 | tOptionVo.setBeian(tOption.getOptionValue());
106 | }else if(tOption.getOptionKey().equals("homeTitle")){
107 | tOptionVo.setHomeTitle(tOption.getOptionValue());
108 | }else if(tOption.getOptionKey().equals("initTagId")){
109 | tOptionVo.setInitTagId(tOption.getOptionValue());
110 | }
111 | }
112 | return DataResult.setSuccess(tOptionVo);
113 | }
114 |
115 | }
116 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/controller/TTagController.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.controller;
2 |
3 |
4 | import cn.ityao.wall.entity.TOption;
5 | import cn.ityao.wall.entity.TResource;
6 | import cn.ityao.wall.entity.TTag;
7 | import cn.ityao.wall.service.ITOptionService;
8 | import cn.ityao.wall.service.ITResourceService;
9 | import cn.ityao.wall.service.ITTagService;
10 | import cn.ityao.wall.util.DataResult;
11 | import cn.ityao.wall.util.StringUtils;
12 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
13 | import com.baomidou.mybatisplus.core.metadata.IPage;
14 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
15 | import org.springframework.beans.factory.annotation.Autowired;
16 | import org.springframework.web.bind.annotation.*;
17 |
18 | import javax.servlet.http.HttpServletRequest;
19 | import javax.validation.Valid;
20 | import java.util.*;
21 |
22 | /**
23 | *
24 | * 标签表 前端控制器
25 | *
26 | *
27 | * @author tongyao
28 | * @since 2023-02-14
29 | */
30 | @RestController
31 | @RequestMapping("/t-tag")
32 | public class TTagController {
33 |
34 |
35 | @Autowired
36 | private ITTagService itTagService;
37 |
38 | @Autowired
39 | private ITResourceService itResourceService;
40 |
41 | @Autowired
42 | private ITOptionService itOptionService;
43 |
44 | @PostMapping("/saveOrUpdate")
45 | public DataResult saveOrUpdate(@Valid @RequestBody TTag tTag, HttpServletRequest request){
46 | String userName = (String) request.getAttribute("userName");
47 | if (tTag.getSort() == null){
48 | tTag.setSort(0);
49 | }
50 | if(StringUtils.isNotBlank(tTag.getTagId())){
51 | tTag.setModifyBy(userName);
52 | tTag.setModifyTime(new Date());
53 | itTagService.updateById(tTag);
54 | }else{
55 | tTag.setCreateBy(userName);
56 | tTag.setCreateTime(new Date());
57 | itTagService.save(tTag);
58 | }
59 | return DataResult.setSuccess(null);
60 | }
61 |
62 | @GetMapping("/list")
63 | public DataResult list(
64 | String tagName,
65 | @RequestParam(defaultValue = "1") int pageNo,
66 | @RequestParam(defaultValue = "10") int pageSize
67 | ){
68 | LambdaQueryWrapper tTagLambdaQueryWrapper = new LambdaQueryWrapper<>();
69 | if(StringUtils.isNotBlank(tagName)){
70 | tTagLambdaQueryWrapper.like(TTag::getTagName,tagName);
71 | }
72 | tTagLambdaQueryWrapper.orderByAsc(TTag::getCreateBy,TTag::getSort);
73 |
74 | Page page = new Page<>(pageNo,pageSize);
75 | IPage iPage = itTagService.page(page,tTagLambdaQueryWrapper);
76 | return DataResult.setSuccess(iPage);
77 | }
78 |
79 | @DeleteMapping("/delete")
80 | public DataResult delete(String tagIds){
81 | List tagId = Arrays.asList(tagIds.split(","));
82 |
83 | LambdaQueryWrapper tResourceLambdaQueryWrapper = new LambdaQueryWrapper<>();
84 | for (String str : tagId){
85 | tResourceLambdaQueryWrapper.like(TResource::getTagId,str);
86 | }
87 | List tResourceList = itResourceService.list(tResourceLambdaQueryWrapper);
88 | for (int i = 0; i < tResourceList.size(); i++) {
89 | for (int j = 0; j < tagId.size(); j++) {
90 | tResourceList.get(i).setTagId(tResourceList.get(i).getTagId().replaceAll(tagId.get(j)+",",""));
91 | }
92 | }
93 | if (tResourceList.size() != 0){
94 | itResourceService.updateBatchById(tResourceList);
95 | }
96 |
97 | Map map = new HashMap();
98 | map.put("option_key","initTagId");
99 | List tOptionList = (List) itOptionService.listByMap(map);
100 | TOption tOption = tOptionList.get(0);
101 | if (tagIds.indexOf(tOption.getOptionValue()) != -1){
102 | tOption = new TOption();
103 | tOption.setOptionKey("initTagId");
104 | tOption.setOptionValue("");
105 | itOptionService.updateById(tOption);
106 | }
107 |
108 | itTagService.removeByIds(tagId);
109 | return DataResult.setSuccess(null);
110 | }
111 |
112 | @GetMapping("/query")
113 | public DataResult query(){
114 | LambdaQueryWrapper tTagLambdaQueryWrapper = new LambdaQueryWrapper<>();
115 | tTagLambdaQueryWrapper.select(TTag::getTagId, TTag::getTagName);
116 | tTagLambdaQueryWrapper.orderByAsc(TTag::getCreateBy,TTag::getSort);
117 | return DataResult.setSuccess(itTagService.list(tTagLambdaQueryWrapper));
118 | }
119 |
120 | }
121 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/util/FileUtils.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.util;
2 |
3 | import cn.hutool.core.exceptions.ExceptionUtil;
4 | import lombok.extern.slf4j.Slf4j;
5 | import net.coobird.thumbnailator.Thumbnails;
6 | import org.apache.tomcat.util.http.fileupload.IOUtils;
7 | import org.bytedeco.javacv.FFmpegFrameGrabber;
8 | import org.bytedeco.javacv.Frame;
9 | import org.bytedeco.javacv.Java2DFrameConverter;
10 |
11 | import javax.imageio.ImageIO;
12 | import java.awt.image.BufferedImage;
13 | import java.io.*;
14 | import java.net.URL;
15 | import java.net.URLConnection;
16 | import java.nio.file.Files;
17 | import java.nio.file.Paths;
18 |
19 |
20 | /**
21 | * wall-service >>> 【cn.ityao.wall.util】
22 | * 文件工具类
23 | *
24 | * 作者注:如果你看到本类代码,觉得写的很优雅的话,那么不用质疑,这是作者舍弃旧代码花了3天时间又重新全部重构了一遍代码!
25 | *
26 | * @author: tongyao
27 | * @since: 2023-02-16
28 | */
29 | @Slf4j
30 | public class FileUtils {
31 |
32 | /**
33 | * 获取文件名称后缀
34 | * @param fileName
35 | * @return
36 | */
37 | public String getFileSuffix(String fileName){
38 | String suffix = fileName.substring(fileName.lastIndexOf(".")+1,fileName.length());
39 | return suffix.toLowerCase();
40 | }
41 |
42 | /**
43 | * 资源和封面的文件写入
44 | * @param inputStream
45 | * @param path
46 | */
47 | public void writeFile(InputStream inputStream,String path){
48 | try {
49 | FileOutputStream fileOutputStream = new FileOutputStream(path);
50 | IOUtils.copy(inputStream, fileOutputStream);
51 | IOUtils.closeQuietly(fileOutputStream);
52 | fileOutputStream.close();
53 | } catch (IOException e) {
54 | throw new RuntimeException("存储文件异常,可能最近修改了文件存储路径,请重启Wall服务!详细错误:"+ExceptionUtil.stacktraceToString(e));
55 | }
56 | }
57 |
58 | /**
59 | * 根据本地上传类型或者图床URL写入图片/视频封面资源
60 | * @param resourcePath
61 | * @param coverPath
62 | */
63 | public String writeCover(String resourcePath,String coverPath){
64 | InputStream inputStream = null;
65 | String contentType = null;
66 | String resourceType = "0";
67 | try {
68 | // 看是本地上传还是图床URL
69 | if (resourcePath.indexOf("http") != -1){
70 | URL url = new URL(resourcePath);
71 | URLConnection connection = url.openConnection();
72 | inputStream = connection.getInputStream();
73 | contentType = connection.getContentType();
74 | }else{
75 | inputStream = new FileInputStream(new File(resourcePath));
76 | contentType = Files.probeContentType(Paths.get(resourcePath));
77 | }
78 | // 看是视频还是图片
79 | if (contentType.startsWith("image/")) {
80 | // 这里不要问为什么不写,因为不想写 - -
81 | resourceType = "1";
82 | } else if (contentType.startsWith("video/")) {
83 | inputStream = videoCover(inputStream,2);
84 | resourceType = "2";
85 | }else{
86 | throw new RuntimeException("未知的资源存储类型:" + contentType);
87 | }
88 | // 不管图床URL还是本地上传 统一 保存 inputStream 写入到封面路径
89 | writeFile(inputStream,coverPath);
90 | } catch (IOException e) {
91 | throw new RuntimeException(ExceptionUtil.stacktraceToString(e));
92 | } finally {
93 | try {
94 | inputStream.close();
95 | } catch (IOException e) {
96 | throw new RuntimeException(ExceptionUtil.stacktraceToString(e));
97 | }
98 | return resourceType;
99 | }
100 | }
101 |
102 | /**
103 | * 获取视频帧数
104 | * @param inputStream 输入流
105 | * @param frameCount 帧数
106 | * @return
107 | */
108 | public InputStream videoCover(InputStream inputStream,int frameCount) {
109 | int flag = 0;
110 | Frame frame = null;
111 | try {
112 | FFmpegFrameGrabber fFmpegFrameGrabber = new FFmpegFrameGrabber(inputStream);
113 | fFmpegFrameGrabber.start();
114 | // 获取视频的总帧数
115 | int lengthInFrames = fFmpegFrameGrabber.getLengthInFrames();
116 | double frameNumber = fFmpegFrameGrabber.getFrameRate();
117 | while (flag <= lengthInFrames) {
118 | frame = fFmpegFrameGrabber.grabImage();
119 | // 帧数截取
120 | if (frame != null && flag == frameCount) {
121 | Java2DFrameConverter converter = new Java2DFrameConverter();
122 | BufferedImage bufferedImage = converter.getBufferedImage(frame);
123 | ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
124 | ImageIO.write(bufferedImage, "jpg", byteArrayOutputStream);
125 | ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
126 | inputStream = byteArrayInputStream;
127 | break;
128 | }
129 | flag++;
130 | }
131 | fFmpegFrameGrabber.stop();
132 | } catch (Exception e) {
133 | throw new RuntimeException("在获取视频帧时失败:" + ExceptionUtil.stacktraceToString(e));
134 | }
135 | return inputStream;
136 | }
137 |
138 | public static void main(String[] args) throws Exception {
139 | Thumbnails.of("C:\\wall-test233\\57eacccd-3610-4d68-a446-9893623d8dd2.jpg").scale(1).toFile("D:\\222_t2.jpg");
140 | Thumbnails.of("C:\\wall-test233\\57eacccd-3610-4d68-a446-9893623d8dd2.jpg").size(376,600).toFile("D:\\222_t.jpg");
141 | }
142 |
143 | }
144 |
--------------------------------------------------------------------------------
/wall-vue/src/views/auth/login.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |

7 |
Wall
8 |
9 |
10 |
11 |
12 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
33 | 登录
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
44 |
45 |
46 |
47 |
48 |
98 |
99 |
169 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/controller/TResourceController.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.controller;
2 |
3 |
4 | import cn.ityao.wall.common.SuperController;
5 | import cn.ityao.wall.entity.TResource;
6 | import cn.ityao.wall.entity.TTag;
7 | import cn.ityao.wall.service.ITOptionService;
8 | import cn.ityao.wall.service.ITResourceService;
9 | import cn.ityao.wall.util.DataResult;
10 | import cn.ityao.wall.util.FileUtils;
11 | import cn.ityao.wall.util.StringUtils;
12 | import cn.ityao.wall.util.picture.CompressUtils;
13 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
14 | import com.baomidou.mybatisplus.core.metadata.IPage;
15 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
16 | import org.springframework.beans.factory.annotation.Autowired;
17 | import org.springframework.web.bind.annotation.*;
18 |
19 | import org.springframework.web.multipart.MultipartFile;
20 |
21 | import javax.imageio.ImageIO;
22 | import javax.servlet.http.HttpServletRequest;
23 | import java.awt.*;
24 | import java.awt.image.BufferedImage;
25 | import java.io.File;
26 | import java.io.FileInputStream;
27 | import java.io.IOException;
28 | import java.util.Arrays;
29 | import java.util.Date;
30 | import java.util.List;
31 | import java.util.UUID;
32 |
33 | /**
34 | *
35 | * 资源表 前端控制器
36 | *
37 | *
38 | * @author tongyao
39 | * @since 2023-02-14
40 | */
41 | @RestController
42 | @RequestMapping("/t-resource")
43 | public class TResourceController extends SuperController {
44 |
45 | @Autowired
46 | private ITResourceService itResourceService;
47 |
48 | @PostMapping("/upload")
49 | public DataResult upload(TResource tResource, MultipartFile[] resource,String[] title,HttpServletRequest request){
50 | if(resource == null){
51 | throw new RuntimeException("请上传图片或视频!");
52 | }
53 | itResourceService.uploadFileAndSave(tResource,resource,request);
54 | return DataResult.setSuccess(null);
55 | }
56 |
57 | @GetMapping("/query")
58 | public DataResult query(String tagId,
59 | @RequestParam(defaultValue = "1") int pageNo,
60 | @RequestParam(defaultValue = "10") int pageSize){
61 |
62 | LambdaQueryWrapper tResourceLambdaQueryWrapper = new LambdaQueryWrapper<>();
63 | if(StringUtils.isNotBlank(tagId)){
64 | tResourceLambdaQueryWrapper.like(TResource::getTagId,tagId);
65 | }
66 | tResourceLambdaQueryWrapper.eq(TResource::isVisibleFlag,true);
67 | tResourceLambdaQueryWrapper.orderByDesc(TResource::getCreateTime);
68 |
69 | /*Page page = new Page<>(pageNo,pageSize);
70 | IPage iPage = itResourceService.page(page,tResourceLambdaQueryWrapper);*/
71 |
72 | String rootPath = itOptionService.getOption("saveFilePath");
73 | List list = itResourceService.list(tResourceLambdaQueryWrapper);
74 | return DataResult.setSuccess(list);
75 | }
76 |
77 | @GetMapping("/list")
78 | public DataResult list(
79 | String title, String tagId,
80 | @RequestParam(defaultValue = "1") int pageNo,
81 | @RequestParam(defaultValue = "10") int pageSize){
82 |
83 | LambdaQueryWrapper tResourceLambdaQueryWrapper = new LambdaQueryWrapper<>();
84 | if(StringUtils.isNotBlank(title)){
85 | tResourceLambdaQueryWrapper.like(TResource::getTitle,title);
86 | }
87 | if(StringUtils.isNotBlank(tagId)){
88 | tResourceLambdaQueryWrapper.like(TResource::getTagId,tagId);
89 | }
90 | tResourceLambdaQueryWrapper.orderByDesc(TResource::getCreateTime);
91 |
92 | Page page = new Page<>(pageNo,pageSize);
93 | IPage iPage = itResourceService.page(page,tResourceLambdaQueryWrapper);
94 | return DataResult.setSuccess(iPage);
95 | }
96 |
97 | @DeleteMapping("/delete")
98 | public DataResult delete(String resourceIds){
99 | List resourceId = Arrays.asList(resourceIds.split(","));
100 | List tResourceList = (List) itResourceService.listByIds(resourceId);
101 |
102 | String saveFilePath = itOptionService.getOption("saveFilePath");
103 | File deleteFile = null;
104 | for (TResource tResource : tResourceList){
105 | deleteFile = new File(saveFilePath+tResource.getCoverPath());
106 | deleteFile.delete();
107 |
108 | deleteFile = new File(saveFilePath+tResource.getResourcePath());
109 | deleteFile.delete();
110 | }
111 | itResourceService.removeByIds(resourceId);
112 | return DataResult.setSuccess(null);
113 | }
114 |
115 | @PostMapping("/updateState")
116 | public DataResult updateState(String resourceId, boolean visibleFlag, HttpServletRequest request){
117 | String userName = (String) request.getAttribute("userName");
118 |
119 | TResource tResource = new TResource();
120 | tResource.setResourceId(resourceId);
121 | tResource.setVisibleFlag(visibleFlag);
122 | tResource.setModifyBy(userName);
123 | tResource.setModifyTime(new Date());
124 | itResourceService.updateById(tResource);
125 | return DataResult.setSuccess(null);
126 | }
127 |
128 |
129 | @PostMapping("/update")
130 | public DataResult update(String resourceId, String title,String tagIds, HttpServletRequest request){
131 | String userName = (String) request.getAttribute("userName");
132 |
133 | TResource tResource = new TResource();
134 | tResource.setResourceId(resourceId);
135 | tResource.setTitle(title);
136 | tResource.setTagId(tagIds);
137 | tResource.setModifyBy(userName);
138 | tResource.setModifyTime(new Date());
139 | itResourceService.updateById(tResource);
140 | return DataResult.setSuccess(null);
141 | }
142 |
143 |
144 |
145 | }
146 |
--------------------------------------------------------------------------------
/wall-service/wall.sql:
--------------------------------------------------------------------------------
1 | /*
2 | Navicat Premium Data Transfer
3 |
4 | Source Server : localhost
5 | Source Server Type : MySQL
6 | Source Server Version : 50730
7 | Source Host : localhost:3306
8 | Source Schema : wall
9 |
10 | Target Server Type : MySQL
11 | Target Server Version : 50730
12 | File Encoding : 65001
13 |
14 | Date: 02/03/2023 12:24:35
15 | */
16 |
17 | SET NAMES utf8mb4;
18 | SET FOREIGN_KEY_CHECKS = 0;
19 |
20 | create database wall;
21 | use wall;
22 |
23 | -- ----------------------------
24 | -- Table structure for t_option
25 | -- ----------------------------
26 | DROP TABLE IF EXISTS `t_option`;
27 | CREATE TABLE `t_option` (
28 | `option_key` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '配置键',
29 | `option_value` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '配置内容',
30 | `create_by` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '创建者',
31 | `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
32 | PRIMARY KEY (`option_key`) USING BTREE
33 | ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '配置表' ROW_FORMAT = Dynamic;
34 |
35 | -- ----------------------------
36 | -- Records of t_option
37 | -- ----------------------------
38 | INSERT INTO `t_option` VALUES ('beian', '', 'system', now());
39 | INSERT INTO `t_option` VALUES ('expireDate', '120', 'system', now());
40 | INSERT INTO `t_option` VALUES ('homeTitle', '🏞️ 照片墙', 'system', now());
41 | INSERT INTO `t_option` VALUES ('initTagId', '', 'system', now());
42 | INSERT INTO `t_option` VALUES ('saveFilePath', 'C:\\wall\\', 'system', now());
43 | INSERT INTO `t_option` VALUES ('secret', uuid(), 'system', now());
44 |
45 | -- ----------------------------
46 | -- Table structure for t_resource
47 | -- ----------------------------
48 | DROP TABLE IF EXISTS `t_resource`;
49 | CREATE TABLE `t_resource` (
50 | `resource_id` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '资源编号',
51 | `title` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '标题标题描述',
52 | `cover_type` tinyint(2) NULL DEFAULT NULL COMMENT '封面类型(1、自动截取封面 2、上传封面)',
53 | `cover_path` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '封面路径',
54 | `resource_path` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '资源物理存储路径',
55 | `resource_width` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '资源图片宽',
56 | `resource_height` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '资源图片高',
57 | `resource_type` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '资源后缀类型',
58 | `tag_id` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '标签编号(可多个,以英文逗号隔开)',
59 | `visible_flag` tinyint(2) NULL DEFAULT NULL COMMENT '可见状态(1、为可见 0、为不可见)',
60 | `create_by` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '创建者',
61 | `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
62 | `modify_by` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '修改者',
63 | `modify_time` datetime(0) NULL DEFAULT NULL COMMENT '修改时间',
64 | PRIMARY KEY (`resource_id`) USING BTREE
65 | ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '资源表' ROW_FORMAT = Dynamic;
66 |
67 | -- ----------------------------
68 | -- Records of t_resource
69 | -- ----------------------------
70 |
71 | -- ----------------------------
72 | -- Table structure for t_tag
73 | -- ----------------------------
74 | DROP TABLE IF EXISTS `t_tag`;
75 | CREATE TABLE `t_tag` (
76 | `tag_id` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '标签编号',
77 | `tag_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '标签名称',
78 | `sort` tinyint(100) NULL DEFAULT NULL COMMENT '排序',
79 | `create_by` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '创建者',
80 | `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
81 | `modify_by` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '修改者',
82 | `modify_time` datetime(0) NULL DEFAULT NULL COMMENT '修改时间',
83 | PRIMARY KEY (`tag_id`) USING BTREE
84 | ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '标签表' ROW_FORMAT = Dynamic;
85 |
86 | -- ----------------------------
87 | -- Records of t_tag
88 | -- ----------------------------
89 |
90 | -- ----------------------------
91 | -- Table structure for t_user
92 | -- ----------------------------
93 | DROP TABLE IF EXISTS `t_user`;
94 | CREATE TABLE `t_user` (
95 | `user_id` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户编号',
96 | `user_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户账号',
97 | `pass_word` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户密码',
98 | `sex` tinyint(4) NULL DEFAULT NULL COMMENT '性别(1为男,2为女)',
99 | `phone` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '电话手机',
100 | `email` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '邮箱地址',
101 | `last_time` datetime(0) NULL DEFAULT NULL COMMENT '最后登录的时间',
102 | `sort` tinyint(255) NULL DEFAULT NULL COMMENT '排序',
103 | `create_by` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '创建者',
104 | `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
105 | `modify_by` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '修改者',
106 | `modify_time` datetime(0) NULL DEFAULT NULL COMMENT '修改时间',
107 | PRIMARY KEY (`user_id`) USING BTREE,
108 | UNIQUE INDEX `email`(`email`) USING BTREE
109 | ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户表' ROW_FORMAT = Dynamic;
110 |
111 | -- ----------------------------
112 | -- Records of t_user
113 | -- ----------------------------
114 | INSERT INTO `t_user` VALUES ('0e191174de65f483d360f0d01e37aa65', 'admin', 'aFJjSQfE+pjqklRTjChVzrK5Ku1uLxkUWP0bwLXn5f5s4AdR1VgcRKwpAVCcGWpT', 1, NULL, NULL, NULL, 1, 'system', now(), NULL, NULL);
115 |
116 | SET FOREIGN_KEY_CHECKS = 1;
117 |
--------------------------------------------------------------------------------
/wall-service/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 |
7 | org.springframework.boot
8 | spring-boot-starter-parent
9 | 2.2.6.RELEASE
10 |
11 |
12 |
13 | cn.ityao
14 | wall-service
15 | 2.0.3
16 |
17 | wall-service
18 |
19 | wall-service
20 |
21 |
22 |
23 | 1.8
24 |
25 |
26 |
27 |
28 | org.springframework.boot
29 | spring-boot-starter
30 |
31 |
32 |
33 | org.springframework.boot
34 | spring-boot-starter-test
35 | test
36 |
37 |
38 | org.junit.vintage
39 | junit-vintage-engine
40 |
41 |
42 |
43 |
44 |
45 |
46 | org.springframework.boot
47 | spring-boot-starter-web
48 |
49 |
50 | org.springframework.boot
51 | spring-boot-starter-test
52 | test
53 |
54 |
55 |
56 |
57 | mysql
58 | mysql-connector-java
59 | 8.0.13
60 |
61 |
62 |
63 |
64 | com.alibaba
65 | druid
66 | 1.1.10
67 |
68 |
69 |
70 |
71 | org.springframework.boot
72 | spring-boot-starter-jdbc
73 |
74 |
75 |
76 |
77 | org.projectlombok
78 | lombok
79 | 1.18.8
80 | provided
81 |
82 |
83 |
84 |
85 | com.baomidou
86 | mybatis-plus-boot-starter
87 | 3.1.1
88 |
89 |
90 |
91 |
92 | com.alibaba
93 | fastjson
94 | 1.2.41
95 |
96 |
97 |
98 |
99 | org.apache.logging.log4j
100 | log4j-core
101 | 2.15.0
102 | compile
103 |
104 |
105 |
106 |
107 | com.auth0
108 | java-jwt
109 | 3.8.2
110 |
111 |
112 |
113 |
114 | cn.hutool
115 | hutool-all
116 | 5.7.12
117 |
118 |
119 |
120 |
121 | org.bytedeco
122 | javacv-platform
123 | 1.5.6
124 |
125 |
126 |
127 | net.coobird
128 | thumbnailator
129 | 0.4.8
130 |
131 |
132 |
133 |
134 | com.drewnoakes
135 | metadata-extractor
136 | 2.7.0
137 |
138 |
139 |
140 |
141 |
142 | wall
143 |
144 |
145 | org.springframework.boot
146 | spring-boot-maven-plugin
147 |
148 |
149 | org.apache.maven.plugins
150 | maven-surefire-plugin
151 | 2.18.1
152 |
153 | true
154 |
155 |
156 |
157 |
158 | org.apache.maven.plugins
159 | maven-compiler-plugin
160 |
161 | ${java.version}
162 | ${java.version}
163 | ${project.build.sourceEncoding}
164 |
165 |
166 | ${java.home}/lib/rt.jar;${java.home}/lib/jce.jar
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
--------------------------------------------------------------------------------
/wall-service/src/main/java/cn/ityao/wall/service/impl/TResourceServiceImpl.java:
--------------------------------------------------------------------------------
1 | package cn.ityao.wall.service.impl;
2 |
3 | import cn.ityao.wall.entity.TResource;
4 | import cn.ityao.wall.mapper.TResourceMapper;
5 | import cn.ityao.wall.service.ITOptionService;
6 | import cn.ityao.wall.service.ITResourceService;
7 | import cn.ityao.wall.util.FileUtils;
8 | import cn.ityao.wall.util.StringUtils;
9 | import com.alibaba.fastjson.JSONObject;
10 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
11 | import net.coobird.thumbnailator.Thumbnails;
12 | import net.coobird.thumbnailator.tasks.UnsupportedFormatException;
13 | import org.springframework.beans.factory.annotation.Autowired;
14 | import org.springframework.stereotype.Service;
15 | import org.springframework.web.multipart.MultipartFile;
16 |
17 | import javax.servlet.http.HttpServletRequest;
18 | import java.io.IOException;
19 | import java.util.*;
20 |
21 | /**
22 | *
23 | * 资源表 服务实现类
24 | *
25 | *
26 | * @author tongyao
27 | * @since 2023-02-14
28 | */
29 | @Service
30 | public class TResourceServiceImpl extends ServiceImpl implements ITResourceService {
31 |
32 | @Autowired
33 | private ITOptionService itOptionService;
34 |
35 | private FileUtils fileUtils = new FileUtils();
36 |
37 | private String resourceSuffix = "";
38 | private String resourceFileName = "";
39 | private String resourcePath = "";
40 |
41 | private List titles = new ArrayList<>();
42 | private List