彩虹女神跃长空,Go语言进阶之Go语言高性能Web框架Iris项目实战-完善用户管 ...

火影  金牌会员 | 2022-9-16 17:22:55 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 547|帖子 547|积分 1641

书接上回,上一回我们完成了用户管理页面的构建,并且通过前端的Vue.js框架动态地获取表单数据,同时异步请求后端Iris接口进行入库操作,过程中使用函数封装可复用的逻辑。 本回我们将继续完善用户管理功能。
唯一索引

虽然在之前的章节中已经完成了用户添加(注册)的功能,然而我们忽略了一个重要的细节,那就是用户名(username)应该是全局唯一的字段,而添加逻辑中并未做唯一性校验,事实上唯一性校验有两种方案,一种是入库之前做一次查询,但这样会浪费一次磁盘的IO操作,另外一种就是通过唯一索引进行拦截操作,这里我们采用后者,修改model.go文件:
  1. package model  
  2.   
  3. import (  
  4.         "time"  
  5.   
  6.         "github.com/jinzhu/gorm"  
  7. )  
  8.   
  9. type Model struct {  
  10.         ID        uint `gorm:"primary_key"`  
  11.         CreatedAt time.Time  
  12.         UpdatedAt time.Time  
  13.         DeletedAt *time.Time  
  14. }  
  15.   
  16. type User struct {  
  17.         gorm.Model  
  18.         Username string `gorm:"unique;not null"`  
  19.         Password string  
  20. }
复制代码
这里为User结构体的字段Username添加unique索引,随后将user表删除,重新进行数据库迁移操作:
  1. db.AutoMigrate(&model.User{})
复制代码
接着查看表结构:
  1. MySQL [irisblog]> SHOW CREATE TABLE user;  
  2. +-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+  
  3. | Table | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |  
  4. +-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+  
  5. | user  | CREATE TABLE `user` (  
  6.   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,  
  7.   `created_at` datetime DEFAULT NULL,  
  8.   `updated_at` datetime DEFAULT NULL,  
  9.   `deleted_at` datetime DEFAULT NULL,  
  10.   `username` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,  
  11.   `password` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,  
  12.   PRIMARY KEY (`id`),  
  13.   UNIQUE KEY `username` (`username`),  
  14.   KEY `idx_user_deleted_at` (`deleted_at`)  
  15. ) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci |  
  16. +-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+  
  17. 1 row in set (0.00 sec)
复制代码
发现username字段已经被Gorm添加了唯一索引:UNIQUE KEY `username` (`username`)
随后修改用户添加逻辑:
  1. app.Post("/admin/user_action/", func(ctx iris.Context) {  
  2.   
  3.                 username := ctx.PostValue("username")  
  4.                 password := ctx.PostValue("password")  
  5.   
  6.                 fmt.Println(username, password)  
  7.   
  8.                 md5str := mytool.Make_password(password)  
  9.   
  10.                 user := &model.User{Username: username, Password: md5str}  
  11.                 res := db.Create(user)  
  12.   
  13.                 if res.Error != nil {  
  14.   
  15.                         fmt.Println(res.Error)  
  16.   
  17.                         ret := map[string]string{  
  18.                                 "errcode": "1",  
  19.                                 "msg":     "用户名不能重复",  
  20.                         }  
  21.                         ctx.JSON(ret)  
  22.   
  23.                         return  
  24.   
  25.                 }  
  26.   
  27.                 ret := map[string]string{  
  28.                         "errcode": "0",  
  29.                         "msg":     "ok",  
  30.                 }  
  31.                 ctx.JSON(ret)  
  32.   
  33.         })
复制代码
这里res结构体中的Error字段来返回错误,如果Error不等于nil,说明被唯一索引拦截了下来。
随后构建 ret 字典,声明错误码和提示信息,然后使用ctx.JSON函数序列化为Json格式返回给前端,注意别忘了用return关键字结束逻辑,否则代码会继续执行,返回值样例:
  1. {  
  2. errcode: "1",  
  3. msg: "用户名不能重复"  
  4. }
复制代码
前端接收到返回值之后,可以通过alert方法打印返回值:
  1. submit:function(){  
  2.   
  3.   
  4.                     this.myaxios("http://localhost:5000/admin/user_action/","post",{"username":this.username,"password":this.password}).then(data => {  
  5.         console.log(data)  
  6.                         alert(data.msg);  
  7.       });  
  8.   
  9.                 }
复制代码
如图所示:

用户更新与删除

用户更新指的是密码的修改,首先需要构造新密码的表单变量:
  1. data() {  
  2.                 return {  
  3.                     //用户名  
  4.                     username: "",  
  5.                     //密码  
  6.                     password:"",  
  7.                     //用户列表  
  8.                     userlist:[],  
  9.                     //新密码  
  10.                     newpass:[]  
  11.                 };  
  12.             },
复制代码
注意,这里是动态表单,因为每一个表单会对应一个用户:
  1. for(let i=0,l=this.userlist.length;i<l;i++){  
  2.   
  3.             this.newpass.push({"value":""})  
  4.   
  5.         }
复制代码
这里传递的参数是用户id以及用户的新密码,注意请求方式使用Put。
随后在后端Iris中添加更新逻辑:
  1. <table >  
  2.   
  3.                 <tr>  
  4.                     <th>用户id</th>  
  5.                     <th>用户名</th>  
  6.                     <th>新密码</th>  
  7.                     <th>添加时间</th>  
  8.                     <th>操作</th>  
  9.                 </tr>  
  10.   
  11.                 <tr v-for="(item,index) in userlist">  
  12.                     <td>{{ item.ID }}</td>  
  13.                     <td>{{ item.Username }}</td>  
  14.                     <td><input type="password" v-model="newpass[index].value"  /></td>  
  15.                     <td>{{ item.CreatedAt }}</td>  
  16.                     <td><button @click="update(index)">更新密码</button></td>  
  17.                 </tr>  
  18.   
  19.   
  20.   
  21.             </table>
复制代码
这里使用Put函数监听路由,随后接受参数ID和Password,注意Put和Post方式都采用ctx.PostValue函数来获取参数。
接着使用db.First(&user, ID)函数来进行主键查询,查出用户的结构体变量对象,最后调用db.Save函数来存储更新结果:
  1. update:function(i){  
  2.   
  3.                     console.log(this.userlist[i].ID);  
  4.                     console.log(this.newpass[i].value);  
  5.   
  6.                     if(this.newpass[i].value == ""){  
  7.                         alert("新密码不能为空");  
  8.                         return false;  
  9.                     }  
  10.   
  11.                     this.myaxios("http://localhost:5000/admin/user_action/","put",{"id":this.userlist[i].ID,"password":this.newpass[i].value}).then(data => {  
  12.                         console.log(data)  
  13.                         alert(data.msg);  
  14.       });  
  15.   
  16.   
  17.                 }
复制代码
可以看到,password和updated_at两个字段已经同步更新了。
接着是删除操作,首先前端添加删除按钮:
  1. app.Put("/admin/user_action/", func(ctx iris.Context) {  
  2.   
  3.                 ID := ctx.PostValue("id")  
  4.                 Password := ctx.PostValue("password")  
  5.   
  6.                 user := &model.User{}  
  7.                 db.First(&user, ID)  
  8.   
  9.                 user.Password = mytool.Make_password(Password)  
  10.                 db.Save(&user)  
  11.   
  12.                 ret := map[string]string{  
  13.                         "errcode": "0",  
  14.                         "msg":     "更新密码成功",  
  15.                 }  
  16.                 ctx.JSON(ret)  
  17.   
  18.         })
复制代码
随后绑定删除事件:
  1. MySQL [irisblog]> select * from user where id = 16\G  
  2. *************************** 1. row ***************************  
  3.         id: 16  
  4. created_at: 2022-08-22 19:41:40  
  5. updated_at: 2022-08-23 15:41:09  
  6. deleted_at: NULL  
  7.   username: admin  
  8.   password: 202cb962ac59075b964b07152d234b70  
  9. 1 row in set (0.00 sec)  
  10.   
  11. MySQL [irisblog]>
复制代码
注意这里的请求方式是delete。
如图所示:

随后编写后端删除逻辑:
  1. <tr v-for="(item,index) in userlist">  
  2.                     <td>{{ item.ID }}</td>  
  3.                     <td>{{ item.Username }}</td>  
  4.                     <td><input type="password" v-model="newpass[index].value"  /></td>  
  5.                     <td>{{ item.CreatedAt }}</td>  
  6.                    <td>
  7.                           
  8.                           
  9.                     <button @click="update(index)">更新密码</button>  
  10.   
  11.                      
  12.   
  13.                     <button @click="del(index)">删除用户</button>  
  14.                      
  15.                      
  16.                     </td>
  17.                 </tr>
复制代码
这里使用Delete函数来监听路由,同时通过ctx.URLParamIntDefault函数获取前端请求的参数,注意Get和Delete方式获取参数的请求函数是一致的,同理,Post方式和Put方式也是相同的。
接着使用db.Delete(&model.User{}, ID)函数通过用户结构体做主键删除。
结语

至此,完成了用户结构体的增:用户添加(唯一索引拦截);删(主键删除);改(动态表单绑定修改密码);查(结构体单项和批量查询)。该项目已开源在Github:https://github.com/zcxey2911/IrisBlog ,与君共觞,和君共勉。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

火影

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表