iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >实战分布式医疗挂号系统登录接口整合阿里云短信详情
  • 144
分享到

实战分布式医疗挂号系统登录接口整合阿里云短信详情

2024-04-02 19:04:59 144人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

目录前言步骤1:搭建service-user用户模块1.启动类&配置网关2.三层调用步骤2:整合Jwt步骤3: 搭建service-msm短信模块(整合阿里云短信)1.启动类

前言

短信接口

本篇文章完成的需求:

1,登录采取弹出层的形式。

2,登录方式:

  • (1)手机号码+手机验证码
  • (2)微信扫描(后文完成)

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

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

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

步骤1:搭建service-user用户模块

1.启动类&配置网关

搭建service-user模块用来做用户登录,其中:

使用@EnableDiscoveryClient注解将服务注册到Nacos

使用@EnableFeignClients(basePackages = "com.gql")注解开启远程服务调用。

使用@ComponentScan(basePackages = "com.gql")注解开启swagger扫描。

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

网关配置:由于项目使用Gateway作为网关,现在添加了用户模块,需要在gateway模块的配置文件中加上网关配置:

# 设置路由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=msm
    public static ArrayList getRandom(List list, int n) {
        Random random = new Random();
        HashMap<Object, Object> hashMap = new HashMap<Object, Object>();
        // 生成随机数字并存入HashMap
        for (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;
    }
}

4.三层调用

Controller层的sendCode(@PathVariable String phone) 方法直接调用RedisTemplate获取生成的验证码,然后调用Service层的send(phone, code)方法通过阿里云发送手机验证码。

@RestController
@RequestMapping("/api/msm")
public class MsmApiController {
    @Autowired
    private MsmService msmService;
    @Autowired
    private RedisTemplate<String, String> 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();
        }
        // 如果获取不到,生成6位验证码
        code = RandomUtil.getSixBitRandom();
        // 偷偷打印到控制台
        System.out.println(code);
        // 调用service返回,通过整合短信服务进行发送
        boolean isSend = msmService.send(phone, code);
        // 将生成的验证码放入redis中,并设置有效时间
        if (isSend) {
            // 验证码超过1分钟失效
            redisTemplate.opsForValue().set(phone, code, 1, TimeUnit.MINUTES);
            return Result.ok();
        } else {
            return Result.fail().message("发送短信失败");
        }
    }
}

Service层发送手机验证码:

@Service
public class MsmServiceImpl implements MsmService {
    // 发送手机验证码
    @Override
    public 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();
        // 如果是https方式就需要设置↓
        //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", "袋鼠佳日");
        //模板code
        request.putQueryParameter("TemplateCode", "SMS_215315088");
        //验证码  使用JSON格式   {"code":"123456"}
        Map<String, Object> 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;
    }
}

步骤4:登录页面前端

1.封装api请求

创建api文件夹,创建/api/userInfo.js、/api/msm.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
        })
    }
}
import request from '@/utils/request'
const api_name = `/api/msm`
export default {
    sendCode(mobile) {
        return request({
            url: `${api_name}/send/${mobile}`,
            method: `get`
        })
    }
}

2.添加登录组件

登录成功后,我们需要把用户信息记录在cookie里面,所以在vscode的命令行执行:npm install js-cookie。

登录弹窗组件是一个公共层,因此我们把它放在头部组件里面,修改layouts/myheader.Vue文件:具体代码点击这里查看仓库。

3.登录全局事件

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

在预约挂号页面,选择科室去挂号时我们需要判断当前是否登录,如果登录可以进入下一个页面;如果没有登录需要显示登录层。我们可以注册一个全局登录事件,当需要登录层时,我们发送一个登录事件,头部监听登录事件,然后我们触发登录按钮的点击事件即可打开登录层。

头部注册和监听登录事件,修改myheader.vue组件:

①.引入vue

import Vue from 'vue'

②注册与监听事件

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

预约挂号页面调整,修改/pages/hospital/_hoscode.vue组件:

①引入cookie

import cookie from 'js-cookie'

②修改方法

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

附加:用户认证与网关整合

思路:

所有请求都会经过服务网关,服务网关对外暴露服务,在网关进行统一用户认证;既然要在网关进行用户认证,网关需要知道对哪些url进行认证,所以我们得对ur制定规则。Api接口异步请求的,我们采取url规则匹配,如:/api//auth/,凡是满足该规则的都必须用户认证。

因此,我们需要对server-gateway模块进行调整。

1.在服务网关添加fillter

@Override
    public Mono<Void> filter(ServerWEBExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getURI().getPath();
        System.out.println("===" + path);
        //内部服务接口,不允许外部访问
        if (antPathMatcher.match("innerauth/**", path)) {
            Long userId = this.getUserId(request);
            if (StringUtils.isEmpty(userId)) {
                ServerHttpResponse response = exchange.getResponse();
                return out(response, ResultCodeEnum.LOGIN_AUTH);
            }
        }
        return chain.filter(exchange);
    }

网站网关filter代码详见仓库。

2.调整前端代码

请求服务器端接口时我们默认带上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:9000',
    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 => {
        if (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

至此,已经将阿里云短信整合到项目中,更多关于分布式医疗挂号系统登录接口整合阿里云短信的资料请关注编程网其它相关文章!

--结束END--

本文标题: 实战分布式医疗挂号系统登录接口整合阿里云短信详情

本文链接: https://www.lsjlt.com/news/147272.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作