sdsd
This commit is contained in:
parent
22c6fe6da1
commit
618f786364
@ -22,7 +22,12 @@
|
|||||||
background-color: #c4cbd7;
|
background-color: #c4cbd7;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
.el-upload-list__item-name{
|
||||||
|
padding: 4px !important;
|
||||||
|
}
|
||||||
|
.el-upload-list__item-file-name{
|
||||||
|
overflow: visible!important;
|
||||||
|
}
|
||||||
// .el-popover.el-popper {
|
// .el-popover.el-popper {
|
||||||
// border-radius: var(--my-border-radius) !important;
|
// border-radius: var(--my-border-radius) !important;
|
||||||
// }
|
// }
|
||||||
|
|||||||
@ -10,8 +10,27 @@
|
|||||||
<div class="editor-box-content">
|
<div class="editor-box-content">
|
||||||
<div class="title-box">
|
<div class="title-box">
|
||||||
<input type="text" v-model="newTitle" class="title-input" placeholder="请输入文章标题" />
|
<input type="text" v-model="newTitle" class="title-input" placeholder="请输入文章标题" />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<Editor class="editor" style="height: calc(100% - 60px); overflow-y: hidden;" v-model="valueHtml"
|
<div class="title-upload">
|
||||||
|
<!-- <el-button type="primary">
|
||||||
|
上传患教图片
|
||||||
|
<el-input type="file" class="up-input" @change="uploadBgimg" ref="uploadBgimg" />
|
||||||
|
</el-button>
|
||||||
|
<span class="title-span" :preview-src-list="['123.png']">上传图片</span> -->
|
||||||
|
<el-upload ref="upload" class="upload-demo" action="" :limit="1" :file-list="fileList"
|
||||||
|
:on-exceed="handleExceed" :on-change="handleChangeBgimg" :auto-upload="false"
|
||||||
|
:on-preview="handlePreview" :show-file-list="false">
|
||||||
|
<template #trigger>
|
||||||
|
<el-button type="primary">设置患教图片</el-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #file>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
<UploadList v-if="cover_image" v-model="cover_image" @remove="removeImg" @preview="handlePreview" ></UploadList>
|
||||||
|
</div>
|
||||||
|
<Editor class="editor" style="height: calc(100% - 140px); overflow-y: hidden;" v-model="valueHtml"
|
||||||
:defaultConfig="editorConfig" :mode="mode" @onCreated="handleCreated" />
|
:defaultConfig="editorConfig" :mode="mode" @onCreated="handleCreated" />
|
||||||
</div>
|
</div>
|
||||||
<!-- 添加字数统计显示 -->
|
<!-- 添加字数统计显示 -->
|
||||||
@ -42,7 +61,8 @@
|
|||||||
<el-button type="primary" @click="dialogPreview = false">关闭</el-button>
|
<el-button type="primary" @click="dialogPreview = false">关闭</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
|
<el-image-viewer @close="() => { showViewer = false }" v-if="showViewer" :url-list="[cover_image]" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
@ -56,14 +76,16 @@ import { getCode } from '@/api/upload'
|
|||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { DomEditor } from '@wangeditor/editor'
|
import { DomEditor } from '@wangeditor/editor'
|
||||||
|
|
||||||
import OSS from 'ali-oss'
|
// import OSS from 'ali-oss'
|
||||||
|
import { genFileId } from 'element-plus'
|
||||||
|
import UploadList from './uploadList.vue'
|
||||||
|
|
||||||
const ossurl = 'https://image-fudan.oss-cn-beijing.aliyuncs.com'
|
const ossurl = 'https://image-fudan.oss-cn-beijing.aliyuncs.com'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
|
const showViewer = ref(false)
|
||||||
|
|
||||||
const generating = ref(1)
|
const generating = ref(1)
|
||||||
// 编辑器实例,必须用 shallowRef
|
// 编辑器实例,必须用 shallowRef
|
||||||
@ -134,7 +156,6 @@ editorConfig.MENU_CONF['uploadImage'] = {
|
|||||||
// }
|
// }
|
||||||
// 自定义上传
|
// 自定义上传
|
||||||
async customUpload(file, insertFn) {
|
async customUpload(file, insertFn) {
|
||||||
|
|
||||||
const url = await uploadFile(file)
|
const url = await uploadFile(file)
|
||||||
insertFn(url, file.name, url);
|
insertFn(url, file.name, url);
|
||||||
|
|
||||||
@ -151,7 +172,6 @@ const uploadFile = (file) => {
|
|||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
const code = await getCode()
|
const code = await getCode()
|
||||||
const res = JSON.parse(code.token)
|
const res = JSON.parse(code.token)
|
||||||
console.log(res)
|
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('policy', res.policy);
|
formData.append('policy', res.policy);
|
||||||
formData.append('OSSAccessKeyId', res.ossAccessKeyId);
|
formData.append('OSSAccessKeyId', res.ossAccessKeyId);
|
||||||
@ -169,14 +189,27 @@ const uploadFile = (file) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const handleChangeBgimg = async (file) => {
|
||||||
|
console.log(file)
|
||||||
|
const url = await uploadFile(file.raw)
|
||||||
|
cover_image.value = url
|
||||||
|
fileList.value = [{ url: url, name: file.name }]
|
||||||
|
}
|
||||||
|
const upload = ref(null)
|
||||||
|
const handleExceed = (files) => {
|
||||||
|
upload.value.clearFiles()
|
||||||
|
const file = files[0]
|
||||||
|
file.uid = genFileId()
|
||||||
|
upload.value.handleStart(file)
|
||||||
|
}
|
||||||
|
const cover_image = ref('')
|
||||||
const handleSaveArticle = () => {
|
const handleSaveArticle = () => {
|
||||||
|
|
||||||
if (route.query.id) {
|
if (route.query.id) {
|
||||||
editNews({
|
editNews({
|
||||||
title: newTitle.value,
|
title: newTitle.value,
|
||||||
content: valueHtml.value
|
content: valueHtml.value,
|
||||||
|
cover_image: cover_image.value
|
||||||
}, route.query.id).then(res => {
|
}, route.query.id).then(res => {
|
||||||
ElNotification.success('编辑成功')
|
ElNotification.success('编辑成功')
|
||||||
router.back()
|
router.back()
|
||||||
@ -184,7 +217,8 @@ const handleSaveArticle = () => {
|
|||||||
} else {
|
} else {
|
||||||
addNews({
|
addNews({
|
||||||
title: newTitle.value,
|
title: newTitle.value,
|
||||||
content: valueHtml.value
|
content: valueHtml.value,
|
||||||
|
cover_image: cover_image.value
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
ElNotification.success('添加成功')
|
ElNotification.success('添加成功')
|
||||||
router.back()
|
router.back()
|
||||||
@ -235,15 +269,22 @@ const handlePreviewArticle = () => {
|
|||||||
dialogPreview.value = true
|
dialogPreview.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const previewImg = ref('')
|
||||||
|
const handlePreview = () => {
|
||||||
|
showViewer.value = true
|
||||||
|
}
|
||||||
|
const removeImg = () => {
|
||||||
|
cover_image.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileList = ref([])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (route.query.id) {
|
if (route.query.id) {
|
||||||
newTitle.value = sessionStorage.getItem('title')
|
newTitle.value = sessionStorage.getItem('title')
|
||||||
|
cover_image.value = sessionStorage.getItem('cover_image')
|
||||||
|
const fileNameWithExt = cover_image.value.split('/').pop(); // hello.png
|
||||||
|
const fileName = fileNameWithExt.split('.').slice(0, -1).join('.'); // hello
|
||||||
|
fileList.value = [{ url: sessionStorage.getItem('cover_image'), name: fileName }]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -824,6 +865,25 @@ app.appContext.app.directive('auto-resize', vAutoResize)
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.title-upload {
|
||||||
|
border-bottom: 1px solid var(--el-border-color);
|
||||||
|
padding-bottom: 10px;
|
||||||
|
.el-button {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.up-input {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 0;
|
||||||
|
opacity: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes blink {
|
@keyframes blink {
|
||||||
|
|||||||
@ -2,17 +2,9 @@
|
|||||||
<div>
|
<div>
|
||||||
<div class="user-search">
|
<div class="user-search">
|
||||||
<el-input style="width: 200px;margin-right: 10px;" v-model="query.title" placeholder="请输入文章标题" />
|
<el-input style="width: 200px;margin-right: 10px;" v-model="query.title" placeholder="请输入文章标题" />
|
||||||
<el-date-picker
|
<el-date-picker v-model="dateTime" type="daterange" range-separator="至" start-placeholder="开始日期"
|
||||||
v-model="dateTime"
|
end-placeholder="结束日期" value-format="YYYY-MM-DD" @change="handleDateChange" clearable
|
||||||
type="daterange"
|
style="margin-right: 10px;" />
|
||||||
range-separator="至"
|
|
||||||
start-placeholder="开始日期"
|
|
||||||
end-placeholder="结束日期"
|
|
||||||
value-format="YYYY-MM-DD"
|
|
||||||
@change="handleDateChange"
|
|
||||||
clearable
|
|
||||||
style="margin-right: 10px;"
|
|
||||||
/>
|
|
||||||
<el-button type="primary" icon="Search" @click="handleSearch">搜索</el-button>
|
<el-button type="primary" icon="Search" @click="handleSearch">搜索</el-button>
|
||||||
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||||
<el-button type="primary" @click="handleBatchDelete" :disabled="selectedRows.length === 0">批量删除</el-button>
|
<el-button type="primary" @click="handleBatchDelete" :disabled="selectedRows.length === 0">批量删除</el-button>
|
||||||
@ -22,16 +14,18 @@
|
|||||||
<el-table :data="tableData" style="width: 100%" @selection-change="handleSelectionChange" row-key="id">
|
<el-table :data="tableData" style="width: 100%" @selection-change="handleSelectionChange" row-key="id">
|
||||||
<el-table-column type="selection" width="55" align="center" reserve-selection />
|
<el-table-column type="selection" width="55" align="center" reserve-selection />
|
||||||
<el-table-column prop="title" label="文章标题" />
|
<el-table-column prop="title" label="文章标题" />
|
||||||
<!-- <el-table-column prop="content" label="内容">
|
<el-table-column prop="content" label="患教图片">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div class="content-wrap" v-html="scope.row.content"></div>
|
<span v-if="!scope.row.cover_image">--</span>
|
||||||
|
<el-image v-else style="width: 36px; height: 36px" :src="scope.row.cover_image" :zoom-rate="1.2" :max-scale="7"
|
||||||
|
:min-scale="0.2" :preview-src-list="[scope.row.cover_image]" fit="cover" preview-teleported />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column> -->
|
</el-table-column>
|
||||||
<el-table-column prop="created_at" label="创建时间" />
|
<el-table-column prop="created_at" label="创建时间" />
|
||||||
<el-table-column label="操作" width="100" align="center">
|
<el-table-column label="操作" width="100" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-link type="primary" @click="editNews(scope.row)">
|
<el-link type="primary" @click="editNews(scope.row)">
|
||||||
<el-icon type="primary" @click="editNews(scope.row)">
|
<el-icon type="primary">
|
||||||
<Edit />
|
<Edit />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</el-link>
|
</el-link>
|
||||||
@ -48,15 +42,9 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<div class="user-pagination">
|
<div class="user-pagination">
|
||||||
<el-pagination
|
<el-pagination background layout="total, sizes, prev, pager, next, jumper" :total="total"
|
||||||
background
|
:page-size="query.page_size" :current-page="query.page" @size-change="handleSizeChange"
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
@current-change="handleCurrentChange" />
|
||||||
:total="total"
|
|
||||||
:page-size="query.page_size"
|
|
||||||
:current-page="query.page"
|
|
||||||
@size-change="handleSizeChange"
|
|
||||||
@current-change="handleCurrentChange"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -82,11 +70,12 @@ const addNews = () => {
|
|||||||
const editNews = (row) => {
|
const editNews = (row) => {
|
||||||
sessionStorage.setItem('works', row.content);
|
sessionStorage.setItem('works', row.content);
|
||||||
sessionStorage.setItem('title', row.title);
|
sessionStorage.setItem('title', row.title);
|
||||||
|
sessionStorage.setItem('cover_image', row.cover_image);
|
||||||
router.push(`/addNew?id=${row.id}`)
|
router.push(`/addNew?id=${row.id}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleDeleteNews = (row) => {
|
const handleDeleteNews = (row) => {
|
||||||
deleteNews({ids: `${row.id}`}).then(res => {
|
deleteNews({ ids: `${row.id}` }).then(res => {
|
||||||
ElMessage.success('删除成功')
|
ElMessage.success('删除成功')
|
||||||
getNews()
|
getNews()
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
@ -99,7 +88,7 @@ const handleSelectionChange = (selection) => {
|
|||||||
selectedRows.value = selection
|
selectedRows.value = selection
|
||||||
}
|
}
|
||||||
const handleBatchDelete = () => {
|
const handleBatchDelete = () => {
|
||||||
deleteNews({ids: selectedRows.value.map(item => item.id).join(',')}).then(res => {
|
deleteNews({ ids: selectedRows.value.map(item => item.id).join(',') }).then(res => {
|
||||||
ElMessage.success('删除成功')
|
ElMessage.success('删除成功')
|
||||||
getNews()
|
getNews()
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
@ -159,24 +148,27 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.user-search {
|
.user-search {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
.content-wrap {
|
|
||||||
max-height: 100px;
|
.content-wrap {
|
||||||
overflow: hidden;
|
max-height: 100px;
|
||||||
text-overflow: ellipsis;
|
overflow: hidden;
|
||||||
display: -webkit-box;
|
text-overflow: ellipsis;
|
||||||
-webkit-line-clamp: 1;
|
display: -webkit-box;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-line-clamp: 1;
|
||||||
}
|
-webkit-box-orient: vertical;
|
||||||
.el-link+ .el-link {
|
}
|
||||||
margin-left: 10px;
|
|
||||||
}
|
.el-link+.el-link {
|
||||||
.user-pagination {
|
margin-left: 10px;
|
||||||
margin-top: 20px;
|
}
|
||||||
text-align: right;
|
|
||||||
display: flex;
|
.user-pagination {
|
||||||
justify-content: right;
|
margin-top: 20px;
|
||||||
}
|
text-align: right;
|
||||||
|
display: flex;
|
||||||
|
justify-content: right;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
55
src/views/news/uploadList.vue
Normal file
55
src/views/news/uploadList.vue
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<template>
|
||||||
|
<ul class="el-upload-list el-upload-list--text">
|
||||||
|
<li class="el-upload-list__item is-success" tabindex="0"><!--v-if-->
|
||||||
|
<div class="el-upload-list__item-info"><a class="el-upload-list__item-name" @click="handleclick"><i
|
||||||
|
class="el-icon el-icon--document"><svg xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 1024 1024">
|
||||||
|
<path fill="currentColor"
|
||||||
|
d="M832 384H576V128H192v768h640zm-26.496-64L640 154.496V320zM160 64h480l256 256v608a32 32 0 0 1-32 32H160a32 32 0 0 1-32-32V96a32 32 0 0 1 32-32m160 448h384v64H320zm0-192h160v64H320zm0 384h384v64H320z">
|
||||||
|
</path>
|
||||||
|
</svg></i><span class="el-upload-list__item-file-name"
|
||||||
|
title="element-plus-logo.svg">{{fileName}}</span></a><!--v-if--></div><label
|
||||||
|
class="el-upload-list__item-status-label"><i
|
||||||
|
class="el-icon el-icon--upload-success el-icon--circle-check"><svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
|
||||||
|
<path fill="currentColor"
|
||||||
|
d="M512 896a384 384 0 1 0 0-768 384 384 0 0 0 0 768m0 64a448 448 0 1 1 0-896 448 448 0 0 1 0 896">
|
||||||
|
</path>
|
||||||
|
<path fill="currentColor"
|
||||||
|
d="M745.344 361.344a32 32 0 0 1 45.312 45.312l-288 288a32 32 0 0 1-45.312 0l-160-160a32 32 0 1 1 45.312-45.312L480 626.752l265.344-265.408z">
|
||||||
|
</path>
|
||||||
|
</svg></i></label><i class="el-icon el-icon--close" @click="handleClose"><svg xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 1024 1024">
|
||||||
|
<path fill="currentColor"
|
||||||
|
d="M764.288 214.592 512 466.88 259.712 214.592a31.936 31.936 0 0 0-45.12 45.12L466.752 512 214.528 764.224a31.936 31.936 0 1 0 45.12 45.184L512 557.184l252.288 252.288a31.936 31.936 0 0 0 45.12-45.12L557.12 512.064l252.288-252.352a31.936 31.936 0 1 0-45.12-45.184z">
|
||||||
|
</path>
|
||||||
|
</svg></i><!-- Due to close btn only appears when li gets focused disappears after li gets blurred, thus keyboard navigation can never reach close btn--><!-- This is a bug which needs to be fixed --><!-- TODO: Fix the incorrect navigation interaction --><i
|
||||||
|
class="el-icon--close-tip">press delete to remove</i><!--v-if-->
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
|
||||||
|
})
|
||||||
|
const emit = defineEmits([
|
||||||
|
'update:modelValue', 'remove', 'preview'
|
||||||
|
])
|
||||||
|
const handleClose = () => {
|
||||||
|
emit('remove')
|
||||||
|
}
|
||||||
|
const handleclick = () => {
|
||||||
|
emit('preview')
|
||||||
|
}
|
||||||
|
const fileName = computed(() => {
|
||||||
|
return props.modelValue.split('/').pop()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
Loading…
x
Reference in New Issue
Block a user