Selaa lähdekoodia

fix: 个人简历模块第二版调整

zhangying 4 päivää sitten
vanhempi
commit
f027d35200
1 muutettua tiedostoa jossa 328 lisäystä ja 0 poistoa
  1. 328 0
      .docs/260603-前端框架全局开发规范与最佳实践.md

+ 328 - 0
.docs/260603-前端框架全局开发规范与最佳实践.md

@@ -1473,6 +1473,334 @@ import { getToken, getTenantId, setAuthCache, getAuthCache, clearAuthCache } fro
 | `rowDragSort`       | 拖拽排序  | JVxeDragSortCell       |
 | `slot`              | 插槽自定义 | JVxeSlotCell           |
 
+### 19.3 数据校验(validateRules)
+
+JVxeTable 完全支持对输入数据进行校验检查,包括非空、纯数字、纯字母、正则、自定义函数等。校验规则通过列配置中的 `validateRules`
+数组定义。
+
+#### 19.3.1 两级校验机制
+
+| 层级      | 配置位置                | 说明                                      |
+|---------|---------------------|-----------------------------------------|
+| **组件级** | `editRules` prop    | 全局 vxe-table 原生 `editRules`,可对所有列施加通用校验 |
+| **列级**  | `validateRules` 列属性 | 每列独立配置校验规则数组,优先级更高                      |
+
+两种校验规则通过 `lodash.merge` 合并后传入底层 vxe-table。
+
+#### 19.3.2 validateRules 规则项字段
+
+| 字段          | 类型                  | 说明                                                   |
+|-------------|---------------------|------------------------------------------------------|
+| `required`  | `boolean`           | 是否必填(非空校验)                                           |
+| `pattern`   | `string` / `RegExp` | 正则表达式,支持快捷值                                          |
+| `message`   | `string`            | 校验失败提示,支持 `${title}`、`${key}`、`${defaultValue}` 变量替换 |
+| `validator` | `function`          | 自定义异步校验函数(Promise 形式)                                |
+| `handler`   | `function`          | 旧版回调式校验函数(兼容模式,内部转为 validator)                       |
+| `unique`    | `boolean`           | 唯一性校验(同一列中值不能重复)                                     |
+
+#### 19.3.3 内置快捷校验值(fooPatterns)
+
+组件内置了常用校验规则的快捷值,使用时直接传入 `pattern` 对应的快捷字符串即可,无需写正则。
+
+定义位置:[useValidateRules.ts](file:///d:/Code/Project/湛江人社/code/zjrs-jeecgBoot/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useValidateRules.ts#L82-L105)
+
+| 快捷值     | 含义        | 对应正则                                                        |
+|---------|-----------|-------------------------------------------------------------|
+| `*`     | 非空        | 等同于 `required: true`                                        |
+| `n`     | 纯数字(含小数)  | `/^-?\d+(\.?\d+\|\d?)$/`                                    |
+| `s`     | 纯字母       | `/^[A-Z\|a-z]+$/`                                           |
+| `z`     | 整数        | `/^-?\d+$/`                                                 |
+| `e`     | 电子邮件      | `/^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/`      |
+| `m`     | 手机号码      | `/^1[3456789]\d{9}$/`                                       |
+| `p`     | 邮政编码      | `/^\d{6}$/`                                                 |
+| `url`   | 网址        | URL 格式正则                                                    |
+| `money` | 金额        | `/^(([1-9][0-9]*)\|([0]\.\d{0,2}\|[1-9][0-9]*\.\d{0,5}))$/` |
+| `n6-16` | 6到16位数字   | `/^\d{6,16}$/`                                              |
+| `*6-16` | 6到16位任意字符 | `/^.{6,16}$/`                                               |
+| `s6-18` | 6到18位字母   | `/^[a-z\|A-Z]{6,18}$/`                                      |
+| `only`  | 唯一性校验     | 同 `unique: true`,遍历整表检查同列值是否重复                              |
+
+#### 19.3.4 使用示例
+
+```typescript
+import {JVxeTable, JVxeTypes} from '/@/components/jeecg/JVxeTable';
+
+const columns = [
+    {
+        key: 'name',
+        title: '姓名',
+        type: JVxeTypes.input,
+        // 非空校验
+        validateRules: [{required: true, message: '${title}不能为空'}],
+    },
+    {
+        key: 'age',
+        title: '年龄',
+        type: JVxeTypes.inputNumber,
+        // 整数校验 + 非空
+        validateRules: [
+            {required: true, message: '${title}不能为空'},
+            {pattern: 'z', message: '${title}必须为整数'},
+        ],
+    },
+    {
+        key: 'email',
+        title: '邮箱',
+        type: JVxeTypes.input,
+        // 非必填但格式校验
+        validateRules: [{pattern: 'e', message: '${title}格式不正确'}],
+    },
+    {
+        key: 'phone',
+        title: '手机号',
+        type: JVxeTypes.input,
+        // 手机号校验
+        validateRules: [{pattern: 'm', message: '${title}格式不正确'}],
+    },
+    {
+        key: 'code',
+        title: '编码',
+        type: JVxeTypes.input,
+        // 纯字母校验 + 唯一性校验
+        validateRules: [
+            {required: true, message: '${title}不能为空'},
+            {pattern: 's', message: '${title}只能包含字母'},
+            {unique: true, message: '${title}不能重复'},
+        ],
+    },
+    {
+        key: 'amount',
+        title: '金额',
+        type: JVxeTypes.inputNumber,
+        // 金额格式校验
+        validateRules: [{pattern: 'money', message: '${title}格式不正确'}],
+    },
+    {
+        key: 'idCard',
+        title: '身份证号',
+        type: JVxeTypes.input,
+        // 自定义正则校验
+        validateRules: [{
+            pattern: '^\\d{6}(18|19|20)?\\d{2}(0[1-9]|1[012])(0[1-9]|[12]\\d|3[01])\\d{3}(\\d|[xX])$',
+            message: '${title}格式不正确',
+        }],
+    },
+    {
+        key: 'customField',
+        title: '自定义校验',
+        type: JVxeTypes.input,
+        // 自定义校验函数(handler 回调式,兼容旧版)
+        validateRules: [{
+            handler: (event, callback) => {
+                const {cellValue} = event;
+                if (cellValue && cellValue.length < 3) {
+                    callback(false, '长度不能少于3位');
+                } else {
+                    callback(true);
+                }
+            },
+            message: '${title}校验不通过',
+        }],
+    },
+];
+```
+
+#### 19.3.5 非编辑组件的必填标记
+
+对于 `checkbox`、`radio`、`upload`、`progress`、`departSelect`、`userSelect`、`image`、`file` 等非文本编辑组件,如果配置了
+`validateRules` 且包含 `required`,会在列头的 `title` 前自动加 ` * ` 标记,提示用户该列为必填。
+
+定义位置:[useColumns.ts](file:///d:/Code/Project/湛江人社/code/zjrs-jeecgBoot/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useColumns.ts#L125-L149)
+
+#### 19.3.6 手动触发校验
+
+JVxeTable 对外暴露了两个校验方法,可在外部通过 ref 调用:
+
+| 方法                         | 说明                             |
+|----------------------------|--------------------------------|
+| `validateTable(rows?)`     | 校验当前表格,成功返回 `null`,失败返回 errMap |
+| `fullValidateTable(rows?)` | 完整校验所有数据(无论是否修改过)              |
+
+```vue
+
+<template>
+  <JVxeTable ref="tableRef" :columns="columns" :dataSource="dataSource"/>
+</template>
+
+<script setup>
+  import {ref} from 'vue';
+
+  const tableRef = ref();
+
+  async function handleSubmit() {
+    // 调用表格校验
+    const errMap = await tableRef.value.validateTable();
+    if (errMap) {
+      console.log('校验失败:', errMap);
+      return;
+    }
+    // 校验通过,执行后续逻辑
+    console.log('校验通过');
+  }
+</script>
+```
+
+定义位置:[useMethods.ts](file:///d:/Code/Project/湛江人社/code/zjrs-jeecgBoot/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useMethods.ts#L580-L595)
+
+### 19.4 插槽自定义字段输入(slotName + JVxeTypes.slot)
+
+JVxeTable 支持通过插槽(slot)方式自定义某个字段的输入框内容,适用于需要自定义编辑组件(如下拉框、级联选择、日期范围等)且选项数据来自父组件的场景。
+
+#### 19.4.1 插槽机制原理
+
+JVxeTable 的插槽机制分两层:
+
+**第一层:`JVxeTypes.slot` + `slotName`(推荐方式)**
+
+这是 JVxeTable 内置的插槽支持机制,完全集成到行编辑系统中。
+
+- 列配置中设置 `type: JVxeTypes.slot`,同时指定 `slotName`(如 `'myFieldSlot'`)
+- JVxeTable 内部的 `JVxeSlotCell` 组件负责渲染该单元格
+- `useColumns.ts` 中的 `handleSlots()`
+  方法([源码](file:///d:/Code/Project/湛江人社/code/zjrs-jeecgBoot/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/hooks/useColumns.ts#L402-L408)
+  )会检查父组件是否传入了同名插槽,若有则将插槽函数注入渲染参数
+
+**第二层:`$slots` 透传至底层 `vxe-grid`**
+
+在 [JVxeTable.ts](file:///d:/Code/Project/湛江人社/code/zjrs-jeecgBoot/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/JVxeTable.ts#L77-L81)
+的 render 函数中,`this.$slots` 被完整透传给底层的 `vxe-grid` 组件。这意味着所有传递给 JVxeTable 的插槽也会被 vxe-grid
+接收,可以使用 vxe-grid 原生的所有插槽能力。
+
+#### 19.4.2 slot 插槽接收的参数
+
+[JVxeSlotCell.ts](file:///d:/Code/Project/湛江人社/code/zjrs-jeecgBoot/jeecgboot-vue3/src/components/jeecg/JVxeTable/src/components/cells/JVxeSlotCell.ts#L10-L24)
+中定义了插槽函数接收的参数对象:
+
+| 参数                   | 类型                | 说明                           |
+|----------------------|-------------------|------------------------------|
+| `value`              | `any`             | 当前单元格的值                      |
+| `row`                | `object`          | 当前行数据                        |
+| `column`             | `object`          | 当前列配置信息                      |
+| `params`             | `object`          | vxe-table 原始渲染参数             |
+| `$table`             | `object`          | vxe-table 实例,可调用内置方法         |
+| `rowId`              | `string`          | 当前行唯一标识                      |
+| `index` / `rowIndex` | `number`          | 当前行下标                        |
+| `columnIndex`        | `number`          | 当前列下标                        |
+| `scrolling`          | `boolean`         | 是否正在滚动                       |
+| `reloadEffect`       | `boolean`         | 是否开启了数据刷新特效                  |
+| `triggerChange`      | `(value) => void` | **触发值变更**,用于将插槽组件的值更新到单元格数据中 |
+
+#### 19.4.3 下拉框选项来自父组件的实现示例
+
+**场景**:在 JVxeTable 中,某个字段需要使用下拉选择,下拉选项来自父组件(如通过 props 传入、API 加载、或父组件的响应式数据)。
+
+**列配置(data 文件)**:
+
+```typescript
+import {JVxeTypes} from '/@/components/jeecg/JVxeTable';
+
+export const studyAbroadColumns: JVxeColumn[] = [
+    {
+        title: '国家/地区',
+        key: 'country',
+        type: JVxeTypes.slot,       // 使用 slot 类型
+        slotName: 'countrySlot',    // 插槽名称,与模板中的 #countrySlot 对应
+        width: 160,
+        validateRules: [{required: true, message: '${title}不能为空'}],
+    },
+    {
+        title: '学校名称',
+        key: 'schoolName',
+        type: JVxeTypes.input,
+        width: 200,
+    },
+    {
+        title: '开始日期',
+        key: 'startDate',
+        type: JVxeTypes.date,
+        width: 140,
+    },
+    // ... 其他列
+];
+```
+
+**父组件模板**:
+
+```vue
+
+<template>
+  <JVxeTable
+      ref="studyAbroadTableRef"
+      :columns="computedStudyAbroadColumns"
+      :dataSource="studyAbroadData.dataSource"
+      :height="250"
+      keepSource
+      rowNumber
+      rowSelection
+      stripe
+      toolbar
+  >
+    <!-- 自定义国家/地区字段的下拉选择框 -->
+    <template #countrySlot="{ row, triggerChange }">
+      <a-select
+          :value="row.country"
+          :options="countryOptions"
+          placeholder="请选择国家/地区"
+          allow-clear
+          :bordered="false"
+          style="width: 100%"
+          @change="(val) => triggerChange(val)"
+      />
+    </template>
+  </JVxeTable>
+</template>
+```
+
+**父组件脚本**:
+
+```typescript
+<script lang = "ts"
+setup >
+import {ref} from 'vue';
+import {JVxeTable} from '/@/components/jeecg/JVxeTable';
+import {studyAbroadColumns} from '../ResumeInfo.data';
+
+// 下拉选项数据——来自父组件,可以是 props、API 加载、或本地定义的响应式数据
+const countryOptions = ref([
+    {label: '美国', value: '美国'},
+    {label: '英国', value: '英国'},
+    {label: '澳大利亚', value: '澳大利亚'},
+    {label: '日本', value: '日本'},
+    {label: '新加坡', value: '新加坡'},
+]);
+
+// 也可以是通过 API 动态加载
+// import { getCountryList } from '../xxx.api';
+// onMounted(async () => {
+//   const res = await getCountryList();
+//   countryOptions.value = res.map(item => ({ label: item.name, value: item.code }));
+// });
+</script>
+```
+
+#### 19.4.4 关键注意点
+
+1. **`triggerChange` 是必须调用的**:插槽组件值变更时,必须调用 `triggerChange(newValue)` 将值同步回 JVxeTable
+   的数据源,否则表格数据不会更新。
+
+2. **插槽名称要唯一**:每个 `JVxeTypes.slot` 列需要指定不同的 `slotName`,同一个 JVxeTable 内不能重名。
+
+3. **slot 列支持校验**:`validateRules` 对 slot 列同样生效,非空校验会在列头显示 ` * ` 标记。
+
+4. **`bordered: false`**:插槽内部使用 Ant Design 组件时,建议设置 `:bordered="false"` 以与表格单元格样式融合。
+
+5. **插槽作用域来自父组件**:插槽模板在父组件中编写,可以直接访问父组件的所有响应式数据(props、ref、computed
+   等),因此下拉选项可以灵活地来自任何父组件数据源。
+
+6. **与普通 select 类型对比**:
+    - `JVxeTypes.select`:适用于选项固定或通过 `dictCode` 从字典加载的场景
+    - `JVxeTypes.slot`:适用于选项来自父组件、需要完全自定义UI、或涉及复杂交互的场景
+
 ---
 
 ## 二十、WebSocket 实时推送