2.6发版合并

This commit is contained in:
X1627315083
2025-02-05 10:09:53 +08:00
177 changed files with 15452 additions and 9320 deletions

View File

@@ -5,8 +5,8 @@ NODE_ENV = 'development'
# VUE_APP_BASE_URL = 'http://18.167.251.121:10086'
VUE_APP_BASE_URL = 'https://develop.api.aida.com.hk'
# VUE_APP_BASE_URL = 'https://www.api.aida.com.hk'
#
#
# VUE_APP_BASE_URL = 'http://192.168.1.4:5567'
# 海波
# VUE_APP_BASE_URL = 'http://192.168.1.9:5567'
# VUE_APP_BASE_URL = 'http://192.168.1.2:5567'

Binary file not shown.

After

Width:  |  Height:  |  Size: 952 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 746 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 817 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 888 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1020 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 849 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 443 KiB

After

Width:  |  Height:  |  Size: 766 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 432 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 424 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 376 KiB

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 456 KiB

After

Width:  |  Height:  |  Size: 546 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 365 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 428 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 477 KiB

After

Width:  |  Height:  |  Size: 324 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 503 KiB

View File

@@ -9,6 +9,7 @@
<title>AiDA</title>
<!-- <link href="https://fonts.font.im/css?family=Roboto:400,500,700,700i" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700;900&display=swap" rel="stylesheet"> -->
<!-- 字体css -->
<link rel="stylesheet" href="/css/googleapis.css">
<link rel="stylesheet" href="/css/roboto.css">
<link rel="stylesheet" href="/css/sloganFamily.css">

View File

@@ -4,7 +4,7 @@
*
*/
var ctx,canvasAligning
function initAligningGuidelines(canvas,bor) {
function initAligningGuidelines(canvas,bor){
ctx = canvas.getSelectionContext()
canvasAligning = canvas
setCanvasAligning(bor)

View File

@@ -126,6 +126,42 @@ fabric.Point.prototype.normalize = function(thickness) {
* Convert a brush drawing on the upperCanvas to an image on the fabric canvas.
* This makes the drawing editable, it can be moved, rotated, scaled, skewed etc.
*/
fabric.BaseBrush.prototype.convertToPath = function() {
var pixelRatio = this.canvas.getRetinaScaling(),
c = fabric.util.copyCanvasElement(this.canvas.upperCanvasEl),
xy = fabric.util.trimCanvas(c),
path = this._points.map(arr => {
arr[1] = arr[1] / this.canvas.getZoom()
arr[2] = arr[2] / this.canvas.getZoom()
return arr.join(' ')
}).join(' '),
pathElemetn = new fabric.Path(path);
if(!xy){
return
}
let pointerX = this.canvas.viewportTransform[4];
let pointerY = this.canvas.viewportTransform[5];
pathElemetn.set({
strokeDashArray: [this._width*3, this._width*3],
strokeWidth: this._width,
stroke: 'black',
fill:'transparent',
custom:{
dashed:true
},
}).setCoords();
let group = new fabric.Group([pathElemetn],{
left:((xy.x)/pixelRatio-pointerX)/this.canvas.getZoom(),
top:((xy.y)/pixelRatio-pointerY)/this.canvas.getZoom(),
custom:{
dashed:true
},
})
this.canvas.add(group).clearContext(this.canvas.contextTop);
this.canvas.clearContext(this.canvas.contextTop);
}
fabric.BaseBrush.prototype.convertToImg = function() {
var pixelRatio = this.canvas.getRetinaScaling(),
c = fabric.util.copyCanvasElement(this.canvas.upperCanvasEl),
@@ -135,8 +171,13 @@ fabric.BaseBrush.prototype.convertToImg = function() {
return
}
let pointerX = this.canvas.viewportTransform[4];
let pointerY = this.canvas.viewportTransform[5];
img.set({left:(xy.x)/pixelRatio-pointerX,top:(xy.y)/pixelRatio-pointerY,'scaleX':1/pixelRatio,'scaleY':1/pixelRatio}).setCoords();
let pointerY = this.canvas.viewportTransform[5];
img.set({
left:((xy.x)/pixelRatio-pointerX)/this.canvas.getZoom(),
top:((xy.y)/pixelRatio-pointerY)/this.canvas.getZoom(),
'scaleX':1/pixelRatio/this.canvas.getZoom(),
'scaleY':1/pixelRatio/this.canvas.getZoom()
}).setCoords();
this.canvas.add(img).clearContext(this.canvas.contextTop);
this.canvas.clearContext(this.canvas.contextTop);
}
@@ -234,8 +275,8 @@ fabric.CrayonBrush = fabric.util.createClass(fabric.BaseBrush, {
},
onMouseDown: function(pointer) {
pointer.x = pointer.x + this.canvas.viewportTransform[4];
pointer.y = pointer.y + this.canvas.viewportTransform[5];
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
this.canvas.contextTop.globalAlpha = this.opacity;
this._size = this.width / 2 + this._baseWidth;
this._drawn = false;
@@ -243,8 +284,8 @@ fabric.CrayonBrush = fabric.util.createClass(fabric.BaseBrush, {
},
onMouseMove: function(pointer) {
pointer.x = pointer.x + this.canvas.viewportTransform[4];
pointer.y = pointer.y + this.canvas.viewportTransform[5];
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
this.update(pointer);
this.draw(this.canvas.contextTop);
},
@@ -399,7 +440,6 @@ fabric.InkBrush = fabric.util.createClass(fabric.BaseBrush, {
initialize: function(canvas, opt) {
opt = opt || {};
this.canvas = canvas;
this.width = opt.width || this.width;
this.color = opt.color || this.color;
@@ -409,8 +449,8 @@ fabric.InkBrush = fabric.util.createClass(fabric.BaseBrush, {
},
_render: function(pointer) {
pointer.x = pointer.x + this.canvas.viewportTransform[4];
pointer.y = pointer.y + this.canvas.viewportTransform[5];
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
var len, i, point = this.setPointer(pointer),
subtractPoint = point.subtract(this._lastPoint),
distance = point.distanceFrom(this._lastPoint),
@@ -422,7 +462,7 @@ fabric.InkBrush = fabric.util.createClass(fabric.BaseBrush, {
}
if (distance > 30) {
// this.drawSplash(point, this._inkAmount);
this.drawSplash(point, this._inkAmount);
}
},
@@ -475,8 +515,8 @@ fabric.InkBrush = fabric.util.createClass(fabric.BaseBrush, {
},
_resetTip: function(pointer) {
pointer.x = pointer.x + this.canvas.viewportTransform[4];
pointer.y = pointer.y + this.canvas.viewportTransform[5];
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
var len, i, point = this.setPointer(pointer);
this._strokes = [];
@@ -510,8 +550,8 @@ fabric.LongfurBrush = fabric.util.createClass(fabric.BaseBrush, {
},
onMouseDown: function(pointer) {
pointer.x = pointer.x + this.canvas.viewportTransform[4];
pointer.y = pointer.y + this.canvas.viewportTransform[5];
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
this._points = [pointer];
this._count = 0;
@@ -524,8 +564,8 @@ fabric.LongfurBrush = fabric.util.createClass(fabric.BaseBrush, {
},
onMouseMove: function(pointer) {
pointer.x = pointer.x + this.canvas.viewportTransform[4];
pointer.y = pointer.y + this.canvas.viewportTransform[5];
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
this._points.push(pointer);
var i, dx, dy, d, size,
@@ -609,8 +649,8 @@ fabric.WritingBrush = fabric.util.createClass(fabric.BaseBrush, {
},
onMouseDown: function(pointer) {
pointer.x = pointer.x + this.canvas.viewportTransform[4];
pointer.y = pointer.y + this.canvas.viewportTransform[5];
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
this._lastPoint = pointer;
this.canvas.contextTop.strokeStyle = this.color;
this.canvas.contextTop.lineWidth = this._lineWidth;
@@ -619,8 +659,8 @@ fabric.WritingBrush = fabric.util.createClass(fabric.BaseBrush, {
onMouseMove: function(pointer) {
if (this.canvas._isCurrentlyDrawing) {
pointer.x = pointer.x + this.canvas.viewportTransform[4];
pointer.y = pointer.y + this.canvas.viewportTransform[5];
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
this._render(pointer);
}
},
@@ -680,8 +720,8 @@ fabric.MarkerBrush = fabric.util.createClass(fabric.BaseBrush, {
},
onMouseDown: function(pointer) {
pointer.x = pointer.x + this.canvas.viewportTransform[4];
pointer.y = pointer.y + this.canvas.viewportTransform[5];
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
this._lastPoint = pointer;
this.canvas.contextTop.strokeStyle = this.color;
this.canvas.contextTop.lineWidth = this._lineWidth;
@@ -690,8 +730,8 @@ fabric.MarkerBrush = fabric.util.createClass(fabric.BaseBrush, {
onMouseMove: function(pointer) {
if (this.canvas._isCurrentlyDrawing) {
pointer.x = pointer.x + this.canvas.viewportTransform[4];
pointer.y = pointer.y + this.canvas.viewportTransform[5];
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
this._render(pointer);
}
},
@@ -702,6 +742,67 @@ fabric.MarkerBrush = fabric.util.createClass(fabric.BaseBrush, {
this.convertToImg();
}
}); // End MarkerBrush
/**
* test
* Based on code by Tennison Chan.
*/
fabric.Test = fabric.util.createClass(fabric.BaseBrush, {
color: '#000',
opacity: 1,
_points: [],
_width: 2,
initialize: function(canvas, opt) {
opt = opt || {};
this.canvas = canvas;
this._width = opt._width || this._width;
this.color = opt.color || this.color;
},
_render: function(pointer) {
var ctx, lineWidthDiff, i, len;
ctx = this.canvas.contextTop;
this._points.push(['L', pointer.x, pointer.y]);
// if(this._points.length % 10 < 5){
let points = this._points
ctx.beginPath();
ctx.moveTo(points[points.length - 2][1], points[points.length - 2][2]);
ctx.lineTo(points[points.length - 1][1], points[points.length - 1][2]);
ctx.stroke();
// }
},
onMouseDown: function(pointer) {
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
this._points = []
this._points.push(['M', pointer.x, pointer.y]);
var ctx = this.canvas.contextTop;
ctx.strokeStyle = 'rgba(' + 0 + ',' + 0 + ',' + 0 + ',' + 1 + ')';
ctx.lineWidth = this._width * this.canvas.getZoom();
ctx.lineJoin = ctx.lineCap = 'round';
},
onMouseMove: function(pointer) {
if (this.canvas._isCurrentlyDrawing) {
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
this._render(pointer);
}
},
onMouseUp: function() {
this._points.push(['Z']);
this.convertToPath();
}
}); // End test
/**
* MarkerBrush
* Based on code by Tennison Chan.
@@ -756,8 +857,8 @@ fabric.MarkerBrush1 = fabric.util.createClass(fabric.BaseBrush, {
},
onMouseDown: function(pointer) {
pointer.x = pointer.x + this.canvas.viewportTransform[4];
pointer.y = pointer.y + this.canvas.viewportTransform[5];
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
this._lastPoint = pointer;
this.canvas.contextTop.strokeStyle = this.color;
this.canvas.contextTop.lineWidth = this._lineWidth;
@@ -766,8 +867,8 @@ fabric.MarkerBrush1 = fabric.util.createClass(fabric.BaseBrush, {
onMouseMove: function(pointer) {
if (this.canvas._isCurrentlyDrawing) {
pointer.x = pointer.x + this.canvas.viewportTransform[4];
pointer.y = pointer.y + this.canvas.viewportTransform[5];
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
this._render(pointer);
}
},
@@ -833,8 +934,8 @@ fabric.PenBrush = fabric.util.createClass(fabric.BaseBrush, {
},
onMouseDown: function(pointer) {
pointer.x = pointer.x + this.canvas.viewportTransform[4];
pointer.y = pointer.y + this.canvas.viewportTransform[5];
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
this._lastPoint = pointer;
this.canvas.contextTop.lineWidth = this._lineWidth;
this._size = this.width + this._baseWidth;
@@ -842,8 +943,8 @@ fabric.PenBrush = fabric.util.createClass(fabric.BaseBrush, {
onMouseMove: function(pointer) {
if (this.canvas._isCurrentlyDrawing) {
pointer.x = pointer.x + this.canvas.viewportTransform[4];
pointer.y = pointer.y + this.canvas.viewportTransform[5];
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
this._render(pointer);
}
},
@@ -900,8 +1001,8 @@ fabric.RibbonBrush = fabric.util.createClass(fabric.BaseBrush, {
for (var i = 0; i < this._nrPainters; i++) {
this._painters.push({ dx:this.canvas.width / 2, dy:this.canvas.height / 2, ax:0, ay:0, div:.1, ease:Math.random() * .2 + .6 });
}
pointer.x = pointer.x + this.canvas.viewportTransform[4];
pointer.y = pointer.y + this.canvas.viewportTransform[5];
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
this._lastPoint = pointer;
//ctx.globalCompositeOperation = 'source-over';
@@ -918,8 +1019,8 @@ fabric.RibbonBrush = fabric.util.createClass(fabric.BaseBrush, {
},
onMouseMove: function(pointer) {
pointer.x = pointer.x + this.canvas.viewportTransform[4];
pointer.y = pointer.y + this.canvas.viewportTransform[5];
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
this._lastPoint = pointer;
},
@@ -954,8 +1055,8 @@ fabric.ShadedBrush = fabric.util.createClass(fabric.BaseBrush, {
},
onMouseDown: function(pointer) {
pointer.x = pointer.x + this.canvas.viewportTransform[4];
pointer.y = pointer.y + this.canvas.viewportTransform[5];
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
this._points = [pointer];
var ctx = this.canvas.contextTop,
@@ -967,8 +1068,8 @@ fabric.ShadedBrush = fabric.util.createClass(fabric.BaseBrush, {
},
onMouseMove: function(pointer) {
pointer.x = pointer.x + this.canvas.viewportTransform[4];
pointer.y = pointer.y + this.canvas.viewportTransform[5];
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
this._points.push(pointer);
var ctx = this.canvas.contextTop,
@@ -1025,8 +1126,8 @@ fabric.SketchyBrush = fabric.util.createClass(fabric.BaseBrush, {
onMouseDown: function(pointer) {
this._count = 0;
pointer.x = pointer.x + this.canvas.viewportTransform[4];
pointer.y = pointer.y + this.canvas.viewportTransform[5];
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
this._points = [pointer];
var ctx = this.canvas.contextTop,
@@ -1037,8 +1138,8 @@ fabric.SketchyBrush = fabric.util.createClass(fabric.BaseBrush, {
},
onMouseMove: function(pointer) {
pointer.x = pointer.x + this.canvas.viewportTransform[4];
pointer.y = pointer.y + this.canvas.viewportTransform[5];
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
this._points.push(pointer);
var i, dx, dy, d, factor = .3 * this.width,
@@ -1124,8 +1225,8 @@ fabric.SpraypaintBrush = fabric.util.createClass(fabric.BaseBrush, {
onMouseDown: function(pointer) {
this.canvas.contextTop.globalAlpha = this.opacity;
pointer.x = pointer.x + this.canvas.viewportTransform[4];
pointer.y = pointer.y + this.canvas.viewportTransform[5];
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
this._point = new fabric.Point(pointer.x, pointer.y);
this._lastPoint = this._point;
@@ -1138,8 +1239,8 @@ fabric.SpraypaintBrush = fabric.util.createClass(fabric.BaseBrush, {
},
onMouseMove: function(pointer) {
pointer.x = pointer.x + this.canvas.viewportTransform[4];
pointer.y = pointer.y + this.canvas.viewportTransform[5];
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
this._lastPoint = this._point;
this._point = new fabric.Point(pointer.x, pointer.y);
},
@@ -1214,8 +1315,8 @@ fabric.SquaresBrush = fabric.util.createClass(fabric.BaseBrush, {
var ctx = this.canvas.contextTop,
color = fabric.util.colorValues(this.color),
bgColor = fabric.util.colorValues(this.bgColor);
pointer.x = pointer.x + this.canvas.viewportTransform[4];
pointer.y = pointer.y + this.canvas.viewportTransform[5];
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
this._lastPoint = pointer;
this._drawn = false;
@@ -1227,8 +1328,8 @@ fabric.SquaresBrush = fabric.util.createClass(fabric.BaseBrush, {
},
onMouseMove: function(pointer) {
pointer.x = pointer.x + this.canvas.viewportTransform[4];
pointer.y = pointer.y + this.canvas.viewportTransform[5];
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
var ctx = this.canvas.contextTop,
dx = pointer.x - this._lastPoint.x,
dy = pointer.y - this._lastPoint.y,
@@ -1281,16 +1382,16 @@ fabric.WebBrush = fabric.util.createClass(fabric.BaseBrush, {
},
onMouseDown: function(pointer) {
pointer.x = pointer.x + this.canvas.viewportTransform[4];
pointer.y = pointer.y + this.canvas.viewportTransform[5];
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
this._points = [pointer];
this._count = 0;
this._colorValues = fabric.util.colorValues(this.color);
},
onMouseMove: function(pointer) {
pointer.x = pointer.x + this.canvas.viewportTransform[4];
pointer.y = pointer.y + this.canvas.viewportTransform[5];
pointer.x = (pointer.x * this.canvas.getZoom()) + this.canvas.viewportTransform[4];
pointer.y = (pointer.y * this.canvas.getZoom()) + this.canvas.viewportTransform[5];
this._points.push(pointer);
var ctx = this.canvas.contextTop,

View File

@@ -7,5 +7,6 @@
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
height: 100%;
}
</style>

View File

@@ -1,3 +0,0 @@
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<path fill-rule="evenodd" clip-rule="evenodd" d="M16 4H0v-.75C0 2.56.448 2 1 2h14c.552 0 1 .56 1 1.25V4zm0 2.5V13a1 1 0 01-1 1H1a1 1 0 01-1-1V6.5h16zM4 10a1 1 0 100 2h1a1 1 0 100-2H4z" fill="#000"/>
</svg>

Before

Width:  |  Height:  |  Size: 281 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1735265169559" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1495" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M802.158921 871.935232h-580.317842c-63.174813 0-114.374813-51.2-114.374812-114.374812V177.31934c0-63.174813 51.2-114.374813 114.374812-114.374812h580.317842c63.174813 0 114.374813 51.2 114.374812 114.374812v580.317841c0 63.098051-51.2 114.298051-114.374812 114.298051z" fill="#009BF1" p-id="1496"></path><path d="M469.627586 350.647076c0-25.638381 21.416492-35.54063 55.728936-35.540629 49.971814 0 113.376912 15.275562 163.271964 42.21889V202.804198c-54.423988-21.723538-108.771214-30.013793-163.195203-30.013793-133.181409 0-221.917841 69.546027-221.917841 185.763118 0 181.694753 249.552024 152.295052 249.552024 230.668666 0 30.397601-26.329235 40.146327-62.944527 40.146327-54.347226 0-124.507346-22.414393-179.622189-52.351425v147.919641c61.025487 26.252474 122.895352 37.306147 179.545427 37.306147 136.482159 0 230.515142-58.722639 230.515142-176.782009-0.076762-195.972414-250.933733-160.892354-250.933733-234.813794" fill="#FFFFFF" p-id="1497"></path></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 639 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 748 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@@ -0,0 +1,18 @@
<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_537_3867)">
<mask id="mask0_537_3867" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="50" height="50">
<path d="M50 0H0V50H50V0Z" fill="white"/>
</mask>
<g mask="url(#mask0_537_3867)">
<path d="M10.4143 25.186C10.4143 23.552 10.689 21.9857 11.1769 20.5169L2.61091 14.0449C0.887829 17.5063 -0.00607483 21.3202 3.10708e-05 25.186C3.10708e-05 29.1896 0.937897 32.9657 2.60603 36.3185L11.1696 29.8355C10.6695 28.3363 10.4155 26.7663 10.4143 25.186Z" fill="#FBBC05"/>
</g>
<path d="M25.4614 10.3262C28.874 10.3195 32.1846 11.4894 34.834 13.6388L42.2405 6.32383C37.7276 2.43915 31.9416 0.0366211 25.4614 0.0366211C15.4001 0.0366211 6.75174 5.72914 2.61133 14.045L11.1834 20.517C13.1568 14.5884 18.784 10.3256 25.4639 10.3256" fill="#EA4335"/>
<path d="M25.5704 39.7145C18.8551 39.7145 13.2004 35.4785 11.2148 29.5859L2.60547 36.0189C6.76603 44.2835 15.4566 49.9382 25.5704 49.9382C31.8094 49.9382 37.7663 47.7724 42.2395 43.7102L34.0649 37.5291C31.7605 38.949 28.8553 39.7151 25.5679 39.7151" fill="#34A853"/>
<path d="M49.9922 24.9489C49.9922 23.4723 49.7584 21.8809 49.4109 20.4043H25.5674V30.0602H39.2904C38.6065 33.3526 36.7393 35.8838 34.0662 37.53L42.2389 43.7111C46.9374 39.4477 49.9922 33.0958 49.9922 24.9489Z" fill="#4285F4"/>
</g>
<defs>
<clipPath id="clip0_537_3867">
<rect width="50" height="50" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,16 @@
<svg width="38" height="38" viewBox="0 0 38 38" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_262_1244)">
<circle cx="19" cy="19" r="19" fill="black"/>
<g clip-path="url(#clip1_262_1244)">
<path d="M22.3777 20.5705C21.6009 20.5705 21.0096 21.2797 20.3004 21.2797C18.7142 20.3709 17.4199 19.0292 16.568 17.412C16.568 16.6352 17.311 16.3482 17.311 15.47C17.311 14.5917 15.1999 11.3999 14.3386 11.3999C13.4772 11.3999 11.3999 12.9705 11.3999 14.4062C11.3999 18.5946 18.9323 26.5999 23.6613 26.5999C25.2425 26.4478 26.4836 25.1782 26.5999 23.5936C25.5015 22.2123 24.0389 21.1654 22.3777 20.5705Z" fill="white"/>
</g>
</g>
<defs>
<clipPath id="clip0_262_1244">
<rect width="38" height="38" fill="white"/>
</clipPath>
<clipPath id="clip1_262_1244">
<rect width="15.2" height="15.2" fill="white" transform="translate(11.3999 11.3999)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 884 B

View File

@@ -0,0 +1,11 @@
<svg width="38" height="38" viewBox="0 0 38 38" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_262_1241)">
<path d="M12.5565 12.6113C11.8955 12.6113 11.2349 13.0519 11.2349 13.713C11.2349 14.374 11.8955 14.8146 12.5565 14.8146C13.2176 14.8146 13.6582 14.374 13.6582 13.713C13.6582 13.0519 13.2176 12.6113 12.5565 12.6113ZM21.5058 19.0001C21.0653 19.0001 20.6522 19.4681 20.6522 19.8812C20.6522 20.3492 21.0927 20.7623 21.5058 20.7623C22.1664 20.7623 22.6075 20.3218 22.6075 19.8812C22.6075 19.4407 22.1669 19.0001 21.5058 19.0001ZM18.6694 14.8146C19.3305 14.8146 19.7711 14.3466 19.7711 13.713C19.7711 13.0793 19.3305 12.6113 18.6694 12.6113C18.0084 12.6113 17.3478 13.0519 17.3478 13.713C17.3478 14.374 18.0088 14.8146 18.6694 14.8146ZM26.2971 19.0001C25.8565 19.0001 25.4434 19.4681 25.4434 19.8812C25.4434 20.3492 25.884 20.7623 26.2971 20.7623C26.9577 20.7623 27.3987 20.3218 27.3987 19.8812C27.3987 19.4407 26.9581 19.0001 26.2971 19.0001Z" fill="#28C445"/>
<path d="M19.0002 0C8.50875 0 0 8.50875 0 19.0002C0 29.4917 8.50875 38 19.0002 38C29.4917 38 38 29.4913 38 19.0002C38 8.50921 29.4913 0 19.0002 0ZM15.393 23.8738C14.2913 23.8738 13.4102 23.6538 12.364 23.4058L9.33497 24.948L10.1886 22.2767C8.0133 20.735 6.69162 18.7244 6.69162 16.329C6.69162 12.116 10.6297 8.8116 15.393 8.8116C19.6613 8.8116 23.4337 11.4549 24.1771 15.0073C23.9017 14.9799 23.6263 14.9524 23.3509 14.9524C19.2203 15.0073 15.9712 18.1191 15.9712 21.9743C15.9712 22.6075 16.0815 23.2132 16.2466 23.8194C15.9712 23.8468 15.6684 23.8743 15.393 23.8743V23.8738ZM28.2803 26.9577L28.9409 29.1605L26.573 27.8388C25.7193 28.0589 24.8382 28.2794 23.9571 28.2794C19.799 28.2794 16.522 25.4155 16.522 21.8632C16.4946 18.3387 19.7711 15.4748 23.9017 15.4748C28.0323 15.4748 31.3088 18.3661 31.3088 21.8906C31.3088 23.8733 30.0146 25.6356 28.2798 26.9572L28.2803 26.9577Z" fill="#28C445"/>
</g>
<defs>
<clipPath id="clip0_262_1241">
<rect width="38" height="38" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -4,11 +4,71 @@
<img src="https://code-create.com.hk/wp-content/uploads/2022/12/about_banner-1.jpg" alt="">
</div> -->
<div class="account_page_content_box">
<div class="content_item_user">
<div class="content_item_user_left">
<div class="content_item_user_left_detail">
<img :src="uploadUrl?uploadUrl:userDetail.avatar" alt="">
<div class="upload_box">
<i class="fi fi-rr-camera"></i>
<a-upload
class="upload"
:capture="null"
list-type="picture-card"
:before-upload="beforeUpload"
v-model:file-list="fileList"
:customRequest="function(){}"
:maxCount="1"
accept=".jpg,.png,.jpeg,.bmp"
@change="fileUploadChange"
>
<div
class="upload_tip_block"
>
<!-- <i class="fi fi-br-upload"></i> -->
<!-- <img :src="uploadUrl?uploadUrl:userDetail.avatar" alt=""> -->
</div>
</a-upload>
</div>
</div>
<div class="content_item_user_left_detail">
<div class="modal_title_text">
<div class="label">
<div class="content">
<div v-if="!isEditUserName">{{ userDetail.userName }}</div>
<input v-else type="text" v-model="editUserName">
</div>
<div class="icon">
<i v-if="!isEditUserName" class="fi fi-rr-edit" @click="openEdit('userName')"></i>
<i v-else class="fi fi-br-check" @click="editChek('userName')"></i>
</div>
<span class="Modifiable" v-if="userDetail.usernameModify > 0 && isEditUserName">{{ $t('account.remainingModifications') }}{{ userDetail.usernameModify }}/5</span>
<span class="Modifiable notModifiable" v-else-if="isEditUserName">{{ $t('account.notModifiable') }} {{ userDetail.usernameModify }}/5</span>
</div>
<div class="label">
<span>{{$t('account.email')}}: </span>
<div class="content">
<div v-if="!isEditEmail">{{ userDetail.email }}</div>
<input v-else type="text" :value="editEmail">
</div>
<div class="icon">
<i v-if="!isEditEmail" class="fi fi-rr-edit" @click="openEdit('email')"></i>
<i v-else class="fi fi-br-check" @click="editChek('email')"></i>
</div>
</div>
</div>
<div class="content_item_user_left_detail_bottom">
<div>
<span>{{$t('account.Follow')}}</span>{{ userDetail.followeeCount }}
</div>
<div>
<span>{{$t('account.Fans')}}</span>{{ userDetail.followerCount }}
</div>
</div>
</div>
</div>
</div>
<div class="account_page_content">
<div class="account_page_content_left">
<div class="content_left_item">
<!-- <div>{{$t('account.personCentered')}}</div> -->
</div>
<!-- {{ router.path }} -->
<router-link class="content_left_item" v-for="item in rootSubmenuKeys" :class="{active: $route.path == item.route}" :to="item.route">
<i class="fi" :class="item.icon"></i>
@@ -28,6 +88,8 @@
</div>
</div>
</div>
<bindEmail ref="bindEmail"></bindEmail>
<Cropper ref="Cropper" @handleCropperSuccess="handleCropperSuccess" @closeCropper="deletUploadFile()" :cropperFileData="cropperFileData" :isRound="true"></Cropper>
</div>
</template>
<script lang="ts">
@@ -36,24 +98,36 @@ import { Https } from "@/tool/https";
import { Modal,message } from 'ant-design-vue';
import { useRouter,useRoute } from 'vue-router'
import { useStore } from "vuex";
import { setCookie, getCookie, WriteCookie } from "@/tool/cookie";
import { useI18n } from 'vue-i18n'
import bindEmail from "@/component/HomePage/bindEmail.vue";
import Cropper from '@/component/HomePage/Cropper.vue'
export default defineComponent({
components:{
bindEmail,Cropper
},
setup() {
const {t} = useI18n()
const store = useStore();
let userDetail= computed(()=>{
return store.state.UserHabit.userDetail
})
let accountHomeData = reactive({
isEditUserName:false,
editUserName:'',
isEditEmail:false,
editEmail:'',
bindEmail:null as any,
Cropper:null as any,
cropperFileData:{name:'',uid:''}, //裁剪的原始文件数据
uploadUrl:'',
uploadFile:undefined,
token:'',
fileList:[] as any,
rootSubmenuKeys:[
{
name:t('account.Home'),
route:'/home/account/accountHome',
icon:'fi-rr-house-chimney'
},{
name:t('account.myInformation'),
route:'/home/account/accountEdit',
name:t('account.frontPage'),
route:'/home/account/frontPage',
icon:'fi-rr-user'
},{
name:t('account.Messages'),
@@ -72,11 +146,113 @@ export default defineComponent({
// state.selectedKeys = [Number(event.key)]
// state.nowPageName = event.item.name
router.push({path:event.item.route})
}
const editUserName = async ()=>{
if(!accountHomeData.editUserName)return message.warning(t('LibraryPage.jsContent7'))
if(accountHomeData.editUserName == userDetail.value.userName)return
await new Promise<void>((resolve, reject) => {
Https.axiosGet(Https.httpUrls.editUserName,{params:{newUserName:accountHomeData.editUserName}}).
then((rv:any)=>{
let value = {
userName:accountHomeData.editUserName,
usernameModify:userDetail.value.usernameModify-=1
}
store.commit('upUserDetail',value)
resolve()
}).catch((err:any)=>{
resolve()
})
})
}
const editEmail = ()=>{
if(!accountHomeData.editEmail)return message.warning(t('LibraryPage.jsContent7'))
}
const editChek = async (str:string)=>{
if(str == 'userName'){
await editUserName()
}else{
// await editEmail()
}
accountHomeData.isEditUserName = false
accountHomeData.isEditEmail = false
accountHomeData.editUserName = ''
accountHomeData.editEmail = ''
}
const openEdit = (str:string)=>{
if(str == 'userName'){
// if(userDetail.value.usernameModify.remainingTimes == 0)return
accountHomeData.isEditUserName = true
accountHomeData.isEditEmail = false
accountHomeData.editUserName = userDetail.value.userName
}else{
accountHomeData.bindEmail.init('Modify')
// accountHomeData.isEditEmail = true
accountHomeData.isEditUserName = false
// accountHomeData.editEmail = userDetail.value.email
}
}
let beforeUpload=(file:any,fileList:any)=>{
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg' || file.type === 'image/bmp';
if (!isJpgOrPng) {
message.info(useI18n().t('PrintboardUpload.jsContent1'));
}
const isLt2M = file.size / 1024 / 1024 < 5;
if (!isLt2M) {
message.info(useI18n().t('PrintboardUpload.jsContent2'));
}
}
let fileUploadChange = (data:any)=>{
let file = data.file
// file.id = res.data.id?res.data.id:""
var reader = new FileReader();
reader.onload = (e:any) => {
let data_new;
if (typeof e.target.result === 'object') {
// 把Array Buffer转化为blob 如果是base64不需要
data_new = window.URL.createObjectURL(new Blob([e.target.result]));
} else {
data_new = e.target.result;
}
accountHomeData.Cropper.getOptionImg(data_new)
};
reader.readAsArrayBuffer(file.originFileObj);
accountHomeData.Cropper.changeShowModal(true)
}
let handleCropperSuccess = (event:any)=>{
let {file, fileData,base64} =event
accountHomeData.fileList[0].status = 'done'
accountHomeData.uploadUrl = base64
accountHomeData.uploadFile = file
accountHomeData.Cropper.closeCropper()
if(!accountHomeData.uploadFile)return
let param = new FormData();
param.append('file',accountHomeData.uploadFile);
let config:any = {headers:{'Content-Type':'multipart/form-data','Accept':'*/*' }}
Https.axiosPost(Https.httpUrls.uploadAvatar,param,config)
.then((rv)=>{
let data = {
avatar : rv
}
store.commit("upUserDetail", data)
message.success('提交成功')
})
}
let deletUploadFile = () => {
accountHomeData.fileList = []
}
return{
userDetail,
...toRefs(accountHomeData),
router,
handleClick,
editChek,
openEdit,
beforeUpload,
fileUploadChange,
handleCropperSuccess,
deletUploadFile,
}
},
data(){
@@ -89,8 +265,11 @@ export default defineComponent({
<style lang="less" scoped>
.account_page{
height: 100%;
overflow-y: auto;
padding: 0 9rem;
// overflow-y: auto;
padding: 0 30rem;
padding-top: 10rem;
display: flex;
overflow: hidden;
.account_page_titleImg{
img{
width: 100%;
@@ -99,43 +278,166 @@ export default defineComponent({
}
}
.account_page_content_box{
padding: 5rem 0;
.account_page_content{
box-shadow: 0 0px 10px 1px rgba(0, 0, 0, 0.12);
border: 1px solid #e9eaec;
border-radius: 5px;
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
.content_item_user{
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 7rem;
.content_item_user_left{
display: flex;
.content_item_user_left_detail{
position: relative;
> .upload_box{
position: absolute;
bottom: 0;
right: 0;
> i{
width: 4rem;
height: 4rem;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background: rgba(0,0,0,.5);
color: #fff;
font-size: 2rem;
}
> .upload{
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
overflow: hidden;
opacity: 0;
}
}
> .modal_title_text{
margin: 0;
> .label{
display: flex;
margin: 0;
> .content{
> input{
min-width: 20rem;
height: 3.6rem;
border-radius: 4rem;
border: 1px solid;
padding-left: 1.5rem;
}
}
> .Modifiable{
font-size: 1.6rem;
font-weight: 500;
color: #666666;
display: flex;
align-items: center;
&.notModifiable{
color: #FF0000;
}
}
> .icon{
margin: 0 1.5rem;
display: flex;
align-items: center;
> i{
font-weight: 600;
font-size: 2.2rem;
cursor: pointer;
&.fi-br-check{
width: 3rem;
height: 3rem;
display: flex;
align-items: center;
justify-content: center;
background: #000;
color: #fff;
border-radius: 50%;
}
}
}
}
> div{
margin-bottom: 1rem;
}
}
img{
border-radius: 50%;
width: 10rem;
height: 10rem
}
.content_item_user_left_detail_bottom{
display: flex;
font-size: 1.8rem;
>div{
font-weight: 900;
width: 10rem;
span{
font-weight: 600;
color: rgba(0,0,0,.45);
}
}
}
}
.content_item_user_left_detail:last-child{
margin-left: 3rem;
}
}
}
.account_page_content{
display: flex;
flex: 1;
overflow: hidden;
.account_page_content_left{
width: 20%;
width: 24rem;
text-align: center;
background: #fafafa;
border-right: 1px solid #e9eaec;
margin-right: 10rem;
}
.account_page_content_right{
width: 80%;
flex: 1;
overflow: hidden;
.account_message{
height: 100%;
:deep(.account_message_body){
height: 100%;
.ant-tabs-content-holder{
flex: 1;
}
.ant-tabs-content{
height: 100%;
overflow-y: auto;
}
}
}
}
.content_left_item{
display: flex;
align-items: center;
justify-content: center;
height: 10rem;
height: 6rem;
color: #232323;
div{
white-space: nowrap;
width: 15rem;
color: #232323;
text-align-last: justify;
font-size: 3rem;
color: #999999;
// text-align-last: justify;
text-align: left;
font-size: 2rem;
}
i{
color: #cfcfcf;
font-size: 2.5rem;
font-size: 2rem;
display: flex;
margin-right: 2rem;
margin: 0 2rem;
}
&.active{
color: #fff;
background: #39215b;
background: #000;
div{
color: #fff;
font-weight: 900;
@@ -155,10 +457,6 @@ export default defineComponent({
display: flex;
align-items: center;
justify-content: space-between;
padding: 2rem 5rem;
border-bottom: 1px solid #e9eaec;
box-shadow: 0 0px 10px 1px rgba(0, 0, 0, 0.12);
border: 1px solid #e9eaec;
border-radius: 5px;
position: sticky;
top: 0;
@@ -188,12 +486,9 @@ export default defineComponent({
}
}
.account_generalMessage_center{
box-shadow: 0 0px 10px 1px rgba(0, 0, 0, 0.12);
border: 1px solid #e9eaec;
// box-shadow: 0 0px 10px 1px rgba(0, 0, 0, 0.12);
// border: 1px solid #e9eaec;
border-radius: 5px;
padding: 2rem 0;
margin-right: 5rem;
margin-left: 5rem;
.account_generalMessage_item{
margin-right: 0;
margin-left: 0;
@@ -208,8 +503,6 @@ export default defineComponent({
}
}
.account_generalMessage_item{
box-shadow: 0 0px 10px 1px rgba(0, 0, 0, 0.12);
border: 1px solid #e9eaec;
border-radius: 5px;
padding: 5rem 5rem;
margin-right: 5rem;

View File

@@ -1,222 +0,0 @@
<template>
<div class="accountEdit_page">
<div class="accountEdit_page_head">
<div class="upload_item">
<div class="upload_file_item">
<a-upload
:capture="null"
list-type="picture-card"
:before-upload="beforeUpload"
v-model:file-list="fileList"
:customRequest="function(){}"
:maxCount="1"
accept=".jpg,.png,.jpeg,.bmp"
@change="fileUploadChange"
>
<div
class="upload_tip_block"
>
<!-- <i class="fi fi-br-upload"></i> -->
<img :src="uploadUrl" alt="">
</div>
</a-upload>
</div>
</div>
</div>
<div class="accountEdit_page_body">
<div class="accountEdit_page_body_item">
<div class="accountEdit_page_body_item_name">{{$t('account.userName')}}:</div>
<div class="accountEdit_page_body_item_inut">
<input type="text" disabled :value="cookieUserInfo.userName">
</div>
</div>
<div class="accountEdit_page_body_item">
<div class="accountEdit_page_body_item_name">{{$t('account.email')}}:</div>
<div class="accountEdit_page_body_item_inut">
<input type="text" disabled :value="cookieUserInfo.email">
</div>
</div>
<div class="accountEdit_page_body_item">
<div class="started_btn" @click="setSubmit">
{{$t('account.Submit')}}
</div>
</div>
</div>
<Cropper ref="Cropper" @handleCropperSuccess="handleCropperSuccess" @closeCropper="deletUploadFile()" :cropperFileData="cropperFileData" :isRound="true"></Cropper>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,reactive,nextTick,toRefs,createVNode, onMounted} from 'vue'
import { Https } from "@/tool/https";
import { Modal,message } from 'ant-design-vue';
import { useStore } from "vuex";
import Cropper from '@/component/HomePage/Cropper.vue'
import { setCookie, getCookie, WriteCookie } from "@/tool/cookie";
import { useI18n } from 'vue-i18n'
export default defineComponent({
components:{
Cropper,
},
setup() {
const store = useStore();
let userInfo:any= computed(()=>{
return store.state.UserHabit.userInfo
})
let cookieUserInfo = JSON.parse(getCookie('userInfo') as any)
let accountHomeData:any = reactive({
cropperFileData:{name:'',uid:''}, //裁剪的原始文件数据
uploadUrl:userInfo.value?.avatar,
uploadFile:undefined,
token:'',
fileList:[]
})
let Cropper = ref()
// provide('exhibitionList',exhibitionList)
let handleCropperSuccess = (event:any)=>{
let {file, fileData,base64} =event
accountHomeData.fileList[0].status = 'done'
accountHomeData.uploadUrl = base64
accountHomeData.uploadFile = file
Cropper.value.closeCropper()
}
let beforeUpload=(file:any,fileList:any)=>{
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg' || file.type === 'image/bmp';
if (!isJpgOrPng) {
message.info(useI18n().t('PrintboardUpload.jsContent1'));
}
const isLt2M = file.size / 1024 / 1024 < 5;
if (!isLt2M) {
message.info(useI18n().t('PrintboardUpload.jsContent2'));
}
if(isJpgOrPng && isLt2M){
// }else{
// return (isJpgOrPng && isLt2M) || Upload.LIST_IGNORE;
}
}
let fileUploadChange = (data:any)=>{
let file = data.file
// file.id = res.data.id?res.data.id:""
var reader = new FileReader();
reader.onload = (e:any) => {
let data_new;
if (typeof e.target.result === 'object') {
// 把Array Buffer转化为blob 如果是base64不需要
data_new = window.URL.createObjectURL(new Blob([e.target.result]));
} else {
data_new = e.target.result;
}
Cropper.value.getOptionImg(data_new)
};
// 转化为base64
// reader.readAsDataURL(file)
// 转化为blob
reader.readAsArrayBuffer(file.originFileObj);
Cropper.value.changeShowModal(true)
}
let deletUploadFile = () => {
accountHomeData.fileList = []
// let index = -1
// this.fileList.forEach((ele:any,index1:any) => {
// if(this.cropperFileData.uid === ele.uid){
// index = index1
// }
// });
// if(index > -1){
// this.fileList.splice(index, 1)
// }
}
let setSubmit = ()=>{
if(!accountHomeData.uploadFile)return
let param = new FormData();
param.append('file',accountHomeData.uploadFile);
let config:any = {headers:{'Content-Type':'multipart/form-data','Accept':'*/*' }}
Https.axiosPost(Https.httpUrls.uploadAvatar,param,config)
.then((rv)=>{
let data = {
avatar : rv
}
store.commit("setUserInfo", data)
message.success('提交成功')
})
}
return{
...toRefs(accountHomeData),
userInfo,
cookieUserInfo,
Cropper,
handleCropperSuccess,
beforeUpload,
fileUploadChange,
deletUploadFile,
setSubmit,
}
},
data(){
return{
}
},
})
</script>
<style lang="less" scoped>
.accountEdit_page{
padding: 8rem 5rem;
.accountEdit_page_head{
display: flex;
align-items: center;
justify-content: center;
width: 20rem;
margin: 0 auto;
position: relative;
img{
width: 15rem;
object-fit: contain;
height: 15rem;
border-radius: 50%;
background: #fff;
}
.accountEdit_page_head_upload{
width: auto;
}
.upload_item{
:deep(.ant-upload-list-picture-card-container){
display: none !important;
}
}
margin-bottom: 5rem;
}
.accountEdit_page_body{
.accountEdit_page_body_item{
display: flex;
margin-bottom: 5rem;
width: 100%;
.started_btn{
text-align: center;
}
input,textarea{
padding-left: 2rem;
border-radius: 4px;
border: 1px solid #dcdfe6;
width: 100%;
}
.accountEdit_page_body_item_name{
color: #606266;
width: 14rem;
text-align: right;
}
.accountEdit_page_body_item_inut{
margin-left: 2rem;
flex: 1;
}
}
.accountEdit_page_body_item:last-child{
justify-content: center;
}
}
}
</style>

View File

@@ -1,11 +1,11 @@
<template>
<div class="account_followFans">
<div class="account_followFans_title modal_title_text">
<!-- <div class="account_followFans_title modal_title_text">
<div class="">
{{$t('account.Interact')}}
</div>
<!-- <div class="account_followFans_title_setting">设置</div> -->
</div>
<div class="account_followFans_title_setting">设置</div>
</div> -->
<a-tabs class="account_followFans_body" v-model:activeKey="activeKey" @change="changeTabs">
<a-tab-pane v-for="item in messageList" :key="item.key">
<follow v-if="item.key == 'follow'" :ref="item.key"></follow>
@@ -43,7 +43,6 @@ import { Https } from "@/tool/https";
import { useRouter,useRoute } from 'vue-router'
import { Modal,message } from 'ant-design-vue';
import { useStore } from "vuex";
import { setCookie, getCookie, WriteCookie } from "@/tool/cookie";
import follow from '@/component/Account/followFans/follow.vue'
import fans from '@/component/Account/followFans/fans.vue'
import { useI18n } from 'vue-i18n'
@@ -70,9 +69,6 @@ export default defineComponent({
],
activeKey: '',
})
let userInfo= computed(()=>{
return store.state.UserHabit.userInfo
})
let domRefs:any = reactive({
follow:ref(null),
fans:ref(null),
@@ -108,7 +104,6 @@ export default defineComponent({
return{
...toRefs(accountMessage),
...toRefs(domRefs),
userInfo,
messageSystem,
setReadStatus,
changeTabs,
@@ -141,32 +136,24 @@ export default defineComponent({
}
:deep(.ant-tabs-nav){
padding: 0rem 5rem;
&::before{
display: none;
}
.ant-tabs-nav-wrap{
.ant-tabs-tab-btn{
color: #000;
font-size: 2.4rem;
}
.ant-tabs-tab-btn:active{
color: #39215b;
}
.ant-tabs-tab-active{
.ant-tabs-tab-btn{
color: #39215b;
font-weight: 900;
}
}
}
.ant-tabs-tab:hover{
color: #39215b;
}
.ant-tabs-ink-bar{
background: #39215b;
background: #000;
}
}
:deep(.ant-tabs-content){
height: 80rem;
// min-height: 80rem;
overflow-y: auto;
}
}
}
</style>

View File

@@ -1,222 +0,0 @@
<template>
<div class="account_home">
<div class="account_home_content">
<div class="content_item content_item_user">
<div class="content_item_user_left">
<div class="content_item_user_left_detail">
<img :src="userInfo?.avatar" alt="">
</div>
<div class="content_item_user_left_detail">
<div class="modal_title_text">
<div>{{ cookieUserInfo.userName }}</div>
<div class="modal_title_text_assistant"><span>{{$t('account.email')}}: </span>{{ cookieUserInfo?.email }}</div>
</div>
<div class="content_item_user_left_detail_bottom">
<div>
<span>{{$t('account.Follow')}}</span>{{ userInfo?.followeeCount }}
</div>
<div>
<span>{{$t('account.Fans')}}</span>{{ userInfo?.followerCount }}
</div>
</div>
</div>
</div>
<div class="content_item_user_right">
<div @click="setUserData">{{$t('account.editUser')}}</div>
</div>
</div>
<div class="content_item content_item_task">
<!-- <div class="content_item_title">
<i>icon</i>
<div>每日奖励</div>
</div>
<div class="content_item_task_max">
<div class="content_item_task_item">
<div class="content_item_task_item_state">
<div class="state_credits">20 Credits</div>
<i class="fi fi-br-check"></i>
</div>
<div class="content_item_task_item_title">
每日点赞
</div>
<div class="content_item_task_item_award">
已完成 0 / 10
</div>
</div>
<div class="content_item_task_item active">
<div class="content_item_task_item_state">
<div class="state_credits">20 Credits</div>
<i class="fi fi-br-check"></i>
</div>
<div class="content_item_task_item_title">
每日发布作品
</div>
<div class="content_item_task_item_award">
20 Credits 到手
</div>
</div>
</div> -->
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,reactive,nextTick,toRefs,createVNode} from 'vue'
import { Https } from "@/tool/https";
import { useRouter,useRoute } from 'vue-router'
import { Modal,message } from 'ant-design-vue';
import { useStore } from "vuex";
import { setCookie, getCookie, WriteCookie } from "@/tool/cookie";
import { useI18n } from 'vue-i18n'
export default defineComponent({
components:{
},
setup() {
const router = useRouter()
const store = useStore();
let userInfo:any= computed(()=>{
return store.state.UserHabit.userInfo
})
let cookieUserInfo = ref(null)
if(getCookie('userInfo')){
let userInfo:any = getCookie('userInfo')
cookieUserInfo.value = JSON.parse(userInfo)
}
let accountHomeData = reactive({
})
// provide('exhibitionList',exhibitionList)
let setUserData = ()=>{
router.push({path:'/home/account/accountEdit'})
}
return{
userInfo,
cookieUserInfo,
...toRefs(accountHomeData),
setUserData,
}
},
data(){
return{
}
},
})
</script>
<style lang="less" scoped>
.account_home{
width: 100%;
.account_home_content{
.content_item{
padding: 8rem 5rem;
border-bottom: 1px solid #e9eaec;
.content_item_title{
display: flex;
align-items: center;
i{
margin-right: 1rem;
}
}
}
.content_item:last-child{
border-bottom: none;
}
.content_item_user{
display: flex;
justify-content: space-between;
align-items: center;
.content_item_user_left{
display: flex;
.content_item_user_left_detail{
img{
border-radius: 50%;
width: 10rem;
height: 10rem
}
.content_item_user_left_detail_bottom{
display: flex;
font-size: 1.8rem;
>div{
font-weight: 900;
width: 10rem;
span{
font-weight: 600;
color: rgba(0,0,0,.45);
}
}
}
}
.content_item_user_left_detail:last-child{
margin-left: 4rem;
}
}
.content_item_user_right{
border: 1px solid #e9eaec;
color: #6f767f;
font-size: 1.8rem;
cursor: pointer;
display: flex;
padding: 0 1rem;
border-radius: 4px;
}
}
.content_item_task{
.content_item_task_max{
display: flex;
margin-top: 4rem;
}
.content_item_task_item{
display: flex;
flex-direction: column;
align-items: center;
width: 25%;
.content_item_task_item_state{
width: 10rem;
height: 10rem;
background: linear-gradient(135deg, #cdacfc 50%, #a46ef0 50%) 00px 0;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
.state_credits{
font-size: 1.6rem;
font-weight: 900;
color: #fff;
}
i{
font-size: 3rem;
font-weight: 900;
display: none;
color: #fff;
}
}
.content_item_task_item_title{
margin: 2rem 0 ;
}
.content_item_task_item_award{
font-size: 1.8rem;
background: #fff;
border-radius: 4px;
padding: 0 1rem;
color: #99a2aa;
}
&.active{
.content_item_task_item_state{
background: linear-gradient(135deg, #4ddda8 50%, #3bcd98 50%) 00px 0;
.state_credits{
display: none;
}
i{
display: flex;
}
}
.content_item_task_item_award{
background: #8a95a8;
color: #fff;
}
}
}
}
}
}
</style>

View File

@@ -1,11 +1,5 @@
<template>
<div class="account_message">
<div class="account_message_title modal_title_text">
<div class="">
{{$t('account.Messages')}}
</div>
<!-- <div class="account_message_title_setting">设置</div> -->
</div>
<a-tabs class="account_message_body" v-model:activeKey="activeKey" @change="changeTabs">
<a-tab-pane v-for="item in messageList" :key="item.key">
<system v-if="item.key == 'system'" :ref="item.key" :setReadStatus="setReadStatus" :setAllmessage="setAllmessage" :getHistory="getHistory"></system>
@@ -45,7 +39,6 @@ import { Https } from "@/tool/https";
import { useRouter,useRoute } from 'vue-router'
import { Modal,message } from 'ant-design-vue';
import { useStore } from "vuex";
import { setCookie, getCookie, WriteCookie } from "@/tool/cookie";
import system from '@/component/Account/message/system.vue'
import privateChat from '@/component/Account/message/privateChat.vue'
import newFollow from '@/component/Account/message/newFollow.vue'
@@ -181,16 +174,6 @@ export default defineComponent({
<style lang="less" scoped>
.account_message{
width: 100%;
.account_message_title{
display: flex;
align-items: center;
justify-content: space-between;
padding: 2rem 5rem;
border-bottom: 1px solid #e9eaec;
.account_message_title_setting{
cursor: pointer;
}
}
.account_message_body{
padding-bottom: 3rem;
:deep(.ant-badge){
@@ -198,32 +181,24 @@ export default defineComponent({
}
:deep(.ant-tabs-nav){
padding: 0rem 5rem;
&::before{
display: none;
}
.ant-tabs-nav-wrap{
.ant-tabs-tab-btn{
font-size: 2.4rem;
}
.ant-tabs-tab-btn:active{
color: #39215b;
}
.ant-tabs-tab-active{
.ant-tabs-tab-btn{
color: #39215b;
font-weight: 900;
}
}
}
.ant-tabs-tab:hover{
color: #39215b;
}
.ant-tabs-ink-bar{
background: #39215b;
background: #000;
}
}
:deep(.ant-tabs-content){
height: 80rem;
// min-height: 80rem;
overflow-y: auto;
}
}
}
</style>

View File

@@ -2,10 +2,8 @@
<div class="account_fans">
<div class="account_generalMessage_title modal_title_text">
<span class="account_generalMessage_title_seach">
<input type="text" @keydown.enter="searchFollowFansList" class="search_input" v-model="getListData.seachContent">
<div class="search_icon_block" @click="searchFollowFansList">
<i class="icon iconfont icon-sousuo"></i>
</div>
<input class="gallery_input" type="text" :placeholder="$t('LibraryPage.jsContent7')" @keydown.enter="searchFollowFansList" v-model="getListData.seachContent">
<div class="gallery_btn" style="margin-left: 2rem;" @click="searchFollowFansList">Search</div>
</span>
</div>
<div class="account_generalMessage_center modal_title_text">
@@ -41,10 +39,7 @@
import { defineComponent,computed,ref,reactive,nextTick,toRefs,createVNode, onMounted} from 'vue'
import { Https } from "@/tool/https";
import { useRouter,useRoute } from 'vue-router'
import { Modal,message } from 'ant-design-vue';
import { useStore } from "vuex";
import { setCookie, getCookie, WriteCookie } from "@/tool/cookie";
import { useI18n } from 'vue-i18n'
export default defineComponent({
components:{
},

View File

@@ -1,11 +1,15 @@
<template>
<div class="account_follow">
<div class="account_generalMessage_title modal_title_text">
<span class="account_generalMessage_title_seach">
<!-- <span class="account_generalMessage_title_seach">
<input type="text" @keydown.enter="searchFollowFansList" class="search_input" v-model="getListData.seachContent">
<div class="search_icon_block" @click="searchFollowFansList">
<i class="icon iconfont icon-sousuo"></i>
</div>
</span> -->
<span class="account_generalMessage_title_seach">
<input class="gallery_input" type="text" :placeholder="$t('LibraryPage.jsContent7')" @keydown.enter="searchFollowFansList" v-model="getListData.seachContent">
<div class="gallery_btn" style="margin-left: 2rem;" @click="searchFollowFansList">Search</div>
</span>
</div>
<div class="account_generalMessage_center modal_title_text">
@@ -42,10 +46,7 @@
import { defineComponent,computed,ref,reactive,nextTick,toRefs,createVNode, onMounted} from 'vue'
import { Https } from "@/tool/https";
import { useRouter,useRoute } from 'vue-router'
import { Modal,message } from 'ant-design-vue';
import { useStore } from "vuex";
import { setCookie, getCookie, WriteCookie } from "@/tool/cookie";
import { useI18n } from 'vue-i18n'
export default defineComponent({
components:{
},

View File

@@ -0,0 +1,165 @@
<template>
<div class="account_frontPage">
<a-tabs class="account_frontPage_body" v-model:activeKey="activeKey" @change="changeTabs">
<a-tab-pane v-for="item in frontPageList" :key="item.key">
<myInformation v-if="item.key == 'myInformation' && activeKey == 'myInformation'" :ref="item.key"></myInformation>
<bind v-if="item.key == 'bind' && activeKey == 'bind'" :ref="item.key"></bind>
<cancelRenewal v-if="item.key == 'cancelRenewal' && activeKey == 'cancelRenewal'" :ref="item.key"></cancelRenewal>
<template #tab>
<a-badge :count="0" >
<span>{{item.title}}</span>
</a-badge>
</template>
</a-tab-pane>
</a-tabs>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,reactive,nextTick,toRefs,createVNode, onMounted} from 'vue'
import { Https } from "@/tool/https";
import { useRouter,useRoute } from 'vue-router'
import { Modal,message } from 'ant-design-vue';
import { useStore } from "vuex";
import myInformation from '@/component/Account/frontPage/mylnformation.vue';
import bind from '@/component/Account/frontPage/bindPage.vue';
import cancelRenewal from '@/component/Account/frontPage/cancelRenewal.vue';
import { useI18n } from 'vue-i18n'
export default defineComponent({
components:{
myInformation,
bind,
cancelRenewal,
},
setup() {
const {t} = useI18n()
const route = useRoute();
const router = useRouter();
const store = useStore();
let accountfrontPage = reactive({
frontPageList:[
{
title:t('account.myInfor'),
key:'myInformation',
},{
title:t('account.bindWeChat'),
key:'bind',
},{
title:t('account.cancel'),
key:'cancelRenewal',
}
],
loadingShow:false,
activeKey: '',
userDetail:computed(()=>{
return store.state.UserHabit.userDetail
})
})
let domRefs:any = reactive({
myInformation:ref(null),
bind:ref(null),
cancelRenewal:ref(null),
})
let changeTabs = (key:any)=>{
console.log(key);
// if(accountfrontPage.activeKey == 'service')return
}
let setReadStatus = (value:any)=>{
return new Promise((resolve,reject)=>{
if(value.isRead == 1)return reject('')
let data = {
type:accountfrontPage.activeKey,
notificationIdList:value.id
}
Https.axiosPost(Https.httpUrls.setReadStatus,'',{params:data}).then((rv)=>{
if(rv){
resolve(rv)
// store.commit('setfrontPageSystem',rv)
}
}).catch((err)=>{
reject(err)
})
})
}
const wechatLogin = (value:any)=> {
let data = {
code : value.code
}
accountfrontPage.loadingShow = true
Https.axiosGet(Https.httpUrls.bindWeChat, {params:data})
.then((rv) => {
accountfrontPage.loadingShow = false
let value = {
accountExtendList:{
WeChat:rv,
Google:accountfrontPage.userDetail.accountExtendList?.Google
}
}
store.commit("upUserDetail", value)
router.push({ query: {} });
})
.catch((res) => {accountfrontPage.loadingShow = false});
}
onMounted(()=>{
let key = accountfrontPage.frontPageList[0].key
accountfrontPage.activeKey = key
const data = route.query
if(data?.state == 'weiXin'){
accountfrontPage.activeKey = 'bind'
wechatLogin(data)
}
})
return{
...toRefs(accountfrontPage),
...toRefs(domRefs),
setReadStatus,
changeTabs,
}
},
data(){
return{
}
},
})
</script>
<style lang="less" scoped>
.account_frontPage{
width: 100%;
height: 100%;
.account_frontPage_body{
padding-bottom: 3rem;
height: 100%;
:deep(.ant-badge){
font-size: var(--aida-fsize2);
}
:deep(.ant-tabs-content){
height: 100%;
}
:deep(.ant-tabs-tabpane){
padding: 0 5rem;
}
:deep(.ant-tabs-nav){
padding: 0rem 5rem;
&::before{
display: none;
}
.ant-tabs-nav-wrap{
.ant-tabs-tab-btn{
font-size: 2.4rem;
}
.ant-tabs-tab-active{
.ant-tabs-tab-btn{
font-weight: 900;
}
}
}
.ant-tabs-ink-bar{
background: #000;
}
}
}
}
</style>

View File

@@ -0,0 +1,289 @@
<template>
<div class="bindPage_page">
<div class="bindPage_page_body">
<div class="bind_item">
<div class="title">{{ $t('frontPage.BindWechat') }}</div>
<div class="box">
<div class="type">
<img v-if="!userDetail.accountExtendList?.WeChat" src="@/assets/images/loginPage/weiXinIcon.svg" alt="">
<img v-else :src="userDetail.accountExtendList?.WeChat.headImgUrl" alt="">
<div class="text">{{ userDetail.accountExtendList?.WeChat?userDetail.accountExtendList?.WeChat.name:$t('frontPage.Unbound') }}</div>
</div>
<div v-if="!userDetail.accountExtendList?.WeChat" class="gallery_btn" @click="openWeiXinModel">{{ $t('frontPage.BindNow') }}</div>
<div v-if="userDetail.accountExtendList?.WeChat" class="gallery_btn" @click="ungroupWeiXinModel">{{ $t('frontPage.Unbind') }}</div>
</div>
</div>
<div class="bind_item">
<div class="title">{{ $t('frontPage.BindGmail') }}</div>
<div class="box">
<div class="type">
<img v-if="!userDetail.accountExtendList?.Google" src="@/assets/images/loginPage/gmailIcon.svg" alt="">
<img v-else :src="userDetail.accountExtendList?.Google?.headImgUrl" alt="">
<div class="text">{{ userDetail.accountExtendList?.Google?userDetail.accountExtendList?.Google.name:$t('frontPage.Unbound') }}</div>
</div>
<!-- <div class="gmail_btn">
<div v-if="!userDetail.accountExtendList?.Google && googleLoad" class="gallery_btn">{{ $t('frontPage.BindNow') }}</div>
<div v-else-if="!userDetail.accountExtendList?.Google" class="gallery_btn loading"><i class="fi fi-br-loading"></i></div>
<div v-show="!userDetail.accountExtendList?.Google" id="g_id_bind"></div>
<div v-if="userDetail.accountExtendList?.Google" class="gallery_btn" @click="ungroupGoogleModel">{{ $t('frontPage.Unbind') }}</div>
</div> -->
<div class="gmail_btn">
<div v-if="!userDetail.accountExtendList?.Google" class="gallery_btn">{{ $t('frontPage.BindNow') }}</div>
<div v-show="!userDetail.accountExtendList?.Google" id="g_id_bind"></div>
<div v-if="userDetail.accountExtendList?.Google" class="gallery_btn" @click="ungroupGoogleModel">{{ $t('frontPage.Unbind') }}</div>
<!-- <div v-if="userDetail.accountExtendList?.Google" class="gallery_btn" @click="ungroupGoogleModel">{{ $t('frontPage.Unbind') }}</div> -->
</div>
</div>
</div>
<!-- <div class="bind_item">
<div class="title">{{ $t('frontPage.ModifyEmail') }}</div>
<div class="box">
<div class="type">
<img :src="userDetail.avatar" alt="">
<div class="text">{{ userDetail.email }}</div>
</div>
<div class="gmail_btn">
<div class="gallery_btn" @click="modifyEmail">{{ $t('frontPage.Modify') }}</div>
</div>
</div>
</div> -->
</div>
<div class="mark_loading" v-show="loadingShow">
<a-spin size="large" />
</div>
<weiXinModel ref="weiXinModel"></weiXinModel>
<bindEmail ref="bindEmail"></bindEmail>
</div>
</template>
<script>
import { defineComponent,computed,createVNode,reactive,nextTick,toRefs,onBeforeUnmount, onMounted} from 'vue'
import { Https } from "@/tool/https";
import { Modal,message } from 'ant-design-vue';
import { useStore } from "vuex";
import weiXinModel from "@/component/LoginPage/weiXinModel.vue";
import { useRoute } from 'vue-router';
import { useRouter } from 'vue-router';
import { useI18n } from 'vue-i18n'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import bindEmail from "@/component/HomePage/bindEmail.vue";
export default defineComponent({
components:{
weiXinModel,bindEmail
},
setup() {
const route = useRoute();
const router = useRouter();
const t = useI18n().t;
const store = useStore();
let accountHomeData = reactive({
router:null,
loadingShow:false,
googleLoad:false,
userDetail:computed(()=>{
return store.state.UserHabit.userDetail
})
})
let bindPageDom = reactive({
weiXinModel:null,
bindEmail:null,
})
let data = reactive({
scriptSrc:'https://accounts.google.com/gsi/client',
})
const openWeiXinModel = ()=>{
bindPageDom.weiXinModel.init()
}
const handleCredentialResponse = (response)=>{
let code = response.credential
accountHomeData.loadingShow = true
let data = {credential : code}
Https.axiosGet(Https.httpUrls.bindGoogle, {params:data})
.then((rv) => {
accountHomeData.loadingShow = false
let value = {
accountExtendList:{
WeChat:accountHomeData.userDetail.accountExtendList?.WeChat,
Google:rv,
}
}
store.commit("upUserDetail", value)
})
.catch((res) => {accountHomeData.loadingShow = false});
}
const ungroupWeiXinModel = ()=>{
Https.axiosGet(Https.httpUrls.unbindWeChat,).then((rv)=>{
message.success(t('frontPage.jsContent1'));
let value = {
accountExtendList:{
WeChat:undefined,
Google:accountHomeData.userDetail.accountExtendList?.Google
}
}
store.commit("upUserDetail", value)
})
}
const ungroupGoogleModel = ()=>{
Https.axiosGet(Https.httpUrls.unbindGoogle,).then((rv)=>{
let value = {
accountExtendList:{
WeChat:accountHomeData.userDetail.accountExtendList?.WeChat,
Google:undefined,
}
}
store.commit("upUserDetail", value)
message.success(t('frontPage.jsContent1'));
})
}
const modifyEmail = ()=>{
bindPageDom.bindEmail.init('Modify')
}
onMounted(async ()=>{
let GOOGLE_CLIENT_ID = '194770296147-njd68pm7tnapgonkj2h48mhf63n15n3f.apps.googleusercontent.com'
var existingScript = document.querySelector(`script[src="${data.scriptSrc}"]`);
if(!window.isAddGmail){
if(!existingScript){
window.isAddGmail = true
await new Promise((resolve, reject) => {
const script = document.createElement("script");
script.src = data.scriptSrc
script.onload=()=>{
accountHomeData.googleLoad = true
resolve()
}
script.onerror = ()=>{
Modal.confirm({
title: t('frontPage.jsContent2'),
icon: createVNode(ExclamationCircleOutlined),
okText: 'Yes',
cancelText: 'No',
mask:false,
centered:true,
onOk() {
}
});
accountHomeData.googleLoad = true
}
document.body.appendChild(script);
})
}
window.google.accounts.id.initialize({
// 主要就是填写client_id
client_id: GOOGLE_CLIENT_ID,
auto_select: false,
callback: handleCredentialResponse,
// context:"signin",
ux_mode:"popup",
itp_support:true,
});
window.google.accounts.id.renderButton(
document.getElementById("g_id_bind"),
{
type:"icon",//icon为只有一个icon
shape:"circle",
theme:"outline",
size:"large",
logo_alignment:"center",
}
);
}
})
onBeforeUnmount(()=>{
var existingScript = document.querySelector(`script[src="${data.scriptSrc}"]`);
if(existingScript){
existingScript.remove()
window.isAddGmail = false
}
})
return{
...toRefs(accountHomeData),
...toRefs(bindPageDom),
openWeiXinModel,
ungroupGoogleModel,
ungroupWeiXinModel,
modifyEmail,
}
},
data(){
return{
}
},
})
</script>
<style lang="less" scoped>
.bindPage_page{
height: 100%;
overflow-y: auto;
padding-bottom: 2rem;
.bindPage_page_body{
.bind_item{
margin-bottom: 4rem;
>.title{
font-size: 2rem;
margin-bottom: 2rem;
font-weight: 600;
}
>.box{
width: 100%;
border: 2px solid #000;
border-radius: 2rem;
padding: 3rem;
display: flex;
align-items: center;
justify-content: space-between;
>.type{
display: flex;
>img{
margin-right: 3rem;
width: 5rem;
height: 5rem;
}
>.text{
display: flex;
align-items: center;
font-size: 1.8rem;
}
}
.gallery_btn{
&.loading{
width: 10rem;
i{
&::before{
display: inline-block;
animation: loading 1s linear infinite;
@keyframes loading {
from{
transform: rotate(0deg);
}
to{
transform: rotate(360deg);
}
}
}
}
}
}
>.gmail_btn{
position: relative;
#g_id_bind{
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
opacity: 0;
z-index: 2;
:deep(.nsm7Bb-HzV7m-LgbsSe.Bz112c-LgbsSe){
width: 100%;
}
}
}
}
}
.bind_item:last-child{
margin-bottom: 0;
}
}
}
</style>

View File

@@ -0,0 +1,248 @@
<template>
<div class="cancelRenewal_page">
<div v-if="userDetail.status != 'canceled'">
<div class="cancel_box_item">
<div class="modal_title_text">
<div>{{ $t('cancelRenewal.cancelling') }}</div>
</div>
<div class="cause_list">
<label class="cause_item" v-for="item in causeList" :key="item.vlaue">
<input type="checkbox" name="cause" v-model="selectedOptions" :value="item.value">
<div>{{ item.str }}</div>
</label>
<textarea v-model="textareaValue" placeholder="Share your feedback here..."></textarea>
</div>
</div>
<div class="cancel_box_item cancel_box_item2">
<!-- <div class="modal_title_text">
<div>{{ $t('cancelRenewal.subscription') }}</div>
<div>
<i class="fi fi-sr-circle-xmark"></i>
<div class="modal_title_text_assistant">{{ $t('cancelRenewal.looseDate') }}</div>
</div>
<div>
<i class="fi fi-sr-circle-xmark"></i>
<div class="modal_title_text_assistant">{{ $t('cancelRenewal.looseCustomizations') }}</div>
</div>
</div>
<div class="tips">
<i class="fi fi-sr-triangle-warning"></i>
<div>{{ $t('cancelRenewal.DonWorry') }}</div>
</div> -->
<div class="button_box">
<div class="gallery_btn white" @click="subscribe">{{ $t('cancelRenewal.Continue') }}</div>
<div class="gallery_btn" @click="cancelSubscription">{{ $t('cancelRenewal.cancel') }}</div>
</div>
</div>
</div>
<div v-else class="no_renewal">
{{ $t('cancelRenewal.subscriptionRenewal') }}
</div>
<div class="mark_loading" v-show="isShowMark">
<a-spin size="large" />
</div>
<renew ref="renew"></renew>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,reactive,nextTick,toRefs,createVNode, onMounted} from 'vue'
import { Https } from "@/tool/https";
import { Modal,message } from 'ant-design-vue';
import { useStore } from "vuex";
import { useI18n } from 'vue-i18n'
import renew from "@/component/HomePage/renew.vue";
export default defineComponent({
components:{
renew,
},
setup() {
const store = useStore();
const {t} = useI18n()
let userDetail:any= computed(()=>{
return store.state.UserHabit.userDetail
})
let accountHomeData:any = reactive({
textareaValue:'',
isShowMark:false,
causeList:[
{
vlaue:'Too expensive',
str:t('account.jsContent1'),
},{
value:'Sytem not user friendly',
str:t('account.jsContent2'),
},{
value:'Too Slowy',
str:t('account.jsContent3'),
},{
value:'Difficult to edit',
str:t('account.jsContent4'),
},{
value:'Insufficlent Tutorial/Support',
str:t('account.jsContent5'),
},{
value:'Unable to generate what you need',
str:t('account.jsContent6'),
}
],
selectedOptions:[]
})
let renew = ref()
const subscribe = ()=>{
renew.value.init()
}
const cancelSubscription = ()=>{
let str = ''
accountHomeData.selectedOptions.forEach((item:any)=>{
str += ' #' + item
})
let data = {
subscriptionId:userDetail.value.subscriptionId,
reason:accountHomeData.textareaValue + str,
}
accountHomeData.isShowMark = true
Https.axiosGet(Https.httpUrls.cancelSubscription, {params:data})
.then((rv: any) => {
message.success(rv)
let value = {
status:'canceled',
}
accountHomeData.isShowMark = false
store.commit("upUserDetail", value)
})
.catch((res) => {
accountHomeData.isShowMark = false
});
}
return{
...toRefs(accountHomeData),
userDetail,
renew,
subscribe,
cancelSubscription,
}
},
data(){
return{
}
},
})
</script>
<style lang="less" scoped>
.cancelRenewal_page{
height: 100%;
overflow-y: auto;
padding-bottom: 2rem;
>div{
display: flex;
flex-direction: column;
align-items: center;
&.no_renewal{
font-size: 2rem;
font-weight: 400;
}
}
.cancel_box_item{
margin-bottom: 3rem;
width: 100%;
>.modal_title_text{
margin: 0;
>div{
font-weight: 600;
}
.modal_title_text_assistant{
margin-top: 1rem;
font-weight: 600;
}
}
>.gallerySelect{
width: 100%;
:deep(.ant-select-selector){
border-radius: 1.4rem;
}
}
>.cause_list{
> .cause_item{
display: flex;
align-items: center;
font-size: 1.6rem;
font-weight: 600;
input{
margin-right: 1rem;
width: 2.2rem;
height: 2.2rem;
}
}
>textarea{
margin-top: 1.5rem;
width: 100%;
border-radius: 1.4rem;
border: 1px solid #D0D0D0;
height: 11rem !important;
font-size: 1.6rem;
transition: border .3s;
padding: 1.5rem;
}
>textarea:hover{
border: 1px solid #000;
}
}
>.button_box{
display: flex;
margin-top: 2.5rem;
justify-content: flex-end;
>div:nth-child(1){
margin-right: 1rem;
// width: calc((100% - 1rem) / 2);
}
}
}
.cancel_box_item:last-child{
margin: 0;
}
.cancel_box_item2{
.modal_title_text{
>div:nth-child(1){
margin-bottom: 2rem;
}
>div:nth-child(2){
margin-bottom: 1.5rem;
}
>div:nth-child(2),>div:nth-child(3){
display: flex;
align-items: center;
>.modal_title_text_assistant{
margin: 0;
}
>i{
margin-right: 1.5rem;
display: flex;
}
}
>div:nth-child(3){
margin-bottom: 2rem;
}
}
.tips{
padding: 1.5rem 1rem;
display: flex;
align-items: center;
margin-bottom: 3rem;
background: #f3f3f6;
border-radius: 1.4rem;
border: 1px solid #D0D0D0;
>i{
margin-right: 1.3rem;
}
>div{
font-size: 1.6rem;
font-weight: 400;
}
}
}
}
</style>

View File

@@ -0,0 +1,151 @@
<template>
<div class="accountEdit_page">
<div class="accountEdit_page_body">
<div class="accountEdit_page_body_item">
<div class="accountEdit_page_body_item_name">{{$t('account.Country')}}:</div>
<div class="accountEdit_page_body_item_inut">
<a-select
v-model:value="Country"
size="large"
optionFilterProp="label"
:options="countryList"
placeholder="Please select"
allowClear
show-search
></a-select>
</div>
</div>
<div class="accountEdit_page_body_item">
<div class="accountEdit_page_body_item_name">{{$t('account.CompanyName')}}:</div>
<div class="accountEdit_page_body_item_inut">
<input type="text" v-model="CompanyName">
</div>
</div>
<div class="accountEdit_page_body_item">
<div class="gallery_btn" @click="setSubmit">
{{$t('account.Submit')}}
</div>
</div>
</div>
<div class="mark_loading" v-show="loadingShow">
<a-spin size="large" />
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,reactive,nextTick,toRefs,createVNode, onMounted} from 'vue'
import { Https } from "@/tool/https";
import { Modal,message } from 'ant-design-vue';
import { useStore } from "vuex";
import { country } from "@/tool/country";
import { useI18n } from 'vue-i18n'
export default defineComponent({
components:{
},
setup() {
const store = useStore();
const {t} = useI18n();
let userDetail:any= computed(()=>{
return store.state.UserHabit.userDetail
})
let accountHomeData:any = reactive({
Country:'',
CompanyName:'',
loadingShow:false,
countryList:country
})
let setSubmit = ()=>{
let data = {
country:accountHomeData.Country,
occupation:accountHomeData.CompanyName
}
accountHomeData.loadingShow = true
Https.axiosGet(Https.httpUrls.updateUserInfo,{params:data}).
then((rv:any)=>{
let value = {
userName:accountHomeData.editUserName
}
store.commit('upUserDetail',value)
accountHomeData.loadingShow = false
message.success(t('exportModel.jsContent7'))
}).catch((err:any)=>{
accountHomeData.loadingShow = false
})
}
onMounted(()=>{
let country = userDetail.value.country
let CompanyName = userDetail.value.occupation
accountHomeData.Country = country
accountHomeData.CompanyName = CompanyName
})
return{
...toRefs(accountHomeData),
userDetail,
setSubmit,
}
},
data(){
return{
}
},
})
</script>
<style lang="less" scoped>
.accountEdit_page{
height: 100%;
overflow-y: auto;
padding-bottom: 2rem;
.accountEdit_page_body{
width: 100%;
// width: 85rem;
.accountEdit_page_body_item{
display: flex;
margin-bottom: 20px;
flex-direction: column;
width: 100%;
.gallery_btn{
margin-left: auto;
}
input,textarea{
padding-left: 11px;
border-radius: 1.6rem;
border: 2px solid #D0D0D0;
width: 100%;
font-size: 2rem;
}
input{
height: 40px;
}
.accountEdit_page_body_item_name{
color: #000;
text-align: left;
font-size: 2rem;
}
.accountEdit_page_body_item_inut{
margin-top: 1.5rem;
flex: 1;
.ant-select-lg{
font-size: 2rem;
}
.ant-select{
width: 100%;
border-radius: 1.6rem;
border: 2px solid #D0D0D0;
overflow: hidden;
.ant-select-selector{
border-radius: 1.6rem;
}
:deep(.ant-select-selector ){
border: none !important;
}
}
}
}
.accountEdit_page_body_item:last-child{
justify-content: center;
}
}
}
</style>

View File

@@ -43,8 +43,6 @@ import { Https } from "@/tool/https";
import { useRouter,useRoute } from 'vue-router'
import { Modal,message } from 'ant-design-vue';
import { useStore } from "vuex";
import { setCookie, getCookie, WriteCookie } from "@/tool/cookie";
import { useI18n } from 'vue-i18n'
export default defineComponent({
components:{
},

View File

@@ -41,8 +41,6 @@ import { Https } from "@/tool/https";
import { useRouter,useRoute } from 'vue-router'
import { Modal,message } from 'ant-design-vue';
import { useStore } from "vuex";
import { setCookie, getCookie, WriteCookie } from "@/tool/cookie";
import { useI18n } from 'vue-i18n'
export default defineComponent({
components:{
},

View File

@@ -37,9 +37,7 @@
import { defineComponent,computed,ref,reactive,nextTick,toRefs,createVNode, onMounted} from 'vue'
import { Https } from "@/tool/https";
import { useRouter,useRoute } from 'vue-router'
import { Modal,message } from 'ant-design-vue';
import { useStore } from "vuex";
import { setCookie, getCookie, WriteCookie } from "@/tool/cookie";
import { useI18n } from 'vue-i18n'
export default defineComponent({
components:{

View File

@@ -73,7 +73,6 @@ import { Https } from "@/tool/https";
import { useRouter,useRoute } from 'vue-router'
import { Modal,message } from 'ant-design-vue';
import { useStore } from "vuex";
import { setCookie, getCookie, WriteCookie } from "@/tool/cookie";
import { useI18n } from 'vue-i18n'
export default defineComponent({
components:{

View File

@@ -30,9 +30,7 @@
import { defineComponent,computed,ref,reactive,nextTick,toRefs,createVNode, onMounted} from 'vue'
import { Https } from "@/tool/https";
import { useRouter,useRoute } from 'vue-router'
import { Modal,message } from 'ant-design-vue';
import { useStore } from "vuex";
import { setCookie, getCookie, WriteCookie } from "@/tool/cookie";
import { useI18n } from 'vue-i18n'
export default defineComponent({
components:{

View File

@@ -53,7 +53,6 @@ import { Https } from "@/tool/https";
import { useRouter,useRoute } from 'vue-router'
import { Modal,message } from 'ant-design-vue';
import { useStore } from "vuex";
import { setCookie, getCookie, WriteCookie } from "@/tool/cookie";
import { useI18n } from 'vue-i18n'
import Works from '@/views/HomeView/Works.vue';
export default defineComponent({
@@ -114,7 +113,7 @@ export default defineComponent({
.otherUsers{
width: 100%;
height: 100%;
padding: 0 9rem;
padding: 0 6rem;
display: flex;
flex-direction: column;
overflow-y: auto;

View File

@@ -0,0 +1,572 @@
<template>
<div class="admin_page">
<div class="admin_table_search">
<div class="admin_state">
<div class="admin_state_item">
<span>Create Time:</span>
<a-range-picker
style="width: 250px"
class="range_picker"
v-model:value="rangePickerValue"
:placeholder="[
$t('HistoryPage.StartDate'),
$t('HistoryPage.EndDate'),
]"
valueFormat="YYYY-MM-DD"
>
<template #suffixIcon>
<span
class="icon iconfont range_picker_icon icon-rili"
></span>
</template>
</a-range-picker>
</div>
<div class="admin_state_item">
<span>Country:</span>
<a-select
v-model:value="country"
:allowClear="true"
show-search
style="width: 250px"
:filter-option="filterOption"
placeholder="Select Item..."
max-tag-count="responsive"
:options="countryList"
></a-select>
</div>
<div class="admin_state_item">
<span>City:</span>
<a-select
v-model:value="city"
:allowClear="true"
show-search
style="width: 250px"
:filter-option="filterOption"
placeholder="Select Item..."
max-tag-count="responsive"
:options="cityList"
></a-select>
</div>
<div class="admin_state_item">
<span>Payment Amount:</span>
<input
v-model="payerTotal"
placeholder="Please enter payment amount"
@keydown.enter="gettrialList"
type="text"
style="width: 250px"
/>
</div>
<div class="admin_state_item">
<span>platform:</span>
<a-select
v-model:value="platform"
size="large"
style="width: 250px"
optionFilterProp="label"
:options="platformList"
placeholder="Please select"
allowClear
show-search
></a-select>
</div>
<div class="admin_state_item">
<span>Status:</span>
<a-select
v-model:value="status"
size="large"
style="width: 250px"
optionFilterProp="label"
:options="statusList"
placeholder="Please select"
allowClear
show-search
></a-select>
</div>
<div class="admin_state_item">
<span>Type:</span>
<a-select
v-model:value="type"
size="large"
style="width: 250px"
optionFilterProp="label"
:options="articleCategoryList"
placeholder="Please select"
allowClear
show-search
></a-select>
</div>
</div>
<div class="admin_search">
<div class="admin_search_item" @click="searchHistoryList">
Search
</div>
<div class="admin_search_item" @click="downloadTransaction">
Export
</div>
</div>
<div class="admin_state_list">
<div
class="admin_state_list_item"
@click="lastGeTrialList('year')"
>
Nearly a year
</div>
<div
class="admin_state_list_item"
@click="lastGeTrialList('month')"
>
Last month
</div>
<div
class="admin_state_list_item"
@click="lastGeTrialList('week')"
>
Last week
</div>
</div>
</div>
<div class="admin_table_content" ref="historyTable">
<a-table
@resizeColumn="handleResizeColumn"
:loading="tableLoading"
:columns="columns"
:data-source="dataList"
:scroll="{ y: historyTableHeight }"
@change="changePage"
:showSorterTooltip='false'
:pagination="{
showSizeChanger: true,
current: currentPage,
pageSize: pageSize,
total: total,
showQuickJumper: true,
bordered: false,
}"
>
<template #bodyCell="{ column, text, record, index }">
<div class="operate_list" v-if="column?.Operations">
<div v-if="record.status == 'Success'" :class="{success:record.status == 'Success'}">
<i class="fi fi-ss-check-circle"></i>{{ record.status }}
</div>
<div v-if="record.status == 'Pending'" :class="{pending:record.status == 'Pending'}">
<i class="fi fi-br-hourglass-end"></i>{{ record.status }}
</div>
<div v-if="record.status == 'Fail'" :class="{fail:record.status == 'Fail'}">
<i class="fi fi-ss-cross-circle"></i>{{ record.status }}
</div>
</div>
</template>
</a-table>
</div>
</div>
</template>
<script lang="ts">
import {
defineComponent,
ref,
createVNode,
computed,
reactive,
toRefs,
onMounted,
} from "vue";
import { formatTime } from "@/tool/util";
import { useStore } from "vuex";
import { Https } from "@/tool/https";
import {getCookie,clonAllCookie} from '@/tool/cookie'
export default defineComponent({
components: {},
setup() {
const store:any = useStore()
let filter: any = reactive({
dataList: [],
tableLoading: false,
allCountry:[],
cityList: computed(()=>{
return store.state.adminPage.city
}),
countryList: computed(()=>{
return store.state.adminPage.country
}),
});
let filterData: any = reactive({
rangePickerValue: [],
currentPage: 1,
pageSize: 10,
total: 0,
country: "",
city:"",
payerTotal: "",
platform: "",
order: "", //'Ascending 升序 Descending 降序'
orderBy:'',
status: "",
type: "",
});
let selectList=reactive({
platformList:[
{
label: "all",
value: "",
},
{
label:'PayPal',
value:'PayPal',
},
{
label:'Stripe',
value:'Stripe',
},
{
label:'Alipay-HK',
value:'Alipay-HK',
},
],
statusList:[
{
label: "all",
value: "",
},
{
label:'Success',
value:'Success',
},
{
label:'Fail',
value:'Fail',
},
{
label:'Pending',
value:'Pending',
},
],
articleCategoryList:[
{
label: "all",
value: "",
},
{
label:'new',
value:'new',
},
{
label:'renewal',
value:'renewal',
},
{
label:'credits',
value:'credits',
},
],
})
let renameData: any = ref({}); //修改名字选中的数据
const columns: any = computed(() => {
return [
{
title: "Id",
align: "center",
dataIndex: "id",
key: "id",
width:100,
fixed: "left",
sorter: true,
},
{
title: "Payer",
align: "center",
dataIndex: "payer",
key: "payer",
width:150,
ellipsis:true,
},
{
title: "Platform",
align: "center",
dataIndex: "platform",
key: "platform",
width:150,
ellipsis:true,
},{
title: "Payment Amount",
align: "center",
dataIndex: "payerTotal",
key: "payerTotal",
width:150,
ellipsis:true,
},
{
title: "Type",
align: "center",
dataIndex: "type",
key: "type",
width:150,
ellipsis:true,
},
{
title: "Payment Method",
align: "center",
dataIndex: "paymentMethod",
key: "paymentMethod",
width:150,
ellipsis:true,
},
{
title: "last4",
key: "last4",
width:120,
align: "center",
dataIndex: "last4",
// slots:{customRender:'action'}
},
// {
// title: 'User Type',
// align: "center",
// dataIndex: "systemUser",
// key: "systemUser",
// width:100,
// customRender: (record: any) => {
// let str;
// if (record.value == 0) {
// str = "visitor";
// } else if (record.value == 1) {
// str = "yearly";
// } else if (record.value == 2) {
// str = "monthly";
// } else if (record.value == 3) {
// str = "trial";
// } else if (record.value == 4) {
// str = "userInEvent";
// }
// return str;
// },
// },
{
title: "City",
align: "center",
dataIndex: "city",
key: "city",
width:150,
ellipsis:true
},
{
title: "Country",
align: "center",
dataIndex: "country",
key: "country",
width:150,
ellipsis:true
},
{
title: "Create Time",
align: "center",
dataIndex: "createTime",
key: "createTime",
width:150,
ellipsis:true,
},
{
title: "Status",
align: "center",
dataIndex: "status",
key: "status",
fixed: "right",
width:150,
Operations: true,
ellipsis:true,
}
];
});
//改变页码
let changePage = (e: any, filters:any, sorter:any) => {
filterData.currentPage = e.current;
filterData.pageSize = e.pageSize;
if(sorter.order){
if(sorter.columnKey == 'id'){
filterData.orderBy = 'id'
}else if(sorter.columnKey == "createDate"){
filterData.orderBy = 'time'
}else if(sorter.columnKey == "credits"){
filterData.orderBy = 'credits'
}
}
filterData.order = sorter.order == "descend" ? "DESC" : "ASC";
gettrialList();
};
//查询列表
let searchHistoryList = () => {
filterData.currentPage = 1;
gettrialList();
};
let clearHistoryList = () => {
filterData.rangePickerValue = [],
filterData.currentPage = 1,
filterData.pageSize = 10,
filterData.total = 0,
filterData.city = "",
filterData.country = "",
filterData.payerTotal = ""
filterData.order = "" //'Ascending 升序 Descending 降序'
filterData.orderBy = "" //'Ascending 升序 Descending 降序'
filterData.platform = ""
filterData.status = ""
filterData.type = ""
};
let setHistoryListData = () => {
let startDate: any = filterData.rangePickerValue?.[0]
? filterData.rangePickerValue[0] + " " + "00:00:00"
: "";
let endDate: any = filterData.rangePickerValue?.[1]
? filterData.rangePickerValue[1] + " " + "23:59:59"
: "";
console.log(startDate);
let data = {
order: filterData.order,
orderBy: filterData.orderBy,
"city": filterData.city,
"country": filterData.country,
startTime: startDate,
endTime: endDate,
"id": 0,
page: filterData.currentPage,
"payerTotal": filterData.payerTotal,
"platform": filterData.platform,
size: filterData.pageSize,
"status": filterData.status,
"type": filterData.type
};
return data;
};
//获取列表
let gettrialList = () => {
filter.tableLoading = true;
let data = setHistoryListData();
Https.axiosPost(Https.httpUrls.queryTransaction, data).then(
(rv: any) => {
if (rv) {
console.log(rv);
// this.dataList = rv
filter.dataList = rv.content;
filterData.total = rv.total;
filter.tableLoading = false;
// this.workspaceItem.position = this.singleTypeList[0].label
}
}
);
};
//导出报表
let downloadTransaction = () => {
filter.tableLoading = true;
let data = setHistoryListData();
Https.axiosPost(Https.httpUrls.queryTransactionDownload, data).then(
(rv: any) => {
if (rv) {
fetch(rv)
.then(response => response.blob()) // 将响应转换为 Blob 对象
.then(blob => {
// 创建一个指向 Blob 对象的 URL
const link = document.createElement('a');
link.href = URL.createObjectURL(blob); // 将 Blob 对象转换为可下载的 URL
link.download = 'transaction'; // 设置文件名
filter.tableLoading = false;
link.click(); // 触发下载
URL.revokeObjectURL(link.href); // 释放 URL 对象
})
}
}
);
};
let lastGeTrialList = (str: string) => {
clearHistoryList();
let currentDate = new Date();
let currentTimestamp = Math.floor(currentDate.getTime() / 1000);
// 计算30天前的时间戳
let thirtyDaysAgoTimestamp;
if (str == "year") {
thirtyDaysAgoTimestamp = currentTimestamp - 360 * 24 * 60 * 60;
} else if (str == "month") {
thirtyDaysAgoTimestamp = currentTimestamp - 30 * 24 * 60 * 60;
} else if (str == "week") {
thirtyDaysAgoTimestamp = currentTimestamp - 7 * 24 * 60 * 60;
}
// filterData.rangePickerValue[0] = formatTime(
// thirtyDaysAgoTimestamp,
// "YYYY-MM-DD"
// );
filterData.rangePickerValue = [formatTime(thirtyDaysAgoTimestamp,'YYYY-MM-DD'),formatTime(currentTimestamp,'YYYY-MM-DD')]
gettrialList();
};
let filterOption = (input: any, option: any) => {
// 使用 option.label 进行搜索
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
};
onMounted(() => {
let allCountry: any = sessionStorage.getItem("allCountry");
if (allCountry) {
filter.allCountry = JSON.parse(allCountry);
}
gettrialList();
});
return {
...toRefs(filter),
...toRefs(filterData),
...toRefs(selectList),
columns,
renameData,
changePage,
searchHistoryList,
lastGeTrialList,
gettrialList,
downloadTransaction,
filterOption,
};
},
data() {
return {
historyTableHeight: 0,
handleResizeColumn: (w: any, col: any) => {
col.width = w;
},
};
},
mounted() {
let historyTable: any = this.$refs.historyTable;
this.historyTableHeight = historyTable.clientHeight - 200;
},
methods: {},
});
</script>
<style lang="less" scoped>
.admin_page .admin_table_search .admin_state {
display: flex;
flex-wrap: wrap;
}
:deep(.operate_list){
.fi{
font-size: 2rem;
margin-right: 1rem;
}
.success{
.fi-ss-check-circle{
color: #3ab45c;
}
}
.pending{
.fi-ss-check-circle{
color: #ffc628;
}
}
.fail{
.fi-ss-check-circle{
color: #ff0000;
}
}
}
</style>

View File

@@ -0,0 +1,313 @@
<template>
<div class="admin_page">
<div class="admin_table_search">
<div class="admin_state">
<div class="admin_state_item">
<span>Start Time:</span>
<a-range-picker
style="width:280px"
class="range_picker"
v-model:value="rangePickerValue"
:allowClear="false"
:placeholder="[
$t('HistoryPage.StartDate'),
$t('HistoryPage.EndDate'),
]"
valueFormat="YYYY-MM-DD"
>
<template #suffixIcon>
<span
class="icon iconfont range_picker_icon icon-rili"
></span>
</template>
</a-range-picker>
</div>
<div class="admin_state_item">
<span>State:</span>
<a-select v-model:value="currentState.value" size="large" style="width:280px" optionFilterProp="label" :options="state" placeholder="Please select" allowClear show-search></a-select>
</div>
<div class="admin_state_item">
<span>Affiliate Id:</span>
<input
style="width:280px"
v-model="affiliateId"
placeholder="Please enter Affiliate Id"
@keydown.enter="gettrialList"
type="text"
/>
</div>
</div>
<div class="admin_search">
<div class="admin_search_item" @click="searchHistoryList">Search</div>
</div>
</div>
<div class="admin_table_content" ref="historyTable">
<a-table
:columns="columns"
:data-source="collectionList"
:scroll="{ y: historyTableHeight }"
@change="changePage"
>
<template
#bodyCell="{ column, text, record, index }"
>
<div
class="operate_list"
v-if="column?.Operations && record.status == 'Pending'"
>
<div v-show="status == 0" class="operate_item" @click="setAgree(record, true)">
agree
</div>
<div v-show="status == 0" class="operate_item" @click="setAgree(record, false)" >
refuse
</div>
</div>
<div v-else-if="column?.Operations">
{{ record.status }}
</div>
<div v-else-if="column?.openType" @click="openDetail(record,column?.openType)">
{{ text }} HDK
</div>
</template>
</a-table>
</div>
<itemAffiliateDetail ref="itemAffiliateDetail"></itemAffiliateDetail>
</div>
</template>
<script lang="ts">
import { defineComponent, ref, createVNode, computed } from "vue";
import { Https } from "@/tool/https";
import { Modal, message } from "ant-design-vue";
import itemAffiliateDetail from "./itemAffiliateDetail.vue";
export default defineComponent({
components: {
itemAffiliateDetail,
},
setup() {
let renameData: any = ref({}); //修改名字选中的数据
const columns: any = computed(() => {
return [
{
title: 'Id',
align: "center",
width: 50,
dataIndex: "id",
key: "id",
fixed: "left",
},
{
title: 'User Name',
align: "center",
width: 100,
dataIndex: "username",
key: "username",
},
{
title: 'Create Time',
align: "center",
width: 200,
dataIndex: "createTime",
key: "createTime",
sorter: true,
},{
title: 'State',
align: "center",
ellipsis: true,
width: 100,
dataIndex: "status",
key: "status",
},{
title: 'Total income',
align: "center",
ellipsis: true,
width: 100,
dataIndex: "totalEarnings",
key: "totalEarnings",
openType:'month',
},{
title: 'Monthly income',
align: "center",
ellipsis: true,
width: 100,
dataIndex: "monthlyEarnings",
key: "monthlyEarnings",
openType:'all',
},{
title: 'Unpaid amount',
align: "center",
ellipsis: true,
width: 100,
dataIndex: "unpaidEarnings",
key: "unpaidEarnings",
},{
title: 'Invitation Link',
align: "center",
ellipsis: true,
width: 250,
dataIndex: "link",
key: "link",
},{
title: 'Updata Time',
align: "center",
width: 200,
dataIndex: "updateTime",
key: "updateTime",
},
{
title: 'Operations',
key: "operation",
align: "center",
fixed: "right",
width: 130,
// slots:{customRender:'action'}
Operations: true,
},
];
});
let currentState = ref({
label:'All',
value:'',
state:false,
},)
let state:any = ref([
{
label:'All',
value:'',
},
{
label:'Pending',
value:'Pending',
},
{
label:'Active',
value:'Active',
},
{
label:'Inactive',
value:'Inactive',
},
{
label:'Refused',
value:'Refused',
},
])
const itemAffiliateDetail = ref()
let collectionList: any = ref([]);
let status: any = ref(0);
const openDetail = (value:any,openType:string)=>{
console.log(value,openType);
let data = {
id:value.id,
type:openType
}
itemAffiliateDetail.value.init(data)
}
return {
columns,
collectionList,
renameData,
status,
currentState,
itemAffiliateDetail,
state,
openDetail,
};
},
data() {
return {
rangePickerValue:[],
currentPage: 1,
pageSize: 10,
total: 0,
order:'',
affiliateId:'',
historyTableHeight: 0,
newCollectionName: "",
renameVisivle: false, //修改名字弹窗
collectionName: "", //选中的名字
searchCollectionName: "",
};
},
mounted() {
let historyTable: any = this.$refs.historyTable;
this.historyTableHeight = historyTable.clientHeight - 200;
this.gettrialList();
},
methods: {
//改变页码
changePage(e: any, filters:any, sorter:any) {
this.currentPage = e.current;
this.pageSize = e.pageSize;
this.order = sorter.order == "descend" ? "DESC" : "ASC";
this.gettrialList();
},
//查询列表
searchHistoryList() {
this.currentPage = 1;
this.gettrialList();
},
//获取列表
gettrialList() {
let startDate: any = this.rangePickerValue?.[0]
? this.rangePickerValue[0]+' '+'00:00:00'
: "";
let endDate: any = this.rangePickerValue?.[1]
? this.rangePickerValue[1]+' '+'23:59:59'
: "";
let data = {
page: this.currentPage,
size: this.pageSize,
order: this.order,
status: this.currentState.value,
startTime:startDate,
endTime:endDate,
affiliateId:this.affiliateId
};
Https.axiosPost(Https.httpUrls.affiliateList, data).then(
(rv: any) => {
this.collectionList = rv.content;
this.total=rv.total
}
);
},
setAgree(record: any, boolean: boolean){
// const formData = new FormData()
// formData.append('id',record.id)
// formData.append('isApproved ',boolean+'')
let data = {
id:record.id,
isApproved: boolean,
}
let config:any = {headers:{'Content-Type':'multipart/form-data','Accept':'*/*' }}
Https.axiosGet(Https.httpUrls.affiliateApproval, {params:data}).then(
(rv: any) => {
if(boolean){
message.success('同意成功~')
}else{
message.success('拒绝成功~')
}
this.gettrialList();
}
);
},
setState(){
this.currentState.state = true
},
setStateItem(item:any){
this.currentState = item
this.currentState.state = false
},
},
});
</script>
<style lang="less" scoped>
.admin_page .admin_table_content .operate_list{
justify-content: space-between;
}
</style>

View File

@@ -0,0 +1,229 @@
<template>
<div class="itemAffiliateDetail" ref="itemAffiliateDetail"></div>
<a-modal class="generalModel"
v-model:visible="itemAffiliateDetailShow"
:footer="null"
:get-container="() => $refs.itemAffiliateDetail"
width="75%"
:maskClosable="false"
:centered="true"
:closable="false"
:mask="true"
wrapClassName="#app"
>
<div class="generalModel_btn">
<div class="generalModel_closeIcon" @click.stop="cancelDsign()">
<svg width="46" height="46" viewBox="0 0 46 46" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="23" cy="23" r="23" fill="white" fill-opacity="0.3"/>
<rect x="32.5063" y="12" width="3" height="29" rx="1.5" transform="rotate(45 32.5063 12)" fill="white"/>
<rect x="34.6274" y="32.5059" width="3" height="29" rx="1.5" transform="rotate(135 34.6274 32.5059)" fill="white"/>
</svg>
</div>
</div>
<div class="admin_page">
<div class="admin_state_item">
<span>Start Time:</span>
<a-range-picker
style="width:280px"
class="range_picker"
v-model:value="rangePickerValue"
:allowClear="false"
:placeholder="[
$t('HistoryPage.StartDate'),
$t('HistoryPage.EndDate'),
]"
valueFormat="YYYY-MM-DD"
>
<template #suffixIcon>
<span
class="icon iconfont range_picker_icon icon-rili"
></span>
</template>
</a-range-picker>
<div class="gallery_btn" @click="getDetailList" style="margin-left: 2rem;">Search</div>
</div>
<div class="itemAffiliateDetail_content generalModel_table_content" ref="historyTable">
<a-table
:columns="columns"
:data-source="collectionList"
:scroll="{ y: 200 }"
@change="changePage"
:pagination="{
showSizeChanger: true,
current: currentPage,
pageSize: pageSize,
total: total,
showQuickJumper: true,
bordered: false,
}"
>
</a-table>
</div>
</div>
</a-modal>
<div class="mark_loading" v-show="loadingShow">
<a-spin size="large" />
</div>
</template>
<script lang="ts">
import { defineComponent, ref, createVNode, computed, reactive, toRefs, nextTick } from "vue";
import { Https } from "@/tool/https";
import { Modal, message } from "ant-design-vue";
export default defineComponent({
components: {
},
setup() {
let renameData: any = ref({}); //修改名字选中的数据
const itemAffiliateDom = reactive({
historyTable:null as any,
})
const itemAffiliateDetail = reactive({
itemAffiliateDetailShow:false,
loadingShow:false,
rangePickerValue:[] as any,
itemId:-1,
collectionList:[],
currentPage: 1,
pageSize: 10,
order:'',
total: 0,
historyTableHeight:0,
columns:computed(() => {
return [
{
title: 'Id',
align: "center",
width: 50,
dataIndex: "accountId",
key: "accountId",
fixed: "left",
},{
title: 'User Name',
key: "username",
dataIndex: "username",
align: "center",
width: 150,
},
{
title: 'Time',
align: "center",
width: 200,
dataIndex: "time",
key: "time",
sorter: true,
},{
title: 'First Subscription Payment Amount',
align: "center",
width: 200,
dataIndex: "firstSubscriptionPaymentAmount",
key: "firstSubscriptionPaymentAmount",
},{
title: 'Commission',
align: "center",
ellipsis: true,
width: 150,
dataIndex: "commission",
key: "commission",
fixed: "right",
}
];
})
})
const init = (value:any)=>{
itemAffiliateDetail.itemAffiliateDetailShow = true
getCurrentMonthStart(value.type)
nextTick(()=>{
itemAffiliateDetail.historyTableHeight = itemAffiliateDom.historyTable.clientHeight - 40;
itemAffiliateDetail.itemId = value.id
getDetailList()
})
}
const cancelDsign = () =>{
itemAffiliateDetail.itemAffiliateDetailShow = false
itemAffiliateDetail.loadingShow = false
}
const getCurrentMonthStart = (type:any) => {
const now = new Date(); // 获取当前日期
const year = now.getFullYear(); // 获取当前年份
const month = now.getMonth(); // 获取当前月份0 - 11
let startOfPeriod:any, endOfPeriod:any;
if (type === 'month') {
startOfPeriod = new Date(year, month, 1);
endOfPeriod = new Date(year, month + 1, 0); // 下个月的第0天即为当前月的最后一天
startOfPeriod.setHours(0, 0, 0, 0);
endOfPeriod.setHours(23, 59, 59, 999); // 设置为最后一天的23:59:59.999
} else if (type === 'year') {
startOfPeriod = new Date(year, 0, 1);
endOfPeriod = new Date(year, 11, 31);
}
const formatDate = (date:any) => {
return date.getFullYear() + '-' +
String(date.getMonth() + 1).padStart(2, '0') + '-' +
String(date.getDate()).padStart(2, '0') + ' ' +
String(date.getHours()).padStart(2, '0') + ':' +
String(date.getMinutes()).padStart(2, '0') + ':' +
String(date.getSeconds()).padStart(2, '0');
};
if (type === 'month')itemAffiliateDetail.rangePickerValue = [formatDate(startOfPeriod),formatDate(endOfPeriod)]
}
const changePage = (e: any, filters:any, sorter:any)=>{
itemAffiliateDetail.currentPage = e.current;
itemAffiliateDetail.pageSize = e.pageSize;
itemAffiliateDetail.order = sorter.order == "descend" ? "DESC" : "ASC";
getDetailList();
}
const getDetailList = ()=>{
itemAffiliateDetail.loadingShow = true
let startDate: any = itemAffiliateDetail.rangePickerValue?.[0]
? itemAffiliateDetail.rangePickerValue[0]+' '+'00:00:00'
: "";
let endDate: any = itemAffiliateDetail.rangePickerValue?.[1]
? itemAffiliateDetail.rangePickerValue[1]+' '+'23:59:59'
: "";
let data = {
affiliateId:itemAffiliateDetail.itemId,
endTime:endDate,
startTime:startDate,
order:itemAffiliateDetail.order,
page: itemAffiliateDetail.currentPage,
size: itemAffiliateDetail.pageSize,
}
Https.axiosPost(Https.httpUrls.getEachAffiliateGeneratedRevenue,data).then((rv:any)=>{
console.log(rv);
itemAffiliateDetail.collectionList = rv.records
itemAffiliateDetail.loadingShow = false
itemAffiliateDetail.total=rv.total
}).catch((err:any)=>{
itemAffiliateDetail.loadingShow = false
})
}
return {
...toRefs(itemAffiliateDom),
...toRefs(itemAffiliateDetail),
init,
cancelDsign,
changePage,
getDetailList,
};
},
});
</script>
<style lang="less" scoped>
.itemAffiliateDetail{
.itemAffiliateDetail_content{
margin-top: 2rem;
}
.admin_page .admin_table_content .operate_list{
justify-content: space-between;
}
}
</style>

View File

@@ -415,7 +415,7 @@ export default defineComponent({
? filterData.rangePickerValue[0] + " " + "00:00:00"
: "";
let endDate: any = filterData.rangePickerValue?.[1]
? filterData.rangePickerValue[1] + " " + "00:00:00"
? filterData.rangePickerValue[1] + " " + "23:59:59"
: "";
let data = {
endTime: endDate,

View File

@@ -1,19 +1,26 @@
<template>
<div class="allUserPoerationModal" ref="allUserPoerationModal"></div>
<a-modal
class="allUserPoeration_modal generalModel"
v-model:visible="operationsModal"
:footer="null"
:get-container="() => $refs.allUserPoerationModal"
width="50%"
:maskClosable="false"
:centered="true"
:closable="false"
:mask="false"
:mask="true"
wrapClassName="#app"
:keyboard="false"
>
<div class="generalModel_btn">
<div class="generalModel_closeIcon" @click.stop="cancelDsign()">
<i class="fi fi-rr-cross-small"></i>
<svg width="46" height="46" viewBox="0 0 46 46" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="23" cy="23" r="23" fill="white" fill-opacity="0.3"/>
<rect x="32.5063" y="12" width="3" height="29" rx="1.5" transform="rotate(45 32.5063 12)" fill="white"/>
<rect x="34.6274" y="32.5059" width="3" height="29" rx="1.5" transform="rotate(135 34.6274 32.5059)" fill="white"/>
</svg>
</div>
</div>
<div class="modal_title_text">
@@ -114,18 +121,11 @@
<script>
import { defineComponent, ref, reactive, watch, onMounted, nextTick, toRefs } from "vue";
import { Https } from "@/tool/https";
import { setCookie, getCookie } from "@/tool/cookie";
import { Modal, message } from "ant-design-vue";
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";
import { formatTime } from "@/tool/util";
import allOrder from "@/component/Pay/allOrder.vue";
import creditsDetail from "@/component/Pay/creditsDetail.vue";
import { exportSele,JSRectUpdata,JSchangeType,JScanvasMouseDown,JSSetRemoveImage,JScreateCheck,JSSetTexture } from "@/tool/canvasDrawing";
import { useI18n } from "vue-i18n";
export default defineComponent({
components: {
creditsDetail,
allOrder,
},
emits: ['searchHistoryList'],
setup(props,{emit}) {
@@ -277,7 +277,7 @@ export default defineComponent({
},
});
</script>
<style lang="less">
<style lang="less" scoped>
.allUserPoeration_modal{
.ant-modal-body{
height: auto;

View File

@@ -1,5 +1,5 @@
<template>
<div class="admin_page">
<div class="admin_page" ref="adminPage">
<div class="admin_table_search">
<div class="admin_state">
<div class="admin_state_item">
@@ -34,18 +34,26 @@
</a-table>
</div>
<a-modal
class="generalModelOperate"
class="generalModel"
v-model:visible="isFeedbackShow"
:footer="null"
:get-container="() => $refs.adminPage"
width="55%"
:maskClosable="false"
:centered="true"
:keyboard="false"
:closable="false"
:mask="false"
:mask="true"
>
<div class="generalModelOperate_closeIcon" @click.stop="closeModal()">
<i class="fi fi-rr-cross-small"></i>
<div class="generalModel_btn">
<div class="generalModel_closeIcon" @click.stop="closeModal()">
<svg width="46" height="46" viewBox="0 0 46 46" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="23" cy="23" r="23" fill="white" fill-opacity="0.3"/>
<rect x="32.5063" y="12" width="3" height="29" rx="1.5" transform="rotate(45 32.5063 12)" fill="white"/>
<rect x="34.6274" y="32.5059" width="3" height="29" rx="1.5" transform="rotate(135 34.6274 32.5059)" fill="white"/>
</svg>
</div>
</div>
<feedbackSurveyVue ref="feedbackSurveyVue"></feedbackSurveyVue>
</a-modal>
@@ -184,7 +192,7 @@ export default defineComponent({
methods: {},
});
</script>
<style lang="less">
<style lang="less" scoped>
.generalModelOperate{
// .ant-modal-body{
// height: calc(65rem*1.2);

View File

@@ -88,7 +88,7 @@ export default defineComponent({
? filterData.rangePickerValue[0]+' '+'00:00:00'
: "";
let endDate: any = filterData.rangePickerValue?.[1]
? filterData.rangePickerValue[1]+' '+'00:00:00'
? filterData.rangePickerValue[1]+' '+'23:59:59'
: "";
let data = {
endTime:endDate,

View File

@@ -259,7 +259,7 @@ export default defineComponent({
? filterData.rangePickerValue[0]+' '+'00:00:00'
: "";
let endDate: any = filterData.rangePickerValue?.[1]
? filterData.rangePickerValue[1]+' '+'00:00:00'
? filterData.rangePickerValue[1]+' '+'23:59:59'
: "";
let data = {
endTime:endDate,

View File

@@ -71,7 +71,7 @@ export default defineComponent({
? filterData.rangePickerValue[0]+' '+'00:00:00'
: "";
let endDate: any = filterData.rangePickerValue?.[1]
? filterData.rangePickerValue[1]+' '+'00:00:00'
? filterData.rangePickerValue[1]+' '+'23:59:59'
: "";
let data = {
endTime:endDate,

View File

@@ -285,7 +285,7 @@ export default defineComponent({
? filterData.rangePickerValue[0]+' '+'00:00:00'
: "";
let endDate: any = filterData.rangePickerValue?.[1]
? filterData.rangePickerValue[1]+' '+'00:00:00'
? filterData.rangePickerValue[1]+' '+'23:59:59'
: "";
let data = {
endTime:endDate,

View File

@@ -97,7 +97,7 @@ export default defineComponent({
? filterData.rangePickerValue[0]+' '+'00:00:00'
: "";
let endDate: any = filterData.rangePickerValue?.[1]
? filterData.rangePickerValue[1]+' '+'00:00:00'
? filterData.rangePickerValue[1]+' '+'23:59:59'
: "";
let data = {
endTime:endDate,

View File

@@ -218,7 +218,7 @@ export default defineComponent({
? filterData.rangePickerValue[0]+' '+'00:00:00'
: "";
let endDate: any = filterData.rangePickerValue?.[1]
? filterData.rangePickerValue[1]+' '+'00:00:00'
? filterData.rangePickerValue[1]+' '+'23:59:59'
: "";
let data = {
endTime:endDate,

View File

@@ -41,7 +41,7 @@
<div
v-show="status == 0"
class="operate_item"
@click="setAagree(record, index)"
@click="setAgree(record, index)"
>
agree
</div>
@@ -67,7 +67,6 @@
</template>
<script lang="ts">
import { defineComponent, ref, createVNode, computed } from "vue";
import { setCookie, getCookie, WriteCookie } from "@/tool/cookie";
import { Https } from "@/tool/https";
import { Modal, message } from "ant-design-vue";
export default defineComponent({
@@ -184,14 +183,12 @@ export default defineComponent({
},
])
let collectionList: any = ref([]);
let userInfo: any = {};
let status: any = ref(0);
let voluntarily: any = ref(false);
return {
columns,
collectionList,
renameData,
userInfo,
status,
currentState,
state,
@@ -214,8 +211,6 @@ export default defineComponent({
let historyTable: any = this.$refs.historyTable;
this.historyTableHeight = historyTable.clientHeight - 200;
this.gettrialList();
let userInfo:any = getCookie("userInfo")
this.userInfo = JSON.parse(userInfo);
this.getIsAutoApproval()
},
methods: {

View File

@@ -88,7 +88,7 @@ export default defineComponent({
? filterData.rangePickerValue[0]+' '+'00:00:00'
: "";
let endDate: any = filterData.rangePickerValue?.[1]
? filterData.rangePickerValue[1]+' '+'00:00:00'
? filterData.rangePickerValue[1]+' '+'23:59:59'
: "";
let data = {
endTime:endDate,

View File

@@ -106,7 +106,7 @@ export default defineComponent({
? filterData.rangePickerValue[0]+' '+'00:00:00'
: "";
let endDate: any = filterData.rangePickerValue?.[1]
? filterData.rangePickerValue[1]+' '+'00:00:00'
? filterData.rangePickerValue[1]+' '+'23:59:59'
: "";
let data = {
endTime:endDate,

View File

@@ -0,0 +1,197 @@
<template>
<div class="canvasArgument">
<div class="label_item wH">
<div class="title">{{ $t('exportModel.Width') }}</div>
<input type="number" @input="canvasGeneral.setCanvasWH('width')" v-model="canvasGeneral.canvasWH.width">
</div>
<div class="label_item wH">
<div class="title">{{ $t('exportModel.Height') }}</div>
<input type="number" @input="canvasGeneral.setCanvasWH('height')" v-model="canvasGeneral.canvasWH.height">
</div>
<div class="label_item" v-show="
canvasGeneral.operation != 'movePosition' &&
canvasGeneral.operation != 'move' &&
canvasGeneral.operation != 'eraser' &&
canvasGeneral.operation != 'texture' &&
canvasGeneral.operation != 'zoomIn' &&
canvasGeneral.operation != 'zoomOut' &&
canvasGeneral.operation != 'dashedPencil' &&
canvasGeneral.operation != 'dashed'">
<div class="title">{{ $t('exportModel.Color') }}</div>
<input type="color" @input="canvasGeneral.setPencilColor" v-model="canvasGeneral.brushwork.color">
<span class="icon iconfont icon-xiala" @click.stop="setOperation('color')" :class="{active: operation == 'color'}"></span>
<div class="labelHover_show" v-show="operation == 'color'" @click.stop="">
<div v-for="item in canvasGeneral.colorHistoryList" :style="{'background':item}" @click="canvasGeneral.setColorHistory(item)"></div>
</div>
</div>
<div class="label_item" v-show="
canvasGeneral.operation != 'movePosition' &&
canvasGeneral.operation != 'move' &&
canvasGeneral.brushwork.value != 'RibbonBrush' &&
canvasGeneral.brushwork.value != 'LongfurBrush'&&
canvasGeneral.operation != 'zoomIn' &&
canvasGeneral.operation != 'zoomOut' &&
canvasGeneral.operation != 'dashedPencil' &&
canvasGeneral.operation != 'dashed'">
<div >{{ $t('exportModel.Size') }}:</div>
<input @change="canvasGeneral.setFontFamily" type="range" @input="canvasGeneral.setPencilWidth" min="3" max="50" v-model="canvasGeneral.brushwork.width[canvasGeneral.operation]">
</div>
<div class="label_item" v-show="canvasGeneral.operation == 'pencil'">
<div >{{ $t('exportModel.Brushwork') }}:</div>
<a-select ref="select" class="label_select" size="small" v-model:value="canvasGeneral.brushwork.value"
style="width: 12rem "
@change="canvasGeneral.brushworkChange"
>
<a-select-option class="label_select_item" v-for="item in canvasGeneral.pencilList.brushList" :value="item.value">
<img style="width: 100%;" :src="item.url" alt="">
</a-select-option>
</a-select>
</div>
<div class="label_item texture" v-show="canvasGeneral.operation == 'texture'">
<div >{{ $t('exportModel.Texture') }}:</div>
<a-select ref="select" class="label_select" size="small" v-model:value="canvasGeneral.texture.value"
style="width: 12rem "
@change="canvasGeneral.textureValueChange"
>
<a-select-option class="label_select_item" v-for="item in canvasGeneral.texture.list" :value="item.value">
<img :src="item.url" alt="">
</a-select-option>
</a-select>
</div>
<div class="label_item" v-show="
canvasGeneral.operation != 'pencil' &&
canvasGeneral.operation != 'eraser'&&
canvasGeneral.operation != 'movePosition' &&
canvasGeneral.operation != 'move'&&
canvasGeneral.operation != 'text'&&
canvasGeneral.operation != 'texture'&&
canvasGeneral.operation != ''&&
canvasGeneral.operation != 'zoomIn' &&
canvasGeneral.operation != 'zoomOut' &&
canvasGeneral.operation != 'dashedPencil' &&
canvasGeneral.operation != 'dashed'">
<div >{{ $t('exportModel.FillBack') }}:</div>
<div class="leftAlign">
<i class="icon iconfont icon-tuceng1" @click="canvasGeneral.setOperationMode('fill')" :class="{active:canvasGeneral.operationMode == 'fill'}"></i>
<i class="icon iconfont icon-tuceng" @click="canvasGeneral.setOperationMode('border')" :class="{active:canvasGeneral.operationMode == 'border'}"></i>
</div>
</div>
<!-- <div class="label_item" v-show="canvasGeneral.operation == 'movePosition'">
<div >{{ $t('exportModel.Layer') }}:</div>
<div class="leftAlign">
<i class="icon iconfont icon-shangyiceng" @click="canvasGeneral.setLayerIndex('Front')"></i>
<i class="icon iconfont icon-shangyiceng2" @click="canvasGeneral.setLayerIndex('Forward')"></i>
<i class="icon iconfont icon-xiayiceng" @click="canvasGeneral.setLayerIndex('Backwards')"></i>
<i class="icon iconfont icon-shangyiceng1" @click="canvasGeneral.setLayerIndex('Back')"></i>
</div>
</div> -->
<div class="label_item" v-show="(canvasGeneral.operation == '' || canvasGeneral.operation == 'text' || canvasGeneral.createPatterning.textDataShow) && canvasGeneral.operation != 'movePosition' && canvasGeneral.operation != 'move'">
<div>Font Family</div>
<a-select ref="select" class="label_select" size="small" v-model:value="canvasGeneral.fontFamily"
style="flex: 1;width: 15rem;"
@change="canvasGeneral.setFontFamily"
:style="{'font-family':canvasGeneral.fontFamily}"
>
<a-select-option class="label_select_item" v-for="item in canvasGeneral.pencilList.textFontFamilyList" :style="{'font-family':item.value}" :value="item.value">
{{item.name}}
</a-select-option>
</a-select>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,ref,reactive,nextTick,toRefs,inject} from 'vue'
export default defineComponent({
components:{},
setup(){
let testModal = ref(true)
let canvasGeneral:any = inject('canvasObj')
const data = reactive({
colorHistoryList:[],
operation:'',
})
const setOperation = (str:any)=>{
data.operation = str
}
const setOper = ()=>{
setOperation('')
}
document.addEventListener('click',setOper)
const closeModal = ()=>{
document.removeEventListener('click',setOper)
}
return {
canvasGeneral,
...toRefs(data),
testModal,
setOperation,
closeModal,
}
}
});
</script>
<style lang='less' scoped>
.canvasArgument{
display: flex;
flex-wrap: wrap;
height: 100%;
.label_item{
margin-right: 2rem;
position: relative;
display: flex;
align-items: center;
.leftAlign{
display: flex;
}
.labelHover_show{
position: absolute;
width: 100%;
height: 10rem;
top: 100%;
z-index: 2;
display: block;
border-radius: 4px;
border: 1px solid;
padding: .5rem 1rem;
background: #fff;
div{
width: 2rem;
height: 2rem;
margin-right: .5rem;
margin-bottom: .5rem;
display: inline-block;
cursor: pointer;
}
}
input{
height: 100%;
}
&.wH input{
width: 5rem;
}
.title{
margin-right: 1rem;
}
.icon-xiala{
cursor: pointer;
transform: rotate(0deg);
height: 4rem;
width: 4rem;
transition: all .3s;
line-height: 4rem;
text-align: center;
&.active{
transform: rotate(180deg);
}
}
}
.label_item:hover{
// .labelHover_show{
// display: flex;
// }
}
}
</style>

View File

@@ -0,0 +1,184 @@
<template>
<div class="canvasContent_box">
<div class="canvasContent" ref="canvasScaleDom">
<div v-if="isPresuppose" class="generalCanvas_center presuppose">
<div class="presuppose16-9" @click="setPresuppose('16/9')">16 : 9</div>
<div class="presuppose1-1" @click="setPresuppose('1/1')">1 : 1</div>
<div class="presuppose9-16" @click="setPresuppose('9/16')">9 : 16</div>
</div>
<div v-else class="generalCanvas_center canvas" ref="canvasDom">
<div class="editFrontBack_pencilbtn" v-show="!isShowMark" :style="canvasGeneral.pencilbtnStyle"></div>
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,ref,reactive,nextTick,toRefs,inject,createVNode, onMounted} from 'vue'
import { Modal,message } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { useI18n } from 'vue-i18n'
export default defineComponent({
component:{},
setup(){
let {t} = useI18n()
let canvasType = inject('canvasType')
let canvasGeneral:any = inject('canvasObj')
const data:any = reactive({
canvasScaleDom:null,
canvasDom:null,
isPresuppose:false,
isShowMark:false,
pencilbtnStyle:{},
})
const createCanvas = (canvasSize:any)=>{
data.isPresuppose = false
nextTick(()=>{
canvasGeneral.canvasInit(data.canvasDom,canvasSize)
console.log(canvasGeneral);
})
}
const openMode = (data:any)=>{
let {yes,no} = data
console.log(yes,no);
Modal.confirm({
title: '是否栅格化',
icon: createVNode(ExclamationCircleOutlined),
okText: 'Yes',
cancelText: 'No',
mask:false,
centered:true,
onOk() {
yes()
},
onCancel(){
no()
}
});
yes()
}
// canvasGeneral.openMode.fun = openMode
const setPresuppose = (presuppose:any)=>{
let canvasDomSize = {
width:data.canvasScaleDom.offsetWidth,
height:data.canvasScaleDom.offsetHeight,
}
let width,height
let scale = [0,0]
if(presuppose == '16/9'){
// scale[0] = 16
// scale[1] = 9
width = 1600
height = 900
}else if(presuppose == '1/1'){
// scale[0] = 1
// scale[1] = 1
width = 1000
height = 1000
}else if(presuppose == '9/16'){
// scale[0] = 9
// scale[1] = 16
width = 900
height = 1600
}
// let mbHeight = canvasDomSize.width / scale[0] * scale[1]
// if(mbHeight < canvasDomSize.height){
// width = canvasDomSize.width
// height = mbHeight
// }else{
// width = canvasDomSize.height / scale[1] * scale[0]
// height = canvasDomSize.height
// }
let canvasSize = {width,height}
createCanvas(canvasSize)
}
onMounted(()=>{
if(canvasType == 'export'){
data.isPresuppose = true
}else{
createCanvas({})
}
})
return {
canvasGeneral,
...toRefs(data),
setPresuppose,
}
}
});
</script>
<style lang='less' scoped>
.canvasContent_box{
height: 100%;
width: 100%;
// padding: 2rem;
background: #e6e6e6;
.canvasContent{
height: 100%;
width: 100%;
position: relative;
}
}
.generalCanvas_center{
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
&.canvas{
}
&.presuppose{
display: flex;
align-items: center;
justify-content: center;
> div{
border: 1rem solid #6b6b6b;
color: #6b6b6b;
display: flex;
margin-right: 2rem;
display: flex;
align-items: center;
justify-content: center;
font-size: 3rem;
font-weight: 900;
cursor: pointer;
border-radius: 4px;
&:last-child{
margin-right: 0;
}
&.presuppose16-9{
height: calc(30rem / 16 * 9);
width: 30rem;
}
&.presuppose1-1{
height: 30rem;
width: 30rem;
}
&.presuppose9-16{
height: 30rem;
width: calc(30rem / 16 * 9);
}
}
}
.editFrontBack_pencilbtn{
position: absolute;
z-index: 1;
border-radius: 50%;
border: 1px solid #000;
pointer-events: none;
transform: translate(-50%,-50%);
}
:deep(.canvas-container){
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
// background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC);
}
}
</style>

View File

@@ -0,0 +1,305 @@
<template>
<div class="detail" ref="detailDom"
@mousemove="mousemove($event)"
@touchmove="touchmove($event)"
>
<div class="layer">
<div class="layer-item button" @click="canvasGeneral.createLayer">
新建图层
</div>
<div class="layer-item-box-scroll">
<div class="layer-item-box" :style="{'height':layerList.length * 6 + 'rem'}">
<div class="layer-item"
v-for="item,index in layerList"
:key="item"
:style="item?.style"
@click="canvasGeneral.selectLayer(item.id)"
@mousedown="mousedown($event,item,index)"
@touchstart="touchstart($event,item,index)"
@contextmenu="openMenu($event,item,index)"
:class="{'active':item.id == canvasGeneral.layer.selectLayer.id}">
<!-- <div @click.stop="canvasGeneral.layerShowHide(item.id,item)">{{ item.isShow }}</div> -->
<i class="fi" :class="[(item.isShow)?'fi-rr-eye':'fi-rr-eye-crossed']" @click.stop="canvasGeneral.layerShowHide(item.id,item)"></i>
<img :src="item.img" alt="">
<div>
{{ item.name }}
</div>
<div @click.stop="canvasGeneral.layerDelete(index,item.id)" :class="{noDelete:canvasGeneral.layer.list.length == 1}">删除</div>
</div>
</div>
</div>
</div>
<div class="layer-menu" :style="styleMenu">
<div class="layer-menu-item" @click="canvasGeneral.copyLayer(itemMenu.id)">复制</div>
<div class="layer-menu-item" @click="canvasGeneral.layerDelete(itemMenu.index,itemMenu.id)">删除</div>
<div class="layer-menu-item" v-if="itemMenu.groupType == 'Object'" @click="canvasGeneral.setGridOrObject(itemMenu.id,'Grid')">设置栅格化</div>
<div class="layer-menu-item" v-if="itemMenu.groupType == 'Grid'" @click="canvasGeneral.setGridOrObject(itemMenu.id,'Object')">取消栅格化</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,ref,reactive,nextTick,toRefs,inject,watch,computed} from 'vue'
import { getMousePosition } from "@/tool/mdEvent";
export default defineComponent({
component:{},
setup(){
let canvasGeneral:any = inject('canvasObj')
const data = reactive({
detailDom:null as any,
layerList:computed(()=>canvasGeneral.layer.list) as any,
styleMenu:{
left:0+'px',
top:0+'px',
display:'none',
},
itemMenu:{} as any,
})
watch(()=>canvasGeneral.layer.list.length, (newValue, oldValue) => {
let sortedArr = data.layerList.map((item:any) => ({ ...item })).sort((a:any, b:any) => b.index - a.index)
sortedArr.forEach((item:any,index:any)=>{
item.index = sortedArr.length - index
})
data.layerList.forEach((item:any) => {
//图层高度50px 下边距10px
sortedArr.forEach((sortedArrItem:any)=>{
if(item.id == sortedArrItem.id){
item.index = sortedArrItem.index
}
let style = {
top:(data.layerList.length - item.index) * 60 + 'px',
transition:'all .3s',
}
item.style = style
})
});
},{immediate:true});
const incident:any = reactive({
isDown:false,
selectStyleTop:null,
selectStyle:null,
downPoint:null,
select:null,
radius:25,
})
const openMenu = (event:any,item:any,index:number)=>{
if(event.preventDefault)event.preventDefault();
data.itemMenu = item;
data.itemMenu.index = index
let position = data.detailDom.getBoundingClientRect();
data.styleMenu = {
left:event.clientX - position.left+'px',
top:event.clientY - position.top+'px',
display:'block',
}
}
document.onclick = ()=>{
data.styleMenu.display = 'none'
data.itemMenu = {};
}
let mousedown = (event:any,item:any,index:number)=>{
if(event.button != 0)return
let e:any = getMousePosition(event,false)
mouseDownOperation(e,item,index)
}
let ipadDownTime:any = null
let touchstart = (event:any,item:any,index:number)=>{
let e:any = getMousePosition(event,true)
mouseDownOperation(e,item,index)
clearTimeout(ipadDownTime)
ipadDownTime = setTimeout(()=>{
openMenu(e,item,index)
},1000)
}
let mouseDownOperation = (e:any,item:any,index:number)=>{
incident.isDown = true
incident.selectStyleTop = item.style.top
incident.selectStyle = item.style
incident.selectStyle.transition = 'none'
incident.select = item
incident.downPoint = e.clientY
}
let mousemove = (event:any)=>{
let e:any = getMousePosition(event,false)
mouseMoveOperation(e)
}
let touchmove = (event:any)=>{
let e:any = getMousePosition(event,true)
clearTimeout(ipadDownTime)
if(data.styleMenu.display != 'none')data.styleMenu.display = 'none'
mouseMoveOperation(e)
}
let mouseMoveOperation = (e:any)=>{
if(incident.isDown){
let domTop = Number(incident.selectStyleTop.split('px')[0])
let gTop = domTop + (e.clientY - incident.downPoint)
if(gTop < 0){
gTop = 0
}
incident.select.style.top = gTop + 'px'
data.layerList.forEach((item:any,index:number) => {
let itemTop = Number(item.style.top.split('px')[0])
if(Math.abs(gTop - itemTop) < 30 && item.id != incident.select.id){
let itemIndex = item.index
// if(gTop - itemTop > 0){
// console.log('从下往上');
// }
// if(gTop - itemTop < 0){
// console.log('从上往下');
// }
item.index = incident.select.index
incident.select.index = itemIndex
}
})
sort(data.layerList,'move')
}
}
const mouseUp = ()=>{
if(data.styleMenu.display == 'none')clearTimeout(ipadDownTime)
if(incident.isDown){
if(incident.selectStyle)incident.selectStyle.transition = 'all .3s'
incident.selectStyleTop = null
incident.isDown = false
incident.selectStyle = null
incident.select = null
sort(data.layerList,'up')
}
}
document.onmouseup = mouseUp
document.ontouchend = mouseUp
//排序
let time:any = null
let sort = (list:any,str:string)=>{
clearTimeout(time)
// list = list.sort((a:any, b:any) =>{
// return b.index - a.index;
// });
list.forEach((item:any) => {
if(str == 'move'){
if(item.id != incident.select.id)item.style.top = (list.length - item.index) * 60 + 'px'
}else{
item.style.top = (list.length - item.index) * 60 + 'px'
}
});
if(str == 'up')time = setTimeout(()=>canvasGeneral.upLayerIndex(list),500)
}
return {
canvasGeneral,
...toRefs(data),
openMenu,
mousedown,
touchstart,
mousemove,
touchmove,
}
}
});
</script>
<style lang='less' scoped>
.detail{
width: 100%;
height: 100%;
padding: 1rem;
border: 1px solid #dcdfe6;
position: relative;
* {
-webkit-user-drag: none;
-moz-user-drag: none;
-ms-user-drag: none;
user-drag: none;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
}
.layer{
display: flex;
flex-direction: column;
height: 100%;
.layer-button{
}
.layer-item{
display: flex;
justify-content: space-between;
align-items: center;
padding: .5rem 2rem;
border: 1px solid #e6e6e6;
margin-bottom: 10px;
height: 50px;
border-radius: 4px;
i{
font-size: 18px;
}
&.active{
background: #e6e6e6;
}
.noDelete{
background: #e6e6e6;
opacity: .4;
pointer-events: none;
}
&.button{
justify-content: center;
cursor: pointer;
}
img{
height: 100%;
width: 35px;
object-fit: contain;
}
div{
cursor: pointer;
}
&:last-child{
margin-bottom: 0;
}
}
.layer-item-box-scroll{
flex: 1;
overflow-y: auto;
.layer-item-box{
position: relative;
.layer-item{
position: absolute;
width: 100%;
}
}
}
}
.layer-menu{
position: absolute;
width: 60%;
line-height: 4rem;
background: #fff;
border-radius: 4px;
border: 1px solid;
overflow: hidden;
>div{
border-bottom: 1px solid;
padding: 0 2rem;
cursor: pointer;
}
>div:hover{
background: #e6e6e6;
}
>div:last-child{
border-bottom: none;
}
}
}
</style>

View File

@@ -0,0 +1,187 @@
<template>
<div class="generalCanvas">
<div class="argument-box">
<argument ref="argument" v-if="canvasObj.canvas"></argument>
</div>
<div class="canvasBox">
<tool ref="tool" v-if="canvasObj.canvas" @toolLiquefaction="toolLiquefaction"></tool>
<div class="canvas">
<canvasContent ref="canvasContent"></canvasContent>
</div>
<div class="detail-box">
<detail ref="detail" v-if="canvasObj.canvas"></detail>
</div>
</div>
<div class="mark_loading" v-show="isShowMark">
<a-spin size="large" />
</div>
</div>
<liquefaction ref="liquefaction" @submitLiquefaction="submitLiquefaction"></liquefaction>
</template>
<script>
import {defineComponent, computed, provide, h, ref, nextTick, onBeforeUnmount, reactive, onMounted,
} from "vue";
import {message} from 'ant-design-vue'
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { useI18n } from "vue-i18n";
import canvasGeneral from "@/tool/canvasGeneralCopy";
import tool from "./tool.vue"
import argument from "./argument.vue"
import detail from "./detail.vue"
import canvasContent from "./canvasContent.vue"
import liquefaction from "@/component/modules/liquefaction.vue";
export default defineComponent({
components: {
tool,
argument,
detail,
canvasContent,
liquefaction,
},
setup(props,{emit}) {
const { t } = useI18n();
const store = useStore();
const isShowMark = ref(false)
const component = reactive({
argument:ref(null),tool:ref(null),detail:ref(null),canvasContent:ref(null)
})
let liquefaction = ref(null)
let liquefactionData = ref()
let groupDashed = ref(null)//用来判断是否需要对group添加img
let canvasType = 'export'
let canvasObj = reactive(canvasGeneral)
provide('canvasType',canvasType)
provide('canvasObj',canvasObj)
provide('isShowMark',isShowMark)
const close = ()=>{
component.forEach((item)=>{
if(item.value.closeModal)item.value.closeModal()
})
}
let expoet = ()=>{
console.log( canvasObj.selectExport());
console.log( canvasObj.allExport());
}
const setLiquefaction = async ()=>{//进入液化页面
canvasObj.getLiquefactionImgObj().then((data)=>{
if(data?.img){
liquefactionData.value = data
liquefaction.value.init(data.img)
}else {
message.info(t('exportModel.jsContent6'))
return null;
}
})
}
const toolLiquefaction = ()=>{//工具点击按钮
setLiquefaction()
}
const submitLiquefaction = (rv)=>{//液化回参
canvasObj.setLiquefactionImgObj(liquefactionData.value,rv)
// liquefactionData.value.setSrc(rv, (value)=>{
// // liquefactionData.value.scaleToWidth(originalWidth);
// // liquefactionData.value.scaleToHeight(originalHeight);
// delete liquefactionData.value.minioUrl
// if(groupDashed.value && groupDashed.value._objects.length == 1){
// value.set({
// left:-groupDashed.value.width/2,
// top:-groupDashed.value.height/2,
// })
// groupDashed.value.insertAt(value)
// // canvasObj.addDashedImg(value)
// }
// canvasObj.canvas.renderAll();
// canvasObj.updateCanvasState()
// });
}
onMounted(() => {
});
onBeforeUnmount(()=>{
// canvasGeneral.canvasClear()
})
return {
isShowMark,
liquefaction,
canvasObj,
close,
expoet,
toolLiquefaction,
submitLiquefaction,
};
},
data(prop) {
return {
};
},
computed: {
},
watch: {
},
mounted() {},
methods: {
},
});
</script>
<style lang="less" scoped>
.generalCanvas{
width: 100%;
height: 100%;
position: relative;
display: flex;
flex-direction: column;
overflow: hidden;
.argument-box,
.canvasBox,
.detail-box{
:deep(i){
font-size: 2.5rem;
cursor: pointer;
width: 3rem;
height: 3rem;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
transition: all .3s;
margin-bottom: .5rem;
&.active{
border: 1px solid;
border-radius: .4rem;
}
&.icon-xiala{
transform: rotate(-90deg);
}
&.icon-xialaActive{
transform: rotate(90deg);
}
}
}
.argument-box{
margin-left: 4rem;
height: 4rem;
margin-bottom: 1rem;
}
.canvasBox{
flex: 1;
overflow: hidden;
display: flex;
.canvas{
flex: 1;
overflow: hidden;
}
}
.detail-box{
width: 20%;
margin-left: 1rem;
}
}
</style>

View File

@@ -0,0 +1,54 @@
<template>
<div ref="modalTest"></div>
<a-modal class="modal_test generalModel"
v-model:visible="testModal"
:footer="null"
:get-container="() => $refs.modalTest"
width="78%"
:maskClosable="false"
:centered="true"
:closable="false"
wrapClassName="#app"
:keyboard="false"
>
<div class="generalModel_btn">
<div class="generalModel_closeIcon" @click.stop="cancelDsign()">
<svg width="46" height="46" viewBox="0 0 46 46" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="23" cy="23" r="23" fill="white" fill-opacity="0.3"/>
<rect x="32.5063" y="12" width="3" height="29" rx="1.5" transform="rotate(45 32.5063 12)" fill="white"/>
<rect x="34.6274" y="32.5059" width="3" height="29" rx="1.5" transform="rotate(135 34.6274 32.5059)" fill="white"/>
</svg>
</div>
</div>
<canvasIndex></canvasIndex>
</a-modal>
</template>
<script lang="ts">
import { defineComponent,ref,createVNode,nextTick} from 'vue'
import canvasIndex from './index.vue'
export default defineComponent({
components:{canvasIndex},
setup(){
let testModal = ref(true)
const init = ()=>{
testModal.value = true
}
const cancelDsign = ()=>{
testModal.value = false
}
return {
testModal,
init,
cancelDsign,
}
}
});
</script>
<style lang='less' scoped>
.box {
border: 1px solid #f00;
}
</style>

View File

@@ -0,0 +1,168 @@
<template>
<div class="canvasTool">
<i class="icon iconfont icon-chehui" @click="historyState('')"></i>
<i class="icon iconfont icon-fanchehui" @click="historyState('reverse')"></i>
<i class="icon iconfont icon-bianji" @click="setOperation('pencil')" :class="{active:canvasGeneral.operation == 'pencil'}"></i>
<i class="icon iconfont icon-caizhi" @click="setOperation('texture')" :class="{active:canvasGeneral.operation == 'texture'}"></i>
<i class="fi fi-rr-hand-paper" @click="setOperation('move')" :class="{active:canvasGeneral.operation == 'move'}"></i>
<i class="icon iconfont icon-move" @click="setOperation('movePosition')" :class="{active:canvasGeneral.operation == 'movePosition'}"></i>
<i class="icon iconfont icon-xiangpi_huaban1" @click="setOperation('eraser')" :class="{active:canvasGeneral.operation == 'eraser'}"></i>
<!-- <i class="icon iconfont icon-xiala" :class="closeNav.tool?'icon-rotate':''" @click.stop="setCloseNav('tool')"></i> -->
<i class="fi fi-rr-square-dashed" @click="setOperation('dashed')" :class="{active:canvasGeneral.operation == 'dashed'}"></i>
<i class="fi fi-rr-scalpel-path" @click="setOperation('dashedPencil')" :class="{active:canvasGeneral.operation == 'dashedPencil'}"></i>
<i class="fi fi-rr-zoom-in" @click="setOperation('zoomIn')" :class="{active:canvasGeneral.operation == 'zoomIn'}"></i>
<i class="fi fi-rr-zoom-out" @click="setOperation('zoomOut')" :class="{active:canvasGeneral.operation == 'zoomOut'}"></i>
<i class="icon iconfont icon-IC-yehua" @click="setLiquefaction()"></i>
<div class="label_item uploadImage">
<i class="icon fi fi-br-upload" ></i>
<input type="file" @change="uploadImage">
</div>
<i class="icon iconfont" @click="setOperation('text')" :class="{active:canvasGeneral.operation == 'text'}">T</i>
<i class="icon iconfont icon-xiala" :class="{'icon-xialaActive':isMove}" @click.stop="openMore"></i>
<div class="btnModal" v-show="isMove" :style="moveStyle">
<!-- <i class="icon iconfont icon-xian" @click="setOperation('fold')" :class="{active:canvasGeneral.operation == 'fold'}"></i> -->
<i class="icon iconfont icon-checkbox-full" @click="setOperation('rect')" :class="{active:canvasGeneral.operation == 'rect'}"></i>
<!-- <i class="icon iconfont icon-zhixian" @click="setOperation('line')" :class="{active:canvasGeneral.operation == 'line'}"></i> -->
<!-- <i class="icon iconfont icon-circle" @click="setOperation('circle')" :class="{active:canvasGeneral.operation == 'circle'}"></i> -->
<i class="icon iconfont icon-sanjiaoxing" @click="setOperation('triangle')" :class="{active:canvasGeneral.operation == 'triangle'}"></i>
<i class="icon iconfont icon-tx-fill-tuoyuanxing" @click="setOperation('ellipse')" :class="{active:canvasGeneral.operation == 'ellipse'}"></i>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,ref,reactive,nextTick,toRefs,inject} from 'vue'
import {base64ToFile} from '@/tool/util'
import { Https } from "@/tool/https";
export default defineComponent({
component:{},
emits:['toolLiquefaction'],
setup(props,{emit}){
let canvasGeneral:any = inject('canvasObj')
let isShowMark:any = inject('isShowMark')
const data:any = reactive({
isMove:false,
moveStyle:{},
})
const uploadImage = (event:any)=>{
isShowMark.value = true
const file = event.target.files[0];
let input = event.target
setOperation('movePosition')
if (file) {
const reader = new FileReader();
reader.onload = (e:any) => {
let file = base64ToFile(e.target.result,'upload')
let formData = new FormData();
formData.append("file", file);
let config = {headers:{'Content-Type':'multipart/form-data','Accept':'*/*' }}
Https.axiosPost(Https.httpUrls.canvasElementUpload, formData,config).then((rv)=>{
rv.imgUrl = rv.minioUrl
isShowMark.value = false
canvasGeneral.addImage(rv)
})
input.value = ''
};
reader.readAsDataURL(file);
}
}
const historyState = (str:any)=>{
canvasGeneral.historyState(str)
}
const setOperation = (str:any)=>{
canvasGeneral.setOperation(str)
}
const openMore = (e:any)=>{
data.isMove=!data.isMove
if(data.isMove){
let domPoint = e.target.getBoundingClientRect()
let domParentPoint = e.target.parentElement.getBoundingClientRect()
const left = domPoint.left - domParentPoint.left;
const top = domPoint.top - domParentPoint.top;
data.moveStyle.top = top + 'px'
data.moveStyle.left = left + domPoint.width + 2 + 'px'
}
}
const setMore = ()=>{
data.isMove = false
}
let setLiquefaction = ()=>{
emit('toolLiquefaction')
}
document.addEventListener('click',setMore)
const closeModal = ()=>{
document.removeEventListener('click',setMore)
}
return {
canvasGeneral,
...toRefs(data),
uploadImage,
historyState,
setOperation,
openMore,
closeModal,
setLiquefaction,
}
}
});
</script>
<style lang='less' scoped>
.canvasTool::-webkit-scrollbar{
display: none;
}
.canvasTool{
display: flex;
flex-direction: column;
position: relative;
align-items: center;
&.leftAlign{
justify-content: flex-start;
}
&.leftAlign{
justify-content: flex-start;
}
.uploadImage{
width: 3rem;
height: 3rem;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
i{
zoom:.8;
}
input{
height: 0;
width: 0;
border: none;
}
}
.uploadImage{
position: relative;
input{
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
opacity: 0;
z-index: 2;
cursor: pointer;
}
}
.btnModal{
position: absolute;
z-index: 2;
background: #fff;
top: 0;
border: 1px solid;
display: flex;
padding: .5rem 1rem;
border-radius: 4px;
}
}
</style>

View File

@@ -1,10 +1,11 @@
<template>
<div>
<div ref="designDetailModal">
<!-- designDetailShow -->
<a-modal class="design_detail_modal_component Guide_1_18"
:class="[driver__.driver?'hideEvents':'']"
<!-- :class="[driver__.driver?'hideEvents':'']" -->
<a-modal class="design_detail_modal_component Guide_1_18 generalModel"
v-model:visible="designDetailShow"
:footer="null"
:get-container="() => $refs.designDetailModal"
width="78%"
:maskClosable="false"
:centered="true"
@@ -15,8 +16,15 @@
<div>{{ $t('DesignDetail.Details') }}</div>
<div class="modal_title_text_intro">{{ $t('DesignDetail.EditDetails') }}</div>
</div>
<div class="design_closeIcon" @click.stop="closeModal('')">
<i class="fi fi-rr-cross-small"></i>
<div class="generalModel_btn">
<div class="generalModel_closeIcon" @click.stop="closeModal('')">
<!-- <i class="fi fi-rr-cross-small"></i> -->
<svg width="46" height="46" viewBox="0 0 46 46" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="23" cy="23" r="23" fill="white" fill-opacity="0.3"/>
<rect x="32.5063" y="12" width="3" height="29" rx="1.5" transform="rotate(45 32.5063 12)" fill="white"/>
<rect x="34.6274" y="32.5059" width="3" height="29" rx="1.5" transform="rotate(135 34.6274 32.5059)" fill="white"/>
</svg>
</div>
</div>
<div class="turn_button turn_left_button" v-show="designShowPrview == 1" @click="changeDesignItem('last')"><span class="icon iconfont icon_turn icon-shangyibu"></span></div>
<div class="turn_button turn_right_button" v-show="designShowPrview == 1" @click="changeDesignItem('next')"><span class="icon iconfont icon_turn icon-xiayibu"></span></div>
@@ -59,7 +67,7 @@
<!-- 全屏 -->
<i class="fi fi-bs-expand-arrows-alt" @click="showDesignImgDetail(2)"></i>
<!-- 编辑 -->
<i class="fi fi-rr-edit" :title="$t('DesignDetail.editTitle')" @click="showDesignImgDetail(3)"></i>
<i class="fi fi-rr-edit" v-show="!body" :title="$t('DesignDetail.editTitle')" @click="showDesignImgDetail(3)"></i>
<i v-show="!body && !deleteShow" :title="$t('DesignDetail.DetailTitle')" class="fi fi-rr-trash" @click="deleteNav(0)"></i>
<i v-show="!body && deleteShow" class="fi fi-br-check" @click="deleteNav(1)"></i>
@@ -153,7 +161,6 @@
<div class="design_detail_perview_content" >
<!-- <div class="generate_button" v-show="designItemDetail.singleOverall == 'overall'" @click="generateHighDesign()">Generate Product lmage</div> -->
<setDesignItem ref="setDesignItem" :isBody="body" @setParentLoadingShow=setParentLoadingShow @setDesignCoverage="setDesignCoverage" @setSubmit="setSubmit"></setDesignItem>
<!-- <setDesignItemMobile v-else ref="setDesignItemMobile" @setParentLoadingShow=setParentLoadingShow @setDesignCoverage="setDesignCoverage" @setSubmit="setSubmit"></setDesignItemMobile> -->
</div>
</div>
@@ -171,7 +178,6 @@ import DesignDetailAlter from '@/component/Detail/DesignDetailAlter.vue'
import magnifyingGlass from '@/component/Detail/magnifyingGlass.vue'
import setDesignItem from '@/component/Detail/setDesignItem.vue'
// import setDesignItem from '@/component/Detail/setDesignItem2.vue'
import setDesignItemMobile from '@/component/Detail/setDesignItemMobile.vue'
import Draggable from 'vuedraggable'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
@@ -179,7 +185,6 @@ import { Modal,message } from 'ant-design-vue';
import {getUploadUrl,isMoible,setGradual} from '@/tool/util'
import { useStore } from "vuex";
import { openGuide,driverObj__ } from "@/tool/guide";
import { setCookie, getCookie, WriteCookie } from "@/tool/cookie";
import { useI18n } from 'vue-i18n'
import addDetails from '@/component/Detail/addDetails.vue'
export default defineComponent({
@@ -188,7 +193,6 @@ export default defineComponent({
DesignDetailAlter,
setDesignItem,
magnifyingGlass,
setDesignItemMobile,
addDetails,
},
setup() {
@@ -199,6 +203,9 @@ export default defineComponent({
let designItemDetail :any = computed(()=>{
return store.state.DesignDetailModule.designItemDetail
})
const userDetail = computed(()=>{
return store.state.UserHabit.userDetail
})
let parentData:any = ref({
design:{},
index:0,
@@ -219,7 +226,6 @@ export default defineComponent({
let body = ref(false)
let designItemId = ref()
let designOutfitId = ref()
let userInfo:any = {}
let ifSubmit = ref(false)
let designItemDetailUrl = ref({})
let setRevocationShow = ref(false)//判断是不是第一次进来和切换下一张
@@ -247,6 +253,7 @@ export default defineComponent({
return{
designItemDetail,
userDetail,
store,
parentData,
others,
@@ -256,7 +263,6 @@ export default defineComponent({
body,
designItemId,
designOutfitId,
userInfo,
ifSubmit,
designItemDetailUrl,
setRevocationShow,
@@ -381,8 +387,6 @@ export default defineComponent({
window.removeEventListener('beforeunload',beforeunload)
}
window.addEventListener('beforeunload',beforeunload)
let userInfo:any = getCookie("userInfo")
this.userInfo = JSON.parse(userInfo);
// let url = Https.httpUrls.getDesignDetail + `?designItemId=34242&designPythonOutfitId=34004`
// this.loadingShow = true
// Https.axiosGet(url).then(
@@ -463,7 +467,6 @@ export default defineComponent({
// this.designItemDetail = {}
this.frontBack = {}
let setDesignItem:any = this.$refs.setDesignItem
// let setDesignItem:any = isMoible() ? this.$refs.setDesignItemMobile : this.$refs.setDesignItem
setDesignItem.clear()
}
@@ -779,7 +782,7 @@ export default defineComponent({
isPreview:false,
sketchString:'',
ifSubmit:designItemDetail.isPreview,
processId:String(this.userInfo?.userId),
processId:this.userDetail.userId,
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
}
if(str == 'preview'){
@@ -1165,26 +1168,25 @@ export default defineComponent({
}
})
</script>
<style lang="less">
.design_detail_modal_component{
<style lang="less" scoped>
:deep(.design_detail_modal_component){
color: #000;
// max-width: 1440px ;
.mark_loading{
position: absolute;
}
.ant-modal-content{
border-radius: calc(1rem*1.2);
>.ant-modal-content{
// overflow: hidden;
.ant-modal-header{
background-color: #fff;
border-bottom: none;
}
.ant-modal-body{
>.ant-modal-body{
padding: calc(5rem*1.2) calc(6rem*1.2) calc(0rem*1.2)!important;
// height: calc(65vh - 6.4rem*1.2));
height: calc(65rem*1.2);
display: flex;
overflow-y: hidden;
// overflow-y: hidden;
flex-direction: column;
}
}
@@ -1725,10 +1727,5 @@ export default defineComponent({
}
</style>
<style lang="less">
.design_detail_modal_component{
}
</style>

View File

@@ -1364,8 +1364,8 @@ export default defineComponent({
margin: 0;
margin-bottom: calc(2rem*1.2);
width: calc(9rem*1.2);
height: calc(9rem*1.2);
width: 10rem;
height: 10rem;
display: flex;
align-items: center;
justify-content: center;

View File

@@ -110,7 +110,6 @@ import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { Sketch} from '@ans1998/vue3-color'
import DesignPrintOperation from './DesignPrintOperation.vue';
import DesignPrintOperationMobile from './DesignPrintOperationMobile.vue';
import DesignElementsOperation from './DesignElements.vue';
import { message,Upload} from 'ant-design-vue';
import { openGuide,driverObj__ } from "@/tool/guide";
@@ -121,7 +120,7 @@ import sketchCategory from "@/component/HomePage/sketchCategory.vue";
export default defineComponent({
props: ["msg"],
components:{
Draggable,Sketch,DesignPrintOperation,DesignPrintOperationMobile,
Draggable,Sketch,DesignPrintOperation,
DesignElementsOperation,sketchCategory
},
setup(prop) {
@@ -262,7 +261,6 @@ export default defineComponent({
setPrint(){
// if(this.current?.printObject?.prints?.[0]?.path){
let DesignPrintOperation = this.$refs.DesignPrintOperation
// let DesignPrintOperation = isMoible() ? this.$refs.DesignPrintOperationMobile : this.$refs.DesignPrintOperation
DesignPrintOperation.init()
if(this.driver__.driver){
nextTick().then(()=>{

View File

@@ -1,9 +1,10 @@
<template>
<div>
<div ref="designElementsModal">
<a-modal
class="designElements_modal"
class="designElements_modal generalModel"
v-model:visible="designElements"
:footer="null"
:get-container="() => $refs.designElementsModal"
width="78%"
:maskClosable="false"
:centered="true"
@@ -15,8 +16,15 @@
<div class="design_title_text">
<div>{{ $t('DesignPrintOperation.Placement') }}</div>
</div>
<div class="design_closeIcon" @click.stop="closeModal()">
<i class="fi fi-rr-cross-small"></i>
<div class="generalModel_btn">
<div class="generalModel_closeIcon" @click.stop="closeModal()">
<!-- <i class="fi fi-rr-cross-small"></i> -->
<svg width="46" height="46" viewBox="0 0 46 46" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="23" cy="23" r="23" fill="white" fill-opacity="0.3"/>
<rect x="32.5063" y="12" width="3" height="29" rx="1.5" transform="rotate(45 32.5063 12)" fill="white"/>
<rect x="34.6274" y="32.5059" width="3" height="29" rx="1.5" transform="rotate(135 34.6274 32.5059)" fill="white"/>
</svg>
</div>
</div>
<div class="designElements_open">
<!-- -->
@@ -678,7 +686,7 @@ export default defineComponent({
});
</script>
<style lang="less">
<style lang="less" scoped>
.designElements_modal {
// max-width: 1440px;
user-select: none; /* 对现代浏览器有效 */

View File

@@ -1,925 +0,0 @@
<template>
<div>
<a-modal
class="designElementsMobile_modal"
v-model:visible="designElements"
:footer="null"
width="78%"
:maskClosable="false"
:centered="true"
:closable="false"
:keyboard="false"
:mask="true"
>
<div class="designElementsMobile_content">
<div class="design_title_text">
<div>{{ $t('DesignPrintOperation.Placement') }}</div>
</div>
<div class="design_closeIcon" @click.stop="closeModal()">
<i class="fi fi-rr-cross-small"></i>
</div>
<div class="designElementsMobile_open">
<!-- -->
<div class="print_right">
<div class="print_right show_print_right ">
<div @click="random" class="button_second">{{ $t('DesignPrintOperation.Random') }}</div>
<div class="designElementsMobile_nav">
<div class="designElementsMobile_single" v-for="item,index in designElementsList" :key="item">
<img :src="item.path" @click="setpitch(item,index)">
</div>
<div class="designElementsMobile_single" v-for="item,index in designSelectElementsList" :key="item">
<img :src="item.path" @click="setpitch(item,index)">
</div>
</div>
<div class="subitOkPreviewBtn" @click.stop="setPreview">{{ $t('DesignPrintOperation.preview') }}</div>
<div class="subitOkPreviewBtn _1" @click.stop="setOK">OK</div>
</div>
</div>
</div>
<div class="designElementsMobile_centent" id="designElementsCentent">
<div class="designElementsMobile_imgMask">
<div class="designElementsMobile_print">
<div
v-for="item,index in exhibitionElementsList"
:key="item"
:style="[printStyleList?.[index]?.style]"
@touchstart.passive="itemMoveMousedown(index,$event)"
class="modal_imgItem"
ref="content" >
<img crossOrigin="anonymous" :src="item?.path" :style="{transform:`rotateZ(${printStyleList[index]?.transform?.rotateZ}deg)`}" class="designElementsMobile_imgItme" draggable="false">
</div>
</div>
<!-- <img :src="current?.path" alt="" class="designElementsMobile_sketch"> -->
<img :src="current?.undividedLayer?current.undividedLayer:current.path" alt="" class="designElementsMobile_sketch">
<div class="designElementsMobile_btn">
<ul v-for="item,index in printStyleList" :key="item" :class="{active:item?.designElementsBtn?item?.designElementsBtn:false}" class="designElementsMobile_Mousingle" :style="item.style" @touchstart.passive="itemMoveMousedown(index,$event)">
<li class="designElementsMobile_btn_top" @touchstart.passive="itemSizeMousedown('top',$event)"></li>
<li class="designElementsMobile_btn_bottom" @touchstart.passive="itemSizeMousedown('bottom',$event)"></li>
<li class="designElementsMobile_btn_left" @touchstart.passive="itemSizeMousedown('left',$event)"></li>
<li class="designElementsMobile_btn_right" @touchstart.passive="itemSizeMousedown('right',$event)"></li>
<li class="designElementsMobile_rotote" v-rotote.stop="[index,item.transform]"></li>
<li class="designElementsMobile_delete" @click="deletePrint">
<img src="../../assets/images/homePage/cuowu.svg" alt="">
</li>
</ul>
<div></div>
</div>
</div>
</div>
<div class="designElementsMobile_right">
<div class="designElementsMobile_entirety_img">
<img :src="currentFullBodyView" alt="">
</div>
</div>
</div>
<div class="mark_loading" v-show="loadingShow">
<a-spin size="large" />
</div>
</a-modal>
</div>
</template>
<script >
import { defineComponent, h,createVNode, ref ,computed, inject,nextTick} from "vue";
// import { LoadingOutlined } from "@ant-design/icons-vue";
import { useStore } from "vuex";
import { openGuide,driverObj__ } from "@/tool/guide";
import { Https } from "@/tool/https";
import { Modal,message } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { useI18n } from "vue-i18n";
export default defineComponent({
setup(prop) {
let designElements = ref(false);
let designSelectElementsList = ref([])//新增的元素
let designElementsList = ref([])//已经存在的元素
let exhibitionElementsList = ref([])//展示的元素
let setOkData = ref([])
let current = inject('current')//父组件传过来的数据
let driver__ = inject('driver__')
let setRevocation = inject('setRevocation')//父组件传过来的数据
let printZIndex = ref(2)//印花优先级
let printStyleList = ref([]);
let currentPrintStyleList = {
centers:{
left:0,
top:0,
},
style:{
left:0+"px",
top:0+"px",
right:"auto",
bottom:"auto",
width:'auto',
height:'auto',
zIndex:1,
},
transform:{
scale:1,
rotateZ:0,
},
designElementsBtn:false
}
let direction = ref('')
let imgDom = ref()
let imgDomIndex = ref(0)
let print = ref({
width:'',
height:''
})
let sketch = ref({
width:'',
height:''
})
let loadingShow = ref(false)
let currentFullBodyView = ref('')
let designItemDetailTS = ref({})
let body = ref(false)
let {t} = useI18n()
return {
designElements,
designSelectElementsList,
designElementsList,
exhibitionElementsList,
setOkData,
current,
driver__,
printZIndex,
printStyleList,
currentPrintStyleList,
direction,//判断点击的是li那个边
imgDom,
imgDomIndex,
print,
sketch,
loadingShow,
setRevocation,
t,
currentFullBodyView,
designItemDetailTS,
body,
};
},
data() {
return {
store: useStore(),
};
},
directives:{
//操作旋转
rotote:{
mounted(el,value){
el.addEventListener('touchstart', (e) => {
let elParent = document.getElementsByClassName('designElementsMobile_modal')[0].getElementsByClassName('modal_imgItem')[value.instance.imgDomIndex]
let mouse = true;
let angle = 0
let num = 1
let x = 0
let y = 0
num = value.instance.printStyleList[value.instance.imgDomIndex].transform.scale
angle = value.instance.printStyleList[value.instance.imgDomIndex].transform.rotateZ
// 添加鼠标按下事件监听器
el.style.transform = "translate(-50%, -50%)rotateZ("+ angle + "deg)"
// let scale = Number(elParent.firstElementChild.style.transform?.split('scale(')[1]?.split(')')[0])
// let rotateZ = Number(elParent.firstElementChild.style.transform?.split('rotateZ(')[1]?.split('deg')[0])
e.stopPropagation()
mouse = true;
var info = el.getBoundingClientRect();
let eX = info.x + info.width / 2;
let eY = info.y + info.height / 2;
let touchmove = (e) => {
if (mouse) {
let X = eX
let Y = eY
let x = e.targetTouches[0].clientX - X
let y = Y - e.targetTouches[0].clientY
angle = Math.atan2(x,y)*(180 / Math.PI)
elParent.firstElementChild.style.transform = "rotateZ("+ angle + "deg)"
el.style.transform = "translate(-50%, -50%)rotateZ("+ angle + "deg)"
}
}
document.addEventListener('touchmove', touchmove,{passive:true});
// 添加鼠标松开事件监听器
let touchend = () => {
value.instance.printStyleList[value.instance.imgDomIndex].transform.rotateZ = angle
mouse = false;
document.removeEventListener('touchend',touchend)
document.removeEventListener('touchmove',touchmove)
}
document.addEventListener('touchend', touchend);
});
}
},
},
methods: {
init(){
let designItemDetail = JSON.parse(JSON.stringify(this.store.state.DesignDetailModule.designItemDetail))
this.currentFullBodyView = designItemDetail.currentFullBodyView? designItemDetail.currentFullBodyView:designItemDetail.designItemUrl
if(designItemDetail.others.length == 0){
this.body = true
}
this.designElements = true
this.clearModal()
if(this.current.trims.prints)this.exhibitionElementsList = JSON.parse(JSON.stringify(this.current.trims.prints))
if(this.$parent.exhibitionList.elements)this.designSelectElementsList = JSON.parse(JSON.stringify(this.$parent.exhibitionList.elements))
if(this.$parent.elementsList)this.designElementsList = JSON.parse(JSON.stringify(this.$parent.elementsList))
let skecth = new Image
skecth.src = this.current.path
skecth.onload=()=>{
this.sketch.width = skecth.width/10+'rem'
this.sketch.height = skecth.height/10+'rem'
skecth.remove()
}
if(this.exhibitionElementsList.length > 0){
this.exhibitionElementsList.forEach((item,index)=>{
this.setTemplate(item,index)
})
}else{
}
},
random(){
if(this.printStyleList.length == 0)return
this.printStyleList.forEach((v,index)=>{
this.refetchTemplate(index)
})
},
setPrintWH(url){
let print = new Image
return new Promise((resolve, reject) => {
print.onload=()=>{
this.print.width = print.width+'px'
this.print.height = print.height+'px'
resolve()
print.remove()
}
print.src = url
})
},
async setpitch(item,index){
await this.setPrintWH(item.path)
this.printStyleList.forEach((v)=>{
v.designElementsBtn = false
})
this.currentPrintStyleList.url = item.url
this.printStyleList.push(JSON.parse(JSON.stringify(this.currentPrintStyleList)))
let currentIndex = this.printStyleList.length-1
this.exhibitionElementsList.push({
angle:0,
designType:item.designType,
minIOPath:item.minIOPath,
path:item.path,
priority:1,
scale:1,
location:[0,0]
})
this.refetchTemplate(currentIndex)
},
//设置移动
itemMoveMousedown(index,event){
this.imgDomIndex = index
this.printStyleList.forEach((v)=>{
v.designElementsBtn = false
})
this.imgDom = document.getElementsByClassName('designElementsMobile_modal')[0].getElementsByClassName("modal_imgItem")[this.imgDomIndex]
let scale = Number(this.imgDom.children[0].style.transform?.split('scale(')[1]?.split(')')[0])
let rotateZ = Number(this.imgDom.children[0].style.transform?.split('rotateZ(')[1]?.split('deg')[0])
this.printStyleList[index].designElementsBtn = true
this.printStyleList[index].style.zIndex = this.printZIndex++
this.printStyleList[index].transform = {
scale:scale,
rotateZ:rotateZ?rotateZ:0,
}
let imgDomWH = this.imgDom.getBoundingClientRect()
let left = Number(this.printStyleList[index].style.left.replace(/px/g,''))
let top = Number(this.printStyleList[index].style.top.replace(/px/g,''))
this.printStyleList[index].centers.left = imgDomWH.x+event.changedTouches[0].pageX - this.imgDom.getBoundingClientRect().left-left
this.printStyleList[index].centers.top = imgDomWH.y+event.changedTouches[0].pageY - this.imgDom.getBoundingClientRect().top-top
document.addEventListener("touchend", this.touchend);
document.addEventListener("touchmove", this.moveMousemove);
},
//设置尺寸
itemSizeMousedown(direction,event){
this.direction = direction
this.imgDom = document.getElementsByClassName('designElementsMobile_modal')[0].getElementsByClassName("modal_imgItem")[this.imgDomIndex]
let scale = Number(this.imgDom.children[0].style.transform?.split('scale(')[1]?.split(')')[0])
let rotateZ = Number(this.imgDom.children[0].style.transform?.split('rotateZ(')[1]?.split('deg')[0])
this.printStyleList[this.imgDomIndex].designElementsBtn = true
this.printStyleList[this.imgDomIndex].transform = {
scale:scale,
rotateZ:rotateZ?rotateZ:0,
}
let imgDomWH = this.imgDom.getBoundingClientRect()
let li = document.getElementsByClassName('designElementsMobile_modal')[0].getElementsByClassName("designElementsMobile_btn_top")[0].offsetWidth/2
if(this.direction == 'right' || this.direction == 'bottom'){
this.printStyleList[this.imgDomIndex].centers.left = imgDomWH.x+event.changedTouches[0].pageX - this.imgDom.getBoundingClientRect().left-li
this.printStyleList[this.imgDomIndex].centers.top = imgDomWH.y+event.changedTouches[0].pageY - this.imgDom.getBoundingClientRect().top-li
}else{
this.printStyleList[this.imgDomIndex].centers.left = imgDomWH.x+event.changedTouches[0].pageX - this.imgDom.getBoundingClientRect().left+imgDomWH.width-li
this.printStyleList[this.imgDomIndex].centers.top = imgDomWH.y+event.changedTouches[0].pageY - this.imgDom.getBoundingClientRect().top+imgDomWH.height-li
this.printStyleList[this.imgDomIndex].centers.right = this.imgDom.parentNode.offsetWidth -imgDomWH.width - this.imgDom.offsetLeft
this.printStyleList[this.imgDomIndex].centers.bottom = this.imgDom.parentNode.offsetHeight -imgDomWH.height - this.imgDom.offsetTop
}
document.addEventListener("touchend", this.sizeMouseup);
document.addEventListener("touchmove", this.sizeMousemove);
},
//鼠标移动
moveMousemove(e) {
let imgDomWH = this.imgDom.getBoundingClientRect()
let parentNode = document.getElementsByClassName('designElementsMobile_modal')[0].getElementsByClassName("designElementsMobile_imgMask")[0]
parentNode = parentNode.getBoundingClientRect()
let x = ( e.changedTouches[0].pageX - this.printStyleList[this.imgDomIndex].centers.left)+'px'
let y = ( e.changedTouches[0].pageY - this.printStyleList[this.imgDomIndex].centers.top)+'px'
this.printStyleList[this.imgDomIndex].style.left = x
this.printStyleList[this.imgDomIndex].style.top = y
},
sizeMousemove(e) {
let imgDomWH = this.imgDom.getBoundingClientRect()
let parentNode =this.imgDom.parentNode
let width = imgDomWH.width
let height = imgDomWH.height
let num = width/height
let num1 = height/width
let w,h
//判断移动四个边
if(this.direction == 'right'){
w = ( e.changedTouches[0].pageX -imgDomWH.left)
h = ( e.changedTouches[0].pageX - imgDomWH.left)*num
width = w+'px'
height = w*num1+'px'
}else if(this.direction == 'top'){
this.printStyleList[this.imgDomIndex].style.top = 'auto'
// this.printStyleList[this.imgDomIndex].style.left = 'auto'
// this.printStyleList[this.imgDomIndex].style.bottom = parentNode.offsetHeight -imgDomWH.height - this.imgDom.offsetTop+'px'
this.printStyleList[this.imgDomIndex].style.bottom = this.printStyleList[this.imgDomIndex].centers.bottom+'px'
w = ( e.changedTouches[0].pageX - this.printStyleList[this.imgDomIndex].centers.left)*num
h = (this.printStyleList[this.imgDomIndex].centers.top - e.changedTouches[0].pageY)
height = h+'px'
width = h*num+'px'
}else if(this.direction == 'bottom'){
h = ( e.changedTouches[0].pageY - imgDomWH.top)
height = h+'px'
width = h*num+'px'
}else if(this.direction == 'left'){
this.printStyleList[this.imgDomIndex].style.left = 'auto'
this.printStyleList[this.imgDomIndex].style.right = this.printStyleList[this.imgDomIndex].centers.right+'px'
w = (this.printStyleList[this.imgDomIndex].centers.left - e.changedTouches[0].pageX)
width = w+'px'
height = w*num1+'px'
}
//判断尺寸是否到边
this.printStyleList[this.imgDomIndex].style.width = width
this.printStyleList[this.imgDomIndex].style.height = height
},
//鼠标抬起
sizeMouseup(e){
this.printStyleList[this.imgDomIndex].style={
right:'auto',
left:this.imgDom.offsetLeft+'px',
bottom:'auto',
top:this.imgDom.offsetTop+'px',
height:this.imgDom.offsetHeight+'px',
width:this.imgDom.offsetWidth+'px',
zIndex:this.printZIndex
}
document.removeEventListener("touchend", this.sizeMouseup);
document.removeEventListener("touchmove", this.sizeMousemove);
},
touchend(e) {
document.removeEventListener("touchend", this.touchend);
document.removeEventListener("touchmove", this.moveMousemove);
},
deletePrint(){
this.exhibitionElementsList.splice(this.imgDomIndex,1)
this.printStyleList.splice(this.imgDomIndex,1)
},
//随机重置图片顺序
refetchTemplate(index) {
// let scale = (Math.trunc(Math.random()*15)+1)*.1
let rotateZ1 = Math.trunc(Math.random()*360)+1
let rotateZ2 = Math.trunc(Math.random()*360)+1
let sketch = document.getElementsByClassName("designElementsMobile_modal")[0]?.getElementsByClassName('designElementsMobile_sketch')[0]
let width
let scale
if(sketch.width<sketch.height){
width = Math.trunc(Math.random()*(sketch?.width-sketch?.width/2))+sketch?.width/4
scale = width / this.print.width.replace(/px/g,'')
}else{
width = Math.trunc(Math.random()*(sketch?.height-sketch?.height/2))+sketch?.height/4
scale = width / this.print.height.replace(/px/g,'')
}
// let x = sketch.width-Number(this.print.width.replace(/px/g,''))
// let y = sketch.height-Number(this.print.height.replace(/px/g,''))
let x = sketch?.width - this.print.width.replace(/px/g,'')*scale
let y = sketch?.height-this.print.height.replace(/px/g,'')*scale
this.printStyleList[index].style = {
left:Math.trunc(Math.random()*x)+1+"px",
top:Math.trunc(Math.random()*y)+1+"px",
right:"auto",
bottom:"auto",
width:this.print.width.replace(/px/g,'')*scale+'px',
height:this.print.height.replace(/px/g,'')*scale+'px',
zIndex:this.printZIndex++
}
this.printStyleList[index].transform = {
rotateZ:this.printStyleList[index].transform.rotateZ?this.printStyleList[index].transform.rotateZ:0
}
},
//设置图片
async setTemplate(item,index) {
await this.setPrintWH(item.path)
this.designElementsList
let sketch = document.getElementsByClassName("designElementsMobile_modal")[0]?.getElementsByClassName('designElementsMobile_sketch')[0]
let sketchImg = new Image()
sketchImg.onload = ()=>{
let sketchNum = this.sketch.width.replace(/rem/g,'')*10/sketch.offsetWidth
let scale
scale = (this.print.width.replace(/px/g,'')*sketchNum/this.print.width.replace(/px/g,''))
let zIndex = 1
let left = item.location[0]/sketchNum+'px'
let top = item.location[1]/sketchNum+'px'
if(sketch.offsetWidth < item.location[0]/sketchNum){
left = sketch.offsetWidth +'px'
}
if(sketch.offsetHeight < item.location[1]/sketchNum){
top = sketch.offsetHeight +'px'
}
this.printStyleList[index]={
centers:{
left:0,
top:0,
},
style:{
left:left,
top:top,
right:"auto",
bottom:"auto",
width:this.print.width.replace(/px/g,'')/sketchNum*item.scale+'px',
height:this.print.height.replace(/px/g,'')/sketchNum*item.scale+'px',
zIndex:zIndex++
},
transform:{
// scale:scale<.2?.2:scale,//0.2-3
rotateZ:item.angle,
},
designElementsBtn:false
}
sketchImg.remove()
}
sketchImg.src = sketch.src
},
computeZindex(resolve,prints){
prints.sort((a, b) => {
var a_num = a.priority;
var b_num = b.priority;
return a_num - b_num;
});
let num = 1
prints.forEach((v)=>{
v.priority = num++
})
resolve(prints)
// return this.computeSize(arr)//计算单件衣服初始大小到目前大小的缩放比
},
async computeSize(arr){
// let num = this.sketch/
return new Promise(async (resolve, reject) => {
let arr = JSON.parse(JSON.stringify(this.printStyleList))
let sketch = document.getElementsByClassName("designElementsMobile_modal")[0]?.getElementsByClassName('designElementsMobile_sketch')[0]
let sketchNum = this.sketch.width.replace(/rem/g,'')*10/sketch.offsetWidth
let prints = []
let scale
let location
for (let index = 0; index < arr.length; index++) {
await this.setPrintWH(this.exhibitionElementsList[index].path)
scale = (arr[index].style.width.replace(/px/g,'')*sketchNum/this.print.width.replace(/px/g,''))
location = [arr[index].style.left.replace(/px/g,'')*sketchNum,arr[index].style.top.replace(/px/g,'')*sketchNum]
let obj = {
angle : arr[index].transform.rotateZ,
location : location,
priority:arr[index].style.zIndex,
scale: scale,
designType:this.exhibitionElementsList[index].designType,
path:this.exhibitionElementsList[index].path,
minIOPath:this.exhibitionElementsList[index].minIOPath,
}
prints.push(obj)
}
this.computeZindex(resolve,prints)
})
},
async setPreview(){
let designItemDetail = JSON.parse(JSON.stringify(this.store.state.DesignDetailModule.designItemDetail))
let index
designItemDetail.clothes.forEach((v,ind)=>{
if(v.id == this.current.id){
index = ind
}
})
// let data = {
// ...designItemDetail,
// priority:priority,
// timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
// }
let data = JSON.parse(JSON.stringify(this.store.state.DesignDetailModule.designPreviewData))
await this.computeSize().then((rv)=>{
this.setOkData = rv
})
data.designSingleItemDTOList[index].trims.prints = this.setOkData
data.timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone
this.loadingShow = true
Https.axiosPost(Https.httpUrls.designSingle, data).then(
(rv) => {
// designItemDetail.clothes[index].printObject.path = rv.clothes[0].printObject.path
this.currentFullBodyView = rv.currentFullBodyView
this.designItemDetailTS.rv = rv
this.designItemDetailTS.data = data
this.loadingShow = false
// this.designElements = false
if(this.driver__.driver){
nextTick().then(()=>{
driverObj__.moveNext();
})
}
}
).catch(res=>{
this.loadingShow = false
});
},
setOK(){
let designItemDetail = JSON.parse(JSON.stringify(this.store.state.DesignDetailModule.designItemDetail))
let index
designItemDetail.clothes.forEach((v,ind)=>{
if(v.id == this.current.id){
index = ind
}
})
if(this.designItemDetailTS.rv){
designItemDetail.currentFullBodyView = this.designItemDetailTS.rv.currentFullBodyView
designItemDetail.clothes[index].layersObject = this.designItemDetailTS.rv.clothes[index].layersObject
designItemDetail.clothes[index].printObject = this.designItemDetailTS.rv.clothes[index].printObject
designItemDetail.clothes[index].trims.prints = this.setOkData
designItemDetail.ifSubmit = true
designItemDetail.clothes.forEach((item,i)=>{
let a
if(item.layersObject[0].imageCategory.indexOf("back") == -1){
a = item.layersObject[0]
item.layersObject[0] = item.layersObject[1]
item.layersObject[1] = a
}
item.layersObject[0].id = this.store.state.DesignDetailModule.designItemDetail.clothes[i].layersObject[0]?.id
item.layersObject[1].id = this.store.state.DesignDetailModule.designItemDetail.clothes[i].layersObject[1]?.id
})
this.store.commit("setDesignItemDetail", designItemDetail);
this.store.commit("setDesignPreviewData", this.designItemDetailTS.data);
this.setRevocation(designItemDetail,this.designItemDetailTS.data)
this.designItemDetailTS = {}
}
this.designElements = false
if(this.driver__.driver){
driverObj__.moveNext();
}
},
clearModal(){
this.designElements = true//modal页面关闭
this.printZIndex = 2//点击图片z-index
this.imgDomIndex = 0//点击图片下标
this.designSelectElementsList = []
this.printStyleList = []
this.designElementsList = []
this.exhibitionElementsList = []
},
closeModal(){
let designItemDetail = JSON.parse(JSON.stringify(this.store.state.DesignDetailModule.designItemDetail))
let _this = this
Modal.confirm({
title: this.t('DesignPrintOperation.jsContent1'),
icon: createVNode(ExclamationCircleOutlined),
okText: 'Yes',
cancelText: 'No',
mask:false,
centered:true,
onOk() {
_this.designElements=false
}
});
},
},
});
</script>
<style lang="less">
.designElementsMobile_modal {
// max-width: 1440px;
.mark_loading{
position: absolute;
}
.ant-modal-body{
padding: calc(5rem*1.2) calc(6rem*1.2) calc(0rem*1.2)!important;
// height: calc(65vh - 6.4rem*1.2));
height: calc(65rem*1.2);
display: flex;
overflow-y: hidden;
flex-direction: column;
}
.ant-modal-content{
border-radius: calc(1rem*1.2);
overflow: hidden;
}
.designElementsMobile_content {
// background: #f2f3fb;
// padding-bottom: 2.9rem*1.2);
display: flex;
flex-direction: column;
height: 100%;
.designElementsMobile_header {
position: relative;
height: calc(6.6rem*1.2);
width: 100%;
background: #F7F7F7;
.placement_modal_title{
position: absolute;
height: 100%;
line-height: calc(6.6rem*1.2);
left: calc(3.7rem*1.2);
top: 0;
font-size: calc(1.8rem*1.2);
color: #030303;
}
}
.designElementsMobile_right{
height: calc(50rem*1.2);
position: absolute;
right: calc(2rem*1.2);
left: auto;
top: 50%;
transform: translateY(-50%);
max-height: calc(50rem*1.2);
max-width: calc(30rem*1.2);
.designElementsMobile_entirety_img{
height: 100%;
img{
max-width: 100%;
max-height: 100%;
object-fit: contain;
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
}
}
.designElementsMobile_open{
position: absolute;
top: 50%;
transform: translateY(-50%);
.print_right{
display: flex;
flex-direction: column;
align-items: center;
border: 2px solid;
padding: calc(2rem*1.2) 0;
width: calc(16rem*1.2);
border-radius: calc(1rem*1.2);
height: calc(40rem*1.2);
.button_second{
margin: calc(1rem*1.2) 0;
width: calc(10rem*1.2);
text-align: center;
position: initial;
transform: none;
height: calc(3rem*1.2);
line-height: calc(3rem*1.2);
}
.designElementsMobile_nav{
display: flex;
margin-top: calc(2rem*1.2);
flex-wrap: wrap;
width: 100%;
height: calc(22rem*1.2);
overflow-x: hidden;
justify-content: space-evenly;
align-content: flex-start;
&.designElementsMobile_nav::-webkit-scrollbar {
display: none;
}
.active{
img{
border: 2px solid;
border-radius: 2px;
box-sizing: border-box;
}
}
.designElementsMobile_single{
width: 40%;
margin-bottom: calc(2rem*1.2);
}
img{
width: 100%;
cursor: pointer;
}
}
&.show_print_right{
border: none;
padding: 0;
height: 100%;
}
}
}
.designElementsMobile_centent{
margin: 0 auto;
overflow: hidden;
justify-content: space-between;
position: relative;
user-select:none;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
display: flex;
&.active{
flex-direction: row;
}
.designElementsMobile_imgMask{
width: auto;
height: auto;
position: relative;
>img{
z-index: 2;
position: relative;
// max-width: 100%;
// max-height: 100%;
// width: 100%;
// height: 50rem*1.2);
max-height: calc(50rem*1.2);
min-height: calc(30rem*1.2);
width: auto;
max-width: calc(60rem*1.2);
}
.designElementsMobile_sketch_mask{
z-index: 3;
position: absolute;
inset: 0;
width: 100%;
}
>div{
position: absolute;
width: 100%;
height: 100%;
top: 0;
}
}
.designElementsMobile_print{
z-index: 3;
.modal_imgItem{
position: absolute;
overflow: hidden;
top: 0;
img{
width: 100%;
height: 100%;
float: left;
user-select:none;
-webkit-user-drag: none;
}
}
}
.designElementsMobile_btn{
z-index: 3;
>div{
width: 100%;
height: 100%;
border: 2px solid rgb(20, 188, 255);
position: absolute;
}
ul{
list-style: none;
// width: 100%;
// height: 100%;
position: absolute;
top: 0;
left: 0;
box-sizing: border-box;
border: 2px solid rgb(20, 188, 255);
padding: 0;
-webkit-user-drag: none;
user-select:none;
opacity: 0;
margin: 0;
&.designElementsMobile_Mouoverall{
opacity: 1;
border: none;
width: calc(1.4rem*1.2);
height: calc(1.4rem*1.2);
i{
display: flex;
color: #14bcff;
}
}
li{
cursor: pointer;
// border-radius: 50%;
width: calc(2.5rem*1.2);
height: calc(2.5rem*1.2);
background-color: rgb(20, 188, 255);
position: absolute;
pointer-events: none;
}
&.active{
opacity: 1;
li{
pointer-events: auto;
}
}
.designElementsMobile_btn_top,.designElementsMobile_btn_bottom{
left: 50%;
transform: translate(-50%,-50%) ;
cursor: n-resize;
}
.designElementsMobile_btn_top{
top: 0;
}
.designElementsMobile_btn_bottom{
top: 100%;
}
.designElementsMobile_btn_left,.designElementsMobile_btn_right{
top: 50%;
transform: translate(-50%,-50%) ;
cursor: e-resize;
}
.designElementsMobile_btn_left{
left: 0;
}
.designElementsMobile_btn_right{
left: 100%;
}
.designElementsMobile_rotote{
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
width: 0;
height: 0;
}
.designElementsMobile_delete{
position: absolute;
top: 0;
right: 0;
width: 2.5rem;
background: none;
transform: translate(100%, -100%);
height: 2.5rem;
img{
width: 100%;
height: 100%;
}
}
.designElementsMobile_rotote::after{
position: absolute;
content: "";
background-color: #14bcff;
width: calc(.2rem*1.2);
height: calc(3rem*1.2);
left: 50%;
bottom: 0;
transform: translateX(-50%);
}
.designElementsMobile_rotote::before{
position: absolute;
content: "";
background-color: #14bcff;
top: calc(50% - 3rem*1.2);
left: 50%;
transform: translate(-50%,-50%) ;
width: calc(1.5rem*1.2);
height: calc(1.5rem*1.2);
border-radius: 50%;
}
}
}
}
.subitOkPreviewBtn{
z-index: 2;
margin: calc(1rem*1.2) 0;
width: calc(10rem*1.2);
text-align: center;
position: initial;
transform: none;
}
}
}
</style>

View File

@@ -1,10 +1,11 @@
<template>
<div>
<div ref="designOpenrtionModal">
<a-modal
class="designOpenrtion_modal Guide_1_24"
class="designOpenrtion_modal Guide_1_24 generalModel"
:class="[driver__.driver?'hideEvents':'']"
v-model:visible="designOpenrtion"
:footer="null"
:get-container="() => $refs.designOpenrtionModal"
width="78%"
:maskClosable="false"
:centered="true"
@@ -17,8 +18,15 @@
<div class="design_title_text">
<div>{{ $t('DesignPrintOperation.Placement') }}</div>
</div>
<div class="design_closeIcon" @click.stop="closeModal()">
<i class="fi fi-rr-cross-small"></i>
<div class="generalModel_btn">
<div class="generalModel_closeIcon" @click.stop="closeModal()">
<!-- <i class="fi fi-rr-cross-small"></i> -->
<svg width="46" height="46" viewBox="0 0 46 46" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="23" cy="23" r="23" fill="white" fill-opacity="0.3"/>
<rect x="32.5063" y="12" width="3" height="29" rx="1.5" transform="rotate(45 32.5063 12)" fill="white"/>
<rect x="34.6274" y="32.5059" width="3" height="29" rx="1.5" transform="rotate(135 34.6274 32.5059)" fill="white"/>
</svg>
</div>
</div>
<div class="designOpenrtion_open">
<!-- -->
@@ -62,6 +70,7 @@
<div v-show="!overallSingle" class="habit_System_Designer">
<div class="habit_System_Designer_text">{{ $t('DesignPrintOperation.Scale') }}</div>
<a-slider id="system_silder"
class="system_silder"
:min="20"
:max="1000"
v-model:value="systemDesignerPercentage"
@@ -941,7 +950,7 @@ export default defineComponent({
});
</script>
<style lang="less">
<style lang="less" scoped>
.designOpenrtion_modal {
// max-width: 1440px;
user-select: none; /* 对现代浏览器有效 */
@@ -950,6 +959,7 @@ export default defineComponent({
-ms-user-select: none; /* Internet Explorer/Edge */
.mark_loading{
position: absolute;
border-radius: 3rem;
}
.ant-modal-body{
padding: calc(5rem*1.2) calc(6rem*1.2) calc(0rem*1.2)!important;

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,10 @@
<template>
<div class="addDetailsModal" ref="addDetailsModal"></div>
<a-modal
class="addDetails_modal generalModel"
v-model:visible="addDetails"
:footer="null"
:get-container="() => $refs.addDetailsModal"
width="78%"
:maskClosable="false"
:centered="true"
@@ -13,7 +15,12 @@
>
<div class="generalModel_btn">
<div class="generalModel_closeIcon" @click.stop="cancelDsign()">
<i class="fi fi-rr-cross-small"></i>
<svg width="46" height="46" viewBox="0 0 46 46" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="23" cy="23" r="23" fill="white" fill-opacity="0.3"/>
<rect x="32.5063" y="12" width="3" height="29" rx="1.5" transform="rotate(45 32.5063 12)" fill="white"/>
<rect x="34.6274" y="32.5059" width="3" height="29" rx="1.5" transform="rotate(135 34.6274 32.5059)" fill="white"/>
</svg>
</div>
</div>
@@ -69,7 +76,7 @@ export default defineComponent({
},
});
</script>
<style lang="less">
<style lang="less" scoped>
.addDetails_modal {
.closeIcon {
z-index: 2;

View File

@@ -27,21 +27,13 @@
</template>
<script>
import { defineComponent, ref, reactive, watch, onMounted, nextTick, toRefs } from "vue";
import { Https } from "@/tool/https";
import { formatTime,segmentImage } from "@/tool/util";
import { setCookie, getCookie } from "@/tool/cookie";
import { Modal, message } from "ant-design-vue";
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";
import allOrder from "@/component/Pay/allOrder.vue";
import creditsDetail from "@/component/Pay/creditsDetail.vue";
import { exportSele,JSRectUpdata,JSchangeType,JScanvasMouseDown,JSSetRemoveImage,JScreateCheck,JSSetTexture } from "@/tool/canvasDrawing";
import { getMousePosition } from "@/tool/mdEvent";
import { useI18n } from "vue-i18n";
import canvasGeneral from "@/tool/canvasGeneral";
export default defineComponent({
components: {
creditsDetail,
allOrder,
},
// emits: ['setSloganData'],
props:['patchData','imgDomIndex'],
@@ -211,7 +203,6 @@ export default defineComponent({
}
let setClone = ()=>{
let canvasBox = document.querySelector(".editFrontBack_center .exportCanvasBox_center");
let oldCanvasDom = canvasBox.querySelector('.canvas-container')
let oldCanvasDom1 = canvasBox.querySelector('canvas')

View File

@@ -95,7 +95,7 @@
</div>
</div>
<div class="habit_System_Designer">
<a-slider id="system_silder"
<a-slider class="system_silder"
v-model:value="workspaceItem.systemDesignerPercentage"
@afterChange="setSystemDesigner"
:tip-formatter="formatter"
@@ -848,15 +848,13 @@ export default defineComponent({
.habit_button {
background-color: #fff;
border: solid 2px #000;
padding: 0px calc(2rem*1.2);
box-sizing: initial;
border-radius: 4rem;
font-weight: 600;
height: calc(3.2rem*1.2);
line-height: calc(3.2rem*1.2);
padding: calc(.4rem*1.2) calc(1.5rem*1.2);
font-size: calc(1.2rem*1.2);
font-size: 1.8rem;
padding: 0 1.8rem;
cursor: pointer;
position: relative;
line-height: 6rem;
.fi-bs-angle-down {
margin-left: calc(1rem*1.2);
display: inline-block;

View File

@@ -7,14 +7,19 @@
:maskClosable="false"
:centered="true"
:closable="false"
:mask="habitSetStyleMask"
:mask="true"
:keyboard="false"
:destroyOnClose="true"
:zIndex="1050"
:zIndex="1000"
>
<div class="generalModel_btn">
<div class="generalModel_closeIcon" @click.stop="cancelDsign()">
<i class="fi fi-rr-cross-small"></i>
<svg width="46" height="46" viewBox="0 0 46 46" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="23" cy="23" r="23" fill="white" fill-opacity="0.3"/>
<rect x="32.5063" y="12" width="3" height="29" rx="1.5" transform="rotate(45 32.5063 12)" fill="white"/>
<rect x="34.6274" y="32.5059" width="3" height="29" rx="1.5" transform="rotate(135 34.6274 32.5059)" fill="white"/>
</svg>
</div>
</div>
<div class="habitSetStyle_content" v-hoverAnmi>
@@ -47,12 +52,10 @@
<script lang="ts">
import { defineComponent,watch,createVNode, h, ref ,toRefs,computed,reactive,triggerRef, nextTick} from "vue";
// import { getCookie } from "@/tool/cookie";
import { message,Modal } from "ant-design-vue";
import { LoadingOutlined ,ExclamationCircleOutlined} from "@ant-design/icons-vue";
import { Https } from "@/tool/https";
import { getCookie,setCookie } from "@/tool/cookie";
// import domTurnImg from '@/tool/domTurnImg'
import { downloadIamge } from "@/tool/util";
import { useI18n } from "vue-i18n";
@@ -213,7 +216,6 @@ methods: {
.habitSetStyle_modal {
&.generalModel{
.ant-modal-body {
height: calc(55rem*1.2);
}
}

View File

@@ -35,7 +35,7 @@
</ul>
</div>
</div>
<div class="subitOkPreviewBtn" @click="imgClear">{{ $t('LibraryPage.Reset') }}</div>
<div class="subitOkPreviewBtn" @click="imgClear" style="margin-bottom: 0rem;">{{ $t('LibraryPage.Reset') }}</div>
<div @click="setPreviewData" class="subitOkPreviewBtn">OK</div>
</div>
<div class="designOpenrtion_imgMask_open" @click.stop="deleteBorder"></div>
@@ -382,7 +382,6 @@ export default defineComponent({
//判断尺寸是否到边
this.frontBack.front[this.imgDomIndex].style.width = width
this.frontBack.front[this.imgDomIndex].style.height = height
},
//鼠标抬起
sizeMouseup(e){
@@ -747,7 +746,8 @@ export default defineComponent({
}
.subitOkPreviewBtn{
z-index: 2;
margin-bottom: calc(1rem*1.2);
// margin-bottom: calc(1rem*1.2);
margin-bottom: 4rem;
width: calc(10rem*1.2);
text-align: center;
bottom: 0;

View File

@@ -1,626 +0,0 @@
<template>
<div class="design_compile_content" id="design_compile_content">
<div class="designOpenrtion_centent" id="designOpenrtionCentent">
<div class="detail_modal_body_title">
<div class="detail_modal_body_nav">
<div v-for="item,index in designItemDetail?.clothes" v-show="item.id" :class="{active:designShowIndex.value == index}" @click="clothesOpen(item,index)">
<img :src="item?.path" alt="">
</div>
</div>
</div>
<div class="designOpenrtion_imgMask">
<!-- <canvas ref="canvasDom" ></canvas> -->
</div>
<div class="subitOkPreviewBtn" @click="imgClear">{{ $t('LibraryPage.Reset') }}</div>
<div @click="setPreviewData" class="subitOkPreviewBtn">OK</div>
</div>
<div class="designOpenrtion_imgMask_open" @click.stop="deleteBorder"></div>
</div>
</template>
<script >
import { defineComponent, h,reactive, ref ,computed, inject,nextTick, onMounted} from "vue";
// import { LoadingOutlined } from "@ant-design/icons-vue";
import { useStore } from "vuex";
// import { Modal,message } from 'ant-design-vue';
import { Https } from "@/tool/https";
export default defineComponent({
emits: ['setDesignCoverage', 'setSubmit'],
// props: ["frontBack"],
setup(prop) {
const store = useStore();
let designItemDetail = computed(()=>{
return store.state.DesignDetailModule.designItemDetail
})
let current = inject('current')//父组件传过来的数据
let setRevocation = inject('setRevocation')//父组件传过来的数据
let printZIndex = ref(4)//印花优先级
let designShowIndex = reactive({value:-1})
let frontBack = reactive({})
let frontBackOld = reactive({})
let canvasFontBackMove = {
back:[],
front:[],
}
let setPostition = async (url) =>{
let img = await loadImage(url)
let modal_body = document.getElementsByClassName('designOpenrtion_imgMask')[0]
const num = modal_body?.offsetHeight / img.height;
function loadImage(url) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => {
resolve(img)
};
img.onerror = reject;
img.src = url;
});
}
return num
}
let computeZindex = (designItemDetail)=>{
let arr = designItemDetail.clothes
arr.sort((a, b) => {
var a_num = a.priority;
var b_num = b.priority;
return a_num - b_num;
});
designItemDetail.clothes = arr
return designItemDetail
}
let setImgSize = async ()=>{
let designItemDetail = JSON.parse(JSON.stringify(store.state.DesignDetailModule.designItemDetail))
let front = []
let back = []
let body
designItemDetail.others.forEach((item) => {
if(item.type == 'Body'){
body = item
}
});
let ratio = await setPostition(body.layersObject[0]?.imageUrl)
designItemDetail = computeZindex(designItemDetail)
designItemDetail.clothes.forEach((v,index)=>{
for (let i = v.layersObject.length-1; i >= 0; i--) {
v.layersObject[i].style = {
top:v.layersObject[i].position?.[0]*ratio+'px',
left:v.layersObject[i].position?.[1]*ratio+'px',
width:v.layersObject[i].imageSize?.[0]*ratio+'px',
height:v.layersObject[i].imageSize?.[1]*ratio+'px',
}
v.layersObject[i].centers={
left:0,
top:0,
}
v.scale = ratio
v.layersObject[i].designOpenrtionBtn = false
if(v.layersObject[i].imageCategory.indexOf("back") == -1){
front[index] = v.layersObject[i]
front[index].style.zIndex = v.priority
front[index].id = v.id
}else{
back[index] = v.layersObject[i]
back[index].style.zIndex = v.priority
back[index].id = v.id
}
if(printZIndex < v.priority){
printZIndex = v.priority
}
}
printZIndex++
})
let bodyImgWH = document.getElementsByClassName("design_compile_content")[0].getElementsByClassName("perview_img")[0]
body.style = {
width:body.layersObject[0].imageSize?.[0]*ratio+'px',
height:body.layersObject[0].imageSize?.[1]*ratio+'px',
}
frontBack = {
front:front,
back:back,
body:body,
}
frontBackOld = JSON.parse(JSON.stringify({
front:front,
back:back,
body:body,
}))
setCanvas(frontBack)
}
let canvas = reactive({})
let setCanvas = (frontBack)=>{
let canvasBox = document.querySelector('.design_compile_content .designOpenrtion_imgMask')
var canvasDom = document.createElement('canvas')
// console.log(canvasBox);
canvasBox.innerHTML = ''; // 清空原有内容
canvasBox.appendChild(canvasDom);
canvas = new fabric.Canvas(canvasDom, {
backgroundColor: "rgba(255,255,255,1)",
// fill: '#ffde7d',
selection: false, //设置多选
width: Number(frontBack?.body?.style.width.match(/\d+(\.\d+)?/)[0]),
height: Number(frontBack?.body?.style.height.match(/\d+(\.\d+)?/)[0]),
isDrawingMode: false, // 开启绘图模式
});
canvas.clear();
canvasFontBackMove = {
back:[],
front:[],
}
let fontBackMove = []
canvas.on('selection:created', (e)=> {
// console.log(canvas.getActiveObject());
// // if()
// console.log(frontBack.front.find(person => person.id === canvas.getActiveObject().id));
// designShowIndex.value =
});
// selection:updated
canvas.on('selection:cleared', ()=>{
designShowIndex.value = -1
})
frontBack.back.forEach((item) => {
if(!item.imageUrl){
return
}
fabric.Image.fromURL(item.imageUrl, (img) => {
img.set({
left: Number(item.style.left.match(/\d+(\.\d+)?/)[0]),
top: Number(item.style.top.match(/\d+(\.\d+)?/)[0]),
scaleX: Number(item.style.width.match(/\d+(\.\d+)?/)[0])/img.width,
scaleY: Number(item.style.height.match(/\d+(\.\d+)?/)[0])/img.height,
evented : false,
// selectable: false
});
canvas.add(img);
canvasFontBackMove.back.push({id:item.id,img:img})
});
});
fabric.Image.fromURL(frontBack?.body?.layersObject?.[0].imageUrl || '', (img) => {
img.set({
left: 0,
top: 0,
// width: Number(frontBack?.body?.style.width.match(/\d+(\.\d+)?/)[0]) * scale,
// height: Number(frontBack?.body?.style.height.match(/\d+(\.\d+)?/)[0]) * scale,
scaleX: Number(frontBack?.body?.style.width.match(/\d+(\.\d+)?/)[0])/img.width,
scaleY: Number(frontBack?.body?.style.height.match(/\d+(\.\d+)?/)[0])/img.height,
evented : false,
// selectable: false
});
canvas.add(img);
});
frontBack.front.forEach((item) => {
if(!item.imageUrl){
return
}
fabric.Image.fromURL(item.imageUrl, (img) => {
img.set({
left: Number(item.style.left.match(/\d+(\.\d+)?/)[0]),
top: Number(item.style.top.match(/\d+(\.\d+)?/)[0]),
scaleX: Number(item.style.width.match(/\d+(\.\d+)?/)[0])/img.width,
scaleY: Number(item.style.height.match(/\d+(\.\d+)?/)[0])/img.height,
// selectable: false
});
img.id = item.id
canvas.add(img);
canvasFontBackMove.back.forEach((backItem) => {
if(backItem && backItem.id == item.id){
img.on('moving', function() {
// 计算第二个矩形应该移动的距离
// 更新第二个矩形的位置
backItem.img.set({
left: img.left,
top: img.top,
width: img.width,
height: img.height,
scaleX: img.scaleX,
scaleY: img.scaleY,
});
});
img.on('scaling', function(e) {
backItem.img.set({
left: img.left,
top: img.top,
width: img.width,
height: img.height,
scaleX: img.scaleX,
scaleY: img.scaleY,
});
});
canvas.renderAll();
}
})
canvasFontBackMove.front.push({id:item.id,img:img})
});
});
var objects = canvas.getObjects();
}
let clothesOpen = (item,index)=>{
setpitch(item,index)
designShowIndex.value = index
}
let setpitch = (item,index)=>{
canvas.discardActiveObject();
// this.designItemDetail.clothes.forEach((item)=>{
// item.clothesOpen = false
// })
// this.designItemDetail.clothes[index].clothesOpen = true
for (const iterator in canvasFontBackMove) {
canvasFontBackMove[iterator].forEach((canvasItem,canvasIndex) => {
if(canvasItem.id == item.id){
// var rect1Index = canvas.getObjects().indexOf(canvasItem.img);
if(iterator == 'front'){
canvas.moveTo(canvasItem.img,canvas.getObjects().length)
canvas.setActiveObject(canvasItem.img);
}else{
canvas.moveTo(0)
// canvas.moveTo(canvasItem.img,canvasFontBackMove[iterator].length-1)
}
}
});
}
// canvas.setDepth(object1, canvas.getObjects().indexOf(object2) + 1);
}
let imgClear = ()=>{
frontBack = JSON.parse(JSON.stringify(frontBackOld))
setCanvas(frontBack)
}
return {
designItemDetail,
current,
printZIndex,
designShowIndex,
frontBack,
setRevocation,
frontBackOld,
canvasFontBackMove,
setImgSize,
clothesOpen,
imgClear,
};
},
data() {
return {
loadingShow:false,//加载中
store: useStore(),
};
},
mounted () {
},
methods: {
init(){
this.setImgSize()
},
//按比设置单件衣服宽高位置
async setPostition(url){
let img = await loadImage(url)
let modal_body = document.getElementsByClassName('designOpenrtion_imgMask')[0]
const num = modal_body?.offsetHeight / img.height;
function loadImage(url) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => {
resolve(img)
};
img.onerror = reject;
img.src = url;
});
}
return num
},
capitalizeFirstLetter(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
},
setPreviewData(){
this.$emit('setSubmit','preview');
},
deleteBorder(){
this.frontBack?.front?.forEach((item)=>{
item.designOpenrtionBtn = false
})
},
clothesOpenActive(index){
},
sort(arr){
arr.sort((a, b) => {
var a_num = a.style.zIndex;
var b_num = b.style.zIndex;
return a_num - b_num;
});
return arr
},
async setPreview(data){
let ratio = this.frontBack.body.layersObject[0].imageSize[0]/this.frontBack.body.style.width.replace(/px/g,'')
let designItemDetail = this.store.state.DesignDetailModule.designItemDetail
// this.frontBack.back.sort((a, b) => {
// var a_num = a.style.zIndex;
// var b_num = b.style.zIndex;
// return a_num - b_num;
// });
let arr = this.sort(JSON.parse(JSON.stringify(this.frontBack.front)))
let num = 10
arr.forEach((item)=>{
item.priority = num++
item.similarity = false//新增衣服传的是衣服id会存在两件衣服id相同所以设置为false让每次赋值都是不一样的
})
data.designSingleItemDTOList.forEach((item)=>{
let front = arr
let imageCategory1
if(arr.length > 1){
imageCategory1 = arr[1].imageCategory
}
for (let index = 0; index < arr.length; index++) {
if(item.id == arr[index].id && !arr[index].similarity){
let y = ((arr[index]?.style?.top.replace(/px/g,'')*ratio).toFixed(0) - arr[index]?.position[0])
let x = ((arr[index]?.style?.left.replace(/px/g,'')*ratio).toFixed(0) - arr[index]?.position[1])
let scale = arr[index]?.imageSize?Number(((arr[index]?.style?.width.replace(/px/g,'')*ratio)/(arr[index]?.imageSize[0]/arr[index].scale)).toFixed(2)):1
item.scale = scale
let top = y == 0 ? item.offset[1]:y+item.offset[1]
let left = x == 0 ? item.offset[0]:x+item.offset[0]
item.offset = [left,top]
item.priority = arr[index].priority
arr[index].similarity = true
// item.offset = [(arr[index]?.style?.left.replace(/px/g,'')*ratio).toFixed(0),(i?.style?.top.replace(/px/g,'')*ratio).toFixed(0)]
break
}
}
if(arr.length > 1 && item.type == this.capitalizeFirstLetter(imageCategory1)){
item.scale = front?.imageSize?Number(((front?.style?.width.replace(/px/g,'')*ratio)/front?.imageSize[0]).toFixed(2)):1
}
})
// return
Https.axiosPost(Https.httpUrls.designSingle, data).then(
(rv) => {
this.$parent.loadingShow = false
let designItemDetail = JSON.parse(JSON.stringify(this.store.state.DesignDetailModule.designItemDetail))
rv.clothes.forEach((i)=>{
i.similarity = false//新增衣服传的是衣服id会存在两件衣服id相同所以设置为false让每次赋值都是不一样的
})
designItemDetail.designItemUrl = rv.designItemUrl
designItemDetail.ifSubmit = true
designItemDetail.currentFullBodyView = rv.currentFullBodyView
designItemDetail.clothes.forEach((item)=>{
for (let index = 0; index < rv.clothes.length; index++) {
if(rv.clothes[index].id === item.id && !rv.clothes[index].similarity){
item.layersObject = rv.clothes[index].layersObject
item.priority = rv.clothes[index].layersObject[0].priority
rv.clothes[index].similarity = true
break
}
}
})
this.$emit('setDesignCoverage');
this.store.commit("setDesignItemDetail", designItemDetail);
this.setRevocation(designItemDetail,data)
}
).catch(res=>{
});
},
},
});
</script>
<style lang="less" scoped>
.designOpenrtion_modal {
// max-width: 1440px;
.ant-modal-body{
padding: calc(5rem*1.2) calc(6rem*1.2) calc(0rem*1.2)!important;
// height: calc(65vh - 6.4rem*1.2));
height: calc(65rem*1.2);
display: flex;
overflow-y: hidden;
flex-direction: column;
}
.ant-modal-content{
border-radius: calc(1rem*1.2);
overflow: hidden;
}
}
.design_compile_content {
// background: #f2f3fb;
// padding-bottom: 2.9rem*1.2);
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
.designOpenrtion_centent{
flex: 1;
display: flex;
flex-direction: column;
align-content: space-around;
flex-wrap: nowrap;
margin: 0 auto;
overflow: hidden;
justify-content: space-between;
position: relative;
user-select:none;
z-index: 2;
position: relative;
&.active{
flex-direction: row;
}
.designOpenrtion_imgMask{
width: auto;
height: auto;
position: relative;
height: 100%;
overflow: hidden;
margin: 0 auto;
>img{
z-index: 2;
position: relative;
}
>div{
position: absolute;
width: 100%;
height: 100%;
top: 0;
}
}
.detail_modal_body_nav{
display: flex;
position: relative;
top: 0;
left: 50%;
z-index: 999;
transform: translate(-50%,-0%);
transition: all .3s;
justify-content: center;
margin-bottom: calc(1rem*1.2);
>div{
width: calc(4rem*1.2);
height: calc(4rem*1.2);
cursor: pointer;
text-align: center;
margin-left: calc(.3rem*1.2);
img{
// width: 100%;
height: 100%;
max-width: 100%;
object-fit: cover;
}
&.active{
border: 2px solid rgba(0,0,0,0.4);
img{
transform: scale(.8);
opacity: .8;
}
}
}
>div:nth-child(1){
margin-left: calc(0rem*1.2);
}
}
.designOpenrtion_print,.detail_modal_item_front{
z-index: 1;
img{
width: 100%;
height: 100%;
float: left;
user-select:none;
-webkit-user-drag: none;
}
.modal_imgItem{
position: absolute;
overflow: hidden;
top: 0;
}
}
.designOpenrtion_print{
z-index: 1 !important;
}
.designOpenrtion_btn{
z-index: 9999;
ul{
list-style: none;
// width: 100%;
// height: 100%;
position: absolute;
top: 0;
left: 0;
box-sizing: border-box;
border: 2px solid rgb(20, 188, 255);
padding: 0;
-webkit-user-drag: none;
user-select:none;
opacity: 0;
margin: 0;
li{
cursor: pointer;
// border-radius: 50%;
width: calc(1rem*1.2);
height: calc(1rem*1.2);
background-color: rgb(20, 188, 255);
position: absolute;
pointer-events: none;
}
&.active{
opacity: 1;
li{
pointer-events: auto;
}
}
.designOpenrtion_btn_top,.designOpenrtion_btn_bottom{
left: 50%;
transform: translate(-50%,-50%) ;
cursor: n-resize;
}
.designOpenrtion_btn_top{
top: 0;
}
.designOpenrtion_btn_bottom{
top: 100%;
}
.designOpenrtion_btn_left,.designOpenrtion_btn_right{
top: 50%;
transform: translate(-50%,-50%) ;
cursor: e-resize;
}
.designOpenrtion_btn_left{
left: 0;
}
.designOpenrtion_btn_right{
left: 100%;
}
.designOpenrtion_rotote{
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
width: 0;
height: 0;
}
.designOpenrtion_rotote::after{
position: absolute;
content: "";
background-color: #14bcff;
width: 2px;
height: 30px;
left: 50%;
bottom: 0;
transform: translateX(-50%);
}
.designOpenrtion_rotote::before{
position: absolute;
content: "";
background-color: #14bcff;
top: calc(50% - 30px);
left: 50%;
transform: translate(-50%,-50%) ;
width: calc(1.5rem*1.2);
height: calc(1.5rem*1.2);
border-radius: 50%;
}
}
}
.subitOkPreviewBtn{
z-index: 2;
margin-bottom: calc(1rem*1.2);
width: calc(10rem*1.2);
text-align: center;
bottom: 0;
position: relative;
}
}
.designOpenrtion_imgMask_open{
position: absolute;
width: 100%;
height: 100%;
}
}
</style>

View File

@@ -1,685 +0,0 @@
<template>
<div class="design_compile_content" id="design_compile_content">
<div class="designOpenrtion_centent" id="designOpenrtionCentent">
<div class="detail_modal_body_nav">
<div v-for="item,index in designItemDetail?.clothes" v-show="item.id" :class="{active:item.clothesOpen}" @click="clothesOpen(index)">
<img :src="item?.path" alt="">
</div>
</div>
<div class="designOpenrtion_imgMask" :style="frontBack?.body?.style">
<!-- <div
v-for="item,index in frontBack.back"
:key="item"
:style="item.style"
@touchstart.passive="itemMoveMousedown(index,$event)"
class="modal_imgItem"
@click="setpitch(item,index)" ref="content" >
<img crossOrigin="anonymous" :src="item.path" class="designOpenrtion_imgItme" draggable="false">
</div> -->
<div class="designOpenrtion_print" v-for="item,index in frontBack.back" @touchstart.passive="itemMoveMousedown(index,$event)" @click="setpitch(item,index)" :style="frontBack.front[index].style">
<img :style="item.imageUrl?'':'display:none;'" :src="item.imageUrl" alt="">
</div>
<img class="perview_img" :style="'width:'+ frontBack?.body?.layersObject?.[0].imageSize?.[0] +';height:' + frontBack?.body?.layersObject?.[0].imageSize?.[0] +';'" v-lazy="frontBack?.body?.layersObject?.[0].imageUrl || ''" :key="designItemDetail.designItemUrl">
<div class="detail_modal_item_front" v-for="item,index in frontBack.front" @touchstart.passive="itemMoveMousedown(index,$event)" @click="setpitch(item,index)" :style="item.style">
<img :src="item.imageUrl" alt="">
</div>
<div class="designOpenrtion_btn">
<ul v-for="item,index in frontBack.front" :key="item" :class="{active:item.designOpenrtionBtn}" class="designOpenrtion_btn" :style="item.style" @touchstart.passive="itemMoveMousedown(index,$event)">
<li class="designOpenrtion_btn_top" @touchstart.passive="itemSizeMousedown('top',$event)"></li>
<li class="designOpenrtion_btn_bottom" @touchstart.passive="itemSizeMousedown('bottom',$event)"></li>
<li class="designOpenrtion_btn_left" @touchstart.passive="itemSizeMousedown('left',$event)"></li>
<li class="designOpenrtion_btn_right" @touchstart.passive="itemSizeMousedown('right',$event)"></li>
<!-- <li class="designOpenrtion_rotote" v-rotote.stop="[index,item.transform]"></li> -->
</ul>
</div>
</div>
<div class="subitOkPreviewBtn" @click="imgClear">{{ $t('LibraryPage.Reset') }}</div>
<div @click="setPreviewData" class="subitOkPreviewBtn">OK</div>
</div>
<div class="designOpenrtion_imgMask_open" @click.stop="deleteBorder"></div>
</div>
</template>
<script >
import { defineComponent, h,createVNode, ref ,computed, inject,nextTick} from "vue";
import { useStore } from "vuex";
import { Https } from "@/tool/https";
export default defineComponent({
// props: ["frontBack"],
emits:['setParentLoadingShow','setDesignCoverage','setSubmit'],
setup(prop) {
const store = useStore();
let designItemDetail = computed(()=>{
return store.state.DesignDetailModule.designItemDetail
})
let current = inject('current')//父组件传过来的数据
let setRevocation = inject('setRevocation')//父组件传过来的数据
let printZIndex = ref(4)//印花优先级
let printStyleList = ref([
{
centers:{
left:0,
top:0,
},
style:{
left:0+"px",
top:0+"px",
right:"auto",
bottom:"auto",
width:100+'px',
height:100+'px',
// zIndex:1,
},
transform:{
scale:1,
rotateZ:0,
},
designOpenrtionBtn:false
}
]);
let direction = ref('')
let imgDom = ref()
let imgDomIndex = ref(0)
let frontBack = ref({})
let frontBackOld = ref({})
return {
designItemDetail,
current,
printZIndex,
printStyleList,
direction,//判断点击的是li那个边
imgDom,
imgDomIndex,
frontBack,
setRevocation,
frontBackOld
};
},
data() {
return {
loadingShow:false,//加载中
store: useStore(),
setImgSizeTimeout:null
};
},
mounted () {
window.addEventListener('resize', this.setImgSizeTime);
},
methods: {
init(){
let DesignParent = this.$parent
// this.clearModal()
// console.log(this.current,DesignParent.frontBack);
this.printStyleList.push({
centers:{
left:0,
top:0,
},
style:{
left:0+"px",
top:0+"px",
right:"auto",
bottom:"auto",
width:100+'px',
height:100+'px',
// zIndex:1,
},
transform:{
scale:1,
rotateZ:0,
},
designOpenrtionBtn:false
})
this.setImgSize()
},
setImgSizeTime(){
clearTimeout(this.setImgSizeTimeout)
this.setImgSizeTimeout = setTimeout(()=>{
this.setImgSize()
},300)
},
async setImgSize(){
this.frontBack.body = null
let designItemDetail = JSON.parse(JSON.stringify(this.store.state.DesignDetailModule.designItemDetail))
let front = []
let back = []
let body
designItemDetail.others.forEach((item) => {
if(item.type == 'Body'){
body = item
}
});
let ratio = await this.setPostition(body.layersObject[0]?.imageUrl)
let frontIndex = 6
let backIndex = 3
// let front = 3
// let back = 3
designItemDetail.clothes.forEach((v,index)=>{
for (let i = v.layersObject.length-1; i >= 0; i--) {
v.layersObject[i].style = {
top:v.layersObject[i].position?.[0]*ratio+'px',
left:v.layersObject[i].position?.[1]*ratio+'px',
width:v.layersObject[i].imageSize?.[0]*ratio+'px',
height:v.layersObject[i].imageSize?.[1]*ratio+'px',
// zIndex:zIndex-=1
}
v.layersObject[i].centers={
left:0,
top:0,
}
v.layersObject[i].designOpenrtionBtn = false
if(v.layersObject[i].imageCategory.indexOf("back") == -1){
front[index] = v.layersObject[i]
front[index].style.zIndex = v.priority
front[index].id = v.id
}else{
back[index] = v.layersObject[i]
back[index].style.zIndex = v.priority
back[index].id = v.id
// back[index].style.zIndex = backIndex==0?v.layersObject[i]:backIndex++
}
if(this.printZIndex < v.priority){
this.printZIndex = v.priority
}
}
this.printZIndex++
})
let bodyImgWH = document.getElementsByClassName("design_compile_content")[0].getElementsByClassName("perview_img")[0]
body.style = {
width:body.layersObject[0].imageSize?.[0]*ratio+'px',
height:body.layersObject[0].imageSize?.[1]*ratio+'px',
}
this.frontBack = {
front:front,
back:back,
body:body,
}
this.frontBackOld = JSON.parse(JSON.stringify({
front:front,
back:back,
body:body,
}))
},
imgClear(){
this.frontBack = JSON.parse(JSON.stringify(this.frontBackOld))
},
//按比设置单件衣服宽高位置
async setPostition(url){
let img = await loadImage(url)
let modal_body = document.getElementsByClassName('designOpenrtion_imgMask')[0]
const num = modal_body?.offsetHeight / img.height;
function loadImage(url) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => {
resolve(img)
img.remove()
};
img.onerror = reject;
img.src = url;
});
}
return num
},
clear(){
window.removeEventListener('resize', this.setImgSizeTime);
},
setpitch(item,index){
this.frontBack.front.forEach((v)=>{
v.designOpenrtionBtn = false
})
this.frontBack.front[index].designOpenrtionBtn = true
this.frontBack.front[index].style.zIndex = this.printZIndex++
this.frontBack.back[index].style.zIndex = this.printZIndex
this.clothesOpenActive(index)
},
// 设置移动
itemMoveMousedown(index,e){
this.imgDomIndex = index
this.frontBack.front.forEach((v)=>{
v.designOpenrtionBtn = false
})
this.clothesOpenActive(index)
let event = e||window.event
this.imgDom = document.getElementsByClassName('design_compile_content')[0].getElementsByClassName("detail_modal_item_front")[this.imgDomIndex]
this.frontBack.front[index].designOpenrtionBtn = true
this.frontBack.front[index].style.zIndex = this.printZIndex++
this.frontBack.back[index].style.zIndex = this.printZIndex
let imgDomWH = this.imgDom.getBoundingClientRect()
let left = Number(this.frontBack.front[index].style.left.replace(/px/g,''))
let top = Number(this.frontBack.front[index].style.top.replace(/px/g,''))
this.frontBack.front[index].centers.left = imgDomWH.x+event.changedTouches[0].pageX - this.imgDom.getBoundingClientRect().left-left
this.frontBack.front[index].centers.top = imgDomWH.y+event.changedTouches[0].pageY - this.imgDom.getBoundingClientRect().top-top
document.addEventListener("touchend", this.touchend);
document.addEventListener("touchmove", this.moveMousemove);
},
//设置尺寸
itemSizeMousedown(direction,event){
this.direction = direction
this.imgDom = document.getElementsByClassName('design_compile_content')[0].getElementsByClassName("detail_modal_item_front")[this.imgDomIndex]
this.frontBack.front[this.imgDomIndex].designOpenrtionBtn = true
let imgDomWH = this.imgDom.getBoundingClientRect()
let li = document.getElementsByClassName('design_compile_content')[0].getElementsByClassName("designOpenrtion_btn_top")[0].offsetWidth/2
if(this.direction == 'right' || this.direction == 'bottom'){
this.frontBack.front[this.imgDomIndex].centers.left = imgDomWH.x+event.changedTouches[0].pageX - this.imgDom.getBoundingClientRect().left-li
this.frontBack.front[this.imgDomIndex].centers.top = imgDomWH.y+event.changedTouches[0].pageY - this.imgDom.getBoundingClientRect().top-li
}else{
this.frontBack.front[this.imgDomIndex].centers.left = imgDomWH.x+event.changedTouches[0].pageX - this.imgDom.getBoundingClientRect().left+imgDomWH.width-li
this.frontBack.front[this.imgDomIndex].centers.top = imgDomWH.y+event.changedTouches[0].pageY - this.imgDom.getBoundingClientRect().top+imgDomWH.height-li
this.frontBack.front[this.imgDomIndex].centers.right = this.imgDom.parentNode.offsetWidth -imgDomWH.width - this.imgDom.offsetLeft
this.frontBack.front[this.imgDomIndex].centers.bottom = this.imgDom.parentNode.offsetHeight -imgDomWH.height - this.imgDom.offsetTop
}
document.addEventListener("touchend", this.sizeMouseup);
document.addEventListener("touchmove", this.sizeMousemove);
},
//鼠标移动
moveMousemove(e) {
let imgDomWH = this.imgDom.getBoundingClientRect()
let parentNode = document.getElementsByClassName('design_compile_content')[0].getElementsByClassName("designOpenrtion_imgMask")[0].getBoundingClientRect()
let x = (e.changedTouches[0].pageX - this.frontBack.front[this.imgDomIndex].centers.left)+'px'
let y = ( e.changedTouches[0].pageY - this.frontBack.front[this.imgDomIndex].centers.top)+'px'
this.frontBack.front[this.imgDomIndex].style.left = x
this.frontBack.front[this.imgDomIndex].style.top = y
// if(x.replace(/px/g,'') >= parentNode.width - imgDomWH.width){
// this.frontBack.front[this.imgDomIndex].style.left = parentNode.width - imgDomWH.width+'px'
// }
// if(x.replace(/px/g,'') <= 0){
// this.frontBack.front[this.imgDomIndex].style.left = 0+'px'
// }
// if(y.replace(/px/g,'') >= parentNode.height - imgDomWH.height){
// this.frontBack.front[this.imgDomIndex].style.top = parentNode.height - imgDomWH.height+'px'
// }
// if(y.replace(/px/g,'') <= 0){
// this.frontBack.front[this.imgDomIndex].style.top = 0+'px'
// }
},
sizeMousemove(e) {
let imgDomWH = this.imgDom.getBoundingClientRect()
let parentNode =this.imgDom.parentNode
let width = imgDomWH.width
let height = imgDomWH.height
let w,h
let num = height/width
//判断移动四个边
if(this.direction == 'right'){
w = (e.changedTouches[0].pageX -imgDomWH.left)
h = (e.changedTouches[0].pageX -imgDomWH.left)*num
width = w+'px'
// height = w*num+'px'
}else if(this.direction == 'top'){
num = width/height
this.frontBack.front[this.imgDomIndex].style.top = 'auto'
// this.printStyleList[this.imgDomIndex].style.left = 'auto'
// this.frontBack.front[this.imgDomIndex].style.bottom = parentNode.offsetHeight -this.imgDom.offsetHeight - this.imgDom.offsetTop+'px'
this.frontBack.front[this.imgDomIndex].style.bottom = this.frontBack.front[this.imgDomIndex].centers.bottom+'px'
w = (e.changedTouches[0].pageX -imgDomWH.left)*num
h = (this.frontBack.front[this.imgDomIndex].centers.top - e.changedTouches[0].pageY)
height = h+'px'
// width = h*num+'px'
}else if(this.direction == 'bottom'){
num = width/height
h = (e.changedTouches[0].pageY -imgDomWH.top)
height = h+'px'
// width = h*num+'px'
}else if(this.direction == 'left'){
w = (this.frontBack.front[this.imgDomIndex].centers.left - e.changedTouches[0].pageX)
this.frontBack.front[this.imgDomIndex].style.left = 'auto'
this.frontBack.front[this.imgDomIndex].style.right = this.frontBack.front[this.imgDomIndex].centers.right+'px'
width = w+'px'
// height = w*num+'px'
}
//判断尺寸是否到边
this.frontBack.front[this.imgDomIndex].style.width = width
this.frontBack.front[this.imgDomIndex].style.height = height
},
//鼠标抬起
sizeMouseup(e){
this.frontBack.front[this.imgDomIndex].style={
right:'auto',
left:this.imgDom.offsetLeft+'px',
bottom:'auto',
top:this.imgDom.offsetTop+'px',
height:this.imgDom.offsetHeight+'px',
width:this.imgDom.offsetWidth+'px',
zIndex:this.printZIndex
}
this.frontBack.back[this.imgDomIndex].style.zIndex = this.printZIndex
document.removeEventListener("touchend", this.sizeMouseup);
document.removeEventListener("touchmove", this.sizeMousemove);
},
touchend(e) {
document.removeEventListener("touchend", this.touchend);
document.removeEventListener("touchmove", this.moveMousemove);
},
clearModal(){
this.printZIndex = 2//点击图片z-index
this.imgDomIndex = 0//点击图片下标
this.clothes = []
this.printStyleList.splice(1,this.printStyleList.length-1)
},
capitalizeFirstLetter(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
},
setPreviewData(){
this.$emit('setSubmit','preview');
},
deleteBorder(){
this.frontBack?.front?.forEach((item)=>{
item.designOpenrtionBtn = false
})
},
clothesOpen(index){
this.imgDomIndex = index
this.clothesOpenActive(index)
this.setpitch('',index)
},
clothesOpenActive(index){
this.designItemDetail.clothes.forEach((item)=>{
item.clothesOpen = false
})
this.designItemDetail.clothes[index].clothesOpen = true
},
sort(arr){
arr.sort((a, b) => {
var a_num = a.style.zIndex;
var b_num = b.style.zIndex;
return a_num - b_num;
});
return arr
},
async setPreview(data){
let ratio = this.frontBack.body.layersObject[0].imageSize[0]/this.frontBack.body.style.width.replace(/px/g,'')
let designItemDetail = this.store.state.DesignDetailModule.designItemDetail
// this.frontBack.back.sort((a, b) => {
// var a_num = a.style.zIndex;
// var b_num = b.style.zIndex;
// return a_num - b_num;
// });
let arr = this.sort(JSON.parse(JSON.stringify(this.frontBack.front)))
let num = 10
arr.forEach((item)=>{
item.priority = num++
})
data.designSingleItemDTOList.forEach((item)=>{
let front = arr
let imageCategory1
if(arr.length > 1){
imageCategory1 = arr[1].imageCategory
}
arr.forEach((i)=>{
if(item.id == i.id){
let y = ((i?.style?.top.replace(/px/g,'')*ratio).toFixed(0) - i?.position[0])
let x = ((i?.style?.left.replace(/px/g,'')*ratio).toFixed(0) - i?.position[1])
// let scale = i?.imageSize?Number(((i?.style?.width.replace(/px/g,'')*ratio)/(i?.imageSize[0]/i.scale)).toFixed(2)):1
let scaleWidth = i?.imageSize?Number(((i?.style?.width.replace(/px/g,'')*ratio)/(i?.imageSize[0]/i.scale[0])).toFixed(2)):1
let scaleHeight = i?.imageSize?Number(((i?.style?.height.replace(/px/g,'')*ratio)/(i?.imageSize[1]/i.scale[1])).toFixed(2)):1
item.scale = [scaleWidth,scaleHeight]
let top = y == 0 ? item.offset[1]:y+item.offset[1]
let left = x == 0 ? item.offset[0]:x+item.offset[0]
item.offset = [left,top]
item.priority = i.priority
// item.offset = [(i?.style?.left.replace(/px/g,'')*ratio).toFixed(0),(i?.style?.top.replace(/px/g,'')*ratio).toFixed(0)]
}
})
if(arr.length > 1 && item.type == this.capitalizeFirstLetter(imageCategory1)){
item.scale = front?.imageSize?Number(((front?.style?.width.replace(/px/g,'')*ratio)/front?.imageSize[0]).toFixed(2)):1
}
})
Https.axiosPost(Https.httpUrls.designSingle, data).then(
(rv) => {
let designItemDetail = JSON.parse(JSON.stringify(this.store.state.DesignDetailModule.designItemDetail))
designItemDetail.designItemUrl = rv.designItemUrl
designItemDetail.ifSubmit = true
designItemDetail.currentFullBodyView = rv.currentFullBodyView
rv.clothes.forEach((item)=>{
designItemDetail.clothes.forEach((i)=>{
if(item.id === i.id){
i.layersObject = item.layersObject
i.priority = item.layersObject[0].priority
}
})
})
this.$emit('setDesignCoverage');
this.store.commit("setDesignItemDetail", designItemDetail);
this.setRevocation(designItemDetail,data)
this.clear()
}
).catch(res=>{
this.$emit('setParentLoadingShow');
});
},
},
});
</script>
<style lang="less" scoped>
.designOpenrtion_modal {
// max-width: 1440px;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
.ant-modal-body{
padding: calc(5rem*1.2) calc(6rem*1.2) calc(0rem*1.2)!important;
// height: calc(65vh - 6.calc(4rem*1.2));
height: calc(65rem*1.2);
display: flex;
overflow-y: hidden;
flex-direction: column;
}
.ant-modal-content{
border-radius: calc(1rem*1.2);
overflow: hidden;
}
}
.design_compile_content {
// background: #f2f3fb;
// padding-bottom: 2.calc(9rem*1.2);
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
.designOpenrtion_centent{
// flex: 1;
height: 100%;
display: flex;
flex-direction: column;
align-content: space-around;
flex-wrap: nowrap;
margin: 0 auto;
// overflow: hidden;
justify-content: space-between;
position: relative;
user-select:none;
z-index: 2;
position: relative;
&.active{
flex-direction: row;
}
.designOpenrtion_imgMask{
width: auto;
height: auto;
position: relative;
// height: 100%;
// overflow: hidden;
height: calc(100% - 1.2rem - 4.8rem - 20%);
margin: 0 auto;
>img{
z-index: 2;
position: relative;
}
>div{
position: absolute;
width: 100%;
height: 100%;
top: 0;
}
}
.detail_modal_body_nav{
display: flex;
position: relative;
top: 0;
left: 50%;
z-index: 999;
transform: translate(-50%,-0%);
transition: all .3s;
justify-content: center;
margin-bottom: calc(1rem*1.2);
>div{
width: calc(4rem*1.2);
height: calc(4rem*1.2);
cursor: pointer;
text-align: center;
margin-left: calc(.3rem*1.2);
img{
// width: 100%;
height: 100%;
max-width: 100%;
object-fit: cover;
}
&.active{
border: 2px solid rgba(0,0,0,0.4);
img{
transform: scale(.8);
opacity: .8;
}
}
}
>div:nth-child(1){
margin-left: calc(0rem*1.2);
}
}
.designOpenrtion_print,.detail_modal_item_front{
z-index: 1;
img{
width: 100%;
height: 100%;
float: left;
user-select:none;
-webkit-user-drag: none;
}
.modal_imgItem{
position: absolute;
overflow: hidden;
top: 0;
}
}
.designOpenrtion_print{
z-index: 1 !important;
}
.designOpenrtion_btn{
z-index: 9999;
ul{
list-style: none;
// width: 100%;
// height: 100%;
position: absolute;
top: 0;
left: 0;
box-sizing: border-box;
border: 2px solid rgb(20, 188, 255);
padding: 0;
-webkit-user-drag: none;
user-select:none;
opacity: 0;
margin: 0;
li{
cursor: pointer;
// border-radius: 50%;
width: calc(1.5rem*1.2);
height: calc(1.5rem*1.2);
padding: calc(1rem*1.2);
background-color: rgb(20, 188, 255);
position: absolute;
pointer-events: none;
z-index: 2;
}
&.active{
opacity: 1;
li{
pointer-events: auto;
}
}
.designOpenrtion_btn_top,.designOpenrtion_btn_bottom{
left: 50%;
transform: translate(-50%,-50%) ;
cursor: n-resize;
}
.designOpenrtion_btn_top{
top: 0;
}
.designOpenrtion_btn_bottom{
top: 100%;
}
.designOpenrtion_btn_left,.designOpenrtion_btn_right{
top: 50%;
transform: translate(-50%,-50%) ;
cursor: e-resize;
}
.designOpenrtion_btn_left{
left: 0;
}
.designOpenrtion_btn_right{
left: 100%;
}
.designOpenrtion_rotote{
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
width: 0;
height: 0;
}
.designOpenrtion_rotote::after{
position: absolute;
content: "";
background-color: #14bcff;
width: 2px;
height: 30px;
left: 50%;
bottom: 0;
transform: translateX(-50%);
}
.designOpenrtion_rotote::before{
position: absolute;
content: "";
background-color: #14bcff;
top: calc(50% - 30px);
left: 50%;
transform: translate(-50%,-50%) ;
width: calc(1.5rem*1.2);
height: calc(1.5rem*1.2);
border-radius: 50%;
}
}
}
.subitOkPreviewBtn{
z-index: 2;
margin-bottom: calc(1rem*1.2);
width: calc(10rem*1.2);
text-align: center;
bottom: 0;
position: relative;
}
}
.designOpenrtion_imgMask_open{
position: absolute;
width: 100%;
height: 100%;
}
}
</style>

View File

@@ -0,0 +1,268 @@
<template>
<div ref="designDetailModal" class="designDetailModal">
<!-- designDetailShow -->
<!-- :class="[driver__.driver?'hideEvents':'']" -->
<a-modal class="Guide_1_18 generalModel fullScreen"
v-model:visible="designDetailShow"
:footer="null"
:get-container="() => $refs.designDetailModal"
width="100%"
height="100%"
:maskClosable="false"
:mask="false"
:centered="true"
:keyboard="false"
:closable="false"
>
<div class="content">
<div class="nav">
<div class="back_home">
<div class="gallery_btn" @click="closeModal()">
<i class="fi fi-rs-house-chimney"></i>
</div>
</div>
<div class="nav_list">
<div class="nav_item active">
<img src="@/assets/images/icon/details_sketch.png" alt="">
<div class="detailText">Apparel</div>
</div>
<div class="nav_item">
<img src="@/assets/images/icon/details_print.png" alt="">
<div class="detailText">Print</div>
</div>
<div class="nav_item">
<img src="@/assets/images/icon/details_color.png" alt="">
<div class="detailText">Color</div>
</div>
<div class="nav_item">
<img src="@/assets/images/icon/details_elements.png" alt="">
<div class="detailText">Elements</div>
</div>
</div>
</div>
<div class="item">
<sketchLeft></sketchLeft>
</div>
<div class="item">
<model></model>
</div>
<div></div>
<div class="gallery_btn submit">Submit</div>
</div>
</a-modal>
<div class="mark_loading" v-show="loadingShow">
<a-spin size="large" />
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,onBeforeUnmount,provide,nextTick,createVNode,toRefs, reactive} from 'vue'
import sketchLeft from './sketchLeft.vue'
import model from './model/index.vue'
// import setDesignItem from '@/component/Detail/setDesignItem2.vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
import { Modal,message } from 'ant-design-vue';
import {getUploadUrl,isMoible,setGradual} from '@/tool/util'
import { useStore } from "vuex";
import { openGuide,driverObj__ } from "@/tool/guide";
import { useI18n } from 'vue-i18n'
import addDetails from '@/component/Detail/addDetails.vue'
export default defineComponent({
components:{
sketchLeft,model
},
setup() {
const store = useStore();
const userDetail = computed(()=>{
return store.state.UserHabit.userDetail
})
const detailData = reactive({
designDetail:store.state.DesignDetailCopy.designDetail,
designDetailShow:false,
loadingShow:false,
})
const closeModal = ()=>{
detailData.designDetailShow = false
}
const showDesignDetailModal = (data:any,str:any)=>{
// this.moible = isMoible()
// this.designItemId = data.design.designItemId
// this.designOutfitId = data.design.designOutfitId
let url = Https.httpUrls.getDesignDetail + `?designItemId=${data.design.designItemId}&designPythonOutfitId=${data.design.designOutfitId}`
// let url = Https.httpUrls.getDesignDetail + `?designItemId=61204&designPythonOutfitId=60908`
// this.parentData = data
detailData.loadingShow = true
Https.axiosGet(url).then(
async (rv: any) => {
rv.clothes.forEach((item:any)=>{
let a
item.designType='Library'
if(item.layersObject[0].imageCategory.indexOf("back") == -1){
a = item.layersObject[0]
item.layersObject[0] = item.layersObject[1]
item.layersObject[1] = a
}
if(item.printObject.prints == null)item.printObject.prints = []
item.printObject.prints.forEach((element:any) => {
if(!element.designType){
element.designType = 'Library'
}
});
})
detailData.designDetailShow = true
store.commit('designDeatailCopy/setDesignDetail',rv)
// this.deleteShow = false
setRevocation(rv,'')
// if(rv.singleOverall == 'overall'){
// this.body = false
// }else{
// this.body = true
// }
// await this.setImgSize()
// this.generateHighDesignImg = rv.highDesignUrl
// this.designDetailShow = true
detailData.loadingShow = false
// await this.setImgSize()
}
).catch(rv=>{
detailData.loadingShow = false
})
}
const initialize = ()=>{//design后初始化
sessionStorage.removeItem('oppositeRevocation')
sessionStorage.removeItem('revocation')
}
const setRevocation = (designItemDetail:any,data:any)=>{//设置撤销
}
onBeforeUnmount(()=>{
detailData.designDetail = null
})
return{
...toRefs(detailData),
closeModal,
showDesignDetailModal,
}
},
provide() {
return {
}
},
mounted(){
let beforeunload = () => {
window.removeEventListener('beforeunload',beforeunload)
}
window.addEventListener('beforeunload',beforeunload)
// let url = Https.httpUrls.getDesignDetail + `?designItemId=34242&designPythonOutfitId=34004`
// this.loadingShow = true
// Https.axiosGet(url).then(
// async (rv: any) => {
// rv.clothes.forEach((item:any)=>{
// let a
// if(item.layersObject[0].imageCategory.indexOf("back") == -1){
// a = item.layersObject[0]
// item.layersObject[0] = item.layersObject[1]
// item.layersObject[1] = a
// }
// if(item.printObject.prints == null){
// item.printObject.prints = [{}]
// }
// })
// this.store.commit('setDesignItemDetail',rv)
// if(rv.others[0].printObject.path == null){
// this.body = false
// }else{
// this.body = true
// }
// this.setImgSize()
// this.generateHighDesignImg = rv.highDesignUrl
// this.designShowPrview = 1
// this.designDetailShow = true
// this.loadingShow = false
// }
// ).catch(rv=>{
// this.loadingShow = false
// })
},
})
</script>
<style lang="less" scoped>
:deep(.detailText){
font-size: 1.8rem;
font-weight: 600;
}
.designDetailModal{
position: relative;
top: -100%;
height: 100%;
:deep(.ant-modal-wrap){
position: absolute;
top: 0;
left: 0;
}
.content{
display: flex;
align-items: flex-start;
height: 100%;
width: 100%;
> .item{
height: 100%;
}
> .nav{
margin-right: 5rem;
> .back_home{
width: 9rem;
text-align: center;
> .gallery_btn{
width: 6rem;
height: 6rem;
border-radius: 50%;
}
}
> .nav_list{
margin-top: 2.7rem;
height: 38rem;
width: 9rem;
background: #f4f4f4;
border-radius: 1.4rem;
padding: 1.4rem 0;
> .nav_item{
text-align: center;
width: 100%;
height: calc((38rem - 1.4rem * 2) / 4);
cursor: pointer;
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
> img{
width: 4rem;
height: 3.6rem;
object-fit: contain;
}
&.active{
background: #bdbdbd;
}
}
}
}
> .submit{
margin-left: auto;
}
}
}
</style>

View File

@@ -0,0 +1,221 @@
<template>
<div class="libraryList">
<div class="generalModel_state">
<div class="generalModel_state_item">
<a-select
v-model:value="designType"
:options="designTypeList"
@change="handleChange"
style="width:100%"
size="large"
:fieldNames="{ label: 'name', value: 'value' }"
>
<template #suffixIcon
><span
class="icon iconfont icon-xiala"
style="color: #343579"
></span
></template>
</a-select>
</div>
<div class="generalModel_state_item">
<input class="search_input" :placeholder="$t('DesignDetailAlter.inputContent1')" v-model="searchPictureName" @keydown.enter="getLibraryList()">
<div class="search_icon_block" @click.stop="getLibraryList()"><span class="icon iconfont icon-sousuo"></span></div>
</div>
<!-- clothesPrint -->
</div>
<div class="libraryList_box">
<div class="content_img_item" v-for="(file) in libraryList" :key="file.id">
<div class="content_img_item_block" :class="{active:file?.checked}">
<img v-lazy="file.url" :key="file.url" :alt="file.name" @click.stop="selectImgItem(file)"/>
<sketchCategory :disignTypeList="designTypeList" :generateList="libraryList" :item="file" :isSetSketchCategory="true"></sketchCategory>
</div>
</div>
<div v-show="total > libraryList.length" class="material_content_list_loding" v-observe>
<img src="@/assets/images/homePage/loading.gif" alt="">
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,provide,nextTick,createVNode,toRefs, reactive, onMounted} from 'vue'
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import sketchCategory from "@/component/HomePage/sketchCategory.vue";
export default defineComponent({
components:{
sketchCategory
},
props:{
catecoryList:{
type:Object,
default:()=>[] as any,
required:true
}
},
setup(props,{emit}) {
const store = useStore();
const detailData = reactive({
isShowLoading:false,//懒加载,加载中
libraryList:[],
designTypeList:[] as any,
designType:'',
searchPictureName:'',
})
const getDetailListData = reactive({
total:0,
pageSize:10,
currentPage:1,
})
const init = ()=>{
detailData.designTypeList = props.catecoryList
detailData.designType = detailData.designTypeList[0].value
getLibraryList()
}
const selectImgItem = ()=>{
}
const getLibraryList = ()=>{
detailData.isShowLoading = true
let level2Type = ''
let workspace = store.state.Workspace.workspace
let data = {
level1Type:'Sketchboard',
// level2Type:'Pattern',
level2Type:detailData.designType,
modelSex:workspace?.sex,
page:getDetailListData.currentPage,
pictureName:detailData.searchPictureName,
size:getDetailListData.pageSize+detailData.libraryList.length,
}
Https.axiosPost(Https.httpUrls.queryLibraryPage,data).then(
(rv) => {
rv.content.forEach((vItem:any)=>{
if(props.catecoryList){
props.catecoryList.forEach((item:any) => {
if(item.value == vItem.level2Type){
vItem.categoryValue = item.value
vItem.category = item.name
}
});
}
})
detailData.libraryList = rv.content
detailData.isShowLoading = false
getDetailListData.total = rv.total
}
).catch((res)=>{
detailData.isShowLoading = false
});
}
const handleChange = ()=>{
getDetailListData.currentPage = 1
detailData.libraryList = []
getLibraryList()
}
onMounted(()=>{
// getLibraryList()
})
return{
...toRefs(detailData),
...toRefs(getDetailListData),
init,
selectImgItem,
getLibraryList,
handleChange,
}
},
directives:{
observe:{
mounted (el,binding) {
// console.log(binding.instance);
let callback = (entries:any, observer:any)=> {
entries.forEach((entry:any) => {
if (entry.isIntersecting && !this_.isShowLoading) {
this_.getLibraryList()
} else {
}
});
}
const ob = new IntersectionObserver(callback,{
root:null,
threshold:[.5]
})
ob.observe(el)
// this.currentPage = +=1
// this.pageSize = 12
// currentPage
let this_:any = binding.instance
},
},
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.libraryList{
height: 100%;
display: flex;
flex-direction: column;
> .generalModel_state{
width: 100%;
> .generalModel_state_item{
width: 100%;
margin: 0;
position: relative;
> .search_icon_block{
position: absolute;
right: 5px;
width: calc(6rem - 4px);
height: calc(6rem - 4px);
color: #fff;
background: #000;
border-radius: 50%;
display: flex;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
}
> .generalModel_state_item:last-child{
margin-top: 2rem;
}
}
> .libraryList_box{
width: 100%;
flex: 1;
overflow-y: auto;
display: flex;
flex-wrap: wrap;
margin-top: 1rem;
justify-content: space-between;
align-content: flex-start;
&::-webkit-scrollbar{display: none;}
> .content_img_item{
> .content_img_item_block{
width: calc((34rem - 2rem) / 2);
height: calc((34rem - 2rem) / 2);
position: relative;
margin-bottom: 2rem;
> img{
width: 100%;
height: 100%;
object-fit: contain;
}
}
}
> .material_content_list_loding{
width: 100%;
height: calc((34rem - 2rem) / 2);
}
}
}
</style>

View File

@@ -0,0 +1,79 @@
<template>
<div class="modelindex">
<div class="detail_btn">
<!-- 全屏 -->
<i class="fi fi-bs-expand-arrows-alt" @click="showDesignImgDetail(2)"></i>
<!-- 编辑 -->
<i class="fi fi-rr-edit" :title="$t('DesignDetail.editTitle')" @click="showDesignImgDetail(3)"></i>
<!-- <i v-show="!body && !deleteShow" :title="$t('DesignDetail.DetailTitle')" class="fi fi-rr-trash" @click="deleteNav(0)"></i>
<i v-show="!body && deleteShow" class="fi fi-br-check" @click="deleteNav(1)"></i> -->
<!-- -->
<!-- <i class="fi fi-rr-copy" :title="$t('DesignDetail.compareTitle')" @mousedown="mousedownDesignImg" @mouseup="mouseupDesignImg" @touchstart="mousedownDesignImg" @touchend="mouseupDesignImg"></i> -->
<!-- <i v-show="revocationShow>1" class="icon iconfont icon-chehui" @click="revocation"></i>
<i v-show="oppositeRevocationShow>=1" class="icon iconfont icon-fanchehui" @click="oppositeRevocation"></i> -->
</div>
<div>
<position></position>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,inject,nextTick,createVNode,toRefs, reactive} from 'vue'
// import setDesignItem from '@/component/Detail/setDesignItem2.vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { useI18n } from 'vue-i18n'
import position from './modelPosition.vue';
export default defineComponent({
components:{
position,
},
setup(props,{emit}) {
const store = useStore();
const detailData = reactive({
})
const getDetailListData = reactive({
total:0,
pageSize:10,
currentPage:1,
designDetail:store.state.DesignDetailCopy.designDetail,
})
const getDetailListDom = reactive({
libraryList:null as any,
})
const showDesignImgDetail = ()=>{
}
const deleteNav = ()=>{
}
return{
...toRefs(detailData),
...toRefs(getDetailListData),
...toRefs(getDetailListDom),
showDesignImgDetail,
deleteNav,
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.modelindex{
width: 80rem;
height: 100%;
display: flex;
flex-direction: column;
padding-top: 3rem;
overflow: hidden;
}
</style>

View File

@@ -0,0 +1,228 @@
<template>
<div class="molepositon">
<div class="designOpenrtion_imgMask" :style="frontBack?.body?.style">
<div class="designOpenrtion_print" v-for="item,index in frontBack.back" @mousedown.stop="itemMoveMousedown(index,getMousePosition($event,false))" @touchstart.passive="itemMoveMousedown(index,getMousePosition($event,true))" @click="setpitch(item,index)" :style="frontBack.front[index].style">
<img :style="item.imageUrl?'':'display:none;'" :src="item.imageUrl" alt="">
</div>
<img class="perview_img" :style="'width:'+ frontBack?.body?.layersObject?.[0].imageSize?.[0] +';height:' + frontBack?.body?.layersObject?.[0].imageSize?.[0] +';'" v-lazy="frontBack?.body?.layersObject?.[0].imageUrl || ''">
<div class="detail_modal_item_front" v-for="item,index in frontBack.front" @mousedown.stop="itemMoveMousedown(index,getMousePosition($event,false))" @touchstart.passive="itemMoveMousedown(index,getMousePosition($event,true))" @click="setpitch(item,index)" :style="item.style">
<img :src="item.imageUrl" alt="">
</div>
<div class="designOpenrtion_btn">
<ul v-for="item,index in frontBack.front" :key="item" :class="{active:item.designOpenrtionBtn}" class="designOpenrtion_btn" :style="item.style" @mousedown.stop="itemMoveMousedown(index,getMousePosition($event,false))" @touchstart.passive="itemMoveMousedown(index,getMousePosition($event,true))">
<li class="designOpenrtion_btn_top" @mousedown.stop="itemSizeMousedown('top',getMousePosition($event,false))" @touchstart.passive="itemSizeMousedown('top',getMousePosition($event,true))"></li>
<li class="designOpenrtion_btn_bottom" @mousedown.stop="itemSizeMousedown('bottom',getMousePosition($event,false))" @touchstart.passive="itemSizeMousedown('bottom',getMousePosition($event,true))"></li>
<li class="designOpenrtion_btn_left" @mousedown.stop="itemSizeMousedown('left',getMousePosition($event,false))" @touchstart.passive="itemSizeMousedown('left',getMousePosition($event,true))"></li>
<li class="designOpenrtion_btn_right" @mousedown.stop="itemSizeMousedown('right',getMousePosition($event,false))" @touchstart.passive="itemSizeMousedown('right',getMousePosition($event,true))"></li>
<!-- <li class="designOpenrtion_rotote" v-rotote.stop="[index,item.transform]"></li> -->
</ul>
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,inject,watch,nextTick,createVNode,toRefs, reactive} from 'vue'
// import setDesignItem from '@/component/Detail/setDesignItem2.vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { useI18n } from 'vue-i18n'
import { getMousePosition } from "@/tool/mdEvent";
export default defineComponent({
components:{
},
setup(props,{emit}) {
const store = useStore();
const detailData = reactive({
frontBack:{
front:{},
back:{},
body:{},
},
frontBackc:store.state.DesignDetailModule.designItemDetail,
designDetail:store.state.DesignDetailCopy.designDetail,
})
const getDetailListDom = reactive({
libraryList:null as any,
})
//设置尺寸
const itemSizeMousedown = (direction:any,event:any)=>{
// this.direction = direction
// this.imgDom = document.getElementsByClassName('design_compile_content')[0].getElementsByClassName("detail_modal_item_front")[this.imgDomIndex]
// this.frontBack.front[this.imgDomIndex].designOpenrtionBtn = true
// let imgDomWH = this.imgDom.getBoundingClientRect()
// let li = document.getElementsByClassName('design_compile_content')[0].getElementsByClassName("designOpenrtion_btn_top")[0].offsetWidth/2
// if(this.direction == 'right' || this.direction == 'bottom'){
// this.frontBack.front[this.imgDomIndex].centers.left = imgDomWH.x+event.offsetX-li
// this.frontBack.front[this.imgDomIndex].centers.top = imgDomWH.y+event.offsetY-li
// }else{
// this.frontBack.front[this.imgDomIndex].centers.left = imgDomWH.x+event.offsetX+imgDomWH.width-li
// this.frontBack.front[this.imgDomIndex].centers.top = imgDomWH.y+event.offsetY+imgDomWH.height-li
// }
document.addEventListener('mousemove', sizeMouseMove);
document.addEventListener('touchmove', sizeTouchmove);
document.addEventListener('mouseup', sizeMouseup);
document.addEventListener('touchend', sizeMouseup);
}
const sizeMouseMove = (event:any)=>{
let e = getMousePosition(event,false)
sizeMouseMoveOperation(e)
}
const sizeTouchmove = (event:any)=>{
let e = getMousePosition(event,true)
sizeMouseMoveOperation(e)
}
const sizeMouseup = (e:any)=>{
// this.frontBack.front[this.imgDomIndex].style={
// right:'auto',
// left:this.imgDom.offsetLeft+'px',
// bottom:'auto',
// top:this.imgDom.offsetTop+'px',
// height:this.imgDom.offsetHeight+'px',
// width:this.imgDom.offsetWidth+'px',
// zIndex:this.printZIndex
// }
// this.frontBack.back[this.imgDomIndex].style.zIndex = this.printZIndex
document.removeEventListener('mousemove',sizeMouseMove)
document.removeEventListener('touchmove',sizeTouchmove)
document.removeEventListener('mouseup',sizeMouseup)
document.removeEventListener('touchend',sizeMouseup)
}
const sizeMouseMoveOperation = (e:any)=> {
// let imgDomWH = this.imgDom.getBoundingClientRect()
// let parentNode =this.imgDom.parentNode
// let width = imgDomWH.width
// let height = imgDomWH.height
// let w,h
// let num = height/width
// //判断移动四个边
// if(this.direction == 'right'){
// w = (e.clientX - this.frontBack.front[this.imgDomIndex].centers.left)
// h = (e.clientX - this.frontBack.front[this.imgDomIndex].centers.left)*num
// width = w+'px'
// // height = w*num+'px'
// }else if(this.direction == 'top'){
// num = width/height
// this.frontBack.front[this.imgDomIndex].style.top = 'auto'
// // this.printStyleList[this.imgDomIndex].style.left = 'auto'
// this.frontBack.front[this.imgDomIndex].style.bottom = parentNode.offsetHeight -imgDomWH.height - this.imgDom.offsetTop+'px'
// w = (e.clientX - this.frontBack.front[this.imgDomIndex].centers.left)*num
// h = (this.frontBack.front[this.imgDomIndex].centers.top - e.clientY)
// height = h+'px'
// // width = h*num+'px'
// }else if(this.direction == 'bottom'){
// num = width/height
// h = (e.clientY - this.frontBack.front[this.imgDomIndex].centers.top)
// height = h+'px'
// // width = h*num+'px'
// }else if(this.direction == 'left'){
// this.frontBack.front[this.imgDomIndex].style.left = 'auto'
// this.frontBack.front[this.imgDomIndex].style.right = parentNode.offsetWidth -imgDomWH.width - this.imgDom.offsetLeft+'px'
// w = (this.frontBack.front[this.imgDomIndex].centers.left - e.clientX)
// width = w+'px'
// // height = w*num+'px'
// }
// //判断尺寸是否到边
// this.frontBack.front[this.imgDomIndex].style.width = width
// this.frontBack.front[this.imgDomIndex].style.height = height
}
// 设置移动
const mouseMove = (event:any)=>{
let e = getMousePosition(event,false)
mouseMoveOperation(e)
}
const touchmove=(event:any)=>{
let e = getMousePosition(event,true)
mouseMoveOperation(e)
}
const mouseup = (e:any)=> {
document.removeEventListener('mousemove',mouseMove)
document.removeEventListener('touchmove',touchmove)
document.removeEventListener('mouseup',mouseup)
document.removeEventListener('touchend',mouseup)
}
const mouseMoveOperation = (e:any)=>{
// let imgDomWH = this.imgDom.getBoundingClientRect()
// let parentNode = document.getElementsByClassName('design_compile_content')[0].getElementsByClassName("designOpenrtion_imgMask")[0].getBoundingClientRect()
// let x = (e.clientX - this.frontBack.front[this.imgDomIndex].centers.left)+'px'
// let y = ( e.clientY - this.frontBack.front[this.imgDomIndex].centers.top)+'px'
// this.frontBack.front[this.imgDomIndex].style.left = x
// this.frontBack.front[this.imgDomIndex].style.top = y
}
const itemMoveMousedown = (index:any,e:any)=>{
// this.imgDomIndex = index
// this.frontBack.front.forEach((v)=>{
// v.designOpenrtionBtn = false
// })
// this.clothesOpenActive(index)
// let event = e||window.event
// this.imgDom = document.getElementsByClassName('design_compile_content')[0].getElementsByClassName("detail_modal_item_front")[this.imgDomIndex]
// this.frontBack.front[index].designOpenrtionBtn = true
// this.frontBack.front[index].style.zIndex = this.printZIndex++
// this.frontBack.back[index].style.zIndex = this.printZIndex
// let imgDomWH = this.imgDom.getBoundingClientRect()
// let left = Number(this.frontBack.front[index].style.left.replace(/px/g,''))
// let top = Number(this.frontBack.front[index].style.top.replace(/px/g,''))
// this.frontBack.front[index].centers.left = imgDomWH.x+event.offsetX-left
// this.frontBack.front[index].centers.top = imgDomWH.y+event.offsetY-top
document.addEventListener('mousemove', mouseMove);
document.addEventListener('touchmove', touchmove);
document.addEventListener('mouseup', mouseup);
document.addEventListener('touchend', mouseup);
}
const showDesignImgDetail = ()=>{
}
const deleteNav = ()=>{
}
return{
...toRefs(detailData),
...toRefs(getDetailListDom),
itemSizeMousedown,
itemMoveMousedown,
showDesignImgDetail,
deleteNav,
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.molepositon{
width: 80rem;
height: 100%;
display: flex;
flex-direction: column;
padding-top: 3rem;
> .designOpenrtion_imgMask{
width: auto;
height: auto;
position: relative;
height: calc(100% - 1.2rem - 4.8rem - 20%);
// overflow: hidden;
>img{
z-index: 2;
position: relative;
}
>div{
position: absolute;
width: 100%;
height: 100%;
top: 0;
}
}
}
</style>

View File

@@ -0,0 +1,165 @@
<template>
<div class="sketchLeft">
<div class="detailText">Current Print</div>
<div class="select_sketch">
<img src="https://develop.aida.com.hk/img/aida_logo_centent.b8a50882.jpg" alt="">
</div>
<div class="switch_type_list">
<div
@click.stop="openUpload()"
class="switch_type_item"
:class="[selectTitle == 'upload' ? 'select_swtich' : '',]"
>
<span class="detailText">{{ $t('DesignDetailAlter.Upload') }}</span>
</div>
<div
@click.stop="openLibrary()"
class="switch_type_item"
:class="[selectTitle == 'library' ? 'select_swtich' : '']"
>
<span class="detailText">{{ $t('DesignDetailAlter.Library') }}</span>
</div>
</div>
<div class="sketch_content_list">
<div class="content_item" v-show="selectTitle == 'upload'">
<uploadList :catecoryList="sketchCatecoryList"></uploadList>
</div>
<div class="content_item" v-show="selectTitle == 'library'">
<libraryList ref="libraryList" :catecoryList="sketchCatecoryList"></libraryList>
</div>
</div>
<div class="mark_loading" v-show="loadingShow">
<a-spin size="large" />
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,provide,nextTick,createVNode,toRefs, reactive} from 'vue'
// import setDesignItem from '@/component/Detail/setDesignItem2.vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { useI18n } from 'vue-i18n'
import sketchCategory from "@/component/HomePage/sketchCategory.vue";
import libraryList from './libraryList.vue'
import uploadList from './uploadList.vue'
export default defineComponent({
components:{
libraryList,
uploadList,
sketchCategory,
},
setup(props,{emit}) {
const store = useStore();
const detailData = reactive({
selectTitle:'upload',
loadingShow:false,
isShowLoading:false,//懒加载,加载中
sketchCatecoryList:computed(()=>{
return store.state.Workspace.workspacePosition
})
})
const getDetailListData = reactive({
total:0,
pageSize:10,
currentPage:1,
})
const getDetailListDom = reactive({
libraryList:null as any,
})
const openUpload = ()=>{
detailData.selectTitle = 'upload'
}
const openLibrary = ()=>{
detailData.selectTitle = 'library'
getDetailListDom.libraryList.init()
}
const selectImgItem = ()=>{
}
return{
...toRefs(detailData),
...toRefs(getDetailListData),
...toRefs(getDetailListDom),
openUpload,
openLibrary,
selectImgItem,
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.sketchLeft{
width: 34rem;
height: 100%;
display: flex;
flex-direction: column;
> .detailText{
margin-bottom: 1rem;
}
> .select_sketch{
width: 100%;
height: 23.5rem;
padding: 1rem 0;
text-align: center;
border-radius: .5rem;
// border: 1px dashed #202020;
border: 1px dashed transparent;
background: linear-gradient(#fff, #fff) padding-box,repeating-linear-gradient(-45deg,#fff 0,#fff 0.3em, #000 0,#000 0.6em);
margin-bottom: 3rem;
> img{
width: 100%;
height: 100%;
object-fit: contain;
}
}
> .switch_type_list{
display: flex;
margin-bottom: 2.5rem;
> .switch_type_item:nth-child(1){
margin-right: 6.5rem;
}
> .switch_type_item{
position: relative;
cursor: pointer;
}
> .switch_type_item::before {
position: absolute;
content: "";
display: block;
background: #000;
height: calc(.4rem*1.2);
left: 50%;
transform: translateX(-50%);
bottom: -.5rem;
width: 0px;
transition: 0.3s all;
}
> .select_swtich {
color: #000;
font-weight: 600;
transform: scale(1.15);
}
> .select_swtich::before {
width: 100%;
}
}
> .sketch_content_list{
flex: 1;
overflow: hidden;
> .content_item{
height: 100%;
margin-top: 1rem;
}
}
}
</style>

View File

@@ -0,0 +1,212 @@
<template>
<div class="uploadList">
<div class="uploadList_box">
<div class="content_img_item" v-for="(file) in uploadList" :key="file.id">
<div class="content_img_item_block" :class="{active:file?.checked}">
<img v-lazy="file.url" :key="file.url" :alt="file.name" @click.stop="selectImgItem(file)"/>
<sketchCategory :disignTypeList="catecoryList" :generateList="uploadList" :item="file" ></sketchCategory>
</div>
</div>
<div class="upload_item">
<div class="upload_file_item upload_component">
<a-upload
:action="uploadUrl + '/api/element/upload'"
list-type="picture-card"
:capture="null"
:data="{
...upload,
}"
:headers="{ Authorization: token }"
v-model:file-list="uploadList"
:before-upload="beforeUpload"
:maxCount="8"
accept=".jpg,.png,.jpeg,.bmp"
@change="(file) => upFileUploadChange(file)"
>
<div
class="upload_tip_block"
v-show="uploadList.length != 8"
>
<i class="fi fi-br-upload"></i>
<!-- <img class="upload_img_icon" src="@/assets/images/homePage/add_file.png"> -->
</div>
</a-upload>
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent,computed,ref,provide,nextTick,createVNode,toRefs, reactive, onMounted} from 'vue'
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import sketchCategory from "@/component/HomePage/sketchCategory.vue";
import { getCookie } from "@/tool/cookie";
import { message,Upload} from 'ant-design-vue';
import {getUploadUrl} from '@/tool/util'
import { useI18n } from 'vue-i18n'
export default defineComponent({
components:{
sketchCategory
},
props:{
catecoryList:{
type:Object,
default:()=>[] as any,
required:true
}
},
setup(props,{emit}) {
const {t} = useI18n();
const store = useStore();
const detailData = reactive({
isShowLoading:false,//懒加载,加载中
uploadList:[],
upload:{
isPin: 0,
level1Type: 'Sketchboard',
gender:store.state.Workspace.workspace.sex,
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
},
token:getCookie("token"),
uploadUrl:getUploadUrl(),
})
const getDetailListData = reactive({
total:0,
pageSize:10,
currentPage:1,
})
const selectImgItem = ()=>{
}
const upFileUploadChange = (data:any)=>{
let file = data.file;
let bor = true
if (file.status === "done") {
let res = JSON.parse(file.xhr.response);
if(res.errCode == 0){
file.id = res.data.id;
file.url = res.data.url;
file.resData = res.data;
let type
if(props?.catecoryList){
if(res.data.level2Type){
props?.catecoryList.forEach((item:any) => {
if(item.value == res.data.level2Type){
file.categoryValue = item?.value;
type = item.value
file.category = item?.name;
}
});
}else{
file.categoryValue = props?.catecoryList?.[0].value;
type = props.catecoryList[0].value
file.category = props.catecoryList[0].name;
}
}
file.designType = res.data.designType
file.level2Type = type;
file.minIOPath = file.resData.minIOPath
let fileList = detailData.uploadList.filter(
(v:any) => v.status === "done"
);
detailData.uploadList = fileList
// this.selectImgItem(detailData.uploadList[detailData.uploadList.length-1])
}else{
bor = false
}
} else if (file.status === "error") {
bor = false
}
if(!bor){
let res = JSON.parse(file.xhr.response);
let index = -1;
detailData.uploadList.forEach((ele:any, index1) => {
if (file.uid === ele.uid) {
index = index1;
}
});
if (index > -1) {
detailData.uploadList.splice(index, 1);
}
message.warning(res.errMsg);
}
}
const beforeUpload = (file:any)=>{
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg' || file.type === 'image/bmp';
if (!isJpgOrPng) {
message.info(t('DesignDetailAlter.jsContent4'));
}
const isLt2M = file.size / 1024 / 1024 < 5;
if (!isLt2M) {
message.info(t('DesignDetailAlter.jsContent5'));
}
return (isJpgOrPng && isLt2M) || Upload.LIST_IGNORE;
}
onMounted(()=>{
})
return{
...toRefs(detailData),
...toRefs(getDetailListData),
selectImgItem,
beforeUpload,
upFileUploadChange,
}
},
provide() {
return {
}
},
})
</script>
<style lang="less" scoped>
.uploadList{
height: 100%;
display: flex;
flex-direction: column;
> .uploadList_box{
width: 100%;
flex: 1;
overflow-y: auto;
display: flex;
flex-wrap: wrap;
margin-top: 1rem;
justify-content: space-between;
align-content: flex-start;
&::-webkit-scrollbar{display: none;}
> .content_img_item{
> .content_img_item_block{
width: calc((34rem - 2rem) / 2);
height: calc((34rem - 2rem) / 2);
position: relative;
margin-bottom: 2rem;
> img{
width: 100%;
height: 100%;
object-fit: contain;
}
}
}
> .material_content_list_loding{
width: 100%;
height: calc((34rem - 2rem) / 2);
}
> .upload_item{
width: calc((34rem - 2rem) / 2);
height: calc((34rem - 2rem) / 2);
align-items: center;
justify-content: center;
}
}
}
</style>

View File

@@ -70,13 +70,11 @@ export default defineComponent({
isNoData:false,//如果数据为空就不加载
loadingShow:{},
})
let systemUser = computed(()=>{
return store.state.UserHabit.systemUser
})
let likeFile = (item:any,type:string) => {
}
let setBack = ()=>{
router.go(-1);
// router.push('/home/events')
}
let openButton = (data:any,index:number)=>{
if(filter.loadingShow[index]){
@@ -111,7 +109,6 @@ export default defineComponent({
})
return {
...toRefs(filter),
systemUser,
likeFile,
setBack,
openButton,
@@ -133,7 +130,7 @@ export default defineComponent({
.eventsDetail_page {
min-height: 100%;
width: 100%;
padding: 0 9rem;
padding: 0 6rem;
padding-top: 5rem;
&.active{

View File

@@ -103,7 +103,8 @@
</div>
</div>
<div class="upload_file_item_scale" :style="[(driver__.driver && (driver__.index == 19 || driver__.index == 18))?'display :flex;':'']">
<a-upload
<div style="position: relative;">
<a-upload
:title="$t('ColorboardUpload.uploadTitle')"
:capture="null"
:max-count="1"
@@ -118,6 +119,7 @@
<i class="fi fi-br-upload"></i>
</div>
</a-upload>
</div>
<div :title="$t('ColorboardUpload.selectTitle')" class="upload_file_item" @click="setPrintImg()">
<i class="fi fi-rr-picture"></i>
</div>
@@ -166,7 +168,6 @@ import { Https } from "@/tool/https";
import GO from "@/tool/GO";
import { defineComponent, h,ref,inject, nextTick } from 'vue'
import { LoadingOutlined } from '@ant-design/icons-vue';
import {getCookie} from '@/tool/cookie'
import {getUploadUrl,rgbToHsv,isMoible} from '@/tool/util'
import {useStore} from 'vuex'
import ColorThief from '@/tool/colorthief/colorthief'
@@ -181,6 +182,11 @@ export default defineComponent({
Sketch,
selectImgList,
},
props: {
collectionStep: {
type: Number,
}
},
setup(){
// console.log(isMoible());
let fileList = ref([])
@@ -236,6 +242,33 @@ export default defineComponent({
// this.setColorboardList(colorList)
// // this.clearSelectColor()
// },
collectionStep:{
handler(newVal,oldVal){
if(newVal != 3)return
const backIcon = document.createElement('div');
if(backIcon.classList.contains('vc-sketch-color-wrap'))return
backIcon.classList.add('vc-sketch-color-wrap')
let dropperDom = document.getElementsByClassName("colorboard_upload_modal")[0].getElementsByClassName('vc-chrome-fields-wrap')[0]
dropperDom.appendChild(backIcon);
backIcon.addEventListener('click', async ()=>{
try {
const dropper = new EyeDropper();
const result = await dropper.open();
let hex = result.sRGBHex.replace("#", "");
// 将十六进制颜色码拆分成红、绿、蓝三个部分
const r = parseInt(hex.substring(0, 2), 16);
const g = parseInt(hex.substring(2, 4), 16);
const b = parseInt(hex.substring(4, 6), 16);
this.selectColor = {rgba:{r:r,g:g,b:b,a:1},hex:result.sRGBHex}
// 返回RGB格式的字符串
// return `rgb(${r}, ${g}, ${b})`;
// box.style.backgroundColor = label.textContent = result.sRGBHex;
} catch (e) {
message.info(this.t('ColorboardUpload.jsContent1'))
}
})
}
},
selectColor:{
handler(newVal,oldVal){
if(typeof newVal?.rgba?.r !== 'number' && typeof newVal?.rgba?.r !== 'string'){
@@ -319,7 +352,6 @@ export default defineComponent({
level1Type:'Moodboard',
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
},
token:'',
uploadUrl:'',
store:useStore(),
colorPickerVisible: true,
@@ -328,31 +360,11 @@ export default defineComponent({
}
},
mounted(){
this.token = getCookie('token') || ''
this.uploadUrl = getUploadUrl()
const backIcon = document.createElement('div');
backIcon.classList.add('vc-sketch-color-wrap')
let dropperDom = document.getElementsByClassName("colorboard_upload_modal")[0].getElementsByClassName('vc-chrome-fields-wrap')[0]
dropperDom.appendChild(backIcon);
backIcon.addEventListener('click', async ()=>{
try {
const dropper = new EyeDropper();
const result = await dropper.open();
let hex = result.sRGBHex.replace("#", "");
// 将十六进制颜色码拆分成红、绿、蓝三个部分
const r = parseInt(hex.substring(0, 2), 16);
const g = parseInt(hex.substring(2, 4), 16);
const b = parseInt(hex.substring(4, 6), 16);
this.selectColor = {rgba:{r:r,g:g,b:b,a:1},hex:result.sRGBHex}
// 返回RGB格式的字符串
// return `rgb(${r}, ${g}, ${b})`;
// box.style.backgroundColor = label.textContent = result.sRGBHex;
} catch (e) {
message.info(this.t('ColorboardUpload.jsContent1'))
}
nextTick(()=>{
this.uploadUrl = getUploadUrl()
})
// this.clearSelectColor()
// if ("EyeDropper" in window) {
// console.log(true);
@@ -932,6 +944,9 @@ export default defineComponent({
box-shadow: 0 0px 4px 0px rgba(0, 0, 0, 0.3);
overflow: hidden;
background: #fff;
>div,>span{
width: 50%;
}
}
.upload_file_item_show:hover{
border-bottom: none;

View File

@@ -1,7 +1,9 @@
<template>
<a-modal class="modal_component cut_pricture_modal"
<div ref="cutPrictureModal">
<a-modal class="generalModel cut_pricture_modal"
v-model:visible="cutPicuterModal"
:footer="null"
:get-container="() => $refs.cutPrictureModal"
width="78%"
:maskClosable="false"
:centered="true"
@@ -30,6 +32,7 @@
:outputType="option.outputType"
:auto-crop="option.autoCrop"
:fixedBox="!isRound"
:movable="true"
:fixed="isRound"
:auto-crop-width="option.autoCropWidth"
:auto-crop-height="option.autoCropWidth"
@@ -70,6 +73,7 @@
</div>
</div>
</a-modal>
</div>
</template>
<script lang="ts">
import { defineComponent,inject } from 'vue'
@@ -168,20 +172,6 @@ export default defineComponent({
}
})
</script>
<style lang="less">
.component_modal{
}
.cut_pricture_modal{
.ant-modal-content{
// transform: scale(1.2);
// transform-origin: center !important;
}
*{
pointer-events: auto;
}
}
</style>
<style lang="less" scoped>
.cut_pricture_modal{
@@ -190,7 +180,7 @@ export default defineComponent({
.collection_title{
position: absolute;
width: calc(100% - 10rem*1.2);
top: calc(4rem*1.2);
top: calc(3rem*1.2);
display: flex;
font-size: var(--aida-fsize2);
font-weight: 900;

View File

@@ -1,8 +1,10 @@
<template>
<div ref="ExportModal">
<a-modal
class="modal_component Export generalModelOperate"
class="modal_component Export generalModel"
v-model:visible="showUpgradePlan"
:footer="null"
:get-container="() => $refs.ExportModal"
width="78%"
:maskClosable="false"
:centered="true"
@@ -10,10 +12,17 @@
:keyboard="false"
:destroyOnClose="true"
>
<div class="UpgradePlan_closeIcon generalModelOperate_closeIcon ">
<i class="fi fi-rr-cross-small" @click.stop="cancelDsign()"></i>
</div>
<div class="UpgradePlan_content generalModelOperate">
<div class="generalModel_btn">
<div class="generalModel_closeIcon" @click.stop="cancelDsign()">
<svg width="46" height="46" viewBox="0 0 46 46" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="23" cy="23" r="23" fill="white" fill-opacity="0.3"/>
<rect x="32.5063" y="12" width="3" height="29" rx="1.5" transform="rotate(45 32.5063 12)" fill="white"/>
<rect x="34.6274" y="32.5059" width="3" height="29" rx="1.5" transform="rotate(135 34.6274 32.5059)" fill="white"/>
</svg>
</div>
</div>
<div class="UpgradePlan_content">
<div>{{ $t('exportModel.EditExport') }}</div>
</div>
<!-- <div>
@@ -152,6 +161,22 @@
<input type="number" @input="setPencilColor" v-model="canvasPencilColor">
</div> -->
</div>
<div class="shortcutKeys_box">
<div class="gallery_btn white" @click.stop="setCloseNav('shortcut')">
{{ $t('exportModel.ShortcutKeys') }}
<i class="icon iconfont icon-xiala" :class="closeNav.shortcut?'icon-rotate-tool':''" ></i>
</div>
<div class="shortcutKeys_list">
<div class="shortcutKeys_list_item" v-for="item in keysList" :key="item.name">
<div class="name">{{ item.name }}</div>
<div class="key">
<div v-if="!isWindow">{{ item.macKey }}</div>
<div v-else>{{ item.winDowKey }}</div>
</div>
</div>
</div>
</div>
<!-- <div class="exportCanvasBox_title" @click.stop="setCloseNav('move')">
{{ $t('exportModel.More') }}
</div>
@@ -161,16 +186,16 @@
<div class="exportCanvasBox_center_box exportCanvasBox_left">
<div class="exportCanvasBox_left_tool exportCanvasBox_title">
<div class="exportCanvasBox_left_tool_item">
<i class="icon iconfont icon-chehui" @click="historyState('')"></i>
<i class="icon iconfont icon-fanchehui" @click="historyState('reverse')"></i>
<i class="icon iconfont icon-bianji" @click="setOperation('pencil')" :class="{active:operation == 'pencil'}"></i>
<i class="icon iconfont icon-chehui" @click="historyState('')" :title="isWindow?'Ctrl+Z':'Command+Z'"></i>
<i class="icon iconfont icon-fanchehui" @click="historyState('reverse')" :title="isWindow?'Ctrl+Shift+Z':'Command+Ctrl+Z'"></i>
<i class="icon iconfont icon-move" @click="setOperation('move')" :class="{active:operation == 'move'}" :title="isWindow?'M':'M'"></i>
<i class="icon iconfont icon-bianji" @click="setOperation('pencil')" :class="{active:operation == 'pencil'}" :title="isWindow?'B':'B'"></i>
<i class="icon iconfont icon-xiangpi_huaban1" @click="setOperation('eraser')" :class="{active:operation == 'eraser'}" :title="isWindow?'E':'E'"></i>
<i class="icon iconfont icon-caizhi" @click="setOperation('texture')" :class="{active:operation == 'texture'}"></i>
<i class="icon iconfont icon-move" @click="setOperation('move')" :class="{active:operation == 'move'}"></i>
<i class="icon iconfont icon-xiangpi_huaban1" @click="setOperation('eraser')" :class="{active:operation == 'eraser'}"></i>
<label class="uploadImage">
<label class="uploadImage" :title="isWindow?'Ctrl+O':'Command+O'">
<i class="fi fi-br-upload" ></i>
<input type="file" @change="uploadImage">
<input type="file" @change="uploadImage" accept="image/*">
</label>
<i class="icon iconfont" @click="setOperation('text')" :class="{active:operation == 'text'}">T</i>
<i class="icon iconfont icon-IC-yehua" @click="setLiquefaction()"></i>
@@ -239,7 +264,7 @@
</div>
<a-modal
v-model:visible="showSRExport"
class="modal_component SRExport generalModelOperate"
class="modal_component SRExport generalModel"
width="48%"
:maskClosable="false"
:centered="true"
@@ -248,9 +273,11 @@
:footer="null"
:mask="false"
>
<div class="generalModelOperate_closeIcon">
<i class="fi fi-rr-cross-small" @click.stop="cancelSRExport()"></i>
<div class="generalModel_btn">
<div class="generalModel_closeIcon" @click.stop="cancelDsign()">
<i class="fi fi-rr-cross-small"></i>
</div>
</div>
<div class="modal_title_text">
<div class="modal_title_text_max">{{ $t('exportModel.SR') }}</div>
<div class="modal_title_text_intro">{{ $t('exportModel.requiresCredits',{data:(allExportSR.filter(item=> item.checked ).length*5)}) }}</div>
@@ -286,12 +313,13 @@
<div class="generalModelOperate_btn_ok" :class="[credits < (allExportSR.filter(item=> item.checked ).length*5)?'active':'']" @click="setExportSR">OK</div>
</div>
</a-modal>
<publish ref="publish" @setPublish="setSubmit"></publish>
<liquefaction ref="liquefaction" @submitLiquefaction="submitLiquefaction"></liquefaction>
<publish ref="publish" @clearPublish="clearPublish"></publish>
<liquefaction ref="liquefaction" @submitLiquefaction="submitLiquefaction" @clearLiquefaction="clearLiquefaction"></liquefaction>
</a-modal>
</div>
</template>
<script>
import {defineComponent, computed, h, ref, nextTick, inject, reactive, onMounted,
import {defineComponent, computed, h, ref, nextTick, inject, reactive, onMounted,onBeforeUnmount
} from "vue";
import { Https } from "@/tool/https";
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
@@ -318,14 +346,14 @@ export default defineComponent({
publish,
liquefaction,
},
props: ["msg", "sketchCatecoryList"],
props: ["msg", "sketchCatecoryList",'setTask'],
setup(props,{emit}) {
const {t} = useI18n()
const store = useStore();
let driver__ = computed(()=>{
return store.state.Guide.guide
})
let isWindow = true
let showUpgradePlan = ref(false);
let canvas = ref({});
// let canvasDom = ref()
@@ -386,6 +414,12 @@ export default defineComponent({
"likeDesignCollectionList",
productData.key,
];
const userAgent = navigator.userAgent.toLowerCase();
if (userAgent.indexOf('windows') !== -1) {
isWindow = true
}else if(userAgent.indexOf('macintosh') !== -1 || userAgent.indexOf('mac os') !== -1) {
isWindow = false
}
createCanvas()
}
let setCanvasData = async (oldExportCanvas)=>{
@@ -521,6 +555,9 @@ export default defineComponent({
let createCanvas = (oldExportCanvas) => {
showUpgradePlan.value = true;
clearTimeout(submitCanvasContent)
setCanvasKeyDown()
// document.addEventListener("keydown", setCanvasKeyDown);
// document.addEventListener("keyup", clearCanvasKeyDown);
normalCanvasState.value = []
reverseCanvasState.value = []
allBoardData.value.likeDesignCollectionList =
@@ -531,8 +568,6 @@ export default defineComponent({
let oldCanvasDom = canvasBox.querySelector('.canvas-container')
let oldCanvasDom1 = canvasBox.querySelector('canvas')
var canvasDom = document.createElement("canvas");
document.addEventListener("keydown", setCanvasKeyDown);
document.addEventListener("keyup", clearCanvasKeyDown);
if(oldCanvasDom)oldCanvasDom.remove()
if(oldCanvasDom)loadingShow.value = false
if(oldCanvasDom1)oldCanvasDom1.remove()
@@ -559,12 +594,6 @@ export default defineComponent({
});
canvas.preserveObjectStacking = true;
//鼠标移动
// canvas.wrapperEl.onmouseover = setCanvasKeyDown;//document上添加按下和抬起事件
// canvas.wrapperEl.onmouseout = clearCanvasKeyDown;//document上添加按下和抬起事件
// canvas.on("mouse:over", event =>setCanvasKeyDown(event));//document上添加按下和抬起事件
// canvas.on("mouse:out", clearCanvasKeyDown);//document上添加按下和抬起事件
canvas.on("mouse:move", event =>setCanvasMove(event));
canvas.on("mouse:down", event=>setCanvasDown(event));
canvas.on("mouse:up", event=>setCanvasUp(event));
@@ -711,11 +740,6 @@ export default defineComponent({
let heightScale = imgObj.height / height
imgWidth = imgObj.width * heightScale
}
// imgWidth =
// (canvasWH.value.width -
// (likeDesign - 1) * 20) /
// likeDesign;
}
return imgWidth
}
@@ -922,7 +946,6 @@ export default defineComponent({
centered:true,
onOk() {
showUpgradePlan.value = false;
canvas.off("mouse:out", clearCanvasKeyDown);
canvas.dispose();
position = {
//设置每个图形位置的初始值
@@ -965,7 +988,7 @@ export default defineComponent({
let closeNav = ref({
nav:false,
tool:false,
move:false,
shortcut:false,
})
let setCloseNav = (key)=>{
closeNav.value[key] = !closeNav.value[key]
@@ -1192,26 +1215,122 @@ export default defineComponent({
// let brushwork = ref('')
// 监听键盘的 keydown 和 keyup 事件
let keyDown = []
const keysList = [
{
name:useI18.t('exportModel.Painting'),
winDowKey:'B',
macKey:'B',
},{
name:useI18.t('exportModel.Eraser'),
winDowKey:'E',
macKey:'E',
},{
name:useI18.t('exportModel.Uncheck'),
winDowKey:'Ctrl + D',
macKey:'Command + D',
},{
name:useI18.t('exportModel.Revoke'),
winDowKey:'Ctrl + Z',
macKey:'Command + Z',
},{
name:useI18.t('exportModel.Retreat'),
winDowKey:'Ctrl + Shift + Z',
macKey:'Command + Ctrl + Z',
},{
name:useI18.t('exportModel.ReduceBrushSize'),
winDowKey:'[',
macKey:'[',
},{
name:useI18.t('exportModel.IncreaseBrushSize'),
winDowKey:']',
macKey:']',
},{
name:useI18.t('exportModel.DrinkingStraw'),
winDowKey:'I',
macKey:'I',
},{
name:useI18.t('exportModel.Copy'),
winDowKey:'Ctrl + C',
macKey:'Command + C',
},{
name:useI18.t('exportModel.Paste'),
winDowKey:'Ctrl + V',
macKey:'Command + V',
},{
name:useI18.t('exportModel.UploadOpenimage'),
winDowKey:'Ctrl + O',
macKey:'Command + O',
},
]
let canvasKeyDown = (event) => {
if(keyDown.indexOf(event.key)>-1){
let keys = ['Enter','Delete','ControlLeft','KeyZ','ShiftLeft','KeyC','KeyV','BracketLeft','BracketRight','KeyI','KeyD','KeyO','KeyE','KeyB','MetaLeft']
if(keys.indexOf(event.code) > -1){
event.preventDefault();
}
if(keyDown.indexOf(event.code)>-1){
}else{
keyDown.push(event.code)
if(event.key === 'Enter' && operation.value == 'fold'){
// console.log(keyDown.indexOf('ControlLeft') > -1 , keyDown.indexOf('MetaLeft') > -1, event.code == 'KeyC')
if(event.code === 'Enter' && operation.value == 'fold'){
foldEnd('Enter')
}else if(event.key === 'Delete'){
deleteObject()
}else if(keyDown.indexOf('ControlLeft') > -1 && keyDown.indexOf('KeyZ') > -1 && keyDown.indexOf('ShiftLeft') > -1){
}else if((keyDown.indexOf('ControlLeft') > -1 || keyDown.indexOf('MetaLeft') > -1) && event.code == 'KeyZ' && keyDown.indexOf('ShiftLeft') > -1){
historyState('reverse')
}else if(keyDown.indexOf('ControlLeft') > -1 && keyDown.indexOf('KeyZ') > -1){
}else if((keyDown.indexOf('ControlLeft') > -1 || keyDown.indexOf('MetaLeft') > -1) && event.code == 'KeyZ'){
historyState('')
}else if(keyDown.indexOf('ControlLeft') > -1 && keyDown.indexOf('KeyC') > -1){
}else if((keyDown.indexOf('ControlLeft') > -1 || keyDown.indexOf('MetaLeft') > -1) && event.code == 'KeyC'){
copy()
}else if(keyDown.indexOf('ControlLeft') > -1 && keyDown.indexOf('KeyV') > -1){
}else if((keyDown.indexOf('ControlLeft') > -1 || keyDown.indexOf('MetaLeft') > -1) && event.code == 'KeyV'){
paste()
}else if(keyDown.indexOf('BracketLeft') > -1){
let width = canvasPencilWidth.value[operation.value]
canvasPencilWidth.value[operation.value] = (width - 5) < 3?3:(width - 5)
setPencilWidth()
}else if(keyDown.indexOf('BracketRight') > -1){
let width = canvasPencilWidth.value[operation.value]
canvasPencilWidth.value[operation.value] = (width + 5) > 50?50:(width + 5)
setPencilWidth()
}else if(keyDown.indexOf('KeyI') > -1){
getColor()//吸色
}else if(keyDown.indexOf('KeyM') > -1){
setOperation('move')
}else if((keyDown.indexOf('ControlLeft') > -1 || keyDown.indexOf('MetaLeft') > -1) && event.code == 'KeyD'){
canvas.discardActiveObject().renderAll();
}else if((keyDown.indexOf('ControlLeft') > -1 || keyDown.indexOf('MetaLeft') > -1) && event.code == 'KeyO'){
let input = document.querySelector('.uploadImage input')
input.click()
}else if(keyDown.indexOf('KeyB') > -1){
// if(operation.value == 'pencil' || operation.value == 'texture'){
setOperation('pencil')
// }
}else if(keyDown.indexOf('KeyE') > -1){
// if(operation.value == 'pencil' || operation.value == 'texture'){
setOperation('eraser')
// }
}
}
}
let getColor = async ()=>{
try {
const dropper = new EyeDropper();
const result = await dropper.open();
let hex = result.sRGBHex.replace("#", "");
// 将十六进制颜色码拆分成红、绿、蓝三个部分
// const r = parseInt(hex.substring(0, 2), 16);
// const g = parseInt(hex.substring(2, 4), 16);
// const b = parseInt(hex.substring(4, 6), 16);
canvasPencilColor.value = result.sRGBHex;
setPencilColor()
} catch (e) {
message.info(this.t('ColorboardUpload.jsContent1'))
}
}
let canvasKeyUp = (event) =>{
let keys = ['Enter','Delete','ControlLeft','KeyZ','ShiftLeft','KeyC','KeyV','BracketLeft','BracketRight','KeyI','KeyD','KeyO','KeyE','KeyB','MetaLeft']
if(keys.indexOf(event.code) > -1){
event.preventDefault();
}
keyDown = keyDown.filter(function(item) {
return event.code !== item;
})
@@ -1566,6 +1685,7 @@ export default defineComponent({
setFontFamily()
return
}
console.log(canvasPencilColor.value);
// brushIndicator.fill = canvasPencilColor.value;
if(canvas.freeDrawingBrush.isEraser){
}else{
@@ -1968,6 +2088,12 @@ export default defineComponent({
userlikeGroupId:userlikeGroupId,
}
publishModal.init(data)
document.removeEventListener('keydown',canvasKeyDown);
document.removeEventListener('keyup', canvasKeyUp);
}
const clearPublish = ()=>{
document.addEventListener('keydown',canvasKeyDown);
document.addEventListener('keyup', canvasKeyUp);
}
let setSubmit = ()=>{
let data = setCanvasContent(false)
@@ -2025,11 +2151,15 @@ export default defineComponent({
updateCanvasState()
});
}
const clearLiquefaction = ()=>{
setCanvasKeyDown()
}
let setLiquefaction = ()=>{
const activeObjects = canvas.getActiveObjects(); // 获取选中的对象
if (activeObjects.length === 1 && activeObjects[0].type === 'image') {
liquefactionData = activeObjects[0]
liquefaction.value.init(activeObjects[0])
clearCanvasKeyDown()
} else {
message.info(useI18.t('exportModel.jsContent6'))
return null;
@@ -2057,10 +2187,14 @@ export default defineComponent({
fontFamily.value = arr[0].value
});
onBeforeUnmount(()=>{
clearCanvasKeyDown()
})
return {
toSvg,
t,
toSvg,
isWindow,//判断是window还是mac
showUpgradePlan,//当前弹窗是否打开
canvasWH,//画布初始宽高
pencilbtnStyle,//笔触按钮
@@ -2085,6 +2219,7 @@ export default defineComponent({
uploadImage,//上传图帕
setLayerIndex,//设置选中元素的层级
brushList,//笔触列表
clearPublish,
textureList,//材质列表
canvasPencilColor,//input选择颜色
canvasPencilWidth,//input选择宽度
@@ -2096,6 +2231,7 @@ export default defineComponent({
setPencilWidth,//切换宽度执行函数 给当前矩形或者笔触设置宽度
setHDExport,//高清导出选择的图片
brushworkChange,//切换笔触的回调
keysList,
textureValueChange,//切换材质信息
brushworkValue,//当前笔触
textureValue,//当前材质
@@ -2118,6 +2254,7 @@ export default defineComponent({
//液化
liquefaction,
submitLiquefaction,
clearLiquefaction,
setLiquefaction,
};
},
@@ -2234,10 +2371,18 @@ export default defineComponent({
</script>
<style lang="less" scoped>
.Export {
:deep(.Export) {
flex: 1;
// height: 30rem;
// overflow-x: hidden;
>.ant-modal-content {
.ant-modal-body{
display: flex;
flex-direction: column;
background: #f9fafb;
border-radius: 3rem;
}
}
.icon{
transition: all .3s;
}
@@ -2263,7 +2408,6 @@ export default defineComponent({
justify-content: space-between;
cursor: pointer;
position: sticky;
background: #f9fafb;
z-index: 2;
align-items: flex-start;
margin: 0 2rem;
@@ -2282,6 +2426,39 @@ export default defineComponent({
.exportCanvasBox_left_tool{
margin: 0;
}
.shortcutKeys_box{
position: relative;
.shortcutKeys_list{
display: none;
position: absolute;
z-index: 2;
width: 30rem;
max-height: 45rem;
background: #f7f8fa;
border-radius: 2rem;
right: 0;
overflow-y: auto;
padding: 2rem;
.shortcutKeys_list_item{
display: flex;
font-size: 1.8rem;
justify-content: space-between;
margin-bottom: 2rem;
>.key{
display: flex;
}
}
.shortcutKeys_list_item:last-child{
margin-bottom: 0;
}
}
&:hover{
.shortcutKeys_list{
display: block;
}
}
}
.label_item,label {
display: flex;
align-items: center;

View File

@@ -15,7 +15,7 @@
<div class="input_border" >
<div class="input_box Guide_1_5" :class="[inputShow?'active':'',type_.type2 =='Sketchboard'?'Guide_1_9_2':'',driver__.driver?'showEvents':'']">
<div class="input_box_btnBox" v-if="scene?.value != 'extract'">
<div class="upload_item">
<div class="upload_item" v-show="sketchboardList?.length != 0">
<div
class="upload_file_item Guide_1_2_7"
v-for="(file, index) in sketchboardList"
@@ -47,6 +47,7 @@
v-model="searchPictureName"
@keydown.enter="getgenerate()"
@click="inputFocus()"
@paste="onPaste"
/>
<i class="fi fi-br-upload" :class="{ Guide_1_2_6:type_.type2 == 'Printboard'}" :title="$t('Generate.uploadTitle')" v-show="!isTextarea && upload.level1Type !== 'Moodboard' && scene?.value != 'Slogan' && scene?.value != 'Logo'">
<a-upload
@@ -195,6 +196,7 @@
</div>
<scaleImage ref="scaleImage" :isCanvas="type_.type2 == 'Sketchboard'" :workspace="workspace"></scaleImage>
<createSlogan ref="createSlogan" @setSloganData="setSloganData"></createSlogan>
<UpgradePlan ref="UpgradePlan"></UpgradePlan>
</div>
</template>
<script lang="ts">
@@ -214,17 +216,22 @@ import { openGuide,driverObj__,driverIndex__ } from "@/tool/guide";
import createSlogan from "@/component/HomePage/createSlogan.vue";
import { useI18n } from "vue-i18n";
import sketchCategory from "@/component/HomePage/sketchCategory.vue";
import UpgradePlan from "@/component/HomePage/UpgradePlan.vue";
export default defineComponent({
components: {
scaleImage,
generalMenu,
createSlogan,
sketchCategory,
UpgradePlan,
},
props: ["msg",'sketchCatecoryList','scene'],
setup(props) {
// console.log(prop.msg);
let userDetail:any= computed(()=>{
return store.state.UserHabit.userDetail
})
let printModelList:any = ref([])
let sketchStyleList:any = ref([])
let printModel:any = ref({
@@ -252,7 +259,6 @@ export default defineComponent({
let driver__:any = inject('driver__')
let {t} = useI18n()
let isTest = ref()
let userInfo:any = {}
let generateTime:any = ref()
let generateProceedList:any = ref([])
let remGenerate:any = ref(false)
@@ -293,6 +299,7 @@ export default defineComponent({
speed.speedData = item
}
return {
userDetail,
searchPictureName,
searchPictureSeed,
store,
@@ -313,7 +320,6 @@ export default defineComponent({
driver__,
t,
isTest,
userInfo,
generateTime,
generateProceedList,
remGenerate,
@@ -361,8 +367,6 @@ export default defineComponent({
// item.id_ = GO.id++
// })
// this.store.commit("addGenerateFils", this.fileList);
let userInfo:any = getCookie("userInfo")
this.userInfo = JSON.parse(userInfo);
this.token = getCookie("token") || "";
let isTest:any = getCookie('isTest')
this.isTest =JSON.parse(isTest)
@@ -588,7 +592,7 @@ export default defineComponent({
level2Type:level2Type,
text:sloganText,
seed:this.searchPictureSeed,
userId:this?.userInfo?.userId,
userId:this?.userDetail?.userId,
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
version:this.speedData.value,//为1就是Print
isTestUser:this.driver__.driver?false:this.isTest,
@@ -602,21 +606,15 @@ export default defineComponent({
},10000)
Https.axiosPost(Https.httpUrls.generatePrepare, data).then(
(rv) => {
if(data.isTestUser){
if(rv.leftUsageCount >= 1){
message.warning(this.t('Generate.jsContent8',{num:rv.leftUsageCount,str:this.t('collectionModal.Moodboard')}));
}else if(rv.leftUsageCount == 0){
message.warning(this.t('Generate.jsContent9',{str:this.t('collectionModal.Moodboard')}));
this.isGenerate = false
return
}
}
// rv.uniqueId.forEach((item:any) => {
// let arr:any = {}
// arr.taskId = item
// arr.status = 'execution'
// this.fileList.unshift(arr)
// });
// if(data.isTestUser){
// if(rv.leftUsageCount >= 1){
// message.warning(this.t('Generate.jsContent8',{num:rv.leftUsageCount,str:this.t('collectionModal.Moodboard')}));
// }else if(rv.leftUsageCount == 0){
// message.warning(this.t('Generate.jsContent9',{str:this.t('collectionModal.Moodboard')}));
// this.isGenerate = false
// return
// }
// }
this.setGenerate(rv.uniqueId)
}
@@ -625,6 +623,26 @@ export default defineComponent({
this.isGenerate = false
clearInterval(this.remGenerateTime)
this.remGenerate = false
if(res.errCode === 2){
let this_ = this
Modal.confirm({
title: res.errMsg,
icon: createVNode(ExclamationCircleOutlined),
okText: 'Yes',
cancelText: 'No',
mask:false,
zIndex:99999,
centered:true,
onOk() {
let UpgradePlan:any = this_.$refs.UpgradePlan
UpgradePlan.init()
},
onCancel(){
}
});
}
});
},
setGenerate(dataList:any){
@@ -701,7 +719,7 @@ export default defineComponent({
}
let data = {
uniqueId:str,
userId:this?.userInfo?.userId,
userId:this?.userDetail?.userId,
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
type: type
}
@@ -790,12 +808,12 @@ export default defineComponent({
file.id_ = GO.id++;
file.categoryValue = category?.value;
file.category = category?.name;
let fileList = this.sketchboardList.filter(
(v: any) => v.status === "done"
);
this.sketchboardList = fileList
//判断是否粘贴来的图片
let paste = this.sketchboardList.filter((v: any) => v.id === file.id);
if(paste.length == 0)this.sketchboardList.push(file);
this.sketchboardList = this.sketchboardList.filter((v: any) => v.status === "done");
nextTick().then(()=>{
if(this.driver__.driver){
if(this.driver__.driver && this.type_.type2 == 'Printboard'){
driverObj__.moveNext()
}
})
@@ -904,6 +922,32 @@ export default defineComponent({
// this.myMaterialModalShow = false
this.searchPictureName = "";
},
onPaste(e:any){
if(e.clipboardData.items[0] && !this.isTextarea && this.upload.level1Type !== 'Moodboard' && this.scene?.value != 'Slogan' && this.scene?.value != 'Logo'){
let param = new FormData();
param.append('inPin','0')
param.append('gender',this.upload.gender)
param.append('level1Type',this.upload.level1Type)
param.append('timeZone',Intl.DateTimeFormat().resolvedOptions().timeZone)
param.append('file',e.clipboardData.files[0]);
let config:any = {headers:{'Content-Type':'multipart/form-data','Accept':'*/*' }}
Https.axiosPost(Https.httpUrls.elementUpload, param, config).then((v)=>{
let value = {data:v,errCode : 0}
v.status = 'done'
let data = {
file:{
status: 'done',
xhr:{
response:JSON.stringify(value)
}
}
}
this.fileUploadChange(data)
})
}
}
},
});
</script>
@@ -919,7 +963,7 @@ export default defineComponent({
position: relative;
// padding-top: calc(2.5rem*1.2);
.input_border{
padding-top: calc(2.5rem*1.2);
padding-top: 1rem;
}
.mark_loading{

View File

@@ -420,7 +420,6 @@ export default defineComponent({
(rv) => {
if (rv) {
this.userInfo.email = this.email;
setCookie("userInfo", JSON.stringify(this.userInfo));
(this.bindEmailVisible = false),
(this.bindEmailStep = 1);
this.clearTimer();

View File

@@ -149,7 +149,6 @@
</div>
<layout ref="layout" :moodb_className="moodb_className" :flex_direction="flex_direction" @setmoodbClass="setmoodbClass"></layout>
<layoutMobile ref="layoutMobile" :moodb_className="moodb_className" :flex_direction="flex_direction" @setmoodbClass="setmoodbClass"></layoutMobile>
</div>
</template>
@@ -165,14 +164,13 @@ import Material from "@/component/HomePage/Material.vue";
import Generate from "@/component/HomePage/Generate.vue";
import MoodTemplate from "@/component/HomePage/MoodTemplate.vue";
import layout from "@/component/HomePage/layout.vue";
import layoutMobile from "@/component/HomePage/layoutMobile.vue";
import domTurnImg from '@/tool/domTurnImg'
import GO from "@/tool/GO";
import moodb from "@/tool/moodb";
import { useI18n } from "vue-i18n";
import { openGuide,driverObj__ } from "@/tool/guide";
export default defineComponent({
components: { Material, MoodTemplate, Generate,layout,layoutMobile },
components: { Material, MoodTemplate, Generate,layout },
setup() {
const store = useStore()
let lessenList: any = ref([]);
@@ -437,7 +435,6 @@ export default defineComponent({
async changeTemplateModal() {
if(this.modalImg[0]?.id){
// let layout:any = isMoible() ? this.$refs.layoutMobile : this.$refs.layout
let layout:any = this.$refs.layout
if(this.layoutList.length <= 0){
let styleObj = this.store.state.UploadFilesModule.moodboardPosition

Some files were not shown because too many files have changed in this diff Show More