[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-public-pgDLuOpz":3,"public-project-articles-pgDLuOpz":17},{"id":4,"uuid":5,"project_id":6,"title":7,"content":8,"type":9,"status":10,"public_enabled":10,"views":11,"sort":12,"created_at":13,"updated_at":14,"project_title":15,"project_slug":16},1087,"pgDLuOpz",54,"03. 开发普通用户信息管理功能","## SQL\n\n```sql\nCREATE TABLE `user` (\n  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID',\n  `username` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '账号',\n  `password` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '密码',\n  `name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '名称',\n  `avatar` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '头像',\n  `role` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '角色',\n  `phone` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '联系方式',\n  `email` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '邮箱',\n  PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='普通用户信息';\n```\n\n## 开发后端接口\n\n1. 开发实体类 entity （跟数据库的表的字段对应）\n2. 创建 controller（定义后端的 http 接口）\n3. 创建 Service（业务实现）\n4. 创建 Mapper（数据库操作的接口 增、删、改、查） 以及 Mapper.xml（sql 实现）\n\n\n\nUser.java\n\n```java\npackage com.example.entity;\n\n\u002F**\n * 普通用户\n*\u002F\npublic class User extends Account {\n\n    \u002F** ID *\u002F\n    private Integer id;\n    \u002F** 用户名 *\u002F\n    private String username;\n    \u002F** 密码 *\u002F\n    private String password;\n    \u002F** 姓名 *\u002F\n    private String name;\n    \u002F** 头像 *\u002F\n    private String avatar;\n    \u002F** 角色标识 *\u002F\n    private String role;\n    private String phone;\n    private String email;\n\n    public String getPhone() {\n        return phone;\n    }\n\n    public void setPhone(String phone) {\n        this.phone = phone;\n    }\n\n    public String getEmail() {\n        return email;\n    }\n\n    public void setEmail(String email) {\n        this.email = email;\n    }\n\n    @Override\n    public Integer getId() {\n        return id;\n    }\n\n    @Override\n    public void setId(Integer id) {\n        this.id = id;\n    }\n\n    @Override\n    public String getUsername() {\n        return username;\n    }\n\n    @Override\n    public void setUsername(String username) {\n        this.username = username;\n    }\n\n    @Override\n    public String getPassword() {\n        return password;\n    }\n\n    @Override\n    public void setPassword(String password) {\n        this.password = password;\n    }\n\n    @Override\n    public String getName() {\n        return name;\n    }\n\n    @Override\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    @Override\n    public String getAvatar() {\n        return avatar;\n    }\n\n    @Override\n    public void setAvatar(String avatar) {\n        this.avatar = avatar;\n    }\n\n    @Override\n    public String getRole() {\n        return role;\n    }\n\n    @Override\n    public void setRole(String role) {\n        this.role = role;\n    }\n}\n```\n\n\n\nUserMapper.xml\n\n```xml\n\u003C?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\u003C!DOCTYPE mapper\n        PUBLIC \"-\u002F\u002Fmybatis.org\u002F\u002FDTD Mapper 3.0\u002F\u002FEN\"\n        \"http:\u002F\u002Fmybatis.org\u002Fdtd\u002Fmybatis-3-mapper.dtd\">\n\u003Cmapper namespace=\"com.example.mapper.UserMapper\">\n\n    \u003Cselect id=\"selectAll\" resultType=\"com.example.entity.User\">\n        select * from `user`\n        \u003Cwhere>\n            \u003Cif test=\"name != null\"> and name like concat('%', #{name}, '%')\u003C\u002Fif>\n        \u003C\u002Fwhere>\n        order by id desc\n    \u003C\u002Fselect>\n\n    \u003Cinsert id=\"insert\" parameterType=\"com.example.entity.User\" useGeneratedKeys=\"true\">\n        insert into `user`(id, username, password, name, avatar, role, phone, email)\n        values (#{id}, #{username}, #{password}, #{name}, #{avatar}, #{role}, #{phone}, #{email})\n    \u003C\u002Finsert>\n\n    \u003Cupdate id=\"updateById\" parameterType=\"com.example.entity.User\">\n        update `user` set username = #{username}, password = #{password}, name = #{name}, avatar = #{avatar}, role = #{role},\n        phone = #{phone}, email = #{email}\n        where id = #{id} \n    \u003C\u002Fupdate>\n\n\u003C\u002Fmapper>\n```\n\n## 开发前端页面\n\n1. 创建 vue 页面\n2. 创建路由\n3. 配置菜单\n\n\n\nUser.vue\n\n```vue\n\u003Ctemplate>\n  \u003Cdiv>\n\n    \u003Cdiv class=\"card\" style=\"margin-bottom: 5px;\">\n      \u003Cel-input v-model=\"data.name\" style=\"width: 300px; margin-right: 10px\" placeholder=\"请输入名称查询\">\u003C\u002Fel-input>\n      \u003Cel-button type=\"primary\" @click=\"load\">查询\u003C\u002Fel-button>\n      \u003Cel-button type=\"info\" style=\"margin: 0 10px\" @click=\"reset\">重置\u003C\u002Fel-button>\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"card\" style=\"margin-bottom: 5px\">\n      \u003Cdiv style=\"margin-bottom: 10px\">\n        \u003Cel-button type=\"primary\" @click=\"handleAdd\">新增\u003C\u002Fel-button>\n      \u003C\u002Fdiv>\n      \u003Cel-table :data=\"data.tableData\" stripe>\n        \u003Cel-table-column label=\"用户名\" prop=\"username\">\u003C\u002Fel-table-column>\n        \u003Cel-table-column label=\"名称\" prop=\"name\">\u003C\u002Fel-table-column>\n        \u003Cel-table-column label=\"头像\">\n          \u003Ctemplate #default=\"scope\">\n            \u003Cel-image v-if=\"scope.row.avatar\" :src=\"scope.row.avatar\" preview-teleported :preview-src-list=\"[scope.row.avatar]\" style=\"width: 40px; height: 40px; border-radius: 50%\">\u003C\u002Fel-image>\n          \u003C\u002Ftemplate>\n        \u003C\u002Fel-table-column>\n        \u003Cel-table-column label=\"角色\" prop=\"role\">\u003C\u002Fel-table-column>\n        \u003Cel-table-column label=\"手机号\" prop=\"phone\">\u003C\u002Fel-table-column>\n        \u003Cel-table-column label=\"邮箱\" prop=\"email\">\u003C\u002Fel-table-column>\n        \u003Cel-table-column label=\"操作\" align=\"center\" width=\"160\">\n          \u003Ctemplate #default=\"scope\">\n            \u003Cel-button type=\"primary\" @click=\"handleEdit(scope.row)\">编辑\u003C\u002Fel-button>\n            \u003Cel-button type=\"danger\" @click=\"handleDelete(scope.row.id)\">删除\u003C\u002Fel-button>\n          \u003C\u002Ftemplate>\n        \u003C\u002Fel-table-column>\n      \u003C\u002Fel-table>\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"card\">\n      \u003Cel-pagination @current-change=\"load\" background layout=\"total, prev, pager, next\" v-model:page-size=\"data.pageSize\" v-model:current-page=\"data.pageNum\" :total=\"data.total\"\u002F>\n    \u003C\u002Fdiv>\n\n    \u003Cel-dialog title=\"普通用户信息\" width=\"40%\" v-model=\"data.formVisible\" :close-on-click-modal=\"false\" destroy-on-close>\n      \u003Cel-form ref=\"formRef\" :model=\"data.form\" :rules=\"data.rules\" label-width=\"100px\" style=\"padding-right: 50px\">\n        \u003Cel-form-item label=\"账号\" prop=\"username\">\n          \u003Cel-input :disabled=\"data.form.id > 0\" v-model=\"data.form.username\" autocomplete=\"off\" \u002F>\n        \u003C\u002Fel-form-item>\n        \u003Cel-form-item label=\"名称\" prop=\"name\">\n          \u003Cel-input v-model=\"data.form.name\" autocomplete=\"off\" \u002F>\n        \u003C\u002Fel-form-item>\n        \u003Cel-form-item label=\"头像\" prop=\"avatar\">\n          \u003Cel-upload :action=\"uploadUrl\" list-type=\"picture\" :on-success=\"handleImgSuccess\">\n            \u003Cel-button type=\"primary\">上传图片\u003C\u002Fel-button>\n          \u003C\u002Fel-upload>\n        \u003C\u002Fel-form-item>\n        \u003Cel-form-item label=\"手机号\" prop=\"phone\">\n          \u003Cel-input v-model=\"data.form.phone\" autocomplete=\"off\" \u002F>\n        \u003C\u002Fel-form-item>\n        \u003Cel-form-item label=\"邮箱\" prop=\"email\">\n          \u003Cel-input v-model=\"data.form.email\" autocomplete=\"off\" \u002F>\n        \u003C\u002Fel-form-item>\n      \u003C\u002Fel-form>\n      \u003Ctemplate #footer>\n      \u003Cspan class=\"dialog-footer\">\n        \u003Cel-button @click=\"data.formVisible = false\">取 消\u003C\u002Fel-button>\n        \u003Cel-button type=\"primary\" @click=\"save\">保 存\u003C\u002Fel-button>\n      \u003C\u002Fspan>\n      \u003C\u002Ftemplate>\n    \u003C\u002Fel-dialog>\n\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup>\nimport request from \"@\u002Futils\u002Frequest\";\nimport {reactive, ref} from \"vue\";\nimport {ElMessageBox, ElMessage} from \"element-plus\";\n\n\u002F\u002F 文件上传的接口地址\nconst uploadUrl = import.meta.env.VITE_BASE_URL + '\u002Ffiles\u002Fupload'\n\nconst formRef = ref()\nconst data = reactive({\n  user: JSON.parse(localStorage.getItem('system-user') || '{}'),\n  pageNum: 1,\n  pageSize: 10,\n  total: 0,\n  formVisible: false,\n  form: {},\n  tableData: [],\n  name: null,\n  rules: {\n    username: [\n      { required: true, message: '请输入账号', trigger: 'blur' }\n    ],\n    name: [\n      { required: true, message: '请输入名称', trigger: 'blur' }\n    ],\n    avatar: [\n      { required: true, message: '请上传头像', trigger: 'blur' }\n    ],\n    phone: [\n      { required: true, message: '请输入手机号', trigger: 'blur' }\n    ],\n    email: [\n      { required: true, message: '请输入邮箱', trigger: 'blur' }\n    ],\n  }\n})\n\n\u002F\u002F 分页查询\nconst load = () => {\n  request.get('\u002Fuser\u002FselectPage', {\n    params: {\n      pageNum: data.pageNum,\n      pageSize: data.pageSize,\n      name: data.name\n    }\n  }).then(res => {\n    data.tableData = res.data?.list\n    data.total = res.data?.total\n  })\n}\n\n\u002F\u002F 新增\nconst handleAdd = () => {\n  data.form = {}\n  data.formVisible = true\n}\n\n\u002F\u002F 编辑\nconst handleEdit = (row) => {\n  data.form = JSON.parse(JSON.stringify(row))\n  data.formVisible = true\n}\n\n\u002F\u002F 新增保存\nconst add = () => {\n  request.post('\u002Fuser\u002Fadd', data.form).then(res => {\n    if (res.code === '200') {\n      load()\n      ElMessage.success('操作成功')\n      data.formVisible = false\n    } else {\n      ElMessage.error(res.msg)\n    }\n  })\n}\n\n\u002F\u002F 编辑保存\nconst update = () => {\n  request.put('\u002Fuser\u002Fupdate', data.form).then(res => {\n    if (res.code === '200') {\n      load()\n      ElMessage.success('操作成功')\n      data.formVisible = false\n    } else {\n      ElMessage.error(res.msg)\n    }\n  })\n}\n\n\u002F\u002F 弹窗保存\nconst save = () => {\n  formRef.value.validate(valid => {\n    if (valid) {\n      \u002F\u002F data.form有id就是更新，没有就是新增\n      data.form.id ? update() : add()\n    }\n  })\n}\n\n\u002F\u002F 删除\nconst handleDelete = (id) => {\n  ElMessageBox.confirm('删除后数据无法恢复，您确定删除吗?', '删除确认', { type: 'warning' }).then(res => {\n    request.delete('\u002Fuser\u002Fdelete\u002F' + id).then(res => {\n      if (res.code === '200') {\n        load()\n        ElMessage.success('操作成功')\n      } else {\n        ElMessage.error(res.msg)\n      }\n    })\n  }).catch(err => {})\n}\n\n\u002F\u002F 重置\nconst reset = () => {\n  data.name = null\n  load()\n}\n\n\u002F\u002F 处理文件上传的钩子\nconst handleImgSuccess = (res) => {\n  data.form.avatar = res.data  \u002F\u002F res.data就是文件上传返回的文件路径，获取到路径后赋值表单的属性\n}\n\nload()\n\u003C\u002Fscript>\n```\n\n## Element-Plus 官方网站\n\n[https:\u002F\u002Felement-plus.org\u002Fzh-CN\u002F](https:\u002F\u002Felement-plus.org\u002Fzh-CN\u002F)\n\n\n\n\n\n\u003Cfont style=\"color:#bcbec4;background-color:#1e1f22;\">preview\u003C\u002Ffont>\n\n","coding",1,544,2121,"2025-12-09 16:59:38","2026-05-03 22:49:02","基于SpringBoot3+Vue3的校园物品分享系统","campus-item-sharing",{"project":18,"items":19},{"id":6,"title":15,"slug":16},[20,27,34,35,42,50,57,64,71,78,85,92,99],{"id":21,"uuid":22,"project_id":6,"title":23,"type":9,"status":10,"public_enabled":10,"views":24,"sort":25,"created_at":26,"updated_at":14,"project_title":15,"project_slug":16},1085,"bKvz3GMB","01. 校园物品分享系统介绍",1584,2118,"2026-04-01 22:12:21",{"id":28,"uuid":29,"project_id":6,"title":30,"type":9,"status":10,"public_enabled":10,"views":31,"sort":32,"created_at":33,"updated_at":14,"project_title":15,"project_slug":16},1086,"G7CRiFiL","02. 导入并运行项目脚手架",670,2119,"2025-12-09 16:59:49",{"id":4,"uuid":5,"project_id":6,"title":7,"type":9,"status":10,"public_enabled":10,"views":11,"sort":12,"created_at":13,"updated_at":14,"project_title":15,"project_slug":16},{"id":36,"uuid":37,"project_id":6,"title":38,"type":9,"status":10,"public_enabled":10,"views":39,"sort":40,"created_at":41,"updated_at":14,"project_title":15,"project_slug":16},1090,"2l7FVzgx","04. 开发普通用户登录、注册、个人信息、修改密码功能",365,2131,"2025-12-10 16:11:48",{"id":43,"uuid":44,"project_id":6,"title":45,"type":9,"status":10,"public_enabled":10,"views":46,"sort":47,"created_at":48,"updated_at":49,"project_title":15,"project_slug":16},1091,"l5SB4JYK","05. 开发系统公告管理功能",417,2132,"2025-12-10 16:12:08","2026-05-07 15:36:12.649662+00",{"id":51,"uuid":52,"project_id":6,"title":53,"type":9,"status":10,"public_enabled":10,"views":54,"sort":55,"created_at":56,"updated_at":14,"project_title":15,"project_slug":16},1098,"mXLOXdBC","06. 开发物品分类信息管理功能",297,2143,"2025-12-11 16:37:57",{"id":58,"uuid":59,"project_id":6,"title":60,"type":9,"status":10,"public_enabled":10,"views":61,"sort":62,"created_at":63,"updated_at":14,"project_title":15,"project_slug":16},1099,"nj87VT4L","07. 开发物品信息管理功能",406,2144,"2025-12-11 16:38:16",{"id":65,"uuid":66,"project_id":6,"title":67,"type":9,"status":10,"public_enabled":10,"views":68,"sort":69,"created_at":70,"updated_at":14,"project_title":15,"project_slug":16},1107,"nGHKfpf4","08. 开发用户端物品展示功能",329,2162,"2025-12-15 17:27:07",{"id":72,"uuid":73,"project_id":6,"title":74,"type":9,"status":10,"public_enabled":10,"views":75,"sort":76,"created_at":77,"updated_at":14,"project_title":15,"project_slug":16},1123,"A6caJxFd","09. 开发物品申请交换功能",322,2196,"2025-12-19 16:16:03",{"id":79,"uuid":80,"project_id":6,"title":81,"type":9,"status":10,"public_enabled":10,"views":82,"sort":83,"created_at":84,"updated_at":14,"project_title":15,"project_slug":16},1135,"s5I1gomY","10. 开发物品收藏功能",285,2223,"2025-12-23 17:38:15",{"id":86,"uuid":87,"project_id":6,"title":88,"type":9,"status":10,"public_enabled":10,"views":89,"sort":90,"created_at":91,"updated_at":14,"project_title":15,"project_slug":16},1159,"qadunvVA","11. 开发论坛帖子管理功能",263,2266,"2025-12-30 16:08:47",{"id":93,"uuid":94,"project_id":6,"title":95,"type":9,"status":10,"public_enabled":10,"views":96,"sort":97,"created_at":98,"updated_at":14,"project_title":15,"project_slug":16},1202,"CpPqHdiT","12. 开发论坛帖子展示功能",220,2339,"2026-01-19 17:04:21",{"id":100,"uuid":101,"project_id":6,"title":102,"type":9,"status":10,"public_enabled":10,"views":103,"sort":104,"created_at":105,"updated_at":14,"project_title":15,"project_slug":16},1203,"7YABYvbd","13. 开发论坛帖子点赞和评论功能",239,2340,"2026-01-19 17:04:37"]