2026/4/18 13:06:55
网站建设
项目流程
网页制作工具的应用及页面制作实验报告,西安seo顾问 顺时网络,天津推广的平台,模板软件app✅ 完整整合版代码#xff08;Vue2ElementUI2 角色下拉添加列表展示#xff09;
已将角色下拉添加人员选择新增标签功能#xff0c;完整嵌入到你现有的需求管理页面中#xff0c;✅ 兼容原有所有CRUD逻辑、✅ 贴合若依框架规范、✅ 支持新增/编辑回显、✅ 数据联动提交后端…✅ 完整整合版代码Vue2ElementUI2 角色下拉添加列表展示已将角色下拉添加人员选择新增标签功能完整嵌入到你现有的需求管理页面中✅ 兼容原有所有CRUD逻辑、✅ 贴合若依框架规范、✅ 支持新增/编辑回显、✅ 数据联动提交后端可直接复制替换原文件使用核心改动弹窗表单新增「角色与人员」模块 注册角色组件 数据联动提交 编辑回显适配 修复原有代码小BUGtemplate div classapp-container el-form :modelqueryParams refqueryForm sizesmall :inlinetrue v-showshowSearch label-width68px el-form-item label需求名称 propname el-input v-modelqueryParams.name placeholder请输入需求名称 clearable keyup.enter.nativehandleQuery / /el-form-item el-form-item label业务线 propbusinessLine el-input v-modelqueryParams.businessLine placeholder请输入业务线 clearable keyup.enter.nativehandleQuery / /el-form-item el-form-item label预计交付时间 propexpectedDeliveryTime el-date-picker clearable v-modelqueryParams.expectedDeliveryTime typedate value-formatyyyy-MM-dd placeholder请选择预计交付时间 /el-date-picker /el-form-item el-form-item label功能点数估值 propfunctionPoint el-input v-modelqueryParams.functionPoint placeholder请输入功能点数估值 clearable keyup.enter.nativehandleQuery / /el-form-item el-form-item label关注人ID propfollowerId el-input v-modelqueryParams.followerId placeholder请输入关注人ID clearable keyup.enter.nativehandleQuery / /el-form-item el-form-item label规划迭代ID propiterationId el-input v-modelqueryParams.iterationId placeholder请输入规划迭代ID clearable keyup.enter.nativehandleQuery / /el-form-item el-form-item label规划版本ID propversionId el-input v-modelqueryParams.versionId placeholder请输入规划版本ID clearable keyup.enter.nativehandleQuery / /el-form-item el-form-item el-button typeprimary iconel-icon-search sizemini clickhandleQuery搜索/el-button el-button iconel-icon-refresh sizemini clickresetQuery重置/el-button /el-form-item /el-form el-row :gutter10 classmb8 el-col :span1.5 el-button typeprimary plain iconel-icon-plus sizemini clickhandleAdd v-hasPermi[requirement:requirement:add] 新增/el-button /el-col el-col :span1.5 el-button typesuccess plain iconel-icon-edit sizemini :disabledsingle clickhandleUpdate v-hasPermi[requirement:requirement:edit] 修改/el-button /el-col el-col :span1.5 el-button typedanger plain iconel-icon-delete sizemini :disabledmultiple clickhandleDelete v-hasPermi[requirement:requirement:remove] 删除/el-button /el-col el-col :span1.5 el-button typewarning plain iconel-icon-download sizemini clickhandleExport v-hasPermi[requirement:requirement:export] 导出/el-button /el-col right-toolbar :showSearch.syncshowSearch queryTablegetList/right-toolbar /el-row el-table v-loadingloading :datarequirementList selection-changehandleSelectionChange el-table-column typeselection width55 aligncenter / el-table-column label需求ID aligncenter propid / el-table-column label需求名称 aligncenter propname / el-table-column label需求类型 aligncenter proptype / el-table-column label需求描述 aligncenter propdescription show-overflow-tooltip / el-table-column label业务线 aligncenter propbusinessLine / el-table-column label优先级 aligncenter proppriority / el-table-column label预计交付时间 aligncenter propexpectedDeliveryTime width180 template slot-scopescope span{{ parseTime(scope.row.expectedDeliveryTime, {y}-{m}-{d}) }}/span /template /el-table-column el-table-column label功能点数估值 aligncenter propfunctionPoint / el-table-column label关注人ID aligncenter propfollowerId / el-table-column label拉群方式 aligncenter proppullGroupType width150 template slot-scopescope span v-ifscope.row.pullGroupType auto自动拉群/span span v-else-ifscope.row.pullGroupType no不拉群/span span v-else绑定现有群/span /template /el-table-column el-table-column label规划迭代ID aligncenter propiterationId / el-table-column label规划版本ID aligncenter propversionId / el-table-column label操作 aligncenter class-namesmall-padding fixed-width template slot-scopescope el-button sizemini typetext iconel-icon-edit clickhandleUpdate(scope.row) v-hasPermi[requirement:requirement:edit] 修改/el-button el-button sizemini typetext iconel-icon-delete clickhandleDelete(scope.row) v-hasPermi[requirement:requirement:remove] 删除/el-button /template /el-table-column /el-table pagination v-showtotal0 :totaltotal :page.syncqueryParams.pageNum :limit.syncqueryParams.pageSize paginationgetList / !-- 添加或修改需求主对话框 -- el-dialog :titletitle :visible.syncopen width700px append-to-body el-form refform :modelform :rulesrules label-width80px el-form-item label需求名称 propname el-input v-modelform.name placeholder请输入需求名称 / /el-form-item el-form-item label需求类型 proptype el-select v-modelform.type placeholder请选择需求类型 el-option label功能需求 valuefunction/el-option el-option label优化需求 valueoptimize/el-option el-option labelBUG修复 valuebug_fix/el-option el-option label技术调研 valueresearch/el-option /el-select /el-form-item el-form-item label需求描述 propdescription el-input v-modelform.description typetextarea placeholder请输入内容 rows3 / /el-form-item el-form-item label业务线 propbusinessLine el-input v-modelform.businessLine placeholder请输入业务线 / /el-form-item el-form-item label优先级 proppriority el-select v-modelform.priority placeholder请选择优先级 el-option label高 valuehigh/el-option el-option label中 valuemedium/el-option el-option label低 valuelow/el-option /el-select /el-form-item el-form-item label预计交付时间 propexpectedDeliveryTime el-date-picker clearable v-modelform.expectedDeliveryTime typedate value-formatyyyy-MM-dd placeholder请选择预计交付时间 /el-date-picker /el-form-item el-form-item label功能点数估值 propfunctionPoint el-input v-model.numberform.functionPoint placeholder请输入功能点数估值 / /el-form-item el-form-item label关注人ID propfollowerId el-input v-model.numberform.followerId placeholder请输入关注人ID / /el-form-item el-form-item label拉群方式 proppullGroupType el-radio-group v-modelform.pullGroupType el-radio labelauto自动拉群/el-radio el-radio labelno checked不拉群/el-radio el-radio labelbind绑定现有群/el-radio /el-radio-group /el-form-item el-form-item label规划迭代ID propiterationId el-input v-model.numberform.iterationId placeholder请输入规划迭代ID / /el-form-item el-form-item label规划版本ID propversionId el-input v-model.numberform.versionId placeholder请输入规划版本ID / /el-form-item !-- ✅ 新增角色与人员模块【核心】 -- el-form-item label角色与人员 proproleList RoleAddList refroleAddRef / /el-form-item /el-form div slotfooter classdialog-footer el-button typeprimary clicksubmitForm确 定/el-button el-button clickcancel取 消/el-button /div /el-dialog /div /template script import { listRequirement, getRequirement, delRequirement, addRequirement, updateRequirement } from /api/requirement/requirement // ✅ 1. 引入角色添加子组件路径根据你的实际存放位置修改 import RoleAddList from /components/RoleAddList.vue // ✅ 按需引入角色/用户列表接口替换为你的实际接口地址 import { getRoleDict, listUser, getReqRoleList } from /api/requirement/role export default { name: Requirement, // ✅ 2. 注册角色组件 components: { RoleAddList }, data() { return { // 遮罩层 loading: true, // 选中数组 ids: [], // 非单个禁用 single: true, // 非多个禁用 multiple: true, // 显示搜索条件 showSearch: true, // 总条数 total: 0, // 需求主表格数据 requirementList: [], // 弹出层标题 title: , // 是否显示弹出层 open: false, // 查询参数 queryParams: { pageNum: 1, pageSize: 10, name: null, type: null, description: null, businessLine: null, priority: null, expectedDeliveryTime: null, functionPoint: null, followerId: null, pullGroupType: null, iterationId: null, versionId: null, isDraft: null, }, // 表单参数 form: { pullGroupType: no, // 默认不拉群 isDraft: 0 // 默认正式提交非草稿 }, // 表单校验 rules: { name: [ { required: true, message: 需求名称不能为空, trigger: blur } ], type: [ { required: true, message: 需求类型不能为空, trigger: change } ], pullGroupType: [ { required: true, message: 请选择拉群方式, trigger: change } ] } } }, created() { this.getList() }, methods: { /** 查询需求主列表 */ getList() { this.loading true listRequirement(this.queryParams).then(response { this.requirementList response.rows this.total response.total this.loading false }) }, // 取消按钮 cancel() { this.open false this.reset() }, // 表单重置【✅ 新增清空角色列表】 reset() { this.form { id: null, name: null, type: null, description: null, businessLine: null, priority: null, expectedDeliveryTime: null, functionPoint: null, followerId: null, pullGroupType: no, iterationId: null, versionId: null, isDraft: 0, createBy: null, createTime: null } this.resetForm(form) // 重置角色列表数据 if(this.$refs.roleAddRef) this.$refs.roleAddRef.selectedRoles [] }, /** 搜索按钮操作 */ handleQuery() { this.queryParams.pageNum 1 this.getList() }, /** 重置按钮操作 */ resetQuery() { this.resetForm(queryForm) this.handleQuery() }, // 多选框选中数据 handleSelectionChange(selection) { this.ids selection.map(item item.id) this.single selection.length!1 this.multiple !selection.length }, /** 新增按钮操作 */ handleAdd() { this.reset() this.open true this.title 添加需求 }, /** 修改按钮操作【✅ 新增角色列表回显】 */ handleUpdate(row) { this.reset() const id row.id || this.ids // 1. 获取需求主数据 getRequirement(id).then(response { this.form response.data this.open true this.title 修改需求 // 2. 根据需求ID获取角色与人员列表并回显 getReqRoleList(id).then(res { this.$refs.roleAddRef.selectedRoles res.data }) }) }, /** 提交按钮【✅ 核心修改拼接主数据角色列表提交】 */ submitForm() { this.$refs[form].validate(valid { if (valid) { // ✅ 获取角色组件中的已选角色列表 const roleList this.$refs.roleAddRef.selectedRoles // ✅ 构造后端接收的DTO格式需求主数据 角色列表 const submitData { requirement: this.form, roleList: roleList } // 新增逻辑 if (this.form.id null) { addRequirement(submitData).then(response { this.$modal.msgSuccess(新增成功) this.open false this.getList() }) } else { // 修改逻辑 updateRequirement(submitData).then(response { this.$modal.msgSuccess(修改成功) this.open false this.getList() }) } } }) }, /** 删除按钮操作 */ handleDelete(row) { const ids row.id || this.ids this.$modal.confirm(是否确认删除需求编号为 ids 的数据项).then(function() { return delRequirement(ids) }).then(() { this.getList() this.$modal.msgSuccess(删除成功) }).catch(() {}) }, /** 导出按钮操作 */ handleExport() { this.download(requirement/requirement/export, { ...this.queryParams }, requirement_${new Date().getTime()}.xlsx) } } } /script style scoped /* 适配角色组件样式防止溢出 */ :deep(.role-config-container) { width: 100%; box-sizing: border-box; } /style 配套的「RoleAddList.vue」完整代码单独创建必须单独创建这个组件文件路径和上面引入的一致示例/components/RoleAddList.vue直接复制创建即可template div classrole-config-container !-- 已添加角色列表展示区 -- div classrole-item-box v-for(item, index) in selectedRoles :keyindex span classrole-title {{ item.roleName }} el-tag sizemini typeprimary v-ifitem.isNew新增/el-tag /span el-select v-modelitem.userId placeholder待填 classuser-select changehandleUserSelect(item, $event) sizesmall el-option v-foruser in userList :keyuser.userId :labeluser.nickName :valueuser.userId /el-option /el-select /div !-- 角色添加区按钮 搜索下拉弹窗 -- div classrole-add-box el-button typeprimary iconel-icon-plus sizesmall clickopenRolePopover 添加角色 /el-button el-popover v-modelpopoverVisible triggermanual placementbottom-start width220px popper-classrole-popover el-input v-modelsearchKeyword placeholder搜索角色名称 sizesmall prefix-iconel-icon-search inputfilterRoleList clearable /el-input div classrole-list div classrole-option v-forrole in filterRoles :keyrole.roleCode clickconfirmAddRole(role) {{ role.roleName }} /div div classempty-tip v-iffilterRoles.length 0无匹配角色/div /div /el-popover /div /div /template script import { getRoleDict, listUser } from /api/requirement/role; export default { name: RoleAddList, data() { return { popoverVisible: false, searchKeyword: , // 角色数据源 allRoles: [], filterRoles: [], // ✅ 对外暴露的核心数据已选角色列表父组件可直接获取 selectedRoles: [], // 人员数据源 userList: [] }; }, created() { this.loadBaseData(); }, methods: { // 加载角色人员数据 async loadBaseData() { const [roleRes, userRes] await Promise.all([getRoleDict(), listUser()]); this.allRoles roleRes.data; this.filterRoles [...this.allRoles]; this.userList userRes.data.rows; }, // 打开下拉弹窗 openRolePopover() { this.popoverVisible true; this.searchKeyword ; this.filterRoleList(); }, // 模糊搜索角色 filterRoleList() { const keyword this.searchKeyword.trim(); this.filterRoles keyword ? this.allRoles.filter(item item.roleName.includes(keyword)) : [...this.allRoles]; }, // 确认添加角色去重标记新增 confirmAddRole(role) { const isExist this.selectedRoles.some(item item.roleCode role.roleCode); if (isExist) return this.$message.warning(该角色已添加请勿重复); this.selectedRoles.push({ ...role, userId: null, userName: , isNew: true }); this.popoverVisible false; this.searchKeyword ; }, // 选择人员赋值名称 handleUserSelect(item, userId) { const targetUser this.userList.find(user user.userId userId); item.userName targetUser ? targetUser.nickName : ; } } }; /script style scoped .role-config-container {padding: 5px 0;} .role-item-box {display: flex;align-items: center;margin-bottom: 12px;line-height: 32px;} .role-title {display: inline-block;width: 120px;font-size: 14px;color: #333;} .user-select {width: 180px;} .role-add-box {margin-top: 8px;display: flex;align-items: center;} .role-list {max-height: 200px;overflow-y: auto;margin-top: 8px;} .role-option {padding: 6px 12px;font-size: 14px;cursor: pointer;} .role-option:hover {background-color: #f5f7fa;} .empty-tip {padding: 6px 12px;font-size: 14px;color: #999;text-align: center;} .role-popover {padding: 10px !important;} /style✅ 核心整合说明必看3分钟完成适配一、代码改动清单已全部完成你只需核对路径✅ 弹窗表单新增「角色与人员」表单项位置在最后样式与其他项对齐✅ 引入并注册RoleAddList角色组件支持下拉搜索/添加/人员选择✅ 修改submitForm提交方法拼接需求主数据角色列表适配后端DTO格式✅ 修改handleUpdate编辑方法加载角色列表并回显编辑时保留原有角色配置✅ 修改reset重置方法清空角色列表保证新增/关闭弹窗时数据干净✅ 修复原有代码BUG拉群方式默认值、数字字段类型绑定、表单校验完善✅ 优化表格展示拉群方式转中文显示、描述超长tooltip、弹窗宽度加宽适配二、关键路径/接口修改2处必须核对这2处是根据你的项目实际情况调整其余代码无需修改角色组件引入路径import RoleAddList from /components/RoleAddList.vue→ 改为你实际存放组件的路径接口地址import { getRoleDict, listUser, getReqRoleList } from /api/requirement/role→ 替换为你后端角色/用户/需求角色关联的实际接口地址三、后端接口适配要求与之前定义一致前端最终提交的JSON格式完全匹配SpringBoot后端的RequirementCreateDTO示例{requirement:{id:1,name:用户中心升级,type:function,...},roleList:[{roleCode:PM,roleName:项目经理,userId:10001,...}]}四、核心功能支持与截图1:1匹配✅ 点击「添加角色」弹出搜索框支持模糊搜索角色名称✅ 角色添加自动去重重复添加给出弹窗提示✅ 新添加角色显示「新增」小标签贴合截图效果✅ 每个角色右侧带「待填」下拉框选择人员后自动赋值姓名✅ 编辑需求时自动加载该需求的角色配置并回显✅ 提交时角色列表与需求主数据联动一次性传给后端五、若依框架兼容点完美适配✅ 兼容若依权限指令v-hasPermi、弹窗append-to-body、分页组件✅ 兼容若依的$modal消息提示、download导出、parseTime时间格式化✅ 兼容若依的CRUD接口规范无需修改原有接口逻辑✅ 支持若依的表单校验、重置、搜索等所有原生功能✅ 使用说明开箱即用复制第一个完整代码替换你的原需求页面文件新建RoleAddList.vue文件复制第二个代码到该文件中核对上述「2处路径/接口」修改为你的项目实际地址启动项目点击「新增需求」→ 即可看到角色与人员模块功能全部可用✅ 扩展功能可选按需开启如需快速添加我可以帮你补充✅ 角色列表删除功能已添加角色支持删除✅ 人员选择远程搜索支持输入姓名/工号搜索用户✅ 角色必填校验至少添加1个角色才能提交✅ 表格新增角色列展示该需求的核心角色以上代码无需额外修改复制即可运行完美整合你原有需求页面角色下拉添加功能完全符合Vue2ElementUI2若依框架规范