first commit
3
.env.production
Normal file
@@ -0,0 +1,3 @@
|
||||
NODE_ENV = 'production'
|
||||
VUE_APP_BASE_URL = 'https://www.aida.com.hk'
|
||||
|
||||
2
.env.test
Normal file
@@ -0,0 +1,2 @@
|
||||
NODE_ENV = 'production'
|
||||
VUE_APP_BASE_URL = 'http://18.162.111.141:80'
|
||||
72
.eslintrc.js
Normal file
@@ -0,0 +1,72 @@
|
||||
module.exports = {
|
||||
root: true, // 停止在父级目录中寻找
|
||||
env: {
|
||||
es6: true, // 启用 ES6 语法支持以及新的 ES6 全局变量或类型
|
||||
node: true // Node.js 全局变量和 Node.js 作用域
|
||||
},
|
||||
extends: ['plugin:vue/essential'],
|
||||
rules: {
|
||||
'no-alert': 0, // 禁止使用alert confirm prompt
|
||||
'no-console': 0, // 禁止使用console
|
||||
'no-debugger': 0, // 禁止使用debugger
|
||||
'prefer-const': 0, // 建议使用 const 关闭
|
||||
'no-dupe-keys': 2, // 在创建对象字面量时不允许键重复 {a:1,a:1}
|
||||
'no-dupe-args': 2, // 函数参数不能重复
|
||||
'no-duplicate-imports': [
|
||||
1,
|
||||
{
|
||||
includeExports: true
|
||||
}
|
||||
], // 不允许重复导入
|
||||
|
||||
'no-duplicate-case': 2, // switch中的case标签不能重复
|
||||
'padded-blocks': 0, // 块语句内行首行尾是否要空行
|
||||
'space-after-keywords': [0, 'always'], // 关键字后面是否要空一格
|
||||
'space-before-blocks': [0, 'always'], // 不以新行开始的块{前面要不要有空格
|
||||
'space-before-function-paren': [0, 'always'], // 函数定义时括号前面要不要有空格
|
||||
'space-in-parens': [0, 'never'], // 小括号里面要不要有空格
|
||||
'space-infix-ops': 0, // 中缀操作符周围要不要有空格
|
||||
eqeqeq: 0, // 必须使用全等
|
||||
'no-var': 0, // 禁用var,用let和const代替
|
||||
'no-inline-comments': 0, // 禁止行内备注
|
||||
indent: 0,
|
||||
'vue/script-indent': 0,
|
||||
'vue/require-prop-type-constructor': 0,
|
||||
'vue/no-use-v-if-with-v-for': 0,
|
||||
'no-trailing-spaces': 0, // 一行结束后面不要有空格
|
||||
'no-multiple-empty-lines': 0, // [1, {"max": 2}],空行最多不能超过2行
|
||||
'no-extra-boolean-cast': 0, // 禁止不必要的bool转换
|
||||
'valid-jsdoc': 0,
|
||||
'one-var': 0, // 连续声明
|
||||
semi: 0, // 语句强制分号结尾
|
||||
'semi-spacing': [0, { before: false, after: true }], // 分号前后空格
|
||||
'no-new': 0, // 禁止在使用new构造一个实例后不赋值
|
||||
'no-extra-semi': 0, // 禁止多余的冒号
|
||||
'keyword-spacing': 0,
|
||||
'arrow-parens': 0, // 箭头函数用小括号括起来 - 关闭
|
||||
'generator-star-spacing': 0, // 生成器函数*的前后空格
|
||||
'no-mixed-operators': 0,
|
||||
'eol-last': 0, // 文件以单一的换行符结束 - 关闭
|
||||
'object-curly-spacing': 0, // 大括号内是否允许不必要的空格
|
||||
'no-callback-literal': 0,
|
||||
'multiline-ternary': 0,
|
||||
'no-self-assign':'off',
|
||||
'vue/multi-word-component-names': "off",
|
||||
"vue/no-v-model-argument": "off",
|
||||
},
|
||||
plugins:[
|
||||
'vue'
|
||||
],
|
||||
parserOptions: {
|
||||
parser: 'babel-eslint',
|
||||
"requireConfigFile": false,
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ['**/__tests__/*.{j,t}s?(x)', '**/tests/unit/**/*.spec.{j,t}s?(x)'],
|
||||
env: {
|
||||
jest: true
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
24
.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
dist.rar
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
5
babel.config.js
Normal file
@@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
'@vue/cli-plugin-babel/preset'
|
||||
]
|
||||
}
|
||||
21464
package-lock.json
generated
Normal file
70
package.json
Normal file
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"name": "aida",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"build:test": "vue-cli-service build --mode test",
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ans1998/vue3-color": "^3.0.7",
|
||||
"ant-design-vue": "^3.2.12",
|
||||
"axios": "^0.27.2",
|
||||
"core-js": "^3.8.3",
|
||||
"file-saver": "^2.0.5",
|
||||
"html2canvas": "^1.4.1",
|
||||
"jszip": "^3.10.1",
|
||||
"md5": "^2.3.0",
|
||||
"quantize": "^1.0.2",
|
||||
"sortablejs": "^1.15.0",
|
||||
"vue": "^3.2.13",
|
||||
"vue-class-component": "^8.0.0-0",
|
||||
"vue-cropper": "^1.0.5",
|
||||
"vue-router": "^4.0.3",
|
||||
"vuedraggable": "^4.1.0",
|
||||
"vuex": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
||||
"@typescript-eslint/parser": "^5.4.0",
|
||||
"@vue/cli-plugin-babel": "~5.0.0",
|
||||
"@vue/cli-plugin-eslint": "~5.0.0",
|
||||
"@vue/cli-plugin-router": "~5.0.0",
|
||||
"@vue/cli-plugin-typescript": "~5.0.0",
|
||||
"@vue/cli-plugin-vuex": "~5.0.0",
|
||||
"@vue/cli-service": "~5.0.0",
|
||||
"@vue/eslint-config-typescript": "^9.1.0",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-plugin-vue": "^8.0.3",
|
||||
"less": "^4.1.3",
|
||||
"less-loader": "^11.0.0",
|
||||
"style-resources-loader": "^1.5.0",
|
||||
"typescript": "~4.5.5",
|
||||
"vue-cli-plugin-style-resources-loader": "^0.1.5",
|
||||
"vue-lazyload": "^3.0.0-rc.2"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:vue/vue3-essential",
|
||||
"eslint:recommended",
|
||||
"@vue/typescript/recommended"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2020
|
||||
},
|
||||
"rules": {}
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not dead",
|
||||
"not ie 11"
|
||||
]
|
||||
}
|
||||
BIN
public/favicon.ico
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
20
public/index.html
Normal file
@@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<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">
|
||||
</head>
|
||||
<body>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/color-thief/2.3.0/color-thief.umd.js"></script>
|
||||
<noscript>
|
||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
||||
11
src/App.vue
Normal file
@@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<router-view/>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
#app {
|
||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
</style>
|
||||
199
src/assets/iconfont/iconfont.css
Normal file
@@ -0,0 +1,199 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 3608736 */
|
||||
src: url('iconfont.woff2?t=1668859174141') format('woff2'),
|
||||
url('iconfont.woff?t=1668859174141') format('woff'),
|
||||
url('iconfont.ttf?t=1668859174141') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-family: "iconfont" !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-yanjing_yincang_o:before {
|
||||
content: "\ebcd";
|
||||
}
|
||||
|
||||
.icon-31tishi:before {
|
||||
content: "\e601";
|
||||
}
|
||||
|
||||
.icon-tianxie:before {
|
||||
content: "\ec88";
|
||||
}
|
||||
|
||||
.icon-moban:before {
|
||||
content: "\e664";
|
||||
}
|
||||
|
||||
.icon-fuwushichang:before {
|
||||
content: "\e7ee";
|
||||
}
|
||||
|
||||
.icon-sumiao:before {
|
||||
content: "\ee24";
|
||||
}
|
||||
|
||||
.icon-dayin-dayinji:before {
|
||||
content: "\e619";
|
||||
}
|
||||
|
||||
.icon-baocun1:before {
|
||||
content: "\e644";
|
||||
}
|
||||
|
||||
.icon-fanhui1:before {
|
||||
content: "\e60e";
|
||||
}
|
||||
|
||||
.icon-huifu:before {
|
||||
content: "\e652";
|
||||
}
|
||||
|
||||
.icon-shengchengyulan:before {
|
||||
content: "\e613";
|
||||
}
|
||||
|
||||
.icon-xiangqing-:before {
|
||||
content: "\e608";
|
||||
}
|
||||
|
||||
.icon-zhongmingming:before {
|
||||
content: "\e64c";
|
||||
}
|
||||
|
||||
.icon-sousuo:before {
|
||||
content: "\e607";
|
||||
}
|
||||
|
||||
.icon-tianjiatupian_huaban:before {
|
||||
content: "\e62c";
|
||||
}
|
||||
|
||||
.icon-rili:before {
|
||||
content: "\e62a";
|
||||
}
|
||||
|
||||
.icon-xiayibu:before {
|
||||
content: "\e6ba";
|
||||
}
|
||||
|
||||
.icon-shangyibu:before {
|
||||
content: "\e60d";
|
||||
}
|
||||
|
||||
.icon-mote:before {
|
||||
content: "\e61f";
|
||||
}
|
||||
|
||||
.icon-guanbi:before {
|
||||
content: "\eca0";
|
||||
}
|
||||
|
||||
.icon-shanchu:before {
|
||||
content: "\e663";
|
||||
}
|
||||
|
||||
.icon-tianjiatubiao:before {
|
||||
content: "\e60b";
|
||||
}
|
||||
|
||||
.icon-xialajiantouxiao:before {
|
||||
content: "\e87e";
|
||||
}
|
||||
|
||||
.icon-xuanze:before {
|
||||
content: "\e667";
|
||||
}
|
||||
|
||||
.icon-jiahao:before {
|
||||
content: "\e614";
|
||||
}
|
||||
|
||||
.icon-shuaxin:before {
|
||||
content: "\e62f";
|
||||
}
|
||||
|
||||
.icon-chexiao:before {
|
||||
content: "\e637";
|
||||
}
|
||||
|
||||
.icon-yulan:before {
|
||||
content: "\e656";
|
||||
}
|
||||
|
||||
.icon-zhuyi:before {
|
||||
content: "\e633";
|
||||
}
|
||||
|
||||
.icon-ziyuan:before {
|
||||
content: "\e624";
|
||||
}
|
||||
|
||||
.icon-baocun:before {
|
||||
content: "\e60a";
|
||||
}
|
||||
|
||||
.icon-yunlishi:before {
|
||||
content: "\e665";
|
||||
}
|
||||
|
||||
.icon-huoquduixiang:before {
|
||||
content: "\e61e";
|
||||
}
|
||||
|
||||
.icon-diaosebanpalette3:before {
|
||||
content: "\e635";
|
||||
}
|
||||
|
||||
.icon-tuichu1:before {
|
||||
content: "\e612";
|
||||
}
|
||||
|
||||
.icon-window-up-full:before {
|
||||
content: "\e9c1";
|
||||
}
|
||||
|
||||
.icon-yansefangan:before {
|
||||
content: "\ed99";
|
||||
}
|
||||
|
||||
.icon-fanhui:before {
|
||||
content: "\e655";
|
||||
}
|
||||
|
||||
.icon-youxiang:before {
|
||||
content: "\e908";
|
||||
}
|
||||
|
||||
.icon-tuichu:before {
|
||||
content: "\e60c";
|
||||
}
|
||||
|
||||
.icon-dangqianweizhi:before {
|
||||
content: "\e642";
|
||||
}
|
||||
|
||||
.icon-jushoucang:before {
|
||||
content: "\e643";
|
||||
}
|
||||
|
||||
.icon-jushoucanggift:before {
|
||||
content: "\e684";
|
||||
}
|
||||
|
||||
.icon-touxiang3:before {
|
||||
content: "\e632";
|
||||
}
|
||||
|
||||
.icon-xiala:before {
|
||||
content: "\e64d";
|
||||
}
|
||||
|
||||
.icon--shangyibu:before {
|
||||
content: "\e620";
|
||||
}
|
||||
|
||||
1
src/assets/iconfont/iconfont.js
Normal file
331
src/assets/iconfont/iconfont.json
Normal file
@@ -0,0 +1,331 @@
|
||||
{
|
||||
"id": "3608736",
|
||||
"name": "AIDL",
|
||||
"font_family": "iconfont",
|
||||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "5388071",
|
||||
"name": "眼睛_隐藏_o",
|
||||
"font_class": "yanjing_yincang_o",
|
||||
"unicode": "ebcd",
|
||||
"unicode_decimal": 60365
|
||||
},
|
||||
{
|
||||
"icon_id": "201572",
|
||||
"name": "3.1-提示",
|
||||
"font_class": "31tishi",
|
||||
"unicode": "e601",
|
||||
"unicode_decimal": 58881
|
||||
},
|
||||
{
|
||||
"icon_id": "6337498",
|
||||
"name": "编辑",
|
||||
"font_class": "tianxie",
|
||||
"unicode": "ec88",
|
||||
"unicode_decimal": 60552
|
||||
},
|
||||
{
|
||||
"icon_id": "3851366",
|
||||
"name": "模板",
|
||||
"font_class": "moban",
|
||||
"unicode": "e664",
|
||||
"unicode_decimal": 58980
|
||||
},
|
||||
{
|
||||
"icon_id": "18494056",
|
||||
"name": "服务市场",
|
||||
"font_class": "fuwushichang",
|
||||
"unicode": "e7ee",
|
||||
"unicode_decimal": 59374
|
||||
},
|
||||
{
|
||||
"icon_id": "22385752",
|
||||
"name": "素描",
|
||||
"font_class": "sumiao",
|
||||
"unicode": "ee24",
|
||||
"unicode_decimal": 60964
|
||||
},
|
||||
{
|
||||
"icon_id": "26257269",
|
||||
"name": "打印-打印机",
|
||||
"font_class": "dayin-dayinji",
|
||||
"unicode": "e619",
|
||||
"unicode_decimal": 58905
|
||||
},
|
||||
{
|
||||
"icon_id": "9568043",
|
||||
"name": "保存",
|
||||
"font_class": "baocun1",
|
||||
"unicode": "e644",
|
||||
"unicode_decimal": 58948
|
||||
},
|
||||
{
|
||||
"icon_id": "10933908",
|
||||
"name": "返回",
|
||||
"font_class": "fanhui1",
|
||||
"unicode": "e60e",
|
||||
"unicode_decimal": 58894
|
||||
},
|
||||
{
|
||||
"icon_id": "22138734",
|
||||
"name": "恢复",
|
||||
"font_class": "huifu",
|
||||
"unicode": "e652",
|
||||
"unicode_decimal": 58962
|
||||
},
|
||||
{
|
||||
"icon_id": "28782404",
|
||||
"name": "生成预览",
|
||||
"font_class": "shengchengyulan",
|
||||
"unicode": "e613",
|
||||
"unicode_decimal": 58899
|
||||
},
|
||||
{
|
||||
"icon_id": "10392628",
|
||||
"name": "详情-",
|
||||
"font_class": "xiangqing-",
|
||||
"unicode": "e608",
|
||||
"unicode_decimal": 58888
|
||||
},
|
||||
{
|
||||
"icon_id": "17272014",
|
||||
"name": "重命名",
|
||||
"font_class": "zhongmingming",
|
||||
"unicode": "e64c",
|
||||
"unicode_decimal": 58956
|
||||
},
|
||||
{
|
||||
"icon_id": "27966456",
|
||||
"name": "搜索",
|
||||
"font_class": "sousuo",
|
||||
"unicode": "e607",
|
||||
"unicode_decimal": 58887
|
||||
},
|
||||
{
|
||||
"icon_id": "12753044",
|
||||
"name": "添加图片",
|
||||
"font_class": "tianjiatupian_huaban",
|
||||
"unicode": "e62c",
|
||||
"unicode_decimal": 58924
|
||||
},
|
||||
{
|
||||
"icon_id": "10156220",
|
||||
"name": "日历",
|
||||
"font_class": "rili",
|
||||
"unicode": "e62a",
|
||||
"unicode_decimal": 58922
|
||||
},
|
||||
{
|
||||
"icon_id": "672037",
|
||||
"name": "下一步",
|
||||
"font_class": "xiayibu",
|
||||
"unicode": "e6ba",
|
||||
"unicode_decimal": 59066
|
||||
},
|
||||
{
|
||||
"icon_id": "1001422",
|
||||
"name": "上一步",
|
||||
"font_class": "shangyibu",
|
||||
"unicode": "e60d",
|
||||
"unicode_decimal": 58893
|
||||
},
|
||||
{
|
||||
"icon_id": "5220657",
|
||||
"name": "模特",
|
||||
"font_class": "mote",
|
||||
"unicode": "e61f",
|
||||
"unicode_decimal": 58911
|
||||
},
|
||||
{
|
||||
"icon_id": "6616997",
|
||||
"name": "关闭",
|
||||
"font_class": "guanbi",
|
||||
"unicode": "eca0",
|
||||
"unicode_decimal": 60576
|
||||
},
|
||||
{
|
||||
"icon_id": "7450626",
|
||||
"name": "删除",
|
||||
"font_class": "shanchu",
|
||||
"unicode": "e663",
|
||||
"unicode_decimal": 58979
|
||||
},
|
||||
{
|
||||
"icon_id": "23458810",
|
||||
"name": "添加图片",
|
||||
"font_class": "tianjiatubiao",
|
||||
"unicode": "e60b",
|
||||
"unicode_decimal": 58891
|
||||
},
|
||||
{
|
||||
"icon_id": "2076220",
|
||||
"name": " 下拉箭头小",
|
||||
"font_class": "xialajiantouxiao",
|
||||
"unicode": "e87e",
|
||||
"unicode_decimal": 59518
|
||||
},
|
||||
{
|
||||
"icon_id": "7450651",
|
||||
"name": "选择",
|
||||
"font_class": "xuanze",
|
||||
"unicode": "e667",
|
||||
"unicode_decimal": 58983
|
||||
},
|
||||
{
|
||||
"icon_id": "351760",
|
||||
"name": "加号",
|
||||
"font_class": "jiahao",
|
||||
"unicode": "e614",
|
||||
"unicode_decimal": 58900
|
||||
},
|
||||
{
|
||||
"icon_id": "6966935",
|
||||
"name": "刷新",
|
||||
"font_class": "shuaxin",
|
||||
"unicode": "e62f",
|
||||
"unicode_decimal": 58927
|
||||
},
|
||||
{
|
||||
"icon_id": "11399565",
|
||||
"name": "撤销",
|
||||
"font_class": "chexiao",
|
||||
"unicode": "e637",
|
||||
"unicode_decimal": 58935
|
||||
},
|
||||
{
|
||||
"icon_id": "5831330",
|
||||
"name": "预览",
|
||||
"font_class": "yulan",
|
||||
"unicode": "e656",
|
||||
"unicode_decimal": 58966
|
||||
},
|
||||
{
|
||||
"icon_id": "6903295",
|
||||
"name": "注意",
|
||||
"font_class": "zhuyi",
|
||||
"unicode": "e633",
|
||||
"unicode_decimal": 58931
|
||||
},
|
||||
{
|
||||
"icon_id": "8448539",
|
||||
"name": "启动工作流",
|
||||
"font_class": "ziyuan",
|
||||
"unicode": "e624",
|
||||
"unicode_decimal": 58916
|
||||
},
|
||||
{
|
||||
"icon_id": "14313157",
|
||||
"name": "保存",
|
||||
"font_class": "baocun",
|
||||
"unicode": "e60a",
|
||||
"unicode_decimal": 58890
|
||||
},
|
||||
{
|
||||
"icon_id": "16372346",
|
||||
"name": "云历史",
|
||||
"font_class": "yunlishi",
|
||||
"unicode": "e665",
|
||||
"unicode_decimal": 58981
|
||||
},
|
||||
{
|
||||
"icon_id": "15296099",
|
||||
"name": "获取对象",
|
||||
"font_class": "huoquduixiang",
|
||||
"unicode": "e61e",
|
||||
"unicode_decimal": 58910
|
||||
},
|
||||
{
|
||||
"icon_id": "775360",
|
||||
"name": "调色板_palette3",
|
||||
"font_class": "diaosebanpalette3",
|
||||
"unicode": "e635",
|
||||
"unicode_decimal": 58933
|
||||
},
|
||||
{
|
||||
"icon_id": "8229473",
|
||||
"name": "退出",
|
||||
"font_class": "tuichu1",
|
||||
"unicode": "e612",
|
||||
"unicode_decimal": 58898
|
||||
},
|
||||
{
|
||||
"icon_id": "18170455",
|
||||
"name": "展开",
|
||||
"font_class": "window-up-full",
|
||||
"unicode": "e9c1",
|
||||
"unicode_decimal": 59841
|
||||
},
|
||||
{
|
||||
"icon_id": "22376146",
|
||||
"name": "颜色方案",
|
||||
"font_class": "yansefangan",
|
||||
"unicode": "ed99",
|
||||
"unicode_decimal": 60825
|
||||
},
|
||||
{
|
||||
"icon_id": "6548532",
|
||||
"name": "返回",
|
||||
"font_class": "fanhui",
|
||||
"unicode": "e655",
|
||||
"unicode_decimal": 58965
|
||||
},
|
||||
{
|
||||
"icon_id": "4552970",
|
||||
"name": "邮箱",
|
||||
"font_class": "youxiang",
|
||||
"unicode": "e908",
|
||||
"unicode_decimal": 59656
|
||||
},
|
||||
{
|
||||
"icon_id": "6204098",
|
||||
"name": "退出",
|
||||
"font_class": "tuichu",
|
||||
"unicode": "e60c",
|
||||
"unicode_decimal": 58892
|
||||
},
|
||||
{
|
||||
"icon_id": "12109851",
|
||||
"name": "当前位置",
|
||||
"font_class": "dangqianweizhi",
|
||||
"unicode": "e642",
|
||||
"unicode_decimal": 58946
|
||||
},
|
||||
{
|
||||
"icon_id": "627569",
|
||||
"name": "聚收藏",
|
||||
"font_class": "jushoucang",
|
||||
"unicode": "e643",
|
||||
"unicode_decimal": 58947
|
||||
},
|
||||
{
|
||||
"icon_id": "829167",
|
||||
"name": "聚收藏gift",
|
||||
"font_class": "jushoucanggift",
|
||||
"unicode": "e684",
|
||||
"unicode_decimal": 59012
|
||||
},
|
||||
{
|
||||
"icon_id": "21954894",
|
||||
"name": "头像3",
|
||||
"font_class": "touxiang3",
|
||||
"unicode": "e632",
|
||||
"unicode_decimal": 58930
|
||||
},
|
||||
{
|
||||
"icon_id": "16913185",
|
||||
"name": "下拉",
|
||||
"font_class": "xiala",
|
||||
"unicode": "e64d",
|
||||
"unicode_decimal": 58957
|
||||
},
|
||||
{
|
||||
"icon_id": "6010943",
|
||||
"name": "2-上一步",
|
||||
"font_class": "-shangyibu",
|
||||
"unicode": "e620",
|
||||
"unicode_decimal": 58912
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
src/assets/iconfont/iconfont.ttf
Normal file
BIN
src/assets/iconfont/iconfont.woff
Normal file
BIN
src/assets/iconfont/iconfont.woff2
Normal file
BIN
src/assets/images/homePage/add_file.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
src/assets/images/homePage/bg.png
Normal file
|
After Width: | Height: | Size: 164 KiB |
BIN
src/assets/images/homePage/loading.gif
Normal file
|
After Width: | Height: | Size: 66 KiB |
BIN
src/assets/images/homePage/null_img.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
src/assets/images/homePage/system_model.png
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
src/assets/images/loginPage/aida_Logo_login.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
src/assets/images/loginPage/aida_logo.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
209
src/assets/style/style.less
Normal file
@@ -0,0 +1,209 @@
|
||||
|
||||
html,body,#app{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
}
|
||||
.page_content{
|
||||
width: 1440px;
|
||||
max-width: 100%;
|
||||
height: 100%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.button_first{
|
||||
width: 9.85rem;
|
||||
text-align: center;
|
||||
background: #E0E0F6;
|
||||
height: 4rem;
|
||||
line-height: 4rem;
|
||||
font-size: 1.3rem;
|
||||
font-weight: 400;
|
||||
color: #343579;
|
||||
cursor: pointer;
|
||||
}
|
||||
.button_second{
|
||||
width: 9.85rem;
|
||||
text-align: center;
|
||||
background: #343579;
|
||||
height: 4rem;
|
||||
line-height: 4rem;
|
||||
font-size: 1.4rem;
|
||||
font-weight: 400;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.system_silder{
|
||||
width: 100%;
|
||||
.ant-slider{
|
||||
margin: 0;
|
||||
width: 12rem;
|
||||
|
||||
.ant-slider-rail{
|
||||
height: 0.6rem;
|
||||
border-radius: 0.3rem;
|
||||
background: #F2F0FD;
|
||||
}
|
||||
.ant-slider-track{
|
||||
height: 0.6rem;
|
||||
border-radius: 0.3rem;
|
||||
background: #343579;
|
||||
}
|
||||
.ant-slider-handle{
|
||||
margin-top: -0.4rem;
|
||||
border: solid 0.2rem #343579;
|
||||
}
|
||||
}
|
||||
}
|
||||
.ant-tooltip{
|
||||
// top: 74px !important;
|
||||
z-index: 2;
|
||||
|
||||
.ant-tooltip-inner{
|
||||
background: #343579;
|
||||
border-radius: 5px;
|
||||
padding: 0.6rem 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.select_block{
|
||||
.ant-select:not(.ant-select-customize-input) .ant-select-selector{
|
||||
background: transparent;
|
||||
height: 4rem;
|
||||
border: 0.1rem solid #000 !important;
|
||||
border-radius: 0;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
.ant-select-single .ant-select-selector .ant-select-selection-item, .ant-select-single .ant-select-selector .ant-select-selection-placeholder{
|
||||
line-height: 3.8rem;
|
||||
color: #1A1A1A;
|
||||
font-size: 1.3rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
//弹窗公共样式
|
||||
|
||||
.modal_component{
|
||||
|
||||
&.ant-modal{
|
||||
top: 0;
|
||||
}
|
||||
.ant-modal-content{
|
||||
overflow: hidden;
|
||||
|
||||
.ant-modal-header{
|
||||
padding: 2.4rem 2.6rem;
|
||||
background: #F7F7F7;
|
||||
|
||||
.ant-modal-title{
|
||||
font-size: 1.8rem;
|
||||
line-height: 1.8rem;
|
||||
color: #030303;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-modal-body{
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//collection 弹窗
|
||||
.collection_modal{
|
||||
|
||||
.ant-modal-body{
|
||||
height: calc(80vh - 6.4rem);
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.ant-upload.ant-upload-select-picture-card{
|
||||
width: 16.5rem;
|
||||
height: 16.5rem;
|
||||
background: #FFFFFF;
|
||||
border: 0.3rem dashed #EDEDED;
|
||||
margin: 0 2rem 2rem 0;
|
||||
|
||||
.upload_tip_block{
|
||||
.icon-jiahao{
|
||||
font-size: 3.2rem;
|
||||
color: #B7B7B7;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-upload-text{
|
||||
font-size: 1.6rem;
|
||||
color: #B7B7B7;
|
||||
}
|
||||
}
|
||||
.ant-upload-list-picture-card-container{
|
||||
display: none !important;
|
||||
}
|
||||
.ant-upload-picture-card-wrapper{
|
||||
width: auto;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
//剪裁弹窗
|
||||
.cut_pricture_modal{
|
||||
|
||||
.ant-modal-body{
|
||||
height: 65.4rem;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.scroll_style{
|
||||
&::-webkit-scrollbar-button:single-button {
|
||||
// background-color: #ffffff;
|
||||
display: block;
|
||||
border-style: solid;
|
||||
height: 1.3rem;
|
||||
width: 1.4rem;
|
||||
}
|
||||
&::-webkit-scrollbar-button:single-button:vertical:decrement {
|
||||
border-width: 0 0.8rem 0.8rem 0.8rem;
|
||||
border-color: transparent transparent #555555 transparent;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-button:single-button:vertical:decrement:hover {
|
||||
border-color: transparent transparent #777777 transparent;
|
||||
}
|
||||
&::-webkit-scrollbar-button:single-button:vertical:increment {
|
||||
border-width: 0.8rem 0.8rem 0 0.8rem;
|
||||
border-color: #555555 transparent transparent transparent;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-button:vertical:single-button:increment:hover {
|
||||
border-color: #777777 transparent transparent transparent;
|
||||
}
|
||||
&::-webkit-scrollbar {
|
||||
/*滚动条整体样式*/
|
||||
width: 1.4rem; /*高宽分别对应横竖滚动条的尺寸*/
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
/*滚动条里面小方块*/
|
||||
background: #c2c2c2;
|
||||
opacity: 0.8;
|
||||
border-radius: 0.7rem;
|
||||
}
|
||||
&::-webkit-scrollbar-track {
|
||||
// background: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
//蒙层样式
|
||||
.mark_loading{
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 99999;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
344
src/component/Detail/AccessoryReplaceModal.vue
Normal file
@@ -0,0 +1,344 @@
|
||||
<template>
|
||||
<a-modal class="accessory_replace_modal"
|
||||
v-model:visible="accessoryReplaceShow"
|
||||
:footer="null"
|
||||
width="40rem"
|
||||
:maskClosable="false"
|
||||
:centered="true"
|
||||
>
|
||||
<template #closeIcon>
|
||||
<div class="close_icon" @click.stop="closeModal()"><span class="icon iconfont icon-guanbi"></span></div>
|
||||
</template>
|
||||
|
||||
<div class="accessory_replace_content">
|
||||
<div class="new_accessory_block">
|
||||
<div class="new_accessory_title">New {{othersData?.type}}</div>
|
||||
<div class="new_accessory_img_block">
|
||||
<img class="element_img" :src="othersData?.path">
|
||||
<div class="element_img_loading" v-show="loadingShow">
|
||||
<a-spin :indicator="indicator"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="new_accessory_operate_list">
|
||||
<div class="new_accessory_operate_button pervious_button" @click="changeElement('PREV')">Previous</div>
|
||||
<div class="new_accessory_operate_button fetch_button" @click="changeElement('NEXT')">Re-fetch</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="accessory_color_block" v-show="othersData?.type !== 'Earring' && othersData?.type !== 'Hairstyle'">
|
||||
<div class="accessory_color_block_header">Modify Color</div>
|
||||
<div class="accessory_color_block_body">
|
||||
<div class="review_color_block" :style="{background:`rgb(${modifyColor.r},${modifyColor.g},${modifyColor.b})`}"></div>
|
||||
<div class="setting_color_block">
|
||||
<div class="setting_color_content">
|
||||
<Chrome class="chrome_color" v-model="selectColor"></Chrome>
|
||||
<Slider class="sileder_color" v-model="selectColor"></Slider>
|
||||
</div>
|
||||
<div class="color_rgb_block">
|
||||
<div class="rgb_item">R:{{getSelectRGB(selectColor).r}}</div>
|
||||
<div class="rgb_item">G:{{getSelectRGB(selectColor).g}}</div>
|
||||
<div class="rgb_item">B:{{getSelectRGB(selectColor).b}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="submit_button" @click="submitOthers()">Submit</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent,ref,h} from 'vue'
|
||||
import { Chrome,Slider } from '@ans1998/vue3-color'
|
||||
import { Https } from "@/tool/https";
|
||||
import { useStore } from "vuex";
|
||||
import { LoadingOutlined } from '@ant-design/icons-vue';
|
||||
export default defineComponent({
|
||||
components:{Chrome,Slider},
|
||||
setup(){
|
||||
let selectColor:any = ref({rgba:{}}) //顔色选择器默认颜色
|
||||
let othersData:any = ref({})
|
||||
const store = useStore();
|
||||
return {
|
||||
selectColor,
|
||||
othersData,
|
||||
store
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
loadingShow:false,
|
||||
accessoryReplaceShow:false,
|
||||
modifyColor:{r:255,g:255,b:255},
|
||||
othersIndex:0, //该元素在列表中的索引
|
||||
indicator : h(LoadingOutlined, {
|
||||
style: {
|
||||
fontSize: '2.4rem',
|
||||
},
|
||||
spin: true,
|
||||
}),
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
selectColor(newVal:any,oldVal:any){
|
||||
this.modifyColor = newVal.rgba || {}
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
getSelectRGB(selectColor){
|
||||
return (selectColor:any)=>{
|
||||
let rgba = selectColor.rgba
|
||||
let data = {
|
||||
r:rgba?.r || 255,
|
||||
g:rgba?.g || 255,
|
||||
b:rgba?.b || 255
|
||||
}
|
||||
return data
|
||||
}
|
||||
},
|
||||
},
|
||||
methods:{
|
||||
showAccessoryReplaceModal(data:any){
|
||||
this.othersData = JSON.parse(JSON.stringify(data.others))
|
||||
this.othersIndex = data.index
|
||||
this.accessoryReplaceShow = true
|
||||
let color = this.othersData.color ? this.othersData.color.split(' ') :''
|
||||
this.selectColor = {rgba:{r:color[0],g:color[1],b:color[2]}}
|
||||
},
|
||||
|
||||
//关闭弹窗
|
||||
closeModal(){
|
||||
this.accessoryReplaceShow = false
|
||||
this.othersData = {}
|
||||
this.othersIndex = 0
|
||||
},
|
||||
|
||||
//切换元素
|
||||
changeElement(type:string){
|
||||
let url = Https.httpUrls.getNextSysElement + `?id=${this.othersData.id}&operateType=${type}&type=${this.othersData.type}`
|
||||
this.loadingShow = true
|
||||
Https.axiosGet(url).then(
|
||||
(rv: any) => {
|
||||
this.othersData.id = rv.id
|
||||
this.othersData.path = rv.path
|
||||
this.loadingShow = false
|
||||
}
|
||||
).catch(rv=>{
|
||||
this.loadingShow = false
|
||||
})
|
||||
},
|
||||
|
||||
//提交
|
||||
submitOthers(){
|
||||
this.othersData.color = this.othersData.color ? `${this.modifyColor.r} ${this.modifyColor.g} ${this.modifyColor.b}` : ''
|
||||
let data = {
|
||||
others:this.othersData,
|
||||
index:this.othersIndex
|
||||
}
|
||||
this.store.commit('setDesignItemOthers',data)
|
||||
this.closeModal()
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="less">
|
||||
.accessory_replace_modal{
|
||||
|
||||
.ant-modal-close{
|
||||
width: 3.6rem;
|
||||
height: 3.6rem;
|
||||
position: absolute;
|
||||
top: -1.8rem;
|
||||
right: -1.8rem;
|
||||
}
|
||||
|
||||
.ant-modal-header{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ant-modal-body{
|
||||
padding: 2rem 1.8rem 3rem;
|
||||
box-sizing: border-box;
|
||||
background: #F2F3FB;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.close_icon{
|
||||
width: 3.6rem;
|
||||
height: 3.6rem;
|
||||
background: #000000;
|
||||
border-radius: 50%;
|
||||
line-height: 3.6rem;
|
||||
text-align: center;
|
||||
|
||||
.icon-guanbi{
|
||||
font-size: 2rem;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
.accessory_replace_content{
|
||||
|
||||
.new_accessory_block{
|
||||
padding: 2rem 2rem 1.2rem;
|
||||
background: #ffffff;
|
||||
width: 100%;
|
||||
|
||||
.new_accessory_title{
|
||||
font-size: 1.6rem;
|
||||
line-height: 1.6rem;
|
||||
color: #030303;
|
||||
margin-bottom: 1.3rem;
|
||||
}
|
||||
.new_accessory_img_block{
|
||||
width: 20rem;
|
||||
height: 16rem;
|
||||
background: #FFFFFF;
|
||||
border: 0.1rem solid #F5F5F5;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin:0 auto 1.7rem;
|
||||
position: relative;
|
||||
|
||||
.element_img{
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.element_img_loading{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.new_accessory_operate_list{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
.new_accessory_operate_button{
|
||||
padding: 0 1.5rem;
|
||||
height: 3.2rem;
|
||||
text-align: center;
|
||||
line-height: 3.2rem;
|
||||
font-size: 1.2rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
.pervious_button{
|
||||
background: #343579;
|
||||
color: #ffffff;
|
||||
margin-right: 2rem;
|
||||
}
|
||||
.fetch_button{
|
||||
background: #E6E6F6;
|
||||
color: #343579;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.accessory_color_block{
|
||||
width: 100%;
|
||||
background: #FFFFFF;
|
||||
padding: 0 2rem;
|
||||
margin: 1.3rem 0 1.8rem;
|
||||
|
||||
.accessory_color_block_header{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 3.7rem;
|
||||
font-size: 1.6rem;
|
||||
color: #030303;
|
||||
}
|
||||
|
||||
.accessory_color_block_body{
|
||||
padding:0 1.5rem 1.5rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.review_color_block{
|
||||
width: 11.5rem;
|
||||
height: 11.5rem;
|
||||
border: 0.1rem solid #343579;
|
||||
}
|
||||
|
||||
.setting_color_block{
|
||||
|
||||
.setting_color_content{
|
||||
|
||||
.vc-chrome-body{
|
||||
display: none;
|
||||
}
|
||||
.chrome_color{
|
||||
width: 11.5rem;
|
||||
height: 11.5rem;
|
||||
overflow: hidden;
|
||||
|
||||
.vc-chrome-saturation-wrap{
|
||||
height: 100%;
|
||||
}
|
||||
.vc-chrome-saturation-wrap .vc-saturation-circle{
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
}
|
||||
.sileder_color{
|
||||
width: 1.6rem;
|
||||
|
||||
.vc-slider-swatches{
|
||||
display:none
|
||||
}
|
||||
.vc-slider-hue-warp {
|
||||
width: 11.5rem;
|
||||
height: 1.6rem;
|
||||
border-radius: 0.8rem;
|
||||
overflow: hidden;
|
||||
|
||||
.vc-hue-picker{
|
||||
width: 1.2rem;
|
||||
height: 1.2rem;
|
||||
border-radius: 50%;
|
||||
transform: translate(-0.6rem, -0.4rem);
|
||||
|
||||
}
|
||||
}
|
||||
.vc-hue-pointer{
|
||||
top: 0.5rem !important;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.color_rgb_block{
|
||||
margin-top: 0.5rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 1.4rem;
|
||||
color: #343579;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.submit_button{
|
||||
width: 9.8rem;
|
||||
height: 3.6rem;
|
||||
text-align: center;
|
||||
background: #343579;
|
||||
font-size: 1.4rem;
|
||||
line-height: 3.6rem;
|
||||
color: #FFFFFF;
|
||||
margin: 1.8rem auto 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
529
src/component/Detail/DesignDetail.vue
Normal file
@@ -0,0 +1,529 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-modal class="design_detail_modal_component"
|
||||
v-model:visible="designDetailShow"
|
||||
:footer="null"
|
||||
title="Mailbox binding"
|
||||
width="80%"
|
||||
:maskClosable="false"
|
||||
:centered="true"
|
||||
>
|
||||
<template #closeIcon>
|
||||
<div class="close_icon" @click.stop="closeModal()"><span class="icon iconfont icon-guanbi"></span></div>
|
||||
</template>
|
||||
<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>
|
||||
|
||||
<div class="design_detail_modal_body" v-show="designShowPrview == 1">
|
||||
<div class="detail_modal_body_left" @click="showDesignImgDetail()">
|
||||
<img class="detial_img" :src="designItemDetail.designItemUrl">
|
||||
</div>
|
||||
<div class="detail_modal_body_right">
|
||||
<div class="detail_modal_right_top scroll_style">
|
||||
<div class="clothes_detail_item">
|
||||
<div class="clothes_item_header"><span class="icon iconfont icon-dangqianweizhi"></span>Apparel</div>
|
||||
<div class="clothes_item_content">
|
||||
<Draggable :list="designItemDetail.clothes" item-key="id" :animation="100">
|
||||
<template #item="{ element,index }">
|
||||
<div class="clothes_item_img_block" @click="clothesDetail(element,index)">
|
||||
<img class="clothes_item_img" :src="element.path">
|
||||
</div>
|
||||
</template>
|
||||
</Draggable>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clothes_detail_item" v-show="designItemDetail.others && designItemDetail.others.length">
|
||||
<div class="clothes_item_header"><span class="icon iconfont icon-dangqianweizhi"></span>Others</div>
|
||||
<div class="clothes_item_content others_clothes_item_content">
|
||||
<div class="clothes_item_img_block" v-for="(element,index) in designItemDetail.others" :key="element.path" @click="othersDetail(element,index)">
|
||||
<img class="clothes_item_img" :src="element.path">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail_modal_right_bottom">
|
||||
<div class="detail_page_num">{{parentData.index + 1}}/{{parentData.collectionList.length}}</div>
|
||||
<div class="detail_redesign_button" @click="redesignItem()">Redesign</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="design_detail_perview" v-show="designShowPrview == 2">
|
||||
<div class="design_detail_perview_content" >
|
||||
<img class="perview_img" v-lazy="designItemDetail.designItemUrl || ''" :key="designItemDetail.designItemUrl">
|
||||
<!-- <div class="generate_button" v-show="designItemDetail.singleOverall == 'overall'" @click="generateHighDesign()">Generate Product lmage</div> -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="design_detail_perview design_detail_perview_second" v-show="designShowPrview == 3">
|
||||
<div class="design_detail_perview_content" >
|
||||
<img class="perview_img" v-lazy="designItemDetail.designItemUrl || ''" :key="designItemDetail.designItemUrl">
|
||||
</div>
|
||||
<div class="design_detail_perview_content" >
|
||||
<img class="perview_img" v-lazy="generateHighDesignImg || ''" :key="generateHighDesignImg">
|
||||
<div class="img_item_hover">
|
||||
<div class="img_operate_block delete_img_block" @click.stop="deleteGeneratePic()">
|
||||
<span class="icon iconfont icon-shanchu operate_icon"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
<ElementReplace ref="ElementReplace"></ElementReplace>
|
||||
<AccessoryReplace ref="AccessoryReplace"></AccessoryReplace>
|
||||
|
||||
<div class="mark_loading" v-show="loadingShow">
|
||||
<a-spin size="large" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent,computed,ref } from 'vue'
|
||||
import ElementReplace from '@/component/Detail/ElementReplace.vue'
|
||||
import AccessoryReplace from '@/component/Detail/AccessoryReplaceModal.vue'
|
||||
import Draggable from 'vuedraggable'
|
||||
import { Https } from "@/tool/https";
|
||||
import { useStore } from "vuex";
|
||||
export default defineComponent({
|
||||
components:{
|
||||
ElementReplace,
|
||||
AccessoryReplace,
|
||||
Draggable,
|
||||
},
|
||||
setup() {
|
||||
const store = useStore();
|
||||
let designItemDetail :any = computed(()=>{return store.state.DesignDetailModule.designItemDetail})
|
||||
let parentData:any = ref({
|
||||
design:{},
|
||||
index:0,
|
||||
collectionList:[],
|
||||
type:'',
|
||||
})//父组件传过来的数据
|
||||
return{
|
||||
designItemDetail,
|
||||
store,
|
||||
parentData
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
loadingShow:false,
|
||||
designDetailShow:false,
|
||||
designShowPrview:1, //展示图片预览步骤
|
||||
generateHighDesignImg:'',//点击generate按钮生成的高级设计图
|
||||
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
closeModal(){
|
||||
if(this.designShowPrview == 1){
|
||||
this.designDetailShow = false
|
||||
}else if(this.designShowPrview == 2){
|
||||
this.designShowPrview = this.designShowPrview - 1
|
||||
}else if(this.designShowPrview == 3){
|
||||
this.designShowPrview = 1
|
||||
}
|
||||
},
|
||||
|
||||
showDesignDetailModal(data:any){
|
||||
let url = Https.httpUrls.getDesignDetail + `?designItemId=${data.design.designItemId}`
|
||||
this.parentData = data
|
||||
this.loadingShow = true
|
||||
Https.axiosGet(url).then(
|
||||
(rv: any) => {
|
||||
this.store.commit('setDesignItemDetail',rv)
|
||||
this.generateHighDesignImg = rv.highDesignUrl
|
||||
this.designShowPrview = 1
|
||||
this.designDetailShow = true
|
||||
this.loadingShow = false
|
||||
}
|
||||
).catch(rv=>{
|
||||
this.loadingShow = false
|
||||
})
|
||||
},
|
||||
|
||||
//切换上一张或下一张图的详情
|
||||
changeDesignItem(type:string){
|
||||
let {design,index,collectionList} = this.parentData
|
||||
let newDesign = {}
|
||||
let newIndex = 0
|
||||
if(type === 'last'){
|
||||
if(index>0){
|
||||
newIndex = this.parentData.index - 1
|
||||
}else{
|
||||
newIndex = this.parentData.collectionList.length - 1
|
||||
}
|
||||
}else{
|
||||
if(index < this.parentData.collectionList.length - 1){
|
||||
newIndex = this.parentData.index + 1
|
||||
}else{
|
||||
newIndex = 0
|
||||
}
|
||||
}
|
||||
newDesign = collectionList[newIndex]
|
||||
let data = {
|
||||
design:newDesign,
|
||||
index:newIndex,
|
||||
collectionList:collectionList
|
||||
}
|
||||
this.showDesignDetailModal(data)
|
||||
},
|
||||
|
||||
//显示图片详情
|
||||
showDesignImgDetail(){
|
||||
if(this.generateHighDesignImg){
|
||||
this.designShowPrview = 3
|
||||
}else{
|
||||
this.designShowPrview = 2
|
||||
}
|
||||
},
|
||||
|
||||
//生成高级图片
|
||||
generateHighDesign(){
|
||||
let design:any = this.parentData.design
|
||||
let data = {
|
||||
designItemId: design.designItemId,
|
||||
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
}
|
||||
this.loadingShow = true
|
||||
Https.axiosPost(Https.httpUrls.generateHighDesign,data).then(
|
||||
(rv: any) => {
|
||||
this.generateHighDesignImg = rv
|
||||
this.loadingShow = false
|
||||
this.designShowPrview = 3
|
||||
}
|
||||
).catch(rv=>{
|
||||
this.loadingShow = false
|
||||
})
|
||||
},
|
||||
|
||||
//删除生成的真人图
|
||||
deleteGeneratePic(){
|
||||
let design:any = this.parentData.design
|
||||
let data = {
|
||||
designItemId: design.designItemId,
|
||||
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
}
|
||||
this.loadingShow = true
|
||||
Https.axiosPost(Https.httpUrls.deleteHighDesign,data).then(
|
||||
(rv: any) => {
|
||||
this.loadingShow = false
|
||||
this.generateHighDesignImg = ''
|
||||
this.designShowPrview = 2
|
||||
}
|
||||
).catch(rv=>{
|
||||
this.loadingShow = false
|
||||
})
|
||||
},
|
||||
|
||||
//元素替换
|
||||
clothesDetail(clothes:any, index:number){
|
||||
let elementReplace:any = this.$refs.ElementReplace
|
||||
let data ={
|
||||
clothes:clothes,
|
||||
index:index,
|
||||
}
|
||||
elementReplace.showelementReplaceModal(data)
|
||||
},
|
||||
|
||||
othersDetail(others:any, index:number){
|
||||
let accessoryReplace:any = this.$refs.AccessoryReplace
|
||||
let data ={
|
||||
others:others,
|
||||
index:index,
|
||||
}
|
||||
accessoryReplace.showAccessoryReplaceModal(data)
|
||||
},
|
||||
|
||||
//重新设计
|
||||
redesignItem(){
|
||||
let designItemDetail = JSON.parse(JSON.stringify(this.store.state.DesignDetailModule.designItemDetail))
|
||||
delete designItemDetail.designItemUrl
|
||||
let priority = designItemDetail.clothes.map((v:any)=>{
|
||||
return v.type
|
||||
})
|
||||
let data = {
|
||||
...designItemDetail,
|
||||
priority:priority,
|
||||
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
}
|
||||
this.loadingShow = true
|
||||
Https.axiosPost(Https.httpUrls.designSingle, data).then(
|
||||
(rv: any) => {
|
||||
this.parentData.design.designItemUrl = rv.designItemUrl
|
||||
this.$emit('finishRedesign',this.parentData)
|
||||
this.closeModal()
|
||||
this.loadingShow = false
|
||||
this.closeModal()
|
||||
}
|
||||
).catch(res=>{
|
||||
this.loadingShow = false
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="less">
|
||||
.design_detail_modal_component{
|
||||
color: #000;
|
||||
|
||||
.ant-modal-close{
|
||||
width: 3.6rem;
|
||||
height: 3.6rem;
|
||||
position: absolute;
|
||||
top: -1.8rem;
|
||||
right: -1.8rem;
|
||||
}
|
||||
|
||||
.ant-modal-header{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ant-modal-body{
|
||||
background: #F2F3FB;
|
||||
height: 80vh;
|
||||
overflow-y: hidden;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.close_icon{
|
||||
width: 3.6rem;
|
||||
height: 3.6rem;
|
||||
background: #000000;
|
||||
border-radius: 50%;
|
||||
line-height: 3.6rem;
|
||||
text-align: center;
|
||||
|
||||
.icon-guanbi{
|
||||
font-size: 2rem;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
.turn_button{
|
||||
width: 3.6rem;
|
||||
height: 3.6rem;
|
||||
background: #000000;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
top: calc(50% - 1.8rem);
|
||||
cursor: pointer;
|
||||
line-height: 3.6rem;
|
||||
text-align: center;
|
||||
|
||||
&.turn_left_button{
|
||||
left: -8rem;
|
||||
}
|
||||
|
||||
&.turn_right_button{
|
||||
right: -8rem;
|
||||
}
|
||||
|
||||
.icon_turn{
|
||||
font-size: 2.4rem;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.design_detail_modal_body{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 1.5rem 1rem 2.5rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
.detail_modal_body_left{
|
||||
width: 43.3rem;
|
||||
height: 100%;
|
||||
background: #FFFFFF;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.detial_img{
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.detail_modal_body_right{
|
||||
width: calc(100% - 44rem);
|
||||
height: 100%;
|
||||
|
||||
.detail_modal_right_top{
|
||||
width: 100%;
|
||||
height: calc(100% - 3.9rem);
|
||||
background: #fff;
|
||||
overflow-y: auto;
|
||||
|
||||
.clothes_detail_item{
|
||||
padding-left: 1.5rem;
|
||||
|
||||
.clothes_item_header{
|
||||
height: 6.4rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 18px;
|
||||
color: #000000;
|
||||
|
||||
.icon-dangqianweizhi{
|
||||
font-size: 1.8rem;
|
||||
color: #000000;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.clothes_item_content{
|
||||
padding:0 0.5rem 2.3rem;
|
||||
border-bottom: 0.1rem solid #F2F3FB;
|
||||
|
||||
&.others_clothes_item_content{
|
||||
border-bottom:none
|
||||
}
|
||||
|
||||
.clothes_item_img_block{
|
||||
width: 20.5rem;
|
||||
height: 20.5rem;
|
||||
border: 0.1rem solid #F5F5F5;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
line-height: 21.3rem;
|
||||
margin-right: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
|
||||
.clothes_item_img{
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.detail_modal_right_bottom{
|
||||
position: relative;
|
||||
|
||||
.detail_page_num{
|
||||
position: absolute;
|
||||
top: 2rem;
|
||||
left: 12.4rem;
|
||||
font-size: 1.8rem;
|
||||
font-family: Roboto;
|
||||
font-weight: 400;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.detail_redesign_button{
|
||||
position: absolute;
|
||||
top: 1.4rem;
|
||||
right: 0;
|
||||
padding: 0 1.8rem;
|
||||
text-align: center;
|
||||
height: 3.6rem;
|
||||
line-height: 3.6rem;
|
||||
background: #343579;
|
||||
font-size: 14px;
|
||||
font-family: Roboto;
|
||||
color: #FFFFFF;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.design_detail_perview{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0.7rem 0 0.6rem;
|
||||
|
||||
&.design_detail_perview_second{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0.7rem 9.1rem 0.6rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.design_detail_perview_content{
|
||||
width: 46.2rem;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.perview_img{
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
.generate_button{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -20.2rem;
|
||||
padding: 0 1.5rem;
|
||||
text-align: center;
|
||||
height: 3.6rem;
|
||||
line-height: 3.6rem;
|
||||
background: #343579;
|
||||
font-size: 14px;
|
||||
font-family: Roboto;
|
||||
color: #FFFFFF;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:hover .img_item_hover{
|
||||
display: block;
|
||||
}
|
||||
|
||||
.img_item_hover{
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top:0;
|
||||
background: rgba(0,0,0,0.4);
|
||||
display: none;
|
||||
|
||||
.img_operate_block{
|
||||
width: 3.6rem;
|
||||
height: 3.6rem;
|
||||
background: rgba(0,0,0,0.6);
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
right: 2.2rem;
|
||||
text-align: center;
|
||||
line-height: 3.6rem;
|
||||
cursor: pointer;
|
||||
|
||||
&.delete_img_block{
|
||||
top: 2rem;
|
||||
}
|
||||
|
||||
.operate_icon{
|
||||
font-size: 1.8rem;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
</style>
|
||||
900
src/component/Detail/ElementReplace.vue
Normal file
@@ -0,0 +1,900 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-modal class="element_replace_modal"
|
||||
v-model:visible="elementReplaceShow"
|
||||
:footer="null"
|
||||
width="80%"
|
||||
:maskClosable="false"
|
||||
:centered="true"
|
||||
>
|
||||
<template #closeIcon>
|
||||
<div class="close_icon" @click.stop="closeModal()"><span class="icon iconfont icon-guanbi"></span></div>
|
||||
</template>
|
||||
|
||||
<div class="element_replace_content">
|
||||
<div class="element_replace_content_left">
|
||||
<div class="content_left_block">
|
||||
<div class="content_left_block_header">New {{swtich_type}}</div>
|
||||
<div class="content_left_block_body">
|
||||
<div class="content_body_img_block">
|
||||
<img class="element_img" :src="clothesData?.path">
|
||||
<div class="upload_block">
|
||||
<a-upload
|
||||
:action="uploadUrl + '/api/element/upload'"
|
||||
:data="{
|
||||
...upload,
|
||||
level1Type:clothesData?.level1Type
|
||||
}"
|
||||
:headers="{Authorization:token}"
|
||||
:before-upload="beforeUpload"
|
||||
:maxCount="1"
|
||||
accept=".jpg,.png,.jpeg,.bmp"
|
||||
@change="(file)=>fileUploadChange(file,'top')"
|
||||
:showUploadList="false"
|
||||
>
|
||||
<div class="upload_icon_block">
|
||||
<span class="icon iconfont icon-tianjiatupian_huaban"></span>
|
||||
</div>
|
||||
</a-upload>
|
||||
</div>
|
||||
<div class="operate_file_block">
|
||||
<div class="select_category" @click.stop="showNewTopOperate()">
|
||||
{{clothesData?.type}}
|
||||
<div :class="['icon','iconfont', 'icon-xiala', newTopOperateShow?'icon_rotate':'']"></div>
|
||||
</div>
|
||||
<div class="category_list" v-show="newTopOperateShow">
|
||||
<div :class="['category_item', clothesData?.type == cate.value?'select_category_item':'']" v-for="(cate,index) in sketchCatecoryList" :key="index" @click="selectNewTopOperate(cate)">{{cate.label}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content_left_block">
|
||||
<div class="content_left_block_header">
|
||||
<div>New Print</div>
|
||||
<div class="placement_button" @click="placementClick()" v-show="clothesData?.printObject?.path && clothesData?.printObject?.path != 'none'">Placement</div>
|
||||
</div>
|
||||
<div class="content_left_block_body">
|
||||
<div class="content_body_img_block">
|
||||
<img class="element_img print_element_img" :src="clothesData?.printObject?.path" v-if="clothesData?.printObject?.path && clothesData?.printObject?.path != 'none'">
|
||||
<img class="element_null_img" src="@/assets/images/homePage/null_img.png" v-else />
|
||||
<div class="upload_block">
|
||||
<a-upload
|
||||
:action="uploadUrl + '/api/element/upload'"
|
||||
:data="{
|
||||
...upload,
|
||||
level1Type:clothesData?.printObject?.level1Type || Printboard
|
||||
}"
|
||||
:headers="{Authorization:token}"
|
||||
:before-upload="beforeUpload"
|
||||
:maxCount="1"
|
||||
accept=".jpg,.png,.jpeg,.bmp"
|
||||
@change="(file)=>fileUploadChange(file,'print')"
|
||||
:showUploadList="false"
|
||||
>
|
||||
<div class="upload_icon_block">
|
||||
<span class="icon iconfont icon-tianjiatupian_huaban"></span>
|
||||
</div>
|
||||
</a-upload>
|
||||
</div>
|
||||
<div class="delete_file_block" @click="deletePrintFile()">
|
||||
<span class="icon iconfont icon-shanchu"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content_left_block">
|
||||
<div class="content_left_block_header content_color_block_header">Edit Color</div>
|
||||
<div class="content_left_block_body content_color_block_body">
|
||||
<div class="review_color_block" :style="{background:`rgb(${modifyColor.r},${modifyColor.g},${modifyColor.b})`}"></div>
|
||||
<div class="setting_color_block">
|
||||
<div class="setting_color_content">
|
||||
<Chrome class="chrome_color" v-model="selectColor"></Chrome>
|
||||
<Slider class="sileder_color" v-model="selectColor"></Slider>
|
||||
</div>
|
||||
<div class="color_rgb_block">
|
||||
<div class="rgb_item">R:{{getSelectRGB(selectColor).r}}</div>
|
||||
<div class="rgb_item">G:{{getSelectRGB(selectColor).g}}</div>
|
||||
<div class="rgb_item">B:{{getSelectRGB(selectColor).b}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="submit_button" @click="submitElement()">Submit</div>
|
||||
</div>
|
||||
|
||||
<div class="element_replace_content_right">
|
||||
<div class="content_right_header"><div class="content_right_header_content">Select from library</div></div>
|
||||
|
||||
<div class="content_right_search_block">
|
||||
<input class="search_input" placeholder="Search by your style code" v-model="searchPictureName" @keydown.enter="getLibraryList()">
|
||||
<div class="search_icon_block" @click="getLibraryList()"><span class="icon iconfont icon-sousuo"></span></div>
|
||||
</div>
|
||||
|
||||
<div class="content_right_table_block">
|
||||
<div class="table_block_header">
|
||||
<div class="table_block_header_left">
|
||||
<div v-show="['Outwear','Dress','Blouse'].indexOf(clothesData.type) > -1" @click="select_type('Top')" :class="['switch_type_item', swtich_type === 'Top' ? 'select_swtich' : '']">
|
||||
<span>Top</span>
|
||||
</div>
|
||||
<div v-show="['Skirt','Trousers'].indexOf(clothesData.type) > -1" @click="select_type('Bottom')" :class="['switch_type_item', swtich_type === 'Bottom' ? 'select_swtich' : '']">
|
||||
<span>Bottom</span>
|
||||
</div>
|
||||
<div @click="select_type('Print')" :class="['switch_type_item', swtich_type === 'Print' ? 'select_swtich' : '']">
|
||||
<span>Print</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table_header_select_block select_block" v-show="swtich_type != 'Print'">
|
||||
<a-select
|
||||
ref="select"
|
||||
placeholder="All"
|
||||
v-model:value="designType"
|
||||
:allowClear="true"
|
||||
:options="disignTypeList"
|
||||
@change="handleChange"
|
||||
>
|
||||
<template #suffixIcon
|
||||
><span
|
||||
class="icon iconfont icon-xiala"
|
||||
style="color: #343579"
|
||||
></span
|
||||
></template>
|
||||
</a-select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table_img_list scroll_style">
|
||||
<div class="table_img_item_block" v-for="img in imgList" :key="img" @click="selectImgItem(img)">
|
||||
<div class="img_item_block">
|
||||
<img :class="[swtich_type === 'Print'?'print_img_body':'img_item_body']" v-lazy="img.url" :key="img.url">
|
||||
</div>
|
||||
<div class="img_item_name">{{img.name}}</div>
|
||||
</div>
|
||||
<div class="no_data_block" v-show="!imgList.length && !isShowLoading">
|
||||
<img src="@/assets/images/homePage/null_img.png">
|
||||
</div>
|
||||
<div class="no_data_block" v-show="isShowLoading">
|
||||
<a-spin size="large"></a-spin>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table_pagination" v-show="imgList.length">
|
||||
<a-pagination
|
||||
|
||||
v-model:current="currentPage"
|
||||
v-model:pageSize="pageSize"
|
||||
:total="total"
|
||||
:showQuickJumper="true"
|
||||
:showSizeChanger="false"
|
||||
@change="changePage"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</a-modal>
|
||||
<PlacementModal ref="PlacementModal" @submitPlacement="submitPlacement"></PlacementModal>
|
||||
<PlacementModalMobile ref="PlacementModalMobile" @submitPlacement="submitPlacement"></PlacementModalMobile>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent,ref } from 'vue'
|
||||
import {getCookie} from '@/tool/cookie'
|
||||
import {getUploadUrl,isMoible} from '@/tool/util'
|
||||
import { message, Upload } from 'ant-design-vue';
|
||||
import { Chrome,Slider } from '@ans1998/vue3-color'
|
||||
import PlacementModal from '@/component/Detail/PlacementModal.vue'
|
||||
import PlacementModalMobile from '@/component/Detail/PlacementModalMobile.vue'
|
||||
import { Https } from "@/tool/https";
|
||||
import { useStore } from "vuex";
|
||||
export default defineComponent({
|
||||
components:{Chrome,Slider,PlacementModal,PlacementModalMobile},
|
||||
setup(){
|
||||
const store = useStore();
|
||||
let selectColor:any = ref({rgba:{}}) //顔色选择器默认颜色
|
||||
let clothesData:any = ref({})
|
||||
let disignTypeList:any = ref([])
|
||||
return {
|
||||
store,
|
||||
selectColor,
|
||||
clothesData,
|
||||
disignTypeList
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
elementReplaceShow:false,
|
||||
newTopOperateShow:false,
|
||||
sketchCatecoryList:[
|
||||
{
|
||||
value: 'Outwear',
|
||||
label: "Outwear",
|
||||
},
|
||||
{
|
||||
value: 'Blouse',
|
||||
label: "Blouse",
|
||||
},
|
||||
{
|
||||
value: 'Dress',
|
||||
label: "Dress",
|
||||
},
|
||||
{
|
||||
value: 'Trousers',
|
||||
label: "Trousers",
|
||||
},
|
||||
{
|
||||
value: 'Skirt',
|
||||
label: "Skirt",
|
||||
},
|
||||
],
|
||||
upload:{
|
||||
isPin:0,
|
||||
level1Type:'Moodboard',
|
||||
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
},
|
||||
token:'',
|
||||
uploadUrl:'',
|
||||
modifyColor:{r:255,g:255,b:255},
|
||||
designType:null,
|
||||
swtich_type:'Top',
|
||||
imgList:[], //图片列表
|
||||
currentPage:1, //当前页码
|
||||
pageSize:20,
|
||||
total:0,//图片总数
|
||||
clothesIndex:0, //该元素在列表中的索引
|
||||
isShowLoading:false,
|
||||
searchPictureName:'',//搜索图片的名称
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
selectColor(newVal:any,oldVal:any){
|
||||
this.modifyColor = newVal.rgba || {}
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
getSelectRGB(selectColor){
|
||||
return (selectColor:any)=>{
|
||||
let rgba = selectColor.rgba
|
||||
let data = {
|
||||
r:rgba?.r || 255,
|
||||
g:rgba?.g || 255,
|
||||
b:rgba?.b || 255
|
||||
}
|
||||
return data
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted(){
|
||||
this.token = getCookie('token') || ''
|
||||
this.uploadUrl = getUploadUrl()
|
||||
},
|
||||
methods:{
|
||||
select_type(type:string){
|
||||
this.imgList = []
|
||||
this.currentPage = 1
|
||||
this.searchPictureName = ''
|
||||
this.designType = null
|
||||
this.swtich_type = type
|
||||
this.getLibraryList()
|
||||
},
|
||||
showNewTopOperate(){
|
||||
this.newTopOperateShow = !this.newTopOperateShow
|
||||
document.addEventListener('click', this.hiddenNewTopOperate)
|
||||
},
|
||||
|
||||
selectNewTopOperate(cate:any){
|
||||
this.clothesData.type = cate.value
|
||||
},
|
||||
|
||||
hiddenNewTopOperate(){
|
||||
this.newTopOperateShow = false
|
||||
document.removeEventListener('click', this.hiddenNewTopOperate)
|
||||
},
|
||||
|
||||
fileUploadChange(data:any,type:any){
|
||||
let file = data.file
|
||||
if(file.status === 'done'){
|
||||
let res = JSON.parse(file.xhr.response)
|
||||
if(type === 'top'){
|
||||
this.clothesData.path = res.data.url
|
||||
this.clothesData.type = 'Outwear'
|
||||
}else if(type === 'print'){
|
||||
this.clothesData.printObject.path = res.data.url
|
||||
this.clothesData.printObject.location = []
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
beforeUpload(file:any){
|
||||
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg' || file.type === 'image/bmp';
|
||||
if (!isJpgOrPng) {
|
||||
message.error('You can only upload Image file!');
|
||||
}
|
||||
const isLt2M = file.size / 1024 / 1024 < 2;
|
||||
if (!isLt2M) {
|
||||
message.error('Image must smaller than 5MB!');
|
||||
}
|
||||
return (isJpgOrPng && isLt2M) || Upload.LIST_IGNORE;
|
||||
},
|
||||
|
||||
|
||||
//改变页码
|
||||
changePage(current: number, pageSize: number){
|
||||
this.currentPage = current
|
||||
this.pageSize = pageSize
|
||||
this.getLibraryList()
|
||||
},
|
||||
|
||||
handleChange(){
|
||||
this.getLibraryList()
|
||||
},
|
||||
|
||||
showelementReplaceModal(data:any){
|
||||
this.clothesData = JSON.parse(JSON.stringify(data.clothes))
|
||||
this.clothesIndex = data.index
|
||||
this.elementReplaceShow = true
|
||||
let color = this.clothesData.color.split(' ')
|
||||
this.selectColor = {rgba:{r:color[0],g:color[1],b:color[2]}}
|
||||
let topList = ['Outwear','Dress','Blouse']
|
||||
if(topList.indexOf(this.clothesData.type) > -1){
|
||||
this.swtich_type = 'Top'
|
||||
this.disignTypeList = [{
|
||||
value: "Outwear",
|
||||
label: "Outwear",
|
||||
},
|
||||
{
|
||||
value: "Blouse",
|
||||
label: "Blouse",
|
||||
},
|
||||
{
|
||||
value: "Dress",
|
||||
label: "Dress",
|
||||
}]
|
||||
}else{
|
||||
this.swtich_type = 'Bottom'
|
||||
this.disignTypeList = [{
|
||||
value: "Trousers",
|
||||
label: "Trousers",
|
||||
},
|
||||
{
|
||||
value: "Skirt",
|
||||
label: "Skirt",
|
||||
},]
|
||||
}
|
||||
this.getLibraryList()
|
||||
},
|
||||
|
||||
//关闭弹窗
|
||||
closeModal(){
|
||||
this.elementReplaceShow = false
|
||||
this.swtich_type = 'Top'
|
||||
this.clothesData = {}
|
||||
this.clothesIndex = 0
|
||||
},
|
||||
|
||||
//提交元素
|
||||
submitElement(){
|
||||
this.clothesData.color = `${this.modifyColor.r} ${this.modifyColor.g} ${this.modifyColor.b}`
|
||||
let data = {
|
||||
clothes:this.clothesData,
|
||||
index:this.clothesIndex
|
||||
}
|
||||
this.store.commit('setDesignItemColthes',data)
|
||||
this.closeModal()
|
||||
},
|
||||
|
||||
//删除print的图片
|
||||
deletePrintFile(){
|
||||
this.clothesData.printObject.path = ''
|
||||
},
|
||||
|
||||
placementClick(){
|
||||
let placementModal:any = isMoible() ? this.$refs.PlacementModalMobile : this.$refs.PlacementModal
|
||||
let data = {
|
||||
clothesData:this.clothesData,
|
||||
index:this.clothesIndex
|
||||
}
|
||||
placementModal.showPlacementModal(data)
|
||||
},
|
||||
|
||||
|
||||
//placement提交
|
||||
submitPlacement(e:any){
|
||||
this.clothesData.printObject = e
|
||||
},
|
||||
|
||||
getLibraryList(){
|
||||
let data = {
|
||||
level2Type:this.designType,
|
||||
page:this.currentPage,
|
||||
pictureName:this.searchPictureName,
|
||||
size:this.pageSize,
|
||||
type:this.swtich_type
|
||||
}
|
||||
this.isShowLoading = true
|
||||
Https.axiosPost(Https.httpUrls.queryLibraryTopAndBottomPage,data).then(
|
||||
(rv: any) => {
|
||||
this.imgList = rv.content
|
||||
this.total = rv.total
|
||||
this.isShowLoading = false
|
||||
}
|
||||
).catch((res)=>{
|
||||
this.isShowLoading = false
|
||||
});
|
||||
},
|
||||
|
||||
//选择库里的图片
|
||||
selectImgItem(img:any){
|
||||
if(this.swtich_type != 'Print'){
|
||||
this.clothesData.path = img.url
|
||||
}else{
|
||||
this.clothesData.printObject.path = img.url
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="less">
|
||||
.element_replace_modal{
|
||||
|
||||
.ant-modal-close{
|
||||
width: 3.6rem;
|
||||
height: 3.6rem;
|
||||
position: absolute;
|
||||
top: -1.8rem;
|
||||
right: -1.8rem;
|
||||
}
|
||||
|
||||
.ant-modal-header{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ant-modal-body{
|
||||
background: #F2F3FB;
|
||||
height: 80vh;
|
||||
min-height: 72rem;
|
||||
overflow-y: hidden;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.close_icon{
|
||||
width: 3.6rem;
|
||||
height: 3.6rem;
|
||||
background: #000000;
|
||||
border-radius: 50%;
|
||||
line-height: 3.6rem;
|
||||
text-align: center;
|
||||
|
||||
.icon-guanbi{
|
||||
font-size: 2rem;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
.element_replace_content{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 1.5rem 1rem 2rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
.element_replace_content_left{
|
||||
width: 36.4rem;
|
||||
height: 100%;
|
||||
|
||||
.content_left_block{
|
||||
width: 100%;
|
||||
background: #FFFFFF;
|
||||
padding: 0 2rem;
|
||||
margin-bottom: 1rem;
|
||||
|
||||
.content_left_block_header{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 5rem;
|
||||
font-size: 1.6rem;
|
||||
color: #030303;
|
||||
|
||||
&.content_color_block_header{
|
||||
height: 3.7rem;
|
||||
}
|
||||
|
||||
.placement_button{
|
||||
padding: 0 0.9rem;
|
||||
height: 3.2rem;
|
||||
line-height: 3.2rem;
|
||||
background: #E6E6F6;
|
||||
font-size: 1.2rem;
|
||||
color: #343579;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.content_left_block_body{
|
||||
width: 100%;
|
||||
|
||||
&.content_color_block_body{
|
||||
padding:0 1.5rem 1.5rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.content_body_img_block{
|
||||
width: 20rem;
|
||||
height: 15.8rem;
|
||||
background: #FFFFFF;
|
||||
border: 0.1rem solid #F5F5F5;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin:0 auto;
|
||||
position: relative;
|
||||
|
||||
|
||||
.element_img{
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
|
||||
&.print_element_img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.element_null_img{
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.operate_file_block{
|
||||
display: none;
|
||||
width: 100%;
|
||||
height: 3.2rem;
|
||||
line-height: 3.2rem;
|
||||
font-size: 1.6rem;
|
||||
color: #FFFFFF;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0,0,0,0.6);
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
|
||||
|
||||
.select_category{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.icon-xiala{
|
||||
margin-left: 0.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
.icon_rotate{
|
||||
-moz-transform:rotate(180deg);
|
||||
-webkit-transform:rotate(180deg);
|
||||
transform: rotate(180deg);
|
||||
animation-direction: 0.5s;
|
||||
}
|
||||
|
||||
.category_list{
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 3.3rem;
|
||||
left: 0;
|
||||
background: #FFFFFF;
|
||||
border: 0.1rem solid #000000;
|
||||
box-shadow: 0 0.4rem 0.4rem 0 rgba(0,0,0,0.1);
|
||||
overflow: hidden;
|
||||
z-index: 2;
|
||||
color: #4D4D4D;
|
||||
|
||||
.category_item{
|
||||
text-align: center;
|
||||
font-size: 1.4rem;
|
||||
height: 3.5rem;
|
||||
line-height:3.5rem;
|
||||
|
||||
&.select_category_item{
|
||||
background: #F7F7F7;
|
||||
}
|
||||
|
||||
&:hover{
|
||||
background: #F7F7F7;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.upload_block{
|
||||
display: none;
|
||||
width: 3.6rem;
|
||||
height: 3.6rem;
|
||||
position: absolute;
|
||||
top: 1.1rem;
|
||||
right: 0.9rem;
|
||||
border-radius: 50%;
|
||||
|
||||
.upload_icon_block{
|
||||
width: 3.6rem;
|
||||
height: 3.6rem;
|
||||
background: rgba(0,0,0,0.6);
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
line-height: 3.6rem;
|
||||
cursor: pointer;
|
||||
|
||||
.icon-tianjiatupian_huaban{
|
||||
font-size: 1.8rem;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.delete_file_block{
|
||||
display: none;
|
||||
width: 3.6rem;
|
||||
height: 3.6rem;
|
||||
background: rgba(0,0,0,0.6);
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
top: 1.1rem;
|
||||
right: 5.5rem;
|
||||
text-align: center;
|
||||
line-height: 3.6rem;
|
||||
cursor: pointer;
|
||||
|
||||
.icon-shanchu{
|
||||
font-size: 1.8rem;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover .delete_file_block, &:hover .operate_file_block, &:hover .upload_block{
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.review_color_block{
|
||||
width: 11.5rem;
|
||||
height: 11.5rem;
|
||||
border: 0.1rem solid #343579;
|
||||
}
|
||||
|
||||
.setting_color_block{
|
||||
|
||||
.setting_color_content{
|
||||
|
||||
.vc-chrome-body{
|
||||
display: none;
|
||||
}
|
||||
.chrome_color{
|
||||
width: 11.5rem;
|
||||
height: 11.5rem;
|
||||
overflow: hidden;
|
||||
|
||||
.vc-chrome-saturation-wrap{
|
||||
height: 100%;
|
||||
}
|
||||
.vc-chrome-saturation-wrap .vc-saturation-circle{
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
}
|
||||
.sileder_color{
|
||||
width: 1.6rem;
|
||||
|
||||
.vc-slider-swatches{
|
||||
display:none
|
||||
}
|
||||
.vc-slider-hue-warp {
|
||||
width: 11.5rem;
|
||||
height: 1.6rem;
|
||||
border-radius: 0.8rem;
|
||||
overflow: hidden;
|
||||
|
||||
.vc-hue-picker{
|
||||
width: 1.2rem;
|
||||
height: 1.2rem;
|
||||
border-radius: 50%;
|
||||
transform: translate(-0.6rem, -0.4rem);
|
||||
|
||||
}
|
||||
}
|
||||
.vc-hue-pointer{
|
||||
top: 0.5rem !important;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.color_rgb_block{
|
||||
margin-top: 0.5rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 1.4rem;
|
||||
color: #343579;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.submit_button{
|
||||
width: 9.8rem;
|
||||
height: 3.6rem;
|
||||
text-align: center;
|
||||
background: #343579;
|
||||
font-size: 1.4rem;
|
||||
line-height: 3.6rem;
|
||||
color: #FFFFFF;
|
||||
margin: 1.8rem auto 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.element_replace_content_right{
|
||||
width: calc(100% - 37rem);
|
||||
height: 100%;
|
||||
background: #FFFFFF;
|
||||
|
||||
.content_right_header{
|
||||
padding: 1.8rem 2.2rem 2.2rem;
|
||||
font-size: 1.6rem;
|
||||
color: #030303;
|
||||
|
||||
.content_right_header_content{
|
||||
height: 1.7rem;
|
||||
}
|
||||
}
|
||||
|
||||
.content_right_search_block{
|
||||
padding: 0 2.2rem;
|
||||
display: flex;
|
||||
|
||||
.search_input{
|
||||
width: 50.3rem;
|
||||
padding-left: 1.5rem;
|
||||
height: 4.8rem;
|
||||
line-height: 4.6rem;
|
||||
background: #FFFFFF;
|
||||
border: 0.1rem solid #F1F1F1;
|
||||
font-size: 1.6rem;
|
||||
font-weight: 400;
|
||||
|
||||
&::placeholder {
|
||||
color: #C2C2C2;
|
||||
}
|
||||
}
|
||||
|
||||
.search_icon_block{
|
||||
width: 7.2rem;
|
||||
height: 4.8rem;
|
||||
line-height: 4.8rem;
|
||||
text-align: center;
|
||||
background: #343579;
|
||||
cursor: pointer;
|
||||
|
||||
.icon-sousuo{
|
||||
font-size: 2rem;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.content_right_table_block{
|
||||
height: calc(100% - 10.5rem);
|
||||
|
||||
.table_block_header{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 1.7rem 1.7rem 0 2.3rem;
|
||||
border-bottom: 0.1rem solid #EBEBEC;
|
||||
|
||||
.table_block_header_left{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.switch_type_item{
|
||||
height: 4.2rem;
|
||||
width: 6rem;
|
||||
text-align: center;
|
||||
line-height: 4.2rem;
|
||||
line-height: 4rem;
|
||||
font-size: 1.6rem;
|
||||
margin-right: 3rem;
|
||||
border-bottom: 0.2rem solid transparent;
|
||||
color: #343579;
|
||||
cursor: pointer;
|
||||
|
||||
&.select_swtich{
|
||||
color: #343579;
|
||||
border-bottom: 0.2rem solid #343579;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
.select_block {
|
||||
|
||||
.ant-select-selector{
|
||||
min-width: 8rem;
|
||||
}
|
||||
|
||||
.icon-xiala{
|
||||
color: #1A1A1A !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.table_img_list{
|
||||
padding: 2rem 0 0 2.3rem;
|
||||
height: calc(100% - 13rem);
|
||||
overflow-y: auto;
|
||||
|
||||
.table_img_item_block{
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
margin:0 1.6rem 3rem 0;
|
||||
cursor: pointer;
|
||||
|
||||
.img_item_block{
|
||||
width: 16.5rem;
|
||||
height: 16.5rem;
|
||||
border: 0.1rem solid #343579;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.print_img_body{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.img_item_body{
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.img_item_name{
|
||||
white-space: nowrap;
|
||||
overflow:hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 1.4rem;
|
||||
color: #343579;
|
||||
text-align: center;
|
||||
width: 16.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.no_data_block{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.table_pagination{
|
||||
text-align: center;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
116
src/component/Detail/HistoryDetail.vue
Normal file
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<a-modal class="hsitory_detail_modal_component"
|
||||
v-model:visible="hsitoryDetailShow"
|
||||
:footer="null"
|
||||
:title="collectionName"
|
||||
width="80%"
|
||||
:maskClosable="false"
|
||||
:centered="true"
|
||||
>
|
||||
<template #closeIcon>
|
||||
<div class="close_icon" @click.stop="changeDetailShow()"><span class="icon iconfont icon-guanbi"></span></div>
|
||||
</template>
|
||||
<div class="history_detail_content scroll_style">
|
||||
<div class="history_img_block" v-for="img in groupDetails" :key="img">
|
||||
<div class="history_img_item" >
|
||||
<img class="element_img" :src="img.url">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</a-modal>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
props:{
|
||||
groupDetails:{
|
||||
default:{},
|
||||
},
|
||||
collectionName:{
|
||||
default:''
|
||||
}
|
||||
},
|
||||
setup() {
|
||||
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
hsitoryDetailShow:false,
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
changeDetailShow(){
|
||||
this.hsitoryDetailShow = !this.hsitoryDetailShow
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="less">
|
||||
.hsitory_detail_modal_component{
|
||||
|
||||
.ant-modal-close{
|
||||
width: 3.6rem;
|
||||
height: 3.6rem;
|
||||
position: absolute;
|
||||
top: -1.8rem;
|
||||
right: -1.8rem;
|
||||
}
|
||||
|
||||
.ant-modal-header{
|
||||
background: #F7F7F7;
|
||||
}
|
||||
|
||||
.ant-modal-body{
|
||||
background: #F2F3FB;
|
||||
height: 80vh;
|
||||
min-height: 72rem;
|
||||
overflow-y: hidden;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.close_icon{
|
||||
width: 3.6rem;
|
||||
height: 3.6rem;
|
||||
background: #000000;
|
||||
border-radius: 50%;
|
||||
line-height: 3.6rem;
|
||||
text-align: center;
|
||||
|
||||
.icon-guanbi{
|
||||
font-size: 2rem;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
.history_detail_content{
|
||||
padding: 2.6rem 2.0rem 2.6rem 3.7rem;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow-y:auto;
|
||||
background: #FFFFFF;
|
||||
|
||||
.history_img_block{
|
||||
width: 16.5rem;
|
||||
height: 16.5rem;
|
||||
border: 0.1rem solid #343579;
|
||||
margin: 0 1.7rem 1.7rem 0;
|
||||
display: inline-block;
|
||||
|
||||
.history_img_item{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.element_img{
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
565
src/component/Detail/PlacementModal.vue
Normal file
@@ -0,0 +1,565 @@
|
||||
<template>
|
||||
<div v-show="placementShow">
|
||||
<a-modal class="placement_modal_component"
|
||||
v-model:visible="placementShow"
|
||||
:footer="null"
|
||||
width="111.5rem"
|
||||
:maskClosable="false"
|
||||
:centered="true"
|
||||
>
|
||||
<template #closeIcon>
|
||||
<div class="close_icon" @click.stop="closeModal()"><span class="icon iconfont icon-guanbi"></span></div>
|
||||
</template>
|
||||
<div class="placement_modal_body" >
|
||||
<div class="palcement_modal_header">
|
||||
<div class="placement_modal_title">Placement</div>
|
||||
<div class="placement_operate_list">
|
||||
<div class="operate_item" @click="submitPlacement">
|
||||
<div class="icon iconfont icon-baocun1 operate_icon"></div>
|
||||
<div class="operate_item_des">Submit</div>
|
||||
</div>
|
||||
<div class="operate_item" @click="printPreview">
|
||||
<div class="icon iconfont icon-shengchengyulan operate_icon"></div>
|
||||
<div class="operate_item_des">Preview</div>
|
||||
</div>
|
||||
<div class="operate_item" v-show="perviewUrl" @click="backPreview">
|
||||
<div class="icon iconfont icon-fanhui1 operate_icon"></div>
|
||||
<div class="operate_item_des">Back</div>
|
||||
</div>
|
||||
<div class="operate_item" @click="restoreLocationList">
|
||||
<div class="icon iconfont icon-huifu operate_icon"></div>
|
||||
<div class="operate_item_des">Restore</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="placement_modal_content">
|
||||
<div class="placement_content_operate_list">
|
||||
<!-- <div class="placement_content_operate_item" @click="overallClick()">
|
||||
<div class="placement_overall_icon">
|
||||
<div class="placement_overall_content" v-show="!printObject.ifSingle"></div>
|
||||
</div>
|
||||
<div class="placement_content_operate_des">Overall</div>
|
||||
</div> -->
|
||||
|
||||
<div class="placement_content_operate_item">
|
||||
<div class="print_scale_value">{{placement_sacle}}%</div>
|
||||
<a-slider
|
||||
id="placement_silder"
|
||||
:tooltipVisible="false"
|
||||
v-model:value="placement_sacle"
|
||||
:min="30"
|
||||
:max="300"
|
||||
/>
|
||||
<div class="placement_content_operate_des">Print Scale</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class="placement_content_operate_item" @mousedown="AddDian()" v-show="!perviewUrl">
|
||||
<div class="placement_add_point_block">
|
||||
<div class="placement_add_point_content"></div>
|
||||
</div>
|
||||
<div class="placement_content_operate_des" >Add Point</div>
|
||||
</div>
|
||||
|
||||
<div class="placement_content_operate_item" @click="changeRemoveStatus" v-show="!perviewUrl">
|
||||
<div class="placement_remove_point_block"></div>
|
||||
<div class="placement_content_operate_des">Remove Point</div>
|
||||
</div> -->
|
||||
</div>
|
||||
|
||||
<div class="img_preview_block" >
|
||||
<div class="perview_mark_loading" v-show="isShowMark">
|
||||
<a-spin size="large" />
|
||||
</div>
|
||||
<div class="img_content_block" ref="imgbox" @mousemove="startMove($event)">
|
||||
<img class="placement_img" v-lazy="perviewUrl || clothesData?.path" :key="perviewUrl || clothesData?.path">
|
||||
<div :class="['ponit_click',isRemoveStatus?'remove_point_click':'']" v-show="!perviewUrl" v-for="(item,index) in locationList" :key="item" :style="{left:item.left+'px', top:item.top+'px'}" @mousedown="getMouseDown($event,item,index)" @mousemove="startMove($event)">
|
||||
<div class="placement_add_point_content" v-show="!isRemoveStatus"></div>
|
||||
<div class="icon iconfont icon-guanbi" v-show="isRemoveStatus"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent,ref} from 'vue'
|
||||
import { Https } from "@/tool/https";
|
||||
import { useStore } from "vuex";
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const store = useStore()
|
||||
let oldLocationList:any = ref([])
|
||||
let locationList:any = ref([])
|
||||
let printObject:any = ref({})
|
||||
let imgBox:any = ref({})
|
||||
let intObj:any = ref(null)
|
||||
let currentSign:any = ref({})
|
||||
let clothesData:any = ref({})
|
||||
return {
|
||||
store,
|
||||
oldLocationList,
|
||||
locationList,
|
||||
printObject,
|
||||
imgBox,
|
||||
intObj,
|
||||
currentSign,
|
||||
clothesData
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
placementShow:false,
|
||||
collectionIndex:0,
|
||||
startDian:false,
|
||||
moveOriginal:{posX: 0, posY: 0},
|
||||
isRemoveStatus:false,
|
||||
placement_sacle:30,
|
||||
perviewUrl:'',//预览的图片地址
|
||||
isShowMark:false,
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
formatter(value:number){
|
||||
return `${value}%`;
|
||||
},
|
||||
|
||||
showPlacementModal(data:any){
|
||||
this.clothesData = JSON.parse(JSON.stringify(data.clothesData))
|
||||
this.printObject = this.clothesData.printObject
|
||||
this.collectionIndex = data.index
|
||||
this.placement_sacle = this.printObject.scale ? this.printObject.scale * 100 : 30
|
||||
this.placementShow = true
|
||||
setTimeout(()=>{
|
||||
let imgbox:any = this.$refs.imgbox
|
||||
let position = imgbox.getBoundingClientRect()
|
||||
this.imgBox = {
|
||||
width:imgbox.clientWidth,
|
||||
height:imgbox.scrollHeight,
|
||||
left : position.left,
|
||||
top:position.top,
|
||||
scrollTop:imgbox.scrollTop || 0,
|
||||
}
|
||||
this.getLocationList(this.imgBox)
|
||||
},500)
|
||||
},
|
||||
|
||||
getLocationList(imgBox:any){
|
||||
if(this.printObject.location){
|
||||
this.locationList = this.printObject.location.map((v:any)=>{
|
||||
let data = {
|
||||
left:(v[0] * imgBox.width) - 12,
|
||||
top:(v[1] * imgBox.height) -12
|
||||
}
|
||||
return data
|
||||
})
|
||||
this.oldLocationList = JSON.parse(JSON.stringify(this.locationList))
|
||||
}
|
||||
},
|
||||
|
||||
overallClick(){
|
||||
this.printObject.ifSingle = !this.printObject.ifSingle
|
||||
},
|
||||
|
||||
AddDian(){
|
||||
this.startDian = true
|
||||
this.isRemoveStatus = false
|
||||
this.intObj = true
|
||||
},
|
||||
|
||||
changeRemoveStatus(){
|
||||
this.isRemoveStatus = true
|
||||
},
|
||||
|
||||
startMove(event:any){
|
||||
if(this.isRemoveStatus){
|
||||
return
|
||||
}
|
||||
let imgbox:any = this.$refs.imgbox
|
||||
let scrollTop = imgbox.scrollTop;
|
||||
if(this.intObj){
|
||||
this.currentSign.left = event.clientX - this.imgBox.left
|
||||
this.currentSign.top = event.clientY + scrollTop - this.imgBox.top
|
||||
this.locationList.push(this.currentSign)
|
||||
this.printObject.ifSingle = true
|
||||
this.intObj = null
|
||||
}else{
|
||||
if(this.startDian){
|
||||
this.currentSign.left = event.clientX - this.imgBox.left - this.moveOriginal.posX
|
||||
this.currentSign.top = event.clientY + scrollTop - this.imgBox.top -this.moveOriginal.posY
|
||||
document.addEventListener('mouseup', this.getMouseOver);
|
||||
this.$forceUpdate()
|
||||
this.setBoundarySign()
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
// 在边界上的签名域处理
|
||||
setBoundarySign() {
|
||||
let imgbox:any = this.$refs.imgbox
|
||||
let height = imgbox.offsetHeight + imgbox.scrollTop;
|
||||
// 2 为签名域的边框
|
||||
let maxPosHeight = height - 24
|
||||
let maxPosWidth = imgbox.clientWidth - 24 //+ this.signBox.paddLeft;
|
||||
if (this.currentSign.top <= 0) {
|
||||
this.currentSign.top = 0
|
||||
} else if (this.currentSign.top >= maxPosHeight ) {
|
||||
this.currentSign.top = maxPosHeight;
|
||||
}
|
||||
if (this.currentSign.left <= 0) {
|
||||
this.currentSign.left = 0
|
||||
} else if (this.currentSign.left >= maxPosWidth) {
|
||||
this.currentSign.left = maxPosWidth;
|
||||
}
|
||||
},
|
||||
|
||||
getMouseDown(event:any,item:any,index:number){
|
||||
if(this.isRemoveStatus){
|
||||
this.locationList.splice(index,1)
|
||||
}else{
|
||||
this.currentSign = item
|
||||
// 计算出鼠标在签名域上的偏移
|
||||
this.moveOriginal.posX = event.offsetX
|
||||
this.moveOriginal.posY = event.offsetY // 1为边框
|
||||
this.startDian = true
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
getMouseOver(){
|
||||
this.startDian = false
|
||||
this.currentSign = {}
|
||||
document.removeEventListener('mouseup', this.getMouseOver);
|
||||
},
|
||||
|
||||
closeModal(){
|
||||
this.oldLocationList = []
|
||||
this.locationList = []
|
||||
this.printObject = {}
|
||||
this.intObj = null
|
||||
this.currentSign = {}
|
||||
this.isRemoveStatus = false
|
||||
this.placementShow = false
|
||||
this.perviewUrl = ''
|
||||
},
|
||||
|
||||
restoreLocationList(){
|
||||
this.locationList = JSON.parse(JSON.stringify(this.oldLocationList))
|
||||
},
|
||||
|
||||
submitPlacement(){
|
||||
this.printObject.scale = this.placement_sacle / 100
|
||||
this.printObject.location = this.printObject.ifSingle ? this.getPrintLocation() : []
|
||||
this.$emit('submitPlacement',this.printObject)
|
||||
this.closeModal()
|
||||
|
||||
},
|
||||
|
||||
getPrintLocation(){
|
||||
let {width , height} = this.imgBox
|
||||
let location = this.locationList.map((v:any)=>{
|
||||
let left = ((v.left + 12) / width).toFixed(4)
|
||||
let top = ((v.top + 12) / height).toFixed(4)
|
||||
let data = [left,top]
|
||||
return data
|
||||
})
|
||||
return location
|
||||
},
|
||||
|
||||
printPreview(){
|
||||
this.printObject.scale = this.placement_sacle / 100
|
||||
this.printObject.location = this.printObject.ifSingle ? this.getPrintLocation() : []
|
||||
let designItemDetail = JSON.parse(JSON.stringify(this.store.state.DesignDetailModule.designItemDetail))
|
||||
designItemDetail.clothes[this.collectionIndex] = this.clothesData
|
||||
delete designItemDetail.designItemUrl
|
||||
let priority = designItemDetail.clothes.map((v:any)=>{
|
||||
return v.type
|
||||
})
|
||||
let data = {
|
||||
...designItemDetail,
|
||||
priority:priority,
|
||||
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
}
|
||||
if(this.isShowMark){
|
||||
return
|
||||
}
|
||||
this.isShowMark = true
|
||||
Https.axiosPost(Https.httpUrls.detailPrintDot, data).then(
|
||||
(rv: any) => {
|
||||
this.perviewUrl = rv
|
||||
this.isShowMark = false
|
||||
}
|
||||
).catch(res=>{
|
||||
this.isShowMark = false
|
||||
});
|
||||
},
|
||||
|
||||
backPreview(){
|
||||
this.perviewUrl = ''
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="less">
|
||||
.placement_modal_component{
|
||||
|
||||
.ant-modal-close{
|
||||
width: 3.6rem;
|
||||
height: 3.6rem;
|
||||
position: absolute;
|
||||
top: -1.8rem;
|
||||
right: -1.8rem;
|
||||
}
|
||||
|
||||
.ant-modal-header{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ant-modal-body{
|
||||
background: #F2F3FB;
|
||||
min-height: 72rem;
|
||||
overflow-y: hidden;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.close_icon{
|
||||
width: 3.6rem;
|
||||
height: 3.6rem;
|
||||
background: #000000;
|
||||
border-radius: 50%;
|
||||
line-height: 3.6rem;
|
||||
text-align: center;
|
||||
|
||||
.icon-guanbi{
|
||||
font-size: 2rem;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
.placement_modal_body{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.palcement_modal_header{
|
||||
position: relative;
|
||||
height: 6.6rem;
|
||||
width: 100%;
|
||||
background: #F7F7F7;
|
||||
|
||||
.placement_modal_title{
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
line-height: 6.6rem;
|
||||
left: 3.7rem;
|
||||
top: 0;
|
||||
font-size: 1.8rem;
|
||||
color: #030303;
|
||||
}
|
||||
.placement_operate_list{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin:0 auto;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
height: 100%;
|
||||
|
||||
.operate_item{
|
||||
margin-right: 4rem;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
|
||||
.operate_icon{
|
||||
font-size: 2.1rem;
|
||||
color: #64686D;
|
||||
}
|
||||
|
||||
.operate_item_des{
|
||||
height: 1.2rem;
|
||||
font-size: 1.3rem;
|
||||
color: #64686D;
|
||||
}
|
||||
&:last-child{
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.placement_modal_content{
|
||||
position: relative;
|
||||
height: calc(100% - 6.6rem);
|
||||
width: 100%;
|
||||
padding: 1.1rem 0;
|
||||
|
||||
.placement_content_operate_list{
|
||||
width: 9rem;
|
||||
background: #EBECF4;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top:6.8rem;
|
||||
|
||||
.placement_content_operate_item{
|
||||
padding: 1.5rem 0;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
|
||||
.placement_overall_icon{
|
||||
width: 2.4rem;
|
||||
height: 2.4rem;
|
||||
padding: 0.3rem;
|
||||
background: #EBECF4;
|
||||
border: 0.1rem solid #64686D;
|
||||
margin: 0 auto 0.4rem;
|
||||
|
||||
.placement_overall_content{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #343579;
|
||||
}
|
||||
}
|
||||
|
||||
.placement_content_operate_des{
|
||||
width: 100%;
|
||||
font-size: 1.3rem;
|
||||
color: #64686D;
|
||||
-moz-user-select:none;
|
||||
user-select:none
|
||||
}
|
||||
|
||||
.print_scale_value{
|
||||
height: 1.1rem;
|
||||
font-size: 1.2rem;
|
||||
text-align: center;
|
||||
margin-bottom: 0.3rem;
|
||||
color: #64686D;
|
||||
}
|
||||
|
||||
.ant-tooltip-placement-top{
|
||||
top: -37px !important;
|
||||
}
|
||||
|
||||
.ant-slider-track{
|
||||
background: #343579;
|
||||
}
|
||||
.ant-slider-handle{
|
||||
border-color: #343579;
|
||||
}
|
||||
|
||||
.placement_add_point_block{
|
||||
width: 2.4rem;
|
||||
height: 2.4rem;
|
||||
position: relative;
|
||||
border: 2px solid #6E70FF;
|
||||
border-radius: 50%;
|
||||
margin: 0 auto 0.4rem;
|
||||
|
||||
.placement_add_point_content{
|
||||
width: 0.4rem;
|
||||
height: 0.4rem;
|
||||
border-radius: 50%;
|
||||
background: #6E70FF;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
.placement_remove_point_block{
|
||||
width: 2.4rem;
|
||||
height: 2.4rem;
|
||||
border: 2px solid #000000;
|
||||
border-radius: 50%;
|
||||
margin: 0 auto 0.4rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.img_preview_block{
|
||||
width: 40.8rem;
|
||||
background: #ffffff;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
user-select:none;
|
||||
-moz-user-select:none;
|
||||
position: relative;
|
||||
|
||||
.img_content_block{
|
||||
width: 40.8rem;
|
||||
height: 100%;
|
||||
max-height: 63.2rem;
|
||||
overflow-y: auto;
|
||||
-ms-overflow-style: none;
|
||||
overflow: -moz-scrollbars-none;
|
||||
position: relative;
|
||||
|
||||
&::-webkit-scrollbar { width: 0 !important }
|
||||
}
|
||||
|
||||
.perview_mark_loading{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
height: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
z-index: 9;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
}
|
||||
|
||||
.placement_img{
|
||||
width: 100%;
|
||||
user-select:none;
|
||||
-moz-user-select:none;
|
||||
}
|
||||
|
||||
.ponit_click{
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
position: absolute;
|
||||
border: 2px solid #6E70FF;
|
||||
border-radius: 50%;
|
||||
-moz-user-select:none; /* Firefox私有属性 */
|
||||
-webkit-user-select:none; /* WebKit内核私有属性 */
|
||||
-ms-user-select:none; /* IE私有属性(IE10及以后) */
|
||||
-khtml-user-select:none; /* KHTML内核私有属性 */
|
||||
-o-user-select:none; /* Opera私有属性 */
|
||||
user-select:none; /* CSS3属性 */
|
||||
cursor: pointer;
|
||||
|
||||
&.remove_point_click{
|
||||
border-color: transparent;
|
||||
background: #EF3C3C;
|
||||
}
|
||||
|
||||
.placement_add_point_content{
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
border-radius: 50%;
|
||||
background: #6E70FF;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.icon-guanbi{
|
||||
font-size: 20px;
|
||||
line-height: 20px;
|
||||
color:#ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
570
src/component/Detail/PlacementModalMobile.vue
Normal file
@@ -0,0 +1,570 @@
|
||||
<template>
|
||||
<div v-show="placementShow">
|
||||
<a-modal class="placement_modal_mobile_component"
|
||||
v-model:visible="placementShow"
|
||||
:footer="null"
|
||||
width="111.5rem"
|
||||
:maskClosable="false"
|
||||
:centered="true"
|
||||
>
|
||||
<template #closeIcon>
|
||||
<div class="close_icon" @click.stop="closeModal()"><span class="icon iconfont icon-guanbi"></span></div>
|
||||
</template>
|
||||
<div class="placement_modal_body" >
|
||||
<div class="palcement_modal_header">
|
||||
<div class="placement_modal_title">Placement</div>
|
||||
<div class="placement_operate_list">
|
||||
<div class="operate_item" @click="submitPlacement">
|
||||
<div class="icon iconfont icon-baocun1 operate_icon"></div>
|
||||
<div class="operate_item_des">Submit</div>
|
||||
</div>
|
||||
<div class="operate_item" @click="printPreview">
|
||||
<div class="icon iconfont icon-shengchengyulan operate_icon"></div>
|
||||
<div class="operate_item_des">Preview</div>
|
||||
</div>
|
||||
<div class="operate_item" v-show="perviewUrl" @click="backPreview">
|
||||
<div class="icon iconfont icon-fanhui1 operate_icon"></div>
|
||||
<div class="operate_item_des">Back</div>
|
||||
</div>
|
||||
<div class="operate_item" @click="restoreLocationList">
|
||||
<div class="icon iconfont icon-huifu operate_icon"></div>
|
||||
<div class="operate_item_des">Restore</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="placement_modal_content" @touchmove="startMove($event)">
|
||||
<div class="placement_content_operate_list">
|
||||
<!-- <div class="placement_content_operate_item" @click="overallClick()">
|
||||
<div class="placement_overall_icon">
|
||||
<div class="placement_overall_content" v-show="!printObject.ifSingle"></div>
|
||||
</div>
|
||||
<div class="placement_content_operate_des">Overall</div>
|
||||
</div> -->
|
||||
|
||||
<div class="placement_content_operate_item">
|
||||
<div class="print_scale_value">{{placement_sacle}}%</div>
|
||||
<a-slider
|
||||
id="placement_silder"
|
||||
:tooltipVisible="false"
|
||||
v-model:value="placement_sacle"
|
||||
:min="30"
|
||||
:max="300"
|
||||
/>
|
||||
<div class="placement_content_operate_des">Print Scale</div>
|
||||
</div>
|
||||
<!--
|
||||
<div class="placement_content_operate_item" @touchstart="AddDian()">
|
||||
<div class="placement_add_point_block">
|
||||
<div class="placement_add_point_content"></div>
|
||||
</div>
|
||||
<div class="placement_content_operate_des" >Add Point</div>
|
||||
</div>
|
||||
|
||||
<div class="placement_content_operate_item" @click="changeRemoveStatus">
|
||||
<div class="placement_remove_point_block"></div>
|
||||
<div class="placement_content_operate_des">Remove Point</div>
|
||||
</div> -->
|
||||
</div>
|
||||
|
||||
<div class="img_preview_block" >
|
||||
<div class="perview_mark_loading" v-show="isShowMark">
|
||||
<a-spin size="large" />
|
||||
</div>
|
||||
<div class="img_content_block" ref="imgbox" @touchmove="startMove($event)">
|
||||
<img class="placement_img" v-lazy="perviewUrl || clothesData?.path" :key="perviewUrl || clothesData?.path">
|
||||
<div :class="['ponit_click',isRemoveStatus?'remove_point_click':'']" v-for="(item,index) in locationList" :key="item" :style="{left:item.left+'px', top:item.top+'px'}" @touchstart="getMouseDown($event,item,index)" @touchmove="startMove($event)">
|
||||
<div class="placement_add_point_content" v-show="!isRemoveStatus"></div>
|
||||
<div class="icon iconfont icon-guanbi" v-show="isRemoveStatus"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent,ref} from 'vue'
|
||||
import { Https } from "@/tool/https";
|
||||
import { useStore } from "vuex";
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const store = useStore()
|
||||
let oldLocationList:any = ref([])
|
||||
let locationList:any = ref([])
|
||||
let printObject:any = ref({})
|
||||
let imgBox:any = ref({})
|
||||
let intObj:any = ref(null)
|
||||
let currentSign:any = ref({})
|
||||
let clothesData:any = ref({})
|
||||
return {
|
||||
store,
|
||||
oldLocationList,
|
||||
locationList,
|
||||
printObject,
|
||||
imgBox,
|
||||
intObj,
|
||||
currentSign,
|
||||
clothesData
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
placementShow:false,
|
||||
collectionIndex:0,
|
||||
startDian:false,
|
||||
moveOriginal:{posX: 0, posY: 0},
|
||||
isRemoveStatus:false,
|
||||
placement_sacle:30,
|
||||
isShowMark:false,
|
||||
perviewUrl:'',//预览的图片地址
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
formatter(value:number){
|
||||
return `${value}%`;
|
||||
},
|
||||
|
||||
showPlacementModal(data:any){
|
||||
this.clothesData = JSON.parse(JSON.stringify(data.clothesData))
|
||||
this.printObject = this.clothesData.printObject
|
||||
this.collectionIndex = data.index
|
||||
this.placement_sacle = this.printObject.scale ? this.printObject.scale * 100 : 30
|
||||
this.placementShow = true
|
||||
setTimeout(()=>{
|
||||
let imgbox:any = this.$refs.imgbox
|
||||
let position = imgbox.getBoundingClientRect()
|
||||
this.imgBox = {
|
||||
width:imgbox.clientWidth,
|
||||
height:imgbox.scrollHeight,
|
||||
left : position.left,
|
||||
top:position.top,
|
||||
scrollTop:imgbox.scrollTop || 0,
|
||||
}
|
||||
this.getLocationList(this.imgBox)
|
||||
},500)
|
||||
},
|
||||
|
||||
getLocationList(imgBox:any){
|
||||
if(this.printObject.location){
|
||||
this.locationList = this.printObject.location.map((v:any)=>{
|
||||
let data = {
|
||||
left:v[0] * imgBox.width,
|
||||
top:v[1] * imgBox.height
|
||||
}
|
||||
return data
|
||||
})
|
||||
this.oldLocationList = JSON.parse(JSON.stringify(this.locationList))
|
||||
}
|
||||
},
|
||||
|
||||
overallClick(){
|
||||
this.printObject.ifSingle = !this.printObject.ifSingle
|
||||
},
|
||||
|
||||
AddDian(){
|
||||
this.startDian = true
|
||||
this.isRemoveStatus = false
|
||||
this.intObj = true
|
||||
},
|
||||
|
||||
changeRemoveStatus(){
|
||||
this.isRemoveStatus = true
|
||||
},
|
||||
|
||||
startMove(event:any){
|
||||
if(this.isRemoveStatus){
|
||||
return
|
||||
}
|
||||
let imgbox:any = this.$refs.imgbox
|
||||
let scrollTop = imgbox.scrollTop;
|
||||
if(event.targetTouches[0].pageX > this.imgBox.left){
|
||||
if(this.intObj){
|
||||
this.currentSign.left = event.targetTouches[0].pageX - this.imgBox.left
|
||||
this.currentSign.top = event.targetTouches[0].pageY + scrollTop - this.imgBox.top
|
||||
this.locationList.push(this.currentSign)
|
||||
this.printObject.ifSingle = true
|
||||
this.intObj = null
|
||||
}else{
|
||||
if(this.startDian){
|
||||
this.currentSign.left = event.targetTouches[0].pageX - this.imgBox.left - this.moveOriginal.posX
|
||||
this.currentSign.top = event.targetTouches[0].pageY + scrollTop - this.imgBox.top -this.moveOriginal.posY
|
||||
document.addEventListener('touchend', this.getMouseOver);
|
||||
this.$forceUpdate()
|
||||
this.setBoundarySign()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
|
||||
|
||||
// 在边界上的签名域处理
|
||||
setBoundarySign() {
|
||||
let imgbox:any = this.$refs.imgbox
|
||||
let height = imgbox.offsetHeight + imgbox.scrollTop;
|
||||
// 2 为签名域的边框
|
||||
let maxPosHeight = height - 24
|
||||
let maxPosWidth = imgbox.clientWidth - 24 //+ this.signBox.paddLeft;
|
||||
if (this.currentSign.top <= 0) {
|
||||
this.currentSign.top = 0
|
||||
} else if (this.currentSign.top >= maxPosHeight ) {
|
||||
this.currentSign.top = maxPosHeight;
|
||||
}
|
||||
if (this.currentSign.left <= 0) {
|
||||
this.currentSign.left = 0
|
||||
} else if (this.currentSign.left >= maxPosWidth) {
|
||||
this.currentSign.left = maxPosWidth;
|
||||
}
|
||||
},
|
||||
|
||||
getMouseDown(event:any,item:any,index:number){
|
||||
if(this.isRemoveStatus){
|
||||
this.locationList.splice(index,1)
|
||||
}else{
|
||||
this.currentSign = item
|
||||
// 计算出鼠标在签名域上的偏移
|
||||
this.moveOriginal.posX = event.targetTouches[0].pageX - this.imgBox.left - this.currentSign.left
|
||||
this.moveOriginal.posY = event.targetTouches[0].pageY - this.imgBox.top- this.currentSign.top // 1为边框
|
||||
this.startDian = true
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
getMouseOver(){
|
||||
this.startDian = false
|
||||
this.currentSign = {}
|
||||
document.removeEventListener('touchend', this.getMouseOver);
|
||||
},
|
||||
|
||||
closeModal(){
|
||||
this.oldLocationList = []
|
||||
this.locationList = []
|
||||
this.printObject = {}
|
||||
this.intObj = null
|
||||
this.currentSign = {}
|
||||
this.isRemoveStatus = false
|
||||
this.placementShow = false
|
||||
this.perviewUrl = ''
|
||||
},
|
||||
|
||||
restoreLocationList(){
|
||||
this.locationList = JSON.parse(JSON.stringify(this.oldLocationList))
|
||||
},
|
||||
|
||||
submitPlacement(){
|
||||
this.printObject.scale = (this.placement_sacle / 100).toFixed(2)
|
||||
this.printObject.location = this.printObject.ifSingle ? this.getPrintLocation() :[]
|
||||
this.$emit('submitPlacement',this.printObject)
|
||||
this.closeModal()
|
||||
|
||||
},
|
||||
|
||||
getPrintLocation(){
|
||||
let {width , height} = this.imgBox
|
||||
let location = this.locationList.map((v:any)=>{
|
||||
let left = (v.left + 12) / width
|
||||
let top = (v.top + 12) / height
|
||||
let data = [left,top]
|
||||
return data
|
||||
})
|
||||
return location
|
||||
},
|
||||
|
||||
//preview打点图
|
||||
printPreview(){
|
||||
this.printObject.scale = this.placement_sacle / 100
|
||||
this.printObject.location = this.printObject.ifSingle ? this.getPrintLocation() :[]
|
||||
let designItemDetail = JSON.parse(JSON.stringify(this.store.state.DesignDetailModule.designItemDetail))
|
||||
designItemDetail.clothes[this.collectionIndex] = this.clothesData
|
||||
delete designItemDetail.designItemUrl
|
||||
let priority = designItemDetail.clothes.map((v:any)=>{
|
||||
return v.type
|
||||
})
|
||||
let data = {
|
||||
...designItemDetail,
|
||||
priority:priority,
|
||||
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
}
|
||||
if(this.isShowMark){
|
||||
return
|
||||
}
|
||||
this.isShowMark = true
|
||||
Https.axiosPost(Https.httpUrls.detailPrintDot, data).then(
|
||||
(rv: any) => {
|
||||
this.perviewUrl = rv
|
||||
this.isShowMark = false
|
||||
}
|
||||
).catch(res=>{
|
||||
this.isShowMark = false
|
||||
});
|
||||
},
|
||||
|
||||
backPreview(){
|
||||
this.perviewUrl = ''
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="less">
|
||||
.placement_modal_mobile_component{
|
||||
|
||||
.ant-modal-close{
|
||||
width: 3.6rem;
|
||||
height: 3.6rem;
|
||||
position: absolute;
|
||||
top: -1.8rem;
|
||||
right: -1.8rem;
|
||||
}
|
||||
|
||||
.ant-modal-header{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ant-modal-body{
|
||||
background: #F2F3FB;
|
||||
min-height: 72rem;
|
||||
overflow-y: hidden;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.close_icon{
|
||||
width: 3.6rem;
|
||||
height: 3.6rem;
|
||||
background: #000000;
|
||||
border-radius: 50%;
|
||||
line-height: 3.6rem;
|
||||
text-align: center;
|
||||
|
||||
.icon-guanbi{
|
||||
font-size: 2rem;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
.placement_modal_body{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.palcement_modal_header{
|
||||
position: relative;
|
||||
height: 6.6rem;
|
||||
width: 100%;
|
||||
background: #F7F7F7;
|
||||
|
||||
.placement_modal_title{
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
line-height: 6.6rem;
|
||||
left: 3.7rem;
|
||||
top: 0;
|
||||
font-size: 1.8rem;
|
||||
color: #030303;
|
||||
}
|
||||
.placement_operate_list{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin:0 auto;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
height: 100%;
|
||||
|
||||
.operate_item{
|
||||
margin-right: 4rem;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
|
||||
.operate_icon{
|
||||
font-size: 2.1rem;
|
||||
color: #64686D;
|
||||
}
|
||||
|
||||
.operate_item_des{
|
||||
height: 1.2rem;
|
||||
font-size: 1.3rem;
|
||||
color: #64686D;
|
||||
}
|
||||
&:last-child{
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.placement_modal_content{
|
||||
position: relative;
|
||||
height: calc(100% - 6.6rem);
|
||||
width: 100%;
|
||||
padding: 1.1rem 0;
|
||||
|
||||
.placement_content_operate_list{
|
||||
width: 9rem;
|
||||
background: #EBECF4;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top:6.8rem;
|
||||
|
||||
.placement_content_operate_item{
|
||||
padding: 1.5rem 0;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
|
||||
.placement_overall_icon{
|
||||
width: 2.4rem;
|
||||
height: 2.4rem;
|
||||
padding: 0.3rem;
|
||||
background: #EBECF4;
|
||||
border: 0.1rem solid #64686D;
|
||||
margin: 0 auto 0.4rem;
|
||||
|
||||
.placement_overall_content{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #343579;
|
||||
}
|
||||
}
|
||||
|
||||
.placement_content_operate_des{
|
||||
width: 100%;
|
||||
font-size: 1.3rem;
|
||||
color: #64686D;
|
||||
-moz-user-select:none;
|
||||
user-select:none
|
||||
}
|
||||
|
||||
.print_scale_value{
|
||||
height: 1.1rem;
|
||||
font-size: 1.2rem;
|
||||
text-align: center;
|
||||
margin-bottom: 0.3rem;
|
||||
color: #64686D;
|
||||
}
|
||||
|
||||
.ant-tooltip-placement-top{
|
||||
top: -37px !important;
|
||||
}
|
||||
|
||||
.ant-slider-track{
|
||||
background: #343579;
|
||||
}
|
||||
.ant-slider-handle{
|
||||
border-color: #343579;
|
||||
}
|
||||
|
||||
.placement_add_point_block{
|
||||
width: 2.4rem;
|
||||
height: 2.4rem;
|
||||
position: relative;
|
||||
border: 2px solid #6E70FF;
|
||||
border-radius: 50%;
|
||||
margin: 0 auto 0.4rem;
|
||||
|
||||
.placement_add_point_content{
|
||||
width: 0.4rem;
|
||||
height: 0.4rem;
|
||||
border-radius: 50%;
|
||||
background: #6E70FF;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
.placement_remove_point_block{
|
||||
width: 2.4rem;
|
||||
height: 2.4rem;
|
||||
border: 2px solid #000000;
|
||||
border-radius: 50%;
|
||||
margin: 0 auto 0.4rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.img_preview_block{
|
||||
width: 40.8rem;
|
||||
background: #ffffff;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
user-select:none;
|
||||
-moz-user-select:none;
|
||||
position: relative;
|
||||
|
||||
.img_content_block{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-height: 63.2rem;
|
||||
overflow-y: auto;
|
||||
-ms-overflow-style: none;
|
||||
overflow: -moz-scrollbars-none;
|
||||
position: relative;
|
||||
|
||||
&::-webkit-scrollbar { width: 0 !important }
|
||||
}
|
||||
|
||||
.perview_mark_loading{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
height: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
z-index: 9;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
}
|
||||
|
||||
.placement_img{
|
||||
width: 100%;
|
||||
user-select:none;
|
||||
-moz-user-select:none;
|
||||
}
|
||||
|
||||
.ponit_click{
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
position: absolute;
|
||||
border: 2px solid #6E70FF;
|
||||
border-radius: 50%;
|
||||
-moz-user-select:none; /* Firefox私有属性 */
|
||||
-webkit-user-select:none; /* WebKit内核私有属性 */
|
||||
-ms-user-select:none; /* IE私有属性(IE10及以后) */
|
||||
-khtml-user-select:none; /* KHTML内核私有属性 */
|
||||
-o-user-select:none; /* Opera私有属性 */
|
||||
user-select:none; /* CSS3属性 */
|
||||
cursor: pointer;
|
||||
|
||||
&.remove_point_click{
|
||||
border-color: transparent;
|
||||
background: #EF3C3C;
|
||||
}
|
||||
|
||||
.placement_add_point_content{
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
border-radius: 50%;
|
||||
background: #6E70FF;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.icon-guanbi{
|
||||
font-size: 20px;
|
||||
line-height: 20px;
|
||||
color:#ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
546
src/component/HomePage/ColorboardUpload.vue
Normal file
@@ -0,0 +1,546 @@
|
||||
<template>
|
||||
<div class="colorboard_upload_modal">
|
||||
<div class="colorboard_upload_left">
|
||||
<div class="upload_left_header">
|
||||
<span class="color_list icon iconfont icon-diaosebanpalette3"></span>
|
||||
<span>My Color Palette</span>
|
||||
</div>
|
||||
<div class="upload_left_content scroll_style">
|
||||
<div class="upload_color_block" v-for="(color,index) in colorList" :key="color">
|
||||
<div @click="selectColorItem(index,color)" :class="['upload_color',selectIndex === index ? 'select_upload_color' : '']" :style="{background:`rgb(${color?.r},${color?.g},${color?.b})`}"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="colorboard_upload_right">
|
||||
<div class="upload_right_content">
|
||||
<div class="right_content_line">
|
||||
<div class="upload_right_header">
|
||||
<span class="color_edit icon iconfont icon-yansefangan"></span>
|
||||
<span>Choose Color</span>
|
||||
</div>
|
||||
<div class="color_setting_block">
|
||||
<Chrome class="chrome_color" v-model="selectColor"></Chrome>
|
||||
<Slider class="sileder_color" v-model="selectColor"></Slider>
|
||||
<div class="color_rgb_block">
|
||||
<div class="rgb_item">R:{{getSelectRGB(selectColor).r}}</div>
|
||||
<div class="rgb_item">G:{{getSelectRGB(selectColor).g}}</div>
|
||||
<div class="rgb_item">B:{{getSelectRGB(selectColor).b}}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="color_review_block">
|
||||
<div class="color_review_content" :style="{background: reviewColor?.r || reviewColor?.r===0 ?`rgb(${reviewColor?.r},${reviewColor?.g},${reviewColor?.b})` : 'none'}"></div>
|
||||
<div class="pantong_name" v-show="pantongName">{{pantongName}}</div>
|
||||
<div class="clear_button" @click="clearCurrentColor()">Clear</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="right_content_line">
|
||||
<div class="upload_right_header">
|
||||
<span class="color_edit icon iconfont icon-yansefangan"></span>
|
||||
<span>Upload Color</span>
|
||||
</div>
|
||||
<div class="upload_item">
|
||||
<div class="upload_file_item" v-for="(file) in fileList" :key="file">
|
||||
<div class="upload_file_item_content" v-show="file.status !== 'done'">
|
||||
<a-spin :indicator="indicator" tip="Uploading..."/>
|
||||
</div>
|
||||
<div class="upload_file_item_content" v-show="file.status === 'done'">
|
||||
<img :src="file?.imgUrl" class="upload_img" ref="colorImage">
|
||||
<div class="delete_file_block" @click="deleteFile(index)">Delete</div>
|
||||
</div>
|
||||
</div>
|
||||
<a-upload
|
||||
v-show="fileList.length < 1"
|
||||
list-type="picture-card"
|
||||
:customRequest="function(){}"
|
||||
@change="fileUploadChange"
|
||||
:before-upload="beforeUpload"
|
||||
accept=".jpg,.png,.jpeg,.bmp"
|
||||
>
|
||||
<div class="upload_tip_block">
|
||||
<img class="upload_img_icon" src="@/assets/images/homePage/add_file.png">
|
||||
</div>
|
||||
</a-upload>
|
||||
</div>
|
||||
|
||||
<div class="upload_right_header">
|
||||
<span class="color_edit icon iconfont icon-yansefangan"></span>
|
||||
<span>Key in Color Code</span>
|
||||
</div>
|
||||
<div class="get_color_block">
|
||||
<input class="get_color_input" placeholder="tcx value (e.g.: 19-4052)" v-model="tcxColor" @keydown.enter="getTcxColor()"/>
|
||||
<div class="get_color_button" @click="getTcxColor()">
|
||||
<span class="icon iconfont icon-huoquduixiang"></span>
|
||||
<span class="get_color_des">Extract Color</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { Chrome,Slider } from '@ans1998/vue3-color'
|
||||
import { Https } from "@/tool/https";
|
||||
import { defineComponent, h,ref } from 'vue'
|
||||
import { LoadingOutlined } from '@ant-design/icons-vue';
|
||||
import {getCookie} from '@/tool/cookie'
|
||||
import {getUploadUrl,rgbToHsv} from '@/tool/util'
|
||||
import {useStore} from 'vuex'
|
||||
import ColorThief from '@/tool/colorthief/colorthief'
|
||||
import { message,Upload} from 'ant-design-vue';
|
||||
export default defineComponent({
|
||||
components:{
|
||||
Chrome,
|
||||
Slider
|
||||
},
|
||||
setup(){
|
||||
let fileList:any = ref([])
|
||||
let colorList:any = [{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}]
|
||||
let selectColor:any = ref({rgba:{}}) //顔色选择器默认颜色
|
||||
return {
|
||||
fileList,
|
||||
colorList,
|
||||
selectColor,
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
selectColor(newVal:any,oldVal:any){
|
||||
this.reviewColor = newVal.rgba || {}
|
||||
this.colorList[this.selectIndex] = newVal.rgba
|
||||
let colorList =this.colorList.filter((v:any) => v && Object.keys(v).length)
|
||||
this.setColorboardList(colorList)
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
getSelectRGB(selectColor){
|
||||
return (selectColor:any)=>{
|
||||
let rgba = selectColor.rgba
|
||||
let data = {
|
||||
r:rgba?.r || rgba?.r===0 ? rgba?.r : 255,
|
||||
g:rgba?.g || rgba?.g===0 ? rgba?.g : 255,
|
||||
b:rgba?.b || rgba?.b===0 ? rgba?.b : 255,
|
||||
}
|
||||
return data
|
||||
}
|
||||
},
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
|
||||
reviewColor:{}, //预览的颜色
|
||||
selectIndex:0,//选中的文件索引
|
||||
tcxColor:'',
|
||||
pantongName:'',//潘通值
|
||||
indicator : h(LoadingOutlined, {
|
||||
style: {
|
||||
fontSize: '2.4rem',
|
||||
},
|
||||
spin: true,
|
||||
}),
|
||||
upload:{
|
||||
isPin:0,
|
||||
level1Type:'Moodboard',
|
||||
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
},
|
||||
token:'',
|
||||
uploadUrl:'',
|
||||
store:useStore()
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
this.token = getCookie('token') || ''
|
||||
this.uploadUrl = getUploadUrl()
|
||||
},
|
||||
methods:{
|
||||
//选择不同的色块
|
||||
selectColorItem(index:any,color:any){
|
||||
this.selectIndex = index
|
||||
this.reviewColor = color?.r + ''? {r:color.r,g:color.g ,b:color.b } : {}
|
||||
this.selectColor = color?.r + ''? {rgba:{r:color.r,g:color.g,b:color.b,a:1}} : {}
|
||||
this.fileList = []
|
||||
this.tcxColor = ''
|
||||
this.pantongName = ''
|
||||
},
|
||||
|
||||
//通过tcx获取颜色
|
||||
getTcxColor(){
|
||||
if(!this.tcxColor){
|
||||
return
|
||||
}
|
||||
Https.axiosGet(Https.httpUrls.getRgbByTcx + '?tcx=' + this.tcxColor).then((rv) =>{
|
||||
if(rv && rv.name){
|
||||
this.reviewColor = {r:rv.r, g:rv.g, b:rv.b}
|
||||
this.colorList[this.selectIndex] = {r:rv.r, g:rv.g, b:rv.b}
|
||||
this.pantongName = rv.name
|
||||
let colorList =this.colorList.filter((v:any) => Object.keys(v).length)
|
||||
this.setColorboardList(colorList)
|
||||
}else{
|
||||
message.error("Can't find the TCX color")
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
//清除当前的颜色
|
||||
clearCurrentColor(){
|
||||
this.selectColor = {}
|
||||
this.fileList = []
|
||||
this.pantongName = ''
|
||||
this.tcxColor = ''
|
||||
},
|
||||
|
||||
fileUploadChange(data:any){
|
||||
let file = data.file
|
||||
let fileData = file.originFileObj
|
||||
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;
|
||||
}
|
||||
file.imgUrl = data_new
|
||||
file.status = 'done'
|
||||
this.fileList.push(file)
|
||||
|
||||
setTimeout(()=>{
|
||||
const colorThief = new ColorThief();
|
||||
let colorImage:any = this.$refs.colorImage
|
||||
let domImg:any = colorImage[0];
|
||||
let color = colorThief.getColor(domImg)
|
||||
this.getHsvColor(color)
|
||||
this.reviewColor = {r:color[0],g:color[1],b:color[2]}
|
||||
this.selectColor = {rgba:{r:color[0],g:color[1],b:color[2],a:1}}
|
||||
},100)
|
||||
};
|
||||
// 转化为base64S
|
||||
reader.readAsDataURL(fileData)
|
||||
},
|
||||
|
||||
beforeUpload(file:any){
|
||||
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg' || file.type === 'image/bmp';
|
||||
if (!isJpgOrPng) {
|
||||
message.error('You can only upload Image file!');
|
||||
}
|
||||
const isLt2M = file.size / 1024 / 1024 < 2;
|
||||
if (!isLt2M) {
|
||||
message.error('Image must smaller than 5MB!');
|
||||
}
|
||||
return (isJpgOrPng && isLt2M) || Upload.LIST_IGNORE;
|
||||
},
|
||||
|
||||
deleteFile(index:any){
|
||||
this.fileList.splice(index, 1)
|
||||
},
|
||||
|
||||
//通过HSV获取颜色
|
||||
getHsvColor(color:any){
|
||||
let hsv = rgbToHsv(color)
|
||||
this.pantongName = ''
|
||||
Https.axiosGet(Https.httpUrls.getRgbByHsv + `?h=${hsv[0]}&s=${hsv[0]}&v=${hsv[1]}`).then((rv) =>{
|
||||
if(rv){
|
||||
this.pantongName = rv.name
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
setColorboardList(colorList:any){
|
||||
let newColorList = colorList.map((v:any)=>{
|
||||
let data = {
|
||||
id:'',
|
||||
name:'',
|
||||
rgbValue:v
|
||||
}
|
||||
return data
|
||||
})
|
||||
this.store.commit('setColorboardList',newColorList)
|
||||
|
||||
},
|
||||
|
||||
recollection(){
|
||||
let colorList = this.store.state.UploadFilesModule.allBoardData.colorBoards
|
||||
colorList.forEach((ele:any, index:number) => {
|
||||
this.colorList[index] = ele.rgbValue
|
||||
});
|
||||
this.reviewColor = this.colorList[0]
|
||||
this.selectColor = {rgba:this.colorList[0]}, //顔色选择器默认颜色
|
||||
this.store.commit('setColorboardList',colorList)
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="less">
|
||||
.colorboard_upload_modal{
|
||||
padding: 1rem 1rem 1.8rem 1rem;
|
||||
height: 100%;
|
||||
background: #F2F3FB;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.colorboard_upload_left{
|
||||
width: calc(100% - 48rem);
|
||||
height: 100%;
|
||||
background: #FFFFFF;
|
||||
|
||||
.upload_left_header{
|
||||
padding: 1.4rem 2rem 1.6rem;
|
||||
font-size: 1.6rem;
|
||||
color: #333333;
|
||||
font-weight: bold;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 2.4rem;
|
||||
|
||||
.color_list{
|
||||
font-size: 2.2rem;
|
||||
margin-right: 0.7rem;
|
||||
}
|
||||
}
|
||||
|
||||
.upload_left_content{
|
||||
padding: 1rem 1.6rem;
|
||||
height: calc(100% - 5.4rem);
|
||||
overflow-y: auto;
|
||||
|
||||
.upload_color_block{
|
||||
padding: 0 0.4rem;
|
||||
margin-bottom: 2.6rem;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
|
||||
.upload_color{
|
||||
width: 11.5rem;
|
||||
height: 11.5rem;
|
||||
border: 0.1rem solid #DCDCEC;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.select_upload_color{
|
||||
border-color: #343579;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.colorboard_upload_right{
|
||||
width: 47rem;
|
||||
height: 100%;
|
||||
background: #FFFFFF;
|
||||
|
||||
.upload_right_header{
|
||||
padding: 0.4rem 0 1.6rem 0;
|
||||
font-weight: bold;
|
||||
line-height: 2.4rem;
|
||||
font-size: 1.6rem;
|
||||
color: #333333;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.color_edit{
|
||||
font-size: 2.4rem;
|
||||
margin-right: 0.7rem;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.upload_right_content{
|
||||
padding: 1rem 2.8rem;
|
||||
height: calc(100% - 5.4rem);
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
display: flex;
|
||||
|
||||
.right_content_line{
|
||||
margin-bottom: 2.3rem;
|
||||
|
||||
.color_review_block{
|
||||
margin-right: 4rem;
|
||||
|
||||
.color_review_content{
|
||||
width: 16.5rem;
|
||||
height: 16.5rem;
|
||||
background: #FFFFFF;
|
||||
border: 0.1rem solid #DCDCEC;
|
||||
}
|
||||
|
||||
.pantong_name{
|
||||
margin-top: 1rem;
|
||||
font-size: 1.6rem;
|
||||
font-weight: 400;
|
||||
color: #030303;
|
||||
text-align: left;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.clear_button{
|
||||
padding: 0 2.8rem;
|
||||
height: 3.2rem;
|
||||
line-height: 3.2rem;
|
||||
background: #EFEEFF;
|
||||
font-size: 1.2rem;
|
||||
font-family: Roboto;
|
||||
color: #343579;
|
||||
display: inline-block;
|
||||
margin-top: 1rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.upload_file_item{
|
||||
margin: 0 2rem 2rem 0;
|
||||
display: inline-block;
|
||||
width: 16.5rem;
|
||||
height: 16.5rem;
|
||||
border: 1px solid #F5F5F5;
|
||||
vertical-align: top;
|
||||
|
||||
.upload_file_item_content{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover .delete_file_block{
|
||||
display: block;
|
||||
}
|
||||
|
||||
.upload_img{
|
||||
display: block;
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.delete_file_block{
|
||||
display: none;
|
||||
width: 100%;
|
||||
height: 4rem;
|
||||
background: rgba(0,0,0,0.2);
|
||||
font-size: 1.6rem;
|
||||
color: #FFFFFF;
|
||||
line-height: 4rem;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.upload_img_icon{
|
||||
width: 4.6rem;
|
||||
}
|
||||
|
||||
.color_setting_block{
|
||||
width: 16.5rem;
|
||||
margin-right: 4rem;
|
||||
margin-bottom: 7rem;
|
||||
.vc-chrome-body{
|
||||
display: none;
|
||||
}
|
||||
.chrome_color{
|
||||
width: 16.5rem;
|
||||
height: 16.5rem;
|
||||
overflow: hidden;
|
||||
|
||||
.vc-chrome-saturation-wrap{
|
||||
height: 100%;
|
||||
}
|
||||
.vc-chrome-saturation-wrap .vc-saturation-circle{
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.sileder_color{
|
||||
margin-top:1.3rem;
|
||||
|
||||
.vc-slider-swatches{
|
||||
display:none
|
||||
}
|
||||
.vc-slider-hue-warp {
|
||||
width: 16.5rem;
|
||||
height: 2.4rem;
|
||||
border-radius: 1.2rem;
|
||||
overflow: hidden;
|
||||
|
||||
.vc-hue-picker{
|
||||
width: 1.4rem;
|
||||
height: 1.4rem;
|
||||
border-radius: 50%;
|
||||
transform: translate(-0.7rem, -0.2rem);
|
||||
}
|
||||
}
|
||||
.vc-hue-pointer{
|
||||
top: 0.5rem !important;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.color_rgb_block{
|
||||
margin-top: 1rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 1.6rem;
|
||||
color: #343579;
|
||||
}
|
||||
}
|
||||
|
||||
.get_color_block{
|
||||
|
||||
.get_color_input{
|
||||
width: 19.4rem;
|
||||
height: 3.8rem;
|
||||
background: #FFFFFF;
|
||||
border: 0.1rem solid #DCDCEC;
|
||||
padding: 1rem 1.3rem;
|
||||
box-sizing: border-box;
|
||||
font-size: 1.4rem;
|
||||
text-align: left;
|
||||
|
||||
&::placeholder {
|
||||
color: #B7B7B7;
|
||||
}
|
||||
}
|
||||
|
||||
.get_color_button{
|
||||
margin-top: 1.5rem;
|
||||
padding: 0 2.2rem;
|
||||
height: 3.2rem;
|
||||
background: #EFEEFF;
|
||||
display: inline-block;
|
||||
line-height: 3rem;
|
||||
font-size: 1.2rem;
|
||||
color: #343579;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
|
||||
.icon-huoquduixiang{
|
||||
margin-right: 0.5rem;
|
||||
font-size: 2rem;
|
||||
color:#343579;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.get_color_des{
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.upload_item{
|
||||
margin-bottom: 11.6rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
316
src/component/HomePage/Cropper.vue
Normal file
@@ -0,0 +1,316 @@
|
||||
<template>
|
||||
<a-modal class="modal_component cut_pricture_modal"
|
||||
v-model:visible="cutPicuterModal"
|
||||
:footer="null"
|
||||
title="Cut picture"
|
||||
width="115rem"
|
||||
:maskClosable="false"
|
||||
:centered="true"
|
||||
>
|
||||
<template #closeIcon>
|
||||
<div class="header_right_block" @click.stop="">
|
||||
<div class="next_step_button" @click.stop="finishCropper()">Finish</div>
|
||||
<div class="header_cancel_button" @click.stop="cancleCropper()">Cancel</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="collection_modal_body">
|
||||
<div class="cut_picture_left">
|
||||
<div class="cut_picture_body">
|
||||
<VueCropper
|
||||
ref="cropper"
|
||||
:original="option.original"
|
||||
:img="option.img"
|
||||
:outputSize="option.size"
|
||||
:outputType="option.outputType"
|
||||
:auto-crop="option.autoCrop"
|
||||
:auto-crop-width="option.autoCropWidth"
|
||||
:auto-crop-height="option.autoCropHeight"
|
||||
:center-box="option.centerBox"
|
||||
:can-move="option.canMove" :can-move-box="option.canMoveBox"
|
||||
@real-time="realTime"
|
||||
></VueCropper>
|
||||
</div>
|
||||
<div class="cur_picture_opterate">
|
||||
<div class="cur_picture_opterate_item" @click="rotateLeft()"><span class="icon iconfont icon-chexiao operate_icon"></span></div>
|
||||
<div class="cur_picture_opterate_item" @click="rotateRight()"><span class="icon iconfont icon-chexiao operate_icon icon_chexiao_sec"></span></div>
|
||||
<div class="cur_picture_opterate_item" @click="changeScale(-1)"><span class="operate_icon icon_font">-</span></div>
|
||||
<div class="cur_picture_opterate_item" @click="changeScale(1)"><span class="operate_icon icon_font">+</span></div>
|
||||
<div class="cur_picture_opterate_item" @click="refreshCrop()"><span class="icon iconfont icon-shuaxin operate_icon"></span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cut_picture_right">
|
||||
<div class="cur_picture_right_header">
|
||||
<div class="review_logo icon iconfont icon-yulan"></div>
|
||||
<div>Crop Preview</div>
|
||||
</div>
|
||||
<div class="cut_picture_review_block">
|
||||
<div class="cut_picture_review_item">
|
||||
<div class="cut_picture_review_content" :style="{'width': previews.w + 'px', 'height': previews.h + 'px', 'overflow': 'hidden'}">
|
||||
<div :style="previews.div" >
|
||||
<img class="previews_image" :style="previews.img" :src="previews.url">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cut_picture_review_item">
|
||||
<div class="cut_picture_review_block_sec" :style="{'width': previews.w + 'px', 'height': previews.h + 'px', 'overflow': 'hidden'}">
|
||||
<div :style="previews.div" >
|
||||
<img class="previews_image" :style="previews.img" :src="previews.url">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import 'vue-cropper/dist/index.css'
|
||||
import { VueCropper } from "vue-cropper";
|
||||
import {base64toFile} from '@/tool/util'
|
||||
export default defineComponent({
|
||||
props:['cropperFileData','isUpload'],
|
||||
components:{
|
||||
VueCropper,
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
cutPicuterModal:false,
|
||||
option: {
|
||||
original:false,
|
||||
img: '',
|
||||
size: 1,
|
||||
full: false,
|
||||
outputType: 'png',
|
||||
autoCrop: true,
|
||||
// 只有自动截图开启 宽度高度才生效
|
||||
autoCropWidth: 360,
|
||||
autoCropHeight: 360,
|
||||
max: 99999,
|
||||
centerBox:true,
|
||||
canMove:true,
|
||||
canMoveBox:true,
|
||||
},
|
||||
previews:{},
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
|
||||
rotateLeft() {
|
||||
let cropper:any = this.$refs.cropper
|
||||
cropper.rotateLeft();
|
||||
},
|
||||
rotateRight() {
|
||||
let cropper:any = this.$refs.cropper
|
||||
cropper.rotateRight();
|
||||
},
|
||||
refreshCrop() {
|
||||
let cropper:any = this.$refs.cropper
|
||||
cropper.refresh();
|
||||
},
|
||||
|
||||
changeScale(num:any) {
|
||||
num = num || 1;
|
||||
let cropper:any = this.$refs.cropper
|
||||
cropper.changeScale(num);
|
||||
},
|
||||
// 实时预览函数
|
||||
realTime(data:any) {
|
||||
this.previews = data;
|
||||
},
|
||||
|
||||
getOptionImg(img:any){
|
||||
this.option.img = img
|
||||
},
|
||||
|
||||
changeShowModal(type:any){
|
||||
this.cutPicuterModal = type
|
||||
},
|
||||
|
||||
finishCropper(){
|
||||
let cropper:any = this.$refs.cropper,
|
||||
that = this
|
||||
cropper.getCropData((data:any) => {
|
||||
// 转换为File对象
|
||||
let file = base64toFile(data,this.cropperFileData.name);
|
||||
this.$emit('handleCropperSuccess',{file:file, fileData:this.cropperFileData})
|
||||
})
|
||||
},
|
||||
|
||||
closeCropper(){
|
||||
this.cutPicuterModal = false
|
||||
this.option.img = ''
|
||||
},
|
||||
|
||||
cancleCropper(){
|
||||
this.cutPicuterModal = false
|
||||
this.option.img = ''
|
||||
this.$emit('closeCropper')
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.cut_pricture_modal{
|
||||
.header_right_block{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
right: 2.1rem;
|
||||
height: 100%;
|
||||
|
||||
.next_step_button{
|
||||
padding: 0 1.2rem;
|
||||
height: 3.2rem;
|
||||
background: linear-gradient(160deg, #AC2A3B, #292161);
|
||||
border-radius: 1.6rem;
|
||||
font-size: 1.4rem;
|
||||
color: #FFFFFF;
|
||||
line-height: 3.2rem;
|
||||
margin-right: 1.6rem;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.header_cancel_button{
|
||||
padding: 0 2.1rem;
|
||||
height: 3.2rem;
|
||||
background: #E4E5EB;
|
||||
border-radius: 1.6rem;
|
||||
font-size: 1.4rem;
|
||||
color: #030303;
|
||||
line-height: 3.2rem;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.collection_modal_body{
|
||||
height: 100%;
|
||||
padding: 1rem 2.5rem 1.4rem 1.4rem;
|
||||
box-sizing: border-box;
|
||||
background: #F2F3FB;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.cut_picture_left{
|
||||
width: 70.7rem;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
border-radius: 2rem;
|
||||
padding: 1.3rem 1.3rem 2rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
.cut_picture_body{
|
||||
width: 100%;
|
||||
height: 53rem;
|
||||
background: yellow;
|
||||
}
|
||||
|
||||
.cur_picture_opterate{
|
||||
margin: 2.7rem auto 0;
|
||||
border-radius: 1.6rem;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
border: 1px solid #E2E2E4;
|
||||
width: 24rem;
|
||||
|
||||
.cur_picture_opterate_item{
|
||||
width: 4.7rem;
|
||||
height: 4rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-right: 0.1rem solid #E6E8EA;
|
||||
cursor: pointer;
|
||||
|
||||
.icon_chexiao_sec{
|
||||
transform: rotateY(180deg); /* 垂直镜像翻转 */
|
||||
}
|
||||
|
||||
.operate_icon{
|
||||
font-size: 1.8rem;
|
||||
color: rgba(102, 102, 102, 1);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.icon_font{
|
||||
font-size: 2.5rem;
|
||||
position: relative;
|
||||
top: -0.3rem;
|
||||
user-select:none;
|
||||
}
|
||||
|
||||
.icon-shuaxin{
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
&:last-child{
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cut_picture_right{
|
||||
width: 39.2rem;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
border-radius: 2rem;
|
||||
|
||||
.cur_picture_right_header{
|
||||
padding: 2rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 1.6rem;
|
||||
font-weight: 400;
|
||||
color: #030303;
|
||||
line-height: 1.8rem;
|
||||
font-weight: bold;
|
||||
|
||||
.review_logo{
|
||||
font-size: 1.8rem;
|
||||
color: #333;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.cut_picture_review_block{
|
||||
width: 100%;
|
||||
padding: 0 2rem;
|
||||
height: calc(100% - 5.8rem);
|
||||
|
||||
.cut_picture_review_item{
|
||||
width: 100%;
|
||||
height: 50%;
|
||||
position: relative;
|
||||
|
||||
.cut_picture_review_content{
|
||||
transform-origin: 0 0;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: scale(0.45) translate(-50%, -50%);
|
||||
background: rgba(91,94,105,0.8);
|
||||
box-shadow: 0 0.2rem 0.5rem 0 rgba(216,213,239,0.3);
|
||||
border-radius: 1rem;
|
||||
}
|
||||
|
||||
.cut_picture_review_block_sec{
|
||||
transform-origin: 0 0;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: scale(0.45) translate(-50%, -50%);
|
||||
border-radius: 100%;
|
||||
background: rgba(91,94,105,0.8);
|
||||
box-shadow: 0 0.2rem 0.5rem 0 rgba(216,213,239,0.3);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
177
src/component/HomePage/ExportNewCoolection.vue
Normal file
@@ -0,0 +1,177 @@
|
||||
<template>
|
||||
<!-- 生成collention缩略图用的 -->
|
||||
<div class="export_new_collection_review">
|
||||
<div class="img_block_item" v-if="allBoardData?.moodTemplateId">
|
||||
<MoodTemplate :fileList="allBoardData?.moodboardFiles" :moodTemplateId="allBoardData?.moodTemplateId"></MoodTemplate>
|
||||
</div>
|
||||
<div class="img_block_item" v-else>
|
||||
<div class="lager_img_item" v-for="(mood) in allBoardData.moodboardFiles" :key="mood">
|
||||
<div class="all_img_item_block">
|
||||
<img class="all_img_content cover_img" :src="mood.imgUrl" >
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="img_block_item">
|
||||
<div class="small_img_item" v-for="(print) in allBoardData.printboardFiles" :key="print">
|
||||
<div class="all_img_item_block">
|
||||
<img class="all_img_content cover_img" :src="print.imgUrl">
|
||||
</div>
|
||||
</div>
|
||||
<div class="small_img_item" v-for="(generate) in allBoardData.generatePrintFiles" :key="generate">
|
||||
<div class="all_img_item_block">
|
||||
<img class="all_img_content cover_img" :src="generate.imgUrl">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="img_block_item">
|
||||
<div class="color_item" v-for="(color) in allBoardData.colorBoards" :key="color">
|
||||
<div class="color_content" :style="{background:`rgb(${color?.rgbValue?.r},${color?.rgbValue?.g},${color?.rgbValue?.b})`}"></div>
|
||||
<div class="color_content_body">
|
||||
<div class="color_des">{{color.tcx}}</div>
|
||||
<div class="color_des">{{color.name}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="img_block_item">
|
||||
<div class="lager_img_item" v-for="(skecth) in allBoardData.skecthboardFiles" :key="skecth">
|
||||
<div class="all_img_item_block">
|
||||
<img class="all_img_content" :src="skecth.imgUrl">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="img_block_item">
|
||||
<div class="lager_img_item" v-for="(marketing) in allBoardData.marketingSketchFiles" :key="marketing">
|
||||
<div class="all_img_item_block">
|
||||
<img class="all_img_content" :src="marketing.imgUrl">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="img_block_item">
|
||||
<div class="lager_img_item" v-for="(design) in likeDesignCollectionList" :key="design.designItemUrl">
|
||||
<div class="all_img_item_block">
|
||||
<img class="all_img_content" :src="design.designItemUrl">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent } from 'vue'
|
||||
import MoodTemplate from '@/component/HomePage/MoodTemplate.vue'
|
||||
import { useStore } from "vuex";
|
||||
export default defineComponent({
|
||||
components:{MoodTemplate},
|
||||
setup() {
|
||||
const store = useStore();
|
||||
let allBoardData:any = computed(()=>{return store.state.UploadFilesModule.allBoardData})
|
||||
let likeDesignCollectionList : any = computed(()=>{return store.state.HomeStoreModule.likeDesignCollectionList})
|
||||
return {
|
||||
allBoardData,
|
||||
likeDesignCollectionList,
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.export_new_collection_review{
|
||||
width: 40.8rem;
|
||||
background: #fff;
|
||||
position: fixed;
|
||||
left: -100rem;
|
||||
top: 0;
|
||||
|
||||
|
||||
.img_block_item{
|
||||
margin-bottom: 2rem;
|
||||
|
||||
// &.color_block_item{
|
||||
// padding: 0 0.5rem 0 0.3rem;
|
||||
// }
|
||||
|
||||
.lager_img_item{
|
||||
display: inline-block;
|
||||
width: 20.4rem;
|
||||
height: 20.4rem;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.sketch_img_item{
|
||||
display: inline-block;
|
||||
width: 20.4rem;
|
||||
height: 42.2rem;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.small_img_item{
|
||||
width: 6.8rem;
|
||||
height: 6.8rem;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
.color_item{
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
// padding: 0 0.5rem;
|
||||
margin-right: 1.6rem;
|
||||
margin-bottom: 0.5rem;
|
||||
|
||||
&:nth-child(4n){
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.color_content{
|
||||
width: 9rem;
|
||||
height:6.2rem
|
||||
}
|
||||
.color_content_body{
|
||||
width: 9rem;
|
||||
padding: 0.7rem 0.2rem;
|
||||
background: #FEFEFE;
|
||||
border: 1px solid #E6E6E6;
|
||||
|
||||
.color_des{
|
||||
font-size: 1rem;
|
||||
font-family: Roboto;
|
||||
font-weight: 500;
|
||||
color: #000000;
|
||||
margin-bottom: 0.5rem;
|
||||
line-height: 1.3rem;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
&:last-child{
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.all_img_item_block{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.all_img_content{
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
|
||||
&.cover_img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
486
src/component/HomePage/Header.vue
Normal file
@@ -0,0 +1,486 @@
|
||||
<template>
|
||||
<div>
|
||||
<header class="header_component">
|
||||
<img class="header_logo" @click="turnToNewPage('https://www.aidlab.hk/en/')" src="@/assets/images/loginPage/aida_logo.png" />
|
||||
<nav class="header_nav_content">
|
||||
<div :class="['nav_item', $route.name === 'home'?'select_nav':'']" @click="turnToPage('home')">HOME</div>
|
||||
<div :class="['nav_item', $route.name === 'library'?'select_nav':'']" @click="turnToPage('library')">LIBRARY</div>
|
||||
<div :class="['nav_item', $route.name === 'history'?'select_nav':'']" @click="turnToPage('history')">HISTORY</div>
|
||||
</nav>
|
||||
<div class="header_right_content">
|
||||
<div class="header_icon icon iconfont icon-touxiang3"></div>
|
||||
<div class="header_user_content">
|
||||
<div class="username">{{userInfo?.userName}}</div>
|
||||
<div :class="['icon','iconfont', 'icon-xiala', isShowOperate?'icon_rotate':'']" @click.stop="changeShowOperateContent()"></div>
|
||||
<nav class="select_block" v-show="isShowOperate">
|
||||
<!-- <div class="select_item" @click="showBindEmailModal()">
|
||||
<span class="icon iconfont icon-youxiang"></span><span class="select_item_des">bind email</span>
|
||||
</div> -->
|
||||
<div class="select_item" @click="logout()">
|
||||
<span class="icon iconfont icon-tuichu"></span><span class="select_item_des">log off</span>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<a-modal class="modal_component"
|
||||
v-model:visible="bindEmailVisible"
|
||||
:footer="null"
|
||||
title="Mailbox binding"
|
||||
width="56rem"
|
||||
:maskClosable="false"
|
||||
:centered="true"
|
||||
>
|
||||
<template #closeIcon v-if="!isHaveBindEmail && bindEmailStep === 1">
|
||||
<div class="skip_content">skip</div>
|
||||
</template>
|
||||
<div class="bind_email_content" v-if="isHaveBindEmail">
|
||||
<div class="bind_email_tip">you have binded email</div>
|
||||
<div class="bind_email">{{userInfo.email}}</div>
|
||||
</div>
|
||||
<div class="bind_email_content" v-else>
|
||||
<!-- 绑定邮箱第一步 start -->
|
||||
<div v-show="bindEmailStep === 1">
|
||||
<div class="bind_email_form_content">
|
||||
<div class="bind_email_form_title">Email</div>
|
||||
<input class="bind_email_form_input" placeholder="Enter a new email" v-model="email" @keydown.enter="emailNextStepFun()">
|
||||
</div>
|
||||
<div class="bind_email_submit_button" @click="emailNextStepFun()">Next step</div>
|
||||
</div>
|
||||
<!-- 绑定邮箱第一步 end -->
|
||||
|
||||
<!-- 绑定邮箱第二步 start -->
|
||||
<div v-show="bindEmailStep === 2">
|
||||
<div @click="emailLastStepFun()">
|
||||
<span class="icon iconfont icon--shangyibu"></span><span class="email_last_step_content">Enter verification code</span>
|
||||
</div>
|
||||
<div class="email_last_step_des">
|
||||
<div class="sent_email_content">Sent to {{email}}</div>
|
||||
<div class="tip_content">
|
||||
<span v-show="time">{{time}}s</span>
|
||||
<span v-show="!time" @click="emailNextStepFun()">Resend</span>
|
||||
</div>
|
||||
</div>
|
||||
<VerificationCodeInput :ct="emailCode" @sendCaptcha="submitBindEmail($event)"></VerificationCodeInput>
|
||||
</div>
|
||||
<!-- 绑定邮箱第一步 end -->
|
||||
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<script >
|
||||
import { defineComponent ,createVNode} from 'vue'
|
||||
import {isEmail} from '@/tool/util'
|
||||
import {setCookie, getCookie, WriteCookie} from '@/tool/cookie'
|
||||
import VerificationCodeInput from '@/component/LoginPage/verificationCodeInput.vue'
|
||||
import { Https } from "@/tool/https";
|
||||
import { Modal,message } from 'ant-design-vue';
|
||||
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
||||
export default defineComponent({
|
||||
components:{
|
||||
VerificationCodeInput,
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
isShowOperate:false,
|
||||
bindEmailVisible:false,
|
||||
isHaveBindEmail:false,
|
||||
bindEmailStep:1,
|
||||
email:'',
|
||||
emailCode:['','','','','',''],//邮箱验证码
|
||||
time:60,//60秒倒计时
|
||||
timer: 0,
|
||||
userInfo:{},
|
||||
timerOperate:null,
|
||||
numTime:30,
|
||||
timerSec:null,
|
||||
modalWarning:null
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
this.userInfo = JSON.parse(getCookie('userInfo'))
|
||||
if(!this.userInfo){
|
||||
this.$router.replace('/login')
|
||||
}else{
|
||||
this.accountIsLogin(this.userInfo)
|
||||
}
|
||||
this.isHaveBindEmail = this.userInfo?.email ? true : false
|
||||
|
||||
this.operateClick()
|
||||
document.addEventListener('click',this.operateClick)
|
||||
},
|
||||
methods:{
|
||||
turnToNewPage(url){
|
||||
window.open(url)
|
||||
},
|
||||
|
||||
turnToPage(name){
|
||||
let noRefresh = name === 'home' ? true :false
|
||||
this.$router.push({name:name,params: {noRefresh:noRefresh}})
|
||||
},
|
||||
|
||||
//点击下拉图标出现操作
|
||||
changeShowOperateContent(){
|
||||
this.isShowOperate = !this.isShowOperate
|
||||
document.addEventListener('click',this.closeShowOperateContent,false)
|
||||
},
|
||||
|
||||
//关闭下拉图标
|
||||
closeShowOperateContent(){
|
||||
this.isShowOperate = false
|
||||
document.removeEventListener('click',this.closeShowOperateContent)
|
||||
},
|
||||
|
||||
//打开绑定邮箱弹窗
|
||||
showBindEmailModal(){
|
||||
this.bindEmailVisible = true
|
||||
},
|
||||
|
||||
emailNextStepFun(){
|
||||
if(!isEmail(this.email)){
|
||||
message.error('The email format is incorrect');
|
||||
return
|
||||
}
|
||||
let data = {
|
||||
email:this.email,
|
||||
operationType: "BIND_MAILBOX",
|
||||
}
|
||||
const hide = message.loading('loading', 0);
|
||||
Https.axiosPost(Https.httpUrls.accountSendEmail, data).then((rv) =>{
|
||||
if(rv){
|
||||
this.bindEmailStep = 2
|
||||
this.emailCode = ['','','','','',''],
|
||||
this.createTimer()
|
||||
hide()
|
||||
message.success('Succeeded in binding the mailbox.')
|
||||
}
|
||||
}).catch(res=>{
|
||||
hide()
|
||||
})
|
||||
},
|
||||
|
||||
//绑定邮箱的上一步
|
||||
emailLastStepFun(){
|
||||
this.bindEmailStep = 1
|
||||
this.email = ''
|
||||
this.emailCode = ['','','','','',''],
|
||||
this.clearTimer()
|
||||
},
|
||||
|
||||
//创建定时器
|
||||
createTimer(){
|
||||
this.timer = setInterval(()=>{
|
||||
this.time--
|
||||
if(!this.time){
|
||||
clearInterval(this.timer)
|
||||
}
|
||||
},1000)
|
||||
},
|
||||
|
||||
//清除定时器
|
||||
clearTimer(){
|
||||
this.time = 60
|
||||
if(this.timer){
|
||||
clearInterval(this.timer)
|
||||
}
|
||||
},
|
||||
|
||||
//登出
|
||||
logout(){
|
||||
let data = {
|
||||
userId:this.userInfo.userId
|
||||
}
|
||||
Https.axiosPost(Https.httpUrls.accountLogout, data).then((rv) =>{
|
||||
this.$router.replace('/login')
|
||||
WriteCookie('token')
|
||||
})
|
||||
},
|
||||
|
||||
//绑定邮箱
|
||||
submitBindEmail(emailVerifyCode){
|
||||
let data = {
|
||||
userEmail:this.email,
|
||||
userId: this.userInfo.userId,
|
||||
emailVerifyCode:emailVerifyCode
|
||||
}
|
||||
Https.axiosPost(Https.httpUrls.accountBindEmail, data).then((rv) =>{
|
||||
if(rv){
|
||||
this.userInfo.email = this.email
|
||||
setCookie('userInfo',JSON.stringify(this.userInfo))
|
||||
this.bindEmailVisible = false,
|
||||
this.bindEmailStep = 1
|
||||
this.clearTimer()
|
||||
this.emailCode = ['','','','','','']
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
//判断是否登录
|
||||
accountIsLogin(userInfo){
|
||||
let data ={
|
||||
userId:userInfo.userId
|
||||
}
|
||||
Https.axiosPost(Https.httpUrls.accountIsLogin, data).then((rv) =>{
|
||||
if(!rv){
|
||||
this.$router.replace('/login')
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
//点击重置判断是否长时间五操作
|
||||
operateClick(){
|
||||
if(this.timer){
|
||||
clearTimeout(this.timer)
|
||||
}
|
||||
let _this = this
|
||||
let timeNum = 1000 * 60 *120
|
||||
this.timer = setTimeout(()=>{
|
||||
this.modalWarning = Modal.warning ({
|
||||
title: () => `You have not performed any operation for a long time. You must be active;otherwise, you will log out in ${_this.numTime} S`,
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
okText: 'Ok',
|
||||
onOk() {
|
||||
_this.numTime = 30
|
||||
clearInterval(_this.timerSec)
|
||||
}
|
||||
});
|
||||
_this.numCounter()
|
||||
},timeNum)
|
||||
},
|
||||
|
||||
numCounter(){
|
||||
this.timerSec = setInterval(()=>{
|
||||
if(this.numTime > 0){
|
||||
this.numTime = this.numTime - 1
|
||||
}else{
|
||||
clearTimeout(this.timer)
|
||||
clearInterval(this.timerSec)
|
||||
this.logout()
|
||||
this.modalWarning.destroy()
|
||||
}
|
||||
},1000)
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.header_component{
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 7rem;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
border-bottom: 0.1rem solid rgba(3,3,3,0.1);
|
||||
position: relative;
|
||||
|
||||
.header_logo{
|
||||
width: 14.4rem;
|
||||
height: 3.2rem;
|
||||
margin: 2.1rem 0 0 2.8rem;
|
||||
}
|
||||
|
||||
.header_nav_content{
|
||||
display: flex;
|
||||
margin-left: 28.9rem;
|
||||
align-items: center;
|
||||
|
||||
.nav_item{
|
||||
padding: 1.1rem 1rem;
|
||||
border-bottom: 0.1rem solid transparent;
|
||||
margin-right: 3.4rem;
|
||||
font-size: 1.6rem;
|
||||
line-height: 1.3rem;
|
||||
color: #333333;
|
||||
cursor: pointer;
|
||||
font-weight: 500;
|
||||
|
||||
&.select_nav{
|
||||
background: #E6E6F6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.header_right_content{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 3.2rem;
|
||||
display: flex;
|
||||
|
||||
.header_icon{
|
||||
font-size: 3.6rem;
|
||||
position: relative;
|
||||
top: 0.3rem;
|
||||
}
|
||||
|
||||
.header_user_content{
|
||||
margin-left: 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
top: 1.2rem;
|
||||
height: 3.7rem;
|
||||
|
||||
.username{
|
||||
font-size: 1.6rem;
|
||||
color: #1A1A1A;
|
||||
margin-right: 0.8rem;
|
||||
}
|
||||
|
||||
.icon-xiala{
|
||||
font-size: 1.4rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icon_rotate{
|
||||
-moz-transform:rotate(180deg);
|
||||
-webkit-transform:rotate(180deg);
|
||||
transform: rotate(180deg);
|
||||
animation-direction: 0.5s;
|
||||
}
|
||||
|
||||
.select_block{
|
||||
position: absolute;
|
||||
right: -1.5rem;
|
||||
top: 3.7rem;
|
||||
width: 11.4rem;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 0.4rem 0.4rem 0px rgba(0,0,0,0.1);
|
||||
z-index: 9;
|
||||
overflow: hidden;
|
||||
border: 1px solid #000000;
|
||||
|
||||
.select_item{
|
||||
padding-left: 1.5rem;
|
||||
height: 4.1rem;
|
||||
color: #4D4D4D;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
user-select:none;
|
||||
|
||||
&:hover{
|
||||
background: #F7F7F7;
|
||||
}
|
||||
|
||||
.iconfont{
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.select_item_des{
|
||||
font-size: 1.3rem;
|
||||
margin-left: 0.8rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.modal_component{
|
||||
|
||||
.skip_content{
|
||||
width: 6rem;
|
||||
height: 3rem;
|
||||
line-height: 2.8rem;
|
||||
border: 0.1rem solid #343579;
|
||||
font-size: 1.4rem;
|
||||
color: #343579;
|
||||
position: absolute;
|
||||
top: 1.8rem;
|
||||
right: 1.8rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.bind_email_content{
|
||||
padding: 4.8rem 9.2rem 6rem;
|
||||
|
||||
.bind_email_tip{
|
||||
font-size: 1.8rem;
|
||||
color: #A5B0C2;
|
||||
line-height: 1.9rem;
|
||||
text-align: center;
|
||||
}
|
||||
.bind_email{
|
||||
margin-top: 2rem;
|
||||
font-size: 2.2rem;
|
||||
font-weight: 400;
|
||||
color: #030303;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.bind_email_form_content{
|
||||
|
||||
.bind_email_form_title{
|
||||
font-size: 2.2rem;
|
||||
font-weight: bold;
|
||||
color: #030303;
|
||||
line-height: 2.4rem;
|
||||
}
|
||||
|
||||
.bind_email_form_input{
|
||||
width: 100%;
|
||||
height: 4.6rem;
|
||||
margin-top: 1rem;
|
||||
border: 0.1rem solid #B4BED7;
|
||||
padding-left: 2.1rem;
|
||||
line-height: 4.6rem;
|
||||
font-size: 1.8rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
&::placeholder {
|
||||
color:#A5B0C2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bind_email_submit_button{
|
||||
height: 4.6rem;
|
||||
line-height: 4.6rem;
|
||||
background: #343579;
|
||||
font-size: 1.6rem;
|
||||
font-weight: 500;
|
||||
color: #FFFFFF;
|
||||
width: 12.8rem;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
margin: 3rem auto 0;
|
||||
}
|
||||
|
||||
.icon--shangyibu{
|
||||
font-size: 2.5rem;
|
||||
font-weight: bold;
|
||||
color: #030303;
|
||||
}
|
||||
|
||||
.email_last_step_content{
|
||||
margin-left: 1rem;
|
||||
font-size: 2.2rem;
|
||||
font-family: PingFang SC;
|
||||
font-weight: bold;
|
||||
color: #030303;
|
||||
}
|
||||
|
||||
.tip_content{
|
||||
font-size: 1.3rem;
|
||||
font-weight: bold;
|
||||
color: #343579;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.email_last_step_des{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 2.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
|
||||
.sent_email_content{
|
||||
font-size: 1.8rem;
|
||||
font-weight: bold;
|
||||
color: #A5B0C2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
272
src/component/HomePage/MarketingSketchUpload.vue
Normal file
@@ -0,0 +1,272 @@
|
||||
<template>
|
||||
<div class="collection_modal_item">
|
||||
<div class="switch_type_list">
|
||||
<div class="switch_type_item select_swtich">
|
||||
<span>Upload</span>
|
||||
</div>
|
||||
<div @click="openLibrary()" class="switch_type_item">
|
||||
<span>My Library</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="marketingUpload_body" v-show="swtich_type==='upload'">
|
||||
<div class="upload_img_body scroll_style">
|
||||
<div class="upload_item">
|
||||
<div class="upload_file_item" v-for="(file, index) in fileList" :key="file">
|
||||
<div class="upload_file_item_content" v-show="file?.status === 'uploading'">
|
||||
<a-spin :indicator="indicator" tip="Uploading..."/>
|
||||
</div>
|
||||
<div class="upload_file_item_content" v-show="file?.status === 'done'">
|
||||
<img :src="file?.imgUrl" class="upload_img">
|
||||
<div class="delete_file_block" @click="deleteFile(index)">Delete</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="upload_file_item upload_component" v-show="fileList.length < 15">
|
||||
<a-upload
|
||||
:action="uploadUrl + '/api/element/upload'"
|
||||
list-type="picture-card"
|
||||
:data="{
|
||||
...upload
|
||||
}"
|
||||
:before-upload="beforeUpload"
|
||||
:headers="{Authorization:token}"
|
||||
v-model:file-list="fileList"
|
||||
multiple
|
||||
:maxCount="15"
|
||||
accept=".jpg,.png,.jpeg,.bmp"
|
||||
@change="(file)=>fileUploadChange(file)"
|
||||
>
|
||||
<div class="upload_tip_block" v-show="fileList.length < 15">
|
||||
<img class="upload_img_icon" src="@/assets/images/homePage/add_file.png">
|
||||
</div>
|
||||
</a-upload>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="upload_max_tip">
|
||||
<span class="icon iconfont icon-zhuyi"></span>
|
||||
<span>Maximum 15 images can be uploaded, Maximum 2M per image</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Material ref="Material" @confirmSelect="confirmSelect"></Material>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, h,ref } from 'vue'
|
||||
import { LoadingOutlined } from '@ant-design/icons-vue';
|
||||
import {getCookie} from '@/tool/cookie'
|
||||
import {getUploadUrl} from '@/tool/util'
|
||||
import {useStore} from 'vuex'
|
||||
import { message,Upload} from 'ant-design-vue';
|
||||
import Material from '@/component/HomePage/Material.vue'
|
||||
export default defineComponent({
|
||||
components:{Material},
|
||||
setup(){
|
||||
let fileList:any = ref([])
|
||||
return {
|
||||
fileList
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
swtich_type:'upload',
|
||||
indicator : h(LoadingOutlined, {
|
||||
style: {
|
||||
fontSize: '2.4rem',
|
||||
},
|
||||
spin: true,
|
||||
}),
|
||||
upload:{
|
||||
isPin:0,
|
||||
level1Type:'MarketingSketch',
|
||||
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
},
|
||||
token:'',
|
||||
uploadUrl:'',
|
||||
store:useStore()
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
this.token = getCookie('token') || ''
|
||||
this.uploadUrl = getUploadUrl()
|
||||
},
|
||||
methods:{
|
||||
openLibrary(){
|
||||
let material:any = this.$refs.Material
|
||||
material.init('MarketingSketch')
|
||||
},
|
||||
fileUploadChange(data:any){
|
||||
let file = data.file
|
||||
if(file.status === 'done'){
|
||||
let res = JSON.parse(file.xhr.response)
|
||||
file.imgUrl = res.data.url
|
||||
file.resData = res.data
|
||||
let fileList = this.fileList.filter((v:any)=> v.status === 'done')
|
||||
this.store.commit('setMarketingSketchFile',fileList)
|
||||
}else if(file.status === 'error'){
|
||||
let index = -1
|
||||
this.fileList.forEach((ele:any,index1:any) => {
|
||||
if(file.uid === ele.uid){
|
||||
index = index1
|
||||
}
|
||||
});
|
||||
if(index > -1){
|
||||
this.fileList.splice(index, 1)
|
||||
}
|
||||
message.error(file.name + 'upload failed')
|
||||
}
|
||||
},
|
||||
|
||||
beforeUpload(file:any){
|
||||
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg' || file.type === 'image/bmp';
|
||||
if (!isJpgOrPng) {
|
||||
message.error('You can only upload Image file!');
|
||||
}
|
||||
const isLt2M = file.size / 1024 / 1024 < 2;
|
||||
if (!isLt2M) {
|
||||
message.error('Image must smaller than 5MB!');
|
||||
}
|
||||
return (isJpgOrPng && isLt2M) || Upload.LIST_IGNORE;
|
||||
},
|
||||
|
||||
deleteFile(index:any){
|
||||
this.fileList.splice(index, 1)
|
||||
this.store.commit('setMarketingSketchFile',this.fileList)
|
||||
},
|
||||
|
||||
recollection(){
|
||||
this.fileList = JSON.parse(JSON.stringify(this.store.state.UploadFilesModule.allBoardData.marketingSketchFiles))
|
||||
this.store.commit('setMarketingSketchFile',this.fileList)
|
||||
},
|
||||
|
||||
confirmSelect(event:any){
|
||||
for(let item of event){
|
||||
let data = {
|
||||
imgUrl:item.url,
|
||||
resData:item,
|
||||
status:'done',
|
||||
}
|
||||
if(this.fileList.length == 15){
|
||||
message.error('Maximum number of allowable file uploads has been exceeded')
|
||||
break
|
||||
}
|
||||
this.fileList.push(data)
|
||||
}
|
||||
this.store.commit('setMarketingSketchFile',this.fileList)
|
||||
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.collection_modal_item{
|
||||
padding: 1.5rem 2.6rem 4rem;
|
||||
height: 100%;
|
||||
|
||||
.switch_type_list{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.switch_type_item{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 2rem;
|
||||
height: 4rem;
|
||||
background: #fff;
|
||||
border-radius: 0.8rem;
|
||||
line-height: 4rem;
|
||||
font-size: 1.6rem;
|
||||
margin-right: 2.2rem;
|
||||
color: #5B5E69;
|
||||
cursor: pointer;
|
||||
|
||||
&.select_swtich{
|
||||
color: #343579;
|
||||
}
|
||||
|
||||
.switch_icon{
|
||||
font-size: 1.8rem;
|
||||
margin-right: 0.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.marketingUpload_body{
|
||||
margin-top: 1rem;
|
||||
height: calc(100% - 5rem);
|
||||
|
||||
.upload_img_body{
|
||||
height: calc(100% - 3rem);
|
||||
overflow-y: auto;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.upload_file_item{
|
||||
margin: 0 2rem 2rem 0;
|
||||
display: inline-block;
|
||||
width: 16.5rem;
|
||||
height: 16.5rem;
|
||||
border: 1px solid #F5F5F5;
|
||||
vertical-align: top;
|
||||
|
||||
&.upload_component{
|
||||
border: none;
|
||||
}
|
||||
|
||||
.upload_file_item_content{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
|
||||
&:hover .delete_file_block{
|
||||
display: block;
|
||||
}
|
||||
|
||||
.upload_img{
|
||||
display: block;
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.delete_file_block{
|
||||
display: none;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
height: 4rem;
|
||||
background: rgba(0,0,0,0.2);
|
||||
font-size: 1.6rem;
|
||||
color: #FFFFFF;
|
||||
line-height: 4rem;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.upload_img_icon{
|
||||
width: 4.6rem;
|
||||
}
|
||||
}
|
||||
|
||||
.upload_max_tip{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.4rem;
|
||||
color: #030303;
|
||||
|
||||
.icon-zhuyi{
|
||||
font-size: 1.6rem;
|
||||
margin-right: 0.7rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
470
src/component/HomePage/Material.vue
Normal file
@@ -0,0 +1,470 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-modal class="my_material_modal"
|
||||
v-model:visible="myMaterialModalShow"
|
||||
:footer="null"
|
||||
width="80%"
|
||||
:maskClosable="false"
|
||||
:centered="true"
|
||||
>
|
||||
<div class="my_material_header">
|
||||
<div class="my_material_title">My Library</div>
|
||||
<div class="my_material_header_right">
|
||||
<div class="content_search_block">
|
||||
<input class="search_input" placeholder="Please input" v-model="searchPictureName" @keydown.enter="getLibraryList()">
|
||||
<div class="search_icon_block" @click="getLibraryList()"><span class="icon iconfont icon-sousuo"></span></div>
|
||||
</div>
|
||||
|
||||
<div class="icon iconfont icon-guanbi icon_close" @click="closeModal"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="my_material_content">
|
||||
<div class="material_content_top">
|
||||
<div class="material_content_top_title"></div>
|
||||
<div class="material_content_top_right">
|
||||
<div class="select_block" v-show="selectCode == 'Sketchboard' || selectCode == 'MarketingSketch'">
|
||||
<a-select
|
||||
ref="select"
|
||||
v-model:value="designType"
|
||||
:options="disignTypeList"
|
||||
placeholder="All"
|
||||
:allowClear="true"
|
||||
@change="handleChange"
|
||||
>
|
||||
<template #suffixIcon
|
||||
><span
|
||||
class="icon iconfont icon-xiala"
|
||||
style="color: #343579"
|
||||
></span
|
||||
></template>
|
||||
</a-select>
|
||||
</div>
|
||||
<div :class="['check_all_block',selectImgList.length == imgList.length ? 'check_all' : '']" @click="selectAllImg()" v-show="imgList.length">
|
||||
<div class="check_block"><div class="check_block_body" v-show="selectImgList.length == imgList.length && imgList.length"></div></div>
|
||||
<div>all</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="material_content_body scroll_style">
|
||||
<div class="content_img_item" v-for="(img) in imgList" :key="img.id" @click="selectImgItem(img)">
|
||||
<div :class="['content_img_item_block', selectImgListIds.indexOf(img.id) > -1 ? 'select_item_img' :'']">
|
||||
<img :class="[selectCode == 'Moodboard' || selectCode == 'Printboard' ? 'print_content_img' : 'content_img']" v-lazy="img.url" :key="img.url"/>
|
||||
</div>
|
||||
<div class="content_img_name">{{img.name}}</div>
|
||||
</div>
|
||||
<div class="no_data_block" v-show="!imgList.length && !isShowLoading">
|
||||
<img src="@/assets/images/homePage/null_img.png">
|
||||
</div>
|
||||
</div>
|
||||
<div class="no_data_block loading_block" v-show="isShowLoading">
|
||||
<a-spin size="large"></a-spin>
|
||||
</div>
|
||||
<div class="material_confirm" @click="confirmSelect()" v-show="imgList.length">Confirm</div>
|
||||
<div class="table_pagination" v-show="imgList.length">
|
||||
<a-pagination
|
||||
|
||||
v-model:current="currentPage"
|
||||
v-model:pageSize="pageSize"
|
||||
:total="total"
|
||||
:showSizeChanger="false"
|
||||
:showQuickJumper="true"
|
||||
@change="changePage"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref} from 'vue'
|
||||
import { Https } from "@/tool/https";
|
||||
import { message } from 'ant-design-vue';
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
let myMaterialModalShow = ref(false)
|
||||
let imgList = ref([])
|
||||
let selectImgList:any = ref([])
|
||||
let selectImgListIds:any = ref([])
|
||||
let isShowLoading:any = ref(false)
|
||||
let selectCode:any = ref('')
|
||||
let currentPage:any = ref(1)
|
||||
let searchPictureName = ref('')
|
||||
let pageSize = ref(20)
|
||||
let total = ref(0)
|
||||
let searcMaterialhName:any = ref('') //搜索名字
|
||||
let designType:any = ref(null)
|
||||
let disignTypeList = [
|
||||
{
|
||||
value: "Outwear",
|
||||
label: "Outwear",
|
||||
},
|
||||
{
|
||||
value: "Blouse",
|
||||
label: "Blouse",
|
||||
},
|
||||
{
|
||||
value: "Dress",
|
||||
label: "Dress",
|
||||
},
|
||||
{
|
||||
value: "Trousers",
|
||||
label: "Trousers",
|
||||
},
|
||||
{
|
||||
value: "Skirt",
|
||||
label: "Skirt",
|
||||
},
|
||||
]
|
||||
let boardList = {
|
||||
Moodboard:'Mood',
|
||||
Printboard:'Print',
|
||||
Sketchboard:'Sketch',
|
||||
MarketingSketch:'MarketingSketch'
|
||||
}
|
||||
return{
|
||||
myMaterialModalShow,
|
||||
imgList,
|
||||
selectImgList,
|
||||
selectImgListIds,
|
||||
isShowLoading,
|
||||
selectCode,
|
||||
currentPage,
|
||||
searchPictureName,
|
||||
pageSize,
|
||||
total,
|
||||
searcMaterialhName,
|
||||
designType,
|
||||
disignTypeList,
|
||||
boardList
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
|
||||
init(code:any){
|
||||
this.selectCode = code
|
||||
this.myMaterialModalShow = true
|
||||
this.getLibraryList()
|
||||
},
|
||||
|
||||
selectImgItem(imgData:any){
|
||||
this.selectImgListIds = this.selectImgList.map((v:any)=>v.id)
|
||||
if(this.selectImgListIds.indexOf(imgData.id) === -1){
|
||||
this.selectImgList.push(imgData)
|
||||
this.selectImgListIds.push(imgData.id)
|
||||
}else{
|
||||
let index = this.selectImgListIds.indexOf(imgData.id)
|
||||
this.selectImgList.splice(index,1)
|
||||
this.selectImgListIds.splice(index,1)
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
//改变页码
|
||||
changePage(current: number, pageSize: number){
|
||||
this.currentPage = current
|
||||
this.pageSize = pageSize
|
||||
this.getLibraryList()
|
||||
},
|
||||
|
||||
handleChange(){
|
||||
this.getLibraryList()
|
||||
},
|
||||
|
||||
//选择所有的图片
|
||||
selectAllImg(){
|
||||
if(this.selectImgListIds.length == this.imgList.length){
|
||||
this.selectImgListIds = []
|
||||
this.selectImgList = []
|
||||
}else{
|
||||
this.selectImgListIds = this.imgList.map((v:any) => v.id)
|
||||
this.selectImgList = this.imgList
|
||||
}
|
||||
},
|
||||
|
||||
getLibraryList(){
|
||||
let data = {
|
||||
level1Type:this.selectCode,
|
||||
level2Type:this.designType,
|
||||
page:this.currentPage,
|
||||
pictureName:this.searchPictureName,
|
||||
size:this.pageSize,
|
||||
}
|
||||
this.isShowLoading = true
|
||||
Https.axiosPost(Https.httpUrls.queryLibraryPage,data).then(
|
||||
(rv: any) => {
|
||||
this.imgList = rv.content
|
||||
this.total = rv.total
|
||||
this.isShowLoading = false
|
||||
}
|
||||
).catch((res)=>{
|
||||
this.isShowLoading = false
|
||||
});
|
||||
},
|
||||
|
||||
confirmSelect(){
|
||||
if(!this.selectImgList.length){
|
||||
message.error('Please select at least one image')
|
||||
return
|
||||
}
|
||||
this.$emit('confirmSelect',this.selectImgList)
|
||||
this.closeModal()
|
||||
},
|
||||
|
||||
closeModal(){
|
||||
this.myMaterialModalShow = false
|
||||
this.searchPictureName = ''
|
||||
this.designType = null
|
||||
this.selectImgList = []
|
||||
this.selectImgListIds = []
|
||||
this.imgList = []
|
||||
this.currentPage = 1
|
||||
this.pageSize = 10
|
||||
this.total = 0
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="less">
|
||||
.my_material_modal{
|
||||
|
||||
.ant-modal-close{
|
||||
width: 3.6rem;
|
||||
height: 3.6rem;
|
||||
position: absolute;
|
||||
top: -1.8rem;
|
||||
right: -1.8rem;
|
||||
}
|
||||
|
||||
.ant-modal-header{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ant-modal-body{
|
||||
background: #F2F3FB;
|
||||
height: 80vh;
|
||||
min-height: 72rem;
|
||||
overflow-y: hidden;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.my_material_header{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 6.6rem;
|
||||
background: #F7F7F7;
|
||||
padding: 0 3.4rem 0 3.1rem;
|
||||
|
||||
.my_material_title{
|
||||
font-size: 1.8rem;
|
||||
color: #030303;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.my_material_header_right{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.content_search_block{
|
||||
margin-right: 5rem;
|
||||
display: flex;
|
||||
|
||||
.search_input{
|
||||
width: 30rem;
|
||||
padding-left: 1.5rem;
|
||||
height: 4rem;
|
||||
line-height: 3.8rem;
|
||||
background: #FFFFFF;
|
||||
border: 0.1rem solid #F1F1F1;
|
||||
font-size: 1.6rem;
|
||||
font-weight: 400;
|
||||
|
||||
&::placeholder {
|
||||
color: #C2C2C2;
|
||||
}
|
||||
}
|
||||
|
||||
.search_icon_block{
|
||||
width: 6rem;
|
||||
height: 4rem;
|
||||
line-height: 4rem;
|
||||
text-align: center;
|
||||
background: #343579;
|
||||
cursor: pointer;
|
||||
|
||||
.icon-sousuo{
|
||||
font-size: 2rem;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon_close{
|
||||
color: rgba(174, 178, 183, 1);
|
||||
font-size: 2.4rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
.my_material_content{
|
||||
padding: 0 3rem 3.5rem 3rem;
|
||||
height: calc(100% - 6.6rem);
|
||||
position: relative;
|
||||
|
||||
.material_content_top{
|
||||
padding: 1.3rem 0 2.1rem;
|
||||
height: 7rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
|
||||
.material_content_top_title{
|
||||
font-size: 20px;
|
||||
color: #030303;
|
||||
}
|
||||
|
||||
.material_content_top_right{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.select_block{
|
||||
background: #FFFFFF;
|
||||
color: #1A1A1A !important;
|
||||
margin-right: 2.3rem;
|
||||
|
||||
.icon-xiala{
|
||||
color: #1A1A1A !important;
|
||||
}
|
||||
}
|
||||
|
||||
.check_all_block{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 1.6rem;
|
||||
color: #64686D;
|
||||
cursor: pointer;
|
||||
|
||||
&.check_all{
|
||||
color: #1A1A1A;
|
||||
}
|
||||
|
||||
.check_block{
|
||||
width: 2.4rem;
|
||||
height: 2.4rem;
|
||||
background: #EBECF4;
|
||||
border: 0.1rem solid #64686D;
|
||||
padding: 0.3rem;
|
||||
margin-right: 0.7rem;
|
||||
|
||||
.check_block_body{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #343579;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.material_content_body{
|
||||
width: 100%;
|
||||
height: calc(100% - 19rem);
|
||||
overflow-y: auto;
|
||||
position: relative;
|
||||
|
||||
.content_img_item{
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
padding: 0 1.4rem;
|
||||
margin-bottom: 2.8rem;
|
||||
|
||||
.content_img_item_block{
|
||||
border: 0.1rem solid transparent;
|
||||
width: 16.5rem;
|
||||
height: 16.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
|
||||
&.select_item_img{
|
||||
border-color: #343579;
|
||||
}
|
||||
|
||||
.print_content_img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.content_img{
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
}
|
||||
.content_img_name{
|
||||
width: 16.5rem;
|
||||
height: 3.5rem;
|
||||
line-height: 3.5rem;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 1.4rem;
|
||||
color: #030303;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
.no_data_block{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 99;
|
||||
|
||||
&.loading_block{
|
||||
background: rgba(0,0,0,0.2);
|
||||
}
|
||||
}
|
||||
|
||||
.material_confirm{
|
||||
width: 9.8rem;
|
||||
height: 3.6rem;
|
||||
line-height: 3.6rem;
|
||||
font-size: 1.4rem;
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
color: #FFFFFF;
|
||||
background: #343579;
|
||||
cursor: pointer;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.table_pagination{
|
||||
position: absolute;
|
||||
bottom: 3.5rem;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin-top: 5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
446
src/component/HomePage/MoodTemplate.vue
Normal file
@@ -0,0 +1,446 @@
|
||||
<template>
|
||||
<div class="mood_template_component">
|
||||
<div class="mood_template_item template_three" v-show="moodTemplateId == 3">
|
||||
<div class="img_template three_1" :style="{backgroundImage:`url(${fileList[0]?.imgUrl})`}"></div>
|
||||
<div class="img_template three_2" :style="{backgroundImage:`url(${fileList[1]?.imgUrl})`}"></div>
|
||||
<div class="img_template three_1" :style="{backgroundImage:`url(${fileList[2]?.imgUrl})`}"></div>
|
||||
</div>
|
||||
<div class="mood_template_item template_four" v-show="moodTemplateId == 4">
|
||||
<div class="img_template four_1" :style="{backgroundImage:`url(${fileList[0]?.imgUrl})`}"></div>
|
||||
<div class="img_template four_2" :style="{backgroundImage:`url(${fileList[1]?.imgUrl})`}"></div>
|
||||
<div class="img_template four_3" :style="{backgroundImage:`url(${fileList[2]?.imgUrl})`}"></div>
|
||||
<div class="img_template four_4" :style="{backgroundImage:`url(${fileList[3]?.imgUrl})`}"></div>
|
||||
</div>
|
||||
<div class="mood_template_item template_five" v-show="moodTemplateId == 5">
|
||||
<div class="img_template five_1" :style="{backgroundImage:`url(${fileList[0]?.imgUrl})`}"></div>
|
||||
<div class="img_template five_2" :style="{backgroundImage:`url(${fileList[1]?.imgUrl})`}"></div>
|
||||
<div class="img_template five_3" :style="{backgroundImage:`url(${fileList[2]?.imgUrl})`}"></div>
|
||||
<div class="img_template five_4" :style="{backgroundImage:`url(${fileList[3]?.imgUrl})`}"></div>
|
||||
<div class="img_template five_5" :style="{backgroundImage:`url(${fileList[4]?.imgUrl})`}"></div>
|
||||
</div>
|
||||
<div class="mood_template_item template_six" v-show="moodTemplateId == 6">
|
||||
<div class="img_template six_1" :style="{backgroundImage:`url(${fileList[0]?.imgUrl})`}"></div>
|
||||
<div class="img_template six_2" :style="{backgroundImage:`url(${fileList[1]?.imgUrl})`}"></div>
|
||||
<div class="img_template six_3" :style="{backgroundImage:`url(${fileList[2]?.imgUrl})`}"></div>
|
||||
<div class="img_template six_4" :style="{backgroundImage:`url(${fileList[3]?.imgUrl})`}"></div>
|
||||
<div class="img_template six_5" :style="{backgroundImage:`url(${fileList[4]?.imgUrl})`}"></div>
|
||||
<div class="img_template six_6" :style="{backgroundImage:`url(${fileList[5]?.imgUrl})`}"></div>
|
||||
</div>
|
||||
<div class="mood_template_item template_seven" v-show="moodTemplateId == 7">
|
||||
<div class="img_template seven_1" :style="{backgroundImage:`url(${fileList[0]?.imgUrl})`}"></div>
|
||||
<div class="img_template seven_2" :style="{backgroundImage:`url(${fileList[1]?.imgUrl})`}"></div>
|
||||
<div class="img_template seven_3" :style="{backgroundImage:`url(${fileList[2]?.imgUrl})`}"></div>
|
||||
<div class="img_template seven_4" :style="{backgroundImage:`url(${fileList[3]?.imgUrl})`}"></div>
|
||||
<div class="img_template seven_5" :style="{backgroundImage:`url(${fileList[4]?.imgUrl})`}"></div>
|
||||
<div class="img_template seven_6" :style="{backgroundImage:`url(${fileList[5]?.imgUrl})`}"></div>
|
||||
<div class="img_template seven_7" :style="{backgroundImage:`url(${fileList[6]?.imgUrl})`}"></div>
|
||||
</div>
|
||||
<div class="mood_template_item template_eight" v-show="moodTemplateId == 8">
|
||||
<div class="img_template eight_1" :style="{backgroundImage:`url(${fileList[0]?.imgUrl})`}"></div>
|
||||
<div class="img_template eight_2" :style="{backgroundImage:`url(${fileList[1]?.imgUrl})`}"></div>
|
||||
<div class="img_template eight_3" :style="{backgroundImage:`url(${fileList[2]?.imgUrl})`}"></div>
|
||||
<div class="img_template eight_4" :style="{backgroundImage:`url(${fileList[3]?.imgUrl})`}"></div>
|
||||
<div class="img_template eight_5" :style="{backgroundImage:`url(${fileList[4]?.imgUrl})`}"></div>
|
||||
<div class="img_template eight_6" :style="{backgroundImage:`url(${fileList[5]?.imgUrl})`}"></div>
|
||||
<div class="img_template eight_7" :style="{backgroundImage:`url(${fileList[6]?.imgUrl})`}"></div>
|
||||
<div class="img_template eight_8" :style="{backgroundImage:`url(${fileList[7]?.imgUrl})`}"></div>
|
||||
</div>
|
||||
<div class="mood_template_item template_nine" v-show="moodTemplateId == 9">
|
||||
<div class="img_template nine_1" :style="{backgroundImage:`url(${fileList[0]?.imgUrl})`}"></div>
|
||||
<div class="img_template nine_2" :style="{backgroundImage:`url(${fileList[1]?.imgUrl})`}"></div>
|
||||
<div class="img_template nine_3" :style="{backgroundImage:`url(${fileList[2]?.imgUrl})`}"></div>
|
||||
<div class="img_template nine_4" :style="{backgroundImage:`url(${fileList[3]?.imgUrl})`}"></div>
|
||||
<div class="img_template nine_5" :style="{backgroundImage:`url(${fileList[4]?.imgUrl})`}"></div>
|
||||
<div class="img_template nine_6" :style="{backgroundImage:`url(${fileList[5]?.imgUrl})`}"></div>
|
||||
<div class="img_template nine_7" :style="{backgroundImage:`url(${fileList[6]?.imgUrl})`}"></div>
|
||||
<div class="img_template nine_8" :style="{backgroundImage:`url(${fileList[7]?.imgUrl})`}"></div>
|
||||
<div class="img_template nine_9" :style="{backgroundImage:`url(${fileList[8]?.imgUrl})`}"></div>
|
||||
</div>
|
||||
<div class="mood_template_item template_ten" v-show="moodTemplateId == 10">
|
||||
<div class="img_template ten_1" :style="{backgroundImage:`url(${fileList[0]?.imgUrl})`}"></div>
|
||||
<div class="img_template ten_2" :style="{backgroundImage:`url(${fileList[1]?.imgUrl})`}"></div>
|
||||
<div class="img_template ten_3" :style="{backgroundImage:`url(${fileList[2]?.imgUrl})`}"></div>
|
||||
<div class="img_template ten_4" :style="{backgroundImage:`url(${fileList[3]?.imgUrl})`}"></div>
|
||||
<div class="img_template ten_5" :style="{backgroundImage:`url(${fileList[4]?.imgUrl})`}"></div>
|
||||
<div class="img_template ten_6" :style="{backgroundImage:`url(${fileList[5]?.imgUrl})`}"></div>
|
||||
<div class="img_template ten_7" :style="{backgroundImage:`url(${fileList[6]?.imgUrl})`}"></div>
|
||||
<div class="img_template ten_8" :style="{backgroundImage:`url(${fileList[7]?.imgUrl})`}"></div>
|
||||
<div class="img_template ten_9" :style="{backgroundImage:`url(${fileList[8]?.imgUrl})`}"></div>
|
||||
<div class="img_template ten_10" :style="{backgroundImage:`url(${fileList[9]?.imgUrl})`}"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
props:['fileList','moodTemplateId'],
|
||||
setup() {
|
||||
|
||||
},
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.mood_template_component{
|
||||
width: 40.8rem;
|
||||
background: #fff;
|
||||
|
||||
.mood_template_item{
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
.template_three{
|
||||
height: 18.7rem;
|
||||
display: flex;
|
||||
|
||||
.img_template{
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.three_1{
|
||||
width: 10.2rem;
|
||||
height: 100%;
|
||||
}
|
||||
.three_2{
|
||||
width: 19.6rem;
|
||||
margin: 0 0.4rem;
|
||||
}
|
||||
}
|
||||
|
||||
.template_four{
|
||||
height: 21.1rem;
|
||||
|
||||
.four_1{
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 20.1rem;
|
||||
height: 10.7rem;
|
||||
}
|
||||
|
||||
.four_2{
|
||||
left: 0;
|
||||
top: 11.1rem;
|
||||
width: 9.6rem;
|
||||
height: 10rem;
|
||||
}
|
||||
.four_3{
|
||||
left: 9.9rem;
|
||||
top: 11.1rem;
|
||||
width: 10.2rem;
|
||||
height: 10rem;
|
||||
}
|
||||
.four_4{
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 20.1rem;
|
||||
height: 21.1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.template_five{
|
||||
height: 24.2rem;
|
||||
|
||||
.five_1{
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 15.2rem;
|
||||
height: 15.3rem;
|
||||
}
|
||||
.five_2{
|
||||
left: 0;
|
||||
top: 15.3rem;
|
||||
width: 15.2rem;
|
||||
height: 8.7rem;
|
||||
}
|
||||
.five_3{
|
||||
left: 15.2rem;
|
||||
top: 0;
|
||||
width: 14.5rem;
|
||||
height: 24rem;
|
||||
}
|
||||
.five_4{
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 11.1rem;
|
||||
height: 12rem;
|
||||
}
|
||||
.five_5{
|
||||
right: 0;
|
||||
top: 12rem;
|
||||
width: 11.1rem;
|
||||
height: 12rem;
|
||||
}
|
||||
}
|
||||
|
||||
.template_six{
|
||||
height: 27.4rem;
|
||||
|
||||
.six_1{
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 13.4rem;
|
||||
height: 13.8rem;
|
||||
}
|
||||
.six_2{
|
||||
left: 0;
|
||||
top: 13.8rem;
|
||||
width: 14.3rem;
|
||||
height: 13.6rem;
|
||||
}
|
||||
.six_3{
|
||||
left: 13.4rem;
|
||||
top: 0;
|
||||
width: 13.9rem;
|
||||
height: 13.8rem;
|
||||
}
|
||||
.six_4{
|
||||
left: 14.3rem;
|
||||
top: 13.8rem;
|
||||
width: 18.6rem;
|
||||
height: 13.6rem;
|
||||
}
|
||||
.six_5{
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 13.5rem;
|
||||
height: 13.8rem;
|
||||
}
|
||||
.six_6{
|
||||
right: 0;
|
||||
top: 13.8rem;
|
||||
width: 7.9rem;
|
||||
height: 13.6rem;
|
||||
}
|
||||
}
|
||||
|
||||
.template_seven{
|
||||
height: 21rem;
|
||||
|
||||
.seven_1{
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 7.3rem;
|
||||
height: 7.6rem;
|
||||
}
|
||||
.seven_2{
|
||||
left: 0;
|
||||
top: 7.5rem;
|
||||
width: 7.3rem;
|
||||
height: 13.2rem;
|
||||
}
|
||||
.seven_3{
|
||||
left: 7.5rem;
|
||||
top: 0;
|
||||
width: 12.1rem;
|
||||
height: 11.7rem;
|
||||
}
|
||||
.seven_4{
|
||||
left: 7.5rem;
|
||||
top: 11.9rem;
|
||||
width: 12.1rem;
|
||||
height: 9.1rem;
|
||||
}
|
||||
.seven_5{
|
||||
left: 19.7rem;
|
||||
top: 0;
|
||||
width: 10.4rem;
|
||||
height: 10.1rem;
|
||||
}
|
||||
.seven_6{
|
||||
left: 19.7rem;
|
||||
top: 10.3rem;
|
||||
width: 10.4rem;
|
||||
height: 10.7rem;
|
||||
}
|
||||
.seven_7{
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 10.6rem;
|
||||
height: 21rem;
|
||||
}
|
||||
}
|
||||
|
||||
.template_eight{
|
||||
height: 24.9rem;
|
||||
|
||||
.eight_1{
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 8.5rem;
|
||||
height: 9.1rem;
|
||||
}
|
||||
.eight_2{
|
||||
left: 0;
|
||||
top: 9.3rem;
|
||||
width: 8.5rem;
|
||||
height: 15.5rem;
|
||||
}
|
||||
.eight_3{
|
||||
left: 8.7rem;
|
||||
top: 0;
|
||||
width: 13.8rem;
|
||||
height: 13.8rem;
|
||||
}
|
||||
.eight_4{
|
||||
left: 8.7rem;
|
||||
top: 14rem;
|
||||
width: 10.9rem;
|
||||
height: 10.8rem;
|
||||
}
|
||||
.eight_5{
|
||||
left: 19.8rem;
|
||||
top: 14rem;
|
||||
width: 4.9rem;
|
||||
height: 10.8rem;
|
||||
}
|
||||
.eight_6{
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 18.1rem;
|
||||
height: 13.8rem;
|
||||
}
|
||||
.eight_7{
|
||||
left: 24.9rem;
|
||||
top: 14rem;
|
||||
width: 10.5rem;
|
||||
height: 10.8rem;
|
||||
}
|
||||
.eight_8{
|
||||
right: 0;
|
||||
top: 14rem;
|
||||
width: 5.2rem;
|
||||
height: 10.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
.template_nine{
|
||||
height: 19.3rem;
|
||||
|
||||
.nine_1{
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 6rem;
|
||||
height: 6.4rem;
|
||||
}
|
||||
.nine_2{
|
||||
left: 0;
|
||||
top: 6.6rem;
|
||||
width: 6rem;
|
||||
height: 12.5rem;
|
||||
}
|
||||
.nine_3{
|
||||
left: 6.3rem;
|
||||
top: 0;
|
||||
width: 10.2rem;
|
||||
height: 19.1rem;
|
||||
}
|
||||
.nine_4{
|
||||
left: 16.7rem;
|
||||
top: 0;
|
||||
width: 5.9rem;
|
||||
height: 5.8rem;
|
||||
}
|
||||
.nine_5{
|
||||
left: 16.7rem;
|
||||
top: 5.9rem;
|
||||
width: 5.9rem;
|
||||
height: 13.2rem;
|
||||
}
|
||||
.nine_6{
|
||||
left: 22.7rem;
|
||||
top: 0;
|
||||
width: 9.3rem;
|
||||
height: 9.4rem;
|
||||
}
|
||||
.nine_7{
|
||||
left: 22.7rem;
|
||||
top: 9.5rem;
|
||||
width: 9.3rem;
|
||||
height: 9.6rem;
|
||||
}
|
||||
.nine_8{
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 8.7rem;
|
||||
height: 6.7rem;
|
||||
}
|
||||
.nine_9{
|
||||
right: 0;
|
||||
top: 6.8rem;
|
||||
width: 8.7rem;
|
||||
height: 12.3rem;
|
||||
}
|
||||
}
|
||||
|
||||
.template_ten{
|
||||
height: 21.2rem;
|
||||
|
||||
.ten_1{
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 9.9rem;
|
||||
height: 10.6rem;
|
||||
}
|
||||
.ten_2{
|
||||
left: 0;
|
||||
top: 10.8rem;
|
||||
width: 9.9rem;
|
||||
height: 10.4rem;
|
||||
}
|
||||
.ten_3{
|
||||
left: 10rem;
|
||||
top: 0;
|
||||
width: 9.9rem;
|
||||
height: 21.2rem;
|
||||
}
|
||||
.ten_4{
|
||||
left: 20rem;
|
||||
top: 0;
|
||||
width: 8.1rem;
|
||||
height: 15rem;
|
||||
}
|
||||
.ten_5{
|
||||
left: 20rem;
|
||||
top: 15.3rem;
|
||||
width: 8.1rem;
|
||||
height: 5.9rem;
|
||||
}
|
||||
.ten_6{
|
||||
left:28.2rem;
|
||||
top: 0;
|
||||
width: 6.4rem;
|
||||
height: 6.3rem;
|
||||
}
|
||||
.ten_7{
|
||||
left:28.2rem;
|
||||
top: 6.4rem;
|
||||
width: 6.4rem;
|
||||
height: 14.7rem;
|
||||
}
|
||||
.ten_8{
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 6.1rem;
|
||||
height: 6rem;
|
||||
}
|
||||
.ten_9{
|
||||
right: 0;
|
||||
top: 6.2rem;
|
||||
width: 6.1rem;
|
||||
height: 6.1rem;
|
||||
}
|
||||
.ten_10{
|
||||
right: 0;
|
||||
top: 12.5rem;
|
||||
width: 6.1rem;
|
||||
height: 8.7rem;
|
||||
}
|
||||
}
|
||||
.img_template{
|
||||
position: absolute;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
422
src/component/HomePage/MoodboardUpload.vue
Normal file
@@ -0,0 +1,422 @@
|
||||
<template>
|
||||
<div class="collection_modal_item">
|
||||
<div class="switch_type_list">
|
||||
<div class="switch_type_item select_swtich">
|
||||
<span>Upload</span>
|
||||
</div>
|
||||
<div @click="openLibrary()" class="switch_type_item">
|
||||
<span>My Library</span>
|
||||
</div>
|
||||
<div class="design_template_button" @click.stop="changeTemplateModal()" v-show="fileList.length>2">Design</div>
|
||||
</div>
|
||||
|
||||
<div class="moodboard_body">
|
||||
<div class="upload_img_body scroll_style" >
|
||||
<div class="upload_item">
|
||||
<div class="upload_file_item" v-for="(file, index) in fileList" :key="file">
|
||||
<div class="upload_file_item_content" v-show="file?.status === 'uploading'">
|
||||
<a-spin :indicator="indicator" tip="Uploading..."/>
|
||||
</div>
|
||||
<div class="upload_file_item_content" v-show="file?.status === 'done'">
|
||||
<img :src="file?.imgUrl" class="upload_img">
|
||||
<div class="delete_file_block" @click="deleteFile(index)">Delete</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="upload_file_item upload_component" v-show="fileList.length < 10">
|
||||
<a-upload
|
||||
:action="uploadUrl + '/api/element/upload'"
|
||||
list-type="picture-card"
|
||||
:data="{
|
||||
...upload
|
||||
}"
|
||||
:headers="{Authorization:token}"
|
||||
v-model:file-list="fileList"
|
||||
:before-upload="beforeUpload"
|
||||
multiple
|
||||
:maxCount="10"
|
||||
accept=".jpg,.png,.jpeg,.bmp"
|
||||
@change="(file)=>fileUploadChange(file)"
|
||||
>
|
||||
<div class="upload_tip_block" v-show="fileList.length < 10">
|
||||
<img class="upload_img_icon" src="@/assets/images/homePage/add_file.png">
|
||||
</div>
|
||||
</a-upload>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="upload_max_tip">
|
||||
<span class="icon iconfont icon-zhuyi"></span>
|
||||
<span>Maximum 10 images can be uploaded, Maximum 2M per image</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Material ref="Material" @confirmSelect="confirmSelect"></Material>
|
||||
|
||||
<a-modal class="moodboard_template_modal"
|
||||
v-model:visible="templateModal"
|
||||
:footer="null"
|
||||
width="47rem"
|
||||
:maskClosable="false"
|
||||
:centered="true"
|
||||
:closable="false"
|
||||
>
|
||||
<div class="moodboard_template_content">
|
||||
<div class="moodboard_template_header">
|
||||
<div class="moodboard_template_title">MoodBoard Design</div>
|
||||
<div class="icon iconfont icon-guanbi close_icon" @click.stop="changeTemplateModal()"></div>
|
||||
</div>
|
||||
<div class="moodboard_template_block">
|
||||
<div class="moodboard_template_info">
|
||||
<MoodTemplate :fileList="this.templateFileList" :moodTemplateId="moodTemplateId"></MoodTemplate>
|
||||
<div class="moodboard_template_refetch_content">
|
||||
<div class="button_second" @click="refetchTemplate()">Re-fetch</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="button_second submit_button" @click="submitTemplate()">Submit</div>
|
||||
</div>
|
||||
|
||||
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
|
||||
import { defineComponent, h,ref } from 'vue'
|
||||
import { LoadingOutlined } from '@ant-design/icons-vue';
|
||||
import {getCookie} from '@/tool/cookie'
|
||||
import {getUploadUrl} from '@/tool/util'
|
||||
import {useStore} from 'vuex'
|
||||
import { message, Upload } from 'ant-design-vue';
|
||||
import Material from '@/component/HomePage/Material.vue'
|
||||
import MoodTemplate from '@/component/HomePage/MoodTemplate.vue'
|
||||
export default defineComponent({
|
||||
components:{Material,MoodTemplate},
|
||||
setup(){
|
||||
let fileList:any = ref([])
|
||||
let templateModal:any = ref(false)
|
||||
let templateFileList:any = ref([])
|
||||
return {
|
||||
fileList,
|
||||
templateModal,
|
||||
templateFileList
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
indicator : h(LoadingOutlined, {
|
||||
style: {
|
||||
fontSize: '2.4rem',
|
||||
},
|
||||
spin: true,
|
||||
}),
|
||||
upload:{
|
||||
isPin:0,
|
||||
level1Type:'Moodboard',
|
||||
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
},
|
||||
token:'',
|
||||
uploadUrl:'',
|
||||
moodTemplateId:'',//模板id
|
||||
store:useStore()
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
this.token = getCookie('token') || ''
|
||||
this.uploadUrl = getUploadUrl()
|
||||
},
|
||||
methods:{
|
||||
openLibrary(){
|
||||
let material:any = this.$refs.Material
|
||||
material.init('Moodboard')
|
||||
},
|
||||
fileUploadChange(data:any){
|
||||
let file = data.file
|
||||
if(file.status === 'done'){
|
||||
let res = JSON.parse(file.xhr.response)
|
||||
file.imgUrl = res.data.url
|
||||
file.resData = res.data
|
||||
let fileList = this.fileList.filter((v:any)=> v.status === 'done')
|
||||
this.store.commit('setMoodboardFile',fileList)
|
||||
this.store.commit('clearMoodTemplateId')
|
||||
}else if(file.status === 'error'){
|
||||
let index = -1
|
||||
this.fileList.forEach((ele:any,index1:any) => {
|
||||
if(file.uid === ele.uid){
|
||||
index = index1
|
||||
}
|
||||
});
|
||||
if(index > -1){
|
||||
this.fileList.splice(index, 1)
|
||||
}
|
||||
message.error(file.name + 'upload failed')
|
||||
}
|
||||
},
|
||||
|
||||
beforeUpload(file:any){
|
||||
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg' || file.type === 'image/bmp';
|
||||
if (!isJpgOrPng) {
|
||||
message.error('You can only upload Image file!');
|
||||
}
|
||||
const isLt2M = file.size / 1024 / 1024 < 2;
|
||||
if (!isLt2M) {
|
||||
message.error('Image must smaller than 5MB!');
|
||||
}
|
||||
return (isJpgOrPng && isLt2M) || Upload.LIST_IGNORE;
|
||||
},
|
||||
|
||||
deleteFile(index:any){
|
||||
this.fileList.splice(index, 1)
|
||||
this.store.commit('setMoodboardFile',this.fileList)
|
||||
this.store.commit('clearMoodTemplateId')
|
||||
},
|
||||
recollection(){
|
||||
this.fileList = JSON.parse(JSON.stringify(this.store.state.UploadFilesModule.allBoardData.moodboardFiles))
|
||||
let moodTemplateId = this.store.state.UploadFilesModule.allBoardData.moodTemplateId
|
||||
this.store.commit('setMoodboardFile',this.fileList)
|
||||
this.store.commit('setMoodTemplateId',moodTemplateId)
|
||||
},
|
||||
|
||||
confirmSelect(event:any){
|
||||
for(let item of event){
|
||||
let data = {
|
||||
imgUrl:item.url,
|
||||
resData:item,
|
||||
status:'done',
|
||||
}
|
||||
if(this.fileList.length == 10){
|
||||
message.error('Maximum number of allowable file uploads has been exceeded')
|
||||
break
|
||||
}
|
||||
this.fileList.push(data)
|
||||
}
|
||||
this.store.commit('setMoodboardFile',this.fileList)
|
||||
this.store.commit('clearMoodTemplateId')
|
||||
|
||||
},
|
||||
|
||||
changeTemplateModal(){
|
||||
this.templateModal = !this.templateModal
|
||||
if(this.templateModal){
|
||||
this.templateFileList = this.fileList.map((v:any)=>{
|
||||
let data = {
|
||||
...v,
|
||||
imgUrl:v.imgUrl.replace(/\s/g, encodeURIComponent(' '))
|
||||
}
|
||||
return data
|
||||
})
|
||||
this.moodTemplateId = this.store.state.UploadFilesModule.moodTemplateId || this.templateFileList.length
|
||||
}
|
||||
},
|
||||
|
||||
randomRange(min:any, max:any, num:any) { // min最小值,max最大值 num排除的值
|
||||
let index = Math.floor(Math.random() * (max - min)) + min;
|
||||
while(index === num){
|
||||
index = Math.floor(Math.random() * (max - min)) + min;
|
||||
}
|
||||
return index
|
||||
|
||||
},
|
||||
|
||||
//随机重置图片顺序
|
||||
refetchTemplate(){
|
||||
let arr= Array.from({length:this.templateFileList.length})
|
||||
for(let item of this.templateFileList){
|
||||
let index = this.randomRange(0,this.templateFileList.length,-1)
|
||||
while(arr[index]){
|
||||
index = this.randomRange(0,this.templateFileList.length,-1)
|
||||
}
|
||||
arr[index] = item
|
||||
}
|
||||
this.templateFileList = arr
|
||||
},
|
||||
|
||||
//提交模板
|
||||
submitTemplate(){
|
||||
this.fileList = JSON.parse(JSON.stringify(this.templateFileList))
|
||||
this.store.commit('setMoodboardFile',this.fileList)
|
||||
this.store.commit('setMoodTemplateId',this.moodTemplateId)
|
||||
this.changeTemplateModal()
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.collection_modal_item{
|
||||
padding: 1.5rem 2.6rem 4rem;
|
||||
height: 100%;
|
||||
|
||||
.switch_type_list{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
.switch_type_item{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 2rem;
|
||||
height: 4rem;
|
||||
background: #fff;
|
||||
border-radius: 0.8rem;
|
||||
line-height: 4rem;
|
||||
font-size: 1.6rem;
|
||||
margin-right: 2.2rem;
|
||||
color: #5B5E69;
|
||||
cursor: pointer;
|
||||
|
||||
&.select_swtich{
|
||||
color: #343579;
|
||||
}
|
||||
|
||||
.switch_icon{
|
||||
font-size: 1.8rem;
|
||||
margin-right: 0.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
.design_template_button{
|
||||
background: #E6E6F6;
|
||||
padding: 0 2.7rem;
|
||||
font-size: 1.4rem;
|
||||
height: 3.2rem;
|
||||
line-height: 3.2rem;
|
||||
cursor: pointer;
|
||||
color: #343579;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.moodboard_body{
|
||||
margin-top: 1rem;
|
||||
height: calc(100% - 5rem);
|
||||
|
||||
.upload_img_body{
|
||||
height: calc(100% - 3rem);
|
||||
overflow-y: auto;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.upload_file_item{
|
||||
margin: 0 2rem 2rem 0;
|
||||
display: inline-block;
|
||||
width: 16.5rem;
|
||||
height: 16.5rem;
|
||||
border: 1px solid #F5F5F5;
|
||||
vertical-align: top;
|
||||
|
||||
&.upload_component{
|
||||
border: none;
|
||||
}
|
||||
|
||||
.upload_file_item_content{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
|
||||
&:hover .delete_file_block{
|
||||
display: block;
|
||||
}
|
||||
|
||||
.upload_img{
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.delete_file_block{
|
||||
display: none;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
height: 4rem;
|
||||
background: rgba(0,0,0,0.2);
|
||||
font-size: 1.6rem;
|
||||
color: #FFFFFF;
|
||||
line-height: 4rem;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.upload_img_icon{
|
||||
width: 4.6rem;
|
||||
}
|
||||
}
|
||||
|
||||
.upload_max_tip{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.4rem;
|
||||
color: #030303;
|
||||
|
||||
.icon-zhuyi{
|
||||
font-size: 1.6rem;
|
||||
margin-right: 0.7rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
</style>
|
||||
<style lang="less">
|
||||
.moodboard_template_modal{
|
||||
|
||||
.ant-modal-body{
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.moodboard_template_content{
|
||||
background: #F2F3FB;
|
||||
padding-bottom: 2.9rem;
|
||||
|
||||
.moodboard_template_header{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 2rem 0 2.5rem;
|
||||
height: 6.6rem;
|
||||
|
||||
.moodboard_template_title{
|
||||
font-size: 1.8rem;
|
||||
font-weight: 500;
|
||||
color: #030303;
|
||||
}
|
||||
|
||||
.close_icon{
|
||||
font-size: 1.8rem;
|
||||
color: #AEB2B7;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.moodboard_template_block{
|
||||
padding: 0 3.1rem 0;
|
||||
|
||||
.moodboard_template_info{
|
||||
background: #fff;
|
||||
|
||||
.moodboard_template_refetch_content{
|
||||
padding: 3.1rem 0 2rem;
|
||||
|
||||
.button_second{
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.submit_button{
|
||||
margin: 2rem auto 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
174
src/component/HomePage/NewCollectionReview.vue
Normal file
@@ -0,0 +1,174 @@
|
||||
<template>
|
||||
<!-- 生成collention缩略图用的 -->
|
||||
<div class="collection_review">
|
||||
<div class="collection_review_mark"></div>
|
||||
<div class="img_block_item" v-if="allBoardData?.moodTemplateId">
|
||||
<MoodTemplate :fileList="allBoardData?.moodboardFiles" :moodTemplateId="allBoardData?.moodTemplateId"></MoodTemplate>
|
||||
</div>
|
||||
<div class="img_block_item" v-else>
|
||||
<div class="lager_img_item" v-for="(mood) in allBoardData.moodboardFiles" :key="mood">
|
||||
<div class="all_img_item_block">
|
||||
<img class="all_img_content cover_img" :src="mood.imgUrl" >
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="img_block_item">
|
||||
<div class="small_img_item" v-for="(print) in allBoardData.printboardFiles" :key="print">
|
||||
<div class="all_img_item_block">
|
||||
<img class="all_img_content cover_img" :src="print.imgUrl">
|
||||
</div>
|
||||
</div>
|
||||
<div class="small_img_item" v-for="(generate) in allBoardData.generatePrintFiles" :key="generate">
|
||||
<div class="all_img_item_block">
|
||||
<img class="all_img_content cover_img" :src="generate.imgUrl">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="img_block_item">
|
||||
<div class="color_item" v-for="(color) in allBoardData.colorBoards" :key="color">
|
||||
<div class="color_content" :style="{background:`rgb(${color?.rgbValue?.r},${color?.rgbValue?.g},${color?.rgbValue?.b})`}"></div>
|
||||
<div class="color_content_body">
|
||||
<div class="color_des">{{color.tcx}}</div>
|
||||
<div class="color_des">{{color.name}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="img_block_item">
|
||||
<div class="lager_img_item" v-for="(skecth) in allBoardData.skecthboardFiles" :key="skecth">
|
||||
<div class="all_img_item_block">
|
||||
<img class="all_img_content" :src="skecth.imgUrl">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="img_block_item">
|
||||
<div class="lager_img_item" v-for="(marketing) in allBoardData.marketingSketchFiles" :key="marketing">
|
||||
<div class="all_img_item_block">
|
||||
<img class="all_img_content" :src="marketing.imgUrl">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent } from 'vue'
|
||||
import MoodTemplate from '@/component/HomePage/MoodTemplate.vue'
|
||||
import { useStore } from "vuex";
|
||||
export default defineComponent({
|
||||
components:{MoodTemplate},
|
||||
setup() {
|
||||
const store = useStore();
|
||||
let allBoardData:any = computed(()=>{return store.state.UploadFilesModule.allBoardData})
|
||||
return {
|
||||
allBoardData,
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.collection_review{
|
||||
width: 40.8rem;
|
||||
background: #fff;
|
||||
position: relative;
|
||||
|
||||
.collection_review_mark{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.img_block_item{
|
||||
margin-bottom: 2rem;
|
||||
|
||||
// &.color_block_item{
|
||||
// padding: 0 0.5rem 0 0.3rem;
|
||||
// }
|
||||
|
||||
.lager_img_item{
|
||||
display: inline-block;
|
||||
width: 20.4rem;
|
||||
height: 20.4rem;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.sketch_img_item{
|
||||
display: inline-block;
|
||||
width: 20.4rem;
|
||||
height: 42.2rem;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.small_img_item{
|
||||
width: 6.8rem;
|
||||
height: 6.8rem;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
.color_item{
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
// padding: 0 0.5rem;
|
||||
margin-right: 1.6rem;
|
||||
margin-bottom: 0.5rem;
|
||||
|
||||
&:nth-child(4n){
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.color_content{
|
||||
width: 9rem;
|
||||
height:6.2rem
|
||||
}
|
||||
.color_content_body{
|
||||
width: 9rem;
|
||||
padding: 0.7rem 0.2rem;
|
||||
background: #FEFEFE;
|
||||
border: 1px solid #E6E6E6;
|
||||
|
||||
.color_des{
|
||||
font-size: 1rem;
|
||||
font-family: Roboto;
|
||||
font-weight: 500;
|
||||
color: #000000;
|
||||
margin-bottom: 0.5rem;
|
||||
line-height: 1.3rem;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
&:last-child{
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.all_img_item_block{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.all_img_content{
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
|
||||
&.cover_img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
733
src/component/HomePage/PrintboardUpload.vue
Normal file
@@ -0,0 +1,733 @@
|
||||
<template>
|
||||
<div class="printboard_upload_modal">
|
||||
<div class="printboard_left_upload">
|
||||
<div class="left_upload_header">
|
||||
<div class="upload_header_item">
|
||||
<div class="switch_type_list">
|
||||
<div class="switch_type_item select_swtich">
|
||||
<span>Upload</span>
|
||||
</div>
|
||||
<div @click="openLibrary()" class="switch_type_item">
|
||||
<span>My Library</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="upload_header_item">
|
||||
<div><span class="select_img_num">{{getPinLength}}</span><span class="select_tip">selected</span></div>
|
||||
<div v-show="fileList.length>1 || (moodBoards.length && fileList.length)" class="recollection_button" @click="generatePrint()">Generate</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="printboard_body">
|
||||
<div class="upload_img_body">
|
||||
<div class="upload_item">
|
||||
<div :class="['upload_file_item']" v-for="(file, index) in fileList" :key="file">
|
||||
<div class="upload_file_img_block">
|
||||
<div class="upload_file_item_content" v-show="file?.status === 'uploading'">
|
||||
<a-spin :indicator="indicator" tip="Uploading..."/>
|
||||
</div>
|
||||
<div class="upload_file_item_content" @click="selectImg(file)" v-show="file?.status === 'done'">
|
||||
<img v-lazy="file.imgUrl" class="upload_img" :key="file.imgUrl">
|
||||
<div class="delete_file_block" @click.stop="deleteFile(index,file)">Delete</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pin_block" v-show="file?.status === 'done'">
|
||||
<a-checkbox v-model:checked="file.pin">PIN</a-checkbox>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="upload_file_item upload_component" v-show="fileList.length < 15">
|
||||
<a-upload
|
||||
v-show="fileList.length < 15"
|
||||
:action="uploadUrl + '/api/element/upload'"
|
||||
list-type="picture-card"
|
||||
:before-upload="beforeUpload"
|
||||
:data="{
|
||||
...upload
|
||||
}"
|
||||
:headers="{Authorization:token}"
|
||||
v-model:file-list="fileList"
|
||||
:customRequest="function(){}"
|
||||
multiple
|
||||
:maxCount="15"
|
||||
accept=".jpg,.png,.jpeg,.bmp"
|
||||
@change="fileUploadChange"
|
||||
>
|
||||
<div class="upload_tip_block" >
|
||||
<img class="upload_img_icon" src="@/assets/images/homePage/add_file.png">
|
||||
</div>
|
||||
</a-upload>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="upload_max_tip">
|
||||
<span class="icon iconfont icon-zhuyi"></span>
|
||||
<span>Maximum 15 images can be uploaded, Maximum 2M per image</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="generate_print">
|
||||
<div class="generate_print_header">
|
||||
<div class="generate_title">Generate New Print</div>
|
||||
<div class="generate_save_button" @click="savePrint()">Save</div>
|
||||
</div>
|
||||
<div class="generate_print_content_block">
|
||||
<div class="generate_print_content scroll_style">
|
||||
<div class="image_block" v-for="(img, index) in printImgList" :key="index">
|
||||
<div class="image_block_content">
|
||||
<img class="image_body" v-lazy="img.imgUrl" :key="img.imgUrl">
|
||||
<div class="delete_file_block" @click="deleteGenerateFile(index)">Delete</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="generate_loading_mark" v-show="generateloading">
|
||||
<a-spin size="large" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<Cropper ref="Cropper" @handleCropperSuccess="handleCropperSuccess" @closeCropper="deletUploadFile()" :cropperFileData="cropperFileData" :isUpload="isUpload"></Cropper>
|
||||
<Material ref="Material" @confirmSelect="confirmSelect"></Material>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent,h,ref,computed } from 'vue'
|
||||
import { LoadingOutlined } from '@ant-design/icons-vue';
|
||||
import {getCookie} from '@/tool/cookie'
|
||||
import {getUploadUrl} from '@/tool/util'
|
||||
import {useStore} from 'vuex'
|
||||
import { Https } from "@/tool/https";
|
||||
import { message,Upload} from 'ant-design-vue';
|
||||
import Cropper from '@/component/HomePage/Cropper.vue'
|
||||
import Material from '@/component/HomePage/Material.vue'
|
||||
export default defineComponent({
|
||||
components:{
|
||||
Cropper,
|
||||
Material
|
||||
},
|
||||
setup(){
|
||||
let store:any =useStore()
|
||||
let fileList:any = ref([]),//选中的文件id数据
|
||||
printImgList:any = ref([]), //print的印花图片
|
||||
moodBoards:any = computed(()=>{return store.state.UploadFilesModule.moodboardFiles})
|
||||
return {
|
||||
fileList,
|
||||
printImgList,
|
||||
moodBoards
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
getPinLength(){
|
||||
let selectLength:any = 0
|
||||
for(let item of this.fileList){
|
||||
if(item.pin){
|
||||
selectLength++
|
||||
}
|
||||
}
|
||||
return selectLength
|
||||
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
swtich_type:'upload',
|
||||
indicator : h(LoadingOutlined, {
|
||||
style: {
|
||||
fontSize: '2.4rem',
|
||||
},
|
||||
spin: true,
|
||||
}),
|
||||
upload:{
|
||||
isPin:0,
|
||||
level1Type:'Printboard',
|
||||
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
},
|
||||
token:'',
|
||||
uploadUrl:'',
|
||||
store:useStore(),
|
||||
cropperFileData:{name:'',uid:''}, //裁剪的原始文件数据
|
||||
currentFileNum:0, //当前上传的文件数
|
||||
isUpload:false,
|
||||
generateloading:false,
|
||||
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
this.token = getCookie('token') || ''
|
||||
this.uploadUrl = getUploadUrl()
|
||||
},
|
||||
methods:{
|
||||
openLibrary(){
|
||||
let material:any = this.$refs.Material
|
||||
material.init('Printboard')
|
||||
},
|
||||
fileUploadChange(data:any){
|
||||
let file = data.file
|
||||
let Cropper:any = this.$refs.Cropper
|
||||
if(this.currentFileNum === 1){
|
||||
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.getOptionImg(data_new)
|
||||
};
|
||||
// 转化为base64
|
||||
// reader.readAsDataURL(file)
|
||||
// 转化为blob
|
||||
reader.readAsArrayBuffer(file.originFileObj);
|
||||
this.cropperFileData = file
|
||||
Cropper.changeShowModal(true)
|
||||
|
||||
}else{
|
||||
this.customRequest(file)
|
||||
}
|
||||
},
|
||||
|
||||
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.error('You can only upload Image file!');
|
||||
}
|
||||
const isLt2M = file.size / 1024 / 1024 < 2;
|
||||
if (!isLt2M) {
|
||||
message.error('Image must smaller than 5MB!');
|
||||
}
|
||||
if(isJpgOrPng && isLt2M){
|
||||
this.currentFileNum = fileList.length
|
||||
}else{
|
||||
return (isJpgOrPng && isLt2M) || Upload.LIST_IGNORE;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
deleteFile(index:any,file:any){
|
||||
this.fileList.splice(index, 1)
|
||||
this.store.commit('setPrintboardFile',this.fileList)
|
||||
},
|
||||
|
||||
deleteGenerateFile(index:any){
|
||||
this.printImgList.splice(index, 1)
|
||||
this.store.commit('setGeneratePrintFile',this.printImgList)
|
||||
},
|
||||
|
||||
randomRange(min:any, max:any, num:any) { // min最小值,max最大值 num排除的值
|
||||
let index = Math.floor(Math.random() * (max - min)) + min;
|
||||
while(index === num){
|
||||
index = Math.floor(Math.random() * (max - min)) + min;
|
||||
}
|
||||
return index
|
||||
|
||||
},
|
||||
|
||||
generatePrint(){
|
||||
let data:any = {}
|
||||
//随机获取图片id
|
||||
if(!this.moodBoards.length){ //mood没有图片
|
||||
let index1 = -1
|
||||
let index2 = -2
|
||||
if(!this.getPinLength){ //没pin住
|
||||
index1 = this.randomRange(0, this.fileList.length, -1)
|
||||
index2 = this.randomRange(0, this.fileList.length, index1)
|
||||
|
||||
}else if(this.getPinLength === 1){ //pin住1个
|
||||
this.fileList.forEach((element:any,index:number) => {
|
||||
if(element.pin){
|
||||
index1 = index
|
||||
}
|
||||
});
|
||||
index2 = this.randomRange(0, this.fileList.length, index1)
|
||||
}else{ //pin住多个
|
||||
let selectIndexList:any = []
|
||||
this.fileList.forEach((element:any,index:number) => {
|
||||
if(element.pin){
|
||||
selectIndexList.push(index)
|
||||
}
|
||||
});
|
||||
index1 = this.randomRange(0, selectIndexList.length, -1) //pin住的中随机选一个
|
||||
index2 = this.randomRange(0, this.fileList.length, selectIndexList[index1]) //除了选中的外再来一个
|
||||
|
||||
}
|
||||
data = {
|
||||
select1Id:this.fileList[index1].id,
|
||||
select2Id:this.fileList[index2].id
|
||||
}
|
||||
}else{
|
||||
let index1 = this.randomRange(0, this.moodBoards.length, -1)
|
||||
let index2 = -2
|
||||
if(!this.getPinLength){ //没pin住
|
||||
index2 = this.randomRange(0, this.fileList.length, -1)
|
||||
}else if(this.getPinLength === 1){ //pin住1个
|
||||
this.fileList.forEach((element:any,index:number) => {
|
||||
if(element.pin){
|
||||
index2 = index
|
||||
}
|
||||
});
|
||||
}else{ //pin住多个
|
||||
let selectIndexList:any = []
|
||||
this.fileList.forEach((element:any,index:number) => {
|
||||
if(element.pin){
|
||||
selectIndexList.push(index)
|
||||
}
|
||||
});
|
||||
index2 = this.randomRange(0, selectIndexList.length, -1) //pin住的中随机选一个
|
||||
}
|
||||
data = {
|
||||
select1Id:this.moodBoards[index1].resData.id,
|
||||
select2Id:this.fileList[index2].id
|
||||
}
|
||||
}
|
||||
data.timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
this.generateloading = true
|
||||
Https.axiosPost(Https.httpUrls.elementGeneratePrint, data).then((rv) =>{
|
||||
if(rv){
|
||||
let data = {
|
||||
imgUrl:rv.url,
|
||||
resData:rv
|
||||
}
|
||||
this.printImgList.push(data)
|
||||
this.store.commit('setGeneratePrintFile',this.printImgList)
|
||||
this.generateloading = false
|
||||
}
|
||||
}).catch(res=>{
|
||||
this.generateloading = false
|
||||
})
|
||||
|
||||
},
|
||||
|
||||
savePrint(){
|
||||
let printId = this.printImgList.map((v:any) => v.resData.id)
|
||||
let data = {
|
||||
printId:printId,
|
||||
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
}
|
||||
Https.axiosPost(Https.httpUrls.elementSavePrint, data).then((rv) =>{
|
||||
if(rv){
|
||||
message.success('Save successfully')
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
customRequest(data:any){
|
||||
let new_data = {
|
||||
...this.upload,
|
||||
file:data.originFileObj
|
||||
}
|
||||
let fileUid = data.uid
|
||||
Https.axiosPost('/api/element/upload', new_data,{headers:{'Content-Type': 'multipart/form-data'}}).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
for(let file of this.fileList){
|
||||
if(fileUid === file.uid){
|
||||
file.status = 'done'
|
||||
file.imgUrl = rv.url
|
||||
file.pin = false
|
||||
file.id = rv.id
|
||||
file.resData = rv
|
||||
|
||||
}
|
||||
}
|
||||
let fileList = this.fileList.filter((v:any)=> v.status === 'done')
|
||||
this.store.commit('setPrintboardFile',fileList)
|
||||
}
|
||||
}
|
||||
).catch((res)=>{
|
||||
let index = -1
|
||||
this.fileList.forEach((ele:any,index1:any) => {
|
||||
if(fileUid === ele.uid){
|
||||
index = index1
|
||||
}
|
||||
});
|
||||
if(index > -1){
|
||||
this.fileList.splice(index, 1)
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
closeCropper(type:any){
|
||||
if(this.isUpload){
|
||||
return
|
||||
}
|
||||
if(type == 'error'){
|
||||
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 Cropper:any = this.$refs.Cropper
|
||||
Cropper.closeCropper()
|
||||
|
||||
},
|
||||
|
||||
deletUploadFile(){
|
||||
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)
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
handleCropperSuccess(event:any){
|
||||
let {file, fileData} =event
|
||||
let new_data = {
|
||||
...this.upload,
|
||||
file:file
|
||||
}
|
||||
if(this.isUpload){
|
||||
return
|
||||
}
|
||||
this.isUpload = true
|
||||
const hide = message.loading('loading', 0);
|
||||
Https.axiosPost('/api/element/upload', new_data,{headers:{'Content-Type': 'multipart/form-data'}}).then(
|
||||
(rv: any) => {
|
||||
for(let file of this.fileList){
|
||||
if(fileData.uid === file.uid){
|
||||
file.status = 'done'
|
||||
file.imgUrl = rv.url
|
||||
file.id = rv.id
|
||||
file.resData = rv
|
||||
}
|
||||
}
|
||||
let fileList = this.fileList.filter((v:any)=> v.status === 'done')
|
||||
this.isUpload = false
|
||||
this.closeCropper('success')
|
||||
this.cropperFileData = {name:'',uid:''}
|
||||
this.store.commit('setPrintboardFile',fileList)
|
||||
hide()
|
||||
}
|
||||
).catch(res=>{
|
||||
let index = -1
|
||||
this.fileList.forEach((ele:any,index1:any) => {
|
||||
if(fileData.uid === ele.uid){
|
||||
index = index1
|
||||
}
|
||||
});
|
||||
if(index > -1){
|
||||
this.fileList.splice(index, 1)
|
||||
}
|
||||
this.cropperFileData = {name:'',uid:''}
|
||||
this.isUpload = false
|
||||
this.closeCropper('error')
|
||||
hide()
|
||||
});
|
||||
},
|
||||
|
||||
recollection(){
|
||||
this.fileList = JSON.parse(JSON.stringify(this.store.state.UploadFilesModule.allBoardData.printboardFiles))
|
||||
this.printImgList = JSON.parse(JSON.stringify(this.store.state.UploadFilesModule.allBoardData.generatePrintFiles))
|
||||
this.store.commit('setPrintboardFile',this.fileList)
|
||||
this.store.commit('setGeneratePrintFile',this.printImgList)
|
||||
},
|
||||
|
||||
confirmSelect(event:any){
|
||||
for(let item of event){
|
||||
let data = {
|
||||
imgUrl:item.url,
|
||||
resData:item,
|
||||
pin:false,
|
||||
id:item.id,
|
||||
status:'done',
|
||||
}
|
||||
if(this.fileList.length == 15){
|
||||
message.error('Maximum number of allowable file uploads has been exceeded')
|
||||
break
|
||||
}
|
||||
this.fileList.push(data)
|
||||
}
|
||||
this.store.commit('setPrintboardFile',this.fileList)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.printboard_upload_modal{
|
||||
padding: 1rem 1rem 1.8rem 1rem;
|
||||
height: 100%;
|
||||
background: #F2F3FB;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.printboard_left_upload{
|
||||
width: calc(100% - 39.8rem);
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
padding: 0.5rem 2.2rem 2rem 2.6rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
.left_upload_header{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.upload_header_item{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.switch_type_list{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.switch_type_item{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 2rem;
|
||||
height: 4rem;
|
||||
background: #fff;
|
||||
line-height: 4rem;
|
||||
font-size: 1.6rem;
|
||||
margin-right: 2.2rem;
|
||||
color: #5B5E69;
|
||||
cursor: pointer;
|
||||
|
||||
&.select_swtich{
|
||||
color: #343579;
|
||||
}
|
||||
|
||||
.switch_icon{
|
||||
font-size: 1.8rem;
|
||||
margin-right: 0.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.select_img_num{
|
||||
font-size: 2rem;
|
||||
color: #030303;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.select_tip{
|
||||
font-size: 1.6rem;
|
||||
margin-left: 0.9rem;
|
||||
color: #B7B7B7;
|
||||
}
|
||||
|
||||
.recollection_button{
|
||||
padding: 0 1rem;
|
||||
height: 3.2rem;
|
||||
line-height: 3.2rem;
|
||||
background: #E6E6F6;
|
||||
font-size: 1.2rem;
|
||||
color: #343579;
|
||||
margin-left: 0.9rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
.printboard_body{
|
||||
margin-top: 1rem;
|
||||
height: calc(100% - 5rem);
|
||||
|
||||
.upload_img_body{
|
||||
height: calc(100% - 3rem);
|
||||
overflow-y: auto;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.upload_file_item{
|
||||
margin: 0 2rem 2rem 0;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
|
||||
.upload_file_img_block{
|
||||
width: 16.5rem;
|
||||
height: 16.5rem;
|
||||
border: 1px solid #F5F5F5;
|
||||
}
|
||||
|
||||
.pin_block{
|
||||
text-align: center;
|
||||
margin-top:1.6rem;
|
||||
}
|
||||
|
||||
&.upload_component{
|
||||
border: none;
|
||||
}
|
||||
|
||||
.upload_file_item_content{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
|
||||
|
||||
&:hover .delete_file_block{
|
||||
display: block;
|
||||
}
|
||||
|
||||
.upload_img{
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.delete_file_block{
|
||||
display: none;
|
||||
width: 100%;
|
||||
height: 4rem;
|
||||
background: rgba(0,0,0,0.2);
|
||||
font-size: 1.6rem;
|
||||
color: #FFFFFF;
|
||||
line-height: 4rem;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.upload_img_icon{
|
||||
width: 4.6rem;
|
||||
}
|
||||
}
|
||||
|
||||
.upload_max_tip{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.4rem;
|
||||
color: #030303;
|
||||
|
||||
.icon-zhuyi{
|
||||
font-size: 1.6rem;
|
||||
margin-right: 0.7rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.generate_print{
|
||||
width: 38.4rem;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
|
||||
.generate_print_header{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 1rem 1rem 2.5rem 2.5rem;
|
||||
|
||||
.generate_title{
|
||||
font-size: 1.6rem;
|
||||
font-weight: bold;
|
||||
color: #030303;
|
||||
}
|
||||
.generate_save_button{
|
||||
background: #E6E6F6;
|
||||
padding: 0.1rem;
|
||||
padding: 0 2.7rem;
|
||||
font-size: 1.4rem;
|
||||
height: 3.2rem;
|
||||
line-height: 3.2rem;
|
||||
cursor: pointer;
|
||||
color: #343579;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.generate_print_content_block{
|
||||
height: calc(100% - 6.7rem);
|
||||
position: relative;
|
||||
|
||||
.generate_loading_mark{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(0,0,0,0.4);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.generate_print_content{
|
||||
overflow-y: auto;
|
||||
height: 100%;
|
||||
padding:0 0.8rem;
|
||||
position: relative;
|
||||
|
||||
|
||||
|
||||
.image_block{
|
||||
display: inline-block;
|
||||
margin-right: 1.6rem;
|
||||
margin-bottom: 1.6rem;
|
||||
width: 16.5rem;
|
||||
height: 16.5rem;
|
||||
border: 0.1rem solid #F5F5F5;
|
||||
vertical-align: top;
|
||||
|
||||
&:nth-child(2n){
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.image_block_content{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
|
||||
&:hover .delete_file_block{
|
||||
display: block;
|
||||
}
|
||||
|
||||
.delete_file_block{
|
||||
display: none;
|
||||
width: 100%;
|
||||
height: 4rem;
|
||||
background: rgba(0,0,0,0.2);
|
||||
font-size: 1.6rem;
|
||||
color: #FFFFFF;
|
||||
line-height: 4rem;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.image_body{
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
420
src/component/HomePage/SketchboardUpload.vue
Normal file
@@ -0,0 +1,420 @@
|
||||
<template>
|
||||
<div class="sketchboard_upload_modal">
|
||||
<div class="switch_type_list">
|
||||
<div class="switch_type_item select_swtich">
|
||||
<span>Upload</span>
|
||||
</div>
|
||||
<div @click="openLibrary()" class="switch_type_item">
|
||||
<span>My Library</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sketchboard_body">
|
||||
<div class="upload_img_body scroll_style">
|
||||
<div class="upload_item">
|
||||
<div class="upload_file_item" v-for="(file,index) in fileList" :key="file">
|
||||
<div class="upload_file_item_content" v-show="file?.status === 'uploading'">
|
||||
<a-spin :indicator="indicator" tip="Uploading..."/>
|
||||
</div>
|
||||
<div class="upload_file_item_content" v-show="file?.status === 'done'">
|
||||
<img :src="file?.imgUrl" class="upload_img">
|
||||
<div class="operate_file_block" >
|
||||
<!-- <div class="delete_file_block" @click="deleteFile(index)">Delete</div> -->
|
||||
<div class="select_img_type">
|
||||
<div class="select_category" @click.stop="showFileCategory(file)">
|
||||
{{getSketchLabel(file.category)}}
|
||||
<div :class="['icon','iconfont', 'icon-xiala', file.categoryShow?'icon_rotate':'']"></div>
|
||||
</div>
|
||||
<div class="category_list" v-show="file.categoryShow">
|
||||
<div :class="['category_item', file.category == cate.value?'select_category_item':'']" v-for="(cate,index) in sketchCatecoryList" :key="index" @click="selectFileCategory(file,cate)">{{cate.label}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="delete_file_block" @click="deleteFile(index)">
|
||||
<span class="icon iconfont icon-shanchu"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pin_block" v-show="file?.status === 'done'">
|
||||
<a-checkbox v-model:checked="file.pin">PIN</a-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
<div class="upload_file_item upload_component" v-show="fileList.length < 15">
|
||||
<a-upload
|
||||
:action="uploadUrl + '/api/element/upload'"
|
||||
list-type="picture-card"
|
||||
:data="{
|
||||
...upload
|
||||
}"
|
||||
:before-upload="beforeUpload"
|
||||
:headers="{Authorization:token}"
|
||||
v-model:file-list="fileList"
|
||||
multiple
|
||||
:maxCount="15"
|
||||
accept=".jpg,.png,.jpeg,.bmp"
|
||||
@change="(file)=>fileUploadChange(file)"
|
||||
>
|
||||
<div class="upload_tip_block" v-show="fileList.length < 15">
|
||||
<img class="upload_img_icon" src="@/assets/images/homePage/add_file.png">
|
||||
</div>
|
||||
</a-upload>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="upload_max_tip">
|
||||
<span class="icon iconfont icon-zhuyi"></span>
|
||||
<span>Maximum 15 images can be uploaded, Maximum 2M per image</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Material ref="Material" @confirmSelect="confirmSelect"></Material>
|
||||
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, h,ref } from 'vue'
|
||||
import { LoadingOutlined } from '@ant-design/icons-vue';
|
||||
import {getCookie} from '@/tool/cookie'
|
||||
import {getUploadUrl} from '@/tool/util'
|
||||
import {useStore} from 'vuex'
|
||||
import { message,Upload} from 'ant-design-vue';
|
||||
import Material from '@/component/HomePage/Material.vue'
|
||||
export default defineComponent({
|
||||
components:{Material},
|
||||
setup(){
|
||||
let fileList:any = ref([])
|
||||
return {
|
||||
fileList
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
swtich_type:'upload',
|
||||
indicator : h(LoadingOutlined, {
|
||||
style: {
|
||||
fontSize: '2.4rem',
|
||||
},
|
||||
spin: true,
|
||||
}),
|
||||
upload:{
|
||||
isPin:0,
|
||||
level1Type:'Sketchboard',
|
||||
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
},
|
||||
token:'',
|
||||
uploadUrl:'',
|
||||
store:useStore(),
|
||||
sketchCatecoryList:[
|
||||
{
|
||||
value: 'Outwear',
|
||||
label: "Outwear",
|
||||
},
|
||||
{
|
||||
value: 'Blouse',
|
||||
label: "Blouse",
|
||||
},
|
||||
{
|
||||
value: 'Dress',
|
||||
label: "Dress",
|
||||
},
|
||||
{
|
||||
value: 'Trousers',
|
||||
label: "Trousers",
|
||||
},
|
||||
{
|
||||
value: 'Skirt',
|
||||
label: "Skirt",
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
getSketchLabel(value){
|
||||
return (value:any)=>{
|
||||
let lable = '';
|
||||
for(let item of this.sketchCatecoryList){
|
||||
if(item.value === value){
|
||||
lable = item.label
|
||||
break
|
||||
}
|
||||
}
|
||||
return lable
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
this.token = getCookie('token') || ''
|
||||
this.uploadUrl = getUploadUrl()
|
||||
},
|
||||
methods:{
|
||||
openLibrary(){
|
||||
let material:any = this.$refs.Material
|
||||
material.init('Sketchboard')
|
||||
},
|
||||
fileUploadChange(data:any){
|
||||
let file = data.file
|
||||
if(file.status === 'done'){
|
||||
let res = JSON.parse(file.xhr.response)
|
||||
file.imgUrl = res.data.url
|
||||
file.resData = res.data
|
||||
file.pin = false
|
||||
file.category = 'Outwear'
|
||||
file.categoryShow = false
|
||||
let fileList = this.fileList.filter((v:any)=> v.status === 'done')
|
||||
this.store.commit('setSketchboardFile',fileList)
|
||||
}else if(file.status === 'error'){
|
||||
let index = -1
|
||||
this.fileList.forEach((ele:any,index1:any) => {
|
||||
if(file.uid === ele.uid){
|
||||
index = index1
|
||||
}
|
||||
});
|
||||
if(index > -1){
|
||||
this.fileList.splice(index, 1)
|
||||
}
|
||||
message.error(file.name + 'upload failed')
|
||||
}
|
||||
},
|
||||
|
||||
beforeUpload(file:any){
|
||||
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg' || file.type === 'image/bmp';
|
||||
if (!isJpgOrPng) {
|
||||
message.error('You can only upload Image file!');
|
||||
}
|
||||
const isLt2M = file.size / 1024 / 1024 < 2;
|
||||
if (!isLt2M) {
|
||||
message.error('Image must smaller than 5MB!');
|
||||
}
|
||||
return (isJpgOrPng && isLt2M) || Upload.LIST_IGNORE;
|
||||
},
|
||||
|
||||
showFileCategory(file:any){
|
||||
file.categoryShow = true
|
||||
document.addEventListener('click', this.hiddenFileCategory)
|
||||
},
|
||||
|
||||
selectFileCategory(file:any,cate:any){
|
||||
file.category = cate.value
|
||||
this.store.commit('setSketchboardFile',this.fileList)
|
||||
},
|
||||
|
||||
hiddenFileCategory(){
|
||||
for(let item of this.fileList){
|
||||
item.categoryShow = false
|
||||
}
|
||||
document.removeEventListener('click', this.hiddenFileCategory)
|
||||
},
|
||||
|
||||
deleteFile(index:any){
|
||||
this.fileList.splice(index, 1)
|
||||
this.store.commit('setSketchboardFile',this.fileList)
|
||||
},
|
||||
|
||||
recollection(){
|
||||
this.fileList = JSON.parse(JSON.stringify(this.store.state.UploadFilesModule.allBoardData.skecthboardFiles))
|
||||
this.store.commit('setSketchboardFile',this.fileList)
|
||||
},
|
||||
|
||||
confirmSelect(event:any){
|
||||
for(let item of event){
|
||||
let data = {
|
||||
imgUrl:item.url,
|
||||
resData:item,
|
||||
pin:false,
|
||||
status:'done',
|
||||
category:item.level2Type || 'Outwear',
|
||||
categoryShow:false,
|
||||
}
|
||||
if(this.fileList.length == 15){
|
||||
message.error('Maximum number of allowable file uploads has been exceeded')
|
||||
break
|
||||
}
|
||||
this.fileList.push(data)
|
||||
}
|
||||
this.store.commit('setSketchboardFile',this.fileList)
|
||||
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.sketchboard_upload_modal{
|
||||
padding: 1.5rem 2.6rem 4rem;
|
||||
height: 100%;
|
||||
|
||||
.switch_type_list{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.switch_type_item{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 2rem;
|
||||
height: 4rem;
|
||||
background: #fff;
|
||||
border-radius: 0.8rem;
|
||||
line-height: 4rem;
|
||||
font-size: 1.6rem;
|
||||
margin-right: 2.2rem;
|
||||
color: #5B5E69;
|
||||
cursor: pointer;
|
||||
|
||||
&.select_swtich{
|
||||
color: #343579;
|
||||
}
|
||||
|
||||
.switch_icon{
|
||||
font-size: 1.8rem;
|
||||
margin-right: 0.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.sketchboard_body{
|
||||
margin-top: 1rem;
|
||||
height: calc(100% - 5rem);
|
||||
|
||||
.upload_img_body{
|
||||
height: calc(100% - 3rem);
|
||||
overflow-y: auto;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.upload_file_item{
|
||||
margin: 0 2rem 2rem 0;
|
||||
display: inline-block;
|
||||
width: 16.5rem;
|
||||
border: 1px solid #F5F5F5;
|
||||
vertical-align: top;
|
||||
|
||||
&.upload_component{
|
||||
border: none;
|
||||
}
|
||||
|
||||
.upload_file_item_content{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
height: 16.5rem;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
|
||||
.upload_img{
|
||||
display: block;
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.delete_file_block{
|
||||
display: none;
|
||||
width: 3.2rem;
|
||||
height: 3.2rem;
|
||||
background: rgba(0,0,0,0.6);
|
||||
border-radius: 0.4rem;
|
||||
position: absolute;
|
||||
top: 0.9rem;
|
||||
right: 0.9rem;
|
||||
text-align: center;
|
||||
line-height: 3.2rem;
|
||||
|
||||
.icon-shanchu{
|
||||
font-size: 1.6rem;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover .delete_file_block{
|
||||
display: block;
|
||||
}
|
||||
|
||||
.operate_file_block{
|
||||
width: 100%;
|
||||
height: 4rem;
|
||||
font-size: 1.6rem;
|
||||
color: #FFFFFF;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
|
||||
.select_img_type{
|
||||
height: 100%;
|
||||
line-height: 4rem;
|
||||
text-align: center;
|
||||
background: rgba(0,0,0,0.6);
|
||||
position: relative;
|
||||
|
||||
.select_category{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.icon-xiala{
|
||||
margin-left: 0.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
.icon_rotate{
|
||||
-moz-transform:rotate(180deg);
|
||||
-webkit-transform:rotate(180deg);
|
||||
transform: rotate(180deg);
|
||||
animation-direction: 0.5s;
|
||||
}
|
||||
|
||||
.category_list{
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 4.1rem;
|
||||
left: 0;
|
||||
background: rgba(0,0,0,0.4);
|
||||
border: 1px solid #343579;
|
||||
border-radius: 0.8rem;
|
||||
overflow: hidden;
|
||||
z-index: 2;
|
||||
|
||||
.category_item{
|
||||
text-align: left;
|
||||
font-size: 1.4rem;
|
||||
padding: 1rem 1.9rem;
|
||||
line-height: 1.6rem;
|
||||
|
||||
&.select_category_item{
|
||||
background: linear-gradient(160deg, #AC2A3B, #292161);
|
||||
}
|
||||
|
||||
&:hover{
|
||||
background: linear-gradient(160deg, #AC2A3B, #292161);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.pin_block{
|
||||
text-align: center;
|
||||
margin-top:1.6rem;
|
||||
}
|
||||
|
||||
.upload_img_icon{
|
||||
width: 4.6rem;
|
||||
}
|
||||
}
|
||||
|
||||
.upload_max_tip{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.4rem;
|
||||
color: #030303;
|
||||
|
||||
.icon-zhuyi{
|
||||
font-size: 1.6rem;
|
||||
margin-right: 0.7rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
157
src/component/HomePage/collectionModal.vue
Normal file
@@ -0,0 +1,157 @@
|
||||
<template>
|
||||
<div v-if="showCollectionModal">
|
||||
<a-modal class="modal_component collection_modal"
|
||||
v-model:visible="showCollectionModal"
|
||||
:footer="null"
|
||||
width="80%"
|
||||
:maskClosable="false"
|
||||
:centered="true"
|
||||
>
|
||||
<template #title>
|
||||
<div v-show="collectionStep === 1">Moodboard Upload</div>
|
||||
<div v-show="collectionStep === 2"><span class="icon iconfont icon-fanhui header_icon_fanhui" @click="lastStep()"></span>Printboard Upload</div>
|
||||
<div v-show="collectionStep === 3"><span class="icon iconfont icon-fanhui header_icon_fanhui" @click="lastStep()"></span>Colorboard Upload</div>
|
||||
<div v-show="collectionStep === 4"><span class="icon iconfont icon-fanhui header_icon_fanhui" @click="lastStep()"></span>Sketchboard Upload</div>
|
||||
<div v-show="collectionStep === 5"><span class="icon iconfont icon-fanhui header_icon_fanhui" @click="lastStep()"></span>Markets Sketch</div>
|
||||
</template>
|
||||
<template #closeIcon>
|
||||
<div class="header_right_block" @click.stop="">
|
||||
<div v-if="collectionStep < 5" class="next_step_button" @click.stop="nextStep()">Next Step</div>
|
||||
<div v-else class="next_step_button" @click.stop="finishCollection()">Finish</div>
|
||||
<div class="header_cancel_button" @click.stop="cancelDsign()">Cancel</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="collection_modal_body">
|
||||
<MoodboardUpload ref="MoodboardUpload" v-show="collectionStep === 1"></MoodboardUpload>
|
||||
<PrintboardUpload ref="PrintboardUpload" v-show="collectionStep === 2"></PrintboardUpload>
|
||||
<ColorboardUpload ref="ColorboardUpload" v-show="collectionStep === 3"></ColorboardUpload>
|
||||
<SketchboardUpload ref="SketchboardUpload" v-show="collectionStep === 4"></SketchboardUpload>
|
||||
<MarketingSketchUpload ref="MarketingSketchUpload" v-show="collectionStep === 5"></MarketingSketchUpload>
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent ,createVNode } from 'vue'
|
||||
import MoodboardUpload from '@/component/HomePage/MoodboardUpload.vue'
|
||||
import PrintboardUpload from '@/component/HomePage/PrintboardUpload.vue'
|
||||
import ColorboardUpload from '@/component/HomePage/ColorboardUpload.vue'
|
||||
import SketchboardUpload from '@/component/HomePage/SketchboardUpload.vue'
|
||||
import MarketingSketchUpload from '@/component/HomePage/MarketingSketchUpload.vue'
|
||||
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
||||
import { Modal,message } from 'ant-design-vue';
|
||||
import {useStore} from 'vuex'
|
||||
export default defineComponent({
|
||||
components:{
|
||||
MoodboardUpload,
|
||||
PrintboardUpload,
|
||||
ColorboardUpload,
|
||||
SketchboardUpload,
|
||||
MarketingSketchUpload
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
showCollectionModal:false,
|
||||
collectionStep:1,
|
||||
store:useStore()
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
nextStep(){
|
||||
this.collectionStep = this.collectionStep + 1
|
||||
},
|
||||
|
||||
lastStep(){
|
||||
this.collectionStep = this.collectionStep - 1
|
||||
},
|
||||
changeCollectionModal(type:boolean){
|
||||
this.showCollectionModal = type
|
||||
},
|
||||
|
||||
recollection(){
|
||||
setTimeout(()=>{
|
||||
let childredCom = ['MoodboardUpload','PrintboardUpload','ColorboardUpload','SketchboardUpload','MarketingSketchUpload']
|
||||
for(let child of childredCom){
|
||||
let childRef:any = this.$refs[child]
|
||||
childRef.recollection()
|
||||
}
|
||||
},200)
|
||||
|
||||
},
|
||||
|
||||
|
||||
//取消
|
||||
cancelDsign(){
|
||||
let _this = this
|
||||
Modal.confirm({
|
||||
title: 'The uploaded files will not be saved, being sure to continue? ',
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
okText: 'Yes',
|
||||
cancelText: 'No',
|
||||
// centered:true,
|
||||
onOk() {
|
||||
_this.showCollectionModal = false
|
||||
_this.store.commit('clearAllData')
|
||||
_this.collectionStep = 1
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
//完成
|
||||
finishCollection(){
|
||||
let colorBoards = this.store.state.UploadFilesModule.colorBoards
|
||||
if(!colorBoards || colorBoards?.length < 1){
|
||||
message.error('You must choose one or more colors for further process.')
|
||||
return
|
||||
}
|
||||
this.showCollectionModal =false
|
||||
this.collectionStep = 1
|
||||
this.$emit('finishCollection')
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.collection_modal{
|
||||
.header_icon_fanhui{
|
||||
margin-right: 1rem;
|
||||
font-size: 2rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
.header_right_block{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
right: 2.1rem;
|
||||
height: 100%;
|
||||
|
||||
.next_step_button{
|
||||
padding: 0 1.2rem;
|
||||
height: 3.2rem;
|
||||
background: #343579;
|
||||
font-size: 1.4rem;
|
||||
color: #FFFFFF;
|
||||
line-height: 3.2rem;
|
||||
margin-right: 1.6rem;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.header_cancel_button{
|
||||
padding: 0 2.1rem;
|
||||
height: 3.2rem;
|
||||
background: #E4E5EB;
|
||||
font-size: 1.4rem;
|
||||
color: #030303;
|
||||
line-height: 3.2rem;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.collection_modal_body{
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
708
src/component/LibraryPage/ModelPlacement.vue
Normal file
@@ -0,0 +1,708 @@
|
||||
<template>
|
||||
<div v-show="placementShow">
|
||||
<a-modal class="models_placement_component"
|
||||
v-model:visible="placementShow"
|
||||
:footer="null"
|
||||
width="111.5rem"
|
||||
:maskClosable="false"
|
||||
:centered="true"
|
||||
>
|
||||
<template #closeIcon>
|
||||
<div class="close_icon" @click.stop="closeModal()"><span class="icon iconfont icon-guanbi"></span></div>
|
||||
</template>
|
||||
<div class="models_placement_body" >
|
||||
<div class="palcement_modal_header">
|
||||
<div class="models_placement_title">Registration</div>
|
||||
<div class="placement_operate_list">
|
||||
<div class="operate_item" v-show="locationList.length == 6" @click="submitPlacement">
|
||||
<div class="icon iconfont icon-baocun1 operate_icon"></div>
|
||||
<div class="operate_item_des">Submit</div>
|
||||
</div>
|
||||
<div class="operate_item" v-show="locationList.length == 6" @click="printPreview">
|
||||
<div class="icon iconfont icon-shengchengyulan operate_icon"></div>
|
||||
<div class="operate_item_des">Preview</div>
|
||||
</div>
|
||||
<div class="operate_item" v-show="perviewUrl" @click="backPreview">
|
||||
<div class="icon iconfont icon-fanhui1 operate_icon"></div>
|
||||
<div class="operate_item_des">Back</div>
|
||||
</div>
|
||||
<div class="operate_item" @click="restoreLocationList">
|
||||
<div class="icon iconfont icon-huifu operate_icon"></div>
|
||||
<div class="operate_item_des">Restore</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="models_placement_content">
|
||||
<div class="plcaement_point_content">
|
||||
<div class="placement_point_item" v-for="(point,index) in pointList" :key="index" >
|
||||
<div class="ponit_title">{{point.title}}</div>
|
||||
<div class="point_list">
|
||||
<div class="point_item" v-for="item in point.pointList" :key="item.color" :style="{borderColor:item.color,visibility:item.show?'inherit':'hidden'}" @mousedown="AddDian(item)"><div class="point_block" :style="{background:item.color}"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="placement_content_operate_list">
|
||||
<div class="placement_content_operate_item" @click="changeRemoveStatus">
|
||||
<div class="placement_remove_point_block"></div>
|
||||
<div class="placement_content_operate_des">Remove Point</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="placement_tip_content">Please change the pure white inside the mannequin for another color to enhance your experience</div>
|
||||
|
||||
<div class="img_preview_block" >
|
||||
<div class="perview_mark_loading" v-show="isShowMark">
|
||||
<a-spin size="large" />
|
||||
</div>
|
||||
<div class="img_content_block" ref="imgbox" @mousemove="startMove($event)">
|
||||
<img class="placement_img" :src="perviewUrl || printObject?.url">
|
||||
<div :class="['ponit_click',isRemoveStatus?'remove_point_click':'']" v-show="!perviewUrl" v-for="(item,index) in locationList" :key="item" :style="{left:item.left+'px', top:item.top+'px',borderColor:item.color}" @mousedown="getMouseDown($event,item,index)" @mousemove="startMove($event)">
|
||||
<div class="placement_add_point_content" :style="{background:item.color}" v-show="!isRemoveStatus"></div>
|
||||
<div class="icon iconfont icon-guanbi" v-show="isRemoveStatus"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent,ref,createVNode} from 'vue'
|
||||
import { Https } from "@/tool/https";
|
||||
import {dataURLtoFile} from "@/tool/util"
|
||||
import { useStore } from "vuex";
|
||||
import { Modal,message } from 'ant-design-vue';
|
||||
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const store = useStore()
|
||||
let oldLocationList:any = ref([])
|
||||
let locationList:any = ref([])
|
||||
let printObject:any = ref({})
|
||||
let imgBox:any = ref({})
|
||||
let intObj:any = ref(null)
|
||||
let currentSign:any = ref({})
|
||||
let oldPointList:any = ref([]) //备份点
|
||||
let pointList:any = ref([])
|
||||
let isSubmit:any = ref(false) //判断历史是否有提交过
|
||||
return {
|
||||
store,
|
||||
oldLocationList,
|
||||
locationList,
|
||||
printObject,
|
||||
imgBox,
|
||||
intObj,
|
||||
currentSign,
|
||||
oldPointList,
|
||||
pointList,
|
||||
isSubmit
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
placementShow:false,
|
||||
collectionIndex:0,
|
||||
startDian:false,
|
||||
moveOriginal:{posX: 0, posY: 0},
|
||||
isRemoveStatus:false,
|
||||
placement_sacle:30,
|
||||
perviewUrl:'',//预览的图片地址
|
||||
isShowMark:false,
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
formatter(value:number){
|
||||
return `${value}%`;
|
||||
},
|
||||
|
||||
showPlacementModal(data:any){
|
||||
this.placementShow = true
|
||||
this.printObject = {
|
||||
...data
|
||||
}
|
||||
setTimeout(()=>{
|
||||
let imgbox:any = this.$refs.imgbox
|
||||
let position = imgbox.getBoundingClientRect()
|
||||
this.imgBox = {
|
||||
width:imgbox.clientWidth,
|
||||
height:imgbox.scrollHeight,
|
||||
left : position.left,
|
||||
top:position.top,
|
||||
scrollTop:imgbox.scrollTop || 0,
|
||||
}
|
||||
this.getDefaultPointList(this.imgBox)
|
||||
},500)
|
||||
},
|
||||
|
||||
//初始化可以使用的点位
|
||||
getDefaultPointList(imgBox:any){
|
||||
this.isSubmit = false
|
||||
this.pointList = [
|
||||
{
|
||||
title:'SHOULDER',
|
||||
pointList:[{type:'shoulderLeft',color:'#6E70FF',show:true,field:'shoulder'},{type:'shoulderRight',color:'#6E70FF',show:true,field:'shoulder'}]
|
||||
},
|
||||
{
|
||||
title:'WAISTBAND',
|
||||
pointList:[{type:'waistbandLeft',color:'#6FCEFF',show:true,field:'waistband'},{type:'waistbandRight',color:'#6FCEFF',show:true,field:'waistband'}]
|
||||
},
|
||||
{
|
||||
title:'HAND',
|
||||
pointList:[{type:'handLeft',color:'#CCFF7B',show:true,field:'hand'},{type:'handRight',color:'#CCFF7B',show:true,field:'hand'}]
|
||||
},
|
||||
]
|
||||
if(this.printObject.templateId){//编辑
|
||||
this.isSubmit = true
|
||||
for(let ponit of this.pointList){
|
||||
for(let pointItem of ponit.pointList){
|
||||
if(this.printObject[pointItem.type]?.length){
|
||||
pointItem.show = false
|
||||
let data = {
|
||||
left:this.printObject[pointItem.type][0] * imgBox.width - 12,
|
||||
top:this.printObject[pointItem.type][1] * imgBox.height - 12,
|
||||
color:pointItem.color,
|
||||
type:pointItem.type,
|
||||
field:pointItem.field,
|
||||
}
|
||||
this.locationList.push(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
this.oldLocationList = JSON.parse(JSON.stringify(this.locationList))
|
||||
|
||||
}
|
||||
|
||||
this.oldPointList = JSON.parse(JSON.stringify(this.pointList))
|
||||
},
|
||||
|
||||
|
||||
AddDian(point:any){
|
||||
if(!point.show){
|
||||
return
|
||||
}
|
||||
this.startDian = true
|
||||
this.isRemoveStatus = false
|
||||
this.intObj = point
|
||||
},
|
||||
|
||||
changeRemoveStatus(){
|
||||
this.isRemoveStatus = true
|
||||
},
|
||||
|
||||
startMove(event:any){
|
||||
if(this.isRemoveStatus){
|
||||
return
|
||||
}
|
||||
let imgbox:any = this.$refs.imgbox
|
||||
let scrollTop = imgbox.scrollTop;
|
||||
if(this.intObj){
|
||||
this.currentSign.left = event.clientX - this.imgBox.left
|
||||
this.currentSign.top = event.clientY + scrollTop - this.imgBox.top
|
||||
this.currentSign.color = this.intObj.color
|
||||
this.currentSign.type= this.intObj.type
|
||||
this.currentSign.field = this.intObj.field
|
||||
this.locationList.push(this.currentSign)
|
||||
this.intObj.show = false
|
||||
this.intObj = null
|
||||
}else{
|
||||
if(this.startDian){
|
||||
this.currentSign.left = event.clientX - this.imgBox.left - this.moveOriginal.posX
|
||||
this.currentSign.top = event.clientY + scrollTop - this.imgBox.top -this.moveOriginal.posY
|
||||
document.addEventListener('mouseup', this.getMouseOver);
|
||||
this.$forceUpdate()
|
||||
this.setBoundarySign()
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
// 在边界上的签名域处理
|
||||
setBoundarySign() {
|
||||
let imgbox:any = this.$refs.imgbox
|
||||
let height = imgbox.offsetHeight + imgbox.scrollTop;
|
||||
// 2 为签名域的边框
|
||||
let maxPosHeight = height - 24
|
||||
let maxPosWidth = imgbox.clientWidth - 24 //+ this.signBox.paddLeft;
|
||||
if (this.currentSign.top <= 0) {
|
||||
this.currentSign.top = 0
|
||||
} else if (this.currentSign.top >= maxPosHeight ) {
|
||||
this.currentSign.top = maxPosHeight;
|
||||
}
|
||||
if (this.currentSign.left <= 0) {
|
||||
this.currentSign.left = 0
|
||||
} else if (this.currentSign.left >= maxPosWidth) {
|
||||
this.currentSign.left = maxPosWidth;
|
||||
}
|
||||
},
|
||||
|
||||
getMouseDown(event:any,item:any,index:number){
|
||||
if(this.isRemoveStatus){
|
||||
for(let itemPoint of this.pointList){
|
||||
for(let point of itemPoint.pointList){
|
||||
if(item.type == point.type){
|
||||
point.show = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
this.locationList.splice(index,1)
|
||||
}else{
|
||||
this.currentSign = item
|
||||
// 计算出鼠标在签名域上的偏移
|
||||
this.moveOriginal.posX = event.offsetX
|
||||
this.moveOriginal.posY = event.offsetY // 1为边框
|
||||
this.startDian = true
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
getMouseOver(){
|
||||
this.startDian = false
|
||||
this.currentSign = {}
|
||||
document.removeEventListener('mouseup', this.getMouseOver);
|
||||
},
|
||||
|
||||
closeModal(){
|
||||
let _this = this
|
||||
if(!this.isSubmit){
|
||||
Modal.confirm({
|
||||
title: "You haven't marked the image yet, and the model will not be uploaded. Are you sure you want to close it?",
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
okText: 'Ok',
|
||||
cancelText: 'Cancel',
|
||||
// centered:true,
|
||||
onOk() {
|
||||
// _this.getDefaultPointList(_this.imgBox)
|
||||
_this.oldLocationList = []
|
||||
_this.locationList = []
|
||||
_this.intObj = null
|
||||
_this.currentSign = {}
|
||||
_this.isRemoveStatus = false
|
||||
_this.placementShow = false
|
||||
_this.perviewUrl = ''
|
||||
}
|
||||
});
|
||||
}else{
|
||||
// _this.getDefaultPointList(_this.imgBox)
|
||||
_this.oldLocationList = []
|
||||
_this.locationList = []
|
||||
_this.intObj = null
|
||||
_this.currentSign = {}
|
||||
_this.isRemoveStatus = false
|
||||
_this.placementShow = false
|
||||
_this.perviewUrl = ''
|
||||
}
|
||||
},
|
||||
|
||||
restoreLocationList(){
|
||||
this.pointList = JSON.parse(JSON.stringify(this.oldPointList))
|
||||
this.locationList = JSON.parse(JSON.stringify(this.oldLocationList))
|
||||
},
|
||||
|
||||
submitPlacement(){
|
||||
if(this.printObject.templateId){
|
||||
this.printObject.id = this.printObject.libraryId
|
||||
this.confrimSubmit()
|
||||
}else{
|
||||
this.customRequest().then((rv:any)=>{
|
||||
this.isShowMark = false
|
||||
this.printObject.id = rv.id
|
||||
this.confrimSubmit()
|
||||
}).catch((res:any)=>{
|
||||
this.isShowMark = false
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
confrimSubmit(){
|
||||
let param = {
|
||||
libraryId:this.printObject.id,
|
||||
templateId:this.printObject.templateId || null,
|
||||
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
...this.getPrintLocation()
|
||||
}
|
||||
this.isShowMark = true
|
||||
Https.axiosPost(Https.httpUrls.saveOrEditTemplatePoint, param).then(
|
||||
(rv: any) => {
|
||||
this.isShowMark = false
|
||||
this.isSubmit = true
|
||||
this.$emit('submitModelPlacement')
|
||||
this.closeModal()
|
||||
}
|
||||
).catch(res=>{
|
||||
this.isShowMark = false
|
||||
});
|
||||
},
|
||||
|
||||
customRequest(){
|
||||
let new_data = {
|
||||
file:this.printObject.file,
|
||||
level1Type:'Models',
|
||||
level2Type:'',
|
||||
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
}
|
||||
this.isShowMark = true
|
||||
return new Promise((resolve,reject)=>{
|
||||
Https.axiosPost(Https.httpUrls.libraryUpload, new_data,{headers:{'Content-Type': 'multipart/form-data'}}).then(
|
||||
(rv: any) => {
|
||||
resolve(rv)
|
||||
}
|
||||
).catch((res)=>{
|
||||
reject(res)
|
||||
});
|
||||
})
|
||||
|
||||
},
|
||||
|
||||
getPrintLocation(){
|
||||
let {width , height} = this.imgBox
|
||||
let locationData:any = {}
|
||||
let returnData:any = {}
|
||||
let newLocationList = JSON.parse(JSON.stringify(this.locationList))
|
||||
//进行字段归类
|
||||
for(let item of newLocationList){
|
||||
locationData[item.field] = locationData[item.field] || []
|
||||
locationData[item.field].push(item)
|
||||
}
|
||||
for(let key in locationData){
|
||||
locationData[key].sort(this.sortBy("left")) //通过left字段进行排序
|
||||
locationData[key].forEach((v:any,index:any) => {
|
||||
v.type = !index ?v.field + 'Left' :v.field +'Right' //第一个是left,第二个是right
|
||||
v.left = ((v.left + 12) / width).toFixed(4)
|
||||
v.top = ((v.top + 12) / height).toFixed(4)
|
||||
returnData[v.type] = [v.left, v.top]
|
||||
});
|
||||
}
|
||||
return returnData
|
||||
},
|
||||
|
||||
sortBy(field:any) {
|
||||
return function(a:any,b:any) {
|
||||
return a[field] - b[field];
|
||||
}
|
||||
},
|
||||
|
||||
printPreview(){
|
||||
let file = this.printObject.templateId ? null :this.printObject.file,
|
||||
models = {
|
||||
libraryId:this.printObject.libraryId || null,
|
||||
templateId:this.printObject.templateId || null,
|
||||
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
...this.getPrintLocation()
|
||||
}
|
||||
let formData = new FormData();
|
||||
formData.append('file', file);
|
||||
formData.append("models", new Blob([JSON.stringify(models)], {type: "application/json"}));
|
||||
if(this.isShowMark){
|
||||
return
|
||||
}
|
||||
this.isShowMark = true
|
||||
Https.axiosPost(Https.httpUrls.libraryModelsDot, formData,{headers:{'Content-Type': 'multipart/form-data'}}).then(
|
||||
(rv: any) => {
|
||||
this.perviewUrl = rv
|
||||
this.isShowMark = false
|
||||
}
|
||||
).catch(res=>{
|
||||
this.isShowMark = false
|
||||
});
|
||||
},
|
||||
|
||||
backPreview(){
|
||||
this.perviewUrl = ''
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="less">
|
||||
.models_placement_component{
|
||||
|
||||
.ant-modal-close{
|
||||
width: 3.6rem;
|
||||
height: 3.6rem;
|
||||
position: absolute;
|
||||
top: -1.8rem;
|
||||
right: -1.8rem;
|
||||
}
|
||||
|
||||
.ant-modal-header{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ant-modal-body{
|
||||
background: #F2F3FB;
|
||||
min-height: 72rem;
|
||||
overflow-y: hidden;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.close_icon{
|
||||
width: 3.6rem;
|
||||
height: 3.6rem;
|
||||
background: #000000;
|
||||
border-radius: 50%;
|
||||
line-height: 3.6rem;
|
||||
text-align: center;
|
||||
|
||||
.icon-guanbi{
|
||||
font-size: 2rem;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
.models_placement_body{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.palcement_modal_header{
|
||||
position: relative;
|
||||
height: 6.6rem;
|
||||
width: 100%;
|
||||
background: #F7F7F7;
|
||||
|
||||
.models_placement_title{
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
line-height: 6.6rem;
|
||||
left: 3.7rem;
|
||||
top: 0;
|
||||
font-size: 1.8rem;
|
||||
color: #030303;
|
||||
}
|
||||
.placement_operate_list{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin:0 auto;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
height: 100%;
|
||||
|
||||
.operate_item{
|
||||
margin-right: 4rem;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
|
||||
.operate_icon{
|
||||
font-size: 2.1rem;
|
||||
color: #64686D;
|
||||
}
|
||||
|
||||
.operate_item_des{
|
||||
height: 1.2rem;
|
||||
font-size: 1.3rem;
|
||||
color: #64686D;
|
||||
}
|
||||
&:last-child{
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.models_placement_content{
|
||||
position: relative;
|
||||
height: calc(100% - 6.6rem);
|
||||
width: 100%;
|
||||
padding: 1.1rem 0;
|
||||
|
||||
.plcaement_point_content{
|
||||
width: 22rem;
|
||||
background: #EBECF4;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top:18.4rem;
|
||||
padding: 3rem 2.7rem 0 1.4rem;
|
||||
|
||||
.placement_point_item{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 3rem;
|
||||
|
||||
.ponit_title{
|
||||
font-size: 1.3rem;
|
||||
color: #64686D;
|
||||
user-select:none; /* CSS3属性 */
|
||||
}
|
||||
|
||||
.point_list{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 6.2rem;
|
||||
justify-content: space-between;
|
||||
|
||||
.point_item{
|
||||
width: 2.4rem;
|
||||
height: 2.4rem;
|
||||
border-radius: 50%;
|
||||
border:solid 0.2rem transparent;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
-moz-user-select:none; /* Firefox私有属性 */
|
||||
-webkit-user-select:none; /* WebKit内核私有属性 */
|
||||
-ms-user-select:none; /* IE私有属性(IE10及以后) */
|
||||
-khtml-user-select:none; /* KHTML内核私有属性 */
|
||||
-o-user-select:none; /* Opera私有属性 */
|
||||
user-select:none; /* CSS3属性 */
|
||||
|
||||
|
||||
.point_block{
|
||||
width: 0.4rem;
|
||||
height: 0.4rem;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.placement_content_operate_list{
|
||||
width: 10.6rem;
|
||||
background: #EBECF4;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top:18.4rem;
|
||||
|
||||
.placement_content_operate_item{
|
||||
padding: 1.5rem 0;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
|
||||
|
||||
.placement_content_operate_des{
|
||||
width: 100%;
|
||||
font-size: 1.3rem;
|
||||
color: #64686D;
|
||||
-moz-user-select:none;
|
||||
user-select:none
|
||||
}
|
||||
|
||||
.print_scale_value{
|
||||
height: 1.1rem;
|
||||
font-size: 1.2rem;
|
||||
text-align: center;
|
||||
margin-bottom: 0.3rem;
|
||||
color: #64686D;
|
||||
}
|
||||
|
||||
.ant-tooltip-placement-top{
|
||||
top: -37px !important;
|
||||
}
|
||||
|
||||
.ant-slider-track{
|
||||
background: #343579;
|
||||
}
|
||||
.ant-slider-handle{
|
||||
border-color: #343579;
|
||||
}
|
||||
|
||||
.placement_remove_point_block{
|
||||
width: 2.4rem;
|
||||
height: 2.4rem;
|
||||
border: 2px solid #000000;
|
||||
border-radius: 50%;
|
||||
margin: 0 auto 0.4rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.placement_tip_content{
|
||||
position: absolute;
|
||||
right: 2rem;
|
||||
bottom: 2rem;
|
||||
width: 30rem;
|
||||
font-size: 1.3rem;
|
||||
color: #64686D;
|
||||
}
|
||||
|
||||
.img_preview_block{
|
||||
width: 40.8rem;
|
||||
background: #ffffff;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
user-select:none;
|
||||
-moz-user-select:none;
|
||||
position: relative;
|
||||
|
||||
.img_content_block{
|
||||
width: 40.8rem;
|
||||
height: 100%;
|
||||
max-height: 63.2rem;
|
||||
overflow-y: auto;
|
||||
-ms-overflow-style: none;
|
||||
overflow: -moz-scrollbars-none;
|
||||
position: relative;
|
||||
|
||||
&::-webkit-scrollbar { width: 0 !important }
|
||||
}
|
||||
|
||||
.perview_mark_loading{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
height: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
z-index: 9;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
}
|
||||
|
||||
.placement_img{
|
||||
width: 100%;
|
||||
user-select:none;
|
||||
-moz-user-select:none;
|
||||
}
|
||||
|
||||
.ponit_click{
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
position: absolute;
|
||||
border: 2px solid transparent;
|
||||
border-radius: 50%;
|
||||
-moz-user-select:none; /* Firefox私有属性 */
|
||||
-webkit-user-select:none; /* WebKit内核私有属性 */
|
||||
-ms-user-select:none; /* IE私有属性(IE10及以后) */
|
||||
-khtml-user-select:none; /* KHTML内核私有属性 */
|
||||
-o-user-select:none; /* Opera私有属性 */
|
||||
user-select:none; /* CSS3属性 */
|
||||
cursor: pointer;
|
||||
|
||||
&.remove_point_click{
|
||||
border-color: transparent;
|
||||
background: #EF3C3C;
|
||||
}
|
||||
|
||||
.placement_add_point_content{
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
border-radius: 50%;
|
||||
background: #6E70FF;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.icon-guanbi{
|
||||
font-size: 20px;
|
||||
line-height: 20px;
|
||||
color:#ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
711
src/component/LibraryPage/ModelPlacementMobile.vue
Normal file
@@ -0,0 +1,711 @@
|
||||
<template>
|
||||
<div v-show="placementShow">
|
||||
<a-modal class="models_placement_mobile_component"
|
||||
v-model:visible="placementShow"
|
||||
:footer="null"
|
||||
width="111.5rem"
|
||||
:maskClosable="false"
|
||||
:centered="true"
|
||||
>
|
||||
<template #closeIcon>
|
||||
<div class="close_icon" @click.stop="closeModal()"><span class="icon iconfont icon-guanbi"></span></div>
|
||||
</template>
|
||||
<div class="models_placement_body" >
|
||||
<div class="palcement_modal_header">
|
||||
<div class="models_placement_title">Registration</div>
|
||||
<div class="placement_operate_list">
|
||||
<div class="operate_item" v-show="locationList.length == 6" @click="submitPlacement">
|
||||
<div class="icon iconfont icon-baocun1 operate_icon"></div>
|
||||
<div class="operate_item_des">Submit</div>
|
||||
</div>
|
||||
<div class="operate_item" v-show="locationList.length == 6" @click="printPreview">
|
||||
<div class="icon iconfont icon-shengchengyulan operate_icon"></div>
|
||||
<div class="operate_item_des">Preview</div>
|
||||
</div>
|
||||
<div class="operate_item" v-show="perviewUrl" @click="backPreview">
|
||||
<div class="icon iconfont icon-fanhui1 operate_icon"></div>
|
||||
<div class="operate_item_des">Back</div>
|
||||
</div>
|
||||
<div class="operate_item" @click="restoreLocationList">
|
||||
<div class="icon iconfont icon-huifu operate_icon"></div>
|
||||
<div class="operate_item_des">Restore</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="models_placement_content" @touchmove="startMove($event)">
|
||||
<div class="plcaement_point_content">
|
||||
<div class="placement_point_item" v-for="(point,index) in pointList" :key="index" >
|
||||
<div class="ponit_title">{{point.title}}</div>
|
||||
<div class="point_list">
|
||||
<div class="point_item" v-for="item in point.pointList" :key="item.color" :style="{borderColor:item.color,visibility:item.show?'inherit':'hidden'}" @touchstart="AddDian(item)"><div class="point_block" :style="{background:item.color}"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="placement_content_operate_list">
|
||||
<div class="placement_content_operate_item" @click="changeRemoveStatus">
|
||||
<div class="placement_remove_point_block"></div>
|
||||
<div class="placement_content_operate_des">Remove Point</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="placement_tip_content">Please change the pure white inside the mannequin for another color to enhance your experience</div>
|
||||
|
||||
<div class="img_preview_block" >
|
||||
<div class="perview_mark_loading" v-show="isShowMark">
|
||||
<a-spin size="large" />
|
||||
</div>
|
||||
<div class="img_content_block" ref="imgbox">
|
||||
<img class="placement_img" :src="perviewUrl || printObject?.url">
|
||||
<div :class="['ponit_click',isRemoveStatus?'remove_point_click':'']" v-for="(item,index) in locationList" :key="item" :style="{left:item.left+'px', top:item.top+'px',borderColor:item.color}" @touchstart="getMouseDown($event,item,index)" @touchmove="startMove($event)">
|
||||
<div class="placement_add_point_content" :style="{background:item.color}" v-show="!isRemoveStatus"></div>
|
||||
<div class="icon iconfont icon-guanbi" v-show="isRemoveStatus"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent,ref,createVNode} from 'vue'
|
||||
import { Https } from "@/tool/https";
|
||||
import { useStore } from "vuex";
|
||||
import { Modal,message } from 'ant-design-vue';
|
||||
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const store = useStore()
|
||||
let oldLocationList:any = ref([])
|
||||
let locationList:any = ref([])
|
||||
let printObject:any = ref({})
|
||||
let imgBox:any = ref({})
|
||||
let intObj:any = ref(null)
|
||||
let currentSign:any = ref({})
|
||||
let oldPointList:any = ref([]) //备份点
|
||||
let pointList:any = ref([])
|
||||
let isSubmit:any = ref(false) //判断历史是否有提交过
|
||||
return {
|
||||
store,
|
||||
oldLocationList,
|
||||
locationList,
|
||||
printObject,
|
||||
imgBox,
|
||||
intObj,
|
||||
currentSign,
|
||||
oldPointList,
|
||||
pointList,
|
||||
isSubmit
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
placementShow:false,
|
||||
collectionIndex:0,
|
||||
startDian:false,
|
||||
moveOriginal:{posX: 0, posY: 0},
|
||||
isRemoveStatus:false,
|
||||
placement_sacle:30,
|
||||
perviewUrl:'',//预览的图片地址
|
||||
isShowMark:false,
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
formatter(value:number){
|
||||
return `${value}%`;
|
||||
},
|
||||
|
||||
showPlacementModal(data:any){
|
||||
this.placementShow = true
|
||||
this.printObject = {
|
||||
...data
|
||||
}
|
||||
setTimeout(()=>{
|
||||
let imgbox:any = this.$refs.imgbox
|
||||
let position = imgbox.getBoundingClientRect()
|
||||
this.imgBox = {
|
||||
width:imgbox.clientWidth,
|
||||
height:imgbox.scrollHeight,
|
||||
left : position.left,
|
||||
top:position.top,
|
||||
scrollTop:imgbox.scrollTop || 0,
|
||||
}
|
||||
this.getDefaultPointList(this.imgBox)
|
||||
},400)
|
||||
},
|
||||
|
||||
//初始化可以使用的点位
|
||||
getDefaultPointList(imgBox:any){
|
||||
this.isSubmit = false
|
||||
this.pointList = [
|
||||
{
|
||||
title:'SHOULDER',
|
||||
pointList:[{type:'shoulderLeft',color:'#6E70FF',show:true,field:'shoulder'},{type:'shoulderRight',color:'#6E70FF',show:true,field:'shoulder'}]
|
||||
},
|
||||
{
|
||||
title:'WAISTBAND',
|
||||
pointList:[{type:'waistbandLeft',color:'#6FCEFF',show:true,field:'waistband'},{type:'waistbandRight',color:'#6FCEFF',show:true,field:'waistband'}]
|
||||
},
|
||||
{
|
||||
title:'HAND',
|
||||
pointList:[{type:'handLeft',color:'#CCFF7B',show:true,field:'hand'},{type:'handRight',color:'#CCFF7B',show:true,field:'hand'}]
|
||||
},
|
||||
]
|
||||
if(this.printObject.templateId){//编辑
|
||||
this.isSubmit = true
|
||||
for(let ponit of this.pointList){
|
||||
for(let pointItem of ponit.pointList){
|
||||
if(this.printObject[pointItem.type]?.length){
|
||||
pointItem.show = false
|
||||
let data = {
|
||||
left:this.printObject[pointItem.type][0] * imgBox.width - 12,
|
||||
top:this.printObject[pointItem.type][1] * imgBox.height - 12,
|
||||
color:pointItem.color,
|
||||
type:pointItem.type,
|
||||
field:pointItem.field,
|
||||
}
|
||||
this.locationList.push(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
this.oldLocationList = JSON.parse(JSON.stringify(this.locationList))
|
||||
|
||||
}
|
||||
|
||||
this.oldPointList = JSON.parse(JSON.stringify(this.pointList))
|
||||
},
|
||||
|
||||
|
||||
AddDian(point:any){
|
||||
if(!point.show){
|
||||
return
|
||||
}
|
||||
this.startDian = true
|
||||
this.isRemoveStatus = false
|
||||
this.intObj = point
|
||||
},
|
||||
|
||||
changeRemoveStatus(){
|
||||
this.isRemoveStatus = true
|
||||
},
|
||||
|
||||
startMove(event:any){
|
||||
if(this.isRemoveStatus){
|
||||
return
|
||||
}
|
||||
let imgbox:any = this.$refs.imgbox
|
||||
let scrollTop = imgbox.scrollTop;
|
||||
if(event.targetTouches[0].pageX > this.imgBox.left){
|
||||
if(this.intObj){
|
||||
this.currentSign.left = event.targetTouches[0].pageX - this.imgBox.left
|
||||
this.currentSign.top = event.targetTouches[0].pageY + scrollTop - this.imgBox.top
|
||||
this.currentSign.color = this.intObj.color
|
||||
this.currentSign.type= this.intObj.type
|
||||
this.currentSign.field = this.intObj.field
|
||||
this.locationList.push(this.currentSign)
|
||||
this.intObj.show = false
|
||||
this.intObj = null
|
||||
}else{
|
||||
if(this.startDian){
|
||||
this.currentSign.left = event.targetTouches[0].pageX - this.imgBox.left - this.moveOriginal.posX
|
||||
this.currentSign.top = event.targetTouches[0].pageY + scrollTop - this.imgBox.top -this.moveOriginal.posY
|
||||
document.addEventListener('touchend', this.getMouseOver);
|
||||
this.$forceUpdate()
|
||||
this.setBoundarySign()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
// 在边界上的签名域处理
|
||||
setBoundarySign() {
|
||||
let imgbox:any = this.$refs.imgbox
|
||||
let height = imgbox.offsetHeight + imgbox.scrollTop;
|
||||
// 2 为签名域的边框
|
||||
let maxPosHeight = height - 24
|
||||
let maxPosWidth = imgbox.clientWidth - 24 //+ this.signBox.paddLeft;
|
||||
if (this.currentSign.top <= 0) {
|
||||
this.currentSign.top = 0
|
||||
} else if (this.currentSign.top >= maxPosHeight ) {
|
||||
this.currentSign.top = maxPosHeight;
|
||||
}
|
||||
if (this.currentSign.left <= 0) {
|
||||
this.currentSign.left = 0
|
||||
} else if (this.currentSign.left >= maxPosWidth) {
|
||||
this.currentSign.left = maxPosWidth;
|
||||
}
|
||||
},
|
||||
|
||||
getMouseDown(event:any,item:any,index:number){
|
||||
if(this.isRemoveStatus){
|
||||
for(let itemPoint of this.pointList){
|
||||
for(let point of itemPoint.pointList){
|
||||
if(item.id == point.id){
|
||||
point.show = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
this.locationList.splice(index,1)
|
||||
}else{
|
||||
this.currentSign = item
|
||||
// 计算出鼠标在签名域上的偏移
|
||||
this.moveOriginal.posX = event.targetTouches[0].pageX - this.imgBox.left - this.currentSign.left
|
||||
this.moveOriginal.posY = event.targetTouches[0].pageY - this.imgBox.top- this.currentSign.top // 1为边框
|
||||
this.startDian = true
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
getMouseOver(){
|
||||
this.startDian = false
|
||||
this.currentSign = {}
|
||||
document.removeEventListener('touchend', this.getMouseOver);
|
||||
},
|
||||
|
||||
closeModal(){
|
||||
let _this = this
|
||||
if(!this.isSubmit){
|
||||
Modal.confirm({
|
||||
title: "You haven't marked the image yet, and the model will not be uploaded. Are you sure you want to close it?",
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
okText: 'Ok',
|
||||
cancelText: 'Cancel',
|
||||
// centered:true,
|
||||
onOk() {
|
||||
// _this.getDefaultPointList(_this.imgBox)
|
||||
_this.oldLocationList = []
|
||||
_this.locationList = []
|
||||
_this.intObj = null
|
||||
_this.currentSign = {}
|
||||
_this.isRemoveStatus = false
|
||||
_this.placementShow = false
|
||||
}
|
||||
});
|
||||
}else{
|
||||
// _this.getDefaultPointList(_this.imgBox)
|
||||
_this.oldLocationList = []
|
||||
_this.locationList = []
|
||||
_this.intObj = null
|
||||
_this.currentSign = {}
|
||||
_this.isRemoveStatus = false
|
||||
_this.placementShow = false
|
||||
}
|
||||
},
|
||||
|
||||
restoreLocationList(){
|
||||
this.pointList = JSON.parse(JSON.stringify(this.oldPointList))
|
||||
this.locationList = JSON.parse(JSON.stringify(this.oldLocationList))
|
||||
},
|
||||
|
||||
submitPlacement(){
|
||||
if(this.printObject.templateId){
|
||||
this.printObject.id = this.printObject.libraryId
|
||||
this.confrimSubmit()
|
||||
}else{
|
||||
this.customRequest().then((rv:any)=>{
|
||||
this.isShowMark = false
|
||||
this.printObject.id = rv.id
|
||||
this.confrimSubmit()
|
||||
}).catch((res:any)=>{
|
||||
this.isShowMark = false
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
confrimSubmit(){
|
||||
let param = {
|
||||
libraryId:this.printObject.id,
|
||||
templateId:this.printObject.templateId || null,
|
||||
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
...this.getPrintLocation()
|
||||
}
|
||||
this.isShowMark = true
|
||||
Https.axiosPost(Https.httpUrls.saveOrEditTemplatePoint, param).then(
|
||||
(rv: any) => {
|
||||
this.isShowMark = false
|
||||
this.isSubmit = true
|
||||
this.$emit('submitModelPlacement')
|
||||
this.closeModal()
|
||||
}
|
||||
).catch(res=>{
|
||||
this.isShowMark = false
|
||||
});
|
||||
},
|
||||
|
||||
customRequest(){
|
||||
let new_data = {
|
||||
file:this.printObject.file,
|
||||
level1Type:'Models',
|
||||
level2Type:'',
|
||||
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
}
|
||||
this.isShowMark = true
|
||||
return new Promise((resolve,reject)=>{
|
||||
Https.axiosPost(Https.httpUrls.libraryUpload, new_data,{headers:{'Content-Type': 'multipart/form-data'}}).then(
|
||||
(rv: any) => {
|
||||
resolve(rv)
|
||||
}
|
||||
).catch((res)=>{
|
||||
reject(res)
|
||||
});
|
||||
})
|
||||
|
||||
},
|
||||
|
||||
|
||||
getPrintLocation(){
|
||||
let {width , height} = this.imgBox
|
||||
let locationData:any = {}
|
||||
let returnData:any = {}
|
||||
let newLocationList = JSON.parse(JSON.stringify(this.locationList))
|
||||
//进行字段归类
|
||||
for(let item of newLocationList){
|
||||
locationData[item.field] = locationData[item.field] || []
|
||||
locationData[item.field].push(item)
|
||||
}
|
||||
for(let key in locationData){
|
||||
locationData[key].sort(this.sortBy("left")) //通过left字段进行排序
|
||||
locationData[key].forEach((v:any,index:any) => {
|
||||
v.type = !index ?v.field + 'Left' :v.field +'Right' //第一个是left,第二个是right
|
||||
v.left = ((v.left + 12) / width).toFixed(4)
|
||||
v.top = ((v.top + 12) / height).toFixed(4)
|
||||
returnData[v.type] = [v.left, v.top]
|
||||
});
|
||||
}
|
||||
return returnData
|
||||
},
|
||||
|
||||
sortBy(field:any) {
|
||||
return function(a:any,b:any) {
|
||||
return a[field] - b[field];
|
||||
}
|
||||
},
|
||||
|
||||
printPreview(){
|
||||
// this.printObject.scale = this.placement_sacle / 100
|
||||
// this.printObject.location = this.printObject.ifSingle ? this.getPrintLocation() : []
|
||||
// let designItemDetail = JSON.parse(JSON.stringify(this.store.state.DesignDetailModule.designItemDetail))
|
||||
// designItemDetail.clothes[this.collectionIndex] = this.clothesData
|
||||
// delete designItemDetail.designItemUrl
|
||||
// let priority = designItemDetail.clothes.map((v:any)=>{
|
||||
// return v.type
|
||||
// })
|
||||
// let data = {
|
||||
// ...designItemDetail,
|
||||
// priority:priority,
|
||||
// timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
// }
|
||||
// if(this.isShowMark){
|
||||
// return
|
||||
// }
|
||||
// this.isShowMark = true
|
||||
// Https.axiosPost(Https.httpUrls.detailPrintDot, data).then(
|
||||
// (rv: any) => {
|
||||
// this.perviewUrl = rv
|
||||
// this.isShowMark = false
|
||||
// }
|
||||
// ).catch(res=>{
|
||||
// this.isShowMark = false
|
||||
// });
|
||||
},
|
||||
|
||||
backPreview(){
|
||||
this.perviewUrl = ''
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="less">
|
||||
.models_placement_mobile_component{
|
||||
|
||||
.ant-modal-close{
|
||||
width: 3.6rem;
|
||||
height: 3.6rem;
|
||||
position: absolute;
|
||||
top: -1.8rem;
|
||||
right: -1.8rem;
|
||||
}
|
||||
|
||||
.ant-modal-header{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ant-modal-body{
|
||||
background: #F2F3FB;
|
||||
min-height: 72rem;
|
||||
overflow-y: hidden;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.close_icon{
|
||||
width: 3.6rem;
|
||||
height: 3.6rem;
|
||||
background: #000000;
|
||||
border-radius: 50%;
|
||||
line-height: 3.6rem;
|
||||
text-align: center;
|
||||
|
||||
.icon-guanbi{
|
||||
font-size: 2rem;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
.models_placement_body{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.palcement_modal_header{
|
||||
position: relative;
|
||||
height: 6.6rem;
|
||||
width: 100%;
|
||||
background: #F7F7F7;
|
||||
|
||||
.models_placement_title{
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
line-height: 6.6rem;
|
||||
left: 3.7rem;
|
||||
top: 0;
|
||||
font-size: 1.8rem;
|
||||
color: #030303;
|
||||
}
|
||||
.placement_operate_list{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin:0 auto;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
height: 100%;
|
||||
|
||||
.operate_item{
|
||||
margin-right: 4rem;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
|
||||
.operate_icon{
|
||||
font-size: 2.1rem;
|
||||
color: #64686D;
|
||||
}
|
||||
|
||||
.operate_item_des{
|
||||
height: 1.2rem;
|
||||
font-size: 1.3rem;
|
||||
color: #64686D;
|
||||
}
|
||||
&:last-child{
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.models_placement_content{
|
||||
position: relative;
|
||||
height: calc(100% - 6.6rem);
|
||||
width: 100%;
|
||||
padding: 1.1rem 0;
|
||||
|
||||
.plcaement_point_content{
|
||||
width: 22rem;
|
||||
background: #EBECF4;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top:18.4rem;
|
||||
padding: 3rem 2.7rem 0 1.4rem;
|
||||
|
||||
.placement_point_item{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 3rem;
|
||||
|
||||
.ponit_title{
|
||||
font-size: 1.3rem;
|
||||
color: #64686D;
|
||||
user-select:none; /* CSS3属性 */
|
||||
}
|
||||
|
||||
.point_list{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 6.2rem;
|
||||
justify-content: space-between;
|
||||
|
||||
.point_item{
|
||||
width: 2.4rem;
|
||||
height: 2.4rem;
|
||||
border-radius: 50%;
|
||||
border:solid 0.2rem transparent;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
-moz-user-select:none; /* Firefox私有属性 */
|
||||
-webkit-user-select:none; /* WebKit内核私有属性 */
|
||||
-ms-user-select:none; /* IE私有属性(IE10及以后) */
|
||||
-khtml-user-select:none; /* KHTML内核私有属性 */
|
||||
-o-user-select:none; /* Opera私有属性 */
|
||||
user-select:none; /* CSS3属性 */
|
||||
|
||||
|
||||
.point_block{
|
||||
width: 0.4rem;
|
||||
height: 0.4rem;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.placement_content_operate_list{
|
||||
width: 10.6rem;
|
||||
background: #EBECF4;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top:18.4rem;
|
||||
|
||||
.placement_content_operate_item{
|
||||
padding: 1.5rem 0;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
|
||||
|
||||
.placement_content_operate_des{
|
||||
width: 100%;
|
||||
font-size: 1.3rem;
|
||||
color: #64686D;
|
||||
-moz-user-select:none;
|
||||
user-select:none
|
||||
}
|
||||
|
||||
.print_scale_value{
|
||||
height: 1.1rem;
|
||||
font-size: 1.2rem;
|
||||
text-align: center;
|
||||
margin-bottom: 0.3rem;
|
||||
color: #64686D;
|
||||
}
|
||||
|
||||
.ant-tooltip-placement-top{
|
||||
top: -37px !important;
|
||||
}
|
||||
|
||||
.ant-slider-track{
|
||||
background: #343579;
|
||||
}
|
||||
.ant-slider-handle{
|
||||
border-color: #343579;
|
||||
}
|
||||
|
||||
.placement_remove_point_block{
|
||||
width: 2.4rem;
|
||||
height: 2.4rem;
|
||||
border: 2px solid #000000;
|
||||
border-radius: 50%;
|
||||
margin: 0 auto 0.4rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.placement_tip_content{
|
||||
position: absolute;
|
||||
right: 2rem;
|
||||
bottom: 2rem;
|
||||
width: 30rem;
|
||||
font-size: 1.3rem;
|
||||
color: #64686D;
|
||||
}
|
||||
|
||||
.img_preview_block{
|
||||
width: 40.8rem;
|
||||
background: #ffffff;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
user-select:none;
|
||||
-moz-user-select:none;
|
||||
position: relative;
|
||||
|
||||
.img_content_block{
|
||||
width: 40.8rem;
|
||||
height: 100%;
|
||||
max-height: 63.2rem;
|
||||
overflow-y: auto;
|
||||
-ms-overflow-style: none;
|
||||
overflow: -moz-scrollbars-none;
|
||||
position: relative;
|
||||
|
||||
&::-webkit-scrollbar { width: 0 !important }
|
||||
}
|
||||
|
||||
.perview_mark_loading{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
height: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
z-index: 9;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
}
|
||||
|
||||
.placement_img{
|
||||
width: 100%;
|
||||
user-select:none;
|
||||
-moz-user-select:none;
|
||||
}
|
||||
|
||||
.ponit_click{
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
position: absolute;
|
||||
border: 2px solid transparent;
|
||||
border-radius: 50%;
|
||||
-moz-user-select:none; /* Firefox私有属性 */
|
||||
-webkit-user-select:none; /* WebKit内核私有属性 */
|
||||
-ms-user-select:none; /* IE私有属性(IE10及以后) */
|
||||
-khtml-user-select:none; /* KHTML内核私有属性 */
|
||||
-o-user-select:none; /* Opera私有属性 */
|
||||
user-select:none; /* CSS3属性 */
|
||||
cursor: pointer;
|
||||
|
||||
&.remove_point_click{
|
||||
border-color: transparent;
|
||||
background: #EF3C3C;
|
||||
}
|
||||
|
||||
.placement_add_point_content{
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
border-radius: 50%;
|
||||
background: #6E70FF;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.icon-guanbi{
|
||||
font-size: 20px;
|
||||
line-height: 20px;
|
||||
color:#ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
386
src/component/LibraryPage/ModelsModal.vue
Normal file
@@ -0,0 +1,386 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-modal class="models_modal"
|
||||
v-model:visible="modelsModalShow"
|
||||
:footer="null"
|
||||
width="80%"
|
||||
:maskClosable="false"
|
||||
:centered="true"
|
||||
>
|
||||
<div class="models_header">
|
||||
<div class="models_title">Select Mannequin</div>
|
||||
<div class="models_header_right">
|
||||
<div class="content_search_block">
|
||||
<input class="search_input" placeholder="Search by name" v-model="searchPictureName" @keydown.enter="getLibraryList()">
|
||||
<div class="search_icon_block" @click="getLibraryList()"><span class="icon iconfont icon-sousuo"></span></div>
|
||||
</div>
|
||||
|
||||
<div class="icon iconfont icon-guanbi icon_close" @click="closeModal"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="models_content">
|
||||
|
||||
<div class="models_content_left">
|
||||
<div class="content_left_header">
|
||||
<div class="left_header_title">Current Mannequin</div>
|
||||
<div class="system_button" @click="setSystemModel()">Standard Mannequin</div>
|
||||
</div>
|
||||
<div class="content_left_perview">
|
||||
<img class="perview_img" :src="selectImg"/>
|
||||
</div>
|
||||
<div class="sure_button" @click="confimSure()">ok</div>
|
||||
</div>
|
||||
<div class="models_content_right">
|
||||
<div class="models_content_body scroll_style">
|
||||
<div class="content_img_item" v-for="(img) in imgList" :key="img.id" @click="selectImgItem(img)">
|
||||
<div :class="['content_img_item_block', selectImgListId == img.libraryModelPoint.templateId ? 'select_item_img' :'']">
|
||||
<img :src="img.url" class="content_img"/>
|
||||
</div>
|
||||
<div class="content_img_name">{{img.name}}</div>
|
||||
</div>
|
||||
<div class="no_data_block" v-show="!imgList.length && !isShowLoading">
|
||||
<img src="@/assets/images/homePage/null_img.png">
|
||||
</div>
|
||||
<div class="no_data_block" v-show="isShowLoading">
|
||||
<a-spin size="large"></a-spin>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table_pagination">
|
||||
<a-pagination
|
||||
v-model:current="currentPage"
|
||||
v-model:pageSize="pageSize"
|
||||
:total="total"
|
||||
:showQuickJumper="true"
|
||||
:showSizeChanger="false"
|
||||
@change="changePage"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref} from 'vue'
|
||||
import { Https } from "@/tool/https";
|
||||
import {useStore} from 'vuex'
|
||||
import { message } from 'ant-design-vue';
|
||||
const systemImg = require('../../assets/images/homePage/system_model.png')
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const store = useStore();
|
||||
let searchPictureName = ref('')
|
||||
let modelsModalShow = ref(false)
|
||||
let currentPage:any = ref(1)
|
||||
let pageSize = ref(12)
|
||||
let total = ref(0)
|
||||
let imgList:any = ref([])
|
||||
let isShowLoading:any = ref(false)
|
||||
let selectImgListId:any = ref('')
|
||||
let selectImg:any = ref('')
|
||||
|
||||
return{
|
||||
store,
|
||||
searchPictureName,
|
||||
modelsModalShow,
|
||||
currentPage,
|
||||
pageSize,
|
||||
total,
|
||||
imgList,
|
||||
isShowLoading,
|
||||
selectImgListId,
|
||||
selectImg
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
|
||||
init(code:any){
|
||||
this.modelsModalShow = true
|
||||
this.selectImg = this.store.state.HomeStoreModule.templateImgUrl || systemImg
|
||||
this.selectImgListId = this.store.state.HomeStoreModule.templateId
|
||||
this.getLibraryList()
|
||||
},
|
||||
|
||||
selectImgItem(imgData:any){
|
||||
this.selectImgListId = imgData.libraryModelPoint.templateId
|
||||
this.selectImg = imgData.url
|
||||
},
|
||||
|
||||
|
||||
//改变页码
|
||||
changePage(current: number, pageSize: number){
|
||||
this.currentPage = current
|
||||
this.pageSize = pageSize
|
||||
this.getLibraryList()
|
||||
},
|
||||
|
||||
getLibraryList(){
|
||||
let data = {
|
||||
level1Type:'Models',
|
||||
level2Type:'',
|
||||
page:this.currentPage,
|
||||
pictureName:this.searchPictureName,
|
||||
size:this.pageSize,
|
||||
}
|
||||
this.isShowLoading = true
|
||||
Https.axiosPost(Https.httpUrls.queryLibraryPage,data).then(
|
||||
(rv: any) => {
|
||||
this.imgList = rv.content
|
||||
this.total = rv.total
|
||||
this.isShowLoading = false
|
||||
}
|
||||
).catch((res)=>{
|
||||
this.isShowLoading = false
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
|
||||
closeModal(){
|
||||
this.modelsModalShow = false
|
||||
this.searchPictureName = ''
|
||||
this.imgList = []
|
||||
this.currentPage = 1
|
||||
this.pageSize = 10
|
||||
this.total = 0
|
||||
},
|
||||
|
||||
setSystemModel(){
|
||||
this.selectImg = systemImg
|
||||
this.selectImgListId = ''
|
||||
},
|
||||
|
||||
//确定选择model
|
||||
confimSure(){
|
||||
this.$emit('sureSelectModel',{id:this.selectImgListId,url:this.selectImg})
|
||||
this.closeModal()
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="less">
|
||||
.models_modal{
|
||||
|
||||
.ant-modal-close{
|
||||
width: 3.6rem;
|
||||
height: 3.6rem;
|
||||
position: absolute;
|
||||
top: -1.8rem;
|
||||
right: -1.8rem;
|
||||
}
|
||||
|
||||
.ant-modal-header{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ant-modal-body{
|
||||
background: #F2F3FB;
|
||||
height: 80vh;
|
||||
min-height: 72rem;
|
||||
overflow-y: hidden;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.models_header{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 6.6rem;
|
||||
background: #F7F7F7;
|
||||
padding: 0 3.4rem 0 3rem;
|
||||
|
||||
.models_title{
|
||||
font-size: 1.8rem;
|
||||
color: #030303;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.models_header_right{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.content_search_block{
|
||||
margin-right: 5rem;
|
||||
display: flex;
|
||||
|
||||
.search_input{
|
||||
width: 30rem;
|
||||
padding-left: 1.5rem;
|
||||
height: 4rem;
|
||||
line-height: 3.8rem;
|
||||
background: #FFFFFF;
|
||||
border: 0.1rem solid #F1F1F1;
|
||||
font-size: 1.6rem;
|
||||
font-weight: 400;
|
||||
|
||||
&::placeholder {
|
||||
color: #C2C2C2;
|
||||
}
|
||||
}
|
||||
|
||||
.search_icon_block{
|
||||
width: 6rem;
|
||||
height: 4rem;
|
||||
line-height: 4rem;
|
||||
text-align: center;
|
||||
background: #343579;
|
||||
cursor: pointer;
|
||||
|
||||
.icon-sousuo{
|
||||
font-size: 2rem;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon_close{
|
||||
color: rgba(174, 178, 183, 1);
|
||||
font-size: 2.4rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
.models_content{
|
||||
padding-right: 1.4rem;
|
||||
height: calc(100% - 6.6rem);
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.models_content_left{
|
||||
width: 36.4rem;
|
||||
height: 100%;
|
||||
background: #FFFFFF;
|
||||
flex-shrink: 0;
|
||||
|
||||
.content_left_header{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 1.3rem 1rem 0.9rem 3rem;
|
||||
|
||||
.left_header_title{
|
||||
font-size: 1.6rem;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.system_button{
|
||||
padding: 0 1rem;
|
||||
height: 3.2rem;
|
||||
line-height: 3.2rem;
|
||||
background: #E6E6F6;
|
||||
font-size: 1.2rem;
|
||||
color: #343579;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.content_left_perview{
|
||||
width: 100%;
|
||||
height: calc(100% - 13.8rem);
|
||||
padding: 1.9rem 3rem 0;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 1.3rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.perview_img{
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.sure_button{
|
||||
width: 9.8rem;
|
||||
height: 3.6rem;
|
||||
background: #343579;
|
||||
font-size: 1.4rem;
|
||||
color: #FFFFFF;
|
||||
text-align: center;
|
||||
line-height: 3.6rem;
|
||||
margin: 0 auto;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.models_content_right{
|
||||
width: calc(100% - 37rem);
|
||||
height: 100%;
|
||||
background: #FFFFFF;
|
||||
padding: 1.5rem 1rem 1rem 1rem;
|
||||
|
||||
.models_content_body{
|
||||
width: 100%;
|
||||
height: calc(100% - 6rem);
|
||||
overflow-y: auto;
|
||||
|
||||
.content_img_item{
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
padding: 0 0.91rem;
|
||||
margin-bottom: 1rem;
|
||||
|
||||
.content_img_item_block{
|
||||
border: 0.1rem solid #F5F5F5;;
|
||||
width: 16.5rem;
|
||||
height: 25.1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
|
||||
&.select_item_img{
|
||||
border-color: #343579;
|
||||
}
|
||||
|
||||
.content_img{
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
}
|
||||
.content_img_name{
|
||||
width: 16.5rem;
|
||||
height: 3.4rem;
|
||||
line-height: 3.4rem;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 1.4rem;
|
||||
color: #030303;
|
||||
}
|
||||
}
|
||||
|
||||
.no_data_block{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.table_pagination{
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
130
src/component/LoginPage/verificationCodeInput.vue
Normal file
@@ -0,0 +1,130 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<div class="captcha">
|
||||
<input v-for="(c, index) in getCtData" :key="index"
|
||||
v-model="getCtData[index]" ref="input"
|
||||
@input="e => {onInput(e.target.value, index)}"
|
||||
@keydown.delete="e=>{onKeydown(e.target.value, index)}"
|
||||
@focus="onFocus"
|
||||
:disabled="loading"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
props:['ct'],
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getCtData(){
|
||||
return this.ct
|
||||
},
|
||||
ctSize() {
|
||||
return this.getCtData.length;
|
||||
},
|
||||
cIndex() {
|
||||
let i = this.getCtData.findIndex(item => item === '');
|
||||
i = (i + this.ctSize) % this.ctSize;
|
||||
return i;
|
||||
},
|
||||
lastCode() {
|
||||
return this.getCtData[this.ctSize - 1];
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
cIndex() {
|
||||
this.resetCaret();
|
||||
},
|
||||
lastCode(val) {
|
||||
if (val) {
|
||||
this.$refs.input[this.ctSize - 1].blur();
|
||||
this.sendCaptcha();
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.resetCaret();
|
||||
},
|
||||
methods: {
|
||||
onInput(val, index) {
|
||||
val = val.replace(/\D/g, '');
|
||||
if (index == this.ctSize - 1) {
|
||||
this.getCtData[this.ctSize - 1] = val[0]; // 最后一个码,只允许输入一个字符。
|
||||
} else if(val.length > 1) {
|
||||
let i = index;
|
||||
for (i = index; i < this.ctSize && i - index < val.length; i++) {
|
||||
this.getCtData[i] = val[i];
|
||||
}
|
||||
this.resetCaret();
|
||||
}else if(!(val+'')){
|
||||
this.getCtData[index] = ''
|
||||
}
|
||||
},
|
||||
// 重置光标位置。
|
||||
resetCaret() {
|
||||
this.$refs.input[this.ctSize-1].focus();
|
||||
},
|
||||
onFocus() {
|
||||
// 监听 focus 事件,将光标重定位到“第一个空白符的位置”。
|
||||
let index = this.getCtData.findIndex(item => item === '');
|
||||
index = (index + this.ctSize) % this.ctSize;
|
||||
this.$refs.input[index].focus();
|
||||
},
|
||||
onKeydown(val, index) {
|
||||
if (val === '') {
|
||||
// 删除上一个input里的值,并对其focus。
|
||||
if (index > 0) {
|
||||
this.getCtData[index - 1] = '';
|
||||
this.$refs.input[index - 1].focus();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
sendCaptcha() {
|
||||
let password = this.getCtData.map(item => item).join('');
|
||||
this.$emit('sendCaptcha',password)
|
||||
},
|
||||
|
||||
reset() {
|
||||
// 重置。一般是验证码错误时触发。
|
||||
this.getCtData = this.getCtData.map(item => '');
|
||||
this.resetCaret();
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.captcha {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
input {
|
||||
width: 4.8rem;
|
||||
height: 4.8rem;
|
||||
border: 0.1rem solid #B4BED7;
|
||||
border-radius: 0.8rem;
|
||||
text-align: center;
|
||||
font-size: 2.4rem;
|
||||
line-height: 4.8rem;
|
||||
outline: none;
|
||||
}
|
||||
input:last-of-type {
|
||||
margin-right: 0;
|
||||
}
|
||||
input:disabled {
|
||||
color: #000;
|
||||
background-color: #fff;
|
||||
}
|
||||
.msg {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
</style>
|
||||
19
src/main.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import store from './store'
|
||||
import './assets/iconfont/iconfont.css'
|
||||
import './assets/iconfont/iconfont.js'
|
||||
import flexible from './tool/flexible.js'
|
||||
import 'ant-design-vue/dist/antd.css';
|
||||
import Antd from 'ant-design-vue';
|
||||
import './assets/style/style.less'
|
||||
import VueLazyload from "vue-lazyload";
|
||||
flexible()
|
||||
|
||||
let loadingParam = {
|
||||
loading: require('./assets/images/homePage/loading.gif'),
|
||||
attempt: 1
|
||||
}
|
||||
|
||||
createApp(App).use(store).use(router).use(Antd).use(VueLazyload,loadingParam).mount('#app')
|
||||
43
src/router/index.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
|
||||
import { defineAsyncComponent } from 'vue'
|
||||
const _import = (path : string) => defineAsyncComponent(() => import(`../views/${path}.vue`));
|
||||
|
||||
const routes: Array<RouteRecordRaw> = [
|
||||
{
|
||||
path: "/",
|
||||
// redirect重定向
|
||||
redirect: "/login"
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
name: 'login',
|
||||
component: _import('LoginPage')
|
||||
},
|
||||
{
|
||||
path: '/home',
|
||||
name: 'home',
|
||||
component: _import('HomeView')
|
||||
},
|
||||
{
|
||||
path: '/demo',
|
||||
name: 'demo',
|
||||
component: _import('Demo')
|
||||
},
|
||||
{
|
||||
path: '/history',
|
||||
name: 'history',
|
||||
component: _import('HistoryPage')
|
||||
},
|
||||
{
|
||||
path: '/library',
|
||||
name: 'library',
|
||||
component: _import('LibraryPage')
|
||||
},
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(process.env.BASE_URL),
|
||||
routes
|
||||
})
|
||||
|
||||
export default router
|
||||
7
src/shims-vue.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/* eslint-disable */
|
||||
declare module '*.vue' {
|
||||
import type { DefineComponent } from 'vue'
|
||||
const component: DefineComponent<{}, {}, any>
|
||||
export default component
|
||||
}
|
||||
declare module '@ans1998/vue3-color'
|
||||
30
src/store/Detail/designDetail.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import {Module} from 'vuex'
|
||||
import {RootState} from '../index'
|
||||
|
||||
interface DesignDetail{
|
||||
designItemDetail:any,
|
||||
|
||||
}
|
||||
|
||||
const DesignDetailModule : Module<DesignDetail,RootState> = {
|
||||
state:{
|
||||
designItemDetail:{}
|
||||
},
|
||||
mutations:{
|
||||
setDesignItemDetail(state,files){
|
||||
state.designItemDetail = files
|
||||
},
|
||||
setDesignItemColthes(state,data){
|
||||
state.designItemDetail.clothes[data.index] = data.clothes
|
||||
},
|
||||
setDesignItemOthers(state,data){
|
||||
state.designItemDetail.others[data.index] = data.others
|
||||
},
|
||||
|
||||
},
|
||||
actions:{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export default DesignDetailModule
|
||||
92
src/store/homeStore/homeStore.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
import {Module} from 'vuex'
|
||||
import {RootState} from '../index'
|
||||
|
||||
interface DesignDetail{
|
||||
designCollectionList:any,
|
||||
likeDesignCollectionList:any,
|
||||
userGroupId:any,
|
||||
designCollectionId:any,
|
||||
templateId:any,
|
||||
templateImgUrl:any,
|
||||
designId:any,
|
||||
|
||||
}
|
||||
|
||||
const HomeStoreModule : Module<DesignDetail,RootState> = {
|
||||
state:{
|
||||
designCollectionList:[],
|
||||
likeDesignCollectionList:[],
|
||||
userGroupId:'',
|
||||
designCollectionId:'',
|
||||
templateId:'',
|
||||
templateImgUrl:'',
|
||||
designId:'',
|
||||
|
||||
},
|
||||
mutations:{
|
||||
setDesignCollectionList(state,data){
|
||||
state.designCollectionList = data
|
||||
},
|
||||
setLikeDesignCollectionList(state,data){
|
||||
state.likeDesignCollectionList = data
|
||||
},
|
||||
setSingleDesignCollectionList(state,data){
|
||||
state.designCollectionList[data.index] = data.design
|
||||
},
|
||||
setSingleLikeDesignCollectionList(state,data){
|
||||
state.likeDesignCollectionList[data.index] = data.design
|
||||
},
|
||||
addDesignCollectionList(state,data){
|
||||
state.designCollectionList.push(data)
|
||||
},
|
||||
addLikeDesignCollectionList(state,data){
|
||||
state.likeDesignCollectionList.push(data)
|
||||
},
|
||||
deleteDesignCollectionList(state,index){
|
||||
state.designCollectionList.splice(index,1)
|
||||
},
|
||||
deleteLikeDesignCollectionList(state,index){
|
||||
state.likeDesignCollectionList.splice(index,1)
|
||||
},
|
||||
setUserGroupId(state,data){
|
||||
state.userGroupId = data
|
||||
},
|
||||
deleteUserGroupId(state){
|
||||
state.userGroupId = ''
|
||||
},
|
||||
setDesignCollectionId(state,data){
|
||||
state.designCollectionId = data
|
||||
},
|
||||
deleteDesignCollectionId(state,data){
|
||||
state.designCollectionId = ''
|
||||
},
|
||||
setDesignId(state,data){
|
||||
state.designId = data
|
||||
},
|
||||
deleteDesignId(state){
|
||||
state.designId = ''
|
||||
},
|
||||
clearAllCollection(state){
|
||||
state.designCollectionList=[]
|
||||
state.likeDesignCollectionList = []
|
||||
state.designCollectionId = ''
|
||||
},
|
||||
setTemplateData(state,data){
|
||||
state.templateId=data.id
|
||||
state.templateImgUrl = data.url
|
||||
},
|
||||
clearTemplateData(state){
|
||||
state.templateId= ''
|
||||
state.templateImgUrl = ''
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
},
|
||||
actions:{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export default HomeStoreModule
|
||||
23
src/store/index.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { createStore } from 'vuex'
|
||||
import UploadFilesModule from './uploadFile/uploadFile'
|
||||
import DesignDetailModule from './Detail/designDetail'
|
||||
import HomeStoreModule from './homeStore/homeStore'
|
||||
export interface RootState{
|
||||
|
||||
}
|
||||
|
||||
export default createStore<RootState>({
|
||||
state: {
|
||||
},
|
||||
getters: {
|
||||
},
|
||||
mutations: {
|
||||
},
|
||||
actions: {
|
||||
},
|
||||
modules: {
|
||||
UploadFilesModule,
|
||||
DesignDetailModule,
|
||||
HomeStoreModule
|
||||
}
|
||||
})
|
||||
80
src/store/uploadFile/uploadFile.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import {Module} from 'vuex'
|
||||
import {RootState} from '../index'
|
||||
|
||||
interface UploadFiles{
|
||||
moodboardFiles:any,
|
||||
printboardFiles:any,
|
||||
generatePrintFiles:any,
|
||||
colorBoards:any,
|
||||
skecthboardFiles:any,
|
||||
marketingSketchFiles:any,
|
||||
allBoardData:any, //备份的所有数据,点finish之后备份
|
||||
moodTemplateId:any,
|
||||
}
|
||||
|
||||
const UploadFilesModule : Module<UploadFiles,RootState> = {
|
||||
state:{
|
||||
moodboardFiles:[],
|
||||
printboardFiles:[],
|
||||
generatePrintFiles:[],
|
||||
colorBoards:[],
|
||||
skecthboardFiles:[],
|
||||
marketingSketchFiles:[],
|
||||
allBoardData:{},
|
||||
moodTemplateId:'',
|
||||
},
|
||||
mutations:{
|
||||
setMoodboardFile(state,files){
|
||||
state.moodboardFiles = files
|
||||
},
|
||||
setPrintboardFile(state,files){
|
||||
state.printboardFiles = files
|
||||
},
|
||||
setGeneratePrintFile(state,files){
|
||||
state.generatePrintFiles = files
|
||||
},
|
||||
setColorboardList(state,colorBoards){
|
||||
state.colorBoards = colorBoards
|
||||
},
|
||||
setSketchboardFile(state,files){
|
||||
state.skecthboardFiles = files
|
||||
},
|
||||
setMarketingSketchFile(state,files){
|
||||
state.marketingSketchFiles = files
|
||||
},
|
||||
setAllBoardData(state){
|
||||
state.allBoardData = {
|
||||
moodboardFiles:state.moodboardFiles,
|
||||
printboardFiles:state.printboardFiles,
|
||||
generatePrintFiles:state.generatePrintFiles,
|
||||
colorBoards:state.colorBoards,
|
||||
skecthboardFiles:state.skecthboardFiles,
|
||||
marketingSketchFiles:state.marketingSketchFiles,
|
||||
moodTemplateId:state.moodTemplateId,
|
||||
}
|
||||
},
|
||||
setAllBoardDataChoose(state,data){
|
||||
state.allBoardData = data
|
||||
},
|
||||
clearAllData(state){
|
||||
state.moodboardFiles = []
|
||||
state.printboardFiles = []
|
||||
state.generatePrintFiles=[]
|
||||
state.colorBoards = []
|
||||
state.skecthboardFiles = []
|
||||
state.marketingSketchFiles = []
|
||||
state.moodTemplateId = ''
|
||||
},
|
||||
setMoodTemplateId(state,moodTemplateId){
|
||||
state.moodTemplateId = moodTemplateId
|
||||
},
|
||||
clearMoodTemplateId(state){
|
||||
state.moodTemplateId = ''
|
||||
},
|
||||
},
|
||||
actions:{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export default UploadFilesModule
|
||||
147
src/tool/colorthief/colorthief.js
Normal file
@@ -0,0 +1,147 @@
|
||||
import quantize from 'quantize';
|
||||
import core from './core.js';
|
||||
|
||||
/*
|
||||
* Color Thief v2.3.2
|
||||
* by Lokesh Dhakar - http://www.lokeshdhakar.com
|
||||
*
|
||||
* Thanks
|
||||
* ------
|
||||
* Nick Rabinowitz - For creating quantize.js.
|
||||
* John Schulz - For clean up and optimization. @JFSIII
|
||||
* Nathan Spady - For adding drag and drop support to the demo page.
|
||||
*
|
||||
* License
|
||||
* -------
|
||||
* Copyright Lokesh Dhakar
|
||||
* Released under the MIT license
|
||||
* https://raw.githubusercontent.com/lokesh/color-thief/master/LICENSE
|
||||
*
|
||||
* @license
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
CanvasImage Class
|
||||
Class that wraps the html image element and canvas.
|
||||
It also simplifies some of the canvas context manipulation
|
||||
with a set of helper functions.
|
||||
*/
|
||||
|
||||
const CanvasImage = function (image) {
|
||||
this.canvas = document.createElement('canvas');
|
||||
this.context = this.canvas.getContext('2d');
|
||||
this.width = this.canvas.width = image.naturalWidth;
|
||||
this.height = this.canvas.height = image.naturalHeight;
|
||||
this.context.drawImage(image, 0, 0, this.width, this.height);
|
||||
};
|
||||
|
||||
CanvasImage.prototype.getImageData = function () {
|
||||
return this.context.getImageData(0, 0, this.width, this.height);
|
||||
};
|
||||
|
||||
var ColorThief = function () {};
|
||||
|
||||
/*
|
||||
* getColor(sourceImage[, quality])
|
||||
* returns {r: num, g: num, b: num}
|
||||
*
|
||||
* Use the median cut algorithm provided by quantize.js to cluster similar
|
||||
* colors and return the base color from the largest cluster.
|
||||
*
|
||||
* Quality is an optional argument. It needs to be an integer. 1 is the highest quality settings.
|
||||
* 10 is the default. There is a trade-off between quality and speed. The bigger the number, the
|
||||
* faster a color will be returned but the greater the likelihood that it will not be the visually
|
||||
* most dominant color.
|
||||
*
|
||||
* */
|
||||
ColorThief.prototype.getColor = function(sourceImage, quality = 10) {
|
||||
const palette = this.getPalette(sourceImage, 5, quality);
|
||||
const dominantColor = palette[0];
|
||||
return dominantColor;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* getPalette(sourceImage[, colorCount, quality])
|
||||
* returns array[ {r: num, g: num, b: num}, {r: num, g: num, b: num}, ...]
|
||||
*
|
||||
* Use the median cut algorithm provided by quantize.js to cluster similar colors.
|
||||
*
|
||||
* colorCount determines the size of the palette; the number of colors returned. If not set, it
|
||||
* defaults to 10.
|
||||
*
|
||||
* quality is an optional argument. It needs to be an integer. 1 is the highest quality settings.
|
||||
* 10 is the default. There is a trade-off between quality and speed. The bigger the number, the
|
||||
* faster the palette generation but the greater the likelihood that colors will be missed.
|
||||
*
|
||||
*
|
||||
*/
|
||||
ColorThief.prototype.getPalette = function(sourceImage, colorCount, quality) {
|
||||
const options = core.validateOptions({
|
||||
colorCount,
|
||||
quality
|
||||
});
|
||||
|
||||
// Create custom CanvasImage object
|
||||
const image = new CanvasImage(sourceImage);
|
||||
const imageData = image.getImageData();
|
||||
const pixelCount = image.width * image.height;
|
||||
|
||||
const pixelArray = core.createPixelArray(imageData.data, pixelCount, options.quality);
|
||||
|
||||
// Send array to quantize function which clusters values
|
||||
// using median cut algorithm
|
||||
const cmap = quantize(pixelArray, options.colorCount);
|
||||
const palette = cmap? cmap.palette() : null;
|
||||
|
||||
return palette;
|
||||
};
|
||||
|
||||
ColorThief.prototype.getColorFromUrl = function(imageUrl, callback, quality) {
|
||||
const sourceImage = document.createElement("img");
|
||||
|
||||
sourceImage.addEventListener('load' , () => {
|
||||
const palette = this.getPalette(sourceImage, 5, quality);
|
||||
const dominantColor = palette[0];
|
||||
callback(dominantColor, imageUrl);
|
||||
});
|
||||
sourceImage.src = imageUrl
|
||||
};
|
||||
|
||||
|
||||
ColorThief.prototype.getImageData = function(imageUrl, callback) {
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', imageUrl, true);
|
||||
xhr.responseType = 'arraybuffer';
|
||||
xhr.onload = function() {
|
||||
if (this.status == 200) {
|
||||
let uInt8Array = new Uint8Array(this.response);
|
||||
i = uInt8Array.length;
|
||||
let binaryString = new Array(i);
|
||||
for (let i = 0; i < uInt8Array.length; i++){
|
||||
binaryString[i] = String.fromCharCode(uInt8Array[i]);
|
||||
}
|
||||
let data = binaryString.join('');
|
||||
let base64 = window.btoa(data);
|
||||
callback ('data:image/png;base64,' + base64);
|
||||
}
|
||||
}
|
||||
xhr.send();
|
||||
};
|
||||
|
||||
ColorThief.prototype.getColorAsync = function(imageUrl, callback, quality) {
|
||||
const thief = this;
|
||||
this.getImageData(imageUrl, function(imageData){
|
||||
const sourceImage = document.createElement("img");
|
||||
sourceImage.addEventListener('load' , function(){
|
||||
const palette = thief.getPalette(sourceImage, 5, quality);
|
||||
const dominantColor = palette[0];
|
||||
callback(dominantColor, this);
|
||||
});
|
||||
sourceImage.src = imageData;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
export default ColorThief;
|
||||
47
src/tool/colorthief/core.js
Normal file
@@ -0,0 +1,47 @@
|
||||
function createPixelArray(imgData, pixelCount, quality) {
|
||||
const pixels = imgData;
|
||||
const pixelArray = [];
|
||||
|
||||
for (let i = 0, offset, r, g, b, a; i < pixelCount; i = i + quality) {
|
||||
offset = i * 4;
|
||||
r = pixels[offset + 0];
|
||||
g = pixels[offset + 1];
|
||||
b = pixels[offset + 2];
|
||||
a = pixels[offset + 3];
|
||||
|
||||
// If pixel is mostly opaque and not white
|
||||
if (typeof a === 'undefined' || a >= 125) {
|
||||
if (!(r > 250 && g > 250 && b > 250)) {
|
||||
pixelArray.push([r, g, b]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return pixelArray;
|
||||
}
|
||||
|
||||
function validateOptions(options) {
|
||||
let { colorCount, quality } = options;
|
||||
|
||||
if (typeof colorCount === 'undefined' || !Number.isInteger(colorCount)) {
|
||||
colorCount = 10;
|
||||
} else if (colorCount === 1 ) {
|
||||
throw new Error('colorCount should be between 2 and 20. To get one color, call getColor() instead of getPalette()');
|
||||
} else {
|
||||
colorCount = Math.max(colorCount, 2);
|
||||
colorCount = Math.min(colorCount, 20);
|
||||
}
|
||||
|
||||
if (typeof quality === 'undefined' || !Number.isInteger(quality) || quality < 1) {
|
||||
quality = 10;
|
||||
}
|
||||
|
||||
return {
|
||||
colorCount,
|
||||
quality
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
createPixelArray,
|
||||
validateOptions
|
||||
};
|
||||
30
src/tool/cookie.js
Normal file
@@ -0,0 +1,30 @@
|
||||
const setCookie = (name,value) => {
|
||||
var Days = 30;
|
||||
var exp = new Date();
|
||||
exp.setTime(exp.getTime() + Days*24*60*60*30);
|
||||
document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString();
|
||||
}
|
||||
|
||||
const getCookie = (name) => {
|
||||
var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)");
|
||||
if(arr=document.cookie.match(reg))
|
||||
return unescape(arr[2]);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
function WriteCookie(name) {
|
||||
var now = new Date();
|
||||
now.setMonth( now.getMonth() - 1 );
|
||||
cookievalue = escape(document.myform.customer.value) + ";"
|
||||
|
||||
document.cookie = name + '=' + cookievalue;
|
||||
document.cookie = "expires=" + now.toUTCString() + ";"
|
||||
document.write("Setting Cookies : " + "name=" + cookievalue );
|
||||
}
|
||||
|
||||
export {
|
||||
setCookie,
|
||||
getCookie,
|
||||
WriteCookie
|
||||
}
|
||||
43
src/tool/flexible.js
Normal file
@@ -0,0 +1,43 @@
|
||||
let flexible = (designWidth, maxWidth) =>{
|
||||
var doc = document, win = window, docEl = doc.documentElement, remStyle = document.createElement("style"), tid;
|
||||
designWidth = designWidth || 1440;
|
||||
maxWidth = maxWidth || 1440;
|
||||
function refreshRem() {
|
||||
var width = docEl.getBoundingClientRect().width;
|
||||
maxWidth = maxWidth || 1440;
|
||||
width > maxWidth && (width = maxWidth);
|
||||
var rem = width * 10 / designWidth;
|
||||
remStyle.innerHTML = 'html{font-size:' + rem + 'px;}';
|
||||
}
|
||||
if (docEl.firstElementChild) {
|
||||
docEl.firstElementChild.appendChild(remStyle);
|
||||
} else {
|
||||
var wrap = doc.createElement("div");
|
||||
wrap.appendChild(remStyle);
|
||||
doc.write(wrap.innerHTML);
|
||||
wrap = null;
|
||||
}
|
||||
//要等 wiewport 设置好后才能执行 refreshRem,不然 refreshRem 会执行2次;
|
||||
refreshRem();
|
||||
win.addEventListener("resize", function() {
|
||||
clearTimeout(tid); //防止执行两次
|
||||
tid = setTimeout(refreshRem, 300);
|
||||
}, false);
|
||||
|
||||
win.addEventListener("pageshow", function(e) {
|
||||
if (e.persisted) { // 浏览器后退的时候重新计算
|
||||
clearTimeout(tid);
|
||||
tid = setTimeout(refreshRem, 300);
|
||||
}
|
||||
}, false);
|
||||
|
||||
if (doc.readyState === "complete") {
|
||||
doc.body.style.fontSize = "16px";
|
||||
} else {
|
||||
doc.addEventListener("DOMContentLoaded", function(e) {
|
||||
doc.body.style.fontSize = "16px";
|
||||
}, false);
|
||||
}
|
||||
};
|
||||
|
||||
export default flexible
|
||||
139
src/tool/https.js
Normal file
@@ -0,0 +1,139 @@
|
||||
import axios from 'axios'
|
||||
// import qs from 'qs'
|
||||
// import message from '@/components/public/message/src'
|
||||
|
||||
import router from '@/router/index'
|
||||
import {getCookie} from '@/tool/cookie'
|
||||
// import cookie from '@/tools/cookie.js'
|
||||
|
||||
axios.defaults.timeout = 60000; //响应时间
|
||||
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'; //配置请求头
|
||||
axios.defaults.withCredentials = true; //跨域携带cookie
|
||||
import { message } from 'ant-design-vue';
|
||||
axios.defaults.baseURL = process.env.VUE_APP_BASE_URL; //配置接口地址
|
||||
|
||||
//POST传参序列化(添加请求拦截器)
|
||||
axios.interceptors.request.use((config) => {
|
||||
//在发送请求之前做某件事
|
||||
if(config.method === 'post' || config.method === 'put' || config.method === 'delete'){
|
||||
// config.data = qs.stringify(config.data);
|
||||
// config.data = JSON.stringify(config.data);
|
||||
}
|
||||
|
||||
config.headers.Authorization = getCookie('token');
|
||||
return config;
|
||||
},(error) =>{
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
//返回状态判断(添加响应拦截器)
|
||||
axios.interceptors.response.use((res) =>{
|
||||
if (res.data) {
|
||||
if (res.data.errCode === 0) {
|
||||
return Promise.resolve(res.data.data);
|
||||
|
||||
} else {
|
||||
message.error(res.data.errMsg)
|
||||
return Promise.reject(res.data);
|
||||
}
|
||||
} else {
|
||||
message.error(res.data.errMsg)
|
||||
return Promise.reject(res.data);
|
||||
}
|
||||
|
||||
}, function(error) {
|
||||
if(error?.response?.status === 401){
|
||||
router.replace('/login')
|
||||
return Promise.reject()
|
||||
}
|
||||
let data_new = error?.response?.data
|
||||
message.error(data_new?.errMsg || 'Error: server exception')
|
||||
return Promise.reject(data_new);
|
||||
|
||||
});
|
||||
|
||||
export const Https = {
|
||||
httpUrls: {
|
||||
interfaceUrl: '',
|
||||
accountIsLogin:'/api/account/isLogin', //判断用户是否登录
|
||||
accountLogin:'/api/account/login', //账号密码登录接口
|
||||
preLogin:'/api/account/preLogin',//预先登入
|
||||
accountSendEmail:'/api/account/sendEmail', //发送邮件
|
||||
accountResetPwd:'/api/account/resetPwd', //忘记密码修改
|
||||
accountLogout:'/api/account/logout',//登出
|
||||
accountBindEmail:'/api/account/bindEmail', //绑定邮箱
|
||||
elementGeneratePrint:'/api/element/generatePrint', //生成印花
|
||||
elementSavePrint:'/api/element/savePrint',//保存印花
|
||||
getRgbByTcx:'/api/element/getRgbByTcx', // 通过hsv值获取潘通信息
|
||||
getRgbByHsv:'/api/element/getRgbByHsv', //通过hsv值获取潘通信息
|
||||
designCollection:'/api/design/designCollection', //设计 Conllection
|
||||
reDesignCollection:'/api/design/reDesignCollection',//重新设计 Conllection
|
||||
countDesignProcess:'/api/design/countDesignProcess', //统计design进度
|
||||
getRgbByHsvBatch:'/api/element/getRgbByHsvBatch', //通过hsv值数组批量获取潘通信息
|
||||
designLike:'/api/design/like', //Design Like
|
||||
designDislike: '/api/design/dislike', //Design Dislike
|
||||
queryUserGroup:'/api/history/queryUserGroup', //History用户分页分组列表
|
||||
deleteUserGroup:'/api/history/deleteUserGroup', //History删除用户分组
|
||||
updateUserGroupName:'/api/history/updateUserGroupName', //History修改用户分组名
|
||||
historyChoose:'/api/history/choose', //History choose
|
||||
getDesignDetail:'/api/design/detail/getDetail',//查询design详情
|
||||
generateHighDesign:'/api/design/detail/generateHighDesign',//生成高级design图片
|
||||
getNextSysElement:'/api/design/detail/getNextSysElement',//切换系统的element
|
||||
detailPrintDot:'/api/design/detail/printDot',//print打点预览
|
||||
designSingle:'/api/design/detail/designSingle',//单个design
|
||||
queryLibraryPage:'/api/library/queryLibraryPage',//Library分页列表
|
||||
libraryUpload:'/api/library/upload', // Library文件上传
|
||||
batchUpdateLibraryName:'/api/library/batchUpdateLibraryName',//Library修改用户文件名
|
||||
batchDeleteLibrary:'/api/library/batchDeleteLibrary',//删除library
|
||||
queryLibraryTopAndBottomPage:'/api/library/queryLibraryTopAndBottomPage',//Library分页列表(查询top和bottom)
|
||||
deleteHighDesign:'/api/design/detail/deleteHighDesign',//删除高级design图片
|
||||
saveOrEditTemplatePoint:'/api/library/saveOrEditTemplatePoint',//保存或者编辑template打点
|
||||
libraryModelsDot:'/api/library/modelsDot',//Models打点预览
|
||||
|
||||
},
|
||||
|
||||
axiosGet(url,config) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios.get(url,config).then(response => {
|
||||
resolve(response)
|
||||
}).catch((error) => {
|
||||
reject(error)
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
axiosPut(url, data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios.put(url, data).then(response => {
|
||||
resolve(response)
|
||||
}).catch((error) => {
|
||||
reject(error)
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
axiosPost(url, data,config) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios.post(url, data,config).then(response => {
|
||||
resolve(response)
|
||||
}).catch((error) => {
|
||||
reject(error)
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
axiosDelete(url, newData) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios.delete(url,{data:newData}).then(response => {
|
||||
resolve(response)
|
||||
}).catch((error) => {
|
||||
reject(error)
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
141
src/tool/util.js
Normal file
@@ -0,0 +1,141 @@
|
||||
const isEmail = (email)=>{
|
||||
let reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/
|
||||
let result = reg.test(email)
|
||||
return result
|
||||
}
|
||||
|
||||
const getUploadUrl = () =>{
|
||||
let url = process.env.VUE_APP_BASE_URL || ''
|
||||
return url
|
||||
}
|
||||
|
||||
function dataURLtoBlob(dataurl) {
|
||||
var arr = dataurl.split(',');
|
||||
var mime = arr[0].match(/:(.*?);/)[1];
|
||||
var bstr =atob(arr[1]);
|
||||
var n = bstr.length;
|
||||
var u8arr =new Uint8Array(n);
|
||||
while (n--) {
|
||||
u8arr[n] = bstr.charCodeAt(n);
|
||||
}
|
||||
return new Blob([u8arr], {type: mime });
|
||||
}
|
||||
|
||||
function blobToFile(blob, fileName){
|
||||
blob.lastModifiedDate =new Date();
|
||||
blob.name = fileName;
|
||||
return blob;
|
||||
}
|
||||
|
||||
function dataURLtoFile(dataurl, filename){
|
||||
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
|
||||
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
|
||||
while(n--){
|
||||
u8arr[n] = bstr.charCodeAt(n);
|
||||
}
|
||||
var blob = dataURLtoBlob(dataurl);
|
||||
return blobToFile(blob, filename);
|
||||
}
|
||||
|
||||
const base64toFile = (dataurl, filename = 'file') => {
|
||||
let arr = dataurl.split(',')
|
||||
let mime = arr[0].match(/:(.*?);/)[1]
|
||||
let suffix = mime.split('/')[1]
|
||||
let bstr = atob(arr[1])
|
||||
let n = bstr.length
|
||||
let u8arr = new Uint8Array(n)
|
||||
while (n--) {
|
||||
u8arr[n] = bstr.charCodeAt(n)
|
||||
}
|
||||
return new File([u8arr], `${filename}.${suffix}`, {
|
||||
type: mime
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
function rgbToHsv([R, G, B]) {
|
||||
R /= 255
|
||||
G /= 255
|
||||
B /= 255
|
||||
const max = Math.max(R, G, B)
|
||||
const min = Math.min(R, G, B)
|
||||
const range = max - min
|
||||
let V = max
|
||||
let S = V === 0 ? 0 : range / V
|
||||
let H = 0
|
||||
if (R === V) H = (60 * (G - B)) / range
|
||||
if (G === V) H = 120 + (60 * (B - R)) / range
|
||||
if (B === V) H = 240 + (60 * (R - G)) / range
|
||||
|
||||
if (range === 0) H = 0
|
||||
if (H < 0) H += 360
|
||||
H = (H / 2) * (256 / 180)
|
||||
S *= 255
|
||||
V *= 255
|
||||
|
||||
H = parseInt(H)
|
||||
S = parseInt(S)
|
||||
V = parseInt(V)
|
||||
return [H, S, V]
|
||||
}
|
||||
|
||||
const formatTime = (timestamp, fmt) =>{
|
||||
// date = new Date(), fmt = 'MM/dd/yyyy';
|
||||
let date = new Date();
|
||||
date.setTime(timestamp * 1000);
|
||||
|
||||
if (!fmt) {
|
||||
formatRule ? (fmt = formatRule) : (fmt = "YYYY-MM-DD hh:mm:ss");
|
||||
}
|
||||
// console.log(formatRule)
|
||||
let o = {
|
||||
'M+': date.getMonth() + 1, // 月份
|
||||
'D+': date.getDate(), // 日
|
||||
'h+': date.getHours(), // 小时
|
||||
'm+': date.getMinutes(), // 分
|
||||
's+': date.getSeconds(), // 秒
|
||||
'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
|
||||
'S+': date.getMilliseconds(), // 毫秒
|
||||
'a': date.getHours() > 12
|
||||
? 'PM'
|
||||
: 'AM' // 上午还是下午
|
||||
};
|
||||
if (/(Y+)/.test(fmt)) {
|
||||
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
|
||||
}
|
||||
if(/(a)/.test(fmt)&&o['h+']>12){
|
||||
o['h+'] = o['h+'] - 12
|
||||
}
|
||||
for (let k in o) {
|
||||
if (new RegExp('(' + k + ')').test(fmt)) {
|
||||
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1)
|
||||
? (o[k])
|
||||
: (('00' + o[k]).substr(('' + o[k]).length)));
|
||||
}
|
||||
}
|
||||
|
||||
return fmt;
|
||||
}
|
||||
|
||||
const isMoible = () => {
|
||||
let is_mobile = navigator.userAgent.toLowerCase().match(/(ipad|ipod|iphone|android|coolpad|mmp|smartphone|midp|wap|xoom|symbian|j2me|blackberry|wince)/i) != null;
|
||||
if(is_mobile){
|
||||
return true
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
export{
|
||||
isEmail,
|
||||
getUploadUrl,
|
||||
dataURLtoFile,
|
||||
blobToFile,
|
||||
base64toFile,
|
||||
rgbToHsv,
|
||||
formatTime,
|
||||
dataURLtoBlob,
|
||||
isMoible,
|
||||
}
|
||||
158
src/views/Demo.vue
Normal file
@@ -0,0 +1,158 @@
|
||||
<template>
|
||||
<div class="move_page">
|
||||
<div class="move_click">
|
||||
<div class="move_click_dian" v-for="i in moveDian" :key="i" :style="{'background':i}" @mousedown="AddDian(i)"></div>
|
||||
</div>
|
||||
<div class="img_block" ref="imgbox" @mousemove="startMove($event)">
|
||||
<img ref="img" src="https://t7.baidu.com/it/u=1956604245,3662848045&fm=193&f=GIF" />
|
||||
<!-- <div class="img_mark"></div> -->
|
||||
<div class="img_click_dian" v-for="item in imgDian" :key="item" :style="{'background':item.color,left:item.left+'px', top:item.top+'px'}" @mousedown="getMouseDown($event,item)" @mousemove="startMove($event)"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent,h,ref} from "vue";
|
||||
export default defineComponent({
|
||||
data(){
|
||||
return{
|
||||
moveDian:['red','yellow'],
|
||||
imgDian:[],
|
||||
intObj:null,
|
||||
startDian:false,
|
||||
currentSign:{},
|
||||
imgBox:{},
|
||||
moveOriginal:{posX: 0, posY: 0}
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
this.imgBox = {
|
||||
left : this.$refs.imgbox.offsetLeft,
|
||||
top:this.$refs.imgbox.offsetTop,
|
||||
scrollTop:this.$refs.scrollTop || 0,
|
||||
}
|
||||
|
||||
console.log(this.imgBox)
|
||||
},
|
||||
methods:{
|
||||
AddDian(color){
|
||||
this.startDian = true
|
||||
this.intObj = {
|
||||
color:color
|
||||
}
|
||||
console.log(this.intObj)
|
||||
},
|
||||
|
||||
startMove(event){
|
||||
let scrollTop = this.$refs.imgbox.scrollTop;
|
||||
if(this.intObj){
|
||||
this.currentSign.color = this.intObj.color
|
||||
this.currentSign.left = event.clientX - this.imgBox.left
|
||||
this.currentSign.top = event.clientY + scrollTop - this.imgBox.top
|
||||
this.imgDian.push(this.currentSign)
|
||||
console.log(this.currentSign)
|
||||
this.intObj = null
|
||||
}else{
|
||||
if(this.startDian){
|
||||
this.currentSign.left = event.clientX - this.imgBox.left - this.moveOriginal.posX
|
||||
this.currentSign.top = event.clientY + scrollTop - this.imgBox.top -this.moveOriginal.posY
|
||||
document.addEventListener('mouseup', this.getMouseOver);
|
||||
this.$forceUpdate()
|
||||
this.setBoundarySign()
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
// 在边界上的签名域处理
|
||||
setBoundarySign() {
|
||||
let height = this.$refs.imgbox.offsetHeight + this.$refs.imgbox.scrollTop;
|
||||
// 2 为签名域的边框
|
||||
let maxPosHeight = height - 30
|
||||
// console.log(height,maxPosHeight,this.currentSign.pos_params.height)
|
||||
let maxPosWidth = this.$refs.imgbox.clientWidth - 30 //+ this.signBox.paddLeft;
|
||||
if (this.currentSign.top <= 0) {
|
||||
this.currentSign.top = 0
|
||||
} else if (this.currentSign.top >= maxPosHeight ) {
|
||||
this.currentSign.top = maxPosHeight;
|
||||
}
|
||||
if (this.currentSign.left <= 0) {
|
||||
this.currentSign.left = 0
|
||||
} else if (this.currentSign.left >= maxPosWidth) {
|
||||
this.currentSign.left = maxPosWidth;
|
||||
}
|
||||
},
|
||||
|
||||
getMouseDown(event,item){
|
||||
this.currentSign = item
|
||||
// 计算出鼠标在签名域上的偏移
|
||||
this.moveOriginal.posX = event.offsetX
|
||||
// this.moveOriginal.posY = mousedownParam.event.clientY - this.currentSign.pos_params.top - this.signBox.boxTop;
|
||||
this.moveOriginal.posY = event.offsetY // 1为边框
|
||||
this.startDian = true
|
||||
},
|
||||
|
||||
getMouseOver(){
|
||||
this.startDian = false
|
||||
this.currentSign = {}
|
||||
document.removeEventListener('mouseup', this.getMouseOver);
|
||||
document.removeEventListener('touchend', this.getMouseOver);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
.move_page{
|
||||
display: flex;
|
||||
|
||||
}
|
||||
.move_click{
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.move_click_dian{
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 50%;
|
||||
margin-bottom: 60px;
|
||||
cursor: pointer;
|
||||
user-select:none; /* CSS3属性 */
|
||||
}
|
||||
.img_block{
|
||||
position: relative;
|
||||
user-select:none;
|
||||
-moz-user-select:none;
|
||||
overflow-y: auto;
|
||||
background: green;
|
||||
}
|
||||
.img_mark{
|
||||
width: 1200px;
|
||||
height: 600px;
|
||||
background: #ccc;
|
||||
/* width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0; */
|
||||
}
|
||||
img{
|
||||
user-select:none;
|
||||
-moz-user-select:none;
|
||||
width: 700px;
|
||||
}
|
||||
.img_click_dian{
|
||||
position: absolute;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 50%;
|
||||
-moz-user-select:none; /* Firefox私有属性 */
|
||||
-webkit-user-select:none; /* WebKit内核私有属性 */
|
||||
-ms-user-select:none; /* IE私有属性(IE10及以后) */
|
||||
-khtml-user-select:none; /* KHTML内核私有属性 */
|
||||
-o-user-select:none; /* Opera私有属性 */
|
||||
user-select:none; /* CSS3属性 */
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
410
src/views/HistoryPage.vue
Normal file
@@ -0,0 +1,410 @@
|
||||
<template>
|
||||
<div class="history_page">
|
||||
<div class="page_content">
|
||||
<img
|
||||
class="page_content_bg"
|
||||
src="@/assets/images/homePage/bg.png"
|
||||
/>
|
||||
<div class="page_content_body">
|
||||
<HeaderComponent></HeaderComponent>
|
||||
<div class="history_page_body">
|
||||
<div class="history_header">History</div>
|
||||
<div class="history_table_search">
|
||||
<a-range-picker class="range_picker" v-model:value="rangePickerValue" :placeholder="['Start Date', 'End Date']" valueFormat="YYYY-MM-DD">
|
||||
<template #suffixIcon>
|
||||
<span class="icon iconfont range_picker_icon icon-rili"></span>
|
||||
</template>
|
||||
</a-range-picker>
|
||||
<div class="content_search_block">
|
||||
<input class="search_input" placeholder="Search by collection name" v-model="searchCollectionName" @keydown.enter="searchHistoryList()">
|
||||
<div class="search_icon_block" @click="searchHistoryList()"><span class="icon iconfont icon-sousuo"></span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="history_table_content" ref="historyTable">
|
||||
<a-table :columns="columns" :data-source="collectionList" :scroll="{ y: historyTableHeight }" @change="changePage"
|
||||
:pagination="{
|
||||
showSizeChanger:true,
|
||||
current: currentPage,
|
||||
pageSize:pageSize,
|
||||
total: total,
|
||||
showQuickJumper:true,
|
||||
bordered:false
|
||||
}">
|
||||
<template v-slot:action="{record, index}" >
|
||||
<div class="operate_list">
|
||||
<div class="operate_item" @click="turnToDetail(record)">Detail</div>
|
||||
<div class="operate_item" @click="renameCollection(record,index)">Rename</div>
|
||||
<div class="operate_item" @click="retrieveHome(record)">Retrieve</div>
|
||||
<div class="operate_item" @click="deleteGroup(record, index)">Delete</div>
|
||||
</div>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<HistoryDetail ref="historyDetail" :groupDetails="groupDetails" :collectionName="collectionName"></HistoryDetail>
|
||||
|
||||
<a-modal class="rename_modal_component"
|
||||
v-model:visible="renameVisivle"
|
||||
:footer="null"
|
||||
:title="renameData?.name"
|
||||
width="56rem"
|
||||
:maskClosable="false"
|
||||
:centered="true"
|
||||
>
|
||||
<div class="collection_rename_content">
|
||||
<div class="rename_form_content">
|
||||
<input class="rename_form_input" placeholder="Enter a new name" v-model="newCollectionName" @keydown.enter="confrimRename()">
|
||||
</div>
|
||||
<div class="rename_submit_button" @click="confrimRename()">Submit</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent,ref,createVNode} from 'vue'
|
||||
import HeaderComponent from "@/component/HomePage/Header.vue";
|
||||
import HistoryDetail from "@/component/Detail/HistoryDetail.vue";
|
||||
import { Https } from "@/tool/https";
|
||||
import { formatTime } from "@/tool/util"
|
||||
import { Modal,message } from 'ant-design-vue';
|
||||
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
||||
export default defineComponent({
|
||||
components: {
|
||||
HeaderComponent,
|
||||
HistoryDetail,
|
||||
},
|
||||
setup() {
|
||||
let rangePickerValue:any = ref([])
|
||||
let renameData:any = ref({}) //修改名字选中的数据
|
||||
const columns:any = ref([
|
||||
{ title: 'Collections Name', align:'center', ellipsis: true, width: 150, dataIndex: 'name', key: 'collectionName' },
|
||||
{ title: 'Uptate Time', align:'center', ellipsis: true,width: 150, dataIndex: 'updateDate', key: 'updateTime',customRender:(record:any)=>{
|
||||
let time = formatTime(record.text / 1000, 'YYYY-MM-DD hh:mm:ss')
|
||||
return time
|
||||
}},
|
||||
{ title: 'Sketch Counts', align:'center', ellipsis: true, width: 150, dataIndex: 'sketchCount', key: 'sketchCounts' },
|
||||
{
|
||||
title: 'Operations',
|
||||
key: 'operation',
|
||||
align:'center',
|
||||
fixed: 'right',
|
||||
width: 150,
|
||||
slots:{customRender:'action'}
|
||||
},
|
||||
]);
|
||||
let collectionList:any = ref([])
|
||||
return {
|
||||
rangePickerValue,
|
||||
columns,
|
||||
collectionList,
|
||||
renameData,
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
currentPage:1,
|
||||
pageSize:10,
|
||||
total:0,
|
||||
historyTableHeight:0,
|
||||
newCollectionName:'',
|
||||
renameVisivle:false,//修改名字弹窗
|
||||
groupDetails:{},//每个collection的详情
|
||||
collectionName:'',//选中的名字
|
||||
searchCollectionName:'',
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
let historyTable:any = this.$refs.historyTable
|
||||
this.historyTableHeight = historyTable.clientHeight - 130
|
||||
this.getHistoryList()
|
||||
},
|
||||
methods:{
|
||||
turnToDetail(record:any){
|
||||
this.groupDetails = record.groupDetails
|
||||
let historyDetail:any = this.$refs.historyDetail
|
||||
this.collectionName = record.name
|
||||
historyDetail.changeDetailShow()
|
||||
},
|
||||
|
||||
|
||||
//改变页码
|
||||
changePage(e:any){
|
||||
this.currentPage = e.current
|
||||
this.pageSize = e.pageSize
|
||||
this.getHistoryList()
|
||||
},
|
||||
|
||||
//查询列表
|
||||
searchHistoryList(){
|
||||
this.currentPage = 1
|
||||
this.getHistoryList()
|
||||
},
|
||||
|
||||
getHistoryList(){
|
||||
let startDate:any = this.rangePickerValue ? new Date(this.rangePickerValue[0]).getTime(): ''
|
||||
let endDate:any = this.rangePickerValue ? new Date(this.rangePickerValue[1]).getTime(): ''
|
||||
let data = {
|
||||
page:this.currentPage,
|
||||
size:this.pageSize,
|
||||
collectionName:this.searchCollectionName,
|
||||
startDate:startDate,
|
||||
endDate:endDate
|
||||
}
|
||||
Https.axiosPost( Https.httpUrls.queryUserGroup, data).then(
|
||||
(rv: any) => {
|
||||
this.collectionList = rv.content
|
||||
this.total = rv.total
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
//删除分组
|
||||
deleteGroup(record:any,index:number){
|
||||
let deleteGroupFun = (id:any,index:number) =>{
|
||||
let data = {
|
||||
userGroupId:id
|
||||
}
|
||||
Https.axiosPost(Https.httpUrls.deleteUserGroup,data).then(
|
||||
(rv: any) => {
|
||||
message.success('Deleted successfully')
|
||||
this.collectionList.splice(index,1)
|
||||
}
|
||||
);
|
||||
}
|
||||
Modal.confirm({
|
||||
title: 'Do you really want to delete this collection? ',
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
okText: 'Yes',
|
||||
cancelText: 'No',
|
||||
onOk() {
|
||||
deleteGroupFun(record.id,index)
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
//修改名字
|
||||
renameCollection(record:any,index:number){
|
||||
this.renameVisivle = true
|
||||
this.renameData = {
|
||||
...record,
|
||||
index:index
|
||||
}
|
||||
},
|
||||
|
||||
//确定修改名字
|
||||
confrimRename(){
|
||||
let data = {
|
||||
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
userGroupId: this.renameData.id,
|
||||
userGroupName: this.newCollectionName
|
||||
}
|
||||
Https.axiosPost(Https.httpUrls.updateUserGroupName,data).then(
|
||||
(rv: any) => {
|
||||
message.success('Change successfully')
|
||||
this.collectionList[this.renameData.index].name = this.newCollectionName
|
||||
this.collectionList[this.renameData.index].updateDate = rv.updateDate
|
||||
this.renameVisivle = false
|
||||
this.newCollectionName = ''
|
||||
this.renameData = {}
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
retrieveHome(record:any){
|
||||
this.$router.push({name:'home',params: {id:record.id}})
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="less">
|
||||
.history_page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.page_content {
|
||||
position: relative;
|
||||
|
||||
.page_content_bg {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.page_content_body {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
.history_page_body{
|
||||
width: 100%;
|
||||
height: calc(100% - 7rem);
|
||||
padding: 0 2.5rem 4rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
.history_header{
|
||||
font-size: 1.8rem;
|
||||
height: 6.3rem;
|
||||
line-height: 6.3rem;
|
||||
font-weight: 500;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.history_table_search{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.range_picker{
|
||||
width: 36rem;
|
||||
height: 4.8rem;
|
||||
|
||||
.ant-picker-input > input{
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
|
||||
.range_picker_icon{
|
||||
font-size: 2.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.content_search_block{
|
||||
margin-left: 4rem;
|
||||
display: flex;
|
||||
|
||||
.search_input{
|
||||
width: 32.8rem;
|
||||
padding-left: 1.5rem;
|
||||
height: 4.8rem;
|
||||
line-height: 4.6rem;
|
||||
background: #FFFFFF;
|
||||
border: 0.1rem solid #F1F1F1;
|
||||
font-size: 1.6rem;
|
||||
font-weight: 400;
|
||||
|
||||
&::placeholder {
|
||||
color: #C2C2C2;
|
||||
}
|
||||
}
|
||||
|
||||
.search_icon_block{
|
||||
width: 7.2rem;
|
||||
height: 4.8rem;
|
||||
line-height: 4.8rem;
|
||||
text-align: center;
|
||||
background: #343579;
|
||||
cursor: pointer;
|
||||
|
||||
.icon-sousuo{
|
||||
font-size: 2rem;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.history_table_content{
|
||||
margin-top: 2.6rem;
|
||||
width: 100%;
|
||||
height: calc(100% - 13.7rem);
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
padding-bottom: 3rem;
|
||||
|
||||
.ant-table{
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.ant-table-body{
|
||||
overflow-y: auto !important;
|
||||
-ms-overflow-style: none;
|
||||
overflow: -moz-scrollbars-none;
|
||||
|
||||
&::-webkit-scrollbar { width: 0 !important }
|
||||
|
||||
}
|
||||
|
||||
.ant-table-thead > tr > th{
|
||||
background: #FFFFFF;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr > td{
|
||||
border: none;
|
||||
background: transparent;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr{
|
||||
|
||||
&:hover > td{
|
||||
background: #FFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-table-pagination-right{
|
||||
padding-right: 3.5rem;
|
||||
}
|
||||
|
||||
.operate_list{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 1rem;
|
||||
|
||||
.operate_item{
|
||||
font-size: 1.4rem;
|
||||
font-family: Roboto;
|
||||
font-weight: 400;
|
||||
color: #343579;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
.rename_modal_component{
|
||||
|
||||
.collection_rename_content{
|
||||
padding:2rem 9.2rem 3rem;
|
||||
|
||||
|
||||
.rename_form_content{
|
||||
|
||||
.rename_form_input{
|
||||
width: 100%;
|
||||
height: 4.6rem;
|
||||
margin-top: 1rem;
|
||||
border: 0.1rem solid #B4BED7;
|
||||
padding-left: 2.1rem;
|
||||
line-height: 4.6rem;
|
||||
font-size: 1.8rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
&::placeholder {
|
||||
color:#A5B0C2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.rename_submit_button{
|
||||
height: 4.8rem;
|
||||
line-height: 4.8rem;
|
||||
background: #343579;
|
||||
font-size: 2.4rem;
|
||||
font-weight: 500;
|
||||
color: #FFFFFF;
|
||||
width: 16rem;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
margin: 4.5rem auto 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
1106
src/views/HomeView.vue
Normal file
848
src/views/LibraryPage.vue
Normal file
@@ -0,0 +1,848 @@
|
||||
<template>
|
||||
<div class="library_page">
|
||||
<div class="page_content">
|
||||
<img
|
||||
class="page_content_bg"
|
||||
src="@/assets/images/homePage/bg.png"
|
||||
/>
|
||||
<div class="page_content_body">
|
||||
<HeaderComponent></HeaderComponent>
|
||||
<div class="library_page_body">
|
||||
<div class="library_body_left">
|
||||
<div class="library_menu_list" v-for="(menu,index) in menuList" :key="menu.title">
|
||||
<div :class="['menu_item', selectCode==menu.code ? 'select_menu_item' :'']" @click="selectMenuItem(menu,index)">
|
||||
<div class="menu_item_left">
|
||||
<div :class="['icon','iconfont',menu.icon,'type_icon']"></div>
|
||||
<div>{{menu.title}}</div>
|
||||
</div>
|
||||
<div v-show="menu.children.length" :class="['icon','iconfont', 'icon-xiala', menu.showChildren?'icon_rotate':'']"></div>
|
||||
</div>
|
||||
<div v-show="menu.showChildren && menu.children.length">
|
||||
<div :class="['menu_item','child_menu_item', selectCode==child.code ? 'select_menu_item' :'']" v-for="child in menu.children" :key="child.title" @click="selectMenuItem(child,index)">
|
||||
{{child.title}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="library_body_right">
|
||||
<div class="library_right_header">
|
||||
<div class="library_header_left">
|
||||
<div class="header_operate_item operate_select">
|
||||
<a-upload
|
||||
:before-upload="beforeUpload"
|
||||
:customRequest="selectCode != 'Models' ? customRequest : function(){}"
|
||||
:multiple="selectCode != 'Models'"
|
||||
:maxCount="15"
|
||||
accept=".jpg,.png,.jpeg,.bmp"
|
||||
@change="fileUploadChange"
|
||||
>
|
||||
<div>Upload</div>
|
||||
</a-upload>
|
||||
</div>
|
||||
|
||||
|
||||
<div :class="['header_operate_item',selectImgList.length>0?'operate_select':'']" @click="deleteBatchPic()">Delete</div>
|
||||
<div :class="['header_operate_item',selectImgList.length>0?'operate_select':'']" @click="showRenameModal('','batch')">Rename</div>
|
||||
<div class="content_search_block">
|
||||
<input class="search_input" placeholder="Search by your style code" v-model="searchPictureName" @keydown.enter="getLibraryList()">
|
||||
<div class="search_icon_block" @click="getLibraryList()"><span class="icon iconfont icon-sousuo"></span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="librart_headr_right">
|
||||
<div class="select_block" v-show="selectCode == 'Sketchboard' || selectCode == 'MarketingSketch'">
|
||||
<a-select
|
||||
ref="select"
|
||||
v-model:value="designType"
|
||||
:options="disignTypeList"
|
||||
@change="handleChange"
|
||||
>
|
||||
<template #suffixIcon
|
||||
><span
|
||||
class="icon iconfont icon-xiala"
|
||||
style="color: #343579"
|
||||
></span
|
||||
></template>
|
||||
</a-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="libray_right_content">
|
||||
<div class="right_content_body">
|
||||
<div class="content_body_header">
|
||||
<div v-show="imgList.length" :class="['check_all_block',selectImgList.length == imgList.length ? 'check_all' : '']" @click="selectAllImg()">
|
||||
<div class="check_block"><div class="check_block_body" v-show="selectImgList.length == imgList.length && imgList.length"></div></div>
|
||||
<div>all</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content_body_table scroll_style">
|
||||
<div class="content_img_item" v-for="(img,index) in imgList" :key="img.id" @click="selectImgItem(img)">
|
||||
<div :class="['content_img_item_block', selectImgList.indexOf(img.id) > -1 ? 'select_item_img' :'']">
|
||||
<img v-lazy="img.url" :key="img.url" :class="['content_img', ['Moodboard','Printboard'].indexOf(selectCode) > -1 ? 'board_content_img' :'']"/>
|
||||
<div class="img_item_hover">
|
||||
<div class="img_operate_content">
|
||||
<div class="img_operate_block" @click.stop="editPlacementClick(img)" v-show="selectCode === 'Models'">
|
||||
<span class="icon iconfont icon-tianxie operate_icon"></span>
|
||||
</div>
|
||||
<div class="img_operate_block" @click.stop="showRenameModal(img,'single')">
|
||||
<span class="icon iconfont icon-zhongmingming operate_icon"></span>
|
||||
</div>
|
||||
<div class="img_operate_block" @click.stop="deleteSinglePic(img,index)">
|
||||
<span class="icon iconfont icon-shanchu operate_icon"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content_img_name">{{img.name}}</div>
|
||||
</div>
|
||||
<div class="no_data_block" v-show="!imgList.length && !isShowMark">
|
||||
<img src="@/assets/images/homePage/null_img.png">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table_pagination" v-show="imgList.length">
|
||||
<a-pagination
|
||||
|
||||
v-model:current="currentPage"
|
||||
v-model:pageSize="pageSize"
|
||||
:total="total"
|
||||
:showQuickJumper="true"
|
||||
:showSizeChanger="false"
|
||||
@change="changePage"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a-modal class="library_rename_modal_component"
|
||||
v-model:visible="renameVisivle"
|
||||
:footer="null"
|
||||
title="Rename Pic"
|
||||
width="56rem"
|
||||
:maskClosable="false"
|
||||
:centered="true"
|
||||
@onCancel="closeRenameModal"
|
||||
>
|
||||
<div class="collection_rename_content">
|
||||
<div class="rename_form_content">
|
||||
<input class="rename_form_input" placeholder="Enter a new name" v-model="newPicName" @keydown.enter="confrimRename()">
|
||||
</div>
|
||||
<div class="rename_button_list">
|
||||
<div class="rename_button_item rename_cancel_button" @click="closeRenameModal()">Cancel</div>
|
||||
<div class="rename_button_item rename_submit_button" @click="confrimRename()">Sure</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
|
||||
<ModelPlacement ref="ModelPlacement" @submitModelPlacement="getLibraryList"></ModelPlacement>
|
||||
<ModelPlacementMobile ref="ModelPlacementMobile"></ModelPlacementMobile>
|
||||
|
||||
<!-- 蒙层 start-->
|
||||
<div class="mark_loading" v-show="isShowMark">
|
||||
<a-spin size="large" />
|
||||
</div>
|
||||
<!-- 蒙层 end-->
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent ,ref,createVNode} from 'vue'
|
||||
import HeaderComponent from "@/component/HomePage/Header.vue";
|
||||
import ModelPlacement from '@/component/LibraryPage/ModelPlacement.vue';
|
||||
import ModelPlacementMobile from '@/component/LibraryPage/ModelPlacementMobile.vue';
|
||||
import { Modal,message,Upload} from 'ant-design-vue';
|
||||
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
||||
import {getUploadUrl,isMoible} from '@/tool/util'
|
||||
import { Https } from "@/tool/https";
|
||||
export default defineComponent({
|
||||
components: {
|
||||
HeaderComponent,
|
||||
ModelPlacement,
|
||||
ModelPlacementMobile,
|
||||
},
|
||||
setup() {
|
||||
let menuList = ref([
|
||||
{title:'Moodboard',code:'Moodboard',icon:'icon-moban',showChildren:false,children:[]},
|
||||
{title:'Printboard',code:'Printboard',icon:'icon-dayin-dayinji',showChildren:false,children:[]},
|
||||
{title:'Sketchboard',code:'SketchboardFirst',icon:'icon-sumiao',showChildren:false,children:[{title:'Apparel',code:'Sketchboard'}]},
|
||||
{title:'Market Sketch',code:'MarketingSketch',icon:'icon-fuwushichang',showChildren:false,children:[]},
|
||||
{title:'Mannequin',code:'Models',icon:'icon-mote',showChildren:false,children:[]},
|
||||
|
||||
])
|
||||
let selectImgList:any = ref([])
|
||||
let selectCode:any = ref('Moodboard')
|
||||
let searchPictureName = ref('')
|
||||
let designType:any = ref('Outwear')
|
||||
let disignTypeList = [
|
||||
{
|
||||
value: "Outwear",
|
||||
label: "Outwear",
|
||||
},
|
||||
{
|
||||
value: "Blouse",
|
||||
label: "Blouse",
|
||||
},
|
||||
{
|
||||
value: "Dress",
|
||||
label: "Dress",
|
||||
},
|
||||
{
|
||||
value: "Trousers",
|
||||
label: "Trousers",
|
||||
},
|
||||
{
|
||||
value: "Skirt",
|
||||
label: "Skirt",
|
||||
},
|
||||
]
|
||||
let imgList = ref([])
|
||||
let currentPage:any = ref(1)
|
||||
let pageSize:any = ref(18)
|
||||
let total:any = ref(20)
|
||||
let renameVisivle:any = ref(false)
|
||||
let renameType:any = ref('single')//修改名字的方式single-单个 batch-批量
|
||||
let newPicName:any = ref('')
|
||||
let uploadUrl:any = ref('')
|
||||
let currentUploadFileNum:any = ref(0) //当次上传文件数量
|
||||
let isShowMark:any = ref(false) //蒙层
|
||||
let selectSingleImg:any = ref({}) //保存单个图片数据
|
||||
return {
|
||||
menuList,
|
||||
selectImgList,
|
||||
selectCode,
|
||||
searchPictureName,
|
||||
disignTypeList,
|
||||
designType,
|
||||
imgList,
|
||||
currentPage,
|
||||
pageSize,
|
||||
total,
|
||||
renameVisivle,
|
||||
renameType,
|
||||
newPicName,
|
||||
uploadUrl,
|
||||
currentUploadFileNum,
|
||||
isShowMark,
|
||||
selectSingleImg
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
this.uploadUrl = getUploadUrl()
|
||||
this.getLibraryList()
|
||||
},
|
||||
methods:{
|
||||
selectMenuItem(menu:any,index:any){
|
||||
if(menu.children?.length){ //证明是有子菜单
|
||||
menu.showChildren = !menu.showChildren
|
||||
}else{
|
||||
this.selectCode = menu.code
|
||||
this.currentPage = 1,
|
||||
this.total = 0,
|
||||
this.searchPictureName = ''
|
||||
this.imgList = [],
|
||||
this.designType = 'Outwear',
|
||||
this.selectImgList = []
|
||||
this.selectSingleImg = {}
|
||||
this.getLibraryList()
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
handleChange(){
|
||||
this.getLibraryList()
|
||||
},
|
||||
|
||||
fileUploadChange(data:any){
|
||||
let file = data.file
|
||||
// let Cropper:any = this.$refs.Cropper
|
||||
if(this.selectCode == 'Models'){
|
||||
let 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;
|
||||
}
|
||||
this.placementClick({url:data_new,file:file.originFileObj})
|
||||
|
||||
};
|
||||
// 转化为base64
|
||||
// reader.readAsDataURL(file)
|
||||
// 转化为blob
|
||||
reader.readAsArrayBuffer(file.originFileObj);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
//改变页码
|
||||
changePage(current: number, pageSize: number){
|
||||
this.currentPage = current
|
||||
this.pageSize = pageSize
|
||||
this.getLibraryList()
|
||||
},
|
||||
|
||||
//选择图片
|
||||
selectImgItem(imgData:any){
|
||||
if(this.selectImgList.indexOf(imgData.id) === -1){
|
||||
this.selectImgList.push(imgData.id)
|
||||
}else{
|
||||
let index = this.selectImgList.indexOf(imgData.id)
|
||||
this.selectImgList.splice(index,1)
|
||||
}
|
||||
},
|
||||
|
||||
//选择所有的图片
|
||||
selectAllImg(){
|
||||
if(this.selectImgList.length == this.imgList.length){
|
||||
this.selectImgList = []
|
||||
}else{
|
||||
this.selectImgList = this.imgList.map((v:any) => v.id)
|
||||
}
|
||||
},
|
||||
|
||||
closeRenameModal(){
|
||||
this.renameVisivle= false;
|
||||
this.newPicName = ''
|
||||
},
|
||||
|
||||
//确定修改名称
|
||||
confrimRename(){
|
||||
let data = {
|
||||
libraryIds:this.renameType === 'single' ? [this.selectSingleImg.id] : this.selectImgList,
|
||||
libraryName:this.newPicName,
|
||||
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
}
|
||||
Https.axiosPost(Https.httpUrls.batchUpdateLibraryName, data).then(
|
||||
(rv: any) => {
|
||||
if(this.renameType ==='batch'){
|
||||
this.selectImgList = []
|
||||
}
|
||||
this.getLibraryList()
|
||||
this.closeRenameModal()
|
||||
}
|
||||
).catch((res)=>{
|
||||
this.closeRenameModal()
|
||||
});
|
||||
},
|
||||
|
||||
//打开修改名称弹窗
|
||||
showRenameModal(data:any,type:any){
|
||||
if(type =='batch' && !this.selectImgList.length){ //批量但未选中
|
||||
return
|
||||
}
|
||||
if(type === 'single'){
|
||||
this.selectSingleImg = data
|
||||
}
|
||||
this.renameType = type
|
||||
this.renameVisivle = true
|
||||
},
|
||||
|
||||
//删除单个图片
|
||||
deleteSinglePic(data:any,index:any){
|
||||
let _this = this
|
||||
Modal.confirm({
|
||||
title: 'Are you sure to delete the picture?',
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
okText: 'Yes',
|
||||
cancelText: 'No',
|
||||
// centered:true,
|
||||
onOk() {
|
||||
_this.confirmDeletePic(data,index)
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
//批量删除图片
|
||||
deleteBatchPic(){
|
||||
if(!this.selectImgList.length){
|
||||
return
|
||||
}
|
||||
let _this = this
|
||||
Modal.confirm({
|
||||
title: 'Are you sure to delete the picture?',
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
okText: 'Yes',
|
||||
cancelText: 'No',
|
||||
// centered:true,
|
||||
onOk() {
|
||||
_this.confirmDeletePic('',0)
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
//确定删除图片 有data则是单个
|
||||
confirmDeletePic(data:any,index:any){
|
||||
let libraryIds = data ? [data.id] : this.selectImgList
|
||||
let newData = {
|
||||
libraryIds:libraryIds
|
||||
}
|
||||
Https.axiosPost(Https.httpUrls.batchDeleteLibrary, newData).then(
|
||||
(rv: any) => {
|
||||
if(data && data.id){
|
||||
this.imgList.splice(index, 1)
|
||||
}else{
|
||||
this.selectImgList = []
|
||||
this.getLibraryList()
|
||||
}
|
||||
}
|
||||
).catch((res)=>{
|
||||
});
|
||||
},
|
||||
|
||||
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.error('You can only upload Image file!');
|
||||
}
|
||||
const isLt2M = file.size / 1024 / 1024 < 2;
|
||||
if (!isLt2M) {
|
||||
message.error('Image must smaller than 5MB!');
|
||||
}
|
||||
this.currentUploadFileNum = fileList.length
|
||||
return (isJpgOrPng && isLt2M) || Upload.LIST_IGNORE;
|
||||
},
|
||||
|
||||
|
||||
|
||||
customRequest(event:any){
|
||||
let designType = this.selectCode == 'Sketchboard' || this.selectCode == 'MarketingSketch' ? this.designType : ''
|
||||
let new_data = {
|
||||
file:event.file,
|
||||
level1Type:this.selectCode,
|
||||
level2Type:designType,
|
||||
timeZone:Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
}
|
||||
this.isShowMark = true
|
||||
Https.axiosPost(Https.httpUrls.libraryUpload, new_data,{headers:{'Content-Type': 'multipart/form-data'}}).then(
|
||||
(rv: any) => {
|
||||
this.currentUploadFileNum --
|
||||
if(!this.currentUploadFileNum){
|
||||
this.getLibraryList()
|
||||
}
|
||||
|
||||
}
|
||||
).catch((res)=>{
|
||||
this.currentUploadFileNum --
|
||||
if(!this.currentUploadFileNum){
|
||||
this.getLibraryList()
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
getLibraryList(){
|
||||
let designType = this.selectCode == 'Sketchboard' || this.selectCode == 'MarketingSketch' ? this.designType : ''
|
||||
let data = {
|
||||
level1Type:this.selectCode,
|
||||
level2Type:designType,
|
||||
page:this.currentPage,
|
||||
pictureName:this.searchPictureName,
|
||||
size:this.pageSize,
|
||||
}
|
||||
this.isShowMark = true
|
||||
Https.axiosPost(Https.httpUrls.queryLibraryPage,data).then(
|
||||
(rv: any) => {
|
||||
this.imgList = rv.content
|
||||
this.total = rv.total
|
||||
this.isShowMark = false
|
||||
}
|
||||
).catch((res)=>{
|
||||
this.isShowMark = false
|
||||
});
|
||||
},
|
||||
|
||||
//编辑模特打点
|
||||
editPlacementClick(data:any){
|
||||
let newData = {
|
||||
...data.libraryModelPoint,
|
||||
url:data.url,
|
||||
}
|
||||
this.placementClick(newData)
|
||||
},
|
||||
|
||||
//给模特打点编辑
|
||||
placementClick(data:any){
|
||||
let placementModal:any = isMoible() ? this.$refs.ModelPlacementMobile : this.$refs.ModelPlacement
|
||||
placementModal.showPlacementModal(data)
|
||||
},
|
||||
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="less">
|
||||
.library_page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.page_content {
|
||||
position: relative;
|
||||
|
||||
.page_content_bg {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.page_content_body {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
.library_page_body{
|
||||
width: 100%;
|
||||
height: calc(100% - 7rem);
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
|
||||
.library_body_left{
|
||||
width: 23.5rem;
|
||||
height: 100%;
|
||||
background: rgba(255,255,255,0.4);
|
||||
|
||||
.library_menu_list{
|
||||
|
||||
.menu_item{
|
||||
width: 100%;
|
||||
height: 6.8rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 1rem 0 2.5rem;
|
||||
border-left: 0.5rem solid transparent;
|
||||
font-size: 1.8rem;
|
||||
color: #030303;
|
||||
cursor: pointer;
|
||||
|
||||
&.child_menu_item{
|
||||
padding-left: 6.5rem;
|
||||
}
|
||||
|
||||
&.select_menu_item{
|
||||
background: #E6E6F6;
|
||||
border-color: #343579;;
|
||||
}
|
||||
|
||||
.menu_item_left{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
user-select: none;
|
||||
|
||||
.type_icon{
|
||||
font-size: 2.2rem;
|
||||
color: #030303;
|
||||
margin-right: 1.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
.icon_rotate{
|
||||
-moz-transform:rotate(180deg);
|
||||
-webkit-transform:rotate(180deg);
|
||||
transform: rotate(180deg);
|
||||
animation-direction: 0.5s;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
.library_body_right{
|
||||
width: calc(100% - 23.5rem);
|
||||
height: 100%;
|
||||
|
||||
.library_right_header{
|
||||
display: flex;
|
||||
padding: 0 3.5rem 0 2.8rem;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background: rgba(255,255,255,0.4);
|
||||
box-shadow: 0 0.2rem 0.8rem 0 rgba(238,238,244,0.25);
|
||||
|
||||
.library_header_left{
|
||||
height: 8rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.header_operate_item{
|
||||
margin-right: 5rem;
|
||||
color: #C2C2C2;
|
||||
font-size: 1.6rem;
|
||||
|
||||
.ant-upload-list-text{
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.operate_select{
|
||||
color:#333333;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:last-child{
|
||||
margin-right: 11rem;
|
||||
}
|
||||
}
|
||||
|
||||
.content_search_block{
|
||||
margin-left: 4rem;
|
||||
display: flex;
|
||||
|
||||
.search_input{
|
||||
width: 32.8rem;
|
||||
padding-left: 1.5rem;
|
||||
height: 4.8rem;
|
||||
line-height: 4.6rem;
|
||||
background: #FFFFFF;
|
||||
border: 0.1rem solid #F1F1F1;
|
||||
font-size: 1.6rem;
|
||||
font-weight: 400;
|
||||
|
||||
&::placeholder {
|
||||
color: #C2C2C2;
|
||||
}
|
||||
}
|
||||
|
||||
.search_icon_block{
|
||||
width: 7.2rem;
|
||||
height: 4.8rem;
|
||||
line-height: 4.8rem;
|
||||
text-align: center;
|
||||
background: #343579;
|
||||
cursor: pointer;
|
||||
|
||||
.icon-sousuo{
|
||||
font-size: 2rem;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.librart_headr_right{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.select_block{
|
||||
background: #FFFFFF;
|
||||
color: #1A1A1A !important;
|
||||
|
||||
.icon-xiala{
|
||||
color: #1A1A1A !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.libray_right_content{
|
||||
width:100%;
|
||||
height:calc(100% - 8rem);
|
||||
padding: 0.1rem 0 0 0.3rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
.right_content_body{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(246,246,250,0.4);
|
||||
padding: 0 2rem 5rem 1rem;
|
||||
|
||||
.content_body_header{
|
||||
height: 7.5rem;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
|
||||
.check_all_block{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 1.6rem;
|
||||
color: #64686D;
|
||||
cursor: pointer;
|
||||
|
||||
&.check_all{
|
||||
color: #1A1A1A;
|
||||
}
|
||||
|
||||
.check_block{
|
||||
width: 2.4rem;
|
||||
height: 2.4rem;
|
||||
background: #EBECF4;
|
||||
border: 0.1rem solid #64686D;
|
||||
padding: 0.3rem;
|
||||
margin-right: 0.7rem;
|
||||
|
||||
.check_block_body{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #343579;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content_body_table{
|
||||
width: 100%;
|
||||
height: calc(100% - 12rem);
|
||||
overflow-y:auto;
|
||||
|
||||
.content_img_item{
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
padding: 0 1.4rem;
|
||||
margin-bottom: 2.8rem;
|
||||
|
||||
.content_img_item_block{
|
||||
border: 0.1rem solid transparent;
|
||||
width: 16.5rem;
|
||||
height: 16.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
|
||||
&.select_item_img{
|
||||
border-color: #343579;
|
||||
}
|
||||
|
||||
.content_img{
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.board_content_img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&:hover .img_item_hover{
|
||||
display: block;
|
||||
}
|
||||
|
||||
.img_item_hover{
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top:0;
|
||||
background: rgba(0,0,0,0.2);
|
||||
display: none;
|
||||
|
||||
.img_operate_content{
|
||||
position: absolute;
|
||||
right: 0.6rem;
|
||||
top: 0.6rem;
|
||||
}
|
||||
|
||||
.img_operate_block{
|
||||
width: 3.6rem;
|
||||
height: 3.6rem;
|
||||
background: rgba(0,0,0,0.6);
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
line-height: 3.6rem;
|
||||
cursor: pointer;
|
||||
margin-bottom: 0.4rem;
|
||||
|
||||
.operate_icon{
|
||||
font-size: 1.8rem;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.content_img_name{
|
||||
width: 16.5rem;
|
||||
height: 3.5rem;
|
||||
line-height: 3.5rem;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 1.4rem;
|
||||
color: #030303;
|
||||
}
|
||||
}
|
||||
|
||||
.no_data_block{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.table_pagination{
|
||||
text-align: center;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.library_rename_modal_component{
|
||||
|
||||
.collection_rename_content{
|
||||
padding:0 6.8rem 1.8rem;
|
||||
|
||||
|
||||
.rename_form_content{
|
||||
|
||||
.rename_form_input{
|
||||
width: 100%;
|
||||
height: 4.6rem;
|
||||
margin-top: 1rem;
|
||||
border: 0.1rem solid #B4BED7;
|
||||
padding-left: 2.1rem;
|
||||
line-height: 4.6rem;
|
||||
font-size: 1.8rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
&::placeholder {
|
||||
color:#A5B0C2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.rename_button_list{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
margin-top: 3rem;
|
||||
|
||||
.rename_button_item{
|
||||
width: 8.6rem;
|
||||
height: 3.2rem;
|
||||
line-height: 3.2rem;
|
||||
text-align: center;
|
||||
font-size: 1.4rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.rename_cancel_button{
|
||||
background: #E4E5EB;
|
||||
color: #030303;
|
||||
margin-right: 1.8rem;
|
||||
}
|
||||
|
||||
.rename_submit_button{
|
||||
background: #343579;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
715
src/views/LoginPage.vue
Normal file
@@ -0,0 +1,715 @@
|
||||
<template>
|
||||
<div class="login_page">
|
||||
<div class="page_content">
|
||||
<img
|
||||
class="login_logo"
|
||||
src="@/assets/images/loginPage/aida_Logo_login.png"
|
||||
/>
|
||||
<!-- 账号密码和邮箱登录 start-->
|
||||
<div class="login_content" v-if="isLogin === 1">
|
||||
<div class="login_type_list">
|
||||
<div
|
||||
:class="[
|
||||
'login_type_item','username_login_item',
|
||||
'login_active',
|
||||
]"
|
||||
>
|
||||
Log on to AiDA
|
||||
</div>
|
||||
</div>
|
||||
<!-- 账号密码登录 start -->
|
||||
<div v-show="loginType == 'username'">
|
||||
<div class="login_form_content">
|
||||
<div class="login_form_title">Username</div>
|
||||
<input
|
||||
class="login_form_input"
|
||||
placeholder="Enter your username"
|
||||
v-model="username"
|
||||
/>
|
||||
<div class="login_form_title marign_top30">
|
||||
<div>Password</div>
|
||||
<!-- <div class="tip_content" @click="changeIsLogin(2)">
|
||||
Forgot password?
|
||||
</div> -->
|
||||
</div>
|
||||
<div class="password_input_block">
|
||||
<input
|
||||
class="login_form_input"
|
||||
:type="passwordType"
|
||||
placeholder="Enter your password"
|
||||
v-model="password"
|
||||
@keydown.enter="submitPerLogin()"
|
||||
/>
|
||||
<div class="icon iconfont icon-yanjing_yincang_o password_show_icon" @click="changePasswordType()"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div
|
||||
class="login_submit_button marign_top40"
|
||||
@click="submitPerLogin()"
|
||||
>
|
||||
Continue
|
||||
</div>
|
||||
|
||||
<div class="login_text" >
|
||||
<div class="forget_password_text" @click="changeIsLogin(2)">Forgot your password</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- 账号密码登录 end -->
|
||||
|
||||
<!-- 邮箱登录 start -->
|
||||
<div v-show="loginType == 'email'">
|
||||
<div v-show="emailStap === 1" class="forget_password_content">
|
||||
<div class="forget_password_content_block" @click="changeLoginType('username')">
|
||||
<span class="icon iconfont icon--shangyibu"></span
|
||||
><span class="forget_password_content_title"
|
||||
>Log on to AiDA</span
|
||||
>
|
||||
</div>
|
||||
<div class="login_form_content">
|
||||
<div class="login_form_title">Email</div>
|
||||
<input
|
||||
class="login_form_input"
|
||||
placeholder="Enter your email address"
|
||||
v-model="email"
|
||||
@keydown.enter="emailNextStepFun()"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="login_submit_button marign_top40"
|
||||
@click="emailNextStepFun()"
|
||||
>
|
||||
Continue
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-show="emailStap === 2" class="email_last_step">
|
||||
|
||||
<div class="email_last_step_block" @click="emailLastStepFun()">
|
||||
<span class="icon iconfont icon--shangyibu"></span
|
||||
><span class="email_last_step_content"
|
||||
>Verify with one-time verification code</span
|
||||
>
|
||||
</div>
|
||||
<div class="email_last_step_des">
|
||||
<div class="sent_email_content">
|
||||
Sent to {{ email }}
|
||||
</div>
|
||||
<div class="tip_content">
|
||||
<span v-show="time">{{ time }}s</span>
|
||||
<span v-show="!time" @click="emailNextStepFun()"
|
||||
>Resend</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<VerificationCodeInput
|
||||
:ct="emailCode"
|
||||
@sendCaptcha="submitEmailLogin($event)"
|
||||
></VerificationCodeInput>
|
||||
|
||||
<div class="email_last_step_des">
|
||||
<div class="sent_email_content email_tip_content">
|
||||
Please check the junk box if you haven't received verification code
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 邮箱登录 end -->
|
||||
</div>
|
||||
|
||||
<!-- 忘记密码 start -->
|
||||
<div class="forget_password_content" v-else>
|
||||
<div class="forget_password_content_block" @click="forgetPasswordLastStepFun()">
|
||||
<span class="icon iconfont icon--shangyibu"></span
|
||||
><span class="forget_password_content_title"
|
||||
>Retrieve password</span
|
||||
>
|
||||
</div>
|
||||
<div v-show="frogetPasswordStep === 1">
|
||||
<div class="forget_passored_form_content">
|
||||
<div class="forget_passored_form_title">Email</div>
|
||||
<input
|
||||
class="forget_passored_form_input"
|
||||
placeholder="Enter your email"
|
||||
v-model="forgetPasswordEmail"
|
||||
@keydown.enter="forgetPasswordNextStepFun()"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="forget_submit_button marign_top40"
|
||||
@click="forgetPasswordNextStepFun()"
|
||||
>
|
||||
Next step
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-show="frogetPasswordStep === 2">
|
||||
<div class="forget_verif_code_des">Verification Code</div>
|
||||
<div class="email_last_step_des">
|
||||
<div class="sent_email_content">
|
||||
Sent to {{ forgetPasswordEmail }}
|
||||
</div>
|
||||
<div class="tip_content">
|
||||
<span v-show="time">{{ time }}s</span>
|
||||
<span
|
||||
v-show="!time"
|
||||
@click="forgetPasswordNextStepFun()"
|
||||
>Resend</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<VerificationCodeInput
|
||||
:ct="emailCode"
|
||||
@sendCaptcha="submitPasswordCode($event)"
|
||||
></VerificationCodeInput>
|
||||
</div>
|
||||
|
||||
<div v-show="frogetPasswordStep === 3">
|
||||
<div class="forget_passored_form_content">
|
||||
<div class="forget_passored_form_title">Password</div>
|
||||
<input
|
||||
class="forget_passored_form_input"
|
||||
placeholder="Enter a new password"
|
||||
v-model="newPassword"
|
||||
@keydown.enter="submitResetPassword()"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="forget_submit_button marign_top40"
|
||||
@click="submitResetPassword()"
|
||||
>
|
||||
Submit
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 忘记密码 end -->
|
||||
|
||||
</div>
|
||||
|
||||
<div class="login_footer">
|
||||
<div class="login_footer_item"><div class="login_footer_item_text">©2022 CodeCreate</div></div>
|
||||
<div class="login_footer_item">
|
||||
<div class="login_footer_item_text footer_item_text_pointer" @click="turnToWindow('https://code-create.com.hk/aida-terms-and-conditions/')">Terms&Conditions</div>
|
||||
<div class="login_footer_line"></div>
|
||||
<div class="login_footer_item_text footer_item_text_pointer" @click="turnToWindow('https://code-create.com.hk/aida-subscription-agreement/')">Privacy Policy</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "vue";
|
||||
import { Https } from "@/tool/https";
|
||||
import { isEmail } from "@/tool/util";
|
||||
import { setCookie } from "@/tool/cookie";
|
||||
import { message } from "ant-design-vue";
|
||||
import VerificationCodeInput from "@/component/LoginPage/verificationCodeInput.vue";
|
||||
|
||||
const md5 = require("md5");
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
VerificationCodeInput,
|
||||
},
|
||||
setup(){
|
||||
let timer:any = 0
|
||||
return{
|
||||
timer
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isLogin: 1, //是否为登录 1-登录, 2-忘记密码
|
||||
loginType: "username",
|
||||
emailStap: 1, // 邮箱登录步骤
|
||||
emailCode: ["", "", "", "", "", ""], //邮箱验证码
|
||||
emailNextStep: true,
|
||||
username: "",
|
||||
password: "",
|
||||
email: "", //邮箱登录邮箱
|
||||
frogetPasswordStep: 1, //忘记密码的步骤
|
||||
forgetPasswordEmail: "",
|
||||
forgetEmailCode: ["", "", "", "", "", ""], //忘记密码的邮箱验证码
|
||||
forgetEmailValue: "", //忘记密码的邮箱验证码保存值
|
||||
newPassword: "", //新密码
|
||||
isCheckRobot: false,
|
||||
time: 60, //60秒倒计时
|
||||
passwordType:'password',
|
||||
userId:'',
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
changeLoginType(type: string) {
|
||||
this.loginType = type;
|
||||
},
|
||||
|
||||
//是否忘记密码页面
|
||||
changeIsLogin(isLogin: number) {
|
||||
if (isLogin === 1) {
|
||||
//登录
|
||||
this.forgetPasswordEmail = "";
|
||||
this.frogetPasswordStep = 1;
|
||||
this.forgetEmailCode = ["", "", "", "", "", ""];
|
||||
this.emailStap = 1;
|
||||
this.clearTimer();
|
||||
} else {
|
||||
this.username = "";
|
||||
this.password = "";
|
||||
}
|
||||
this.isLogin = isLogin;
|
||||
},
|
||||
|
||||
//邮箱登录的下一步
|
||||
emailNextStepFun() {
|
||||
if (!isEmail(this.email)) {
|
||||
message.error("The email format is incorrect");
|
||||
return;
|
||||
}
|
||||
let data = {
|
||||
email: this.email,
|
||||
operationType: "LOGIN",
|
||||
};
|
||||
Https.axiosPost(Https.httpUrls.accountSendEmail, data).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
this.emailStap = 2;
|
||||
this.time = 60;
|
||||
this.emailCode = ["", "", "", "", "", ""]
|
||||
this.createTimer();
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
//邮箱登录的上一步
|
||||
emailLastStepFun() {
|
||||
this.emailStap = 1;
|
||||
this.email = "";
|
||||
(this.emailCode = ["", "", "", "", "", ""]), this.clearTimer();
|
||||
},
|
||||
|
||||
//忘记密码的下一步
|
||||
forgetPasswordNextStepFun() {
|
||||
if (!isEmail(this.forgetPasswordEmail)) {
|
||||
message.error("The email format is incorrect");
|
||||
return;
|
||||
}
|
||||
let data = {
|
||||
email: this.forgetPasswordEmail,
|
||||
operationType: "FORGET_PWD",
|
||||
};
|
||||
Https.axiosPost(Https.httpUrls.accountSendEmail, data).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
this.frogetPasswordStep = 2;
|
||||
(this.forgetEmailCode = ["", "", "", "", "", ""]),
|
||||
this.createTimer();
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
//忘记密码的上一步
|
||||
forgetPasswordLastStepFun() {
|
||||
if (this.frogetPasswordStep === 1) {
|
||||
this.changeIsLogin(1);
|
||||
} else {
|
||||
this.frogetPasswordStep = this.frogetPasswordStep - 1;
|
||||
this.forgetPasswordEmail = "";
|
||||
(this.forgetEmailCode = ["", "", "", "", "", ""]),
|
||||
this.clearTimer();
|
||||
}
|
||||
},
|
||||
|
||||
//忘记密码填写完邮箱验证码进行下一步
|
||||
submitPasswordCode(emailVerifyCode: any) {
|
||||
this.forgetEmailValue = emailVerifyCode;
|
||||
this.frogetPasswordStep = 3;
|
||||
this.clearTimer();
|
||||
},
|
||||
|
||||
//改变勾选是否是机器人
|
||||
checkRobot() {
|
||||
this.isCheckRobot = !this.isCheckRobot;
|
||||
},
|
||||
|
||||
//提交账号密码预先登录
|
||||
submitPerLogin() {
|
||||
if (!this.username || !this.password) {
|
||||
message.error("Please enter your password");
|
||||
return;
|
||||
}
|
||||
let data = {
|
||||
password: md5(this.password + "abc"),
|
||||
userName: this.username,
|
||||
};
|
||||
Https.axiosPost(Https.httpUrls.preLogin, data).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
this.userId = rv.userId
|
||||
this.loginType = 'email'
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
changePasswordType(){
|
||||
this.passwordType = this.passwordType === 'password' ? 'text' : 'password'
|
||||
},
|
||||
|
||||
//邮箱登录提交
|
||||
submitEmailLogin(emailVerifyCode: any) {
|
||||
let data = {
|
||||
email: this.email,
|
||||
emailVerifyCode: emailVerifyCode,
|
||||
loginType: "EMAIL",
|
||||
userId:this.userId
|
||||
};
|
||||
Https.axiosPost(Https.httpUrls.accountLogin, data).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
this.createTimer();
|
||||
let token = rv.token;
|
||||
setCookie("token", token);
|
||||
setCookie("userInfo", JSON.stringify(rv));
|
||||
this.turnToHomePage();
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
//修改密码提交
|
||||
submitResetPassword() {
|
||||
let data = {
|
||||
email: this.forgetPasswordEmail,
|
||||
emailVerifyCode: this.forgetEmailValue,
|
||||
password: md5(this.newPassword + "abc"),
|
||||
};
|
||||
Https.axiosPost(Https.httpUrls.accountResetPwd, data).then(
|
||||
(rv: any) => {
|
||||
if (rv) {
|
||||
message.success("Changing the password successfully");
|
||||
this.changeIsLogin(1);
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
//创建定时器
|
||||
createTimer() {
|
||||
this.timer = setInterval(() => {
|
||||
this.time--;
|
||||
if (!this.time) {
|
||||
clearInterval(this.timer);
|
||||
}
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
//清除定时器
|
||||
clearTimer() {
|
||||
this.time = 60;
|
||||
if (this.timer) {
|
||||
clearInterval(this.timer);
|
||||
}
|
||||
},
|
||||
|
||||
//跳转到首页
|
||||
turnToHomePage() {
|
||||
this.$router.push("/home");
|
||||
},
|
||||
|
||||
turnToWindow(url: any) {
|
||||
window.open(url);
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.login_page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.page_content {
|
||||
// position: relative;
|
||||
|
||||
.login_logo {
|
||||
position: absolute;
|
||||
left: 4rem;
|
||||
top: 2.5rem;
|
||||
width: 11rem;
|
||||
}
|
||||
|
||||
.login_content {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%,-50%);
|
||||
width: 60rem;
|
||||
background: #FFFFFF;
|
||||
box-shadow: -0.3rem 2rem 5.9rem 0px rgba(200,200,200,0.3);
|
||||
border-radius: 1rem;
|
||||
padding: 3rem 6rem 6.5rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
.login_type_list {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
|
||||
.login_type_item {
|
||||
text-align: center;
|
||||
font-size: 3.6rem;
|
||||
font-weight: bold;
|
||||
color: #D7D7D7;
|
||||
cursor: pointer;
|
||||
height: 4rem;
|
||||
line-height: 4rem;
|
||||
|
||||
&.login_active {
|
||||
color: #030303;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.login_form_content {
|
||||
margin-top: 4rem;
|
||||
|
||||
.login_form_title {
|
||||
font-size: 1.6rem;
|
||||
color: #666666;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.password_input_block{
|
||||
position: relative;
|
||||
|
||||
.password_show_icon{
|
||||
position: absolute;
|
||||
font-size: 2.4rem;
|
||||
right: 2rem;
|
||||
top:1.7rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.login_form_input {
|
||||
width: 100%;
|
||||
height: 5rem;
|
||||
margin-top: 1rem;
|
||||
border: 0.1rem solid #DFDFDF;
|
||||
border-radius: 2.5rem;
|
||||
padding-left: 2.1rem;
|
||||
line-height: 5rem;
|
||||
font-size: 1.4rem;
|
||||
box-sizing: border-box;
|
||||
outline: none;
|
||||
|
||||
|
||||
&::placeholder {
|
||||
color: #a5b0c2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.email_last_step {
|
||||
margin-top: 4rem;
|
||||
|
||||
.email_last_step_block{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icon--shangyibu {
|
||||
font-size: 2.5rem;
|
||||
font-weight: bold;
|
||||
color: #030303;
|
||||
}
|
||||
|
||||
.email_last_step_content {
|
||||
margin-left: 1rem;
|
||||
font-size: 2.2rem;
|
||||
font-weight: bold;
|
||||
color: #030303;
|
||||
}
|
||||
}
|
||||
|
||||
.login_submit_button {
|
||||
height: 5rem;
|
||||
background: #343579;
|
||||
border-radius: 2.5rem;
|
||||
line-height: 5rem;
|
||||
text-align: center;
|
||||
font-size: 1.8rem;
|
||||
font-weight: 500;
|
||||
color: #ffffff;
|
||||
cursor: pointer;
|
||||
}
|
||||
.login_text {
|
||||
font-size: 1.6rem;
|
||||
margin-top: 4rem;
|
||||
color: #151515;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
.forget_password_text{
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.forget_password_content {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%,-50%);
|
||||
width: 60rem;
|
||||
background: #FFFFFF;
|
||||
box-shadow: -0.3rem 2rem 5.9rem 0px rgba(200,200,200,0.3);
|
||||
border-radius: 1rem;
|
||||
padding: 3rem 6rem 6.5rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
.forget_password_content_block{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icon--shangyibu {
|
||||
font-size: 3.8rem;
|
||||
font-weight: bold;
|
||||
color: #030303;
|
||||
}
|
||||
.forget_password_content_title {
|
||||
font-size: 3.2rem;
|
||||
font-weight: bold;
|
||||
color: #030303;
|
||||
margin-left: 2rem;
|
||||
}
|
||||
|
||||
.forget_passored_form_content {
|
||||
margin-top: 3.5rem;
|
||||
|
||||
.forget_passored_form_title {
|
||||
font-size: 2.4rem;
|
||||
font-weight: bold;
|
||||
color: #030303;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.forget_passored_form_input {
|
||||
width: 100%;
|
||||
height: 5rem;
|
||||
margin-top: 1rem;
|
||||
border: 0.1rem solid #DFDFDF;
|
||||
border-radius: 2.5rem;
|
||||
padding-left: 2.1rem;
|
||||
line-height: 5rem;
|
||||
font-size: 1.4rem;
|
||||
box-sizing: border-box;
|
||||
outline: none;
|
||||
|
||||
&::placeholder {
|
||||
color: #a5b0c2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.forget_verif_code_des {
|
||||
font-size: 2.4rem;
|
||||
font-weight: bold;
|
||||
color: #030303;
|
||||
margin-top: 3.5rem;
|
||||
}
|
||||
|
||||
.forget_submit_button {
|
||||
height: 5rem;
|
||||
background: #343579;
|
||||
border-radius: 2.5rem;
|
||||
line-height: 5rem;
|
||||
text-align: center;
|
||||
font-size: 1.8rem;
|
||||
font-weight: 500;
|
||||
color: #ffffff;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.login_footer{
|
||||
position: absolute;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
left: 0;
|
||||
bottom: 3.5rem;
|
||||
width: 100%;
|
||||
padding: 0 4rem;
|
||||
|
||||
.login_footer_item{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.login_footer_item_text{
|
||||
font-size: 1.3rem;
|
||||
color: #151515;
|
||||
}
|
||||
|
||||
.footer_item_text_pointer{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.login_footer_line{
|
||||
width: 0.1rem;
|
||||
height: 2rem;
|
||||
margin: 0 2rem;
|
||||
background: #B9B9B9;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
.marign_top20 {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.marign_top22 {
|
||||
margin-top: 2.2rem;
|
||||
}
|
||||
|
||||
.marign_top30 {
|
||||
margin-top: 3rem;
|
||||
}
|
||||
.marign_top40 {
|
||||
margin-top: 4rem;
|
||||
}
|
||||
|
||||
.tip_content {
|
||||
font-size: 1.3rem;
|
||||
font-weight: bold;
|
||||
color: #343579;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.email_last_step_des {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 4rem;
|
||||
margin-bottom: 2rem;
|
||||
|
||||
.sent_email_content {
|
||||
font-size: 1.8rem;
|
||||
font-weight: bold;
|
||||
color: #a5b0c2;
|
||||
}
|
||||
|
||||
.email_tip_content{
|
||||
font-size: 1.4rem;
|
||||
color: #030303;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
44
tsconfig.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"module": "esnext",
|
||||
"strict": true,
|
||||
"jsx": "preserve",
|
||||
"moduleResolution": "node",
|
||||
"experimentalDecorators": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"useDefineForClassFields": true,
|
||||
"sourceMap": true,
|
||||
"allowJs": true, //编译时允许有js
|
||||
"baseUrl": ".",
|
||||
"outDir": "./",
|
||||
"types": [
|
||||
"webpack-env"
|
||||
],
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"src/*"
|
||||
]
|
||||
},
|
||||
"lib": [
|
||||
"esnext",
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"scripthost"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.tsx",
|
||||
"src/**/*.vue",
|
||||
"tests/**/*.ts",
|
||||
"tests/**/*.tsx",
|
||||
"src/**/*.js",
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
44
vue.config.js
Normal file
@@ -0,0 +1,44 @@
|
||||
const {defineConfig} = require('@vue/cli-service')
|
||||
const path = require('path');
|
||||
module.exports = defineConfig({
|
||||
transpileDependencies: ['vuetify'],
|
||||
lintOnSave:false,//关闭语法检查
|
||||
devServer: {
|
||||
// hot: true, // 热更新
|
||||
port: '8060',
|
||||
proxy: {
|
||||
"/api": {
|
||||
target: 'https://www.aida.com.hk', //后端接口地址
|
||||
changeOrigin: true, //是否允许跨越
|
||||
}
|
||||
},
|
||||
},
|
||||
pluginOptions: {
|
||||
"style-resources-loader": {
|
||||
preProcessor: "less",
|
||||
patterns: [
|
||||
// 存放less变量文件的路径
|
||||
path.resolve(__dirname, "./src/assets/style/style.less")
|
||||
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
css: {
|
||||
loaderOptions: {
|
||||
less: {
|
||||
lessOptions: {
|
||||
modifyVars: {
|
||||
'primary-color': '#ec6800'
|
||||
},
|
||||
javascriptEnabled: true,
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
}
|
||||
})
|
||||