mirror of
https://github.com/palxiao/poster-design.git
synced 2025-07-15 16:02:19 +08:00
Merge pull request #89 from JeremyYu-cn/feat-pinia
Rebuilt: base store to pinia
This commit is contained in:
commit
8372b3d893
40
README.md
40
README.md
@ -1,19 +1,21 @@
|
|||||||
**[在线体验网址](https://design.palxp.cn/)** | **[中文文档](https://xp.palxp.cn/)** | [常见问题](https://xp.palxp.cn/#/articles/1689323321667) | [架构说明](https://xp.palxp.cn/#/articles/1689321259854)
|
**[在线体验网站](https://design.palxp.cn/)** | **[在线文档](https://xp.palxp.cn/)** | [常见问题](https://xp.palxp.cn/#/articles/1689323321667)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Poster Design
|
## 迅排设计
|
||||||
|
|
||||||
迅排设计是一款漂亮易用且功能强大的开源创意图片编辑器,是对标稿定设计、创客贴、Canva 等商业产品的免费在线设计工具。
|
一款漂亮易用且功能强大的创意图片编辑器,对标稿定设计、创客贴、Canva 等商业产品。
|
||||||
|
|
||||||
|
适用于多种场景:海报图片生成、电商分享图、文章长图、视频/公众号封面等,无需下载软件即可轻松实现云端编辑、迅速完成图文排版。
|
||||||
|
|
||||||
[](https://design.palxp.cn/)
|
[](https://design.palxp.cn/)
|
||||||
|
|
||||||
适用于多种场景:海报图片生成、电商分享图、文章长图、视频/公众号封面等,无需下载软件即可轻松实现云端编辑、迅速完成图文排版。
|
### 特点
|
||||||
|
|
||||||
- 丝滑的页面操作体验,丰富的交互细节,基础功能完善
|
- 丝滑的页面操作体验,丰富的交互细节,基础功能完善
|
||||||
- 采用服务端生成图片,能确保多端出图统一性,支持各种 CSS 特性
|
- 采用服务端生成图片,能确保多端出图统一性,支持各种 CSS 特性
|
||||||
- 简易 AI 抠图工具,上传图片一键去除背景
|
- 简易 AI 抠图工具,上传图片一键去除背景
|
||||||
- 技术栈:Vue3 、Vite2 、Vuex 、ElementPlus,开发体验畅快
|
- 技术栈:Vue3 、Vite5 、Vuex 、ElementPlus,开发体验畅快
|
||||||
- 图片生成:Puppeteer、Express
|
- 图片生成:Puppeteer、Express
|
||||||
|
|
||||||
### 支持功能
|
### 支持功能
|
||||||
@ -35,25 +37,35 @@
|
|||||||
git clone https://github.com/palxiao/poster-design.git
|
git clone https://github.com/palxiao/poster-design.git
|
||||||
cd poster-design
|
cd poster-design
|
||||||
npm run prepared
|
npm run prepared
|
||||||
npm run serve
|
npm run dev
|
||||||
|
cd screreenshot
|
||||||
|
npm run dev
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
访问 http://127.0.0.1:5173/ 查看网页。点此查看[完整说明文档](https://xp.palxp.cn/#/articles/1689319644311)。
|
访问 http://127.0.0.1:5173/ 查看网页。点此查看[更多说明文档](https://xp.palxp.cn/#/articles/1689319644311)。
|
||||||
|
|
||||||
### 图片生成服务
|
### 图片生成服务
|
||||||
|
|
||||||
代码位于根目录 [/screenshot](https://github.com/palxiao/poster-design/tree/main/screenshot),接口API文档点此查看:[接口 API 文档](https://xp.palxp.cn/apidoc/screenshot.html)。
|
代码位于根目录 [/screenshot](https://github.com/palxiao/poster-design/tree/main/screenshot),接口API文档点此查看:[接口 API 文档](https://xp.palxp.cn/apidoc/screenshot.html)。
|
||||||
|
|
||||||
> 更多相关事项请进入该目录下查看 [README.md](https://github.com/palxiao/poster-design/blob/main/screenshot/README.md) 文件。 Docker 部署:[参考说明](https://xp.palxp.cn/#/articles/1689319644311?id=docker%e5%ae%b9%e5%99%a8)。
|
|
||||||
|
|
||||||
### 服务端
|
### 服务端
|
||||||
|
|
||||||
目前本项目演示 Demo 中的后端接口参考:[接口 API 文档](https://xp.palxp.cn/apidoc/index.html)。
|
后端需要自己开发,目前本项目演示 Demo 中的后端接口参考:[接口 API 文档](https://xp.palxp.cn/apidoc/index.html)。
|
||||||
|
|
||||||
## 其它
|
## 其它
|
||||||
|
|
||||||
|
我们尝试沉淀一个高质量内容社区,形成可持续学习的平台,同时解决开发者在项目中遇到的疑难和困惑,帮大家少走一些弯路。
|
||||||
|
|
||||||
|
<img style="width: 380px;" src="https://github.com/palxiao/poster-design/assets/21021314/643dcc8b-ef73-4c76-a78c-a7c377b5f268" />
|
||||||
|
|
||||||
|
也欢迎关注公众号:品味前端,回复“加群”进行交流。
|
||||||
|
|
||||||
|
<img style="width: 380px;" src="https://xp.palxp.cn/images/2024-3-1-1709306365949.png" />
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
本项目最早使用 Vue2 开发,现改用 Vue3 重构中。[一些迭代计划记录](https://xp.palxp.cn/#/articles/1689319986889?id=%e8%bf%ad%e4%bb%a3%e8%ae%a1%e5%88%92).
|
本项目最早使用 Vue2 开发,现改用 Vue3 重构中。[一些迭代计划记录](https://xp.palxp.cn/#/articles/1689319986889?id=%e8%bf%ad%e4%bb%a3%e8%ae%a1%e5%88%92).
|
||||||
|
|
||||||
目前开源版仍在持续迭代中,还有很多的不足,可以将你遇到的问题在 Issues 中提出,或者提交 Pull Request 帮助完善。
|
目前开源版仍在持续迭代中,还有很多的不足,可以将你遇到的问题在 Issues 中提出,或者提交 Pull Request 帮助完善。
|
||||||
@ -67,13 +79,7 @@ npm run serve
|
|||||||
- [qr-code-styling](https://qr-code-styling.com/): 风格化二维码
|
- [qr-code-styling](https://qr-code-styling.com/): 风格化二维码
|
||||||
- [rembg](https://github.com/danielgatis/rembg): 图片抠图,使用 u2net 预训练模型
|
- [rembg](https://github.com/danielgatis/rembg): 图片抠图,使用 u2net 预训练模型
|
||||||
|
|
||||||
### 交流群
|
开源不易,最后别忘了给本项目点个 **Star** ~
|
||||||
|
|
||||||
| 作者微信:备注加群 | 关注公众号 |
|
|
||||||
| --- | --- |
|
|
||||||
| <img style="width: 240px;" src="https://xp.palxp.cn/images/2024-3-1-1709306328344.png" /> | <img style="width: 320px;" src="https://xp.palxp.cn/images/2024-3-1-1709306365949.png" /> |
|
|
||||||
|
|
||||||
开源不易,别忘了给本项目点个 **Star** ~
|
|
||||||
|
|
||||||
[](https://star-history.com/#palxiao/poster-design&Date)
|
[](https://star-history.com/#palxiao/poster-design&Date)
|
||||||
|
|
||||||
|
51
package-lock.json
generated
51
package-lock.json
generated
@ -25,6 +25,7 @@
|
|||||||
"moveable-helper": "^0.4.0",
|
"moveable-helper": "^0.4.0",
|
||||||
"nanoid": "^3.1.23",
|
"nanoid": "^3.1.23",
|
||||||
"normalize.css": "^8.0.1",
|
"normalize.css": "^8.0.1",
|
||||||
|
"pinia": "^2.1.7",
|
||||||
"qr-code-styling": "^1.6.0-rc.1",
|
"qr-code-styling": "^1.6.0-rc.1",
|
||||||
"selecto": "^1.13.0",
|
"selecto": "^1.13.0",
|
||||||
"throttle-debounce": "^3.0.1",
|
"throttle-debounce": "^3.0.1",
|
||||||
@ -3276,6 +3277,56 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/pinia": {
|
||||||
|
"version": "2.1.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/pinia/-/pinia-2.1.7.tgz",
|
||||||
|
"integrity": "sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@vue/devtools-api": "^6.5.0",
|
||||||
|
"vue-demi": ">=0.14.5"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/posva"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@vue/composition-api": "^1.4.0",
|
||||||
|
"typescript": ">=4.4.4",
|
||||||
|
"vue": "^2.6.14 || ^3.3.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@vue/composition-api": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"typescript": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pinia/node_modules/vue-demi": {
|
||||||
|
"version": "0.14.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz",
|
||||||
|
"integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"bin": {
|
||||||
|
"vue-demi-fix": "bin/vue-demi-fix.js",
|
||||||
|
"vue-demi-switch": "bin/vue-demi-switch.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/antfu"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@vue/composition-api": "^1.0.0-rc.1",
|
||||||
|
"vue": "^3.0.0-0 || ^2.6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@vue/composition-api": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/postcss": {
|
"node_modules/postcss": {
|
||||||
"version": "8.4.35",
|
"version": "8.4.35",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz",
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
"moveable-helper": "^0.4.0",
|
"moveable-helper": "^0.4.0",
|
||||||
"nanoid": "^3.1.23",
|
"nanoid": "^3.1.23",
|
||||||
"normalize.css": "^8.0.1",
|
"normalize.css": "^8.0.1",
|
||||||
|
"pinia": "^2.1.7",
|
||||||
"qr-code-styling": "^1.6.0-rc.1",
|
"qr-code-styling": "^1.6.0-rc.1",
|
||||||
"selecto": "^1.13.0",
|
"selecto": "^1.13.0",
|
||||||
"throttle-debounce": "^3.0.1",
|
"throttle-debounce": "^3.0.1",
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="page-design" ref="page_design" :style="{ paddingTop: dPaddingTop + 'px' }">
|
<div id="page-design" ref="page_design" :style="{ paddingTop: dPaddingTop + 'px' }">
|
||||||
|
<!-- <el-scrollbar> -->
|
||||||
<div
|
<div
|
||||||
id="out-page"
|
id="out-page"
|
||||||
class="out-page"
|
class="out-page"
|
||||||
@ -54,6 +55,7 @@
|
|||||||
<!-- <size-control v-if="dSelectWidgets.length === 0" /> -->
|
<!-- <size-control v-if="dSelectWidgets.length === 0" /> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- </el-scrollbar> -->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -61,7 +63,7 @@
|
|||||||
import { nextTick, onMounted, ref } from 'vue'
|
import { nextTick, onMounted, ref } from 'vue'
|
||||||
import { mapGetters, mapActions, useStore } from 'vuex'
|
import { mapGetters, mapActions, useStore } from 'vuex'
|
||||||
import { getTarget } from '@/common/methods/target'
|
import { getTarget } from '@/common/methods/target'
|
||||||
|
// import { ElScrollbar } from 'element-plus'
|
||||||
import setWidgetData from '@/common/methods/DesignFeatures/setWidgetData'
|
import setWidgetData from '@/common/methods/DesignFeatures/setWidgetData'
|
||||||
import PointImg from '@/utils/plugins/pointImg'
|
import PointImg from '@/utils/plugins/pointImg'
|
||||||
import getComponentsData from '@/common/methods/DesignFeatures/setComponents'
|
import getComponentsData from '@/common/methods/DesignFeatures/setComponents'
|
||||||
|
@ -32,6 +32,7 @@ import useConfirm from '@/common/methods/confirm'
|
|||||||
import { useSetupMapGetters } from '@/common/hooks/mapGetters'
|
import { useSetupMapGetters } from '@/common/hooks/mapGetters'
|
||||||
import imgWaterFall from './components/imgWaterFall.vue'
|
import imgWaterFall from './components/imgWaterFall.vue'
|
||||||
import { IGetTempListData } from '@/api/home'
|
import { IGetTempListData } from '@/api/home'
|
||||||
|
import useUserStore from '@/store/modules/base/user'
|
||||||
|
|
||||||
type TState = {
|
type TState = {
|
||||||
loading: boolean
|
loading: boolean
|
||||||
@ -52,6 +53,7 @@ const listRef = ref<HTMLElement | null>(null)
|
|||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
|
const userStore = useUserStore()
|
||||||
const state = reactive<TState>({
|
const state = reactive<TState>({
|
||||||
loading: false,
|
loading: false,
|
||||||
loadDone: false,
|
loadDone: false,
|
||||||
@ -64,8 +66,9 @@ const { tempEditing, dHistoryParams } = useSetupMapGetters(['tempEditing', 'dHis
|
|||||||
|
|
||||||
const pageOptions: TPageOptions = { page: 0, pageSize: 20, cate: 1 }
|
const pageOptions: TPageOptions = { page: 0, pageSize: 20, cate: 1 }
|
||||||
const { cate, edit } = route.query
|
const { cate, edit } = route.query
|
||||||
cate && (pageOptions.cate = (cate as LocationQueryValue) || 1)
|
cate && (pageOptions.cate = (cate as LocationQueryValue) ?? 1)
|
||||||
edit && store.commit('managerEdit', true)
|
// edit && store.commit('managerEdit', true)
|
||||||
|
edit && userStore.managerEdit(true)
|
||||||
|
|
||||||
// onMounted(async () => {})
|
// onMounted(async () => {})
|
||||||
|
|
||||||
@ -116,7 +119,8 @@ async function selectItem(item: IGetTempListData) {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
store.commit('managerEdit', false)
|
// store.commit('managerEdit', false)
|
||||||
|
userStore.managerEdit(false)
|
||||||
store.commit('setDWidgets', [])
|
store.commit('setDWidgets', [])
|
||||||
|
|
||||||
setTempId(item.id)
|
setTempId(item.id)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* @Date: 2021-08-02 19:10:06
|
* @Date: 2021-08-02 19:10:06
|
||||||
* @Description: 选项选择(未拆分字体选择器)
|
* @Description: 选项选择(未拆分字体选择器)
|
||||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2023-11-20 18:21:55
|
* @LastEditTime: 2024-03-15 17:34:00
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div ref="select" class="value-select" :style="{ width: inputWidth }">
|
<div ref="select" class="value-select" :style="{ width: inputWidth }">
|
||||||
@ -65,7 +65,7 @@ import { computed, onMounted, reactive, ref, watch } from 'vue';
|
|||||||
|
|
||||||
type TProps = {
|
type TProps = {
|
||||||
label?: string
|
label?: string
|
||||||
modelValue?: Record<string, any>
|
modelValue?: Record<string, any> | string | number
|
||||||
suffix?: string
|
suffix?: string
|
||||||
data: Record<string, any>
|
data: Record<string, any>
|
||||||
disable?: boolean
|
disable?: boolean
|
||||||
@ -189,9 +189,8 @@ function down() {
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
// Color variables (appears count calculates by raw css)
|
@color0: #e1e1e1;
|
||||||
@color0: #e1e1e1; // Appears 2 times
|
@color1: #d1d1d1;
|
||||||
@color1: #d1d1d1; // Appears 2 times
|
|
||||||
|
|
||||||
.value-select {
|
.value-select {
|
||||||
// height: 60px;
|
// height: 60px;
|
||||||
|
@ -13,7 +13,9 @@ import utils from './utils'
|
|||||||
import 'normalize.css/normalize.css'
|
import 'normalize.css/normalize.css'
|
||||||
import '@/assets/styles/index.less'
|
import '@/assets/styles/index.less'
|
||||||
import elementConfig from './utils/widgets/elementConfig'
|
import elementConfig from './utils/widgets/elementConfig'
|
||||||
|
import { createPinia } from 'pinia'
|
||||||
|
|
||||||
|
const pinia = createPinia()
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
|
|
||||||
elementConfig.components.forEach((component) => {
|
elementConfig.components.forEach((component) => {
|
||||||
@ -26,6 +28,7 @@ elementConfig.plugins.forEach((plugin) => {
|
|||||||
|
|
||||||
app
|
app
|
||||||
.use(store)
|
.use(store)
|
||||||
|
.use(pinia)
|
||||||
.use(router)
|
.use(router)
|
||||||
.use(utils)
|
.use(utils)
|
||||||
.mount('#app')
|
.mount('#app')
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* @Date: 2022-03-09 16:29:54
|
* @Date: 2022-03-09 16:29:54
|
||||||
* @Description: 处理和ctrl建相关的操作
|
* @Description: 处理和ctrl建相关的操作
|
||||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2023-10-09 09:49:54
|
* @LastEditTime: 2024-03-15 17:34:51
|
||||||
*/
|
*/
|
||||||
import store from '@/store'
|
import store from '@/store'
|
||||||
import handlePaste from './handlePaste'
|
import handlePaste from './handlePaste'
|
||||||
@ -50,7 +50,7 @@ function checkGroupChild(pid: number | string, key: any) {
|
|||||||
return itHas
|
return itHas
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 复制
|
* 复制元素
|
||||||
*/
|
*/
|
||||||
function copy() {
|
function copy() {
|
||||||
if (store.getters.dActiveElement.uuid === '-1') {
|
if (store.getters.dActiveElement.uuid === '-1') {
|
||||||
@ -64,13 +64,14 @@ function copy() {
|
|||||||
* 粘贴
|
* 粘贴
|
||||||
*/
|
*/
|
||||||
function paste() {
|
function paste() {
|
||||||
handlePaste()
|
handlePaste().then(() => {
|
||||||
if (store.getters.dCopyElement.length === 0) {
|
if (store.getters.dCopyElement.length === 0) {
|
||||||
return
|
return
|
||||||
} else if (store.getters.dActiveElement.isContainer && checkGroupChild(store.getters.dActiveElement.uuid, 'editable')) {
|
} else if (store.getters.dActiveElement.isContainer && checkGroupChild(store.getters.dActiveElement.uuid, 'editable')) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
!store.getters.dActiveElement.editable && store.dispatch('pasteWidget')
|
!store.getters.dActiveElement.editable && store.dispatch('pasteWidget')
|
||||||
|
})
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 撤销
|
* 撤销
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* @Date: 2023-10-09 09:47:40
|
* @Date: 2023-10-09 09:47:40
|
||||||
* @Description: 处理剪贴板
|
* @Description: 处理剪贴板
|
||||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||||
* @LastEditTime: 2023-10-09 10:35:21
|
* @LastEditTime: 2024-03-15 17:35:18
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// window.addEventListener('paste', (e: any) => {
|
// window.addEventListener('paste', (e: any) => {
|
||||||
@ -17,13 +17,16 @@ import Qiniu from '@/common/methods/QiNiu'
|
|||||||
import _config from '@/config'
|
import _config from '@/config'
|
||||||
import { getImage } from '@/common/methods/getImgDetail'
|
import { getImage } from '@/common/methods/getImgDetail'
|
||||||
import wImage from '@/components/modules/widgets/wImage/wImage.vue'
|
import wImage from '@/components/modules/widgets/wImage/wImage.vue'
|
||||||
// import wText from '@/components/modules/widgets/wText/wText.vue'
|
import wText from '@/components/modules/widgets/wText/wText.vue'
|
||||||
import { wTextSetting } from '@/components/modules/widgets/wText/wTextSetting'
|
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
|
return new Promise<void>((resolve) => {
|
||||||
navigator.clipboard
|
navigator.clipboard
|
||||||
.read()
|
.read()
|
||||||
.then(async (dataTransfer: any) => {
|
.then(async (dataTransfer: any) => {
|
||||||
|
if (store.getters.dActiveElement.editable) {
|
||||||
|
return
|
||||||
|
}
|
||||||
for (let i = 0; i < dataTransfer.length; i++) {
|
for (let i = 0; i < dataTransfer.length; i++) {
|
||||||
const item = dataTransfer[i]
|
const item = dataTransfer[i]
|
||||||
if (item.types.toString().indexOf('image') !== -1) {
|
if (item.types.toString().indexOf('image') !== -1) {
|
||||||
@ -45,10 +48,16 @@ export default () => {
|
|||||||
setting.left = pW / 2 - width / 2
|
setting.left = pW / 2 - width / 2
|
||||||
setting.top = pH / 2 - height / 2
|
setting.top = pH / 2 - height / 2
|
||||||
store.dispatch('addWidget', setting)
|
store.dispatch('addWidget', setting)
|
||||||
|
// 清空剪贴板,防止多次上传图片
|
||||||
|
navigator.clipboard.write([
|
||||||
|
new ClipboardItem({
|
||||||
|
'text/plain': new Blob([''], {type: 'text/plain'})
|
||||||
|
})
|
||||||
|
])
|
||||||
break
|
break
|
||||||
} else if (item.types.toString().indexOf('text') !== -1) {
|
} else if (item.types.toString().indexOf('text') !== -1) {
|
||||||
store.commit('setShowMoveable', false) // 清理掉上一次的选择
|
store.commit('setShowMoveable', false) // 清理掉上一次的选择
|
||||||
const setting = JSON.parse(JSON.stringify(wTextSetting))
|
const setting = JSON.parse(JSON.stringify(wText.setting))
|
||||||
setting.text = await navigator.clipboard.readText()
|
setting.text = await navigator.clipboard.readText()
|
||||||
store.dispatch('addWidget', setting)
|
store.dispatch('addWidget', setting)
|
||||||
break
|
break
|
||||||
@ -56,6 +65,8 @@ export default () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('无法读取剪贴板内容:', error)
|
// 剪贴板内容为空
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { createStore } from 'vuex'
|
import { createStore } from 'vuex'
|
||||||
|
|
||||||
import base from './modules/base'
|
// import base from './modules/base'
|
||||||
import design from './modules/design'
|
import design from './modules/design'
|
||||||
|
|
||||||
export default createStore({
|
export default createStore({
|
||||||
...base,
|
// ...base,
|
||||||
modules: {
|
modules: {
|
||||||
design,
|
design,
|
||||||
},
|
},
|
||||||
|
@ -2,18 +2,19 @@
|
|||||||
* 异步操作 store.dispatch() 调用
|
* 异步操作 store.dispatch() 调用
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface Iprops {
|
// interface Iprops {
|
||||||
commit: (a: any, b: any) => void
|
// commit: (a: any, b: any) => void
|
||||||
state: any
|
// state: any
|
||||||
}
|
// }
|
||||||
|
|
||||||
export default {
|
// export default {
|
||||||
hideLoading(props: Iprops, data: Type.Object) {
|
// hideLoading(props: Iprops, data: Type.Object) {
|
||||||
setTimeout(() => {
|
// setTimeout(() => {
|
||||||
props.commit('loading', false)
|
// props.commit('loading', false)
|
||||||
}, 600)
|
// }, 600)
|
||||||
},
|
// },
|
||||||
setFonts(store: Iprops, list: Type.Object) {
|
// setFonts(store: Iprops, list: Type.Object) {
|
||||||
store.state.fonts = list
|
// store.state.fonts = list
|
||||||
},
|
// },
|
||||||
}
|
|
||||||
|
// }
|
||||||
|
@ -2,48 +2,86 @@
|
|||||||
* @Author: ShawnPhang
|
* @Author: ShawnPhang
|
||||||
* @Date: 2021-12-16 16:20:16
|
* @Date: 2021-12-16 16:20:16
|
||||||
* @Description:
|
* @Description:
|
||||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
* @LastEditors: ShawnPhang <https://m.palxp.cn>, Jeremy Yu <https://github.com/JeremyYu-cn>
|
||||||
* @LastEditTime: 2023-09-28 17:42:25
|
* @LastEditTime: 2024-03-17 15:00:00
|
||||||
*/
|
*/
|
||||||
import mutations from './mutations'
|
|
||||||
import actions from './actions'
|
|
||||||
import _config from '@/config'
|
|
||||||
|
|
||||||
const all = {
|
import { defineStore } from 'pinia'
|
||||||
state: {
|
|
||||||
|
// import actions from './actions'
|
||||||
|
// import _config from '@/config'
|
||||||
|
|
||||||
|
type TStoreBaseState = {
|
||||||
|
loading: boolean | null
|
||||||
|
scroll: boolean
|
||||||
|
/** fonts */
|
||||||
|
fonts: string[]
|
||||||
|
/** 抠图服务 */
|
||||||
|
app: string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
type TUserAction = {
|
||||||
|
hideLoading: () => void
|
||||||
|
setFonts: (list: string[]) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const useBaseStore = defineStore<'base', TStoreBaseState, {}, TUserAction>('base', {
|
||||||
|
state: () => ({
|
||||||
loading: null,
|
loading: null,
|
||||||
online: true, // 登录状态,
|
|
||||||
user: {
|
|
||||||
name: localStorage.getItem('username'),
|
|
||||||
}, // 储存用户信息
|
|
||||||
scroll: true,
|
scroll: true,
|
||||||
manager: '', // 是否为管理员模式
|
|
||||||
tempEditing: false, // 管理员是否正在编辑模板
|
|
||||||
fonts: [], // 缓存字体列表
|
fonts: [], // 缓存字体列表
|
||||||
app: null, // 抠图服务
|
app: null, // 抠图服务
|
||||||
},
|
}),
|
||||||
getters: {
|
|
||||||
online: (state: Type.Object) => {
|
|
||||||
return state.online
|
|
||||||
},
|
|
||||||
user: (state: Type.Object) => {
|
|
||||||
return state.user
|
|
||||||
},
|
|
||||||
manager: (state: Type.Object) => {
|
|
||||||
return state.manager
|
|
||||||
},
|
|
||||||
tempEditing: (state: Type.Object) => {
|
|
||||||
return state.tempEditing
|
|
||||||
},
|
|
||||||
fonts: (state: Type.Object) => {
|
|
||||||
return state.fonts
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mutations: {
|
|
||||||
...mutations,
|
|
||||||
},
|
|
||||||
actions: {
|
actions: {
|
||||||
...actions,
|
/** 隐藏loading */
|
||||||
|
hideLoading() {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.loading = false
|
||||||
|
}, 600)
|
||||||
},
|
},
|
||||||
}
|
setFonts(list: string[]) {
|
||||||
export default all
|
this.fonts = list
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
export default useBaseStore
|
||||||
|
|
||||||
|
// const all = {
|
||||||
|
// state: {
|
||||||
|
// loading: null,
|
||||||
|
// online: true, // 登录状态,
|
||||||
|
// user: {
|
||||||
|
// name: localStorage.getItem('username'),
|
||||||
|
// }, // 储存用户信息
|
||||||
|
// scroll: true,
|
||||||
|
// manager: '', // 是否为管理员模式
|
||||||
|
// tempEditing: false, // 管理员是否正在编辑模板
|
||||||
|
// fonts: [], // 缓存字体列表
|
||||||
|
// app: null, // 抠图服务
|
||||||
|
// },
|
||||||
|
// getters: {
|
||||||
|
// online: (state: Type.Object) => {
|
||||||
|
// return state.online
|
||||||
|
// },
|
||||||
|
// user: (state: Type.Object) => {
|
||||||
|
// return state.user
|
||||||
|
// },
|
||||||
|
// manager: (state: Type.Object) => {
|
||||||
|
// return state.manager
|
||||||
|
// },
|
||||||
|
// tempEditing: (state: Type.Object) => {
|
||||||
|
// return state.tempEditing
|
||||||
|
// },
|
||||||
|
// fonts: (state: Type.Object) => {
|
||||||
|
// return state.fonts
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// mutations: {
|
||||||
|
// ...mutations,
|
||||||
|
// },
|
||||||
|
// actions: {
|
||||||
|
// ...actions,
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
|
||||||
|
@ -8,35 +8,35 @@
|
|||||||
|
|
||||||
// import { Toast } from 'vant'
|
// import { Toast } from 'vant'
|
||||||
|
|
||||||
export default {
|
// export default {
|
||||||
loading(state: Type.Object, data: any) {
|
// loading(state: Type.Object, data: any) {
|
||||||
// Toast.clear();
|
// // Toast.clear();
|
||||||
// let msg = ''
|
// // let msg = ''
|
||||||
// if (typeof data === 'string') {
|
// // if (typeof data === 'string') {
|
||||||
// msg = data
|
// // msg = data
|
||||||
// } else {
|
// // } else {
|
||||||
// Toast.clear();
|
// // Toast.clear();
|
||||||
// return false
|
// // return false
|
||||||
// }
|
// // }
|
||||||
// Toast.loading({
|
// // Toast.loading({
|
||||||
// duration: 0, // 持续展示 toast
|
// // duration: 0, // 持续展示 toast
|
||||||
// loadingType: 'spinner',
|
// // loadingType: 'spinner',
|
||||||
// message: msg
|
// // message: msg
|
||||||
// });
|
// // });
|
||||||
},
|
// },
|
||||||
changeRoute(state: Type.Object, from: string) {
|
// changeRoute(state: Type.Object, from: string) {
|
||||||
state.routeFrom = from
|
// state.routeFrom = from
|
||||||
},
|
// },
|
||||||
changeOnline(state: Type.Object, status: string) {
|
// changeOnline(state: Type.Object, status: string) {
|
||||||
state.online = status
|
// state.online = status
|
||||||
},
|
// },
|
||||||
changeUser(state: Type.Object, name: string) {
|
// changeUser(state: Type.Object, name: string) {
|
||||||
state.user.name = name
|
// state.user.name = name
|
||||||
// state.user = Object.assign({}, state.user)
|
// // state.user = Object.assign({}, state.user)
|
||||||
state.user = { ...state.user }
|
// state.user = { ...state.user }
|
||||||
localStorage.setItem('username', name)
|
// localStorage.setItem('username', name)
|
||||||
},
|
// },
|
||||||
managerEdit(state: Type.Object, status: string) {
|
// managerEdit(state: Type.Object, status: string) {
|
||||||
state.tempEditing = status
|
// state.tempEditing = status
|
||||||
},
|
// },
|
||||||
}
|
// }
|
||||||
|
58
src/store/modules/base/user.ts
Normal file
58
src/store/modules/base/user.ts
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* @Author: Jeremy Yu
|
||||||
|
* @Date: 2024-03-17 15:00:00
|
||||||
|
* @Description: User全局状态管理
|
||||||
|
* @LastEditors: Jeremy Yu <https://github.com/JeremyYu-cn>
|
||||||
|
* @LastEditTime: 2024-03-17 15:00:00
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { defineStore } from "pinia"
|
||||||
|
|
||||||
|
type TUserStoreState = {
|
||||||
|
/** 登录状态 */
|
||||||
|
online: boolean
|
||||||
|
/** 储存用户信息 */
|
||||||
|
user: {
|
||||||
|
name: string | null
|
||||||
|
}
|
||||||
|
/**是否为管理员模式 */
|
||||||
|
manager: string
|
||||||
|
/** 管理员是否正在编辑模板 */
|
||||||
|
tempEditing: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
type TUserAction = {
|
||||||
|
/** 修改登录状态 */
|
||||||
|
changeOnline: (state: boolean) => void
|
||||||
|
/** 修改登录用户 */
|
||||||
|
changeUser: (userName: string) => void
|
||||||
|
managerEdit: (status: boolean) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const useUserStore = defineStore<'userStore', TUserStoreState, {}, TUserAction>('userStore', {
|
||||||
|
state: () => ({
|
||||||
|
online: true, // 登录状态,
|
||||||
|
user: {
|
||||||
|
name: localStorage.getItem('username'),
|
||||||
|
}, // 储存用户信息
|
||||||
|
manager: '', // 是否为管理员模式
|
||||||
|
tempEditing: false, // 管理员是否正在编辑模板
|
||||||
|
}),
|
||||||
|
actions: {
|
||||||
|
changeOnline(status: boolean) {
|
||||||
|
this.online = status
|
||||||
|
},
|
||||||
|
changeUser(name: string) {
|
||||||
|
this.user.name = name
|
||||||
|
// state.user = Object.assign({}, state.user)
|
||||||
|
// state.user = { ...state.user }
|
||||||
|
localStorage.setItem('username', name)
|
||||||
|
},
|
||||||
|
managerEdit(status: boolean) {
|
||||||
|
this.tempEditing = status
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
export default useUserStore
|
@ -237,7 +237,7 @@ export default {
|
|||||||
if (activeElement.type === 'page') {
|
if (activeElement.type === 'page') {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
navigator.clipboard.writeText('') // 清空系统剪贴板内容
|
||||||
const container = []
|
const container = []
|
||||||
const selectWidgets = store.state.dSelectWidgets
|
const selectWidgets = store.state.dSelectWidgets
|
||||||
if (selectWidgets.length === 0) {
|
if (selectWidgets.length === 0) {
|
||||||
|
@ -29,7 +29,6 @@ const all = {
|
|||||||
dDraging: false, // 是否正在抓取组件
|
dDraging: false, // 是否正在抓取组件
|
||||||
dResizeing: false, // 是否正在调整组件宽高
|
dResizeing: false, // 是否正在调整组件宽高
|
||||||
dShowRefLine: true, // 是否显示参考线
|
dShowRefLine: true, // 是否显示参考线
|
||||||
|
|
||||||
dResizeWH: {
|
dResizeWH: {
|
||||||
// 初始化调整大小时组件的宽高
|
// 初始化调整大小时组件的宽高
|
||||||
width: 0,
|
width: 0,
|
||||||
|
0
src/store/pinia.ts
Normal file
0
src/store/pinia.ts
Normal file
@ -6,8 +6,10 @@
|
|||||||
* @LastEditTime: 2024-02-26 17:54:00
|
* @LastEditTime: 2024-02-26 17:54:00
|
||||||
*/
|
*/
|
||||||
import axios, { AxiosRequestConfig, AxiosResponse, AxiosStatic } from 'axios'
|
import axios, { AxiosRequestConfig, AxiosResponse, AxiosStatic } from 'axios'
|
||||||
import store from '@/store'
|
// import store from '@/store'
|
||||||
import app_config, { LocalStorageKey } from '@/config'
|
import app_config, { LocalStorageKey } from '@/config'
|
||||||
|
import useUserStore from '@/store/modules/base/user';
|
||||||
|
import useBaseStore from '@/store/modules/base';
|
||||||
|
|
||||||
axios.defaults.timeout = 30000
|
axios.defaults.timeout = 30000
|
||||||
axios.defaults.headers.authorization = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MTAwMDEsImV4cCI6MTc4ODU3NDc1MDU4NX0.L_t6DFD48Dm6rUPfgIgOWJkz18En1m_-hhMHcpbxliY';
|
axios.defaults.headers.authorization = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MTAwMDEsImV4cCI6MTc4ODU3NDc1MDU4NX0.L_t6DFD48Dm6rUPfgIgOWJkz18En1m_-hhMHcpbxliY';
|
||||||
@ -53,7 +55,8 @@ axios.interceptors.response.use((res: AxiosResponse<any>) => {
|
|||||||
}
|
}
|
||||||
if (res.data.code === 401) {
|
if (res.data.code === 401) {
|
||||||
console.log('登录失效')
|
console.log('登录失效')
|
||||||
store.commit('changeOnline', false)
|
useUserStore().changeOnline(false)
|
||||||
|
// store.commit('changeOnline', false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.data.result && res.data.code === 200) {
|
if (res.data.result && res.data.code === 200) {
|
||||||
@ -67,7 +70,8 @@ axios.interceptors.response.use((res: AxiosResponse<any>) => {
|
|||||||
(error) => {
|
(error) => {
|
||||||
// if (error.response.status === 401) {
|
// if (error.response.status === 401) {
|
||||||
// }
|
// }
|
||||||
store.dispatch('hideLoading')
|
useBaseStore().hideLoading()
|
||||||
|
// store.dispatch('hideLoading')
|
||||||
return Promise.reject(error)
|
return Promise.reject(error)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -12,7 +12,8 @@
|
|||||||
<span style="color: #999; font-size: 14px; margin-right: 0.5rem">{{ state.stateBollean ? '启用' : '停用' }}</span> <el-switch v-model="state.stateBollean" @change="stateChange" />
|
<span style="color: #999; font-size: 14px; margin-right: 0.5rem">{{ state.stateBollean ? '启用' : '停用' }}</span> <el-switch v-model="state.stateBollean" @change="stateChange" />
|
||||||
<div class="divide__line">|</div>
|
<div class="divide__line">|</div>
|
||||||
<el-button plain type="primary" @click="saveTemp">保存模板</el-button>
|
<el-button plain type="primary" @click="saveTemp">保存模板</el-button>
|
||||||
<el-button @click="$store.commit('managerEdit', false)">取消</el-button>
|
<el-button @click="userStore.managerEdit(false)">取消</el-button>
|
||||||
|
<!-- <el-button @click="$store.commit('managerEdit', false)">取消</el-button> -->
|
||||||
<div class="divide__line">|</div>
|
<div class="divide__line">|</div>
|
||||||
</template>
|
</template>
|
||||||
<!-- <el-button @click="draw">绘制(测试)</el-button> -->
|
<!-- <el-button @click="draw">绘制(测试)</el-button> -->
|
||||||
@ -39,6 +40,7 @@ import _config from '@/config'
|
|||||||
import useConfirm from '@/common/methods/confirm'
|
import useConfirm from '@/common/methods/confirm'
|
||||||
import wGroup from '@/components/modules/widgets/wGroup/wGroup.vue'
|
import wGroup from '@/components/modules/widgets/wGroup/wGroup.vue'
|
||||||
import { useSetupMapGetters } from '@/common/hooks/mapGetters'
|
import { useSetupMapGetters } from '@/common/hooks/mapGetters'
|
||||||
|
import useUserStore from '@/store/modules/base/user'
|
||||||
|
|
||||||
type TProps = {
|
type TProps = {
|
||||||
modelValue?: boolean
|
modelValue?: boolean
|
||||||
@ -60,6 +62,7 @@ const emit = defineEmits<TEmits>()
|
|||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
|
const userStore = useUserStore()
|
||||||
const canvasImage = ref<typeof SaveImage | null>(null)
|
const canvasImage = ref<typeof SaveImage | null>(null)
|
||||||
const {
|
const {
|
||||||
dPage, dWidgets, tempEditing, dHistory, dPageHistory
|
dPage, dWidgets, tempEditing, dHistory, dPageHistory
|
||||||
|
@ -58,6 +58,7 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
hmr: { overlay: false },
|
hmr: { overlay: false },
|
||||||
|
host: '127.0.0.1'
|
||||||
// proxy: {
|
// proxy: {
|
||||||
// '/api': {
|
// '/api': {
|
||||||
// target: '',
|
// target: '',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user