福建定制网站开发,wordpress获取文章作者id,做网站文章要一篇一篇的写吗,wordpress newsplus文章目录什么是若依使用若依验证码的前端实现#x1f4cc; 前后端验证码流程说明文档1、前端初始化验证码2、前端界面显示3、后端生成验证码接口#xff08;GET /captchaImage#xff09;4、用户提交登录信息5、后端验证验证码逻辑#xff08;POST /login#xff09;6、登…
文章目录什么是若依使用若依验证码的前端实现 前后端验证码流程说明文档1、前端初始化验证码2、前端界面显示3、后端生成验证码接口GET /captchaImage4、用户提交登录信息5、后端验证验证码逻辑POST /login6、登录失败处理前端新增岗位功能详细解析一、前端实现流程1. 用户触发新增操作2. 初始化表单3. 表单结构4. 表单验证规则5. 提交表单二、后端实现流程1. 控制器接收请求2. 唯一性校验3. 数据插入实现4. 实体类验证三、关键特性与设计思想四、完整数据流修改岗位功能详细解析一、前端实现流程1. 修改按钮触发 (Post.vue)2. 处理修改操作 (Post.vue)3. 获取岗位详情API (post.js)4. 表单提交处理 (Post.vue)5. 修改岗位API (post.js)二、后端实现流程1. 控制器接收请求 (SysPostController.java)2. 服务层处理 (SysPostServiceImpl.java)3. 唯一性校验逻辑 (SysPostServiceImpl.java)4. Mapper层SQL (SysPostMapper.xml)三、关键设计要点删除岗位功能详细解析一、前端实现流程1. 删除触发方式2. 删除处理逻辑3. 关键处理步骤二、后端实现流程1. 控制器入口2. 服务层实现3. 关键业务逻辑三、安全与完整性设计1. 多级保护机制2. 外键约束建议DDL示例四、异常处理流程1. 业务异常处理2. 前端异常处理五、设计亮点分析六、完整工作流程查询岗位功能详细解析一、查询功能分类二、分页条件查询核心功能1. 前端实现流程2. 后端实现流程3. 分页机制三、导出查询1. 前端实现2. 后端实现四、详情查询单个岗位查询1. 前端实现2. 后端实现五、查询功能设计亮点六、复杂查询场景处理统计查询岗位导出功能详细解析一、前端实现流程1. 导出按钮触发2. 导出处理逻辑3. 下载方法封装二、后端实现流程1. 控制器入口2. 实体类Excel注解什么是若依
提示这里可以添加本文要记录的大概内容
若依是开源项目便于二次开发百度直接搜索若依官网
1、减少了自己的代码量
2、学习优秀开源项目底层的编程思想设计思路提高自己的编程能力
使用若依
使用开源项目的步骤
1、下载并运行 启动后端
启动前端VS CODE 插件GitHub Copilot ChatAgent模式下 项目成功启动页面
2、看懂业务流程
3、进行二次开发
验证码的前端实现
后端生成一个表达式
112
11?211?转成图片传到前端展示答案2存入Redis
输入答案点击登录就把表单存入后台了这时候从Redis中把正确答案拿出来两个答案对比 前后端验证码流程说明文档
1、前端初始化验证码
在 Vue 的 script setup 中组件挂载时会调用 getCode() 函数初始化验证码。
getCode() 函数逻辑
getCode().then(res {captchaEnabled.value res.captchaEnabled undefined ? true : res.captchaEnabledif (captchaEnabled.value) {codeUrl.value data:image/gif;base64, res.imgloginForm.value.uuid res.uuid}
})captchaEnabled.value根据后端返回决定是否启用验证码默认启用codeUrl.value将 base64 图片数据拼接为可直接显示的 URLloginForm.value.uuid保存后端返回的验证码唯一标识UUID 2、前端界面显示
在模板中通过 v-ifcaptchaEnabled 控制验证码区域的显示
el-form-item propcode v-ifcaptchaEnabledel-input v-modelloginForm.code placeholder验证码 /div classlogin-codeimg :srccodeUrl clickgetCode title点击刷新验证码 //div
/el-form-item点击图片时重新调用 getCode()刷新验证码用户输入验证码后与 uuid 一起提交给后端 3、后端生成验证码接口GET /captchaImage
通过getCodeImg引入
找到对应代码 解释 定义一个名为 getCodeImg 的函数 request这是封装好的 Axios 请求函数通常是项目中封装的 HTTP 请求方法。 整个 request({ ... }) 是一个 HTTP 请求配置对象。 请求的后端接口地址是 /captchaImage
使用 HTTP 的 GET 方法发送请求用于获取数据
设置请求超时时间为 20 秒20000 毫秒如果 20 秒内没有返回结果请求将自动中断并进入 .catch() 分支。
在登录页F12
打开 request 文件 创建一个 Axios 实例 service用于发起 HTTP 请求 配置该实例的基础 URL 为一个环境变量实现环境自适应 设置请求超时时间为 10 秒防止请求长时间挂起
值在配置文件中定义配置文件
4、用户提交登录信息
用户点击登录时前端调用 handleLogin() 提交数据
userStore.login(loginForm.value)提交内容包括
username用户名password密码code用户输入的验证码uuid当前验证码的唯一标识 5、后端验证验证码逻辑POST /login
登录请求
export function login(username, password, code, uuid) {return request({url: /login,method: post,data: { username, password, code, uuid }})
}后端伪代码逻辑
function login(username, password, code, uuid) {// 1. 检查是否启用验证码if (captchaEnabled) {// 2. 从 Redis 获取验证码String redisCode redis.get(uuid);// 3. 验证码比对忽略大小写if (!redisCode || !redisCode.equalsIgnoreCase(code)) {return error(验证码错误);}// 4. 删除已使用的验证码redis.delete(uuid);}// 5. 继续账号密码验证...
}6、登录失败处理前端
userStore.login(loginForm.value).catch(() {loading.value falseif (captchaEnabled.value) {getCode() // 登录失败时刷新验证码}
})登录失败时自动刷新验证码防止暴力破解用户点击图片也可手动刷新验证码 完整流程图
getCodeImg()↓
调用 request()↓
发送 GET 请求到 /captchaImage↓
请求头中设置 isToken false表示不需要 token↓
等待响应最多 20 秒↓
返回 base64 图片和 uuid新增岗位功能详细解析
新增功能是岗位管理系统的核心操作之一涉及前后端协同工作。下面从用户操作到数据存储的完整流程进行详细解析
一、前端实现流程
1. 用户触发新增操作
el-button typeprimary plain iconPlusclickhandleAddv-hasPermi[system:post:add]
新增/el-buttonv-hasPermi指令校验用户是否有system:post:add权限点击按钮触发handleAdd方法
2. 初始化表单
function handleAdd() {reset() // 重置表单数据open.value true // 打开对话框title.value 添加岗位 // 设置对话框标题
}function reset() {form.value {postId: undefined,postCode: undefined,postName: undefined,postSort: 0,status: 0,remark: undefined}proxy.resetForm(postRef) // 重置表单验证状态
}初始化表单对象设置默认值如状态默认为0正常重置表单验证状态清除之前的错误提示
3. 表单结构
el-dialog :titletitle v-modelopen width500pxel-form refpostRef :modelform :rulesrules label-width80pxel-form-item label岗位名称 proppostNameel-input v-modelform.postName placeholder请输入岗位名称 //el-form-itemel-form-item label岗位编码 proppostCodeel-input v-modelform.postCode placeholder请输入编码名称 //el-form-item!-- 其他字段... --/el-form
/el-dialog使用el-dialog组件实现模态对话框el-form绑定表单数据和验证规则
4. 表单验证规则
const rules {postName: [{ required: true, message: 岗位名称不能为空, trigger: blur }],postCode: [{ required: true, message: 岗位编码不能为空, trigger: blur }],postSort: [{ required: true, message: 岗位顺序不能为空, trigger: blur }],
}定义字段级验证规则required标记必填字段trigger: blur表示失去焦点时触发验证
5. 提交表单
function submitForm() {proxy.$refs[postRef].validate(valid {if (valid) {addPost(form.value).then(response {proxy.$modal.msgSuccess(新增成功)open.value false // 关闭对话框getList() // 刷新列表})}})
}触发表单验证验证通过后调用addPost API显示操作成功提示关闭对话框并刷新岗位列表
二、后端实现流程
1. 控制器接收请求
PostMapping
PreAuthorize(ss.hasPermi(system:post:add))
Log(title 岗位管理, businessType BusinessType.INSERT)
public AjaxResult add(Validated RequestBody SysPost post) {// 唯一性校验if (!postService.checkPostNameUnique(post)) {return error(新增岗位 post.getPostName() 失败岗位名称已存在);} else if (!postService.checkPostCodeUnique(post)) {return error(新增岗位 post.getPostName() 失败岗位编码已存在);}// 设置创建人post.setCreateBy(getUsername());// 执行插入return toAjax(postService.insertPost(post));
}PostMapping处理POST请求PreAuthorize校验用户权限Log记录操作日志类型为INSERTValidated触发实体类字段验证RequestBody接收JSON格式的岗位数据
2. 唯一性校验
// 校验岗位名称唯一性Overridepublic boolean checkPostNameUnique(SysPost post) {Long postId StringUtils.isNull(post.getPostId()) ? -1L : post.getPostId();SysPost info postMapper.checkPostNameUnique(post.getPostName());if (StringUtils.isNotNull(info) info.getPostId().longValue() ! postId.longValue()) {return UserConstants.NOT_UNIQUE;}return UserConstants.UNIQUE;}// Mapper查询
Select(select * from sys_post where post_name #{postName} limit 1)
SysPost checkPostNameUnique(String postName);查询数据库是否存在相同岗位名称排除当前岗位自身更新时使用同样逻辑校验岗位编码唯一性
3. 数据插入实现
// 服务层
public int insertPost(SysPost post) {return postMapper.insertPost(post);
}// Mapper XML
insert idinsertPost parameterTypeSysPost useGeneratedKeystrue keyPropertypostIdinsert into sys_post(if testpostId ! null and postId ! 0post_id,/ifif testpostCode ! null and postCode ! post_code,/ifif testpostName ! null and postName ! post_name,/ifif testpostSort ! nullpost_sort,/ifif teststatus ! null and status ! status,/ifif testremark ! null and remark ! remark,/ifif testcreateBy ! null and createBy ! create_by,/ifcreate_time)values(if testpostId ! null and postId ! 0#{postId},/ifif testpostCode ! null and postCode ! #{postCode},/ifif testpostName ! null and postName ! #{postName},/ifif testpostSort ! null#{postSort},/ifif teststatus ! null and status ! #{status},/ifif testremark ! null and remark ! #{remark},/ifif testcreateBy ! null and createBy ! #{createBy},/ifsysdate())
/insert动态生成SQL语句useGeneratedKeystrue获取自增主键自动填充创建时间和创建人只插入非空字段提高灵活性
4. 实体类验证
public class SysPost extends BaseEntity {/*** 岗位编码*/Excel(name 岗位编码)private String postCode;/*** 岗位名称*/Excel(name 岗位名称)private String postName;/*** 岗位排序*/Excel(name 岗位排序)private Integer postSort;// 其他字段
}NotBlank验证非空字符串Size限制字符串长度NotNull确保数值字段不为空验证失败自动返回错误信息给前端
三、关键特性与设计思想 多层验证机制 前端Element Plus表单验证网络层JSON格式校验后端JSR-303实体验证业务层唯一性校验数据库唯一约束需在DDL中定义 操作审计 通过Log注解自动记录 Log(title 岗位管理, businessType BusinessType.INSERT)安全控制 权限校验PreAuthorize(ss.hasPermi(system:post:add)数据隔离自动注入当前用户getUsername() 响应式设计 前端提交后自动刷新列表后端返回标准化的AjaxResult对象 异常处理 唯一性冲突返回可读性错误信息数据库操作异常全局处理
四、完整数据流
用户点击新增按钮前端打开对话框并重置表单用户填写表单并提交前端进行字段级验证验证通过后调用/system/post POST API后端控制器接收请求 权限校验实体字段验证业务规则校验唯一性 服务层设置创建人Mapper执行动态SQL插入返回操作结果成功/失败前端提示结果并刷新列表
这种设计实现了前后端分离架构下的高效协作通过多层验证保证数据质量利用注解简化开发同时确保系统的安全性和可维护性。
修改岗位功能详细解析
我将详细讲解岗位管理模块中的修改功能从前端到后端的完整实现流程。修改功能是CRUD操作中的重要环节涉及数据加载、校验、更新等多个关键步骤。
一、前端实现流程
1. 修改按钮触发 (Post.vue)
el-table-column label操作 aligncenter class-namesmall-padding fixed-widthtemplate #defaultscopeel-button link typeprimary iconEdit clickhandleUpdate(scope.row) v-hasPermi[system:post:edit]修改/el-button/template
/el-table-column在表格操作列中放置修改按钮使用v-hasPermi指令进行权限控制点击时调用handleUpdate方法并传入当前行数据
2. 处理修改操作 (Post.vue)
// 修改按钮操作
function handleUpdate(row) {reset(); // 重置表单状态const postId row.postId; // 获取当前岗位IDgetPost(postId).then(response {form.value response.data; // 填充表单数据open.value true; // 打开对话框title.value 修改岗位; // 设置对话框标题});
}执行流程
重置表单状态确保无残留数据从行数据中获取岗位ID调用API获取岗位详细信息将返回数据填充到表单打开对话框并设置标题
3. 获取岗位详情API (post.js)
// 查询岗位详细
export function getPost(postId) {return request({url: /system/post/ postId,method: get})
}向后台发送GET请求URL格式/system/post/{postId}获取指定ID的岗位详情
4. 表单提交处理 (Post.vue)
// 提交按钮
function submitForm() {proxy.$refs[postRef].validate(valid {if (valid) {if (form.value.postId ! undefined) {// 修改操作updatePost(form.value).then(response {proxy.$modal.msgSuccess(修改成功);open.value false; // 关闭对话框getList(); // 刷新列表})} else {// 新增操作...}}});
}先进行表单验证根据postId判断是修改还是新增调用updatePostAPI提交修改成功后关闭对话框并刷新列表
5. 修改岗位API (post.js)
// 修改岗位
export function updatePost(data) {return request({url: /system/post,method: put,data: data})
}使用HTTP PUT方法将整个表单数据作为请求体发送URL为/system/post
二、后端实现流程
1. 控制器接收请求 (SysPostController.java)
PreAuthorize(ss.hasPermi(system:post:edit))
Log(title 岗位管理, businessType BusinessType.UPDATE)
PutMapping
public AjaxResult edit(Validated RequestBody SysPost post) {// 唯一性校验if (!postService.checkPostNameUnique(post)) {return error(修改岗位 post.getPostName() 失败岗位名称已存在);} else if (!postService.checkPostCodeUnique(post)) {return error(修改岗位 post.getPostName() 失败岗位编码已存在);}// 设置更新人post.setUpdateBy(getUsername());// 执行更新return toAjax(postService.updatePost(post));
}执行流程
PreAuthorize进行权限校验Log记录操作日志Validated进行参数校验基于JSR-303校验岗位名称和编码的唯一性设置更新人当前登录用户调用服务层执行更新
2. 服务层处理 (SysPostServiceImpl.java)
Override
public int updatePost(SysPost post) {return postMapper.updatePost(post);
}直接调用Mapper层执行更新返回影响行数
3. 唯一性校验逻辑 (SysPostServiceImpl.java)
Override
public boolean checkPostNameUnique(SysPost post) {Long postId StringUtils.isNull(post.getPostId()) ? -1L : post.getPostId();SysPost info postMapper.checkPostNameUnique(post.getPostName());if (StringUtils.isNotNull(info) info.getPostId().longValue() ! postId.longValue()) {return UserConstants.NOT_UNIQUE;}return UserConstants.UNIQUE;
}校验逻辑
获取当前岗位ID修改时为真实ID新增时为null查询数据库是否存在相同名称的岗位如果存在同名岗位 且ID不同表示是其他岗位的同名返回不唯一且ID相同表示是自身允许更新
4. Mapper层SQL (SysPostMapper.xml)
update idupdatePost parameterTypeSysPostupdate sys_postsetif testpostCode ! null and postCode ! post_code #{postCode},/ifif testpostName ! null and postName ! post_name #{postName},/ifif testpostSort ! nullpost_sort #{postSort},/ifif teststatus ! null and status ! status #{status},/ifif testremark ! nullremark #{remark},/ifif testupdateBy ! null and updateBy ! update_by #{updateBy},/ifupdate_time sysdate()/setwhere post_id #{postId}
/updateSQL特点
使用动态SQLset和if标签只更新非空字段自动设置更新时间使用数据库函数设置时间sysdate()根据postId定位记录
三、关键设计要点 权限控制双重保障 前端v-hasPermi指令控制按钮显示后端PreAuthorize注解进行方法级权限校验 数据一致性保证 唯一性校验防止名称/编码重复事务管理确保更新操作的原子性 审计字段自动化 自动记录更新人post.setUpdateBy(getUsername())自动更新时间update_time sysdate() 前后端校验结合 前端Element Plus表单校验后端JSR-303参数校验 业务逻辑校验 性能优化 动态SQL只更新变化的字段最小化数据传输前端只发送必要字段 用户体验优化 修改前加载完整数据操作成功自动刷新列表明确的错误提示信息
删除岗位功能详细解析
删除功能是岗位管理系统中最敏感的操作之一需要特别关注数据完整性和安全控制。下面从前后端协同角度深入解析删除功能的实现
一、前端实现流程
1. 删除触发方式
前端支持两种删除模式
!-- 单个删除行内操作 --
el-table-column label操作template #defaultscopeel-button link typeprimary iconDelete clickhandleDelete(scope.row) v-hasPermi[system:post:remove]删除/el-button/template
/el-table-column!-- 批量删除顶部操作栏 --
el-buttontypedangerplainiconDelete:disabledmultipleclickhandleDeletev-hasPermi[system:post:remove]
删除/el-button2. 删除处理逻辑
function handleDelete(row) {// 获取待删除的岗位IDconst postIds row.postId || ids.value;// 确认对话框proxy.$modal.confirm(是否确认删除岗位编号为 postIds 的数据项).then(function() {// 调用删除APIreturn delPost(postIds);}).then(() {// 删除成功后刷新列表getList();proxy.$modal.msgSuccess(删除成功);}).catch(() {// 用户取消操作});
}3. 关键处理步骤
获取删除目标 单个删除从行数据获取row.postId批量删除从选中的ids数组中获取多个ID const postIds row.postId || ids.value;二次确认 使用$modal.confirm显示确认对话框明确显示将被删除的岗位编号 API调用 调用delPost方法发送删除请求支持单个ID或ID数组自动处理 结果反馈 成功显示删除成功提示失败全局异常处理已在底层封装 状态更新 刷新岗位列表数据重置选中状态
二、后端实现流程
1. 控制器入口
PreAuthorize(ss.hasPermi(system:post:remove))
Log(title 岗位管理, businessType BusinessType.DELETE)
DeleteMapping(/{postIds})
public AjaxResult remove(PathVariable Long[] postIds) {return toAjax(postService.deletePostByIds(postIds));
}DeleteMapping处理DELETE请求PathVariable获取URL路径中的岗位ID数组PreAuthorize权限校验需system:post:remove权限Log记录操作日志类型为DELETE
2. 服务层实现
Override
public int deletePostByIds(Long[] postIds) {// 1. 检查岗位是否被用户使用for (Long postId : postIds) {SysPost post selectPostById(postId);if (countUserPostById(postId) 0) {throw new ServiceException(String.format(%1$s已分配,不能删除, post.getPostName()));}}// 2. 执行批量删除return postMapper.deletePostByIds(postIds);
}3. 关键业务逻辑
使用状态检查 // 查询岗位用户关联数量public int countUserPostById(Long postId) {return userPostMapper.countUserPostById(postId);}// SysUserPostMapper.xmlselect idcountUserPostById resultTypeintSELECT COUNT(1) FROM sys_user_post WHERE post_id #{postId}/select安全删除机制 遍历每个待删除岗位检查sys_user_post关联表如果存在关联用户抛出业务异常包含岗位名称的友好错误提示 批量删除执行 delete iddeletePostByIds parameterTypeLongDELETE FROM sys_post WHERE post_id INforeach collectionarray itempostId open( separator, close)#{postId}/foreach/delete使用MyBatis的foreach处理ID数组生成DELETE FROM sys_post WHERE post_id IN (1,2,3)语句
三、安全与完整性设计
1. 多级保护机制
层级保护措施目的前端v-hasPermi指令控制按钮显示网络JWT令牌验证身份认证应用PreAuthorize注解方法级权限控制数据关联检查防止误删使用中的岗位数据库外键约束最终数据保护
2. 外键约束建议DDL示例
CREATE TABLE sys_user_post (user_id BIGINT NOT NULL,post_id BIGINT NOT NULL,PRIMARY KEY (user_id, post_id),FOREIGN KEY (post_id) REFERENCES sys_post(post_id)ON DELETE RESTRICT -- 阻止删除被引用的岗位
);四、异常处理流程
1. 业务异常处理
// 服务层抛出异常
if (countUserPostById(postId) 0) {throw new ServiceException(String.format(%1$s已分配不能删除, post.getPostName()));
}// 全局异常处理器
ExceptionHandler(ServiceException.class)
public AjaxResult handleServiceException(ServiceException e) {return AjaxResult.error(e.getMessage());
}返回HTTP 200状态码前端能处理的业务异常错误信息格式{ code: 500, msg: 岗位已分配不能删除 }
2. 前端异常处理
// post.js API封装
export function delPost(postId) {return request({url: /system/post/ postId,method: delete})
}// 全局响应拦截器
service.interceptors.response.use(response {const res response.data;if (res.code ! 200) {// 显示后端返回的错误信息Message.error(res.msg || Error);return Promise.reject(new Error(res.msg || Error));}return res;},error {// 处理HTTP错误如401, 500等}
);五、设计亮点分析 批量操作优化 单次数据库交互完成批量删除IN语句减少数据库连接开销 用户友好设计 明确提示哪个岗位无法删除二次确认避免误操作批量选择状态自动管理 事务完整性 Transactional(rollbackFor Exception.class)public int deletePostByIds(Long[] postIds) {// 操作在同一个事务中}整个删除操作原子性执行检查与删除要么全成功要么全回滚
前后端协作 RESTful风格APIDELETE /system/post/{ids}统一的ID传递格式数组自动转换标准化的响应格式AjaxResult
六、完整工作流程 前端操作 用户选择单个/多个岗位点击删除按钮确认删除提示 请求发送 DELETE /system/post/12,34,56Authorization: Bearer xxxx后端处理 权限验证PreAuthorize日志记录Log遍历检查每个岗位使用状态执行批量删除SQL返回操作结果 结果反馈 成功{ code: 200, msg: 操作成功 }失败{ code: 500, msg: 经理岗位已分配不能删除 } 前端响应 显示操作结果提示刷新岗位列表重置选中状态
这种设计确保了删除操作的安全性、完整性和用户体验通过多层校验防止数据误删同时提供清晰的反馈帮助用户理解操作结果。
查询岗位功能详细解析
我将详细讲解岗位管理模块中的各种查询功能包括分页查询、条件过滤、详情查询和下拉框查询等。查询功能是系统的核心基础功能设计良好的查询机制能极大提升用户体验。
一、查询功能分类
查询类型前端调用方法后端接口主要用途分页条件查询listPost(query)GET /system/post/list管理页面主列表展示导出查询同分页查询POST /system/post/exportExcel导出功能详情查询getPost(postId)GET /system/post/{postId}查看/修改单个岗位详情下拉框查询optionselect()GET /system/post/optionselect用户管理中的岗位选择下拉框
二、分页条件查询核心功能
1. 前端实现流程
页面组件 (Post.vue)
template!-- 搜索表单 --el-form :modelqueryParams refqueryRef :inlinetrue v-showshowSearchel-form-item label岗位编码 proppostCodeel-inputv-modelqueryParams.postCodeplaceholder请输入岗位编码clearablestylewidth: 200pxkeyup.enterhandleQuery//el-form-itemel-form-itemel-button typeprimary iconSearch clickhandleQuery搜索/el-buttonel-button iconRefresh clickresetQuery重置/el-button/el-form-item/el-form!-- 数据表格 --el-table :datapostList v-loadingloading!-- 表格列定义 --el-table-column label岗位编码 aligncenter proppostCode //el-table!-- 分页组件 --pagination :totaltotal v-model:pagequeryParams.pageNumv-model:limitqueryParams.pageSizepaginationgetList/
/templatescript setup
import { listPost } from /api/system/post;// 查询参数
const queryParams reactive({pageNum: 1, // 当前页码pageSize: 10, // 每页条数postCode: , // 岗位编码条件postName: , // 岗位名称条件status: // 状态条件
});// 岗位列表数据
const postList ref([]);
// 总记录数
const total ref(0);
// 加载状态
const loading ref(true);// 获取岗位列表
function getList() {loading.value true;listPost(queryParams).then(response {postList.value response.rows; // 当前页数据total.value response.total; // 总记录数loading.value false;});
}// 处理搜索
function handleQuery() {queryParams.pageNum 1; // 重置到第一页getList();
}// 初始化加载数据
getList();
/script2. 后端实现流程
Controller层 (SysPostController.java)
PreAuthorize(ss.hasPermi(system:post:list))
GetMapping(/list)
public TableDataInfo list(SysPost post) {// 1. 启动分页startPage(); // 2. 查询数据ListSysPost list postService.selectPostList(post);// 3. 封装分页结果return getDataTable(list);
}Service层 (SysPostServiceImpl.java)
Override
public ListSysPost selectPostList(SysPost post) {return postMapper.selectPostList(post);
}Mapper XML (SysPostMapper.xml)
select idselectPostList parameterTypeSysPost resultMapSysPostResultSELECT post_id, post_code, post_name, post_sort, status, create_timeFROM sys_postwhereif testpostCode ! null and postCode ! AND post_code LIKE CONCAT(%, #{postCode}, %)/ifif testpostName ! null and postName ! AND post_name LIKE CONCAT(%, #{postName}, %)/ifif teststatus ! null and status ! AND status #{status}/if/whereORDER BY post_sort ASC
/select3. 分页机制
分页关键点
startPage()方法从请求参数中解析pageNum和pageSizePageHelper自动改写SQL添加分页语句分页信息存储在ThreadLocal中查询结束后自动获取总记录数
三、导出查询
1. 前端实现
function handleExport() {proxy.download(system/post/export, {...queryParams.value}, post_${new Date().getTime()}.xlsx);
}2. 后端实现
Log(title 岗位管理, businessType BusinessType.EXPORT)
PreAuthorize(ss.hasPermi(system:post:export))
PostMapping(/export)
public void export(HttpServletResponse response, SysPost post) {// 1. 查询所有符合条件的数据不分页ListSysPost list postService.selectPostList(post);// 2. 使用Excel工具类导出ExcelUtilSysPost util new ExcelUtil(SysPost.class);util.exportExcel(response, list, 岗位数据);
}特点
复用相同的查询逻辑selectPostList不分页查询所有数据使用ExcelUtil工具类简化导出自动将实体字段映射到Excel列
四、详情查询单个岗位查询
1. 前端实现
// 查询岗位详细
function handleUpdate(row) {const postId row.postId;getPost(postId).then(response {form.value response.data;open.value true;});
}// API方法
export function getPost(postId) {return request({url: /system/post/ postId,method: get})
}2. 后端实现
PreAuthorize(ss.hasPermi(system:post:query))
GetMapping(value /{postId})
public AjaxResult getInfo(PathVariable Long postId) {return success(postService.selectPostById(postId));
}// Service实现
Override
public SysPost selectPostById(Long postId) {return postMapper.selectPostById(postId);
}// Mapper XML
select idselectPostById parameterTypeLong resultMapSysPostResultSELECT * FROM sys_post WHERE post_id #{postId}
/select五、查询功能设计亮点 统一查询逻辑复用 分页查询和导出查询共用同一套查询逻辑避免代码重复保证数据一致性 灵活的条件组合 SELECT * FROM sys_postWHERE 11/* 动态添加条件 */AND post_code LIKE %DEV%AND status 0ORDER BY post_sort ASC使用MyBatis动态SQL支持多条件自由组合 安全的分页机制 最大分页限制配置文件设置防止恶意请求大量数据 响应式前端设计 el-table v-loadingloading :datapostListel-table-column label状态template #defaultscopedict-tag :optionssys_normal_disable :valuescope.row.status//template/el-table-column/el-table加载状态提示字典值自动转换分页组件与表格联动
完善的权限控制 // 列表查询权限PreAuthorize(ss.hasPermi(system:post:list))// 导出权限PreAuthorize(ss.hasPermi(system:post:export))// 详情查看权限PreAuthorize(ss.hasPermi(system:post:query))六、复杂查询场景处理
统计查询
// 统计岗位使用人数
Override
public int countUserPostById(Long postId) {return userPostMapper.countUserPostById(postId);
}// Mapper
select idcountUserPostById resultTypeintSELECT COUNT(1) FROM sys_user_post WHERE post_id #{postId}
/select岗位导出功能详细解析
导出功能是岗位管理系统的重要特性允许用户将查询结果导出为Excel文件。下面从技术实现角度深入分析导出功能的完整流程
一、前端实现流程
1. 导出按钮触发
el-buttontypewarningplainiconDownloadclickhandleExportv-hasPermi[system:post:export]
导出/el-buttonv-hasPermi指令校验导出权限点击触发handleExport方法
2. 导出处理逻辑
function handleExport() {// 调用封装的下载方法proxy.download(system/post/export, {...queryParams.value // 携带当前查询条件}, post_${new Date().getTime()}.xlsx); // 生成带时间戳的文件名
}3. 下载方法封装
// /utils/request.js 在post.js内找import request from /utils/request
// 通用下载方法
export function download(url, params, filename, config) {downloadLoadingInstance ElLoading.service({ text: 正在下载数据请稍候, background: rgba(0, 0, 0, 0.7), })return service.post(url, params, {transformRequest: [(params) { return tansParams(params) }],headers: { Content-Type: application/x-www-form-urlencoded },responseType: blob,...config}).then(async (data) {const isBlob blobValidate(data)if (isBlob) {const blob new Blob([data])saveAs(blob, filename)} else {const resText await data.text()const rspObj JSON.parse(resText)const errMsg errorCode[rspObj.code] || rspObj.msg || errorCode[default]ElMessage.error(errMsg)}downloadLoadingInstance.close()}).catch((r) {console.error(r)ElMessage.error(下载文件出现错误请联系管理员)downloadLoadingInstance.close()})
}二、后端实现流程
1. 控制器入口
Log(title 岗位管理, businessType BusinessType.EXPORT)
PreAuthorize(ss.hasPermi(system:post:export))
PostMapping(/export)
public void export(HttpServletResponse response, SysPost post) {// 查询所有符合条件的岗位ListSysPost list postService.selectPostList(post);// 使用Excel工具类导出ExcelUtilSysPost util new ExcelUtil(SysPost.class);util.exportExcel(response, list, 岗位数据);
}2. 实体类Excel注解
public class SysPost extends BaseEntity {Excel(name 岗位序号, cellType ColumnType.NUMERIC)private Long postId;Excel(name 岗位编码)private String postCode;Excel(name 岗位名称)private String postName;Excel(name 岗位排序, cellType ColumnType.NUMERIC)private Integer postSort;Excel(name 状态, readConverterExp 0正常,1停用)private String status;
}导出功能通过前后端协同实现后端负责数据处理和Excel生成前端负责文件下载。合理的设计可以支持从几百条到数百万条数据的导出需求同时保证系统的稳定性和安全性。