[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-public-hi7dGSTj":3,"public-project-articles-hi7dGSTj":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},252,"hi7dGSTj",38,"11. 顾客信息管理","## user表\n\n```sql\nCREATE TABLE `user` (\n  `id` int(11) 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  `sex` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '性别',\n  `phone` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '手机号',\n  `account` decimal(10,2) DEFAULT '0.00' COMMENT '账户余额',\n  PRIMARY KEY (`id`)\n) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户信息';\n```\n\n404问题？\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\n    \u003Cinsert id=\"insert\">\n        insert into user (username, password, name, avatar, role, sex, phone)\n        values (#{username}, #{password}, #{name}, #{avatar}, #{role}, #{sex}, #{phone})\n    \u003C\u002Finsert>\n\n\n    \u003Cupdate id=\"updateById\">\n        update user\n        \u003Cset>\n            \u003Cif test=\"username != null\"> username = #{username}, \u003C\u002Fif>\n            \u003Cif test=\"password != null\"> password = #{password}, \u003C\u002Fif>\n            \u003Cif test=\"name != null\"> name = #{name}, \u003C\u002Fif>\n            \u003Cif test=\"avatar != null\"> avatar = #{avatar}, \u003C\u002Fif>\n            \u003Cif test=\"role != null\"> role = #{role}, \u003C\u002Fif>\n            \u003Cif test=\"sex != null\"> sex = #{sex}, \u003C\u002Fif>\n            \u003Cif test=\"phone != null\"> phone = #{phone}, \u003C\u002Fif>\n            \u003Cif test=\"account != null\"> account = #{account}, \u003C\u002Fif>\n        \u003C\u002Fset>\n        where id = #{id}\n    \u003C\u002Fupdate>\n\n    \u003Cdelete id=\"deleteById\">\n        delete from user where id = #{id}\n    \u003C\u002Fdelete>\n\n    \u003Cselect id=\"selectAll\" resultType=\"com.example.entity.User\">\n        select * from user\n        \u003Cwhere>\n            \u003Cif test=\"name != null\">\n                name like concat('%', #{name}, '%')\n            \u003C\u002Fif>\n        \u003C\u002Fwhere>\n        order by id desc\n    \u003C\u002Fselect>\n\n\n\u003C\u002Fmapper>\n```\n\nUserMapper\n\n```java\npackage com.example.mapper;\n\nimport com.example.entity.User;\nimport org.apache.ibatis.annotations.Select;\n\nimport java.util.List;\n\npublic interface UserMapper {\n\n\n    @Select(\"select * from user where username = #{username}\")\n    User selectByUsername(String username);\n\n    void insert(User user);\n\n    void deleteById(Integer id);\n\n    void updateById(User user);\n\n    @Select(\"select * from user where id = #{id}\")\n    User selectById(Integer id);\n\n    List\u003CUser> selectAll(String name);\n\n}\n```\n\nUserService\n\n```java\npackage com.example.service;\n\nimport cn.hutool.core.util.ObjectUtil;\nimport com.example.common.RoleEnum;\nimport com.example.entity.Account;\nimport com.example.entity.User;\nimport com.example.exception.CustomException;\nimport com.example.mapper.UserMapper;\nimport com.github.pagehelper.PageHelper;\nimport com.github.pagehelper.PageInfo;\nimport jakarta.annotation.Resource;\nimport org.springframework.stereotype.Service;\n\nimport java.util.List;\n\n@Service\npublic class UserService {\n\n    @Resource\n    UserMapper userMapper;\n\n\n    public Account login(Account account) {\n        String username = account.getUsername();\n        \u002F\u002F 根据账号查询数据\n        User dbUser = userMapper.selectByUsername(username);\n        if (dbUser == null) {\n            throw new CustomException(\"账号不存在\");\n        }\n        \u002F\u002F 校验密码\n        if (!dbUser.getPassword().equals(account.getPassword())) {\n            throw new CustomException(\"账号或者密码错误\");\n        }\n        return dbUser;\n    }\n\n    \u002F**\n     * 注册\n     *\u002F\n    public void register(User user) {\n        \u002F\u002F 1. 校验用户账号是否存在\n        User dbUser = userMapper.selectByUsername(user.getUsername());\n        if (dbUser != null) {\n            throw new CustomException(\"账号已存在\");\n        }\n        \u002F\u002F 校验密码是否为空\n        if (ObjectUtil.isEmpty(user.getPassword())) {\n            throw new CustomException(\"密码不能为空\");\n        }\n        if (ObjectUtil.isEmpty(user.getName())) {\n            user.setName(user.getUsername());  \u002F\u002F 设置用户的名称为账号名称\n        }\n        user.setRole(RoleEnum.USER.name());\n        userMapper.insert(user);\n    }\n\n    public void add(User user) {\n        User dbUser = userMapper.selectByUsername(user.getUsername());\n        if (dbUser != null) {\n            throw new CustomException(\"账号已存在\");\n        }\n        if (ObjectUtil.isEmpty(user.getPassword())) {\n            user.setPassword(\"123\");  \u002F\u002F 默认密码\n        }\n        if (ObjectUtil.isEmpty(user.getName())) {\n            user.setName(user.getUsername());\n        }\n        user.setRole(RoleEnum.USER.name());\n        userMapper.insert(user);\n    }\n\n    public void deleteById(Integer id) {\n        userMapper.deleteById(id);\n    }\n\n    public void deleteBatch(List\u003CInteger> ids) {\n        for (Integer id : ids) {\n            this.deleteById(id);\n        }\n    }\n\n    public void updateById(User user) {\n        userMapper.updateById(user);\n    }\n\n    public User selectById(Integer id) {\n        return userMapper.selectById(id);\n    }\n\n    public List\u003CUser> selectAll(String name) {\n        return userMapper.selectAll(name);\n    }\n\n    public PageInfo\u003CUser> selectPage(String name, Integer pageNum, Integer pageSize) {\n        PageHelper.startPage(pageNum, pageSize);\n        List\u003CUser> list = this.selectAll(name);\n        return PageInfo.of(list);\n    }\n\n}\n\n```\n\nUserController\n\n```java\npackage com.example.controller;\n\nimport com.example.common.Result;\nimport com.example.entity.User;\nimport com.example.service.UserService;\nimport com.github.pagehelper.PageInfo;\nimport jakarta.annotation.Resource;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\n\n@RestController\n@RequestMapping(\"\u002Fuser\")\npublic class UserController {\n\n    @Resource\n    UserService userService;\n\n    \u002F**\n     * 新增\n     *\u002F\n    @PostMapping(\"\u002Fadd\")\n    public Result add(@RequestBody User user) {\n        userService.add(user);\n        return Result.success();\n    }\n\n    \u002F**\n     * 删除\n     *\u002F\n    @DeleteMapping(\"\u002Fdelete\u002F{id}\")\n    public Result delete(@PathVariable Integer id) {\n        userService.deleteById(id);\n        return Result.success();\n    }\n\n    \u002F**\n     * 批量删除\n     *\u002F\n    @DeleteMapping(\"\u002Fdelete\u002Fbatch\")\n    public Result delete(@RequestBody List\u003CInteger> ids) {\n        userService.deleteBatch(ids);\n        return Result.success();\n    }\n\n    \u002F**\n     * 新增\n     *\u002F\n    @PutMapping(\"\u002Fupdate\")\n    public Result update(@RequestBody User user) {\n        userService.updateById(user);\n        return Result.success();\n    }\n\n    \u002F**\n     * 查询单个\n     *\u002F\n    @GetMapping(\"\u002FselectById\u002F{id}\")\n    public Result selectById(@PathVariable Integer id) {\n        User user = userService.selectById(id);\n        return Result.success(user);\n    }\n\n    \u002F**\n     * 查询所有\n     *\u002F\n    @GetMapping(\"\u002FselectAll\")\n    public Result selectAll(String name) {\n        List\u003CUser> list = userService.selectAll(name);\n        return Result.success(list);\n    }\n\n    \u002F**\n     * 查询所有\n     *\u002F\n    @GetMapping(\"\u002FselectPage\")\n    public Result selectPage(\n            String name,\n            @RequestParam(defaultValue = \"1\") Integer pageNum,\n            @RequestParam(defaultValue = \"10\") Integer pageSize) {\n        PageInfo\u003CUser> pageInfo = userService.selectPage(name, pageNum, pageSize);\n        return Result.success(pageInfo);\n    }\n\n}\n\n```\n\n## 前台Vue页面\n\n```vue\n\u003Ctemplate>\n  \u003Cdiv>\n\n    \u003Cdiv class=\"card\" style=\"margin-bottom: 10px;\">\n      \u003Cel-input prefix-icon=\"Search\" style=\"width: 300px; margin-right: 10px\" placeholder=\"请输入名称查询\" v-model=\"data.name\">\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: 10px\">\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\" style=\"width: 100%\">\n        \u003Cel-table-column prop=\"id\" label=\"序号\" width=\"70\"\u002F>\n        \u003Cel-table-column prop=\"username\" label=\"账号\"\u002F>\n        \u003Cel-table-column prop=\"name\" label=\"名称\"\u002F>\n        \u003Cel-table-column prop=\"avatar\" label=\"头像\">\n          \u003Ctemplate v-slot=\"scope\">\n            \u003Cimg v-if=\"scope.row.avatar\" :src=\"scope.row.avatar\" alt=\"\" style=\"width: 50px; height: 50px; border-radius: 50%\">\n          \u003C\u002Ftemplate>\n        \u003C\u002Fel-table-column>\n        \u003Cel-table-column prop=\"role\" label=\"角色\"\u002F>\n        \u003Cel-table-column prop=\"sex\" label=\"性别\"\u002F>\n        \u003Cel-table-column prop=\"phone\" label=\"手机号\"\u002F>\n        \u003Cel-table-column prop=\"account\" label=\"账号余额\"\u002F>\n        \u003Cel-table-column label=\"操作\" width=\"180\">\n          \u003Ctemplate #default=\"scope\">\n            \u003Cel-button type=\"primary\" @click=\"handleEdit(scope.row)\">编辑\u003C\u002Fel-button>\n            \u003Cel-button type=\"danger\" @click=\"del(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\" v-if=\"data.total\">\n      \u003Cel-pagination background layout=\"prev, pager, next\" @current-change=\"load\" :page-size=\"data.pageSize\" v-model:current-page=\"data.pageNum\" :total=\"data.total\"\u002F>\n    \u003C\u002Fdiv>\n\n    \u003Cel-dialog v-model=\"data.formVisible\" title=\"信息\" width=\"40%\" destroy-on-close>\n      \u003Cel-form :model=\"data.form\" label-width=\"100px\" style=\"padding-right: 50px\">\n        \u003Cel-form-item label=\"账号\">\n          \u003Cel-input v-model=\"data.form.username\" autocomplete=\"off\" :disabled=\"!!data.form.id\" \u002F>\n        \u003C\u002Fel-form-item>\n        \u003Cel-form-item label=\"名称\">\n          \u003Cel-input v-model=\"data.form.name\" autocomplete=\"off\" \u002F>\n        \u003C\u002Fel-form-item>\n        \u003Cel-form-item label=\"头像\">\n          \u003Cel-upload action=\"http:\u002F\u002Flocalhost:9090\u002Ffiles\u002Fupload\" :on-success=\"handleFileUpload\">\n            \u003Cel-button type=\"primary\">点击上传\u003C\u002Fel-button>\n          \u003C\u002Fel-upload>\n        \u003C\u002Fel-form-item>\n        \u003Cel-form-item label=\"性别\">\n          \u003Cel-radio-group v-model=\"data.form.sex\">\n            \u003Cel-radio label=\"男\">\u003C\u002Fel-radio>\n            \u003Cel-radio label=\"女\">\u003C\u002Fel-radio>\n          \u003C\u002Fel-radio-group>\n        \u003C\u002Fel-form-item>\n        \u003Cel-form-item label=\"手机号\">\n          \u003Cel-input v-model=\"data.form.phone\" 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 {reactive} from \"vue\"\nimport request from \"@\u002Futils\u002Frequest\";\nimport {ElMessage, ElMessageBox} from \"element-plus\";\n\nconst data = reactive({\n  tableData: [],\n  total: 0,\n  pageNum: 1,  \u002F\u002F 当前的页码\n  pageSize: 5,  \u002F\u002F 每页的个数\n  formVisible: false,\n  form: {},\n  name: '',\n})\n\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\nload()\n\nconst reset = () => {\n  data.name = null\n  load()\n}\n\nconst handleAdd = () => {\n  data.form = {}  \u002F\u002F 初始化表单\n  data.formVisible = true  \u002F\u002F 打开弹窗\n}\n\n\u002F\u002F 保存数据\nconst save = () => {\n  request.request({\n    method: data.form.id ? 'PUT' : 'POST',\n    url: data.form.id ? '\u002Fuser\u002Fupdate' : '\u002Fuser\u002Fadd',\n    data: data.form\n  }).then(res => {\n    if (res.code === '200') {  \u002F\u002F成功\n      ElMessage.success('操作成功')\n      data.formVisible = false \u002F\u002F 关闭弹窗\n      load()  \u002F\u002F 重新加载表格数据\n    } else {\n      ElMessage.error(res.msg)\n    }\n  })\n}\n\nconst handleEdit = (row) => {\n  data.form = JSON.parse(JSON.stringify(row))\n  data.formVisible = true\n}\n\nconst del = (id) => {\n  ElMessageBox.confirm('删除后数据无法恢复，您确认删除吗？', '确认删除', { type: 'warning' }).then(res => {\n    request.delete('\u002Fuser\u002Fdelete\u002F' + id).then(res => {\n      if (res.code === '200') {  \u002F\u002F成功\n        ElMessage.success('操作成功')\n        load()  \u002F\u002F 重新加载表格数据\n      } else {\n        ElMessage.error(res.msg)\n      }\n    })\n  }).catch(err => {\n    console.log(err)\n  })\n}\n\nconst handleFileUpload = (file) => {\n  data.form.avatar = file.data\n}\n\n\u003C\u002Fscript>\n```","coding",1,643,431,"2024-06-20 15:59:16","2026-05-03 22:49:02","SpringBoot3+Vue3的在线点餐系统","online-ordering",{"project":18,"items":19},{"id":6,"title":15,"slug":16},[20,27,34,41,48,55,62,69,76,83,90,91,98,105,112,119],{"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},58,"JOJVoOQd","01. 在线点餐系统介绍",2745,102,"2025-01-09 09:49:39",{"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},59,"Tt7tzqbb","02. 脚手架介绍",2364,103,"2025-01-09 09:54:51",{"id":35,"uuid":36,"project_id":6,"title":37,"type":9,"status":10,"public_enabled":10,"views":38,"sort":39,"created_at":40,"updated_at":14,"project_title":15,"project_slug":16},60,"h74qSg8n","03. 开发登录功能",1974,104,"2024-04-16 02:30:00",{"id":42,"uuid":43,"project_id":6,"title":44,"type":9,"status":10,"public_enabled":10,"views":45,"sort":46,"created_at":47,"updated_at":14,"project_title":15,"project_slug":16},61,"uv8MFWZg","04. 开发后台登录接口",1729,105,"2024-04-16 02:29:56",{"id":49,"uuid":50,"project_id":6,"title":51,"type":9,"status":10,"public_enabled":10,"views":52,"sort":53,"created_at":54,"updated_at":14,"project_title":15,"project_slug":16},62,"jd2xjxUG","05. 开发普通用户登录功能",1145,106,"2024-04-16 02:29:27",{"id":56,"uuid":57,"project_id":6,"title":58,"type":9,"status":10,"public_enabled":10,"views":59,"sort":60,"created_at":61,"updated_at":14,"project_title":15,"project_slug":16},63,"TnvWfP4t","06. 开发普通用户注册功能",861,107,"2024-04-16 02:29:23",{"id":63,"uuid":64,"project_id":6,"title":65,"type":9,"status":10,"public_enabled":10,"views":66,"sort":67,"created_at":68,"updated_at":14,"project_title":15,"project_slug":16},64,"j9QNZGZU","07. 开发管理员后台接口",873,108,"2024-04-16 02:29:17",{"id":70,"uuid":71,"project_id":6,"title":72,"type":9,"status":10,"public_enabled":10,"views":73,"sort":74,"created_at":75,"updated_at":14,"project_title":15,"project_slug":16},65,"Sle0aiDs","08. 开发管理员管理页面并对接后台接口",821,109,"2024-04-16 02:29:13",{"id":77,"uuid":78,"project_id":6,"title":79,"type":9,"status":10,"public_enabled":10,"views":80,"sort":81,"created_at":82,"updated_at":14,"project_title":15,"project_slug":16},66,"msAf9SFh","09. 开发文件上传功能",659,110,"2024-04-16 02:29:09",{"id":84,"uuid":85,"project_id":6,"title":86,"type":9,"status":10,"public_enabled":10,"views":87,"sort":88,"created_at":89,"updated_at":14,"project_title":15,"project_slug":16},67,"8FBiQ4ue","10. 个人资料管理",736,111,"2024-04-16 02:29:06",{"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":92,"uuid":93,"project_id":6,"title":94,"type":9,"status":10,"public_enabled":10,"views":95,"sort":96,"created_at":97,"updated_at":14,"project_title":15,"project_slug":16},253,"2vquH0pr","12. 餐桌管理",879,432,"2024-06-03 22:12:16",{"id":99,"uuid":100,"project_id":6,"title":101,"type":9,"status":10,"public_enabled":10,"views":102,"sort":103,"created_at":104,"updated_at":14,"project_title":15,"project_slug":16},254,"F8DqfdBe","13. 开发餐品管理功能.",731,433,"2024-06-03 22:12:43",{"id":106,"uuid":107,"project_id":6,"title":108,"type":9,"status":10,"public_enabled":10,"views":109,"sort":110,"created_at":111,"updated_at":14,"project_title":15,"project_slug":16},275,"G20uzwaW","14. 开发在线点餐功能（一）",768,467,"2024-06-27 12:21:02",{"id":113,"uuid":114,"project_id":6,"title":115,"type":9,"status":10,"public_enabled":10,"views":116,"sort":117,"created_at":118,"updated_at":14,"project_title":15,"project_slug":16},276,"0bl3zvbT","15. 开发在线点餐功能（二）",609,468,"2024-06-27 12:21:30",{"id":120,"uuid":121,"project_id":6,"title":122,"type":9,"status":10,"public_enabled":10,"views":123,"sort":124,"created_at":125,"updated_at":14,"project_title":15,"project_slug":16},277,"AUgPvs9x","16. 开发在线点餐功能（三）",716,469,"2024-06-27 12:22:01"]