磁贴编辑、磁贴审核、待办表格
Frontend CI/CD / build (web-office) (push) Has been cancelled Details

This commit is contained in:
hujiale 2024-10-17 15:39:55 +08:00
parent 4f2a4abc85
commit 201cfd7322
19 changed files with 1068 additions and 163 deletions

View File

@ -113,7 +113,6 @@ watch(builtinValue, (n, o) => {
builtinType: n builtinType: n
} }
}) })
console.log('zzzz',preferences.theme.builtinType);
}) })
let menuOpen = ref(preferences.sidebar.enable) let menuOpen = ref(preferences.sidebar.enable)
watch(menuOpen, (n, o) => { watch(menuOpen, (n, o) => {
@ -122,7 +121,6 @@ watch(menuOpen, (n, o) => {
enable: n enable: n
} }
}) })
console.log('zz111zz',n);
}) })
let menuTheme = ref(preferences.theme.semiDarkSidebar) let menuTheme = ref(preferences.theme.semiDarkSidebar)
watch(menuTheme, (n, o) => { watch(menuTheme, (n, o) => {
@ -131,7 +129,6 @@ watch(menuTheme, (n, o) => {
semiDarkSidebar: n semiDarkSidebar: n
} }
}) })
console.log('zz222zz',n);
}) })
let value1 = ref('') let value1 = ref('')
let activeKey = ref('1'); let activeKey = ref('1');

View File

@ -0,0 +1,14 @@
import type { App } from 'vue';
import FastCrud from '@fast-crud/fast-crud';
import ui from '@fast-crud/ui-antdv4';
import Antdv from 'ant-design-vue';
import '@fast-crud/fast-crud/dist/style.css';
import '@fast-crud/ui-antdv4/dist/style.css';
export function registerFastCrud(app: App) {
app.use(Antdv);
app.use(ui);
app.use(FastCrud, {
});
}

View File

@ -0,0 +1,202 @@
import type { App } from 'vue';
import VXETable from 'vxe-table'
import {
VxeTable,
VxeColumn,
VxeColgroup,
VxeGrid,
VxeToolbar
} from 'vxe-table'
import VxeUI from 'vxe-pc-ui'
import {
VxeAlert,
VxeAnchor,
VxeAnchorLink,
VxeBreadcrumb,
VxeBreadcrumbItem,
VxeButton,
VxeButtonGroup,
VxeCalendar,
VxeCard,
VxeCarousel,
VxeCheckbox,
VxeCheckboxGroup,
VxeCol,
VxeCollapse,
VxeCollapsePane,
VxeDatePicker,
VxeDrawer,
VxeForm,
VxeFormDesign,
VxeFormGather,
VxeFormItem,
VxeFormView,
VxeIcon,
VxeIconPicker,
VxeImage,
VxeImageGroup,
VxeImagePreview,
VxeInput,
VxeLayoutAside,
VxeLayoutBody,
VxeLayoutContainer,
VxeLayoutFooter,
VxeLayoutHeader,
VxeLink,
VxeListDesign,
VxeListView,
VxeList,
VxeLoading,
VxeMenu,
VxeModal,
VxeNumberInput,
VxeOptgroup,
VxeOption,
VxePager,
VxePasswordInput,
VxePrintPageBreak,
VxePrint,
VxePulldown,
VxeRadio,
VxeRadioButton,
VxeRadioGroup,
VxeRow,
VxeSelect,
VxeSwitch,
VxeTabPane,
VxeTabs,
VxeTag,
VxeText,
VxeTextarea,
VxeTip,
VxeTooltip,
VxeTree,
VxeTreeSelect,
VxeUpload
} from 'vxe-pc-ui'
import VXETablePluginExportXLSX from 'vxe-table-plugin-export-xlsx'
import ExcelJS from 'exceljs'
import VXETablePluginAntd from 'vxe-table-plugin-antd'
// 导入主题变量,也可以重写主题变量
import 'vxe-pc-ui/lib/style.css'
import 'vxe-table/lib/style.css'
import 'vxe-table/styles/cssvar.scss'
import 'vxe-pc-ui/styles/cssvar.scss'
// VxeUI.setTheme('dark')
VxeUI.component(VxeAlert)
VxeUI.component(VxeAnchor)
VxeUI.component(VxeAnchorLink)
VxeUI.component(VxeBreadcrumb)
VxeUI.component(VxeBreadcrumbItem)
VxeUI.component(VxeButton)
VxeUI.component(VxeButtonGroup)
VxeUI.component(VxeCalendar)
VxeUI.component(VxeCard)
VxeUI.component(VxeCarousel)
VxeUI.component(VxeCheckbox)
VxeUI.component(VxeCheckboxGroup)
VxeUI.component(VxeCol)
VxeUI.component(VxeCollapse)
VxeUI.component(VxeCollapsePane)
VxeUI.component(VxeDatePicker)
VxeUI.component(VxeDrawer)
VxeUI.component(VxeForm)
VxeUI.component(VxeFormDesign)
VxeUI.component(VxeFormGather)
VxeUI.component(VxeFormItem)
VxeUI.component(VxeFormView)
VxeUI.component(VxeIcon)
VxeUI.component(VxeIconPicker)
VxeUI.component(VxeImage)
VxeUI.component(VxeImageGroup)
VxeUI.component(VxeImagePreview)
VxeUI.component(VxeInput)
VxeUI.component(VxeLayoutAside)
VxeUI.component(VxeLayoutBody)
VxeUI.component(VxeLayoutContainer)
VxeUI.component(VxeLayoutFooter)
VxeUI.component(VxeLayoutHeader)
VxeUI.component(VxeLink)
VxeUI.component(VxeListDesign)
VxeUI.component(VxeListView)
VxeUI.component(VxeList)
VxeUI.component(VxeLoading)
VxeUI.component(VxeMenu)
VxeUI.component(VxeModal)
VxeUI.component(VxeNumberInput)
VxeUI.component(VxeOptgroup)
VxeUI.component(VxeOption)
VxeUI.component(VxePager)
VxeUI.component(VxePasswordInput)
VxeUI.component(VxePrintPageBreak)
VxeUI.component(VxePrint)
VxeUI.component(VxePulldown)
VxeUI.component(VxeRadio)
VxeUI.component(VxeRadioButton)
VxeUI.component(VxeRadioGroup)
VxeUI.component(VxeRow)
VxeUI.component(VxeSelect)
VxeUI.component(VxeSwitch)
VxeUI.component(VxeTabPane)
VxeUI.component(VxeTabs)
VxeUI.component(VxeTag)
VxeUI.component(VxeText)
VxeUI.component(VxeTextarea)
VxeUI.component(VxeTip)
VxeUI.component(VxeTooltip)
VxeUI.component(VxeTree)
VxeUI.component(VxeTreeSelect)
VxeUI.component(VxeUpload)
VxeUI.component(VxeTable)
VxeUI.component(VxeColumn)
VxeUI.component(VxeColgroup)
VxeUI.component(VxeGrid)
VxeUI.component(VxeToolbar)
VXETable.use(VXETablePluginAntd)
VXETable.use(VXETablePluginExportXLSX, {
ExcelJS
})
VXETable.setConfig({
// zIndex: 9999,
grid: {
size: 'mini',
proxyConfig: {
props: {
result: 'data.rows',
total: 'data.total',
},
},
toolbarConfig: {
enabled: true,
},
},
pager: {
background: true,
pageSize: 50,
pageSizes: [50, 100, 300, 500, 1000],
layouts: ['PrevJump', 'PrevPage', 'Number', 'NextPage', 'NextJump', 'Sizes', 'FullJump', 'Total'],
},
})
export function registerVxeTable(app: App) {
app.use(VxeUI)
app.use(VxeTable)
app.use(VxeColumn)
app.use(VxeColgroup)
app.use(VxeGrid)
app.use(VxeToolbar)
}

View File

@ -70,10 +70,43 @@ const routes: RouteRecordRaw[] = [
hideInMenu: true, hideInMenu: true,
icon: 'lucide:area-chart', icon: 'lucide:area-chart',
title: '总部系统', title: '总部系统',
affixTab: true
}, },
}, },
...getRouter(firstRouter, 'first') ...getRouter(firstRouter, 'first'),
{
name: 'portal',
path: '/portal',
component: () => import('#/views/dashboard/home/portal.vue'),
// component: () => import('#/views/dashboard/home/main.vue'),
meta: {
hideInMenu: true,
icon: 'lucide:area-chart',
title: '磁贴管理',
},
},
{
name: 'audit',
path: '/audit',
component: () => import('#/views/dashboard/home/audit.vue'),
// component: () => import('#/views/dashboard/home/main.vue'),
meta: {
hideInMenu: true,
icon: 'lucide:area-chart',
title: '磁贴审核',
},
},
// {
// name: 'test',
// path: '/test',
// component: () => import('#/views/dashboard/home/test.vue'),
// // component: () => import('#/views/dashboard/home/main.vue'),
// meta: {
// icon: 'lucide:area-chart',
// title: '测试',
// },
// },
// { // {
// name: 'zshxgw', // name: 'zshxgw',
// path: '', // path: '',
@ -105,6 +138,4 @@ const routes: RouteRecordRaw[] = [
...getRouter(otherRouter,'other') ...getRouter(otherRouter,'other')
]; ];
console.log('999999',...getRouter(otherRouter,'other'));
export default routes; export default routes;

View File

@ -28,3 +28,4 @@
// ]; // ];
// export default routes; // export default routes;
export default [];

View File

@ -79,3 +79,4 @@
// ]; // ];
// export default routes; // export default routes;
export default [];

View File

@ -0,0 +1,38 @@
<template>
<VueDraggable class="drag-area" tag="ul" v-model="list" group="g1">
<li v-for="el in modelValue" :key="el.name" class="grup-box">
<p>{{ el.name }}</p>
<nested-component v-model="el.children" />
</li>
</VueDraggable>
</template>
<script setup lang="ts">
import { VueDraggable } from 'vue-draggable-plus'
import { computed } from 'vue'
interface IList {
name: string
children: IList[]
}
interface Props {
modelValue: IList[]
}
const props = defineProps<Props>()
interface Emits {
(e: 'update:modelValue', value: IList[]): void
}
const emits = defineEmits<Emits>()
const list = computed({
get: () => props.modelValue,
set: value => emits('update:modelValue', value)
})
</script>
<style scoped>
.drag-area {
min-height: 50px;
}
</style>

View File

@ -0,0 +1,50 @@
<template>
<div class="main-box bg-[#ecf3f8] px-3 mt-3 h-[100%]">
<div class="top-box flex justify-between items-center">
<Button type="primary">批量审批</Button>
<div class="flex items-center gap-2">
<VbenIconButton
class="hover:text-[#007da3] w-[30px] h-[30px] flex justify-center items-center rounded-[50%]">
<UnorderedListOutlined />
</VbenIconButton>
</div>
</div>
<CardTitle :type="'audit'" :list="list" />
</div>
</template>
<script setup lang="ts">
import {
VbenIconButton,
} from '@vben-core/shadcn-ui';
import CardTitle from './components/CardTiles/index.vue';
import { UnorderedListOutlined } from '@ant-design/icons-vue';
import { Button} from 'ant-design-vue';
import { tilesList } from './tiles'
let list: any[] = []
for (let i = tilesList.length; i > 0; i--) {
if(!tilesList[i]?.name) continue;
let obj: any = {}
obj.name = tilesList[i]?.name;
obj.url = tilesList[i]?.name2;
obj.work = '经营管理';
obj.code = tilesList[i]?.name1.split('.')[0];
list.push(obj);
obj = null
}
</script>
<style scoped lang="scss">
.tiles-list {
border-top: 1px solid #ddd;
}
.card-bt-box {
border-top: 1px solid #ddd;
}
.card-box:hover {
.mask-box {
display: block;
}
}
</style>

View File

@ -0,0 +1,111 @@
<template>
<div class="content-box bg-[#fff] px-3 mt-2 h-[100%]">
<div class="filter-box py-3">
<Form layout="inline">
<FormItem label="标题">
<Input class="!w-[150px]"></Input>
</FormItem>
<FormItem label="业务域">
<Select placeholder="请选择" class="!w-[150px]"></Select>
</FormItem>
<FormItem label="适用范围">
<Select v-model:value="scope" :options="options2" placeholder="请选择" class="!w-[150px]"></Select>
</FormItem>
<FormItem label="状态" v-if="type == 'portal'">
<Select placeholder="请选择" class="!w-[150px]"></Select>
</FormItem>
<FormItem>
<Button type="primary">查询</Button>
</FormItem>
</Form>
</div>
<div class="tiles-list flex flex-wrap justify-stretch gap-4 py-3 ">
<Card class="w-[18%] relative card-box" :bodyStyle="{ padding: 0 }"
v-for="(item, index) in list.slice(0, 10)" :key="index">
<div class="card-tp-b flex flex-col items-center">
<img :src="'/xbyt/' + item.url" alt="" class="mt-3 w-[100px] h-[100px]">
<div class="text-sm pb-2">{{ item.name }}</div>
</div>
<div class="card-bt-box pt-2 pl-6 text-xs flex flex-col gap-1 pb-3">
<div class="c-b-item flex">
<div class="font-semibold">编码</div>{{ item.code }}
</div>
<div class="c-b-item flex">
<div class="font-semibold">标题</div>{{ item.name }}
</div>
<div class="c-b-item flex">
<div class="font-semibold">业务域</div>{{ item.work }}
</div>
</div>
<div class="mask-box hidden">
<div v-if="type == 'portal'"
class="absolute inset-x-0 inset-y-0 bg-[rgba(0,0,0,.3)] flex items-center justify-center gap-4">
<Button type="primary">修改</Button>
<Button type="primary" danger>删除</Button>
</div>
<div v-else-if="type == 'audit'"
class="absolute inset-x-0 inset-y-0 bg-[rgba(0,0,0,.3)] flex items-center justify-center gap-4">
<Button type="primary">通过</Button>
<Button type="primary" danger>驳回</Button>
</div>
<ExpandOutlined class="absolute top-2 right-2 text-[#fff]" />
</div>
</Card>
</div>
<div class="flex justify-end">
<Pagination v-model:current="current" :total="500" />
</div>
</div>
</template>
<script setup lang="ts">
import { ref,toRefs } from 'vue';
import { ExpandOutlined } from '@ant-design/icons-vue';
import { Button, Form, FormItem, Input, Select, Card, Pagination } from 'ant-design-vue';
import { tilesList } from '../../tiles'
const props = defineProps({
type: {
type: String,
default: ''
},
list: {
type: Object,
default: []
}
})
let { list,type } = toRefs(props);
for (let i = 0; i < tilesList.length; i++) {
let obj: any = {}
obj.name = tilesList[i]?.name;
obj.url = tilesList[i]?.name2;
obj.work = '经营管理';
obj.code = tilesList[i]?.name1.split('.')[0];
list.value.push(obj);
obj = null
}
let scope = 'all'
const options2 = [
{
value: 'all',
label: '全部',
},
]
let current = ref(1)
</script>
<style scoped lang="scss">
.tiles-list {
border-top: 1px solid #ddd;
}
.card-bt-box {
border-top: 1px solid #ddd;
}
.card-box:hover {
.mask-box {
display: block;
}
}
</style>

View File

@ -1,12 +1,10 @@
<script setup> <script setup>
import { defineAsyncComponent, getCurrentInstance, markRaw, onMounted, ref } from 'vue'; import { defineAsyncComponent, getCurrentInstance, markRaw, onMounted, ref,nextTick } from 'vue';
import { UndoOutlined, CheckOutlined, CloseCircleFilled, QuestionCircleOutlined, SyncOutlined, ShoppingCartOutlined, EditOutlined } from '@ant-design/icons-vue'; import { UndoOutlined, CheckOutlined, CloseCircleFilled, QuestionCircleOutlined, SyncOutlined, ShoppingCartOutlined, EditOutlined } from '@ant-design/icons-vue';
import { CheckboxGroup, Checkbox, Collapse, CollapsePanel, FloatButtonGroup, FloatButton, BackTop, Popover } from 'ant-design-vue'; import { CheckboxGroup, Checkbox, Collapse, CollapsePanel, FloatButtonGroup, FloatButton, BackTop, Popover } from 'ant-design-vue';
// import GridGroup from './components/GridGroup/index.vue'
import { toRefs } from 'vue' import { toRefs } from 'vue'
const props = defineProps({ const props = defineProps({
@ -19,6 +17,44 @@ let { list } = toRefs(props);
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const layout = ref(JSON.parse(JSON.stringify(list.value))); const layout = ref(JSON.parse(JSON.stringify(list.value)));
onMounted(() => {
layout.value = [
{
"x": 1,
"y": 0,
"w": 1,
"h": 2,
"i": "1728964990256",
"component": {
"name1": "AUTO_1612155980933.png",
"name2": "AUTO_1612155980933_C会议管理.png",
"size": "2x2",
"name": "会议管理",
"w": 1,
"h": 2,
"component": "../Output1/index.vue",
"i": 0
},
},
{
"x": 4,
"y": 0,
"w": 1,
"h": 2,
"i": "1728965029729",
"component": {
"name1": "AUTO_1612155980933.png",
"name2": "AUTO_1612155980933_C会议管理.png",
"size": "2x2",
"name": "会议管理",
"w": 1,
"h": 2,
"component": "../Output1/index.vue",
"i": 0
},
},
]
})
const colNum = 12; const colNum = 12;
let defaultH = 2; let defaultH = 2;
let defaultW = 2; let defaultW = 2;
@ -33,7 +69,6 @@ const DragPos = {
h: null, h: null,
i: null, i: null,
}; };
const componentsInfo = list
// [ // [
// { // {
// id: '1-1', // id: '1-1',
@ -182,6 +217,8 @@ const drag = (e, item) => {
} }
}; };
const dragend = (e) => { const dragend = (e) => {
console.log('eeeee',e);
tilesIsMove.value = false;
const parentRect = document const parentRect = document
.querySelector('.grid-box') .querySelector('.grid-box')
.getBoundingClientRect(); .getBoundingClientRect();
@ -212,6 +249,8 @@ const dragend = (e) => {
w: currentDragCom.w, w: currentDragCom.w,
h: currentDragCom.h, h: currentDragCom.h,
i: DragPos.i, i: DragPos.i,
isDraggable: true,
isResizable: true,
component: currentDragCom, component: currentDragCom,
loadComp, loadComp,
}); });
@ -226,8 +265,12 @@ const dragend = (e) => {
try { try {
proxy.$refs.gridItem[layout.value.length].$refs.item.style.display = proxy.$refs.gridItem[layout.value.length].$refs.item.style.display =
'block'; 'block';
} catch { } } catch {
}
} }
nextTick(()=>{
tilesIsMove.value = true;
})
}; };
// resize使resize // resize使resize
const resizedEvent = (e) => { const resizedEvent = (e) => {
@ -249,7 +292,7 @@ let shop = ref(false)
// //
let editTiles = ref(false) let editTiles = ref(false)
// //
let activeKeyArr = ref(['1','2','3']) let activeKeyArr = ref(['1', '2', '3'])
// //
let selectTilseArr = ref([]) let selectTilseArr = ref([])
// //
@ -265,49 +308,54 @@ let addTiles = (val) => {
selectTilseArr.value = arr selectTilseArr.value = arr
} }
//
let tilesIsMove = ref(true)
//
let cancelOrSure = (type) => {
if (type == 'cance') {
editTiles.value = false;
tilesIsMove.value = false;
} else if (type == 'sure') {
editTiles.value = true;
tilesIsMove.value = true;
}
}
</script> </script>
<template> <template>
<div class="container h-[calc(100%-10px)]"> <div class="container-group">
<!-- 自定义布局的部分 --> <!-- 自定义布局的部分 -->
<div class="grid-box "> <div class="grid-box select-none">
<grid-layout ref="gridLayout" v-model:layout="layout" :col-num="12" :is-draggable="true" :is-mirrored="false" :auto-size="false" :responsive="false" <grid-layout ref="gridLayout" v-model:layout="layout" :col-num="3" :is-draggable="tilesIsMove" :is-mirrored="false"
:is-resizable="false" :margin="[10, 10]" :row-height="45" :vertical-compact="true"> :auto-size="false" :is-resizable="tilesIsMove" :margin="[10, 10]" :row-height="55"
:vertical-compact="true">
<grid-item v-for="item in layout" :key="item.i" ref="gridItem" :h="item.h" :i="item.i" :w="item.w" :x="item.x" <grid-item v-for="(item, index ) in layout" :key="item.i" ref="gridItem" :h="item.h" :i="item.i" :w="item.w"
:y="item.y" :dragAllowFrom="null" @resized="resizedEvent"> :x="item.x" :y="item.y" :dragAllowFrom="item.component&&item.component.dom?item.component.dom:null" @resized="resizedEvent">
<span class="close" @click="delItem(item)"> <span class="close" @click="delItem(item)" v-if="tilesIsMove">
<CloseCircleFilled style="color: #f10215;" /> <CloseCircleFilled style="color: #f10215;" />
</span> </span>
<div class="py-2 px-4 box-border w-[100%] h-[100%] bg-[#fff] us-card-box"> <div class="py-2 px-4 box-border w-[100%] h-[100%] us-card-box bg-background">
<component :is="item.loadComp" :data="item" :key="item.i"/> <component :is="item.loadComp" :data="item" :key="item.i" />
</div> </div>
</grid-item> </grid-item>
<!-- <grid-item>
<div style="width: 200px;height: 200px;border: 1px solid #f00;">
</div>
</grid-item> -->
</grid-layout> </grid-layout>
</div> </div>
</div> </div>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
.container { .container-group {
min-width: 1000px;
position: relative;
overflow-x: auto;
}
.grid-box {
min-width: 1000px;
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.grid-box {
width: 100%;
height: 100%;
}
.components-box { .components-box {
padding: 12px 20px; padding: 12px 20px;
// border: 1px solid rgb(66 66 66 / 100%); // border: 1px solid rgb(66 66 66 / 100%);
@ -359,6 +407,7 @@ let addTiles = (val) => {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
border-radius: 4px; border-radius: 4px;
} }
.shop-box { .shop-box {
width: 550px; width: 550px;
height: 75vh; height: 75vh;
@ -371,7 +420,7 @@ let addTiles = (val) => {
height: 100% !important; height: 100% !important;
overflow: auto; overflow: auto;
background: transparent; background: transparent;
border: 1px solid rgb(66 66 66 / 100%); border: 0px solid rgb(66 66 66 / 100%);
.vue-grid-item { .vue-grid-item {
// padding: 12px 20px; // padding: 12px 20px;

View File

@ -1,5 +1,5 @@
<template> <template>
<a href="#" class="pointer-events-none inline-block w-[100%] h-[100%] flex flex-col items-center gap-1"> <a href="/portal" class="pointer-events-none inline-block w-[100%] h-[100%] flex flex-col items-center gap-1">
<img :src="'/xbyt/'+data.component.name2" alt="" class="w-full object-content"> <img :src="'/xbyt/'+data.component.name2" alt="" class="w-full object-content">
<div class="text-sm">{{ data.component.name }}</div> <div class="text-sm">{{ data.component.name }}</div>
</a> </a>

View File

@ -1,31 +1,41 @@
<template> <template>
<div style="width: 100%;height: 100%;" class="flex flex-col"> <div style="width: 100%;height: 100%;" class="flex flex-col">
<div class="head-top-box flex justify-between mb-3"> <div class="head-top-box flex justify-between mb-3 titlt-top">
<div class="flex items-center gap-3"> <div class="flex items-center gap-10">
<div class="flex items-center gap-1"> <Badge :count="9" :offset="[6, -3]">
<CalendarOutlined />待办 <div class="flex items-center gap-1 cursor-pointer">
</div> <CalendarOutlined />待办
<div class="flex items-center gap-1"> </div>
</Badge>
<div class="flex items-center gap-1 cursor-pointer">
<CarryOutOutlined />已办 <CarryOutOutlined />已办
</div> </div>
<div class="flex items-center gap-1"> <Badge :count="9" :offset="[6, -3]">
<ExceptionOutlined />待阅 <div class="flex items-center gap-1 cursor-pointer">
</div> <ExceptionOutlined />待阅
<div class="flex items-center gap-1"> </div>
</Badge>
<div class="flex items-center gap-1 cursor-pointer">
<FileDoneOutlined />已阅 <FileDoneOutlined />已阅
</div> </div>
<div class="flex items-center gap-1"> <div class="flex items-center gap-1 cursor-pointer">
<StarOutlined />关注 <StarOutlined />关注
</div> </div>
</div> </div>
<div class="flex items-center gap-3"> <div class="flex items-center gap-3">
<InputSearch placeholder="任务查询" style="width: 200px" /> <InputSearch placeholder="任务查询" style="width: 200px" />
<SettingOutlined /> <SettingOutlined class="cursor-pointer" @click="userSet = true" />
<ReloadOutlined /> <ReloadOutlined class="cursor-pointer" />
</div> </div>
</div> </div>
<ul class="f-btn-box">
<li v-for="(item) in plainOptions" :key="item">
<Button >{{ item }}</Button>
</li>
</ul>
<div class="flex-1 overflow-hidden"> <div class="flex-1 overflow-hidden">
<vxe-grid v-bind="gridOptions" v-on="gridEvents"> <vxe-grid v-bind="gridOptions">
<template #attention_default="{ row }"> <template #attention_default="{ row }">
<StarOutlined class="text-lg"></StarOutlined> <StarOutlined class="text-lg"></StarOutlined>
</template> </template>
@ -36,16 +46,37 @@
</template> </template>
</vxe-grid> </vxe-grid>
</div> </div>
<Modal v-model:open="userSet" title="个人设置" :okText="'提交'" :width="800">
<div class="flex gap-2">
<div class="shrink-0">接收消息系统</div>
<div>
<Checkbox v-model:checked="state.checkAll" :indeterminate="state.indeterminate" @change="onCheckAllChange">
全选
</Checkbox>
<CheckboxGroup v-model:value="state.checkedList">
<div class="flex flex-wrap gap-2 mt-2">
<Checkbox :value="item" v-for="(item) in plainOptions" :key="item">
<div class="w-[85px] truncate">{{ item }}</div>
</Checkbox>
</div>
</CheckboxGroup>
</div>
</div>
</Modal>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { reactive } from 'vue' import { reactive, watch, ref } from 'vue'
import type { VxeGridProps, VxeGridListeners } from 'vxe-table' import { type VxeGridProps, VxeUI } from 'vxe-table'
import { CalendarOutlined, CarryOutOutlined, StarOutlined, ExceptionOutlined, FileDoneOutlined, SettingOutlined, ReloadOutlined } from '@ant-design/icons-vue'; import { CalendarOutlined, CarryOutOutlined, StarOutlined, ExceptionOutlined, FileDoneOutlined, SettingOutlined, ReloadOutlined } from '@ant-design/icons-vue';
import { InputSearch,Pagination } from 'ant-design-vue'; import { InputSearch, Pagination, Badge, Modal, Checkbox, CheckboxGroup, Button } from 'ant-design-vue';
import { preferences } from '@vben/preferences';
watch(() => preferences.theme.mode, (n: any) => {
VxeUI.setTheme(n)
})
interface RowVO { interface RowVO {
id: number id: number
@ -102,19 +133,44 @@ const findList = () => {
}, 300) }, 300)
} }
const searchEvent = () => {
tablePage.currentPage = 1
findList()
}
const handlePageChange: VxePagerEvents.PageChange = ({ currentPage, pageSize }) => {
tablePage.currentPage = currentPage
tablePage.pageSize = pageSize
findList()
}
findList() findList()
//
let userSet = ref(false);
const plainOptions = ['公文系统', '合同管理', '物资管理', '督查管理', '市场管理', '电子考勤', '财务管理信息通知', '费用报销', '设备管理', '工程造价', '员工诉求', '即完即结', '科技研发', '标准化系统', '纪检监督系统', '后勤管理系统', '信用风险系统'];
const state = reactive({
indeterminate: true,
checkAll: false,
checkedList: ['公文系统', '合同管理'],
});
const onCheckAllChange = (e: any) => {
Object.assign(state, {
checkedList: e.target.checked ? plainOptions : [],
indeterminate: false,
});
};
watch(
() => state.checkedList,
val => {
state.indeterminate = !!val.length && val.length < plainOptions.length;
state.checkAll = val.length === plainOptions.length;
},
);
</script> </script>
<style> <style lang="scss">
@import 'vxe-table/lib/style.css' @import 'vxe-table/lib/style.css';
.f-btn-box {
width: 100%; //
overflow: hidden; //
white-space: nowrap; //
overflow-x: auto; //
li {
display: inline-block;
margin-right: 10px;
}
}
</style> </style>

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="custom-card w-[100%] h-[100%]"> <div class="custom-card w-[100%] h-[100%] flex flex-col">
<div class="card-name">我的应用</div> <div class="card-name titlt-top">我的应用</div>
<GridGroup :list="data.component.childer"></GridGroup> <GridGroup :list="data.component.childer" class="flex-1"></GridGroup>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -19,5 +19,9 @@ let { data } = toRefs(props);
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.card-name {
font-weight: 500;
padding: 5px 0;
border-bottom: 1px solid #ddd;
}
</style> </style>

View File

@ -1,17 +1,75 @@
<script setup> <script setup>
import { defineAsyncComponent, getCurrentInstance, markRaw, onMounted, ref } from 'vue'; import { defineAsyncComponent, getCurrentInstance, markRaw, onMounted, ref, nextTick } from 'vue';
import { UndoOutlined, CheckOutlined, CloseCircleFilled, QuestionCircleOutlined, SyncOutlined, ShoppingCartOutlined, EditOutlined } from '@ant-design/icons-vue'; import { UndoOutlined, CheckOutlined, CloseCircleFilled, QuestionCircleOutlined, SyncOutlined, ShoppingCartOutlined, EditOutlined } from '@ant-design/icons-vue';
import { CheckboxGroup, Checkbox, Collapse, CollapsePanel, FloatButtonGroup, FloatButton, BackTop, Popover } from 'ant-design-vue'; import { CheckboxGroup, Checkbox, Collapse, CollapsePanel, FloatButtonGroup, FloatButton, BackTop, Popover } from 'ant-design-vue';
import { tilesList } from './tiles' import { tilesList } from './tiles'
import { useRouter } from "vue-router";
const router = useRouter();
// import GridGroup from './components/GridGroup/index.vue' // import GridGroup from './components/GridGroup/index.vue'
const { proxy, ctx: that } = getCurrentInstance();
const { proxy } = getCurrentInstance();
const layout = ref([]); const layout = ref([]);
onMounted(() => {
layout.value = [
{
"x": 1,
"y": 0,
"w": 1,
"h": 2,
"i": "1728964990256",
"component": {
"name1": "AUTO_1612155980933.png",
"name2": "AUTO_1612155980933_C会议管理.png",
"size": "2x2",
"name": "会议管理",
"w": 1,
"h": 2,
"component": "./components/Output1/index.vue",
"i": 0,
"path": "/portal"
},
},
{
"x": 0,
"y": 2,
"w": 8,
"h": 5,
"i": "1728964991972",
"component": {
"name1": "AUTO_1612159241967.png",
"name2": "AUTO_1612159241967_C车辆调度.png",
"size": "2x2",
"name": "车辆调度",
"w": 8,
"h": 5,
"component": "./components/Output2/index.vue",
"i": 2,
"dom": '.titlt-top'
},
},
{
"x": 4,
"y": 0,
"w": 1,
"h": 2,
"i": "1728965029729",
"component": {
"name1": "AUTO_1612155980933.png",
"name2": "AUTO_1612155980933_C会议管理.png",
"size": "2x2",
"name": "会议管理",
"w": 1,
"h": 2,
"component": "./components/Output1/index.vue",
"i": 0,
"path": "/audit"
},
}
]
})
const colNum = 12; const colNum = 12;
let defaultH = 2; let defaultH = 2;
let defaultW = 2; let defaultW = 2;
@ -26,7 +84,7 @@ const DragPos = {
h: null, h: null,
i: null, i: null,
}; };
const componentsInfo = tilesList const componentsInfo = tilesList
// [ // [
// { // {
// id: '1-1', // id: '1-1',
@ -175,6 +233,8 @@ const drag = (e, item) => {
} }
}; };
const dragend = (e) => { const dragend = (e) => {
console.log('eeeee', e);
tilesIsMove.value = false;
const parentRect = document const parentRect = document
.querySelector('.grid-box') .querySelector('.grid-box')
.getBoundingClientRect(); .getBoundingClientRect();
@ -219,8 +279,12 @@ const dragend = (e) => {
try { try {
proxy.$refs.gridItem[layout.value.length].$refs.item.style.display = proxy.$refs.gridItem[layout.value.length].$refs.item.style.display =
'block'; 'block';
} catch { } } catch {
}
} }
nextTick(() => {
tilesIsMove.value = true;
})
}; };
// resize使resize // resize使resize
const resizedEvent = (e) => { const resizedEvent = (e) => {
@ -242,7 +306,7 @@ let shop = ref(false)
// //
let editTiles = ref(false) let editTiles = ref(false)
// //
let activeKeyArr = ref(['1','2','3']) let activeKeyArr = ref(['1', '2', '3'])
// //
let selectTilseArr = ref([]) let selectTilseArr = ref([])
// //
@ -258,22 +322,41 @@ let addTiles = (val) => {
selectTilseArr.value = arr selectTilseArr.value = arr
} }
//
let tilesIsMove = ref(false)
//
let cancelOrSure = (type) => {
if (type == 'cance') {
editTiles.value = false;
tilesIsMove.value = false;
} else if (type == 'sure') {
editTiles.value = true;
tilesIsMove.value = true;
}
}
//
let goPage = (item) => {
if (tilesIsMove.value) return;
router.push(item.component?.path);
}
</script> </script>
<template> <template>
<div class="container h-[calc(100%-10px)]"> <div class="container h-[calc(100%-10px)] px-[20px]">
<!-- 自定义布局的部分 --> <!-- 自定义布局的部分 -->
<div class="grid-box "> <div class="grid-box select-none">
<grid-layout ref="gridLayout" v-model:layout="layout" :col-num="12" :is-draggable="true" :is-mirrored="false" :auto-size="false" :responsive="false" <grid-layout ref="gridLayout" v-model:layout="layout" :col-num="12" :is-draggable="tilesIsMove"
:is-resizable="true" :margin="[10, 10]" :row-height="45" :vertical-compact="true"> :is-mirrored="false" :auto-size="false" :responsive="false" :is-resizable="tilesIsMove" :margin="[10, 10]"
:row-height="45" :vertical-compact="true">
<grid-item v-for="item in layout" :key="item.i" ref="gridItem" :h="item.h" :i="item.i" :w="item.w" :x="item.x" <grid-item v-for="(item, index ) in layout" :key="item.i" ref="gridItem" :h="item.h" :i="item.i" :w="item.w"
:y="item.y" :dragAllowFrom="'.head-top-box'" @resized="resizedEvent"> :x="item.x" :y="item.y" :dragAllowFrom="item.component && item.component.dom ? item.component.dom : null"
<span class="close" @click="delItem(item)"> @resized="resizedEvent">
<span class="close" @click="delItem(item)" v-if="tilesIsMove">
<CloseCircleFilled style="color: #f10215;" /> <CloseCircleFilled style="color: #f10215;" />
</span> </span>
<div class="py-2 px-4 box-border w-[100%] h-[100%] bg-[#fff] us-card-box"> <div class="py-2 px-4 box-border w-[100%] h-[100%] us-card-box bg-background" @click="goPage(item)">
<component :is="item.loadComp" :data="item" :key="item.i"/> <component :is="item.loadComp" :data="item" :key="item.i" />
</div> </div>
</grid-item> </grid-item>
@ -284,79 +367,129 @@ let addTiles = (val) => {
</grid-item> --> </grid-item> -->
</grid-layout> </grid-layout>
</div> </div>
</div>
<!-- 右侧悬浮部分 --> <!-- 右侧悬浮部分 -->
<FloatButtonGroup shape="circle" :style="{ right: '40px' }"> <FloatButtonGroup shape="circle" :style="{ right: '40px' }">
<template v-if="!editTiles"> <template v-if="!editTiles">
<FloatButton tooltip="编辑磁贴" @click="editTiles = true"> <FloatButton tooltip="编辑磁贴" @click="cancelOrSure('sure')">
<template #icon>
<EditOutlined style="font-size: 20px;" />
</template>
</FloatButton>
</template>
<template v-else>
<FloatButton tooltip="保存修改">
<template #icon>
<CheckOutlined style="font-size: 20px;" />
</template>
</FloatButton>
<FloatButton tooltip="取消修改" @click="editTiles = false">
<template #icon>
<UndoOutlined style="font-size: 20px;" />
</template>
</FloatButton>
<Popover v-model:open="shop" title="磁贴商店133" trigger="click" placement="topRight">
<template #content>
<div class="shop-box">
<CheckboxGroup style="width: 100%" v-model:value="selectTilseArr">
<Collapse v-model:activeKey="activeKeyArr" style="width: 100%">
<CollapsePanel key="1" header="个人工作台44">
<!-- 可拖入的组件部分 -->
<div class="components-box">
<div v-for="item in componentsInfo.slice(0, 44)" :key="item.name" class="ctrl-box" draggable="true" @drag="drag"
@dragend="dragend" @dragstart="dragstart($event, item)" @click="addTiles(item.name)"
:class="{ 'active': selectTilseArr.includes(item.name) }">
<div class="ctrl-name">{{ item.name + '('+item.size+')' }}</div>
<img :src="'/xbyt/' + item.name2" alt="">
<Checkbox :value="item.name" class="absolute bottom-0 right-1" />
</div>
</div>
</CollapsePanel>
<CollapsePanel key="2" header="个人工作台44">
<div class="components-box">
<div v-for="item in componentsInfo.slice(44, 87)" :key="item.name" class="ctrl-box" draggable="true" @drag="drag"
@dragend="dragend" @dragstart="dragstart($event, item)" @click="addTiles(item.name)"
:class="{ 'active': selectTilseArr.includes(item.name) }">
<div class="ctrl-name">{{ item.name + '('+item.size+')' }}</div>
<img :src="'/xbyt/' + item.name2" alt="">
<Checkbox :value="item.name" :checked="selectTilseArr.includes(item.name)" class="absolute bottom-0 right-1" />
</div>
</div>
</CollapsePanel>
<CollapsePanel key="3" header="个人工作台45">
<div class="components-box">
<div v-for="item in componentsInfo.slice(-45)" :key="item.name" class="ctrl-box" draggable="true" @drag="drag"
@dragend="dragend" @dragstart="dragstart($event, item)" @click="addTiles(item.name)"
:class="{ 'active': selectTilseArr.includes(item.name) }">
<div class="ctrl-name">{{ item.name + '('+item.size+')' }}</div>
<img :src="'/xbyt/' + item.name2" alt="">
<Checkbox :value="item.name" :checked="selectTilseArr.includes(item.name)" class="absolute bottom-0 right-1" />
</div>
</div>
</CollapsePanel>
</Collapse>
</CheckboxGroup>
</div>
</template>
<FloatButton tooltip="磁贴商店">
<template #icon> <template #icon>
<ShoppingCartOutlined style="font-size: 20px;" :visibility-height="0" /> <EditOutlined style="font-size: 20px;" />
</template> </template>
</FloatButton> </FloatButton>
</Popover> </template>
</template> <template v-else>
</FloatButtonGroup> <FloatButton tooltip="保存修改" @click="cancelOrSure('sure')">
<template #icon>
<CheckOutlined style="font-size: 20px;" />
</template>
</FloatButton>
<FloatButton tooltip="取消修改" @click="cancelOrSure('cance')">
<template #icon>
<UndoOutlined style="font-size: 20px;" />
</template>
</FloatButton>
<Popover v-model:open="shop" title="磁贴商店127" trigger="click" placement="topRight">
<template #content>
<div class="shop-box">
<CheckboxGroup style="width: 100%" v-model:value="selectTilseArr">
<Collapse v-model:activeKey="activeKeyArr" style="width: 100%">
<CollapsePanel key="1" header="个人工作台22">
<!-- 可拖入的组件部分 -->
<div class="components-box">
<div v-for="item in componentsInfo.slice(0, 22)" :key="item.name" class="ctrl-box"
draggable="true" @drag="drag" @dragend="dragend($event)" @dragstart="dragstart($event, item)"
@click="addTiles(item.name)" :class="{ 'active': selectTilseArr.includes(item.name) }">
<div class="ctrl-name">{{ item.name + '(' + item.size + ')' }}</div>
<img :src="'/xbyt/' + item.name2" alt="">
<Checkbox :value="item.name" class="absolute bottom-0 right-1" />
</div>
</div>
</CollapsePanel>
<CollapsePanel key="2" header="综合行政12">
<div class="components-box">
<div v-for="item in componentsInfo.slice(22, 34)" :key="item.name" class="ctrl-box"
draggable="true" @drag="drag" @dragend="dragend" @dragstart="dragstart($event, item)"
@click="addTiles(item.name)" :class="{ 'active': selectTilseArr.includes(item.name) }">
<div class="ctrl-name">{{ item.name + '(' + item.size + ')' }}</div>
<img :src="'/xbyt/' + item.name2" alt="">
<Checkbox :value="item.name" :checked="selectTilseArr.includes(item.name)"
class="absolute bottom-0 right-1" />
</div>
</div>
</CollapsePanel>
<CollapsePanel key="3" header="经营管理22">
<div class="components-box">
<div v-for="item in componentsInfo.slice(34, 56)" :key="item.name" class="ctrl-box"
draggable="true" @drag="drag" @dragend="dragend" @dragstart="dragstart($event, item)"
@click="addTiles(item.name)" :class="{ 'active': selectTilseArr.includes(item.name) }">
<div class="ctrl-name">{{ item.name + '(' + item.size + ')' }}</div>
<img :src="'/xbyt/' + item.name2" alt="">
<Checkbox :value="item.name" :checked="selectTilseArr.includes(item.name)"
class="absolute bottom-0 right-1" />
</div>
</div>
</CollapsePanel>
<CollapsePanel key="4" header="安全生产19">
<div class="components-box">
<div v-for="item in componentsInfo.slice(56, 75)" :key="item.name" class="ctrl-box"
draggable="true" @drag="drag" @dragend="dragend" @dragstart="dragstart($event, item)"
@click="addTiles(item.name)" :class="{ 'active': selectTilseArr.includes(item.name) }">
<div class="ctrl-name">{{ item.name + '(' + item.size + ')' }}</div>
<img :src="'/xbyt/' + item.name2" alt="">
<Checkbox :value="item.name" :checked="selectTilseArr.includes(item.name)"
class="absolute bottom-0 right-1" />
</div>
</div>
</CollapsePanel>
<CollapsePanel key="5" header="勘探开发26">
<div class="components-box">
<div v-for="item in componentsInfo.slice(75, 101)" :key="item.name" class="ctrl-box"
draggable="true" @drag="drag" @dragend="dragend" @dragstart="dragstart($event, item)"
@click="addTiles(item.name)" :class="{ 'active': selectTilseArr.includes(item.name) }">
<div class="ctrl-name">{{ item.name + '(' + item.size + ')' }}</div>
<img :src="'/xbyt/' + item.name2" alt="">
<Checkbox :value="item.name" :checked="selectTilseArr.includes(item.name)"
class="absolute bottom-0 right-1" />
</div>
</div>
</CollapsePanel>
<CollapsePanel key="6" header="数据管理1">
<div class="components-box">
<div v-for="item in componentsInfo.slice(101, 102)" :key="item.name" class="ctrl-box"
draggable="true" @drag="drag" @dragend="dragend" @dragstart="dragstart($event, item)"
@click="addTiles(item.name)" :class="{ 'active': selectTilseArr.includes(item.name) }">
<div class="ctrl-name">{{ item.name + '(' + item.size + ')' }}</div>
<img :src="'/xbyt/' + item.name2" alt="">
<Checkbox :value="item.name" :checked="selectTilseArr.includes(item.name)"
class="absolute bottom-0 right-1" />
</div>
</div>
</CollapsePanel>
<CollapsePanel key="7" header="总部系统25">
<div class="components-box">
<div v-for="item in componentsInfo.slice(102, 127)" :key="item.name" class="ctrl-box"
draggable="true" @drag="drag" @dragend="dragend" @dragstart="dragstart($event, item)"
@click="addTiles(item.name)" :class="{ 'active': selectTilseArr.includes(item.name) }">
<div class="ctrl-name">{{ item.name + '(' + item.size + ')' }}</div>
<img :src="'/xbyt/' + item.name2" alt="">
<Checkbox :value="item.name" :checked="selectTilseArr.includes(item.name)"
class="absolute bottom-0 right-1" />
</div>
</div>
</CollapsePanel>
</Collapse>
</CheckboxGroup>
</div>
</template>
<FloatButton tooltip="磁贴商店">
<template #icon>
<ShoppingCartOutlined style="font-size: 20px;" :visibility-height="0" />
</template>
</FloatButton>
</Popover>
</template>
</FloatButtonGroup>
</div>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
@ -423,6 +556,7 @@ let addTiles = (val) => {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
border-radius: 4px; border-radius: 4px;
} }
.shop-box { .shop-box {
width: 550px; width: 550px;
height: 75vh; height: 75vh;
@ -435,7 +569,7 @@ let addTiles = (val) => {
height: 100% !important; height: 100% !important;
overflow: auto; overflow: auto;
background: transparent; background: transparent;
border: 1px solid rgb(66 66 66 / 100%); // border: 1px solid rgb(66 66 66 / 100%);
.vue-grid-item { .vue-grid-item {
// padding: 12px 20px; // padding: 12px 20px;

View File

@ -0,0 +1,41 @@
<template>
<div class="flex justify-between">
<nested-draggable v-model="list" class="w-full"></nested-draggable>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import NestedDraggable from './NestedComponent.vue'
const list = ref([
{
name: 'item 1',
type: 'father',
children: [
{
name: 'item 2',
type: 'son',
children: []
}
]
},
{
name: 'item 3',
type: 'father',
children: [
{
name: 'item 4',
type: 'son',
children: []
}
]
},
{
name: 'item 5',
type: 'father',
children: []
}
])
</script>

View File

@ -0,0 +1,35 @@
<template>
<div class="main-box bg-[#ecf3f8] px-3 mt-3 h-[100%]">
<div class="top-box flex justify-between items-center">
<div class="t-b-name text-base">磁贴管理</div>
<div class="flex items-center gap-2">
<Button type="primary">注册磁贴</Button>
<VbenIconButton
class="hover:text-[#007da3] w-[30px] h-[30px] flex justify-center items-center rounded-[50%]">
<UnorderedListOutlined />
</VbenIconButton>
</div>
</div>
<CardTitle :type="'portal'" :list="list" />
</div>
</template>
<script setup lang="ts">
import {
VbenIconButton,
} from '@vben-core/shadcn-ui';
import CardTitle from './components/CardTiles/index.vue';
import { UnorderedListOutlined, ExpandOutlined } from '@ant-design/icons-vue';
import { Button, Form, FormItem, Input, Select, Card, Pagination} from 'ant-design-vue';
import { tilesList } from './tiles'
let list: any[] = []
for (let i = 0; i < tilesList.length; i++) {
let obj: any = {}
obj.name = tilesList[i]?.name;
obj.url = tilesList[i]?.name2;
obj.work = '经营管理';
obj.code = tilesList[i]?.name1.split('.')[0];
list.push(obj);
obj = null
}
</script>

View File

@ -0,0 +1,137 @@
<template>
<div>
<div class="flex flex-col">
Displayed as <code>[x, y, w, h]</code>:
<div class="flex flex-wrap">
<div v-for="item in layout">
<b>{{item.i}}</b>: [{{item.x}}, {{item.y}}, {{item.w}}, {{item.h}}]
</div>
</div>
</div>
{{ xxx }}
<grid-layout :layout.sync="layout" :col-num="12" :row-height="30" :is-draggable="draggable"
:is-resizable="resizable" :responsive="false" :vertical-compact="false" :prevent-collision="true"
:use-css-transforms="true">
<grid-item v-for="item in layout" :static="item.static" :x="item.x" :y="item.y" :w="item.w" :h="item.h"
:i="item.i" @dragging="moveEvent" @resizeEvent="resizeEvent">
<span class="text">{{ item.i }}</span>
</grid-item>
</grid-layout>
</div>
</template>
<script lang="ts">
import { GridLayout, GridItem } from "vue-grid-layout"
export default {
components: {
GridLayout,
GridItem
},
data() {
return {
xxx:{},
layout: [
{ "x": 0, "y": 0, "w": 2, "h": 2, "i": "0", static: false },
{ "x": 2, "y": 0, "w": 2, "h": 4, "i": "1", static: true },
{ "x": 4, "y": 0, "w": 2, "h": 5, "i": "2", static: false },
{ "x": 6, "y": 0, "w": 2, "h": 3, "i": "3", static: false },
{ "x": 8, "y": 0, "w": 2, "h": 3, "i": "4", static: false },
{ "x": 10, "y": 0, "w": 2, "h": 3, "i": "5", static: false },
{ "x": 0, "y": 5, "w": 2, "h": 5, "i": "6", static: false },
{ "x": 2, "y": 5, "w": 2, "h": 5, "i": "7", static: false },
{ "x": 4, "y": 5, "w": 2, "h": 5, "i": "8", static: false },
{ "x": 6, "y": 3, "w": 2, "h": 4, "i": "9", static: true },
{ "x": 8, "y": 4, "w": 2, "h": 4, "i": "10", static: false },
{ "x": 10, "y": 4, "w": 2, "h": 4, "i": "11", static: false },
{ "x": 0, "y": 10, "w": 2, "h": 5, "i": "12", static: false },
{ "x": 2, "y": 10, "w": 2, "h": 5, "i": "13", static: false },
{ "x": 4, "y": 8, "w": 2, "h": 4, "i": "14", static: false },
{ "x": 6, "y": 8, "w": 2, "h": 4, "i": "15", static: false },
{ "x": 8, "y": 10, "w": 2, "h": 5, "i": "16", static: false },
{ "x": 10, "y": 4, "w": 2, "h": 2, "i": "17", static: false },
{ "x": 0, "y": 9, "w": 2, "h": 3, "i": "18", static: false },
{ "x": 2, "y": 6, "w": 2, "h": 2, "i": "19", static: false }
],
draggable: true,
resizable: true,
}
},
methods: {
moveEvent(e) {
console.log(e)
this.xxx = {delta:e.delta,velocity:e.velocity}
},
resizeEvent(e) {
console.log(e)
},
}
}
</script>
<style scoped>
.vue-grid-layout {
background: #eee;
}
.vue-grid-item:not(.vue-grid-placeholder) {
background: #ccc;
border: 1px solid black;
}
.vue-grid-item .resizing {
opacity: 0.9;
}
.vue-grid-item .static {
background: #cce;
}
.vue-grid-item .text {
font-size: 24px;
text-align: center;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
height: 100%;
width: 100%;
}
.vue-grid-item .no-drag {
height: 100%;
width: 100%;
}
.vue-grid-item .minMax {
font-size: 12px;
}
.vue-grid-item .add {
cursor: pointer;
}
.vue-draggable-handle {
position: absolute;
width: 20px;
height: 20px;
top: 0;
left: 0;
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10'><circle cx='5' cy='5' r='5' fill='#999999'/></svg>") no-repeat;
background-position: bottom right;
padding: 0 8px 8px 0;
background-repeat: no-repeat;
background-origin: content-box;
box-sizing: border-box;
cursor: pointer;
}
</style>

View File

@ -7,7 +7,8 @@ let tilesList = [
"w": 1, "w": 1,
"h": 2, "h": 2,
"component": "./components/Output1/index.vue", "component": "./components/Output1/index.vue",
"i": 0 "i": 0,
"path": "/portal"
}, },
{ {
"name1": "AUTO_1612158921536.png", "name1": "AUTO_1612158921536.png",
@ -17,6 +18,7 @@ let tilesList = [
"w": 4, "w": 4,
"h": 6, "h": 6,
"component": "./components/Output5/index.vue", "component": "./components/Output5/index.vue",
"dom": '.titlt-top',
"childer": [ "childer": [
{ {
"name1": "AUTO_1612159241967.png", "name1": "AUTO_1612159241967.png",
@ -41,7 +43,8 @@ let tilesList = [
"w": 8, "w": 8,
"h": 5, "h": 5,
"component": "./components/Output2/index.vue", "component": "./components/Output2/index.vue",
"i": 2 "i": 2,
"dom": '.titlt-top'
}, },
{ {
"name1": "AUTO_1612159773503.png", "name1": "AUTO_1612159773503.png",
@ -51,7 +54,8 @@ let tilesList = [
"w": 1, "w": 1,
"h": 2, "h": 2,
"component": "./components/Output1/index.vue", "component": "./components/Output1/index.vue",
"i": 3 "i": 3,
"path": '/audit'
}, },
{ {
"name1": "AUTO_1612160044533.png", "name1": "AUTO_1612160044533.png",

View File

@ -180,7 +180,7 @@ if (enableShortcutKey.value) {
<div <div
class="text-foreground mb-1 flex items-center text-sm font-medium" class="text-foreground mb-1 flex items-center text-sm font-medium"
> >
{{ text }} 李华
<Badge class="ml-2 text-green-400"> <Badge class="ml-2 text-green-400">
{{ tagText }} {{ tagText }}
</Badge> </Badge>