style: 在线管理列表问题修改

This commit is contained in:
huweihang
2025-12-22 18:15:22 +08:00
parent 6922882111
commit 79111b9e6b
3 changed files with 133 additions and 32 deletions

View File

@@ -651,7 +651,8 @@ li{
color: #000000; color: #000000;
margin-left: 4px; margin-left: 4px;
.el-input__inner { .el-input__inner {
width: 28px; width: 100%;
min-width: 28px;
height: 28px; height: 28px;
background: #F5F9FF; background: #F5F9FF;
border-radius: 4px; border-radius: 4px;

View File

@@ -1410,7 +1410,8 @@ export default {
color: #000000; color: #000000;
margin-left: 4px; margin-left: 4px;
.el-input__inner { .el-input__inner {
width: 28px; width: 100%;
min-width: 28px;
height: 28px; height: 28px;
background: #f5f9ff; background: #f5f9ff;
border-radius: 4px; border-radius: 4px;

View File

@@ -758,6 +758,7 @@ export default {
}, },
handleTeacherChange(value = []) { handleTeacherChange(value = []) {
this.params.teacherId = (value || []).join(','); this.params.teacherId = (value || []).join(',');
this.adjustTeacherWidth();
}, },
handleTeacherClear() { handleTeacherClear() {
this.teacherSelected = []; this.teacherSelected = [];
@@ -821,10 +822,12 @@ export default {
}, },
handleCreatorChange(value = []) { handleCreatorChange(value = []) {
this.params.createUserId = (value || []).slice(0, 5).join(','); this.params.createUserId = (value || []).slice(0, 5).join(',');
this.adjustCreatorWidth();
}, },
handleCreatorClear() { handleCreatorClear() {
this.creatorSelected = []; this.creatorSelected = [];
this.params.createUserId = ''; this.params.createUserId = '';
this.adjustCreatorWidth();
}, },
// 创建人下拉展开时,如果当前没有关键字,则清空上一次的查询结果 // 创建人下拉展开时,如果当前没有关键字,则清空上一次的查询结果
handleCreatorVisibleChange(visible) { handleCreatorVisibleChange(visible) {
@@ -843,6 +846,7 @@ export default {
if (this.$refs.teacherSelect) { if (this.$refs.teacherSelect) {
this.$refs.teacherSelect.query = limited; this.$refs.teacherSelect.query = limited;
} }
this.adjustTeacherWidth();
}, },
limitCreatorInput(event) { limitCreatorInput(event) {
const limited = (event && event.target && event.target.value ? event.target.value : '').slice(0, 50); const limited = (event && event.target && event.target.value ? event.target.value : '').slice(0, 50);
@@ -852,6 +856,7 @@ export default {
if (this.$refs.creatorSelect) { if (this.$refs.creatorSelect) {
this.$refs.creatorSelect.query = limited; this.$refs.creatorSelect.query = limited;
} }
this.adjustCreatorWidth();
}, },
limitResOwnerInput(event) { limitResOwnerInput(event) {
const limited = (event && event.target && event.target.value ? event.target.value : '').slice(0, 200); const limited = (event && event.target && event.target.value ? event.target.value : '').slice(0, 200);
@@ -892,6 +897,9 @@ export default {
}, },
resOwnerFilterMethod(node, keyword) { resOwnerFilterMethod(node, keyword) {
if (!keyword) return true; if (!keyword) return true;
// 只对叶子节点做匹配,避免同一个名称在父/子层级出现时,看起来像“重复数据”
const isLeaf = node.isLeaf || (node.data && node.data.leaf);
if (!isLeaf) return false;
const text = (node.label || (node.data && node.data.name) || '').toString().toLowerCase(); const text = (node.label || (node.data && node.data.name) || '').toString().toLowerCase();
const kw = keyword.toString().toLowerCase(); const kw = keyword.toString().toLowerCase();
return text.includes(kw); return text.includes(kw);
@@ -1508,6 +1516,14 @@ export default {
sessionStorage.setItem('courseDetail', JSON.stringify(row)); sessionStorage.setItem('courseDetail', JSON.stringify(row));
this.$router.push({ path: '/iframe/course/coursemanage-remote' }); this.$router.push({ path: '/iframe/course/coursemanage-remote' });
}, },
// 克隆一个用于懒加载的节点:只保留当前层必要字段,不预置 children避免 Element Cascader 出现重复节点
cloneOrgNodeForLazy(node = {}) {
return {
id: node.id,
name: node.name,
leaf: node.leaf,
};
},
// 前端“伪懒加载”:根据本地全量机构树按需返回子节点 // 前端“伪懒加载”:根据本地全量机构树按需返回子节点
// 为了让 el-cascader 的 loading 动画有可见效果,这里故意加入一个很小的延时再 resolve // 为了让 el-cascader 的 loading 动画有可见效果,这里故意加入一个很小的延时再 resolve
async loadResOwnerNodeFromCache(node, resolve) { async loadResOwnerNodeFromCache(node, resolve) {
@@ -1517,9 +1533,15 @@ export default {
setTimeout(() => resolve(nodes), 150); setTimeout(() => resolve(nodes), 150);
}; };
// 根节点level === 0返回所有一级机构 // 如果当前节点在数据上被标记为叶子节点,直接返回空数组,不再触发“懒加载”
if (node && node.data && node.data.leaf) {
return resolve([]);
}
// 根节点level === 0返回所有一级机构只返回当前层的浅拷贝不带 children避免重复
if (node.level === 0) { if (node.level === 0) {
return delayResolve(this.resOwnerTreeAll || []); const roots = (this.resOwnerTreeAll || []).map(item => this.cloneOrgNodeForLazy(item));
return delayResolve(roots);
} }
// 其他层级:根据当前节点 id 在树中查找对应节点,再返回其 children // 其他层级:根据当前节点 id 在树中查找对应节点,再返回其 children
@@ -1543,11 +1565,25 @@ export default {
}; };
const target = findNodeById(this.resOwnerTreeAll || [], currentId); const target = findNodeById(this.resOwnerTreeAll || [], currentId);
if (target && Array.isArray(target.children)) { if (!target) {
delayResolve(target.children); // 未找到对应节点,直接返回空
} else { return resolve([]);
delayResolve([]);
} }
// 如果在树里这个节点本身就是叶子节点,同样直接返回空,不展示 loading
if (target.leaf) {
return resolve([]);
}
if (Array.isArray(target.children) && target.children.length > 0) {
// 有子节点时,只返回当前层的浅拷贝,不预置更深 children避免重复
const children = target.children.map(child => this.cloneOrgNodeForLazy(child));
// 做一个轻微延迟,让 loading 有一点点反馈
return delayResolve(children);
}
// 没有子节点,直接返回空
return resolve([]);
} catch (e) { } catch (e) {
console.error('本地懒加载资源归属节点失败:', e); console.error('本地懒加载资源归属节点失败:', e);
resolve([]); resolve([]);
@@ -1557,6 +1593,10 @@ export default {
if (!value || value.length === 0) { if (!value || value.length === 0) {
this.orgId = ''; this.orgId = '';
this.orgName = ''; this.orgName = '';
// 清空选择时,直接收起下拉
if (this.$refs.resOwnerCascader) {
this.$refs.resOwnerCascader.dropDownVisible = false;
}
return; return;
} }
// value 是选中的路径数组最后一个元素是选中的节点ID // value 是选中的路径数组最后一个元素是选中的节点ID
@@ -1571,31 +1611,49 @@ export default {
const lastNode = checkedNodes[checkedNodes.length - 1]; const lastNode = checkedNodes[checkedNodes.length - 1];
this.orgName = lastNode.label || lastNode.name || ''; this.orgName = lastNode.label || lastNode.name || '';
} }
// 选中后自动收起下拉
this.$refs.resOwnerCascader.dropDownVisible = false;
} }
}); });
}, },
// 将后端机构节点转换为级联组件所需结构 // 将后端机构节点转换为级联组件所需结构
mapOrgToCascaderNode(node = {}) { mapOrgToCascaderNode(node = {}) {
const children = Array.isArray(node.childList) const hasChildren = Array.isArray(node.childList) && node.childList.length > 0;
const children = hasChildren
? node.childList.map(child => this.mapOrgToCascaderNode(child)) ? node.childList.map(child => this.mapOrgToCascaderNode(child))
: []; : [];
return { return {
id: node.organizationId, id: node.organizationId,
name: node.orgName, name: node.orgName,
children, children,
// childList 为空就标记为叶子节点,去掉右侧箭头,且不再触发懒加载
leaf: !hasChildren,
}; };
}, },
// 加载资源归属全量机构树 // 加载资源归属全量机构树
async loadAllResOwnerTree() { async loadAllResOwnerTree() {
try { try {
const res = await apiUserbasic.getAllOrgTree(); const res = await apiUserbasic.getAllOrgTree();
// 调试日志:打印原始机构树与映射后的树结构,用于排查“重复节点”问题
try {
const raw = res && res.result && res.result.orgTreeList
? JSON.parse(JSON.stringify(res.result.orgTreeList))
: [];
// 注意:这里日志仅用于前端调试,确认后可删除
console.log('[资源归属] getAllOrgTree 原始 orgTreeList =>', raw);
} catch (e) {
console.warn('[资源归属] 打印 orgTreeList 日志失败:', e);
}
if (res && res.status === 200 && res.result && Array.isArray(res.result.orgTreeList)) { if (res && res.status === 200 && res.result && Array.isArray(res.result.orgTreeList)) {
this.resOwnerTreeAll = res.result.orgTreeList.map(item => this.mapOrgToCascaderNode(item)); this.resOwnerTreeAll = res.result.orgTreeList.map(item => this.mapOrgToCascaderNode(item));
console.log('[资源归属] 映射后的 resOwnerTreeAll =>', this.resOwnerTreeAll);
// 默认进入非搜索模式,由懒加载从本地树按需返回节点 // 默认进入非搜索模式,由懒加载从本地树按需返回节点
this.resOwnerOptions = []; this.resOwnerOptions = [];
} else if (res && res.result && Array.isArray(res.result.orgTreeList)) { } else if (res && res.result && Array.isArray(res.result.orgTreeList)) {
// 兼容没有 status 字段但有 result 的情况 // 兼容没有 status 字段但有 result 的情况
this.resOwnerTreeAll = res.result.orgTreeList.map(item => this.mapOrgToCascaderNode(item)); this.resOwnerTreeAll = res.result.orgTreeList.map(item => this.mapOrgToCascaderNode(item));
console.log('[资源归属] 映射后的 resOwnerTreeAll(无status) =>', this.resOwnerTreeAll);
this.resOwnerOptions = []; this.resOwnerOptions = [];
} else { } else {
this.resOwnerTreeAll = []; this.resOwnerTreeAll = [];
@@ -1718,6 +1776,9 @@ export default {
buildActions(row) { buildActions(row) {
const actions = []; const actions = [];
// 优先级按原有展示顺序 // 优先级按原有展示顺序
if (row.isPermission && !this.forChoose && row.status == 2) {
actions.push({ key: 'withdraw', label: '撤回', className: 'action-link--primary' });
}
if (row.isPermission && row.status != 2) { if (row.isPermission && row.status != 2) {
actions.push({ key: 'edit', label: '编辑', className: 'action-link--primary' }); actions.push({ key: 'edit', label: '编辑', className: 'action-link--primary' });
} }
@@ -1727,9 +1788,6 @@ export default {
if (row.isPermission && !this.forChoose && row.published) { if (row.isPermission && !this.forChoose && row.published) {
actions.push({ key: 'manage', label: '管理', className: 'action-link--primary' }); actions.push({ key: 'manage', label: '管理', className: 'action-link--primary' });
} }
if (row.isPermission && !this.forChoose && row.status == 2) {
actions.push({ key: 'withdraw', label: '撤回', className: 'action-link--primary' });
}
if ((row.isPermission && row.status != 2 && !row.published) || (row.isPermission && !row.enabled)) { if ((row.isPermission && row.status != 2 && !row.published) || (row.isPermission && !row.enabled)) {
actions.push({ key: 'delete', label: '删除', className: 'action-link--danger' }); actions.push({ key: 'delete', label: '删除', className: 'action-link--danger' });
} }
@@ -1751,6 +1809,35 @@ export default {
const actions = this.buildActions(row); const actions = this.buildActions(row);
return actions.length > 4 ? actions.slice(4) : []; return actions.length > 4 ? actions.slice(4) : [];
} }
,
// 按已选标签宽度动态调整“授课教师”选择框宽度
adjustTeacherWidth() {
this.$nextTick(() => {
const select = this.$refs.teacherSelect;
this.adjustSelectWidth(select, 200, 800, 60);
});
},
// 按已选标签宽度动态调整“创建人”选择框宽度
adjustCreatorWidth() {
this.$nextTick(() => {
const select = this.$refs.creatorSelect;
this.adjustSelectWidth(select, 200, 800, 60);
});
},
// 通用:累加 el-select__tags 内所有 tag 的宽度,设置选择框宽度
adjustSelectWidth(selectRef, min = 200, max = 800, extra = 0) {
if (!selectRef || !selectRef.$el) return;
const el = selectRef.$el;
const tags = Array.from(el.querySelectorAll('.el-select__tags .el-tag'));
const inputInner = el.querySelector('.el-input__inner');
const padding = 24; // 预留箭头/输入余量
const tagsWidth = tags.reduce((sum, tag) => sum + (tag.getBoundingClientRect().width || 0), 0);
const target = Math.max(min, Math.min(tagsWidth + padding + extra, max));
el.style.width = `${target}px`;
if (inputInner) {
inputInner.style.width = `${target}px`;
}
}
} }
}; };
</script> </script>
@@ -2065,7 +2152,7 @@ export default {
color: #000000; color: #000000;
margin-left: 4px; margin-left: 4px;
.el-input__inner { .el-input__inner {
width: 28px; min-width: 28px;
height: 28px; height: 28px;
background: #F5F9FF; background: #F5F9FF;
border-radius: 4px; border-radius: 4px;
@@ -2149,7 +2236,12 @@ export default {
background-color: #4284F7 background-color: #4284F7
} }
::v-deep .el-table__empty-block {
width: 100% !important;
display: flex;
justify-content: center;
align-items: center;
}
::v-deep.el-table { ::v-deep.el-table {
border-radius: 6px 6px 0 0; border-radius: 6px 6px 0 0;
@@ -2292,7 +2384,7 @@ export default {
border-radius: 6px; border-radius: 6px;
border: 1px solid rgba(0, 0, 0, .2); border: 1px solid rgba(0, 0, 0, .2);
line-height: 32px; line-height: 32px;
padding: 0 10px; padding: 0 15px 0 10px;
&:focus { &:focus {
border-color: #4284F7; border-color: #4284F7;
} }
@@ -2309,7 +2401,7 @@ export default {
border-radius: 6px; border-radius: 6px;
border: 1px solid rgba(0, 0, 0, .2); border: 1px solid rgba(0, 0, 0, .2);
line-height: 32px; line-height: 32px;
padding: 0 10px; padding: 0 15px 0 10px;
color: #000000; color: #000000;
&:focus { &:focus {
border: 1px solid #4284F7; border: 1px solid #4284F7;
@@ -2341,13 +2433,14 @@ export default {
margin-left: 10px; margin-left: 10px;
} }
.el-input__inner { .el-input__inner {
width: 180px; min-width: 180px;
width: auto;
height: 32px; height: 32px;
background: #FFFFFF; background: #FFFFFF;
border-radius: 6px; border-radius: 6px;
border: 1px solid rgba(0, 0, 0, .2); border: 1px solid rgba(0, 0, 0, .2);
line-height: 32px; line-height: 32px;
padding: 0 10px; padding: 0 15px 0 10px;
} }
.el-input { .el-input {
&.is-focus .el-input__inner{ &.is-focus .el-input__inner{
@@ -2370,7 +2463,7 @@ export default {
border-radius: 6px; border-radius: 6px;
border: 1px solid rgba(0, 0, 0, .2); border: 1px solid rgba(0, 0, 0, .2);
line-height: 32px; line-height: 32px;
padding: 0 10px; padding: 0 15px 0 10px;
&.is-focus .el-input__inner{ &.is-focus .el-input__inner{
border-color: #4284F7; border-color: #4284F7;
} }
@@ -2395,7 +2488,7 @@ export default {
border-radius: 6px; border-radius: 6px;
border: 1px solid rgba(0, 0, 0, .2); border: 1px solid rgba(0, 0, 0, .2);
line-height: 32px; line-height: 32px;
padding: 0 10px; padding: 0 15px 0 10px;
&.is-focus .el-input__inner{ &.is-focus .el-input__inner{
border-color: #4284F7; border-color: #4284F7;
} }
@@ -2420,7 +2513,7 @@ export default {
border-radius: 6px; border-radius: 6px;
border: 1px solid rgba(0, 0, 0, .2); border: 1px solid rgba(0, 0, 0, .2);
line-height: 32px; line-height: 32px;
padding: 0 10px; padding: 0 15px 0 10px;
&.is-focus .el-input__inner{ &.is-focus .el-input__inner{
border-color: #4284F7; border-color: #4284F7;
} }
@@ -2446,7 +2539,7 @@ export default {
border-radius: 6px; border-radius: 6px;
border: 1px solid rgba(0, 0, 0, .2); border: 1px solid rgba(0, 0, 0, .2);
line-height: 32px; line-height: 32px;
padding: 0 10px; padding: 0 15px 0 10px;
&.is-focus .el-input__inner{ &.is-focus .el-input__inner{
border-color: #4284F7; border-color: #4284F7;
} }
@@ -2460,16 +2553,18 @@ export default {
.filter-field--resowner { .filter-field--resowner {
.el-cascader { .el-cascader {
width: 180px; min-width: 200px;
width: auto;
line-height: 32px; line-height: 32px;
.el-input__inner { .el-input__inner {
width: 180px; min-width: 200px;
width: auto;
height: 32px; height: 32px;
background: #FFFFFF; background: #FFFFFF;
border-radius: 6px; border-radius: 6px;
border: 1px solid rgba(0, 0, 0, .2); border: 1px solid rgba(0, 0, 0, .2);
line-height: 32px; line-height: 32px;
padding: 0 10px; padding: 0 15px 0 10px;
&:focus { &:focus {
border-color: #4284F7; border-color: #4284F7;
} }
@@ -2480,31 +2575,35 @@ export default {
} }
.el-input { .el-input {
.el-input__inner { .el-input__inner {
width: 180px; min-width: 200px;
width: auto;
height: 32px; height: 32px;
background: #FFFFFF; background: #FFFFFF;
border-radius: 6px; border-radius: 6px;
border: 1px solid rgba(0, 0, 0, .2); border: 1px solid rgba(0, 0, 0, .2);
line-height: 32px; line-height: 32px;
padding: 0 10px; padding: 0 15px 0 10px;
} }
} }
} }
.filter-field--creator { .filter-field--creator {
.el-select { .el-select {
min-width: 180px;
width: auto;
.el-select__input { .el-select__input {
margin-left: 10px; margin-left: 10px;
} }
.el-input__inner { .el-input__inner {
width: 136px; min-width: 180px;
width: auto;
height: 32px; height: 32px;
background: #FFFFFF; background: #FFFFFF;
border-radius: 6px; border-radius: 6px;
border: 1px solid rgba(0, 0, 0, .2); border: 1px solid rgba(0, 0, 0, .2);
line-height: 32px; line-height: 32px;
padding: 0 10px; padding: 0 15px 0 10px;
&.is-focus .el-input__inner{ &.is-focus .el-input__inner{
border-color: #4284F7; border-color: #4284F7;
} }
@@ -2520,13 +2619,13 @@ export default {
} }
.el-input__inner { .el-input__inner {
width: 180px; width: 136px;
height: 32px; height: 32px;
background: #FFFFFF; background: #FFFFFF;
border-radius: 6px; border-radius: 6px;
border: 1px solid rgba(0, 0, 0, .2); border: 1px solid rgba(0, 0, 0, .2);
line-height: 32px; line-height: 32px;
padding: 0 10px; padding: 0 15px 0 10px;
&.is-focus .el-input__inner{ &.is-focus .el-input__inner{
border-color: #4284F7; border-color: #4284F7;
} }
@@ -2547,7 +2646,7 @@ export default {
border-radius: 6px; border-radius: 6px;
border: 1px solid rgba(0, 0, 0, .2); border: 1px solid rgba(0, 0, 0, .2);
line-height: 32px; line-height: 32px;
padding: 0 10px; padding: 0 15px 0 10px;
.el-input__icon { .el-input__icon {
line-height: 32px; line-height: 32px;