Files
geg-gas-web/src/views/generator/desktop/index.vue

393 lines
11 KiB
Vue
Raw Normal View History

2024-02-05 09:15:37 +08:00
<template>
<PageLayout
:title="t('桌面设计')"
:searchConfig="searchConfig"
@search="search"
@scroll-height="scrollHeight"
>
<template #search> </template>
<template #operation>
<div class="button-box">
<a-button @click.stop="handleAdd" type="primary" v-auth="'desktop:add'">{{
t('新增')
}}</a-button>
</div>
</template>
<template #right>
<div v-if="data.dataSource.length > 0">
<div
class="list-box"
:style="{ overflowY: 'auto', maxHeight: tableOptions.scrollHeight + 70 + 'px' }"
:key="data.renderKey"
>
<div class="item" v-for="(item, index) in data.dataSource" :key="index">
<div class="image"><img :src="item.backgroundUrlFixed || item.backgroundUrl" /></div>
2024-02-05 09:15:37 +08:00
<div class="edit" @click.stop="handleEdit(item.id)">{{ t('设计') }}</div>
<div class="mark">
<a-switch
v-model:checked="item.enabledMark"
:checkedValue="1"
:unCheckedValue="0"
:checked-children="t('已启用')"
:un-checked-children="t('已禁用')"
:disabled="item.isFirst === 1"
@change="changeEnabledMark(item)"
/>
</div>
<div class="main">
<span class="name">{{ item.name }}</span>
<div class="menu-list">
<Tag v-if="item.isFirst === 1" style="background: transparent; color: #fff"
>默认首页</Tag
>
<template v-else>
<a-tooltip placement="bottom" @click="handleFirst(item.id)">
<template #title>
<span>{{ t('设为默认首页') }}</span>
</template>
<Icon icon="ant-design:desktop-outlined" class="menu-item" />
</a-tooltip>
<a-popconfirm :title="t('确定删除吗?')" @confirm="handleDelete(item.id)">
<a-tooltip placement="bottom">
<template #title>
<span>{{ t('删除') }}</span>
</template>
<Icon icon="ant-design:delete-outlined" class="menu-item" />
</a-tooltip>
</a-popconfirm>
</template>
<a-tooltip placement="bottom" @click="handlePreview(item.id)">
<template #title>
<span>{{ t('查看') }}</span>
</template>
<Icon icon="ant-design:eye-outlined" class="menu-item" />
</a-tooltip>
<a-tooltip placement="bottom" @click="copy(item.id)">
<template #title>
<span>{{ t('复制') }}</span>
</template>
<Icon icon="ant-design:copy-outlined" class="menu-item" />
</a-tooltip>
<a-tooltip placement="bottom" @click="handleDownByData(item)">
<template #title>
<span>{{ t('导出') }}</span>
</template>
<Icon icon="ant-design:arrow-down-outlined" class="menu-item" />
</a-tooltip>
<a-tooltip placement="bottom" @click="showHistory(item.id)">
<template #title>
<span>{{ t('历史') }}</span>
</template>
<Icon icon="ant-design:history-outlined" class="menu-item" />
</a-tooltip>
</div>
</div>
</div>
</div>
<div class="page-box">
<a-pagination
size="small"
v-model:current="data.pagination.current"
:pageSize="data.pagination.pageSize"
:total="data.pagination.total"
show-less-items
@change="getList"
:show-total="(total) => t(`共 ${total} 条数据`)"
show-size-changer
show-quick-jumper
:page-size-options="['10', '20', '50', '80', '100']"
/>
</div>
</div>
<div v-else>
<EmptyBox />
</div>
<DesktopDesign v-if="data.desktopDesignVisible" :editId="data.editId" @close="handleClose" />
<DesktopPreview
v-if="data.previewVisible"
ref="previewRef"
:list="data.list"
@close="data.previewVisible = false"
/>
<a-drawer
size="large"
v-model:visible="data.historyVisible"
:title="t('历史记录')"
placement="right"
>
<DesktopHistory v-if="data.historyVisible" :id="data.historyId" />
</a-drawer>
</template>
</PageLayout>
</template>
<script lang="ts" setup>
import { onMounted, reactive, defineAsyncComponent } from 'vue';
import { Icon } from '/@/components/Icon/index';
import DesktopHistory from './components/DesktopHistory.vue';
import { DesktopPageModel } from '/@/api/desktop/model';
import { PageLayout, EmptyBox } from '/@/components/ModalPanel';
import userTableScrollHeight from '/@/hooks/setting/userTableScrollHeight';
import { LoadingBox } from '/@/components/ModalPanel';
import { notification, Tag } from 'ant-design-vue';
import {
copyDesktop,
deleteDesktop,
exportDesktop,
getDesktopInfo,
getPageList,
setFirstHome,
setEnabled,
} from '/@/api/desktop';
import { DesktopInfoItem } from '/@/model/desktop/designer';
import DesktopPreview from './components/DesktopPreview.vue';
import { downloadByData } from '/@/utils/file/download';
import { useI18n } from '/@/hooks/web/useI18n';
import { usePermissionStore } from '/@/store/modules/permission';
const { t } = useI18n();
const DesktopDesign = defineAsyncComponent({
loader: () => import('./components/DesktopDesign.vue'),
loadingComponent: LoadingBox,
});
const searchConfig = [
{
field: 'keyword',
label: t('关键字'),
type: 'input',
},
];
const { tableOptions, scrollHeight } = userTableScrollHeight();
let data: {
dataSource: Array<DesktopPageModel>;
renderKey: number;
keyword: string;
pagination: {
current: number;
total: number;
pageSize: number;
};
desktopDesignVisible: boolean;
editId: string;
list: Array<DesktopInfoItem>;
previewVisible: boolean;
historyVisible: boolean;
historyId: string;
} = reactive({
dataSource: [],
renderKey: 0,
pagination: { current: 1, total: 0, pageSize: 20 },
keyword: '',
desktopDesignVisible: false,
editId: '',
list: [],
previewVisible: false,
historyVisible: false,
historyId: '',
});
onMounted(() => {
data.dataSource = [];
getList();
});
async function getList() {
let params = {
limit: data.pagination.current,
size: data.pagination.pageSize,
keyword: data.keyword,
};
let res = await getPageList(params);
data.dataSource = res.list;
data.pagination.total = res.total;
data.renderKey++;
}
function search(params?: any) {
data.keyword = params.keyword;
data.pagination.current = 1;
data.dataSource = [];
getList();
}
function handleAdd() {
data.desktopDesignVisible = true;
}
async function handlePreview(id: string) {
let { jsonContent } = await getDesktopInfo(id);
data.list = JSON.parse(jsonContent);
data.previewVisible = true;
}
function handleEdit(id: string) {
data.editId = id;
data.desktopDesignVisible = true;
}
async function handleDelete(id: string) {
try {
let res = await deleteDesktop(id);
if (res) {
notification.open({
type: 'success',
message: t('删除'),
description: t('成功'),
});
getList();
}
} catch (error) {}
}
function handleClose() {
data.editId = '';
data.list = [];
data.desktopDesignVisible = false;
getList();
}
async function copy(id: string) {
try {
let res = await copyDesktop(id);
if (res) {
notification.open({
type: 'success',
message: t('复制'),
description: t('成功'),
});
getList();
}
} catch (error) {}
}
async function handleDownByData(item: DesktopPageModel) {
try {
let res: any = await exportDesktop(item.id);
downloadByData(res, item.name + '.json');
} catch (error) {}
}
function showHistory(id: string) {
data.historyId = id;
data.historyVisible = true;
}
async function changeEnabledMark(info) {
const params = {
id: info.id,
enabledMark: info.enabledMark,
};
try {
const res = await setEnabled(params);
if (res) {
notification.open({
type: 'success',
message: `${info.enabledMark ? t('启用') : t('禁用')}${t('成功')}`,
description: t('成功'),
});
getList();
} else {
notification.open({
type: 'error',
message: `${info.enabledMark ? t('启用') : t('禁用')}${t('失败')}`,
description: t('失败'),
});
info.enabledMark = info.enabledMark ? 0 : 1;
}
} catch (error) {}
}
async function handleFirst(id) {
let res = await setFirstHome(id);
if (res) {
notification.open({
type: 'success',
message: t('设为默认首页'),
description: t('成功'),
});
getList();
const permissionStore = usePermissionStore();
await permissionStore.changePermissionCode();
} else {
notification.open({
type: 'error',
message: t('设为默认首页'),
description: t('失败'),
});
}
}
</script>
<style lang="less" scoped>
.list-box {
display: flex;
flex-wrap: wrap;
.item {
position: relative;
margin: 8px;
width: 258px;
height: 184px;
overflow: hidden;
border-radius: 4px;
padding-bottom: 36px;
box-shadow: 0 3px 6px 1px rgb(0 0 0 / 16%);
}
.image {
width: 100%;
img {
width: 100%;
height: 100%;
}
}
.mark {
position: absolute;
top: 10px;
right: 10px;
}
.edit {
position: absolute;
top: 58px;
left: 85px;
height: 32px;
line-height: 32px;
padding: 0 30px;
text-align: center;
font-size: 14px;
background-color: #39f;
color: #fff;
border: none;
transition: 0.3s ease;
cursor: pointer;
opacity: 0;
}
.item:hover .edit {
opacity: 1;
}
.main {
position: absolute;
left: 0;
right: 0;
top: 148px;
height: 36px;
display: flex;
justify-content: space-between;
align-items: center;
background-color: #202d40;
color: #fff;
font-size: 12px;
.name {
margin-left: 10px;
}
.menu-list {
margin-right: 10px;
.menu-item {
margin: 0 2px;
cursor: pointer;
}
}
}
}
.page-box {
position: absolute;
bottom: 20px;
right: 20px;
}
</style>