DerivedIndexForm.jsx 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. import {memo, useCallback, useEffect, useRef, useState} from 'react';
  2. import {ProCard, ProFormGroup, ProFormRadio, ProFormSelect, ProFormDigit} from "@ant-design/pro-components";
  3. import {Button, Col} from "antd";
  4. import {LogicPanel} from "../../../components/LogicPanel";
  5. import {styled} from "styled-components";
  6. import {useAppDispatch, useAppSelector} from "../../../../redux/configureStore";
  7. import {selectConditions, selectModals} from "../../MainPage/slice/selectors";
  8. import {getConditions, getModalDetail, getModalInfo} from "../../MainPage/slice/thunks";
  9. import {DATA_TYPE, FORM_TYPE} from "../constants";
  10. import {CodeEditor} from "../../../components/CodeEditor";
  11. import useI18NPrefix from "../../../hooks/useI18NPrefix";
  12. /** 派生指标 */
  13. export const DerivedIndexForm = memo(({
  14. onChange,
  15. onConditionSave,
  16. initialValues,
  17. onSetField,
  18. onExprChange
  19. }) => {
  20. const isCondition = !!initialValues?.ext?.filters;
  21. const measures = initialValues?.metricDefineByMeasureParams?.measures[0];
  22. const initTab = initialValues?.ext?.filters?.length<1 && measures?.constraint ?'customScript':'fieldsConfig';
  23. const t = useI18NPrefix('global');
  24. const dispatch = useAppDispatch();
  25. const modals = useAppSelector(selectModals);
  26. const conditions = useAppSelector(selectConditions);
  27. const [tab, setTab] = useState(initTab);
  28. const [conditionType, setConditionType] = useState(!isCondition);
  29. const [dateDims, setDateDims] = useState([]);
  30. const [analyzeDims, setAnalyzeDims] = useState([]);
  31. const [metrics, setMetrics] = useState([]);
  32. const [filters, setFilters] = useState([]);
  33. const editorRef = useRef(null);
  34. useEffect(() => {
  35. const initialSelector = async (modelId)=>{
  36. await onModalSelect(modelId)
  37. }
  38. if (initialValues?.modelId){
  39. initialSelector(initialValues?.modelId)
  40. onExprChange?.({expr:measures?.constraint})
  41. }
  42. }, []);
  43. useEffect(() => {
  44. if (initialValues?.metricDefineByMeasureParams?.measures){
  45. const newMetric = metrics.map(item=>JSON.parse(item.value));
  46. const findMetric = newMetric.find(item=>item.bizName===measures?.bizName);
  47. if (findMetric){
  48. onSetField("formIndex",JSON.stringify(findMetric))
  49. }
  50. }
  51. }, [metrics]);
  52. const onModalSelect = useCallback((id) => {
  53. if (!id) return false
  54. dispatch(getConditions({}))
  55. dispatch(getModalDetail({
  56. id,
  57. resolve(data){
  58. if (data?.modelDetail){
  59. const {fields} = data.modelDetail
  60. const fieldsOptions = fields.map(({comment,fieldName})=>({
  61. label: comment ,
  62. value: fieldName,
  63. }))
  64. setFilters(fieldsOptions)
  65. }
  66. }
  67. }))
  68. dispatch(getModalInfo({
  69. id,
  70. resolve(data) {
  71. const getDimensions = data?.dimensions||[];
  72. const getMetrics = data?.metrics || [];
  73. const date = getDimensions.filter(item=>item.type === "time").map(item=>({label:item.description || item.name|| item.bizName, value: item.id}));
  74. const analyze =getDimensions.filter(item=>item.type !== "time").map(item=>({label:item.description || item.name, value: item.id}));
  75. const tempMetrics = getMetrics
  76. .filter(item=>item.bizName!==initialValues?.bizName && FORM_TYPE.ATOMIC.value === item.type)
  77. .map(item=>({label:item.name, value: JSON.stringify({id: item.id,bizName:item.bizName,operations:item?.operations,expr:item.expr})}));
  78. setDateDims(date);
  79. setAnalyzeDims(analyze);
  80. setMetrics(tempMetrics);
  81. }
  82. }))
  83. // 缓存维度列表
  84. onChange?.();
  85. }, [])
  86. const onEditorChange = (expr)=>{
  87. editorRef.current = expr;
  88. onExprChange?.({expr})
  89. }
  90. const onSaveCondition = (tab)=>{
  91. onConditionSave(tab,editorRef.current);
  92. }
  93. return (
  94. <>
  95. <ProFormSelect
  96. name="modelId"
  97. label={t("formItem.model")}
  98. rules={[{required: true}]}
  99. options={modals}
  100. onChange={onModalSelect}
  101. />
  102. <ProFormSelect
  103. name="formIndex"
  104. label={t("formItem.formIndex")}
  105. rules={[{required: true}]}
  106. options={metrics}
  107. />
  108. <ProFormRadio.Group
  109. name="conditionType"
  110. label={t("formItem.condition")}
  111. initialValue={conditionType}
  112. style={{marginBottom: 0}}
  113. rules={[{required: true}]}
  114. fieldProps={{
  115. onChange: (e) => setConditionType(e.target.value)
  116. }}
  117. options={[
  118. {label: t("operation.formLibrary"), value: true},
  119. {label: t("operation.custom"), value: false}
  120. ]}
  121. />
  122. {
  123. conditionType
  124. ? <ProFormSelect
  125. name="conditionId"
  126. label={t("formItem.bizCondition")}
  127. rules={[{required: true}]}
  128. initialValue={initialValues?.bizConditionResp?.id}
  129. options={conditions.map(item=>({label: item.name, value: item.id}))}
  130. />
  131. : <Col offset={4} span={18} style={{marginBottom: 24, marginTop: -28}}>
  132. <CustomProCard
  133. tabs={{
  134. tabBarExtraContent:<Button type='link' onClick={()=>onSaveCondition(tab)}>{t("button.save")+t("formItem.bizCondition")}</Button>,
  135. activeKey: tab,
  136. items: [
  137. {
  138. label: t("operation.fieldsConfig"),
  139. key: 'fieldsConfig',
  140. children: <LogicPanel value={initialValues?.ext?.filters} type={FORM_TYPE.DERIVED.value} options={filters}/>,
  141. },
  142. {
  143. label: t("operation.customScript"),
  144. key: 'customScript',
  145. children: <CodeEditor ref={editorRef} value={measures?.constraint} onEditorChange={onEditorChange} width="100%" height="180"/>,
  146. }
  147. ],
  148. onChange: (key) => {
  149. setTab(key);
  150. },
  151. }}
  152. />
  153. </Col>
  154. }
  155. <ProFormGroup style={{marginLeft: 105}}>
  156. <ProFormSelect
  157. name="dataFormatType"
  158. label={t("formItem.dataFormat")}
  159. valueEnum={DATA_TYPE}
  160. width={480}
  161. />
  162. <ProFormDigit name="decimalPlaces" placeholder={t("placeholder.decimalPlaces")} initialValue={initialValues?.dataFormat?.decimalPlaces} min={1} max={10}/>
  163. </ProFormGroup>
  164. <ProFormSelect
  165. name="relateDimension"
  166. options={analyzeDims}
  167. label={t("formItem.dimension")}
  168. fieldProps={{
  169. mode: 'multiple'
  170. }}
  171. />
  172. <ProFormSelect
  173. name="dateDimId"
  174. label={t("formItem.dateDimension")}
  175. rules={[{required: true}]}
  176. options={dateDims}
  177. />
  178. </>
  179. )
  180. })
  181. const CustomProCard = styled(ProCard)`
  182. .ant-pro-card-body {
  183. padding: 0;
  184. }
  185. `