修改河南项目的管理后台ui

This commit is contained in:
2026-09-27 10:00:18 +08:00
parent ab91b0ca82
commit 266dad03e4
28 changed files with 406 additions and 1288 deletions
@@ -48,7 +48,8 @@ public class TtUserAvatarController extends BaseController {
public AjaxResult add(@RequestBody TtUserAvatar ttUserAvatar) {
if (StringUtils.isEmpty(ttUserAvatar.getAvatar())) ttUserAvatar.setAvatar("");
else ttUserAvatar.setAvatar(RuoYiConfig.getDomainName() + ttUserAvatar.getAvatar());
return toAjax(userAvatarService.save(ttUserAvatar));
// 走 service 的新增(内含「是否默认」互斥:置为默认时自动清掉其他记录的默认标记)
return toAjax(userAvatarService.saveAvatar(ttUserAvatar));
}
@Log(title = "头像设置", action = "修改", businessType = BusinessType.UPDATE,
@@ -6,4 +6,17 @@ import com.ruoyi.domain.other.TtUserAvatar;
public interface TtUserAvatarService extends IService<TtUserAvatar> {
String updateUserAvatarById(TtUserAvatar ttUserAvatar);
/**
* 新增头像(含「是否默认」互斥处理:置为默认时自动清掉其他记录的默认标记)。
*/
boolean saveAvatar(TtUserAvatar ttUserAvatar);
/**
* 取当前唯一的默认头像(is_default='1' 且 status='0'),没有则返回 null。
* <p>
* ⚠️ 修复「多默认」之前,各消费点是用 list() + RandomUtil.choice() 随机挑一个的,
* 那是在「可能有多条默认」的既成事实下打的补丁;现在约束唯一后应统一走本方法。
*/
TtUserAvatar getDefaultAvatar();
}
@@ -1,20 +1,78 @@
package com.ruoyi.admin.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.domain.other.TtUserAvatar;
import com.ruoyi.admin.mapper.TtUserAvatarMapper;
import com.ruoyi.admin.service.TtUserAvatarService;
import com.ruoyi.common.config.RuoYiConfig;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* 用户头像库
* <p>
* 【默认头像的唯一性约束 —— 2026-09-24】
* 默认头像用于给新注册 / 白号 / 推广号分配初始头像(见 ApiRegisterServiceImpl、
* ApiLoginServiceImpl、ApiUserServiceImpl、PromoLoginServiceImpl 四处消费点),
* 语义上必须**全表最多只有一条 is_default='1'**。
* <p>
* 原实现只做 updateById,导致「把 A 设为默认」时 B/C/D 的 is_default 仍为 '1',
* 库里一度出现 7 条默认(id 63~69),并且部分消费点用的是 RandomUtil.choice(...),
* 会随机挑一条 ⇒ 默认头像实际不唯一、每次注册拿到的头像都不同。
* <p>
* ⇒ 现在把「互斥」收敛到 service 层:凡是把某条写成 is_default='1' 的写操作,
* 都先把其余记录的 is_default 清成 '0',再落当前这条;两步同一事务。
*/
@Service
public class TtUserAvatarServiceImpl extends ServiceImpl<TtUserAvatarMapper, TtUserAvatar> implements TtUserAvatarService {
/** 是 / 否 —— 与 TtUserAvatar#isDefault 的字典口径一致(@Excel readConverterExp = "0=否,1=是") */
private static final String YES = "1";
private static final String NO = "0";
@Override
@Transactional(rollbackFor = Exception.class)
public String updateUserAvatarById(TtUserAvatar ttUserAvatar) {
String avatar = ttUserAvatar.getAvatar();
ttUserAvatar.setAvatar(avatar);
// 头像字段允许为空(后端会拼域名),此处不再做无意义的 setAvatar(avatar)
clearOtherDefaultsIfNeeded(ttUserAvatar);
this.updateById(ttUserAvatar);
return "";
}
/**
* 新增头像:应用同一套唯一性约束。
* 原实现直接 save,新增一条 is_default='1' 就会叠加出第二个默认。
*/
@Override
@Transactional(rollbackFor = Exception.class)
public boolean saveAvatar(TtUserAvatar ttUserAvatar) {
clearOtherDefaultsIfNeeded(ttUserAvatar);
return this.save(ttUserAvatar);
}
/**
* 若本次写入把该条置为「是默认」,则把其余记录的 is_default 全部清成「否」。
* 只在确实要置为默认时执行 UPDATE,避免每次普通编辑都白扫一次全表。
*/
private void clearOtherDefaultsIfNeeded(TtUserAvatar ttUserAvatar) {
if (ttUserAvatar == null || !YES.equals(ttUserAvatar.getIsDefault())) return;
LambdaUpdateWrapper<TtUserAvatar> wrapper = new LambdaUpdateWrapper<TtUserAvatar>()
.set(TtUserAvatar::getIsDefault, NO)
.eq(TtUserAvatar::getIsDefault, YES);
// 编辑场景排除自身,避免刚 set 完又被自己这条排除掉(新增时 id 为 null,不需要排除)
if (ttUserAvatar.getId() != null) {
wrapper.ne(TtUserAvatar::getId, ttUserAvatar.getId());
}
this.update(wrapper);
}
@Override
public TtUserAvatar getDefaultAvatar() {
return this.getOne(new LambdaQueryWrapper<TtUserAvatar>()
.eq(TtUserAvatar::getIsDefault, YES)
.eq(TtUserAvatar::getStatus, "0")
.orderByAsc(TtUserAvatar::getId)
.last("limit 1"));
}
}