当前位置: 首页 > news >正文

点瑞网络网站建设网站做业务赚钱

点瑞网络网站建设,网站做业务赚钱,seo搜索引擎优化就业前景,阿克顿巴网站建设的目的本次内容需要 gin框架基础知识, golang微服务基础知识才能更好理解 一.Captcha验证码功能引入 在前面,讲解了微服务的架构等,这里,来讲解前面商城项目的 Captcha验证码 微服务 ,captcha验证码功能在前台,后端 都要用到 ,可以把它 抽离出来 ,做成微服务功能 编辑 这个验证码功能…本次内容需要 gin框架基础知识, golang微服务基础知识才能更好理解 一.Captcha验证码功能引入 在前面,讲解了微服务的架构等,这里,来讲解前面商城项目的 Captcha验证码 微服务 ,captcha验证码功能在前台,后端 都要用到 ,可以把它 抽离出来 ,做成微服务功能 编辑 这个验证码功能封装代码captcha.go如下: package models//验证码属性: https://captcha.mojotv.cn/ import (github.com/mojocn/base64Captchaimage/color )//创建store,保存验证码的位置,默认为mem(内存中)单机部署,如果要布置多台服务器,则可以设置保存在redis中 //var store base64Captcha.DefaultMemStore//配置RedisStore, 保存验证码的位置为redis, RedisStore实现base64Captcha.Store接口 var store base64Captcha.Store RedisStore{}//获取验证码 func MakeCaptcha(height int, width int, length int) (string, string, error) {//定义一个drivervar driver base64Captcha.Driver//创建一个字符串类型的验证码驱动DriverString, DriverChinese :中文驱动driverString : base64Captcha.DriverString{Height: height, //高度Width: width, //宽度NoiseCount: 0, //干扰数ShowLineOptions: 2 | 4, //展示个数Length: length, //长度Source: 1234567890qwertyuioplkjhgfdsazxcvbnm, //验证码随机字符串来源BgColor: color.RGBA{ // 背景颜色R: 3,G: 102,B: 214,A: 125,},Fonts: []string{wqy-microhei.ttc}, // 字体}driver driverString.ConvertFonts()//生成验证码c : base64Captcha.NewCaptcha(driver, store)id, b64s, err : c.Generate()return id, b64s, err }//校验验证码 func VerifyCaptcha(id string, VerifyValue string) bool {// 参数说明: id 验证码id, verifyValue 验证码的值, true: 验证成功后是否删除原来的验证码if store.Verify(id, VerifyValue, true) {return true} else {return false} } 把这个验证码做成微服务的话,就需要实现上面的两个方法: 获取验证码(MakeCaptcha), 校验验证码(VerifyCaptcha) 二.创建captcha验证码微服务服务端 创建两个文件夹,client(客户端),server(服务端) 生成服务端captcha微服务代码 在server目录下运行: go-micro new service captcha,生成captcha服务端代码 运行命令后,生成的服务端目录如下: 编写proto/captcha.proto文件 在这个文件中编写 获取验证码,验验证码相关代码 syntax proto3;package captcha;option go_package ./proto/captcha;service Captcha {//获取验证码: MakeCaptchaRequest请求, MakeCaptchaRequest返回rpc MakeCaptcha(MakeCaptchaRequest) returns (MakeCaptchaResponse) {}//校验验证码: VerifyCaptchaRequest请求, VerifyCaptchaResponse返回rpc VerifyCaptcha(VerifyCaptchaRequest) returns (VerifyCaptchaResponse) {} }//以下具体参数类型参考captcha.go中对应的方法//获取验证码请求参数 message MakeCaptchaRequest {//验证码高度int32 height 1;//验证码宽度int32 width 2;//验证码长度int32 length 3; }//获取验证码返回数据 message MakeCaptchaResponse {//验证码idstring id 1;//验证码base64编码string b64s 2; }//校验验证码请求参数 message VerifyCaptchaRequest {//验证码idstring id 1;//输入的验证码string verifyValue 2; }//校验验证码返回数据 message VerifyCaptchaResponse {//校验的结果bool verifyResult 1; } 生成proto相关文件 参考 [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,windows下运行 Makefile里面的proto下的代码 :protoc --proto_path. --micro_out. --go_out:. proto/captcha.proto, 当然,如果是初次使用go-micro,则还需运行init下面的代码(go xxx),引入相关包 初始化项目 在captcha目录下运行命令: go mod init captcha,初始化项目 删除go.mod后再次执行 go mod init captcha命令: 运行命令 :go mod tidy,加载项目需要的包: 上面表示:下载 go-micro.dev/v4这个包失败了,这时则需运行命令 go get go-micro.dev/v4, 具体参考 : [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例 在这里可能会出现 import中始终报红 的情况,解决见 : golang开启mod后import报红解决方案 启动consul服务发现 在cmd中运行命令: consul agent -dev,具体参考: [golang 微服务] 5. 微服务服务发现介绍,安装以及consul的使用,Consul集群 main.go中实例化consul 具体参考: [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,代码如下: package mainimport (captcha/handlerpb captcha/proto/captchago-micro.dev/v4go-micro.dev/v4/loggergithub.com/go-micro/plugins/v4/registry/consul )var (service captchaversion latest )func main() {//集成consulconsulReg : consul.NewRegistry()// Create servicesrv : micro.NewService(micro.Address(127.0.0.1:8081), //指定微服务的ip: 选择注册服务器地址,也可以不配置,默认为本机,也可以选择consul集群中的clientmicro.Name(service),micro.Version(version),//注册consulmicro.Registry(consulReg),)srv.Init(micro.Name(service),micro.Version(version),)// Register handlerif err : pb.RegisterCaptchaHandler(srv.Server(), new(handler.Captcha)); err ! nil {logger.Fatal(err)}// Run serviceif err : srv.Run(); err ! nil {logger.Fatal(err)} } handler/captcha.go封装实现proto/captcha.proto里面的rpc方法 参考 proto/captcha.proto里面的 service Captcha 方法实现,也可以参考生成的 .pb.micro.go里面生成的方法进行实现 (1).pb.micro.go参考代码: // Client API for Captcha service type CaptchaService interface {// 获取验证码: MakeCaptchaRequest请求, MakeCaptchaRequest返回MakeCaptcha(ctx context.Context, in *MakeCaptchaRequest, opts ...client.CallOption) (*MakeCaptchaResponse, error)// 校验验证码: VerifyCaptchaRequest请求, VerifyCaptchaResponse返回VerifyCaptcha(ctx context.Context, in *VerifyCaptchaRequest, opts ...client.CallOption) (*VerifyCaptchaResponse, error) } (2).handler/captcha.go代码: 把 一.Captcha验证码功能引入中captcha.go的代码复制到 handler/captcha.go中, 然后修修改改就可以了 1)首先,import github.com/mojocn/base64Captcha 把 github.com/mojocn/base64Captcha放入import中,然后通过 go mod tidy或者 go get github.com/mojocn/base64Captcha 引入 2).配置RedisStore 把 var store base64Captcha.Store RedisStore{}复制进去 //创建store,保存验证码的位置,默认为mem(内存中)单机部署,如果要布置多台服务器,则可以设置保存在redis中 //var store base64Captcha.DefaultMemStore//配置RedisStore, 保存验证码的位置为redis, RedisStore实现base64Captcha.Store接口 var store base64Captcha.Store RedisStore{} 这里使用的是 redis的存储方式,故需要 初始化redis,以及实现 设置 captcha 的方法的代码,故需要在captcha下创建 models/redisCore.go, models/redisStore.go文件,具体参考: [golang gin框架] 12.Gin 商城项目-base64Captcha生成图形验证码以及分布式架构中配置Captcha 初始化redis的代码 redisCore.go代码如下: package models//redis官网: github.com/go-redis //下载go-redis: go get github.com/redis/go-redis/v9 //连接redis数据库核心代码import (contextfmtgithub.com/redis/go-redis/v9gopkg.in/ini.v1os )//全局使用,就需要把定义成公有的 var ctxRedis context.Background()var (RedisDb *redis.Client )//是否开启redis var redisEnable bool//自动初始化数据库 func init() {//加载配置文件config, iniErr : ini.Load(./conf/app.ini)if iniErr ! nil {fmt.Printf(Fail to read file: %v, iniErr)os.Exit(1)}//获取redis配置ip : config.Section(redis).Key(ip).String()port : config.Section(redis).Key(port).String()redisEnable, _ config.Section(redis).Key(redisEnable).Bool()//判断是否开启redisif redisEnable {RedisDb redis.NewClient(redis.Options{Addr: ip : port,Password: , // no password setDB: 0, // use default DB})//连接redis_, err : RedisDb.Ping(ctxRedis).Result()//判断连接是否成功if err ! nil {println(err)}} } 设置 captcha 的方法的代码 redisStore.go代码如下: package models/** 使用redis需实现Store中的三个方法 type Store interface {// Set sets the digits for the captcha id.Set(id string, value string)// Get returns stored digits for the captcha id. Clear indicates// whether the captcha must be deleted from the store.Get(id string, clear bool) string//Verify captchas answer directlyVerify(id, answer string, clear bool) bool }*/import (contextfmttime )var ctx context.Background()const CAPTCHA captcha:type RedisStore struct { }//实现设置 captcha 的方法 func (r RedisStore) Set(id string, value string) error {key : CAPTCHA iderr : RedisDb.Set(ctx, key, value, time.Minute*2).Err()return err }//实现获取 captcha 的方法 func (r RedisStore) Get(id string, clear bool) string {key : CAPTCHA id//获取 captchaval, err : RedisDb.Get(ctx, key).Result()if err ! nil {fmt.Println(err)return }//如果clear true, 则删除if clear {err : RedisDb.Del(ctx, key).Err()if err ! nil {fmt.Println(err)return }}return val }//实现验证 captcha 的方法 func (r RedisStore) Verify(id, answer string, clear bool) bool {v : RedisStore{}.Get(id, clear)return v answer } 这里使用了ini.Load加载 参考: [golang gin框架] 9.Gin GORM 中使用事务以及go-ini加载.ini配置文件 3).实现获取验证码方法的业务逻辑代码 把 一.Captcha验证码功能引入中captcha.go 获取验证码方法代码复制到handler/captcha.go的 MakeCaptcha,然后修修改改就可以了,代码如下 //获取验证码的方法 func (e *Captcha) MakeCaptcha(ctx context.Context, req *pb.MakeCaptchaRequest, rsp *pb.MakeCaptchaResponse) error {//实现业务逻辑代码//定义一个drivervar driver base64Captcha.Driver//创建一个字符串类型的验证码驱动DriverString, DriverChinese :中文驱动driverString : base64Captcha.DriverString{Height: int(req.Height), //高度Width: int(req.Width), //宽度NoiseCount: 0, //干扰数ShowLineOptions: 2 | 4, //展示个数Length: int(req.Length), //长度Source: 1234567890qwertyuioplkjhgfdsazxcvbnm, //验证码随机字符串来源BgColor: color.RGBA{ // 背景颜色R: 3,G: 102,B: 214,A: 125,},Fonts: []string{wqy-microhei.ttc}, // 字体}driver driverString.ConvertFonts()//生成验证码c : base64Captcha.NewCaptcha(driver, store)id, b64s, err : c.Generate()//把生成的验证码id,base64编码赋值给返回的rsp参数rsp.Id idrsp.B64S b64sreturn err } 4).实现校验验证码方法的业务逻辑代码 把 一.Captcha验证码功能引入中captcha.go 校验验证码的方法代码复制到handler/captcha.go的 MakeCaptcha,然后修修改改就可以了,代码如下: //校验验证码的方法 func (e *Captcha) VerifyCaptcha(ctx context.Context, req *pb.VerifyCaptchaRequest, rsp *pb.VerifyCaptchaResponse) error {// 参数说明: id 验证码id, verifyValue 验证码的值, true: 验证成功后是否删除原来的验证码if store.Verify(req.Id, req.VerifyValue, true) {rsp.VerifyResult true //校验成功} else {rsp.VerifyResult false //校验失败}return nil } 4).完整代码如下 package handlerimport (captcha/modelspb captcha/proto/captchacontextgithub.com/mojocn/base64Captchaimage/color )//创建store,保存验证码的位置,默认为mem(内存中)单机部署,如果要布置多台服务器,则可以设置保存在redis中 //var store base64Captcha.DefaultMemStore//配置RedisStore, 保存验证码的位置为redis, RedisStore实现base64Captcha.Store接口 var store base64Captcha.Store models.RedisStore{}type Captcha struct{}//获取验证码的方法 func (e *Captcha) MakeCaptcha(ctx context.Context, req *pb.MakeCaptchaRequest, rsp *pb.MakeCaptchaResponse) error {//实现业务逻辑代码//定义一个drivervar driver base64Captcha.Driver//创建一个字符串类型的验证码驱动DriverString, DriverChinese :中文驱动driverString : base64Captcha.DriverString{Height: int(req.Height), //高度Width: int(req.Width), //宽度NoiseCount: 0, //干扰数ShowLineOptions: 2 | 4, //展示个数Length: int(req.Length), //长度Source: 1234567890qwertyuioplkjhgfdsazxcvbnm, //验证码随机字符串来源BgColor: color.RGBA{ // 背景颜色R: 3,G: 102,B: 214,A: 125,},Fonts: []string{wqy-microhei.ttc}, // 字体}driver driverString.ConvertFonts()//生成验证码c : base64Captcha.NewCaptcha(driver, store)id, b64s, err : c.Generate()//把生成的验证码id,base64编码赋值给返回的rsp参数rsp.Id idrsp.B64S b64sreturn err }//校验验证码的方法 func (e *Captcha) VerifyCaptcha(ctx context.Context, req *pb.VerifyCaptchaRequest, rsp *pb.VerifyCaptchaResponse) error {// 参数说明: id 验证码id, verifyValue 验证码的值, true: 验证成功后是否删除原来的验证码if store.Verify(req.Id, req.VerifyValue, true) {rsp.VerifyResult true //校验成功} else {rsp.VerifyResult false //校验失败}return nil } 注册验证码微服务服务端到服务发现(consul) captcha目录下运行go run main.go,然后在consul UI 查看,是否注册成功 注册成功了 三.创建captcha验证码微服务客户端 在前面商城项目单体架构中生成客户端代码 前面单体架构商城中调用captcha验证码接口代码是通过接口 http://127.0.0.1:8080/admin/captcha这个访问的,具体代码如下: adminRouters.go //验证码 adminRouters.GET(/captcha, admin.LoginController{}.Captcha) LoginController.go //获取验证码,验证验证码func(con LoginController) Captcha(c *gin.Context) {id, b64s, err : models.MakeCaptcha(50, 100 ,1)if err ! nil {fmt.Println(err)}c.JSON(http.StatusOK, gin.H{captchaId: id,captchaImage: b64s,}) } 上面调用models下 captcha.go中的方法 MakeCaptcha()获取验证码,该captcha.go也就是 一.Captcha验证码功能引入 中captcha.go代码,这是 原来单体架构的做法,访问如下: 现在就要交给 captcha验证码微服务来处理 首先把server/captcha/proto文件夹复制到项目中 封装captcha.go验证码微服务客户端方法 前面章节对于验证码这块儿, 前端和 后台都需要进行 验证码逻辑处理,调用的方法都是models/captcha.go下面的方法,故在进行微服务客户端处理时,也在这里面进行修改 (1).配置consul服务发现 首先,在models下创建initCaptchaConsul.go,配置consul服务发现,以便调用,代码如下: package models//微服务客户端配置: 初始化consul配置,当一个项目中多个微服务时,就很方便了 //建议:一个微服务对应一个客户端,这样好管理import (github.com/go-micro/plugins/v4/registry/consulgo-micro.dev/v4/clientgo-micro.dev/v4/registry )//CaptchaClient: 全局变量 在外部的包中可以调用 var CaptchaClient client.Client//init 方法: 当程序运行时就会自动执行 func init() {consulRegistry : consul.NewRegistry(//指定微服务的ip: 选择注册服务器地址,默认为本机,也可以选择consul集群中的client,建议一个微服务对应一个consul集群的clientregistry.Addrs(127.0.0.1:8500),)// Create servicesrv : micro.NewService(micro.Registry(consulRegistry),)srv.Init()CaptchaClient srv.Client() } 在这里,也许没有引入,执行命令:go mod tidy引入对应的包 (2).完善models/captcha.go中的MakeCaptcha获取验证码方法 在该方法中实现调用获取验证码微服务逻辑功能 //调用获取验证码微服务 func MakeCaptcha(height int, width int, length int) (string, string, error) {// Create client: 这里的服务名称需要和服务端注册的名称一致captchaClient : pbCaptcha.NewCaptchaService(captcha, CaptchaClient)// Call service: 创建连接captcha微服务的连接,并传递参数,//该方法最终是请求server端handler中的captcha.go中的MakeCaptcha方法rsp, err : captchaClient.MakeCaptcha(context.Background(), pbCaptcha.MakeCaptchaRequest{Height: int32(height), //验证码高度Width: int32(width), //验证码宽度Length: int32(length), //验证码长度})//判断是否获取成功if err ! nil {log.Fatal(err)}//记录loglog.Info(rsp)//返回return rsp.Id, rsp.B64S, err } (3).完善models/captcha.go中的VerifyCaptcha校验验证码方法 在该方法中实现调用校验验证码微服务逻辑功能 //调用校验验证码微服务 func VerifyCaptcha(id string, VerifyValue string) bool {// Create client: 这里的服务名称需要和服务端注册的名称一致captchaClient : pbCaptcha.NewCaptchaService(captcha, CaptchaClient)// Call service: 创建连接captcha微服务的连接,并传递参数,//该方法最终是请求server端handler中的captcha.go中的VerifyCaptcha方法rsp, err : captchaClient.VerifyCaptcha(context.Background(), pbCaptcha.VerifyCaptchaRequest{Id: id, //验证码IdVerifyValue: VerifyValue, //验证码})//判断是否获取成功if err ! nil {log.Fatal(err)}//记录loglog.Info(rsp)//返回return rsp.VerifyResult } (4).完整代码如下 package models//验证码属性: https://captcha.mojotv.cn/ import (contextgithub.com/prometheus/common/logpbCaptcha goshop/proto/captcha )//调用获取验证码微服务 func MakeCaptcha(height int, width int, length int) (string, string, error) {// Create client: 这里的服务名称需要和服务端注册的名称一致captchaClient : pbCaptcha.NewCaptchaService(captcha, CaptchaClient)// Call service: 创建连接captcha微服务的连接,并传递参数,//该方法最终是请求server端handler中的captcha.go中的MakeCaptcha方法rsp, err : captchaClient.MakeCaptcha(context.Background(), pbCaptcha.MakeCaptchaRequest{Height: int32(height), //验证码高度Width: int32(width), //验证码宽度Length: int32(length), //验证码长度})//判断是否获取成功if err ! nil {log.Fatal(err)}//记录loglog.Info(rsp)//返回return rsp.Id, rsp.B64S, err }//调用校验验证码微服务 func VerifyCaptcha(id string, VerifyValue string) bool {// Create client: 这里的服务名称需要和服务端注册的名称一致captchaClient : pbCaptcha.NewCaptchaService(captcha, CaptchaClient)// Call service: 创建连接captcha微服务的连接,并传递参数,//该方法最终是请求server端handler中的captcha.go中的VerifyCaptcha方法rsp, err : captchaClient.VerifyCaptcha(context.Background(), pbCaptcha.VerifyCaptchaRequest{Id: id, //验证码IdVerifyValue: VerifyValue, //验证码})//判断是否获取成功if err ! nil {log.Fatal(err)}//记录loglog.Info(rsp)//返回return rsp.VerifyResult } 校验captcha验证码微服务功能 (1).先启动服务端 见前面代码 (2).启动客户端 在项目根目录下运行 :go run main.go,启动项目 (3).访问http://127.0.0.1:8080/admin/captcha 访问 http://127.0.0.1:8080/admin/captcha看看是否显示验证码相关数据 显示了,说明调用了验证码微服务操作 (4).校验验证码微服务操作是否成功 访问后台登录页面,输入用户名,密码,验证码,看看是否成功 好了,captcha验证码微服务客户端操作完成,在这里,上面讲解的是web页面调用captcha验证码微服务功能,下面则讲解Go Web Restfull APi 调用Captcha验证码微服务 四.Go Web Restfull APi 调用Captcha验证码微服务 Go Web Restfull APi 调用Captcha验证码微服务主要是给手机app,微信小程序等提供接口,架构如下 创建一个api的Gin项目,并配置routers 这里直接以上面项目为案例,在routers下创建 apiRouters.go路由文件 构建验证码相关接口,代码如下 在controllers/api/ CaptchaController.go下编写获取验证码,校验验证码相关逻辑,代码如下: package apiimport (contextgithub.com/gin-gonic/gingithub.com/prometheus/common/loggoshop/modelspbCaptcha goshop/proto/captchanet/http )type CatpchaController struct { }//获取验证码的接口(调用验证码微服务操作) func (con CatpchaController) MakeCaptcha(c *gin.Context) {// Create client: 这里的服务名称需要和服务端注册的名称一致captchaClient : pbCaptcha.NewCaptchaService(captcha, models.CaptchaClient)// Call service: 创建连接captcha微服务的连接,并传递参数,//该方法最终是请求server端handler中的captcha.go中的MakeCaptcha方法rsp, err : captchaClient.MakeCaptcha(context.Background(), pbCaptcha.MakeCaptchaRequest{Height: 100, //验证码高度Width: 200, //验证码宽度Length: 4, //验证码长度})//判断是否获取成功if err ! nil {log.Fatal(err)}//记录loglog.Info(rsp)//返回c.JSON(http.StatusOK, gin.H{captchaId: rsp.Id,B64s: rsp.B64S,}) }//校验验证码接口 func (con CatpchaController) VerifyCaptcha(c *gin.Context) {//获取请求参数verifyId : c.PostForm(verifyId)verifyValue : c.PostForm(verifyValue)// Create client: 这里的服务名称需要和服务端注册的名称一致captchaClient : pbCaptcha.NewCaptchaService(captcha, models.CaptchaClient)// Call service: 创建连接captcha微服务的连接,并传递参数,//该方法最终是请求server端handler中的captcha.go中的VerifyCaptcha方法rsp, err : captchaClient.VerifyCaptcha(context.Background(), pbCaptcha.VerifyCaptchaRequest{Id: verifyId, //验证码IdVerifyValue: verifyValue, //验证码})//判断是否获取成功if err ! nil {log.Fatal(err)}//记录loglog.Info(rsp)//返回if rsp.VerifyResult true { // 说明验证通过c.JSON(http.StatusOK, gin.H{message: 验证验证码成功,success: true,})} else {c.JSON(http.StatusOK, gin.H{message: 验证验证码失败,success: false,})} } 校验api请求是否成功 请求http://127.0.0.1:8080/api/MakeCaptcha,看看是否返回对应的验证码json请求 从上图看得出来,返回了对应验证码的数据的,把 B64s中的数据放入img srcB64s /中,就可以了,展示的图片如下: 然后校验验证码,一般通过postman校验 好了,Go Web Restfull APi 调用Captcha验证码微服务 获取验证码,以及校验验证码api接口操作就完成了 [上一节][golang gin框架] 39.Gin商城项目-微服务实战之微服务架构 [下一节][golang gin框架] 41.Gin商城项目-微服务实战之后台Rbac微服务(用户登录 、Gorm数据库配置单独抽离、 Consul配置单独抽离)
http://www.dnsts.com.cn/news/29485.html

相关文章:

  • 优化网站价位wordpress the7主题
  • 购物网站导航模板h5网页网站制作代码
  • 建设部网站防排烟规范那些市区做网站群
  • 网站内容规划流程wordpress 网页慢
  • 万泉河网站建设商城类网站怎么优化
  • 做兼职什么网站比较好百度快速收录权限域名
  • 廊坊做网站的大公司找关键词的方法与技巧
  • 我想要个网站windows 2003做网站
  • 免费网站注册免费创建网站化妆品营销型网站模板
  • 建设网站怎么制作甘肃企业网站建设
  • 用户研究 网站南通网站定制企业
  • 佛山新网站建设信息网站后台管理员密码
  • 企业名录搜索网站东营小程序开发制作
  • 网站推广的企业销售推广的方法都有哪些
  • 沈阳网站建设哪里的公司比较好关于做ppt的网站有哪些
  • 营销型网站建设制作推广购物网站哪个质量好
  • 网站建设与维护模拟一如何选择做pc端网站
  • 怎么做属于自己的音乐网站莱芜找工作网站
  • 公司网站要多少钱重庆定制网站开发
  • 请简述网站制作流程wordpress ent主题
  • yes风淘宝网站图片展示网页设计
  • 没有域名的网站需要备案吗网络商城建设费用
  • 一个网站大概多少页面只有后端可以做网站吗
  • 上海迈诺网站建设专业生产佛山网站建设
  • 高清素材网站无水印杭州公司注册地址租赁
  • 苏州网站推广哪家好美食网站设计规划书
  • 百度站点宁波网站seo报价
  • asp网站数据库扫描网上商城搭建
  • 360云盘做 网站图片服务器个人域名备案查询
  • 响应式网站好还是自适应网站好海外推广