[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-public-BDvVa4By":3,"public-project-articles-BDvVa4By":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},49,"BDvVa4By",39,"16. SpringBoot+Vue管理系统实现增删改查","\n## 使用 Mybatis-plus\n\n官网：[https:\u002F\u002Fwww.baomidou.com\u002Fpages\u002F226c21\u002F](https:\u002F\u002Fwww.baomidou.com\u002Fpages\u002F226c21\u002F)\n\npom 依赖\n\n```xml\n\u003C!-- mybatis-plus -->\n\u003Cdependency>\n    \u003CgroupId>com.baomidou\u003C\u002FgroupId>\n    \u003CartifactId>mybatis-plus-boot-starter\u003C\u002FartifactId>\n    \u003Cversion>3.5.3.2\u003C\u002Fversion>\n\u003C\u002Fdependency>\n```\n\n实体类注解：\n\n- @TableName(\"user\")\n- @TableId(type=IdType.AUTO)\n\n分页插件\n\n```java\nimport com.baomidou.mybatisplus.annotation.DbType;\nimport com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;\nimport com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;\nimport org.mybatis.spring.annotation.MapperScan;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\n@MapperScan(\"com.example.springboot.mapper\")\npublic class MybatisPlusConfig {\n\n    \u002F**\n     * 添加分页插件\n     *\u002F\n    @Bean\n    public MybatisPlusInterceptor mybatisPlusInterceptor() {\n        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();\n        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));\u002F\u002F如果配置多个插件,切记分页最后添加\n        return interceptor;\n    }\n}\n```\n\n注意，你的实体类里面多出来的字段需要加上一个注解：@TableField(exist = false)\n![image.png](https:\u002F\u002Fcdn.nlark.com\u002Fyuque\u002F0\u002F2023\u002Fpng\u002F751015\u002F1693831619026-c7f75788-596b-4361-93ac-eaf50b679b84.png#averageHue=%232e2c2b&clientId=ucbf82d3e-04b6-4&from=paste&height=446&id=u60bd6e15&originHeight=558&originWidth=603&originalType=binary&ratio=1.25&rotation=0&showTitle=false&size=53428&status=done&style=none&taskId=u9531dffd-fdcd-4fa8-b0c6-88da53959df&title=&width=482.4)\n\n改造 Mapper\n\n```java\nimport com.baomidou.mybatisplus.core.mapper.BaseMapper;\nimport com.example.springboot.entity.User;\n\npublic interface UserMapper extends BaseMapper\u003CUser> {\n\n}\n```\n\n改造 Service\n\n```java\npackage com.example.springboot.service;\n\nimport com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;\nimport com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;\nimport com.example.springboot.entity.User;\nimport com.example.springboot.exception.ServiceException;\nimport com.example.springboot.mapper.UserMapper;\nimport com.example.springboot.utils.TokenUtils;\nimport org.springframework.stereotype.Service;\n\nimport javax.annotation.Resource;\n\n@Service\npublic class UserService extends ServiceImpl\u003CUserMapper, User> {\n\n    @Resource\n    UserMapper userMapper;\n\n    public User selectByUsername(String username) {\n        QueryWrapper\u003CUser> queryWrapper = new QueryWrapper\u003C>();\n        queryWrapper.eq(\"username\", username);  \u002F\u002F  eq => ==   where username = #{username}\n        \u002F\u002F 根据用户名查询数据库的用户信息\n        return getOne(queryWrapper); \u002F\u002F  select * from user where username = #{username}\n    }\n\n    \u002F\u002F 验证用户账户是否合法\n    public User login(User user) {\n        User dbUser = selectByUsername(user.getUsername());\n        if (dbUser == null) {\n            \u002F\u002F 抛出一个自定义的异常\n            throw new ServiceException(\"用户名或密码错误\");\n        }\n        if (!user.getPassword().equals(dbUser.getPassword())) {\n            throw new ServiceException(\"用户名或密码错误\");\n        }\n        \u002F\u002F 生成token\n        String token = TokenUtils.createToken(dbUser.getId().toString(), dbUser.getPassword());\n        dbUser.setToken(token);\n        return dbUser;\n    }\n\n    public User register(User user) {\n        User dbUser = selectByUsername(user.getUsername());\n        if (dbUser != null) {\n            \u002F\u002F 抛出一个自定义的异常\n            throw new ServiceException(\"用户名已存在\");\n        }\n        user.setName(user.getUsername());\n        userMapper.insert(user);\n        return user;\n    }\n\n    public void resetPassword(User user) {\n        User dbUser = selectByUsername(user.getUsername());\n        if (dbUser == null) {\n            \u002F\u002F 抛出一个自定义的异常\n            throw new ServiceException(\"用户不存在\");\n        }\n        if (!user.getPhone().equals(dbUser.getPhone())) {\n            throw new ServiceException(\"验证错误\");\n        }\n        dbUser.setPassword(\"123\");   \u002F\u002F 重置密码\n        updateById(dbUser);\n    }\n}\n\n```\n\n改造 Controller\n\n```java\npackage com.example.springboot.controller;\n\nimport cn.hutool.core.util.StrUtil;\nimport com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;\nimport com.baomidou.mybatisplus.core.metadata.IPage;\nimport com.baomidou.mybatisplus.extension.plugins.pagination.Page;\nimport com.example.springboot.common.Result;\nimport com.example.springboot.entity.User;\nimport com.example.springboot.service.UserService;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.dao.DuplicateKeyException;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\n\n@CrossOrigin\n@RestController\n@RequestMapping(\"\u002Fuser\")\npublic class UserController {\n\n    @Autowired\n    UserService userService;\n\n    \u002F**\n     * 新增用户信息\n     *\u002F\n    @PostMapping(\"\u002Fadd\")\n    public Result add(@RequestBody User user) {\n        try {\n            userService.save(user);\n        } catch (Exception e) {\n            if (e instanceof DuplicateKeyException) {\n                return Result.error(\"插入数据库错误\");\n            } else {\n                return Result.error(\"系统错误\");\n            }\n        }\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    @DeleteMapping(\"\u002Fdelete\u002F{id}\")\n    public Result delete(@PathVariable Integer id) {\n        userService.removeById(id);\n        return Result.success();\n    }\n\n\n    \u002F**\n     * 批量删除用户信息\n     *\u002F\n    @DeleteMapping(\"\u002Fdelete\u002Fbatch\")\n    public Result batchDelete(@RequestBody List\u003CInteger> ids) {  \u002F\u002F  [7, 8]\n        userService.removeBatchByIds(ids);\n        return Result.success();\n    }\n\n    \u002F**\n     * 查询全部用户信息\n     *\u002F\n    @GetMapping(\"\u002FselectAll\")\n    public Result selectAll() {\n        List\u003CUser> userList = userService.list(new QueryWrapper\u003CUser>().orderByDesc(\"id\"));  \u002F\u002F select * from user order by id desc\n        return Result.success(userList);\n    }\n\n    \u002F**\n     * 根据ID查询用户信息\n     *\u002F\n    @GetMapping(\"\u002FselectById\u002F{id}\")\n    public Result selectById(@PathVariable Integer id) {\n        User user = userService.getById(id);\n        return Result.success(user);\n    }\n\n\n    \u002F**\n     * 多条件模糊查询用户信息\n     * pageNum 当前的页码\n     * pageSize 每页查询的个数\n     *\u002F\n    @GetMapping(\"\u002FselectByPage\")\n    public Result selectByPage(@RequestParam Integer pageNum,\n                               @RequestParam Integer pageSize,\n                               @RequestParam String username,\n                               @RequestParam String name) {\n        QueryWrapper\u003CUser> queryWrapper = new QueryWrapper\u003CUser>().orderByDesc(\"id\");\n        queryWrapper.like(StrUtil.isNotBlank(username), \"username\", username);\n        queryWrapper.like(StrUtil.isNotBlank(name), \"name\", name);\n        \u002F\u002F select * from user where username like '%#{username}%' and name like '%#{name}%'\n        Page\u003CUser> page = userService.page(new Page\u003C>(pageNum, pageSize), queryWrapper);\n        return Result.success(page);\n    }\n\n}\n\n```\n\n## 开始编写 Vue 的增删改查\n\n报错\n![image.png](https:\u002F\u002Fcdn.nlark.com\u002Fyuque\u002F0\u002F2023\u002Fpng\u002F751015\u002F1693834006107-4483d87e-1083-48b0-b3d5-498495cba7ca.png#averageHue=%23020507&clientId=ucbf82d3e-04b6-4&from=paste&height=347&id=u7d15174d&originHeight=434&originWidth=1808&originalType=binary&ratio=1.25&rotation=0&showTitle=false&size=79641&status=done&style=none&taskId=ub003c31a-7df7-4b27-9d58-98d5289ee73&title=&width=1446.4)\n![image.png](https:\u002F\u002Fcdn.nlark.com\u002Fyuque\u002F0\u002F2023\u002Fpng\u002F751015\u002F1693834022917-fb5fa4cc-2197-4399-ab0a-f2edac0dd144.png#averageHue=%23cdefd2&clientId=ucbf82d3e-04b6-4&from=paste&height=278&id=uff2f765d&originHeight=348&originWidth=1345&originalType=binary&ratio=1.25&rotation=0&showTitle=false&size=42390&status=done&style=none&taskId=ub7789622-b71f-400c-b5bc-2bdbb6a8176&title=&width=1076)\n需要这样的一个参数 pageSize，但是没传 所以报错了\n![image.png](https:\u002F\u002Fcdn.nlark.com\u002Fyuque\u002F0\u002F2023\u002Fpng\u002F751015\u002F1693834054009-910b817a-e8e4-451d-87a8-5f4723fadd2b.png#averageHue=%23342f2e&clientId=ucbf82d3e-04b6-4&from=paste&height=304&id=u3867ec95&originHeight=380&originWidth=1803&originalType=binary&ratio=1.25&rotation=0&showTitle=false&size=141713&status=done&style=none&taskId=u45f646f8-be18-4bad-9718-d38a6a73ec9&title=&width=1442.4)\n![image.png](https:\u002F\u002Fcdn.nlark.com\u002Fyuque\u002F0\u002F2023\u002Fpng\u002F751015\u002F1693834097129-cb9fb6f1-a540-4c30-8388-88c5253775b8.png#averageHue=%23ebc895&clientId=ucbf82d3e-04b6-4&from=paste&height=223&id=u309b42dd&originHeight=279&originWidth=1106&originalType=binary&ratio=1.25&rotation=0&showTitle=false&size=19461&status=done&style=none&taskId=uee33580c-71ab-4c8e-a6a6-bd01e06ebf9&title=&width=884.8)\n\n错误：\n![image.png](https:\u002F\u002Fcdn.nlark.com\u002Fyuque\u002F0\u002F2023\u002Fpng\u002F751015\u002F1693835698533-a0da35a4-0b79-42ae-90d0-79ee7a8e2245.png#averageHue=%23312e2e&clientId=ucbf82d3e-04b6-4&from=paste&height=99&id=u39c55141&originHeight=124&originWidth=1469&originalType=binary&ratio=1.25&rotation=0&showTitle=false&size=29611&status=done&style=none&taskId=u666bf849-4428-48ef-bec2-b83e2845a15&title=&width=1175.2)\n![image.png](https:\u002F\u002Fcdn.nlark.com\u002Fyuque\u002F0\u002F2023\u002Fpng\u002F751015\u002F1693835820459-79eef64b-d765-4ac1-bdaa-9d383a5b6d50.png#averageHue=%232e2c2b&clientId=ucbf82d3e-04b6-4&from=paste&height=428&id=u73695f8b&originHeight=535&originWidth=908&originalType=binary&ratio=1.25&rotation=0&showTitle=false&size=53770&status=done&style=none&taskId=ubbb6e448-1265-434c-b810-a4f1a02e14c&title=&width=726.4)\n\n![image.png](https:\u002F\u002Fcdn.nlark.com\u002Fyuque\u002F0\u002F2023\u002Fpng\u002F751015\u002F1693836037115-6ebd16b8-2e16-4fdc-92e1-3e196ef9cc08.png#averageHue=%23aeadad&clientId=ucbf82d3e-04b6-4&from=paste&height=649&id=ud10d0876&originHeight=811&originWidth=1236&originalType=binary&ratio=1.25&rotation=0&showTitle=false&size=47289&status=done&style=none&taskId=ubb61c51c-f4f4-408a-950a-aa0e14bfdec&title=&width=988.8)\n因为代码没写\n\n![image.png](https:\u002F\u002Fcdn.nlark.com\u002Fyuque\u002F0\u002F2023\u002Fpng\u002F751015\u002F1693837306059-b43be82c-af25-4651-9940-cc0af21cc637.png#averageHue=%232e2c2b&clientId=ucbf82d3e-04b6-4&from=paste&height=446&id=ue7216be3&originHeight=558&originWidth=1245&originalType=binary&ratio=1.25&rotation=0&showTitle=false&size=79745&status=done&style=none&taskId=u5c90a286-9c13-4b76-9139-98991a9c543&title=&width=996)\n\n前端 User.vue\n\n```vue\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cdiv>\n      \u003Cel-input style=\"width: 200px\" placeholder=\"查询用户名\" v-model=\"username\">\u003C\u002Fel-input>\n      \u003Cel-input style=\"width: 200px; margin: 0 5px\" placeholder=\"查询姓名\"  v-model=\"name\">\u003C\u002Fel-input>\n      \u003Cel-button type=\"primary\" @click=\"load(1)\">查询\u003C\u002Fel-button>\n      \u003Cel-button type=\"info\" @click=\"reset\">重置\u003C\u002Fel-button>\n    \u003C\u002Fdiv>\n    \u003Cdiv style=\"margin: 10px 0\">\n      \u003Cel-button type=\"primary\" plain @click=\"handleAdd\">新增\u003C\u002Fel-button>\n      \u003Cel-button type=\"danger\" plain @click=\"delBatch\">批量删除\u003C\u002Fel-button>\n    \u003C\u002Fdiv>\n    \u003Cel-table :data=\"tableData\" stripe :header-cell-style=\"{ backgroundColor: 'aliceblue', color: '#666' }\" @selection-change=\"handleSelectionChange\">\n      \u003Cel-table-column type=\"selection\" width=\"55\" align=\"center\">\u003C\u002Fel-table-column>\n      \u003Cel-table-column prop=\"id\" label=\"序号\" width=\"70\" align=\"center\">\u003C\u002Fel-table-column>\n      \u003Cel-table-column prop=\"username\" label=\"用户名\">\u003C\u002Fel-table-column>\n      \u003Cel-table-column prop=\"name\" label=\"姓名\">\u003C\u002Fel-table-column>\n      \u003Cel-table-column prop=\"phone\" label=\"手机号\">\u003C\u002Fel-table-column>\n      \u003Cel-table-column prop=\"email\" label=\"邮箱\">\u003C\u002Fel-table-column>\n      \u003Cel-table-column prop=\"address\" label=\"地址\">\u003C\u002Fel-table-column>\n      \u003Cel-table-column label=\"头像\">\n        \u003Ctemplate v-slot=\"scope\">\n          \u003Cdiv style=\"display: flex; align-items: center\">\n            \u003Cel-image style=\"width: 50px; height: 50px; border-radius: 50%\" v-if=\"scope.row.avatar\" :src=\"scope.row.avatar\" :preview-src-list=\"[scope.row.avatar]\">\u003C\u002Fel-image>\n          \u003C\u002Fdiv>\n        \u003C\u002Ftemplate>\n      \u003C\u002Fel-table-column>\n      \u003Cel-table-column prop=\"role\" label=\"角色\">\u003C\u002Fel-table-column>\n      \u003Cel-table-column label=\"操作\" align=\"center\" width=\"180\">\n        \u003Ctemplate v-slot=\"scope\">\n          \u003Cel-button size=\"mini\" type=\"primary\" plain @click=\"handleEdit(scope.row)\">编辑\u003C\u002Fel-button>\n          \u003Cel-button size=\"mini\" type=\"danger\" plain @click=\"del(scope.row.id)\">删除\u003C\u002Fel-button>\n        \u003C\u002Ftemplate>\n      \u003C\u002Fel-table-column>\n    \u003C\u002Fel-table>\n\n    \u003Cdiv style=\"margin: 10px 0\">\n      \u003Cel-pagination\n          @current-change=\"handleCurrentChange\"\n          :current-page=\"pageNum\"\n          :page-sizes=\"[100, 200, 300, 400]\"\n          :page-size=\"pageSize\"\n          layout=\"total, prev, pager, next\"\n          :total=\"total\">\n      \u003C\u002Fel-pagination>\n    \u003C\u002Fdiv>\n\n    \u003Cel-dialog title=\"收货地址\" :visible.sync=\"fromVisible\" width=\"30%\">\n      \u003Cel-form :model=\"form\" label-width=\"80px\" style=\"padding-right: 20px\" :rules=\"rules\" ref=\"formRef\">\n        \u003Cel-form-item label=\"用户名\" prop=\"username\">\n          \u003Cel-input v-model=\"form.username\" placeholder=\"用户名\">\u003C\u002Fel-input>\n        \u003C\u002Fel-form-item>\n        \u003Cel-form-item label=\"姓名\" prop=\"name\">\n          \u003Cel-input v-model=\"form.name\" placeholder=\"姓名\">\u003C\u002Fel-input>\n        \u003C\u002Fel-form-item>\n        \u003Cel-form-item label=\"电话\" prop=\"phone\">\n          \u003Cel-input v-model=\"form.phone\" placeholder=\"电话\">\u003C\u002Fel-input>\n        \u003C\u002Fel-form-item>\n        \u003Cel-form-item label=\"邮箱\" prop=\"email\">\n          \u003Cel-input v-model=\"form.email\" placeholder=\"邮箱\">\u003C\u002Fel-input>\n        \u003C\u002Fel-form-item>\n        \u003Cel-form-item label=\"地址\" prop=\"address\">\n          \u003Cel-input type=\"textarea\" v-model=\"form.address\" placeholder=\"地址\">\u003C\u002Fel-input>\n        \u003C\u002Fel-form-item>\n        \u003Cel-form-item label=\"角色\" prop=\"role\">\n          \u003Cel-radio-group v-model=\"form.role\">\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-upload\n              class=\"avatar-uploader\"\n              action=\"http:\u002F\u002Flocalhost:9090\u002Ffile\u002Fupload\"\n              :headers=\"{ token: user.token }\"\n              :file-list=\"form.avatar? [form.avatar] : []\"\n              list-type=\"picture\"\n              :on-success=\"handleAvatarSuccess\"\n          >\n            \u003Cel-button type=\"primary\">上传头像\u003C\u002Fel-button>\n          \u003C\u002Fel-upload>\n        \u003C\u002Fel-form-item>\n      \u003C\u002Fel-form>\n\n      \u003Cdiv slot=\"footer\" class=\"dialog-footer\">\n        \u003Cel-button @click=\"fromVisible = false\">取 消\u003C\u002Fel-button>\n        \u003Cel-button type=\"primary\" @click=\"save\">确 定\u003C\u002Fel-button>\n      \u003C\u002Fdiv>\n    \u003C\u002Fel-dialog>\n\n\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript>\nexport default {\n  name: \"User\",\n  data() {\n    return {\n      tableData: [],  \u002F\u002F 所有的数据\n      pageNum: 1,   \u002F\u002F 当前的页码\n      pageSize: 5,  \u002F\u002F 每页显示的个数\n      username: '',\n      name: '',\n      total: 0,\n      fromVisible: false,\n      form: {},\n      user: JSON.parse(localStorage.getItem('honey-user') || '{}'),\n      rules: {\n        username: [\n          { required: true, message: '请输入账号', trigger: 'blur' },\n        ]\n      },\n      ids: []\n    }\n  },\n  created() {\n    this.load()\n  },\n  methods: {\n    delBatch() {\n      if (!this.ids.length) {\n        this.$message.warning('请选择数据')\n        return\n      }\n      this.$confirm('您确认批量删除这些数据吗？', '确认删除', {type: \"warning\"}).then(response => {\n        this.$request.delete('\u002Fuser\u002Fdelete\u002Fbatch', { data: this.ids }).then(res => {\n          if (res.code === '200') {   \u002F\u002F 表示操作成功\n            this.$message.success('操作成功')\n            this.load(1)\n          } else {\n            this.$message.error(res.msg)  \u002F\u002F 弹出错误的信息\n          }\n        })\n      }).catch(() => {})\n    },\n    handleSelectionChange(rows) {   \u002F\u002F 当前选中的所有的行数据\n      this.ids = rows.map(v => v.id)\n    },\n    del(id) {\n      this.$confirm('您确认删除吗？', '确认删除', {type: \"warning\"}).then(response => {\n        this.$request.delete('\u002Fuser\u002Fdelete\u002F' + id).then(res => {\n          if (res.code === '200') {   \u002F\u002F 表示操作成功\n            this.$message.success('操作成功')\n            this.load(1)\n          } else {\n            this.$message.error(res.msg)  \u002F\u002F 弹出错误的信息\n          }\n        })\n      }).catch(() => {})\n    },\n    handleEdit(row) {   \u002F\u002F 编辑数据\n      this.form = JSON.parse(JSON.stringify(row))  \u002F\u002F 给form对象赋值  注意要深拷贝数据\n      this.fromVisible = true   \u002F\u002F 打开弹窗\n    },\n    handleAdd() {   \u002F\u002F 新增数据\n      this.form = { role: '用户' }  \u002F\u002F 新增数据的时候清空数据\n      this.fromVisible = true   \u002F\u002F 打开弹窗\n    },\n    save() {   \u002F\u002F 保存按钮触发的逻辑  它会触发新增或者更新\n      this.$refs.formRef.validate((valid) => {\n        if (valid) {\n          this.$request({\n            url: this.form.id ? '\u002Fuser\u002Fupdate': '\u002Fuser\u002Fadd',\n            method: this.form.id ? 'PUT' : 'POST',\n            data: this.form\n          }).then(res => {\n            if (res.code === '200') {  \u002F\u002F 表示成功保存\n              this.$message.success('保存成功')\n              this.load(1)\n              this.fromVisible = false\n            } else {\n              this.$message.error(res.msg)  \u002F\u002F 弹出错误的信息\n            }\n          })\n        }\n      })\n    },\n    reset() {\n      this.name = ''\n      this.username = ''\n      this.load()\n    },\n    load(pageNum) {  \u002F\u002F 分页查询\n      if (pageNum)  this.pageNum = pageNum\n      this.$request.get('\u002Fuser\u002FselectByPage', {\n        params: {\n          pageNum: this.pageNum,\n          pageSize: this.pageSize,\n          username: this.username,\n          name: this.name\n        }\n      }).then(res => {\n        this.tableData = res.data.records\n        this.total = res.data.total\n      })\n    },\n    handleCurrentChange(pageNum) {\n      this.load(pageNum)\n    },\n    handleAvatarSuccess(response, file, fileList) {\n      \u002F\u002F 把user的头像属性换成上传的图片的链接\n      this.form.avatar = response.data\n    },\n  }\n}\n\u003C\u002Fscript>\n\n\u003Cstyle scoped>\n\n\u003C\u002Fstyle>\n```\n\n后台判断不能删除当前登录的用户信息\n\n```vue\nUser currentUser = TokenUtils.getCurrentUser();\nif (id.equals(currentUser.getId())) {\n    throw new ServiceException(\"不能删除当前的用户\");\n}\n```\n","coding",1,2598,71,"2024-04-16 02:32:29","2026-05-03 22:49:02","【青哥带小白做毕设2024】完整教程资料汇总","qingge-graduation-project-2024",{"project":18,"items":19},{"id":6,"title":15,"slug":16},[20,28,35,42,49,56,63,69,76,83,90,97,104,111,118,125,132,133,140,147,154,161,168],{"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":27,"project_title":15,"project_slug":16},33,"R1oMCsCX","00. 从0开始带小白做SpringBoot+Vue+uniapp微信小程序实战项目",12130,55,"2025-04-08 11:28:17","2026-05-07 15:33:28.189425+00",{"id":29,"uuid":30,"project_id":6,"title":31,"type":9,"status":10,"public_enabled":10,"views":32,"sort":33,"created_at":34,"updated_at":14,"project_title":15,"project_slug":16},34,"s3u3u8W7","01. 网页布局技巧",3326,56,"2025-04-08 11:28:13",{"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},35,"21zUHQYS","02. JavaScript入门",2017,57,"2025-04-08 11:27:55",{"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":14,"project_title":15,"project_slug":16},36,"4XVgY9Ti","03. Vue脚手架搭建",3719,58,"2025-04-08 11:27:46",{"id":50,"uuid":51,"project_id":6,"title":52,"type":9,"status":10,"public_enabled":10,"views":53,"sort":54,"created_at":55,"updated_at":14,"project_title":15,"project_slug":16},37,"S8vLLLvk","04. Git速成，推送代码到云端",1585,59,"2025-04-08 11:27:41",{"id":57,"uuid":58,"project_id":6,"title":59,"type":9,"status":10,"public_enabled":10,"views":60,"sort":61,"created_at":62,"updated_at":14,"project_title":15,"project_slug":16},38,"9EbwnGDp","05. 网页布局神器ElementUI速成",2670,60,"2025-04-08 11:27:37",{"id":6,"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},"tmzahWer","06. Vue管理系统速成",3744,61,"2025-04-08 11:27:32",{"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},40,"2agqAUQK","07. SpringBoot速成",3654,62,"2025-04-08 11:27:27",{"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},41,"SXPAzgy7","08. Http扫盲，让小白也能听懂",2337,63,"2025-04-08 11:27:20",{"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},42,"ostBIxAV","09. SpringBoot集成Mybatis实现增删改查",4190,64,"2025-04-08 11:27:13",{"id":91,"uuid":92,"project_id":6,"title":93,"type":9,"status":10,"public_enabled":10,"views":94,"sort":95,"created_at":96,"updated_at":14,"project_title":15,"project_slug":16},43,"6Sv7afpa","10. Vue封装前后端数据交互工具",3716,65,"2024-04-16 02:33:13",{"id":98,"uuid":99,"project_id":6,"title":100,"type":9,"status":10,"public_enabled":10,"views":101,"sort":102,"created_at":103,"updated_at":14,"project_title":15,"project_slug":16},44,"d53BPIQs","11. Vue登录（含验证码）、注册页面开发",4867,66,"2024-04-16 02:33:08",{"id":105,"uuid":106,"project_id":6,"title":107,"type":9,"status":10,"public_enabled":10,"views":108,"sort":109,"created_at":110,"updated_at":14,"project_title":15,"project_slug":16},45,"m033ng06","12. SpringBoot集成JWT token实现权限验证",3243,67,"2024-04-16 02:33:00",{"id":112,"uuid":113,"project_id":6,"title":114,"type":9,"status":10,"public_enabled":10,"views":115,"sort":116,"created_at":117,"updated_at":14,"project_title":15,"project_slug":16},46,"7xzyVD06","13. SpringBoot+Vue实现单文件、多文件上传和下载",2784,68,"2024-04-16 02:32:52",{"id":119,"uuid":120,"project_id":6,"title":121,"type":9,"status":10,"public_enabled":10,"views":122,"sort":123,"created_at":124,"updated_at":14,"project_title":15,"project_slug":16},47,"BdOLUenp","14. 多角色登录（Vue-Router路由守卫）",2318,69,"2024-04-16 02:32:39",{"id":126,"uuid":127,"project_id":6,"title":128,"type":9,"status":10,"public_enabled":10,"views":129,"sort":130,"created_at":131,"updated_at":14,"project_title":15,"project_slug":16},48,"2Wkx3igg","15. Vue个人信息修改、修改密码、重置密码",2092,70,"2024-04-16 02:32:33",{"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":134,"uuid":135,"project_id":6,"title":136,"type":9,"status":10,"public_enabled":10,"views":137,"sort":138,"created_at":139,"updated_at":14,"project_title":15,"project_slug":16},50,"FJVl0rCu","17. SpringBoot+Vue实现数据的批量导入和导出",1684,72,"2024-04-16 02:32:26",{"id":141,"uuid":142,"project_id":6,"title":143,"type":9,"status":10,"public_enabled":10,"views":144,"sort":145,"created_at":146,"updated_at":14,"project_title":15,"project_slug":16},51,"FvW9oHgj","18. SpringBoot+Vue项目部署上线",2845,73,"2024-04-16 02:32:22",{"id":148,"uuid":149,"project_id":6,"title":150,"type":9,"status":10,"public_enabled":10,"views":151,"sort":152,"created_at":153,"updated_at":14,"project_title":15,"project_slug":16},52,"xyqrxxiR","19. SpringBoot+Vue集成富文本编辑器",1499,74,"2024-04-16 02:32:18",{"id":155,"uuid":156,"project_id":6,"title":157,"type":9,"status":10,"public_enabled":10,"views":158,"sort":159,"created_at":160,"updated_at":14,"project_title":15,"project_slug":16},53,"XAaCXz8W","20. SpringBoot+Vue集成系统公告",1043,75,"2024-04-16 02:32:14",{"id":162,"uuid":163,"project_id":6,"title":164,"type":9,"status":10,"public_enabled":10,"views":165,"sort":166,"created_at":167,"updated_at":14,"project_title":15,"project_slug":16},54,"2havlmaC","21. SpringBoot+Vue集成AOP系统日志",1159,76,"2024-04-16 02:32:11",{"id":25,"uuid":169,"project_id":6,"title":170,"type":9,"status":10,"public_enabled":10,"views":171,"sort":172,"created_at":173,"updated_at":14,"project_title":15,"project_slug":16},"ObvLqJdX","22. SpringBoot+Vue实现Echarts数据报表（柱状图、饼图、折线图）",1688,99,"2024-04-16 02:30:25"]