修正快捷链接错误

修正部分IdUtils.validate调用结果判断错误
This commit is contained in:
liweiyi 2025-02-12 17:07:54 +08:00
parent 3055676cf8
commit 0e7b319498
22 changed files with 310 additions and 282 deletions

View File

@ -30,6 +30,8 @@ import com.chestnut.contentcore.fixed.dict.ContentAttribute;
import com.chestnut.contentcore.fixed.dict.ContentStatus;
import com.chestnut.contentcore.service.ICatalogService;
import com.chestnut.contentcore.service.IContentService;
import com.chestnut.contentcore.template.tag.CmsCatalogTag;
import com.chestnut.contentcore.template.tag.CmsContentTag;
import com.chestnut.contentcore.util.CatalogUtils;
import com.chestnut.contentcore.util.InternalUrlUtils;
import lombok.RequiredArgsConstructor;
@ -72,21 +74,21 @@ public class ArticleApiController extends BaseRestController {
@RequestParam(value = "preview", required = false, defaultValue = "false") Boolean preview,
@RequestParam(value = "text", required = false, defaultValue = "false") Boolean text
) {
if (!"Root".equalsIgnoreCase(level) && !IdUtils.validate(catalogId)) {
if (!CmsCatalogTag.CatalogTagLevel.isRoot(level) && !IdUtils.validate(catalogId)) {
return R.fail("The parameter cid is required where lv is `Root`.");
}
LambdaQueryWrapper<CmsContent> q = new LambdaQueryWrapper<>();
q.eq(CmsContent::getSiteId, siteId).eq(CmsContent::getStatus, ContentStatus.PUBLISHED);
if (!"Root".equalsIgnoreCase(level)) {
if (!CmsCatalogTag.CatalogTagLevel.isRoot(level)) {
CmsCatalog catalog = this.catalogService.getCatalog(catalogId);
if (Objects.isNull(catalog)) {
return R.fail("Catalog not found: " + catalogId);
}
if ("Current".equalsIgnoreCase(level)) {
if (CmsCatalogTag.CatalogTagLevel.isCurrent(level)) {
q.eq(CmsContent::getCatalogId, catalog.getCatalogId());
} else if ("Child".equalsIgnoreCase(level)) {
} else if (CmsCatalogTag.CatalogTagLevel.isChild(level)) {
q.likeRight(CmsContent::getCatalogAncestors, catalog.getAncestors() + CatalogUtils.ANCESTORS_SPLITER);
} else if ("CurrentAndChild".equalsIgnoreCase(level)) {
} else if (CmsCatalogTag.CatalogTagLevel.isCurrentAndChild(level)) {
q.likeRight(CmsContent::getCatalogAncestors, catalog.getAncestors());
}
}
@ -102,7 +104,7 @@ public class ArticleApiController extends BaseRestController {
q.apply(bit > 0, "attributes&{0}<>{1}", attrTotal, bit);
}
}
if ("Recent".equalsIgnoreCase(sortType)) {
if (CmsContentTag.SortTagAttr.isRecent(sortType)) {
q.orderByDesc(CmsContent::getPublishDate);
} else {
q.orderByDesc(Arrays.asList(CmsContent::getTopFlag, CmsContent::getSortFlag));

View File

@ -1,18 +1,18 @@
/*
* Copyright 2022-2024 兮玥(190785909@qq.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Copyright 2022-2024 兮玥(190785909@qq.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.chestnut.article.dao;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@ -39,7 +39,7 @@ import java.util.List;
public class CmsArticleDetailDAO extends BackupServiceImpl<CmsArticleDetailMapper, CmsArticleDetail, BCmsArticleDetailMapper, BCmsArticleDetail> {
public long countBySiteId(Long siteId) {
if (IdUtils.validate(siteId)) {
if (!IdUtils.validate(siteId)) {
return 0;
}
return this.count(new LambdaQueryWrapper<CmsArticleDetail>()
@ -47,7 +47,7 @@ public class CmsArticleDetailDAO extends BackupServiceImpl<CmsArticleDetailMappe
}
public Page<CmsArticleDetail> pageBySiteId(Page<CmsArticleDetail> page, Long siteId, List<SFunction<CmsArticleDetail, ?>> columns) {
if (IdUtils.validate(siteId)) {
if (!IdUtils.validate(siteId)) {
return page;
}
LambdaQueryWrapper<CmsArticleDetail> q = new LambdaQueryWrapper<CmsArticleDetail>()
@ -57,7 +57,7 @@ public class CmsArticleDetailDAO extends BackupServiceImpl<CmsArticleDetailMappe
}
public long countBackupBySiteId(Long siteId) {
if (IdUtils.validate(siteId)) {
if (!IdUtils.validate(siteId)) {
return 0;
}
return this.getBackupMapper().selectCount(new LambdaQueryWrapper<BCmsArticleDetail>()
@ -65,7 +65,7 @@ public class CmsArticleDetailDAO extends BackupServiceImpl<CmsArticleDetailMappe
}
public Page<BCmsArticleDetail> pageBackupBySiteId(Page<BCmsArticleDetail> page, Long siteId, List<SFunction<BCmsArticleDetail, ?>> columns) {
if (IdUtils.validate(siteId)) {
if (!IdUtils.validate(siteId)) {
return page;
}
return this.getBackupMapper().selectPage(page, new LambdaQueryWrapper<BCmsArticleDetail>()

View File

@ -1,18 +1,18 @@
/*
* Copyright 2022-2024 兮玥(190785909@qq.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Copyright 2022-2024 兮玥(190785909@qq.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.chestnut.contentcore.dao;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@ -52,7 +52,7 @@ public class CmsContentDAO extends BackupServiceImpl<CmsContentMapper, CmsConten
}
public long countBySiteId(Long siteId) {
if (IdUtils.validate(siteId)) {
if (!IdUtils.validate(siteId)) {
return 0;
}
return this.count(new LambdaQueryWrapper<CmsContent>()
@ -60,7 +60,7 @@ public class CmsContentDAO extends BackupServiceImpl<CmsContentMapper, CmsConten
}
public Page<CmsContent> pageBySiteId(Page<CmsContent> page, Long siteId, List<SFunction<CmsContent, ?>> columns) {
if (IdUtils.validate(siteId)) {
if (!IdUtils.validate(siteId)) {
return page;
}
LambdaQueryWrapper<CmsContent> q = new LambdaQueryWrapper<CmsContent>()
@ -70,7 +70,7 @@ public class CmsContentDAO extends BackupServiceImpl<CmsContentMapper, CmsConten
}
public long countBackupBySiteId(Long siteId) {
if (IdUtils.validate(siteId)) {
if (!IdUtils.validate(siteId)) {
return 0;
}
return this.getBackupMapper().selectCount(new LambdaQueryWrapper<BCmsContent>()
@ -78,7 +78,7 @@ public class CmsContentDAO extends BackupServiceImpl<CmsContentMapper, CmsConten
}
public Page<BCmsContent> pageBackupBySiteId(Page<BCmsContent> page, Long siteId, List<SFunction<BCmsContent, ?>> columns) {
if (IdUtils.validate(siteId)) {
if (!IdUtils.validate(siteId)) {
return page;
}
return this.getBackupMapper().selectPage(page, new LambdaQueryWrapper<BCmsContent>()

View File

@ -137,7 +137,7 @@ public class CmsCatalogTag extends AbstractListTag {
return DESC;
}
private enum CatalogTagLevel {
public enum CatalogTagLevel {
Root(ATTR_OPTION_LEVEL_ROOT),
Current(ATTR_OPTION_LEVEL_CURRENT),
Child(ATTR_OPTION_LEVEL_CHILD),
@ -150,27 +150,27 @@ public class CmsCatalogTag extends AbstractListTag {
this.desc = desc;
}
static boolean isRoot(String level) {
public static boolean isRoot(String level) {
return Root.name().equalsIgnoreCase(level);
}
static boolean isCurrent(String level) {
public static boolean isCurrent(String level) {
return Current.name().equalsIgnoreCase(level);
}
static boolean isChild(String level) {
public static boolean isChild(String level) {
return Child.name().equalsIgnoreCase(level);
}
static boolean isCurrentAndChild(String level) {
public static boolean isCurrentAndChild(String level) {
return CurrentAndChild.name().equalsIgnoreCase(level);
}
static boolean isSelf(String level) {
public static boolean isSelf(String level) {
return Self.name().equalsIgnoreCase(level);
}
static List<TagAttrOption> toTagAttrOptions() {
public static List<TagAttrOption> toTagAttrOptions() {
return List.of(
new TagAttrOption(Root.name(), Root.desc),
new TagAttrOption(Current.name(), Current.desc),

View File

@ -63,7 +63,7 @@ public class CmsContentRelaTag extends AbstractListTag {
public TagPageData prepareData(Environment env, Map<String, String> attrs, boolean page, int size, int pageIndex)
throws TemplateException {
long contentId = MapUtils.getLongValue(attrs, ATTR_CONTENT_ID);
if (IdUtils.validate(contentId)) {
if (!IdUtils.validate(contentId)) {
throw new TemplateException("Invalid content id: " + contentId, env);
}
TemplateContext context = FreeMarkerUtils.getTemplateContext(env);

View File

@ -220,7 +220,7 @@ public class CmsContentTag extends AbstractListTag {
}
}
enum SortTagAttr {
public enum SortTagAttr {
Recent(ATTR_OPTION_SORT_RECENT),
Views(ATTR_OPTION_SORT_VIEWS),
Default(ATTR_OPTION_SORT_DEFAULT);

View File

@ -68,7 +68,7 @@ public class CmsXModelDataTag extends AbstractTag {
public Map<String, TemplateModel> execute0(Environment env, Map<String, String> attrs)
throws TemplateException {
long modelId = MapUtils.getLongValue(attrs, ATTR_MODEL_ID);
if (IdUtils.validate(modelId)) {
if (!IdUtils.validate(modelId)) {
throw new InvalidTagAttrValueException(getTagName(), ATTR_MODEL_ID, String.valueOf(modelId), env);
}
String dataType = MapUtils.getString(attrs, ATTR_DATA_TYPE);

View File

@ -63,7 +63,7 @@ public class CmsXModelFieldTag extends AbstractListTag {
@Override
public TagPageData prepareData(Environment env, Map<String, String> attrs, boolean page, int size, int pageIndex) throws TemplateException {
long modelId = MapUtils.getLongValue(attrs, ATTR_MODEL_ID);
if (IdUtils.validate(modelId)) {
if (!IdUtils.validate(modelId)) {
throw new InvalidTagAttrValueException(getTagName(), ATTR_MODEL_ID, String.valueOf(modelId), env);
}
XModel xmodel = this.modelService.getById(modelId);

View File

@ -67,7 +67,7 @@ public class CmsImageTag extends AbstractListTag {
public TagPageData prepareData(Environment env, Map<String, String> attrs, boolean page, int size, int pageIndex)
throws TemplateException {
long contentId = MapUtils.getLongValue(attrs, ATTR_CONTENT_ID, 0);
if (IdUtils.validate(contentId)) {
if (!IdUtils.validate(contentId)) {
throw new InvalidTagAttrValueException(getTagName(), ATTR_CONTENT_ID, String.valueOf(contentId), env);
}
CmsContent c = this.contentService.dao().getById(contentId);

View File

@ -67,7 +67,7 @@ public class CmsAudioTag extends AbstractListTag {
public TagPageData prepareData(Environment env, Map<String, String> attrs, boolean page, int size, int pageIndex)
throws TemplateException {
long contentId = MapUtils.getLongValue(attrs, ATTR_CONTENT_ID, 0);
if (IdUtils.validate(contentId)) {
if (!IdUtils.validate(contentId)) {
throw new InvalidTagAttrValueException(getTagName(), ATTR_CONTENT_ID, String.valueOf(contentId), env);
}
CmsContent c = this.contentService.dao().getById(contentId);

View File

@ -67,7 +67,7 @@ public class CmsVideoTag extends AbstractListTag {
public TagPageData prepareData(Environment env, Map<String, String> attrs, boolean page, int size, int pageIndex)
throws TemplateException {
long contentId = MapUtils.getLongValue(attrs, ATTR_CONTENT_ID, 0);
if (IdUtils.validate(contentId)) {
if (!IdUtils.validate(contentId)) {
throw new InvalidTagAttrValueException(getTagName(), ATTR_CONTENT_ID, String.valueOf(contentId), env);
}
CmsContent c = this.contentService.dao().getById(contentId);

View File

@ -85,7 +85,12 @@ public enum CommonErrorCode implements ErrorCode {
/**
* 任务{0}正在运行中
*/
ASYNC_TASK_RUNNING;
ASYNC_TASK_RUNNING,
/**
* 上传文件不能为空
*/
UPLOAD_FILE_EMPTY;
@Override
public String value() {

View File

@ -40,5 +40,5 @@ public @interface I18nField {
* 可使用占位符来获取当前对象其他字段属性值例如实体类的ID字段值可使用#{fieldName}大括号内是字段名会被替换为指定字段的值
* </p>
*/
public String value() default StringUtils.EMPTY;
String value() default StringUtils.EMPTY;
}

View File

@ -83,7 +83,7 @@ public class IdUtils {
* @return
*/
public static boolean validate(List<Long> ids, boolean removeInvalidId) {
if (ids == null || ids.size() == 0) {
if (ids == null || ids.isEmpty()) {
return false;
}
for (Iterator<Long> iterator = ids.iterator(); iterator.hasNext();) {
@ -96,7 +96,7 @@ public class IdUtils {
}
}
}
return ids.size() > 0;
return !ids.isEmpty();
}
public static boolean validate(List<Long> ids) {

View File

@ -15,5 +15,6 @@ ERRCODE.COMMON.FIXED_DICT_NOT_ALLOW_ADD=此系统固定字典类型不能添加
ERRCODE.COMMON.FIXED_CONFIG_DEL=系统固定配置参数[{0}]不能删除
ERRCODE.COMMON.FIXED_CONFIG_UPDATE=系统固定配置参数[{0}]不能修改键名
ERRCODE.COMMON.ASYNC_TASK_RUNNING=任务“{0}”正在运行中
ERRCODE.COMMON.UPLOAD_FILE_EMPTY=上传文件不能为空
AsyncTask.SuccessMsg=任务执行成功

View File

@ -15,5 +15,6 @@ ERRCODE.COMMON.FIXED_DICT_NOT_ALLOW_ADD=The fixed dict not allow to add data ite
ERRCODE.COMMON.FIXED_CONFIG_DEL=The fixed config "{0}" cannot be delete.
ERRCODE.COMMON.FIXED_CONFIG_UPDATE=The fixed config "{0}" cannot modify key.
ERRCODE.COMMON.ASYNC_TASK_RUNNING=The task "{0}" is running.
ERRCODE.COMMON.UPLOAD_FILE_EMPTY=Upload file cannot be empty.
AsyncTask.SuccessMsg=Task completed.

View File

@ -15,5 +15,6 @@ ERRCODE.COMMON.FIXED_DICT_NOT_ALLOW_ADD=此系統固定字典類型不能添加
ERRCODE.COMMON.FIXED_CONFIG_DEL=系統固定配置參數[{0}]不能刪除
ERRCODE.COMMON.FIXED_CONFIG_UPDATE=系統固定配置參數[{0}]不能修改鍵名
ERRCODE.COMMON.ASYNC_TASK_RUNNING=任務“{0}”正在運行中
ERRCODE.COMMON.UPLOAD_FILE_EMPTY=上傳文件不能為空
AsyncTask.SuccessMsg=任務執行成功

View File

@ -20,6 +20,7 @@ import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.chestnut.common.domain.R;
import com.chestnut.common.i18n.I18nUtils;
import com.chestnut.common.utils.DateUtils;
import com.chestnut.common.utils.StringUtils;
import jakarta.servlet.http.HttpServletResponse;
@ -114,7 +115,7 @@ public class BaseRestController {
public record SelectOption(String value, String label) {}
protected <T> R<List<SelectOption>> bindSelectOptions(Collection<T> list, Function<T, String> valueGetter, Function<T, String> labelGetter) {
List<SelectOption> options = list.stream().map(item -> {
return new SelectOption(valueGetter.apply(item), labelGetter.apply(item));
return new SelectOption(valueGetter.apply(item), I18nUtils.get(labelGetter.apply(item)));
}).toList();
return R.ok(options);
}

View File

@ -15,27 +15,26 @@
*/
package com.chestnut.common.staticize.config;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.Properties;
import com.chestnut.common.staticize.config.properties.FreeMarkerProperties;
import com.chestnut.common.utils.SpringUtils;
import com.chestnut.common.utils.StringUtils;
import com.chestnut.common.utils.file.FileExUtils;
import freemarker.cache.FileTemplateLoader;
import freemarker.cache.MruCacheStorage;
import freemarker.cache.MultiTemplateLoader;
import freemarker.cache.TemplateLoader;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.chestnut.common.staticize.config.properties.FreeMarkerProperties;
import com.chestnut.common.utils.SpringUtils;
import com.chestnut.common.utils.StringUtils;
import com.chestnut.common.utils.file.FileExUtils;
import freemarker.cache.FileTemplateLoader;
import freemarker.cache.MruCacheStorage;
import freemarker.cache.MultiTemplateLoader;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.Properties;
@Configuration
@EnableConfigurationProperties(FreeMarkerProperties.class)
@ -51,19 +50,18 @@ public class FreeMarkerConfig {
* @param properties
* @param fileTemplateLoader
* @return
* @throws IOException
* @throws TemplateException
*/
@Bean("staticizeConfiguration")
@ConditionalOnMissingBean(freemarker.template.Configuration.class)
freemarker.template.Configuration staticizeFreeMarkerConfiguration(final FreeMarkerProperties properties,
final List<FileTemplateLoader> fileTemplateLoaders) throws IOException, TemplateException {
final List<TemplateLoader> templateLoaders) throws TemplateException {
freemarker.template.Configuration cfg = new freemarker.template.Configuration(
freemarker.template.Configuration.VERSION_2_3_31);
cfg.setDefaultEncoding(properties.getDefaultEncoding());
// 模板加载路径
MultiTemplateLoader multiTemplateLoader = new MultiTemplateLoader(
fileTemplateLoaders.toArray(FileTemplateLoader[]::new));
templateLoaders.toArray(TemplateLoader[]::new));
cfg.setTemplateLoader(multiTemplateLoader);
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.HTML_DEBUG_HANDLER);
// 默认模板缓存策略Most recently use cache.

View File

@ -1,191 +1,210 @@
/*
* Copyright 2022-2024 兮玥(190785909@qq.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.chestnut.system.controller;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.chestnut.common.domain.R;
import com.chestnut.common.exception.CommonErrorCode;
import com.chestnut.common.i18n.I18nUtils;
import com.chestnut.common.log.annotation.Log;
import com.chestnut.common.log.enums.BusinessType;
import com.chestnut.common.security.SecurityUtils;
import com.chestnut.common.security.anno.Priv;
import com.chestnut.common.security.domain.LoginUser;
import com.chestnut.common.security.web.BaseRestController;
import com.chestnut.common.utils.Assert;
import com.chestnut.common.utils.IP2RegionUtils;
import com.chestnut.common.utils.StringUtils;
import com.chestnut.system.annotation.IgnoreDemoMode;
import com.chestnut.system.config.SystemConfig;
import com.chestnut.system.domain.SysMenu;
import com.chestnut.system.domain.SysUser;
import com.chestnut.system.domain.vo.DashboardUserVO;
import com.chestnut.system.domain.vo.ShortcutVO;
import com.chestnut.system.domain.vo.UserProfileVO;
import com.chestnut.system.enums.MenuType;
import com.chestnut.system.security.AdminUserType;
import com.chestnut.system.security.StpAdminUtil;
import com.chestnut.system.service.*;
import com.chestnut.system.user.preference.ShortcutUserPreference;
import lombok.RequiredArgsConstructor;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
/**
* 个人信息 业务处理
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/system/user/profile")
public class SysProfileController extends BaseRestController {
private final ISysUserService userService;
private final ISysDeptService deptService;
private final ISecurityConfigService securityConfigService;
private final ISysMenuService menuService;
private final ISysPermissionService permissionService;
@Priv(type = AdminUserType.TYPE)
@GetMapping
public R<?> profile() {
LoginUser loginUser = StpAdminUtil.getLoginUser();
SysUser user = (SysUser) loginUser.getUser();
user.setAvatarSrc(SystemConfig.getResourcePrefix() + user.getAvatar());
String roleGroup = userService.selectUserRoleGroup(loginUser.getUserId());
String postGroup = userService.selectUserPostGroup(loginUser.getUserId());
return R.ok(new UserProfileVO(user, roleGroup, postGroup));
}
@Priv(type = AdminUserType.TYPE)
@PutMapping
@Log(title = "个人中心", businessType = BusinessType.UPDATE)
public R<?> updateProfile(@RequestBody SysUser user) {
LoginUser loginUser = StpAdminUtil.getLoginUser();
boolean checkPhoneUnique = this.userService.checkPhoneUnique(user.getPhoneNumber(), loginUser.getUserId());
Assert.isTrue(checkPhoneUnique, () -> CommonErrorCode.DATA_CONFLICT.exception("PhoneNumber"));
boolean checkEmailUnique = this.userService.checkPhoneUnique(user.getEmail(), loginUser.getUserId());
Assert.isTrue(checkEmailUnique, () -> CommonErrorCode.DATA_CONFLICT.exception("Email"));
SysUser sysUser = (SysUser) loginUser.getUser();
sysUser.setNickName(user.getNickName());
sysUser.setPhoneNumber(user.getPhoneNumber());
sysUser.setEmail(user.getEmail());
sysUser.setSex(user.getSex());
LambdaUpdateWrapper<SysUser> q = new LambdaUpdateWrapper<SysUser>()
.set(SysUser::getNickName, user.getNickName()).set(SysUser::getPhoneNumber, user.getPhoneNumber())
.set(SysUser::getEmail, user.getEmail()).set(SysUser::getSex, user.getSex())
.eq(SysUser::getUserId, loginUser.getUserId());
if (this.userService.update(q)) {
StpAdminUtil.setLoginUser(loginUser);
return R.ok();
}
return R.fail();
}
@Priv(type = AdminUserType.TYPE)
@Log(title = "个人中心", businessType = BusinessType.UPDATE, isSaveRequestData = false)
@PutMapping("/updatePwd")
public R<?> updatePwd(String oldPassword, String newPassword) {
LoginUser loginUser = StpAdminUtil.getLoginUser();
SysUser user = userService.getById(loginUser.getUserId());
if (!SecurityUtils.matches(oldPassword, user.getPassword())) {
return R.fail("修改密码失败,旧密码错误");
}
if (SecurityUtils.matches(newPassword, user.getPassword())) {
return R.fail("新密码不能与旧密码相同");
}
// 密码安全规则校验
this.securityConfigService.validPassword(user, newPassword);
boolean update = this.userService.lambdaUpdate()
.set(SysUser::getPassword, SecurityUtils.passwordEncode(newPassword))
.set(SysUser::getPasswordModifyTime, LocalDateTime.now())
.eq(SysUser::getUserId, loginUser.getUserId()).update();
return update ? R.ok() : R.fail();
}
@IgnoreDemoMode
@Priv(type = AdminUserType.TYPE)
@Log(title = "个人中心", businessType = BusinessType.UPDATE)
@PostMapping("/avatar")
public R<?> avatar(@RequestParam("avatarfile") MultipartFile file) throws Exception {
if (Objects.isNull(file) || file.isEmpty()) {
return R.fail("上传图片异常,请联系管理员");
}
LoginUser loginUser = StpAdminUtil.getLoginUser();
String avatar = this.userService.uploadAvatar(loginUser.getUserId(), file);
// 更新缓存用户头像
SysUser user = (SysUser) loginUser.getUser();
user.setAvatar(avatar);
StpAdminUtil.setLoginUser(loginUser);
return R.ok(SystemConfig.getResourcePrefix() + avatar);
}
/**
* 首页用户信息
*/
@Priv(type = AdminUserType.TYPE)
@GetMapping("/homeInfo")
public R<?> getHomeInfo() {
LoginUser loginUser = StpAdminUtil.getLoginUser();
SysUser user = (SysUser) loginUser.getUser();
DashboardUserVO vo = new DashboardUserVO();
vo.setUserName(user.getUserName());
vo.setNickName(user.getNickName());
vo.setLastLoginTime(user.getLoginDate());
vo.setLastLoginIp(user.getLoginIp());
vo.setLastLoginAddr(IP2RegionUtils.ip2Region(user.getLoginIp()));
if (StringUtils.isNotEmpty(user.getAvatar())) {
vo.setAvatar(SystemConfig.getResourcePrefix() + user.getAvatar());
}
this.deptService.getDept(user.getDeptId()).ifPresent(dept -> vo.setDeptName(dept.getDeptName()));
return R.ok(vo);
}
@Priv(type = AdminUserType.TYPE)
@GetMapping("/shortcuts")
public R<?> getHomeShortcuts() {
SysUser user = this.userService.getById(StpAdminUtil.getLoginIdAsLong());
List<Long> menuIds = ShortcutUserPreference.getValue(user.getPreferences());
List<SysMenu> menus = this.menuService.lambdaQuery().eq(SysMenu::getMenuType, MenuType.Menu.value())
.in(menuIds.size() > 0, SysMenu::getMenuId, menuIds).last("limit 8").list();
List<String> menuPerms = StpAdminUtil.getLoginUser().getPermissions();
if (!menuPerms.contains(ISysPermissionService.ALL_PERMISSION)) {
menus = menus.stream().filter(m -> {
return StringUtils.isEmpty(m.getPerms()) || menuPerms.contains(m.getPerms());
}).toList();
}
I18nUtils.replaceI18nFields(menus, LocaleContextHolder.getLocale());
List<ShortcutVO> result = menus.stream()
.sorted(Comparator.comparingInt(m -> menuIds.indexOf(m.getMenuId())))
.map(m -> new ShortcutVO(m.getMenuName(), m.getIcon(), StringUtils.capitalize(m.getPath()))).toList();
return R.ok(result);
}
}
/*
* Copyright 2022-2024 兮玥(190785909@qq.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.chestnut.system.controller;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.chestnut.common.domain.R;
import com.chestnut.common.exception.CommonErrorCode;
import com.chestnut.common.i18n.I18nUtils;
import com.chestnut.common.log.annotation.Log;
import com.chestnut.common.log.enums.BusinessType;
import com.chestnut.common.security.SecurityUtils;
import com.chestnut.common.security.anno.Priv;
import com.chestnut.common.security.domain.LoginUser;
import com.chestnut.common.security.web.BaseRestController;
import com.chestnut.common.utils.Assert;
import com.chestnut.common.utils.IP2RegionUtils;
import com.chestnut.common.utils.IdUtils;
import com.chestnut.common.utils.StringUtils;
import com.chestnut.system.annotation.IgnoreDemoMode;
import com.chestnut.system.config.SystemConfig;
import com.chestnut.system.domain.SysMenu;
import com.chestnut.system.domain.SysUser;
import com.chestnut.system.domain.vo.DashboardUserVO;
import com.chestnut.system.domain.vo.ShortcutVO;
import com.chestnut.system.domain.vo.UserProfileVO;
import com.chestnut.system.enums.MenuType;
import com.chestnut.system.security.AdminUserType;
import com.chestnut.system.security.StpAdminUtil;
import com.chestnut.system.service.*;
import com.chestnut.system.user.preference.ShortcutUserPreference;
import lombok.RequiredArgsConstructor;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
/**
* 个人信息 业务处理
*/
@RestController
@RequiredArgsConstructor
@RequestMapping("/system/user/profile")
public class SysProfileController extends BaseRestController {
private final ISysUserService userService;
private final ISysDeptService deptService;
private final ISecurityConfigService securityConfigService;
private final ISysMenuService menuService;
private final ISysPermissionService permissionService;
@Priv(type = AdminUserType.TYPE)
@GetMapping
public R<?> profile() {
LoginUser loginUser = StpAdminUtil.getLoginUser();
SysUser user = (SysUser) loginUser.getUser();
user.setAvatarSrc(SystemConfig.getResourcePrefix() + user.getAvatar());
String roleGroup = userService.selectUserRoleGroup(loginUser.getUserId());
String postGroup = userService.selectUserPostGroup(loginUser.getUserId());
return R.ok(new UserProfileVO(user, roleGroup, postGroup));
}
@Priv(type = AdminUserType.TYPE)
@PutMapping
@Log(title = "个人中心", businessType = BusinessType.UPDATE)
public R<?> updateProfile(@RequestBody SysUser user) {
LoginUser loginUser = StpAdminUtil.getLoginUser();
boolean checkPhoneUnique = this.userService.checkPhoneUnique(user.getPhoneNumber(), loginUser.getUserId());
Assert.isTrue(checkPhoneUnique, () -> CommonErrorCode.DATA_CONFLICT.exception("PhoneNumber"));
boolean checkEmailUnique = this.userService.checkPhoneUnique(user.getEmail(), loginUser.getUserId());
Assert.isTrue(checkEmailUnique, () -> CommonErrorCode.DATA_CONFLICT.exception("Email"));
SysUser sysUser = (SysUser) loginUser.getUser();
sysUser.setNickName(user.getNickName());
sysUser.setPhoneNumber(user.getPhoneNumber());
sysUser.setEmail(user.getEmail());
sysUser.setSex(user.getSex());
LambdaUpdateWrapper<SysUser> q = new LambdaUpdateWrapper<SysUser>()
.set(SysUser::getNickName, user.getNickName()).set(SysUser::getPhoneNumber, user.getPhoneNumber())
.set(SysUser::getEmail, user.getEmail()).set(SysUser::getSex, user.getSex())
.eq(SysUser::getUserId, loginUser.getUserId());
if (this.userService.update(q)) {
StpAdminUtil.setLoginUser(loginUser);
return R.ok();
}
return R.fail();
}
@Priv(type = AdminUserType.TYPE)
@Log(title = "个人中心", businessType = BusinessType.UPDATE, isSaveRequestData = false)
@PutMapping("/updatePwd")
public R<?> updatePwd(String oldPassword, String newPassword) {
LoginUser loginUser = StpAdminUtil.getLoginUser();
SysUser user = userService.getById(loginUser.getUserId());
if (!SecurityUtils.matches(oldPassword, user.getPassword())) {
return R.fail("修改密码失败,旧密码错误");
}
if (SecurityUtils.matches(newPassword, user.getPassword())) {
return R.fail("新密码不能与旧密码相同");
}
// 密码安全规则校验
this.securityConfigService.validPassword(user, newPassword);
boolean update = this.userService.lambdaUpdate()
.set(SysUser::getPassword, SecurityUtils.passwordEncode(newPassword))
.set(SysUser::getPasswordModifyTime, LocalDateTime.now())
.eq(SysUser::getUserId, loginUser.getUserId()).update();
return update ? R.ok() : R.fail();
}
@IgnoreDemoMode
@Priv(type = AdminUserType.TYPE)
@Log(title = "个人中心", businessType = BusinessType.UPDATE)
@PostMapping("/avatar")
public R<?> avatar(@RequestParam("avatarfile") MultipartFile file) throws Exception {
if (Objects.isNull(file) || file.isEmpty()) {
return R.fail("上传图片异常,请联系管理员");
}
LoginUser loginUser = StpAdminUtil.getLoginUser();
String avatar = this.userService.uploadAvatar(loginUser.getUserId(), file);
// 更新缓存用户头像
SysUser user = (SysUser) loginUser.getUser();
user.setAvatar(avatar);
StpAdminUtil.setLoginUser(loginUser);
return R.ok(SystemConfig.getResourcePrefix() + avatar);
}
/**
* 首页用户信息
*/
@Priv(type = AdminUserType.TYPE)
@GetMapping("/homeInfo")
public R<?> getHomeInfo() {
LoginUser loginUser = StpAdminUtil.getLoginUser();
SysUser user = (SysUser) loginUser.getUser();
DashboardUserVO vo = new DashboardUserVO();
vo.setUserName(user.getUserName());
vo.setNickName(user.getNickName());
vo.setLastLoginTime(user.getLoginDate());
vo.setLastLoginIp(user.getLoginIp());
vo.setLastLoginAddr(IP2RegionUtils.ip2Region(user.getLoginIp()));
if (StringUtils.isNotEmpty(user.getAvatar())) {
vo.setAvatar(SystemConfig.getResourcePrefix() + user.getAvatar());
}
this.deptService.getDept(user.getDeptId()).ifPresent(dept -> vo.setDeptName(dept.getDeptName()));
return R.ok(vo);
}
@Priv(type = AdminUserType.TYPE)
@GetMapping("/shortcuts")
public R<?> getHomeShortcuts() {
SysUser user = this.userService.getById(StpAdminUtil.getLoginIdAsLong());
List<Long> menuIds = ShortcutUserPreference.getValue(user.getPreferences());
List<SysMenu> allMenus = this.menuService.lambdaQuery().list();
List<SysMenu> shortcuts = allMenus.stream().filter(m -> menuIds.contains(m.getMenuId())).toList();
List<String> menuPerms = StpAdminUtil.getLoginUser().getPermissions();
if (!menuPerms.contains(ISysPermissionService.ALL_PERMISSION)) {
shortcuts = shortcuts.stream().filter(m -> {
return StringUtils.isEmpty(m.getPerms()) || menuPerms.contains(m.getPerms());
}).toList();
}
shortcuts.forEach(shortcut -> {
List<String> paths = new ArrayList<>();
generateMenuRoute(shortcut, allMenus, paths);
shortcut.setPath(String.join("/", paths));
});
I18nUtils.replaceI18nFields(shortcuts, LocaleContextHolder.getLocale());
List<ShortcutVO> result = shortcuts.stream()
.sorted(Comparator.comparingInt(m -> menuIds.indexOf(m.getMenuId())))
.map(m -> new ShortcutVO(m.getMenuName(), m.getIcon(), m.getPath())).toList();
return R.ok(result);
}
private void generateMenuRoute(SysMenu menu, List<SysMenu> menus, List<String> paths) {
paths.add(0, menu.getPath());
if (IdUtils.validate(menu.getParentId())) {
menus.forEach(m -> {
if (m.getMenuId().equals(menu.getParentId())) {
generateMenuRoute(m, menus, paths);
}
});
}
}
}

View File

@ -15,13 +15,13 @@
*/
package com.chestnut.system.service;
import java.util.List;
import com.baomidou.mybatisplus.extension.service.IService;
import com.chestnut.common.domain.TreeNode;
import com.chestnut.system.domain.SysMenu;
import com.chestnut.system.domain.vo.RouterVO;
import java.util.List;
/**
* 菜单 业务层
*
@ -37,7 +37,7 @@ public interface ISysMenuService extends IService<SysMenu> {
* 菜单列表
* @return 路由列表
*/
public List<RouterVO> buildRouters(List<SysMenu> menus);
List<RouterVO> buildRouters(List<SysMenu> menus);
/**
* 构建前端所需要树结构
@ -46,7 +46,7 @@ public interface ISysMenuService extends IService<SysMenu> {
* 菜单列表
* @return 树结构列表
*/
public List<SysMenu> buildMenuTree(List<SysMenu> menus);
List<SysMenu> buildMenuTree(List<SysMenu> menus);
/**
* 构建前端所需要下拉树结构
@ -55,7 +55,7 @@ public interface ISysMenuService extends IService<SysMenu> {
* 菜单列表
* @return 下拉树结构列表
*/
public List<TreeNode<Long>> buildMenuTreeSelect(List<SysMenu> menus);
List<TreeNode<Long>> buildMenuTreeSelect(List<SysMenu> menus);
/**
* 新增保存菜单信息
@ -64,7 +64,7 @@ public interface ISysMenuService extends IService<SysMenu> {
* 菜单信息
* @return 结果
*/
public void insertMenu(SysMenu menu);
void insertMenu(SysMenu menu);
/**
* 修改保存菜单信息
@ -73,7 +73,7 @@ public interface ISysMenuService extends IService<SysMenu> {
* 菜单信息
* @return 结果
*/
public void updateMenu(SysMenu menu);
void updateMenu(SysMenu menu);
/**
* 删除菜单管理信息
@ -82,7 +82,7 @@ public interface ISysMenuService extends IService<SysMenu> {
* 菜单ID
* @return 结果
*/
public void deleteMenuById(Long menuId);
void deleteMenuById(Long menuId);
List<SysMenu> getChildPerms(List<SysMenu> list, int parentId);
}

View File

@ -38,7 +38,7 @@ export default {
})
},
handleShortcutRedirect(router) {
this.$router.push({ name: router })
this.$router.push({ path: router })
}
}
};