This commit is contained in:
2025-01-25 20:30:58 +08:00
parent 7fb31b5c53
commit 662b18548f
5 changed files with 311 additions and 71 deletions

View File

@@ -0,0 +1,161 @@
import type { CalcType, LinkType, SelectType } from '@/types/my-kintone';
import { isType, type FieldType, type OneOf } from './kintone-rest-api-client';
import { calcJoinType, linkJoinType, type SpecialType, isSpecialType } from './join';
import { KintoneFormFieldProperty } from '@kintone/rest-api-client';
// LEFT
export type LeftLookupMappingType = SpecialType<'LOOKUP_MAPPING_FOR_LEFT', FieldType[]>;
export const lookupMappingType = (format: FieldType[]): LeftLookupMappingType => {
return {
type: 'LOOKUP_MAPPING_FOR_LEFT',
format,
check: function (field: OneOf, rightField?: OneOf) {
if (rightField && isLookup(rightField) && !isLookup(field)) {
return false;
}
return !!this.format?.find((e) => e === field.type);
},
};
};
const mayLookupText = lookupMappingType(['SINGLE_LINE_TEXT']);
const mayLookupNumber = lookupMappingType(['NUMBER']);
export type LeftCalcMappingType = SpecialType<
'CALC_MAPPING_FOR_LEFT',
Record<CalcType, Array<FieldType | LeftLookupMappingType>>
>;
// same as join
export const calcMappingType: LeftCalcMappingType = {
type: 'CALC_MAPPING_FOR_LEFT',
format: {
NUMBER: [mayLookupText, mayLookupNumber],
NUMBER_DIGIT: [mayLookupText, mayLookupNumber],
DATE: ['DATE'],
TIME: ['TIME'],
DATETIME: ['DATETIME'],
HOUR_MINUTE: [],
DAY_HOUR_MINUTE: [],
},
check: function (field: OneOf, rightField?: OneOf) {
let allowed: Array<FieldType | LeftLookupMappingType> = [];
if (rightField && isType.CALC(rightField)) {
allowed = this.format[rightField.format];
}
if (field && isType.CALC(field)) {
return !!allowed.find((e) => {
if (isSpecialType(e) && isLeftLookupMappingType(e)) {
return e.check(field, rightField);
}
return e === field.format
});
}
return false;
},
};
export type LinkMappingType = SpecialType<'LINK_MAPPING', Record<LinkType, LinkType[]>>;
// same as join
export const linkMappingType = {
...linkJoinType,
type: 'LINK_MAPPING',
} as LinkMappingType;
const availableLeftMappingType = {
SINGLE_LINE_TEXT: [mayLookupText],
MULTI_LINE_TEXT: ['MULTI_LINE_TEXT'],
RICH_TEXT: ['RICH_TEXT'],
NUMBER: [mayLookupNumber, mayLookupText],
CALC: [calcMappingType],
RADIO_BUTTON: ['RADIO_BUTTON'],
CHECK_BOX: ['CHECK_BOX'],
MULTI_SELECT: ['MULTI_SELECT'], // TODO 带选项字段报错
DROP_DOWN: ['DROP_DOWN'],
USER_SELECT: ['USER_SELECT'],
ORGANIZATION_SELECT: ['ORGANIZATION_SELECT'],
GROUP_SELECT: ['GROUP_SELECT'],
DATE: ['DATE', 'DATETIME'],
TIME: ['TIME'],
DATETIME: ['DATETIME'],
LINK: [linkMappingType, mayLookupText],
//LOOKUP
RECORD_NUMBER: [mayLookupText, mayLookupNumber],
CREATOR: ['USER_SELECT'],
CREATED_TIME: ['DATETIME'],
MODIFIER: ['USER_SELECT'],
UPDATED_TIME: ['DATETIME'],
} as Record<FieldType, Array<FieldType | LeftCalcMappingType | LinkMappingType | LeftLookupMappingType>>;
// RIGHT
export type RightCalcMappingType = SpecialType<'CALC_MAPPING_FOR_RIGHT', CalcType[]>;
export type RightLookupMappingType = SpecialType<'LOOKUP_MAPPING_FOR_RIGHT', FieldType[]>;
export const forCalc = (format: CalcType[]): RightCalcMappingType => {
return {
type: 'CALC_MAPPING_FOR_RIGHT',
format,
check: function (field: OneOf, leftField?: OneOf) {
return isType.CALC(field) && !!this.format?.find((e) => e === field.format);
},
};
};
export const forLookup = (format: FieldType[]): RightLookupMappingType => {
return {
type: 'LOOKUP_MAPPING_FOR_RIGHT',
format,
check: function (field: OneOf, leftField?: OneOf) {
if (!isLookup(field)) return false;
return !!this.format?.find((e) => e === field.type);
},
};
};
const availableRightMappingType = {
SINGLE_LINE_TEXT: ['SINGLE_LINE_TEXT', 'NUMBER', forCalc(['NUMBER', 'NUMBER_DIGIT']), 'LINK', 'RECORD_NUMBER'],
MULTI_LINE_TEXT: ['MULTI_LINE_TEXT'],
RICH_TEXT: ['RICH_TEXT'],
NUMBER: ['NUMBER', forCalc(['NUMBER', 'NUMBER_DIGIT']), forLookup(['NUMBER']), 'RECORD_NUMBER'],
RADIO_BUTTON: ['RADIO_BUTTON'],
CHECK_BOX: ['CHECK_BOX'],
MULTI_SELECT: ['MULTI_SELECT'], // TODO 带选项字段报错
DROP_DOWN: ['DROP_DOWN'],
USER_SELECT: ['USER_SELECT', 'CREATOR', 'MODIFIER'],
ORGANIZATION_SELECT: ['ORGANIZATION_SELECT'],
GROUP_SELECT: ['GROUP_SELECT'],
DATE: ['DATE', forCalc(['DATE'])],
TIME: ['TIME', forCalc(['TIME'])],
DATETIME: ['DATE', 'DATETIME', forCalc(['DATETIME']), 'CREATED_TIME', 'UPDATED_TIME'],
LINK: [linkMappingType],
} as Record<FieldType, Array<FieldType | RightCalcMappingType | RightLookupMappingType | LinkMappingType>>;
// undefined means all
export function getRightAvailableMappingType(left?: OneOf | '') {
if (left === undefined) {
return Object.keys(availableRightMappingType) as FieldType[];
}
return left ? availableLeftMappingType[left.type] : [];
}
// undefined means all
export function getLeftAvailableMappingType(right?: OneOf | '') {
if (right === undefined) {
return Object.keys(availableLeftMappingType) as FieldType[];
}
return right ? availableRightMappingType[right.type] : [];
}
export function isLeftLookupMappingType(obj: SpecialType): obj is LeftLookupMappingType {
return obj.type === 'LOOKUP_MAPPING_FOR_LEFT';
}
export function isLookup(field: OneOf): field is KintoneFormFieldProperty.Lookup {
return 'lookup' in field;
}
// export function isSelectType(field: OneOf): field is SelectType {
// return 'options' in field;
// }