This commit is contained in:
chenhao 2025-03-25 16:50:47 +08:00
parent 6a25f63cbe
commit 2f36aa1588
110 changed files with 23075 additions and 3 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

3
.gitignore vendored
View File

@ -423,3 +423,6 @@ docs/_book
# TODO: where does this rule come from? # TODO: where does this rule come from?
test/ test/
dist/
package-lock.json

View File

@ -1,3 +1,3 @@
# Ly.Offical.HYL # Pan.Template.H5
好运徕 - 官网 h5底版

46
index.html Normal file
View File

@ -0,0 +1,46 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<link rel="shortcut icon" href="#" />
<link rel="icon" type="image/x-icon" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>素材网</title>
<link rel="stylesheet/less" type="text/css" href="/css/ly.less" />
<script src="js/jquery-1.11.3.min.js"></script>
<script src="js/html2canvas.min.js"></script>
<script src="js/canvas2image.js"></script>
</head>
<body>
<div id="app" v-cloak></div>
<script type="module" src="/src/main.js"></script>
</body>
<style>
[v-cloak] {
display: none;
}
/* Light mode */
@media (prefers-color-scheme: light) {
body {
--base-nav-bar-bg-color: #ededed;
--base-nav-bar-color: #111;
}
}
/* Dark mode */
@media (prefers-color-scheme: dark) {
body {
--base-nav-bar-bg-color: #111;
--base-nav-bar-color: #ededed;
}
}
</style>
</html>

34
package.json Normal file
View File

@ -0,0 +1,34 @@
{
"name": "pan.template.h5",
"private": true,
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "vite build"
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"axios": "^1.7.9",
"canvas2image": "^1.0.5",
"element-plus": "^2.9.4",
"html2canvas": "^1.4.1",
"jquery": "^3.7.1",
"pan.template.h5": "file:",
"postcss-px-to-viewport": "^1.1.1",
"vant": "^4.9.9",
"vue": "^3.2.45",
"vue-fast-marquee": "^1.0.6",
"vue-qr": "^4.0.9",
"vue-router": "^4.5.0",
"vuex": "^4.1.0"
},
"devDependencies": {
"@types/node": "^22.10.5",
"@vant/auto-import-resolver": "^1.0.1",
"@vitejs/plugin-vue": "^4.3.4",
"less": "^4.2.0",
"unplugin-auto-import": "^19.1.0",
"unplugin-vue-components": "^0.25.2",
"vite": "^4.5.5"
}
}

BIN
public/.DS_Store vendored Normal file

Binary file not shown.

140
public/css/common.less Normal file
View File

@ -0,0 +1,140 @@
body {
.b_l_w;
font-size: 3.2vw;
}
.bg(@e, @url) {
&::before {
content: '';
width: 100vw;
height: 100vh;
position: fixed;
left: 0;
top: 0;
background-color: @e;
background-image: @url;
background-repeat: no-repeat;
background-size: 100% auto;
z-index: -1;
}
}
.f5 {
.bg(#f5f5f5, none);
}
p {
margin: 0;
}
img {
display: block;
object-fit: contain;
}
[v-cloak] {
display: none !important;
}
body,
.van-pull-refresh {
overflow: visible !important;
}
.van-toast {
width: max-content !important;
}
.van-nav-bar--fixed {
z-index: 999 !important;
}
.van-tabbar__placeholder {
.b_l_w;
}
.van-nav-bar {
.van-nav-bar__text,
.van-icon {
color: #000 !important;
}
}
.van-nav-bar__placeholder {
.van-nav-bar .van-icon {
color: #000;
}
}
.van-tabbar {
.b_l_w;
height: 20vw !important;
.van-tabbar-item__icon img {
height: 10vw;
margin: -2vw 0 0;
}
.van-tabbar-item__text {
font-size: 3.2vw;
}
}
.tabs {
--van-tabs-line-height: 12vw;
--van-tab-font-size: 4.267vw;
.van-tabs__line {
border-radius: 0 !important;
}
}
.van-image-preview__cover {
left: 0 !important;
bottom: 0 !important;
top: initial !important;
width: 100%;
height: 12vw !important;
}
.van-uploader {
.van-uploader__input-wrapper {
.b_l_w;
.box;
.box-tb;
.box-align-center;
>p {
font-size: 3.467vw;
color: #1b1b1b;
}
}
.Avatar {
width: 33.333vw;
height: 33.333vw;
margin: 0 0 5vw;
position: relative;
&::before {
content: '';
position: absolute;
right: 0;
bottom: 2vw;
width: 9.333vw;
height: 9.333vw;
.y50;
background: url(/images/upload-picture.png) no-repeat;
background-size: 100% 100%;
}
img {
width: 100%;
height: 100%;
.y50;
}
}
}

334
public/css/gm.less Normal file
View File

@ -0,0 +1,334 @@
::after,
::before,
* {
word-wrap: break-word;
box-sizing: border-box;
}
a {
text-decoration: none;
color: #000;
}
.mx-auto {
margin: 0 auto !important;
}
.bs {
color: #fff;
}
.f(@e, @u) {
font-size: unit(@e, @u);
}
.r(@e, @u) {
border-radius: unit(@e, @u);
}
.mt(@e, @u) {
margin-top: unit(@e, @u);
}
.mb(@e, @u) {
margin-bottom: unit(@e, @u);
}
.b_k {
background: #fff;
}
.b {
font-weight: bold;
}
.y50 {
border-radius: 50%;
object-fit: cover !important;
}
.w(@e, @u) {
width: unit(@e, @u);
}
.w {
width: 100%;
}
.h {
height: 100%;
}
.w100 {
width: 100% !important;
img {
width: 100% !important;
}
}
.p-r {
position: relative;
}
.p-a {
position: absolute;
}
.p-f {
position: fixed;
}
.div_chao {
white-space: nowrap;
overflow-x: auto;
.inline {
display: inline-block !important;
}
}
.dis {
display: none;
}
.dis-l {
display: block;
}
.songti {
font-family: 宋体;
}
.b_l {
float: left;
}
.b_r {
float: right;
}
.r {
margin-left: auto;
}
.b_l_w {
width: 100%;
float: left;
}
.w1 {
width: 100%;
float: left;
}
.text-center {
text-align: center;
}
.text-left {
text-align: left;
}
.text-right {
text-align: right;
}
.text-hide(@line) {
overflow: hidden !important;
text-overflow: ellipsis;
display: -webkit-box !important;
-webkit-box-orient: vertical;
-webkit-line-clamp: @line;
}
.text-hide-1 {
overflow: hidden !important;
text-overflow: ellipsis;
white-space: nowrap;
}
.gray(@a, @b) {
filter: grayscale(@a) invert(@b);
}
.brightness(@a, @b) {
filter: brightness(@a) invert(@b);
}
/*伸缩盒子模型*/
.box {
display: flex;
flex-wrap: nowrap;
}
/*从左至右*/
.box-lr {
flex-direction: row;
}
/*从右至左*/
.box-rl {
flex-direction: row-reverse;
}
/*从上至下*/
.box-tb {
flex-direction: column;
}
/*从下至上*/
.box-bt {
flex-direction: column-reverse;
}
/*主轴居中*/
.box-pack-center {
justify-content: center;
}
.middle {
display: flex;
justify-content: space-between;
/*justify-content: space-evenly;*/
}
.middle::before,
.middle::after {
content: '';
display: block;
}
/*主轴居左*/
.box-pack-start {
justify-content: flex-start;
}
/*主轴居右*/
.box-pack-end {
justify-content: flex-end;
}
/*主轴左右不留白*/
.box-pack-between {
justify-content: space-between;
}
/*主轴左右留白*/
.box-pack-around {
justify-content: space-around;
}
/*自动间隔,每个元素的间隔相等*/
.box-middle {
justify-content: space-evenly;
}
/*交叉轴居中对齐*/
.box-align-center {
align-items: center;
}
/*交叉轴居左对齐*/
.box-align-start {
align-items: flex-start;
}
/*交叉轴居右对齐*/
.box-align-end {
align-items: flex-end;
}
/**单个指定的子元素自定义对齐方式,可以不同于其他子元素对齐方式**/
/**指定子元素居中对齐**/
.self-align-center {
align-self: center;
margin: 0 auto;
}
/**指定子元素顶部对齐**/
.self-align-start {
align-self: flex-start;
}
/**指定子元素底部对齐**/
.self-align-end {
align-self: flex-end;
}
/**指定子元素拉伸**/
.self-align-stretch {
align-self: stretch;
}
/**子元素换行**/
.box-wrap {
flex-wrap: wrap;
}
/**子元素不换行**/
.box-nowrap {
flex-wrap: nowrap;
}
/*允许子元素伸展1倍*/
.flex {
flex-grow: 1;
/*如果值是2 那么当前元素就是其他元素宽的2倍了*/
}
/* flex:1 是 flex-grow、flex-shrink、flex-basis的缩写。故其取值可以考虑以下情况
flex-grow:0表示不会拉伸 flex-shrink:1表示 可以缩小
flex 的默认值是以上三个属性值的组合。假设以上三个属性同样取默认值,则 flex 的默认值是 0 1 auto*/
/*允许子元素收缩(1倍)*/
.shrink {
flex-shrink: 1;
}
/**水平居中*/
.box-center-center {
justify-content: center;
align-items: center;
text-align: center;
}

1495
public/css/ly.less Normal file

File diff suppressed because it is too large Load Diff

BIN
public/images/.DS_Store vendored Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

BIN
public/images/about-i1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 519 KiB

BIN
public/images/banner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

BIN
public/images/btm-i1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
public/images/btm-i2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
public/images/btm-i3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
public/images/btm-i4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
public/images/btm-i5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
public/images/btm-i6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
public/images/btm-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

BIN
public/images/bus-i1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 515 KiB

BIN
public/images/cert-bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

BIN
public/images/cert-i1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

BIN
public/images/cert-i2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

BIN
public/images/cert-i3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

BIN
public/images/cert-i4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

BIN
public/images/com-bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 692 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
public/images/cul-i5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

BIN
public/images/detail-i1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 530 KiB

BIN
public/images/detail-i2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
public/images/detail-i3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
public/images/detail-i4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 809 B

BIN
public/images/detail-i5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
public/images/detail-i6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 895 B

BIN
public/images/detail-i7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 935 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 369 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
public/images/e-i1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

BIN
public/images/e-i2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

BIN
public/images/e-i3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

BIN
public/images/intro-i1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 419 KiB

BIN
public/images/list-i1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

BIN
public/images/list-i2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

BIN
public/images/list-i3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 KiB

BIN
public/images/list-i4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

BIN
public/images/list-i5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 KiB

BIN
public/images/list-i6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

BIN
public/images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

BIN
public/images/maps.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 509 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 837 KiB

BIN
public/images/news-i1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 530 KiB

BIN
public/images/office-i1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 475 KiB

BIN
public/images/office-i2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 KiB

BIN
public/images/office-i3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

BIN
public/images/office-i4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

BIN
public/images/op-i1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
public/images/op-i2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

BIN
public/images/op-i3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
public/images/op-i4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

BIN
public/images/op-i5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
public/images/op-i6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

BIN
public/images/op-i7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 741 KiB

BIN
public/images/part-i1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
public/images/part-i2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
public/images/part-i3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

BIN
public/images/scheme.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 738 KiB

BIN
public/images/team-i1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

235
public/js/canvas2image.js Normal file
View File

@ -0,0 +1,235 @@
/*
* Canvas2Image v0.1
* Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk
* MIT License [http://www.opensource.org/licenses/mit-license.php]
*/
var Canvas2Image = (function () {
// check if we have canvas support
var bHasCanvas = false;
var oCanvas = document.createElement("canvas");
if (oCanvas.getContext("2d")) {
bHasCanvas = true;
}
// no canvas, bail out.
if (!bHasCanvas) {
return {
saveAsBMP: function () { },
saveAsPNG: function () { },
saveAsJPEG: function () { }
}
}
var bHasImageData = !!(oCanvas.getContext("2d").getImageData);
var bHasDataURL = !!(oCanvas.toDataURL);
var bHasBase64 = !!(window.btoa);
var strDownloadMime = "image/octet-stream";
// ok, we're good
var readCanvasData = function (oCanvas) {
var iWidth = parseInt(oCanvas.width);
var iHeight = parseInt(oCanvas.height);
return oCanvas.getContext("2d").getImageData(0, 0, iWidth, iHeight);
}
// base64 encodes either a string or an array of charcodes
var encodeData = function (data) {
var strData = "";
if (typeof data == "string") {
strData = data;
} else {
var aData = data;
for (var i = 0; i < aData.length; i++) {
strData += String.fromCharCode(aData[i]);
}
}
return btoa(strData);
}
// creates a base64 encoded string containing BMP data
// takes an imagedata object as argument
var createBMP = function (oData) {
var aHeader = [];
var iWidth = oData.width;
var iHeight = oData.height;
aHeader.push(0x42); // magic 1
aHeader.push(0x4D);
var iFileSize = iWidth * iHeight * 3 + 54; // total header size = 54 bytes
aHeader.push(iFileSize % 256); iFileSize = Math.floor(iFileSize / 256);
aHeader.push(iFileSize % 256); iFileSize = Math.floor(iFileSize / 256);
aHeader.push(iFileSize % 256); iFileSize = Math.floor(iFileSize / 256);
aHeader.push(iFileSize % 256);
aHeader.push(0); // reserved
aHeader.push(0);
aHeader.push(0); // reserved
aHeader.push(0);
aHeader.push(54); // dataoffset
aHeader.push(0);
aHeader.push(0);
aHeader.push(0);
var aInfoHeader = [];
aInfoHeader.push(40); // info header size
aInfoHeader.push(0);
aInfoHeader.push(0);
aInfoHeader.push(0);
var iImageWidth = iWidth;
aInfoHeader.push(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth / 256);
aInfoHeader.push(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth / 256);
aInfoHeader.push(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth / 256);
aInfoHeader.push(iImageWidth % 256);
var iImageHeight = iHeight;
aInfoHeader.push(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight / 256);
aInfoHeader.push(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight / 256);
aInfoHeader.push(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight / 256);
aInfoHeader.push(iImageHeight % 256);
aInfoHeader.push(1); // num of planes
aInfoHeader.push(0);
aInfoHeader.push(24); // num of bits per pixel
aInfoHeader.push(0);
aInfoHeader.push(0); // compression = none
aInfoHeader.push(0);
aInfoHeader.push(0);
aInfoHeader.push(0);
var iDataSize = iWidth * iHeight * 3;
aInfoHeader.push(iDataSize % 256); iDataSize = Math.floor(iDataSize / 256);
aInfoHeader.push(iDataSize % 256); iDataSize = Math.floor(iDataSize / 256);
aInfoHeader.push(iDataSize % 256); iDataSize = Math.floor(iDataSize / 256);
aInfoHeader.push(iDataSize % 256);
for (var i = 0; i < 16; i++) {
aInfoHeader.push(0); // these bytes not used
}
var iPadding = (4 - ((iWidth * 3) % 4)) % 4;
var aImgData = oData.data;
var strPixelData = "";
var y = iHeight;
do {
var iOffsetY = iWidth * (y - 1) * 4;
var strPixelRow = "";
for (var x = 0; x < iWidth; x++) {
var iOffsetX = 4 * x;
strPixelRow += String.fromCharCode(aImgData[iOffsetY + iOffsetX + 2]);
strPixelRow += String.fromCharCode(aImgData[iOffsetY + iOffsetX + 1]);
strPixelRow += String.fromCharCode(aImgData[iOffsetY + iOffsetX]);
}
for (var c = 0; c < iPadding; c++) {
strPixelRow += String.fromCharCode(0);
}
strPixelData += strPixelRow;
} while (--y);
var strEncoded = encodeData(aHeader.concat(aInfoHeader)) + encodeData(strPixelData);
return strEncoded;
}
// sends the generated file to the client
var saveFile = function (strData) {
document.location.href = strData;
}
var makeDataURI = function (strData, strMime) {
return "data:" + strMime + ";base64," + strData;
}
// generates a <img> object containing the imagedata
var makeImageObject = function (strSource) {
var oImgElement = document.createElement("img");
oImgElement.src = strSource;
return oImgElement;
}
var scaleCanvas = function (oCanvas, iWidth, iHeight) {
if (iWidth && iHeight) {
var oSaveCanvas = document.createElement("canvas");
oSaveCanvas.width = iWidth;
oSaveCanvas.height = iHeight;
oSaveCanvas.style.width = iWidth + "px";
oSaveCanvas.style.height = iHeight + "px";
var oSaveCtx = oSaveCanvas.getContext("2d");
oSaveCtx.drawImage(oCanvas, 0, 0, oCanvas.width, oCanvas.height, 0, 0, iWidth, iHeight);
return oSaveCanvas;
}
return oCanvas;
}
return {
saveAsPNG: function (oCanvas, bReturnImg, iWidth, iHeight) {
if (!bHasDataURL) {
return false;
}
var oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight);
var strData = oScaledCanvas.toDataURL("image/png");
if (bReturnImg) {
return makeImageObject(strData);
} else {
saveFile(strData.replace("image/png", strDownloadMime));
}
return true;
},
saveAsJPEG: function (oCanvas, bReturnImg, iWidth, iHeight) {
if (!bHasDataURL) {
return false;
}
var oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight);
var strMime = "image/jpeg";
var strData = oScaledCanvas.toDataURL(strMime);
// check if browser actually supports jpeg by looking for the mime type in the data uri.
// if not, return false
if (strData.indexOf(strMime) != 5) {
return false;
}
if (bReturnImg) {
return makeImageObject(strData);
} else {
saveFile(strData.replace(strMime, strDownloadMime));
}
return true;
},
saveAsBMP: function (oCanvas, bReturnImg, iWidth, iHeight) {
if (!(bHasImageData && bHasBase64)) {
return false;
}
var oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight);
var oData = readCanvasData(oScaledCanvas);
var strImgData = createBMP(oData);
if (bReturnImg) {
return makeImageObject(makeDataURI(strImgData, "image/bmp"));
} else {
saveFile(makeDataURI(strImgData, strDownloadMime));
}
return true;
}
};
})();

3718
public/js/html2canvas.min.js vendored Normal file

File diff suppressed because it is too large Load Diff

5
public/js/jquery-1.11.3.min.js vendored Normal file

File diff suppressed because one or more lines are too long

BIN
src/.DS_Store vendored Normal file

Binary file not shown.

47
src/App.vue Normal file
View File

@ -0,0 +1,47 @@
<template>
<router-view />
</template>
<script>
export default {
watch: {
$route(to, from) {
},
},
computed: {
},
data() {
return {
show: false,
showData: 0,
shown: false,
loading: false,
}
},
mounted() {
this.init();
},
methods: {
init() {
},
onRefresh() {
location.reload();
},
getShareLink() {
},
},
};
</script>
<style>
.van-pull-refresh__track {
min-height: 100vh;
}
.van-toast {
width: max-content !important;
}
</style>

14780
src/api/area.json Normal file

File diff suppressed because it is too large Load Diff

11
src/api/common.js Normal file
View File

@ -0,0 +1,11 @@
import http from '../utils/http';
const CommonAPI = {
Post(name, data, index, size) {
if (index)
return http.post(`Common/${name}`, { data: data, PageIndex: index, PageSize: size });
return http.post(`Common/${name}`, { data: data });
},
}
export default CommonAPI;

37
src/api/location.js Normal file
View File

@ -0,0 +1,37 @@
export function getCurrentPosition() {
return new Promise((resolve, reject) => {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
(position) => {
resolve({
latitude: position.coords.latitude,
longitude: position.coords.longitude
});
},
(error) => {
reject(error);
},
{
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
}
);
} else {
reject(new Error('Geolocation is not supported'));
}
});
}
// 获取城市代码
export async function getCityCode() {
try {
const position = await getCurrentPosition();
const url = `https://restapi.amap.com/v3/geocode/regeo?key=${AMAP_KEY}&location=${position.longitude},${position.latitude}`;
const response = await axios.get(url);
return response.data?.regeocode?.addressComponent?.citycode;
} catch (error) {
console.error('获取城市代码失败:', error);
return null;
}
}

17
src/api/member.js Normal file
View File

@ -0,0 +1,17 @@
import http from '../utils/http'
const MemberAPI = {
WXAuthorize(data) {
return http.get('Wechat/Authorize', { path: data });
},
Login(data) {
return http.get('Auth/Token', data);
},
Post(name, data, index, size) {
if (index)
return http.post(`Member/${name}`, { data: data, PageIndex: index, PageSize: size });
return http.post(`Member/${name}`, { data: data });
},
}
export default MemberAPI;

21
src/api/pay.js Normal file
View File

@ -0,0 +1,21 @@
import http from '../utils/http'
const PayAPI = {
PayInfo(data) {
return http.post('Member/PayInfo', { data: data });
},
WalletPay(data) {
return http.post('Member/WalletPay', { data, data });
},
Wechat_JS(data) {
return http.get('Pay/Wechat_JS', data);
},
AliPay_H5(data) {
return http.get('Pay/AliPay_H5', data);
},
// Wechat_Mini(data) {
// return http.get('Pay/Wechat_Mini', data);
// },
}
export default PayAPI;

288
src/main.js Normal file
View File

@ -0,0 +1,288 @@
import $ from 'jquery';
import { createApp, h, render } from "vue";
import App from "./App.vue";
import store from './store';
// import { initPreload } from './api/amap';
import { createRouter, createWebHashHistory } from "vue-router";
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
// // 初始化预加载
// initPreload().then(() => {
// console.log('地区数据预加载完成');
// }).catch(err => {
// console.error('地区数据预加载失败:', err);
// });
import routes from "./router";
import less from "less";
import axios from 'axios';
import "vue-fast-marquee/style.css";
import Marquee from 'vue-fast-marquee';
import VueQr from "vue-qr/src/packages/vue-qr.vue";
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import {
showToast,
showLoadingToast,
showSuccessToast,
showFailToast,
showNotify,
showDialog,
showConfirmDialog,
showImagePreview,
closeToast
} from "vant";
import "vant/es/notify/style";
import "vant/es/dialog/style";
import "vant/es/toast/style";
import "vant/es/image-preview/style";
const app = createApp(App);
app.config.globalProperties.$ = $;
app.use(ElementPlus);
app.component("VueQr", VueQr)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
const router = createRouter({
history: createWebHashHistory(),
routes,
scrollBehavior(to, from, savedPosition) {
if (to.meta.cache && savedPosition)
return new Promise((resolve, reject) => {
resolve(savedPosition);
});
else
return { top: 0 };
}
});
app.use(router);
app.use(store);
app.use(Marquee);
const getStore = (e) => {
return store.state[e];
}
app.config.globalProperties.$getStore = getStore;
app.config.globalProperties.$showDialog = showDialog;
app.config.globalProperties.$showConfirmDialog = showConfirmDialog;
app.config.globalProperties.$showNotify = showNotify;
app.config.globalProperties.$showToast = showToast;
app.config.globalProperties.$showLoadingToast = showLoadingToast;
app.config.globalProperties.$showSuccessToast = showSuccessToast;
app.config.globalProperties.$showFailToast = showFailToast;
app.config.globalProperties.$closeToast = closeToast;
app.config.globalProperties.$showImagePreview = showImagePreview;
app.config.globalProperties.$toMoney = (e, label) => {
const num = parseFloat(e).toFixed(2);
const [a, b] = num.split('.');
return `${a}.<${label}>${b}</${label}>`;
};
app.config.globalProperties.$autoToast = (val, msg, type = 'Fail', isThrow = true) => {
if (val) {
app.config.globalProperties[`$show${type}Toast`](msg);
if (isThrow)
throw msg;
}
};
let skeleton;
app.config.globalProperties.$showSkeleton = () => {
if (!skeleton)
skeleton = h(BaseSkeleton);
render(skeleton, document.body);
document.body.appendChild(skeleton.el);
};
app.config.globalProperties.$closeSkeleton = () => {
if (skeleton && document.body.contains(skeleton.el))
document.body.removeChild(skeleton.el);
};
app.config.globalProperties.$navigate = (e) => {
if (window.__wxjs_environment === 'miniprogram') {
const index = e.indexOf('?');
let query = '';
if (index > -1)
query = e.slice(index);
const data = router.resolve({ path: e });
wx.miniProgram.navigateTo({
url: `/pages/webview/webview?url=${encodeURIComponent(`${location.origin}/${data.href}${query}`)}`,
});
}
else { router.push(e); }
};
app.config.globalProperties.$ls = {
set: (e, obj) => {
localStorage.setItem(e, obj);
},
get: (e) => {
return localStorage.getItem(e);
},
remove: (e) => {
localStorage.removeItem(e);
}
};
app.config.globalProperties.$ss = {
set: (e, obj) => {
sessionStorage.setItem(e, obj);
},
get: (e) => {
return sessionStorage.getItem(e);
},
remove: (e) => {
sessionStorage.removeItem(e);
}
};
app.config.globalProperties.$conf = {
apiUrl: import.meta.env.VITE_API_URL,
ossUrl: import.meta.env.VITE_OSS_URL,
};
app.config.globalProperties.$unsigned = (e) => { return e > 0 ? e : 0 };
app.config.globalProperties.$truncate = (e, p, a) => {
return `${e.substring(0, p)}...${e.substring(e.length - a)}`;
};
app.config.globalProperties.$token = (e) => {
const token = localStorage.getItem(e).split('.');
return {
header: JSON.parse(atob(token[0])),
payload: JSON.parse(atob(token[1])),
}
};
app.config.globalProperties.$file = (e) => {
e = e || 'base/avatar.png';
if (e.startsWith('http://') || e.startsWith('https://'))
return e;
else
return import.meta.env.VITE_OSS_URL + e;
};
app.config.globalProperties.$openUrl = (e) => {
window.open(e);
};
app.config.globalProperties.$refresh = () => { window.location.replace('#/refresh?key=' + app.config.globalProperties.$route.name) };
app.config.globalProperties.$verify = (permissions, module, type) => {
return permissions.indexOf(`${module}:${type}`) > -1;
};
app.config.globalProperties.$substring = (e, begin, end) => {
if (typeof e !== 'string') {
return '';
}
return e.length > end ? e.substring(begin, end) + "..." : e;
}
app.config.globalProperties.$fileSize = (e) => {
let level = 0;
while (e >= 1024 && level < 4) {
e /= 1024;
level++;
}
return `${e.toFixed(2)}${['B', 'KB', 'MB', 'GB'][level]}`;
};
app.config.globalProperties.$compressFiles = (files) => {
const fileArray = Array.isArray(files) ? files : [files];
const promises = fileArray.map(file => {
return new Promise((resolve, reject) => {
if (!(file instanceof File)) {
return reject(new Error('Invalid file type'));
}
imageConversion.compressAccurately(file, 400)
.then(res => {
res = new File([res], file.name, { type: res.type, lastModified: Date.now() });
resolve(res);
})
.catch(err => {
console.error('压缩失败', err);
reject(err);
});
});
});
return Promise.all(promises);
};
app.config.globalProperties.$uploadFiles = (files) => {
return new Promise((resolve, reject) => {
const config = {
headers: {
'Content-Type': "multipart/form-data",
'Member-Token': localStorage.getItem('member_token'),
}
};
axios.post(`${import.meta.env.VITE_API_URL}File/MemberUpload`, files, config).then(data => {
if (data?.data) {
if (data.data?.errcode) {
reject(data.data);
}
else {
//上传成功
resolve(data.data);
}
}
else {
reject({ errmsg: '上传失败' });
}
}).catch(err => {
reject(err);
});
});
}
app.config.globalProperties.$distance = (e) => {
if (e < 1)
return `${e * 1000}m`;
return `${e}km`;
};
app.config.globalProperties.$goIndex = () => {
if (window.__wxjs_environment == 'miniprogram') {
wx.miniProgram.reLaunch({
url: `/pages/index/index`,
});
}
else {
location.replace('#/');
setTimeout(() => {
location.reload();
}, 100);
}
}
app.config.globalProperties.$CheckStates = [{ label: '待审核', color: 'primary' }, { label: '已通过', color: 'success' }, { label: '已拒绝', color: 'danger' }];
// api
import MemberAPI from './api/member';
import CommonAPI from './api/common';
import PayAPI from './api/pay';
app.config.globalProperties.$MemberAPI = MemberAPI;
app.config.globalProperties.$CommonAPI = CommonAPI;
app.config.globalProperties.$PayAPI = PayAPI;
app.config.globalProperties.$isWechat = () => { return navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger' };
app.config.globalProperties.$isWechatMini = () => { return window.__wxjs_environment == 'miniprogram' };
app.config.globalProperties.$openLocation = (lon, lat, name = '', address = '') => {
if (wx && app.config.globalProperties.$isWechat())
wx.openLocation({
longitude: lon,
latitude: lat,
name: name,
address: address,
scale: 18,
});
else
window.open(`http://api.map.baidu.com/marker?location=${lat},${lon}&coord_type=gcj02&title=${name}&content=${address}&output=html`);
};
app.config.globalProperties.$isLogin = () => {
if (!localStorage.getItem('member_token'))
return false;
const token = app.config.globalProperties.$token('member_token');
return token.header.exp > Date.now() && (window.__wxjs_environment != 'miniprogram' || localStorage.getItem('miniopenid'));
}
app.config.globalProperties.$validPhone = (e) => {
return /^1(3|4|5|6|7|8|9)\d{9}$/.test(e);
}
app.mount("#app");

111
src/router.js Normal file
View File

@ -0,0 +1,111 @@
const routes = [
{
path: '/',
name: 'Index',
component: () => import('./views/Index.vue'),
children: [
],
meta: { noLogin: true, }
},
{
path: '/SyncAuth',
name: 'SyncAuth',
component: () => import('./views/SyncAuth.vue'),
meta: {
title: '同步认证',
noLogin: true,
}
},
{
path: '/Clear',
name: 'Clear',
component: () => import('./views/Clear.vue'),
meta: {
title: '清除缓存',
noLogin: true,
}
},
{
path: '/404',
name: '404',
component: () => import('./views/404.vue'),
meta: {
title: '404',
noLogin: true,
}
},
{
path: '/Layout',
name: 'Layout',
component: () => import('./views/Layout.vue'),
meta: {
noLogin: true,
},
children: [
{
path: '/Home',
name: 'Home',
component: () => import('./views/Home.vue'),
meta: {
noLogin: true,
}
},
{
path: '/Business',
name: 'Business',
component: () => import('./views/Business.vue'),
meta: {
noLogin: true,
}
},
{
path: '/About',
name: 'About',
component: () => import('./views/About.vue'),
meta: {
noLogin: true,
}
},
{
path: '/News',
name: 'News',
component: () => import('./views/News.vue'),
meta: {
noLogin: true,
}
},
{
path: '/Detail',
name: 'Detail',
component: () => import('./views/Detail.vue'),
meta: {
noLogin: true,
}
},
{
path: '/Partners',
name: 'Partners',
component: () => import('./views/Partners.vue'),
meta: {
noLogin: true,
}
},
{
path: '/Contact',
name: 'Contact',
component: () => import('./views/Contact.vue'),
meta: {
noLogin: true,
}
}
]
},
{
path: '/:pathMatch(.*)',
redirect: '/404'
},
];
export default routes;

20
src/store/index.js Normal file
View File

@ -0,0 +1,20 @@
// store.js
import { createStore } from 'vuex';
const store = createStore({
state: {
imageSrc: null,
},
mutations: {
setImageSrc(state, src) {
state.imageSrc = src;
},
},
actions: {
updateImageSrc({ commit }, src) {
commit('setImageSrc', src);
},
},
});
export default store;

36
src/utils/http.js Normal file
View File

@ -0,0 +1,36 @@
import {request} from './request'
const http = {
get(url, params) {
const config = {
method: 'get',
url: url
}
if (params) config.params = params
return request(config)
},
post(url, params) {
const config = {
method: 'post',
url: url
}
if (params) config.data = params
return request(config)
},
put(url, params) {
const config = {
method: 'put',
url: url
}
if (params) config.params = params
return request(config)
},
delete(url, params) {
const config = {
method: 'post',
url: url
}
if (params) config.params = params
return request(config)
}
}
export default http

68
src/utils/request.js Normal file
View File

@ -0,0 +1,68 @@
import axios from 'axios'
export function request(config) {
const instance = axios.create({
baseURL: import.meta.env.VITE_API_URL,
timeout: 60000,
})
instance.interceptors.request.use(config => {
config.headers['Member-Token'] = localStorage.getItem('member_token') || '';
config.headers['Content-Type'] = 'application/json';
if (config.data) {
config.data.ts = Date.now();
} else {
config.data = {
data: {},
ts: Date.now(),
};
}
return config;
}, error => {
return Promise.error(error)
}
)
instance.interceptors.response.use(rep => {
if (rep.data.errcode) {
if (rep.data.errcode == 41000) {
localStorage.setItem('member_token', rep.data.access_token);
return new Promise((resolve, reject) => {
axios.request(rep.config).then(data => {
if (data.data.errcode)
reject(data.data);
else
resolve(data.data);
}).catch(err => {
if (err.isAxiosError) {
switch (err.code) {
case 'ERR_NETWORK': reject('服务器连接失败');
case 'ECONNABORTED': reject('网络繁忙,请重试');
default: reject(err.message);
}
}
reject(err);
});
});
}
else if ([41001, 40001, 40002].includes(rep.data.errcode)) {
localStorage.removeItem('member_token');
location.replace('#/Login');
return Promise.reject({ errcode: rep.data.errcode, errmsg: '请先登录' });
}
else
return Promise.reject(rep.data);
}
else
return Promise.resolve(rep.data);
}, error => {
if (error.isAxiosError) {
switch (error.code) {
case 'ERR_NETWORK': return Promise.reject('服务器连接失败');
case 'ECONNABORTED': return Promise.reject('网络繁忙,请重试');
default: return Promise.reject(error.message);
}
}
return Promise.reject(error)
})
return instance(config);
}
export default request

BIN
src/videos/test.mp4 Normal file

Binary file not shown.

24
src/views/404.vue Normal file
View File

@ -0,0 +1,24 @@
<template>
<van-empty image="error" description="抱歉,该页面不存在" />
<div class="b_l_w" style="display: flex; justify-content: center;">
<van-button type="primary" @click="back">返回</van-button>
</div>
</template>
<script>
export default {
mounted() {
},
data() {
return {
}
},
methods: {
back() {
this.$router.back();
}
}
}
</script>

271
src/views/About.vue Normal file
View File

@ -0,0 +1,271 @@
<script>
import { ref } from 'vue';
export default {
setup() {
const culture = ref([
{
id: 1,
img: '/images/culture-i1.png',
num: '01',
title: '企业使命',
content: '让生活更美好',
},
{
id: 2,
img: '/images/culture-i2.png',
num: '02',
title: '经营理念',
content: '致诚、致勤、致善、致远',
},
{
id: 3,
img: '/images/culture-i3.png',
num: '03',
title: '核心价值观',
content: '共创、共享、共赢',
brtext: '利他、感恩、有爱',
},
{
id: 4,
img: '/images/culture-i4.png',
num: '04',
title: '企业宗旨',
content: '科学创新、无私奉献',
brtext: '服务社会、造福于民',
},
])
return {
culture,
};
},
methods: {
onlefticon() {
const element = document.getElementById("certimgs");
element.scrollLeft -= 333;
console.log("element.scrollLeft");
},
onrighticon() {
const element = document.getElementById("certimgs");
element.scrollLeft += 333;
},
}
};
</script>
<template>
<div class="about">
<div class="banner">
<img src="/images/about-banner.png" alt="" style="width: 100%;">
</div>
<div class="profile">
<div class="pbox">
<div class="fonts">
<b class="big-ft">ABOUT</b>
<span class="title-ft">
企业
<p class="red-title-ft">
简介
</p>
</span>
<span class="en-title-ft">
COMPANY PROFILE
</span>
<span class="p1">
<p>
浙江好运徕品牌运营管理有限公司座落于美丽的杭州市滨江区是一家以互联网技术为核心集科贸于一体的综合性电商企业业务范围涵盖软件系统开发技术咨询大数据服务品牌运营管理市场营销策划产品供应链线下实体商家拓客引流解决方案等领域公司拥有国内领先的技术团队和一流的运营管理团队本着科学创新无私奉献服务社会造福于民的企业宗旨共创共享共赢的经营理念以及利他感恩有爱的核心价值观
</p>
<p>
公司历时多年调研倾力开发出一个全新的数字电商平台<b>好运徕数字生活</b>该平台拥有优越于传统电商平台的商业逻辑能够很好地赋能百业实体帮助商家进行数字化转型升级解决当下全国实体商家所共同面临的获客难的痛点问题继而帮助众多商家快速实现拓客增收
</p>
<p>
好运徕云平台的上线落地可以加快全国乡村振兴步伐带动再就业拉动内循环促进绿色消费实现共同富裕必将为繁荣我国实体经济注入新的活力能够真正实现为政府解忧为百姓谋福利为社会做贡献的巨大社会价值意义!
</p>
</span>
</div>
<div class="imgs">
<img src="/images/about-i1.png" alt="">
</div>
</div>
</div>
<div class="videobox">
<span class="b-font">
COMPANY VIDEO
</span>
<span class="black-ft">
企业
<p class="red-ft">
视频
</p>
</span>
<video src="/src/videos/test.mp4" controls loop="false" disablepictureinpicture controlslist="nodownload"
style="width: 960px;border: solid 11px #000;border-radius: 6px;cursor: pointer;"></video>
</div>
<div class="develop">
<span class="b-font">
DEVELOPMENT STRATEGY
</span>
<span class="black-ft">
发展
<p class="red-ft">
规划
</p>
</span>
<div class="d-imgs">
<img src="/images/develop-i1.png" alt="">
<hr>
<img src="/images/develop-i2.png" alt="">
<hr>
<img src="/images/develop-i3.png" alt="">
</div>
<div class="d-fonts">
<div class="ftbox">
<b>数字电商板块布局</b>
<span>
依托数字电商平台快速实现公司的三个宏伟目标:庞大的用户数据(超6亿的粉丝量)完善的渠道建设(全国每个城市都有服务商)平台及公司的品牌塑造
</span>
</div>
<div class="ftbox">
<b>落地千城万店计划</b>
<span>
在全国每个城市都落地以大健康产业和民生产业为主的品牌连锁计划惠及平台全国数亿会员的同时还能帮我们的党和国家政府解决诸多社会问题
</span>
</div>
<div class="ftbox">
<b>大力发展公益事业</b>
<span>
成立慈善基金会和自己品牌旗下的公益基金在全国各地捐建养老社区和希望小学以及其它惠民工程打造最受人民欢迎和社会尊敬的民族企业
</span>
</div>
</div>
<div class="botm">
<div class="widbox">
<div class="btm-ft">
<span class="b-ft">2983</span>
<span class="s-ft">运营中心</span>
</div>
<div class="btm-ft">
<span class="b-ft">31W+</span>
<span class="s-ft">全国推广大使</span>
</div>
<div class="btm-ft">
<span class="b-ft">300W+</span>
<span class="s-ft">优质商家入驻</span>
</div>
<div class="btm-ft">
<span class="b-ft">3亿+</span>
<span class="s-ft">粉丝用户</span>
</div>
</div>
</div>
</div>
<div class="culture">
<span class="b-font">
CORPORATE CULTURE
</span>
<span class="black-ft">
企业
<p class="red-ft">
文化
</p>
</span>
<div class="cul-imgs">
<div class="cul-box" v-for="item in culture" :style="{ backgroundImage: 'url(' + item.img + ')' }">
<span class="cul-num">
{{ item.num }}
</span>
<hr>
<p>
{{ item.title }}
</p>
<span>
{{ item.content }}
<br>
{{ item.brtext }}
</span>
</div>
</div>
<div class="cul-btm">
<img src="/images/cul-i5.png" alt="">
</div>
</div>
<div class="certification">
<span class="b-font">
COMPANY QUALIFICATION
</span>
<span class="black-ft">
荣誉
<p class="red-ft">
资质
</p>
</span>
<span class="cert-ft">
公司先后被评为品牌强国·品牌创新 100 品牌强国·新质生产力企业电商行业领先品牌品牌强国·绿色消费积分创新领军品牌
2024 新时代中国最佳商业模式创新企业2024 新时代中国最具投资合作价值创业创富平台CCTV 爱心慈善企业AAA 级信用企业等荣誉称号
董事长个人先后获得品牌强国·新质生产力工匠先锋人物2024 新时代中国经济模式十大创新人物CCTV爱心慈善大使等荣誉称号
</span>
<div class="certificate">
<ArrowLeft class="arrow" @click="onlefticon" />
<div class="certimgs" id="certimgs">
<img src="/images/cert-i1.png" alt="">
<img src="/images/cert-i2.png" alt="">
<img src="/images/cert-i3.png" alt="">
<img src="/images/cert-i4.png" alt="">
<img src="/images/cert-i1.png" alt="">
<img src="/images/cert-i2.png" alt="">
<img src="/images/cert-i3.png" alt="">
<img src="/images/cert-i4.png" alt="">
</div>
<ArrowRight class="arrow" @click="onrighticon" />
</div>
</div>
<div class="office">
<span class="b-font">
OFFICE ENVIRONMENT
</span>
<span class="black-ft">
办公
<p class="red-ft">
环境
</p>
</span>
<div class="officeimgs">
<img src="/images/office-i1.png" alt="">
<div class="xbox">
<img src="/images/office-i2.png" alt="">
<div class="ybox">
<img src="/images/office-i3.png" alt="">
<img src="/images/office-i4.png" alt="">
</div>
</div>
</div>
</div>
</div>
</template>

156
src/views/Business.vue Normal file
View File

@ -0,0 +1,156 @@
<script>
import { ref } from 'vue';
export default {
setup() {
const list = ref([
{
id: 1,
title: '软件系统开发',
desc: '定制化软件开发,满足企业多样化需求,提升运营效率',
img: '/images/list-i1.png',
},
{
id: 2,
title: '技术咨询',
desc: '提供专业的技术咨询服务,助力企业解决复杂技术难题',
img: '/images/list-i2.png',
},
{
id: 3,
title: '大数据服务',
desc: '通过大数据分析与应用,驱动企业决策与业务增长',
img: '/images/list-i3.png',
},
{
id: 4,
title: '品牌运营管理',
desc: '全方位品牌策划与管理,提升品牌价值与市场影响力',
img: '/images/list-i4.png',
},
{
id: 5,
title: '市场营销策划',
desc: '定制化营销策略,帮助企业实现精准获客与业绩增长',
img: '/images/list-i5.png',
},
{
id: 6,
title: '产品供应链',
desc: '优化供应链管理,确保产品高效流通与成本控制',
img: '/images/list-i6.png',
},
])
return {
list,
};
},
methods: {
},
data() {
return {
};
}
};
</script>
<template>
<div class="business">
<div class="banner">
<img src="/images/business-banner.png" alt="">
</div>
<div class="area">
<span class="b-font">
OPERATIONAL AREA
</span>
<span class="black-ft">
业务
<p class="red-ft">
领域
</p>
</span>
<div class="list">
<div class="lbox" v-for="item in list" :key="item.id">
<img :src="item.img" alt="">
<span class="l-b-font">{{ item.title }}</span>
<span class="l-s-font">{{ item.desc }}</span>
</div>
</div>
<div class="scheme">
<div>
<p>线下实体商家拓客引流解决方案</p>
<hr>
<span>
商家通过让利活动吸引消费者消费并获得余额余额激励再次消费形成良性循环这不仅提升了客户粘性还促
使消费者回流为商家带来持续客流同时通过口碑传播吸引新客户实现引流和品牌影响力的双重提升最终达到商家与消费者的双赢
</span>
</div>
</div>
</div>
<div class="commodel">
<span class="b-font">
COMMERCIAL MODEL
</span>
<span class="black-ft">
商业
<p class="red-ft">
模式
</p>
</span>
<span class="title">
世界上最伟大的商业模式
<b>
利他
</b>
</span>
<div class="details">
<span>利他商业模式以共赢为核心通过赋能商家惠及消费者成就创业者构建了
一个多方受益的商业生态真正体现了利他即利己的核心理念
</span>
</div>
<div class="example">
<div class="ebox">
<span>01</span>
<hr>
<b>联盟商家</b>
<p>
全国数千万实体商家免费入驻赠送云拓客系统工具赋能商家精准引流快速增收
</p>
<img src="/images/e-i1.png" alt="">
</div>
<hr style="width: 1px;height: 435px;background-color: #eaeaea;border: none;">
<div class="ebox">
<span>02</span>
<hr>
<b>创业者</b>
<p>
为创业者提供低门槛高回报的创业机会帮助其快速搭建财富通道
</p>
<img src="/images/e-i2.png" alt="">
</div>
<hr style="width: 1px;height: 435px;background-color: #eaeaea;border: none;">
<div class="ebox">
<span>03</span>
<hr>
<b>消费者</b>
<p>
为全国十四亿消费者打造一个优质的消费
渠道实现自用省钱分享赚钱
</p>
<img src="/images/e-i3.png" alt="">
</div>
</div>
</div>
</div>
</template>

22
src/views/Clear.vue Normal file
View File

@ -0,0 +1,22 @@
<template>
</template>
<script>
export default {
mounted() {
setTimeout(() => {
localStorage.clear();
location.replace('#/');
}, 0);
},
data() {
return {
}
},
methods: {
}
}
</script>

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