feat 移动端的逻辑交互

This commit is contained in:
damonyuan 2024-10-20 11:31:30 +08:00
parent d8ff09aadf
commit 1555ca659e
12 changed files with 271 additions and 31 deletions

View File

@ -15,7 +15,7 @@ public enum ErrorEnum {
LOGIN_ACCOUNT_ERROR(0, "登录账号或密码错误"),
LOGIN_DISABLE_ERROR(0, "登录账号已被禁用了"),
TOKEN_EMPTY(0, "登录超时,请重新登录"),
TOKEN_INVALID(0, "token参数无效"),
TOKEN_INVALID(-1, "token参数无效"),
CAPTCHA_ERROR(0, "验证码错误"),
PAYMENT_ERROR(0, "发起支付失败"),

View File

@ -63,6 +63,16 @@ public class UserController {
return AjaxResult.success();
}
@NotLogin
@PostMapping("/resetPassword")
@ApiOperation(value="重置密码")
public AjaxResult<Object> resetPassword(@Validated @RequestBody ResetPasswordValidate passwordValidate) {
iUserService.resetPassword(passwordValidate);
return AjaxResult.success();
}
@NotLogin
@PostMapping("/forgotPwd")
@ApiOperation(value="忘记密码")

View File

@ -0,0 +1,20 @@
package com.mdd.front.service;
import com.mdd.common.entity.decorate.DecorateTabbar;
import com.mdd.front.vo.decorateTabbar.DecorateTabbarVo;
import java.util.List;
/**
* 底部导航服务接口类
*/
public interface IDecorateTabbarService {
/**
* @notes 获取底部导航列表
* @return array
* @author damonyuan
*/
List<DecorateTabbarVo> getTabbarLists();
}

View File

@ -97,4 +97,12 @@ public interface IUserService {
* @param userId 用户ID
*/
void bindOa(UserBindWechatValidate bindOaValidate, Integer userId);
/**
* @notes 重置登录密码
* @param $params
* @return bool
* @author damonyuan
*/
void resetPassword(ResetPasswordValidate passwordValidate);
}

View File

@ -161,7 +161,6 @@ public class ArticleServiceImpl implements IArticleService {
@Override
public ArticleDetailVo detail(Integer id, Integer userId) {
Article article = articleMapper.selectOne(new QueryWrapper<Article>()
.select("id,title,image,intro,summary,visit,author,content,create_time")
.eq("id", id)
.eq("is_show", 1)
.isNull("delete_time" )
@ -181,6 +180,8 @@ public class ArticleServiceImpl implements IArticleService {
vo.setCollect(articleCollect != null);
vo.setImage(UrlUtils.toAbsoluteUrl(article.getImage()));
vo.setCreateTime(TimeUtils.timestampToDate(article.getCreateTime()));
vo.setUpdateTime(TimeUtils.timestampToDate(article.getUpdateTime()));
vo.setClick(article.getClickActual() + article.getClickVirtual());
article.setClickActual(article.getClickActual() + 1);
articleMapper.updateById(article);

View File

@ -0,0 +1,58 @@
package com.mdd.front.service.impl;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mdd.common.entity.decorate.DecorateTabbar;
import com.mdd.common.enums.YesNoEnum;
import com.mdd.common.mapper.decorate.DecorateTabbarMapper;
import com.mdd.common.util.*;
import com.mdd.front.service.IDecorateTabbarService;
import com.mdd.front.vo.decorateTabbar.DecorateTabbarVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* 底部导航服务实现类
*/
@Service
public class DecorateTabbarServiceImpl implements IDecorateTabbarService {
@Resource
DecorateTabbarMapper decorateTabbarMapper;
@Override
public List<DecorateTabbarVo> getTabbarLists() {
List<DecorateTabbar> list = decorateTabbarMapper.selectList(new QueryWrapper<DecorateTabbar>().eq("is_show", YesNoEnum.YES.getCode()));
List<DecorateTabbarVo> ret = new ArrayList<DecorateTabbarVo>();
if (list.size() == 0) {
return ret;
}
for (DecorateTabbar item : list) {
DecorateTabbarVo vo = new DecorateTabbarVo();
BeanUtils.copyProperties(item, vo);
if (StringUtils.isNotEmpty(item.getSelected())) {
vo.setSelected(UrlUtils.toAbsoluteUrl(item.getSelected()));
}
if (StringUtils.isNotEmpty(item.getUnselected())) {
vo.setUnselected(UrlUtils.toAbsoluteUrl(item.getUnselected()));
}
vo.setCreateTime(TimeUtils.timestampToDate(item.getCreateTime()));
vo.setUpdateTime(TimeUtils.timestampToDate(item.getUpdateTime()));
vo.setLink(StringUtils.isEmpty(item.getLink()) ? new JSONObject() : JSONObject.parse(item.getLink()));
ret.add(vo);
}
return ret;
}
}

View File

@ -1,5 +1,7 @@
package com.mdd.front.service.impl;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.mdd.common.config.GlobalConfig;
@ -12,7 +14,9 @@ import com.mdd.common.mapper.decorate.DecoratePageMapper;
import com.mdd.common.mapper.decorate.DecorateTabbarMapper;
import com.mdd.common.mapper.setting.HotSearchMapper;
import com.mdd.common.util.*;
import com.mdd.front.service.IDecorateTabbarService;
import com.mdd.front.service.IIndexService;
import com.mdd.front.vo.decorateTabbar.DecorateTabbarVo;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@ -24,6 +28,8 @@ import java.util.*;
@Service
public class IndexServiceImpl implements IIndexService {
@Resource
IDecorateTabbarService iDecorateTabbarService;
@Resource
DecoratePageMapper decoratePageMapper;
@ -61,17 +67,17 @@ public class IndexServiceImpl implements IIndexService {
Map<String, Object> map = new LinkedHashMap<>();
map.put("id", article.getId());
map.put("title", article.getTitle());
map.put("intro", article.getContent());
map.put("summary", article.getAbstractField());
map.put("desc", article.getDesc());
map.put("abstract", article.getAbstractField());
map.put("image", UrlUtils.toAbsoluteUrl(article.getImage()));
map.put("author", article.getAuthor());
map.put("click", article.getClickActual() + article.getClickVirtual());
map.put("createTime", TimeUtils.timestampToDate(article.getCreateTime()));
map.put("create_time", TimeUtils.timestampToDate(article.getCreateTime()));
articleList.add(map);
}
response.put("domain", UrlUtils.domain());
response.put("pages", decoratePage.getData());
response.put("page", decoratePage);
response.put("article", articleList);
return response;
}
@ -95,7 +101,8 @@ public class IndexServiceImpl implements IIndexService {
Map<String, Object> response = new LinkedHashMap<>();
response.put("type", decoratePage.getType());
response.put("name", decoratePage.getName());
response.put("pages", decoratePage.getData());
response.put("data", decoratePage.getData());
response.put("meta", decoratePage.getMeta());
return response;
}
@ -109,11 +116,17 @@ public class IndexServiceImpl implements IIndexService {
public Map<String, Object> config() {
Map<String, Object> response = new LinkedHashMap<>();
// 底部导航
List<DecorateTabbarVo> tabbar = iDecorateTabbarService.getTabbarLists();
// 导航颜色
JSONObject style = JSONObject.parse(ConfigUtils.get("tabbar", "style"));
// 登录配置
Map<String, Object> loginMap = new LinkedHashMap<>();
JSONObject loginMap = new JSONObject();
Map<String, String> loginConfig = ConfigUtils.get("login");
// 登录方式
loginMap.put("login_way", ListUtils.stringToListAsInt(loginConfig.getOrDefault("login_way", ""), ","));
loginMap.put("login_way", JSONArray.parseArray(loginConfig.getOrDefault("login_way", "[]")));
// 注册强制绑定手机
loginMap.put("coerce_mobile", Integer.parseInt(loginConfig.getOrDefault("coerce_mobile", "0")));
// 政策协议
@ -125,17 +138,32 @@ public class IndexServiceImpl implements IIndexService {
// qq授权登录
loginMap.put("qq_auth", Integer.parseInt(loginConfig.getOrDefault("qq_auth", "0")));
// 网站信息
JSONObject website = new JSONObject();
website.put("h5_favicon", UrlUtils.toAbsoluteUrl(ConfigUtils.get("website", "h5_favicon", "")));
website.put("shop_name", ConfigUtils.get("website", "shop_name", ""));
website.put("shop_logo", UrlUtils.toAbsoluteUrl(ConfigUtils.get("website", "shop_logo", "")));
// 备案信息
Map<String, String> websiteConfig = ConfigUtils.get("copyright");
String copyright = websiteConfig.getOrDefault("config", "[]");
List<Map<String, String>> copyrightMap = ListUtils.stringToListAsMapStr(copyright);
// 网址信息
// H5配置
JSONObject webPage = new JSONObject();
webPage.put("status", Integer.valueOf(ConfigUtils.get("web_page", "status", "1")));
webPage.put("page_status", Integer.valueOf(ConfigUtils.get("web_page", "page_status", "0")));
webPage.put("page_url", ConfigUtils.get("web_page", "page_url", ""));
webPage.put("url", UrlUtils.domain() + "/mobile");
response.put("admin_url", "");
response.put("copyright", copyrightMap);
response.put("domain", UrlUtils.domain());
response.put("style", style);
response.put("tabbar", tabbar);
response.put("login", loginMap);
response.put("website", website);
response.put("webPage", webPage);
response.put("version", GlobalConfig.version);
response.put("copyright", copyrightMap);
return response;
}

View File

@ -339,6 +339,9 @@ public class PcServiceImpI implements IPcService {
vo.setNext(nextMap);
}
article.setClickActual(article.getClickActual() + 1);
articleMapper.updateById(article);
return vo;
}
}

View File

@ -28,6 +28,7 @@ import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import javax.annotation.Resource;
@ -383,6 +384,36 @@ public class UserServiceImpl implements IUserService {
}
}
@Override
@Transactional
public void resetPassword(ResetPasswordValidate passwordValidate) {
String code = passwordValidate.getCode();
String mobile = passwordValidate.getMobile();
String password = passwordValidate.getPassword();
// 校验验证码
int sceneCode = NoticeEnum.FIND_LOGIN_PASSWORD_CAPTCHA.getCode();
if (!NoticeCheck.verify(sceneCode, code, mobile)) {
throw new OperateException("验证码错误!");
}
// 查询手机号
User user = userMapper.selectOne(new QueryWrapper<User>()
.select("id,account,mobile,is_disable")
.isNull("delete_time")
.eq("mobile", mobile)
.last("limit 1"));
// 验证账号
com.baomidou.mybatisplus.core.toolkit.Assert.notNull(user, "账号不存在!");
String pwd = ToolUtils.makePassword(password.trim());
// 更新密码
user.setPassword(pwd);
user.setUpdateTime(System.currentTimeMillis() / 1000);
userMapper.updateById(user);
}
/**
* 绑定微信授权
*

View File

@ -0,0 +1,34 @@
package com.mdd.front.validate.users;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import java.io.Serializable;
@Data
@ApiModel("修改密码参数")
public class ResetPasswordValidate implements Serializable {
private static final long serialVersionUID = 1L;
@NotNull(message = "password参数缺失")
@Pattern(message = "密码必须是6-20字母+数字组合!", regexp="^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$")
@ApiModelProperty(value = "新密码", required = true)
private String password;
@NotNull(message = "请确认密码")
@Pattern(message = "确认密码密码必须是6-20字母+数字组合!", regexp="^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$")
@ApiModelProperty(value = "确认密码", required = true)
private String passwordConfirm;
@NotNull(message = "验证码不能为空")
@ApiModelProperty(value = "code", required = true)
private String code;
@NotNull(message = "手机号不能为空")
@ApiModelProperty(value = "mobile", required = true)
private String mobile;
}

View File

@ -1,5 +1,6 @@
package com.mdd.front.vo.article;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ -15,31 +16,32 @@ public class ArticleDetailVo implements Serializable {
@ApiModelProperty(value = "文章ID")
private Integer id;
@ApiModelProperty("摘要")
@JsonProperty(value = "abstract")
private String abstractField;
@ApiModelProperty(value = "文章作者")
private String author;
@ApiModelProperty(value = "分类ID")
private Integer cid;
@ApiModelProperty(value = "浏览数量")
private Integer click;
@ApiModelProperty(value = "文章标题")
private String title;
@ApiModelProperty(value = "文章封面")
private String image;
@ApiModelProperty(value = "文章简介")
private String intro;
@ApiModelProperty(value = "文章描述")
private String summary;
@ApiModelProperty(value = "浏览数量")
private Integer visit;
@ApiModelProperty(value = "作者名称")
private String author;
@ApiModelProperty(value = "是否收藏")
private Boolean collect;
@ApiModelProperty(value = "文章内容")
private String content;
@ApiModelProperty(value = "创建时间")
private String createTime;
@ApiModelProperty(value = "更新时间")
private String updateTime;
@ApiModelProperty("简介")
private String desc;
@ApiModelProperty(value = "文章封面")
private String image;
@ApiModelProperty("是否显示: [0=否, 1=是]")
private Integer isShow;
@ApiModelProperty(value = "排序编号")
private Integer sort;
}

View File

@ -0,0 +1,45 @@
package com.mdd.front.vo.decorateTabbar;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
@Data
@ApiModel(value = "底部导航服务Vo")
public class DecorateTabbarVo implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value="id", type= IdType.AUTO)
@ApiModelProperty("ID")
private Integer id;
@ApiModelProperty("导航名称")
private String name;
@ApiModelProperty("未选图标")
private String selected;
@ApiModelProperty("已选图标")
private String unselected;
@ApiModelProperty("链接地址")
private JSONObject link;
@ApiModelProperty("是否显示")
private Integer isShow;
@ApiModelProperty("创建时间")
private String createTime;
@ApiModelProperty("更新时间")
private String updateTime;
}