mirror of
https://codeup.aliyun.com/67762337eccfc218f6110e0e/vue/fe-manage.git
synced 2025-12-20 00:06:47 +08:00
feat(courselibrary): 增强课程章节编辑功能
- 添加章节标题编辑功能,支持输入框修改 - 实现章节删除确认弹窗及成功提示 - 更新拖拽组件属性配置,移除旧插槽用法 - 替换 SVG 图标为 iconfont 字体图标 - 引入新的图标样式和 hover 效果 - 优化 collapse 组件交互逻辑与样式表现 - 升级 iconfont 字体文件,新增多个图标定义
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 5086622 */
|
||||
src: url("iconfont.woff2?t=1765446803106") format("woff2"),
|
||||
url("iconfont.woff?t=1765446803106") format("woff"),
|
||||
url("iconfont.ttf?t=1765446803106") format("truetype");
|
||||
src: url("iconfont.woff2?t=1765507086795") format("woff2"),
|
||||
url("iconfont.woff?t=1765507086795") format("woff"),
|
||||
url("iconfont.ttf?t=1765507086795") format("truetype");
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
@@ -11,11 +11,30 @@
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
color: #b5b5b5;
|
||||
display: inline-table;
|
||||
}
|
||||
|
||||
.icon-danseshixintubiao- {
|
||||
color: #b5b5b5;
|
||||
.icon-delete:before {
|
||||
content: "\e6a6";
|
||||
}
|
||||
|
||||
.icon-view:before {
|
||||
content: "\e68d";
|
||||
}
|
||||
|
||||
.icon-up:before {
|
||||
content: "\e616";
|
||||
}
|
||||
|
||||
.icon-setting:before {
|
||||
content: "\e623";
|
||||
}
|
||||
|
||||
.icon-edit:before {
|
||||
content: "\e659";
|
||||
}
|
||||
|
||||
.icon-danseshixintubiao-:before {
|
||||
content: "\e632";
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -194,6 +194,7 @@ const deleteRow = (data) => {
|
||||
type: "error",
|
||||
})
|
||||
.then(() => {
|
||||
$message.success("删除成功");
|
||||
if (
|
||||
courseList.value[courseMetadata.chooseIndex] &&
|
||||
courseList.value[courseMetadata.chooseIndex].data
|
||||
@@ -254,8 +255,12 @@ const handleNext = () => {
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<dragCollapse v-model:courseList="courseList">
|
||||
<template #title="{ course }">{{ course.title }}</template>
|
||||
<dragCollapse
|
||||
v-model:courseList="courseList"
|
||||
titleKey="title"
|
||||
:isEdit="true"
|
||||
>
|
||||
<!-- <template #title="{ course }">{{ course.title }}</template>-->
|
||||
<template #desc="{ course }">
|
||||
若课程只有一个章节,将不在学员端显示该章节名称
|
||||
</template>
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import draggable from "vuedraggable";
|
||||
import { ElIcon } from "element-plus";
|
||||
import { Delete, ArrowUp, ArrowDown, Operation } from "@element-plus/icons-vue";
|
||||
import svgIcon from "@/components/SvgIcon.vue";
|
||||
import { ElInput, ElMessageBox } from "element-plus";
|
||||
import { $message } from "@/utils/useMessage";
|
||||
|
||||
const props = defineProps({
|
||||
courseList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
titleKey: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
isEdit: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
// 定义 emits 用于更新父组件数据
|
||||
@@ -48,6 +56,34 @@ const moveStart = (e) => {
|
||||
item.isCollapsed = true;
|
||||
});
|
||||
};
|
||||
const showInput = ref(false);
|
||||
const editTitle = (element) => {
|
||||
console.log("编辑");
|
||||
element.showInput = true;
|
||||
element.copyTitle = element[props.titleKey];
|
||||
};
|
||||
|
||||
const saveTitle = (element) => {
|
||||
element.showInput = false;
|
||||
element[props.titleKey] = element.copyTitle;
|
||||
delete element.copyTitle;
|
||||
delete element.showInput;
|
||||
delete element.isCollapsed;
|
||||
emit("update:courseList", dragList.value);
|
||||
};
|
||||
|
||||
const deleteCourse = (index) => {
|
||||
ElMessageBox.confirm("确定删除所选章节吗", "删除确认", {
|
||||
title: "删除确认",
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "error",
|
||||
}).then(() => {
|
||||
$message.success("删除成功");
|
||||
dragList.value.splice(index, 1);
|
||||
emit("update:courseList", dragList.value);
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -62,9 +98,28 @@ const moveStart = (e) => {
|
||||
<template #item="{ element, index }">
|
||||
<div class="drag-collapse">
|
||||
<div class="drag-collapse-header">
|
||||
<div>
|
||||
<span class="drag-collapse-header-title">
|
||||
<slot name="title" :course="element">视频可见名称</slot>
|
||||
<div class="flex align-center">
|
||||
<span
|
||||
class="drag-collapse-header-title flex align-item-c"
|
||||
style="align-items: center"
|
||||
>
|
||||
<span v-if="element.showInput">
|
||||
<el-input v-model="element.copyTitle" clearable></el-input>
|
||||
</span>
|
||||
<span v-else>{{ element[titleKey] }}</span>
|
||||
<i
|
||||
class="iconfont icon-edit fs14 ml20"
|
||||
v-if="isEdit && !element.showInput"
|
||||
@click="editTitle(element)"
|
||||
></i>
|
||||
|
||||
<i
|
||||
class="fs16 ml20"
|
||||
v-if="isEdit && element.showInput"
|
||||
style="cursor: pointer; color: #4284f7"
|
||||
@click="saveTitle(element)"
|
||||
>✓</i
|
||||
>
|
||||
</span>
|
||||
<span class="drag-collapse-header-desc">
|
||||
<slot name="desc" :course="element">
|
||||
@@ -74,25 +129,27 @@ const moveStart = (e) => {
|
||||
</div>
|
||||
|
||||
<div style="display: flex; align-items: center">
|
||||
<i class="iconfont icon-danseshixintubiao- move-icon"></i>
|
||||
<svg-icon
|
||||
icon-class="del"
|
||||
class="ml10"
|
||||
style="width: 0.9em; cursor: pointer"
|
||||
></svg-icon>
|
||||
<span>
|
||||
<i class="iconfont icon-danseshixintubiao- move-icon fs16"></i>
|
||||
</span>
|
||||
<span>
|
||||
<i
|
||||
class="ml10 iconfont icon-delete fs14"
|
||||
style="cursor: pointer"
|
||||
@click="deleteCourse(index)"
|
||||
></i>
|
||||
</span>
|
||||
<span @click="toggleCollapse(element)">
|
||||
<svg-icon
|
||||
<i
|
||||
v-if="!element.isCollapsed"
|
||||
icon-class="up"
|
||||
class="ml10"
|
||||
style="width: 0.9em; cursor: pointer"
|
||||
></svg-icon>
|
||||
<svg-icon
|
||||
class="ml10 iconfont icon-up fs10"
|
||||
style="cursor: pointer; display: inline-table"
|
||||
></i>
|
||||
<i
|
||||
v-else
|
||||
icon-class="up"
|
||||
class="ml10"
|
||||
style="width: 0.9em; cursor: pointer; transform: rotate(180deg)"
|
||||
></svg-icon>
|
||||
class="ml10 iconfont icon-up fs10"
|
||||
style="cursor: pointer; transform: rotate(180deg)"
|
||||
></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -106,9 +163,17 @@ const moveStart = (e) => {
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.icon-danseshixintubiao- {
|
||||
.icon-danseshixintubiao-,
|
||||
.icon-up,
|
||||
.icon-edit {
|
||||
&:hover {
|
||||
color: #4284f7;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.icon-delete {
|
||||
&:hover {
|
||||
color: #ff2626;
|
||||
}
|
||||
}
|
||||
.drag-collapse {
|
||||
|
||||
@@ -197,14 +197,20 @@ const renderNameColumn = () => {
|
||||
startEdit(record);
|
||||
},
|
||||
},
|
||||
createVNode(svgIcon, {
|
||||
iconClass: "tableEdit",
|
||||
h("i", {
|
||||
class: "iconfont icon-edit",
|
||||
style: {
|
||||
fontSize: "12px",
|
||||
width: "1em",
|
||||
height: "1em",
|
||||
},
|
||||
})
|
||||
// createVNode(svgIcon, {
|
||||
// iconClass: "tableEdit",
|
||||
// style: {
|
||||
// fontSize: "12px",
|
||||
// width: "1em",
|
||||
// height: "1em",
|
||||
// },
|
||||
// })
|
||||
),
|
||||
]
|
||||
);
|
||||
@@ -435,6 +441,11 @@ const components = {
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
:deep(.icon-edit) {
|
||||
&:hover {
|
||||
color: #4284f7;
|
||||
}
|
||||
}
|
||||
.drag-table-container {
|
||||
padding: 20px;
|
||||
margin: 0 auto;
|
||||
|
||||
Reference in New Issue
Block a user