You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

376 lines
11 KiB

4 months ago
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选中行数据
4 months ago
state?: String; // edit 为编辑态 其他为编辑中
extra?: Recordable;
}
/**
* step1:检测route
* step2:检测apihandle先行请求apihandle则执行
* step3:检测confirmstep2
*/
interface actionParams {
reload?: Function;
clearCheck?: Function;
4 months ago
}
export function useAction(actionParams: actionParams = {}) {
const router = useRouter();
const route = useRoute();
const { reload, clearCheck } = actionParams;
4 months ago
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,
4 months ago
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,
4 months ago
};
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);
}
4 months ago
if (isReload) {
isFunction(reload) && reload();
}
if (isClearCheck) {
isFunction(clearCheck) && clearCheck();
}
4 months ago
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,
};
}