Files
SaaS-lib/lib/use/use-action.ts

376 lines
11 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { createVNode, inject } from 'vue';
import { NsMessage } from '../component/message';
import { NsModal } from '../component/modal';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { useRouter, useRoute } from 'vue-router';
import { cloneDeep, isBoolean, isEmpty, isFunction, isString, isUndefined } from 'lodash-es';
import { useParams } from '/nerv-lib/use/use-params';
import { usePath } from '/nerv-lib/use/use-path';
import { useApi } from '/nerv-lib/use/use-api';
import type { AxiosRequestConfig } from 'axios';
import { authorizationService } from '/nerv-base/store/modules/authorization-service';
import { stringUtil } from '/nerv-lib/util/string-util';
import { appConfigStore } from '/nerv-base/store/modules/app-config';
import { xlsxExport, xlsxImport } from '/nerv-lib/util/xlsx-util';
export interface Confirm {
title: string; // 弹窗标题
content: string; // 弹窗内容
icon: string; //弹窗图标
okButtonProps: object;
okText: string; //确定按钮文本
}
export interface Action {
label: string; //操作中文名
name: string; //操作英文名
openPermission?: boolean; // true则不鉴权
checkApi?: string | Function | AxiosRequestConfig; // 检查api
checkDynamicParams?: string | Array<string> | object; //check api传参 || url传参
checkDefaultParams?: object; //check默认参数 固定值
route?: string | Recordable; // 配置了路由则直接跳转
confirm?: boolean | Confirm; //先弹窗再操作, true则使用默认显示方案
showSuccess?: Boolean;
api?: string | Function | AxiosRequestConfig; // 自动请求api
dynamicParams?: string | Array<string> | object; //api传参 || url传参
defaultParams?: object; //默认参数 固定值
handle?: Function; //自定义回调,路由模式不触发
finalHandle?: Function; //最终执行的函数
ifShow?: boolean | Function; //显示依赖
type?: string; //按钮 primary | ghost | dashed | link | text | default
dynamicDisabled?: boolean | Function;
isReload?: boolean;
isClearCheck?: boolean; // 清空table选中行数据
state?: String; // edit 为编辑态 其他为编辑中
extra?: Recordable;
}
/**
* step1:检测route有则直接跳转。
* step2:检测api有则设置handle先行请求api请求成功有默认handle则执行。
* step3:检测confirm有则先弹窗再执行step2
*/
interface actionParams {
reload?: Function;
clearCheck?: Function;
}
export function useAction(actionParams: actionParams = {}) {
const router = useRouter();
const route = useRoute();
const { reload, clearCheck } = actionParams;
const { getPath } = usePath();
const { httpRequest } = useApi();
const authService = authorizationService();
const appConfig = appConfigStore();
//todo 类型定义需简化
const { tableEdit, tableSave, tableCancel, addRow, validate, getValue, getKey, tableDelete } =
inject('tableEdit', {
tableEdit: () => {},
tableSave: () => {},
tableCancel: () => {},
addRow: () => {},
validate: () => {},
getValue: () => {},
getKey: () => {},
tableDelete: () => {},
}) as {
tableEdit: Function;
tableSave: Function;
tableCancel: Function;
addRow: Function;
validate: Function;
getValue: Function;
getKey: Function;
tableDelete: Function;
};
function isIfShow(action: Action, data: any): boolean {
const ifShow = action.ifShow;
if (isBoolean(ifShow)) return ifShow;
if (isFunction(ifShow)) return ifShow(data);
return true;
}
function hasPermission(action: Action, data: any) {
//todo 临时处理saas不鉴权
if (__APP_INFO__.serviceMode === 'saas') {
if (action.children) {
return true;
}
if (action.openPermission) return true;
return authService.checkAllPermission(action.name);
}
if (action.openPermission) return true;
if (!appConfig.actionPermission) {
return true;
}
if (isUndefined(route.name) || isUndefined(route.matched[0].name)) {
console.error('route name is required');
}
const { projectName } = route.params;
//处理IASSAction判断
if (data && data.viewInfo && Array.isArray(data.viewInfo.actions)) {
return data.viewInfo.actions.includes(action.name);
} else {
return authService.checkPermission(
route.meta?.app ? route.meta?.app : (route.matched[0].name as string),
route.meta?.bindView ? route.meta?.bindView : (route.name as string),
stringUtil.firstToLower(
action.name.replace(
route.meta?.bindView ? route.meta?.bindView : (route.name as string),
'',
),
),
data.projectName || projectName,
);
}
}
function filterAction(action: Action, data: any) {
const { state } = action;
let stateShow = true;
if (state && state !== 'add') {
if (getValue(getKey(data))) {
stateShow = state === 'edit' || isUndefined(state) ? false : true;
} else {
stateShow = state === 'edit' || isUndefined(state) ? true : false;
}
}
return stateShow && hasPermission(action, data) && isIfShow(action, data);
}
function filterActionNoAuth(action: Action, data: any) {
const { state } = action;
let stateShow = true;
if (state && state !== 'add') {
if (getValue(getKey(data))) {
stateShow = state === 'edit' || isUndefined(state) ? false : true;
} else {
stateShow = state === 'edit' || isUndefined(state) ? true : false;
}
}
return stateShow && isIfShow(action, data);
}
function transformAction(action: Action, data: any) {
const {
label,
name,
state,
route: toRoute,
api,
dynamicParams,
defaultParams,
showSuccess,
confirm,
checkApi,
checkDynamicParams,
checkDefaultParams,
handle,
isReload = false,
isClearCheck = false,
extra,
} = action;
const { getParams } = useParams();
const tableDynamicDisabledAction = ['deletes', 'exports']; //表格默认动态禁用操作
let { dynamicDisabled } = action;
const extraData = { router, reload, action }; // handle传出数据
if (tableDynamicDisabledAction.includes(name)) {
dynamicDisabled = (data: any) => {
return data.list.length === 0;
};
}
if (dynamicDisabled) {
if (isFunction(dynamicDisabled)) {
action.dynamicDisabled = dynamicDisabled(data);
}
} else {
action.dynamicDisabled = false;
}
if (state === 'edit') {
action.finalHandle = () => {
tableEdit(getKey(data));
};
return action;
}
if (state === 'save') {
action.finalHandle = () => {
console.log('save', getKey(data));
validate(getKey(data))
.then(() => {
tableSave(getKey(data));
})
.catch((_: any) => {});
};
return action;
}
if (state === 'cancel') {
action.finalHandle = () => {
console.log('cancel', getKey(data));
tableCancel(getKey(data));
};
return action;
}
if (state === 'delete') {
action.finalHandle = () => {
console.log("state === 'delete'", getKey(data));
tableDelete(getKey(data));
};
return action;
}
if (state === 'add') {
action.finalHandle = () => {
addRow(data);
};
return action;
}
const handleList: Recordable = {
confirm: null,
checkApi: null,
route: null,
api: null,
handle,
isReload,
isClearCheck,
};
let modelInstance: Recordable = {};
if (name && name.toLowerCase().includes('exports')) {
action.finalHandle = () => {
xlsxExport({ data: data.list, ...extra } as any);
};
return action;
}
if (name && name.toLowerCase().includes('import')) {
if (!action.handle) {
action.finalHandle = () => {
xlsxImport({ ...extra, reload } as any);
};
return action;
}
}
function routeGo(toRoute: any) {
const query = getParams(data, dynamicParams, defaultParams);
if (isString(toRoute)) {
router.push({ path: getPath(toRoute, data), query });
} else {
if (toRoute.path) {
toRoute.path = getPath(toRoute.path, data);
toRoute.query = query;
}
if (toRoute.name) {
toRoute.query = query;
}
router.push(toRoute);
}
}
if (checkApi) {
handleList.checkApi = () => {
const params = getParams(data, checkDynamicParams, checkDefaultParams);
const requestConfig: AxiosRequestConfig = { method: 'get' };
return httpRequest({ api: checkApi, params, pathParams: data, requestConfig });
};
}
if (api) {
handleList.api = () => {
const params = getParams(data, dynamicParams, defaultParams);
const requestConfig: AxiosRequestConfig = { method: 'post' };
if (__APP_INFO__.serviceMode === 'saas') {
if (requestConfig.headers) {
requestConfig.headers.resourceCode = action.name;
} else {
requestConfig.headers = {
resourceCode: action.name,
};
}
}
console.log('eeee', requestConfig);
return httpRequest({ api, params, pathParams: data, requestConfig }).then(() => {
showSuccess !== false && NsMessage.success(`${label}成功`);
});
};
}
//todo router name支持
if (toRoute) {
handleList.route = () => {
return routeGo(toRoute);
};
}
const modeUpdate = (prop: Recordable) => {
if (!isEmpty(modelInstance)) {
modelInstance.update(prop);
}
};
action.finalHandle = async () => {
modeUpdate({
okButtonProps: {
disabled: true,
},
});
if (handleList.checkApi) await handleList.checkApi();
if (handleList.route) return handleList.route();
if (handleList.api) await handleList.api();
// handleList.api && showSuccess !== false && NsMessage.success(`${label}成功`);
try {
if (handleList.handle) await handleList.handle(data, name, { ...extraData });
} catch (error) {
console.log(error);
}
if (isReload) {
isFunction(reload) && reload();
}
if (isClearCheck) {
isFunction(clearCheck) && clearCheck();
}
setTimeout(() => {
modeUpdate({
okButtonProps: {
disabled: false,
},
});
}, 100);
};
if (confirm) {
const _finalHandle: any = action.finalHandle;
const { title, content, icon, okText, okButtonProps } = confirm as Confirm;
action.finalHandle = () => {
modelInstance = NsModal.confirm({
title: title || '警告',
content: content || `确定要${label}吗?`,
icon: icon || createVNode(ExclamationCircleOutlined),
okText: okText || '确认',
cancelText: '取消',
okButtonProps,
onOk: _finalHandle,
});
};
}
return action;
}
return {
filterAction,
filterActionNoAuth,
transformAction,
};
}