Merge branch 'dev_vite' into main

This commit is contained in:
2025-11-28 14:08:06 +08:00
240 changed files with 28310 additions and 16912 deletions

View File

@@ -1,4 +1,4 @@
VITE_USER_NODE_ENV = 'production'
VITE_USER_NODE_ENV = 'development'
# VITE_APP_BASE_URL = 'https://aida.com.hk/test'
# VITE_APP_BASE_URL = 'http://18.167.251.121:10088'
# VITE_APP_BASE_URL = 'https://api.aida.com.hk'

View File

@@ -1,12 +1,6 @@
<<<<<<< HEAD
VITE_USER_NODE_ENV = 'development'
VITE_APP_BASE_URL = 'https://test.api.aida.com.hk'
# VITE_APP_BASE_URL = 'https://api.aida.com.hk'
=======
NODE_ENV = 'development'
# VUE_APP_BASE_URL = 'https://api.aida.com.hk'
VUE_APP_BASE_URL = 'https://test.api.aida.com.hk'
>>>>>>> 5d8304ce3ece21dd3200ffffb0c76e3ef55dd213
# VITE_APP_BASE_URL = 'http://18.167.251.121:10086'
# VITE_APP_BASE_URL = 'http://192.168.1.9:5567'

1
.gitignore vendored
View File

@@ -23,3 +23,4 @@ dist.rar
*.sln
*.sw?
.eslintrc-auto-import.json
components.d.ts

38
components.d.ts vendored
View File

@@ -1,38 +0,0 @@
/* eslint-disable */
// @ts-nocheck
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
// biome-ignore lint: disable
export {}
/* prettier-ignore */
declare module 'vue' {
export interface GlobalComponents {
ABadge: typeof import('ant-design-vue/es')['Badge']
ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
AConfigProvider: typeof import('ant-design-vue/es')['ConfigProvider']
ADrawer: typeof import('ant-design-vue/es')['Drawer']
AImage: typeof import('ant-design-vue/es')['Image']
AInputNumber: typeof import('ant-design-vue/es')['InputNumber']
AModal: typeof import('ant-design-vue/es')['Modal']
APagination: typeof import('ant-design-vue/es')['Pagination']
APopover: typeof import('ant-design-vue/es')['Popover']
ARangePicker: typeof import('ant-design-vue/es')['RangePicker']
ASelect: typeof import('ant-design-vue/es')['Select']
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
ASlider: typeof import('ant-design-vue/es')['Slider']
ASpin: typeof import('ant-design-vue/es')['Spin']
ASwitch: typeof import('ant-design-vue/es')['Switch']
ATable: typeof import('ant-design-vue/es')['Table']
ATabPane: typeof import('ant-design-vue/es')['TabPane']
ATabs: typeof import('ant-design-vue/es')['Tabs']
AUpload: typeof import('ant-design-vue/es')['Upload']
ElCascader: typeof import('element-plus/es')['ElCascader']
ElLoading: typeof import('element-plus/es')['ElLoading']
ElPagination: typeof import('element-plus/es')['ElPagination']
ElTable: typeof import('element-plus/es')['ElTable']
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
}
}

BIN
dist.7z

Binary file not shown.

9
package-lock.json generated
View File

@@ -35,7 +35,8 @@
"vue-i18n": "^9.6.1",
"vue-router": "^4.0.3",
"vuedraggable": "^4.1.0",
"vuex": "^4.0.0"
"vuex": "^4.0.0",
"x-sender": "^1.1.6"
},
"devDependencies": {
"@types/three": "^0.174.0",
@@ -10106,6 +10107,12 @@
}
}
},
"node_modules/x-sender": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/x-sender/-/x-sender-1.1.6.tgz",
"integrity": "sha512-es24YnTY1+g3TdDVrEgRVW8uW2nYPyHjQveBgZxk8JrB7809yd8AkYptrLgqL1trpUZtMILVW+2GIoB0V5HfVQ==",
"license": "MIT"
},
"node_modules/xml-name-validator": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz",

View File

@@ -41,7 +41,8 @@
"vue-i18n": "^9.6.1",
"vue-router": "^4.0.3",
"vuedraggable": "^4.1.0",
"vuex": "^4.0.0"
"vuex": "^4.0.0",
"x-sender": "^1.1.6"
},
"devDependencies": {
"@types/three": "^0.174.0",
@@ -105,4 +106,4 @@
"not dead",
"not ie 11"
]
}
}

View File

@@ -0,0 +1,427 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<title>style category</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js"></script>
<style>
body {
margin: 0;
padding: 0;
font-family: sans-serif;
box-sizing: border-box;
background-color: #f9f9f9;
}
.viewport {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: auto;
background-color: #f9f9f9;
cursor: grab;
scrollbar-width: thick;
scrollbar-color: #666 #eee;
}
.viewport::-webkit-scrollbar {
height: 16px;
width: 16px;
}
.viewport::-webkit-scrollbar-track {
background: #eee;
border-radius: 8px;
}
.viewport::-webkit-scrollbar-thumb {
background: #666;
border-radius: 8px;
border: 3px solid #eee;
}
.viewport::-webkit-scrollbar-thumb:hover {
background: #333;
}
.content-size {
position: relative;
width: 100%;
height: 100%;
}
.content {
padding: 30px;
transform-origin: top left;
width: max-content;
min-width: 100%;
}
h1 {
text-align: center;
font-size: 100px;
margin: 40px 0 60px;
font-weight: bold;
color: #333;
}
.chart-section {
margin-bottom: 80px;
background: #fff;
border-radius: 16px;
padding: 30px;
box-shadow: 0 6px 20px rgba(0,0,0,0.08);
}
h2 {
text-align: center;
font-size: 80px;
margin: 0 0 40px;
font-weight: bold;
color: #444;
}
.chart-container {
overflow-x: auto;
width: 100%;
min-width: 8000px; /* 适配20倍组间空隙大幅扩大容器宽度 */
min-height: 1900px;
scrollbar-width: thick;
scrollbar-color: #666 #eee;
padding-bottom: 100px;
}
/* 自定义滚动条 */
.chart-container::-webkit-scrollbar {
height: 16px;
}
.chart-container::-webkit-scrollbar-track {
background: #eee;
border-radius: 8px;
}
.chart-container::-webkit-scrollbar-thumb {
background: #666;
border-radius: 8px;
border: 3px solid #eee;
}
.chart-container::-webkit-scrollbar-thumb:hover {
background: #333;
}
canvas {
width: 100%;
height: 1800px !important;
background: #fff;
border: 2px solid #ddd;
border-radius: 12px;
box-shadow: 0 4px 16px rgba(0,0,0,0.1);
}
/* 响应式调整保持默认缩放30%,不额外调整 */
@media (max-width: 1200px) {
.chart-container {
min-height: 1900px;
}
canvas {
height: 1800px !important;
}
h1 {
font-size: 48px;
}
h2 {
font-size: 36px;
}
}
</style>
<!-- 禁止页面缩放的meta标签 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
</head>
<body>
<div id="viewport" class="viewport">
<div id="content-size" class="content-size">
<div id="content" class="content">
<h1>style category</h1>
<div class="chart-section">
<h2>1. ALL </h2>
<div class="chart-container">
<canvas id="chartAll"></canvas>
</div>
</div>
<div class="chart-section">
<h2>2. Male </h2>
<div class="chart-container">
<canvas id="chartMale"></canvas>
</div>
</div>
<div class="chart-section">
<h2>3. Female </h2>
<div class="chart-container">
<canvas id="chartFemale"></canvas>
</div>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const viewport = document.getElementById('viewport');
const content = document.getElementById('content');
const contentSize = document.getElementById('content-size');
let MIN_SCALE = 1;
const MAX_SCALE = 3;
let scale = 1;
function computeMinScale() {
const cw = content.offsetWidth;
const vw = viewport.clientWidth;
if (!cw || !vw) return 1;
return Math.min(MAX_SCALE, Math.max(0.2, vw / cw));
}
function updateWrapperSize() {
const w = content.offsetWidth * scale;
const h = content.offsetHeight * scale;
contentSize.style.width = w + 'px';
contentSize.style.height = h + 'px';
}
function applyScale(newScale, ax, ay) {
const prev = scale;
const target = Math.max(MIN_SCALE, Math.min(MAX_SCALE, newScale));
if (target === prev) return;
const ratio = target / prev;
const rect = viewport.getBoundingClientRect();
const anchorX = ax != null ? ax : viewport.scrollLeft + viewport.clientWidth / 2;
const anchorY = ay != null ? ay : viewport.scrollTop + viewport.clientHeight / 2;
scale = target;
content.style.transform = 'scale(' + scale + ')';
updateWrapperSize();
let newLeft = anchorX * ratio - viewport.clientWidth / 2;
let newTop = anchorY * ratio - viewport.clientHeight / 2;
const maxLeft = Math.max(0, contentSize.scrollWidth - viewport.clientWidth);
const maxTop = Math.max(0, contentSize.scrollHeight - viewport.clientHeight);
viewport.scrollLeft = Math.max(0, Math.min(maxLeft, newLeft));
viewport.scrollTop = Math.max(0, Math.min(maxTop, newTop));
}
function initScale() {
MIN_SCALE = computeMinScale();
scale = MIN_SCALE;
content.style.transform = 'scale(' + scale + ')';
updateWrapperSize();
}
initScale();
let dragging = false;
let sx = 0, sy = 0, sl = 0, st = 0;
viewport.addEventListener('mousedown', function(e) {
if (e.button !== 0) return;
dragging = true;
viewport.style.cursor = 'grabbing';
sx = e.clientX;
sy = e.clientY;
sl = viewport.scrollLeft;
st = viewport.scrollTop;
});
window.addEventListener('mousemove', function(e) {
if (!dragging) return;
viewport.scrollLeft = sl - (e.clientX - sx);
viewport.scrollTop = st - (e.clientY - sy);
});
window.addEventListener('mouseup', function() {
dragging = false;
viewport.style.cursor = '';
});
viewport.addEventListener('wheel', function(e) {
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
const factor = e.deltaY < 0 ? 1.1 : 0.9;
const rect = viewport.getBoundingClientRect();
const ax = viewport.scrollLeft + (e.clientX - rect.left);
const ay = viewport.scrollTop + (e.clientY - rect.top);
const next = scale * factor;
applyScale(next < MIN_SCALE ? MIN_SCALE : next, ax, ay);
}
}, { passive: false });
window.addEventListener('resize', function() {
const prevMin = MIN_SCALE;
MIN_SCALE = computeMinScale();
if (scale < MIN_SCALE) {
applyScale(MIN_SCALE);
} else {
updateWrapperSize();
}
});
window.addEventListener('load', function() {
initScale();
});
});
// 共用配置 - 保持原有标签处理逻辑(下划线换行)
const labels = [
'ACADEMIC','BUSINESS','CASUAL','COUNTRY_STYLE','DOPAMINE','ETHNIC','FUTURISM',
'GOTHIC','LOLITA','MERLAD','MINIMALISM','NEW_CHINESE','OUTDOOR_FUNCTIONAL',
'POST_APOCALYPTIC','PREPPY','ROCK','ROMANTIC','SEXY','SWEET','WABI_SABI','Y2K','民族风'
].map(label => label.replace('_', '\n'));
// 所有数据(保持更新后的数值)
const allData = {
male_tops: [0,686,638,491,128,11,366,35,0,20,313,126,359,166,385,187,6,3,3,219,282,0],
male_bottoms: [0,280,199,141,132,1,43,49,0,13,178,93,279,10,96,25,0,5,0,163,239,0],
male_outwear: [0,2442,2147,1245,161,19,671,216,0,58,471,168,1001,319,803,367,11,1,1,278,631,0],
female_dress: [260,1030,4322,1158,256,0,397,340,488,279,1104,312,215,170,0,223,990,607,1438,293,292,159],
female_skirt: [408,662,1177,633,214,0,381,280,278,308,358,200,297,209,0,231,584,233,714,246,385,95],
female_blouse: [618,1275,3786,710,385,0,533,412,454,453,616,221,852,181,0,437,869,533,899,336,991,169],
female_outwear: [267,1255,740,453,178,0,418,160,101,301,273,172,712,172,0,245,198,13,159,280,500,76],
female_trousers: [171,782,1899,391,232,0,267,64,137,293,351,141,865,101,0,189,654,137,319,299,427,96]
};
// 颜色配置(保持原有颜色)
const colors = {
male_tops: '#1f77b4',
male_bottoms: '#ff7f0e',
male_outwear: '#2ca02c',
female_dress: '#d62728',
female_skirt: '#9467bd',
female_blouse: '#8c564b',
female_outwear: '#e377c2',
female_trousers: '#7f7f7f'
};
// 图表基础配置 - 核心修改categoryPercentage设为0.04原0.8的1/20扩大组间空隙20倍
const baseChartConfig = {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'top',
labels: {
font: { size: 60, weight: 'bold' },
padding: 60,
boxWidth: 60
},
padding: { bottom: 60 }
},
tooltip: {
mode: 'index',
intersect: false,
padding: 30,
titleFont: { size: 60 },
bodyFont: { size: 42 },
boxPadding: 20,
cornerRadius: 12
}
},
scales: {
x: {
stacked: false,
title: {
display: true,
text: '',
font: { size: 1, weight: 'bold' },
padding: { top: 1, bottom: 1 }
},
ticks: {
maxRotation: 0, // 保持原有斜放角度向左下45度
minRotation: 0, // 强制固定角度
autoSkip: false,
font: { size: 28, weight: 'bold' },
padding: 150,
color: '#333',
lineHeight: 1.3,
align: 'right' // 斜放标签右对齐,提升可读性
},
grid: { display: false },
border: { width: 3 },
categoryPercentage: 0.5, // 核心修改原0.8 → 0.04组间空隙扩大20倍
barPercentage: 0.8, // 保持组内柱子宽度不变
},
y: {
beginAtZero: true,
title: {
display: true,
text: '',
font: { size: 1, weight: 'bold' },
padding: { right: 1 }
},
ticks: {
font: { size: 33, weight: 'bold' },
padding: 30,
color: '#333',
stepSize: 500 // 适配更大数值范围
},
grid: { color: '#e0e0e0', lineWidth: 3 },
border: { width: 3 }
}
},
layout: {
padding: { top: 60, right: 90, bottom: 100, left: 90 }
},
animation: { duration: 1500, easing: 'easeOutQuart' },
barThickness: 'flex',
maxBarThickness: 70,
minBarLength: 5
};
// 1. 创建综合图表
new Chart(document.getElementById('chartAll'), {
type: 'bar',
data: {
labels: labels,
datasets: Object.keys(allData).map(key => ({
label: key,
data: allData[key],
backgroundColor: colors[key]
}))
},
options: { ...baseChartConfig }
});
// 2. 创建男性分类图表
new Chart(document.getElementById('chartMale'), {
type: 'bar',
data: {
labels: labels,
datasets: [
{ label: 'male_tops', data: allData.male_tops, backgroundColor: colors.male_tops },
{ label: 'male_bottoms', data: allData.male_bottoms, backgroundColor: colors.male_bottoms },
{ label: 'male_outwear', data: allData.male_outwear, backgroundColor: colors.male_outwear }
]
},
options: {
...baseChartConfig,
scales: {
...baseChartConfig.scales,
x: {
...baseChartConfig.scales.x,
categoryPercentage: 0.35
},
y: {
...baseChartConfig.scales.y,
stepSize: 800 // 适配男性外套最大值2442
}
}
}
});
// 3. 创建女性分类图表
new Chart(document.getElementById('chartFemale'), {
type: 'bar',
data: {
labels: labels,
datasets: [
{ label: 'female_dress', data: allData.female_dress, backgroundColor: colors.female_dress },
{ label: 'female_skirt', data: allData.female_skirt, backgroundColor: colors.female_skirt },
{ label: 'female_blouse', data: allData.female_blouse, backgroundColor: colors.female_blouse },
{ label: 'female_outwear', data: allData.female_outwear, backgroundColor: colors.female_outwear },
{ label: 'female_trousers', data: allData.female_trousers, backgroundColor: colors.female_trousers }
]
},
options: {
...baseChartConfig,
scales: {
...baseChartConfig.scales,
x: {
...baseChartConfig.scales.x,
categoryPercentage: 0.28
},
y: {
...baseChartConfig.scales.y,
stepSize: 1000 // 适配女性连衣裙最大值4322
}
}
}
});
</script>
</body>
</html>

View File

@@ -0,0 +1,539 @@
/* Logo 字体 */
@font-face {
font-family: "iconfont logo";
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
}
.logo {
font-family: "iconfont logo";
font-size: 160px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* tabs */
.nav-tabs {
position: relative;
}
.nav-tabs .nav-more {
position: absolute;
right: 0;
bottom: 0;
height: 42px;
line-height: 42px;
color: #666;
}
#tabs {
border-bottom: 1px solid #eee;
}
#tabs li {
cursor: pointer;
width: 100px;
height: 40px;
line-height: 40px;
text-align: center;
font-size: 16px;
border-bottom: 2px solid transparent;
position: relative;
z-index: 1;
margin-bottom: -1px;
color: #666;
}
#tabs .active {
border-bottom-color: #f00;
color: #222;
}
.tab-container .content {
display: none;
}
/* 页面布局 */
.main {
padding: 30px 100px;
width: 960px;
margin: 0 auto;
}
.main .logo {
color: #333;
text-align: left;
margin-bottom: 30px;
line-height: 1;
height: 110px;
margin-top: -50px;
overflow: hidden;
*zoom: 1;
}
.main .logo a {
font-size: 160px;
color: #333;
}
.helps {
margin-top: 40px;
}
.helps pre {
padding: 20px;
margin: 10px 0;
border: solid 1px #e7e1cd;
background-color: #fffdef;
overflow: auto;
}
.icon_lists {
width: 100% !important;
overflow: hidden;
*zoom: 1;
}
.icon_lists li {
width: 100px;
margin-bottom: 10px;
margin-right: 20px;
text-align: center;
list-style: none !important;
cursor: default;
}
.icon_lists li .code-name {
line-height: 1.2;
}
.icon_lists .icon {
display: block;
height: 100px;
line-height: 100px;
font-size: 42px;
margin: 10px auto;
color: #333;
-webkit-transition: font-size 0.25s linear, width 0.25s linear;
-moz-transition: font-size 0.25s linear, width 0.25s linear;
transition: font-size 0.25s linear, width 0.25s linear;
}
.icon_lists .icon:hover {
font-size: 100px;
}
.icon_lists .svg-icon {
/* 通过设置 font-size 来改变图标大小 */
width: 1em;
/* 图标和文字相邻时,垂直对齐 */
vertical-align: -0.15em;
/* 通过设置 color 来改变 SVG 的颜色/fill */
fill: currentColor;
/* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
normalize.css 中也包含这行 */
overflow: hidden;
}
.icon_lists li .name,
.icon_lists li .code-name {
color: #666;
}
/* markdown 样式 */
.markdown {
color: #666;
font-size: 14px;
line-height: 1.8;
}
.highlight {
line-height: 1.5;
}
.markdown img {
vertical-align: middle;
max-width: 100%;
}
.markdown h1 {
color: #404040;
font-weight: 500;
line-height: 40px;
margin-bottom: 24px;
}
.markdown h2,
.markdown h3,
.markdown h4,
.markdown h5,
.markdown h6 {
color: #404040;
margin: 1.6em 0 0.6em 0;
font-weight: 500;
clear: both;
}
.markdown h1 {
font-size: 28px;
}
.markdown h2 {
font-size: 22px;
}
.markdown h3 {
font-size: 16px;
}
.markdown h4 {
font-size: 14px;
}
.markdown h5 {
font-size: 12px;
}
.markdown h6 {
font-size: 12px;
}
.markdown hr {
height: 1px;
border: 0;
background: #e9e9e9;
margin: 16px 0;
clear: both;
}
.markdown p {
margin: 1em 0;
}
.markdown>p,
.markdown>blockquote,
.markdown>.highlight,
.markdown>ol,
.markdown>ul {
width: 80%;
}
.markdown ul>li {
list-style: circle;
}
.markdown>ul li,
.markdown blockquote ul>li {
margin-left: 20px;
padding-left: 4px;
}
.markdown>ul li p,
.markdown>ol li p {
margin: 0.6em 0;
}
.markdown ol>li {
list-style: decimal;
}
.markdown>ol li,
.markdown blockquote ol>li {
margin-left: 20px;
padding-left: 4px;
}
.markdown code {
margin: 0 3px;
padding: 0 5px;
background: #eee;
border-radius: 3px;
}
.markdown strong,
.markdown b {
font-weight: 600;
}
.markdown>table {
border-collapse: collapse;
border-spacing: 0px;
empty-cells: show;
border: 1px solid #e9e9e9;
width: 95%;
margin-bottom: 24px;
}
.markdown>table th {
white-space: nowrap;
color: #333;
font-weight: 600;
}
.markdown>table th,
.markdown>table td {
border: 1px solid #e9e9e9;
padding: 8px 16px;
text-align: left;
}
.markdown>table th {
background: #F7F7F7;
}
.markdown blockquote {
font-size: 90%;
color: #999;
border-left: 4px solid #e9e9e9;
padding-left: 0.8em;
margin: 1em 0;
}
.markdown blockquote p {
margin: 0;
}
.markdown .anchor {
opacity: 0;
transition: opacity 0.3s ease;
margin-left: 8px;
}
.markdown .waiting {
color: #ccc;
}
.markdown h1:hover .anchor,
.markdown h2:hover .anchor,
.markdown h3:hover .anchor,
.markdown h4:hover .anchor,
.markdown h5:hover .anchor,
.markdown h6:hover .anchor {
opacity: 1;
display: inline-block;
}
.markdown>br,
.markdown>p>br {
clear: both;
}
.hljs {
display: block;
background: white;
padding: 0.5em;
color: #333333;
overflow-x: auto;
}
.hljs-comment,
.hljs-meta {
color: #969896;
}
.hljs-string,
.hljs-variable,
.hljs-template-variable,
.hljs-strong,
.hljs-emphasis,
.hljs-quote {
color: #df5000;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-type {
color: #a71d5d;
}
.hljs-literal,
.hljs-symbol,
.hljs-bullet,
.hljs-attribute {
color: #0086b3;
}
.hljs-section,
.hljs-name {
color: #63a35c;
}
.hljs-tag {
color: #333333;
}
.hljs-title,
.hljs-attr,
.hljs-selector-id,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #795da3;
}
.hljs-addition {
color: #55a532;
background-color: #eaffea;
}
.hljs-deletion {
color: #bd2c00;
background-color: #ffecec;
}
.hljs-link {
text-decoration: underline;
}
/* 代码高亮 */
/* PrismJS 1.15.0
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
/**
* prism.js default theme for JavaScript, CSS and HTML
* Based on dabblet (http://dabblet.com)
* @author Lea Verou
*/
code[class*="language-"],
pre[class*="language-"] {
color: black;
background: none;
text-shadow: 0 1px white;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
pre[class*="language-"]::-moz-selection,
pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection,
code[class*="language-"] ::-moz-selection {
text-shadow: none;
background: #b3d4fc;
}
pre[class*="language-"]::selection,
pre[class*="language-"] ::selection,
code[class*="language-"]::selection,
code[class*="language-"] ::selection {
text-shadow: none;
background: #b3d4fc;
}
@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
}
:not(pre)>code[class*="language-"],
pre[class*="language-"] {
background: #f5f2f0;
}
/* Inline code */
:not(pre)>code[class*="language-"] {
padding: .1em;
border-radius: .3em;
white-space: normal;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: slategray;
}
.token.punctuation {
color: #999;
}
.namespace {
opacity: .7;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
color: #905;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #690;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #9a6e3a;
background: hsla(0, 0%, 100%, .5);
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}
.token.function,
.token.class-name {
color: #DD4A68;
}
.token.regex,
.token.important,
.token.variable {
color: #e90;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}

View File

@@ -0,0 +1,970 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>iconfont Demo</title>
<link rel="shortcut icon" href="//img.alicdn.com/imgextra/i4/O1CN01Z5paLz1O0zuCC7osS_!!6000000001644-55-tps-83-82.svg" type="image/x-icon"/>
<link rel="icon" type="image/svg+xml" href="//img.alicdn.com/imgextra/i4/O1CN01Z5paLz1O0zuCC7osS_!!6000000001644-55-tps-83-82.svg"/>
<link rel="stylesheet" href="https://g.alicdn.com/thx/cube/1.3.2/cube.min.css">
<link rel="stylesheet" href="demo.css">
<link rel="stylesheet" href="iconfont.css">
<script src="iconfont.js"></script>
<!-- jQuery -->
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/7bfddb60-08e8-11e9-9b04-53e73bb6408b.js"></script>
<!-- 代码高亮 -->
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/a3f714d0-08e6-11e9-8a15-ebf944d7534c.js"></script>
<style>
.main .logo {
margin-top: 0;
height: auto;
}
.main .logo a {
display: flex;
align-items: center;
}
.main .logo .sub-title {
margin-left: 0.5em;
font-size: 22px;
color: #fff;
background: linear-gradient(-45deg, #3967FF, #B500FE);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
</style>
</head>
<body>
<div class="main">
<h1 class="logo"><a href="https://www.iconfont.cn/" title="iconfont 首页" target="_blank">
<img width="200" src="https://img.alicdn.com/imgextra/i3/O1CN01Mn65HV1FfSEzR6DKv_!!6000000000514-55-tps-228-59.svg">
</a></h1>
<div class="nav-tabs">
<ul id="tabs" class="dib-box">
<li class="dib active"><span>Unicode</span></li>
<li class="dib"><span>Font class</span></li>
<li class="dib"><span>Symbol</span></li>
</ul>
<a href="https://www.iconfont.cn/manage/index?manage_type=myprojects&projectId=4292253" target="_blank" class="nav-more">查看项目</a>
</div>
<div class="tab-container">
<div class="content unicode" style="display: block;">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont">&#xe650;</span>
<div class="name">裁剪</div>
<div class="code-name">&amp;#xe650;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe60a;</span>
<div class="name">角度</div>
<div class="code-name">&amp;#xe60a;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe69e;</span>
<div class="name">水平翻转</div>
<div class="code-name">&amp;#xe69e;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xec60;</span>
<div class="name">垂直翻转</div>
<div class="code-name">&amp;#xec60;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe8d1;</span>
<div class="name">clothes</div>
<div class="code-name">&amp;#xe8d1;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe647;</span>
<div class="name">材质</div>
<div class="code-name">&amp;#xe647;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe61b;</span>
<div class="name">IC-液化</div>
<div class="code-name">&amp;#xe61b;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe751;</span>
<div class="name">上一层</div>
<div class="code-name">&amp;#xe751;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe604;</span>
<div class="name">上一层</div>
<div class="code-name">&amp;#xe604;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe68a;</span>
<div class="name">下一层</div>
<div class="code-name">&amp;#xe68a;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe68b;</span>
<div class="name">上一层</div>
<div class="code-name">&amp;#xe68b;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe6a1;</span>
<div class="name">审批</div>
<div class="code-name">&amp;#xe6a1;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe617;</span>
<div class="name">用户</div>
<div class="code-name">&amp;#xe617;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe601;</span>
<div class="name">使用次数</div>
<div class="code-name">&amp;#xe601;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe634;</span>
<div class="name">下拉</div>
<div class="code-name">&amp;#xe634;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe600;</span>
<div class="name">编辑</div>
<div class="code-name">&amp;#xe600;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe64f;</span>
<div class="name">圆形</div>
<div class="code-name">&amp;#xe64f;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe615;</span>
<div class="name">三角形</div>
<div class="code-name">&amp;#xe615;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe632;</span>
<div class="name">图层</div>
<div class="code-name">&amp;#xe632;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe616;</span>
<div class="name">平移</div>
<div class="code-name">&amp;#xe616;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe67b;</span>
<div class="name">橡皮</div>
<div class="code-name">&amp;#xe67b;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe64c;</span>
<div class="name">tx-fill-椭圆形</div>
<div class="code-name">&amp;#xe64c;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe602;</span>
<div class="name">直线</div>
<div class="code-name">&amp;#xe602;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xec5f;</span>
<div class="name">线</div>
<div class="code-name">&amp;#xec5f;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xea6f;</span>
<div class="name">正方形</div>
<div class="code-name">&amp;#xea6f;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe62d;</span>
<div class="name">图层</div>
<div class="code-name">&amp;#xe62d;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe685;</span>
<div class="name">点位</div>
<div class="code-name">&amp;#xe685;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe620;</span>
<div class="name">并集</div>
<div class="code-name">&amp;#xe620;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe668;</span>
<div class="name">并集</div>
<div class="code-name">&amp;#xe668;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe603;</span>
<div class="name">标签</div>
<div class="code-name">&amp;#xe603;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe85f;</span>
<div class="name">语言</div>
<div class="code-name">&amp;#xe85f;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe626;</span>
<div class="name">撤销 返回 撤回 上一步</div>
<div class="code-name">&amp;#xe626;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe609;</span>
<div class="name">撤销 返回 撤回 上一步</div>
<div class="code-name">&amp;#xe609;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe66c;</span>
<div class="name">外套_长款外套1@1x</div>
<div class="code-name">&amp;#xe66c;</div>
</li>
</ul>
<div class="article markdown">
<h2 id="unicode-">Unicode 引用</h2>
<hr>
<p>Unicode 是字体在网页端最原始的应用方式,特点是:</p>
<ul>
<li>支持按字体的方式去动态调整图标大小,颜色等等。</li>
<li>默认情况下不支持多色,直接添加多色图标会自动去色。</li>
</ul>
<blockquote>
<p>注意:新版 iconfont 支持两种方式引用多色图标SVG symbol 引用方式和彩色字体图标模式。(使用彩色字体图标需要在「编辑项目」中开启「彩色」选项后并重新生成。)</p>
</blockquote>
<p>Unicode 使用步骤如下:</p>
<h3 id="-font-face">第一步:拷贝项目下面生成的 <code>@font-face</code></h3>
<pre><code class="language-css"
>@font-face {
font-family: 'iconfont';
src: url('iconfont.woff2?t=1762934152017') format('woff2'),
url('iconfont.woff?t=1762934152017') format('woff'),
url('iconfont.ttf?t=1762934152017') format('truetype');
}
</code></pre>
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
<pre><code class="language-css"
>.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
</code></pre>
<h3 id="-">第三步:挑选相应图标并获取字体编码,应用于页面</h3>
<pre>
<code class="language-html"
>&lt;span class="iconfont"&gt;&amp;#x33;&lt;/span&gt;
</code></pre>
<blockquote>
<p>"iconfont" 是你项目下的 font-family。可以通过编辑项目查看默认是 "iconfont"。</p>
</blockquote>
</div>
</div>
<div class="content font-class">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont icon-caijian"></span>
<div class="name">
裁剪
</div>
<div class="code-name">.icon-caijian
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-angle"></span>
<div class="name">
角度
</div>
<div class="code-name">.icon-angle
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-flip-horizontal"></span>
<div class="name">
水平翻转
</div>
<div class="code-name">.icon-flip-horizontal
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-flip-vertical"></span>
<div class="name">
垂直翻转
</div>
<div class="code-name">.icon-flip-vertical
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-clothes"></span>
<div class="name">
clothes
</div>
<div class="code-name">.icon-clothes
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-caizhi"></span>
<div class="name">
材质
</div>
<div class="code-name">.icon-caizhi
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-IC-yehua"></span>
<div class="name">
IC-液化
</div>
<div class="code-name">.icon-IC-yehua
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-shangyiceng"></span>
<div class="name">
上一层
</div>
<div class="code-name">.icon-shangyiceng
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-shangyiceng1"></span>
<div class="name">
上一层
</div>
<div class="code-name">.icon-shangyiceng1
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-xiayiceng"></span>
<div class="name">
下一层
</div>
<div class="code-name">.icon-xiayiceng
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-shangyiceng2"></span>
<div class="name">
上一层
</div>
<div class="code-name">.icon-shangyiceng2
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-shenpi"></span>
<div class="name">
审批
</div>
<div class="code-name">.icon-shenpi
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-yonghu"></span>
<div class="name">
用户
</div>
<div class="code-name">.icon-yonghu
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-usetime"></span>
<div class="name">
使用次数
</div>
<div class="code-name">.icon-usetime
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-xiala"></span>
<div class="name">
下拉
</div>
<div class="code-name">.icon-xiala
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-bianji"></span>
<div class="name">
编辑
</div>
<div class="code-name">.icon-bianji
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-circle"></span>
<div class="name">
圆形
</div>
<div class="code-name">.icon-circle
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-sanjiaoxing"></span>
<div class="name">
三角形
</div>
<div class="code-name">.icon-sanjiaoxing
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-tuceng"></span>
<div class="name">
图层
</div>
<div class="code-name">.icon-tuceng
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-move"></span>
<div class="name">
平移
</div>
<div class="code-name">.icon-move
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-xiangpi_huaban1"></span>
<div class="name">
橡皮
</div>
<div class="code-name">.icon-xiangpi_huaban1
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-tx-fill-tuoyuanxing"></span>
<div class="name">
tx-fill-椭圆形
</div>
<div class="code-name">.icon-tx-fill-tuoyuanxing
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-zhixian"></span>
<div class="name">
直线
</div>
<div class="code-name">.icon-zhixian
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-xian"></span>
<div class="name">
线
</div>
<div class="code-name">.icon-xian
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-checkbox-full"></span>
<div class="name">
正方形
</div>
<div class="code-name">.icon-checkbox-full
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-tuceng1"></span>
<div class="name">
图层
</div>
<div class="code-name">.icon-tuceng1
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-dianwei"></span>
<div class="name">
点位
</div>
<div class="code-name">.icon-dianwei
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-bingji"></span>
<div class="name">
并集
</div>
<div class="code-name">.icon-bingji
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-bingji1"></span>
<div class="name">
并集
</div>
<div class="code-name">.icon-bingji1
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-biaoqian"></span>
<div class="name">
标签
</div>
<div class="code-name">.icon-biaoqian
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-yuyan"></span>
<div class="name">
语言
</div>
<div class="code-name">.icon-yuyan
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-fanchehui"></span>
<div class="name">
撤销 返回 撤回 上一步
</div>
<div class="code-name">.icon-fanchehui
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-chehui"></span>
<div class="name">
撤销 返回 撤回 上一步
</div>
<div class="code-name">.icon-chehui
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-a-waitao_changkuanwaitao11x"></span>
<div class="name">
外套_长款外套1@1x
</div>
<div class="code-name">.icon-a-waitao_changkuanwaitao11x
</div>
</li>
</ul>
<div class="article markdown">
<h2 id="font-class-">font-class 引用</h2>
<hr>
<p>font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。</p>
<p>与 Unicode 使用方式相比,具有如下特点:</p>
<ul>
<li>相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。</li>
<li>因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。</li>
</ul>
<p>使用步骤如下:</p>
<h3 id="-fontclass-">第一步:引入项目下面生成的 fontclass 代码:</h3>
<pre><code class="language-html">&lt;link rel="stylesheet" href="./iconfont.css"&gt;
</code></pre>
<h3 id="-">第二步:挑选相应图标并获取类名,应用于页面:</h3>
<pre><code class="language-html">&lt;span class="iconfont icon-xxx"&gt;&lt;/span&gt;
</code></pre>
<blockquote>
<p>"
iconfont" 是你项目下的 font-family。可以通过编辑项目查看默认是 "iconfont"。</p>
</blockquote>
</div>
</div>
<div class="content symbol">
<ul class="icon_lists dib-box">
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-caijian"></use>
</svg>
<div class="name">裁剪</div>
<div class="code-name">#icon-caijian</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-angle"></use>
</svg>
<div class="name">角度</div>
<div class="code-name">#icon-angle</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-flip-horizontal"></use>
</svg>
<div class="name">水平翻转</div>
<div class="code-name">#icon-flip-horizontal</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-flip-vertical"></use>
</svg>
<div class="name">垂直翻转</div>
<div class="code-name">#icon-flip-vertical</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-clothes"></use>
</svg>
<div class="name">clothes</div>
<div class="code-name">#icon-clothes</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-caizhi"></use>
</svg>
<div class="name">材质</div>
<div class="code-name">#icon-caizhi</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-IC-yehua"></use>
</svg>
<div class="name">IC-液化</div>
<div class="code-name">#icon-IC-yehua</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-shangyiceng"></use>
</svg>
<div class="name">上一层</div>
<div class="code-name">#icon-shangyiceng</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-shangyiceng1"></use>
</svg>
<div class="name">上一层</div>
<div class="code-name">#icon-shangyiceng1</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-xiayiceng"></use>
</svg>
<div class="name">下一层</div>
<div class="code-name">#icon-xiayiceng</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-shangyiceng2"></use>
</svg>
<div class="name">上一层</div>
<div class="code-name">#icon-shangyiceng2</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-shenpi"></use>
</svg>
<div class="name">审批</div>
<div class="code-name">#icon-shenpi</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-yonghu"></use>
</svg>
<div class="name">用户</div>
<div class="code-name">#icon-yonghu</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-usetime"></use>
</svg>
<div class="name">使用次数</div>
<div class="code-name">#icon-usetime</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-xiala"></use>
</svg>
<div class="name">下拉</div>
<div class="code-name">#icon-xiala</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-bianji"></use>
</svg>
<div class="name">编辑</div>
<div class="code-name">#icon-bianji</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-circle"></use>
</svg>
<div class="name">圆形</div>
<div class="code-name">#icon-circle</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-sanjiaoxing"></use>
</svg>
<div class="name">三角形</div>
<div class="code-name">#icon-sanjiaoxing</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-tuceng"></use>
</svg>
<div class="name">图层</div>
<div class="code-name">#icon-tuceng</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-move"></use>
</svg>
<div class="name">平移</div>
<div class="code-name">#icon-move</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-xiangpi_huaban1"></use>
</svg>
<div class="name">橡皮</div>
<div class="code-name">#icon-xiangpi_huaban1</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-tx-fill-tuoyuanxing"></use>
</svg>
<div class="name">tx-fill-椭圆形</div>
<div class="code-name">#icon-tx-fill-tuoyuanxing</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-zhixian"></use>
</svg>
<div class="name">直线</div>
<div class="code-name">#icon-zhixian</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-xian"></use>
</svg>
<div class="name">线</div>
<div class="code-name">#icon-xian</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-checkbox-full"></use>
</svg>
<div class="name">正方形</div>
<div class="code-name">#icon-checkbox-full</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-tuceng1"></use>
</svg>
<div class="name">图层</div>
<div class="code-name">#icon-tuceng1</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-dianwei"></use>
</svg>
<div class="name">点位</div>
<div class="code-name">#icon-dianwei</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-bingji"></use>
</svg>
<div class="name">并集</div>
<div class="code-name">#icon-bingji</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-bingji1"></use>
</svg>
<div class="name">并集</div>
<div class="code-name">#icon-bingji1</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-biaoqian"></use>
</svg>
<div class="name">标签</div>
<div class="code-name">#icon-biaoqian</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-yuyan"></use>
</svg>
<div class="name">语言</div>
<div class="code-name">#icon-yuyan</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-fanchehui"></use>
</svg>
<div class="name">撤销 返回 撤回 上一步</div>
<div class="code-name">#icon-fanchehui</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-chehui"></use>
</svg>
<div class="name">撤销 返回 撤回 上一步</div>
<div class="code-name">#icon-chehui</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-a-waitao_changkuanwaitao11x"></use>
</svg>
<div class="name">外套_长款外套1@1x</div>
<div class="code-name">#icon-a-waitao_changkuanwaitao11x</div>
</li>
</ul>
<div class="article markdown">
<h2 id="symbol-">Symbol 引用</h2>
<hr>
<p>这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇<a href="">文章</a>
这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:</p>
<ul>
<li>支持多色图标了,不再受单色限制。</li>
<li>通过一些技巧,支持像字体那样,通过 <code>font-size</code>, <code>color</code> 来调整样式。</li>
<li>兼容性较差,支持 IE9+,及现代浏览器。</li>
<li>浏览器渲染 SVG 的性能一般,还不如 png。</li>
</ul>
<p>使用步骤如下:</p>
<h3 id="-symbol-">第一步:引入项目下面生成的 symbol 代码:</h3>
<pre><code class="language-html">&lt;script src="./iconfont.js"&gt;&lt;/script&gt;
</code></pre>
<h3 id="-css-">第二步:加入通用 CSS 代码(引入一次就行):</h3>
<pre><code class="language-html">&lt;style&gt;
.icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
&lt;/style&gt;
</code></pre>
<h3 id="-">第三步:挑选相应图标并获取类名,应用于页面:</h3>
<pre><code class="language-html">&lt;svg class="icon" aria-hidden="true"&gt;
&lt;use xlink:href="#icon-xxx"&gt;&lt;/use&gt;
&lt;/svg&gt;
</code></pre>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function () {
$('.tab-container .content:first').show()
$('#tabs li').click(function (e) {
var tabContent = $('.tab-container .content')
var index = $(this).index()
if ($(this).hasClass('active')) {
return
} else {
$('#tabs li').removeClass('active')
$(this).addClass('active')
tabContent.hide().eq(index).fadeIn()
}
})
})
</script>
</body>
</html>

View File

@@ -1,18 +1,38 @@
@font-face {
font-family: "iconfont"; /* Project id 4292253 */
src: url('iconfont.woff2?t=1727415711578') format('woff2'),
url('iconfont.woff?t=1727415711578') format('woff'),
url('iconfont.ttf?t=1727415711578') format('truetype');
src: url('iconfont.woff2?t=1762934152017') format('woff2'),
url('iconfont.woff?t=1762934152017') format('woff'),
url('iconfont.ttf?t=1762934152017') format('truetype');
}
.iconfont {
font-family: "iconfont" !important;
font-size: 1.8rem;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-caijian:before {
content: "\e650";
}
.icon-angle:before {
content: "\e60a";
}
.icon-flip-horizontal:before {
content: "\e69e";
}
.icon-flip-vertical:before {
content: "\ec60";
}
.icon-clothes:before {
content: "\e8d1";
}
.icon-caizhi:before {
content: "\e647";
}

File diff suppressed because one or more lines are too long

View File

@@ -1,170 +1,247 @@
{
"id": "",
"name": "",
"id": "4292253",
"name": "aida",
"font_family": "iconfont",
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "124968799",
"name": "外套_长款外套1@1x",
"font_class": "a-waitao_changkuanwaitao11x",
"unicode": "e66c",
"unicode_decimal": 58988
"icon_id": "22138606",
"name": "裁剪",
"font_class": "caijian",
"unicode": "e650",
"unicode_decimal": 58960
},
{
"icon_id": "125198319",
"name": "撤销 返回 撤回 上一步",
"font_class": "fanchehui",
"unicode": "e626",
"unicode_decimal": 58918
"icon_id": "8875396",
"name": "角度",
"font_class": "angle",
"unicode": "e60a",
"unicode_decimal": 58890
},
{
"icon_id": "125198320",
"name": "撤销 返回 撤回 上一步",
"font_class": "chehui",
"unicode": "e609",
"unicode_decimal": 58889
"icon_id": "15551512",
"name": "水平翻转",
"font_class": "flip-horizontal",
"unicode": "e69e",
"unicode_decimal": 59038
},
{
"icon_id": "125524062",
"name": "语言",
"font_class": "yuyan",
"unicode": "e85f",
"unicode_decimal": 59487
"icon_id": "46016160",
"name": "垂直翻转",
"font_class": "flip-vertical",
"unicode": "ec60",
"unicode_decimal": 60512
},
{
"icon_id": "126177191",
"name": "标签",
"font_class": "biaoqian",
"unicode": "e603",
"unicode_decimal": 58883
"icon_id": "20183053",
"name": "clothes",
"font_class": "clothes",
"unicode": "e8d1",
"unicode_decimal": 59601
},
{
"icon_id": "126459101",
"name": "并集",
"font_class": "bingji",
"unicode": "e620",
"unicode_decimal": 58912
"icon_id": "15739173",
"name": "材质",
"font_class": "caizhi",
"unicode": "e647",
"unicode_decimal": 58951
},
{
"icon_id": "126459102",
"name": "并集",
"font_class": "bingji1",
"unicode": "e668",
"unicode_decimal": 58984
"icon_id": "35023469",
"name": "IC-液化",
"font_class": "IC-yehua",
"unicode": "e61b",
"unicode_decimal": 58907
},
{
"icon_id": "126901286",
"name": "点位",
"font_class": "dianwei",
"unicode": "e685",
"unicode_decimal": 59013
"icon_id": "12096844",
"name": "上一层",
"font_class": "shangyiceng",
"unicode": "e751",
"unicode_decimal": 59217
},
{
"icon_id": "130743908",
"name": "编辑",
"font_class": "bianji",
"unicode": "e600",
"unicode_decimal": 58880
"icon_id": "16531912",
"name": "上一层",
"font_class": "shangyiceng1",
"unicode": "e604",
"unicode_decimal": 58884
},
{
"icon_id": "130743909",
"name": "圆形",
"font_class": "circle",
"unicode": "e64f",
"unicode_decimal": 58959
"icon_id": "24253227",
"name": "下一层",
"font_class": "xiayiceng",
"unicode": "e68a",
"unicode_decimal": 59018
},
{
"icon_id": "130743910",
"name": "三角形",
"font_class": "sanjiaoxing",
"unicode": "e615",
"unicode_decimal": 58901
"icon_id": "24253230",
"name": "上一层",
"font_class": "shangyiceng2",
"unicode": "e68b",
"unicode_decimal": 59019
},
{
"icon_id": "130743911",
"name": "图层",
"font_class": "tuceng",
"unicode": "e632",
"unicode_decimal": 58930
},
{
"icon_id": "130743912",
"name": "平移",
"font_class": "move",
"unicode": "e616",
"unicode_decimal": 58902
},
{
"icon_id": "130743913",
"name": "橡皮",
"font_class": "xiangpi_huaban1",
"unicode": "e67b",
"unicode_decimal": 59003
},
{
"icon_id": "130743914",
"name": "tx-fill-椭圆形",
"font_class": "tx-fill-tuoyuanxing",
"unicode": "e64c",
"unicode_decimal": 58956
},
{
"icon_id": "130743915",
"name": "直线",
"font_class": "zhixian",
"unicode": "e602",
"unicode_decimal": 58882
},
{
"icon_id": "130743916",
"name": "线",
"font_class": "xian",
"unicode": "ec5f",
"unicode_decimal": 60511
},
{
"icon_id": "130743917",
"name": "正方形",
"font_class": "checkbox-full",
"unicode": "ea6f",
"unicode_decimal": 60015
},
{
"icon_id": "130743918",
"name": "图层",
"font_class": "tuceng1",
"unicode": "e62d",
"unicode_decimal": 58925
},
{
"icon_id": "130751283",
"icon_id": "3663275",
"name": "审批",
"font_class": "shenpi",
"unicode": "e6a1",
"unicode_decimal": 59041
},
{
"icon_id": "130751284",
"icon_id": "7638976",
"name": "用户",
"font_class": "yonghu",
"unicode": "e617",
"unicode_decimal": 58903
},
{
"icon_id": "130751285",
"icon_id": "9775414",
"name": "使用次数",
"font_class": "usetime",
"unicode": "e601",
"unicode_decimal": 58881
},
{
"icon_id": "130751286",
"icon_id": "16843615",
"name": "下拉",
"font_class": "xiala",
"unicode": "e634",
"unicode_decimal": 58932
},
{
"icon_id": "1264",
"name": "编辑",
"font_class": "bianji",
"unicode": "e600",
"unicode_decimal": 58880
},
{
"icon_id": "755612",
"name": "圆形",
"font_class": "circle",
"unicode": "e64f",
"unicode_decimal": 58959
},
{
"icon_id": "3101162",
"name": "三角形",
"font_class": "sanjiaoxing",
"unicode": "e615",
"unicode_decimal": 58901
},
{
"icon_id": "6774075",
"name": "图层",
"font_class": "tuceng",
"unicode": "e632",
"unicode_decimal": 58930
},
{
"icon_id": "10905244",
"name": "平移",
"font_class": "move",
"unicode": "e616",
"unicode_decimal": 58902
},
{
"icon_id": "14421659",
"name": "橡皮",
"font_class": "xiangpi_huaban1",
"unicode": "e67b",
"unicode_decimal": 59003
},
{
"icon_id": "14718690",
"name": "tx-fill-椭圆形",
"font_class": "tx-fill-tuoyuanxing",
"unicode": "e64c",
"unicode_decimal": 58956
},
{
"icon_id": "17521049",
"name": "直线",
"font_class": "zhixian",
"unicode": "e602",
"unicode_decimal": 58882
},
{
"icon_id": "17581689",
"name": "线",
"font_class": "xian",
"unicode": "ec5f",
"unicode_decimal": 60511
},
{
"icon_id": "18175800",
"name": "正方形",
"font_class": "checkbox-full",
"unicode": "ea6f",
"unicode_decimal": 60015
},
{
"icon_id": "26998795",
"name": "图层",
"font_class": "tuceng1",
"unicode": "e62d",
"unicode_decimal": 58925
},
{
"icon_id": "31762941",
"name": "点位",
"font_class": "dianwei",
"unicode": "e685",
"unicode_decimal": 59013
},
{
"icon_id": "8722601",
"name": "并集",
"font_class": "bingji",
"unicode": "e620",
"unicode_decimal": 58912
},
{
"icon_id": "15192904",
"name": "并集",
"font_class": "bingji1",
"unicode": "e668",
"unicode_decimal": 58984
},
{
"icon_id": "17863630",
"name": "标签",
"font_class": "biaoqian",
"unicode": "e603",
"unicode_decimal": 58883
},
{
"icon_id": "16399020",
"name": "语言",
"font_class": "yuyan",
"unicode": "e85f",
"unicode_decimal": 59487
},
{
"icon_id": "4240742",
"name": "撤销 返回 撤回 上一步",
"font_class": "fanchehui",
"unicode": "e626",
"unicode_decimal": 58918
},
{
"icon_id": "6126117",
"name": "撤销 返回 撤回 上一步",
"font_class": "chehui",
"unicode": "e609",
"unicode_decimal": 58889
},
{
"icon_id": "33174601",
"name": "外套_长款外套1@1x",
"font_class": "a-waitao_changkuanwaitao11x",
"unicode": "e66c",
"unicode_decimal": 58988
}
]
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

@@ -0,0 +1 @@
<svg t="1763432312095" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4678" width="200" height="200"><path d="M509.92 176C325.504 176 176 325.504 176 509.92c0 184.416 149.504 333.92 333.92 333.92 184.416 0 333.92-149.504 333.92-333.92C843.84 325.504 694.32 176 509.92 176z m166.64 214.848a16 16 0 0 1 22.624 0l11.328 11.312a16 16 0 0 1 0 22.624l-254.08 254.08a16 16 0 0 1-22.624 0l-159.616-159.632a16 16 0 0 1 0-22.624l11.312-11.312a16 16 0 0 1 22.624 0l136.992 136.992z" fill="currentColor" p-id="4679"></path></svg>

After

Width:  |  Height:  |  Size: 562 B

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1759472135618" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="15482" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M341.12 85.333h373.845A170.667 170.667 0 0 1 835.67 135.34l130.987 130.986a46.933 46.933 0 0 1 8.79 54.187l-82.774 165.547A46.933 46.933 0 0 1 850.688 512h-40.021v298.667a128 128 0 0 1-128 128H341.333a128 128 0 0 1-128-128V512h-40.021a46.933 46.933 0 0 1-41.984-25.941L48.555 320.512a46.933 46.933 0 0 1 8.789-54.187L188.331 135.34a170.667 170.667 0 0 1 120.704-50.006h32.085z m-18.944 85.334h-13.141a85.333 85.333 0 0 0-60.374 25.002L137.26 307.072l59.776 119.595h54.698a46.933 46.933 0 0 1 46.934 46.933v337.067a42.667 42.667 0 0 0 42.666 42.666h341.334a42.667 42.667 0 0 0 42.666-42.666V473.6a46.933 46.933 0 0 1 46.934-46.933h54.698l59.776-119.595L775.34 195.669a85.333 85.333 0 0 0-60.374-25.002h-13.141L575.787 312.49a85.333 85.333 0 0 1-127.574 0L322.176 170.667z m114.176 0L512 255.787l75.648-85.12H436.352z" fill="#2c2c2c" p-id="15483"></path></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" data-name="Layer 1" viewBox="0 0 24 24" width="512" height="512"><path d="m16,18.5v1c0,2.481-2.019,4.5-4.5,4.5h-7c-2.481,0-4.5-2.019-4.5-4.5v-7c0-2.481,2.019-4.5,4.5-4.5h1c.276,0,.5.224.5.5s-.224.5-.5.5h-1c-1.93,0-3.5,1.57-3.5,3.5v7c0,1.93,1.57,3.5,3.5,3.5h7c1.93,0,3.5-1.57,3.5-3.5v-1c0-.276.224-.5.5-.5s.5.224.5.5Zm8-14v7c0,2.481-2.019,4.5-4.5,4.5h-7c-2.481,0-4.5-2.019-4.5-4.5v-7c0-2.481,2.019-4.5,4.5-4.5h7c2.481,0,4.5,2.019,4.5,4.5Zm-1,0c0-1.93-1.57-3.5-3.5-3.5h-7c-1.93,0-3.5,1.57-3.5,3.5v7c0,1.93,1.57,3.5,3.5,3.5h7c1.93,0,3.5-1.57,3.5-3.5v-7Z"/></svg>

After

Width:  |  Height:  |  Size: 652 B

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" data-name="Layer 1" viewBox="0 0 24 24" width="512" height="512"><path d="M23.5,24H.5c-.28,0-.5-.22-.5-.5s.22-.5,.5-.5H23.5c.28,0,.5,.22,.5,.5s-.22,.5-.5,.5Zm-8.83-4.09l6.56-7.35c.77-.77,.98-1.88,.57-2.88-.42-1.01-1.36-1.65-2.45-1.65h-2.34V3.47c0-1.92-1.57-3.47-3.51-3.47h-2.99c-1.93,0-3.51,1.56-3.51,3.47v4.55s-2.33,0-2.33,0c-1.1,0-2.04,.64-2.45,1.65s-.19,2.12,.56,2.88l6.59,7.38c.73,.73,1.68,1.09,2.64,1.09s1.93-.37,2.67-1.11ZM7.5,9.03c.13,0,.26-.05,.35-.15s.15-.22,.15-.35V3.47c0-1.36,1.12-2.47,2.5-2.47h2.99c1.38,0,2.51,1.11,2.51,2.47v5.05c0,.28,.22,.5,.5,.5h2.84c.82,0,1.33,.54,1.53,1.03,.2,.5,.21,1.23-.36,1.81,0,0-.01,.01-.02,.02l-6.55,7.34c-1.07,1.07-2.81,1.07-3.86,.02L3.49,11.86c-.58-.58-.57-1.31-.36-1.81,.2-.5,.71-1.03,1.53-1.03h2.84Z"/></svg>

After

Width:  |  Height:  |  Size: 848 B

View File

@@ -0,0 +1,9 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect width="20" height="20" fill="url(#pattern0_2040_2152)"/>
<defs>
<pattern id="pattern0_2040_2152" patternContentUnits="objectBoundingBox" width="1" height="1">
<use xlink:href="#image0_2040_2152" transform="scale(0.015625)"/>
</pattern>
<image id="image0_2040_2152" width="64" height="64" preserveAspectRatio="none" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAAAHYAAAB2AH6XKZyAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAABVhJREFUeJztm11sFUUUx3/XoFSQ0goJivjZKKmASPUqRsTvqjEqNaKRaOKT0ahRY4I+qFEBDT6oiS/65osPNn5ECdCgEGpoxSKJYv2oiLYRio1KsFYC1N7rw7m32Xtmdm93dvYS4/6TSZgy/Z//zO6ec+bMFDJkyJAhw/8XuRrZaQIuAy4CzgXOAmYAk0v/P1xq+4BdQC/QBfxUI32poBlYC3wPFB3bt8DLwPk11p4INwGf4j5pWysAHwM313AesZEHPsPvxG1tE/J2eYEPH1CHvOoPA8eFjCkAXwKdwHZgP/B7qf0D1AMNwFxgAbAYWAqcEMI3CrwKPAMc9TAHZ5yDOK2o13YF0OjAPQ24C9gawl8EtgGnJJlAErQgT9Im7H1goUdbC4GOEFt7gUs82poQrkfClhazG7g2RbvLgJ8tdoep4SLkgUMWEW8jr23aaADWW+z/gfiPVDEHGLQYX0PtkioQZ7vGomM/cFpaRuuAncpgAfH+xwrPYi7CZsKjUSKsshhblYahmFiLqWulbyPNwBFl5F1q+9qHIQdsoFLbETwmS2DG4l9wc3jTgfuBjUA/cADoA9qBewhPfKphFjCkNL7nyGXgasxXrM2B507gTwtXsA0gIdYFbYqrgKfQ+JEiXufAsZLoiQfbGHCfo9ZtimuDI884zisJCpIujslxJZLvx9nwHEVqB3GxBHMxT3fgGcdqRdjtwNGjOEaQTcwFSMxeAryJTDo4bouj5m7F86QjDyA7uCDZipi/vwjziVwVMrYN+W6D4+fEVgwPKI5eBw4oGQ8KGkXS0Dh4SIlprzJ+hxp/S0x7ACcDhxXP7LDBURlTK5Vxvgs4GFNMJxKTQfzAa1XGD6p+XUx7IKG1R/3s0rDBUQug63CbHcT0IsXQp5BvPcqHzMT8PPodbIIUXYIIXYAo6PC33FHMRDAVM9kaBCY58t2huDpcSHQ112eBI4hp2IuoTyTg1M53pwvJAUXiUtaqhgbgc8zJd+L+9AHOUHz9LiQHFclJCQTZcDxSM9ST/wLx5EkwVXH+5UKiS15TEorSeBpz8tuRDVNSTFG8Iy4kegHqPQgrYxbyVIL8O4ifZ4ThVMW9L2xgVBjUMfnM5LrGsZzKT2oQuIH4eUYY9CcUyhu1APpgsslZjokW1X8dcbq+oIshA2EDoxZgj+rPdZZjQn9OP3jkBpiv+l+HDYxagG9U32e9/8fAv4vIeYJPLFV9pw3R2VQ6ksP4C4WNwDvAd8BjnjjLmI65tXb2X32K6HYPAtPGvVRq/ipqcLX6+UbVf8RdlxWTqw+JjQdV36WEN44FmEUK7cFd0IS8XWPAW/grr+cxCzCJo9cmRfphUkLgDcV5uQdOgE8U73ofpDcq0iJwW0LO4GlOAT+Hmrdi6rzOAy85zO3qAMlOgoNR4PGkApEbZ3up1Ji4JB7EPMzQ8gEpHULGRA65kBHUNkoKN8tewnzFVvs24gDbMfnzaRg6EbPGXyBZ5SYpHsWcfDfJiimRmI1sLbXRF6ntSXEOeMGiYwi5hZoq8sDfFuPtJK/kTAT1yHUcbX8Yt+M0J1yBWTIrIp64NUW7rcg2XdsdId3LWVZcCPxqEVNEUuiLPdpahCRgNltDHINrcmU0Ya/qlh1kB3LxwSVnqAfuRrI7nY6X2y78FmqcMAkJO6PYRRaRa3XrgOeQ875mpG5Xh2yIZiDZ4DLkdngP0UfqY8AruB2dpYY8cqQdJtpX68LPhiw1XIN5U8NH60T2Jf8ZzEcyxT24T7qPlP9golbJyzwkKrQg0WMmsiFqLGk4BPyGHGHtRnxAN5W1wwwZMmTIkMEz/gUzEqIONKOEMwAAAABJRU5ErkJggg=="/>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" data-name="Layer 1" viewBox="0 0 24 24" width="512" height="512"><path d="M7,0h-3C1.79,0,0,1.79,0,4v3c0,2.21,1.79,4,4,4h3c2.21,0,4-1.79,4-4v-3C11,1.79,9.21,0,7,0Zm2,7c0,1.1-.9,2-2,2h-3c-1.1,0-2-.9-2-2v-3c0-1.1,.9-2,2-2h3c1.1,0,2,.9,2,2v3Zm11,6h-3c-2.21,0-4,1.79-4,4v3c0,2.21,1.79,4,4,4h3c2.21,0,4-1.79,4-4v-3c0-2.21-1.79-4-4-4Zm2,7c0,1.1-.9,2-2,2h-3c-1.1,0-2-.9-2-2v-3c0-1.1,.9-2,2-2h3c1.1,0,2,.9,2,2v3ZM7,13h-3c-2.21,0-4,1.79-4,4v3c0,2.21,1.79,4,4,4h3c2.21,0,4-1.79,4-4v-3c0-2.21-1.79-4-4-4Zm2,7c0,1.1-.9,2-2,2h-3c-1.1,0-2-.9-2-2v-3c0-1.1,.9-2,2-2h3c1.1,0,2,.9,2,2v3Zm8.18-10.47c.38,.31,.85,.46,1.32,.46s.94-.15,1.32-.46c1.56-1.25,4.18-3.7,4.18-6.06,0-1.92-1.46-3.48-3.25-3.48-.85,0-1.65,.36-2.25,.94-.59-.59-1.39-.94-2.25-.94-1.79,0-3.25,1.56-3.25,3.48,0,2.35,2.62,4.81,4.18,6.06Zm-.93-7.53c.6,0,1.14,.5,1.26,1.17,.08,.48,.5,.83,.98,.83s.9-.35,.98-.83c.12-.67,.67-1.17,1.27-1.17,.69,0,1.25,.66,1.25,1.48,0,1.06-1.35,2.83-3.43,4.5-.04,.03-.1,.03-.14,0-2.08-1.67-3.43-3.44-3.43-4.5,0-.81,.56-1.48,1.25-1.48Z"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<path fill="currentColor" d="M14 10h-2v12h2zm6 0h-2v12h2z" />
<path fill="currentColor" d="M16 4A12 12 0 1 1 4 16A12 12 0 0 1 16 4m0-2a14 14 0 1 0 14 14A14 14 0 0 0 16 2" />
</svg>

After

Width:  |  Height:  |  Size: 266 B

View File

@@ -0,0 +1 @@
<svg t="1762937400333" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4603" width="200" height="200"><path d="M817.088 484.96l-512-323.744C295.232 154.976 282.752 154.592 272.576 160.224 262.336 165.856 256 176.608 256 188.256l0 647.328c0 11.648 6.336 22.4 16.576 28.032 4.8 2.656 10.112 3.968 15.424 3.968 5.952 0 11.904-1.664 17.088-4.928l512-323.616C826.368 533.184 832 522.976 832 512 832 501.024 826.368 490.816 817.088 484.96z" fill="currentColor" p-id="4604"></path></svg>

After

Width:  |  Height:  |  Size: 524 B

View File

@@ -0,0 +1 @@
<svg t="1761795702180" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5928" width="200" height="200"><path d="M433.505 126.568c174.435 0 316.207 141.805 316.207 316.486 0 75.209-26.384 144.234-69.824 198.526l209.166 209.1c12.849 13.148 12.849 34.459 0 47.582-13.177 13.148-34.692 13.148-47.904 0l-209.166-209.1c-54.203 43.843-123.131 70.111-198.373 70.111-174.987 0-316.682-141.627-316.682-316.434 0-174.724 141.826-316.486 316.682-316.486zM433.505 710.778c147.649 0 267.808-120.113 267.808-267.647 0-147.741-120.204-267.712-267.808-267.712-147.649 0-267.808 120.099-267.808 267.712 0 147.649 120.204 267.647 267.808 267.647z" fill="currentColor" p-id="5929"></path></svg>

After

Width:  |  Height:  |  Size: 717 B

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" ?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_105_1836)">
<path d="M13 3.99976H6C4.89543 3.99976 4 4.89519 4 5.99976V17.9998C4 19.1043 4.89543 19.9998 6 19.9998H13M17 3.99976H18C19.1046 3.99976 20 4.89519 20 5.99976V6.99976M20 16.9998V17.9998C20 19.1043 19.1046 19.9998 18 19.9998H17M20 10.9998V12.9998M12 1.99976V21.9998" stroke="#292929" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
<defs>

After

Width:  |  Height:  |  Size: 752 B

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="288.000000pt" height="288.000000pt" viewBox="0 0 288.000000 288.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,288.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M379 2446 c-101 -36 -179 -116 -209 -214 -19 -62 -20 -93 -20 -792 0
-701 1 -730 20 -793 26 -83 88 -155 168 -194 l57 -28 1045 0 1045 0 47 22
c101 46 170 138 188 250 6 32 10 329 10 668 0 659 -3 692 -54 774 -35 54 -101
108 -163 131 -52 19 -78 20 -626 20 l-572 0 -46 53 c-25 29 -70 66 -100 82
l-54 30 -350 2 c-269 2 -358 0 -386 -11z m710 -175 c20 -11 42 -25 48 -33 6
-7 48 -92 92 -188 85 -183 118 -229 196 -274 73 -43 119 -46 635 -46 l490 0 0
-517 c0 -496 -1 -519 -20 -547 -10 -17 -36 -40 -57 -53 l-38 -23 -993 0 c-968
0 -994 0 -1031 20 -22 11 -48 35 -60 53 -21 34 -21 40 -21 777 0 737 0 743 21
777 12 18 37 42 57 53 34 18 60 19 340 20 280 0 306 -1 341 -19z m1381 -174
c53 -28 80 -75 80 -139 l0 -48 -506 0 c-498 0 -507 0 -541 21 -31 19 -74 88
-103 165 l-10 24 519 0 518 0 43 -23z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,3 @@
<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M25 0C20.0555 0 15.222 1.46622 11.1108 4.21326C6.99953 6.9603 3.79521 10.8648 1.90302 15.4329C0.0108322 20.0011 -0.484251 25.0277 0.480379 29.8773C1.44501 34.7268 3.82603 39.1814 7.32234 42.6777C10.8187 46.174 15.2732 48.555 20.1228 49.5196C24.9723 50.4843 29.9989 49.9892 34.5671 48.097C39.1353 46.2048 43.0397 43.0005 45.7867 38.8893C48.5338 34.778 50 29.9445 50 25C50 18.3696 47.3661 12.0107 42.6777 7.32233C37.9893 2.63392 31.6304 0 25 0ZM34.8063 31.8604L31.8604 34.8063L25 27.9458L18.1396 34.8063L15.1938 31.8604L22.0542 25L15.1938 18.1396L18.1396 15.1938L25 22.0542L31.8604 15.1938L34.8063 18.1396L27.9458 25L34.8063 31.8604Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 760 B

View File

@@ -0,0 +1,3 @@
<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M25 0C11.2146 0 0 11.2146 0 25C0 38.7854 11.2146 50 25 50C38.7854 50 50 38.7854 50 25C50 11.2146 38.7854 0 25 0ZM24.8104 32.1229C24.0042 32.9292 22.9437 33.3312 21.8792 33.3312C20.8146 33.3312 19.7437 32.925 18.9292 32.1125L13.1333 26.4958L16.0354 23.5021L21.8542 29.1417L33.9562 17.2646L36.8812 20.2333L24.8104 32.1229Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 582 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 400 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 709 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 521 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 KiB

View File

@@ -8,14 +8,6 @@
"id": 2,
"title":"AiDA X SFT AI Fashion Award 2024",
"imgUrl": "/image/events/Fashion-Award-2024.png"
},{
"id": 3,
"title":"✨New Year 2025🎉Let's kick off the year with a burst of inspiration and design!",
"imgUrl": "/image/events/AiDA2025-En.jpg"
},{
"id": 4,
"title":"Welcome back Subscribe with the discount code to enjoy 50% OFF!",
"imgUrl": "/image/events/Welcome-back-En.jpg"
}
],
"eventsItem":[
@@ -96,106 +88,6 @@
]
}
]
},{
"id":3,
"title":"✨New Year 2025🎉Let's kick off the year with a burst of inspiration and design!",
"imgUrl": "/image/events/AiDA2025-En.jpg",
"textList":[
{
"paragraph":[
{
"text":"Share your work and get 1 month of free access to AiDA"
}
]
},{
"paragraph":[
{
"text":" Just do the following:"
}
]
},{
"paragraph":[
{
"text":" ✅Share your designs on AiDA's Gallery "
},{
"text":" ✅Add the tag #NewYear_2025 in the work description"
},{
"text":" ✅At least 20 likes "
}
]
},{
"paragraph":[
{
"text":"📅 Duration: January 1, 2025 January 31, 2025"
}
]
},{
"paragraph":[
{
"text":"Join in the fun and embark on a new year's journey of design. Mix your creativity with tech to make amazing, unique creations! Get your friends to help you seize this opportunity! Invite them to give your design some love with their likes💗"
}
]
},{
"paragraph":[
{
"text":"👍 AiDA is waiting for you to unlock a new world of design!"
}
]
}
]
},{
"id":4,
"title":"Welcome back Subscribe with the discount code to enjoy 50% OFF!",
"imgUrl": "/image/events/Welcome-back-En.jpg",
"textList":[
{
"paragraph":[
{
"text":"💠 In February, AiDA underwent a legendary transformation"
},{
"text":"💠 A silky-smooth interface and a turbocharged upgrade to all functions"
},{
"text":"😆 Long-time users are saying: “Wait… is this still the AiDA I knew?!"
}
]
},{
"paragraph":[
{
"text":"Demo video👉 <a href='https://sg834.apps.aliyunpds.com/disk/s/R6SsxBaju9h' target='_blank'>https://sg834.apps.aliyunpds.com/disk/s/R6SsxBaju9h</a>"
}
]
},{
"paragraph":[
{
"text":"⚡️ To welcome back our trial users, weve prepared an exclusive design power-up:"
},{
"text":"✔️ Use the promo code「RIINRMKK」 and enjoy 50% off your subscription"
},{
"text":"✔️ Boost your efficiency by 60%—save hours on every project"
},{
"text":"✔️ sNo design background? No problem! Get stunning drafts in just 5 minutes"
}
]
},{
"paragraph":[
{
"text":"⏳ The countdown is on:"
},{
"text":"✨Ignite your creativity like a volcanic eruption"
},{
"text":"✨Let your inspiration flow like a cosmic waterfall"
}
]
},{
"paragraph":[
{
"text":"Promotional Code: <strong>RIINRMKK</strong>"
},{
"text":"Duration: June 10 to June 30, 2025 After that, subscriptions return to full price. Dont miss it!"
}
]
}
]
}
]
}

View File

@@ -8,15 +8,7 @@
"id": 2,
"title":"AiDA X SFT AI时尚设计比赛2024",
"imgUrl": "/image/events/Fashion-Award-2024.png"
},{
"id": 3,
"title":"🎉搭上2025的列车打开新设计的大门",
"imgUrl": "/image/events/AiDA2025-Cn.jpg"
},{
"id": 4,
"title":"设计时速狂飙AiDA 618半价让灵感永不限流",
"imgUrl": "/image/events/Welcome-back-Cn.jpg"
}
}
],
"eventsItem":[
{
@@ -96,112 +88,6 @@
]
}
]
},{
"id":3,
"title":"🎉搭上2025的列车打开新设计的大门",
"imgUrl": "/image/events/AiDA2025-Cn.jpg",
"textList":[
{
"paragraph":[
{
"text":"快来发布作品获得1个月免费使用AiDA的福利"
}
]
},{
"paragraph":[
{
"text":" 只需要:"
}
]
},{
"paragraph":[
{
"text":" ✅在AiDA将设计作品分享至广场/Gallery"
},{
"text":" ✅点赞至少20"
},{
"text":" ✅在作品描述加上tag #NewYear_2025"
}
]
},{
"paragraph":[
{
"text":"📅 活动时间2025.1.1—2025.1.31"
}
]
},{
"paragraph":[
{
"text":"快来参与,让我们共同开启新年的设计之旅,让创意与科技完美融合,创造出属于你的独一无二的作品!机会难得,叫上你的朋友们助你一臂之力,为你点上大拇指哦!"
}
]
},{
"paragraph":[
{
"text":"👍 点赞即启程AiDA等你来解锁设计新世界"
}
]
}
]
},{
"id":4,
"title":"设计时速狂飙AiDA 618半价让灵感永不限流",
"imgUrl": "/image/events/Welcome-back-En.jpg",
"textList":[
{
"paragraph":[
{
"text":"618的钟声敲响AiDA的AI设计宇宙正式进入「超维折扣纪元」"
}
]
},{
"paragraph":[
{
"text":"💠 就在今年2月AiDA完成史诗级进化"
},{
"text":"💠 界面如丝绸般顺滑,功能矩阵全面升级。"
},{
"text":"😆 旧版用户惊呼这还是我认识的AiDA吗⁉"
}
]
},{
"paragraph":[
{
"text":"演示视频👉 <a href='https://sg834.apps.aliyunpds.com/disk/s/R6SsxBaju9h' target='_blank'>https://sg834.apps.aliyunpds.com/disk/s/R6SsxBaju9h</a>"
}
]
},{
"paragraph":[
{
"text":"⚡️ 618特供「专属暴击福利」💥"
},{
"text":"✔️ 输入口令“RIINRMKK”订阅直接享受半价"
},{
"text":"✔️ 效率提升60%,设计实践节省一大半!"
},{
"text":"✔️ 零基础也能5分钟出稿轻松搞定设计需求"
}
]
},{
"paragraph":[
{
"text":"⏳ 倒计时警报:"
},{
"text":"👉 让设计如火山喷发般炽热"
},{
"text":"👉 让灵感似银河倾泻般璀璨"
}
]
},{
"paragraph":[
{
"text":"优惠码:<strong>RIINRMKK</strong>"
},{
"text":"活动日期2025.6.10-6.30(后续订阅费用将恢复至原价)"
}
]
}
]
}
]
}

View File

@@ -62,6 +62,9 @@ li {
height: 100%;
margin: 0 auto;
}
.ant-dropdown-menu {
border-radius: 1rem;
}
.button_second {
width: 14rem;
text-align: center;
@@ -165,6 +168,7 @@ li {
}
.ant-modal-mask {
background-color: #666666;
opacity: 0.5;
}
.select_block {
height: 4rem;
@@ -237,7 +241,7 @@ li {
color: #fff;
background-color: #000;
text-align: center;
font-weight: 600;
font-weight: 500;
border: 2px solid #000;
cursor: pointer;
box-sizing: border-box;
@@ -1247,7 +1251,9 @@ tr > .ant-picker-cell-in-view.ant-picker-cell-range-hover-start:last-child::afte
border-color: #000 !important;
}
.ant-spin-dot-item {
background-color: #000000;
background-color: #000000 !important;
width: 9px !important;
height: 9px !important;
}
.ant-spin {
color: #000;
@@ -1373,7 +1379,7 @@ tr > .ant-picker-cell-in-view.ant-picker-cell-range-hover-start:last-child::afte
}
.admin_page .admin_state_item .active {
cursor: no-drop;
background-color: #f5f5f5;
background-color: #F9FAFA;
}
.admin_page .admin_search_item {
height: 4rem;
@@ -1707,7 +1713,7 @@ textarea:focus {
display: inline-block;
width: calc(25% - 2rem);
aspect-ratio: 1 / 1;
border: 1px solid #f5f5f5;
border: 1px solid #F9FAFA;
vertical-align: top;
position: relative;
cursor: pointer;
@@ -1989,7 +1995,7 @@ textarea:focus {
display: flex;
float: left;
align-items: center;
padding: 1.5rem 2rem;
padding: 1rem 2rem;
background-color: #fff;
flex: 1;
height: auto;
@@ -2314,6 +2320,8 @@ textarea:focus {
top: 0rem;
flex: 1;
border: 1px solid #dcdfe6;
width: calc(var(--width) + 6rem);
padding: 1rem;
}
.generage_btn_box {
position: relative;

View File

@@ -63,6 +63,9 @@ input:focus{
height: 100%;
margin: 0 auto;
}
.ant-dropdown-menu{
border-radius: 1rem;
}
.button_second{
width: 14rem;
text-align: center;
@@ -170,6 +173,7 @@ input:focus{
}
.ant-modal-mask{
background-color: #666666;
opacity: .5;
}
.select_block{
height: 4rem;
@@ -241,7 +245,7 @@ input:focus{
color: #fff;
background-color: #000;
text-align: center;
font-weight: 600;
font-weight: 500;
border: 2px solid #000;
cursor: pointer;
box-sizing: border-box;
@@ -1375,7 +1379,9 @@ tr > .ant-picker-cell-in-view.ant-picker-cell-range-hover-start:last-child::afte
}
//loding样式
.ant-spin-dot-item{
background-color: #000000;
background-color: #000000 !important;
width: 9px !important;
height: 9px !important;
}
.ant-spin{
color: #000;
@@ -1507,7 +1513,7 @@ tr > .ant-picker-cell-in-view.ant-picker-cell-range-hover-start:last-child::afte
}
.active{
cursor: no-drop;
background-color: #f5f5f5;
background-color: #F9FAFA;
}
}
.admin_search_item{
@@ -1862,7 +1868,7 @@ textarea:focus{
// height: calc(10rem);
width: calc(25% - 2rem);
aspect-ratio: 1 / 1;
border: 1px solid #f5f5f5;
border: 1px solid #F9FAFA;
vertical-align: top;
position: relative;
cursor: pointer;
@@ -2057,7 +2063,7 @@ textarea:focus{
display: flex;
float: left;
align-items: center;
padding: 1.5rem 2rem;
padding: 1rem 2rem;
// padding-right: 0;
background-color: #fff;
flex: 1;
@@ -2200,6 +2206,8 @@ textarea:focus{
top: 0rem;
flex: 1;
border: 1px solid #dcdfe6;
width: calc(var(--width) + 6rem);
padding: 1rem;
}
// span{

View File

@@ -50,10 +50,10 @@
<div v-if="!isEditEmail">{{ userDetail.email }}</div>
<input v-else type="text" :value="editEmail">
</div>
<div class="icon">
<!-- <div class="icon">
<i v-if="!isEditEmail" class="fi fi-rr-edit" @click="openEdit('email')"></i>
<i v-else class="fi fi-br-check" @click="editChek('email')"></i>
</div>
</div> -->
</div>
</div>
<div class="content_item_user_left_detail_bottom">

View File

@@ -6,7 +6,7 @@
<bind v-if="item.key == 'bind' && activeKey == 'bind'" :ref="item.key"></bind>
<cancelRenewal v-if="item.key == 'cancelRenewal' && activeKey == 'cancelRenewal'" :ref="item.key"></cancelRenewal>
<template #tab>
<a-badge :count="0" >
<a-badge :count="0" v-if="!(item.key == 'cancelRenewal' && [5,6,7,8].includes(userDetail.systemUser))">
<span>{{item.title}}</span>
</a-badge>
</template>
@@ -104,6 +104,12 @@ export default defineComponent({
let key = accountfrontPage.frontPageList[0].key
accountfrontPage.activeKey = key
const data = route.query
if(!!data.subscribe){
accountfrontPage.activeKey = 'cancelRenewal'
nextTick(()=>{
domRefs.cancelRenewal[0].subscribe()
})
}
if(data?.state == 'weiXin'){
accountfrontPage.activeKey = 'bind'
wechatLogin(data)

View File

@@ -27,10 +27,10 @@
<div v-show="!userDetail.accountExtendList?.Google" id="g_id_bind"></div>
<div v-if="userDetail.accountExtendList?.Google" class="gallery_btn" @click="ungroupGoogleModel">{{ $t('frontPage.Unbind') }}</div>
</div> -->
<div class="gmail_btn" @click="toGmailLogin">
<div v-if="!userDetail.accountExtendList?.Google" class="gallery_btn forbidden">{{ $t('frontPage.BindNow') }}</div>
<!-- <div v-show="!userDetail.accountExtendList?.Google" id="g_id_bind"></div> -->
<div v-if="userDetail.accountExtendList?.Google" class="gallery_btn forbidden" @click="ungroupGoogleModel">{{ $t('frontPage.Unbind') }}</div>
<div class="gmail_btn">
<div v-if="!userDetail.accountExtendList?.Google" class="gallery_btn" style="pointer-events: none;">{{ $t('frontPage.BindNow') }}</div>
<div v-show="!userDetail.accountExtendList?.Google" id="g_id_bind"></div>
<div v-if="userDetail.accountExtendList?.Google" class="gallery_btn" @click="ungroupGoogleModel">{{ $t('frontPage.Unbind') }}</div>
<!-- <div v-if="userDetail.accountExtendList?.Google" class="gallery_btn" @click="ungroupGoogleModel">{{ $t('frontPage.Unbind') }}</div> -->
</div>
</div>
@@ -111,39 +111,58 @@ export default defineComponent({
.catch((res) => {accountHomeData.loadingShow = false});
}
const ungroupWeiXinModel = ()=>{
Https.axiosGet(Https.httpUrls.unbindWeChat,).then((rv)=>{
message.success(t('frontPage.jsContent1'));
let value = {
accountExtendList:{
WeChat:undefined,
Google:accountHomeData.userDetail.accountExtendList?.Google
}
Modal.confirm({
title: t('frontPage.UnbindTip'),
okText: t('Yes'),
cancelText: t('No'),
mask:false,
centered:true,
onOk() {
Https.axiosGet(Https.httpUrls.unbindWeChat,).then((rv)=>{
message.success(t('frontPage.jsContent1'));
let value = {
accountExtendList:{
WeChat:undefined,
Google:accountHomeData.userDetail.accountExtendList?.Google
}
}
store.commit("upUserDetail", value)
})
}
store.commit("upUserDetail", value)
})
});
}
const ungroupGoogleModel = ()=>{
Https.axiosGet(Https.httpUrls.unbindGoogle,).then((rv)=>{
let value = {
accountExtendList:{
WeChat:accountHomeData.userDetail.accountExtendList?.WeChat,
Google:undefined,
}
Modal.confirm({
title: t('frontPage.UnbindTip'),
okText: t('Yes'),
cancelText: t('No'),
mask:false,
centered:true,
onOk() {
Https.axiosGet(Https.httpUrls.unbindGoogle,).then((rv)=>{
let value = {
accountExtendList:{
WeChat:accountHomeData.userDetail.accountExtendList?.WeChat,
Google:undefined,
}
}
store.commit("upUserDetail", value)
message.success(t('frontPage.jsContent1'));
})
}
store.commit("upUserDetail", value)
message.success(t('frontPage.jsContent1'));
})
});
}
const modifyEmail = ()=>{
bindPageDom.bindEmail.init('Modify')
}
const toGmailLogin = ()=>{
message.info(t('account.canNotUtilize'))
}
onMounted(async ()=>{
return
let GOOGLE_CLIENT_ID = '29310152396-nnsd3h533fld665oguu8ovrt1nukmt46.apps.googleusercontent.com'
let GOOGLE_CLIENT_ID
if(import.meta.env.VITE_USER_NODE_ENV == 'development'){
GOOGLE_CLIENT_ID = '157095842121-kdd1fdf8m8nudvj9sprstb2k2prnf9e4.apps.googleusercontent.com'
}else{
GOOGLE_CLIENT_ID = '29310152396-nnsd3h533fld665oguu8ovrt1nukmt46.apps.googleusercontent.com'
}
var existingScript = document.querySelector(`script[src="${data.scriptSrc}"]`);
if(!window.isAddGmail){
if(!existingScript){
@@ -206,7 +225,6 @@ export default defineComponent({
ungroupGoogleModel,
ungroupWeiXinModel,
modifyEmail,
toGmailLogin,
}
},
data(){
@@ -271,14 +289,21 @@ export default defineComponent({
}
>.gmail_btn{
position: relative;
border-radius: 4rem;
overflow: hidden;
> .gallery_btn{
position: relative;
z-index: 2;
}
#g_id_bind{
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
opacity: 0;
z-index: 2;
// opacity: 0;
z-index: 1;
:deep(.nsm7Bb-HzV7m-LgbsSe.Bz112c-LgbsSe){
width: 100%;
}

View File

@@ -28,7 +28,7 @@
optionFilterProp="label"
:options="countryList"
:field-names="{ label: locale == 'CHINESE_SIMPLIFIED'?'labelCn':'label' }"
placeholder="Please select"
:placeholder="`${$t('account.plaseSelect')} ${$t('account.Country')}`"
allowClear
show-search
></a-select>
@@ -117,13 +117,12 @@ export default defineComponent({
let value = {
country:accountHomeData.Country,
title:accountHomeData.selectSex,
userName:accountHomeData.editUserName,
surname:accountHomeData.surname,
givenName:accountHomeData.givenName,
}
store.commit('upUserDetail',value)
accountHomeData.loadingShow = false
message.success(t('exportModel.jsContent7'))
message.success(t('account.jsContent13'))
}).catch((err:any)=>{
accountHomeData.loadingShow = false
})

View File

@@ -133,8 +133,14 @@ export default defineComponent({
}
.modal_title_text_intro{
margin-left: 4rem;
}
}
}
.modal_title_text_intro{
word-break: break-word;
white-space: pre-wrap;
font-family: Arial, sans-serif;
}
}
</style>

View File

@@ -22,7 +22,7 @@
</a-range-picker>
</div>
<!-- <div class="admin_state_item">
<span>Country:</span>
<span>Country or Region:</span>
<a-select
v-model:value="country"
:allowClear="true"
@@ -324,7 +324,11 @@ export default defineComponent({
filterData.orderBy = 'credits'
}
}
filterData.order = sorter.order == "descend" ? "Descending" : "Ascending";
if(sorter.order){
filterData.order = sorter.order == "descend" ? "Descending" : "Ascending";
}else{
filterData.order = ''
}
gettrialList();
};

View File

@@ -1,12 +1,11 @@
<template>
<div class="test_cli admin_page">
<div class="test_cli admin_page">
<div class="admin_table_search">
<div class="admin_state">
<div class="admin_state_item">
<span>{{ $t('admin.StartDate') }}:</span>
<span>{{ $t("admin.StartDate") }}:</span>
<a-range-picker
style="width:250px"
style="width: 250px"
class="range_picker"
v-model:value="rangePickerValue"
:placeholder="[
@@ -23,35 +22,56 @@
</a-range-picker>
</div>
<div class="admin_state_item">
<span>{{ $t('admin.StartTime') }}:</span>
<a-time-range-picker style="width:250px" :placeholder="[$t('admin.startTime'), $t('admin.endTime'),]" class="range_picker" valueFormat="HH:mm:ss" v-model:value="rangeTimeValue" />
<span>{{ $t("admin.StartTime") }}:</span>
<a-time-range-picker
style="width: 250px"
:placeholder="[
$t('admin.startTime'),
$t('admin.endTime'),
]"
class="range_picker"
valueFormat="HH:mm:ss"
v-model:value="rangeTimeValue"
/>
</div>
<div class="admin_state_item">
<span>{{ $t('admin.Email') }}:</span>
<input
v-model="email"
:placeholder="$t('admin.enterEmail')"
@keydown.enter="gettrialList"
type="text"
style="width: 250px"
/>
</div>
<span>{{ $t("admin.Email") }}:</span>
<input
v-model="email"
:placeholder="$t('admin.enterEmail')"
@keydown.enter="gettrialList"
type="text"
style="width: 250px"
/>
</div>
<div class="admin_state_item">
<span>{{ $t('admin.UserName') }}:</span>
<a-select
v-model:value="ids"
mode="multiple"
style="width: 250px"
:filter-option="filterOption"
:placeholder="$t('admin.selectUserName')"
max-tag-count="responsive"
:options="allUserList"
@keydown.enter="gettrialList"
></a-select>
</div>
<span>{{ $t("admin.UserName") }}:</span>
<a-select
v-model:value="ids"
mode="multiple"
style="width: 250px"
:filter-option="filterOption"
:placeholder="$t('admin.selectUserName')"
max-tag-count="responsive"
:options="allUserList"
@keydown.enter="gettrialList"
></a-select>
</div>
<div class="admin_state_item">
<span>Organization Name:</span>
<input
v-model="organizationName"
placeholder="Please enter Organization Name"
@keydown.enter="gettrialList"
type="text"
style="width: 250px"
/>
</div>
</div>
<div class="admin_search">
<div class="admin_search_item" @click="searchHistoryList">{{ $t('admin.search') }}</div>
<div class="admin_search_item" @click="searchHistoryList">
{{ $t("admin.search") }}
</div>
</div>
</div>
@@ -73,205 +93,207 @@
>
</a-table>
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, ref, createVNode, computed } from "vue";
import { useStore } from "vuex";
import { Https } from "@/tool/https";
import { useI18n } from 'vue-i18n'
export default defineComponent({
components: {
},
setup() {
const store:any = useStore()
let rangePickerValue: any = ref([]);
let rangeTimeValue: any = ref([]);
let renameData: any = ref({}); //修改名字选中的数据
const {t} = useI18n()
const columns: any = computed(() => {
return [
{
title: t('admin.Email'),
align: "center",
dataIndex: "userEmail",
key: "userEmail",
width:200,
fixed: "left",
},
{
title: t('admin.UserId'),
align: "center",
ellipsis: true,
dataIndex: "accountId",
key: "accountId",
width:100,
},
{
title: t('admin.UserName'),
align: "center",
ellipsis: 200,
dataIndex: "userName",
key: "userName",
width:100,
// customRender: (record: any) => {
// let time = formatTime(
// record.text / 1000,
// "YYYY-MM-DD hh:mm:ss"
// );
// return time;
// },
},
{
title: t('admin.Frequency'),
align: "center",
ellipsis: true,
dataIndex: "designTimes",
key: "designTimes",
width:100,
},
{
title: t('admin.CreateTime'),
align: "center",
ellipsis: true,
// width: 150,
// minWidth: 100,
// maxWidth: 200,
// resizable: true,
dataIndex: "createTime",
key: "createTime",
width:200,
},
{
title: t('admin.Credits'),
align: "center",
ellipsis: true,
// width: 150,
// minWidth: 100,
// maxWidth: 200,
// resizable: true,
dataIndex: "credits",
key: "credits",
width:100,
},
];
});
import { defineComponent, ref, createVNode, computed } from "vue";
import { useStore } from "vuex";
import { Https } from "@/tool/https";
import { useI18n } from "vue-i18n";
export default defineComponent({
components: {},
setup() {
const store: any = useStore();
let rangePickerValue: any = ref([]);
let rangeTimeValue: any = ref([]);
let renameData: any = ref({}); //修改名字选中的数据
const { t } = useI18n();
const columns: any = computed(() => {
return [
{
title: t("admin.Email"),
align: "center",
dataIndex: "userEmail",
key: "userEmail",
width: 200,
fixed: "left",
},
{
title: t("admin.UserId"),
align: "center",
ellipsis: true,
dataIndex: "accountId",
key: "accountId",
width: 100,
},
{
title: t("admin.UserName"),
align: "center",
ellipsis: 200,
dataIndex: "userName",
key: "userName",
width: 100,
// customRender: (record: any) => {
// let time = formatTime(
// record.text / 1000,
// "YYYY-MM-DD hh:mm:ss"
// );
// return time;
// },
},
{
title: t("admin.Frequency"),
align: "center",
ellipsis: true,
dataIndex: "designTimes",
key: "designTimes",
width: 100,
},
{
title: t("admin.CreateTime"),
align: "center",
ellipsis: true,
// width: 150,
// minWidth: 100,
// maxWidth: 200,
// resizable: true,
dataIndex: "createTime",
key: "createTime",
width: 200,
},
{
title: t("admin.Credits"),
align: "center",
ellipsis: true,
// width: 150,
// minWidth: 100,
// maxWidth: 200,
// resizable: true,
dataIndex: "credits",
key: "credits",
width: 100,
},
];
});
let allUserList: any = computed(()=>{
return store.state.adminPage.allUserList
})
let ids = ref([])
let email = ref('')
let dataList: any = ref([]);
let status: any = ref(0);
let filterOption = (input: any, option: any) => {
// 使用 option.label 进行搜索
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
};
return {
rangePickerValue,
rangeTimeValue,
columns,
dataList,
allUserList,
ids,
email,
renameData,
status,
filterOption,
};
},
data() {
return {
currentPage: 1,
pageSize: 10,
total: 0,
historyTableHeight: 0,
handleResizeColumn: (w:any, col:any) => {
col.width = w;
let allUserList: any = computed(() => {
return store.state.adminPage.allUserList;
});
let ids = ref([]);
let email = ref("");
let dataList: any = ref([]);
let status: any = ref(0);
let organizationName: any = ref("");
let filterOption = (input: any, option: any) => {
// 使用 option.label 进行搜索
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
};
return {
rangePickerValue,
rangeTimeValue,
columns,
dataList,
allUserList,
ids,
email,
renameData,
status,
filterOption,
organizationName,
};
},
data() {
return {
currentPage: 1,
pageSize: 10,
total: 0,
historyTableHeight: 0,
handleResizeColumn: (w: any, col: any) => {
col.width = w;
},
};
},
mounted() {
let historyTable: any = this.$refs.historyTable;
this.historyTableHeight = historyTable.clientHeight - 200;
this.gettrialList();
},
methods: {
//改变页码
changePage(e: any) {
this.currentPage = e.current;
this.pageSize = e.pageSize;
this.gettrialList();
},
};
},
mounted() {
let historyTable: any = this.$refs.historyTable;
this.historyTableHeight = historyTable.clientHeight - 200;
this.gettrialList();
},
methods: {
//改变页码
changePage(e: any) {
this.currentPage = e.current;
this.pageSize = e.pageSize;
this.gettrialList();
},
//查询列表
searchHistoryList() {
this.currentPage = 1;
this.gettrialList();
},
//查询列表
searchHistoryList() {
this.currentPage = 1;
this.gettrialList();
},
//获取列表
gettrialList() {
let startTime: any = this.rangeTimeValue?.[0]
? this.rangeTimeValue[0]
: '00:00:00';
let endTime: any = this.rangeTimeValue?.[1]
? this.rangeTimeValue[1]
: '23:59:59';
let startDate: any = this.rangePickerValue?.[0]
? this.rangePickerValue[0]+' '+startTime
: "";
let endDate: any = this.rangePickerValue?.[1]
? this.rangePickerValue[1]+' '+endTime
: "";
let ids = this.ids.join(',')
let data = {
endTime:endDate,
startTime:startDate,
ids:ids,
email:this.email.trim(),
}
Https.axiosGet(Https.httpUrls.getDesignStatistic,{params:data}).then((rv: any) => {
if (rv) {
this.dataList = rv
// this.workspaceItem.position = this.singleTypeList[0].label
}
})
},
//删除分组
// deleteGroup(record: any, index: number) {
// let deleteGroupFun = (id: any, index: number) => {
// let data = {
// userGroupId: id,
// };
// Https.axiosPost(Https.httpUrls.deleteUserGroup, data).then(
// (rv: any) => {
// this.dataList.splice(index, 1);
// }
// );
// };
// Modal.confirm({
// title: "",
// icon: createVNode(ExclamationCircleOutlined),
// okText: "Yes",
// cancelText: "No",
// centered: true,
// mask: false,
// onOk() {
// deleteGroupFun(record.id, index);
// },
// });
// },
},
});
//获取列表
gettrialList() {
let startTime: any = this.rangeTimeValue?.[0]
? this.rangeTimeValue[0]
: "00:00:00";
let endTime: any = this.rangeTimeValue?.[1]
? this.rangeTimeValue[1]
: "23:59:59";
let startDate: any = this.rangePickerValue?.[0]
? this.rangePickerValue[0] + " " + startTime
: "";
let endDate: any = this.rangePickerValue?.[1]
? this.rangePickerValue[1] + " " + endTime
: "";
let ids = this.ids.join(",");
let data = {
endTime: endDate,
startTime: startDate,
ids: ids,
email: this.email.trim(),
organizationName: this.organizationName,
};
Https.axiosGet(Https.httpUrls.getDesignStatistic, {
params: data,
}).then((rv: any) => {
if (rv) {
this.dataList = rv;
// this.workspaceItem.position = this.singleTypeList[0].label
}
});
},
//删除分组
// deleteGroup(record: any, index: number) {
// let deleteGroupFun = (id: any, index: number) => {
// let data = {
// userGroupId: id,
// };
// Https.axiosPost(Https.httpUrls.deleteUserGroup, data).then(
// (rv: any) => {
// this.dataList.splice(index, 1);
// }
// );
// };
// Modal.confirm({
// title: "",
// icon: createVNode(ExclamationCircleOutlined),
// okText: "Yes",
// cancelText: "No",
// centered: true,
// mask: false,
// onOk() {
// deleteGroupFun(record.id, index);
// },
// });
// },
},
});
</script>
<style lang="less" scoped>
.admin_page .admin_table_search .admin_state {
display: flex;
flex-wrap: wrap;
}
.admin_page .admin_table_search .admin_state {
display: flex;
flex-wrap: wrap;
}
</style>

View File

@@ -77,10 +77,12 @@ import { PieChart } from 'echarts/charts';
import { LabelLayout } from 'echarts/features';
import { useStore } from "vuex";
import { CanvasRenderer } from 'echarts/renderers';
import { useI18n } from 'vue-i18n'
export default defineComponent({
components: {
},
setup() {
const {t} = useI18n()
const store:any = useStore()
let filter:any = reactive({
dataList:computed(()=>{
@@ -115,7 +117,7 @@ export default defineComponent({
let data:any = []
rv.names.forEach((item:any,index:number) => {
let obj = {
name : item,
name : t(`admin.${item}`),
value:rv.values[index],
}
data.push(obj)

View File

@@ -1,12 +1,11 @@
<template>
<div class="test_cli admin_page">
<div class="test_cli admin_page">
<div class="admin_table_search">
<div class="admin_state">
<div class="admin_state_item">
<span>Start Date:</span>
<a-range-picker
style="width:250px"
style="width: 250px"
class="range_picker"
v-model:value="rangePickerValue"
:placeholder="[
@@ -24,34 +23,51 @@
</div>
<div class="admin_state_item">
<span>Start Time:</span>
<a-time-range-picker style="width:250px" class="range_picker" valueFormat="HH:mm:ss" v-model:value="rangeTimeValue" />
<a-time-range-picker
style="width: 250px"
class="range_picker"
valueFormat="HH:mm:ss"
v-model:value="rangeTimeValue"
/>
</div>
<div class="admin_state_item">
<span>Email:</span>
<input
v-model="email"
placeholder="Please enter email"
@keydown.enter="gettrialList"
type="text"
style="width: 250px"
/>
</div>
<span>Email:</span>
<input
v-model="email"
placeholder="Please enter email"
@keydown.enter="gettrialList"
type="text"
style="width: 250px"
/>
</div>
<div class="admin_state_item">
<span>User Name:</span>
<a-select
v-model:value="ids"
mode="multiple"
style="width: 250px"
:filter-option="filterOption"
placeholder="Select Item..."
max-tag-count="responsive"
:options="allUserList"
@keydown.enter="gettrialList"
></a-select>
</div>
<span>User Name:</span>
<a-select
v-model:value="ids"
mode="multiple"
style="width: 250px"
:filter-option="filterOption"
placeholder="Select Item..."
max-tag-count="responsive"
:options="allUserList"
@keydown.enter="gettrialList"
></a-select>
</div>
<div class="admin_state_item">
<span>Organization Name:</span>
<input
v-model="organizationName"
placeholder="Please enter Organization Name"
@keydown.enter="gettrialList"
type="text"
style="width: 250px"
/>
</div>
</div>
<div class="admin_search">
<div class="admin_search_item" @click="searchHistoryList">Search</div>
<div class="admin_search_item" @click="searchHistoryList">
Search
</div>
</div>
</div>
@@ -73,270 +89,272 @@
>
</a-table>
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, ref, createVNode, computed } from "vue";
import { useStore } from "vuex";
import { Https } from "@/tool/https";
export default defineComponent({
components: {
},
setup() {
const store:any = useStore()
let rangePickerValue: any = ref([]);
let rangeTimeValue: any = ref([]);
let renameData: any = ref({}); //修改名字选中的数据
const columns: any = computed(() => {
return [
{
title: 'Email',
align: "center",
dataIndex: "userEmail",
key: "userEmail",
width:200,
fixed: "left",
},
{
title: 'User Id',
align: "center",
ellipsis: true,
dataIndex: "accountId",
key: "accountId",
width:100,
},
{
title: 'User Name',
align: "center",
ellipsis: 200,
dataIndex: "userName",
key: "userName",
width:100,
// customRender: (record: any) => {
// let time = formatTime(
// record.text / 1000,
// "YYYY-MM-DD hh:mm:ss"
// );
// return time;
// },
},
{
title: 'isTrial',
align: "center",
ellipsis: true,
dataIndex: "isTrial",
key: "isTrial",
width:100,
customRender: (record: any) => {
let str
if(record.value == 1){
str ='Yes'
}else{
str ='No'
}
return str;
},
},
{
title: 'Frequency',
align: "center",
ellipsis: true,
dataIndex: "designTimes",
key: "designTimes",
width:100,
},
{
title: 'Country',
align: "center",
ellipsis: true,
dataIndex: "country",
key: "country",
width:200,
},
{
title: 'Title',
align: "center",
ellipsis: true,
dataIndex: "title",
key: "title",
width:100,
},
{
title: 'Surname',
align: "center",
ellipsis: true,
dataIndex: "surname",
key: "surname",
width:150,
},
{
title: 'Given Name',
align: "center",
ellipsis: true,
dataIndex: "givenName",
key: "givenName",
width:100,
},
{
title: 'Create Time',
align: "center",
ellipsis: true,
dataIndex: "createTime",
key: "createTime",
width:200,
},
{
title: 'Credits',
align: "center",
ellipsis: true,
// width: 150,
// minWidth: 100,
// maxWidth: 200,
// resizable: true,
dataIndex: "credits",
key: "credits",
width:100,
},
{
title: 'Occupation',
align: "center",
ellipsis: true,
// width: 150,
// minWidth: 100,
// maxWidth: 200,
// resizable: true,
dataIndex: "occupation",
key: "occupation",
width:100,
},
{
title: 'Trial Order Id',
align: "center",
ellipsis: true,
// width: 150,
// resizable: true,
dataIndex: "trialOrderId",
key: "trialOrderId",
width:100,
},
];
});
import { defineComponent, ref, createVNode, computed } from "vue";
import { useStore } from "vuex";
import { Https } from "@/tool/https";
export default defineComponent({
components: {},
setup() {
const store: any = useStore();
let rangePickerValue: any = ref([]);
let rangeTimeValue: any = ref([]);
let renameData: any = ref({}); //修改名字选中的数据
let organizationName: any = ref("");
const columns: any = computed(() => {
return [
{
title: "Email",
align: "center",
dataIndex: "userEmail",
key: "userEmail",
width: 200,
fixed: "left",
},
{
title: "User Id",
align: "center",
ellipsis: true,
dataIndex: "accountId",
key: "accountId",
width: 100,
},
{
title: "User Name",
align: "center",
ellipsis: 200,
dataIndex: "userName",
key: "userName",
width: 100,
// customRender: (record: any) => {
// let time = formatTime(
// record.text / 1000,
// "YYYY-MM-DD hh:mm:ss"
// );
// return time;
// },
},
{
title: "isTrial",
align: "center",
ellipsis: true,
dataIndex: "isTrial",
key: "isTrial",
width: 100,
customRender: (record: any) => {
let str;
if (record.value == 1) {
str = "Yes";
} else {
str = "No";
}
return str;
},
},
{
title: "Frequency",
align: "center",
ellipsis: true,
dataIndex: "designTimes",
key: "designTimes",
width: 100,
},
{
title: "Country",
align: "center",
ellipsis: true,
dataIndex: "country",
key: "country",
width: 200,
},
{
title: "Title",
align: "center",
ellipsis: true,
dataIndex: "title",
key: "title",
width: 100,
},
{
title: "Surname",
align: "center",
ellipsis: true,
dataIndex: "surname",
key: "surname",
width: 150,
},
{
title: "Given Name",
align: "center",
ellipsis: true,
dataIndex: "givenName",
key: "givenName",
width: 100,
},
{
title: "Create Time",
align: "center",
ellipsis: true,
dataIndex: "createTime",
key: "createTime",
width: 200,
},
{
title: "Credits",
align: "center",
ellipsis: true,
// width: 150,
// minWidth: 100,
// maxWidth: 200,
// resizable: true,
dataIndex: "credits",
key: "credits",
width: 100,
},
{
title: "Occupation",
align: "center",
ellipsis: true,
// width: 150,
// minWidth: 100,
// maxWidth: 200,
// resizable: true,
dataIndex: "occupation",
key: "occupation",
width: 100,
},
{
title: "Trial Order Id",
align: "center",
ellipsis: true,
// width: 150,
// resizable: true,
dataIndex: "trialOrderId",
key: "trialOrderId",
width: 100,
},
];
});
let allUserList: any = computed(()=>{
return store.state.adminPage.allUserList
})
let ids = ref([])
let email = ref('')
let dataList: any = ref([]);
let status: any = ref(0);
let filterOption = (input: any, option: any) => {
// 使用 option.label 进行搜索
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
};
return {
rangePickerValue,
rangeTimeValue,
columns,
dataList,
allUserList,
ids,
email,
renameData,
status,
filterOption,
};
},
data() {
return {
currentPage: 1,
pageSize: 10,
total: 0,
historyTableHeight: 0,
handleResizeColumn: (w:any, col:any) => {
col.width = w;
let allUserList: any = computed(() => {
return store.state.adminPage.allUserList;
});
let ids = ref([]);
let email = ref("");
let dataList: any = ref([]);
let status: any = ref(0);
let filterOption = (input: any, option: any) => {
// 使用 option.label 进行搜索
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
};
return {
rangePickerValue,
organizationName,
rangeTimeValue,
columns,
dataList,
allUserList,
ids,
email,
renameData,
status,
filterOption,
};
},
data() {
return {
currentPage: 1,
pageSize: 10,
total: 0,
historyTableHeight: 0,
handleResizeColumn: (w: any, col: any) => {
col.width = w;
},
};
},
mounted() {
let historyTable: any = this.$refs.historyTable;
this.historyTableHeight = historyTable.clientHeight - 200;
this.gettrialList();
},
methods: {
//改变页码
changePage(e: any) {
this.currentPage = e.current;
this.pageSize = e.pageSize;
this.gettrialList();
},
};
},
mounted() {
let historyTable: any = this.$refs.historyTable;
this.historyTableHeight = historyTable.clientHeight - 200;
this.gettrialList();
},
methods: {
//改变页码
changePage(e: any) {
this.currentPage = e.current;
this.pageSize = e.pageSize;
this.gettrialList();
},
//查询列表
searchHistoryList() {
this.currentPage = 1;
this.gettrialList();
},
//查询列表
searchHistoryList() {
this.currentPage = 1;
this.gettrialList();
},
//获取列表
gettrialList() {
let startTime: any = this.rangeTimeValue?.[0]
? this.rangeTimeValue?.[0]
: '00:00:00';
let endTime: any = this.rangeTimeValue[1]
? this.rangeTimeValue[1]
: '23:59:59';
let startDate: any = this.rangePickerValue[0]
? this.rangePickerValue[0]+' '+startTime
: "";
let endDate: any = this.rangePickerValue[1]
? this.rangePickerValue[1]+' '+endTime
: "";
let ids = this.ids.join(',')
let data = {
endTime:endDate,
startTime:startDate,
ids:ids,
email:this.email.trim(),
}
Https.axiosGet(Https.httpUrls.getDesignStatistic,{params:data}).then((rv: any) => {
if (rv) {
this.dataList = rv
// this.workspaceItem.position = this.singleTypeList[0].label
}
})
},
//删除分组
// deleteGroup(record: any, index: number) {
// let deleteGroupFun = (id: any, index: number) => {
// let data = {
// userGroupId: id,
// };
// Https.axiosPost(Https.httpUrls.deleteUserGroup, data).then(
// (rv: any) => {
// this.dataList.splice(index, 1);
// }
// );
// };
// Modal.confirm({
// title: "",
// icon: createVNode(ExclamationCircleOutlined),
// okText: "Yes",
// cancelText: "No",
// centered: true,
// mask: false,
// onOk() {
// deleteGroupFun(record.id, index);
// },
// });
// },
},
});
//获取列表
gettrialList() {
let startTime: any = this.rangeTimeValue?.[0]
? this.rangeTimeValue?.[0]
: "00:00:00";
let endTime: any = this.rangeTimeValue[1]
? this.rangeTimeValue[1]
: "23:59:59";
let startDate: any = this.rangePickerValue[0]
? this.rangePickerValue[0] + " " + startTime
: "";
let endDate: any = this.rangePickerValue[1]
? this.rangePickerValue[1] + " " + endTime
: "";
let ids = this.ids.join(",");
let data = {
endTime: endDate,
startTime: startDate,
ids: ids,
email: this.email.trim(),
organizationName: this.organizationName,
};
Https.axiosGet(Https.httpUrls.getDesignStatistic, {
params: data,
}).then((rv: any) => {
if (rv) {
this.dataList = rv;
// this.workspaceItem.position = this.singleTypeList[0].label
}
});
},
//删除分组
// deleteGroup(record: any, index: number) {
// let deleteGroupFun = (id: any, index: number) => {
// let data = {
// userGroupId: id,
// };
// Https.axiosPost(Https.httpUrls.deleteUserGroup, data).then(
// (rv: any) => {
// this.dataList.splice(index, 1);
// }
// );
// };
// Modal.confirm({
// title: "",
// icon: createVNode(ExclamationCircleOutlined),
// okText: "Yes",
// cancelText: "No",
// centered: true,
// mask: false,
// onOk() {
// deleteGroupFun(record.id, index);
// },
// });
// },
},
});
</script>
<style lang="less" scoped>
.admin_page .admin_table_search .admin_state {
display: flex;
flex-wrap: wrap;
}
.admin_page .admin_table_search .admin_state {
display: flex;
flex-wrap: wrap;
}
</style>

View File

@@ -22,7 +22,7 @@
</a-range-picker>
</div>
<div class="admin_state_item">
<span>Country:</span>
<span>Country or Region:</span>
<a-select
v-model:value="country"
:allowClear="true"
@@ -97,7 +97,7 @@
></a-select>
</div>
<div class="admin_state_item">
<span>Total Amount:</span>
<span>Total Amount: {{ totalPayer }}</span>
</div>
</div>
<div class="admin_search">
@@ -210,6 +210,8 @@ export default defineComponent({
orderBy:'',
status: "",
type: "",
totalPayer:0,
});
let selectList=reactive({
platformList:[
@@ -365,11 +367,11 @@ export default defineComponent({
ellipsis:true
},
{
title: "Country",
title: "Country or Region",
align: "center",
dataIndex: "country",
key: "country",
width:150,
width:200,
ellipsis:true
},
{
@@ -405,8 +407,11 @@ export default defineComponent({
filterData.orderBy = 'credits'
}
}
filterData.order = sorter.order == "descend" ? "DESC" : "ASC";
if(sorter.order){
filterData.order = sorter.order == "descend" ? "DESC" : "ASC";
}else{
filterData.order = ''
}
gettrialList();
};
@@ -466,6 +471,9 @@ export default defineComponent({
filter.dataList = rv.content;
filterData.total = rv.total;
filter.tableLoading = false;
rv.content.forEach((item: any) => {
filterData.totalPayer += Number(item.payerTotal)
})
// this.workspaceItem.position = this.singleTypeList[0].label
}

View File

@@ -69,13 +69,13 @@
<div class="operate_item" @click="editAffiliate(record)">Edit</div>
</div>
<div v-else-if="column?.openType" @click="openDetail(record,column?.openType)">
{{ text }} HDK
{{ text }} HKD
</div>
</template>
</a-table>
</div>
<itemAffiliateDetail ref="itemAffiliateDetail"></itemAffiliateDetail>
<editAudit ref="editAudit"></editAudit>
<editAudit ref="editAudit" @searchHistoryList="searchHistoryList"></editAudit>
</div>
</template>
<script lang="ts">
@@ -109,20 +109,33 @@ export default defineComponent({
key: "username",
},
{
title: 'Create Time',
align: "center",
width: 200,
dataIndex: "createTime",
key: "createTime",
sorter: true,
},{
title: 'State',
align: "center",
ellipsis: true,
width: 100,
dataIndex: "status",
key: "status",
},{
title: 'Visits',
align: "center",
ellipsis: true,
width: 100,
dataIndex: "visits",
key: "visits",
},{
title: 'Commission Percent',
align: "center",
ellipsis: true,
width: 100,
dataIndex: "commissionPercent",
key: "commissionPercent",
customRender: (record: any) => {
if(record.text){
return record.text+'%'
}else{
return '-'
}
},
},{
title: 'Total income',
align: "center",
@@ -154,6 +167,13 @@ export default defineComponent({
width: 250,
dataIndex: "link",
key: "link",
},{
title: 'Create Time',
align: "center",
width: 200,
dataIndex: "createTime",
key: "createTime",
sorter: true,
},{
title: 'Updata Time',
align: "center",

View File

@@ -57,6 +57,11 @@
style="width: 250px"
/>
</div>
<!-- {{ currentState }} -->
<div class="admin_state_item">
<span>State:</span>
<a-select v-model:value="currentState" style="width:250px" optionFilterProp="label" :options="state" placeholder="Please select" allowClear show-search></a-select>
</div>
</div>
<div class="allUserPoeration_btn admin_page">
<div class="admin_search_item" @click="cancelDsign">Close</div>
@@ -96,14 +101,29 @@ export default defineComponent({
id: "",
commission: "",
});
let currentState = ref('')
let state = ref([
{
label:'Active',
value:'Active',
},
{
label:'Delete',
value:'Delete',
},
{
label:'Inactive',
value:'Inactive',
},
])
let init = (data) => {
let funStr = 'Edit'
console.log(data)
operations.operationsModal = true;
operations.title = funStr;
if (funStr == "Edit") {
operationsData.id = data.id;
operationsData.commission = data.commissionPercent;
currentState.value = data.status;
}
};
@@ -111,11 +131,13 @@ export default defineComponent({
return {
id: operationsData.id,
commission: operationsData.commission,
operationType: currentState.value,
};
};
let cancelDsign = () => {
operationsData.id = "";
operationsData.commission = "";
currentState.value = "";
operations.operationsModal = false;
};
let setOk = () => {
@@ -125,7 +147,7 @@ export default defineComponent({
!data.commission
)
return message.warning("Please check the input box marked with *");
Https.axiosGet(Https.httpUrls.updateCommission, {params:data}).then(
Https.axiosGet(Https.httpUrls.editAffiliate, {params:data}).then(
(rv) => {
if (rv) {
cancelDsign();
@@ -139,6 +161,8 @@ export default defineComponent({
...toRefs(operationsData),
cancelDsign,
init,
state,
currentState,
setOk,
};
},

View File

@@ -26,7 +26,7 @@
<a-select v-model:value="userType" size="large" style="width:250px" optionFilterProp="label" :options="state" placeholder="Please select" allowClear show-search></a-select>
</div> -->
<div class="admin_state_item">
<span>Country:</span>
<span>Country or Region:</span>
<a-select
v-model:value="country"
:allowClear="true"
@@ -292,11 +292,11 @@ export default defineComponent({
},
},
{
title: "Country",
title: "Country or Region",
align: "center",
dataIndex: "country",
key: "country",
width:100,
width:200,
},
{
title: "Create Date",
@@ -394,8 +394,11 @@ export default defineComponent({
filterData.orderBy = 'credits'
}
}
filterData.order = sorter.order == "descend" ? "Descending" : "Ascending";
if(sorter.order){
filterData.order = sorter.order == "descend" ? "Descending" : "Ascending";
}else{
filterData.order = ''
}
gettrialList();
};

View File

@@ -92,7 +92,7 @@
/>
</div>
<div class="admin_state_item">
<span>Country:</span>
<span>Country or Region:</span>
<input
:disabled="title != 'Add'"
:class="{active:title != 'Add'}"

View File

@@ -1,298 +1,331 @@
<template>
<div class="allUserPoerationModal" ref="allUserPoerationModal"></div>
<a-modal
class="allUserPoeration_modal generalModel"
v-model:visible="operationsModal"
:footer="null"
:get-container="() => $refs.allUserPoerationModal"
width="50%"
:height="'77rem'"
:maskClosable="false"
:centered="true"
:closable="false"
:mask="true"
wrapClassName="#app"
:keyboard="false"
>
<div class="generalModel_btn">
<div class="generalModel_closeIcon" @click.stop="cancelDsign()">
<svg
width="100%" height="100%"
viewBox="0 0 46 46"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="23" cy="23" r="23" fill="black" fill-opacity="0.3" />
<rect
x="32.5063"
y="12"
width="3"
height="29"
rx="1.5"
transform="rotate(45 32.5063 12)"
fill="white"
/>
<rect
x="34.6274"
y="32.5059"
width="3"
height="29"
rx="1.5"
transform="rotate(135 34.6274 32.5059)"
fill="white"
/>
</svg>
</div>
</div>
<div class="modal_title_text">
<div>{{ title }} Coupon</div>
</div>
<div class="allUserPoeration_center admin_page">
<div class="admin_state_item">
<span>Cooperator:</span>
<input
v-model="cooperator"
placeholder="Please enter cooperator"
type="text"
style="width: 220px"
/>
</div>
<div class="admin_state_item">
<span>percentOff(%): <span>*</span></span>
<input
:class="{ active: title != 'Add' }"
:disabled="title != 'Add'"
v-model="percentOff"
placeholder="Please enter percentOff"
type="text"
style="width: 220px"
/>
</div>
<div class="admin_state_item">
<span>Commission Rate: <span>*</span></span>
<input
:class="{ active: title != 'Add' }"
:disabled="title != 'Add'"
v-model="commissionRate"
placeholder="Please enter commission rate"
type="text"
style="width: 220px"
/>
</div>
<div class="admin_state_item">
<!-- <div class="admin_state_item" > -->
<span>End Time: <span>*</span></span>
<a-space direction="vertical" style="width: 220px">
<a-date-picker
v-model:value="rangePickerValue"
:disabled="title != 'Add'"
style="width: 220px"
/>
</a-space>
</div>
<div class="admin_state_item">
<span>MaxRedemptions:</span>
<input
:class="{ active: title != 'Add' }"
:disabled="title != 'Add'"
v-model="maxRedemptions"
placeholder="Please enter maximum"
type="text"
style="width: 220px"
/>
</div>
<div class="admin_state_item">
<span>PaidCommission:</span>
<input
v-model="paidCommission"
placeholder="Please enter paidCommission"
type="text"
style="width: 220px"
/>
</div>
<div class="admin_state_item">
<span>Remark:</span>
<input
v-model="remark"
placeholder="Please enter remark"
type="text"
style="width: 220px"
/>
</div>
</div>
<div class="allUserPoeration_btn admin_page">
<div class="admin_search_item" @click="cancelDsign">Close</div>
<div class="admin_search_item" @click="setOk">OK</div>
</div>
</a-modal>
<div class="mark_loading" v-show="loadingShow">
<a-spin size="large" />
</div>
</template>
<script>
import {
defineComponent,
ref,
reactive,
watch,
onMounted,
nextTick,
toRefs,
} from "vue";
import { Https } from "@/tool/https";
import { Modal, message } from "ant-design-vue";
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";
import { formatTime, isEmail } from "@/tool/util";
import dayjs, { Dayjs } from "dayjs";
import md5 from "md5";
export default defineComponent({
components: {},
emits: ["searchHistoryList"],
setup(props, { emit }) {
let operations = reactive({
operationsModal: false,
operationsEdit: false,
loadingShow: false,
title: "",
});
let operationsData = reactive({
rangePickerValue: "",
percentOff: "",
commissionRate: "",
maxRedemptions: "",
cooperator: "",
paidCommission: "",
remark: "",
id: "",
});
let init = (funStr, data) => {
operations.operationsModal = true;
operations.operationsEdit = true;
operations.title = funStr;
if (funStr == "Add") operations.operationsEdit = false;
if (funStr == "Edit") {
operationsData.id = data.id;
operationsData.percentOff = data.percentOff;
operationsData.commissionRate = data.commissionRate;
operationsData.maxRedemptions = data.maxRedemptions;
operationsData.cooperator = data.cooperator;
operationsData.paidCommission = data.paidCommission;
operationsData.remark = data.remark;
operationsData.rangePickerValue = dayjs(
new Date(data.redeemBy * 1000).toISOString().split("T")[0],
"YYYY/MM/DD"
);
// operationsData.rangePickerValue='2024-08-05T00:00:06'
// operationsData.validEndTime='2024-08-05T00:00:06'
// operationsData.commissionRate = data.commissionRate
// operationsData.maxRedemptions = data.maxRedemptions
// operationsData.validStartTime = formatTime(data.validStartTime)
// operationsData.validEndTime = formatTime(data.validEndTime)
}
};
let setAddData = () => {
const timestampMs =
new Date(operationsData.rangePickerValue).getTime() / 1000; // 直接获取毫秒时间戳
return {
percentOff: operationsData.percentOff,
maxRedemptions: operationsData.maxRedemptions,
commissionRate: operationsData.commissionRate,
timestamp: timestampMs,
cooperator: operationsData.cooperator,
remark: operationsData.remark,
};
};
let setEditData = () => {
const timestampMs =
new Date(operationsData.rangePickerValue).getTime() / 1000; // 直接获取毫秒时间戳
return {
id: operationsData.id,
paidCommission: operationsData.commissionRate,
cooperator: operationsData.cooperator,
remark: operationsData.remark,
};
};
let cancelDsign = () => {
operationsData.rangePickerValue = "";
operationsData.percentOff = "";
operationsData.commissionRate = "";
operationsData.maxRedemptions = "";
operationsData.cooperator = "";
operationsData.paidCommission = "";
operationsData.remark = "";
operationsData.id = "";
operations.operationsModal = false;
};
let setOk = () => {
let data;
if (operations.title == "Add") {
data = setAddData();
if (!data.commissionRate || !data.timestamp || !data.percentOff)
return message.warning("Please check the input box marked with *");
Https.axiosPost(Https.httpUrls.createCoupon, data).then((rv) => {
if (rv) {
cancelDsign();
emit("searchHistoryList");
}
});
} else {
data = setEditData();
Https.axiosGet(Https.httpUrls.updatePromCodeInfo, {
params: data,
}).then((rv) => {
if (rv) {
cancelDsign();
emit("searchHistoryList");
}
});
}
};
return {
...toRefs(operations),
...toRefs(operationsData),
cancelDsign,
init,
focus,
blur,
setOk,
};
},
data() {
return {};
},
mounted() {},
methods: {},
});
</script>
<style lang="less" scoped>
:deep(.allUserPoeration_modal) {
.ant-modal-body {
display: flex;
flex-direction: column;
<div class="allUserPoerationModal" ref="allUserPoerationModal"></div>
<a-modal
class="allUserPoeration_modal generalModel"
v-model:visible="operationsModal"
:footer="null"
:get-container="() => $refs.allUserPoerationModal"
width="50%"
:height="'77rem'"
:maskClosable="false"
:centered="true"
:closable="false"
:mask="true"
wrapClassName="#app"
:keyboard="false"
>
<div class="generalModel_btn">
<div class="generalModel_closeIcon" @click.stop="cancelDsign()">
<svg
width="100%" height="100%"
viewBox="0 0 46 46"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="23" cy="23" r="23" fill="black" fill-opacity="0.3" />
<rect
x="32.5063"
y="12"
width="3"
height="29"
rx="1.5"
transform="rotate(45 32.5063 12)"
fill="white"
/>
<rect
x="34.6274"
y="32.5059"
width="3"
height="29"
rx="1.5"
transform="rotate(135 34.6274 32.5059)"
fill="white"
/>
</svg>
</div>
</div>
<div class="modal_title_text">
<div>{{ title }} Coupon</div>
</div>
<div class="allUserPoeration_center admin_page">
<div class="admin_state_item">
<span>Cooperator:</span>
<input
v-model="cooperator"
placeholder="Please enter cooperator"
type="text"
style="width: 220px"
/>
</div>
<div class="admin_state_item">
<span>percentOff(%): <span>*</span></span>
<input
:class="{ active: title != 'Add' }"
:disabled="title != 'Add'"
v-model="percentOff"
placeholder="Please enter percentOff"
type="text"
style="width: 220px"
/>
</div>
<div class="admin_state_item">
<span>Commission Rate: <span>*</span></span>
<input
:class="{ active: title != 'Add' }"
:disabled="title != 'Add'"
v-model="commissionRate"
placeholder="Please enter commission rate"
type="text"
style="width: 220px"
/>
</div>
<div class="admin_state_item">
<!-- <div class="admin_state_item" > -->
<span>Start Time: <span>*</span></span>
<a-space direction="vertical" style="width: 220px">
<a-date-picker
v-model:value="startTime"
:disabled="title != 'Add'"
style="width: 220px"
/>
</a-space>
</div>
<div class="admin_state_item">
<!-- <div class="admin_state_item" > -->
<span>End Time: <span>*</span></span>
<a-space direction="vertical" style="width: 220px">
<a-date-picker
v-model:value="endTime"
:disabled="title != 'Add'"
style="width: 220px"
/>
</a-space>
</div>
<div class="admin_state_item">
<span>MaxRedemptions:</span>
<input
:class="{ active: title != 'Add' }"
:disabled="title != 'Add'"
v-model="maxRedemptions"
placeholder="Please enter maximum"
type="text"
style="width: 220px"
/>
</div>
<div class="admin_state_item">
<span>PaidCommission:</span>
<input
v-model="paidCommission"
placeholder="Please enter paidCommission"
type="text"
style="width: 220px"
/>
</div>
<div class="admin_state_item">
<span>Remark:</span>
<input
v-model="remark"
placeholder="Please enter remark"
type="text"
style="width: 220px"
/>
</div>
</div>
<div class="allUserPoeration_btn admin_page">
<div class="admin_search_item" @click="cancelDsign">Close</div>
<div class="admin_search_item" @click="setOk">OK</div>
</div>
</a-modal>
<div class="mark_loading" v-show="loadingShow">
<a-spin size="large" />
</div>
</template>
<script>
import {
defineComponent,
ref,
reactive,
watch,
onMounted,
nextTick,
toRefs,
} from "vue";
import { Https } from "@/tool/https";
import { Modal, message } from "ant-design-vue";
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";
import { formatTime, isEmail } from "@/tool/util";
import dayjs, { Dayjs } from "dayjs";
import md5 from "md5";
export default defineComponent({
components: {},
emits: ["searchHistoryList"],
setup(props, { emit }) {
let operations = reactive({
operationsModal: false,
operationsEdit: false,
loadingShow: false,
title: "",
});
let operationsData = reactive({
endTime: "",
startTime: "",
percentOff: "",
commissionRate: "",
maxRedemptions: "",
cooperator: "",
paidCommission: "",
remark: "",
id: "",
});
let init = (funStr, data) => {
operations.operationsModal = true;
operations.operationsEdit = true;
operations.title = funStr;
if (funStr == "Add") operations.operationsEdit = false;
if (funStr == "Edit") {
operationsData.id = data.id;
operationsData.percentOff = data.percentOff;
operationsData.commissionRate = data.commissionRate;
operationsData.maxRedemptions = data.maxRedemptions;
operationsData.cooperator = data.cooperator;
operationsData.paidCommission = data.paidCommission;
operationsData.remark = data.remark;
operationsData.endTime = dayjs(
new Date(data.redeemBy * 1000).toLocaleDateString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit'
}).replace(/\//g, '/'),
"YYYY/MM/DD"
);
// 确保格式一致
// operationsData.startTime = dayjs(
// new Date(data.startTime * 1000).toISOString().split("T")[0],
// "YYYY/MM/DD"
// );
operationsData.startTime = dayjs(
new Date(data.startTime * 1000).toLocaleDateString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit'
}).replace(/\//g, '/'),
"YYYY/MM/DD"
);
// operationsData.endTime='2024-08-05T00:00:06'
// operationsData.validEndTime='2024-08-05T00:00:06'
// operationsData.commissionRate = data.commissionRate
// operationsData.maxRedemptions = data.maxRedemptions
// operationsData.validStartTime = formatTime(data.validStartTime)
// operationsData.validEndTime = formatTime(data.validEndTime)
}
};
let setAddData = () => {
const emdTimeMs =
new Date(operationsData.endTime).getTime() / 1000; // 直接获取毫秒时间戳
const startTimeMs =
new Date(operationsData.startTime).getTime() / 1000; // 直接获取毫秒时间戳
return {
percentOff: operationsData.percentOff,
maxRedemptions: operationsData.maxRedemptions,
commissionRate: operationsData.commissionRate,
endTime: emdTimeMs,
startTime: startTimeMs,
cooperator: operationsData.cooperator,
remark: operationsData.remark,
};
};
let setEditData = () => {
const timestampMs =
new Date(operationsData.endTime).getTime() / 1000; // 直接获取毫秒时间戳
return {
id: operationsData.id,
paidCommission: operationsData.commissionRate,
cooperator: operationsData.cooperator,
remark: operationsData.remark,
};
};
let cancelDsign = () => {
operationsData.endTime = "";
operationsData.startTime = "";
operationsData.percentOff = "";
operationsData.commissionRate = "";
operationsData.maxRedemptions = "";
operationsData.cooperator = "";
operationsData.paidCommission = "";
operationsData.remark = "";
operationsData.id = "";
operations.operationsModal = false;
};
let setOk = () => {
let data;
if (operations.title == "Add") {
data = setAddData();
if (!data.commissionRate || !data.startTime || !data.percentOff || !data.endTime)
return message.warning("Please check the input box marked with *");
Https.axiosPost(Https.httpUrls.createCoupon, data).then((rv) => {
if (rv) {
cancelDsign();
emit("searchHistoryList");
}
});
} else {
data = setEditData();
Https.axiosGet(Https.httpUrls.updatePromCodeInfo, {
params: data,
}).then((rv) => {
if (rv) {
cancelDsign();
emit("searchHistoryList");
}
});
}
};
return {
...toRefs(operations),
...toRefs(operationsData),
cancelDsign,
init,
focus,
blur,
setOk,
};
},
data() {
return {};
},
mounted() {},
methods: {},
});
</script>
<style lang="less" scoped>
:deep(.allUserPoeration_modal) {
.ant-modal-body {
display: flex;
flex-direction: column;
}
}
}
</style>
<style lang="less" scoped>
.allUserPoeration_modal {
.closeIcon {
z-index: 2;
</style>
<style lang="less" scoped>
.allUserPoeration_modal {
.closeIcon {
z-index: 2;
}
.allUserPoeration_btn {
display: flex;
flex-direction: row;
height: auto;
justify-content: flex-end;
padding: 1rem 0;
.admin_search_item {
margin-bottom: 0;
}
}
.allUserPoeration_center {
flex: 1;
overflow-y: auto;
flex-direction: row;
flex-wrap: wrap;
}
}
.allUserPoeration_btn {
display: flex;
flex-direction: row;
height: auto;
justify-content: flex-end;
padding: 1rem 0;
.admin_search_item {
margin-bottom: 0;
}
}
.allUserPoeration_center {
flex: 1;
overflow-y: auto;
flex-direction: row;
flex-wrap: wrap;
}
}
</style>
</style>

View File

@@ -1,228 +1,305 @@
<template>
<div class="admin_page">
<div class="admin_table_search" >
<div class="admin_state">
<div class="admin_page">
<div class="admin_table_search">
<div class="admin_state">
<div class="admin_state_item">
<span>Status:</span>
<a-select
v-model:value="status"
size="large"
style="width: 250px"
optionFilterProp="label"
:options="statusList"
placeholder="Please select"
allowClear
show-search
></a-select>
</div>
</div>
<div class="admin_search">
<div class="admin_search_item" @click="searchHistoryList">
Search
</div>
<div class="admin_search_item" @click="addhHistoryList">
Add
</div>
</div>
</div>
<div class="admin_table_content" ref="historyTable">
<a-table
@resizeColumn="handleResizeColumn"
:loading="tableLoading"
:columns="columns"
:data-source="dataList"
:scroll="{ y: historyTableHeight }"
@change="changePage"
:showSorterTooltip='false'
:pagination="{
showSizeChanger: true,
current: currentPage,
pageSize: pageSize,
total: total,
showQuickJumper: true,
bordered: false,
}"
>
</a-table>
</div>
<span>Create Time:</span>
<a-range-picker
style="width: 250px"
class="range_picker"
v-model:value="rangePickerValue"
:placeholder="[
$t('HistoryPage.StartDate'),
$t('HistoryPage.EndDate'),
]"
valueFormat="YYYY-MM-DD"
>
<template #suffixIcon>
<span
class="icon iconfont range_picker_icon icon-rili"
></span>
</template>
</a-range-picker>
</div>
<div class="admin_state_item">
<span>Status:</span>
<a-select
v-model:value="status"
size="large"
style="width: 250px"
optionFilterProp="label"
:options="statusList"
placeholder="Please select"
@change="changeStatus"
allowClear
show-search
></a-select>
</div>
<div class="admin_state_item">
<span>School:</span>
<a-select
v-model:value="school"
size="large"
style="width: 250px"
optionFilterProp="label"
:options="schoolList"
placeholder="Please select"
allowClear
show-search
@focus="handleFocus"
></a-select>
</div>
</div>
<div class="admin_search">
<div class="admin_search_item" @click="searchHistoryList">
Search
</div>
<div class="admin_search_item" @click="addhHistoryList">
Add
</div>
</div>
</div>
<div class="admin_table_content" ref="historyTable">
<a-table
@resizeColumn="handleResizeColumn"
:loading="tableLoading"
:columns="columns"
:data-source="dataList"
:scroll="{ y: historyTableHeight }"
@change="changePage"
:showSorterTooltip="false"
:pagination="{
showSizeChanger: true,
current: currentPage,
pageSize: pageSize,
total: total,
showQuickJumper: true,
bordered: false,
}"
>
</a-table>
</div>
<add ref="add" @searchHistoryList="searchHistoryList"></add>
</div>
</div>
</template>
<script lang="ts">
import {
defineComponent,
ref,
createVNode,
computed,
reactive,
toRefs,
onMounted,
} from "vue";
import { formatTime } from "@/tool/util";
import { useStore } from "vuex";
import { Https } from "@/tool/https";
import {getCookie,clonAllCookie} from '@/tool/cookie'
import add from './add.vue'
export default defineComponent({
components: {add},
setup() {
const store:any = useStore()
let filter: any = reactive({
dataList: [],
tableLoading: false,
countryList: computed(()=>{
return store.state.adminPage.country
}),
add:null as any,
status:'',
});
let filterData: any = reactive({
currentPage: 1,
pageSize: 10,
total: 0,
country: "",
status: "",
type: "",
});
let selectList=reactive({
statusList:[
{
label: "all",
value: "",
import {
defineComponent,
ref,
createVNode,
computed,
reactive,
toRefs,
onMounted,
} from "vue";
import { formatTime } from "@/tool/util";
import { useStore } from "vuex";
import { Https } from "@/tool/https";
import { getCookie, clonAllCookie } from "@/tool/cookie";
import add from "./add.vue";
export default defineComponent({
components: { add },
setup() {
const store: any = useStore();
let filter: any = reactive({
dataList: [],
tableLoading: false,
countryList: computed(() => {
return store.state.adminPage.country;
}),
add: null as any,
});
let filterData: any = reactive({
currentPage: 1,
pageSize: 10,
total: 0,
country: "",
status: "",
school: "",
rangePickerValue: [],
});
let selectList = reactive({
statusList: [
{
label: "all",
value: "",
},
{
label: "Enterprise",
value: "Enterprise",
},
{
label: "Education",
value: "Education",
},
],
schoolList: [],
});
let renameData: any = ref({}); //修改名字选中的数据
const columns: any = computed(() => {
return [
{
title: "Id",
align: "center",
dataIndex: "id",
key: "id",
width: 150,
ellipsis: true,
},
{
title: "Name",
align: "center",
dataIndex: "name",
key: "name",
width: 150,
ellipsis: true,
},
{
title: "Create Time",
align: "center",
dataIndex: "createTime",
key: "createTime",
width: 150,
ellipsis: true,
},
{
title: "Type",
align: "center",
dataIndex: "type",
key: "type",
width: 150,
ellipsis: true,
},
];
});
//改变页码
let changePage = (e: any, filters: any, sorter: any) => {
filterData.currentPage = e.current;
filterData.pageSize = e.pageSize;
gettrialList();
};
const filterOption = (e: any) => {
let type = filterData.status;
if (type == "Education") type = "School";
let params = {
name: e,
type,
};
Https.axiosPost(
Https.httpUrls.organizationNameSearch,
{},
{ params: params }
).then((rv: any) => {
if (rv.length == 0) return (selectList.schoolList = []);
selectList.schoolList = rv.map((item: any) => {
return {
label: item,
value: item,
};
});
});
};
//查询列表
let searchHistoryList = () => {
filterData.currentPage = 1;
gettrialList();
};
//获取列表
let gettrialList = () => {
filter.tableLoading = true;
const dateArr = filterData.rangePickerValue;
const startDate = dateArr?.[0] ? dateArr[0] + " " + "00:00:00" : "";
const endDate = dateArr?.[1] ? dateArr[1] + " " + "23:59:59" : "";
const params = {
startTime: startDate,
endTime: endDate,
id: "",
name: filterData.school,
type: filterData.status,
size: filterData.pageSize,
page: filterData.currentPage,
}; //type: "Enterprise"
Https.axiosPost(Https.httpUrls.queryOrganization, params).then(
(rv: any) => {
if (rv) {
console.log(rv);
// filter.dataList = rv;
filter.dataList = rv.records;
filterData.total = rv.total;
filter.tableLoading = false;
// this.workspaceItem.position = this.singleTypeList[0].label
}
}
);
};
let addhHistoryList = () => {
filter.add.init("Add", "");
};
const handleFocus = () => {
if (selectList.schoolList.length == 0) {
filterOption("");
}
};
const changeStatus = () => {
filterData.school = "";
selectList.schoolList = [];
};
onMounted(() => {
gettrialList();
});
return {
...toRefs(filter),
...toRefs(filterData),
...toRefs(selectList),
columns,
renameData,
changePage,
searchHistoryList,
gettrialList,
addhHistoryList,
handleFocus,
changeStatus,
};
},
data() {
return {
historyTableHeight: 0,
handleResizeColumn: (w: any, col: any) => {
col.width = w;
},
{
label:'Enterprise',
value:'Enterprise',
},
{
label:'Education',
value:'Education',
},
],
})
let renameData: any = ref({}); //修改名字选中的数据
const columns: any = computed(() => {
return [
{
title: "Id",
align: "center",
dataIndex: "id",
key: "id",
width:150,
ellipsis:true
},
{
title: "Name",
align: "center",
dataIndex: "name",
key: "name",
width:150,
ellipsis:true
},
{
title: "Create Time",
align: "center",
dataIndex: "createTime",
key: "createTime",
width:150,
ellipsis:true
},
{
title: "Type",
align: "center",
dataIndex: "type",
key: "type",
width:150,
ellipsis:true,
},
];
});
//改变页码
let changePage = (e: any, filters:any, sorter:any) => {
filterData.currentPage = e.current;
filterData.pageSize = e.pageSize;
gettrialList();
};
//查询列表
let searchHistoryList = () => {
filterData.currentPage = 1;
gettrialList();
};
//获取列表
let gettrialList = () => {
filter.tableLoading = true;
Https.axiosGet(Https.httpUrls.queryOrganization, {params:{type:'Enterprise'}}).then(
(rv: any) => {
if (rv) {
console.log(rv)
filter.dataList = rv
// filter.dataList = rv.content;
// filterData.total = rv.total;
filter.tableLoading = false;
// this.workspaceItem.position = this.singleTypeList[0].label
}
}
);
};
let addhHistoryList = () => {
filter.add.init('Add','')
};
onMounted(() => {
gettrialList();
});
return {
...toRefs(filter),
...toRefs(filterData),
...toRefs(selectList),
columns,
renameData,
changePage,
searchHistoryList,
gettrialList,
addhHistoryList,
};
},
data() {
return {
historyTableHeight: 0,
handleResizeColumn: (w: any, col: any) => {
col.width = w;
},
};
},
mounted() {
let historyTable: any = this.$refs.historyTable;
this.historyTableHeight = historyTable.clientHeight - 200;
},
methods: {},
});
};
},
mounted() {
let historyTable: any = this.$refs.historyTable;
this.historyTableHeight = historyTable.clientHeight - 200;
},
methods: {},
});
</script>
<style lang="less" scoped>
.admin_page .admin_table_search .admin_state {
display: flex;
flex-wrap: wrap;
}
:deep(.operate_list){
.fi{
font-size: 2rem;
margin-right: 1rem;
.admin_page .admin_table_search .admin_state {
display: flex;
flex-wrap: wrap;
}
.success{
.fi-ss-check-circle{
color: #3ab45c;
:deep(.operate_list) {
.fi {
font-size: 2rem;
margin-right: 1rem;
}
.success {
.fi-ss-check-circle {
color: #3ab45c;
}
}
.pending {
.fi-ss-check-circle {
color: #ffc628;
}
}
.fail {
.fi-ss-check-circle {
color: #ff0000;
}
}
}
.pending{
.fi-ss-check-circle{
color: #ffc628;
}
}
.fail{
.fi-ss-check-circle{
color: #ff0000;
}
}
}
</style>

View File

@@ -150,11 +150,11 @@ export default defineComponent({
},
},
{
title: "Country",
title: "Country or Region",
align: "center",
dataIndex: "country",
key: "country",
width:100,
width:200,
},
{
title: "Create Date",
@@ -242,7 +242,11 @@ export default defineComponent({
filterData.orderBy = 'credits'
}
}
filterData.order = sorter.order == "descend" ? "Descending" : "Ascending";
if(sorter.order){
filterData.order = sorter.order == "descend" ? "Descending" : "Ascending";
}else{
filterData.order = ''
}
gettrialList();
}

View File

@@ -177,11 +177,11 @@ export default defineComponent({
},
},
{
title: "Country",
title: "Country or Region",
align: "center",
dataIndex: "country",
key: "country",
width:100,
width:200,
},
{
title: "Create Date",
@@ -268,7 +268,11 @@ export default defineComponent({
filterData.orderBy = 'credits'
}
}
filterData.order = sorter.order == "descend" ? "Descending" : "Ascending";
if(sorter.order){
filterData.order = sorter.order == "descend" ? "Descending" : "Ascending";
}else{
filterData.order = ''
}
gettrialList();
}

View File

@@ -23,7 +23,7 @@
</a-range-picker>
</div>
<div class="admin_state_item">
<span>Country:</span>
<span>Country or Region:</span>
<a-select
v-model:value="country"
:allowClear="true"
@@ -201,7 +201,11 @@ export default defineComponent({
filterData.orderBy = 'time'
}
}
filterData.order = sorter.order == "descend" ? "Descending" : "Ascending";
if(sorter.order){
filterData.order = sorter.order == "descend" ? "Descending" : "Ascending";
}else{
filterData.order = ''
}
gettrialList();
}

View File

@@ -10,6 +10,8 @@ import { fabric } from "fabric-with-all";
import { generateId } from "../utils/helper.js";
import { ClearSelectionCommand } from "./LassoCutoutCommand.js";
import { ClearSelectionContentCommand } from "./ClearSelectionContentCommand.js";
import i18n from "@/lang/index.ts";
const { t } = i18n.global;
/**
* 剪切选区到新图层命令
@@ -36,7 +38,7 @@ export class CutSelectionToNewLayerCommand extends CompositeCommand {
this.baseResolutionScale = options.baseResolutionScale || 2; // 基础分辨率倍数
this.groupId = options.groupId || generateId("lasso-copy-group-");
this.groupName = options.groupName || `选区组`;
this.groupName = options.groupName || t(`Canvas.ConstituencyGroup`);
this.groupLayer = null; // 新增:保存组图层的引用
this.originalLayersLength = 0; // 新增:保存原始图层数量
@@ -179,7 +181,7 @@ export class CutSelectionToNewLayerCommand extends CompositeCommand {
// 创建新的组图层
this.groupLayer = createLayer({
id: this.groupId,
name: this.groupName || `选区组`,
name: this.groupName || t(`Canvas.ConstituencyGroup`),
type: LayerType.GROUP,
visible: true,
locked: false,

View File

@@ -18,6 +18,7 @@ export class FillGroupLayerBackgroundCommand extends Command {
this.canvas = options.canvas;
this.layers = options.layers;
this.canvasManager = options.canvasManager;
this.layerManager = options.layerManager;
this.layerId = options.layerId;
this.fillColor = options.fillColor;
this.oldFill = null;
@@ -42,13 +43,25 @@ export class FillGroupLayerBackgroundCommand extends Command {
this.firstObj = null; // 用于存储组图层的原始对象
}
async execute() {
const layer = this.layer;
async execute(isUndo = false) {
const { layer, parent } = findLayerRecursively(
this.layers.value,
this.layerId
);
this.layer = layer;
this.parent = parent;
console.log("==========",layer);
if (!layer) return false;
this.oldFill = layer.fill ?? null;
this.oldFillColor = layer.oldFillColor ?? null;
if(!isUndo){
this.oldFill = layer.fill ?? null;
this.oldFillColor = layer.fillColor ?? null;
if(this.oldFill){
// 移除旧的填充对象
removeCanvasObjectByObject(this.canvas, this.oldFill);
}
}
const fillColor = isUndo ? this.oldFillColor : this.fillColor;
// 构建填充对象
let clippingMaskFabricObject = null;
if (layer.clippingMask) {
@@ -63,7 +76,7 @@ export class FillGroupLayerBackgroundCommand extends Command {
height: clippingMaskFabricObject.height,
left: clippingMaskFabricObject.left || 0,
top: clippingMaskFabricObject.top || 0,
fill: this.fillColor,
fill: fillColor,
layerId: this.layerId,
id: this.oldFill?.id || generateId("fill-"),
selectable: false,
@@ -84,7 +97,7 @@ export class FillGroupLayerBackgroundCommand extends Command {
height: originalInfo.height,
left: originalInfo.left + originalInfo.width / 2 || 0,
top: originalInfo.top + originalInfo.height / 2 || 0,
fill: this.fillColor,
fill: fillColor,
layerId: this.layerId,
id: this.oldFill?.id || generateId("fill-"),
selectable: false,
@@ -111,7 +124,7 @@ export class FillGroupLayerBackgroundCommand extends Command {
height: clippingMaskFabricObject.height,
left: clippingMaskFabricObject.left || 0,
top: clippingMaskFabricObject.top || 0,
fill: this.fillColor,
fill: fillColor,
layerId: this.layerId,
id: this.oldFill?.id || generateId("fill-"),
selectable: false,
@@ -127,7 +140,7 @@ export class FillGroupLayerBackgroundCommand extends Command {
height: this.canvasManager?.canvasHeight?.value || this.canvas.height,
left: this.canvas.width / 2 || 0,
top: this.canvas.height / 2 || 0,
fill: this.fillColor,
fill: fillColor,
layerId: this.layerId,
id: this.oldFill?.id || generateId("fill-"),
selectable: false,
@@ -143,8 +156,8 @@ export class FillGroupLayerBackgroundCommand extends Command {
layer.fabricObjects = [
this.newFill.toObject(["id", "layerId"]) || this.newFill,
];
layer.fill = null; // this.newFill.toObject(["id", "layerId"]);
layer.fillColor = this.fillColor;
layer.fill = this.newFill; // this.newFill.toObject(["id", "layerId"]);
layer.fillColor = fillColor;
// 取消激活对象
this.canvas.discardActiveObject(); // 取消当前活动对象
@@ -199,6 +212,7 @@ export class FillGroupLayerBackgroundCommand extends Command {
this.group.set({
id: layerObjects[0]?.id || generateId("group-"),
layerId: this.layer?.id,
layerName: this.layer?.name,
});
// this.group.setCoords();
// this.group.setObjectsCoords();
@@ -213,7 +227,7 @@ export class FillGroupLayerBackgroundCommand extends Command {
this.group.clipPath = clipPath;
}
layer.fabricObjects = [
this.group.toObject(["id", "layerId"]) || this.group,
this.group.toObject(["id", "layerId", "layerName"]) || this.group,
];
// removeCanvasObjectByObject(this.canvas, layerObjects?.[0]);
insertObjectAtZIndex(this.canvas, this.group, insertIndex, false, true);
@@ -222,8 +236,8 @@ export class FillGroupLayerBackgroundCommand extends Command {
// this.group?.addWithUpdate?.();
// layer.fabricObjects = [this.group?.toObject?.(["id", "layerId"]) || this.group];
// this.canvas.renderAll();
layer.fill = null; // this.newFill.toObject(["id", "layerId"]);
layer.fillColor = this.fillColor;
layer.fill = this.newFill; // this.newFill.toObject(["id", "layerId"]);
layer.fillColor = fillColor;
// 取消激活对象
this.canvas.discardActiveObject(); // 取消当前活动对象
@@ -237,14 +251,11 @@ export class FillGroupLayerBackgroundCommand extends Command {
return true;
}
async undo() {
this.layer.fillColor = this.oldFillColor;
this.layer.fill = this.oldFill;
if (!this.originalInfo && this.firstObj) {
if (!this.originalInfo && this.layer.fill) {
this.canvas.discardActiveObject();
this.canvas.remove(this.firstObj);
this.canvas.remove(this.layer.fill);
this.canvas.renderAll();
this.canvasManager.thumbnailManager?.generateLayerThumbnail(
this.parent && this.canvasManager.thumbnailManager?.generateLayerThumbnail(
this.parent.id
);
this.canvasManager.thumbnailManager?.generateLayerThumbnail(
@@ -264,7 +275,8 @@ export class FillGroupLayerBackgroundCommand extends Command {
canvasObj?._objects?.length > 0
) {
// 移除新添加的填充对象
if (canvasObj._objects?.[0] === this.newFill) {
// if (canvasObj._objects?.[0] === this.newFill) {
if (/^fill-/.test(canvasObj._objects?.[0]?.id)) {
canvasObj._objects.shift();
canvasObj.addWithUpdate();
canvasObj.setCoords();
@@ -284,6 +296,14 @@ export class FillGroupLayerBackgroundCommand extends Command {
this.canvas.renderAll();
this.group = null;
}
if(this.oldFill){
this.layer.fill = this.oldFill;
this.layer.fillColor = this.oldFillColor;
return this.execute(true);
}else{
this.layer.fill = null;
this.layer.fillColor = null;
}
this.canvas.discardActiveObject(); // 取消当前活动对象
// 重新排序

View File

@@ -11,6 +11,10 @@ import {
} from "./LayerCommands.js";
import { fabric } from "fabric-with-all";
import { generateId } from "../utils/helper.js";
import i18n from "@/lang/index.ts";
const { t } = i18n.global;
/**
* 套索抠图命令
@@ -37,7 +41,7 @@ export class LassoCutoutCommand extends CompositeCommand {
this.baseResolutionScale = options.baseResolutionScale || 2; // 基础分辨率倍数
this.groupId = options.groupId || generateId("lasso-group-");
this.groupName = options.groupName || `选区组`;
this.groupName = options.groupName || t(`Canvas.ConstituencyGroup`);
this.clippingMaskId = generateId("clipping-mask-");
@@ -238,7 +242,7 @@ export class LassoCutoutCommand extends CompositeCommand {
// 创建新的组图层
this.groupLayer = createLayer({
id: this.groupId,
name: this.groupName || `选区组`,
name: this.groupName || t(`Canvas.ConstituencyGroup`),
type: LayerType.GROUP,
visible: true,
locked: false,

View File

@@ -13,6 +13,9 @@ import {
import { fabric } from "fabric-with-all";
import { generateId } from "../utils/helper.js";
import { ToolCommand } from "./ToolCommands.js";
import i18n from "@/lang/index.ts";
const { t } = i18n.global;
/**
* 套索抠图命令
@@ -39,7 +42,7 @@ export class LassoCutoutCommand extends CompositeCommand {
this.baseResolutionScale = options.baseResolutionScale || 2; // 基础分辨率倍数
this.groupId = options.groupId || generateId("lasso-group-");
this.groupName = options.groupName || `选区组`;
this.groupName = options.groupName || t(`Canvas.ConstituencyGroup`);
this.clippingMaskId = generateId("clipping-mask-");
@@ -220,16 +223,26 @@ export class LassoCutoutCommand extends CompositeCommand {
await clearSelectionCmd.execute();
this.executedCommands.push(clearSelectionCmd);
const topLayerIndex = this.layerManager.layers.value.findIndex(
(layer) => layer.id === this.originalLayer.id
);
const layers = this.layerManager.layers.value;
var topLayerIndex = 0;
layers.forEach((layer, index) => {
if (layer.id === this.originalLayer.id) {
topLayerIndex = index;
}else if (layer.children.length > 0) {
layer.children.forEach((childLayer) => {
if (childLayer.id === this.originalLayer.id) {
topLayerIndex = index;
}
});
}
});
// const selectLayer = this.layerManager.layers.value[topLayerIndex];
// 创建新的组图层
this.groupLayer = createLayer({
id: this.groupId,
name: this.groupName || `选区组`,
name: this.groupName || t(`Canvas.ConstituencyGroup`),
type: LayerType.GROUP,
visible: true,
locked: false,
@@ -244,7 +257,7 @@ export class LassoCutoutCommand extends CompositeCommand {
// });
const selectLayer = createLayer({
name: `选区空图层`,
name: t(`Canvas.ConstituencyEmptyLayer`),
type: LayerType.EMPTY,
visible: true,
locked: false,
@@ -284,6 +297,7 @@ export class LassoCutoutCommand extends CompositeCommand {
this.groupLayer.children.push(selectLayer);
// 插入新组图层
console.log("新增套索添加index", topLayerIndex);
this.layerManager.layers.value.splice(topLayerIndex, 0, this.groupLayer);
this.layerManager.activeLayerId.value = selectLayer.id; // 设置新组图层为活动图层

View File

@@ -70,7 +70,7 @@ export class AddLayerCommand extends Command {
undo() {
// 从图层列表删除该图层
this.layers.value = this.beforeLayers;
this.layers.value = [...this.beforeLayers];
// 恢复原活动图层
this.activeLayerId.value = this.oldActiveLayerId;
@@ -116,7 +116,7 @@ export class AddLayerCommand extends Command {
parentLayer.children.splice(insertIndex, 0, newLayer);
console.log(
`新图层已插入到子图层位置: ${insertIndex} (父图层: ${parentLayer.name})`
`新图层已插入到子图层位置: ${insertIndex} (父图层: ${parentLayer.name})`
);
} else {
// 当前激活图层是一级图层
@@ -528,6 +528,7 @@ export class RemoveLayerCommand extends Command {
this.layerIndex = this.layers.value.findIndex(
(layer) => layer.id === this.layerId
);
this.removedLayer = this.layers.value[this.layerIndex];
this.isActiveLayer = this.layerId === this.activeLayerId.value;
@@ -563,7 +564,12 @@ export class RemoveLayerCommand extends Command {
allObjects.push(object);
}
}
layer.fabricObjects?.forEach((fabric) => {
const { object } = findObjectById(this.canvas, fabric.id);
if (object && !allObjects.includes(object)) {
allObjects.push(object);
}
});
// 递归收集子图层的对象
if (layer.children && Array.isArray(layer.children)) {
layer.children.forEach((childLayer) => {
@@ -588,6 +594,9 @@ export class RemoveLayerCommand extends Command {
}
});
this.layerIndex = this.layers.value.findIndex(
(layer) => layer.id === this.layerId
);
// 从图层列表中删除
this.layers.value.splice(this.layerIndex, 1);
@@ -599,6 +608,9 @@ export class RemoveLayerCommand extends Command {
);
if (newActiveLayer) {
this.activeLayerId.value = newActiveLayer.id;
if(this.canvas.toolId === OperationType.SELECT){
this.layerManager.selectLayerObjects(newActiveLayer.id);
}
} else {
this.activeLayerId.value = null;
}
@@ -609,7 +621,7 @@ export class RemoveLayerCommand extends Command {
// this.canvas.renderAll();
// }
await this.layerManager?.updateLayersObjectsInteractivity?.();
// this.canvas.renderAll();
this.canvas.renderAll();
console.log(
`✅ 已移除图层: ${this.removedLayer.name} (ID: ${this.layerId}),包含 ${this.originalObjects.length} 个对象`
@@ -2013,7 +2025,7 @@ export class LayerObjectsToGroupCommand extends Command {
console.error("图层或Canvas未初始化");
return null;
}
this.activeLayer = this.layerManager.getActiveLayer();
// 查找图层中是否已有组对象
const existingGroup = this._findExistingGroup();
this.existingGroupId = existingGroup?.id || null;
@@ -2053,7 +2065,7 @@ export class LayerObjectsToGroupCommand extends Command {
}
try {
await optimizeCanvasRendering(this.canvas, () => {
await optimizeCanvasRendering(this.canvas, async () => {
if (existingGroup) {
// 向现有组添加对象
this._addObjectsToExistingGroup(existingGroup, newObjectsToAdd);
@@ -2064,13 +2076,13 @@ export class LayerObjectsToGroupCommand extends Command {
this._createNewGroupWithAllObjects(newObjectsToAdd);
this.groupObjectId = this.newGroupId;
this.wasGroupCreated = true;
await this.layerManager?.layerSort?.rearrangeObjects();
}
// 更新交互性
this.layerManager?.updateLayersObjectsInteractivity?.(false);
// 更新缩略图
this._updateThumbnail();
this.layerManager?.updateLayersObjectsInteractivity?.(false).then(()=>{
// 更新缩略图
this._updateThumbnail();
});
});
// 标记为非首次执行
@@ -2220,7 +2232,7 @@ export class LayerObjectsToGroupCommand extends Command {
async undo() {
if (!this.activeLayer || !this.canvas || !this.groupObjectId) return;
this.activeLayer = this.layerManager.getActiveLayer();
try {
await optimizeCanvasRendering(this.canvas, async () => {
if (this.wasGroupCreated) {
@@ -2338,7 +2350,7 @@ export class LayerObjectsToGroupCommand extends Command {
// 将对象添加回画布
this.canvas.add(obj);
restoredObjects.push(obj);
restoredObjects.push(obj.toObject("id", "layerId", "layerName"));
console.log(
`✅ 恢复原始对象 ${obj.id || obj.type} 到位置 (${position.left}, ${
@@ -2537,9 +2549,9 @@ export class LayerObjectsToGroupCommand extends Command {
* @private
*/
_updateThumbnail() {
// this.canvas?.thumbnailManager?.generateLayerThumbnail?.(
// this.activeLayer.id
// );
this.canvas?.thumbnailManager?.generateLayerThumbnail?.(
this.activeLayer.id
);
}
getInfo() {
@@ -2569,7 +2581,6 @@ export class CreateImageLayerCommand extends Command {
this.fabricImage = options.fabricImage;
this.toolManager = options.toolManager;
this.layerName = options.layerName || null;
this.imageId = generateId("image_");
// 存储执行过程中的结果
@@ -2591,7 +2602,7 @@ export class CreateImageLayerCommand extends Command {
// 生成图层名称
const fileName =
this.layerName || `图片 ${new Date().toLocaleTimeString()}`;
this.layerName || `${new Date().toLocaleTimeString()}`;
this.fabricImage.set({
id: this.imageId,
@@ -2617,6 +2628,18 @@ export class CreateImageLayerCommand extends Command {
this.commands.push(createLayerCmd);
this.executedCommands.push(createLayerCmd);
// 新加功能-选区套索内添加图片自动居中
const { parent } = findLayerRecursively(this.layerManager.layers.value, this.newLayerId);
if(parent && parent.selectObject){
let {top,left,width,height} = parent.selectObject;
const ltop = top + height / 2;
const lleft = left + width / 2;
this.fabricImage.set({
top: ltop,
left: lleft,
})
}
// 2. 添加图片对象到图层命令
const addObjectCmd = new AddObjectToLayerCommand({
canvas: this.layerManager.canvas,
@@ -4197,6 +4220,7 @@ export class RemoveChildLayerCommand extends Command {
this.isActiveLayer = this.layerId === this.activeLayerId.value;
this.originalObjects = this.canvas.getObjects().filter((obj) => {
obj.parentId = this.parentId;
return obj.layerId === this.layerId;
});
}

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