若依管理系统开发
注: 参考黑马程序员若依开发框架视频
一. 基本概念
- RABC: 基于角色的权限管理
后端: 在用户登录时后端根据角色信息获取所有的权限集合,当请求后端方法时,通过@PreAuthorize()注解拦截用户请求,判断是否有该权限,若有,则放行。
前端:通过v-hasPermi=[“”]来动态显示操作按钮。
2. 数据字典:若依内置数据字典,用于维护系统中常见的静态数据。例如性别,状态。如图在代码生成中,字段类型可以设置为数据字典类型。然后将对应的前端代码放到对应的位置下即可生效。
3. 菜单管理:
- 主类目:类似于首页,系统管理目录。点击不会发生跳转。
- 菜单:点击会根据路由地址发生跳转。当点击时,路由地址为各级路由地址拼接而成。。
- 路由地址:对应数据库中sys_menu表的path字段,该字段必须保证唯一性,为跳转路径。
- 组件路径:组件路径为为sys_menu表的componet字段,为前端工程代码下的views下的实际路径
- 权限字符:sys_menu表中的perm字段,系统生成的该字段由组件路径和按钮拼接而成。
在添加菜单时,组件路径,权限字符先不必填写,待生成代码后,系统会自动生成。
4. 代码生成:
-
字段信息:由于后端所有实体类默认继承了BaseEntity基类(createTime,updateBy,updateTime,remark),框架会自动处理这些字段。因此在插入,编辑列时可以不必勾选这些字段。
-
生成信息: 生成功能名:为左侧导航显示的名称。
5. 后端返回数据
-
TableDataInfo: 分页查询统一返回对象:表格分页数据对象
-
AjaxResult: 增删改查统一返回对象:操作消息提醒
6. 跨域:
在前端开发中,跨域是一个常见的问题,特别是在使用Vue框架进行开发时。跨域是指在浏览器中发送的AJAX请求的目标地址与当前页面的地址不在同一个域下,这会导致浏览器的同源策略产生限制,从而阻止了跨域请求的发送。然而,我们可以通过代理服务器来解决这个问题。
代理服务器是位于客户端和目标服务器之间的一台服务器,它接收客户端发送的请求,并将请求转发给目标服务器。通过在代理服务器上进行请求转发,可以绕过浏览器的同源策略限制,从而实现跨域请求。
在vue.config.js文件中添加以下内容:
二. 二次开发
- 若依框架修改器:修改包名,项目名
- 新建业务模块
注意:若有加载不出来ruoyi-merchant模块,可以选择mvn clean清理一下重新加载
- 新建模块sys-merchant,添加sysmerchant模块依赖
<!-- 核心模块-->
<dependency>
<groupId>com.sky</groupId>
<artifactId>sky-framework</artifactId>
</dependency>
- 在父工程中进行版本锁定
<!-- 商家管理-->
<dependency>
<groupId>com.sky</groupId>
<artifactId>sky-merchant</artifactId>
<version>${sky.version}</version>
</dependency>
- 在sky-admin模块中添加sky-merchant依赖
<!-- 商家管理-->
<dependency>
<groupId>com.sky</groupId>
<artifactId>sky-merchant</artifactId>
</dependency>
- 新建数据表,代码生成
菜品表(tb_dish)和口味表(tb_dish_flavor)是一对多的关系,因此,可以利用代码生成框架的主子表进行生成
- 个性化定制
- 修改图片上传组件访问地址,如果image字段存储的图片地址没有https,则不需要在拼接服务器地址。
- 实现在新增表单中口味名称和口味列表联动
为了能实现联动效果,可以在前端存储静态数据,当选择口味名称时,根据口味名称查找对应的口味列表数据。
注意: label为展示的下拉框的数据,value为实际上提交的数据
<el-table-column label="口味名称" prop="name" width="150">
<template #default="scope">
<el-select v-model="scope.row.name" placeholder="请选择口味名称" @change="changeFalvorName(scope.row)">
<el-option
v-for="dish_Flavor in dishFlavorListSelect"
:key="dish_Flavor.name"
:label="dish_Flavor.name"
:value="dish_Flavor.name"
/>
</el-select>
</template>
</el-table-column>
<el-table-column label="口味列表" prop="value" width="350">
<template #default="scope">
<el-select v-model="scope.row.value" placeholder="请选择口味列表" multiple @focus="foucusFlavorname(scope.row)" style="width: 90%;">
<el-option
v-for="value in checkedDishFlavorList"
:key="value"
:label="value"
:value="value"
/>
</el-select>
</template>
</el-table-column>
//定义口味名称和口味列表静态数据
const dishFlavorListSelect = ref([
{ name: '辣度', value: ["不辣","微辣","中辣","重辣" ]},
{ name: '忌口', value: ["不要葱","不要蒜","不要香菜","不要辣" ]},
{ name: '甜味', value: ["无糖","少糖","半糖","多糖"] },
]);
//存储当前选中口味列表数组
const checkedDishFlavorList = ref([]);
function changeFalvorName(row){
//清空当前行value
row.value=[]
//根据当前口味名称获取口味列表
checkedDishFlavorList.value = dishFlavorListSelect.value.find(item => item.name === row.name).value;
console.log(checkedDishFlavor)
}
直接提交数据,发现value属性为list
在提交后会发现不能将list类型转为string类型,因为在添加multiple属性后,绑定的value属性的值的类型为list类型,而后台在数据库中存储为string类型,因此在提交时,必须对value属性进行序列化,回显示,进行反序列化
//提交时,将口味列表中value通过Json工具序列化
if(form.value.dishFlavorList !=null){
form.value.dishFlavorList.forEach(item => {
item.value= JSON.stringify(item.value)
});
}
//回显时,反序列化
if(dishFlavorList.value !=null){
dishFlavorList.value.forEach(item=>{
item.value=JSON.parse(item.value)
})
- 实现在修改表单中点击口味列表可以在显示列表
根据口味名称和口味列表联动逻辑,只有当改变口味名称时,才会加载对应的口味列表数据,因此当在修改表单中,由于没有改变已加载的口味名称,故对应的口味列表数据并未进行加载,因此下拉框无数据。因此可以增加焦点事件,当展开下来框时可以调用方法,获取对应的口味列表数据
注意:修改表单和新增表单复用同一个表单,根据id是否为null来进行区分是新增还是修改,最终选择不同的后端接口提交。(在新增按钮操作和修改按钮操作执行时首先要执行reset方法,以此来防止造成影响。如果不首先执行reset(),如果先进行修改操作,没有清空表单,然后再新增操作,那么id值一定不为null,因此请求的后端接口有误)。
- 页面调整
- 浏览器标签页logo标识、标题
找到根目录下的index.html文件,把title更换为自己想要的内容即可
-
系统页面中的logo标识、标题
替换 src/assets/logo/logo.png文件
若依的系统页面标题引用的是开发环境的配置,我们只需要修改开发的环境的VITE_APP_TITLE属性即可
-
去除源码地址 & 文档地址
-
主题风格和菜单图标
-
登录名称及背景图