1 Star 0 Fork 0

NHCode / WxMicro

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

WxMicro微服务系统 一、 环境以及语言 系统:windows 10 专业版

底层框架:.net Core 5.1 Mvc2.0

开发工具:Visual Studio Enterprise 2019

开发语言:C#

二、 需求以及构想 目前大多的业务平台、办公OA、以及相关的数据管理后台,Api接口等的开发在环境搭载方面均比较复杂。每套程序都需要自行去构建复杂的权限、开发繁琐的权限分配计算。设想如果有一个框架可以实现简单的数据配置就能 实现复杂高效的权限功能,只需要简短的代码就能构建出复杂的鉴权,那么在构建开发时是否可以减轻程序员构建复杂权限的时间?可直接进行业务接口的开发,无需去考虑权限以及分配问题。开发好直接通过简单的权限配置即可得到想要的结果。

微服务架构的维护是很让程序员头疼的事情,可不可以简化微服务的架构?通过鉴权的方式让程序自动去完成日志、记录、接口、发现、网关等一系列的繁琐品配置。让程序员快速构建对应的业务程序即可发布出相应的微服务,其他的挂载的微服务程序可检测到新的服务程序,并提供相应的程序使用场景。可通过实现新开发出的微服务程序接口,使用或调用对应微服务的相关接口进行业务处理来实现微服务开发的繁琐性质。

通过以往经验了解以往的MVC(Model View Controller)框架是将M和V实现代码分离,从而使同一个程序可以使用不同的表现形,而这种设计模式是比较单一而且复杂的。程序员在开发不同的功能时通过书写多个Controller以及多个View实现不同的业务和功能,设想一下如果将MVC设计理念+上微服务理念,实现出来的新架构会是什么样子的?单独的模块是MVC处理模式。可单独布置或者单独的发表,而MVC模式中Controller其实是可以跨服务器限制实现远程访问的。那么我们可以不可以通过一些特殊的程序完成MVC的服务继承?实现接口和业务的模块化,实现权限统一的校验标准,让我们构建项目时,不需要过多的区书写相同的功能或者界面,然后构建对应的功能模块仓库或者商城实现模块的复用。完成微服务能做到而MVC做不到的一些功能呢?如果可以那将如何去实现,由此构建了一下的响应项目,并完成由MVC框架保留以往的设计模式以及理念,加上一些新的微服务理念,完成MVC设计的模块编程。

根据上述需求以及构想进行相应资料的查阅以及通过以往开发经验的整理,建设该MVC微服务项目。项目命名为“WxMicro” 名字大概的意思就是“微小工程”。

三、 思维导图

四、 WxMicro 单个微服务结构

五、 微服务处理模块 微服务处理模块分为两个主要部分的功能。一个模块负责实现个借口业务方法功能连接等权限访问,权限分发功能。而另一个模块则主要承担模块和模块之间的通信发现调用功能。

5.1 服务管理模块 模块管理功能主要实现模块之间的加载问题,模块和模块之间只需要实现框架对应的业务接口就可以实现模块相互合并相互调用的功能。模块是以动态链接库方式(.dll)的方式进行微服务模块扩展的。除此职位单个服务模块还可以进行托管模式下载IIs或者docker环境下单独运行。其中不影响其功能方面使用。

实现服务管理模块,需要实现对应接口完成对业务接口的反射或者存储,并能够获取对应的接口信息以及处理各个模块之间的衔接问题达到管理模块和模块之间的目的。

通过相关方面的资料了解到,在C#语言中在System.runtime.dll支持库中有的Attribute类可以做出相应的业务信息记录和发现功,经研究可以大致推导出一下算法:

  1. 定义接口规则以及特性标注规则标准。

  2. 定义特性Attribute属性完成特定信息的标识以及注解(包含接口调用方式、业务接口相关信息等)。
  3. 构建对应的工具对象算法实现attribute特性的读取。

  4. 构建属性特性信息记录再载体的数据结构

  5. 将获取的数据结构赋值给对应信息记录的载体结构,完成数据记录载体的存储。

  6. 实现对应特性或指定对象的反射机制。

  7. 从反射机制中获取相应的结构信息载体。

将模块和模块之间通过结构信息载体构建相应的逻辑程序完成模块和模块之间的合并、分离、等功能。

5.2 权限管理模块 承接权限的配置功能,程序员可以通过该模块实现的接口进行用户访问权限的配置,实现用户权限的校验、用户证书的生成、程序员可通过实现对应接口或调用对应的特性对象实现对接口或者业务功能的概述以及备注说明。

同时在程序模块加载时自动衔接为主从服务协作模块。如a模块和B模块合并时,如果将B设置成a的子模块,那么B的权限模块将不会进行任何操作,而使用a的权限管理操作。同时a模块可以检测出B模块需要授权的对应业务接口以及连接。程序员通过权限分配功能接口直接对B模块进行权限接管,同时反过来这个方法也是可行的,这样就实现两个模块之间的衔接以及分离后亦可以单独运行。

权限管理模块主要功能时做好各业务层接口的权限功能分配、验证、针对用户证书的颁、用户证书的校验以及授权等 管控模块,是WxMicro服务中一个不可缺少的模块。

该模块通过服务管理模块获取的业务接口信息,可以构建出对应的访问路径等,然后通过用户证书与接口地址或者链接进行相互的关系建立达成权限控制以及相应的访问限制功能。

大致的权限管理算法如下:

  1. 从服务管理模块获取业务接口资料结构(包含接口信息,请求方式,请求方法、验证或加密方法等)。

  2. 通过证书的加解密以及验证规则完成对用户身份的确认。

  3. 实现对用户证书与业务接口资料结构进行相关的关系绑定。

  4. 通过用户证书与业务接口资料的结构进行权限访问。

  5. 通过权限的校验结果调用服务管理模块对子模块对应接口等调用完成业务逻辑数据交互。

六、 数据模块 数据模块通过EF6框架进行数据库当相关操作。实现数据库连接以及数据的增、删、查、改功能。

七、 使用手册 WxUtile.Attributes.PortServiceAttribute(Class) 接口文档构建特性对象

WxUtile.Attributes.PortServiceAttribute.Ports(属性) 接口文档存储对象

WxUtile.Attributes.PortServiceAttribute(System.Type)(构造函数) 作用是根据反射对象获取到对应接口、以及请求方式、等接口参数的资料特性

需要获取参数的对象类型(属性名称[type]))

WxUtile.Attributes.PortServiceAttribute.GetControllerName(System.String)(方法) 获取Controller名称

对应ControllerName的类型名称(属性名称[ControllerName]))

返回:

WxUtile.Attributes.PortServiceAttribute.GetTypeName(System.String)(方法) 获取属性类型

属性名称(属性名称[Name]))

返回:

WxUtile.Attributes.PortServiceAttribute.GetPresentation(System.Reflection.ParameterInfo)(方法) 获取属性介绍

反射获取的属性对象(属性名称[Parameter]))

返回:

WxUtile.Attributes.PortServiceAttribute.GetPresentation(System.Reflection.PropertyInfo)(方法) 获取属性介绍

反射获取的属性对象(属性名称[Parameter]))

返回:

WxUtile.Attributes.RemarkAttribute(Class) 备注特性,提供程序员备注对应接口的文档资料

WxUtile.Attributes.RemarkAttribute.Remark(属性) 备注资料属性内容

WxUtile.Attributes.RemarkAttribute(System.String)(构造函数) 构建备注特性的属性构造函数

备注说明内容(属性名称[Remark]))

WxUtile.Attributes.AuthorizationAttribute(Class) 用户授权(需要用户登录并获得访问允许的相应权限才能访问)

WxUtile.Attributes.UserDataAttribute(Class) 用户资料(需要使用用户资料,但不需要用户获得授权就可以访问)

WxUtile.Attributes.SignDataAttribute(Class) 用户请求接口时需要对资料进行签名处理)

WxUtile.Attributes.ApiAttribute(Class) 标识接口是API

WxUtile.Attributes.ApiAttribute.Name(属性) 接口名称

WxUtile.Attributes.ApiAttribute.Subchain(属性) 子接口列表

WxUtile.Attributes.ApiAttribute(System.String)(构造函数) 特性构造函数

接口名称(属性名称[Name]))

WxUtile.Attributes.ApiAttribute(System.String,System.String[])(构造函数) 特性构造函数

接口名称(属性名称[Name]))

子接口链接地址(属性名称[Subchain]))

WxUtile.Attributes.PageAttribute(Class) 标识接口是Page

WxUtile.Attributes.PageAttribute(System.String)(构造函数) 特性构造函数

接口名称(属性名称[Name]))

WxUtile.Attributes.PageAttribute(System.String,System.String[])(构造函数) 特性构造函数

接口名称(属性名称[Name]))

子接口链接地址(属性名称[Subchain]))

WxUtile.Attributes.MenuAttribute(Class) 标识接口为菜单

WxUtile.Attributes.MenuAttribute.GroupName(属性) 菜单组名称

WxUtile.Attributes.MenuAttribute.MenuGroup(属性) 菜单组对象

WxUtile.Attributes.MenuAttribute.IMenuSite(属性) 菜单位置标识(用户自定义标识位置所在)

WxUtile.Attributes.MenuAttribute(System.String,System.Int32)(构造函数) 构造菜单标识对象

菜单组名称(属性名称[GroupName]))

菜单位置标识(属性名称[menuSite]))

WxUtile.Attributes.MenuAttribute(System.Int32)(构造函数) 构造菜单标识对象

菜单位置标识(属性名称[menuSite]))

WxUtile.Authorizs.WxAuthorization(Class) 用户权限证书对象

WxUtile.Authorizs.WxAuthorization.GetAuthorization(Microsoft.AspNetCore.Http.HttpContext,WxUtile.Authorizs.WxCertificate{WxUtile.Models.WxUser}@,System.String@)(方法) 获取用户证书对象Token

HttpContext对象(属性名称[httpContext]))

用证书存储对象(属性名称[Ca]))

获取情况消息(属性名称[Msg]))

返回:

WxUtile.Authorizs.WxAuthorization.GetAuthorization(System.String,System.String,WxUtile.Authorizs.WxCertificate{WxUtile.Models.WxUser}@,System.String@)(方法) 获取用户证书对象Token

用户证书编号(属性名称[Aation]))

客户端IP地址(属性名称[IP]))

用户帧数存储对象(属性名称[Ca]))

获取情况消息(属性名称[Msg]))

返回:

WxUtile.Authorizs.WxAuthorizService(Class) 用户权限鉴别对象中间件

WxUtile.Authorizs.WxAuthorizService.IAutService(属性) 用户服务权限接口对象

WxUtile.Authorizs.WxAuthorizService(Microsoft.AspNetCore.Http.RequestDelegate,WxUtile.Interfaces.IAuthorizService)(构造函数) 构造函数,构建用户鉴权中间件对象

请求委托(属性名称[Next]))

用户服务权限接口对象(属性名称[IAutService]))

WxUtile.Authorizs.WxAuthorizService.InvokeAsync(Microsoft.AspNetCore.Http.HttpContext)(方法) 用户与委托通道中间对象

HttpContext对象(属性名称[httpContext]))

返回:

WxUtile.Authorizs.WxCa.ID(属性) 证书编号

WxUtile.Authorizs.WxCa.PublicKey(属性) 证书证书值(PublicKey)服务端公钥

WxUtile.Authorizs.WxCa.Authorization(属性) 获取Authorization

WxUtile.Authorizs.WxCa.AuthorizationBearer(属性) 获取 Bearer Authorization

WxUtile.Authorizs.WxCa.AuthorizationUrl(属性) 获取URL Authorization

WxUtile.Authorizs.WxCertificate`1(Class) 用户证书资料

WxUtile.Authorizs.WxCertificate`1.PublicKey(属性) 证书公钥

WxUtile.Authorizs.WxCertificate`1.PrivateKey(属性) 证书私钥

WxUtile.Authorizs.WxCertificate`1.UserPublicKey(属性) 用户提供的RSA265-2048的公钥串

WxUtile.Authorizs.WxCertificate`1.ExpiringDate(属性) 证书到期时间

WxUtile.Authorizs.WxCertificate`1.IssuanceDate(属性) 证书颁发日期

WxUtile.Authorizs.WxCertificate`1.LoginIP(属性) 用户登录IP地址

WxUtile.Authorizs.WxCertificate`1.AuthPortIDs(属性) 用户允许使用连接授权接口ID数组

返回:

WxUtile.Authorizs.WxCertificate`1.User(属性) 证书使用者资料

WxUtile.Configs.WxUtileConfig(Class) 获取配置项工具

WxUtile.Configs.WxUtileConfig.GetValue(System.String)(方法) 读取配置

配置项键(属性名称[key]))

返回:

WxUtile.Configs.WxUtileConfig.GetOBject``1(System.String)(方法) 获取对象

配置项键(属性名称[Key]))

返回:

WxUtile.Configs.WxUtileConfig.GetDbData(System.String)(方法) 获取数据连接对象

配置项键(属性名称[Key]))

返回:

WxUtile.ConstantData(Class) 数据存储对象

WxUtile.ConstantData.ISsuedBy(属性) 用户配置的证书文件存储

WxUtile.ConstantData.CSRedisClient(属性) Redis存储

WxUtile.ConstantData.CertificateExpirationTime(属性) 证书有效时间

WxUtile.ConstantData.MsgMinutes(属性) 消息签名有效时间

WxUtile.Controllers.BaseController(Class) 基础控制器对象(构建MVC控制器时需要继承该控制器)

WxUtile.Controllers.BaseController.RedisClient(属性) 植入缓存服务器

WxUtile.Controllers.BaseController.Certificate(WxUtile.Interfaces.IUser)(方法) 颁发用户证书

(属性名称[user]))

返回:

WxUtile.Controllers.BaseController.GetUser(WxUtile.Interfaces.IUser@)(方法) 根据用户证书获取用户资料

(属性名称[httpContext]))

返回:

WxUtile.Controllers.BaseController.GetUser(System.String,WxUtile.Interfaces.IUser@)(方法) 根据用户证书获取用户资料

(属性名称[Token]))

用户资料(属性名称[User]))

返回:

WxUtile.Controllers.BaseController.GetWxPorts(方法) 获取接口列表

返回:

WxUtile.DataBase.WxBaseContent(Class) Entity Framework 数据库连接对象

WxUtile.DataBase.WxBaseContent.GetDbData(方法) 获取连接配置方法

返回:

WxUtile.DataBase.WxBaseContent.OnConfiguring(Microsoft.EntityFrameworkCore.DbContextOptionsBuilder)(方法) 数据库连接字段配置

WxUtile.DataBase.WxBaseContent.Initialize(方法) 初始化数据表格,该算法是通过用户反射方式以及C#特性属性获取对应参数实现 C#对象转SQL命令,并写入数据库完成数据表构建的数据函数

WxUtile.DataBase.WxDbData.SQL(属性) 标识数据库引擎,(sqlserver、mysql、sqlite、oracle)

WxUtile.DataBase.WxDbData.DB(属性)

数据库连接字段

WxUtile.Interfaces.IAuthorizService(Class) 服务鉴权中间件对象

WxUtile.Interfaces.IAuthorizService.ToUser(WxUtile.Interfaces.IUser)(方法) 通知用户消息

(属性名称[Token]))

返回:

WxUtile.Interfaces.IAuthorizService.CertificateExpirationTime(方法) 用户证书失效时间,单位分钟

WxUtile.Interfaces.IAuthorizService.MsgMinutes(方法) 消息签名有效时间(单位:分钟)

返回:

WxUtile.Interfaces.IAuthorizService.GetPublicResourceTypes(方法) 允许公共资源文件类型资源文件类型 ".png|.js|.jpg|.svg|.font"

返回:

WxUtile.Interfaces.IAuthorizService.AccessError(方法) 访问错误跳转页面

返回:

WxUtile.Interfaces.IStartup(Class) 启动文件配置接口函数

WxUtile.Interfaces.IStartup.GetTheISsuedBy(方法) 获取用户证书对象

返回:

WxUtile.Interfaces.IStartup.GetRedisConnecting(方法) 获取Redis服务器连接地址

返回:

WxUtile.Interfaces.IStartup.Initialize(方法) 数据初始化

WxUtile.Interfaces.IStartup.GetAuthorizService(方法) 权限管理对象

返回:

WxUtile.Interfaces.IUser.ID(属性)

用户唯一标识

WxUtile.Interfaces.IUser.UserName(属性) 用户登录账号

WxUtile.Interfaces.IUser.UserPublicKey(属性) 用户提供的RSA265-2048的公钥串

WxUtile.Interfaces.IUser.OtherInformation(属性) 其他资料存储字符串

WxUtile.Interfaces.IUser.SetOtherInformation1(0)(方法) 设置其他消息

(属性名称[t]))

WxUtile.Interfaces.IUser.GetAuthPortIDArray(方法) 获取用户允许使用连接授权接口ID数组

返回:

WxUtile.Interfaces.IUser.GetOtherInformation``1(方法) 其他资料

返回:

WxUtile.Models.Ports.WxMenuGroup(Class) 菜单组对象

WxUtile.Models.Ports.WxMenuGroup.Name(属性) 菜单组名称

WxUtile.Models.Ports.WxMenuGroup.SubsetMenuGroup(属性) 子菜单组对象

WxUtile.Models.Ports.WxParameter(Class) 参数对象

WxUtile.Models.Ports.WxParameter.ParameterName(属性) 参数名称

WxUtile.Models.Ports.WxParameter.ParameterType(属性) 参数类型

WxUtile.Models.Ports.WxParameter.ParameterSpecification(属性) 参数说明

WxUtile.Models.Ports.WxParameter.IsNotNull(属性) 参数是否允许为空

WxUtile.Models.Ports.WxParameter.Remark(属性) 备注

WxUtile.Models.Ports.WxPort(Class) 接口对象

WxUtile.Models.Ports.WxPort.ID(属性) 连接唯一编号

WxUtile.Models.Ports.WxPort.ModuleName(属性) 模块名称

WxUtile.Models.Ports.WxPort.Path(属性) 接口连接访问路径

WxUtile.Models.Ports.WxPort.PathType(属性) 接口类型

WxUtile.Models.Ports.WxPort.Name(属性) 接口名称

WxUtile.Models.Ports.WxPort.RequesMethod(属性) 请求方法

WxUtile.Models.Ports.WxPort.Parameters(属性) 参数集合

WxUtile.Models.Ports.WxPort.IsAuthorization(属性) 该接口是否需要授权

WxUtile.Models.Ports.WxPort.IsUserValidation(属性) 该接口是否需要用户资料

WxUtile.Models.Ports.WxPort.IsSign(属性) 该接口是否需要签名处理(签名只支持RSA签名处理)

WxUtile.Models.Ports.WxPort.IsMenu(属性) 该接口是否标识为菜单

WxUtile.Models.Ports.WxPort.IsUrlToken(属性) 该接口Token传输验证匿名在请求路径

WxUtile.Models.Ports.WxPort.MenuGroupName(属性) 菜单组名称(菜单组名称格式:用户组->权限组->授权组->....)

WxUtile.Models.Ports.WxPort.MenuGroup(属性) 菜单组对象

WxUtile.Models.Ports.WxPort.MenuLocation(属性) 菜单位置标识(用户可自行定义位置标识)

WxUtile.Models.Ports.WxPort.Remark(属性) 接口备注

WxUtile.Models.Ports.WxPort.SubchainIDs(属性) 子链接编号

WxUtile.Models.WxError(Class) 错误访问页面

WxUtile.Models.WxError.PageErroUrl(属性) 页面错误访问地址

WxUtile.Models.WxError.APIErroUrl(属性) 接口错误访问地址

WxUtile.Models.ErrorData(Class) 错误数据对象

WxUtile.Models.ErrorData.Code(属性) 错误代码

WxUtile.Models.ErrorData.ErrorMsg(属性) 错误消息

WxUtile.Models.ErrorData.ExceptionJson(属性) 系统错误信息对象

WxUtile.Models.ErrorData.GetData(方法) 获取错误对象结构拼接字符串

返回:

WxUtile.Models.WxTheISsuedBy(Class) 证书签发对象

WxUtile.Models.WxTheISsuedBy.SecurityKey(属性) 平台数据加密安全秘钥,长度不得低于32位长度

返回:

WxUtile.Models.WxTheISsuedBy.ValidIssuer(属性) 签发地址

返回:

WxUtile.Models.WxTheISsuedBy.ServiceURL(属性) 服务数据请求地址

WxUtile.Models.WxTheISsuedBy.TerracePrivateKey(属性) 平台数字签名私钥

WxUtile.Models.WxTheISsuedBy.TerracePublicKey(属性) 平台数字签名验证公钥

WxUtile.Models.WxUser(Class) 用户资料对象

WxUtile.Models.WxUser.ID(属性) 用户唯一标识

WxUtile.Models.WxUser.UserName(属性) 用户登录账号

WxUtile.Models.WxUser.UserPublicKey(属性) 用户公钥

WxUtile.Models.WxUser.OtherInformation(属性) 用户其他资料

WxUtile.Models.WxUser.GetAuthPortIDArray(方法) 获取用户可以使用的接口列表

返回:

WxUtile.Startup(Class) startup类

WxUtile.Startup.initialize(Microsoft.Extensions.Configuration.IConfiguration,WxUtile.Interfaces.IStartup)(方法) 初始化方法

IConfiguration 对象(属性名称[configuration]))

IStartup接口对象(属性名称[IStart]))

WxUtile.Startup.Configuration(属性) 配置常量

WxUtile.Startup.ConfigureServices(Microsoft.Extensions.DependencyInjection.IServiceColl0ection)(方法) 服务配置

IServiceCollection 对象(属性名称[services]))

WxUtile.Startup.Configure(Microsoft.AspNetCore.Builder.IApplicationBuilder,Microsoft.AspNetCore.Hosting.IHostingEnvironment)(方法) 路由配置

IApplicationBuilder(属性名称[app])) IHostingEnvironment(属性名称[env])) WxMicro.DynamicChangeTokenProvider(Class) 构建IActionDescriptorChangeProvider接口完成对接口模块加载的任务反射功能,以及通知mvc框架新模块加入

WxMicro.DynamicChangeTokenProvider(Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartManager)(构造函数) 构造方法实现对象实例化,以及数据初始化

ApplicationPartManager 缓存组件(属性名称[manager]))

WxMicro.DynamicChangeTokenProvider.GetChangeToken(方法) CancellationChangeToken 调用

返回:

WxMicro.DynamicChangeTokenProvider.NotifyChanges(方法) 服务注册通知

WxMicro.DynamicChangeTokenProvider.InitializeAssembly(方法) 子服务加载

WxMicro.DynamicChangeTokenProvider.GetFilePath(System.String)(方法) 递归查找子模块文件夹下的子模块dll

路径(属性名称[Exists]))

MIT License Copyright (c) 2022 INode Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

通过以往经验了解以往的MVC(Model View Controller)框架是将M和V实现代码分离,从而使同一个程序可以使用不同的表现形,而这种设计模式是比较单一而且复杂的。程序员在开发不同的功能时通过书写多个Controller以及多个View实现不同的业务和功能,设想一下如果将MVC设计理念+上微服务理念,实现出来的新架构会是什么样子的?单独的模块是MVC处理模式。可单独布置或者单独的发表, 展开 收起
C#
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
C#
1
https://gitee.com/nhcode/wx-micro.git
git@gitee.com:nhcode/wx-micro.git
nhcode
wx-micro
WxMicro
develop

搜索帮助