B070-项目实战-用户模块--手机注册

目录

      • 用户模块需求分析
      • 静态网站部署与调试
        • 两种前端项目的部署
        • 两种前端项目的调试(热部署)
        • 创建静态web项目
      • 注册分析与设计
        • 分析需求
        • 设计 界面设计(ui)设计表(后台) 流程设计(后台)
          • 三范式
          • 表设计
          • 流程设计
        • 相关技术准备
          • 1.随机字符串(用StrUtils工具类)
          • 2.springdata-redis
          • 3.Md5技术
          • 4.短信接口
      • 发送短信验证码
        • 前端页面准备
        • 发送短信后台
          • 搭建用户模块
          • 单独写公共可用的发短信接口
            • VerifycodeController
            • VerifycodeServiceImpl

用户模块需求分析

用户注册
  登录信息
  基本信息
  安全信息
用户登录
  账号登录
  扫码登录-自己app扫描页面
  三方登录-使用三方app(微信,qq,支付宝等)
  验证码登录-自己做  reids.set(logincode+phone,xxx)
用户管理
地址管理
收藏
   商品收藏
   店铺收藏
   服务收藏
   宠物收藏
   。。。。
足迹
   。。。。

静态网站部署与调试

两种前端项目的部署

vue-cli项目:pethome-admin(管理员的管理界面),用npm打包成静态项目后丢进Tomcat服务器跑
Css+div项目:pethome_web(用户访问门户网站),本身是静态项目可以直接丢进Tomcat服务器跑

两种前端项目的调试(热部署)

vue-cli项目可以npm run dev启动调试
传统静态项目需要安装 live-server服务器来调试,这个服务器很简单就是node的一个模块,
全局安装:npm install -g live-server,运行:live-server --port=80

创建静态web项目

拷贝amz_02_adp的two里项目资源到pethome-web目录下
复制home3.html到pethome-web根目录并改名为index.html作为首页
修改css和js引用路径

进入web子项目
全局安装:npm install -g live-server
启动调试:live-server --port=80

替换images图片

注册分析与设计

分析需求

注册分为:邮箱注册,和手机号注册,逻辑都是一样的,只是激活方式不一样。

  手机号注册:
    1)输入手机号
    2)获取验证码并且输入
    3)输入蜜马和确认蜜马
    4)完成注册

设计 界面设计(ui)设计表(后台) 流程设计(后台)

三范式

1NF:列的原子性,不可再拆分
2NF:行唯一,
3NF:如果一张表的数据能够通过其他表推导出来,不应该单独设计,应该通过外键的方式关联查询出来。

反3NF:有的时候我们为了增强查询效率,会设计一些冗余字段,变多表查询为单表查询。

表设计

在这里插入图片描述
在这里插入图片描述
注意:以后只要在eployee或user操作时涉及到登录信息都要同步操作logininfo。比如添加员工也要在logininfo添加一条记录,注册用户也要在logininfo中添加。同理删除或修改也要同步。

流程设计

见文档

相关技术准备

1.随机字符串(用StrUtils工具类)
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * @author yaohuaipeng
 * @date 2018/10/26-16:16
 */
public class StrUtils {
    /**
     * 把逗号分隔的字符串转换字符串数组
     *
     * @param str
     * @return
     */
    public static String[] splitStr2StrArr(String str,String split) {
        if (str != null && !str.equals("")) {
            return str.split(split);
        }
        return null;
    }


    /**
     * 把逗号分隔字符串转换List的Long
     *
     * @param str
     * @return
     */
    public static List<Long> splitStr2LongArr(String str) {
        String[] strings = splitStr2StrArr(str,",");
        if (strings == null) return null;

        List<Long> result = new ArrayList<>();
        for (String string : strings) {
            result.add(Long.parseLong(string));
        }

        return result;
    }
    /**
     * 把逗号分隔字符串转换List的Long
     *
     * @param str
     * @return
     */
    public static List<Long> splitStr2LongArr(String str,String split) {
        String[] strings = splitStr2StrArr(str,split);
        if (strings == null) return null;

        List<Long> result = new ArrayList<>();
        for (String string : strings) {
            result.add(Long.parseLong(string));
        }

        return result;
    }

    public static String getRandomString(int length) {
        String str = "0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(10);
            sb.append(str.charAt(number));
        }
        return sb.toString();

    }

    // 26字母+10数字
    public static String getComplexRandomString(int length) {
        String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(62);
            sb.append(str.charAt(number));
        }
        return sb.toString();
    }

    public static String convertPropertiesToHtml(String properties){
        //1:容量:6:32GB_4:样式:12:塑料壳
        StringBuilder sBuilder = new StringBuilder();
        String[] propArr = properties.split("_");
        for (String props : propArr) {
            String[] valueArr = props.split(":");
            sBuilder.append(valueArr[1]).append(":").append(valueArr[3]).append("<br>");
        }
        return sBuilder.toString();
    }

}
2.springdata-redis

A 导入jar

<!--spirngboot springdata对redis支持-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

B 配置属性

spring:
  redis:
    database: 0
    host: 127.0.0.1
    port: 6379
    password: 123456
    jedis:
      pool:
        max-wait: 2000ms
        min-idle: 2
        max-idle: 8

启动redis服务:找到redis安装目录,cmd运行,redis-server.exe redis.windows.conf
C 编写测试类(基于springboot的测试类(继承BaseTest即可),用springdataredis提供的bean直接操作redis)

public class RedisTest extends BaseTest {
    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void test(){
        redisTemplate.opsForValue().set("ceshi", "搞一条数据");
        System.out.println(redisTemplate.opsForValue().get("ceshi"));

    }
}
3.Md5技术

不可逆加密技术,只能加密不能解密。 只能做比对,一般用来加密用户登录蜜马。
我们要做的是把传入的蜜马进行加密和然后数据库查询出来的密文进行比对判断蜜马是否正确。

盐值:同一种加密算法,由于不同的盐值,加密出来就不一样。
每个用户都有自己盐值,就算是相同的蜜马,两个用户加密出来的密文也不一样。

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Utils {

    /**
     * 加密
     * @param context  明文
     */
    public static String encrypByMd5(String context) {
        try {  
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(context.getBytes());//update处理
            byte [] encryContext = md.digest();//调用该方法完成计算

            int i;
            StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < encryContext.length; offset++) {//做相应的转化(十六进制)
                i = encryContext[offset];
                if (i < 0) i += 256;
                if (i < 16) buf.append("0");
                buf.append(Integer.toHexString(i));
            }
            return buf.toString();
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block  
            e.printStackTrace();
            return  null;
        }  
    }

    public static void main(String[] args) {

        //1.准备需要加密的蜜马
        String pwd = "1";
        //2 准备盐值
        String salt = StrUtils.getComplexRandomString(32);
        //2.加密  + 盐
        String pwdMd5 = MD5Utils.encrypByMd5(pwd + salt);
            // 将盐值和秘文存储到数据
        System.out.println(pwdMd5);

        //模拟登陆蜜马校验
        String pwdStr = pwd;
        String saltTem = salt;//相当于从数据库查询出来
        String pwdTmpMd5 = MD5Utils.encrypByMd5(pwdStr + saltTem);
        System.out.println("==="+pwdTmpMd5);
        if(pwdTmpMd5.equals(pwdMd5)){
            System.out.println("登陆成功");
        }else{
            System.out.println("蜜马错误");
        }

    }

}
4.短信接口

http://sms.webchinese.com.cn/Rates.shtml
用户信息修改,修改短信秘钥

导入依赖包

        <dependency>
            <groupId>commons-httpclient</groupId>
            <artifactId>commons-httpclient</artifactId>
            <version>3.1</version>
        </dependency>

代码应用(工具类 常量类)

	public static void sendsms(String phones, String message) throws IOException {
        HttpClient client = new HttpClient();
        PostMethod post = new PostMethod("https://utf8api.smschinese.cn/");
        post.addRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8");//在头文件中设置转码
        NameValuePair[] data ={ new NameValuePair("Uid", "mingfeng"),new NameValuePair("Key", "d41d8cd98f00b204e980"),new NameValuePair("smsMob",phones),new NameValuePair("smsText",message)};
        post.setRequestBody(data);

        client.executeMethod(post);
        Header[] headers = post.getResponseHeaders();
        int statusCode = post.getStatusCode();
        System.out.println("statusCode:"+statusCode); //HTTP状态码
        for(Header h : headers){
            System.out.println(h.toString());
        }
        String result = new String(post.getResponseBodyAsString().getBytes("utf-8"));
        System.out.println(result);  //打印返回消息状态

        post.releaseConnection();
    }

发送短信验证码

前端页面准备

1.拷贝register.html到根目录,更新引用路径

2.index.html设置在新标签页打开登录界面: target=“_blank”

	<div class="menu-hd">
		<a href="#" target="_top" class="h">亲,请登录</a>
		<a href="register.html" target="_blank">免费注册</a>
	</div>

	<div class="member-logout">
		<a class="am-btn-warning btn" href="login.html">登录</a>
		<a class="am-btn-warning btn" target="_blank" href="register.html">注册</a>
	</div>

3.静态项目引入js插件vue和axios
拷贝ph-admin\node_modules里的axios和vue到ph-web/js/plugin目录里并在register.html页面引入

        <!--引入vue和axios-->
		<script src="js/plugin/vue/dist/vue.min.js"></script>
		<script src="js/plugin/axios/dist/axios.js"></script>
		<!--全局使用-->
		<script src="js/common.js"></script>
		<!-- 局部使用
		<script type="text/javascript">
            //配置axios的全局基本路径
            /*axios.defaults.baseURL='/api' 前端解决跨域*/
            axios.defaults.baseURL='http://localhost:8080/'
            //全局属性配置,在任意组件内可以使用this.$http获取axios对象
            Vue.prototype.$http = axios
		</script>-->

在js目录下新建common.js

//配置axios的全局基本路径
/*axios.defaults.baseURL='/api' 前端解决跨域*/
axios.defaults.baseURL='http://localhost:8080/'
//全局属性配置,在任意组件内可以使用this.$http获取axios对象
Vue.prototype.$http = axios

绑定div节点

<div class="am-tab-panel" id="myDiv">

写vue.js

<script type="text/javascript">
	new Vue({
		el:"#myDiv",
		mounted(){
			alert(this.$http)
		}
	})
</script>

获取的a标签换为按钮(方便置灰和显示秒数倒计时),绑定方法

<!--<a class="btn" href="javascript:void(0);" οnclick="sendMobileCode();" id="sendMobileCode">
	<span id="dyMobileButton">获取</span></a>-->
<button type="button" @click="sendMobileCode">获取</button>
		methods:{
			sendMobileCode(){
				alert(123)
			}
		},

点击获取拿到手机号

<input type="tel" v-model="phoneUserForm.phone" name="" id="phone" placeholder="请输入手机号">
<script type="text/javascript">
	new Vue({
		el:"#myDiv",
		data:{
			phoneUserForm:{
				phone:18696148335
			}
		},
		methods:{
			sendMobileCode(){
				alert(this.registerForm.phone)
			}
		},
		mounted(){
			// alert(this.$http)
		}
	})
</script>
<script type="text/javascript">
	new Vue({
		el:"#myDiv",
		data:{
			phoneUserForm:{
				phone:""
			}
		},
		methods:{
			sendMobileCode(){
				//1.判断手机号不为空
				if(!this.phoneUserForm.phone){
					alert("手机号不能为空");
					return;
				}
				//2.获取按钮 禁用按钮 发送时灰化不能使用 发送成功倒计时60才能使用 如果发送失败立即可以发送
				var sendBtn = $(event.target);
				sendBtn.attr("disabled",true);
				this.$http.post('/verifycode/smsCode',
						{"phone":this.phoneUserForm.phone}).then((res) => {
					console.log(res);
					var ajaxResult = res.data;
					if(ajaxResult.success){
						alert("手机验证码已经发送到您的手机,请在3分钟内使用");
						//3.1.发送成:倒计时
						var time = 60;
						var interval = window.setInterval( function () {
							//每一条倒计时减一
							time = time - 1 ;
							//把倒计时时间搞到按钮上
							sendBtn.html(time);
							//3.2.倒计时完成恢复按钮
							if(time <= 0){
								sendBtn.html("重发");
								sendBtn.attr("disabled",false);
								//清除定时器
								window.clearInterval(interval);
							}
						},1000);
					}else{
						//3.3.发送失败:提示,恢复按钮
						sendBtn.attr("disabled",false);
						alert("发送失败:"+ajaxResult.message);
					}
				});
			}
		},
		mounted(){
			// alert(this.$http)
		}
	})
</script>

发送短信后台

搭建用户模块

User,loginInfo
搭建完模块后记得yml配置domain和query的扫描路径(别名)

单独写公共可用的发短信接口
VerifycodeController
@RestController
@RequestMapping("/verifycode")
public class VerifycodeController {
    @Autowired
    private IVerifycodeService verifycodeService;

    /**
     * 发送短信验证码
     * @param phone  给谁发送  只是允许传入一个手机号
     * @return
     */
    @PostMapping("/smsCode")
    public AjaxResult sendSmsCode(@RequestBody String phone){
        try {
            verifycodeService.sendSmsCode(phone);
            return AjaxResult.me();
        } catch (BusinessException e) {
            return AjaxResult.me().setMessage("发送失败!"+e.getMessage());
        }catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.me().setMessage("系统繁忙,稍后重试!!");
        }
    }
}
VerifycodeServiceImpl
		//1.校验
          //1.1手机号空校验
          //1.2不能被注册
        //2.判断是否存在验证码(从redis中获取电话对应的验证码)
        //2.1 存在
            //2.1.1 判断是否过了重发时间(1分钟)
                //2.1.1.1 如果没过重发时间。报错:请勿重复发送
                //2.1.1.2 如果过了,使用原来还没过期的验证码,刷新过期时间
        //2.2 不存在
           //2.2.1直接生成验证码
        //3 保存验证码到redis  设置过期时间
        //4 发送短信(使用工具类掉短信接口即可)
@Service
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS)
public class VerifycodeServiceImpl implements IVerifycodeService {
    @Autowired
    private IUserService userService;
    @Autowired
    private RedisTemplate redisTemplate;


    @Override
    public void sendSmsCode(String phone) {
        //1.校验
          //1.1手机号空校验
        if(!StringUtils.hasLength(phone)){
           throw new BusinessException("手机号不能为空!");
        }
          //1.2不能被注册
        User user = userService.loadUserByPhone(phone);
        if(user != null){
            throw new BusinessException("用户已经你存在!");
        }
        //2.判断是否存在验证码(从redis中获取电话对应的验证码)
        Object codeObj = redisTemplate.opsForValue().get(UserConstant.USER_VERFIY_CODE+":"+phone);
        String code = "";
        if(codeObj !=null){
            //2.1 存在
            String value =(String)codeObj;
            String timeStr = value.split(":")[1];//时间戳
            //2.1.1 判断是否过了重发时间(1分钟)
            if(System.currentTimeMillis()-Long.valueOf(timeStr) <= 1*60*1000){
                //2.1.1.1 如果没过重发时间。报错:请勿重复发送
                throw new BusinessException("请勿重复发送验证码!!!");
            }
            //2.1.1.2 如果过了,使用原来还没过期的验证码,刷新过期时间
            code = value.split(":")[0];//验证码
        }else{//2.2 不存在
            //2.2.1直接生成验证码
            code = StrUtils.getComplexRandomString(4);
        }
        //拼接存储验证码的格式
        String codeValue = code + ":" + System.currentTimeMillis();
        //3 保存验证码到redis  设置过期时间
        redisTemplate.opsForValue().set(UserConstant.USER_VERFIY_CODE+":"+phone, codeValue, 3, TimeUnit.MINUTES);
        //4 发送短信(使用工具类掉短信接口即可)
        /*SmsUtils.sendSms(phone, "您的验证码是:"+code+"; 请在3分钟内使用!");*/
        System.out.println("您的验证码是:"+code+"; 请在3分钟内使用!");
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/40471.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Appium+python自动化(十二)- Android UIAutomator终极定位凶器(超详解)

简介 乍眼一看&#xff0c;小伙伴们觉得这部分其实在异性兄弟那里就做过介绍和分享了&#xff0c;其实不然&#xff0c;上次介绍和分享的大哥是uiautomatorviewer&#xff0c;是一款定位工具。今天介绍的是一个java库&#xff0c;提供执行自动化测试的各种API。 Android团队在4…

SPSS中级统计--S05-5多个样本率的卡方检验及两两比较

小伙伴们&#xff0c;今天我们学习SPSS中级统计--多个样本率的卡方检验及两两比较。 例1、2 C列联表资料 上期我们学习了双向无序RC表资料&#xff08;c2&#xff09;的检验&#xff0c;案例如下&#xff0c;比较不同污染地区的动物畸形率是否有差异&#xff1f; H0&#xff…

旅游管理系统的设计与实现(论文+源码)_kaic

摘 要 旅游业走过了改革开放&#xff0c;到现在依旧蓬勃发展。但是放眼国际社会&#xff0c;我们在旅游业发展的深度和广度上所做的努力还远远不够。在中国&#xff0c;旅游业也将成为经济崛起中的重要一环。目前&#xff0c;我们生活在一个信息时代里。无论是工作&#xff0c;…

uniapp动态获取列表中每个下标的高度赋值给另一个数组(完整代码附效果图)

uniapp实现动态获取列表中每个下标的高度&#xff0c;赋值给另一个数组。 先看效果图&#xff1a; 完整代码&#xff1a; <template><div class""><div class"">我是A列表&#xff0c;我的高度不是固定的</div><div class&qu…

Docker使用总结

Docker 1.什么是 Docker 官网的介绍是“Docker is the world’s leading software container platform.” 官方给Docker的定位是一个应用容器平台。 Docker 是一个容器平台的领导者 Docker 容器平台 Docker 应用容器平台 application项目 Mysql Redis MongoDB ElasticSeacrh …

我国版式文档格式OFD前端WEB展示之EasyOFD

EasyOFD an ofd file web shower 一个在web端展示ofd文件的控件&#xff0c;该控件基于CANVAS绘制。 该控件使用了以下外部程序 1&#xff09;jszip&#xff1a;解决解压文件。 2&#xff09;x2js: 解决XML文件到JS转换 3&#xff09;easyjbig2: 解决ofd内部使用jb2文件存储的…

java项目之足球赛会管理系统(ssm+mysql+jsp)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的足球赛会管理系统。技术交流和部署相关看文章末尾&#xff01; 项目地址&#xff1a; https://download.csdn.net/download/sinat_26552841…

什么是渲染?一文看懂,萌新赶紧收藏码住!

十四五规划提出“加快数字化发展&#xff0c;建设数字中国”&#xff0c;数字技术的快速发展&#xff0c;从起初的内容创建到最终的效果呈现&#xff0c;都离不开渲染技术。目前&#xff0c;渲染技术被广泛应用于教育、医疗、影视动画、建筑设计等多个领域。它能有效满足用户对…

docker基础1——架构组成、安装配置

文章目录 一、发展起源1.1 传统虚拟化与容器虚拟化1.2 docker底层核心技术1.2.1 命名空间1.2.2 控制组 1.3 docker工作方式1.4 docker容器编排1.5 docker优劣势1.6 docker架构组成 二、yum安装docker三、配置docker加速器 一、发展起源 背景了解&#xff1a; 容器是内核里的一项…

【Python】PyCharm中调用另一个文件的函数或类

&#x1f389;欢迎来到Python专栏~PyCharm中调用另一个文件的函数或类 ☆* o(≧▽≦)o *☆嗨~我是小夏与酒&#x1f379; ✨博客主页&#xff1a;小夏与酒的博客 &#x1f388;该系列文章专栏&#xff1a;Python学习专栏 文章作者技术和水平有限&#xff0c;如果文中出现错误&…

Langchain-ChatGLM配置文件参数测试

1 已知可能影响对话效果的参数&#xff08;位于configs/model_config.py文件&#xff09;&#xff1a; # 文本分句长度 SENTENCE_SIZE 100# 匹配后单段上下文长度 CHUNK_SIZE 250 # 传入LLM的历史记录长度 LLM_HISTORY_LEN 3 # 知识库检索时返回的匹配内容条数 VECTO…

leetcode 9 回文数

class Solution {public boolean isPalindrome(int x) {if(x < 0){return false;}int num x;int value 0;while(num > 0){value value * 10 num % 10;num num / 10;}return value x;} }

golang 日志库logrus和lumberjack 日志切割库实践

package mainimport (log "github.com/Sirupsen/logrus""gopkg.in/natefinch/lumberjack.v2" )func main() {logger : &lumberjack.Logger{// 日志输出文件路径Filename: "/var/log/myapp/foo.log",// 日志文件最大 size, 单位是 MBMaxSiz…

【问题解决】VSCode 远程安装插件特别慢

【问题描述】 我要配置 VSCode WSL 的开发环境&#xff0c;需要在 WSL 里也装上 C、CMake 系列的插件&#xff0c;如下图的直接下载方式特别慢&#xff1a; 【解决方法】 先去网站下载插件&#xff1a;https://marketplace.visualstudio.com/&#xff0c;后缀名&#xff1a;…

re学习(18)[ACTF新生赛2020]rome1(Z3库+window远程调试)

参考视频: Jamiexu793的个人空间-Jamiexu793个人主页-哔哩哔哩视频 代码分析&#xff1a; 其主要内容在两个while循环中&#xff08;从定义中可知flag位16个字符&#xff09;。 看第二个循环&#xff0c;可知是比较result和经过第一个循环得到的v1比较&#xff08;就是flag…

Django MultiValueDictKeyError 表单数据用request.POST 非表单数据用request.body

表单数据&#xff1a;Content-Type(请求头)为application/x-www-form-urlencoded的数据。 用request.POST获取 a request.POST.get(a) a request.POST[a] alist request.POST.getlist(a) 非表单数据&#xff1a;Content-Type(请求头)为非application/x-www-form-urlenco…

Ghost Buster Pro for mac(快速清理卸载的应用残存文件)

Ghost Buster Pro for mac可从您已卸载的应用程序中查找并删除文件。该应用程序速度快如闪电&#xff0c;可立即释放内存。 许多应用程序都安装在计算机上&#xff0c;但它们通常只会在您的计算机上停留很短的时间。每个应用程序都会创建文件&#xff0c;但删除应用程序不会删…

create database创建数据库失败

瀚高数据库 目录 环境 症状 问题原因 解决方案 环境 系统平台&#xff1a;Linux x86-64 Red Hat Enterprise Linux 7 版本&#xff1a;4.5.7 症状 1、执行如下sql语句创建数据库报错。 create database printcdburn with encodingUTF8 OWNERprintcdburn LC_COLLATEzh_CN.UTF-…

第八十八回:创建一个调色板

文章目录 概念介绍实现方法整体思路具体步骤 示例代码 我们在上一章回中介绍了打印日志相关的内容&#xff0c;本章回中将介绍 如何创建一个调色板.闲话休提&#xff0c;让我们一起Talk Flutter吧。 概念介绍 我们在本章回中介绍的调色板是一个具有各种颜色的窗口&#xff0c…

Taurus .Net Core 微服务开源框架:Admin 插件【4-3】 - 配置管理-Mvc【Plugin-MicroService 微服务】

目录 1、系统配置节点&#xff1a;Mvc - Plugin - MicroService 配置界面&#xff1a;注册中心 2、系统配置节点&#xff1a;Mvc - Plugin - MicroService 配置界面&#xff1a;注册中心&#xff08;从&#xff09; 3、系统配置节点&#xff1a;Mvc - Plugin - MicroService…