优化:网站管理界面

This commit is contained in:
jmal 2021-01-21 22:48:02 +08:00
parent 0e7d958c07
commit 8d140c3b92
9 changed files with 139 additions and 93 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "jmal-cloud-view", "name": "jmal-cloud-view",
"version": "2.0.1", "version": "2.0.3",
"description": "jmal cloud", "description": "jmal cloud",
"author": "Jmal <zhushilun084@163.com>", "author": "Jmal <zhushilun084@163.com>",
"license": "MIT", "license": "MIT",

View File

@ -1,49 +1,64 @@
<template> <template>
<div class="upload-input-image"> <div class="upload-input-image">
<select-file title="选择图片" @select="selectedFile" :visible.sync="dialogSelectFile"></select-file> <el-row>
<div class="upload"> <el-col :xs="24">
<div class="url-desc url-desc-first">输入图片的url 或</div> <select-file title="选择图片" @select="selectedFile" :visible.sync="dialogSelectFile"></select-file>
<el-button class="upload-select-btn" title="选择文件" type="primary" size="small" icon="el-icon-folder" circle @click="dialogSelectFile = true"></el-button> <div class="upload">
<el-upload <!-- <div class="url-desc url-desc-first">输入图片的url 或</div>-->
ref="uploadRef" <el-button class="upload-select-btn" title="选择文件" type="primary" size="small" icon="el-icon-folder" circle @click="dialogSelectFile = true"></el-button>
class="upload" <el-upload
action="/api/upload-markdown-image" ref="uploadRef"
:headers="headers" class="upload"
:data="extraData" action="/api/upload-markdown-image"
name="files" :headers="headers"
accept="image/*" :data="extraData"
:show-file-list="false" name="files"
:file-list="fileList" accept="image/*"
:limit="1" :show-file-list="false"
:before-upload="handleBeforeUpload" :file-list="fileList"
:on-success="handleSuccess" :limit="1"
:on-remove="handleFileListRemove" :before-upload="handleBeforeUpload"
:on-progress="handleProgress" :on-success="handleSuccess"
> :on-remove="handleFileListRemove"
<el-button title="上传" type="primary" size="small" icon="el-icon-upload2" circle></el-button> :on-progress="handleProgress"
<div class="url-desc" v-if="uploadState > 0" slot="tip"> >
<span v-show="uploadState === 1">图片上传中{{uploadPercentage}}%</span> <el-button title="上传" type="primary" size="small" icon="el-icon-upload2" circle></el-button>
<span v-show="uploadState === 2">图片上传成功</span> <div class="url-desc" v-if="uploadState > 0" slot="tip">
<span v-show="uploadState === 3">该图片不支持自动上传</span> <span v-show="uploadState === 1">图片上传中{{uploadPercentage}}%</span>
<span v-show="uploadState === 4">图片加载中</span> <span v-show="uploadState === 2">图片上传成功</span>
<i :class="{ <span v-show="uploadState === 3">该图片不支持自动上传</span>
<span v-show="uploadState === 4">图片加载中</span>
<i :class="{
'el-icon-loading': uploadState === 1 || uploadState === 4, 'el-icon-loading': uploadState === 1 || uploadState === 4,
'el-icon-check': uploadState === 2, 'el-icon-check': uploadState === 2,
'el-icon-warning-outline': uploadState === 3 'el-icon-warning-outline': uploadState === 3
}"></i> }"></i>
</div>
</el-upload>
</div> </div>
</el-upload> </el-col>
</div> <el-col :xs="24">
<el-tooltip class="item" effect="dark" placement="bottom"> <el-tooltip class="item" effect="dark" placement="bottom">
<el-input :autosize="intputAutosize" type="textarea" width="100%" v-model="currentValue" @change="change" @input="input" @focus="isLocked = true"></el-input> <el-input
<div slot="content"> :autosize="intputAutosize"
<el-image :style="{maxWidth: tipImageMaxWidth + 'px'}" :src="currentValue" fit="contain" @load="loadSuccess"> placeholder="请输入图片的url 或 上传"
<div slot="error" class="image-slot"> type="textarea"
<i class="el-icon-picture-outline"></i> width="100%"
v-model="currentValue"
@change="change"
@input="input"
@focus="isLocked = true">
</el-input>
<div slot="content">
<el-image :style="{maxWidth: tipImageMaxWidth + 'px'}" :src="currentValue" fit="contain" @load="loadSuccess">
<div slot="error" class="image-slot">
<i class="el-icon-picture-outline"></i>
</div>
</el-image>
</div> </div>
</el-image> </el-tooltip>
</div> </el-col>
</el-tooltip> </el-row>
</div> </div>
</template> </template>
<script> <script>
@ -219,6 +234,7 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.upload { .upload {
margin-bottom: 1px;
display: -webkit-box; display: -webkit-box;
.upload-select-btn { .upload-select-btn {
margin-right: 5px; margin-right: 5px;

View File

@ -109,6 +109,8 @@ export default {
} }
}, 100) }, 100)
}) })
} else {
this.valueTitles = []
} }
}, },
selectNode(props, data){ selectNode(props, data){

View File

@ -81,9 +81,19 @@ export default {
// 初始化值 // 初始化值
initHandle(){ initHandle(){
if(this.valueId){ if(this.valueId){
this.valueTitle = this.$refs.selectTree.getNode(this.valueId).data[this.props.label] // 初始化显示 this.$nextTick(() => {
this.$refs.selectTree.setCurrentKey(this.valueId) // 设置默认选中 // 设置默认选中
this.defaultExpandedKey = [this.valueId] // 设置默认展开 this.$refs.selectTree.setCurrentKey(this.valueId)
const that = this
setTimeout(function (){
// 初始化显示
that.valueTitle = that.$refs.selectTree.getNode(that.valueId).data[that.props.label]
}, 100)
// 设置默认展开
this.defaultExpandedKey = [this.valueId]
})
} else {
this.valueTitle = ''
} }
}, },
// 切换选项 // 切换选项

View File

@ -134,12 +134,6 @@ a:hover {
border-top: 1px solid #f4f4f4; border-top: 1px solid #f4f4f4;
} }
} }
/deep/.el-input {
width: unset;
}
/deep/.el-textarea {
max-width: 500px;
}
.form-slogan { .form-slogan {
width: 100%; width: 100%;
max-width: 500px; max-width: 500px;

View File

@ -46,9 +46,11 @@
</el-radio-group> </el-radio-group>
</div> </div>
</el-col> </el-col>
<el-col :xs="24" :sm="14"> <el-col :xs="24" :sm="14" class="text-align-right">
<el-button v-if="isFilter" type="text" size="mini" @click="cancelFilter">取消筛选</el-button>
<el-input <el-input
v-model="query.keyword" v-model="query.keyword"
style="width:unset;"
class="query-item" class="query-item"
clearable clearable
size="mini" size="mini"
@ -66,7 +68,6 @@
> >
</multiple-tree-select> </multiple-tree-select>
<el-button type="primary" size="mini" @click="theFilter">筛选</el-button> <el-button type="primary" size="mini" @click="theFilter">筛选</el-button>
<el-button v-if="isFilter" type="text" size="mini" @click="cancelFilter">取消筛选</el-button>
</el-col> </el-col>
</el-row> </el-row>
</div> </div>

View File

@ -158,9 +158,6 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
@import "src/styles/setting"; @import "src/styles/setting";
@import "src/styles/markdown"; @import "src/styles/markdown";
/deep/ .el-textarea {
max-width: 1080px;
}
/deep/ .el-collapse-item__header { /deep/ .el-collapse-item__header {
font-size: 16px; font-size: 16px;
padding-left: 20px; padding-left: 20px;

View File

@ -1,37 +1,37 @@
<template> <template>
<div class="container" v-wechat-title="title"> <div class="container" v-wechat-title="title">
<el-dialog class="dialog-cm" :title="dialogTitle" :close-on-click-modal="false" :visible.sync="dialogVisible"> <el-dialog class="dialog-cm" width="500px" :title="dialogTitle" :close-on-click-modal="false" :visible.sync="dialogVisible">
<el-form ref="managerForm" :model="form" label-position="left" :rules="rules" label-width="85px"> <el-form ref="managerForm" size="medium" :model="form" label-position="left" :rules="rules" label-width="95px">
<el-form-item label="分类名称" prop="name"> <el-form-item label="分类名称:" prop="name">
<el-input v-model="form.name" style="width: 100%;"/> <el-input v-model="form.name" placeholder="请输入分类名称"/>
</el-form-item> </el-form-item>
<el-form-item label="分类缩略名" prop="slug"> <el-form-item label="分类缩略名:" prop="slug">
<el-input v-model="form.slug" style="width: 100%;"/> <el-input v-model="form.slug" placeholder="分类缩略名用于创建友好的链接形式"/>
<div class="instruction">分类缩略名用于创建友好的链接形式.</div>
</el-form-item> </el-form-item>
<el-form-item label="父级分类" prop="parentCategoryId"> <el-form-item label="父级分类:" prop="parentCategoryId">
<el-cascader <tree-select
style="width: 100%;"
v-model="form.parentCategoryId" v-model="form.parentCategoryId"
placeholder="不选择" placeholder="不选择"
:options="categories" :options="categories"
:show-all-levels="false"
:props="{ checkStrictly: true, value: 'id', label: 'name'}" :props="{ checkStrictly: true, value: 'id', label: 'name'}"
clearable></el-cascader> >
</tree-select>
</el-form-item> </el-form-item>
<el-form-item label="分类描述" prop="desc"> <el-form-item label="分类描述:" prop="desc">
<el-input type="textarea" v-model="form.desc" :autosize="{ minRows: 2, maxRows: 6 }"/> <el-input type="textarea" placeholder="此文字用于描述分类, 在该分类首页中它会被显示" v-model="form.desc" :autosize="{ minRows: 2, maxRows: 6 }"/>
<div class="instruction">此文字用于描述分类, 在该分类首页中它会被显示.</div>
</el-form-item> </el-form-item>
<el-form-item label="分类背景" prop="categoryBackground"> <el-form-item label="分类背景:" prop="categoryBackground">
<upload-image-input v-model="form.categoryBackground"/> <upload-image-input v-model="form.categoryBackground"/>
<div class="instruction">在这里填入图片的URL地址, 以在分类页面显示一个背景大图.</div> <div class="instruction">在这里填入图片的URL地址, 以在分类页面显示一个背景大图.</div>
</el-form-item> </el-form-item>
<el-form-item>
<el-button native-type="submit" type="primary" size="small" :loading="categoryUpdateLoading"
@click.native.prevent="onSave('managerForm')">保 存
</el-button>
</el-form-item>
</el-form> </el-form>
<div slot="footer" class="dialog-footer">
<el-button size="small" @click="dialogVisible = false">取 消</el-button>
<el-button native-type="submit" type="primary" size="small" :loading="categoryUpdateLoading"
@click.native.prevent="onSave('managerForm')">保 存
</el-button>
</div>
</el-dialog> </el-dialog>
<el-card class="box-card"> <el-card class="box-card">
<div slot="header"> <div slot="header">
@ -106,10 +106,11 @@
<script> <script>
import categoryApi from "@/api/category"; import categoryApi from "@/api/category";
import UploadImageInput from "@/components/input/UploadImageInput"; import UploadImageInput from "@/components/input/UploadImageInput";
import TreeSelect from "@/components/select/tree";
export default { export default {
name: 'categoryManager', name: 'categoryManager',
components: {UploadImageInput}, components: {TreeSelect, UploadImageInput},
data() { data() {
return { return {
title: "分类管理", title: "分类管理",

View File

@ -1,24 +1,24 @@
<template> <template>
<div class="container" v-wechat-title="title"> <div class="container" v-wechat-title="title">
<el-dialog class="dialog-cm" :title="dialogTitle" :close-on-click-modal="false" :visible.sync="dialogVisible"> <el-dialog class="dialog-cm" width="500px" :title="dialogTitle" :close-on-click-modal="false" :visible.sync="dialogVisible">
<el-form ref="managerForm" :model="form" label-position="left" :rules="rules" label-width="85px"> <el-form ref="managerForm" size="medium" :model="form" label-position="left" :rules="rules" label-width="95px">
<el-form-item label="标签名称" prop="name"> <el-form-item label="标签名称:" prop="name">
<el-input v-model="form.name" style="width: 100%;"/> <el-input v-model="form.name" placeholder="请输入标签名称"/>
</el-form-item> </el-form-item>
<el-form-item label="标签缩略名" prop="slug"> <el-form-item label="标签缩略名:" prop="slug">
<el-input v-model="form.slug" style="width: 100%;"/> <el-input v-model="form.slug" placeholder="请输入标签缩略名"/>
<div class="instruction">标签缩略名用于创建友好的链接形式, 如果留空则默认使用标签名称.</div>
</el-form-item> </el-form-item>
<el-form-item label="标签背景" prop="categoryBackground"> <el-form-item label="标签背景:" prop="categoryBackground">
<upload-image-input v-model="form.tagBackground"/> <upload-image-input v-model="form.tagBackground"/>
<div class="instruction">在这里填入图片的URL地址, 以在该标签页面显示一个背景大图.</div> <div class="instruction">在这里填入图片的URL地址, 以在该标签页面显示一个背景大图.</div>
</el-form-item> </el-form-item>
<el-form-item>
<el-button native-type="submit" type="primary" :loading="tagUpdateLoading"
@click.native.prevent="onSave('managerForm')">保 存
</el-button>
</el-form-item>
</el-form> </el-form>
<div slot="footer" class="dialog-footer">
<el-button size="small" @click="dialogVisible = false">取 消</el-button>
<el-button size="small" native-type="submit" type="primary" :loading="tagUpdateLoading"
@click.native.prevent="onSave('managerForm')">保 存
</el-button>
</div>
</el-dialog> </el-dialog>
<el-card class="box-card"> <el-card class="box-card">
<div slot="header"> <div slot="header">
@ -38,9 +38,24 @@
</div> </div>
<div> <div>
<el-checkbox-group v-model="multipleSelection" size="small" @change="handleCheckTagChange"> <el-checkbox-group v-model="multipleSelection" size="small" @change="handleCheckTagChange">
<el-checkbox v-for="tag in tags" :key="tag.id" class="tag-checkbox" :label="tag.id" border> <span v-for="tag in tags"
{{tag.name}} class="tag-checkbox"
</el-checkbox> :key="tag.id"
@mouseover.prevent="hoverEditId = tag.id"
@mouseleave.prevent="hoverEditId = ''">
<el-checkbox
:label="tag.id"
border
>
{{tag.name}}
<i
:style="{marginLeft: '-5px',visibility: hoverEditId === tag.id ? 'visible' : 'hidden'}"
class="el-tag__close el-icon-edit"
@click.prevent="handleEdit(tag.id)"
>
</i>
</el-checkbox>
</span>
</el-checkbox-group> </el-checkbox-group>
</div> </div>
</el-card> </el-card>
@ -50,7 +65,6 @@
<script> <script>
import tagApi from "@/api/tag"; import tagApi from "@/api/tag";
import categoryApi from "@/api/category";
import UploadImageInput from "@/components/input/UploadImageInput"; import UploadImageInput from "@/components/input/UploadImageInput";
export default { export default {
@ -62,6 +76,7 @@ export default {
dialogVisible: false, dialogVisible: false,
dialogTitle: '', dialogTitle: '',
tagUpdateLoading: false, tagUpdateLoading: false,
hoverEditId: '',
form: { form: {
name: '', name: '',
slug: '', slug: '',
@ -90,6 +105,9 @@ export default {
this.tags = res.data this.tags = res.data
}) })
}, },
mouseover(id) {
console.log(6789)
},
handleCheckTagChange(value) { handleCheckTagChange(value) {
let checkedCount = value.length; let checkedCount = value.length;
this.checkAll = checkedCount === this.tags.length; this.checkAll = checkedCount === this.tags.length;
@ -105,12 +123,16 @@ export default {
} }
this.isIndeterminate = false this.isIndeterminate = false
}, },
handleEdit() { handleEdit(id) {
let tagId = this.multipleSelection[0]
if(id){
tagId = id
}
this.editMove = 2 this.editMove = 2
this.dialogVisible = true this.dialogVisible = true
this.dialogTitle = '修改标签' this.dialogTitle = '修改标签'
tagApi.tagInfo({ tagApi.tagInfo({
tagId: this.multipleSelection[0] tagId: tagId
}).then(res => { }).then(res => {
this.form = res.data this.form = res.data
}) })
@ -220,6 +242,7 @@ export default {
line-height: 32px; line-height: 32px;
} }
/deep/ .tag-checkbox { /deep/ .tag-checkbox {
padding-left: 8px;
.el-checkbox__inner { .el-checkbox__inner {
display: none; display: none;
} }
@ -235,6 +258,8 @@ export default {
background-color: #f4f4f5; background-color: #f4f4f5;
border-color: #e9e9eb; border-color: #e9e9eb;
color: #909399; color: #909399;
font-weight: 400;
padding: 5px 5px 5px 10px;
} }
/deep/ .el-checkbox.is-bordered.is-checked { /deep/ .el-checkbox.is-bordered.is-checked {
background-color: #ecf5ff; background-color: #ecf5ff;