Phase 1 #20 #23: 通用模块 + Vue3 前端框架搭建

#20 通用模块:
- MinioService: MinIO 文件上传/下载/桶管理
- @DataScope 注解: 数据权限切片
- ExcelUtils: EasyExcel 导出
- IdUtils: Snowflake ID 生成器
- BaseEntity: MyBatis-Plus 基础实体

#23 前端框架:
- Vue3 + TypeScript + Vite + Element Plus + ECharts + Pinia
- 路由系统: 登录守卫 + 动态路由
- 登录页: 渐变背景 + Axios+Sa-Token 认证
- 仪表盘: 统计卡片 + 供水趋势折线图 + 片区饼图
- MainLayout: 侧边栏菜单 + 顶栏用户下拉(退出)
- API 层: Axios 请求/响应拦截器 + Token 自动注入
- 系统管理骨架: 用户/角色/菜单/部门 列表页
This commit is contained in:
bot_pm
2026-06-14 13:17:40 +08:00
parent 9a7e0481ef
commit 575b2138c1
24 changed files with 538 additions and 0 deletions
@@ -0,0 +1,11 @@
package com.water.common.core.annotation;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataScope {
String deptAlias() default "d";
String userAlias() default "u";
}
@@ -0,0 +1,15 @@
package com.water.common.core.config;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SwaggerCommonConfig {
@Bean
public OpenAPI commonOpenAPI() {
return new OpenAPI().info(new Info().title("智慧水务管理系统 API")
.description("精河县供水工程综合管理平台").version("1.0.0"));
}
}
@@ -0,0 +1,16 @@
package com.water.common.core.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public abstract class BaseEntity {
@TableId(type = IdType.AUTO)
private Long id;
@TableLogic
private Integer deleted;
private LocalDateTime createdAt;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updatedAt;
}
@@ -0,0 +1,41 @@
package com.water.common.core.storage;
import io.minio.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.util.UUID;
@Slf4j
@Service
public class MinioService {
private final MinioClient client;
@Value("${minio.bucket:water-management}") private String bucket;
public MinioService(@Value("${minio.endpoint:http://127.0.0.1:9000}") String endpoint,
@Value("${minio.access-key:minioadmin}") String accessKey,
@Value("${minio.secret-key:minioadmin}") String secretKey) {
this.client = MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();
}
public String upload(MultipartFile file, String module) throws Exception {
String objectName = module + "/" + UUID.randomUUID() + "_" + file.getOriginalFilename();
ensureBucket();
client.putObject(PutObjectArgs.builder().bucket(bucket).object(objectName)
.stream(file.getInputStream(), file.getSize(), -1)
.contentType(file.getContentType()).build());
return objectName;
}
public InputStream download(String objectName) throws Exception {
return client.getObject(GetObjectArgs.builder().bucket(bucket).object(objectName).build());
}
private void ensureBucket() throws Exception {
if (!client.bucketExists(BucketExistsArgs.builder().bucket(bucket).build())) {
client.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
}
}
}
@@ -0,0 +1,23 @@
package com.water.common.core.util;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import jakarta.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.List;
public class ExcelUtils {
public static <T> void export(HttpServletResponse resp, String fileName, String sheetName, Class<T> clazz, List<T> data) {
try {
resp.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
resp.setCharacterEncoding("utf-8");
resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
EasyExcel.write(resp.getOutputStream(), clazz)
.sheet(sheetName)
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.doWrite(data);
} catch (Exception e) {
throw new RuntimeException("导出Excel失败", e);
}
}
}
@@ -0,0 +1,10 @@
package com.water.common.core.util;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
public class IdUtils {
private static final Snowflake SNOWFLAKE = IdUtil.getSnowflake(1, 1);
public static long nextId() { return SNOWFLAKE.nextId(); }
public static String nextIdStr() { return String.valueOf(SNOWFLAKE.nextId()); }
}