mirror of
https://codeup.aliyun.com/67762337eccfc218f6110e0e/vue/fe-manage.git
synced 2025-12-16 14:26:45 +08:00
- 新增 Cropper 组件,支持图片裁剪、缩放、旋转功能 - 集成 cropperjs 库及其相关元素组件 - 在专业模式页面中引入并使用裁剪组件 - 更新 package.json 和 lock 文件以包含新依赖 - 优化登录过期弹窗按钮文本显示
405 lines
11 KiB
Vue
405 lines
11 KiB
Vue
<script setup>
|
||
import { ref, defineOptions, onMounted } from "vue";
|
||
import { Plus, Loading } from "@element-plus/icons-vue";
|
||
import courseTag from "./courseTag.vue";
|
||
import { $message } from "@/utils/useMessage";
|
||
import {
|
||
ElForm,
|
||
ElFormItem,
|
||
ElRadio,
|
||
ElRadioGroup,
|
||
ElUpload,
|
||
ElButton,
|
||
ElInput,
|
||
ElCascader,
|
||
ElSelect,
|
||
ElSelectV2,
|
||
ElTreeSelect,
|
||
ElOption,
|
||
ElDialog,
|
||
} from "element-plus";
|
||
import FieldCloud from "@/components/FileCloud/index.vue";
|
||
import Cropper from "@/components/Cropper/Cropper.vue";
|
||
import { useUpload } from "@/hooks/useUpload";
|
||
import { useCourseForm } from "@/hooks/useCourseForm";
|
||
import { useRouter } from "vue-router";
|
||
const router = useRouter();
|
||
defineOptions({
|
||
name: "ProfessionalMode",
|
||
});
|
||
// 使用上传hook
|
||
const { fileList, loading, handleChange, beforeUpload } = useUpload();
|
||
// 使用表单hook
|
||
const { formRef, formState, visibilityOptions, resetForm } = useCourseForm();
|
||
import { useFetchCourseList } from "@/hooks/useFetchCourseList";
|
||
const {
|
||
fetchClassTree,
|
||
getUserGroupList,
|
||
teachersList,
|
||
sysTypeListMap,
|
||
courseTags,
|
||
loadOrgNode,
|
||
curCourseId,
|
||
userGroupList,
|
||
sysTypeList,
|
||
} = useFetchCourseList();
|
||
|
||
import { useMediaComponent } from "@/hooks/useMediaComponent";
|
||
const { fileBaseUrl } = useMediaComponent({});
|
||
const handleTagsChange = (tags) => {
|
||
console.log("父组件:", tags);
|
||
// 限制最多5个标签
|
||
if (tags.length > 5) {
|
||
this.$message.warning("最多只能选择5个标签");
|
||
// 强制限制为5个
|
||
tags = tags.slice(0, 5);
|
||
return;
|
||
}
|
||
let ids = "";
|
||
tags.forEach((tag) => {
|
||
console.log("父组件name : ", tag.tagName);
|
||
ids += tag.id + ",";
|
||
});
|
||
};
|
||
const onTagFocus = () => {};
|
||
// 文件选择对话框
|
||
const dlgFileShow = ref(false);
|
||
// 方法定义
|
||
const chooseFile = () => {
|
||
dlgFileShow.value = true;
|
||
};
|
||
const dlgCutShow = ref(false);
|
||
|
||
const changeCourseImage = (img) => {
|
||
if (!img.path) {
|
||
return;
|
||
}
|
||
dlgFileShow.value = false;
|
||
formState.coverImg = fileBaseUrl + img.path;
|
||
dlgCutShow.value = true;
|
||
};
|
||
|
||
const choseChoose = () => {
|
||
dlgFileShow.value = false;
|
||
};
|
||
|
||
const success = (e) => {
|
||
console.log(e);
|
||
formState.coverImg = e;
|
||
};
|
||
// 表单提交
|
||
const handleSubmit = () => {
|
||
// formRef.value
|
||
// .validate()
|
||
// .then(() => {
|
||
// console.log("Received values of form:", formState);
|
||
// ElMessage.success("表单提交成功");
|
||
// })
|
||
// .catch((error) => {
|
||
// console.log("Validate Failed:", error);
|
||
// ElMessage.error("请检查表单填写内容");
|
||
// });
|
||
console.log("Received values of form:", formState);
|
||
$message.success("表单提交成功");
|
||
};
|
||
|
||
// 表单重置
|
||
const handleReset = () => {
|
||
resetForm(fileList);
|
||
};
|
||
const next = () => {
|
||
// 注意:这里的路由跳转需要正确引入和使用vue-router
|
||
router.push({
|
||
path: "/createcourse",
|
||
query: {
|
||
orgId: "1693922746301661185",
|
||
orgName: "'N'业务",
|
||
duration: "1",
|
||
},
|
||
});
|
||
};
|
||
// 调用接口
|
||
onMounted(() => {
|
||
fetchClassTree(1);
|
||
getUserGroupList({ keyword: "", page: 1, pageSize: 500 });
|
||
});
|
||
</script>
|
||
|
||
<template>
|
||
<div class="professional-mode">
|
||
<el-form
|
||
ref="formRef"
|
||
:model="formState"
|
||
:label-position="'right'"
|
||
label-width="80px"
|
||
class="default-form"
|
||
@submit.prevent="handleSubmit"
|
||
>
|
||
<div class="professional-mode-title">
|
||
<div class="professional-mode-title-text" style="padding-bottom: 20px">
|
||
基本信息
|
||
</div>
|
||
<div class="professional-mode-form">
|
||
<el-form-item
|
||
label="课程名称"
|
||
prop="name"
|
||
:rules="[{ required: true, message: '请输入课程名称' }]"
|
||
>
|
||
<el-input
|
||
size="large"
|
||
v-model="formState.name"
|
||
placeholder="请输入课程名称"
|
||
/>
|
||
</el-form-item>
|
||
|
||
<el-form-item
|
||
label="课程分类"
|
||
prop="courseCategory"
|
||
:rules="[{ required: true, message: '请选择课程分类' }]"
|
||
>
|
||
<el-cascader
|
||
size="large"
|
||
v-model="formState.courseCategory"
|
||
placeholder="请选择课程分类"
|
||
:options="sysTypeListMap"
|
||
:props="{
|
||
label: 'name',
|
||
value: 'id',
|
||
}"
|
||
/>
|
||
</el-form-item>
|
||
|
||
<el-form-item
|
||
label="资源归属"
|
||
prop="orgName"
|
||
:rules="[{ required: true, message: '请选择资源归属' }]"
|
||
>
|
||
<el-tree-select
|
||
size="large"
|
||
check-strictly
|
||
lazy
|
||
:load="loadOrgNode"
|
||
:render-after-expand="false"
|
||
v-model="formState.orgName"
|
||
:props="{ value: 'id', label: 'name', children: 'children' }"
|
||
placeholder="请选择资源归属"
|
||
/>
|
||
</el-form-item>
|
||
|
||
<el-form-item
|
||
label="授课教师"
|
||
prop="lecturer"
|
||
:rules="[{ required: true, message: '请选择授课教师' }]"
|
||
>
|
||
<el-select-v2
|
||
size="large"
|
||
filterable
|
||
multiple
|
||
v-model="formState.lecturer"
|
||
:options="teachersList"
|
||
placeholder="请选择授课教师"
|
||
>
|
||
</el-select-v2>
|
||
</el-form-item>
|
||
|
||
<el-form-item
|
||
label="目标人群"
|
||
prop="forUsers"
|
||
:rules="[{ required: true, message: '请输入目标人群' }]"
|
||
>
|
||
<el-input
|
||
size="large"
|
||
v-model="formState.forUsers"
|
||
placeholder="请输入目标人群"
|
||
/>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="课程标签" prop="courseTags">
|
||
<courseTag
|
||
:courseId="curCourseId"
|
||
:sysTypeList="sysTypeList"
|
||
:initialTags="courseTags"
|
||
@change="handleTagsChange"
|
||
@focus="onTagFocus"
|
||
style="width: 100%"
|
||
></courseTag>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="受众" prop="crowds">
|
||
<el-select
|
||
size="large"
|
||
v-model="formState.crowds"
|
||
placeholder="请选择受众"
|
||
multiple
|
||
value-key="id"
|
||
>
|
||
<el-option
|
||
v-for="item in userGroupList"
|
||
:key="item.id"
|
||
:label="item.name"
|
||
:value="item"
|
||
></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="观看设置" prop="device">
|
||
<el-radio-group v-model="formState.device">
|
||
<el-radio
|
||
v-for="item in visibilityOptions"
|
||
:key="item.value"
|
||
:label="item.value"
|
||
>
|
||
{{ item.label }}
|
||
</el-radio>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
</div>
|
||
|
||
<div class="professional-mode-title-text" style="padding-top: 0">
|
||
课程介绍
|
||
</div>
|
||
|
||
<div class="professional-mode-form">
|
||
<el-form-item label="封面介绍" prop="coverIntro">
|
||
<div style="display: flex; align-items: flex-end">
|
||
<el-upload
|
||
v-model:file-list="fileList"
|
||
name="avatar"
|
||
list-type="picture-card"
|
||
class="avatar-uploader"
|
||
:show-file-list="false"
|
||
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
|
||
:before-upload="beforeUpload"
|
||
:on-change="handleChange"
|
||
>
|
||
<img
|
||
v-if="formState.coverImg"
|
||
:src="formState.coverImg"
|
||
alt="avatar"
|
||
style="width: 100%"
|
||
/>
|
||
<div v-else class="text-center">
|
||
<Loading v-if="loading" class="w30" />
|
||
<Plus v-else class="w30" />
|
||
<div class="el-upload-text">上传图片</div>
|
||
</div>
|
||
</el-upload>
|
||
<el-button type="primary" link @click="chooseFile" class="ml10"
|
||
>选择封面</el-button
|
||
>
|
||
</div>
|
||
|
||
<div class="upload-hint">
|
||
建议上传800px*450px(16:9)的图片,格式为.png或.jpg,大小不超过2M
|
||
</div>
|
||
</el-form-item>
|
||
|
||
<el-form-item
|
||
label="课程价值"
|
||
prop="courseValue"
|
||
:rules="[{ required: true, message: '请输入课程价值' }]"
|
||
>
|
||
<el-input
|
||
type="textarea"
|
||
size="large"
|
||
v-model="formState.courseValue"
|
||
:rows="3"
|
||
placeholder="请输入课程价值"
|
||
/>
|
||
</el-form-item>
|
||
|
||
<el-form-item
|
||
label="课程简介"
|
||
prop="summary"
|
||
:rules="[{ required: true, message: '请输入课程简介' }]"
|
||
>
|
||
<el-input
|
||
type="textarea"
|
||
size="large"
|
||
v-model="formState.summary"
|
||
:rows="4"
|
||
placeholder="请输入课程简介"
|
||
/>
|
||
</el-form-item>
|
||
</div>
|
||
|
||
<div class="form-actions">
|
||
<el-button
|
||
style="margin-left: 80px; margin-right: 12px"
|
||
size="large"
|
||
@click="handleReset"
|
||
>存草稿</el-button
|
||
>
|
||
<el-button type="primary" @click="next">创建下一步</el-button>
|
||
</div>
|
||
</div>
|
||
</el-form>
|
||
<field-cloud
|
||
:show="dlgFileShow"
|
||
@choose="changeCourseImage"
|
||
@close="choseChoose"
|
||
></field-cloud>
|
||
|
||
<!-- 裁切-->
|
||
<Cropper
|
||
:img="formState.coverImg"
|
||
v-model:show="dlgCutShow"
|
||
@crop-success="success"
|
||
></Cropper>
|
||
</div>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.professional-mode {
|
||
width: 70%;
|
||
|
||
.default-form {
|
||
width: 100%;
|
||
margin-bottom: 30px;
|
||
padding: 10px 15px;
|
||
}
|
||
|
||
.professional-mode-title {
|
||
width: 100%;
|
||
|
||
.professional-mode-title-text {
|
||
font-size: 15px;
|
||
padding: 10px 0;
|
||
font-weight: 600;
|
||
}
|
||
}
|
||
|
||
.professional-mode-form {
|
||
width: 100%;
|
||
|
||
.upload-hint {
|
||
margin-top: 8px;
|
||
font-size: 12px;
|
||
color: #999;
|
||
}
|
||
|
||
:deep(.el-form-item) {
|
||
margin-bottom: 22px;
|
||
}
|
||
}
|
||
|
||
.form-actions {
|
||
padding: 20px 0;
|
||
}
|
||
|
||
:deep(.el-upload--picture-card) {
|
||
width: 200px;
|
||
height: 112px;
|
||
}
|
||
|
||
:deep(.el-upload-list--picture-card) {
|
||
width: 200px;
|
||
}
|
||
|
||
:deep(.el-upload-list--picture-card .el-upload-list__item) {
|
||
width: 200px;
|
||
height: 112px;
|
||
}
|
||
}
|
||
</style>
|