mirror of
https://github.com/fantastic-admin/basic.git
synced 2026-10-07 09:43:17 +08:00
采用script、template、style的顺序优化所有sfc文件
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
<script setup{{#if isGlobal}} name="{{ properCase name }}"{{/if}}>
|
||||
// const { proxy } = getCurrentInstance()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<!-- 内容区 -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup{{#if isGlobal}} name="{{ properCase name }}"{{/if}}>
|
||||
// const { proxy } = getCurrentInstance()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// scss
|
||||
</style>
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
<script setup name="{{ properCase componentName }}">
|
||||
// const { proxy } = getCurrentInstance()
|
||||
// const router = useRouter()
|
||||
// const route = useRoute()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<page-header title="{{ cname }}" />
|
||||
@@ -7,12 +13,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="{{ properCase componentName }}">
|
||||
// const { proxy } = getCurrentInstance()
|
||||
// const router = useRouter()
|
||||
// const route = useRoute()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// scss
|
||||
</style>
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
<template>
|
||||
<div>
|
||||
<slot v-if="check()" />
|
||||
<slot v-else name="no-auth" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="Auth">
|
||||
import { auth } from '@/util'
|
||||
|
||||
const props = defineProps({
|
||||
@@ -19,3 +12,10 @@ function check() {
|
||||
return auth(props.value)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<slot v-if="check()" />
|
||||
<slot v-else name="no-auth" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
<template>
|
||||
<div>
|
||||
<slot v-if="check()" />
|
||||
<slot v-else name="no-auth" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="AuthAll">
|
||||
import { authAll } from '@/util'
|
||||
|
||||
const props = defineProps({
|
||||
@@ -19,3 +12,10 @@ function check() {
|
||||
return authAll(props.value)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<slot v-if="check()" />
|
||||
<slot v-else name="no-auth" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,14 +1,4 @@
|
||||
<template>
|
||||
<div class="batch-action-bar">
|
||||
<el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" :disabled="!data.length">当页全选</el-checkbox>
|
||||
<div v-if="selectionData.length" class="tips">已选 {{ selectionData.length }} 项</div>
|
||||
<el-form :disabled="!selectionData.length">
|
||||
<slot />
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="BatchActionBar">
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Array,
|
||||
@@ -44,6 +34,16 @@ const isIndeterminate = computed(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="batch-action-bar">
|
||||
<el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" :disabled="!data.length">当页全选</el-checkbox>
|
||||
<div v-if="selectionData.length" class="tips">已选 {{ selectionData.length }} 项</div>
|
||||
<el-form :disabled="!selectionData.length">
|
||||
<slot />
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.batch-action-bar {
|
||||
display: flex;
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-cascader v-model="myValue" :options="data.options" :props="data.props" :size="size" :disabled="disabled" clearable filterable />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="CascaderArea">
|
||||
import area from '@/util/area'
|
||||
|
||||
const props = defineProps({
|
||||
@@ -84,6 +78,12 @@ const myValue = computed({
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-cascader v-model="myValue" :options="data.options" :props="data.props" :size="size" :disabled="disabled" clearable filterable />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-cascader) {
|
||||
width: 100%;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
<script setup name="Copyright">
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<footer class="copyright">
|
||||
Copyright © {{ settingsStore.copyright.dates }}
|
||||
@@ -7,11 +12,6 @@
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
footer {
|
||||
margin: 40px 0 20px;
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
<template>
|
||||
<div class="editor">
|
||||
<TinymceEditor v-model="myValue" :init="completeSetting" :disabled="disabled" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="Editor">
|
||||
import tinymce from 'tinymce/tinymce'
|
||||
import TinymceEditor from '@tinymce/tinymce-vue'
|
||||
import 'tinymce/themes/silver/theme'
|
||||
@@ -88,6 +82,12 @@ onMounted(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="editor">
|
||||
<TinymceEditor v-model="myValue" :init="completeSetting" :disabled="disabled" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.tox-tinymce) {
|
||||
border: 1px solid #dcdfe6;
|
||||
|
||||
@@ -1,30 +1,4 @@
|
||||
<template>
|
||||
<el-upload
|
||||
:action="action"
|
||||
:data="data"
|
||||
:name="name"
|
||||
:before-upload="beforeUpload"
|
||||
:on-exceed="onExceed"
|
||||
:on-success="onSuccess"
|
||||
:file-list="files"
|
||||
:limit="max"
|
||||
drag
|
||||
>
|
||||
<div class="slot">
|
||||
<el-icon class="el-icon--upload"><el-icon-upload-filled /></el-icon>
|
||||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||
</div>
|
||||
<template #tip>
|
||||
<div v-if="!notip" class="el-upload__tip">
|
||||
<div style="display: inline-block;">
|
||||
<el-alert :title="`上传文件支持 ${ ext.join(' / ') } 格式,单个文件大小不超过 ${ size }MB,且文件数量不超过 ${ max } 个`" type="info" show-icon :closable="false" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="FileUpload">
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const props = defineProps({
|
||||
@@ -89,6 +63,32 @@ function onSuccess(res, file) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-upload
|
||||
:action="action"
|
||||
:data="data"
|
||||
:name="name"
|
||||
:before-upload="beforeUpload"
|
||||
:on-exceed="onExceed"
|
||||
:on-success="onSuccess"
|
||||
:file-list="files"
|
||||
:limit="max"
|
||||
drag
|
||||
>
|
||||
<div class="slot">
|
||||
<el-icon class="el-icon--upload"><el-icon-upload-filled /></el-icon>
|
||||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||
</div>
|
||||
<template #tip>
|
||||
<div v-if="!notip" class="el-upload__tip">
|
||||
<div style="display: inline-block;">
|
||||
<el-alert :title="`上传文件支持 ${ ext.join(' / ') } 格式,单个文件大小不超过 ${ size }MB,且文件数量不超过 ${ max } 个`" type="info" show-icon :closable="false" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-upload-dragger) {
|
||||
width: auto;
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
<template>
|
||||
<div class="actionbar" :class="{'shadow': !data.isBottom}" data-fixed-calc-width>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="FixedActionBar">
|
||||
const data = ref({
|
||||
isBottom: true
|
||||
})
|
||||
@@ -34,6 +28,12 @@ function onScroll() {
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="actionbar" :class="{'shadow': !data.isBottom}" data-fixed-calc-width>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.actionbar {
|
||||
z-index: 4;
|
||||
|
||||
@@ -1,14 +1,4 @@
|
||||
<template>
|
||||
<el-image :src="src" fit="cover" :style="`width:${realWidth};height:${realHeight};`" :preview-src-list="[src]">
|
||||
<template #error>
|
||||
<div class="image-slot">
|
||||
<svg-icon name="image-load-fail" />
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="ImagePreview">
|
||||
const props = defineProps({
|
||||
src: {
|
||||
type: String,
|
||||
@@ -33,6 +23,16 @@ const realHeight = computed(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-image :src="src" fit="cover" :style="`width:${realWidth};height:${realHeight};`" :preview-src-list="[src]">
|
||||
<template #error>
|
||||
<div class="image-slot">
|
||||
<svg-icon name="image-load-fail" />
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.el-image {
|
||||
border-radius: 5px;
|
||||
|
||||
@@ -1,51 +1,4 @@
|
||||
<template>
|
||||
<div class="upload-container">
|
||||
<el-upload
|
||||
:show-file-list="false"
|
||||
:headers="headers"
|
||||
:action="action"
|
||||
:data="data"
|
||||
:name="name"
|
||||
:before-upload="beforeUpload"
|
||||
:on-progress="onProgress"
|
||||
:on-success="onSuccess"
|
||||
drag
|
||||
>
|
||||
<el-image v-if="url === ''" :src="url === '' ? placeholder : url" :style="`width:${width}px;height:${height}px;`" fit="fill">
|
||||
<template #error>
|
||||
<div class="image-slot">
|
||||
<svg-icon name="el-icon-plus" />
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
<div v-else class="image">
|
||||
<el-image :src="url" :style="`width:${width}px;height:${height}px;`" fit="fill" />
|
||||
<div class="mask">
|
||||
<div class="actions">
|
||||
<span title="预览" @click.stop="preview">
|
||||
<el-icon><el-icon-zoom-in /></el-icon>
|
||||
</span>
|
||||
<span title="移除" @click.stop="remove">
|
||||
<el-icon><el-icon-delete /></el-icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-show="url === '' && uploadData.progress.percent" class="progress" :style="`width:${width}px;height:${height}px;`">
|
||||
<el-image :src="uploadData.progress.preview" :style="`width:${width}px;height:${height}px;`" fit="fill" />
|
||||
<el-progress type="circle" :width="Math.min(width, height) * 0.8" :percentage="uploadData.progress.percent" />
|
||||
</div>
|
||||
</el-upload>
|
||||
<div v-if="!notip" class="el-upload__tip">
|
||||
<div style="display: inline-block;">
|
||||
<el-alert :title="`上传图片支持 ${ ext.join(' / ') } 格式,且图片大小不超过 ${ size }MB,建议图片尺寸为 ${width}*${height}`" type="info" show-icon :closable="false" />
|
||||
</div>
|
||||
</div>
|
||||
<el-image-viewer v-if="uploadData.imageViewerVisible" :url-list="[url]" @close="previewClose" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="ImageUpload">
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const props = defineProps({
|
||||
@@ -143,6 +96,53 @@ function onSuccess(res) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="upload-container">
|
||||
<el-upload
|
||||
:show-file-list="false"
|
||||
:headers="headers"
|
||||
:action="action"
|
||||
:data="data"
|
||||
:name="name"
|
||||
:before-upload="beforeUpload"
|
||||
:on-progress="onProgress"
|
||||
:on-success="onSuccess"
|
||||
drag
|
||||
>
|
||||
<el-image v-if="url === ''" :src="url === '' ? placeholder : url" :style="`width:${width}px;height:${height}px;`" fit="fill">
|
||||
<template #error>
|
||||
<div class="image-slot">
|
||||
<svg-icon name="el-icon-plus" />
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
<div v-else class="image">
|
||||
<el-image :src="url" :style="`width:${width}px;height:${height}px;`" fit="fill" />
|
||||
<div class="mask">
|
||||
<div class="actions">
|
||||
<span title="预览" @click.stop="preview">
|
||||
<el-icon><el-icon-zoom-in /></el-icon>
|
||||
</span>
|
||||
<span title="移除" @click.stop="remove">
|
||||
<el-icon><el-icon-delete /></el-icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-show="url === '' && uploadData.progress.percent" class="progress" :style="`width:${width}px;height:${height}px;`">
|
||||
<el-image :src="uploadData.progress.preview" :style="`width:${width}px;height:${height}px;`" fit="fill" />
|
||||
<el-progress type="circle" :width="Math.min(width, height) * 0.8" :percentage="uploadData.progress.percent" />
|
||||
</div>
|
||||
</el-upload>
|
||||
<div v-if="!notip" class="el-upload__tip">
|
||||
<div style="display: inline-block;">
|
||||
<el-alert :title="`上传图片支持 ${ ext.join(' / ') } 格式,且图片大小不超过 ${ size }MB,建议图片尺寸为 ${width}*${height}`" type="info" show-icon :closable="false" />
|
||||
</div>
|
||||
</div>
|
||||
<el-image-viewer v-if="uploadData.imageViewerVisible" :url-list="[url]" @close="previewClose" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.upload-container {
|
||||
line-height: initial;
|
||||
|
||||
@@ -1,55 +1,4 @@
|
||||
<template>
|
||||
<div class="upload-container">
|
||||
<div v-for="(item, index) in url" :key="index" class="images">
|
||||
<el-image v-if="index < max" :src="item" :style="`width:${width}px;height:${height}px;`" fit="cover" />
|
||||
<div class="mask">
|
||||
<div class="actions">
|
||||
<span title="预览" @click="preview(index)">
|
||||
<el-icon><el-icon-zoom-in /></el-icon>
|
||||
</span>
|
||||
<span title="移除" @click="remove(index)">
|
||||
<el-icon><el-icon-delete /></el-icon>
|
||||
</span>
|
||||
<span v-show="url.length > 1" title="左移" :class="{'disabled': index == 0}" @click="move(index, 'left')">
|
||||
<el-icon><el-icon-back /></el-icon>
|
||||
</span>
|
||||
<span v-show="url.length > 1" title="右移" :class="{'disabled': index == url.length - 1}" @click="move(index, 'right')">
|
||||
<el-icon><el-icon-right /></el-icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-upload
|
||||
v-show="url.length < max"
|
||||
:show-file-list="false"
|
||||
:headers="headers"
|
||||
:action="action"
|
||||
:data="data"
|
||||
:name="name"
|
||||
:before-upload="beforeUpload"
|
||||
:on-progress="onProgress"
|
||||
:on-success="onSuccess"
|
||||
drag
|
||||
class="images-upload"
|
||||
>
|
||||
<div class="image-slot" :style="`width:${width}px;height:${height}px;`">
|
||||
<svg-icon name="el-icon-plus" />
|
||||
</div>
|
||||
<div v-show="uploadData.progress.percent" class="progress" :style="`width:${width}px;height:${height}px;`">
|
||||
<el-image :src="uploadData.progress.preview" :style="`width:${width}px;height:${height}px;`" fit="fill" />
|
||||
<el-progress type="circle" :width="Math.min(width, height) * 0.8" :percentage="uploadData.progress.percent" />
|
||||
</div>
|
||||
</el-upload>
|
||||
<div v-if="!notip" class="el-upload__tip">
|
||||
<div style="display: inline-block;">
|
||||
<el-alert :title="`上传图片支持 ${ ext.join(' / ') } 格式,单张图片大小不超过 ${ size }MB,建议图片尺寸为 ${width}*${height},且图片数量不超过 ${ max } 张`" type="info" show-icon :closable="false" />
|
||||
</div>
|
||||
</div>
|
||||
<el-image-viewer v-if="uploadData.imageViewerVisible" :url-list="url" :initial-index="uploadData.dialogImageIndex" @close="previewClose" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="ImagesUpload">
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const props = defineProps({
|
||||
@@ -166,6 +115,57 @@ function onSuccess(res) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="upload-container">
|
||||
<div v-for="(item, index) in url" :key="index" class="images">
|
||||
<el-image v-if="index < max" :src="item" :style="`width:${width}px;height:${height}px;`" fit="cover" />
|
||||
<div class="mask">
|
||||
<div class="actions">
|
||||
<span title="预览" @click="preview(index)">
|
||||
<el-icon><el-icon-zoom-in /></el-icon>
|
||||
</span>
|
||||
<span title="移除" @click="remove(index)">
|
||||
<el-icon><el-icon-delete /></el-icon>
|
||||
</span>
|
||||
<span v-show="url.length > 1" title="左移" :class="{'disabled': index == 0}" @click="move(index, 'left')">
|
||||
<el-icon><el-icon-back /></el-icon>
|
||||
</span>
|
||||
<span v-show="url.length > 1" title="右移" :class="{'disabled': index == url.length - 1}" @click="move(index, 'right')">
|
||||
<el-icon><el-icon-right /></el-icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-upload
|
||||
v-show="url.length < max"
|
||||
:show-file-list="false"
|
||||
:headers="headers"
|
||||
:action="action"
|
||||
:data="data"
|
||||
:name="name"
|
||||
:before-upload="beforeUpload"
|
||||
:on-progress="onProgress"
|
||||
:on-success="onSuccess"
|
||||
drag
|
||||
class="images-upload"
|
||||
>
|
||||
<div class="image-slot" :style="`width:${width}px;height:${height}px;`">
|
||||
<svg-icon name="el-icon-plus" />
|
||||
</div>
|
||||
<div v-show="uploadData.progress.percent" class="progress" :style="`width:${width}px;height:${height}px;`">
|
||||
<el-image :src="uploadData.progress.preview" :style="`width:${width}px;height:${height}px;`" fit="fill" />
|
||||
<el-progress type="circle" :width="Math.min(width, height) * 0.8" :percentage="uploadData.progress.percent" />
|
||||
</div>
|
||||
</el-upload>
|
||||
<div v-if="!notip" class="el-upload__tip">
|
||||
<div style="display: inline-block;">
|
||||
<el-alert :title="`上传图片支持 ${ ext.join(' / ') } 格式,单张图片大小不超过 ${ size }MB,建议图片尺寸为 ${width}*${height},且图片数量不超过 ${ max } 张`" type="info" show-icon :closable="false" />
|
||||
</div>
|
||||
</div>
|
||||
<el-image-viewer v-if="uploadData.imageViewerVisible" :url-list="url" :initial-index="uploadData.dialogImageIndex" @close="previewClose" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.upload-container {
|
||||
line-height: initial;
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
<script setup name="PageHeader">
|
||||
defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
content: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="header">
|
||||
<div class="main">
|
||||
@@ -12,19 +25,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
content: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.header {
|
||||
display: flex;
|
||||
|
||||
@@ -1,21 +1,4 @@
|
||||
<template>
|
||||
<div
|
||||
:class="{
|
||||
'page-main': true,
|
||||
'is-collaspe': collaspeData
|
||||
}" :style="{
|
||||
'height': collaspeData ? height : ''
|
||||
}"
|
||||
>
|
||||
<div v-if="title" class="title-container">{{ title }}</div>
|
||||
<slot />
|
||||
<div v-if="collaspeData" class="collaspe" title="展开" @click="unCollaspe">
|
||||
<el-icon><el-icon-arrow-down /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="PageMain">
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
@@ -38,6 +21,23 @@ function unCollaspe() {
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
:class="{
|
||||
'page-main': true,
|
||||
'is-collaspe': collaspeData
|
||||
}" :style="{
|
||||
'height': collaspeData ? height : ''
|
||||
}"
|
||||
>
|
||||
<div v-if="title" class="title-container">{{ title }}</div>
|
||||
<slot />
|
||||
<div v-if="collaspeData" class="collaspe" title="展开" @click="unCollaspe">
|
||||
<el-icon><el-icon-arrow-down /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-main {
|
||||
position: relative;
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
<script setup name="Result">
|
||||
defineProps({
|
||||
type: {
|
||||
type: String,
|
||||
validator: val => ['success', 'warning', 'error'].includes(val),
|
||||
required: true
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
desc: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="result">
|
||||
<div v-if="type === 'success'" class="icon icon-success">
|
||||
@@ -20,24 +38,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
type: {
|
||||
type: String,
|
||||
validator: val => ['success', 'warning', 'error'].includes(val),
|
||||
required: true
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
desc: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$success: #67c23a;
|
||||
$warning: #e6a23c;
|
||||
|
||||
@@ -1,13 +1,4 @@
|
||||
<template>
|
||||
<div class="search-container">
|
||||
<slot />
|
||||
<div v-if="showMore" class="more">
|
||||
<el-button type="text" size="small" :icon="isUnfold ? 'el-icon-caret-top' : 'el-icon-caret-bottom'" @click="toggle">{{ isUnfold ? '收起' : '展开' }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="SearchBar">
|
||||
const props = defineProps({
|
||||
showMore: {
|
||||
type: Boolean,
|
||||
@@ -33,6 +24,15 @@ function toggle() {
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="search-container">
|
||||
<slot />
|
||||
<div v-if="showMore" class="more">
|
||||
<el-button type="text" size="small" :icon="isUnfold ? 'el-icon-caret-top' : 'el-icon-caret-bottom'" @click="toggle">{{ isUnfold ? '收起' : '展开' }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.search-container {
|
||||
position: relative;
|
||||
|
||||
@@ -1,13 +1,4 @@
|
||||
<template>
|
||||
<el-icon v-if="name.indexOf('el-icon-') === 0 || name.indexOf('ElIcon') === 0" class="svg-icon" :style="transformStyle">
|
||||
<Component :is="name" />
|
||||
</el-icon>
|
||||
<svg v-else class="svg-icon" :style="transformStyle" aria-hidden="true">
|
||||
<use :xlink:href="`#icon-${name}`" />
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="SvgIcon">
|
||||
const props = defineProps({
|
||||
name: {
|
||||
type: String,
|
||||
@@ -52,12 +43,21 @@ const transformStyle = computed(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-icon v-if="name.indexOf('el-icon-') === 0 || name.indexOf('ElIcon') === 0" class="svg-icon" :style="transformStyle">
|
||||
<Component :is="name" />
|
||||
</el-icon>
|
||||
<svg v-else class="svg-icon" :style="transformStyle" aria-hidden="true">
|
||||
<use :xlink:href="`#icon-${name}`" />
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.svg-icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: -0.15em;
|
||||
fill: currentColor;
|
||||
fill: currentcolor;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
<template>
|
||||
<div class="adaption-container">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="TableHeightAdaption">
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
@@ -18,6 +12,12 @@ onMounted(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="adaption-container">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.adaption-container {
|
||||
height: 100%;
|
||||
|
||||
@@ -1,13 +1,4 @@
|
||||
<template>
|
||||
<div :class="`trend ${isUp ? 'up' : 'down'}`">
|
||||
<span v-if="prefix" class="prefix">{{ prefix }}</span>
|
||||
<span class="text">{{ value }}</span>
|
||||
<span v-if="suffix" class="suffix">{{ suffix }}</span>
|
||||
<svg-icon :name="`${isUp ? 'el-icon-caret-top' : 'el-icon-caret-bottom'}`" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="Trend">
|
||||
const props = defineProps({
|
||||
value: {
|
||||
type: String,
|
||||
@@ -41,6 +32,15 @@ const isUp = computed(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="`trend ${isUp ? 'up' : 'down'}`">
|
||||
<span v-if="prefix" class="prefix">{{ prefix }}</span>
|
||||
<span class="text">{{ value }}</span>
|
||||
<span v-if="suffix" class="suffix">{{ suffix }}</span>
|
||||
<svg-icon :name="`${isUp ? 'el-icon-caret-top' : 'el-icon-caret-bottom'}`" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.trend {
|
||||
display: inline-block;
|
||||
|
||||
@@ -1,3 +1,45 @@
|
||||
<script setup name="AppSetting">
|
||||
const { proxy } = getCurrentInstance()
|
||||
const route = useRoute()
|
||||
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
import { useMenuStore } from '@/store/modules/menu'
|
||||
const menuStore = useMenuStore()
|
||||
|
||||
const isShow = ref(false)
|
||||
|
||||
import globalSettings from '@/settings'
|
||||
const settings = ref(globalSettings)
|
||||
|
||||
watch(() => settings, () => {
|
||||
settingsStore.updateThemeSetting(settings.value)
|
||||
menuStore.setActived(0)
|
||||
settings.value.menu.menuMode !== 'single' && menuStore.setActived(route.fullPath)
|
||||
}, {
|
||||
deep: true
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
proxy.$eventBus.on('global-theme-toggle', () => {
|
||||
isShow.value = !isShow.value
|
||||
})
|
||||
})
|
||||
|
||||
import { useClipboard } from '@vueuse/core'
|
||||
const { copy, copied, isSupported } = useClipboard()
|
||||
|
||||
watch(copied, val => {
|
||||
if (val) {
|
||||
proxy.$message.success('复制成功,请粘贴到 src/settings.custom.json 文件中!')
|
||||
}
|
||||
})
|
||||
|
||||
function handleCopy() {
|
||||
copy(JSON.stringify(settings.value, null, 4))
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-drawer v-model="isShow" title="应用配置" direction="rtl" :size="350" custom-class="flex-container">
|
||||
@@ -163,48 +205,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const { proxy } = getCurrentInstance()
|
||||
const route = useRoute()
|
||||
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
import { useMenuStore } from '@/store/modules/menu'
|
||||
const menuStore = useMenuStore()
|
||||
|
||||
const isShow = ref(false)
|
||||
|
||||
import globalSettings from '@/settings'
|
||||
const settings = ref(globalSettings)
|
||||
|
||||
watch(() => settings, () => {
|
||||
settingsStore.updateThemeSetting(settings.value)
|
||||
menuStore.setActived(0)
|
||||
settings.value.menu.menuMode !== 'single' && menuStore.setActived(route.fullPath)
|
||||
}, {
|
||||
deep: true
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
proxy.$eventBus.on('global-theme-toggle', () => {
|
||||
isShow.value = !isShow.value
|
||||
})
|
||||
})
|
||||
|
||||
import { useClipboard } from '@vueuse/core'
|
||||
const { copy, copied, isSupported } = useClipboard()
|
||||
|
||||
watch(copied, val => {
|
||||
if (val) {
|
||||
proxy.$message.success('复制成功,请粘贴到 src/settings.custom.json 文件中!')
|
||||
}
|
||||
})
|
||||
|
||||
function handleCopy() {
|
||||
copy(JSON.stringify(settings.value, null, 4))
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-drawer__body) {
|
||||
display: flex;
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
<script setup name="Header">
|
||||
import Logo from '../Logo/index.vue'
|
||||
import Tools from '../Tools/index.vue'
|
||||
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
import { useMenuStore } from '@/store/modules/menu'
|
||||
const menuStore = useMenuStore()
|
||||
|
||||
const switchMenu = inject('switchMenu')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<transition name="header">
|
||||
<header v-if="settingsStore.mode === 'pc' && settingsStore.menu.menuMode === 'head'">
|
||||
@@ -20,18 +32,6 @@
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Logo from '../Logo/index.vue'
|
||||
import Tools from '../Tools/index.vue'
|
||||
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
import { useMenuStore } from '@/store/modules/menu'
|
||||
const menuStore = useMenuStore()
|
||||
|
||||
const switchMenu = inject('switchMenu')
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 头部动画
|
||||
.header-enter-active {
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
<template>
|
||||
<router-link :to="to" class="title" :class="{'is-link': settingsStore.dashboard.enable}" :title="title">
|
||||
<img v-if="showLogo" :src="logo" class="logo">
|
||||
<span v-if="showTitle">{{ title }}</span>
|
||||
</router-link>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="Logo">
|
||||
import imgLogo from '@/assets/images/logo.png'
|
||||
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
@@ -34,6 +27,13 @@ const to = computed(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<router-link :to="to" class="title" :class="{'is-link': settingsStore.dashboard.enable}" :title="title">
|
||||
<img v-if="showLogo" :src="logo" class="logo">
|
||||
<span v-if="showTitle">{{ title }}</span>
|
||||
</router-link>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.title {
|
||||
position: fixed;
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
<script setup name="MainSidebar">
|
||||
import Logo from '../Logo/index.vue'
|
||||
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
import { useMenuStore } from '@/store/modules/menu'
|
||||
const menuStore = useMenuStore()
|
||||
|
||||
const switchMenu = inject('switchMenu')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<transition name="main-sidebar">
|
||||
<div v-if="settingsStore.menu.menuMode === 'side' || (settingsStore.mode === 'mobile' && settingsStore.menu.menuMode !== 'single')" class="main-sidebar-container">
|
||||
@@ -20,17 +31,6 @@
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Logo from '../Logo/index.vue'
|
||||
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
import { useMenuStore } from '@/store/modules/menu'
|
||||
const menuStore = useMenuStore()
|
||||
|
||||
const switchMenu = inject('switchMenu')
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 主侧边栏动画
|
||||
.main-sidebar-enter-active {
|
||||
|
||||
@@ -1,57 +1,4 @@
|
||||
<template>
|
||||
<teleport to="#app">
|
||||
<div id="search" :class="{'searching': isShow}" @click="isShow && $eventBus.emit('global-search-toggle')">
|
||||
<div class="container">
|
||||
<div class="search-box" @click.stop>
|
||||
<el-input ref="input" v-model="searchInput" prefix-icon="el-icon-search" placeholder="搜索页面,支持标题、URL模糊查询" clearable @keydown.esc="$eventBus.emit('global-search-toggle')" @keydown.up.prevent="keyUp" @keydown.down.prevent="keyDown" @keydown.enter.prevent="keyEnter" />
|
||||
<div v-if="settingsStore.mode === 'pc'" class="tips">
|
||||
<div class="tip">
|
||||
<span>Alt</span>+<span>S</span>
|
||||
唤醒搜索面板
|
||||
</div>
|
||||
<div class="tip">
|
||||
<span><svg-icon name="search-up" /></span>
|
||||
<span><svg-icon name="search-down" /></span>
|
||||
切换搜索结果
|
||||
</div>
|
||||
<div class="tip">
|
||||
<span><svg-icon name="search-enter" /></span>
|
||||
访问页面
|
||||
</div>
|
||||
<div class="tip">
|
||||
<span>ESC</span>
|
||||
退出
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ref="search" class="result" :class="{'mobile': settingsStore.mode === 'mobile'}">
|
||||
<router-link v-for="(item, index) in resultList" :key="item.path" v-slot="{ href, navigate }" custom :to="isShow ? item.path : ''">
|
||||
<a :ref="`search-item-${index}`" :href="isExternalLink(item.path) ? item.path : href" class="item" :class="{'actived': index === actived}" :target="isExternalLink(item.path) ? '_blank' : '_self'" @click="navigate" @mouseover="actived = index">
|
||||
<div class="icon">
|
||||
<svg-icon v-if="item.icon" :name="item.icon" />
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="title">
|
||||
{{ item.title }}
|
||||
<svg-icon v-if="item.isExternalLink" name="external-link" />
|
||||
</div>
|
||||
<div class="breadcrumb">
|
||||
<span v-for="(bc, bcIndex) in item.breadcrumb" :key="bcIndex">
|
||||
{{ bc }}
|
||||
<svg-icon name="el-icon-arrow-right" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="path">{{ item.path }}</div>
|
||||
</div>
|
||||
</a>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</teleport>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="Search">
|
||||
import { deepClone, isExternalLink } from '@/util'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
@@ -212,6 +159,59 @@ function scrollTo(offsetTop) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<teleport to="#app">
|
||||
<div id="search" :class="{'searching': isShow}" @click="isShow && $eventBus.emit('global-search-toggle')">
|
||||
<div class="container">
|
||||
<div class="search-box" @click.stop>
|
||||
<el-input ref="input" v-model="searchInput" prefix-icon="el-icon-search" placeholder="搜索页面,支持标题、URL模糊查询" clearable @keydown.esc="$eventBus.emit('global-search-toggle')" @keydown.up.prevent="keyUp" @keydown.down.prevent="keyDown" @keydown.enter.prevent="keyEnter" />
|
||||
<div v-if="settingsStore.mode === 'pc'" class="tips">
|
||||
<div class="tip">
|
||||
<span>Alt</span>+<span>S</span>
|
||||
唤醒搜索面板
|
||||
</div>
|
||||
<div class="tip">
|
||||
<span><svg-icon name="search-up" /></span>
|
||||
<span><svg-icon name="search-down" /></span>
|
||||
切换搜索结果
|
||||
</div>
|
||||
<div class="tip">
|
||||
<span><svg-icon name="search-enter" /></span>
|
||||
访问页面
|
||||
</div>
|
||||
<div class="tip">
|
||||
<span>ESC</span>
|
||||
退出
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ref="search" class="result" :class="{'mobile': settingsStore.mode === 'mobile'}">
|
||||
<router-link v-for="(item, index) in resultList" :key="item.path" v-slot="{ href, navigate }" custom :to="isShow ? item.path : ''">
|
||||
<a :ref="`search-item-${index}`" :href="isExternalLink(item.path) ? item.path : href" class="item" :class="{'actived': index === actived}" :target="isExternalLink(item.path) ? '_blank' : '_self'" @click="navigate" @mouseover="actived = index">
|
||||
<div class="icon">
|
||||
<svg-icon v-if="item.icon" :name="item.icon" />
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="title">
|
||||
{{ item.title }}
|
||||
<svg-icon v-if="item.isExternalLink" name="external-link" />
|
||||
</div>
|
||||
<div class="breadcrumb">
|
||||
<span v-for="(bc, bcIndex) in item.breadcrumb" :key="bcIndex">
|
||||
{{ bc }}
|
||||
<svg-icon name="el-icon-arrow-right" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="path">{{ item.path }}</div>
|
||||
</div>
|
||||
</a>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</teleport>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
#search {
|
||||
position: fixed;
|
||||
|
||||
@@ -1,31 +1,4 @@
|
||||
<template>
|
||||
<div v-if="item.meta.sidebar !== false" class="sidebar-item">
|
||||
<el-sub-menu v-if="item.path == undefined" :title="item.meta.title" :index="JSON.stringify(item)">
|
||||
<template #title>
|
||||
<svg-icon v-if="item.meta.icon" :name="item.meta.icon" />
|
||||
<span class="title">{{ item.meta.title }}</span>
|
||||
</template>
|
||||
<SidebarItem v-for="route in item.children" :key="route.path" :item="route" />
|
||||
</el-sub-menu>
|
||||
<router-link v-else-if="!hasChildren" v-slot="{ href, navigate, isActive, isExactActive }" custom :to="resolveRoutePath(basePath, item.path)">
|
||||
<a :href="isExternalLink(resolveRoutePath(basePath, item.path)) ? resolveRoutePath(basePath, item.path) : href" :class="[isActive && 'router-link-active', isExactActive && 'router-link-exact-active']" :target="isExternalLink(resolveRoutePath(basePath, item.path)) ? '_blank' : '_self'" @click="navigate">
|
||||
<el-menu-item :title="item.meta.title" :index="resolveRoutePath(basePath, item.path)">
|
||||
<svg-icon v-if="item.meta.icon" :name="item.meta.icon" />
|
||||
<span class="title">{{ item.meta.title }}</span>
|
||||
</el-menu-item>
|
||||
</a>
|
||||
</router-link>
|
||||
<el-sub-menu v-else :title="item.meta.title" :index="resolveRoutePath(basePath, item.path)">
|
||||
<template #title>
|
||||
<svg-icon v-if="item.meta.icon" :name="item.meta.icon" />
|
||||
<span class="title">{{ item.meta.title }}</span>
|
||||
</template>
|
||||
<SidebarItem v-for="route in item.children" :key="route.path" :item="route" :base-path="resolveRoutePath(basePath, item.path)" />
|
||||
</el-sub-menu>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="SidebarItem">
|
||||
import SidebarItem from './index.vue'
|
||||
import { isExternalLink, resolveRoutePath } from '@/util'
|
||||
|
||||
@@ -53,6 +26,33 @@ const hasChildren = computed(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="item.meta.sidebar !== false" class="sidebar-item">
|
||||
<el-sub-menu v-if="item.path == undefined" :title="item.meta.title" :index="JSON.stringify(item)">
|
||||
<template #title>
|
||||
<svg-icon v-if="item.meta.icon" :name="item.meta.icon" />
|
||||
<span class="title">{{ item.meta.title }}</span>
|
||||
</template>
|
||||
<SidebarItem v-for="route in item.children" :key="route.path" :item="route" />
|
||||
</el-sub-menu>
|
||||
<router-link v-else-if="!hasChildren" v-slot="{ href, navigate, isActive, isExactActive }" custom :to="resolveRoutePath(basePath, item.path)">
|
||||
<a :href="isExternalLink(resolveRoutePath(basePath, item.path)) ? resolveRoutePath(basePath, item.path) : href" :class="[isActive && 'router-link-active', isExactActive && 'router-link-exact-active']" :target="isExternalLink(resolveRoutePath(basePath, item.path)) ? '_blank' : '_self'" @click="navigate">
|
||||
<el-menu-item :title="item.meta.title" :index="resolveRoutePath(basePath, item.path)">
|
||||
<svg-icon v-if="item.meta.icon" :name="item.meta.icon" />
|
||||
<span class="title">{{ item.meta.title }}</span>
|
||||
</el-menu-item>
|
||||
</a>
|
||||
</router-link>
|
||||
<el-sub-menu v-else :title="item.meta.title" :index="resolveRoutePath(basePath, item.path)">
|
||||
<template #title>
|
||||
<svg-icon v-if="item.meta.icon" :name="item.meta.icon" />
|
||||
<span class="title">{{ item.meta.title }}</span>
|
||||
</template>
|
||||
<SidebarItem v-for="route in item.children" :key="route.path" :item="route" :base-path="resolveRoutePath(basePath, item.path)" />
|
||||
</el-sub-menu>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-menu-item),
|
||||
:deep(.el-menu-item span.title),
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
<script setup name="SubSidebar">
|
||||
import Logo from '../Logo/index.vue'
|
||||
import SidebarItem from '../SidebarItem/index.vue'
|
||||
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
import { useMenuStore } from '@/store/modules/menu'
|
||||
const menuStore = useMenuStore()
|
||||
|
||||
const sidebarScrollTop = ref(0)
|
||||
|
||||
function onSidebarScroll(e) {
|
||||
sidebarScrollTop.value = e.target.scrollTop
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="['side', 'head', 'single'].includes(settingsStore.menu.menuMode) || settingsStore.mode === 'mobile'" class="sub-sidebar-container" :class="{'is-collapse': settingsStore.mode === 'pc' && settingsStore.menu.subMenuCollapse}" @scroll="onSidebarScroll">
|
||||
<Logo
|
||||
@@ -22,22 +38,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Logo from '../Logo/index.vue'
|
||||
import SidebarItem from '../SidebarItem/index.vue'
|
||||
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
import { useMenuStore } from '@/store/modules/menu'
|
||||
const menuStore = useMenuStore()
|
||||
|
||||
const sidebarScrollTop = ref(0)
|
||||
|
||||
function onSidebarScroll(e) {
|
||||
sidebarScrollTop.value = e.target.scrollTop
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 次侧边栏动画
|
||||
.sub-sidebar-enter-active {
|
||||
|
||||
@@ -1,3 +1,38 @@
|
||||
<script setup name="Tools">
|
||||
const reload = inject('reload')
|
||||
const router = useRouter()
|
||||
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
const userStore = useUserStore()
|
||||
|
||||
import { useFullscreen } from '@vueuse/core'
|
||||
const { isFullscreen, toggle } = useFullscreen()
|
||||
|
||||
function userCommand(command) {
|
||||
switch (command) {
|
||||
case 'dashboard':
|
||||
router.push({
|
||||
name: 'dashboard'
|
||||
})
|
||||
break
|
||||
case 'setting':
|
||||
router.push({
|
||||
name: 'personalSetting'
|
||||
})
|
||||
break
|
||||
case 'logout':
|
||||
userStore.logout().then(() => {
|
||||
router.push({
|
||||
name: 'login'
|
||||
})
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="tools">
|
||||
<div class="buttons">
|
||||
@@ -33,41 +68,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const reload = inject('reload')
|
||||
const router = useRouter()
|
||||
|
||||
import { useSettingsStore } from '@/store/modules/settings'
|
||||
const settingsStore = useSettingsStore()
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
const userStore = useUserStore()
|
||||
|
||||
import { useFullscreen } from '@vueuse/core'
|
||||
const { isFullscreen, toggle } = useFullscreen()
|
||||
|
||||
function userCommand(command) {
|
||||
switch (command) {
|
||||
case 'dashboard':
|
||||
router.push({
|
||||
name: 'dashboard'
|
||||
})
|
||||
break
|
||||
case 'setting':
|
||||
router.push({
|
||||
name: 'personalSetting'
|
||||
})
|
||||
break
|
||||
case 'logout':
|
||||
userStore.logout().then(() => {
|
||||
router.push({
|
||||
name: 'login'
|
||||
})
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tools {
|
||||
display: flex;
|
||||
|
||||
@@ -1,32 +1,4 @@
|
||||
<template>
|
||||
<div
|
||||
class="topbar-container" :class="{
|
||||
'fixed': settingsStore.topbar.fixed,
|
||||
'shadow': scrollTop
|
||||
}" data-fixed-calc-width
|
||||
>
|
||||
<div class="left-box">
|
||||
<div v-if="enableSidebarCollapse" class="sidebar-collapse" :class="{'is-collapse': settingsStore.menu.subMenuCollapse}" @click="settingsStore.toggleSidebarCollapse()">
|
||||
<svg-icon name="toolbar-collapse" />
|
||||
</div>
|
||||
<el-breadcrumb v-if="settingsStore.topbar.enableBreadcrumb && settingsStore.mode === 'pc'" separator-class="el-icon-arrow-right">
|
||||
<transition-group name="breadcrumb">
|
||||
<template v-for="(item, index) in breadcrumbList">
|
||||
<el-breadcrumb-item v-if="index < breadcrumbList.length - 1" :key="item.path" :to="pathCompile(item.path)">
|
||||
{{ item.title }}
|
||||
</el-breadcrumb-item>
|
||||
<el-breadcrumb-item v-else :key="item.path">
|
||||
{{ item.title }}
|
||||
</el-breadcrumb-item>
|
||||
</template>
|
||||
</transition-group>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<Tools />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="Topbar">
|
||||
import { compile } from 'path-to-regexp'
|
||||
import { deepClone } from '@/util'
|
||||
import Tools from '../Tools/index.vue'
|
||||
@@ -74,6 +46,34 @@ function pathCompile(path) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="topbar-container" :class="{
|
||||
'fixed': settingsStore.topbar.fixed,
|
||||
'shadow': scrollTop
|
||||
}" data-fixed-calc-width
|
||||
>
|
||||
<div class="left-box">
|
||||
<div v-if="enableSidebarCollapse" class="sidebar-collapse" :class="{'is-collapse': settingsStore.menu.subMenuCollapse}" @click="settingsStore.toggleSidebarCollapse()">
|
||||
<svg-icon name="toolbar-collapse" />
|
||||
</div>
|
||||
<el-breadcrumb v-if="settingsStore.topbar.enableBreadcrumb && settingsStore.mode === 'pc'" separator-class="el-icon-arrow-right">
|
||||
<transition-group name="breadcrumb">
|
||||
<template v-for="(item, index) in breadcrumbList">
|
||||
<el-breadcrumb-item v-if="index < breadcrumbList.length - 1" :key="item.path" :to="pathCompile(item.path)">
|
||||
{{ item.title }}
|
||||
</el-breadcrumb-item>
|
||||
<el-breadcrumb-item v-else :key="item.path">
|
||||
{{ item.title }}
|
||||
</el-breadcrumb-item>
|
||||
</template>
|
||||
</transition-group>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<Tools />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.topbar-container {
|
||||
position: absolute;
|
||||
|
||||
+33
-33
@@ -1,36 +1,4 @@
|
||||
<template>
|
||||
<div class="layout">
|
||||
<div id="app-main">
|
||||
<Header />
|
||||
<div class="wrapper">
|
||||
<div class="sidebar-container" :class="{'show': settingsStore.mode === 'mobile' && !settingsStore.menu.subMenuCollapse}">
|
||||
<MainSidebar />
|
||||
<SubSidebar />
|
||||
</div>
|
||||
<div class="sidebar-mask" :class="{'show': settingsStore.mode === 'mobile' && !settingsStore.menu.subMenuCollapse}" @click="settingsStore.toggleSidebarCollapse()" />
|
||||
<div class="main-container" :style="{'padding-bottom': $route.meta.paddingBottom}">
|
||||
<Topbar v-if="!(settingsStore.menu.menuMode === 'head' && !settingsStore.topbar.enableSidebarCollapse && !settingsStore.topbar.enableBreadcrumb)" />
|
||||
<div class="main">
|
||||
<router-view v-slot="{ Component, route }">
|
||||
<transition name="main" mode="out-in" appear>
|
||||
<!-- BUG https://github.com/vuejs/vue-next/issues/4984 -->
|
||||
<keep-alive :include="[...keepAliveStore.list]">
|
||||
<component :is="Component" :key="route.fullPath" />
|
||||
</keep-alive>
|
||||
</transition>
|
||||
</router-view>
|
||||
</div>
|
||||
<Copyright v-if="showCopyright" />
|
||||
</div>
|
||||
</div>
|
||||
<el-backtop :right="20" :bottom="20" title="回到顶部" />
|
||||
</div>
|
||||
<Search />
|
||||
<AppSetting />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup name="Layout">
|
||||
import Header from './components/Header/index.vue'
|
||||
import MainSidebar from './components/MainSidebar/index.vue'
|
||||
import SubSidebar from './components/SubSidebar/index.vue'
|
||||
@@ -99,6 +67,38 @@ function switchMenu(index) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="layout">
|
||||
<div id="app-main">
|
||||
<Header />
|
||||
<div class="wrapper">
|
||||
<div class="sidebar-container" :class="{'show': settingsStore.mode === 'mobile' && !settingsStore.menu.subMenuCollapse}">
|
||||
<MainSidebar />
|
||||
<SubSidebar />
|
||||
</div>
|
||||
<div class="sidebar-mask" :class="{'show': settingsStore.mode === 'mobile' && !settingsStore.menu.subMenuCollapse}" @click="settingsStore.toggleSidebarCollapse()" />
|
||||
<div class="main-container" :style="{'padding-bottom': $route.meta.paddingBottom}">
|
||||
<Topbar v-if="!(settingsStore.menu.menuMode === 'head' && !settingsStore.topbar.enableSidebarCollapse && !settingsStore.topbar.enableBreadcrumb)" />
|
||||
<div class="main">
|
||||
<router-view v-slot="{ Component, route }">
|
||||
<transition name="main" mode="out-in" appear>
|
||||
<!-- BUG https://github.com/vuejs/vue-next/issues/4984 -->
|
||||
<keep-alive :include="[...keepAliveStore.list]">
|
||||
<component :is="Component" :key="route.fullPath" />
|
||||
</keep-alive>
|
||||
</transition>
|
||||
</router-view>
|
||||
</div>
|
||||
<Copyright v-if="showCopyright" />
|
||||
</div>
|
||||
</div>
|
||||
<el-backtop :right="20" :bottom="20" title="回到顶部" />
|
||||
</div>
|
||||
<Search />
|
||||
<AppSetting />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
[data-mode="mobile"] {
|
||||
.sidebar-container {
|
||||
|
||||
+11
-11
@@ -1,14 +1,3 @@
|
||||
<template>
|
||||
<div class="notfound">
|
||||
<svg-icon name="404" />
|
||||
<div class="content">
|
||||
<h1>404</h1>
|
||||
<div class="desc">抱歉,你访问的页面不存在</div>
|
||||
<el-button type="primary" @click="goBack">{{ data.countdown }} 秒后,返回首页</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onBeforeRouteLeave } from 'vue-router'
|
||||
const router = useRouter()
|
||||
@@ -37,6 +26,17 @@ function goBack() {
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="notfound">
|
||||
<svg-icon name="404" />
|
||||
<div class="content">
|
||||
<h1>404</h1>
|
||||
<div class="desc">抱歉,你访问的页面不存在</div>
|
||||
<el-button type="primary" @click="goBack">{{ data.countdown }} 秒后,返回首页</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.notfound {
|
||||
display: flex;
|
||||
|
||||
+86
-86
@@ -1,89 +1,3 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="bg-banner" />
|
||||
<div id="login-box">
|
||||
<div class="login-banner" />
|
||||
<el-form v-show="formType == 'login'" ref="loginFormRef" :model="loginForm" :rules="loginRules" class="login-form" autocomplete="on" label-position="left">
|
||||
<div class="title-container">
|
||||
<h3 class="title">{{ title }}管理后台</h3>
|
||||
</div>
|
||||
<div>
|
||||
<el-form-item prop="account">
|
||||
<el-input ref="name" v-model="loginForm.account" placeholder="用户名" type="text" tabindex="1" autocomplete="on">
|
||||
<template #prefix>
|
||||
<svg-icon name="user" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input ref="password" v-model="loginForm.password" :type="passwordType" placeholder="密码" tabindex="2" autocomplete="on" @keyup.enter="handleLogin">
|
||||
<template #prefix>
|
||||
<svg-icon name="password" />
|
||||
</template>
|
||||
<template #suffix>
|
||||
<svg-icon :name="passwordType === 'password' ? 'eye' : 'eye-open'" @click="showPassword" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="flex-bar">
|
||||
<el-checkbox v-model="loginForm.remember">记住我</el-checkbox>
|
||||
<el-button type="text" @click="formType = 'reset'">忘记密码</el-button>
|
||||
</div>
|
||||
<el-button :loading="loading" type="primary" size="large" style="width: 100%;" @click.prevent="handleLogin">登 录</el-button>
|
||||
<div style="margin-top: 20px; margin-bottom: -10px; color: #666; font-size: 14px; text-align: center; font-weight: bold;">
|
||||
<span style="margin-right: 5px;">演示帐号一键登录:</span>
|
||||
<el-button type="danger" size="small" @click="testAccount('admin')">admin</el-button>
|
||||
<el-button type="danger" size="small" plain @click="testAccount('test')">test</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
<el-form v-show="formType == 'reset'" ref="resetFormRef" :model="resetForm" :rules="resetRules" class="login-form" auto-complete="on" label-position="left">
|
||||
<div class="title-container">
|
||||
<h3 class="title">重置密码</h3>
|
||||
</div>
|
||||
<div>
|
||||
<el-form-item prop="account">
|
||||
<el-input ref="name" v-model="resetForm.account" placeholder="用户名" type="text" tabindex="1" autocomplete="on">
|
||||
<template #prefix>
|
||||
<svg-icon name="user" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="captcha">
|
||||
<el-input ref="captcha" v-model="resetForm.captcha" placeholder="验证码" type="text" tabindex="2" autocomplete="on">
|
||||
<template #prefix>
|
||||
<svg-icon name="captcha" />
|
||||
</template>
|
||||
<template #append>
|
||||
<el-button>发送验证码</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="newPassword">
|
||||
<el-input ref="newPassword" v-model="resetForm.newPassword" :type="passwordType" placeholder="新密码" tabindex="3" autocomplete="on">
|
||||
<template #prefix>
|
||||
<svg-icon name="password" />
|
||||
</template>
|
||||
<template #suffix>
|
||||
<svg-icon :name="passwordType === 'password' ? 'eye' : 'eye-open'" @click="showPassword" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<el-row :gutter="15" style="padding-top: 20px;">
|
||||
<el-col :md="6">
|
||||
<el-button size="large" style="width: 100%;" @click="formType = 'login'">去登录</el-button>
|
||||
</el-col>
|
||||
<el-col :md="18">
|
||||
<el-button :loading="loading" type="primary" size="large" style="width: 100%;" @click.prevent="handleFind">确 认</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
<Copyright v-if="settingsStore.copyright.enable" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="Login">
|
||||
const { proxy } = getCurrentInstance()
|
||||
const route = useRoute(), router = useRouter()
|
||||
@@ -184,6 +98,92 @@ function testAccount(account) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="bg-banner" />
|
||||
<div id="login-box">
|
||||
<div class="login-banner" />
|
||||
<el-form v-show="formType == 'login'" ref="loginFormRef" :model="loginForm" :rules="loginRules" class="login-form" autocomplete="on" label-position="left">
|
||||
<div class="title-container">
|
||||
<h3 class="title">{{ title }}管理后台</h3>
|
||||
</div>
|
||||
<div>
|
||||
<el-form-item prop="account">
|
||||
<el-input ref="name" v-model="loginForm.account" placeholder="用户名" type="text" tabindex="1" autocomplete="on">
|
||||
<template #prefix>
|
||||
<svg-icon name="user" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input ref="password" v-model="loginForm.password" :type="passwordType" placeholder="密码" tabindex="2" autocomplete="on" @keyup.enter="handleLogin">
|
||||
<template #prefix>
|
||||
<svg-icon name="password" />
|
||||
</template>
|
||||
<template #suffix>
|
||||
<svg-icon :name="passwordType === 'password' ? 'eye' : 'eye-open'" @click="showPassword" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="flex-bar">
|
||||
<el-checkbox v-model="loginForm.remember">记住我</el-checkbox>
|
||||
<el-button type="text" @click="formType = 'reset'">忘记密码</el-button>
|
||||
</div>
|
||||
<el-button :loading="loading" type="primary" size="large" style="width: 100%;" @click.prevent="handleLogin">登 录</el-button>
|
||||
<div style="margin-top: 20px; margin-bottom: -10px; color: #666; font-size: 14px; text-align: center; font-weight: bold;">
|
||||
<span style="margin-right: 5px;">演示帐号一键登录:</span>
|
||||
<el-button type="danger" size="small" @click="testAccount('admin')">admin</el-button>
|
||||
<el-button type="danger" size="small" plain @click="testAccount('test')">test</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
<el-form v-show="formType == 'reset'" ref="resetFormRef" :model="resetForm" :rules="resetRules" class="login-form" auto-complete="on" label-position="left">
|
||||
<div class="title-container">
|
||||
<h3 class="title">重置密码</h3>
|
||||
</div>
|
||||
<div>
|
||||
<el-form-item prop="account">
|
||||
<el-input ref="name" v-model="resetForm.account" placeholder="用户名" type="text" tabindex="1" autocomplete="on">
|
||||
<template #prefix>
|
||||
<svg-icon name="user" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="captcha">
|
||||
<el-input ref="captcha" v-model="resetForm.captcha" placeholder="验证码" type="text" tabindex="2" autocomplete="on">
|
||||
<template #prefix>
|
||||
<svg-icon name="captcha" />
|
||||
</template>
|
||||
<template #append>
|
||||
<el-button>发送验证码</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="newPassword">
|
||||
<el-input ref="newPassword" v-model="resetForm.newPassword" :type="passwordType" placeholder="新密码" tabindex="3" autocomplete="on">
|
||||
<template #prefix>
|
||||
<svg-icon name="password" />
|
||||
</template>
|
||||
<template #suffix>
|
||||
<svg-icon :name="passwordType === 'password' ? 'eye' : 'eye-open'" @click="showPassword" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<el-row :gutter="15" style="padding-top: 20px;">
|
||||
<el-col :md="6">
|
||||
<el-button size="large" style="width: 100%;" @click="formType = 'login'">去登录</el-button>
|
||||
</el-col>
|
||||
<el-col :md="18">
|
||||
<el-button :loading="loading" type="primary" size="large" style="width: 100%;" @click.prevent="handleFind">确 认</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
<Copyright v-if="settingsStore.copyright.enable" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
[data-mode="mobile"] {
|
||||
#login-box {
|
||||
|
||||
@@ -1,29 +1,3 @@
|
||||
<template>
|
||||
<div>
|
||||
<page-header title="修改密码" content="定期修改密码可以提高帐号安全性噢~" />
|
||||
<page-main>
|
||||
<el-row>
|
||||
<el-col :md="24" :lg="12">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
|
||||
<el-form-item label="原密码" prop="password">
|
||||
<el-input v-model="form.password" type="password" placeholder="请输入原密码" />
|
||||
</el-form-item>
|
||||
<el-form-item label="新密码" prop="newpassword">
|
||||
<el-input v-model="form.newpassword" type="password" placeholder="请输入原密码" />
|
||||
</el-form-item>
|
||||
<el-form-item label="确认新密码" prop="checkpassword">
|
||||
<el-input v-model="form.checkpassword" type="password" placeholder="请输入原密码" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</page-main>
|
||||
<fixed-action-bar>
|
||||
<el-button type="primary" size="large" @click="onSubmit">提交</el-button>
|
||||
</fixed-action-bar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="PersonalEditPassword">
|
||||
const route = useRoute(), router = useRouter()
|
||||
const { proxy } = getCurrentInstance()
|
||||
@@ -80,3 +54,29 @@ function onSubmit() {
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<page-header title="修改密码" content="定期修改密码可以提高帐号安全性噢~" />
|
||||
<page-main>
|
||||
<el-row>
|
||||
<el-col :md="24" :lg="12">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
|
||||
<el-form-item label="原密码" prop="password">
|
||||
<el-input v-model="form.password" type="password" placeholder="请输入原密码" />
|
||||
</el-form-item>
|
||||
<el-form-item label="新密码" prop="newpassword">
|
||||
<el-input v-model="form.newpassword" type="password" placeholder="请输入原密码" />
|
||||
</el-form-item>
|
||||
<el-form-item label="确认新密码" prop="checkpassword">
|
||||
<el-input v-model="form.checkpassword" type="password" placeholder="请输入原密码" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</page-main>
|
||||
<fixed-action-bar>
|
||||
<el-button type="primary" size="large" @click="onSubmit">提交</el-button>
|
||||
</fixed-action-bar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,3 +1,29 @@
|
||||
<script setup name="PersonalSetting">
|
||||
const router = useRouter()
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const form = ref({
|
||||
headimg: '',
|
||||
mobile: '',
|
||||
name: '',
|
||||
qq: '',
|
||||
wechat: ''
|
||||
})
|
||||
|
||||
function handleSuccess(res) {
|
||||
if (res.error == '') {
|
||||
form.value.headimg = res.data.path
|
||||
} else {
|
||||
proxy.$message.warning(res.error)
|
||||
}
|
||||
}
|
||||
function editPassword() {
|
||||
router.push({
|
||||
name: 'personalEditPassword'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<!-- 页面:Setting -->
|
||||
@@ -67,32 +93,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="PersonalSetting">
|
||||
const router = useRouter()
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const form = ref({
|
||||
headimg: '',
|
||||
mobile: '',
|
||||
name: '',
|
||||
qq: '',
|
||||
wechat: ''
|
||||
})
|
||||
|
||||
function handleSuccess(res) {
|
||||
if (res.error == '') {
|
||||
form.value.headimg = res.data.path
|
||||
} else {
|
||||
proxy.$message.warning(res.error)
|
||||
}
|
||||
}
|
||||
function editPassword() {
|
||||
router.push({
|
||||
name: 'personalEditPassword'
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-tabs) {
|
||||
.el-tabs__header .el-tabs__nav {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<script setup>
|
||||
const router = useRouter()
|
||||
|
||||
onMounted(() => {
|
||||
router.go(-1)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
mounted() {
|
||||
this.$router.go(-1)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user