mirror of
https://github.com/palxiao/poster-design.git
synced 2025-07-15 16:02:19 +08:00
code: remove invalid file
This commit is contained in:
parent
1bf998beea
commit
f12b904202
@ -1,4 +1,4 @@
|
||||
[在线体验](https://design.palxp.com/) | [文档网站](https://xp.palxp.com/) | [项目架构及目录](https://xp.palxp.com/#/articles/1689321259854)
|
||||
** [在线体验](https://design.palxp.com/) | [文档网站](https://xp.palxp.com/) | [项目架构及目录](https://xp.palxp.com/#/articles/1689321259854) **
|
||||
|
||||
## 迅排设计
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
|
||||
### 拉取源码
|
||||
|
||||
> 环境需求:**Node.js v16** 以上版本
|
||||
> 环境需求:**Node.js v16.18** 以上版本
|
||||
|
||||
```
|
||||
git clone https://github.com/palxiao/poster-design.git
|
||||
|
@ -1,15 +1,21 @@
|
||||
/*
|
||||
* @Author: ShawnPhang
|
||||
* @Date: 2021-09-30 16:28:40
|
||||
* @Description: 加载遮罩 / 弹窗
|
||||
* @Description: 弹出提示
|
||||
* @LastEditors: ShawnPhang
|
||||
* @LastEditTime: 2022-01-20 18:19:20
|
||||
*/
|
||||
import { ElNotification } from 'element-plus'
|
||||
export default (title: string, message: string = '', type: any = 'success') => {
|
||||
|
||||
interface ElNotifi {
|
||||
type?: 'success' | 'warning' | 'info' | 'error' | ''
|
||||
position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'
|
||||
}
|
||||
|
||||
export default (title: string, message: string = '', extra?: ElNotifi) => {
|
||||
ElNotification({
|
||||
title,
|
||||
message,
|
||||
type,
|
||||
...extra,
|
||||
})
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
<!--
|
||||
* @Author: ShawnPhang
|
||||
* @Date: 2021-08-01 11:12:17
|
||||
* @Description: 前端出图 - 生成封面
|
||||
* @Description: 前端出图 - 用于封面
|
||||
* @LastEditors: ShawnPhang <site: book.palxp.com>
|
||||
* @LastEditTime: 2023-07-11 19:47:24
|
||||
* @LastEditTime: 2023-07-26 10:22:17
|
||||
-->
|
||||
<template>
|
||||
<div id="cover-wrap">
|
||||
@ -24,21 +24,6 @@ export default defineComponent({
|
||||
setup(props, context) {
|
||||
let gridSizeIndex: number = 0
|
||||
|
||||
// function fileOrBlobToDataURL(obj: any, cb: Function) {
|
||||
// let a = new FileReader()
|
||||
// a.readAsDataURL(obj)
|
||||
// a.onload = (e: any) => {
|
||||
// cb(e.target.result)
|
||||
// }
|
||||
// }
|
||||
// function blobToImage(blob: any) {
|
||||
// return new Promise((resolve) => {
|
||||
// fileOrBlobToDataURL(blob, (dataurl: string) => {
|
||||
// resolve(dataurl)
|
||||
// })
|
||||
// })
|
||||
// }
|
||||
|
||||
const { proxy }: any = getCurrentInstance() as ComponentInternalInstance
|
||||
|
||||
async function createCover(cb: any) {
|
||||
@ -57,8 +42,8 @@ export default defineComponent({
|
||||
setTimeout(async () => {
|
||||
html2canvas(document.getElementById('page-design-canvas'), opts).then((canvas: any) => {
|
||||
canvas.toBlob(
|
||||
async function (blobObj: Blob) {
|
||||
const result: any = await Qiniu.upload(blobObj, { bucket: 'cloud-design', prePath: 'cover/user' })
|
||||
async (blobObj: Blob) => {
|
||||
const result: any = await Qiniu.upload(blobObj, { bucket: 'xp-design', prePath: 'cover/user' })
|
||||
cb(result)
|
||||
},
|
||||
'image/jpeg',
|
||||
|
@ -1,253 +0,0 @@
|
||||
<!--
|
||||
* @Author: ShawnPhang
|
||||
* @Date: 2021-08-01 11:12:17
|
||||
* @Description: 前端出图 - 已废弃
|
||||
* @LastEditors: ShawnPhang <site: book.palxp.com>
|
||||
* @LastEditTime: 2023-07-11 16:58:34
|
||||
-->
|
||||
<template>
|
||||
<div v-show="fillInfoing" class="fill-info-wrap">
|
||||
<div v-loading="loading" class="fill-info-content">
|
||||
<div class="fill-info-step">
|
||||
<div id="cover-wrap">
|
||||
<img id="cover" />
|
||||
</div>
|
||||
<div class="publish-btn" @click="saveImg">
|
||||
<span v-show="!publishing">下载图片</span>
|
||||
<i v-show="publishing" class="el-icon-loading"></i>
|
||||
</div>
|
||||
<div class="close-publish" @click="closePublish">关闭</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, reactive, toRefs, watch, getCurrentInstance, ComponentInternalInstance } from 'vue'
|
||||
import { mapGetters, mapActions } from 'vuex'
|
||||
import html2canvas from 'html2canvas'
|
||||
import api from '@/api'
|
||||
import useLoading from '@/common/methods/loading'
|
||||
|
||||
export default defineComponent({
|
||||
props: ['modelValue'],
|
||||
emits: ['update:modelValue'],
|
||||
setup(props, context) {
|
||||
let gridSizeIndex: number = 0
|
||||
|
||||
const state = reactive({
|
||||
fillInfoing: false,
|
||||
loading: false,
|
||||
publishing: false,
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(open) => {
|
||||
if (open) {
|
||||
save()
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
const closePublish = () => {
|
||||
state.fillInfoing = false
|
||||
context.emit('update:modelValue', false)
|
||||
}
|
||||
|
||||
function fileOrBlobToDataURL(obj: any, cb: Function) {
|
||||
let a = new FileReader()
|
||||
a.readAsDataURL(obj)
|
||||
a.onload = (e: any) => {
|
||||
cb(e.target.result)
|
||||
}
|
||||
}
|
||||
function blobToImage(blob: any) {
|
||||
return new Promise((resolve) => {
|
||||
fileOrBlobToDataURL(blob, (dataurl: string) => {
|
||||
resolve(dataurl)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const { proxy }: any = getCurrentInstance() as ComponentInternalInstance
|
||||
|
||||
async function save() {
|
||||
// state.loading = true
|
||||
// state.fillInfoing = true
|
||||
let nowGrideSizeIndex = gridSizeIndex
|
||||
let nowZoom = proxy?.dZoom
|
||||
// 取消选中元素
|
||||
proxy?.selectWidget({
|
||||
uuid: '-1',
|
||||
})
|
||||
gridSizeIndex = 0
|
||||
proxy?.updateZoom(100)
|
||||
const opts = {
|
||||
useCORS: true, // 跨域图片
|
||||
scale: 0.4,
|
||||
}
|
||||
setTimeout(async () => {
|
||||
html2canvas(document.getElementById('page-design-canvas'), opts).then((canvas) => {
|
||||
canvas.toBlob(
|
||||
async (blob: any) => {
|
||||
const data = await blobToImage(blob)
|
||||
document.getElementById('cover').src = data
|
||||
state.loading = false
|
||||
gridSizeIndex = nowGrideSizeIndex
|
||||
proxy?.updateZoom(nowZoom)
|
||||
proxy?.saveImg()
|
||||
},
|
||||
'image/jpeg',
|
||||
0.2,
|
||||
)
|
||||
})
|
||||
}, 300)
|
||||
}
|
||||
|
||||
function saveImg() {
|
||||
if (state.publishing) {
|
||||
return
|
||||
}
|
||||
state.publishing = true
|
||||
let image = new Image()
|
||||
// 解决跨域 Canvas 污染问题
|
||||
image.setAttribute('crossOrigin', 'anonymous')
|
||||
image.onload = function () {
|
||||
let canvas = document.createElement('canvas')
|
||||
canvas.width = image.width
|
||||
canvas.height = image.height
|
||||
|
||||
const context = canvas.getContext('2d')
|
||||
context?.drawImage(image, 0, 0, image.width, image.height)
|
||||
let url = canvas.toDataURL('image/png')
|
||||
|
||||
let a = document.createElement('a')
|
||||
let event = new MouseEvent('click')
|
||||
|
||||
// 将a的download属性设置为我们想要下载的图片名称,若name不存在则使用‘ ’作为默认名称
|
||||
a.download = name || '生成图片'
|
||||
a.href = url
|
||||
|
||||
// 触发a的单击事件
|
||||
a.dispatchEvent(event)
|
||||
}
|
||||
|
||||
image.src = document.getElementById('cover').src
|
||||
state.publishing = false
|
||||
state.fillInfoing = false
|
||||
}
|
||||
|
||||
async function createImg(cb: any) {
|
||||
let loading: any = useLoading('保存封面中')
|
||||
let nowGrideSizeIndex = gridSizeIndex
|
||||
let nowZoom = proxy?.dZoom
|
||||
// 取消选中元素
|
||||
proxy?.selectWidget({
|
||||
uuid: '-1',
|
||||
})
|
||||
gridSizeIndex = 0
|
||||
proxy?.updateZoom(100)
|
||||
const opts = {
|
||||
useCORS: true, // 跨域图片
|
||||
scale: 0.4,
|
||||
}
|
||||
setTimeout(async () => {
|
||||
html2canvas(document.getElementById('page-design-canvas'), opts).then(async (canvas) => {
|
||||
cb(canvas.toDataURL('image/jpeg', 0.6))
|
||||
gridSizeIndex = nowGrideSizeIndex
|
||||
proxy?.updateZoom(nowZoom)
|
||||
loading.close()
|
||||
})
|
||||
}, 301)
|
||||
}
|
||||
|
||||
return {
|
||||
save,
|
||||
closePublish,
|
||||
saveImg,
|
||||
createImg,
|
||||
...toRefs(state),
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['dZoom', 'dPage']),
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['selectWidget', 'updateZoom']),
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
// Width variables (appears count calculates by raw css)
|
||||
@width00: 400px; // Appears 2 times
|
||||
@width20: 100%; // Appears 2 times
|
||||
|
||||
// Height variables (appears count calculates by raw css)
|
||||
@height20: 400px; // Appears 2 times
|
||||
|
||||
.fill-info-wrap {
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
height: 100%;
|
||||
padding: 50px;
|
||||
position: absolute;
|
||||
width: @width20;
|
||||
z-index: 9999;
|
||||
.fill-info-content {
|
||||
background-color: @color-white;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0 auto;
|
||||
max-height: 861px;
|
||||
min-height: 600px;
|
||||
padding: 20px;
|
||||
width: 600px;
|
||||
.fill-info-step {
|
||||
flex: 1;
|
||||
width: @width20;
|
||||
#cover-wrap {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
height: @height20;
|
||||
justify-content: center;
|
||||
margin: 20px auto;
|
||||
width: @width00;
|
||||
#cover {
|
||||
box-shadow: 1px 1px 10px 3px rgba(0, 0, 0, 0.1);
|
||||
max-height: @height20;
|
||||
max-width: @width00;
|
||||
}
|
||||
}
|
||||
.publish-btn {
|
||||
background-color: @color-main;
|
||||
border-radius: 5px;
|
||||
color: @color-white;
|
||||
cursor: pointer;
|
||||
margin: 20px auto;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
&:hover {
|
||||
background-color: @color-dark-gray;
|
||||
}
|
||||
}
|
||||
.close-publish {
|
||||
background-color: @color-white;
|
||||
border-radius: 5px;
|
||||
color: @color-main;
|
||||
cursor: pointer;
|
||||
margin-bottom: 0px;
|
||||
margin: 20px auto;
|
||||
outline: 1px solid @color-main;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
&:hover {
|
||||
background-color: @color-dark-gray;
|
||||
color: @color-white;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -19,6 +19,7 @@ import { ElUpload } from 'element-plus'
|
||||
import Qiniu from '@/common/methods/QiNiu'
|
||||
import { getImage } from '@/common/methods/getImgDetail'
|
||||
import _config from '@/config'
|
||||
import useNotification from '@/common/methods/notification'
|
||||
|
||||
export default defineComponent({
|
||||
components: { ElUpload },
|
||||
@ -26,7 +27,7 @@ export default defineComponent({
|
||||
modelValue: {},
|
||||
options: {
|
||||
default: () => {
|
||||
return { bucket: 'cloud-design', prePath: 'user' }
|
||||
return { bucket: 'xp-design', prePath: 'user' }
|
||||
},
|
||||
},
|
||||
hold: {
|
||||
@ -69,10 +70,14 @@ export default defineComponent({
|
||||
const uploadQueue = async () => {
|
||||
if (!uploading) {
|
||||
uploading = true
|
||||
if (uploadList[0]) {
|
||||
tempSimpleRes = await qiNiuUpload(uploadList[0]) // 队列有文件,执行上传
|
||||
const { width, height }: any = await getImage(uploadList[0])
|
||||
context.emit('done', { width, height, url: _config.IMG_URL + tempSimpleRes.key }) // 单个文件进行响应
|
||||
const file = uploadList[0]
|
||||
if (file) {
|
||||
if (file.size <= 1024 * 1024) {
|
||||
tempSimpleRes = await qiNiuUpload(file) // 队列有文件,执行上传
|
||||
const { width, height }: any = await getImage(file)
|
||||
useNotification('上传成功', '目前没有用户系统,请注意别上传隐私照片哦!', { position: 'bottom-left' })
|
||||
context.emit('done', { width, height, url: _config.IMG_URL + tempSimpleRes.key }) // 单个文件进行响应
|
||||
} else useNotification('爱护小水管', '请上传小于 1M 的图片哦!', { type: 'error', position: 'bottom-left' })
|
||||
uploading = false
|
||||
handleRemove() // 移除已上传文件
|
||||
index++
|
||||
@ -110,10 +115,7 @@ export default defineComponent({
|
||||
context.emit('update:modelValue', percent)
|
||||
}
|
||||
const handleRemove = () => {
|
||||
if (uploadList.length <= 0) {
|
||||
return
|
||||
}
|
||||
uploadList.splice(0, 1)
|
||||
uploadList.length > 0 && uploadList.splice(0, 1)
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -70,10 +70,10 @@ export default {
|
||||
fontSize: 24,
|
||||
zoom: 1,
|
||||
fontClass: {
|
||||
alias: '思源黑体 常规',
|
||||
id: 206607,
|
||||
value: 'SourceHanSansSC-Regular',
|
||||
url: 'https://font.palxp.com/SourceHanSansSC-Regular.woff',
|
||||
alias: '素材集市酷方体',
|
||||
id: 33925853,
|
||||
value: 'sucaijishikufangti',
|
||||
url: 'https://res.palxp.com/static/fonts/20200809-152508-8654.woff',
|
||||
},
|
||||
fontFamily: 'SourceHanSansSC-Regular',
|
||||
fontWeight: 'normal',
|
||||
|
20
src/config.ts
Normal file
20
src/config.ts
Normal file
@ -0,0 +1,20 @@
|
||||
// const prefix = import.meta.env
|
||||
const prefix = process.env
|
||||
|
||||
const isDev = prefix.NODE_ENV === 'development'
|
||||
|
||||
export default {
|
||||
isDev,
|
||||
BASE_URL: isDev ? '/' : './',
|
||||
VERSION: '1.1.0',
|
||||
APP_NAME: '迅排设计',
|
||||
COPYRIGHT: 'ShawnPhang - Palxp.com',
|
||||
// API_URL: isDev ? 'http://localhost:9998' : '${API}',
|
||||
API_URL: 'https://app.palxp.com:8887',
|
||||
SCREEN_URL: isDev ? 'http://localhost:7001' : '${SCREEN_URL}',
|
||||
IMG_URL: 'https://store.palxp.com/',
|
||||
// ICONFONT_URL: '//at.alicdn.com/t/font_3223711_74mlzj4jdue.css',
|
||||
ICONFONT_URL: '//at.alicdn.com/t/font_2717063_ypy8vprc3b.css',
|
||||
ICONFONT_EXTRA: '//at.alicdn.com/t/c/font_3228074_6qsac4kteu7.css',
|
||||
QINIUYUN_PLUGIN: 'https://cdn.jsdelivr.net/npm/qiniu-js@2.5.5/dist/qiniu.min.js',
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
* @Date: 2022-01-10 14:57:53
|
||||
* @Description: Psd文件解析
|
||||
* @LastEditors: ShawnPhang <site: book.palxp.com>
|
||||
* @LastEditTime: 2023-07-25 17:03:02
|
||||
* @LastEditTime: 2023-07-25 15:56:22
|
||||
-->
|
||||
<template>
|
||||
<div id="page-design-index" ref="pageDesignIndex">
|
||||
|
@ -64,7 +64,7 @@ export default defineComponent({
|
||||
const cover = hasCover ? await proxy?.draw() : undefined
|
||||
const widgets = proxy.dWidgets // reviseData()
|
||||
const { id: newId, stat, msg } = await api.home.saveWorks({ cover, id, title: proxy.title || '未命名设计', data: JSON.stringify({ page: proxy.dPage, widgets }), temp_id: tempid, width: proxy.dPage.width, height: proxy.dPage.height })
|
||||
stat !== 0 ? useNotification('保存成功', '可在"我的作品"中查看') : useNotification('保存失败', msg, 'error')
|
||||
stat !== 0 ? useNotification('保存成功', '可在"我的作品"中查看') : useNotification('保存失败', msg, { type: 'error' })
|
||||
!id && router.push({ path: '/home', query: { id: newId }, replace: true })
|
||||
store.commit('setShowMoveable', true)
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ export default defineComponent({
|
||||
context.emit('change', { downloadPercent: 95, downloadText: '正在处理封面', downloadMsg: '即将结束...' })
|
||||
const cover = await draw()
|
||||
const { id, stat, msg } = await api.home.saveWorks({ cover, title: '自设计模板', data: JSON.stringify({ page, widgets }), width: page.width, height: page.height })
|
||||
stat !== 0 ? useNotification('保存成功', '可在"我的模板"中查看') : useNotification('保存失败', msg, 'error')
|
||||
stat !== 0 ? useNotification('保存成功', '可在"我的模板"中查看') : useNotification('保存失败', msg, { type: 'error' })
|
||||
router.push({ path: '/psd', query: { id }, replace: true })
|
||||
context.emit('change', { downloadPercent: 99.99, downloadText: '上传完成', cancelText: '查看我的作品' }) // 关闭弹窗
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user