|
|
@@ -1,275 +0,0 @@
|
|
|
-<template>
|
|
|
- <basicModal
|
|
|
- @register="modalRegister"
|
|
|
- ref="modalRef"
|
|
|
- class="basicModal basicFormModal"
|
|
|
- @ok="okModal"
|
|
|
- @close="handleReset"
|
|
|
- >
|
|
|
- <template #default>
|
|
|
- <el-form
|
|
|
- :model="formParams"
|
|
|
- :rules="rules"
|
|
|
- ref="formRef"
|
|
|
- label-placement="left"
|
|
|
- :label-width="80"
|
|
|
- class="mt-6"
|
|
|
- >
|
|
|
- <el-form-item label="标题" prop="title">
|
|
|
- <el-input placeholder="请输入标题" v-model="formParams.title" />
|
|
|
- </el-form-item>
|
|
|
-
|
|
|
- <el-form-item label="内容" prop="content">
|
|
|
- <div class="editor-container">
|
|
|
- <Toolbar
|
|
|
- style="border-bottom: 1px solid #ccc"
|
|
|
- :editor="editorRef"
|
|
|
- :defaultConfig="toolbarConfig"
|
|
|
- :mode="mode"
|
|
|
- />
|
|
|
- <Editor
|
|
|
- style="height: 350px; overflow-y: hidden"
|
|
|
- v-model="formParams.content"
|
|
|
- :defaultConfig="editorConfig"
|
|
|
- :mode="mode"
|
|
|
- @on-created="handleCreated"
|
|
|
- />
|
|
|
- </div>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="发布时间" prop="publicTime">
|
|
|
- <el-date-picker
|
|
|
- v-model="formParams.publicTime"
|
|
|
- value-format="yyyy-MM-dd HH:mm:ss"
|
|
|
- type="datetime"
|
|
|
- clearable
|
|
|
- />
|
|
|
- </el-form-item>
|
|
|
- </el-form>
|
|
|
- </template>
|
|
|
- </basicModal>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script lang="ts" setup>
|
|
|
- import { onBeforeUnmount, reactive, ref, shallowRef, nextTick } from 'vue';
|
|
|
-
|
|
|
- import { ElMessage } from 'element-plus';
|
|
|
- import type { formParamsType } from './types';
|
|
|
- import { basicModal, useModal } from '@/components/Modal';
|
|
|
- import { addArticle, editArticle, articleInfo } from '@/api/article/index';
|
|
|
-
|
|
|
- import '@wangeditor/editor/dist/css/style.css'; // 引入 css
|
|
|
-
|
|
|
- import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
|
|
|
- import { useUserStoreWidthOut } from '@/store/modules/user';
|
|
|
- import { useGlobSetting } from '@/hooks/setting';
|
|
|
-
|
|
|
- const rules = {
|
|
|
- title: {
|
|
|
- required: true,
|
|
|
- message: '标题不能为空',
|
|
|
- trigger: 'blur',
|
|
|
- },
|
|
|
- content: {
|
|
|
- required: true,
|
|
|
- message: '内容不能为空',
|
|
|
- trigger: 'blur',
|
|
|
- },
|
|
|
- publicTime: {
|
|
|
- required: true,
|
|
|
- message: '发布时间不能为空',
|
|
|
- trigger: 'change',
|
|
|
- },
|
|
|
- };
|
|
|
-
|
|
|
- const emit = defineEmits(['change', 'register']);
|
|
|
-
|
|
|
- const props = defineProps({
|
|
|
- title: {
|
|
|
- type: String,
|
|
|
- default: '添加文章',
|
|
|
- },
|
|
|
- width: {
|
|
|
- type: Number,
|
|
|
- default: 450,
|
|
|
- },
|
|
|
- });
|
|
|
-
|
|
|
- const message = ElMessage;
|
|
|
- const formRef: any = ref(null);
|
|
|
- const isDrawer = ref(false);
|
|
|
- const userStore = useUserStoreWidthOut();
|
|
|
- const token = userStore.getToken;
|
|
|
-
|
|
|
- const [modalRegister, { openModal, closeModal, setSubLoading, setProps }] = useModal({
|
|
|
- title: props.title,
|
|
|
- subBtuText: '保存',
|
|
|
- width: 950,
|
|
|
- });
|
|
|
-
|
|
|
- const defaultValueRef = () => ({
|
|
|
- id: null,
|
|
|
- content: '',
|
|
|
- title: '',
|
|
|
- publicTime: undefined,
|
|
|
- });
|
|
|
-
|
|
|
- const formParams = ref<formParamsType>(defaultValueRef());
|
|
|
-
|
|
|
- // 编辑器实例,必须用 shallowRef
|
|
|
- const editorRef = shallowRef();
|
|
|
- const globSetting = useGlobSetting();
|
|
|
- const mode = ref('default'); // 或 'simple'
|
|
|
- const { uploadUrl, imgUrl } = globSetting;
|
|
|
- const uploadHeaders = reactive({
|
|
|
- satoken: token,
|
|
|
- });
|
|
|
-
|
|
|
- // 内容 HTML
|
|
|
- const valueHtml = ref(formParams.value.content);
|
|
|
-
|
|
|
- type InsertFnType = (url: string, alt?: string, href?: string) => void;
|
|
|
-
|
|
|
- const toolbarConfig = {};
|
|
|
- const editorConfig = reactive({
|
|
|
- MENU_CONF: {
|
|
|
- uploadImage: {
|
|
|
- fieldName: 'file',
|
|
|
- headers: uploadHeaders,
|
|
|
- meta: {
|
|
|
- type: 0,
|
|
|
- },
|
|
|
- server: `${uploadUrl}/api/file/do_upload_action`,
|
|
|
- // 自定义插入图片
|
|
|
- customInsert(res: any, insertFn: InsertFnType) {
|
|
|
- // res 即服务端的返回结果
|
|
|
- // 从 res 中找到 url alt href ,然后插图图片
|
|
|
- if (res.code === 200) {
|
|
|
- insertFn(imgUrl + res.data.filePath);
|
|
|
- }
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- placeholder: '请输入内容...',
|
|
|
- });
|
|
|
-
|
|
|
- // 组件销毁时,也及时销毁编辑器
|
|
|
- onBeforeUnmount(() => {
|
|
|
- const editor = editorRef.value;
|
|
|
- if (editor == null) return;
|
|
|
- editor.destroy();
|
|
|
- });
|
|
|
-
|
|
|
- const handleCreated = (editor) => {
|
|
|
- editorRef.value = editor; // 记录 editor 实例,重要!
|
|
|
- };
|
|
|
-
|
|
|
- async function showModal(id?) {
|
|
|
- if (id) {
|
|
|
- formParams.value.id = id;
|
|
|
- setProps({
|
|
|
- title: '编辑文章',
|
|
|
- });
|
|
|
- getInfo();
|
|
|
- return;
|
|
|
- }
|
|
|
- setProps({
|
|
|
- title: '添加文章',
|
|
|
- });
|
|
|
- openModal();
|
|
|
- }
|
|
|
-
|
|
|
- function okModal() {
|
|
|
- formRef.value.validate((valid) => {
|
|
|
- if (!valid) {
|
|
|
- setSubLoading(false);
|
|
|
- return message.error('请填写完整信息');
|
|
|
- }
|
|
|
- const msg = formParams.value.id ? '编辑成功' : '添加成功';
|
|
|
- if (formParams.value.id) {
|
|
|
- editArticle(formParams.value)
|
|
|
- .then((_) => {
|
|
|
- message.success(msg);
|
|
|
- setSubLoading(false);
|
|
|
- emit('change');
|
|
|
- handleReset();
|
|
|
- closeModal();
|
|
|
- })
|
|
|
- .catch(() => {
|
|
|
- setSubLoading(false);
|
|
|
- });
|
|
|
- } else {
|
|
|
- addArticle(formParams.value)
|
|
|
- .then((_) => {
|
|
|
- message.success(msg);
|
|
|
- setSubLoading(false);
|
|
|
- emit('change');
|
|
|
- handleReset();
|
|
|
- closeModal();
|
|
|
- })
|
|
|
- .catch(() => {
|
|
|
- setSubLoading(false);
|
|
|
- });
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- function handleReset() {
|
|
|
- formRef.value.resetFields();
|
|
|
- formParams.value = Object.assign(formParams.value, defaultValueRef());
|
|
|
- }
|
|
|
-
|
|
|
- function getInfo() {
|
|
|
- articleInfo({ id: formParams.value.id }).then((res) => {
|
|
|
- const params = {
|
|
|
- id: res.id,
|
|
|
- title: res.title,
|
|
|
- content: res.content,
|
|
|
- publicTime: res.publicTime,
|
|
|
- };
|
|
|
- formParams.value = Object.assign(formParams.value, params);
|
|
|
- isDrawer.value = true;
|
|
|
- valueHtml.value = res.content;
|
|
|
- openModal();
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- defineExpose({
|
|
|
- showModal,
|
|
|
- closeModal,
|
|
|
- });
|
|
|
-</script>
|
|
|
-
|
|
|
-<style lang="scss" scoped>
|
|
|
- .editor-container {
|
|
|
- border: 1px solid #e5e7eb;
|
|
|
- z-index: 100;
|
|
|
- dl,
|
|
|
- dd,
|
|
|
- h1,
|
|
|
- h2,
|
|
|
- h3,
|
|
|
- h4,
|
|
|
- h5,
|
|
|
- h6,
|
|
|
- hr,
|
|
|
- figure,
|
|
|
- p,
|
|
|
- pre {
|
|
|
- margin: revert;
|
|
|
- }
|
|
|
- h1,
|
|
|
- h2,
|
|
|
- h3,
|
|
|
- h4,
|
|
|
- h5,
|
|
|
- h6 {
|
|
|
- font-size: revert;
|
|
|
- font-weight: revert;
|
|
|
- }
|
|
|
- ul {
|
|
|
- list-style: circle;
|
|
|
- margin: revert;
|
|
|
- padding: revert;
|
|
|
- }
|
|
|
- }
|
|
|
-</style>
|