<!-- 新增通知公告弹窗 --> <script lang="ts" setup name="addNotice"> import type { FormInstance, FormRules } from 'element-plus' import { ElMessage } from 'element-plus' import dayjs from 'dayjs' import { Editor, Toolbar } from '@wangeditor/editor-for-vue' import { addNoticeApi, uploadApi } from '@/api/system/notice' import { getPhotoUrl } from '@/api/system/tool' import useUserStore from '@/store/modules/user' import '@wangeditor/editor/dist/css/style.css' // 引入 css const emits = defineEmits(['resetData']) const userInfo = useUserStore() const ruleFormRef = ref<FormInstance>() // from组件 const ruleForm = reactive({ noticeNo: '', // 通知公告编号 noticePublisher: '', // 发布人 noticeCompany: '', // 发布单位 noticeTime: '', // 发布时间 noticeSketch: '', // 内容简述 noticeContent: '', // 发布内容 minioFileName: '', // 上传文件名 noticeTitle: '', // 标题 }) // 表单 const rules = ref<FormRules>({ noticeTitle: [{ required: true, message: '标题不能为空', trigger: 'blur' }], noticeSketch: [{ required: true, message: '内容简述不能为空', trigger: 'blur' }], noticeContent: [{ required: true, message: '发布内容不能为空', trigger: 'blur' }], }) // 表单验证规则 const dialogVisible = ref<boolean>(false) // 弹窗显示 // 弹窗初始化 const initDialog = () => { dialogVisible.value = true ruleForm.noticePublisher = userInfo.$state.name ruleForm.noticeCompany = userInfo.$state.deptName ruleForm.noticeTime = dayjs().format('YYYY-MM-DD') } defineExpose({ initDialog }) // 关闭弹窗 const close = () => { dialogVisible.value = false emits('resetData') } // 提交 const submitForm = async (formEl: FormInstance | undefined) => { console.log(ruleForm.noticeContent) if (!formEl) { return } await formEl.validate((valid, fields) => { if (valid) { ruleForm.noticeTime = dayjs().format('YYYY-MM-DD HH:mm:ss') addNoticeApi(ruleForm).then((res) => { if (res.code === 200) { close() ElMessage.success('发布成功') } else { ElMessage.error(res.message) } }) } }) } // 取消 const resetForm = (formEl: FormInstance | undefined) => { // if (!formEl) { return } formEl?.resetFields() dialogVisible.value = false emits('resetData') } const fileRef = ref() // 文件上传input const onFileChange = (event: any) => { // 原生上传图片 // console.log(event.target.files) // if (event.target.files[0].type === 'application/pdf') { if (event.target.files?.length !== 0) { // 创建formdata对象 const fd = new FormData() fd.append('multipartFile', event.target.files[0]) uploadApi(fd).then((res) => { if (res.code === 200) { ruleForm.minioFileName = res.data[0] ElMessage.success('上传成功') } else { ElMessage.error(res.message) } }) } // } // else { // ElMessage.error('请上传pdf格式') // } } const upload = () => { fileRef.value.click() } // 富文本实例对象 const editorRef = shallowRef() // 菜单配置 const toolbarConfig = ref({}) // 编辑器配置 const editorConfig = ref({ placeholder: '请输入内容...', MENU_CONF: { // 配置上传图片 uploadImage: { server: 'http://111.198.10.15:21409/minio/file/upload', // 配置图片上传地址 maxFileSize: 2 * 1024 * 1024, // 10M 图片大小限制 fieldName: 'img', // 上传类型 allowedFileTypes: [], // 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 [] // 自定义上传参数,传递图片时需要带一些参数过去写在这。参数会被添加到 formData 中,一起上传到服务端。 // meta: { // image_class_id: "2", // file_type: "1", // }, // 自定义设置请求头,比如添加token之类的 // headers: { // Accept: 'text/x-json', // otherKey: 'xxx' // }, // 上传进度的回调函数,可以用来显示进度条 onProgress(progress: any) { // progress 是 0-100 的数字 console.log('progress', progress) }, // // 单个文件上传成功之后 // onSuccess(file, res) { // console.log(`${file.name} 上传成功`, res) // }, // 单个文件上传失败 onFailed(file: any, res: any) { console.log(`${file.name} 上传失败`, res) }, // 上传错误,或者触发 timeout 超时 onError(file: any, err: any, res: any) { console.log(`${file.name} 上传出错`, err, res) }, // 插入图片到富文本编辑器回显 customInsert(res: any, insertFn: any) { console.log() // res 即服务端的返回结果 getPhotoUrl(res.data[0]).then((res) => { const url = res.data const alt = '' const href = res.data // 从 res 中找到 url alt href ,然后插入图片 insertFn(url, alt, href) }) }, }, // 配置上传视频 uploadVideo: { server: 'http://111.198.10.15:21409/minio/file/upload', // 配置视频上传地址 maxFileSize: 5 * 1024 * 1024, // 5M 视频大小限制 fieldName: 'your-custom-name', // 上传类型 // 最多可上传几个文件,默认为 5 maxNumberOfFiles: 3, allowedFileTypes: [], // 选择文件时的类型限制,默认为 ['video/*'] 。如不想限制,则设置为 [] // 自定义上传参数,传递图片时需要带一些参数过去写在这。参数会被添加到 formData 中,一起上传到服务端。 // meta: { // type: 1, // }, // 自定义设置请求头,比如添加token之类的 // headers: { // Accept: 'text/x-json', // otherKey: 'xxx' // }, metaWithUrl: false, // 将 meta 拼接到 url 参数中,默认 false withCredentials: true, // 跨域是否传递 cookie ,默认为 false // 上传之前触发 onBeforeUpload(file: any) { // file 选中的文件,格式如 { key: file } return file // 可以 return // 1. return file 或者 new 一个 file ,接下来将上传 // 2. return false ,不上传这个 file }, // 上传进度的回调函数,可以用来显示进度条 onProgress(progress: any) { // progress 是 0-100 的数字 console.log('progress', progress) }, // // 单个文件上传成功之后 onSuccess(file: any, res: any) { console.log(`${file.name} 上传成功`, res) }, // 单个文件上传失败 onFailed(file: any, res: any) { console.log(`${file.name} 上传失败`, res) }, // 上传错误,或者触发 timeout 超时 onError(file: any, err: any, res: any) { console.log(`${file.name} 上传出错`, err, res) }, // 插入图片到富文本编辑器回显 customInsert(res: any, insertFn: any) { console.log(res, '视频插入') // res 即服务端的返回结果 // let url = res.data.url; // let poster = res.data.poster; // 从 res 中找到 url poster ,然后插入 // 参数url是视频地址,poster是视频封面图片,后端如果不返回,可以考虑写死一个固定的封面图 getPhotoUrl(res.data[0]).then((res) => { const url = res.data // 从 res 中找到 url alt href ,然后插入图片 insertFn(url, '') }) }, }, }, }) const onCreated = (editor: any) => { editorRef.value = editor nextTick(() => { editorRef.value = editor // 一定要用 Object.seal() ,否则会报错 }) } const look = () => { console.log(ruleForm.noticeContent) } const minioFileUrl = ref('') watch(() => ruleForm.minioFileName, (newVal) => { if (newVal) { getPhotoUrl(newVal).then((res) => { minioFileUrl.value = res.data }) } }) </script> <template> <el-dialog v-if="dialogVisible" v-model="dialogVisible" title="添加公告" width="50%" append-to-body class="container"> <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-position="right" label-width="110px"> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="通知公告编号" prop="noticeNo"> <el-input v-model.trim="ruleForm.noticeNo" placeholder="系统自动生成" disabled /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="发布人" prop="noticePublisher"> <el-input v-model.trim="ruleForm.noticePublisher" disabled /> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="发布单位" prop="noticeCompany"> <el-input v-model.trim="ruleForm.noticeCompany" disabled /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="发布时间" prop="noticeTime"> <el-input v-model.trim="ruleForm.noticeTime" disabled /> </el-form-item> </el-col> </el-row> <el-form-item label="标题" prop="noticeTitle"> <el-input v-model.trim="ruleForm.noticeTitle" /> </el-form-item> <el-form-item label="内容简述" prop="noticeSketch"> <el-input v-model.trim="ruleForm.noticeSketch" /> </el-form-item> <el-form-item label="发布内容" prop="noticeContent"> <div style="border: 1px solid #dcdfe6;width: 100%;border-radius: 4px;"> <toolbar style="border-bottom: 1px solid #dcdfe6;width: 100%;border-radius: 4px;" :editor="editorRef" :default-config="toolbarConfig" mode="default" /> <editor v-model="ruleForm.noticeContent" style="height: 150px; overflow-y: hidden;" :default-config="editorConfig" mode="default" @onCreated="onCreated" /> </div> <!-- <el-input v-model.trim="ruleForm.noticeContent" :rows="4" type="textarea" /> --> </el-form-item> <el-form-item label="附件" prop="minioFileName"> <el-link v-if="ruleForm.minioFileName" :href="minioFileUrl" type="primary" target="_blank"> {{ ruleForm.minioFileName }} </el-link> <el-button type="primary" :style="{ 'margin-left': ruleForm.minioFileName === '' ? '0px' : '20px' }" @click="upload"> {{ ruleForm.minioFileName === '' ? '上传' : '更换附件' }} </el-button> <input v-show="false" ref="fileRef" type="file" accept="pdf/*" @change="onFileChange"> </el-form-item> </el-form> <template #footer> <div class="dialog-footer footer"> <el-button type="primary" @click="submitForm(ruleFormRef)"> 发布 </el-button> <el-button @click="resetForm(ruleFormRef)"> 关闭 </el-button> </div> </template> </el-dialog> </template> <style lang="scss" scoped> .container { ::v-deep { .w-e-bar { padding: 0; .w-e-bar-item { padding: 0; height: 30px; } .w-e-bar-divider { margin: 0; display: none; width: 0; height: 0; } } } } </style>