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

平阳网站建设做网页一个页面多少钱

平阳网站建设,做网页一个页面多少钱,网站设置二级域名,权重查询爱站网提要使用gin框架(go的web框架)来创建简单的几个crud接口)使用技术: gin sqlite3 sqlx创建初始工程新建文件夹,创建三个子文件夹分别初始化工程 go mod如果没有.go文件,执行go mod tidy可能报错(warning: all matched no packages), 可以先不弄,只初始化模块就行(…提要使用gin框架(go的web框架)来创建简单的几个crud接口)使用技术: gin sqlite3 sqlx创建初始工程新建文件夹,创建三个子文件夹分别初始化工程 go mod如果没有.go文件,执行go mod tidy可能报错(warning: all matched no packages), 可以先不弄,只初始化模块就行(go mod init 模块名)# 项目根目录创建模块 go mod init go_manager go mod tidy # 进入db目录 cd db # 初始化模块 go mod init go_manager_db go mod tidy # 进入utils目录 cd ../utils # 初始化模块 go mod init go_manager_utils go mod tidy # 进入web目录 cd ../web # 初始化模块 go mod init go_manager_web go mod tidygo_manager_db模块编写创建数据库连接(sqlite如果没有库会自动建)// db\main.go package go_manager_dbimport (fmtgithub.com/jmoiron/sqlx_ github.com/mattn/go-sqlite3 )// 数据库相关操作 var db *sqlx.DB// 初始化数据库连接 func InitDB() (err error) {dsn : ./manager.db// 连接// Open可能仅校验参数而没有与db间创建连接// 要确认db是否可用需要调用Ping。Connect则相当于OpenPing。db, err sqlx.Connect(sqlite3, dsn)if err ! nil {fmt.Printf(connect DB failed, err:%v\n, err)return}// 最大连接数db.SetMaxOpenConns(100)// 最大空闲连接数db.SetMaxIdleConns(16)// 初始化方法,建表插入原始数据CreateRoleTable()CreateUserTable()return }添加建表方法(初始化权限表和用户表)// db\main.go package go_manager_dbimport (fmtgithub.com/jmoiron/sqlx_ github.com/mattn/go-sqlite3 )// 数据库相关操作 var db *sqlx.DB// 初始化数据库连接 func InitDB() (err error) {......} // 创建用户表 func CreateUserTable() error {sqlc : CREATE TABLE IF NOT EXISTS mal_user (-- sqlite 不能用 comment 添加注释id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT , -- 主键uname varchar(20) NOT NULL UNIQUE , -- 用户昵称upass varchar(50) NOT NULL, -- 密码(md5加密)rid INTEGER NOT NULL UNIQUE DEFAULT 1 -- 角色id); _, err : db.Exec(sqlc)if err ! nil {fmt.Println(err)return err}// 初始化表//因为有unique约束,所以不会重复添加// sqlStr : insert into mal_user(uname,upass,rid) values(?,?,?)Insert(mal_user, []string{uname, upass, rid}, admin, e120012d113ff6ea124a2493453c6dd5, 2)return nil }// 创建权限表 func CreateRoleTable() error {sqlc : CREATE TABLE IF NOT EXISTS mal_role (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, -- 主键 role varchar(20) NOT NULL UNIQUE DEFAULT user -- 角色(权限) ); _, err : db.Exec(sqlc)if err ! nil {return err}// 初始化表// 因为有unique约束,所以不会重复添加 // 有四种权限,id(自增)越大代表权限越大,rootsuperadminuserInsert(mal_role, []string{role}, user)Insert(mal_role, []string{role}, admin)Insert(mal_role, []string{role}, super)Insert(mal_role, []string{role}, root)return nil }base.go: 通用插入和删除方法// db\base.go package go_manager_dbimport (fmt_ github.com/mattn/go-sqlite3utils go_manager_utils )// 插入数据 func Insert(tableName string, params []string, datas ...interface{}) (err error) {// 拼接 表名(参数1,参数2,...)paramStr : utils.ParamsStr(params)// 拼接 values(?,?,...)values : utils.ValueStr(len(params))var sqlStr insert into tableName paramStr values valuesfmt.Println(sqlStr)_, err db.Exec(sqlStr, datas...) // 要用...展开if err ! nil {fmt.Println(err)fmt.Println(插入数据失败)return}return }// 删除数据 func Delete(tableName string, id int64) (err error) {sqlStr : delete from tableName where id?fmt.Println(sqlStr)_, err db.Exec(sqlStr, id)if err ! nil {fmt.Println(删除数据失败)return}return } model.go: 定义数据表对应的结构体package go_manager_db// 专门定义与数据库交互的结构体// 用户表 type MalUser struct {Id int64 db:id json:RdUname string db:uname json:UnameUpass string db:upass json:UpassRid int64 db:rid json:Rid } // 角色表 type MalRole struct {Id int64 db:id json:IdRole string db:role json:Role }mal_user.go和mal_role.go: 定义用户表和角色表的crud方法mal_user.gopackage go_manager_dbimport (fmt utils go_manager_utils_ github.com/mattn/go-sqlite3 )// 查数据 func GetAllUser() (users []*MalUser, err error) {sqlStr : select * from mal_user// 查询,记录到booklisterr db.Select(users, sqlStr)if err ! nil {fmt.Println(查询信息失败)fmt.Println(err)return}return }// 根据id查数据 func GetUserById(id int64) (user MalUser, err error) {// 如果返回的是指针,需要初始化//bookBook{}sqlStr : select * from mal_user where id?err db.Get(user, sqlStr, id)if err ! nil {fmt.Println(查询信息失败)return}return }// 根据name查数据 func GetUserByName(uname string, upass string) (user MalUser, err error) {sqlStr : select * from mal_user where uname? and upass?err db.Get(user, sqlStr, uname, upass)if err ! nil {fmt.Println(查询信息失败)return}return }// 根据id改 func UptUserById(uid string, params []string, datas ...interface{}) (err error) {// 拼接参数列表 xxx?,xxx?paramsStr : utils.UptParamsStr(params)// uid直接传字符串拼接sqlStr : update mal_role set paramsStr where id uid_, err db.Exec(sqlStr, datas...)if err ! nil {fmt.Println(修改信息失败)return}return }mal_role.gopackage go_manager_dbimport (fmt_ github.com/mattn/go-sqlite3 )// 应该id越大,权限越高,比较方便区分权限 // user admin super root // 查数据 func GetAllRole() (roles []*MalRole, err error) {sqlStr : select * from mal_role// 查询,记录到booklisterr db.Select(roles, sqlStr)if err ! nil {fmt.Println(查询信息失败)fmt.Println(err)return}return }// 根据id查数据 func GetRoleById(id int64) (role MalRole, err error) {// 如果返回的是指针,需要初始化//bookBook{}sqlStr : select * from mal_role where id?err db.Get(role, sqlStr, id)if err ! nil {fmt.Println(查询信息失败)return}return }// 根据id改数据 func UptRoleById(id int64, roleName string) (err error) {// 如果返回的是指针,需要初始化//bookBook{}sqlStr : update mal_role set role? where id?_, err db.Exec(sqlStr, roleName, id)if err ! nil {fmt.Println(修改信息失败)return}return }引入项目里的其他模块: utils在go.mod末尾添加replace go_manager_utils ../utils运行 go mod tidygo_manager_utils模块编写jwt.go: 编写加密方法,定时销毁token方法package go_manager_utilimport (crypto/md5fmtgopkg.in/square/go-jose.v2gopkg.in/square/go-jose.v2/jwttime )// sign 签名 // 传入密码,加密 func SignJWT(secret string, uname string, upass string) (jwtStr string) {key : []byte(secret)fmt.Println(secret)sig, err : jose.NewSigner(jose.SigningKey{Algorithm: jose.HS256, Key: key},(jose.SignerOptions{}).WithType(JWT))if err ! nil {panic(err)}cl : jwt.Claims{// Registered claims : 这里有一组预定义的声明它们不是强制的但是推荐// 比如iss (issuer), exp (expiration time), sub (subject), aud (audience)等。Issuer: uname,Subject: upass,NotBefore: jwt.NewNumericDate(time.Now()),Audience: jwt.Audience{name, admin},}raw, err : jwt.Signed(sig).Claims(cl).CompactSerialize()if err ! nil {panic(err)}// fmt.Println(raw)return raw }// 解析jwt // 传入key(之前加密的密码),raw(jwt令牌) func ParseJWT(key string, raw string) {var sharedKey []byte(key)tok, err : jwt.ParseSigned(raw)if err ! nil {panic(err)}out : jwt.Claims{}// 解析出issuer(uname)和subject(upass),校验if err : tok.Claims(sharedKey, out); err ! nil {panic(err)}fmt.Printf(iss: %s, sub: %s\n, out.Issuer, out.Subject) }// DM5加密 func MD5(str string) string {data : []byte(str) //切片has : md5.Sum(data)md5str : fmt.Sprintf(%x, has) //将[]byte转成16进制return md5str }// 销毁TokenMap的方法 // 定时销毁token(默认2小时) func DestoryTokenMap(tokenMap map[string]string) {for k : range tokenMap {delete(tokenMap, k)} }myTime.go: 定义定时器方法package go_manager_utilimport ( time )// 定义函数类型 type Fn func() error// 定时器中的成员 type MyTicker struct {MyTick *time.TickerRunner Fn } type MyTimer struct {MyTime *time.TimerRunner Fn }func NewMyTick(interval int, f Fn) *MyTicker {return MyTicker{MyTick: time.NewTicker(time.Duration(interval) * time.Second),Runner: f,} }// 一次性 func NewMyTimer(interval int, f Fn) *MyTimer {return MyTimer{MyTime: time.NewTimer(time.Duration(interval) * time.Second),Runner: f,} }// 启动定时器需要执行的任务 func (t *MyTicker) Start() {for {select {case -t.MyTick.C:t.Runner()}} }// 启动定时器需要执行的任务 func (t *MyTimer) Start() { select {case -t.MyTime.C:t.Runner()} }// func over() error { // fmt.Println(token过期) // return nil // } // 测试 // func main() { // t : NewMyTimer(2, over) // t.Start() // }res.go: 响应前端请求的方法package go_manager_utilimport (fmtgithub.com/gin-gonic/ginnet/http )/* 通用响应方法 */ func R(c *gin.Context, err error, msg interface{}, data interface{}) {// 如果有err,就说明是有错误,就返回错误响应(msg)if err ! nil {fmt.Println(err)c.JSON(http.StatusInternalServerError, gin.H{status: 500,msg: msg,})return}// 返回正确响应(data)c.JSON(http.StatusOK, gin.H{status: 200,msg: data,}) }stringUtils.go: 封装字符串操作方法package go_manager_utils// 拼接sql语句的value // len是语句有几个参数 func ValueStr(len int) (values string) {// 拼接 values(?,?,...)values (for i : 0; i len-1; i {values ?values ,}values ?values )return }// 拼接sql语句update的param // params是参数名数组 func UptParamsStr(params []string) (paramStr string) {// 拼接参数列表 xxx?,xxx?paramStr for i : 0; i len(params)-1; i {paramStr params[i]paramStr ?,}paramStr params[len(params)-1]paramStr ?return }// 拼接sql语句的param // params是参数名数组 func ParamsStr(params []string) (paramStr string) {// 拼接 表名(参数1,参数2,...)paramStr (for i : 0; i len(params)-1; i {paramStr params[i]paramStr ,}paramStr params[len(params)-1]paramStr )return }运行go mod tidy处理go文件里的依赖go_manager_web模块编写main.go: 主要逻辑,创建web实例,注册路由...package go_manager_webimport (fmtgithub.com/gin-gonic/gindb go_manager_dbutils go_manager_utilsnet/http )// 定义路由组 // 组中组(嵌套路由组) func DefineRouteGroup(fatherGroup *gin.RouterGroup, groupName string, r *gin.Engine) *gin.RouterGroup {var group *gin.RouterGroupif fatherGroup ! nil {// v1/groupNamegroup fatherGroup.Group(groupName)} else {// /groupNamegroup r.Group(groupName)}// 返回路由组return group }// 存放 token (不同ip不同token) var TokenMap make(map[string]string, 10)// 定时销毁token func timeDT() {// 两小时后销毁t : utils.NewMyTimer(2*60*60, func() error {utils.DestoryTokenMap(TokenMap)return nil})t.Start()fmt.Println(TokenMap) }// 路由和处理函数放在不同文件好像会使中间件失效 func Login(c *gin.Context) { user : db.MalUser{}// 绑定json和结构体(接收json,数据放入结构体)if err : c.BindJSON(user); err ! nil {return}uname : user.Unameupass : user.Upass userModel, err : db.GetUserByName(uname, upass)if err ! nil || userModel nil {fmt.Println(err)c.JSON(500, gin.H{status: 500,msg: 登录失败,})return} token : utils.SignJWT(malred, uname, upass)// 存入map// fmt.Println(c.ClientIP(),c.RemoteIP())TokenMap[c.ClientIP()] tokenfmt.Println(TokenMap)c.JSON(http.StatusOK, gin.H{status: 200,msg: 登录成功,// 返回jwt令牌(密码因为前端md5加密过,所以直接放入jwt)token: token,})go timeDT() }// 路由器 // 启动默认的路由 var r gin.Default()// user路由组 var v1 *gin.RouterGroupfunc Run() {// 使用中间件// 日志r.Use(gin.Logger())// 错误恢复r.Use(gin.Recovery())// 跨域r.Use(Core())// 阻止缓存响应r.Use(NoCache())// 安全设置r.Use(Secure())// 创建路由组v1v1 DefineRouteGroup(nil, v1, r)v1.POST(login, Login)// 注册user的路由registerUser(Token(), Core())// 注册role的路由registerRole(Token(), Core())// 启动webserver,监听本地127.0.0.1(默认)端口r.Run(:10101) }moddilewares.go: 中间件package go_manager_webimport ( utils go_manager_utilsnet/httpstrconvtimegithub.com/gin-gonic/gin )//解决跨域问题 func Core() gin.HandlerFunc {return func(c *gin.Context) {method : c.Request.Methodc.Header(Access-Control-Allow-Origin, *)c.Header(Access-Control-Allow-Headers, *)c.Header(Access-Control-Allow-Methods, *)c.Header(Access-Control-Expose-Headers, Content-Length,Access-Control-Allow-Origin,Access-Control-Allow-Headers,Content-Type)c.Header(Access-Control-Max-Age, 3600)c.Header(Access-Control-Allow-Credentials, true)//放行索引optionsif method OPTIONS {c.AbortWithStatus(http.StatusNoContent)}//处理请求c.Next()} }// 权限认证(验证token) func Token() gin.HandlerFunc {return func(c *gin.Context) {// for k, v : range c.Request.Header {// fmt.Println(k, v)// }secret : c.Request.Header[Secret] // 获取前端传来的secrettoken : c.Request.Header[Token]if len(token) 0 {// 验证不通过不再调用后续的函数处理c.Abort()c.JSON(http.StatusUnauthorized, gin.H{code: 401,message: 访问未授权,})return}timeInt64 : strconv.FormatInt(time.Now().UnixNano()/1e6/1000/60, 10)md5Str : utils.MD5(timeInt64 TokenMap[c.ClientIP()])// fmt.Println(TokenMap[c.ClientIP()], timeInt64)// fmt.Println(timeInt64 TokenMap[c.ClientIP()])// fmt.Println(md5Str, secret[0])if md5Str ! secret[0] {// 验证不通过不再调用后续的函数处理c.Abort()c.JSON(http.StatusUnauthorized, gin.H{code: 401,message: 访问未授权,})return}// 验证jwt// utils.ParseJWT(secret[0][8:11]secret[0][19:22], token[0])//处理请求c.Next()} }// 阻止缓存响应 func NoCache() gin.HandlerFunc {return func(ctx *gin.Context) {ctx.Header(Cache-Control, no-cache, no-store, max-age0, must-revalidate, value)ctx.Header(Expires, Thu, 01 Jan 1970 00:00:00 GMT)ctx.Header(Last-Modified, time.Now().UTC().Format(http.TimeFormat))ctx.Next()} }// 响应 options 请求, 并退出 // func Options() gin.HandlerFunc { // return func(ctx *gin.Context) { // if ctx.Request.Method ! OPTIONS { // ctx.Next() // } else { // ctx.Header(Access-Control-Allow-Origin, *) // ctx.Header(Access-Control-Allow-Methods, GET,POST,PUT,PATCH,DELETE,OPTIONS) // ctx.Header(Access-Control-Allow-Headers, authorization, origin, content-type, accept) // ctx.Header(Allow, HEAD,GET,POST,PUT,PATCH,DELETE,OPTIONS) // ctx.Header(Content-Type, application/json) // ctx.AbortWithStatus(200) // } // } // }// 安全设置 func Secure() gin.HandlerFunc {return func(ctx *gin.Context) {ctx.Header(Access-Control-Allow-Origin, *)ctx.Header(X-Frame-Options, DENY)ctx.Header(X-Content-Type-Options, nosniff)ctx.Header(X-XSS-Protection, 1; modeblock)if ctx.Request.TLS ! nil {ctx.Header(Strict-Transport-Security, max-age31536000)}// Also consider adding Content-Security-Policy headers// ctx.Header(Content-Security-Policy, script-src self https://cdnjs.cloudflare.com)} }// todo 权限控制(token携带当前用户的权限信息,过滤低于指定权限的请求)role.go和user.go: 真的role和user表的web操作role.gopackage go_manager_webimport (fmtdb go_manager_dbutils go_manager_utilsstrconv github.com/gin-gonic/gin )func GetAllRoleHandler(c *gin.Context) {roles, err : db.GetAllRole()// 通用响应utils.R(c, err, 获取角色列表失败, roles) } func AddRoleHandler(c *gin.Context) {// Role : c.PostForm(Role)// fmt.Println(Role)role : db.MalRole{}//绑定json和结构体if err : c.BindJSON(role); err ! nil {return}Role : role.Roleerr : db.Insert(mal_role, []string{role}, Role)// 通用响应utils.R(c, err, 添加角色失败, 添加角色成功) } func DelRoleHandler(c *gin.Context) {// 从url获取参数idStr : c.Query(rid)// fmt.Println(idStr)rid, err : strconv.ParseInt(idStr, 10, 64)err db.Delete(mal_role, rid)// 通用响应utils.R(c, err, 删除角色失败, 删除角色成功) } func GetOneRoleHandler(c *gin.Context) {// 从url获取参数idStr : c.Query(rid)fmt.Println(idStr)rid, _ : strconv.ParseInt(idStr, 10, 64)one, err2 : db.GetRoleById(rid)// 通用响应utils.R(c, err2, 查询角色失败, one) } func UptRoleHandler(c *gin.Context) {role : db.MalRole{}//绑定json和结构体if err : c.BindJSON(role); err ! nil {return} rid : role.IdroleName : role.Rolefmt.Println(role)err : db.UptRoleById(rid, roleName)// 通用响应utils.R(c, err, 修改角色失败, 修改角色成功) } func registerRole(middles ...gin.HandlerFunc) {// 创建路由组v1/userrole : DefineRouteGroup(v1, role, r)// 添加中间件if middles ! nil {role.Use(middles...)}// 获取所有role.GET(all, GetAllRoleHandler)// 添加role.POST(add, AddRoleHandler)// 删除role.DELETE(del, DelRoleHandler)// 根据id获取role.GET(id, GetOneRoleHandler)// 根据id修改role.PUT(upt, UptRoleHandler) }user.gopackage go_manager_webimport (fmtdb go_manager_dbutils go_manager_utilsstrconv github.com/gin-gonic/gin )func GetAllUserHandler(c *gin.Context) {users, err : db.GetAllUser()// 通用响应utils.R(c, err, 查询角色失败, users) } func AddUserHandler(c *gin.Context) {// uname : c.PostForm(uname)// upass : c.PostForm(upass)// idStr : c.PostForm(rid)user : db.MalUser{}//绑定json和结构体if err : c.BindJSON(user); err ! nil {return}uname : user.Unameupass : user.Upassrid : user.Ridfmt.Println(user)// rid, err : strconv.ParseInt(idStr, 10, 64)err : db.Insert(mal_user, []string{uname, upass, rid}, uname, upass, rid)// 通用响应utils.R(c, err, 添加角色失败, 添加角色成功) } func DelUserHandler(c *gin.Context) {// 从url获取参数idStr : c.Query(uid)// fmt.Println(idStr)uid, err : strconv.ParseInt(idStr, 10, 64)err db.Delete(mal_user, uid)// 通用响应utils.R(c, err, 删除角色失败, 删除角色成功) } func GetOneUserHandler(c *gin.Context) {// 从url获取参数idStr : c.Query(uid)fmt.Println(idStr)uid, _ : strconv.ParseInt(idStr, 10, 64)one, err2 : db.GetUserById(uid)// 通用响应utils.R(c, err2, 查询角色失败, one) } func UptUserHandler(c *gin.Context) {// 从url获取参数// uid : c.PostForm(uid)// uname : c.PostForm(uname)// upass : c.PostForm(upass)// ridStr : c.PostForm(rid)user : db.MalUser{}//绑定json和结构体if err : c.BindJSON(user); err ! nil {return}uname : user.Unameupass : user.Upassrid : user.Riduid : user.Id// fmt.Println(idStr, UserName)// rid, _ : strconv.ParseInt(ridStr, 10, 64)err : db.UptUserById(strconv.FormatInt(uid, 10), []string{uname, upass, rid}, uname, upass, rid)// 通用响应utils.R(c, err, 修改角色失败, 修改角色成功) } func registerUser(middles ...gin.HandlerFunc) {// 创建路由组v1/useruser : DefineRouteGroup(v1, user, r)// 添加中间件if middles ! nil {user.Use(middles...)}user.GET(all, GetAllUserHandler)// 添加user.POST(add, AddUserHandler)// 删除user.DELETE(del, DelUserHandler)// 根据id获取user.GET(id, GetOneUserHandler)// 根据id修改user.PUT(upt, UptUserHandler) }运行go mod tidy忘了,要引用项目里的其他包replace go_manager_utils ../utils replace go_manager_db ../dbgo mod tidy编写根目录的go_manager模块main.gopackage mainimport ( db go_manager_dbweb go_manager_web )func main() {// 初始化数据库db.InitDB() // 开启服务web.Run() }go.modmodule go_managergo 1.18replace go_manager_web ./webreplace go_manager_db ./dbreplace go_manager_utils ./utilsgo mod tidy测试(可以用go build打包)完整目录结构go run main.go因为后端存的密码是md5加密过的,所以前端也要传md5加密的密码,二者相同才能通过安全: 我的安全不咋地,加密的方法是前端根据当前时间戳(转为分钟,防止因为前后端延迟而导致时间戳不一致)登录后从后端获取的token来md5,每次请求都会验证这个md5(后端也加密(时间戳/60token)然后对比),这个就不测试了代码仓库: https://gitee.com/malguy/go-manager配套前端管理系统(react18):https://github.com/malred/base-manager
http://www.w-s-a.com/news/119758/

相关文章:

  • 如何创建网站乐清网络科技有限公司
  • 沈阳市网站制作艺术字体logo设计生成器
  • 网站设计常用软件都有哪些中国建设银行官方招聘网站
  • 证券投资网站建设视频直播怎么赚钱的
  • 建设酒店网站ppt模板下载郑州小程序设计外包
  • 网站建设自我总结google推广公司
  • 安全网站建设情况wordpress 评论表单
  • 网站建设发言材料个人网站推广软件
  • php建站软件哪个好南京哪家做网站好
  • 排名好的手机网站建设番禺网站建设专家
  • 番禺怎么读百度有专做优化的没
  • 网站开发中应注意哪些问题网络营销的主要特点
  • 网站定制案例北京网站制作招聘网
  • 网站建设与推广实训小结网站建设专业英文
  • 郑州网站建设动态凡科网站建设是免费的吗
  • 湖北手机网站建设wordpress转emlog博客
  • 北京东站设计网名的花样符号
  • 安徽建设厅网站首页网站开发aichengkeji
  • 自贡网站制作荣茂网站建设
  • 什么做的网站吗正规的机械外包加工订单网
  • 网络工程公司的业务邵阳seo快速排名
  • 博主怎么赚钱网站seo找准隐迅推
  • 营销号经典废话北京网站建设公司网站优化资讯
  • 一六八互联网站建设怎么做套版网站
  • wordpress 书站建筑公司简介范文大全
  • 建设官方网站多少鲜花网站建设的主要工作流程
  • 卖主机网站轻量wordpress主题
  • 网站建设规划书结构制作一个自己的网站
  • 外贸网站商城建设做网站和推广
  • 网站建设微信群免费简约ppt模板