completepage: 🍻 文件页面删除和批量下载,修改部分页面bug
This commit is contained in:
parent
2ed9f007f0
commit
73a2e70354
|
@ -7,8 +7,13 @@ export const fetchGetFilesList = (data: any) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 系统文件管理---下载系统文件 */
|
/** 系统文件管理---下载系统文件 */
|
||||||
export const fetchDownloadFiles = (data: any) => {
|
export const downloadFilesByFileId = (data: any) => {
|
||||||
return http.request<any>('get', `files/downloadFiles/${data.id}`);
|
return http.request<any>('get', `files/downloadFilesByFileId/${data.id}`, { responseType: 'blob' });
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 系统文件管理---下载系统文件 */
|
||||||
|
export const downloadFilesByFilepath = (data: any) => {
|
||||||
|
return http.request<any>('get', `files/downloadFilesByFilepath`, { params: data, responseType: 'blob' });
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 系统文件管理---添加系统文件管理 */
|
/** 系统文件管理---添加系统文件管理 */
|
||||||
|
|
|
@ -128,11 +128,8 @@ export default defineComponent({
|
||||||
...props.options,
|
...props.options,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!result.ready) {
|
// 如果图片不存在直接将加载变为加载完成
|
||||||
isReady.value = true;
|
if (!result.ready) emit('readied', cropper.value);
|
||||||
realTimeCroppered();
|
|
||||||
emit('readied', cropper.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
cropper.value = result;
|
cropper.value = result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import userAvatarIcon from '@/assets/svg/user_avatar.svg?component';
|
|
||||||
import { columns } from './columns';
|
|
||||||
import TablePlus from '@/components/TableBar/src/TablePlus.vue';
|
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
import { fetchGetUserinfoById } from '@/api/v1/adminUser';
|
import { fetchGetUserinfoById } from '@/api/v1/adminUser';
|
||||||
|
import userAvatarIcon from '@/assets/svg/user_avatar.svg?component';
|
||||||
import { $t } from '@/plugins/i18n';
|
import { $t } from '@/plugins/i18n';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
@ -35,22 +33,42 @@ onMounted(() => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="list-card-item">
|
<div v-if="userId && userinfo" class="list-card-item bg-bg_color">
|
||||||
<div v-if="userId && userinfo" class="list-card-item_detail bg-bg_color">
|
<el-row justify="space-between">
|
||||||
<el-row justify="space-between">
|
<div class="flex flex-row justify-center items-center">
|
||||||
<div class="list-card-item_detail--logo">
|
<div class="list-card-item_detail--logo">
|
||||||
<userAvatarIcon />
|
<userAvatarIcon />
|
||||||
</div>
|
</div>
|
||||||
<el-tag :color="userinfo.status ? '#F67676' : '#00a870'" class="mx-1 list-card-item_detail--operation--tag" effect="dark">
|
<h1 class="list-card-item_detail--name">{{ $t('user_details') }}</h1>
|
||||||
{{ $t('user_status') }}:{{ userinfo.status ? $t('disable') : $t('normal') }}
|
</div>
|
||||||
</el-tag>
|
<el-tag :color="userinfo.status ? '#F67676' : '#00a870'" class="mx-1 list-card-item_detail--operation--tag" effect="dark">
|
||||||
</el-row>
|
{{ $t('user_status') }}:{{ userinfo.status ? $t('disable') : $t('normal') }}
|
||||||
|
</el-tag>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
<p class="list-card-item_detail--name text-text_color_primary">{{ $t('user_details') }}</p>
|
<el-descriptions border>
|
||||||
<TablePlus :column="columns" :data-list="[userinfo]" :loading="loading" />
|
<el-descriptions-item :label="$t('avatar')" :width="100" align="center">
|
||||||
</div>
|
<el-image :src="userinfo.avatar" style="width: 100px; height: 100px" />
|
||||||
<el-empty v-else description="无数据" />
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item :label="$t('username')" :width="100">{{ userinfo.username }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item :label="$t('nickName')" :width="100">{{ userinfo.nickName }}</el-descriptions-item>
|
||||||
|
|
||||||
|
<el-descriptions-item :label="$t('email')"> {{ userinfo.email }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item :label="$t('phone')">{{ userinfo.phone }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item :label="$t('sex')">
|
||||||
|
<el-tag v-if="userinfo.sex === 1">男</el-tag>
|
||||||
|
<el-tag v-if="userinfo.sex === 0" type="danger">女</el-tag>
|
||||||
|
</el-descriptions-item>
|
||||||
|
|
||||||
|
<el-descriptions-item :label="$t('personDescription')" span="3">
|
||||||
|
{{ userinfo.personDescription }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
|
||||||
|
<el-descriptions-item :label="$t('table.createTime')" span="1.5">{{ userinfo.createTime }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item :label="$t('table.updateTime')" span="1.5">{{ userinfo.updateTime }}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
</div>
|
</div>
|
||||||
|
<el-empty v-else :description="$t('no_data')" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@ -63,10 +81,6 @@ onMounted(() => {
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
|
||||||
&_detail {
|
&_detail {
|
||||||
flex: 1;
|
|
||||||
min-height: 140px;
|
|
||||||
padding: 24px 32px;
|
|
||||||
|
|
||||||
&--logo {
|
&--logo {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -88,27 +102,16 @@ onMounted(() => {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
&--tag {
|
&--tag {
|
||||||
|
margin: 15px 0;
|
||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&--name {
|
&--name {
|
||||||
margin: 24px 0 8px;
|
margin: 0 0 0 8px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
&--desc {
|
|
||||||
display: -webkit-box;
|
|
||||||
height: 40px;
|
|
||||||
margin-bottom: 24px;
|
|
||||||
overflow: hidden;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 20px;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
-webkit-line-clamp: 2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__disabled {
|
&__disabled {
|
||||||
|
|
|
@ -51,3 +51,24 @@ import { getQueryMap, subBefore } from '@pureadmin/utils';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量创建下载链接
|
||||||
|
* @param blob
|
||||||
|
* @param filename
|
||||||
|
*/
|
||||||
|
export function download(blob: any, filename: string) {
|
||||||
|
// 创建一个临时的 URL,用于下载文件
|
||||||
|
const a = document.createElement('a');
|
||||||
|
const url = window.URL.createObjectURL(new Blob([blob]));
|
||||||
|
a.href = url;
|
||||||
|
|
||||||
|
// 创建一个<a>元素,设置其 download 属性和 href 属性,模拟点击下载
|
||||||
|
a.download = filename;
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
|
||||||
|
// 清理创建的临时元素和 URL
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
document.body.removeChild(a);
|
||||||
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { columns } from '@/views/configuration/emailTemplate/utils/columns';
|
||||||
import PureTableBar from '@/components/TableBar/src/bar';
|
import PureTableBar from '@/components/TableBar/src/bar';
|
||||||
import AddFill from '@iconify-icons/ri/add-circle-line';
|
import AddFill from '@iconify-icons/ri/add-circle-line';
|
||||||
import PureTable from '@pureadmin/table';
|
import PureTable from '@pureadmin/table';
|
||||||
import { onAdd, onDelete, onSearch, onUpdate } from '@/views/configuration/emailTemplate/utils/hooks';
|
import { onAdd, onDelete, onDeleteBatch, onSearch, onUpdate, selectRows } from '@/views/configuration/emailTemplate/utils/hooks';
|
||||||
import Delete from '@iconify-icons/ep/delete';
|
import Delete from '@iconify-icons/ep/delete';
|
||||||
import EditPen from '@iconify-icons/ep/edit-pen';
|
import EditPen from '@iconify-icons/ep/edit-pen';
|
||||||
import Refresh from '@iconify-icons/ep/refresh';
|
import Refresh from '@iconify-icons/ep/refresh';
|
||||||
|
@ -44,6 +44,11 @@ const resetForm = async formEl => {
|
||||||
await onSearch();
|
await onSearch();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** 选择多行 */
|
||||||
|
const onSelectionChange = (rows: Array<any>) => {
|
||||||
|
selectRows.value = rows;
|
||||||
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
onSearch();
|
onSearch();
|
||||||
});
|
});
|
||||||
|
@ -73,6 +78,11 @@ onMounted(() => {
|
||||||
<PureTableBar :columns="columns" title="邮件模板表" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
<PureTableBar :columns="columns" title="邮件模板表" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
||||||
<template #buttons>
|
<template #buttons>
|
||||||
<el-button :icon="useRenderIcon(AddFill)" type="primary" @click="onAdd"> {{ $t('add_new') }}</el-button>
|
<el-button :icon="useRenderIcon(AddFill)" type="primary" @click="onAdd"> {{ $t('add_new') }}</el-button>
|
||||||
|
|
||||||
|
<!-- 批量删除按钮 -->
|
||||||
|
<el-button v-show="selectRows.length > 0" :icon="useRenderIcon(Delete)" type="danger" @click="onDeleteBatch">
|
||||||
|
{{ $t('delete_batches') }}
|
||||||
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-slot="{ size, dynamicColumns }">
|
<template v-slot="{ size, dynamicColumns }">
|
||||||
|
@ -92,6 +102,7 @@ onMounted(() => {
|
||||||
row-key="id"
|
row-key="id"
|
||||||
showOverflowTooltip
|
showOverflowTooltip
|
||||||
table-layout="auto"
|
table-layout="auto"
|
||||||
|
@selection-change="onSelectionChange"
|
||||||
@page-size-change="onPageSizeChange"
|
@page-size-change="onPageSizeChange"
|
||||||
@page-current-change="onCurrentPageChange"
|
@page-current-change="onCurrentPageChange"
|
||||||
>
|
>
|
||||||
|
|
|
@ -6,6 +6,8 @@ import { messageBox } from '@/utils/message';
|
||||||
import type { FormItemProps } from '@/views/configuration/emailTemplate/utils/types';
|
import type { FormItemProps } from '@/views/configuration/emailTemplate/utils/types';
|
||||||
import { $t } from '@/plugins/i18n';
|
import { $t } from '@/plugins/i18n';
|
||||||
|
|
||||||
|
// 选择的row列表
|
||||||
|
export const selectRows = ref([]);
|
||||||
export const formRef = ref();
|
export const formRef = ref();
|
||||||
const emailTemplateStore = useEmailTemplateStore();
|
const emailTemplateStore = useEmailTemplateStore();
|
||||||
|
|
||||||
|
@ -104,3 +106,21 @@ export const onDelete = async (row: any) => {
|
||||||
await emailTemplateStore.deleteEmailTemplate([id]);
|
await emailTemplateStore.deleteEmailTemplate([id]);
|
||||||
await onSearch();
|
await onSearch();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** 批量删除 */
|
||||||
|
export const onDeleteBatch = async () => {
|
||||||
|
const ids = selectRows.value.map((row: any) => row.id);
|
||||||
|
|
||||||
|
// 是否确认删除
|
||||||
|
const result = await messageBox({
|
||||||
|
title: $t('confirm_delete'),
|
||||||
|
showMessage: false,
|
||||||
|
confirmMessage: undefined,
|
||||||
|
cancelMessage: $t('cancel_delete'),
|
||||||
|
});
|
||||||
|
if (!result) return;
|
||||||
|
|
||||||
|
// 删除数据
|
||||||
|
await emailTemplateStore.deleteEmailTemplate(ids);
|
||||||
|
await onSearch();
|
||||||
|
};
|
||||||
|
|
|
@ -4,8 +4,9 @@ import { columns } from '@/views/monitor/files/utils/columns';
|
||||||
import PureTableBar from '@/components/TableBar/src/bar';
|
import PureTableBar from '@/components/TableBar/src/bar';
|
||||||
import AddFill from '@iconify-icons/ri/add-circle-line';
|
import AddFill from '@iconify-icons/ri/add-circle-line';
|
||||||
import PureTable from '@pureadmin/table';
|
import PureTable from '@pureadmin/table';
|
||||||
import { onAdd, onDelete, onDeleteBatch, onDownload, onSearch, onUpdate, selectIds } from '@/views/monitor/files/utils/hooks';
|
import { onAdd, onDelete, onDeleteBatch, onDownload, onDownloadBatch, onSearch, onUpdate, selectRows } from '@/views/monitor/files/utils/hooks';
|
||||||
import Delete from '@iconify-icons/ep/delete';
|
import Delete from '@iconify-icons/ep/delete';
|
||||||
|
import Download from '@iconify-icons/ep/download';
|
||||||
import EditPen from '@iconify-icons/ep/edit-pen';
|
import EditPen from '@iconify-icons/ep/edit-pen';
|
||||||
import Refresh from '@iconify-icons/ep/refresh';
|
import Refresh from '@iconify-icons/ep/refresh';
|
||||||
import { selectUserinfo } from '@/components/Table/Userinfo/columns';
|
import { selectUserinfo } from '@/components/Table/Userinfo/columns';
|
||||||
|
@ -39,7 +40,7 @@ const resetForm = async (formEl: FormInstance) => {
|
||||||
|
|
||||||
/** 选择多行 */
|
/** 选择多行 */
|
||||||
const onSelectionChange = (rows: Array<any>) => {
|
const onSelectionChange = (rows: Array<any>) => {
|
||||||
selectIds.value = rows.map((row: any) => row.id);
|
selectRows.value = rows;
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
@ -72,8 +73,13 @@ onMounted(() => {
|
||||||
<template #buttons>
|
<template #buttons>
|
||||||
<el-button :icon="useRenderIcon(AddFill)" type="primary" @click="onAdd"> {{ $t('add_new') }}</el-button>
|
<el-button :icon="useRenderIcon(AddFill)" type="primary" @click="onAdd"> {{ $t('add_new') }}</el-button>
|
||||||
|
|
||||||
|
<!-- 批量下载 -->
|
||||||
|
<el-button v-show="selectRows.length > 0" :icon="useRenderIcon(Download)" type="success" @click="onDownloadBatch">
|
||||||
|
{{ $t('download_batch') }}
|
||||||
|
</el-button>
|
||||||
|
|
||||||
<!-- 批量删除按钮 -->
|
<!-- 批量删除按钮 -->
|
||||||
<el-button v-show="selectIds.length > 0" :icon="useRenderIcon(Delete)" type="danger" @click="onDeleteBatch">
|
<el-button v-show="selectRows.length > 0" :icon="useRenderIcon(Delete)" type="danger" @click="onDeleteBatch">
|
||||||
{{ $t('delete_batches') }}
|
{{ $t('delete_batches') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -5,9 +5,11 @@ import { h, ref } from 'vue';
|
||||||
import { messageBox } from '@/utils/message';
|
import { messageBox } from '@/utils/message';
|
||||||
import type { FormItemProps } from '@/views/monitor/files/utils/types';
|
import type { FormItemProps } from '@/views/monitor/files/utils/types';
|
||||||
import { $t } from '@/plugins/i18n';
|
import { $t } from '@/plugins/i18n';
|
||||||
|
import { downloadFilesByFileId, downloadFilesByFilepath } from '@/api/v1/files';
|
||||||
|
import { download } from '@/utils/sso';
|
||||||
|
|
||||||
// 选择的id列表
|
// 选择的row列表
|
||||||
export const selectIds = ref([]);
|
export const selectRows = ref([]);
|
||||||
export const formRef = ref();
|
export const formRef = ref();
|
||||||
const filesStore = useFilesStore();
|
const filesStore = useFilesStore();
|
||||||
|
|
||||||
|
@ -109,7 +111,7 @@ export const onDelete = async (row: any) => {
|
||||||
|
|
||||||
/** 批量删除 */
|
/** 批量删除 */
|
||||||
export const onDeleteBatch = async () => {
|
export const onDeleteBatch = async () => {
|
||||||
const ids = selectIds.value;
|
const ids = selectRows.value.map(row => row.id);
|
||||||
|
|
||||||
// 是否确认删除
|
// 是否确认删除
|
||||||
const result = await messageBox({
|
const result = await messageBox({
|
||||||
|
@ -130,18 +132,16 @@ export const onDeleteBatch = async () => {
|
||||||
* @param row
|
* @param row
|
||||||
*/
|
*/
|
||||||
export const onDownload = async (row: any) => {
|
export const onDownload = async (row: any) => {
|
||||||
const id = row.id;
|
const blob = await downloadFilesByFilepath({ filepath: row.filepath });
|
||||||
|
|
||||||
fetch(`/admin/files/downloadFiles/${id}`)
|
download(blob, row.filename);
|
||||||
.then(response => response.blob()) // 将响应转换为Blob对象
|
};
|
||||||
.then(blob => {
|
|
||||||
// 创建一个链接元素
|
/** 批量下载文件 */
|
||||||
const link = document.createElement('a');
|
export const onDownloadBatch = () => {
|
||||||
link.href = URL.createObjectURL(blob);
|
selectRows.value.forEach(async row => {
|
||||||
link.download = 'filename.jpg'; // 指定下载文件名
|
const blob = await downloadFilesByFileId({ id: row.id });
|
||||||
document.body.appendChild(link);
|
|
||||||
link.click(); // 模拟点击
|
download(blob, row.filename);
|
||||||
document.body.removeChild(link); // 下载后移除元素
|
});
|
||||||
})
|
|
||||||
.catch(error => console.error('下载失败:', error));
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue