diff --git a/src/api/modules/courseStudy.js b/src/api/modules/courseStudy.js index af906be0..f16a36b3 100644 --- a/src/api/modules/courseStudy.js +++ b/src/api/modules/courseStudy.js @@ -17,7 +17,7 @@ const hasSignup = function(courseId) { * 课程报名,微课,录播课 * @param {Object} data * { - courseId: + courseId: courseName: courseType: 课程类型,对应微课,录播课 signType:1,后名方式,默认是1自主报名,可以不传 @@ -367,6 +367,15 @@ const deleteSignUp=function(id,courseId){ return ajax.post(`/xboe/school/study/course/delete-signup?id=${id}&couserId=${courseId}`); } +/* +删除课程学习记录 +@param id 学习id +@param courseId 课程id 用于删除课程报名信息和修改课程学习人数 + */ +const deleteNewSignUp=function(data){ + return ajax.post(`/xboe/school/study/course/delete-signup`, data); +} + /** * 二次查询 用于个人主页/他人主页 * { @@ -432,6 +441,7 @@ export default { signup, findSignup, deleteSignup, + deleteNewSignUp, importSignup, countSignup, studyIndex, diff --git a/src/components/signup/AudienceModal.vue b/src/components/signup/AudienceModal.vue index abec78ce..f58aebda 100644 --- a/src/components/signup/AudienceModal.vue +++ b/src/components/signup/AudienceModal.vue @@ -5,16 +5,37 @@ import { fetchAudienceList, saveStu } from "@/api/signup/commonStudent"; +import apiUserbasic from "@/api/boe/userbasic.js"; export default { name: "AudienceModal", @@ -74,6 +96,10 @@ export default { total: 0, pageNo: 1, selectedRows: [], + // 成员远程搜索多选 + memberSelected: [], + memberOptions: [], + memberLoading: false, }; }, watch: { @@ -89,15 +115,18 @@ export default { }, methods: { resetAndFetch() { - this.keyword = ""; this.pageNo = 1; this.selectedRows = []; + this.keyword = ""; + this.memberSelected = []; + this.memberOptions = []; this.fetchList(); }, fetchList() { this.loading = true; fetchAudienceList({ - keyword: this.keyword, + // memberList 为多选成员 ID 列表 + memberList: this.memberSelected || [], pageNo: this.pageNo, pageSize: this.pageSize, audienceIdList: this.audienceIds || [], @@ -117,6 +146,8 @@ export default { }, onReset() { this.keyword = ""; + this.memberSelected = []; + this.memberOptions = []; this.onSearch(); }, onPageChange(page) { @@ -126,6 +157,79 @@ export default { onSelectionChange(list) { this.selectedRows = list; }, + // ===== 成员远程搜索,多选逻辑(参考 ManageListRemote.vue 的创建人筛选) ===== + async remoteSearchMember(keyword) { + const limited = (keyword || "").slice(0, 50); + if (this.$refs.memberSelect && this.$refs.memberSelect.query !== limited) { + this.$refs.memberSelect.query = limited; + this.$nextTick(() => { + if ( + this.$refs.memberSelect && + this.$refs.memberSelect.$refs && + this.$refs.memberSelect.$refs.input + ) { + this.$refs.memberSelect.$refs.input.value = limited; + } + }); + } + const query = limited.trim(); + if (!query || query.length <= 1) { + this.memberOptions = []; + return; + } + this.memberLoading = true; + try { + const res = await apiUserbasic.selectUser(query); + if (res && res.status === 200) { + const resultList = res.result || []; + this.memberOptions = resultList + .map((item) => this.formatMemberItem(item)) + .filter((item) => item.userId); + } else { + this.memberOptions = []; + } + } catch (error) { + this.memberOptions = []; + } finally { + this.memberLoading = false; + } + }, + formatMemberItem(item = {}) { + return { + userId: item.id, + name: item.realName, + code: item.userNo, + }; + }, + handleMemberChange(value = []) { + // 限制最多 5 个,保持与 ManageListRemote 中创建人筛选一致 + this.memberSelected = (value || []).slice(0, 5); + }, + handleMemberClear() { + this.memberSelected = []; + this.memberOptions = []; + }, + handleMemberVisibleChange(visible) { + if (!visible) return; + const select = this.$refs.memberSelect; + const query = (select && select.query) || ""; + if (!query) { + this.memberOptions = []; + } + }, + limitMemberInput(event) { + const limited = + (event && event.target && event.target.value + ? event.target.value + : "" + ).slice(0, 50); + if (event && event.target && event.target.value !== limited) { + event.target.value = limited; + } + if (this.$refs.memberSelect) { + this.$refs.memberSelect.query = limited; + } + }, handleClose() { this.visibleSync = false; }, diff --git a/src/components/signup/SignupModal.vue b/src/components/signup/SignupModal.vue index 51b12065..1295a05d 100644 --- a/src/components/signup/SignupModal.vue +++ b/src/components/signup/SignupModal.vue @@ -35,7 +35,7 @@ 搜索 - 重置 + 重置
@@ -43,8 +43,15 @@ @node-click="onOrgSelect" />
- + @@ -83,8 +90,15 @@ 重置
- + @@ -309,6 +323,8 @@ export default { visible(val) { if (val) { this.initData(); + } else { + this.resetState(); } }, }, @@ -318,6 +334,30 @@ export default { } }, methods: { + // 参考 CommonStudent.vue,在关闭弹窗时清空各种选中与搜索条件 + resetState() { + this.projectParams.studentName = ""; + this.nameSearch = { keyword: "", departId: "" }; + this.audienceName = { keyword: "" }; + this.searchOrgName = { keyword: "", pageNo: 1, pageSize: 200 }; + this.projectSelectRows = []; + this.stuSelectRows = []; + this.auditSelectRows = []; + this.deptList = []; + this.selectedOrgKeys = []; + this.member = false; + this.dept = false; + this.person = false; + this.group = false; + + // 清空表格勾选 + if (this.$refs.stuTable && this.$refs.stuTable.clearSelection) { + this.$refs.stuTable.clearSelection(); + } + if (this.$refs.audienceTable && this.$refs.audienceTable.clearSelection) { + this.$refs.audienceTable.clearSelection(); + } + }, initData() { this.courseDetail = JSON.parse(sessionStorage.getItem("courseDetail") || "{}"); this.projectParams = { @@ -374,6 +414,10 @@ export default { console.log("res", res); this.stuTable.list = res.data?.list || []; this.stuTable.total = res.data?.total || 0; + // 根据右侧已选,恢复当前页的勾选状态 + this.$nextTick(() => { + this.syncStuTableSelection(); + }); }); }, onStuPageChange(page) { @@ -381,7 +425,22 @@ export default { this.onSearchStu(); }, onStuSelectionChange(list) { - this.stuSelectRows = list; + // Element 表格在翻页时会把当前页的 selection 通过 list 传进来 + // 为了保留其他页已选,这里做合并而不是直接覆盖 + const currentPageIds = this.stuTable.list.map((r) => r.id || r.userId); + // 先保留非当前页的已选 + const otherPageSelected = this.stuSelectRows.filter( + (r) => !currentPageIds.includes(r.id || r.userId) + ); + const merged = [...otherPageSelected, ...list]; + // 根据 id/userId 去重 + const seen = new Set(); + this.stuSelectRows = merged.filter((r) => { + const key = r.id || r.userId; + if (!key || seen.has(key)) return false; + seen.add(key); + return true; + }); }, resetStu() { this.nameSearch = { keyword: "", departId: "" }; @@ -444,6 +503,10 @@ export default { console.log('searchAudience', res); this.audienceTable.list = res.data?.list || []; this.audienceTable.total = res.data?.total || 0; + // 根据右侧已选,恢复当前页的受众勾选状态 + this.$nextTick(() => { + this.syncAudienceTableSelection(); + }); }); }, onAudiencePageChange(page) { @@ -451,7 +514,50 @@ export default { this.searchAudience(); }, onAudienceSelectionChange(list) { - this.auditSelectRows = list; + const currentPageIds = this.audienceTable.list.map((r) => r.id); + const otherPageSelected = this.auditSelectRows.filter( + (r) => !currentPageIds.includes(r.id) + ); + const merged = [...otherPageSelected, ...list]; + const seen = new Set(); + this.auditSelectRows = merged.filter((r) => { + const key = r.id; + if (!key || seen.has(key)) return false; + seen.add(key); + return true; + }); + }, + // 根据 stuSelectRows 恢复当前页表格里的勾选 + syncStuTableSelection() { + if (!this.$refs.stuTable) return; + const table = this.$refs.stuTable; + if (!table.clearSelection || !table.toggleRowSelection) return; + const selectedMap = new Set( + (this.stuSelectRows || []).map((r) => r.id || r.userId) + ); + table.clearSelection(); + this.stuTable.list.forEach((row) => { + const key = row.id || row.userId; + if (key && selectedMap.has(key)) { + table.toggleRowSelection(row, true); + } + }); + }, + // 根据 auditSelectRows 恢复当前页受众表格里的勾选 + syncAudienceTableSelection() { + if (!this.$refs.audienceTable) return; + const table = this.$refs.audienceTable; + if (!table.clearSelection || !table.toggleRowSelection) return; + const selectedMap = new Set( + (this.auditSelectRows || []).map((r) => r.id) + ); + table.clearSelection(); + this.audienceTable.list.forEach((row) => { + const key = row.id; + if (key && selectedMap.has(key)) { + table.toggleRowSelection(row, true); + } + }); }, resetAudienceInfo() { this.audienceName.keyword = "";