first commit

This commit is contained in:
编码猿
2024-09-27 02:06:13 +08:00
commit 852d94fbb9
36760 changed files with 3274413 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
> 1%
last 2 versions
not dead
not ie <= 11

View File

@@ -0,0 +1,23 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View File

@@ -0,0 +1,19 @@
# hello-world
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

View File

@@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}

View File

@@ -0,0 +1,25 @@
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"baseUrl": "./",
"moduleResolution": "node",
"paths": {
"@/*": [
"src/*"
],
"@less/*": [
"src/assets/less/*"
],
"@page/*": [
"src/assets/less/page/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,31 @@
{
"name": "hello-world",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "vue-cli-service serve",
"build": "vue-cli-service build"
},
"dependencies": {
"amfe-flexible": "^2.2.1",
"axios": "^0.26.1",
"core-js": "^3.8.3",
"node-rsa": "^1.1.1",
"vant": "^2.12.47",
"vue": "^2.6.14",
"vue-router": "^3.5.1",
"vuex": "^3.5.1"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"compression-webpack-plugin": "^9.2.0",
"less": "^3.0.4",
"less-loader": "^5.0.0",
"postcss-pxtorem": "^5.1.1",
"style-resources-loader": "^1.5.0",
"uglifyjs-webpack-plugin": "^2.2.0",
"vue-template-compiler": "^2.6.11"
}
}

View File

@@ -0,0 +1,11 @@
module.exports = {
plugins: {
autoprefixer: {
browsers: ['Android >= 4.0', 'iOS >= 7'],
},
'postcss-pxtorem': {
rootValue: 37.5,
propList: ['*'],
},
},
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 703 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 983 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 522 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 646 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 952 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 910 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 865 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %>
<link rel="stylesheet" href="<%= htmlWebpackPlugin.options.cdn.css[i] %>">
<% } %>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
<script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
<% } %>
</body>
</html>

View File

@@ -0,0 +1,13 @@
<template>
<div id="app">
<keep-alive >
<router-view v-if="$route.meta.keepAlive" :key="$route.fullPath"/>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" :key="$route.fullPath"/>
</div>
</template>
<style lang="less">
@import "~@less/config/normalize";
@import "~@less/mixins/restUI";
</style>

View File

@@ -0,0 +1,2 @@
@import "./config/color";
@import "./mixins/mixins";

View File

@@ -0,0 +1,305 @@
@theme: #998cf5;
@red50: #ffebee;
@red100: #ffcdd2;
@red200: #ef9a9a;
@red300: #e57373;
@red400: #ef5350;
@red500: #f44336;
@red600: #e53935;
@red700: #d32f2f;
@red800: #c62828;
@red900: #b71c1c;
@redA100: #ff8a80;
@redA200: #ff5252;
@redA400: #ff1744;
@redA700: #d50000;
@red: @red500;
@pink50: #fce4ec;
@pink100: #f8bbd0;
@pink200: #f48fb1;
@pink300: #f06292;
@pink400: #ec407a;
@pink500: #e91e63;
@pink600: #d81b60;
@pink700: #c2185b;
@pink800: #ad1457;
@pink900: #880e4f;
@pinkA100: #ff80ab;
@pinkA200: #ff4081;
@pinkA400: #f50057;
@pinkA700: #c51162;
@pink: @pink500;
@purple50: #f3e5f5;
@purple100: #e1bee7;
@purple200: #ce93d8;
@purple300: #ba68c8;
@purple400: #ab47bc;
@purple500: #9c27b0;
@purple600: #8e24aa;
@purple700: #7b1fa2;
@purple800: #6a1b9a;
@purple900: #4a148c;
@purpleA100: #ea80fc;
@purpleA200: #e040fb;
@purpleA400: #d500f9;
@purpleA700: #aa00ff;
@purple: @purple500;
@deepPurple50: #ede7f6;
@deepPurple100: #d1c4e9;
@deepPurple200: #b39ddb;
@deepPurple300: #9575cd;
@deepPurple400: #7e57c2;
@deepPurple500: #673ab7;
@deepPurple600: #5e35b1;
@deepPurple700: #512da8;
@deepPurple800: #4527a0;
@deepPurple900: #311b92;
@deepPurpleA100: #b388ff;
@deepPurpleA200: #7c4dff;
@deepPurpleA400: #651fff;
@deepPurpleA700: #6200ea;
@deepPurple: @deepPurple500;
@indigo50: #e8eaf6;
@indigo100: #c5cae9;
@indigo200: #9fa8da;
@indigo300: #7986cb;
@indigo400: #5c6bc0;
@indigo500: #3f51b5;
@indigo600: #3949ab;
@indigo700: #303f9f;
@indigo800: #283593;
@indigo900: #1a237e;
@indigoA100: #8c9eff;
@indigoA200: #536dfe;
@indigoA400: #3d5afe;
@indigoA700: #304ffe;
@indigo: @indigo500;
@blue50: #e3f2fd;
@blue100: #bbdefb;
@blue200: #90caf9;
@blue300: #64b5f6;
@blue400: #42a5f5;
@blue500: #2196f3;
@blue600: #1e88e5;
@blue700: #1976d2;
@blue800: #1565c0;
@blue900: #0d47a1;
@blueA100: #82b1ff;
@blueA200: #448aff;
@blueA400: #2979ff;
@blueA700: #2962ff;
@blue: @blue500;
@lightBlue50: #e1f5fe;
@lightBlue100: #b3e5fc;
@lightBlue200: #81d4fa;
@lightBlue300: #4fc3f7;
@lightBlue400: #29b6f6;
@lightBlue500: #03a9f4;
@lightBlue600: #039be5;
@lightBlue700: #0288d1;
@lightBlue800: #0277bd;
@lightBlue900: #01579b;
@lightBlueA100: #80d8ff;
@lightBlueA200: #40c4ff;
@lightBlueA400: #00b0ff;
@lightBlueA700: #0091ea;
@lightBlue: @lightBlue500;
@cyan50: #e0f7fa;
@cyan100: #b2ebf2;
@cyan200: #80deea;
@cyan300: #4dd0e1;
@cyan400: #26c6da;
@cyan500: #00bcd4;
@cyan600: #00acc1;
@cyan700: #0097a7;
@cyan800: #00838f;
@cyan900: #006064;
@cyanA100: #84ffff;
@cyanA200: #18ffff;
@cyanA400: #00e5ff;
@cyanA700: #00b8d4;
@cyan: @cyan500;
@teal50: #e0f2f1;
@teal100: #b2dfdb;
@teal200: #80cbc4;
@teal300: #4db6ac;
@teal400: #26a69a;
@teal500: #009688;
@teal600: #00897b;
@teal700: #00796b;
@teal800: #00695c;
@teal900: #004d40;
@tealA100: #a7ffeb;
@tealA200: #64ffda;
@tealA400: #1de9b6;
@tealA700: #00bfa5;
@teal: @teal500;
@green50: #e8f5e9;
@green100: #c8e6c9;
@green200: #a5d6a7;
@green300: #81c784;
@green400: #66bb6a;
@green500: #4caf50;
@green600: #43a047;
@green700: #388e3c;
@green800: #2e7d32;
@green900: #1b5e20;
@greenA100: #b9f6ca;
@greenA200: #69f0ae;
@greenA400: #00e676;
@greenA700: #00c853;
@green: @green500;
@lightGreen50: #f1f8e9;
@lightGreen100: #dcedc8;
@lightGreen200: #c5e1a5;
@lightGreen300: #aed581;
@lightGreen400: #9ccc65;
@lightGreen500: #8bc34a;
@lightGreen600: #7cb342;
@lightGreen700: #689f38;
@lightGreen800: #558b2f;
@lightGreen900: #33691e;
@lightGreenA100: #ccff90;
@lightGreenA200: #b2ff59;
@lightGreenA400: #76ff03;
@lightGreenA700: #64dd17;
@lightGreen: @lightGreen500;
@lime50: #f9fbe7;
@lime100: #f0f4c3;
@lime200: #e6ee9c;
@lime300: #dce775;
@lime400: #d4e157;
@lime500: #cddc39;
@lime600: #c0ca33;
@lime700: #afb42b;
@lime800: #9e9d24;
@lime900: #827717;
@limeA100: #f4ff81;
@limeA200: #eeff41;
@limeA400: #c6ff00;
@limeA700: #aeea00;
@lime: @lime500;
@yellow50: #fffde7;
@yellow100: #fff9c4;
@yellow200: #fff59d;
@yellow300: #fff176;
@yellow400: #ffee58;
@yellow500: #ffeb3b;
@yellow600: #fdd835;
@yellow700: #fbc02d;
@yellow800: #f9a825;
@yellow900: #f57f17;
@yellowA100: #ffff8d;
@yellowA200: #ffff00;
@yellowA400: #ffea00;
@yellowA700: #ffd600;
@yellow: @yellow500;
@amber50: #fff8e1;
@amber100: #ffecb3;
@amber200: #ffe082;
@amber300: #ffd54f;
@amber400: #ffca28;
@amber500: #ffc107;
@amber600: #ffb300;
@amber700: #ffa000;
@amber800: #ff8f00;
@amber900: #ff6f00;
@amberA100: #ffe57f;
@amberA200: #ffd740;
@amberA400: #ffc400;
@amberA700: #ffab00;
@amber: @amber500;
@orange50: #fff3e0;
@orange100: #ffe0b2;
@orange200: #ffcc80;
@orange300: #ffb74d;
@orange400: #ffa726;
@orange500: #ff9800;
@orange600: #fb8c00;
@orange700: #f57c00;
@orange800: #ef6c00;
@orange900: #e65100;
@orangeA100: #ffd180;
@orangeA200: #ffab40;
@orangeA400: #ff9100;
@orangeA700: #ff6d00;
@orange: @orange500;
@deepOrange50: #fbe9e7;
@deepOrange100: #ffccbc;
@deepOrange200: #ffab91;
@deepOrange300: #ff8a65;
@deepOrange400: #ff7043;
@deepOrange500: #ff5722;
@deepOrange600: #f4511e;
@deepOrange700: #e64a19;
@deepOrange800: #d84315;
@deepOrange900: #bf360c;
@deepOrangeA100: #ff9e80;
@deepOrangeA200: #ff6e40;
@deepOrangeA400: #ff3d00;
@deepOrangeA700: #dd2c00;
@deepOrange: @deepOrange500;
@brown50: #efebe9;
@brown100: #d7ccc8;
@brown200: #bcaaa4;
@brown300: #a1887f;
@brown400: #8d6e63;
@brown500: #795548;
@brown600: #6d4c41;
@brown700: #5d4037;
@brown800: #4e342e;
@brown900: #3e2723;
@brown: @brown500;
@blueGrey50: #eceff1;
@blueGrey100: #cfd8dc;
@blueGrey200: #b0bec5;
@blueGrey300: #90a4ae;
@blueGrey400: #78909c;
@blueGrey500: #607d8b;
@blueGrey600: #546e7a;
@blueGrey700: #455a64;
@blueGrey800: #37474f;
@blueGrey900: #263238;
@blueGrey: @blueGrey500;
@grey50: #fafafa;
@grey100: #f5f5f5;
@grey200: #eeeeee;
@grey300: #e0e0e0;
@grey400: #bdbdbd;
@grey500: #9e9e9e;
@grey600: #757575;
@grey700: #616161;
@grey800: #424242;
@grey900: #212121;
@grey: @grey500;
@black: #000000;
@white: #ffffff;
@transparent: rgba(0, 0, 0, 0);
@fullBlack: rgba(0, 0, 0, 1);
@darkBlack: rgba(0, 0, 0, 0.87);
@lightBlack: rgba(0, 0, 0, 0.54);
@minBlack: rgba(0, 0, 0, 0.26);
@faintBlack: rgba(0, 0, 0, 0.12);
@fullWhite: rgba(255, 255, 255, 1);
@darkWhite: rgba(255, 255, 255, 0.87);
@lightWhite: rgba(255, 255, 255, 0.54);

View File

@@ -0,0 +1,432 @@
/*! normalize.css v4.1.1 | MIT License | github.com/necolas/normalize.css */
/**
* 1. Change the default font family in all browsers (opinionated).
* 2. Prevent adjustments of font size after orientation changes in IE and iOS.
*/
html {
font-family: sans-serif; /* 1 */
-ms-text-size-adjust: 100%; /* 2 */
-webkit-text-size-adjust: 100%; /* 2 */
}
/**
* Remove the margin in all browsers (opinionated).
*/
body,ul,li,p,h1,h2,h3,h4,h5,h6 {
margin: 0;
padding: 0;
list-style: none;
}
img {
width: 100%;
}
body {
//font-size: 0 !important;
}
/* HTML5 display definitions
========================================================================== */
/**
* Add the correct display in IE 9-.
* 1. Add the correct display in Edge, IE, and Firefox.
* 2. Add the correct display in IE.
*/
article,
aside,
details, /* 1 */
figcaption,
figure,
footer,
header,
main, /* 2 */
menu,
nav,
section,
summary { /* 1 */
display: block;
}
/**
* Add the correct display in IE 9-.
*/
audio,
canvas,
progress,
video {
display: inline-block;
}
/**
* Add the correct display in iOS 4-7.
*/
audio:not([controls]) {
display: none;
height: 0;
}
/**
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
*/
progress {
vertical-align: baseline;
}
/**
* Add the correct display in IE 10-.
* 1. Add the correct display in IE.
*/
template, /* 1 */
[hidden] {
display: none;
}
/* Links
========================================================================== */
/**
* 1. Remove the gray background on active links in IE 10.
* 2. Remove gaps in links underline in iOS 8+ and Safari 8+.
*/
a {
background-color: transparent; /* 1 */
-webkit-text-decoration-skip: objects; /* 2 */
text-decoration: none;
}
/**
* Remove the outline on focused links when they are also active or hovered
* in all browsers (opinionated).
*/
a:active,
a:hover {
outline-width: 0;
}
/* Text-level semantics
========================================================================== */
/**
* 1. Remove the bottom border in Firefox 39-.
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
*/
abbr[title] {
border-bottom: none; /* 1 */
text-decoration: underline; /* 2 */
text-decoration: underline dotted; /* 2 */
}
/**
* Prevent the duplicate application of `bolder` by the next rule in Safari 6.
*/
b,
strong {
font-weight: inherit;
}
/**
* Add the correct font weight in Chrome, Edge, and Safari.
*/
b,
strong {
font-weight: bolder;
}
/**
* Add the correct font style in Android 4.3-.
*/
dfn {
font-style: italic;
}
/**
* Correct the font size and margin on `h1` elements within `section` and
* `article` contexts in Chrome, Firefox, and Safari.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
/**
* Add the correct background and color in IE 9-.
*/
mark {
background-color: #ff0;
color: #000;
}
/**
* Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/**
* Prevent `sub` and `sup` elements from affecting the line height in
* all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/* Embedded content
========================================================================== */
/**
* Remove the border on images inside links in IE 10-.
*/
img {
border-style: none;
}
/**
* Hide the overflow in IE.
*/
svg:not(:root) {
overflow: hidden;
}
/* Grouping content
========================================================================== */
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
pre,
samp {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/**
* Add the correct margin in IE 8.
*/
figure {
margin: 1em 40px;
}
/**
* 1. Add the correct box sizing in Firefox.
* 2. Show the overflow in Edge and IE.
*/
hr {
box-sizing: content-box; /* 1 */
height: 0; /* 1 */
overflow: visible; /* 2 */
}
/* Forms
========================================================================== */
/**
* 1. Change font properties to `inherit` in all browsers (opinionated).
* 2. Remove the margin in Firefox and Safari.
*/
button,
input,
select,
textarea {
font: inherit; /* 1 */
margin: 0; /* 2 */
outline: none;
border: none;
}
/**
* Restore the font weight unset by the previous rule.
*/
optgroup {
font-weight: bold;
}
/**
* Show the overflow in IE.
* 1. Show the overflow in Edge.
*/
button,
input { /* 1 */
overflow: visible;
}
/**
* Remove the inheritance of text transform in Edge, Firefox, and IE.
* 1. Remove the inheritance of text transform in Firefox.
*/
button,
select { /* 1 */
text-transform: none;
}
/**
* 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
* controls in Android 4.
* 2. Correct the inability to style clickable types in iOS and Safari.
*/
button,
html [type="button"], /* 1 */
[type="reset"],
[type="submit"] {
-webkit-appearance: button; /* 2 */
}
/**
* Remove the inner border and padding in Firefox.
*/
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
/**
* Restore the focus styles unset by the previous rule.
*/
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
}
/**
* Change the border, margin, and padding in all browsers (opinionated).
*/
fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
}
/**
* 1. Correct the text wrapping in Edge and IE.
* 2. Correct the color inheritance from `fieldset` elements in IE.
* 3. Remove the padding so developers are not caught out when they zero out
* `fieldset` elements in all browsers.
*/
legend {
box-sizing: border-box; /* 1 */
color: inherit; /* 2 */
display: table; /* 1 */
max-width: 100%; /* 1 */
padding: 0; /* 3 */
white-space: normal; /* 1 */
}
/**
* Remove the default vertical scrollbar in IE.
*/
textarea {
overflow: auto;
}
/**
* 1. Add the correct box sizing in IE 10-.
* 2. Remove the padding in IE 10-.
*/
[type="checkbox"],
[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/**
* Correct the cursor style of increment and decrement buttons in Chrome.
*/
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
/**
* 1. Correct the odd appearance in Chrome and Safari.
* 2. Correct the outline style in Safari.
*/
[type="search"] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}
/**
* Remove the inner padding and cancel buttons in Chrome and Safari on OS X.
*/
[type="search"]::-webkit-search-cancel-button,
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* Correct the text style of placeholders in Chrome, Edge, and Safari.
*/
::-webkit-input-placeholder {
color: inherit;
opacity: 0.54;
}
/**
* 1. Correct the inability to style clickable types in iOS and Safari.
* 2. Change font properties to `inherit` in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}

View File

@@ -0,0 +1,313 @@
.padd(@d:15px) {
padding: 0 @d;
}
.transition(@d) {
-webkit-transition-duration: @d;
transition-duration: @d;
}
.delay(@d) {
-webkit-transition-delay: @d;
transition-delay: @d;
}
.transform(@t) {
-webkit-transform: @t;
transform: @t;
}
.transform-origin(@to) {
-webkit-transform-origin: @to;
transform-origin: @to;
}
.translate3d(@x:0, @y:0, @z:0) {
-webkit-transform: translate3d(@x,@y,@z);
transform: translate3d(@x,@y,@z);
}
.animation (@a) {
-webkit-animation: @a;
animation: @a;
}
.scrollable() {
overflow: auto;
-webkit-overflow-scrolling: touch;
}
.flex-shrink(@fs) {
-webkit-box-flex: @fs;
-webkit-flex-shrink: @fs;
-ms-flex: 0 @fs auto;
flex-shrink: @fs;
}
.clearfix() {
&:after,
&:before {
content: " ";
display: table;
}
&:after {
clear: both;
}
}
.hairline(@position, @color) when (@position = top) {
&:before {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: auto;
right: auto;
height: 1px;
width: 100%;
background-color: @color;
display: block;
z-index: 15;
// .transform-origin(50% 0%);
html.pixel-ratio-2 & {
.transform(scaleY(0.5));
}
html.pixel-ratio-3 & {
.transform(scaleY(0.33));
}
}
}
.hairline(@position, @color) when (@position = left) {
&:before {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: auto;
right: auto;
width: 1px;
height: 100%;
background-color: @color;
display: block;
z-index: 15;
// .transform-origin(0% 50%);
html.pixel-ratio-2 & {
.transform(scaleX(0.5));
}
html.pixel-ratio-3 & {
.transform(scaleX(0.33));
}
}
}
.hairline(@position, @color) when (@position = bottom) {
&:after {
content: '';
position: absolute;
left: 0;
bottom: 0;
right: auto;
top: auto;
height: 1px;
width: 100%;
background-color: @color;
display: block;
z-index: 15;
html.pixel-ratio-2 & {
.transform(scaleY(0.5));
}
html.pixel-ratio-3 & {
.transform(scaleY(0.33));
}
}
}
.hairline(@position, @color) when (@position = right) {
&:after {
content: '';
position: absolute;
right: 0;
top: 0;
left: auto;
bottom: auto;
width: 1px;
height: 100%;
background-color: @color;
display: block;
z-index: 15;
// .transform-origin(100% 50%);
html.pixel-ratio-2 & {
.transform(scaleX(0.5));
}
html.pixel-ratio-3 & {
.transform(scaleX(0.33));
}
}
}
// For right and bottom
.hairline-remove(@position) when not (@position = left) and not (@position = top) {
&:after {
display: none;
}
}
// For left and top
.hairline-remove(@position) when not (@position = right) and not (@position = bottom) {
&:before {
display: none;
}
}
// For right and bottom
.hairline-color(@position, @color) when not (@position = left) and not (@position = top) {
&:after {
background-color: @color;
}
}
// For left and top
.hairline-color(@position, @color) when not (@position = right) and not (@position = bottom) {
&:before {
background-color: @color;
}
}
// Encoded SVG Background
.encoded-svg-background(@svg) {
@url: `encodeURIComponent(@{svg})`;
background-image: url("data:image/svg+xml;charset=utf-8,@{url}");
}
// Preserve3D
.preserve3d() {
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-ms-transform-style: preserve-3d;
transform-style: preserve-3d;
}
// Shadow
.depth(@level:1) {
& when (@level = 0) {
box-shadow: none;
}
& when (@level = 1) {
box-shadow: 0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);
}
& when (@level = 2) {
box-shadow: 0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12);
}
& when (@level = 3) {
box-shadow: 0 3px 3px -2px rgba(0,0,0,.2),0 3px 4px 0 rgba(0,0,0,.14),0 1px 8px 0 rgba(0,0,0,.12);
}
& when (@level = 4) {
box-shadow: 0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12);
}
& when (@level = 5) {
box-shadow: 0 3px 5px -1px rgba(0,0,0,.2),0 5px 8px 0 rgba(0,0,0,.14),0 1px 14px 0 rgba(0,0,0,.12);
}
& when (@level = 6) {
box-shadow: 0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12);
}
& when (@level = 7) {
box-shadow: 0 4px 5px -2px rgba(0,0,0,.2),0 7px 10px 1px rgba(0,0,0,.14),0 2px 16px 1px rgba(0,0,0,.12);
}
& when (@level = 8) {
box-shadow: 0 5px 5px -3px rgba(0,0,0,.2),0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12);
}
& when (@level = 9) {
box-shadow: 0 5px 6px -3px rgba(0,0,0,.2),0 9px 12px 1px rgba(0,0,0,.14),0 3px 16px 2px rgba(0,0,0,.12);
}
& when (@level = 10) {
box-shadow: 0 6px 6px -3px rgba(0,0,0,.2),0 10px 14px 1px rgba(0,0,0,.14),0 4px 18px 3px rgba(0,0,0,.12);
}
& when (@level = 11) {
box-shadow: 0 6px 7px -4px rgba(0,0,0,.2),0 11px 15px 1px rgba(0,0,0,.14),0 4px 20px 3px rgba(0,0,0,.12);
}
& when (@level = 12) {
box-shadow: 0 7px 8px -4px rgba(0,0,0,.2),0 12px 17px 2px rgba(0,0,0,.14),0 5px 22px 4px rgba(0,0,0,.12);
}
& when (@level = 13) {
box-shadow: 0 7px 8px -4px rgba(0,0,0,.2),0 13px 19px 2px rgba(0,0,0,.14),0 5px 24px 4px rgba(0,0,0,.12);
}
& when (@level = 14) {
box-shadow: 0 7px 9px -4px rgba(0,0,0,.2),0 14px 21px 2px rgba(0,0,0,.14),0 5px 26px 4px rgba(0,0,0,.12);
}
& when (@level = 15) {
box-shadow: 0 8px 9px -5px rgba(0,0,0,.2),0 15px 22px 2px rgba(0,0,0,.14),0 6px 28px 5px rgba(0,0,0,.12);
}
& when (@level = 16) {
box-shadow: 0 8px 10px -5px rgba(0,0,0,.2),0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12);
}
& when (@level = 17) {
box-shadow: 0 8px 11px -5px rgba(0,0,0,.2),0 17px 26px 2px rgba(0,0,0,.14),0 6px 32px 5px rgba(0,0,0,.12);
}
& when (@level = 18) {
box-shadow: 0 9px 11px -5px rgba(0,0,0,.2),0 18px 28px 2px rgba(0,0,0,.14),0 7px 34px 6px rgba(0,0,0,.12);
}
& when (@level = 19) {
box-shadow: 0 9px 12px -6px rgba(0,0,0,.2),0 19px 29px 2px rgba(0,0,0,.14),0 7px 36px 6px rgba(0,0,0,.12);
}
& when (@level = 20) {
box-shadow: 0 10px 13px -6px rgba(0,0,0,.2),0 20px 31px 3px rgba(0,0,0,.14),0 8px 38px 7px rgba(0,0,0,.12);
}
& when (@level = 21) {
box-shadow: 0 10px 13px -6px rgba(0,0,0,.2),0 21px 33px 3px rgba(0,0,0,.14),0 8px 40px 7px rgba(0,0,0,.12);
}
& when (@level = 22) {
box-shadow: 0 10px 14px -6px rgba(0,0,0,.2),0 22px 35px 3px rgba(0,0,0,.14),0 8px 42px 7px rgba(0,0,0,.12);
}
& when (@level = 23) {
box-shadow: 0 11px 14px -7px rgba(0,0,0,.2),0 23px 36px 3px rgba(0,0,0,.14),0 9px 44px 8px rgba(0,0,0,.12);
}
& when (@level = 24) {
box-shadow: 0 11px 15px -7px rgba(0,0,0,.2),0 24px 38px 3px rgba(0,0,0,.14),0 9px 46px 8px rgba(0,0,0,.12);
}
// & when (@level = 1) {
// box-shadow: rgba(0, 0, 0, 0.117647) 0px 1px 6px, rgba(0, 0, 0, 0.117647) 0px 1px 4px;
// }
// & when (@level = 2) {
// box-shadow: rgba(0, 0, 0, 0.156863) 0px 3px 10px, rgba(0, 0, 0, 0.227451) 0px 3px 10px;
// }
// & when (@level = 3) {
// box-shadow: rgba(0, 0, 0, 0.188235) 0px 10px 30px, rgba(0, 0, 0, 0.227451) 0px 6px 10px;
// }
// & when (@level = 4) {
// box-shadow: rgba(0, 0, 0, 0.247059) 0px 14px 45px, rgba(0, 0, 0, 0.219608) 0px 10px 18px;
// }
// & when (@level = 5) {
// box-shadow: rgba(0, 0, 0, 0.298039) 0px 19px 60px, rgba(0, 0, 0, 0.219608) 0px 15px 20px;
// }
}
// Highlighted Links
.active-highlight(@color:rgba(255, 255, 255, 0.15)){
&:before {
content: '';
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
background-color: @color;
background-repeat: no-repeat;
background-position: center;
background-size: 100% 100%;
opacity: 0;
pointer-events: none;
.transition(600ms);
}
&.active-state:before,
html:not(.watch-active-state) &:active:before {
opacity: 1;
.transition(150ms);
}
}
.active-highlight-color(@color) {
&:before {
background-image: -webkit-radial-gradient(center, circle cover, @color 66%, rgba(red(@color),green(@color),blue(@color),0) 66%);
background-image: radial-gradient(circle at center, @color 66%, rgba(red(@color),green(@color),blue(@color),0) 66%);
}
}
// No Scrollbar
.no-scrollbar() {
&::-webkit-scrollbar {
display: none !important;
width: 0 !important;
height: 0 !important;
-webkit-appearance: none;
opacity: 0 !important;
}
}
.ellipsis() {
white-space:nowrap;
text-overflow:ellipsis;
overflow:hidden;
word-wrap: break-word;
}

View File

@@ -0,0 +1,111 @@
.account {
.welcome {
background: #e0edfe;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
img {
width: 92%;
}
.login_but {
width: 80%;
/* text-align: center; */
height: 40px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 25px;
font-size: 16px;
background: linear-gradient(25deg, #a1c4fc, @theme);
color: #ffff;
box-shadow: 2px 3px 6px #a1c4fc;
margin-bottom: 20px;
}
.tips {
font-size: 14px;
span {
color: @theme
}
}
}
.login_title {
.back {
height: 80px;
background:@theme;
position: relative;
margin-bottom: 50px;
.title {
position: absolute;
bottom: -18px;
width: 80px;
height: 40px;
font-size: 16px;
background: #fff;
box-shadow: 1px 1px 5px #d6d4d4;
left: 14px;
border-radius: 2px;
display: flex;
align-items: center;
justify-content: center;
}
}
.van-col {
text-align: center;
}
.tabs_title {
font-size: 16px;
}
.active {
color: @theme;
span {
position: relative;
&:after {
content: "";
position: absolute;
width: 100%;
height: 4px;
background: @theme;
bottom: -8px;
left: 0;
border-radius: 10px;
}
}
}
}
.reg {
.padd();
margin-top: 60px;
}
.login {
.padd();
margin-top: 60px;
}
.input_filed {
width: 100%;
position: relative;
.hairline(bottom, @grey200);
margin-bottom: 25px;
.tips {
font-size: 14px;
color: #8d8d8d;
margin-bottom: 10px;
}
input {
font-size: 16px;
}
}
.sub_filed {
width: 100%;
height: 45px;
border-radius: 25px;
background: linear-gradient(25deg, #a1c4fc, @theme);
box-shadow: 2px 3px 6px #a1c4fc;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 17px;
}
}

View File

@@ -0,0 +1,19 @@
.Car {
.van-submit-bar {
bottom: 50px !important;
}
.list {
margin-top: 46px;
margin-bottom: 100px;
.item {
display: flex;
align-items: center;
padding-left: 12px;
}
.van-card {
flex: 1;
width: calc(100vw - 48px);
background: #fff !important;
}
}
}

View File

@@ -0,0 +1,61 @@
.home {
.search {
display: flex;
align-items: center;
height: 45px;
.padd();
box-sizing: border-box;
position: fixed;
left: 0;
top: 0;
z-index: 99;
justify-content: space-between;
img {
width: 25px;
margin-right: 20px;
}
input {
width: 80%;
border-radius: 25px;
margin-right: 17px;
height: 30px;
background: #ffffffad;
border: 1px solid #dddddd;
}
.van-icon {
}
}
.van-grid {
img {
width: 35px;
height: 35px;
}
}
.shop_list {
.shop_item {
text-align: center;
margin-bottom: 15px;
}
.title {
font-size: 0.37333rem;
color: #000;
margin-top: 7px;
}
.desc {
color: rgba(0,0,0,0.54);
font-size: 0.32rem;
margin-top: 0.08333rem;
.ellipsis();
padding: 0 10px;
}
.price {
color: #ea625b;
font-size: 0.37333rem;
margin-top: 0.13333rem;
}
}
}

View File

@@ -0,0 +1,84 @@
.info {
.header_back {
position: fixed;
width: 100%;
left: 0;
top: 0;
right: 0;
z-index: 98;
height: 43.99px;
display: flex;
align-items: center;
.padd();
justify-content: space-between;
box-sizing: border-box;
.van-icon {
width: 30px;
height: 30px;
text-align: center;
line-height: 30px;
border-radius: 100%;
}
.default {
background: #7e7d7db8;
color: #fff;
}
.theme {
color: #000;
}
}
.text {
.padd();
.price {
margin-top: 15px;
font-size: 25px;
color: #ff6700;
font-weight: 700;
}
.title {
font-size: 16px;
color: #000;
margin-bottom: 15px;
font-weight: 700;
margin-top: 10px;
}
.desc {
font-size: 12px;
color: #000;
margin-bottom: 15px;
}
.point_desc {
padding-left: 20px;
li {
font-size: 12.5px;
color: #3c3c3c;
margin-bottom: 10px;
list-style: auto;
}
}
}
.van-contact-card {
padding: 0.42667rem 0;
&:before {
height: 0 !important;
}
}
.van-tabs {
margin-bottom: 50px;
/deep/ .van-tabs__nav {
width: 40%;
margin: 0 auto;
background: #fff0;
z-index: 99;
}
}
.noclick {
background: linear-gradient(to right,#e8e8e7,#858585) !important;
}
.hidden {
/deep/ .van-tab,
/deep/ .van-tabs__line {
display: none !important;
}
}
}

View File

@@ -0,0 +1,5 @@
.order {
.content {
margin-top: 45px;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@@ -0,0 +1,58 @@
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>

View File

@@ -0,0 +1,55 @@
<template>
<div class="Swipe">
<van-swipe ref="vanSwipe" @change="onChange"
class="my-swipe"
:autoplay="0"
indicator-color="white">
<van-swipe-item v-for="(item,index) in list" :key="index">
<slot :item="{ src: item, index: index }"></slot>
</van-swipe-item>
<template #indicator>
<div class="custom-indicator">{{ current + 1 }}/{{ list.length }}</div>
</template>
</van-swipe>
</div>
</template>
<script>
export default {
name: "Swipe",
props: {
list: {
type: Array,
default: () => []
}
},
data() {
return {
current: 0,
}
},
methods: {
onChange(index) {
this.current = index;
},
to(index) {
this.$refs.vanSwipe.swipeTo(index)
}
}
}
</script>
<style scoped lang="less">
.custom-indicator {
position: absolute;
right: 5px;
bottom: 5px;
padding: 2px 5px;
font-size: 14px;
background: rgba(0, 0, 0, 0.1);
}
</style>

View File

@@ -0,0 +1,53 @@
import Vant from 'vant'
import 'vant/lib/index.css'
import service from '../service/_'
import utils from '../utils/index'
export default {
devBaseUrl: 'http://127.0.0.1:9090', // 开发阶段地址
testBaseUrl: '', // 测试阶段地址
prodBaseUrl: 'http://www.geekhelp.cn:9090', // 上线后的地址
urlList: {
index: "/home/index", // 首页接口
add: '/user/add', // 用户注册
login: '/user/login', // 用户登录
info: '/home/info', // 详情
addCar: '/car/addCar', // 添加购物车
checkCar: '/car/checkCar', // 检查商品是否被添加购物车
getCarList: '/car/getCarList', // 获取购物车的商品数量
deleteCar: '/car/deleteCar', // 删除购物车
updateCarNum: '/car/updateCarNum', // 更新购物车数量
submitCar: '/car/submitCar', // 提交购物车到订单
buyOrder: '/order/buyOrder', // 付款后调用的,修改订单支付状态
allOrder: '/order/allOrder', // 获取所有订单
},
publicKey: `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9eo8WIbWS5Yql06imlhrW0ZXh
faivPavdULvYLIxIKyUaOwMPFrPuHqqBNGnYOpiPHAKL+zxk2j4u+6jhB6VK1SOD
ccSLxIRxd0HmSDS+hBzYRf4vKc8BLlhMrYhnLmcxCc+PJIIa4DfCZnu8FfQlu/5L
ljjpYN9kHOpHAT+xpQIDAQAB
-----END PUBLIC KEY-----`,
vuePlugins: [Vant], // vue插件
noVuePlugins: [
{name: '$http', value: service},
{name: '$utils', value: utils}
],
checkBaseUrl: function () {
switch (process.env.NODE_ENV) {
case "development":
return this.devBaseUrl;
break;
case "test":
return this.testBaseUrl;
break;
case "production":
return this.prodBaseUrl;
break;
}
}
}

View File

@@ -0,0 +1,84 @@
import axios from 'axios'
import config from '@/config/index'
import RSA from '@/utils/rsa'
import { Toast, Dialog } from 'vant';
class Http {
constructor() {
this.instance = axios.create({
baseURL: config.checkBaseUrl(),
timeout: 3000,
headers: {
"Content-Type": "application/json;charset=UTF-8"
}
});
this.interceptors()
}
async get(params) {
return await this.instance.get(params.url, {
params: params.data,
headers: Object.assign({
token: localStorage.getItem("token")
},params.headers)
})
}
async post(params) {
return await this.instance.post(params.url, {}, {
headers: Object.assign({
data: new RSA().PublicKeyEncryption(params.data),
token: localStorage.getItem("token")
},params.headers)
})
}
interceptors() {
// 添加请求拦截器
this.instance.interceptors.request.use(function (config) {
Toast.loading({
message: '加载中...',
duration: 0,
});
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
this.instance.interceptors.response.use(function (response) {
Toast.clear();
switch (response.data.status) {
case 200:
return new RSA().PublicKeyDecryption(response.data.result);
break;
case 501:
Dialog.alert({
title: '提示',
message: response.data.message,
}).then(() => {
location.href = "#/account"
});
break;
case 404:
Toast({
type: 'fail',
message: response.data.message
});
throw new Error(response.data.message)
break;
default:
break;
}
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
}
}
export default Http;

View File

@@ -0,0 +1,17 @@
import 'amfe-flexible'
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import config from './config'
Vue.config.productionTip = false
config.vuePlugins.forEach(v => Vue.use(v));
config.noVuePlugins.forEach(v => Vue.prototype[v.name] = v.value);
new Vue({
store,
router,
render: h => h(App)
}).$mount('#app')

View File

@@ -0,0 +1,145 @@
<template>
<div class="account">
<div class="welcome" v-if="type == 1">
<img src="../../public/img/welcome_login.png" alt="">
<div class="login_but" @click="type = 3">登 录</div>
<div class="tips">还没有账号?快来 <span @click="type = 2">注册</span> </div>
</div>
<div v-else>
<div class="login_title">
<div class="back">
<div class="title">{{ type == 3 ? '登 录' : '注 册' }}</div>
</div>
<van-row type="flex" justify="center">
<van-col v-for="(item,index) in tabsTitle"
:class="item.type == type ? 'active' : '' "
@click="type = item.type" span="12" class="tabs_title">
<span>{{ item.title }}</span>
</van-col>
</van-row>
</div>
<div class="reg" v-if="type == 2">
<div class="input_filed">
<div class="tips">用户名</div>
<input type="text" v-model="params.name"/>
</div>
<div class="input_filed">
<div class="tips">密码</div>
<input type="password" v-model="params.pwd"/>
</div>
<div class="input_filed">
<div class="tips">手机号</div>
<input type="number" v-model="params.phone"/>
</div>
<div class="sub_filed" @click="addUser">注 册</div>
</div>
<div class="login" v-else-if="type == 3">
<div class="input_filed">
<div class="tips">用户名</div>
<input type="text" v-model="params.name"/>
</div>
<div class="input_filed">
<div class="tips">密码</div>
<input type="password" v-model="params.pwd"/>
</div>
<div class="sub_filed" @click="loginUser">登 录</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "account",
data() {
return {
params: {
name: '',
pwd: '',
phone: ''
},
tabsTitle: [
{ title: '登 录', type: 3 },
{ title: '注 册', type: 2 },
],
type: 3, // 1 欢迎页面,2 注册,3 登录
}
},
methods: {
async addUser() {
if (this.params.name.length == 0) {
this.$toast.fail({
message: '用户名不能为空'
})
return false;
}
if (this.params.pwd.length == 0) {
this.$toast.fail({
message: '密码不能为空'
})
return false;
}
if (!this.$utils.checkPhone(this.params.phone)) {
this.$toast.fail({
message: '手机号不正确'
})
return false;
}
let res = await this.$http.user.add(this.params)
this.$toast.success({
message: '恭喜,注册成功!',
onClose: () => {
this.type = 3
}
})
},
async loginUser() {
if (this.params.name.length == 0) {
this.$toast.fail({
message: '用户名不能为空'
})
return false;
}
if (this.params.pwd.length == 0) {
this.$toast.fail({
message: '密码不能为空'
})
return false;
}
let res = await this.$http.user.login(this.params)
localStorage.setItem("token", res.token);
if (this.$route.query.hasOwnProperty("from")) {
this.$router.replace({
path: this.$route.query.from
})
} else {
this.$router.replace({
path: '/home'
})
}
}
}
}
</script>
<style scoped lang="less">
@import "~@page/account.less";
</style>

View File

@@ -0,0 +1,128 @@
<template>
<div class="Car">
<van-nav-bar
title="购物车"
fixed
:right-text="status ? '管理' : '完成'"
left-arrow
@click-left="$router.back()"
@click-right="status = !status"
/>
<div class="list">
<van-checkbox-group v-model="YouSelectCar" ref="checkboxGroup" @change="changeSelect">
<div class="item" v-for="(item,index) in getCarArr" :key="index">
<van-checkbox :name="item.car_id"></van-checkbox>
<van-card
:price="item.wares_nowprice"
:desc="item.wares_info"
:title="item.wares_title"
:thumb="item.wares_masterimg[0]">
<template #num>
<van-stepper :name="item.car_id" v-model="item.car_num" @change="numChange"/>
</template>
</van-card>
</div>
</van-checkbox-group>
</div>
<van-submit-bar :price="totalMoney">
<template #button>
<van-button v-if="status" type="danger" round @click="saveOrder"> 结 算 </van-button>
<van-button v-else type="warning" round @click="deleteCar"> 删 除 </van-button>
</template>
<van-checkbox v-model="isChecked" @click="checkAll">全选</van-checkbox>
</van-submit-bar>
</div>
</template>
<script>
import { mapGetters, mapMutations, mapActions } from 'vuex'
export default {
name: "Car",
data() {
return {
status: true,
YouSelectCar: [], // 你选中的购物车商品的集合
isChecked: false
}
},
async created() {
if (this.getCarArr.length == 0) {
await this.getCarList()
}
},
methods: {
...mapMutations([
'setOrderList'
]),
saveOrder() {
let order = []
this.getCarArr.forEach(v => {
this.YouSelectCar.forEach(j => {
if (v.car_id == j) {
order.push(v)
}
})
});
this.setOrderList(order)
this.$router.push('/order')
},
async numChange(nums, { name }) {
await this.$http.car.updateCarNum({
carid: name,
quantity: nums
})
},
async deleteCar() {
await this.$http.car.deleteCar({
carid: this.YouSelectCar
})
setTimeout(async ()=> await this.getCarList(), 300)
},
checkAll() {
if (this.isChecked) {
this.$refs.checkboxGroup.toggleAll(true);
} else {
this.$refs.checkboxGroup.toggleAll();
}
},
changeSelect(checked) {
if (this.getCarArr.length == this.YouSelectCar.length) {
this.isChecked = true
} else {
this.isChecked = false
}
},
...mapActions([
'getCarList'
]),
},
computed: {
totalMoney() {
let money = 0;
this.getCarArr.forEach(v => {
this.YouSelectCar.forEach(j => {
if (v.car_id == j) {
money += v.car_num * v.wares_nowprice
}
})
})
return money * 100
},
...mapGetters([
'getCarArr'
])
},
}
</script>
<style scoped lang="less">
@import "~@page/car.less";
</style>

View File

@@ -0,0 +1,105 @@
<template>
<div class="home">
<div class="search">
<img src="../../public/img/logo.png" alt="">
<input type="text" placeholder="" >
<van-icon name="friends-o" color="#fff"/>
</div>
<van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
<van-swipe-item>
<img src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/102902bca7a9ccba097cc07d8b9dd65e.png?thumb=1&w=720&h=360" alt="">
</van-swipe-item>
<van-swipe-item>
<img src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/3b88e01cd560ff4fc2ec5b54dc81d630.jpg?thumb=1&w=720&h=360" alt="">
</van-swipe-item>
</van-swipe>
<van-grid :border="false">
<van-grid-item text="限时白嫖">
<template #icon>
<img src="../../public/img/type_1.png" />
</template>
</van-grid-item>
<van-grid-item text="新品推荐">
<template #icon>
<img src="../../public/img/type_2.png" />
</template>
</van-grid-item>
<van-grid-item text="低价高配">
<template #icon>
<img src="../../public/img/type_3.png" />
</template>
</van-grid-item>
<van-grid-item text="超值特卖">
<template #icon>
<img src="../../public/img/type_4.png" />
</template>
</van-grid-item>
</van-grid>
<van-row>
<van-col span="12">
<img src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/16305100fd7913dd727e8906b97e8998.png?f=webp&w=537&h=762&bg=DDE2E6" alt="">
</van-col>
<van-col span="12">
<van-row>
<van-col span="24">
<img src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/f8a28a90c3c449ba422a10e40085d2e9.png?f=webp&w=537&h=378&bg=DBDEEF" alt="">
</van-col>
<van-col span="24">
<img src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/200a6f45d1ccbf7d8fd92f4bbe2842d4.jpeg?f=webp&w=537&h=378&bg=F3E7E7" alt="">
</van-col>
</van-row>
</van-col>
</van-row>
<van-row>
<van-col span="24">
<img src="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/051b383d45f1fad5aa3bfae8851af7c4.png?f=webp&w=1080&h=660&bg=FFFFFF" alt="">
</van-col>
</van-row>
<van-row class="shop_list" gutter="5">
<van-col class="shop_item" span="12" v-for="(item,index) in list" :key="index">
<router-link :to="{ name: 'info', query: { id: item.wares_id } }">
<img :src="item.wares_masterimg[0]" alt="">
<div class="title">{{ item.wares_title }}</div>
<div class="desc">{{ item.wares_info }}</div>
<div class="price">{{ item.wares_nowprice }}</div>
</router-link>
</van-col>
</van-row>
</div>
</template>
<script>
export default {
name: 'HomeView',
data() {
return {
list: []
}
},
created() {
this.getIndex()
},
methods: {
async getIndex() {
let res = await this.$http.index.home();
this.list = res;
console.log(res)
}
}
}
</script>
<style scoped lang="less">
@import "~@page/home.less";
</style>

View File

@@ -0,0 +1,150 @@
<template>
<div class="info">
<div class="header_back" :style="{ background: `rgba(255,255,255,${opacity})` }">
<van-icon size="18" :class="isHidden ? 'default' : 'theme' " name="arrow-left" />
<van-icon size="18" :class="isHidden ? 'default' : 'theme' " name="shopping-cart-o" />
</div>
<van-tabs ref="mytab" :class=" isHidden ? 'hidden' : '' " v-model="active" scrollspy sticky>
<van-tab title="商品">
<SwipeComponents ref="mySwipe" :list="infoData.wares_masterimg">
<template #default="{ item }">
<img @click="showImgPri(item.index)" :src="item.src" alt="">
</template>
</SwipeComponents>
<div class="text">
<div class="price">¥5399</div>
<div class="title">小米12</div>
<div class="desc">「24期免息,信用卡分期至高立减500元;+99元得50W立式无线充;【全款支付套装】赠蓝牙耳机Air2 SE」</div>
<ul class="point_desc">
<li>【性能跃升】全新一代 骁龙8 移动平台</li>
<li>【性能跃升】全新一代 骁龙8 移动平台</li>
<li>【性能跃升】全新一代 骁龙8 移动平台</li>
</ul>
<van-contact-card
type="edit"
name="bmy"
tel="15155145354"
/>
</div>
</van-tab>
<van-tab title="详情">
<div class="info_img">
<img v-for="(item,index) in infoData.wares_infoimg"
:key="index"
:src="item" @click="infoPreview(index)" alt="">
</div>
</van-tab>
</van-tabs>
<van-goods-action>
<van-goods-action-icon icon="chat-o" text="收藏" dot />
<van-goods-action-icon icon="cart-o" to="/car" text="购物车" :badge="getCarArr.length" />
<van-goods-action-button :class="isAddCar ? 'noclick' : '' " type="warning" @click="isAddCar ? '' : addCar() " text="加入购物车" />
<van-goods-action-button type="danger" text="立即购买" />
</van-goods-action>
</div>
</template>
<script>
import SwipeComponents from "@/components/Swipe"
import { ImagePreview } from 'vant';
import { mapGetters, mapMutations, mapActions } from 'vuex'
export default {
name: "info",
data() {
return {
active: 0,
opacity: 0,
infoData: {},
isHidden: true,
isAddCar: true
}
},
async created() {
await this.getCarList()
this.getInfo();
this.checkCar();
},
mounted() {
window.addEventListener("scroll", this.handleScroll);
},
destroyed() {
window.removeEventListener("scroll", this.handleScroll)
},
methods: {
...mapActions([
'getCarList'
]),
...mapMutations([
'setCount'
]),
async checkCar() {
let res = await this.$http.car.checkCar({
waresid: this.$route.query.id
});
this.isAddCar = res.isAddCar
},
async addCar() {
let res = await this.$http.car.addCar({
waresid: this.$route.query.id
});
this.isAddCar = true
await this.getCarList()
},
infoPreview(index) {
ImagePreview({
images: this.infoData.wares_infoimg,
startPosition: index
});
},
showImgPri(index) {
ImagePreview({
images: this.infoData.wares_masterimg,
startPosition: index,
onChange: (index) => {
this.$refs.mySwipe.to(index)
}
});
},
handleScroll() {
const scrollTop = window.pageYOffset;
this.opacity = scrollTop / 412
// 显示tab切换
if (scrollTop >= 50) {
this.isHidden = false
this.$refs.mytab.resize()
// 隐藏tab切换
} else {
this.isHidden = true
}
},
async getInfo() {
let res = await this.$http.index.info({
id: this.$route.query.id
});
this.infoData = res;
}
},
computed: {
...mapGetters([
'getCarArr',
'getTheme'
])
},
components: {
SwipeComponents
}
}
</script>
<style scoped lang="less">
@import "~@page/info.less";
</style>

View File

@@ -0,0 +1,19 @@
<template>
<div class="Me">
Me
</div>
</template>
<script>
export default {
name: "Me",
data() {
return {}
},
methods: {}
}
</script>
<style scoped lang="less">
</style>

View File

@@ -0,0 +1,107 @@
<template>
<div class="order">
<van-nav-bar
title="确认订单"
fixed
left-arrow
@click-left="$router.back()"
/>
<div class="content">
<van-contact-card
type="edit"
name="bmy"
tel="15155145354"/>
<van-card
v-for="(item,index) in getOrderArr"
:key="index"
:num="item.car_num"
:price="item.wares_nowprice"
:desc="item.wares_info"
:title="item.wares_title"
:thumb="item.wares_masterimg[0]">
</van-card>
<van-submit-bar :price="totalMoney" button-text=" 付 款 " @submit="onSubmit" />
<van-popup v-model="show" position="bottom" :style="{ height: '60%' }">
<van-button type="default" @click="changeOrderStatus"> 付 款 </van-button>
</van-popup>
</div>
</div>
</template>
<script>
import { mapGetters, mapMutations, mapActions } from 'vuex'
export default {
name: "order",
data() {
return {
show: true
}
},
created() {
console.log(this.getOrderArr)
},
methods: {
async changeOrderStatus() {
let res = await this.$http.car.allOrder({
status: 0
});
let param = []
res.forEach(v => param.push(v.goods_id))
console.log(param)
let orderStatus = await this.$http.car.buyOrder({
goodsid: param
});
this.$toast.success({
message: '支付成功',
onClose: () => {
this.$router.replace('/status')
}
})
console.log(orderStatus)
},
async onSubmit() {
let param = []
this.getOrderArr.forEach(v => {
param.push({
waresid: v.wares_id,
goodsnum: v.car_num,
goodsprice: v.wares_nowprice,
})
})
let res = await this.$http.car.submitCar({
carList: param
});
this.show = true
console.log(res)
}
},
computed: {
totalMoney() {
let money = 0;
this.getOrderArr.forEach(v => {
money += v.car_num * v.wares_nowprice
})
return money * 100
},
...mapGetters([
'getOrderArr'
])
}
}
</script>
<style scoped lang="less">
@import "~@page/order.less";
</style>

View File

@@ -0,0 +1,17 @@
<template>
<div class="Type">Type</div>
</template>
<script>
export default {
name: "Type.vue",
data() {
return {}
},
methods: {}
}
</script>
<style scoped lang="less">
</style>

View File

@@ -0,0 +1,25 @@
<template>
<div class="layout">
<router-view/>
<van-tabbar v-model="active" route>
<van-tabbar-item icon="home-o" to="/home">首页</van-tabbar-item>
<van-tabbar-item icon="search" to="/type">分类</van-tabbar-item>
<van-tabbar-item icon="friends-o" to="/car">购物车</van-tabbar-item>
<van-tabbar-item icon="setting-o" to="/me">我的</van-tabbar-item>
</van-tabbar>
</div>
</template>
<script>
export default {
data() {
return {
active: 0,
};
},
};
</script>
<style scoped lang="less">
</style>

View File

@@ -0,0 +1,72 @@
<template>
<div class="orderStatus">
<van-nav-bar
title="我的订单"
left-arrow
@click-left="$router.back()"
/>
<van-tabs v-model="active" @change="tabsChange">
<van-tab :title="item.title" v-for="(item, index) in tabList" :key="index">
<van-card
v-for="(val,ix) in item.content"
:key="ix"
:num="val.car_num"
:price="val.wares_nowprice"
:desc="val.wares_info"
:title="val.wares_title"
:thumb="val.wares_masterimg[0]">
</van-card>
</van-tab>
</van-tabs>
</div>
</template>
<script>
export default {
name: "orderStatus",
data() {
return {
active: 0,
tabList: [
{ type: -1, title: '全部', page: 1, totalPage: 0, content: [] },
{ type: 0, title: '待付款', page: 1, totalPage: 0, content: [] },
{ type: 1, title: '待发货', page: 1, totalPage: 0, content: [] },
{ type: 2, title: '待收货', page: 1, totalPage: 0, content: [] },
{ type: 3, title: '退款/售后', page: 1, totalPage: 0, content: [] },
]
}
},
created() {
this.active = Number(this.$route.query.active) || 0
this.allOrder()
},
methods: {
tabsChange(index) {
this.active = index;
this.allOrder()
},
async allOrder() {
if (this.tabList[this.active].content.length == 0 ) {
let res = await this.$http.car.allOrder({
status: this.tabList[this.active].type
});
console.log(res)
this.tabList[this.active].content = [
...this.tabList[this.active].content,
...res
]
}
}
}
}
</script>
<style scoped lang="less">
</style>

View File

@@ -0,0 +1,111 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'layout',
component: () => import(/* webpackChunkName: "layout" */ '@/pages/layout.vue'),
redirect: '/home',
children: [
{
path: '/home',
name: 'home',
component: () => import(/* webpackChunkName: "Home" */ '@/pages/Home.vue'),
meta: {
isLogin: false,
keepAlive: true
}
},
{
path: '/type',
name: 'type',
component: () => import(/* webpackChunkName: "Type" */ '@/pages/Type.vue'),
meta: {
isLogin: false,
keepAlive: true
}
},
{
path: '/car',
name: 'car',
component: () => import(/* webpackChunkName: "Car" */ '@/pages/Car.vue'),
meta: {
isLogin: true,
keepAlive: false
}
},
{
path: '/me',
name: 'me',
component: () => import(/* webpackChunkName: "Me" */ '@/pages/Me.vue'),
meta: {
isLogin: true,
keepAlive: false
}
}
]
},
{
path: '/account',
name: 'account',
component: () => import(/* webpackChunkName: "Account" */ '@/pages/Account.vue'),
meta: {
isLogin: false,
keepAlive: false
}
},
{
path: '/info',
name: 'info',
component: () => import(/* webpackChunkName: "Info" */ '@/pages/Info.vue'),
meta: {
isLogin: false,
keepAlive: false
}
},
{
path: '/order',
name: 'order',
component: () => import(/* webpackChunkName: "Order" */ '@/pages/Order.vue'),
meta: {
isLogin: false,
keepAlive: false
}
},
{
path: '/status',
name: 'status',
component: () => import(/* webpackChunkName: "orderStatus" */ '@/pages/orderStatus.vue'),
meta: {
isLogin: false,
keepAlive: false
}
},
]
const router = new VueRouter({
routes
});
router.beforeEach((to, from, next) => {
if (to.meta.isLogin) {
if (localStorage.getItem("token") != null) {
next()
} else {
next({
path: '/account',
query: {
from: to.fullPath
}
})
}
} else {
next()
}
})
export default router

View File

@@ -0,0 +1,85 @@
import config from '@/config/index'
import http from '@/http/index'
class CarService {
async addCar(data = {}, header = {}) {
return await (new http()).post({
url: config.urlList.addCar,
data: data,
headers: header
})
}
async buyOrder(data = {}, header = {}) {
return await (new http()).post({
url: config.urlList.buyOrder,
data: data,
headers: header
})
}
async allOrder(data = {}, header = {}) {
let res = await (new http()).post({
url: config.urlList.allOrder,
data: data,
headers: header
});
if (Array.isArray(res)) {
res.forEach(v => {
v.wares_masterimg = JSON.parse(v.wares_masterimg)
});
return res
} else {
res = [];
return res;
}
}
async checkCar(data = {}, header = {}) {
return await (new http()).post({
url: config.urlList.checkCar,
data: data,
headers: header
})
}
async submitCar(data = {}, header = {}) {
return await (new http()).post({
url: config.urlList.submitCar,
data: data,
headers: header
})
}
async updateCarNum(data = {}, header = {}) {
return await (new http()).post({
url: config.urlList.updateCarNum,
data: data,
headers: header
})
}
async deleteCar(data = {}, header = {}) {
return await (new http()).post({
url: config.urlList.deleteCar,
data: data,
headers: header
})
}
async getCarList(data = {}, header = {}) {
let res = await (new http()).post({
url: config.urlList.getCarList,
data: data,
headers: header
})
res.forEach(v => {
v.wares_masterimg = JSON.parse(v.wares_masterimg)
});
return res;
}
}
export default CarService

View File

@@ -0,0 +1,32 @@
import config from '@/config/index'
import http from '@/http/index'
class IndexService {
async home(data = {}, header = {}) {
let res = await (new http()).post({
url: config.urlList.index,
data: data,
headers: header
});
res.forEach(v => {
v.wares_masterimg = JSON.parse(v.wares_masterimg)
});
return res;
}
async info(data = {}, header = {}) {
let res = await (new http()).post({
url: config.urlList.info,
data: data,
headers: header
});
res.wares_masterimg = JSON.parse(res.wares_masterimg)
res.wares_infoimg = JSON.parse(res.wares_infoimg)
return res;
}
}
export default IndexService

View File

@@ -0,0 +1,21 @@
import config from '@/config/index'
import http from '@/http/index'
class UserService {
async add(data = {}, header = {}) {
return await (new http()).post({
url: config.urlList.add,
data: data,
headers: header
})
}
async login(data = {}, header = {}) {
return await (new http()).post({
url: config.urlList.login,
data: data,
headers: header
})
}
}
export default UserService

View File

@@ -0,0 +1,9 @@
import IndexService from "@/service/IndexService"
import CarService from "@/service/CarService"
import UserService from "@/service/UserService";
export default {
index: new IndexService(),
car: new CarService(),
user: new UserService(),
}

View File

@@ -0,0 +1,6 @@
export default {
getCarArr: state => state.car.carList,
getOrderArr: state => state.car.orderList,
getTheme: state => state.setting.theme,
}

View File

@@ -0,0 +1,17 @@
import Vue from 'vue'
import Vuex from 'vuex'
import car from './modules/car'
import temp from './modules/public'
import setting from './modules/setting'
import getters from './getters'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
car,
temp,
setting
},
getters
})

View File

@@ -0,0 +1,20 @@
export default {
state: {
carList: [],
orderList: []
},
mutations: {
setCarList: (state, data) => {
state.carList = data
},
setOrderList: (state, data) => {
state.orderList = data
}
},
actions: {
async getCarList ({ commit }) {
let res = await this._vm.$http.car.getCarList();
commit('setCarList', res)
}
}
}

View File

@@ -0,0 +1,7 @@
export default {
state: {
},
mutations: {
},
}

View File

@@ -0,0 +1,8 @@
export default {
state: {
theme: 1
},
mutations: {
},
}

View File

@@ -0,0 +1,8 @@
class Utils {
checkPhone(phone) {
return /^1[3456789]\d{9}$/.test(phone)
}
}
export default new Utils();

View File

@@ -0,0 +1,20 @@
import NodeRSA from "node-rsa";
import config from "@/config/index";
class rsa {
constructor () {
this.public_key = config.publicKey
}
// 公钥加密
PublicKeyEncryption(text) {
return (new NodeRSA(this.public_key)).encrypt(JSON.stringify(text), 'base64')
}
// 公钥解密
PublicKeyDecryption(text) {
return JSON.parse((new NodeRSA(this.public_key)).decryptPublic(text, 'utf8'))
}
}
export default rsa;

View File

@@ -0,0 +1,135 @@
const path = require('path');
const CompressionPlugin = require('compression-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
let cdn = {
css: [
'https://cdn.jsdelivr.net/npm/vant@2.12/lib/index.css'
],
js: [
'https://cdn.bootcss.com/vue/2.6.10/vue.runtime.min.js',
'https://cdn.bootcss.com/vue-router/3.1.2/vue-router.min.js',
// 'https://cdn.bootcss.com/vuex/3.1.1/vuex.min.js',
'https://cdn.bootcss.com/axios/0.19.0-beta.1/axios.min.js',
'https://cdn.jsdelivr.net/npm/vant@2.12/lib/vant.min.js'
]
}
module.exports = {
publicPath: './',
productionSourceMap: false,
devServer: {
hot: false,
compress: true,
open: false,
overlay: {
errors: true,
warnings: false,
},
// proxy: {
// '/api': {
// target: 'http://115.159.153.142:9010/h5',
// changeOrigin: true,
// ws: true,
// pathRewrite: {
// '^/api': ''
// }
// }
// }
},
chainWebpack: config => {
if (process.env.NODE_ENV === 'production') {
// 生产环境下注入一个变量cdn 变量可以在html中通过htmlWebpackPlugin.options进行获取
config.plugin('html')
.tap(args => {
args[0].cdn = cdn;
return args;
})
}
// 移除 prefetch 插件
config.plugins.delete('prefetch')
config.plugins.delete('preload')
// 配置别名
config.resolve.alias
//第一个参数:别名 第二个参数:路径
.set('@',resolve('src'))
.set('@less',resolve('src/assets/less'))
.set('@page',resolve('src/assets/less/page'))
// 配置 less 的自动导入
const types = ['vue-modules', 'vue', 'normal-modules', 'normal']
types.forEach(type => addStyleResource(config.module.rule('less').oneOf(type)))
},
configureWebpack: config => {
// 正式阶段,项目打包上线的优化措施
if (process.env.NODE_ENV === 'production') {
/**
* 去除这些公共包,让webpack不打包到项目源码的js中,减小项目js体积
* 然后使用 pages 节点下的 cdn 数组里面的资源外链来引入。
*/
config.externals = {
vue: 'Vue',
'vue-router': 'VueRouter',
axios: 'axios',
Vant: 'Vant'
};
/**
* 部署阶段 代码压缩
*/
config.plugins.push(
// 生产环境自动删除console
new UglifyJsPlugin({
uglifyOptions: {
warnings: false,
compress: {
drop_debugger: true,
drop_console: true
}
},
sourceMap: false,
parallel: true
})
);
/**
* Gzip压缩
*/
return {
plugins: [new CompressionPlugin({
test: /\.js$|\.html$|\.css/, //匹配文件名
threshold: 10240, //对超过10k的数据进行压缩
deleteOriginalAssets: false //是否删除原文件
})]
}
}
}
}
function resolve(dir) {
return path.join(__dirname,dir)
}
function addStyleResource (rule) {
rule.use('style-resource')
.loader('style-resources-loader')
.options({
patterns: [
path.resolve(__dirname, './src/assets/less/_.less'),
],
})
}

View File

@@ -0,0 +1,133 @@
RSA 非对称加密
原始数据
公钥
私钥
MD5 不可逆的加密
base64 文件编码
params = {
id: 1,
page: 2,
num: 3,
time: '%$#^%&*bvjhvytfyt#$%$jn'
}
1: 先按照26个字母进行排序,然后转换成 query 参数的方式
id=1&num=3&page=2&time=%$#^%&*bvjhvytfyt#$%$jn
2:使用MD5对上一步的结果进行加密 2e156a8c7a7c3cde2a42335a7e332d58
加盐
params = {
id: 1,
page: 2,
num: 3,
sign: 2e156a8c7a7c3cde2a42335a7e332d58
}
vuex:
state 用来存储状态(变量),类似vue中的data
Getter 用来读取 state 中的变量
Mutation 用来修改 state 中的变量
Action 用来存放异步操作
支付分类:
支付宝
pc支付
1:下单接口 对商品进行下单
返回数值:
1:https://excashier.alipay.com/standard/auth.htm?payOrderId=61184b1924844771b218306664f5b91f.00
2: <form action="https://excashier.alipay.com/standard/auth.htm?payOrderId=61184b1924844771b218306664f5b91f.00">
<input type="submit">
</form>
订单号
2: 检查订单是否支付成功的接口
参数:orderNUm statu 1
2
H5支付
小程序支付
微信
pc支付
1:下单接口 对商品进行下单
返回数值:二维码的图片地址 http://www.ac.com/1.png
订单号
2:需要 使用 setInterval 调用 检查订单是否支付成功的接口
参数:订单号
返回数值:{ status: 1 }
H5支付
小程序支付 主要和 微信小程序逻辑一样
支付的时候调用 my.tradePay
银联
支付流程:
1:下单接口 对商品进行下单
参数:购物车的id构成的数组 [1,2,3,4,5]
支付类型:type 1支付宝 2微信 3余额支付
返回数值:
支付参数 var res = {
"appId": "wx2421b1c4370ec43b", //公众号ID,由商户传入
"timeStamp": "1395712654", //时间戳,自1970年以来的秒数
"nonceStr": "e61463f8efa94090b1f366cccfbbb444", //随机串
"package": "prepay_id=up_wx21201855730335ac86f8c43d1889123400",
"signType": "RSA", //微信签名方式:
"paySign": "oR9d8PuhnIc+YZ8cBHFCwfgpaK9gd7vaRvkYD7rthRAZ\/X+QBhcCYL21N7cHCTUxbQ+EAt6Uy+lwSN22f5YZvI45MLko8Pfso0jm46v5hqcVwrk6uddkGuT+Cdvu4WBqDzaDjnNa5UK3GfE1Wfl2gHxIIY5lLdUgWFts17D4WuolLLkiFZV+JSHMvH7eaLdT9N5GBovBwu5yYKUR7skR8Fu+LozcSqQixnlEZUfyE55feLOQTUYzLmR9pNtPbPsu6WVhbNHMS3Ss2+AehHvz+n64GDmXxbX++IOBvm2olHu3PsOUGRwhudhVf7UcGcunXt8cqNjKNqZLhLw4jq\/xDg==" //微信签名
}
订单号:orderNumber
2:发起支付
微信 jsapi (H5)
调用: WeixinJSBridge.invoke
在回调函数里面判断状态是否为支付成功 if (res.err_msg == "get_brand_wcpay_request:ok")
微信小程序
调用: wx.requestPayment
3:查看订单状态接口
参数:订单号
返回:{ status: 0 } // 0未支付 1支付成功
李康
活动页面
要求 query 传参
接口: http://127.0.0.1:9090/home/activity
缪虎
搜索页面
处理一下首页,点击搜索框的时候直接跳转到搜索页面
接口: http://127.0.0.1:9090/home/search
陆旗
分类页面:
接口: http://127.0.0.1:9090/type/list