init
This commit is contained in:
29
src/hooks/dict.ts
Normal file
29
src/hooks/dict.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { dict } from '/@/stores/dict';
|
||||
import { getDicts } from '/@/api/admin/dict';
|
||||
import { ref, toRefs } from 'vue';
|
||||
|
||||
/**
|
||||
* 获取字典数据
|
||||
*/
|
||||
export function useDict(...args: any): any {
|
||||
const res = ref({});
|
||||
return (() => {
|
||||
args.forEach((dictType: String) => {
|
||||
// @ts-ignore
|
||||
res.value[dictType] = [];
|
||||
const dicts = dict().getDict(dictType);
|
||||
if (dicts) {
|
||||
// @ts-ignore
|
||||
res.value[dictType] = dicts;
|
||||
} else {
|
||||
getDicts(dictType).then((resp) => {
|
||||
// @ts-ignore
|
||||
res.value[dictType] = resp.data.map((p: any) => ({ label: p.label, value: p.value, elTagType: p.listClass, elTagClass: p.cssClass }));
|
||||
// @ts-ignore
|
||||
dict().setDict(dictType, res.value[dictType]);
|
||||
});
|
||||
}
|
||||
});
|
||||
return toRefs(res.value);
|
||||
})();
|
||||
}
|
||||
103
src/hooks/message.ts
Normal file
103
src/hooks/message.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { i18n } from '../i18n';
|
||||
|
||||
const { t } = i18n.global;
|
||||
|
||||
const defaultOptions = {
|
||||
duration: 3000, // 显示时间为3秒
|
||||
showClose: true, // 显示关闭按钮
|
||||
offset: 20, // 消息距离顶部的偏移量
|
||||
};
|
||||
|
||||
interface MessageImplements {
|
||||
info(title: string): void;
|
||||
warning(title: string): void;
|
||||
success(title: string): void;
|
||||
error(title: string): void;
|
||||
}
|
||||
|
||||
export function useMessage() {
|
||||
class MessageClass implements MessageImplements {
|
||||
// 普通提示
|
||||
info(title: string): void {
|
||||
ElMessage({
|
||||
...defaultOptions,
|
||||
message: title,
|
||||
type: 'info',
|
||||
});
|
||||
}
|
||||
|
||||
// 警告提示
|
||||
warning(title: string): void {
|
||||
ElMessage({
|
||||
...defaultOptions,
|
||||
message: title,
|
||||
type: 'warning',
|
||||
});
|
||||
}
|
||||
|
||||
// 成功提示
|
||||
success(title: string): void {
|
||||
ElMessage({
|
||||
...defaultOptions,
|
||||
message: title,
|
||||
type: 'success',
|
||||
});
|
||||
}
|
||||
|
||||
// 错误提示
|
||||
error(title: string): void {
|
||||
ElMessage({
|
||||
...defaultOptions,
|
||||
message: title,
|
||||
type: 'error',
|
||||
duration: 2000, // 错误提示显示时间延长到5秒
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return new MessageClass();
|
||||
}
|
||||
|
||||
export function useMessageBox() {
|
||||
class MessageBoxClass implements MessageImplements {
|
||||
// 普通提示
|
||||
info(msg: string): void {
|
||||
ElMessageBox.alert(msg, t('message.box.title'));
|
||||
}
|
||||
|
||||
// 警告提示
|
||||
warning(msg: string): void {
|
||||
ElMessageBox.alert(msg, t('message.box.title'), { type: 'warning' });
|
||||
}
|
||||
|
||||
// 成功提示
|
||||
success(msg: string): void {
|
||||
ElMessageBox.alert(msg, t('message.box.title'), { type: 'success' });
|
||||
}
|
||||
|
||||
// 错误提示
|
||||
error(msg: string): void {
|
||||
ElMessageBox.alert(msg, t('message.box.title'), { type: 'error' });
|
||||
}
|
||||
|
||||
// 确认窗体
|
||||
confirm(msg: string) {
|
||||
return ElMessageBox.confirm(msg, t('message.box.title'), {
|
||||
confirmButtonText: t('common.confirmButtonText'),
|
||||
cancelButtonText: t('common.cancelButtonText'),
|
||||
type: 'warning',
|
||||
});
|
||||
}
|
||||
// 提交内容
|
||||
prompt(msg: string) {
|
||||
return ElMessageBox.prompt(msg, t('message.box.title'), {
|
||||
confirmButtonText: t('common.confirmButtonText'),
|
||||
cancelButtonText: t('common.cancelButtonText'),
|
||||
type: 'warning',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return new MessageBoxClass();
|
||||
}
|
||||
27
src/hooks/param.ts
Normal file
27
src/hooks/param.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { param } from '/@/stores/param';
|
||||
import { getValue } from '/@/api/admin/param';
|
||||
import { ref } from 'vue';
|
||||
|
||||
/**
|
||||
* 获取参数数据
|
||||
* @function
|
||||
* @param {string} paramType - 参数类型
|
||||
* @returns {object} - 返回参数数据引用对象
|
||||
*/
|
||||
export function useParam(paramType: string) {
|
||||
const paramValue = ref('');
|
||||
|
||||
const cachedParams = param().getParam(paramType);
|
||||
if (cachedParams) {
|
||||
paramValue.value = cachedParams;
|
||||
} else {
|
||||
getValue(paramType).then(({ data }) => {
|
||||
if (data) {
|
||||
paramValue.value = data;
|
||||
param().setParam(paramType, data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return paramValue;
|
||||
}
|
||||
260
src/hooks/table.ts
Normal file
260
src/hooks/table.ts
Normal file
@@ -0,0 +1,260 @@
|
||||
import { CellStyle, ElMessage } from 'element-plus';
|
||||
import other from '/@/utils/other';
|
||||
|
||||
/**
|
||||
* 表格组件基础配置属性
|
||||
*/
|
||||
export interface BasicTableProps {
|
||||
// 是否在创建页面时即调用数据列表接口,默认为true
|
||||
createdIsNeed?: boolean;
|
||||
// 是否需要分页,默认为true
|
||||
isPage?: boolean;
|
||||
// 查询条件表单对象,类型为any
|
||||
queryForm?: any;
|
||||
// 数据列表数组
|
||||
dataList?: any[];
|
||||
// 分页属性对象
|
||||
pagination?: Pagination;
|
||||
// 数据列表,loading状态标志,默认为false
|
||||
dataListLoading?: boolean;
|
||||
// 数据列表多选项数组
|
||||
dataListSelections?: any[];
|
||||
// 数据列表查询接口api方法,接收任意数量参数,返回Promise
|
||||
pageList?: (...arg: any) => Promise<any>;
|
||||
// loading标志,默认为false
|
||||
loading?: Boolean;
|
||||
// 多选结果数组
|
||||
selectObjs?: any[];
|
||||
// 排序字段数组
|
||||
descs?: string[];
|
||||
// 排序方式数组
|
||||
ascs?: string[];
|
||||
// props属性对象,类型为any
|
||||
props?: any;
|
||||
validate?: Function;
|
||||
// 回调事件,类型为any
|
||||
onLoaded?: Function;
|
||||
// 回调事件,类型为any
|
||||
onCascaded?: Function;
|
||||
// 转义数据
|
||||
dicData?: any;
|
||||
// 转义数据
|
||||
cascadeDic?: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* 表格样式。
|
||||
*/
|
||||
export interface TableStyle {
|
||||
cellStyle: CellStyle<any>;
|
||||
headerCellStyle: CellStyle<any>;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页属性配置接口
|
||||
*/
|
||||
export interface Pagination {
|
||||
// 当前页码,默认为1
|
||||
current?: number;
|
||||
// 每页显示条数,默认为10
|
||||
size?: number;
|
||||
// 总条数,默认为0
|
||||
total?: number;
|
||||
// 每页显示条数选择器的选项数组,默认为[10,20,30,40]
|
||||
pageSizes?: any[];
|
||||
// 分页组件布局方式,可选值有 total,sizes,prev,jump,next,默认为'total,sizes,prev,jump,next'
|
||||
layout?: String;
|
||||
}
|
||||
|
||||
export function useTable(options?: BasicTableProps) {
|
||||
const defaultOptions: BasicTableProps = {
|
||||
// 列表数据是否正在加载中,默认为false
|
||||
dataListLoading: false,
|
||||
// 是否需要自动请求创建接口来获取表格数据,默认为true
|
||||
createdIsNeed: true,
|
||||
// 是否展示分页组件,默认为true
|
||||
isPage: true,
|
||||
// 查询表单对象,用于提交条件查询时的参数传递,默认为空对象
|
||||
queryForm: {},
|
||||
// 表格展示的数据数组,默认为空数组
|
||||
dataList: [],
|
||||
// 分页组件属性配置,如当前页码、每页展示数据条数等,默认值为 {current:1, size:10,total:0,pageSizes:[1, 10, 20, 50, 100, 200],layout:'total, sizes, prev, pager, next, jumper'}
|
||||
pagination: {
|
||||
current: 1,
|
||||
size: 10,
|
||||
total: 0,
|
||||
pageSizes: [1, 10, 20, 50, 100, 200],
|
||||
layout: 'total, sizes, prev, pager, next, jumper',
|
||||
} as Pagination,
|
||||
// 当前选中的数据项,默认为空数组
|
||||
dataListSelections: [],
|
||||
// 是否正在从服务器加载数据,默认为false
|
||||
loading: false,
|
||||
// 表格数据项的选择数据,默认为空数组
|
||||
selectObjs: [],
|
||||
// 排序时使用的字段名数组,如 ['id','name'],默认为空数组
|
||||
descs: [],
|
||||
// 排序方向数组,如 ['asc', 'desc'],默认为空数组
|
||||
ascs: [],
|
||||
// props属性配置对象,用于自定义数据属性,默认值为 {item:'records',totalCount:'total'}
|
||||
props: {
|
||||
item: 'records',
|
||||
totalCount: 'total',
|
||||
},
|
||||
// 转义数据
|
||||
dicData: {},
|
||||
// 转义数据
|
||||
cascadeDic: {}
|
||||
};
|
||||
|
||||
/**
|
||||
* 合并默认属性配置和自定义属性配置
|
||||
* @param options 默认属性配置对象
|
||||
* @param props 自定义属性配置对象
|
||||
* @returns 合并后的属性配置对象
|
||||
*/
|
||||
const mergeDefaultOptions = (options: any, props: any): BasicTableProps => {
|
||||
for (const key in options) {
|
||||
if (!Object.getOwnPropertyDescriptor(props, key)) {
|
||||
props[key] = options[key];
|
||||
}
|
||||
}
|
||||
return props;
|
||||
};
|
||||
|
||||
// 覆盖默认值
|
||||
const state = mergeDefaultOptions(defaultOptions, options);
|
||||
|
||||
/**
|
||||
* 发起分页查询,并设置表格数据和分页信息
|
||||
*/
|
||||
const query = async () => {
|
||||
// 判断是否存在state.pageList属性
|
||||
if (state.pageList) {
|
||||
if (state.validate) {
|
||||
let isPass = await state.validate(state);
|
||||
if (!isPass) return
|
||||
}
|
||||
try {
|
||||
// 开始加载数据,设置state.loading为true
|
||||
state.loading = true;
|
||||
|
||||
// 调用state.pageList方法发起分页查询
|
||||
const res = await state.pageList({
|
||||
...state.queryForm,
|
||||
current: state.pagination?.current,
|
||||
size: state.pagination?.size,
|
||||
descs: state.descs?.join(','),
|
||||
ascs: state.ascs?.join(','),
|
||||
});
|
||||
|
||||
// 设置表格展示的数据数组
|
||||
state.dataList = state.isPage ? res.data[state.props.item] : res.data;
|
||||
// 设置分页信息中的总数据条数
|
||||
state.pagination!.total = state.isPage ? res.data[state.props.totalCount] : 0;
|
||||
// 执行回调事件
|
||||
if (state.onLoaded) await state.onLoaded(state);
|
||||
if (state.onCascaded) await state.onCascaded(state);
|
||||
} catch (err: any) {
|
||||
// 捕获异常并显示错误提示
|
||||
ElMessage.error(err.msg || err.data.msg);
|
||||
} finally {
|
||||
// 结束加载数据,设置state.loading为false
|
||||
state.loading = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
if (state.createdIsNeed) {
|
||||
query();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 分页大小改变事件处理函数
|
||||
* @param val 新的分页大小
|
||||
*/
|
||||
const sizeChangeHandle = (val: number) => {
|
||||
// 修改state.pagination中的size属性
|
||||
state.pagination!.size = val;
|
||||
// 再次发起查询操作
|
||||
query();
|
||||
};
|
||||
|
||||
/**
|
||||
* 当前页码改变事件处理函数
|
||||
* @param val 新的页码
|
||||
*/
|
||||
const currentChangeHandle = (val: number) => {
|
||||
// 修改state.pagination中的current属性
|
||||
state.pagination!.current = val;
|
||||
// 再次发起查询操作
|
||||
query();
|
||||
};
|
||||
|
||||
// 排序触发事件
|
||||
const sortChangeHandle = (column: any) => {
|
||||
const prop = other.toUnderline(column.prop);
|
||||
|
||||
// First remove the property from both arrays to avoid duplicates
|
||||
state.ascs = state.ascs?.filter((item) => item !== prop) || [];
|
||||
state.descs = state.descs?.filter((item) => item !== prop) || [];
|
||||
|
||||
// Then add to the appropriate array based on sort direction
|
||||
if (column.order === 'descending') {
|
||||
state.descs?.push(prop);
|
||||
} else if (column.order === 'ascending') {
|
||||
state.ascs?.push(prop);
|
||||
}
|
||||
|
||||
query();
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取数据列表,并可选择是否刷新当前页码
|
||||
* 刷新后不跳转第一页,则入参 getDataList(false)
|
||||
* @param refresh 是否刷新当前页码
|
||||
*/
|
||||
const getDataList = (refresh?: any) => {
|
||||
// 如果需要刷新,则将state.pagination.current重置为1
|
||||
if (refresh !== false) {
|
||||
state.pagination!.current = 1;
|
||||
}
|
||||
// 再次发起查询操作
|
||||
query();
|
||||
};
|
||||
|
||||
/**
|
||||
* 下载文件
|
||||
* @param url 文件下载地址
|
||||
* @param query 请求参数(可能包含token)
|
||||
* @param fileName 文件名
|
||||
* @returns 返回一个Promise对象,用于异步处理结果
|
||||
*/
|
||||
const downBlobFile = (url: string, query: any, fileName: string) => {
|
||||
return other.downBlobFile(url, query, fileName);
|
||||
};
|
||||
|
||||
/**
|
||||
* 定义表格通用样式
|
||||
* @returns css
|
||||
*/
|
||||
const tableStyle: TableStyle = {
|
||||
cellStyle: { textAlign: 'center' },
|
||||
headerCellStyle: {
|
||||
textAlign: 'center',
|
||||
background: 'var(--el-table-row-hover-bg-color)',
|
||||
color: 'var(--el-text-color-primary)',
|
||||
},
|
||||
};
|
||||
|
||||
return {
|
||||
tableStyle,
|
||||
getDataList,
|
||||
sizeChangeHandle,
|
||||
currentChangeHandle,
|
||||
sortChangeHandle,
|
||||
downBlobFile,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user