From 0a436fb137fb23370df364e18939ee53d7fa60e2 Mon Sep 17 00:00:00 2001 From: yupeng12 Date: Thu, 6 Jun 2024 17:31:34 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=85=AC=E5=BC=8F=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=BF=AB=E6=8D=B7=E5=8F=98=E9=87=8F=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis-editor-core/src/util.ts | 85 +++++++++++-------- .../src/renderer/FormulaControl.tsx | 34 +++++--- .../src/renderer/TplFormulaControl.tsx | 11 ++- .../TextareaFormulaControl.tsx | 1 + .../amis-ui/scss/components/_formula.scss | 6 ++ .../src/components/formula/VariableList.tsx | 79 ++++++++++------- 6 files changed, 138 insertions(+), 78 deletions(-) diff --git a/packages/amis-editor-core/src/util.ts b/packages/amis-editor-core/src/util.ts index cdc4129ca..49e6857da 100644 --- a/packages/amis-editor-core/src/util.ts +++ b/packages/amis-editor-core/src/util.ts @@ -4,7 +4,7 @@ import {hasIcon, mapObject, utils} from 'amis'; import type {PlainObject, Schema, SchemaNode} from 'amis'; import {getGlobalData} from 'amis-theme-editor-helper'; -import {isExpression, resolveVariableAndFilter} from 'amis-core'; +import {filterTree, isExpression, resolveVariableAndFilter} from 'amis-core'; import type {VariableItem} from 'amis-ui'; import {isObservable, reaction} from 'mobx'; import DeepDiff, {Diff} from 'deep-diff'; @@ -1362,65 +1362,78 @@ export async function getVariables(that: any) { return variablesArr; } -export async function getQuickVariables( - that: any, - resolver?: (vars: any[]) => any[] -) { +export async function getQuickVariables(that: any) { const {node, manager} = that.props.formProps || that.props; - const selfName = that.props?.data?.name; + const {quickVars, data} = that.props; + const selfName = data?.name; await manager?.getContextSchemas(node); const options = await manager?.dataSchema?.getDataPropsAsOptions(); if (Array.isArray(options)) { - const vars = options.find(item => item.label === '组件上下文'); - if (vars?.children?.length) { - // 获取当前层的变量 - const current: any[] = vars.children[0].children || []; - const filterVars = current - .filter(item => item.value !== selfName && item.schemaType) - .map(item => { - // 子表过滤成员那层 - if (item.type === 'array' && Array.isArray(item.children)) { - if (item.children.length === 1) { - const child = item.children[0]; - if (child.type === 'object' && child.disabled) { - return { - ...item, - children: child.children - }; - } - } - } - return item; - }); - - return resolver ? resolver(filterVars) : filterVars; - } + const curOptions = options.find(item => item.label === '组件上下文'); + return resolveQuickVariables(curOptions, quickVars, selfName); } return []; } -export function resolveQuickVariablesByType( - variables: VariableItem[], - quickVars?: VariableItem[] +export function resolveQuickVariables( + option: any, + quickVars?: VariableItem[], + selfName?: string ) { + if (!option?.children?.length) { + return []; + } + const finalVars = []; + const curOption = option.children[0]; + const superOption = option.children[1]; + const variables = (curOption.children || []) + .filter((item: any) => item.value !== selfName && item.schemaType) + .map((item: any) => { + // 子表过滤成员那层 + if (item.type === 'array' && Array.isArray(item.children)) { + if (item.children.length === 1) { + const child = item.children[0]; + if (child.type === 'object' && child.disabled) { + return { + ...item, + children: child.children + }; + } + } + } + return item; + }); + if (superOption?.children?.length) { + const superVars = superOption?.children.filter( + (item: any) => item.schemaType && item.type !== 'array' + ); + finalVars.push(...superVars); + finalVars.push({ + label: curOption.label, + children: variables + }); + } else { + finalVars.push(...variables); + } + if (quickVars?.length) { const vars: VariableItem[] = []; vars.push({ label: '快捷变量', children: quickVars }); - if (variables.length) { + if (finalVars.length) { vars.push({ label: '表单变量', - children: variables + children: finalVars }); } return vars; } - return variables; + return finalVars; } /** diff --git a/packages/amis-editor/src/renderer/FormulaControl.tsx b/packages/amis-editor/src/renderer/FormulaControl.tsx index 5b916f2d0..5ad01b962 100644 --- a/packages/amis-editor/src/renderer/FormulaControl.tsx +++ b/packages/amis-editor/src/renderer/FormulaControl.tsx @@ -20,11 +20,7 @@ import FormulaPicker, { import {JSONPipeOut, autobind, translateSchema} from 'amis-editor-core'; import {EditorManager} from 'amis-editor-core'; import {reaction} from 'mobx'; -import { - getVariables, - getQuickVariables, - resolveQuickVariablesByType -} from 'amis-editor-core'; +import {getVariables, getQuickVariables} from 'amis-editor-core'; import type {BaseEventContext} from 'amis-editor-core'; import type {VariableItem, FuncGroup} from 'amis-ui'; @@ -215,14 +211,11 @@ export default class FormulaControl extends React.Component< } ); - const {valueType, quickVars} = this.props; const variables = await getVariables(this); - const quickVariables = await getQuickVariables(this, items => - items.filter(item => item.schemaType === valueType) - ); + const quickVariables = await getQuickVariables(this); this.setState({ variables, - quickVariables: resolveQuickVariablesByType(quickVariables, quickVars) + quickVariables: this.filterQuickVariablesByType(quickVariables) }); } @@ -236,6 +229,26 @@ export default class FormulaControl extends React.Component< this.buttonTarget = ref; } + @autobind + filterQuickVariablesByType(variables: any[]) { + const rendererSchema = this.getRendererSchemaFromProps(); + const filterVars = variables + .map(item => { + if (item.children) { + item.children = item.children.filter( + (i: any) => i.schemaType === rendererSchema.type + ); + } + return item; + }) + .filter( + item => + item.schemaType === rendererSchema.type || + (item.children && item.children?.length) + ); + return filterVars; + } + /** * 将 ${xx}(非 \${xx})替换成 \${xx} * 备注: 手动编辑时,自动处理掉 ${xx},避免识别成 公式表达式 @@ -664,6 +677,7 @@ export default class FormulaControl extends React.Component< data={quickVariables} onSelect={this.handleQuickVariableSelect} popOverContainer={popOverContainer} + simplifyMemberOprs /> ); diff --git a/packages/amis-editor/src/renderer/TplFormulaControl.tsx b/packages/amis-editor/src/renderer/TplFormulaControl.tsx index 9e8af3639..d06fea5b2 100644 --- a/packages/amis-editor/src/renderer/TplFormulaControl.tsx +++ b/packages/amis-editor/src/renderer/TplFormulaControl.tsx @@ -55,6 +55,11 @@ export interface TplFormulaControlProps extends FormControlProps { * 支付支持快捷变量 */ quickVariables?: boolean; + + /** + * 额外的快捷变量 + */ + quickVars?: Array; } interface TplFormulaControlState { @@ -148,7 +153,10 @@ export class TplFormulaControl extends React.Component< const variables = await getVariables(this); const quickVariables = await getQuickVariables(this); - this.setState({variables, quickVariables}); + this.setState({ + variables, + quickVariables + }); } componentWillUnmount() { @@ -474,6 +482,7 @@ export class TplFormulaControl extends React.Component< data={quickVariables} onSelect={this.handleQuickVariableSelect} popOverContainer={popOverContainer} + simplifyMemberOprs /> ); diff --git a/packages/amis-editor/src/renderer/textarea-formula/TextareaFormulaControl.tsx b/packages/amis-editor/src/renderer/textarea-formula/TextareaFormulaControl.tsx index 012d51681..32a6bb383 100644 --- a/packages/amis-editor/src/renderer/textarea-formula/TextareaFormulaControl.tsx +++ b/packages/amis-editor/src/renderer/textarea-formula/TextareaFormulaControl.tsx @@ -484,6 +484,7 @@ export class TextareaFormulaControl extends React.Component< data={quickVariables} onSelect={this.handleQuickVariableSelect} popOverContainer={popOverContainer} + simplifyMemberOprs /> ); diff --git a/packages/amis-ui/scss/components/_formula.scss b/packages/amis-ui/scss/components/_formula.scss index d6968beef..eacd963d2 100644 --- a/packages/amis-ui/scss/components/_formula.scss +++ b/packages/amis-ui/scss/components/_formula.scss @@ -302,6 +302,7 @@ white-space: nowrap; & > label { + cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; @@ -311,6 +312,10 @@ min-width: #{px2rem(50px)}; } + & > .icon { + cursor: pointer; + } + .fa-ellipsis-h { margin-right: #{px2rem(5px)}; &:hover { @@ -319,6 +324,7 @@ } &-tag { + cursor: auto; vertical-align: middle; text-align: center; padding: 0 #{px2rem(8px)}; diff --git a/packages/amis-ui/src/components/formula/VariableList.tsx b/packages/amis-ui/src/components/formula/VariableList.tsx index 5cfb3c96d..648c7a56d 100644 --- a/packages/amis-ui/src/components/formula/VariableList.tsx +++ b/packages/amis-ui/src/components/formula/VariableList.tsx @@ -5,6 +5,7 @@ import GroupedSelection from '../GroupedSelection'; import Tabs, {Tab} from '../Tabs'; import TreeSelection from '../TreeSelection'; import SearchBox from '../SearchBox'; +import {Icon} from '../icons'; import type {VariableItem} from './CodeEditor'; import type {ItemRenderStates} from '../Selection'; @@ -42,29 +43,34 @@ const memberOpers = [ '即当前列表中所有符合该成员条件的记录总数,需补充成员条件,例如:item.xxx === 1' }, { - label: '取该成员去重之后的总数', + label: '去重计数:取该成员去重之后的总数', value: 'COUNT(UNIQ(${arr}, item.${member}))', - description: '即对该成员记录进行去重,并统计总数' + description: '即对该成员记录进行去重,并统计总数', + simple: true }, { - label: '取该成员的总和', + label: '求和:求当前列的所有值之和', value: 'SUM(ARRAYMAP(${arr}, item => item.${member}))', - description: '即计算该成员记录的总和,需确认该成员记录均为数字类型' + description: '即计算该成员记录的总和,需确认该成员记录均为数字类型', + simple: true }, { - label: '取该成员的平均值', + label: '平均值:求当前列的平均值', value: 'AVG(ARRAYMAP(${arr}, item => item.${member}))', - description: '即计算该成员记录的平均值,需确认该成员记录均为数字类型' + description: '即计算该成员记录的平均值,需确认该成员记录均为数字类型', + simple: true }, { - label: '取该成员的最大值', + label: '最大值:取当前列的最大值', value: 'MAX(ARRAYMAP(${arr}, item => item.${member}))', - description: '即计算该成员记录中最大值,需确认该成员记录均为数字类型' + description: '即计算该成员记录中最大值,需确认该成员记录均为数字类型', + simple: true }, { - label: '取该成员的最小值', + label: '最小值:取当前列的最小值', value: 'MIN(ARRAYMAP(${arr}, item => item.${member}))', - description: '即计算该成员记录中最小值,需确认该成员记录均为数字类型' + description: '即计算该成员记录中最小值,需确认该成员记录均为数字类型', + simple: true } ]; @@ -80,6 +86,7 @@ export interface VariableListProps extends ThemeProps, SpinnerExtraProps { onSelect?: (item: VariableItem) => void; selfVariableName?: string; expandTree?: boolean; + simplifyMemberOprs?: boolean; popOverContainer?: () => HTMLElement; } @@ -96,6 +103,7 @@ function VariableList(props: VariableListProps) { placeholderRender, selfVariableName, expandTree, + simplifyMemberOprs, popOverContainer } = props; const [variables, setVariables] = React.useState>([]); @@ -177,28 +185,30 @@ function VariableList(props: VariableListProps) { } popOverRender={({onClose}) => (
    - {memberOpers.map((item, i) => { - return ( - -
  • !simplifyMemberOprs || item.simple) + .map((item, i) => { + return ( + - handleMemberClick( - {...item, isMember: true}, - option, - onClose - ) - } + tooltip={item.description} + tooltipTheme="dark" > - {item.label} -
  • -
    - ); - })} +
  • + handleMemberClick( + {...item, isMember: true}, + option, + onClose + ) + } + > + {item.label} +
  • + + ); + })}
)} > @@ -207,7 +217,14 @@ function VariableList(props: VariableListProps) { tooltip={option.description ?? option.label} tooltipTheme="dark" > - + <> + + + )}