处理打包报错
BIN
src/assets/imgs/avatar.gif
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
BIN
src/assets/imgs/avatar.jpg
Normal file
|
After Width: | Height: | Size: 6.1 KiB |
BIN
src/assets/imgs/diy/app-nav-bar-mp.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
src/assets/imgs/diy/statusBar.png
Normal file
|
After Width: | Height: | Size: 8.7 KiB |
BIN
src/assets/imgs/logo.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
src/assets/imgs/profile.jpg
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
src/assets/imgs/wechat.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
3
src/components/Backtop/index.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import Backtop from './src/Backtop.vue'
|
||||||
|
|
||||||
|
export { Backtop }
|
||||||
17
src/components/Backtop/src/Backtop.vue
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { ElBacktop } from 'element-plus'
|
||||||
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
|
|
||||||
|
defineOptions({ name: 'BackTop' })
|
||||||
|
|
||||||
|
const { getPrefixCls, variables } = useDesign()
|
||||||
|
|
||||||
|
const prefixCls = getPrefixCls('backtop')
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ElBacktop
|
||||||
|
:class="`${prefixCls}-backtop`"
|
||||||
|
:target="`.${variables.namespace}-layout-content-scrollbar .${variables.elNamespace}-scrollbar__wrap`"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapState } from 'pinia'
|
import { mapState } from 'pinia'
|
||||||
import { globalStore } from '@/store'
|
import { globalStore } from '@/stores/indexs'
|
||||||
|
|
||||||
const FormContainerTypeEnum = {
|
const FormContainerTypeEnum = {
|
||||||
DRAWER: 'drawer',
|
DRAWER: 'drawer',
|
||||||
|
|||||||
4
src/components/icon/index.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import Icon from './src/Icon.vue'
|
||||||
|
import IconSelect from './src/IconSelect.vue'
|
||||||
|
|
||||||
|
export { Icon, IconSelect }
|
||||||
86
src/components/icon/src/Icon.vue
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { propTypes } from '@/utils/propTypes'
|
||||||
|
import Iconify from '@purge-icons/generated'
|
||||||
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
|
|
||||||
|
defineOptions({ name: 'Icon' })
|
||||||
|
|
||||||
|
const { getPrefixCls } = useDesign()
|
||||||
|
|
||||||
|
const prefixCls = getPrefixCls('icon')
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
// icon name
|
||||||
|
icon: propTypes.string,
|
||||||
|
// icon color
|
||||||
|
color: propTypes.string,
|
||||||
|
// icon size
|
||||||
|
size: propTypes.number.def(16),
|
||||||
|
// icon svg class
|
||||||
|
svgClass: propTypes.string.def('')
|
||||||
|
})
|
||||||
|
|
||||||
|
const elRef = ref<ElRef>(null)
|
||||||
|
|
||||||
|
const isLocal = computed(() => props.icon.startsWith('svg-icon:'))
|
||||||
|
|
||||||
|
const symbolId = computed(() => {
|
||||||
|
return unref(isLocal) ? `#icon-${props.icon.split('svg-icon:')[1]}` : props.icon
|
||||||
|
})
|
||||||
|
|
||||||
|
const getIconifyStyle = computed(() => {
|
||||||
|
const { color, size } = props
|
||||||
|
return {
|
||||||
|
fontSize: `${size}px`,
|
||||||
|
height: '1em',
|
||||||
|
color
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const getSvgClass = computed(() => {
|
||||||
|
const { svgClass } = props
|
||||||
|
return `iconify ${svgClass}`
|
||||||
|
})
|
||||||
|
|
||||||
|
const updateIcon = async (icon: string) => {
|
||||||
|
if (unref(isLocal)) return
|
||||||
|
|
||||||
|
const el = unref(elRef)
|
||||||
|
if (!el) return
|
||||||
|
|
||||||
|
await nextTick()
|
||||||
|
|
||||||
|
if (!icon) return
|
||||||
|
|
||||||
|
const svg = Iconify.renderSVG(icon, {})
|
||||||
|
if (svg) {
|
||||||
|
el.textContent = ''
|
||||||
|
el.appendChild(svg)
|
||||||
|
} else {
|
||||||
|
const span = document.createElement('span')
|
||||||
|
span.className = 'iconify'
|
||||||
|
span.dataset.icon = icon
|
||||||
|
el.textContent = ''
|
||||||
|
el.appendChild(span)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.icon,
|
||||||
|
(icon: string) => {
|
||||||
|
updateIcon(icon)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ElIcon :class="prefixCls" :color="color" :size="size">
|
||||||
|
<svg v-if="isLocal" :class="getSvgClass" aria-hidden="true">
|
||||||
|
<use :xlink:href="symbolId" />
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<span v-else ref="elRef" :class="$attrs.class" :style="getIconifyStyle">
|
||||||
|
<span :class="getSvgClass" :data-icon="symbolId"></span>
|
||||||
|
</span>
|
||||||
|
</ElIcon>
|
||||||
|
</template>
|
||||||
229
src/components/icon/src/IconSelect.vue
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { CSSProperties } from 'vue'
|
||||||
|
import { cloneDeep } from 'lodash-es'
|
||||||
|
import { IconJson } from '@/components/Icon/src/data'
|
||||||
|
|
||||||
|
defineOptions({ name: 'IconSelect' })
|
||||||
|
|
||||||
|
type ParameterCSSProperties = (item?: string) => CSSProperties | undefined
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
require: false,
|
||||||
|
type: String
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const emit = defineEmits<{ (e: 'update:modelValue', v: string) }>()
|
||||||
|
|
||||||
|
const visible = ref(false)
|
||||||
|
const inputValue = toRef(props, 'modelValue')
|
||||||
|
const iconList = ref(IconJson)
|
||||||
|
const icon = ref('add-location')
|
||||||
|
const currentActiveType = ref('ep:')
|
||||||
|
// 深拷贝图标数据,前端做搜索
|
||||||
|
const copyIconList = cloneDeep(iconList.value)
|
||||||
|
|
||||||
|
const pageSize = ref(96)
|
||||||
|
const currentPage = ref(1)
|
||||||
|
|
||||||
|
// 搜索条件
|
||||||
|
const filterValue = ref('')
|
||||||
|
|
||||||
|
const tabsList = [
|
||||||
|
{
|
||||||
|
label: 'Element Plus',
|
||||||
|
name: 'ep:'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Font Awesome 4',
|
||||||
|
name: 'fa:'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Font Awesome 5 Solid',
|
||||||
|
name: 'fa-solid:'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const pageList = computed(() => {
|
||||||
|
if (currentPage.value === 1) {
|
||||||
|
return copyIconList[currentActiveType.value]
|
||||||
|
?.filter((v) => v.includes(filterValue.value))
|
||||||
|
.slice(currentPage.value - 1, pageSize.value)
|
||||||
|
} else {
|
||||||
|
return copyIconList[currentActiveType.value]
|
||||||
|
?.filter((v) => v.includes(filterValue.value))
|
||||||
|
.slice(
|
||||||
|
pageSize.value * (currentPage.value - 1),
|
||||||
|
pageSize.value * (currentPage.value - 1) + pageSize.value
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const iconCount = computed(() => {
|
||||||
|
return copyIconList[currentActiveType.value] == undefined
|
||||||
|
? 0
|
||||||
|
: copyIconList[currentActiveType.value].length
|
||||||
|
})
|
||||||
|
|
||||||
|
const iconItemStyle = computed((): ParameterCSSProperties => {
|
||||||
|
return (item) => {
|
||||||
|
if (inputValue.value === currentActiveType.value + item) {
|
||||||
|
return {
|
||||||
|
borderColor: 'var(--el-color-primary)',
|
||||||
|
color: 'var(--el-color-primary)'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function handleClick({ props }) {
|
||||||
|
currentPage.value = 1
|
||||||
|
currentActiveType.value = props.name
|
||||||
|
emit('update:modelValue', currentActiveType.value + iconList.value[currentActiveType.value][0])
|
||||||
|
icon.value = iconList.value[currentActiveType.value][0]
|
||||||
|
}
|
||||||
|
|
||||||
|
function onChangeIcon(item) {
|
||||||
|
icon.value = item
|
||||||
|
emit('update:modelValue', currentActiveType.value + item)
|
||||||
|
visible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
function onCurrentChange(page) {
|
||||||
|
currentPage.value = page
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => {
|
||||||
|
return props.modelValue
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
if (props.modelValue && props.modelValue.indexOf(':') >= 0) {
|
||||||
|
currentActiveType.value = props.modelValue.substring(0, props.modelValue.indexOf(':') + 1)
|
||||||
|
icon.value = props.modelValue.substring(props.modelValue.indexOf(':') + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
watch(
|
||||||
|
() => {
|
||||||
|
return filterValue.value
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
currentPage.value = 1
|
||||||
|
}
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="selector">
|
||||||
|
<ElInput v-model="inputValue" @click="visible = !visible">
|
||||||
|
<template #append>
|
||||||
|
<ElPopover
|
||||||
|
:popper-options="{
|
||||||
|
placement: 'auto'
|
||||||
|
}"
|
||||||
|
:visible="visible"
|
||||||
|
:width="350"
|
||||||
|
popper-class="pure-popper"
|
||||||
|
trigger="click"
|
||||||
|
>
|
||||||
|
<template #reference>
|
||||||
|
<div
|
||||||
|
class="h-32px w-40px flex cursor-pointer items-center justify-center"
|
||||||
|
@click="visible = !visible"
|
||||||
|
>
|
||||||
|
<Icon :icon="currentActiveType + icon" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<ElInput v-model="filterValue" class="p-2" clearable placeholder="搜索图标" />
|
||||||
|
<ElDivider border-style="dashed" />
|
||||||
|
|
||||||
|
<ElTabs v-model="currentActiveType" @tab-click="handleClick">
|
||||||
|
<ElTabPane
|
||||||
|
v-for="(pane, index) in tabsList"
|
||||||
|
:key="index"
|
||||||
|
:label="pane.label"
|
||||||
|
:name="pane.name"
|
||||||
|
>
|
||||||
|
<ElDivider border-style="dashed" class="tab-divider" />
|
||||||
|
<ElScrollbar height="220px">
|
||||||
|
<ul class="ml-2 flex flex-wrap px-2">
|
||||||
|
<li
|
||||||
|
v-for="(item, key) in pageList"
|
||||||
|
:key="key"
|
||||||
|
:style="iconItemStyle(item)"
|
||||||
|
:title="item"
|
||||||
|
class="icon-item mr-2 mt-1 w-1/10 flex cursor-pointer items-center justify-center border border-solid p-2"
|
||||||
|
@click="onChangeIcon(item)"
|
||||||
|
>
|
||||||
|
<Icon :icon="currentActiveType + item" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</ElScrollbar>
|
||||||
|
</ElTabPane>
|
||||||
|
</ElTabs>
|
||||||
|
<ElDivider border-style="dashed" />
|
||||||
|
|
||||||
|
<ElPagination
|
||||||
|
:current-page="currentPage"
|
||||||
|
:page-size="pageSize"
|
||||||
|
:total="iconCount"
|
||||||
|
background
|
||||||
|
class="h-10 flex items-center justify-center"
|
||||||
|
layout="prev, pager, next"
|
||||||
|
small
|
||||||
|
@current-change="onCurrentChange"
|
||||||
|
/>
|
||||||
|
</ElPopover>
|
||||||
|
</template>
|
||||||
|
</ElInput>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.el-divider--horizontal {
|
||||||
|
margin: 1px auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-divider.el-divider--horizontal {
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-item {
|
||||||
|
&:hover {
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
border-color: var(--el-color-primary);
|
||||||
|
transform: scaleX(1.05);
|
||||||
|
transition: all 0.4s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tabs__nav-next) {
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 32px;
|
||||||
|
box-shadow: -5px 0 5px -6px #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tabs__nav-prev) {
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 32px;
|
||||||
|
box-shadow: 5px 0 5px -6px #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-input-group__append) {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tabs__item) {
|
||||||
|
height: 30px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tabs__header),
|
||||||
|
:deep(.el-tabs__nav-wrap) {
|
||||||
|
position: static;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
1961
src/components/icon/src/data.ts
Normal file
60
src/hooks/event/useScrollTo.ts
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
export interface ScrollToParams {
|
||||||
|
el: HTMLElement
|
||||||
|
to: number
|
||||||
|
position: string
|
||||||
|
duration?: number
|
||||||
|
callback?: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const easeInOutQuad = (t: number, b: number, c: number, d: number) => {
|
||||||
|
t /= d / 2
|
||||||
|
if (t < 1) {
|
||||||
|
return (c / 2) * t * t + b
|
||||||
|
}
|
||||||
|
t--
|
||||||
|
return (-c / 2) * (t * (t - 2) - 1) + b
|
||||||
|
}
|
||||||
|
const move = (el: HTMLElement, position: string, amount: number) => {
|
||||||
|
el[position] = amount
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useScrollTo({
|
||||||
|
el,
|
||||||
|
position = 'scrollLeft',
|
||||||
|
to,
|
||||||
|
duration = 500,
|
||||||
|
callback
|
||||||
|
}: ScrollToParams) {
|
||||||
|
const isActiveRef = ref(false)
|
||||||
|
const start = el[position]
|
||||||
|
const change = to - start
|
||||||
|
const increment = 20
|
||||||
|
let currentTime = 0
|
||||||
|
|
||||||
|
function animateScroll() {
|
||||||
|
if (!unref(isActiveRef)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
currentTime += increment
|
||||||
|
const val = easeInOutQuad(currentTime, start, change, duration)
|
||||||
|
move(el, position, val)
|
||||||
|
if (currentTime < duration && unref(isActiveRef)) {
|
||||||
|
requestAnimationFrame(animateScroll)
|
||||||
|
} else {
|
||||||
|
if (callback) {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function run() {
|
||||||
|
isActiveRef.value = true
|
||||||
|
animateScroll()
|
||||||
|
}
|
||||||
|
|
||||||
|
function stop() {
|
||||||
|
isActiveRef.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
return { start: run, stop }
|
||||||
|
}
|
||||||
8
src/hooks/web/useIcon.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { h } from 'vue'
|
||||||
|
import type { VNode } from 'vue'
|
||||||
|
import { Icon } from '@/components/icon'
|
||||||
|
import { IconTypes } from '@/types/icon'
|
||||||
|
|
||||||
|
export const useIcon = (props: IconTypes): VNode => {
|
||||||
|
return h(Icon, props)
|
||||||
|
}
|
||||||
35
src/hooks/web/useLocale.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import { i18n } from '@/plugins/vueI18n'
|
||||||
|
import { useLocaleStoreWithOut } from '@/stores/modules/locale'
|
||||||
|
import { setHtmlPageLang } from '@/plugins/vueI18n/helper'
|
||||||
|
|
||||||
|
const setI18nLanguage = (locale: LocaleType) => {
|
||||||
|
const localeStore = useLocaleStoreWithOut()
|
||||||
|
|
||||||
|
if (i18n.mode === 'legacy') {
|
||||||
|
i18n.global.locale = locale
|
||||||
|
} else {
|
||||||
|
;(i18n.global.locale as any).value = locale
|
||||||
|
}
|
||||||
|
localeStore.setCurrentLocale({
|
||||||
|
lang: locale
|
||||||
|
})
|
||||||
|
setHtmlPageLang(locale)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useLocale = () => {
|
||||||
|
// Switching the language will change the locale of useI18n
|
||||||
|
// And submit to configuration modification
|
||||||
|
const changeLocale = async (locale: LocaleType) => {
|
||||||
|
const globalI18n = i18n.global
|
||||||
|
|
||||||
|
const langModule = await import(`../../locales/${locale}.ts`)
|
||||||
|
|
||||||
|
globalI18n.setLocaleMessage(locale, langModule.default)
|
||||||
|
|
||||||
|
setI18nLanguage(locale)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
changeLocale
|
||||||
|
}
|
||||||
|
}
|
||||||
60
src/hooks/web/useNow.ts
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import { dateUtil } from '@/utils/dateUtil'
|
||||||
|
import { reactive, toRefs } from 'vue'
|
||||||
|
import { tryOnMounted, tryOnUnmounted } from '@vueuse/core'
|
||||||
|
|
||||||
|
export const useNow = (immediate = true) => {
|
||||||
|
let timer: IntervalHandle
|
||||||
|
|
||||||
|
const state = reactive({
|
||||||
|
year: 0,
|
||||||
|
month: 0,
|
||||||
|
week: '',
|
||||||
|
day: 0,
|
||||||
|
hour: '',
|
||||||
|
minute: '',
|
||||||
|
second: 0,
|
||||||
|
meridiem: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const update = () => {
|
||||||
|
const now = dateUtil()
|
||||||
|
|
||||||
|
const h = now.format('HH')
|
||||||
|
const m = now.format('mm')
|
||||||
|
const s = now.get('s')
|
||||||
|
|
||||||
|
state.year = now.get('y')
|
||||||
|
state.month = now.get('M') + 1
|
||||||
|
state.week = '星期' + ['日', '一', '二', '三', '四', '五', '六'][now.day()]
|
||||||
|
state.day = now.get('date')
|
||||||
|
state.hour = h
|
||||||
|
state.minute = m
|
||||||
|
state.second = s
|
||||||
|
|
||||||
|
state.meridiem = now.format('A')
|
||||||
|
}
|
||||||
|
|
||||||
|
function start() {
|
||||||
|
update()
|
||||||
|
clearInterval(timer)
|
||||||
|
timer = setInterval(() => update(), 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
function stop() {
|
||||||
|
clearInterval(timer)
|
||||||
|
}
|
||||||
|
|
||||||
|
tryOnMounted(() => {
|
||||||
|
immediate && start()
|
||||||
|
})
|
||||||
|
|
||||||
|
tryOnUnmounted(() => {
|
||||||
|
stop()
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
...toRefs(state),
|
||||||
|
start,
|
||||||
|
stop
|
||||||
|
}
|
||||||
|
}
|
||||||
60
src/hooks/web/useValidator.ts
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
|
import { FormItemRule } from 'element-plus'
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
interface LengthRange {
|
||||||
|
min: number
|
||||||
|
max: number
|
||||||
|
message?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useValidator = () => {
|
||||||
|
const required = (message?: string): FormItemRule => {
|
||||||
|
return {
|
||||||
|
required: true,
|
||||||
|
message: message || t('common.required')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const lengthRange = (options: LengthRange): FormItemRule => {
|
||||||
|
const { min, max, message } = options
|
||||||
|
|
||||||
|
return {
|
||||||
|
min,
|
||||||
|
max,
|
||||||
|
message: message || t('common.lengthRange', { min, max })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const notSpace = (message?: string): FormItemRule => {
|
||||||
|
return {
|
||||||
|
validator: (_, val, callback) => {
|
||||||
|
if (val?.indexOf(' ') !== -1) {
|
||||||
|
callback(new Error(message || t('common.notSpace')))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const notSpecialCharacters = (message?: string): FormItemRule => {
|
||||||
|
return {
|
||||||
|
validator: (_, val, callback) => {
|
||||||
|
if (/[`~!@#$%^&*()_+<>?:"{},.\/;'[\]]/gi.test(val)) {
|
||||||
|
callback(new Error(message || t('common.notSpecialCharacters')))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
required,
|
||||||
|
lengthRange,
|
||||||
|
notSpace,
|
||||||
|
notSpecialCharacters
|
||||||
|
}
|
||||||
|
}
|
||||||
55
src/hooks/web/useWatermark.ts
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
const domSymbol = Symbol('watermark-dom')
|
||||||
|
|
||||||
|
export function useWatermark(appendEl: HTMLElement | null = document.body) {
|
||||||
|
let func: Fn = () => {}
|
||||||
|
const id = domSymbol.toString()
|
||||||
|
const clear = () => {
|
||||||
|
const domId = document.getElementById(id)
|
||||||
|
if (domId) {
|
||||||
|
const el = appendEl
|
||||||
|
el && el.removeChild(domId)
|
||||||
|
}
|
||||||
|
window.removeEventListener('resize', func)
|
||||||
|
}
|
||||||
|
const createWatermark = (str: string) => {
|
||||||
|
clear()
|
||||||
|
|
||||||
|
const can = document.createElement('canvas')
|
||||||
|
can.width = 300
|
||||||
|
can.height = 240
|
||||||
|
|
||||||
|
const cans = can.getContext('2d')
|
||||||
|
if (cans) {
|
||||||
|
cans.rotate((-20 * Math.PI) / 120)
|
||||||
|
cans.font = '15px Vedana'
|
||||||
|
cans.fillStyle = 'rgba(0, 0, 0, 0.15)'
|
||||||
|
cans.textAlign = 'left'
|
||||||
|
cans.textBaseline = 'middle'
|
||||||
|
cans.fillText(str, can.width / 20, can.height)
|
||||||
|
}
|
||||||
|
|
||||||
|
const div = document.createElement('div')
|
||||||
|
div.id = id
|
||||||
|
div.style.pointerEvents = 'none'
|
||||||
|
div.style.top = '0px'
|
||||||
|
div.style.left = '0px'
|
||||||
|
div.style.position = 'absolute'
|
||||||
|
div.style.zIndex = '100000000'
|
||||||
|
div.style.width = document.documentElement.clientWidth + 'px'
|
||||||
|
div.style.height = document.documentElement.clientHeight + 'px'
|
||||||
|
div.style.background = 'url(' + can.toDataURL('image/png') + ') left top repeat'
|
||||||
|
const el = appendEl
|
||||||
|
el && el.appendChild(div)
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
function setWatermark(str: string) {
|
||||||
|
createWatermark(str)
|
||||||
|
func = () => {
|
||||||
|
createWatermark(str)
|
||||||
|
}
|
||||||
|
window.addEventListener('resize', func)
|
||||||
|
}
|
||||||
|
|
||||||
|
return { setWatermark, clear }
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<script lang="tsx">
|
<script lang="tsx">
|
||||||
import { computed, defineComponent, unref } from 'vue'
|
import { computed, defineComponent, unref } from 'vue'
|
||||||
import { useAppStore } from '@/store/modules/app'
|
import { useAppStore } from '@/stores/modules/app'
|
||||||
import { Backtop } from '@/components/Backtop'
|
import { Backtop } from '@/components/Backtop'
|
||||||
import { Setting } from '@/layout/components/Setting'
|
import { Setting } from '@/layouts/components/Setting'
|
||||||
import { useRenderLayout } from './components/useRenderLayout'
|
import { useRenderLayout } from './components/useRenderLayout'
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useTagsViewStore } from '@/store/modules/tagsView'
|
import { useTagsViewStore } from '@/stores/modules/tagsView'
|
||||||
import { useAppStore } from '@/store/modules/app'
|
import { useAppStore } from '@/stores/modules/app'
|
||||||
import { Footer } from '@/layout/components/Footer'
|
import { Footer } from '@/layouts/components/Footer'
|
||||||
|
|
||||||
defineOptions({ name: 'AppView' })
|
defineOptions({ name: 'AppView' })
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
import { ElBreadcrumb, ElBreadcrumbItem } from 'element-plus'
|
import { ElBreadcrumb, ElBreadcrumbItem } from 'element-plus'
|
||||||
import { ref, watch, computed, unref, defineComponent, TransitionGroup } from 'vue'
|
import { ref, watch, computed, unref, defineComponent, TransitionGroup } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { usePermissionStore } from '@/store/modules/permission'
|
import { usePermissionStore } from '@/stores/modules/permission'
|
||||||
import { filterBreadcrumb } from './helper'
|
import { filterBreadcrumb } from './helper'
|
||||||
import { filter, treeToList } from '@/utils/tree'
|
import { filter, treeToList } from '@/utils/tree'
|
||||||
import type { RouteLocationNormalizedLoaded, RouteMeta } from 'vue-router'
|
import type { RouteLocationNormalizedLoaded, RouteMeta } from 'vue-router'
|
||||||
|
|
||||||
import { Icon } from '@/components/Icon'
|
import { Icon } from '@/components/Icon'
|
||||||
import { useAppStore } from '@/store/modules/app'
|
import { useAppStore } from '@/stores/modules/app'
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
|
|
||||||
const { getPrefixCls } = useDesign()
|
const { getPrefixCls } = useDesign()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useAppStore } from '@/store/modules/app'
|
import { useAppStore } from '@/stores/modules/app'
|
||||||
import { propTypes } from '@/utils/propTypes'
|
import { propTypes } from '@/utils/propTypes'
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
import { Expand,Fold,ZoomIn,Delete} from '@element-plus/icons-vue'
|
import { Expand,Fold,ZoomIn,Delete} from '@element-plus/icons-vue'
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useAppStore } from '@/store/modules/app'
|
import { useAppStore } from '@/stores/modules/app'
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
|
|
||||||
// eslint-disable-next-line vue/no-reserved-component-names
|
// eslint-disable-next-line vue/no-reserved-component-names
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useLocaleStore } from '@/store/modules/locale'
|
import { useLocaleStore } from '@/stores/modules/locale'
|
||||||
import { useLocale } from '@/hooks/web/useLocale'
|
import { useLocale } from '@/hooks/web/useLocale'
|
||||||
import { propTypes } from '@/utils/propTypes'
|
import { propTypes } from '@/utils/propTypes'
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, onMounted, ref, unref, watch } from 'vue'
|
import { computed, onMounted, ref, unref, watch } from 'vue'
|
||||||
import { useAppStore } from '@/store/modules/app'
|
import { useAppStore } from '@/stores/modules/app'
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
|
|
||||||
defineOptions({ name: 'Logo' })
|
defineOptions({ name: 'Logo' })
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<script lang="tsx">
|
<script lang="tsx">
|
||||||
import { PropType } from 'vue'
|
import { PropType } from 'vue'
|
||||||
import { ElMenu, ElScrollbar } from 'element-plus'
|
import { ElMenu, ElScrollbar } from 'element-plus'
|
||||||
import { useAppStore } from '@/store/modules/app'
|
import { useAppStore } from '@/stores/modules/app'
|
||||||
import { usePermissionStore } from '@/store/modules/permission'
|
import { usePermissionStore } from '@/stores/modules/permission'
|
||||||
import { useRenderMenuItem } from './components/useRenderMenuItem'
|
import { useRenderMenuItem } from './components/useRenderMenuItem'
|
||||||
import { isUrl } from '@/utils/is'
|
import { isUrl } from '@/utils/is'
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import { useDesign } from '@/hooks/web/useDesign'
|
|||||||
|
|
||||||
import { setCssVar, trim } from '@/utils'
|
import { setCssVar, trim } from '@/utils'
|
||||||
import { colorIsDark, hexToRGB, lighten } from '@/utils/color'
|
import { colorIsDark, hexToRGB, lighten } from '@/utils/color'
|
||||||
import { useAppStore } from '@/store/modules/app'
|
import { useAppStore } from '@/stores/modules/app'
|
||||||
import { ThemeSwitch } from '@/layout/components/ThemeSwitch'
|
import { ThemeSwitch } from '@/layouts/components/ThemeSwitch'
|
||||||
import ColorRadioPicker from './components/ColorRadioPicker.vue'
|
import ColorRadioPicker from './components/ColorRadioPicker.vue'
|
||||||
import InterfaceDisplay from './components/InterfaceDisplay.vue'
|
import InterfaceDisplay from './components/InterfaceDisplay.vue'
|
||||||
import LayoutRadioPicker from './components/LayoutRadioPicker.vue'
|
import LayoutRadioPicker from './components/LayoutRadioPicker.vue'
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { setCssVar } from '@/utils'
|
|||||||
|
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
import { useWatermark } from '@/hooks/web/useWatermark'
|
import { useWatermark } from '@/hooks/web/useWatermark'
|
||||||
import { useAppStore } from '@/store/modules/app'
|
import { useAppStore } from '@/stores/modules/app'
|
||||||
|
|
||||||
defineOptions({ name: 'InterfaceDisplay' })
|
defineOptions({ name: 'InterfaceDisplay' })
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useAppStore } from '@/store/modules/app'
|
import { useAppStore } from '@/stores/modules/app'
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
|
|
||||||
defineOptions({ name: 'LayoutRadioPicker' })
|
defineOptions({ name: 'LayoutRadioPicker' })
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useAppStore } from '@/store/modules/app'
|
import { useAppStore } from '@/stores/modules/app'
|
||||||
|
|
||||||
import { propTypes } from '@/utils/propTypes'
|
import { propTypes } from '@/utils/propTypes'
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
<script lang="tsx">
|
<script lang="tsx">
|
||||||
import { usePermissionStore } from '@/store/modules/permission'
|
import { usePermissionStore } from '@/stores/modules/permission'
|
||||||
import { useAppStore } from '@/store/modules/app'
|
import { useAppStore } from '@/stores/modules/app'
|
||||||
|
|
||||||
import { ElScrollbar } from 'element-plus'
|
import { ElScrollbar } from 'element-plus'
|
||||||
import { Icon } from '@/components/Icon'
|
import { Menu } from '@/layouts/components/Menu'
|
||||||
import { Menu } from '@/layout/components/Menu'
|
|
||||||
import { pathResolve } from '@/utils/routerHelper'
|
import { pathResolve } from '@/utils/routerHelper'
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
import { filterMenusPath, initTabMap, tabPathMap } from './helper'
|
import { filterMenusPath, initTabMap, tabPathMap } from './helper'
|
||||||
@@ -173,7 +172,6 @@ export default defineComponent({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<Icon icon={item?.meta?.icon}></Icon>
|
|
||||||
</div>
|
</div>
|
||||||
{!unref(showTitle) ? undefined : (
|
{!unref(showTitle) ? undefined : (
|
||||||
<p class="mt-5px break-words px-2px">{t(item.meta?.title)}</p>
|
<p class="mt-5px break-words px-2px">{t(item.meta?.title)}</p>
|
||||||
@@ -191,7 +189,6 @@ export default defineComponent({
|
|||||||
]}
|
]}
|
||||||
onClick={setCollapse}
|
onClick={setCollapse}
|
||||||
>
|
>
|
||||||
<Icon icon={unref(collapse) ? 'ep:d-arrow-right' : 'ep:d-arrow-left'}></Icon>
|
|
||||||
</div>
|
</div>
|
||||||
<Menu
|
<Menu
|
||||||
class={[
|
class={[
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { getAllParentPath } from '@/layout/components/Menu/src/helper'
|
import { getAllParentPath } from '@/layouts/components/Menu/src/helper'
|
||||||
import type { RouteMeta } from 'vue-router'
|
import type { RouteMeta } from 'vue-router'
|
||||||
import { isUrl } from '@/utils/is'
|
import { isUrl } from '@/utils/is'
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
|
|||||||
@@ -2,12 +2,12 @@
|
|||||||
import { onMounted, watch, computed, unref, ref, nextTick } from 'vue'
|
import { onMounted, watch, computed, unref, ref, nextTick } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import type { RouteLocationNormalizedLoaded, RouterLinkProps } from 'vue-router'
|
import type { RouteLocationNormalizedLoaded, RouterLinkProps } from 'vue-router'
|
||||||
import { usePermissionStore } from '@/store/modules/permission'
|
import { usePermissionStore } from '@/stores/modules/permission'
|
||||||
import { useTagsViewStore } from '@/store/modules/tagsView'
|
import { useTagsViewStore } from '@/stores/modules/tagsView'
|
||||||
import { useAppStore } from '@/store/modules/app'
|
import { useAppStore } from '@/stores/modules/app'
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
import { filterAffixTags } from './helper'
|
import { filterAffixTags } from './helper'
|
||||||
import { ContextMenu, ContextMenuExpose } from '@/layout/components/ContextMenu'
|
import { ContextMenu, ContextMenuExpose } from '@/layouts/components/ContextMenu'
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
import { useTemplateRefsList } from '@vueuse/core'
|
import { useTemplateRefsList } from '@vueuse/core'
|
||||||
import { ElScrollbar } from 'element-plus'
|
import { ElScrollbar } from 'element-plus'
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useAppStore } from '@/store/modules/app'
|
import { useAppStore } from '@/stores/modules/app'
|
||||||
import { useIcon } from '@/hooks/web/useIcon'
|
import { useIcon } from '@/hooks/web/useIcon'
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
<script lang="tsx">
|
<script lang="tsx">
|
||||||
import { defineComponent, computed } from 'vue'
|
import { defineComponent, computed } from 'vue'
|
||||||
import { Message } from '@/layout/components//Message'
|
import { Collapse } from '@/layouts/components/Collapse'
|
||||||
import { Collapse } from '@/layout/components/Collapse'
|
import { UserInfo } from '@/layouts/components/UserInfo'
|
||||||
import { UserInfo } from '@/layout/components/UserInfo'
|
import { Screenfull } from '@/layouts/components/Screenfull'
|
||||||
import { Screenfull } from '@/layout/components/Screenfull'
|
import { Breadcrumb } from '@/layouts/components/Breadcrumb'
|
||||||
import { Breadcrumb } from '@/layout/components/Breadcrumb'
|
import { SizeDropdown } from '@/layouts/components/SizeDropdown'
|
||||||
import { SizeDropdown } from '@/layout/components/SizeDropdown'
|
import { LocaleDropdown } from '@/layouts/components/LocaleDropdown'
|
||||||
import { LocaleDropdown } from '@/layout/components/LocaleDropdown'
|
|
||||||
import RouterSearch from '@/components/RouterSearch/index.vue'
|
import RouterSearch from '@/components/RouterSearch/index.vue'
|
||||||
import { useAppStore } from '@/store/modules/app'
|
import { useAppStore } from '@/stores/modules/app'
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
|
|
||||||
const { getPrefixCls, variables } = useDesign()
|
const { getPrefixCls, variables } = useDesign()
|
||||||
@@ -76,7 +75,8 @@ export default defineComponent({
|
|||||||
></LocaleDropdown>
|
></LocaleDropdown>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
{message.value ? (
|
{message.value ? (
|
||||||
<Message class="custom-hover" color="var(--top-header-text-color)"></Message>
|
"undefined"
|
||||||
|
// <Message class="custom-hover" color="var(--top-header-text-color)"></Message>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
<UserInfo></UserInfo>
|
<UserInfo></UserInfo>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ import { ElMessageBox } from 'element-plus'
|
|||||||
import { Tools, Menu, Lock, SwitchButton } from '@element-plus/icons-vue'
|
import { Tools, Menu, Lock, SwitchButton } from '@element-plus/icons-vue'
|
||||||
import avatarImg from '@/assets/imgs/avatar.gif'
|
import avatarImg from '@/assets/imgs/avatar.gif'
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
import { useTagsViewStore } from '@/store/modules/tagsView'
|
import { useTagsViewStore } from '@/stores/modules/tagsView'
|
||||||
import { useUserStore } from '@/store/modules/user'
|
import { useUserStore } from '@/stores/modules/user'
|
||||||
import LockDialog from './components/LockDialog.vue'
|
import LockDialog from './components/LockDialog.vue'
|
||||||
import LockPage from './components/LockPage.vue'
|
import LockPage from './components/LockPage.vue'
|
||||||
import { useLockStore } from '@/store/modules/lock'
|
import { useLockStore } from '@/stores/modules/lock'
|
||||||
|
|
||||||
defineOptions({ name: 'UserInfo' })
|
defineOptions({ name: 'UserInfo' })
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useValidator } from '@/hooks/web/useValidator'
|
import { useValidator } from '@/hooks/web/useValidator'
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
import { useLockStore } from '@/store/modules/lock'
|
import { useLockStore } from '@/stores/modules/lock'
|
||||||
import avatarImg from '@/assets/imgs/avatar.gif'
|
import avatarImg from '@/assets/imgs/avatar.gif'
|
||||||
import { useUserStore } from '@/store/modules/user'
|
import { useUserStore } from '@/stores/modules/user'
|
||||||
|
|
||||||
const { getPrefixCls } = useDesign()
|
const { getPrefixCls } = useDesign()
|
||||||
const prefixCls = getPrefixCls('lock-dialog')
|
const prefixCls = getPrefixCls('lock-dialog')
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { resetRouter } from '@/router'
|
|
||||||
import { deleteUserCache } from '@/hooks/web/useCache'
|
import { deleteUserCache } from '@/hooks/web/useCache'
|
||||||
import { useLockStore } from '@/store/modules/lock'
|
import { useLockStore } from '@/stores/modules/lock'
|
||||||
import { useNow } from '@/hooks/web/useNow'
|
import { useNow } from '@/hooks/web/useNow'
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
import { useTagsViewStore } from '@/store/modules/tagsView'
|
import { useTagsViewStore } from '@/stores/modules/tagsView'
|
||||||
import { useUserStore } from '@/store/modules/user'
|
import { useUserStore } from '@/stores/modules/user'
|
||||||
import avatarImg from '@/assets/imgs/avatar.gif'
|
import avatarImg from '@/assets/imgs/avatar.gif'
|
||||||
|
|
||||||
const tagsViewStore = useTagsViewStore()
|
const tagsViewStore = useTagsViewStore()
|
||||||
@@ -52,7 +51,7 @@ async function goLogin() {
|
|||||||
// 登出后清理
|
// 登出后清理
|
||||||
deleteUserCache() // 清空用户缓存
|
deleteUserCache() // 清空用户缓存
|
||||||
tagsViewStore.delAllViews()
|
tagsViewStore.delAllViews()
|
||||||
resetRouter() // 重置静态路由表
|
// resetRouter() // 重置静态路由表
|
||||||
lockStore.resetLockInfo()
|
lockStore.resetLockInfo()
|
||||||
replace('/login')
|
replace('/login')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { useAppStore } from '@/store/modules/app'
|
import { useAppStore } from '@/stores/modules/app'
|
||||||
import { Menu } from '@/layout/components/Menu'
|
import { Menu } from '@/layouts/components/Menu'
|
||||||
import { TabMenu } from '@/layout/components/TabMenu'
|
import { TabMenu } from '@/layouts/components/TabMenu'
|
||||||
import { TagsView } from '@/layout/components/TagsView'
|
import { TagsView } from '@/layouts/components/TagsView'
|
||||||
import { Logo } from '@/layout/components/Logo'
|
import { Logo } from '@/layouts/components/Logo'
|
||||||
import AppView from './AppView.vue'
|
import AppView from './AppView.vue'
|
||||||
import ToolHeader from './ToolHeader.vue'
|
import ToolHeader from './ToolHeader.vue'
|
||||||
import { ElScrollbar } from 'element-plus'
|
import { ElScrollbar } from 'element-plus'
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { store } from '../index'
|
import { store } from '../indexs'
|
||||||
import { setCssVar, humpToUnderline } from '@/utils'
|
import { setCssVar, humpToUnderline } from '@/utils'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
|
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { store } from '@/store'
|
import { store } from '@/stores/indexs'
|
||||||
|
|
||||||
interface lockInfo {
|
interface lockInfo {
|
||||||
isLock?: boolean
|
isLock?: boolean
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { store } from '@/store'
|
import { store } from '@/stores/indexs'
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
import remainingRouter from '@/router/modules/remaining'
|
|
||||||
import { flatMultiLevelRoutes, generateRoute } from '@/utils/routerHelper'
|
import { flatMultiLevelRoutes, generateRoute } from '@/utils/routerHelper'
|
||||||
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
|
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
|
||||||
|
|
||||||
@@ -52,7 +51,6 @@ export const usePermissionStore = defineStore('permission', {
|
|||||||
}
|
}
|
||||||
])
|
])
|
||||||
// 渲染菜单的所有路由
|
// 渲染菜单的所有路由
|
||||||
this.routers = cloneDeep(remainingRouter).concat(routerMap)
|
|
||||||
resolve()
|
resolve()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { store } from '@/store'
|
import { store } from '@/stores/indexs'
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { getAccessToken, removeToken } from '@/utils/auth'
|
import { getAccessToken, removeToken } from '@/utils/auth'
|
||||||
import { CACHE_KEY, useCache, deleteUserCache } from '@/hooks/web/useCache'
|
import { CACHE_KEY, useCache, deleteUserCache } from '@/hooks/web/useCache'
|
||||||
import { getInfo, loginOut } from '@/api/login'
|
// import { getInfo, loginOut } from '@/api/login'
|
||||||
|
|
||||||
const { wsCache } = useCache()
|
const { wsCache } = useCache()
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ export const useUserStore = defineStore('admin-user', {
|
|||||||
}
|
}
|
||||||
let userInfo = wsCache.get(CACHE_KEY.USER)
|
let userInfo = wsCache.get(CACHE_KEY.USER)
|
||||||
if (!userInfo) {
|
if (!userInfo) {
|
||||||
userInfo = await getInfo()
|
// userInfo = await getInfo()
|
||||||
}
|
}
|
||||||
this.permissions = userInfo.permissions
|
this.permissions = userInfo.permissions
|
||||||
this.roles = userInfo.roles
|
this.roles = userInfo.roles
|
||||||
@@ -79,7 +79,7 @@ export const useUserStore = defineStore('admin-user', {
|
|||||||
wsCache.set(CACHE_KEY.USER, userInfo)
|
wsCache.set(CACHE_KEY.USER, userInfo)
|
||||||
},
|
},
|
||||||
async loginOut() {
|
async loginOut() {
|
||||||
await loginOut()
|
// await loginOut()
|
||||||
removeToken()
|
removeToken()
|
||||||
deleteUserCache() // 删除用户缓存
|
deleteUserCache() // 删除用户缓存
|
||||||
this.resetState()
|
this.resetState()
|
||||||
|
|||||||
3
src/types/elementPlus.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export type ElementPlusSize = 'default' | 'small' | 'large'
|
||||||
|
|
||||||
|
export type ElementPlusInfoType = 'success' | 'info' | 'warning' | 'danger'
|
||||||
5
src/types/icon.d.ts
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export interface IconTypes {
|
||||||
|
size?: number
|
||||||
|
color?: string
|
||||||
|
icon: string
|
||||||
|
}
|
||||||
1
src/types/layout.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export type LayoutType = 'classic' | 'topLeft' | 'top' | 'cutMenu'
|
||||||
16
src/types/theme.d.ts
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
export type ThemeTypes = {
|
||||||
|
elColorPrimary?: string
|
||||||
|
leftMenuBorderColor?: string
|
||||||
|
leftMenuBgColor?: string
|
||||||
|
leftMenuBgLightColor?: string
|
||||||
|
leftMenuBgActiveColor?: string
|
||||||
|
leftMenuCollapseBgActiveColor?: string
|
||||||
|
leftMenuTextColor?: string
|
||||||
|
leftMenuTextActiveColor?: string
|
||||||
|
logoTitleTextColor?: string
|
||||||
|
logoBorderColor?: string
|
||||||
|
topHeaderBgColor?: string
|
||||||
|
topHeaderTextColor?: string
|
||||||
|
topHeaderHoverColor?: string
|
||||||
|
topToolBorderColor?: string
|
||||||
|
}
|
||||||
18
src/utils/dateUtil.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* Independent time operation tool to facilitate subsequent switch to dayjs
|
||||||
|
*/
|
||||||
|
// TODO 芋艿:【锁屏】可能后面删除掉
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
|
||||||
|
const DATE_TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss'
|
||||||
|
const DATE_FORMAT = 'YYYY-MM-DD'
|
||||||
|
|
||||||
|
export function formatToDateTime(date?: dayjs.ConfigType, format = DATE_TIME_FORMAT): string {
|
||||||
|
return dayjs(date).format(format)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatToDate(date?: dayjs.ConfigType, format = DATE_FORMAT): string {
|
||||||
|
return dayjs(date).format(format)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const dateUtil = dayjs
|
||||||