This commit is contained in:
熊丽君
2021-09-03 18:35:07 +08:00
parent 7cdaf34735
commit 0178fba4b8
34 changed files with 759 additions and 264 deletions

View File

@ -7,8 +7,11 @@
clearable
v-model="search"
placeholader="搜索内容"
class="width-200" size="mini" suffix-icon="el-icon-search">
<el-button slot="append">搜索</el-button>
class="width-200"
size="mini"
suffix-icon="el-icon-search"
>
<el-button slot="append">搜索</el-button>
</el-input>
</div>
</div>
@ -19,11 +22,12 @@
class="list-item cursor-p"
:key="item.uid"
v-for="(item, i) in imageList"
:style="{background: item.bg}">
:style="{ background: item.bg }"
>
<el-checkbox class="check-ct" :value="item.active"></el-checkbox>
<img :src="item.path" class="img"/>
<img :src="item.path" class="img" />
<div class="text single-row-ellipsis">
{{item.name}}
{{ item.name }}
</div>
</div>
</div>
@ -35,7 +39,7 @@
</div>
</template>
<script>
import uuid from 'uuid'
import uuid from 'uuid';
export default {
props: {
// 是否单选
@ -47,39 +51,39 @@ export default {
type: Object
}
},
data () {
data() {
return {
search: '',
imageList: [
{
uid: uuid(),
name: '钢铁侠',
path: require('../assets/image/1.jpg')
path: require('../assets/image/profile.jpg')
},
{
uid: uuid(),
name: '蜘蛛侠',
path: require('../assets/image/2.jpg')
path: require('../assets/image/profile.jpg')
},
{
uid: uuid(),
name: '美国队长',
path: require('../assets/image/3.jpg')
path: require('../assets/image/profile.jpg')
},
{
uid: uuid(),
name: '奇异博士',
path: require('../assets/image/4.jpg')
path: require('../assets/image/profile.jpg')
},
{
uid: uuid(),
name: '蚁人',
path: require('../assets/image/5.jpg')
path: require('../assets/image/profile.jpg')
},
{
uid: uuid(),
name: '钢铁侠2',
path: require('../assets/image/6.jpg')
path: require('../assets/image/profile.jpg')
}
],
activeIndex: -1,
@ -90,63 +94,67 @@ export default {
tagSelect: ''
// systemMaterialListCount: 0,
// materialListCount: 0
}
};
},
methods: {
handleClickImageItem (i, item) {
this.isSingle ? this.singleModeClick(i, item) : this.multipleModeClick(i, item)
handleClickImageItem(i, item) {
this.isSingle
? this.singleModeClick(i, item)
: this.multipleModeClick(i, item);
},
singleModeClick (i, item) {
singleModeClick(i, item) {
if (i === this.activeIndex) {
this.$set(this.imageList, i, { ...item, active: false })
this.activeIndex = -1
this.$set(this.imageList, i, { ...item, active: false });
this.activeIndex = -1;
} else {
let oldItem = this.imageList[this.activeIndex]
this.$set(this.imageList, this.activeIndex, { ...oldItem, active: false })
this.activeIndex = i
this.$set(this.imageList, this.activeIndex, { ...item, active: true })
let oldItem = this.imageList[this.activeIndex];
this.$set(this.imageList, this.activeIndex, {
...oldItem,
active: false
});
this.activeIndex = i;
this.$set(this.imageList, this.activeIndex, { ...item, active: true });
}
},
multipleModeClick (i, item) {
this.$set(this.imageList, i, { ...item, active: !item.active })
multipleModeClick(i, item) {
this.$set(this.imageList, i, { ...item, active: !item.active });
},
reset () {
reset() {
this.imageList.forEach(v => {
v.active = false
})
v.active = false;
});
},
async submit () {
let imageSelection = this.imageList.filter(v => v.active)
async submit() {
let imageSelection = this.imageList.filter(v => v.active);
if (imageSelection.length === 0) {
this.$message.error('请选择图片!')
return false
this.$message.error('请选择图片!');
return false;
}
this.$emit('success', this.isSingle ? imageSelection[0] : imageSelection)
this.reset()
this.$emit('success', this.isSingle ? imageSelection[0] : imageSelection);
this.reset();
},
cancel () {
this.$emit('cancel')
this.reset()
cancel() {
this.$emit('cancel');
this.reset();
}
},
watch: {
value (val) {
value(val) {
if (val) {
// this.findBackground()
}
}
},
async created () {
}
}
async created() {}
};
</script>
<style lang="scss" scoped>
* {
box-sizing: border-box;
}
.image-selection-comp{
* {
box-sizing: border-box;
}
.image-selection-comp {
position: relative;
.header-ct{
.header-ct {
display: flex;
justify-content: space-between;
align-items: center;
@ -155,30 +163,30 @@ export default {
font-weight: 400;
color: rgba(44, 62, 80, 1);
}
.right{
.right {
display: flex;
}
}
.main{
.main {
display: flex;
.left{
.left {
box-sizing: border-box;
width: 200px;
height: 400px;
border-right: 1px solid #E4E8EB;
.type-child-item{
border-right: 1px solid #e4e8eb;
.type-child-item {
position: relative;
padding-left: 24px;
height: 32px;
line-height: 32px;
&.active{
background: #409EFF;
&.active {
background: #409eff;
color: white;
&:before{
&:before {
background: white;
}
}
&:before{
&:before {
content: '';
display: block;
position: absolute;
@ -193,7 +201,7 @@ export default {
}
}
}
.right{
.right {
flex: 1;
display: grid;
flex-wrap: wrap;
@ -202,31 +210,31 @@ export default {
grid-row-gap: 8px;
grid-column-gap: 8px;
margin-left: 16px;
.list-item{
.list-item {
position: relative;
width: 144px;
height: 144px;
border: 1px solid #e1e1e1;
overflow: hidden;
.check-ct{
.check-ct {
position: absolute;
top: 8px;
left: 8px;
}
.img{
.img {
display: block;
width: 100%;
height: 100.8px;
}
}
.text{
.text {
height: 43px;
line-height: 43px;
text-align: center;
}
}
}
.bottom-ct{
.bottom-ct {
/*position: absolute;
left: 0;
bottom: 0;*/

View File

@ -1,12 +1,14 @@
<template>
<svg
:class="{active: active}"
class="icon el-icon cursor-p" aria-hidden="true">
:class="{ active: active }"
class="icon el-icon cursor-p"
aria-hidden="true"
>
<use :xlink:href="'#icon-' + icon"></use>
</svg>
</template>
<script>
import './iconfont.js'
import './iconfont.js';
export default {
props: {
icon: {
@ -18,18 +20,18 @@ export default {
default: false
}
}
}
};
</script>
<style lang="scss">
.icon{
.icon {
font-size: 18px;
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: rgba(0,0,0,0.5);
fill: rgba(255, 255, 255, 1);
overflow: hidden;
&.active{
fill: rgba(0,0,0,1);
&.active {
fill: rgba(0, 0, 0, 1);
}
}
</style>

View File

@ -24,15 +24,12 @@ export default {
type: Number,
required: true
}
},
created() {
console.log(this.value);
}
};
</script>
<style lang="scss">
.img-widget-ct {
width: 100%;
// width: 100%;
height: 100%;
user-select: none;
}

View File

@ -9,7 +9,12 @@
@click="getHistory(-1)"
type="text"
>
<Icon :active="canClickPrev" class="m-r-16" icon="Undo"></Icon>
<Icon
style="color:#fff"
:active="canClickPrev"
class="m-r-16"
icon="Undo"
></Icon>
</el-button>
</el-tooltip>
<el-tooltip effect="dark" content="前进" placement="top-start">
@ -26,7 +31,8 @@
轻点元素开始编辑
</div>
<div class="right">
<el-button @click="submitImg">提交</el-button>
<el-button size="small" @click="resetItme">重置</el-button>
<el-button size="small" @click="submitImg">保存并返回</el-button>
</div>
</div>
<draggable
@ -42,7 +48,19 @@
class="poster-content m-b-16"
tag="div"
>
<img class="bg-puppet" :src="value && value.background.img" />
<div>
<vue-canvas-poster
v-show="true"
:painting="painting"
@success="success"
@fail="fail"
></vue-canvas-poster>
</div>
<img
v-show="value.background.img"
class="bg-puppet"
:src="value && value.background.img"
/>
<widget
:class="{ disabled: !item.active }"
@click.native="handleActiveWidget(item)"
@ -256,6 +274,7 @@ import { setDataRangeMap, defaultDataMap } from './widgetInitDataMap';
import Icon from './icon/index';
import { qrUpdate } from '@/api/index';
import VueQr from 'vue-qr';
import { VueCanvasPoster } from 'vue-canvas-poster';
let zIndex = 0;
@ -278,8 +297,8 @@ export default {
type: Object,
default() {
return {
width: 375,
height: 620
width: 620,
height: 375
};
}
}
@ -291,10 +310,30 @@ export default {
blankDialog,
imageSelection,
Icon,
VueQr
VueQr,
VueCanvasPoster
},
data() {
return {
painting: {
width: '120px',
height: '120px',
background: '#eee',
views: [
{
type: 'qrcode',
content: 'http://golden.shangqie.cn/#/?id=' + this.id,
css: {
top: '0',
left: '0',
color: '#000',
width: '120px',
height: '120px'
}
}
]
},
imgArr: '',
editorUid: 'uid' + uuid(),
dZoom: 0.52,
isDragging: false,
@ -311,12 +350,36 @@ export default {
};
},
methods: {
resetItme() {
this.$emit('resetData');
},
success(e) {
this.imgArr = e;
},
fail(e) {
console.log(e);
},
submitImg() {
// const
console.log(this.id);
// qrUpdate(this.value).then(res => {
// console.log(res);
// });
html2canvas(
document
.querySelector(`#${this.editorUid}`)
.querySelector('.poster-content'),
{
useCORS: true,
// 编辑器缩放保持 960 * 720 的尺寸
scale: 1 / this.dZoom
}
).then(canvas => {
localStorage.setItem('itemImg', canvas.toDataURL());
qrUpdate({
id: this.id,
notice: JSON.stringify(this.value),
noticePic: localStorage.getItem('itemImg')
}).then(({ message }) => {
this.msgSuccess(message);
this.$router.go(-1);
});
});
},
beforeAddImgWidget(imgObj) {
this.addWidget('img', imgObj.path);
@ -344,7 +407,6 @@ export default {
this.$nextTick(() => {
this.handleActiveWidget(item);
});
console.log(this.value);
this.$emit('input', {
background: this.value.background,
widgetList: this.widgetList
@ -442,6 +504,7 @@ export default {
this.widgetList.forEach(w => {
w.active = false;
});
let that = this;
return new Promise(resolve => {
// 激活当前编辑器 方便截图
this.$emit('active');
@ -456,17 +519,28 @@ export default {
scale: 1 / this.dZoom
}
).then(async canvas => {
console.timeEnd('1');
console.time('2');
// console.timeEnd('1');
// console.time('2');
localStorage.setItem('itemImg', canvas.toDataURL());
let file = canvas
.toDataURL('image/jpeg', 1)
.replace('data:image/jpeg;base64,', '');
// console.log('图片');
// console.log(file);
// base64的图片
console.timeEnd('2');
console.time('3');
// console.timeEnd('2');
// console.time('3');
const link = document.createElement('a');
link.href = canvas.toDataURL();
link.setAttribute('download', new Date().getTime() + '.png');
link.style.display = 'none';
document.body.appendChild(link);
link.click();
if (cb) {
await cb(file, resolve);
console.timeEnd('3');
// console.timeEnd('3');
instance.close();
}
});
@ -474,7 +548,7 @@ export default {
});
},
changeBackground(imgUrl) {
console.log((this.value.background.img = imgUrl));
this.value.background.img = imgUrl;
// this.value.background = imgUrl;
// this.value.material_uid = imgObj.uid;
// this.value.materialType = imgObj.expandType;
@ -482,7 +556,6 @@ export default {
},
changeTextColor(color) {
this.value.background.color = color;
console.log(this.value.background);
},
pushHistory(type, item, index) {
const obj = {
@ -598,6 +671,168 @@ export default {
}
},
deep: true
},
imgArr() {
// 解决多次合并
const noticeItem = localStorage.getItem('notice');
if (noticeItem == 'null') {
const item = [
{
label: '图片',
type: 'img',
content: this.imgArr,
uuid: '32a' + +new Date(),
active: false,
style: {
top: 129,
left: 86,
height: 120,
width: 120,
align: { x: 0, y: 0 },
lineHeight: 14,
fontSize: 14,
background: 'rgba(0, 0, 0, 0)',
color: 'rgba(0, 0, 0, 1)',
letterSpacing: 0,
isOblique: false,
isBold: false,
zIndex: 1
},
setDataRange: {
box: {
show: true,
detail: {
top: true,
left: true,
height: true,
width: true,
background: false,
zIndex: true
}
},
content: {
show: false
},
innerStyle: {
show: false,
detail: {
align: true,
lineHeight: true,
fontSize: true,
color: true,
letterSpacing: true,
isOblique: true,
isBold: true
}
}
}
},
{
label: '文本',
type: 'text',
content: '提货须知',
uuid: '32b' + +new Date(),
active: false,
style: {
top: 108,
left: 269,
height: 40,
width: 120,
align: { x: 0, y: 0 },
lineHeight: 14,
fontSize: 18,
background: 'rgba(0, 0, 0, 0)',
color: 'rgba(0, 0, 0, 1)',
letterSpacing: 0,
isOblique: false,
isBold: true,
zIndex: 1
},
setDataRange: {
box: {
show: true,
detail: {
top: true,
left: true,
height: true,
width: true,
background: false,
zIndex: true
}
},
content: {
show: false
},
innerStyle: {
show: false,
detail: {
align: true,
lineHeight: true,
fontSize: true,
color: true,
letterSpacing: true,
isOblique: true,
isBold: true
}
}
}
},
{
label: '文本',
type: 'text',
content: `&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. 微信或者手机浏览器扫码提货卡二维码,填写姓名、手机号、邮寄地址,点击“我要提货”<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. 一个手机号仅限验证一次,提交地址后即可失效<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3. 有问题请联系客服 0551-63442479`,
uuid: '32c' + +new Date(),
active: false,
style: {
top: 142,
left: 268,
height: 155,
width: 345,
align: { x: 0, y: 0 },
lineHeight: 30,
fontSize: 16,
background: 'rgba(0, 0, 0, 0)',
color: 'rgba(0, 0, 0, 1)',
letterSpacing: 0,
isOblique: false,
isBold: false,
zIndex: 1
},
setDataRange: {
box: {
show: true,
detail: {
top: true,
left: true,
height: true,
width: true,
background: false,
zIndex: true
}
},
content: {
show: false
},
innerStyle: {
show: false,
detail: {
align: true,
lineHeight: true,
fontSize: true,
color: true,
letterSpacing: true,
isOblique: true,
isBold: false
}
}
}
}
];
this.value.widgetList = [...this.value.widgetList, ...item];
} else {
}
}
},
mounted() {
@ -609,6 +844,7 @@ export default {
window.removeEventListener('resize', this.handleResizeFn);
},
created() {
console.log(this.value);
this.widgetList = this.value.widgetList || [];
this.widgetList.forEach(v => {
v.history = {
@ -627,6 +863,7 @@ export default {
display: flex;
min-width: 830px;
.main-pane {
background-color: #7f7f7f;
position: relative;
flex: 1;
padding: 0 16px;
@ -643,11 +880,13 @@ export default {
}
}
.center {
color: #fff;
flex: 1;
}
}
.poster-content {
top: 40px;
border: 1px solid #ccc;
top: 100px;
left: 50%;
position: absolute;
/*min-width: 480px;

View File

@ -3,8 +3,10 @@
:style="{
transform: `scale(${needScale ? dZoom : 1})`
}"
class="text-widget-ct">
{{value}}
class="text-widget-ct"
v-html="value"
>
<!-- {{value}} -->
</div>
</template>
<script>
@ -24,10 +26,10 @@ export default {
required: true
}
}
}
};
</script>
<style lang="scss">
.text-widget-ct {
user-select: none;
}
.text-widget-ct {
user-select: none;
}
</style>

View File

@ -5,15 +5,6 @@
}"
class="widget-ct cursor-p"
>
<widgetWrapper
:d-zoom="dZoom"
:page="page"
:show-wrapper="showWrapper"
:widget-data="widgetData"
:widget-name="widgetData.type"
>
<vue-qr text="123" :size="140"></vue-qr>
</widgetWrapper>
<widgetWrapper
:d-zoom="dZoom"
:page="page"
@ -36,12 +27,6 @@ import widgetWrapper from './widgetWrapper';
import textWidget from './textWidget';
import imgWidget from './imgWidget';
export default {
created() {
console.log(this.dZoom);
console.log(this.widgetData);
console.log(this.showWrapper);
console.log(this.page);
},
props: {
dZoom: {
type: Number,