AdminSubstationUserController.java 6.5 KB
package com.diligrp.rider.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.diligrp.rider.common.enums.AdminRoleScopeEnum;
import com.diligrp.rider.common.exception.BizException;
import com.diligrp.rider.common.result.Result;
import com.diligrp.rider.dto.ChangePasswordDTO;
import com.diligrp.rider.entity.Substation;
import com.diligrp.rider.mapper.SubstationMapper;
import com.diligrp.rider.service.RoleScopeGuardService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * 分站管理员侧子账号管理接口(/api/admin/substation-user/**)
 * 分站管理员只能管理本 cityId 下的账号
 */
@RestController
@RequestMapping("/api/admin/substation-user")
@RequiredArgsConstructor
public class AdminSubstationUserController {

    private final SubstationMapper substationMapper;
    private final RoleScopeGuardService roleScopeGuardService;

    @GetMapping("/list")
    public Result<List<Substation>> list(@RequestParam(required = false) String keyword,
                                          HttpServletRequest request) {
        Long cityId = resolveCityId(request);
        Long selfId = (Long) request.getAttribute("adminId");
        LambdaQueryWrapper<Substation> wrapper = new LambdaQueryWrapper<Substation>()
                .eq(Substation::getCityId, cityId)
                .ne(Substation::getId, selfId)   // 不返回自己
                .orderByDesc(Substation::getId);
        if (keyword != null && !keyword.isBlank()) {
            wrapper.and(w -> w.like(Substation::getUserLogin, keyword)
                    .or().like(Substation::getUserNickname, keyword)
                    .or().like(Substation::getMobile, keyword));
        }
        List<Substation> list = substationMapper.selectList(wrapper);
        // 隐藏密码字段
        list.forEach(s -> s.setUserPass(null));
        return Result.success(list);
    }

    @PostMapping("/add")
    public Result<Void> add(@RequestBody Substation substation, HttpServletRequest request) {
        Long cityId = resolveCityId(request);
        substation.setCityId(cityId);

        Long loginExists = substationMapper.selectCount(new LambdaQueryWrapper<Substation>()
                .eq(Substation::getUserLogin, substation.getUserLogin()));
        if (loginExists > 0) {
            throw new BizException("账号已存在,请更换");
        }
        // 校验角色必须是 SUBSTATION scope 且属于本租户或全局
        roleScopeGuardService.requireRole(substation.getRoleId(), AdminRoleScopeEnum.SUBSTATION.name(), cityId);

        substation.setUserPass(encryptPass(substation.getUserPass()));
        substation.setUserStatus(1);
        substation.setCreateTime(System.currentTimeMillis() / 1000);
        substationMapper.insert(substation);
        return Result.success();
    }

    @PutMapping("/edit")
    public Result<Void> edit(@RequestBody Substation substation, HttpServletRequest request) {
        Long cityId = resolveCityId(request);
        Substation existing = requireOwned(substation.getId(), cityId);

        // 校验角色归属
        roleScopeGuardService.requireRole(substation.getRoleId(), AdminRoleScopeEnum.SUBSTATION.name(), cityId);

        substation.setCityId(existing.getCityId()); // 不允许修改城市
        if (substation.getUserPass() == null || substation.getUserPass().isBlank()) {
            substation.setUserPass(null);
        } else {
            substation.setUserPass(encryptPass(substation.getUserPass()));
        }
        substationMapper.updateById(substation);
        return Result.success();
    }

    @PostMapping("/ban")
    public Result<Void> ban(@RequestParam Long id, HttpServletRequest request) {
        Long cityId = resolveCityId(request);
        requireOwned(id, cityId);
        substationMapper.update(null, new LambdaUpdateWrapper<Substation>()
                .eq(Substation::getId, id).set(Substation::getUserStatus, 0));
        return Result.success();
    }

    @PostMapping("/cancelBan")
    public Result<Void> cancelBan(@RequestParam Long id, HttpServletRequest request) {
        Long cityId = resolveCityId(request);
        requireOwned(id, cityId);
        substationMapper.update(null, new LambdaUpdateWrapper<Substation>()
                .eq(Substation::getId, id).set(Substation::getUserStatus, 1));
        return Result.success();
    }

    @DeleteMapping("/del")
    public Result<Void> del(@RequestParam Long id, HttpServletRequest request) {
        Long cityId = resolveCityId(request);
        requireOwned(id, cityId);
        substationMapper.deleteById(id);
        return Result.success();
    }

    @PostMapping("/changePassword")
    public Result<Void> changePassword(@RequestParam Long id,
                                        @Valid @RequestBody ChangePasswordDTO dto,
                                        HttpServletRequest request) {
        Long cityId = resolveCityId(request);
        Substation sub = requireOwned(id, cityId);
        if (!encryptPass(dto.getOldPassword()).equals(sub.getUserPass())) {
            throw new BizException("原密码不正确");
        }
        if (encryptPass(dto.getNewPassword()).equals(sub.getUserPass())) {
            throw new BizException("新密码不能与原密码相同");
        }
        substationMapper.update(null, new LambdaUpdateWrapper<Substation>()
                .eq(Substation::getId, id)
                .set(Substation::getUserPass, encryptPass(dto.getNewPassword())));
        return Result.success();
    }

    private Substation requireOwned(Long id, Long cityId) {
        Substation sub = substationMapper.selectById(id);
        if (sub == null) {
            throw new BizException("账号不存在");
        }
        if (!cityId.equals(sub.getCityId())) {
            throw new BizException("无权操作其他租户的账号");
        }
        return sub;
    }

    private Long resolveCityId(HttpServletRequest request) {
        Long cityId = (Long) request.getAttribute("cityId");
        if (cityId == null || cityId < 1) {
            throw new BizException("当前账号未绑定有效城市");
        }
        return cityId;
    }

    private String encryptPass(String pass) {
        return DigestUtils.md5DigestAsHex(pass.getBytes(StandardCharsets.UTF_8));
    }
}