Merge branch 'master' into release
commit
fa1735fbdb
@ -0,0 +1,4 @@
|
|||||||
|
import JsonEditor from './src/JsonEditor.vue'
|
||||||
|
export type { JsonEditorProps } from './src/types'
|
||||||
|
|
||||||
|
export { JsonEditor }
|
||||||
@ -0,0 +1,98 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import VueJsonPretty from 'vue-json-pretty'
|
||||||
|
import 'vue-json-pretty/lib/styles.css'
|
||||||
|
import { propTypes } from '@/utils/propTypes'
|
||||||
|
import { computed } from 'vue'
|
||||||
|
|
||||||
|
const emits = defineEmits([
|
||||||
|
'update:modelValue',
|
||||||
|
'node-click',
|
||||||
|
'brackets-click',
|
||||||
|
'icon-click',
|
||||||
|
'selected-value'
|
||||||
|
])
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
},
|
||||||
|
deep: propTypes.number.def(5),
|
||||||
|
showLength: propTypes.bool.def(true),
|
||||||
|
showLineNumbers: propTypes.bool.def(true),
|
||||||
|
showLineNumber: propTypes.bool.def(true),
|
||||||
|
showIcon: propTypes.bool.def(true),
|
||||||
|
showDoubleQuotes: propTypes.bool.def(true),
|
||||||
|
virtual: propTypes.bool.def(false),
|
||||||
|
height: propTypes.number.def(400),
|
||||||
|
itemHeight: propTypes.number.def(20),
|
||||||
|
rootPath: propTypes.string.def('root'),
|
||||||
|
nodeSelectable: propTypes.func.def(),
|
||||||
|
selectableType: propTypes.oneOf<'multiple' | 'single'>(['multiple', 'single']).def(),
|
||||||
|
showSelectController: propTypes.bool.def(false),
|
||||||
|
selectOnClickNode: propTypes.bool.def(true),
|
||||||
|
highlightSelectedNode: propTypes.bool.def(true),
|
||||||
|
collapsedOnClickBrackets: propTypes.bool.def(true),
|
||||||
|
renderNodeKey: propTypes.func.def(),
|
||||||
|
renderNodeValue: propTypes.func.def(),
|
||||||
|
editable: propTypes.bool.def(true),
|
||||||
|
editableTrigger: propTypes.oneOf<'click' | 'dblclick'>(['click', 'dblclick']).def('click')
|
||||||
|
})
|
||||||
|
|
||||||
|
const data = computed(() => props.modelValue)
|
||||||
|
|
||||||
|
const localModelValue = computed({
|
||||||
|
get: () => data.value,
|
||||||
|
set: (val) => {
|
||||||
|
console.log(val)
|
||||||
|
emits('update:modelValue', val)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const nodeClick = (node: any) => {
|
||||||
|
emits('node-click', node)
|
||||||
|
}
|
||||||
|
|
||||||
|
const bracketsClick = (collapsed: boolean) => {
|
||||||
|
emits('brackets-click', collapsed)
|
||||||
|
}
|
||||||
|
|
||||||
|
const iconClick = (collapsed: boolean) => {
|
||||||
|
emits('icon-click', collapsed)
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectedChange = (newVal: any, oldVal: any) => {
|
||||||
|
console.log(newVal, oldVal)
|
||||||
|
emits('selected-value', newVal, oldVal)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<VueJsonPretty
|
||||||
|
v-model:data="localModelValue"
|
||||||
|
:deep="deep"
|
||||||
|
:show-length="showLength"
|
||||||
|
:show-line-numbers="showLineNumbers"
|
||||||
|
:show-line-number="showLineNumber"
|
||||||
|
:show-icon="showIcon"
|
||||||
|
:show-double-quotes="showDoubleQuotes"
|
||||||
|
:virtual="virtual"
|
||||||
|
:height="height"
|
||||||
|
:item-height="itemHeight"
|
||||||
|
:root-path="rootPath"
|
||||||
|
:node-selectable="nodeSelectable"
|
||||||
|
:selectable-type="selectableType"
|
||||||
|
:show-select-controller="showSelectController"
|
||||||
|
:select-on-click-node="selectOnClickNode"
|
||||||
|
:highlight-selected-node="highlightSelectedNode"
|
||||||
|
:collapsed-on-click-brackets="collapsedOnClickBrackets"
|
||||||
|
:render-node-key="renderNodeKey"
|
||||||
|
:render-node-value="renderNodeValue"
|
||||||
|
:editable="editable"
|
||||||
|
:editable-trigger="editableTrigger"
|
||||||
|
@node-click="nodeClick"
|
||||||
|
@brackets-click="bracketsClick"
|
||||||
|
@icon-click="iconClick"
|
||||||
|
@selected-change="selectedChange"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
export interface JsonEditorProps {
|
||||||
|
value: any
|
||||||
|
deep?: number
|
||||||
|
showLength?: boolean
|
||||||
|
showLineNumbers?: boolean
|
||||||
|
showLineNumber?: boolean
|
||||||
|
showIcon?: boolean
|
||||||
|
showDoubleQuotes?: boolean
|
||||||
|
virtual?: boolean
|
||||||
|
height?: number
|
||||||
|
itemHeight?: number
|
||||||
|
rootPath?: string
|
||||||
|
nodeSelectable?: (...args: any[]) => boolean
|
||||||
|
selectableType?: 'multiple' | 'single'
|
||||||
|
showSelectController?: boolean
|
||||||
|
selectOnClickNode?: boolean
|
||||||
|
highlightSelectedNode?: boolean
|
||||||
|
collapsedOnClickBrackets?: boolean
|
||||||
|
renderNodeKey?: (...args: any[]) => any
|
||||||
|
renderNodeValue?: (...args: any[]) => any
|
||||||
|
editable?: boolean
|
||||||
|
editableTrigger?: 'click' | 'dblclick'
|
||||||
|
}
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
import { Config, driver } from 'driver.js'
|
||||||
|
import 'driver.js/dist/driver.css'
|
||||||
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const { variables } = useDesign()
|
||||||
|
|
||||||
|
export const useGuide = (options?: Config) => {
|
||||||
|
const driverObj = driver(
|
||||||
|
options || {
|
||||||
|
showProgress: true,
|
||||||
|
nextBtnText: t('common.nextLabel'),
|
||||||
|
prevBtnText: t('common.prevLabel'),
|
||||||
|
doneBtnText: t('common.doneLabel'),
|
||||||
|
steps: [
|
||||||
|
{
|
||||||
|
element: `#${variables.namespace}-menu`,
|
||||||
|
popover: {
|
||||||
|
title: t('common.menu'),
|
||||||
|
description: t('common.menuDes'),
|
||||||
|
side: 'right'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: `#${variables.namespace}-tool-header`,
|
||||||
|
popover: {
|
||||||
|
title: t('common.tool'),
|
||||||
|
description: t('common.toolDes'),
|
||||||
|
side: 'left'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: `#${variables.namespace}-tags-view`,
|
||||||
|
popover: {
|
||||||
|
title: t('common.tagsView'),
|
||||||
|
description: t('common.tagsViewDes'),
|
||||||
|
side: 'bottom'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
...driverObj
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,47 +0,0 @@
|
|||||||
import introJs from 'intro.js'
|
|
||||||
import { IntroJs, Step, Options } from 'intro.js'
|
|
||||||
import 'intro.js/introjs.css'
|
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
|
||||||
|
|
||||||
export const useIntro = (setps?: Step[], options?: Options) => {
|
|
||||||
const { t } = useI18n()
|
|
||||||
|
|
||||||
const { variables } = useDesign()
|
|
||||||
|
|
||||||
const defaultSetps: Step[] = setps || [
|
|
||||||
{
|
|
||||||
element: `#${variables.namespace}-menu`,
|
|
||||||
title: t('common.menu'),
|
|
||||||
intro: t('common.menuDes'),
|
|
||||||
position: 'right'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
element: `#${variables.namespace}-tool-header`,
|
|
||||||
title: t('common.tool'),
|
|
||||||
intro: t('common.toolDes'),
|
|
||||||
position: 'left'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
element: `#${variables.namespace}-tags-view`,
|
|
||||||
title: t('common.tagsView'),
|
|
||||||
intro: t('common.tagsViewDes'),
|
|
||||||
position: 'bottom'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
const defaultOptions: Options = options || {
|
|
||||||
prevLabel: t('common.prevLabel'),
|
|
||||||
nextLabel: t('common.nextLabel'),
|
|
||||||
skipLabel: t('common.skipLabel'),
|
|
||||||
doneLabel: t('common.doneLabel')
|
|
||||||
}
|
|
||||||
|
|
||||||
const introRef: IntroJs = introJs()
|
|
||||||
|
|
||||||
introRef.addSteps(defaultSetps).setOptions(defaultOptions)
|
|
||||||
|
|
||||||
return {
|
|
||||||
introRef
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,63 @@
|
|||||||
|
import { useTagsViewStoreWithOut } from '@/store/modules/tagsView'
|
||||||
|
import { RouteLocationNormalizedLoaded, useRouter } from 'vue-router'
|
||||||
|
import { computed, nextTick, unref } from 'vue'
|
||||||
|
|
||||||
|
export const useTagsView = () => {
|
||||||
|
const tagsViewStore = useTagsViewStoreWithOut()
|
||||||
|
|
||||||
|
const { replace, currentRoute } = useRouter()
|
||||||
|
|
||||||
|
const selectedTag = computed(() => tagsViewStore.getSelectedTag)
|
||||||
|
|
||||||
|
const closeAll = (callback?: Fn) => {
|
||||||
|
tagsViewStore.delAllViews()
|
||||||
|
callback?.()
|
||||||
|
}
|
||||||
|
|
||||||
|
const closeLeft = (callback?: Fn) => {
|
||||||
|
tagsViewStore.delLeftViews(unref(selectedTag) as RouteLocationNormalizedLoaded)
|
||||||
|
callback?.()
|
||||||
|
}
|
||||||
|
|
||||||
|
const closeRight = (callback?: Fn) => {
|
||||||
|
tagsViewStore.delRightViews(unref(selectedTag) as RouteLocationNormalizedLoaded)
|
||||||
|
callback?.()
|
||||||
|
}
|
||||||
|
|
||||||
|
const closeOther = (callback?: Fn) => {
|
||||||
|
tagsViewStore.delOthersViews(unref(selectedTag) as RouteLocationNormalizedLoaded)
|
||||||
|
callback?.()
|
||||||
|
}
|
||||||
|
|
||||||
|
const closeCurrent = (view?: RouteLocationNormalizedLoaded, callback?: Fn) => {
|
||||||
|
if (view?.meta?.affix) return
|
||||||
|
tagsViewStore.delView(view || unref(currentRoute))
|
||||||
|
|
||||||
|
callback?.()
|
||||||
|
}
|
||||||
|
|
||||||
|
const refreshPage = async (view?: RouteLocationNormalizedLoaded, callback?: Fn) => {
|
||||||
|
tagsViewStore.delCachedView()
|
||||||
|
const { path, query } = view || unref(currentRoute)
|
||||||
|
await nextTick()
|
||||||
|
replace({
|
||||||
|
path: '/redirect' + path,
|
||||||
|
query: query
|
||||||
|
})
|
||||||
|
callback?.()
|
||||||
|
}
|
||||||
|
|
||||||
|
const setTitle = (title: string, path?: string) => {
|
||||||
|
tagsViewStore.setTitle(title, path)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
closeAll,
|
||||||
|
closeLeft,
|
||||||
|
closeRight,
|
||||||
|
closeOther,
|
||||||
|
closeCurrent,
|
||||||
|
refreshPage,
|
||||||
|
setTitle
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,34 +0,0 @@
|
|||||||
import { defineStore } from 'pinia'
|
|
||||||
import { store } from '../index'
|
|
||||||
|
|
||||||
export interface DictState {
|
|
||||||
isSetDict: boolean
|
|
||||||
dictObj: Recordable
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useDictStore = defineStore('dict', {
|
|
||||||
state: (): DictState => ({
|
|
||||||
isSetDict: false,
|
|
||||||
dictObj: {}
|
|
||||||
}),
|
|
||||||
getters: {
|
|
||||||
getDictObj(): Recordable {
|
|
||||||
return this.dictObj
|
|
||||||
},
|
|
||||||
getIsSetDict(): boolean {
|
|
||||||
return this.isSetDict
|
|
||||||
}
|
|
||||||
},
|
|
||||||
actions: {
|
|
||||||
setDictObj(dictObj: Recordable) {
|
|
||||||
this.dictObj = dictObj
|
|
||||||
},
|
|
||||||
setIsSetDict(isSetDict: boolean) {
|
|
||||||
this.isSetDict = isSetDict
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
export const useDictStoreWithOut = () => {
|
|
||||||
return useDictStore(store)
|
|
||||||
}
|
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { ContentWrap } from '@/components/ContentWrap'
|
||||||
|
import { JsonEditor } from '@/components/JsonEditor'
|
||||||
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
|
import { ref, watch } from 'vue'
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const defaultData = ref({
|
||||||
|
title: '标题',
|
||||||
|
content: '内容'
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => defaultData.value,
|
||||||
|
(val) => {
|
||||||
|
console.log(val)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deep: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
defaultData.value = {
|
||||||
|
title: '异步标题',
|
||||||
|
content: '异步内容'
|
||||||
|
}
|
||||||
|
}, 4000)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ContentWrap :title="t('richText.jsonEditor')" :message="t('richText.jsonEditorDes')">
|
||||||
|
<JsonEditor v-model="defaultData" />
|
||||||
|
</ContentWrap>
|
||||||
|
</template>
|
||||||
@ -1,223 +1,186 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
// import { ContentWrap } from '@/components/ContentWrap'
|
import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'
|
||||||
// import { Search } from '@/components/Search'
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
// import { useI18n } from '@/hooks/web/useI18n'
|
import { reactive } from 'vue'
|
||||||
// import { ElButton, ElTag } from 'element-plus'
|
import { JsonEditor } from '@/components/JsonEditor'
|
||||||
// import { Table } from '@/components/Table'
|
import { ContentWrap } from '@/components/ContentWrap'
|
||||||
// import { getTableListApi, delTableListApi } from '@/api/table'
|
import { ElRow, ElCol } from 'element-plus'
|
||||||
// import { useTable } from '@/hooks/web/useTable'
|
|
||||||
// import { TableData } from '@/api/table/types'
|
|
||||||
// import { h, ref, reactive } from 'vue'
|
|
||||||
// import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'
|
|
||||||
// import { useDictStore } from '@/store/modules/dict'
|
|
||||||
// import { getDictOneApi } from '@/api/common'
|
|
||||||
// import { TableColumn } from '@/types/table'
|
|
||||||
|
|
||||||
// const dictStore = useDictStore()
|
const { t } = useI18n()
|
||||||
|
|
||||||
// const { register, tableObject, methods } = useTable<TableData>({
|
const crudSchemas = reactive<CrudSchema[]>([
|
||||||
// getListApi: getTableListApi,
|
{
|
||||||
// delListApi: delTableListApi,
|
field: 'selection',
|
||||||
// response: {
|
search: {
|
||||||
// list: 'list',
|
hidden: true
|
||||||
// total: 'total'
|
},
|
||||||
// }
|
form: {
|
||||||
// })
|
hidden: true
|
||||||
|
},
|
||||||
|
detail: {
|
||||||
|
hidden: true
|
||||||
|
},
|
||||||
|
table: {
|
||||||
|
type: 'selection'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'index',
|
||||||
|
label: t('tableDemo.index'),
|
||||||
|
type: 'index',
|
||||||
|
search: {
|
||||||
|
hidden: true
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
hidden: true
|
||||||
|
},
|
||||||
|
detail: {
|
||||||
|
hidden: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'title',
|
||||||
|
label: t('tableDemo.title'),
|
||||||
|
search: {
|
||||||
|
component: 'Input'
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
component: 'Input',
|
||||||
|
colProps: {
|
||||||
|
span: 24
|
||||||
|
}
|
||||||
|
},
|
||||||
|
detail: {
|
||||||
|
span: 24
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'author',
|
||||||
|
label: t('tableDemo.author'),
|
||||||
|
search: {
|
||||||
|
hidden: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'display_time',
|
||||||
|
label: t('tableDemo.displayTime'),
|
||||||
|
search: {
|
||||||
|
hidden: true
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
component: 'DatePicker',
|
||||||
|
componentProps: {
|
||||||
|
type: 'datetime',
|
||||||
|
valueFormat: 'YYYY-MM-DD HH:mm:ss'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'importance',
|
||||||
|
label: t('tableDemo.importance'),
|
||||||
|
search: {
|
||||||
|
hidden: true
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
style: {
|
||||||
|
width: '100%'
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: '重要',
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '良好',
|
||||||
|
value: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '一般',
|
||||||
|
value: 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'pageviews',
|
||||||
|
label: t('tableDemo.pageviews'),
|
||||||
|
search: {
|
||||||
|
hidden: true
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
component: 'InputNumber',
|
||||||
|
value: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'content',
|
||||||
|
label: t('exampleDemo.content'),
|
||||||
|
search: {
|
||||||
|
hidden: true
|
||||||
|
},
|
||||||
|
table: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
component: 'Editor',
|
||||||
|
colProps: {
|
||||||
|
span: 24
|
||||||
|
}
|
||||||
|
},
|
||||||
|
detail: {
|
||||||
|
span: 24
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'action',
|
||||||
|
width: '260px',
|
||||||
|
label: t('tableDemo.action'),
|
||||||
|
search: {
|
||||||
|
hidden: true
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
hidden: true
|
||||||
|
},
|
||||||
|
detail: {
|
||||||
|
hidden: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
// const { getList, setSearchParams } = methods
|
const { allSchemas } = useCrudSchemas(crudSchemas)
|
||||||
|
|
||||||
// getList()
|
|
||||||
|
|
||||||
// const { t } = useI18n()
|
|
||||||
|
|
||||||
// const crudSchemas = reactive<CrudSchema[]>([
|
|
||||||
// {
|
|
||||||
// field: 'index',
|
|
||||||
// label: t('tableDemo.index'),
|
|
||||||
// type: 'index',
|
|
||||||
// form: {
|
|
||||||
// show: false
|
|
||||||
// },
|
|
||||||
// detail: {
|
|
||||||
// show: false
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// field: 'title',
|
|
||||||
// label: t('tableDemo.title'),
|
|
||||||
// search: {
|
|
||||||
// show: true
|
|
||||||
// },
|
|
||||||
// form: {
|
|
||||||
// colProps: {
|
|
||||||
// span: 24
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// detail: {
|
|
||||||
// span: 24
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// field: 'author',
|
|
||||||
// label: t('tableDemo.author')
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// field: 'display_time',
|
|
||||||
// label: t('tableDemo.displayTime'),
|
|
||||||
// form: {
|
|
||||||
// component: 'DatePicker',
|
|
||||||
// componentProps: {
|
|
||||||
// type: 'datetime',
|
|
||||||
// valueFormat: 'YYYY-MM-DD HH:mm:ss'
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// field: 'importance',
|
|
||||||
// label: t('tableDemo.importance'),
|
|
||||||
// formatter: (_: Recordable, __: TableColumn, cellValue: number) => {
|
|
||||||
// return h(
|
|
||||||
// ElTag,
|
|
||||||
// {
|
|
||||||
// type: cellValue === 1 ? 'success' : cellValue === 2 ? 'warning' : 'danger'
|
|
||||||
// },
|
|
||||||
// () =>
|
|
||||||
// cellValue === 1
|
|
||||||
// ? t('tableDemo.important')
|
|
||||||
// : cellValue === 2
|
|
||||||
// ? t('tableDemo.good')
|
|
||||||
// : t('tableDemo.commonly')
|
|
||||||
// )
|
|
||||||
// },
|
|
||||||
// search: {
|
|
||||||
// show: true,
|
|
||||||
// component: 'Select',
|
|
||||||
// componentProps: {
|
|
||||||
// options: dictStore.getDictObj.importance
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// form: {
|
|
||||||
// component: 'Select',
|
|
||||||
// componentProps: {
|
|
||||||
// options: [
|
|
||||||
// {
|
|
||||||
// label: '重要',
|
|
||||||
// value: 3
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// label: '良好',
|
|
||||||
// value: 2
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// label: '一般',
|
|
||||||
// value: 1
|
|
||||||
// }
|
|
||||||
// ]
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// field: 'importance2',
|
|
||||||
// label: `${t('tableDemo.importance')}2`,
|
|
||||||
// search: {
|
|
||||||
// show: true,
|
|
||||||
// component: 'Select',
|
|
||||||
// dictName: 'importance'
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// field: 'importance3',
|
|
||||||
// label: `${t('tableDemo.importance')}3`,
|
|
||||||
// search: {
|
|
||||||
// show: true,
|
|
||||||
// component: 'Select',
|
|
||||||
// api: async () => {
|
|
||||||
// const res = await getDictOneApi()
|
|
||||||
// return res.data
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// field: 'pageviews',
|
|
||||||
// label: t('tableDemo.pageviews'),
|
|
||||||
// form: {
|
|
||||||
// component: 'InputNumber',
|
|
||||||
// value: 0
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// field: 'content',
|
|
||||||
// label: t('exampleDemo.content'),
|
|
||||||
// table: {
|
|
||||||
// show: false
|
|
||||||
// },
|
|
||||||
// form: {
|
|
||||||
// component: 'Editor',
|
|
||||||
// colProps: {
|
|
||||||
// span: 24
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// detail: {
|
|
||||||
// span: 24
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// field: 'action',
|
|
||||||
// width: '260px',
|
|
||||||
// label: t('tableDemo.action'),
|
|
||||||
// form: {
|
|
||||||
// show: false
|
|
||||||
// },
|
|
||||||
// detail: {
|
|
||||||
// show: false
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ])
|
|
||||||
|
|
||||||
// const { allSchemas } = useCrudSchemas(crudSchemas)
|
|
||||||
|
|
||||||
// const delLoading = ref(false)
|
|
||||||
|
|
||||||
// const delData = async (row: TableData | null, multiple: boolean) => {
|
|
||||||
// tableObject.currentRow = row
|
|
||||||
// const { delList, getSelections } = methods
|
|
||||||
// const selections = await getSelections()
|
|
||||||
// delLoading.value = true
|
|
||||||
// await delList(
|
|
||||||
// multiple ? selections.map((v) => v.id) : [tableObject.currentRow?.id as string],
|
|
||||||
// multiple
|
|
||||||
// ).finally(() => {
|
|
||||||
// delLoading.value = false
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ContentWrap>
|
<ContentWrap title="useCrudSchemas">
|
||||||
<!-- <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
|
<ElRow :gutter="20">
|
||||||
|
<ElCol :span="24">
|
||||||
<div class="mb-10px">
|
<ContentWrap title="原始数据数据" class="mt-20px">
|
||||||
<ElButton :loading="delLoading" type="danger" @click="delData(null, true)">
|
<JsonEditor v-model="crudSchemas" />
|
||||||
{{ t('exampleDemo.del') }}
|
</ContentWrap>
|
||||||
</ElButton>
|
</ElCol>
|
||||||
</div>
|
<ElCol :span="24">
|
||||||
|
<ContentWrap title="查询组件数据结构" class="mt-20px">
|
||||||
<Table
|
<JsonEditor v-model="allSchemas.searchSchema" />
|
||||||
v-model:pageSize="tableObject.pageSize"
|
</ContentWrap>
|
||||||
v-model:currentPage="tableObject.currentPage"
|
</ElCol>
|
||||||
:columns="allSchemas.tableColumns"
|
<ElCol :span="24">
|
||||||
:data="tableObject.tableList"
|
<ContentWrap title="表单组件数据结构" class="mt-20px">
|
||||||
:loading="tableObject.loading"
|
<JsonEditor v-model="allSchemas.formSchema" />
|
||||||
:pagination="{
|
</ContentWrap>
|
||||||
total: tableObject.total
|
</ElCol>
|
||||||
}"
|
<ElCol :span="24">
|
||||||
@register="register"
|
<ContentWrap title="表格组件数据结构" class="mt-20px">
|
||||||
>
|
<JsonEditor v-model="allSchemas.tableColumns" />
|
||||||
<template #action="{ row }">
|
</ContentWrap>
|
||||||
<ElButton type="danger" @click="delData(row, false)">
|
</ElCol>
|
||||||
{{ t('exampleDemo.del') }}
|
<ElCol :span="24">
|
||||||
</ElButton>
|
<ContentWrap title="表格组件数据结构" class="mt-20px">
|
||||||
</template>
|
<JsonEditor v-model="allSchemas.detailSchema" />
|
||||||
</Table> -->
|
</ContentWrap>
|
||||||
|
</ElCol>
|
||||||
|
</ElRow>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -0,0 +1,60 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { ContentWrap } from '@/components/ContentWrap'
|
||||||
|
import { ElButton } from 'element-plus'
|
||||||
|
import { useTagsView } from '@/hooks/web/useTagsView'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
|
const { push } = useRouter()
|
||||||
|
|
||||||
|
const { closeAll, closeLeft, closeRight, closeOther, closeCurrent, refreshPage, setTitle } =
|
||||||
|
useTagsView()
|
||||||
|
|
||||||
|
const closeAllTabs = () => {
|
||||||
|
closeAll(() => {
|
||||||
|
push('/dashboard/analysis')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const closeLeftTabs = () => {
|
||||||
|
closeLeft()
|
||||||
|
}
|
||||||
|
|
||||||
|
const closeRightTabs = () => {
|
||||||
|
closeRight()
|
||||||
|
}
|
||||||
|
|
||||||
|
const closeOtherTabs = () => {
|
||||||
|
closeOther()
|
||||||
|
}
|
||||||
|
|
||||||
|
const refresh = () => {
|
||||||
|
refreshPage()
|
||||||
|
}
|
||||||
|
|
||||||
|
const closeCurrentTab = () => {
|
||||||
|
closeCurrent(undefined, () => {
|
||||||
|
push('/dashboard/analysis')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const setTabTitle = () => {
|
||||||
|
setTitle(new Date().getTime().toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
const setAnalysisTitle = () => {
|
||||||
|
setTitle(`分析页-${new Date().getTime().toString()}`, '/dashboard/analysis')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ContentWrap title="useTagsView">
|
||||||
|
<ElButton type="primary" @click="closeAllTabs"> 关闭所有标签页 </ElButton>
|
||||||
|
<ElButton type="primary" @click="closeLeftTabs"> 关闭左侧标签页 </ElButton>
|
||||||
|
<ElButton type="primary" @click="closeRightTabs"> 关闭右侧标签页 </ElButton>
|
||||||
|
<ElButton type="primary" @click="closeOtherTabs"> 关闭其他标签页 </ElButton>
|
||||||
|
<ElButton type="primary" @click="closeCurrentTab"> 关闭当前标签页 </ElButton>
|
||||||
|
<ElButton type="primary" @click="refresh"> 刷新当前标签页 </ElButton>
|
||||||
|
<ElButton type="primary" @click="setTabTitle"> 修改当前标题 </ElButton>
|
||||||
|
<ElButton type="primary" @click="setAnalysisTitle"> 修改分析页标题 </ElButton>
|
||||||
|
</ContentWrap>
|
||||||
|
</template>
|
||||||
@ -0,0 +1,80 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { ContentWrap } from '@/components/ContentWrap'
|
||||||
|
import { Form, FormSchema } from '@/components/Form'
|
||||||
|
import { useValidator } from '@/hooks/web/useValidator'
|
||||||
|
import { useForm } from '@/hooks/web/useForm'
|
||||||
|
import { reactive } from 'vue'
|
||||||
|
import { FormItemRule } from 'element-plus'
|
||||||
|
|
||||||
|
const { formRegister, formMethods } = useForm()
|
||||||
|
|
||||||
|
const { getFormData } = formMethods
|
||||||
|
|
||||||
|
const { required, lengthRange, notSpace, notSpecialCharacters } = useValidator()
|
||||||
|
|
||||||
|
const formSchema = reactive<FormSchema[]>([
|
||||||
|
{
|
||||||
|
field: 'field1',
|
||||||
|
label: '必填',
|
||||||
|
component: 'Input'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'field2',
|
||||||
|
label: '长度范围',
|
||||||
|
component: 'Input'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'field3',
|
||||||
|
label: '不能有空格',
|
||||||
|
component: 'Input'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'field4',
|
||||||
|
label: '不能有特殊字符',
|
||||||
|
component: 'Input'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'field5',
|
||||||
|
label: '是否相等-值1',
|
||||||
|
component: 'Input'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'field6',
|
||||||
|
label: '是否相等-值2',
|
||||||
|
component: 'Input'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
const rules = reactive<{
|
||||||
|
[key: string]: FormItemRule[]
|
||||||
|
}>({
|
||||||
|
field1: [required()],
|
||||||
|
field2: [
|
||||||
|
lengthRange({
|
||||||
|
min: 2,
|
||||||
|
max: 5
|
||||||
|
})
|
||||||
|
],
|
||||||
|
field3: [notSpace()],
|
||||||
|
field4: [notSpecialCharacters()],
|
||||||
|
field5: [
|
||||||
|
{
|
||||||
|
asyncValidator: async (_, val, callback) => {
|
||||||
|
const formData = await getFormData()
|
||||||
|
const { field6 } = formData
|
||||||
|
if (val !== field6) {
|
||||||
|
callback(new Error('两个值不相等'))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ContentWrap title="useValidator">
|
||||||
|
<Form :schema="formSchema" :rules="rules" @register="formRegister" />
|
||||||
|
</ContentWrap>
|
||||||
|
</template>
|
||||||
Loading…
Reference in New Issue