diff --git a/sky-common/pom.xml b/sky-common/pom.xml
index 3a374b4..2c1d2cc 100644
--- a/sky-common/pom.xml
+++ b/sky-common/pom.xml
@@ -40,6 +40,11 @@
com.aliyun.oss
aliyun-sdk-oss
+
+ org.apache.httpcomponents
+ httpmime
+ 4.5.13
+
javax.xml.bind
jaxb-api
diff --git a/sky-common/src/main/java/com/sky/properties/FileBrowserProperties.java b/sky-common/src/main/java/com/sky/properties/FileBrowserProperties.java
new file mode 100644
index 0000000..2f1955b
--- /dev/null
+++ b/sky-common/src/main/java/com/sky/properties/FileBrowserProperties.java
@@ -0,0 +1,14 @@
+package com.sky.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigurationProperties(prefix = "sky.filebrowser")
+@Data
+public class FileBrowserProperties {
+ private String domain;
+ private String username;
+ private String password;
+}
diff --git a/sky-common/src/main/java/com/sky/utils/AliOssUtil.java b/sky-common/src/main/java/com/sky/utils/AliOssUtil.java
index ac5b027..bd663ba 100644
--- a/sky-common/src/main/java/com/sky/utils/AliOssUtil.java
+++ b/sky-common/src/main/java/com/sky/utils/AliOssUtil.java
@@ -24,79 +24,57 @@ import java.util.UUID;
@Data
@AllArgsConstructor
@Slf4j
-@Component
public class AliOssUtil {
- @Autowired
- private AliOssProperties aliOssProperties;
-// private String endpoint;
-// private String accessKeyId;
-// private String accessKeySecret;
-// private String bucketName;
-//
-// /**
-// * 文件上传
-// *
-// * @param bytes
-// * @param objectName
-// * @return
-// */
-// public String upload(byte[] bytes, String objectName) {
-//
-// // 创建OSSClient实例。
-// OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
-//
-// try {
-// // 创建PutObject请求。
-// ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes));
-// } catch (OSSException oe) {
-// System.out.println("Caught an OSSException, which means your request made it to OSS, "
-// + "but was rejected with an error response for some reason.");
-// System.out.println("Error Message:" + oe.getErrorMessage());
-// System.out.println("Error Code:" + oe.getErrorCode());
-// System.out.println("Request ID:" + oe.getRequestId());
-// System.out.println("Host ID:" + oe.getHostId());
-// } catch (ClientException ce) {
-// System.out.println("Caught an ClientException, which means the client encountered "
-// + "a serious internal problem while trying to communicate with OSS, "
-// + "such as not being able to access the network.");
-// System.out.println("Error Message:" + ce.getMessage());
-// } finally {
-// if (ossClient != null) {
-// ossClient.shutdown();
-// }
-// }
-//
-// //文件访问路径规则 https://BucketName.Endpoint/ObjectName
-// StringBuilder stringBuilder = new StringBuilder("https://");
-// stringBuilder
-// .append(bucketName)
-// .append(".")
-// .append(endpoint)
-// .append("/")
-// .append(objectName);
-//
-// log.info("文件上传到:{}", stringBuilder.toString());
-//
-// return stringBuilder.toString();
-// }
- public String upload(MultipartFile file) throws IOException, com.aliyuncs.exceptions.ClientException {
- InputStream inputStream = file.getInputStream();
- // 避免文件覆盖
- String originalFilename = file.getOriginalFilename();
- String extname = originalFilename.substring(originalFilename.lastIndexOf("."));//文件扩展名
- String fileName = UUID.randomUUID().toString() + extname;
+ private String endpoint;
+ private String accessKeyId;
+ private String accessKeySecret;
+ private String bucketName;
- //上传文件到 OSS
- EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); //从环境变量中获取
- OSS ossClient = new OSSClientBuilder().build(aliOssProperties.getEndpoint(), credentialsProvider);
- PutObjectRequest putObjectRequest = new PutObjectRequest(aliOssProperties.getBucketName(), fileName, inputStream);
- PutObjectResult result = ossClient.putObject(putObjectRequest);
+ /**
+ * 文件上传
+ *
+ * @param bytes
+ * @param objectName
+ * @return
+ */
+ public String upload(byte[] bytes, String objectName) {
- //文件访问路径
- String url = aliOssProperties.getEndpoint().split("//")[0] + "//" + aliOssProperties.getBucketName() + "." + aliOssProperties.getEndpoint().split("//")[1] + "/" + fileName;
- // 关闭ossClient
- ossClient.shutdown();
- return url;// 把上传到oss的路径返回
+ // 创建OSSClient实例。
+ OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+
+ try {
+ // 创建PutObject请求。
+ ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes));
+ } catch (OSSException oe) {
+ System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ + "but was rejected with an error response for some reason.");
+ System.out.println("Error Message:" + oe.getErrorMessage());
+ System.out.println("Error Code:" + oe.getErrorCode());
+ System.out.println("Request ID:" + oe.getRequestId());
+ System.out.println("Host ID:" + oe.getHostId());
+ } catch (ClientException ce) {
+ System.out.println("Caught an ClientException, which means the client encountered "
+ + "a serious internal problem while trying to communicate with OSS, "
+ + "such as not being able to access the network.");
+ System.out.println("Error Message:" + ce.getMessage());
+ } finally {
+ if (ossClient != null) {
+ ossClient.shutdown();
+ }
+ }
+
+ //文件访问路径规则 https://BucketName.Endpoint/ObjectName
+ StringBuilder stringBuilder = new StringBuilder("https://");
+ stringBuilder
+ .append(bucketName)
+ .append(".")
+ .append(endpoint)
+ .append("/")
+ .append(objectName);
+
+ log.info("文件上传到:{}", stringBuilder.toString());
+
+ return stringBuilder.toString();
}
}
diff --git a/sky-common/src/main/java/com/sky/utils/FileBrowserUtil.java b/sky-common/src/main/java/com/sky/utils/FileBrowserUtil.java
new file mode 100644
index 0000000..ab578db
--- /dev/null
+++ b/sky-common/src/main/java/com/sky/utils/FileBrowserUtil.java
@@ -0,0 +1,121 @@
+package com.sky.utils;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.HttpEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.entity.mime.HttpMultipartMode;
+import org.apache.http.entity.mime.MultipartEntityBuilder;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.UUID;
+
+@Slf4j
+@AllArgsConstructor
+@Data
+public class FileBrowserUtil {
+ private String domain;
+ private String username;
+ private String password;
+
+ /**
+ * —— 第一步:登录拿 token ——
+ * 调用 /api/login 接口,返回原始的 JWT token 字符串
+ * curl -X POST "https://fshare.bitday.top/api/login" \
+ * -H "Content-Type: application/json" \
+ * -d '{
+ * "username":"admin",
+ * "password":"asdf14789"
+ * }'
+ * 返回值: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…
+ */
+
+ public String login() throws IOException {
+ String url = domain + "/api/login";
+ // 创建 HttpClient 实例
+ try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
+ // 构造 POST 请求
+ HttpPost httpPost = new HttpPost(url);
+ httpPost.setHeader("Content-Type", "application/json");
+
+ // 构造 JSON body
+ JSONObject json = new JSONObject();
+ json.put("username", username);
+ json.put("password", password);
+
+ // 设置请求体
+ StringEntity requestEntity = new StringEntity(json.toString(), StandardCharsets.UTF_8);
+ requestEntity.setContentType("application/json");
+ httpPost.setEntity(requestEntity);
+
+ // 发送请求并处理响应
+ try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
+ int statusCode = response.getStatusLine().getStatusCode();
+ if (statusCode >= 200 && statusCode < 300) {
+ HttpEntity respEntity = response.getEntity();
+ String body = EntityUtils.toString(respEntity, StandardCharsets.UTF_8);
+ log.info("token:{}",body);
+ // 返回原始返回值(假设就是 JWT token 字符串)
+ return body;
+ } else {
+ throw new IOException("Login failed, HTTP status code: " + statusCode);
+ }
+ }
+ }
+ }
+
+ /**
+ * —— 第二步:上传文件 ——
+ * curl -v -X POST \
+ * "$DOMAIN/api/resources/$REMOTE_PATH?override=true" \ //服务器上相对路径
+ * -H "X-Auth: $TOKEN" \
+ * -F "data=@/path/to/local/photo.jpg" //photo.jpg 以 multipart/form-data 的格式上传
+ */
+ public String upload(byte[] fileBytes, String objectName) throws IOException {
+ // 1.获取唯一文件名
+ // 2. 构造远程路径:固定到 userfiles 目录
+ String remotePath = "userfiles/" + objectName;
+
+ // 3. 获取登录令牌
+ String token = login();
+
+ // 4. URL 编码(保留斜杠)
+ String encodedPath = URLEncoder.encode(remotePath, StandardCharsets.UTF_8.toString())
+ .replace("%2F", "/");
+ String url = domain + "/api/resources/" + encodedPath + "?override=true";
+
+ // 5. 构建并发送 multipart/form-data 请求
+ try (CloseableHttpClient client = HttpClients.createDefault()) {
+ HttpPost post = new HttpPost(url);
+ post.setHeader("X-Auth", token);
+
+ HttpEntity multipart = MultipartEntityBuilder.create()
+ .setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
+ // name="files",filename 用新生成的 objectName
+ .addBinaryBody("files", fileBytes, ContentType.APPLICATION_OCTET_STREAM, objectName)
+ .build();
+
+ post.setEntity(multipart);
+
+ try (CloseableHttpResponse resp = client.execute(post)) {
+ int status = resp.getStatusLine().getStatusCode();
+ String body = EntityUtils.toString(resp.getEntity(), StandardCharsets.UTF_8);
+ if (status >= 200 && status < 300) {
+ log.info("上传成功 → {}", remotePath);
+ return body;
+ } else {
+ throw new IOException("上传失败,HTTP " + status + ",响应:" + body);
+ }
+ }
+ }
+ }
+}
diff --git a/sky-server/pom.xml b/sky-server/pom.xml
index ff9b983..012b22f 100644
--- a/sky-server/pom.xml
+++ b/sky-server/pom.xml
@@ -115,8 +115,8 @@
poi-ooxml
- org.springframework.boot
- spring-boot-starter-security
+ org.springframework.security
+ spring-security-crypto
com.github.pagehelper
@@ -132,6 +132,7 @@
spring-boot-starter-cache
2.7.3
+
diff --git a/sky-server/src/main/java/com/sky/config/FileBrowserConfiguration.java b/sky-server/src/main/java/com/sky/config/FileBrowserConfiguration.java
new file mode 100644
index 0000000..fedc625
--- /dev/null
+++ b/sky-server/src/main/java/com/sky/config/FileBrowserConfiguration.java
@@ -0,0 +1,20 @@
+package com.sky.config;
+import com.sky.properties.FileBrowserProperties;
+import com.sky.utils.FileBrowserUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@Slf4j
+public class FileBrowserConfiguration {
+ @Bean
+ @ConditionalOnMissingBean
+ public FileBrowserUtil fileBrowserUtil(FileBrowserProperties fileBrowserProperties){
+ log.info("开始创建filebrowser上传工具类对象:{}",fileBrowserProperties);
+ return new FileBrowserUtil(fileBrowserProperties.getDomain(),
+ fileBrowserProperties.getUsername(),
+ fileBrowserProperties.getPassword());
+ }
+}
diff --git a/sky-server/src/main/java/com/sky/config/OssConfiguration.java b/sky-server/src/main/java/com/sky/config/OssConfiguration.java
new file mode 100644
index 0000000..8e75d01
--- /dev/null
+++ b/sky-server/src/main/java/com/sky/config/OssConfiguration.java
@@ -0,0 +1,26 @@
+package com.sky.config;
+
+import com.sky.properties.AliOssProperties;
+import com.sky.utils.AliOssUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 配置类,用于创建AliOssUtil对象
+ */
+@Configuration
+@Slf4j
+public class OssConfiguration {
+
+ @Bean
+ @ConditionalOnMissingBean
+ public AliOssUtil aliOssUtil(AliOssProperties aliOssProperties){
+ log.info("开始创建阿里云文件上传工具类对象:{}",aliOssProperties);
+ return new AliOssUtil(aliOssProperties.getEndpoint(),
+ aliOssProperties.getAccessKeyId(),
+ aliOssProperties.getAccessKeySecret(),
+ aliOssProperties.getBucketName());
+ }
+}
diff --git a/sky-server/src/main/java/com/sky/config/SecurityConfiguration.java b/sky-server/src/main/java/com/sky/config/SecurityConfiguration.java
new file mode 100644
index 0000000..13c5c1d
--- /dev/null
+++ b/sky-server/src/main/java/com/sky/config/SecurityConfiguration.java
@@ -0,0 +1,15 @@
+package com.sky.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+@Configuration
+public class SecurityConfiguration {
+ @Bean
+ public PasswordEncoder passwordEncoder() {
+ // 参数 strength 为工作因子,默认为 10,这里可以根据需要进行调整
+ return new BCryptPasswordEncoder(10);
+ }
+}
diff --git a/sky-server/src/main/java/com/sky/config/WebSecurityConfig.java b/sky-server/src/main/java/com/sky/config/WebSecurityConfig.java
deleted file mode 100644
index a6aa253..0000000
--- a/sky-server/src/main/java/com/sky/config/WebSecurityConfig.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package com.sky.config;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
-import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
-
-@Configuration
-@EnableWebSecurity
-public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- http
- .authorizeRequests()
- .anyRequest().permitAll() // 允许所有请求
- .and()
- .csrf().disable(); // 禁用CSRF保护
- }
- @Bean
- public BCryptPasswordEncoder encoder(){
- return new BCryptPasswordEncoder();
- }
-}
-//@Configuration
-//@EnableWebSecurity
-//public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
-// @Override
-// protected void configure(HttpSecurity http) throws Exception {
-// http
-// .authorizeRequests()
-// .anyRequest().authenticated() // 需要认证才能访问
-// .and()
-// .httpBasic() // 使用基本的HTTP认证
-// .and()
-// .csrf().disable(); // 禁用CSRF保护,适用于API服务
-// }
-//
-// @Bean
-// public BCryptPasswordEncoder encoder() {
-// return new BCryptPasswordEncoder();
-// }
-//}
\ No newline at end of file
diff --git a/sky-server/src/main/java/com/sky/controller/admin/CommonController.java b/sky-server/src/main/java/com/sky/controller/admin/CommonController.java
index 343728e..b10a77b 100644
--- a/sky-server/src/main/java/com/sky/controller/admin/CommonController.java
+++ b/sky-server/src/main/java/com/sky/controller/admin/CommonController.java
@@ -1,6 +1,6 @@
package com.sky.controller.admin;
-import com.aliyuncs.exceptions.ClientException;
+import com.sky.constant.MessageConstant;
import com.sky.result.Result;
import com.sky.utils.AliOssUtil;
import io.swagger.annotations.Api;
@@ -13,20 +13,45 @@ import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
+import java.util.UUID;
+/**
+ * 通用接口
+ */
@RestController
@RequestMapping("/admin/common")
@Api(tags = "通用接口")
@Slf4j
-
public class CommonController {
+
@Autowired
private AliOssUtil aliOssUtil;
+
+ /**
+ * 文件上传
+ * @param file
+ * @return
+ */
@PostMapping("/upload")
@ApiOperation("文件上传")
- public Result upload(MultipartFile file) throws IOException, ClientException {
- log.info("文件上传:{}",file);
- String url=aliOssUtil.upload(file);
- return Result.success(url);
+ public Result upload(MultipartFile file){
+ log.info("文件上传:{}",file);
+
+ try {
+ //原始文件名
+ String originalFilename = file.getOriginalFilename();
+ //截取原始文件名的后缀 dfdfdf.png
+ String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
+ //构造新文件名称
+ String objectName = UUID.randomUUID().toString() + extension;
+
+ //文件的访问地址
+ String filePath = aliOssUtil.upload(file.getBytes(), objectName);
+ return Result.success(filePath);
+ } catch (IOException e) {
+ log.error("文件上传失败:{}", e);
+ }
+
+ return Result.error(MessageConstant.UPLOAD_FAILED);
}
}
diff --git a/sky-server/src/main/java/com/sky/service/impl/EmployeeServiceImpl.java b/sky-server/src/main/java/com/sky/service/impl/EmployeeServiceImpl.java
index 6f23cac..6d613e3 100644
--- a/sky-server/src/main/java/com/sky/service/impl/EmployeeServiceImpl.java
+++ b/sky-server/src/main/java/com/sky/service/impl/EmployeeServiceImpl.java
@@ -21,6 +21,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.List;
@@ -32,7 +33,7 @@ public class EmployeeServiceImpl implements EmployeeService {
@Autowired
private EmployeeMapper employeeMapper;
@Autowired
- private BCryptPasswordEncoder bCryptPasswordEncoder;
+ private PasswordEncoder passwordEncoder;
/**
* 员工登录
@@ -54,7 +55,7 @@ public class EmployeeServiceImpl implements EmployeeService {
}
//密码比对
- if (!bCryptPasswordEncoder.matches(password,employee.getPassword())) {
+ if (!passwordEncoder.matches(password,employee.getPassword())) {
//密码错误
throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
}
@@ -73,7 +74,7 @@ public class EmployeeServiceImpl implements EmployeeService {
Employee employee = new Employee();
//对象属性拷贝
BeanUtils.copyProperties(employeeDTO, employee);
- String encodedPassword=bCryptPasswordEncoder.encode(PasswordConstant.DEFAULT_PASSWORD);
+ String encodedPassword=passwordEncoder.encode(PasswordConstant.DEFAULT_PASSWORD);
employee.setPassword(encodedPassword);
employee.setStatus(StatusConstant.ENABLE);
employeeMapper.save(employee);
@@ -113,8 +114,8 @@ public class EmployeeServiceImpl implements EmployeeService {
@Override
public void changePassword(EmployeeChangePasswordDTO employeeChangePasswordDTO) {
Employee employee=employeeMapper.queryById(BaseContext.getCurrentId());
- if(bCryptPasswordEncoder.matches(employeeChangePasswordDTO.getOldPassword(),employee.getPassword())){
- String encodedPassword = bCryptPasswordEncoder.encode(employeeChangePasswordDTO.getNewPassword());
+ if(passwordEncoder.matches(employeeChangePasswordDTO.getOldPassword(),employee.getPassword())){
+ String encodedPassword = passwordEncoder.encode(employeeChangePasswordDTO.getNewPassword());
employee.setPassword(encodedPassword);
employeeMapper.update(employee);
}else
diff --git a/sky-server/src/main/resources/application-dev.yml b/sky-server/src/main/resources/application-dev.yml
index 4a8cc35..11402dc 100644
--- a/sky-server/src/main/resources/application-dev.yml
+++ b/sky-server/src/main/resources/application-dev.yml
@@ -17,6 +17,10 @@ sky:
access-key-secret: AJPJSYc5sdwiZoj8RWzsXtjKR3W8f0
endpoint: https://oss-cn-hangzhou.aliyuncs.com
bucket-name: zyjavaweb
+ filebrowser:
+ domain: https://fshare.bitday.top
+ username: admin
+ password: asdf14789
wechat:
appid: wxa3b6f70e4ffb92cd
diff --git a/sky-server/src/main/resources/application.yml b/sky-server/src/main/resources/application.yml
index 2ba91e8..0486e81 100644
--- a/sky-server/src/main/resources/application.yml
+++ b/sky-server/src/main/resources/application.yml
@@ -55,6 +55,12 @@ sky:
bucket-name: {sky.alioss.bucket-name}
access-key-id: {sky.alioss.access-key-id}
access-key-secret: {sky.alioss.access-key-secret}
+
+ filebrowser:
+ domain: {sky.filebrowser.domain}
+ username: {sky.filebrowser.username}
+ password: {sky.filebrowser.password}
+
wechat:
appid: ${sky.wechat.appid}
secret: ${sky.wechat.secret}