plain-design 1.0.0-beta.136 → 1.0.0-beta.138

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "plain-design",
3
- "version": "1.0.0-beta.136",
3
+ "version": "1.0.0-beta.138",
4
4
  "description": "",
5
5
  "main": "dist/plain-design.min.js",
6
6
  "module": "dist/plain-design.commonjs.min.js",
@@ -12,30 +12,30 @@ import {defer} from "@peryl/utils/defer";
12
12
  import {toArray} from "@peryl/utils/toArray";
13
13
 
14
14
  export const $ai = (() => {
15
+
15
16
  const getConfig = (): iAiConfiguration => {
16
17
  const aiConfig = $configuration.get('aiConfig');
17
18
  if (!aiConfig) {
18
19
  throw new Error('There is a lack of aiConfig when initializing the $configuration.');
19
20
  }
20
21
  return aiConfig;
22
+
21
23
  };
22
- const chat = async (userContent: string, systemContent?: string, _aiConfig?: iAiConfiguration): Promise<{ message: string, chatData: iAiChatResponse }> => {
24
+
25
+ const chatHistories = async (histories: iAiHistory[], _aiConfig?: iAiConfiguration): Promise<{ message: string, chatData: iAiChatResponse }> => {
23
26
  const axios = Axios.create();
24
27
  const aiConfig = _aiConfig || getConfig();
25
- const messages: { role: 'system' | 'user', content: string }[] = [];
26
- !!systemContent && messages.push({ role: 'system', content: systemContent });
27
- messages.push({ role: 'user', content: userContent });
28
28
  try {
29
29
  const resp = await axios.request({
30
30
  method: 'post',
31
- url: aiConfig.api_url,
31
+ url: aiConfig.url,
32
32
  headers: {
33
- 'Authorization': `Bearer ${aiConfig.api_key}`,
33
+ 'Authorization': `Bearer ${aiConfig.key}`,
34
34
  "Content-Type": 'application/json'
35
35
  },
36
36
  data: {
37
37
  "model": aiConfig.model,
38
- "messages": messages
38
+ "messages": histories
39
39
  }
40
40
  });
41
41
 
@@ -43,14 +43,9 @@ export const $ai = (() => {
43
43
 
44
44
  let message = result.choices[0].message.content;
45
45
 
46
- /*todo 先在这里处理一下json的返回结果吧*/
47
- /*const pattern = /^```json([\s\S]*?)```/;
48
- if (pattern.test(message)) {
49
- const match = message.match(pattern);
50
- if (match && match[1]) {
51
- message = match[1].trim();
52
- }
53
- }*/
46
+ if (message.slice(0, 7) === '```json' && message.slice(-3) === '```') {
47
+ message = message.slice(7, -3).trim();
48
+ }
54
49
 
55
50
  return { message, chatData: result };
56
51
  } catch (e: any) {
@@ -58,6 +53,20 @@ export const $ai = (() => {
58
53
  throw e;
59
54
  }
60
55
  };
56
+
57
+ const chatSystem = async (userContent: string, systemContent?: string, _aiConfig?: iAiConfiguration) => {
58
+ const messages = [{ "role": "user", "content": userContent }];
59
+ if (!!systemContent) {
60
+ messages.unshift({ "role": "system", "content": systemContent });
61
+ }
62
+ return chatHistories(messages, _aiConfig);
63
+ };
64
+
65
+ const chat = async (userContent: string, _aiConfig?: iAiConfiguration): Promise<{ message: string, chatData: iAiChatResponse }> => {
66
+ return chatSystem(userContent, '', _aiConfig);
67
+ };
68
+
69
+
61
70
  /**
62
71
  * 根据ai对话,将用户描述转化为表单数据对象,
63
72
  * @author 韦胜健
@@ -77,7 +86,7 @@ export const $ai = (() => {
77
86
 
78
87
  const systemContent = `
79
88
  当前时间是:${createSimpleDate()["YYYY-MM-DD HH:mm:ss"]}
80
- 你是一名专业的自然一样分析师,你需要将用户描述转化为一个json对象数据;这个json对象的属性是确定的,json对象的属性名来源于以下的字段的field,这个属性对应的值需要你从用户描述中获取,没有的话就给默认值null;
89
+ 你是一名专业的自然语言分析师,你需要将用户描述转化为一个json对象数据;这个json对象的属性是确定的,json对象的属性名来源于以下的字段的field,这个属性对应的值需要你从用户描述中获取,没有的话就给默认值null;
81
90
  目前支持的字段:
82
91
  ${JSON.stringify(fields)}
83
92
 
@@ -126,6 +135,8 @@ export const $ai = (() => {
126
135
 
127
136
  return {
128
137
  chat,
138
+ chatSystem,
139
+ chatHistories,
129
140
  getConfig,
130
141
  getFormDataByChat,
131
142
  };
@@ -133,13 +144,18 @@ export const $ai = (() => {
133
144
 
134
145
  export interface iAiConfiguration {
135
146
  /*大模型的调用地址*/
136
- api_url: string,
147
+ url: string,
137
148
  /*大模型的调用key*/
138
- api_key: string,
149
+ key: string,
139
150
  /*调用的大模型名称*/
140
151
  model: string,
141
152
  }
142
153
 
154
+ export interface iAiHistory {
155
+ content: string,
156
+ role: string,
157
+ }
158
+
143
159
  export interface iAiChoice {
144
160
  /**
145
161
  * 模型停止生成 token 的原因。取值范围:
@@ -167,10 +183,7 @@ export interface iAiChoice {
167
183
  */
168
184
  logprobs: any,
169
185
  /*模型输出内容*/
170
- message: {
171
- content: string,
172
- role: string,
173
- }
186
+ message: iAiHistory
174
187
  }
175
188
 
176
189
  export interface iAiChatResponse {
@@ -71,7 +71,7 @@ export const AiChatBox = designComponent({
71
71
  state.histories.push({ role: 'user', content: userContent, id: uuid() });
72
72
  await methods.scrollEnd();
73
73
 
74
- const { message, chatData } = await $ai.chat(userContent, props.systemContent, aiConfig);
74
+ const { message, chatData } = await $ai.chatSystem(userContent, props.systemContent, aiConfig);
75
75
 
76
76
  /*可以手动处理返回的消息,自定义往对话框插入内容*/
77
77
  const newHistory: iChatBoxHistory | iChatBoxHistory[] = await props.handleMessage?.({ message, userContent, chatData, addHistory: methods.addHistory }) || ({ role: 'assistant', content: message, id: uuid() });
@@ -207,7 +207,7 @@ export const useTableOptionAi = AutoModule.createRegistration((option) => {
207
207
  /*---------------------------------------处理搜索-------------------------------------------*/
208
208
 
209
209
  let hasSearch = false;
210
- const searchData: iTableAiOperateSearch['data'] | undefined = operateItems.find(i => i.type === "search")?.data;
210
+ const searchData: iTableAiOperateSearch['data'] | undefined = (operateItems as any).find((i: iTableAiOperate) => i.type === "search")?.data;
211
211
  if (!!searchData) {
212
212
 
213
213
  hasSearch = true;
@@ -320,7 +320,7 @@ export const useTableOptionAi = AutoModule.createRegistration((option) => {
320
320
 
321
321
  /*---------------------------------------处理排序-------------------------------------------*/
322
322
  let hasSort = false;
323
- const sortData: iTableAiOperateSort['data'] | undefined = operateItems.find(i => i.type === "sort")?.data;
323
+ const sortData: iTableAiOperateSort['data'] | undefined = (operateItems as any).find((i: iTableAiOperate) => i.type === "sort")?.data;
324
324
  if (!!sortData) {
325
325
  hasSort = true;
326
326
  option.settingSeniorSort.methods.update(sortData, false);
@@ -328,7 +328,7 @@ export const useTableOptionAi = AutoModule.createRegistration((option) => {
328
328
 
329
329
  /*---------------------------------------处理配置-------------------------------------------*/
330
330
  let hasConfig = false;
331
- const configData: iTableAiOperateConfig['data'] | undefined = operateItems.find(i => i.type === "config")?.data;
331
+ const configData: iTableAiOperateConfig['data'] | undefined = (operateItems as any).find((i: iTableAiOperate) => i.type === "config")?.data;
332
332
  if (!!configData) {
333
333
  hasConfig = true;
334
334
  await option.settingConfig.methods.updateItemPlc({
@@ -54,9 +54,10 @@ export function installFilterCity(
54
54
  );
55
55
  },
56
56
  getQueryParam: async ({ formData, option }) => {
57
- const { isEmpty, value, field } = checkEmpty(formData, option);
57
+ const { isEmpty, value: _value, field } = checkEmpty(formData, option);
58
58
  if (isEmpty) {return;}
59
- return { queries: [{ field, value: value.city, operator: eFilterOperator.eq }] };
59
+ const value = typeof _value === "string" ? _value : _value.city;
60
+ return { queries: [{ field, value: value, operator: eFilterOperator.eq }] };
60
61
  },
61
62
  })
62
63
  .setHandler('in', {
@@ -55,9 +55,10 @@ export function installFilterDistrict(
55
55
  );
56
56
  },
57
57
  getQueryParam: async ({ formData, option }) => {
58
- const { isEmpty, value, field } = checkEmpty(formData, option);
58
+ const { isEmpty, value: _value, field } = checkEmpty(formData, option);
59
59
  if (isEmpty) {return;}
60
- return { queries: [{ field, value: value.district, operator: eFilterOperator.eq }] };
60
+ const value = typeof _value === "string" ? _value : _value.city;
61
+ return { queries: [{ field, value: value, operator: eFilterOperator.eq }] };
61
62
  },
62
63
  })
63
64
  .setHandler('in', {
@@ -55,14 +55,17 @@ export function useFormItemValidation({ props }: { props: iFormItemValidateProps
55
55
  * @author 韦胜健
56
56
  * @date 2022.11.6 0:00
57
57
  */
58
- const getValueByRule = (rule: iValidateRule): { label?: string | null, field?: string, value?: string } | null => {
58
+ const getValueByRule = (rule: iValidateRule): { label?: string | null, field?: string } | null => {
59
59
  if (formValidation.props.validateMode === eFormValidateMode.table) {return null;}
60
- const { field, label, valueGetter } = rule;
60
+ // const { field, label, valueGetter } = rule;
61
+ const { field, label } = rule;
61
62
  if (!rule.field && !rule.valueGetter) {return null;}
62
63
  return {
63
64
  label,
64
65
  field,
65
- value: getRuleValue({ formData: formValidation.props.modelValue, field, validateValueGetter: valueGetter, formItemProps: props }),
66
+ /*这里不能调用valueGetter,这样会导致值变化也会触发教研,设计是触发onChange才触发校验而不是值变化就触发*/
67
+ /*这里调用valueGetter的话,会导致触发watch,进而触发onFieldChange*/
68
+ // value: getRuleValue({ formData: formValidation.props.modelValue, field, validateValueGetter: valueGetter, formItemProps: props }),
66
69
  };
67
70
  };
68
71
 
@@ -88,9 +91,9 @@ export function useFormItemValidation({ props }: { props: iFormItemValidateProps
88
91
  return;
89
92
  }
90
93
  /*值没有变化*/
91
- if (newValue.value == oldValue.value) {
94
+ /*if (newValue.value == oldValue.value) {
92
95
  return;
93
- }
96
+ }*/
94
97
  formValidation.handler.onFieldChange({ label: newValue.label, field: newValue.field });
95
98
  }
96
99
  ));
@@ -70,7 +70,7 @@ export function useFormValidation({ props }: { props: iFormValidatePropsType })
70
70
  return parentValidation.methods.validateItem({ label, field, trigger: eFormValidateTrigger.change, state, formData: props.modelValue });
71
71
  },
72
72
  onEditChange: ({ label, field }: { label: string | null | undefined, field: string | undefined }) => {
73
- if (props.validateMode !== eFormValidateMode.table) {return; }
73
+ // if (props.validateMode !== eFormValidateMode.table) {return; }
74
74
  return handler.onFieldChange({ label, field });
75
75
  },
76
76
  onBlurChange: ({ label, field }: { label: string | null | undefined, field: string | undefined }) => {
@@ -138,7 +138,7 @@ export type {iContextmenuOption} from './components/useContextmenuOptions';
138
138
  export {AiChatBox} from './components/AiChatBox';
139
139
  export type {iChatBoxHistory} from './components/AiChatBox';
140
140
  export {$ai} from './components/$ai';
141
- export type {iAiChoice, iAiChatResponse, iAiConfiguration} from './components/$ai';
141
+ export type {iAiChoice, iAiChatResponse, iAiConfiguration, iAiHistory} from './components/$ai';
142
142
 
143
143
  export {VirtualTable} from './components/VirtualTable';
144
144
  export {Table} from './components/Table';
@@ -198,6 +198,7 @@ export type {
198
198
  iTableOperationPermitConfig
199
199
  } from './components/Table/standard/PlcOperation/PlcOperation.utils';
200
200
  export type {iTreeProps, iTreeState, iTreeKey2CheckStatus, iTreeKeyOrNode, iTreeNodeComputedData} from './components/TreeCore/TreeCore.type';
201
+ export type {iTreeNodeWithMenuOption} from './components/TreeNodeWithMenu/treeNodeWithMenu.utils';
201
202
 
202
203
  export {$configuration} from './components/$configuration';
203
204
  export {createAddressService} from './components/createAddressService';
@@ -1,6 +1,8 @@
1
1
  import {useFunctionWrapper} from "./useFunctionWrapper";
2
2
  import {computed, inject, onBeforeUnmount, PropType, provide, reactive} from '@peryl/react-compose';
3
3
  import {eMultipleValueType} from "./useMultipleModel";
4
+ import {PlainObject} from "@peryl/utils/event";
5
+ import {createEffects} from "@peryl/utils/createEffects";
4
6
 
5
7
  export const EDIT_PROVIDER = '@@EDIT_PROVIDER';
6
8
 
@@ -29,6 +31,9 @@ export const useEdit = useFunctionWrapper(
29
31
  'edit',
30
32
  (ctx, option: { adjust?: (data: EditProvideData) => void | EditProvideData } = {}) => {
31
33
 
34
+ /*销毁时处理掉useEdit产生的副作用*/
35
+ const { effects } = createEffects();
36
+
32
37
  const parentEditComputed = inject(EDIT_PROVIDER, null) as null | { value: EditProvideData };
33
38
 
34
39
  const editState = reactive({ loading: null as null | boolean });
@@ -55,6 +60,11 @@ export const useEdit = useFunctionWrapper(
55
60
  data.loading = editState.loading;
56
61
  }
57
62
 
63
+ /*合并自身的onChange以及父edit的onChange*/
64
+ data.onChange = mergeHandlers({ methodName: 'onChange', parent: parentEditComputed?.value, self: data, });
65
+ /*合并自身的onBlur以及父edit的onBlur*/
66
+ data.onBlur = mergeHandlers({ methodName: 'onBlur', parent: parentEditComputed?.value, self: data, });
67
+
58
68
  if (!!option.adjust) data = option.adjust(data) || data;
59
69
 
60
70
  return {
@@ -62,25 +72,25 @@ export const useEdit = useFunctionWrapper(
62
72
  editable: !data.disabled && !data.readonly && !data.loading
63
73
  };
64
74
  });
75
+ effects.push(() => {editComputed.effect.stop();});
65
76
 
66
77
  provide(EDIT_PROVIDER, editComputed);
67
78
 
68
79
  const event = (ctx as any).event;
69
80
 
70
- if (!!parentEditComputed) {
71
- if (!!parentEditComputed.value.onBlur && !!event && !!event.on.onBlur) {
72
- event.on.onBlur(parentEditComputed.value.onBlur);
73
- onBeforeUnmount(() => event.off.onBlur(parentEditComputed.value.onBlur!));
74
- }
75
- if (!!parentEditComputed.value.onChange && !!event && !!event.on.onChange) {
76
- event.on.onChange(parentEditComputed.value.onChange);
77
- onBeforeUnmount(() => event.off.onChange(parentEditComputed.value.onChange!));
78
- }
81
+ /*处理onBlur事件传递*/
82
+ if (event.on.onBlur && !!editComputed.value.onBlur) {
83
+ event.on.onBlur(editComputed.value.onBlur);
84
+ effects.push(() => event.off.onBlur(editComputed.value.onBlur));
79
85
  }
80
86
 
81
- onBeforeUnmount(() => {
82
- editComputed.effect.stop();
83
- });
87
+ /*处理onChange传递*/
88
+ if (event.on.onChange && !!editComputed.value.onChange) {
89
+ event.on.onChange(editComputed.value.onChange);
90
+ effects.push(() => event.off.onChange(editComputed.value.onChange));
91
+ }
92
+
93
+ onBeforeUnmount(effects.clear);
84
94
 
85
95
  return {
86
96
  editState,
@@ -91,3 +101,16 @@ export const useEdit = useFunctionWrapper(
91
101
  export type tEditControl = ReturnType<typeof useEdit>
92
102
 
93
103
  export type tEditComputed = tEditControl["editComputed"]
104
+
105
+ const mergeHandlers = ({ methodName, parent, self }: { methodName: string, parent: PlainObject | undefined, self: PlainObject }) => {
106
+ if (parent?.[methodName] || self[methodName]) {
107
+ const selfOnChange = self[methodName];
108
+ const parentOnChange = parent?.[methodName];
109
+ return (...args: any[]) => {
110
+ // console.log({ args, methodName, parentOnChange, selfOnChange });
111
+ selfOnChange?.(...args);
112
+ parentOnChange?.(...args);
113
+ };
114
+ }
115
+ return undefined;
116
+ };