123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376 |
- import {memo, forwardRef, useRef, useCallback, useEffect} from 'react';
- import {Button, Card, Drawer, message} from "antd";
- import {
- ProForm,
- ProFormDatePicker,
- ProFormTimePicker,
- ProFormGroup,
- ProFormText,
- ProFormRadio,
- ProFormDependency,
- ProFormTreeSelect,
- ProFormSelect, ProFormTextArea
- } from "@ant-design/pro-components";
- import {AtomicIndexForm} from "./AtomicIndexForm";
- import {FORM_TYPE, INDEX_TYPE, INVOKE_TYPE, PERSISTENCE_WAY, SENSITIVE, TIME_MODE, CONFIRM_STATUS} from "../constants";
- import {DerivedIndexForm} from "./DerivedIndexForm";
- import {CompositeIndexForm} from "./CompositeIndexForm";
- import {useAppDispatch, useAppSelector} from "../../../../redux/configureStore";
- import {selectDomains, selectPeriods} from "../../MainPage/slice/selectors";
- import {createCondition, getConditions, getModals, getPersistenceConfig, periodList} from "../../MainPage/slice/thunks";
- import {styled} from "styled-components";
- import useI18NPrefix from "../../../hooks/useI18NPrefix";
- import {bizConditionToSQL} from "../../../../utils/listTools";
- import {pinyin} from "pinyin-pro";
- const formLayoutType = "horizontal";
- const pickerWidth = 390;
- const component = forwardRef(({
- onFinish,
- initialValues,
- open,
- handleCancel,
- }, ref) => {
- const t = useI18NPrefix('global');
- const dispatch = useAppDispatch()
- const domains = useAppSelector(selectDomains);
- const periods = useAppSelector(selectPeriods);
- const formRef = useRef(null);
- const compositeRef = useRef(null);
- useEffect(() => {
- dispatch(periodList({}));
- const {domainId,id} = initialValues;
- if (domainId){
- dispatch(getModals({domainId}));
- }
- if (id){
- dispatch(getPersistenceConfig({
- id,
- resolve(data){
- if (data){
- const defaultConfig = JSON.parse(data.defaultConfig)
- formRef.current?.setFieldsValue({
- invokeMethod:defaultConfig?.type || 'AUTO',
- runCycleCode:data?.runCycleCode,
- unit:defaultConfig?.unit,
- way:defaultConfig?.way,
- startTime:defaultConfig?.startTime,
- incrementPeriod:defaultConfig?.period,
- syncToBI:defaultConfig?.syncToBI,
- })
- }
- }
- }))
- if (initialValues?.expr && initialValues?.metricDefineType === "CUSTOM"){
- const expr = initialValues?.metricDefineByFieldParams?.expr
- const fields = initialValues?.metricDefineByFieldParams?.fields
- compositeRef.current = {
- expr,
- metrics:(fields||[]).map(item=>({bizName:item.fieldName})),
- }
- }
- if (initialValues?.expr && initialValues?.metricDefineType === "METRIC"){
- compositeRef.current = initialValues?.metricDefineByMetricParams
- }
- }
- }, [open,initialValues]);
- /** 主题域选择回调 */
- const handelDomainSelect =useCallback((value)=>{
- dispatch(getModals({domainId:value}));
- formRef.current?.resetFields(['modelId']);
- },[]);
- /** 切换模型时清空子数据 */
- const onFieldChange = useCallback(()=>{
- formRef.current?.resetFields([
- 'measure',
- 'dateDimId',
- 'relateDimension',
- 'formIndex',
- "attributes",
- "filters"
- ])
- },[]);
- /** 业务限定保存 */
- const onConditionSave=useCallback(async (tab,txt)=>{
- const formatValue = await formRef.current?.validateFieldsReturnFormatValue?.();
- // 组织数据
- const {filters,name,domainId,modelId} = formatValue;
- if (!domainId) {
- message.error("请先选择主题")
- return false
- }
- if (!modelId) {
- message.error("请先选择模型")
- return false
- }
- const defaultConfig = (tab==='customScript') ? txt : bizConditionToSQL(filters);
- if (defaultConfig){
- const params = {
- status:1,
- defaultConfig,
- name,
- modelId,
- domainId
- }
- dispatch(createCondition({
- params,
- resolve(){
- message.success(t("validation.success"))
- dispatch(getConditions({}))
- }
- }))
- }else {
- const errorMessage = (tab==='customScript') ? '请先编辑脚本' :'请先配置字段'
- message.error(errorMessage)
- }
- },[])
- const handleCreatorFinish=(val)=>{
- const { modelId, dateDimId, dimensionId } = val;
- let composite = compositeRef.current || '';
- if(val.type == "COMPOSITE") {
- val.dimensionId = '';
- val.dateDimId = '';
- val.modelId = Array.isArray(modelId) ? modelId.join(',') : modelId;
- const metrics = [];
- composite.metrics.forEach((v, i) =>{
- delete v.dateArr;
- delete v.analyzeArr,
- metrics.push({
- ...v,
- dateDimId: dateDimId[i] || '',
- dimensionId: dimensionId[i] ? dimensionId[i].join(',') : '',
- });
- });
- composite = {
- ...composite,
- metrics,
- }
- console.log(composite, val);
- }
- onFinish({
- id:initialValues?.id || null,
- domainId:initialValues?.domainId,
- ...val,
- conditionId:val?.conditionId || null,
- metricDefineByMetricParams: composite,
- measureExpr:composite,
- })
- }
- // 当名称改变时自动填充业务限定编码为中文首字母
- const onNameChange =(event)=>{
- const py = pinyin(event?.target?.value, { toneType: "none", type: "array" });
- let bizCode = "";
- py.forEach(p=>bizCode+=p[0].toUpperCase());
- formRef?.current?.setFieldValue('bizName',"BIZ_"+bizCode);
- }
- const onSetFields=useCallback((f,v)=> {
- formRef?.current?.setFieldValue(f,v)
- },[])
- return (
- <Drawer
- title={t(initialValues?.id?"title.metricUpdate":"title.metricCreate")}
- width={1230}
- styles={{body:{padding:'0'}}}
- open={open}
- maskClosable={false}
- destroyOnClose
- onClose={handleCancel}
- footer={[
- <Button key="previewer" style={{marginLeft:'40%'}} onClick={handleCancel} disabled={!initialValues?.id}>
- {t("button.preview")}
- </Button>,
- <Button key="upload" style={{marginLeft:15}} onClick={handleCancel} disabled={!initialValues?.id}>
- {t("button.publish")}
- </Button>,
- <Button key="submit" style={{marginLeft:15}} type="primary" onClick={()=>{formRef?.current?.submit()}}>
- {t("button.save")}
- </Button>
- ]}
- >
- <ProForm
- formRef={formRef}
- layout={formLayoutType}
- initialValues={initialValues}
- onFinish={handleCreatorFinish}
- labelCol={{ span: 4 }}
- wrapperCol={{ span: 18 }}
- submitter={false}
- >
- {/** 指标通用字段 */}
- <Card type="inner" title={t("title.baseInfo")} bordered={false}>
- <ProFormRadio.Group
- name="type"
- label={t("formItem.metricType")}
- rules={[{ required: true }]}
- valueEnum={INDEX_TYPE}
- fieldProps={{
- onChange(){
- formRef.current?.resetFields(['modelId'])
- }
- }}
- />
- <ProFormRadio.Group
- name="sensitiveLevel"
- label={t("formItem.sensitiveLevel")}
- rules={[{ required: true }]}
- valueEnum={SENSITIVE}
- />
- <ProFormText
- name="name"
- label={t("formItem.metricName")}
- rules={[{ required: true }]}
- fieldProps={{
- onChange:onNameChange
- }}
- />
- <ProFormText
- name="description"
- label={t("formItem.metricDesc")}
- />
- <ProFormText
- name="bizName"
- label={t("formItem.bizName")}
- rules={[{ required: true }]}
- />
- <ProFormTreeSelect
- name="domainId"
- label={t("formItem.domain")}
- rules={[{ required: true }]}
- request={async ()=>domains}
- fieldProps={{
- onSelect:handelDomainSelect
- }}
- />
- <ProFormTextArea
- name="alias"
- label={t("formItem.caliber")}
- rules={[{ required: true }]}
- />
- <ProFormText
- name="director"
- label={t("formItem.director")}
- rules={[{ required: true }]}
- />
- <ProFormGroup style={{marginLeft:115}}>
- <ProFormDatePicker name="createdAt" label={t("formItem.startDate")} rules={[{ required: true }]} width={pickerWidth} initialValue={initialValues?.createdAt || new Date}/>
- <ProFormDatePicker name="stopDate" label={t("formItem.stopDate")} width={pickerWidth}/>
- </ProFormGroup>
- </Card>
- <Card bordered={false} type="inner" title={t("title.metricDefine")} style={{boxShadow:'none'}}>
- <ProFormDependency name={["type"]}>
- {({ type }) => {
- switch (type) {
- case FORM_TYPE.ATOMIC.value:
- return <AtomicIndexForm initialValues={initialValues} onChange={onFieldChange} onExprChange={expr=>compositeRef.current=expr}/>
- case FORM_TYPE.DERIVED.value:
- return <DerivedIndexForm initialValues={initialValues} onSetField={onSetFields} onExprChange={expr=>compositeRef.current=expr} onChange={onFieldChange} onConditionSave={onConditionSave}/>
- case FORM_TYPE.COMPOSITE.value:
- return <CompositeIndexForm initialValues={initialValues} onChange={expr=>compositeRef.current=expr}/>
- default : return null
- }
- }}
- </ProFormDependency>
- <ProFormSelect
- name="periodId"
- label={t("formItem.period")}
- options={periods.map(item=>({label:item.name,value:item.id}))}
- rules={[{ required: true }]}
- />
- <ProFormRadio.Group
- name="invokeMethod"
- label={t("formItem.invokeMethod")}
- valueEnum={INVOKE_TYPE}
- />
- <ProFormDependency name={["invokeMethod"]}>
- {
- ({ invokeMethod }) =>
- invokeMethod==='MANUAL' && <>
- <Wrapper>
- <Title className="divider"> {t("title.invokeRule")} </Title>
- </Wrapper>
- <ProFormSelect
- name="incrementPeriod"
- label={t("formItem.incrementPeriod")}
- valueEnum={TIME_MODE}
- rules={[{ required: true }]}
- />
- <ProFormSelect
- name="runCycleCode"
- label={t("formItem.runCycle")}
- valueEnum={TIME_MODE}
- rules={[{ required: true }]}
- />
- <ProFormTimePicker name="startTime" width="100%" label={t("formItem.startTime")} initialValue={initialValues?.startTime}/>
- <ProFormRadio.Group
- name="way"
- label={t("formItem.invokeWay")}
- initialValue={initialValues?.syncToBI || 'INC'}
- options={PERSISTENCE_WAY}
- rules={[{ required: true }]}
- />
- <ProFormRadio.Group
- name="syncToBI"
- label={t("formItem.syncToBI")}
- options={CONFIRM_STATUS}
- initialValue={initialValues?.syncToBI || 0}
- rules={[{ required: true }]}
- />
- </>
- }
- </ProFormDependency>
- </Card>
- </ProForm>
- </Drawer>
- )
- })
- export const IndexCreator = memo(component);
- const Wrapper = styled.div`
- width: 100%;
- display: flex;
- align-items: center;
- box-sizing: border-box;
- `
- const Title = styled.div`
- display: inline-block;
- flex: 1;
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- box-sizing: border-box;
- text-align: center;
- font-weight: 600;
- padding-block-end: 10px;
- &.divider {
- // 添加必填红色*的样式
- &::before {
- display: inline-block;
- margin-inline-end: 4px;
- color: #bfbfbf;
- font-size: 16px;
- line-height: 1;
- content: "------------------";
- }
- &::after {
- display: inline-block;
- margin-inline-start: 4px;
- color: #bfbfbf;
- font-size: 16px;
- line-height: 1;
- content: "------------------";
- }
- }
- `
|