🔱: [client] sync upgrade with 21 commits [trident-sync]

perf: 优化antdv4 示例授权页面tree的样式
build: publish success
chore: 1
chore: 1
chore: 1
fix: getFileName支持item参数

https://github.com/fast-crud/fast-crud/issues/385
fix: fs-form独立使用支持插槽

https://github.com/fast-crud/fast-crud/issues/389
fix: 修复三级以上路由页面无法缓存的问题

https://github.com/fast-crud/fast-crud/issues/394
perf: form.wrapper.buttons支持compute动态计算
feat: 表单支持变更关闭前提醒保存,form.wrapper支持beforeClose事件
fix: 修复图片裁剪按钮上下和左右相反的bug

https://github.com/fast-crud/fast-crud/issues/402
perf: alioss getAuthorization接口支持后台返回key

https://github.com/fast-crud/fast-crud/issues/405
perf: alioss getAuthorization接口支持后台返回key

https://github.com/fast-crud/fast-crud/issues/405
perf: fs-dict-tree支持插槽

https://github.com/fast-crud/fast-crud/issues/407
perf: 单选、多选、select、tree-select、table-select 都提供selected-change事件,可以获取选中的dict选项
feat: table-select 支持查看模式

https://github.com/fast-crud/fast-crud/issues/413
perf: 优化fs-admin可以在手机上操作
chore: pnpm workspace问题优化
docs: 1
chore: antdv4 支持主题色选择
...
pull/39/head
GitHub Actions Bot 2024-06-15 18:32:36 +00:00
parent 9caa4cd1d4
commit ad360e81cb
173 changed files with 3386 additions and 1108 deletions

View File

@ -1,3 +1,8 @@
VITE_APP_API=/api
#登录与权限关闭
VITE_APP_PM_ENABLED=true
VITE_APP_PM_ENABLED=false
VITE_APP_TITLE=fs-admin-antdv4
VITE_APP_SLOGAN=面向配置的CRUD开发快如闪电
VITE_APP_COPYRIGHT=Copyright © 2021 Greper
VITE_APP_LOGO_PATH=./images/logo/logo.svg
VITE_APP_PROJECT_PATH=https://github.com/fast-crud/fast-crud

View File

@ -30,6 +30,8 @@ jobs:
- name: push to gitee # 4. 执行同步
run: |
git remote add upstream https://gitee.com/fast-crud/fs-admin-antdv
git remote add upstream https://gitee.com/fast-crud/fs-admin-antdv4
git push --set-upstream upstream main

View File

@ -7,34 +7,60 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
### Bug Fixes
* 修复图片裁剪按钮上下和左右相反的bug ([c62b8d4](https://github.com/fast-crud/fast-crud/commit/c62b8d42371364b4e50d7289055ba2adfdff05aa))
* 修复三级以上路由页面无法缓存的问题 ([9ce8c7a](https://github.com/fast-crud/fast-crud/commit/9ce8c7a6a5fc12f347351ca74213ff9c542820d3))
* 修复提交表单只有一个输入框时点回车会刷新浏览器的问题 ([3d756ea](https://github.com/fast-crud/fast-crud/commit/3d756eaab6894355053e078424835d3edbd80025))
* 修复fs-table.less中的颜色污染 ([a0b1de4](https://github.com/fast-crud/fast-crud/commit/a0b1de45668f882e13669c5aee484d3d2532ce25))
* edit-wang 改成edit-wang5 ([7b994c1](https://github.com/fast-crud/fast-crud/commit/7b994c19637aa4b6399acbf362d4dc6a73c07ca4))
### Performance Improvements
* fs-dict-tree支持插槽 ([fca02f9](https://github.com/fast-crud/fast-crud/commit/fca02f9f6bb3b027ef39b7366c205ffbf3620dd8))
* 富文本编辑器增加为空校验示例 ([3e51ac1](https://github.com/fast-crud/fast-crud/commit/3e51ac1c2c22f2dc5200134732fc0146a4a0fd2d))
* 图片裁剪组件中英文支持 ([8b5b3f6](https://github.com/fast-crud/fast-crud/commit/8b5b3f61bc67e17ed13ded4a5519434249d5c4df))
* alioss getAuthorization接口支持后台返回key ([75e5b14](https://github.com/fast-crud/fast-crud/commit/75e5b1449238fbae86f002c290771a6b9fd1f824))
## [1.20.2](https://github.com/fast-crud/fast-crud/compare/v1.20.1...v1.20.2) (2024-03-21)
**Note:** Version bump only for package @fast-crud/fs-admin-antdv
### Bug Fixes
## [1.20.1](https://github.com/fast-crud/fast-crud/compare/v1.20.0...v1.20.1) (2024-02-27)
**Note:** Version bump only for package @fast-crud/fs-admin-antdv
# [1.20.0](https://github.com/fast-crud/fast-crud/compare/v1.19.3...v1.20.0) (2024-01-28)
* 修复单元格valueChange 的value 改变滞后的问题 ([768c233](https://github.com/fast-crud/fast-crud/commit/768c233c915dc4277f3fb49106bf99f0bd1fb31c))
### Performance Improvements
* 升级依赖版本 ([42ae562](https://github.com/fast-crud/fast-crud/commit/42ae56289cc9d80ee1b3c1f9b7b2dd4656e9ba84))
* table-select element增加radio列 ([b56b5df](https://github.com/fast-crud/fast-crud/commit/b56b5df79c6ce634bdac0545e83629f6f5587d42))
## [1.20.1](https://github.com/fast-crud/fast-crud/compare/v1.20.0...v1.20.1) (2024-02-27)
**Note:** Version bump only for package @fast-crud/fs-admin-antdv4
# [1.20.0](https://github.com/fast-crud/fast-crud/compare/v1.19.3...v1.20.0) (2024-01-28)
### Bug Fixes
* 修复查询valueChange 修改form无效的bug ([054f8b4](https://github.com/fast-crud/fast-crud/commit/054f8b4b808a52f6d8daf2d19ee3adf43f693c0a))
### Performance Improvements
* 优化element 日期示例格式化问题输入数据格式告警问题range样式问题 ([66fd07b](https://github.com/fast-crud/fast-crud/commit/66fd07b96143b77ed73b5e3b88182070ebdb4c80))
* 优化form.wrapper.buttons的默认配置 ([61f2ae5](https://github.com/fast-crud/fast-crud/commit/61f2ae5600814a59e2eaad8933892c1ec9f57c69))
* 优化free模式支持默认不激活 ([aeaf0a6](https://github.com/fast-crud/fast-crud/commit/aeaf0a683ecc24dcb86036daea363f3019347299))
* first 增加 tour示例 ([b1ae0aa](https://github.com/fast-crud/fast-crud/commit/b1ae0aa2c901b38ca61151c4eba6e238b55fa0f0))
* dict-tree组件无需手动配置labelName keyName ([c8b0ee1](https://github.com/fast-crud/fast-crud/commit/c8b0ee1ee5fa22e73b3a8ef77e1ad3335351dc70))
## [1.19.3](https://github.com/fast-crud/fast-crud/compare/v1.19.2...v1.19.3) (2023-12-15)
**Note:** Version bump only for package @fast-crud/fs-admin-antdv
### Bug Fixes
* antdv4 日期组件bug修复 ([a55b3e2](https://github.com/fast-crud/fast-crud/commit/a55b3e293a94396bbdfbd7d6dabb19d886cb8e16))
### Performance Improvements
* 增加表单label=0px示例 ([500d793](https://github.com/fast-crud/fast-crud/commit/500d793d72d727e8945cf7bca47aee684856bd80))
## [1.19.2](https://github.com/fast-crud/fast-crud/compare/v1.19.1...v1.19.2) (2023-11-22)
**Note:** Version bump only for package @fast-crud/fs-admin-antdv
### Bug Fixes
* **editable:** 行编辑只能删除第一条数据的bug ([daf041f](https://github.com/fast-crud/fast-crud/commit/daf041f21cf531b4e32655248e522c96dd06f460))
## [1.19.1](https://github.com/fast-crud/fast-crud/compare/v1.19.0...v1.19.1) (2023-11-20)
@ -44,9 +70,9 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
# [1.19.0](https://github.com/fast-crud/fast-crud/compare/v1.18.5...v1.19.0) (2023-11-20)
### Features
### Bug Fixes
* **editable:** editable优化重构分三种模式free、row、cell本次为破坏性更新请谨慎升级 ([a592780](https://github.com/fast-crud/fast-crud/commit/a592780697dc723117bce8759b2c02223ed930c8))
* **editable:** 支持多级数据 ([89db59e](https://github.com/fast-crud/fast-crud/commit/89db59ea2b3dbe8227399086513e27aa7c2ab7aa))
## [1.18.5](https://github.com/fast-crud/fast-crud/compare/v1.18.4...v1.18.5) (2023-11-08)
@ -60,91 +86,119 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
* 修复afterSubmit返回false仍然关闭对话框的bug ([80337ff](https://github.com/fast-crud/fast-crud/commit/80337ffc46eda74d526562d9f27c43a2b6eb0534))
### Performance Improvements
* 新增国际手机号输入框 ([ebabee2](https://github.com/fast-crud/fast-crud/commit/ebabee2f61caed3678f0681330ed3cb044803a2f))
* antdv 支持按钮组 ([cfdefdf](https://github.com/fast-crud/fast-crud/commit/cfdefdf89bfe7e037d1a8d3c6416cf38678074c9))
## [1.18.3](https://github.com/fast-crud/fast-crud/compare/v1.18.2...v1.18.3) (2023-10-26)
**Note:** Version bump only for package @fast-crud/fs-admin-antdv
**Note:** Version bump only for package @fast-crud/fs-admin-antdv4
## [1.18.2](https://github.com/fast-crud/fast-crud/compare/v1.18.1...v1.18.2) (2023-10-26)
**Note:** Version bump only for package @fast-crud/fs-admin-antdv
### Bug Fixes
* 导出配置columns报错的bug ([d12f881](https://github.com/fast-crud/fast-crud/commit/d12f881f83e8c521673dc49d656e457a4fc67102))
* 修复动态切换component.name报 resolveComponent 只能在setup和render中使用的问题 ([8792962](https://github.com/fast-crud/fast-crud/commit/8792962156346dbf05445d8f143b23296d60c781))
## [1.18.1](https://github.com/fast-crud/fast-crud/compare/v1.18.0...v1.18.1) (2023-10-26)
**Note:** Version bump only for package @fast-crud/fs-admin-antdv
### Bug Fixes
* 取消 searchCopyFormProps valueResolve配置 ([ae55fda](https://github.com/fast-crud/fast-crud/commit/ae55fda1f9aa206d644f2e3da654201f0831f0be))
# [1.18.0](https://github.com/fast-crud/fast-crud/compare/v1.17.5...v1.18.0) (2023-10-25)
### Bug Fixes
* 修复antdv4drawer弹窗过时的api ([9514db6](https://github.com/fast-crud/fast-crud/commit/9514db6768b5a5e1bef283b961438a6671f7df79))
* 修复element下按钮图标异常问题 ([4959c2e](https://github.com/fast-crud/fast-crud/commit/4959c2e15b89f6d2fec50864f1453f2965a85159))
* 增加文档链接 ([2b9f525](https://github.com/fast-crud/fast-crud/commit/2b9f525988c34ea322695b1a40de0628a627e50a))
### Features
* 新特性CrudOptionsPlugin ([9e1ac6d](https://github.com/fast-crud/fast-crud/commit/9e1ac6df56622b3b75cd5a23ea565f5c722085de))
* ui-demoui-interface独立 ([d78f040](https://github.com/fast-crud/fast-crud/commit/d78f040cd666d072937b0350edb2da11871206e6))
### Performance Improvements
* 导出增加loading ([6530c29](https://github.com/fast-crud/fast-crud/commit/6530c29615be9e1ff04029a962d521bed2df30a6))
* 优化文档搜索 ([19fff41](https://github.com/fast-crud/fast-crud/commit/19fff41b3f431e2bd1c84274a7d17ad96a547b03))
## [1.17.5](https://github.com/fast-crud/fast-crud/compare/v1.17.4...v1.17.5) (2023-09-26)
**Note:** Version bump only for package @fast-crud/fs-admin-antdv
**Note:** Version bump only for package @fast-crud/fs-admin-antdv4
## [1.17.4](https://github.com/fast-crud/fast-crud/compare/v1.17.3...v1.17.4) (2023-09-26)
**Note:** Version bump only for package @fast-crud/fs-admin-antdv
**Note:** Version bump only for package @fast-crud/fs-admin-antdv4
## [1.17.3](https://github.com/fast-crud/fast-crud/compare/v1.17.2...v1.17.3) (2023-09-23)
**Note:** Version bump only for package @fast-crud/fs-admin-antdv
**Note:** Version bump only for package @fast-crud/fs-admin-antdv4
## [1.17.2](https://github.com/fast-crud/fast-crud/compare/v1.17.1...v1.17.2) (2023-09-16)
### Bug Fixes
* 修复naive 时间示例无法修改的bug ([6ab9218](https://github.com/fast-crud/fast-crud/commit/6ab92188fc19d792de8bed0190853c444784b009))
* antdv 查询框label上置错位的bug ([00a35ad](https://github.com/fast-crud/fast-crud/commit/00a35ade86de3f2b9c3c336f3c8dda6f224e1abf))
## [1.17.1](https://github.com/fast-crud/fast-crud/compare/v1.17.0...v1.17.1) (2023-09-13)
**Note:** Version bump only for package @fast-crud/fs-admin-antdv
**Note:** Version bump only for package @fast-crud/fs-admin-antdv4
# [1.17.0](https://github.com/fast-crud/fast-crud/compare/v1.16.11...v1.17.0) (2023-09-12)
### Bug Fixes
* 修复element 图片裁剪组件无法横向排列的bug ([25fa258](https://github.com/fast-crud/fast-crud/commit/25fa25855e9750813d5a959a8b09ff6e90b04c1c))
### Features
* table-select支持 ([1c5b749](https://github.com/fast-crud/fast-crud/commit/1c5b7493a7782581a5f2a5bff843b135eb531f92))
### Performance Improvements
* dict.getNodesByValues 修改为单例模式也可以运行无需配置prototype优化性能 ([be4a6a7](https://github.com/fast-crud/fast-crud/commit/be4a6a744a97cb92e6da2b8094dd3930be6ebdc2))
* 增加重置后清空排序设置演示 ([6a563ad](https://github.com/fast-crud/fast-crud/commit/6a563ad67b87f66e2765e47f72c5d4831cf06801))
## [1.16.11](https://github.com/fast-crud/fast-crud/compare/v1.16.10...v1.16.11) (2023-09-03)
**Note:** Version bump only for package @fast-crud/fs-admin-antdv
**Note:** Version bump only for package @fast-crud/fs-admin-antdv4
## [1.16.10](https://github.com/fast-crud/fast-crud/compare/v1.16.9...v1.16.10) (2023-09-03)
**Note:** Version bump only for package @fast-crud/fs-admin-antdv
**Note:** Version bump only for package @fast-crud/fs-admin-antdv4
## [1.16.9](https://github.com/fast-crud/fast-crud/compare/v1.16.8...v1.16.9) (2023-09-03)
**Note:** Version bump only for package @fast-crud/fs-admin-antdv
### Performance Improvements
* 表单下所有组件优化为宽度100% ([da38460](https://github.com/fast-crud/fast-crud/commit/da384605f9c6bfc26359a369613dce4f48a3ba64))
## [1.16.8](https://github.com/fast-crud/fast-crud/compare/v1.16.7...v1.16.8) (2023-09-03)
### Performance Improvements
* 表单labelWidth演示 ([72f5372](https://github.com/fast-crud/fast-crud/commit/72f5372948f9aefebb0aba8671c277e8d80566bd))
* 翻页后自动滚动到顶部 ([a6e5f67](https://github.com/fast-crud/fast-crud/commit/a6e5f6740a59780995283c7d787864fdd65f0d4b))
## [1.16.7](https://github.com/fast-crud/fast-crud/compare/v1.16.6...v1.16.7) (2023-08-21)
**Note:** Version bump only for package @fast-crud/fs-admin-antdv
**Note:** Version bump only for package @fast-crud/fs-admin-antdv4
## [1.16.6](https://github.com/fast-crud/fast-crud/compare/v1.16.5...v1.16.6) (2023-08-21)
**Note:** Version bump only for package @fast-crud/fs-admin-antdv
**Note:** Version bump only for package @fast-crud/fs-admin-antdv4
## [1.16.5](https://github.com/fast-crud/fast-crud/compare/v1.16.4...v1.16.5) (2023-08-20)
### Bug Fixes
* 修复initialForm会覆盖editForm的bug ([c1d0d8a](https://github.com/fast-crud/fast-crud/commit/c1d0d8a3bef2586386a59c9211de7ca45be83f08))
**Note:** Version bump only for package @fast-crud/fs-admin-antdv4
## [1.16.4](https://github.com/fast-crud/fast-crud/compare/v1.16.3...v1.16.4) (2023-08-18)
**Note:** Version bump only for package @fast-crud/fs-admin-antdv
**Note:** Version bump only for package @fast-crud/fs-admin-antdv4
## [1.16.3](https://github.com/fast-crud/fast-crud/compare/v1.16.2...v1.16.3) (2023-08-18)
@ -154,19 +208,19 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
## [1.16.2](https://github.com/fast-crud/fast-crud/compare/v1.16.1...v1.16.2) (2023-08-10)
**Note:** Version bump only for package @fast-crud/fs-admin-antdv
**Note:** Version bump only for package @fast-crud/fs-admin-antdv4
## [1.16.1](https://github.com/fast-crud/fast-crud/compare/v1.16.0...v1.16.1) (2023-08-09)
**Note:** Version bump only for package @fast-crud/fs-admin-antdv
**Note:** Version bump only for package @fast-crud/fs-admin-antdv4
# [1.16.0](https://github.com/fast-crud/fast-crud/compare/v1.15.1...v1.16.0) (2023-08-07)
**Note:** Version bump only for package @fast-crud/fs-admin-antdv
**Note:** Version bump only for package @fast-crud/fs-admin-antdv4
## [1.15.1](https://github.com/fast-crud/fast-crud/compare/v1.15.0...v1.15.1) (2023-08-05)
**Note:** Version bump only for package @fast-crud/fs-admin-antdv
**Note:** Version bump only for package @fast-crud/fs-admin-antdv4
# [1.15.0](https://github.com/fast-crud/fast-crud/compare/v1.14.7...v1.15.0) (2023-08-05)

View File

@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" href="/logo.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>antdv-fast-crud</title>
<title><%= title %></title>
<link rel="stylesheet" type="text/css" href="/index.css" />
</head>
<body>
@ -14,8 +14,8 @@
<div class="fs-bootstrap__loading"></div>
</div>
<div class="fs-bootstrap__footer">
<a href="https://github.com/fast-crud/fast-crud" target="_blank">
https://github.com/fast-crud/fast-crud
<a href="<%= projectPath %>" target="_blank">
<%= projectPath %>
</a>
</div>
</div>

View File

@ -1,5 +1,5 @@
{
"name": "@fast-crud/fs-admin-antdv",
"name": "@fast-crud/fs-admin-antdv4",
"version": "1.21.0",
"private": true,
"scripts": {
@ -9,7 +9,7 @@
"debug": "vite --mode debug --open",
"debug:pm": "vite --mode debugpm",
"debug:force": "vite --force --mode debug",
"build": "npm run tsc && vite build ",
"build": " vite build ",
"serve": "vite preview",
"preview": "vite preview",
"pretty-quick": "pretty-quick",
@ -22,98 +22,97 @@
"author": "Greper",
"license": "MIT",
"dependencies": {
"@ant-design/colors": "^7.0.0",
"@ant-design/icons-vue": "^6.1.0",
"@aws-sdk/client-s3": "^3.383.0",
"@aws-sdk/s3-request-presigner": "^3.383.0",
"@ant-design/colors": "^7.0.2",
"@ant-design/icons-vue": "^7.0.1",
"@aws-sdk/client-s3": "^3.535.0",
"@aws-sdk/s3-request-presigner": "^3.535.0",
"@fast-crud/fast-crud": "^1.21.0",
"@fast-crud/fast-extends": "^1.21.0",
"@fast-crud/ui-antdv": "^1.21.0",
"@fast-crud/ui-antdv4": "^1.21.0",
"@fast-crud/ui-interface": "^1.21.0",
"@iconify/iconify": "^3.1.1",
"@iconify/json": "^2.2.98",
"@iconify/vue": "^4.1.1",
"@purge-icons/generated": "^0.9.0",
"@soerenmartius/vue3-clipboard": "^0.1.2",
"ant-design-vue": "^3.2.20",
"axios": "^1.3.4",
"axios-mock-adapter": "^1.21.2",
"ant-design-vue": "^4.1.2",
"axios": "^1.6.8",
"axios-mock-adapter": "^1.22.0",
"base64-js": "^1.5.1",
"better-scroll": "^2.5.1",
"china-division": "^2.6.1",
"core-js": "^3.32.0",
"cos-js-sdk-v5": "^1.4.19",
"cropperjs": "^1.5.13",
"dayjs": "^1.11.9",
"highlight.js": "^11.8.0",
"china-division": "^2.7.0",
"core-js": "^3.36.0",
"cos-js-sdk-v5": "^1.7.0",
"cropperjs": "^1.6.1",
"dayjs": "^1.11.10",
"highlight.js": "^11.9.0",
"lodash-es": "^4.17.21",
"mitt": "^3.0.1",
"nprogress": "^0.2.0",
"object-assign": "^4.1.1",
"pinia": "2.1.6",
"qiniu-js": "^3.4.1",
"sortablejs": "^1.15.0",
"vue": "^3.3.4",
"pinia": "2.1.7",
"qiniu-js": "^3.4.2",
"sortablejs": "^1.15.2",
"vue": "^3.4.21",
"vue-cropperjs": "^5.0.0",
"vue-i18n": "^9.2.2",
"vue-router": "^4.2.4",
"vue-i18n": "^9.10.2",
"vue-router": "^4.3.0",
"vuedraggable": "^2.24.3"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^25.0.3",
"@rollup/plugin-node-resolve": "^15.1.0",
"@types/chai": "^4.3.5",
"@types/lodash-es": "^4.17.8",
"@types/mocha": "^10.0.1",
"@types/node": "^20.4.7",
"@types/nprogress": "^0.2.0",
"@typescript-eslint/eslint-plugin": "^6.2.1",
"@typescript-eslint/parser": "^6.2.1",
"@vitejs/plugin-legacy": "^4.1.1",
"@vitejs/plugin-vue": "^4.2.3",
"@vitejs/plugin-vue-jsx": "^3.0.1",
"@vue/compiler-sfc": "^3.3.4",
"@vue/eslint-config-typescript": "^11.0.3",
"@vue/test-utils": "^2.4.1",
"autoprefixer": "^10.4.14",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-node-resolve": "^15.2.3",
"@types/chai": "^4.3.12",
"@types/lodash-es": "^4.17.12",
"@types/mocha": "^10.0.6",
"@types/node": "^20.11.28",
"@types/nprogress": "^0.2.3",
"@typescript-eslint/eslint-plugin": "^7.2.0",
"@typescript-eslint/parser": "^7.2.0",
"@vitejs/plugin-legacy": "^5.3.2",
"@vitejs/plugin-vue": "^5.0.4",
"@vitejs/plugin-vue-jsx": "^3.1.0",
"@vue/compiler-sfc": "^3.4.21",
"@vue/eslint-config-typescript": "^13.0.0",
"@vue/test-utils": "^2.4.5",
"autoprefixer": "^10.4.18",
"caller-path": "^4.0.0",
"chai": "^4.3.7",
"dependency-cruiser": "^13.1.1",
"chai": "^5.1.0",
"dependency-cruiser": "^16.2.3",
"dot": "^1.1.3",
"eslint": "8.46.0",
"eslint-config-prettier": "^8.10.0",
"eslint-plugin-import": "^2.28.0",
"eslint": "8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-vue": "^9.16.1",
"esno": "^0.17.0",
"husky": "^8.0.3",
"less": "^4.1.3",
"less-loader": "^11.1.3",
"lint-staged": "^13.2.3",
"postcss": "^8.4.27",
"prettier": "3.0.1",
"pretty-quick": "^3.1.3",
"rimraf": "^5.0.1",
"rollup": "^3.27.2",
"rollup-plugin-visualizer": "^5.9.2",
"stylelint": "^15.10.2",
"eslint-plugin-vue": "^9.23.0",
"esno": "^4.7.0",
"husky": "^9.0.11",
"less": "^4.2.0",
"less-loader": "^12.2.0",
"lint-staged": "^15.2.2",
"postcss": "^8.4.35",
"prettier": "3.2.5",
"pretty-quick": "^4.0.0",
"rimraf": "^5.0.5",
"rollup": "^4.13.0",
"rollup-plugin-visualizer": "^5.12.0",
"stylelint": "^16.2.1",
"stylelint-config-prettier": "^9.0.5",
"stylelint-order": "^6.0.3",
"tailwindcss": "^3.3.3",
"terser": "^5.19.2",
"ts-node": "^10.9.1",
"typescript": "5.1.6",
"unplugin-vue-define-options": "^1.3.14",
"vite": "^4.4.8",
"stylelint-order": "^6.0.4",
"tailwindcss": "^3.4.1",
"terser": "^5.29.2",
"ts-node": "^10.9.2",
"tslint": "^6.1.3",
"typescript": "5.4.2",
"unplugin-vue-define-options": "^1.4.2",
"vite": "^5.1.6",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-html": "^3.2.2",
"vite-plugin-optimize-persist": "^0.1.2",
"vite-plugin-package-config": "^0.1.1",
"vite-plugin-purge-icons": "^0.9.2",
"vite-plugin-purge-icons": "^0.10.0",
"vite-plugin-theme": "^0.8.6",
"vite-plugin-windicss": "^1.9.0",
"vue-eslint-parser": "^9.3.1",
"vite-plugin-windicss": "^1.9.3",
"vue-eslint-parser": "^9.4.2",
"vue-tsc": "^1.8.8",
"windicss": "^3.5.6"
},

View File

@ -1,7 +0,0 @@
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="500" height="500" viewBox="0 0 500.000000 500.000000"
>
<path d="M28.34 56.68h28.34V36.12H28.34a7.79 7.79 0 1 1 0-15.58h19.84v9.05h8.5V12H28.34a16.29 16.29 0 0 0 0 32.58h19.84v3.56H28.34a19.84 19.84 0 0 1 0-39.68h28.34V0H28.34a28.34 28.34 0 0 0 0 56.68z"
transform="translate(70, 76) scale(6,6)"
></path>
</svg>

Before

Width:  |  Height:  |  Size: 402 B

View File

@ -1,44 +0,0 @@
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="800" height="300" viewBox="0 0 800.000000 300.000000"
>
<g fill="#333">
<path d="M28.34 56.68h28.34V36.12H28.34a7.79 7.79 0 1 1 0-15.58h19.84v9.05h8.5V12H28.34a16.29 16.29 0 0 0 0 32.58h19.84v3.56H28.34a19.84 19.84 0 0 1 0-39.68h28.34V0H28.34a28.34 28.34 0 0 0 0 56.68z"
transform="translate(40, 40) scale(4,4)"
></path>
<g transform="translate(280, 260) scale(2,2)">
<path d="M28.95-58.70L49.98-58.70L49.98-48.22L33.70-48.22Q27.37-48.22 24.46-47.34Q21.56-46.46 19.62-43.91L19.62-43.91Q18.30-42.15 17.82-40.39Q17.34-38.63 16.98-34.41L16.98-34.41L49.98-34.41L49.98-23.94L16.98-23.94Q17.69-16.37 21.47-13.42Q25.26-10.47 34.32-10.47L34.32-10.47L49.98-10.47L49.98 0L33.70 0Q27.10 0 22.09-0.79L22.09-0.79Q14.17-2.11 9.50-7.74L9.50-7.74Q2.82-15.84 2.82-29.66L2.82-29.66Q2.82-44.97 12.23-53.50L12.23-53.50Q15.49-56.41 19.14-57.55Q22.79-58.70 28.95-58.70L28.95-58.70Z"
transform="translate(0 0) "
></path>
<path d="M28.51-22.26L18.48-22.26L18.48 0L5.98 0L5.98-58.70L34.67-58.70Q46.99-58.70 51.83-55.53L51.83-55.53Q55.18-53.42 56.98-49.94Q58.78-46.46 58.78-42.33L58.78-42.33Q58.78-33.97 54.56-29.39L54.56-29.39Q51.92-26.66 47.61-25.26L47.61-25.26Q51.04-24.02 52.80-22.66Q54.56-21.30 55.97-18.66L55.97-18.66Q57.02-16.54 57.51-14.61Q57.99-12.67 58.26-8.89L58.26-8.89Q58.78-2.55 59.66 0L59.66 0L45.67 0Q45.06-2.02 44.35-8.36L44.35-8.36Q43.91-13.46 42.55-16.19Q41.18-18.92 38.46-20.50L38.46-20.50Q35.02-22.35 28.51-22.26L28.51-22.26ZM18.48-48.22L18.48-32.74L35.99-32.74Q40.39-32.74 42.24-34.06L42.24-34.06Q45.06-35.99 45.06-40.83L45.06-40.83Q45.06-46.20 40.83-47.70L40.83-47.70Q39.34-48.22 35.99-48.22L35.99-48.22L18.48-48.22Z"
transform="translate(58.855999999999995 0) "
></path>
<path d="M19.01 0L19.01-48.22L0.35-48.22L0.35-58.70L50.95-58.70L50.95-48.22L31.50-48.22L31.50 0L19.01 0Z"
transform="translate(126.68799999999999 0) "
></path>
<path d="M5.98 0L5.98-58.70L30.89-58.70Q40.22-58.70 45.32-56.85L45.32-56.85Q54.74-53.42 57.90-44.26L57.90-44.26Q60.28-37.22 60.28-29.22L60.28-29.22Q60.28-21.30 57.99-14.26L57.99-14.26Q55.70-7.04 50.42-3.61L50.42-3.61Q47.08-1.50 43.08-0.75Q39.07 0 30.89 0L30.89 0L5.98 0ZM30.89-48.22L18.48-48.22L18.48-10.47L30.89-10.47Q39.07-10.47 42.24-14.08L42.24-14.08Q44.18-16.37 45.36-20.50Q46.55-24.64 46.55-29.30L46.55-29.30Q46.55-34.50 45.14-38.81Q43.74-43.12 41.45-45.23L41.45-45.23Q38.10-48.22 30.89-48.22L30.89-48.22Z"
transform="translate(183.07999999999998 0) "
></path>
</g>
<!-- <path d="M13.00-21.91L21.24-21.91L21.24-17.23L14.04-17.23Q10.39-17.23-->
<!-- 9-15.62L9-15.62Q7.65-14.08-->
<!-- 7.65-10.93L7.65-10.93Q7.65-7.42 9.86-5.80L9.86-5.80Q10.75-5.17-->
<!-- 11.81-4.93Q12.87-4.68-->
<!-- 14.76-4.68L14.76-4.68L21.24-4.68L21.24-->
<!-- 0L13.00 0Q9.67 0 7.74-0.67Q5.80-1.35-->
<!-- 4.32-3.01L4.32-3.01Q1.48-6.17-->
<!-- 1.48-11.03L1.48-11.03Q1.48-16.88-->
<!-- 4.86-19.75L4.86-19.75Q6.21-20.93-->
<!-- 8.10-21.42Q9.99-21.91-->
<!-- 13.00-21.91L13.00-21.91ZM31.05-13.32L43.74-13.32L43.74-8.64L31.05-8.64Q31.23-6.48-->
<!-- 32.44-5.58Q33.66-4.68 36.41-4.68L36.41-4.68L43.74-4.68L43.74 0L35.73 0Q33.12 0 31.48-0.47Q29.83-0.94 28.39-2.02L28.39-2.02Q24.39-5.13 24.39-11.25L24.39-11.25Q24.39-15.21 26.50-18.18L26.50-18.18Q27.94-20.20 29.97-21.06Q31.99-21.91 35.28-21.91L35.28-21.91L43.74-21.91L43.74-17.23L35.73-17.23Q33.25-17.23 32.27-16.40Q31.27-15.57 31.05-13.32L31.05-13.32ZM48.64 0L48.64-21.91L57.55-21.91Q60.30-21.91 61.81-21.53Q63.31-21.15 64.31-20.25L64.31-20.25Q65.30-19.35 65.70-18Q66.10-16.65 66.10-14.13L66.10-14.13L66.10-12.01L60.30-12.01L60.30-13.18Q60.30-15.52 59.49-16.38Q58.68-17.23 56.38-17.23L56.38-17.23L54.67-17.23L54.67 0L48.64 0ZM67.50-21.91L71.33-21.91L71.33-30.02L77.36-30.02L77.36-21.91L82.94-21.91L82.94-17.23L77.36-17.23L77.36-9.27Q77.36-6.48 77.85-5.76L77.85-5.76Q78.61-4.68 80.55-4.68L80.55-4.68L82.94-4.68L82.94 0L78.57 0Q74.66 0 72.99-1.89Q71.33-3.78 71.33-8.23L71.33-8.23L71.33-17.23L67.50-17.23L67.50-21.91ZM96.08-21.91L101.75-21.91L101.75-30.02L107.73-30.02L107.73 0L97.38 0Q94.23 0 92.61-0.49L92.61-0.49Q88.78-1.71 86.90-5.26L86.90-5.26Q85.59-7.65 85.59-11.12L85.59-11.12Q85.59-16.74 89.37-19.84L89.37-19.84Q91.84-21.91 96.08-21.91L96.08-21.91ZM97.38-4.68L101.75-4.68L101.75-17.23L97.38-17.23Q94.50-17.23 93.02-15.30L93.02-15.30Q91.71-13.68 91.71-11.12L91.71-11.12Q91.71-7.38 93.87-5.76L93.87-5.76Q95.36-4.68 97.38-4.68L97.38-4.68Z"-->
<!-- fill="#2c3e50"-->
<!-- transform="translate(300, 270) scale(4,4)"-->
<!-- ></path>-->
<text x="300" y="100" font-size="50" font-weight="bold">让你的证书永不过期</text>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -1,44 +0,0 @@
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="800" height="300" viewBox="0 0 800.000000 300.000000"
>
<g fill="#fff">
<path d="M28.34 56.68h28.34V36.12H28.34a7.79 7.79 0 1 1 0-15.58h19.84v9.05h8.5V12H28.34a16.29 16.29 0 0 0 0 32.58h19.84v3.56H28.34a19.84 19.84 0 0 1 0-39.68h28.34V0H28.34a28.34 28.34 0 0 0 0 56.68z"
transform="translate(40, 40) scale(4,4)"
></path>
<g transform="translate(280, 260) scale(2,2)">
<path d="M28.95-58.70L49.98-58.70L49.98-48.22L33.70-48.22Q27.37-48.22 24.46-47.34Q21.56-46.46 19.62-43.91L19.62-43.91Q18.30-42.15 17.82-40.39Q17.34-38.63 16.98-34.41L16.98-34.41L49.98-34.41L49.98-23.94L16.98-23.94Q17.69-16.37 21.47-13.42Q25.26-10.47 34.32-10.47L34.32-10.47L49.98-10.47L49.98 0L33.70 0Q27.10 0 22.09-0.79L22.09-0.79Q14.17-2.11 9.50-7.74L9.50-7.74Q2.82-15.84 2.82-29.66L2.82-29.66Q2.82-44.97 12.23-53.50L12.23-53.50Q15.49-56.41 19.14-57.55Q22.79-58.70 28.95-58.70L28.95-58.70Z"
transform="translate(0 0) "
></path>
<path d="M28.51-22.26L18.48-22.26L18.48 0L5.98 0L5.98-58.70L34.67-58.70Q46.99-58.70 51.83-55.53L51.83-55.53Q55.18-53.42 56.98-49.94Q58.78-46.46 58.78-42.33L58.78-42.33Q58.78-33.97 54.56-29.39L54.56-29.39Q51.92-26.66 47.61-25.26L47.61-25.26Q51.04-24.02 52.80-22.66Q54.56-21.30 55.97-18.66L55.97-18.66Q57.02-16.54 57.51-14.61Q57.99-12.67 58.26-8.89L58.26-8.89Q58.78-2.55 59.66 0L59.66 0L45.67 0Q45.06-2.02 44.35-8.36L44.35-8.36Q43.91-13.46 42.55-16.19Q41.18-18.92 38.46-20.50L38.46-20.50Q35.02-22.35 28.51-22.26L28.51-22.26ZM18.48-48.22L18.48-32.74L35.99-32.74Q40.39-32.74 42.24-34.06L42.24-34.06Q45.06-35.99 45.06-40.83L45.06-40.83Q45.06-46.20 40.83-47.70L40.83-47.70Q39.34-48.22 35.99-48.22L35.99-48.22L18.48-48.22Z"
transform="translate(58.855999999999995 0) "
></path>
<path d="M19.01 0L19.01-48.22L0.35-48.22L0.35-58.70L50.95-58.70L50.95-48.22L31.50-48.22L31.50 0L19.01 0Z"
transform="translate(126.68799999999999 0) "
></path>
<path d="M5.98 0L5.98-58.70L30.89-58.70Q40.22-58.70 45.32-56.85L45.32-56.85Q54.74-53.42 57.90-44.26L57.90-44.26Q60.28-37.22 60.28-29.22L60.28-29.22Q60.28-21.30 57.99-14.26L57.99-14.26Q55.70-7.04 50.42-3.61L50.42-3.61Q47.08-1.50 43.08-0.75Q39.07 0 30.89 0L30.89 0L5.98 0ZM30.89-48.22L18.48-48.22L18.48-10.47L30.89-10.47Q39.07-10.47 42.24-14.08L42.24-14.08Q44.18-16.37 45.36-20.50Q46.55-24.64 46.55-29.30L46.55-29.30Q46.55-34.50 45.14-38.81Q43.74-43.12 41.45-45.23L41.45-45.23Q38.10-48.22 30.89-48.22L30.89-48.22Z"
transform="translate(183.07999999999998 0) "
></path>
</g>
<!-- <path d="M13.00-21.91L21.24-21.91L21.24-17.23L14.04-17.23Q10.39-17.23-->
<!-- 9-15.62L9-15.62Q7.65-14.08-->
<!-- 7.65-10.93L7.65-10.93Q7.65-7.42 9.86-5.80L9.86-5.80Q10.75-5.17-->
<!-- 11.81-4.93Q12.87-4.68-->
<!-- 14.76-4.68L14.76-4.68L21.24-4.68L21.24-->
<!-- 0L13.00 0Q9.67 0 7.74-0.67Q5.80-1.35-->
<!-- 4.32-3.01L4.32-3.01Q1.48-6.17-->
<!-- 1.48-11.03L1.48-11.03Q1.48-16.88-->
<!-- 4.86-19.75L4.86-19.75Q6.21-20.93-->
<!-- 8.10-21.42Q9.99-21.91-->
<!-- 13.00-21.91L13.00-21.91ZM31.05-13.32L43.74-13.32L43.74-8.64L31.05-8.64Q31.23-6.48-->
<!-- 32.44-5.58Q33.66-4.68 36.41-4.68L36.41-4.68L43.74-4.68L43.74 0L35.73 0Q33.12 0 31.48-0.47Q29.83-0.94 28.39-2.02L28.39-2.02Q24.39-5.13 24.39-11.25L24.39-11.25Q24.39-15.21 26.50-18.18L26.50-18.18Q27.94-20.20 29.97-21.06Q31.99-21.91 35.28-21.91L35.28-21.91L43.74-21.91L43.74-17.23L35.73-17.23Q33.25-17.23 32.27-16.40Q31.27-15.57 31.05-13.32L31.05-13.32ZM48.64 0L48.64-21.91L57.55-21.91Q60.30-21.91 61.81-21.53Q63.31-21.15 64.31-20.25L64.31-20.25Q65.30-19.35 65.70-18Q66.10-16.65 66.10-14.13L66.10-14.13L66.10-12.01L60.30-12.01L60.30-13.18Q60.30-15.52 59.49-16.38Q58.68-17.23 56.38-17.23L56.38-17.23L54.67-17.23L54.67 0L48.64 0ZM67.50-21.91L71.33-21.91L71.33-30.02L77.36-30.02L77.36-21.91L82.94-21.91L82.94-17.23L77.36-17.23L77.36-9.27Q77.36-6.48 77.85-5.76L77.85-5.76Q78.61-4.68 80.55-4.68L80.55-4.68L82.94-4.68L82.94 0L78.57 0Q74.66 0 72.99-1.89Q71.33-3.78 71.33-8.23L71.33-8.23L71.33-17.23L67.50-17.23L67.50-21.91ZM96.08-21.91L101.75-21.91L101.75-30.02L107.73-30.02L107.73 0L97.38 0Q94.23 0 92.61-0.49L92.61-0.49Q88.78-1.71 86.90-5.26L86.90-5.26Q85.59-7.65 85.59-11.12L85.59-11.12Q85.59-16.74 89.37-19.84L89.37-19.84Q91.84-21.91 96.08-21.91L96.08-21.91ZM97.38-4.68L101.75-4.68L101.75-17.23L97.38-17.23Q94.50-17.23 93.02-15.30L93.02-15.30Q91.71-13.68 91.71-11.12L91.71-11.12Q91.71-7.38 93.87-5.76L93.87-5.76Q95.36-4.68 97.38-4.68L97.38-4.68Z"-->
<!-- fill="#2c3e50"-->
<!-- transform="translate(300, 270) scale(4,4)"-->
<!-- ></path>-->
<text x="300" y="100" font-size="50" font-weight="bold">让你的证书永不过期</text>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -1,17 +0,0 @@
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="500" height="500" viewBox="0 0 500.000000 500.000000"
>
<path d="M28.34 56.68h28.34V36.12H28.34a7.79 7.79 0 1 1 0-15.58h19.84v9.05h8.5V12H28.34a16.29 16.29 0 0 0 0 32.58h19.84v3.56H28.34a19.84 19.84 0 0 1 0-39.68h28.34V0H28.34a28.34 28.34 0 0 0 0 56.68z"
fill="#2c3e50"
transform="translate(124, 60) scale(4,4)"
></path>
<path d="M13.00-21.91L21.24-21.91L21.24-17.23L14.04-17.23Q10.39-17.23 9-15.62L9-15.62Q7.65-14.08 7.65-10.93L7.65-10.93Q7.65-7.42 9.86-5.80L9.86-5.80Q10.75-5.17 11.81-4.93Q12.87-4.68 14.76-4.68L14.76-4.68L21.24-4.68L21.24 0L13.00 0Q9.67 0 7.74-0.67Q5.80-1.35 4.32-3.01L4.32-3.01Q1.48-6.17 1.48-11.03L1.48-11.03Q1.48-16.88 4.86-19.75L4.86-19.75Q6.21-20.93 8.10-21.42Q9.99-21.91 13.00-21.91L13.00-21.91ZM31.05-13.32L43.74-13.32L43.74-8.64L31.05-8.64Q31.23-6.48 32.44-5.58Q33.66-4.68 36.41-4.68L36.41-4.68L43.74-4.68L43.74 0L35.73 0Q33.12 0 31.48-0.47Q29.83-0.94 28.39-2.02L28.39-2.02Q24.39-5.13 24.39-11.25L24.39-11.25Q24.39-15.21 26.50-18.18L26.50-18.18Q27.94-20.20 29.97-21.06Q31.99-21.91 35.28-21.91L35.28-21.91L43.74-21.91L43.74-17.23L35.73-17.23Q33.25-17.23 32.27-16.40Q31.27-15.57 31.05-13.32L31.05-13.32ZM48.64 0L48.64-21.91L57.55-21.91Q60.30-21.91 61.81-21.53Q63.31-21.15 64.31-20.25L64.31-20.25Q65.30-19.35 65.70-18Q66.10-16.65 66.10-14.13L66.10-14.13L66.10-12.01L60.30-12.01L60.30-13.18Q60.30-15.52 59.49-16.38Q58.68-17.23 56.38-17.23L56.38-17.23L54.67-17.23L54.67 0L48.64 0ZM67.50-21.91L71.33-21.91L71.33-30.02L77.36-30.02L77.36-21.91L82.94-21.91L82.94-17.23L77.36-17.23L77.36-9.27Q77.36-6.48 77.85-5.76L77.85-5.76Q78.61-4.68 80.55-4.68L80.55-4.68L82.94-4.68L82.94 0L78.57 0Q74.66 0 72.99-1.89Q71.33-3.78 71.33-8.23L71.33-8.23L71.33-17.23L67.50-17.23L67.50-21.91ZM96.08-21.91L101.75-21.91L101.75-30.02L107.73-30.02L107.73 0L97.38 0Q94.23 0 92.61-0.49L92.61-0.49Q88.78-1.71 86.90-5.26L86.90-5.26Q85.59-7.65 85.59-11.12L85.59-11.12Q85.59-16.74 89.37-19.84L89.37-19.84Q91.84-21.91 96.08-21.91L96.08-21.91ZM97.38-4.68L101.75-4.68L101.75-17.23L97.38-17.23Q94.50-17.23 93.02-15.30L93.02-15.30Q91.71-13.68 91.71-11.12L91.71-11.12Q91.71-7.38 93.87-5.76L93.87-5.76Q95.36-4.68 97.38-4.68L97.38-4.68Z"
fill="#2c3e50"
transform="translate(28, 430) scale(4,4)"
></path>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -1,7 +1,106 @@
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="500" height="500" viewBox="0 0 500.000000 500.000000"
>
<path d="M28.34 56.68h28.34V36.12H28.34a7.79 7.79 0 1 1 0-15.58h19.84v9.05h8.5V12H28.34a16.29 16.29 0 0 0 0 32.58h19.84v3.56H28.34a19.84 19.84 0 0 1 0-39.68h28.34V0H28.34a28.34 28.34 0 0 0 0 56.68z"
transform="translate(70, 76) scale(6,6)"
></path>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns="http://www.w3.org/2000/svg"
width="210mm"
height="210mm"
viewBox="0 0 210 210"
version="1.1"
id="svg8"
>
<g id="layer1" style="display:inline">
<path
style="fill:#002255;stroke:none;stroke-width:0.625348"
d="M 35.587501,69.766667 V 59.766664 h 70.000109 69.99991 v 10.000003 9.999997 H 105.58761 35.587501 Z"
id="path12" />
<rect
style="fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-2"
width="32.244232"
height="20"
x="71.506088"
y="106.64581" />
<rect
style="fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-8-8"
width="32.244232"
height="20"
x="107.42467"
y="106.64581" />
<rect
style="fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-8-5-8"
width="32.244232"
height="20"
x="143.34325"
y="106.64581" />
<rect
style="fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-2-4"
width="32.244232"
height="20"
x="71.506088"
y="129.82079" />
<rect
style="fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-8-8-3"
width="32.244232"
height="20"
x="107.42467"
y="129.82079" />
<rect
style="fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-8-5-8-2"
width="32.244232"
height="20"
x="143.34325"
y="129.82079" />
<rect
style="fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-2-7"
width="32.244232"
height="20"
x="35.587502"
y="106.64581" />
<rect
style="fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-2-4-0"
width="32.244232"
height="20"
x="35.587502"
y="129.82079" />
<rect
style="display:inline;fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-2-9"
width="32.244232"
height="20"
x="71.506088"
y="82.941666" />
<rect
style="display:inline;fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-8-8-37"
width="32.244232"
height="20"
x="107.42467"
y="82.941666" />
<rect
style="display:inline;fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-8-5-8-4"
width="32.244232"
height="20"
x="143.34325"
y="82.941666" />
<rect
style="display:inline;fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-2-7-1"
width="32.244232"
height="20"
x="35.587502"
y="82.941666" />
</g>
<polygon
points="75.3,174.4 103.1,103.6 79.8,103.6 112.6,41.3 156.4,41.3 129.9,90.5 148.1,90.5 "
fill="#f6cc00"
id="polygon276"
transform="matrix(1.0930933,0,0,0.99853202,-17.517362,-0.52287941)" />
</svg>

Before

Width:  |  Height:  |  Size: 402 B

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@ -1,108 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns="http://www.w3.org/2000/svg"
width="210mm"
height="210mm"
viewBox="0 0 210 210"
version="1.1"
id="svg8">
<defs
id="defs2" />
<g
id="layer1"
style="display:inline">
<path
style="fill:#002255;stroke:none;stroke-width:0.625348"
d="M 35.587501,69.766667 V 59.766664 h 70.000109 69.99991 v 10.000003 9.999997 H 105.58761 35.587501 Z"
id="path12" />
<rect
style="fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-2"
width="32.244232"
height="20"
x="71.506088"
y="106.64581" />
<rect
style="fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-8-8"
width="32.244232"
height="20"
x="107.42467"
y="106.64581" />
<rect
style="fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-8-5-8"
width="32.244232"
height="20"
x="143.34325"
y="106.64581" />
<rect
style="fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-2-4"
width="32.244232"
height="20"
x="71.506088"
y="129.82079" />
<rect
style="fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-8-8-3"
width="32.244232"
height="20"
x="107.42467"
y="129.82079" />
<rect
style="fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-8-5-8-2"
width="32.244232"
height="20"
x="143.34325"
y="129.82079" />
<rect
style="fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-2-7"
width="32.244232"
height="20"
x="35.587502"
y="106.64581" />
<rect
style="fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-2-4-0"
width="32.244232"
height="20"
x="35.587502"
y="129.82079" />
<rect
style="display:inline;fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-2-9"
width="32.244232"
height="20"
x="71.506088"
y="82.941666" />
<rect
style="display:inline;fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-8-8-37"
width="32.244232"
height="20"
x="107.42467"
y="82.941666" />
<rect
style="display:inline;fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-8-5-8-4"
width="32.244232"
height="20"
x="143.34325"
y="82.941666" />
<rect
style="display:inline;fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-2-7-1"
width="32.244232"
height="20"
x="35.587502"
y="82.941666" />
</g>
<polygon
points="75.3,174.4 103.1,103.6 79.8,103.6 112.6,41.3 156.4,41.3 129.9,90.5 148.1,90.5 "
fill="#f6cc00"
id="polygon276"
transform="matrix(1.0930933,0,0,0.99853202,-17.517362,-0.52287941)" />
</svg>

Before

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -1,44 +0,0 @@
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="800" height="300" viewBox="0 0 800.000000 300.000000"
>
<g fill="#fff">
<path d="M28.34 56.68h28.34V36.12H28.34a7.79 7.79 0 1 1 0-15.58h19.84v9.05h8.5V12H28.34a16.29 16.29 0 0 0 0 32.58h19.84v3.56H28.34a19.84 19.84 0 0 1 0-39.68h28.34V0H28.34a28.34 28.34 0 0 0 0 56.68z"
transform="translate(40, 40) scale(4,4)"
></path>
<g transform="translate(280, 260) scale(2,2)">
<path d="M28.95-58.70L49.98-58.70L49.98-48.22L33.70-48.22Q27.37-48.22 24.46-47.34Q21.56-46.46 19.62-43.91L19.62-43.91Q18.30-42.15 17.82-40.39Q17.34-38.63 16.98-34.41L16.98-34.41L49.98-34.41L49.98-23.94L16.98-23.94Q17.69-16.37 21.47-13.42Q25.26-10.47 34.32-10.47L34.32-10.47L49.98-10.47L49.98 0L33.70 0Q27.10 0 22.09-0.79L22.09-0.79Q14.17-2.11 9.50-7.74L9.50-7.74Q2.82-15.84 2.82-29.66L2.82-29.66Q2.82-44.97 12.23-53.50L12.23-53.50Q15.49-56.41 19.14-57.55Q22.79-58.70 28.95-58.70L28.95-58.70Z"
transform="translate(0 0) "
></path>
<path d="M28.51-22.26L18.48-22.26L18.48 0L5.98 0L5.98-58.70L34.67-58.70Q46.99-58.70 51.83-55.53L51.83-55.53Q55.18-53.42 56.98-49.94Q58.78-46.46 58.78-42.33L58.78-42.33Q58.78-33.97 54.56-29.39L54.56-29.39Q51.92-26.66 47.61-25.26L47.61-25.26Q51.04-24.02 52.80-22.66Q54.56-21.30 55.97-18.66L55.97-18.66Q57.02-16.54 57.51-14.61Q57.99-12.67 58.26-8.89L58.26-8.89Q58.78-2.55 59.66 0L59.66 0L45.67 0Q45.06-2.02 44.35-8.36L44.35-8.36Q43.91-13.46 42.55-16.19Q41.18-18.92 38.46-20.50L38.46-20.50Q35.02-22.35 28.51-22.26L28.51-22.26ZM18.48-48.22L18.48-32.74L35.99-32.74Q40.39-32.74 42.24-34.06L42.24-34.06Q45.06-35.99 45.06-40.83L45.06-40.83Q45.06-46.20 40.83-47.70L40.83-47.70Q39.34-48.22 35.99-48.22L35.99-48.22L18.48-48.22Z"
transform="translate(58.855999999999995 0) "
></path>
<path d="M19.01 0L19.01-48.22L0.35-48.22L0.35-58.70L50.95-58.70L50.95-48.22L31.50-48.22L31.50 0L19.01 0Z"
transform="translate(126.68799999999999 0) "
></path>
<path d="M5.98 0L5.98-58.70L30.89-58.70Q40.22-58.70 45.32-56.85L45.32-56.85Q54.74-53.42 57.90-44.26L57.90-44.26Q60.28-37.22 60.28-29.22L60.28-29.22Q60.28-21.30 57.99-14.26L57.99-14.26Q55.70-7.04 50.42-3.61L50.42-3.61Q47.08-1.50 43.08-0.75Q39.07 0 30.89 0L30.89 0L5.98 0ZM30.89-48.22L18.48-48.22L18.48-10.47L30.89-10.47Q39.07-10.47 42.24-14.08L42.24-14.08Q44.18-16.37 45.36-20.50Q46.55-24.64 46.55-29.30L46.55-29.30Q46.55-34.50 45.14-38.81Q43.74-43.12 41.45-45.23L41.45-45.23Q38.10-48.22 30.89-48.22L30.89-48.22Z"
transform="translate(183.07999999999998 0) "
></path>
</g>
<!-- <path d="M13.00-21.91L21.24-21.91L21.24-17.23L14.04-17.23Q10.39-17.23-->
<!-- 9-15.62L9-15.62Q7.65-14.08-->
<!-- 7.65-10.93L7.65-10.93Q7.65-7.42 9.86-5.80L9.86-5.80Q10.75-5.17-->
<!-- 11.81-4.93Q12.87-4.68-->
<!-- 14.76-4.68L14.76-4.68L21.24-4.68L21.24-->
<!-- 0L13.00 0Q9.67 0 7.74-0.67Q5.80-1.35-->
<!-- 4.32-3.01L4.32-3.01Q1.48-6.17-->
<!-- 1.48-11.03L1.48-11.03Q1.48-16.88-->
<!-- 4.86-19.75L4.86-19.75Q6.21-20.93-->
<!-- 8.10-21.42Q9.99-21.91-->
<!-- 13.00-21.91L13.00-21.91ZM31.05-13.32L43.74-13.32L43.74-8.64L31.05-8.64Q31.23-6.48-->
<!-- 32.44-5.58Q33.66-4.68 36.41-4.68L36.41-4.68L43.74-4.68L43.74 0L35.73 0Q33.12 0 31.48-0.47Q29.83-0.94 28.39-2.02L28.39-2.02Q24.39-5.13 24.39-11.25L24.39-11.25Q24.39-15.21 26.50-18.18L26.50-18.18Q27.94-20.20 29.97-21.06Q31.99-21.91 35.28-21.91L35.28-21.91L43.74-21.91L43.74-17.23L35.73-17.23Q33.25-17.23 32.27-16.40Q31.27-15.57 31.05-13.32L31.05-13.32ZM48.64 0L48.64-21.91L57.55-21.91Q60.30-21.91 61.81-21.53Q63.31-21.15 64.31-20.25L64.31-20.25Q65.30-19.35 65.70-18Q66.10-16.65 66.10-14.13L66.10-14.13L66.10-12.01L60.30-12.01L60.30-13.18Q60.30-15.52 59.49-16.38Q58.68-17.23 56.38-17.23L56.38-17.23L54.67-17.23L54.67 0L48.64 0ZM67.50-21.91L71.33-21.91L71.33-30.02L77.36-30.02L77.36-21.91L82.94-21.91L82.94-17.23L77.36-17.23L77.36-9.27Q77.36-6.48 77.85-5.76L77.85-5.76Q78.61-4.68 80.55-4.68L80.55-4.68L82.94-4.68L82.94 0L78.57 0Q74.66 0 72.99-1.89Q71.33-3.78 71.33-8.23L71.33-8.23L71.33-17.23L67.50-17.23L67.50-21.91ZM96.08-21.91L101.75-21.91L101.75-30.02L107.73-30.02L107.73 0L97.38 0Q94.23 0 92.61-0.49L92.61-0.49Q88.78-1.71 86.90-5.26L86.90-5.26Q85.59-7.65 85.59-11.12L85.59-11.12Q85.59-16.74 89.37-19.84L89.37-19.84Q91.84-21.91 96.08-21.91L96.08-21.91ZM97.38-4.68L101.75-4.68L101.75-17.23L97.38-17.23Q94.50-17.23 93.02-15.30L93.02-15.30Q91.71-13.68 91.71-11.12L91.71-11.12Q91.71-7.38 93.87-5.76L93.87-5.76Q95.36-4.68 97.38-4.68L97.38-4.68Z"-->
<!-- fill="#2c3e50"-->
<!-- transform="translate(300, 270) scale(4,4)"-->
<!-- ></path>-->
<text x="300" y="100" font-size="50" font-weight="bold">让你的证书永不过期</text>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -1,106 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns="http://www.w3.org/2000/svg"
width="210mm"
height="210mm"
viewBox="0 0 210 210"
version="1.1"
id="svg8"
>
<g id="layer1" style="display:inline">
<path
style="fill:#002255;stroke:none;stroke-width:0.625348"
d="M 35.587501,69.766667 V 59.766664 h 70.000109 69.99991 v 10.000003 9.999997 H 105.58761 35.587501 Z"
id="path12" />
<rect
style="fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-2"
width="32.244232"
height="20"
x="71.506088"
y="106.64581" />
<rect
style="fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-8-8"
width="32.244232"
height="20"
x="107.42467"
y="106.64581" />
<rect
style="fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-8-5-8"
width="32.244232"
height="20"
x="143.34325"
y="106.64581" />
<rect
style="fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-2-4"
width="32.244232"
height="20"
x="71.506088"
y="129.82079" />
<rect
style="fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-8-8-3"
width="32.244232"
height="20"
x="107.42467"
y="129.82079" />
<rect
style="fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-8-5-8-2"
width="32.244232"
height="20"
x="143.34325"
y="129.82079" />
<rect
style="fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-2-7"
width="32.244232"
height="20"
x="35.587502"
y="106.64581" />
<rect
style="fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-2-4-0"
width="32.244232"
height="20"
x="35.587502"
y="129.82079" />
<rect
style="display:inline;fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-2-9"
width="32.244232"
height="20"
x="71.506088"
y="82.941666" />
<rect
style="display:inline;fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-8-8-37"
width="32.244232"
height="20"
x="107.42467"
y="82.941666" />
<rect
style="display:inline;fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-8-5-8-4"
width="32.244232"
height="20"
x="143.34325"
y="82.941666" />
<rect
style="display:inline;fill:#2a7fff;fill-rule:evenodd;stroke-width:0.214311"
id="rect22-2-7-1"
width="32.244232"
height="20"
x="35.587502"
y="82.941666" />
</g>
<polygon
points="75.3,174.4 103.1,103.6 79.8,103.6 112.6,41.3 156.4,41.3 129.9,90.5 148.1,90.5 "
fill="#f6cc00"
id="polygon276"
transform="matrix(1.0930933,0,0,0.99853202,-17.517362,-0.52287941)" />
</svg>

Before

Width:  |  Height:  |  Size: 3.7 KiB

View File

@ -1,29 +1,32 @@
<template>
<a-config-provider :locale="locale">
<router-view v-if="routerEnabled" />
<a-config-provider :locale="locale" :theme="settingStore.themeToken">
<fs-form-provider>
<router-view v-if="routerEnabled" />
</fs-form-provider>
</a-config-provider>
</template>
<script lang="ts">
import zhCN from "ant-design-vue/es/locale/zh_CN";
import enUS from "ant-design-vue/es/locale/en_US";
import { provide, ref, nextTick, getCurrentInstance } from "vue";
import { nextTick, provide, ref } from "vue";
import { usePageStore } from "/src/store/modules/page";
import { useResourceStore } from "/src/store/modules/resource";
import { useSettingStore } from "/@/store/modules/settings";
import "dayjs/locale/zh-cn";
import "dayjs/locale/en";
import dayjs from "dayjs";
export default {
name: "App",
setup(props: any, ctx: any) {
setup() {
//
const routerEnabled = ref(true);
const locale = ref(zhCN);
async function reload() {
routerEnabled.value = false;
await nextTick();
routerEnabled.value = true;
// routerEnabled.value = false;
// await nextTick();
// routerEnabled.value = true;
}
function localeChanged(value: any) {
console.log("locale changed:", value);
@ -49,7 +52,8 @@ export default {
return {
routerEnabled,
locale
locale,
settingStore
};
}
};

View File

@ -1,3 +1,8 @@
export default {
app: { crud: { i18n: { name: "name", city: "city", status: "status" } } }
app: { crud: { i18n: { name: "name", city: "city", status: "status" } } },
fs: {
rowHandle: {
title: "Operation"
}
}
};

View File

@ -5,5 +5,10 @@ export default {
logoutTip: "确认",
logoutMessage: "确定要注销登录吗?"
}
},
fs: {
rowHandle: {
title: "操作列"
}
}
};

View File

@ -22,7 +22,7 @@ export default defineComponent({
},
{ immediate: true }
);
const middle = "/fast-crud/fs-admin-antdv/blob/main/src/views";
const middle = "/fast-crud/fs-admin-antdv4/blob/main/src/views";
function goSource(prefix: any) {
const path = router.currentRoute.value.fullPath;
window.open(prefix + middle + path + "/index.vue");

View File

@ -54,6 +54,7 @@ export default defineComponent({
name: "FsThemeColorPicker",
props: {
primaryColor: {
type: String,
default: "#1890ff"
}
},

View File

@ -1,8 +1,8 @@
<template>
<div class="fs-theme" @click="show()">
<fs-iconify icon="ion:sparkles-outline" />
<a-drawer v-model:visible="visible" title="主题设置" placement="right" width="350px" :closable="false" @after-visible-change="afterVisibleChange">
<fs-theme-color-picker :primary-color="setting.getTheme.primaryColor" @change="setting.setPrimaryColor"></fs-theme-color-picker>
<a-drawer v-model:open="visible" title="主题设置" placement="right" width="350px" :closable="false" @after-open-change="afterVisibleChange">
<fs-theme-color-picker :primary-color="setting.themeConfig?.colorPrimary" @change="setting.setPrimaryColor"></fs-theme-color-picker>
</a-drawer>
</div>
</template>

View File

@ -0,0 +1,44 @@
<template>
<div class="fs-theme-mode">
<a-switch :checked="setting.themeConfig.mode === 'dark'" @update:checked="onChange">
<template #checkedChildren>
<fs-iconify icon="ion:moon" />
</template>
<template #unCheckedChildren>
<fs-iconify icon="ion:sunny" />
</template>
</a-switch>
</div>
</template>
<script lang="ts">
import { ref, defineComponent } from "vue";
import { useSettingStore } from "/@/store/modules/settings";
export default defineComponent({
name: "FsThemeModeSet",
components: {},
setup() {
const setting = useSettingStore();
const onChange = (checked: boolean) => {
if (checked) {
setting.setDarkMode("dark");
} else {
setting.setDarkMode("light");
}
};
return {
setting,
onChange
};
}
});
</script>
<style lang="less">
.fs-theme-mode {
display: inline-flex;
justify-content: center;
align-items: center;
}
</style>

View File

@ -2,8 +2,8 @@
<a-layout class="fs-framework">
<a-layout-sider v-model:collapsed="asideCollapsed" :trigger="null" collapsible>
<div class="header-logo">
<img src="/images/logo/rect-black.svg" />
<span v-if="!asideCollapsed" class="title">FsAdmin</span>
<img :src="envRef.LOGO_PATH" />
<span v-if="!asideCollapsed" class="title">{{ envRef.TITLE }}</span>
</div>
<div class="aside-menu">
<fs-menu :scroll="true" :menus="asideMenus" :expand-selected="!asideCollapsed" />
@ -31,9 +31,18 @@
<!-- Button-->
<!-- </button>-->
<fs-menu class="header-menu" mode="horizontal" :expand-selected="false" :selectable="false" :menus="headerMenus" />
<fs-locale class="btn" />
<!-- <fs-theme-set class="btn" />-->
<fs-user-info class="btn" />
<div class="header-btn">
<fs-locale />
</div>
<!-- <div class="header-btn">-->
<!-- <fs-theme-mode-set />-->
<!-- </div>-->
<div class="header-btn">
<fs-theme-set />
</div>
<div class="header-btn">
<fs-user-info />
</div>
</div>
</a-layout-header>
<fs-tabs></fs-tabs>
@ -69,11 +78,12 @@ import { useResourceStore } from "../store/modules/resource";
import { usePageStore } from "/@/store/modules/page";
import { MenuFoldOutlined, MenuUnfoldOutlined } from "@ant-design/icons-vue";
import FsThemeSet from "/@/layout/components/theme/index.vue";
import { notification } from "ant-design-vue";
import { env } from "../utils/util.env";
import FsThemeModeSet from "./components/theme/mode-set.vue";
export default {
name: "LayoutFramework",
// eslint-disable-next-line vue/no-unused-components
components: { FsThemeSet, MenuFoldOutlined, MenuUnfoldOutlined, FsMenu, FsLocale, FsSourceLink, FsUserInfo, FsTabs },
components: { FsThemeSet, MenuFoldOutlined, MenuUnfoldOutlined, FsMenu, FsLocale, FsSourceLink, FsUserInfo, FsTabs, FsThemeModeSet },
setup() {
const resourceStore = useResourceStore();
const frameworkMenus = computed(() => {
@ -95,11 +105,13 @@ export default {
}
onErrorCaptured((e) => {
console.error("ErrorCaptured:", e);
notification.error({ message: e.message });
// notification.error({ message: e.message });
//
return false;
});
const version = ref(import.meta.env.VITE_APP_VERSION);
const envRef = ref(env);
return {
version,
frameworkMenus,
@ -107,7 +119,8 @@ export default {
asideMenus,
keepAlive,
asideCollapsed,
asideCollapsedToggle
asideCollapsedToggle,
envRef
};
}
};
@ -165,11 +178,16 @@ export default {
cursor: pointer;
padding: 0 10px;
}
height: 100%;
& > .btn {
& > .header-btn {
display: inline-flex;
justify-content: center;
align-items: center;
height: 100%;
//border-bottom: 1px solid rgba(255, 255, 255, 0);
&:hover {
background-color: #fff;
color: @primary-color;
}
}
}

View File

@ -5,10 +5,10 @@
<div class="user-layout-content">
<div class="top flex flex-col items-center justify-center">
<div class="header flex flex-row items-center">
<img src="/images/logo/rect-black.svg" class="logo" alt="logo" />
<span class="title">FsAdmin</span>
<img :src="envRef.LOGO_PATH" class="logo" alt="logo" />
<span class="title">{{ envRef.TITLE }}</span>
</div>
<div class="desc">fast-crud开发crud快如闪电</div>
<div class="desc">{{ envRef.SLOGAN }}</div>
</div>
<router-view />
@ -19,15 +19,24 @@
<a href="_self">隐私</a>
<a href="_self">条款</a>
</div>
<div class="copyright">Copyright &copy; 2021 Greper</div>
<div class="copyright">{{ envRef.COPYRIGHT }}</div>
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import { env } from "/@/utils/util.env";
import { ref } from "vue";
export default {
name: "LayoutOutside"
name: "LayoutOutside",
setup() {
const envRef = ref(env);
return {
envRef
};
}
};
</script>

View File

@ -1,3 +1,10 @@
<template>
<router-view />
<router-view> </router-view>
</template>
<!--<script lang="ts" setup>-->
<!--import { usePageStore } from "/@/store/modules/page";-->
<!--const pageStore = usePageStore();-->
<!--const keepAlive = pageStore.keepAlive;-->
<!--</script>-->

View File

@ -2,14 +2,12 @@ import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import Antd from "ant-design-vue";
import "ant-design-vue/dist/antd.less";
import "./style/common.less";
import i18n from "./i18n";
import store from "./store";
import components from "./components";
import plugin from "./plugin/";
// 正式项目请删除mock避免影响性能
import "./mock";

View File

@ -27,9 +27,11 @@ let manyStatus = [
{ value: "2", label: "停止", color: "cyan" },
{ value: "0", label: "关闭", color: "red", icon: "ion:radio-button-off" }
];
for (let i = 0; i < 2; i++) {
manyStatus = manyStatus.concat(_.cloneDeep(manyStatus));
let tempManyStatus: any[] = [];
for (let i = 0; i < 100; i++) {
tempManyStatus = tempManyStatus.concat(_.cloneDeep(manyStatus));
}
manyStatus = tempManyStatus;
let idIndex = 0;
for (const item of manyStatus) {
idIndex++;

View File

@ -1,6 +1,7 @@
import { mock } from "../api/service";
import * as tools from "../api/tools";
import _ from "lodash-es";
import { utils } from "@fast-crud/fast-crud";
// @ts-ignore
const commonMocks: any = import.meta.glob("./common/mock.*.[j|t]s", { eager: true });
// @ts-ignore
@ -22,8 +23,8 @@ _.forEach(viewMocks, (value) => {
list.forEach((apiFile: any) => {
for (const item of apiFile) {
mock.onAny(new RegExp(item.path)).reply(async (config: any) => {
console.log("------------fake request start -------------");
console.log("request:", config);
utils.logger.debug("------------fake request start -------------");
utils.logger.debug("request:", config);
const data = config.data ? JSON.parse(config.data) : {};
const query = config.url.indexOf("?") >= 0 ? config.url.substring(config.url.indexOf("?") + 1) : undefined;
const params = config.params || {};
@ -40,8 +41,8 @@ list.forEach((apiFile: any) => {
params: params
};
const ret = await item.handle(req);
console.log("response:", ret);
console.log("------------fake request end-------------");
utils.logger.debug("response:", ret);
utils.logger.debug("------------fake request end-------------");
if (ret.code === 0) {
return tools.responseSuccess(ret.data, ret.msg);
} else {

View File

@ -1,9 +1,11 @@
import { request, requestForMock } from "/src/api/service";
import { ColumnCompositionProps, CrudOptions, FastCrud, PageQuery, PageRes, setLogger, TransformResProps, useColumns, UseCrudProps, UserPageQuery, useTypes, useUi } from "@fast-crud/fast-crud";
// import "/src/mock";
import { ColumnCompositionProps, CrudOptions, FastCrud, PageQuery, PageRes, setLogger, TransformResProps, useColumns, UseCrudProps, UserPageQuery, useTypes, utils } from "@fast-crud/fast-crud";
import "@fast-crud/fast-crud/dist/style.css";
import { FsExtendsCopyable, FsExtendsEditor, FsExtendsJson, FsExtendsTime, FsExtendsUploader, FsUploaderAliossSTS, FsUploaderGetAuthContext, FsUploaderS3SignedUrlType } from "@fast-crud/fast-extends";
import { FsExtendsCopyable, FsExtendsEditor, FsExtendsJson, FsExtendsTime, FsExtendsUploader, FsExtendsInput, FsUploaderS3SignedUrlType, FsUploaderGetAuthContext, FsUploaderAliossSTS } from "@fast-crud/fast-extends";
import "@fast-crud/fast-extends/dist/style.css";
import UiAntdv from "@fast-crud/ui-antdv";
import UiAntdv from "@fast-crud/ui-antdv4";
import "@fast-crud/ui-antdv4/dist/style.css";
import _ from "lodash-es";
import { useCrudPermission } from "../permission";
import { GetSignedUrl } from "/@/views/crud/component/uploader/s3/api";
@ -27,9 +29,13 @@ function install(app: any, options: any = {}) {
* @param propsuseCrud
*/
commonOptions(props: UseCrudProps): CrudOptions {
utils.logger.debug("commonOptions:", props);
const crudBinding = props.crudExpose?.crudBinding;
const opts: CrudOptions = {
table: {
scroll: {
x: 960
},
size: "small",
pagination: false,
onResizeColumn: (w: number, col: any) => {
@ -40,7 +46,7 @@ function install(app: any, options: any = {}) {
conditionalRender: {
match(scope) {
//不能用 !scope.value 否则switch组件设置为关之后就消失了
const { value, key } = scope;
const { value, key, props } = scope;
return !value && key != "_index" && value != false;
},
render() {
@ -56,6 +62,7 @@ function install(app: any, options: any = {}) {
rowHandle: {
buttons: {
view: { type: "link", text: null, icon: "ion:eye-outline" },
copy: { show: true, type: "link", text: null, icon: "ion:copy-outline" },
edit: { type: "link", text: null, icon: "ion:create-outline" },
remove: { type: "link", style: { color: "red" }, text: null, icon: "ion:trash-outline" }
},
@ -88,7 +95,7 @@ function install(app: any, options: any = {}) {
if (res.offset % pageSize === 0) {
currentPage++;
}
return { currentPage, pageSize, records: res.records, total: res.total };
return { currentPage, pageSize, records: res.records, total: res.total, ...res };
}
},
form: {
@ -109,6 +116,23 @@ function install(app: any, options: any = {}) {
},
wrapperCol: {
span: null
},
wrapper: {
saveRemind: true
// inner: true,
// innerContainerSelector: "main.fs-framework-content"
}
},
columns: {
createdAt: {
title: "创建时间",
type: "datetime",
form: {
show: false
},
column: {
order: 1000
}
}
}
};
@ -131,7 +155,7 @@ function install(app: any, options: any = {}) {
region: "ap-guangzhou",
secretId: "", //
secretKey: "", // 传了secretKey 和secretId 代表使用本地签名模式(不安全,生产环境不推荐)
async getAuthorization(context: FsUploaderGetAuthContext): Promise<FsUploaderAliossSTS> {
async getAuthorization(custom: any) {
// 不传secretKey代表使用临时签名模式,此时此参数必传(安全,生产环境推荐)
const ret = request({
url: "http://www.docmirror.cn:7070/api/upload/cos/getAuthorization",
@ -143,7 +167,6 @@ function install(app: any, options: any = {}) {
// TmpSecretKey,
// XCosSecurityToken,
// ExpiredTime, // SDK 在 ExpiredTime 时间前,不会再次调用 getAuthorization
// key //【可选】后台生成的文件key如果不传则用前端自己生成的key
// }
return ret;
},
@ -154,19 +177,27 @@ function install(app: any, options: any = {}) {
}
},
alioss: {
keepName: true,
domain: "https://d2p-demo.oss-cn-shenzhen.aliyuncs.com",
bucket: "d2p-demo",
region: "oss-cn-shenzhen",
accessKeyId: "",
accessKeySecret: "",
keepName: true,
async getAuthorization(custom: any, context: any) {
async getAuthorization(context: FsUploaderGetAuthContext): Promise<FsUploaderAliossSTS> {
// 不传accessKeySecret代表使用临时签名模式,此时此参数必传(安全,生产环境推荐)
const ret = await request({
url: "http://www.docmirror.cn:7070/api/upload/alioss/getAuthorization",
method: "get"
});
console.log("ret", ret);
// 返回结构要求如下
// ret.data:{
// TmpSecretId,
// TmpSecretKey,
// XCosSecurityToken,
// ExpiredTime, // SDK 在 ExpiredTime 时间前,不会再次调用 getAuthorization
// key //【可选】后台生成的文件key如果不传则用前端自己生成的key
// }
return ret;
},
sdkOpts: {
@ -214,7 +245,7 @@ function install(app: any, options: any = {}) {
}
},
//预签名配置,向后端获取上传的预签名连接
async getSignedUrl(bucket: string, key: string, options: any, type: FsUploaderS3SignedUrlType) {
async getSignedUrl(bucket: string, key: string, options: any, type: FsUploaderS3SignedUrlType = "put") {
return await GetSignedUrl(bucket, key, type);
},
successHandle(ret: any) {
@ -268,11 +299,12 @@ function install(app: any, options: any = {}) {
app.use(FsExtendsJson);
app.use(FsExtendsTime);
app.use(FsExtendsCopyable);
app.use(FsExtendsInput);
const { addTypes, getType } = useTypes();
//此处演示修改官方字段类型
const textType = getType("text");
textType.search.autoSearchTrigger = "change"; //修改官方的字段类型,设置为文本变化就触发查询
textType.search.autoSearchTrigger = "change"; //修改官方的字段类型,变化就触发 "enter"=回车键触发
// 此处演示自定义字段类型
addTypes({

View File

@ -1,2 +1,2 @@
// import "@iconify/iconify";
import "@purge-icons/generated";
// import "@purge-icons/generated";

View File

@ -57,6 +57,9 @@ router.afterEach((to: any) => {
NProgress.done();
// 多页控制 打开新的页面
const pageStore = usePageStore();
// for (const item of to.matched) {
// pageStore.keepAlivePush(item.name);
// }
pageStore.open(to);
// 更改标题
site.title(to.meta.title);

View File

@ -152,3 +152,4 @@ const routes = [...outsideRoutes, ...frameworkRoutes];
const frameworkMenus = frameworkRet.menus;
const headerMenus = headerRet.menus;
export { routes, outsideRoutes, frameworkRoutes, frameworkMenus, headerMenus, findMenus, filterMenus };

View File

@ -54,14 +54,14 @@ export const headerResource = [
children: [
{
title: "github",
path: "http://github.com/fast-crud/fs-admin-antdv",
path: "http://github.com/fast-crud/fs-admin-antdv4",
meta: {
icon: "ion:logo-github"
}
},
{
title: "gitee",
path: "http://gitee.com/fast-crud/fs-admin-antdv",
path: "http://gitee.com/fast-crud/fs-admin-antdv4",
meta: {
icon: "ion:logo-octocat"
}

View File

@ -96,7 +96,22 @@ export const crudResources = [
title: "ResetCrudOptions",
name: "BasisReset",
path: "/crud/basis/reset",
component: "/crud/basis/reset/index.vue"
component: "/crud/basis/reset/index.vue",
meta: {
cache: true
}
},
{
title: "CrudOptions插件",
name: "BasisPlugin",
path: "/crud/basis/plugin",
component: "/crud/basis/plugin/index.vue"
},
{
title: "Ts定义测试",
name: "BasisTsTest",
path: "/crud/basis/ts",
component: "/crud/basis/ts/index.vue"
}
]
},
@ -193,7 +208,7 @@ export const crudResources = [
component: "/crud/component/select/index.vue"
},
{
title: "表格选择(table-select)",
title: " 表格选择(table-select)",
name: "ComponentTableSelect",
path: "/crud/component/table-select",
component: "/crud/component/table-select/index.vue"
@ -300,6 +315,12 @@ export const crudResources = [
path: "/crud/component/json",
component: "/crud/component/json/index.vue"
},
{
title: "手机号输入框",
name: "ComponentPhone",
path: "/crud/component/phone",
component: "/crud/component/phone/index.vue"
},
{
title: "组件独立使用",
name: "ComponentIndependent",
@ -449,6 +470,12 @@ export const crudResources = [
path: "/crud/form/view",
component: "/crud/form/view/index.vue"
},
{
title: "initialForm",
name: "FormInitial",
path: "/crud/form/initial",
component: "/crud/form/initial/index.vue"
},
{
title: "表单Watch",
name: "FormWatch",

View File

@ -1,63 +1,81 @@
import { defineStore } from "pinia";
import { theme } from "ant-design-vue";
import _ from "lodash-es";
// @ts-ignore
import { LocalStorage } from "/src/utils/util.storage";
// import { replaceStyleVariables } from "vite-plugin-theme/es/client";
// import { getThemeColors, generateColors } from "/src/../build/theme-colors";
//
// import { mixLighten, mixDarken, tinycolor } from "vite-plugin-theme/es/colorUtils";
// export async function changeTheme(color?: string) {
// if (color == null) {
// return;
// }
// const colors = generateColors({
// mixDarken,
// mixLighten,
// tinycolor,
// color
// });
//
// return await replaceStyleVariables({
// colorVariables: [...getThemeColors(color), ...colors]
// });
// }
interface SettingState {
theme: any;
export type ThemeToken = {
token: {
colorPrimary?: string;
};
algorithm: any;
};
export type ThemeConfig = {
colorPrimary: string;
mode: string;
};
export interface SettingState {
themeConfig?: ThemeConfig;
themeToken: ThemeToken;
}
const defaultThemeConfig = {
colorPrimary: "#1890ff",
mode: "light"
};
const SETTING_THEME_KEY = "SETTING_THEME";
export const useSettingStore = defineStore({
id: "app.setting",
state: (): SettingState => ({
// user info
theme: null
themeConfig: null,
themeToken: {
token: {},
algorithm: theme.defaultAlgorithm
}
}),
getters: {
getTheme(): any {
return this.theme || LocalStorage.get(SETTING_THEME_KEY) || {};
getThemeConfig(): any {
return this.themeConfig || _.merge({}, defaultThemeConfig, LocalStorage.get(SETTING_THEME_KEY) || {});
}
},
actions: {
persistTheme() {
LocalStorage.set(SETTING_THEME_KEY, this.getTheme);
persistThemeConfig() {
LocalStorage.set(SETTING_THEME_KEY, this.getThemeConfig);
},
async setTheme(theme?: Object) {
if (theme == null) {
theme = this.getTheme;
async setThemeConfig(themeConfig?: ThemeConfig) {
this.themeConfig = _.merge({}, this.themeConfig, themeConfig);
this.persistThemeConfig();
this.setPrimaryColor(this.themeConfig.colorPrimary);
this.setDarkMode(this.themeConfig.mode);
},
setPrimaryColor(color: any) {
this.themeConfig.colorPrimary = color;
_.set(this.themeToken, "token.colorPrimary", color);
this.persistThemeConfig();
},
setDarkMode(mode: string) {
this.themeConfig.mode = mode;
if (mode === "dark") {
this.themeToken.algorithm = theme.darkAlgorithm;
// const defaultSeed = theme.defaultSeed;
// const mapToken = theme.darkAlgorithm(defaultSeed);
// less.modifyVars(mapToken);
// less.modifyVars({
// "@colorPrimaryBg": "#111a2c",
// colorPrimaryBg: "#111a2c"
// });
// less.refreshStyles();
} else {
this.themeToken.algorithm = theme.defaultAlgorithm;
// const defaultSeed = theme.defaultSeed;
// const mapToken = theme.defaultAlgorithm(defaultSeed);
// less.modifyVars(mapToken);
}
this.theme = theme;
this.persistTheme();
// await changeTheme(this.theme.primaryColor);
},
async setPrimaryColor(color: any) {
const theme = this.theme;
theme.primaryColor = color;
await this.setTheme();
this.persistThemeConfig();
},
async init() {
await this.setTheme(this.getTheme);
await this.setThemeConfig(this.getThemeConfig);
}
}
});

View File

@ -99,8 +99,3 @@ export const useUserStore = defineStore({
}
}
});
// Need to be used outside the setup
export function useUserStoreWidthOut() {
return useUserStore(store);
}

View File

@ -0,0 +1,28 @@
.ant-layout .ant-layout-sider{
background-color: #ebf1f6;
}
.ant-layout .ant-layout-header{
background-color: #ebf1f6;
}
.fs-multiple-page-control-group .fs-multiple-page-control-content{
overflow-y: hidden;
}
.fs-multiple-page-control-group .fs-multiple-page-control-btn .ant-btn{
border-bottom-left-radius:0;
border-bottom-right-radius:0;
}
.ant-menu-horizontal{
border-bottom: 0;
}
.fs-framework .header-menu{
overflow-y: hidden;
}
.ant-btn.ant-btn-icon-only{
padding-inline:revert;
}

View File

@ -3,7 +3,7 @@
@import './scroll.less';
@import './transition.less';
@import './fix-windicss.less';
@import './antdv4.less';
html, body {
margin: 0;
padding: 0;
@ -12,6 +12,9 @@ html, body {
box-sizing: border-box;
}
body{
min-width: 1000px;
}
div#app {
height: 100%
}
@ -60,3 +63,7 @@ h1, h2, h3, h4, h5, h6 {
.m-10{
margin:10px;
}
.p-5{
padding:5px;
}

View File

@ -1,21 +1,21 @@
.ant-layout{
background-color: @bg-color;
background-color: @colorPrimaryBg;
}
.ant-layout-header {
background-color: @bg-color
background-color: @colorPrimaryBg
}
.ant-layout-sider {
background-color:@bg-color
background-color:@colorPrimaryBg
}
.ant-menu{
background-color: @bg-color;
background-color: @colorPrimaryBg;
&.ant-menu-submenu-popup{
background-color: transparent;
}
}
.aside-menu{
.ant-menu-submenu > .ant-menu{
background-color:@bg-color
background-color:@colorPrimaryBg
}
.ant-menu-item-active{

View File

@ -1,4 +1,3 @@
@primary-color: #1890ff;
// theme
@bg-color: #ebf1f6;
@bg-menu-item-color:hsla(0,0%,100%,.5);
@colorPrimaryBg:#ebf1f6;
@primary-color: #1890ff;

View File

@ -9,6 +9,9 @@ export class EnvConfig {
MODE: string;
STORAGE: string;
TITLE: string;
SLOGAN: string;
COPYRIGHT: string;
LOGO_PATH: string;
PM_ENABLED: string;
constructor() {
this.init();

View File

@ -1,5 +1,15 @@
import * as api from "./api";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes, dict } from "@fast-crud/fast-crud";
import {
AddReq,
CreateCrudOptionsProps,
CreateCrudOptionsRet,
DelReq,
EditReq,
UserPageQuery,
UserPageRes,
dict,
utils
} from "@fast-crud/fast-crud";
import { SearchOutlined } from "@ant-design/icons-vue";
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
@ -78,7 +88,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
title: "复杂输入",
component: {
render(context: any) {
console.log("context scope", context);
utils.logger.info("context scope", context);
return (
<a-input-group compact>
<a-input placeholder={"render1 input"} style="width: 50%" v-model={[context.form.render, "value"]} />

View File

@ -44,7 +44,14 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
title: "省",
type: "dict-select",
search: {
show: true
show: true,
valueChange({ form, value, getComponentRef }: any) {
form.city = undefined; // 将“city”的值置空
form.county = undefined; // 将“county”的值置空
if (value) {
getComponentRef("city").reloadDict(); // 执行city的select组件的reloadDict()方法触发“city”重新加载字典
}
}
},
dict: dict({
url: "/mock/linkage/province",
@ -53,8 +60,8 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
}),
form: {
valueChange({ form, value, getComponentRef }) {
form.city = undefined; // 将“city”的值置空
form.county = undefined; // 将“county”的值置空
form.city = ""; // 将“city”的值置空
form.county = ""; // 将“county”的值置空
if (value) {
getComponentRef("city").reloadDict(); // 执行city的select组件的reloadDict()方法触发“city”重新加载字典
}
@ -84,7 +91,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
// 注释同上
valueChange({ value, form, getComponentRef }: ScopeContext) {
if (value) {
form.county = undefined; // 将county的value置空
form.county = ""; // 将county的value置空
const countySelect = getComponentRef("county");
if (form && form.province && form.city) {
countySelect.reloadDict(); // 重新加载字典项

View File

@ -96,6 +96,13 @@ mock.push({
const a = tree.filter((item) => {
return item.id === province;
});
if (a == null || a.length === 0) {
return {
code: 0,
msg: "success",
data: []
};
}
const list = omitChildren(a[0].children);
return {
code: 0,
@ -113,10 +120,24 @@ mock.push({
const a = tree.filter((item) => {
return item.id === province;
});
if (a == null || a.length === 0) {
return {
code: 0,
msg: "success",
data: []
};
}
const city = parseInt(req.params.city);
const b = a[0].children.filter((item) => {
return item.id === city;
});
if (b == null || b.length === 0) {
return {
code: 0,
msg: "success",
data: []
};
}
const list = omitChildren(b[0].children);
return {

View File

@ -51,11 +51,11 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
};
const addRequest = async ({ form }: AddReq) => {
const id = await api.AddObj(form);
const { id } = await api.AddObj(form);
//本地添加
form.id = id;
localDataRef.value.unshift(form);
return id;
return form;
};
const delRequest = async ({ row }: DelReq) => {

View File

@ -25,6 +25,7 @@ export default function ({ crudExpose, context: { asideTableRef } }: CreateCrudO
const onCurrentRowChange = (id: number) => {
currentRow.value = id;
asideTableRef.value.crudBinding.search.initialForm = { gradeId: id };
asideTableRef.value.setSearchFormData({ form: { gradeId: id } });
asideTableRef.value.doRefresh();
};
@ -90,7 +91,8 @@ export default function ({ crudExpose, context: { asideTableRef } }: CreateCrudO
// 嵌套表格字段
rules: [{ required: true, message: "请选择用户" }],
component: {
name: SubTable,
//局部引用子表格要用shallowRef包裹
name: shallowRef(SubTable),
vModel: "modelValue",
gradeId: compute(({ form }) => {
return form.id;

View File

@ -10,7 +10,7 @@
<script lang="ts">
import { defineComponent, onMounted, watch } from "vue";
import createCrudOptions from "./crud";
import { useFs } from "@fast-crud/fast-crud";
import {useFs, utils} from "@fast-crud/fast-crud";
export default defineComponent({
name: "SubTable",
@ -33,7 +33,7 @@ export default defineComponent({
return props.modelValue;
},
(value) => {
console.log("modelValue changed", value);
utils.logger.info("modelValue changed", value);
}
);
return {

View File

@ -1,6 +1,7 @@
import * as api from "./api.js";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { message } from "ant-design-vue";
import { computed } from "vue";
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const { crudBinding } = crudExpose;
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
@ -29,7 +30,10 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
},
toolbar: {
columnsFilter: {
mode: "default"
mode: "default",
container: {
width: "500px"
}
}
},
actionbar: {
@ -78,7 +82,12 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
type: "dict-radio",
dict: dict({
url: "/mock/dicts/OpenStatusEnum?single"
})
}),
column: {
show: computed(() => {
return true;
})
}
},
disabled: {
title: "列设置禁用",

View File

@ -1,6 +1,7 @@
import * as api from "./api";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { computed, ref } from "vue";
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { computed, ref, shallowRef } from "vue";
import ShallowComponent from "/@/views/crud/basis/compute-more/shallow-component.vue";
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
@ -22,13 +23,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
//普通的ref引用可以动态切换配置
const defValueRef = ref("我是动态的默认值");
const defValueComputed = computed(() => {
return defValueRef.value;
});
return {
output: {
defValueRef,
defValueComputed
defValueRef
},
crudOptions: {
request: {
@ -67,11 +64,39 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
type: "text",
search: { show: true, value: null },
form: {
// form.value不支持asyncCompute
// 假如你的默认值异步获取的,那么你自己必须保证先异步计算完成之后,才能打开对话框。
// 因为在打开对话框时,默认值就必须得设置好。
// form.value不支持asyncCompute/Compute, 因为上下文动态计算要先有上下文上下文需要先有form数据
value: defValueRef
}
},
switch: {
title: "切换动态组件",
type: "dict-radio",
dict: dict({
data: [
{ value: "radio", label: "radio" },
{ value: "select", label: "select" },
{ value: "shallow", label: "shallowComponent" }
]
})
},
componentName: {
title: "动态组件",
type: "dict-select",
search: { show: true, value: null },
dict: dict({
data: [
{ value: "1", label: "开启" },
{ value: "2", label: "关闭" }
]
}),
form: {
component: {
value: "2",
name: compute(({ form }) => {
return form.switch === "select" ? "fs-dict-select" : form.switch === "radio" ? "fs-dict-radio" : ShallowComponent;
})
}
}
}
}
}

View File

@ -0,0 +1,14 @@
<template>
<component :is="ui.tag.name" type="red">value : {{ modelValue || value }}</component>
</template>
<script setup lang="ts">
import { useUi } from "@fast-crud/ui-interface";
type ScProps = {
modelValue?: string;
value?: string;
};
const props = defineProps<ScProps>();
const { ui } = useUi();
</script>

View File

@ -33,6 +33,9 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
editRequest,
delRequest
},
toolbar: {
compact: false
},
table: {
scroll: {
x: 1500
@ -184,6 +187,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
search: { show: false },
type: "text",
column: {
order: 1000,
fixed: "right",
component: {
name: "a-switch",

View File

@ -48,7 +48,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
column: {
component: {
//引用自定义组件
name: shallowRef(VmodelCounter),
name: VmodelCounter,
color: "blue",
slots: {
//插槽示例
@ -68,7 +68,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
//form表单
component: {
//引用自定义组件
name: shallowRef(VmodelCounter),
name: VmodelCounter,
vModel: "modelValue",
color: "red",
on: {

View File

@ -1,7 +1,17 @@
import { requestForMock } from "/src/api/service";
const request = requestForMock;
const apiPrefix = "/mock/FsCrudFirst";
export function GetList(query: any) {
/**
*
*/
export type FirstRow = {
id?: number;
name?: string;
type?: number;
};
export function GetList(query: FirstRow) {
return request({
url: apiPrefix + "/page",
method: "get",
@ -9,7 +19,7 @@ export function GetList(query: any) {
});
}
export function AddObj(obj: any) {
export function AddObj(obj: FirstRow) {
return request({
url: apiPrefix + "/add",
method: "post",
@ -17,7 +27,7 @@ export function AddObj(obj: any) {
});
}
export function UpdateObj(obj: any) {
export function UpdateObj(obj: FirstRow) {
return request({
url: apiPrefix + "/update",
method: "post",

View File

@ -1,31 +1,34 @@
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery } from "@fast-crud/fast-crud";
import * as api from "./api";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {
return await api.DelObj(row.id);
};
const addRequest = async ({ form }: AddReq) => {
return await api.AddObj(form);
};
import { FirstRow } from "./api";
/**
* context
*/
export type FirstContext = {
test?: number;
};
export default function ({ crudExpose, context }: CreateCrudOptionsProps<FirstRow, FirstContext>): CreateCrudOptionsRet<FirstRow> {
context.test = 111;
return {
crudOptions: {
// 自定义crudOptions配置
request: {
pageRequest,
addRequest,
editRequest,
delRequest
pageRequest: async (query: UserPageQuery<FirstRow>) => {
return await api.GetList(query);
},
addRequest: async ({ form }: AddReq) => {
return await api.AddObj(form);
},
editRequest: async ({ form, row }: EditReq) => {
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
},
delRequest: async ({ row }: DelReq) => {
return await api.DelObj(row.id);
}
},
//两个字段
columns: {

View File

@ -1,5 +1,5 @@
<template>
<fs-page>
<fs-page class="page-first">
<template #header>
<div class="title">第一个crud</div>
<div class="more">
@ -7,13 +7,17 @@
</div>
</template>
<fs-crud ref="crudRef" v-bind="crudBinding" />
<a-tour v-model:current="current" :open="open" :steps="steps" @close="handleOpen(false)" />
</fs-page>
</template>
<script lang="ts">
import { defineComponent, onMounted } from "vue";
import { useFs } from "@fast-crud/fast-crud";
import createCrudOptions from "./crud";
import { defineComponent, onMounted, ref } from "vue";
import { useFs, utils } from "@fast-crud/fast-crud";
import createCrudOptions, { FirstContext } from "./crud";
import { TourProps } from "ant-design-vue";
import { FirstRow } from "./api";
//
export default defineComponent({
@ -32,15 +36,67 @@ export default defineComponent({
// =======fs=========
// ===============
const { crudRef, crudBinding, crudExpose, context } = useFs({ createCrudOptions, context: {} });
const { crudRef, crudBinding, crudExpose, context } = useFs<FirstRow, FirstContext>({ createCrudOptions, context: {} });
utils.logger.info("test", context.test);
function useTour() {
const open = ref<boolean>(false);
const current = ref(0);
//
const steps: TourProps["steps"] = [
{
title: "查询",
description: "查询数据.",
target: () => {
return document.querySelector(".page-first .fs-search-btn-search") as HTMLElement;
}
},
{
title: "重置",
description: "重置查询条件.",
target: () => {
return document.querySelector(".page-first .fs-search-btn-reset") as HTMLElement;
}
},
{
title: "添加",
description: "打开添加对话框",
target: () => {
return document.querySelector(".page-first .fs-actionbar-btn-add") as HTMLElement;
}
},
{
title: "刷新列表",
description: "刷新列表",
target: () => {
return document.querySelector(".page-first .fs-toolbar-btn-refresh") as HTMLElement;
}
}
];
const handleOpen = (val: boolean): void => {
open.value = val;
};
return {
open,
current,
steps,
handleOpen
};
}
const tour = useTour();
//
onMounted(() => {
crudExpose.doRefresh();
tour.handleOpen(true);
});
return {
crudBinding,
crudRef
crudRef,
...tour
};
}
});

View File

@ -18,10 +18,10 @@ import _ from "lodash-es";
//crudOptions
const createCrudOptions = function ({}: CreateCrudOptionsProps): CreateCrudOptionsRet {
//crud ----
const records = reactive([{ id: 1, name: "Hello World", type: 1 }]);
const records = [{ id: 1, name: "Hello World", type: 1 }];
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
return {
records,
records: _.cloneDeep(records),
offset: 0, //transformRescurrentPage
limit: 20, //transformRespageSize
total: records.length

View File

@ -100,6 +100,26 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
dict: dict({
url: "/mock/dicts/OpenStatusEnum?single"
})
},
text: {
title: "text",
type: "text",
search: { show: true }
},
text2: {
title: "text2",
type: "text",
search: { show: true }
},
text3: {
title: "text3",
type: "text",
search: { show: true }
},
text4: {
title: "text4",
type: "text",
search: { show: true }
}
}
}

View File

@ -6,7 +6,11 @@
<a target="_blank" href="http://fast-crud.docmirror.cn/guide/advance/layout.html">文档</a>
</div>
</template>
<fs-crud ref="crudRef" v-bind="crudBinding"> </fs-crud>
<fs-crud ref="crudRef" v-bind="crudBinding">
<template #actionbar-right>
<a-button type="danger">actionbar-right插槽</a-button>
</template>
</fs-crud>
</fs-page>
</template>

View File

@ -0,0 +1,50 @@
import { requestForMock } from "/src/api/service";
const request = requestForMock;
const apiPrefix = "/mock/BasisPlugin";
export function GetList(query: any) {
return request({
url: apiPrefix + "/page",
method: "get",
data: query
});
}
export function AddObj(obj: any) {
return request({
url: apiPrefix + "/add",
method: "post",
data: obj
});
}
export function UpdateObj(obj: any) {
return request({
url: apiPrefix + "/update",
method: "post",
data: obj
});
}
export function DelObj(id: any) {
return request({
url: apiPrefix + "/delete",
method: "post",
params: { id }
});
}
export function GetObj(id: any) {
return request({
url: apiPrefix + "/get",
method: "get",
params: { id }
});
}
export function BatchDelete(ids: any) {
return request({
url: apiPrefix + "/batchDelete",
method: "post",
data: { ids }
});
}

View File

@ -0,0 +1,72 @@
import * as api from "./api";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes, utils } from "@fast-crud/fast-crud";
import { ref } from "vue";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {
return await api.DelObj(row.id);
};
const addRequest = async ({ form }: AddReq) => {
return await api.AddObj(form);
};
const selectedRowKeys: Ref<any[]> = ref([]);
context.selectedRowKeys = selectedRowKeys;
return {
crudOptions: {
settings: {
plugins: {
//这里使用行选择插件生成行选择crudOptions配置最终会与crudOptions合并
rowSelection: {
enabled: true,
order: -2,
before: true,
// handle: (pluginProps,useCrudProps)=>CrudOptions,
props: {
multiple: true,
crossPage: true,
selectedRowKeys,
onSelectedChanged(selected) {
utils.logger.info("已选择变化:", selected);
}
}
}
}
},
request: {
pageRequest,
addRequest,
editRequest,
delRequest
},
columns: {
id: {
title: "ID",
type: "number",
column: {
width: 50
},
form: {
show: false
}
},
text: {
title: "Text",
type: "text",
search: { show: true }
}
}
}
};
}

View File

@ -0,0 +1,63 @@
<template>
<fs-page>
<template #header>
<div class="title">
CrudOptionsPlugin
<span class="sub">用于合并CrudOptions做一些可配置化的公共参数此处演示使用rowSelectionPlugin生成行选择配置,支持跨页选择</span>
</div>
<div class="more">
<a target="_blank" href="http://fast-crud.docmirror.cn/api/crud-options/settings.html#plugins">文档</a>
</div>
</template>
<fs-crud ref="crudRef" v-bind="crudBinding">
<template #pagination-left>
<a-tooltip title="批量删除">
<fs-button icon="DeleteOutlined" @click="handleBatchDelete"></fs-button>
</a-tooltip>
</template>
</fs-crud>
</fs-page>
</template>
<script lang="ts">
import { defineComponent, onMounted } from "vue";
import createCrudOptions from "./crud";
import { useFs } from "@fast-crud/fast-crud";
import { message, Modal } from "ant-design-vue";
import { BatchDelete } from "./api";
export default defineComponent({
name: "BasisPlugin",
setup() {
const { crudBinding, crudRef, crudExpose, context } = useFs({ createCrudOptions });
const selectedRowKeys = context.selectedRowKeys;
//
onMounted(() => {
crudExpose.doRefresh();
});
const handleBatchDelete = () => {
if (selectedRowKeys.value?.length > 0) {
Modal.confirm({
title: "确认",
content: `确定要批量删除这${selectedRowKeys.value.length}条记录吗`,
async onOk() {
await BatchDelete(selectedRowKeys.value);
message.info("删除成功");
crudExpose.doRefresh();
selectedRowKeys.value = [];
}
});
} else {
message.error("请先勾选记录");
}
};
return {
crudBinding,
crudRef,
handleBatchDelete
};
}
});
</script>

View File

@ -0,0 +1,22 @@
import mockUtil from "/src/mock/base";
const options: any = {
name: "BasisPlugin",
idGenerator: 0
};
const list = [
{
text: "张三",
radio: "1"
},
{
text: "李四",
radio: "2"
},
{
text: "王五",
radio: "0"
}
];
options.list = list;
const mock = mockUtil.buildMock(options);
export default mock;

View File

@ -1,6 +1,6 @@
import { requestForMock } from "/src/api/service";
const request = requestForMock;
const apiPrefix = "/mock/BasisReset";
const apiPrefix = "/mock/BasisValueChange";
export function GetList(query: any) {
return request({
url: apiPrefix + "/page",

View File

@ -15,14 +15,13 @@
<script lang="ts">
import { defineComponent, onMounted } from "vue";
import { CrudOptions, DynamicType, useFs } from "@fast-crud/fast-crud";
import { CrudOptions, DynamicType, useFs, UseFsProps } from "@fast-crud/fast-crud";
import createCrudOptions from "./crud.js";
import _ from "lodash-es";
export default defineComponent({
name: "BasisReset",
setup() {
const { crudBinding, crudRef, crudExpose, crudOptions, resetCrudOptions, appendBindingOptions } = useFs({ createCrudOptions, context: {} });
const { crudBinding, crudRef, crudExpose, context, crudOptions, resetCrudOptions, appendBindingOptions } = useFs({ createCrudOptions, context: { text: 111 } });
setTimeout(() => {
//crudOptions

View File

@ -1,7 +1,7 @@
// @ts-ignore
import mockUtil from "/src/mock/base";
const options: any = {
name: "BasisReset",
name: "BasisValueChange",
idGenerator: 0
};
const list = [

View File

@ -0,0 +1,54 @@
//@ts-ignore
import { requestForMock } from "/src/api/service";
const request = requestForMock;
const apiPrefix = "/mock/FsCrudFirst";
/**
*
*/
export type TsTestRow = {
id?: number;
name?: string;
type?: number;
compute?: string;
};
export function GetList(query: TsTestRow) {
return request({
url: apiPrefix + "/page",
method: "get",
data: query
});
}
export function AddObj(obj: TsTestRow) {
return request({
url: apiPrefix + "/add",
method: "post",
data: obj
});
}
export function UpdateObj(obj: TsTestRow) {
return request({
url: apiPrefix + "/update",
method: "post",
data: obj
});
}
export function DelObj(id: any) {
return request({
url: apiPrefix + "/delete",
method: "post",
params: { id }
});
}
export function GetObj(id: any) {
return request({
url: apiPrefix + "/get",
method: "get",
params: { id }
});
}

View File

@ -0,0 +1,79 @@
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery } from "@fast-crud/fast-crud";
import * as api from "./api";
import { TsTestRow } from "./api";
/**
* context
*/
export type TsTestContext = {
test?: number;
};
export default function ({ crudExpose, context }: CreateCrudOptionsProps<TsTestRow, TsTestContext>): CreateCrudOptionsRet<TsTestRow> {
context.test = 111;
return {
crudOptions: {
// 自定义crudOptions配置
columns: {
name: {
title: "姓名",
type: "text",
search: { show: true },
column: {
resizable: true,
width: 200
}
},
type: {
title: "类型",
type: "dict-select",
dict: dict({
data: [
{ value: 1, label: "开始", color: "green" },
{ value: 0, label: "停止", color: "red" }
]
}),
valueResolve: ({ form }) => {
console.log("valueResolve", form.type);
},
valueBuilder: ({ row }) => {
console.log("valueBuilder", row.type);
}
},
compute: {
title: "compute",
type: "text",
form: {
component: {
show: compute(({ form }) => {
//自动带form ts提示
return form.type === 1;
}),
disabled: compute<boolean, TsTestRow>(({ form }) => {
//disabled属性 不在component配置的定义中所有不带row、form的ts提示, 需要手动指定类型
return form.type === 1;
})
}
}
}
},
//两个字段
request: {
pageRequest: async (query: UserPageQuery) => {
return await api.GetList(query);
},
addRequest: async ({ form }: AddReq) => {
return await api.AddObj(form);
},
editRequest: async ({ form, row }: EditReq) => {
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
},
delRequest: async ({ row }: DelReq) => {
return await api.DelObj(row.id);
}
}
}
};
}

View File

@ -0,0 +1,47 @@
<template>
<fs-page class="page-first">
<template #header>
<div class="title">Ts定义测试</div>
<div class="more"></div>
</template>
<fs-crud ref="crudRef" v-bind="crudBinding" />
</fs-page>
</template>
<script lang="ts">
import { defineComponent, onMounted, ref } from "vue";
import { useFs, utils } from "@fast-crud/fast-crud";
import createCrudOptions, { TsTestContext } from "./crud";
import { TsTestRow } from "./api";
//
export default defineComponent({
name: "FsCrudTsTest",
setup() {
// // crudref
// const crudRef: Ref = ref();
// // crud ref
// const crudBinding: Ref<CrudBinding> = ref();
// //
// const { crudExpose } = useExpose({ crudRef, crudBinding });
// // crud
// const { crudOptions, customExport } = createCrudOptions({ crudExpose, customValue });
// // crud
// const { resetCrudOptions, appendCrudBinding } = useCrud({ crudExpose, crudOptions });
// =======fs=========
// ===============
const { crudRef, crudBinding, crudExpose, context } = useFs<TsTestRow, TsTestContext>({ createCrudOptions, context: {} });
utils.logger.info("test", context.test);
//
onMounted(() => {
crudExpose.doRefresh();
});
return {
crudBinding,
crudRef
};
}
});
</script>

View File

@ -0,0 +1,22 @@
// @ts-ignore
import mockUtil from "/src/mock/base";
const options: any = {
name: "FsCrudFirst",
idGenerator: 0
};
const list = [
{
name: "张三",
type: 1
},
{
name: "李四",
type: 0
},
{
name: "王五"
}
];
options.list = list;
const mock = mockUtil.buildMock(options);
export default mock;

View File

@ -1,6 +1,17 @@
import * as api from "./api";
import { message } from "ant-design-vue";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes, ValueChangeContext } from "@fast-crud/fast-crud";
import {
AddReq,
CreateCrudOptionsProps,
CreateCrudOptionsRet,
DelReq,
dict,
EditReq,
UserPageQuery,
UserPageRes,
utils,
ValueChangeContext
} from "@fast-crud/fast-crud";
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
@ -55,12 +66,12 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
vModel: "checked"
},
valueChange(context: ValueChangeContext) {
console.log("column value changed:", context);
utils.logger.info("column value changed:", context);
}
},
form: {
valueChange({ value, key, form }: ValueChangeContext) {
console.log("valueChanged,", key, value, form);
utils.logger.info("valueChanged,", key, value, form);
message.info(`valueChanged:${key}=${value}`);
}
}
@ -70,7 +81,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
type: "text",
form: {
valueChange({ value, key, form }: ValueChangeContext) {
console.log("valueChanged,", key, value, form);
utils.logger.info("valueChanged,", key, value, form);
message.info(`valueChanged:${key}=${value}`);
}
}
@ -84,7 +95,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
form: {
valueChange: {
handle({ value, key, form, immediate }: ValueChangeContext) {
console.log("valueChange,", key, value, "isImmediate=", immediate);
utils.logger.info("valueChange,", key, value, "isImmediate=", immediate);
message.info(`valueChanged:${key}=${value},isImmediate=${immediate}`);
},
immediate: true

View File

@ -50,6 +50,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
type: "button",
column: {
component: {
icon: "ion:search",
show: compute(({ value }) => {
//当value为null时不显示
return value != null;

View File

@ -1,5 +1,6 @@
<template>
<fs-page>
<div class="title">按钮</div>
<fs-crud ref="crudRef" v-bind="crudBinding" />
</fs-page>
</template>

View File

@ -1,6 +1,6 @@
import * as api from "./api";
import { requestForMock } from "/src/api/service";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes, utils, useUi } from "@fast-crud/fast-crud";
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
@ -19,6 +19,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
const addRequest = async ({ form }: AddReq) => {
return await api.AddObj(form);
};
const { ui } = useUi();
return {
crudOptions: {
request: {
@ -52,7 +53,18 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
dict: dict({
isTree: true,
url: "/mock/dicts/cascaderData?single"
})
}),
form: {
component: {
on: {
selectedChange({ $event }) {
utils.logger.info("onSelectedChange", $event);
const labels = $event.map((item) => item.label);
ui.message.info(`selected-change:${JSON.stringify(labels)}`);
}
}
}
}
},
lazyLoad: {
title: "懒加载",
@ -65,9 +77,6 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
prototype: true,
getNodesByValues(values: any) {
//给cell展示组件调用根据value值获取节点每行都会请求一次
if (values == null) {
return [];
}
return requestForMock({
url: "/mock/tree/GetNodesByValues",
params: { values }
@ -90,7 +99,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
}
],
loadData: async (selectedOptions: any) => {
console.log("lazyLoad", selectedOptions);
utils.logger.info("lazyLoad", selectedOptions);
const targetOption = selectedOptions[selectedOptions.length - 1];
targetOption.loading = true;

View File

@ -1,5 +1,5 @@
import * as api from "./api";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes, utils, useUi } from "@fast-crud/fast-crud";
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
@ -18,6 +18,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
const addRequest = async ({ form }: AddReq) => {
return await api.AddObj(form);
};
const { ui } = useUi();
return {
crudOptions: {
request: {
@ -44,7 +45,20 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
type: "dict-checkbox",
dict: dict({
url: "/mock/dicts/OpenStatusEnum?single"
})
}),
form: {
component: {
on: {
selectedChange({ form, $event }) {
// $event就是原始的事件值也就是选中的 option对象
utils.logger.info("onSelectedChange", form, $event);
ui.message.info(`你选择了${JSON.stringify($event)}`);
// 你还可以将选中的label值赋值给表单里其他字段
// context.form.xxxLabel = context.$event.label
}
}
}
}
}
}
}

View File

@ -2,7 +2,6 @@ import * as api from "./api";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, ScopeContext, UserPageQuery, UserPageRes, utils } from "@fast-crud/fast-crud";
import dayjs from "dayjs";
console.log("utils", utils);
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
return await api.GetList(query);
@ -33,6 +32,11 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
scroll: { x: 3000 }
},
rowHandle: { fixed: "right" },
search: {
initialForm: {
// datetimerange: [dayjs().subtract(1, "month").startOf("day"), dayjs().endOf("day")]
}
},
columns: {
id: {
title: "ID",
@ -54,7 +58,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
component: {}
},
valueBuilder({ value, row, key }) {
console.log("value builder:", key, value, row);
utils.logger.info("value builder:", key, value, row);
if (value != null) {
row[key] = dayjs(value);
}
@ -76,7 +80,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
}
},
valueBuilder({ value, row, key }) {
console.log("value builder:", key, value, row);
utils.logger.info("value builder:", key, value, row);
if (value != null) {
row[key] = dayjs(value);
}
@ -121,7 +125,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
valueFormat: "YYYY-MM-DD HH:mm:ss", //输入值的格式
on: {
onChange(context: ScopeContext) {
console.log("change", context);
utils.logger.info("change", context);
}
}
}
@ -187,7 +191,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
daterange: {
title: "日期范围",
type: "daterange",
search: { show: true, width: 300 },
search: { show: true, width: 300, col: { span: 6 } },
valueBuilder({ row, key }) {
if (!utils.strings.hasEmpty(row.daterangeStart, row.daterangeEnd)) {
row[key] = [dayjs(row.daterangeStart), dayjs(row.daterangeEnd)];
@ -197,7 +201,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
datetimerange: {
title: "日期时间范围",
type: "datetimerange",
search: { show: true, width: 300 },
search: { show: true, width: 300, col: { span: 8 } },
valueBuilder({ row, key }) {
if (!utils.strings.hasEmpty(row.datetimerangeStart, row.datetimerangeEnd)) {
row[key] = [dayjs(row.datetimerangeStart), dayjs(row.datetimerangeEnd)];

View File

@ -104,7 +104,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
toolbarConfig: {},
editorConfig: {},
onOnChange(value: any) {
console.log("value changed", value);
utils.logger.info("value changed", value);
},
uploader: {
type: "form",

View File

@ -26,6 +26,15 @@
<input type="file" @change="fileUploaderChange" />
<a v-if="signedUrl" :href="signedUrl" target="_blank"></a>
</a-form-item>
<a-form-item label="表格选择">
<fs-table-select v-model="form.tableSelect" v-bind="tableSelectBinding" />
<fs-label label="切换value">
<a-radio-group v-model:value="form.tableSelect">
<a-radio :value="1">王小虎</a-radio>
<a-radio :value="2">id为2的记录</a-radio>
</a-radio-group>
</fs-label>
</a-form-item>
<a-form-item>
<a-button @click="submit"></a-button>
</a-form-item>
@ -37,9 +46,11 @@
<script lang="ts" setup>
import { reactive, ref } from "vue";
import { message } from "ant-design-vue";
import { dict, useUi } from "@fast-crud/fast-crud";
import {dict, useUi, utils} from "@fast-crud/fast-crud";
import dayjs from "dayjs";
import { FsUploaderS3, loadUploader, useUploader } from "@fast-crud/fast-extends";
import createCrudOptionsText from "/@/views/crud/component/text/crud";
import * as textTableApi from "/@/views/crud/component/text/api";
defineOptions({
name: "ComponentIndependent"
@ -49,7 +60,8 @@ const form = reactive({
avatar: undefined,
copyable: "可复制的内容",
select: 1,
humanizeTime: dayjs(new Date().getTime() - 100000)
humanizeTime: dayjs(new Date().getTime() - 100000),
tableSelect: null
});
const uploader = ref({
@ -66,7 +78,7 @@ const cropperUploader = ref({
viewMode: 1
},
async onReady(context: any) {
console.log("onReady", context);
utils.logger.info("onReady", context);
context.zoom(-0.1);
context.zoom(-0.1);
context.zoom(-0.1);
@ -81,6 +93,26 @@ const dictRef = dict({
]
});
const tableSelectBinding = ref({
dict: dict({
value: "id",
label: "name",
getNodesByValues: async (values: any[]) => {
return await textTableApi.GetByIds(values);
}
}),
crossPage: true,
valuesFormat: {
labelFormatter: (item: any) => {
return `${item.id}.${item.name}`;
}
},
select: {
placeholder: "点击选择"
},
createCrudOptions: createCrudOptionsText
});
const signedUrl = ref();
async function fileUploaderChange(event: any) {
const file = event.target.files[0];
@ -90,7 +122,7 @@ async function fileUploaderChange(event: any) {
file,
fileName: file.name,
onProgress(progress: any) {
console.log("progress:" + progress.percent + "%");
utils.logger.info("progress:" + progress.percent + "%");
}
});
const { ui } = useUi();
@ -104,6 +136,6 @@ async function fileUploaderChange(event: any) {
function submit() {
message.info("submit:" + JSON.stringify(form));
console.log("submit:", form);
utils.logger.info("submit:", form);
}
</script>

View File

@ -0,0 +1,50 @@
import { requestForMock } from "/src/api/service";
const request = requestForMock;
const apiPrefix = "/mock/ComponentPhone";
export function GetList(query: any) {
return request({
url: apiPrefix + "/page",
method: "get",
data: query
});
}
export function AddObj(obj: any) {
return request({
url: apiPrefix + "/add",
method: "post",
data: obj
});
}
export function UpdateObj(obj: any) {
return request({
url: apiPrefix + "/update",
method: "post",
data: obj
});
}
export function DelObj(id: any) {
return request({
url: apiPrefix + "/delete",
method: "post",
params: { id }
});
}
export function GetObj(id: any) {
return request({
url: apiPrefix + "/get",
method: "get",
params: { id }
});
}
export function GetByIds(ids: any) {
return request({
url: apiPrefix + "/byIds",
method: "post",
data: { ids }
});
}

View File

@ -0,0 +1,92 @@
import * as api from "./api";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, ScopeContext, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { SearchOutlined } from "@ant-design/icons-vue";
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {
return await api.DelObj(row.id);
};
const addRequest = async ({ form }: AddReq) => {
return await api.AddObj(form);
};
return {
crudOptions: {
request: {
pageRequest,
addRequest,
editRequest,
delRequest
},
columns: {
id: {
title: "ID",
type: "number",
form: { show: false }
},
phone: {
title: "手机号码",
type: "phone",
search: { show: true }
},
phoneNumber: {
title: "区号手机号分开",
type: "phone",
valueBuilder({ row, key, value }) {
row[key] = {
callingCode: row.code || undefined,
phoneNumber: value || ""
};
},
valueResolve({ form, key, value }) {
if (value) {
form.code = value.callingCode;
form.phoneNumber = value.phoneNumber;
}
}
},
only: {
title: "仅某些国家",
type: "phone",
form: {
component: {
onlyCountries: ["CN", "US"]
},
helper: "仅CN,US"
}
},
ignore: {
title: "排除某些国家",
type: "phone",
form: {
component: {
ignoredCountries: ["jp"]
},
helper: "排除JP"
}
},
priority: {
title: "优先某些国家",
type: "phone",
form: {
component: {
priorityCountries: ["CN", "US"],
ignoredCountries: ["jp"]
},
helper: "优先CNUS排除JP"
}
}
}
}
};
}

View File

@ -0,0 +1,37 @@
<template>
<fs-page>
<template #header>
<div class="title">
国际手机号输入
<span class="sub"> </span>
</div>
<div class="more">
<a target="_blank" href="http://fast-crud.docmirror.cn/api/components/extends/input/components/fs-phone-input">文档</a>
</div>
</template>
<fs-crud ref="crudRef" v-bind="crudBinding" />
</fs-page>
</template>
<script lang="ts">
import { defineComponent, onMounted } from "vue";
import { useFs } from "@fast-crud/fast-crud";
import createCrudOptions from "./crud";
export default defineComponent({
name: "ComponentPhone",
setup() {
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions });
//
onMounted(() => {
crudExpose.doRefresh();
});
return {
crudBinding,
crudRef
};
}
});
</script>

View File

@ -0,0 +1,18 @@
import mockUtil from "/src/mock/base";
const options: any = {
name: "ComponentPhone",
idGenerator: 0
};
const list = [
{
phone: {
callingCode: "86",
phoneNumber: "12345678"
},
code: "86",
phoneNumber: "12424354"
}
];
options.list = list;
const mock = mockUtil.buildMock(options);
export default mock;

View File

@ -1,5 +1,5 @@
import * as api from "./api";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes, useUi, utils } from "@fast-crud/fast-crud";
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
return await api.GetList(query);
@ -17,7 +17,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
const addRequest = async ({ form }: AddReq) => {
return await api.AddObj(form);
};
const { ui } = useUi();
return {
crudOptions: {
request: {
@ -44,7 +44,23 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
type: "dict-radio",
dict: dict({
url: "/mock/dicts/OpenStatusEnum?single"
})
}),
form: {
valueChange({ value }) {
utils.logger.info("change", value);
},
component: {
on: {
selectedChange({ form, $event }) {
// $event就是原始的事件值也就是选中的 option对象
utils.logger.info("onSelectedChange", form, $event);
ui.message.info(`你选择了${JSON.stringify($event)}`);
// 你还可以将选中的label值赋值给表单里其他字段
// context.form.xxxLabel = context.$event.label
}
}
}
}
},
button: {
title: "按钮样式",

View File

@ -1,6 +1,6 @@
import * as api from "./api";
import { requestForMock } from "/src/api/service";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, DictOnReadyContext, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, DictOnReadyContext, EditReq, UserPageQuery, UserPageRes, useUi, utils } from "@fast-crud/fast-crud";
import { ref } from "vue";
import _ from "lodash-es";
function useSearchRemote() {
@ -11,7 +11,7 @@ function useSearchRemote() {
fetching: ref(false)
};
const fetchUser = _.debounce((value) => {
console.log("fetching user", value);
utils.logger.info("fetching user", value);
lastFetchId += 1;
const fetchId = lastFetchId;
@ -76,6 +76,8 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
//dictRef.toMap();
}
const { ui } = useUi();
const { fetchUser, searchState } = useSearchRemote();
return {
dynamicUpdateDictOptions,
@ -117,7 +119,24 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
statusLocal: {
title: "单选本地",
type: "dict-select",
dict: dictRef
dict: dictRef,
form: {
component: {
onChange(args: any) {
utils.logger.info("onChange", args);
},
on: {
selectedChange({ form, $event }) {
// $event就是原始的事件值也就是选中的 option对象
utils.logger.info("onSelectedChange", form, $event);
ui.message.info(`你选择了${JSON.stringify($event)}`);
// 你还可以将选中的label值赋值给表单里其他字段
// context.form.xxxLabel = context.$event.label
}
}
},
helper: "selected-change事件可以获取选中的option对象"
}
},
statusRemote: {
title: "单选远程",
@ -131,11 +150,6 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
}),
form: {
rules: [{ required: true, message: "请选择一个选项" }]
},
column: {
component: {
type: "text"
}
}
},
filter: {
@ -191,7 +205,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
dict: dict({
getData({ dict }) {
// 覆盖全局获取字典请求配置
console.log(`我是从自定义的getData方法中加载的数据字典`, dict);
utils.logger.info(`我是从自定义的getData方法中加载的数据字典`, dict);
return requestForMock({
url: "/mock/dicts/OpenStatusEnum?cache",
method: "get"
@ -221,7 +235,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
// 此处dict配置会覆盖上面dict的属性
prototype: true, // form表单的dict设置为原型复制每次初始化时都会重新loadDict
onReady({ dict }: DictOnReadyContext) {
console.log("字典请求ready", dict);
utils.logger.info("字典请求ready", dict);
dict.data[0].disabled = true; // 禁用某个选项, 还可以自己修改选项
}
}
@ -242,7 +256,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
component: {
//监听 dict-change事件
onDictChange({ dict, form, key }: any) {
console.log("dict data changed", dict, key);
utils.logger.info("dict data changed", dict, key);
if (dict.data != null && form.firstDefault == null) {
form.firstDefault = dict.data[0].value;
}

View File

@ -1,5 +1,16 @@
import * as api from "./api";
import { dict, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, UserPageQuery, UserPageRes, EditReq, DelReq, AddReq } from "@fast-crud/fast-crud";
import {
dict,
compute,
CreateCrudOptionsProps,
CreateCrudOptionsRet,
UserPageQuery,
UserPageRes,
EditReq,
DelReq,
AddReq,
utils
} from "@fast-crud/fast-crud";
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
return await api.GetList(query);
@ -98,7 +109,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
name: "fs-dict-switch",
vModel: "checked",
onChange: (value: any) => {
console.log("onChange", value);
utils.logger.info("onChange", value);
}
// onChange: compute((context) => {
// //动态onChange方法测试
@ -132,7 +143,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
},
form: {
show: compute((context) => {
console.log("context", context);
utils.logger.info("context", context);
//根据cellSwitch字段显隐
return context.form.cellSwitch === true;
})

View File

@ -1,7 +1,8 @@
import * as api from "./api";
import * as textTableApi from "../text/api";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes, useUi } from "@fast-crud/fast-crud";
import createCrudOptionsText from "../text/crud";
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
return await api.GetList(query);
@ -20,6 +21,17 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.AddObj(form);
};
const crudOptionsOverride = {
table: {
scroll: {
x: 2000
}
},
rowHandle: {
fixed: "right"
}
};
const { ui } = useUi();
return {
crudOptions: {
request: {
@ -40,6 +52,16 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
show: false
}
},
dynamicShow: {
title: "动态显隐",
type: "dict-switch",
dict: dict({
data: [
{ value: true, label: "显示" },
{ value: false, label: "隐藏" }
]
})
},
single: {
title: "单选",
search: { show: true },
@ -47,19 +69,31 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
dict: dict({
value: "id",
label: "name",
//重要根据value懒加载数据
getNodesByValues: async (values: any[]) => {
return await textTableApi.GetByIds(values);
}
}),
form: {
show: compute(({ form }) => {
return form.dynamicShow;
}),
component: {
crossPage: true,
valuesFormat: {
labelFormatter: (item: any) => {
return `${item.id}.${item.name}`;
}
},
select: {
placeholder: "点击选择"
},
createCrudOptions: createCrudOptionsText,
crudOptionsOverride: {
table: {
scroll: {
x: 2000
}
crudOptionsOverride,
on: {
selectedChange({ $event }) {
console.log("selectedChange", $event);
ui.message.info(`你选择了${JSON.stringify($event)}`);
}
}
}
@ -72,6 +106,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
dict: dict({
value: "id",
label: "name",
//重要根据value懒加载数据
getNodesByValues: async (values: any[]) => {
return await textTableApi.GetByIds(values);
}
@ -80,15 +115,126 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
component: {
crossPage: true,
multiple: true,
valuesFormat: {
labelFormatter: (item: any) => {
return `${item.id}.${item.name}`;
}
},
select: {
placeholder: "点击选择"
},
createCrudOptions: createCrudOptionsText,
crudOptionsOverride: {
table: {
scroll: {
x: 2000
crudOptionsOverride: crudOptionsOverride
}
},
column: {
component: {
labelFormatter: (item: any) => {
return `${item.id}.${item.name}`;
}
}
}
},
valueType: {
title: "object类型",
search: { show: true },
type: "table-select",
dict: dict({
value: "id",
label: "name",
//重要根据value懒加载数据
getNodesByValues: async (values: any[]) => {
return await textTableApi.GetByIds(values);
}
}),
column: {
component: {
valueType: "object"
}
},
form: {
helper: "这里提交的值是整个对象",
component: {
valueType: "object",
crossPage: true,
valuesFormat: {
labelFormatter: (item: any) => {
return `${item.id}.${item.name}`;
}
},
select: {
placeholder: "点击选择"
},
createCrudOptions: createCrudOptionsText,
crudOptionsOverride
}
}
},
//值是object类型
valueTypeMulti: {
title: "object类型多选",
search: { show: true },
type: "table-select",
dict: dict({
value: "id",
label: "name",
getNodesByValues: async (values: any[]) => {
return await textTableApi.GetByIds(values);
}
}),
column: {
component: {
valueType: "object"
}
},
form: {
helper: "这里提交的值是对象数组",
component: {
valueType: "object",
crossPage: true,
multiple: true,
valuesFormat: {
labelFormatter: (item: any) => {
return `${item.id}.${item.name}`;
}
},
select: {
placeholder: "点击选择"
},
createCrudOptions: createCrudOptionsText,
crudOptionsOverride
}
}
},
viewMode: {
title: "查看模式",
dict: dict({
value: "id",
label: "name"
}),
column: {
component: {
name: "fs-table-select",
//设置为查看模式
viewMode: true,
createCrudOptions: createCrudOptionsText,
crudOptionsOverride,
slots: {
default({ scope, value }) {
async function open() {
//打开时传入默认查询参数
const crudOptions = {
search: {
initialForm: {
classId: value
}
}
};
const { crudExpose } = await scope.open({ crudOptions });
// 这里还能通过crudExpose等返回值操作表格
}
},
rowHandle: {
fixed: "right"
return <a-button onClick={open}>:{value}</a-button>;
}
}
}

View File

@ -1,13 +1,33 @@
<template>
<fs-page>
<template #header>
<div class="title">table-select</div>
<div class="more">
<fs-label label="直接设置值">
<fs-table-select v-model="value" :dict="singleDictRef" :create-crud-options="createCrudOptionsText" />
<a-button @click="setValue"> </a-button>
</fs-label>
<fs-label label="自定义插槽">
{{ value }}
<fs-table-select v-model="value" :dict="singleDictRef" :create-crud-options="createCrudOptionsText">
<template #default="scope">
<fs-button @click="scope.open()"> </fs-button>
</template>
</fs-table-select>
</fs-label>
</div>
</template>
<fs-crud ref="crudRef" v-bind="crudBinding" />
</fs-page>
</template>
<script lang="ts">
import createCrudOptionsText from "../text/crud";
import { defineComponent, onMounted, ref } from "vue";
import createCrudOptions from "./crud.js";
import { useFs } from "@fast-crud/fast-crud";
import { dict, useFs } from "@fast-crud/fast-crud";
import * as textTableApi from "/@/views/crud/component/text/api";
export default defineComponent({
name: "ComponentTableSelect",
@ -20,10 +40,25 @@ export default defineComponent({
});
const value = ref(null);
const singleDictRef = dict({
value: "id",
label: "name",
//value
getNodesByValues: async (values: any[]) => {
return await textTableApi.GetByIds(values);
}
});
function setValue() {
value.value = 1;
}
return {
crudBinding,
crudRef,
value
value,
singleDictRef,
createCrudOptionsText,
setValue
};
}
});

View File

@ -6,11 +6,15 @@ const options: any = {
const list = [
{
single: 1,
multi: [1, 2]
multi: [1, 2],
valueType: { id: 1, name: "王小虎" },
viewMode: 1
},
{
single: 3,
multi: [1, 2, 3]
multi: [1, 2, 3],
dynamicShow: false,
viewMode: 2
},
{
single: 2

View File

@ -40,6 +40,7 @@ export function GetObj(id: any) {
params: { id }
});
}
export function GetByIds(ids: any) {
return request({
url: apiPrefix + "/byIds",

View File

@ -1,5 +1,5 @@
import * as api from "./api";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, ScopeContext, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, ScopeContext, UserPageQuery, UserPageRes, utils } from "@fast-crud/fast-crud";
import { SearchOutlined } from "@ant-design/icons-vue";
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
@ -29,6 +29,11 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
delRequest
},
columns: {
id: {
title: "ID",
type: "number",
form: { show: false }
},
name: {
title: "姓名",
type: "text", //虽然不写也能正确显示组件,但不建议省略它
@ -37,8 +42,19 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
component: {
maxlength: 20
}
},
column: {
formatter(scope) {
utils.logger.info("formatter scope", scope);
return scope.value;
}
}
},
classId: {
title: "班级id",
type: "number", //虽然不写也能正确显示组件,但不建议省略它
search: { show: true }
},
trim: {
title: "trim空格",
type: "text", //虽然不写也能正确显示组件,但不建议省略它
@ -150,7 +166,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
title: "复杂输入",
component: {
render(context: ScopeContext) {
console.log("context scope", context);
utils.logger.info("context scope", context);
return (
<a-input-group compact>
<a-input placeholder={"render1 input"} style="width: 50%" v-model={[context.form.render, "value"]} />

View File

@ -17,21 +17,24 @@ const list = [
address: "123123",
zip: "518000",
intro: "王小虎是element-plus的table示例出现的名字",
copy: "测试文本"
copy: "测试文本",
classId: 1
},
{
name: "张三",
date: "2016-05-04",
status: "1",
province: "2",
copy: "测试文本"
copy: "测试文本",
classId: 2
},
{
name: "李四",
date: 2232433534511,
status: "1",
province: "0",
copy: "测试文本"
copy: "测试文本",
classId: 3
},
{
name: "王五",

View File

@ -1,5 +1,5 @@
import * as api from "./api";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes, useUi, utils } from "@fast-crud/fast-crud";
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
return await api.GetList(query);
@ -18,6 +18,26 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.AddObj(form);
};
const lazyloadDictRef = dict({
data: [
{
id: "0",
label: "Root",
value: "0"
}
]
});
const genTreeNode = (parentId: number, isLeaf = false) => {
const random = Math.random().toString(36).substring(2, 6);
return {
id: random,
pId: parentId,
value: random,
label: isLeaf ? "Tree Node" : "Expand to load",
isLeaf
};
};
const { ui } = useUi();
return {
crudOptions: {
request: {
@ -45,7 +65,30 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
dict: dict({
isTree: true,
url: "/mock/dicts/cascaderData?single"
})
}),
form: {
valueChange({ getComponentRef }) {
const compRef = getComponentRef("tree");
console.log("tree ref:", compRef, compRef.$refs.treeRef);
},
component: {
on: {
selectedChange({ form, $event }) {
// $event就是原始的事件值也就是选中的 option对象
utils.logger.info("onSelectedChange", form, $event);
ui.message.info(`你选择了${JSON.stringify($event.label)}`);
// 你还可以将选中的label值赋值给表单里其他字段
// context.form.xxxLabel = context.$event.label
}
},
slots: {
title({ scope }) {
//自定义选项text
return `${scope.label}(${scope.value})`;
}
}
}
}
},
multiple: {
title: "多选",
@ -57,7 +100,27 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
}),
form: {
component: {
"tree-checkable": true
"tree-checkable": true,
on: {
selectedChange({ form, $event }) {
// $event就是原始的事件值也就是选中的 option对象
utils.logger.info("onSelectedChange", form, $event);
const labels = $event.map((item) => item.label);
ui.message.info(`你选择了${JSON.stringify(labels)}`);
// 你还可以将选中的label值赋值给表单里其他字段
// context.form.xxxLabel = context.$event.label
}
}
},
rules: [{ required: true, message: "请选择" }],
on: {
selectedChange({ form, $event }) {
// $event就是原始的事件值也就是选中的 option对象
utils.logger.info("onSelectedChange", form, $event);
ui.message.info(`你选择了${JSON.stringify($event)}`);
// 你还可以将选中的label值赋值给表单里其他字段
// context.form.xxxLabel = context.$event.label
}
}
}
},
@ -70,10 +133,25 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
url: "/mock/dicts/littlePca",
value: "code",
label: "name"
}),
})
},
lazy: {
title: "懒加载",
search: { show: false },
type: "dict-tree",
dict: lazyloadDictRef,
form: {
component: {
fieldNames: { label: "name", key: "code", value: "code" }
"tree-data-simple-mode": true,
loadData: (treeNode: any) => {
return new Promise((resolve: (value?: unknown) => void) => {
const { id } = treeNode.dataRef;
setTimeout(() => {
lazyloadDictRef.data = lazyloadDictRef.data.concat([genTreeNode(id, false), genTreeNode(id, true)]);
resolve();
}, 300);
});
}
}
}
}

View File

@ -44,6 +44,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
type: "file-uploader",
form: {
component: {
multiple: true, //可选择多个
uploader: {
type: "alioss"
}
@ -58,7 +59,8 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
uploader: {
type: "alioss"
}
}
},
helper: "可以同时选择多个文件"
}
},
cropper: {

View File

@ -44,10 +44,12 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
type: "file-uploader",
form: {
component: {
multiple: true, //可选择多个
uploader: {
type: "cos"
}
}
},
helper: "可以同时选择多个文件"
}
},
pictureCard: {

View File

@ -41,7 +41,14 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
},
cropper: {
title: "头像裁剪上传",
type: "cropper-uploader"
type: "cropper-uploader",
form: {
component: {
uploader: {
type: "form"
}
}
}
},
avatar: {
title: "数量限制",

View File

@ -1,5 +1,5 @@
import * as api from "./api";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes, utils } from "@fast-crud/fast-crud";
import { createUploaderRules } from "@fast-crud/fast-extends";
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
@ -33,7 +33,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
async onOpened() {
// 异步组件实例的获取
const componentRef = await crudExpose.getFormComponentRef("file", true);
console.log("componentRef", componentRef);
utils.logger.info("componentRef", componentRef);
}
}
},
@ -56,9 +56,11 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
component: {
multiple: true, //可选择多个
uploader: {
type: "form"
type: "form",
keepName: true
}
}
},
helper: "可以同时选择多个文件"
},
column: {
component: {
@ -155,20 +157,14 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
},
valueType: "key",
async buildUrl(value: any) {
return new Promise((resolve) => {
const url = "http://www.docmirror.cn:7070/api/upload/form/download?key=" + value;
resolve(url);
});
return "http://www.docmirror.cn:7070/api/upload/form/download?key=" + value;
}
}
},
column: {
component: {
async buildUrl(value: any) {
return new Promise((resolve) => {
const url = "http://www.docmirror.cn:7070/api/upload/form/download?key=" + value;
resolve(url);
});
return "http://www.docmirror.cn:7070/api/upload/form/download?key=" + value;
}
}
}
@ -193,24 +189,19 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
valueType: "fileId",
async buildUrls(value: any[]) {
//批量构建url
return new Promise((resolve) => {
const urls: string[] = [];
for (const item of value) {
const url = "http://www.docmirror.cn:7070/api/upload/form/download?key=" + item;
urls.push(url);
}
resolve(urls);
});
const urls: string[] = [];
for (const item of value) {
const url = "http://www.docmirror.cn:7070/api/upload/form/download?key=" + item;
urls.push(url);
}
return urls;
}
}
},
column: {
component: {
async buildUrl(value: any) {
return new Promise((resolve) => {
const url = "http://www.docmirror.cn:7070/api/upload/form/download?key=" + value;
resolve(url);
});
return "http://www.docmirror.cn:7070/api/upload/form/download?key=" + value;
}
}
}

View File

@ -43,10 +43,12 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
type: "file-uploader",
form: {
component: {
multiple: true, //可选择多个
uploader: {
type: "qiniu"
}
}
},
helper: "可以同时选择多个文件"
}
},
pictureCard: {

View File

@ -1,7 +1,8 @@
// @ts-ignore
import { S3Client, GetObjectCommand, PutObjectCommand, CreateBucketCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
import {utils} from "@fast-crud/fast-crud";
// TODO 模拟server 你应该将此代码搬到你的server端
let bucketCreated = false;
export async function generateSignedUrl(bucket: string, key: string, type: "put" | "get" = "get") {
const client = new S3Client({
@ -39,7 +40,7 @@ export async function generateSignedUrl(bucket: string, key: string, type: "put"
try {
url = await getSignedUrl(client, cmd);
} catch (err) {
console.log("Error getting signed URL ", err);
utils.logger.info("Error getting signed URL ", err);
}
return url;

View File

@ -1,8 +1,7 @@
import * as api from "./api";
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes, utils } from "@fast-crud/fast-crud";
import dayjs from "dayjs";
import { computed, Ref, ref } from "vue";
import dayjs from "dayjs";
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
return await api.GetList(query);
@ -23,71 +22,168 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
const options: Ref = ref([]);
let arr = [
{
value: "1",
label: "test"
},
{
value: "1",
label: "test2"
}
];
for (let i = 0; i < 10; i++) {
arr = arr.concat(arr);
}
let i = 0;
for (const item of arr) {
i++;
item.value = i + "";
}
options.value = arr;
return {
crudOptions: {
table: {},
request: {
pageRequest,
addRequest,
editRequest,
delRequest
},
form: {
// 单列布局
col: { span: 24 },
labelCol: { span: 4 },
wrapperCol: { span: 18 }
},
toolbar: {},
rowHandle: {
fixed: "right"
buttons: {
edit: { show: true }
}
},
form: {
watch({ form }) {
form.totalAmount = form.users * form.months * form.licensePrice;
form.statementAmount = form.totalAmount - form.discountAmount;
form.statementPrice = form.statementAmount / form.months / form.users;
if (form.months && form.startTime) {
// form.endTime = dayjs(form.startTime).add(form.months, "month");
}
}
},
columns: {
id: {
title: "ID",
key: "id",
type: "text",
form: { show: false },
column: { show: false }
},
users: {
title: "用户数量",
type: "number",
column: {
width: 50
},
column: { width: 120 },
form: {
show: false
component: { min: 1, max: 10000 },
rules: [{ required: true, message: "用户数量不能为空" }]
}
},
statusRemote: {
title: "单选远程",
search: {
show: false
months: {
title: "月数",
type: "number",
column: { width: 100 },
form: {
component: { min: 1, max: 120 },
rules: [{ required: true, message: "采购月数不能为空" }]
}
},
licensePrice: {
title: "单用户价",
type: "number",
column: { width: 150 },
form: {
component: { min: 1, max: 99999 },
helper: "单个用户许可价格"
}
},
totalAmount: {
title: "总额",
type: "number",
search: { show: false },
column: { width: 150 },
form: {
component: { disabled: true }
}
},
discountAmount: {
title: "优惠",
type: "number",
column: { width: 150 },
addForm: {
value: 0
},
form: {
component: { min: 0, max: 9999999 },
rules: [{ required: true, message: "优惠金额不能为空" }]
}
},
statementAmount: {
title: "结算金额",
type: "number",
search: { show: false },
column: { width: 150 },
form: {
component: { disabled: true },
rules: [{ required: true, message: "结算金额不能为空" }],
helper: "结算金额 = 总额 - 优惠金额"
}
},
statementPrice: {
title: "结算单价",
type: "number",
column: { width: 150 },
form: {
component: { disabled: true },
helper: "结算单价 = 结算金额 / 月份 / 用户数"
}
},
startTime: {
title: "开始时间",
type: "date",
valueBuilder({ value, row, key }) {
if (value != null) {
row[key] = dayjs.unix(value);
}
},
valueResolve({ value, row, key }) {
if (value != null) {
row[key] = dayjs(value).unix();
}
},
form: {
rules: [{ required: true, message: "订阅起始日期不能为空" }],
component: {
format: "YYYY-MM-DD"
}
}
},
endTime: {
title: "结束时间",
type: "date",
valueResolve({ value, row, key }) {
if (value != null) {
row[key] = dayjs(value).unix();
}
},
form: {
component: {
format: "YYYY-MM-DD",
disabled: true
},
rules: [{ required: true, message: "订阅结束日期不能为空" }],
helper: "结束日期 = 开始日期 + 采购月份"
}
},
paymentStatus: {
title: "状态",
type: "dict-select",
column: { width: 100, align: "center" },
search: { show: true },
dict: dict({
url: "/mock/dicts/ManyOpenStatusEnum?from=dict1"
data: [
{ value: "0", label: "待支付", color: "error" },
{ value: "10", label: "部分支付", color: "warning" },
{ value: "20", label: "已支付", color: "success" }
]
}),
form: {
component: { mode: "multiple" },
rules: [{ required: true, message: "请选择一个选项" }]
},
column: {
width: 200
rules: [{ required: true, message: "支付状态不能为空" }]
}
},
description: {
title: "产品描述",
column: { show: false },
type: ["textarea"],
form: {
rules: [{ required: true, message: "描述不能为空" }],
col: {
span: 24
}
}
}
}

View File

@ -1,5 +1,5 @@
import * as api from "./api";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes, ValueChangeContext } from "@fast-crud/fast-crud";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes, utils } from "@fast-crud/fast-crud";
import { requestForMock } from "../../../../api/service";
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
@ -80,7 +80,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
vModel: "checked"
},
valueChange({ form, value, getComponentRef }) {
console.log("form", value);
utils.logger.info("form", value);
const targetDict = getComponentRef("remote").getDict();
targetDict.url = form.modifyDict ? "/mock/dicts/moreOpenStatusEnum?remote" : "/mock/dicts/OpenStatusEnum?remote";
targetDict.reloadDict();
@ -92,7 +92,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
vModel: "checked"
},
valueChange({ value, getComponentRef }) {
console.log("value", value);
utils.logger.info("value", value);
const targetDict = getComponentRef("remote").getDict();
targetDict.url = value ? "/mock/dicts/moreOpenStatusEnum?remote" : "/mock/dicts/OpenStatusEnum?remote";
targetDict.reloadDict();

View File

@ -1,5 +1,5 @@
import * as api from "./api";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes, utils } from "@fast-crud/fast-crud";
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
return await api.GetList(query);
@ -55,7 +55,15 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
},
status: {
title: "本地字典",
search: { show: false },
search: {
show: true,
component: {
transformDictData(data: any[]) {
data.unshift({ value: "", label: "全部" });
return data;
}
}
},
dict: statusDict,
type: "dict-select"
},
@ -67,7 +75,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
column: {
component: {
onDictChange(opts: any) {
console.log("字典变化:", opts);
utils.logger.info("字典变化:", opts);
}
}
}
@ -82,7 +90,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
vModel: "checked"
},
valueChange({ form }) {
console.log("changed", form.modifyDict);
utils.logger.info("changed", form.modifyDict);
remoteDict.url = form.modifyDict ? "/mock/dicts/moreOpenStatusEnum?remote" : "/mock/dicts/OpenStatusEnum?remote";
// 由于remoteDict.cloneable =false,所以全局公用一个实例,修改会影响全部地方
remoteDict.reloadDict();
@ -101,6 +109,28 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
}
}
}
},
cache1: {
title: "全局缓存1",
search: { show: false },
dict: dict({
url: "/mock/dicts/OpenStatusEnum?cache_flat=1",
cache: true
}),
type: "dict-select"
},
cache2: {
title: "全局缓存2",
search: { show: false },
column: {
show: false
},
dict: dict({
url: "/mock/dicts/OpenStatusEnum?cache_flat=1",
immediate: false,
cache: true
}),
type: "dict-select"
}
}
}

View File

@ -19,7 +19,7 @@
<script lang="ts">
import { defineComponent, onMounted } from "vue";
import { useFs } from "@fast-crud/fast-crud";
import {useFs, utils} from "@fast-crud/fast-crud";
import createCrudOptions from "./crud";
export default defineComponent({
@ -33,7 +33,7 @@ export default defineComponent({
});
function onClick() {
console.log("this.ref", crudRef.value);
utils.logger.info("this.ref", crudRef.value);
}
return {

View File

@ -57,7 +57,7 @@ export function UpdateCell(id: number, key: string, value: any) {
data: { id, key, value }
});
}
export function UpdateColumn(data) {
export function UpdateColumn(data: any) {
return request({
url: apiPrefix + "/columnUpdate",
method: "post",

Some files were not shown because too many files have changed in this diff Show More