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

谷粒商城实战笔记-59-商品服务-API-品牌管理-使用逆向工程的前后端代码

文章目录

  • 一, 使用逆向工程生成的代码
  • 二,生成品牌管理菜单
  • 三,几个小问题

在本次的技术实践中,我们利用逆向工程的方法成功地为后台管理系统增加了品牌管理功能。这种开发方式不仅能快速地构建起功能模块,还能在一定程度上减少编码工作量,提高开发效率。下面我们将详细介绍整个过程及遇到的一些问题。

一, 使用逆向工程生成的代码

品牌管理的代码使用逆向工程生成的代码,再次基础上进行修改。

小细节,使用逆向工程生成代码时,要注意分页导致只生成部分代码,可以调整每页显示的数据条数,一次把所有的数据都显示出来。

在这里插入图片描述
我们从逆向工程中获得了两个核心的Vue组件文件——brand.vue 和 band-add-or-update.vue。这两个文件包含了品牌管理的主要逻辑和界面元素。我们随后将它们复制到了前端工程中,以便进一步集成和测试。
在这里插入图片描述

拷贝到前端工程中。

在这里插入图片描述

二,生成品牌管理菜单

在后台管理系统新增品牌管理菜单。

在这里插入图片描述

为了将新生成的品牌管理功能集成到现有的后台管理系统中,我们需要在主菜单栏中添加一个新的菜单项——“品牌管理”。这一步骤非常直接,只需在后台管理系统的配置文件中添加相应的路由信息即可。完成配置后,刷新前端界面,便能看到新增的“品牌管理”菜单项。
在这里插入图片描述
刷新后台管理系统前端界面,可以看到品牌管理菜单。

在这里插入图片描述

点击该菜单项后,我们可以看到完整的品牌管理界面,整个过程十分快捷高效,充分体现了逆向工程的价值所在。

在这里插入图片描述

三,几个小问题

在使用逆向工程生成的代码时,我们发现生成的界面中缺失了一些重要的功能,例如新增和删除按钮的权限控制。为了解决这个问题,我们暂时忽略了权限检查,以便快速推进项目的开发进程。具体做法是找到负责权限控制的代码段,并将其调整为总是返回true的状态,这样就可以让所有用户都能访问这些功能了。

在这里插入图片描述

把控制权限的代码调整为返回true,即暂时不考虑权限控制。

找到如下函数的定义。

在这里插入图片描述

把原来的函数定义注释掉,改为返回true。

在这里插入图片描述
虽然暂时绕过了权限检查,但长远来看,我们需要重新考虑如何实现权限管理。毕竟,一个安全稳定的系统应该具备完善的权限控制机制。为此,我们可以在后续开发中引入更加精细的角色权限管理方案,确保每个用户的操作权限与其职责相符。

总的来说,通过逆向工程我们不仅能够快速搭建出功能完备的界面,还能有效降低开发成本。当然,为了确保系统的稳定性和安全性,我们还需要不断地对生成的代码进行优化和完善。在未来的工作中,我们将继续探索更多类似的技术手段,以进一步提升开发效率。

brand.js代码如下。

<template><div class="mod-config"><el-form :inline="true" :model="dataForm" @keyup.enter.native="getDataList()"><el-form-item><el-input v-model="dataForm.key" placeholder="参数名" clearable></el-input></el-form-item><el-form-item><el-button @click="getDataList()">查询</el-button><el-button v-if="isAuth('product:brand:save')" type="primary" @click="addOrUpdateHandle()">新增</el-button><el-button v-if="isAuth('product:brand:delete')" type="danger" @click="deleteHandle()" :disabled="dataListSelections.length <= 0">批量删除</el-button></el-form-item></el-form><el-table:data="dataList"borderv-loading="dataListLoading"@selection-change="selectionChangeHandle"style="width: 100%;"><el-table-columntype="selection"header-align="center"align="center"width="50"></el-table-column><el-table-columnprop="brandId"header-align="center"align="center"label="品牌id"></el-table-column><el-table-columnprop="name"header-align="center"align="center"label="品牌名"></el-table-column><el-table-columnprop="logo"header-align="center"align="center"label="品牌logo地址"></el-table-column><el-table-columnprop="descript"header-align="center"align="center"label="介绍"></el-table-column><el-table-columnprop="showStatus"header-align="center"align="center"label="显示状态[0-不显示;1-显示]"></el-table-column><el-table-columnprop="firstLetter"header-align="center"align="center"label="检索首字母"></el-table-column><el-table-columnprop="sort"header-align="center"align="center"label="排序"></el-table-column><el-table-columnfixed="right"header-align="center"align="center"width="150"label="操作"><template slot-scope="scope"><el-button type="text" size="small" @click="addOrUpdateHandle(scope.row.brandId)">修改</el-button><el-button type="text" size="small" @click="deleteHandle(scope.row.brandId)">删除</el-button></template></el-table-column></el-table><el-pagination@size-change="sizeChangeHandle"@current-change="currentChangeHandle":current-page="pageIndex":page-sizes="[10, 20, 50, 100]":page-size="pageSize":total="totalPage"layout="total, sizes, prev, pager, next, jumper"></el-pagination><!-- 弹窗, 新增 / 修改 --><add-or-update v-if="addOrUpdateVisible" ref="addOrUpdate" @refreshDataList="getDataList"></add-or-update></div>
</template><script>import AddOrUpdate from './brand-add-or-update'export default {data () {return {dataForm: {key: ''},dataList: [],pageIndex: 1,pageSize: 10,totalPage: 0,dataListLoading: false,dataListSelections: [],addOrUpdateVisible: false}},components: {AddOrUpdate},activated () {this.getDataList()},methods: {// 获取数据列表getDataList () {this.dataListLoading = truethis.$http({url: this.$http.adornUrl('/product/brand/list'),method: 'get',params: this.$http.adornParams({'page': this.pageIndex,'limit': this.pageSize,'key': this.dataForm.key})}).then(({data}) => {if (data && data.code === 0) {this.dataList = data.page.listthis.totalPage = data.page.totalCount} else {this.dataList = []this.totalPage = 0}this.dataListLoading = false})},// 每页数sizeChangeHandle (val) {this.pageSize = valthis.pageIndex = 1this.getDataList()},// 当前页currentChangeHandle (val) {this.pageIndex = valthis.getDataList()},// 多选selectionChangeHandle (val) {this.dataListSelections = val},// 新增 / 修改addOrUpdateHandle (id) {this.addOrUpdateVisible = truethis.$nextTick(() => {this.$refs.addOrUpdate.init(id)})},// 删除deleteHandle (id) {var ids = id ? [id] : this.dataListSelections.map(item => {return item.brandId})this.$confirm(`确定对[id=${ids.join(',')}]进行[${id ? '删除' : '批量删除'}]操作?`, '提示', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).then(() => {this.$http({url: this.$http.adornUrl('/product/brand/delete'),method: 'post',data: this.$http.adornData(ids, false)}).then(({data}) => {if (data && data.code === 0) {this.$message({message: '操作成功',type: 'success',duration: 1500,onClose: () => {this.getDataList()}})} else {this.$message.error(data.msg)}})})}}}
</script>

brand-add-or-update.vue代码如下。

<template><el-dialog:title="!dataForm.brandId ? '新增' : '修改'":close-on-click-modal="false":visible.sync="visible"><el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmit()" label-width="80px"><el-form-item label="品牌名" prop="name"><el-input v-model="dataForm.name" placeholder="品牌名"></el-input></el-form-item><el-form-item label="品牌logo地址" prop="logo"><el-input v-model="dataForm.logo" placeholder="品牌logo地址"></el-input></el-form-item><el-form-item label="介绍" prop="descript"><el-input v-model="dataForm.descript" placeholder="介绍"></el-input></el-form-item><el-form-item label="显示状态[0-不显示;1-显示]" prop="showStatus"><el-input v-model="dataForm.showStatus" placeholder="显示状态[0-不显示;1-显示]"></el-input></el-form-item><el-form-item label="检索首字母" prop="firstLetter"><el-input v-model="dataForm.firstLetter" placeholder="检索首字母"></el-input></el-form-item><el-form-item label="排序" prop="sort"><el-input v-model="dataForm.sort" placeholder="排序"></el-input></el-form-item></el-form><span slot="footer" class="dialog-footer"><el-button @click="visible = false">取消</el-button><el-button type="primary" @click="dataFormSubmit()">确定</el-button></span></el-dialog>
</template><script>export default {data () {return {visible: false,dataForm: {brandId: 0,name: '',logo: '',descript: '',showStatus: '',firstLetter: '',sort: ''},dataRule: {name: [{ required: true, message: '品牌名不能为空', trigger: 'blur' }],logo: [{ required: true, message: '品牌logo地址不能为空', trigger: 'blur' }],descript: [{ required: true, message: '介绍不能为空', trigger: 'blur' }],showStatus: [{ required: true, message: '显示状态[0-不显示;1-显示]不能为空', trigger: 'blur' }],firstLetter: [{ required: true, message: '检索首字母不能为空', trigger: 'blur' }],sort: [{ required: true, message: '排序不能为空', trigger: 'blur' }]}}},methods: {init (id) {this.dataForm.brandId = id || 0this.visible = truethis.$nextTick(() => {this.$refs['dataForm'].resetFields()if (this.dataForm.brandId) {this.$http({url: this.$http.adornUrl(`/product/brand/info/${this.dataForm.brandId}`),method: 'get',params: this.$http.adornParams()}).then(({data}) => {if (data && data.code === 0) {this.dataForm.name = data.brand.namethis.dataForm.logo = data.brand.logothis.dataForm.descript = data.brand.descriptthis.dataForm.showStatus = data.brand.showStatusthis.dataForm.firstLetter = data.brand.firstLetterthis.dataForm.sort = data.brand.sort}})}})},// 表单提交dataFormSubmit () {this.$refs['dataForm'].validate((valid) => {if (valid) {this.$http({url: this.$http.adornUrl(`/product/brand/${!this.dataForm.brandId ? 'save' : 'update'}`),method: 'post',data: this.$http.adornData({'brandId': this.dataForm.brandId || undefined,'name': this.dataForm.name,'logo': this.dataForm.logo,'descript': this.dataForm.descript,'showStatus': this.dataForm.showStatus,'firstLetter': this.dataForm.firstLetter,'sort': this.dataForm.sort})}).then(({data}) => {if (data && data.code === 0) {this.$message({message: '操作成功',type: 'success',duration: 1500,onClose: () => {this.visible = falsethis.$emit('refreshDataList')}})} else {this.$message.error(data.msg)}})}})}}}
</script>

相关文章:

谷粒商城实战笔记-59-商品服务-API-品牌管理-使用逆向工程的前后端代码

文章目录 一&#xff0c; 使用逆向工程生成的代码二&#xff0c;生成品牌管理菜单三&#xff0c;几个小问题 在本次的技术实践中&#xff0c;我们利用逆向工程的方法成功地为后台管理系统增加了品牌管理功能。这种开发方式不仅能快速地构建起功能模块&#xff0c;还能在一定程度…...

如何利用Jenkins自动化管理、部署数百个应用

目录 1. Jenkins 安装与部署步骤 1.1 系统要求 1.2 安装步骤 1.2.1 Windows 系统 1.2.2 CentOS 系统 1.3 初次配置 2. Gradle 详细配置方式 2.1 安装 Gradle 2.1.1 Windows 系统 2.1.2 CentOS 系统 2.2 配置 Jenkins 中的 Gradle 3. JDK 详细配置方式 3.1 安装 JD…...

Java之归并排序

归并排序 归并排序(Merge Sort)算法&#xff0c;使用的是分治思想。分治&#xff0c;顾名思义&#xff0c;就是分而治之&#xff0c;将一个大问题分解成小的子问题来解决。小的子问题解决了&#xff0c;大问题也就解决了。 核心源码: mergeSort(m->n) merge(mergeSort(m-&g…...

了解ChatGPT API

要了解如何使用 ChatGPT API&#xff0c;可以参考几个有用的资源和教程&#xff0c;这些资源能帮助你快速开始使用 API 进行项目开发。下面是一些推荐的资源&#xff1a; OpenAI 官方文档&#xff1a; 访问 OpenAI 的官方网站可以找到 ChatGPT API 的详细文档。这里包括了 API …...

EasyAnimate - 阿里开源视频生成项目,国产版Sora,高质量长视频生成 本地一键整合包下载

EasyAnimate是阿里云人工智能平台PAI自主研发的DiT-based视频生成框架&#xff0c;它提供了完整的高清长视频生成解决方案&#xff0c;包括视频数据预处理、VAE训练、DiT训练、模型推理和模型评测等。在预训练模型的基础上&#xff0c;EasyAnimate可通过少量图片的LoRA微调来改…...

7月23日JavaSE学习笔记

异常&#xff1a; 程序中一些程序处理不了的特殊情况 异常类 Exception 继承自 Throwable 类&#xff08;可抛出的&#xff09; Throwable继承树 Error&#xff1a;错误/事故&#xff0c;Java程序无法处理&#xff0c;如 OOM内存溢出错误、内存泄漏...会导出程序崩溃 常见的…...

Linux——DNS服务搭建

&#xff08;一&#xff09;搭建nginx 1.首先布置基本环境 要求能够ping通外网&#xff0c;有yum源 2.安装nginx yum -y install nginx 然后查看验证 3.修改网页配置文件 修改文件&#xff0c;任意编写内容&#xff0c;然后去物理机测试 &#xff08;二&#xff09;创建一…...

C#中的wpf基础

在WPF中&#xff0c;Grid 是一种非常强大的布局控件&#xff0c;用于创建网格布局。它允许你将界面划分为行和列&#xff0c;并将控件放置在这些行和列中。 以下是一些关键点和示例&#xff0c;帮助你理解 WPF 中的 Grid&#xff1a; 基本属性 RowDefinitions&#xff1a;定义…...

基于微信小程序+SpringBoot+Vue的刷题系统(带1w+文档)

基于微信小程序SpringBootVue的刷题系统(带1w文档) 基于微信小程序SpringBootVue的刷题系统(带1w文档) 本系统是将网络技术和现代的管理理念相结合&#xff0c;根据试题信息的特点进行重新分配、整合形成动态的、分类明确的信息资源&#xff0c;实现了刷题的自动化&#xff0c;…...

SSH -i的用法

缘起 今天使用ssh -i指定私钥时遇到以下错误&#xff1a; WARNING: UNPROTECTED PRIVATE KEY FILE! Permissions 0644 for /home/ken/.ssh/my.pem are too open. It is required that your private key files are NOT accessible by others. This private key will b…...

小白学习webgis的详细路线

推荐打开boss直聘搜索相关岗位&#xff0c;查看岗位要求&#xff0c;对症下药是最快的。 第一阶段&#xff1a;基础知识准备 计算机基础 操作系统&#xff1a;理解Windows、Linux或macOS等操作系统的基本操作&#xff0c;学会使用命令行界面。网络基础&#xff1a;掌握TCP/I…...

使用ChatGPT来撰写和润色学术论文的教程(含最新升级开通ChatGpt4教程)​​

现在有了ChatGPT4o更加方便了, 但次数太少了 想要增加次数可以考虑升级开桶ChatGpt4​​ &#xff08; OPENAI4 可以减2刀&#xff09; 一、引言 在学术研究中&#xff0c;撰写高质量的论文是一项重要的技能。本教程将介绍如何利用ChatGPT来辅助完成从论文构思到润色的全过程…...

常见的 HTTP 状态码分类及说明

HTTP 响应状态码&#xff08;HTTP status code&#xff09;&#xff0c;表示服务器对请求的处理结果。常见的 HTTP 状态码有以下几类&#xff1a; 1xx: 信息响应 (Informational Responses) 100 Continue: 请求已收到&#xff0c;客户端应继续发送请求的其余部分。101 Switch…...

Leetcode700.二叉搜索树中搜索具体值

二叉搜索树的定义&#xff1a; 一颗空树或者具有以下性质的二叉树&#xff1a; 若任意节点的左子树不空&#xff0c;则左子树上所有节点的值均小于它的根节点的值&#xff1b;若任意节点的右子树不空&#xff0c;则右子树上所有节点的值均大于它的根节点的值&#xff1b;任意节…...

自动导入unplugin-auto-import+unplugin-vue-components

文章介绍 接下来将会以Vite Vue3 TS的项目来举例实现 在我们进行项目开发时&#xff0c;无论是声明响应式数据使用的ref、reactive&#xff0c;或是各种生命周期&#xff0c;又或是computed、watch、watchEffect、provide-inject。这些都需要前置引入才能使用&#xff1a; …...

Conda修改包/虚拟环境储存目录

Conda修改包/虚拟环境储存目录 关键字样例 关键字 通过conda config --show [key]可以查看某个配置的值&#xff0c;[key]留空可以查看所有配置 其中&#xff1a; envs-dirs 存放虚拟环境的储存目录pkgs_dirs 包的目录 通过conda config --add [key] [value]可以为配置添加值…...

Live555源码阅读笔记:哈希表的实现(C++)

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…...

警务平台app

智慧公安以大数据、云计算、人工智能、物联网和移动互联网技术为支撑&#xff0c;以“打、防、管、控”为目的&#xff0c;综合研判为核心&#xff0c;共享信息数据资源&#xff0c;融合业务功能&#xff0c;构建公安智慧大数据平台&#xff0c;实现公安信息数字化、网络化和智…...

Java代理模式详解

Java代理模式详解 概念 代理模式是一种设计模式&#xff0c;为其他对象提供一种代理以控制对这个对象的访问。在某些情况下&#xff0c;一个对象不适合或者不能直接引用另一个对象&#xff0c;而代理对象可以在客户端和目标对象之间起到中介的作用。在Java中&#xff0c;代理…...

docker centos镜像 npm安装包时报错“npm ERR! code ECONNRESET”

1.采用新的镜像地址 npm config set registry https://registry.npmmirror.com2.清理缓存 npm cache clean --force3.安装yarn npm install -g yarn4. 安装模块 在node_modules 同级目录执行下面命令&#xff1a; yarn add napi-build-utils env-paths express ejs cors …...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件&#xff0c;我的文件路径是/etc/mysql/my.cnf&#xff0c;有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

iview框架主题色的应用

1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题&#xff0c;无需引入&#xff0c;直接可…...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案

在大数据时代&#xff0c;海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构&#xff0c;在处理大规模数据抓取任务时展现出强大的能力。然而&#xff0c;随着业务规模的不断扩大和数据抓取需求的日益复杂&#xff0c;传统…...

stm32wle5 lpuart DMA数据不接收

配置波特率9600时&#xff0c;需要使用外部低速晶振...

如何做好一份技术文档?从规划到实践的完整指南

如何做好一份技术文档&#xff1f;从规划到实践的完整指南 &#x1f31f; 嗨&#xff0c;我是IRpickstars&#xff01; &#x1f30c; 总有一行代码&#xff0c;能点亮万千星辰。 &#x1f50d; 在技术的宇宙中&#xff0c;我愿做永不停歇的探索者。 ✨ 用代码丈量世界&…...