Compare commits

..

2 Commits

Author SHA1 Message Date
朱浩 6128f267e1 Merge remote-tracking branch 'origin/main' 2024-12-19 11:07:27 +08:00
朱浩 e0a406c497 新增宫格查看插件 2024-12-19 11:07:12 +08:00
6 changed files with 250 additions and 2 deletions

View File

@ -92,6 +92,8 @@
"tinycolor2": "^1.6.0", "tinycolor2": "^1.6.0",
"tinymce": "6.8.3", "tinymce": "6.8.3",
"tippy.js": "^6.3.7", "tippy.js": "^6.3.7",
"v-viewer": "^3.0.11",
"viewerjs": "^1.11.7",
"vite-plugin-electron": "^0.28.8", "vite-plugin-electron": "^0.28.8",
"vue": "^3.4.34", "vue": "^3.4.34",
"vue-cropper": "1.0.3", "vue-cropper": "1.0.3",

View File

@ -0,0 +1,172 @@
<template>
<draggable handle=".header-btn" :draggable="false" item-key="backgroundColor" v-model="gridPicList" class="grid-pic-wrap" :style="getGrid">
<template #item="{ element, index }">
<div class="grid-pic-item" :key="element.backgroundColor" :style="getWH(element,index)">
<div class="delete-btn" @click="gridPicList.splice(index,1)">X</div>
<div class="header-btn"></div>
<ViewerItem :gridPicList="gridPicList" :index="index" :images="[element.src]"></ViewerItem>
</div>
</template>
</draggable>
<el-input style="position:fixed;bottom: 20px;right: 80px;width: 1000px" v-model="inputValue" type="text" />
<el-button class="add-btn" @click="addPic">
添加
</el-button>
</template>
<script setup>
import {ref, computed} from 'vue'
import Draggable from 'vuedraggable'
import ViewerItem from "./viewer-item.vue";
const gridPicList = ref([])
const inputValue = ref('')
//
const getWH = (item,index)=>{
return {
backgroundColor: item.backgroundColor,
'grid-area': 'a' + index
}
}
// grid
const getGrid = computed(() => {
switch (gridPicList.value.length) {
case 1:
return {
'grid-template-areas':
`"a0"`
}
case 2:
return {
'grid-template-areas':
`"a0 a1"`
}
case 3:
return {
'grid-template-areas':
`"a0 a1"
"a0 a2"`
}
case 4:
return {
'grid-template-areas':
`"a0 a2"
"a1 a3"`
}
case 5:
return {
'grid-template-areas':
`"a0 a2 a4"
"a1 a3 a4"`
}
case 6:
return {
'grid-template-areas':
`"a0 a2 a4"
"a1 a3 a5"`
}
case 7:
return {
'grid-template-areas':
`"a0 a2 a4"
"a0 a2 a4"
"a0 a2 a5"
"a1 a3 a5"
"a1 a3 a6"
"a1 a3 a6"`
}
case 8:
return {
'grid-template-areas':
`"a0 a3 a6"
"a0 a3 a6"
"a1 a4 a6"
"a1 a4 a7"
"a2 a5 a7"
"a2 a5 a7"`
}
case 9:
return {
'grid-template-areas':
`"a0 a3 a6"
"a1 a4 a7"
"a2 a5 a8"`
}
default:
return {
width: '100%',
height: '100%'
}
}
})
//
const addPic = () => {
if (gridPicList.value.length >= 9) {
return
}
gridPicList.value.push({
src: inputValue.value,
backgroundColor: getRandomColor()
})
inputValue.value = ''
}
//
function getRandomColor() {
let r = Math.floor(Math.random() * 256).toString(16);
let g = Math.floor(Math.random() * 256).toString(16);
let b = Math.floor(Math.random() * 256).toString(16);
// 0
r = r.length === 1? '0' + r : r;
g = g.length === 1? '0' + g : g;
b = b.length === 1? '0' + b : b;
return `#${r}${g}${b}`;
}
</script>
<style scoped lang="scss">
.grid-pic-wrap{
width: 100%;
height: 100%;
display: grid;
overflow: hidden;
.grid-pic-item{
//animation: fadeIn 0.5s ease-in-out forwards;
background-color: #0a84ff;
position: relative;
.delete-btn{
position: absolute;
top: 0;
right: 10px;
z-index: 999;
&:hover{
color: #fff;
cursor: pointer;
}
}
.header-btn{
position: absolute;
z-index: 998;
height: 30px;
width: 100%;
border-bottom: 1px dotted #ccc;
}
}
}
.add-btn{
position: fixed;
right: 20px;
bottom: 20px;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
</style>

View File

@ -0,0 +1,59 @@
<template>
<viewer :ref="collectRef('viewerRef'+index)" :options="optins" :images="images" class="images clearfix">
<template #default="scope">
<img v-for="src in scope.images" :key="index" :src="src" style="display: none">
</template>
</viewer>
</template>
<script setup>
import {ref, watch, nextTick} from "vue";
const props = defineProps({
images: {
type: Object,
default: () => {}
},
index: {
type: Number,
default: 0
},
gridPicList: {
type: Array,
default: () => []
}
})
const refs = ref([]);
const collectRef = (key) => {
return (el) => {
refs.value[key] = el;
};
};
//viewer
const optins = {
"inline": true,
"button": false,
"navbar": false,
"title": false,
"toolbar": false,
"tooltip": true,
"movable": true,
"zoomable": true,
"rotatable": true,
"scalable": true,
"transition": true,
"fullscreen": true,
"keyboard": true
}
const initViewers = () => {
refs.value['viewerRef'+props.index]?.rebuildViewer()
}
watch(props.gridPicList, (newValue, oldValue) => {
nextTick(()=>{
initViewers()
})
});
</script>
<style scoped lang="scss">
</style>

View File

@ -17,14 +17,14 @@ import log from 'electron-log/renderer' // 渲染进程日志-文件记录
import customComponent from '@/components/common' // 自定义组件 import customComponent from '@/components/common' // 自定义组件
import plugins from './plugins' // plugins插件 import plugins from './plugins' // plugins插件
import useUserStore from '@/store/modules/user' import useUserStore from '@/store/modules/user'
import VueViewer from 'v-viewer'
import 'viewerjs/dist/viewer.css'
if(process.env.NODE_ENV != 'development') { // 非开发环境,将日志打印到日志文件 if(process.env.NODE_ENV != 'development') { // 非开发环境,将日志打印到日志文件
Object.assign(console, log.functions) // 渲染进程日志-控制台替换 Object.assign(console, log.functions) // 渲染进程日志-控制台替换
} }
const app = createApp(App) const app = createApp(App)
//专为菁优网配置的请求转发 //专为菁优网配置的请求转发
app.config.globalProperties.$requestGetJYW = (url,config)=>{ app.config.globalProperties.$requestGetJYW = (url,config)=>{
config.params = config.params?config.params:{} config.params = config.params?config.params:{}
@ -42,6 +42,7 @@ import Directive from '@/AixPPTist/src/plugins/directive'
app.use(router) app.use(router)
.use(store) .use(store)
.use(VueViewer)
.use(ElementPlus, { locale: zhLocale }) .use(ElementPlus, { locale: zhLocale })
.use(customComponent) // 自定义组件 .use(customComponent) // 自定义组件
.use(plugins) .use(plugins)

View File

@ -31,6 +31,11 @@ export const constantRoutes = [
component: () => import('@/AixPPTist/src/App.vue'), component: () => import('@/AixPPTist/src/App.vue'),
hidden: true hidden: true
}, },
{
path: '/gridPic',
component: () => import('@/components/grid-pic/index.vue'),
hidden: true
},
{ {
path: '/model', path: '/model',
component: Layout, component: Layout,

View File

@ -10,6 +10,7 @@
<el-dropdown-menu> <el-dropdown-menu>
<el-dropdown-item @click="createAIPPT">新建文枢课件</el-dropdown-item> <el-dropdown-item @click="createAIPPT">新建文枢课件</el-dropdown-item>
<el-dropdown-item @click="aiTOPPT">AI一键生成</el-dropdown-item> <el-dropdown-item @click="aiTOPPT">AI一键生成</el-dropdown-item>
<el-dropdown-item @click="openGridPic">打开宫格</el-dropdown-item>
<el-dropdown-item @click="openFilePicker">导入PPT</el-dropdown-item> <el-dropdown-item @click="openFilePicker">导入PPT</el-dropdown-item>
<input type="file" ref="fileInput" style="display: none;" @change="handleFileChange" accept="application/vnd.ms-powerpoint,application/vnd.openxmlformats-officedocument.presentationml.presentation"> <input type="file" ref="fileInput" style="display: none;" @change="handleFileChange" accept="application/vnd.ms-powerpoint,application/vnd.openxmlformats-officedocument.presentationml.presentation">
</el-dropdown-menu> </el-dropdown-menu>
@ -341,6 +342,14 @@ export default {
// } // }
// }, // },
methods: { methods: {
openGridPic() {
createWindow('open-win', {
url: '/gridPic', //
option: {
maximizable: true
}
})
},
// //
sleep(ms){return new Promise(resolve => setTimeout(resolve, ms))}, sleep(ms){return new Promise(resolve => setTimeout(resolve, ms))},
addAiPPT(item) { addAiPPT(item) {