cabloy 5.1.67 → 5.1.69

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/package.json +1 -1
  3. package/vona/packages-cli/cli/package.json +1 -1
  4. package/vona/packages-cli/cli-set-api/package.json +1 -1
  5. package/vona/packages-utils/zod-query/package.json +1 -1
  6. package/vona/packages-utils/zod-query/src/lib/query.ts +4 -0
  7. package/vona/packages-vona/vona/package.json +1 -1
  8. package/vona/packages-vona/vona-core/package.json +1 -1
  9. package/vona/packages-vona/vona-mock/package.json +1 -1
  10. package/vona/pnpm-lock.yaml +762 -840
  11. package/vona/pnpm-workspace.yaml +1 -1
  12. package/vona/src/suite/a-training/modules/training-record/src/bean/meta.version.ts +4 -1
  13. package/vona/src/suite/a-training/modules/training-record/src/config/locale/en-us.ts +5 -2
  14. package/vona/src/suite/a-training/modules/training-record/src/config/locale/zh-cn.ts +5 -2
  15. package/vona/src/suite/a-training/modules/training-record/src/dto/recordCreate.tsx +1 -1
  16. package/vona/src/suite/a-training/modules/training-record/src/dto/recordSelectReq.tsx +4 -4
  17. package/vona/src/suite/a-training/modules/training-record/src/dto/recordUpdate.tsx +1 -1
  18. package/vona/src/suite/a-training/modules/training-record/src/dto/recordView.tsx +1 -1
  19. package/vona/src/suite/a-training/modules/training-record/src/entity/record.tsx +26 -11
  20. package/vona/src/suite/a-training/modules/training-record/test/record.test.ts +27 -3
  21. package/vona/src/suite/a-training/modules/training-recordsubject/src/config/locale/en-us.ts +2 -2
  22. package/vona/src/suite/a-training/modules/training-recordsubject/src/config/locale/zh-cn.ts +2 -2
  23. package/vona/src/suite/a-training/modules/training-recordsubject/src/entity/subject.tsx +3 -3
  24. package/vona/src/suite/a-training/modules/training-student/src/.metadata/index.ts +1 -1
  25. package/vona/src/suite/a-training/modules/training-student/src/config/locale/en-us.ts +1 -1
  26. package/vona/src/suite/a-training/modules/training-student/src/config/locale/zh-cn.ts +1 -1
  27. package/vona/src/suite/a-training/modules/training-student/src/dto/detailRecordBase.tsx +11 -2
  28. package/vona/src/suite/a-training/modules/training-student/src/dto/studentSummary.tsx +1 -1
  29. package/vona/src/suite/a-training/modules/training-student/src/entity/student.tsx +1 -1
  30. package/vona/src/suite/a-training/modules/training-student/src/model/student.ts +9 -1
  31. package/vona/src/suite/a-training/modules/training-student/test/student.test.ts +21 -2
  32. package/vona/src/suite-vendor/a-vona/modules/a-core/package.json +1 -1
  33. package/vona/src/suite-vendor/a-vona/modules/a-openapi/package.json +1 -1
  34. package/vona/src/suite-vendor/a-vona/package.json +1 -1
  35. package/zova/packages-cli/cli/package.json +2 -2
  36. package/zova/packages-cli/cli-set-front/cli/templates/rest/render.ts +2 -0
  37. package/zova/packages-cli/cli-set-front/cli/templates/rest/rest.ts +14 -4
  38. package/zova/packages-cli/cli-set-front/package.json +1 -1
  39. package/zova/packages-utils/zova-jsx/package.json +2 -2
  40. package/zova/packages-zova/zova/package.json +3 -3
  41. package/zova/packages-zova/zova-core/package.json +2 -2
  42. package/zova/pnpm-lock.yaml +56 -56
  43. package/zova/pnpm-workspace.yaml +1 -1
  44. package/zova/src/suite/a-training/modules/training-student/src/api/openapi/schemas.ts +52 -24
  45. package/zova/src/suite/a-training/modules/training-student/src/api/openapi/types.ts +860 -307
  46. package/zova/src/suite/cabloy-basic/modules/basic-date/src/.metadata/component/date.ts +61 -0
  47. package/zova/src/suite/cabloy-basic/modules/basic-date/src/.metadata/index.ts +17 -4
  48. package/zova/src/suite/cabloy-basic/modules/basic-date/src/component/date/controller.tsx +44 -0
  49. package/zova/src/suite/cabloy-basic/modules/basic-date/src/component/formFieldDate/controller.tsx +49 -9
  50. package/zova/src/suite/cabloy-basic/modules/basic-date/src/lib/utils.ts +60 -1
  51. package/zova/src/suite/cabloy-basic/modules/basic-date/src/types/date.ts +2 -0
  52. package/zova/src/suite/cabloy-basic/modules/basic-resource/src/bean/tableCell.resourcePicker.tsx +1 -1
  53. package/zova/src/suite/cabloy-basic/modules/basic-resource/src/component/formFieldResourcePicker/controller.tsx +1 -1
  54. package/zova/src/suite-vendor/a-zova/modules/a-form/package.json +1 -1
  55. package/zova/src/suite-vendor/a-zova/modules/a-form/src/component/formField/controller.tsx +8 -0
  56. package/zova/src/suite-vendor/a-zova/modules/a-form/src/types/formField.ts +2 -0
  57. package/zova/src/suite-vendor/a-zova/modules/a-openapi/package.json +1 -1
  58. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/rest.ts +3 -0
  59. package/zova/src/suite-vendor/a-zova/modules/a-zod/package.json +2 -2
  60. package/zova/src/suite-vendor/a-zova/modules/a-zova/package.json +2 -2
  61. package/zova/src/suite-vendor/a-zova/package.json +5 -5
@@ -40,7 +40,7 @@ overrides:
40
40
  '@vue/runtime-dom': '3.5.36'
41
41
  '@vue/server-renderer': '3.5.36'
42
42
  '@vue/shared': '3.5.36'
43
- zod: 'npm:@cabloy/zod@4.3.6'
43
+ zod: 'npm:@cabloy/zod@4.3.8'
44
44
 
45
45
  allowBuilds:
46
46
  '@swc/core': true
@@ -13,7 +13,10 @@ export class MetaVersion extends BeanBase implements IMetaVersionUpdate {
13
13
  table.basicFields();
14
14
  table.tableIdentity(entityRecord.studentId).comment(entityRecord.$comment.studentId);
15
15
  table.string(entityRecord.name, 50).comment(entityRecord.$comment.name);
16
- table.integer(entityRecord.score).comment(entityRecord.$comment.score);
16
+ table.integer(entityRecord.subjectCount).comment(entityRecord.$comment.subjectCount);
17
+ table.integer(entityRecord.totalScore).comment(entityRecord.$comment.totalScore);
18
+ table.decimal(entityRecord.averageScore, 8, 2).comment(entityRecord.$comment.averageScore);
19
+ table.dateTime(entityRecord.trainingTime).comment(entityRecord.$comment.trainingTime);
17
20
  table.string(entityRecord.description, 255).comment(entityRecord.$comment.description);
18
21
  });
19
22
  }
@@ -1,10 +1,13 @@
1
1
  export default {
2
+ AverageScore: 'Average Score',
2
3
  Description: 'Description',
3
- Name: 'Name',
4
4
  Operations: 'Operations',
5
- Score: 'Score',
6
5
  Student: 'Student',
6
+ SubjectCount: 'Subject Count',
7
+ TotalScore: 'Total Score',
7
8
  TrainingRecord: 'Student Training Record',
9
+ TrainingRecordName: 'Training Record Name',
10
+ TrainingTime: 'Training Time',
8
11
  AddTrainingRecord: 'Add Student Training Record',
9
12
  EditTrainingRecord: 'Edit Student Training Record',
10
13
  ViewTrainingRecord: 'View Student Training Record',
@@ -1,10 +1,13 @@
1
1
  export default {
2
+ AverageScore: '平均分',
2
3
  Description: '描述',
3
- Name: '名称',
4
4
  Operations: '操作',
5
- Score: '成绩',
6
5
  Student: '学生',
6
+ SubjectCount: '科目数量',
7
+ TotalScore: '总得分',
7
8
  TrainingRecord: '学生培训记录',
9
+ TrainingRecordName: '培训记录名称',
10
+ TrainingTime: '培训时间',
8
11
  AddTrainingRecord: '添加学生培训记录',
9
12
  EditTrainingRecord: '编辑学生培训记录',
10
13
  ViewTrainingRecord: '查看学生培训记录',
@@ -31,7 +31,7 @@ export interface IDtoOptionsRecordCreate extends IDecoratorDtoOptions {}
31
31
  fields: {
32
32
  trainingRecordSubjects: $makeMetadata(
33
33
  v.title($locale('TrainingRecordSubjects')),
34
- ZovaRender.order(5),
34
+ ZovaRender.order(8),
35
35
  ZovaRender.field('basic-details:formFieldDetails'),
36
36
  v.optional(),
37
37
  ),
@@ -1,6 +1,6 @@
1
1
  import type { IDecoratorDtoOptions } from 'vona-module-a-web';
2
2
 
3
- import { $makeSchema, v } from 'vona-module-a-openapiutils';
3
+ import { $makeSchema, $resourceName, v } from 'vona-module-a-openapiutils';
4
4
  import { $Dto } from 'vona-module-a-orm';
5
5
  import { Dto } from 'vona-module-a-web';
6
6
  import z from 'zod';
@@ -17,9 +17,9 @@ export interface IDtoOptionsRecordSelectReq extends IDecoratorDtoOptions {}
17
17
  name: $makeSchema(v.optional(), z.string()),
18
18
  studentId: $makeSchema(
19
19
  v.title($locale('Student')),
20
- // ZovaRender.field('basic-resource:formFieldResourcePicker', {
21
- // resource: $resourceName('training-student:student'),
22
- // }),
20
+ ZovaRender.field('basic-resource:formFieldResourcePicker', {
21
+ resource: $resourceName('training-student:student'),
22
+ }),
23
23
  v.optional(),
24
24
  z.number(),
25
25
  ),
@@ -31,7 +31,7 @@ export interface IDtoOptionsRecordUpdate extends IDecoratorDtoOptions {}
31
31
  fields: {
32
32
  trainingRecordSubjects: $makeMetadata(
33
33
  v.title($locale('TrainingRecordSubjects')),
34
- ZovaRender.order(5),
34
+ ZovaRender.order(8),
35
35
  ZovaRender.field('basic-details:formFieldDetails'),
36
36
  v.optional(),
37
37
  ),
@@ -28,7 +28,7 @@ export interface IDtoOptionsRecordView extends IDecoratorDtoOptions {}
28
28
  fields: {
29
29
  trainingRecordSubjects: $makeMetadata(
30
30
  v.title($locale('TrainingRecordSubjects')),
31
- ZovaRender.order(5),
31
+ ZovaRender.order(8),
32
32
  ZovaRender.field('basic-details:formFieldDetails'),
33
33
  v.optional(),
34
34
  ),
@@ -1,7 +1,7 @@
1
1
  import type { TableIdentity } from 'table-identity';
2
2
  import type { IDecoratorEntityOptions } from 'vona-module-a-orm';
3
3
 
4
- import { $makeMetadata, Api, v } from 'vona-module-a-openapiutils';
4
+ import { $makeMetadata, $resourceName, Api, v } from 'vona-module-a-openapiutils';
5
5
  import { Entity, EntityBase } from 'vona-module-a-orm';
6
6
  import { ZovaRender } from 'zova-rest-cabloy-basic-admin';
7
7
 
@@ -29,7 +29,7 @@ export interface IEntityOptionsRecord extends IDecoratorEntityOptions {}
29
29
  })
30
30
  export class EntityRecord extends EntityBase {
31
31
  @Api.field(
32
- v.title($locale('Name')),
32
+ v.title($locale('TrainingRecordName')),
33
33
  v.required(),
34
34
  v.min(2),
35
35
  ZovaRender.order(1),
@@ -41,19 +41,34 @@ export class EntityRecord extends EntityBase {
41
41
  v.title($locale('Student')),
42
42
  v.required(),
43
43
  ZovaRender.order(2),
44
- // ZovaRender.field('basic-resource:formFieldResourcePicker', {
45
- // resource: $resourceName('training-student:student'),
46
- // }),
47
- // ZovaRender.cell('basic-resource:resourcePicker', {
48
- // resource: $resourceName('training-student:student'),
49
- // }),
44
+ ZovaRender.field('basic-resource:formFieldResourcePicker', {
45
+ resource: $resourceName('training-student:student'),
46
+ }),
47
+ ZovaRender.cell('basic-resource:resourcePicker', {
48
+ resource: $resourceName('training-student:student'),
49
+ }),
50
50
  v.tableIdentity(),
51
51
  )
52
52
  studentId: TableIdentity;
53
53
 
54
- @Api.field(v.title($locale('Score')), v.optional(), ZovaRender.order(3))
55
- score?: number;
54
+ @Api.field(v.title($locale('SubjectCount')), v.optional(), ZovaRender.order(3))
55
+ subjectCount?: number;
56
56
 
57
- @Api.field(v.title($locale('Description')), v.optional(), ZovaRender.order(4))
57
+ @Api.field(v.title($locale('TotalScore')), v.optional(), ZovaRender.order(4))
58
+ totalScore?: number;
59
+
60
+ @Api.field(v.title($locale('AverageScore')), v.optional(), ZovaRender.order(5))
61
+ averageScore?: number;
62
+
63
+ @Api.field(
64
+ v.title($locale('TrainingTime')),
65
+ v.optional(),
66
+ ZovaRender.order(6),
67
+ ZovaRender.field('basic-date:formFieldDate', { preset: 'DATE_FULL' }),
68
+ ZovaRender.cell('basic-date:date', { preset: 'DATE_FULL' }),
69
+ )
70
+ trainingTime?: Date;
71
+
72
+ @Api.field(v.title($locale('Description')), v.optional(), ZovaRender.order(7))
58
73
  description?: string;
59
74
  }
@@ -19,10 +19,15 @@ describe('record.test.ts', () => {
19
19
  level: 1,
20
20
  trainingRecords: [],
21
21
  };
22
+ const trainingTime = new Date('2026-01-15T09:30:00.000Z');
23
+ const trainingTimeUpdate = new Date('2026-02-20T14:45:00.000Z');
22
24
  const recordData = {
23
25
  studentId: 0 as any,
24
26
  name: '__Record__',
25
- score: 88,
27
+ subjectCount: 1,
28
+ totalScore: 88,
29
+ averageScore: 88,
30
+ trainingTime,
26
31
  description: 'This is a record',
27
32
  trainingRecordSubjects: [
28
33
  {
@@ -57,6 +62,10 @@ describe('record.test.ts', () => {
57
62
  const recordSubject = record.trainingRecordSubjects?.[0];
58
63
  assert.equal(record.name, recordData.name);
59
64
  assert.equal(String(record.studentId), String(studentId));
65
+ assert.equal(record.subjectCount, recordData.subjectCount);
66
+ assert.equal(record.totalScore, recordData.totalScore);
67
+ assert.equal(record.averageScore, recordData.averageScore);
68
+ assert.equal(new Date(record.trainingTime).toISOString(), trainingTime.toISOString());
60
69
  assert.equal(record.trainingRecordSubjects?.length, 1);
61
70
  assert.equal(recordSubject?.name, '__Math__');
62
71
  assert.equal(recordSubject?.score, 95);
@@ -73,7 +82,10 @@ describe('record.test.ts', () => {
73
82
  const dataUpdate = {
74
83
  studentId,
75
84
  name: '__RecordNew__',
76
- score: 89,
85
+ subjectCount: 2,
86
+ totalScore: 183,
87
+ averageScore: 91.5,
88
+ trainingTime: trainingTimeUpdate,
77
89
  description: 'This is an updated record',
78
90
  trainingRecordSubjects: [
79
91
  {
@@ -99,7 +111,10 @@ describe('record.test.ts', () => {
99
111
  });
100
112
  const [updatedMathSubject, updatedEnglishSubject] = record.trainingRecordSubjects ?? [];
101
113
  assert.equal(record.name, dataUpdate.name);
102
- assert.equal(record.score, dataUpdate.score);
114
+ assert.equal(record.subjectCount, dataUpdate.subjectCount);
115
+ assert.equal(record.totalScore, dataUpdate.totalScore);
116
+ assert.equal(record.averageScore, dataUpdate.averageScore);
117
+ assert.equal(new Date(record.trainingTime).toISOString(), trainingTimeUpdate.toISOString());
103
118
  assert.equal(record.trainingRecordSubjects?.length, 2);
104
119
  assert.equal(updatedMathSubject?.name, '__MathNew__');
105
120
  assert.equal(updatedMathSubject?.score, 96);
@@ -132,6 +147,15 @@ describe('record.test.ts', () => {
132
147
  );
133
148
  assert.equal(studentRecord, undefined);
134
149
 
150
+ await app.bean.executor.performAction('delete', '/training/student/:id', {
151
+ params: { id: studentId },
152
+ });
153
+
154
+ student = await app.bean.executor.performAction('get', '/training/student/:id', {
155
+ params: { id: studentId },
156
+ });
157
+ assert.equal(student, undefined);
158
+
135
159
  await app.bean.passport.signout();
136
160
  });
137
161
  });
@@ -1,9 +1,9 @@
1
1
  export default {
2
2
  Description: 'Description',
3
- Name: 'Name',
4
3
  Operations: 'Operations',
5
- Score: 'Score',
6
4
  Subject: 'Subject',
5
+ SubjectName: 'Subject Name',
6
+ SubjectScore: 'Subject Score',
7
7
  TrainingRecord: 'Student Training Record',
8
8
  TrainingRecordSubject: 'Student Training Record Detail',
9
9
  };
@@ -1,9 +1,9 @@
1
1
  export default {
2
2
  Description: '描述',
3
- Name: '名称',
4
3
  Operations: '操作',
5
- Score: '科目得分',
6
4
  Subject: '科目',
5
+ SubjectName: '科目名称',
6
+ SubjectScore: '科目得分',
7
7
  TrainingRecord: '学生培训记录',
8
8
  TrainingRecordSubject: '学生培训记录明细',
9
9
  };
@@ -31,11 +31,11 @@ export class EntitySubject extends EntityBase {
31
31
  @Api.field(v.required(), ZovaRender.visible(false))
32
32
  recordId: TableIdentity;
33
33
 
34
- @Api.field(v.title($locale('Name')), v.required(), v.min(2), ZovaRender.order(1))
34
+ @Api.field(v.title($locale('SubjectName')), v.required(), v.min(2), ZovaRender.order(1))
35
35
  name: string;
36
36
 
37
- @Api.field(v.title($locale('Score')), v.optional(), ZovaRender.order(2))
38
- score?: number;
37
+ @Api.field(v.title($locale('SubjectScore')), v.required(), ZovaRender.order(2))
38
+ score: number;
39
39
 
40
40
  @Api.field(v.title($locale('Description')), v.optional(), ZovaRender.order(3))
41
41
  description?: string;
@@ -86,7 +86,7 @@ import { SymbolKeyEntity, SymbolKeyEntityMeta, SymbolKeyModelOptions } from 'von
86
86
  declare module 'vona-module-training-student' {
87
87
  export interface IModelOptionsStudent {
88
88
  relations: {
89
- trainingRecords: IModelRelationHasMany<'training-record:record', 'studentId', false, 'id'|'name'|'score'|'description', undefined, undefined, undefined>;
89
+ trainingRecords: IModelRelationHasMany<'training-record:record', 'studentId', false, 'id'|'name'|'subjectCount'|'totalScore'|'averageScore'|'trainingTime'|'description', undefined, undefined, undefined>;
90
90
  };
91
91
  }
92
92
  export interface ModelStudent {
@@ -5,9 +5,9 @@ export default {
5
5
  LevelBeginner: 'Foundation Track',
6
6
  LevelIntermediate: 'Progress Track',
7
7
  Mobile: 'Mobile',
8
- Name: 'Name',
9
8
  Operations: 'Operations',
10
9
  Student: 'Student',
10
+ StudentName: 'Student Name',
11
11
  Summary: 'Summary',
12
12
  LevelTitle: 'Level Title',
13
13
  DescriptionLength: 'Description Length',
@@ -5,9 +5,9 @@ export default {
5
5
  LevelBeginner: '基础班',
6
6
  LevelIntermediate: '提升班',
7
7
  Mobile: '手机号',
8
- Name: '名称',
9
8
  Operations: '操作',
10
9
  Student: '学生',
10
+ StudentName: '学生姓名',
11
11
  Summary: '摘要',
12
12
  LevelTitle: '阶段名称',
13
13
  DescriptionLength: '描述长度',
@@ -15,13 +15,22 @@ export interface IDtoOptionsDetailRecordBase extends IDecoratorDtoOptions {}
15
15
  id: $makeMetadata(ZovaRender.visible(false)),
16
16
  trainingRecordSubjects: $makeMetadata(
17
17
  v.title($locale('TrainingRecordSubjects')),
18
- ZovaRender.order(4),
18
+ ZovaRender.order(8),
19
19
  ZovaRender.field('basic-details:formFieldDetails'),
20
20
  v.optional(),
21
21
  ),
22
22
  },
23
23
  })
24
24
  export class DtoDetailRecordBase extends $Dto.get(() => ModelRecord, {
25
- columns: ['id', 'deleted', 'name', 'score', 'description'],
25
+ columns: [
26
+ 'id',
27
+ 'deleted',
28
+ 'name',
29
+ 'subjectCount',
30
+ 'totalScore',
31
+ 'averageScore',
32
+ 'trainingTime',
33
+ 'description',
34
+ ],
26
35
  include: { trainingRecordSubjects: true },
27
36
  }) {}
@@ -13,7 +13,7 @@ export class DtoStudentSummary {
13
13
  @Api.field(v.tableIdentity())
14
14
  id: TableIdentity;
15
15
 
16
- @Api.field(v.title($locale('Name')))
16
+ @Api.field(v.title($locale('StudentName')))
17
17
  name: string;
18
18
 
19
19
  @Api.field(
@@ -35,7 +35,7 @@ export interface IEntityOptionsStudent extends IDecoratorEntityOptions {}
35
35
  })
36
36
  export class EntityStudent extends EntityBase {
37
37
  @Api.field(
38
- v.title($locale('Name')),
38
+ v.title($locale('StudentName')),
39
39
  v.required(),
40
40
  v.min(2),
41
41
  ZovaRender.order(1),
@@ -10,7 +10,15 @@ export interface IModelOptionsStudent extends IDecoratorModelOptions<EntityStude
10
10
  entity: EntityStudent,
11
11
  relations: {
12
12
  trainingRecords: $relation.hasMany('training-record:record', 'studentId', {
13
- columns: ['id', 'name', 'score', 'description'],
13
+ columns: [
14
+ 'id',
15
+ 'name',
16
+ 'subjectCount',
17
+ 'totalScore',
18
+ 'averageScore',
19
+ 'trainingTime',
20
+ 'description',
21
+ ],
14
22
  }),
15
23
  },
16
24
  })
@@ -18,6 +18,8 @@ describe('student.test.ts', () => {
18
18
  const maskedMobile = '138****5678';
19
19
  const mobileUpdate = '13987654321';
20
20
  const maskedMobileUpdate = '139****4321';
21
+ const trainingTime = new Date('2026-03-10T08:00:00.000Z');
22
+ const trainingTimeUpdate = new Date('2026-04-18T13:20:00.000Z');
21
23
  const data = {
22
24
  name: '__Tom__',
23
25
  description: 'This is a test',
@@ -26,7 +28,10 @@ describe('student.test.ts', () => {
26
28
  trainingRecords: [
27
29
  {
28
30
  name: '__Record__',
29
- score: 88,
31
+ subjectCount: 1,
32
+ totalScore: 88,
33
+ averageScore: 88,
34
+ trainingTime,
30
35
  description: 'This is a record',
31
36
  trainingRecordSubjects: [
32
37
  {
@@ -80,6 +85,10 @@ describe('student.test.ts', () => {
80
85
  const recordSubject = record?.trainingRecordSubjects?.[0];
81
86
  assert.equal(student.trainingRecords?.length, 1);
82
87
  assert.equal(record?.name, '__Record__');
88
+ assert.equal(record?.subjectCount, 1);
89
+ assert.equal(record?.totalScore, 88);
90
+ assert.equal(record?.averageScore, 88);
91
+ assert.equal(new Date(record?.trainingTime).toISOString(), trainingTime.toISOString());
83
92
  assert.equal(record?.trainingRecordSubjects?.length, 1);
84
93
  assert.equal(recordSubject?.name, '__Math__');
85
94
  assert.equal(recordSubject?.score, 95);
@@ -93,7 +102,10 @@ describe('student.test.ts', () => {
93
102
  {
94
103
  id: record.id,
95
104
  name: '__RecordNew__',
96
- score: 89,
105
+ subjectCount: 2,
106
+ totalScore: 183,
107
+ averageScore: 91.5,
108
+ trainingTime: trainingTimeUpdate,
97
109
  description: 'This is an updated record',
98
110
  trainingRecordSubjects: [
99
111
  {
@@ -127,6 +139,13 @@ describe('student.test.ts', () => {
127
139
  assert.equal(student.mobile, maskedMobileUpdate);
128
140
  assert.equal(student.trainingRecords?.length, 1);
129
141
  assert.equal(updatedRecord?.name, '__RecordNew__');
142
+ assert.equal(updatedRecord?.subjectCount, 2);
143
+ assert.equal(updatedRecord?.totalScore, 183);
144
+ assert.equal(updatedRecord?.averageScore, 91.5);
145
+ assert.equal(
146
+ new Date(updatedRecord?.trainingTime).toISOString(),
147
+ trainingTimeUpdate.toISOString(),
148
+ );
130
149
  assert.equal(updatedRecord?.trainingRecordSubjects?.length, 2);
131
150
  assert.equal(updatedMathSubject?.name, '__MathNew__');
132
151
  assert.equal(updatedMathSubject?.score, 96);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-module-a-core",
3
- "version": "5.1.34",
3
+ "version": "5.1.35",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "",
6
6
  "keywords": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-module-a-openapi",
3
- "version": "5.1.18",
3
+ "version": "5.1.19",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "",
6
6
  "keywords": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-suite-a-vona",
3
- "version": "5.1.49",
3
+ "version": "5.1.50",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "",
6
6
  "author": "",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-cli",
3
- "version": "1.2.89",
3
+ "version": "1.2.90",
4
4
  "gitHead": "6f675a8cc46d596142c591c28a40cc4d82fcc6cc",
5
5
  "description": "zova cli",
6
6
  "keywords": [
@@ -44,7 +44,7 @@
44
44
  "@cabloy/process-helper": "^3.1.8",
45
45
  "fs-extra": "^11.3.5",
46
46
  "semver": "^7.6.2",
47
- "zova-cli-set-front": "^1.2.87"
47
+ "zova-cli-set-front": "^1.2.88"
48
48
  },
49
49
  "devDependencies": {
50
50
  "clean-package": "^2.2.0",
@@ -20,6 +20,7 @@ import {
20
20
  schemaRenderDisableNotifyChanged,
21
21
  schemaRenderFieldSource,
22
22
  schemaRenderLayout,
23
+ schemaRenderOnEffect,
23
24
  schemaRenderOrder,
24
25
  schemaRenderReadonly,
25
26
  schemaRenderVisible,
@@ -32,6 +33,7 @@ export const ZovaRender = {
32
33
  readonly: schemaRenderReadonly,
33
34
  order: schemaRenderOrder,
34
35
  disableNotifyChanged: schemaRenderDisableNotifyChanged,
36
+ onEffect: schemaRenderOnEffect,
35
37
  fieldSource: schemaRenderFieldSource,
36
38
  // component
37
39
  field: schemaRenderField,
@@ -1,9 +1,9 @@
1
1
  import type z from 'zod';
2
2
 
3
- import { TypeFormSchemaScene } from 'zova-module-a-openapi';
4
- import { IResourceFormFieldLayoutOptions } from 'zova-module-a-openapi';
5
- import { TypeSchemaScene } from 'zova-module-a-openapi';
6
- import { TypeSchemaOrderLevel } from 'zova-module-a-openapi';
3
+ import type { TypeFormSchemaScene, TypeFormFieldOnEffect } from 'zova-module-a-openapi';
4
+ import type { IResourceFormFieldLayoutOptions } from 'zova-module-a-openapi';
5
+ import type { TypeSchemaScene } from 'zova-module-a-openapi';
6
+ import type { TypeSchemaOrderLevel } from 'zova-module-a-openapi';
7
7
 
8
8
  import { _generalSchemaRest, _order } from './inner.ts';
9
9
 
@@ -47,6 +47,16 @@ export function schemaRenderDisableNotifyChanged<T extends z.ZodType>(
47
47
  };
48
48
  }
49
49
 
50
+ export function schemaRenderOnEffect<T extends z.ZodType>(
51
+ onEffect: TypeFormFieldOnEffect,
52
+ scene?: TypeSchemaScene,
53
+ ) {
54
+ return function (schema: T): T {
55
+ const options = { onEffect };
56
+ return _generalSchemaRest(schema, options, scene);
57
+ };
58
+ }
59
+
50
60
  export function schemaRenderFieldSource<T extends z.ZodType>(
51
61
  fieldSource: string,
52
62
  scene?: TypeSchemaScene,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-cli-set-front",
3
- "version": "1.2.87",
3
+ "version": "1.2.88",
4
4
  "gitHead": "6f675a8cc46d596142c591c28a40cc4d82fcc6cc",
5
5
  "description": "zova cli-set-front",
6
6
  "keywords": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-jsx",
3
- "version": "1.1.63",
3
+ "version": "1.1.64",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "Zova JSX",
6
6
  "keywords": [
@@ -50,7 +50,7 @@
50
50
  "@cabloy/word-utils": "^2.1.14",
51
51
  "typestyle": "^2.4.0",
52
52
  "vue": "^3.5.38",
53
- "zova-core": "^5.1.57"
53
+ "zova-core": "^5.1.58"
54
54
  },
55
55
  "devDependencies": {
56
56
  "clean-package": "^2.2.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova",
3
- "version": "5.1.113",
3
+ "version": "5.1.115",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "A vue3 framework with ioc",
6
6
  "keywords": [
@@ -45,8 +45,8 @@
45
45
  "postpack": "clean-package restore"
46
46
  },
47
47
  "dependencies": {
48
- "zova-core": "^5.1.57",
49
- "zova-suite-a-zova": "^5.1.112"
48
+ "zova-core": "^5.1.58",
49
+ "zova-suite-a-zova": "^5.1.114"
50
50
  },
51
51
  "devDependencies": {
52
52
  "clean-package": "^2.2.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-core",
3
- "version": "5.1.57",
3
+ "version": "5.1.58",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "A vue3 framework with ioc",
6
6
  "keywords": [
@@ -62,7 +62,7 @@
62
62
  "@cabloy/word-utils": "^2.1.14",
63
63
  "@cabloy/zod-errors-custom": "^2.1.9",
64
64
  "@cabloy/zod-openapi": "^1.1.9",
65
- "@cabloy/zod-query": "^2.1.11",
65
+ "@cabloy/zod-query": "^2.1.12",
66
66
  "@types/js-cookie": "^3.0.6",
67
67
  "@vue/shared": "^3.5.32",
68
68
  "deep-equal": "^2.2.3",