Browse Source

chore: update deps

main
刘凯 11 months ago
parent
commit
ed99d3ce76
  1. 6
      build/utils.ts
  2. 1
      build/vite/plugin/html.ts
  3. 3
      eslint.config.js
  4. 88
      package.json
  5. 5380
      pnpm-lock.yaml
  6. 1
      public/resource/tinymce/langs/en.js
  7. 1
      public/resource/tinymce/langs/zh_CN.js
  8. 2
      src/components/Container/src/LazyContainer.vue
  9. 8
      src/components/Container/src/collapse/CollapseContainer.vue
  10. 2
      src/components/ContextMenu/src/createContextMenu.ts
  11. 4
      src/components/CronTab/index.ts
  12. 360
      src/components/CronTab/src/CronTabInner.vue
  13. 55
      src/components/CronTab/src/CronTabInput.vue
  14. 18
      src/components/CronTab/src/CronTabModal.vue
  15. 10
      src/components/CronTab/src/cron.data.ts
  16. 101
      src/components/CronTab/src/tabs/DayUI.vue
  17. 69
      src/components/CronTab/src/tabs/HourUI.vue
  18. 69
      src/components/CronTab/src/tabs/MinuteUI.vue
  19. 69
      src/components/CronTab/src/tabs/MonthUI.vue
  20. 69
      src/components/CronTab/src/tabs/SecondUI.vue
  21. 135
      src/components/CronTab/src/tabs/WeekUI.vue
  22. 55
      src/components/CronTab/src/tabs/YearUI.vue
  23. 204
      src/components/CronTab/src/tabs/useTabMixin.ts
  24. 50
      src/components/CronTab/src/validator.ts
  25. 2
      src/components/Description/src/typing.ts
  26. 2
      src/components/EllipsisText/src/_utils.ts
  27. 2
      src/components/Form/src/components/FileUpload.vue
  28. 10
      src/components/Form/src/components/FormItem.vue
  29. 5
      src/components/Form/src/hooks/useFormEvents.ts
  30. 4
      src/components/Form/src/types/index.ts
  31. 2
      src/components/Markdown/src/Markdown.vue
  32. 2
      src/components/Markdown/src/MarkdownViewer.vue
  33. 6
      src/components/Modal/src/components/ModalWrapper.vue
  34. 5
      src/components/Preview/src/Functional.vue
  35. 19
      src/components/Table/src/BasicTable.vue
  36. 4
      src/components/Table/src/components/HeaderCell.vue
  37. 2
      src/components/Table/src/components/editable/EditableCell.vue
  38. 3
      src/components/Table/src/components/editable/helper.ts
  39. 2
      src/components/Table/src/hooks/useColumns.ts
  40. 2
      src/components/Table/src/hooks/useRender.ts
  41. 1
      src/components/Table/src/hooks/useTable.ts
  42. 1
      src/components/Table/src/props.ts
  43. 2
      src/components/Table/src/types/column.ts
  44. 9
      src/components/Table/src/types/table.ts
  45. 28
      src/components/Tree/src/BasicTree.vue
  46. 2
      src/hooks/setting/index.ts
  47. 2
      src/hooks/web/useContentHeight.ts
  48. 18
      src/hooks/web/useMessage.tsx
  49. 2
      src/hooks/web/usePermission.ts
  50. 3
      src/layouts/default/header/MultipleHeader.vue
  51. 18
      src/layouts/default/menu/index.vue
  52. 4
      src/logics/error-handle/index.ts
  53. 4
      src/router/guard/permissionGuard.ts
  54. 2
      src/router/helper/menuHelper.ts
  55. 2
      src/store/modules/lock.ts
  56. 3
      src/store/modules/multipleTab.ts
  57. 2
      src/store/modules/permission.ts
  58. 4
      src/store/modules/user.ts
  59. 2
      src/utils/cache/storageCache.ts
  60. 6
      src/utils/cipher.ts
  61. 2
      src/utils/color.ts
  62. 22
      src/utils/dateUtil.ts
  63. 2
      src/utils/domUtils.ts
  64. 2
      src/utils/env.ts
  65. 2
      src/utils/file/download.ts
  66. 3
      src/utils/http/axios/Axios.ts
  67. 6
      src/utils/index.ts
  68. 2
      src/utils/is.ts
  69. 11
      src/utils/mitt.ts
  70. 12
      src/utils/props.ts
  71. 2
      src/utils/tree.ts
  72. 2
      vite.config.ts

6
build/utils.ts

@ -34,7 +34,7 @@ export function wrapperEnv(envConf: Recordable): ViteEnv {
try { try {
realName = JSON.parse(realName.replace(/'/g, '"')) realName = JSON.parse(realName.replace(/'/g, '"'))
} }
catch (error) { catch {
realName = '' realName = ''
} }
} }
@ -71,8 +71,8 @@ export async function getEnvConfig(
match = 'VITE_GLOB_', match = 'VITE_GLOB_',
confFiles = getConfFiles(), confFiles = getConfFiles(),
): Promise<{ ): Promise<{
[key: string]: string [key: string]: string
}> { }> {
let envConfig = {} let envConfig = {}
for (const confFile of confFiles) { for (const confFile of confFiles) {

1
build/vite/plugin/html.ts

@ -8,7 +8,6 @@ import { createHtmlPlugin } from 'vite-plugin-html'
export function configHtmlPlugin({ isBuild }: { isBuild: boolean }) { export function configHtmlPlugin({ isBuild }: { isBuild: boolean }) {
const htmlPlugin: PluginOption[] = createHtmlPlugin({ const htmlPlugin: PluginOption[] = createHtmlPlugin({
minify: isBuild, minify: isBuild,
viteNext: true,
}) })
return htmlPlugin return htmlPlugin
} }

3
eslint.config.js

@ -10,6 +10,9 @@ export default antfu(
'vue/component-name-in-template-casing': 'off', 'vue/component-name-in-template-casing': 'off',
'vue/require-toggle-inside-transition': 'off', 'vue/require-toggle-inside-transition': 'off',
'ts/no-use-before-define': 'off', 'ts/no-use-before-define': 'off',
'no-unused-expressions': 'off',
'@typescript-eslint/no-unused-expressions': 'off',
'regexp/no-unused-capturing-group': 'off',
}, },
}, },
unocss.configs.flat, unocss.configs.flat,

88
package.json

@ -24,84 +24,84 @@
"release": "bumpp -x \"pnpm run changelog\" --all" "release": "bumpp -x \"pnpm run changelog\" --all"
}, },
"dependencies": { "dependencies": {
"@ant-design/colors": "^7.0.2", "@ant-design/colors": "^7.1.0",
"@ant-design/icons-vue": "^7.0.1", "@ant-design/icons-vue": "^7.0.1",
"@codemirror/commands": "^6.3.3", "@codemirror/commands": "^6.6.0",
"@codemirror/lang-javascript": "^6.2.2", "@codemirror/lang-javascript": "^6.2.2",
"@codemirror/lang-json": "^6.0.1", "@codemirror/lang-json": "^6.0.1",
"@codemirror/state": "^6.4.1", "@codemirror/state": "^6.4.1",
"@codemirror/theme-one-dark": "^6.1.2", "@codemirror/theme-one-dark": "^6.1.2",
"@codemirror/view": "^6.25.1", "@codemirror/view": "^6.28.4",
"@vueuse/core": "^10.6.1", "@vueuse/core": "^10.11.0",
"@zxcvbn-ts/core": "^3.0.4", "@zxcvbn-ts/core": "^3.0.4",
"ant-design-vue": "~4.0.8", "ant-design-vue": "^4.2.3",
"axios": "^1.6.4", "axios": "^1.7.2",
"codemirror": "^6.0.1", "codemirror": "^6.0.1",
"cron-parser": "^4.9.0", "cron-parser": "^4.9.0",
"cropperjs": "^1.6.1", "cropperjs": "^1.6.2",
"crypto-js": "^4.2.0", "crypto-js": "^4.2.0",
"dayjs": "^1.11.10", "dayjs": "^1.11.11",
"echarts": "^5.4.3", "echarts": "^5.5.1",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"path-to-regexp": "^6.2.1", "path-to-regexp": "^6.2.2",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"pinia-plugin-persistedstate": "^3.2.1", "pinia-plugin-persistedstate": "^3.2.1",
"print-js": "^1.6.0", "print-js": "^1.6.0",
"qs": "^6.11.2", "qs": "^6.12.3",
"resize-observer-polyfill": "^1.5.1", "resize-observer-polyfill": "^1.5.1",
"sortablejs": "^1.15.1", "sortablejs": "^1.15.2",
"tinymce": "^5.10.9", "tinymce": "^5.10.9",
"vditor": "^3.9.8", "vditor": "^3.10.4",
"vite-plugin-html": "^3.2.1", "vite-plugin-html": "^3.2.2",
"vue": "~3.3.8", "vue": "^3.4.31",
"vue-i18n": "^9.9.0", "vue-i18n": "^9.13.1",
"vue-json-pretty": "^2.3.0", "vue-json-pretty": "^2.4.0",
"vue-router": "^4.2.5", "vue-router": "^4.4.0",
"vue-types": "^5.1.1", "vue-types": "^5.1.3",
"vuedraggable": "^4.1.0", "vuedraggable": "^4.1.0",
"xlsx": "^0.18.5" "xlsx": "^0.18.5"
}, },
"devDependencies": { "devDependencies": {
"@antfu/eslint-config": "^2.6.2", "@antfu/eslint-config": "^2.22.3",
"@iconify/json": "^2.2.164", "@iconify/json": "^2.2.228",
"@types/codemirror": "^5.60.15", "@types/codemirror": "^5.60.15",
"@types/crypto-js": "^4.2.1", "@types/crypto-js": "^4.2.2",
"@types/fs-extra": "^11.0.4", "@types/fs-extra": "^11.0.4",
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"@types/node": "^20.11.0", "@types/node": "^20.14.10",
"@types/nprogress": "^0.2.3", "@types/nprogress": "^0.2.3",
"@types/qs": "^6.9.11", "@types/qs": "^6.9.15",
"@types/sortablejs": "^1.15.5", "@types/sortablejs": "^1.15.8",
"@unocss/eslint-config": "^0.58.3", "@unocss/eslint-config": "^0.58.9",
"@vitejs/plugin-vue": "^4.6.2", "@vitejs/plugin-vue": "^4.6.2",
"@vitejs/plugin-vue-jsx": "^3.1.0", "@vitejs/plugin-vue-jsx": "^3.1.0",
"@vue/compiler-sfc": "^3.4.10", "@vue/compiler-sfc": "^3.4.31",
"bumpp": "^9.2.1", "bumpp": "^9.4.1",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"dotenv": "^16.3.1", "dotenv": "^16.4.5",
"eslint": "^8.56.0", "eslint": "^8.57.0",
"esno": "^4.0.0", "esno": "^4.7.0",
"fs-extra": "^11.2.0", "fs-extra": "^11.2.0",
"inquirer": "^9.2.12", "inquirer": "^9.3.5",
"less": "^4.2.0", "less": "^4.2.0",
"lint-staged": "^15.2.0", "lint-staged": "^15.2.7",
"picocolors": "^1.0.0", "picocolors": "^1.0.1",
"postcss": "^8.4.33", "postcss": "^8.4.39",
"postcss-html": "^1.5.0", "postcss-html": "^1.7.0",
"postcss-less": "^6.0.0", "postcss-less": "^6.0.0",
"rimraf": "^5.0.5", "rimraf": "^5.0.9",
"rollup-plugin-visualizer": "^5.12.0", "rollup-plugin-visualizer": "^5.12.0",
"simple-git-hooks": "^2.9.0", "simple-git-hooks": "^2.11.1",
"terser": "^5.26.0", "terser": "^5.31.2",
"typescript": "^5.3.3", "typescript": "^5.5.3",
"unocss": "^0.58.3", "unocss": "^0.61.3",
"vite": "^4.5.1", "vite": "^5.3.3",
"vite-plugin-compression": "^0.5.1", "vite-plugin-compression": "^0.5.1",
"vite-plugin-pwa": "^0.17.4", "vite-plugin-pwa": "^0.17.5",
"vite-plugin-svg-icons": "^2.0.1", "vite-plugin-svg-icons": "^2.0.1",
"vite-vue-plugin-html": "^1.0.5", "vite-vue-plugin-html": "^1.0.5",
"vue-tsc": "^1.8.27" "vue-tsc": "^2.0.26"
}, },
"simple-git-hooks": { "simple-git-hooks": {
"pre-commit": "pnpm lint-staged && pnpm type:check", "pre-commit": "pnpm lint-staged && pnpm type:check",

5380
pnpm-lock.yaml

File diff suppressed because it is too large Load Diff

1
public/resource/tinymce/langs/en.js

@ -1,3 +1,4 @@
// eslint-disable-next-line no-undef
tinymce.addI18n('es', { tinymce.addI18n('es', {
'Redo': 'Rehacer', 'Redo': 'Rehacer',
'Undo': 'Deshacer', 'Undo': 'Deshacer',

1
public/resource/tinymce/langs/zh_CN.js

@ -1,3 +1,4 @@
// eslint-disable-next-line no-undef
tinymce.addI18n('zh_CN', { tinymce.addI18n('zh_CN', {
'Redo': '\u91CD\u505A', 'Redo': '\u91CD\u505A',
'Undo': '\u64A4\u9500', 'Undo': '\u64A4\u9500',

2
src/components/Container/src/LazyContainer.vue

@ -112,7 +112,7 @@ function initIntersectionObserver() {
root: toRef(props, 'viewport'), root: toRef(props, 'viewport'),
}) })
} }
catch (e) { catch {
init() init()
} }
} }

8
src/components/Container/src/collapse/CollapseContainer.vue

@ -72,12 +72,12 @@ export default defineComponent({
<CollapseTransition enable={props.canExpan}> <CollapseTransition enable={props.canExpan}>
{props.loading {props.loading
? ( ? (
<Skeleton active={props.loading} /> <Skeleton active={props.loading} />
) )
: ( : (
<div class={`${prefixCls}__body`} v-show={show.value}> <div class={`${prefixCls}__body`} v-show={show.value}>
{slots.default?.()} {slots.default?.()}
</div> </div>
)} )}
</CollapseTransition> </CollapseTransition>
</div> </div>

2
src/components/ContextMenu/src/createContextMenu.ts

@ -49,7 +49,7 @@ export const createContextMenu = function (options: CreateContextOptions) {
try { try {
dom && body.removeChild(dom) dom && body.removeChild(dom)
} }
catch (error) {} catch {}
}) })
body.removeEventListener('click', handleClick) body.removeEventListener('click', handleClick)
body.removeEventListener('scroll', handleClick) body.removeEventListener('scroll', handleClick)

4
src/components/CronTab/index.ts

@ -1,4 +0,0 @@
export { default as CronTab } from './src/CronTabInput.vue'
export { default as CronTabInner } from './src/CronTabInner.vue'
export { default as CronTabModal } from './src/CronTabModal.vue'
export { default as CronValidator } from './src/validator'

360
src/components/CronTab/src/CronTabInner.vue

@ -1,360 +0,0 @@
<script lang="ts" setup>
import { computed, provide, reactive, ref, watch } from 'vue'
import { Col, Divider, Input, Row, TabPane, Tabs, Textarea, Tooltip } from 'ant-design-vue'
import CronParser from 'cron-parser'
import SecondUI from './tabs/SecondUI.vue'
import MinuteUI from './tabs/MinuteUI.vue'
import HourUI from './tabs/HourUI.vue'
import DayUI from './tabs/DayUI.vue'
import MonthUI from './tabs/MonthUI.vue'
import WeekUI from './tabs/WeekUI.vue'
import YearUI from './tabs/YearUI.vue'
import { cronEmits, cronProps } from './cron.data'
import { useDesign } from '@/hooks/web/useDesign'
import { dateFormat } from '@/utils/dateUtil'
import { simpleDebounce } from '@/utils'
const props = defineProps({ ...cronProps })
const emit = defineEmits([...cronEmits])
const { prefixCls } = useDesign('cron-inner')
provide('prefixCls', prefixCls)
const activeKey = ref(props.hideSecond ? 'minute' : 'second')
const second = ref('*')
const minute = ref('*')
const hour = ref('*')
const day = ref('*')
const month = ref('*')
const week = ref('?')
const year = ref('*')
const inputValues = reactive({
second: '',
minute: '',
hour: '',
day: '',
month: '',
week: '',
year: '',
cron: '',
})
const preTimeList = ref('执行预览,会忽略年份参数。')
// cron
const cronValueInner = computed(() => {
const result: string[] = []
if (!props.hideSecond)
result.push(second.value ? second.value : '*')
result.push(minute.value ? minute.value : '*')
result.push(hour.value ? hour.value : '*')
result.push(day.value ? day.value : '*')
result.push(month.value ? month.value : '*')
result.push(week.value ? week.value : '?')
if (!props.hideYear && !props.hideSecond)
result.push(year.value ? year.value : '*')
return result.join(' ')
})
//
const cronValueNoYear = computed(() => {
const v = cronValueInner.value
if (props.hideYear || props.hideSecond)
return v
const vs = v.split(' ')
if (vs.length >= 6) {
// Quartz
vs[5] = convertWeekToQuartz(vs[5])
}
return vs.slice(0, vs.length - 1).join(' ')
})
const calTriggerList = simpleDebounce(calTriggerListInner, 500)
watch(
() => props.value,
(newVal) => {
if (newVal === cronValueInner.value)
return
formatValue()
},
)
watch(cronValueInner, (newValue) => {
calTriggerList()
emitValue(newValue)
assignInput()
})
assignInput()
formatValue()
calTriggerListInner()
function assignInput() {
inputValues.second = second.value
inputValues.minute = minute.value
inputValues.hour = hour.value
inputValues.day = day.value
inputValues.month = month.value
inputValues.week = week.value
inputValues.year = year.value
inputValues.cron = cronValueInner.value
}
function formatValue() {
if (!props.value)
return
const values = props.value.split(' ').filter(item => !!item)
if (!values || values.length <= 0)
return
let i = 0
if (!props.hideSecond)
second.value = values[i++]
if (values.length > i)
minute.value = values[i++]
if (values.length > i)
hour.value = values[i++]
if (values.length > i)
day.value = values[i++]
if (values.length > i)
month.value = values[i++]
if (values.length > i)
week.value = values[i++]
if (values.length > i)
year.value = values[i]
assignInput()
}
// Quartz
// 1 = 2 = 3 = 4 = 5 = 6 = 7 =
function convertWeekToQuartz(week: string) {
const convert = (v: string) => {
if (v === '0')
return '1'
if (v === '1')
return '0'
return (Number.parseInt(v) - 1).toString()
}
// 1-7 or 1/7
const patten1 = /^([0-7])([-/])([0-7])$/
// 1,4,7
const patten2 = /^([0-7])(,[0-7])+$/
if (/^[0-7]$/.test(week)) {
return convert(week)
}
else if (patten1.test(week)) {
return week.replace(patten1, (_$0, before, separator, after) => {
if (separator === '/')
return convert(before) + separator + after
else
return convert(before) + separator + convert(after)
})
}
else if (patten2.test(week)) {
return week
.split(',')
.map(v => convert(v))
.join(',')
}
return week
}
function calTriggerListInner() {
//
if (props.remote) {
props.remote(cronValueInner.value, +new Date(), (v) => {
preTimeList.value = v
})
return
}
const format = 'yyyy-MM-dd hh:mm:ss'
const options = {
currentDate: dateFormat(new Date(), format),
}
const iter = CronParser.parseExpression(cronValueNoYear.value, options)
const result: string[] = []
for (let i = 1; i <= 10; i++)
result.push(dateFormat(new Date(iter.next() as any), format))
preTimeList.value = result.length > 0 ? result.join('\n') : '无执行时间'
}
function onInputBlur() {
second.value = inputValues.second
minute.value = inputValues.minute
hour.value = inputValues.hour
day.value = inputValues.day
month.value = inputValues.month
week.value = inputValues.week
year.value = inputValues.year
}
function onInputCronBlur(event) {
emitValue(event.target.value)
}
function emitValue(value) {
emit('change', value)
emit('update:value', value)
}
</script>
<template>
<div :class="`${prefixCls}`">
<div class="content">
<Tabs v-model:activeKey="activeKey" size="small">
<TabPane v-if="!hideSecond" key="second" tab="秒">
<SecondUI v-model:value="second" :disabled="disabled" />
</TabPane>
<TabPane key="minute" tab="分">
<MinuteUI v-model:value="minute" :disabled="disabled" />
</TabPane>
<TabPane key="hour" tab="时">
<HourUI v-model:value="hour" :disabled="disabled" />
</TabPane>
<TabPane key="day" tab="日">
<DayUI v-model:value="day" :week="week" :disabled="disabled" />
</TabPane>
<TabPane key="month" tab="月">
<MonthUI v-model:value="month" :disabled="disabled" />
</TabPane>
<TabPane key="week" tab="周">
<WeekUI v-model:value="week" :day="day" :disabled="disabled" />
</TabPane>
<TabPane v-if="!hideYear && !hideSecond" key="year" tab="年">
<YearUI v-model:value="year" :disabled="disabled" />
</TabPane>
</Tabs>
<Divider />
<!-- 执行时间预览 -->
<Row :gutter="8">
<Col :span="18" style="margin-top: 22px">
<Row :gutter="8">
<Col :span="8" style="margin-bottom: 12px">
<Input v-model:value="inputValues.second" @blur="onInputBlur">
<template #addonBefore>
<span class="allow-click" @click="activeKey = 'second'"></span>
</template>
</Input>
</Col>
<Col :span="8" style="margin-bottom: 12px">
<Input v-model:value="inputValues.minute" @blur="onInputBlur">
<template #addonBefore>
<span class="allow-click" @click="activeKey = 'minute'"></span>
</template>
</Input>
</Col>
<Col :span="8" style="margin-bottom: 12px">
<Input v-model:value="inputValues.hour" @blur="onInputBlur">
<template #addonBefore>
<span class="allow-click" @click="activeKey = 'hour'"></span>
</template>
</Input>
</Col>
<Col :span="8" style="margin-bottom: 12px">
<Input v-model:value="inputValues.day" @blur="onInputBlur">
<template #addonBefore>
<span class="allow-click" @click="activeKey = 'day'"></span>
</template>
</Input>
</Col>
<Col :span="8" style="margin-bottom: 12px">
<Input v-model:value="inputValues.month" @blur="onInputBlur">
<template #addonBefore>
<span class="allow-click" @click="activeKey = 'month'"></span>
</template>
</Input>
</Col>
<Col :span="8" style="margin-bottom: 12px">
<Input v-model:value="inputValues.week" @blur="onInputBlur">
<template #addonBefore>
<span class="allow-click" @click="activeKey = 'week'"></span>
</template>
</Input>
</Col>
<Col :span="8">
<Input v-model:value="inputValues.year" @blur="onInputBlur">
<template #addonBefore>
<span class="allow-click" @click="activeKey = 'year'"></span>
</template>
</Input>
</Col>
<Col :span="16">
<Input v-model:value="inputValues.cron" @blur="onInputCronBlur">
<template #addonBefore>
<Tooltip title="Cron表达式">
</Tooltip>
</template>
</Input>
</Col>
</Row>
</Col>
<Col :span="6">
<div>近十次执行时间不含年</div>
<Textarea :value="preTimeList" :rows="5" />
</Col>
</Row>
</div>
</div>
</template>
<style lang="less">
@prefix-cls: ~'@{namespace}-cron-inner';
.@{prefix-cls} {
.content {
.ant-checkbox-wrapper + .ant-checkbox-wrapper {
margin-left: 0;
}
}
&-config-list {
margin: 0 10px 10px;
text-align: left;
.item {
margin-top: 5px;
font-size: 14px;
span {
padding: 0 2px;
}
}
.choice {
padding: 5px 8px;
}
.w60 {
width: 60px;
min-width: 60px;
}
.w80 {
width: 80px;
min-width: 80px;
}
.list {
margin: 0 20px;
}
.list-check-item {
width: 4em;
padding: 1px 3px;
}
.list-cn .list-check-item {
width: 5em;
}
.tip-info {
color: #999;
}
}
.allow-click {
cursor: pointer;
}
}
</style>

55
src/components/CronTab/src/CronTabInput.vue

@ -1,55 +0,0 @@
<script lang="ts" setup>
import { ref, watch } from 'vue'
import { Input } from 'ant-design-vue'
import CronTabModal from './CronTabModal.vue'
import { cronEmits, cronProps } from './cron.data'
import { useModal } from '@/components/Modal'
import { propTypes } from '@/utils/propTypes'
const props = defineProps({
...cronProps,
placeholder: propTypes.string.def('请输入cron表达式'),
exeStartTime: propTypes.oneOfType([propTypes.number, propTypes.string, propTypes.object]).def(0),
})
const emit = defineEmits([...cronEmits])
const [registerModal, { openModal }] = useModal()
const editCronValue = ref(props.value)
watch(
() => props.value,
(newVal) => {
if (newVal !== editCronValue.value)
editCronValue.value = newVal
},
)
watch(editCronValue, (newVal) => {
emit('change', newVal)
emit('update:value', newVal)
})
function showConfigModal() {
if (!props.disabled)
openModal()
}
</script>
<template>
<div>
<Input v-model:value="editCronValue" :placeholder="placeholder" :disabled="disabled">
<template #addonAfter>
<a class="cursor-pointer" :disabled="disabled ? 'disabled' : null" @click="showConfigModal">
<span class="i-ant-design:setting-outlined relative right-0.5 top-0.25" />
<span>选择</span>
</a>
</template>
</Input>
<CronTabModal
v-model:value="editCronValue"
:exe-start-time="exeStartTime"
:hide-year="hideYear"
:remote="remote"
:hide-second="hideSecond"
@register="registerModal"
/>
</div>
</template>

18
src/components/CronTab/src/CronTabModal.vue

@ -1,18 +0,0 @@
<script lang="ts" setup>
import CronTab from './CronTabInner.vue'
import { BasicModal, useModalInner } from '@/components/Modal'
defineOptions({ name: 'CronTabModal', inheritAttrs: false })
const [registerModal, { closeModal }] = useModalInner()
function onOk() {
closeModal()
}
</script>
<template>
<BasicModal title="Cron表达式" width="800px" @register="registerModal" @ok="onOk">
<CronTab v-bind="$attrs" />
</BasicModal>
</template>

10
src/components/CronTab/src/cron.data.ts

@ -1,10 +0,0 @@
import { propTypes } from '@/utils/propTypes'
export const cronEmits = ['change', 'update:value']
export const cronProps = {
value: propTypes.string.def(''),
disabled: propTypes.bool.def(false),
hideSecond: propTypes.bool.def(false),
hideYear: propTypes.bool.def(false),
remote: propTypes.func,
}

101
src/components/CronTab/src/tabs/DayUI.vue

@ -1,101 +0,0 @@
<script lang="ts">
import { computed, defineComponent, watch } from 'vue'
import { Checkbox, Input, Radio } from 'ant-design-vue'
import { TypeEnum, useTabEmits, useTabProps, useTabSetup } from './useTabMixin'
export default defineComponent({
name: 'DayUI',
components: { AInput: Input, Checkbox, CheckboxGroup: Checkbox.Group, Radio, RadioGroup: Radio.Group },
props: useTabProps({
defaultValue: '*',
props: {
week: { type: String, default: '?' },
},
}),
emits: useTabEmits(),
setup(props, context) {
const disabledChoice = computed(() => {
return (props.week && props.week !== '?') || props.disabled
})
const setup = useTabSetup(props, context, {
defaultValue: '*',
valueWork: 1,
minValue: 1,
maxValue: 31,
valueRange: { start: 1, end: 31 },
valueLoop: { start: 1, interval: 1 },
disabled: disabledChoice,
})
const typeWorkAttrs = computed(() => ({
disabled: setup.type.value !== TypeEnum.work || props.disabled || disabledChoice.value,
...setup.inputNumberAttrs.value,
}))
watch(
() => props.week,
() => {
setup.updateValue(disabledChoice.value ? '?' : setup.computeValue.value)
},
)
return { ...setup, typeWorkAttrs }
},
})
</script>
<template>
<div :class="`${prefixCls}-config-list`">
<RadioGroup v-model:value="type">
<div class="item">
<Radio :value="TypeEnum.unset" v-bind="beforeRadioAttrs">
不设置
</Radio>
<span class="tip-info">日和周只能设置其中之一</span>
</div>
<div class="item">
<Radio :value="TypeEnum.every" v-bind="beforeRadioAttrs">
每日
</Radio>
</div>
<div class="item">
<Radio :value="TypeEnum.range" v-bind="beforeRadioAttrs">
区间
</Radio>
<span> </span>
<AInput v-model:value="valueRange.start" type="number" v-bind="typeRangeAttrs" />
<span> </span>
<AInput v-model:value="valueRange.end" type="number" v-bind="typeRangeAttrs" />
<span> </span>
</div>
<div class="item">
<Radio :value="TypeEnum.loop" v-bind="beforeRadioAttrs">
循环
</Radio>
<span> </span>
<AInput v-model:value="valueLoop.start" type="number" class="w-4" v-bind="typeLoopAttrs" />
<span> 日开始间隔 </span>
<AInput v-model:value="valueLoop.interval" type="number" v-bind="typeLoopAttrs" />
<span> </span>
</div>
<div class="item">
<Radio :value="TypeEnum.last" v-bind="beforeRadioAttrs">
最后一日
</Radio>
</div>
<div class="item">
<Radio :value="TypeEnum.specify" v-bind="beforeRadioAttrs">
指定
</Radio>
<div class="list">
<CheckboxGroup v-model:value="valueList">
<template v-for="i in specifyRange" :key="i">
<Checkbox :value="i" v-bind="typeSpecifyAttrs">
{{ i }}
</Checkbox>
</template>
</CheckboxGroup>
</div>
</div>
</RadioGroup>
</div>
</template>

69
src/components/CronTab/src/tabs/HourUI.vue

@ -1,69 +0,0 @@
<script lang="ts">
import { defineComponent } from 'vue'
import { Checkbox, Input, Radio } from 'ant-design-vue'
import { useTabEmits, useTabProps, useTabSetup } from './useTabMixin'
export default defineComponent({
name: 'HourUI',
components: { AInput: Input, Checkbox, CheckboxGroup: Checkbox.Group, Radio, RadioGroup: Radio.Group },
props: useTabProps({
defaultValue: '*',
}),
emits: useTabEmits(),
setup(props, context) {
return useTabSetup(props, context, {
defaultValue: '*',
minValue: 0,
maxValue: 23,
valueRange: { start: 0, end: 23 },
valueLoop: { start: 0, interval: 1 },
})
},
})
</script>
<template>
<div :class="`${prefixCls}-config-list`">
<RadioGroup v-model:value="type">
<div class="item">
<Radio :value="TypeEnum.every" v-bind="beforeRadioAttrs">
每时
</Radio>
</div>
<div class="item">
<Radio :value="TypeEnum.range" v-bind="beforeRadioAttrs">
区间
</Radio>
<span> </span>
<AInput v-model:value="valueRange.start" type="number" v-bind="typeRangeAttrs" />
<span> </span>
<AInput v-model:value="valueRange.end" type="number" v-bind="typeRangeAttrs" />
<span> </span>
</div>
<div class="item">
<Radio :value="TypeEnum.loop" v-bind="beforeRadioAttrs">
循环
</Radio>
<span> </span>
<AInput v-model:value="valueLoop.start" type="number" v-bind="typeLoopAttrs" />
<span> 时开始间隔 </span>
<AInput v-model:value="valueLoop.interval" type="number" v-bind="typeLoopAttrs" />
<span> </span>
</div>
<div class="item">
<Radio :value="TypeEnum.specify" v-bind="beforeRadioAttrs">
指定
</Radio>
<div class="list">
<CheckboxGroup v-model:value="valueList">
<template v-for="i in specifyRange" :key="i">
<Checkbox :value="i" v-bind="typeSpecifyAttrs">
{{ i }}
</Checkbox>
</template>
</CheckboxGroup>
</div>
</div>
</RadioGroup>
</div>
</template>

69
src/components/CronTab/src/tabs/MinuteUI.vue

@ -1,69 +0,0 @@
<script lang="ts">
import { defineComponent } from 'vue'
import { Checkbox, Input, Radio } from 'ant-design-vue'
import { useTabEmits, useTabProps, useTabSetup } from './useTabMixin'
export default defineComponent({
name: 'MinuteUI',
components: { AInput: Input, Checkbox, CheckboxGroup: Checkbox.Group, Radio, RadioGroup: Radio.Group },
props: useTabProps({
defaultValue: '*',
}),
emits: useTabEmits(),
setup(props, context) {
return useTabSetup(props, context, {
defaultValue: '*',
minValue: 0,
maxValue: 59,
valueRange: { start: 0, end: 59 },
valueLoop: { start: 0, interval: 1 },
})
},
})
</script>
<template>
<div :class="`${prefixCls}-config-list`">
<RadioGroup v-model:value="type">
<div class="item">
<Radio :value="TypeEnum.every" v-bind="beforeRadioAttrs">
每分
</Radio>
</div>
<div class="item">
<Radio :value="TypeEnum.range" v-bind="beforeRadioAttrs">
区间
</Radio>
<span> </span>
<AInput v-model:value="valueRange.start" type="number" v-bind="typeRangeAttrs" />
<span> </span>
<AInput v-model:value="valueRange.end" type="number" v-bind="typeRangeAttrs" />
<span> </span>
</div>
<div class="item">
<Radio :value="TypeEnum.loop" v-bind="beforeRadioAttrs">
循环
</Radio>
<span> </span>
<AInput v-model:value="valueLoop.start" type="number" v-bind="typeLoopAttrs" />
<span> 分开始间隔 </span>
<AInput v-model:value="valueLoop.interval" type="number" v-bind="typeLoopAttrs" />
<span> </span>
</div>
<div class="item">
<Radio :value="TypeEnum.specify" v-bind="beforeRadioAttrs">
指定
</Radio>
<div class="list">
<CheckboxGroup v-model:value="valueList">
<template v-for="i in specifyRange" :key="i">
<Checkbox :value="i" v-bind="typeSpecifyAttrs">
{{ i }}
</Checkbox>
</template>
</CheckboxGroup>
</div>
</div>
</RadioGroup>
</div>
</template>

69
src/components/CronTab/src/tabs/MonthUI.vue

@ -1,69 +0,0 @@
<script lang="ts">
import { defineComponent } from 'vue'
import { Checkbox, Input, Radio } from 'ant-design-vue'
import { useTabEmits, useTabProps, useTabSetup } from './useTabMixin'
export default defineComponent({
name: 'MonthUI',
components: { AInput: Input, Checkbox, CheckboxGroup: Checkbox.Group, Radio, RadioGroup: Radio.Group },
props: useTabProps({
defaultValue: '*',
}),
emits: useTabEmits(),
setup(props, context) {
return useTabSetup(props, context, {
defaultValue: '*',
minValue: 1,
maxValue: 12,
valueRange: { start: 1, end: 12 },
valueLoop: { start: 1, interval: 1 },
})
},
})
</script>
<template>
<div :class="`${prefixCls}-config-list`">
<RadioGroup v-model:value="type">
<div class="item">
<Radio :value="TypeEnum.every" v-bind="beforeRadioAttrs">
每月
</Radio>
</div>
<div class="item">
<Radio :value="TypeEnum.range" v-bind="beforeRadioAttrs">
区间
</Radio>
<span> </span>
<AInput v-model:value="valueRange.start" type="number" v-bind="typeRangeAttrs" />
<span> </span>
<AInput v-model:value="valueRange.end" type="number" v-bind="typeRangeAttrs" />
<span> </span>
</div>
<div class="item">
<Radio :value="TypeEnum.loop" v-bind="beforeRadioAttrs">
循环
</Radio>
<span> </span>
<AInput v-model:value="valueLoop.start" type="number" v-bind="typeLoopAttrs" />
<span> 月开始间隔 </span>
<AInput v-model:value="valueLoop.interval" type="number" v-bind="typeLoopAttrs" />
<span> </span>
</div>
<div class="item">
<Radio :value="TypeEnum.specify" v-bind="beforeRadioAttrs">
指定
</Radio>
<div class="list">
<CheckboxGroup v-model:value="valueList">
<template v-for="i in specifyRange" :key="i">
<Checkbox :value="i" v-bind="typeSpecifyAttrs">
{{ i }}
</Checkbox>
</template>
</CheckboxGroup>
</div>
</div>
</RadioGroup>
</div>
</template>

69
src/components/CronTab/src/tabs/SecondUI.vue

@ -1,69 +0,0 @@
<script lang="ts">
import { defineComponent } from 'vue'
import { Checkbox, Input, Radio } from 'ant-design-vue'
import { useTabEmits, useTabProps, useTabSetup } from './useTabMixin'
export default defineComponent({
name: 'SecondUI',
components: { AInput: Input, Checkbox, CheckboxGroup: Checkbox.Group, Radio, RadioGroup: Radio.Group },
props: useTabProps({
defaultValue: '*',
}),
emits: useTabEmits(),
setup(props, context) {
return useTabSetup(props, context, {
defaultValue: '*',
minValue: 0,
maxValue: 59,
valueRange: { start: 0, end: 59 },
valueLoop: { start: 0, interval: 1 },
})
},
})
</script>
<template>
<div :class="`${prefixCls}-config-list`">
<RadioGroup v-model:value="type">
<div class="item">
<Radio :value="TypeEnum.every" v-bind="beforeRadioAttrs">
每秒
</Radio>
</div>
<div class="item">
<Radio :value="TypeEnum.range" v-bind="beforeRadioAttrs">
区间
</Radio>
<span> </span>
<AInput v-model:value="valueRange.start" type="number" v-bind="typeRangeAttrs" />
<span> </span>
<AInput v-model:value="valueRange.end" type="number" v-bind="typeRangeAttrs" />
<span> </span>
</div>
<div class="item">
<Radio :value="TypeEnum.loop" v-bind="beforeRadioAttrs">
循环
</Radio>
<span> </span>
<AInput v-model:value="valueLoop.start" type="number" v-bind="typeLoopAttrs" />
<span> 秒开始间隔 </span>
<AInput v-model:value="valueLoop.interval" type="number" v-bind="typeLoopAttrs" />
<span> </span>
</div>
<div class="item">
<Radio :value="TypeEnum.specify" v-bind="beforeRadioAttrs">
指定
</Radio>
<div class="list">
<CheckboxGroup v-model:value="valueList">
<template v-for="i in specifyRange" :key="i">
<Checkbox :value="i" v-bind="typeSpecifyAttrs">
{{ i }}
</Checkbox>
</template>
</CheckboxGroup>
</div>
</div>
</RadioGroup>
</div>
</template>

135
src/components/CronTab/src/tabs/WeekUI.vue

@ -1,135 +0,0 @@
<script lang="ts">
import { computed, defineComponent, watch } from 'vue'
import { Checkbox, Input, Radio, Select } from 'ant-design-vue'
import { TypeEnum, useTabEmits, useTabProps, useTabSetup } from './useTabMixin'
const WEEK_MAP_EN = {
1: 'SUN',
2: 'MON',
3: 'TUE',
4: 'WED',
5: 'THU',
6: 'FRI',
7: 'SAT',
}
const WEEK_MAP_CN = {
1: '周日',
2: '周一',
3: '周二',
4: '周三',
5: '周四',
6: '周五',
7: '周六',
}
export default defineComponent({
name: 'WeekUI',
components: { AInput: Input, ASelect: Select, Checkbox, CheckboxGroup: Checkbox.Group, Radio, RadioGroup: Radio.Group },
props: useTabProps({
defaultValue: '?',
props: {
day: { type: String, default: '*' },
},
}),
emits: useTabEmits(),
setup(props, context) {
const disabledChoice = computed(() => {
return (props.day && props.day !== '?') || props.disabled
})
const setup = useTabSetup(props, context, {
defaultType: TypeEnum.unset,
defaultValue: '?',
minValue: 1,
maxValue: 7,
// 0,7 1
valueRange: { start: 1, end: 7 },
valueLoop: { start: 2, interval: 1 },
disabled: disabledChoice,
})
const weekOptions = computed(() => {
const options: { label: string, value: number }[] = []
for (const weekKey of Object.keys(WEEK_MAP_CN)) {
const weekName: string = WEEK_MAP_CN[weekKey]
options.push({
value: Number.parseInt(weekKey),
label: weekName,
})
}
return options
})
const typeRangeSelectAttrs = computed(() => ({
class: ['w80'],
disabled: setup.typeRangeAttrs.value.disabled,
}))
const typeLoopSelectAttrs = computed(() => ({
class: ['w80'],
disabled: setup.typeLoopAttrs.value.disabled,
}))
watch(
() => props.day,
() => {
setup.updateValue(disabledChoice.value ? '?' : setup.computeValue.value)
},
)
return {
...setup,
weekOptions,
typeLoopSelectAttrs,
typeRangeSelectAttrs,
WEEK_MAP_CN,
WEEK_MAP_EN,
}
},
})
</script>
<template>
<div :class="`${prefixCls}-config-list`">
<RadioGroup v-model:value="type">
<div class="item">
<Radio :value="TypeEnum.unset" v-bind="beforeRadioAttrs">
不设置
</Radio>
<span class="tip-info">日和周只能设置其中之一</span>
</div>
<div class="item">
<Radio :value="TypeEnum.range" v-bind="beforeRadioAttrs">
区间
</Radio>
<span> </span>
<ASelect v-model:value="valueRange.start" :options="weekOptions" v-bind="typeRangeSelectAttrs" />
<span> </span>
<ASelect v-model:value="valueRange.end" :options="weekOptions" v-bind="typeRangeSelectAttrs" />
</div>
<div class="item">
<Radio :value="TypeEnum.loop" v-bind="beforeRadioAttrs">
循环
</Radio>
<span> </span>
<ASelect v-model:value="valueLoop.start" :options="weekOptions" v-bind="typeLoopSelectAttrs" />
<span> 开始间隔 </span>
<AInput v-model:value="valueLoop.interval" type="number" v-bind="typeLoopAttrs" />
<span> </span>
</div>
<div class="item">
<Radio :value="TypeEnum.specify" v-bind="beforeRadioAttrs">
指定
</Radio>
<div class="list list-cn">
<CheckboxGroup v-model:value="valueList">
<template v-for="opt in weekOptions" :key="opt.value">
<Checkbox :value="opt.value" v-bind="typeSpecifyAttrs">
{{ opt.label }}
</Checkbox>
</template>
</CheckboxGroup>
</div>
</div>
</RadioGroup>
</div>
</template>

55
src/components/CronTab/src/tabs/YearUI.vue

@ -1,55 +0,0 @@
<script lang="ts">
import { defineComponent } from 'vue'
import { Input, Radio } from 'ant-design-vue'
import { useTabEmits, useTabProps, useTabSetup } from './useTabMixin'
export default defineComponent({
name: 'YearUI',
components: { AInput: Input, Radio, RadioGroup: Radio.Group },
props: useTabProps({
defaultValue: '*',
}),
emits: useTabEmits(),
setup(props, context) {
const nowYear = new Date().getFullYear()
return useTabSetup(props, context, {
defaultValue: '*',
minValue: 0,
valueRange: { start: nowYear, end: nowYear + 100 },
valueLoop: { start: nowYear, interval: 1 },
})
},
})
</script>
<template>
<div :class="`${prefixCls}-config-list`">
<RadioGroup v-model:value="type">
<div class="item">
<Radio :value="TypeEnum.every" v-bind="beforeRadioAttrs">
每年
</Radio>
</div>
<div class="item">
<Radio :value="TypeEnum.range" v-bind="beforeRadioAttrs">
区间
</Radio>
<span> </span>
<AInput v-model:value="valueRange.start" type="number" class="w80" v-bind="typeRangeAttrs" />
<span> </span>
<AInput v-model:value="valueRange.end" type="number" class="w80" v-bind="typeRangeAttrs" />
<span> </span>
</div>
<div class="item">
<Radio :value="TypeEnum.loop" v-bind="beforeRadioAttrs">
循环
</Radio>
<span> </span>
<AInput v-model:value="valueLoop.start" type="number" class="w80" v-bind="typeLoopAttrs" />
<span> 年开始间隔 </span>
<AInput v-model:value="valueLoop.interval" type="number" class="w80" v-bind="typeLoopAttrs" />
<span> </span>
</div>
</RadioGroup>
</div>
</template>

204
src/components/CronTab/src/tabs/useTabMixin.ts

@ -1,204 +0,0 @@
// 主要用于日和星期的互斥使用
import { computed, inject, reactive, ref, unref, watch } from 'vue'
import { propTypes } from '@/utils/propTypes'
export enum TypeEnum {
unset = 'UNSET',
every = 'EVERY',
range = 'RANGE',
loop = 'LOOP',
work = 'WORK',
last = 'LAST',
specify = 'SPECIFY',
}
// use 公共 props
export function useTabProps(options) {
const defaultValue = options?.defaultValue ?? '?'
return {
value: propTypes.string.def(defaultValue),
disabled: propTypes.bool.def(false),
...options?.props,
}
}
// use 公共 emits
export function useTabEmits() {
return ['change', 'update:value']
}
// use 公共 setup
export function useTabSetup(props, context, options) {
const { emit } = context
const prefixCls = inject('prefixCls')
const defaultValue = ref(options?.defaultValue ?? '?')
// 类型
const type = ref(options.defaultType ?? TypeEnum.every)
const valueList = ref<any[]>([])
// 对于不同的类型,所定义的值也有所不同
const valueRange = reactive(options.valueRange)
const valueLoop = reactive(options.valueLoop)
const valueWeek = reactive(options.valueWeek)
const valueWork = ref(options.valueWork)
const maxValue = ref(options.maxValue)
const minValue = ref(options.minValue)
// 根据不同的类型计算出的value
const computeValue = computed(() => {
const valueArray: any[] = []
switch (type.value) {
case TypeEnum.unset:
valueArray.push('?')
break
case TypeEnum.every:
valueArray.push('*')
break
case TypeEnum.range:
valueArray.push(`${valueRange.start}-${valueRange.end}`)
break
case TypeEnum.loop:
valueArray.push(`${valueLoop.start}/${valueLoop.interval}`)
break
case TypeEnum.work:
valueArray.push(`${valueWork.value}W`)
break
case TypeEnum.last:
valueArray.push('L')
break
case TypeEnum.specify:
if (valueList.value.length === 0)
valueList.value.push(minValue.value)
valueArray.push(valueList.value.join(','))
break
default:
valueArray.push(defaultValue.value)
break
}
return valueArray.length > 0 ? valueArray.join('') : defaultValue.value
})
// 指定值范围区间,介于最小值和最大值之间
const specifyRange = computed(() => {
const range: number[] = []
if (maxValue.value != null) {
for (let i = minValue.value; i <= maxValue.value; i++)
range.push(i)
}
return range
})
watch(
() => props.value,
(val) => {
if (val !== computeValue.value)
parseValue(val)
},
{ immediate: true },
)
watch(computeValue, v => updateValue(v))
function updateValue(value) {
emit('change', value)
emit('update:value', value)
}
/**
* parseValue
* @param value
*/
function parseValue(value) {
if (value === computeValue.value)
return
try {
if (!value || value === defaultValue.value) {
type.value = TypeEnum.every
}
else if (value.includes('?')) {
type.value = TypeEnum.unset
}
else if (value.includes('-')) {
type.value = TypeEnum.range
const values = value.split('-')
if (values.length >= 2) {
valueRange.start = Number.parseInt(values[0])
valueRange.end = Number.parseInt(values[1])
}
}
else if (value.includes('/')) {
type.value = TypeEnum.loop
const values = value.split('/')
if (values.length >= 2) {
valueLoop.start = value[0] === '*' ? 0 : Number.parseInt(values[0])
valueLoop.interval = Number.parseInt(values[1])
}
}
else if (value.includes('W')) {
type.value = TypeEnum.work
const values = value.split('W')
if (!values[0] && !Number.isNaN(values[0]))
valueWork.value = Number.parseInt(values[0])
}
else if (value.includes('L')) {
type.value = TypeEnum.last
}
else if (value.includes(',') || !Number.isNaN(value)) {
type.value = TypeEnum.specify
valueList.value = value.split(',').map(item => Number.parseInt(item))
}
else {
type.value = TypeEnum.every
}
}
catch (e) {
type.value = TypeEnum.every
}
}
const beforeRadioAttrs = computed(() => ({
class: ['choice'],
disabled: props.disabled || unref(options.disabled),
}))
const inputNumberAttrs = computed(() => ({
class: ['w60'],
max: maxValue.value,
min: minValue.value,
precision: 0,
}))
const typeRangeAttrs = computed(() => ({
disabled: type.value !== TypeEnum.range || props.disabled || unref(options.disabled),
...inputNumberAttrs.value,
}))
const typeLoopAttrs = computed(() => ({
disabled: type.value !== TypeEnum.loop || props.disabled || unref(options.disabled),
...inputNumberAttrs.value,
}))
const typeSpecifyAttrs = computed(() => ({
disabled: type.value !== TypeEnum.specify || props.disabled || unref(options.disabled),
class: ['list-check-item'],
}))
return {
type,
TypeEnum,
prefixCls,
defaultValue,
valueRange,
valueLoop,
valueWeek,
valueList,
valueWork,
maxValue,
minValue,
computeValue,
specifyRange,
updateValue,
parseValue,
beforeRadioAttrs,
inputNumberAttrs,
typeRangeAttrs,
typeLoopAttrs,
typeSpecifyAttrs,
}
}

50
src/components/CronTab/src/validator.ts

@ -1,50 +0,0 @@
/* eslint-disable prefer-promise-reject-errors */
import CronParser from 'cron-parser'
import type { ValidatorRule } from 'ant-design-vue/lib/form/interface'
const cronRule: ValidatorRule = {
// eslint-disable-next-line no-empty-pattern
validator({}, value) {
// 没填写就不校验
if (!value)
return Promise.resolve()
const values: string[] = value.split(' ').filter(item => !!item)
if (values.length > 7)
return Promise.reject('Cron表达式最多7项!')
// 检查第7项
let val: string = value
if (values.length === 7) {
const year = values[6]
if (year !== '*' && year !== '?') {
let yearValues: string[] = []
if (year.includes('-'))
yearValues = year.split('-')
else if (year.indexOf('/'))
yearValues = year.split('/')
else
yearValues = [year]
// 判断是否都是数字
const checkYear = yearValues.some(item => Number.isNaN(Number(item)))
if (checkYear)
return Promise.reject(`Cron表达式参数[年]错误:${year}`)
}
// 取其中的前六项
val = values.slice(0, 6).join(' ')
}
// 6位 没有年
// 5位没有秒、年
try {
const iter = CronParser.parseExpression(val)
iter.next()
return Promise.resolve()
}
catch (e: any) {
return Promise.reject(`Cron表达式错误:${e}`)
}
},
}
export default cronRule.validator

2
src/components/Description/src/typing.ts

@ -36,7 +36,7 @@ export interface DescriptionProps extends DescriptionsProps {
} }
export interface DescInstance { export interface DescInstance {
setDescProps(descProps: Partial<DescriptionProps>): void setDescProps: (descProps: Partial<DescriptionProps>) => void
} }
export type Register = (descInstance: DescInstance) => void export type Register = (descInstance: DescInstance) => void

2
src/components/EllipsisText/src/_utils.ts

@ -1,7 +1,7 @@
// cancelAnimationFrame // cancelAnimationFrame
export const cancelAnimationFrame = window.cancelAnimationFrame export const cancelAnimationFrame = window.cancelAnimationFrame
// 使用 requestAnimationFrame 模拟 setTimeout 和 setInterval // 使用 requestAnimationFrame 模拟 setTimeout 和 setInterval
export function rafTimeout(fn: Function, delay = 0, interval = false): object { export function rafTimeout(fn: (...args: any) => any, delay = 0, interval = false): object {
const requestAnimationFrame const requestAnimationFrame
= typeof window !== 'undefined' ? window.requestAnimationFrame : () => {} = typeof window !== 'undefined' ? window.requestAnimationFrame : () => {}
let start: any = null let start: any = null

2
src/components/Form/src/components/FileUpload.vue

@ -264,7 +264,7 @@ function uidGenerator() {
} }
function getFileName(path) { function getFileName(path) {
if (path.lastIndexOf('\\') >= 0) { if (path.includes('\\')) {
const reg = /\\/g const reg = /\\/g
path = path.replace(reg, '/') path = path.replace(reg, '/')
} }

10
src/components/Form/src/components/FormItem.vue

@ -312,11 +312,11 @@ export default defineComponent({
const { label, helpMessage, helpComponentProps, subLabel } = props.schema const { label, helpMessage, helpComponentProps, subLabel } = props.schema
const renderLabel = subLabel const renderLabel = subLabel
? ( ? (
<span> <span>
{label} {label}
{' '} {' '}
<span class="text-secondary">{subLabel}</span> <span class="text-secondary">{subLabel}</span>
</span> </span>
) )
: ( : (
label label

5
src/components/Form/src/hooks/useFormEvents.ts

@ -165,7 +165,7 @@ export function useFormEvents({
validKeys.push(nestKey) validKeys.push(nestKey)
} }
} }
catch (e) { catch {
// key not exist // key not exist
if (isDef(defaultValueRef.value[nestKey])) if (isDef(defaultValueRef.value[nestKey]))
unref(formModel)[nestKey] = cloneDeep(unref(defaultValueRef.value[nestKey])) unref(formModel)[nestKey] = cloneDeep(unref(defaultValueRef.value[nestKey]))
@ -313,8 +313,9 @@ export function useFormEvents({
&& (!(item.field in currentFieldsValue) && (!(item.field in currentFieldsValue)
|| isNil(currentFieldsValue[item.field]) || isNil(currentFieldsValue[item.field])
|| isEmpty(currentFieldsValue[item.field])) || isEmpty(currentFieldsValue[item.field]))
) ) {
obj[item.field] = item.defaultValue obj[item.field] = item.defaultValue
}
}) })
setFieldsValue(obj) setFieldsValue(obj)
} }

4
src/components/Form/src/types/index.ts

@ -113,8 +113,6 @@ interface _CustomComponents {
ApiTransfer: ExtractPropTypes<(typeof import('../components/ApiTransfer.vue'))['default']> ApiTransfer: ExtractPropTypes<(typeof import('../components/ApiTransfer.vue'))['default']>
InputCountDown: ExtractPropTypes<(typeof import('@/components/CountDown/src/CountdownInput.vue'))['default']> InputCountDown: ExtractPropTypes<(typeof import('@/components/CountDown/src/CountdownInput.vue'))['default']>
FileUpload: ExtractPropTypes<(typeof import('../components/FileUpload.vue'))['default']> FileUpload: ExtractPropTypes<(typeof import('../components/FileUpload.vue'))['default']>
Editor: ExtractPropTypes<(typeof import('@/components/Tinymce/src/Editor.vue'))['default']>
CronTab: ExtractPropTypes<(typeof import('@/components/CronTab/src/CronTabInput.vue'))['default']>
ApiCheckboxGroup: ExtractPropTypes<(typeof import('../components/ApiCheckboxGroup.vue'))['default']> ApiCheckboxGroup: ExtractPropTypes<(typeof import('../components/ApiCheckboxGroup.vue'))['default']>
} }
@ -160,8 +158,6 @@ interface _ComponentProps {
Divider: ExtractPropTypes<(typeof import('ant-design-vue/es/divider'))['default']> Divider: ExtractPropTypes<(typeof import('ant-design-vue/es/divider'))['default']>
ApiTransfer: CustomComponents['ApiTransfer'] & ExtractPropTypes<(typeof import('ant-design-vue/es/transfer'))['default']> ApiTransfer: CustomComponents['ApiTransfer'] & ExtractPropTypes<(typeof import('ant-design-vue/es/transfer'))['default']>
FileUpload: CustomComponents['FileUpload'] & ExtractPropTypes<(typeof import('ant-design-vue/es/upload'))['default']> FileUpload: CustomComponents['FileUpload'] & ExtractPropTypes<(typeof import('ant-design-vue/es/upload'))['default']>
Editor: CustomComponents['Editor']
CronTab: CustomComponents['CronTab']
ApiCheckboxGroup: CustomComponents['ApiCheckboxGroup'] & ComponentProps['CheckboxGroup'] ApiCheckboxGroup: CustomComponents['ApiCheckboxGroup'] & ComponentProps['CheckboxGroup']
} }

2
src/components/Markdown/src/Markdown.vue

@ -132,7 +132,7 @@ function destroy() {
try { try {
vditorInstance?.destroy?.() vditorInstance?.destroy?.()
} }
catch (error) {} catch {}
vditorRef.value = null vditorRef.value = null
initedRef.value = false initedRef.value = false
} }

2
src/components/Markdown/src/MarkdownViewer.vue

@ -51,7 +51,7 @@ function destroy() {
try { try {
vditorInstance?.destroy?.() vditorInstance?.destroy?.()
} }
catch (error) {} catch {}
vditorPreviewRef.value = null vditorPreviewRef.value = null
} }

6
src/components/Modal/src/components/ModalWrapper.vue

@ -81,9 +81,11 @@ onUnmounted(() => {
async function scrollTop() { async function scrollTop() {
nextTick(() => { nextTick(() => {
const wrapperRefDom = unref(wrapperRef) const wrapperRefDom = unref(wrapperRef)
if (!wrapperRefDom) if (!wrapperRefDom) {
return return
;(wrapperRefDom as any)?.scrollTo?.(0) }
(wrapperRefDom as any)?.scrollTo?.(0)
}) })
} }

5
src/components/Preview/src/Functional.vue

@ -103,10 +103,11 @@ export default defineComponent({
// //
function initMouseWheel() { function initMouseWheel() {
const wrapEl = unref(wrapElRef) const wrapEl = unref(wrapElRef)
if (!wrapEl) if (!wrapEl) {
return return
}
;(wrapEl as any).onmousewheel = scrollFunc (wrapEl as any).onmousewheel = scrollFunc
// onmousewheelDOMMouseScroll // onmousewheelDOMMouseScroll
document.body.addEventListener('DOMMouseScroll', scrollFunc) document.body.addEventListener('DOMMouseScroll', scrollFunc)
// //

19
src/components/Table/src/BasicTable.vue

@ -71,9 +71,8 @@ const getProps = computed(() => {
const isFixedHeightPage = inject(PageWrapperFixedHeightKey, false) const isFixedHeightPage = inject(PageWrapperFixedHeightKey, false)
watchEffect(() => { watchEffect(() => {
unref(isFixedHeightPage) if (unref(isFixedHeightPage) && props.canResize)
&& props.canResize warn('\'canResize\' of BasicTable may not work in PageWrapper with \'fixedHeight\' (especially in hot updates)')
&& warn('\'canResize\' of BasicTable may not work in PageWrapper with \'fixedHeight\' (especially in hot updates)')
}) })
const { getLoading, setLoading } = useLoading(getProps) const { getLoading, setLoading } = useLoading(getProps)
@ -130,7 +129,8 @@ function handleTableChange(pagination: any, filters: any, sorter: any, extra: an
emit('change', pagination, filters, sorter) emit('change', pagination, filters, sorter)
// useTableonChange // useTableonChange
const { onChange } = unref(getProps) const { onChange } = unref(getProps)
onChange && isFunction(onChange) && onChange(pagination, filters, sorter, extra) if (onChange && isFunction(onChange))
onChange(pagination, filters, sorter, extra)
} }
const { const {
@ -331,13 +331,14 @@ emit('register', tableAction, formActions)
<slot name="bodyCell" v-bind="((data || {}) as SlotBodyCellProps<T>)" /> <slot name="bodyCell" v-bind="((data || {}) as SlotBodyCellProps<T>)" />
</template> </template>
<template #expandIcon="{ expanded, record, onExpand }"> <template #expandIcon="renderExpandIconProps">
<!-- if children is an array, render ExpandIcon --> <!-- if children is an array, render ExpandIcon -->
<ExpandIcon <ExpandIcon
:class="{ invisible: !record.children }" v-if="renderExpandIconProps"
:expanded="expanded" :class="{ invisible: !renderExpandIconProps.record.children }"
:record="record" :expanded="renderExpandIconProps.expanded"
:on-expand="onExpand" :record="renderExpandIconProps.record"
:on-expand="renderExpandIconProps.onExpand"
:load-data="loadData" :load-data="loadData"
/> />
</template> </template>

4
src/components/Table/src/components/HeaderCell.vue

@ -37,10 +37,10 @@ export default defineComponent({
<div> <div>
{getIsEdit.value {getIsEdit.value
? ( ? (
<EditTableHeaderCell>{getTitle.value}</EditTableHeaderCell> <EditTableHeaderCell>{getTitle.value}</EditTableHeaderCell>
) )
: ( : (
<span class="default-header-cell">{getTitle.value}</span> <span class="default-header-cell">{getTitle.value}</span>
)} )}
{getHelpMessage.value && ( {getHelpMessage.value && (
<BasicHelp text={getHelpMessage.value} class={`${prefixCls}__help`} /> <BasicHelp text={getHelpMessage.value} class={`${prefixCls}__help`} />

2
src/components/Table/src/components/editable/EditableCell.vue

@ -274,7 +274,7 @@ export default defineComponent({
value, value,
}) })
} }
catch (e) { catch {
result = false result = false
} }
finally { finally {

3
src/components/Table/src/components/editable/helper.ts

@ -20,8 +20,9 @@ export function createPlaceholderMessage(component: ComponentType) {
|| component.includes('Switch') || component.includes('Switch')
|| component.includes('DatePicker') || component.includes('DatePicker')
|| component.includes('TimePicker') || component.includes('TimePicker')
) ) {
return t('common.chooseText') return t('common.chooseText')
}
return '' return ''
} }

2
src/components/Table/src/hooks/useColumns.ts

@ -318,7 +318,7 @@ export function formatCell(text: string, format: CellFormat, record: Recordable,
if (isMap(format)) if (isMap(format))
return format.get(text) return format.get(text)
} }
catch (error) { catch {
return text return text
} }
} }

2
src/components/Table/src/hooks/useRender.ts

@ -111,7 +111,7 @@ export const useRender = {
const data = JSON.parse(json) const data = JSON.parse(json)
return h(JsonPreview, { data }) return h(JsonPreview, { data })
} }
catch (e) { catch {
return json return json
} }
} }

1
src/components/Table/src/hooks/useTable.ts

@ -124,7 +124,6 @@ export function useTable<T>(tableProps?: Props<T>): [
getSize: () => { getSize: () => {
return toRaw(getTableInstance().getSize()) return toRaw(getTableInstance().getSize())
}, },
// eslint-disable-next-line ts/ban-types
updateTableData: <K extends keyof T | (string & {})>(index: number, key: K, value: K extends keyof T ? T[K] : any) => { updateTableData: <K extends keyof T | (string & {})>(index: number, key: K, value: K extends keyof T ? T[K] : any) => {
return getTableInstance().updateTableData(index, key, value) return getTableInstance().updateTableData(index, key, value)
}, },

1
src/components/Table/src/props.ts

@ -129,7 +129,6 @@ export function defineTableProps<T>() {
default: null, default: null,
}, },
rowKey: { rowKey: {
// eslint-disable-next-line ts/ban-types
type: [String, Function] as PropType<keyof T | ((record: T) => keyof T) | (string & {})>, type: [String, Function] as PropType<keyof T | ((record: T) => keyof T) | (string & {})>,
default: '', default: '',
}, },

2
src/components/Table/src/types/column.ts

@ -138,7 +138,7 @@ export interface ColumnProps<T> {
* Sort function for local sort, see Array.sort's compareFunction. If you need sort buttons only, set to true * Sort function for local sort, see Array.sort's compareFunction. If you need sort buttons only, set to true
* @type boolean | Function * @type boolean | Function
*/ */
sorter?: boolean | Function sorter?: boolean | ((...args: any) => any)
/** /**
* Order of sorted values: 'ascend' 'descend' false * Order of sorted values: 'ascend' 'descend' false

9
src/components/Table/src/types/table.ts

@ -115,7 +115,6 @@ export interface TableActionType<T = Recordable> {
getRowSelection: () => TableRowSelection<EditRecordRow<T>> getRowSelection: () => TableRowSelection<EditRecordRow<T>>
getCacheColumns: () => BasicColumn[] getCacheColumns: () => BasicColumn[]
emit?: EmitType emit?: EmitType
// eslint-disable-next-line ts/ban-types
updateTableData: <K extends keyof T | (string & {})>(index: number, key: K, value: K extends keyof T ? T[K] : any) => Promise<EditRecordRow<T>> updateTableData: <K extends keyof T | (string & {})>(index: number, key: K, value: K extends keyof T ? T[K] : any) => Promise<EditRecordRow<T>>
setShowPagination: (show: boolean) => Promise<void> setShowPagination: (show: boolean) => Promise<void>
getShowPagination: () => boolean getShowPagination: () => boolean
@ -215,8 +214,6 @@ export interface BasicTableProps<T = Recordable<any>> {
// 在分页改变的时候清空选项 // 在分页改变的时候清空选项
clearSelectOnPageChange?: boolean clearSelectOnPageChange?: boolean
//
// eslint-disable-next-line ts/ban-types
rowKey?: keyof T | ((record: T) => keyof T) | (string & {}) rowKey?: keyof T | ((record: T) => keyof T) | (string & {})
// 数据 // 数据
dataSource?: T[] dataSource?: T[]
@ -273,7 +270,7 @@ export interface BasicTableProps<T = Recordable<any>> {
* Customize row expand Icon. * Customize row expand Icon.
* @type Function | VNodeChild * @type Function | VNodeChild
*/ */
expandIcon?: Function | VNodeChild | JSX.Element expandIcon?: (...args: any) => any | VNodeChild | JSX.Element
/** /**
* Whether to expand row by clicking anywhere in the whole row * Whether to expand row by clicking anywhere in the whole row
@ -291,7 +288,7 @@ export interface BasicTableProps<T = Recordable<any>> {
* Table footer renderer * Table footer renderer
* @type Function | VNodeChild * @type Function | VNodeChild
*/ */
footer?: Function | VNodeChild | JSX.Element footer?: ((...args: any) => any) | VNodeChild | JSX.Element
/** /**
* Indent size in pixels of tree data * Indent size in pixels of tree data
@ -381,7 +378,7 @@ export interface BasicTableProps<T = Recordable<any>> {
* *
* @version 1.5.4 * @version 1.5.4
*/ */
transformCellText?: Function transformCellText?: (...args: any) => any
/** /**
* Callback executed before editable cell submit value, not for row-editor * Callback executed before editable cell submit value, not for row-editor

28
src/components/Tree/src/BasicTree.vue

@ -360,11 +360,11 @@ export default defineComponent({
const titleDom = isHighlight const titleDom = isHighlight
? ( ? (
<span class={unref(getBindValues)?.blockNode ? `${bem('content')}` : ''}> <span class={unref(getBindValues)?.blockNode ? `${bem('content')}` : ''}>
<span>{title.slice(0, searchIdx)}</span> <span>{title.slice(0, searchIdx)}</span>
<span style={highlightStyle}>{searchText}</span> <span style={highlightStyle}>{searchText}</span>
<span>{title.slice(searchIdx + (searchText as string).length)}</span> <span>{title.slice(searchIdx + (searchText as string).length)}</span>
</span> </span>
) )
: ( : (
title title
@ -377,17 +377,17 @@ export default defineComponent({
<span class={`${bem('title')} pl-2`} onClick={handleClickNode.bind(null, item[keyField], item[childrenField])}> <span class={`${bem('title')} pl-2`} onClick={handleClickNode.bind(null, item[keyField], item[childrenField])}>
{slots?.title {slots?.title
? ( ? (
<> <>
{iconDom} {iconDom}
{getSlot(slots, 'title', item)} {getSlot(slots, 'title', item)}
</> </>
) )
: ( : (
<> <>
{iconDom} {iconDom}
{titleDom} {titleDom}
<span class={bem('actions')}>{renderAction(item)}</span> <span class={bem('actions')}>{renderAction(item)}</span>
</> </>
)} )}
</span> </span>
) )

2
src/hooks/setting/index.ts

@ -12,7 +12,7 @@ export function useGlobSetting(): Readonly<GlobConfig> {
VITE_GLOB_UPLOAD_URL, VITE_GLOB_UPLOAD_URL,
} = getAppEnvConfig() } = getAppEnvConfig()
if (!/[a-zA-Z\_]*/.test(VITE_GLOB_APP_SHORT_NAME)) { if (!/[a-z_]*/i.test(VITE_GLOB_APP_SHORT_NAME)) {
warn( warn(
'VITE_GLOB_APP_SHORT_NAME Variables can only be characters/underscores, please modify in the environment variables and re-running.', 'VITE_GLOB_APP_SHORT_NAME Variables can only be characters/underscores, please modify in the environment variables and re-running.',
) )

2
src/hooks/web/useContentHeight.ts

@ -53,7 +53,7 @@ export function useContentHeight(
function calcSubtractSpace(element: Element | null | undefined, direction: 'all' | 'top' | 'bottom' = 'all'): number { function calcSubtractSpace(element: Element | null | undefined, direction: 'all' | 'top' | 'bottom' = 'all'): number {
function numberPx(px: string) { function numberPx(px: string) {
return Number(px.replace(/[^\d]/g, '')) return Number(px.replace(/\D/g, ''))
} }
let subtractHeight = 0 let subtractHeight = 0
const ZERO_PX = '0px' const ZERO_PX = '0px'

18
src/hooks/web/useMessage.tsx

@ -8,15 +8,15 @@ import { useI18n } from './useI18n'
import { isString } from '@/utils/is' import { isString } from '@/utils/is'
export interface NotifyApi { export interface NotifyApi {
info(config: NotificationArgsProps): void info: (config: NotificationArgsProps) => void
success(config: NotificationArgsProps): void success: (config: NotificationArgsProps) => void
error(config: NotificationArgsProps): void error: (config: NotificationArgsProps) => void
warn(config: NotificationArgsProps): void warn: (config: NotificationArgsProps) => void
warning(config: NotificationArgsProps): void warning: (config: NotificationArgsProps) => void
open(args: NotificationArgsProps): void open: (args: NotificationArgsProps) => void
close(key: string): void close: (key: string) => void
config(options: ConfigProps): void config: (options: ConfigProps) => void
destroy(): void destroy: () => void
} }
export declare type NotificationPlacement = 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' export declare type NotificationPlacement = 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight'

2
src/hooks/web/usePermission.ts

@ -27,7 +27,7 @@ export function usePermission() {
try { try {
router.addRoute(route as unknown as RouteRecordRaw) router.addRoute(route as unknown as RouteRecordRaw)
} }
catch (e) {} catch {}
}) })
permissionStore.setLastBuildMenuTime() permissionStore.setLastBuildMenuTime()
closeAll() closeAll()

3
src/layouts/default/header/MultipleHeader.vue

@ -64,8 +64,9 @@ const getPlaceholderDomStyle = computed((): CSSProperties => {
(unref(getShowFullHeaderRef) || !unref(getSplit)) (unref(getShowFullHeaderRef) || !unref(getSplit))
&& unref(getShowHeader) && unref(getShowHeader)
&& !unref(getFullContent) && !unref(getFullContent)
) ) {
height += HEADER_HEIGHT height += HEADER_HEIGHT
}
if (unref(getShowMultipleTab) && !unref(getFullContent)) if (unref(getShowMultipleTab) && !unref(getFullContent))
height += TABS_HEIGHT height += TABS_HEIGHT

18
src/layouts/default/menu/index.vue

@ -135,17 +135,17 @@ export default defineComponent({
return null return null
return !props.isHorizontal return !props.isHorizontal
? ( ? (
<SimpleMenu {...menuProps} isSplitMenu={unref(getSplit)} items={menus} /> <SimpleMenu {...menuProps} isSplitMenu={unref(getSplit)} items={menus} />
) )
: ( : (
<BasicMenu <BasicMenu
{...(menuProps as any)} {...(menuProps as any)}
isHorizontal={props.isHorizontal} isHorizontal={props.isHorizontal}
type={unref(getMenuType)} type={unref(getMenuType)}
showLogo={unref(getIsShowLogo)} showLogo={unref(getIsShowLogo)}
mode={unref(getComputedMenuMode as any)} mode={unref(getComputedMenuMode as any)}
items={menus} items={menus}
/> />
) )
} }

4
src/logics/error-handle/index.ts

@ -19,13 +19,13 @@ function processStackMsg(error: Error) {
return '' return ''
let stack = error.stack let stack = error.stack
.replace(/\n/gi, '') // Remove line breaks to save the size of the transmitted content .replace(/\n/g, '') // Remove line breaks to save the size of the transmitted content
.replace(/\bat\b/gi, '@') // At in chrome, @ in ff .replace(/\bat\b/gi, '@') // At in chrome, @ in ff
.split('@') // Split information with @ .split('@') // Split information with @
.slice(0, 9) // The maximum stack length (Error.stackTraceLimit = 10), so only take the first 10 .slice(0, 9) // The maximum stack length (Error.stackTraceLimit = 10), so only take the first 10
.map(v => v.replace(/^\s*|\s*$/g, '')) // Remove extra spaces .map(v => v.replace(/^\s*|\s*$/g, '')) // Remove extra spaces
.join('~') // Manually add separators for later display .join('~') // Manually add separators for later display
.replace(/\?[^:]+/gi, '') // Remove redundant parameters of js file links (?x=1 and the like) .replace(/\?[^:]+/g, '') // Remove redundant parameters of js file links (?x=1 and the like)
const msg = error.toString() const msg = error.toString()
if (!stack.includes(msg)) if (!stack.includes(msg))
stack = `${msg}@${stack}` stack = `${msg}@${stack}`

4
src/router/guard/permissionGuard.ts

@ -87,7 +87,7 @@ export function createPermissionGuard(router: Router) {
try { try {
await userStore.getUserInfoAction(userInfo?.user) await userStore.getUserInfoAction(userInfo?.user)
} }
catch (err) { catch {
next() next()
return return
} }
@ -104,7 +104,7 @@ export function createPermissionGuard(router: Router) {
try { try {
router.addRoute(route as unknown as RouteRecordRaw) router.addRoute(route as unknown as RouteRecordRaw)
} }
catch (e) {} catch {}
}) })
router.addRoute(PAGE_NOT_FOUND_ROUTE as unknown as RouteRecordRaw) router.addRoute(PAGE_NOT_FOUND_ROUTE as unknown as RouteRecordRaw)

2
src/router/helper/menuHelper.ts

@ -81,7 +81,7 @@ export function transformRouteToMenu(routeModList: AppRouteModule[], routerMappi
/** /**
* config menu with given params * config menu with given params
*/ */
const menuParamRegex = /(?::)([\s\S]+?)((?=\/)|$)/g const menuParamRegex = /:([\s\S]+?)(?=\/)|$/g
export function configureDynamicParamsMenu(menu: Menu, params: RouteParams) { export function configureDynamicParamsMenu(menu: Menu, params: RouteParams) {
const { path, paramPath } = toRaw(menu) const { path, paramPath } = toRaw(menu)

2
src/store/modules/lock.ts

@ -50,7 +50,7 @@ export const useLockStore = defineStore('app-lock', {
// return res // return res
} }
catch (error) { catch {
return false return false
} }
} }

3
src/store/modules/multipleTab.ts

@ -123,8 +123,9 @@ export const useMultipleTabStore = defineStore('app-multiple-tab', {
|| path === PageEnum.BASE_LOGIN || path === PageEnum.BASE_LOGIN
|| !name || !name
|| [REDIRECT_ROUTE.name, PAGE_NOT_FOUND_ROUTE.name].includes(name as string) || [REDIRECT_ROUTE.name, PAGE_NOT_FOUND_ROUTE.name].includes(name as string)
) ) {
return return
}
let updateIndex = -1 let updateIndex = -1
// Existing pages, do not add tabs repeatedly // Existing pages, do not add tabs repeatedly

2
src/store/modules/permission.ts

@ -129,7 +129,7 @@ export const usePermissionStore = defineStore('app-permission', {
try { try {
patcher(routes) patcher(routes)
} }
catch (e) { catch {
// 已处理完毕跳出循环 // 已处理完毕跳出循环
} }
} }

4
src/store/modules/user.ts

@ -129,7 +129,7 @@ export const useUserStore = defineStore('app-user', {
try { try {
router.addRoute(route as unknown as RouteRecordRaw) router.addRoute(route as unknown as RouteRecordRaw)
} }
catch (e) {} catch {}
}) })
router.addRoute(PAGE_NOT_FOUND_ROUTE as unknown as RouteRecordRaw) router.addRoute(PAGE_NOT_FOUND_ROUTE as unknown as RouteRecordRaw)
permissionStore.setDynamicAddedRoute(true) permissionStore.setDynamicAddedRoute(true)
@ -155,7 +155,7 @@ export const useUserStore = defineStore('app-user', {
.map(i => `${i[0].toUpperCase()}${i.slice(1)}`) .map(i => `${i[0].toUpperCase()}${i.slice(1)}`)
.join('') .join('')
const component = __menu.path.replaceAll(/\/:[\s|\S]*/g, '') const component = __menu.path.replaceAll(/\/:[\s\S]*/g, '')
let isPadIndexExtension = false let isPadIndexExtension = false
if (!component.endsWith('index') && !/\/:/.test(__menu.path)) if (!component.endsWith('index') && !/\/:/.test(__menu.path))

2
src/utils/cache/storageCache.ts vendored

@ -84,7 +84,7 @@ export function createStorage({
this.remove(key) this.remove(key)
} }
catch (e) { catch {
return def return def
} }
} }

6
src/utils/cipher.ts

@ -10,13 +10,13 @@ import SHA512 from 'crypto-js/sha512'
// Define an interface for encryption // Define an interface for encryption
// 定义一个加密器的接口 // 定义一个加密器的接口
export interface Encryption { export interface Encryption {
encrypt(plainText: string): string encrypt: (plainText: string) => string
decrypt(cipherText: string): string decrypt: (cipherText: string) => string
} }
// Define an interface for Hashing // Define an interface for Hashing
// 定义一个哈希算法的接口 // 定义一个哈希算法的接口
export interface Hashing { export interface Hashing {
hash(data: string): string hash: (data: string) => string
} }
export interface EncryptionParams { export interface EncryptionParams {

2
src/utils/color.ts

@ -6,7 +6,7 @@
* @return Boolean * @return Boolean
*/ */
export function isHexColor(color: string) { export function isHexColor(color: string) {
const reg = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/ const reg = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i
return reg.test(color) return reg.test(color)
} }

22
src/utils/dateUtil.ts

@ -29,28 +29,6 @@ export function betweenDay(date1, date2) {
return Math.floor((date2.getTime() - date1.getTime()) / (24 * 3600 * 1000)) return Math.floor((date2.getTime() - date1.getTime()) / (24 * 3600 * 1000))
} }
export function formatDate(date, fmt) {
date = convertDate(date)
const o = {
'M+': date.getMonth() + 1, // 月份
'd+': date.getDate(), // 日
'H+': date.getHours(), // 小时
'm+': date.getMinutes(), // 分
's+': date.getSeconds(), // 秒
'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
'S': date.getMilliseconds(), // 毫秒
}
if (/(y+)/.test(fmt)) {
// 年份
fmt = fmt.replace(RegExp.$1, (`${date.getFullYear()}`).substr(4 - RegExp.$1.length))
}
for (const k in o) {
if (new RegExp(`(${k})`).test(fmt))
fmt = fmt.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : (`00${o[k]}`).substr((`${o[k]}`).length))
}
return fmt
}
export function addTime(date, time) { export function addTime(date, time) {
date = convertDate(date) date = convertDate(date)
return new Date(date.getTime() + time) return new Date(date.getTime() + time)

2
src/utils/domUtils.ts

@ -18,7 +18,7 @@ export function getBoundingClientRect(element: Element): DOMRect | number {
} }
function trim(string: string) { function trim(string: string) {
return (string || '').replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g, '') return (string || '').replace(/^\s+|\s+$/g, '')
} }
/* istanbul ignore next */ /* istanbul ignore next */

2
src/utils/env.ts

@ -24,7 +24,7 @@ export function getAppEnvConfig() {
VITE_GLOB_UPLOAD_URL, VITE_GLOB_UPLOAD_URL,
} = ENV } = ENV
if (!/^[a-zA-Z\_]*$/.test(VITE_GLOB_APP_SHORT_NAME)) { if (!/^[a-z_]*$/i.test(VITE_GLOB_APP_SHORT_NAME)) {
warn( warn(
'VITE_GLOB_APP_SHORT_NAME Variables can only be characters/underscores, please modify in the environment variables and re-running.', 'VITE_GLOB_APP_SHORT_NAME Variables can only be characters/underscores, please modify in the environment variables and re-running.',
) )

2
src/utils/file/download.ts

@ -59,7 +59,7 @@ export function downloadByUrl({ url, target = '_blank', fileName }: { url: strin
const isChrome = window.navigator.userAgent.toLowerCase().includes('chrome') const isChrome = window.navigator.userAgent.toLowerCase().includes('chrome')
const isSafari = window.navigator.userAgent.toLowerCase().includes('safari') const isSafari = window.navigator.userAgent.toLowerCase().includes('safari')
if (/(iP)/g.test(window.navigator.userAgent)) { if (/(iP)/.test(window.navigator.userAgent)) {
console.error('Your browser does not support download!') console.error('Your browser does not support download!')
return false return false
} }

3
src/utils/http/axios/Axios.ts

@ -234,8 +234,9 @@ export class VAxios {
contentType !== ContentTypeEnum.FORM_URLENCODED contentType !== ContentTypeEnum.FORM_URLENCODED
|| !Reflect.has(config, 'data') || !Reflect.has(config, 'data')
|| config.method?.toUpperCase() === RequestEnum.GET || config.method?.toUpperCase() === RequestEnum.GET
) ) {
return config return config
}
return { return {
...config, ...config,

6
src/utils/index.ts

@ -130,7 +130,7 @@ interface EventShim {
} }
export type WithInstall<T> = T & { export type WithInstall<T> = T & {
install(app: App): void install: (app: App) => void
} & EventShim } & EventShim
export type CustomComponent = Component & { displayName?: string } export type CustomComponent = Component & { displayName?: string }
@ -176,10 +176,10 @@ export function simpleDebounce(fn, delay = 100) {
export function toCamelCase(str: string, upperCaseFirst: boolean) { export function toCamelCase(str: string, upperCaseFirst: boolean) {
str = (str || '') str = (str || '')
.replace(/[-|\/](.)/g, (group1) => { .replace(/[-|/](.)/g, (group1) => {
return group1.toUpperCase() return group1.toUpperCase()
}) })
.replaceAll(/[-|\/]/g, '') .replaceAll(/[-|/]/g, '')
if (upperCaseFirst && str) if (upperCaseFirst && str)
str = str.charAt(0).toUpperCase() + str.slice(1) str = str.charAt(0).toUpperCase() + str.slice(1)

2
src/utils/is.ts

@ -61,6 +61,6 @@ export const isServer = typeof window === 'undefined'
export const isClient = !isServer export const isClient = !isServer
export function isHttpUrl(path: string): boolean { export function isHttpUrl(path: string): boolean {
const reg = /^http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- ./?%&=]*)?/ const reg = /^http(s)?:\/\/([\w\-]+\.)+[\w\-]+(\/[\w\- ./?%&=]*)?$/
return reg.test(path) return reg.test(path)
} }

11
src/utils/mitt.ts

@ -25,15 +25,12 @@ export type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<
export interface Emitter<Events extends Record<EventType, unknown>> { export interface Emitter<Events extends Record<EventType, unknown>> {
all: EventHandlerMap<Events> all: EventHandlerMap<Events>
on<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): void on: (<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>) => void) & ((type: '*', handler: WildcardHandler<Events>) => void)
on(type: '*', handler: WildcardHandler<Events>): void
off<Key extends keyof Events>(type: Key, handler?: Handler<Events[Key]>): void off: (<Key extends keyof Events>(type: Key, handler?: Handler<Events[Key]>) => void) & ((type: '*', handler: WildcardHandler<Events>) => void)
off(type: '*', handler: WildcardHandler<Events>): void
emit<Key extends keyof Events>(type: Key, event: Events[Key]): void emit: (<Key extends keyof Events>(type: Key, event: Events[Key]) => void) & (<Key extends keyof Events>(type: undefined extends Events[Key] ? Key : never) => void)
emit<Key extends keyof Events>(type: undefined extends Events[Key] ? Key : never): void clear: () => void
clear(): void
} }
/** /**

12
src/utils/props.ts

@ -138,13 +138,13 @@ export function buildProps<
: [O[K]] extends NativePropType : [O[K]] extends NativePropType
? O[K] ? O[K]
: O[K] extends BuildPropOption< : O[K] extends BuildPropOption<
infer T, infer T,
infer _D, infer _D,
infer R, infer R,
infer V, infer V,
infer C infer C
> >
? BuildPropReturn<T, O[K]['default'], R, V, C> ? BuildPropReturn<T, O[K]['default'], R, V, C>
: never : never
} }

2
src/utils/tree.ts

@ -268,7 +268,7 @@ export function handleTree2(data, id, parentId, children, rootId) {
// 返回每一项的子级数组 // 返回每一项的子级数组
return father[id] === child[parentId] return father[id] === child[parentId]
}) })
// eslint-disable-next-line no-unused-expressions
branchArr.length > 0 ? (father.children = branchArr) : '' branchArr.length > 0 ? (father.children = branchArr) : ''
// 返回第一层 // 返回第一层
return father[parentId] === rootId return father[parentId] === rootId

2
vite.config.ts

@ -50,7 +50,7 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
}, },
// @/xxxx => src/xxxx // @/xxxx => src/xxxx
{ {
find: /\@\//, find: /@\//,
replacement: `${pathResolve('src')}/`, replacement: `${pathResolve('src')}/`,
}, },
], ],

Loading…
Cancel
Save