import { CnDialog, CnMessage } from '@cainiaofe/cn-ui'; import { request as requestInstance } from 'cn-request'; import get from 'lodash/get'; import { calculateRequestExecute, calculateTextExprValue, condition, executeObjectExpr, getRealRequestUrl, handleDesignMokelayUrl, handleSuccessMessage, } from './util'; import { getButtonAction, getButtonListByPosition, getButtonPrototypeListByPosition, } from '../manager/button'; import isPlainObject from 'lodash/isPlainObject'; import isFunction from 'lodash/isFunction' import { getJSExpressionPrototype } from '../manager/common-style'; import { ButtonPosition } from '@/common/manager/position/button-position'; import { AfterRequestSuccess, formUrlencoded, } from '@/common/util/const'; import qs from 'query-string'; import { getJSXTemplate } from '@/common/manager/setter-snippet'; import { __dataSource__ } from '@/common/util/expr-const'; export const createRequestSuccessPrototype = (position, config) => { const { afterRequestCondition } = config || {}; const buttonList = getButtonListByPosition(position); const buttonPrototypeList = getButtonPrototypeListByPosition(position); const configure = [ { name: 'optType', title: '请求成功后', display: 'inline', setter: { componentName: 'CnSelectSetter', props: { options: buttonList, selectProps: { hasClear: true, }, }, }, }, ]; if (buttonPrototypeList?.length > 0) { configure.push({ name: 'options', display: 'plain', title: '按钮配置项', setter: { componentName: 'ObjectSetter', props: { config: { items: [...buttonPrototypeList], }, }, }, }); } const result = { name: 'afterRequest', title: '请求成功后', display: 'plain', setter: { componentName: 'ObjectSetter', props: { config: { items: configure, }, }, }, }; if (afterRequestCondition) { result.condition = afterRequestCondition; } return result; }; export const createServiceSelectPrototype = (config) => { const { optType, paramSetter, wholeParamSetter, position, paramSelectSetter, jsExpressionSetter, paramTitleDom, dynamicUrlTemplate, } = config || {}; let confirmShowType; let hoverTip = []; if ([ButtonPosition.tableOperate].includes(position)) { confirmShowType = { name: 'confirmShowType', title: '二次确认展示效果', display: 'inline', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '弹窗(默认)', value: 'dialog' }, { title: '气泡', value: 'balloon' }, ], }, }, condition(prop) { return condition(prop, true, 'needConfirm'); }, }; } // if([ButtonPosition.tableToolArea, ButtonPosition.tableBatchArea].includes(position)) { // hoverTip = [ // { // name: 'needHover', // title: '气泡提示', // display: 'inline', // setter: { // componentName: 'BoolSetter', // }, // condition(prop) { // return condition(prop, optType, 'optType'); // }, // }, // { // name: 'hoverInfo', // display: 'plain', // title: '悬浮配置项', // condition(prop) { // return condition(prop, optType, 'optType'); // }, // setter: { // componentName: 'ObjectSetter', // props: { // config: { // items: [ // { // name: 'title', // title: '气泡提示标题', // display: 'inline', // // setter: { // // componentName: 'StringSetter', // // }, // setter: { // componentName: 'MixedSetter', // props: { // setters: [ // { // componentName: 'CnI18nSetter', // title: '字符串', // }, // paramSelectSetter, // (jsExpressionSetter || getJSExpressionPrototype({ // type: 'tableRequest', // })), // ], // }, // }, // condition(prop) { // return condition(prop, true, 'needHover'); // }, // }, // { // name: 'content', // title: '气泡提示内容', // display: 'inline', // // setter: { // // componentName: 'TextAreaSetter', // // }, // setter: { // componentName: 'MixedSetter', // props: { // setters: [ // { // componentName: 'CnI18nSetter', // title: '字符串', // }, // paramSelectSetter, // (jsExpressionSetter || getJSExpressionPrototype({ // type: 'tableRequest', // })), // getJSXTemplate({position}) // ], // }, // }, // condition(prop) { // return condition(prop, true, 'needHover'); // }, // }, // confirmShowType, // ], // }, // }, // }, // }, // ] // } const configure = [ { name: 'requestConfig', title: '查询服务', display: 'inline', setter: { componentName: 'ServiceChoiceSetter', props: { paramTitleDom, buttonText: '选择请求API', params: { env: 'pre', pageSize: 999, // serviceType: 'HSF', }, paramSetter, wholeParamSetter, dynamicUrlTemplate, }, }, condition(prop) { return condition(prop, optType, 'optType'); }, }, { name: 'needConfirm', title: '二次确认', display: 'inline', setter: { componentName: 'BoolSetter', }, condition(prop) { return condition(prop, optType, 'optType'); }, }, { name: 'confirmInfo', display: 'plain', title: '按钮配置项', condition(prop) { return condition(prop, optType, 'optType'); }, setter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'title', title: '二次确认标题', display: 'inline', // setter: { // componentName: 'StringSetter', // }, setter: { componentName: 'MixedSetter', props: { setters: [ { componentName: 'CnI18nSetter', title: '字符串', }, paramSelectSetter, jsExpressionSetter || getJSExpressionPrototype({ type: 'tableRequest', }), ], }, }, condition(prop) { return condition(prop, true, 'needConfirm'); }, }, { name: 'content', title: '二次确认内容', display: 'inline', // setter: { // componentName: 'TextAreaSetter', // }, setter: { componentName: 'MixedSetter', props: { setters: [ { componentName: 'CnI18nSetter', title: '字符串', }, paramSelectSetter, jsExpressionSetter || getJSExpressionPrototype({ type: 'tableRequest', }), getJSXTemplate({ position }), ], }, }, condition(prop) { return condition(prop, true, 'needConfirm'); }, }, confirmShowType, ], }, }, }, }, // ...hoverTip, ]; if ( [ ButtonPosition.tableOperate, ButtonPosition.tableCell, ButtonPosition.tableToolArea, ].includes(position) ) { configure.push( createRequestSuccessPrototype(position + AfterRequestSuccess), ); } if (position === ButtonPosition.tableOperate) { configure.push({ name: 'keepPagination', title: '刷新表格时保留分页信息', setter: 'BoolSetter', }); } return configure; }; export function makeRequest(config) { let { needSuccessToast = true } = config; const { handleParams, buttonConfig, record, state, recordDataSource, urlParamsDataSource, onCancel, extraParamList, isDesign, position = '', noNeedHandleResult, _context, getExtraParam, } = config; return new Promise((resolve, reject) => { if (buttonConfig) { const { options = {} } = buttonConfig; const { requestConfig, needConfirm, confirmInfo = {}, afterRequest, } = options; const sendRequest = () => { const realUrl = getRealRequestUrl({ requestConfig, state, extraParam: getExtraParam?.(), }); if (realUrl) { const execute = calculateRequestExecute( requestConfig, { [__dataSource__]: state, }, {}, state, ); if (execute === false) { reject(); return; } requestInstance( transRequestConfigToRemote({ requestConfig, handleParams, state, urlParamsDataSource, recordDataSource, isDesign, extraParamList, getExtraParam, }), ) .then((res) => { let result = getRealResponse(res); if (!noNeedHandleResult) { result = handleResultProcessFunc2(res, requestConfig, { state, }); } const { success, errorCode, errorMsg } = result; if (success) { if (afterRequest?.optType) { const pos = position + AfterRequestSuccess; const action = getButtonAction({ ...afterRequest, position: pos, }); if (action) { needSuccessToast = false; action?.({ position: pos, urlParamsDataSource, recordDataSource, state, buttonConfig: afterRequest, response: result, _context, }); } } resolve(result); if (needSuccessToast) { handleSuccessMessage(result); } } else { reject(result); if (!res?.hadShowErrorFeedback) { CnMessage.error(errorMsg || errorCode || `${requestConfig?.url} 请求异常`); } } }) .catch((err) => { reject(err); // const {errorCode, errorMsg } = err || {} // CnMessage.error(errorMsg || errorCode || `${requestConfig?.url} 请求异常`); }); } }; if (needConfirm) { const title = calculateTextExprValue(confirmInfo.title, { urlParamsDataSource, recordDataSource, state, extraParamList, }); const content = calculateTextExprValue(confirmInfo.content, { urlParamsDataSource, recordDataSource, state, extraParamList, }); CnDialog.confirm({ title: title || '通知', content: content || '', messageProps: { className: 'l2-dialog-message-content', }, onOk: () => { sendRequest(); }, onCancel: () => { onCancel && onCancel(); reject() }, onClose: () => { onCancel && onCancel(); reject() }, // cancelProps: { // // children: '关闭弹窗', // }, }); } else { sendRequest(); } } }); } export function transRequestConfigToRemote(config = {}) { const { requestConfig, handleParams, isDesign, urlParamsDataSource, recordDataSource, state, extraParamList, getExtraParam, needFormatResult, noQsStringifyFormatting, refreshDeps, formatParam, } = config; if (requestConfig) { const realUrl = getRealRequestUrl({ requestConfig, state, extraParam: getExtraParam?.(), }); const { url, params = [], serviceType, method, contentType, timeout, } = requestConfig; const temp = { url, method: 'post', data: {}, }; if (realUrl) { temp.url = realUrl; } if (formatParam) { temp.formatParam = formatParam; } if (refreshDeps) { temp.refreshDeps = refreshDeps; } if (timeout) { temp.timeout = timeout; } if (isDesign && serviceType === 'mokelay') { temp.url = handleDesignMokelayUrl(temp.url); } if (serviceType === 'http') { temp.withCredentials = true; } if (typeof handleParams === 'function') { temp.data = handleParams(temp.data); } const realParams = handleRequestParams(params, { urlParamsDataSource, recordDataSource, state, extraParamList, getExtraParam, flexibleParams: true, }); if (typeof realParams === 'function') { temp.data = realParams(); } else if (Object.keys(realParams).length > 0) { temp.data = { ...temp.data, ...realParams }; } if (serviceType === 'http') { if (method) { temp.method = method; } if (contentType === formUrlencoded) { temp.headers = { 'content-type': contentType, }; if ( temp.method === 'post' && isPlainObject(temp.data) && !noQsStringifyFormatting ) { temp.data = qs.stringify(temp.data); } } } if (temp.method === 'get') { temp.params = temp.data; delete temp.data; } if (needFormatResult === true) { temp.formatResult = handleResultProcessFunc(requestConfig); } return temp; } else { return {}; } } export function handleRequestParams(params, config: any = {}) { let result = {}; const { flexibleParams = false } = config; if (params && params.length > 0) { params.forEach((item) => { if (item) { const { label, value } = item; if (label && value !== undefined) { result[label] = calculateTextExprValue(value, config); } } }); } else if (typeof params === 'function') { const temp = calculateTextExprValue(params, config); if (isPlainObject(temp) || (isFunction(temp) && flexibleParams)) { result = temp; } } return result; } export function getRealResponse(res = {}) { const { status, data } = res; let result = res; if (status === 200 && data) { result = data; } return result; } export function handleResultProcessFunc(requestConfig) { if (requestConfig) { const { resultProcessFunc, serviceType, mockData } = requestConfig; if (typeof resultProcessFunc === 'function') { return (res, state) => { let newRes = getRealResponse(res); try { const temp = resultProcessFunc(newRes, state); if (temp && temp.data && temp.success !== undefined) { newRes = temp.data; } else { newRes = temp; } } catch (e) { console.error('请求结果回调执行失败', e); } return newRes; }; } else if (serviceType === 'mock' && isPlainObject(mockData)) { return () => { return mockData?.data; }; } else { return (res) => { if (res?.data) { return res.data; } return res; }; } } } export function handleResultProcessFunc2(response, requestConfig, extra) { const { state } = extra || {}; let newRes = getRealResponse(response); if (requestConfig) { const { resultProcessFunc, serviceType, mockData } = requestConfig; if ( typeof resultProcessFunc === 'function' && (serviceType === 'mokelay' || serviceType === 'http') ) { try { if (isPlainObject(state)) { newRes = resultProcessFunc(newRes, state); } else { newRes = resultProcessFunc(newRes); } } catch (e) { console.error('请求结果回调执行失败', e); } return newRes; } else if (serviceType === 'mock' && isPlainObject(mockData)) { return mockData; } } return newRes; }