Commit bd22847a authored by Menethil's avatar Menethil
Browse files

添加注册短信验证和重置密码短信验证

parent 129cd27f
package org.linlinjava.litemall.core.notify; package org.linlinjava.litemall.core.notify;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.MailSender; import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.SimpleMailMessage;
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Async;
...@@ -54,6 +53,23 @@ public class NotifyService { ...@@ -54,6 +53,23 @@ public class NotifyService {
smsSender.sendWithTemplate(phoneNumber, templateId, params); smsSender.sendWithTemplate(phoneNumber, templateId, params);
} }
/**
* 以同步的方式发送短信模版消息通知
*
* @param phoneNumber 接收通知的电话号码
* @param notifyType 通知类别,通过该枚举值在配置文件中获取相应的模版ID
* @param params 通知模版内容里的参数,类似"您的验证码为{1}"中{1}的值
* @return
*/
public SmsResult notifySmsTemplateSync(String phoneNumber, NotifyType notifyType, String[] params) {
if (smsSender == null)
return null;
int templateId = Integer.parseInt(getTemplateId(notifyType, smsTemplate));
return smsSender.sendWithTemplate(phoneNumber, templateId, params);
}
/** /**
* 微信模版消息通知 * 微信模版消息通知
* *
......
package org.linlinjava.litemall.core.notify;
/**
* 发送短信的返回结果
*/
public class SmsResult {
private boolean successful;
private Object result;
/**
* 短信是否发送成功
*
* @return
*/
public boolean isSuccessful() {
return successful;
}
public void setSuccessful(boolean successful) {
this.successful = successful;
}
public Object getResult() {
return result;
}
public void setResult(Object result) {
this.result = result;
}
}
...@@ -8,7 +8,7 @@ public interface SmsSender { ...@@ -8,7 +8,7 @@ public interface SmsSender {
* @param phone 接收通知的电话号码 * @param phone 接收通知的电话号码
* @param content 短消息内容 * @param content 短消息内容
*/ */
void send(String phone, String content); SmsResult send(String phone, String content);
/** /**
...@@ -18,5 +18,5 @@ public interface SmsSender { ...@@ -18,5 +18,5 @@ public interface SmsSender {
* @param templateId 通知模板ID * @param templateId 通知模板ID
* @param params 通知模版内容里的参数,类似"您的验证码为{1}"中{1}的值 * @param params 通知模版内容里的参数,类似"您的验证码为{1}"中{1}的值
*/ */
void sendWithTemplate(String phone, int templateId, String[] params); SmsResult sendWithTemplate(String phone, int templateId, String[] params);
} }
\ No newline at end of file
...@@ -5,11 +5,14 @@ import com.github.qcloudsms.SmsSingleSenderResult; ...@@ -5,11 +5,14 @@ import com.github.qcloudsms.SmsSingleSenderResult;
import com.github.qcloudsms.httpclient.HTTPException; import com.github.qcloudsms.httpclient.HTTPException;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;
import java.io.IOException; import java.io.IOException;
/* /*
* 腾讯云短信服务 * 腾讯云短信服务
*/ */
@Service
public class TencentSmsSender implements SmsSender { public class TencentSmsSender implements SmsSender {
private final Log logger = LogFactory.getLog(TencentSmsSender.class); private final Log logger = LogFactory.getLog(TencentSmsSender.class);
...@@ -24,22 +27,36 @@ public class TencentSmsSender implements SmsSender { ...@@ -24,22 +27,36 @@ public class TencentSmsSender implements SmsSender {
} }
@Override @Override
public void send(String phone, String content) { public SmsResult send(String phone, String content) {
try { try {
SmsSingleSenderResult result = sender.send(0, "86", phone, content, "", ""); SmsSingleSenderResult result = sender.send(0, "86", phone, content, "", "");
logger.debug(result); logger.debug(result);
SmsResult smsResult = new SmsResult();
smsResult.setSuccessful(true);
smsResult.setResult(result);
return smsResult;
} catch (HTTPException | IOException e) { } catch (HTTPException | IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
return null;
} }
@Override @Override
public void sendWithTemplate(String phone, int templateId, String[] params) { public SmsResult sendWithTemplate(String phone, int templateId, String[] params) {
try { try {
SmsSingleSenderResult result = sender.sendWithParam("86", phone, templateId, params, "", "", ""); SmsSingleSenderResult result = sender.sendWithParam("86", phone, templateId, params, "", "", "");
logger.debug(result); logger.debug(result);
SmsResult smsResult = new SmsResult();
smsResult.setSuccessful(true);
smsResult.setResult(result);
return smsResult;
} catch (HTTPException | IOException e) { } catch (HTTPException | IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
return null;
} }
} }
package org.linlinjava.litemall.wx.dao;
import java.time.LocalDateTime;
public class CaptchaItem {
private String phoneNumber;
private String code;
private LocalDateTime expireTime;
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public LocalDateTime getExpireTime() {
return expireTime;
}
public void setExpireTime(LocalDateTime expireTime) {
this.expireTime = expireTime;
}
}
\ No newline at end of file
package org.linlinjava.litemall.wx.service;
import org.linlinjava.litemall.wx.dao.CaptchaItem;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
/**
* 缓存系统中的验证码
*/
public class CaptchaCodeManager {
private static Map<String, CaptchaItem> captchaCodeCache = new HashMap<>();
/**
* 添加到缓存
*
* @param phoneNumber 电话号码
* @param code 验证码
*/
public static boolean addToCache(String phoneNumber, String code) {
//已经发过验证码且验证码还未过期
if (captchaCodeCache.get(phoneNumber) != null) {
if (captchaCodeCache.get(phoneNumber).getExpireTime().isAfter(LocalDateTime.now())) {
return false;
} else {
//存在但是已过期,删掉
captchaCodeCache.remove(phoneNumber);
}
}
CaptchaItem captchaItem = new CaptchaItem();
captchaItem.setPhoneNumber(phoneNumber);
captchaItem.setCode(code);
// 有效期为1分钟
captchaItem.setExpireTime(LocalDateTime.now().plusMinutes(1));
captchaCodeCache.put(phoneNumber, captchaItem);
return true;
}
/**
* 获取缓存的验证码
*
* @param phoneNumber 关联的电话号码
* @return 验证码
*/
public static String getCachedCaptcha(String phoneNumber) {
//没有这个电话记录
if (captchaCodeCache.get(phoneNumber) == null)
return null;
//有电话记录但是已经过期
if (captchaCodeCache.get(phoneNumber).getExpireTime().isBefore(LocalDateTime.now())) {
return null;
}
return captchaCodeCache.get(phoneNumber).getCode();
}
}
...@@ -5,17 +5,22 @@ import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; ...@@ -5,17 +5,22 @@ import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.common.exception.WxErrorException;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.linlinjava.litemall.core.notify.NotifyService;
import org.linlinjava.litemall.core.notify.NotifyType;
import org.linlinjava.litemall.core.notify.SmsResult;
import org.linlinjava.litemall.core.util.CharUtil;
import org.linlinjava.litemall.core.util.JacksonUtil;
import org.linlinjava.litemall.core.util.RegexUtil; import org.linlinjava.litemall.core.util.RegexUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.core.util.bcrypt.BCryptPasswordEncoder;
import org.linlinjava.litemall.db.domain.LitemallUser; import org.linlinjava.litemall.db.domain.LitemallUser;
import org.linlinjava.litemall.db.service.LitemallUserService; import org.linlinjava.litemall.db.service.LitemallUserService;
import org.linlinjava.litemall.core.util.JacksonUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.wx.dao.WxLoginInfo;
import org.linlinjava.litemall.wx.dao.UserInfo; import org.linlinjava.litemall.wx.dao.UserInfo;
import org.linlinjava.litemall.wx.dao.UserToken; import org.linlinjava.litemall.wx.dao.UserToken;
import org.linlinjava.litemall.wx.dao.WxLoginInfo;
import org.linlinjava.litemall.wx.service.CaptchaCodeManager;
import org.linlinjava.litemall.wx.service.UserTokenManager; import org.linlinjava.litemall.wx.service.UserTokenManager;
import org.linlinjava.litemall.wx.util.IpUtil; import org.linlinjava.litemall.wx.util.IpUtil;
import org.linlinjava.litemall.core.util.bcrypt.BCryptPasswordEncoder;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
...@@ -39,47 +44,48 @@ public class WxAuthController { ...@@ -39,47 +44,48 @@ public class WxAuthController {
@Autowired @Autowired
private WxMaService wxService; private WxMaService wxService;
@Autowired
private NotifyService notifyService;
/** /**
* 账号登录 * 账号登录
* *
* @param body 请求内容,{ username: xxx, password: xxx } * @param body 请求内容,{ username: xxx, password: xxx }
* @param request 请求对象 * @param request 请求对象
* @return 登录结果 * @return 登录结果
* 成功则 * 成功则
* { * {
* errno: 0, * errno: 0,
* errmsg: '成功', * errmsg: '成功',
* data: * data:
* { * {
* token: xxx, * token: xxx,
* tokenExpire: xxx, * tokenExpire: xxx,
* userInfo: xxx * userInfo: xxx
* } * }
* } * }
* 失败则 { errno: XXX, errmsg: XXX } * 失败则 { errno: XXX, errmsg: XXX }
*/ */
@RequestMapping("login") @RequestMapping("login")
public Object login(@RequestBody String body, HttpServletRequest request) { public Object login(@RequestBody String body, HttpServletRequest request) {
String username = JacksonUtil.parseString(body, "username"); String username = JacksonUtil.parseString(body, "username");
String password = JacksonUtil.parseString(body, "password"); String password = JacksonUtil.parseString(body, "password");
if(username == null || password == null){ if (username == null || password == null) {
return ResponseUtil.badArgument(); return ResponseUtil.badArgument();
} }
List<LitemallUser> userList =userService.queryByUsername(username); List<LitemallUser> userList = userService.queryByUsername(username);
LitemallUser user = null; LitemallUser user = null;
if(userList.size() > 1){ if (userList.size() > 1) {
return ResponseUtil.serious(); return ResponseUtil.serious();
} } else if (userList.size() == 0) {
else if(userList.size() == 0){
return ResponseUtil.badArgumentValue(); return ResponseUtil.badArgumentValue();
} } else {
else {
user = userList.get(0); user = userList.get(0);
} }
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
if(!encoder.matches(password, user.getPassword())){ if (!encoder.matches(password, user.getPassword())) {
return ResponseUtil.fail(403, "账号密码不对"); return ResponseUtil.fail(403, "账号密码不对");
} }
...@@ -102,26 +108,26 @@ public class WxAuthController { ...@@ -102,26 +108,26 @@ public class WxAuthController {
* 微信登录 * 微信登录
* *
* @param wxLoginInfo 请求内容,{ code: xxx, userInfo: xxx } * @param wxLoginInfo 请求内容,{ code: xxx, userInfo: xxx }
* @param request 请求对象 * @param request 请求对象
* @return 登录结果 * @return 登录结果
* 成功则 * 成功则
* { * {
* errno: 0, * errno: 0,
* errmsg: '成功', * errmsg: '成功',
* data: * data:
* { * {
* token: xxx, * token: xxx,
* tokenExpire: xxx, * tokenExpire: xxx,
* userInfo: xxx * userInfo: xxx
* } * }
* } * }
* 失败则 { errno: XXX, errmsg: XXX } * 失败则 { errno: XXX, errmsg: XXX }
*/ */
@RequestMapping("login_by_weixin") @RequestMapping("login_by_weixin")
public Object loginByWeixin(@RequestBody WxLoginInfo wxLoginInfo, HttpServletRequest request) { public Object loginByWeixin(@RequestBody WxLoginInfo wxLoginInfo, HttpServletRequest request) {
String code = wxLoginInfo.getCode(); String code = wxLoginInfo.getCode();
UserInfo userInfo = wxLoginInfo.getUserInfo(); UserInfo userInfo = wxLoginInfo.getUserInfo();
if(code == null || userInfo == null){ if (code == null || userInfo == null) {
return ResponseUtil.badArgument(); return ResponseUtil.badArgument();
} }
...@@ -135,12 +141,12 @@ public class WxAuthController { ...@@ -135,12 +141,12 @@ public class WxAuthController {
e.printStackTrace(); e.printStackTrace();
} }
if(sessionKey == null || openId == null){ if (sessionKey == null || openId == null) {
return ResponseUtil.fail(); return ResponseUtil.fail();
} }
LitemallUser user = userService.queryByOid(openId); LitemallUser user = userService.queryByOid(openId);
if(user == null){ if (user == null) {
user = new LitemallUser(); user = new LitemallUser();
user.setUsername(userInfo.getNickName()); // 其实没有用,因为用户没有真正注册 user.setUsername(userInfo.getNickName()); // 其实没有用,因为用户没有真正注册
user.setPassword(openId); // 其实没有用,因为用户没有真正注册 user.setPassword(openId); // 其实没有用,因为用户没有真正注册
...@@ -148,15 +154,14 @@ public class WxAuthController { ...@@ -148,15 +154,14 @@ public class WxAuthController {
user.setAvatar(userInfo.getAvatarUrl()); user.setAvatar(userInfo.getAvatarUrl());
user.setNickname(userInfo.getNickName()); user.setNickname(userInfo.getNickName());
user.setGender(userInfo.getGender()); user.setGender(userInfo.getGender());
user.setUserLevel((byte)0); user.setUserLevel((byte) 0);
user.setStatus((byte)0); user.setStatus((byte) 0);
user.setLastLoginTime(LocalDateTime.now()); user.setLastLoginTime(LocalDateTime.now());
user.setLastLoginIp(IpUtil.client(request)); user.setLastLoginIp(IpUtil.client(request));
user.setAddTime(LocalDateTime.now()); user.setAddTime(LocalDateTime.now());
userService.add(user); userService.add(user);
} } else {
else{
user.setLastLoginTime(LocalDateTime.now()); user.setLastLoginTime(LocalDateTime.now());
user.setLastLoginIp(IpUtil.client(request)); user.setLastLoginIp(IpUtil.client(request));
userService.update(user); userService.update(user);
...@@ -172,31 +177,49 @@ public class WxAuthController { ...@@ -172,31 +177,49 @@ public class WxAuthController {
return ResponseUtil.ok(result); return ResponseUtil.ok(result);
} }
/**
* 请求验证码
*
* @param body 手机号码{mobile}
* @return
*/
@PostMapping("regCaptcha")
public Object registerCaptcha(@RequestBody String body) {
String phoneNumber = JacksonUtil.parseString(body, "mobile");
String code = CharUtil.getRandomNum(6);
notifyService.notifySmsTemplateSync(phoneNumber, NotifyType.CAPTCHA, new String[]{code});
boolean successful = CaptchaCodeManager.addToCache(phoneNumber, code);
return successful ? ResponseUtil.ok() : ResponseUtil.badArgument();
}
/** /**
* 账号注册 * 账号注册
* *
* @param body 请求内容 * @param body 请求内容
* { * {
* username: xxx, * username: xxx,
* password: xxx, * password: xxx,
* mobile: xxx * mobile: xxx
* code: xxx * code: xxx
* } * }
* 其中code是手机验证码,目前还不支持手机短信验证码 * 其中code是手机验证码,目前还不支持手机短信验证码
* @param request 请求对象 * @param request 请求对象
* @return 登录结果 * @return 登录结果
* 成功则 * 成功则
* { * {
* errno: 0, * errno: 0,
* errmsg: '成功', * errmsg: '成功',
* data: * data:
* { * {
* token: xxx, * token: xxx,
* tokenExpire: xxx, * tokenExpire: xxx,
* userInfo: xxx * userInfo: xxx
* } * }
* } * }
* 失败则 { errno: XXX, errmsg: XXX } * 失败则 { errno: XXX, errmsg: XXX }
*/ */
@PostMapping("register") @PostMapping("register")
public Object register(@RequestBody String body, HttpServletRequest request) { public Object register(@RequestBody String body, HttpServletRequest request) {
...@@ -205,22 +228,27 @@ public class WxAuthController { ...@@ -205,22 +228,27 @@ public class WxAuthController {
String mobile = JacksonUtil.parseString(body, "mobile"); String mobile = JacksonUtil.parseString(body, "mobile");
String code = JacksonUtil.parseString(body, "code"); String code = JacksonUtil.parseString(body, "code");
if(username == null || password == null || mobile == null || code == null){ if (username == null || password == null || mobile == null || code == null) {
return ResponseUtil.badArgument(); return ResponseUtil.badArgument();
} }
List<LitemallUser> userList = userService.queryByUsername(username); List<LitemallUser> userList = userService.queryByUsername(username);
if(userList.size() > 0){ if (userList.size() > 0) {
return ResponseUtil.fail(403, "用户名已注册"); return ResponseUtil.fail(403, "用户名已注册");
} }
userList = userService.queryByMobile(mobile); userList = userService.queryByMobile(mobile);
if(userList.size() > 0){ if (userList.size() > 0) {
return ResponseUtil.fail(403, "手机号已注册"); return ResponseUtil.fail(403, "手机号已注册");
} }
if(!RegexUtil.isMobileExact(mobile)){ if (!RegexUtil.isMobileExact(mobile)) {
return ResponseUtil.fail(403, "手机号格式不正确"); return ResponseUtil.fail(403, "手机号格式不正确");
} }
//判断验证码是否正确
String cacheCode = CaptchaCodeManager.getCachedCaptcha(mobile);
if (cacheCode == null || cacheCode.isEmpty() || !cacheCode.equals(code))
return ResponseUtil.fail(403, "验证码错误");
LitemallUser user = new LitemallUser(); LitemallUser user = new LitemallUser();
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
...@@ -234,9 +262,9 @@ public class WxAuthController { ...@@ -234,9 +262,9 @@ public class WxAuthController {
user.setWeixinOpenid(""); user.setWeixinOpenid("");
user.setAvatar("https://yanxuan.nosdn.127.net/80841d741d7fa3073e0ae27bf487339f.jpg?imageView&quality=90&thumbnail=64x64"); user.setAvatar("https://yanxuan.nosdn.127.net/80841d741d7fa3073e0ae27bf487339f.jpg?imageView&quality=90&thumbnail=64x64");
user.setNickname(username); user.setNickname(username);
user.setGender((byte)0); user.setGender((byte) 0);
user.setUserLevel((byte)0); user.setUserLevel((byte) 0);
user.setStatus((byte)0); user.setStatus((byte) 0);
user.setLastLoginTime(LocalDateTime.now()); user.setLastLoginTime(LocalDateTime.now());
user.setLastLoginIp(IpUtil.client(request)); user.setLastLoginIp(IpUtil.client(request));
user.setAddTime(LocalDateTime.now()); user.setAddTime(LocalDateTime.now());
...@@ -261,17 +289,17 @@ public class WxAuthController { ...@@ -261,17 +289,17 @@ public class WxAuthController {
/** /**
* 账号密码重置 * 账号密码重置
* *
* @param body 请求内容 * @param body 请求内容
* { * {
* password: xxx, * password: xxx,
* mobile: xxx * mobile: xxx
* code: xxx * code: xxx
* } * }
* 其中code是手机验证码,目前还不支持手机短信验证码 * 其中code是手机验证码,目前还不支持手机短信验证码
* @param request 请求对象 * @param request 请求对象
* @return 登录结果 * @return 登录结果
* 成功则 { errno: 0, errmsg: '成功' } * 成功则 { errno: 0, errmsg: '成功' }
* 失败则 { errno: XXX, errmsg: XXX } * 失败则 { errno: XXX, errmsg: XXX }
*/ */
@PostMapping("reset") @PostMapping("reset")
public Object reset(@RequestBody String body, HttpServletRequest request) { public Object reset(@RequestBody String body, HttpServletRequest request) {
...@@ -279,22 +307,26 @@ public class WxAuthController { ...@@ -279,22 +307,26 @@ public class WxAuthController {
String mobile = JacksonUtil.parseString(body, "mobile"); String mobile = JacksonUtil.parseString(body, "mobile");
String code = JacksonUtil.parseString(body, "code"); String code = JacksonUtil.parseString(body, "code");
if(mobile == null || code == null || password == null){ if (mobile == null || code == null || password == null) {
return ResponseUtil.badArgument(); return ResponseUtil.badArgument();
} }
//判断验证码是否正确
String cacheCode = CaptchaCodeManager.getCachedCaptcha(mobile);
if (cacheCode == null || cacheCode.isEmpty() || !cacheCode.equals(code))
return ResponseUtil.fail(403, "验证码错误");
List<LitemallUser> userList = userService.queryByMobile(mobile); List<LitemallUser> userList = userService.queryByMobile(mobile);
LitemallUser user = null; LitemallUser user = null;
if(userList.size() > 1){ if (userList.size() > 1) {
return ResponseUtil.serious(); return ResponseUtil.serious();
} } else if (userList.size() == 0) {
else if(userList.size() == 0){
return ResponseUtil.fail(403, "手机号未注册"); return ResponseUtil.fail(403, "手机号未注册");
} } else {
else{
user = userList.get(0); user = userList.get(0);
} }
// TODO 重新生成的密码无法登陆
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String encodedPassword = encoder.encode(password); String encodedPassword = encoder.encode(password);
user.setPassword(encodedPassword); user.setPassword(encodedPassword);
......
...@@ -31,10 +31,32 @@ Page({ ...@@ -31,10 +31,32 @@ Page({
}, },
sendCode: function () { sendCode: function () {
wx.showModal({ let that = this;
title: '注意', wx.request({
content: '由于目前不支持手机短信发送,因此验证码任意值都可以', url: api.AuthRegisterCaptcha,
showCancel: false data: {
mobile: that.data.mobile
},
method: 'POST',
header: {
'content-type': 'application/json'
},
success: function (res) {
if (res.data.errno == 0) {
wx.showModal({
title: '发送成功',
content: '验证码已发送',
showCancel: false
});
}
else {
wx.showModal({
title: '错误信息',
content: res.data.errmsg,
showCancel: false
});
}
}
}); });
}, },
startRegister: function () { startRegister: function () {
......
...@@ -29,11 +29,34 @@ Page({ ...@@ -29,11 +29,34 @@ Page({
// 页面关闭 // 页面关闭
}, },
sendCode: function () { sendCode: function () {
wx.showModal({ let that = this;
title: '注意', wx.request({
content: '由于目前不支持手机短信发送,因此验证码任意值都可以', url: api.AuthRegisterCaptcha,
showCancel: false data: {
mobile: that.data.mobile
},
method: 'POST',
header: {
'content-type': 'application/json'
},
success: function (res) {
if (res.data.errno == 0) {
wx.showModal({
title: '发送成功',
content: '验证码已发送',
showCancel: false
});
}
else {
wx.showModal({
title: '错误信息',
content: res.data.errmsg,
showCancel: false
});
}
}
}); });
}, },
startReset: function(){ startReset: function(){
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment