赞
踩
情景描述:Ruoyi框架自动生成的代码,对应的只按照一个主键来进行操作,在面临多个或联合主键时,会出现操作上的误解。
推荐解决方法:调整后端接口逻辑。
1、打开管理员后台,在页面内进行新增操作。(假设对应的联合主键表为:A)
发现只是将对应的修改。
2、直接在数据库中添加2条数据。选择修改,报错。
3、删除时,会直接将同id下的数据全部删除
(1)定位到对应的.vue文件,一般在ruoyi-ui模块的src目录,views下
比如我的:ruoyi-ui/src/views/user_fill_content/user_content/index.vue
(2)找到对应的修改和增加代码区域:定位到JS逻辑处理区
(3)定位到submitForm()函数,发现是form的值来进行操作的,而form的获取由按钮处理操作来获取。
(4)我们发现,按钮处理操作是按照一个单独的id来判断,并非是双主键,问题所在。
(5)删除同理:
(1)找到<script>开头的import,crtl+左键,点进去。找url,选中末尾,crtl+左键
(2)下面以删除为例:查看对应的mapper.xml
(3)定位到删除:发现如猜测一样,单主键进行操作。比如我的:
- <delete id="deleteUserFillContentBySpecificEventId" parameterType="Long">
- delete from user_fill_content where specific_event_id = #{specificEventId}
- </delete>
- <!--我的表中,还有个user_id,联合做主键-->
(这是各层示意图)
重写sql(建议重命名,以便区分):完成查找和删除的操作。
- <!--查找:id可以随便起,需要和mapper.java类中方法一致,-->
- <!--这里我parameterType用的Map,方便接口传递多个主键,且更直观。-->
- <!--在where 语句里把主键属性补上即可,比如我这两个属性:specificEventId与userId-->
- <select id="selectUserFillContentBySpecificEventIdAndUserId" parameterType="java.util.Map"
- resultMap="UserFillContentResult">
- <include refid="selectUserFillContentVo"/>
- where specific_event_id = #{specificEventId} and user_id = #{userId}
- </select>
-
- <delete id="deleteUserFillContentBySpecificEventIdAndUserId" parameterType="java.util.Map"
- delete from user_fill_content
- where specific_event_id = #{specificEventId} and user_id = #{userId}
- </delete>
限制修改操作的属性,注意此处。业务规则:主键部分不让修改
- <update id="updateUserFillContent" parameterType="com.ruoyi.act.user_fill_content.domain.UserFillContent">
- update user_fill_content
- <trim prefix="SET" suffixOverrides=",">
- <if test="specificFillContent != null and specificFillContent != ''">specific_fill_content = #{specificFillContent},</if>
- <!-- 注释掉这个主键 <if test="userId != null">user_id = #{userId},</if>-->
- <if test="formId != null">form_id = #{formId},</if>
- </trim>
- where specific_event_id = #{specificEventId} and user_id=#{userId}
- <!-- 依据联合主键来定位-->
- </update>
- public int deleteUserFillContentBySpecificEventIdAndUserId(Map usermap);
- //把方法名称换为你在xml写的id
- public UserFillContent selectUserFillContentBySpecificEventIdAndUserId(Map userMap);
比如我的:IUserFillContentService
直接把上文添加的复制过来就可以。名称可以自定义,但建议保持和上文一致,注释可以不写。
- /**
- * 依据具体事件编号和用户id查询用户填写内容
- *
- * @param specificEventId 用户填写内容主键
- * userId 填写者编号
- * @return 用户填写内容
- */
- public UserFillContent selectUserFillContentBySpecificEventIdAndUserId(Map userMap);
-
- /**
- * 依据具体事件编号和用户id删除用户填写内容
- *
- * @param usermap 用户填写内容主键
- * @return 结果
- */
- public int deleteUserFillContentBySpecificEventIdAndUserId(Map usermap);
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
比如我的:UserFillContentServiceImpl文件
- //方法的返回值,就是对应的Mapper文件中,我们新增的方法的返回值。直接xxMapper.就行
- //注意;方法返回值要保持一致。方法参数一直是Map
-
- @Override
- public int deleteUserFillContentBySpecificEventIdAndUserId(Map usermap) {
- return userFillContentMapper.deleteUserFillContentBySpecificEventIdAndUserId(usermap);
- }
- }
-
- @Override
- public UserFillContent selectUserFillContentBySpecificEventIdAndUserId(Map userMap) {
- return userFillContentMapper.selectUserFillContentBySpecificEventIdAndUserId(userMap);
- }
比如我的:UserFillContentController文件
- @ApiOperation("依据具体事件编号和用户id删除用户填写内容")
- //这是权限验证,可以注释掉不管@PreAuthorize("@ss.hasPermi('user_fill_content:user_content:remove')")
- @Log(title = "用户填写内容", businessType = BusinessType.DELETE)
- //日志相关
- @DeleteMapping("/{specificEventId}/{userId}")
- //写你的接口使用形式,这里直接对应的传递所有主键即可,比如我的specificEventId、userId
- //removeBySpeId_UserId为自定义名称
- public AjaxResult removeBySpeId_UserId(@PathVariable Long specificEventId,@PathVariable Long userId)
- //@PathVariable说明需要的参数,一共两个
- {
- HashMap<String, Object> userMap = new HashMap<>();
- userMap.put("specificEventId",specificEventId);
- userMap.put("userId",userId);
- //以map的形式存储,从而接收所有主键。
- return toAjax(userFillContentService.deleteUserFillContentBySpecificEventIdAndUserId(userMap));
- }
-
-
- @ApiOperation("依据具体事件编号和用户id获取用户填写内容详细信息")
- //@PreAuthorize("@ss.hasPermi('user_fill_content:user_content:query')")
- @GetMapping(value = "/{specificEventId}/{userId}")
- public AjaxResult getInfoBySpeId_UserId(@PathVariable("specificEventId") Long specificEventId,@PathVariable("userId") Long userId)
- {
- HashMap<String, Object> userMap = new HashMap<>();
- userMap.put("specificEventId",specificEventId);
- userMap.put("userId",userId);
- return success(userFillContentService.selectUserFillContentBySpecificEventIdAndUserId(userMap));
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
比如我的:user_content.js文件
- //依据具体事件编号和用户id获取用户填写内容详细信息
- export function getInfoBySpeId_UserId(specificEventId,userId) {
- return request({
- url: '/user_fill_content/user_content/' + specificEventId + '/' +userId,
- method: 'get'
- })
- }
- //这一步就是把上一步写的复制下
-
- //把名字和参数替换为你的即可
-
- // 依据具体事件编号和用户id删除用户填写内容
- export function removeBySpeId_UserId(specificEventId,userId) {
- return request({
- url: '/user_fill_content/user_content/' + specificEventId+ '/' +userId,
- method: 'delete'
- })
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
(1)引入新添加的接口,import导入:
import {removeBySpeId_UserId, getInfoBySpeId_UserId} from "@/api/user_fill_content/user_content";
(2)修改按钮操作的处理逻辑:
在data内定义一个数组,存储选择的id
- //在data内定义一个数组,用于选中时定位id
- data() {
- return {
- userIds: [], //定义的id
- }
- }
找到:handleSelectionChange()方法:进行userIds的数据获取
- // 多选框选中数据
- handleSelectionChange(selection) {
- this.ids = selection.map(item => item.specificEventId)
- this.userIds = selection.map(item => item.userId) //新增方法,和上一行类似
- this.single = selection.length !== 1
- this.multiple = !selection.length
- },
声明一个对象,用于存储另一个主键。同时更改接口的使用。
- /** 修改按钮操作 */
- handleUpdate(row) {
- this.reset();
- const specificEventId = row.specificEventId || this.ids
- const userId = row.userId || this.userIds //这是新添加的
- //将接口换为你写的get,比如我的为:getInfoBySpeId_UserId,获取准确的内容
- getInfoBySpeId_UserId(specificEventId, userId).then(res => {
- this.form = res.data;
- this.open = true;
- this.title = "修改用户填写内容";
- });
(3)修改删除逻辑:
- /** 删除按钮操作 */
- handleDelete(row) {
- const specificEventId = row.specificEventId || this.ids;
- const userId = row.userId || this.userIds;//这是新添加的
- this.$modal.confirm('是否确认删除用户填写内容编号为"' + specificEventId +'用户编号为:'+ userId + '"的数据项?').then(function () {
- //将接口换为你写的delete,比如我的为:removeBySpeId_UserId,定位准确的内容
- return removeBySpeId_UserId(specificEventId,userId);
- }).then(() => {
- this.getList();
- this.$modal.msgSuccess("删除成功");
- }).catch(() => {
- });
- },
(4)建议分开添加或修改用户填写内容对话框:
- v-if="title==='修改用户填写内容'"
- //在<el-dialog>标签内,替换为你的对应的操作title
对应的@click也更改下,一个添加、一个修改。
(5)完善添加、修改逻辑
-
- /** 添加按钮 */
-
- submitForm_add() {
- this.$refs["form"].validate(valid => {
- if (valid) {
- addUser_content(this.form).then(response => {
- this.$modal.msgSuccess("新增成功");
- this.open = false;
- this.getList();
- });
- }
- });
- },
- /** 修改按钮 */
- submitForm_update() {
- this.$refs["form"].validate(valid => {
- if (valid)) {
- updateUser_content(this.form).then(response => {
- this.$modal.msgSuccess("修改成功");
- this.open = false;
- this.getList();
- });
- }
- });
- },
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
(1)添加前:
(2)添加后:
(1)选择修改
(2)修改之后
(1)选择删除
(2)删除后
验证完毕,整体符合正常使用的逻辑。因为整体书写花费时间比较长,可能有些地方存在遗漏,欢迎补充。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。