mirror of
http://git.pig4cloud.com/pig/pigx.git
synced 2026-11-08 04:39:00 +08:00
feat(app-article, app-article-category, sys-post): 添加文章和分类拖拽排序功能
- 在 AppArticleController 和 AppArticleCategoryController 中新增排序接口 - 在 AppArticleService 和 AppArticleCategoryService 中添加排序方法 - 在 SysPostController 和 SysPostService 中实现岗位排序功能 - 所有排序功能支持按传入 ID 顺序调整,保留未选中记录位置 (cherry picked from commit 0ba00ddcaba9a042bf082c10230042ba0ecf84d2)
This commit is contained in:
1 parent
d927a5b984
commit
a177f3073a
9 files changed
+301
-93
No files matched your search
+21
-1
@@ -51,6 +51,7 @@ public class AppArticleCategoryController {
|
||||
LambdaQueryWrapper<AppArticleCategoryEntity> wrapper = Wrappers.lambdaQuery();
|
||||
wrapper.like(StrUtil.isNotBlank(appArticleCategory.getName()), AppArticleCategoryEntity::getName,
|
||||
appArticleCategory.getName());
|
||||
wrapper.orderByAsc(AppArticleCategoryEntity::getSort, AppArticleCategoryEntity::getId);
|
||||
return R.ok(appArticleCategoryService.page(page, wrapper));
|
||||
}
|
||||
|
||||
@@ -74,7 +75,8 @@ public class AppArticleCategoryController {
|
||||
@Inner(value = false)
|
||||
@GetMapping("/list")
|
||||
public R list() {
|
||||
return R.ok(appArticleCategoryService.list());
|
||||
return R.ok(appArticleCategoryService.list(Wrappers.<AppArticleCategoryEntity>lambdaQuery()
|
||||
.orderByAsc(AppArticleCategoryEntity::getSort, AppArticleCategoryEntity::getId)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,6 +105,24 @@ public class AppArticleCategoryController {
|
||||
return R.ok(appArticleCategoryService.updateById(appArticleCategory));
|
||||
}
|
||||
|
||||
/**
|
||||
* 按传入 ID 顺序调整文章分类,保留未选中记录在排序序列中的位置。
|
||||
* <p>
|
||||
* 以当前租户内未删除记录的排序值、主键升序为基准,仅重排选中记录占据的位置, 再将全部记录的排序值从 1 起连续重编号。
|
||||
* @param ids 按目标顺序排列的文章分类 ID;不可为 null 或空,不可包含 null、重复或不可用的 ID
|
||||
* @return 排序保存成功的响应;校验或更新失败时抛出异常,由统一异常处理器转换响应
|
||||
* @throws IllegalArgumentException ID 列表为空、包含 null 或重复值,或指定记录已删除、不属于当前租户 或不存在
|
||||
* @throws IllegalStateException 批量更新返回失败
|
||||
*/
|
||||
@Operation(summary = "拖拽排序", description = "按当前列表顺序保存排序")
|
||||
@SysLog("文章分类排序")
|
||||
@PutMapping("/sort")
|
||||
@HasPermission("app_appArticleCategory_edit")
|
||||
public R sort(@RequestBody List<Long> ids) {
|
||||
appArticleCategoryService.sort(ids);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除文章分类表
|
||||
* @param ids id列表
|
||||
|
||||
+28
-12
@@ -36,13 +36,12 @@ public class AppArticleController {
|
||||
private final AppArticleService appArticleService;
|
||||
|
||||
/**
|
||||
* 分页查询文章资讯。
|
||||
* <p>
|
||||
* 返回文章列表时会关联分类名称,供 App 资讯列表和后台管理复用。
|
||||
*
|
||||
* 分页查询文章资讯。
|
||||
* <p>
|
||||
* 返回文章列表时会关联分类名称,供 App 资讯列表和后台管理复用。
|
||||
* @param page 分页对象
|
||||
* @param appArticle 文章资讯
|
||||
* @return 文章分页结果
|
||||
* @return 文章分页结果
|
||||
*/
|
||||
@Operation(summary = "分页查询", description = "分页查询")
|
||||
@Inner(value = false)
|
||||
@@ -52,13 +51,12 @@ public class AppArticleController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询文章详情。
|
||||
* <p>
|
||||
* 会递增访问次数;如果传入 userId,则额外返回该用户是否收藏当前文章。
|
||||
*
|
||||
* @param id 文章 ID
|
||||
* @param userId 用户 ID,可为空
|
||||
* @return 文章详情
|
||||
* 查询文章详情。
|
||||
* <p>
|
||||
* 会递增访问次数;如果传入 userId,则额外返回该用户是否收藏当前文章。
|
||||
* @param id 文章 ID
|
||||
* @param userId 用户 ID,可为空
|
||||
* @return 文章详情
|
||||
*/
|
||||
@Inner(value = false)
|
||||
@Operation(summary = "通过id查询", description = "通过id查询")
|
||||
@@ -93,6 +91,24 @@ public class AppArticleController {
|
||||
return R.ok(appArticleService.updateById(appArticle));
|
||||
}
|
||||
|
||||
/**
|
||||
* 按传入 ID 顺序调整文章,保留未选中记录在排序序列中的位置。
|
||||
* <p>
|
||||
* 以当前租户内未删除记录的排序值、主键升序为基准,仅重排选中记录占据的位置, 再将全部记录的排序值从 1 起连续重编号。
|
||||
* @param ids 按目标顺序排列的文章 ID;不可为 null 或空,不可包含 null、重复或不可用的 ID
|
||||
* @return 排序保存成功的响应;校验或更新失败时抛出异常,由统一异常处理器转换响应
|
||||
* @throws IllegalArgumentException ID 列表为空、包含 null 或重复值,或指定记录已删除、不属于当前租户 或不存在
|
||||
* @throws IllegalStateException 批量更新返回失败
|
||||
*/
|
||||
@Operation(summary = "拖拽排序", description = "按当前列表顺序保存排序")
|
||||
@SysLog("文章资讯排序")
|
||||
@PutMapping("/sort")
|
||||
@HasPermission("app_appArticle_edit")
|
||||
public R sort(@RequestBody List<Long> ids) {
|
||||
appArticleService.sort(ids);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除文章资讯
|
||||
* @param ids id列表
|
||||
|
||||
+12
@@ -3,9 +3,21 @@ package com.pig4cloud.pigx.app.service;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.pig4cloud.pigx.app.api.entity.AppArticleCategoryEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 文章分类基础服务。
|
||||
*/
|
||||
public interface AppArticleCategoryService extends IService<AppArticleCategoryEntity> {
|
||||
|
||||
/**
|
||||
* 按传入 ID 顺序调整文章分类,保留未选中记录在排序序列中的位置。
|
||||
* <p>
|
||||
* 以当前租户内未删除记录的排序值、主键升序为基准,仅重排选中记录占据的位置, 再将全部记录的排序值从 1 起连续重编号。
|
||||
* @param ids 按目标顺序排列的文章分类 ID;不可为 null 或空,不可包含 null、重复或不可用的 ID
|
||||
* @throws IllegalArgumentException ID 列表为空、包含 null 或重复值,或指定记录已删除、不属于当前租户 或不存在
|
||||
* @throws IllegalStateException 批量更新返回失败
|
||||
*/
|
||||
void sort(List<Long> ids);
|
||||
|
||||
}
|
||||
+15
@@ -4,8 +4,23 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.pig4cloud.pigx.app.api.entity.AppArticleEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 文章查询与排序服务,供管理端和 App 文章接口调用。
|
||||
*/
|
||||
public interface AppArticleService extends IService<AppArticleEntity> {
|
||||
|
||||
/**
|
||||
* 按传入 ID 顺序调整文章,保留未选中记录在排序序列中的位置。
|
||||
* <p>
|
||||
* 以当前租户内未删除记录的排序值、主键升序为基准,仅重排选中记录占据的位置, 再将全部记录的排序值从 1 起连续重编号。
|
||||
* @param ids 按目标顺序排列的文章 ID;不可为 null 或空,不可包含 null、重复或不可用的 ID
|
||||
* @throws IllegalArgumentException ID 列表为空、包含 null 或重复值,或指定记录已删除、不属于当前租户 或不存在
|
||||
* @throws IllegalStateException 批量更新返回失败
|
||||
*/
|
||||
void sort(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 获取文章并使阅读数+1
|
||||
* @param id id
|
||||
|
||||
+41
@@ -1,10 +1,18 @@
|
||||
package com.pig4cloud.pigx.app.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.pig4cloud.pigx.app.api.entity.AppArticleCategoryEntity;
|
||||
import com.pig4cloud.pigx.app.mapper.AppArticleCategoryMapper;
|
||||
import com.pig4cloud.pigx.app.service.AppArticleCategoryService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 文章分类表
|
||||
@@ -16,4 +24,37 @@ import org.springframework.stereotype.Service;
|
||||
public class AppArticleCategoryServiceImpl extends ServiceImpl<AppArticleCategoryMapper, AppArticleCategoryEntity>
|
||||
implements AppArticleCategoryService {
|
||||
|
||||
/**
|
||||
* 按传入 ID 顺序调整文章分类,保留未选中记录在排序序列中的位置。
|
||||
* <p>
|
||||
* 以当前租户内未删除记录的排序值、主键升序为基准,仅重排选中记录占据的位置, 再将全部记录的排序值从 1 起连续重编号。
|
||||
* @param ids 按目标顺序排列的文章分类 ID;不可为 null 或空,不可包含 null、重复或不可用的 ID
|
||||
* @throws IllegalArgumentException ID 列表为空、包含 null 或重复值,或指定记录已删除、不属于当前租户 或不存在
|
||||
* @throws IllegalStateException 批量更新返回失败
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void sort(List<Long> ids) {
|
||||
Assert.notEmpty(ids, "排序记录不能为空");
|
||||
Set<Long> selected = new HashSet<>(ids);
|
||||
Assert.isTrue(!selected.contains(null) && selected.size() == ids.size(), "排序记录无效");
|
||||
// 锁定统一顺序,避免重复排序值和分页边界导致拖动后顺序丢失。
|
||||
List<AppArticleCategoryEntity> records = list(Wrappers.<AppArticleCategoryEntity>lambdaQuery()
|
||||
.orderByAsc(AppArticleCategoryEntity::getSort, AppArticleCategoryEntity::getId)
|
||||
.last("FOR UPDATE"));
|
||||
long matched = records.stream().filter(row -> selected.contains(row.getId())).count();
|
||||
Assert.isTrue(matched == ids.size(), "记录已变更,请刷新后重试");
|
||||
List<AppArticleCategoryEntity> updates = new ArrayList<>();
|
||||
int next = 0;
|
||||
for (int i = 0; i < records.size(); i++) {
|
||||
AppArticleCategoryEntity current = records.get(i);
|
||||
Long id = selected.contains(current.getId()) ? ids.get(next++) : current.getId();
|
||||
AppArticleCategoryEntity update = new AppArticleCategoryEntity();
|
||||
update.setId(id);
|
||||
update.setSort(i + 1);
|
||||
updates.add(update);
|
||||
}
|
||||
Assert.state(updateBatchById(updates), "排序保存失败");
|
||||
}
|
||||
|
||||
}
|
||||
+52
-14
@@ -13,6 +13,13 @@ import com.pig4cloud.pigx.app.mapper.AppArticleMapper;
|
||||
import com.pig4cloud.pigx.app.service.AppArticleService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -32,19 +39,17 @@ public class AppArticleServiceImpl extends ServiceImpl<AppArticleMapper, AppArti
|
||||
private final AppArticleCollectMapper collectMapper;
|
||||
|
||||
/**
|
||||
* 获取文章详情,并尝试将阅读数加 1。
|
||||
* <p>
|
||||
* 如果传入用户 ID,会额外查询该用户是否已收藏当前文章。
|
||||
* 阅读数更新使用当前 visit 值作为条件,降低并发覆盖风险。
|
||||
*
|
||||
* @param id 文章 ID
|
||||
* @param userId 当前用户 ID,可为空
|
||||
* @return 文章详情
|
||||
* 获取文章详情,并尝试将阅读数加 1。
|
||||
* <p>
|
||||
* 如果传入用户 ID,会额外查询该用户是否已收藏当前文章。 阅读数更新使用当前 visit 值作为条件,降低并发覆盖风险。
|
||||
* @param id 文章 ID
|
||||
* @param userId 当前用户 ID,可为空
|
||||
* @return 文章详情
|
||||
*/
|
||||
@Override
|
||||
public AppArticleEntity getArticleAndIncrById(Long id, Long userId) {
|
||||
AppArticleEntity appArticleEntity = baseMapper.selectById(id);
|
||||
// 登录用户访问详情时,补充当前用户是否已收藏该文章。
|
||||
// 登录用户访问详情时,补充当前用户是否已收藏该文章。
|
||||
if (Objects.nonNull(userId)) {
|
||||
boolean exists = collectMapper.exists(Wrappers.<AppArticleCollectEntity>lambdaQuery()//
|
||||
.eq(AppArticleCollectEntity::getArticleId, appArticleEntity.getId())//
|
||||
@@ -54,7 +59,7 @@ public class AppArticleServiceImpl extends ServiceImpl<AppArticleMapper, AppArti
|
||||
|
||||
Integer nowVisit = appArticleEntity.getVisit();
|
||||
appArticleEntity.setVisit(nowVisit + 1);
|
||||
// 使用旧 visit 值作为更新条件,避免并发访问时直接覆盖最新阅读数。
|
||||
// 使用旧 visit 值作为更新条件,避免并发访问时直接覆盖最新阅读数。
|
||||
baseMapper.update(appArticleEntity,
|
||||
Wrappers.<AppArticleEntity>lambdaQuery()
|
||||
.eq(AppArticleEntity::getId, id)
|
||||
@@ -63,11 +68,10 @@ public class AppArticleServiceImpl extends ServiceImpl<AppArticleMapper, AppArti
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询文章列表,并关联分类名称。
|
||||
*
|
||||
* 分页查询文章列表,并关联分类名称。
|
||||
* @param page 分页参数
|
||||
* @param appArticle 文章查询条件
|
||||
* @return 文章分页结果,包含分类名称 cname
|
||||
* @return 文章分页结果,包含分类名称 cname
|
||||
*/
|
||||
@Override
|
||||
public Page pageAndCname(Page page, AppArticleEntity appArticle) {
|
||||
@@ -77,8 +81,42 @@ public class AppArticleServiceImpl extends ServiceImpl<AppArticleMapper, AppArti
|
||||
.leftJoin(AppArticleCategoryEntity.class, AppArticleCategoryEntity::getId, AppArticleEntity::getCid)
|
||||
.like(StrUtil.isNotBlank(appArticle.getAuthor()), AppArticleEntity::getAuthor, appArticle.getAuthor())
|
||||
.like(StrUtil.isNotBlank(appArticle.getTitle()), AppArticleEntity::getTitle, appArticle.getTitle())
|
||||
.eq(Objects.nonNull(appArticle.getCid()), AppArticleEntity::getCid, appArticle.getCid());
|
||||
.eq(Objects.nonNull(appArticle.getCid()), AppArticleEntity::getCid, appArticle.getCid())
|
||||
.orderByAsc(AppArticleEntity::getSort, AppArticleEntity::getId);
|
||||
return this.page(page, wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 按传入 ID 顺序调整文章,保留未选中记录在排序序列中的位置。
|
||||
* <p>
|
||||
* 以当前租户内未删除记录的排序值、主键升序为基准,仅重排选中记录占据的位置, 再将全部记录的排序值从 1 起连续重编号。
|
||||
* @param ids 按目标顺序排列的文章 ID;不可为 null 或空,不可包含 null、重复或不可用的 ID
|
||||
* @throws IllegalArgumentException ID 列表为空、包含 null 或重复值,或指定记录已删除、不属于当前租户 或不存在
|
||||
* @throws IllegalStateException 批量更新返回失败
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void sort(List<Long> ids) {
|
||||
Assert.notEmpty(ids, "排序记录不能为空");
|
||||
Set<Long> selected = new HashSet<>(ids);
|
||||
Assert.isTrue(!selected.contains(null) && selected.size() == ids.size(), "排序记录无效");
|
||||
// 锁定统一顺序,避免重复排序值和分页边界导致拖动后顺序丢失。
|
||||
List<AppArticleEntity> records = list(Wrappers.<AppArticleEntity>lambdaQuery()
|
||||
.orderByAsc(AppArticleEntity::getSort, AppArticleEntity::getId)
|
||||
.last("FOR UPDATE"));
|
||||
long matched = records.stream().filter(row -> selected.contains(row.getId())).count();
|
||||
Assert.isTrue(matched == ids.size(), "记录已变更,请刷新后重试");
|
||||
List<AppArticleEntity> updates = new ArrayList<>();
|
||||
int next = 0;
|
||||
for (int i = 0; i < records.size(); i++) {
|
||||
AppArticleEntity current = records.get(i);
|
||||
Long id = selected.contains(current.getId()) ? ids.get(next++) : current.getId();
|
||||
AppArticleEntity update = new AppArticleEntity();
|
||||
update.setId(id);
|
||||
update.setSort(i + 1);
|
||||
updates.add(update);
|
||||
}
|
||||
Assert.state(updateBatchById(updates), "排序保存失败");
|
||||
}
|
||||
|
||||
}
|
||||
+24
-3
@@ -61,7 +61,8 @@ public class SysPostController {
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public R<List<SysPost>> listPosts() {
|
||||
return R.ok(sysPostService.list(Wrappers.emptyWrapper()));
|
||||
return R.ok(sysPostService
|
||||
.list(Wrappers.<SysPost>lambdaQuery().orderByAsc(SysPost::getPostSort, SysPost::getPostId)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,8 +75,10 @@ public class SysPostController {
|
||||
@GetMapping("/page")
|
||||
@HasPermission("sys_post_view")
|
||||
public R getSysPostPage(@ParameterObject Page page, @ParameterObject SysPost sysPost) {
|
||||
return R.ok(sysPostService.page(page, Wrappers.<SysPost>lambdaQuery()
|
||||
.like(StrUtil.isNotBlank(sysPost.getPostName()), SysPost::getPostName, sysPost.getPostName())));
|
||||
return R.ok(sysPostService.page(page,
|
||||
Wrappers.<SysPost>lambdaQuery()
|
||||
.like(StrUtil.isNotBlank(sysPost.getPostName()), SysPost::getPostName, sysPost.getPostName())
|
||||
.orderByAsc(SysPost::getPostSort, SysPost::getPostId)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,6 +131,24 @@ public class SysPostController {
|
||||
return R.ok(sysPostService.updateById(sysPost));
|
||||
}
|
||||
|
||||
/**
|
||||
* 按传入 ID 顺序调整岗位,保留未选中记录在排序序列中的位置。
|
||||
* <p>
|
||||
* 以当前租户内未删除记录的排序值、主键升序为基准,仅重排选中记录占据的位置, 再将全部记录的排序值从 1 起连续重编号。
|
||||
* @param ids 按目标顺序排列的岗位 ID;不可为 null 或空,不可包含 null、重复或不可用的 ID
|
||||
* @return 排序保存成功的响应;校验或更新失败时抛出异常,由统一异常处理器转换响应
|
||||
* @throws IllegalArgumentException ID 列表为空、包含 null 或重复值,或指定记录已删除、不属于当前租户 或不存在
|
||||
* @throws IllegalStateException 批量更新返回失败
|
||||
*/
|
||||
@Operation(summary = "岗位拖拽排序", description = "按当前列表顺序保存岗位排序")
|
||||
@SysLog("岗位排序")
|
||||
@PutMapping("/sort")
|
||||
@HasPermission("sys_post_edit")
|
||||
public R sort(@RequestBody List<Long> ids) {
|
||||
sysPostService.sort(ids);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除岗位信息表
|
||||
* @param ids id 列表
|
||||
|
||||
+12
-2
@@ -33,6 +33,16 @@ import java.util.List;
|
||||
*/
|
||||
public interface SysPostService extends IService<SysPost> {
|
||||
|
||||
/**
|
||||
* 按传入 ID 顺序调整岗位,保留未选中记录在排序序列中的位置。
|
||||
* <p>
|
||||
* 以当前租户内未删除记录的排序值、主键升序为基准,仅重排选中记录占据的位置, 再将全部记录的排序值从 1 起连续重编号。
|
||||
* @param ids 按目标顺序排列的岗位 ID;不可为 null 或空,不可包含 null、重复或不可用的 ID
|
||||
* @throws IllegalArgumentException ID 列表为空、包含 null 或重复值,或指定记录已删除、不属于当前租户 或不存在
|
||||
* @throws IllegalStateException 批量更新返回失败
|
||||
*/
|
||||
void sort(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 导出excel 表格
|
||||
* @return
|
||||
@@ -42,8 +52,8 @@ public interface SysPostService extends IService<SysPost> {
|
||||
/**
|
||||
* 导入岗位
|
||||
* @param excelVOList 岗位列表
|
||||
* @param bindingResult 错误信息列表
|
||||
* @return ok fail
|
||||
* @param bindingResult 通用校验结果,其 target 持有错误信息列表
|
||||
* @return 全部导入成功返回 ok;存在校验失败时返回携带错误信息列表的 failed
|
||||
*/
|
||||
R importPost(List<PostExcelVO> excelVOList, BindingResult bindingResult);
|
||||
|
||||
|
||||
+96
-61
@@ -30,8 +30,11 @@ import com.pig4cloud.pigx.common.core.util.MsgUtils;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.excel.vo.ErrorMessage;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.validation.BindingResult;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -45,72 +48,104 @@ import java.util.Set;
|
||||
@Service
|
||||
public class SysPostServiceImpl extends ServiceImpl<SysPostMapper, SysPost> implements SysPostService {
|
||||
|
||||
/**
|
||||
* 导入岗位
|
||||
*
|
||||
* @param excelVOList 岗位列表
|
||||
* @param bindingResult 错误信息列表
|
||||
* @return ok fail
|
||||
*/
|
||||
@Override
|
||||
public R importPost(List<PostExcelVO> excelVOList, BindingResult bindingResult) {
|
||||
// 通用校验获取失败的数据
|
||||
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
|
||||
/**
|
||||
* 导入岗位
|
||||
* @param excelVOList 岗位列表
|
||||
* @param bindingResult 通用校验结果,其 target 持有错误信息列表
|
||||
* @return 全部导入成功返回 ok;存在校验失败时返回携带错误信息列表的 failed
|
||||
*/
|
||||
@Override
|
||||
public R importPost(List<PostExcelVO> excelVOList, BindingResult bindingResult) {
|
||||
// 通用校验获取失败的数据
|
||||
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
|
||||
|
||||
// 个性化校验逻辑
|
||||
List<SysPost> postList = this.list();
|
||||
// 个性化校验逻辑
|
||||
List<SysPost> postList = this.list();
|
||||
|
||||
// 执行数据插入操作 组装 PostDto
|
||||
for (PostExcelVO excel : excelVOList) {
|
||||
Set<String> errorMsg = new HashSet<>();
|
||||
// 检验岗位名称或者岗位编码是否存在
|
||||
boolean existPost = postList.stream()
|
||||
.anyMatch(post -> excel.getPostName().equals(post.getPostName())
|
||||
|| excel.getPostCode().equals(post.getPostCode()));
|
||||
// 执行数据插入操作 组装 PostDto
|
||||
for (PostExcelVO excel : excelVOList) {
|
||||
Set<String> errorMsg = new HashSet<>();
|
||||
// 检验岗位名称或者岗位编码是否存在
|
||||
boolean existPost = postList.stream()
|
||||
.anyMatch(post -> excel.getPostName().equals(post.getPostName())
|
||||
|| excel.getPostCode().equals(post.getPostCode()));
|
||||
|
||||
if (existPost) {
|
||||
errorMsg.add(MsgUtils.getMessage(UpmsErrorCodes.SYS_POST_NAMEORCODE_EXISTING, excel.getPostName(),
|
||||
excel.getPostCode()));
|
||||
}
|
||||
if (existPost) {
|
||||
errorMsg.add(MsgUtils.getMessage(UpmsErrorCodes.SYS_POST_NAMEORCODE_EXISTING, excel.getPostName(),
|
||||
excel.getPostCode()));
|
||||
}
|
||||
|
||||
// 数据合法情况
|
||||
if (CollUtil.isEmpty(errorMsg)) {
|
||||
insertExcelPost(excel);
|
||||
} else {
|
||||
// 数据不合法
|
||||
errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg));
|
||||
}
|
||||
}
|
||||
if (CollUtil.isNotEmpty(errorMessageList)) {
|
||||
return R.failed(errorMessageList);
|
||||
}
|
||||
return R.ok();
|
||||
}
|
||||
// 数据合法情况
|
||||
if (CollUtil.isEmpty(errorMsg)) {
|
||||
insertExcelPost(excel);
|
||||
}
|
||||
else {
|
||||
// 数据不合法
|
||||
errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg));
|
||||
}
|
||||
}
|
||||
if (CollUtil.isNotEmpty(errorMessageList)) {
|
||||
return R.failed(errorMessageList);
|
||||
}
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel 表格
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<PostExcelVO> listPost(SysPost query, Long[] ids) {
|
||||
List<SysPost> postList = this
|
||||
.list(Wrappers.lambdaQuery(query).in(ArrayUtil.isNotEmpty(ids), SysPost::getPostId, CollUtil.toList(ids)));
|
||||
// 转换成execl 对象输出
|
||||
return postList.stream().map(post -> {
|
||||
PostExcelVO postExcelVO = new PostExcelVO();
|
||||
BeanUtil.copyProperties(post, postExcelVO);
|
||||
return postExcelVO;
|
||||
}).toList();
|
||||
}
|
||||
/**
|
||||
* 导出excel 表格
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<PostExcelVO> listPost(SysPost query, Long[] ids) {
|
||||
List<SysPost> postList = this
|
||||
.list(Wrappers.lambdaQuery(query).in(ArrayUtil.isNotEmpty(ids), SysPost::getPostId, CollUtil.toList(ids)));
|
||||
// 转换成execl 对象输出
|
||||
return postList.stream().map(post -> {
|
||||
PostExcelVO postExcelVO = new PostExcelVO();
|
||||
BeanUtil.copyProperties(post, postExcelVO);
|
||||
return postExcelVO;
|
||||
}).toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入excel Post
|
||||
*/
|
||||
private void insertExcelPost(PostExcelVO excel) {
|
||||
SysPost sysPost = new SysPost();
|
||||
BeanUtil.copyProperties(excel, sysPost);
|
||||
this.save(sysPost);
|
||||
}
|
||||
/**
|
||||
* 插入excel Post
|
||||
*/
|
||||
private void insertExcelPost(PostExcelVO excel) {
|
||||
SysPost sysPost = new SysPost();
|
||||
BeanUtil.copyProperties(excel, sysPost);
|
||||
this.save(sysPost);
|
||||
}
|
||||
|
||||
/**
|
||||
* 按传入 ID 顺序调整岗位,保留未选中记录在排序序列中的位置。
|
||||
* <p>
|
||||
* 以当前租户内未删除记录的排序值、主键升序为基准,仅重排选中记录占据的位置, 再将全部记录的排序值从 1 起连续重编号。
|
||||
* @param ids 按目标顺序排列的岗位 ID;不可为 null 或空,不可包含 null、重复或不可用的 ID
|
||||
* @throws IllegalArgumentException ID 列表为空、包含 null 或重复值,或指定记录已删除、不属于当前租户 或不存在
|
||||
* @throws IllegalStateException 批量更新返回失败
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void sort(List<Long> ids) {
|
||||
Assert.notEmpty(ids, "排序记录不能为空");
|
||||
Set<Long> selected = new HashSet<>(ids);
|
||||
Assert.isTrue(!selected.contains(null) && selected.size() == ids.size(), "排序记录无效");
|
||||
// 锁定统一顺序,避免重复排序值和分页边界导致拖动后顺序丢失。
|
||||
List<SysPost> records = list(Wrappers.<SysPost>lambdaQuery()
|
||||
.orderByAsc(SysPost::getPostSort, SysPost::getPostId)
|
||||
.last("FOR UPDATE"));
|
||||
long matched = records.stream().filter(row -> selected.contains(row.getPostId())).count();
|
||||
Assert.isTrue(matched == ids.size(), "记录已变更,请刷新后重试");
|
||||
List<SysPost> updates = new ArrayList<>();
|
||||
int next = 0;
|
||||
for (int i = 0; i < records.size(); i++) {
|
||||
SysPost current = records.get(i);
|
||||
Long id = selected.contains(current.getPostId()) ? ids.get(next++) : current.getPostId();
|
||||
SysPost update = new SysPost();
|
||||
update.setPostId(id);
|
||||
update.setPostSort(i + 1);
|
||||
updates.add(update);
|
||||
}
|
||||
Assert.state(updateBatchById(updates), "排序保存失败");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user