diff --git a/src/api/modules/notice/index.ts b/src/api/modules/notice/index.ts
index 4eb4565..2e4c040 100644
--- a/src/api/modules/notice/index.ts
+++ b/src/api/modules/notice/index.ts
@@ -6,5 +6,13 @@ export const getNoticeListApi = (params: any) => {
}
//创建公告
export const createNoticeApi = (params: any) => {
- return request.get('/notice/createNotice', {...params})
-}
\ No newline at end of file
+ return request.post('/notice/createNotice', {...params})
+}
+//编辑草稿
+export const editNoticeApi = (params: any) => {
+ return request.post('/notice/editNotice', {...params})
+}
+//删除草稿
+export const deleteNoticeApi = (params: any) => {
+ return request.post('/notice/delNotice', {...params})
+}
diff --git a/src/api/modules/upload.ts b/src/api/modules/upload.ts
new file mode 100644
index 0000000..f7342ce
--- /dev/null
+++ b/src/api/modules/upload.ts
@@ -0,0 +1,27 @@
+import { request } from '@/api'; // 引入你已封装的request
+
+/**
+ * 图片上传接口(适配富文本编辑器)
+ * @param file 要上传的文件对象
+ * @returns Promise<{ url: string }> 图片上传后的URL
+ */
+export const uploadImageApi = (file: File): Promise<{ url: string }> => {
+ // 构建FormData(图片上传必须用FormData格式)
+ const formData = new FormData();
+ formData.append('image', file); // 对应后端接收字段名image
+
+ // 使用你已封装的post请求,禁用loading(富文本自身有状态提示)
+ return request.post<{ url: string }>(
+ '/upload/image',
+ formData,
+ {
+ // 覆盖默认配置:图片上传需要特殊的请求头
+ headers: {
+ 'Content-Type': 'multipart/form-data', // 表单上传必须的头
+ showLoading: false // 禁用全局loading,避免和编辑器loading冲突
+ },
+ timeout: 30 * 1000, // 图片上传超时时间30秒
+ noRetry: false // 允许重试(网络波动时自动重试)
+ }
+ );
+};
\ No newline at end of file
diff --git a/src/views/notice/index.vue b/src/views/notice/index.vue
index 057ebee..2225408 100644
--- a/src/views/notice/index.vue
+++ b/src/views/notice/index.vue
@@ -7,24 +7,34 @@
新建
+
+ 已发布
+ 草稿
+
- {{ row.status === 1 ? '已发布' : '未发布' }}
+
+ {{ row.status === 1 ? '草稿' : '已发布' }}
- 查看
+ 查看
+
+
+ 编辑
+ 删除
+
-
-
+
@@ -33,7 +43,10 @@
-
+
+
公告名称:{{ noticeForm.noticeName }}
+
+
@@ -51,45 +64,55 @@ import { search, tableColumns, formItem } from './options'
import { rules } from './rules'
// 接口
-import { getNoticeListApi, createNoticeApi } from '@/api/modules/notice'
+import { getNoticeListApi, createNoticeApi, editNoticeApi, deleteNoticeApi } from '@/api/modules/notice'
+import { uploadImageApi } from '@/api/modules/upload'
+
+
import { DomEditor } from '@wangeditor/editor'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import '@wangeditor/editor/dist/css/style.css'
-// 编辑器实例
+// 富文本编辑器实例
const editorRef = shallowRef()
// 工具栏实例(通过 DomEditor 获取)
const toolbarRef = shallowRef()
-// 内容 HTML
+// 富文本编辑器内容 HTML
const valueHtml = ref('')
-
+// 工具栏配置
const toolbarConfig = {
- excludeKeys: ["group-video"]
+ excludeKeys: ["group-video", "fullScreen"]
}
-const editorConfig = { placeholder: '请输入内容...' }
-
-// 组件销毁时销毁编辑器
-onBeforeUnmount(() => {
- const editor = editorRef.value
- if (editor == null) return
- editor.destroy()
-})
-
-// 编辑器创建完成后回调
-const handleCreated = (editor) => {
- editorRef.value = editor
-
- // ✅ 在这里获取工具栏实例(必须等编辑器和工具栏都挂载后)
- nextTick(() => {
- const toolbar = DomEditor.getToolbar(editor)
- if (toolbar) {
- const curToolbarConfig = toolbar.getConfig()
- console.log('curToolbarConfig.toolbarKeys', curToolbarConfig.toolbarKeys)
- toolbarRef.value = toolbar
- console.log('toolbarRef.value', valueHtml.value)
+// 富文本编辑器配置
+const editorConfig = {
+ placeholder: '请输入内容...',
+ MENU_CONF: {
+ uploadImage: {
+ customUpload: async (file: any, insertFn: any) => {
+ try {
+ // 调用封装后的上传API
+ const res = await uploadImageApi(file);
+ // 插入图片到富文本
+ insertFn(res.url);
+ } catch (error: any) {
+ // 复用你已有的错误提示逻辑(ElNotification)
+ const errMsg = error?.message || error?.data?.msg || '图片上传失败';
+ alert(`图片${file.name}上传失败:${errMsg}`);
+ ElNotification({
+ message: errMsg || '未知的错误!',
+ type: 'error',
+ duration: 2000,
+ customClass: 'global-notification'
+ })
+ }
+ },
+ // 保留基础配置
+ fieldName: 'image',
+ timeout: 30 * 1000,
+ maxFileSize: 5 * 1024 * 1024,
+ allowedFileTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'],
}
- })
+ }
}
/**
@@ -99,10 +122,15 @@ const searchForm = ref({
noticeName: '',
startDateTime: '',
endDateTime: '',
- status: 1,
+ status: 2,
})
const searchOptions = ref(search)
+/**
+ * @description: 定义tab数据
+ */
+const activeTab = ref(2)
+
/**
* @description: 定义表格数据
*/
@@ -131,20 +159,18 @@ const noticeForm = ref({
publishStartTime: '',
publishEndTime: '',
status: 1,
+ id: 0,
})
const noticeFormRef = ref()
const noticeRules = ref(rules())
const noticeFormItem = ref(formItem)
const noticeFormOptionsMap = ref({
status: [
- { label: '发布', value: 1 },
- { label: '草稿', value: 2 },
+ { label: '发布', value: 2 },
+ { label: '草稿', value: 1 },
],
})
-/**
- * @description: 定义公共数据处理方法
- */
/**
* @description: 定义请求数据方法
*/
@@ -161,17 +187,16 @@ const getNoticeList = async () => {
const data: any = await getNoticeListApi(params)
// 表格数据
noticeTree.value = data.data.map((item: any) => ({
+ id: item.id,
noticeName: item.name,
noticeContent: item.content,
- startDateTime: item.publish_start_time,
+ publishTime: item.publish_time,
status: item.status,
}))
// 分页数据
total.value = data.total
currentPage.value = data.current_page
pageSize.value = Number(data.per_page)
-
- console.log(noticeTree.value)
}
/**
@@ -192,8 +217,9 @@ const handleReset = () => {
noticeName: '',
startDateTime: '',
endDateTime: '',
- status: 1,
+ status: 2,
}
+ activeTab.value = 2
getNoticeList()
}
const handleCreate = () => {
@@ -201,14 +227,54 @@ const handleCreate = () => {
dialogTitle.value = '新建公告'
dialogType.value = 'create'
}
+
+/**
+ * @description: 定义tab方法
+ */
+const handleTabChange = (tab: number) => {
+ activeTab.value = tab
+ searchForm.value.status = tab
+ currentPage.value = 1
+ getNoticeList()
+}
+
/**
* @description: 定义表格方法
*/
const handleView = (row: any) => {
+ console.log(row)
dialogVisible.value = true
dialogTitle.value = '查看公告'
dialogType.value = 'view'
+ noticeForm.value = {
+ noticeName: row.noticeName,
+ noticeContent: row.noticeContent,
+ } as any
}
+
+
+const handleEdit = (row: any) => {
+ dialogVisible.value = true
+ dialogTitle.value = '编辑公告'
+ dialogType.value = 'edit'
+ noticeForm.value = {
+ noticeName: row.noticeName,
+ noticeContent: row.noticeContent,
+ publishStartTime: row.startDateTime,
+ publishEndTime: row.endDateTime,
+ status: row.status,
+ id: row.id,
+ }
+}
+// 删除公告
+const handleDelete = async (row: any) => {
+ const params = {
+ id: row.id,
+ }
+ await deleteNoticeApi(params)
+ getNoticeList()
+}
+
/**
* @description: 定义分页方法
*/
@@ -221,24 +287,79 @@ const handlePaginationChange = async (page: { currentPage: number, pageSize: num
* @description: 定义弹窗方法
*/
const handleSubmit = async () => {
+ await noticeFormRef.value.validate()
if (dialogType.value === 'create') {
+ noticeForm.value.noticeContent = valueHtml.value
const params = {
name: noticeForm.value.noticeName,
content: noticeForm.value.noticeContent,
status: noticeForm.value.status,
}
await createNoticeApi(params)
+ dialogVisible.value = false
+ getNoticeList()
+ }else {
+ noticeForm.value.noticeContent = valueHtml.value
+ const params = {
+ id: noticeForm.value.id,
+ name: noticeForm.value.noticeName,
+ content: noticeForm.value.noticeContent,
+ status: noticeForm.value.status,
+ }
+ await editNoticeApi(params)
+ dialogVisible.value = false
+ getNoticeList()
}
- dialogVisible.value = false
- getNoticeList()
+
}
+
const handleCancel = () => {
dialogVisible.value = false
}
const handleClose = () => {
dialogVisible.value = false
}
+
/**
- * @description: 定义弹窗表格方法
+ * @description: 定义富文本编辑器方法
*/
-
\ No newline at end of file
+// 组件销毁时销毁编辑器
+onBeforeUnmount(() => {
+ const editor = editorRef.value
+ if (editor == null) return
+ editor.destroy()
+})
+
+// 富文本编辑器创建完成后回调
+const handleCreated = (editor: any) => {
+ editorRef.value = editor
+
+ // 在这里获取工具栏实例(必须等编辑器和工具栏都挂载后)
+ nextTick(() => {
+ const toolbar = DomEditor.getToolbar(editor)
+ if (toolbar) {
+ const curToolbarConfig = toolbar.getConfig()
+ console.log('curToolbarConfig.toolbarKeys', curToolbarConfig.toolbarKeys)
+ toolbarRef.value = toolbar
+ console.log('toolbarRef.value', valueHtml.value)
+ }
+ })
+}
+
+
+
diff --git a/src/views/notice/options.ts b/src/views/notice/options.ts
index ee75659..16e93cd 100644
--- a/src/views/notice/options.ts
+++ b/src/views/notice/options.ts
@@ -2,7 +2,7 @@
* @description: 搜索配置
*/
export const search = [
- { prop: 'username', label: '公告名称', type: 'input' as const, placeholder: '请输入公告名称', width: '120px' },
+ { prop: 'noticeName', label: '公告名称', type: 'input' as const, placeholder: '请输入公告名称', width: '120px' },
{
prop: "startDateTime", label: '发布时间', type: 'date' as const, dateType: 'date' as const, // 时间范围选择器
valueFormat: 'YYYY-MM-DD',
@@ -20,8 +20,8 @@ export const search = [
*/
export const tableColumns = [
{ prop: 'noticeName', label: '公告名称'},
- { prop: 'noticeContent', label: '公告内容'},
- { prop: 'startDateTime', label: '发布时间'},
+ // { prop: 'noticeContent', label: '公告内容'},
+ { prop: 'publishTime', label: '发布时间'},
{ slotName: 'status', label: '状态'},
{ slotName: 'action', label: '操作'},
]
@@ -32,6 +32,6 @@ export const tableColumns = [
export const formItem = [
{ prop: 'noticeName', label: '公告名称', type: 'input' as const, placeholder: '请输入公告名称'},
// 公告内容
- { slotName: 'noticeContent',label: '公告内容', type: 'edit' as const},
+ { slotName: 'noticeContent', label: '公告内容', type: 'editor' as const},
{ prop: 'status', label: '状态', type: 'radio' as const, placeholder: '请选择状态'},
]
diff --git a/src/views/notice/rules.ts b/src/views/notice/rules.ts
index 0a47db1..d6e7e5e 100644
--- a/src/views/notice/rules.ts
+++ b/src/views/notice/rules.ts
@@ -1,7 +1,7 @@
import type { FormRules } from 'element-plus'
export const rules = (): FormRules => {
return {
- name: [
+ noticeName: [
{ required: true, message: '请输入名称', trigger: ['blur'] }
],
}