Browse Source

chore: Refactor project structure

1. Remove unnecessary files
2. Upgrade ESLint to the latest version
main
刘凯 1 year ago
parent
commit
782bbfb73d
  1. 2
      .env
  2. 2
      .env.development
  3. 28
      .env.front
  4. 6
      .gitpod.yml
  5. 16
      .hintrc
  6. 9
      .prettierignore
  7. 2
      .vscode/launch.json
  8. 46
      .vscode/settings.json
  9. 2
      README.md
  10. 23
      package.json
  11. 562
      pnpm-lock.yaml
  12. 2
      src/api/base/login.ts
  13. 6
      src/components/Application/src/search/AppSearchModal.vue
  14. 6
      src/components/Container/src/LazyContainer.vue
  15. 2
      src/components/CronTab/src/tabs/WeekUI.vue
  16. 2
      src/components/Cropper/src/CopperModal.vue
  17. 2
      src/components/Cropper/src/CropperAvatar.vue
  18. 4
      src/components/Drawer/src/typing.ts
  19. 16
      src/components/Drawer/src/useDrawer.ts
  20. 6
      src/components/Form/src/BasicForm.vue
  21. 2
      src/components/Form/src/components/ApiRadioGroup.vue
  22. 2
      src/components/Form/src/components/ApiSelect.vue
  23. 10
      src/components/Form/src/components/FormItem.vue
  24. 2
      src/components/Form/src/components/RadioButtonGroup.vue
  25. 8
      src/components/Form/src/hooks/useForm.ts
  26. 4
      src/components/Form/src/hooks/useFormEvents.ts
  27. 6
      src/components/Form/src/types/form.ts
  28. 12
      src/components/Form/src/types/index.ts
  29. 34
      src/components/FormDesign/src/components/VFormDesign/components/ComponentProps.vue
  30. 2
      src/components/FormDesign/src/components/VFormDesign/components/FormNodeOperate.vue
  31. 6
      src/components/FormDesign/src/components/VFormDesign/components/ImportJsonModal.vue
  32. 12
      src/components/FormDesign/src/components/VFormDesign/components/LayoutItem.vue
  33. 7
      src/components/FormDesign/src/components/VFormDesign/modules/FormComponentPanel.vue
  34. 14
      src/components/FormDesign/src/typings/v-form-component.ts
  35. 8
      src/components/FormDesign/src/utils/index.ts
  36. 12
      src/components/Menu/src/BasicMenu.vue
  37. 16
      src/components/Modal/src/hooks/useModal.ts
  38. 20
      src/components/Preview/src/Functional.vue
  39. 12
      src/components/Preview/src/Preview.vue
  40. 12
      src/components/Preview/src/typing.ts
  41. 12
      src/components/SimpleMenu/src/components/useSimpleMenuContext.ts
  42. 4
      src/components/Table/src/BasicTable.vue
  43. 2
      src/components/Table/src/hooks/useDataSource.ts
  44. 8
      src/components/Table/src/hooks/useTable.ts
  45. 4
      src/components/Table/src/hooks/useTableScroll.ts
  46. 2
      src/components/Table/src/props.ts
  47. 6
      src/components/Table/src/types/column.ts
  48. 6
      src/components/Table/src/types/table.ts
  49. 24
      src/components/Table/src/types/tableAction.ts
  50. 2
      src/components/Tree/src/types/tree.ts
  51. 2
      src/components/Upload/src/data.tsx
  52. 2
      src/components/Verifition/src/Verify.vue
  53. 4
      src/components/Verifition/src/Verify/VerifyPoints.vue
  54. 4
      src/components/Verifition/src/Verify/VerifySlide.vue
  55. 2
      src/directives/ripple/index.ts
  56. 4
      src/layouts/default/header/MultipleHeader.vue
  57. 8
      src/layouts/default/tabs/useMultipleTabs.ts
  58. 2
      src/router/guard/permissionGuard.ts
  59. 1
      src/utils/domUtils.ts
  60. 2
      src/utils/file/download.ts
  61. 4
      src/utils/helper/treeHelper.ts
  62. 12
      src/utils/http/axios/Axios.ts
  63. 4
      src/utils/http/axios/index.ts
  64. 3
      src/utils/index.ts
  65. 2
      src/utils/props.ts
  66. 4
      src/utils/tree.ts
  67. 22
      src/views/base/login/LoginForm.vue
  68. 2
      src/views/infra/webSocket/index.vue

2
.env

@ -1,5 +1,5 @@
# 端口号
VITE_PORT = 80
VITE_PORT = 3000
# 网站标题
VITE_GLOB_APP_TITLE = 芋道管理系统

2
.env.development

@ -7,7 +7,7 @@ VITE_PUBLIC_PATH = /
# 本地开发代理,可以解决跨域及多地址代理
# 如果接口地址匹配到,则会转发到http://localhost:3000,防止本地出现跨域问题
# 可以有多个,注意多个不能换行,否则代理将会失效
VITE_PROXY = [["/dev-api","http://localhost:48080/admin-api"],["/upload","http://localhost:48080/admin-api/infra/file/upload"]]
VITE_PROXY = [["/dev-api","http://192.168.1.100:48080/admin-api"],["/upload","http://192.168.1.100:48080/admin-api/infra/file/upload"]]
# VITE_PROXY=[["/api","http://vben.xingyuv.com/test"]]
# 是否删除Console.log

28
.env.front

@ -1,28 +0,0 @@
# 本地开发环境
NODE_ENV=development
# 资源公共路径,需要以 /开头和结尾
VITE_PUBLIC_PATH = /
# 本地开发代理,可以解决跨域及多地址代理
# 如果接口地址匹配到,则会转发到http://localhost:3000,防止本地出现跨域问题
# 可以有多个,注意多个不能换行,否则代理将会失效
VITE_PROXY = [["/dev-api","http://api-dashboard.yudao.iocoder.cn/admin-api"],["/upload","http://api-dashboard.yudao.iocoder.cn/admin-api/infra/file/upload"]]
# VITE_PROXY=[["/api","http://vben.xingyuv.com/test"]]
# 是否删除Console.log
VITE_DROP_CONSOLE = false
# 基础页面地址,例如 swagger 等页面
VITE_GLOB_BASE_URL = "http://api-dashboard.yudao.iocoder.cn"
# 接口地址,如果没有跨域问题,直接在这里配置即可
VITE_GLOB_API_URL = /dev-api
# 文件上传接口 可选
VITE_GLOB_UPLOAD_URL = /upload
# 接口地址前缀,有些系统所有接口地址都有前缀,可以在这里统一加,方便切换
VITE_GLOB_API_URL_PREFIX =
# 百度统计
VITE_APP_BAIDU_CODE = eb21166668bf766b9d059a6fd1c10777

6
.gitpod.yml

@ -1,6 +0,0 @@
ports:
- port: 3344
onOpen: open-preview
tasks:
- init: pnpm install
command: pnpm run dev

16
.hintrc

@ -1,16 +0,0 @@
{
"extends": [
"development"
],
"hints": {
"compat-api/css": [
"default",
{
"ignore": [
"-webkit-tap-highlight-color",
"text-size-adjust"
]
}
]
}
}

9
.prettierignore

@ -1,9 +0,0 @@
/dist/*
.local
.output.js
/node_modules/**
**/*.svg
**/*.sh
/public/*

2
.vscode/launch.json vendored

@ -5,7 +5,7 @@
"type": "chrome",
"request": "launch",
"name": "Launch Chrome",
"url": "http://localhost:80",
"url": "http://localhost:3000",
"webRoot": "${workspaceFolder}/src",
"sourceMaps": true
}

46
.vscode/settings.json vendored

@ -2,8 +2,6 @@
"typescript.tsdk": "./node_modules/typescript/lib",
"npm.packageManager": "pnpm",
"editor.tabSize": 2,
"prettier.printWidth": 140, //
"editor.defaultFormatter": "esbenp.prettier-vscode",
"files.eol": "\n",
"search.exclude": {
"**/node_modules": true,
@ -60,8 +58,8 @@
"path-intellisense.mappings": {
"@/": "${workspaceRoot}/src"
},
"eslint.experimental.useFlatConfig": true,
"prettier.enable": false,
"eslint.experimental.useFlatConfig": true,
"editor.formatOnSave": false,
"editor.codeActionsOnSave": {
"source.fixAll": "explicit",
@ -90,35 +88,11 @@
"jsonc",
"yaml"
],
"[javascriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[css]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[less]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[scss]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[markdown]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[vue]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.organizeImports": false,
"source.fixAll.stylelint": true
"source.fixAll.eslint": "explicit",
"source.organizeImports": "never",
"source.fixAll.stylelint": "explicit"
}
},
"i18n-ally.localesPaths": ["src/locales/lang"],
@ -173,18 +147,8 @@
"yudao",
"zxcvbn"
],
//
"explorer.fileNesting.enabled": true,
"explorer.fileNesting.expand": false,
"explorer.fileNesting.patterns": {
"*.ts": "$(capture).test.ts, $(capture).test.tsx",
"*.tsx": "$(capture).test.ts, $(capture).test.tsx",
"*.env": "$(capture).env.*",
"package.json": ".hintrc,pnpm-lock.yaml,yarn.lock,LICENSE,README*,CHANGELOG*,CNAME,.gitattributes,.gitignore,stylelint.config.js,eslint.config.js,commitlint.config.js,.stylelintignore,.prettierignore,.gitpod.yml,.eslintrc.js,.eslintignore"
},
"eslint.codeAction.showDocumentation": {
"enable": true
},
"terminal.integrated.scrollback": 10000,
"nuxt.isNuxtApp": false
"terminal.integrated.scrollback": 10000
}

2
README.md

@ -2,7 +2,7 @@
**严肃声明:现在、未来都不会有商业版本,所有代码全部开源!!**
**「我喜欢写代码,乐此不疲」**
**「我喜欢写代码,乐此不疲」**
**「我喜欢做开源,以此为乐」**
如果这个项目让你有所收获,记得 Star 关注哦,这对我是非常不错的鼓励与支持。

23
package.json

@ -22,25 +22,18 @@
},
"scripts": {
"commit": "czg",
"bootstrap": "pnpm install",
"serve": "pnpm dev",
"dev": "vite",
"front": "vite --mode front",
"build": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=8192 vite build && esno ./build/script/postBuild.ts",
"build:test": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build --mode test && esno ./build/script/postBuild.ts",
"build:static": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build --mode static && esno ./build/script/postBuild.ts",
"build:no-cache": "pnpm store prune && pnpm build",
"report": "cross-env REPORT=true pnpm build",
"type:check": "vue-tsc --noEmit --skipLibCheck",
"preview": "pnpm build && vite preview",
"preview:dist": "vite preview",
"clean:cache": "rimraf node_modules/.cache/ && rimraf node_modules/.vite",
"clean:lib": "rimraf node_modules",
"preview": "vite preview",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"lint:stylelint": "stylelint \"**/*.{vue,css,less,scss}\" --fix --cache --cache-location node_modules/.cache/stylelint/",
"lint:lint-staged": "lint-staged",
"reinstall": "rimraf pnpm-lock.yaml && rimraf node_modules && npm run bootstrap",
"prepare": "husky install",
"gen:icon": "esno ./build/generate/icon/index.ts"
},
@ -82,7 +75,7 @@
"xlsx": "^0.18.5"
},
"devDependencies": {
"@antfu/eslint-config": "^1.1.1",
"@antfu/eslint-config": "^2.6.1",
"@commitlint/cli": "^18.4.1",
"@commitlint/config-conventional": "^18.4.0",
"@iconify/json": "^2.2.141",
@ -104,7 +97,7 @@
"cz-git": "^1.7.1",
"czg": "^1.7.1",
"dotenv": "^16.3.1",
"eslint": "^8.53.0",
"eslint": "^8.56.0",
"esno": "^4.0.0",
"fs-extra": "^11.1.1",
"husky": "^8.0.3",
@ -115,7 +108,6 @@
"postcss": "^8.4.31",
"postcss-html": "^1.5.0",
"postcss-less": "^6.0.0",
"prettier": "^3.1.0",
"rimraf": "^5.0.5",
"rollup": "^4.4.0",
"rollup-plugin-visualizer": "^5.9.2",
@ -143,21 +135,12 @@
"*.{js,jsx,ts,tsx}": [
"eslint --fix"
],
"{!(package)*.json,*.code-snippets,.!(browserslist)*rc}": [
"prettier --write--parser json"
],
"package.json": [
"prettier --write"
],
"*.vue": [
"eslint --fix",
"stylelint --fix"
],
"*.{scss,less,styl,html}": [
"stylelint --fix"
],
"*.md": [
"prettier --write"
]
},
"config": {

562
pnpm-lock.yaml

File diff suppressed because it is too large Load Diff

2
src/api/base/login.ts

@ -25,7 +25,7 @@ export function getTenantIdByName(name: string) {
// 使用租户域名,获得租户信息
export function getTenantByWebsite(website: string) {
return defHttp.get({ url: `/system/tenant/get-by-website?website=${website}` })
return defHttp.get({ url: `/system/tenant/get-by-website?website=${website}` }, { errorMessageMode: 'none' })
}
// 登出

6
src/components/Application/src/search/AppSearchModal.vue

@ -41,9 +41,9 @@ watch(
() => props.open,
(open: boolean) => {
open
&& nextTick(() => {
unref(inputRef)?.focus()
})
&& nextTick(() => {
unref(inputRef)?.focus()
})
},
)

6
src/components/Container/src/LazyContainer.vue

@ -66,9 +66,9 @@ onMounted(() => {
function immediateInit() {
const { timeout } = props
timeout
&& useTimeoutFn(() => {
init()
}, timeout)
&& useTimeoutFn(() => {
init()
}, timeout)
}
function init() {

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

@ -48,7 +48,7 @@ export default defineComponent({
disabled: disabledChoice,
})
const weekOptions = computed(() => {
const options: { label: string; value: number }[] = []
const options: { label: string, value: number }[] = []
for (const weekKey of Object.keys(WEEK_MAP_CN)) {
const weekName: string = WEEK_MAP_CN[weekKey]
options.push({

2
src/components/Cropper/src/CopperModal.vue

@ -22,7 +22,7 @@ const props = defineProps({
const emit = defineEmits(['uploadSuccess', 'uploadError', 'register'])
interface apiFunParams { file: Blob; name: string; filename: string }
interface apiFunParams { file: Blob, name: string, filename: string }
let filename = ''
const src = ref(props.src || '')

2
src/components/Cropper/src/CropperAvatar.vue

@ -19,7 +19,7 @@ const props = defineProps({
btnProps: { type: Object as PropType<ButtonProps> },
btnText: { type: String, default: '' },
uploadApi: {
type: Function as PropType<({ file, name }: { file: Blob; name: string }) => Promise<void>>,
type: Function as PropType<({ file, name }: { file: Blob, name: string }) => Promise<void>>,
},
size: { type: Number, default: 5 },
})

4
src/components/Drawer/src/typing.ts

@ -52,13 +52,13 @@ export interface DrawerFooterProps {
* The ok button props, follow jsx rules
* @type object
*/
okButtonProps: { props: ButtonProps; on: object }
okButtonProps: { props: ButtonProps, on: object }
/**
* The cancel button props, follow jsx rules
* @type object
*/
cancelButtonProps: { props: ButtonProps; on: object }
cancelButtonProps: { props: ButtonProps, on: object }
/**
* Whether to apply loading visual effect for OK button or not
* @default false

16
src/components/Drawer/src/useDrawer.ts

@ -23,11 +23,11 @@ export function useDrawer(): UseDrawerReturnType {
function register(drawerInstance: DrawerInstance, uuid: number) {
isProdMode()
&& tryOnUnmounted(() => {
drawer.value = null
loaded.value = null
dataTransferRef[unref(uid)] = null
})
&& tryOnUnmounted(() => {
drawer.value = null
loaded.value = null
dataTransferRef[unref(uid)] = null
})
if (unref(loaded) && isProdMode() && drawerInstance === unref(drawer))
return
@ -101,9 +101,9 @@ export function useDrawerInner(callbackFn?: Fn): UseDrawerInnerReturnType {
const register = (modalInstance: DrawerInstance, uuid: number) => {
isProdMode()
&& tryOnUnmounted(() => {
drawerInstanceRef.value = null
})
&& tryOnUnmounted(() => {
drawerInstanceRef.value = null
})
uidRef.value = uuid
drawerInstanceRef.value = modalInstance

6
src/components/Form/src/BasicForm.vue

@ -88,9 +88,9 @@ const getSchema = computed((): FormSchema[] => {
// handle date type
if (
isHandleDateDefaultValue
&& defaultValue
&& component
&& dateItemType.includes(component)
&& defaultValue
&& component
&& dateItemType.includes(component)
) {
if (!Array.isArray(defaultValue)) {
schema.defaultValue = valueFormat

2
src/components/Form/src/components/ApiRadioGroup.vue

@ -11,7 +11,7 @@ import { useRuleFormItem } from '@/hooks/component/useFormItem'
import { useAttrs } from '@/hooks/core/useAttrs'
import { propTypes } from '@/utils/propTypes'
interface OptionsItem { label: string; value: string | number | boolean; disabled?: boolean; [name: string]: any }
interface OptionsItem { label: string, value: string | number | boolean, disabled?: boolean, [name: string]: any }
defineOptions({ name: 'ApiRadioGroup' })

2
src/components/Form/src/components/ApiSelect.vue

@ -10,7 +10,7 @@ import { useRuleFormItem } from '@/hooks/component/useFormItem'
import { useI18n } from '@/hooks/web/useI18n'
import { propTypes } from '@/utils/propTypes'
interface OptionsItem { label: string; value: string; disabled?: boolean }
interface OptionsItem { label: string, value: string, disabled?: boolean }
defineOptions({ name: 'ApiSelect', inheritAttrs: false })

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

@ -108,7 +108,7 @@ export default defineComponent({
return disabled
})
function getShow(): { isShow: boolean; isIfShow: boolean } {
function getShow(): { isShow: boolean, isIfShow: boolean } {
const { show, ifShow } = props.schema
const { showAdvancedButton } = props.formProps
const itemIsAdvanced = showAdvancedButton
@ -360,10 +360,10 @@ export default defineComponent({
// TODO autoLink=false
if (component && NO_AUTO_LINK_COMPONENTS.includes(component)) {
props.schema
&& (props.schema.itemProps! = {
autoLink: false,
...props.schema.itemProps,
})
&& (props.schema.itemProps! = {
autoLink: false,
...props.schema.itemProps,
})
}
return (

2
src/components/Form/src/components/RadioButtonGroup.vue

@ -9,7 +9,7 @@ import { isString } from '@/utils/is'
import { useRuleFormItem } from '@/hooks/component/useFormItem'
import { useAttrs } from '@/hooks/core/useAttrs'
interface OptionsItem { label: string; value: string | number | boolean; disabled?: boolean }
interface OptionsItem { label: string, value: string | number | boolean, disabled?: boolean }
type RadioItem = string | OptionsItem
defineOptions({ name: 'RadioButtonGroup' })

8
src/components/Form/src/hooks/useForm.ts

@ -25,10 +25,10 @@ export function useForm(props?: Props): UseFormReturnType {
function register(instance: FormActionType) {
isProdMode()
&& onUnmounted(() => {
formRef.value = null
loadedRef.value = null
})
&& onUnmounted(() => {
formRef.value = null
loadedRef.value = null
})
if (unref(loadedRef) && isProdMode() && instance === unref(formRef))
return

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

@ -311,8 +311,8 @@ export function useFormEvents({
&& item.field
&& !isNil(item.defaultValue)
&& (!(item.field in currentFieldsValue)
|| isNil(currentFieldsValue[item.field])
|| isEmpty(currentFieldsValue[item.field]))
|| isNil(currentFieldsValue[item.field])
|| isEmpty(currentFieldsValue[item.field]))
)
obj[item.field] = item.defaultValue
})

6
src/components/Form/src/types/form.ts

@ -144,9 +144,9 @@ interface BaseFormSchema {
subLabel?: string
// Help text on the right side of the text
helpMessage?:
| string
| string[]
| ((renderCallbackParams: RenderCallbackParams) => string | string[])
| string
| string[]
| ((renderCallbackParams: RenderCallbackParams) => string | string[])
// BaseHelp component props
helpComponentProps?: Partial<HelpComponentProps>
// Label width, if it is passed, the labelCol and WrapperCol configured by itemProps will be invalid

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

@ -47,37 +47,37 @@ export interface ColEx {
* <576px and also default setting, could be a span value or an object containing above props
* @type { span: ColSpanType, offset: ColSpanType } | ColSpanType
*/
xs?: { span: ColSpanType; offset: ColSpanType } | ColSpanType
xs?: { span: ColSpanType, offset: ColSpanType } | ColSpanType
/**
* 576px, could be a span value or an object containing above props
* @type { span: ColSpanType, offset: ColSpanType } | ColSpanType
*/
sm?: { span: ColSpanType; offset: ColSpanType } | ColSpanType
sm?: { span: ColSpanType, offset: ColSpanType } | ColSpanType
/**
* 768px, could be a span value or an object containing above props
* @type { span: ColSpanType, offset: ColSpanType } | ColSpanType
*/
md?: { span: ColSpanType; offset: ColSpanType } | ColSpanType
md?: { span: ColSpanType, offset: ColSpanType } | ColSpanType
/**
* 992px, could be a span value or an object containing above props
* @type { span: ColSpanType, offset: ColSpanType } | ColSpanType
*/
lg?: { span: ColSpanType; offset: ColSpanType } | ColSpanType
lg?: { span: ColSpanType, offset: ColSpanType } | ColSpanType
/**
* 1200px, could be a span value or an object containing above props
* @type { span: ColSpanType, offset: ColSpanType } | ColSpanType
*/
xl?: { span: ColSpanType; offset: ColSpanType } | ColSpanType
xl?: { span: ColSpanType, offset: ColSpanType } | ColSpanType
/**
* 1600px, could be a span value or an object containing above props
* @type { span: ColSpanType, offset: ColSpanType } | ColSpanType
*/
xxl?: { span: ColSpanType; offset: ColSpanType } | ColSpanType
xxl?: { span: ColSpanType, offset: ColSpanType } | ColSpanType
}
export type ComponentType =

34
src/components/FormDesign/src/components/VFormDesign/components/ComponentProps.vue

@ -33,12 +33,12 @@ watch(
() => formConfig.value.currentItem?.field,
(_newValue, oldValue) => {
formConfig.value.schemas
&& formItemsForEach(formConfig.value.schemas, (item) => {
if (item.link) {
const index = item.link.findIndex(linkItem => linkItem === oldValue)
index !== -1 && remove(item.link, index)
}
})
&& formItemsForEach(formConfig.value.schemas, (item) => {
if (item.link) {
const index = item.link.findIndex(linkItem => linkItem === oldValue)
index !== -1 && remove(item.link, index)
}
})
},
)
@ -75,18 +75,18 @@ watch(
})
baseComponentAttrs[formConfig.value.currentItem!.component]
&& baseComponentAttrs[formConfig.value.currentItem!.component].forEach(async (item) => {
if (item.component) {
if (['Switch', 'Checkbox', 'Radio'].includes(item.component)) {
item.category = 'control'
allOptions.value.push(item)
}
else {
item.category = 'input'
allOptions.value.push(item)
}
&& baseComponentAttrs[formConfig.value.currentItem!.component].forEach(async (item) => {
if (item.component) {
if (['Switch', 'Checkbox', 'Radio'].includes(item.component)) {
item.category = 'control'
allOptions.value.push(item)
}
})
else {
item.category = 'input'
allOptions.value.push(item)
}
}
})
},
{
immediate: true,

2
src/components/FormDesign/src/components/VFormDesign/components/FormNodeOperate.vue

@ -33,7 +33,7 @@ function handleDelete() {
const { component, key } = formItem;
//
['Grid', 'Tabs'].includes(component)
&& formItem.columns?.forEach(item => traverse(item.children))
&& formItem.columns?.forEach(item => traverse(item.children))
if (key === props.currentItem.key) {
const params: IVFormComponent
= schemas.length === 1

6
src/components/FormDesign/src/components/VFormDesign/components/ImportJsonModal.vue

@ -56,9 +56,9 @@ function handleImportJson() {
try {
const editorJsonData = JSON.parse(state.json) as IFormConfig
editorJsonData.schemas
&& formItemsForEach(editorJsonData.schemas, (formItem) => {
generateKey(formItem)
})
&& formItemsForEach(editorJsonData.schemas, (formItem) => {
generateKey(formItem)
})
formDesignMethods.setFormConfig({
...editorJsonData,
activeKey: 1,

12
src/components/FormDesign/src/components/VFormDesign/components/LayoutItem.vue

@ -30,18 +30,18 @@ const emit = defineEmits(['dragStart', 'handleColAdd', 'handle-copy', 'handle-de
const Draggable = draggable
const { formDesignMethods: { handleSetSelectItem }, formConfig } = useFormDesignState()
const { formDesignMethods: { handleSetSelectItem } } = useFormDesignState()
const colPropsComputed = computed(() => {
const { colProps = {} } = props.schema
return colProps
})
const list1 = computed(() => props.schema.columns)
// const list1 = computed(() => props.schema.columns)
// AColdiv
const layoutTag = computed(() => {
return formConfig.value.layout === 'horizontal' ? 'Col' : 'div'
})
// // AColdiv
// const layoutTag = computed(() => {
// return formConfig.value.layout === 'horizontal' ? 'Col' : 'div'
// })
</script>
<template>

7
src/components/FormDesign/src/components/VFormDesign/modules/FormComponentPanel.vue

@ -4,7 +4,6 @@
-->
<script lang="ts" setup>
import draggable from 'vuedraggable'
import { computed } from 'vue'
import { cloneDeep } from 'lodash-es'
import { Empty, Form } from 'ant-design-vue'
import { useFormDesignState } from '../../../hooks/useFormDesignState'
@ -38,9 +37,9 @@ function handleDragStart(e: any) {
// currentItem
// AColdiv
const layoutTag = computed(() => {
return formConfig.value.layout === 'horizontal' ? 'Col' : 'div'
})
// const layoutTag = computed(() => {
// return formConfig.value.layout === 'horizontal' ? 'Col' : 'div'
// })
</script>
<template>

14
src/components/FormDesign/src/typings/v-form-component.ts

@ -67,7 +67,7 @@ export interface IVFormComponent {
// 组件布局
wrapperCol?: IAnyObject
// 子控件
columns?: Array<{ span: number; children: any[] }>
columns?: Array<{ span: number, children: any[] }>
}
declare type namesType = string | string[]
@ -241,37 +241,37 @@ interface IACol {
* <576px and also default setting, could be a span value or an object containing above props
* @type { span: ColSpanType, offset: ColSpanType } | ColSpanType
*/
xs: { span: ColSpanType; offset: ColSpanType } | ColSpanType
xs: { span: ColSpanType, offset: ColSpanType } | ColSpanType
/**
* 576px, could be a span value or an object containing above props
* @type { span: ColSpanType, offset: ColSpanType } | ColSpanType
*/
sm: { span: ColSpanType; offset: ColSpanType } | ColSpanType
sm: { span: ColSpanType, offset: ColSpanType } | ColSpanType
/**
* 768px, could be a span value or an object containing above props
* @type { span: ColSpanType, offset: ColSpanType } | ColSpanType
*/
md: { span: ColSpanType; offset: ColSpanType } | ColSpanType
md: { span: ColSpanType, offset: ColSpanType } | ColSpanType
/**
* 992px, could be a span value or an object containing above props
* @type { span: ColSpanType, offset: ColSpanType } | ColSpanType
*/
lg: { span: ColSpanType; offset: ColSpanType } | ColSpanType
lg: { span: ColSpanType, offset: ColSpanType } | ColSpanType
/**
* 1200px, could be a span value or an object containing above props
* @type { span: ColSpanType, offset: ColSpanType } | ColSpanType
*/
xl: { span: ColSpanType; offset: ColSpanType } | ColSpanType
xl: { span: ColSpanType, offset: ColSpanType } | ColSpanType
/**
* 1600px, could be a span value or an object containing above props
* @type { span: ColSpanType, offset: ColSpanType } | ColSpanType
*/
xxl: { span: ColSpanType; offset: ColSpanType } | ColSpanType
xxl: { span: ColSpanType, offset: ColSpanType } | ColSpanType
}
export interface IValidationRule {

8
src/components/FormDesign/src/utils/index.ts

@ -140,10 +140,10 @@ export function removeAttrs(formConfig: IFormConfig): IFormConfig {
delete copyFormConfig.currentItem
delete copyFormConfig.activeKey
copyFormConfig.schemas
&& formItemsForEach(copyFormConfig.schemas, (item) => {
delete item.icon
delete item.key
})
&& formItemsForEach(copyFormConfig.schemas, (item) => {
delete item.icon
delete item.key
})
return copyFormConfig
}

12
src/components/Menu/src/BasicMenu.vue

@ -82,12 +82,12 @@ listenerRouteChange((route) => {
})
!props.mixSider
&& watch(
() => props.items,
() => {
handleMenuChange()
},
)
&& watch(
() => props.items,
() => {
handleMenuChange()
},
)
const handleMenuClick: MenuProps['onClick'] = async ({ key }) => {
const { beforeClickFn } = props

16
src/components/Modal/src/hooks/useModal.ts

@ -24,11 +24,11 @@ export function useModal(): UseModalReturnType {
uid.value = uuid
isProdMode()
&& onUnmounted(() => {
modal.value = null
loaded.value = false
dataTransfer[unref(uid)] = null
})
&& onUnmounted(() => {
modal.value = null
loaded.value = false
dataTransfer[unref(uid)] = null
})
if (unref(loaded) && isProdMode() && modalMethod === unref(modal))
return
@ -100,9 +100,9 @@ export function useModalInner(callbackFn?: Fn): UseModalInnerReturnType {
const register = (modalInstance: ModalMethods, uuid: number) => {
isProdMode()
&& tryOnUnmounted(() => {
modalInstanceRef.value = null
})
&& tryOnUnmounted(() => {
modalInstanceRef.value = null
})
uidRef.value = uuid
modalInstanceRef.value = modalInstance
currentInstance?.emit('register', modalInstance, uuid)

20
src/components/Preview/src/Functional.vue

@ -201,11 +201,11 @@ export default defineComponent({
}
ele
&& emit('imgLoad', {
index: imgState.currentIndex,
dom: ele[0] as HTMLImageElement,
url,
})
&& emit('imgLoad', {
index: imgState.currentIndex,
dom: ele[0] as HTMLImageElement,
url,
})
}
imgState.currentUrl = url
imgState.status = StatueEnum.DONE
@ -213,11 +213,11 @@ export default defineComponent({
img.onerror = (e: Event) => {
const ele: EventTarget[] = e.composedPath()
ele
&& emit('imgError', {
index: imgState.currentIndex,
dom: ele[0] as HTMLImageElement,
url,
})
&& emit('imgError', {
index: imgState.currentIndex,
dom: ele[0] as HTMLImageElement,
url,
})
imgState.status = StatueEnum.FAIL
}
}

12
src/components/Preview/src/Preview.vue

@ -13,12 +13,12 @@ interface ImageProps {
height?: string | number
placeholder?: string | boolean
preview?:
| boolean
| {
open?: boolean
onOpenChange?: (open: boolean, prevOpen: boolean) => void
getContainer: string | HTMLElement | (() => HTMLElement)
}
| boolean
| {
open?: boolean
onOpenChange?: (open: boolean, prevOpen: boolean) => void
getContainer: string | HTMLElement | (() => HTMLElement)
}
}
type ImageItem = string | ImageProps

12
src/components/Preview/src/typing.ts

@ -44,12 +44,12 @@ export interface ImageProps {
height?: string | number
placeholder?: string | boolean
preview?:
| boolean
| {
open?: boolean
onOpenChange?: (open: boolean, prevOpen: boolean) => void
getContainer: string | HTMLElement | (() => HTMLElement)
}
| boolean
| {
open?: boolean
onOpenChange?: (open: boolean, prevOpen: boolean) => void
getContainer: string | HTMLElement | (() => HTMLElement)
}
}
export type ImageItem = string | ImageProps

12
src/components/SimpleMenu/src/components/useSimpleMenuContext.ts

@ -4,12 +4,12 @@ import { createContext, useContext } from '@/hooks/core/useContext'
export interface MenuEmitterEvents {
'on-update-opened':
| (string | number)[]
| {
opend: boolean
parent?: ComponentInternalInstance | null
uidList: number[]
}
| (string | number)[]
| {
opend: boolean
parent?: ComponentInternalInstance | null
uidList: number[]
}
'on-menu-item-select': string | number
'open-name-change': {
name: string | number

4
src/components/Table/src/BasicTable.vue

@ -70,8 +70,8 @@ const getProps = computed(() => {
const isFixedHeightPage = inject(PageWrapperFixedHeightKey, false)
watchEffect(() => {
unref(isFixedHeightPage)
&& props.canResize
&& warn('\'canResize\' of BasicTable may not work in PageWrapper with \'fixedHeight\' (especially in hot updates)')
&& props.canResize
&& warn('\'canResize\' of BasicTable may not work in PageWrapper with \'fixedHeight\' (especially in hot updates)')
})
const { getLoading, setLoading } = useLoading(getProps)

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

@ -161,7 +161,7 @@ export function useDataSource(
const rowKeys = !Array.isArray(rowKey) ? [rowKey] : rowKey
function deleteRow(data, key) {
const row: { index: number; data: [] } = findRow(data, key)
const row: { index: number, data: [] } = findRow(data, key)
if (row === null || row.index === -1)
return

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

@ -29,10 +29,10 @@ export function useTable(tableProps?: Props): [
function register(instance: TableActionType, formInstance: UseTableMethod) {
isProdMode()
&& onUnmounted(() => {
tableRef.value = null
loadedRef.value = null
})
&& onUnmounted(() => {
tableRef.value = null
loadedRef.value = null
})
if (unref(loadedRef) && isProdMode() && instance === unref(tableRef))
return

4
src/components/Table/src/hooks/useTableScroll.ts

@ -61,7 +61,7 @@ export function useTableScroll(
if (hasScrollBarY) {
tableEl.classList.contains('hide-scrollbar-y')
&& tableEl.classList.remove('hide-scrollbar-y')
&& tableEl.classList.remove('hide-scrollbar-y')
}
else {
!tableEl.classList.contains('hide-scrollbar-y') && tableEl.classList.add('hide-scrollbar-y')
@ -69,7 +69,7 @@ export function useTableScroll(
if (hasScrollBarX) {
tableEl.classList.contains('hide-scrollbar-x')
&& tableEl.classList.remove('hide-scrollbar-x')
&& tableEl.classList.remove('hide-scrollbar-x')
}
else {
!tableEl.classList.contains('hide-scrollbar-x') && tableEl.classList.add('hide-scrollbar-x')

2
src/components/Table/src/props.ts

@ -131,7 +131,7 @@ export const basicProps = {
type: Function as PropType<(record: TableCustomRecord<any>, index: number) => string>,
},
scroll: {
type: Object as PropType<{ x: number | string | true; y: number | string }>,
type: Object as PropType<{ x: number | string | true, y: number | string }>,
default: null,
},
beforeEditSubmit: {

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

@ -72,9 +72,9 @@ export interface ColumnProps<T> {
* @type any (slot)
*/
filterDropdown?:
| VNodeChild
| JSX.Element
| ((props: FilterDropdownProps) => VNodeChild | JSX.Element)
| VNodeChild
| JSX.Element
| ((props: FilterDropdownProps) => VNodeChild | JSX.Element)
/**
* Whether filterDropdown is visible

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

@ -314,7 +314,7 @@ export interface BasicTableProps<T = any> {
* you need to add style .ant-table td { white-space: nowrap; }.
* @type object
*/
scroll?: { x?: number | string | true; y?: number | string }
scroll?: { x?: number | string | true, y?: number | string }
/**
* Whether to show table header
@ -422,8 +422,8 @@ export interface BasicColumn extends ColumnProps<Recordable> {
text: string
value: string
children?:
| unknown[]
| (((props: Record<string, unknown>) => unknown[]) & (() => unknown[]) & (() => unknown[]))
| unknown[]
| (((props: Record<string, unknown>) => unknown[]) & (() => unknown[]) & (() => unknown[]))
}[]
//

24
src/components/Table/src/types/tableAction.ts

@ -25,16 +25,16 @@ export interface PopConfirm {
cancel?: Fn
icon?: string
placement?:
| 'top'
| 'left'
| 'right'
| 'bottom'
| 'topLeft'
| 'topRight'
| 'leftTop'
| 'leftBottom'
| 'rightTop'
| 'rightBottom'
| 'bottomLeft'
| 'bottomRight'
| 'top'
| 'left'
| 'right'
| 'bottom'
| 'topLeft'
| 'topRight'
| 'leftTop'
| 'leftBottom'
| 'rightTop'
| 'rightBottom'
| 'bottomLeft'
| 'bottomRight'
}

2
src/components/Tree/src/types/tree.ts

@ -29,7 +29,7 @@ export interface FieldNames {
export type KeyType = string | number
export type CheckKeys = KeyType[] | { checked: string[] | number[]; halfChecked: string[] | number[] }
export type CheckKeys = KeyType[] | { checked: string[] | number[], halfChecked: string[] | number[] }
export const treeProps = buildProps({
value: {

2
src/components/Upload/src/data.tsx

@ -108,7 +108,7 @@ export function createPreviewColumns(): BasicColumn[] {
]
}
export function createPreviewActionColumn({ handleRemove, handleDownload }: { handleRemove: Fn; handleDownload: Fn }): BasicColumn {
export function createPreviewActionColumn({ handleRemove, handleDownload }: { handleRemove: Fn, handleDownload: Fn }): BasicColumn {
return {
width: 160,
title: t('component.upload.operating'),

2
src/components/Verifition/src/Verify.vue

@ -123,7 +123,7 @@ export default {
<!-- 验证码容器 -->
<component
:is="componentType" v-if="componentType" ref="instance" :captcha-type="captchaType" :type="verifyType"
:figure="figure" :arith="arith" :mode="mode" :v-space="vSpace" :explain="explain" :img-size="imgSize"
:figure="figure" :arith="arith" :mode="mode" :spaces="vSpace" :explain="explain" :img-size="imgSize"
:block-size="blockSize" :bar-size="barSize"
/>
</div>

4
src/components/Verifition/src/Verify/VerifyPoints.vue

@ -19,7 +19,7 @@ const props = defineProps({
type: String,
},
//
vSpace: {
spaces: {
type: Number,
default: 5,
},
@ -204,7 +204,7 @@ async function getPictrue() {
'width': setSize.imgWidth,
'height': setSize.imgHeight,
'background-size': `${setSize.imgWidth} ${setSize.imgHeight}`,
'margin-bottom': `${vSpace}px`,
'margin-bottom': `${spaces}px`,
}"
>
<div v-show="showRefresh" class="verify-refresh" style="z-index: 3" @click="refresh">

4
src/components/Verifition/src/Verify/VerifySlide.vue

@ -22,7 +22,7 @@ const props = defineProps({
type: String,
default: 'fixed',
},
vSpace: {
spaces: {
type: Number,
default: 5,
},
@ -306,7 +306,7 @@ async function getPictrue() {
<template>
<div style="position: relative">
<div v-if="type === '2'" class="verify-img-out" :style="{ height: `${parseInt(setSize.imgHeight) + vSpace}px` }">
<div v-if="type === '2'" class="verify-img-out" :style="{ height: `${parseInt(setSize.imgHeight) + spaces}px` }">
<div class="verify-img-panel" :style="{ width: setSize.imgWidth, height: setSize.imgHeight }">
<img :src="`data:image/png;base64,${backImgBase}`" alt="" style=" display: block;width: 100%; height: 100%">
<div v-show="showRefresh" class="verify-refresh" @click="refresh">

2
src/directives/ripple/index.ts

@ -48,7 +48,7 @@ const RippleDirective: Directive & RippleProto = {
},
}
function rippler({ event, el, zIndex, background }: { event: EventType; el: HTMLElement } & RippleProto) {
function rippler({ event, el, zIndex, background }: { event: EventType, el: HTMLElement } & RippleProto) {
const targetBorder = Number.parseInt(getComputedStyle(el).borderWidth.replace('px', ''))
const clientX = event.clientX || event.touches[0].clientX
const clientY = event.clientY || event.touches[0].clientY

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

@ -62,8 +62,8 @@ const getPlaceholderDomStyle = computed((): CSSProperties => {
if (!(unref(getAutoCollapse) && unref(getIsUnFold))) {
if (
(unref(getShowFullHeaderRef) || !unref(getSplit))
&& unref(getShowHeader)
&& !unref(getFullContent)
&& unref(getShowHeader)
&& !unref(getFullContent)
)
height += HEADER_HEIGHT

8
src/layouts/default/tabs/useMultipleTabs.ts

@ -21,10 +21,10 @@ export function initAffixTabs(): string[] {
function filterAffixTabs(routes: RouteLocationNormalized[]) {
const tabs: RouteLocationNormalized[] = []
routes
&& routes.forEach((route) => {
if (route.meta && route.meta.affix)
tabs.push(toRaw(route))
})
&& routes.forEach((route) => {
if (route.meta && route.meta.affix)
tabs.push(toRaw(route))
})
return tabs
}

2
src/router/guard/permissionGuard.ts

@ -59,7 +59,7 @@ export function createPermissionGuard(router: Router) {
}
// redirect login page
const redirectData: { path: string; replace: boolean; query?: Recordable<string> } = {
const redirectData: { path: string, replace: boolean, query?: Recordable<string> } = {
path: LOGIN_PATH,
replace: true,
}

1
src/utils/domUtils.ts

@ -163,7 +163,6 @@ export function useRafThrottle<T extends FunctionArgs>(fn: T): T {
return
locked = true
window.requestAnimationFrame(() => {
// eslint-disable-next-line ts/no-invalid-this
fn.apply(this, args)
locked = false
})

2
src/utils/file/download.ts

@ -55,7 +55,7 @@ export function downloadByData(data: BlobPart, filename: string, mime?: string,
* Download file according to file address
* @param {*} sUrl
*/
export function downloadByUrl({ url, target = '_blank', fileName }: { url: string; target?: TargetContext; fileName?: string }): boolean {
export function downloadByUrl({ url, target = '_blank', fileName }: { url: string, target?: TargetContext, fileName?: string }): boolean {
const isChrome = window.navigator.userAgent.toLowerCase().includes('chrome')
const isSafari = window.navigator.userAgent.toLowerCase().includes('safari')

4
src/utils/helper/treeHelper.ts

@ -156,7 +156,7 @@ export function forEach<T = any>(tree: T[], func: (n: T) => any, config: Partial
* @description: Extract tree specified structure
* @description:
*/
export function treeMap<T = any>(treeData: T[], opt: { children?: string; conversion: Fn }): T[] {
export function treeMap<T = any>(treeData: T[], opt: { children?: string, conversion: Fn }): T[] {
return treeData.map(item => treeMapEach(item, opt))
}
@ -164,7 +164,7 @@ export function treeMap<T = any>(treeData: T[], opt: { children?: string; conver
* @description: Extract tree specified structure
* @description:
*/
export function treeMapEach(data: any, { children = 'children', conversion }: { children?: string; conversion: Fn }) {
export function treeMapEach(data: any, { children = 'children', conversion }: { children?: string, conversion: Fn }) {
const haveChildren = Array.isArray(data[children]) && data[children].length > 0
const conversionData = conversion(data) || {}
if (haveChildren) {

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

@ -118,8 +118,8 @@ export class VAxios {
// 请求拦截器错误捕获
requestInterceptorsCatch
&& isFunction(requestInterceptorsCatch)
&& this.axiosInstance.interceptors.request.use(undefined, requestInterceptorsCatch)
&& isFunction(requestInterceptorsCatch)
&& this.axiosInstance.interceptors.request.use(undefined, requestInterceptorsCatch)
// 响应结果拦截器处理
this.axiosInstance.interceptors.response.use(async (res: AxiosResponse<any>) => {
@ -177,10 +177,10 @@ export class VAxios {
// 响应结果拦截器错误捕获
responseInterceptorsCatch
&& isFunction(responseInterceptorsCatch)
&& this.axiosInstance.interceptors.response.use(undefined, (error) => {
return responseInterceptorsCatch(axiosInstance, error)
})
&& isFunction(responseInterceptorsCatch)
&& this.axiosInstance.interceptors.response.use(undefined, (error) => {
return responseInterceptorsCatch(axiosInstance, error)
})
}
/**

4
src/utils/http/axios/index.ts

@ -259,8 +259,8 @@ const transform: AxiosTransform = {
const retryRequest = new AxiosRetry()
const { isOpenRetry } = config.requestOptions.retryRequest
config.method?.toUpperCase() === RequestEnum.GET
&& isOpenRetry
&& retryRequest.retry(axiosInstance, error)
&& isOpenRetry
&& retryRequest.retry(axiosInstance, error)
return Promise.reject(error)
},
}

3
src/utils/index.ts

@ -81,7 +81,7 @@ export function deepMerge<T extends object | null | undefined, U extends object
export function openWindow(
url: string,
opt?: { target?: TargetContext | string; noopener?: boolean; noreferrer?: boolean },
opt?: { target?: TargetContext | string, noopener?: boolean, noreferrer?: boolean },
) {
const { target = '__blank', noopener = true, noreferrer = true } = opt || {}
const feature: string[] = []
@ -167,7 +167,6 @@ export function simpleDebounce(fn, delay = 100) {
clearTimeout(timer)
timer = setTimeout(() => {
// eslint-disable-next-line ts/no-invalid-this
fn.apply(this, args)
}, delay)
}

2
src/utils/props.ts

@ -12,7 +12,7 @@ export interface PropWrapper<T> { [wrapperKey]: T }
export const propKey = Symbol('propKey')
type ResolveProp<T> = ExtractPropTypes<{
key: { type: T; required: true }
key: { type: T, required: true }
}>['key']
type ResolvePropType<T> = ResolveProp<T> extends { type: infer V } ? V : ResolveProp<T>
type ResolvePropTypeWithReadonly<T> = Readonly<T> extends Readonly<Array<infer A>> ? ResolvePropType<A[]> : ResolvePropType<T>

4
src/utils/tree.ts

@ -146,14 +146,14 @@ export function forEach<T = any>(tree: T[], func: (n: T) => any, config: Partial
/**
* @description: Extract tree specified structure
*/
export function treeMap<T = any>(treeData: T[], opt: { children?: string; conversion: Fn }): T[] {
export function treeMap<T = any>(treeData: T[], opt: { children?: string, conversion: Fn }): T[] {
return treeData.map(item => treeMapEach(item, opt))
}
/**
* @description: Extract tree specified structure
*/
export function treeMapEach(data: any, { children = 'children', conversion }: { children?: string; conversion: Fn }) {
export function treeMapEach(data: any, { children = 'children', conversion }: { children?: string, conversion: Fn }) {
const haveChildren = Array.isArray(data[children]) && data[children].length > 0
const conversionData = conversion(data) || {}
if (haveChildren) {

22
src/views/base/login/LoginForm.vue

@ -19,6 +19,7 @@ import * as authUtil from '@/utils/auth'
import { Verify } from '@/components/Verifition'
import { getTenantByWebsite, getTenantIdByName } from '@/api/base/login'
import { noop } from '@/utils'
const FormItem = Form.Item
const InputPassword = Input.Password
@ -71,7 +72,7 @@ async function getCode() {
async function getTenantId() {
if (tenantEnable === 'true') {
const website = location.host
const tenant = await getTenantByWebsite(website)
const tenant = await getTenantByWebsite(website).catch(noop)
if (tenant) {
formData.tenantName = tenant.name
authUtil.setTenantId(tenant.id)
@ -205,25 +206,6 @@ async function handleLogin(params) {
<!-- <GoogleCircleFilled /> -->
<!-- <TwitterCircleFilled /> -->
</div>
<!-- 萌新必读 -->
<Divider class="enter-x">
萌新必读
</Divider>
<div class="enter-x flex justify-evenly" :class="`${prefixCls}-sign-in-way`">
<a-button href="https://doc.iocoder.cn/" target="_blank" class="w-1/4">
📚开发指南
</a-button>
<a-button href="https://doc.iocoder.cn/video/" target="_blank" class="w-1/4 pl-1">
🔥视频教程
</a-button>
<a-button href="https://www.iocoder.cn/Interview/good-collection/" target="_blank" class="w-1/4 pl-1">
面试手册
</a-button>
<a-button href="http://static.yudao.iocoder.cn/mp/xinyu370.jpeg" target="_blank" class="w-1/4 pl-1">
🤝外包咨询
</a-button>
</div>
</Form>
<Verify ref="verify" mode="pop" :captcha-type="captchaType" :img-size="{ width: '360px', height: '180px' }" @success="handleLogin" />
</template>

2
src/views/infra/webSocket/index.vue

@ -14,7 +14,7 @@ const userStore = useUserStore()
const state = reactive({
sendValue: '',
recordList: [] as { id: number; time: number; res: string }[],
recordList: [] as { id: number, time: number, res: string }[],
})
const server = ref(
`${(`${import.meta.env.VITE_GLOB_BASE_URL}/websocket/message`).replace('http', 'ws')}?userId=${userStore.getUserInfo.user.id}`,