diff --git a/apps/vben5/.changeset/.prettierrc.json b/apps/vben5/.changeset/.prettierrc.json new file mode 100644 index 000000000..544138be4 --- /dev/null +++ b/apps/vben5/.changeset/.prettierrc.json @@ -0,0 +1,3 @@ +{ + "singleQuote": true +} diff --git a/apps/vben5/.changeset/fancy-ears-walk.md b/apps/vben5/.changeset/fancy-ears-walk.md new file mode 100644 index 000000000..f73cb596b --- /dev/null +++ b/apps/vben5/.changeset/fancy-ears-walk.md @@ -0,0 +1,7 @@ +--- +'@vben/styles': patch +'@vben-core/form-ui': patch +'@vben/web-naive': patch +--- + +feat(@core/form-ui): 新增 useVbenForm 数组编辑器 VbenFormFieldArray diff --git a/apps/vben5/.gitignore b/apps/vben5/.gitignore index 8cb16e7e0..12c3e492a 100644 --- a/apps/vben5/.gitignore +++ b/apps/vben5/.gitignore @@ -23,7 +23,8 @@ pnpm-lock.yaml package-lock.json .VSCodeCounter **/backend-mock/data - +.omx +.pnpm-store # local env files .env.local .env.*.local @@ -51,3 +52,12 @@ vite.config.ts.* *.sw? .history .cursor + +# AI +.agent +.agents +.claude +.codex +skills-lock.json +.atomcode +datalog diff --git a/apps/vben5/.node-version b/apps/vben5/.node-version index 85e502778..b832e4001 100644 --- a/apps/vben5/.node-version +++ b/apps/vben5/.node-version @@ -1 +1 @@ -22.22.0 +24.16.0 diff --git a/apps/vben5/.npmrc b/apps/vben5/.npmrc index aeac1ae91..7549542d7 100644 --- a/apps/vben5/.npmrc +++ b/apps/vben5/.npmrc @@ -1,13 +1 @@ registry=https://registry.npmmirror.com -public-hoist-pattern[]=lefthook -public-hoist-pattern[]=eslint -public-hoist-pattern[]=prettier -public-hoist-pattern[]=prettier-plugin-tailwindcss -public-hoist-pattern[]=stylelint -public-hoist-pattern[]=*postcss* -public-hoist-pattern[]=@commitlint/* -public-hoist-pattern[]=czg - -strict-peer-dependencies=false -auto-install-peers=true -dedupe-peer-dependents=true diff --git a/apps/vben5/.prettierignore b/apps/vben5/.prettierignore deleted file mode 100644 index 7c572fd66..000000000 --- a/apps/vben5/.prettierignore +++ /dev/null @@ -1,20 +0,0 @@ -dist -dev-dist -.local -.output.js -node_modules -.nvmrc -coverage -CODEOWNERS -.nitro -.output - - -**/*.svg -**/*.sh - -public -.npmrc -*-lock.yaml - -packages/@abp/components diff --git a/apps/vben5/.prettierrc.mjs b/apps/vben5/.prettierrc.mjs deleted file mode 100644 index 3e25d2cfa..000000000 --- a/apps/vben5/.prettierrc.mjs +++ /dev/null @@ -1 +0,0 @@ -export { default } from '@vben/prettier-config'; diff --git a/apps/vben5/.stylelintignore b/apps/vben5/.stylelintignore index 339bcf6c2..3adb33b22 100644 --- a/apps/vben5/.stylelintignore +++ b/apps/vben5/.stylelintignore @@ -2,4 +2,7 @@ dist public __tests__ coverage -packages/@abp/components +.codex +.claude +.agent +.agents diff --git a/apps/vben5/.vscode/extensions.json b/apps/vben5/.vscode/extensions.json index e8dc9ed9b..d4e28662b 100644 --- a/apps/vben5/.vscode/extensions.json +++ b/apps/vben5/.vscode/extensions.json @@ -2,14 +2,18 @@ "recommendations": [ // Vue 3 的语言支持 "Vue.volar", - // 将 ESLint JavaScript 集成到 VS Code 中。 + // 将 eslint 集成到 VS Code 中。 "dbaeumer.vscode-eslint", + // 将 oxlint 集成到 VS Code 中。 + "oxc.oxc-vscode", // Visual Studio Code 的官方 Stylelint 扩展 "stylelint.vscode-stylelint", - // 使用 Prettier 的代码格式化程序 - "esbenp.prettier-vscode", + // 使用 oxfmt 的代码格式化程序 + "oxc.oxc-vscode", // 支持 dotenv 文件语法 "mikestead.dotenv", + // YAML 语言支持,供 ESLint 校验 pnpm-workspace.yaml 等文件 + "redhat.vscode-yaml", // 源代码的拼写检查器 "streetsidesoftware.code-spell-checker", // Tailwind CSS 的官方 VS Code 插件 diff --git a/apps/vben5/.vscode/settings.json b/apps/vben5/.vscode/settings.json index 8da37dc96..993b52039 100644 --- a/apps/vben5/.vscode/settings.json +++ b/apps/vben5/.vscode/settings.json @@ -1,5 +1,6 @@ { - "tailwindCSS.experimental.configFile": "internal/tailwind-config/src/index.ts", + "tailwindCSS.experimental.configFile": "internal/tailwind-config/src/theme.css", + "tailwindCSS.lint.suggestCanonicalClasses": "ignore", // workbench "workbench.list.smoothScrolling": true, "workbench.startupEditor": "newUntitledFile", @@ -31,39 +32,51 @@ "editor.autoClosingOvertype": "always", "editor.autoClosingQuotes": "beforeWhitespace", "editor.wordSeparators": "`~!@#%^&*()=+[{]}\\|;:'\",.<>/?", + "editor.quickSuggestions": { + "strings": "on" + }, + + // lint && format + "oxc.enable": true, + "oxc.typeAware": true, + "oxc.configPath": "oxlint.config.ts", + "oxc.fmt.configPath": "oxfmt.config.ts", + "eslint.useFlatConfig": true, "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit", + "source.fixAll.oxc": "explicit", "source.fixAll.stylelint": "explicit", "source.organizeImports": "never" }, - "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.defaultFormatter": "oxc.oxc-vscode", "[html]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "oxc.oxc-vscode" }, "[css]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "oxc.oxc-vscode" }, "[scss]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "oxc.oxc-vscode" }, "[javascript]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "oxc.oxc-vscode" }, "[typescript]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "oxc.oxc-vscode" }, "[json]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "oxc.oxc-vscode" }, "[markdown]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "oxc.oxc-vscode" }, "[jsonc]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "oxc.oxc-vscode" }, "[vue]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "oxc.oxc-vscode" }, + // extensions "extensions.ignoreRecommendations": true, @@ -79,6 +92,7 @@ "files.insertFinalNewline": true, "files.simpleDialog.enable": true, "files.associations": { + "*.css": "tailwindcss", "*.ejs": "html", "*.art": "html", "**/tsconfig.json": "jsonc", @@ -118,7 +132,7 @@ // search "search.searchEditor.singleClickBehaviour": "peekDefinition", "search.followSymlinks": false, - // 在使用搜索功能时,将这些文件夹/文件排除在外 + // 使用搜索功能时,将这些文件和文件夹排除在外 "search.exclude": { "**/node_modules": true, "**/*.log": true, @@ -158,7 +172,7 @@ "emmet.triggerExpansionOnTab": false, "errorLens.enabledDiagnosticLevels": ["warning", "error"], - "errorLens.excludeBySource": ["cSpell", "Grammarly", "eslint"], + "errorLens.excludeBySource": ["cSpell", "Grammarly"], "stylelint.enable": true, "stylelint.packageManager": "pnpm", @@ -166,9 +180,10 @@ "stylelint.customSyntax": "postcss-html", "stylelint.snippet": ["css", "less", "postcss", "scss", "vue"], - "typescript.inlayHints.enumMemberValues.enabled": true, - "typescript.preferences.preferTypeOnlyAutoImports": true, - "typescript.preferences.includePackageJsonAutoImports": "on", + "js/ts.tsdk.path": "node_modules/typescript/lib", + "js/ts.inlayHints.enumMemberValues.enabled": true, + "js/ts.preferences.preferTypeOnlyAutoImports": true, + "js/ts.preferences.includePackageJsonAutoImports": "on", "eslint.validate": [ "javascript", @@ -195,7 +210,7 @@ "yaml": false }, - "cssVariables.lookupFiles": ["packages/core/base/design/src/**/*.css"], + "cssVariables.lookupFiles": ["packages/@core/base/design/src/**/*.css"], "i18n-ally.localesPaths": [ "packages/locales/src/langs", @@ -220,12 +235,9 @@ "*.env": "$(capture).env.*", "README.md": "README*,CHANGELOG*,LICENSE,CNAME", "package.json": "pnpm-lock.yaml,pnpm-workspace.yaml,.gitattributes,.gitignore,.gitpod.yml,.npmrc,.browserslistrc,.node-version,.git*,.tazerc.json", - "eslint.config.mjs": ".eslintignore,.prettierignore,.stylelintignore,.commitlintrc.*,.prettierrc.*,stylelint.config.*,.lintstagedrc.mjs,cspell.json,lefthook.yml", - "tailwind.config.mjs": "postcss.*" + "oxlint.config.ts": ".eslintignore,.stylelintignore,.commitlintrc.*,stylelint.config.*,.lintstagedrc.mjs,cspell.json,lefthook.yml,oxfmt.config.*,eslint.config.*" }, "commentTranslate.hover.enabled": false, "commentTranslate.multiLineMerge": true, - "vue.server.hybridMode": true, - "typescript.tsdk": "node_modules/typescript/lib", - "oxc.enable": false + "vue.server.hybridMode": true } diff --git a/apps/vben5/README.ja-JP.md b/apps/vben5/README.ja-JP.md index 4ce285a74..ca0a9775d 100644 --- a/apps/vben5/README.ja-JP.md +++ b/apps/vben5/README.ja-JP.md @@ -114,7 +114,7 @@ pnpm build ## ブラウザサポート -ローカル開発には `Chrome 80+` ブラウザを推奨します +Tailwind CSS v4.0 is designed for Safari 16.4+, Chrome 111+, and Firefox 128+ モダンブラウザをサポートし、IEはサポートしません diff --git a/apps/vben5/README.md b/apps/vben5/README.md index ce8e89758..e1c9f29cd 100644 --- a/apps/vben5/README.md +++ b/apps/vben5/README.md @@ -114,7 +114,7 @@ Reference [vue](https://github.com/vuejs/vue/blob/dev/.github/COMMIT_CONVENTION. ## Browser Support -The `Chrome 80+` browser is recommended for local development +Tailwind CSS v4.0 is designed for Safari 16.4+, Chrome 111+, and Firefox 128+ Support modern browsers, not IE diff --git a/apps/vben5/README.zh-CN.md b/apps/vben5/README.zh-CN.md index d3193ef65..da7ec5fa8 100644 --- a/apps/vben5/README.zh-CN.md +++ b/apps/vben5/README.zh-CN.md @@ -114,7 +114,7 @@ pnpm build ## 浏览器支持 -本地开发推荐使用 `Chrome 80+` 浏览器 +Tailwind CSS v4.0 is designed for Safari 16.4+, Chrome 111+, and Firefox 128+ 支持现代浏览器,不支持 IE diff --git a/apps/vben5/apps/app-antd/.env.development b/apps/vben5/apps/app-antd/.env.development index ef5b909eb..302e7c03e 100644 --- a/apps/vben5/apps/app-antd/.env.development +++ b/apps/vben5/apps/app-antd/.env.development @@ -17,6 +17,7 @@ VITE_INJECT_APP_LOADING=true # 是否仅允许OIDC登录 VITE_GLOB_AUTH_ONLY_OIDC=true +VITE_GLOB_AUTH_DISABLE_PKCE=true # 认证服务器 VITE_GLOB_AUTH_AUTHORITY="http://localhost:30000" # 授权范围 diff --git a/apps/vben5/apps/app-antd/.vite/deps/_metadata.json b/apps/vben5/apps/app-antd/.vite/deps/_metadata.json index 5f0b346a8..cca964d5e 100644 --- a/apps/vben5/apps/app-antd/.vite/deps/_metadata.json +++ b/apps/vben5/apps/app-antd/.vite/deps/_metadata.json @@ -5,4 +5,4 @@ "browserHash": "cfcea6c4", "optimized": {}, "chunks": {} -} \ No newline at end of file +} diff --git a/apps/vben5/apps/app-antd/index.html b/apps/vben5/apps/app-antd/index.html index 33d34a9e2..39be77767 100644 --- a/apps/vben5/apps/app-antd/index.html +++ b/apps/vben5/apps/app-antd/index.html @@ -9,8 +9,7 @@ + content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0" /> <%= VITE_APP_TITLE %> diff --git a/apps/vben5/apps/app-antd/package.json b/apps/vben5/apps/app-antd/package.json index 8fe700c52..4ae7bbc58 100644 --- a/apps/vben5/apps/app-antd/package.json +++ b/apps/vben5/apps/app-antd/package.json @@ -50,6 +50,7 @@ "@abp/ui": "workspace:*", "@abp/webhooks": "workspace:*", "@abp/wechat": "workspace:*", + "@tanstack/vue-query": "catalog:", "@vben-core/shadcn-ui": "workspace:*", "@vben/access": "workspace:*", "@vben/common-ui": "workspace:*", diff --git a/apps/vben5/apps/app-antd/postcss.config.mjs b/apps/vben5/apps/app-antd/postcss.config.mjs deleted file mode 100644 index 3d8070455..000000000 --- a/apps/vben5/apps/app-antd/postcss.config.mjs +++ /dev/null @@ -1 +0,0 @@ -export { default } from '@vben/tailwind-config/postcss'; diff --git a/apps/vben5/apps/app-antd/public/resource/tinymce/langs/en.js b/apps/vben5/apps/app-antd/public/resource/tinymce/langs/en.js index 27337c394..6389318fd 100644 --- a/apps/vben5/apps/app-antd/public/resource/tinymce/langs/en.js +++ b/apps/vben5/apps/app-antd/public/resource/tinymce/langs/en.js @@ -13,20 +13,20 @@ tinymce.addI18n('es', { Italic: 'Cursiva', Underline: 'Subrayado', Strikethrough: 'Tachado', - Superscript: 'Super\u00edndice', - Subscript: 'Sub\u00edndice', + Superscript: 'Super\u00EDndice', + Subscript: 'Sub\u00EDndice', 'Clear formatting': 'Limpiar formato', 'Align left': 'Alinear a la izquierda', 'Align center': 'Alinear al centro', 'Align right': 'Alinear a la derecha', Justify: 'Justificar', - 'Bullet list': 'Lista de vi\u00f1etas', + 'Bullet list': 'Lista de vi\u00F1etas', 'Numbered list': 'Lista numerada', - 'Decrease indent': 'Disminuir sangr\u00eda', - 'Increase indent': 'Incrementar sangr\u00eda', + 'Decrease indent': 'Disminuir sangr\u00EDa', + 'Increase indent': 'Incrementar sangr\u00EDa', Close: 'Cerrar', Formats: 'Formatos', - "Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.": 'Su navegador no es compatible con el acceso directo al portapapeles. Use las teclas Crtl+X\/C\/V de su teclado.', + "Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X/C/V keyboard shortcuts instead.": 'Su navegador no es compatible con el acceso directo al portapapeles. Use las teclas Crtl+X/C/V de su teclado.', Headers: 'Encabezados', 'Header 1': 'Encabezado 1', 'Header 2': 'Encabezado 2', @@ -44,23 +44,23 @@ tinymce.addI18n('es', { Preformatted: 'Con formato previo', Div: 'Div', Pre: 'Pre', - Code: 'C\u00f3digo', - Paragraph: 'P\u00e1rrafo', + Code: 'C\u00F3digo', + Paragraph: 'P\u00E1rrafo', Blockquote: 'Blockquote', Inline: 'Alineado', Blocks: 'Bloques', - 'Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.': 'Pegar est\u00e1 ahora en modo de texto plano. El contenido se pegar\u00e1 como texto plano hasta que desactive esta opci\u00f3n.', + 'Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.': 'Pegar est\u00E1 ahora en modo de texto plano. El contenido se pegar\u00E1 como texto plano hasta que desactive esta opci\u00F3n.', Fonts: 'Fuentes', - 'Font Sizes': 'Tama\u00f1os de fuente', + 'Font Sizes': 'Tama\u00F1os de fuente', Class: 'Clase', 'Browse for an image': 'Buscar una imagen', OR: 'OR', - 'Drop an image here': 'Arrastre una imagen aqu\u00ed', + 'Drop an image here': 'Arrastre una imagen aqu\u00ED', Upload: 'Cargar', Block: 'Bloque', Align: 'Alinear', Default: 'Por defecto', - Circle: 'C\u00edrculo', + Circle: 'C\u00EDrculo', Disc: 'Disco', Square: 'Cuadrado', 'Lower Alpha': 'Inferior Alfa', @@ -71,14 +71,14 @@ tinymce.addI18n('es', { 'Anchor...': 'Anclaje...', Name: 'Nombre', Id: 'Id', - 'Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.': 'Deber\u00eda comenzar por una letra, seguida solo de letras, n\u00fameros, guiones, puntos, dos puntos o guiones bajos.', - 'You have unsaved changes are you sure you want to navigate away?': 'Tiene cambios sin guardar. \u00bfEst\u00e1 seguro de que quiere salir?', - 'Restore last draft': 'Restaurar el \u00faltimo borrador', - 'Special character...': 'Car\u00e1cter especial...', - 'Source code': 'C\u00f3digo fuente', - 'Insert\/Edit code sample': 'Insertar\/editar c\u00f3digo de prueba', + 'Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.': 'Deber\u00EDa comenzar por una letra, seguida solo de letras, n\u00FAmeros, guiones, puntos, dos puntos o guiones bajos.', + 'You have unsaved changes are you sure you want to navigate away?': 'Tiene cambios sin guardar. \u00BFEst\u00E1 seguro de que quiere salir?', + 'Restore last draft': 'Restaurar el \u00FAltimo borrador', + 'Special character...': 'Car\u00E1cter especial...', + 'Source code': 'C\u00F3digo fuente', + 'Insert/Edit code sample': 'Insertar/editar c\u00F3digo de prueba', Language: 'Idioma', - 'Code sample...': 'Ejemplo de c\u00f3digo...', + 'Code sample...': 'Ejemplo de c\u00F3digo...', 'Color Picker': 'Selector de colores', R: 'R', G: 'V', @@ -87,33 +87,33 @@ tinymce.addI18n('es', { 'Right to left': 'De derecha a izquierda', 'Emoticons...': 'Emoticones...', 'Metadata and Document Properties': 'Metadatos y propiedades del documento', - Title: 'T\u00edtulo', + Title: 'T\u00EDtulo', Keywords: 'Palabras clave', - Description: 'Descripci\u00f3n', + Description: 'Descripci\u00F3n', Robots: 'Robots', Author: 'Autor', - Encoding: 'Codificaci\u00f3n', + Encoding: 'Codificaci\u00F3n', Fullscreen: 'Pantalla completa', - Action: 'Acci\u00f3n', + Action: 'Acci\u00F3n', Shortcut: 'Atajo', Help: 'Ayuda', - Address: 'Direcci\u00f3n', - 'Focus to menubar': 'Enfocar la barra del men\u00fa', + Address: 'Direcci\u00F3n', + 'Focus to menubar': 'Enfocar la barra del men\u00FA', 'Focus to toolbar': 'Enfocar la barra de herramientas', 'Focus to element path': 'Enfocar la ruta del elemento', 'Focus to contextual toolbar': 'Enfocar la barra de herramientas contextual', - 'Insert link (if link plugin activated)': 'Insertar enlace (si el complemento de enlace est\u00e1 activado)', - 'Save (if save plugin activated)': 'Guardar (si el componente de salvar est\u00e1 activado)', - 'Find (if searchreplace plugin activated)': 'Buscar (si el complemento buscar-remplazar est\u00e1 activado)', + 'Insert link (if link plugin activated)': 'Insertar enlace (si el complemento de enlace est\u00E1 activado)', + 'Save (if save plugin activated)': 'Guardar (si el componente de salvar est\u00E1 activado)', + 'Find (if searchreplace plugin activated)': 'Buscar (si el complemento buscar-remplazar est\u00E1 activado)', 'Plugins installed ({0}):': 'Plugins instalados ({0}):', 'Premium plugins:': 'Complementos premium:', - 'Learn more...': 'Aprende m\u00e1s...', + 'Learn more...': 'Aprende m\u00E1s...', 'You are using {0}': 'Estas usando {0}', Plugins: 'Complementos', 'Handy Shortcuts': 'Accesos directos', - 'Horizontal line': 'L\u00ednea horizontal', - 'Insert\/edit image': 'Insertar\/editar imagen', - 'Image description': 'Descripci\u00f3n de la imagen', + 'Horizontal line': 'L\u00EDnea horizontal', + 'Insert/edit image': 'Insertar/editar imagen', + 'Image description': 'Descripci\u00F3n de la imagen', Source: 'Enlace', Dimensions: 'Dimensiones', 'Constrain proportions': 'Restringir proporciones', @@ -125,7 +125,7 @@ tinymce.addI18n('es', { Border: 'Borde', 'Insert image': 'Insertar imagen', 'Image...': 'Imagen...', - 'Image list': 'Lista de im\u00e1genes', + 'Image list': 'Lista de im\u00E1genes', 'Rotate counterclockwise': 'Girar a la izquierda', 'Rotate clockwise': 'Girar a la derecha', 'Flip vertically': 'Invertir verticalmente', @@ -136,7 +136,7 @@ tinymce.addI18n('es', { 'Zoom out': 'Alejar', Crop: 'Recortar', Resize: 'Redimensionar', - Orientation: 'Orientaci\u00f3n', + Orientation: 'Orientaci\u00F3n', Brightness: 'Brillo', Sharpen: 'Forma', Contrast: 'Contraste', @@ -144,11 +144,11 @@ tinymce.addI18n('es', { Gamma: 'Gamma', Invert: 'Invertir', Apply: 'Aplicar', - Back: 'Atr\u00e1s', - 'Insert date\/time': 'Insertar fecha\/hora', - 'Date\/time': 'Fecha\/hora', - 'Insert\/Edit Link': 'Insertar\/editar enlace', - 'Insert\/edit link': 'Insertar\/editar enlace', + Back: 'Atr\u00E1s', + 'Insert date/time': 'Insertar fecha/hora', + 'Date/time': 'Fecha/hora', + 'Insert/Edit Link': 'Insertar/editar enlace', + 'Insert/edit link': 'Insertar/editar enlace', 'Text to display': 'Texto para mostrar', Url: 'URL', 'Open link in...': 'Abrir enlace en...', @@ -159,20 +159,20 @@ tinymce.addI18n('es', { Anchors: 'Anclas', 'Link...': 'Enlace...', 'Paste or type a link': 'Pega o introduce un enlace', - 'The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?': 'El enlace que has introducido no parece ser una direcci\u00f3n de correo electr\u00f3nico. Quieres a\u00f1adir el prefijo necesario mailto: ?', - 'The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?': 'El enlace que has introducido no parece ser una enlace externo. Quieres a\u00f1adir el prefijo necesario http:\/\/ ?', + 'The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?': 'El enlace que has introducido no parece ser una direcci\u00F3n de correo electr\u00F3nico. Quieres a\u00F1adir el prefijo necesario mailto: ?', + 'The URL you entered seems to be an external link. Do you want to add the required http:// prefix?': 'El enlace que has introducido no parece ser una enlace externo. Quieres a\u00F1adir el prefijo necesario http:// ?', 'Link list': 'Lista de enlaces', 'Insert video': 'Insertar video', - 'Insert\/edit video': 'Insertar\/editar video', - 'Insert\/edit media': 'Insertar\/editar medio', + 'Insert/edit video': 'Insertar/editar video', + 'Insert/edit media': 'Insertar/editar medio', 'Alternative source': 'Enlace alternativo', 'Alternative source URL': 'Origen de URL alternativo', - 'Media poster (Image URL)': 'P\u00f3ster de medio (URL de imagen)', - 'Paste your embed code below:': 'Pega tu c\u00f3digo embebido debajo', + 'Media poster (Image URL)': 'P\u00F3ster de medio (URL de imagen)', + 'Paste your embed code below:': 'Pega tu c\u00F3digo embebido debajo', Embed: 'Incrustado', 'Media...': 'Medios...', 'Nonbreaking space': 'Espacio fijo', - 'Page break': 'Salto de p\u00e1gina', + 'Page break': 'Salto de p\u00E1gina', 'Paste as text': 'Pegar como texto', Preview: 'Previsualizar', 'Print...': 'Imprimir...', @@ -187,11 +187,11 @@ tinymce.addI18n('es', { 'Could not find the specified string.': 'No se encuentra la cadena de texto especificada', 'Match case': 'Coincidencia exacta', 'Find whole words only': 'Solo palabras completas', - 'Spell check': 'Revisar ortograf\u00eda', + 'Spell check': 'Revisar ortograf\u00EDa', Ignore: 'Ignorar', 'Ignore all': 'Ignorar todos', Finish: 'Finalizar', - 'Add to Dictionary': 'A\u00f1adir al Diccionario', + 'Add to Dictionary': 'A\u00F1adir al Diccionario', 'Insert table': 'Insertar tabla', 'Table properties': 'Propiedades de la tabla', 'Delete table': 'Eliminar tabla', @@ -202,15 +202,15 @@ tinymce.addI18n('es', { 'Merge cells': 'Combinar celdas', 'Split cell': 'Dividir celdas', 'Insert row before': 'Insertar fila antes', - 'Insert row after': 'Insertar fila despu\u00e9s ', + 'Insert row after': 'Insertar fila despu\u00E9s ', 'Delete row': 'Eliminar fila', 'Row properties': 'Propiedades de la fila', 'Cut row': 'Cortar fila', 'Copy row': 'Copiar fila', 'Paste row before': 'Pegar la fila antes', - 'Paste row after': 'Pegar la fila despu\u00e9s', + 'Paste row after': 'Pegar la fila despu\u00E9s', 'Insert column before': 'Insertar columna antes', - 'Insert column after': 'Insertar columna despu\u00e9s', + 'Insert column after': 'Insertar columna despu\u00E9s', 'Delete column': 'Eliminar columna', Cols: 'Columnas', Rows: 'Filas', @@ -218,13 +218,13 @@ tinymce.addI18n('es', { Height: 'Alto', 'Cell spacing': 'Espacio entre celdas', 'Cell padding': 'Relleno de celda', - 'Show caption': 'Mostrar t\u00edtulo', + 'Show caption': 'Mostrar t\u00EDtulo', Left: 'Izquierda', Center: 'Centrado', Right: 'Derecha', 'Cell type': 'Tipo de celda', - Scope: '\u00c1mbito', - Alignment: 'Alineaci\u00f3n', + Scope: '\u00C1mbito', + Alignment: 'Alineaci\u00F3n', 'H Align': 'Alineamiento Horizontal', 'V Align': 'Alineamiento Vertical', Top: 'Arriba', @@ -236,7 +236,7 @@ tinymce.addI18n('es', { 'Row type': 'Tipo de fila', Header: 'Cabecera', Body: 'Cuerpo', - Footer: 'Pie de p\u00e1gina', + Footer: 'Pie de p\u00E1gina', 'Border color': 'Color del borde', 'Insert template...': 'Insertar plantilla...', Templates: 'Plantillas', @@ -253,7 +253,7 @@ tinymce.addI18n('es', { 'Word count': 'Contar palabras', Count: 'Recuento', Document: 'Documento', - Selection: 'Selecci\u00f3n', + Selection: 'Selecci\u00F3n', Words: 'Palabras', 'Words: {0}': 'Palabras: {0}', '{0} words': '{0} palabras', @@ -265,15 +265,15 @@ tinymce.addI18n('es', { Table: 'Tabla', Tools: 'Herramientas', 'Powered by {0}': 'Desarrollado por {0}', - 'Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help': '\u00c1rea de texto enriquecido. Pulse ALT-F9 para el menu. Pulse ALT-F10 para la barra de herramientas. Pulse ALT-0 para ayuda', + 'Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help': '\u00C1rea de texto enriquecido. Pulse ALT-F9 para el menu. Pulse ALT-F10 para la barra de herramientas. Pulse ALT-0 para ayuda', 'Image title': 'Titulo de imagen', 'Border width': 'Ancho de borde', 'Border style': 'Estilo de borde', Error: 'Error', Warn: 'Advertencia', - Valid: 'V\u00e1lido', - 'To open the popup, press Shift+Enter': 'Para abrir el elemento emergente, pulse May\u00fas+Intro', - 'Rich Text Area. Press ALT-0 for help.': '\u00c1rea de texto enriquecido. Pulse ALT-0 para abrir la ayuda.', + Valid: 'V\u00E1lido', + 'To open the popup, press Shift+Enter': 'Para abrir el elemento emergente, pulse May\u00FAs+Intro', + 'Rich Text Area. Press ALT-0 for help.': '\u00C1rea de texto enriquecido. Pulse ALT-0 para abrir la ayuda.', 'System Font': 'Fuente de sistema', 'Failed to upload image: {0}': 'Fallo al cargar imagen: {0}', 'Failed to load plugin: {0} from url {1}': 'Fallo al cargar complemento: {0} desde URL {1}', @@ -285,31 +285,31 @@ tinymce.addI18n('es', { Currency: 'Divisa', Text: 'Texto', Quotations: 'Comillas', - Mathematical: 'S\u00edmbolo matem\u00e1tico', + Mathematical: 'S\u00EDmbolo matem\u00E1tico', 'Extended Latin': 'Latino extendido A', - Symbols: 'S\u00edmbolos', + Symbols: 'S\u00EDmbolos', Arrows: 'Flechas', 'User Defined': 'Definido por el usuario', - 'dollar sign': 'signo de d\u00f3lar', + 'dollar sign': 'signo de d\u00F3lar', 'currency sign': 'signo de divisa', 'euro-currency sign': 'signo de euro', 'colon sign': 'signo de dos puntos', 'cruzeiro sign': 'signo de cruceiro', - 'french franc sign': 'signo de franco franc\u00e9s', + 'french franc sign': 'signo de franco franc\u00E9s', 'lira sign': 'signo de lira', 'mill sign': 'signo de mill', 'naira sign': 'signo de naira', 'peseta sign': 'signo de peseta', 'rupee sign': 'signo de rupia', 'won sign': 'signo de won', - 'new sheqel sign': 'signo de nuevo s\u00e9quel', + 'new sheqel sign': 'signo de nuevo s\u00E9quel', 'dong sign': 'signo de dong', 'kip sign': 'signo de kip', 'tugrik sign': 'signo de tugrik', 'drachma sign': 'signo de dracma', - 'german penny symbol': 'signo de penique alem\u00e1n', + 'german penny symbol': 'signo de penique alem\u00E1n', 'peso sign': 'signo de peso', - 'guarani sign': 'signo de guaran\u00ed', + 'guarani sign': 'signo de guaran\u00ED', 'austral sign': 'signo de austral', 'hryvnia sign': 'signo de grivna', 'cedi sign': 'signo de cedi', @@ -318,13 +318,13 @@ tinymce.addI18n('es', { 'tenge sign': 'signo de tenge', 'indian rupee sign': 'signo de rupia india', 'turkish lira sign': 'signo de lira turca', - 'nordic mark sign': 'signo de marco n\u00f3rdico', + 'nordic mark sign': 'signo de marco n\u00F3rdico', 'manat sign': 'signo de manat', 'ruble sign': 'signo de rublo', - 'yen character': 'car\u00e1cter de yen', - 'yuan character': 'car\u00e1cter de yuan', - 'yuan character, in hong kong and taiwan': 'car\u00e1cter de yuan en Hong Kong y Taiw\u00e1n', - 'yen\/yuan character variant one': 'Variante uno de car\u00e1cter de yen\/yuan', + 'yen character': 'car\u00E1cter de yen', + 'yuan character': 'car\u00E1cter de yuan', + 'yuan character, in hong kong and taiwan': 'car\u00E1cter de yuan en Hong Kong y Taiw\u00E1n', + 'yen/yuan character variant one': 'Variante uno de car\u00E1cter de yen/yuan', 'Loading emoticons...': 'Cargando emoticonos...', 'Could not load emoticons': 'No se han podido cargar los emoticonos', People: 'Personas', @@ -337,19 +337,19 @@ tinymce.addI18n('es', { Characters: 'Caracteres', 'Characters (no spaces)': 'Caracteres (sin espacios)', '{0} characters': '{0} caracteres', - 'Error: Form submit field collision.': 'Error: Colisi\u00f3n de campo al enviar formulario.', - 'Error: No form element found.': 'Error: No se encuentra ning\u00fan elemento de formulario.', + 'Error: Form submit field collision.': 'Error: Colisi\u00F3n de campo al enviar formulario.', + 'Error: No form element found.': 'Error: No se encuentra ning\u00FAn elemento de formulario.', Update: 'Actualizar', 'Color swatch': 'Muestrario de colores', Turquoise: 'Turquesa', Green: 'Verde', Blue: 'Azul', - Purple: 'P\u00farpura', + Purple: 'P\u00FArpura', 'Navy Blue': 'Azul marino', 'Dark Turquoise': 'Turquesa oscuro', 'Dark Green': 'Verde oscuro', 'Medium Blue': 'Azul medio', - 'Medium Purple': 'P\u00farpura medio', + 'Medium Purple': 'P\u00FArpura medio', 'Midnight Blue': 'Azul medio', Yellow: 'Amarillo', Orange: 'Naranja', @@ -371,35 +371,35 @@ tinymce.addI18n('es', { Black: 'Negro', White: 'Blanco', 'Switch to or from fullscreen mode': 'Activar o desactivar modo pantalla completa', - 'Open help dialog': 'Abrir di\u00e1logo de ayuda', + 'Open help dialog': 'Abrir di\u00E1logo de ayuda', history: 'historial', styles: 'estilos', formatting: 'formato', - alignment: 'alineaci\u00f3n', - indentation: 'sangr\u00eda', - 'permanent pen': 'bol\u00edgrafo permanente', + alignment: 'alineaci\u00F3n', + indentation: 'sangr\u00EDa', + 'permanent pen': 'bol\u00EDgrafo permanente', comments: 'comentarios', 'Format Painter': 'Copiar formato', - 'Insert\/edit iframe': 'Insertar\/editar iframe', - Capitalization: 'Uso de may\u00fasculas', - lowercase: 'min\u00fasculas', - UPPERCASE: 'MAY\u00daSCULAS', - 'Title Case': 'Tipo T\u00edtulo', - 'Permanent Pen Properties': 'Propiedades del bol\u00edgrafo permanente', - 'Permanent pen properties...': 'Propiedades del bol\u00edgrafo permanente...', + 'Insert/edit iframe': 'Insertar/editar iframe', + Capitalization: 'Uso de may\u00FAsculas', + lowercase: 'min\u00FAsculas', + UPPERCASE: 'MAY\u00DASCULAS', + 'Title Case': 'Tipo T\u00EDtulo', + 'Permanent Pen Properties': 'Propiedades del bol\u00EDgrafo permanente', + 'Permanent pen properties...': 'Propiedades del bol\u00EDgrafo permanente...', Font: 'Fuente', - Size: 'Tama\u00f1o', - 'More...': 'M\u00e1s...', + Size: 'Tama\u00F1o', + 'More...': 'M\u00E1s...', 'Spellcheck Language': 'Corrector', 'Select...': 'Seleccionar...', Preferences: 'Preferencias', - Yes: 'S\u00ed', + Yes: 'S\u00ED', No: 'No', - 'Keyboard Navigation': 'Navegaci\u00f3n con el teclado', - Version: 'Versi\u00f3n', + 'Keyboard Navigation': 'Navegaci\u00F3n con el teclado', + Version: 'Versi\u00F3n', Anchor: 'Ancla', - 'Special character': 'Car\u00e1cter especial', - 'Code sample': 'Ejemplo de c\u00f3digo', + 'Special character': 'Car\u00E1cter especial', + 'Code sample': 'Ejemplo de c\u00F3digo', Color: 'Color', Emoticons: 'Emoticonos', 'Document properties': 'Propiedades del documento', @@ -413,7 +413,7 @@ tinymce.addI18n('es', { Prev: 'Anterior', 'Find and replace': 'Buscar y reemplazar', 'Whole words': 'Palabras completas', - Spellcheck: 'Corrector ortogr\u00e1fico', - Caption: 'Subt\u00edtulo', + Spellcheck: 'Corrector ortogr\u00E1fico', + Caption: 'Subt\u00EDtulo', 'Insert template': 'Insertar plantilla' }) diff --git a/apps/vben5/apps/app-antd/public/resource/tinymce/langs/zh-CN.js b/apps/vben5/apps/app-antd/public/resource/tinymce/langs/zh-CN.js index f9d8b5cfd..452395aa5 100644 --- a/apps/vben5/apps/app-antd/public/resource/tinymce/langs/zh-CN.js +++ b/apps/vben5/apps/app-antd/public/resource/tinymce/langs/zh-CN.js @@ -1,32 +1,32 @@ tinymce.addI18n('zh_CN',{ -"Redo": "\u91cd\u505a", -"Undo": "\u64a4\u9500", -"Cut": "\u526a\u5207", -"Copy": "\u590d\u5236", -"Paste": "\u7c98\u8d34", +"Redo": "\u91CD\u505A", +"Undo": "\u64A4\u9500", +"Cut": "\u526A\u5207", +"Copy": "\u590D\u5236", +"Paste": "\u7C98\u8D34", "Select all": "\u5168\u9009", -"New document": "\u65b0\u6587\u4ef6", -"Ok": "\u786e\u5b9a", -"Cancel": "\u53d6\u6d88", -"Visual aids": "\u7f51\u683c\u7ebf", -"Bold": "\u7c97\u4f53", -"Italic": "\u659c\u4f53", -"Underline": "\u4e0b\u5212\u7ebf", -"Strikethrough": "\u5220\u9664\u7ebf", -"Superscript": "\u4e0a\u6807", -"Subscript": "\u4e0b\u6807", -"Clear formatting": "\u6e05\u9664\u683c\u5f0f", -"Align left": "\u5de6\u8fb9\u5bf9\u9f50", -"Align center": "\u4e2d\u95f4\u5bf9\u9f50", -"Align right": "\u53f3\u8fb9\u5bf9\u9f50", -"Justify": "\u4e24\u7aef\u5bf9\u9f50", -"Bullet list": "\u9879\u76ee\u7b26\u53f7", -"Numbered list": "\u7f16\u53f7\u5217\u8868", -"Decrease indent": "\u51cf\u5c11\u7f29\u8fdb", -"Increase indent": "\u589e\u52a0\u7f29\u8fdb", -"Close": "\u5173\u95ed", -"Formats": "\u683c\u5f0f", -"Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.": "\u4f60\u7684\u6d4f\u89c8\u5668\u4e0d\u652f\u6301\u6253\u5f00\u526a\u8d34\u677f\uff0c\u8bf7\u4f7f\u7528Ctrl+X\/C\/V\u7b49\u5feb\u6377\u952e\u3002", +"New document": "\u65B0\u6587\u4EF6", +"Ok": "\u786E\u5B9A", +"Cancel": "\u53D6\u6D88", +"Visual aids": "\u7F51\u683C\u7EBF", +"Bold": "\u7C97\u4F53", +"Italic": "\u659C\u4F53", +"Underline": "\u4E0B\u5212\u7EBF", +"Strikethrough": "\u5220\u9664\u7EBF", +"Superscript": "\u4E0A\u6807", +"Subscript": "\u4E0B\u6807", +"Clear formatting": "\u6E05\u9664\u683C\u5F0F", +"Align left": "\u5DE6\u8FB9\u5BF9\u9F50", +"Align center": "\u4E2D\u95F4\u5BF9\u9F50", +"Align right": "\u53F3\u8FB9\u5BF9\u9F50", +"Justify": "\u4E24\u7AEF\u5BF9\u9F50", +"Bullet list": "\u9879\u76EE\u7B26\u53F7", +"Numbered list": "\u7F16\u53F7\u5217\u8868", +"Decrease indent": "\u51CF\u5C11\u7F29\u8FDB", +"Increase indent": "\u589E\u52A0\u7F29\u8FDB", +"Close": "\u5173\u95ED", +"Formats": "\u683C\u5F0F", +"Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X/C/V keyboard shortcuts instead.": "\u4F60\u7684\u6D4F\u89C8\u5668\u4E0D\u652F\u6301\u6253\u5F00\u526A\u8D34\u677F\uFF0C\u8BF7\u4F7F\u7528Ctrl+X/C/V\u7B49\u5FEB\u6377\u952E\u3002", "Headers": "\u6807\u9898", "Header 1": "\u6807\u98981", "Header 2": "\u6807\u98982", @@ -41,349 +41,349 @@ tinymce.addI18n('zh_CN',{ "Heading 4": "\u6807\u98984", "Heading 5": "\u6807\u98985", "Heading 6": "\u6807\u98986", -"Preformatted": "\u9884\u5148\u683c\u5f0f\u5316\u7684", +"Preformatted": "\u9884\u5148\u683C\u5F0F\u5316\u7684", "Div": "Div", "Pre": "Pre", -"Code": "\u4ee3\u7801", -"Paragraph": "\u6bb5\u843d", -"Blockquote": "\u5f15\u6587\u533a\u5757", -"Inline": "\u6587\u672c", -"Blocks": "\u57fa\u5757", -"Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.": "\u5f53\u524d\u4e3a\u7eaf\u6587\u672c\u7c98\u8d34\u6a21\u5f0f\uff0c\u518d\u6b21\u70b9\u51fb\u53ef\u4ee5\u56de\u5230\u666e\u901a\u7c98\u8d34\u6a21\u5f0f\u3002", -"Fonts": "\u5b57\u4f53", -"Font Sizes": "\u5b57\u53f7", -"Class": "\u7c7b\u578b", -"Browse for an image": "\u6d4f\u89c8\u56fe\u50cf", +"Code": "\u4EE3\u7801", +"Paragraph": "\u6BB5\u843D", +"Blockquote": "\u5F15\u6587\u533A\u5757", +"Inline": "\u6587\u672C", +"Blocks": "\u57FA\u5757", +"Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.": "\u5F53\u524D\u4E3A\u7EAF\u6587\u672C\u7C98\u8D34\u6A21\u5F0F\uFF0C\u518D\u6B21\u70B9\u51FB\u53EF\u4EE5\u56DE\u5230\u666E\u901A\u7C98\u8D34\u6A21\u5F0F\u3002", +"Fonts": "\u5B57\u4F53", +"Font Sizes": "\u5B57\u53F7", +"Class": "\u7C7B\u578B", +"Browse for an image": "\u6D4F\u89C8\u56FE\u50CF", "OR": "\u6216", -"Drop an image here": "\u62d6\u653e\u4e00\u5f20\u56fe\u50cf\u81f3\u6b64", -"Upload": "\u4e0a\u4f20", +"Drop an image here": "\u62D6\u653E\u4E00\u5F20\u56FE\u50CF\u81F3\u6B64", +"Upload": "\u4E0A\u4F20", "Block": "\u5757", -"Align": "\u5bf9\u9f50", -"Default": "\u9ed8\u8ba4", -"Circle": "\u7a7a\u5fc3\u5706", -"Disc": "\u5b9e\u5fc3\u5706", -"Square": "\u65b9\u5757", -"Lower Alpha": "\u5c0f\u5199\u82f1\u6587\u5b57\u6bcd", -"Lower Greek": "\u5c0f\u5199\u5e0c\u814a\u5b57\u6bcd", -"Lower Roman": "\u5c0f\u5199\u7f57\u9a6c\u5b57\u6bcd", -"Upper Alpha": "\u5927\u5199\u82f1\u6587\u5b57\u6bcd", -"Upper Roman": "\u5927\u5199\u7f57\u9a6c\u5b57\u6bcd", -"Anchor...": "\u951a\u70b9...", -"Name": "\u540d\u79f0", -"Id": "\u6807\u8bc6\u7b26", -"Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.": "\u6807\u8bc6\u7b26\u5e94\u8be5\u4ee5\u5b57\u6bcd\u5f00\u5934\uff0c\u540e\u8ddf\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u7834\u6298\u53f7\u3001\u70b9\u3001\u5192\u53f7\u6216\u4e0b\u5212\u7ebf\u3002", -"You have unsaved changes are you sure you want to navigate away?": "\u4f60\u8fd8\u6709\u6587\u6863\u5c1a\u672a\u4fdd\u5b58\uff0c\u786e\u5b9a\u8981\u79bb\u5f00\uff1f", -"Restore last draft": "\u6062\u590d\u4e0a\u6b21\u7684\u8349\u7a3f", -"Special characters...": "\u7279\u6b8a\u5b57\u7b26...", -"Source code": "\u6e90\u4ee3\u7801", -"Insert\/Edit code sample": "\u63d2\u5165\/\u7f16\u8f91\u4ee3\u7801\u793a\u4f8b", -"Language": "\u8bed\u8a00", -"Code sample...": "\u793a\u4f8b\u4ee3\u7801...", +"Align": "\u5BF9\u9F50", +"Default": "\u9ED8\u8BA4", +"Circle": "\u7A7A\u5FC3\u5706", +"Disc": "\u5B9E\u5FC3\u5706", +"Square": "\u65B9\u5757", +"Lower Alpha": "\u5C0F\u5199\u82F1\u6587\u5B57\u6BCD", +"Lower Greek": "\u5C0F\u5199\u5E0C\u814A\u5B57\u6BCD", +"Lower Roman": "\u5C0F\u5199\u7F57\u9A6C\u5B57\u6BCD", +"Upper Alpha": "\u5927\u5199\u82F1\u6587\u5B57\u6BCD", +"Upper Roman": "\u5927\u5199\u7F57\u9A6C\u5B57\u6BCD", +"Anchor...": "\u951A\u70B9...", +"Name": "\u540D\u79F0", +"Id": "\u6807\u8BC6\u7B26", +"Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.": "\u6807\u8BC6\u7B26\u5E94\u8BE5\u4EE5\u5B57\u6BCD\u5F00\u5934\uFF0C\u540E\u8DDF\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u7834\u6298\u53F7\u3001\u70B9\u3001\u5192\u53F7\u6216\u4E0B\u5212\u7EBF\u3002", +"You have unsaved changes are you sure you want to navigate away?": "\u4F60\u8FD8\u6709\u6587\u6863\u5C1A\u672A\u4FDD\u5B58\uFF0C\u786E\u5B9A\u8981\u79BB\u5F00\uFF1F", +"Restore last draft": "\u6062\u590D\u4E0A\u6B21\u7684\u8349\u7A3F", +"Special characters...": "\u7279\u6B8A\u5B57\u7B26...", +"Source code": "\u6E90\u4EE3\u7801", +"Insert/Edit code sample": "\u63D2\u5165/\u7F16\u8F91\u4EE3\u7801\u793A\u4F8B", +"Language": "\u8BED\u8A00", +"Code sample...": "\u793A\u4F8B\u4EE3\u7801...", "Color Picker": "\u9009\u8272\u5668", "R": "R", "G": "G", "B": "B", -"Left to right": "\u4ece\u5de6\u5230\u53f3", -"Right to left": "\u4ece\u53f3\u5230\u5de6", -"Emoticons...": "\u8868\u60c5\u7b26\u53f7...", -"Metadata and Document Properties": "\u5143\u6570\u636e\u548c\u6587\u6863\u5c5e\u6027", +"Left to right": "\u4ECE\u5DE6\u5230\u53F3", +"Right to left": "\u4ECE\u53F3\u5230\u5DE6", +"Emoticons...": "\u8868\u60C5\u7B26\u53F7...", +"Metadata and Document Properties": "\u5143\u6570\u636E\u548C\u6587\u6863\u5C5E\u6027", "Title": "\u6807\u9898", -"Keywords": "\u5173\u952e\u8bcd", -"Description": "\u63cf\u8ff0", -"Robots": "\u673a\u5668\u4eba", -"Author": "\u4f5c\u8005", -"Encoding": "\u7f16\u7801", -"Fullscreen": "\u5168\u5c4f", -"Action": "\u64cd\u4f5c", -"Shortcut": "\u5feb\u6377\u952e", -"Help": "\u5e2e\u52a9", +"Keywords": "\u5173\u952E\u8BCD", +"Description": "\u63CF\u8FF0", +"Robots": "\u673A\u5668\u4EBA", +"Author": "\u4F5C\u8005", +"Encoding": "\u7F16\u7801", +"Fullscreen": "\u5168\u5C4F", +"Action": "\u64CD\u4F5C", +"Shortcut": "\u5FEB\u6377\u952E", +"Help": "\u5E2E\u52A9", "Address": "\u5730\u5740", -"Focus to menubar": "\u79fb\u52a8\u7126\u70b9\u5230\u83dc\u5355\u680f", -"Focus to toolbar": "\u79fb\u52a8\u7126\u70b9\u5230\u5de5\u5177\u680f", -"Focus to element path": "\u79fb\u52a8\u7126\u70b9\u5230\u5143\u7d20\u8def\u5f84", -"Focus to contextual toolbar": "\u79fb\u52a8\u7126\u70b9\u5230\u4e0a\u4e0b\u6587\u83dc\u5355", -"Insert link (if link plugin activated)": "\u63d2\u5165\u94fe\u63a5 (\u5982\u679c\u94fe\u63a5\u63d2\u4ef6\u5df2\u6fc0\u6d3b)", -"Save (if save plugin activated)": "\u4fdd\u5b58(\u5982\u679c\u4fdd\u5b58\u63d2\u4ef6\u5df2\u6fc0\u6d3b)", -"Find (if searchreplace plugin activated)": "\u67e5\u627e(\u5982\u679c\u67e5\u627e\u66ff\u6362\u63d2\u4ef6\u5df2\u6fc0\u6d3b)", -"Plugins installed ({0}):": "\u5df2\u5b89\u88c5\u63d2\u4ef6 ({0}):", -"Premium plugins:": "\u4f18\u79c0\u63d2\u4ef6\uff1a", -"Learn more...": "\u4e86\u89e3\u66f4\u591a...", -"You are using {0}": "\u4f60\u6b63\u5728\u4f7f\u7528 {0}", -"Plugins": "\u63d2\u4ef6", -"Handy Shortcuts": "\u5feb\u6377\u952e", -"Horizontal line": "\u6c34\u5e73\u5206\u5272\u7ebf", -"Insert\/edit image": "\u63d2\u5165\/\u7f16\u8f91\u56fe\u7247", -"Image description": "\u56fe\u7247\u63cf\u8ff0", +"Focus to menubar": "\u79FB\u52A8\u7126\u70B9\u5230\u83DC\u5355\u680F", +"Focus to toolbar": "\u79FB\u52A8\u7126\u70B9\u5230\u5DE5\u5177\u680F", +"Focus to element path": "\u79FB\u52A8\u7126\u70B9\u5230\u5143\u7D20\u8DEF\u5F84", +"Focus to contextual toolbar": "\u79FB\u52A8\u7126\u70B9\u5230\u4E0A\u4E0B\u6587\u83DC\u5355", +"Insert link (if link plugin activated)": "\u63D2\u5165\u94FE\u63A5 (\u5982\u679C\u94FE\u63A5\u63D2\u4EF6\u5DF2\u6FC0\u6D3B)", +"Save (if save plugin activated)": "\u4FDD\u5B58(\u5982\u679C\u4FDD\u5B58\u63D2\u4EF6\u5DF2\u6FC0\u6D3B)", +"Find (if searchreplace plugin activated)": "\u67E5\u627E(\u5982\u679C\u67E5\u627E\u66FF\u6362\u63D2\u4EF6\u5DF2\u6FC0\u6D3B)", +"Plugins installed ({0}):": "\u5DF2\u5B89\u88C5\u63D2\u4EF6 ({0}):", +"Premium plugins:": "\u4F18\u79C0\u63D2\u4EF6\uFF1A", +"Learn more...": "\u4E86\u89E3\u66F4\u591A...", +"You are using {0}": "\u4F60\u6B63\u5728\u4F7F\u7528 {0}", +"Plugins": "\u63D2\u4EF6", +"Handy Shortcuts": "\u5FEB\u6377\u952E", +"Horizontal line": "\u6C34\u5E73\u5206\u5272\u7EBF", +"Insert/edit image": "\u63D2\u5165/\u7F16\u8F91\u56FE\u7247", +"Image description": "\u56FE\u7247\u63CF\u8FF0", "Source": "\u5730\u5740", -"Dimensions": "\u5927\u5c0f", -"Constrain proportions": "\u4fdd\u6301\u7eb5\u6a2a\u6bd4", -"General": "\u666e\u901a", -"Advanced": "\u9ad8\u7ea7", -"Style": "\u6837\u5f0f", -"Vertical space": "\u5782\u76f4\u8fb9\u8ddd", -"Horizontal space": "\u6c34\u5e73\u8fb9\u8ddd", -"Border": "\u8fb9\u6846", -"Insert image": "\u63d2\u5165\u56fe\u7247", -"Image...": "\u56fe\u7247...", -"Image list": "\u56fe\u7247\u5217\u8868", -"Rotate counterclockwise": "\u9006\u65f6\u9488\u65cb\u8f6c", -"Rotate clockwise": "\u987a\u65f6\u9488\u65cb\u8f6c", -"Flip vertically": "\u5782\u76f4\u7ffb\u8f6c", -"Flip horizontally": "\u6c34\u5e73\u7ffb\u8f6c", -"Edit image": "\u7f16\u8f91\u56fe\u7247", -"Image options": "\u56fe\u7247\u9009\u9879", -"Zoom in": "\u653e\u5927", -"Zoom out": "\u7f29\u5c0f", -"Crop": "\u88c1\u526a", -"Resize": "\u8c03\u6574\u5927\u5c0f", -"Orientation": "\u65b9\u5411", -"Brightness": "\u4eae\u5ea6", +"Dimensions": "\u5927\u5C0F", +"Constrain proportions": "\u4FDD\u6301\u7EB5\u6A2A\u6BD4", +"General": "\u666E\u901A", +"Advanced": "\u9AD8\u7EA7", +"Style": "\u6837\u5F0F", +"Vertical space": "\u5782\u76F4\u8FB9\u8DDD", +"Horizontal space": "\u6C34\u5E73\u8FB9\u8DDD", +"Border": "\u8FB9\u6846", +"Insert image": "\u63D2\u5165\u56FE\u7247", +"Image...": "\u56FE\u7247...", +"Image list": "\u56FE\u7247\u5217\u8868", +"Rotate counterclockwise": "\u9006\u65F6\u9488\u65CB\u8F6C", +"Rotate clockwise": "\u987A\u65F6\u9488\u65CB\u8F6C", +"Flip vertically": "\u5782\u76F4\u7FFB\u8F6C", +"Flip horizontally": "\u6C34\u5E73\u7FFB\u8F6C", +"Edit image": "\u7F16\u8F91\u56FE\u7247", +"Image options": "\u56FE\u7247\u9009\u9879", +"Zoom in": "\u653E\u5927", +"Zoom out": "\u7F29\u5C0F", +"Crop": "\u88C1\u526A", +"Resize": "\u8C03\u6574\u5927\u5C0F", +"Orientation": "\u65B9\u5411", +"Brightness": "\u4EAE\u5EA6", "Sharpen": "\u9510\u5316", -"Contrast": "\u5bf9\u6bd4\u5ea6", -"Color levels": "\u989c\u8272\u5c42\u6b21", -"Gamma": "\u4f3d\u9a6c\u503c", -"Invert": "\u53cd\u8f6c", -"Apply": "\u5e94\u7528", -"Back": "\u540e\u9000", -"Insert date\/time": "\u63d2\u5165\u65e5\u671f\/\u65f6\u95f4", -"Date\/time": "\u65e5\u671f\/\u65f6\u95f4", -"Insert\/Edit Link": "\u63d2\u5165\/\u7f16\u8f91\u94fe\u63a5", -"Insert\/edit link": "\u63d2\u5165\/\u7f16\u8f91\u94fe\u63a5", -"Text to display": "\u663e\u793a\u6587\u5b57", +"Contrast": "\u5BF9\u6BD4\u5EA6", +"Color levels": "\u989C\u8272\u5C42\u6B21", +"Gamma": "\u4F3D\u9A6C\u503C", +"Invert": "\u53CD\u8F6C", +"Apply": "\u5E94\u7528", +"Back": "\u540E\u9000", +"Insert date/time": "\u63D2\u5165\u65E5\u671F/\u65F6\u95F4", +"Date/time": "\u65E5\u671F/\u65F6\u95F4", +"Insert/Edit Link": "\u63D2\u5165/\u7F16\u8F91\u94FE\u63A5", +"Insert/edit link": "\u63D2\u5165/\u7F16\u8F91\u94FE\u63A5", +"Text to display": "\u663E\u793A\u6587\u5B57", "Url": "\u5730\u5740", -"Open link in...": "\u94fe\u63a5\u6253\u5f00\u4f4d\u7f6e...", -"Current window": "\u5f53\u524d\u7a97\u53e3", -"None": "\u65e0", -"New window": "\u5728\u65b0\u7a97\u53e3\u6253\u5f00", -"Remove link": "\u5220\u9664\u94fe\u63a5", -"Anchors": "\u951a\u70b9", -"Link...": "\u94fe\u63a5...", -"Paste or type a link": "\u7c98\u8d34\u6216\u8f93\u5165\u94fe\u63a5", -"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u4e3a\u90ae\u4ef6\u5730\u5740\uff0c\u9700\u8981\u52a0\u4e0amailto:\u524d\u7f00\u5417\uff1f", -"The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?": "\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u5c5e\u4e8e\u5916\u90e8\u94fe\u63a5\uff0c\u9700\u8981\u52a0\u4e0ahttp:\/\/:\u524d\u7f00\u5417\uff1f", -"Link list": "\u94fe\u63a5\u5217\u8868", -"Insert video": "\u63d2\u5165\u89c6\u9891", -"Insert\/edit video": "\u63d2\u5165\/\u7f16\u8f91\u89c6\u9891", -"Insert\/edit media": "\u63d2\u5165\/\u7f16\u8f91\u5a92\u4f53", -"Alternative source": "\u955c\u50cf", -"Alternative source URL": "\u66ff\u4ee3\u6765\u6e90\u7f51\u5740", -"Media poster (Image URL)": "\u5c01\u9762(\u56fe\u7247\u5730\u5740)", -"Paste your embed code below:": "\u5c06\u5185\u5d4c\u4ee3\u7801\u7c98\u8d34\u5728\u4e0b\u9762:", -"Embed": "\u5185\u5d4c", -"Media...": "\u591a\u5a92\u4f53...", -"Nonbreaking space": "\u4e0d\u95f4\u65ad\u7a7a\u683c", -"Page break": "\u5206\u9875\u7b26", -"Paste as text": "\u7c98\u8d34\u4e3a\u6587\u672c", -"Preview": "\u9884\u89c8", +"Open link in...": "\u94FE\u63A5\u6253\u5F00\u4F4D\u7F6E...", +"Current window": "\u5F53\u524D\u7A97\u53E3", +"None": "\u65E0", +"New window": "\u5728\u65B0\u7A97\u53E3\u6253\u5F00", +"Remove link": "\u5220\u9664\u94FE\u63A5", +"Anchors": "\u951A\u70B9", +"Link...": "\u94FE\u63A5...", +"Paste or type a link": "\u7C98\u8D34\u6216\u8F93\u5165\u94FE\u63A5", +"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "\u4F60\u6240\u586B\u5199\u7684URL\u5730\u5740\u4E3A\u90AE\u4EF6\u5730\u5740\uFF0C\u9700\u8981\u52A0\u4E0Amailto:\u524D\u7F00\u5417\uFF1F", +"The URL you entered seems to be an external link. Do you want to add the required http:// prefix?": "\u4F60\u6240\u586B\u5199\u7684URL\u5730\u5740\u5C5E\u4E8E\u5916\u90E8\u94FE\u63A5\uFF0C\u9700\u8981\u52A0\u4E0Ahttp://:\u524D\u7F00\u5417\uFF1F", +"Link list": "\u94FE\u63A5\u5217\u8868", +"Insert video": "\u63D2\u5165\u89C6\u9891", +"Insert/edit video": "\u63D2\u5165/\u7F16\u8F91\u89C6\u9891", +"Insert/edit media": "\u63D2\u5165/\u7F16\u8F91\u5A92\u4F53", +"Alternative source": "\u955C\u50CF", +"Alternative source URL": "\u66FF\u4EE3\u6765\u6E90\u7F51\u5740", +"Media poster (Image URL)": "\u5C01\u9762(\u56FE\u7247\u5730\u5740)", +"Paste your embed code below:": "\u5C06\u5185\u5D4C\u4EE3\u7801\u7C98\u8D34\u5728\u4E0B\u9762:", +"Embed": "\u5185\u5D4C", +"Media...": "\u591A\u5A92\u4F53...", +"Nonbreaking space": "\u4E0D\u95F4\u65AD\u7A7A\u683C", +"Page break": "\u5206\u9875\u7B26", +"Paste as text": "\u7C98\u8D34\u4E3A\u6587\u672C", +"Preview": "\u9884\u89C8", "Print...": "\u6253\u5370...", -"Save": "\u4fdd\u5b58", -"Find": "\u67e5\u627e", -"Replace with": "\u66ff\u6362\u4e3a", -"Replace": "\u66ff\u6362", -"Replace all": "\u5168\u90e8\u66ff\u6362", -"Previous": "\u4e0a\u4e00\u4e2a", -"Next": "\u4e0b\u4e00\u4e2a", -"Find and replace...": "\u67e5\u627e\u5e76\u66ff\u6362...", -"Could not find the specified string.": "\u672a\u627e\u5230\u641c\u7d22\u5185\u5bb9.", -"Match case": "\u533a\u5206\u5927\u5c0f\u5199", -"Find whole words only": "\u5168\u5b57\u5339\u914d", -"Spell check": "\u62fc\u5199\u68c0\u67e5", -"Ignore": "\u5ffd\u7565", -"Ignore all": "\u5168\u90e8\u5ffd\u7565", -"Finish": "\u5b8c\u6210", -"Add to Dictionary": "\u6dfb\u52a0\u5230\u5b57\u5178", -"Insert table": "\u63d2\u5165\u8868\u683c", -"Table properties": "\u8868\u683c\u5c5e\u6027", -"Delete table": "\u5220\u9664\u8868\u683c", -"Cell": "\u5355\u5143\u683c", -"Row": "\u884c", +"Save": "\u4FDD\u5B58", +"Find": "\u67E5\u627E", +"Replace with": "\u66FF\u6362\u4E3A", +"Replace": "\u66FF\u6362", +"Replace all": "\u5168\u90E8\u66FF\u6362", +"Previous": "\u4E0A\u4E00\u4E2A", +"Next": "\u4E0B\u4E00\u4E2A", +"Find and replace...": "\u67E5\u627E\u5E76\u66FF\u6362...", +"Could not find the specified string.": "\u672A\u627E\u5230\u641C\u7D22\u5185\u5BB9.", +"Match case": "\u533A\u5206\u5927\u5C0F\u5199", +"Find whole words only": "\u5168\u5B57\u5339\u914D", +"Spell check": "\u62FC\u5199\u68C0\u67E5", +"Ignore": "\u5FFD\u7565", +"Ignore all": "\u5168\u90E8\u5FFD\u7565", +"Finish": "\u5B8C\u6210", +"Add to Dictionary": "\u6DFB\u52A0\u5230\u5B57\u5178", +"Insert table": "\u63D2\u5165\u8868\u683C", +"Table properties": "\u8868\u683C\u5C5E\u6027", +"Delete table": "\u5220\u9664\u8868\u683C", +"Cell": "\u5355\u5143\u683C", +"Row": "\u884C", "Column": "\u5217", -"Cell properties": "\u5355\u5143\u683c\u5c5e\u6027", -"Merge cells": "\u5408\u5e76\u5355\u5143\u683c", -"Split cell": "\u62c6\u5206\u5355\u5143\u683c", -"Insert row before": "\u5728\u4e0a\u65b9\u63d2\u5165", -"Insert row after": "\u5728\u4e0b\u65b9\u63d2\u5165", -"Delete row": "\u5220\u9664\u884c", -"Row properties": "\u884c\u5c5e\u6027", -"Cut row": "\u526a\u5207\u884c", -"Copy row": "\u590d\u5236\u884c", -"Paste row before": "\u7c98\u8d34\u5230\u4e0a\u65b9", -"Paste row after": "\u7c98\u8d34\u5230\u4e0b\u65b9", -"Insert column before": "\u5728\u5de6\u4fa7\u63d2\u5165", -"Insert column after": "\u5728\u53f3\u4fa7\u63d2\u5165", +"Cell properties": "\u5355\u5143\u683C\u5C5E\u6027", +"Merge cells": "\u5408\u5E76\u5355\u5143\u683C", +"Split cell": "\u62C6\u5206\u5355\u5143\u683C", +"Insert row before": "\u5728\u4E0A\u65B9\u63D2\u5165", +"Insert row after": "\u5728\u4E0B\u65B9\u63D2\u5165", +"Delete row": "\u5220\u9664\u884C", +"Row properties": "\u884C\u5C5E\u6027", +"Cut row": "\u526A\u5207\u884C", +"Copy row": "\u590D\u5236\u884C", +"Paste row before": "\u7C98\u8D34\u5230\u4E0A\u65B9", +"Paste row after": "\u7C98\u8D34\u5230\u4E0B\u65B9", +"Insert column before": "\u5728\u5DE6\u4FA7\u63D2\u5165", +"Insert column after": "\u5728\u53F3\u4FA7\u63D2\u5165", "Delete column": "\u5220\u9664\u5217", "Cols": "\u5217", -"Rows": "\u884c", -"Width": "\u5bbd", -"Height": "\u9ad8", -"Cell spacing": "\u5355\u5143\u683c\u5916\u95f4\u8ddd", -"Cell padding": "\u5355\u5143\u683c\u5185\u8fb9\u8ddd", -"Show caption": "\u663e\u793a\u6807\u9898", -"Left": "\u5de6\u5bf9\u9f50", -"Center": "\u5c45\u4e2d", -"Right": "\u53f3\u5bf9\u9f50", -"Cell type": "\u5355\u5143\u683c\u7c7b\u578b", -"Scope": "\u8303\u56f4", -"Alignment": "\u5bf9\u9f50\u65b9\u5f0f", -"H Align": "\u6c34\u5e73\u5bf9\u9f50", -"V Align": "\u5782\u76f4\u5bf9\u9f50", -"Top": "\u9876\u90e8\u5bf9\u9f50", -"Middle": "\u5782\u76f4\u5c45\u4e2d", -"Bottom": "\u5e95\u90e8\u5bf9\u9f50", -"Header cell": "\u8868\u5934\u5355\u5143\u683c", -"Row group": "\u884c\u7ec4", -"Column group": "\u5217\u7ec4", -"Row type": "\u884c\u7c7b\u578b", +"Rows": "\u884C", +"Width": "\u5BBD", +"Height": "\u9AD8", +"Cell spacing": "\u5355\u5143\u683C\u5916\u95F4\u8DDD", +"Cell padding": "\u5355\u5143\u683C\u5185\u8FB9\u8DDD", +"Show caption": "\u663E\u793A\u6807\u9898", +"Left": "\u5DE6\u5BF9\u9F50", +"Center": "\u5C45\u4E2D", +"Right": "\u53F3\u5BF9\u9F50", +"Cell type": "\u5355\u5143\u683C\u7C7B\u578B", +"Scope": "\u8303\u56F4", +"Alignment": "\u5BF9\u9F50\u65B9\u5F0F", +"H Align": "\u6C34\u5E73\u5BF9\u9F50", +"V Align": "\u5782\u76F4\u5BF9\u9F50", +"Top": "\u9876\u90E8\u5BF9\u9F50", +"Middle": "\u5782\u76F4\u5C45\u4E2D", +"Bottom": "\u5E95\u90E8\u5BF9\u9F50", +"Header cell": "\u8868\u5934\u5355\u5143\u683C", +"Row group": "\u884C\u7EC4", +"Column group": "\u5217\u7EC4", +"Row type": "\u884C\u7C7B\u578B", "Header": "\u8868\u5934", -"Body": "\u8868\u4f53", -"Footer": "\u8868\u5c3e", -"Border color": "\u8fb9\u6846\u989c\u8272", -"Insert template...": "\u63d2\u5165\u6a21\u677f...", -"Templates": "\u6a21\u677f", -"Template": "\u6a21\u677f", -"Text color": "\u6587\u5b57\u989c\u8272", -"Background color": "\u80cc\u666f\u8272", -"Custom...": "\u81ea\u5b9a\u4e49...", -"Custom color": "\u81ea\u5b9a\u4e49\u989c\u8272", -"No color": "\u65e0", -"Remove color": "\u79fb\u9664\u989c\u8272", -"Table of Contents": "\u5185\u5bb9\u5217\u8868", -"Show blocks": "\u663e\u793a\u533a\u5757\u8fb9\u6846", -"Show invisible characters": "\u663e\u793a\u4e0d\u53ef\u89c1\u5b57\u7b26", -"Word count": "\u5b57\u6570", -"Words: {0}": "\u5b57\u6570\uff1a{0}", -"{0} words": "{0} \u5b57", -"File": "\u6587\u4ef6", -"Edit": "\u7f16\u8f91", -"Insert": "\u63d2\u5165", -"View": "\u89c6\u56fe", -"Format": "\u683c\u5f0f", -"Table": "\u8868\u683c", -"Tools": "\u5de5\u5177", -"Powered by {0}": "\u7531{0}\u9a71\u52a8", -"Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help": "\u5728\u7f16\u8f91\u533a\u6309ALT-F9\u6253\u5f00\u83dc\u5355\uff0c\u6309ALT-F10\u6253\u5f00\u5de5\u5177\u680f\uff0c\u6309ALT-0\u67e5\u770b\u5e2e\u52a9", -"Image title": "\u56fe\u7247\u6807\u9898", -"Border width": "\u8fb9\u6846\u5bbd\u5ea6", -"Border style": "\u8fb9\u6846\u6837\u5f0f", -"Error": "\u9519\u8bef", -"Warn": "\u8b66\u544a", +"Body": "\u8868\u4F53", +"Footer": "\u8868\u5C3E", +"Border color": "\u8FB9\u6846\u989C\u8272", +"Insert template...": "\u63D2\u5165\u6A21\u677F...", +"Templates": "\u6A21\u677F", +"Template": "\u6A21\u677F", +"Text color": "\u6587\u5B57\u989C\u8272", +"Background color": "\u80CC\u666F\u8272", +"Custom...": "\u81EA\u5B9A\u4E49...", +"Custom color": "\u81EA\u5B9A\u4E49\u989C\u8272", +"No color": "\u65E0", +"Remove color": "\u79FB\u9664\u989C\u8272", +"Table of Contents": "\u5185\u5BB9\u5217\u8868", +"Show blocks": "\u663E\u793A\u533A\u5757\u8FB9\u6846", +"Show invisible characters": "\u663E\u793A\u4E0D\u53EF\u89C1\u5B57\u7B26", +"Word count": "\u5B57\u6570", +"Words: {0}": "\u5B57\u6570\uFF1A{0}", +"{0} words": "{0} \u5B57", +"File": "\u6587\u4EF6", +"Edit": "\u7F16\u8F91", +"Insert": "\u63D2\u5165", +"View": "\u89C6\u56FE", +"Format": "\u683C\u5F0F", +"Table": "\u8868\u683C", +"Tools": "\u5DE5\u5177", +"Powered by {0}": "\u7531{0}\u9A71\u52A8", +"Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help": "\u5728\u7F16\u8F91\u533A\u6309ALT-F9\u6253\u5F00\u83DC\u5355\uFF0C\u6309ALT-F10\u6253\u5F00\u5DE5\u5177\u680F\uFF0C\u6309ALT-0\u67E5\u770B\u5E2E\u52A9", +"Image title": "\u56FE\u7247\u6807\u9898", +"Border width": "\u8FB9\u6846\u5BBD\u5EA6", +"Border style": "\u8FB9\u6846\u6837\u5F0F", +"Error": "\u9519\u8BEF", +"Warn": "\u8B66\u544A", "Valid": "\u6709\u6548", -"To open the popup, press Shift+Enter": "\u6309Shitf+Enter\u952e\u6253\u5f00\u5bf9\u8bdd\u6846", -"Rich Text Area. Press ALT-0 for help.": "\u7f16\u8f91\u533a\u3002\u6309Alt+0\u952e\u6253\u5f00\u5e2e\u52a9\u3002", -"System Font": "\u7cfb\u7edf\u5b57\u4f53", -"Failed to upload image: {0}": "\u56fe\u7247\u4e0a\u4f20\u5931\u8d25: {0}", -"Failed to load plugin: {0} from url {1}": "\u63d2\u4ef6\u52a0\u8f7d\u5931\u8d25: {0} \u6765\u81ea\u94fe\u63a5 {1}", -"Failed to load plugin url: {0}": "\u63d2\u4ef6\u52a0\u8f7d\u5931\u8d25 \u94fe\u63a5: {0}", -"Failed to initialize plugin: {0}": "\u63d2\u4ef6\u521d\u59cb\u5316\u5931\u8d25: {0}", -"example": "\u793a\u4f8b", -"Search": "\u641c\u7d22", -"All": "\u5168\u90e8", -"Currency": "\u8d27\u5e01", -"Text": "\u6587\u5b57", -"Quotations": "\u5f15\u7528", -"Mathematical": "\u6570\u5b66", -"Extended Latin": "\u62c9\u4e01\u8bed\u6269\u5145", -"Symbols": "\u7b26\u53f7", -"Arrows": "\u7bad\u5934", -"User Defined": "\u81ea\u5b9a\u4e49", -"dollar sign": "\u7f8e\u5143\u7b26\u53f7", -"currency sign": "\u8d27\u5e01\u7b26\u53f7", -"euro-currency sign": "\u6b27\u5143\u7b26\u53f7", -"colon sign": "\u5192\u53f7", -"cruzeiro sign": "\u514b\u9c81\u8d5b\u7f57\u5e01\u7b26\u53f7", -"french franc sign": "\u6cd5\u90ce\u7b26\u53f7", -"lira sign": "\u91cc\u62c9\u7b26\u53f7", -"mill sign": "\u5bc6\u5c14\u7b26\u53f7", -"naira sign": "\u5948\u62c9\u7b26\u53f7", -"peseta sign": "\u6bd4\u585e\u5854\u7b26\u53f7", -"rupee sign": "\u5362\u6bd4\u7b26\u53f7", -"won sign": "\u97e9\u5143\u7b26\u53f7", -"new sheqel sign": "\u65b0\u8c22\u514b\u5c14\u7b26\u53f7", -"dong sign": "\u8d8a\u5357\u76fe\u7b26\u53f7", -"kip sign": "\u8001\u631d\u57fa\u666e\u7b26\u53f7", -"tugrik sign": "\u56fe\u683c\u91cc\u514b\u7b26\u53f7", -"drachma sign": "\u5fb7\u62c9\u514b\u9a6c\u7b26\u53f7", -"german penny symbol": "\u5fb7\u56fd\u4fbf\u58eb\u7b26\u53f7", -"peso sign": "\u6bd4\u7d22\u7b26\u53f7", -"guarani sign": "\u74dc\u62c9\u5c3c\u7b26\u53f7", -"austral sign": "\u6fb3\u5143\u7b26\u53f7", -"hryvnia sign": "\u683c\u91cc\u592b\u5c3c\u4e9a\u7b26\u53f7", -"cedi sign": "\u585e\u5730\u7b26\u53f7", -"livre tournois sign": "\u91cc\u5f17\u5f17\u5c14\u7b26\u53f7", -"spesmilo sign": "spesmilo\u7b26\u53f7", -"tenge sign": "\u575a\u6208\u7b26\u53f7", -"indian rupee sign": "\u5370\u5ea6\u5362\u6bd4", -"turkish lira sign": "\u571f\u8033\u5176\u91cc\u62c9", -"nordic mark sign": "\u5317\u6b27\u9a6c\u514b", -"manat sign": "\u9a6c\u7eb3\u7279\u7b26\u53f7", -"ruble sign": "\u5362\u5e03\u7b26\u53f7", -"yen character": "\u65e5\u5143\u5b57\u6837", -"yuan character": "\u4eba\u6c11\u5e01\u5143\u5b57\u6837", -"yuan character, in hong kong and taiwan": "\u5143\u5b57\u6837\uff08\u6e2f\u53f0\u5730\u533a\uff09", -"yen\/yuan character variant one": "\u5143\u5b57\u6837\uff08\u5927\u5199\uff09", -"Loading emoticons...": "\u52a0\u8f7d\u8868\u60c5\u7b26\u53f7...", -"Could not load emoticons": "\u4e0d\u80fd\u52a0\u8f7d\u8868\u60c5\u7b26\u53f7", -"People": "\u4eba\u7c7b", -"Animals and Nature": "\u52a8\u7269\u548c\u81ea\u7136", -"Food and Drink": "\u98df\u7269\u548c\u996e\u54c1", -"Activity": "\u6d3b\u52a8", -"Travel and Places": "\u65c5\u6e38\u548c\u5730\u70b9", -"Objects": "\u7269\u4ef6", -"Flags": "\u65d7\u5e1c", -"Characters": "\u5b57\u7b26", -"Characters (no spaces)": "\u5b57\u7b26(\u65e0\u7a7a\u683c)", -"Error: Form submit field collision.": "\u9519\u8bef: \u8868\u5355\u63d0\u4ea4\u5b57\u6bb5\u51b2\u7a81\u3002", -"Error: No form element found.": "\u9519\u8bef: \u6ca1\u6709\u8868\u5355\u63a7\u4ef6\u3002", -"Update": "\u66f4\u65b0", -"Color swatch": "\u989c\u8272\u6837\u672c", -"Turquoise": "\u9752\u7eff\u8272", -"Green": "\u7eff\u8272", -"Blue": "\u84dd\u8272", -"Purple": "\u7d2b\u8272", -"Navy Blue": "\u6d77\u519b\u84dd", -"Dark Turquoise": "\u6df1\u84dd\u7eff\u8272", -"Dark Green": "\u6df1\u7eff\u8272", -"Medium Blue": "\u4e2d\u84dd\u8272", -"Medium Purple": "\u4e2d\u7d2b\u8272", -"Midnight Blue": "\u6df1\u84dd\u8272", -"Yellow": "\u9ec4\u8272", -"Orange": "\u6a59\u8272", -"Red": "\u7ea2\u8272", -"Light Gray": "\u6d45\u7070\u8272", +"To open the popup, press Shift+Enter": "\u6309Shitf+Enter\u952E\u6253\u5F00\u5BF9\u8BDD\u6846", +"Rich Text Area. Press ALT-0 for help.": "\u7F16\u8F91\u533A\u3002\u6309Alt+0\u952E\u6253\u5F00\u5E2E\u52A9\u3002", +"System Font": "\u7CFB\u7EDF\u5B57\u4F53", +"Failed to upload image: {0}": "\u56FE\u7247\u4E0A\u4F20\u5931\u8D25: {0}", +"Failed to load plugin: {0} from url {1}": "\u63D2\u4EF6\u52A0\u8F7D\u5931\u8D25: {0} \u6765\u81EA\u94FE\u63A5 {1}", +"Failed to load plugin url: {0}": "\u63D2\u4EF6\u52A0\u8F7D\u5931\u8D25 \u94FE\u63A5: {0}", +"Failed to initialize plugin: {0}": "\u63D2\u4EF6\u521D\u59CB\u5316\u5931\u8D25: {0}", +"example": "\u793A\u4F8B", +"Search": "\u641C\u7D22", +"All": "\u5168\u90E8", +"Currency": "\u8D27\u5E01", +"Text": "\u6587\u5B57", +"Quotations": "\u5F15\u7528", +"Mathematical": "\u6570\u5B66", +"Extended Latin": "\u62C9\u4E01\u8BED\u6269\u5145", +"Symbols": "\u7B26\u53F7", +"Arrows": "\u7BAD\u5934", +"User Defined": "\u81EA\u5B9A\u4E49", +"dollar sign": "\u7F8E\u5143\u7B26\u53F7", +"currency sign": "\u8D27\u5E01\u7B26\u53F7", +"euro-currency sign": "\u6B27\u5143\u7B26\u53F7", +"colon sign": "\u5192\u53F7", +"cruzeiro sign": "\u514B\u9C81\u8D5B\u7F57\u5E01\u7B26\u53F7", +"french franc sign": "\u6CD5\u90CE\u7B26\u53F7", +"lira sign": "\u91CC\u62C9\u7B26\u53F7", +"mill sign": "\u5BC6\u5C14\u7B26\u53F7", +"naira sign": "\u5948\u62C9\u7B26\u53F7", +"peseta sign": "\u6BD4\u585E\u5854\u7B26\u53F7", +"rupee sign": "\u5362\u6BD4\u7B26\u53F7", +"won sign": "\u97E9\u5143\u7B26\u53F7", +"new sheqel sign": "\u65B0\u8C22\u514B\u5C14\u7B26\u53F7", +"dong sign": "\u8D8A\u5357\u76FE\u7B26\u53F7", +"kip sign": "\u8001\u631D\u57FA\u666E\u7B26\u53F7", +"tugrik sign": "\u56FE\u683C\u91CC\u514B\u7B26\u53F7", +"drachma sign": "\u5FB7\u62C9\u514B\u9A6C\u7B26\u53F7", +"german penny symbol": "\u5FB7\u56FD\u4FBF\u58EB\u7B26\u53F7", +"peso sign": "\u6BD4\u7D22\u7B26\u53F7", +"guarani sign": "\u74DC\u62C9\u5C3C\u7B26\u53F7", +"austral sign": "\u6FB3\u5143\u7B26\u53F7", +"hryvnia sign": "\u683C\u91CC\u592B\u5C3C\u4E9A\u7B26\u53F7", +"cedi sign": "\u585E\u5730\u7B26\u53F7", +"livre tournois sign": "\u91CC\u5F17\u5F17\u5C14\u7B26\u53F7", +"spesmilo sign": "spesmilo\u7B26\u53F7", +"tenge sign": "\u575A\u6208\u7B26\u53F7", +"indian rupee sign": "\u5370\u5EA6\u5362\u6BD4", +"turkish lira sign": "\u571F\u8033\u5176\u91CC\u62C9", +"nordic mark sign": "\u5317\u6B27\u9A6C\u514B", +"manat sign": "\u9A6C\u7EB3\u7279\u7B26\u53F7", +"ruble sign": "\u5362\u5E03\u7B26\u53F7", +"yen character": "\u65E5\u5143\u5B57\u6837", +"yuan character": "\u4EBA\u6C11\u5E01\u5143\u5B57\u6837", +"yuan character, in hong kong and taiwan": "\u5143\u5B57\u6837\uFF08\u6E2F\u53F0\u5730\u533A\uFF09", +"yen/yuan character variant one": "\u5143\u5B57\u6837\uFF08\u5927\u5199\uFF09", +"Loading emoticons...": "\u52A0\u8F7D\u8868\u60C5\u7B26\u53F7...", +"Could not load emoticons": "\u4E0D\u80FD\u52A0\u8F7D\u8868\u60C5\u7B26\u53F7", +"People": "\u4EBA\u7C7B", +"Animals and Nature": "\u52A8\u7269\u548C\u81EA\u7136", +"Food and Drink": "\u98DF\u7269\u548C\u996E\u54C1", +"Activity": "\u6D3B\u52A8", +"Travel and Places": "\u65C5\u6E38\u548C\u5730\u70B9", +"Objects": "\u7269\u4EF6", +"Flags": "\u65D7\u5E1C", +"Characters": "\u5B57\u7B26", +"Characters (no spaces)": "\u5B57\u7B26(\u65E0\u7A7A\u683C)", +"Error: Form submit field collision.": "\u9519\u8BEF: \u8868\u5355\u63D0\u4EA4\u5B57\u6BB5\u51B2\u7A81\u3002", +"Error: No form element found.": "\u9519\u8BEF: \u6CA1\u6709\u8868\u5355\u63A7\u4EF6\u3002", +"Update": "\u66F4\u65B0", +"Color swatch": "\u989C\u8272\u6837\u672C", +"Turquoise": "\u9752\u7EFF\u8272", +"Green": "\u7EFF\u8272", +"Blue": "\u84DD\u8272", +"Purple": "\u7D2B\u8272", +"Navy Blue": "\u6D77\u519B\u84DD", +"Dark Turquoise": "\u6DF1\u84DD\u7EFF\u8272", +"Dark Green": "\u6DF1\u7EFF\u8272", +"Medium Blue": "\u4E2D\u84DD\u8272", +"Medium Purple": "\u4E2D\u7D2B\u8272", +"Midnight Blue": "\u6DF1\u84DD\u8272", +"Yellow": "\u9EC4\u8272", +"Orange": "\u6A59\u8272", +"Red": "\u7EA2\u8272", +"Light Gray": "\u6D45\u7070\u8272", "Gray": "\u7070\u8272", -"Dark Yellow": "\u6697\u9ec4\u8272", -"Dark Orange": "\u6df1\u6a59\u8272", -"Dark Red": "\u6df1\u7ea2\u8272", -"Medium Gray": "\u4e2d\u7070\u8272", -"Dark Gray": "\u6df1\u7070\u8272", -"Black": "\u9ed1\u8272", -"White": "\u767d\u8272", -"Switch to or from fullscreen mode": "\u5207\u6362\u5168\u5c4f\u6a21\u5f0f", -"Open help dialog": "\u6253\u5f00\u5e2e\u52a9\u5bf9\u8bdd\u6846", -"history": "\u5386\u53f2", -"styles": "\u6837\u5f0f", -"formatting": "\u683c\u5f0f\u5316", -"alignment": "\u5bf9\u9f50", -"indentation": "\u7f29\u8fdb", -"permanent pen": "\u8bb0\u53f7\u7b14", -"comments": "\u5907\u6ce8", -"Anchor": "\u951a\u70b9", -"Special character": "\u7279\u6b8a\u7b26\u53f7", -"Code sample": "\u4ee3\u7801\u793a\u4f8b", -"Color": "\u989c\u8272", -"Emoticons": "\u8868\u60c5", -"Document properties": "\u6587\u6863\u5c5e\u6027", -"Image": "\u56fe\u7247", -"Insert link": "\u63d2\u5165\u94fe\u63a5", -"Target": "\u6253\u5f00\u65b9\u5f0f", -"Link": "\u94fe\u63a5", -"Poster": "\u5c01\u9762", -"Media": "\u5a92\u4f53", +"Dark Yellow": "\u6697\u9EC4\u8272", +"Dark Orange": "\u6DF1\u6A59\u8272", +"Dark Red": "\u6DF1\u7EA2\u8272", +"Medium Gray": "\u4E2D\u7070\u8272", +"Dark Gray": "\u6DF1\u7070\u8272", +"Black": "\u9ED1\u8272", +"White": "\u767D\u8272", +"Switch to or from fullscreen mode": "\u5207\u6362\u5168\u5C4F\u6A21\u5F0F", +"Open help dialog": "\u6253\u5F00\u5E2E\u52A9\u5BF9\u8BDD\u6846", +"history": "\u5386\u53F2", +"styles": "\u6837\u5F0F", +"formatting": "\u683C\u5F0F\u5316", +"alignment": "\u5BF9\u9F50", +"indentation": "\u7F29\u8FDB", +"permanent pen": "\u8BB0\u53F7\u7B14", +"comments": "\u5907\u6CE8", +"Anchor": "\u951A\u70B9", +"Special character": "\u7279\u6B8A\u7B26\u53F7", +"Code sample": "\u4EE3\u7801\u793A\u4F8B", +"Color": "\u989C\u8272", +"Emoticons": "\u8868\u60C5", +"Document properties": "\u6587\u6863\u5C5E\u6027", +"Image": "\u56FE\u7247", +"Insert link": "\u63D2\u5165\u94FE\u63A5", +"Target": "\u6253\u5F00\u65B9\u5F0F", +"Link": "\u94FE\u63A5", +"Poster": "\u5C01\u9762", +"Media": "\u5A92\u4F53", "Print": "\u6253\u5370", -"Prev": "\u4e0a\u4e00\u4e2a", -"Find and replace": "\u67e5\u627e\u548c\u66ff\u6362", -"Whole words": "\u5168\u5b57\u5339\u914d", -"Spellcheck": "\u62fc\u5199\u68c0\u67e5", +"Prev": "\u4E0A\u4E00\u4E2A", +"Find and replace": "\u67E5\u627E\u548C\u66FF\u6362", +"Whole words": "\u5168\u5B57\u5339\u914D", +"Spellcheck": "\u62FC\u5199\u68C0\u67E5", "Caption": "\u6807\u9898", -"Insert template": "\u63d2\u5165\u6a21\u677f" +"Insert template": "\u63D2\u5165\u6A21\u677F" }); \ No newline at end of file diff --git a/apps/vben5/apps/app-antd/src/adapter/component/index.ts b/apps/vben5/apps/app-antd/src/adapter/component/index.ts index 4ac7e46f3..b3bb2375f 100644 --- a/apps/vben5/apps/app-antd/src/adapter/component/index.ts +++ b/apps/vben5/apps/app-antd/src/adapter/component/index.ts @@ -6,14 +6,39 @@ /* eslint-disable vue/one-component-per-file */ import type { + AutoCompleteProps, + ButtonProps, + CascaderProps, + CheckboxGroupProps, + CheckboxProps, + DatePickerProps, + DividerProps, + InputNumberProps, + InputProps, + MentionsProps, + RadioGroupProps, + RadioProps, + RateProps, + SelectProps, + SpaceProps, + SwitchProps, + TextAreaProps, + TimePickerProps, + TreeSelectProps, UploadChangeParam, UploadFile, UploadProps, } from 'ant-design-vue'; +import type { RangePickerProps } from 'ant-design-vue/es/date-picker'; import type { Component, Ref } from 'vue'; -import type { BaseFormComponentType } from '@vben/common-ui'; +import type { + ApiComponentSharedProps, + BaseFormComponentType, + IconPickerProps, +} from '@vben/common-ui'; +import type { Sortable } from '@vben/hooks'; import type { Recordable } from '@vben/types'; import { @@ -21,6 +46,9 @@ import { defineAsyncComponent, defineComponent, h, + nextTick, + onMounted, + onUnmounted, ref, render, unref, @@ -33,6 +61,7 @@ import { IconPicker, VCropper, } from '@vben/common-ui'; +import { useSortable } from '@vben/hooks'; import { IconifyIcon } from '@vben/icons'; import { $t } from '@vben/locales'; import { isEmpty } from '@vben/utils'; @@ -40,7 +69,14 @@ import { isEmpty } from '@vben/utils'; import { FeatureStateCheck, GlobalFeatureStateCheck } from '@abp/features'; import { PermissionStateCheck } from '@abp/permissions'; import { TenantSelect } from '@abp/saas'; -import { message, Modal, notification } from 'ant-design-vue'; +import { + Empty, + InputSearch, + message, + Modal, + notification, + Tree, +} from 'ant-design-vue'; const ColorPicker = defineAsyncComponent(() => import('vue3-colorpicker').then((res) => { @@ -49,6 +85,16 @@ const ColorPicker = defineAsyncComponent(() => }), ); +type AdapterUploadProps = UploadProps & { + aspectRatio?: string; + crop?: boolean; + draggable?: boolean; + handleChange?: (event: UploadChangeParam) => void; + maxSize?: number; + onDragSort?: (oldIndex: number, newIndex: number) => void; + onHandleChange?: (event: UploadChangeParam) => void; +}; + const AutoComplete = defineAsyncComponent( () => import('ant-design-vue/es/auto-complete'), ); @@ -63,7 +109,6 @@ const DatePicker = defineAsyncComponent( () => import('ant-design-vue/es/date-picker'), ); const Divider = defineAsyncComponent(() => import('ant-design-vue/es/divider')); -const Empty = defineAsyncComponent(() => import('ant-design-vue/es/empty')); const Input = defineAsyncComponent(() => import('ant-design-vue/es/input')); const InputNumber = defineAsyncComponent( () => import('ant-design-vue/es/input-number'), @@ -71,9 +116,6 @@ const InputNumber = defineAsyncComponent( const InputPassword = defineAsyncComponent(() => import('ant-design-vue/es/input').then((res) => res.InputPassword), ); -const InputSearch = defineAsyncComponent(() => - import('ant-design-vue/es/input').then((res) => res.InputSearch), -); const Mentions = defineAsyncComponent( () => import('ant-design-vue/es/mentions'), ); @@ -94,7 +136,6 @@ const Textarea = defineAsyncComponent(() => const TimePicker = defineAsyncComponent( () => import('ant-design-vue/es/time-picker'), ); -const Tree = defineAsyncComponent(() => import('ant-design-vue/es/tree')); const TreeSelect = defineAsyncComponent( () => import('ant-design-vue/es/tree-select'), ); @@ -107,8 +148,8 @@ const PreviewGroup = defineAsyncComponent(() => import('ant-design-vue/es/image').then((res) => res.ImagePreviewGroup), ); -const withDefaultPlaceholder = ( - component: T, +const withDefaultPlaceholder = ( + component: Component, type: 'input' | 'select', componentProps: Recordable = {}, ) => { @@ -141,260 +182,261 @@ const withDefaultPlaceholder = ( }); }; -const withPreviewUpload = () => { - // 检查是否为图片文件的辅助函数 - const isImageFile = (file: UploadFile): boolean => { - const imageExtensions = new Set([ - 'bmp', - 'gif', - 'jpeg', - 'jpg', - 'png', - 'svg', - 'webp', - ]); - if (file.url) { - try { - const pathname = new URL(file.url, 'http://localhost').pathname; - const ext = pathname.split('.').pop()?.toLowerCase(); - return ext ? imageExtensions.has(ext) : false; - } catch { - const ext = file.url?.split('.').pop()?.toLowerCase(); - return ext ? imageExtensions.has(ext) : false; - } - } - if (!file.type) { - const ext = file.name?.split('.').pop()?.toLowerCase(); - return ext ? imageExtensions.has(ext) : false; +const IMAGE_EXTENSIONS = new Set([ + 'bmp', + 'gif', + 'jpeg', + 'jpg', + 'png', + 'svg', + 'webp', +]); + +/** + * 检查是否为图片文件 + */ +function isImageFile(file: UploadFile): boolean { + if (file.url) { + try { + const pathname = new URL(file.url, 'http://localhost').pathname; + const ext = pathname.split('.').pop()?.toLowerCase(); + return ext ? IMAGE_EXTENSIONS.has(ext) : false; + } catch { + const ext = file.url?.split('.').pop()?.toLowerCase(); + return ext ? IMAGE_EXTENSIONS.has(ext) : false; } - return file.type.startsWith('image/'); + } + if (!file.type) { + const ext = file.name?.split('.').pop()?.toLowerCase(); + return ext ? IMAGE_EXTENSIONS.has(ext) : false; + } + return file.type.startsWith('image/'); +} + +/** + * 创建默认的上传按钮插槽 + */ +function createDefaultUploadSlots(listType: string, placeholder: string) { + if (listType === 'picture-card') { + return { default: () => placeholder }; + } + return { + default: () => + h( + Button, + { + icon: h(IconifyIcon, { + icon: 'ant-design:upload-outlined', + class: 'mb-1 size-4', + }), + }, + () => placeholder, + ), }; - // 创建默认的上传按钮插槽 - const createDefaultSlotsWithUpload = ( - listType: string, - placeholder: string, - ) => { - switch (listType) { - case 'picture-card': { - return { - default: () => placeholder, - }; - } - default: { - return { - default: () => - h( - Button, - { - icon: h(IconifyIcon, { - icon: 'ant-design:upload-outlined', - class: 'mb-1 size-4', - }), +} + +/** + * 获取文件的 Base64 + */ +function getBase64(file: File): Promise { + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.readAsDataURL(file); + reader.addEventListener('load', () => resolve(reader.result as string)); + reader.addEventListener('error', reject); + }); +} + +/** + * 预览图片 + */ +async function previewImage( + file: UploadFile, + visible: Ref, + fileList: Ref, +) { + // 非图片文件直接打开链接 + if (!isImageFile(file)) { + const url = file.url || file.preview; + if (url) { + window.open(url, '_blank'); + } else { + message.error($t('ui.formRules.previewWarning')); + } + return; + } + + const [ImageComponent, PreviewGroupComponent] = await Promise.all([ + Image, + PreviewGroup, + ]); + + // 过滤图片文件并生成预览 + const imageFiles = (unref(fileList) || []).filter((f) => isImageFile(f)); + + for (const imgFile of imageFiles) { + if (!imgFile.url && !imgFile.preview && imgFile.originFileObj) { + imgFile.preview = await getBase64(imgFile.originFileObj); + } + } + + const container = document.createElement('div'); + document.body.append(container); + let isUnmounted = false; + + const currentIndex = imageFiles.findIndex((f) => f.uid === file.uid); + + const PreviewWrapper = { + setup() { + return () => { + if (isUnmounted) return null; + return h( + PreviewGroupComponent, + { + class: 'hidden', + preview: { + visible: visible.value, + current: currentIndex, + onVisibleChange: (value: boolean) => { + visible.value = value; + if (!value) { + setTimeout(() => { + if (!isUnmounted && container) { + isUnmounted = true; + render(null, container); + container.remove(); + } + }, 300); + } }, - () => placeholder, + }, + }, + () => + imageFiles.map((imgFile) => + h(ImageComponent, { + key: imgFile.uid, + src: imgFile.url || imgFile.preview, + }), ), - }; - } - } + ); + }; + }, }; - // 构建预览图片组 - const previewImage = async ( - file: UploadFile, - visible: Ref, - fileList: Ref, - ) => { - // 如果当前文件不是图片,直接打开 - if (!isImageFile(file)) { - if (file.url) { - window.open(file.url, '_blank'); - } else if (file.preview) { - window.open(file.preview, '_blank'); - } else { - message.error($t('ui.formRules.previewWarning')); - } - return; - } - // 对于图片文件,继续使用预览组 - const [ImageComponent, PreviewGroupComponent] = await Promise.all([ - Image, - PreviewGroup, - ]); - - const getBase64 = (file: File) => { - return new Promise((resolve, reject) => { - const reader = new FileReader(); - reader.readAsDataURL(file); - reader.addEventListener('load', () => resolve(reader.result)); - reader.addEventListener('error', (error) => reject(error)); - }); - }; - // 从fileList中过滤出所有图片文件 - const imageFiles = (unref(fileList) || []).filter((element) => - isImageFile(element), - ); - - // 为所有没有预览地址的图片生成预览 - for (const imgFile of imageFiles) { - if (!imgFile.url && !imgFile.preview && imgFile.originFileObj) { - imgFile.preview = (await getBase64(imgFile.originFileObj)) as string; - } - } - const container: HTMLElement | null = document.createElement('div'); + render(h(PreviewWrapper), container); +} + +/** + * 图片裁剪操作 + */ +function cropImage(file: File, aspectRatio: string | undefined) { + return new Promise((resolve, reject) => { + const container = document.createElement('div'); document.body.append(container); - // 用于追踪组件是否已卸载 let isUnmounted = false; + let objectUrl: null | string = null; - const PreviewWrapper = { + const open = ref(true); + const cropperRef = ref | null>(null); + + const closeModal = () => { + open.value = false; + setTimeout(() => { + if (!isUnmounted && container) { + if (objectUrl) { + URL.revokeObjectURL(objectUrl); + } + isUnmounted = true; + render(null, container); + container.remove(); + } + }, 300); + }; + + const CropperWrapper = { setup() { return () => { if (isUnmounted) return null; + if (!objectUrl) { + objectUrl = URL.createObjectURL(file); + } return h( - PreviewGroupComponent, + Modal, { - class: 'hidden', - preview: { - visible: visible.value, - // 设置初始显示的图片索引 - current: imageFiles.findIndex((f) => f.uid === file.uid), - onVisibleChange: (value: boolean) => { - visible.value = value; - if (!value) { - // 延迟清理,确保动画完成 - setTimeout(() => { - if (!isUnmounted && container) { - isUnmounted = true; - render(null, container); - container.remove(); - } - }, 300); + open: open.value, + title: h('div', {}, [ + $t('ui.crop.title'), + h( + 'span', + { + class: `${aspectRatio ? '' : 'hidden'} ml-2 text-sm text-gray-400 font-normal`, + }, + $t('ui.crop.titleTip', [aspectRatio]), + ), + ]), + centered: true, + width: 548, + keyboard: false, + maskClosable: false, + closable: false, + cancelText: $t('common.cancel'), + okText: $t('ui.crop.confirm'), + destroyOnClose: true, + onOk: async () => { + const cropper = cropperRef.value; + if (!cropper) { + reject(new Error('Cropper not found')); + closeModal(); + return; + } + try { + const dataUrl = await cropper.getCropImage(); + if (dataUrl) { + resolve(dataUrl); + } else { + reject(new Error($t('ui.crop.errorTip'))); } - }, + } catch { + reject(new Error($t('ui.crop.errorTip'))); + } finally { + closeModal(); + } + }, + onCancel() { + resolve(''); + closeModal(); }, }, () => - // 渲染所有图片文件 - imageFiles.map((imgFile) => - h(ImageComponent, { - key: imgFile.uid, - src: imgFile.url || imgFile.preview, - }), - ), + h(VCropper, { + ref: (ref: any) => (cropperRef.value = ref), + img: objectUrl as string, + aspectRatio, + }), ); }; }, }; - render(h(PreviewWrapper), container); - }; - - // 图片裁剪操作 - const cropImage = (file: File, aspectRatio: string | undefined) => { - return new Promise((resolve, reject) => { - const container: HTMLElement | null = document.createElement('div'); - document.body.append(container); - - // 用于追踪组件是否已卸载 - let isUnmounted = false; - let objectUrl: null | string = null; - - const open = ref(true); - const cropperRef = ref | null>(null); - - const closeModal = () => { - open.value = false; - // 延迟清理,确保动画完成 - setTimeout(() => { - if (!isUnmounted && container) { - if (objectUrl) { - URL.revokeObjectURL(objectUrl); - } - isUnmounted = true; - render(null, container); - container.remove(); - } - }, 300); - }; - - const CropperWrapper = { - setup() { - return () => { - if (isUnmounted) return null; - if (!objectUrl) { - objectUrl = URL.createObjectURL(file); - } - return h( - Modal, - { - open: open.value, - title: h('div', {}, [ - $t('ui.crop.title'), - h( - 'span', - { - class: `${aspectRatio ? '' : 'hidden'} ml-2 text-sm text-gray-400 font-normal`, - }, - $t('ui.crop.titleTip', [aspectRatio]), - ), - ]), - centered: true, - width: 548, - keyboard: false, - maskClosable: false, - closable: false, - cancelText: $t('common.cancel'), - okText: $t('ui.crop.confirm'), - destroyOnClose: true, - onOk: async () => { - const cropper = cropperRef.value; - if (!cropper) { - reject(new Error('Cropper not found')); - closeModal(); - return; - } - try { - const dataUrl = await cropper.getCropImage(); - resolve(dataUrl); - } catch { - reject(new Error($t('ui.crop.errorTip'))); - } finally { - closeModal(); - } - }, - onCancel() { - resolve(''); - closeModal(); - }, - }, - () => - h(VCropper, { - ref: (ref: any) => (cropperRef.value = ref), - img: objectUrl as string, - aspectRatio, - }), - ); - }; - }, - }; - - render(h(CropperWrapper), container); - }); - }; + render(h(CropperWrapper), container); + }); +} +/** + * 带预览功能的上传组件 + */ +const withPreviewUpload = () => { return defineComponent({ name: Upload.name, emits: ['update:modelValue'], - setup: ( + setup( props: any, { attrs, slots, emit }: { attrs: any; emit: any; slots: any }, - ) => { + ) { const previewVisible = ref(false); - - const placeholder = attrs?.placeholder || $t(`ui.placeholder.upload`); - + const placeholder = attrs?.placeholder || $t('ui.placeholder.upload'); const listType = attrs?.listType || attrs?.['list-type'] || 'text'; - const fileList = ref( attrs?.fileList || attrs?.['file-list'] || [], ); @@ -408,12 +450,14 @@ const withPreviewUpload = () => { file: UploadFile, originFileList: Array, ) => { + // 文件大小限制 if (maxSize.value && (file.size || 0) / 1024 / 1024 > maxSize.value) { message.error($t('ui.formRules.sizeLimit', [maxSize.value])); file.status = 'removed'; return false; } - // 多选或者非图片不唤起裁剪框 + + // 图片裁剪处理 if ( attrs.crop && !attrs.multiple && @@ -421,14 +465,11 @@ const withPreviewUpload = () => { isImageFile(file) ) { file.status = 'removed'; - // antd Upload组件问题 file参数获取的是UploadFile类型对象无法取到File类型 所以通过originFileList[0]获取 const blob = await cropImage(originFileList[0], aspectRatio.value); - return new Promise((resolve, reject) => { - if (!blob) { - return reject(new Error($t('ui.crop.errorTip'))); - } - resolve(blob); - }); + if (!blob) { + throw new Error($t('ui.crop.errorTip')); + } + return blob; } return attrs.beforeUpload?.(file) ?? true; @@ -436,12 +477,9 @@ const withPreviewUpload = () => { const handleChange = (event: UploadChangeParam) => { try { - // 行内写法 handleChange: (event) => {} attrs.handleChange?.(event); - // template写法 @handle-change="(event) => {}" attrs.onHandleChange?.(event); } catch (error) { - // Avoid breaking internal v-model sync on user handler errors console.error(error); } fileList.value = event.fileList.filter( @@ -458,21 +496,88 @@ const withPreviewUpload = () => { await previewImage(file, previewVisible, fileList); }; - const renderUploadButton = (): any => { - const isDisabled = attrs.disabled; - - // 如果禁用,不渲染上传按钮 - if (isDisabled) { - return null; - } - - // 否则渲染默认上传按钮 + const renderUploadButton = () => { + if (attrs.disabled) return null; return isEmpty(slots) - ? createDefaultSlotsWithUpload(listType, placeholder) + ? createDefaultUploadSlots(listType, placeholder) : slots; }; - // 可以监听到表单API设置的值 + // 拖拽排序 + const draggable = computed( + () => (attrs.draggable ?? false) && !attrs.disabled, + ); + const uploadId = `upload-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`; + const sortableInstance = ref(null); + + const styleId = `upload-drag-style-${uploadId}`; + + function injectDragStyle() { + if (!document.querySelector(`[id="${styleId}"]`)) { + const style = document.createElement('style'); + style.id = styleId; + style.textContent = ` + [data-upload-id="${uploadId}"] .ant-upload-list-item { cursor: move; } + [data-upload-id="${uploadId}"] .ant-upload-list-item:hover { box-shadow: 0 2px 8px rgba(0,0,0,0.15); } + `; + document.head.append(style); + } + } + + function removeDragStyle() { + document.querySelector(`[id="${styleId}"]`)?.remove(); + } + + async function initSortable(retryCount = 0) { + if (!draggable.value) return; + + injectDragStyle(); + await nextTick(); + await new Promise((resolve) => setTimeout(resolve, 100)); + + const container = document.querySelector( + `[data-upload-id="${uploadId}"] .ant-upload-list`, + ) as HTMLElement; + + if (!container) { + if (retryCount < 5) { + setTimeout(() => initSortable(retryCount + 1), 200); + } + return; + } + + const { initializeSortable } = useSortable(container, { + animation: 300, + delay: 400, + delayOnTouchOnly: true, + filter: + '.ant-upload-select, .ant-upload-list-item-error, .ant-upload-list-item-uploading', + onEnd: (evt) => { + const { oldIndex, newIndex } = evt; + if ( + oldIndex === undefined || + newIndex === undefined || + oldIndex === newIndex + ) { + return; + } + + const list = [...(fileList.value || [])]; + const [movedItem] = list.splice(oldIndex, 1); + if (movedItem) { + list.splice(newIndex, 0, movedItem); + fileList.value = list; + } + + attrs.onDragSort?.(oldIndex, newIndex); + emit('update:modelValue', fileList.value); + }, + }); + + sortableInstance.value = await initializeSortable(); + } + + // 监听表单值变化 watch( () => attrs.modelValue, (res) => { @@ -480,18 +585,28 @@ const withPreviewUpload = () => { }, ); + onMounted(initSortable); + onUnmounted(() => { + sortableInstance.value?.destroy(); + removeDragStyle(); + }); + return () => h( - Upload, - { - ...props, - ...attrs, - fileList: fileList.value, - beforeUpload: handleBeforeUpload, - onChange: handleChange, - onPreview: handlePreview, - }, - renderUploadButton(), + 'div', + { 'data-upload-id': uploadId, class: 'w-full' }, + h( + Upload, + { + ...props, + ...attrs, + fileList: fileList.value, + beforeUpload: handleBeforeUpload, + onChange: handleChange, + onPreview: handlePreview, + }, + renderUploadButton() as any, + ), ); }, }); @@ -536,6 +651,39 @@ export type ComponentType = | 'Upload' | BaseFormComponentType; +/** + * 与 {@link ComponentType} 中注册的组件名一一对应,便于 Schema 上 `component` + `componentProps` 联动提示 + */ +export interface ComponentPropsMap { + ApiCascader: ApiComponentSharedProps & CascaderProps; + ApiSelect: ApiComponentSharedProps & SelectProps; + ApiTreeSelect: ApiComponentSharedProps & TreeSelectProps; + AutoComplete: AutoCompleteProps; + Cascader: CascaderProps; + Checkbox: CheckboxProps; + CheckboxGroup: CheckboxGroupProps; + DatePicker: DatePickerProps; + DefaultButton: ButtonProps; + Divider: DividerProps; + IconPicker: IconPickerProps; + Input: InputProps; + InputNumber: InputNumberProps; + InputPassword: InputProps; + Mentions: MentionsProps; + PrimaryButton: ButtonProps; + Radio: RadioProps; + RadioGroup: RadioGroupProps; + RangePicker: RangePickerProps; + Rate: RateProps; + Select: SelectProps; + Space: SpaceProps; + Switch: SwitchProps; + Textarea: TextAreaProps; + TimePicker: TimePickerProps; + TreeSelect: TreeSelectProps; + Upload: AdapterUploadProps; +} + async function initComponentAdapter() { const components: Partial> = { // 如果你的组件体积比较大,可以使用异步加载 diff --git a/apps/vben5/apps/app-antd/src/adapter/request/index.ts b/apps/vben5/apps/app-antd/src/adapter/request/index.ts index 072e67d12..8db1a7434 100644 --- a/apps/vben5/apps/app-antd/src/adapter/request/index.ts +++ b/apps/vben5/apps/app-antd/src/adapter/request/index.ts @@ -56,7 +56,7 @@ export function initRequestClient() { const timezoneStore = useTimezoneStore(); if (accessStore.accessToken) { - config.headers.Authorization = `${accessStore.accessToken}`; + config.headers.Authorization = accessStore.accessToken; } config.headers['Accept-Language'] = preferences.app.locale; config.headers['X-Request-From'] = 'vben'; @@ -76,7 +76,7 @@ export function initRequestClient() { }); // response数据解构 - requestClient.addResponseInterceptor({ + requestClient.addResponseInterceptor({ fulfilled: (response) => { const { data, status } = response; const { hasWrapResult, getData } = useWrapperResult(response); diff --git a/apps/vben5/apps/app-antd/src/bootstrap.ts b/apps/vben5/apps/app-antd/src/bootstrap.ts index f75585871..5dc0bbd3d 100644 --- a/apps/vben5/apps/app-antd/src/bootstrap.ts +++ b/apps/vben5/apps/app-antd/src/bootstrap.ts @@ -2,6 +2,7 @@ import { createApp, watchEffect } from 'vue'; import { registerAccessDirective } from '@vben/access'; import { registerLoadingDirective } from '@vben/common-ui'; +import { providePluginsOptions } from '@vben/plugins'; import { preferences } from '@vben/preferences'; import { initStores } from '@vben/stores'; import '@vben/styles'; @@ -12,7 +13,7 @@ import { useTitle } from '@vueuse/core'; import { $t, setupI18n } from '#/locales'; import { initComponentAdapter } from './adapter/component'; -import { initSetupVbenForm } from './adapter/form'; +import { initSetupVbenForm, useVbenForm } from './adapter/form'; import { initRequestClient } from './adapter/request'; import App from './app.vue'; import { router } from './router'; @@ -25,6 +26,11 @@ async function bootstrap(namespace: string) { // 初始化表单组件 await initSetupVbenForm(); + // 注入插件全局配置 + providePluginsOptions({ + form: { useVbenForm }, + }); + // 初始化axios initRequestClient(); @@ -64,6 +70,10 @@ async function bootstrap(namespace: string) { // 配置路由及路由守卫 app.use(router); + // 配置@tanstack/vue-query + const { VueQueryPlugin } = await import('@tanstack/vue-query'); + app.use(VueQueryPlugin); + // 配置Motion插件 const { MotionPlugin } = await import('@vben/plugins/motion'); app.use(MotionPlugin); diff --git a/apps/vben5/apps/app-antd/src/layouts/auth.vue b/apps/vben5/apps/app-antd/src/layouts/auth.vue index 18d415bc7..525e2112f 100644 --- a/apps/vben5/apps/app-antd/src/layouts/auth.vue +++ b/apps/vben5/apps/app-antd/src/layouts/auth.vue @@ -15,8 +15,7 @@ const logo = computed(() => preferences.logo.source); :app-name="appName" :logo="logo" :page-description="$t('authentication.pageDesc')" - :page-title="$t('authentication.pageTitle')" - > + :page-title="$t('authentication.pageTitle')"> diff --git a/apps/vben5/apps/app-antd/src/layouts/basic.vue b/apps/vben5/apps/app-antd/src/layouts/basic.vue index 507ee63d8..f3565effb 100644 --- a/apps/vben5/apps/app-antd/src/layouts/basic.vue +++ b/apps/vben5/apps/app-antd/src/layouts/basic.vue @@ -108,13 +108,17 @@ function handleMakeAll() { } async function handleLinkUser(token: string) { - const { currentUser, currentTenant } = abpStore.application!; const extraQueryParams: Record = { - LinkUserId: currentUser.id!, LinkToken: token, }; - if (currentTenant.id) { - extraQueryParams.LinkTenantId = currentTenant.id; + if (abpStore.application) { + const { currentUser, currentTenant } = abpStore.application; + if (currentUser.id) { + extraQueryParams.LinkUserId = currentUser.id; + } + if (currentTenant.id) { + extraQueryParams.LinkTenantId = currentTenant.id; + } } // 跳转登录页,交由后端处理 await authStore.oidcLogin({ @@ -173,8 +177,7 @@ watch( :menus :tag-text="userInfo?.email" :text="userInfo?.realName" - @logout="handleLogout" - /> + @logout="handleLogout" /> {{ description }} @@ -186,14 +189,12 @@ watch( :dot="showDot" :notifications="notifications" @clear="handleNoticeClear" - @make-all="handleMakeAll" - /> + @make-all="handleMakeAll" /> diff --git a/apps/vben5/apps/app-antd/src/preferences.ts b/apps/vben5/apps/app-antd/src/preferences.ts index 1591bd1d8..9b9f94727 100644 --- a/apps/vben5/apps/app-antd/src/preferences.ts +++ b/apps/vben5/apps/app-antd/src/preferences.ts @@ -1,4 +1,7 @@ -import { defineOverridesPreferences } from '@vben/preferences'; +import { + appCopyrightPreferences, + defineOverridesPreferences, +} from '@vben/preferences'; /** * @description 项目配置文件 @@ -13,6 +16,7 @@ export const overridesPreferences = defineOverridesPreferences({ enableRefreshToken: true, name: import.meta.env.VITE_APP_TITLE, }, + copyright: appCopyrightPreferences, logo: { source: '/resource/img/logo.png', }, diff --git a/apps/vben5/apps/app-antd/src/store/auth.ts b/apps/vben5/apps/app-antd/src/store/auth.ts index 06791a955..6ac164de0 100644 --- a/apps/vben5/apps/app-antd/src/store/auth.ts +++ b/apps/vben5/apps/app-antd/src/store/auth.ts @@ -58,7 +58,6 @@ export const useAuthStore = defineStore('auth', () => { accessToken: user.access_token, tokenType: user.token_type, refreshToken: user.refresh_token ?? '', - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion expiresIn: user.expires_in!, }); } catch (error: any) { @@ -81,7 +80,6 @@ export const useAuthStore = defineStore('auth', () => { accessToken: user.access_token, tokenType: user.token_type, refreshToken: user.refresh_token ?? '', - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion expiresIn: user.expires_in!, }, onSuccess, @@ -104,7 +102,6 @@ export const useAuthStore = defineStore('auth', () => { accessToken: user.access_token, tokenType: user.token_type, refreshToken: user.refresh_token ?? '', - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion expiresIn: user.expires_in!, }, onSuccess, @@ -132,7 +129,6 @@ export const useAuthStore = defineStore('auth', () => { accessToken: user.access_token, tokenType: user.token_type, refreshToken: user.refresh_token ?? '', - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion expiresIn: user.expires_in!, }, onSuccess, @@ -163,7 +159,6 @@ export const useAuthStore = defineStore('auth', () => { accessToken: user.access_token, tokenType: user.token_type, refreshToken: user.refresh_token ?? '', - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion expiresIn: user.expires_in!, }, onSuccess, @@ -190,7 +185,6 @@ export const useAuthStore = defineStore('auth', () => { accessToken: user.access_token, tokenType: user.token_type, refreshToken: user.refresh_token ?? '', - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion expiresIn: user.expires_in!, }, onSuccess, @@ -228,7 +222,6 @@ export const useAuthStore = defineStore('auth', () => { } async function fetchUserInfo() { - let userInfo: null | (UserInfo & { [key: string]: any }) = null; let userInfoRes: { [key: string]: any } = {}; const user = await oAuthService.getUser(); if (user) { @@ -237,7 +230,7 @@ export const useAuthStore = defineStore('auth', () => { const abpConfig = await getConfigApi({ includeLocalizationResources: false, }); - userInfo = { + const userInfo = { userId: userInfoRes.sub ?? abpConfig.currentUser.id, username: userInfoRes.uniqueName ?? abpConfig.currentUser.userName, realName: diff --git a/apps/vben5/apps/app-antd/src/views/_core/authentication/code-login.vue b/apps/vben5/apps/app-antd/src/views/_core/authentication/code-login.vue index 8238ed31d..12ec951d2 100644 --- a/apps/vben5/apps/app-antd/src/views/_core/authentication/code-login.vue +++ b/apps/vben5/apps/app-antd/src/views/_core/authentication/code-login.vue @@ -86,6 +86,5 @@ async function handleLogin(values: Recordable) { ref="codeLogin" :form-schema="formSchema" :loading="loading" - @submit="handleLogin" - /> + @submit="handleLogin" /> diff --git a/apps/vben5/apps/app-antd/src/views/_core/authentication/forget-password.vue b/apps/vben5/apps/app-antd/src/views/_core/authentication/forget-password.vue index 3e676213e..5676a503b 100644 --- a/apps/vben5/apps/app-antd/src/views/_core/authentication/forget-password.vue +++ b/apps/vben5/apps/app-antd/src/views/_core/authentication/forget-password.vue @@ -160,6 +160,5 @@ async function handleSubmit(values: Recordable) { :form-schema="formSchema" :submit-button-text="$t('AbpAccount.ResetPassword')" :loading="loading" - @submit="handleSubmit" - /> + @submit="handleSubmit" /> diff --git a/apps/vben5/apps/app-antd/src/views/_core/authentication/login.vue b/apps/vben5/apps/app-antd/src/views/_core/authentication/login.vue index c414aad1d..de31f751b 100644 --- a/apps/vben5/apps/app-antd/src/views/_core/authentication/login.vue +++ b/apps/vben5/apps/app-antd/src/views/_core/authentication/login.vue @@ -162,8 +162,7 @@ onMounted(onInit); :form-schema="formSchema" :loading="authStore.loginLoading" :show-register="isTrue('Abp.Account.IsSelfRegistrationEnabled')" - @submit="onLogin" - > + @submit="onLogin"> diff --git a/apps/vben5/apps/app-antd/src/views/_core/authentication/register.vue b/apps/vben5/apps/app-antd/src/views/_core/authentication/register.vue index b1a5de726..5c3dc93ff 100644 --- a/apps/vben5/apps/app-antd/src/views/_core/authentication/register.vue +++ b/apps/vben5/apps/app-antd/src/views/_core/authentication/register.vue @@ -91,6 +91,5 @@ function handleSubmit(value: Recordable) { + @submit="handleSubmit" /> diff --git a/apps/vben5/apps/app-antd/src/views/_core/authentication/two-factor-login.vue b/apps/vben5/apps/app-antd/src/views/_core/authentication/two-factor-login.vue index cf9270deb..0736dbb24 100644 --- a/apps/vben5/apps/app-antd/src/views/_core/authentication/two-factor-login.vue +++ b/apps/vben5/apps/app-antd/src/views/_core/authentication/two-factor-login.vue @@ -130,33 +130,28 @@ async function onSendCode(api: () => Promise) { ref="formRef" :label-col="{ span: 6 }" :model="formModel" - :wrapper-col="{ span: 18 }" - > + :wrapper-col="{ span: 18 }"> + required>