v3.8.0【优化】简介明了的数据范围说明文档;【优化】Long序列化;【优化】标签页右键关闭;【优化】表格排序Demo

This commit is contained in:
zhuoda
2024-10-17 21:55:56 +08:00
parent 753283191a
commit 053d562157
72 changed files with 1838 additions and 331 deletions

View File

@@ -32,6 +32,7 @@
},
},
}"
:getPopupContainer="getPopupContainer"
>
<!---全局loading--->
<a-spin :spinning="spinning" tip="稍等片刻,我在拼命加载中..." size="large">
@@ -49,6 +50,8 @@
import { useSpinStore } from '/@/store/modules/system/spin';
import { theme } from 'ant-design-vue';
import { themeColors } from '/@/theme/color.js';
import { SmartLoading } from '/@/components/framework/smart-loading/index.js';
import { LAYOUT_ELEMENT_IDS } from '/@/layout/layout-const.js';
const antdLocale = computed(() => messages[useAppConfigStore().language].antdLocale);
const dayjsLocale = computed(() => messages[useAppConfigStore().language].dayjsLocale);
@@ -67,4 +70,31 @@
const borderRadius = computed(() => {
return useAppConfigStore().borderRadius;
});
function getPopupContainer(node, dialogContext) {
let fullScreenFlag = useAppConfigStore().$state.fullScreenFlag;
if(fullScreenFlag){
return getFullScreenContainer(node, dialogContext);
}else{
return getNotFullScreenContainer(node, dialogContext);
}
}
function getFullScreenContainer(node, dialogContext) {
if (node === document.body) {
return document.getElementById(LAYOUT_ELEMENT_IDS.content);
}else if (node) {
return node.parentNode;
} else {
return document.getElementById(LAYOUT_ELEMENT_IDS.content);
}
}
function getNotFullScreenContainer(node, dialogContext) {
if (node) {
return node.parentNode;
} else {
return document.body;
}
}
</script>

View File

@@ -12,12 +12,12 @@
<template>
<span>
<a-tooltip title="全屏" v-if="!fullScreenFlag">
<a-button type="text" @click="fullScreen" size="small">
<a-button type="text" @click="onFullScreen" size="small">
<template #icon><fullscreen-outlined /></template>
</a-button>
</a-tooltip>
<a-tooltip title="取消全屏" v-if="fullScreenFlag">
<a-button type="text" @click="fullScreen" size="small">
<a-button type="text" @click="onFullScreen" size="small">
<template #icon><fullscreen-exit-outlined /></template>
</a-button>
</a-tooltip>
@@ -43,11 +43,13 @@
import { message } from 'ant-design-vue';
import { mergeColumn } from './smart-table-column-merge';
import { smartSentry } from '/@/lib/smart-sentry';
import { LAYOUT_ELEMENT_IDS } from '/@/layout/layout-const.js';
import { useAppConfigStore } from '/@/store/modules/system/app-config.js';
const props = defineProps({
// 表格列数组
modelValue: {
type: Array,
default: new Array(),
default: [],
},
// 刷新表格函数
refresh: {
@@ -93,22 +95,39 @@
// ----------------- 全屏 -------------------
const fullScreenFlag = ref(false);
function fullScreen() {
function onFullScreen() {
if (fullScreenFlag.value) {
//取消全屏
exitFullscreen(document.querySelector('#smartAdminLayoutContent'));
fullScreenFlag.value = false;
document.querySelector('#smartAdminPageTag').style.visibility = 'visible';
// 退出全屏
handleExitFullScreen();
exitElementFullscreen(document.getElementById(LAYOUT_ELEMENT_IDS.content));
} else {
//全屏
launchFullScreen(document.querySelector('#smartAdminLayoutContent'));
message.config({
getContainer: () => document.getElementById(LAYOUT_ELEMENT_IDS.content),
});
fullScreenFlag.value = true;
document.querySelector('#smartAdminPageTag').style.visibility = 'hidden';
useAppConfigStore().startFullScreen();
launchElementFullScreen(document.getElementById(LAYOUT_ELEMENT_IDS.content));
}
}
// 处理退出全屏
function handleExitFullScreen(){
//取消全屏
message.config({
getContainer: () => document.body,
});
fullScreenFlag.value = false;
useAppConfigStore().exitFullScreen();
document.removeEventListener('fullscreenchange', handleFullscreenChange);
document.removeEventListener('mozfullscreenchange', handleFullscreenChange); // Firefox
document.removeEventListener('webkitfullscreenchange', handleFullscreenChange); // Chrome, Safari and Opera
document.removeEventListener('MSFullscreenChange', handleFullscreenChange); // Internet Explorer and Edge
}
//判断各种浏览器 -全屏
function launchFullScreen(element) {
function launchElementFullScreen(element) {
if (element.requestFullscreen) {
element.requestFullscreen();
} else if (element.mozRequestFullScreen) {
@@ -120,9 +139,23 @@
} else {
message.error('当前浏览器不支持部分全屏!');
}
document.addEventListener('fullscreenchange', handleFullscreenChange);
document.addEventListener('mozfullscreenchange', handleFullscreenChange); // Firefox
document.addEventListener('webkitfullscreenchange', handleFullscreenChange); // Chrome, Safari and Opera
document.addEventListener('MSFullscreenChange', handleFullscreenChange); // Internet Explorer and Edge
}
function handleFullscreenChange() {
if (document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement) {
console.log('进入全屏模式');
} else {
console.log('退出全屏模式');
handleExitFullScreen();
}
}
//判断各种浏览器 -退出全屏
function exitFullscreen(element) {
function exitElementFullscreen(element) {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.mozCancelFullScreen) {

View File

@@ -23,7 +23,7 @@
</a-tab-pane>
</a-tabs>
</div>
<template #rightExtra>
<template #overlay>
<a-menu>
<a-menu-item @click="closeByMenu(false)">关闭其他</a-menu-item>
<a-menu-item @click="closeByMenu(true)">关闭所有</a-menu-item>

View File

@@ -24,7 +24,7 @@
</a-tab-pane>
</a-tabs>
</div>
<template #rightExtra>
<template #overlay>
<a-menu>
<a-menu-item @click="closeByMenu(false)">关闭其他</a-menu-item>
<a-menu-item @click="closeByMenu(true)">关闭所有</a-menu-item>

View File

@@ -1,11 +1,11 @@
<!--
* 帮助文档 layout
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-09-06 20:40:16
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
*
* @Author: 1024创新实验室-主任卓大
* @Date: 2022-09-06 20:40:16
* @Wechat: zhuda1024
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
-->
<template>
<!--
@@ -79,10 +79,10 @@
const websiteName = computed(() => useAppConfigStore().websiteName);
const windowHeight = window.innerHeight;
onMounted(() => {
watermark.set('smartAdminLayoutContent', useUserStore().actualName);
watermark.set(LAYOUT_ELEMENT_IDS.content, useUserStore().actualName);
});
const backTopTarget = () => {
return document.getElementById('smartAdminMain');
return document.getElementById(LAYOUT_ELEMENT_IDS.main);
};
const router = useRouter();
const route = useRoute();

View File

@@ -0,0 +1,9 @@
/**
* layout 相关元素 id
*/
export const LAYOUT_ELEMENT_IDS = {
menu: 'smartAdminMenu',
main: 'smartAdminMain',
header: 'smartAdminHeader',
content: 'smartAdminLayoutContent',
}

View File

@@ -10,15 +10,15 @@
<template>
<a-layout class="admin-layout" style="min-height: 100%">
<!-- 侧边菜单 side-menu -->
<a-layout-sider :theme="theme" class="side-menu" :collapsed="collapsed" :trigger="null">
<a-layout-sider :id="LAYOUT_ELEMENT_IDS.menu" :theme="theme" class="side-menu" :collapsed="collapsed" :trigger="null">
<!-- 左侧菜单 -->
<SideExpandMenu :collapsed="collapsed" />
</a-layout-sider>
<!--中间内容一共三部分1顶部;2中间内容区域;3底部一般是公司版权信息;-->
<a-layout class="admin-layout-main" :style="`height: ${windowHeight}px`" id="smartAdminMain">
<a-layout class="admin-layout-main" :style="`height: ${windowHeight}px`" :id="LAYOUT_ELEMENT_IDS.main">
<!-- 顶部头部信息 -->
<a-layout-header class="smart-layout-header">
<a-layout-header class="smart-layout-header" :id="LAYOUT_ELEMENT_IDS.header">
<a-row justify="space-between" class="smart-layout-header-user">
<a-col class="smart-layout-header-left">
<span class="collapsed-button">
@@ -44,19 +44,19 @@
</a-layout-header>
<!--中间内容-->
<a-layout-content class="admin-layout-content" id="smartAdminLayoutContent">
<a-layout-content class="admin-layout-content" :id="LAYOUT_ELEMENT_IDS.content">
<!--不keepAlive的iframe使用单个iframe组件-->
<IframeIndex v-show="iframeNotKeepAlivePageFlag" :key="route.name" :name="route.name" :url="route.meta.frameUrl" />
<!--keepAlive的iframe 每个页面一个iframe组件-->
<IframeIndex
v-for="item in keepAliveIframePages"
v-show="route.name == item.name"
v-show="route.name === item.name"
:key="item.name"
:name="item.name"
:url="item.meta.frameUrl"
/>
<!--非iframe使用router-view-->
<div v-show="!iframeNotKeepAlivePageFlag && keepAliveIframePages.every((e) => route.name != e.name)">
<div v-show="!iframeNotKeepAlivePageFlag && keepAliveIframePages.every((e) => route.name !== e.name)">
<router-view v-slot="{ Component }">
<keep-alive :include="keepAliveIncludes">
<component :is="Component" :key="route.name" />
@@ -98,6 +98,7 @@
import SideHelpDoc from './components/side-help-doc/index.vue';
import { useRouter } from 'vue-router';
import { HOME_PAGE_NAME } from '/@/constants/system/home-const';
import { LAYOUT_ELEMENT_IDS } from '/@/layout/layout-const.js';
const windowHeight = ref(window.innerHeight);
@@ -130,7 +131,7 @@
//页面初始化的时候加载水印
onMounted(() => {
if (watermarkFlag.value) {
watermark.set('smartAdminLayoutContent', useUserStore().actualName);
watermark.set(LAYOUT_ELEMENT_IDS.content, useUserStore().actualName);
} else {
watermark.clear();
}
@@ -140,7 +141,7 @@
() => watermarkFlag.value,
(newValue) => {
if (newValue) {
watermark.set('smartAdminLayoutContent', useUserStore().actualName);
watermark.set(LAYOUT_ELEMENT_IDS.content, useUserStore().actualName);
} else {
watermark.clear();
}
@@ -153,7 +154,7 @@
//回到顶部
const backTopTarget = () => {
return document.getElementById('smartAdminMain');
return document.getElementById(LAYOUT_ELEMENT_IDS.main);
};
// ----------------------- keep-alive相关 -----------------------
let { route, keepAliveIncludes, iframeNotKeepAlivePageFlag, keepAliveIframePages } = smartKeepAlive();

View File

@@ -1,15 +1,15 @@
<template>
<a-layout class="admin-layout" style="min-height: 100%">
<!-- 侧边菜单 side-menu -->
<a-layout-sider class="side-menu" :width="sideMenuWidth" :collapsed="collapsed" :theme="theme">
<a-layout-sider :id="LAYOUT_ELEMENT_IDS.menu" class="side-menu" :width="sideMenuWidth" :collapsed="collapsed" :theme="theme">
<!-- 左侧菜单 -->
<SideMenu :collapsed="collapsed" />
</a-layout-sider>
<!--中间内容一共三部分1顶部;2中间内容区域;3底部一般是公司版权信息;-->
<a-layout id="smartAdminMain" :style="`height: ${windowHeight}px`" class="admin-layout-main">
<a-layout :id="LAYOUT_ELEMENT_IDS.main" :style="`height: ${windowHeight}px`" class="admin-layout-main">
<!-- 顶部头部信息 -->
<a-layout-header class="layout-header">
<a-layout-header class="layout-header" :id="LAYOUT_ELEMENT_IDS.header">
<a-row class="layout-header-user" justify="space-between">
<a-col class="layout-header-left">
<span class="collapsed-button">
@@ -35,13 +35,13 @@
</a-layout-header>
<!--中间内容-->
<a-layout-content id="smartAdminLayoutContent" class="admin-layout-content">
<a-layout-content :id="LAYOUT_ELEMENT_IDS.content" class="admin-layout-content">
<!--不keepAlive的iframe使用单个iframe组件-->
<IframeIndex v-if="iframeNotKeepAlivePageFlag" :key="route.name" :name="route.name" :url="route.meta.frameUrl" />
<!--keepAlive的iframe 每个页面一个iframe组件-->
<IframeIndex
v-for="item in keepAliveIframePages"
v-show="route.name == item.name"
v-show="route.name === item.name"
:key="item.name"
:name="item.name"
:url="item.meta.frameUrl"
@@ -93,6 +93,7 @@
import SideHelpDoc from './components/side-help-doc/index.vue';
import { useRouter } from 'vue-router';
import { HOME_PAGE_NAME } from '/@/constants/system/home-const';
import { LAYOUT_ELEMENT_IDS } from '/@/layout/layout-const.js';
const windowHeight = ref(window.innerHeight);
//菜单宽度
@@ -126,7 +127,7 @@
//页面初始化的时候加载水印
onMounted(() => {
if (watermarkFlag.value) {
watermark.set('smartAdminLayoutContent', useUserStore().actualName);
watermark.set(LAYOUT_ELEMENT_IDS.content, useUserStore().actualName);
} else {
watermark.clear();
}
@@ -136,7 +137,7 @@
() => watermarkFlag.value,
(newValue) => {
if (newValue) {
watermark.set('smartAdminLayoutContent', useUserStore().actualName);
watermark.set(LAYOUT_ELEMENT_IDS.content, useUserStore().actualName);
} else {
watermark.clear();
}
@@ -145,7 +146,7 @@
//回到顶部
const backTopTarget = () => {
return document.getElementById('smartAdminMain');
return document.getElementById(LAYOUT_ELEMENT_IDS.main);
};
const router = useRouter();

View File

@@ -1,14 +1,14 @@
<template>
<a-layout class="admin-layout">
<!-- 顶部菜单 -->
<a-layout-header class="top-menu" :theme="theme">
<a-layout-header class="top-menu" :theme="theme" :id="LAYOUT_ELEMENT_IDS.menu">
<TopMenu />
</a-layout-header>
<!--中间内容-->
<a-layout-content id="smartAdminLayoutContent" class="admin-layout-content">
<a-layout-content :id="LAYOUT_ELEMENT_IDS.content" class="admin-layout-content">
<!---标签页-->
<div class="page-tag-div" v-show="pageTagFlag">
<div class="page-tag-div" v-show="pageTagFlag" :id="LAYOUT_ELEMENT_IDS.header">
<PageTag />
</div>
@@ -18,14 +18,14 @@
<!--keepAlive的iframe 每个页面一个iframe组件-->
<IframeIndex
v-for="item in keepAliveIframePages"
v-show="route.name == item.name"
v-show="route.name === item.name"
:key="item.name"
:name="item.name"
:url="item.meta.frameUrl"
/>
<!--非iframe使用router-view-->
<div v-show="!iframeNotKeepAlivePageFlag && keepAliveIframePages.every((e) => route.name != e.name)">
<div v-show="!iframeNotKeepAlivePageFlag && keepAliveIframePages.every((e) => route.name !== e.name)">
<router-view v-slot="{ Component }">
<keep-alive :include="keepAliveIncludes">
<component :is="Component" :key="route.name" />
@@ -55,6 +55,7 @@
import { useUserStore } from '/@/store/modules/system/user';
import { useRouter } from 'vue-router';
import { HOME_PAGE_NAME } from '/@/constants/system/home-const';
import { LAYOUT_ELEMENT_IDS } from '/@/layout/layout-const.js';
const windowHeight = ref(window.innerHeight);
//主题颜色
@@ -87,7 +88,7 @@
//页面初始化的时候加载水印
onMounted(() => {
if (watermarkFlag.value) {
watermark.set('smartAdminLayoutContent', useUserStore().actualName);
watermark.set(LAYOUT_ELEMENT_IDS.content, useUserStore().actualName);
} else {
watermark.clear();
}
@@ -97,7 +98,7 @@
() => watermarkFlag.value,
(newValue) => {
if (newValue) {
watermark.set('smartAdminLayoutContent', useUserStore().actualName);
watermark.set(LAYOUT_ELEMENT_IDS.content, useUserStore().actualName);
} else {
watermark.clear();
}
@@ -106,7 +107,7 @@
//回到顶部
const backTopTarget = () => {
return document.getElementById('smartAdminMain');
return document.getElementById(LAYOUT_ELEMENT_IDS.main);
};
const router = useRouter();

View File

@@ -13,7 +13,9 @@ import localStorageKeyConst from '/@/constants/local-storage-key-const';
import { smartSentry } from '/@/lib/smart-sentry';
import { localRead } from '/@/utils/local-util';
let state = { ...appDefaultConfig };
let state = {
...appDefaultConfig
};
let appConfigStr = localRead(localStorageKeyConst.APP_CONFIG);
let language = appDefaultConfig.language;
@@ -38,6 +40,8 @@ export const useAppConfigStore = defineStore({
state: () => ({
// 读取config下的默认配置
...state,
// 全屏
fullScreenFlag: false,
}),
actions: {
reset() {
@@ -51,5 +55,11 @@ export const useAppConfigStore = defineStore({
hideHelpDoc() {
this.helpDocExpandFlag = false;
},
startFullScreen() {
this.fullScreenFlag = true;
},
exitFullScreen() {
this.fullScreenFlag = false;
},
},
});

View File

@@ -97,7 +97,6 @@
</div>
</a-row>
<!---------- 表格操作行 end ----------->
<a-table
size="small"
:dataSource="tableData"
@@ -105,7 +104,9 @@
rowKey="goodsId"
bordered
:pagination="false"
:showSorterTooltip="false"
:row-selection="{ selectedRowKeys: selectedRowKeyList, onChange: onSelectChange }"
@change="onChange"
>
<template #bodyCell="{ text, record, column }">
<template v-if="column.dataIndex === 'place'">
@@ -190,6 +191,7 @@
import SmartEnumSelect from '/@/components/framework/smart-enum-select/index.vue';
import { FILE_FOLDER_TYPE_ENUM } from '/@/constants/support/file-const.js';
import FileUpload from '/@/components/support/file-upload/index.vue';
import _ from 'lodash';
// ---------------------------- 表格列 ----------------------------
@@ -205,6 +207,7 @@
{
title: '商品状态',
dataIndex: 'goodsStatus',
sorter: true
},
{
title: '产地',
@@ -213,10 +216,12 @@
{
title: '商品价格',
dataIndex: 'price',
sorter: true
},
{
title: '上架状态',
dataIndex: 'shelvesFlag',
sorter: true
},
{
title: '备注',
@@ -246,9 +251,10 @@
goodsType: undefined,
pageNum: 1,
pageSize: 10,
sortItemList: []
};
// 查询表单form
const queryForm = reactive({ ...queryFormState });
const queryForm = reactive(_.cloneDeep(queryFormState));
// 表格加载loading
const tableLoading = ref(false);
// 表格数据
@@ -259,7 +265,7 @@
// 重置查询条件
function resetQuery() {
let pageSize = queryForm.pageSize;
Object.assign(queryForm, queryFormState);
Object.assign(queryForm, _.cloneDeep(queryFormState));
queryForm.pageSize = pageSize;
queryData();
}
@@ -414,4 +420,27 @@
async function onExportGoods() {
await goodsApi.exportGoods();
}
function onChange(pagination, filters, sorter, { action }){
if (action === 'sort') {
const { order, field } = sorter;
let column = camelToUnderscore(field);
let findIndex = queryForm.sortItemList.findIndex(e => e.column === column);
if (findIndex !== -1) {
queryForm.sortItemList.splice(findIndex, 1);
}
if (order) {
let isAsc = order !== 'ascend';
queryForm.sortItemList.push({
column,
isAsc
});
}
queryData();
}
}
function camelToUnderscore(str) {
return str.replace(/([A-Z])/g, "_$1").toLowerCase();
}
</script>