Files
mayfly-go/mayfly_go_web/src/components/SearchForm/index.ts

319 lines
7.5 KiB
TypeScript
Raw Normal View History

2023-12-16 17:41:15 +08:00
import Api from '@/common/Api';
import { VNode, ref, toValue } from 'vue';
2023-12-12 23:31:53 +08:00
export type FieldNamesProps = {
label: string;
value: string;
children?: string;
};
export type SearchItemType =
| 'input'
| 'input-number'
| 'select'
| 'select-v2'
| 'tree-select'
| 'cascader'
| 'date-picker'
| 'time-picker'
| 'time-select'
| 'switch'
| 'slider';
2023-12-16 17:41:15 +08:00
/**
* api信息
*/
export class OptionsApi {
/**
* options的api
*/
api: Api;
/**
*
*/
params: any;
/**
* focus事件中获取
*/
immediate: boolean = false;
/**
* api
*/
once: boolean = true;
/**
* api结果转换为满足组件options的结构
*/
convertFn: (apiResp: any) => any;
2023-12-17 01:43:38 +08:00
// remote: boolean = false;
/**
* 使remote-method进行远程搜索
*/
remoteMethodParamProp: string;
2023-12-16 17:41:15 +08:00
withConvertFn(fn: (apiResp: any) => any) {
this.convertFn = fn;
return this;
}
/**
*
* @returns
*/
withImmediate() {
this.immediate = true;
return this;
}
/**
* apifocus获取的时候都允许重新获取options
* @returns this
*/
withNoOnce() {
this.once = false;
return this;
}
2023-12-17 01:43:38 +08:00
/**
* 使select的remote方式远程搜索调用
* @param remoteReqParamKey remote请求参数对应的propvalue赋值给params[paramProp]
*/
isRemote(paramProp: string) {
this.remoteMethodParamProp = paramProp;
return this;
}
2023-12-16 17:41:15 +08:00
/**
* api获取组件可选项
* @returns
*/
async getOptions() {
let res = await this.api.request(toValue(this.params));
if (this.convertFn) {
res = this.convertFn(res);
}
return res;
}
static new(api: Api, params: any): OptionsApi {
const oa = new OptionsApi();
oa.api = api;
oa.params = params;
return oa;
}
}
2023-12-12 23:31:53 +08:00
/**
*
*/
export class SearchItem {
/**
*
*/
prop: string;
/**
* label
*/
label: string;
/**
* inputselectdate等
*/
type: SearchItemType;
/**
* select等组件的可选值
*/
options: any;
2023-12-16 17:41:15 +08:00
/**
* api信息
*/
optionsApi: OptionsApi;
2023-12-12 23:31:53 +08:00
/**
*
*/
slot: string;
2023-12-16 17:41:15 +08:00
/**
* element plus
*/
props?: any;
2023-12-12 23:31:53 +08:00
2023-12-16 17:41:15 +08:00
/**
* element plus
*/
events?: any;
2023-12-12 23:31:53 +08:00
2023-12-16 17:41:15 +08:00
/**
*
*/
tooltip?: string;
2023-12-12 23:31:53 +08:00
2023-12-16 17:41:15 +08:00
/**
* 1
*/
span?: number;
2023-12-12 23:31:53 +08:00
2023-12-16 17:41:15 +08:00
/**
*
*/
offset?: number;
2023-12-12 23:31:53 +08:00
2023-12-16 17:41:15 +08:00
/**
* label && value && children key select等类型组件
*/
fieldNames: FieldNamesProps;
/**
* tsx语法
*/
render?: (scope: any) => VNode;
2023-12-12 23:31:53 +08:00
constructor(prop: string, label: string) {
this.prop = prop;
this.label = label;
}
static new(prop: string, label: string): SearchItem {
return new SearchItem(prop, label);
}
2023-12-16 17:41:15 +08:00
static input(prop: string, label: string): SearchItem {
2023-12-12 23:31:53 +08:00
const tq = new SearchItem(prop, label);
tq.type = 'input';
return tq;
}
static select(prop: string, label: string): SearchItem {
const tq = new SearchItem(prop, label);
tq.type = 'select';
2023-12-16 17:41:15 +08:00
tq.withOneProps('filterable', true);
2023-12-12 23:31:53 +08:00
return tq;
}
2023-12-16 17:41:15 +08:00
static datePicker(prop: string, label: string): SearchItem {
2023-12-12 23:31:53 +08:00
const tq = new SearchItem(prop, label);
tq.type = 'date-picker';
return tq;
}
static slot(prop: string, label: string, slotName: string): SearchItem {
const tq = new SearchItem(prop, label);
tq.slot = slotName;
return tq;
}
2023-12-16 17:41:15 +08:00
/**
* props属性
* @param propsKey key
* @param propsValue value
* @returns
*/
withOneProps(propsKey: string, propsValue: any): SearchItem {
if (!this.props) {
this.props = {};
}
this.props[propsKey] = propsValue;
return this;
}
/**
* props属性 ( element plus )
* @returns this
*/
withProps(props: any = {}): SearchItem {
this.props = props;
return this;
}
/**
*
* @param event
* @param fn
* @returns
*/
bindEvent(event: string, eventFn: any): SearchItem {
if (!this.events) {
this.events = {};
}
2023-12-17 01:43:38 +08:00
this.events[event] = eventFn;
2023-12-12 23:31:53 +08:00
return this;
}
/**
*
* @param enumValues
* @returns
*/
withEnum(enumValues: any): SearchItem {
this.options = Object.values(enumValues);
return this;
}
2023-12-16 17:41:15 +08:00
/**
* options可选项值的api配置
* @param optionsApi api配置
* @returns this
*/
withOptionsApi(optionsApi: OptionsApi): SearchItem {
this.optionsApi = optionsApi;
// 使用api获取组件可选项需要将options转为响应式否则组件无法响应式获取组件可选项
this.options = ref(null);
2023-12-17 01:43:38 +08:00
// 存在远程搜索请求参数prop则为使用远程搜索可选项
if (optionsApi.remoteMethodParamProp) {
return this.withOneProps('remote', true).withOneProps('remote-method', async (value: any) => {
if (!value) {
this.options.value = [];
return;
}
// 将输入的内容赋值为真实api请求参数中指定的属性字段
optionsApi.params[optionsApi.remoteMethodParamProp] = value;
this.options.value = await this.optionsApi.getOptions();
});
}
2023-12-16 17:41:15 +08:00
// 立即执行则直接调用api获取并赋值options
if (this.optionsApi.immediate) {
this.optionsApi.getOptions().then((res) => {
this.options.value = res;
});
} else {
// 注册focus事件在触发focus时赋值options
this.bindEvent('focus', async () => {
if (!toValue(this.options) || !optionsApi.once) {
this.options.value = await this.optionsApi.getOptions();
}
});
}
return this;
}
withSpan(span: number): SearchItem {
this.span = span;
return this;
}
withOptions(options: any): SearchItem {
2023-12-12 23:31:53 +08:00
this.options = options;
return this;
}
2023-12-17 01:43:38 +08:00
/**
* placeholder
* @param val placeholder
* @returns
*/
withPlaceholder(val: string): SearchItem {
return this.withOneProps('placeholder', val);
}
2023-12-12 23:31:53 +08:00
}