Compare commits

...

34 Commits

Author SHA1 Message Date
xiaojunnuo
b745712791 v1.20.2 2024-02-28 11:17:55 +08:00
xiaojunnuo
7ee753ac85 build: prepare to build 2024-02-28 11:14:08 +08:00
xiaojunnuo
eea6b8ab5d chore: 2024-02-28 10:36:44 +08:00
xiaojunnuo
a135f5742c Merge remote-tracking branch 'origin/client_sync' into v2
# Conflicts:
#	packages/ui/certd-client/CHANGELOG.md
#	packages/ui/certd-client/package.json
2024-02-28 10:29:12 +08:00
xiaojunnuo
04adbb45d8 build: prepare to build 2024-02-28 10:25:07 +08:00
xiaojunnuo
62efb22f37 chore: 2024-02-28 10:24:37 +08:00
xiaojunnuo
5e98f05036 build: prepare to build 2024-02-28 10:23:15 +08:00
xiaojunnuo
292a7ecbe3 chore: 2024-02-28 10:23:15 +08:00
xiaojunnuo
4cea45bd87 build: prepare to build 2024-02-28 10:11:16 +08:00
xiaojunnuo
7f0b075529 chore: 2024-02-28 10:10:47 +08:00
xiaojunnuo
8c7ff5e0e8 chore: 2024-02-28 10:06:43 +08:00
xiaojunnuo
afea5a1623 build: prepare to build 2024-02-28 10:02:13 +08:00
xiaojunnuo
c60dd7f151 build: prepare to build 2024-02-28 09:49:29 +08:00
GitHub Actions Bot
92f9371156 🔱: [client] sync upgrade with 3 commits [trident-sync]
build: publish success
fix: 修复1.20.0版本子表行編輯情況下,删除无效的bug

Closes https://github.com/fast-crud/fast-crud/issues/362
2024-02-27 19:24:07 +00:00
xiaojunnuo
c5714ec6d9 chore: 2024-02-27 21:37:42 +08:00
xiaojunnuo
dd16386317 chore: 2024-02-27 21:35:22 +08:00
xiaojunnuo
7cf1f75eb9 Merge remote-tracking branch 'origin/v2' into v2 2024-02-27 21:33:58 +08:00
xiaojunnuo
cf28a00ccd Merge remote-tracking branch 'origin/v2' into v2 2024-02-27 21:32:39 +08:00
xiaojunnuo
9e48474f11 Merge remote-tracking branch 'origin/v2' into v2 2024-02-27 21:32:38 +08:00
xiaojunnuo
c327c0c995 chore: 2024-02-27 21:31:18 +08:00
xiaojunnuo
bb567da8c6 chore: 2024-02-27 21:31:17 +08:00
GitHub Actions Bot
3e3373b8c7 🔱: [client] sync upgrade with 2 commits [trident-sync]
build: publish success
2024-01-28 19:24:14 +00:00
GitHub Actions Bot
7d45db89bf 🔱: [client] sync upgrade with 2 commits [trident-sync]
perf: 行编辑也支持排他式激活

Closes https://github.com/fast-crud/fast-crud/issues/332
2024-01-25 19:23:52 +00:00
xiaojunnuo
849c145926 fix: 临时修复阿里云domainlist接口返回域名列表不全的问题,后续还需要增加翻页查询 2024-01-03 14:11:21 +08:00
xiaojunnuo
36a773df0b chore: dns 域名查询输出域名列表 2024-01-03 11:45:58 +08:00
GitHub Actions Bot
b2abf1490b 🔱: [client] sync upgrade with 2 commits [trident-sync]
build: publish success
2023-12-15 19:24:10 +00:00
GitHub Actions Bot
02bfbd5019 🔱: [client] sync upgrade with 2 commits [trident-sync]
perf: 增加formWatch示例
2023-12-06 19:24:02 +00:00
GitHub Actions Bot
282f8b4e02 🔱: [client] sync upgrade with 5 commits [trident-sync]
chore:
chore:
chore: editRequest 判断form.id不为空
chore:
2023-11-23 19:24:19 +00:00
GitHub Actions Bot
3393bde820 🔱: [client] sync upgrade with 2 commits [trident-sync]
build: publish success
2023-11-22 19:24:09 +00:00
GitHub Actions Bot
2277c87908 🔱: [client] sync upgrade with 2 commits [trident-sync]
chore:
2023-11-21 19:24:11 +00:00
GitHub Actions Bot
2ea0c48853 🔱: [client] sync upgrade with 8 commits [trident-sync]
build: publish success
chore:
chore:
chore:
chore:
build: publish success
chore:
2023-11-20 19:24:12 +00:00
GitHub Actions Bot
28cbefde04 🔱: [client] sync upgrade with 2 commits [trident-sync]
feat(editable): editable优化重构,分三种模式:free、row、cell
2023-11-19 19:24:08 +00:00
GitHub Actions Bot
4e13843c78 🔱: [client] sync upgrade with 2 commits [trident-sync]
build: publish success
2023-11-08 19:24:13 +00:00
GitHub Actions Bot
a929f8429d 🔱: [client] sync upgrade with 2 commits [trident-sync]
build: publish success
2023-11-07 19:24:00 +00:00
159 changed files with 2456 additions and 168 deletions

View File

@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.20.2](https://github.com/certd/certd/compare/v1.2.1...v1.20.2) (2024-02-28)
### Bug Fixes
* 临时修复阿里云domainlist接口返回域名列表不全的问题后续还需要增加翻页查询 ([849c145](https://github.com/certd/certd/commit/849c145926984762bd9dbec87bd91cd047fc0855))
## [1.2.1](https://github.com/certd/certd/compare/v1.2.0...v1.2.1) (2023-12-12)
### Bug Fixes

View File

@@ -106,6 +106,19 @@ http://your_server_ip:7001
![](https://ai.handsfree.work/images/exchange_wxqroup.png)
加作者好友
<p align="center">
<img height="230" src="./doc/images/me.png">
</p>
## 捐赠
媳妇儿说:“一天到晚搞开源,也不管管老婆孩子!😡😡😡”
拜托各位捐赠支持一下,让媳妇儿开心开心,我也能有更多时间进行开源项目,感谢🙏🙏🙏
<p align="center">
<img height="380" src="./doc/images/donate.png">
</p>
## 七、我的其他项目
* [袖手GPT](https://ai.handsfree.work/) ChatGPT国内可用无需FQ每日免费额度
* [fast-crud](https://gitee.com/fast-crud/fast-crud/) 基于vue3的crud快速开发框架

BIN
doc/images/donate.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

BIN
doc/images/me.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 KiB

View File

@@ -9,5 +9,5 @@
}
},
"npmClient": "pnpm",
"version": "1.2.1"
"version": "1.20.2"
}

View File

@@ -4,9 +4,10 @@
"private": true,
"type": "module",
"devDependencies": {
"@lerna-lite/cli": "^2.4.0",
"@lerna-lite/publish": "^2.4.0",
"@lerna-lite/run": "^2.4.0"
"@lerna-lite/cli": "^3.2.1",
"@lerna-lite/publish": "^3.2.1",
"@lerna-lite/run": "^3.2.1",
"@lerna-lite/version": "^3.2.1"
},
"scripts": {
"start": "lerna bootstrap --hoist",
@@ -18,7 +19,7 @@
"before-build": "cd ./packages/core/acme-client && time /t >build.md && git add ./build.md && git commit -m \"build: prepare to build\"",
"deploy1": "node deploy.js"
},
"license": "MIT",
"license": "AGPL-3.0",
"dependencies": {
"axios": "^1.4.0",
"lodash": "^4.17.21"

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.20.2](https://github.com/publishlab/node-acme-client/compare/v1.2.1...v1.20.2) (2024-02-28)
**Note:** Version bump only for package @certd/acme-client
## [1.2.1](https://github.com/publishlab/node-acme-client/compare/v1.2.0...v1.2.1) (2023-12-12)
**Note:** Version bump only for package @certd/acme-client

View File

@@ -1 +1 @@
23:41
11:14

View File

@@ -3,7 +3,7 @@
"description": "Simple and unopinionated ACME client",
"private": false,
"author": "nmorsman",
"version": "1.2.1",
"version": "1.20.2",
"main": "src/index.js",
"types": "types",
"license": "MIT",

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.20.2](https://github.com/certd/certd/compare/v1.2.1...v1.20.2) (2024-02-28)
**Note:** Version bump only for package @certd/pipeline
## [1.2.1](https://github.com/certd/certd/compare/v1.2.0...v1.2.1) (2023-12-12)
**Note:** Version bump only for package @certd/pipeline

View File

@@ -1,7 +1,7 @@
{
"name": "@certd/pipeline",
"private": false,
"version": "1.2.1",
"version": "1.20.2",
"main": "./src/index.ts",
"module": "./src/index.ts",
"types": "./src/index.ts",
@@ -23,7 +23,7 @@
"qs": "^6.11.2"
},
"devDependencies": {
"@certd/acme-client": "^1.2.1",
"@certd/acme-client": "^1.20.2",
"@rollup/plugin-commonjs": "^23.0.4",
"@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.0.1",

View File

@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.20.2](https://github.com/certd/certd/compare/v1.2.1...v1.20.2) (2024-02-28)
### Bug Fixes
* 临时修复阿里云domainlist接口返回域名列表不全的问题后续还需要增加翻页查询 ([849c145](https://github.com/certd/certd/commit/849c145926984762bd9dbec87bd91cd047fc0855))
## [1.2.1](https://github.com/certd/certd/compare/v1.2.0...v1.2.1) (2023-12-12)
**Note:** Version bump only for package @certd/plugin-aliyun

View File

@@ -1,7 +1,7 @@
{
"name": "@certd/plugin-aliyun",
"private": false,
"version": "1.2.1",
"version": "1.20.2",
"main": "./src/index.ts",
"module": "./src/index.ts",
"types": "./src/index.ts",
@@ -23,10 +23,10 @@
"node-forge": "^0.10.0"
},
"devDependencies": {
"@certd/acme-client": "^1.2.1",
"@certd/pipeline": "^1.2.1",
"@certd/plugin-cert": "^1.2.1",
"@certd/plugin-util": "^1.2.1",
"@certd/acme-client": "^1.20.2",
"@certd/pipeline": "^1.20.2",
"@certd/plugin-cert": "^1.20.2",
"@certd/plugin-util": "^1.20.2",
"@midwayjs/core": "^3.0.0",
"@midwayjs/decorator": "^3.0.0",
"@rollup/plugin-commonjs": "^23.0.4",

View File

@@ -29,6 +29,7 @@ export class AliyunDnsProvider implements IDnsProvider {
async getDomainList() {
const params = {
RegionId: "cn-hangzhou",
PageSize: 100,
};
const requestOption = {
@@ -42,14 +43,16 @@ export class AliyunDnsProvider implements IDnsProvider {
async matchDomain(dnsRecord: string) {
const list = await this.getDomainList();
let domain = null;
const domainList = [];
for (const item of list) {
domainList.push(item.DomainName);
if (_.endsWith(dnsRecord, item.DomainName)) {
domain = item.DomainName;
break;
}
}
if (!domain) {
throw new Error("can not find Domain ," + dnsRecord);
throw new Error(`can not find Domain :${dnsRecord} ,list: ${JSON.stringify(domainList)}`);
}
return domain;
}

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.20.2](https://github.com/certd/certd/compare/v1.2.1...v1.20.2) (2024-02-28)
**Note:** Version bump only for package @certd/plugin-all
## [1.2.1](https://github.com/certd/certd/compare/v1.2.0...v1.2.1) (2023-12-12)
**Note:** Version bump only for package @certd/plugin-all

View File

@@ -1,7 +1,7 @@
{
"name": "@certd/plugin-all",
"private": false,
"version": "1.2.1",
"version": "1.20.2",
"main": "./src/index.ts",
"module": "./src/index.ts",
"types": "./src/index.ts",
@@ -17,12 +17,12 @@
"preview": "vite preview"
},
"devDependencies": {
"@certd/pipeline": "^1.2.1",
"@certd/plugin-aliyun": "^1.2.1",
"@certd/plugin-cert": "^1.2.1",
"@certd/plugin-host": "^1.2.1",
"@certd/plugin-huawei": "^1.2.1",
"@certd/plugin-tencent": "^1.2.1",
"@certd/pipeline": "^1.20.2",
"@certd/plugin-aliyun": "^1.20.2",
"@certd/plugin-cert": "^1.20.2",
"@certd/plugin-host": "^1.20.2",
"@certd/plugin-huawei": "^1.20.2",
"@certd/plugin-tencent": "^1.20.2",
"@rollup/plugin-commonjs": "^23.0.4",
"@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.0.1",

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.20.2](https://github.com/certd/certd/compare/v1.2.1...v1.20.2) (2024-02-28)
**Note:** Version bump only for package @certd/plugin-cert
## [1.2.1](https://github.com/certd/certd/compare/v1.2.0...v1.2.1) (2023-12-12)
**Note:** Version bump only for package @certd/plugin-cert

View File

@@ -1,7 +1,7 @@
{
"name": "@certd/plugin-cert",
"private": false,
"version": "1.2.1",
"version": "1.20.2",
"main": "./src/index.ts",
"module": "./src/index.ts",
"types": "./src/index.ts",
@@ -17,8 +17,8 @@
"preview": "vite preview"
},
"dependencies": {
"@certd/acme-client": "^1.2.1",
"@certd/pipeline": "^1.2.1",
"@certd/acme-client": "^1.20.2",
"@certd/pipeline": "^1.20.2",
"jszip": "^3.10.1",
"node-forge": "^0.10.0"
},

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.20.2](https://github.com/certd/certd/compare/v1.2.1...v1.20.2) (2024-02-28)
**Note:** Version bump only for package @certd/plugin-host
## [1.2.1](https://github.com/certd/certd/compare/v1.2.0...v1.2.1) (2023-12-12)
**Note:** Version bump only for package @certd/plugin-host

View File

@@ -1,7 +1,7 @@
{
"name": "@certd/plugin-host",
"private": false,
"version": "1.2.1",
"version": "1.20.2",
"main": "./src/index.ts",
"module": "./src/index.ts",
"types": "./src/index.ts",
@@ -17,8 +17,8 @@
"preview": "vite preview"
},
"dependencies": {
"@certd/pipeline": "^1.2.1",
"@certd/plugin-cert": "^1.2.1",
"@certd/pipeline": "^1.20.2",
"@certd/plugin-cert": "^1.20.2",
"ssh2": "^0.8.9"
},
"devDependencies": {

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.20.2](https://github.com/certd/certd/compare/v1.2.1...v1.20.2) (2024-02-28)
**Note:** Version bump only for package @certd/plugin-huawei
## [1.2.1](https://github.com/certd/certd/compare/v1.2.0...v1.2.1) (2023-12-12)
**Note:** Version bump only for package @certd/plugin-huawei

View File

@@ -1,7 +1,7 @@
{
"name": "@certd/plugin-huawei",
"private": false,
"version": "1.2.1",
"version": "1.20.2",
"main": "./src/index.ts",
"module": "./src/index.ts",
"types": "./src/index.ts",
@@ -17,10 +17,10 @@
"preview": "vite preview"
},
"dependencies": {
"@certd/acme-client": "^1.2.1",
"@certd/pipeline": "^1.2.1",
"@certd/plugin-cert": "^1.2.1",
"@certd/plugin-util": "^1.2.1",
"@certd/acme-client": "^1.20.2",
"@certd/pipeline": "^1.20.2",
"@certd/plugin-cert": "^1.20.2",
"@certd/plugin-util": "^1.20.2",
"axios": "^0.27.2",
"dayjs": "^1.11.6",
"lodash": "^4.17.21",

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.20.2](https://github.com/certd/certd/compare/v1.2.1...v1.20.2) (2024-02-28)
**Note:** Version bump only for package @certd/plugin-tencent
## [1.2.1](https://github.com/certd/certd/compare/v1.2.0...v1.2.1) (2023-12-12)
**Note:** Version bump only for package @certd/plugin-tencent

View File

@@ -1,7 +1,7 @@
{
"name": "@certd/plugin-tencent",
"private": false,
"version": "1.2.1",
"version": "1.20.2",
"main": "./src/index.ts",
"module": "./src/index.ts",
"types": "./src/index.ts",
@@ -17,9 +17,9 @@
"preview": "vite preview"
},
"dependencies": {
"@certd/pipeline": "^1.2.1",
"@certd/plugin-cert": "^1.2.1",
"@certd/plugin-util": "^1.2.1",
"@certd/pipeline": "^1.20.2",
"@certd/plugin-cert": "^1.20.2",
"@certd/plugin-util": "^1.20.2",
"tencentcloud-sdk-nodejs": "^4.0.44"
},
"devDependencies": {

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.20.2](https://github.com/certd/certd/compare/v1.2.1...v1.20.2) (2024-02-28)
**Note:** Version bump only for package @certd/plugin-util
## [1.2.1](https://github.com/certd/certd/compare/v1.2.0...v1.2.1) (2023-12-12)
**Note:** Version bump only for package @certd/plugin-util

View File

@@ -1,7 +1,7 @@
{
"name": "@certd/plugin-util",
"private": false,
"version": "1.2.1",
"version": "1.20.2",
"main": "./src/index.ts",
"module": "./src/index.ts",
"types": "./src/index.ts",
@@ -21,7 +21,7 @@
"shelljs": "^0.8.5"
},
"devDependencies": {
"@certd/pipeline": "^1.2.1",
"@certd/pipeline": "^1.20.2",
"@rollup/plugin-commonjs": "^23.0.4",
"@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.0.1",

View File

@@ -20,6 +20,7 @@ module.exports = {
rules: {
//"max-len": [0, 200, 2, { ignoreUrls: true }],
"@typescript-eslint/no-unused-vars": "off",
"no-unused-vars": "off",
"@typescript-eslint/ban-ts-ignore": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/ban-types": "off",

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.20.2](https://github.com/certd/certd/compare/v1.2.1...v1.20.2) (2024-02-28)
**Note:** Version bump only for package @certd/ui-client
## [1.2.1](https://github.com/certd/certd/compare/v1.2.0...v1.2.1) (2023-12-12)
**Note:** Version bump only for package @certd/ui-client

View File

@@ -1,6 +1,6 @@
{
"name": "@certd/ui-client",
"version": "1.2.1",
"version": "1.20.2",
"private": true,
"scripts": {
"dev": "vite",
@@ -20,18 +20,19 @@
"afterPubPush": "git add . && git commit -m \"build: publish success\" && git push"
},
"author": "Greper",
"license": "MIT",
"license": "AGPL-3.0",
"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",
"@fast-crud/fast-crud": "^1.18.3",
"@fast-crud/fast-extends": "^1.18.3",
"@fast-crud/ui-antdv": "^1.18.3",
"@fast-crud/ui-interface": "^1.18.3",
"@fast-crud/fast-crud": "^1.20.1",
"@fast-crud/fast-extends": "^1.20.1",
"@fast-crud/ui-antdv": "^1.20.1",
"@fast-crud/ui-interface": "^1.20.1",
"@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",
@@ -61,7 +62,7 @@
"vuedraggable": "^2.24.3"
},
"devDependencies": {
"@certd/pipeline": "^1.2.1",
"@certd/pipeline": "^1.20.2",
"@rollup/plugin-commonjs": "^25.0.3",
"@rollup/plugin-node-resolve": "^15.1.0",
"@types/chai": "^4.3.5",

View File

@@ -1,7 +1,11 @@
import _ from "lodash-es";
function copyList(originList: any, newList: any, options: any, parentId?: any) {
for (const item of originList) {
const newItem = { ...item, parentId };
const newItem: any = _.cloneDeep(item);
if(parentId!= null && newItem.parentId == null){
newItem.parentId = parentId;
}
newItem.id = ++options.idGenerator;
newList.push(newItem);
if (item.children != null) {
@@ -214,7 +218,7 @@ const mockUtil: any = {
return {
code: 0,
msg: "success",
data: req.body.id
data: _.cloneDeep(req.body)
};
}
},
@@ -293,6 +297,62 @@ const mockUtil: any = {
data: list
};
}
},
{
path: "/mock/" + name + "/cellUpdate",
method: "post",
handle(req: any): any {
console.log("req", req);
let item = findById(req.body.id, list);
if (item) {
_.mergeWith(item, { [req.body.key]: req.body.value }, (objValue, srcValue) => {
if (srcValue == null) {
return;
}
// 如果被合并对象为数组,则直接被覆盖对象覆盖,只要覆盖对象不为空
if (_.isArray(objValue)) {
return srcValue;
}
});
} else {
item = {
id: ++options.idGenerator,
[req.body.key]: req.body.value
};
list.unshift(item);
}
return {
code: 0,
msg: "success",
data: item
};
}
},
{
path: "/mock/" + name + "/columnUpdate",
method: "post",
handle(req: any): any {
for (const item of req.body) {
const item2 = findById(item.id, list);
if (item2) {
_.mergeWith(item2, item, (objValue, srcValue) => {
if (srcValue == null) {
return;
}
// 如果被合并对象为数组,则直接被覆盖对象覆盖,只要覆盖对象不为空
if (_.isArray(objValue)) {
return srcValue;
}
});
}
}
return {
code: 0,
msg: "success",
data: null
};
}
}
];
}

View File

@@ -448,6 +448,12 @@ export const crudResources = [
name: "FormView",
path: "/crud/form/view",
component: "/crud/form/view/index.vue"
},
{
title: "表单Watch",
name: "FormWatch",
path: "/crud/form/watch",
component: "/crud/form/watch/index.vue"
}
]
},
@@ -537,18 +543,6 @@ export const crudResources = [
path: "/crud/feature/height",
component: "/crud/feature/height/index.vue"
},
{
title: "可编辑",
name: "FeatureEditable",
path: "/crud/feature/editable",
component: "/crud/feature/editable/index.vue"
},
{
title: "行编辑",
name: "FeatureEditableRow",
path: "/crud/feature/editable-row",
component: "/crud/feature/editable-row/index.vue"
},
{
title: "查询框",
name: "FeatureSearch",
@@ -623,6 +617,47 @@ export const crudResources = [
}
]
},
{
title: "可编辑",
name: "Editable",
path: "/crud/editable",
redirect: "/crud/editable/free",
meta: {
icon: "ion:create-outline"
},
children: [
{
title: "自由编辑",
name: "EditableFree",
path: "/crud/editable/free",
component: "/crud/editable/free/index.vue"
},
{
title: "行编辑",
name: "EditableRow",
path: "/crud/editable/row",
component: "/crud/editable/row/index.vue"
},
{
title: "单元格编辑",
name: "EditableCell",
path: "/crud/editable/cell",
component: "/crud/editable/cell/index.vue"
},
{
title: "子表格编辑",
name: "EditableVModel",
path: "/crud/editable/vmodel",
component: "/crud/editable/vmodel/index.vue"
},
{
title: "子CRUD",
name: "EditableSubCrud",
path: "/crud/editable/sub-crud",
component: "/crud/editable/sub-crud/index.vue"
}
]
},
{
title: "插槽",
name: "Slots",

View File

@@ -6,7 +6,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -13,7 +13,9 @@ export default async function (props: CreateCrudOptionsProps): Promise<CreateCru
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -6,7 +6,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -5,7 +5,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -37,7 +37,9 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
};
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
await api.UpdateObj(form);
//更新本地数据
const tableData = localDataRef.value;

View File

@@ -6,7 +6,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -8,7 +8,9 @@ export default function ({ crudExpose, context: { asideTableRef } }: CreateCrudO
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -6,7 +6,9 @@ export default function ({ crudExpose, context: { props, ctx } }: CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -6,7 +6,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -7,7 +7,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -7,7 +7,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -10,7 +10,9 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -9,7 +9,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -5,7 +5,9 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -7,7 +7,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -7,7 +7,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -7,7 +7,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -6,7 +6,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -7,7 +7,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -7,7 +7,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -7,7 +7,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -6,7 +6,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -8,7 +8,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -7,7 +7,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -5,7 +5,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -5,7 +5,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -6,7 +6,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -5,7 +5,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -46,7 +46,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -5,7 +5,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -7,7 +7,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -7,7 +7,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -5,7 +5,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -6,7 +6,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -6,7 +6,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -6,7 +6,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -7,7 +7,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -5,7 +5,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -7,7 +7,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -8,7 +8,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -5,7 +5,9 @@ export default function createCrudOptions({}: CreateCrudOptionsProps): CreateCru
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -7,7 +7,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -6,7 +6,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -7,7 +7,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -5,7 +5,9 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
if (form.id == null) {
form.id = row.id;
}
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {

View File

@@ -0,0 +1,66 @@
// @ts-ignore
import { requestForMock } from "/src/api/service";
const request = requestForMock;
const apiPrefix = "/mock/EditableCell";
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 }
});
}
export function UpdateCell(id: number, key: string, value: any) {
return request({
url: apiPrefix + "/cellUpdate",
method: "post",
data: { id, key, value }
});
}
export function UpdateColumn(data) {
return request({
url: apiPrefix + "/columnUpdate",
method: "post",
data
});
}

View File

@@ -0,0 +1,210 @@
import * as api from "./api";
import { dict, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, UserPageQuery, UserPageRes, EditReq, DelReq, AddReq } from "@fast-crud/fast-crud";
import { computed, reactive, ref } from "vue";
import _ from "lodash-es";
import { EditableEachCellsOpts } from "@fast-crud/fast-crud";
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const { crudBinding } = crudExpose;
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 radioDictRef = dict({
url: "/mock/dicts/OpenStatusEnum?single"
});
const radioColumnValue = ref("");
function columnUpdate(event: Event) {
//批量设置值
// _.forEach(crudBinding.value?.data, (item) => {
// item.radio = event.target.value;
// });
crudExpose.editable.eachCells((opts: EditableEachCellsOpts) => {
const { key, cell, rowData } = opts;
if (key === "radio") {
if (cell.isEditing) {
//@ts-ignore
rowData.radio = event.target.value;
}
}
});
}
const radioColumnEditor = reactive({
editing: false,
loading: false,
onSubmit: async () => {
console.log("onSubmit");
radioColumnEditor.loading = true;
try {
const data: any[] = [];
for (const row of crudBinding.value.data) {
data.push({ id: row.id, radio: row.radio });
}
await api.UpdateColumn(data);
crudExpose.editable.persist();
radioColumnEditor.editing = false;
} finally {
radioColumnEditor.loading = false;
}
},
onCancel: () => {
console.log("cancel");
crudExpose.editable.cancel();
radioColumnEditor.editing = false;
},
"onUpdate:editing": (value: boolean) => {
radioColumnEditor.editing = value;
if (value === true) {
crudExpose.editable.activeCols({ cols: ["radio"], showAction: false });
}
},
vSlots: {
edit: () => {
return <fs-dict-radio dict={radioDictRef} v-model:value={radioColumnValue.value} onChange={columnUpdate}></fs-dict-radio>;
}
}
});
return {
crudOptions: {
request: {
pageRequest,
addRequest,
editRequest,
delRequest
},
actionbar: {
buttons: {
// add: {
// show: computed(() => {
// if (crudBinding.value) {
// return !crudBinding.value?.table.editable.enabled;
// }
// return false;
// })
// },
// addRow: {
// show: computed(() => {
// if (crudBinding.value) {
// return crudBinding.value?.table.editable.enabled;
// }
// return false;
// })
// }
}
},
table: {
editable: {
mode: "cell",
exclusive: true,
//排他式激活效果,将其他行的编辑状态触发保存
exclusiveEffect: "save",
async updateCell(opts) {
const { row, key, value } = opts;
//如果是添加,需要返回{[rowKey]:xxx},比如:{id:2}
return await api.UpdateCell(row.id, key, value);
}
},
slots: {
//编辑列
headerCell({ column }: any) {
if (column.key === "radio") {
return (
<div style={{ width: "100%" }} class={"flex "}>
<fs-editable {...radioColumnEditor} v-slots={radioColumnEditor.vSlots}>
{column.title} <span style={{ color: "red" }}>()</span>
</fs-editable>
</div>
);
}
}
}
},
columns: {
id: {
title: "ID",
type: "number",
form: {
show: false
},
column: { width: 80, align: "center" }
},
disable: {
title: "禁止编辑",
type: "text",
column: {
editable: {
disabled: true //也可以配置为方法,根据条件禁用或启用编辑
// disabled: ({ column, index, row }) => {
// return index % 2 === 0;
// }
}
}
},
radio: {
title: "状态",
search: { show: true },
type: "dict-radio",
dict: radioDictRef,
column: {
width: 300
}
},
name: {
title: "姓名",
type: "text",
form: {
rules: [
{ required: true, message: "请输入姓名" },
{
type: "string",
min: 2,
max: 10,
message: "长度在 2 到 10 个字符"
}
]
}
},
address: {
title: "地址",
children: {
province: {
title: "省份",
search: { show: true },
type: "text"
},
city: {
title: "城市",
search: { show: true },
type: "dict-select",
dict: dict({
value: "id",
label: "text",
data: [
{ id: "sz", text: "深圳", color: "success" },
{ id: "gz", text: "广州", color: "primary" },
{ id: "bj", text: "北京" },
{ id: "wh", text: "武汉" },
{ id: "sh", text: "上海" }
]
})
}
}
}
}
}
};
}

View File

@@ -0,0 +1,90 @@
<template>
<fs-page>
<template #header>
<div class="title">
单元格编辑
<span class="sub">单元格修改确认后直接提交到后台</span>
</div>
<div class="more"></div>
</template>
<fs-crud ref="crudRef" v-bind="crudBinding">
<template #actionbar-right>
<!-- <fs-button class="ml-1" @click="addRow">添加行</fs-button>-->
<a-radio-group v-model:value="crudBinding.table.editable.enabled" class="ml-5">
<a-radio-button :value="true">启用编辑</a-radio-button>
<a-radio-button :value="false">退出编辑</a-radio-button>
</a-radio-group>
<fs-label label="排他式激活" class="ml-5" title="激活某个cell时其他已激活的自动关闭永远只有一个cell被激活">
<a-switch v-model:checked="crudBinding.table.editable.exclusive" class="ml-5"> </a-switch>
</fs-label>
<fs-label label="排他式激活效果" class="ml-5" title="排他式激活时,将未关闭的自动保存还是取消">
<a-radio-group v-model:value="crudBinding.table.editable.exclusiveEffect" class="ml-5">
<a-radio-button value="cancel">自动取消</a-radio-button>
<a-radio-button value="save">自动保存</a-radio-button>
</a-radio-group>
</fs-label>
<template v-if="crudBinding.table.editable.enabled">
<fs-button class="ml-5" @click="active">激活全部编辑</fs-button>
<fs-button class="ml-5" @click="cancel">取消/恢复原状</fs-button>
<fs-button class="ml-5" @click="log">log</fs-button>
</template>
</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 } from "ant-design-vue";
export default defineComponent({
name: "EditableCell",
setup() {
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions });
// 页面打开后获取列表数据
onMounted(() => {
crudExpose.doRefresh();
//默认启用编辑
crudExpose.editable.enable({});
});
return {
crudBinding,
crudRef,
active() {
crudExpose.editable.active();
},
inactive() {
crudExpose.editable.inactive();
},
save() {
crudExpose.getTableRef().editable.submit(({ changed, removed, setData }: any) => {
console.log("changed", changed);
console.log("removed", removed);
console.log("table data:", crudBinding.value.data, crudExpose.getTableData());
// setData({ 0: {id:1} }); //设置data
message.success("保存,修改行:" + JSON.stringify(changed) + ";删除行:" + JSON.stringify(removed));
});
},
log() {
console.log("table data:", crudBinding.value.data, crudExpose.getTableData());
},
cancel() {
crudExpose.editable.resume();
},
addRow() {
crudExpose.editable.addRow();
},
editCol() {
crudExpose.editable.activeCols({ cols: ["radio"] });
}
};
}
});
</script>

View File

@@ -0,0 +1,25 @@
// @ts-ignore
import mockUtil from "/src/mock/base";
const options: any = {
name: "EditableCell",
idGenerator: 0
};
const list = [
{
radio: "1",
children: [
{
radio: "2"
}
]
},
{
radio: "2"
},
{
radio: "0"
}
];
options.list = list;
const mock = mockUtil.buildMock(options);
export default mock;

View File

@@ -0,0 +1,50 @@
import { requestForMock } from "/src/api/service";
const request = requestForMock;
const apiPrefix = "/mock/EditableFree";
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,117 @@
import * as api from "./api";
import { dict, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, UserPageQuery, UserPageRes, EditReq, DelReq, AddReq } from "@fast-crud/fast-crud";
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const { crudBinding } = crudExpose;
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
},
actionbar: {
buttons: {
add: {
show: false
},
addRow: {
show: true
}
}
},
table: {
editable: {
mode: "free"
}
},
pagination: {
pageSize: 5,
pageSizes: [5, 10, 20, 50, 100]
},
columns: {
id: {
title: "ID",
type: "number",
form: {
show: false
},
column: { width: 80, align: "center" }
},
disable: {
title: "禁止编辑",
type: "text",
column: {
editable: {
disabled: true //也可以配置为方法,根据条件禁用或启用编辑
// disabled: ({ column, index, row }) => {
// return index % 2 === 0;
// }
}
}
},
radio: {
title: "状态",
search: { show: true },
type: "dict-radio",
dict: dict({
url: "/mock/dicts/OpenStatusEnum?single"
})
},
name: {
title: "姓名",
type: "text",
form: {
rules: [
{ required: true, message: "请输入姓名" },
{ min: 2, max: 10, message: "长度在 2 到 10 个字符" }
]
}
},
address: {
title: "地址",
children: {
province: {
title: "省份",
search: { show: true },
type: "text"
},
city: {
title: "城市",
search: { show: true },
type: "dict-select",
dict: dict({
value: "id",
label: "text",
data: [
{ id: "sz", text: "深圳", color: "success" },
{ id: "gz", text: "广州", color: "primary" },
{ id: "bj", text: "北京" },
{ id: "wh", text: "武汉" },
{ id: "sh", text: "上海" }
]
})
}
}
}
}
}
};
}

View File

@@ -0,0 +1,76 @@
<template>
<fs-page>
<template #header>
<div class="title">可编辑</div>
<div class="more"><a target="_blank" href="http://fast-crud.docmirror.cn/api/expose.html">文档</a></div>
</template>
<fs-crud ref="crudRef" v-bind="crudBinding">
<template #actionbar-right>
<!-- <fs-button class="ml-1" @click="addRow">添加行</fs-button>-->
<a-radio-group v-model:value="crudBinding.table.editable.enabled" class="ml-5">
<a-radio-button :value="true">启用编辑</a-radio-button>
<a-radio-button :value="false">退出编辑</a-radio-button>
</a-radio-group>
<!-- <a-radio-group class="ml-1" v-model="crudBinding.table.editable.mode">-->
<!-- <a-radio-button label="free">自由模式</a-radio-button>-->
<!-- <a-radio-button label="row">行编辑模式</a-radio-button>-->
<!-- </a-radio-group>-->
<template v-if="crudBinding.table.editable.enabled">
<fs-button class="ml-5" @click="save">保存</fs-button>
<fs-button class="ml-5" @click="log">log</fs-button>
</template>
</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 } from "ant-design-vue";
export default defineComponent({
name: "EditableFree",
setup() {
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions });
// 页面打开后获取列表数据
onMounted(() => {
crudExpose.doRefresh();
crudExpose.editable.enable({ mode: "free", activeDefault: true });
});
return {
crudBinding,
crudRef,
active() {
crudExpose.editable.active();
},
inactive() {
crudExpose.editable.inactive();
},
async save() {
const res = await crudExpose.editable.validate();
if (res !== true) {
console.error("validate error:", res);
return;
}
message.success("保存,修改行:" + JSON.stringify(crudBinding.value.data));
},
log() {
console.log("table data:", crudBinding.value.data, crudExpose.getTableData());
},
cancel() {
crudExpose.editable.resume();
},
addRow() {
crudExpose.editable.addRow();
},
editCol() {
crudExpose.editable.activeCols({ cols: ["radio"] });
}
};
}
});
</script>

View File

@@ -0,0 +1,24 @@
import mockUtil from "/src/mock/base";
const options: any = {
name: "EditableFree",
idGenerator: 0
};
const list = [
{
radio: "1",
children: [
{
radio: "2"
}
]
},
{
radio: "2"
},
{
radio: "0"
}
];
options.list = list;
const mock = mockUtil.buildMock(options);
export default mock;

View File

@@ -0,0 +1,50 @@
import { requestForMock } from "/src/api/service";
const request = requestForMock;
const apiPrefix = "/mock/EditableRow";
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,144 @@
import * as api from "./api";
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
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
},
//将 addRow 按钮启用
actionbar: { buttons: { add: { show: false }, addRow: { show: true } } },
table: {
editable: {
enabled: true,
mode: "row"
}
},
columns: {
id: {
title: "ID",
type: "number",
form: {
show: false
},
column: { width: 80, align: "center" }
},
disable: {
title: "禁止编辑",
type: "text",
column: {
editable: {
disabled: true //也可以配置为方法,根据条件禁用或启用编辑
// disabled: ({ column, index, row }) => {
// return index % 2 === 0;
// }
}
}
},
radio: {
title: "状态",
search: { show: true },
type: "dict-radio",
dict: dict({
url: "/mock/dicts/OpenStatusEnum?single"
}),
column: {
width: 300
},
form: {
rules: {
async asyncValidator(context) {
console.log("context", context);
return true;
},
message: "远程校验测试"
}
}
},
target: {
title: "根据状态动态显隐",
search: { show: true },
type: "text",
form: {
conditionalRender: {
match: ({ form }) => {
return form.radio === "2";
},
render: ({ form }) => {
return <div></div>;
}
},
show: compute(({ form }) => {
return form.radio !== "0";
})
}
},
"user.name": {
title: "姓名",
type: "text",
form: {
key: ["user", "name"],
rules: [
{ required: true, message: "请输入姓名" },
{
type: "string",
min: 2,
max: 10,
message: "长度在 2 到 10 个字符"
}
]
}
},
address: {
title: "地址",
children: {
province: {
title: "省份",
search: { show: true },
type: "text",
form: {
rules: [{ required: true, message: "请输入省份" }]
}
},
city: {
title: "城市",
search: { show: true },
type: "dict-select",
dict: dict({
value: "id",
label: "text",
data: [
{ id: "sz", text: "深圳", color: "success" },
{ id: "gz", text: "广州", color: "primary" },
{ id: "bj", text: "北京" },
{ id: "wh", text: "武汉" },
{ id: "sh", text: "上海" }
]
})
}
}
}
}
}
};
}

View File

@@ -0,0 +1,43 @@
<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/expose.html">文档</a></div>
</template>
<fs-crud ref="crudRef" v-bind="crudBinding">
<template #actionbar-right>
<fs-button class="ml-5" @click="log">log</fs-button>
</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";
export default defineComponent({
name: "EditableRow",
setup() {
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions });
// 页面打开后获取列表数据
onMounted(() => {
crudExpose.doRefresh();
crudExpose.editable.enable();
});
return {
crudBinding,
crudRef,
log() {
console.log("table data:", crudBinding.value.data, crudExpose.getTableData());
}
};
}
});
</script>

View File

@@ -0,0 +1,24 @@
import mockUtil from "/src/mock/base";
const options: any = {
name: "EditableRow",
idGenerator: 0
};
const list = [
{
radio: "1",
children: [
{
radio: "2"
}
]
},
{
radio: "2"
},
{
radio: "0"
}
];
options.list = list;
const mock = mockUtil.buildMock(options);
export default mock;

View File

@@ -0,0 +1,50 @@
import { requestForMock } from "/src/api/service";
const request = requestForMock;
const apiPrefix = "/mock/EditableSubCrud";
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,92 @@
import * as api from "./api";
import { dict, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, UserPageQuery, UserPageRes, EditReq, DelReq, AddReq } from "@fast-crud/fast-crud";
import EditableRowSub from "/@/views/crud/editable/sub-crud/row/index.vue";
export default function (props: CreateCrudOptionsProps): CreateCrudOptionsRet {
const { crudBinding,crudRef } = props.crudExpose;
const { crudExpose } = props;
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
},
form: {
wrapper: {
width: "80%"
},
},
columns: {
id: {
title: "ID",
type: "number",
form: {
show: false
},
column: { width: 80, align: "center" }
},
radio: {
title: "状态",
search: { show: true },
type: "dict-radio",
dict: dict({
url: "/mock/dicts/OpenStatusEnum?single"
}),
form:{
rules: [{ required: true, message: "请选择状态" }]
}
},
subTable: {
title: "子表格",
type: "text",
form: {
component: {
name: EditableRowSub,
id:compute(({form})=>{
return form.id
}),
on:{
async saveMain({form}){
//保存主表
const formRef = crudExpose.getFormRef()
const ret = await formRef.submit()
//将form改为编辑模式
let formWrapperRef = crudExpose.getFormWrapperRef();
formWrapperRef.setFormData(ret.res)
crudRef.value.formWrapperRef.formOptions.mode = "edit"
crudRef.value.formWrapperRef.title="编辑"
}
}
},
col: {
span: 24
},
},
column: {
formatter: ({ row }) => {
return "点击编辑查看子表";
}
}
}
}
}
};
}

View File

@@ -0,0 +1,43 @@
<template>
<fs-page>
<template #header>
<div class="title">
子表crud
<span class="sub"> 外键关联子表子表有自己的crud接口 </span>
</div>
<div class="more"><a target="_blank" href="http://fast-crud.docmirror.cn/api/crud-options/table.html#editable">文档</a></div>
</template>
<fs-crud ref="crudRef" v-bind="crudBinding">
<template #actionbar-right>
<fs-button class="ml-5" @click="log">log</fs-button>
</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 } from "ant-design-vue";
export default defineComponent({
name: "EditableSubCrud",
setup() {
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions });
// 页面打开后获取列表数据
onMounted(() => {
crudExpose.doRefresh();
});
return {
crudBinding,
crudRef,
log() {
console.log("table data:", crudBinding.value.data);
}
};
}
});
</script>

View File

@@ -0,0 +1,20 @@
import mockUtil from "/src/mock/base";
const options: any = {
name: "EditableSubCrud",
idGenerator: 0
};
const list = [
{
radio: "1",
subTable: [{ id: 0, name: "王小虎" }]
},
{
radio: "2"
},
{
radio: "0"
}
];
options.list = list;
const mock = mockUtil.buildMock(options);
export default mock;

View File

@@ -0,0 +1,50 @@
import { requestForMock } from "/src/api/service";
const request = requestForMock;
const apiPrefix = "/mock/EditableSubCrudTarget";
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,121 @@
import {
AddReq,
CreateCrudOptionsProps,
CreateCrudOptionsRet, DelReq,
dict,
EditReq,
UserPageQuery,
UserPageRes
} from "@fast-crud/fast-crud";
import * as api from "./api";
export default function ({ crudExpose,context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const { crudBinding } = crudExpose;
const {parentIdRef} = context
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
},
actionbar: {
buttons: {
add: {
show: false
},
addRow: {
show: true
}
}
},
search: {
show: false,
initialForm:{
parentId:parentIdRef
}
},
toolbar: {
buttons: {
refresh: {
show: false
}
}
},
table: {
editable: {
enabled: true,
mode: "row",
activeDefault:false,
}
},
// pagination: { show: false, pageSize: 9999999 },
columns: {
id: {
title: "ID",
type: "number",
form: {
show: false
},
column: { width: 80, align: "center" }
},
radio: {
title: "状态",
search: { show: true },
type: "dict-radio",
dict: dict({
url: "/mock/dicts/OpenStatusEnum?single"
}),
form:{
value:'1',
}
},
name: {
title: "姓名",
type: "text",
form: {
rules: [
{ required: true, message: "请输入姓名" },
{ min: 2, max: 10, message: "长度在 2 到 10 个字符" }
]
}
},
parentId:{
title: "父Id",
type: "number",
search:{
show:true,
},
form:{
value:parentIdRef,
component:{
disabled:true
}
}
},
createdAt: {
column: {
show: false
}
}
}
}
};
}

View File

@@ -0,0 +1,104 @@
<template>
<div class="sub-table">
<div v-if="id>0" style="height: 500px; position: relative">
<fs-crud ref="crudRef" v-bind="crudBinding"> </fs-crud>
</div>
<div v-else>
<fs-button @click="saveMain">保存</fs-button> 保存后即可编辑子表
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, onMounted, watch,ref } from "vue";
import createCrudOptions from "./crud";
import { useFs, useUi } from "@fast-crud/fast-crud";
export default defineComponent({
name: "EditableSubCrudTarget",
props: {
/**
* 主表id
*/
id:{
type:Number,
default:0
},
disabled:{
type:Boolean,
default:false
},
readonly:{
type:Boolean,
default:false
},
},
emits: ["save-main"],
setup(props, ctx) {
const parentIdRef = ref(props.id)
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions ,context:{parentIdRef}});
const { ui } = useUi();
let formItemContext = ui.formItem.injectFormItemContext();
function emit(data:any) {
console.log("emit:", data);
formItemContext.onBlur();
formItemContext.onChange();
}
function saveMain(){
ctx.emit("save-main",true)
}
watch(
() => {
return props.id;
},
(value: any) => {
if(value>0){
crudExpose.setSearchFormData({
form:{parentId:value},
mergeForm:true,
triggerSearch:true
})
parentIdRef.value = value
}
},
{
immediate: true
}
);
// 页面打开后获取列表数据
onMounted(() => {
crudExpose.doRefresh();
watch(()=>{
return props.disabled || props.readonly
},(value)=>{
if(value){
crudBinding.value.table.editable.readonly=true
crudBinding.value.actionbar.buttons.addRow.show=false
crudBinding.value.rowHandle.show=false
}else{
crudBinding.value.table.editable.readonly=false
crudBinding.value.actionbar.buttons.addRow.show=true
crudBinding.value.rowHandle.show=true
}
},{
immediate:true
})
});
return {
crudBinding,
crudRef,
saveMain
};
}
});
</script>

View File

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

View File

@@ -0,0 +1,50 @@
import { requestForMock } from "/src/api/service";
const request = requestForMock;
const apiPrefix = "/mock/EditableVModel";
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,81 @@
import * as api from "./api";
import { dict, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, UserPageQuery, UserPageRes, EditReq, DelReq, AddReq } from "@fast-crud/fast-crud";
import EditableFreeSub from "./free/index.vue";
export default function (props: CreateCrudOptionsProps): CreateCrudOptionsRet {
const { crudBinding } = props.crudExpose;
const { crudExpose } = props;
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
},
form: {
wrapper: {
width: "80%"
},
async beforeSubmit() {
const validate = await crudExpose.getFormComponentRef("subTable")?.validate();
if (validate !== true) {
return false;
}
}
},
columns: {
id: {
title: "ID",
type: "number",
form: {
show: false
},
column: { width: 80, align: "center" }
},
radio: {
title: "状态",
search: { show: true },
type: "dict-radio",
dict: dict({
url: "/mock/dicts/OpenStatusEnum?single"
})
},
subTable: {
title: "子表格",
type: "text",
form: {
component: {
name: EditableFreeSub,
vModel: "modelValue"
},
col: {
span: 24
}
},
column: {
formatter: ({ row }) => {
return row.subTable?.length + "条数据";
}
}
}
}
}
};
}

View File

@@ -0,0 +1,75 @@
import { CreateCrudOptionsProps, CreateCrudOptionsRet, dict } from "@fast-crud/fast-crud";
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const { crudBinding } = crudExpose;
return {
crudOptions: {
actionbar: {
buttons: {
add: {
show: false
},
addRow: {
show: true
}
}
},
search: {
show: false
},
toolbar: {
buttons: {
refresh: {
show: false
}
}
},
mode: {
name: "local",
isMergeWhenUpdate: true,
isAppendWhenAdd: true
},
table: {
editable: {
enabled: true,
mode: "free"
}
},
pagination: { show: false, pageSize: 9999999 },
columns: {
id: {
title: "ID",
type: "number",
form: {
show: false
},
column: { width: 80, align: "center" }
},
radio: {
title: "状态",
search: { show: true },
type: "dict-radio",
dict: dict({
url: "/mock/dicts/OpenStatusEnum?single"
})
},
name: {
title: "姓名",
type: "text",
form: {
rules: [
{ required: true, message: "请输入姓名" },
{ min: 2, max: 10, message: "长度在 2 到 10 个字符" }
]
}
},
createdAt: {
column: {
show: false
}
}
}
}
};
}

View File

@@ -0,0 +1,70 @@
<template>
<div style="height: 500px; position: relative">
<fs-crud ref="crudRef" v-bind="crudBinding"> </fs-crud>
</div>
</template>
<script lang="ts">
import { defineComponent, onMounted, watch } from "vue";
import createCrudOptions from "./crud";
import { useFs, useUi } from "@fast-crud/fast-crud";
import { message } from "ant-design-vue";
export default defineComponent({
name: "EditableFreeSub",
props: {
modelValue: {
type: Array,
default() {
return undefined;
}
}
},
emits: ["update:modelValue"],
setup(props, ctx) {
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions });
const { ui } = useUi();
let formItemContext = ui.formItem.injectFormItemContext();
function emit(data) {
console.log("emit:", data);
ctx.emit("update:modelValue", data);
formItemContext.onBlur();
formItemContext.onChange();
}
// 页面打开后获取列表数据
onMounted(() => {
// crudExpose.doRefresh();
watch(
() => {
return props.modelValue;
},
(value: any) => {
if (value != null) {
crudBinding.value.data = value;
} else {
crudBinding.value.data = [];
emit(crudBinding.value.data);
}
},
{
immediate: true
}
);
crudExpose.editable.enable({ mode: "free", activeDefault: true });
});
async function validate() {
//校验在上级表单的beforeSubmit中调用
return await crudExpose.getTableRef().editable.validate();
}
return {
crudBinding,
crudRef,
validate
};
}
});
</script>

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