Files
reader-star/apps/admin/src/components/common/wang-editor.vue
rjl ca42c6a876 feat(admin): 新增用户端答题流程页面与相关功能模块
- 新增用户端答题流程主页面,包含封面、介绍、答题、答题图解四个状态
- 新增用户端组件:封面、介绍页、答题页、答题图解页、题目渲染器及通用布局组件
- 新增用户端类型定义、模拟数据及业务常量
- 新增用户路由及类型声明,包含组别和队伍选择页面
- 新增管理端首页模块:数据卡片、头部横幅、折线图、饼图、创意横幅和项目新闻
- 新增富文本编辑器组件,支持图片和视频上传至OSS
- 优化题库分类树,改为扁平化列表结构
- 完善比赛创建功能,增加轮次类型、题目分数类型及关联AP字段
- 修复模板删除函数调用参数错误
- 添加 pinyin-pro 依赖以支持拼音处理功能
2026-02-05 18:00:11 +08:00

117 lines
2.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { onBeforeUnmount, shallowRef } from 'vue'
import { getAliOssTokenAxios } from '@/service/api/upload'
import { browserPathJoin } from '@/utils/date'
import { initOSSClient, uploadFileToOSS } from '@/utils/oss'
import '@wangeditor/editor/dist/css/style.css'
interface Props {
modelValue: string
placeholder?: string
mode?: 'default' | 'simple'
height?: string
path?: string
}
const props = withDefaults(defineProps<Props>(), {
modelValue: '',
placeholder: '请输入内容...',
mode: 'default',
height: '300px',
path: 'temp',
})
const emit = defineEmits(['update:modelValue'])
// Editor Logic
const editorRef = shallowRef()
const toolbarConfig = {
excludeKeys: [],
}
type InsertFnType = (url: string, alt: string, href: string) => void
async function customUpload(file: File, insertFn: InsertFnType) {
try {
const { data: tokenData, error: tokenError } = await getAliOssTokenAxios()
if (tokenError || !tokenData) {
window.$message?.error('获取上传凭证失败')
return
}
const client = initOSSClient(tokenData?.data || {})
const path = `${props.path}/${Date.now()}/${file.name}`
await uploadFileToOSS(client, file, path)
const url = browserPathJoin(import.meta.env.VITE_BASE_OSS_URL, path)
insertFn(url, file.name, url)
}
catch (error) {
console.error('上传失败', error)
window.$message?.error('上传失败')
}
}
const editorConfig = {
placeholder: props.placeholder,
MENU_CONF: {
uploadImage: {
customUpload,
},
uploadVideo: {
customUpload,
},
},
}
// 监听 placeholder 变化
// watch(() => props.placeholder, (_newVal) => {
// if (editorRef.value) {
// // 似乎 wangeditor 不支持动态修改 placeholder这里作为占位
// }
// })
function handleCreated(editor: any) {
editorRef.value = editor
}
function handleChange(editor: any) {
emit('update:modelValue', editor.getHtml())
}
onBeforeUnmount(() => {
const editor = editorRef.value
if (editor == null)
return
editor.destroy()
})
</script>
<template>
<div class="overflow-hidden border border-gray-200 rounded-lg bg-white">
<Toolbar
style="border-bottom: 1px solid #eee"
:editor="editorRef"
:default-config="toolbarConfig"
:mode="mode"
/>
<div :style="{ height: props.height }">
<Editor
:model-value="modelValue"
:style="{ height: '100%', overflowY: 'hidden' }"
:default-config="editorConfig"
:mode="mode"
@on-created="handleCreated"
@on-change="handleChange"
/>
</div>
</div>
</template>
<style scoped>
:deep(.w-e-text-container) {
background-color: transparent;
}
</style>