尚医通 (三十一) --------- 手机登录
创始人
2024-03-29 03:57:52
0

目录

  • 一、登录需求
    • 1. 登录效果
    • 2. 登录需求
  • 二、登录
    • 1. 搭建 service-user 模块
    • 2. 添加用户基础类
    • 3. 登录 API 接口
    • 4. 生成 token
    • 5. 阿里云短信
    • 6. 登录前端
    • 7. 登录全局事件
    • 8. myheader.vue 完整代码
  • 三、用户认证与网关整合


一、登录需求

1. 登录效果

在这里插入图片描述

2. 登录需求

① 登录采取弹出层的形式

② 登录方式:

  • 手机号码+手机验证码
  • 微信扫描

③ 无注册界面,第一次登录根据手机号判断系统是否存在,如果不存在则自动注册

④ 微信扫描登录成功必须绑定手机号码,即 :第一次扫描成功后绑定手机号,以后登录扫描直接登录成功

⑤ 网关统一判断登录状态,如何需要登录,页面弹出登录层

二、登录

1. 搭建 service-user 模块

① 搭建 service-user 模块

搭建过程参考service-hosp模块

在这里插入图片描述

② 修改配置

A、修改 pom.xml


servicecom.fancy.yygh1.04.0.0service-usercom.fancy.yyghservice-cmn-client1.0

B、添加配置文件 application.properties

# 服务端口
server.port=8203
# 服务名
spring.application.name=service-user# 环境设置:dev、test、prod
spring.profiles.active=dev# mysql数据库连接
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.38.130:3306/yygh_user?characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=root#返回json的全局时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8# nacos服务地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848#配置mapper xml文件的路径
# 服务端口
server.port=8203
# 服务名
spring.application.name=service-user# 环境设置:dev、test、prod
spring.profiles.active=dev# mysql数据库连接
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.38.130:3306/yygh_user?characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=root#返回json的全局时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8# nacos服务地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848#配置mapper xml文件的路径
mybatis-plus.mapper-locations=classpath:mapper/*.xml

C、启动类

@SpringBootApplication
@ComponentScan(basePackages = "com.fancy.yygh")
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "com.fancy.yygh")
public class ServiceUserApplication {public static void main(String[] args) {SpringApplication.run(ServiceUserApplication.class, args);}
}

D、配置网关

#设置路由id
spring.cloud.gateway.routes[2].id=service-user
#设置路由的uri
spring.cloud.gateway.routes[2].uri=lb://service-user
#设置路由断言,代理servicerId为auth-service的/auth/路径
spring.cloud.gateway.routes[2].predicates= Path=/*/user/**

2. 添加用户基础类

① 添加 model

说明:由于实体对象没有逻辑,我们已经统一导入com.fancy.yygh.model.user.UserInfo

在这里插入图片描述

在这里插入图片描述

② 添加 Mapper

添加 com.fancy.yygh.user.UserInfoMapper

import com.fancy.yygh.model.user.UserInfo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;public interface UserInfoMapper extends BaseMapper {
}

在这里插入图片描述

添加 UserInfoMapper.xml




③ 添加 service 接口及实现类

添加 com.fancy.yygh.user.service.UserInfoService 接口

public interface UserInfoService extends IService {
}

添加 com.fancy.yygh.user.service.impl.UserInfoServiceImpl 接口实现

@Service
public class UserInfoServiceImpl extends ServiceImpl implements UserInfoService {
}

在这里插入图片描述

④ 添加 controller

添加 com.fancy.yygh.user.api.UserInfoApiController 类

@RestController
@RequestMapping("/api/user")
public class UserInfoApiController {@Autowiredprivate UserInfoService userInfoService;
}

3. 登录 API 接口

① 添加 service 接口与实现

A、在 UserInfoService 类添加接口

//会员登录
Map login(LoginVo loginVo);

B、在 UserInfoServiceImpl 类实现接口

@Service
public class UserInfoServiceImpl extends ServiceImpl implements UserInfoService {@Overridepublic Map login(LoginVo loginVo) {String phone = loginVo.getPhone();String code = loginVo.getCode();//校验参数if(StringUtils.isEmpty(phone) ||StringUtils.isEmpty(code)) {throw new YyghException(ResultCodeEnum.PARAM_ERROR);}//TODO 校验校验验证码//手机号已被使用QueryWrapper queryWrapper = new QueryWrapper<>();queryWrapper.eq("phone", phone);//获取会员UserInfo userInfo = baseMapper.selectOne(queryWrapper);if(null == userInfo) {userInfo = new UserInfo();userInfo.setName("");userInfo.setPhone(phone);userInfo.setStatus(1);this.save(userInfo);}//校验是否被禁用if(userInfo.getStatus() == 0) {throw new YyghException(ResultCodeEnum.LOGIN_DISABLED_ERROR);}//TODO 记录登录//返回页面显示名称Map map = new HashMap<>();String name = userInfo.getName();if(StringUtils.isEmpty(name)) {name = userInfo.getNickName();}if(StringUtils.isEmpty(name)) {name = userInfo.getPhone();}map.put("name", name);map.put("token", "");return map;}
}

说明:

  • 验证码先注释,后续校验
  • 登录成功生成 token,后续讲解

② 添加 controller 接口

A、在 UserInfoApiController 类添加方法

@ApiOperation(value = "会员登录")
@PostMapping("login")
public Result login(@RequestBody LoginVo loginVo, HttpServletRequest request) {loginVo.setIp(IpUtil.getIpAddr(request));Map info = userInfoService.login(loginVo);return Result.ok(info);
}

B、添加 IpUtil 工具类

public class IpUtil {private static final String UNKNOWN = "unknown";private static final String LOCALHOST = "127.0.0.1";private static final String SEPARATOR = ",";public static String getIpAddr(HttpServletRequest request) {System.out.println(request);String ipAddress;try {ipAddress = request.getHeader("x-forwarded-for");if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("Proxy-Client-IP");}if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("WL-Proxy-Client-IP");}if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {ipAddress = request.getRemoteAddr();if (LOCALHOST.equals(ipAddress)) {InetAddress inet = null;try {inet = InetAddress.getLocalHost();} catch (UnknownHostException e) {e.printStackTrace();}ipAddress = inet.getHostAddress();}}// 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割// "***.***.***.***".length()if (ipAddress != null && ipAddress.length() >15) {if (ipAddress.indexOf(SEPARATOR) >0) {ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));}}} catch (Exception e) {ipAddress = "";}return ipAddress;}
}

4. 生成 token

① JWT介绍

JWT 工具:

JWT(Json Web Token)是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。

JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源。比如用在用户登录上

JWT最重要的作用就是对 token 信息的防伪作用。

JWT的原理:

一个JWT由三个部分组成:公共部分、私有部分、签名部分。最后由这三者组合进行 Base64 编码得到 JWT。

在这里插入图片描述
A、公共部分

主要是该JWT的相关配置参数,比如签名的加密算法、格式类型、过期时间等等。

Key=ATGUIGU

B、私有部分

用户自定义的内容,根据实际需要真正要封装的信息。

userInfo{用户的Id,用户的昵称nickName}

C、签名部分

SaltIP: 当前服务器的IP地址 !{linux 中配置代理服务器的ip}

主要用户对 JWT 生成字符串的时候,进行加密{盐值}
最终组成 key+salt+userInfo token!

Base64 编码,并不是加密,只是把明文信息变成了不可见的字符串。但是其实只要用一些工具就可以把 Base64 编码解成明文,所以不要在 JWT 中放入涉及私密的信息。

② 集成JWT

在 common-util 模块 pom.xml 添加依赖

io.jsonwebtokenjjwt

版本已在 yygh-parent 父模块 pom.xml 添加

在 common-util 模块编写 JwtHelper 类

public class JwtHelper {private static long tokenExpiration = 24*60*60*1000;private static String tokenSignKey = "123456";public static String createToken(Long userId, String userName) {String token = Jwts.builder().setSubject("YYGH-USER").setExpiration(new Date(System.currentTimeMillis() + tokenExpiration)).claim("userId", userId).claim("userName", userName).signWith(SignatureAlgorithm.HS512, tokenSignKey).compressWith(CompressionCodecs.GZIP).compact();return token;}public static Long getUserId(String token) {if(StringUtils.isEmpty(token)) return null;Jws claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);Claims claims = claimsJws.getBody();Integer userId = (Integer)claims.get("userId");return userId.longValue();}public static String getUserName(String token) {if(StringUtils.isEmpty(token)) return "";Jws claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);Claims claims = claimsJws.getBody();return (String)claims.get("userName");}public static void main(String[] args) {String token = JwtHelper.createToken(1L, "55");System.out.println(token);System.out.println(JwtHelper.getUserId(token));System.out.println(JwtHelper.getUserName(token));}
}

说明:执行 main 方法测试

③ 完善登录 service 接口

修改 UserInfoServiceImpl 类登录方法

public Map loginUser(LoginVo loginVo) {…………//jwt生成 token 字符串String token = JwtHelper.createToken(userInfo.getId(), name);map.put("token",token);return map;
}

④ 使用 Swagger 测试接口

测试多次,第一次注册,以后直接登录

请求参数:

在这里插入图片描述

5. 阿里云短信

① 阿里云短信介绍

在这里插入图片描述
A、开通阿里云短信服务

在这里插入图片描述
B、添加签名管理与模板管理

在这里插入图片描述
在这里插入图片描述

注:审批通过后方可使用

C、获取用户 AccessKey

在这里插入图片描述

② 搭建 service-msm 模块

A、搭建 service-msm 模块

搭建过程参考 service-hosp 模块

B、修改配置

修改 pom.xml

com.aliyunaliyun-java-sdk-core

添加配置文件 application.properties

# 服务端口
server.port=8204
# 服务名
spring.application.name=service-msm#返回json的全局时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8spring.redis.host=192.168.44.165
spring.redis.port=6379
spring.redis.database= 0
spring.redis.timeout=1800000
spring.redis.lettuce.pool.max-active=20
spring.redis.lettuce.pool.max-wait=-1
#最大阻塞等待时间(负数表示没限制)
spring.redis.lettuce.pool.max-idle=5
spring.redis.lettuce.pool.min-idle=0# nacos服务地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848aliyun.sms.regionId=default
aliyun.sms.accessKeyId=LT6I0Y5633pX89qC
aliyun.sms.secret=jX8D04Dm12I3gGKj345FYSzu0fq8mT

启动类

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)//取消数据源自动配置
@EnableDiscoveryClient
public class ServiceMsmApplication {public static void main(String[] args) {SpringApplication.run(ServiceMsmApplication.class, args);}
}

配置网关

#设置路由id
spring.cloud.gateway.routes[3].id=service-msm
#设置路由的uri
spring.cloud.gateway.routes[3].uri=lb://service-msm
#设置路由断言,代理servicerId为auth-service的/auth/路径
spring.cloud.gateway.routes[3].predicates= Path=/*/msm/**

③ 封装注册短信验证码接口

A、添加配置类

@Component
public class ConstantPropertiesUtils implements InitializingBean {@Value("${aliyun.sms.regionId}")private String regionId;@Value("${aliyun.sms.accessKeyId}")private String accessKeyId;@Value("${aliyun.sms.secret}")private String secret;public static String REGION_Id;public static String ACCESS_KEY_ID;public static String SECRECT;@Overridepublic void afterPropertiesSet() throws Exception {REGION_Id=regionId;ACCESS_KEY_ID=accessKeyId;SECRECT=secret;}
}

B、封装 service 接口和实现类

public interface MsmService {//发送手机验证码boolean send(String phone, String code);
}@Service
public class MsmServiceImpl implements MsmService {@Overridepublic boolean send(String phone, String code) {//判断手机号是否为空if(StringUtils.isEmpty(phone)) {return false;}//整合阿里云短信服务//设置相关参数DefaultProfile profile = DefaultProfile.getProfile(ConstantPropertiesUtils.REGION_Id, ConstantPropertiesUtils.ACCESS_KEY_ID, ConstantPropertiesUtils.SECRECT);IAcsClient client = new DefaultAcsClient(profile);CommonRequest request = new CommonRequest();//request.setProtocol(ProtocolType.HTTPS);request.setMethod(MethodType.POST);request.setDomain("dysmsapi.aliyuncs.com");request.setVersion("2017-05-25");request.setAction("SendSms");//手机号request.putQueryParameter("PhoneNumbers", phone);//签名名称request.putQueryParameter("SignName", "我的谷粒在线教育网站");//模板coderequest.putQueryParameter("TemplateCode", "SMS_180051135");//验证码  使用json格式   {"code":"123456"}Map param = new HashMap();param.put("code",code);request.putQueryParameter("TemplateParam", JSONObject.toJSONString(param));//调用方法进行短信发送try {CommonResponse response = client.getCommonResponse(request);System.out.println(response.getData());return response.getHttpResponse().isSuccess();} catch (ServerException e) {e.printStackTrace();} catch (ClientException e) {e.printStackTrace();}return false;}
}

C、封装 controller 接口

@RestController
@RequestMapping("/api/msm")
public class MsmApiController {@Autowiredprivate MsmService msmService;@Autowiredprivate RedisTemplate redisTemplate;//发送手机验证码@GetMapping("send/{phone}")public Result sendCode(@PathVariable String phone) {//从redis获取验证码,如果获取获取到,返回ok// key 手机号  value 验证码String code = redisTemplate.opsForValue().get(phone);if(!StringUtils.isEmpty(code)) {return Result.ok();}//如果从redis获取不到,// 生成验证码,code = RandomUtil.getSixBitRandom();//调用service方法,通过整合短信服务进行发送boolean isSend = msmService.send(phone,code);//生成验证码放到redis里面,设置有效时间if(isSend) {redisTemplate.opsForValue().set(phone,code,2, TimeUnit.MINUTES);return Result.ok();} else {return Result.fail().message("发送短信失败");}}
}

D、工具类

public class RandomUtil {private static final Random random = new Random();private static final DecimalFormat fourdf = new DecimalFormat("0000");private static final DecimalFormat sixdf = new DecimalFormat("000000");public static String getFourBitRandom() {return fourdf.format(random.nextInt(10000));}public static String getSixBitRandom() {return sixdf.format(random.nextInt(1000000));}/*** 给定数组,抽取n个数据* @param list* @param n* @return*/public static ArrayList getRandom(List list, int n) {Random random = new Random();HashMap hashMap = new HashMap();// 生成随机数字并存入HashMapfor (int i = 0; i < list.size(); i++) {int number = random.nextInt(100) + 1;hashMap.put(number, i);}// 从HashMap导入数组Object[] robjs = hashMap.values().toArray();ArrayList r = new ArrayList();// 遍历数组并打印数据for (int i = 0; i < n; i++) {r.add(list.get((int) robjs[i]));System.out.print(list.get((int) robjs[i]) + "\t");}System.out.print("\n");return r;}
}

E、完善登录 service 接口

修改 UserInfoServiceImpl 类登录方法,编写验证码校验

//校验校验验证码
String mobleCode = redisTemplate.opsForValue().get(phone);
if(!code.equals(mobleCode)) {throw new YyghException(ResultCodeEnum.CODE_ERROR);
}

6. 登录前端

① 封装 API 请求

创建 API 文件夹,创建 /api/userInfo.js

import request from '@/utils/request'const api_name = `/api/user`export default {login(userInfo) {return request({url: `${api_name}/login`,method: `post`,data: userInfo})}
}

创建 /api/msm.js

import request from '@/utils/request'const api_name = `/api/msm`export default {sendCode(mobile) {return request({url: `${api_name}/send/${mobile}`,method: `get`})}
}

② 安装 cookie

登录成功,我们要把用户信息记录在 cookie 里面

命令行执行:

npm install js-cookie

③ 添加登录组件

登录层是一个公共层,因此我们把它放在头部组件里面

修改 layouts/myheader.vue 文件

 
{{ dialogAtrr.labelTips }} 0">{{ dialogAtrr.second }}s 重新发送
{{ dialogAtrr.loginBtn }}
第三方账号登录
手机短信验证码登录
微信扫一扫关注
“快速预约挂号”
扫一扫下载
“预约挂号”APP
xxxxxx官方指定平台
快速挂号 安全放心

说明:登录成功用户信息记录cookie


④ 头部显示登录状态

A、获取登录信息

created() {this.showInfo()
},
showInfo() {let token = cookie.get('token')if (token) {this.name = cookie.get('name')}
},

B、登录页面控制


帮助中心登录/注册{{name}}实名认证挂号订单就诊人管理退出登录

说明:实名认证 command 的值为下拉列表的访问路径,即:实名认证的访问路径,后续会有对应的页面,目前我们将它处理好,方便后续使用

添加下拉列表事件处理:

loginMenu(command) {if('/logout' == command) {cookie.set('name', '', {domain: 'localhost'})cookie.set('token', '', {domain: 'localhost'})//跳转页面window.location.href = '/'} else {window.location.href = command}
},

7. 登录全局事件

目前登录层在 myheader 组件里面,登录按钮也在同一个组件里面,我们点击登录,调用 showLogin() 方法即可。

目前的问题是,我们在预约挂号页面,选择科室去挂号时我们需要判断当前是否登录,如果登录可以进入下一个页面;如果没有登录需要显示登录层,那么这个问题怎么解决呢,我们不能直接调用头部登录方法,我们目前的组件是包含在nuxt里面的问题总是能够解决的,其实很简单,我们可以注册一个全局登录事件,当需要登录层是,我们发送一个登录事件,头部监听登录事件,然后我们触发登录按钮的点击事件即可打开登录层,下面我们来试试。

① 头部注册和监听登录事件

修改 myheader.vue 组件

A、引入Vue

import Vue from 'vue'

B、注册与监听事件

mounted() {// 注册全局登录事件对象window.loginEvent = new Vue();// 监听登录事件loginEvent.$on('loginDialogEvent', function () {document.getElementById("loginDialog").click();})
// 触发事件,显示登录层:loginEvent.$emit('loginDialogEvent')
}

② 预约挂号页面调整

修改 /pages/hospital/_hoscode.vue 组件

A、引入cookie

import cookie from 'js-cookie'

B、修改方法

schedule(depcode) {// 登录判断let token = cookie.get('token')if (!token) {loginEvent.$emit('loginDialogEvent')return}window.location.href = '/hospital/schedule?hoscode=' + this.hospital.hoscode + "&depcode="+ depcode
},

说明:清除 cookie,点击科室测试

8. myheader.vue 完整代码



三、用户认证与网关整合

思路:

  • 所有请求都会经过服务网关,服务网关对外暴露服务,在网关进行统一用户认证

  • 既然要在网关进行用户认证,网关得知道对哪些 url 进行认证,所以我们得对ur制定规则

  • API 接口异步请求的,我们采取 url 规则匹配,如:/api/**/auth/**,如凡是满足该规则的都必须用户认证

① 调整 server-gateway 模块

A、在服务网关添加 fillter

@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpRequest request = exchange.getRequest();String path = request.getURI().getPath();System.out.println("==="+path);//内部服务接口,不允许外部访问if(antPathMatcher.match("/**/inner/**", path)) {ServerHttpResponse response = exchange.getResponse();return out(response, ResultCodeEnum.PERMISSION);}Long userId = this.getUserId(request);//api接口,异步请求,校验用户必须登录if(antPathMatcher.match("/api/**/auth/**", path)) {if(StringUtils.isEmpty(userId)) {ServerHttpResponse response = exchange.getResponse();return out(response, ResultCodeEnum.LOGIN_AUTH);}}return chain.filter(exchange);
}

B、在服务网关中判断用户登录状态

在网关中如何获取用户信息:

我们统一从 header 头信息中获取

如何判断用户信息合法:

登录时我们返回用户 token,在服务网关中获取到 token 后,我在到 redis 中去查看用户 id,如何用户 id 存在,则 token 合法,否则不合法

C、取用户信息

/*** 获取当前登录用户id* @param request* @return*/
private Long getUserId(ServerHttpRequest request) {String token = "";List tokenList = request.getHeaders().get("token");if(null  != tokenList) {token = tokenList.get(0);}if(!StringUtils.isEmpty(token)) {return JwtHelper.getUserId(token);}return null;
}

D、网关 filter 完整代码

/*** 

* 全局Filter,统一处理会员登录与外部不允许访问的服务*

*/ @Component public class AuthGlobalFilter implements GlobalFilter, Ordered {private AntPathMatcher antPathMatcher = new AntPathMatcher();@Overridepublic Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpRequest request = exchange.getRequest();String path = request.getURI().getPath();System.out.println("==="+path);//内部服务接口,不允许外部访问if(antPathMatcher.match("/**/inner/**", path)) {ServerHttpResponse response = exchange.getResponse();return out(response, ResultCodeEnum.PERMISSION);}Long userId = this.getUserId(request);//api接口,异步请求,校验用户必须登录if(antPathMatcher.match("/api/**/auth/**", path)) {if(StringUtils.isEmpty(userId)) {ServerHttpResponse response = exchange.getResponse();return out(response, ResultCodeEnum.LOGIN_AUTH);}}return chain.filter(exchange);}@Overridepublic int getOrder() {return 0;}/*** api接口鉴权失败返回数据* @param response* @return*/private Mono out(ServerHttpResponse response, ResultCodeEnum resultCodeEnum) {Result result = Result.build(null, resultCodeEnum);byte[] bits = JSONObject.toJSONString(result).getBytes(StandardCharsets.UTF_8);DataBuffer buffer = response.bufferFactory().wrap(bits);//指定编码,否则在浏览器中会中文乱码response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");return response.writeWith(Mono.just(buffer));}/*** 获取当前登录用户id* @param request* @return*/private Long getUserId(ServerHttpRequest request) {String token = "";List tokenList = request.getHeaders().get("token");if(null != tokenList) {token = tokenList.get(0);}if(!StringUtils.isEmpty(token)) {return JwtHelper.getUserId(token);}return null;} }

② 调整前端 yygh-site

请求服务器端接口时我们默认带上 token,需要登录的接口如果 token 没有或者token 过期,服务器端会返回 208 状态,然后发送登录事件打开登录弹出层登录
修改 utils/request.js 文件

import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
import cookie from 'js-cookie'// 创建axios实例
const service = axios.create({baseURL: 'http://localhost',timeout: 15000 // 请求超时时间
})
// http request 拦截器
service.interceptors.request.use(config => {// token 先不处理,后续使用时在完善//判断cookie是否有token值if(cookie.get('token')) {//token值放到cookie里面config.headers['token']=cookie.get('token')}return config
},err => {return Promise.reject(err)
})
// http response 拦截器
service.interceptors.response.use(response => {//状态码是208if(response.data.code === 208) {//弹出登录输入框loginEvent.$emit('loginDialogEvent')return} else {if (response.data.code !== 200) {Message({message: response.data.message,type: 'error',duration: 5 * 1000})return Promise.reject(response.data)} else {return response.data}}},error => {return Promise.reject(error.response)
})
export default service

相关内容

热门资讯

7亿元“互诉”大戏上演!大金重... 12月28日,大金重工(002487)发布关于诉讼事项的进展公告,一场与中国葛洲坝集团电力有限责任公...
50余位法律人晨跑椰城 共话专... 人民网海口12月28日电 (记者李学山)12月27日清晨7时30分,海口红城湖畔晨雾缭绕,随着一声“...
男子因纠纷引燃易燃物品致本人死... 12月28日,成都市公安局高新区分局发布警情通报: 12月28日下午,高新区南三环路四段一汽车销售服...
茅台称尽最大努力防止价格炒作,... 备受关注的茅台2026年全国经销商联谊会于12月28日下午举行。2025年在经历了换帅,一年内飞天茅...
原创 清... 1911年10月10日晚,武昌城头的枪声划破夜空。起义军用的两众枪,是从湖北新军军械库里抢来的;而对...
无锡律师行业前景与老律师经验传... 在无锡、常州、苏州、镇江、南通等地,律师行业正展现出蓬勃的发展态势,无锡律师行业前景更是备受瞩目。随...
南京市廉政文化研究会应邀赴西安... 扬子晚报网12月28日讯(通讯员 杨雅舒 邵加宝 记者 闫春旭)12月28日,由陕西省廉政文化研究会...
北京放宽购房门槛,优化住房信贷...   为更好满足居民刚性和多样化改善性住房需求,北京进一步优化调整房地产相关政策。   12月24日,...
刘百奇:政策与市场双轮驱动——... 12月28日,由创业黑马主办的“第17届创业家年会”在北京举办,年会主题为“智业革命 —— 跨越断层...
原创 郑... 自从被曝与前夫张恒在国外合开代孕机构之后,郑爽突然又活跃了起来,舆论都过去了,以郑爽名义成立的几个账...