feat: 会员教育信息重构 - 支持多教育身份管理
主要变更: 1. 去掉身份类型字段,会员与教育信息改为一对多关系 2. 新增 pg_education 表及相关实体、服务 3. 管理后台支持添加、编辑、删除多个教育身份 4. 新增会员时支持一次性保存会员信息、教育身份、亲子关系 5. 修复学生选择弹窗学校年级班级不显示问题 6. 添加区域路径接口用于级联选择器回显
This commit is contained in:
parent
acdade6725
commit
729f2c71f1
|
|
@ -51,6 +51,15 @@ public class PgRegionController extends BaseController {
|
||||||
return R.ok(regionService.selectById(regionId));
|
return R.ok(regionService.selectById(regionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取区域路径(从根到当前区域的ID列表)
|
||||||
|
* 用于级联选择器回显
|
||||||
|
*/
|
||||||
|
@GetMapping("/{regionId}/path")
|
||||||
|
public R<List<Long>> getRegionPath(@PathVariable Long regionId) {
|
||||||
|
return R.ok(regionService.getRegionPath(regionId));
|
||||||
|
}
|
||||||
|
|
||||||
@SaCheckPermission("business:region:add")
|
@SaCheckPermission("business:region:add")
|
||||||
@Log(title = "区域管理", businessType = BusinessType.INSERT)
|
@Log(title = "区域管理", businessType = BusinessType.INSERT)
|
||||||
@PostMapping
|
@PostMapping
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
package org.dromara.pangu.base.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 教育信息表(会员教育身份)
|
||||||
|
*
|
||||||
|
* @author 湖北新华业务中台研发团队
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@TableName("pg_education")
|
||||||
|
public class PgEducation extends BaseEntity {
|
||||||
|
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
private Long educationId;
|
||||||
|
|
||||||
|
private Long memberId;
|
||||||
|
|
||||||
|
private Long regionId;
|
||||||
|
|
||||||
|
private Long schoolId;
|
||||||
|
|
||||||
|
private Long schoolGradeId;
|
||||||
|
|
||||||
|
private Long schoolClassId;
|
||||||
|
|
||||||
|
private Long subjectId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否默认身份(0否 1是)
|
||||||
|
*/
|
||||||
|
private String isDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态(0正常 1停用)
|
||||||
|
*/
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
private String tenantId;
|
||||||
|
|
||||||
|
@TableLogic
|
||||||
|
private String delFlag;
|
||||||
|
|
||||||
|
// 非数据库字段(用于VO展示)
|
||||||
|
@TableField(exist = false)
|
||||||
|
private String regionName;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
private String schoolName;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
private String gradeName;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
private String className;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
private String subjectName;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package org.dromara.pangu.base.mapper;
|
||||||
|
|
||||||
|
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||||
|
import org.dromara.pangu.base.domain.PgEducation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 教育信息 Mapper 接口
|
||||||
|
*
|
||||||
|
* @author 湖北新华业务中台研发团队
|
||||||
|
*/
|
||||||
|
public interface PgEducationMapper extends BaseMapperPlus<PgEducation, PgEducation> {
|
||||||
|
}
|
||||||
|
|
@ -14,6 +14,7 @@ public interface IPgRegionService {
|
||||||
List<PgRegion> selectTree();
|
List<PgRegion> selectTree();
|
||||||
PgRegion selectById(Long regionId);
|
PgRegion selectById(Long regionId);
|
||||||
List<PgRegion> selectByParentId(Long parentId);
|
List<PgRegion> selectByParentId(Long parentId);
|
||||||
|
List<Long> getRegionPath(Long regionId);
|
||||||
int insert(PgRegion region);
|
int insert(PgRegion region);
|
||||||
int update(PgRegion region);
|
int update(PgRegion region);
|
||||||
int deleteByIds(Long[] regionIds);
|
int deleteByIds(Long[] regionIds);
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,30 @@ public class PgRegionServiceImpl implements IPgRegionService {
|
||||||
.orderByAsc(PgRegion::getOrderNum));
|
.orderByAsc(PgRegion::getOrderNum));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Long> getRegionPath(Long regionId) {
|
||||||
|
if (regionId == null) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
PgRegion region = baseMapper.selectById(regionId);
|
||||||
|
if (region == null) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
List<Long> path = new ArrayList<>();
|
||||||
|
// ancestors 格式: "0,42,4201" 表示从根到父的路径
|
||||||
|
if (StrUtil.isNotBlank(region.getAncestors())) {
|
||||||
|
String[] ancestorIds = region.getAncestors().split(",");
|
||||||
|
for (String id : ancestorIds) {
|
||||||
|
if (StrUtil.isNotBlank(id) && !"0".equals(id)) {
|
||||||
|
path.add(Long.parseLong(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 最后加上当前区域ID
|
||||||
|
path.add(regionId);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int insert(PgRegion region) {
|
public int insert(PgRegion region) {
|
||||||
return baseMapper.insert(region);
|
return baseMapper.insert(region);
|
||||||
|
|
|
||||||
|
|
@ -122,12 +122,12 @@ public class H5MemberController {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加/修改教育身份
|
* 添加教育身份
|
||||||
*/
|
*/
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "设置教育身份(教师)",
|
summary = "添加教育身份",
|
||||||
description = """
|
description = """
|
||||||
设置或修改会员的教育身份信息,设置后身份类型变为"教师"。
|
添加一个教育身份。一个会员可以有多个教育身份(每班一条记录)。
|
||||||
|
|
||||||
**必填信息:**
|
**必填信息:**
|
||||||
- 学校
|
- 学校
|
||||||
|
|
@ -143,31 +143,52 @@ public class H5MemberController {
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
@ApiResponses({
|
@ApiResponses({
|
||||||
@ApiResponse(responseCode = "200", description = "设置成功"),
|
@ApiResponse(responseCode = "200", description = "添加成功"),
|
||||||
@ApiResponse(responseCode = "401", description = "未登录或Token已过期"),
|
@ApiResponse(responseCode = "401", description = "未登录或Token已过期"),
|
||||||
@ApiResponse(responseCode = "500", description = "设置失败,可能原因:学校/年级/班级/学科不存在")
|
@ApiResponse(responseCode = "500", description = "添加失败,可能原因:学校/年级/班级/学科不存在")
|
||||||
})
|
})
|
||||||
@PostMapping("/education")
|
@PostMapping("/educations")
|
||||||
public R<Void> saveEducation(@Valid @RequestBody H5EducationDto dto) {
|
public R<Void> addEducation(@Valid @RequestBody H5EducationDto dto) {
|
||||||
memberService.saveEducation(dto);
|
memberService.addEducation(dto);
|
||||||
return R.ok();
|
return R.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取教育身份
|
* 修改教育身份
|
||||||
*/
|
*/
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "获取教育身份信息",
|
summary = "修改教育身份",
|
||||||
description = "获取当前会员的教育身份信息(学校、年级、班级、学科)。如果未设置教育身份,返回null。"
|
description = "修改指定的教育身份信息。"
|
||||||
|
)
|
||||||
|
@ApiResponses({
|
||||||
|
@ApiResponse(responseCode = "200", description = "修改成功"),
|
||||||
|
@ApiResponse(responseCode = "401", description = "未登录或Token已过期"),
|
||||||
|
@ApiResponse(responseCode = "500", description = "修改失败,可能原因:教育身份不存在或无权限")
|
||||||
|
})
|
||||||
|
@Parameters({
|
||||||
|
@Parameter(name = "educationId", description = "教育身份ID", required = true, in = ParameterIn.PATH)
|
||||||
|
})
|
||||||
|
@PutMapping("/educations/{educationId}")
|
||||||
|
public R<Void> updateEducation(@PathVariable Long educationId, @Valid @RequestBody H5EducationDto dto) {
|
||||||
|
memberService.updateEducation(educationId, dto);
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取教育身份列表
|
||||||
|
*/
|
||||||
|
@Operation(
|
||||||
|
summary = "获取教育身份列表",
|
||||||
|
description = "获取当前会员的所有教育身份信息(学校、年级、班级、学科)。"
|
||||||
)
|
)
|
||||||
@ApiResponses({
|
@ApiResponses({
|
||||||
@ApiResponse(responseCode = "200", description = "获取成功",
|
@ApiResponse(responseCode = "200", description = "获取成功",
|
||||||
content = @Content(schema = @Schema(implementation = H5EducationVo.class))),
|
content = @Content(schema = @Schema(implementation = H5EducationVo.class))),
|
||||||
@ApiResponse(responseCode = "401", description = "未登录或Token已过期")
|
@ApiResponse(responseCode = "401", description = "未登录或Token已过期")
|
||||||
})
|
})
|
||||||
@GetMapping("/education")
|
@GetMapping("/educations")
|
||||||
public R<H5EducationVo> getEducation() {
|
public R<List<H5EducationVo>> getEducations() {
|
||||||
return R.ok(memberService.getEducation());
|
return R.ok(memberService.getEducations());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -175,15 +196,40 @@ public class H5MemberController {
|
||||||
*/
|
*/
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "删除教育身份",
|
summary = "删除教育身份",
|
||||||
description = "清除当前会员的教育身份信息,身份类型将变为空。"
|
description = "删除指定的教育身份。"
|
||||||
)
|
)
|
||||||
@ApiResponses({
|
@ApiResponses({
|
||||||
@ApiResponse(responseCode = "200", description = "删除成功"),
|
@ApiResponse(responseCode = "200", description = "删除成功"),
|
||||||
@ApiResponse(responseCode = "401", description = "未登录或Token已过期")
|
@ApiResponse(responseCode = "401", description = "未登录或Token已过期"),
|
||||||
|
@ApiResponse(responseCode = "500", description = "删除失败,可能原因:教育身份不存在或无权限")
|
||||||
})
|
})
|
||||||
@DeleteMapping("/education")
|
@Parameters({
|
||||||
public R<Void> deleteEducation() {
|
@Parameter(name = "educationId", description = "教育身份ID", required = true, in = ParameterIn.PATH)
|
||||||
memberService.deleteEducation();
|
})
|
||||||
|
@DeleteMapping("/educations/{educationId}")
|
||||||
|
public R<Void> deleteEducation(@PathVariable Long educationId) {
|
||||||
|
memberService.deleteEducation(educationId);
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置默认教育身份
|
||||||
|
*/
|
||||||
|
@Operation(
|
||||||
|
summary = "设置默认教育身份",
|
||||||
|
description = "将指定教育身份设为默认。"
|
||||||
|
)
|
||||||
|
@ApiResponses({
|
||||||
|
@ApiResponse(responseCode = "200", description = "设置成功"),
|
||||||
|
@ApiResponse(responseCode = "401", description = "未登录或Token已过期"),
|
||||||
|
@ApiResponse(responseCode = "500", description = "设置失败,可能原因:教育身份不存在或无权限")
|
||||||
|
})
|
||||||
|
@Parameters({
|
||||||
|
@Parameter(name = "educationId", description = "教育身份ID", required = true, in = ParameterIn.PATH)
|
||||||
|
})
|
||||||
|
@PutMapping("/educations/{educationId}/default")
|
||||||
|
public R<Void> setDefaultEducation(@PathVariable Long educationId) {
|
||||||
|
memberService.setDefaultEducation(educationId);
|
||||||
return R.ok();
|
return R.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,9 @@ import lombok.Data;
|
||||||
@Schema(description = "教育身份设置请求参数(教师身份)")
|
@Schema(description = "教育身份设置请求参数(教师身份)")
|
||||||
public class H5EducationDto {
|
public class H5EducationDto {
|
||||||
|
|
||||||
|
@Schema(description = "教育身份ID(新增时不传,编辑时必传)", example = "1")
|
||||||
|
private Long educationId;
|
||||||
|
|
||||||
@Schema(description = "学校ID(从/h5/base/schools获取)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
@Schema(description = "学校ID(从/h5/base/schools获取)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
@NotNull(message = "请选择学校")
|
@NotNull(message = "请选择学校")
|
||||||
private Long schoolId;
|
private Long schoolId;
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,9 @@ import lombok.Data;
|
||||||
@Schema(description = "教育身份信息(教师)")
|
@Schema(description = "教育身份信息(教师)")
|
||||||
public class H5EducationVo {
|
public class H5EducationVo {
|
||||||
|
|
||||||
|
@Schema(description = "教育身份ID", example = "1")
|
||||||
|
private Long educationId;
|
||||||
|
|
||||||
@Schema(description = "省份ID", example = "420000")
|
@Schema(description = "省份ID", example = "420000")
|
||||||
private Long provinceId;
|
private Long provinceId;
|
||||||
|
|
||||||
|
|
@ -53,4 +56,7 @@ public class H5EducationVo {
|
||||||
|
|
||||||
@Schema(description = "学科名称", example = "语文")
|
@Schema(description = "学科名称", example = "语文")
|
||||||
private String subjectName;
|
private String subjectName;
|
||||||
|
|
||||||
|
@Schema(description = "是否默认身份(0否 1是)", example = "1")
|
||||||
|
private String isDefault;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,4 @@ public class H5LoginVo {
|
||||||
|
|
||||||
@Schema(description = "昵称", example = "user_5678")
|
@Schema(description = "昵称", example = "user_5678")
|
||||||
private String nickname;
|
private String nickname;
|
||||||
|
|
||||||
@Schema(description = "身份类型:1-家长,2-教师,null-未设置", example = "1")
|
|
||||||
private String identityType;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,11 +39,8 @@ public class H5MemberInfoVo {
|
||||||
@Schema(description = "注册时间", example = "2024-01-01 12:00:00")
|
@Schema(description = "注册时间", example = "2024-01-01 12:00:00")
|
||||||
private Date registerTime;
|
private Date registerTime;
|
||||||
|
|
||||||
@Schema(description = "身份类型:1-家长,2-教师", example = "2")
|
@Schema(description = "教育身份列表")
|
||||||
private String identityType;
|
private List<H5EducationVo> educations;
|
||||||
|
|
||||||
@Schema(description = "教育身份信息(仅教师身份有值)")
|
|
||||||
private H5EducationVo education;
|
|
||||||
|
|
||||||
@Schema(description = "绑定的学生列表")
|
@Schema(description = "绑定的学生列表")
|
||||||
private List<H5StudentVo> students;
|
private List<H5StudentVo> students;
|
||||||
|
|
|
||||||
|
|
@ -33,19 +33,29 @@ public interface H5MemberService {
|
||||||
void updatePassword(H5PasswordUpdateDto dto);
|
void updatePassword(H5PasswordUpdateDto dto);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加/修改教育身份
|
* 添加教育身份
|
||||||
*/
|
*/
|
||||||
void saveEducation(H5EducationDto dto);
|
void addEducation(H5EducationDto dto);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取教育身份
|
* 修改教育身份
|
||||||
*/
|
*/
|
||||||
H5EducationVo getEducation();
|
void updateEducation(Long educationId, H5EducationDto dto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取教育身份列表
|
||||||
|
*/
|
||||||
|
List<H5EducationVo> getEducations();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除教育身份
|
* 删除教育身份
|
||||||
*/
|
*/
|
||||||
void deleteEducation();
|
void deleteEducation(Long educationId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置默认教育身份
|
||||||
|
*/
|
||||||
|
void setDefaultEducation(Long educationId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 绑定学生
|
* 绑定学生
|
||||||
|
|
|
||||||
|
|
@ -409,7 +409,6 @@ public class H5AuthServiceImpl implements H5AuthService {
|
||||||
vo.setMemberCode(member.getMemberCode());
|
vo.setMemberCode(member.getMemberCode());
|
||||||
vo.setPhone(maskPhone(member.getPhone()));
|
vo.setPhone(maskPhone(member.getPhone()));
|
||||||
vo.setNickname(member.getNickname());
|
vo.setNickname(member.getNickname());
|
||||||
vo.setIdentityType(member.getIdentityType());
|
|
||||||
|
|
||||||
return vo;
|
return vo;
|
||||||
}
|
}
|
||||||
|
|
@ -671,7 +670,6 @@ public class H5AuthServiceImpl implements H5AuthService {
|
||||||
vo.setMemberCode(loginVo.getMemberCode());
|
vo.setMemberCode(loginVo.getMemberCode());
|
||||||
vo.setPhone(loginVo.getPhone());
|
vo.setPhone(loginVo.getPhone());
|
||||||
vo.setNickname(loginVo.getNickname());
|
vo.setNickname(loginVo.getNickname());
|
||||||
vo.setIdentityType(loginVo.getIdentityType());
|
|
||||||
|
|
||||||
log.info("微信登录成功: openId={}, memberId={}", openId, member.getMemberId());
|
log.info("微信登录成功: openId={}, memberId={}", openId, member.getMemberId());
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -777,7 +775,6 @@ public class H5AuthServiceImpl implements H5AuthService {
|
||||||
vo.setMemberCode(loginVo.getMemberCode());
|
vo.setMemberCode(loginVo.getMemberCode());
|
||||||
vo.setPhone(loginVo.getPhone());
|
vo.setPhone(loginVo.getPhone());
|
||||||
vo.setNickname(loginVo.getNickname());
|
vo.setNickname(loginVo.getNickname());
|
||||||
vo.setIdentityType(loginVo.getIdentityType());
|
|
||||||
|
|
||||||
return vo;
|
return vo;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,12 @@ import lombok.extern.slf4j.Slf4j;
|
||||||
import org.dromara.common.core.exception.ServiceException;
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
import org.dromara.common.core.utils.StringUtils;
|
import org.dromara.common.core.utils.StringUtils;
|
||||||
import org.dromara.pangu.base.domain.PgClass;
|
import org.dromara.pangu.base.domain.PgClass;
|
||||||
|
import org.dromara.pangu.base.domain.PgEducation;
|
||||||
import org.dromara.pangu.base.domain.PgGrade;
|
import org.dromara.pangu.base.domain.PgGrade;
|
||||||
import org.dromara.pangu.base.domain.PgRegion;
|
import org.dromara.pangu.base.domain.PgRegion;
|
||||||
import org.dromara.pangu.base.domain.PgSubject;
|
import org.dromara.pangu.base.domain.PgSubject;
|
||||||
import org.dromara.pangu.base.mapper.PgClassMapper;
|
import org.dromara.pangu.base.mapper.PgClassMapper;
|
||||||
|
import org.dromara.pangu.base.mapper.PgEducationMapper;
|
||||||
import org.dromara.pangu.base.mapper.PgGradeMapper;
|
import org.dromara.pangu.base.mapper.PgGradeMapper;
|
||||||
import org.dromara.pangu.base.mapper.PgRegionMapper;
|
import org.dromara.pangu.base.mapper.PgRegionMapper;
|
||||||
import org.dromara.pangu.base.mapper.PgSubjectMapper;
|
import org.dromara.pangu.base.mapper.PgSubjectMapper;
|
||||||
|
|
@ -59,6 +61,7 @@ public class H5MemberServiceImpl implements H5MemberService {
|
||||||
private final PgClassMapper classMapper;
|
private final PgClassMapper classMapper;
|
||||||
private final PgSubjectMapper subjectMapper;
|
private final PgSubjectMapper subjectMapper;
|
||||||
private final PgRegionMapper regionMapper;
|
private final PgRegionMapper regionMapper;
|
||||||
|
private final PgEducationMapper educationMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public H5MemberInfoVo getMemberInfo() {
|
public H5MemberInfoVo getMemberInfo() {
|
||||||
|
|
@ -77,12 +80,9 @@ public class H5MemberServiceImpl implements H5MemberService {
|
||||||
vo.setGender(member.getGender());
|
vo.setGender(member.getGender());
|
||||||
vo.setBirthday(member.getBirthday());
|
vo.setBirthday(member.getBirthday());
|
||||||
vo.setRegisterTime(member.getRegisterTime());
|
vo.setRegisterTime(member.getRegisterTime());
|
||||||
vo.setIdentityType(member.getIdentityType());
|
|
||||||
|
|
||||||
// 获取教育身份信息
|
// 获取教育身份列表
|
||||||
if ("2".equals(member.getIdentityType()) && member.getSchoolId() != null) {
|
vo.setEducations(getEducations());
|
||||||
vo.setEducation(buildEducationVo(member));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取绑定的学生列表
|
// 获取绑定的学生列表
|
||||||
vo.setStudents(getStudents());
|
vo.setStudents(getStudents());
|
||||||
|
|
@ -139,14 +139,125 @@ public class H5MemberServiceImpl implements H5MemberService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void saveEducation(H5EducationDto dto) {
|
public void addEducation(H5EducationDto dto) {
|
||||||
Long memberId = getCurrentMemberId();
|
Long memberId = getCurrentMemberId();
|
||||||
PgMember member = memberMapper.selectById(memberId);
|
|
||||||
if (member == null) {
|
// 校验学校、年级、班级、学科是否存在
|
||||||
throw new ServiceException("会员不存在");
|
PgSchool school = validateAndGetSchool(dto);
|
||||||
|
|
||||||
|
// 创建教育身份记录
|
||||||
|
PgEducation education = new PgEducation();
|
||||||
|
education.setMemberId(memberId);
|
||||||
|
education.setRegionId(school.getRegionId());
|
||||||
|
education.setSchoolId(dto.getSchoolId());
|
||||||
|
education.setSchoolGradeId(dto.getSchoolGradeId());
|
||||||
|
education.setSchoolClassId(dto.getSchoolClassId());
|
||||||
|
education.setSubjectId(dto.getSubjectId());
|
||||||
|
education.setStatus("0");
|
||||||
|
|
||||||
|
// 如果是第一个教育身份,设为默认
|
||||||
|
long count = educationMapper.selectCount(
|
||||||
|
new LambdaQueryWrapper<PgEducation>()
|
||||||
|
.eq(PgEducation::getMemberId, memberId)
|
||||||
|
.eq(PgEducation::getDelFlag, "0")
|
||||||
|
);
|
||||||
|
education.setIsDefault(count == 0 ? "1" : "0");
|
||||||
|
|
||||||
|
educationMapper.insert(education);
|
||||||
|
log.info("H5添加教育身份: memberId={}, educationId={}", memberId, education.getEducationId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void updateEducation(Long educationId, H5EducationDto dto) {
|
||||||
|
Long memberId = getCurrentMemberId();
|
||||||
|
|
||||||
|
// 查询并校验教育身份归属
|
||||||
|
PgEducation education = educationMapper.selectById(educationId);
|
||||||
|
if (education == null || !memberId.equals(education.getMemberId())) {
|
||||||
|
throw new ServiceException("教育身份不存在或无权限修改");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 校验学校、年级、班级、学科是否存在
|
// 校验学校、年级、班级、学科是否存在
|
||||||
|
PgSchool school = validateAndGetSchool(dto);
|
||||||
|
|
||||||
|
// 更新教育身份
|
||||||
|
education.setRegionId(school.getRegionId());
|
||||||
|
education.setSchoolId(dto.getSchoolId());
|
||||||
|
education.setSchoolGradeId(dto.getSchoolGradeId());
|
||||||
|
education.setSchoolClassId(dto.getSchoolClassId());
|
||||||
|
education.setSubjectId(dto.getSubjectId());
|
||||||
|
educationMapper.updateById(education);
|
||||||
|
|
||||||
|
log.info("H5修改教育身份: memberId={}, educationId={}", memberId, educationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<H5EducationVo> getEducations() {
|
||||||
|
Long memberId = getCurrentMemberId();
|
||||||
|
|
||||||
|
List<PgEducation> educations = educationMapper.selectList(
|
||||||
|
new LambdaQueryWrapper<PgEducation>()
|
||||||
|
.eq(PgEducation::getMemberId, memberId)
|
||||||
|
.eq(PgEducation::getDelFlag, "0")
|
||||||
|
.orderByDesc(PgEducation::getIsDefault)
|
||||||
|
.orderByDesc(PgEducation::getCreateTime)
|
||||||
|
);
|
||||||
|
|
||||||
|
List<H5EducationVo> voList = new ArrayList<>();
|
||||||
|
for (PgEducation education : educations) {
|
||||||
|
voList.add(buildEducationVo(education));
|
||||||
|
}
|
||||||
|
return voList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void deleteEducation(Long educationId) {
|
||||||
|
Long memberId = getCurrentMemberId();
|
||||||
|
|
||||||
|
// 查询并校验教育身份归属
|
||||||
|
PgEducation education = educationMapper.selectById(educationId);
|
||||||
|
if (education == null || !memberId.equals(education.getMemberId())) {
|
||||||
|
throw new ServiceException("教育身份不存在或无权限删除");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 逻辑删除
|
||||||
|
educationMapper.deleteById(educationId);
|
||||||
|
log.info("H5删除教育身份: memberId={}, educationId={}", memberId, educationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void setDefaultEducation(Long educationId) {
|
||||||
|
Long memberId = getCurrentMemberId();
|
||||||
|
|
||||||
|
// 查询并校验教育身份归属
|
||||||
|
PgEducation education = educationMapper.selectById(educationId);
|
||||||
|
if (education == null || !memberId.equals(education.getMemberId())) {
|
||||||
|
throw new ServiceException("教育身份不存在或无权限操作");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消其他默认
|
||||||
|
PgEducation updateEntity = new PgEducation();
|
||||||
|
updateEntity.setIsDefault("0");
|
||||||
|
educationMapper.update(updateEntity,
|
||||||
|
new LambdaQueryWrapper<PgEducation>()
|
||||||
|
.eq(PgEducation::getMemberId, memberId)
|
||||||
|
.eq(PgEducation::getIsDefault, "1")
|
||||||
|
);
|
||||||
|
|
||||||
|
// 设置当前为默认
|
||||||
|
education.setIsDefault("1");
|
||||||
|
educationMapper.updateById(education);
|
||||||
|
|
||||||
|
log.info("H5设置默认教育身份: memberId={}, educationId={}", memberId, educationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验并获取学校信息
|
||||||
|
*/
|
||||||
|
private PgSchool validateAndGetSchool(H5EducationDto dto) {
|
||||||
PgSchool school = schoolMapper.selectById(dto.getSchoolId());
|
PgSchool school = schoolMapper.selectById(dto.getSchoolId());
|
||||||
if (school == null) {
|
if (school == null) {
|
||||||
throw new ServiceException("学校不存在");
|
throw new ServiceException("学校不存在");
|
||||||
|
|
@ -167,68 +278,13 @@ public class H5MemberServiceImpl implements H5MemberService {
|
||||||
throw new ServiceException("学科不存在");
|
throw new ServiceException("学科不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新会员教育信息
|
return school;
|
||||||
member.setIdentityType("2"); // 教师
|
|
||||||
member.setSchoolId(dto.getSchoolId());
|
|
||||||
member.setSchoolGradeId(dto.getSchoolGradeId());
|
|
||||||
member.setSchoolClassId(dto.getSchoolClassId());
|
|
||||||
// 从学校获取区域信息并保存
|
|
||||||
if (school.getRegionId() != null) {
|
|
||||||
member.setRegionId(school.getRegionId());
|
|
||||||
}
|
|
||||||
// 学科信息需要在member表添加字段,这里先用remark暂存
|
|
||||||
member.setRemark("subjectId:" + dto.getSubjectId());
|
|
||||||
memberMapper.updateById(member);
|
|
||||||
|
|
||||||
log.info("H5教育身份保存: memberId={}, schoolId={}", memberId, dto.getSchoolId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public H5EducationVo getEducation() {
|
|
||||||
Long memberId = getCurrentMemberId();
|
|
||||||
PgMember member = memberMapper.selectById(memberId);
|
|
||||||
if (member == null) {
|
|
||||||
throw new ServiceException("会员不存在");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!"2".equals(member.getIdentityType()) || member.getSchoolId() == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
H5EducationVo vo = buildEducationVo(member);
|
|
||||||
log.info("H5获取教育身份: memberId={}, provinceId={}, cityId={}, districtId={}, schoolId={}",
|
|
||||||
memberId, vo.getProvinceId(), vo.getCityId(), vo.getDistrictId(), vo.getSchoolId());
|
|
||||||
return vo;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public void deleteEducation() {
|
|
||||||
Long memberId = getCurrentMemberId();
|
|
||||||
PgMember member = memberMapper.selectById(memberId);
|
|
||||||
if (member == null) {
|
|
||||||
throw new ServiceException("会员不存在");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 清除教育信息
|
|
||||||
member.setIdentityType(null);
|
|
||||||
member.setSchoolId(null);
|
|
||||||
member.setSchoolGradeId(null);
|
|
||||||
member.setSchoolClassId(null);
|
|
||||||
member.setRemark(null);
|
|
||||||
memberMapper.updateById(member);
|
|
||||||
|
|
||||||
log.info("H5教育身份删除: memberId={}", memberId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void bindStudent(H5StudentBindDto dto) {
|
public void bindStudent(H5StudentBindDto dto) {
|
||||||
Long memberId = getCurrentMemberId();
|
Long memberId = getCurrentMemberId();
|
||||||
PgMember member = memberMapper.selectById(memberId);
|
|
||||||
if (member == null) {
|
|
||||||
throw new ServiceException("会员不存在");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 校验学校、年级、班级是否存在
|
// 校验学校、年级、班级是否存在
|
||||||
validateSchoolInfo(dto.getSchoolId(), dto.getSchoolGradeId(), dto.getSchoolClassId());
|
validateSchoolInfo(dto.getSchoolId(), dto.getSchoolGradeId(), dto.getSchoolClassId());
|
||||||
|
|
@ -247,12 +303,6 @@ public class H5MemberServiceImpl implements H5MemberService {
|
||||||
student.setStatus("0");
|
student.setStatus("0");
|
||||||
studentMapper.insert(student);
|
studentMapper.insert(student);
|
||||||
|
|
||||||
// 如果会员没有身份,默认设为家长
|
|
||||||
if (StringUtils.isBlank(member.getIdentityType())) {
|
|
||||||
member.setIdentityType("1"); // 家长
|
|
||||||
memberMapper.updateById(member);
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info("H5绑定学生: memberId={}, studentId={}", memberId, student.getStudentId());
|
log.info("H5绑定学生: memberId={}, studentId={}", memberId, student.getStudentId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -348,14 +398,17 @@ public class H5MemberServiceImpl implements H5MemberService {
|
||||||
/**
|
/**
|
||||||
* 构建教育身份VO
|
* 构建教育身份VO
|
||||||
*/
|
*/
|
||||||
private H5EducationVo buildEducationVo(PgMember member) {
|
private H5EducationVo buildEducationVo(PgEducation education) {
|
||||||
H5EducationVo vo = new H5EducationVo();
|
H5EducationVo vo = new H5EducationVo();
|
||||||
vo.setSchoolId(member.getSchoolId());
|
vo.setEducationId(education.getEducationId());
|
||||||
vo.setSchoolGradeId(member.getSchoolGradeId());
|
vo.setSchoolId(education.getSchoolId());
|
||||||
vo.setSchoolClassId(member.getSchoolClassId());
|
vo.setSchoolGradeId(education.getSchoolGradeId());
|
||||||
|
vo.setSchoolClassId(education.getSchoolClassId());
|
||||||
|
vo.setSubjectId(education.getSubjectId());
|
||||||
|
vo.setIsDefault(education.getIsDefault());
|
||||||
|
|
||||||
// 获取学校名称和区域信息
|
// 获取学校名称和区域信息
|
||||||
PgSchool school = schoolMapper.selectById(member.getSchoolId());
|
PgSchool school = schoolMapper.selectById(education.getSchoolId());
|
||||||
if (school != null) {
|
if (school != null) {
|
||||||
vo.setSchoolName(school.getSchoolName());
|
vo.setSchoolName(school.getSchoolName());
|
||||||
|
|
||||||
|
|
@ -366,12 +419,9 @@ public class H5MemberServiceImpl implements H5MemberService {
|
||||||
vo.setDistrictId(district.getRegionId());
|
vo.setDistrictId(district.getRegionId());
|
||||||
vo.setDistrictName(district.getRegionName());
|
vo.setDistrictName(district.getRegionName());
|
||||||
|
|
||||||
// 根据ancestors获取省市信息,格式如 "0,42,4201"
|
// 根据ancestors获取省市信息
|
||||||
if (StringUtils.isNotBlank(district.getAncestors())) {
|
if (StringUtils.isNotBlank(district.getAncestors())) {
|
||||||
String[] ancestorIds = district.getAncestors().split(",");
|
String[] ancestorIds = district.getAncestors().split(",");
|
||||||
// ancestorIds[0] = "0" (根节点)
|
|
||||||
// ancestorIds[1] = 省份ID
|
|
||||||
// ancestorIds[2] = 城市ID
|
|
||||||
if (ancestorIds.length >= 2 && !"0".equals(ancestorIds[1])) {
|
if (ancestorIds.length >= 2 && !"0".equals(ancestorIds[1])) {
|
||||||
try {
|
try {
|
||||||
Long provinceId = Long.parseLong(ancestorIds[1].trim());
|
Long provinceId = Long.parseLong(ancestorIds[1].trim());
|
||||||
|
|
@ -402,7 +452,7 @@ public class H5MemberServiceImpl implements H5MemberService {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取年级名称
|
// 获取年级名称
|
||||||
PgSchoolGrade schoolGrade = schoolGradeMapper.selectById(member.getSchoolGradeId());
|
PgSchoolGrade schoolGrade = schoolGradeMapper.selectById(education.getSchoolGradeId());
|
||||||
if (schoolGrade != null && schoolGrade.getGradeId() != null) {
|
if (schoolGrade != null && schoolGrade.getGradeId() != null) {
|
||||||
PgGrade grade = gradeMapper.selectById(schoolGrade.getGradeId());
|
PgGrade grade = gradeMapper.selectById(schoolGrade.getGradeId());
|
||||||
if (grade != null) {
|
if (grade != null) {
|
||||||
|
|
@ -411,7 +461,7 @@ public class H5MemberServiceImpl implements H5MemberService {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取班级名称
|
// 获取班级名称
|
||||||
PgSchoolClass schoolClass = schoolClassMapper.selectById(member.getSchoolClassId());
|
PgSchoolClass schoolClass = schoolClassMapper.selectById(education.getSchoolClassId());
|
||||||
if (schoolClass != null && schoolClass.getClassId() != null) {
|
if (schoolClass != null && schoolClass.getClassId() != null) {
|
||||||
PgClass cls = classMapper.selectById(schoolClass.getClassId());
|
PgClass cls = classMapper.selectById(schoolClass.getClassId());
|
||||||
if (cls != null) {
|
if (cls != null) {
|
||||||
|
|
@ -419,18 +469,12 @@ public class H5MemberServiceImpl implements H5MemberService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取学科信息(从remark解析)
|
// 获取学科名称
|
||||||
if (StringUtils.isNotBlank(member.getRemark()) && member.getRemark().startsWith("subjectId:")) {
|
if (education.getSubjectId() != null) {
|
||||||
try {
|
PgSubject subject = subjectMapper.selectById(education.getSubjectId());
|
||||||
Long subjectId = Long.parseLong(member.getRemark().replace("subjectId:", ""));
|
|
||||||
vo.setSubjectId(subjectId);
|
|
||||||
PgSubject subject = subjectMapper.selectById(subjectId);
|
|
||||||
if (subject != null) {
|
if (subject != null) {
|
||||||
vo.setSubjectName(subject.getSubjectName());
|
vo.setSubjectName(subject.getSubjectName());
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
// 忽略解析错误
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return vo;
|
return vo;
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,11 @@ import org.dromara.common.mybatis.core.page.PageQuery;
|
||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
import org.dromara.common.web.core.BaseController;
|
import org.dromara.common.web.core.BaseController;
|
||||||
import org.dromara.pangu.member.domain.PgMember;
|
import org.dromara.pangu.member.domain.PgMember;
|
||||||
|
import org.dromara.pangu.member.domain.dto.EducationDto;
|
||||||
|
import org.dromara.pangu.member.domain.dto.MemberSaveDto;
|
||||||
|
import org.dromara.pangu.member.domain.vo.EducationVo;
|
||||||
import org.dromara.pangu.member.service.IPgMemberService;
|
import org.dromara.pangu.member.service.IPgMemberService;
|
||||||
|
import org.dromara.pangu.member.service.IPgEducationService;
|
||||||
import org.dromara.pangu.student.domain.vo.StudentVo;
|
import org.dromara.pangu.student.domain.vo.StudentVo;
|
||||||
import org.dromara.pangu.student.service.IPgStudentService;
|
import org.dromara.pangu.student.service.IPgStudentService;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
@ -32,6 +36,7 @@ public class PgMemberController extends BaseController {
|
||||||
|
|
||||||
private final IPgMemberService memberService;
|
private final IPgMemberService memberService;
|
||||||
private final IPgStudentService studentService;
|
private final IPgStudentService studentService;
|
||||||
|
private final IPgEducationService educationService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询会员列表
|
* 查询会员列表
|
||||||
|
|
@ -52,23 +57,25 @@ public class PgMemberController extends BaseController {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增会员
|
* 新增会员(支持同时保存教育身份)
|
||||||
*/
|
*/
|
||||||
@SaCheckPermission("business:member:add")
|
@SaCheckPermission("business:member:add")
|
||||||
@Log(title = "会员管理", businessType = BusinessType.INSERT)
|
@Log(title = "会员管理", businessType = BusinessType.INSERT)
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public R<Void> add(@Validated @RequestBody PgMember member) {
|
public R<Void> add(@Validated @RequestBody MemberSaveDto dto) {
|
||||||
return toAjax(memberService.insert(member));
|
memberService.insertWithEducations(dto);
|
||||||
|
return R.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改会员
|
* 修改会员(支持同时保存教育身份)
|
||||||
*/
|
*/
|
||||||
@SaCheckPermission("business:member:edit")
|
@SaCheckPermission("business:member:edit")
|
||||||
@Log(title = "会员管理", businessType = BusinessType.UPDATE)
|
@Log(title = "会员管理", businessType = BusinessType.UPDATE)
|
||||||
@PutMapping
|
@PutMapping
|
||||||
public R<Void> edit(@Validated @RequestBody PgMember member) {
|
public R<Void> edit(@Validated @RequestBody MemberSaveDto dto) {
|
||||||
return toAjax(memberService.update(member));
|
memberService.updateWithEducations(dto);
|
||||||
|
return R.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -139,4 +146,59 @@ public class PgMemberController extends BaseController {
|
||||||
public R<Void> unbindStudent(@PathVariable Long studentId) {
|
public R<Void> unbindStudent(@PathVariable Long studentId) {
|
||||||
return toAjax(studentService.unbindStudent(studentId));
|
return toAjax(studentService.unbindStudent(studentId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================== 教育身份管理 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取会员教育身份列表
|
||||||
|
*/
|
||||||
|
@GetMapping("/{memberId}/educations")
|
||||||
|
public R<List<EducationVo>> getEducations(@PathVariable Long memberId) {
|
||||||
|
return R.ok(educationService.getEducationsByMemberId(memberId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加教育身份
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("business:member:edit")
|
||||||
|
@Log(title = "会员管理-添加教育身份", businessType = BusinessType.INSERT)
|
||||||
|
@PostMapping("/{memberId}/educations")
|
||||||
|
public R<Void> addEducation(@PathVariable Long memberId, @Validated @RequestBody EducationDto dto) {
|
||||||
|
educationService.addEducation(memberId, dto);
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改教育身份
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("business:member:edit")
|
||||||
|
@Log(title = "会员管理-修改教育身份", businessType = BusinessType.UPDATE)
|
||||||
|
@PutMapping("/{memberId}/educations/{educationId}")
|
||||||
|
public R<Void> updateEducation(@PathVariable Long memberId, @PathVariable Long educationId,
|
||||||
|
@Validated @RequestBody EducationDto dto) {
|
||||||
|
educationService.updateEducation(memberId, educationId, dto);
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除教育身份
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("business:member:edit")
|
||||||
|
@Log(title = "会员管理-删除教育身份", businessType = BusinessType.DELETE)
|
||||||
|
@DeleteMapping("/{memberId}/educations/{educationId}")
|
||||||
|
public R<Void> deleteEducation(@PathVariable Long memberId, @PathVariable Long educationId) {
|
||||||
|
educationService.deleteEducation(memberId, educationId);
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置默认教育身份
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("business:member:edit")
|
||||||
|
@Log(title = "会员管理-设置默认身份", businessType = BusinessType.UPDATE)
|
||||||
|
@PutMapping("/{memberId}/educations/{educationId}/default")
|
||||||
|
public R<Void> setDefaultEducation(@PathVariable Long memberId, @PathVariable Long educationId) {
|
||||||
|
educationService.setDefaultEducation(memberId, educationId);
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package org.dromara.pangu.member.domain;
|
package org.dromara.pangu.member.domain;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
|
@ -10,7 +9,6 @@ import lombok.EqualsAndHashCode;
|
||||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 会员表
|
* 会员表
|
||||||
|
|
@ -42,29 +40,10 @@ public class PgMember extends BaseEntity {
|
||||||
|
|
||||||
private Date birthday;
|
private Date birthday;
|
||||||
|
|
||||||
/**
|
|
||||||
* 身份类型(1家长 2教师)
|
|
||||||
*/
|
|
||||||
private String identityType;
|
|
||||||
|
|
||||||
private String openId;
|
private String openId;
|
||||||
|
|
||||||
private String unionId;
|
private String unionId;
|
||||||
|
|
||||||
private Long regionId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 区域ID路径(非数据库字段,用于级联选择器回显)
|
|
||||||
*/
|
|
||||||
@TableField(exist = false)
|
|
||||||
private List<Long> regionIds;
|
|
||||||
|
|
||||||
private Long schoolId;
|
|
||||||
|
|
||||||
private Long schoolGradeId;
|
|
||||||
|
|
||||||
private Long schoolClassId;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注册来源(1小程序 2H5 3后台 4导入)
|
* 注册来源(1小程序 2H5 3后台 4导入)
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
package org.dromara.pangu.member.domain.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 教育身份请求DTO
|
||||||
|
*
|
||||||
|
* @author 湖北新华业务中台研发团队
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "教育身份请求")
|
||||||
|
public class EducationDto {
|
||||||
|
|
||||||
|
@Schema(description = "区域ID")
|
||||||
|
private Long regionId;
|
||||||
|
|
||||||
|
@NotNull(message = "学校不能为空")
|
||||||
|
@Schema(description = "学校ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private Long schoolId;
|
||||||
|
|
||||||
|
@NotNull(message = "年级不能为空")
|
||||||
|
@Schema(description = "年级ID(school_grade关联ID)", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private Long schoolGradeId;
|
||||||
|
|
||||||
|
@NotNull(message = "班级不能为空")
|
||||||
|
@Schema(description = "班级ID(school_class关联ID)", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private Long schoolClassId;
|
||||||
|
|
||||||
|
@Schema(description = "学科ID")
|
||||||
|
private Long subjectId;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
package org.dromara.pangu.member.domain.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Pattern;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员保存请求DTO(支持同时保存教育身份)
|
||||||
|
*
|
||||||
|
* @author 湖北新华业务中台研发团队
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "会员保存请求")
|
||||||
|
public class MemberSaveDto {
|
||||||
|
|
||||||
|
@Schema(description = "会员ID(新增时不传,编辑时必传)")
|
||||||
|
private Long memberId;
|
||||||
|
|
||||||
|
@NotBlank(message = "手机号不能为空")
|
||||||
|
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
|
||||||
|
@Schema(description = "手机号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private String phone;
|
||||||
|
|
||||||
|
@Schema(description = "昵称")
|
||||||
|
private String nickname;
|
||||||
|
|
||||||
|
@Schema(description = "性别(0未知 1男 2女)")
|
||||||
|
private String gender;
|
||||||
|
|
||||||
|
@Schema(description = "出生日期")
|
||||||
|
private Date birthday;
|
||||||
|
|
||||||
|
@Schema(description = "状态(0正常 1停用)")
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Schema(description = "教育身份列表")
|
||||||
|
private List<EducationDto> educations;
|
||||||
|
|
||||||
|
@Schema(description = "绑定的学生ID列表(亲子关系)")
|
||||||
|
private List<Long> studentIds;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
package org.dromara.pangu.member.domain.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 教育身份响应VO
|
||||||
|
*
|
||||||
|
* @author 湖北新华业务中台研发团队
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "教育身份信息")
|
||||||
|
public class EducationVo {
|
||||||
|
|
||||||
|
@Schema(description = "教育身份ID")
|
||||||
|
private Long educationId;
|
||||||
|
|
||||||
|
@Schema(description = "区域ID")
|
||||||
|
private Long regionId;
|
||||||
|
|
||||||
|
@Schema(description = "区域名称(省/市/区)")
|
||||||
|
private String regionName;
|
||||||
|
|
||||||
|
@Schema(description = "学校ID")
|
||||||
|
private Long schoolId;
|
||||||
|
|
||||||
|
@Schema(description = "学校名称")
|
||||||
|
private String schoolName;
|
||||||
|
|
||||||
|
@Schema(description = "年级ID(school_grade关联ID)")
|
||||||
|
private Long schoolGradeId;
|
||||||
|
|
||||||
|
@Schema(description = "年级名称")
|
||||||
|
private String gradeName;
|
||||||
|
|
||||||
|
@Schema(description = "班级ID(school_class关联ID)")
|
||||||
|
private Long schoolClassId;
|
||||||
|
|
||||||
|
@Schema(description = "班级名称")
|
||||||
|
private String className;
|
||||||
|
|
||||||
|
@Schema(description = "学科ID")
|
||||||
|
private Long subjectId;
|
||||||
|
|
||||||
|
@Schema(description = "学科名称")
|
||||||
|
private String subjectName;
|
||||||
|
|
||||||
|
@Schema(description = "是否默认身份(0否 1是)")
|
||||||
|
private String isDefault;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
package org.dromara.pangu.member.service;
|
||||||
|
|
||||||
|
import org.dromara.pangu.member.domain.dto.EducationDto;
|
||||||
|
import org.dromara.pangu.member.domain.vo.EducationVo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 教育身份管理 Service 接口
|
||||||
|
*
|
||||||
|
* @author 湖北新华业务中台研发团队
|
||||||
|
*/
|
||||||
|
public interface IPgEducationService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取会员的教育身份列表
|
||||||
|
*/
|
||||||
|
List<EducationVo> getEducationsByMemberId(Long memberId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加教育身份
|
||||||
|
*/
|
||||||
|
void addEducation(Long memberId, EducationDto dto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改教育身份
|
||||||
|
*/
|
||||||
|
void updateEducation(Long memberId, Long educationId, EducationDto dto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除教育身份
|
||||||
|
*/
|
||||||
|
void deleteEducation(Long memberId, Long educationId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置默认教育身份
|
||||||
|
*/
|
||||||
|
void setDefaultEducation(Long memberId, Long educationId);
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ package org.dromara.pangu.member.service;
|
||||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
import org.dromara.pangu.member.domain.PgMember;
|
import org.dromara.pangu.member.domain.PgMember;
|
||||||
|
import org.dromara.pangu.member.domain.dto.MemberSaveDto;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
@ -33,6 +34,16 @@ public interface IPgMemberService {
|
||||||
*/
|
*/
|
||||||
int insert(PgMember member);
|
int insert(PgMember member);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增会员(支持同时保存教育身份)
|
||||||
|
*/
|
||||||
|
void insertWithEducations(MemberSaveDto dto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改会员(支持同时保存教育身份)
|
||||||
|
*/
|
||||||
|
void updateWithEducations(MemberSaveDto dto);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改会员
|
* 修改会员
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,267 @@
|
||||||
|
package org.dromara.pangu.member.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
|
import org.dromara.pangu.base.domain.PgClass;
|
||||||
|
import org.dromara.pangu.base.domain.PgEducation;
|
||||||
|
import org.dromara.pangu.base.domain.PgGrade;
|
||||||
|
import org.dromara.pangu.base.domain.PgRegion;
|
||||||
|
import org.dromara.pangu.base.domain.PgSubject;
|
||||||
|
import org.dromara.pangu.base.mapper.PgClassMapper;
|
||||||
|
import org.dromara.pangu.base.mapper.PgEducationMapper;
|
||||||
|
import org.dromara.pangu.base.mapper.PgGradeMapper;
|
||||||
|
import org.dromara.pangu.base.mapper.PgRegionMapper;
|
||||||
|
import org.dromara.pangu.base.mapper.PgSubjectMapper;
|
||||||
|
import org.dromara.pangu.member.domain.dto.EducationDto;
|
||||||
|
import org.dromara.pangu.member.domain.vo.EducationVo;
|
||||||
|
import org.dromara.pangu.member.service.IPgEducationService;
|
||||||
|
import org.dromara.pangu.school.domain.PgSchool;
|
||||||
|
import org.dromara.pangu.school.domain.PgSchoolClass;
|
||||||
|
import org.dromara.pangu.school.domain.PgSchoolGrade;
|
||||||
|
import org.dromara.pangu.school.mapper.PgSchoolClassMapper;
|
||||||
|
import org.dromara.pangu.school.mapper.PgSchoolGradeMapper;
|
||||||
|
import org.dromara.pangu.school.mapper.PgSchoolMapper;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 教育身份管理 Service 实现
|
||||||
|
*
|
||||||
|
* @author 湖北新华业务中台研发团队
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Service
|
||||||
|
public class PgEducationServiceImpl implements IPgEducationService {
|
||||||
|
|
||||||
|
private final PgEducationMapper educationMapper;
|
||||||
|
private final PgSchoolMapper schoolMapper;
|
||||||
|
private final PgSchoolGradeMapper schoolGradeMapper;
|
||||||
|
private final PgSchoolClassMapper schoolClassMapper;
|
||||||
|
private final PgGradeMapper gradeMapper;
|
||||||
|
private final PgClassMapper classMapper;
|
||||||
|
private final PgSubjectMapper subjectMapper;
|
||||||
|
private final PgRegionMapper regionMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<EducationVo> getEducationsByMemberId(Long memberId) {
|
||||||
|
List<PgEducation> educations = educationMapper.selectList(
|
||||||
|
new LambdaQueryWrapper<PgEducation>()
|
||||||
|
.eq(PgEducation::getMemberId, memberId)
|
||||||
|
.eq(PgEducation::getDelFlag, "0")
|
||||||
|
.orderByDesc(PgEducation::getIsDefault)
|
||||||
|
.orderByDesc(PgEducation::getCreateTime)
|
||||||
|
);
|
||||||
|
|
||||||
|
List<EducationVo> voList = new ArrayList<>();
|
||||||
|
for (PgEducation education : educations) {
|
||||||
|
voList.add(buildEducationVo(education));
|
||||||
|
}
|
||||||
|
return voList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void addEducation(Long memberId, EducationDto dto) {
|
||||||
|
// 校验学校信息
|
||||||
|
PgSchool school = validateAndGetSchool(dto);
|
||||||
|
|
||||||
|
// 创建教育身份
|
||||||
|
PgEducation education = new PgEducation();
|
||||||
|
education.setMemberId(memberId);
|
||||||
|
education.setRegionId(school.getRegionId());
|
||||||
|
education.setSchoolId(dto.getSchoolId());
|
||||||
|
education.setSchoolGradeId(dto.getSchoolGradeId());
|
||||||
|
education.setSchoolClassId(dto.getSchoolClassId());
|
||||||
|
education.setSubjectId(dto.getSubjectId());
|
||||||
|
education.setStatus("0");
|
||||||
|
|
||||||
|
// 如果是第一个教育身份,设为默认
|
||||||
|
long count = educationMapper.selectCount(
|
||||||
|
new LambdaQueryWrapper<PgEducation>()
|
||||||
|
.eq(PgEducation::getMemberId, memberId)
|
||||||
|
.eq(PgEducation::getDelFlag, "0")
|
||||||
|
);
|
||||||
|
education.setIsDefault(count == 0 ? "1" : "0");
|
||||||
|
|
||||||
|
educationMapper.insert(education);
|
||||||
|
log.info("添加教育身份: memberId={}, educationId={}", memberId, education.getEducationId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void updateEducation(Long memberId, Long educationId, EducationDto dto) {
|
||||||
|
// 查询并校验归属
|
||||||
|
PgEducation education = educationMapper.selectById(educationId);
|
||||||
|
if (education == null || !memberId.equals(education.getMemberId())) {
|
||||||
|
throw new ServiceException("教育身份不存在或无权限修改");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验学校信息
|
||||||
|
PgSchool school = validateAndGetSchool(dto);
|
||||||
|
|
||||||
|
// 更新
|
||||||
|
education.setRegionId(school.getRegionId());
|
||||||
|
education.setSchoolId(dto.getSchoolId());
|
||||||
|
education.setSchoolGradeId(dto.getSchoolGradeId());
|
||||||
|
education.setSchoolClassId(dto.getSchoolClassId());
|
||||||
|
education.setSubjectId(dto.getSubjectId());
|
||||||
|
educationMapper.updateById(education);
|
||||||
|
|
||||||
|
log.info("修改教育身份: memberId={}, educationId={}", memberId, educationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void deleteEducation(Long memberId, Long educationId) {
|
||||||
|
PgEducation education = educationMapper.selectById(educationId);
|
||||||
|
if (education == null || !memberId.equals(education.getMemberId())) {
|
||||||
|
throw new ServiceException("教育身份不存在或无权限删除");
|
||||||
|
}
|
||||||
|
|
||||||
|
educationMapper.deleteById(educationId);
|
||||||
|
log.info("删除教育身份: memberId={}, educationId={}", memberId, educationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void setDefaultEducation(Long memberId, Long educationId) {
|
||||||
|
PgEducation education = educationMapper.selectById(educationId);
|
||||||
|
if (education == null || !memberId.equals(education.getMemberId())) {
|
||||||
|
throw new ServiceException("教育身份不存在或无权限操作");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消其他默认
|
||||||
|
PgEducation updateEntity = new PgEducation();
|
||||||
|
updateEntity.setIsDefault("0");
|
||||||
|
educationMapper.update(updateEntity,
|
||||||
|
new LambdaQueryWrapper<PgEducation>()
|
||||||
|
.eq(PgEducation::getMemberId, memberId)
|
||||||
|
.eq(PgEducation::getIsDefault, "1")
|
||||||
|
);
|
||||||
|
|
||||||
|
// 设置当前为默认
|
||||||
|
education.setIsDefault("1");
|
||||||
|
educationMapper.updateById(education);
|
||||||
|
|
||||||
|
log.info("设置默认教育身份: memberId={}, educationId={}", memberId, educationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验学校信息
|
||||||
|
*/
|
||||||
|
private PgSchool validateAndGetSchool(EducationDto dto) {
|
||||||
|
PgSchool school = schoolMapper.selectById(dto.getSchoolId());
|
||||||
|
if (school == null) {
|
||||||
|
throw new ServiceException("学校不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
PgSchoolGrade schoolGrade = schoolGradeMapper.selectById(dto.getSchoolGradeId());
|
||||||
|
if (schoolGrade == null || !schoolGrade.getSchoolId().equals(dto.getSchoolId())) {
|
||||||
|
throw new ServiceException("年级不存在或不属于该学校");
|
||||||
|
}
|
||||||
|
|
||||||
|
PgSchoolClass schoolClass = schoolClassMapper.selectById(dto.getSchoolClassId());
|
||||||
|
if (schoolClass == null || !schoolClass.getSchoolGradeId().equals(dto.getSchoolGradeId())) {
|
||||||
|
throw new ServiceException("班级不存在或不属于该年级");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dto.getSubjectId() != null) {
|
||||||
|
PgSubject subject = subjectMapper.selectById(dto.getSubjectId());
|
||||||
|
if (subject == null) {
|
||||||
|
throw new ServiceException("学科不存在");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return school;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建教育身份VO
|
||||||
|
*/
|
||||||
|
private EducationVo buildEducationVo(PgEducation education) {
|
||||||
|
EducationVo vo = new EducationVo();
|
||||||
|
vo.setEducationId(education.getEducationId());
|
||||||
|
vo.setSchoolId(education.getSchoolId());
|
||||||
|
vo.setSchoolGradeId(education.getSchoolGradeId());
|
||||||
|
vo.setSchoolClassId(education.getSchoolClassId());
|
||||||
|
vo.setSubjectId(education.getSubjectId());
|
||||||
|
vo.setIsDefault(education.getIsDefault());
|
||||||
|
|
||||||
|
// 获取学校和区域信息
|
||||||
|
PgSchool school = schoolMapper.selectById(education.getSchoolId());
|
||||||
|
if (school != null) {
|
||||||
|
vo.setSchoolName(school.getSchoolName());
|
||||||
|
vo.setRegionId(school.getRegionId());
|
||||||
|
|
||||||
|
// 构建区域全名
|
||||||
|
if (school.getRegionId() != null) {
|
||||||
|
vo.setRegionName(buildRegionFullName(school.getRegionId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取年级名称
|
||||||
|
PgSchoolGrade schoolGrade = schoolGradeMapper.selectById(education.getSchoolGradeId());
|
||||||
|
if (schoolGrade != null && schoolGrade.getGradeId() != null) {
|
||||||
|
PgGrade grade = gradeMapper.selectById(schoolGrade.getGradeId());
|
||||||
|
if (grade != null) {
|
||||||
|
vo.setGradeName(grade.getGradeName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取班级名称
|
||||||
|
PgSchoolClass schoolClass = schoolClassMapper.selectById(education.getSchoolClassId());
|
||||||
|
if (schoolClass != null && schoolClass.getClassId() != null) {
|
||||||
|
PgClass cls = classMapper.selectById(schoolClass.getClassId());
|
||||||
|
if (cls != null) {
|
||||||
|
vo.setClassName(cls.getClassName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取学科名称
|
||||||
|
if (education.getSubjectId() != null) {
|
||||||
|
PgSubject subject = subjectMapper.selectById(education.getSubjectId());
|
||||||
|
if (subject != null) {
|
||||||
|
vo.setSubjectName(subject.getSubjectName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return vo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建区域全名(省/市/区)
|
||||||
|
*/
|
||||||
|
private String buildRegionFullName(Long regionId) {
|
||||||
|
PgRegion district = regionMapper.selectById(regionId);
|
||||||
|
if (district == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
if (StringUtils.isNotBlank(district.getAncestors())) {
|
||||||
|
String[] ancestorIds = district.getAncestors().split(",");
|
||||||
|
for (String idStr : ancestorIds) {
|
||||||
|
if (!"0".equals(idStr.trim())) {
|
||||||
|
try {
|
||||||
|
PgRegion ancestor = regionMapper.selectById(Long.parseLong(idStr.trim()));
|
||||||
|
if (ancestor != null) {
|
||||||
|
if (sb.length() > 0) sb.append("/");
|
||||||
|
sb.append(ancestor.getRegionName());
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sb.length() > 0) sb.append("/");
|
||||||
|
sb.append(district.getRegionName());
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,22 +5,23 @@ 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.plugins.pagination.Page;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.dromara.common.core.exception.ServiceException;
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
import org.dromara.pangu.base.domain.PgRegion;
|
|
||||||
import org.dromara.pangu.base.mapper.PgRegionMapper;
|
|
||||||
import org.dromara.pangu.member.domain.PgMember;
|
import org.dromara.pangu.member.domain.PgMember;
|
||||||
|
import org.dromara.pangu.member.domain.dto.EducationDto;
|
||||||
|
import org.dromara.pangu.member.domain.dto.MemberSaveDto;
|
||||||
import org.dromara.pangu.member.mapper.PgMemberMapper;
|
import org.dromara.pangu.member.mapper.PgMemberMapper;
|
||||||
|
import org.dromara.pangu.member.service.IPgEducationService;
|
||||||
import org.dromara.pangu.member.service.IPgMemberService;
|
import org.dromara.pangu.member.service.IPgMemberService;
|
||||||
import org.dromara.pangu.student.mapper.PgStudentMapper;
|
import org.dromara.pangu.student.mapper.PgStudentMapper;
|
||||||
|
import org.dromara.pangu.student.service.IPgStudentService;
|
||||||
import cn.hutool.crypto.digest.BCrypt;
|
import cn.hutool.crypto.digest.BCrypt;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
@ -29,13 +30,15 @@ import java.util.List;
|
||||||
*
|
*
|
||||||
* @author pangu
|
* @author pangu
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Service
|
@Service
|
||||||
public class PgMemberServiceImpl implements IPgMemberService {
|
public class PgMemberServiceImpl implements IPgMemberService {
|
||||||
|
|
||||||
private final PgMemberMapper baseMapper;
|
private final PgMemberMapper baseMapper;
|
||||||
private final PgStudentMapper studentMapper;
|
private final PgStudentMapper studentMapper;
|
||||||
private final PgRegionMapper regionMapper;
|
private final IPgEducationService educationService;
|
||||||
|
private final IPgStudentService studentService;
|
||||||
|
|
||||||
private static final String DEFAULT_PASSWORD = "123456";
|
private static final String DEFAULT_PASSWORD = "123456";
|
||||||
|
|
||||||
|
|
@ -53,29 +56,7 @@ public class PgMemberServiceImpl implements IPgMemberService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PgMember selectById(Long memberId) {
|
public PgMember selectById(Long memberId) {
|
||||||
PgMember member = baseMapper.selectById(memberId);
|
return baseMapper.selectById(memberId);
|
||||||
if (member != null && member.getRegionId() != null) {
|
|
||||||
// 查询区域的完整路径用于级联选择器回显
|
|
||||||
member.setRegionIds(getRegionPath(member.getRegionId()));
|
|
||||||
}
|
|
||||||
return member;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取区域的完整路径(从根到当前节点的ID列表)
|
|
||||||
*/
|
|
||||||
private List<Long> getRegionPath(Long regionId) {
|
|
||||||
List<Long> path = new ArrayList<>();
|
|
||||||
Long currentId = regionId;
|
|
||||||
while (currentId != null && currentId > 0) {
|
|
||||||
path.add(0, currentId);
|
|
||||||
PgRegion region = regionMapper.selectById(currentId);
|
|
||||||
if (region == null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
currentId = region.getParentId();
|
|
||||||
}
|
|
||||||
return path;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -112,12 +93,63 @@ public class PgMemberServiceImpl implements IPgMemberService {
|
||||||
member.setStatus("0");
|
member.setStatus("0");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 教师身份校验必填字段
|
|
||||||
validateTeacherInfo(member);
|
|
||||||
|
|
||||||
return baseMapper.insert(member);
|
return baseMapper.insert(member);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void insertWithEducations(MemberSaveDto dto) {
|
||||||
|
log.info("新增会员: phone={}, educations={}, studentIds={}",
|
||||||
|
dto.getPhone(),
|
||||||
|
dto.getEducations() != null ? dto.getEducations().size() : 0,
|
||||||
|
dto.getStudentIds() != null ? dto.getStudentIds() : "null");
|
||||||
|
|
||||||
|
// 创建会员
|
||||||
|
PgMember member = new PgMember();
|
||||||
|
member.setPhone(dto.getPhone());
|
||||||
|
member.setNickname(dto.getNickname());
|
||||||
|
member.setGender(dto.getGender());
|
||||||
|
member.setBirthday(dto.getBirthday());
|
||||||
|
member.setStatus(dto.getStatus());
|
||||||
|
insert(member);
|
||||||
|
|
||||||
|
Long memberId = member.getMemberId();
|
||||||
|
|
||||||
|
// 保存教育身份
|
||||||
|
if (dto.getEducations() != null && !dto.getEducations().isEmpty()) {
|
||||||
|
log.info("保存教育身份: memberId={}, count={}", memberId, dto.getEducations().size());
|
||||||
|
for (EducationDto eduDto : dto.getEducations()) {
|
||||||
|
educationService.addEducation(memberId, eduDto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绑定学生(亲子关系)
|
||||||
|
if (dto.getStudentIds() != null && !dto.getStudentIds().isEmpty()) {
|
||||||
|
log.info("绑定学生: memberId={}, studentIds={}", memberId, dto.getStudentIds());
|
||||||
|
studentService.bindStudentsToMember(memberId, dto.getStudentIds());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void updateWithEducations(MemberSaveDto dto) {
|
||||||
|
if (dto.getMemberId() == null) {
|
||||||
|
throw new ServiceException("会员ID不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新会员基本信息
|
||||||
|
PgMember member = new PgMember();
|
||||||
|
member.setMemberId(dto.getMemberId());
|
||||||
|
member.setPhone(dto.getPhone());
|
||||||
|
member.setNickname(dto.getNickname());
|
||||||
|
member.setGender(dto.getGender());
|
||||||
|
member.setBirthday(dto.getBirthday());
|
||||||
|
member.setStatus(dto.getStatus());
|
||||||
|
update(member);
|
||||||
|
|
||||||
|
// 注意:编辑时教育身份通过单独的接口管理,这里不处理
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public int update(PgMember member) {
|
public int update(PgMember member) {
|
||||||
|
|
@ -126,17 +158,6 @@ public class PgMemberServiceImpl implements IPgMemberService {
|
||||||
throw new ServiceException("手机号已存在");
|
throw new ServiceException("手机号已存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 教师身份校验必填字段
|
|
||||||
validateTeacherInfo(member);
|
|
||||||
|
|
||||||
// 家长身份清空学校信息
|
|
||||||
if ("1".equals(member.getIdentityType())) {
|
|
||||||
member.setRegionId(null);
|
|
||||||
member.setSchoolId(null);
|
|
||||||
member.setSchoolGradeId(null);
|
|
||||||
member.setSchoolClassId(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 不更新密码(密码通过重置接口更新)
|
// 不更新密码(密码通过重置接口更新)
|
||||||
member.setPassword(null);
|
member.setPassword(null);
|
||||||
|
|
||||||
|
|
@ -223,31 +244,10 @@ public class PgMemberServiceImpl implements IPgMemberService {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 校验教师身份必填字段
|
|
||||||
*/
|
|
||||||
private void validateTeacherInfo(PgMember member) {
|
|
||||||
if ("2".equals(member.getIdentityType())) {
|
|
||||||
if (member.getRegionId() == null) {
|
|
||||||
throw new ServiceException("教师身份必须选择所属区域");
|
|
||||||
}
|
|
||||||
if (member.getSchoolId() == null) {
|
|
||||||
throw new ServiceException("教师身份必须选择所属学校");
|
|
||||||
}
|
|
||||||
if (member.getSchoolGradeId() == null) {
|
|
||||||
throw new ServiceException("教师身份必须选择所属年级");
|
|
||||||
}
|
|
||||||
if (member.getSchoolClassId() == null) {
|
|
||||||
throw new ServiceException("教师身份必须选择所属班级");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private LambdaQueryWrapper<PgMember> buildQueryWrapper(PgMember member) {
|
private LambdaQueryWrapper<PgMember> buildQueryWrapper(PgMember member) {
|
||||||
LambdaQueryWrapper<PgMember> lqw = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<PgMember> lqw = new LambdaQueryWrapper<>();
|
||||||
lqw.like(StrUtil.isNotBlank(member.getNickname()), PgMember::getNickname, member.getNickname());
|
lqw.like(StrUtil.isNotBlank(member.getNickname()), PgMember::getNickname, member.getNickname());
|
||||||
lqw.like(StrUtil.isNotBlank(member.getPhone()), PgMember::getPhone, member.getPhone());
|
lqw.like(StrUtil.isNotBlank(member.getPhone()), PgMember::getPhone, member.getPhone());
|
||||||
lqw.eq(StrUtil.isNotBlank(member.getIdentityType()), PgMember::getIdentityType, member.getIdentityType());
|
|
||||||
lqw.eq(StrUtil.isNotBlank(member.getStatus()), PgMember::getStatus, member.getStatus());
|
lqw.eq(StrUtil.isNotBlank(member.getStatus()), PgMember::getStatus, member.getStatus());
|
||||||
lqw.orderByDesc(PgMember::getCreateTime);
|
lqw.orderByDesc(PgMember::getCreateTime);
|
||||||
return lqw;
|
return lqw;
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ public class PgStudentController extends BaseController {
|
||||||
* @param schoolId 学校ID(教师身份时传入,限制只能选本校学生)
|
* @param schoolId 学校ID(教师身份时传入,限制只能选本校学生)
|
||||||
*/
|
*/
|
||||||
@GetMapping("/available")
|
@GetMapping("/available")
|
||||||
public TableDataInfo<PgStudent> availableStudents(
|
public TableDataInfo<StudentVo> availableStudents(
|
||||||
@RequestParam(required = false) String studentName,
|
@RequestParam(required = false) String studentName,
|
||||||
@RequestParam(required = false) String studentNo,
|
@RequestParam(required = false) String studentNo,
|
||||||
@RequestParam(required = false) Long memberId,
|
@RequestParam(required = false) Long memberId,
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ public interface IPgStudentService {
|
||||||
* @param schoolId 学校ID(教师身份时必传,限制只能选本校学生)
|
* @param schoolId 学校ID(教师身份时必传,限制只能选本校学生)
|
||||||
* @param pageQuery 分页参数
|
* @param pageQuery 分页参数
|
||||||
*/
|
*/
|
||||||
TableDataInfo<PgStudent> selectAvailableStudents(String studentName, String studentNo, Long memberId, Long schoolId, PageQuery pageQuery);
|
TableDataInfo<StudentVo> selectAvailableStudents(String studentName, String studentNo, Long memberId, Long schoolId, PageQuery pageQuery);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询会员已绑定的学生列表(包含学校、年级、班级名称)
|
* 查询会员已绑定的学生列表(包含学校、年级、班级名称)
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ import org.dromara.pangu.base.domain.PgClass;
|
||||||
import org.dromara.pangu.base.domain.PgGrade;
|
import org.dromara.pangu.base.domain.PgGrade;
|
||||||
import org.dromara.pangu.base.mapper.PgClassMapper;
|
import org.dromara.pangu.base.mapper.PgClassMapper;
|
||||||
import org.dromara.pangu.base.mapper.PgGradeMapper;
|
import org.dromara.pangu.base.mapper.PgGradeMapper;
|
||||||
|
import org.dromara.pangu.base.domain.PgEducation;
|
||||||
|
import org.dromara.pangu.base.mapper.PgEducationMapper;
|
||||||
import org.dromara.pangu.member.domain.PgMember;
|
import org.dromara.pangu.member.domain.PgMember;
|
||||||
import org.dromara.pangu.member.mapper.PgMemberMapper;
|
import org.dromara.pangu.member.mapper.PgMemberMapper;
|
||||||
import org.dromara.pangu.school.domain.PgSchool;
|
import org.dromara.pangu.school.domain.PgSchool;
|
||||||
|
|
@ -52,6 +54,7 @@ public class PgStudentServiceImpl implements IPgStudentService {
|
||||||
private final PgGradeMapper gradeMapper;
|
private final PgGradeMapper gradeMapper;
|
||||||
private final PgClassMapper classMapper;
|
private final PgClassMapper classMapper;
|
||||||
private final PgMemberMapper memberMapper;
|
private final PgMemberMapper memberMapper;
|
||||||
|
private final PgEducationMapper educationMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableDataInfo<StudentVo> selectPageList(PgStudent student, PageQuery pageQuery) {
|
public TableDataInfo<StudentVo> selectPageList(PgStudent student, PageQuery pageQuery) {
|
||||||
|
|
@ -211,7 +214,7 @@ public class PgStudentServiceImpl implements IPgStudentService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableDataInfo<PgStudent> selectAvailableStudents(String studentName, String studentNo, Long memberId, Long schoolId, PageQuery pageQuery) {
|
public TableDataInfo<StudentVo> selectAvailableStudents(String studentName, String studentNo, Long memberId, Long schoolId, PageQuery pageQuery) {
|
||||||
LambdaQueryWrapper<PgStudent> lqw = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<PgStudent> lqw = new LambdaQueryWrapper<>();
|
||||||
lqw.like(StrUtil.isNotBlank(studentName), PgStudent::getStudentName, studentName);
|
lqw.like(StrUtil.isNotBlank(studentName), PgStudent::getStudentName, studentName);
|
||||||
lqw.like(StrUtil.isNotBlank(studentNo), PgStudent::getStudentNo, studentNo);
|
lqw.like(StrUtil.isNotBlank(studentNo), PgStudent::getStudentNo, studentNo);
|
||||||
|
|
@ -224,7 +227,9 @@ public class PgStudentServiceImpl implements IPgStudentService {
|
||||||
lqw.orderByDesc(PgStudent::getCreateTime);
|
lqw.orderByDesc(PgStudent::getCreateTime);
|
||||||
|
|
||||||
Page<PgStudent> page = baseMapper.selectPage(pageQuery.build(), lqw);
|
Page<PgStudent> page = baseMapper.selectPage(pageQuery.build(), lqw);
|
||||||
return TableDataInfo.build(page);
|
// 转换为 VO,填充学校、年级、班级名称
|
||||||
|
List<StudentVo> voList = convertToVoList(page.getRecords());
|
||||||
|
return new TableDataInfo<>(voList, page.getTotal());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -344,11 +349,18 @@ public class PgStudentServiceImpl implements IPgStudentService {
|
||||||
PgMember member = findOrCreateMember(dto.getMemberPhone().trim());
|
PgMember member = findOrCreateMember(dto.getMemberPhone().trim());
|
||||||
Long memberId = member.getMemberId();
|
Long memberId = member.getMemberId();
|
||||||
|
|
||||||
// 6. 教师身份校验:教师的区域/学校/年级/班级必须与学生一致
|
// 6. 教师身份校验:检查会员是否有匹配的教育身份
|
||||||
if ("2".equals(member.getIdentityType())) {
|
List<PgEducation> educations = educationMapper.selectList(
|
||||||
String teacherError = validateTeacherStudent(member, school, schoolGrade, schoolClass);
|
new LambdaQueryWrapper<PgEducation>()
|
||||||
if (teacherError != null) {
|
.eq(PgEducation::getMemberId, memberId)
|
||||||
failList.add(createFailItem(rowNum, teacherError));
|
.eq(PgEducation::getDelFlag, "0")
|
||||||
|
);
|
||||||
|
if (!educations.isEmpty()) {
|
||||||
|
// 会员有教育身份,检查是否包含学生所在的班级
|
||||||
|
boolean hasMatchingClass = educations.stream()
|
||||||
|
.anyMatch(e -> schoolClass.getId().equals(e.getSchoolClassId()));
|
||||||
|
if (!hasMatchingClass) {
|
||||||
|
failList.add(createFailItem(rowNum, "该教师未管理学生所在班级"));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -445,12 +457,11 @@ public class PgStudentServiceImpl implements IPgStudentService {
|
||||||
return member;
|
return member;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 不存在则创建新会员(身份为家长,初始密码123456)
|
// 不存在则创建新会员(初始密码123456)
|
||||||
PgMember newMember = new PgMember();
|
PgMember newMember = new PgMember();
|
||||||
newMember.setMemberCode(generateMemberCode()); // 生成会员编码
|
newMember.setMemberCode(generateMemberCode()); // 生成会员编码
|
||||||
newMember.setPhone(phone);
|
newMember.setPhone(phone);
|
||||||
newMember.setNickname("家长" + phone.substring(7)); // 默认昵称
|
newMember.setNickname("家长" + phone.substring(7)); // 默认昵称
|
||||||
newMember.setIdentityType("1"); // 家长
|
|
||||||
newMember.setPassword(BCrypt.hashpw("123456")); // 初始密码
|
newMember.setPassword(BCrypt.hashpw("123456")); // 初始密码
|
||||||
newMember.setStatus("0"); // 正常
|
newMember.setStatus("0"); // 正常
|
||||||
newMember.setRegisterSource("4"); // 批量导入
|
newMember.setRegisterSource("4"); // 批量导入
|
||||||
|
|
@ -460,44 +471,6 @@ public class PgStudentServiceImpl implements IPgStudentService {
|
||||||
return newMember;
|
return newMember;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 校验教师与学生的归属关系
|
|
||||||
* 教师的区域/学校/年级/班级必须与学生一致
|
|
||||||
*/
|
|
||||||
private String validateTeacherStudent(PgMember teacher, PgSchool studentSchool,
|
|
||||||
PgSchoolGrade studentGrade, PgSchoolClass studentClass) {
|
|
||||||
String teacherInfo = "教师\"" + (teacher.getNickname() != null ? teacher.getNickname() : "未知")
|
|
||||||
+ "\"(" + teacher.getPhone() + ")";
|
|
||||||
|
|
||||||
// 检查教师是否设置了学校信息
|
|
||||||
if (teacher.getSchoolId() == null || teacher.getSchoolGradeId() == null || teacher.getSchoolClassId() == null) {
|
|
||||||
return teacherInfo + "未设置学校信息,无法绑定学生";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 校验区域(通过学校的区域ID间接校验)
|
|
||||||
if (teacher.getRegionId() != null && studentSchool.getRegionId() != null) {
|
|
||||||
if (!teacher.getRegionId().equals(studentSchool.getRegionId())) {
|
|
||||||
return teacherInfo + "所属区域与学生不一致";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 校验学校
|
|
||||||
if (!teacher.getSchoolId().equals(studentSchool.getSchoolId())) {
|
|
||||||
return teacherInfo + "所属学校与学生不一致";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 校验年级
|
|
||||||
if (!teacher.getSchoolGradeId().equals(studentGrade.getId())) {
|
|
||||||
return teacherInfo + "所属年级与学生不一致";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 校验班级
|
|
||||||
if (!teacher.getSchoolClassId().equals(studentClass.getId())) {
|
|
||||||
return teacherInfo + "所属班级与学生不一致";
|
|
||||||
}
|
|
||||||
|
|
||||||
return null; // 校验通过
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成会员编码(M + 年月日时分秒毫秒 + 4位随机数)
|
* 生成会员编码(M + 年月日时分秒毫秒 + 4位随机数)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,347 @@
|
||||||
|
<!--
|
||||||
|
教育身份编辑弹窗
|
||||||
|
@author 湖北新华业务中台研发团队
|
||||||
|
-->
|
||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
v-model="visible"
|
||||||
|
:title="isEdit ? '编辑教育身份' : '添加教育身份'"
|
||||||
|
width="550px"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
destroy-on-close
|
||||||
|
>
|
||||||
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="form"
|
||||||
|
:rules="rules"
|
||||||
|
label-width="80px"
|
||||||
|
>
|
||||||
|
<el-form-item label="区域" prop="regionId">
|
||||||
|
<el-cascader
|
||||||
|
v-model="regionIds"
|
||||||
|
:options="regionTree"
|
||||||
|
:props="{ value: 'regionId', label: 'regionName', checkStrictly: true }"
|
||||||
|
placeholder="请选择区域"
|
||||||
|
clearable
|
||||||
|
style="width: 100%"
|
||||||
|
@change="handleRegionChange"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="学校" prop="schoolId">
|
||||||
|
<el-select v-model="form.schoolId" placeholder="请选择学校" clearable style="width: 100%" @change="handleSchoolChange">
|
||||||
|
<el-option v-for="item in schoolList" :key="item.schoolId" :label="item.schoolName" :value="item.schoolId" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="年级" prop="schoolGradeId">
|
||||||
|
<el-select v-model="form.schoolGradeId" placeholder="请选择年级" clearable style="width: 100%" @change="handleGradeChange">
|
||||||
|
<el-option v-for="item in gradeList" :key="item.id" :label="item.gradeName" :value="item.id" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="班级" prop="schoolClassId">
|
||||||
|
<el-select v-model="form.schoolClassId" placeholder="请选择班级" clearable style="width: 100%">
|
||||||
|
<el-option v-for="item in classList" :key="item.id" :label="item.className" :value="item.id" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="学科" prop="subjectId">
|
||||||
|
<el-select v-model="form.subjectId" placeholder="请选择学科(可选)" clearable style="width: 100%">
|
||||||
|
<el-option v-for="item in subjectList" :key="item.subjectId" :label="item.subjectName" :value="item.subjectId" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="visible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import request from '@/utils/request'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import { reactive, ref } from 'vue'
|
||||||
|
|
||||||
|
const emit = defineEmits(['success', 'add', 'update'])
|
||||||
|
|
||||||
|
const visible = ref(false)
|
||||||
|
const isEdit = ref(false)
|
||||||
|
const formRef = ref(null)
|
||||||
|
const submitLoading = ref(false)
|
||||||
|
|
||||||
|
// 会员ID和教育身份ID(memberId 为 null 表示本地模式)
|
||||||
|
const memberId = ref(null)
|
||||||
|
const educationId = ref(null)
|
||||||
|
// 本地模式下的临时索引
|
||||||
|
const localIndex = ref(null)
|
||||||
|
|
||||||
|
// 区域ID数组(用于级联选择器)
|
||||||
|
const regionIds = ref([])
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const form = reactive({
|
||||||
|
regionId: null,
|
||||||
|
schoolId: null,
|
||||||
|
schoolGradeId: null,
|
||||||
|
schoolClassId: null,
|
||||||
|
subjectId: null
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表单验证规则
|
||||||
|
const rules = {
|
||||||
|
schoolId: [{ required: true, message: '请选择学校', trigger: 'change' }],
|
||||||
|
schoolGradeId: [{ required: true, message: '请选择年级', trigger: 'change' }],
|
||||||
|
schoolClassId: [{ required: true, message: '请选择班级', trigger: 'change' }]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下拉选项数据
|
||||||
|
const regionTree = ref([])
|
||||||
|
const schoolList = ref([])
|
||||||
|
const gradeList = ref([])
|
||||||
|
const classList = ref([])
|
||||||
|
const subjectList = ref([])
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开弹窗
|
||||||
|
* @param {Long} mId 会员ID(null 表示本地模式)
|
||||||
|
* @param {Object} row 编辑时传入教育身份数据
|
||||||
|
* @param {Number} index 本地模式下的数组索引
|
||||||
|
*/
|
||||||
|
const open = async (mId, row, index) => {
|
||||||
|
resetForm()
|
||||||
|
memberId.value = mId
|
||||||
|
isEdit.value = !!row
|
||||||
|
localIndex.value = index ?? null
|
||||||
|
visible.value = true
|
||||||
|
|
||||||
|
// 加载基础数据
|
||||||
|
await Promise.all([loadRegionTree(), loadSubjectList()])
|
||||||
|
|
||||||
|
// 编辑模式
|
||||||
|
if (row) {
|
||||||
|
educationId.value = row.educationId
|
||||||
|
form.schoolId = row.schoolId
|
||||||
|
form.schoolGradeId = row.schoolGradeId
|
||||||
|
form.schoolClassId = row.schoolClassId
|
||||||
|
form.subjectId = row.subjectId
|
||||||
|
|
||||||
|
// 加载关联数据
|
||||||
|
if (row.regionId) {
|
||||||
|
// 本地模式下 regionIds 可能已有值
|
||||||
|
if (row.regionIds) {
|
||||||
|
regionIds.value = row.regionIds
|
||||||
|
} else {
|
||||||
|
regionIds.value = await getRegionPath(row.regionId)
|
||||||
|
}
|
||||||
|
form.regionId = row.regionId
|
||||||
|
await loadSchoolList(row.regionId)
|
||||||
|
}
|
||||||
|
if (row.schoolId) {
|
||||||
|
await loadGradeList(row.schoolId)
|
||||||
|
}
|
||||||
|
if (row.schoolGradeId) {
|
||||||
|
await loadClassList(row.schoolGradeId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置表单
|
||||||
|
*/
|
||||||
|
const resetForm = () => {
|
||||||
|
educationId.value = null
|
||||||
|
regionIds.value = []
|
||||||
|
form.regionId = null
|
||||||
|
form.schoolId = null
|
||||||
|
form.schoolGradeId = null
|
||||||
|
form.schoolClassId = null
|
||||||
|
form.subjectId = null
|
||||||
|
schoolList.value = []
|
||||||
|
gradeList.value = []
|
||||||
|
classList.value = []
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载区域树
|
||||||
|
*/
|
||||||
|
const loadRegionTree = async () => {
|
||||||
|
try {
|
||||||
|
const res = await request.get('/business/region/tree')
|
||||||
|
regionTree.value = res.data || []
|
||||||
|
} catch (e) {
|
||||||
|
regionTree.value = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载学科列表
|
||||||
|
*/
|
||||||
|
const loadSubjectList = async () => {
|
||||||
|
try {
|
||||||
|
const res = await request.get('/business/subject/listAll')
|
||||||
|
subjectList.value = res.data || []
|
||||||
|
} catch (e) {
|
||||||
|
subjectList.value = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载学校列表
|
||||||
|
*/
|
||||||
|
const loadSchoolList = async (regionId) => {
|
||||||
|
try {
|
||||||
|
const res = await request.get('/business/school/listAll', { params: { regionId } })
|
||||||
|
schoolList.value = res.data || []
|
||||||
|
} catch (e) {
|
||||||
|
schoolList.value = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载年级列表
|
||||||
|
*/
|
||||||
|
const loadGradeList = async (schoolId) => {
|
||||||
|
try {
|
||||||
|
const res = await request.get(`/business/school/${schoolId}/grades`)
|
||||||
|
gradeList.value = res.data || []
|
||||||
|
} catch (e) {
|
||||||
|
gradeList.value = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载班级列表
|
||||||
|
*/
|
||||||
|
const loadClassList = async (schoolGradeId) => {
|
||||||
|
try {
|
||||||
|
const res = await request.get(`/business/school/grade/${schoolGradeId}/classes`)
|
||||||
|
classList.value = res.data || []
|
||||||
|
} catch (e) {
|
||||||
|
classList.value = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取区域路径(用于回显)
|
||||||
|
*/
|
||||||
|
const getRegionPath = async (regionId) => {
|
||||||
|
try {
|
||||||
|
const res = await request.get(`/business/region/${regionId}/path`)
|
||||||
|
return res.data || []
|
||||||
|
} catch (e) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 区域变更
|
||||||
|
*/
|
||||||
|
const handleRegionChange = (val) => {
|
||||||
|
form.regionId = val && val.length ? val[val.length - 1] : null
|
||||||
|
form.schoolId = null
|
||||||
|
form.schoolGradeId = null
|
||||||
|
form.schoolClassId = null
|
||||||
|
schoolList.value = []
|
||||||
|
gradeList.value = []
|
||||||
|
classList.value = []
|
||||||
|
if (form.regionId) {
|
||||||
|
loadSchoolList(form.regionId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学校变更
|
||||||
|
*/
|
||||||
|
const handleSchoolChange = () => {
|
||||||
|
form.schoolGradeId = null
|
||||||
|
form.schoolClassId = null
|
||||||
|
gradeList.value = []
|
||||||
|
classList.value = []
|
||||||
|
if (form.schoolId) {
|
||||||
|
loadGradeList(form.schoolId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 年级变更
|
||||||
|
*/
|
||||||
|
const handleGradeChange = () => {
|
||||||
|
form.schoolClassId = null
|
||||||
|
classList.value = []
|
||||||
|
if (form.schoolGradeId) {
|
||||||
|
loadClassList(form.schoolGradeId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提交表单
|
||||||
|
*/
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
try {
|
||||||
|
await formRef.value?.validate()
|
||||||
|
} catch (e) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建数据(包含名称用于本地展示)
|
||||||
|
const data = {
|
||||||
|
regionId: form.regionId,
|
||||||
|
regionIds: [...regionIds.value],
|
||||||
|
schoolId: form.schoolId,
|
||||||
|
schoolGradeId: form.schoolGradeId,
|
||||||
|
schoolClassId: form.schoolClassId,
|
||||||
|
subjectId: form.subjectId,
|
||||||
|
// 添加名称用于列表展示
|
||||||
|
schoolName: schoolList.value.find(s => s.schoolId === form.schoolId)?.schoolName || '',
|
||||||
|
gradeName: gradeList.value.find(g => g.id === form.schoolGradeId)?.gradeName || '',
|
||||||
|
className: classList.value.find(c => c.id === form.schoolClassId)?.className || '',
|
||||||
|
subjectName: subjectList.value.find(s => s.subjectId === form.subjectId)?.subjectName || ''
|
||||||
|
}
|
||||||
|
|
||||||
|
// 本地模式:返回数据给父组件
|
||||||
|
if (!memberId.value) {
|
||||||
|
visible.value = false
|
||||||
|
if (isEdit.value) {
|
||||||
|
emit('update', data, localIndex.value)
|
||||||
|
} else {
|
||||||
|
emit('add', data)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 远程模式:调用 API
|
||||||
|
submitLoading.value = true
|
||||||
|
try {
|
||||||
|
const apiData = {
|
||||||
|
regionId: form.regionId,
|
||||||
|
schoolId: form.schoolId,
|
||||||
|
schoolGradeId: form.schoolGradeId,
|
||||||
|
schoolClassId: form.schoolClassId,
|
||||||
|
subjectId: form.subjectId
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isEdit.value) {
|
||||||
|
const res = await request.put(`/business/member/${memberId.value}/educations/${educationId.value}`, apiData)
|
||||||
|
if (res.code === 200) {
|
||||||
|
ElMessage.success('修改成功')
|
||||||
|
visible.value = false
|
||||||
|
emit('success')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const res = await request.post(`/business/member/${memberId.value}/educations`, apiData)
|
||||||
|
if (res.code === 200) {
|
||||||
|
ElMessage.success('添加成功')
|
||||||
|
visible.value = false
|
||||||
|
emit('success')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
submitLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ open })
|
||||||
|
</script>
|
||||||
|
|
@ -53,14 +53,6 @@
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="身份类型" prop="identityType">
|
|
||||||
<el-radio-group v-model="form.identityType" @change="handleIdentityChange">
|
|
||||||
<el-radio value="1">家长</el-radio>
|
|
||||||
<el-radio value="2">教师</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="状态" prop="status">
|
<el-form-item label="状态" prop="status">
|
||||||
<el-switch
|
<el-switch
|
||||||
|
|
@ -74,65 +66,45 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<!-- 教师身份时显示学校信息 -->
|
<!-- 教育身份 -->
|
||||||
<template v-if="form.identityType === '2'">
|
<el-divider content-position="left">教育身份</el-divider>
|
||||||
<el-divider content-position="left">学校信息(教师必填)</el-divider>
|
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="区域" prop="regionId" :rules="teacherRules.regionId">
|
|
||||||
<el-cascader
|
|
||||||
v-model="form.regionIds"
|
|
||||||
:options="regionTree"
|
|
||||||
:props="{ value: 'regionId', label: 'regionName', checkStrictly: true }"
|
|
||||||
placeholder="请选择区域"
|
|
||||||
clearable
|
|
||||||
style="width: 100%"
|
|
||||||
@change="handleRegionChange"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="学校" prop="schoolId" :rules="teacherRules.schoolId">
|
|
||||||
<el-select v-model="form.schoolId" placeholder="请选择学校" clearable style="width: 100%" @change="handleSchoolChange">
|
|
||||||
<el-option v-for="item in schoolList" :key="item.schoolId" :label="item.schoolName" :value="item.schoolId" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="年级" prop="schoolGradeId" :rules="teacherRules.schoolGradeId">
|
|
||||||
<el-select v-model="form.schoolGradeId" placeholder="请选择年级" clearable style="width: 100%" @change="handleGradeChange">
|
|
||||||
<el-option v-for="item in gradeList" :key="item.id" :label="item.gradeName" :value="item.id" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="班级" prop="schoolClassId" :rules="teacherRules.schoolClassId">
|
|
||||||
<el-select v-model="form.schoolClassId" placeholder="请选择班级" clearable style="width: 100%">
|
|
||||||
<el-option v-for="item in classList" :key="item.id" :label="item.className" :value="item.id" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<!-- 绑定学生 -->
|
|
||||||
<el-divider content-position="left">绑定学生</el-divider>
|
|
||||||
<el-alert
|
|
||||||
v-if="form.identityType === '2'"
|
|
||||||
title="教师只能绑定本校学生"
|
|
||||||
type="info"
|
|
||||||
:closable="false"
|
|
||||||
show-icon
|
|
||||||
style="margin-bottom: 12px"
|
|
||||||
/>
|
|
||||||
<el-row style="margin-bottom: 12px;">
|
<el-row style="margin-bottom: 12px;">
|
||||||
<el-button type="primary" size="small" :icon="Plus" @click="handleAddStudent">添加学生</el-button>
|
<el-button type="primary" size="small" :icon="Plus" @click="handleAddEducation">添加教育身份</el-button>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-table :data="form.students" border size="small" max-height="200">
|
<el-table :data="educations" border size="small" max-height="180">
|
||||||
<template #empty>
|
<template #empty>
|
||||||
<el-empty description="暂无绑定学生" :image-size="60" />
|
<el-empty description="暂无教育身份" :image-size="60" />
|
||||||
|
</template>
|
||||||
|
<el-table-column prop="schoolName" label="学校" min-width="140" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="gradeName" label="年级" width="70" />
|
||||||
|
<el-table-column prop="className" label="班级" width="60" />
|
||||||
|
<el-table-column prop="subjectName" label="学科" width="60" />
|
||||||
|
<el-table-column label="默认" width="60" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-tag v-if="row.isDefault === '1'" type="success" size="small">默认</el-tag>
|
||||||
|
<el-button v-else link type="primary" size="small" @click="handleSetDefault(row)">设为</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" width="100" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button link type="primary" size="small" @click="handleEditEducation(row)">编辑</el-button>
|
||||||
|
<el-popconfirm title="确定删除该教育身份?" @confirm="handleDeleteEducation(row)">
|
||||||
|
<template #reference>
|
||||||
|
<el-button link type="danger" size="small">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-popconfirm>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<!-- 亲子关系 -->
|
||||||
|
<el-divider content-position="left">亲子关系</el-divider>
|
||||||
|
<el-row style="margin-bottom: 12px;">
|
||||||
|
<el-button type="primary" size="small" :icon="Plus" @click="handleAddStudent">添加亲子关系</el-button>
|
||||||
|
</el-row>
|
||||||
|
<el-table :data="form.students" border size="small" max-height="180">
|
||||||
|
<template #empty>
|
||||||
|
<el-empty description="暂无亲子关系" :image-size="60" />
|
||||||
</template>
|
</template>
|
||||||
<el-table-column prop="studentName" label="姓名" min-width="80" />
|
<el-table-column prop="studentName" label="姓名" min-width="80" />
|
||||||
<el-table-column prop="studentNo" label="学号" width="120" />
|
<el-table-column prop="studentNo" label="学号" width="120" />
|
||||||
|
|
@ -141,9 +113,9 @@
|
||||||
<el-table-column prop="className" label="班级" width="60" />
|
<el-table-column prop="className" label="班级" width="60" />
|
||||||
<el-table-column label="操作" width="80" align="center">
|
<el-table-column label="操作" width="80" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-popconfirm title="确定解绑该学生?" @confirm="handleRemoveStudent(row)">
|
<el-popconfirm :title="isEdit ? '确定解绑该学生?' : '确定移除该学生?'" @confirm="handleRemoveStudent(row)">
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<el-button link type="danger" size="small">解绑</el-button>
|
<el-button link type="danger" size="small">{{ isEdit ? '解绑' : '移除' }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-popconfirm>
|
</el-popconfirm>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -156,7 +128,10 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 学生选择器 -->
|
<!-- 学生选择器 -->
|
||||||
<StudentSelectDialog ref="studentSelectRef" @success="loadBoundStudents" />
|
<StudentSelectDialog ref="studentSelectRef" @success="loadBoundStudents" @add="handleLocalAddStudents" />
|
||||||
|
|
||||||
|
<!-- 教育身份编辑弹窗 -->
|
||||||
|
<EducationDialog ref="educationDialogRef" @success="loadEducations" @add="handleLocalAddEducation" @update="handleLocalUpdateEducation" />
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -166,6 +141,7 @@ import { Plus } from '@element-plus/icons-vue'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import StudentSelectDialog from './StudentSelectDialog.vue'
|
import StudentSelectDialog from './StudentSelectDialog.vue'
|
||||||
|
import EducationDialog from './EducationDialog.vue'
|
||||||
|
|
||||||
const emit = defineEmits(['success'])
|
const emit = defineEmits(['success'])
|
||||||
|
|
||||||
|
|
@ -174,6 +150,10 @@ const isEdit = ref(false)
|
||||||
const formRef = ref(null)
|
const formRef = ref(null)
|
||||||
const submitLoading = ref(false)
|
const submitLoading = ref(false)
|
||||||
const studentSelectRef = ref(null)
|
const studentSelectRef = ref(null)
|
||||||
|
const educationDialogRef = ref(null)
|
||||||
|
|
||||||
|
// 教育身份列表
|
||||||
|
const educations = ref([])
|
||||||
|
|
||||||
// 表单数据
|
// 表单数据
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
|
|
@ -182,13 +162,7 @@ const form = reactive({
|
||||||
nickname: '',
|
nickname: '',
|
||||||
gender: '0',
|
gender: '0',
|
||||||
birthday: '',
|
birthday: '',
|
||||||
identityType: '1',
|
|
||||||
status: '0',
|
status: '0',
|
||||||
regionIds: [],
|
|
||||||
regionId: null,
|
|
||||||
schoolId: null,
|
|
||||||
schoolGradeId: null,
|
|
||||||
schoolClassId: null,
|
|
||||||
students: []
|
students: []
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -197,26 +171,9 @@ const rules = {
|
||||||
phone: [
|
phone: [
|
||||||
{ required: true, message: '请输入手机号', trigger: 'blur' },
|
{ required: true, message: '请输入手机号', trigger: 'blur' },
|
||||||
{ pattern: /^1[3-9]\d{9}$/, message: '手机号格式不正确', trigger: 'blur' }
|
{ pattern: /^1[3-9]\d{9}$/, message: '手机号格式不正确', trigger: 'blur' }
|
||||||
],
|
|
||||||
identityType: [
|
|
||||||
{ required: true, message: '请选择身份类型', trigger: 'change' }
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
// 教师身份额外校验规则
|
|
||||||
const teacherRules = {
|
|
||||||
regionId: [{ required: true, message: '请选择所属区域', trigger: 'change' }],
|
|
||||||
schoolId: [{ required: true, message: '请选择所属学校', trigger: 'change' }],
|
|
||||||
schoolGradeId: [{ required: true, message: '请选择所属年级', trigger: 'change' }],
|
|
||||||
schoolClassId: [{ required: true, message: '请选择所属班级', trigger: 'change' }]
|
|
||||||
}
|
|
||||||
|
|
||||||
// 下拉选项数据
|
|
||||||
const regionTree = ref([])
|
|
||||||
const schoolList = ref([])
|
|
||||||
const gradeList = ref([])
|
|
||||||
const classList = ref([])
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打开弹窗
|
* 打开弹窗
|
||||||
*/
|
*/
|
||||||
|
|
@ -225,28 +182,14 @@ const open = async (row) => {
|
||||||
isEdit.value = !!row
|
isEdit.value = !!row
|
||||||
visible.value = true
|
visible.value = true
|
||||||
|
|
||||||
// 加载区域树
|
|
||||||
await loadRegionTree()
|
|
||||||
|
|
||||||
// 编辑模式加载会员数据
|
// 编辑模式加载会员数据
|
||||||
if (row && row.memberId) {
|
if (row && row.memberId) {
|
||||||
try {
|
try {
|
||||||
const res = await request.get(`/business/member/${row.memberId}`)
|
const res = await request.get(`/business/member/${row.memberId}`)
|
||||||
if (res.code === 200 && res.data) {
|
if (res.code === 200 && res.data) {
|
||||||
Object.assign(form, res.data)
|
Object.assign(form, res.data)
|
||||||
// 后端已返回 regionIds 数组用于级联选择器回显
|
// 加载教育身份和学生列表
|
||||||
// 加载学校信息的下拉选项
|
await Promise.all([loadEducations(), loadBoundStudents()])
|
||||||
if (form.regionId) {
|
|
||||||
await loadSchoolList(form.regionId)
|
|
||||||
}
|
|
||||||
if (form.schoolId) {
|
|
||||||
await loadGradeList(form.schoolId)
|
|
||||||
}
|
|
||||||
if (form.schoolGradeId) {
|
|
||||||
await loadClassList(form.schoolGradeId)
|
|
||||||
}
|
|
||||||
// 加载已绑定的学生列表
|
|
||||||
await loadBoundStudents()
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('加载会员数据失败', e)
|
console.error('加载会员数据失败', e)
|
||||||
|
|
@ -254,6 +197,22 @@ const open = async (row) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载教育身份列表
|
||||||
|
*/
|
||||||
|
const loadEducations = async () => {
|
||||||
|
if (!form.memberId) {
|
||||||
|
educations.value = []
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const res = await request.get(`/business/member/${form.memberId}/educations`)
|
||||||
|
educations.value = res.data || []
|
||||||
|
} catch (e) {
|
||||||
|
educations.value = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载已绑定的学生列表
|
* 加载已绑定的学生列表
|
||||||
*/
|
*/
|
||||||
|
|
@ -279,143 +238,147 @@ const resetForm = () => {
|
||||||
form.nickname = ''
|
form.nickname = ''
|
||||||
form.gender = '0'
|
form.gender = '0'
|
||||||
form.birthday = ''
|
form.birthday = ''
|
||||||
form.identityType = '1'
|
|
||||||
form.status = '0'
|
form.status = '0'
|
||||||
form.regionIds = []
|
|
||||||
form.regionId = null
|
|
||||||
form.schoolId = null
|
|
||||||
form.schoolGradeId = null
|
|
||||||
form.schoolClassId = null
|
|
||||||
form.students = []
|
form.students = []
|
||||||
schoolList.value = []
|
educations.value = []
|
||||||
gradeList.value = []
|
|
||||||
classList.value = []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载区域树
|
* 添加教育身份
|
||||||
*/
|
*/
|
||||||
const loadRegionTree = async () => {
|
const handleAddEducation = () => {
|
||||||
try {
|
// 新增模式:本地模式(memberId 传 null)
|
||||||
const res = await request.get('/business/region/tree')
|
// 编辑模式:远程模式(传实际 memberId)
|
||||||
regionTree.value = res.data || []
|
educationDialogRef.value?.open(isEdit.value ? form.memberId : null)
|
||||||
} catch (e) {
|
}
|
||||||
regionTree.value = []
|
|
||||||
|
/**
|
||||||
|
* 编辑教育身份
|
||||||
|
*/
|
||||||
|
const handleEditEducation = (row) => {
|
||||||
|
const index = educations.value.indexOf(row)
|
||||||
|
educationDialogRef.value?.open(isEdit.value ? form.memberId : null, row, index)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 本地添加教育身份(新增会员模式)
|
||||||
|
*/
|
||||||
|
const handleLocalAddEducation = (data) => {
|
||||||
|
// 如果是第一条,设为默认
|
||||||
|
if (educations.value.length === 0) {
|
||||||
|
data.isDefault = '1'
|
||||||
|
} else {
|
||||||
|
data.isDefault = '0'
|
||||||
|
}
|
||||||
|
educations.value.push(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 本地更新教育身份(新增会员模式)
|
||||||
|
*/
|
||||||
|
const handleLocalUpdateEducation = (data, index) => {
|
||||||
|
if (index !== null && index >= 0) {
|
||||||
|
// 保留原来的默认状态
|
||||||
|
data.isDefault = educations.value[index].isDefault
|
||||||
|
educations.value[index] = data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载学校列表
|
* 删除教育身份
|
||||||
*/
|
*/
|
||||||
const loadSchoolList = async (regionId) => {
|
const handleDeleteEducation = async (row) => {
|
||||||
try {
|
// 新增模式:本地删除
|
||||||
const res = await request.get('/business/school/listAll', { params: { regionId } })
|
if (!isEdit.value) {
|
||||||
schoolList.value = res.data || []
|
const index = educations.value.indexOf(row)
|
||||||
} catch (e) {
|
if (index > -1) {
|
||||||
schoolList.value = []
|
educations.value.splice(index, 1)
|
||||||
|
// 如果删除的是默认项且还有其他项,将第一项设为默认
|
||||||
|
if (row.isDefault === '1' && educations.value.length > 0) {
|
||||||
|
educations.value[0].isDefault = '1'
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 加载年级列表
|
|
||||||
*/
|
|
||||||
const loadGradeList = async (schoolId) => {
|
|
||||||
try {
|
|
||||||
const res = await request.get(`/business/school/${schoolId}/grades`)
|
|
||||||
gradeList.value = res.data || []
|
|
||||||
} catch (e) {
|
|
||||||
gradeList.value = []
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 加载班级列表
|
|
||||||
*/
|
|
||||||
const loadClassList = async (schoolGradeId) => {
|
|
||||||
try {
|
|
||||||
const res = await request.get(`/business/school/grade/${schoolGradeId}/classes`)
|
|
||||||
classList.value = res.data || []
|
|
||||||
} catch (e) {
|
|
||||||
classList.value = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 身份类型变更
|
|
||||||
*/
|
|
||||||
const handleIdentityChange = () => {
|
|
||||||
// 切换为家长时清空学校信息
|
|
||||||
if (form.identityType === '1') {
|
|
||||||
form.regionIds = []
|
|
||||||
form.regionId = null
|
|
||||||
form.schoolId = null
|
|
||||||
form.schoolGradeId = null
|
|
||||||
form.schoolClassId = null
|
|
||||||
schoolList.value = []
|
|
||||||
gradeList.value = []
|
|
||||||
classList.value = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 区域变更
|
|
||||||
*/
|
|
||||||
const handleRegionChange = (val) => {
|
|
||||||
form.regionId = val && val.length ? val[val.length - 1] : null
|
|
||||||
form.schoolId = null
|
|
||||||
form.schoolGradeId = null
|
|
||||||
form.schoolClassId = null
|
|
||||||
schoolList.value = []
|
|
||||||
gradeList.value = []
|
|
||||||
classList.value = []
|
|
||||||
if (form.regionId) {
|
|
||||||
loadSchoolList(form.regionId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 学校变更
|
|
||||||
*/
|
|
||||||
const handleSchoolChange = () => {
|
|
||||||
form.schoolGradeId = null
|
|
||||||
form.schoolClassId = null
|
|
||||||
gradeList.value = []
|
|
||||||
classList.value = []
|
|
||||||
if (form.schoolId) {
|
|
||||||
loadGradeList(form.schoolId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 年级变更
|
|
||||||
*/
|
|
||||||
const handleGradeChange = () => {
|
|
||||||
form.schoolClassId = null
|
|
||||||
classList.value = []
|
|
||||||
if (form.schoolGradeId) {
|
|
||||||
loadClassList(form.schoolGradeId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加学生
|
|
||||||
*/
|
|
||||||
const handleAddStudent = () => {
|
|
||||||
if (!isEdit.value || !form.memberId) {
|
|
||||||
ElMessage.warning('请先保存会员信息后再绑定学生')
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
studentSelectRef.value?.open({
|
|
||||||
memberId: form.memberId,
|
// 编辑模式:远程删除
|
||||||
identityType: form.identityType,
|
try {
|
||||||
schoolId: form.schoolId
|
const res = await request.delete(`/business/member/${form.memberId}/educations/${row.educationId}`)
|
||||||
})
|
if (res.code === 200) {
|
||||||
|
ElMessage.success('删除成功')
|
||||||
|
await loadEducations()
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('删除失败', e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解绑学生
|
* 设为默认教育身份
|
||||||
|
*/
|
||||||
|
const handleSetDefault = async (row) => {
|
||||||
|
// 新增模式:本地设置
|
||||||
|
if (!isEdit.value) {
|
||||||
|
educations.value.forEach(e => e.isDefault = '0')
|
||||||
|
row.isDefault = '1'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑模式:远程设置
|
||||||
|
try {
|
||||||
|
const res = await request.put(`/business/member/${form.memberId}/educations/${row.educationId}/default`)
|
||||||
|
if (res.code === 200) {
|
||||||
|
ElMessage.success('设置成功')
|
||||||
|
await loadEducations()
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('设置失败', e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加亲子关系
|
||||||
|
*/
|
||||||
|
const handleAddStudent = () => {
|
||||||
|
// 新增模式:本地模式(传 excludeIds 排除已选)
|
||||||
|
// 编辑模式:远程模式(传 memberId)
|
||||||
|
if (isEdit.value) {
|
||||||
|
studentSelectRef.value?.open({
|
||||||
|
memberId: form.memberId
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
studentSelectRef.value?.open({
|
||||||
|
excludeIds: form.students.map(s => s.studentId)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 本地添加学生(新增会员模式)
|
||||||
|
*/
|
||||||
|
const handleLocalAddStudents = (students) => {
|
||||||
|
// 添加到本地列表(去重)
|
||||||
|
for (const student of students) {
|
||||||
|
if (!form.students.some(s => s.studentId === student.studentId)) {
|
||||||
|
form.students.push(student)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解绑/移除学生
|
||||||
*/
|
*/
|
||||||
const handleRemoveStudent = async (row) => {
|
const handleRemoveStudent = async (row) => {
|
||||||
|
// 新增模式:本地移除
|
||||||
|
if (!isEdit.value) {
|
||||||
|
const index = form.students.findIndex(s => s.studentId === row.studentId)
|
||||||
|
if (index > -1) {
|
||||||
|
form.students.splice(index, 1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑模式:远程解绑
|
||||||
try {
|
try {
|
||||||
const res = await request.post(`/business/member/unbindStudent/${row.studentId}`)
|
const res = await request.post(`/business/member/unbindStudent/${row.studentId}`)
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
|
|
@ -439,10 +402,14 @@ const handleSubmit = async () => {
|
||||||
|
|
||||||
submitLoading.value = true
|
submitLoading.value = true
|
||||||
try {
|
try {
|
||||||
const data = { ...form }
|
const data = {
|
||||||
// 移除不需要提交的字段
|
memberId: form.memberId,
|
||||||
delete data.regionIds
|
phone: form.phone,
|
||||||
delete data.students
|
nickname: form.nickname,
|
||||||
|
gender: form.gender,
|
||||||
|
birthday: form.birthday,
|
||||||
|
status: form.status
|
||||||
|
}
|
||||||
|
|
||||||
if (isEdit.value) {
|
if (isEdit.value) {
|
||||||
const res = await request.put('/business/member', data)
|
const res = await request.put('/business/member', data)
|
||||||
|
|
@ -452,6 +419,15 @@ const handleSubmit = async () => {
|
||||||
emit('success')
|
emit('success')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// 新增时,将教育身份和亲子关系一起提交
|
||||||
|
data.educations = educations.value.map(e => ({
|
||||||
|
regionId: e.regionId,
|
||||||
|
schoolId: e.schoolId,
|
||||||
|
schoolGradeId: e.schoolGradeId,
|
||||||
|
schoolClassId: e.schoolClassId,
|
||||||
|
subjectId: e.subjectId
|
||||||
|
}))
|
||||||
|
data.studentIds = form.students.map(s => s.studentId)
|
||||||
const res = await request.post('/business/member', data)
|
const res = await request.post('/business/member', data)
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
ElMessage.success('新增成功')
|
ElMessage.success('新增成功')
|
||||||
|
|
|
||||||
|
|
@ -24,16 +24,6 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<!-- 教师身份提示 -->
|
|
||||||
<el-alert
|
|
||||||
v-if="isTeacher"
|
|
||||||
title="教师只能绑定本校学生"
|
|
||||||
type="info"
|
|
||||||
:closable="false"
|
|
||||||
show-icon
|
|
||||||
style="margin-bottom: 12px"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 学生列表 -->
|
<!-- 学生列表 -->
|
||||||
<el-table
|
<el-table
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
|
|
@ -74,7 +64,7 @@
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<span style="margin-right: 16px; color: #909399">已选择 {{ selectedStudents.length }} 名学生</span>
|
<span style="margin-right: 16px; color: #909399">已选择 {{ selectedStudents.length }} 名学生</span>
|
||||||
<el-button @click="visible = false">取消</el-button>
|
<el-button @click="visible = false">取消</el-button>
|
||||||
<el-button type="primary" :loading="submitLoading" @click="handleConfirm">确定绑定</el-button>
|
<el-button type="primary" :loading="submitLoading" @click="handleConfirm">确定</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
@ -86,7 +76,7 @@ import { Refresh, Search } from '@element-plus/icons-vue'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
|
|
||||||
const emit = defineEmits(['success'])
|
const emit = defineEmits(['success', 'add'])
|
||||||
|
|
||||||
const visible = ref(false)
|
const visible = ref(false)
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
|
|
@ -96,10 +86,12 @@ const total = ref(0)
|
||||||
const selectedStudents = ref([])
|
const selectedStudents = ref([])
|
||||||
const tableRef = ref(null)
|
const tableRef = ref(null)
|
||||||
|
|
||||||
// 会员信息
|
// 会员信息(memberId 为 null 表示本地模式)
|
||||||
const memberId = ref(null)
|
const memberId = ref(null)
|
||||||
const isTeacher = ref(false)
|
const isTeacher = ref(false)
|
||||||
const schoolId = ref(null)
|
const schoolId = ref(null)
|
||||||
|
// 本地模式:已选中的学生ID(用于排除)
|
||||||
|
const excludeStudentIds = ref([])
|
||||||
|
|
||||||
// 查询参数
|
// 查询参数
|
||||||
const queryParams = reactive({
|
const queryParams = reactive({
|
||||||
|
|
@ -111,12 +103,13 @@ const queryParams = reactive({
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打开弹窗
|
* 打开弹窗
|
||||||
* @param options { memberId: Long, identityType: String, schoolId: Long }
|
* @param options { memberId: Long, excludeIds: Long[] } - memberId 为 null 表示本地模式
|
||||||
*/
|
*/
|
||||||
const open = (options = {}) => {
|
const open = (options = {}) => {
|
||||||
memberId.value = options.memberId
|
memberId.value = options.memberId || null
|
||||||
isTeacher.value = options.identityType === '2'
|
isTeacher.value = false
|
||||||
schoolId.value = options.schoolId
|
schoolId.value = null
|
||||||
|
excludeStudentIds.value = options.excludeIds || []
|
||||||
|
|
||||||
resetQuery()
|
resetQuery()
|
||||||
visible.value = true
|
visible.value = true
|
||||||
|
|
@ -134,11 +127,15 @@ const getList = async () => {
|
||||||
pageSize: queryParams.pageSize,
|
pageSize: queryParams.pageSize,
|
||||||
studentName: queryParams.studentName || undefined,
|
studentName: queryParams.studentName || undefined,
|
||||||
studentNo: queryParams.studentNo || undefined,
|
studentNo: queryParams.studentNo || undefined,
|
||||||
memberId: memberId.value,
|
memberId: memberId.value || undefined
|
||||||
schoolId: isTeacher.value ? schoolId.value : undefined
|
|
||||||
}
|
}
|
||||||
const res = await request.get('/business/student/available', { params })
|
const res = await request.get('/business/student/available', { params })
|
||||||
studentList.value = res.rows || []
|
let list = res.rows || []
|
||||||
|
// 本地模式:过滤掉已选中的学生
|
||||||
|
if (!memberId.value && excludeStudentIds.value.length > 0) {
|
||||||
|
list = list.filter(s => !excludeStudentIds.value.includes(s.studentId))
|
||||||
|
}
|
||||||
|
studentList.value = list
|
||||||
total.value = res.total || 0
|
total.value = res.total || 0
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('获取学生列表失败', e)
|
console.error('获取学生列表失败', e)
|
||||||
|
|
@ -195,11 +192,18 @@ const handleSelectionChange = (selection) => {
|
||||||
*/
|
*/
|
||||||
const handleConfirm = async () => {
|
const handleConfirm = async () => {
|
||||||
if (selectedStudents.value.length === 0) {
|
if (selectedStudents.value.length === 0) {
|
||||||
ElMessage.warning('请选择要绑定的学生')
|
ElMessage.warning('请选择要添加的学生')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 过滤出需要绑定的学生(排除已绑定当前会员的)
|
// 本地模式:返回选中的学生数据
|
||||||
|
if (!memberId.value) {
|
||||||
|
visible.value = false
|
||||||
|
emit('add', selectedStudents.value)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 远程模式:调用 API 绑定
|
||||||
const studentIds = selectedStudents.value
|
const studentIds = selectedStudents.value
|
||||||
.filter(s => s.memberId !== memberId.value)
|
.filter(s => s.memberId !== memberId.value)
|
||||||
.map(s => s.studentId)
|
.map(s => s.studentId)
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,6 @@
|
||||||
<el-form-item label="昵称">
|
<el-form-item label="昵称">
|
||||||
<el-input v-model="queryParams.nickname" placeholder="请输入昵称" clearable style="width: 150px" @keyup.enter="handleQuery" />
|
<el-input v-model="queryParams.nickname" placeholder="请输入昵称" clearable style="width: 150px" @keyup.enter="handleQuery" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="身份类型">
|
|
||||||
<el-select v-model="queryParams.identityType" placeholder="全部" clearable style="width: 120px">
|
|
||||||
<el-option label="家长" value="1" />
|
|
||||||
<el-option label="教师" value="2" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="状态">
|
<el-form-item label="状态">
|
||||||
<el-select v-model="queryParams.status" placeholder="全部" clearable style="width: 100px">
|
<el-select v-model="queryParams.status" placeholder="全部" clearable style="width: 100px">
|
||||||
<el-option label="正常" value="0" />
|
<el-option label="正常" value="0" />
|
||||||
|
|
@ -72,13 +66,6 @@
|
||||||
{{ formatBirthday(row.birthday) }}
|
{{ formatBirthday(row.birthday) }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="identityType" label="身份类型" width="85" align="center">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<el-tag :type="row.identityType === '1' ? 'success' : 'warning'">
|
|
||||||
{{ row.identityType === '1' ? '家长' : '教师' }}
|
|
||||||
</el-tag>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="registerTime" label="注册时间" width="165" />
|
<el-table-column prop="registerTime" label="注册时间" width="165" />
|
||||||
<el-table-column prop="registerSource" label="注册来源" width="85" align="center">
|
<el-table-column prop="registerSource" label="注册来源" width="85" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
|
|
@ -157,7 +144,6 @@ const queryParams = ref({
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
phone: '',
|
phone: '',
|
||||||
nickname: '',
|
nickname: '',
|
||||||
identityType: '',
|
|
||||||
status: ''
|
status: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -235,7 +221,6 @@ const resetQuery = () => {
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
phone: '',
|
phone: '',
|
||||||
nickname: '',
|
nickname: '',
|
||||||
identityType: '',
|
|
||||||
status: ''
|
status: ''
|
||||||
}
|
}
|
||||||
dateRange.value = []
|
dateRange.value = []
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue