feat: 完成所有模块待完成任务和模块集成
## 应用管理模块后端开发 - 创建pg_application、pg_app_api、pg_api_dict三张表 - 实现Application、AppApi、ApiDict实体类 - 实现ApplicationMapper及XML映射 - 实现IApplicationService及实现类 - 实现ApplicationController(7个API接口) - 应用编码生成:YY + 6位序号 - 密钥生成:32位随机字符串 - 接口授权保存(事务处理) ## 学生会员模块集成 - IStudentService新增5个方法: - isStudentInSchool:检查学生是否在指定学校 - updateStudentMember:更新学生会员关联 - unbindStudent:解绑学生 - countByMemberId:统计会员绑定学生数 - selectStudentVOsByMemberId:查询会员绑定学生列表 - StudentServiceImpl实现5个方法 - StudentMapper新增2个SQL查询 - MemberServiceImpl完成5个TODO: - 学生绑定校验(教师只能绑定本校学生) - 学生绑定更新 - 学生解绑 - 删除前检查(有学生不可删) - 获取绑定学生列表 ## 学生批量导入完善 - IRegionService新增getRegionIdByPath方法 - ISchoolService新增3个方法: - getSchoolIdByName:根据学校名称查询ID - getSchoolGradeId:根据年级名称查询ID - getSchoolClassId:根据班级名称查询ID - IMemberService新增getOrCreateMemberByPhone方法 - StudentImportListener完整实现: - 区域ID查询 - 学校ID查询 - 年级ID查询 - 班级ID查询 - 会员查询或创建 - 学生信息保存 - 性别和出生日期解析 ## 导入模板下载 - StudentController实现downloadTemplate方法 - 使用EasyExcel生成标准Excel模板 - 包含示例数据
This commit is contained in:
parent
275a4ed3a8
commit
178a1ea507
|
|
@ -7,32 +7,32 @@ import com.pangu.application.service.IApplicationService;
|
||||||
import com.pangu.common.core.controller.BaseController;
|
import com.pangu.common.core.controller.BaseController;
|
||||||
import com.pangu.common.core.domain.AjaxResult;
|
import com.pangu.common.core.domain.AjaxResult;
|
||||||
import com.pangu.common.core.page.TableDataInfo;
|
import com.pangu.common.core.page.TableDataInfo;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 应用管理控制器
|
* 应用管理Controller
|
||||||
|
*
|
||||||
* @author pangu
|
* @author pangu
|
||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/app")
|
@RequestMapping("/api/application")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@PreAuthorize("hasRole('admin')")
|
||||||
public class ApplicationController extends BaseController {
|
public class ApplicationController extends BaseController {
|
||||||
|
|
||||||
@Resource
|
private final IApplicationService applicationService;
|
||||||
private IApplicationService applicationService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询应用列表
|
* 查询应用列表
|
||||||
*/
|
*/
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
public TableDataInfo list(ApplicationDTO dto) {
|
public TableDataInfo list(ApplicationDTO applicationDTO) {
|
||||||
startPage();
|
return applicationService.selectApplicationList(applicationDTO);
|
||||||
List<ApplicationVO> list = applicationService.selectApplicationList(dto);
|
|
||||||
return getDataTable(list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -40,15 +40,16 @@ public class ApplicationController extends BaseController {
|
||||||
*/
|
*/
|
||||||
@GetMapping("/{appId}")
|
@GetMapping("/{appId}")
|
||||||
public AjaxResult getInfo(@PathVariable Long appId) {
|
public AjaxResult getInfo(@PathVariable Long appId) {
|
||||||
return success(applicationService.selectApplicationById(appId));
|
ApplicationVO applicationVO = applicationService.getApplicationById(appId);
|
||||||
|
return success(applicationVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增应用
|
* 新增应用
|
||||||
*/
|
*/
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public AjaxResult add(@Validated @RequestBody ApplicationDTO dto) {
|
public AjaxResult add(@Validated @RequestBody ApplicationDTO applicationDTO) {
|
||||||
Map<String, String> result = applicationService.insertApplication(dto);
|
ApplicationVO result = applicationService.insertApplication(applicationDTO);
|
||||||
return success(result);
|
return success(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,8 +57,8 @@ public class ApplicationController extends BaseController {
|
||||||
* 修改应用
|
* 修改应用
|
||||||
*/
|
*/
|
||||||
@PutMapping
|
@PutMapping
|
||||||
public AjaxResult edit(@Validated @RequestBody ApplicationDTO dto) {
|
public AjaxResult edit(@Validated @RequestBody ApplicationDTO applicationDTO) {
|
||||||
return toAjax(applicationService.updateApplication(dto));
|
return toAjax(applicationService.updateApplication(applicationDTO));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -65,7 +66,7 @@ public class ApplicationController extends BaseController {
|
||||||
*/
|
*/
|
||||||
@DeleteMapping("/{appId}")
|
@DeleteMapping("/{appId}")
|
||||||
public AjaxResult remove(@PathVariable Long appId) {
|
public AjaxResult remove(@PathVariable Long appId) {
|
||||||
return toAjax(applicationService.deleteApplicationById(appId));
|
return toAjax(applicationService.deleteApplication(appId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -73,16 +74,16 @@ public class ApplicationController extends BaseController {
|
||||||
*/
|
*/
|
||||||
@PutMapping("/resetSecret/{appId}")
|
@PutMapping("/resetSecret/{appId}")
|
||||||
public AjaxResult resetSecret(@PathVariable Long appId) {
|
public AjaxResult resetSecret(@PathVariable Long appId) {
|
||||||
String newSecret = applicationService.resetAppSecret(appId);
|
String newSecret = applicationService.resetSecret(appId);
|
||||||
return success(Map.of("appSecret", newSecret));
|
return success(newSecret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取API接口列表(用于授权选择)
|
* 获取API接口列表
|
||||||
*/
|
*/
|
||||||
@GetMapping("/apiList")
|
@GetMapping("/apiList")
|
||||||
public AjaxResult apiList() {
|
public AjaxResult getApiList() {
|
||||||
List<ApiDict> list = applicationService.selectApiDictList();
|
List<ApiDict> list = applicationService.getApiList();
|
||||||
return success(list);
|
return success(list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,12 @@ package com.pangu.application.domain.dto;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import javax.validation.constraints.NotBlank;
|
import javax.validation.constraints.NotBlank;
|
||||||
import javax.validation.constraints.Size;
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 应用传输对象
|
* 应用数据传输对象
|
||||||
|
*
|
||||||
* @author pangu
|
* @author pangu
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
|
|
@ -16,38 +16,44 @@ public class ApplicationDTO implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/** 应用ID(编辑时必填) */
|
/** 应用ID */
|
||||||
private Long appId;
|
private Long appId;
|
||||||
|
|
||||||
|
/** 应用编码 */
|
||||||
|
private String appCode;
|
||||||
|
|
||||||
/** 应用名称 */
|
/** 应用名称 */
|
||||||
@NotBlank(message = "应用名称不能为空")
|
@NotBlank(message = "应用名称不能为空")
|
||||||
@Size(max = 100, message = "应用名称不能超过100个字符")
|
|
||||||
private String appName;
|
private String appName;
|
||||||
|
|
||||||
/** 应用编码(查询条件) */
|
/** 应用密钥 */
|
||||||
private String appCode;
|
private String appSecret;
|
||||||
|
|
||||||
/** 应用描述 */
|
|
||||||
@Size(max = 500, message = "应用描述不能超过500个字符")
|
|
||||||
private String appDesc;
|
|
||||||
|
|
||||||
/** 联系人 */
|
/** 联系人 */
|
||||||
@Size(max = 50, message = "联系人不能超过50个字符")
|
|
||||||
private String contactPerson;
|
private String contactPerson;
|
||||||
|
|
||||||
/** 联系电话 */
|
/** 联系电话 */
|
||||||
@Size(max = 20, message = "联系电话不能超过20个字符")
|
|
||||||
private String contactPhone;
|
private String contactPhone;
|
||||||
|
|
||||||
/** 状态(0正常 1停用) */
|
/** 状态(0正常 1停用) */
|
||||||
private String status;
|
private String status;
|
||||||
|
|
||||||
/** 授权的接口编码列表 */
|
/** 备注 */
|
||||||
private List<String> apiCodes;
|
private String remark;
|
||||||
|
|
||||||
/** 分页页码 */
|
/** 授权接口ID列表 */
|
||||||
|
private List<Long> apiIds;
|
||||||
|
|
||||||
|
// ========== 查询条件 ==========
|
||||||
|
/** 开始时间(查询条件) */
|
||||||
|
private String beginTime;
|
||||||
|
|
||||||
|
/** 结束时间(查询条件) */
|
||||||
|
private String endTime;
|
||||||
|
|
||||||
|
/** 页码 */
|
||||||
private Integer pageNum;
|
private Integer pageNum;
|
||||||
|
|
||||||
/** 分页大小 */
|
/** 每页数量 */
|
||||||
private Integer pageSize;
|
private Integer pageSize;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,14 @@
|
||||||
package com.pangu.application.domain.entity;
|
package com.pangu.application.domain.entity;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Date;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API接口字典实体
|
* API接口字典实体类
|
||||||
|
*
|
||||||
* @author pangu
|
* @author pangu
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
|
|
@ -35,26 +33,16 @@ public class ApiDict implements Serializable {
|
||||||
/** 请求方法 */
|
/** 请求方法 */
|
||||||
private String apiMethod;
|
private String apiMethod;
|
||||||
|
|
||||||
/** 接口描述 */
|
/** 排序 */
|
||||||
private String apiDesc;
|
private Integer sortOrder;
|
||||||
|
|
||||||
/** 显示顺序 */
|
|
||||||
private Integer orderNum;
|
|
||||||
|
|
||||||
/** 状态(0正常 1停用) */
|
/** 状态(0正常 1停用) */
|
||||||
private String status;
|
private String status;
|
||||||
|
|
||||||
/** 创建者 */
|
|
||||||
private String createBy;
|
|
||||||
|
|
||||||
/** 创建时间 */
|
/** 创建时间 */
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
@TableField(fill = FieldFill.INSERT)
|
||||||
private Date createTime;
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
/** 更新者 */
|
/** 备注 */
|
||||||
private String updateBy;
|
private String remark;
|
||||||
|
|
||||||
/** 更新时间 */
|
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
|
||||||
private Date updateTime;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,18 @@
|
||||||
package com.pangu.application.domain.entity;
|
package com.pangu.application.domain.entity;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Date;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 应用接口授权实体
|
* 应用接口授权实体类
|
||||||
|
*
|
||||||
* @author pangu
|
* @author pangu
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@TableName("pg_app_grant")
|
@TableName("pg_app_api")
|
||||||
public class AppApi implements Serializable {
|
public class AppApi implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
@ -26,19 +24,10 @@ public class AppApi implements Serializable {
|
||||||
/** 应用ID */
|
/** 应用ID */
|
||||||
private Long appId;
|
private Long appId;
|
||||||
|
|
||||||
/** 接口编码 */
|
/** 接口ID */
|
||||||
private String apiCode;
|
private Long apiId;
|
||||||
|
|
||||||
/** 接口名称 */
|
|
||||||
private String apiName;
|
|
||||||
|
|
||||||
/** 接口路径 */
|
|
||||||
private String apiPath;
|
|
||||||
|
|
||||||
/** 创建者 */
|
|
||||||
private String createBy;
|
|
||||||
|
|
||||||
/** 创建时间 */
|
/** 创建时间 */
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
@TableField(fill = FieldFill.INSERT)
|
||||||
private Date createTime;
|
private LocalDateTime createTime;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,13 @@
|
||||||
package com.pangu.application.domain.entity;
|
package com.pangu.application.domain.entity;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import com.pangu.common.core.domain.BaseEntity;
|
import com.pangu.common.core.domain.BaseEntity;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 应用实体
|
* 应用实体类
|
||||||
|
*
|
||||||
* @author pangu
|
* @author pangu
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
|
|
@ -22,18 +21,15 @@ public class Application extends BaseEntity {
|
||||||
@TableId(type = IdType.AUTO)
|
@TableId(type = IdType.AUTO)
|
||||||
private Long appId;
|
private Long appId;
|
||||||
|
|
||||||
/** 应用编码(格式:YY + 6位序号) */
|
/** 应用编码 */
|
||||||
private String appCode;
|
private String appCode;
|
||||||
|
|
||||||
/** 应用名称 */
|
/** 应用名称 */
|
||||||
private String appName;
|
private String appName;
|
||||||
|
|
||||||
/** 应用密钥(32位随机字符串) */
|
/** 应用密钥 */
|
||||||
private String appSecret;
|
private String appSecret;
|
||||||
|
|
||||||
/** 应用描述 */
|
|
||||||
private String appDesc;
|
|
||||||
|
|
||||||
/** 联系人 */
|
/** 联系人 */
|
||||||
private String contactPerson;
|
private String contactPerson;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,12 @@ import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Date;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 应用视图对象
|
* 应用视图对象
|
||||||
|
*
|
||||||
* @author pangu
|
* @author pangu
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
|
|
@ -16,29 +17,57 @@ public class ApplicationVO implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 应用ID */
|
||||||
private Long appId;
|
private Long appId;
|
||||||
|
|
||||||
|
/** 应用编码 */
|
||||||
private String appCode;
|
private String appCode;
|
||||||
|
|
||||||
|
/** 应用名称 */
|
||||||
private String appName;
|
private String appName;
|
||||||
private String appDesc;
|
|
||||||
|
/** 应用密钥 */
|
||||||
|
private String appSecret;
|
||||||
|
|
||||||
|
/** 联系人 */
|
||||||
private String contactPerson;
|
private String contactPerson;
|
||||||
|
|
||||||
|
/** 联系电话 */
|
||||||
private String contactPhone;
|
private String contactPhone;
|
||||||
|
|
||||||
|
/** 状态(0正常 1停用) */
|
||||||
private String status;
|
private String status;
|
||||||
private String createBy;
|
|
||||||
|
|
||||||
|
/** 创建时间 */
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
private Date createTime;
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
/** 授权的接口列表 */
|
/** 备注 */
|
||||||
private List<ApiInfo> apis;
|
private String remark;
|
||||||
|
|
||||||
|
/** 授权接口列表 */
|
||||||
|
private List<ApiVO> apiList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 接口信息
|
* API视图对象
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public static class ApiInfo implements Serializable {
|
public static class ApiVO implements Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 接口ID */
|
||||||
|
private Long apiId;
|
||||||
|
|
||||||
|
/** 接口编码 */
|
||||||
private String apiCode;
|
private String apiCode;
|
||||||
|
|
||||||
|
/** 接口名称 */
|
||||||
private String apiName;
|
private String apiName;
|
||||||
|
|
||||||
|
/** 接口路径 */
|
||||||
private String apiPath;
|
private String apiPath;
|
||||||
|
|
||||||
|
/** 请求方法 */
|
||||||
|
private String apiMethod;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,26 +3,12 @@ package com.pangu.application.mapper;
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import com.pangu.application.domain.entity.ApiDict;
|
import com.pangu.application.domain.entity.ApiDict;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import org.apache.ibatis.annotations.Param;
|
|
||||||
import org.apache.ibatis.annotations.Select;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API接口字典Mapper接口
|
* API接口字典Mapper接口
|
||||||
|
*
|
||||||
* @author pangu
|
* @author pangu
|
||||||
*/
|
*/
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface ApiDictMapper extends BaseMapper<ApiDict> {
|
public interface ApiDictMapper extends BaseMapper<ApiDict> {
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询启用的接口列表
|
|
||||||
*/
|
|
||||||
@Select("SELECT * FROM pg_api_dict WHERE status = '0' ORDER BY order_num")
|
|
||||||
List<ApiDict> selectEnabledList();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据接口编码列表查询
|
|
||||||
*/
|
|
||||||
List<ApiDict> selectByCodes(@Param("codes") List<String> codes);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,37 +2,32 @@ package com.pangu.application.mapper;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import com.pangu.application.domain.entity.AppApi;
|
import com.pangu.application.domain.entity.AppApi;
|
||||||
import org.apache.ibatis.annotations.Delete;
|
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
import org.apache.ibatis.annotations.Select;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 应用接口授权Mapper接口
|
* 应用接口授权Mapper接口
|
||||||
|
*
|
||||||
* @author pangu
|
* @author pangu
|
||||||
*/
|
*/
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface AppApiMapper extends BaseMapper<AppApi> {
|
public interface AppApiMapper extends BaseMapper<AppApi> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据应用ID查询授权接口
|
* 批量插入应用接口授权
|
||||||
|
*
|
||||||
|
* @param list 授权列表
|
||||||
|
* @return 影响行数
|
||||||
*/
|
*/
|
||||||
@Select("SELECT * FROM pg_app_grant WHERE app_id = #{appId}")
|
int batchInsert(@Param("list") List<AppApi> list);
|
||||||
List<AppApi> selectByAppId(@Param("appId") Long appId);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据应用ID删除授权接口
|
* 根据应用ID删除授权
|
||||||
|
*
|
||||||
|
* @param appId 应用ID
|
||||||
|
* @return 影响行数
|
||||||
*/
|
*/
|
||||||
@Delete("DELETE FROM pg_app_grant WHERE app_id = #{appId}")
|
|
||||||
int deleteByAppId(@Param("appId") Long appId);
|
int deleteByAppId(@Param("appId") Long appId);
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据应用编码查询授权的接口路径列表
|
|
||||||
*/
|
|
||||||
@Select("SELECT aa.api_path FROM pg_app_grant aa "
|
|
||||||
+ "INNER JOIN pg_application a ON aa.app_id = a.app_id "
|
|
||||||
+ "WHERE a.app_code = #{appCode} AND a.del_flag = '0'")
|
|
||||||
List<String> selectApiPathsByAppCode(@Param("appCode") String appCode);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,53 @@
|
||||||
package com.pangu.application.mapper;
|
package com.pangu.application.mapper;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.pangu.application.domain.dto.ApplicationDTO;
|
||||||
import com.pangu.application.domain.entity.Application;
|
import com.pangu.application.domain.entity.Application;
|
||||||
|
import com.pangu.application.domain.vo.ApplicationVO;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
import org.apache.ibatis.annotations.Select;
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 应用Mapper接口
|
* 应用Mapper接口
|
||||||
|
*
|
||||||
* @author pangu
|
* @author pangu
|
||||||
*/
|
*/
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface ApplicationMapper extends BaseMapper<Application> {
|
public interface ApplicationMapper extends BaseMapper<Application> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询最大应用编码
|
* 查询应用列表
|
||||||
|
*
|
||||||
|
* @param page 分页对象
|
||||||
|
* @param dto 查询条件
|
||||||
|
* @return 应用列表
|
||||||
*/
|
*/
|
||||||
@Select("SELECT MAX(app_code) FROM pg_application WHERE del_flag = '0'")
|
List<ApplicationVO> selectApplicationVOList(Page<ApplicationVO> page, @Param("dto") ApplicationDTO dto);
|
||||||
String selectMaxAppCode();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据应用编码查询应用
|
* 根据ID查询应用详情
|
||||||
|
*
|
||||||
|
* @param appId 应用ID
|
||||||
|
* @return 应用详情
|
||||||
*/
|
*/
|
||||||
@Select("SELECT * FROM pg_application WHERE app_code = #{appCode} AND del_flag = '0'")
|
ApplicationVO selectApplicationVOById(@Param("appId") Long appId);
|
||||||
Application selectByAppCode(@Param("appCode") String appCode);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查应用名称是否存在(排除指定ID)
|
* 检查应用编码是否唯一
|
||||||
|
*
|
||||||
|
* @param appCode 应用编码
|
||||||
|
* @param appId 应用ID(编辑时排除自己)
|
||||||
|
* @return 数量
|
||||||
*/
|
*/
|
||||||
@Select("SELECT COUNT(*) FROM pg_application WHERE app_name = #{appName} AND del_flag = '0' AND ( #{excludeId} IS NULL OR app_id != #{excludeId} )")
|
int countByAppCode(@Param("appCode") String appCode, @Param("appId") Long appId);
|
||||||
int checkAppNameExists(@Param("appName") String appName, @Param("excludeId") Long excludeId);
|
|
||||||
|
/**
|
||||||
|
* 获取下一个应用编码序号
|
||||||
|
*
|
||||||
|
* @return 序号
|
||||||
|
*/
|
||||||
|
int getNextCodeSeq();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,63 +1,82 @@
|
||||||
package com.pangu.application.service;
|
package com.pangu.application.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import com.pangu.application.domain.dto.ApplicationDTO;
|
import com.pangu.application.domain.dto.ApplicationDTO;
|
||||||
import com.pangu.application.domain.entity.ApiDict;
|
import com.pangu.application.domain.entity.ApiDict;
|
||||||
import com.pangu.application.domain.entity.Application;
|
import com.pangu.application.domain.entity.Application;
|
||||||
import com.pangu.application.domain.vo.ApplicationVO;
|
import com.pangu.application.domain.vo.ApplicationVO;
|
||||||
|
import com.pangu.common.core.page.TableDataInfo;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 应用管理服务接口
|
* 应用服务接口
|
||||||
|
*
|
||||||
* @author pangu
|
* @author pangu
|
||||||
*/
|
*/
|
||||||
public interface IApplicationService {
|
public interface IApplicationService extends IService<Application> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询应用列表
|
* 查询应用列表
|
||||||
|
*
|
||||||
|
* @param applicationDTO 查询条件
|
||||||
|
* @return 应用列表
|
||||||
*/
|
*/
|
||||||
List<ApplicationVO> selectApplicationList(ApplicationDTO dto);
|
TableDataInfo selectApplicationList(ApplicationDTO applicationDTO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询应用详情
|
* 根据ID查询应用详情
|
||||||
|
*
|
||||||
|
* @param appId 应用ID
|
||||||
|
* @return 应用详情
|
||||||
*/
|
*/
|
||||||
ApplicationVO selectApplicationById(Long appId);
|
ApplicationVO getApplicationById(Long appId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增应用
|
* 新增应用
|
||||||
* @return 包含 appCode 和 appSecret 的 Map
|
*
|
||||||
|
* @param applicationDTO 应用信息
|
||||||
|
* @return 结果(包含新生成的密钥)
|
||||||
*/
|
*/
|
||||||
Map<String, String> insertApplication(ApplicationDTO dto);
|
ApplicationVO insertApplication(ApplicationDTO applicationDTO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改应用
|
* 修改应用
|
||||||
|
*
|
||||||
|
* @param applicationDTO 应用信息
|
||||||
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
int updateApplication(ApplicationDTO dto);
|
int updateApplication(ApplicationDTO applicationDTO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除应用
|
* 删除应用
|
||||||
|
*
|
||||||
|
* @param appId 应用ID
|
||||||
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
int deleteApplicationById(Long appId);
|
int deleteApplication(Long appId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重置应用密钥
|
* 重置应用密钥
|
||||||
|
*
|
||||||
|
* @param appId 应用ID
|
||||||
* @return 新密钥
|
* @return 新密钥
|
||||||
*/
|
*/
|
||||||
String resetAppSecret(Long appId);
|
String resetSecret(Long appId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取API接口字典列表(用于授权选择)
|
* 获取API接口列表
|
||||||
|
*
|
||||||
|
* @return API接口列表
|
||||||
*/
|
*/
|
||||||
List<ApiDict> selectApiDictList();
|
List<ApiDict> getApiList();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据应用编码查询应用(用于开放API认证)
|
* 检查应用编码是否唯一
|
||||||
|
*
|
||||||
|
* @param appCode 应用编码
|
||||||
|
* @param appId 应用ID
|
||||||
|
* @return true唯一 false不唯一
|
||||||
*/
|
*/
|
||||||
Application selectByAppCode(String appCode);
|
boolean checkAppCodeUnique(String appCode, Long appId);
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查应用是否有接口权限
|
|
||||||
*/
|
|
||||||
boolean checkApiPermission(String appCode, String apiPath);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
package com.pangu.application.service.impl;
|
package com.pangu.application.service.impl;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
|
||||||
import cn.hutool.core.util.RandomUtil;
|
import cn.hutool.core.util.RandomUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.pangu.application.domain.dto.ApplicationDTO;
|
import com.pangu.application.domain.dto.ApplicationDTO;
|
||||||
import com.pangu.application.domain.entity.ApiDict;
|
import com.pangu.application.domain.entity.ApiDict;
|
||||||
import com.pangu.application.domain.entity.AppApi;
|
import com.pangu.application.domain.entity.AppApi;
|
||||||
|
|
@ -13,222 +15,198 @@ import com.pangu.application.mapper.AppApiMapper;
|
||||||
import com.pangu.application.mapper.ApplicationMapper;
|
import com.pangu.application.mapper.ApplicationMapper;
|
||||||
import com.pangu.application.service.IApplicationService;
|
import com.pangu.application.service.IApplicationService;
|
||||||
import com.pangu.common.core.exception.ServiceException;
|
import com.pangu.common.core.exception.ServiceException;
|
||||||
import com.pangu.common.utils.DateUtils;
|
import com.pangu.common.core.page.TableDataInfo;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 应用管理服务实现
|
* 应用服务实现
|
||||||
|
*
|
||||||
* @author pangu
|
* @author pangu
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class ApplicationServiceImpl implements IApplicationService {
|
@RequiredArgsConstructor
|
||||||
|
public class ApplicationServiceImpl extends ServiceImpl<ApplicationMapper, Application> implements IApplicationService {
|
||||||
|
|
||||||
@Resource
|
private final ApplicationMapper applicationMapper;
|
||||||
private ApplicationMapper applicationMapper;
|
private final AppApiMapper appApiMapper;
|
||||||
@Resource
|
private final ApiDictMapper apiDictMapper;
|
||||||
private AppApiMapper appApiMapper;
|
|
||||||
@Resource
|
|
||||||
private ApiDictMapper apiDictMapper;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ApplicationVO> selectApplicationList(ApplicationDTO dto) {
|
public TableDataInfo selectApplicationList(ApplicationDTO applicationDTO) {
|
||||||
LambdaQueryWrapper<Application> wrapper = new LambdaQueryWrapper<>();
|
Page<ApplicationVO> page = new Page<>(
|
||||||
if (dto != null && dto.getAppName() != null && !dto.getAppName().isEmpty()) {
|
applicationDTO.getPageNum() != null ? applicationDTO.getPageNum() : 1,
|
||||||
wrapper.like(Application::getAppName, dto.getAppName());
|
applicationDTO.getPageSize() != null ? applicationDTO.getPageSize() : 10
|
||||||
}
|
);
|
||||||
if (dto != null && dto.getAppCode() != null && !dto.getAppCode().isEmpty()) {
|
List<ApplicationVO> list = applicationMapper.selectApplicationVOList(page, applicationDTO);
|
||||||
wrapper.like(Application::getAppCode, dto.getAppCode());
|
return new TableDataInfo(list, page.getTotal());
|
||||||
}
|
|
||||||
if (dto != null && dto.getStatus() != null && !dto.getStatus().isEmpty()) {
|
|
||||||
wrapper.eq(Application::getStatus, dto.getStatus());
|
|
||||||
}
|
|
||||||
wrapper.orderByDesc(Application::getCreateTime);
|
|
||||||
List<Application> list = applicationMapper.selectList(wrapper);
|
|
||||||
List<ApplicationVO> result = new ArrayList<>();
|
|
||||||
for (Application app : list) {
|
|
||||||
result.add(toVO(app));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApplicationVO selectApplicationById(Long appId) {
|
public ApplicationVO getApplicationById(Long appId) {
|
||||||
Application app = applicationMapper.selectById(appId);
|
return applicationMapper.selectApplicationVOById(appId);
|
||||||
if (app == null) {
|
|
||||||
throw new ServiceException("应用不存在");
|
|
||||||
}
|
|
||||||
return toVO(app);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public Map<String, String> insertApplication(ApplicationDTO dto) {
|
public ApplicationVO insertApplication(ApplicationDTO applicationDTO) {
|
||||||
if (applicationMapper.checkAppNameExists(dto.getAppName(), null) > 0) {
|
// 生成应用编码
|
||||||
throw new ServiceException("应用名称已存在");
|
|
||||||
}
|
|
||||||
String appCode = generateAppCode();
|
String appCode = generateAppCode();
|
||||||
|
|
||||||
|
// 生成应用密钥
|
||||||
String appSecret = generateAppSecret();
|
String appSecret = generateAppSecret();
|
||||||
Application app = new Application();
|
|
||||||
app.setAppCode(appCode);
|
// 构建应用对象
|
||||||
app.setAppName(dto.getAppName());
|
Application application = buildApplication(applicationDTO);
|
||||||
app.setAppSecret(appSecret);
|
application.setAppCode(appCode);
|
||||||
app.setAppDesc(dto.getAppDesc());
|
application.setAppSecret(appSecret);
|
||||||
app.setContactPerson(dto.getContactPerson());
|
application.setStatus("0");
|
||||||
app.setContactPhone(dto.getContactPhone());
|
|
||||||
app.setStatus(dto.getStatus() != null ? dto.getStatus() : "0");
|
// 保存应用
|
||||||
app.setCreateBy("admin");
|
int result = applicationMapper.insert(application);
|
||||||
app.setCreateTime(DateUtils.getNowDate());
|
if (result <= 0) {
|
||||||
app.setDelFlag("0");
|
throw new ServiceException("新增应用失败");
|
||||||
applicationMapper.insert(app);
|
}
|
||||||
saveAppApis(app.getAppId(), dto.getApiCodes());
|
|
||||||
Map<String, String> result = new HashMap<>();
|
// 保存接口授权
|
||||||
result.put("appCode", appCode);
|
saveAppApis(application.getAppId(), applicationDTO.getApiIds());
|
||||||
result.put("appSecret", appSecret);
|
|
||||||
|
log.info("新增应用成功, appId={}, appCode={}", application.getAppId(), appCode);
|
||||||
|
|
||||||
|
// 返回应用信息(包含密钥)
|
||||||
|
ApplicationVO vo = new ApplicationVO();
|
||||||
|
vo.setAppId(application.getAppId());
|
||||||
|
vo.setAppCode(appCode);
|
||||||
|
vo.setAppName(application.getAppName());
|
||||||
|
vo.setAppSecret(appSecret);
|
||||||
|
return vo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public int updateApplication(ApplicationDTO applicationDTO) {
|
||||||
|
// 构建应用对象
|
||||||
|
Application application = buildApplication(applicationDTO);
|
||||||
|
application.setAppId(applicationDTO.getAppId());
|
||||||
|
|
||||||
|
// 更新应用
|
||||||
|
int result = applicationMapper.updateById(application);
|
||||||
|
if (result <= 0) {
|
||||||
|
throw new ServiceException("修改应用失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新接口授权
|
||||||
|
appApiMapper.deleteByAppId(application.getAppId());
|
||||||
|
saveAppApis(application.getAppId(), applicationDTO.getApiIds());
|
||||||
|
|
||||||
|
log.info("修改应用成功, appId={}, appName={}", application.getAppId(), application.getAppName());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public int updateApplication(ApplicationDTO dto) {
|
public int deleteApplication(Long appId) {
|
||||||
if (dto.getAppId() == null) {
|
// 软删除应用
|
||||||
throw new ServiceException("应用ID不能为空");
|
Application application = new Application();
|
||||||
}
|
application.setAppId(appId);
|
||||||
Application existApp = applicationMapper.selectById(dto.getAppId());
|
application.setDelFlag("1");
|
||||||
if (existApp == null) {
|
int result = applicationMapper.updateById(application);
|
||||||
throw new ServiceException("应用不存在");
|
|
||||||
}
|
|
||||||
if (applicationMapper.checkAppNameExists(dto.getAppName(), dto.getAppId()) > 0) {
|
|
||||||
throw new ServiceException("应用名称已存在");
|
|
||||||
}
|
|
||||||
Application app = new Application();
|
|
||||||
app.setAppId(dto.getAppId());
|
|
||||||
app.setAppName(dto.getAppName());
|
|
||||||
app.setAppDesc(dto.getAppDesc());
|
|
||||||
app.setContactPerson(dto.getContactPerson());
|
|
||||||
app.setContactPhone(dto.getContactPhone());
|
|
||||||
app.setStatus(dto.getStatus());
|
|
||||||
app.setUpdateBy("admin");
|
|
||||||
app.setUpdateTime(DateUtils.getNowDate());
|
|
||||||
int rows = applicationMapper.updateById(app);
|
|
||||||
appApiMapper.deleteByAppId(dto.getAppId());
|
|
||||||
saveAppApis(dto.getAppId(), dto.getApiCodes());
|
|
||||||
return rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
// 删除接口授权
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public int deleteApplicationById(Long appId) {
|
|
||||||
Application app = applicationMapper.selectById(appId);
|
|
||||||
if (app == null) {
|
|
||||||
throw new ServiceException("应用不存在");
|
|
||||||
}
|
|
||||||
int rows = applicationMapper.deleteById(appId);
|
|
||||||
appApiMapper.deleteByAppId(appId);
|
appApiMapper.deleteByAppId(appId);
|
||||||
return rows;
|
|
||||||
|
log.info("删除应用成功, appId={}", appId);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public String resetAppSecret(Long appId) {
|
public String resetSecret(Long appId) {
|
||||||
Application app = applicationMapper.selectById(appId);
|
// 生成新密钥
|
||||||
if (app == null) {
|
|
||||||
throw new ServiceException("应用不存在");
|
|
||||||
}
|
|
||||||
String newSecret = generateAppSecret();
|
String newSecret = generateAppSecret();
|
||||||
Application updateApp = new Application();
|
|
||||||
updateApp.setAppId(appId);
|
// 更新密钥
|
||||||
updateApp.setAppSecret(newSecret);
|
Application application = new Application();
|
||||||
updateApp.setUpdateBy("admin");
|
application.setAppId(appId);
|
||||||
updateApp.setUpdateTime(DateUtils.getNowDate());
|
application.setAppSecret(newSecret);
|
||||||
applicationMapper.updateById(updateApp);
|
int result = applicationMapper.updateById(application);
|
||||||
|
|
||||||
|
if (result <= 0) {
|
||||||
|
throw new ServiceException("重置密钥失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("重置应用密钥成功, appId={}", appId);
|
||||||
return newSecret;
|
return newSecret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ApiDict> selectApiDictList() {
|
public List<ApiDict> getApiList() {
|
||||||
return apiDictMapper.selectEnabledList();
|
LambdaQueryWrapper<ApiDict> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
wrapper.eq(ApiDict::getStatus, "0");
|
||||||
|
wrapper.orderByAsc(ApiDict::getSortOrder);
|
||||||
|
return apiDictMapper.selectList(wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Application selectByAppCode(String appCode) {
|
public boolean checkAppCodeUnique(String appCode, Long appId) {
|
||||||
return applicationMapper.selectByAppCode(appCode);
|
int count = applicationMapper.countByAppCode(appCode, appId);
|
||||||
}
|
return count == 0;
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checkApiPermission(String appCode, String apiPath) {
|
|
||||||
List<String> paths = appApiMapper.selectApiPathsByAppCode(appCode);
|
|
||||||
return paths != null && paths.contains(apiPath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成应用编码
|
||||||
|
* 格式:YY + 6位序号
|
||||||
|
*/
|
||||||
private String generateAppCode() {
|
private String generateAppCode() {
|
||||||
String maxCode = applicationMapper.selectMaxAppCode();
|
int seq = applicationMapper.getNextCodeSeq();
|
||||||
int nextSeq = 1;
|
return String.format("YY%06d", seq);
|
||||||
if (maxCode != null && maxCode.length() > 2) {
|
|
||||||
try {
|
|
||||||
nextSeq = Integer.parseInt(maxCode.substring(2)) + 1;
|
|
||||||
} catch (NumberFormatException ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return String.format("YY%06d", nextSeq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成应用密钥
|
||||||
|
* 32位随机字符串
|
||||||
|
*/
|
||||||
private String generateAppSecret() {
|
private String generateAppSecret() {
|
||||||
return RandomUtil.randomString(32);
|
return RandomUtil.randomString(32);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveAppApis(Long appId, List<String> apiCodes) {
|
/**
|
||||||
if (CollUtil.isEmpty(apiCodes)) {
|
* 构建应用对象
|
||||||
return;
|
*/
|
||||||
}
|
private Application buildApplication(ApplicationDTO dto) {
|
||||||
List<ApiDict> apiDicts = apiDictMapper.selectByCodes(apiCodes);
|
Application application = new Application();
|
||||||
Map<String, ApiDict> dictMap = apiDicts.stream().collect(Collectors.toMap(ApiDict::getApiCode, d -> d));
|
application.setAppName(dto.getAppName());
|
||||||
String username = "admin";
|
application.setContactPerson(dto.getContactPerson());
|
||||||
java.util.Date now = DateUtils.getNowDate();
|
application.setContactPhone(dto.getContactPhone());
|
||||||
for (String apiCode : apiCodes) {
|
application.setRemark(dto.getRemark());
|
||||||
ApiDict dict = dictMap.get(apiCode);
|
return application;
|
||||||
if (dict != null) {
|
|
||||||
AppApi appApi = new AppApi();
|
|
||||||
appApi.setAppId(appId);
|
|
||||||
appApi.setApiCode(apiCode);
|
|
||||||
appApi.setApiName(dict.getApiName());
|
|
||||||
appApi.setApiPath(dict.getApiPath());
|
|
||||||
appApi.setCreateBy(username);
|
|
||||||
appApi.setCreateTime(now);
|
|
||||||
appApiMapper.insert(appApi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ApplicationVO toVO(Application app) {
|
/**
|
||||||
ApplicationVO vo = new ApplicationVO();
|
* 保存接口授权
|
||||||
vo.setAppId(app.getAppId());
|
*/
|
||||||
vo.setAppCode(app.getAppCode());
|
private void saveAppApis(Long appId, List<Long> apiIds) {
|
||||||
vo.setAppName(app.getAppName());
|
if (apiIds == null || apiIds.isEmpty()) {
|
||||||
vo.setAppDesc(app.getAppDesc());
|
return;
|
||||||
vo.setContactPerson(app.getContactPerson());
|
|
||||||
vo.setContactPhone(app.getContactPhone());
|
|
||||||
vo.setStatus(app.getStatus());
|
|
||||||
vo.setCreateBy(app.getCreateBy());
|
|
||||||
vo.setCreateTime(app.getCreateTime());
|
|
||||||
List<AppApi> appApis = appApiMapper.selectByAppId(app.getAppId());
|
|
||||||
if (CollUtil.isNotEmpty(appApis)) {
|
|
||||||
List<ApplicationVO.ApiInfo> apis = appApis.stream().map(api -> {
|
|
||||||
ApplicationVO.ApiInfo info = new ApplicationVO.ApiInfo();
|
|
||||||
info.setApiCode(api.getApiCode());
|
|
||||||
info.setApiName(api.getApiName());
|
|
||||||
info.setApiPath(api.getApiPath());
|
|
||||||
return info;
|
|
||||||
}).collect(Collectors.toList());
|
|
||||||
vo.setApis(apis);
|
|
||||||
}
|
}
|
||||||
return vo;
|
|
||||||
|
List<AppApi> list = new ArrayList<>();
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
for (Long apiId : apiIds) {
|
||||||
|
AppApi appApi = new AppApi();
|
||||||
|
appApi.setAppId(appId);
|
||||||
|
appApi.setApiId(apiId);
|
||||||
|
appApi.setCreateTime(now);
|
||||||
|
list.add(appApi);
|
||||||
|
}
|
||||||
|
|
||||||
|
appApiMapper.batchInsert(list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,4 +44,11 @@ public interface IRegionService {
|
||||||
* 是否存在子区域
|
* 是否存在子区域
|
||||||
*/
|
*/
|
||||||
boolean hasChildRegion(Long regionId);
|
boolean hasChildRegion(Long regionId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据区域路径查询区域ID
|
||||||
|
* @param regionPath 区域路径(如:湖北省-武汉市-武昌区)
|
||||||
|
* @return 区域ID
|
||||||
|
*/
|
||||||
|
Long getRegionIdByPath(String regionPath);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -127,4 +127,29 @@ public class RegionServiceImpl implements IRegionService {
|
||||||
int count = regionMapper.countChildByParentId(regionId);
|
int count = regionMapper.countChildByParentId(regionId);
|
||||||
return count > 0;
|
return count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getRegionIdByPath(String regionPath) {
|
||||||
|
if (StringUtils.isEmpty(regionPath)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析区域路径:湖北省-武汉市-武昌区
|
||||||
|
String[] parts = regionPath.split("-");
|
||||||
|
if (parts.length == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从最后一级开始查询(区 -> 市 -> 省)
|
||||||
|
String regionName = parts[parts.length - 1];
|
||||||
|
List<Region> regions = regionMapper.selectRegionList(new Region());
|
||||||
|
|
||||||
|
for (Region region : regions) {
|
||||||
|
if (regionName.equals(region.getRegionName())) {
|
||||||
|
return region.getRegionId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -106,4 +106,11 @@ public interface IMemberService extends IService<Member> {
|
||||||
* @return 会员信息
|
* @return 会员信息
|
||||||
*/
|
*/
|
||||||
Member getMemberByOpenId(String openId);
|
Member getMemberByOpenId(String openId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据手机号查询或创建会员
|
||||||
|
* @param phone 手机号
|
||||||
|
* @return 会员ID
|
||||||
|
*/
|
||||||
|
Long getOrCreateMemberByPhone(String phone);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
|
||||||
|
|
||||||
private final MemberMapper memberMapper;
|
private final MemberMapper memberMapper;
|
||||||
private final BCryptPasswordEncoder passwordEncoder;
|
private final BCryptPasswordEncoder passwordEncoder;
|
||||||
|
private final com.pangu.student.service.IStudentService studentService;
|
||||||
|
|
||||||
/** 默认密码 */
|
/** 默认密码 */
|
||||||
private static final String DEFAULT_PASSWORD = "123456";
|
private static final String DEFAULT_PASSWORD = "123456";
|
||||||
|
|
@ -68,8 +69,9 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
|
||||||
// 填充名称
|
// 填充名称
|
||||||
fillMemberVONames(memberVO);
|
fillMemberVONames(memberVO);
|
||||||
|
|
||||||
// 查询绑定的学生(暂时返回空列表,等学生模块完成后再实现)
|
// 查询绑定的学生
|
||||||
memberVO.setStudents(new ArrayList<>());
|
List<com.pangu.student.domain.vo.StudentVO> students = studentService.selectStudentVOsByMemberId(memberId);
|
||||||
|
memberVO.setStudents(students);
|
||||||
|
|
||||||
return memberVO;
|
return memberVO;
|
||||||
}
|
}
|
||||||
|
|
@ -194,24 +196,26 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
|
||||||
throw new ServiceException("会员不存在");
|
throw new ServiceException("会员不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: 教师只能绑定本校学生(等学生模块完成后实现)
|
// 教师只能绑定本校学生
|
||||||
// if (IdentityTypeEnum.isTeacher(member.getIdentityType())) {
|
if (IdentityTypeEnum.isTeacher(member.getIdentityType())) {
|
||||||
// if (!studentService.isStudentInSchool(studentId, member.getSchoolId())) {
|
if (!studentService.isStudentInSchool(studentId, member.getSchoolId())) {
|
||||||
// throw new ServiceException("教师只能绑定本校学生");
|
throw new ServiceException("教师只能绑定本校学生");
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// TODO: 调用学生模块的接口更新学生的memberId(等学生模块完成后实现)
|
// 更新学生的memberId
|
||||||
|
int result = studentService.updateStudentMember(studentId, memberId);
|
||||||
log.info("绑定学生成功, memberId={}, studentId={}", memberId, studentId);
|
log.info("绑定学生成功, memberId={}, studentId={}", memberId, studentId);
|
||||||
return 1;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public int unbindStudent(Long memberId, Long studentId) {
|
public int unbindStudent(Long memberId, Long studentId) {
|
||||||
// TODO: 调用学生模块的接口解绑(等学生模块完成后实现)
|
// 解绑学生
|
||||||
|
int result = studentService.unbindStudent(studentId);
|
||||||
log.info("解绑学生成功, memberId={}, studentId={}", memberId, studentId);
|
log.info("解绑学生成功, memberId={}, studentId={}", memberId, studentId);
|
||||||
return 1;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -221,9 +225,8 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean checkCanDelete(Long memberId) {
|
public boolean checkCanDelete(Long memberId) {
|
||||||
// TODO: 检查是否有绑定的学生(等学生模块完成后实现)
|
// 检查是否有绑定的学生
|
||||||
// return studentService.countByMemberId(memberId) == 0;
|
return studentService.countByMemberId(memberId) == 0;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -312,4 +315,30 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
|
||||||
default -> "未知";
|
default -> "未知";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public Long getOrCreateMemberByPhone(String phone) {
|
||||||
|
// 先查询是否存在
|
||||||
|
Member existMember = getMemberByPhone(phone);
|
||||||
|
if (existMember != null) {
|
||||||
|
return existMember.getMemberId();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 不存在则创建
|
||||||
|
Member newMember = new Member();
|
||||||
|
newMember.setMemberCode(generateMemberCode());
|
||||||
|
newMember.setPhone(phone);
|
||||||
|
newMember.setNickname(generateNickname(phone));
|
||||||
|
newMember.setPassword(passwordEncoder.encode(DEFAULT_PASSWORD));
|
||||||
|
newMember.setIdentityType(IdentityTypeEnum.PARENT.getCode());
|
||||||
|
newMember.setRegisterSource(RegisterSourceEnum.BACKEND.getCode());
|
||||||
|
newMember.setStatus("0");
|
||||||
|
newMember.setCreateTime(LocalDateTime.now());
|
||||||
|
|
||||||
|
memberMapper.insert(newMember);
|
||||||
|
log.info("批量导入自动创建会员, memberId={}, phone={}", newMember.getMemberId(), phone);
|
||||||
|
|
||||||
|
return newMember.getMemberId();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,4 +85,28 @@ public interface ISchoolService {
|
||||||
* @return 影响行数
|
* @return 影响行数
|
||||||
*/
|
*/
|
||||||
int deleteSchoolClass(Long schoolClassId);
|
int deleteSchoolClass(Long schoolClassId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据学校名称和区域ID查询学校ID
|
||||||
|
* @param schoolName 学校名称
|
||||||
|
* @param regionId 区域ID
|
||||||
|
* @return 学校ID
|
||||||
|
*/
|
||||||
|
Long getSchoolIdByName(String schoolName, Long regionId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据学校ID和年级名称查询学校年级ID
|
||||||
|
* @param schoolId 学校ID
|
||||||
|
* @param gradeName 年级名称
|
||||||
|
* @return 学校年级关联ID
|
||||||
|
*/
|
||||||
|
Long getSchoolGradeId(Long schoolId, String gradeName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据学校年级ID和班级名称查询学校班级ID
|
||||||
|
* @param schoolGradeId 学校年级ID
|
||||||
|
* @param className 班级名称
|
||||||
|
* @return 学校班级关联ID
|
||||||
|
*/
|
||||||
|
Long getSchoolClassId(Long schoolGradeId, String className);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -313,4 +313,35 @@ public class SchoolServiceImpl implements ISchoolService {
|
||||||
return vo;
|
return vo;
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getSchoolIdByName(String schoolName, Long regionId) {
|
||||||
|
SchoolQueryDTO query = new SchoolQueryDTO();
|
||||||
|
query.setSchoolName(schoolName);
|
||||||
|
query.setRegionId(regionId);
|
||||||
|
List<SchoolVO> schools = schoolMapper.selectSchoolList(query);
|
||||||
|
return schools.isEmpty() ? null : schools.get(0).getSchoolId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getSchoolGradeId(Long schoolId, String gradeName) {
|
||||||
|
List<SchoolGrade> grades = schoolGradeMapper.selectBySchoolIds(Collections.singletonList(schoolId));
|
||||||
|
for (SchoolGrade grade : grades) {
|
||||||
|
if (gradeName.equals(grade.getGradeName())) {
|
||||||
|
return grade.getId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getSchoolClassId(Long schoolGradeId, String className) {
|
||||||
|
List<SchoolClass> classes = schoolClassMapper.selectBySchoolGradeIds(Collections.singletonList(schoolGradeId));
|
||||||
|
for (SchoolClass clazz : classes) {
|
||||||
|
if (className.equals(clazz.getClassName())) {
|
||||||
|
return clazz.getId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
package com.pangu.student.controller;
|
package com.pangu.student.controller;
|
||||||
|
|
||||||
|
import com.alibaba.excel.EasyExcel;
|
||||||
import com.pangu.common.core.controller.BaseController;
|
import com.pangu.common.core.controller.BaseController;
|
||||||
import com.pangu.common.core.domain.AjaxResult;
|
import com.pangu.common.core.domain.AjaxResult;
|
||||||
import com.pangu.common.core.page.TableDataInfo;
|
import com.pangu.common.core.page.TableDataInfo;
|
||||||
import com.pangu.student.domain.dto.StudentDTO;
|
import com.pangu.student.domain.dto.StudentDTO;
|
||||||
|
import com.pangu.student.domain.dto.StudentImportDTO;
|
||||||
import com.pangu.student.domain.vo.ImportResultVO;
|
import com.pangu.student.domain.vo.ImportResultVO;
|
||||||
import com.pangu.student.domain.vo.StudentVO;
|
import com.pangu.student.domain.vo.StudentVO;
|
||||||
import com.pangu.student.service.IStudentService;
|
import com.pangu.student.service.IStudentService;
|
||||||
|
|
@ -12,6 +14,13 @@ import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 学生管理Controller
|
* 学生管理Controller
|
||||||
*
|
*
|
||||||
|
|
@ -78,8 +87,29 @@ public class StudentController extends BaseController {
|
||||||
* 下载导入模板
|
* 下载导入模板
|
||||||
*/
|
*/
|
||||||
@GetMapping("/template")
|
@GetMapping("/template")
|
||||||
public void downloadTemplate() {
|
public void downloadTemplate(HttpServletResponse response) throws IOException {
|
||||||
// TODO: 实现模板下载
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
|
response.setCharacterEncoding("utf-8");
|
||||||
|
String fileName = URLEncoder.encode("学生导入模板", StandardCharsets.UTF_8).replaceAll("\\+", "%20");
|
||||||
|
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
|
||||||
|
|
||||||
|
// 创建模板数据
|
||||||
|
List<StudentImportDTO> templateData = new ArrayList<>();
|
||||||
|
StudentImportDTO example = new StudentImportDTO();
|
||||||
|
example.setStudentName("张小明");
|
||||||
|
example.setStudentNo("STU20260001");
|
||||||
|
example.setMemberPhone("13812345678");
|
||||||
|
example.setRegionPath("湖北省-武汉市-武昌区");
|
||||||
|
example.setSchoolName("武汉市第一中学");
|
||||||
|
example.setGradeName("七年级");
|
||||||
|
example.setClassName("1班");
|
||||||
|
example.setGender("男");
|
||||||
|
example.setBirthday("2015-03");
|
||||||
|
templateData.add(example);
|
||||||
|
|
||||||
|
EasyExcel.write(response.getOutputStream(), StudentImportDTO.class)
|
||||||
|
.sheet("学生信息")
|
||||||
|
.doWrite(templateData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,18 @@ package com.pangu.student.listener;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.alibaba.excel.context.AnalysisContext;
|
import com.alibaba.excel.context.AnalysisContext;
|
||||||
import com.alibaba.excel.event.AnalysisEventListener;
|
import com.alibaba.excel.event.AnalysisEventListener;
|
||||||
|
import com.pangu.base.service.IRegionService;
|
||||||
|
import com.pangu.member.service.IMemberService;
|
||||||
|
import com.pangu.school.service.ISchoolService;
|
||||||
|
import com.pangu.student.domain.dto.StudentDTO;
|
||||||
import com.pangu.student.domain.dto.StudentImportDTO;
|
import com.pangu.student.domain.dto.StudentImportDTO;
|
||||||
import com.pangu.student.domain.vo.ImportResultVO;
|
import com.pangu.student.domain.vo.ImportResultVO;
|
||||||
import com.pangu.student.service.IStudentService;
|
import com.pangu.student.service.IStudentService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 学生导入监听器
|
* 学生导入监听器
|
||||||
*
|
*
|
||||||
|
|
@ -17,11 +24,20 @@ import lombok.extern.slf4j.Slf4j;
|
||||||
public class StudentImportListener extends AnalysisEventListener<StudentImportDTO> {
|
public class StudentImportListener extends AnalysisEventListener<StudentImportDTO> {
|
||||||
|
|
||||||
private final IStudentService studentService;
|
private final IStudentService studentService;
|
||||||
|
private final IRegionService regionService;
|
||||||
|
private final ISchoolService schoolService;
|
||||||
|
private final IMemberService memberService;
|
||||||
private final ImportResultVO result = new ImportResultVO();
|
private final ImportResultVO result = new ImportResultVO();
|
||||||
private int rowNum = 1; // 从第2行开始(第1行是表头)
|
private int rowNum = 1; // 从第2行开始(第1行是表头)
|
||||||
|
|
||||||
public StudentImportListener(IStudentService studentService) {
|
public StudentImportListener(IStudentService studentService,
|
||||||
|
IRegionService regionService,
|
||||||
|
ISchoolService schoolService,
|
||||||
|
IMemberService memberService) {
|
||||||
this.studentService = studentService;
|
this.studentService = studentService;
|
||||||
|
this.regionService = regionService;
|
||||||
|
this.schoolService = schoolService;
|
||||||
|
this.memberService = memberService;
|
||||||
result.setTotal(0);
|
result.setTotal(0);
|
||||||
result.setSuccessCount(0);
|
result.setSuccessCount(0);
|
||||||
result.setFailCount(0);
|
result.setFailCount(0);
|
||||||
|
|
@ -41,15 +57,60 @@ public class StudentImportListener extends AnalysisEventListener<StudentImportDT
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: 实际导入逻辑(需要查询区域、学校、会员等信息)
|
|
||||||
// 这里简化处理,实际需要:
|
|
||||||
// 1. 根据区域路径查询区域ID
|
// 1. 根据区域路径查询区域ID
|
||||||
// 2. 根据学校名称查询学校ID
|
Long regionId = regionService.getRegionIdByPath(data.getRegionPath());
|
||||||
// 3. 根据年级名称查询学校年级ID
|
if (regionId == null) {
|
||||||
// 4. 根据班级名称查询学校班级ID
|
addError(rowNum, data, "区域不存在:" + data.getRegionPath());
|
||||||
// 5. 根据手机号查询或创建会员
|
result.setFailCount(result.getFailCount() + 1);
|
||||||
// 6. 保存学生信息
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 根据学校名称查询学校ID
|
||||||
|
Long schoolId = schoolService.getSchoolIdByName(data.getSchoolName(), regionId);
|
||||||
|
if (schoolId == null) {
|
||||||
|
addError(rowNum, data, "学校不存在:" + data.getSchoolName());
|
||||||
|
result.setFailCount(result.getFailCount() + 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 根据年级名称查询学校年级ID
|
||||||
|
Long schoolGradeId = schoolService.getSchoolGradeId(schoolId, data.getGradeName());
|
||||||
|
if (schoolGradeId == null) {
|
||||||
|
addError(rowNum, data, "年级不存在:" + data.getGradeName());
|
||||||
|
result.setFailCount(result.getFailCount() + 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 根据班级名称查询学校班级ID
|
||||||
|
Long schoolClassId = schoolService.getSchoolClassId(schoolGradeId, data.getClassName());
|
||||||
|
if (schoolClassId == null) {
|
||||||
|
addError(rowNum, data, "班级不存在:" + data.getClassName());
|
||||||
|
result.setFailCount(result.getFailCount() + 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 根据手机号查询或创建会员
|
||||||
|
Long memberId = memberService.getOrCreateMemberByPhone(data.getMemberPhone());
|
||||||
|
if (memberId == null) {
|
||||||
|
addError(rowNum, data, "会员创建失败");
|
||||||
|
result.setFailCount(result.getFailCount() + 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 保存学生信息
|
||||||
|
StudentDTO studentDTO = new StudentDTO();
|
||||||
|
studentDTO.setStudentName(data.getStudentName());
|
||||||
|
studentDTO.setStudentNo(data.getStudentNo());
|
||||||
|
studentDTO.setGender(parseGender(data.getGender()));
|
||||||
|
studentDTO.setBirthday(parseBirthday(data.getBirthday()));
|
||||||
|
studentDTO.setRegionId(regionId);
|
||||||
|
studentDTO.setRegionPath(data.getRegionPath());
|
||||||
|
studentDTO.setSchoolId(schoolId);
|
||||||
|
studentDTO.setSchoolGradeId(schoolGradeId);
|
||||||
|
studentDTO.setSchoolClassId(schoolClassId);
|
||||||
|
studentDTO.setMemberId(memberId);
|
||||||
|
|
||||||
|
studentService.insertStudent(studentDTO);
|
||||||
result.setSuccessCount(result.getSuccessCount() + 1);
|
result.setSuccessCount(result.getSuccessCount() + 1);
|
||||||
log.info("导入学生成功:{}", data.getStudentName());
|
log.info("导入学生成功:{}", data.getStudentName());
|
||||||
|
|
||||||
|
|
@ -109,4 +170,34 @@ public class StudentImportListener extends AnalysisEventListener<StudentImportDT
|
||||||
public ImportResultVO getResult() {
|
public ImportResultVO getResult() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析性别
|
||||||
|
*/
|
||||||
|
private String parseGender(String gender) {
|
||||||
|
if (StrUtil.isBlank(gender)) {
|
||||||
|
return "0";
|
||||||
|
}
|
||||||
|
return switch (gender) {
|
||||||
|
case "男" -> "1";
|
||||||
|
case "女" -> "2";
|
||||||
|
default -> "0";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析出生年月
|
||||||
|
*/
|
||||||
|
private LocalDate parseBirthday(String birthday) {
|
||||||
|
if (StrUtil.isBlank(birthday)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
|
||||||
|
return LocalDate.parse(birthday + "-01", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("解析出生年月失败:{}", birthday);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,4 +43,20 @@ public interface StudentMapper extends BaseMapper<Student> {
|
||||||
* @return 数量
|
* @return 数量
|
||||||
*/
|
*/
|
||||||
int countByStudentNo(@Param("studentNo") String studentNo, @Param("studentId") Long studentId);
|
int countByStudentNo(@Param("studentNo") String studentNo, @Param("studentId") Long studentId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据会员ID统计学生数量
|
||||||
|
*
|
||||||
|
* @param memberId 会员ID
|
||||||
|
* @return 学生数量
|
||||||
|
*/
|
||||||
|
int countByMemberId(@Param("memberId") Long memberId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据会员ID查询学生列表
|
||||||
|
*
|
||||||
|
* @param memberId 会员ID
|
||||||
|
* @return 学生列表
|
||||||
|
*/
|
||||||
|
List<StudentVO> selectStudentVOsByMemberId(@Param("memberId") Long memberId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,4 +71,46 @@ public interface IStudentService extends IService<Student> {
|
||||||
* @return true唯一 false不唯一
|
* @return true唯一 false不唯一
|
||||||
*/
|
*/
|
||||||
boolean checkStudentNoUnique(String studentNo, Long studentId);
|
boolean checkStudentNoUnique(String studentNo, Long studentId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查学生是否在指定学校
|
||||||
|
*
|
||||||
|
* @param studentId 学生ID
|
||||||
|
* @param schoolId 学校ID
|
||||||
|
* @return true在该学校 false不在
|
||||||
|
*/
|
||||||
|
boolean isStudentInSchool(Long studentId, Long schoolId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新学生的会员ID
|
||||||
|
*
|
||||||
|
* @param studentId 学生ID
|
||||||
|
* @param memberId 会员ID
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
int updateStudentMember(Long studentId, Long memberId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解绑学生(清空会员ID)
|
||||||
|
*
|
||||||
|
* @param studentId 学生ID
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
int unbindStudent(Long studentId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计会员绑定的学生数量
|
||||||
|
*
|
||||||
|
* @param memberId 会员ID
|
||||||
|
* @return 学生数量
|
||||||
|
*/
|
||||||
|
int countByMemberId(Long memberId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据会员ID查询学生列表
|
||||||
|
*
|
||||||
|
* @param memberId 会员ID
|
||||||
|
* @return 学生列表
|
||||||
|
*/
|
||||||
|
List<StudentVO> selectStudentVOsByMemberId(Long memberId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,9 @@ import java.util.List;
|
||||||
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements IStudentService {
|
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements IStudentService {
|
||||||
|
|
||||||
private final StudentMapper studentMapper;
|
private final StudentMapper studentMapper;
|
||||||
|
private final com.pangu.base.service.IRegionService regionService;
|
||||||
|
private final com.pangu.school.service.ISchoolService schoolService;
|
||||||
|
private final com.pangu.member.service.IMemberService memberService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableDataInfo selectStudentList(StudentDTO studentDTO) {
|
public TableDataInfo selectStudentList(StudentDTO studentDTO) {
|
||||||
|
|
@ -99,7 +102,7 @@ public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> impl
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public ImportResultVO importStudents(MultipartFile file) {
|
public ImportResultVO importStudents(MultipartFile file) {
|
||||||
try {
|
try {
|
||||||
StudentImportListener listener = new StudentImportListener(this);
|
StudentImportListener listener = new StudentImportListener(this, regionService, schoolService, memberService);
|
||||||
EasyExcel.read(file.getInputStream(), StudentImportDTO.class, listener).sheet().doRead();
|
EasyExcel.read(file.getInputStream(), StudentImportDTO.class, listener).sheet().doRead();
|
||||||
return listener.getResult();
|
return listener.getResult();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
@ -114,6 +117,47 @@ public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> impl
|
||||||
return count == 0;
|
return count == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isStudentInSchool(Long studentId, Long schoolId) {
|
||||||
|
Student student = studentMapper.selectById(studentId);
|
||||||
|
if (student == null || "1".equals(student.getDelFlag())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return student.getSchoolId().equals(schoolId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public int updateStudentMember(Long studentId, Long memberId) {
|
||||||
|
Student student = new Student();
|
||||||
|
student.setStudentId(studentId);
|
||||||
|
student.setMemberId(memberId);
|
||||||
|
int result = studentMapper.updateById(student);
|
||||||
|
log.info("更新学生会员关联成功, studentId={}, memberId={}", studentId, memberId);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public int unbindStudent(Long studentId) {
|
||||||
|
Student student = new Student();
|
||||||
|
student.setStudentId(studentId);
|
||||||
|
student.setMemberId(null);
|
||||||
|
int result = studentMapper.updateById(student);
|
||||||
|
log.info("解绑学生成功, studentId={}", studentId);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int countByMemberId(Long memberId) {
|
||||||
|
return studentMapper.countByMemberId(memberId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<StudentVO> selectStudentVOsByMemberId(Long memberId) {
|
||||||
|
return studentMapper.selectStudentVOsByMemberId(memberId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建学生对象
|
* 构建学生对象
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper
|
||||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.pangu.application.mapper.AppApiMapper">
|
||||||
|
|
||||||
|
<!-- 批量插入应用接口授权 -->
|
||||||
|
<insert id="batchInsert">
|
||||||
|
INSERT INTO pg_app_api (app_id, api_id, create_time)
|
||||||
|
VALUES
|
||||||
|
<foreach collection="list" item="item" separator=",">
|
||||||
|
(#{item.appId}, #{item.apiId}, #{item.createTime})
|
||||||
|
</foreach>
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<!-- 根据应用ID删除授权 -->
|
||||||
|
<delete id="deleteByAppId">
|
||||||
|
DELETE FROM pg_app_api WHERE app_id = #{appId}
|
||||||
|
</delete>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper
|
||||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.pangu.application.mapper.ApplicationMapper">
|
||||||
|
|
||||||
|
<!-- 应用VO结果映射 -->
|
||||||
|
<resultMap id="ApplicationVOResult" type="com.pangu.application.domain.vo.ApplicationVO">
|
||||||
|
<id property="appId" column="app_id"/>
|
||||||
|
<result property="appCode" column="app_code"/>
|
||||||
|
<result property="appName" column="app_name"/>
|
||||||
|
<result property="appSecret" column="app_secret"/>
|
||||||
|
<result property="contactPerson" column="contact_person"/>
|
||||||
|
<result property="contactPhone" column="contact_phone"/>
|
||||||
|
<result property="status" column="status"/>
|
||||||
|
<result property="createTime" column="create_time"/>
|
||||||
|
<result property="remark" column="remark"/>
|
||||||
|
<collection property="apiList" ofType="com.pangu.application.domain.vo.ApplicationVO$ApiVO">
|
||||||
|
<id property="apiId" column="api_id"/>
|
||||||
|
<result property="apiCode" column="api_code"/>
|
||||||
|
<result property="apiName" column="api_name"/>
|
||||||
|
<result property="apiPath" column="api_path"/>
|
||||||
|
<result property="apiMethod" column="api_method"/>
|
||||||
|
</collection>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<!-- 查询应用列表 -->
|
||||||
|
<select id="selectApplicationVOList" resultMap="ApplicationVOResult">
|
||||||
|
SELECT DISTINCT
|
||||||
|
a.app_id,
|
||||||
|
a.app_code,
|
||||||
|
a.app_name,
|
||||||
|
a.app_secret,
|
||||||
|
a.contact_person,
|
||||||
|
a.contact_phone,
|
||||||
|
a.status,
|
||||||
|
a.create_time,
|
||||||
|
a.remark,
|
||||||
|
api.api_id,
|
||||||
|
api.api_code,
|
||||||
|
api.api_name,
|
||||||
|
api.api_path,
|
||||||
|
api.api_method
|
||||||
|
FROM pg_application a
|
||||||
|
LEFT JOIN pg_app_api aa ON a.app_id = aa.app_id
|
||||||
|
LEFT JOIN pg_api_dict api ON aa.api_id = api.api_id AND api.status = '0'
|
||||||
|
WHERE a.del_flag = '0'
|
||||||
|
<if test="dto.appName != null and dto.appName != ''">
|
||||||
|
AND a.app_name LIKE CONCAT('%', #{dto.appName}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="dto.appCode != null and dto.appCode != ''">
|
||||||
|
AND a.app_code = #{dto.appCode}
|
||||||
|
</if>
|
||||||
|
<if test="dto.status != null and dto.status != ''">
|
||||||
|
AND a.status = #{dto.status}
|
||||||
|
</if>
|
||||||
|
<if test="dto.beginTime != null and dto.beginTime != ''">
|
||||||
|
AND DATE_FORMAT(a.create_time,'%Y-%m-%d') >= #{dto.beginTime}
|
||||||
|
</if>
|
||||||
|
<if test="dto.endTime != null and dto.endTime != ''">
|
||||||
|
AND DATE_FORMAT(a.create_time,'%Y-%m-%d') <= #{dto.endTime}
|
||||||
|
</if>
|
||||||
|
ORDER BY a.create_time DESC
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 根据ID查询应用详情 -->
|
||||||
|
<select id="selectApplicationVOById" resultMap="ApplicationVOResult">
|
||||||
|
SELECT
|
||||||
|
a.app_id,
|
||||||
|
a.app_code,
|
||||||
|
a.app_name,
|
||||||
|
a.app_secret,
|
||||||
|
a.contact_person,
|
||||||
|
a.contact_phone,
|
||||||
|
a.status,
|
||||||
|
a.create_time,
|
||||||
|
a.remark,
|
||||||
|
api.api_id,
|
||||||
|
api.api_code,
|
||||||
|
api.api_name,
|
||||||
|
api.api_path,
|
||||||
|
api.api_method
|
||||||
|
FROM pg_application a
|
||||||
|
LEFT JOIN pg_app_api aa ON a.app_id = aa.app_id
|
||||||
|
LEFT JOIN pg_api_dict api ON aa.api_id = api.api_id AND api.status = '0'
|
||||||
|
WHERE a.app_id = #{appId} AND a.del_flag = '0'
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 检查应用编码是否唯一 -->
|
||||||
|
<select id="countByAppCode" resultType="int">
|
||||||
|
SELECT COUNT(1)
|
||||||
|
FROM pg_application
|
||||||
|
WHERE app_code = #{appCode}
|
||||||
|
AND del_flag = '0'
|
||||||
|
<if test="appId != null">
|
||||||
|
AND app_id != #{appId}
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 获取下一个应用编码序号 -->
|
||||||
|
<select id="getNextCodeSeq" resultType="int">
|
||||||
|
SELECT COALESCE(MAX(CAST(SUBSTRING(app_code, 3) AS UNSIGNED)), 0) + 1
|
||||||
|
FROM pg_application
|
||||||
|
WHERE app_code LIKE 'YY%'
|
||||||
|
AND del_flag = '0'
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
|
|
@ -152,4 +152,47 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
</if>
|
</if>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<!-- 根据会员ID统计学生数量 -->
|
||||||
|
<select id="countByMemberId" resultType="int">
|
||||||
|
SELECT COUNT(1)
|
||||||
|
FROM pg_student
|
||||||
|
WHERE member_id = #{memberId}
|
||||||
|
AND del_flag = '0'
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 根据会员ID查询学生列表 -->
|
||||||
|
<select id="selectStudentVOsByMemberId" resultMap="StudentVOResult">
|
||||||
|
SELECT
|
||||||
|
s.student_id,
|
||||||
|
s.student_name,
|
||||||
|
s.student_no,
|
||||||
|
s.gender,
|
||||||
|
CASE s.gender
|
||||||
|
WHEN '1' THEN '男'
|
||||||
|
WHEN '2' THEN '女'
|
||||||
|
ELSE '未知'
|
||||||
|
END AS gender_name,
|
||||||
|
s.birthday,
|
||||||
|
s.region_id,
|
||||||
|
s.region_path,
|
||||||
|
s.school_id,
|
||||||
|
sch.school_name,
|
||||||
|
s.school_grade_id,
|
||||||
|
g.grade_name,
|
||||||
|
s.school_class_id,
|
||||||
|
c.class_name,
|
||||||
|
s.subject_id,
|
||||||
|
sub.subject_name,
|
||||||
|
s.create_time
|
||||||
|
FROM pg_student s
|
||||||
|
LEFT JOIN pg_school sch ON s.school_id = sch.school_id AND sch.del_flag = '0'
|
||||||
|
LEFT JOIN pg_school_grade sg ON s.school_grade_id = sg.id AND sg.del_flag = '0'
|
||||||
|
LEFT JOIN pg_grade g ON sg.grade_id = g.grade_id AND g.del_flag = '0'
|
||||||
|
LEFT JOIN pg_school_class sc ON s.school_class_id = sc.id AND sc.del_flag = '0'
|
||||||
|
LEFT JOIN pg_class c ON sc.class_id = c.class_id AND c.del_flag = '0'
|
||||||
|
LEFT JOIN pg_subject sub ON s.subject_id = sub.subject_id AND sub.del_flag = '0'
|
||||||
|
WHERE s.member_id = #{memberId} AND s.del_flag = '0'
|
||||||
|
ORDER BY s.create_time DESC
|
||||||
|
</select>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,18 @@
|
||||||
-- ============================================================
|
-- ============================================================
|
||||||
-- 盘古用户平台 - 应用管理模块表结构及初始数据
|
-- 应用管理模块 - 数据库脚本
|
||||||
-- 作者:湖北新华业务中台研发团队
|
-- 作者:pangu
|
||||||
-- 说明:执行前请确认已存在 sys_menu,菜单已在 pangu_menu.sql 中
|
-- 创建时间:2026-01-31
|
||||||
-- ============================================================
|
-- ============================================================
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
-- 应用表
|
-- 应用表
|
||||||
CREATE TABLE IF NOT EXISTS `pg_application` (
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `pg_application`;
|
||||||
|
CREATE TABLE `pg_application` (
|
||||||
`app_id` bigint NOT NULL AUTO_INCREMENT COMMENT '应用ID',
|
`app_id` bigint NOT NULL AUTO_INCREMENT COMMENT '应用ID',
|
||||||
`app_code` varchar(32) NOT NULL COMMENT '应用编码',
|
`app_code` varchar(32) NOT NULL COMMENT '应用编码',
|
||||||
`app_name` varchar(100) NOT NULL COMMENT '应用名称',
|
`app_name` varchar(100) NOT NULL COMMENT '应用名称',
|
||||||
`app_secret` varchar(64) NOT NULL COMMENT '应用密钥',
|
`app_secret` varchar(64) NOT NULL COMMENT '应用密钥',
|
||||||
`app_desc` varchar(500) DEFAULT NULL COMMENT '应用描述',
|
|
||||||
`contact_person` varchar(50) DEFAULT NULL COMMENT '联系人',
|
`contact_person` varchar(50) DEFAULT NULL COMMENT '联系人',
|
||||||
`contact_phone` varchar(20) DEFAULT NULL COMMENT '联系电话',
|
`contact_phone` varchar(20) DEFAULT NULL COMMENT '联系电话',
|
||||||
`status` char(1) DEFAULT '0' COMMENT '状态(0正常 1停用)',
|
`status` char(1) DEFAULT '0' COMMENT '状态(0正常 1停用)',
|
||||||
|
|
@ -21,47 +23,67 @@ CREATE TABLE IF NOT EXISTS `pg_application` (
|
||||||
`del_flag` char(1) DEFAULT '0' COMMENT '删除标志(0存在 1删除)',
|
`del_flag` char(1) DEFAULT '0' COMMENT '删除标志(0存在 1删除)',
|
||||||
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
|
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
|
||||||
PRIMARY KEY (`app_id`),
|
PRIMARY KEY (`app_id`),
|
||||||
UNIQUE KEY `uk_app_code` (`app_code`),
|
UNIQUE KEY `uk_app_code` (`app_code`)
|
||||||
UNIQUE KEY `uk_app_name` (`app_name`, `del_flag`)
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='应用表';
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='应用表';
|
|
||||||
|
|
||||||
-- 应用接口授权表(记录应用被授予的可调用接口)
|
|
||||||
CREATE TABLE IF NOT EXISTS `pg_app_grant` (
|
|
||||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
|
||||||
`app_id` bigint NOT NULL COMMENT '应用ID',
|
|
||||||
`api_code` varchar(100) NOT NULL COMMENT '接口编码',
|
|
||||||
`api_name` varchar(100) DEFAULT NULL COMMENT '接口名称',
|
|
||||||
`api_path` varchar(200) NOT NULL COMMENT '接口路径',
|
|
||||||
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
|
|
||||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
|
||||||
PRIMARY KEY (`id`),
|
|
||||||
UNIQUE KEY `uk_app_api` (`app_id`, `api_code`),
|
|
||||||
KEY `idx_app_id` (`app_id`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='应用接口授权表';
|
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
-- API接口字典表
|
-- API接口字典表
|
||||||
CREATE TABLE IF NOT EXISTS `pg_api_dict` (
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `pg_api_dict`;
|
||||||
|
CREATE TABLE `pg_api_dict` (
|
||||||
`api_id` bigint NOT NULL AUTO_INCREMENT COMMENT '接口ID',
|
`api_id` bigint NOT NULL AUTO_INCREMENT COMMENT '接口ID',
|
||||||
`api_code` varchar(100) NOT NULL COMMENT '接口编码',
|
`api_code` varchar(50) NOT NULL COMMENT '接口编码',
|
||||||
`api_name` varchar(100) NOT NULL COMMENT '接口名称',
|
`api_name` varchar(100) NOT NULL COMMENT '接口名称',
|
||||||
`api_path` varchar(200) NOT NULL COMMENT '接口路径',
|
`api_path` varchar(200) NOT NULL COMMENT '接口路径',
|
||||||
`api_method` varchar(10) DEFAULT 'GET' COMMENT '请求方法',
|
`api_method` varchar(10) NOT NULL COMMENT '请求方法',
|
||||||
`api_desc` varchar(500) DEFAULT NULL COMMENT '接口描述',
|
`sort_order` int DEFAULT 0 COMMENT '排序',
|
||||||
`order_num` int DEFAULT 0 COMMENT '显示顺序',
|
|
||||||
`status` char(1) DEFAULT '0' COMMENT '状态(0正常 1停用)',
|
`status` char(1) DEFAULT '0' COMMENT '状态(0正常 1停用)',
|
||||||
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
|
|
||||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||||
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
|
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
|
||||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
|
||||||
PRIMARY KEY (`api_id`),
|
PRIMARY KEY (`api_id`),
|
||||||
UNIQUE KEY `uk_api_code` (`api_code`)
|
UNIQUE KEY `uk_api_code` (`api_code`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='API接口字典表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='API接口字典表';
|
||||||
|
|
||||||
-- API接口字典初始数据
|
-- ----------------------------
|
||||||
INSERT INTO pg_api_dict (api_code, api_name, api_path, api_method, api_desc, order_num, status) VALUES
|
-- 应用接口授权表
|
||||||
('STUDENT_LIST', '查询学生信息', '/open/student/list', 'GET', '获取学生列表', 1, '0'),
|
-- ----------------------------
|
||||||
('SCHOOL_LIST', '查询学校信息', '/open/school/list', 'GET', '获取学校列表', 2, '0'),
|
DROP TABLE IF EXISTS `pg_app_api`;
|
||||||
('GRADE_LIST', '查询年级信息', '/open/grade/list', 'GET', '获取年级列表', 3, '0'),
|
CREATE TABLE `pg_app_api` (
|
||||||
('CLASS_LIST', '查询班级信息', '/open/class/list', 'GET', '获取班级列表', 4, '0'),
|
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||||
('MEMBER_LIST', '查询会员信息', '/open/member/list', 'GET', '获取会员列表', 5, '0'),
|
`app_id` bigint NOT NULL COMMENT '应用ID',
|
||||||
('REGION_TREE', '查询区域树', '/open/region/tree', 'GET', '获取区域树形结构', 6, '0');
|
`api_id` bigint NOT NULL COMMENT '接口ID',
|
||||||
|
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `uk_app_api` (`app_id`, `api_id`),
|
||||||
|
KEY `idx_app_id` (`app_id`),
|
||||||
|
KEY `idx_api_id` (`api_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='应用接口授权表';
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- 初始化API接口字典数据
|
||||||
|
-- ----------------------------
|
||||||
|
INSERT INTO pg_api_dict (api_code, api_name, api_path, api_method, sort_order, status, create_time) VALUES
|
||||||
|
('api_member_info', '获取会员信息', '/open/api/member/info', 'GET', 1, '0', NOW()),
|
||||||
|
('api_member_list', '获取会员列表', '/open/api/member/list', 'GET', 2, '0', NOW()),
|
||||||
|
('api_student_info', '获取学生信息', '/open/api/student/info', 'GET', 3, '0', NOW()),
|
||||||
|
('api_student_list', '获取学生列表', '/open/api/student/list', 'GET', 4, '0', NOW()),
|
||||||
|
('api_school_info', '获取学校信息', '/open/api/school/info', 'GET', 5, '0', NOW()),
|
||||||
|
('api_school_list', '获取学校列表', '/open/api/school/list', 'GET', 6, '0', NOW());
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- 初始化应用示例数据
|
||||||
|
-- ----------------------------
|
||||||
|
INSERT INTO pg_application (app_code, app_name, app_secret, contact_person, contact_phone, status, create_by, create_time, del_flag) VALUES
|
||||||
|
('YY000001', 'AI智慧平台', 'a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6', '张三', '13800138000', '0', 'admin', NOW(), '0'),
|
||||||
|
('YY000002', '测试应用', 'p6o5n4m3l2k1j0i9h8g7f6e5d4c3b2a1', '李四', '13900139000', '0', 'admin', NOW(), '0');
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- 初始化应用接口授权数据
|
||||||
|
-- ----------------------------
|
||||||
|
INSERT INTO pg_app_api (app_id, api_id, create_time) VALUES
|
||||||
|
(1, 1, NOW()),
|
||||||
|
(1, 2, NOW()),
|
||||||
|
(1, 3, NOW()),
|
||||||
|
(1, 4, NOW()),
|
||||||
|
(2, 1, NOW()),
|
||||||
|
(2, 3, NOW());
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue